예제 #1
0
    def _setup_sim(self, **kwargs):
        """ Create a simulation interface to Assimulo using CVODE, given
        a problem definition

        """

        # Create Assimulo interface
        sim = CVode(self.prob)
        sim.discr = 'BDF'
        sim.maxord = 5

        # Setup some default arguments for the ODE solver, or override
        # if available. This is very hackish, but it's fine for now while
        # the number of anticipated tuning knobs is small.
        if 'maxh' in kwargs:
            sim.maxh = kwargs['maxh']
        else:
            sim.maxh = np.min([0.1, self.output_dt])

        if 'minh' in kwargs:
            sim.minh = kwargs['minh']
        # else: sim.minh = 0.001

        if "iter" in kwargs:
            sim.iter = kwargs['iter']
        else:
            sim.iter = 'Newton'

        if "linear_solver" in kwargs:
            sim.linear_solver = kwargs['linear_solver']

        if "max_steps" in kwargs:  # DIFFERENT NAME!!!!
            sim.maxsteps = kwargs['max_steps']
        else:
            sim.maxsteps = 1000

        if "time_limit" in kwargs:
            sim.time_limit = kwargs['time_limit']
            sim.report_continuously = True
        else:
            sim.time_limit = 0.0

        # Don't save the [t_-, t_+] around events
        sim.store_event_points = False

        # Setup tolerances
        nr = self.args[0]
        sim.rtol = state_rtol
        sim.atol = state_atol + [1e-12] * nr

        if not self.console:
            sim.verbosity = 50
        else:
            sim.verbosity = 40
        # sim.report_continuously = False

        # Save the Assimulo interface
        return sim
예제 #2
0
    def _setup_sim(self, **kwargs):
        """ Create a simulation interface to Assimulo using CVODE, given
        a problem definition

        """

        # Create Assimulo interface
        sim = CVode(self.prob)
        sim.discr = 'BDF'
        sim.maxord = 5

        # Setup some default arguments for the ODE solver, or override
        # if available. This is very hackish, but it's fine for now while
        # the number of anticipated tuning knobs is small.
        if 'maxh' in kwargs:
            sim.maxh = kwargs['maxh']
        else:
            sim.maxh = np.min([0.1, self.output_dt])

        if 'minh' in kwargs:
            sim.minh = kwargs['minh']
        # else: sim.minh = 0.001

        if "iter" in kwargs:
            sim.iter = kwargs['iter']
        else:
            sim.iter = 'Newton'

        if "linear_solver" in kwargs:
            sim.linear_solver = kwargs['linear_solver']

        if "max_steps" in kwargs:  # DIFFERENT NAME!!!!
            sim.maxsteps = kwargs['max_steps']
        else:
            sim.maxsteps = 1000

        if "time_limit" in kwargs:
            sim.time_limit = kwargs['time_limit']
            sim.report_continuously = True
        else:
            sim.time_limit = 0.0

        # Don't save the [t_-, t_+] around events
        sim.store_event_points = False

        # Setup tolerances
        nr = self.args[0]
        sim.rtol = state_rtol
        sim.atol = state_atol + [1e-12]*nr

        if not self.console:
            sim.verbosity = 50
        else:
            sim.verbosity = 40
        # sim.report_continuously = False

        # Save the Assimulo interface
        return sim
예제 #3
0
    def _solve_cvode(f, t, y0, args, console=False, max_steps=1000, terminate=False):
        """Wrapper for Assimulo's CVODE-Sundials routine
        """
        def rhs(t, u):
            return f(u, t, *args)

        prob = Explicit_Problem(rhs, y0)
        sim = CVode(prob)
        sim.rtol = 1e-15
        sim.atol = 1e-12
        sim.discr = 'BDF'
        sim.maxord = 5 
        sim.maxsteps = max_steps

        if not console:
            sim.verbosity = 50
        else:
            sim.report_continuously = True


        t_end = t[-1]
        steps = len(t)

        try:
            print t_end, steps
            t, x = sim.simulate(t_end, steps)
        except CVodeError, e:
            raise ValueError("Something broke in CVode: %r" % e)
            return None, False
