Beispiel #1
0
 def setUp(self):
     """Test setUp. Load the test model."""        
     self.cstr = jmi.Model(fname_cstr)
     # Initialize the mesh
     n_e = 150 # 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
     self.nlp = ipopt.NLPCollocationLagrangePolynomials(self.cstr,n_e,hs,n_cp)
Beispiel #2
0
 def setUp(self):
     """Test setUp. Load the test model."""        
     self.vdp = jmi.Model(fname_vdp)
     # Initialize the mesh
     n_e = 100 # Number of elements 
     hs = N.ones(n_e)*1./n_e # Equidistant points
     self.hs = hs
     n_cp = 3; # Number of collocation points in each element
     
     # Create an NLP object
     self.nlp = ipopt.NLPCollocationLagrangePolynomials(self.vdp,n_e,hs,n_cp)
     self.nlp_ipopt = ipopt.CollocationOptimizer(self.nlp)
Beispiel #3
0
def test_dymola_export_import():

    # Load the dynamic library and XML data
    vdp = jmi.Model(fname)

    # 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
    nlp = ipopt.NLPCollocationLagrangePolynomials(vdp, n_e, hs, n_cp)

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

    # Solve the optimization problem
    nlp_ipopt.opt_sim_ipopt_solve()

    # Get the result
    p_opt, traj = nlp.get_result()

    # Write to file
    nlp.export_result_dymola()

    # Load the file we just wrote
    res = jmodelica.io.ResultDymolaTextual(fname + '_result.txt')

    # Check that one of the trajectories match.
    assert max(N.abs(traj[:,3]-res.get_variable_data('x1').x))<1e-12, \
           "The result in the loaded result file does not match that of the loaded file."

    # Check that the value of the cost function is correct
    assert N.abs(p_opt[0]-2.2811587)<1e-5, \
           "The optimal value is not correct."
Beispiel #4
0
def run_demo(with_plots=True):
    """Demonstrate how to solve a dynamic optimization
    problem based on an inverted pendulum system."""

    oc = OptimicaCompiler()
    oc.set_boolean_option('state_start_values_fixed', True)

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

    # Comile the Optimica model first to C code and
    # then to a dynamic library
    oc.compile_model(curr_dir + "/files/Pendulum_pack.mo",
                     "Pendulum_pack.Pendulum_Opt",
                     target='ipopt')

    # Load the dynamic library and XML data
    pend = jmi.Model("Pendulum_pack_Pendulum_Opt")

    # 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
    nlp = ipopt.NLPCollocationLagrangePolynomials(pend, n_e, hs, n_cp)

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

    # Solve the optimization problem
    nlp_ipopt.opt_sim_ipopt_solve()

    # Write to file. The resulting file can also be
    # loaded into Dymola.
    nlp.export_result_dymola()

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

    # Extract variable profiles
    theta = res.get_variable_data('pend.theta')
    dtheta = res.get_variable_data('pend.dtheta')
    x = res.get_variable_data('pend.x')
    dx = res.get_variable_data('pend.dx')
    u = res.get_variable_data('u')

    cost = res.get_variable_data('cost')
    assert N.abs(cost.x[-1] - 1.2921683e-01) < 1e-3, \
           "Wrong value of cost function in pendulum.py"

    if with_plots:
        # Plot
        plt.figure(1)
        plt.clf()
        plt.subplot(211)
        plt.plot(theta.t, theta.x)
        plt.grid()
        plt.ylabel('th')

        plt.subplot(212)
        plt.plot(theta.t, theta.x)
        plt.grid()
        plt.ylabel('dth')
        plt.xlabel('time')
        plt.show()

        plt.figure(2)
        plt.clf()
        plt.subplot(311)
        plt.plot(x.t, x.x)
        plt.grid()
        plt.ylabel('x')

        plt.subplot(312)
        plt.plot(dx.t, dx.x)
        plt.grid()
        plt.ylabel('dx')
        plt.xlabel('time')

        plt.subplot(313)
        plt.plot(u.t, u.x)
        plt.grid()
        plt.ylabel('u')
        plt.xlabel('time')
        plt.show()
