def simulate(self, Tend, nIntervals, gridWidth):

        problem = Explicit_Problem(self.rhs, self.y0)
        problem.name = 'CVode'
        # 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

        simulation = CVode(problem)

        # Change multistep method: 'adams' or 'VDF'
        if self.discr == 'Adams':
            simulation.discr = 'Adams'
            simulation.maxord = 12
        else:
            simulation.discr = 'BDF'
            simulation.maxord = 5
        # Change iteration algorithm: functional(FixedPoint) or newton
        if self.iter == 'FixedPoint':
            simulation.iter = 'FixedPoint'
        else:
            simulation.iter = 'Newton'

        # Sets additional parameters
        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

        # '''Initialize problem '''
        # self.t_cur = self.t0
        # self.y_cur = self.y0

        # 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 = simulation.simulate
Example #2
0
    def simulate(self, Tend, nIntervals, gridWidth):

        problem = Explicit_Problem(self.rhs, self.y0)
        problem.name = 'CVode'
        # 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

        simulation = CVode(problem)

        # Change multistep method: 'adams' or 'VDF'
        if self.discr == 'Adams':
            simulation.discr = 'Adams'
            simulation.maxord = 12
        else:
            simulation.discr = 'BDF'
            simulation.maxord = 5
        # Change iteration algorithm: functional(FixedPoint) or newton
        if self.iter == 'FixedPoint':
            simulation.iter = 'FixedPoint'
        else:
            simulation.iter = 'Newton'

        # Sets additional parameters
        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

        # '''Initialize problem '''
        # self.t_cur = self.t0
        # self.y_cur = self.y0

        # 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 = simulation.simulate
Example #3
0
def simulate_ode(fun, y_initial, tf, opts):
    "function to run CVode solver on given problem"
    # get options
    ode_opts, ode_system_options = opts
    # iter, discretization_method, atol, rtol, time_points = ode_opts
    iter = ode_opts["iter"]
    discretization_method = ode_opts["discr"]
    atol = ode_opts["atol"]
    rtol = ode_opts["rtol"]
    time_points = ode_opts["time_points"]
    try:
        display_progress = ode_opts["display_progress"]
    except KeyError:
        display_progress = True
    try:
        verbosity = ode_opts["verbosity"]
    except KeyError:
        verbosity = 10

    # define explicit assimulo problem
    prob = Explicit_Problem(lambda t, x: fun(t, x, ode_system_options),
                            y0=y_initial)

    # create solver instance
    solver = CVode(prob)

    # set solver options
    solver.iter, solver.discr, solver.atol, solver.rtol, solver.display_progress, solver.verbosity = \
        iter, discretization_method, atol, rtol, display_progress, verbosity

    # simulate system
    time_course, y_result = solver.simulate(tf, time_points)

    return time_course, y_result, prob, solver
Example #4
0
def run_example(with_plots=True):
    r"""
    Demonstration of the use of CVode by solving the
    linear test equation :math:`\dot y = - y`
    
    on return:
    
       - :dfn:`exp_mod`    problem instance
    
       - :dfn:`exp_sim`    solver instance
       
    """

    #Define the rhs
    def f(t, y):
        ydot = -y[0]
        return N.array([ydot])

    #Define an Assimulo problem
    exp_mod = Explicit_Problem(f,
                               y0=4,
                               name=r'CVode Test Example: $\dot y = - y$')

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

    #Sets the parameters
    exp_sim.iter = 'Newton'  #Default 'FixedPoint'
    exp_sim.discr = 'BDF'  #Default 'Adams'
    exp_sim.atol = [1e-4]  #Default 1e-6
    exp_sim.rtol = 1e-4  #Default 1e-6

    #Simulate
    t1, y1 = exp_sim.simulate(5, 100)  #Simulate 5 seconds
    t2, y2 = exp_sim.simulate(7)  #Simulate 2 seconds more

    #Plot
    if with_plots:
        import pylab as P
        P.plot(t1, y1, color="b")
        P.plot(t2, y2, color="r")
        P.title(exp_mod.name)
        P.ylabel('y')
        P.xlabel('Time')
        P.show()

    #Basic test
    nose.tools.assert_almost_equal(float(y2[-1]), 0.00347746, 5)
    nose.tools.assert_almost_equal(exp_sim.get_last_step(), 0.0222169642893, 3)

    return exp_mod, exp_sim
def run_example(with_plots=True):
    """
    The same as example :doc:`EXAMPLE_cvode_basic`  but now integrated backwards in time.
    
    on return:
    
       - :dfn:`exp_mod`    problem instance
    
       - :dfn:`exp_sim`    solver instance
       
    """

    #Define the rhs
    def f(t, y):
        ydot = -y[0]
        return N.array([ydot])

    #Define an Assimulo problem
    exp_mod = Explicit_Problem(
        f,
        t0=5,
        y0=0.02695,
        name=r'CVode Test Example (reverse time): $\dot y = - y$ ')

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

    #Sets the parameters
    exp_sim.iter = 'Newton'  #Default 'FixedPoint'
    exp_sim.discr = 'BDF'  #Default 'Adams'
    exp_sim.atol = [1e-8]  #Default 1e-6
    exp_sim.rtol = 1e-8  #Default 1e-6
    exp_sim.backward = True

    #Simulate
    t, y = exp_sim.simulate(0)  #Simulate 5 seconds (t0=5 -> tf=0)

    #print 'y(5) = {}, y(0) ={}'.format(y[0][0],y[-1][0])

    #Basic test
    nose.tools.assert_almost_equal(float(y[-1]), 4.00000000, 3)

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

    return exp_mod, exp_sim
    def make_explicit_sim(self):
        explicit_sim = CVode(self.explicit_problem)
        explicit_sim.iter = 'Newton'
        explicit_sim.discr = 'BDF'
        explicit_sim.rtol = 1e-7
        explicit_sim.atol = 1e-7
        explicit_sim.sensmethod = 'SIMULTANEOUS'
        explicit_sim.suppress_sens = True
        explicit_sim.report_continuously = False
        explicit_sim.usesens = False
        explicit_sim.verbosity = 50

        if self.use_jac and self.model_jac is not None:
            explicit_sim.usejac = True

        else:
            explicit_sim.usejac = False

        return explicit_sim
Example #7
0
	def setUp(self):
		"""
		Configures the solver
		"""
		#Define an explicit solver 
		simSolver = CVode(self) 
		#Create a CVode solver
		#Sets the parameters 
		#simSolver.verbosity = LOUD
		#simSolver.report_continuously = True
		simSolver.iter = 'Newton' #Default 'FixedPoint'
		simSolver.discr = 'BDF' #Default 'Adams'
		#simSolver.discr = 'Adams' 
		simSolver.atol = [1e-6]	#Default 1e-6 
		simSolver.rtol = 1e-6 	#Default 1e-6
		#simSolver.problem_info['step_events'] = True # activates step events
		#simSolver.maxh = 1.0
		#simSolver.store_event_points = True
		self.simSolver = simSolver
Example #8
0
    def setUp(self):
        """
		Configures the solver
		"""
        #Define an explicit solver
        simSolver = CVode(self)
        #Create a CVode solver
        #Sets the parameters
        #simSolver.verbosity = LOUD
        #simSolver.report_continuously = True
        simSolver.iter = 'Newton'  #Default 'FixedPoint'
        simSolver.discr = 'BDF'  #Default 'Adams'
        #simSolver.discr = 'Adams'
        simSolver.atol = [1e-6]  #Default 1e-6
        simSolver.rtol = 1e-6  #Default 1e-6
        #simSolver.problem_info['step_events'] = True # activates step events
        #simSolver.maxh = 1.0
        #simSolver.store_event_points = True
        self.simSolver = simSolver
Example #9
0
	def prepareSimulation(self, params = None):
		if params == None:
			params = AttributeDict({
				'absTol' : 1e-6, 
				'relTol' : 1e-6,
			})
		
		#Define an explicit solver 
		simSolver = CVode(self) 
		#Create a CVode solver
		#Sets the parameters 
		#simSolver.verbosity = LOUD
		simSolver.report_continuously = True
		simSolver.iter = 'Newton' #Default 'FixedPoint'
		simSolver.discr = 'BDF' #Default 'Adams'
		#simSolver.discr = 'Adams' 
		simSolver.atol = [params.absTol]	#Default 1e-6 
		simSolver.rtol = params.relTol 	#Default 1e-6		
		simSolver.problem_info['step_events'] = True # activates step events
		#simSolver.maxh = 1.0
		simSolver.store_event_points = True
		self.simSolver = simSolver
Example #10
0
    def prepareSimulation(self, params=None):
        if params == None:
            params = AttributeDict({
                'absTol': 1e-6,
                'relTol': 1e-6,
            })

        #Define an explicit solver
        simSolver = CVode(self)
        #Create a CVode solver
        #Sets the parameters
        #simSolver.verbosity = LOUD
        simSolver.report_continuously = True
        simSolver.iter = 'Newton'  #Default 'FixedPoint'
        simSolver.discr = 'BDF'  #Default 'Adams'
        #simSolver.discr = 'Adams'
        simSolver.atol = [params.absTol]  #Default 1e-6
        simSolver.rtol = params.relTol  #Default 1e-6
        simSolver.problem_info['step_events'] = True  # activates step events
        #simSolver.maxh = 1.0
        simSolver.store_event_points = True
        self.simSolver = simSolver
Example #11
0
    def simulate(self, Tend, nIntervals, gridWidth):

        # define assimulo problem:(has to be done here because of the starting value in Explicit_Problem
        solver = Explicit_Problem(self.rhs, self.y0)
        ''' *******DELETE LATER '''''''''
#        problem.handle_event = handle_event
#        problem.state_events = state_events
#        problem.init_mode = init_mode

        solver.handle_result = self.handle_result


        solver.name = 'Simple Explicit Example'
        simulation = CVode(solver)  # Create a RungeKutta34 solver
        # simulation.inith = 0.1 #Sets the initial step, default = 0.01

        # Change multistep method: 'adams' or 'VDF'
        if self.discr == 'Adams':
            simulation.discr = 'Adams'
            simulation.maxord = 12
        else:
            simulation.discr = 'BDF'
            simulation.maxord = 5

        # Change iteration algorithm: functional(FixedPoint) or newton
        if self.iter == 'FixedPoint':
            simulation.iter = 'FixedPoint'
        else:
            simulation.iter = 'Newton'

        # Sets additional parameters
        simulation.atol = self.atol
        simulation.rtol = self.rtol
        simulation.verbosity = 0
        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

        # Create Solver and set settings
#        noRootFunctions = np.size(self.state_events(self.t0, np.array(self.y0)))

#        solver = sundials.CVodeSolver(RHS = self.f, ROOT = self.rootf, SW = [False]*noRootFunctions,
#                       abstol = self.atol, reltol = self.rtol)
        # solver.settings.JAC = None   #Add user-dependent jacobian here

        '''Initialize problem '''
#        solver.init(self.t0, self.y0)
        self.handle_result(self.t0, self.y0)
        nextTimeEvent = self.time_events(self.t0, self.y0)
        self.t_cur = self.t0
        self.y_cur = self.y0
        state_event = False
#
#
        if gridWidth <> None:
            nOutputIntervals = int((Tend - self.t0) / gridWidth)
        else:
            nOutputIntervals = nIntervals
        # Define step length depending on if gridWidth or nIntervals has been chosen
        if nOutputIntervals > 0:
            # Last point on grid (does not have to be Tend:)
            if(gridWidth <> None):
                dOutput = gridWidth
            else:
                dOutput = (Tend - self.t0) / nIntervals
        else:
            dOutput = Tend

        outputStepCounter = long(1)
        nextOutputPoint = min(self.t0 + dOutput, Tend)

        while self.t_cur < Tend:

            # Time-Event detection and step time adjustment
            if nextTimeEvent is None or nextOutputPoint < nextTimeEvent:
                time_event = False
                self.t_cur = nextOutputPoint
            else:
                time_event = True
                self.t_cur = nextTimeEvent



            try:
#                #Integrator step
#                self.y_cur = solver.step(self.t_cur)
#                self.y_cur = np.array(self.y_cur)
#                state_event = False
                # Simulate




                # take a step to next output point:
                t_new, y_new = simulation.simulate(self.t_cur)  # 5, 10) #5, 10  self.t_cur self.t_cur  2. argument nsteps Simulate 5 seconds
                # t_new, y_new are both vectors of the time and states at t_cur and all intermediate
                # points before it! So take last values:
                self.t_cur = t_new[-1]
                self.y_cur = y_new[-1]
                state_event = False

            except:
                import sys
                print "Unexpected error:", sys.exc_info()[0]
#            except CVodeRootException, info:
#                self.t_cur = info.t
#                self.y_cur = info.y
#                self.y_cur = np.array(self.y_cur)
#                time_event = False
#                state_event = True
#
#
            # Depending on events have been detected do different tasks
            if time_event or state_event:
                event_info = [state_event, time_event]
                if not self.handle_event(self, event_info):
                    break
                solver.init(self.t_cur, self.y_cur)

                nextTimeEvent = self.time_events(self.t_cur, self.y_cur)
                # If no timeEvent happens:
                if nextTimeEvent <= self.t_cur:
                    nextTimeEvent = None

            if self.t_cur == nextOutputPoint:
                # Write output if not happened before:
                if not time_event and not state_event:
                    self.handle_result(nextOutputPoint, self.y_cur)
                outputStepCounter += 1
                nextOutputPoint = min(self.t0 + outputStepCounter * dOutput, Tend)

        self.finalize()
Example #12
0
switches0 = [True]   #Initial switches

#Create an Assimulo Problem
mod = Explicit_Problem(pendulum, y0, t0, sw0=switches0)

mod.state_events = state_events #Sets the state events to the problem
mod.handle_event = handle_event #Sets the event handling to the problem
mod.name = 'Pendulum with events'   #Sets the name of the problem


#Create an Assimulo solver (CVode)
sim = CVode(mod)

#Specifies options
sim.discr = 'Adams'     #Sets the discretization method
sim.iter = 'FixedPoint' #Sets the iteration method
sim.rtol = 1.e-8        #Sets the relative tolerance
sim.atol = 1.e-6        #Sets the absolute tolerance

#Simulation
ncp = 200     #Number of communication points
tfinal = 10.0 #Final time

t, y = sim.simulate(tfinal, ncp) #Simulate





#Plots the result
P.plot(t,y)
    gamma = p[3]

    flux = np.array(
        [alpha * y[0], beta * y[0] * y[1], delta * y[0] * y[1], gamma * y[1]])
    rhs = np.array([flux[0] - flux[1], flux[2] - flux[3]])

    return rhs


if __name__ == '__main__':
    p = np.array([.5, .02, .4, .004])
    ode_function = lambda t, x: rhs_fun(t, x, p)

    # define explicit assimulo problem
    prob = Explicit_Problem(ode_function, y0=np.array([10, .0001]))

    # create solver instance
    solver = CVode(prob)

    solver.iter = 'Newton'
    solver.discr = 'Adams'
    solver.atol = 1e-10
    solver.rtol = 1e-10
    solver.display_progress = True
    solver.verbosity = 10

    # simulate system
    time_course, y_result = solver.simulate(10, 200)

    print time_course
    print y_result
Example #14
0
def run_example(with_plots=True):
    """
    Simulations for the Gyro (Heavy Top) example in Celledoni/Safstrom: 
        Journal of Physics A, Vol 39, 5463-5478, 2006
        
    on return:
    
       - :dfn:`exp_mod`    problem instance
    
       - :dfn:`exp_sim`    solver instance
    
    """
    def curl(v):
        return array([[0, v[2], -v[1]], [-v[2], 0, v[0]], [v[1], -v[0], 0]])

    #Defines the rhs
    def f(t, u):
        """
        Simulations for the Gyro (Heavy Top) example in Celledoni/Safstrom: 
        Journal of Physics A, Vol 39, 5463-5478, 2006
        """
        I1 = 1000.
        I2 = 5000.
        I3 = 6000.
        u0 = [0, 0, 1.]
        pi = u[0:3]
        Q = (u[3:12]).reshape((3, 3))
        Qu0 = dot(Q, u0)
        f = array([Qu0[1], -Qu0[0], 0.])
        f = 0
        omega = array([pi[0] / I1, pi[1] / I2, pi[2] / I3])
        pid = dot(curl(omega), pi) + f
        Qd = dot(curl(omega), Q)
        return hstack([pid, Qd.reshape((9, ))])

    def energi(state):
        energi = []
        for st in state:
            Q = (st[3:12]).reshape((3, 3))
            pi = st[0:3]
            u0 = [0, 0, 1.]
            Qu0 = dot(Q, u0)
            V = Qu0[2]  # potential energy
            T = 0.5 * (pi[0]**2 / 1000. + pi[1]**2 / 5000. + pi[2]**2 / 6000.)
            energi.append([T])
        return energi

    #Initial conditions
    y0 = hstack([[1000. * 10, 5000. * 10, 6000 * 10], eye(3).reshape((9, ))])

    #Create an Assimulo explicit problem
    exp_mod = Explicit_Problem(f, y0, name="Gyroscope Example")

    #Create an Assimulo explicit solver (CVode)
    exp_sim = CVode(exp_mod)

    #Sets the parameters
    exp_sim.discr = 'BDF'
    exp_sim.iter = 'Newton'
    exp_sim.maxord = 2  #Sets the maxorder
    exp_sim.atol = 1.e-10
    exp_sim.rtol = 1.e-10

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

    #Plot
    if with_plots:
        import pylab as P
        P.plot(t, y / 10000.)
        P.xlabel('Time')
        P.ylabel('States, scaled by $10^4$')
        P.title(exp_mod.name)
        P.show()

    #Basic tests
    nose.tools.assert_almost_equal(y[-1][0], 692.800241862)
    nose.tools.assert_almost_equal(y[-1][8], 7.08468221e-1)

    return exp_mod, exp_sim
Example #15
0
def run_example(with_plots=True):
    """
    This is the same example from the Sundials package (cvsRoberts_FSA_dns.c)

    This simple example problem for CVode, due to Robertson, 
    is from chemical kinetics, and consists of the following three 
    equations:

    .. math:: 
    
       \dot y_1 &= -p_1 y_1 + p_2 y_2 y_3 \\
       \dot y_2 &= p_1 y_1 - p_2 y_2 y_3 - p_3 y_2^2 \\
       \dot y_3 &= p_3  y_2^2
    
    on return:
    
       - :dfn:`exp_mod`    problem instance
    
       - :dfn:`exp_sim`    solver instance
    """
    def f(t, y, p):
        p3 = 3.0e7

        yd_0 = -p[0] * y[0] + p[1] * y[1] * y[2]
        yd_1 = p[0] * y[0] - p[1] * y[1] * y[2] - p3 * y[1]**2
        yd_2 = p3 * y[1]**2

        return N.array([yd_0, yd_1, yd_2])

    #The initial conditions
    y0 = [1.0, 0.0, 0.0]  #Initial conditions for y

    #Create an Assimulo explicit problem
    exp_mod = Explicit_Problem(f,
                               y0,
                               name='Sundials test example: Chemical kinetics')

    #Sets the options to the problem
    exp_mod.p0 = [0.040, 1.0e4]  #Initial conditions for parameters
    exp_mod.pbar = [0.040, 1.0e4]

    #Create an Assimulo explicit solver (CVode)
    exp_sim = CVode(exp_mod)

    #Sets the paramters
    exp_sim.iter = 'Newton'
    exp_sim.discr = 'BDF'
    exp_sim.rtol = 1.e-4
    exp_sim.atol = N.array([1.0e-8, 1.0e-14, 1.0e-6])
    exp_sim.sensmethod = 'SIMULTANEOUS'  #Defines the sensitvity method used
    exp_sim.suppress_sens = False  #Dont suppress the sensitivity variables in the error test.
    exp_sim.report_continuously = True

    #Simulate
    t, y = exp_sim.simulate(
        4, 400)  #Simulate 4 seconds with 400 communication points

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

    #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(
        exp_sim.p_sol[0][-1][0], -1.8761,
        2)  #Values taken from the example in Sundials
    nose.tools.assert_almost_equal(exp_sim.p_sol[1][-1][0], 2.9614e-06, 8)

    return exp_mod, exp_sim
Example #16
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
    def simulate(self, Tend, nIntervals, gridWidth):

        # define assimulo problem:(has to be done here because of the starting value in Explicit_Problem
        solver = Explicit_Problem(self.rhs, self.y0)
        ''' *******DELETE LATER '''''''''
#        problem.handle_event = handle_event
#        problem.state_events = state_events
#        problem.init_mode = init_mode

        solver.handle_result = self.handle_result


        solver.name = 'Simple Explicit Example'
        simulation = CVode(solver)  # Create a RungeKutta34 solver
        # simulation.inith = 0.1 #Sets the initial step, default = 0.01

        # Change multistep method: 'adams' or 'VDF'
        if self.discr == 'Adams':
            simulation.discr = 'Adams'
            simulation.maxord = 12
        else:
            simulation.discr = 'BDF'
            simulation.maxord = 5

        # Change iteration algorithm: functional(FixedPoint) or newton
        if self.iter == 'FixedPoint':
            simulation.iter = 'FixedPoint'
        else:
            simulation.iter = 'Newton'

        # Sets additional parameters
        simulation.atol = self.atol
        simulation.rtol = self.rtol
        simulation.verbosity = 0
        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

        # Create Solver and set settings
#        noRootFunctions = np.size(self.state_events(self.t0, np.array(self.y0)))

#        solver = sundials.CVodeSolver(RHS = self.f, ROOT = self.rootf, SW = [False]*noRootFunctions,
#                       abstol = self.atol, reltol = self.rtol)
        # solver.settings.JAC = None   #Add user-dependent jacobian here

        '''Initialize problem '''
#        solver.init(self.t0, self.y0)
        self.handle_result(self.t0, self.y0)
        nextTimeEvent = self.time_events(self.t0, self.y0)
        self.t_cur = self.t0
        self.y_cur = self.y0
        state_event = False
#
#
        if gridWidth <> None:
            nOutputIntervals = int((Tend - self.t0) / gridWidth)
        else:
            nOutputIntervals = nIntervals
        # Define step length depending on if gridWidth or nIntervals has been chosen
        if nOutputIntervals > 0:
            # Last point on grid (does not have to be Tend:)
            if(gridWidth <> None):
                dOutput = gridWidth
            else:
                dOutput = (Tend - self.t0) / nIntervals
        else:
            dOutput = Tend

        outputStepCounter = long(1)
        nextOutputPoint = min(self.t0 + dOutput, Tend)

        while self.t_cur < Tend:

            # Time-Event detection and step time adjustment
            if nextTimeEvent is None or nextOutputPoint < nextTimeEvent:
                time_event = False
                self.t_cur = nextOutputPoint
            else:
                time_event = True
                self.t_cur = nextTimeEvent



            try:
#                #Integrator step
#                self.y_cur = solver.step(self.t_cur)
#                self.y_cur = np.array(self.y_cur)
#                state_event = False
                # Simulate




                # take a step to next output point:
                t_new, y_new = simulation.simulate(self.t_cur)  # 5, 10) #5, 10  self.t_cur self.t_cur  2. argument nsteps Simulate 5 seconds
                # t_new, y_new are both vectors of the time and states at t_cur and all intermediate
                # points before it! So take last values:
                self.t_cur = t_new[-1]
                self.y_cur = y_new[-1]
                state_event = False

            except:
                import sys
                print "Unexpected error:", sys.exc_info()[0]
#            except CVodeRootException, info:
#                self.t_cur = info.t
#                self.y_cur = info.y
#                self.y_cur = np.array(self.y_cur)
#                time_event = False
#                state_event = True
#
#
            # Depending on events have been detected do different tasks
            if time_event or state_event:
                event_info = [state_event, time_event]
                if not self.handle_event(self, event_info):
                    break
                solver.init(self.t_cur, self.y_cur)

                nextTimeEvent = self.time_events(self.t_cur, self.y_cur)
                # If no timeEvent happens:
                if nextTimeEvent <= self.t_cur:
                    nextTimeEvent = None

            if self.t_cur == nextOutputPoint:
                # Write output if not happened before:
                if not time_event and not state_event:
                    self.handle_result(nextOutputPoint, self.y_cur)
                outputStepCounter += 1
                nextOutputPoint = min(self.t0 + outputStepCounter * dOutput, Tend)

        self.finalize()
Example #18
0
### Mesh
N = 60
X = 165e-6 # [m]

### Initial conditions
c_init = 1000.0 # [mol/m^3]
c_centered = c_init*numpy.ones( N, dtype='d' )

exp_mod = MyProblem( N, X, c_centered, 'ce only model, explicit CVode' )
#exp_mod = MyProblem( N, X, numpy.linspace(c_init-c_init/5.,c_init+c_init/5.,N), 'ce only model, explicit CVode' )

# Set the ODE solver
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

#Simulate
exp_mod.set_j_vec( 1.e-4 )
t1, y1 = exp_sim.simulate(100, 100)

exp_mod.set_j_vec( 0.0 )
t2, y2 = exp_sim.simulate(200, 100)

#exp_mod.set_j_vec( 0.0 )
#t3, y3 = exp_sim.simulate(10000, 200)