예제 #4
0
def run_example(with_plots=True):
    global t, y
    #Create an instance of the problem
    iter_mod = Extended_Problem() #Create the problem

    iter_sim = CVode(iter_mod) #Create the solver
    
    iter_sim.verbosity = 0
    iter_sim.continuous_output = True
    
    #Simulate
    t, y = iter_sim.simulate(10.0,1000) #Simulate 10 seconds with 1000 communications points
    
    #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)
    
    #Plot
    if with_plots:
        P.plot(t,y)
        P.show()
예제 #5
0
def run_example(with_plots=True):
    global t, y
    #Create an instance of the problem
    iter_mod = Extended_Problem()  #Create the problem

    iter_sim = CVode(iter_mod)  #Create the solver

    iter_sim.verbosity = 0
    iter_sim.continuous_output = True

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

    #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)

    #Plot
    if with_plots:
        P.plot(t, y)
        P.show()
예제 #6
0
def create_model():
    def nav(t, X, sw):
        """
        The ODE to be simulated. The parameter sw should be fixed during
        the simulation and only be changed during the event handling.
        """
        A, b = get_dyn(sw2mode(sw))
        return np.dot(A, X) + b

    def state_events(t, X, sw):
        """
        This is our function that keep track of our events, when the sign
        of any of the events has changed, we have an event.
        """
        #TODO: is this the best way?
        mode = sw2mode(sw)
        g = get_guard_vals(X, mode)
        G = [g[0], g[1], g[2], g[3]]  # y == 0
        if debug:
            print(mode)
            print('G =', G)
        return G

    def handle_event(solver, event_info):
        """
        Event handling. This functions is called when Assimulo finds an event as
        specified by the event functions.
        """
        state_info = event_info[
            0]  #We are only interested in state events info
        if debug:
            print('############### EVENT DETECTED')
        g = state_info
        if g[0] <= 0 or g[1] <= 0 or g[2] <= 0 or g[3] <= 0:
            mode = sw2mode(solver.sw)
            mode_ = new_mode(g, mode)
            if debug:
                print('############### new_mode =', mode_)
            solver.sw = mode2sw(mode_)

    #Initial values
    y0 = [0., 0., 0., 0.]  #Initial states
    t0 = 5.0  #Initial time
    switches0 = [False] * NUM_MODES  #Initial switches
    # Without the below statemment, it hits an error
    switches0[79] = True

    #Create an Assimulo Problem
    mod = Explicit_Problem(nav, 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 = 'nav30'  #Sets the name of the problem

    #Create an Assimulo solver (CVode)
    sim = CVode(mod)
    #sim = LSODAR(mod)
    #sim = RungeKutta34(mod)
    #sim.options['verbosity'] = 20 #LOUD
    #sim.options['verbosity'] = 40 #WHISPER
    sim.verbosity = 40  #WHISPER
    #sim.display_progress = True
    #sim.options['minh'] = 1e-4
    #sim.options['rtol'] = 1e-3

    #     #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

    return sim
예제 #7
0
    def simulate(self, t:numpy.ndarray, parameters:dict=None, verbosity:int=30, reset_afterwards:bool=False, suppress_stdout:bool=True) -> List[TimeSeries]:
        """
        Runs a forward simulation for the fully specified model and its observation functions (if specified).

        Arguments
        ---------
            t : numpy.ndarray or float
                The time points for integration. In case a single time point is provided, 
                the solver will treat this as final integration time and chooses the intermediate steps on its own.

        Keyword arguments
        -----------------
            parameters : dict
                In case a simulation for specific parameter values is wanted. 
                Default is None.
            verbosity : int
                Prints solver statistics (quiet = 50, whisper = 40, normal = 30, loud = 20, scream = 10). 
                Default is 30.
            reset_afterwards : bool
                After simulation, reset the Simulator instance to its state directly after instantiation. 
                Useful, if parameters argument is used.
            suppress_stdout : bool
                No printouts of integrator warnings, which are directed to stdout by the assimulo package.
                Set to False for model debugging purposes.
                Default is True.

        Returns
        -------
            simulations : List[TimeSeries]
                The collection of simulations results as `ModelState` objects
                and `Observation` objects (if at least one `ObservationFunction` has been specified)

        Raises
        ------
            ValueError 
                Not all parameters have values.
        """

        if parameters is not None:
            self.set_parameters(parameters)

        # Create the solver from problem instance
        exp_sim = CVode(self.bioprocess_model)
        exp_sim.verbosity = verbosity # QUIET = 50 WHISPER = 40 NORMAL = 30 LOUD = 20 SCREAM = 10
        exp_sim.store_event_points = False
        exp_sim.discr = 'BDF'
        exp_sim.stablimit = True

        if self.integrator_kwargs is not None:
            for key in list(self.integrator_kwargs.keys()):
                exec(f'exp_sim.{key} = self.integrator_kwargs["{key}"]')

        # Do the actual forward simulation
        _t = numpy.array(t, dtype=numpy.float64).flatten()
        if len(_t) == 1:
            tfinal = float(_t)
            ncp_list = None
        elif len(_t) > 1:
            ncp_list = _t
            tfinal = numpy.max(_t)
        try:
            if suppress_stdout:
                f = io.StringIO()
                with redirect_stdout(f):
                    t, y = exp_sim.simulate(tfinal=tfinal, ncp_list=ncp_list)
            else:
                t, y = exp_sim.simulate(tfinal=tfinal, ncp_list=ncp_list)
        except CVodeError as e:
            print(f'CVodeError occured with flag {e.value}. CVodeError message was: {e}.')
            raise e

        # clean double entry artifacts due to event detection
        unq, unq_idx = numpy.unique(t, return_index=True)

        # build model prediction dictionary
        model_predictions = [
            ModelState(
                name=_name, 
                timepoints=numpy.array(t)[unq_idx], 
                values=numpy.array(_y)[unq_idx], 
                replicate_id=self.replicate_id,
                ) 
            for _name, _y in zip(self.bioprocess_model.states, y.T)
        ]

        if self.observer is not None:
            observations = self.observer.get_observations(model_predictions)
        else:
            observations = []

        if reset_afterwards:
            self.reset()

        simulations = []
        simulations.extend(model_predictions)
        simulations.extend(observations)

        return simulations
예제 #8
0
파일: bball.py 프로젝트: zutshi/S3CAMR
def create_model():
    def pendulum(t, X, sw):
        """
        The ODE to be simulated. The parameter sw should be fixed during
        the simulation and only be changed during the event handling.
        """
        g = 1

        Y = X.copy()
        Y[0] = X[2]     #x_dot
        Y[1] = X[3]     #y_dot
        Y[2] = 0        #vx_dot
        Y[3] = -g       #vy_dot
        return Y

    def state_events(t, X, sw):
        """
        This is our function that keep track of our events, when the sign
        of any of the events has changed, we have an event.
        """
        return [X[1]] # y == 0

    def handle_event(solver, event_info):
        """
        Event handling. This functions is called when Assimulo finds an event as
        specified by the event functions.
        """
        state_info = event_info[0] #We are only interested in state events info

        if state_info[0] != 0: #Check if the first event function have been triggered
            if solver.sw[0]:
                X = solver.y
                if X[3] < 0: # if the ball is falling (vy < 0)
                    # bounce!
                    X[1] = 1e-5
                    X[3] = -0.75*X[3]

            #solver.sw[0] = not solver.sw[0] #Change event function

    #Initial values
    y0 = [0., 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 = 'Bouncing Ball in X-Y'   #Sets the name of the problem

    #Create an Assimulo solver (CVode)
    sim = CVode(mod)
    #sim = LSODAR(mod)
    #sim = RungeKutta34(mod)
    #sim.options['verbosity'] = 20 #LOUD
    sim.verbosity = 40 #WHISPER
    #sim.display_progress = True
    #sim.options['minh'] = 1e-4
    #sim.options['rtol'] = 1e-3

#     #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

    return sim