Beispiel #5
0
def run_demo(with_plots=True):
    """Optimal control of the quadruple tank process."""

    oc = OptimicaCompiler()
    oc.set_boolean_option('state_start_values_fixed', True)

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

    # Compile the Optimica model first to C code and
    # then to a dynamic library
    oc.compile_model(curr_dir + "/files/QuadTank.mo",
                     "QuadTank_pack.QuadTank_Opt",
                     target='ipopt')

    # Load the dynamic library and XML data
    qt = jmi.Model("QuadTank_pack_QuadTank_Opt")

    # Define inputs for operating point A
    u_A = N.array([2., 2])

    # Define inputs for operating point B
    u_B = N.array([2.5, 2.5])

    x_0 = N.ones(4) * 0.01

    def res(y, t):
        for i in range(4):
            qt.get_x()[i] = y[i]
        qt.jmimodel.ode_f()
        return qt.get_dx()[0:4]

    # Compute stationary state values for operating point A
    qt.set_u(u_A)
    #qt.getPI()[21] = u_A[0]
    #qt.getPI()[22] = u_A[1]

    t_sim = N.linspace(0., 2000., 500)
    y_sim = int.odeint(res, x_0, t_sim)

    x_A = y_sim[-1, :]

    if with_plots:
        # Plot
        plt.figure(1)
        plt.clf()
        plt.subplot(211)
        plt.plot(t_sim, y_sim[:, 0:4])
        plt.grid()

    # Compute stationary state values for operating point A
    qt.set_u(u_B)

    t_sim = N.linspace(0., 2000., 500)
    y_sim = int.odeint(res, x_0, t_sim)

    x_B = y_sim[-1, :]

    if with_plots:
        # Plot
        plt.figure(1)
        plt.subplot(212)
        plt.plot(t_sim, y_sim[:, 0:4])
        plt.grid()
        plt.show()

    qt.get_pi()[13] = x_A[0]
    qt.get_pi()[14] = x_A[1]
    qt.get_pi()[15] = x_A[2]
    qt.get_pi()[16] = x_A[3]

    qt.get_pi()[17] = x_B[0]
    qt.get_pi()[18] = x_B[1]
    qt.get_pi()[19] = x_B[2]
    qt.get_pi()[20] = x_B[3]
    qt.get_pi()[21] = u_B[0]
    qt.get_pi()[22] = u_B[1]

    # Solve optimal control problem

    # 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
    nlp = ipopt.NLPCollocationLagrangePolynomials(qt, n_e, hs, n_cp)

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

    #nlp_ipopt.opt_sim_ipopt_set_string_option("derivative_test","first-order")
    nlp_ipopt.opt_sim_ipopt_set_int_option("max_iter", 500)

    # Solve the optimization problem
    nlp_ipopt.opt_sim_ipopt_solve()

    # Write to file. The resulting file can also be
    # loaded into Dymola.
    nlp.export_result_dymola()

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

    # Extract variable profiles
    x1 = res.get_variable_data('x1')
    x2 = res.get_variable_data('x2')
    x3 = res.get_variable_data('x3')
    x4 = res.get_variable_data('x4')
    u1 = res.get_variable_data('u1')
    u2 = res.get_variable_data('u2')

    cost = res.get_variable_data('cost')

    assert N.abs(cost.x[-1] - 5.0333257e+02) < 1e-3, \
           "Wrong value of cost function in quadtank.py"

    if with_plots:
        # Plot
        plt.figure(2)
        plt.clf()
        plt.subplot(411)
        plt.plot(x1.t, x1.x)
        plt.grid()
        plt.ylabel('x1')

        plt.subplot(412)
        plt.plot(x2.t, x2.x)
        plt.grid()
        plt.ylabel('x2')

        plt.subplot(413)
        plt.plot(x3.t, x3.x)
        plt.grid()
        plt.ylabel('x3')

        plt.subplot(414)
        plt.plot(x4.t, x4.x)
        plt.grid()
        plt.ylabel('x4')
        plt.show()

        plt.figure(3)
        plt.clf()
        plt.subplot(211)
        plt.plot(u1.t, u1.x)
        plt.grid()
        plt.ylabel('u1')

        plt.subplot(212)
        plt.plot(u2.t, u2.x)
        plt.grid()
        plt.ylabel('u2')

    if __name__ == "__main__":
        run_demo()
Beispiel #6
0
def run_demo(with_plots=True):
    """Demonstrate how to solve a minimum time
    dynamic optimization problem based on a
    Van der Pol oscillator system."""

    oc = OptimicaCompiler()
    oc.set_boolean_option('state_start_values_fixed',True)

    curr_dir = os.path.dirname(os.path.abspath(__file__));
    
    # Compile the Optimica model first to C code and
    # then to a dynamic library
    oc.compile_model(curr_dir+"/files/VDP.mo",
                     "VDP_pack.VDP_Opt",
                     target='ipopt')

    # Load the dynamic library and XML data
    vdp=jmi.Model("VDP_pack_VDP_Opt")

    # 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
    nlp = ipopt.NLPCollocationLagrangePolynomials(vdp,n_e,hs,n_cp)

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

