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)
Example #2
0
class TestStaticOptimizationDependentParameters:

    @classmethod
    def setUpClass(cls):
        curr_dir = os.path.dirname(os.path.abspath(__file__));
        mofile = os.path.join(get_files_path(), 'Modelica', 'StaticOptimizationTest.mop')
        compile_jmu("StaticOptimizationTest.StaticOptimizationTest2", mofile)
        cls.model = JMUModel("StaticOptimizationTest_StaticOptimizationTest2.jmu")
        cls.nlp = NLPInitialization(cls.model,stat=1)
        cls.ipopt_nlp = InitializationOptimizer(cls.nlp)

    @testattr(ipopt = True)
    def setUp(self):
        self.ipopt_nlp.init_opt_ipopt_solve();
        self.nlp.export_result_dymola()
        self.res = ResultDymolaTextual(
            "StaticOptimizationTest_StaticOptimizationTest2_result.txt")

    @testattr(ipopt = True)
    def test_parameter_value(self):
        k = self.res.get_variable_data("k")
        assert k.x[0] == 1.1

    @testattr(ipopt = True)
    def test_initialization_from_model(self):
        self.model.set("k",-1)
        self.nlp.init_opt_set_initial_from_model()
        assert self.nlp.init_opt_get_x()[0] == -1
Example #3
0
    def test_init_opt_write_result(self):

        cpath_daeinit = "DAEInitTest"
        fname_daeinit = cpath_daeinit.replace('.','_',1)
    
        # self.init_nlp_ipopt.init_opt_ipopt_set_string_option("derivative_test","first-order")
        
        self.init_nlp_ipopt.init_opt_ipopt_solve()

        self.init_nlp.export_result_dymola()
        
        res = ResultDymolaTextual(fname_daeinit + "_result.txt")

        res_Z = N.array([5.,
                         -198.1585290151921,
                         -0.2431975046920718,
                         3.0,
                         4.0,
                         1.0,
                         2197.0,
                         5.0,
                         -0.92009689684513785,
                         0.])

        assert N.abs(res_Z[0] - res.get_variable_data("p").x[0])<1e-3 
        assert N.abs(res_Z[1] - res.get_variable_data("der(x1)").x[0])<1e-3
        assert N.abs(res_Z[2] - res.get_variable_data("der(x2)").x[0])<1e-3
        assert N.abs(res_Z[3] - res.get_variable_data("x1").x[0])<1e-3
        assert N.abs(res_Z[4] - res.get_variable_data("x2").x[0])<1e-3
        assert N.abs(res_Z[5] - res.get_variable_data("u").x[0])<1e-3
        assert N.abs(res_Z[6] - res.get_variable_data("y1").x[0])<1e-3
        assert N.abs(res_Z[7] - res.get_variable_data("y2").x[0])<1e-3
        assert N.abs(res_Z[8] - res.get_variable_data("y3").x[0])<1e-3
Example #4
0
    def setUp(self):
        resfile = os.path.join(get_files_path(), 'Results', 
            'BlockingInitPack_M_init_result.txt')
        self.res_init = ResultDymolaTextual(resfile)

        self.n_e = 5 # Number of elements 
        self.hs = N.ones(self.n_e)*1./self.n_e # Equidistant points
        self.n_cp = 3; # Number of collocation points in each element

        # Blocking factors for control parametrization
        blocking_factors=N.ones(self.n_e,dtype=N.int)

        self.nlp = NLPCollocationLagrangePolynomials(self.opt_model,
            self.n_e,self.hs,self.n_cp,blocking_factors)

        self.nlp.set_initial_from_dymola(self.res_init, self.hs, 0., 10.)

        self.nlp.export_result_dymola("qwe.txt")

        self.res_init2 = ResultDymolaTextual('qwe.txt')
Example #5
0
    def test_init(self):

        m = JMUModel(self.jn)

        # Create a new collocation object
        n_e = 30
        coll = NLPCollocationLagrangePolynomials(m,n_e, N.ones(n_e)/n_e, 3)

        # Initialize with optimization result
        coll.set_initial_from_dymola(self.res.result_data,N.array([]),0,1)

        # Write initial point to file
        coll.export_result_dymola('Init_res.txt')

        # Load result
        res_init = ResultDymolaTextual('Init_res.txt')

        # Load test fixture
        res_init_fix = ResultDymolaTextual(self.curr_dir + '/../files/Results/MinTimeInit_init_fix.txt')

        # Extract trajectories
        dx = res_init.get_variable_data('der(x)')
        dv = res_init.get_variable_data('der(v)')
        x = res_init.get_variable_data('x')
        v = res_init.get_variable_data('v')
        u = res_init.get_variable_data('u')

        dx_fix = res_init_fix.get_variable_data('der(x)')
        dv_fix = res_init_fix.get_variable_data('der(v)')
        x_fix = res_init_fix.get_variable_data('x')
        v_fix = res_init_fix.get_variable_data('v')
        u_fix = res_init_fix.get_variable_data('u')

        # Comparison tests
        N.testing.assert_array_almost_equal(dx_fix.x,dx.x)
        N.testing.assert_array_almost_equal(dv_fix.x,dv.x)
        N.testing.assert_array_almost_equal(x_fix.x,x.x)
        N.testing.assert_array_almost_equal(v_fix.x,v.x)
        N.testing.assert_array_almost_equal(u_fix.x,u.x)

        if False:
            plt.figure(1)
            plt.subplot(2,1,1)
            plt.plot(x.t,x.x,'r')
            plt.hold(True)
            plt.plot(v.t,v.x,'r')
            plt.grid(True)
            plt.subplot(2,1,2)
            plt.plot(u.t,u.x,'r')
            plt.grid(True)
Example #6
0
suppress_alg = False
solver = "IDA"
#~ solver = "Radau5DAE"
expand_to_sx = True
#~ expand_to_sx = False
caus_opts = sp.CausalizationOptions()
#~ caus_opts['plots'] = True
caus_opts['draw_blt'] = True
#~ caus_opts['solve_blocks'] = True
#~ caus_opts['inline'] = False
#~ caus_opts['closed_form'] = True
caus_opts['dense_tol'] = 1e10
#~ caus_opts['inline_solved'] = True

#~ sim_res = ResultDymolaTextual(os.path.join(get_files_path(), "vehicle_turn_dymola.txt"))
sim_res = ResultDymolaTextual("opt_asphalt.txt")
start_time = 0.
final_time = sim_res.get_variable_data('time').t[-1]
ncp = 500
ncp = 0
class_name = "Car"
file_paths = "st_wf.mop"
opts = {'generate_html_diagnostics': True, 'state_initial_equations': True}
model = transfer_model(class_name, file_paths, compiler_options=opts)
grad_model = transfer_model("Car", file_paths, compiler_options=opts)
init_fmu = load_fmu(compile_fmu(class_name, file_paths, compiler_options=opts))

