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 test_input_simulation(self): """ This tests that input simulation works. """ self.m_SENS = JMUModel('QuadTankSens.jmu') self.SENS = JMIDAESens(self.m_SENS) path_result = os.path.join(get_files_path(), 'Results', 'qt_par_est_data.mat') data = loadmat(path_result,appendmat=False) # Extract data series t_meas = data['t'][6000::100,0]-60 u1 = data['u1_d'][6000::100,0] u2 = data['u2_d'][6000::100,0] # Build input trajectory matrix for use in simulation u_data = N.transpose(N.vstack((t_meas,u1,u2))) u_traj = TrajectoryLinearInterpolation(u_data[:,0], u_data[:,1:]) input_object = (['u1','u2'], u_traj) qt_mod = JMIDAESens(self.m_SENS, input_object) qt_sim = IDA(qt_mod) #Store data continuous during the simulation, important when solving a #problem with sensitivites. qt_sim.report_continuously = True #Value used when IDA estimates the tolerances on the parameters qt_sim.pbar = qt_mod.p0 #Let Sundials find consistent initial conditions by use of 'IDA_YA_YDP_INIT' qt_sim.make_consistent('IDA_YA_YDP_INIT') #Simulate qt_sim.simulate(60) #Simulate 4 seconds with 400 communication points #write_data(qt_sim) res = ResultDymolaTextual('QuadTankSens_result.txt') dx1da1 = res.get_variable_data('dx1/da1') dx1da2 = res.get_variable_data('dx1/da2') dx4da1 = res.get_variable_data('dx4/da1') nose.tools.assert_almost_equal(dx1da2.x[0], 0.000000, 4) nose.tools.assert_almost_equal(dx1da2.x[-1], 0.00000, 4)
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 buildsim(self, ): """ Setup the assimulo IDA simulator. """ # Create an Assimulo implicit solver (IDA) imp_sim = IDA(self.imp_mod) # Create a IDA solver # Sets the paramters # 1e-4 #Default 1e-6 imp_sim.atol = self.p.RunInput['TIMESTEPPING']['SOLVER_TOL'] # 1e-4 #Default 1e-6 imp_sim.rtol = self.p.RunInput['TIMESTEPPING']['SOLVER_TOL'] # Suppres the algebraic variables on the error test imp_sim.suppress_alg = True imp_sim.display_progress = False imp_sim.verbosity = 50 imp_sim.report_continuously = True imp_sim.time_limit = 10. self.imp_sim = imp_sim
def run_example(with_plots=True): r""" Example of the use of IDA for an implicit differential equation with a discontinuity (state event) and the need for an event iteration. on return: - :dfn:`imp_mod` problem instance - :dfn:`imp_sim` solver instance """ #Create an instance of the problem imp_mod = Extended_Problem() #Create the problem imp_sim = IDA(imp_mod) #Create the solver imp_sim.verbosity = 0 imp_sim.report_continuously = True #Simulate t, y, yd = imp_sim.simulate(10.0,1000) #Simulate 10 seconds with 1000 communications points #Plot if with_plots: import pylab as P P.plot(t,y) P.title(imp_mod.name) P.ylabel('States') P.xlabel('Time') P.show() #Basic test nose.tools.assert_almost_equal(y[-1][0],8.0) nose.tools.assert_almost_equal(y[-1][1],3.0) nose.tools.assert_almost_equal(y[-1][2],2.0) return imp_mod, imp_sim
def run_example(with_plots=True): """ This example show how to use Assimulo and IDA for simulating sensitivities for initial conditions.:: 0 = dy1/dt - -(k01+k21+k31)*y1 - k12*y2 - k13*y3 - b1 0 = dy2/dt - k21*y1 + (k02+k12)*y2 0 = dy3/dt - k31*y1 + k13*y3 y1(0) = p1, y2(0) = p2, y3(0) = p3 p1=p2=p3 = 0 See http://sundials.2283335.n4.nabble.com/Forward-sensitivities-for-initial-conditions-td3239724.html on return: - :dfn:`imp_mod` problem instance - :dfn:`imp_sim` solver instance """ def f(t, y, yd, p): y1, y2, y3 = y yd1, yd2, yd3 = yd k01 = 0.0211 k02 = 0.0162 k21 = 0.0111 k12 = 0.0124 k31 = 0.0039 k13 = 0.000035 b1 = 49.3 res_0 = -yd1 - (k01 + k21 + k31) * y1 + k12 * y2 + k13 * y3 + b1 res_1 = -yd2 + k21 * y1 - (k02 + k12) * y2 res_2 = -yd3 + k31 * y1 - k13 * y3 return N.array([res_0, res_1, res_2]) #The initial conditions y0 = [0.0, 0.0, 0.0] #Initial conditions for y yd0 = [49.3, 0., 0.] p0 = [0.0, 0.0, 0.0] #Initial conditions for parameters yS0 = N.array([[1, 0, 0], [0, 1, 0], [0, 0, 1.]]) #Create an Assimulo implicit problem imp_mod = Implicit_Problem(f, y0, yd0, p0=p0, name='Example: Computing Sensitivities') #Sets the options to the problem imp_mod.yS0 = yS0 #Create an Assimulo explicit solver (IDA) imp_sim = IDA(imp_mod) #Sets the paramters imp_sim.rtol = 1e-7 imp_sim.atol = 1e-6 imp_sim.pbar = [ 1, 1, 1 ] #pbar is used to estimate the tolerances for the parameters imp_sim.report_continuously = True #Need to be able to store the result using the interpolate methods imp_sim.sensmethod = 'SIMULTANEOUS' #Defines the sensitvity method used imp_sim.suppress_sens = False #Dont suppress the sensitivity variables in the error test. #Simulate t, y, yd = imp_sim.simulate(400) #Simulate 400 seconds #Basic test nose.tools.assert_almost_equal(y[-1][0], 1577.6552477, 3) nose.tools.assert_almost_equal(y[-1][1], 611.9574565, 3) nose.tools.assert_almost_equal(y[-1][2], 2215.88563217, 3) nose.tools.assert_almost_equal(imp_sim.p_sol[0][1][0], 1.0) #Plot if with_plots: P.figure(1) P.subplot(221) P.plot(t, N.array(imp_sim.p_sol[0])[:, 0], t, N.array(imp_sim.p_sol[0])[:, 1], t, N.array(imp_sim.p_sol[0])[:, 2]) P.title("Parameter p1") P.legend(("p1/dy1", "p1/dy2", "p1/dy3")) P.subplot(222) P.plot(t, N.array(imp_sim.p_sol[1])[:, 0], t, N.array(imp_sim.p_sol[1])[:, 1], t, N.array(imp_sim.p_sol[1])[:, 2]) P.title("Parameter p2") P.legend(("p2/dy1", "p2/dy2", "p2/dy3")) P.subplot(223) P.plot(t, N.array(imp_sim.p_sol[2])[:, 0], t, N.array(imp_sim.p_sol[2])[:, 1], t, N.array(imp_sim.p_sol[2])[:, 2]) P.title("Parameter p3") P.legend(("p3/dy1", "p3/dy2", "p3/dy3")) P.subplot(224) P.title('ODE Solution') P.plot(t, y) P.suptitle(imp_mod.name) P.show() return imp_mod, imp_sim
def dae_solver(residual, y0, yd0, t0, p0=None, jac=None, name='DAE', solver='IDA', algvar=None, atol=1e-6, backward=False, display_progress=True, pbar=None, report_continuously=False, rtol=1e-6, sensmethod='STAGGERED', suppress_alg=False, suppress_sens=False, usejac=False, usesens=False, verbosity=30, tfinal=10., ncp=500): ''' DAE solver. Parameters ---------- residual: function Implicit DAE model. y0: List[float] Initial model state. yd0: List[float] Initial model state derivatives. t0: float Initial simulation time. p0: List[float] Parameters for which sensitivites are to be calculated. jac: function Model jacobian. name: string Model name. solver: string DAE solver. algvar: List[bool] A list for defining which variables are differential and which are algebraic. The value True(1.0) indicates a differential variable and the value False(0.0) indicates an algebraic variable. atol: float Absolute tolerance. backward: bool Specifies if the simulation is done in reverse time. display_progress: bool Actives output during the integration in terms of that the current integration is periodically printed to the stdout. Report_continuously needs to be activated. pbar: List[float] An array of positive floats equal to the number of parameters. Default absolute values of the parameters. Specifies the order of magnitude for the parameters. Useful if IDAS is to estimate tolerances for the sensitivity solution vectors. report_continuously: bool Specifies if the solver should report the solution continuously after steps. rtol: float Relative tolerance. sensmethod: string Specifies the sensitivity solution method. Can be either ‘SIMULTANEOUS’ or ‘STAGGERED’. Default is 'STAGGERED'. suppress_alg: bool Indicates that the error-tests are suppressed on algebraic variables. suppress_sens: bool Indicates that the error-tests are suppressed on the sensitivity variables. usejac: bool Sets the option to use the user defined jacobian. usesens: bool Aactivates or deactivates the sensitivity calculations. verbosity: int Determines the level of the output. QUIET = 50 WHISPER = 40 NORMAL = 30 LOUD = 20 SCREAM = 10 tfinal: float Simulation final time. ncp: int Number of communication points (number of return points). Returns ------- sol: solution [time, model states], List[float] ''' if usesens is True: # parameter sensitivity model = Implicit_Problem(residual, y0, yd0, t0, p0=p0) else: model = Implicit_Problem(residual, y0, yd0, t0) model.name = name if usejac is True: # jacobian model.jac = jac if algvar is not None: # differential or algebraic variables model.algvar = algvar if solver == 'IDA': # solver from assimulo.solvers import IDA sim = IDA(model) sim.atol = atol sim.rtol = rtol sim.backward = backward # backward in time sim.report_continuously = report_continuously sim.display_progress = display_progress sim.suppress_alg = suppress_alg sim.verbosity = verbosity if usesens is True: # sensitivity sim.sensmethod = sensmethod sim.pbar = np.abs(p0) sim.suppress_sens = suppress_sens # Simulation # t, y, yd = sim.simulate(tfinal, ncp=(ncp - 1)) ncp_list = np.linspace(t0, tfinal, num=ncp, endpoint=True) t, y, yd = sim.simulate(tfinal, ncp=0, ncp_list=ncp_list) # Plot # sim.plot() # plt.figure() # plt.subplot(221) # plt.plot(t, y[:, 0], 'b.-') # plt.legend([r'$\lambda$']) # plt.subplot(222) # plt.plot(t, y[:, 1], 'r.-') # plt.legend([r'$\dot{\lambda}$']) # plt.subplot(223) # plt.plot(t, y[:, 2], 'k.-') # plt.legend([r'$\eta$']) # plt.subplot(224) # plt.plot(t, y[:, 3], 'm.-') # plt.legend([r'$\dot{\eta}$']) # plt.figure() # plt.subplot(221) # plt.plot(t, yd[:, 0], 'b.-') # plt.legend([r'$\dot{\lambda}$']) # plt.subplot(222) # plt.plot(t, yd[:, 1], 'r.-') # plt.legend([r'$\ddot{\lambda}$']) # plt.subplot(223) # plt.plot(t, yd[:, 2], 'k.-') # plt.legend([r'$\dot{\eta}$']) # plt.subplot(224) # plt.plot(t, yd[:, 3], 'm.-') # plt.legend([r'$\ddot{\eta}$']) # plt.figure() # plt.subplot(121) # plt.plot(y[:, 0], y[:, 1]) # plt.xlabel(r'$\lambda$') # plt.ylabel(r'$\dot{\lambda}$') # plt.subplot(122) # plt.plot(y[:, 2], y[:, 3]) # plt.xlabel(r'$\eta$') # plt.ylabel(r'$\dot{\eta}$') # plt.figure() # plt.subplot(121) # plt.plot(yd[:, 0], yd[:, 1]) # plt.xlabel(r'$\dot{\lambda}$') # plt.ylabel(r'$\ddot{\lambda}$') # plt.subplot(122) # plt.plot(yd[:, 2], yd[:, 3]) # plt.xlabel(r'$\dot{\eta}$') # plt.ylabel(r'$\ddot{\eta}$') # plt.figure() # plt.subplot(121) # plt.plot(y[:, 0], y[:, 2]) # plt.xlabel(r'$\lambda$') # plt.ylabel(r'$\eta$') # plt.subplot(122) # plt.plot(y[:, 1], y[:, 3]) # plt.xlabel(r'$\dot{\lambda}$') # plt.ylabel(r'$\dot{\eta}$') # plt.figure() # plt.subplot(121) # plt.plot(yd[:, 0], yd[:, 2]) # plt.xlabel(r'$\dot{\lambda}$') # plt.ylabel(r'$\dot{\eta}$') # plt.subplot(122) # plt.plot(yd[:, 1], yd[:, 3]) # plt.xlabel(r'$\ddot{\lambda}$') # plt.ylabel(r'$\ddot{\eta}$') # plt.show() sol = [t, y, yd] return sol
def run_example(with_plots=True): r""" This is the same example from the Sundials package (cvsRoberts_FSA_dns.c) Its purpose is to demonstrate the use of parameters in the differential equation. This simple example problem for IDA, due to Robertson see http://www.dm.uniba.it/~testset/problems/rober.php, is from chemical kinetics, and consists of the system: .. math:: \dot y_1 -( -p_1 y_1 + p_2 y_2 y_3)&=0 \\ \dot y_2 -(p_1 y_1 - p_2 y_2 y_3 - p_3 y_2^2)&=0 \\ \dot y_3 -( p_3 y_ 2^2)&=0 on return: - :dfn:`imp_mod` problem instance - :dfn:`imp_sim` solver instance """ 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 = N.array([1.0, 0.0, 0.0]) # Initial conditions for y yd0 = N.array([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.report_continuously = 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.title(imp_mod.name) P.xlabel('Time') P.ylabel('State') P.show() return imp_mod, imp_sim
def DAE_integration_assimulo(self, **kwargs): """ Perform time integration for DAEs with the assimulo package """ assert self.set_time_setting == 1, 'Time discretization must be specified first' if self.tclose > 0: close = True else: close = False # Control vector self.U = interpolate(self.boundary_cntrl_space, self.Vb).vector()[self.bndr_i_b] if self.discontinous_boundary_values == 1: self.U[self.Corner_indices] = self.U[self.Corner_indices]/2 # Definition of the sparse solver for the DAE res function to # be defined next M should be invertible !! my_solver = factorized(csc_matrix(self.M)) rhs = self.my_mult(self.J, self.my_mult(self.Q,self.A0)) + self.my_mult(self.Bext,self.U* self.boundary_cntrl_time(0.,self.tclose)) self.AD0 = my_solver(rhs) # Definition of the rhs function required in assimulo def res(t,y,yd): """ Definition of the residual function required in the DAE part of assimulo """ if close: if t < self.tclose: z = self.my_mult(self.M,yd) - self.my_mult(self.J, self.my_mult(self.Q,y)) - self.my_mult(self.Bext,self.U* self.boundary_cntrl_time(t,self.tclose)) else: z = self.my_mult(self.M,yd) - self.my_mult((self.J - self.R), self.my_mult(self.Q,y)) else: z = self.my_mult(self.M,yd) - self.my_mult(self.J, self.my_mult(self.Q,y)) - self.my_mult(self.Bext,self.U* self.boundary_cntrl_time(t,self.tclose)) return z # Definition of the jacobian function required in assimulo def jac(c,t,y,yd): """ Definition of the Jacobian matrix required in the DAE part of assimulo """ Matrix = csr_matrix(self.my_mult(self.J,self.Q)) if close and t > self.tclose: Matrix = csr_matrix(self.my_mult(self.J - self.R, self.Q)) return c*csr_matrix(self.M) - Matrix # Definition of the jacobian matrix vector function required in assimulo def jacv(t,y,yd,res,v,c): """ Jacobian matrix-vector product required in the DAE part of assimulo """ w = self.my_mult(self.Q, v) z = self.my_mult(self.J, w) if close and t > self.tclose: z -= self.my_mult(self.R, w) return c*self.my_mult(self.M,v) - z print('DAE Integration using assimulo built-in functions:') model = Implicit_Problem(res,self.A0,self.AD0,self.tinit) model.jacv = jacv #sim = Radau5DAE(model,**kwargs) # # IDA method from Assimulo # sim = IDA(model,**kwargs) sim.algvar = [1 for i in range(self.M.shape[0])] sim.atol = 1.e-6 sim.rtol = 1.e-6 sim.report_continuously = True ncp = self.Nt sim.usejac = True sim.suppress_alg = True sim.inith = self.dt sim.maxord = 5 #sim.linear_solver = 'SPGMR' time_span, DAE_y, DAE_yd = sim.simulate(self.tfinal,ncp) #print(sim.get_options()) print(sim.print_statistics()) A_dae = DAE_y.transpose() # Hamiltonian self.Nt = A_dae.shape[1] self.tspan = np.array(time_span) Ham_dae = np.zeros(self.Nt) for k in range(self.Nt): #Ham_dae[k] = 1/2 * A_dae[:,k] @ self.M @ self.Q @ A_dae[:,k] Ham_dae[k] = 1/2 * self.my_mult(A_dae[:,k].T, \ self.my_mult(self.M, self.my_mult(self.Q, A_dae[:,k]))) # Get q variables Aq_dae = A_dae[:self.Nq,:] # Get p variables Ap_dae = A_dae[self.Nq:,:] # Get Deformation Rho = np.zeros(self.Np) for i in range(self.Np): Rho[i] = self.rho(self.coord_p[i]) W_dae = np.zeros((self.Np,self.Nt)) theta = .5 for k in range(self.Nt-1): W_dae[:,k+1] = W_dae[:,k] + self.dt * 1/Rho[:] * ( theta * Ap_dae[:,k+1] + (1-theta) * Ap_dae[:,k] ) self.Ham_dae = Ham_dae return Aq_dae, Ap_dae, Ham_dae, W_dae, np.array(time_span)
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
#imp_mod.set_iapp( I_app/10. ) #imp_sim.make_consistent('IDA_YA_YDP_INIT') #ta, ya, yda = imp_sim.simulate(0.1,5) ## #imp_mod.set_iapp( I_app/2. ) #imp_sim.make_consistent('IDA_YA_YDP_INIT') #tb, yb, ydb = imp_sim.simulate(0.2,5) #imp_mod.set_iapp( I_app ) #imp_sim.make_consistent('IDA_YA_YDP_INIT') ## Sim step 1 #t1, y1, yd1 = imp_sim.simulate(1./Crate*3600.*0.2,100) imp_sim.display_progress = False imp_sim.verbosity = 50 imp_sim.report_continuously = True imp_sim.time_limit = 10. ### Simulate t01, t02 = 0.1, 0.2 imp_mod.set_iapp(I_app / 10.) imp_sim.make_consistent('IDA_YA_YDP_INIT') ta, ya, yda = imp_sim.simulate(t01, 2) imp_mod.set_iapp(I_app / 2.) imp_sim.make_consistent('IDA_YA_YDP_INIT') tb, yb, ydb = imp_sim.simulate(t02, 2) print 'yb shape', yb.shape
def DAE_integration_assimulo_lagrangian(self, **kwargs): """ Perform time integration for DAEs with the assimulo package Lagrangian variant """ assert self.set_time_setting == 1, 'Time discretization must be specified first' if self.tclose > 0: close = True else: close = False # Control vector self.U = interpolate(self.boundary_cntrl_space, self.Vl).vector()[self.bndr_i_l] if self.discontinous_boundary_values == 1: self.U[self.Corner_indices] = self.U[self.Corner_indices]/2 self.UU = np.zeros(self.Nb) for i in range(self.Nb): self.UU[i] = self.boundary_cntrl_space(self.coord_b[i]) # Definition of the sparse solver for the DAE res function to # be defined next M should be invertible !! #my_solver = factorized(csc_matrix(self.M)) #rhs = self.my_mult(self.J, self.my_mult(self.Q,self.A0)) + self.my_mult(self.Bext,self.U* self.boundary_cntrl_time(0.,self.tclose)) #self.AD0 = my_solver(rhs) # Definition of the rhs function required in assimulo def res(t,y,yd): """ Definition of the residual function required in the DAE part of assimulo """ z = np.zeros(self.Np+self.Nl) z[0:self.Np] = self.my_mult(self.M_class, yd[0:self.Np]) + self.my_mult(self.D_class, y[0:self.Np]) - self.my_mult(self.C_class, y[self.Np:]) z[self.Np:self.Np+self.Nl] = self.my_mult(self.C_class.T, y[0:self.Np]) - self.L_class * self.boundary_cntrl_time(t,self.tclose) return z # Definition of the jacobian function required in assimulo def jac(c,t,y,yd): """ Definition of the Jacobian matrix required in the DAE part of assimulo """ #Matrix = csr_matrix(self.my_mult(self.J,self.Q)) #if close and t > self.tclose: # Matrix = csr_matrix(self.my_mult(self.J - self.R, self.Q)) #return c*csr_matrix(self.M) - Matrix return None # Definition of the jacobian matrix vector function required in assimulo def jacv(t,y,yd,res,v,c): """ Jacobian matrix-vector product required in the DAE part of assimulo """ #w = self.my_mult(self.Q, v) #z = self.my_mult(self.J, w) #if close and t > self.tclose: # z -= self.my_mult(self.R, w) #return c*self.my_mult(self.M,v) - z return None print('DAE Integration using assimulo built-in functions:') #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 = np.concatenate(( self.Tp0, np.zeros(self.Nl) )) yd0 = np.zeros(self.Np + self.Nl) model = Implicit_Problem(res,y0,yd0,self.tinit) #model.handle_result = handle_result #model.jacv = jacv #sim = Radau5DAE(model,**kwargs) # # IDA method from Assimulo # sim = IDA(model,**kwargs) sim.algvar = list(np.concatenate((np.ones(self.Np), np.zeros(self.Nl) )) ) sim.atol = 1.e-6 sim.rtol = 1.e-6 sim.report_continuously = True ncp = self.Nt #sim.usejac = True sim.suppress_alg = True sim.inith = self.dt sim.maxord = 5 #sim.linear_solver = 'SPGMR' sim.make_consistent('IDA_YA_YDP_INIT') #time_span, DAE_y, DAE_yd = sim.simulate(self.tfinal,ncp, self.tspan) time_span, DAE_y, DAE_yd = sim.simulate(self.tfinal, 0, self.tspan) #print(sim.get_options()) print(sim.print_statistics()) A_dae = DAE_y[:,0:self.Np].transpose() # Hamiltonian self.Nt = A_dae.shape[1] self.tspan = np.array(time_span) Ham_dae = np.zeros(self.Nt) for k in range(self.Nt): Ham_dae[k] = 1/2 * self.my_mult(A_dae[:,k].T, \ self.my_mult(self.Mp_rho_Cv, A_dae[:,k])) self.Ham_dae = Ham_dae return Ham_dae, np.array(time_span)