Exemplo n.º 1
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
Exemplo n.º 2
0
def run_example(with_plots=True):
    """
    This example show how to use Assimulo and IDA for simulating sensitivities
    for initial conditions.::
    
        0 = dy1/dt - -(k01+k21+k31)*y1 - k12*y2 - k13*y3 - b1
        0 = dy2/dt - k21*y1 + (k02+k12)*y2
        0 = dy3/dt - k31*y1 + k13*y3
     
        y1(0) = p1, y2(0) = p2, y3(0) = p3
        p1=p2=p3 = 0 
    
    See http://sundials.2283335.n4.nabble.com/Forward-sensitivities-for-initial-conditions-td3239724.html
    
    on return:
    
       - :dfn:`imp_mod`    problem instance
    
       - :dfn:`imp_sim`    solver instance
    
    """
    def f(t, y, yd, p):
        y1, y2, y3 = y
        yd1, yd2, yd3 = yd
        k01 = 0.0211
        k02 = 0.0162
        k21 = 0.0111
        k12 = 0.0124
        k31 = 0.0039
        k13 = 0.000035
        b1 = 49.3

        res_0 = -yd1 - (k01 + k21 + k31) * y1 + k12 * y2 + k13 * y3 + b1
        res_1 = -yd2 + k21 * y1 - (k02 + k12) * y2
        res_2 = -yd3 + k31 * y1 - k13 * y3

        return N.array([res_0, res_1, res_2])

    #The initial conditions
    y0 = [0.0, 0.0, 0.0]  #Initial conditions for y
    yd0 = [49.3, 0., 0.]
    p0 = [0.0, 0.0, 0.0]  #Initial conditions for parameters
    yS0 = N.array([[1, 0, 0], [0, 1, 0], [0, 0, 1.]])

    #Create an Assimulo implicit problem
    imp_mod = Implicit_Problem(f,
                               y0,
                               yd0,
                               p0=p0,
                               name='Example: Computing Sensitivities')

    #Sets the options to the problem
    imp_mod.yS0 = yS0

    #Create an Assimulo explicit solver (IDA)
    imp_sim = IDA(imp_mod)

    #Sets the paramters
    imp_sim.rtol = 1e-7
    imp_sim.atol = 1e-6
    imp_sim.pbar = [
        1, 1, 1
    ]  #pbar is used to estimate the tolerances for the parameters
    imp_sim.report_continuously = True  #Need to be able to store the result using the interpolate methods
    imp_sim.sensmethod = 'SIMULTANEOUS'  #Defines the sensitvity method used
    imp_sim.suppress_sens = False  #Dont suppress the sensitivity variables in the error test.

    #Simulate
    t, y, yd = imp_sim.simulate(400)  #Simulate 400 seconds

    #Basic test
    nose.tools.assert_almost_equal(y[-1][0], 1577.6552477, 3)
    nose.tools.assert_almost_equal(y[-1][1], 611.9574565, 3)
    nose.tools.assert_almost_equal(y[-1][2], 2215.88563217, 3)
    nose.tools.assert_almost_equal(imp_sim.p_sol[0][1][0], 1.0)

    #Plot
    if with_plots:
        P.figure(1)
        P.subplot(221)
        P.plot(t,
               N.array(imp_sim.p_sol[0])[:, 0], t,
               N.array(imp_sim.p_sol[0])[:, 1], t,
               N.array(imp_sim.p_sol[0])[:, 2])
        P.title("Parameter p1")
        P.legend(("p1/dy1", "p1/dy2", "p1/dy3"))
        P.subplot(222)
        P.plot(t,
               N.array(imp_sim.p_sol[1])[:, 0], t,
               N.array(imp_sim.p_sol[1])[:, 1], t,
               N.array(imp_sim.p_sol[1])[:, 2])
        P.title("Parameter p2")
        P.legend(("p2/dy1", "p2/dy2", "p2/dy3"))
        P.subplot(223)
        P.plot(t,
               N.array(imp_sim.p_sol[2])[:, 0], t,
               N.array(imp_sim.p_sol[2])[:, 1], t,
               N.array(imp_sim.p_sol[2])[:, 2])
        P.title("Parameter p3")
        P.legend(("p3/dy1", "p3/dy2", "p3/dy3"))
        P.subplot(224)
        P.title('ODE Solution')
        P.plot(t, y)
        P.suptitle(imp_mod.name)
        P.show()

        return imp_mod, imp_sim
Exemplo n.º 3
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