#    nlp_ipopt.opt_sim_ipopt_set_string_option("derivative_test","first-order")
    nlp_ipopt.opt_sim_ipopt_set_int_option("max_iter",500)

    # Solve the optimization problem
    nlp_ipopt.opt_sim_ipopt_solve()

    # Retreive the number of points in each column in the
    # result matrix
    n_points = nlp.opt_sim_get_result_variable_vector_length()

    # Write to file. The resulting file can also be
    # loaded into Dymola.
    nlp.export_result_dymola()
    
    # Load the file we just wrote to file
    res = jmodelica.io.ResultDymolaTextual('VDP_pack_VDP_Opt_result.txt')

    # Extract variable profiles
    x1=res.get_variable_data('x1')
    x2=res.get_variable_data('x2')
    u=res.get_variable_data('u')

    cost=res.get_variable_data('cost')
    
    assert N.abs(cost.x[-1] - 2.3469089e+01) < 1e-3, \
            "Wrong value of cost function in vdp.py"  

    if with_plots:
        # Plot
        plt.figure(1)
        plt.clf()
        plt.subplot(311)
        plt.plot(x1.t,x1.x)
        plt.grid()
        plt.ylabel('x1')
        
        plt.subplot(312)
        plt.plot(x2.t,x2.x)
        plt.grid()
        plt.ylabel('x2')
        
        plt.subplot(313)
        plt.plot(u.t,u.x)
        plt.grid()
        plt.ylabel('u')
        plt.xlabel('time')
        plt.show()
