def mySolve(xf,boltz_eqs,rtol,atol,verbosity=50): """Sets the main options for the ODE solver and solve the equations. Returns the array of x,y points for all components. If numerical instabilities are found, re-do the problematic part of the evolution with smaller steps""" boltz_solver = CVode(boltz_eqs) #Define solver method boltz_solver.rtol = rtol boltz_solver.atol = atol boltz_solver.verbosity = verbosity boltz_solver.linear_solver = 'SPGMR' boltz_solver.maxh = xf/300. xfinal = xf xres = [] yres = [] sw = boltz_solver.sw[:] while xfinal <= xf: try: boltz_solver.re_init(boltz_eqs.t0,boltz_eqs.y0) boltz_solver.sw = sw[:] x,y = boltz_solver.simulate(xfinal) xres += x for ypt in y: yres.append(ypt) if xfinal == xf: break #Evolution has been performed until xf -> exit except Exception,e: print e if not e.t or 'first call' in e.msg[e.value]: logger.error("Error solving equations:\n "+str(e)) return False xfinal = max(e.t*random.uniform(0.85,0.95),boltz_eqs.t0+boltz_solver.maxh) #Try again, but now only until the error logger.warning("Numerical instability found. Restarting evolution from x = " +str(boltz_eqs.t0)+" to x = "+str(xfinal)) continue xfinal = xf #In the next step try to evolve from xfinal -> xf sw = boltz_solver.sw[:] x0 = float(x[-1]) y0 = [float(yval) for yval in y[-1]] boltz_eqs.updateValues(x0,y0,sw)
def run_example(with_plots=True): r""" Example to demonstrate the use of a preconditioner .. math:: \dot y_1 & = 2 t \sin y_1 + t \sin y_2 \\ \dot y_2 & = 3 t \sin y_1 + 2 t \sin y_2 on return: - :dfn:`exp_mod` problem instance - :dfn:`exp_sim` solver instance """ #Define the rhs def rhs(t, y): A = np.array([[2.0, 1.0], [3.0, 2.0]]) yd = np.dot(A * t, np.sin(y)) return yd #Define the preconditioner setup function def prec_setup(t, y, fy, jok, gamma, data): A = np.array([[2.0, 1.0], [3.0, 2.0]]) #If jok is false the jacobian data needs to be recomputed if jok == False: #Extract the diagonal of the jacobian to form a Jacobi preconditioner a0 = A[0, 0] * t * np.cos(y[0]) a1 = A[1, 1] * t * np.cos(y[1]) a = np.array([(1. - gamma * a0), (1. - gamma * a1)]) #Return true (jacobian data was recomputed) and the new data return [True, a] #If jok is true the existing jacobian data can be reused if jok == True: #Return false (jacobian data was reused) and the old data return [False, data] #Define the preconditioner solve function def prec_solve(t, y, fy, r, gamma, delta, data): #Solve the system Pz = r z0 = r[0] / data[0] z1 = r[1] / data[1] z = np.array([z0, z1]) return z #Initial conditions y0 = [1.0, 2.0] #Define an Assimulo problem exp_mod = Explicit_Problem( rhs, y0, name="Example of using a preconditioner in SUNDIALS") #Set the preconditioner setup and solve function for the problem exp_mod.prec_setup = prec_setup exp_mod.prec_solve = prec_solve #Create a CVode solver exp_sim = CVode(exp_mod) #Set the parameters for the solver exp_sim.iter = 'Newton' exp_sim.discr = 'BDF' exp_sim.atol = 1e-5 exp_sim.rtol = 1e-5 exp_sim.linear_solver = 'SPGMR' exp_sim.precond = "PREC_RIGHT" #Set the desired type of preconditioning #Simulate t, y = exp_sim.simulate(5) if with_plots: exp_sim.plot() #Basic verification nose.tools.assert_almost_equal(y[-1, 0], 3.11178295, 4) nose.tools.assert_almost_equal(y[-1, 1], 3.19318992, 4) return exp_mod, exp_sim
def run_example(with_plots=True): r""" An example for CVode with scaled preconditioned GMRES method as a special linear solver. Note, how the operation Jacobian times vector is provided. ODE: .. math:: \dot y_1 &= y_2 \\ \dot y_2 &= -9.82 on return: - :dfn:`exp_mod` problem instance - :dfn:`exp_sim` solver instance """ #Defines the rhs def f(t, y): yd_0 = y[1] yd_1 = -9.82 return N.array([yd_0, yd_1]) #Defines the Jacobian*vector product def jacv(t, y, fy, v): j = N.array([[0, 1.], [0, 0]]) return N.dot(j, v) y0 = [1.0, 0.0] #Initial conditions #Defines an Assimulo explicit problem exp_mod = Explicit_Problem( f, y0, name='Example using the Jacobian Vector product') exp_mod.jacv = jacv #Sets the Jacobian exp_sim = CVode(exp_mod) #Create a CVode solver #Set the parameters exp_sim.iter = 'Newton' #Default 'FixedPoint' exp_sim.discr = 'BDF' #Default 'Adams' exp_sim.atol = 1e-5 #Default 1e-6 exp_sim.rtol = 1e-5 #Default 1e-6 exp_sim.linear_solver = 'SPGMR' #Change linear solver #exp_sim.options["usejac"] = False #Simulate t, y = exp_sim.simulate( 5, 1000) #Simulate 5 seconds with 1000 communication points #Basic tests nose.tools.assert_almost_equal(y[-1][0], -121.75000000, 4) nose.tools.assert_almost_equal(y[-1][1], -49.100000000) #Plot if with_plots: P.plot(t, y) P.xlabel('Time') P.ylabel('State') P.title(exp_mod.name) P.show() return exp_mod, exp_sim
def run_example(with_plots=True): r""" Example for demonstrating the use of a user supplied Jacobian (sparse). Note that this will only work if Assimulo has been configured with Sundials + SuperLU. Based on the SUNDIALS example cvRoberts_sps.c ODE: .. math:: \dot y_1 &= -0.04y_1 + 1e4 y_2 y_3 \\ \dot y_2 &= - \dot y_1 - \dot y_3 \\ \dot y_3 &= 3e7 y_2^2 on return: - :dfn:`exp_mod` problem instance - :dfn:`exp_sim` solver instance """ #Defines the rhs def f(t, y): yd_0 = -0.04 * y[0] + 1e4 * y[1] * y[2] yd_2 = 3e7 * y[1] * y[1] yd_1 = -yd_0 - yd_2 return N.array([yd_0, yd_1, yd_2]) #Defines the Jacobian def jac(t, y): colptrs = [0, 3, 6, 9] rowvals = [0, 1, 2, 0, 1, 2, 0, 1, 2] data = [ -0.04, 0.04, 0.0, 1e4 * y[2], -1e4 * y[2] - 6e7 * y[1], 6e7 * y[1], 1e4 * y[1], -1e4 * y[1], 0.0 ] J = SP.csc_matrix((data, rowvals, colptrs)) return J #Defines an Assimulo explicit problem y0 = [1.0, 0.0, 0.0] #Initial conditions exp_mod = Explicit_Problem(f, y0, name='Example using analytic (sparse) Jacobian') exp_mod.jac = jac #Sets the Jacobian exp_mod.jac_nnz = 9 exp_sim = CVode(exp_mod) #Create a CVode solver #Set the parameters exp_sim.iter = 'Newton' #Default 'FixedPoint' exp_sim.discr = 'BDF' #Default 'Adams' exp_sim.atol = [1e-8, 1e-14, 1e-6] #Default 1e-6 exp_sim.rtol = 1e-4 #Default 1e-6 exp_sim.linear_solver = "sparse" #Simulate t, y = exp_sim.simulate(0.4) #Simulate 0.4 seconds #Basic tests nose.tools.assert_almost_equal(y[-1][0], 0.9851, 3) #Plot if with_plots: P.plot(t, y[:, 1], linestyle="dashed", marker="o") #Plot the solution P.xlabel('Time') P.ylabel('State') P.title(exp_mod.name) P.show() return exp_mod, exp_sim