コード例 #1
0
def mySolve(xf,boltz_eqs,rtol,atol,verbosity=50):
    """Sets the main options for the ODE solver and solve the equations. Returns the
    array of x,y points for all components.
    If numerical instabilities are found, re-do the problematic part of the evolution with smaller steps"""
        
    boltz_solver = CVode(boltz_eqs)  #Define solver method
    boltz_solver.rtol = rtol
    boltz_solver.atol = atol
    boltz_solver.verbosity = verbosity
    boltz_solver.linear_solver = 'SPGMR'
    boltz_solver.maxh = xf/300.
    xfinal = xf
    xres = []
    yres = []
    sw = boltz_solver.sw[:]
    while xfinal <= xf:
        try:
            boltz_solver.re_init(boltz_eqs.t0,boltz_eqs.y0)
            boltz_solver.sw = sw[:]
            x,y = boltz_solver.simulate(xfinal)
            xres += x
            for ypt in y: yres.append(ypt)
            if xfinal == xf: break   #Evolution has been performed until xf -> exit            
        except Exception,e:
            print e
            if not e.t or 'first call' in e.msg[e.value]:
                logger.error("Error solving equations:\n "+str(e))
                return False
            xfinal = max(e.t*random.uniform(0.85,0.95),boltz_eqs.t0+boltz_solver.maxh)  #Try again, but now only until the error
            logger.warning("Numerical instability found. Restarting evolution from x = "
                           +str(boltz_eqs.t0)+" to x = "+str(xfinal))
            continue
        xfinal = xf  #In the next step try to evolve from xfinal -> xf
        sw = boltz_solver.sw[:]
        x0 = float(x[-1])
        y0 = [float(yval) for yval in y[-1]]
        boltz_eqs.updateValues(x0,y0,sw)
コード例 #2
0
def run_example(with_plots=True):
    r"""
    Example to demonstrate the use of a preconditioner
    
    .. math::
        
        \dot y_1 & = 2 t \sin y_1  + t \sin y_2 \\
        \dot y_2 & = 3 t \sin y_1  + 2 t \sin y_2
        
    on return:
    
       - :dfn:`exp_mod`    problem instance
    
       - :dfn:`exp_sim`    solver instance
       
    """

    #Define the rhs
    def rhs(t, y):
        A = np.array([[2.0, 1.0], [3.0, 2.0]])
        yd = np.dot(A * t, np.sin(y))
        return yd

    #Define the preconditioner setup function
    def prec_setup(t, y, fy, jok, gamma, data):
        A = np.array([[2.0, 1.0], [3.0, 2.0]])

        #If jok is false the jacobian data needs to be recomputed
        if jok == False:

            #Extract the diagonal of the jacobian to form a Jacobi preconditioner
            a0 = A[0, 0] * t * np.cos(y[0])
            a1 = A[1, 1] * t * np.cos(y[1])
            a = np.array([(1. - gamma * a0), (1. - gamma * a1)])

            #Return true (jacobian data was recomputed) and the new data
            return [True, a]

        #If jok is true the existing jacobian data can be reused
        if jok == True:

            #Return false (jacobian data was reused) and the old data
            return [False, data]

    #Define the preconditioner solve function
    def prec_solve(t, y, fy, r, gamma, delta, data):

        #Solve the system Pz = r
        z0 = r[0] / data[0]
        z1 = r[1] / data[1]

        z = np.array([z0, z1])
        return z

    #Initial conditions
    y0 = [1.0, 2.0]

    #Define an Assimulo problem
    exp_mod = Explicit_Problem(
        rhs, y0, name="Example of using a preconditioner in SUNDIALS")

    #Set the preconditioner setup and solve function for the problem
    exp_mod.prec_setup = prec_setup
    exp_mod.prec_solve = prec_solve

    #Create a CVode solver
    exp_sim = CVode(exp_mod)

    #Set the parameters for the solver
    exp_sim.iter = 'Newton'
    exp_sim.discr = 'BDF'
    exp_sim.atol = 1e-5
    exp_sim.rtol = 1e-5
    exp_sim.linear_solver = 'SPGMR'
    exp_sim.precond = "PREC_RIGHT"  #Set the desired type of preconditioning

    #Simulate
    t, y = exp_sim.simulate(5)

    if with_plots:
        exp_sim.plot()

    #Basic verification
    nose.tools.assert_almost_equal(y[-1, 0], 3.11178295, 4)
    nose.tools.assert_almost_equal(y[-1, 1], 3.19318992, 4)

    return exp_mod, exp_sim