Beispiel #7
0
def run_demo(with_plots=True):
    """This example is based on the Hicks-Ray
    Continuously Stirred Tank Reactors (CSTR) system. The system
    has two states, the concentration and the temperature. The
    control input to the system is the temperature of the cooling
    flow in the reactor jacket. The chemical reaction in the reactor
    is exothermic, and also temperature dependent; high temperature
    results in high reaction rate.
    
    The example demonstrates the following steps:
    
    1. How to solve a DAE initialization problem. The initialization
       model have equations specifying that all derivatives
       should be identically zero, which implies that a
       stationary solution is obtained. Two stationary points,
       corresponding to different inputs, are computed. We call
       the stationary points A and B respectively. point A corresponds
       to operating conditions where the reactor is cold and
       the reaction rate is low, whereas point B corresponds to
       a higher temperature where the reaction rate is high.

       For more information about the DAE initialization algorithm, see
       http://www.jmodelica.org/page/10.

    2. How to generate an initial guess for a direct collocation method
       by means of simulation. The trajectories resulting from simulation
       are used to initialize the variables in the transcribed NLP.
       
    3. An optimal control problem is solved where the objective Is to
       transfer the state of the system from stationary point A to point
       B. The challenge is to ignite the reactor while avoiding
       uncontrolled temperature increase. It is also demonstrated how to
       set parameter and variable values in a model.

       More information about the simultaneous optimization algorithm
       can be found at http://www.jmodelica.org/page/10.

    4. The optimization result is saved to file and then
       the important variables are plotted.

    5. Simulate the system with the optimal control profile. This step
       is important in order to verify that the approximation in the
       transcription step is valid.
       
"""

    curr_dir = os.path.dirname(os.path.abspath(__file__));
    # Create a Modelica compiler instance
    oc = OptimicaCompiler()
        
    # Compile the stationary initialization model into a DLL
    oc.compile_model(curr_dir+"/files/CSTR.mo", "CSTR.CSTR_Init", target='ipopt')

    # Load a model instance into Python
    init_model = jmi.Model("CSTR_CSTR_Init")
    
    # 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)
    
    # Set inputs for Stationary point A
    Tc_0_A = 250
    init_model.set_value('Tc',Tc_0_A)
    
    # init_nlp_ipopt.init_opt_ipopt_set_string_option("derivative_test","first-order")
    # init_nlp_ipopt.init_opt_ipopt_set_int_option("max_iter",5)
    
    # Solve the DAE initialization system with Ipopt
    init_nlp_ipopt.init_opt_ipopt_solve()
    
    # Store stationary point A
    c_0_A = init_model.get_value('c')
    T_0_A = init_model.get_value('T')
    
    # 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
    init_model.set_value('Tc',Tc_0_B)
        
    # Solve the DAE initialization system with Ipopt
    init_nlp_ipopt.init_opt_ipopt_solve()
    
    # Store stationary point A
    c_0_B = init_model.get_value('c')
    T_0_B = init_model.get_value('T')
    
    # 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)

    # Compute initial guess trajectories by means of simulation

    # Create the time vector
    t = N.linspace(1,150.,100)
    # Create the input vector from the target input value. The
    # target input value is here increased in order to get a
    # better initial guess.
    u = (Tc_0_B+35)*N.ones(N.size(t,0))
    u = N.array([u])
    u = N.transpose(u)
    # Create a Trajectory object that can be passed to the simulator
    u_traj = TrajectoryLinearInterpolation(t,u)

    # Comile the Modelica model first to C code and
    # then to a dynamic library
    oc.compile_model(curr_dir+"/files/CSTR.mo","CSTR.CSTR_Init_Optimization",target='ipopt')

    # Load the dynamic library and XML data
    init_sim_model=jmi.Model("CSTR_CSTR_Init_Optimization")

    # Set model parameters
    init_sim_model.set_value('cstr.c_init',c_0_A)
    init_sim_model.set_value('cstr.T_init',T_0_A)
    init_sim_model.set_value('Tc_0',Tc_0_A)
    init_sim_model.set_value('c_ref',c_0_B)
    init_sim_model.set_value('T_ref',T_0_B)
    init_sim_model.set_value('Tc_ref',u_traj.eval(0.)[0])

    # Create DAE initialization object.
    init_nlp = NLPInitialization(init_sim_model)
    
    # Create an Ipopt solver object for the DAE initialization system
    init_nlp_ipopt = InitializationOptimizer(init_nlp)
        
    # Solve the DAE initialization system with Ipopt
    init_nlp_ipopt.init_opt_ipopt_solve()

    # Create a simulator
    simulator = SundialsDAESimulator(init_sim_model, verbosity=3, start_time=0.0, \
                                     final_time=150, time_step=0.01,input=u_traj)
    # Run simulation
    simulator.run()
    
    # Write data to file 
    simulator.write_data()

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

    # Extract variable profiles
    c_init_sim=res.get_variable_data('cstr.c')
    T_init_sim=res.get_variable_data('cstr.T')
    Tc_init_sim=res.get_variable_data('cstr.Tc')

    # Plot the results
    if with_plots:
        plt.figure(1)
        plt.clf()
        plt.hold(True)
        plt.subplot(311)
        plt.plot(c_init_sim.t,c_init_sim.x)
        plt.grid()
        plt.ylabel('Concentration')

        plt.subplot(312)
        plt.plot(T_init_sim.t,T_init_sim.x)
        plt.grid()
        plt.ylabel('Temperature')

        plt.subplot(313)
        plt.plot(Tc_init_sim.t,Tc_init_sim.x)
        plt.grid()
        plt.ylabel('Cooling temperature')
        plt.xlabel('time')
        plt.show()


    # Solve optimal control problem    
    oc.compile_model(curr_dir+"/files/CSTR.mo", "CSTR.CSTR_Opt", target='ipopt')

    cstr = jmi.Model("CSTR_CSTR_Opt")

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

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

    # Initialize the mesh
    n_e = 100 # 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
    nlp = ipopt.NLPCollocationLagrangePolynomials(cstr,n_e,hs,n_cp)

    # Use the simulated trajectories to initialize the model
    nlp.set_initial_from_dymola(res, hs, 0, 0)
    
    # Create an Ipopt NLP object
    nlp_ipopt = ipopt.CollocationOptimizer(nlp)
       
    nlp_ipopt.opt_sim_ipopt_set_int_option("max_iter",500)

    # Solve the optimization problem
    nlp_ipopt.opt_sim_ipopt_solve()
    
    # Write to file. The resulting file (CSTR_CSTR_Opt_result.txt) can also be
    # loaded into Dymola.
    nlp.export_result_dymola()
    
    # Load the file we just wrote to file
    res = jmodelica.io.ResultDymolaTextual('CSTR_CSTR_Opt_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')

    c_ref=res.get_variable_data('c_ref')
    T_ref=res.get_variable_data('T_ref')
    Tc_ref=res.get_variable_data('Tc_ref')

    cost=res.get_variable_data('cost')
    
    assert N.abs(cost.x[-1]/1.e7 - 1.8585429) < 1e-3, \
            "Wrong value of cost function in cstr.py"  

    # Plot the results
    if with_plots:
        plt.figure(2)
        plt.clf()
        plt.hold(True)
        plt.subplot(311)
        plt.plot(c_res.t,c_res.x)
        plt.plot(c_ref.t,c_ref.x,'--')
        plt.grid()
        plt.ylabel('Concentration')

        plt.subplot(312)
        plt.plot(T_res.t,T_res.x)
        plt.plot(T_ref.t,T_ref.x,'--')
        plt.grid()
        plt.ylabel('Temperature')

        plt.subplot(313)
        plt.plot(Tc_res.t,Tc_res.x)
        plt.plot(Tc_ref.t,Tc_ref.x,'--')
        plt.grid()
        plt.ylabel('Cooling temperature')
        plt.xlabel('time')
        plt.show()

    # Simulate to verify the optimal solution
    # Set up input trajectory
    t = Tc_res.t 
    u = Tc_res.x
    u = N.array([u])
    u = N.transpose(u)
    u_traj = TrajectoryLinearInterpolation(t,u)
    
    # Comile the Modelica model first to C code and
    # then to a dynamic library
    oc.compile_model(curr_dir+"/files/CSTR.mo","CSTR.CSTR",target='ipopt')

    # Load the dynamic library and XML data
    sim_model=jmi.Model("CSTR_CSTR")

    sim_model.set_value('c_init',c_0_A)
    sim_model.set_value('T_init',T_0_A)
    sim_model.set_value('Tc',u_traj.eval(0.)[0])

    # Create DAE initialization object.
    init_nlp = NLPInitialization(sim_model)
    
    # Create an Ipopt solver object for the DAE initialization system
    init_nlp_ipopt = InitializationOptimizer(init_nlp)
        
    # Solve the DAE initialization system with Ipopt
    init_nlp_ipopt.init_opt_ipopt_solve()

    simulator = SundialsDAESimulator(sim_model, verbosity=3, start_time=0.0, \
                                     final_time=150, time_step=0.01,input=u_traj)
    # Run simulation
    simulator.run()

    # Store simulation data to file    
    simulator.write_data()

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

    # Extract variable profiles
    c_sim=res.get_variable_data('c')
    T_sim=res.get_variable_data('T')
    Tc_sim=res.get_variable_data('Tc')

    # Plot the results
    if with_plots:
        plt.figure(3)
        plt.clf()
        plt.hold(True)
        plt.subplot(311)
        plt.plot(c_res.t,c_res.x,'--')
        plt.plot(c_sim.t,c_sim.x)
        plt.legend(('optimized','simulated'))
        plt.grid()
        plt.ylabel('Concentration')

        plt.subplot(312)
        plt.plot(T_res.t,T_res.x,'--')
        plt.plot(T_sim.t,T_sim.x)
        plt.legend(('optimized','simulated'))
        plt.grid()
        plt.ylabel('Temperature')

        plt.subplot(313)
        plt.plot(Tc_res.t,Tc_res.x,'--')
        plt.plot(Tc_sim.t,Tc_sim.x)
        plt.legend(('optimized','simulated'))
        plt.grid()
        plt.ylabel('Cooling temperature')
        plt.xlabel('time')
        plt.show()
