コード例 #1
0
def stiff_ode_solver(matrix,
                     y_initial,
                     forward_rate,
                     rev_rate,
                     third_body=None,
                     iteration='Newton',
                     discr='BDF',
                     atol=1e-10,
                     rtol=1e-6,
                     sim_time=0.001,
                     num_data_points=500):
    """
    Sets up the initial condition for solving the odes
    Parameters
    ----------
    matrix          : ndarray
                    stoichiometric matrix
    y_initial       : list
                    A list of initial concentrations
    forward_rate   : list
                    A list of forward reaction rates
                    for all the reactions in the mechanism
    rev_rate        : list
                    A list of reverse reaction rates
                    for all the reactions in the mechanism
    sim_time        : float
                    total time to simulate in seconds
    third_body      : ndarray
                    third body matrix, default = None
    iteration       : str
                    determines the iteration method that is be
                    used by the solver, default='Newton'
    discr           : determines the discretization method,
                    default='BDF'
    atol            : float
                    absolute tolerance(s) that is to be used
                    by the solver, default=1e-10
    rtol            : float
                    relative tolerance that is to be
                    used by the solver, default= 1e-7
    num_data_points : integer
                    number of even space data points in output
                    arrays, default = 500
    Returns
    ----------
    t1             : list
                    A list of time-points at which
                    the system of ODEs is solved
                    [t1, t2, t3,...]
    y1              : list of lists
                    A list of concentrations of all the species
                    at t1 time-points
                    [[y1(t1), y2(t1),...], [y1(t2), y2(t2),...],...]

    """

    # y0[0] = 0
    # y0[0] = 0
    # dydt = np.zeros((len(species_list)), dtype=float)
    # Define the rhs
    kf = forward_rate
    kr = rev_rate
    mat_reac = np.abs(np.asarray(np.where(matrix < 0, matrix, 0)))
    mat_prod = np.asarray(np.where(matrix > 0, matrix, 0))

    #  d = kf * np.prod(y0**np.abs(mat_reac), axis = 1) - kr * np.prod(y0**mat_prod, axis = 1)

    def rhs(t, concentration):
        #        print(t)

        y = concentration
        if third_body is not None:
            third_body_eff = np.dot(third_body, y)
            third_body_eff = np.where(third_body_eff > 0, third_body_eff, 1)
        #            print(third_body_eff)
        else:
            third_body_eff = np.ones(len(forward_rate))
        #            print(len(third_body_matrix))
        rate_concentration = (kf * np.prod(np.power(y, mat_reac), axis=1) -
                              kr * np.prod(np.power(y, mat_prod), axis=1))

        dydt = np.dot(
            third_body_eff,
            np.multiply(matrix, rate_concentration.reshape(matrix.shape[0],
                                                           1)))
        # dydt = [np.sum(third_body_eff * (matrix[:, i] * rate_concentration)) for i in
        #         range(len(species_list))]
        del t
        del y
        return dydt

    t0 = 0
    # Define an Assimulo problem
    exp_mod = Explicit_Problem(rhs, y_initial, t0)

    # Define an explicit solver
    exp_sim = CVode(exp_mod)  # Create a CVode solver

    # Sets the parameters
    exp_sim.iter = iteration  # Default 'FixedPoint'
    exp_sim.discr = discr  # Default 'Adams'
    exp_sim.atol = [atol]  # Default 1e-6
    exp_sim.rtol = rtol  # Default 1e-6
    exp_sim.maxh = 0.1
    exp_sim.minh = 1e-18
    exp_sim.num_threads = 1

    while True:
        try:
            t1, y1 = exp_sim.simulate(sim_time, num_data_points)
            break
        except CVodeError:
            # reduce absolute error by two orders of magnitude
            # and try to solve again.
            print("next process started")
            atol = atol * 1e-2
            exp_sim.atol = atol
            # if atol < 1e-15:
            #     t1 = 0
            #     y1 = 0
            #     break
            # print(exp_sim.atol)

    return t1, y1