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)
Exemple #5
0
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()
Exemple #7
0
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
Exemple #8
0
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()
Exemple #9
0
 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
Exemple #10
0
    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
Exemple #12
0
 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)
Exemple #13
0
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()
Exemple #14
0
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()
Exemple #15
0
 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)
Exemple #16
0
    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
Exemple #17
0
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()
Exemple #19
0
    # 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
Exemple #21
0
    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
Exemple #23
0
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
Exemple #25
0
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
Exemple #26
0
 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
Exemple #27
0
    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')
Exemple #31
0
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
Exemple #32
0
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)
Exemple #34
0
    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()
Exemple #35
0
        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()

Exemple #36
0
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)
Exemple #37
0
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
Exemple #38
0
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 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
Exemple #40
0
# -*- 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)
Exemple #42
0
    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)))
Exemple #43
0
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