python - algebraic constraint to terminate ODE integration with scipy -


i'm using scipy 14.0 solve system of ordinary differential equations describing dynamics of gas bubble rising vertically (in z direction) in standing still fluid because of buoyancy forces. in particular, have equation expressing rising velocity u function of bubble radius r, i.e. u=dz/dt=f(r), , 1 expressing radius variation function of r , u, i.e. dr/dt=f(r,u). rest appearing in code below material properties. i'd implement account physical constraint on z which, obviously, limited liquid height h. consequently implemented sort of z<=h constraint in order stop integration in advance if needed: used set_solout in order so. situation code runs , gives results, set_solout not working @ (it seems z_constraint never called actually...). know why? there more clever idea, may in order interrupt when z=h (i.e. final value problem) ? right way/tool or should reformulate problem?

thanks in advance

emi

from scipy.integrate import ode   db0 = 0.001 # init bubble radius y0, t0 = [ db0/2 , 0. ], 0. #init conditions h = 1  def y_(t,y,g,p0,rho_g,mi_g,sig_g,h):     r = y[0]      z = y[1]     z_ = ( r**2 * g * rho_g ) / ( 3*mi_g )  #velocity     r_ = ( r/3 * g * rho_g * z_ ) / ( p0 + rho_g*g*(h-z) + 4/3*sig_g/r ) #r dynamics         return [r_, z_]  def z_constraint(t,y):     h = 1  #should rather variable..     z = y[1]      if z >= h:         flag = -1      else:         flag = 0     return flag  r = ode( y_ ) r.set_integrator('dopri5') r.set_initial_value(y0, t0) r.set_f_params(g, 5*1e5, 2000, 40, 0.31, h) r.set_solout(z_constraint)  t1 = 6 dt = 0.1  while r.successful() , r.t < t1:     r.integrate(r.t+dt) 

you're running this issue. set_solout work correctly, must called right after set_integrator, before set_initial_value. if introduce modification code (and set value g), integration terminate when z >= h, want.

to find exact time when bubble reached surface, can make change of variables after integration terminated solout , integrate respect z (rather t) z = h. paper describes technique m. henon, physica 5d, 412 (1982); may find this discussion helpful. here's simple example in time t such y(t) = 0.5 found, given dy/dt = -y:

import numpy np scipy.integrate import ode  def f(t, y):     """exponential decay: dy/dt = -y."""     return -y  def solout(t, y):     if y[0] < 0.5:         return -1     else:         return 0  y_initial = 1 t_initial = 0  r = ode(f).set_integrator('dopri5') r.set_solout(solout) r.set_initial_value(y_initial, t_initial)  # integrate until solout constraint violated r.integrate(2)  # new system t independent variable: see henon's paper details. def g(y, t):     return -1.0/y  r2 = ode(g).set_integrator('dopri5') r2.set_initial_value(r.t, r.y)  r2.integrate(0.5)  y_final = r2.t t_final = r2.y  # error: difference between found , analytical solution print t_final - np.log(2) 

Comments

Popular posts from this blog

database - VFP Grid + SQL server 2008 - grid not showing correctly -

jquery - Set jPicker field to empty value -

.htaccess - htaccess convert request to clean url and add slash at the end of the url -