# Create input data
# This would have worked if one input was not constant...
#~ columns = [0]
#~ columns += [sim_res.get_column(input_var.getName()) for input_var in model.getVariables(model.REAL_INPUT)]
Example #7
0
class TestOptInitBlockingFactors:
    @classmethod
    def setUpClass(cls):
        cls.curr_dir = os.path.dirname(os.path.abspath(__file__));
        mofile = os.path.join(get_files_path(), 'Modelica', 
                'BlockingError.mop')

        m = compile_jmu("BlockingInitPack.M_init", mofile)
        cls.model = JMUModel(m)
        
        m = compile_jmu("BlockingInitPack.M_Opt",mofile)
        cls.opt_model = JMUModel(m)
        
    @testattr(ipopt = True)
    def setUp(self):
        resfile = os.path.join(get_files_path(), 'Results', 
            'BlockingInitPack_M_init_result.txt')
        self.res_init = ResultDymolaTextual(resfile)

        self.n_e = 5 # Number of elements 
        self.hs = N.ones(self.n_e)*1./self.n_e # Equidistant points
        self.n_cp = 3; # Number of collocation points in each element

        # Blocking factors for control parametrization
        blocking_factors=N.ones(self.n_e,dtype=N.int)

        self.nlp = NLPCollocationLagrangePolynomials(self.opt_model,
            self.n_e,self.hs,self.n_cp,blocking_factors)

        self.nlp.set_initial_from_dymola(self.res_init, self.hs, 0., 10.)

        self.nlp.export_result_dymola("qwe.txt")

        self.res_init2 = ResultDymolaTextual('qwe.txt')


    @testattr(ipopt = True)
    def test_initialization(self):


        m_x1_1 = self.res_init.get_variable_data("m.x[1]").x
        m_x1_2 = self.res_init2.get_variable_data("m.x[1]").x
        
        m_x2_1 = self.res_init.get_variable_data("m.x[2]").x
        m_x2_2 = self.res_init2.get_variable_data("m.x[2]").x
        
        m_y_1 = self.res_init.get_variable_data("m.y").x
        m_y_2 = self.res_init2.get_variable_data("m.y").x
        
        u_1 = self.res_init.get_variable_data("u").x
        u_2 = self.res_init2.get_variable_data("u").x
        
        (n_x, n_g, n_h, dg_n_nz, dh_n_nz) = self.nlp.opt_coll_get_dimensions()
        
        x_init = N.zeros(n_x)
        self.nlp.opt_coll_get_initial(x_init)
        
        nbr_dx = self.nlp._model._n_real_dx.value
        nbr_x  = self.nlp._model._n_real_x.value
        nbr_u  = self.nlp._model._n_real_u.value
        nbr_w  = self.nlp._model._n_real_w.value
        
        offs1 = nbr_dx + nbr_x + nbr_u + nbr_w
        offs2 = offs1 - 1
        #print nbr_dx, nbr_x, nbr_u, nbr_w, offs1, offs2
        offs_x_el_junc = offs1 + offs2*self.n_e*self.n_cp + self.n_e
        
        x_el_junc = N.zeros((self.n_e,3))
        
        for i in range(self.n_e):
            x_el_junc[i,:] = x_init[offs_x_el_junc + i*3:offs_x_el_junc + (i+1)*3]

        t_f = 10.

        t_x_el_junc = N.linspace(0,t_f,self.n_e+1)
        t_x_el_junc = t_x_el_junc[1:]

        offs_dx_p = offs1 + offs2*self.n_e*self.n_cp + 4*self.n_e
        offs_x_p = offs_dx_p + nbr_dx
        offs_u_p = offs_x_p + nbr_x
        offs_w_p = offs_u_p + nbr_u

        n_tp = 10
        
        dx_p = N.zeros((n_tp,nbr_dx))
        x_p  = N.zeros((n_tp,nbr_x))
        u_p  = N.zeros((n_tp,nbr_u))
        w_p  = N.zeros((n_tp,nbr_w))
        
        for i in range(n_tp):
            dx_p[i,:] = x_init[offs_dx_p + i*offs1:offs_dx_p + i*offs1 + nbr_dx]
            x_p[i,:]  = x_init[offs_x_p  + i*offs1:offs_x_p  + i*offs1 + nbr_x]
            u_p[i,:]  = x_init[offs_u_p  + i*offs1:offs_u_p  + i*offs1 + nbr_u]
            w_p[i,:]  = x_init[offs_w_p  + i*offs1:offs_w_p  + i*offs1 + nbr_w]

        t_tp = N.linspace(1,10,10)

        h=N.zeros(n_h)
        self.nlp.opt_coll_h(h)
        #print N.max(N.abs(h))

#         plt.figure(3)
#         plt.clf()
#         plt.plot(m_x1_1.t,m_x1_1.x)
#         plt.plot(m_x1_2.t,m_x1_2.x)
#         plt.plot(t_x_el_junc,x_el_junc[:,1],'x')
#         plt.plot(t_tp,x_p[:,1],'o')
#         plt.title("x[1]")
#         plt.grid()
#         plt.show()
        
#         plt.figure(4)
#         plt.clf()
#         plt.plot(m_x2_1.t,m_x2_1.x)
#         plt.plot(m_x2_2.t,m_x2_2.x)
#         plt.plot(t_x_el_junc,x_el_junc[:,2],'x')
#         plt.plot(t_tp,x_p[:,2],'o')
#         plt.title("x[2]")
#         plt.grid()
#         plt.show()

#         plt.figure(5)
#         plt.clf()
#         plt.plot(m_y_1.t,m_y_1.x)
#         plt.plot(m_y_2.t,m_y_2.x)
#         plt.plot(t_tp,w_p[:,0],'o')
#         plt.title("y")
#         plt.grid()
#         plt.show()
        
