def test_time_event(self): f = lambda t,y: [1.0] global tnext global nevent tnext = 0.0 nevent = 0 def time_events(t,y,sw): global tnext,nevent events = [1.0, 2.0, 2.5, 3.0] for ev in events: if t < ev: tnext = ev break else: tnext = None nevent += 1 return tnext def handle_event(solver, event_info): solver.y+= 1.0 global tnext nose.tools.assert_almost_equal(solver.t, tnext) assert event_info[0] == [] assert event_info[1] == True exp_mod = Explicit_Problem(f,0.0) exp_mod.time_events = time_events exp_mod.handle_event = handle_event #CVode exp_sim = CVode(exp_mod) exp_sim(5.,100) assert nevent == 5
def test_time_event(self): f = lambda t, y: [1.0] global tnext global nevent tnext = 0.0 nevent = 0 def time_events(t, y, sw): global tnext, nevent events = [1.0, 2.0, 2.5, 3.0] for ev in events: if t < ev: tnext = ev break else: tnext = None nevent += 1 return tnext def handle_event(solver, event_info): solver.y += 1.0 global tnext nose.tools.assert_almost_equal(solver.t, tnext) assert event_info[0] == [] assert event_info[1] == True exp_mod = Explicit_Problem(f, 0.0) exp_mod.time_events = time_events exp_mod.handle_event = handle_event #CVode exp_sim = CVode(exp_mod) exp_sim(5., 100) assert nevent == 5
def simulate(self, Tend, nIntervals, gridWidth): problem = Explicit_Problem(self.rhs, self.y0) problem.name = 'RK34' problem.handle_result = self.handle_result problem.handle_event = self.handle_event problem.time_events = self.time_events problem.finalize = self.finalize if hasattr(self, 'state_events'): print 'Warning: state_event function in RK34 is not supported and will be ignored!' simulation = RungeKutta34(problem) # 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 simulation.inith = self.inith # 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): 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): 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 test_switches(self): """ This tests that the switches are actually turned when override. """ f = lambda t,x,sw: N.array([1.0]) state_events = lambda t,x,sw: N.array([x[0]-1.]) def handle_event(solver, event_info): solver.sw = [False] #Override the switches to point to another instance mod = Explicit_Problem(f,[0.0]) mod.sw0 = [True] mod.state_events = state_events mod.handle_event = handle_event sim = CVode(mod) assert sim.sw[0] == True sim.simulate(3) assert sim.sw[0] == False
def test_switches(self): """ This tests that the switches are actually turned when override. """ f = lambda t,x,sw: N.array([1.0]) state_events = lambda t,x,sw: N.array([x[0]-1.]) def handle_event(solver, event_info): solver.sw = [False] #Override the switches to point to another instance mod = Explicit_Problem(f,[0.0]) mod.sw0 = [True] mod.state_events = state_events mod.handle_event = handle_event sim = Radau5ODE(mod) assert sim.sw[0] == True sim.simulate(3) assert sim.sw[0] == False
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 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. """ #X = X.copy() g = 9.81 x = X[0] vx = X[2] vy = X[3] return np.array([vx, vy, -(np.pi**2) * x, -g, 1.0]) 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. """ x = X[0] y = X[1] return [x - y] #return np.array([x - y]) 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]: #If the switch is True the pendulum bounces X = solver.y X[1] = X[0] + 1e-3 X[3] = 0.9 * (X[2] - X[3]) #solver.sw[0] = not solver.sw[0] #Change event function #Initial values phi = 1.0241592 Y0 = -13.0666666 A = 2.0003417 w = np.pi y0 = [ A * np.sin(phi), 1 + A * np.sin(phi), A * w * np.cos(phi), Y0 - A * w * np.cos(phi) - 1, 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 on Sonusoidal Platform' #Sets the name of the problem #Create an Assimulo solver (CVode) sim = CVode(mod) #sim = LSODAR(mod) sim.options['verbosity'] = 40 #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 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 # used with CVode X[1] = 1e-3 # gives better results with Dopri 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) # leaks memory!! #sim = CVode(mod) # hands and possibly leaks memory #sim = LSODAR(mod) #sim = RungeKutta34(mod) sim = Dopri5(mod) #sim.options['verbosity'] = 20 #LOUD sim.verbosity = 40 #WHISPER #sim.display_progress = False #sim.options['minh'] = 1e-4 #sim.options['rtol'] = 1e-3 # What is time_limit? sim.time_limit = 1 # #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 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. """ X = X.copy() X[0] = X[1] X[1] = -1 + 0.04 * (X[1]**2) * np.sin(X[1]) X[2] = 1 return X 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[0] - np.sin(X[2])] 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]: #If the switch is True the pendulum bounces X = solver.y if X[1] - np.cos(X[2]) < 0: X[1] = -0.9 * X[1] + 1.9 * np.cos(X[2]) #solver.sw[0] = not solver.sw[0] #Change event function #Initial values y0 = [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 on Sonusoidal Platform' #Sets the name of the problem #Create an Assimulo solver (CVode) sim = CVode(mod) #sim = LSODAR(mod) #sim.options['verbosity'] = 20 #LOUD sim.options['verbosity'] = 40 #WHISPER #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 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. """ X = X.copy() X[0] = X[1] X[1] = -1 + 0.04 * (X[1]**2) * np.sin(X[1]) X[2] = 1 return X 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[0] - np.sin(X[2])] 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]: #If the switch is True the pendulum bounces X = solver.y if X[1] - np.cos(X[2]) < 0: X[1] = -0.9*X[1] + 1.9*np.cos(X[2]) #solver.sw[0] = not solver.sw[0] #Change event function #Initial values y0 = [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 on Sonusoidal Platform' #Sets the name of the problem #Create an Assimulo solver (CVode) sim = CVode(mod) #sim = LSODAR(mod) #sim.options['verbosity'] = 20 #LOUD sim.options['verbosity'] = 40 #WHISPER #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 run_example(): def pendulum(t,y,sw): """ The ODE to be simulated. The parameter sw should be fixed during the simulation and only be changed during the event handling. """ l=1.0 g=9.81 yd_0 = y[1] yd_1 = -g/l*N.sin(y[0]) return N.array([yd_0, yd_1]) def state_events(t,y,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. """ if sw[0]: e_0 = y[0]+N.pi/4. else: e_0 = y[0] return N.array([e_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]: #If the switch is True the pendulum bounces solver.y[1] = -0.9*solver.y[1] #Change the velocity and lose energy solver.sw[0] = not solver.sw[0] #Change event function #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 #Print event information sim.print_event_data() #Plot P.plot(t,y) P.show()
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
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. """ #X = X.copy() g = 9.81 x = X[0] vx = X[2] vy = X[3] return np.array([vx, vy, -(np.pi**2)*x, -g, 1.0]) 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. """ x = X[0] y = X[1] return [x - y] #return np.array([x - y]) 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]: #If the switch is True the pendulum bounces X = solver.y X[1] = X[0] + 1e-3 X[3] = 0.9*(X[2] - X[3]) #solver.sw[0] = not solver.sw[0] #Change event function #Initial values phi = 1.0241592; Y0 = -13.0666666; A = 2.0003417; w = np.pi y0 = [A*np.sin(phi), 1+A*np.sin(phi), A*w*np.cos(phi), Y0 - A*w*np.cos(phi)-1, 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 on Sonusoidal Platform' #Sets the name of the problem #Create an Assimulo solver (CVode) sim = CVode(mod) #sim = LSODAR(mod) sim.options['verbosity'] = 40 #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
# 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()
if solver.sw[0]: #If the switch is True the pendulum bounces solver.y[1] = -0.9*solver.y[1] #Change the velocity and lose energy solver.sw[0] = not solver.sw[0] #Change event function #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