コード例 #3
0
def run_example(with_plots=True):
    r"""
    An example for CVode with scaled preconditioned GMRES method
    as a special linear solver.
    Note, how the operation Jacobian times vector is provided.
    
    ODE:
    
    .. math::
       
       \dot y_1 &= y_2 \\
       \dot y_2 &= -9.82
       
    
    on return:
    
       - :dfn:`exp_mod`    problem instance
    
       - :dfn:`exp_sim`    solver instance
       
    """

    #Defines the rhs
    def f(t, y):
        yd_0 = y[1]
        yd_1 = -9.82

        return N.array([yd_0, yd_1])

    #Defines the Jacobian*vector product
    def jacv(t, y, fy, v):
        j = N.array([[0, 1.], [0, 0]])
        return N.dot(j, v)

    y0 = [1.0, 0.0]  #Initial conditions

    #Defines an Assimulo explicit problem
    exp_mod = Explicit_Problem(
        f, y0, name='Example using the Jacobian Vector product')

    exp_mod.jacv = jacv  #Sets the Jacobian

    exp_sim = CVode(exp_mod)  #Create a CVode solver

    #Set the parameters
    exp_sim.iter = 'Newton'  #Default 'FixedPoint'
    exp_sim.discr = 'BDF'  #Default 'Adams'
    exp_sim.atol = 1e-5  #Default 1e-6
    exp_sim.rtol = 1e-5  #Default 1e-6
    exp_sim.linear_solver = 'SPGMR'  #Change linear solver
    #exp_sim.options["usejac"] = False

    #Simulate
    t, y = exp_sim.simulate(
        5, 1000)  #Simulate 5 seconds with 1000 communication points

    #Basic tests
    nose.tools.assert_almost_equal(y[-1][0], -121.75000000, 4)
    nose.tools.assert_almost_equal(y[-1][1], -49.100000000)

    #Plot
    if with_plots:
        P.plot(t, y)
        P.xlabel('Time')
        P.ylabel('State')
        P.title(exp_mod.name)
        P.show()

    return exp_mod, exp_sim
コード例 #4
0
def run_example(with_plots=True):
    r"""
    Example for demonstrating the use of a user supplied Jacobian (sparse).
    Note that this will only work if Assimulo has been configured with
    Sundials + SuperLU. Based on the SUNDIALS example cvRoberts_sps.c
    
    ODE:
    
    .. math::
       
       \dot y_1 &= -0.04y_1 + 1e4 y_2 y_3 \\
       \dot y_2 &= - \dot y_1 - \dot y_3 \\
       \dot y_3 &= 3e7 y_2^2
       
    
    on return:
    
       - :dfn:`exp_mod`    problem instance
    
       - :dfn:`exp_sim`    solver instance
       
    """

    #Defines the rhs
    def f(t, y):
        yd_0 = -0.04 * y[0] + 1e4 * y[1] * y[2]
        yd_2 = 3e7 * y[1] * y[1]
        yd_1 = -yd_0 - yd_2
        return N.array([yd_0, yd_1, yd_2])

    #Defines the Jacobian
    def jac(t, y):

        colptrs = [0, 3, 6, 9]
        rowvals = [0, 1, 2, 0, 1, 2, 0, 1, 2]
        data = [
            -0.04, 0.04, 0.0, 1e4 * y[2], -1e4 * y[2] - 6e7 * y[1], 6e7 * y[1],
            1e4 * y[1], -1e4 * y[1], 0.0
        ]

        J = SP.csc_matrix((data, rowvals, colptrs))
        return J

    #Defines an Assimulo explicit problem
    y0 = [1.0, 0.0, 0.0]  #Initial conditions

    exp_mod = Explicit_Problem(f,
                               y0,
                               name='Example using analytic (sparse) Jacobian')

    exp_mod.jac = jac  #Sets the Jacobian
    exp_mod.jac_nnz = 9

    exp_sim = CVode(exp_mod)  #Create a CVode solver

    #Set the parameters
    exp_sim.iter = 'Newton'  #Default 'FixedPoint'
    exp_sim.discr = 'BDF'  #Default 'Adams'
    exp_sim.atol = [1e-8, 1e-14, 1e-6]  #Default 1e-6
    exp_sim.rtol = 1e-4  #Default 1e-6
    exp_sim.linear_solver = "sparse"

    #Simulate
    t, y = exp_sim.simulate(0.4)  #Simulate 0.4 seconds

    #Basic tests
    nose.tools.assert_almost_equal(y[-1][0], 0.9851, 3)

    #Plot
    if with_plots:
        P.plot(t, y[:, 1], linestyle="dashed", marker="o")  #Plot the solution
        P.xlabel('Time')
        P.ylabel('State')
        P.title(exp_mod.name)
        P.show()

    return exp_mod, exp_sim