#         plt.figure(6)
#         plt.clf()
#         plt.plot(m_u_1.t,m_u_1.x)
#         plt.plot(m_u_2.t,m_u_2.x)
#         plt.plot(t_tp,u_p[:,0],'o')
#         plt.title("u")
#         plt.grid()
#         plt.show()


        m_x1_2_res = N.array([ 1.        ,  0.96503702,  0.80699964,  0.81708186,  0.82968423,
                               0.73425843,  0.4641878 ,  0.30274918, -0.22539661, -0.45405707,
                               -0.47988416, -0.25883339,  0.07728009,  0.22367095,  0.49688434,
                               0.42028466])
        
        m_x2_2_res = N.array([ 1.        ,  0.77648496,  0.75474237,  0.86572509,  0.85523243,
                               0.47651669, -0.02410645, -0.24417425, -0.68431665, -0.61607295,
                               -0.48363351,  0.15624317,  0.56793272,  0.66948745,  0.56283272,
                               0.14759305])
        
        u_2_res = N.array([ 0.        ,  0.30515581,  0.30515581,  0.30515581,  0.73893649,
                              0.73893649,  0.73893649, -0.920168  , -0.920168  , -0.920168  ,
                              0.0269131 ,  0.0269131 ,  0.0269131 ,  0.89776804,  0.89776804,
                              0.89776804])
        
        m_y_2_res = N.array([ 2.        ,  1.74152198,  1.56174201,  1.68280695,  1.68491666,
                              1.21077512,  0.44008136,  0.05857493, -0.90971326, -1.07013001,
                              -0.96351767, -0.10259022,  0.64521281,  0.8931584 ,  1.05971706,
                              0.56787771])
        
        x_el_junc_res = N.array([[  3.91403795,   0.81708186,   0.86572509],
                                 [  6.38519639,   0.4641878 ,  -0.02410645],
                                 [  8.53595865,  -0.45405707,  -0.61607295],
                                 [  9.99351048,   0.07728009,   0.56793272],
                                 [ 11.69233416,   0.42028466,   0.14759305]])
        
        dx_p_res = N.array([[ 1.89614716, -0.13108396,  0.13906756],
                            [ 2.24392408,  0.04864298,  0.04357222],
                            [ 1.05980345, -0.15348176, -0.49911689],
                            [ 0.78887658, -0.48829925, -0.73269738],
                            [ 1.29975129, -0.52999439, -0.34773495],
                            [ 0.66373748, -0.16201457,  0.33665916],
                [ 0.56780963,  0.31891731,  0.70407499],
                            [ 1.30735387,  0.49065263,  0.42142531],
                            [ 0.81705525,  0.20439241, -0.24969127],
                            [ 0.49438075, -0.27269124, -0.69161393]])
        
        x_p_res = N.array([[  1.71039492,   0.83348678,   0.70240363],
                           [  3.91403795,   0.81708186,   0.86572509],
                           [  5.61520049,   0.79371837,   0.64023676],
                           [  6.38519639,   0.4641878 ,  -0.02410645],
                           [  7.48469697,  -0.08119087,  -0.61118532],
                           [  8.53595865,  -0.45405707,  -0.61607295],
                           [  9.01802285,  -0.36600637,  -0.04708865],
                           [  9.99351048,   0.07728009,   0.56793272],
                           [ 11.15957068,   0.45741668,   0.66180933],
                           [ 11.69233416,   0.42028466,   0.14759305]])
        
        u_p_res = N.array([[ 0.84147098],
                           [ 0.90929742],
                           [ 0.14112001],
                           [-0.75680257],
                           [-0.95892497],
                           [-0.27941585],
                           [ 0.6569871 ],
                           [ 0.98935824],
                           [ 0.41211848],
                           [-0.54402111]])
        
        w_p_res = N.array([[ 1.53589041,  0.84147098],
                           [ 1.68280695,  0.90929742],
                           [ 1.43395513,  0.14112001],
                           [ 0.44008136, -0.75680257],
                           [-0.69237618, -0.95892497],
                           [-1.07013001, -0.27941585],
                           [-0.41309502,  0.6569871 ],
                           [ 0.64521281,  0.98935824],
                           [ 1.11922602,  0.41211848],
                           [ 0.56787771, -0.54402111]])
        
        assert N.sum(N.abs(m_x1_2-m_x1_2_res))<1e-3
        assert N.sum(N.abs(m_x2_2-m_x2_2_res))<1e-3
        assert N.sum(N.abs(u_2-u_2_res))<1e-3
        assert N.sum(N.abs(m_y_2-m_y_2_res))<1e-3
        
        assert N.sum(N.abs(x_el_junc-x_el_junc_res))<1e-3
        
        assert N.sum(N.abs(dx_p-dx_p_res))<1e-3
        assert N.sum(N.abs(x_p-x_p_res))<1e-3
        assert N.sum(N.abs(u_p-u_p_res))<1e-3
        assert N.sum(N.abs(w_p-w_p_res))<1e-3
        
        optimizer = CollocationOptimizer(self.nlp)
        optimizer.opt_coll_ipopt_solve()
Example #8
0
 def setUp(self):
     self.ipopt_nlp.init_opt_ipopt_solve();
     self.nlp.export_result_dymola()
     self.res = ResultDymolaTextual(
         "StaticOptimizationTest_StaticOptimizationTest2_result.txt")
 def setUp(self):
     self.ipopt_nlp.init_opt_ipopt_solve()
     self.nlp.export_result_dymola()
     self.res = ResultDymolaTextual(
         "StaticOptimizationTest_StaticOptimizationTest2_result.txt")
