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