Beispiel #8
0
def run_demo(with_plots=True):
    """ Load change of a distillation column. The distillation column model
    is documented in the paper:

    @Article{hahn+02,
    title={An improved method for nonlinear model reduction using balancing of empirical gramians},
    author={Hahn, J. and Edgar, T.F.},
    journal={Computers and Chemical Engineering},
    volume={26},
    number={10},
    pages={1379-1397},
    year={2002}
    }
    """

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

    # Create a Modelica compiler instance
    mc = ModelicaCompiler()

    # Compile the stationary initialization model into a DLL
    mc.compile_model(curr_dir + "/files/DISTLib.mo",
                     "DISTLib.Binary_Dist_initial",
                     target='ipopt')

    # Load a model instance into Python
    init_model = jmi.Model("DISTLib_Binary_Dist_initial")

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

    # Set inputs for Stationary point A
    u1_0_A = 3.0
    init_model.set_value('u1', u1_0_A)

    # init_nlp_ipopt.init_opt_ipopt_set_string_option("derivative_test","first-order")
    #init_nlp_ipopt.init_opt_ipopt_set_int_option("max_iter",5)

    # Solve the DAE initialization system with Ipopt
    init_nlp_ipopt.init_opt_ipopt_solve()

    # Store stationary point A
    y_A = N.zeros(32)
    x_A = N.zeros(32)
    # print(' *** Stationary point A ***')
    print '(Tray index, x_i_A, y_i_A)'
    for i in range(N.size(y_A)):
        y_A[i] = init_model.get_value('y' + str(i + 1))
        x_A[i] = init_model.get_value('x' + str(i + 1))
        print '(' + str(i + 1) + ', %f, %f)' % (x_A[i], y_A[i])

    # Set inputs for stationary point B
    u1_0_B = 3.0 - 1
    init_model.set_value('u1', u1_0_B)

    # init_nlp_ipopt.init_opt_ipopt_set_string_option("derivative_test","first-order")
    #init_nlp_ipopt.init_opt_ipopt_set_int_option("max_iter",5)

    # Solve the DAE initialization system with Ipopt
    init_nlp_ipopt.init_opt_ipopt_solve()

    # Store stationary point B
    y_B = N.zeros(32)
    x_B = N.zeros(32)
    # print(' *** Stationary point B ***')
    print '(Tray index, x_i_B, y_i_B)'
    for i in range(N.size(y_B)):
        y_B[i] = init_model.get_value('y' + str(i + 1))
        x_B[i] = init_model.get_value('x' + str(i + 1))
        print '(' + str(i + 1) + ', %f, %f)' % (x_B[i], y_B[i])

    # ## Set up and solve an optimal control problem.

    # Create an OptimicaCompiler instance
    oc = OptimicaCompiler()

    # Generate initial equations for states even if fixed=false
    oc.set_boolean_option('state_start_values_fixed', True)

    # Compil the Model
    oc.compile_model(
        (curr_dir + "/files/DISTLib.mo", curr_dir + "/files/DISTLib_Opt.mo"),
        "DISTLib_Opt.Binary_Dist_Opt1",
        target='ipopt')

    # Load the dynamic library and XML data
    model = jmi.Model("DISTLib_Opt_Binary_Dist_Opt1")

    # Initialize the model with parameters

    # Initialize the model to stationary point A
    for i in range(N.size(x_A)):
        model.set_value('x' + str(i + 1) + '_0', x_A[i])

    # Set the target values to stationary point B
    model.set_value('u1_ref', u1_0_B)
    model.set_value('y1_ref', y_B[0])

    # Initialize the optimization 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 representing the discretized problem
    nlp = ipopt.NLPCollocationLagrangePolynomials(model, n_e, hs, n_cp)

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

    #nlp_ipopt.opt_sim_ipopt_set_string_option("derivative_test","first-order")

    # If the convergence is slow, may increase tolerance.
    #nlp_ipopt.opt_sim_ipopt_set_num_option("tol",0.0001)

    #Solve the optimization problem
    nlp_ipopt.opt_sim_ipopt_solve()

    # Write to file. The resulting file  can be
    # loaded into Dymola.
    nlp.export_result_dymola()

    # Load the file we just wrote
    res = jmodelica.io.ResultDymolaTextual(
        'DISTLib_Opt_Binary_Dist_Opt1_result.txt')

    # Extract variable profiles
    u1_res = res.get_variable_data('u1')
    u1_ref_res = res.get_variable_data('u1_ref')
    y1_ref_res = res.get_variable_data('y1_ref')

    x_res = []
    x_ref_res = []
    for i in range(N.size(x_B)):
        x_res.append(res.get_variable_data('x' + str(i + 1)))

    y_res = []
    for i in range(N.size(x_B)):
        y_res.append(res.get_variable_data('y' + str(i + 1)))

    # Plot the results
    if with_plots:
        plt.figure(1)
        plt.clf()
        plt.hold(True)
        plt.subplot(311)
        plt.title('Liquid composition')
        plt.plot(x_res[0].t, x_res[0].x)
        plt.ylabel('x1')
        plt.grid()
        plt.subplot(312)
        plt.plot(x_res[16].t, x_res[16].x)
        plt.ylabel('x17')
        plt.grid()
        plt.subplot(313)
        plt.plot(x_res[31].t, x_res[31].x)
        plt.ylabel('x32')
        plt.grid()
        plt.xlabel('t [s]')
        plt.show()

        # Plot the results
        plt.figure(2)
        plt.clf()
        plt.hold(True)
        plt.subplot(311)
        plt.title('Vapor composition')
        plt.plot(y_res[0].t, y_res[0].x)
        plt.plot(y1_ref_res.t, y1_ref_res.x, '--')
        plt.ylabel('y1')
        plt.grid()
        plt.subplot(312)
        plt.plot(y_res[16].t, y_res[16].x)
        plt.ylabel('y17')
        plt.grid()
        plt.subplot(313)
        plt.plot(y_res[31].t, y_res[31].x)
        plt.ylabel('y32')
        plt.grid()
        plt.xlabel('t [s]')
        plt.show()

        plt.figure(3)
        plt.clf()
        plt.hold(True)
        plt.plot(u1_res.t, u1_res.x)
        plt.ylabel('u')
        plt.plot(u1_ref_res.t, u1_ref_res.x, '--')
        plt.xlabel('t [s]')
        plt.title('Reflux ratio')
        plt.grid()
        plt.show()