Example #10
0
def run_demo(with_plots=True):
    """ 
    Model predicitve control of the Hicks-Ray CSTR reactor. This example 
    demonstrates how to use the blocking factor feature of the collocation 
    algorithm.

    This example also shows how to use classes for initialization, simulation 
    and optimization directly rather than calling then through the high-level 
    classes 'initialialize', 'simulate' and 'optimize'.
    """

    curr_dir = os.path.dirname(os.path.abspath(__file__))

    # Compile the stationary initialization model into a JMU
    jmu_name = compile_jmu("CSTR.CSTR_Init",
                           os.path.join(curr_dir, "files", "CSTR.mop"))

    # Load a JMUModel instance
    init_model = JMUModel(jmu_name)

    # Create DAE initialization object.
    init_nlp = NLPInitialization(init_model)

    # Create an Ipopt solver object for the DAE initialization system
    init_nlp_ipopt = InitializationOptimizer(init_nlp)

    def compute_stationary(Tc_stat):
        init_model.set('Tc', Tc_stat)
        # Solve the DAE initialization system with Ipopt
        init_nlp_ipopt.init_opt_ipopt_solve()
        return (init_model.get('c'), init_model.get('T'))

    # Set inputs for Stationary point A
    Tc_0_A = 250
    c_0_A, T_0_A = compute_stationary(Tc_0_A)

    # Print some data for stationary point A
    print(' *** Stationary point A ***')
    print('Tc = %f' % Tc_0_A)
    print('c = %f' % c_0_A)
    print('T = %f' % T_0_A)

    # Set inputs for Stationary point B
    Tc_0_B = 280
    c_0_B, T_0_B = compute_stationary(Tc_0_B)

    # Print some data for stationary point B
    print(' *** Stationary point B ***')
    print('Tc = %f' % Tc_0_B)
    print('c = %f' % c_0_B)
    print('T = %f' % T_0_B)

    jmu_name = compile_jmu("CSTR.CSTR_Opt_MPC",
                           os.path.join(curr_dir, "files", "CSTR.mop"))

    cstr = JMUModel(jmu_name)

    cstr.set('Tc_ref', Tc_0_B)
    cstr.set('c_ref', c_0_B)
    cstr.set('T_ref', T_0_B)

    cstr.set('cstr.c_init', c_0_A)
    cstr.set('cstr.T_init', T_0_A)

    # Initialize the mesh
    n_e = 50  # Number of elements
    hs = N.ones(n_e) * 1. / n_e  # Equidistant points
    n_cp = 3
    # Number of collocation points in each element

    # Create an NLP object
    # The length of the optimization interval is 50s and the
    # number of elements is 50, which gives a blocking factor
    # vector of 2*ones(n_e/2) to match the sampling interval
    # of 2s.
    nlp = ipopt.NLPCollocationLagrangePolynomials(cstr,
                                                  n_e,
                                                  hs,
                                                  n_cp,
                                                  blocking_factors=2 *
                                                  N.ones(n_e / 2, dtype=N.int))

    # Create an Ipopt NLP object
    nlp_ipopt = ipopt.CollocationOptimizer(nlp)

    nlp_ipopt.opt_coll_ipopt_set_int_option("max_iter", 500)

    h = 2.  # Sampling interval
    T_final = 180.  # Final time of simulation
    t_mpc = N.linspace(0, T_final, T_final / h + 1)
    n_samples = N.size(t_mpc)

    ref_mpc = N.zeros(n_samples)
    ref_mpc[0:3] = N.ones(3) * Tc_0_A
    ref_mpc[3:] = N.ones(n_samples - 3) * Tc_0_B

    cstr.set('cstr.c_init', c_0_A)
    cstr.set('cstr.T_init', T_0_A)

    # Compile the simulation model into a DLL
    jmu_name = compile_jmu("CSTR.CSTR",
                           os.path.join(curr_dir, "files", "CSTR.mop"))

    # Load a model instance into Python
    sim_model = JMUModel(jmu_name)

    sim_model.set('c_init', c_0_A)
    sim_model.set('T_init', T_0_A)

    global cstr_mod
    global cstr_sim

    cstr_mod = JMIDAE(sim_model)  # Create an Assimulo problem
    cstr_sim = IDA(cstr_mod)  # Create an IDA solver

    i = 0

    if with_plots:
        plt.figure(4)
        plt.clf()

    for t in t_mpc[0:-1]:
        Tc_ref = ref_mpc[i]
        c_ref, T_ref = compute_stationary(Tc_ref)

        cstr.set('Tc_ref', Tc_ref)
        cstr.set('c_ref', c_ref)
        cstr.set('T_ref', T_ref)

        # Solve the optimization problem
        nlp_ipopt.opt_coll_ipopt_solve()

        # Write to file.
        nlp.export_result_dymola()

        # Load the file we just wrote to file
        res = ResultDymolaTextual('CSTR_CSTR_Opt_MPC_result.txt')

        # Extract variable profiles
        c_res = res.get_variable_data('cstr.c')
        T_res = res.get_variable_data('cstr.T')
        Tc_res = res.get_variable_data('cstr.Tc')

        # Get the first Tc sample
        Tc_ctrl = Tc_res.x[0]

        # Set the value to the model
        sim_model.set('Tc', Tc_ctrl)

        # Simulate
        cstr_sim.simulate(t_mpc[i + 1])

        t_T_sim = cstr_sim.t_sol

        # Set terminal values of the states
        cstr.set('cstr.c_init', cstr_sim.y[0])
        cstr.set('cstr.T_init', cstr_sim.y[1])
        sim_model.set('c_init', cstr_sim.y[0])
        sim_model.set('T_init', cstr_sim.y[1])

        if with_plots:
            plt.figure(4)
            plt.subplot(3, 1, 1)
            plt.plot(t_T_sim, N.array(cstr_sim.y_sol)[:, 0], 'b')

            plt.subplot(3, 1, 2)
            plt.plot(t_T_sim, N.array(cstr_sim.y_sol)[:, 1], 'b')

            if t_mpc[i] == 0:
                plt.subplot(3, 1, 3)
                plt.plot([t_mpc[i], t_mpc[i + 1]], [Tc_ctrl, Tc_ctrl], 'b')
            else:
                plt.subplot(3, 1, 3)
                plt.plot([t_mpc[i], t_mpc[i], t_mpc[i + 1]],
                         [Tc_ctrl_old, Tc_ctrl, Tc_ctrl], 'b')

        Tc_ctrl_old = Tc_ctrl

        i = i + 1

    assert N.abs(Tc_ctrl - 279.097186038194) < 1e-6
    assert N.abs(N.array(cstr_sim.y_sol)[:, 0][-1] - 350.89028563) < 1e-6
    assert N.abs(N.array(cstr_sim.y_sol)[:, 1][-1] - 283.15229948) < 1e-6

    if with_plots:
        plt.figure(4)
        plt.subplot(3, 1, 1)
        plt.ylabel('c')
        plt.plot([0, T_final], [c_0_B, c_0_B], '--')
        plt.grid()
        plt.subplot(3, 1, 2)
        plt.ylabel('T')
        plt.plot([0, T_final], [T_0_B, T_0_B], '--')
        plt.grid()
        plt.subplot(3, 1, 3)
        plt.ylabel('Tc')
        plt.plot([0, T_final], [Tc_0_B, Tc_0_B], '--')
        plt.grid()
        plt.xlabel('t')
        plt.show()
