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)
Exemplo n.º 2
0
    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)
Exemplo n.º 3
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()
Exemplo n.º 4
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
Exemplo n.º 5
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
Exemplo n.º 6
0
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')
# Sim step 1
t1, y1, yd1 = imp_sim.simulate(100,100) 
#t1, y1, yd1 = imp_sim.simulate(1000,1000) 

imp_mod.set_j_vec( 0.0 )
imp_sim.make_consistent('IDA_YA_YDP_INIT')
# Sim step 1
t2, y2, yd2 = imp_sim.simulate(200,100) 


#Plot

# Plot through space
f, ax = plt.subplots(2,3)
ax[0,0].plot(imp_mod.x_m*1e6,y1.T[:N,:]) #Plot the solution
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
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
Exemplo n.º 9
0
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
Exemplo n.º 10
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
Exemplo n.º 11
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)   
Exemplo n.º 12
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)
Exemplo n.º 13
0
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
    algvar = sol_init.algvar
    atol = np.ones_like(SV_0) * 1e-5
    atol[cat.ptr_vec['eps_S8']] = 1e-25
    atol[cat.ptr_vec['eps_Li2S']] = 1e-25
    atol[cat.ptr_vec['rho_k_el']] = 1e-25
    #    atol = 1e-30;
    rtol = 1e-4
    sim_output = 50

    rate_tag = str(inputs.C_rate) + "C"

    fig, axes = plt.subplots(sharey="row", figsize=(9, 12), nrows=3, ncols=1)
    plt.subplots_adjust(wspace=0.15, hspace=0.4)
    fig.text(0.15,
             0.8,
             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)

    # 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)
    #    SV_eq_df = []

    # Obtain tag strings for dataframe columns
    tags = tag_strings(SV_eq_df)

    #    plot_sim(tags, SV_eq_df, 'Equilibrating', 0, fig, axes)
    #    print(SV_eq_df[tags['rho_el'][4:10]].iloc[-1])

    print('Done equilibrating\n')

    "------------Discharging-------------"

    print('Discharging...')

    # New initial conditions from previous simulation
    SV_0 = SV_eq[-1, :]
    SV_dot_0 = SV_dot_eq[-1, :]

    # 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 = 5
    sim_dch.verbosity = sim_output
    sim_dch.make_consistent('IDA_YA_YDP_INIT')

    t_dch, SV_dch, SV_dot_dch = sim_dch.simulate(t_f)

    #    if hasattr(cathode, 'get_tflag'):
    #        t_flag_ch = cathode.get_tflag

    SV_dch_df = label_columns(t_dch, SV_dch, an.npoints, sep.npoints,
                              cat.npoints)
    #    SV_dch_df = []
    # Obtain tag strings for dataframe columns
    #    tags = tag_strings(SV_ch_df)

    plot_sim(tags, SV_dch_df, 'Discharging', 1, fig, axes)

    plot_meanPS(SV_dch_df, tags)

    print('Done Discharging\n')

    "--------Re-equilibration---------"

    #    if inputs.flag_req == 1:
    #
    #        print('Re-equilibrating...')
    #
    #        # New initial conditions from previous simulation
    #        SV_0 = SV_ch[-1, :]
    #        SV_dot_0 = SV_dot_ch[-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', 2-1, fig, axes)
    #
    #        print('Done re-equilibrating\n')
    #    else:
    #        SV_req = SV_ch
    #        SV_dot_req = SV_dot_ch

    "-----------Charging-----------"

    #    print('Charging...')
    #
    #    SV_0 = SV_req[-1, :]
    #    SV_dot_0 = SV_dot_req[-1, :]
    #
    #    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.verbosity = sim_output
    #    sim_dch.make_consistent('IDA_YA_YDP_INIT')
    #
    #    t_dch, SV_dch, SV_dot_dch = sim_dch.simulate(t_f)
    #
    ##    if hasattr(cathode, 'get_tflag'):
    ##        t_flag_dch = cathode.get_tflag
    #
    #    SV_dch_df = label_columns(t_dch, SV_dch, an.npoints, sep.npoints, cat.npoints)
    #
    #    plot_sim(tags, SV_dch_df, 'Charging', 3, fig, axes)
    #
    #    print('Done Charging\n')

    t_elapsed = time.time() - t_count
    print('t_cpu=', t_elapsed, '\n')

    return SV_eq_df, SV_dch_df, tags  #SV_eq_df, SV_req_df #, SV_dch_df
Exemplo n.º 14
0
    raise Exception('Please select a valid simulation mode." + \
        "  Available options are "detailed", "homogeneous", and "reduced"')

print('\n     Running simulation\n')
# Set up problem instance
SEI_1D = Implicit_Problem(residual, SV_0, SV_dot_0)

SEI_1D.algvar = algvar

# Define simulation parameters
simulation = IDA(SEI_1D)  # Create simulation instance
simulation.atol = 1e-8  # Solver absolute tolerance
simulation.rtol = 1e-4  # Solver relative tolerance
#simulation.maxh = 55                   # Solver max step size

simulation.make_consistent('IDA_YA_YDP_INIT')

# 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 the simulation "
"------------------------------------------------------------------------------"
t, SV, SV_dot = simulation.simulate(t_f)

" Organize, plot, and save the data:"
"----------------------------------------------------------------------------------"
# This function creates a dataframe and adds labels to each element in the SV: