def ode_sim(t_final):
    y0 = get_initial()  # initial conditions from Parameter.py
    t0 = 0.0
    param = new_param()

    ecoli_ode = lambda t, x: rhs(t, x, param)
    model = Explicit_Problem(ecoli_ode, y0, t0)  # Create an Assimulo problem
    model.name = 'E Coli ODE'
    sim = CVode(model)  # Create the solver CVode

    sim.rtol = 1e-8
    sim.atol = 1e-8
#    pdb.set_trace()
    t, y = sim.simulate(t_final)  # Use the .simulate method to simulate and provide the final time

    # Plot
    met_labels = ["ACCOA", "ACEx", "ACO", "ACP", "ADP", "AKG", "AMP", "ASP", "ATP", "BPG", "CAMP", "CIT", "COA", "CYS",
                  "DAP", "E4P", "ei", "eiia", "eiiaP", "eiicb", "eiicbP", "eiP", "F6P", "FDP", "FUM", "G6P", "GAP",
                  "GL6P", "GLCx", "GLX", "HCO3", "hpr", "hprP", "icd", "icdP", "ICIT", "KDPG", "MAL", "MG", "MN", "NAD",
                  "NADH", "NADP", "NADPH", "OAA", "P", "PEP", "PGA2", "PGA3", "PGN", "PYR", "PYRx", "Q", "QH2", "R5P",
                  "RU5P", "S7P", "SUC", "SUCCOA", "SUCx", "tal", "talC3", "tkt", "tktC2", "X5P", "Px", "Pp", "GLCp",
                  "ACEp", "ACE", "Hc", "Hp", "FAD", "FADH2", "O2", "FEED"]

    for i in y:
        if i.any() < 0:
            print i

    plt.plot([t, t], [y[:, i] for i in [4, 9]], label=["ADP", "ATP"])
    plt.title('Metabolite Concentrations Over Time')
    plt.xlabel('Time')
    plt.ylabel('Concentration')
    plt.legend()
    plt.savefig('concentration.png')

    return model, sim
Exemple #2
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
Exemple #3
0
 def x_cvode(self,params):
     from assimulo.problem import Explicit_Problem
     from assimulo.solvers import CVode
     func = self.create_dx(self.create_input_vector(params))
     problem = Explicit_Problem(lambda t,x:func(t,x)['f'](), [1.0,1.0,1.0],0)
     sim = CVode(problem)
     t,x = sim.simulate(250,len(self.time)-1)
     dataframe = pandas.DataFrame(x,
             columns=['population','burden','economy'],index=self.time)
     return dataframe
Exemple #4
0
 def s_cvode(self,params):
     from assimulo.problem import Explicit_Problem
     from assimulo.solvers import CVode
     func = self.create_ds(self.create_input_vector(params))
     s0 = np.ones(21)
     s0[3:]=0
     problem = Explicit_Problem(lambda t,s:func(t,s),s0,1900)
     sim = CVode(problem)
     t,s = sim.simulate(1900+250,self.time.shape[0]-1)
     dataframe = pandas.DataFrame(
         s,columns=self.cols+self.sensitivities,index=self.time)
     return dataframe
Exemple #5
0
def simulate_prob(t_start, t_stop, x0, p, ncp, with_plots=False):
    """Simulates the problem using Assimulo.

    Args:
        t_start (double): Simulation start time.
        t_stop (double): Simulation stop time.
        x0 (list): Initial value.
        p (list): Problem specific parameters.
        ncp (int): Number of communication points.
        with_plots (bool): Plots the solution.

    Returns:
        tuple: (t,y). Time vector and solution at each time.

    """

    # Assimulo
    # Define the right-hand side
    def f(t, y):
        xd_1 = p[0] * y[0]
        xd_2 = p[1] * (y[1] - y[0]**2)
        return np.array([xd_1, xd_2])

    # Define an Assimulo problem
    exp_mod = Explicit_Problem(f, y0=x0, name='Planar ODE')

    # Define an explicit solver
    exp_sim = CVode(exp_mod)

    # Sets the solver parameters
    exp_sim.atol = 1e-12
    exp_sim.rtol = 1e-11

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

    # Plot
    if with_plots:
        x1 = y[:, 0]
        x2 = y[:, 1]
        plt.figure()
        plt.title('Planar ODE')
        plt.plot(t, x1, 'b')
        plt.plot(t, x2, 'k')
        plt.legend(['x1', 'x2'])
        plt.xlim(t_start, t_stop)
        plt.xlabel('Time (s)')
        plt.ylabel('x')
        plt.grid(True)

    return t, y.T
Exemple #6
0
     def solve_ode(self):
         
         #Get initial conditions vector
         self.init_conditions()
 
         #Instantiate reactor as ODE class
         self._rode = AssimuloODE(self._r,self._r.z_in,self.y0)  
      
         #Define the CVode solver
         self.solver = CVode(self._rode) 
         
         #Solver parameters
         self.solver.atol = self.atol         
         self.solver.rtol = self.rtol         
         self.solver.iter = self.iter
         self.solver.discr = self.discr
         self.solver.linear_solver = self.linear_solver
         self.solver.maxord = self.order
         self.solver.maxsteps = self.max_steps
         self.solver.inith = self.first_step_size
         self.solver.minh = self.min_step_size
         self.solver.maxh = self.max_step_size
         self.solver.maxncf = self.max_conv_fails
         self.solver.maxnef = self.max_nonlin_iters
         self.solver.stablimdet = self.bdf_stability
         self.solver.verbosity = 50
 
         #Solve the equations
         z, self.values = self.solver.simulate(self._r.z_out,self.grid-1) 
         
         #Convert axial coordinates list to array
         self._z = np.array(z)
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
Exemple #8
0
def doSimulate():

    theta0 = 1.0  # radianer, startvinkel från lodrätt

    tfinal = 3

    title = 'k = {0}, stretch = {1}, {2}'.format(k, stretch, solver)

    r0 = 1.0 + stretch
    x0 = r0 * np.sin(theta0)
    y0 = -r0 * np.cos(theta0)
    t0 = 0.0

    y_init = np.array([x0, y0, 0, 0])

    ElasticSpring = Explicit_Problem(rhs, y_init, t0)
    if solver.lower() == "cvode":
        sim = CVode(ElasticSpring)
    elif solver.lower() == "bdf_2":
        sim = BDF_2(ElasticSpring)
    elif solver.lower() == "ee":
        sim = EE(ElasticSpring)
    else:
        sim == None
        raise ValueError('Expected "CVode", "EE" or "BDF_2"')
    sim.report_continuously = False

    npoints = 100 * tfinal

    #t,y = sim.simulate(tfinal,npoints)
    try:
        #for i in [1]:
        t, y = sim.simulate(tfinal)
        xpos, ypos = y[:, 0], y[:, 1]
        #plt.plot(t,y[:,0:2])
        plt.plot(xpos, ypos)
        plt.plot(xpos[0], ypos[0], 'or')
        plt.xlabel('y_1')
        plt.ylabel('y_2')
        plt.title(title)
        plt.axis('equal')
        plt.show()
    except Explicit_ODE_Exception as e:
        print(e.message)
        print("for the case {0}.".format(title))
Exemple #9
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
Exemple #10
0
 def s_cvode_natural(self,params):
     from assimulo.problem import Explicit_Problem
     from assimulo.solvers import CVode
     problem = Explicit_Problem(lambda t,x,p:self.create_dx(p)(t,x)['f'](),
                                [1.0,1.0,1.0],0,
                                [params[p] for p in self.params])
     sim = CVode(problem)
     sim.report_continuously = True
     t,x = sim.simulate(250,self.time.shape[0]-1)
     dataframe = pandas.DataFrame(x,
             columns=['population','burden','economy'])
     d = {}
     sens = np.array(sim.p_sol)
     for i,col in enumerate(self.cols):
         for j,param in enumerate(
             ('birthrate','deathrate','regenerationrate',
              'burdenrate','economyaim','growthrate')):
             d['{0},{1}'.format(col,param)] = sens[j,:,i]
     dataframe_sens = pandas.DataFrame(d,index=self.time)
     return dataframe_sens
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
Exemple #12
0
    def generate_integrator(self, y0=None, name='---', verbosity=50):
        """Initializes CVODE integrator

        Parameters
        ----------
        y0 : list or numpy.array
            Initial values
        name : str
            Name of the assimulo problem
        verbosity : int
            Verbosity of the integrator. Possible values = [10, 20, 30, 40, 50]
        Returns
        -------
        None
        """
        if y0 is None:
            y0 = np.zeros(len(self.model.cpdNames))
        self.problem = Explicit_Problem(self.f, y0=y0, name=name)
        self.integrator = CVode(self.problem)
        self.integrator.atol = 1e-8
        self.integrator.rtol = 1e-8
        self.integrator.verbosity = verbosity
