Пример #1
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)
Пример #2
0
    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
Пример #3
0
    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
Пример #4
0
    def initialize_ode_solver(self, y_0, yd_0, t_0):
        model = Implicit_Problem(self.residual, y_0, yd_0, t_0)
        model.handle_result = self.handle_result
        solver = IDA(model)
        solver.rtol = self.solver_rtol
        solver.atol = self.solver_atol  # * np.array([100, 10, 1e-4, 1e-4])
        solver.inith = 0.1  # self.wind.R_g / const.C
        solver.maxh = self.dt * self.wind.R_g / const.C
        solver.report_continuously = True
        solver.display_progress = False
        solver.verbosity = 50  # 50 = quiet
        solver.num_threads = 3

        # solver.display_progress = True
        return solver
Пример #5
0
    def buildsim(self, ):
        """
        Setup the assimulo IDA simulator.
        """
        # Create an Assimulo implicit solver (IDA)
        imp_sim = IDA(self.imp_mod)  # Create a IDA solver

        # Sets the paramters
        # 1e-4 #Default 1e-6
        imp_sim.atol = self.p.RunInput['TIMESTEPPING']['SOLVER_TOL']
        # 1e-4 #Default 1e-6
        imp_sim.rtol = self.p.RunInput['TIMESTEPPING']['SOLVER_TOL']
        # Suppres the algebraic variables on the error test
        imp_sim.suppress_alg = True

        imp_sim.display_progress = False
        imp_sim.verbosity = 50
        imp_sim.report_continuously = True
        imp_sim.time_limit = 10.

        self.imp_sim = imp_sim
Пример #6
0
def run_example(with_plots=True):
    r"""
    Example of the use of IDA for an implicit differential equation
    with a discontinuity (state event) and the need for an event iteration.
    
    on return:
    
       - :dfn:`imp_mod`    problem instance

       - :dfn:`imp_sim`    solver instance
    """
    
    #Create an instance of the problem
    imp_mod = Extended_Problem() #Create the problem

    imp_sim = IDA(imp_mod) #Create the solver
    
    imp_sim.verbosity = 0
    imp_sim.report_continuously = True

    #Simulate
    t, y, yd = imp_sim.simulate(10.0,1000) #Simulate 10 seconds with 1000 communications points
    
     #Plot
    if with_plots:
        import pylab as P
        P.plot(t,y)
        P.title(imp_mod.name)
        P.ylabel('States')
        P.xlabel('Time')
        P.show()
    
    #Basic test
    nose.tools.assert_almost_equal(y[-1][0],8.0)
    nose.tools.assert_almost_equal(y[-1][1],3.0)
    nose.tools.assert_almost_equal(y[-1][2],2.0)
    
    return imp_mod, imp_sim
Пример #7
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 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
Пример #10
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
Пример #11
0
### 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)

#imp_mod.set_iapp( I_app )
#imp_sim.make_consistent('IDA_YA_YDP_INIT')
## Sim step 1
#t1, y1, yd1 = imp_sim.simulate(1./Crate*3600.*0.2,100)

imp_sim.display_progress = False
imp_sim.verbosity = 50
imp_sim.report_continuously = True
imp_sim.time_limit = 10.

### Simulate
t01, t02 = 0.1, 0.2

imp_mod.set_iapp(I_app / 10.)
imp_sim.make_consistent('IDA_YA_YDP_INIT')
ta, ya, yda = imp_sim.simulate(t01, 2)

imp_mod.set_iapp(I_app / 2.)
imp_sim.make_consistent('IDA_YA_YDP_INIT')
tb, yb, ydb = imp_sim.simulate(t02, 2)

print 'yb shape', yb.shape
Пример #12
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