def test_input_simulation(self): """ This tests that input simulation works. """ self.m_SENS = JMUModel('QuadTankSens.jmu') self.SENS = JMIDAESens(self.m_SENS) path_result = os.path.join(get_files_path(), 'Results', 'qt_par_est_data.mat') data = loadmat(path_result,appendmat=False) # Extract data series t_meas = data['t'][6000::100,0]-60 u1 = data['u1_d'][6000::100,0] u2 = data['u2_d'][6000::100,0] # Build input trajectory matrix for use in simulation u_data = N.transpose(N.vstack((t_meas,u1,u2))) u_traj = TrajectoryLinearInterpolation(u_data[:,0], u_data[:,1:]) input_object = (['u1','u2'], u_traj) qt_mod = JMIDAESens(self.m_SENS, input_object) qt_sim = IDA(qt_mod) #Store data continuous during the simulation, important when solving a #problem with sensitivites. qt_sim.report_continuously = True #Value used when IDA estimates the tolerances on the parameters qt_sim.pbar = qt_mod.p0 #Let Sundials find consistent initial conditions by use of 'IDA_YA_YDP_INIT' qt_sim.make_consistent('IDA_YA_YDP_INIT') #Simulate qt_sim.simulate(60) #Simulate 4 seconds with 400 communication points #write_data(qt_sim) res = ResultDymolaTextual('QuadTankSens_result.txt') dx1da1 = res.get_variable_data('dx1/da1') dx1da2 = res.get_variable_data('dx1/da2') dx4da1 = res.get_variable_data('dx4/da1') nose.tools.assert_almost_equal(dx1da2.x[0], 0.000000, 4) nose.tools.assert_almost_equal(dx1da2.x[-1], 0.00000, 4)
def run_example(with_plots=True): """ This example show how to use Assimulo and IDA for simulating sensitivities for initial conditions.:: 0 = dy1/dt - -(k01+k21+k31)*y1 - k12*y2 - k13*y3 - b1 0 = dy2/dt - k21*y1 + (k02+k12)*y2 0 = dy3/dt - k31*y1 + k13*y3 y1(0) = p1, y2(0) = p2, y3(0) = p3 p1=p2=p3 = 0 See http://sundials.2283335.n4.nabble.com/Forward-sensitivities-for-initial-conditions-td3239724.html on return: - :dfn:`imp_mod` problem instance - :dfn:`imp_sim` solver instance """ def f(t, y, yd, p): y1, y2, y3 = y yd1, yd2, yd3 = yd k01 = 0.0211 k02 = 0.0162 k21 = 0.0111 k12 = 0.0124 k31 = 0.0039 k13 = 0.000035 b1 = 49.3 res_0 = -yd1 - (k01 + k21 + k31) * y1 + k12 * y2 + k13 * y3 + b1 res_1 = -yd2 + k21 * y1 - (k02 + k12) * y2 res_2 = -yd3 + k31 * y1 - k13 * y3 return N.array([res_0, res_1, res_2]) #The initial conditions y0 = [0.0, 0.0, 0.0] #Initial conditions for y yd0 = [49.3, 0., 0.] 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 implicit problem imp_mod = Implicit_Problem(f, y0, yd0, p0=p0, name='Example: Computing Sensitivities') #Sets the options to the problem imp_mod.yS0 = yS0 #Create an Assimulo explicit solver (IDA) imp_sim = IDA(imp_mod) #Sets the paramters imp_sim.rtol = 1e-7 imp_sim.atol = 1e-6 imp_sim.pbar = [ 1, 1, 1 ] #pbar is used to estimate the tolerances for the parameters imp_sim.report_continuously = True #Need to be able to store the result using the interpolate methods imp_sim.sensmethod = 'SIMULTANEOUS' #Defines the sensitvity method used imp_sim.suppress_sens = False #Dont suppress the sensitivity variables in the error test. #Simulate t, y, yd = imp_sim.simulate(400) #Simulate 400 seconds #Basic test nose.tools.assert_almost_equal(y[-1][0], 1577.6552477, 3) nose.tools.assert_almost_equal(y[-1][1], 611.9574565, 3) nose.tools.assert_almost_equal(y[-1][2], 2215.88563217, 3) nose.tools.assert_almost_equal(imp_sim.p_sol[0][1][0], 1.0) #Plot if with_plots: P.figure(1) P.subplot(221) P.plot(t, N.array(imp_sim.p_sol[0])[:, 0], t, N.array(imp_sim.p_sol[0])[:, 1], t, N.array(imp_sim.p_sol[0])[:, 2]) P.title("Parameter p1") P.legend(("p1/dy1", "p1/dy2", "p1/dy3")) P.subplot(222) P.plot(t, N.array(imp_sim.p_sol[1])[:, 0], t, N.array(imp_sim.p_sol[1])[:, 1], t, N.array(imp_sim.p_sol[1])[:, 2]) P.title("Parameter p2") P.legend(("p2/dy1", "p2/dy2", "p2/dy3")) P.subplot(223) P.plot(t, N.array(imp_sim.p_sol[2])[:, 0], t, N.array(imp_sim.p_sol[2])[:, 1], t, N.array(imp_sim.p_sol[2])[:, 2]) P.title("Parameter p3") P.legend(("p3/dy1", "p3/dy2", "p3/dy3")) P.subplot(224) P.title('ODE Solution') P.plot(t, y) P.suptitle(imp_mod.name) P.show() return imp_mod, imp_sim
def dae_solver(residual, y0, yd0, t0, p0=None, jac=None, name='DAE', solver='IDA', algvar=None, atol=1e-6, backward=False, display_progress=True, pbar=None, report_continuously=False, rtol=1e-6, sensmethod='STAGGERED', suppress_alg=False, suppress_sens=False, usejac=False, usesens=False, verbosity=30, tfinal=10., ncp=500): ''' DAE solver. Parameters ---------- residual: function Implicit DAE model. y0: List[float] Initial model state. yd0: List[float] Initial model state derivatives. t0: float Initial simulation time. p0: List[float] Parameters for which sensitivites are to be calculated. jac: function Model jacobian. name: string Model name. solver: string DAE solver. algvar: List[bool] A list for defining which variables are differential and which are algebraic. The value True(1.0) indicates a differential variable and the value False(0.0) indicates an algebraic variable. atol: float Absolute tolerance. backward: bool Specifies if the simulation is done in reverse time. display_progress: bool Actives output during the integration in terms of that the current integration is periodically printed to the stdout. Report_continuously needs to be activated. pbar: List[float] An array of positive floats equal to the number of parameters. Default absolute values of the parameters. Specifies the order of magnitude for the parameters. Useful if IDAS is to estimate tolerances for the sensitivity solution vectors. report_continuously: bool Specifies if the solver should report the solution continuously after steps. rtol: float Relative tolerance. sensmethod: string Specifies the sensitivity solution method. Can be either ‘SIMULTANEOUS’ or ‘STAGGERED’. Default is 'STAGGERED'. suppress_alg: bool Indicates that the error-tests are suppressed on algebraic variables. suppress_sens: bool Indicates that the error-tests are suppressed on the sensitivity variables. usejac: bool Sets the option to use the user defined jacobian. usesens: bool Aactivates or deactivates the sensitivity calculations. verbosity: int Determines the level of the output. QUIET = 50 WHISPER = 40 NORMAL = 30 LOUD = 20 SCREAM = 10 tfinal: float Simulation final time. ncp: int Number of communication points (number of return points). Returns ------- sol: solution [time, model states], List[float] ''' if usesens is True: # parameter sensitivity model = Implicit_Problem(residual, y0, yd0, t0, p0=p0) else: model = Implicit_Problem(residual, y0, yd0, t0) model.name = name if usejac is True: # jacobian model.jac = jac if algvar is not None: # differential or algebraic variables model.algvar = algvar if solver == 'IDA': # solver from assimulo.solvers import IDA sim = IDA(model) sim.atol = atol sim.rtol = rtol sim.backward = backward # backward in time sim.report_continuously = report_continuously sim.display_progress = display_progress sim.suppress_alg = suppress_alg sim.verbosity = verbosity if usesens is True: # sensitivity sim.sensmethod = sensmethod sim.pbar = np.abs(p0) sim.suppress_sens = suppress_sens # Simulation # t, y, yd = sim.simulate(tfinal, ncp=(ncp - 1)) ncp_list = np.linspace(t0, tfinal, num=ncp, endpoint=True) t, y, yd = sim.simulate(tfinal, ncp=0, ncp_list=ncp_list) # Plot # sim.plot() # plt.figure() # plt.subplot(221) # plt.plot(t, y[:, 0], 'b.-') # plt.legend([r'$\lambda$']) # plt.subplot(222) # plt.plot(t, y[:, 1], 'r.-') # plt.legend([r'$\dot{\lambda}$']) # plt.subplot(223) # plt.plot(t, y[:, 2], 'k.-') # plt.legend([r'$\eta$']) # plt.subplot(224) # plt.plot(t, y[:, 3], 'm.-') # plt.legend([r'$\dot{\eta}$']) # plt.figure() # plt.subplot(221) # plt.plot(t, yd[:, 0], 'b.-') # plt.legend([r'$\dot{\lambda}$']) # plt.subplot(222) # plt.plot(t, yd[:, 1], 'r.-') # plt.legend([r'$\ddot{\lambda}$']) # plt.subplot(223) # plt.plot(t, yd[:, 2], 'k.-') # plt.legend([r'$\dot{\eta}$']) # plt.subplot(224) # plt.plot(t, yd[:, 3], 'm.-') # plt.legend([r'$\ddot{\eta}$']) # plt.figure() # plt.subplot(121) # plt.plot(y[:, 0], y[:, 1]) # plt.xlabel(r'$\lambda$') # plt.ylabel(r'$\dot{\lambda}$') # plt.subplot(122) # plt.plot(y[:, 2], y[:, 3]) # plt.xlabel(r'$\eta$') # plt.ylabel(r'$\dot{\eta}$') # plt.figure() # plt.subplot(121) # plt.plot(yd[:, 0], yd[:, 1]) # plt.xlabel(r'$\dot{\lambda}$') # plt.ylabel(r'$\ddot{\lambda}$') # plt.subplot(122) # plt.plot(yd[:, 2], yd[:, 3]) # plt.xlabel(r'$\dot{\eta}$') # plt.ylabel(r'$\ddot{\eta}$') # plt.figure() # plt.subplot(121) # plt.plot(y[:, 0], y[:, 2]) # plt.xlabel(r'$\lambda$') # plt.ylabel(r'$\eta$') # plt.subplot(122) # plt.plot(y[:, 1], y[:, 3]) # plt.xlabel(r'$\dot{\lambda}$') # plt.ylabel(r'$\dot{\eta}$') # plt.figure() # plt.subplot(121) # plt.plot(yd[:, 0], yd[:, 2]) # plt.xlabel(r'$\dot{\lambda}$') # plt.ylabel(r'$\dot{\eta}$') # plt.subplot(122) # plt.plot(yd[:, 1], yd[:, 3]) # plt.xlabel(r'$\ddot{\lambda}$') # plt.ylabel(r'$\ddot{\eta}$') # plt.show() sol = [t, y, yd] return sol
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 IDA, 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)&=0 \\ \dot y_2 -(p_1 y_1 - p_2 y_2 y_3 - p_3 y_2^2)&=0 \\ \dot y_3 -( p_3 y_ 2^2)&=0 on return: - :dfn:`imp_mod` problem instance - :dfn:`imp_sim` solver instance """ def f(t, y, yd, p): res1 = -p[0] * y[0] + p[1] * y[1] * y[2] - yd[0] res2 = p[0] * y[0] - p[1] * y[1] * y[2] - p[2] * y[1] ** 2 - yd[1] res3 = y[0] + y[1] + y[2] - 1 return N.array([res1, res2, res3]) # The initial conditons y0 = N.array([1.0, 0.0, 0.0]) # Initial conditions for y yd0 = N.array([0.1, 0.0, 0.0]) # Initial conditions for dy/dt p0 = [0.040, 1.0e4, 3.0e7] # Initial conditions for parameters # Create an Assimulo implicit problem imp_mod = Implicit_Problem(f, y0, yd0, p0=p0) # Create an Assimulo implicit solver (IDA) imp_sim = IDA(imp_mod) # Create a IDA solver # Sets the paramters imp_sim.atol = N.array([1.0e-8, 1.0e-14, 1.0e-6]) imp_sim.algvar = [1.0, 1.0, 0.0] imp_sim.suppress_alg = False # Suppres the algebraic variables on the error test imp_sim.report_continuously = True # Store data continuous during the simulation imp_sim.pbar = p0 imp_sim.suppress_sens = False # Dont suppress the sensitivity variables in the error test. # Let Sundials find consistent initial conditions by use of 'IDA_YA_YDP_INIT' imp_sim.make_consistent('IDA_YA_YDP_INIT') # Simulate t, y, yd = imp_sim.simulate(4, 400) # Simulate 4 seconds with 400 communication points print(imp_sim.p_sol[0][-1], imp_sim.p_sol[1][-1], imp_sim.p_sol[0][-1]) # 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(imp_sim.p_sol[0][-1][0], -1.8761, 2) # Values taken from the example in Sundials nose.tools.assert_almost_equal(imp_sim.p_sol[1][-1][0], 2.9614e-06, 8) nose.tools.assert_almost_equal(imp_sim.p_sol[2][-1][0], -4.9334e-10, 12) # Plot if with_plots: P.plot(t, y) P.title(imp_mod.name) P.xlabel('Time') P.ylabel('State') P.show() return imp_mod, imp_sim