Example #11
0
def run_demo(with_plots=True):
    """ 
    Model predicitve control of the Hicks-Ray CSTR reactor. This example 
    demonstrates how to use the blocking factor feature of the collocation 
    algorithm.

    This example also shows how to use classes for initialization, simulation 
    and optimization directly rather than calling then through the high-level 
    classes 'initialialize', 'simulate' and 'optimize'.
    """

    curr_dir = os.path.dirname(os.path.abspath(__file__));
    
    # Compile the stationary initialization model into a JMU
    jmu_name = compile_jmu("CSTR.CSTR_Init", os.path.join(curr_dir, "files", "CSTR.mop"))

    # Load a JMUModel instance
    init_model = JMUModel(jmu_name)

    # Create DAE initialization object.
    init_nlp = NLPInitialization(init_model)

    # Create an Ipopt solver object for the DAE initialization system
    init_nlp_ipopt = InitializationOptimizer(init_nlp)

    def compute_stationary(Tc_stat):
        init_model.set('Tc',Tc_stat)
        # Solve the DAE initialization system with Ipopt
        init_nlp_ipopt.init_opt_ipopt_solve()
        return (init_model.get('c'),init_model.get('T'))

    # Set inputs for Stationary point A
    Tc_0_A = 250
    c_0_A, T_0_A = compute_stationary(Tc_0_A)

    # Print some data for stationary point A
    print(' *** Stationary point A ***')
    print('Tc = %f' % Tc_0_A)
    print('c = %f' % c_0_A)
    print('T = %f' % T_0_A)
    
    # Set inputs for Stationary point B
    Tc_0_B = 280
    c_0_B, T_0_B = compute_stationary(Tc_0_B)
    
    # Print some data for stationary point B
    print(' *** Stationary point B ***')
    print('Tc = %f' % Tc_0_B)
    print('c = %f' % c_0_B)
    print('T = %f' % T_0_B)
    
    jmu_name = compile_jmu("CSTR.CSTR_Opt_MPC", os.path.join(curr_dir, "files", "CSTR.mop"))

    cstr = JMUModel(jmu_name)

    cstr.set('Tc_ref',Tc_0_B)
    cstr.set('c_ref',c_0_B)
    cstr.set('T_ref',T_0_B)
    
    cstr.set('cstr.c_init',c_0_A)
    cstr.set('cstr.T_init',T_0_A)
    
    # Initialize the mesh
    n_e = 50                 # Number of elements 
    hs = N.ones(n_e)*1./n_e  # Equidistant points
    n_cp = 3;                # Number of collocation points in each element

    # Create an NLP object
    # The length of the optimization interval is 50s and the
    # number of elements is 50, which gives a blocking factor
    # vector of 2*ones(n_e/2) to match the sampling interval
    # of 2s.
    nlp = ipopt.NLPCollocationLagrangePolynomials(
        cstr, n_e, hs, n_cp, blocking_factors=2*N.ones(n_e/2,dtype=N.int))

    # Create an Ipopt NLP object
    nlp_ipopt = ipopt.CollocationOptimizer(nlp)
   
    nlp_ipopt.opt_coll_ipopt_set_int_option("max_iter",500)

    h = 2.           # Sampling interval
    T_final = 180.   # Final time of simulation
    t_mpc = N.linspace(0,T_final,T_final/h+1)
    n_samples = N.size(t_mpc)

    ref_mpc = N.zeros(n_samples)
    ref_mpc[0:3] = N.ones(3)*Tc_0_A
    ref_mpc[3:] = N.ones(n_samples-3)*Tc_0_B
    
    cstr.set('cstr.c_init',c_0_A)
    cstr.set('cstr.T_init',T_0_A)
    
    # Compile the simulation model into a DLL
    jmu_name = compile_jmu("CSTR.CSTR", os.path.join(curr_dir, "files", "CSTR.mop"))
    
    # Load a model instance into Python
    sim_model = JMUModel(jmu_name)
    
    sim_model.set('c_init',c_0_A)
    sim_model.set('T_init',T_0_A)
    
    global cstr_mod
    global cstr_sim
    
    cstr_mod = JMIDAE(sim_model) # Create an Assimulo problem
    cstr_sim = IDA(cstr_mod)     # Create an IDA solver
    
    i = 0
    
    if with_plots:
        plt.figure(4)
        plt.clf()
    
    for t in t_mpc[0:-1]:
        Tc_ref = ref_mpc[i]
        c_ref, T_ref = compute_stationary(Tc_ref)

        cstr.set('Tc_ref',Tc_ref)
        cstr.set('c_ref',c_ref)
        cstr.set('T_ref',T_ref)
        
        # Solve the optimization problem
        nlp_ipopt.opt_coll_ipopt_solve()
        
        # Write to file. 
        nlp.export_result_dymola()
        
        # Load the file we just wrote to file
        res = ResultDymolaTextual('CSTR_CSTR_Opt_MPC_result.txt')
        
        # Extract variable profiles
        c_res = res.get_variable_data('cstr.c')
        T_res = res.get_variable_data('cstr.T')
        Tc_res = res.get_variable_data('cstr.Tc')
        
        # Get the first Tc sample
        Tc_ctrl = Tc_res.x[0]
        
        # Set the value to the model
        sim_model.set('Tc',Tc_ctrl)
        
        # Simulate
        cstr_sim.simulate(t_mpc[i+1])
        
        t_T_sim = cstr_sim.t_sol
        
        # Set terminal values of the states
        cstr.set('cstr.c_init',cstr_sim.y[0])
        cstr.set('cstr.T_init',cstr_sim.y[1])
        sim_model.set('c_init',cstr_sim.y[0])
        sim_model.set('T_init',cstr_sim.y[1])
        
        if with_plots:
            plt.figure(4)
            plt.subplot(3,1,1)
            plt.plot(t_T_sim,N.array(cstr_sim.y_sol)[:,0],'b')
            
            plt.subplot(3,1,2)
            plt.plot(t_T_sim,N.array(cstr_sim.y_sol)[:,1],'b')
        
            if t_mpc[i]==0:
                plt.subplot(3,1,3)
                plt.plot([t_mpc[i],t_mpc[i+1]],[Tc_ctrl,Tc_ctrl],'b')
            else:
                plt.subplot(3,1,3)
                plt.plot(
                    [t_mpc[i],t_mpc[i],t_mpc[i+1]],
                    [Tc_ctrl_old,Tc_ctrl,Tc_ctrl],
                    'b')
            
        Tc_ctrl_old = Tc_ctrl
            
        i = i+1

    assert N.abs(Tc_ctrl - 279.097186038194)                      < 1e-6
    assert N.abs(N.array(cstr_sim.y_sol)[:,0][-1] - 350.89028563) < 1e-6
    assert N.abs(N.array(cstr_sim.y_sol)[:,1][-1] - 283.15229948) < 1e-6

    if with_plots:
        plt.figure(4)
        plt.subplot(3,1,1)
        plt.ylabel('c')
        plt.plot([0,T_final],[c_0_B,c_0_B],'--')
        plt.grid()
        plt.subplot(3,1,2)
        plt.ylabel('T')
        plt.plot([0,T_final],[T_0_B,T_0_B],'--')
        plt.grid()
        plt.subplot(3,1,3)
        plt.ylabel('Tc')
        plt.plot([0,T_final],[Tc_0_B,Tc_0_B],'--')
        plt.grid()
        plt.xlabel('t')
        plt.show()
