def run_example(with_plots=True): """ This is the same example from the Sundials package (idasRoberts_FSA_dns.c) This simple example problem for IDA, due to Robertson, is from chemical kinetics, and consists of the following three equations:: dy1/dt = -p1*y1 + p2*y2*y3 dy2/dt = p1*y1 - p2*y2*y3 - p3*y2**2 0 = y1 + y2 + y3 - 1 """ def f(t, y, yd, p): res1 = -p[0]*y[0]+p[1]*y[1]*y[2]-yd[0] res2 = p[0]*y[0]-p[1]*y[1]*y[2]-p[2]*y[1]**2-yd[1] res3 = y[0]+y[1]+y[2]-1 return N.array([res1,res2,res3]) #The initial conditons y0 = [1.0, 0.0, 0.0] #Initial conditions for y yd0 = [0.1, 0.0, 0.0] #Initial conditions for dy/dt p0 = [0.040, 1.0e4, 3.0e7] #Initial conditions for parameters #Create an Assimulo implicit problem imp_mod = Implicit_Problem(f, y0, yd0,p0=p0) #Create an Assimulo implicit solver (IDA) imp_sim = IDA(imp_mod) #Create a IDA solver #Sets the paramters imp_sim.atol = N.array([1.0e-8, 1.0e-14, 1.0e-6]) imp_sim.algvar = [1.0,1.0,0.0] imp_sim.suppress_alg = False #Suppres the algebraic variables on the error test imp_sim.continuous_output = True #Store data continuous during the simulation imp_sim.pbar = p0 imp_sim.suppress_sens = False #Dont suppress the sensitivity variables in the error test. #Let Sundials find consistent initial conditions by use of 'IDA_YA_YDP_INIT' imp_sim.make_consistent('IDA_YA_YDP_INIT') #Simulate t, y, yd = imp_sim.simulate(4,400) #Simulate 4 seconds with 400 communication points print imp_sim.p_sol[0][-1] , imp_sim.p_sol[1][-1], imp_sim.p_sol[0][-1] #Basic test nose.tools.assert_almost_equal(y[-1][0], 9.05518032e-01, 4) nose.tools.assert_almost_equal(y[-1][1], 2.24046805e-05, 4) nose.tools.assert_almost_equal(y[-1][2], 9.44595637e-02, 4) nose.tools.assert_almost_equal(imp_sim.p_sol[0][-1][0], -1.8761, 2) #Values taken from the example in Sundials nose.tools.assert_almost_equal(imp_sim.p_sol[1][-1][0], 2.9614e-06, 8) nose.tools.assert_almost_equal(imp_sim.p_sol[2][-1][0], -4.9334e-10, 12) #Plot if with_plots: P.plot(t,y) P.show()
def run_example(with_plots=True): #Defines the residual def f(t,y,yd): res_0 = yd[0]-y[2] res_1 = yd[1]-y[3] res_2 = yd[2]+y[4]*y[0] res_3 = yd[3]+y[4]*y[1]+9.82 #res_4 = y[0]**2+y[1]**2-1 res_4 = y[2]**2+y[3]**2-y[4]*(y[0]**2+y[1]**2)-y[1]*9.82 return N.array([res_0,res_1,res_2,res_3,res_4]) #Defines the jacobian def jac(c,t,y,yd): jacobian = N.zeros([len(y),len(y)]) #Derivative jacobian[0,0] = 1*c jacobian[1,1] = 1*c jacobian[2,2] = 1*c jacobian[3,3] = 1*c #Differentiated jacobian[0,2] = -1 jacobian[1,3] = -1 jacobian[2,0] = y[4] jacobian[3,1] = y[4] jacobian[4,0] = y[0]*2*y[4]*-1 jacobian[4,1] = y[1]*2*y[4]*-1-9.82 jacobian[4,2] = y[2]*2 jacobian[4,3] = y[3]*2 #Algebraic jacobian[2,4] = y[0] jacobian[3,4] = y[1] jacobian[4,4] = -(y[0]**2+y[1]**2) return jacobian #The initial conditons y0 = [1.0,0.0,0.0,0.0,5] #Initial conditions yd0 = [0.0,0.0,0.0,-9.82,0.0] #Initial conditions #Create an Assimulo implicit problem imp_mod = Implicit_Problem(f,y0,yd0) #Sets the options to the problem imp_mod.jac = jac #Sets the jacobian imp_mod.algvar = [1.0,1.0,1.0,1.0,0.0] #Set the algebraic components imp_mod.name = 'Test Jacobian' #Create an Assimulo implicit solver (IDA) imp_sim = IDA(imp_mod) #Create a IDA solver #Sets the paramters imp_sim.atol = 1e-6 #Default 1e-6 imp_sim.rtol = 1e-6 #Default 1e-6 imp_sim.suppress_alg = True #Suppres the algebraic variables on the error test #Let Sundials find consistent initial conditions by use of 'IDA_YA_YDP_INIT' imp_sim.make_consistent('IDA_YA_YDP_INIT') #Simulate t, y, yd = imp_sim.simulate(5,1000) #Simulate 5 seconds with 1000 communication points #Basic tests nose.tools.assert_almost_equal(y[-1][0],0.9401995, places=4) nose.tools.assert_almost_equal(y[-1][1],-0.34095124, places=4) nose.tools.assert_almost_equal(yd[-1][0], -0.88198927, places=4) nose.tools.assert_almost_equal(yd[-1][1], -2.43227069, places=4) #Plot if with_plots: P.plot(t,y) P.show()
def run_example(with_plots=True): """ This is the same example from the Sundials package (idasRoberts_FSA_dns.c) This simple example problem for IDA, due to Robertson, is from chemical kinetics, and consists of the following three equations:: dy1/dt = -p1*y1 + p2*y2*y3 dy2/dt = p1*y1 - p2*y2*y3 - p3*y2**2 0 = y1 + y2 + y3 - 1 """ def f(t, y, yd, p): res1 = -p[0] * y[0] + p[1] * y[1] * y[2] - yd[0] res2 = p[0] * y[0] - p[1] * y[1] * y[2] - p[2] * y[1]**2 - yd[1] res3 = y[0] + y[1] + y[2] - 1 return N.array([res1, res2, res3]) #The initial conditons y0 = [1.0, 0.0, 0.0] #Initial conditions for y yd0 = [0.1, 0.0, 0.0] #Initial conditions for dy/dt p0 = [0.040, 1.0e4, 3.0e7] #Initial conditions for parameters #Create an Assimulo implicit problem imp_mod = Implicit_Problem(f, y0, yd0, p0=p0) #Create an Assimulo implicit solver (IDA) imp_sim = IDA(imp_mod) #Create a IDA solver #Sets the paramters imp_sim.atol = N.array([1.0e-8, 1.0e-14, 1.0e-6]) imp_sim.algvar = [1.0, 1.0, 0.0] imp_sim.suppress_alg = False #Suppres the algebraic variables on the error test imp_sim.continuous_output = True #Store data continuous during the simulation imp_sim.pbar = p0 imp_sim.suppress_sens = False #Dont suppress the sensitivity variables in the error test. #Let Sundials find consistent initial conditions by use of 'IDA_YA_YDP_INIT' imp_sim.make_consistent('IDA_YA_YDP_INIT') #Simulate t, y, yd = imp_sim.simulate( 4, 400) #Simulate 4 seconds with 400 communication points print imp_sim.p_sol[0][-1], imp_sim.p_sol[1][-1], imp_sim.p_sol[0][-1] #Basic test nose.tools.assert_almost_equal(y[-1][0], 9.05518032e-01, 4) nose.tools.assert_almost_equal(y[-1][1], 2.24046805e-05, 4) nose.tools.assert_almost_equal(y[-1][2], 9.44595637e-02, 4) nose.tools.assert_almost_equal( imp_sim.p_sol[0][-1][0], -1.8761, 2) #Values taken from the example in Sundials nose.tools.assert_almost_equal(imp_sim.p_sol[1][-1][0], 2.9614e-06, 8) nose.tools.assert_almost_equal(imp_sim.p_sol[2][-1][0], -4.9334e-10, 12) #Plot if with_plots: P.plot(t, y) P.show()
def simulate(model, init_cond, start_time=0., final_time=1., input=(lambda t: []), ncp=500, blt=True, causalization_options=sp.CausalizationOptions(), expand_to_sx=True, suppress_alg=False, tol=1e-8, solver="IDA"): """ Simulate model from CasADi Interface using CasADi. init_cond is a dictionary containing initial conditions for all variables. """ if blt: t_0 = timing.time() blt_model = sp.BLTModel(model, causalization_options) blt_time = timing.time() - t_0 print("BLT analysis time: %.3f s" % blt_time) blt_model._model = model model = blt_model if causalization_options['closed_form']: solved_vars = model._solved_vars solved_expr = model._solved_expr #~ for (var, expr) in itertools.izip(solved_vars, solved_expr): #~ print('%s := %s' % (var.getName(), expr)) return model dh() # This is not a debug statement! # Extract model variables model_states = [var for var in model.getVariables(model.DIFFERENTIATED) if not var.isAlias()] model_derivatives = [var for var in model.getVariables(model.DERIVATIVE) if not var.isAlias()] model_algs = [var for var in model.getVariables(model.REAL_ALGEBRAIC) if not var.isAlias()] model_inputs = [var for var in model.getVariables(model.REAL_INPUT) if not var.isAlias()] states = [var.getVar() for var in model_states] derivatives = [var.getMyDerivativeVariable().getVar() for var in model_states] algebraics = [var.getVar() for var in model_algs] inputs = [var.getVar() for var in model_inputs] n_x = len(states) n_y = len(states) + len(algebraics) n_w = len(algebraics) n_u = len(inputs) # Create vectorized model variables t = model.getTimeVariable() y = MX.sym("y", n_y) yd = MX.sym("yd", n_y) u = MX.sym("u", n_u) # Extract the residuals and substitute the (x,z) variables for the old variables scalar_vars = states + algebraics + derivatives + inputs vector_vars = [y[k] for k in range(n_y)] + [yd[k] for k in range(n_x)] + [u[k] for k in range(n_u)] [dae] = substitute([model.getDaeResidual()], scalar_vars, vector_vars) # Fix parameters if not blt: # Sort parameters par_kinds = [model.BOOLEAN_CONSTANT, model.BOOLEAN_PARAMETER_DEPENDENT, model.BOOLEAN_PARAMETER_INDEPENDENT, model.INTEGER_CONSTANT, model.INTEGER_PARAMETER_DEPENDENT, model.INTEGER_PARAMETER_INDEPENDENT, model.REAL_CONSTANT, model.REAL_PARAMETER_INDEPENDENT, model.REAL_PARAMETER_DEPENDENT] pars = reduce(list.__add__, [list(model.getVariables(par_kind)) for par_kind in par_kinds]) # Get parameter values model.calculateValuesForDependentParameters() par_vars = [par.getVar() for par in pars] par_vals = [model.get_attr(par, "_value") for par in pars] # Eliminate parameters [dae] = casadi.substitute([dae], par_vars, par_vals) # Extract initial conditions y0 = [init_cond[var.getName()] for var in model_states] + [init_cond[var.getName()] for var in model_algs] yd0 = [init_cond[var.getName()] for var in model_derivatives] + n_w * [0.] # Create residual CasADi functions dae_res = MXFunction([t, y, yd, u], [dae]) dae_res.setOption("name", "complete_dae_residual") dae_res.init() ################### #~ import matplotlib.pyplot as plt #~ h = MX.sym("h") #~ iter_matrix_expr = dae_res.jac(2)/h + dae_res.jac(1) #~ iter_matrix = MXFunction([t, y, yd, u, h], [iter_matrix_expr]) #~ iter_matrix.init() #~ n = 100; #~ hs = np.logspace(-8, 1, n); #~ conds = [np.linalg.cond(iter_matrix.call([0, y0, yd0, input(0), hval])[0].toArray()) for hval in hs] #~ plt.close(1) #~ plt.figure(1) #~ plt.loglog(hs, conds, 'b-') #~ #plt.gca().invert_xaxis() #~ plt.grid('on') #~ didx = range(4, 12) + range(30, 33) #~ aidx = [i for i in range(33) if i not in didx] #~ didx = range(10) #~ aidx = [] #~ F = MXFunction([t, y, yd, u], [dae[didx]]) #~ F.init() #~ G = MXFunction([t, y, yd, u], [dae[aidx]]) #~ G.init() #~ dFddx = F.jac(2)[:, :n_x] #~ dFdx = F.jac(1)[:, :n_x] #~ dFdy = F.jac(1)[:, n_x:] #~ dGdx = G.jac(1)[:, :n_x] #~ dGdy = G.jac(1)[:, n_x:] #~ E_matrix = MXFunction([t, y, yd, u, h], [dFddx]) #~ E_matrix.init() #~ E_cond = np.linalg.cond(E_matrix.call([0, y0, yd0, input(0), hval])[0].toArray()) #~ iter_matrix_expr = vertcat([horzcat([dFddx + h*dFdx, h*dFdy]), horzcat([dGdx, dGdy])]) #~ iter_matrix = MXFunction([t, y, yd, u, h], [iter_matrix_expr]) #~ iter_matrix.init() #~ n = 100 #~ hs = np.logspace(-8, 1, n) #~ conds = [np.linalg.cond(iter_matrix.call([0, y0, yd0, input(0), hval])[0].toArray()) for hval in hs] #~ plt.loglog(hs, conds, 'b--') #~ plt.gca().invert_xaxis() #~ plt.grid('on') #~ plt.xlabel('$h$') #~ plt.ylabel('$\kappa$') #~ plt.show() #~ dh() ################### # Expand to SX if expand_to_sx: dae_res = SXFunction(dae_res) dae_res.init() # Create DAE residual Assimulo function def dae_residual(t, y, yd): dae_res.setInput(t, 0) dae_res.setInput(y, 1) dae_res.setInput(yd, 2) dae_res.setInput(input(t), 3) dae_res.evaluate() return dae_res.getOutput(0).toArray().reshape(-1) # Set up simulator problem = Implicit_Problem(dae_residual, y0, yd0, start_time) if solver == "IDA": simulator = IDA(problem) elif solver == "Radau5DAE": simulator = Radau5DAE(problem) else: raise ValueError("Unknown solver %s" % solver) simulator.rtol = tol simulator.atol = 1e-4 * np.array([model.get_attr(var, "nominal") for var in model_states + model_algs]) #~ simulator.atol = tol * np.ones([n_y, 1]) simulator.report_continuously = True # Log method order if solver == "IDA": global order order = [] def handle_result(solver, t, y, yd): global order order.append(solver.get_last_order()) solver.t_sol.extend([t]) solver.y_sol.extend([y]) solver.yd_sol.extend([yd]) problem.handle_result = handle_result # Suppress algebraic variables if suppress_alg: if isinstance(suppress_alg, bool): simulator.algvar = n_x * [True] + (n_y - n_x) * [False] else: simulator.algvar = n_x * [True] + suppress_alg simulator.suppress_alg = True # Simulate t_0 = timing.time() (t, y, yd) = simulator.simulate(final_time, ncp) simul_time = timing.time() - t_0 stats = {'time': simul_time, 'steps': simulator.statistics['nsteps']} if solver == "IDA": stats['order'] = order # Generate result for time and inputs class SimulationResult(dict): pass res = SimulationResult() res.stats = stats res['time'] = t if u.numel() > 0: input_names = [var.getName() for var in model_inputs] for name in input_names: res[name] = [] for time in t: input_val = input(time) for (name, val) in itertools.izip(input_names, input_val): res[name].append(val) # Create results for everything else if blt: # Iteration variables i = 0 for var in model_states: res[var.getName()] = y[:, i] res[var.getMyDerivativeVariable().getName()] = yd[:, i] i += 1 for var in model_algs: res[var.getName()] = y[:, i] i += 1 # Create function for computing solved algebraics for (_, sol_alg) in model._explicit_solved_algebraics: res[sol_alg.name] = [] alg_sol_f = casadi.MXFunction(model._known_vars + model._explicit_unsolved_vars, model._solved_expr) alg_sol_f.init() if expand_to_sx: alg_sol_f = casadi.SXFunction(alg_sol_f) alg_sol_f.init() # Compute solved algebraics for k in xrange(len(t)): for (i, var) in enumerate(model._known_vars + model._explicit_unsolved_vars): alg_sol_f.setInput(res[var.getName()][k], i) alg_sol_f.evaluate() for (j, sol_alg) in model._explicit_solved_algebraics: res[sol_alg.name].append(alg_sol_f.getOutput(j).toScalar()) else: res_vars = model_states + model_algs for (i, var) in enumerate(res_vars): res[var.getName()] = y[:, i] der_var = var.getMyDerivativeVariable() if der_var is not None: res[der_var.getName()] = yd[:, i] # Add results for all alias variables (only treat time-continuous variables) and convert to array if blt: res_model = model._model else: res_model = model for var in res_model.getAllVariables(): if var.getVariability() == var.CONTINUOUS: res[var.getName()] = np.array(res[var.getModelVariable().getName()]) res["time"] = np.array(res["time"]) res._blt_model = blt_model return res
yp[2] = -yp[2] print("DING") solver.yd = yp solver.y = y t0 = 0 tfinal = 1 ncp = 500 y0 = [0., -0.10344, -0.65, 0. ,0. , 0., -0.6911, -0.14161] yp0 = [0., 0., 0., 0., 0., 1.40059e2, 0., 0.] switches0 = [False, True, False] mod = Implicit_Problem(woodpeckertoy, y0, yp0, t0, sw0 = switches0) mod.state_events = state_events mod.handle_event = handle_event sim = IDA(mod) sim.suppress_alg = True sim.rtol=1.e-6 sim.atol[3:8] = 1e6 sim.algvar[3:8] = 0. t, y, yp = sim.simulate(tfinal, ncp) P.plot(t,y[:,0:3]) P.legend(["z","phiS", "phiB", "z vel", "phiS vel", "phiB vel"]) P.ylabel('y') P.xlabel('x') fontlabel_size = 20 tick_size = 14 params = {'lines.markersize' : 0, 'axes.labelsize': fontlabel_size, 'text.fontsize': fontlabel_size, 'legend.fontsize': fontlabel_size, 'xtick.labelsize': tick_size, 'ytick.labelsize': tick_size} P.rcParams.update(params) P.show()
def run_example(with_plots=True): #Defines the residual def f(t, y, yd): res_0 = yd[0] - y[2] res_1 = yd[1] - y[3] res_2 = yd[2] + y[4] * y[0] res_3 = yd[3] + y[4] * y[1] + 9.82 #res_4 = y[0]**2+y[1]**2-1 res_4 = y[2]**2 + y[3]**2 - y[4] * (y[0]**2 + y[1]**2) - y[1] * 9.82 return N.array([res_0, res_1, res_2, res_3, res_4]) #Defines the jacobian def jac(c, t, y, yd): jacobian = N.zeros([len(y), len(y)]) #Derivative jacobian[0, 0] = 1 * c jacobian[1, 1] = 1 * c jacobian[2, 2] = 1 * c jacobian[3, 3] = 1 * c #Differentiated jacobian[0, 2] = -1 jacobian[1, 3] = -1 jacobian[2, 0] = y[4] jacobian[3, 1] = y[4] jacobian[4, 0] = y[0] * 2 * y[4] * -1 jacobian[4, 1] = y[1] * 2 * y[4] * -1 - 9.82 jacobian[4, 2] = y[2] * 2 jacobian[4, 3] = y[3] * 2 #Algebraic jacobian[2, 4] = y[0] jacobian[3, 4] = y[1] jacobian[4, 4] = -(y[0]**2 + y[1]**2) return jacobian #The initial conditons y0 = [1.0, 0.0, 0.0, 0.0, 5] #Initial conditions yd0 = [0.0, 0.0, 0.0, -9.82, 0.0] #Initial conditions #Create an Assimulo implicit problem imp_mod = Implicit_Problem(f, y0, yd0) #Sets the options to the problem imp_mod.jac = jac #Sets the jacobian imp_mod.algvar = [1.0, 1.0, 1.0, 1.0, 0.0] #Set the algebraic components imp_mod.name = 'Test Jacobian' #Create an Assimulo implicit solver (IDA) imp_sim = IDA(imp_mod) #Create a IDA solver #Sets the paramters imp_sim.atol = 1e-6 #Default 1e-6 imp_sim.rtol = 1e-6 #Default 1e-6 imp_sim.suppress_alg = True #Suppres the algebraic variables on the error test #Let Sundials find consistent initial conditions by use of 'IDA_YA_YDP_INIT' imp_sim.make_consistent('IDA_YA_YDP_INIT') #Simulate t, y, yd = imp_sim.simulate( 5, 1000) #Simulate 5 seconds with 1000 communication points #Basic tests nose.tools.assert_almost_equal(y[-1][0], 0.9401995, places=4) nose.tools.assert_almost_equal(y[-1][1], -0.34095124, places=4) nose.tools.assert_almost_equal(yd[-1][0], -0.88198927, places=4) nose.tools.assert_almost_equal(yd[-1][1], -2.43227069, places=4) #Plot if with_plots: P.plot(t, y) P.show()