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 test_ordinary_dae(self): """ This tests a simulation using JMIDAESens without any parameters. """ self.m_DAE = JMUModel('Pendulum_pack_Pendulum.jmu') self.DAE = JMIDAESens(self.m_DAE) sim = IDA(self.DAE) sim.simulate(1.0) nose.tools.assert_almost_equal(sim.y_sol[-1][0], 0.15420124, 4) nose.tools.assert_almost_equal(sim.y_sol[-1][1], 0.11721253, 4)
def run_example(): #initial values t0 = 0 y0 = np.array([0., -0.10344, -0.65, 0., 0. , 0., -0.628993, 0.047088]) #|phi_s| <= 0.1034 rad, |phi_b| <= 0.12 rad yd0 = np.array([0., 0., 0., 0., 0., 0., 0., 0.]) sw = [False, True, False] #problem model = Implicit_Problem(pecker, y0, yd0, t0, sw0=sw) model.state_events = state_events #from woodpecker.py model.handle_event = handle_event #from woodpecker.py model.name = 'Woodpeckermodel' sim = IDA(model) #create IDA solver tfinal = 2.0 #final time ncp = 500 #number control points sim.suppress_alg = True sim.rtol=1.e-6 sim.atol[6:8] = 1e6 sim.algvar[6:8] = 0 t, y, yd = sim.simulate(tfinal, ncp) #simulate #plot fig, ax = P.subplots() ax.plot(t, y[:, 0], label='z') legend = ax.legend(loc='upper center', shadow=True) P.grid() P.figure(1) fig2, ax2 = P.subplots() ax2.plot(t, y[:, 1], label='phi_s') ax2.plot(t, y[:, 2], label='phi_b') legend = ax2.legend(loc='upper center', shadow=True) P.grid() P.figure(2) fig3, ax3 = P.subplots() ax3.plot(t, y[:, 4], label='phi_sp') ax3.plot(t, y[:, 5], label='phi_bp') legend = ax3.legend(loc='upper center', shadow=True) P.grid() P.figure(3) fig4, ax4 = P.subplots() ax4.plot(t, y[:, 6], label='lambda_1') ax4.plot(t, y[:, 7], label='lambda_2') legend = ax4.legend(loc='upper right', shadow=True) P.grid() #event data sim.print_event_data() #show plots P.show() print("...") P.show()
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 main(): y0 = [1.0, 0.0, 0.0, 0.0, 5] yd0 = [0.0, 0.0, 0.0, -9.82, 0.0] # tout = [1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 5.0] tout = np.linspace(0.0, 10.0, 500) implicit_model = Implicit_Problem(res, y0, yd0, name="Example problem") # implicit_model.jac = jac implicit_model.algvar = [1.0, 1.0, 1.0, 1.0, 0.0] implicit_solver = IDA(implicit_model) implicit_solver.atol = 1E-6 implicit_solver.rtol = 1E-6 implicit_solver.suppress_alg = True implicit_solver.make_consistent("IDA_YA_YDP_INIT") t, y, yd = implicit_solver.simulate(10.0, ncp=500) plt.plot(t, y, linestyle="dashed", marker="o") plt.xlabel("Time") plt.ylabel("State") plt.title(implicit_model.name) plt.show()
np.real(b_par_x_min), \ np.imag(b_par_x_min), \ np.real(u_perp_x_min), \ np.imag(u_perp_x_min) )) dU_x_min = np.concatenate(( \ np.real(dux_x_min), \ np.imag(dux_x_min), \ np.real(db_par_x_min), \ np.imag(db_par_x_min), \ np.real(du_perp_x_min), \ np.imag(du_perp_x_min) )) model = Implicit_Problem(residual, U_x_min, dU_x_min, x_min) model.name = 'Pendulum' sim = IDA(model) # x,U,dU = sim.simulate(x_max, nx) # sim.plot() fig = plt.figure() ax = fig.add_subplot(111) ax.plot(x, vA(x, 0)) fig = plt.figure() ax = fig.add_subplot(111) ax.plot(x, np.real(ux_ana(x, 0))) ax.plot(x, np.imag(ux_ana(x, 0))) fig = plt.figure()
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
ux_x_min = ux_ana(x_min) b_par_x_min = b_par_ana(x_min) u_perp_x_min = u_perp_ana(x_min) dux_x_min = dux_ana(x_min) db_par_x_min = 0 du_perp_x_min = du_perp_ana(x_min) U_x_min = np.array([ np.real(ux_x_min), \ np.imag(ux_x_min), \ np.real(b_par_x_min), \ np.imag(b_par_x_min), \ np.real(u_perp_x_min), \ np.imag(u_perp_x_min) ]) dU_x_min = np.array([ \ np.real(dux_x_min), \ np.imag(dux_x_min), \ np.real(db_par_x_min), \ np.imag(db_par_x_min), \ np.real(du_perp_x_min), \ np.imag(du_perp_x_min) ]) model = Implicit_Problem(residual, U_x_min, dU_x_min, x_min) model.name = 'Pendulum' sim = IDA(model) x, U, dU = sim.simulate(x_min + 0.0000001, nx) sim.plot()
def __init__(self, residual_eval, solution, solution_dot, bc_eval, jacobian_eval, set_time): self.residual_eval = residual_eval self.solution = solution self.solution_dot = solution_dot self.bc_eval = bc_eval self.jacobian_eval = jacobian_eval self.set_time = set_time # We should be solving a square system self.sample_residual = residual_eval(0, self.solution, self.solution_dot) self.sample_jacobian = jacobian_eval(0, self.solution, self.solution_dot, 0.) assert self.sample_jacobian.M == self.sample_jacobian.N assert self.sample_jacobian.N == self.sample_residual.N # Storage for current BC self.current_bc = None # Define an Assimulo Implicit problem def _store_solution_and_solution_dot(t, solution, solution_dot): self.solution.vector()[:] = solution self.solution_dot.vector()[:] = solution_dot # Update current bc if self.bc_eval is not None: bcs_t = self.bc_eval(t) assert isinstance(bcs_t, (tuple, dict)) if isinstance(bcs_t, tuple): self.current_bc = DirichletBC(bcs_t) elif isinstance(bcs_t, dict): self.current_bc = DirichletBC(bcs_t, self.sample_residual._component_name_to_basis_component_index, self.solution.vector().N) else: raise TypeError("Invalid bc in _LinearSolver.__init__().") def _assimulo_residual_eval(t, solution, solution_dot): # Store current time self.set_time(t) # Convert to a matrix with one column, rather than an array _store_solution_and_solution_dot(t, solution, solution_dot) # Compute residual residual_vector = self.residual_eval(t, self.solution, self.solution_dot) # Apply BCs, if necessary if self.bc_eval is not None: self.current_bc.apply_to_vector(residual_vector, self.solution.vector()) # Convert to an array, rather than a matrix with one column, and return return residual_vector.__array__() def _assimulo_jacobian_eval(solution_dot_coefficient, t, solution, solution_dot): # Store current time self.set_time(t) # Convert to a matrix with one column, rather than an array _store_solution_and_solution_dot(t, solution, solution_dot) # Compute jacobian jacobian_matrix = self.jacobian_eval(t, self.solution, self.solution_dot, solution_dot_coefficient) # Apply BCs, if necessary if self.bc_eval is not None: self.current_bc.apply_to_matrix(jacobian_matrix) # Return return jacobian_matrix.__array__() self.problem = Implicit_Problem(_assimulo_residual_eval, self.solution.vector(), self.solution_dot.vector()) self.problem.jac = _assimulo_jacobian_eval # Define an Assimulo IDA solver self.solver = IDA(self.problem) self.solver.display_progress = False self.solver.verbosity = 50 # Additional storage which will be setup by set_parameters self._final_time = None self._initial_time = 0. self._max_time_steps = None self._monitor = None self._time_step_size = None
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 main(): SV_0 = solver_inputs.SV_0 SV_dot_0 = np.zeros_like(SV_0) algvar = solver_inputs.algvar # Close any open pyplot objects: plt.close('all') atol = np.ones_like(SV_0)*1e-8 rtol = 1e-4 # Start a timer: t_count = time.time() # Calculate the time span, which should be enough to charge or discharge fully # (i.e. 3600 seconds divided by the C-rate): t_0 = 0 t_f = 3600/Inputs.C_rate rate_tag = str(Inputs.C_rate)+"C" """----------Figures----------""" if Inputs.plot_profiles_flag: fig1, axes1, fig2, axes2, fig3, axes3 = setup_plots(plt, rate_tag) for cycle in np.arange(0, Inputs.n_cycles): """----------Equilibration----------""" # Equilibrate by integrating at zero current: print('\nEquilibrating...') # Create problem instance current.set_i_ext(0) battery_eq = li_ion(li_ion.res_fun, SV_0, SV_dot_0, t_0) battery_eq.external_event_detection = True battery_eq.algvar = algvar # Simulation parameters sim_eq = IDA(battery_eq) # Create simulation instance sim_eq.atol = atol # Solver absolute tolerance sim_eq.rtol = rtol # Solver relative tolerance sim_eq.verbosity = 50 sim_eq.make_consistent('IDA_YA_YDP_INIT') t_eq, SV_eq, SV_dot_eq = sim_eq.simulate(0.1*t_f) # Put solution into pandas dataframe with labeled columns SV_eq_df = Label_Columns(t_eq, SV_eq, an.npoints, sep.npoints, cat.npoints) # Obtain tag strings for dataframe columns tags = tag_strings(SV_eq_df) print('Done equilibrating\n') """------------Charging-------------""" print('\nCharging...') # New initial conditions are the final equilibrium conditions t_0 = 0 SV_0 = SV_eq[-1, :] SV_dot_0 = SV_dot_eq[-1 :] # Charge the battery current.set_i_ext(current.i_ext_set) # Create problem instance battery_ch = li_ion(li_ion.res_fun, SV_0, SV_dot_0, t_0) battery_ch.external_event_detection = True battery_ch.algvar = algvar # Simulation parameters sim_ch = IDA(battery_ch) sim_ch.atol = atol sim_ch.rtol = rtol sim_ch.verbosity = 50 sim_ch.make_consistent('IDA_YA_YDP_INIT') t_ch, SV_ch, SV_dot_ch = sim_ch.simulate(t_f) SV_ch_df = Label_Columns(t_ch, SV_ch, an.npoints, sep.npoints, cat.npoints) if Inputs.plot_potential_profiles == 1: plot_potential(tags['Phi_an'], tags['Phi_cat'], SV_ch_df, 'Charging', 0, fig1, axes1) if Inputs.plot_electrode_profiles == 1: plot_electrode(tags['X_an'], tags['X_cat'], SV_ch_df, 'Charging', 0, fig2, axes2) if Inputs.plot_elyte_profiles == 1: plot_elyte(tags['X_el_an'], tags['X_el_cat'], tags['X_el_sep'], SV_ch_df, 'Charging', 0, fig3, axes3) print('Done charging\n') """------------Re_equilibrating-------------""" if Inputs.flag_re_equil == 1: # New initial conditions are the final charge conditions SV_0 = SV_ch[-2, :] SV_dot_0 = SV_dot_ch[-2, :] # Equilibrate again. Note - this is a specific choice to reflect # equilibration after the charging steps. We may want, at times, to # simulate a situation where the battery is not equilibrated between # charge and discharge, or is equilibrated for a shorter amount of time. print('\nRe-equilibrating...') current.set_i_ext(0) battery_req = li_ion(li_ion.res_fun, SV_0, SV_dot_0, t_0) battery_req.external_event_detection = True battery_req.algvar = algvar # Simulation parameters sim_req = IDA(battery_req) sim_req.atol = atol sim_req.rtol = rtol sim_req.verbosity = 50 sim_req.make_consistent('IDA_YA_YDP_INIT') t_req, SV_req, SV_dot_req = sim_req.simulate(t_f) SV_req_df = Label_Columns(t_req, SV_req, an.npoints, sep.npoints, cat.npoints) if Inputs.plot_potential_profiles*Inputs.phi_time == 1: plot_potential(tags['Phi_an'], tags['Phi_cat'], SV_req_df, 'Re-equilibrating', 1, None, fig1, axes1) if Inputs.plot_electrode_profiles == 1: plot_electrode(tags['X_an'], tags['X_cat'], SV_req_df, 'Re-equilibrating', 1, fig2, axes2) if Inputs.plot_elyte_profiles == 1: plot_elyte(tags['X_el_an'], tags['X_el_cat'], tags['X_el_sep'], SV_req_df, 'Re-equilibrating', 1, fig3, axes3) print('Done re-equilibrating\n') else: SV_req = SV_ch SV_dot_req = SV_dot_ch SV_req_df = SV_req """------------Discharging-------------""" print('\nDischarging...') SV_0 = SV_req[-1, :] SV_dot_0 = SV_dot_req[-1, :] current.set_i_ext(-current.i_ext_set) battery_dch = li_ion(li_ion.res_fun, SV_0, SV_dot_0, t_0) battery_dch.external_event_detection = True battery_dch.algvar = algvar # Simulation parameters sim_dch = IDA(battery_dch) sim_dch.atol = atol sim_dch.rtol = rtol sim_dch.verbosity = 50 sim_dch.make_consistent('IDA_YA_YDP_INIT') t_dch, SV_dch, SV_dot_dch = sim_dch.simulate(t_f) SV_dch_df = Label_Columns(t_dch, SV_dch, an.npoints, sep.npoints, cat.npoints) if Inputs.plot_potential_profiles == 1: plot_potential(tags['Phi_an'], tags['Phi_cat'], SV_dch_df, 'Discharging', 1+(Inputs.flag_re_equil*Inputs.phi_time), fig1, axes1) if Inputs.plot_electrode_profiles == 1: plot_electrode(tags['X_an'], tags['X_cat'], SV_dch_df, 'Discharging', 1+Inputs.flag_re_equil, fig2, axes2) if Inputs.plot_elyte_profiles == 1: plot_elyte(tags['X_el_an'], tags['X_el_cat'], tags['X_el_sep'], SV_dch_df, 'Discharging', 1+Inputs.flag_re_equil, fig3, axes3) print('Done discharging\n') """---------------------------------""" SV_0 = SV_dch[-1, :] SV_dot_0 = np.zeros_like(SV_0) # %% Plot capacity if flagged plt.show('all') plot_cap(SV_ch_df, SV_dch_df, rate_tag, current.i_ext_set, Inputs.plot_cap_flag, tags) elapsed = time.time() - t_count print('t_cpu=', elapsed, '\n') plt.show() return SV_eq_df, SV_ch_df, SV_req_df, SV_dch_df
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 run_demo(with_plots=True): """ Model predicitve control of the Hicks-Ray CSTR reactor. This example demonstrates how to use the blocking factor feature of the collocation algorithm. This example also shows how to use classes for initialization, simulation and optimization directly rather than calling then through the high-level classes 'initialialize', 'simulate' and 'optimize'. """ curr_dir = os.path.dirname(os.path.abspath(__file__)) # Compile the stationary initialization model into a JMU jmu_name = compile_jmu("CSTR.CSTR_Init", os.path.join(curr_dir, "files", "CSTR.mop")) # Load a JMUModel instance init_model = JMUModel(jmu_name) # Create DAE initialization object. init_nlp = NLPInitialization(init_model) # Create an Ipopt solver object for the DAE initialization system init_nlp_ipopt = InitializationOptimizer(init_nlp) def compute_stationary(Tc_stat): init_model.set('Tc', Tc_stat) # Solve the DAE initialization system with Ipopt init_nlp_ipopt.init_opt_ipopt_solve() return (init_model.get('c'), init_model.get('T')) # Set inputs for Stationary point A Tc_0_A = 250 c_0_A, T_0_A = compute_stationary(Tc_0_A) # Print some data for stationary point A print(' *** Stationary point A ***') print('Tc = %f' % Tc_0_A) print('c = %f' % c_0_A) print('T = %f' % T_0_A) # Set inputs for Stationary point B Tc_0_B = 280 c_0_B, T_0_B = compute_stationary(Tc_0_B) # Print some data for stationary point B print(' *** Stationary point B ***') print('Tc = %f' % Tc_0_B) print('c = %f' % c_0_B) print('T = %f' % T_0_B) jmu_name = compile_jmu("CSTR.CSTR_Opt_MPC", os.path.join(curr_dir, "files", "CSTR.mop")) cstr = JMUModel(jmu_name) cstr.set('Tc_ref', Tc_0_B) cstr.set('c_ref', c_0_B) cstr.set('T_ref', T_0_B) cstr.set('cstr.c_init', c_0_A) cstr.set('cstr.T_init', T_0_A) # Initialize the mesh n_e = 50 # Number of elements hs = N.ones(n_e) * 1. / n_e # Equidistant points n_cp = 3 # Number of collocation points in each element # Create an NLP object # The length of the optimization interval is 50s and the # number of elements is 50, which gives a blocking factor # vector of 2*ones(n_e/2) to match the sampling interval # of 2s. nlp = ipopt.NLPCollocationLagrangePolynomials(cstr, n_e, hs, n_cp, blocking_factors=2 * N.ones(n_e / 2, dtype=N.int)) # Create an Ipopt NLP object nlp_ipopt = ipopt.CollocationOptimizer(nlp) nlp_ipopt.opt_coll_ipopt_set_int_option("max_iter", 500) h = 2. # Sampling interval T_final = 180. # Final time of simulation t_mpc = N.linspace(0, T_final, T_final / h + 1) n_samples = N.size(t_mpc) ref_mpc = N.zeros(n_samples) ref_mpc[0:3] = N.ones(3) * Tc_0_A ref_mpc[3:] = N.ones(n_samples - 3) * Tc_0_B cstr.set('cstr.c_init', c_0_A) cstr.set('cstr.T_init', T_0_A) # Compile the simulation model into a DLL jmu_name = compile_jmu("CSTR.CSTR", os.path.join(curr_dir, "files", "CSTR.mop")) # Load a model instance into Python sim_model = JMUModel(jmu_name) sim_model.set('c_init', c_0_A) sim_model.set('T_init', T_0_A) global cstr_mod global cstr_sim cstr_mod = JMIDAE(sim_model) # Create an Assimulo problem cstr_sim = IDA(cstr_mod) # Create an IDA solver i = 0 if with_plots: plt.figure(4) plt.clf() for t in t_mpc[0:-1]: Tc_ref = ref_mpc[i] c_ref, T_ref = compute_stationary(Tc_ref) cstr.set('Tc_ref', Tc_ref) cstr.set('c_ref', c_ref) cstr.set('T_ref', T_ref) # Solve the optimization problem nlp_ipopt.opt_coll_ipopt_solve() # Write to file. nlp.export_result_dymola() # Load the file we just wrote to file res = ResultDymolaTextual('CSTR_CSTR_Opt_MPC_result.txt') # Extract variable profiles c_res = res.get_variable_data('cstr.c') T_res = res.get_variable_data('cstr.T') Tc_res = res.get_variable_data('cstr.Tc') # Get the first Tc sample Tc_ctrl = Tc_res.x[0] # Set the value to the model sim_model.set('Tc', Tc_ctrl) # Simulate cstr_sim.simulate(t_mpc[i + 1]) t_T_sim = cstr_sim.t_sol # Set terminal values of the states cstr.set('cstr.c_init', cstr_sim.y[0]) cstr.set('cstr.T_init', cstr_sim.y[1]) sim_model.set('c_init', cstr_sim.y[0]) sim_model.set('T_init', cstr_sim.y[1]) if with_plots: plt.figure(4) plt.subplot(3, 1, 1) plt.plot(t_T_sim, N.array(cstr_sim.y_sol)[:, 0], 'b') plt.subplot(3, 1, 2) plt.plot(t_T_sim, N.array(cstr_sim.y_sol)[:, 1], 'b') if t_mpc[i] == 0: plt.subplot(3, 1, 3) plt.plot([t_mpc[i], t_mpc[i + 1]], [Tc_ctrl, Tc_ctrl], 'b') else: plt.subplot(3, 1, 3) plt.plot([t_mpc[i], t_mpc[i], t_mpc[i + 1]], [Tc_ctrl_old, Tc_ctrl, Tc_ctrl], 'b') Tc_ctrl_old = Tc_ctrl i = i + 1 assert N.abs(Tc_ctrl - 279.097186038194) < 1e-6 assert N.abs(N.array(cstr_sim.y_sol)[:, 0][-1] - 350.89028563) < 1e-6 assert N.abs(N.array(cstr_sim.y_sol)[:, 1][-1] - 283.15229948) < 1e-6 if with_plots: plt.figure(4) plt.subplot(3, 1, 1) plt.ylabel('c') plt.plot([0, T_final], [c_0_B, c_0_B], '--') plt.grid() plt.subplot(3, 1, 2) plt.ylabel('T') plt.plot([0, T_final], [T_0_B, T_0_B], '--') plt.grid() plt.subplot(3, 1, 3) plt.ylabel('Tc') plt.plot([0, T_final], [Tc_0_B, Tc_0_B], '--') plt.grid() plt.xlabel('t') plt.show()
def run_demo(with_plots=True): """ Model predicitve control of the Hicks-Ray CSTR reactor. This example demonstrates how to use the blocking factor feature of the collocation algorithm. This example also shows how to use classes for initialization, simulation and optimization directly rather than calling then through the high-level classes 'initialialize', 'simulate' and 'optimize'. """ curr_dir = os.path.dirname(os.path.abspath(__file__)); # Compile the stationary initialization model into a JMU jmu_name = compile_jmu("CSTR.CSTR_Init", os.path.join(curr_dir, "files", "CSTR.mop")) # Load a JMUModel instance init_model = JMUModel(jmu_name) # Create DAE initialization object. init_nlp = NLPInitialization(init_model) # Create an Ipopt solver object for the DAE initialization system init_nlp_ipopt = InitializationOptimizer(init_nlp) def compute_stationary(Tc_stat): init_model.set('Tc',Tc_stat) # Solve the DAE initialization system with Ipopt init_nlp_ipopt.init_opt_ipopt_solve() return (init_model.get('c'),init_model.get('T')) # Set inputs for Stationary point A Tc_0_A = 250 c_0_A, T_0_A = compute_stationary(Tc_0_A) # Print some data for stationary point A print(' *** Stationary point A ***') print('Tc = %f' % Tc_0_A) print('c = %f' % c_0_A) print('T = %f' % T_0_A) # Set inputs for Stationary point B Tc_0_B = 280 c_0_B, T_0_B = compute_stationary(Tc_0_B) # Print some data for stationary point B print(' *** Stationary point B ***') print('Tc = %f' % Tc_0_B) print('c = %f' % c_0_B) print('T = %f' % T_0_B) jmu_name = compile_jmu("CSTR.CSTR_Opt_MPC", os.path.join(curr_dir, "files", "CSTR.mop")) cstr = JMUModel(jmu_name) cstr.set('Tc_ref',Tc_0_B) cstr.set('c_ref',c_0_B) cstr.set('T_ref',T_0_B) cstr.set('cstr.c_init',c_0_A) cstr.set('cstr.T_init',T_0_A) # Initialize the mesh n_e = 50 # Number of elements hs = N.ones(n_e)*1./n_e # Equidistant points n_cp = 3; # Number of collocation points in each element # Create an NLP object # The length of the optimization interval is 50s and the # number of elements is 50, which gives a blocking factor # vector of 2*ones(n_e/2) to match the sampling interval # of 2s. nlp = ipopt.NLPCollocationLagrangePolynomials( cstr, n_e, hs, n_cp, blocking_factors=2*N.ones(n_e/2,dtype=N.int)) # Create an Ipopt NLP object nlp_ipopt = ipopt.CollocationOptimizer(nlp) nlp_ipopt.opt_coll_ipopt_set_int_option("max_iter",500) h = 2. # Sampling interval T_final = 180. # Final time of simulation t_mpc = N.linspace(0,T_final,T_final/h+1) n_samples = N.size(t_mpc) ref_mpc = N.zeros(n_samples) ref_mpc[0:3] = N.ones(3)*Tc_0_A ref_mpc[3:] = N.ones(n_samples-3)*Tc_0_B cstr.set('cstr.c_init',c_0_A) cstr.set('cstr.T_init',T_0_A) # Compile the simulation model into a DLL jmu_name = compile_jmu("CSTR.CSTR", os.path.join(curr_dir, "files", "CSTR.mop")) # Load a model instance into Python sim_model = JMUModel(jmu_name) sim_model.set('c_init',c_0_A) sim_model.set('T_init',T_0_A) global cstr_mod global cstr_sim cstr_mod = JMIDAE(sim_model) # Create an Assimulo problem cstr_sim = IDA(cstr_mod) # Create an IDA solver i = 0 if with_plots: plt.figure(4) plt.clf() for t in t_mpc[0:-1]: Tc_ref = ref_mpc[i] c_ref, T_ref = compute_stationary(Tc_ref) cstr.set('Tc_ref',Tc_ref) cstr.set('c_ref',c_ref) cstr.set('T_ref',T_ref) # Solve the optimization problem nlp_ipopt.opt_coll_ipopt_solve() # Write to file. nlp.export_result_dymola() # Load the file we just wrote to file res = ResultDymolaTextual('CSTR_CSTR_Opt_MPC_result.txt') # Extract variable profiles c_res = res.get_variable_data('cstr.c') T_res = res.get_variable_data('cstr.T') Tc_res = res.get_variable_data('cstr.Tc') # Get the first Tc sample Tc_ctrl = Tc_res.x[0] # Set the value to the model sim_model.set('Tc',Tc_ctrl) # Simulate cstr_sim.simulate(t_mpc[i+1]) t_T_sim = cstr_sim.t_sol # Set terminal values of the states cstr.set('cstr.c_init',cstr_sim.y[0]) cstr.set('cstr.T_init',cstr_sim.y[1]) sim_model.set('c_init',cstr_sim.y[0]) sim_model.set('T_init',cstr_sim.y[1]) if with_plots: plt.figure(4) plt.subplot(3,1,1) plt.plot(t_T_sim,N.array(cstr_sim.y_sol)[:,0],'b') plt.subplot(3,1,2) plt.plot(t_T_sim,N.array(cstr_sim.y_sol)[:,1],'b') if t_mpc[i]==0: plt.subplot(3,1,3) plt.plot([t_mpc[i],t_mpc[i+1]],[Tc_ctrl,Tc_ctrl],'b') else: plt.subplot(3,1,3) plt.plot( [t_mpc[i],t_mpc[i],t_mpc[i+1]], [Tc_ctrl_old,Tc_ctrl,Tc_ctrl], 'b') Tc_ctrl_old = Tc_ctrl i = i+1 assert N.abs(Tc_ctrl - 279.097186038194) < 1e-6 assert N.abs(N.array(cstr_sim.y_sol)[:,0][-1] - 350.89028563) < 1e-6 assert N.abs(N.array(cstr_sim.y_sol)[:,1][-1] - 283.15229948) < 1e-6 if with_plots: plt.figure(4) plt.subplot(3,1,1) plt.ylabel('c') plt.plot([0,T_final],[c_0_B,c_0_B],'--') plt.grid() plt.subplot(3,1,2) plt.ylabel('T') plt.plot([0,T_final],[T_0_B,T_0_B],'--') plt.grid() plt.subplot(3,1,3) plt.ylabel('Tc') plt.plot([0,T_final],[Tc_0_B,Tc_0_B],'--') plt.grid() plt.xlabel('t') plt.show()
class ReactorSolverAssimulo(ReactorSolverBase): def __init__(self,reactor,**params): #Initialize base solver class ReactorSolverBase.__init__(self,reactor,**params) #### SOLVER PARAMETERS ####: self.iter = params.get('iter','Newton') #Iteration method (Newton or FixedPoint) self.discr = params.get('discr','BDF') #Discretization method (BDF or Adams) #Set up the linear solver from the following list: # ['DENSE'(= default) or 'SPGMR'] self.linear_solver = params.get('linear_solver','DENSE') #Boolean value to turn OFF Sundials LineSearch when calculating #initial conditions (IDA only) self.lsoff = params.get('lsoff',False) def solve_ode(self): #Get initial conditions vector self.init_conditions() #Instantiate reactor as ODE class self._rode = AssimuloODE(self._r,self._r.z_in,self.y0) #Define the CVode solver self.solver = CVode(self._rode) #Solver parameters self.solver.atol = self.atol self.solver.rtol = self.rtol self.solver.iter = self.iter self.solver.discr = self.discr self.solver.linear_solver = self.linear_solver self.solver.maxord = self.order self.solver.maxsteps = self.max_steps self.solver.inith = self.first_step_size self.solver.minh = self.min_step_size self.solver.maxh = self.max_step_size self.solver.maxncf = self.max_conv_fails self.solver.maxnef = self.max_nonlin_iters self.solver.stablimdet = self.bdf_stability self.solver.verbosity = 50 #Solve the equations z, self.values = self.solver.simulate(self._r.z_out,self.grid-1) #Convert axial coordinates list to array self._z = np.array(z) def solve_dae(self): #Get initial conditions vector self.init_conditions() #Initial derivatives vector self.yd0 = np.zeros(len(self.y0)) #Instantiate reactor as DAE class self._rdae = AssimuloDAE(self._r,self._r.z_in, self.y0,self.yd0) #Get list of differential and algebraic variables varlist = np.ones(len(self.y0)) #Set algebraic variables varlist[self._rdae.p1:] = 0.0 #Set up the solver and its parameters self.solver = IDA(self._rdae) self.solver.atol = self.atol self.solver.rtol = self.rtol self.solver.linear_solver = self.linear_solver self.solver.maxord = self.order self.solver.maxsteps = self.max_steps self.solver.inith = self.first_step_size self.solver.maxh = self.max_step_size self.solver.algvar = varlist self.solver.make_consistent('IDA_YA_YDP_INIT') self.solver.tout1 = 1e-06 self.solver.suppress_alg = self.exclude_algvar_from_error self.solver.lsoff = self.lsoff self.solver.verbosity = 50 #Solve the DAE equation system z, self.values, self.valuesd = self.solver.simulate(self._r.z_out, self.grid-1) #Convert axial coordinates list to array self._z = np.array(z)
def initialize_ode_solver(self, y_0, yd_0, t_0): model = Implicit_Problem(self.residual, y_0, yd_0, t_0) #model.state_events = self.state_events #model.handle_events = self.handle_event 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.maxsteps = self.max_steps solver.num_threads = 3 #solver.display_progress = True return solver
from sei_1d_functions import residual from sei_1d_functions import df_2spec2var import cantera as ct from assimulo.solvers import IDA from assimulo.problem import Implicit_Problem print('\n Importing inputs and intializing.') from sei_1d_init import SV_0, SV_dot_0, SVptr, times, objs, params, \ voltage_lookup print('\n Running simulation\n') # Set up problem instance SEI_1D = Implicit_Problem(residual, SV_0, SV_dot_0) # Define simulation parameters simulation = IDA(SEI_1D) # Create simulation instance simulation.atol = 1e-7 # Solver absolute tolerance simulation.rtol = 1e-4 # Solver relative tolerance #simulation.maxh = 0.1 # Solver max step size # Set simulation end time, slope flag (for anode voltage cycle), and run simulation t_f = times[-1] #ncp_list = np.arange(0, t_f, 0.15) #ncp = 10000 # Run simulation t, SV, SV_dot = simulation.simulate(t_f) # %% Organize data and plot
def run_example(): def residual(t,y,yd): return squeezer(t, y, yd) def residual2(t,y,yd): return squeezer2(t, y, yd) #The initial conditons t0 = 0 y0, yd0 = init_squeezer() model = Implicit_Problem(residual, y0, yd0, t0) #Create an Assimulo problem model2 = Implicit_Problem(residual2, y0, yd0, t0) #Create an Assimulo problem sim = IDA(model) #Create the IDA solver sim2 = IDA(model2) #Create the IDA solver # index 3 sim.algvar = 7*[True] + 7*[False] + 6*[False] sim.suppress_alg = True sim.atol = 7*[1e-6] + 7*[1e5] + 6*[1e5] # index 2 sim2.algvar = 7*[True] + 7*[True] + 6*[False] sim2.suppress_alg = True sim2.atol = 7*[1e-6] + 7*[1e-6] + 6*[1e5] tfinal = 0.03 #Specify the final time ncp = 500 #Number of communcation points (number of return points) t,y,yd = sim.simulate(tfinal, ncp) #Use the .simulate method to simulate and provide the final time and ncp (optional) t2,y2,yd2 = sim2.simulate(tfinal, ncp) #Use the .simulate method to simulate and provide the final time and ncp (optional) print("500####################") print("####################") fig, ax = P.subplots() P.title('IDA, difference between index 3 and index 2 formulation') P.xlabel('Time') P.ylabel('Angle') #P.ylabel('Step size') #P.axis([0, tfinal + 0.01, -0.7, 0.7]) #P.plot(t[1:], np.diff(t)) #P.plot(t, y[:, 0], label='beta') #P.plot(t, y[:, 1], label='theta') #P.plot(t, y[:, 2], label='gamma') #P.plot(t, y[:, 3], label='phi') #P.plot(t, y[:, 4], label='delta') #P.plot(t, y[:, 5], label='omega') #P.plot(t, y[:, 6], label='epsilon') P.plot(t, y[:, 0] - y2[:, 0], label='beta') P.plot(t, y[:, 1] - y2[:, 1], label='theta') P.plot(t, y[:, 2] - y2[:, 2], label='gamma') P.plot(t, y[:, 3] - y2[:, 3], label='phi') P.plot(t, y[:, 4] - y2[:, 4], label='delta') P.plot(t, y[:, 5] - y2[:, 5], label='omega') #P.plot(t, y[:, 6], label='epsilon') legend = ax.legend(shadow=True, loc = 'upper left') ''' P.plot(t, y[:, 14]) P.plot(t, y[:, 15]) P.plot(t, y[:, 16]) P.plot(t, y[:, 17]) P.plot(t, y[:, 18]) P.plot(t, y[:, 19]) P.axis([0, tfinal, -100, 200]) ''' P.grid() P.show()
# State IV => State III if solver.sw[3]: solver.sw[3] = not solver.sw[3] solver.sw[2] = not solver.sw[2] y0,yp0 = init_woodpecker() t0 = 0.0 sw0 = np.array([1,0,0,0]) model = Implicit_Problem(woodpecker,y0,yp0,t0,sw0) model.state_events = state_events model.handle_event = handle_event solver = IDA(model) solver.simulate(3)
def run_example(with_plots=True): r""" An example for IDA 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 &= 0\\ \dot y_2 -9.82 &= 0 on return: - :dfn:`imp_mod` problem instance - :dfn:`imp_sim` solver instance """ #Defines the residual def res(t, y, yd): res_0 = yd[0] - y[1] res_1 = yd[1] + 9.82 return N.array([res_0, res_1]) #Defines the Jacobian*vector product def jacv(t, y, yd, res, v, c): jy = N.array([[0, -1.], [0, 0]]) jyd = N.array([[1, 0.], [0, 1]]) j = jy + c * jyd return N.dot(j, v) #Initial conditions y0 = [1.0, 0.0] yd0 = [0.0, -9.82] #Defines an Assimulo implicit problem imp_mod = Implicit_Problem( res, y0, yd0, name='Example using the Jacobian Vector product') imp_mod.jacv = jacv #Sets the jacobian imp_sim = IDA(imp_mod) #Create an IDA solver instance #Set the parameters imp_sim.atol = 1e-5 #Default 1e-6 imp_sim.rtol = 1e-5 #Default 1e-6 imp_sim.linear_solver = 'SPGMR' #Change linear solver #imp_sim.options["usejac"] = False #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], -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(imp_mod.name) P.show() return imp_mod, imp_sim
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)
yp[5] = -f[5] / Iv # Check Jacobian g = jac(0.1, t, y, yp) isNotValid = isnan(g).any() if isNotValid == True: raise ValueError('Please check initial conditions. Jacobian has NaN.\n') # Create an Assimulo implicit problem imp_mod = Implicit_Problem(res, y, yp) imp_mod.jac = jac # Sets the jacobian # Sets the options to the problem # Create an Assimulo implicit solver (IDA) imp_sim = IDA(imp_mod) # Create a IDA solver imp_sim.algvar = [1.0, 1.0, 1.0, 1.0, 1.0, 1.0] imp_sim.suppress_alg = True # Let Sundials find consistent initial conditions by use of 'IDA_YA_YDP_INIT' imp_sim.make_consistent('IDA_YA_YDP_INIT') # Simulate 4*pi seconds with 1000 communication points endtime = eval(params['endtime']) N = params['timepoints'] t_sol, y_sol, yd_sol = imp_sim.simulate(endtime, N) t = array(t_sol) # Save results outputfile = params['Output'] # Output file name
y0 = numpy.array([0.5, 0,0, -0, w0, w0,-1e-4,0]) yd0 = numpy.array([-0, w0, w0,-g, 1e-12, 0, 0, 0]) #y0 = numpy.array([4.83617428e-01, -3.00000000e-02, -2.16050178e-01, 1.67315232e-16, -5.39725367e-14, -1.31300925e+01, -7.20313572e-02, -6.20545138e-02]) #yd0 = numpy.array([1.55140566e-17, -5.00453439e-15, -1.31302838e+01, 6.62087352e-13, -2.13577297e-10, 2.21484026e+02, -4.67637454e+00, -2.89824658e+00]) #startsw = [0,1, 0, 0] problem = Implicit_Problem(res, y0, yd0, t0, sw0=startsw) problem.state_events = state_events problem.handle_event = handle_event problem.name = 'Woodpecker' phipIndex = [4, 5] lambdaIndex = [6, 7] sim = IDA(problem) sim.rtol = 1e-6 sim.atol[phipIndex] = 1e8 sim.algvar[phipIndex] = 1 sim.atol[lambdaIndex] = 1e8 sim.algvar[lambdaIndex] = 1 sim.suppress_alg = True ncp = 500 tfinal = 2 t, y, yd = sim.simulate(tfinal, ncp) y = y[:,[ 0, ]] plt.plot(t, y) plt.legend(["z", "phi_s", "phi_b", "zp", "phip_s", "phip_b", "lambda_2", "lambda_2"], loc = 'lower left')
def main(): res_class = eval(inputs.test_type) # plt.close('all') t_count = time.time() SV_0 = sol_init.SV_0 SV_dot_0 = np.zeros_like(SV_0) t_0 = 0. t_f = 3600. / inputs.C_rate #63006.69900049 93633 algvar = sol_init.algvar atol = np.ones_like(SV_0) * 1e-6 atol[cat.ptr_vec['eps_S8']] = 1e-15 atol[cat.ptr_vec['eps_Li2S']] = 1e-15 atol[cat.ptr_vec['rho_k_el']] = 1e-16 # 1e-16 for Bessler rtol = 1e-6 sim_output = 50 rtol_ch = 1e-6 atol_ch = np.ones_like(SV_0) * 1e-6 atol_ch[cat.ptr_vec['eps_S8']] = 1e-15 atol_ch[cat.ptr_vec['eps_Li2S']] = 1e-15 atol_ch[cat.ptr_vec['rho_k_el']] = 1e-30 rate_tag = str(inputs.C_rate) + "C" # if 'cascade' in inputs.ctifile: # ncols = 2 + inputs.flag_req # else: ncols = 1 + inputs.flag_req fig, axes = plt.subplots(sharey="row", figsize=(9, 12), nrows=3, ncols=(ncols) * inputs.n_cycles, num=1) plt.subplots_adjust(wspace=0.15, hspace=0.4) fig.text(0.35, 0.85, rate_tag, fontsize=20, bbox=dict(facecolor='white', alpha=0.5)) # Set up user function to build figures based on inputs "----------Equilibration----------" print('\nEquilibrating...') # Set external current to 0 for equilibration cat.set_i_ext(0) # cat.nucleation_flag = 1 # Create problem object bat_eq = res_class(res_class.res_fun, SV_0, SV_dot_0, t_0) bat_eq.external_event_detection = True bat_eq.algvar = algvar # Create simulation object sim_eq = IDA(bat_eq) sim_eq.atol = atol sim_eq.rtol = rtol sim_eq.verbosity = sim_output sim_eq.make_consistent('IDA_YA_YDP_INIT') t_eq, SV_eq, SV_dot_eq = sim_eq.simulate(t_f) # Put solution into pandas dataframe with labeled columns SV_eq_df = label_columns(t_eq, SV_eq, an.npoints, sep.npoints, cat.npoints) # Obtain tag strings for dataframe columns tags = tag_strings(SV_eq_df) # plot_sim(tags, SV_eq_df, 'Equilibrating', 0, fig, axes) t_equilibrate = time.time() - t_count print("Equilibration time = ", t_equilibrate, '\n') print('Done equilibrating\n') for cycle_num in np.arange(0, inputs.n_cycles): "------------Discharging-------------" print('Discharging...') # cat.np_L = inputs.np_Li2S_init cat.nucleation_flag = np.zeros((inputs.npoints_cathode, 1)) # New initial conditions from previous simulation if cycle_num == 0: # SV_0 = SV_0 SV_0 = SV_eq[-1, :] # SV_dot_0 = SV_dot_0 SV_dot_0 = SV_dot_eq[-1, :] else: SV_0 = SV_0_cycle SV_dot_0 = SV_dot_0_cycle # Set external current cat.set_i_ext(cat.i_ext_amp) # Update problem instance initial conditions bat_dch = res_class(res_class.res_fun, SV_0, SV_dot_0, t_0) bat_dch.external_event_detection = True bat_dch.algvar = algvar # Re-initialize simulation object sim_dch = IDA(bat_dch) sim_dch.atol = atol sim_dch.rtol = rtol # sim_dch.maxh = 57 sim_dch.verbosity = sim_output sim_dch.make_consistent('IDA_YA_YDP_INIT') t_dch, SV_dch, SV_dot_dch = sim_dch.simulate(131865.32) SV_dch_df = label_columns(t_dch, SV_dch, an.npoints, sep.npoints, cat.npoints) # Obtain tag strings for dataframe columns tags = tag_strings(SV_dch_df) plot_sim(tags, SV_dch_df, 'Discharging', 0 + 2 * cycle_num, fig, axes) # plot_meanPS(SV_dch_df, tags, 'Discharging') print('Done Discharging\n') "--------Re-equilibration---------" if inputs.flag_req == 1: print('Re-equilibrating...') # New initial conditions from previous simulation SV_0 = SV_dch[-1, :] SV_dot_0 = SV_dot_dch[-1, :] # Set external current cat.set_i_ext(0) # Update problem instance initial conditions bat_req = res_class(res_class.res_fun, SV_0, SV_dot_0, t_0) bat_req.external_event_detection = True bat_req.algvar = algvar # Re-initialize simulation object sim_req = IDA(bat_req) sim_req.atol = atol sim_req.rtol = rtol sim_req.verbosity = sim_output sim_req.make_consistent('IDA_YA_YDP_INIT') t_req, SV_req, SV_dot_req = sim_req.simulate(t_f) SV_req_df = label_columns(t_req, SV_req, an.npoints, sep.npoints, cat.npoints) # plot_sim(tags, SV_req_df, 'Re-Equilibrating', 1, fig, axes) print('Done re-equilibrating\n') else: SV_req = SV_dch SV_dot_req = SV_dot_dch "-----------Charging-----------" if 'dog' in inputs.ctifile: print('Charging...') SV_0 = SV_req[-1, :] SV_dot_0 = SV_dot_req[-1, :] SV_0[cat.ptr_vec['eps_S8']] = cat.eps_cutoff cat.set_i_ext(-cat.i_ext_amp) # Update problem instance initial conditions bat_ch = res_class(res_class.res_fun, SV_0, SV_dot_0, t_0) bat_ch.external_event_detection = True bat_ch.algvar = algvar # Re-initialize simulation object sim_ch = IDA(bat_ch) sim_ch.atol = atol_ch sim_ch.rtol = rtol_ch if cycle_num > 0: sim_ch.maxh = 0.1 sim_ch.verbosity = sim_output sim_ch.make_consistent('IDA_YA_YDP_INIT') t_ch, SV_ch, SV_dot_ch = sim_ch.simulate(t_f) SV_ch_df = label_columns(t_ch, SV_ch, an.npoints, sep.npoints, cat.npoints) plot_sim(tags, SV_ch_df, 'Charging', 1 + inputs.flag_req + 2 * cycle_num, fig, axes) plot_meanPS(SV_ch_df, tags, 'Charging') SV_ch_df = 0 # # print('Max S_8(e) concentration = ', max(SV_ch[:, 6])) # SV_0_cycle = SV_ch[-1, :] # SV_dot_0_cycle = SV_ch[-1, :] print('Done Charging\n') exp_data_01C = pd.read_csv(r'0.1C Data.csv', header=None) exp_data_05C = pd.read_csv(r'0.5C Data.csv', header=None) exp_data_1C = pd.read_csv(r'1C Data.csv', header=None) Bessler = pd.read_csv(r'Bessler Dennis Data.csv', header=None) SV_copy = SV_dch_df.copy() SV_copy.loc[:, 'Time'] *= -cat.i_ext_amp * inputs.A_cat / 3600 / ( cat.m_S_tot_0) "Set up your figure" fig = plt.figure(3) ax = fig.add_axes([0.2, 0.2, 0.6, 0.75]) fig.set_size_inches((10., 5.0)) # ax2 = ax.twinx() "Formatting for the figure:" fs = 20 #font size for plots lw = 3.0 #line width for plots # font = plt.matplotlib.font_manager.FontProperties(family='Times New Roman',size=fs-1) for tick in ax.xaxis.get_major_ticks(): tick.label1.set_fontsize(fs) tick.label1.set_fontname('Times New Roman') for tick in ax.yaxis.get_major_ticks(): tick.label1.set_fontsize(fs) tick.label1.set_fontname('Times New Roman') color = matplotlib.cm.plasma(inputs.C_rate) p1, = plt.plot(SV_copy.loc[:, 'Time'], SV_copy.loc[:, 'Phi_ed1'], 'k-', linewidth=lw) # p2, = plt.plot(exp_data_01C.iloc[:,0], exp_data_01C.iloc[:,1], 'ro') # p3, = plt.plot(exp_data_05C.iloc[:,0], exp_data_05C.iloc[:,1], 'co') # p4, = plt.plot(exp_data_1C.iloc[:,0], exp_data_1C.iloc[:,1], 'ko') p5, = plt.plot(Bessler.iloc[:, 0], Bessler.iloc[:, 1], 'mo', ms=4) plt.xlim((0, 1700)) plt.xticks([0, 400, 800, 1200, 1600]) plt.ylim((1.8, 2.6)) plt.ylabel(r'Cell Voltage $[\mathrm{V}]$', fontstyle='normal', fontname='Times new Roman', fontsize=fs + 2, labelpad=5.0) plt.xlabel( r'Capacity $[\mathrm{Ah} \hspace{0.5} \mathrm{kg}^{-1}_{\mathrm{sulfur}}]$', fontstyle='normal', fontname='Times new Roman', fontsize=fs + 2, labelpad=5.0) # plt.legend(["Discharge", "Charge"]) file_name_dch = 'dch' + str(inputs.C_rate) + "C_" + inputs.mech + '.csv' SV_dch = SV_dch_df.copy() SV_dch.loc[:, 'Time'] *= -cat.i_ext_amp * inputs.A_cat / 3600 / (cat.m_S_0 + cat.m_S_el) SV_dch.to_csv(file_name_dch, index=False, header=True) t_elapsed = time.time() - t_count print('t_cpu=', t_elapsed, '\n') return SV_eq_df, SV_dch_df, SV_ch_df, tags
posIndex = list(range(0,7)) velocityIndex = list(range(7,14)) lambdaIndex = list(range(14,20)) algvar = numpy.ones(numpy.size(y0)) indexNumber = 1 #1 - expl runge - index1 solution #2 - index2 #3 - index3 if indexNumber == 3: problem = Implicit_Problem(squeezer3, y0, yd0, t0) algvar[lambdaIndex] = 0 algvar[velocityIndex] = 0 sim = IDA(problem) sim.atol = numpy.ones(numpy.size(y0))*1e-7 sim.atol[lambdaIndex] = 1e-1 sim.atol[velocityIndex] = 1e-5 elif indexNumber == 2: problem = Implicit_Problem(squeezer2, y0, yd0, t0) algvar[lambdaIndex] = 0 algvar[velocityIndex] = 1 sim = IDA(problem) sim.atol = numpy.ones(numpy.size(y0))*1e-7 sim.atol[lambdaIndex] = 1e-5 sim.atol[velocityIndex] = 1e-5 elif indexNumber == 1: problem = Explicit_Problem(squeezer1, y0[0:14], t0) sim = RungeKutta34(problem) sim.atol = numpy.ones(14)*1e-7
class _AssimuloIDA(object): def __init__(self, residual_eval, solution, solution_dot, bc_eval, jacobian_eval, set_time): self.residual_eval = residual_eval self.solution = solution self.solution_dot = solution_dot self.bc_eval = bc_eval self.jacobian_eval = jacobian_eval self.set_time = set_time # We should be solving a square system self.sample_residual = residual_eval(0, self.solution, self.solution_dot) self.sample_jacobian = jacobian_eval(0, self.solution, self.solution_dot, 0.) assert self.sample_jacobian.M == self.sample_jacobian.N assert self.sample_jacobian.N == self.sample_residual.N # Storage for current BC self.current_bc = None # Define an Assimulo Implicit problem def _store_solution_and_solution_dot(t, solution, solution_dot): self.solution.vector()[:] = solution self.solution_dot.vector()[:] = solution_dot # Update current bc if self.bc_eval is not None: bcs_t = self.bc_eval(t) assert isinstance(bcs_t, (tuple, dict)) if isinstance(bcs_t, tuple): self.current_bc = DirichletBC(bcs_t) elif isinstance(bcs_t, dict): self.current_bc = DirichletBC(bcs_t, self.sample_residual._component_name_to_basis_component_index, self.solution.vector().N) else: raise TypeError("Invalid bc in _LinearSolver.__init__().") def _assimulo_residual_eval(t, solution, solution_dot): # Store current time self.set_time(t) # Convert to a matrix with one column, rather than an array _store_solution_and_solution_dot(t, solution, solution_dot) # Compute residual residual_vector = self.residual_eval(t, self.solution, self.solution_dot) # Apply BCs, if necessary if self.bc_eval is not None: self.current_bc.apply_to_vector(residual_vector, self.solution.vector()) # Convert to an array, rather than a matrix with one column, and return return residual_vector.__array__() def _assimulo_jacobian_eval(solution_dot_coefficient, t, solution, solution_dot): # Store current time self.set_time(t) # Convert to a matrix with one column, rather than an array _store_solution_and_solution_dot(t, solution, solution_dot) # Compute jacobian jacobian_matrix = self.jacobian_eval(t, self.solution, self.solution_dot, solution_dot_coefficient) # Apply BCs, if necessary if self.bc_eval is not None: self.current_bc.apply_to_matrix(jacobian_matrix) # Return return jacobian_matrix.__array__() self.problem = Implicit_Problem(_assimulo_residual_eval, self.solution.vector(), self.solution_dot.vector()) self.problem.jac = _assimulo_jacobian_eval # Define an Assimulo IDA solver self.solver = IDA(self.problem) self.solver.display_progress = False self.solver.verbosity = 50 # Additional storage which will be setup by set_parameters self._final_time = None self._initial_time = 0. self._max_time_steps = None self._monitor = None self._time_step_size = None def set_parameters(self, parameters): for (key, value) in parameters.items(): if key == "absolute_tolerance": self.solver.atol = value elif key == "final_time": self._final_time = value elif key == "initial_time": self._initial_time = value elif key == "integrator_type": assert value == "ida" elif key == "max_time_steps": self.solver.maxsteps = value self._max_time_steps = value elif key == "monitor": self._monitor = value elif key == "nonlinear_solver": for (key_nonlinear, value_nonlinear) in value.items(): if key_nonlinear == "absolute_tolerance": self.solver.atol = value_nonlinear elif key_nonlinear == "line_search": raise NotImplementedError("This feature has not been implemented in IDA.") elif key_nonlinear == "maximum_iterations": raise NotImplementedError("This feature has not been implemented in IDA.") elif key_nonlinear == "relative_tolerance": self.solver.rtol = value elif key_nonlinear == "report": raise NotImplementedError("This feature has not been implemented in IDA.") elif key_nonlinear == "solution_tolerance": raise NotImplementedError("This feature has not been implemented in IDA.") else: raise ValueError("Invalid paramater passed to _AssimuloIDA object.") elif key == "problem_type": pass elif key == "relative_tolerance": self.solver.rtol = value elif key == "report": self.solver.verbosity = 10 self.solver.display_progress = True self.solver.report_continuously = True elif key == "time_step_size": self.solver.inith = value self._time_step_size = value else: raise ValueError("Invalid paramater passed to _AssimuloIDA object.") def solve(self): assert self._max_time_steps is not None or self._time_step_size is not None if self._time_step_size is not None: all_t = [0] all_t_arange = self._time_step_size + arange(self._initial_time, self._final_time, self._time_step_size) all_t.extend(all_t_arange.tolist()) elif self._max_time_steps is not None: all_t = linspace(self._initial_time, self._final_time, num=self._max_time_steps+1) all_t = all_t.tolist() for ida_trial in range(5): try: all_times, all_solutions, all_solutions_dot = self.solver.simulate(self._final_time, ncp_list=all_t) except IDAError as error: if str(error) == "'Error test failures occurred too many times during one internal time step or minimum step size was reached. At time 0.000000.'": # There is no way to increase the number of error test failures in the assimulo interface, try again with smaller inith self.solver.inith /= 10. else: # There was an error, but we cannot handle it. Raise it again raise else: break # Convert all_solutions to a list of Function all_solutions_as_functions = list() all_solutions_dot_as_functions = list() for (t, solution) in zip(all_times, all_solutions): self.solution.vector()[:] = solution all_solutions_as_functions.append(function_copy(self.solution)) if len(all_solutions_as_functions) > 1: # monitor is being called at t > 0. self.solution_dot.vector()[:] = (all_solutions_as_functions[-1].vector() - all_solutions_as_functions[-2].vector())/self._time_step_size else: self.solution_dot.vector()[:] = all_solutions_dot[0] all_solutions_dot_as_functions.append(function_copy(self.solution_dot)) if self._monitor is not None: self._monitor(t, self.solution, self.solution_dot) self.solution.vector()[:] = all_solutions_as_functions[-1].vector() self.solution_dot.vector()[:] = all_solutions_dot_as_functions[-1].vector() return all_times, all_solutions_as_functions, all_solutions_dot_as_functions
elyte_ctr = 0 SEI_ctr = 0 phi_ctr += 1 # Volume fraction of SEI per cell res[-1] = SV_dot[-1] return res """------------------------------------------------------------------------""" # Set up problem instance SEI_1D = Implicit_Problem(residual, SV_0, SV_dot_0, t_0) # Define simulation parameters simulation = IDA(SEI_1D) # Create simulation instance simulation.atol = 1e-6 # Solver absolute tolerance simulation.rtol = 1e-6 # Solver relative tolerance simulation.maxh = 0.1 # Solver max step size # Set simulation end time, slope flag (for anode voltage cycle), and run simulation t_f = ((phi_bounds[1] - phi_anode_0)/R)*5 #ncp_list = np.arange(0, t_f, 0.15) #ncp = 10000 # Run simulation t, SV, SV_dot = simulation.simulate(t_f)
def main(): import numpy as np import time from matplotlib import pyplot as plt from li_ion_battery_p2d_functions import Extended_Problem from assimulo.solvers import IDA from li_ion_battery_p2d_inputs import Inputs as inp from li_ion_battery_p2d_init import anode, cathode, separator, SV_0, algvar from li_ion_battery_p2d_post_process import Label_Columns, tag_strings, plot_sims # Close any open pyplot objects: plt.close() # Start a timer: t_count = time.time() # Calculate the time span, which should be enough to charge or discharge fully # (i.e. 3600 seconds divided by the C-rate): t_0 = 0 t_f = 3600 / inp.C_rate # SV_0 = anode.SV_0 # SV_0 = np.concatenate((anode.SV_0, separator.SV_0, cathode.SV_0)) #SV_0 = np.concatenate((anode.SV_0, separator.SV_0)) SV_dot_0 = np.zeros_like(SV_0) """----------Equilibration----------""" # Equilibrate by integrating at zero current: print('\nEquilibrating...') # Create problem instance #Battery_equil = Extended_Problem(Battery_Func, SV_0, SV_dot_0, t_0) anode.i_ext = 0 cathode.i_ext = 0 Battery_equil = Extended_Problem.Battery_Func(t_0, SV_0, SV_dot_0, True) Battery_equil.external_event_detection = True # algvar = anode.algvar # algvar = np.concatenate((anode.algvar, separator.algvar, cathode.algvar)) #algvar = np.concatenate((anode.algvar, separator.algvar)) # Battery_equil.algvar = algvar # Simulation parameters equil_sim = IDA(Battery_equil) # Create simulation instance equil_sim.atol = atol1 # Solver absolute tolerance equil_sim.rtol = rtol1 # Solver relative tolerance equil_sim.verbosity = 50 equil_sim.make_consistent('IDA_YA_YDP_INIT') t_eq, SV_eq, SV_dot_eq = equil_sim.simulate(t_f) # Put solution into pandas dataframe with labeled columns SV_eq_df = Label_Columns(t_eq, SV_eq) # Obtain tag strings for dataframe columns tags = tag_strings(SV_eq_df) print('Done equilibrating\n') """---------------------------------""" """------------Charging-------------""" print('\nCharging...') # New initial conditions are the final equilibrium conditions t_0 = t_eq[-1] t_f1 = t_0 + t_f SV_0 = SV_eq[-1, :] SV_dot_0 = SV_dot_eq[-1:] # Charge the battery anode.params['i_ext'] = anode.i_ext cathode.params['i_ext'] = -cathode.i_ext # Create problem instance Battery_charge = Extended_Problem(Charge, SV_0, SV_dot_0, t_0) Battery_charge.external_event_detection = True Battery_charge.algvar = algvar # Simulation parameters charge_sim = IDA(Battery_charge) charge_sim.atol = atol2 charge_sim.rtol = rtol2 charge_sim.verbosity = 50 charge_sim.make_consistent('IDA_YA_YDP_INIT') # charge_sim.maxh = 0.5 t_charge, SV_charge, SV_dot_charge = charge_sim.simulate(t_f1) t_flag1 = anode.t_flag SV_charge_df = Label_Columns(t_charge, SV_charge) print('Done charging\n') """---------------------------------""" """------------Re_equilibrating-------------""" # New initial conditions are the final charge conditions t_0 = t_charge[-1] #anode.t_flag t_f2 = t_0 + t_f SV_0 = SV_charge[-1, :] SV_dot_0 = SV_dot_charge[-1, :] # Equilibrate again. Note - this is a specific choice to reflect # equilibration after the charging steps. We may want, at times, to # simulate a situation where the battery is not equilibrated between # charge and discharge, or is equilibrated for a shorter amount of time. print('\nRe-equilibrating...') Battery_re_equil = Extended_Problem(Re_equilibrate, SV_0, SV_dot_0, t_0) Battery_re_equil.external_event_detection = True Battery_re_equil.algvar = algvar # Simulation parameters re_equil_sim = IDA(Battery_re_equil) re_equil_sim.atol = atol3 re_equil_sim.rtol = rtol3 re_equil_sim.verbosity = 50 re_equil_sim.make_consistent('IDA_YA_YDP_INIT') t_req, SV_req, SV_dot_req = re_equil_sim.simulate(t_f2) SV_req_df = Label_Columns(t_req, SV_req) print('Done re-equilibrating\n') """---------------------------------""" """------------Discharging-------------""" print('\nDischarging...') t_0 = t_req[-1] t_f3 = t_f2 + t_f SV_0 = SV_req[-1, :] SV_dot_0 = SV_dot_req[-1, :] anode.params['i_ext'] = -anode.i_ext cathode.params['i_ext'] = cathode.i_ext Battery_discharge = Extended_Problem(Discharge, SV_0, SV_dot_0, t_0) Battery_discharge.external_event_detection = True Battery_discharge.algvar = algvar # Simulation parameters Battery_discharge = IDA(Battery_discharge) Battery_discharge.atol = atol4 Battery_discharge.rtol = rtol4 Battery_discharge.verbosity = 50 Battery_discharge.make_consistent('IDA_YA_YDP_INIT') t_discharge, SV_discharge, SV_dot_discharge = Battery_discharge.simulate( t_f3) t_flag2 = anode.t_flag SV_discharge_df = Label_Columns(t_discharge, SV_discharge) print('Done discharging\n') """---------------------------------""" SV_dict = {} SV_dict['SV_eq'] = SV_eq_df SV_dict['SV_charge'] = SV_charge_df SV_dict['SV_req'] = SV_req_df SV_dict['SV_discharge'] = SV_discharge_df # SV_charge_df = SV_charge_df.loc[SV_charge_df['Time'] <= t_flag1] # SV_discharge_df = SV_discharge_df.loc[SV_discharge_df['Time'] <= t_flag2] # dt_cap = t_flag1 - t_eq[-1] # t_80 = 0.8*dt_cap + t_eq[-1] # elyte80_charge = SV_charge_df.loc[SV_charge_df['Time'] <= t_80] # elyte75_charge = SV_charge_df.loc[SV_charge_df['X_an15'] <= 0.20] # el80 = elyte80_charge[X_elyte].iloc[0] # el80 = list(el80) # el80.append(inp.C_rate) # import openpyxl # book = openpyxl.load_workbook('Elyte_depth_profiles.xlsx') # sheet = book.active # sheet.append(el80) # book.save('Elyte_depth_profiles.xlsx') # print('Elyte Li+ at 80% SOC = ', elyte75_charge, '\n') plot_sims(tags['V_an'], tags['X_an'], tags['X_el_an'], SV_dict, t_f1, t_f3, t_flag1, t_flag2) # plot_sims(tags['V_cat'], tags['X_cat'], tags['X_el_cat'], SV_dict, t_f1, t_f3, t_flag1, t_flag2) # fig, axes = plt.subplots(sharey = "row", figsize = (18, 8), nrows=1, ncols=4) # plt.subplots_adjust(wspace=0, hspace=0.5) # # V_cell_plot = V_cell_eq.plot(ax = axes[0]) # V_cell_plot.set_title('Equilibration') # V_cell_plot.set_ylabel('Cell Voltage') # V_cell_plot.legend().set_visible(False) # # V_cell_plot = V_cell_charge.plot(ax = axes[1]) # V_cell_plot.set_title('Charging') # V_cell_plot.set_ylabel('Cell Voltage') # V_cell_plot.legend().set_visible(False) # # V_cell_plot = V_cell_req.plot(ax = axes[2]) # V_cell_plot.set_title('Re-Equilibration') # V_cell_plot.set_ylabel('Cell Voltage') # V_cell_plot.legend().set_visible(False) # # V_cell_plot = V_cell_discharge.plot(ax = axes[3]) # V_cell_plot.set_title('Discharge') # V_cell_plot.set_ylabel('Cell Voltage') # V_cell_plot.legend().set_visible(False) """---------------------------------""" # Post processing V_charge = np.array(SV_charge_df['V_dl1']) V_discharge = np.array(SV_discharge_df['V_dl1']) t_charge = np.array(SV_charge_df['Time']) t_discharge = np.array(SV_discharge_df['Time']) dt_charge = t_charge - t_charge[0] dt_discharge = t_discharge - t_discharge[0] # Plot charge-discharge curve Capacity_charge = -dt_charge * anode.i_ext / 3600 # A-h/m^2 Capacity_discharge = -dt_discharge * anode.i_ext / 3600 # A-h/m^2 fig1, ax1 = plt.subplots() ax1.plot(Capacity_charge, V_charge) ax1.plot(Capacity_discharge, V_discharge) # ax1.set_ylim((0, 1.2)) # ax1.set_xlim((-0.1, 18.5)) ax1.set_xlabel("Capacity [Ah/m^2]") ax1.set_ylabel("Voltage [V]") ax1.legend(("Charge capacity", "Discharge capacity")) # Calculate battery energy storage/recovery and calculate round-trip # efficiency. Anode voltage is referenced to its initial equilibrium # value (i.e. in the discharged state). # NOTE: This is in W-h/m^2, per unit area of battery. For the specific # capacity, you want W-h/g of anode material. # E_stored = 0 # E_recovered = 0 # for k in np.arange(1, len(t_charge)): # E_stored = (E_stored - (anode.V_cathode - 0.5*(V_charge[k] + V_charge[k-1])) # *ep.i_ext*(dt_charge[k] - dt_charge[k-1])) # # for k in np.arange(1, len(t_discharge)): # E_recovered = (E_recovered - (ep.V_cathode - # 0.5*(V_discharge[k] + V_discharge[k-1])) # *ep.i_ext*(dt_discharge[k] - dt_discharge[k-1])) # # Cap_recovered = Capacity_discharge[-1] # Eta_RT = E_recovered/E_stored # print('Cap_recovered = ', Cap_recovered, '\n') # print(E_stored, '\n') # print(E_recovered, '\n') # print('Eta_RT = ', Eta_RT, '\n') elapsed = time.time() - t_count print('t_cpu=', elapsed, '\n') plt.show() return t_req, SV_req, SV_dot_req
pc_centered ]) #Initial conditions yd0 = [0.0 for i in range(N + Na + Nc + Na + Nc + N + Na + Nc) ] #Initial conditions #Create an Assimulo implicit problem imp_mod = MyProblem(Na, Ns, Nc, X, cell_coated_area, bsp_dir, y0, yd0, 'Example using an analytic Jacobian') #Sets the options to the problem imp_mod.algvar = [1.0 for i in range(N + Na + Nc)] + [ 0.0 for i in range(Na + Nc + N + Na + Nc) ] #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-5 #Default 1e-6 imp_sim.rtol = 1e-5 #Default 1e-6 imp_sim.suppress_alg = True #Suppres the algebraic variables on the error test ### Simulate #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)
#ax[1].plot( imp_mod.x_m, z_out[:imp_mod.N,:-1] ) #ax[2].plot( imp_mod.x_m_a, z_out[imp_mod.N:imp_mod.N+imp_mod.Na,:-1] ) #ax[2].plot( imp_mod.x_m_c, z_out[-imp_mod.Nc:,:-1] ) #plt.show() #print z_out #Sets the options to the problem #imp_mod.jac = jac #Sets the jacobian imp_mod.algvar = [1.0 for i in range(N)] + [0.0 for i in range(N+Na+Nc)] #Set the algebraic components #imp_mod.algvar = [1.0 for i in range(N)] + [0.0 for i in range(N)] #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-5 #Default 1e-6 imp_sim.rtol = 1e-5 #Default 1e-6 imp_sim.suppress_alg = True #Suppres the algebraic variables on the error test ### Simulate imp_mod.set_j_vec( I_app ) #res_test = imp_mod.res( 0.0, y0, yd0 ) #jac_test = imp_mod.jac( 2, 0.0, y0, yd0 ) #Let Sundials find consistent initial conditions by use of 'IDA_YA_YDP_INIT' imp_sim.make_consistent('IDA_YA_YDP_INIT')
from scipy import * from assimulo.problem import Implicit_Problem from assimulo.solvers import IDA from Project_2 import squeezer as sq from Project_2 import squeezer2 as sq2 import matplotlib.pyplot as plt t0 = 0 tfinal = 0.03 # Model 1, squeezer with index 3 constraints y0_1,yp0_1 = sq.init_squeezer() ncp_1 = 100 model_1 = Implicit_Problem(sq.squeezer, y0_1, yp0_1, t0) model_1.name = 'Squeezer index 3 constraints' sim_1 = IDA(model_1) sim_1.suppress_alg = True sim_1.algvar = array([1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0]) sim_1.atol = ones(20,) for i in range(size(sim_1.atol)): if 0 <= i <= 6: sim_1.atol[i] = pow(10,-6) else: sim_1.atol[i] = pow(10,5) t, y, yd = sim_1.simulate(tfinal, ncp_1) plt.plot(t,y[:,14:shape(y)[1]]) # Plots the Lagrange multipliers plt.show() plt.plot(t,(y[:,0:7]+pi)%(2*pi)-pi) # Plots the position variables i.e beta,gamma etc, modulo 2pi. plt.show() # Model 2, squeezer with index 2 constraints
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 """ #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]) #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, name='Example using an analytic Jacobian') #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 #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: import pylab as P P.plot(t, y, linestyle="dashed", marker="o") #Plot the solution P.xlabel('Time') P.ylabel('State') P.title(imp_mod.name) P.show() return imp_mod, imp_sim
from state_event_woodpecker import state_event from handle_event_woodpecker import handle_event from assimulo.problem import Implicit_Problem from assimulo.solvers import IDA import matplotlib.pyplot as P import numpy as N t0 = 0.0 tfinal = 2.0 y0, yd0, switches0 = init_woodpecker() model = Implicit_Problem(res, y0, yd0, t0, sw0=switches0) model.state_events = state_event model.handle_event = handle_event sim = IDA(model) sim.algvar = [1, 1, 1, 0, 0, 0, 0, 0] sim.suppress_alg = True sim.atol = [1e-5, 1e-5, 1e-5, 1e15, 1e15, 1e15, 1e15, 1e15] t, y, yd = sim.simulate(tfinal) #sim.print_event_data() """ Plotting y[:,0] - plots z (height) y[:,1] - plots sleeve angle y[:,2] - plots bird angle """ # Plot z (height)
resid12 = -lambda_2 - g * m - lambda_3(z1 - z2) resid13 = (x1 * du[6] + x1_dot**2) + (y1 * du[7] + y1_dot**2) - du[8] resid14 = (x1 * du[9] + x1_dot**2) + (y1 * du[10] + y1_dot**2) - du[11] resid15 = (x1 - x2) * (du[6] - du[9]) + (x1_dot - x2_dot) * (x1_dot - x2_dot) resid16 = (y1 - y2) * (du[7] - du[10]) + (y1_dot - y2_dot) * (y1_dot - y2_dot) resid17 = (z1 - z2) * (du[8] - du[11]) + (z1_dot - z2_dot) * (z1_dot - z2_dot) return np.array([ resid1, resid2, resid3, resid4, resid5, resid6, resid7, resid8, resid9, resid10, resid11, resid12, resid13, resid14, resid15, resid16, resid17 ]) #initial conditions t0 = 0.0 u0 = [1.0, 1.0, 1.0, 0., 0., 0., 0., 0., 0., 0., 0., 0., 0, 0, 0] du0 = [0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0, 0, 0] model = Implicit_Problem(residual, u0, du0, t0) model.name = 'masses linked on surface' sim = IDA(model) tfinal = 10.0 #Specify the final time ncp = 500 #Number of communication points (number of return points) t, y, yd = sim.simulate(tfinal, ncp) sim.plot()
r[7] = u_b - phip_b return r def res3(self,t,y,yp,sw): print('res2') if sw[0]: return motion_state1(t,y,yp) elif sw[1]: return motion_state2(t,y,yp) elif sw[2]: return motion_state3(t,y,yp) else: print('wrong sw in res') return -1 t0 = 0; sw0 = [1,0,0,0] y0 = numpy.array([5, 0,0, 0, 0, 1,0,0]) yd0 = numpy.array([0, 0, 1,-9.82, 1e-12, 0, 0, 0]) problem = Woodpecker(res, y0, yd0, t0, sw0) #problem.res=res sim = IDA(problem) problem.name = 'Woodpecker' ncp = 500 tfinal = 2 t, y, yd = sim.simulate(tfinal, ncp) plt.plot(t, y) plt.legend(["z", "phi_s", "phi_b", "zp", "phip_s", "phip_b", "lambda_1", "lambda_2"], loc = 'lower left') plt.show()
import numpy as np from assimulo.problem import Implicit_Problem from assimulo.solvers import IDA import squeezer_ind2 import squeezer_ind3 y20,yp20=squeezer_ind2.init_squeezer2() # Initial values y30,yp30=squeezer_ind3.init_squeezer3() # Initial values t0 = 0 # Initial time squeezemodel2 = Implicit_Problem(squeezer_ind2.squeezer2, y20, yp20, t0) squeezemodel3 = Implicit_Problem(squeezer_ind3.squeezer3, y30, yp30, t0) algvar = 7*[1.]+13*[0.] solver2 = IDA(squeezemodel2) # Create solver instance solver3 = IDA(squeezemodel3) # Create solver instance solver2.algvar = algvar solver3.algvar = algvar solver2.suppress_alg=True solver3.suppress_alg=True solver2.atol = 1e-7 solver3.atol = 1e-7 solver3.maxsteps = 322 print(solver3.maxsteps) tf = .03 # End time for simulation t2, y2, yd2 = solver2.simulate(tf) t3, y3, yd3 = solver3.simulate(tf)
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 #Plot if with_plots: import pylab as P 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() #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) 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
# -*- coding: utf-8 -*- from __future__ import division from scipy import * from matplotlib.pyplot import * import numpy as np from assimulo.problem import Implicit_Problem from assimulo.solvers import IDA import squeezer y0,yp0=squeezer.init_squeezer() # Initial values t0 = 0 # Initial time squeezemodel = Implicit_Problem(squeezer.squeezer, y0, yp0, t0) algvar = 7*[1.]+13*[0.] sim = IDA(squeezemodel) # Create solver instance sim.algvar = algvar sim.suppress_alg=True sim.atol = 1e-7 tf = .03 # End time for simulation t, y, yd = sim.simulate(tf) sim.plot(mask=7*[1]+13*[0]) grid(1) axis([0, .03, -1.5, 1.5]) xlabel('Time, t [s]') ylabel('Angle, [rad]')
np.real(b_par_x_min), \ np.imag(b_par_x_min), \ np.real(u_perp_x_min), \ np.imag(u_perp_x_min) ]) dU_x_min = np.array([ \ np.real(dux_x_min), \ np.imag(dux_x_min), \ np.real(db_par_x_min), \ np.imag(db_par_x_min), \ np.real(du_perp_x_min), \ np.imag(du_perp_x_min) ]) model = Implicit_Problem(residual, U_x_min, dU_x_min, x_min) model.name = 'Resonant absorption' sim = IDA(model) x, U, dU = sim.simulate(x_max, nx) x = np.array(x) ux_r = U[:, 0] ux_i = U[:, 1] b_par_r = U[:, 2] b_par_i = U[:, 3] u_perp_r = U[:, 4] u_perp_i = U[:, 5] fig = plt.figure() ax = fig.add_subplot(111) ax.plot(x, ux_r)
res[0:ct.nz] = np.real(dux + 1j * ct.omega * b_par + nabla_perp_u_perp) res[ct.nz:2 * ct.nz] = np.imag(dux + 1j * ct.omega * b_par + nabla_perp_u_perp) res[2 * ct.nz:3 * ct.nz] = np.real(db_par + 1j / ct.omega * L_ux) res[3 * ct.nz:4 * ct.nz] = np.imag(db_par + 1j / ct.omega * L_ux) res[4 * ct.nz:5 * ct.nz] = np.real(L_u_perp - 1j * ct.omega * nabla_perp_b_par) res[5 * ct.nz:] = np.imag(L_u_perp - 1j * ct.omega * nabla_perp_b_par) return res model = Implicit_Problem(residual, ct.U_x_min, ct.dU_x_min, ct.x_min) model.name = 'Resonant abosprotion' sim = IDA(model) x, U, dU = sim.simulate(ct.x_max, ct.nx) # sim.plot() # fig = plt.figure() # ax = fig.add_subplot(111) # ax.plot(ct.z, ct.dU_perp_x_min[0:ct.nz]) # ax.plot(ct.z, np.real(ct.du_perp_ana(ct.x_min,ct.z))) # fig = plt.figure() # ax = fig.add_subplot(111) # ax.plot(ct.z, ct.dU_perp_x_min[ct.nz:]) # ax.plot(ct.z, np.imag(ct.du_perp_ana(ct.x_min,ct.z)))
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