Beispiel #9
0
def run_demo(with_plots=True):
    """This example is based on a system composed of two
    Continously Stirred Tank Reactors (CSTRs) in series.
    The example demonstrates the following steps:
    
    1. How to solve a DAE initialization problem. The initialization
       model have equations specifying that all derivatives
       should be identically zero, which implies that a
       stationary solution is obtained. Two stationary points,
       corresponding to different inputs, are computed. We call
       the stationary points A and B respectively. For more information
       about the DAE initialization algorithm, see
       http://www.jmodelica.org/page/10.
    
    2. An optimal control problem is solved where the objective
       Is to transfer the state of the system from stationary
       point A to point B. Here, it is also demonstrated how
       to set parameter values in a model. More information
       about the simultaneous optimization algorithm can be
       found at http://www.jmodelica.org/page/10.
    
    3. The optimization result is saved to file and then
       the important variables are plotted."""

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

    # Create a Modelica compiler instance
    mc = ModelicaCompiler()

    # Compile the stationary initialization model into a DLL
    mc.compile_model(curr_dir + "/files/CSTRLib.mo",
                     "CSTRLib.Components.Two_CSTRs_stat_init",
                     target='ipopt')

    # Load a model instance into Python
    init_model = jmi.Model("CSTRLib_Components_Two_CSTRs_stat_init")

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

    # Set inputs for Stationary point A
    u1_0_A = 1
    u2_0_A = 1
    init_model.set_value('u1', u1_0_A)
    init_model.set_value('u2', u2_0_A)

    # init_nlp_ipopt.init_opt_ipopt_set_string_option("derivative_test","first-order")
    #init_nlp_ipopt.init_opt_ipopt_set_int_option("max_iter",5)

    # Solve the DAE initialization system with Ipopt
    init_nlp_ipopt.init_opt_ipopt_solve()

    # Store stationary point A
    CA1_0_A = init_model.get_value('CA1')
    CA2_0_A = init_model.get_value('CA2')
    T1_0_A = init_model.get_value('T1')
    T2_0_A = init_model.get_value('T2')

    # Print some data for stationary point A
    print(' *** Stationary point A ***')
    print('u = [%f,%f]' % (u1_0_A, u2_0_A))
    print('CAi = [%f,%f]' % (CA1_0_A, CA2_0_A))
    print('Ti = [%f,%f]' % (T1_0_A, T2_0_A))

    # Set inputs for stationary point B
    u1_0_B = 1.1
    u2_0_B = 0.9
    init_model.set_value('u1', u1_0_B)
    init_model.set_value('u2', u2_0_B)

    # init_nlp_ipopt.init_opt_ipopt_set_string_option("derivative_test","first-order")
    #init_nlp_ipopt.init_opt_ipopt_set_int_option("max_iter",5)

    # Solve the DAE initialization system with Ipopt
    init_nlp_ipopt.init_opt_ipopt_solve()

    # Stationary point B
    CA1_0_B = init_model.get_value('CA1')
    CA2_0_B = init_model.get_value('CA2')
    T1_0_B = init_model.get_value('T1')
    T2_0_B = init_model.get_value('T2')

    # Print some data for stationary point B
    print(' *** Stationary point B ***')
    print('u = [%f,%f]' % (u1_0_B, u2_0_B))
    print('CAi = [%f,%f]' % (CA1_0_B, CA2_0_B))
    print('Ti = [%f,%f]' % (T1_0_B, T2_0_B))

    ## Set up and solve an optimal control problem.

    # Create an OptimicaCompiler instance
    oc = OptimicaCompiler()

    # Compil the Model
    oc.compile_model(
        (curr_dir + "/files/CSTRLib.mo", curr_dir + "/files/CSTR2_Opt.mo"),
        "CSTR2_Opt",
        target='ipopt')

    # Load the dynamic library and XML data
    model = jmi.Model("CSTR2_Opt")

    # Initialize the model with parameters

    # Initialize the model to stationary point A
    model.set_value('two_CSTRs_Series.CA1_0', CA1_0_A)
    model.set_value('two_CSTRs_Series.CA2_0', CA2_0_A)
    model.set_value('two_CSTRs_Series.T1_0', T1_0_A)
    model.set_value('two_CSTRs_Series.T2_0', T2_0_A)

    # Set the target values to stationary point B
    model.set_value('u1_ref', u1_0_B)
    model.set_value('u2_ref', u2_0_B)
    model.set_value('CA1_ref', CA1_0_B)
    model.set_value('CA2_ref', CA2_0_B)

    # Initialize the optimization mesh
    n_e = 30  # 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 representing the discretized problem
    nlp = ipopt.NLPCollocationLagrangePolynomials(model, n_e, hs, n_cp)

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

    #nlp_ipopt.opt_sim_ipopt_set_string_option("derivative_test","first-order")

    # The convergence is slow, for some reason, increasing tolerance.
    nlp_ipopt.opt_sim_ipopt_set_num_option("tol", 0.0001)

    #Solve the optimization problem
    nlp_ipopt.opt_sim_ipopt_solve()

    # Write to file. The resulting file (CSTR2_Opt_result.txt) can be
    # loaded into Dymola.
    nlp.export_result_dymola()

    # Load the file we just wrote
    res = jmodelica.io.ResultDymolaTextual('CSTR2_Opt_result.txt')

    # Extract variable profiles
    CA1_res = res.get_variable_data('two_CSTRs_Series.CA1')
    CA2_res = res.get_variable_data('two_CSTRs_Series.CA2')
    T1_res = res.get_variable_data('two_CSTRs_Series.T1')
    T2_res = res.get_variable_data('two_CSTRs_Series.T2')
    u1_res = res.get_variable_data('two_CSTRs_Series.u1')
    u2_res = res.get_variable_data('two_CSTRs_Series.u2')

    CA1_ref_res = res.get_variable_data('CA1_ref')
    CA2_ref_res = res.get_variable_data('CA2_ref')

    u1_ref_res = res.get_variable_data('u1_ref')
    u2_ref_res = res.get_variable_data('u2_ref')

    # Plot the results
    if with_plots:
        plt.figure(1)
        plt.clf()
        plt.hold(True)
        plt.subplot(211)
        plt.plot(CA1_res.t, CA1_res.x)
        plt.plot(CA1_ref_res.t, CA1_ref_res.x, '--')
        plt.ylabel('Concentration reactor 1 [J/l]')
        plt.grid()
        plt.subplot(212)
        plt.plot(CA2_res.t, CA2_res.x)
        plt.plot(CA2_ref_res.t, CA2_ref_res.x, '--')
        plt.ylabel('Concentration reactor 2 [J/l]')
        plt.xlabel('t [s]')
        plt.grid()
        plt.show()

        plt.figure(2)
        plt.clf()
        plt.hold(True)
        plt.subplot(211)
        plt.plot(T1_res.t, T1_res.x)
        plt.ylabel('Temperature reactor 1 [K]')
        plt.grid()
        plt.subplot(212)
        plt.plot(T2_res.t, T2_res.x)
        plt.ylabel('Temperature reactor 2 [K]')
        plt.grid()
        plt.xlabel('t [s]')
        plt.show()

        plt.figure(3)
        plt.clf()
        plt.hold(True)
        plt.subplot(211)
        plt.plot(u1_res.t, u1_res.x)
        plt.ylabel('Input 1')
        plt.plot(u1_ref_res.t, u1_ref_res.x, '--')
        plt.grid()
        plt.subplot(212)
        plt.plot(u2_res.t, u2_res.x)
        plt.ylabel('Input 2')
        plt.plot(u2_ref_res.t, u2_ref_res.x, '--')
        plt.xlabel('t [s]')
        plt.grid()
        plt.show()
