def get_solver(self, func): """ Returns the solver method from odespy package. Args: func: function function with ODE system. Returns: an instance of odeSolver """ if self.solverMethod is solverMethod.LSODA: solver = odespy.Lsoda(func) elif self.solverMethod is solverMethod.LSODAR: solver = odespy.Lsodar(func) elif self.solverMethod is solverMethod.LSODE: solver = odespy.Lsode(func) elif self.solverMethod is solverMethod.HEUN: solver = odespy.Heun(func) elif self.solverMethod is solverMethod.EULER: solver = odespy.Euler(func) elif self.solverMethod is solverMethod.RK4: solver = odespy.RK4(func) elif self.solverMethod is solverMethod.DORMAN_PRINCE: solver = odespy.DormandPrince(func) elif self.solverMethod is solverMethod.RKFehlberg: solver = odespy.RKFehlberg(func) elif self.solverMethod is solverMethod.Dopri5: solver = odespy.Dopri5(func) elif self.solverMethod is solverMethod.Dop853: solver = odespy.Dop853(func) elif self.solverMethod is solverMethod.Vode: solver = odespy.Vode(func) elif self.solverMethod is solverMethod.AdamsBashforth2: solver = odespy.AdamsBashforth2(func, method='bdf') elif self.solverMethod is solverMethod.Radau5: solver = odespy.Radau5(func) elif self.solverMethod is solverMethod.AdamsBashMoulton2: solver = odespy.AdamsBashMoulton2(func) # update default parameters solver.nsteps = SolverConfigurations.N_STEPS solver.atol = SolverConfigurations.ABSOLUTE_TOL solver.rtol = SolverConfigurations.RELATIVE_TOL return solver
w_F=2 * np.pi) # qualitatively wrong FE, almost ok BE, smaller T #f = RHS(b=0.4, A_F=20, w_F=0.5*np.pi) # cool, FE almost there, BE good # Define different sets of experiments solvers_theta = [ odespy.ForwardEuler(f), # Implicit methods must use Newton solver to converge odespy.BackwardEuler(f, nonlinear_solver='Newton'), odespy.CrankNicolson(f, nonlinear_solver='Newton'), ] solvers_RK = [odespy.RK2(f), odespy.RK4(f)] solvers_accurate = [ odespy.RK4(f), odespy.CrankNicolson(f, nonlinear_solver='Newton'), odespy.DormandPrince(f, atol=0.001, rtol=0.02) ] solvers_CN = [odespy.CrankNicolson(f, nonlinear_solver='Newton')] if __name__ == '__main__': timesteps_per_period = 20 solver_collection = 'theta' num_periods = 1 try: # Example: python vib_odespy.py 30 accurate 50 timesteps_per_period = int(sys.argv[1]) solver_collection = sys.argv[2] num_periods = int(sys.argv[3]) except IndexError: pass # default values are ok solvers = eval('solvers_' + solver_collection) # list of solvers
import scitools.std as plt def f(u, t): return -a * u def exact_solution(t): return I * np.exp(-a * t) I = 1 a = 2 T = 5 tol = float(sys.argv[1]) solver = odespy.DormandPrince(f, atol=tol, rtol=0.1 * tol) N = 1 # just one step - let the scheme find its intermediate points t_mesh = np.linspace(0, T, N + 1) t_fine = np.linspace(0, T, 10001) solver.set_initial_condition(I) u, t = solver.solve(t_mesh) # u and t will only consist of [I, u^N] and [0,T] # solver.u_all and solver.t_all contains all computed points plt.plot(solver.t_all, solver.u_all, 'ko') plt.hold('on') plt.plot(t_fine, exact_solution(t_fine), 'b-') plt.legend(['tol=%.0E' % tol, 'exact']) plt.savefig('tmp_odespy_adaptive.png')