#Plot
Example #19
0
def run_example(with_plots=True):
    r"""
    Example for demonstrating the use of a user supplied Jacobian
    
    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
    def jac(t, y):
        j = N.array([[0, 1.], [0, 0]])
        return j

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

    exp_mod = Explicit_Problem(f, y0, name='Example using analytic Jacobian')
    exp_mod.jac = jac  #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

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

    #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(exp_mod.name)
        P.show()

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

    return exp_mod, exp_sim
Example #20
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
Example #21
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
Example #22
0
    def run_sim_ice(Y, YLIQ):
        def dy_dt_func(t, Y):

            dy_dt = np.zeros(len(Y))

            svp = f.svp_liq(Y[ITEMP])
            svp_ice = f.svp_ice(Y[ITEMP])

            # vapour mixing ratio
            WV = c.eps * Y[IRH_ICE] * svp / (Y[IPRESS_ICE] - svp)
            # liquid mixing ratio
            WL = sum(YLIQ[IND1:IND2] * YLIQ[0:IND1])
            # ice mixing ratio
            WI = sum(Y[IND1:IND2] * Y[0:IND1])

            Cpm = c.CP + WV * c.CPV + WL * c.CPW + WI * c.CPI

            # RH with respect to ice
            RH_ICE = WV / (c.eps * svp_ice / (Y[IPRESS_ICE] - svp_ice))
            # ------------------------- growth rate of ice --------------------------
            RH_EQ = 1e0  # from ACPIM, FPARCELCOLD - MICROPHYSICS.f90

            CAP = f.CAPACITANCE01(Y[0:IND1], np.exp(Y[IND2:IND3]))

            growth_rate = f.ICEGROWTHRATE(Y[ITEMP_ICE], Y[IPRESS_ICE],
                                          RH_ICE, RH_EQ, Y[0:IND1],
                                          np.exp(Y[IND2:IND3]), CAP)
            growth_rate[np.isnan(growth_rate)] = 0  # get rid of nans
            growth_rate = np.where(Y[IND1:IND2] < 1e-6, 0.0, growth_rate)

            # Mass of water condensing
            dy_dt[:IND1] = growth_rate

            #---------------------------aspect ratio---------------------------------------
            DELTA_RHO = c.eps * svp / (Y[IPRESS_ICE] - svp)
            DELTA_RHOI = c.eps * svp_ice / (Y[IPRESS_ICE] - svp_ice)
            DELTA_RHO = Y[IRH_ICE] * DELTA_RHO - DELTA_RHOI
            DELTA_RHO = DELTA_RHO * Y[IPRESS_ICE] / Y[ITEMP_ICE] / c.RA

            RHO_DEP = f.DEP_DENSITY(DELTA_RHO, Y[ITEMP_ICE])

            # this is the rate of change of LOG of the aspect ratio
            dy_dt[IND2:IND3] = (dy_dt[0:IND1] *
                                ((f.INHERENTGROWTH(Y[ITEMP_ICE]) - 1) /
                                 (f.INHERENTGROWTH(Y[ITEMP_ICE]) + 2)) /
                                (Y[0:IND1] * c.rhoi * RHO_DEP))
            #------------------------------------------------------------------------------
            # Change in vapour content
            dwv_dt = -1 * sum(Y[IND1:IND2] * dy_dt[0:IND1])

            # change in water vapour mixing ratio
            DRI = -1 * dwv_dt

            dy_dt[ITEMP_ICE] = 0.0  #+c.LS/Cpm*DRI

            # if n.Simulation_type.lower() == 'parcel':
            #     dy_dt[ITEMP_ICE]=dy_dt[ITEMP_ICE] + c.LS/Cpm*DRI
            #---------------------------RH change------------------------------------------

            dy_dt[IRH_ICE] = (Y[IPRESS_ICE] - svp) * svp * dwv_dt

            dy_dt[IRH_ICE] = (
                dy_dt[IRH_ICE] - WV * Y[IPRESS_ICE] *
                derivative(f.svp_liq, Y[ITEMP_ICE], dx=1.0) * dy_dt[ITEMP_ICE])
            dy_dt[IRH_ICE] = dy_dt[IRH_ICE] / (c.eps * svp**2)
            #------------------------------------------------------------------------------
            return dy_dt

        #--------------------- SET-UP solver --------------------------------------

        y0 = Y
        t0 = 0.0

        #define assimulo problem
        exp_mod = Explicit_Problem(dy_dt_func, y0, t0)

        # define an explicit solver
        exp_sim = CVode(exp_mod)
        exp_sim.iter = 'Newton'
        exp_sim.discr = 'BDF'
        # set tolerance for each dydt function
        tol_list = np.zeros_like(Y)
        tol_list[0:IND1] = 1e-30  # mass
        tol_list[IND1:IND2] = 10  # number

        tol_list[IND2:IND3] = 1e-30  # aspect ratio
        # tol_list[IND3:IRH_SV_ICE] = 1e-26
        #tol_list[IRH_SV_ICE] = 1e-26

        tol_list[IPRESS_ICE] = 10
        tol_list[ITEMP_ICE] = 1e-4
        tol_list[IRH_ICE] = 1e-8

        exp_sim.atol = tol_list
        exp_sim.rtol = 1.0e-8
        exp_sim.inith = 1.0e-2  # initial time step-size
        exp_sim.usejac = False
        exp_sim.maxncf = 100  # max number of convergence failures allowed by solver
        exp_sim.verbosity = 40

        t_output, y_output = exp_sim.simulate(1)

        return y_output[-1, :]
Example #23
0
def run_example(with_plots=True):
    r"""
    This example shows how to use Assimulo and CVode for simulating sensitivities
    for initial conditions.

    .. math::
    
       \dot y_1 &= -(k_{01}+k_{21}+k_{31}) y_1 + k_{12} y_2 + k_{13} y_3 + b_1\\
       \dot y_2 &= k_{21} y_1 - (k_{02}+k_{12}) y_2 \\
       \dot y_3 &= k_{31} y_1 - k_{13} y_3
     
    with the parameter dependent inital conditions 
    :math:`y_1(0) = 0, y_2(0) = 0, y_3(0) = 0` . The initial values are taken as parameters :math:`p_1,p_2,p_3`
    for the computation of the sensitivity matrix, 
    see http://sundials.2283335.n4.nabble.com/Forward-sensitivities-for-initial-conditions-td3239724.html
    
    on return:
    
       - :dfn:`exp_mod`    problem instance
    
       - :dfn:`exp_sim`    solver instance
    
    """
    def f(t, y, p):
        y1, y2, y3 = y
        k01 = 0.0211
        k02 = 0.0162
        k21 = 0.0111
        k12 = 0.0124
        k31 = 0.0039
        k13 = 0.000035
        b1 = 49.3

        yd_0 = -(k01 + k21 + k31) * y1 + k12 * y2 + k13 * y3 + b1
        yd_1 = k21 * y1 - (k02 + k12) * y2
        yd_2 = k31 * y1 - k13 * y3

        return N.array([yd_0, yd_1, yd_2])

    #The initial conditions
    y0 = [0.0, 0.0, 0.0]  #Initial conditions for y
    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 explicit problem
    exp_mod = Explicit_Problem(f,
                               y0,
                               p0=p0,
                               name='Example: Computing Sensitivities')

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

    #Create an Assimulo explicit solver (CVode)
    exp_sim = CVode(exp_mod)

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

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

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

    #Plot
    if with_plots:
        title_text = r"Sensitivity w.r.t.  ${}$"
        legend_text = r"$\mathrm{{d}}{}/\mathrm{{d}}{}$"
        P.figure(1)
        P.subplot(221)
        P.plot(t,
               N.array(exp_sim.p_sol[0])[:, 0], t,
               N.array(exp_sim.p_sol[0])[:, 1], t,
               N.array(exp_sim.p_sol[0])[:, 2])
        P.title(title_text.format('p_1'))
        P.legend((legend_text.format('y_1',
                                     'p_1'), legend_text.format('y_1', 'p_2'),
                  legend_text.format('y_1', 'p_3')))
        P.subplot(222)
        P.plot(t,
               N.array(exp_sim.p_sol[1])[:, 0], t,
               N.array(exp_sim.p_sol[1])[:, 1], t,
               N.array(exp_sim.p_sol[1])[:, 2])
        P.title(title_text.format('p_2'))
        P.legend((legend_text.format('y_2',
                                     'p_1'), legend_text.format('y_2', 'p_2'),
                  legend_text.format('y_2', 'p_3')))
        P.subplot(223)
        P.plot(t,
               N.array(exp_sim.p_sol[2])[:, 0], t,
               N.array(exp_sim.p_sol[2])[:, 1], t,
               N.array(exp_sim.p_sol[2])[:, 2])
        P.title(title_text.format('p_3'))
        P.legend((legend_text.format('y_3',
                                     'p_1'), legend_text.format('y_3', 'p_2'),
                  legend_text.format('y_3', 'p_3')))
        P.subplot(224)
        P.title('ODE Solution')
        P.plot(t, y)
        P.suptitle(exp_mod.name)
        P.show()

        return exp_mod, exp_sim
Example #24
0
    def run_sim(Y, time, Y_AER1, YICE):
        def dy_dt_func(t, Y):

            dy_dt = np.zeros(len(Y))

            # add condensed semi-vol mass into bins
            if n.SV_flag:
                MBIN2[-1 * n.n_sv:, :] = np.reshape(Y[INDSV1:INDSV2],
                                                    [n.n_sv, nbins * nmodes])
            # calculate saturation vapour pressure over liquid
            svp1 = f.svp_liq(Y[ITEMP])
            # saturation ratio
            SL = svp1 * Y[IRH] / (Y[IPRESS] - svp1)
            SL = (SL * Y[IPRESS] / (1 + SL)) / svp1

            # water vapour mixing ratio
            WV = c.eps * Y[IRH] * svp1 / (Y[IPRESS] - svp1)
            WL = np.sum(Y[IND1:IND2] * Y[:IND1])  # LIQUID MIXING RATIO
            WI = np.sum(YICE[IND1:IND2] * YICE[:IND1])  # ice mixing ratio
            RM = c.RA + WV * c.RV

            CPM = c.CP + WV * c.CPV + WL * c.CPW + WI * c.CPI

            if simulation_type.lower() == 'chamber':
                # CHAMBER MODEL - pressure change
                dy_dt[IPRESS] = -100 * PRESS1 * PRESS2 * np.exp(-PRESS2 *
                                                                (time + t))
            elif simulation_type.lower() == 'parcel':
                # adiabatic parcel
                dy_dt[IPRESS] = -Y[IPRESS] / RM / Y[
                    ITEMP] * c.g * w  #! HYDROSTATIC EQUATION
            else:
                print('simulation type unknown')
                return

    # ----------------------------change in vapour content: -----------------------
    # 1. equilibruim size of particles
            if n.kappa_flag:
                #if n.SV_flag:
                # need to recalc kappa taking into acount the condensed semi-vols
                Kappa = np.sum(
                    (MBIN2[:, :] / RHOBIN2[:, :]) * KAPPABIN2[:, :],
                    axis=0) / np.sum(MBIN2[:, :] / RHOBIN2[:, :], axis=0)
                #  print(Kappa)
                #  print(MBIN2/RHOBIN2)
                KK01 = f.kk01(Y[0:IND1], Y[ITEMP], MBIN2, RHOBIN2, Kappa)

            else:
                KK01 = f.K01(Y[0:IND1], Y[ITEMP], MBIN2, n.n_sv, RHOBIN2,
                             NUBIN2, MOLWBIN2)

        #  print(KK01[0])
            Dw = KK01[2]  # wet diameter
            RHOAT = KK01[1]  # density of particles inc water and aerosol mass
            RH_EQ = KK01[0]  # equilibrium RH
            #  print(MBIN2/MOLWBIN2)
            # 2. growth rate of particles, Jacobson p455
            # rate of change of radius
            growth_rate = f.DROPGROWTHRATE(Y[ITEMP], Y[IPRESS], SL, RH_EQ,
                                           RHOAT, Dw)
            growth_rate[np.isnan(growth_rate)] = 0  # get rid of nans
            growth_rate = np.where(Y[IND1:IND2] < 1e-9, 0.0, growth_rate)

            # 3. Mass of water condensing
            # change in mass of water per particle
            dy_dt[:IND1] = (np.pi * RHOAT * Dw**2) * growth_rate

            # 4. Change in vapour content
            # change in water vapour mixing ratio
            dwv_dt = -1 * np.sum(
                Y[IND1:IND2] *
                dy_dt[:IND1])  # change to np.sum for speed  # mass
            # -----------------------------------------------------------------------------

            if simulation_type.lower() == 'chamber':
                # CHAMBER MODEL - temperature change
                dy_dt[ITEMP] = -Temp1 * Temp2 * np.exp(-Temp2 * (time + t))
            elif simulation_type.lower() == 'parcel':
                # adiabatic parcel
                dy_dt[ITEMP] = RM / Y[IPRESS] * dy_dt[IPRESS] * Y[
                    ITEMP] / CPM  # TEMPERATURE CHANGE: EXPANSION
                dy_dt[ITEMP] = dy_dt[ITEMP] - c.LV / CPM * dwv_dt
            else:
                print('simulation type unknown')
                return

    # --------------------------------RH change------------------------------------
            dy_dt[IRH] = svp1 * dwv_dt * (Y[IPRESS] - svp1)
            dy_dt[IRH] = dy_dt[IRH] + svp1 * WV * dy_dt[IPRESS]
            dy_dt[IRH] = (
                dy_dt[IRH] - WV * Y[IPRESS] *
                derivative(f.svp_liq, Y[ITEMP], dx=1.0) * dy_dt[ITEMP])
            dy_dt[IRH] = dy_dt[IRH] / (c.eps * svp1**2)
            # -----------------------------------------------------------------------------

            # ------------------------------ SEMI-VOLATILES -------------------------------
            if n.SV_flag:
                #      SV_mass = np.reshape(Y[INDSV1:INDSV2],[n.n_sv,n.nmodes*n.nbins])
                #     SV_mass = np.where(SV_mass == 0.0,1e-30,SV_mass)
                #    MBIN2[n.n_sv*-1:,:] = SV_mass

                RH_EQ_SV = f.K01SV(Y[:IND1], Y[ITEMP], MBIN2, n.n_sv, RHOBIN2,
                                   NUBIN2, MOLWBIN2)

                RH_EQ = RH_EQ_SV[0]
                RHOAT = RH_EQ_SV[1]
                DW = RH_EQ_SV[2]

                SVP_ORG = f.SVP_GASES(n.semi_vols, Y[ITEMP],
                                      n.n_sv)  #C-C equation

                #RH_ORG = [x*Y[IPRESS]/c.RA/Y[ITEMP] for x in Y[IRH_SV]]
                RH_ORG = [x for x in Y[IRH_SV]]
                RH_ORG = [(x / c.aerosol_dict[key][0]) * c.R * Y[ITEMP]
                          for x, key in zip(RH_ORG, n.semi_vols[:n.n_sv])
                          ]  # just for n_sv keys in dictionary
                RH_ORG = [RH_ORG[x] / SVP_ORG[x] for x in range(n.n_sv)]

                dy_dt[INDSV1:INDSV2] = f.SVGROWTHRATE(Y[ITEMP], Y[IPRESS],
                                                      SVP_ORG, RH_ORG, RH_EQ,
                                                      DW, n.n_sv, n.nbins,
                                                      n.nmodes, MOLWBIN2)

                dy_dt[IRH_SV] = -np.sum(np.reshape(
                    dy_dt[INDSV1:INDSV2], [n.n_sv, IND1]) * Y[IND1:IND2],
                                        axis=1)  #see line 137

            return dy_dt

    #--------------------- SET-UP solver ------------------------------------------

        y0 = Y
        t0 = 0.0

        #define assimulo problem
        exp_mod = Explicit_Problem(dy_dt_func, y0, t0)

        # define an explicit solver
        exp_sim = CVode(exp_mod)
        exp_sim.iter = 'Newton'
        exp_sim.discr = 'BDF'
        #set parameters
        tol_list = np.zeros_like(Y)
        tol_list[0:IND1] = 1e-40  # this is now different to ACPIM (1e-25)
        tol_list[IND1:IND2] = 10  # number

        tol_list[IND2:IND3] = 1e-30  # capacitance
        tol_list[IND3:INDSV2] = 1e-26  #condendensed semi-vol mass
        tol_list[IRH_SV] = 1e-26  # RH of each semi-vol compound

        tol_list[IPRESS] = 10
        tol_list[ITEMP] = 1e-4
        tol_list[IRH] = 1e-8  # set tolerance for each dydt function
        exp_sim.atol = tol_list
        exp_sim.rtol = 1.0e-8
        exp_sim.inith = 0  # initial time step-size
        exp_sim.usejac = False
        exp_sim.maxncf = 100  # max number of convergence failures allowed by solver
        exp_sim.verbosity = 40
        t_output, y_output = exp_sim.simulate(1)

        return y_output[-1, :], t_output[:]
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 CVode, 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 \\
       \dot y_2 &= p_1 y_1 - p_2 y_2 y_3 - p_3 y_2^2 \\
       \dot y_3 &= p_3  y_ 2^2
       
    
    on return:
    
       - :dfn:`exp_mod`    problem instance
    
       - :dfn:`exp_sim`    solver instance
    
    """
    
    def f(t, y, p):
        
        yd_0 = -p[0]*y[0]+p[1]*y[1]*y[2] 
        yd_1 = p[0]*y[0]-p[1]*y[1]*y[2]-p[2]*y[1]**2 
        yd_2 = p[2]*y[1]**2
        
        return N.array([yd_0,yd_1,yd_2])
        
    def jac(t,y, p):
        J = N.array([[-p[0], p[1]*y[2], p[1]*y[1]],
                     [p[0], -p[1]*y[2]-2*p[2]*y[1], -p[1]*y[1]],
                     [0.0, 2*p[2]*y[1],0.0]])
        return J
        
    def fsens(t, y, s, p):
        J = N.array([[-p[0], p[1]*y[2], p[1]*y[1]],
                     [p[0], -p[1]*y[2]-2*p[2]*y[1], -p[1]*y[1]],
                     [0.0, 2*p[2]*y[1],0.0]])
        P = N.array([[-y[0],y[1]*y[2],0],
                     [y[0], -y[1]*y[2], -y[1]**2],
                     [0,0,y[1]**2]])
        return J.dot(s)+P
    
    #The initial conditions
    y0 = [1.0,0.0,0.0]          #Initial conditions for y
    
    #Create an Assimulo explicit problem
    exp_mod = Explicit_Problem(f,y0, name='Robertson Chemical Kinetics Example')
    exp_mod.rhs_sens = fsens
    exp_mod.jac = jac
    
    #Sets the options to the problem
    exp_mod.p0 = [0.040, 1.0e4, 3.0e7]  #Initial conditions for parameters
    exp_mod.pbar = [0.040, 1.0e4, 3.0e7]

    #Create an Assimulo explicit solver (CVode)
    exp_sim = CVode(exp_mod)
    
    #Sets the solver paramters
    exp_sim.iter = 'Newton'
    exp_sim.discr = 'BDF'
    exp_sim.rtol = 1.e-4
    exp_sim.atol = N.array([1.0e-8, 1.0e-14, 1.0e-6])
    exp_sim.sensmethod = 'SIMULTANEOUS' #Defines the sensitvity method used
    exp_sim.suppress_sens = False       #Dont suppress the sensitivity variables in the error test.
    exp_sim.report_continuously = True

    #Simulate
    t, y = exp_sim.simulate(4,400) #Simulate 4 seconds with 400 communication points
    
    #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(exp_sim.p_sol[0][-1][0], -1.8761, 2) #Values taken from the example in Sundials
    nose.tools.assert_almost_equal(exp_sim.p_sol[1][-1][0], 2.9614e-06, 8)
    nose.tools.assert_almost_equal(exp_sim.p_sol[2][-1][0], -4.9334e-10, 12)
    
    #Plot
    if with_plots:
        P.plot(t, y)
        P.title(exp_mod.name)
        P.xlabel('Time')
        P.ylabel('State')
        P.show()  
        
    return exp_mod, exp_sim
Example #26
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