Exemple #13
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
Exemple #14
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
Exemple #15
0
def run_example(with_plots=True):
    """
    Example of the use of CVode for a differential equation
    with a iscontinuity (state event) and the need for an event iteration.
    
    on return:
    
       - :dfn:`exp_mod`    problem instance
    
       - :dfn:`exp_sim`    solver instance
    """
    #Create an instance of the problem
    exp_mod = Extended_Problem()  #Create the problem

    exp_sim = CVode(exp_mod)  #Create the solver

    exp_sim.verbosity = 0
    exp_sim.report_continuously = True

    #Simulate
    t, y = exp_sim.simulate(
        10.0, 1000)  #Simulate 10 seconds with 1000 communications points
    exp_sim.print_event_data()

    #Plot
    if with_plots:
        import pylab as P
        P.plot(t, y)
        P.title(exp_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 exp_mod, exp_sim
Exemple #16
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
Exemple #17
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
Exemple #18
0
	# pretend that boundary conditions change at t_tot=5.0
	if t_tot == 5.0:
		num_eqn = 10.0
		# write dydt code
		f = open('test_numba_func.py', mode='w')
		f.write('import numpy as np\n')
		f.write('\n')
		f.write('def dydt(t, y): # define function:\n')
		f.write('	dydt = np.zeros((len(y)))\n')
		f.write('	num_eqn = ' + str(num_eqn) + '\n')
		f.write('	if num_eqn == 1:\n')
		f.write('		dydt[0] = y[0]*0.1\n')
		f.write('	else:\n')
		f.write('		dydt[0] = y[0]*0.2\n')
		f.write('	return(dydt)')
		f.close()
		test_numba_func = importlib.reload(test_numba_func) # imports updated version
		dydt = test_numba_func.dydt
		dydt = jit(f8[:](f8, f8[:]), nopython=True)(dydt)
		
	mod = Explicit_Problem(dydt, y_rec[count, 1])
	mod_sim = CVode(mod) # define a solver instance
	t_array, res = mod_sim.simulate(t)
	
	t_tot += 1.0
	count += 1
	y_rec[count, 0] = t_tot+t
	y_rec[count, 1] = res[-1]

plt.plot(y_rec[:, 0], y_rec[:, 1])
plt.show()
Exemple #19
0
        return c_dots


### 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 )
Exemple #20
0
        
#Initial values
y0 = [N.pi/2.0, 0.0] #Initial states
t0 = 0.0             #Initial time
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


Exemple #21
0
from assimulo.problem import Explicit_Problem
from assimulo.solvers import CVode
import matplotlib.pyplot as plt

def rhs(t,y):
    k = 1000 
    L = k*(math.sqrt(y[0]**2+y[1]**2)-1)/math.sqrt(y[0]**2+y[1]**2)
    result = numpy.array([y[2],y[3],-y[0]*L,-y[1]*L-1])
    return result
t0 = 0
y0 = numpy.array([0.8,-0.8,0,0])

model = Explicit_Problem(rhs,y0,t0)
model.name = 'task1'

sim = CVode(model)
sim.atol=numpy.array([1,1,1,1])*1e-5
sim.rtol=1e-6
sim.maxord=3
#sim.discr='BDF'
#sim.iter='Newton'


tfinal = 70

(t,y) = sim.simulate(tfinal)

#sim.plot()

plt.plot(y[:,0],y[:,1])
plt.axis('equal')
Exemple #22
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
Exemple #23
0
def run_example(with_plots=True):
    r"""
    Example for the use of the stability limit detection algorithm
    in CVode.
    
    .. math::
       
        \dot y_1 &= y_2 \\
        \dot y_2 &= \mu ((1.-y_1^2) y_2-y_1) \\
        \dot y_3 &= sin(ty_2)

    with :math:`\mu=\frac{1}{5} 10^3`.

    on return:
    
       - :dfn:`exp_mod`    problem instance
    
       - :dfn:`exp_sim`    solver instance

    """
    class Extended_Problem(Explicit_Problem):
        order = []
        
        def handle_result(self, solver, t, y):
            Explicit_Problem.handle_result(self, solver, t, y)
            self.order.append(solver.get_last_order())
            
    eps = 5.e-3
    my = 1./eps
    
    #Define the rhs
    def f(t,y):
        yd_0 = y[1]
        yd_1 = my*((1.-y[0]**2)*y[1]-y[0])
        yd_2 = N.sin(t*y[1])
        
        return N.array([yd_0,yd_1, yd_2])
    
    y0 = [2.0,-0.6, 0.1] #Initial conditions
    
    #Define an Assimulo problem
    exp_mod = Extended_Problem(f,y0, 
                          name = "CVode: Stability problem")
    
    #Define an explicit solver
    exp_sim = CVode(exp_mod) #Create a CVode solver
    
    #Sets the parameters
    exp_sim.stablimdet = True
    exp_sim.report_continuously = True
    
    #Simulate
    t, y = exp_sim.simulate(2.0) #Simulate 2 seconds
    
    #Plot
    if with_plots:
        P.subplot(211)
        P.plot(t,y[:,2])
        P.ylabel("State: $y_1$")
        P.subplot(212)
        P.plot(t,exp_mod.order)
        P.ylabel("Order")
        P.suptitle(exp_mod.name)
        P.xlabel("Time")
        P.show()

    #Basic test
    x1 = y[:,0]
    assert N.abs(x1[-1]-1.8601438) < 1e-1 #For test purpose
    
    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()
    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
    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
Exemple #27
0
def RunModel(flagD,th,STIM,xoutS,xoutG,dataS,dataG,kTCleak,kTCmaxs, inds_to_watch = []):
    # going to return [tout_all,xoutG_all,xoutS_all]


# This function runs the model and outputs timecourse simulation results.
# Required Inputs:
# flagD: 1 for deterministic simulations, 0 for stochastic simulations.
# th: simulation time (hours)
# STIM: stimulus vector
#
# Outputs:
# tout_all: n-by-1 vector of time values (seconds)
# xoutG_all: n-by-g matrix of species (g) through time (n) (g indices lines up to gm tab in Names.xls sheet)
# xoutS_all: n-by-p matrix of speices (p) through time (n) (p indices lines up to PARCDL tab in Names.xls sheet)
#



    # %% RUN
    ts=dataS.ts;
    ts_up=ts;
    N_STEPS=th*3600/ts;

    N_STEPS = int(N_STEPS)


    # % IMPORT INITIALIZED PARAMETERS
    pathi='initialized/';



    # % for PARCDL
    kbR0 = float(open(pathi + "i_kbR0.txt").read())


    kTL = []
    with open(pathi + 'i_kTLF.txt') as f:
        for line in f:
            kTL.append(float(line))
    kTL = np.array(kTL)



    kC173 = float(open(pathi + "i_kC173.txt").read())
    kC82 = float(open(pathi + "i_kC82.txt").read())
    kA77 = float(open(pathi + "i_kA77.txt").read())*5
    # ^ forgot to add the *5 to this line and spent sooooo long looking for this mistake lol


    kA87 = float(open(pathi + "i_kA87.txt").read())
    Rt = float(open(pathi + "i_Rt.txt").read())
    EIF4Efree = float(open(pathi + "i_EIF4Efree.txt").read())
    kDDbasal = float(open(pathi + "i_kDDbasal.txt").read())
    Vc = dataS.kS[2]





    # % for gm

    if len(kTCleak)==0:
      for line in open(pathi + "i_kTCleakF.txt").readlines():
          kTCleak.append(float(line))
      kTCleak = np.matrix.transpose(np.matrix(kTCleak))



    if len(kTCmaxs)==0:
      for line in open(pathi + "i_kTCmaxsF.txt").readlines():
          kTCmaxs.append(float(line))
      kTCmaxs = np.matrix.transpose(np.matrix(kTCmaxs))
      kTCmaxs = np.array(kTCmaxs)


    # % modifying data.S structure
    dataS.kS[0]=Rt;
    dataS.kS[1]=EIF4Efree;
    dataS.kS[11]=kbR0;
    dataS.kS[16:157]=kTL;
    dataS.kS[631]=kC173;
    dataS.kS[540]=kC82;
    dataS.kS[708]=kA77;
    dataS.kS[718]=kA87;
    dataS.kS[449]=kDDbasal;


    # % modifying data.G structure
    dataG.kTCleak=kTCleak;
    dataG.kTCmaxs=kTCmaxs;



    # %species


    if len(xoutS) == 0:
        xoutS = []

        with open(pathi + 'i_xoutF.csv', newline='') as csvfile:
            spamreader = csv.reader(csvfile, delimiter=' ', quotechar='|')
            for row in spamreader:
                x = ', '.join(row)
                x = x.split(',')

                to_append = []
                for item in x:
                    to_append.append(float(item))

                xoutS.append(to_append)


        xoutS = np.matrix(xoutS)
        xoutS = xoutS[24,:]




    if len(xoutG) == 0:
        if flagD:
            xoutG = dataG.x0gm_mpc_D
        else:
            xoutG = dataG.x0gm_mpc
            indsD=dataG.indsD

            xoutG[indsD] = dataG.x0gm_mpc_D[indsD]
            xoutG[indsD+141] = dataG.x0gm_mpc_D[indsD+141]
            xoutG[indsD+141*2] = dataG.x0gm_mpc_D[indsD+141*2]


    # % Apply STIM
    Etop = STIM[len(STIM)-1]

    STIM = STIM[0:len(STIM)-1]


    # code for logical
    if np.any(STIM):

        xoutS[0,STIM.astype(bool)] = STIM[STIM.astype(bool)]



    dataS.kS[452] = Etop





    # NOTE - matlab code
    # % Instantiation
    # t0 = 0;
    # optionscvodes = CVodeSetOptions('UserData', dataS,...
    #                           'RelTol',1.e-3,...
    #                           'LinearSolver','Dense',...
    #                           'JacobianFn',@Jeval774);
    # CVodeInit(@createODEs, 'BDF', 'Newton', t0, xoutS', optionscvodes);
    #
    # %ODE15s options
    # %optionsode15s=odeset('RelTol',1e-3,'Jacobian',@Jeval774ode15s);
    #


    tout_all = np.zeros(shape=(N_STEPS+1))
    xoutG_all = np.zeros(shape=(N_STEPS+1,len(xoutG)))
    xoutS_all = np.zeros(shape=(N_STEPS+1,xoutS.shape[1]))
    tout_all[0] = 0
    xoutG_all[0,:] = np.matrix.transpose(xoutG)
    xoutS_all[0,:] = xoutS



    # % Starting simulations
    print("... Starting Sims")
    start_time = time.time()


    for i in range(0,int(N_STEPS)+1):


        # gm
        [xginN,xgacN,AllGenesVecN,xmN,vTC] = gm(flagD,dataG,ts,xoutG,xoutS);

        xoutG = np.append(np.append(np.squeeze(np.asarray(xgacN)),np.squeeze(np.asarray(xginN))),np.squeeze(np.asarray(xmN)))
        # NOTE - matrix to array syntax
        xoutG = np.matrix.transpose(np.matrix(xoutG))




        dataS.mMod=xmN*(1E9/(Vc*6.023E+23)); #convert mRNAs from mpc to nM
        dataG.AllGenesVec=AllGenesVecN;


        xoutG_all[i,:] = np.matrix.transpose(xoutG)


        try:
            xoutS_all[i,:] = np.squeeze(np.asarray(xoutS))
        except:
            xoutS_all[i,:] = np.squeeze(np.asarray(xoutS[1]))




        if xoutS[0,103]<xoutS[0,105]:
            print("Apoptosis happened")
            tout_all = tout_all[0:i+1]
            xoutG_all = xoutG_all[0:i+1]
            xoutS_all = xoutS_all[0:i+1]
            return [tout_all, xoutG_all, xoutS_all]



        # scipy.odeint -- takes forever
        # xoutS = odeint(createODEs, xoutS_all[i,:],np.array([ts_up-ts, ts_up]), args=(dataS.kS,dataS.VvPARCDL,dataS.VxPARCDL,dataS.S_PARCDL,dataS.mExp_nM.as_matrix(),dataS.mMod,dataS.flagE))


        # assimulo -- much faster
        ode_start_time = time.time()
        exp_mod = MyProblem(y0=xoutS_all[i,:],dataS=dataS, Jeval774 = Jeval774)
        exp_sim = CVode(exp_mod)

        exp_sim.verbosity=50

        exp_sim.re_init(ts_up-ts,xoutS_all[i,:] )
        t1, xoutS = exp_sim.simulate(ts_up, 1)


        try:
            print(xoutS[1,inds_to_watch])
        except:
             print(xoutS)



        print("--- %s seconds ---" % (time.time() - ode_start_time))

        print("Percent complete: " + str(i/N_STEPS))


        # xoutG_all[i,:] = np.matrix.transpose(xoutG);

        try:
            tout_all[i+1] = ts_up
        except:
            pass

        ts_up = ts_up + ts



    print("ODEs done")
    print("--- %s seconds ---" % (time.time() - start_time))


    return [tout_all, xoutG_all, xoutS_all]
Exemple #28
0
    yd = np.dot(A, y) + b

    return yd


#def rhs(t,y):
#    A =np.array([[0, 1],[-2, -1]])
#    yd=np.dot(A, y)
#
#    return yd


def L(y, k):
    norm = ln.norm(y[0:2])
    return k * (norm - 1) / norm


y0 = np.array([1.0, 1.0, 1.0, 1.0])
t0 = 0.0

model = Explicit_Problem(rhs, y0, t0)  # Create an Assimulo problem
model.name = 'Linear Test ODE'  # Specifies the name of problem

sim = CVode(model)

tfinal = 100.0  #Specify the final time

t, y = sim.simulate(
    tfinal)  #Use the .simulate method to simulate and provide the final time
sim.plot()
Exemple #29
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
    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
    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()
Exemple #32
0
def run_simulation(filename, start_time, save_output, temp, RH, RO2_indices,
                   H2O, input_dict, simulation_time, batch_step):

    from assimulo.solvers import RodasODE, CVode  #Choose solver accoring to your need.
    from assimulo.problem import Explicit_Problem

    # In this function, we import functions that have been pre-compiled for use in the ODE solver
    # The function that calculates the RHS of the ODE is also defined within this function, such
    # that it can be used by the Assimulo solvers

    # The variables passed to this function are defined as follows:

    #-------------------------------------------------------------------------------------
    # define the ODE function to be called
    def dydt_func(t, y):
        """
        This function defines the right-hand side [RHS] of the ordinary differential equations [ODEs] to be solved
        input:
        • t - time variable [internal to solver]
        • y - array holding concentrations of all compounds in both gas and particulate [molecules/cc]
        output:
        dydt - the dy_dt of each compound in both gas and particulate phase [molecules/cc.sec]
        """

        #pdb.set_trace()
        # Calculate time of day
        time_of_day_seconds = start_time + t

        # make sure the y array is not a list. Assimulo uses lists
        y_asnumpy = numpy.array(y)

        #Calculate the concentration of RO2 species, using an index file created during parsing
        RO2 = numpy.sum(y[RO2_indices])

        #Calculate reaction rate for each equation.
        # Note that H2O will change in parcel mode
        # The time_of_day_seconds is used for photolysis rates - need to change this if want constant values
        rates = evaluate_rates_fortran(RO2, H2O, temp, time_of_day_seconds)
        #pdb.set_trace()
        # Calculate product of all reactants and stochiometry for each reaction [A^a*B^b etc]
        reactants = reactants_fortran(y_asnumpy)
        #pdb.set_trace()
        #Multiply product of reactants with rate coefficient to get reaction rate
        reactants = numpy.multiply(reactants, rates)
        #pdb.set_trace()
        # Now use reaction rates with the loss_gain matri to calculate the final dydt for each compound
        # With the assimulo solvers we need to output numpy arrays
        dydt = loss_gain_fortran(reactants)
        #pdb.set_trace()

        return dydt

    #-------------------------------------------------------------------------------------
    #-------------------------------------------------------------------------------------
    # define jacobian function to be called
    def jacobian(t, y):
        """
        This function defines Jacobian of the ordinary differential equations [ODEs] to be solved
        input:
        • t - time variable [internal to solver]
        • y - array holding concentrations of all compounds in both gas and particulate [molecules/cc]
        output:
        dydt_dydt - the N_compounds x N_compounds matrix of Jacobian values
        """

        # Different solvers might call jacobian at different stages, so we have to redo some calculations here
        # Calculate time of day
        time_of_day_seconds = start_time + t

        # make sure the y array is not a list. Assimulo uses lists
        y_asnumpy = numpy.array(y)

        #Calculate the concentration of RO2 species, using an index file created during parsing
        RO2 = numpy.sum(y[RO2_indices])

        #Calculate reaction rate for each equation.
        # Note that H2O will change in parcel mode
        rates = evaluate_rates_fortran(RO2, H2O, temp, time_of_day_seconds)
        #pdb.set_trace()
        # Now use reaction rates with the loss_gain matrix to calculate the final dydt for each compound
        # With the assimulo solvers we need to output numpy arrays
        dydt_dydt = jacobian_fortran(rates, y_asnumpy)
        #pdb.set_trace()
        return dydt_dydt

    #-------------------------------------------------------------------------------------

    #import static compilation of Fortran functions for use in ODE solver
    print("Importing pre-compiled Fortran modules")
    from rate_coeff_f2py import evaluate_rates as evaluate_rates_fortran
    from reactants_conc_f2py import reactants as reactants_fortran
    from loss_gain_f2py import loss_gain as loss_gain_fortran
    from jacobian_f2py import jacobian as jacobian_fortran

    # 'Unpack' variables from input_dict
    species_dict = input_dict['species_dict']
    species_dict2array = input_dict['species_dict2array']
    species_initial_conc = input_dict['species_initial_conc']
    equations = input_dict['equations']

    #Specify some starting concentrations [ppt]
    Cfactor = 2.55e+10  #ppb-to-molecules/cc

    # Create variables required to initialise ODE
    num_species = len(species_dict.keys())
    y0 = [0] * num_species  #Initial concentrations, set to 0
    t0 = 0.0  #T0

    # Define species concentrations in ppb
    # You have already set this in the front end script, and now we populate the y array with those concentrations
    for specie in species_initial_conc.keys():
        y0[species_dict2array[specie]] = species_initial_conc[
            specie] * Cfactor  #convert from pbb to molcules/cc

    #Set the total_time of the simulation to 0 [havent done anything yet]
    total_time = 0.0

    # Now run through the simulation in batches.
    # I do this to enable testing of coupling processes. Some initial investigations with non-ideality in
    # the condensed phase indicated that even defining a maximum step was not enough for ODE solvers to
    # overshoot a stable region. It also helps with in-simulation debugging. Its up to you if you want to keep this.
    # To not run in batches, just define one batch as your total simulation time. This will reduce any overhead with
    # initialising the solvers
    # Set total simulation time and batch steps in seconds

    # Note also that the current module outputs solver information after each batch step. This can be turned off and the
    # the batch step change for increased speed
    #simulation_time= 3600.0
    #batch_step=100.0
    t_array = []
    time_step = 0
    number_steps = int(
        simulation_time /
        batch_step)  # Just cycling through 3 steps to get to a solution

    # Define a matrix that stores values as outputs from the end of each batch step. Again, you can remove
    # the need to run in batches. You can tell the Assimulo solvers the frequency of outputs.
    y_matrix = numpy.zeros((int(number_steps), len(y0)))

    print("Starting simulation")

    # In the following, we can
    while total_time < simulation_time:

        if total_time == 0.0:
            #Define an Assimulo problem
            #Define an explicit solver
            exp_mod = Explicit_Problem(dydt_func, y0, t0, name=filename)

        else:
            y0 = y_output[
                -1, :]  # Take the output from the last batch as the start of this
            exp_mod = Explicit_Problem(dydt_func, y0, t0, name=filename)

        # Define ODE parameters.
        # Initial steps might be slower than mid-simulation. It varies.
        #exp_mod.jac = dydt_jac
        # Define which ODE solver you want to use
        exp_sim = CVode(exp_mod)
        tol_list = [1.0e-3] * num_species
        exp_sim.atol = tol_list  #Default 1e-6
        exp_sim.rtol = 0.03  #Default 1e-6
        exp_sim.inith = 1.0e-6  #Initial step-size
        #exp_sim.discr = 'Adams'
        exp_sim.maxh = 100.0
        # Use of a jacobian makes a big differece in simulation time. This is relatively
        # easy to define for a gas phase - not sure for an aerosol phase with composition
        # dependent processes.
        exp_sim.usejac = True  # To be provided as an option in future update.
        #exp_sim.fac1 = 0.05
        #exp_sim.fac2 = 50.0
        exp_sim.report_continuously = True
        exp_sim.maxncf = 1000
        #Sets the parameters
        t_output, y_output = exp_sim.simulate(
            batch_step)  #Simulate 'batch' seconds
        total_time += batch_step
        t_array.append(
            total_time
        )  # Save the output from the end step, of the current batch, to a matrix
        y_matrix[time_step, :] = y_output[-1, :]

        #now save this information into a matrix for later plotting.
        time_step += 1

    # Do you want to save the generated matrix of outputs?
    if save_output:
        numpy.save(filename + '_output', y_matrix)
        df = pd.DataFrame(y_matrix)
        df.to_csv(filename + "_output_matrix.csv")
        w = csv.writer(open(filename + "_output_names.csv", "w"))
        for specie, number in species_dict2array.items():
            w.writerow([specie, number])

    with_plots = True

    #pdb.set_trace()
    #Plot the change in concentration over time for a given specie. For the user to change / remove
    #In a future release I will add this as a seperate module
    if with_plots:

        try:
            P.plot(t_array,
                   numpy.log10(y_matrix[:, species_dict2array['APINENE']]),
                   marker='o',
                   label="APINENE")
            P.plot(t_array,
                   numpy.log10(y_matrix[:, species_dict2array['PINONIC']]),
                   marker='o',
                   label="PINONIC")
            P.title(exp_mod.name)
            P.legend(loc='upper left')
            P.ylabel("Concetration log10[molecules/cc]")
            P.xlabel("Time [seconds] since start of simulation")
            P.show()
        except:
            print(
                "There is a problem using Matplotlib in your environment. If using this within a docker container, you will need to transfer the data to the host or configure your container to enable graphical displays. More information can be found at http://wiki.ros.org/docker/Tutorials/GUI "
            )
Exemple #33
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
Exemple #34
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
Exemple #35
0
    ydot[3] = -y[1] * lambda_fkt(y[0], y[1]) - 1
    return ydot
#    ydot = -y[0]
#    return np.array([ydot])
    
def lambda_fkt(y1, y2):
    k = 100
    return k * (np.sqrt(y1**2 + y2**2) - 1) / np.sqrt(y1**2 + y2**2)
    
    
#Define an Assimulo problem
exp_mod = Explicit_Problem(f, 4)
exp_mod.name = 'Simple BDF-2 Example'

#Define another Assimulo problem
def pend(t,y):
    #g=9.81    l=0.7134354980239037
    gl=13.7503671
    return np.array([y[1],-gl*np.sin(y[0])])
    
#pend_mod=Explicit_Problem(pend, y0=np.array([2.*np.pi,1.]))
pend_mod=Explicit_Problem(f, y0=np.array([1., 0., 0., 0.]))
pend_mod.name='Nonlinear Pendulum'

#Define an explicit solver
#exp_sim = BDF_2(pend_mod) #Create a BDF solver
exp_sim = CVode(pend_mod)
t, y = exp_sim.simulate(10)
exp_sim.plot()
mpl.show()
Exemple #36
0
def run_simulation(filename, save_output, start_time, temp, RH, RO2_indices,
                   H2O, PInit, y_cond, input_dict, simulation_time, batch_step,
                   plot_mass):

    from assimulo.solvers import RodasODE, CVode, RungeKutta4, LSODAR  #Choose solver accoring to your need.
    from assimulo.problem import Explicit_Problem

    # In this function, we import functions that have been pre-compiled for use in the ODE solver
    # The function that calculates the RHS of the ODE is also defined within this function, such
    # that it can be used by the Assimulo solvers

    # The variables passed to this function are defined as follows:

    #-------------------------------------------------------------------------------------
    #-------------------------------------------------------------------------------------
    # define the ODE function to be called
    def dydt_func(t, y):
        """
        This function defines the right-hand side [RHS] of the ordinary differential equations [ODEs] to be solved
        input:
        • t - time variable [internal to solver]
        • y - array holding concentrations of all compounds in both gas and particulate [molecules/cc]
        output:
        dydt - the dy_dt of each compound in both gas and particulate phase [molecules/cc.sec]
        """

        dy_dt = numpy.zeros((total_length_y, 1), )

        #pdb.set_trace()
        # Calculate time of day
        time_of_day_seconds = start_time + t

        #pdb.set_trace()
        # make sure the y array is not a list. Assimulo uses lists
        y_asnumpy = numpy.array(y)
        Model_temp = temp
        #pdb.set_trace()
        #Calculate the concentration of RO2 species, using an index file created during parsing
        RO2 = numpy.sum(y[RO2_indices])

        #Calculate reaction rate for each equation.
        # Note that H2O will change in parcel mode
        # The time_of_day_seconds is used for photolysis rates - need to change this if want constant values
        rates = evaluate_rates_fortran(RO2, H2O, Model_temp,
                                       time_of_day_seconds)
        #pdb.set_trace()
        # Calculate product of all reactants and stochiometry for each reaction [A^a*B^b etc]
        reactants = reactants_fortran(y_asnumpy[0:num_species - 1])
        #pdb.set_trace()
        #Multiply product of reactants with rate coefficient to get reaction rate
        reactants = numpy.multiply(reactants, rates)
        #pdb.set_trace()
        # Now use reaction rates with the loss_gain matri to calculate the final dydt for each compound
        # With the assimulo solvers we need to output numpy arrays
        dydt_gas = loss_gain_fortran(reactants)
        #pdb.set_trace()

        dy_dt[0:num_species - 1, 0] = dydt_gas

        # Change the saturation vapour pressure of water
        # Need to re-think the change of organic vapour pressures with temperature.
        # At the moment this is kept constant as re-calulation using UManSysProp very slow
        sat_vap_water = numpy.exp((-0.58002206E4 / Model_temp) + 0.13914993E1 - \
        (0.48640239E-1 * Model_temp) + (0.41764768E-4 * (Model_temp**2.0E0))- \
        (0.14452093E-7 * (Model_temp**3.0E0)) + (0.65459673E1 * numpy.log(Model_temp)))
        sat_vp[-1] = (numpy.log10(sat_vap_water * 9.86923E-6))
        Psat = numpy.power(10.0, sat_vp)

        # Convert the concentration of each component in the gas phase into a partial pressure using the ideal gas law
        # Units are Pascals
        Pressure_gas = (y_asnumpy[0:num_species, ] /
                        NA) * 8.314E+6 * Model_temp  #[using R]

        core_mass_array = numpy.multiply(ycore_asnumpy / NA, core_molw_asnumpy)

        ####### Calculate the thermal conductivity of gases according to the new temperature ########
        K_water_vapour = (
            5.69 + 0.017 *
            (Model_temp - 273.15)) * 1e-3 * 4.187  #[W/mK []has to be in W/m.K]
        # Use this value for all organics, for now. If you start using a non-zero enthalpy of
        # vapourisation, this needs to change.
        therm_cond_air = K_water_vapour

        #----------------------------------------------------------------------------
        #F2c) Extract the current gas phase concentrations to be used in pressure difference calculations
        C_g_i_t = y_asnumpy[0:num_species, ]
        #Set the values for oxidants etc to 0 as will force no mass transfer
        #C_g_i_t[ignore_index]=0.0
        C_g_i_t = C_g_i_t[include_index]

        #pdb.set_trace()

        total_SOA_mass,aw_array,size_array,dy_dt_calc = dydt_partition_fortran(y_asnumpy,ycore_asnumpy,core_dissociation, \
        core_mass_array,y_density_array_asnumpy,core_density_array_asnumpy,ignore_index_fortran,y_mw,Psat, \
        DStar_org_asnumpy,alpha_d_org_asnumpy,C_g_i_t,N_perbin,gamma_gas_asnumpy,Latent_heat_asnumpy,GRAV, \
        Updraft,sigma,NA,kb,Rv,R_gas,Model_temp,cp,Ra,Lv_water_vapour)

        #pdb.set_trace()

        # Add the calculated gains/losses to the complete dy_dt array
        dy_dt[0:num_species + (num_species_condensed * num_bins),
              0] += dy_dt_calc[:]

        #pdb.set_trace()

        #----------------------------------------------------------------------------
        #F4) Now calculate the change in water vapour mixing ratio.
        #To do this we need to know what the index key for the very last element is
        #pdb.set_trace()
        #pdb.set_trace()
        #print "elapsed time=", elapsedTime
        dydt_func.total_SOA_mass = total_SOA_mass
        dydt_func.size_array = size_array
        dydt_func.temp = Model_temp
        dydt_func.RH = Pressure_gas[-1] / (Psat[-1] * 101325.0)
        dydt_func.water_activity = aw_array

        #----------------------------------------------------------------------------
        return dy_dt

    #-------------------------------------------------------------------------------------
    #-------------------------------------------------------------------------------------

    #import static compilation of Fortran functions for use in ODE solver
    print("Importing pre-compiled Fortran modules")
    from rate_coeff_f2py import evaluate_rates as evaluate_rates_fortran
    from reactants_conc_f2py import reactants as reactants_fortran
    from loss_gain_f2py import loss_gain as loss_gain_fortran
    from partition_f2py import dydt_partition as dydt_partition_fortran

    # 'Unpack' variables from input_dict
    species_dict = input_dict['species_dict']
    species_dict2array = input_dict['species_dict2array']
    species_initial_conc = input_dict['species_initial_conc']
    equations = input_dict['equations']
    num_species = input_dict['num_species']
    num_species_condensed = input_dict['num_species_condensed']
    y_density_array_asnumpy = input_dict['y_density_array_asnumpy']
    y_mw = input_dict['y_mw']
    sat_vp = input_dict['sat_vp']
    Delta_H = input_dict['Delta_H']
    Latent_heat_asnumpy = input_dict['Latent_heat_asnumpy']
    DStar_org_asnumpy = input_dict['DStar_org_asnumpy']
    alpha_d_org_asnumpy = input_dict['alpha_d_org_asnumpy']
    gamma_gas_asnumpy = input_dict['gamma_gas_asnumpy']
    Updraft = input_dict['Updraft']
    GRAV = input_dict['GRAV']
    Rv = input_dict['Rv']
    Ra = input_dict['Ra']
    R_gas = input_dict['R_gas']
    R_gas_other = input_dict['R_gas_other']
    cp = input_dict['cp']
    sigma = input_dict['sigma']
    NA = input_dict['NA']
    kb = input_dict['kb']
    Lv_water_vapour = input_dict['Lv_water_vapour']
    ignore_index = input_dict['ignore_index']
    ignore_index_fortran = input_dict['ignore_index_fortran']
    ycore_asnumpy = input_dict['ycore_asnumpy']
    core_density_array_asnumpy = input_dict['core_density_array_asnumpy']
    y_cond = input_dict['y_cond_initial']
    num_bins = input_dict['num_bins']
    core_molw_asnumpy = input_dict['core_molw_asnumpy']
    core_dissociation = input_dict['core_dissociation']
    N_perbin = input_dict['N_perbin']
    include_index = input_dict['include_index']

    # pdb.set_trace()

    #Specify some starting concentrations [ppt]
    Cfactor = 2.55e+10  #ppb-to-molecules/cc

    # Create variables required to initialise ODE
    y0 = [0] * (num_species + num_species_condensed * num_bins
                )  #Initial concentrations, set to 0
    t0 = 0.0  #T0

    # Define species concentrations in ppb fr the gas phase
    # You have already set this in the front end script, and now we populate the y array with those concentrations
    for specie in species_initial_conc.keys():
        if specie is not 'H2O':
            y0[species_dict2array[specie]] = species_initial_conc[
                specie] * Cfactor  #convert from pbb to molcules/cc
        elif specie is 'H2O':
            y0[species_dict2array[specie]] = species_initial_conc[specie]

    # Now add the initial condensed phase [including water]
    #pdb.set_trace()
    y0[num_species:num_species +
       ((num_bins) * num_species_condensed)] = y_cond[:]
    #pdb.set_trace()

    #Set the total_time of the simulation to 0 [havent done anything yet]
    total_time = 0.0

    # Define a 'key' that represents the end of the composition variables to track
    total_length_y = len(y0)
    key = num_species + ((num_bins) * num_species) - 1

    #pdb.set_trace()

    # Now run through the simulation in batches.
    # I do this to enable testing of coupling processes. Some initial investigations with non-ideality in
    # the condensed phase indicated that even defining a maximum step was not enough for ODE solvers to
    # overshoot a stable region. It also helps with in-simulation debugging. Its up to you if you want to keep this.
    # To not run in batches, just define one batch as your total simulation time. This will reduce any overhead with
    # initialising the solvers
    # Set total simulation time and batch steps in seconds

    # Note also that the current module outputs solver information after each batch step. This can be turned off and the
    # the batch step change for increased speed
    # simulation_time= 3600.0
    # batch_step=300.0
    t_array = []
    time_step = 0
    number_steps = int(
        simulation_time /
        batch_step)  # Just cycling through 3 steps to get to a solution

    # Define a matrix that stores values as outputs from the end of each batch step. Again, you can remove
    # the need to run in batches. You can tell the Assimulo solvers the frequency of outputs.
    y_matrix = numpy.zeros((int(number_steps), len(y0)))
    # Also define arrays and matrices that hold information such as total SOA mass
    SOA_matrix = numpy.zeros((int(number_steps), 1))
    size_matrix = numpy.zeros((int(number_steps), num_bins))

    print("Starting simulation")

    # In the following, we can
    while total_time < simulation_time:

        if total_time == 0.0:
            #Define an Assimulo problem
            #Define an explicit solver
            exp_mod = Explicit_Problem(dydt_func, y0, t0, name=filename)

        else:
            y0 = y_output[
                -1, :]  # Take the output from the last batch as the start of this
            exp_mod = Explicit_Problem(dydt_func, y0, t0, name=filename)

        # Define ODE parameters.
        # Initial steps might be slower than mid-simulation. It varies.
        #exp_mod.jac = dydt_jac
        # Define which ODE solver you want to use
        exp_sim = CVode(exp_mod)
        tol_list = [1.0e-2] * len(y0)
        exp_sim.atol = tol_list  #Default 1e-6
        exp_sim.rtol = 1.0e-4  #Default 1e-6
        exp_sim.inith = 1.0e-6  #Initial step-size
        #exp_sim.discr = 'Adams'
        exp_sim.maxh = 100.0
        # Use of a jacobian makes a big differece in simulation time. This is relatively
        # easy to define for a gas phase - not sure for an aerosol phase with composition
        # dependent processes.
        exp_sim.usejac = False  # To be provided as an option in future update.
        #exp_sim.fac1 = 0.05
        #exp_sim.fac2 = 50.0
        exp_sim.report_continuously = True
        exp_sim.maxncf = 1000
        #Sets the parameters
        t_output, y_output = exp_sim.simulate(
            batch_step)  #Simulate 'batch' seconds
        total_time += batch_step
        t_array.append(
            total_time
        )  # Save the output from the end step, of the current batch, to a matrix
        y_matrix[time_step, :] = y_output[-1, :]
        SOA_matrix[time_step, 0] = dydt_func.total_SOA_mass
        size_matrix[time_step, :] = dydt_func.size_array
        print("SOA [micrograms/m3] = ", dydt_func.total_SOA_mass)

        #now save this information into a matrix for later plotting.
        time_step += 1

    if save_output is True:

        print(
            "Saving the model output as a pickled object for later retrieval")
        # save the dictionary to a file for later retrieval - have to do each seperately.
        with open(filename + '_y_output.pickle', 'wb') as handle:
            pickle.dump(y_matrix, handle, protocol=pickle.HIGHEST_PROTOCOL)
        with open(filename + '_t_output.pickle', 'wb') as handle:
            pickle.dump(t_array, handle, protocol=pickle.HIGHEST_PROTOCOL)
        with open(filename + '_SOA_output.pickle', 'wb') as handle:
            pickle.dump(SOA_matrix, handle, protocol=pickle.HIGHEST_PROTOCOL)
        with open(filename + '_size_output.pickle', 'wb') as handle:
            pickle.dump(size_matrix, handle, protocol=pickle.HIGHEST_PROTOCOL)
        with open(filename + 'include_index.pickle', 'wb') as handle:
            pickle.dump(include_index,
                        handle,
                        protocol=pickle.HIGHEST_PROTOCOL)

    #pdb.set_trace()
    #Plot the change in concentration over time for a given specie. For the user to change / remove
    #In a future release I will add this as a seperate module
    if plot_mass is True:
        try:
            P.plot(t_array, SOA_matrix[:, 0], marker='o')
            P.title(exp_mod.name)
            P.ylabel("SOA mass [micrograms/m3]")
            P.xlabel("Time [seconds] since start of simulation")
            P.show()
        except:
            print(
                "There is a problem using Matplotlib in your environment. If using this within a docker container, you will need to transfer the data to the host or configure your container to enable graphical displays. More information can be found at http://wiki.ros.org/docker/Tutorials/GUI "
            )
Exemple #37
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)
Exemple #38
0
def ode_gen(t, y, num_speci, num_eqn, rindx, pindx, rstoi, pstoi, H2Oi, TEMP,
            RO2_indices, num_sb, Psat, mfp, accom_coeff, surfT, y_dens,
            N_perbin, DStar_org, y_mw, x, core_diss, Varr, Vbou, RH, rad0,
            Vol0, end_sim_time, pconc, save_step, rbou, therm_sp, Cw,
            light_time, light_stat, nreac, nprod, prodn, reacn, new_partr, MV,
            nucv1, nucv2, nucv3, inflectDp, pwl_xpre, pwl_xpro, inflectk,
            nuc_comp, ChamR, Rader, PInit, testf, kwgt):

    # ----------------------------------------------------------
    # inputs

    # t - suggested time step length (s)
    # num_speci - number of components
    # num_eqn - number of equations
    # Psat - saturation vapour pressures (molecules/cm3 (air))
    # y_dens - components' densities (g/cc)
    # y_mw - components' molecular weights (g/mol)
    # x - radii of particle size bins (um) (excluding walls)
    # therm_sp - thermal speed of components (m/s)
    # DStar_org - gas-phase diffusion coefficient of components (m2/s)
    # Cw - concentration of wall (molecules/cm3 (air))
    # light_time - times (s) of when lights on and lights off (corresponding to light
    # 				status in light_stat)
    # light_stat - order of lights on (1) and lights off (0)
    # chamA - chamber area (m2)
    # nreac - number of reactants per equation
    # nprod - number of products per equation
    # pindx - indices of equation products (cols) in each equation (rows)
    # prodn - pindx no. of columns
    # reacn - rindx no. of columns
    # rindx - index of reactants per equation
    # rstoi - stoichometry of reactants per equation
    # pstoi - stoichometry of products
    # pconc - concentration of seed particles (#/cc (air)) (1)
    # new_partr - radius of two ELVOC molecules together in a newly nucleating
    # particle (cm)
    # MV - molar volume (cc/mol) (1D array)
    # nuc_comp - index of the nucleating component
    # ChamR - spherical equivalent radius of chamber (below eq. 2 Charan (2018)) (m)
    # Rader - flag of whether or not to use Rader and McMurry approach
    # PInit - pressure inside chamber (Pa)
    # testf - flag to say whether in normal mode (0) or testing mode (1)
    # kgwt - mass transfer coefficient for vapour-wall partitioning (cm3/molecule.s)
    # ----------------------------------------------------------

    if testf == 1:
        return (0, 0, 0, 0)  # return dummies

    R_gas = si.R  # ideal gas constant (kg.m2.s-2.K-1.mol-1)
    NA = si.Avogadro  # Avogadro's number (molecules/mol)

    step = 0  # ode time interval step number
    t0 = t  # remember original suggested time step (s)
    # final +1 for ELVOC in newly nucleating particles
    y0 = np.zeros((num_speci + num_sb * num_speci))
    y0[:] = y[:]  # initial concentrations (molecules/cc (air))
    y00 = np.zeros((num_speci + num_sb * num_speci))
    y00[:] = y[:]  # initial concentrations (molecules/cc (air))

    # initial volumes of particles in size bins at start of time steps
    if num_sb > 1:
        Vstart = np.zeros((num_sb - 1))
        Vstart[:] = Vol0[:] * N_perbin
    else:
        Vstart = 0.0
    sumt = 0.0  # total time integrated over (s)

    # record initial values
    if num_sb > 0:
        # particle-phase concentrations (molecules/cc (air))
        yp = np.transpose(y[num_speci:-(num_speci)].reshape(
            num_sb - 1, num_speci))
    else:
        yp = 0.0
    [t_out, y_mat, Nresult,
     x2] = recording(y, N_perbin, x, step, sumt, 0, 0, 0, 0,
                     int(end_sim_time / save_step), num_speci, num_sb,
                     y_mw[:, 0], y_dens[:, 0] * 1.0e-3, yp, Vbou)

    tnew = 0.46875  # relatively small time step (s) for first bit
    # number concentration of nucleated particles formed (# particles/cc (air))
    new_part_sum1 = 0.0

    save_count = int(1)  # count on number of times saving code called
    # count in number of time steps since time interval was last reduced
    tinc_count = 10

    from rate_valu_calc import rate_valu_calc  # function to update rate coefficients
    print('starting ode solver')

    while sumt < end_sim_time:  # step through time intervals to do ode

        # increase time step if time step not been decreased for 10 steps
        if tinc_count == 0 and tnew < t0:
            tnew = tnew * 2.0

        # check whether lights on or off
        timediff = sumt - np.array(light_time)
        timedish = (timediff == np.min(timediff[timediff >= 0])
                    )  # reference time index
        lightm = (
            np.array(light_stat))[timedish]  # whether lights on or off now

        # update reaction rate coefficients
        reac_coef = rate_valu_calc(RO2_indices, y[H2Oi], TEMP, lightm, y)

        y0[:] = y[:]  # update initial concentrations (molecules/cc (air))
        # update particle volumes at start of time step (um3)
        Vstart = Varr * N_perbin
        redt = 1  # reset time reduction flag
        t = tnew  # reset integration time (s)

        if num_sb > 1:
            # update partitioning coefficients
            [kimt, kelv_fac
             ] = kimt_calc(y, mfp, num_sb, num_speci, accom_coeff, y_mw, surfT,
                           R_gas, TEMP, NA, y_dens, N_perbin, DStar_org,
                           x.reshape(1, -1) * 1.0e-6, Psat, therm_sp, H2Oi)

        # ensure no confusion that components are present due to low value fillers for
        # concentrations (molecules/cc (air))
        y0[y0 == 1.0e-40] = 0.0
        print()
        # enter a while loop that continues to decrease the time step until particle
        # size bins don't change by more than one size bin (given by moving centre)
        while redt == 1:
            print('cumulative time', sumt)

            # numba compiler to convert to machine code
            @jit(f8[:](f8, f8[:]), nopython=True)
            # ode solver -------------------------------------------------------------
            def dydt(t, y):

                # empty array to hold rate of change (molecules/cc(air).s)
                dydt = np.zeros((len(y)))
                # gas-phase rate of change ------------------------------------
                for i in range(num_eqn):  # equation loop

                    # gas-phase rate of change (molecules/cc (air).s)

                    gprate = ((y[rindx[i, 0:nreac[i]]]**
                               rstoi[i, 0:nreac[i]]).prod()) * reac_coef[i]
                    dydt[rindx[i, 0:nreac[i]]] -= gprate  # loss of reactants
                    dydt[pindx[i, 0:nprod[i]]] += gprate  # gain of products

                if num_sb > 1:

                    # -----------------------------------------------------------
                    for ibin in range(num_sb - 1):  # size bin loop

                        Csit = y[num_speci * (ibin + 1):num_speci * (ibin + 2)]
                        # sum of molecular concentrations per bin (molecules/cc (air))
                        conc_sum = np.zeros((1))
                        if pconc > 0.0:  # if seed particles present
                            conc_sum[0] = ((Csit[0:-1].sum()) +
                                           Csit[-1] * core_diss)
                        else:
                            conc_sum[0] = Csit.sum()
                        # prevent numerical error due to division by zero
                        ish = conc_sum == 0.0
                        conc_sum[ish] = 1.0e-40

                        # particle surface gas-phase concentration (molecules/cc (air))
                        Csit = (Csit / conc_sum) * Psat[:, 0] * kelv_fac[ibin]
                        # partitioning rate (molecules/cc.s)
                        dydt_all = kimt[:, ibin] * (y[0:num_speci] - Csit)

                        # gas-phase change
                        dydt[0:num_speci] -= dydt_all
                        # particle-phase change
                        dydt[num_speci * (ibin + 1):num_speci *
                             (ibin + 2)] += dydt_all

                # -----------------------------------------------------------
                # gas-wall partitioning eq. 14 of Zhang et al.
                # (2015) (https://www.atmos-chem-phys.net/15/4197/2015/
                # acp-15-4197-2015.pdf) (molecules/cc.s (air))

                # concentration at wall (molecules/cc (air))
                Csit = y[num_speci * num_sb:num_speci * (num_sb + 1)]
                Csit = (Psat[:, 0] * (Csit / Cw))

                # eq. 14 of Zhang et al. (2015)
                # (https://www.atmos-chem-phys.net/15/4197/2015/
                # acp-15-4197-2015.pdf) (molecules/cc.s (air))
                dydt_all = (kwgt * Cw) * (y[0:num_speci] - Csit)

                # gas-phase change
                dydt[0:num_speci] -= dydt_all
                # wall concentration change
                dydt[num_speci * num_sb:num_speci * (num_sb + 1)] += dydt_all

                return (dydt)

            mod = Explicit_Problem(dydt, y0)
            mod_sim = CVode(mod)  # define a solver instance
            mod_sim.atol = 1.0e-3  # absolute tolerance
            mod_sim.rtol = 1.0e-3  # relative tolerance
            mod_sim.discr = 'BDF'  # the integration approach, default is 'Adams'
            t_array, res = mod_sim.simulate(t)

            y = res[-1, :]

            # low value filler for concentrations (molecules/cc (air)) to prevent
            # numerical errors
            y0[y0 == 0.0] = 1.0e-40
            y[y == 0.0] = 1.0e-40

            if num_sb > 1 and (N_perbin > 1.0e-10).sum() > 0:

                # call on the moving centre method for rebinning particles
                (N_perbin, Varr, y[num_speci::], x, redt, t, tnew) = movcen(
                    N_perbin, Vbou,
                    np.transpose(y[num_speci::].reshape(num_sb, num_speci)),
                    (np.squeeze(y_dens * 1.0e-3)), num_sb, num_speci, y_mw, x,
                    Vol0, t, t0, tinc_count, y0[num_speci::], MV)
            else:
                redt = 0

            # if time step needs reducing then reset gas-phase concentrations to their
            # values preceding the ode, this will already have been done inside moving
            # centre module for particle-phase
            if redt == 1:
                y[0:num_speci] = y0[0:num_speci]

            # start counter to determine when to next try increasing time interval
            if redt == 1:
                tinc_count = 10
            if redt == 0 and tinc_count > -1:
                tinc_count -= 1
            if tinc_count == -1:
                tinc_count = 10

        sumt += t  # total time covered (s)
        step += 1  # ode time interval step number

        if num_sb > 1:
            if (N_perbin > 1.0e-10).sum() > 0:
                # coagulation
                # y indices due to final element in y being number of ELVOC molecules
                # contributing to newly nucleated particles
                [N_perbin, y[num_speci:-(num_speci)], x, Gi, eta_ai,
                 Varr] = coag(
                     RH, TEMP, x * 1.0e-6, (Varr * 1.0e-18).reshape(1, -1),
                     y_mw.reshape(-1, 1), x * 1.0e-6,
                     np.transpose(y[num_speci::].reshape(num_sb, num_speci)),
                     (N_perbin).reshape(1, -1), t,
                     (Vbou * 1.0e-18).reshape(1, -1), num_speci, 0,
                     (np.squeeze(y_dens * 1.0e-3)), rad0, PInit)

                # particle loss to walls
                [N_perbin, y[num_speci:-(num_speci)]
                 ] = wallloss(N_perbin.reshape(-1,
                                               1), y[num_speci:-(num_speci)],
                              Gi, eta_ai, x * 2.0e-6, y_mw, Varr * 1.0e-18,
                              num_sb, num_speci, TEMP, t, inflectDp, pwl_xpre,
                              pwl_xpro, inflectk, ChamR, Rader)

            # particle nucleation
            if sumt < 3600.0 and pconc == 0.0:
                [N_perbin, y, x[0], Varr[0],
                 new_part_sum1] = nuc(sumt, new_part_sum1, N_perbin, y,
                                      y_mw.reshape(-1, 1),
                                      np.squeeze(y_dens * 1.0e-3), num_speci,
                                      x[0], new_partr, t, MV, nucv1, nucv2,
                                      nucv3, nuc_comp)

        if sumt >= save_step * save_count:  # save at every time step given by save_step (s)

            if num_sb > 0:
                # particle-phase concentrations (molecules/cc (air))
                yp = np.transpose(y[num_speci:-(num_speci)].reshape(
                    num_sb - 1, num_speci))
            else:
                yp = 0.0

            # record new values
            [t_out, y_mat, Nresult,
             x2] = recording(y, N_perbin, x, save_count, sumt,
                             y_mat, Nresult, x2, t_out,
                             int(end_sim_time / save_step), num_speci, num_sb,
                             y_mw[:, 0], y_dens[:, 0] * 1.0e-3, yp, Vbou)
            save_count += int(1)

    return (t_out, y_mat, Nresult, x2)
Exemple #39
0
#  Initial conditions.  The vector X0 is passed into the solver
v0 = 45
theta = 30
theta = np.radians(theta)
X0 = np.array([0, v0 * np.cos(theta), 1, v0 * np.sin(theta)])

#  Time at start of simulation
t0 = 0.0

#  Create a model object with our equations and initial conditions
model = Explicit_Problem(no_drag, X0, t0)

#  Bind event functions to model
model.state_events = events
model.handle_event = handle_event

#  Create simulation object
sim = CVode(model)

#  Run simulation
t, X = sim.simulate(5, 100)

print(X.shape)

#print(t[-1], X[-1, :])

#  Plot results
plt.plot(X[:, 0], X[:, 2], '.')
plt.show()
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