Beispiel #10
0
def run_demo(with_plots=True):
    """Demonstrate how to solve a simple
    parameter estimation problem."""

    oc = OptimicaCompiler()
#    oc.set_boolean_option('state_start_values_fixed',True)

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

    # Compile the Optimica model first to C code and
    # then to a dynamic library
    oc.compile_model(curr_dir+"/files/ParameterEstimation_1.mo",
                     "ParEst.ParEst",
                     target='ipopt')
    
    # Load the dynamic library and XML data
    model=jmi.Model("ParEst_ParEst")
    
    # Retreive parameter and variable vectors
    pi = model.get_pi();
    x = model.get_x();
    dx = model.get_dx();
    u = model.get_u();
    w = model.get_w();
    
    # Set model input
    w[0] = 1

    # ODE right hand side
    # This can be done since DAE residuals 1 and 2
    # are written on simple "ODE" form: f(x,u)-\dot x = 0
    def F(xx,t):
        dx[0] = 0. # Set derivatives to zero
        dx[1] = 0.
        x[0] = xx[0] # Set states
        x[1] = xx[1]
        res = N.zeros(3); # Create residual vector
        model.jmimodel.dae_F(res) # Evaluate DAE residual
        return N.array([res[1],res[2]])
    
    # Simulate model to get measurement data
    N_points = 100 # Number of points in simulation
    t0 = 0
    tf = 15
    t_sim = N.linspace(t0,tf,num=N_points)
    xx0=N.array([0.,0.])
    xx = integr.odeint(F,xx0,t_sim)
        
    # Extract measurements
    N_points_meas = 11
    t_meas = N.linspace(t0,10,num=N_points_meas)
    xx_meas = integr.odeint(F,xx0,t_meas)

    # Add measurement noice
    xx_meas[:,0] = xx_meas[:,0] + N.random.random(N_points_meas)*0.2-0.1
    
    # Set parameters corresponding to measurement data in model
    pi[4:15] = t_meas
    pi[15:26] = xx_meas[:,0]

    if with_plots:
        # Plot simulation
        plt.figure(1)
        plt.clf()
        plt.subplot(211)
        plt.plot(t_sim,xx[:,0])
        plt.grid()
        plt.plot(t_meas,xx_meas[:,0],'x')
        plt.ylabel('x1')
        
        plt.subplot(212)
        plt.plot(t_sim,xx[:,1])
        plt.grid()
        plt.ylabel('x2')
        plt.show()
        
    # 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
    nlp = ipopt.NLPCollocationLagrangePolynomials(model,n_e,hs,n_cp)
    
    # Create an Ipopt NLP object
    nlp_ipopt = ipopt.CollocationOptimizer(nlp)
    
    #nlp_ipopt.opt_sim_ipopt_set_string_option("derivative_test","first-order")
    nlp_ipopt.opt_sim_ipopt_set_int_option("max_iter",500)
    
    # Solve the optimization problem
    nlp_ipopt.opt_sim_ipopt_solve()

    # Write to file. The resulting file can also be
    # loaded into Dymola.
    nlp.export_result_dymola()
    
    # Load the file we just wrote to file
    res = jmodelica.io.ResultDymolaTextual('ParEst_ParEst_result.txt')

    # Extract variable profiles
    x1 = res.get_variable_data('sys.x1')
    u = res.get_variable_data('u')
    
    if with_plots:
        # Plot optimization result
        plt.figure(2)
        plt.clf()
        plt.subplot(211)
        plt.plot(x1.t,x1.x)
        plt.plot(t_meas,xx_meas[:,0],'x')
        plt.grid()
        plt.ylabel('y')
        
        plt.subplot(212)
        plt.plot(u.t,u.x)
        plt.grid()
        plt.ylabel('u')
        plt.show()
        
        print("** Optimal parameter values: **")
        print("w = %f"%pi[0])
        print("z = %f"%pi[1])