Example #12
0
class TestOptInitBlockingFactors:
    @classmethod
    def setUpClass(cls):
        cls.curr_dir = os.path.dirname(os.path.abspath(__file__));
        mofile = os.path.join(get_files_path(), 'Modelica', 
                'BlockingError.mop')

        m = compile_jmu("BlockingInitPack.M_init", mofile)
        cls.model = JMUModel(m)
        
        m = compile_jmu("BlockingInitPack.M_Opt",mofile)
        cls.opt_model = JMUModel(m)
        
    @testattr(ipopt = True)
    def setUp(self):
        resfile = os.path.join(get_files_path(), 'Results', 
            'BlockingInitPack_M_init_result.txt')
        self.res_init = ResultDymolaTextual(resfile)

        self.n_e = 5 # Number of elements 
        self.hs = N.ones(self.n_e)*1./self.n_e # Equidistant points
        self.n_cp = 3; # Number of collocation points in each element

        # Blocking factors for control parametrization
        blocking_factors=N.ones(self.n_e,dtype=N.int)

        self.nlp = NLPCollocationLagrangePolynomials(self.opt_model,
            self.n_e,self.hs,self.n_cp,blocking_factors)

        self.nlp.set_initial_from_dymola(self.res_init, self.hs, 0., 10.)

        self.nlp.export_result_dymola("qwe.txt")

        self.res_init2 = ResultDymolaTextual('qwe.txt')


    @testattr(ipopt = True)
    def test_initialization(self):


        m_x1_1 = self.res_init.get_variable_data("m.x[1]").x
        m_x1_2 = self.res_init2.get_variable_data("m.x[1]").x
        
        m_x2_1 = self.res_init.get_variable_data("m.x[2]").x
        m_x2_2 = self.res_init2.get_variable_data("m.x[2]").x
        
        m_y_1 = self.res_init.get_variable_data("m.y").x
        m_y_2 = self.res_init2.get_variable_data("m.y").x
        
        m_u_1 = self.res_init.get_variable_data("m.u").x
        m_u_2 = self.res_init2.get_variable_data("m.u").x
        
        (n_x, n_g, n_h, dg_n_nz, dh_n_nz) = self.nlp.opt_coll_get_dimensions()
        
        x_init = N.zeros(n_x)
        self.nlp.opt_coll_get_initial(x_init)

        offs_x_el_junc = 8 + 7*self.n_e*self.n_cp + self.n_e

        x_el_junc = N.zeros((self.n_e,3))
        
        for i in range(self.n_e):
            x_el_junc[i,:] = x_init[offs_x_el_junc + i*3:offs_x_el_junc + (i+1)*3]

        t_f = 10.

        t_x_el_junc = N.linspace(0,t_f,self.n_e+1)
        t_x_el_junc = t_x_el_junc[1:]

        offs_dx_p = 8 + 7*self.n_e*self.n_cp + self.n_e + 3*self.n_e
        offs_x_p = offs_dx_p + 3
        offs_u_p = offs_x_p + 3
        offs_w_p = offs_u_p + 1

        n_tp = 10
        
        dx_p = N.zeros((n_tp,3))
        x_p = N.zeros((n_tp,3))
        u_p = N.zeros((n_tp,1))
        w_p = N.zeros((n_tp,1))
        
        for i in range(n_tp):
            dx_p[i,:] = x_init[offs_dx_p + i*8:offs_dx_p + i*8 + 3]
            x_p[i,:] = x_init[offs_x_p + i*8:offs_x_p + i*8 + 3]
            u_p[i,:] = x_init[offs_u_p + i*8:offs_u_p + i*8 + 1]
            w_p[i,:] = x_init[offs_w_p + i*8:offs_w_p + i*8 + 1]

        t_tp = N.linspace(1,10,10)

        h=N.zeros(n_h)
        self.nlp.opt_coll_h(h)
        print N.max(N.abs(h))

#         plt.figure(3)
#         plt.clf()
#         plt.plot(m_x1_1.t,m_x1_1.x)
#         plt.plot(m_x1_2.t,m_x1_2.x)
#         plt.plot(t_x_el_junc,x_el_junc[:,1],'x')
#         plt.plot(t_tp,x_p[:,1],'o')
#         plt.title("x[1]")
#         plt.grid()
#         plt.show()
        
#         plt.figure(4)
#         plt.clf()
#         plt.plot(m_x2_1.t,m_x2_1.x)
#         plt.plot(m_x2_2.t,m_x2_2.x)
#         plt.plot(t_x_el_junc,x_el_junc[:,2],'x')
#         plt.plot(t_tp,x_p[:,2],'o')
#         plt.title("x[2]")
#         plt.grid()
#         plt.show()

#         plt.figure(5)
#         plt.clf()
#         plt.plot(m_y_1.t,m_y_1.x)
#         plt.plot(m_y_2.t,m_y_2.x)
#         plt.plot(t_tp,w_p[:,0],'o')
#         plt.title("y")
#         plt.grid()
#         plt.show()
        
#         plt.figure(6)
#         plt.clf()
#         plt.plot(m_u_1.t,m_u_1.x)
#         plt.plot(m_u_2.t,m_u_2.x)
#         plt.plot(t_tp,u_p[:,0],'o')
#         plt.title("u")
#         plt.grid()
#         plt.show()


        m_x1_2_res = N.array([ 1.        ,  0.96503702,  0.80699964,  0.81708186,  0.82968423,
                               0.73425843,  0.4641878 ,  0.30274918, -0.22539661, -0.45405707,
                               -0.47988416, -0.25883339,  0.07728009,  0.22367095,  0.49688434,
                               0.42028466])
        
        m_x2_2_res = N.array([ 1.        ,  0.77648496,  0.75474237,  0.86572509,  0.85523243,
                               0.47651669, -0.02410645, -0.24417425, -0.68431665, -0.61607295,
                               -0.48363351,  0.15624317,  0.56793272,  0.66948745,  0.56283272,
                               0.14759305])
        
        m_u_2_res = N.array([ 0.        ,  0.30515581,  0.30515581,  0.30515581,  0.73893649,
                              0.73893649,  0.73893649, -0.920168  , -0.920168  , -0.920168  ,
                              0.0269131 ,  0.0269131 ,  0.0269131 ,  0.89776804,  0.89776804,
                              0.89776804])
        
        m_y_2_res = N.array([ 2.        ,  1.74152198,  1.56174201,  1.68280695,  1.68491666,
                              1.21077512,  0.44008136,  0.05857493, -0.90971326, -1.07013001,
                              -0.96351767, -0.10259022,  0.64521281,  0.8931584 ,  1.05971706,
                              0.56787771])
        
        x_el_junc_res = N.array([[  3.91403795,   0.81708186,   0.86572509],
                                 [  6.38519639,   0.4641878 ,  -0.02410645],
                                 [  8.53595865,  -0.45405707,  -0.61607295],
                                 [  9.99351048,   0.07728009,   0.56793272],
                                 [ 11.69233416,   0.42028466,   0.14759305]])
        
        dx_p_res = N.array([[ 1.89614716, -0.13108396,  0.13906756],
                            [ 2.24392408,  0.04864298,  0.04357222],
                            [ 1.05980345, -0.15348176, -0.49911689],
                            [ 0.78887658, -0.48829925, -0.73269738],
                            [ 1.29975129, -0.52999439, -0.34773495],
                            [ 0.66373748, -0.16201457,  0.33665916],
                [ 0.56780963,  0.31891731,  0.70407499],
                            [ 1.30735387,  0.49065263,  0.42142531],
                            [ 0.81705525,  0.20439241, -0.24969127],
                            [ 0.49438075, -0.27269124, -0.69161393]])
        
        x_p_res = N.array([[  1.71039492,   0.83348678,   0.70240363],
                           [  3.91403795,   0.81708186,   0.86572509],
                           [  5.61520049,   0.79371837,   0.64023676],
                           [  6.38519639,   0.4641878 ,  -0.02410645],
                           [  7.48469697,  -0.08119087,  -0.61118532],
                           [  8.53595865,  -0.45405707,  -0.61607295],
                           [  9.01802285,  -0.36600637,  -0.04708865],
                           [  9.99351048,   0.07728009,   0.56793272],
                           [ 11.15957068,   0.45741668,   0.66180933],
                           [ 11.69233416,   0.42028466,   0.14759305]])
        
        u_p_res = N.array([[ 0.84147098],
                           [ 0.90929742],
                           [ 0.14112001],
                           [-0.75680257],
                           [-0.95892497],
                           [-0.27941585],
                           [ 0.6569871 ],
                           [ 0.98935824],
                           [ 0.41211848],
                           [-0.54402111]])
        
        w_p_res = N.array([[ 1.53589041],
                           [ 1.68280695],
                           [ 1.43395513],
                           [ 0.44008136],
                           [-0.69237618],
                           [-1.07013001],
                           [-0.41309502],
                           [ 0.64521281],
                           [ 1.11922602],
                           [ 0.56787771]])
        
        assert N.sum(N.abs(m_x1_2-m_x1_2_res))<1e-3
        assert N.sum(N.abs(m_x2_2-m_x2_2_res))<1e-3
        assert N.sum(N.abs(m_u_2-m_u_2_res))<1e-3
        assert N.sum(N.abs(m_y_2-m_y_2_res))<1e-3
        
        assert N.sum(N.abs(x_el_junc-x_el_junc_res))<1e-3
        
        assert N.sum(N.abs(dx_p-dx_p_res))<1e-3
        assert N.sum(N.abs(x_p-x_p_res))<1e-3
        assert N.sum(N.abs(u_p-u_p_res))<1e-3
        assert N.sum(N.abs(w_p-w_p_res))<1e-3
        
        optimizer = CollocationOptimizer(self.nlp)
        optimizer.opt_coll_ipopt_solve()
