def simulate(self, Tend, nIntervals, gridWidth): problem = Implicit_Problem(self.rhs, self.y0, self.yd0) problem.name = 'IDA' # solver.rhs = self.right_hand_side problem.handle_result = self.handle_result problem.state_events = self.state_events problem.handle_event = self.handle_event problem.time_events = self.time_events problem.finalize = self.finalize # Create IDA object and set additional parameters simulation = IDA(problem) simulation.atol = self.atol simulation.rtol = self.rtol simulation.verbosity = self.verbosity if hasattr(simulation, 'continuous_output'): simulation.continuous_output = False # default 0, if one step approach should be used elif hasattr(simulation, 'report_continuously'): simulation.report_continuously = False # default 0, if one step approach should be used simulation.tout1 = self.tout1 simulation.lsoff = self.lsoff # Calculate nOutputIntervals: if gridWidth <> None: nOutputIntervals = int((Tend - self.t0) / gridWidth) else: nOutputIntervals = nIntervals # Check for feasible input parameters if nOutputIntervals == 0: print 'Error: gridWidth too high or nIntervals set to 0! Continue with nIntervals=1' nOutputIntervals = 1 # Perform simulation simulation.simulate(Tend, nOutputIntervals) # to get the values: t_new, y_new, yd_new = simulation.simulate
def solve(self): # Setup IDA assert self._initial_time is not None problem = Implicit_Problem(self._residual_vector_eval, self.solution.vector(), self.solution_dot.vector(), self._initial_time) problem.jac = self._jacobian_matrix_eval problem.handle_result = self._monitor # Define an Assimulo IDA solver solver = IDA(problem) # Setup options assert self._time_step_size is not None solver.inith = self._time_step_size if self._absolute_tolerance is not None: solver.atol = self._absolute_tolerance if self._max_time_steps is not None: solver.maxsteps = self._max_time_steps if self._relative_tolerance is not None: solver.rtol = self._relative_tolerance if self._report: solver.verbosity = 10 solver.display_progress = True solver.report_continuously = True else: solver.display_progress = False solver.verbosity = 50 # Assert consistency of final time and time step size assert self._final_time is not None final_time_consistency = ( self._final_time - self._initial_time) / self._time_step_size assert isclose( round(final_time_consistency), final_time_consistency ), ("Final time should be occuring after an integer number of time steps" ) # Prepare monitor computation if not provided by parameters if self._monitor_initial_time is None: self._monitor_initial_time = self._initial_time assert isclose( round(self._monitor_initial_time / self._time_step_size), self._monitor_initial_time / self._time_step_size ), ("Monitor initial time should be a multiple of the time step size" ) if self._monitor_time_step_size is None: self._monitor_time_step_size = self._time_step_size assert isclose( round(self._monitor_time_step_size / self._time_step_size), self._monitor_time_step_size / self._time_step_size ), ("Monitor time step size should be a multiple of the time step size" ) monitor_t = arange( self._monitor_initial_time, self._final_time + self._monitor_time_step_size / 2., self._monitor_time_step_size) # Solve solver.simulate(self._final_time, ncp_list=monitor_t)
def initialize_ode_solver(self, y_0, yd_0, t_0): model = Implicit_Problem(self.residual, y_0, yd_0, t_0) model.handle_result = self.handle_result solver = IDA(model) solver.rtol = self.solver_rtol solver.atol = self.solver_atol # * np.array([100, 10, 1e-4, 1e-4]) solver.inith = 0.1 # self.wind.R_g / const.C solver.maxh = self.dt * self.wind.R_g / const.C solver.report_continuously = True solver.display_progress = False solver.verbosity = 50 # 50 = quiet solver.num_threads = 3 # solver.display_progress = True return solver
def test_handle_result(self): """ This function tests the handle result. """ f = lambda t,x,xd: x**0.25-xd def handle_result(solver, t ,y, yd): assert solver.t == t prob = Implicit_Problem(f, [1.0],[1.0]) prob.handle_result = handle_result sim = IDA(prob) sim.continuous_output = True sim.simulate(10.)
def test_handle_result(self): """ This function tests the handle result. """ f = lambda t,x,xd: x**0.25-xd def handle_result(solver, t ,y, yd): assert solver.t == t prob = Implicit_Problem(f, [1.0],[1.0]) prob.handle_result = handle_result sim = IDA(prob) sim.report_continuously = True sim.simulate(10.)
def run_example(with_plots=True): r""" Example for demonstrating the use of a user supplied Jacobian ODE: .. math:: \dot y_1-y_3 &= 0 \\ \dot y_2-y_4 &= 0 \\ \dot y_3+y_5 y_1 &= 0 \\ \dot y_4+y_5 y_2+9.82&= 0 \\ y_3^2+y_4^2-y_5(y_1^2+y_2^2)-9.82 y_2&= 0 on return: - :dfn:`imp_mod` problem instance - :dfn:`imp_sim` solver instance """ global order order = [] #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[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]) 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]) #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, name='Example for plotting used order') imp_mod.handle_result = handle_result #Sets the options to the problem imp_mod.algvar = [1.0, 1.0, 1.0, 1.0, 0.0] #Set the algebraic components #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 imp_sim.report_continuously = True #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) #Simulate 5 seconds #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) nose.tools.assert_almost_equal(order[-1], 5, places=4) #Plot if with_plots: P.figure(1) P.plot(t, y, linestyle="dashed", marker="o") #Plot the solution P.xlabel('Time') P.ylabel('State') P.title(imp_mod.name) P.figure(2) P.plot([0] + N.add.accumulate(N.diff(t)).tolist(), order) P.title("Used order during the integration") P.xlabel("Time") P.ylabel("Order") P.show() return imp_mod, imp_sim
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