Example #13
0
        opt_opts['IPOPT_options']['ma57_pivtol'] = 1e-4
        opt_opts['IPOPT_options']['ma27_pivtol'] = 1e-4
        opt_opts['IPOPT_options']['ma97_u'] = 1e-4
        opt_opts['IPOPT_options']['ma97_umax'] = 1e-2
        opt_opts['IPOPT_options']['ma57_automatic_scaling'] = "yes"
        #~ opt_opts['IPOPT_options']['mu_strategy'] = "adaptive"
        if problem == "vehicle":
            std_dev[problem] = 0.1
            caus_opts = sp.CausalizationOptions()
            caus_opts['uneliminable'] = [
                'car.Fxf', 'car.Fxr', 'car.Fyf', 'car.Fyr'
            ]
            class_name = "Turn"
            file_paths = os.path.join(get_files_path(), "vehicle_turn.mop")
            init_res = LocalDAECollocationAlgResult(
                result_data=ResultDymolaTextual('vehicle_sol.txt'))
            opt_opts['init_traj'] = init_res
            opt_opts['nominal_traj'] = init_res
            opt_opts['IPOPT_options']['max_cpu_time'] = 30
            opt_opts['n_e'] = 60

            # Set blocking factors
            factors = {
                'delta_u': opt_opts['n_e'] / 2 * [2],
                'Twf_u': opt_opts['n_e'] / 4 * [4],
                'Twr_u': opt_opts['n_e'] / 4 * [4]
            }
            rad2deg = 180. / (2 * np.pi)
            du_bounds = {'delta_u': 2. / rad2deg}
            bf = BlockingFactors(factors, du_bounds=du_bounds)
            opt_opts['blocking_factors'] = bf
Example #14
0
                (8, 7),
                (8, 8),
            ]
        else:
            class_name = "Circuit"
            file_paths = "circuit.mo"
            opts = {
                "eliminate_alias_variables": True,
                "generate_html_diagnostics": True,
                "variability_propagation": False,
            }
            model = transfer_model(class_name, file_paths, compiler_options=opts)
            ncp = 500 * model.get("omega")
            init_fmu = load_fmu(compile_fmu(class_name, file_paths, compiler_options=opts))
    elif problem == "vehicle":
        sim_res = ResultDymolaTextual(os.path.join(get_files_path(), "vehicle_turn_dymola.txt"))
        start_time = 0.0
        final_time = sim_res.get_variable_data("time").t[-1]
        ncp = 500
        if source != "Modelica":
            raise ValueError
        class_name = "Car"
        file_paths = os.path.join(get_files_path(), "vehicle_turn.mop")
        opts = {"generate_html_diagnostics": True}
        model = transfer_model(class_name, file_paths, compiler_options=opts)
        init_fmu = load_fmu(compile_fmu(class_name, file_paths, compiler_options=opts))

        # Create input data
        # This would have worked if one input was not constant...
        # ~ columns = [0]
        # ~ columns += [sim_res.get_column(input_var.getName()) for input_var in model.getVariables(model.REAL_INPUT)]
Example #15
0
class _BaseSimOptTest:
    """
    Base class for simulation and optimization tests.
    Actual test classes should inherit SimulationTest or OptimizationTest.
    All assertion methods consider a value correct if it falls within either tolerance 
    limit, absolute or relative.
    """
    @classmethod
    def setup_class_base(cls,
                         mo_file,
                         class_name,
                         options={},
                         format='jmu',
                         target="fmume"):
        """
        Set up a new test model. Compiles the model. 
        Call this with proper args from setUpClass(). 
          mo_file     - the relative path from the files dir to the .mo file to compile
          class_name  - the qualified name of the class to simulate
          options     - a dict of options to set in the compiler, defaults to no options
          format      - either 'jmu' or 'fmu' depending on which format should be tested
        """
        global _model_name
        path = os.path.join(get_files_path(), 'Modelica', mo_file)

        if format == 'jmu':
            _model_name = compile_jmu(class_name,
                                      path,
                                      compiler_options=options)
        elif format == 'fmu':
            _model_name = compile_fmu(class_name,
                                      path,
                                      compiler_options=options,
                                      target=target)
        else:
            raise Exception("Format must be either 'jmu' or 'fmu'.")

    def setup_base(self, rel_tol, abs_tol):
        """ 
        Set up a new test case. Configures test and creates model.
        Call this with proper args from setUp(). 
          rel_tol -  the relative error tolerance when comparing values
          abs_tol -  the absolute error tolerance when comparing values
        Any other named args are passed to the NLP constructor.
        """
        global _model_name
        self.rel_tol = rel_tol
        self.abs_tol = abs_tol
        self.model_name = _model_name
        parts = _model_name.split('.')
        self.format = parts[len(parts) - 1]
        if self.format == 'jmu':
            self.model = JMUModel(self.model_name)
        else:
            self.model = load_fmu(self.model_name)

    def run(self, cvode_options=None):
        """
        Run simulation and load result. 
        Call this from setUp() or within a test depending if all tests should run simulation.
        """
        self._run_and_write_data(cvode_options)
        self.data = ResultDymolaTextual(self.model_name[:-len('.jmu')] +
                                        '_result.txt')

    def load_expected_data(self, name):
        """
        Load the expected data to use for assert_all_paths() and assert_all_end_values().
          name -  the file name of the results file, relative to files dir
        """
        path = os.path.join(get_files_path(), 'Results', name)
        self.expected = ResultDymolaTextual(path)

    def assert_all_inital_values(self, variables, rel_tol=None, abs_tol=None):
        """
        Assert that all given variables match expected intial values loaded by a call to 
        load_expected_data().
          variables -  list of the names of the variables to test
          rel_tol   -  the relative error tolerance, defaults to the value set with setup_base()
          abs_tol   -  the absolute error tolerance, defaults to the value set with setup_base()
        """
        self._assert_all_spec_values(variables, 0, rel_tol, abs_tol)

    def assert_all_end_values(self, variables, rel_tol=None, abs_tol=None):
        """
        Assert that all given variables match expected end values loaded by a call to 
        load_expected_data().
          variables -  list of the names of the variables to test
          rel_tol   -  the relative error tolerance, defaults to the value set with setup_base()
          abs_tol   -  the absolute error tolerance, defaults to the value set with setup_base()
        """
        self._assert_all_spec_values(variables, -1, rel_tol, abs_tol)

    def assert_all_trajectories(self,
                                variables,
                                same_span=True,
                                rel_tol=None,
                                abs_tol=None):
        """
        Assert that the trajectories of all given variables match expected trajectories 
        loaded by a call to load_expected_data().
          variables -  list of the names of the variables to test
          same_span -  if True, require that the paths span the same time interval
                       if False, only compare overlapping part, default True
          rel_tol   -  the relative error tolerance, defaults to the value set with setup_base()
          abs_tol   -  the absolute error tolerance, defaults to the value set with setup_base()
        """
        for var in variables:
            expected = self.expected.get_variable_data(var)
            expected_t = self.expected.get_variable_data('time')
            self.assert_trajectory(var, expected, expected_t, same_span,
                                   rel_tol, abs_tol)

    def assert_initial_value(self,
                             variable,
                             value,
                             rel_tol=None,
                             abs_tol=None):
        """
        Assert that the inital value for a simulation variable matches expected value. 
          variable  -  the name of the variable
          value     -  the expected value
          rel_tol   -  the relative error tolerance, defaults to the value set with setup_base()
          abs_tol   -  the absolute error tolerance, defaults to the value set with setup_base()
        """
        self._assert_value(variable, value, 0, rel_tol, abs_tol)

    def assert_end_value(self, variable, value, rel_tol=None, abs_tol=None):
        """
        Assert that the end result for a simulation variable matches expected value. 
          variable  -  the name of the variable
          value     -  the expected value
          rel_tol   -  the relative error tolerance, defaults to the value set with setup_base()
          abs_tol   -  the absolute error tolerance, defaults to the value set with setup_base()
        """
        self._assert_value(variable, value, -1, rel_tol, abs_tol)

    def assert_trajectory(self,
                          variable,
                          expected,
                          expected_t,
                          same_span=True,
                          rel_tol=None,
                          abs_tol=None):
        """
        Assert that the trajectory of a simulation variable matches expected trajectory. 
          variable  -  the name of the variable
          expected  -  the expected trajectory
          same_span -  if True, require that the paths span the same time interval
                       if False, only compare overlapping part, default True
          rel_tol   -  the relative error tolerance, defaults to the value set with setup_base()
          abs_tol   -  the absolute error tolerance, defaults to the value set with setup_base()
        """
        if rel_tol is None:
            rel_tol = self.rel_tol
        if abs_tol is None:
            abs_tol = self.abs_tol
        ans = expected
        ans_t = expected_t
        res = self.data.get_variable_data(variable)
        res_t = self.data.get_variable_data('time')

        if same_span:
            msg = 'paths do not span the same time interval for ' + variable
            assert _check_error(ans.t[0], res.t[0], rel_tol, abs_tol), msg
            assert _check_error(ans.t[-1], res.t[-1], rel_tol, abs_tol), msg

        # Merge the time lists
        time = list(set(ans.t) | set(res.t))

        # Get overlapping span
        (t1, t2) = (max(ans.t[0], res.t[0]), min(ans.t[-1], res.t[-1]))

        # Remove values outside overlap
        #time = filter((lambda t: t >= t1 and t <= t2), time) #This is not a good approach
        time = filter((lambda t: t >= t1 and t <= t2), res.t)

        # Check error for each time point
        for i, t in enumerate(time):
            try:
                if time[i - 1] == t or t == time[
                        i +
                        1]:  #Necessary in case of jump discontinuities! For instance if there is a result at t_e^- and t_e^+
                    continue
            except IndexError:
                pass
            ans_x = _trajectory_eval(ans, ans_t, t)
            res_x = _trajectory_eval(res, res_t, t)
            (rel, abs) = _error(ans_x, res_x)
            msg = 'error of %s at time %f is too large (rel=%f, abs=%f)' % (
                variable, t, rel, abs)
            assert (rel <= 100 * rel_tol or abs <= 100 * abs_tol), msg

    def _assert_all_spec_values(self,
                                variables,
                                index,
                                rel_tol=None,
                                abs_tol=None):
        """
        Assert that all given variables match expected values loaded by a call to 
        load_expected_data(), for a given index in the value arrays.
          variables -  list of the names of the variables to test
          index     -  the index in the array holding the values, 0 is initial, -1 is end
          rel_tol   -  the relative error tolerance, defaults to the value set with setup_base()
          abs_tol   -  the absolute error tolerance, defaults to the value set with setup_base()
        """
        for var in variables:
            value = self.expected.get_variable_data(var)[index]
            self._assert_value(var, value, index, rel_tol, abs_tol)

    def _assert_value(self,
                      variable,
                      value,
                      index,
                      rel_tol=None,
                      abs_tol=None):
        """
        Assert that a specific value for a simulation variable matches expected value. 
          variable  -  the name of the variable
          value     -  the expected value
          index     -  the index in the array holding the values, 0 is initial, -1 is end
          rel_tol   -  the relative error tolerance, defaults to the value set with setup_base()
          abs_tol   -  the absolute error tolerance, defaults to the value set with setup_base()
        """
        res = self.data.get_variable_data(variable)
        msg = 'error of %s at index %i is too large' % (variable, index)
        self.assert_equals(msg,
                           res.x[index],
                           value,
                           rel_tol=None,
                           abs_tol=None)

    def assert_equals(self,
                      message,
                      actual,
                      expected,
                      rel_tol=None,
                      abs_tol=None):
        """
        Assert that a specific value matches expected value. 
          actual    -  the expected value
          expected  -  the expected value
          message   -  the error message to use if values does not match
          rel_tol   -  the relative error tolerance, defaults to the value set with setup_base()
          abs_tol   -  the absolute error tolerance, defaults to the value set with setup_base()
        """
        if rel_tol is None:
            rel_tol = self.rel_tol
        if abs_tol is None:
            abs_tol = self.abs_tol
        (rel, abs) = _error(actual, expected)
        assert (rel <= rel_tol
                or abs <= abs_tol), '%s (rel=%f, abs=%f)' % (message, rel, abs)