Example #1
0
def run_demo(with_plots=True):
    """
    An example on how to simulate a model using the DAE simulator. The result 
    can be compared with that of sim_rlc.py which has solved the same problem 
    using dymola. Also writes information to a file.
    """

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

    model_name = "RLC_Circuit"
    mofile = curr_dir + "/files/RLC_Circuit.mo"

    jmu_name = compile_jmu(model_name, mofile)
    model = JMUModel(jmu_name)
    init_res = model.initialize()

    (E_dae, A_dae, B_dae, F_dae, g_dae, state_names, input_names, algebraic_names, dx0, x0, u0, w0, t0) = linearize_dae(
        init_res.model
    )

    (A_ode, B_ode, g_ode, H_ode, M_ode, q_ode) = linear_dae_to_ode(E_dae, A_dae, B_dae, F_dae, g_dae)

    res1 = model.simulate()

    jmu_name = compile_jmu("RLC_Circuit_Linearized", mofile)
    lin_model = JMUModel(jmu_name)
    res2 = lin_model.simulate()

    c_v_1 = res1["capacitor.v"]
    i_p_i_1 = res1["inductor.p.i"]
    i_p1_i_1 = res1["inductor1.p.i"]
    t_1 = res1["time"]

    c_v_2 = res2["x[1]"]
    i_p_i_2 = res2["x[2]"]
    i_p1_i_2 = res2["x[3]"]
    t_2 = res2["time"]

    assert N.abs(res1.final("capacitor.v") - res2.final("x[1]")) < 1e-3

    if with_plots:
        p.figure(1)
        p.hold(True)
        p.subplot(311)
        p.plot(t_1, c_v_1)
        p.plot(t_2, c_v_2, "g")
        p.ylabel("c.v")
        p.legend(("original model", "linearized ODE"))
        p.grid()
        p.subplot(312)
        p.plot(t_1, i_p_i_1)
        p.plot(t_2, i_p_i_2, "g")
        p.ylabel("i.p.i")
        p.grid()
        p.subplot(313)
        p.plot(t_1, i_p1_i_1)
        p.plot(t_2, i_p1_i_2, "g")
        p.ylabel("i.p1.i")
        p.grid()
        p.show()
Example #2
0
def run_demo(with_plots=True):
    """
    Demonstrate how to solve a continous state constraint optimization problem.
    reference : PROPT - Matlab Optimal Control Software (DAE, ODE)
    """

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

    jmu_name = compile_jmu(
        "JMExamples_opt.ContState_opt",
        (os.path.join(curr_dir, 'files', 'JMExamples_opt.mop'),
         os.path.join(curr_dir, 'files', 'JMExamples.mo')))
    cs = JMUModel(jmu_name)

    res = cs.optimize()

    # Extract variable profiles
    x1 = res['x1']
    x2 = res['x2']
    u = res['u']
    t = res['time']
    p = res['p']
    J = res['J']

    assert N.abs(res.final('x1') + 0.22364) < 1e-4
    assert N.abs(res.final('x2') - 0.00813) < 1e-4
    assert N.abs(res.final('p') - 1.49187) < 1e-4
    assert N.abs(res.final('J') - 0.16982) < 1e-4

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

        plt.subplot(221)
        plt.plot(t, x1, t, x2)
        plt.grid()
        plt.ylabel('x')
        plt.xlabel('time')

        plt.subplot(222)
        plt.plot(t, u)
        plt.grid()
        plt.ylabel('u')
        plt.xlabel('time')

        plt.subplot(223)
        plt.plot(t, J)
        plt.grid()
        plt.ylabel('J')
        plt.xlabel('time')

        plt.subplot(224)
        plt.plot(t, p)
        plt.grid()
        plt.ylabel('path')
        plt.xlabel('time')

        plt.show()
Example #3
0
def run_demo(with_plots=True):
    """
    Demonstrate how to solve a continous state constraint optimization problem.
    reference : PROPT - Matlab Optimal Control Software (DAE, ODE)
    """

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

    jmu_name = compile_jmu("JMExamples_opt.ContState_opt", 
        (os.path.join(curr_dir, 'files', 'JMExamples_opt.mop'), os.path.join(curr_dir, 'files', 'JMExamples.mo')))
    cs = JMUModel(jmu_name)
    
    res = cs.optimize()

    # Extract variable profiles
    x1 = res['x1']
    x2 = res['x2']
    u = res['u']
    t = res['time']
    p = res['p']
    J = res['J']  

    assert N.abs(res.final('x1') + 0.22364) < 1e-4
    assert N.abs(res.final('x2') - 0.00813) < 1e-4
    assert N.abs(res.final('p') - 1.49187)  < 1e-4
    assert N.abs(res.final('J') - 0.16982)  < 1e-4
   
    if with_plots:
        plt.figure(1)
        plt.clf()
        
        plt.subplot(221)
        plt.plot(t,x1,t,x2)
        plt.grid()
        plt.ylabel('x')
        plt.xlabel('time')
        
        plt.subplot(222)
        plt.plot(t,u)
        plt.grid()
        plt.ylabel('u')
        plt.xlabel('time')
        
        plt.subplot(223)
        plt.plot(t,J)
        plt.grid()
        plt.ylabel('J')
        plt.xlabel('time')
        
        plt.subplot(224)
        plt.plot(t,p)
        plt.grid()
        plt.ylabel('path')
        plt.xlabel('time')
        
        plt.show()
Example #4
0
def run_demo(with_plots=True):
    """
    Demonstrate how to solve and calculate sensitivity for initial conditions.
    See "http://sundials.2283335.n4.nabble.com/Forward-sensitivities-for-  \
               initial-conditions-td3239724.html"
    """
    curr_dir = os.path.dirname(os.path.abspath(__file__));
    
    jmu_name = compile_jmu("LeadTransport", curr_dir+"/files/leadtransport.mop")
    model = JMUModel(jmu_name)
    
    opts = model.simulate_options()
    opts["IDA_options"]["sensitivity"] = True
    opts["IDA_options"]["rtol"] = 1e-7
    opts["IDA_options"]["suppress_sens"] = False #Use the sensitivity variablers
                                                 #in the error test.
    
    res = model.simulate(final_time=400, options=opts)

    # Extract variable profiles
    y1,y2,y3 = res['y1'], res["y2"], res["y3"]
    dy1p1,dy2p1,dy3p1 = res['dy1/dp1'], res['dy2/dp1'], res['dy3/dp1']
    dy1p2,dy2p2,dy3p2 = res['dy1/dp2'], res['dy2/dp2'], res['dy3/dp2']
    dy1p3,dy2p3,dy3p3 = res['dy1/dp3'], res['dy2/dp3'], res['dy3/dp3']
    t=res['time']
    
    assert N.abs(res.initial('dy1/dp1') - 1.000) < 1e-3
    assert N.abs(res.initial('dy1/dp2') - 1.000) < 1e-3
    assert N.abs(res.initial('dy2/dp2') - 1.000) < 1e-3 

    if with_plots:
        # Plot
        plt.figure(1)
        plt.clf()
        plt.subplot(221)
        plt.plot(t,y1,t,y2,t,y3)
        plt.grid()
        plt.legend(("y1","y2","y3"))
        
        plt.subplot(222)
        plt.plot(t,dy1p1,t,dy2p1,t,dy3p1)
        plt.grid()
        plt.legend(("dy1/dp1","dy2/dp1","dy3/dp1"))
        
        plt.subplot(223)
        plt.plot(t,dy1p2,t,dy2p2,t,dy3p2)
        plt.grid()
        plt.legend(("dy1/dp2","dy2/dp2","dy3/dp2"))
        
        plt.subplot(224)
        plt.plot(t,dy1p3,t,dy2p3,t,dy3p3)
        plt.grid()
        plt.legend(("dy1/dp3","dy2/dp3","dy3/dp3"))
        plt.suptitle("Lead transport through the body")
        plt.show()
Example #5
0
def run_simulation_with_inputs(time, price, pv, bldg, plot=False):
    """
    This function runs a simulation that uses inputs data series
    """

    # get current directory
    curr_dir = os.path.dirname(os.path.abspath(__file__))

    # compile FMU
    path = os.path.join(curr_dir, "..", "Models", "ElectricalNetwork.mop")
    jmu_model = compile_jmu('ElectricNetwork.Network', path)

    # Load the model instance into Python
    model = JMUModel(jmu_model)

    # create input data series for price and current battery
    Npoints = len(time)

    # for the simulation no current flow
    Ibatt = np.zeros(Npoints)

    # Build input trajectory matrix for use in simulation
    u = np.transpose(np.vstack((t_data, Ibatt, price, np.squeeze(pv[:,0]), np.squeeze(pv[:,1]), \
                                np.squeeze(pv[:,2]), np.squeeze(bldg[:,0]), np.squeeze(bldg[:,1]), np.squeeze(bldg[:,2]))))

    # Solve the DAE initialization system
    model.initialize()

    # Simulate
    res = model.simulate(input=([
        'Ibatt', 'price', 'pv1', 'pv2', 'pv3', 'bldg1', 'bldg2', 'bldg3'
    ], u),
                         start_time=0.,
                         final_time=24.0 * 3600.0)

    # Extract variable profiles
    Vs_init_sim = res['Vs']
    V1_init_sim = res['V1']
    V2_init_sim = res['V2']
    V3_init_sim = res['V3']
    E_init_sim = res['E']
    SOC_init_sim = res['SOC']
    Money_init_sim = res['Money']
    price_init_sim = res['price']
    t_init_sim = res['time']

    # plot results
    if plot:
        plotFunction(t_init_sim, Vs_init_sim, V1_init_sim, V2_init_sim, \
                 V3_init_sim, E_init_sim, SOC_init_sim, Money_init_sim, price_init_sim)

    return res
Example #6
0
def run_demo(with_plots=True):
    """
    Catalyst Mixing model: Determine the optimal mixing policy of two catalysts along 
    the length of a tubular plug flow reactor involving several reactions.
    
    Reference :
    Second-order sensitivities of general dynamic systems with application to optimal control problems. 
    1999, Vassilios S. Vassiliadis, Eva Balsa Canto, Julio R. Banga Case Study 6.2: Catalyst mixing
    """

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

    jmu_name = compile_jmu(
        "JMExamples_opt.CatalystMixing_opt",
        (os.path.join(curr_dir, 'files', 'JMExamples_opt.mop'),
         os.path.join(curr_dir, 'files', 'JMExamples.mo')))
    cm = JMUModel(jmu_name)

    res = cm.optimize()

    # Extract variable profiles
    x1 = res['x1']
    x2 = res['x2']
    u = res['u']
    t = res['time']

    assert N.abs(res.final('x1') - 0.899996) < 1e-5
    assert N.abs(res.final('x2') - 0.051948) < 1e-5

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

        plt.subplot(311)
        plt.plot(t, x1)
        plt.grid()
        plt.ylabel('x1')
        plt.xlabel('time')

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

        plt.subplot(313)
        plt.plot(t, u)
        plt.grid()
        plt.ylabel('u')
        plt.xlabel('time')

        plt.show()
def run_demo(with_plots=True):
    """
    Static calibration of the quad tank model.
    """

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

    jmu_name = compile_jmu("QuadTank_pack.QuadTank_Static",
                           curr_dir + "/files/QuadTank.mop")

    # Load static calibration model
    qt_static = JMUModel(jmu_name)

    # Set control inputs
    qt_static.set("u1", 2.5)
    qt_static.set("u2", 2.5)

    # Save nominal values
    a1_nom = qt_static.get("a1")
    a2_nom = qt_static.get("a2")

    init_res = qt_static.initialize(options={'stat': 1})

    print "Optimal parameter values:"
    print "a1: %2.2e (nominal: %2.2e)" % (qt_static.get("a1"), a1_nom)
    print "a2: %2.2e (nominal: %2.2e)" % (qt_static.get("a2"), a2_nom)

    assert N.abs(qt_static.get("a1") - 7.95797110936e-06) < 1e-3
    assert N.abs(qt_static.get("a2") - 7.73425542448e-06) < 1e-3
Example #8
0
def run_demo(with_plots=True):
    """
    Catalyst Mixing model: Determine the optimal mixing policy of two catalysts along 
    the length of a tubular plug flow reactor involving several reactions.
    
    Reference :
    Second-order sensitivities of general dynamic systems with application to optimal control problems. 
    1999, Vassilios S. Vassiliadis, Eva Balsa Canto, Julio R. Banga Case Study 6.2: Catalyst mixing
    """

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

    jmu_name = compile_jmu("JMExamples_opt.CatalystMixing_opt", 
        (os.path.join(curr_dir, 'files', 'JMExamples_opt.mop'), os.path.join(curr_dir, 'files', 'JMExamples.mo')))
    cm = JMUModel(jmu_name)
    
    res = cm.optimize()

    # Extract variable profiles
    x1 = res['x1']
    x2 = res['x2']
    u = res['u']
    t = res['time'] 

    assert N.abs(res.final('x1') - 0.899996) < 1e-5
    assert N.abs(res.final('x2') - 0.051948) < 1e-5
    
    if with_plots:
        plt.figure()
        plt.clf()
        
        plt.subplot(311)
        plt.plot(t,x1)
        plt.grid()
        plt.ylabel('x1')
        plt.xlabel('time')

        plt.subplot(312)
        plt.plot(t,x2)
        plt.grid()
        plt.ylabel('x2')
        plt.xlabel('time')
        
        plt.subplot(313)
        plt.plot(t,u)
        plt.grid()
        plt.ylabel('u')
        plt.xlabel('time')

        plt.show()
Example #9
0
def run_demo(with_plots=True):
    """
    Bang bang optimal control problem.
    
    reference : PROPT - Matlab Optimal Control Software (DAE, ODE)
    """

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

    jmu_name = compile_jmu(
        "JMExamples_opt.BangControl_opt",
        (os.path.join(curr_dir, 'files', 'JMExamples_opt.mop'),
         os.path.join(curr_dir, 'files', 'JMExamples.mo')))
    bc = JMUModel(jmu_name)

    res = bc.optimize()

    # Extract variable profiles
    x1 = res['x1']
    x2 = res['x2']
    u = res['u']
    t = res['time']

    assert N.abs(res.final('x1') - 300.0) < 1e-4
    assert N.abs(res.final('x2') - 0.0) < 1e-4
    assert N.abs(res.final('u') + 2.0) < 1e-4

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

        plt.subplot(311)
        plt.plot(t, x1)
        plt.grid()
        plt.ylabel('x1')
        plt.xlabel('time')

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

        plt.subplot(313)
        plt.plot(t, u)
        plt.grid()
        plt.ylabel('u')
        plt.xlabel('time')

        plt.show()
Example #10
0
def run_demo(with_plots=True):
    """
    Bang bang optimal control problem.
    
    reference : PROPT - Matlab Optimal Control Software (DAE, ODE)
    """

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

    jmu_name = compile_jmu("JMExamples_opt.BangControl_opt", 
    (os.path.join(curr_dir, 'files', 'JMExamples_opt.mop'), os.path.join(curr_dir, 'files', 'JMExamples.mo')))
    bc = JMUModel(jmu_name)
    
    res = bc.optimize()

    # Extract variable profiles
    x1 = res['x1']
    x2 = res['x2']
    u  = res['u']
    t  = res['time']
    
    assert N.abs(res.final('x1') - 300.0) < 1e-4
    assert N.abs(res.final('x2') - 0.0)   < 1e-4
    assert N.abs(res.final('u')  + 2.0)   < 1e-4
    
    if with_plots:
        plt.figure(1)
        plt.clf()
        
        plt.subplot(311)
        plt.plot(t,x1)
        plt.grid()
        plt.ylabel('x1')
        plt.xlabel('time')

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

        plt.subplot(313)
        plt.plot(t,u)
        plt.grid()
        plt.ylabel('u')
        plt.xlabel('time')

        plt.show()
Example #11
0
def run_simulation_with_inputs(time, price, pv, bldg, plot = False):
    """
    This function runs a simulation that uses inputs data series
    """
    
    # get current directory
    curr_dir = os.path.dirname(os.path.abspath(__file__));
    
    # compile FMU
    path = os.path.join(curr_dir,"..","Models","ElectricalNetwork.mop")
    jmu_model = compile_jmu('ElectricNetwork.Network', path)

    # Load the model instance into Python
    model = JMUModel(jmu_model)
    
    # create input data series for price and current battery
    Npoints = len(time)
    
    # for the simulation no current flow
    Ibatt  = np.zeros(Npoints)
    
    # Build input trajectory matrix for use in simulation
    u = np.transpose(np.vstack((t_data, Ibatt, price, np.squeeze(pv[:,0]), np.squeeze(pv[:,1]), \
                                np.squeeze(pv[:,2]), np.squeeze(bldg[:,0]), np.squeeze(bldg[:,1]), np.squeeze(bldg[:,2]))))
    
    # Solve the DAE initialization system
    model.initialize()
    
    # Simulate
    res = model.simulate(input=(['Ibatt', 'price', 'pv1', 'pv2', 'pv3', 'bldg1', 'bldg2', 'bldg3'], u), start_time=0., final_time=24.0*3600.0)
    
    # Extract variable profiles
    Vs_init_sim = res['Vs']
    V1_init_sim = res['V1']
    V2_init_sim = res['V2']
    V3_init_sim = res['V3']
    E_init_sim = res['E']
    SOC_init_sim = res['SOC']
    Money_init_sim = res['Money']
    price_init_sim = res['price']
    t_init_sim = res['time']
    
    # plot results
    if plot:
        plotFunction(t_init_sim, Vs_init_sim, V1_init_sim, V2_init_sim, \
                 V3_init_sim, E_init_sim, SOC_init_sim, Money_init_sim, price_init_sim)
    
    return res
def run_demo(with_plots=True):
    """
    Demonstrate how to solve a minimum time dynamic optimization problem based 
    on a Van der Pol oscillator system.
    """

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

    jmu_name = compile_jmu("JMExamples_opt.VDP_Opt_Min_Time", 
    (curr_dir+"/files/JMExamples_opt.mop",curr_dir+"/files/JMExamples.mo"))
    vdp = JMUModel(jmu_name)
    
    opts = vdp.optimize_options()
    
    opts["result_mode"] = "element_interpolation"
    
    res = vdp.optimize(options=opts)
    
    # Extract variable profiles
    x1 = res['x1']
    x2 = res['x2']
    u = res['u']
    tf = res['finalTime']
    t = res['time']
    
    assert N.abs(res.final('finalTime') - 2.2811587) < 1e-3
    
    if with_plots:
        # Plot
        plt.figure(1)
        plt.clf()
        plt.subplot(311)
        plt.plot(t,x1)
        plt.grid()
        plt.ylabel('x1')
        
        plt.subplot(312)
        plt.plot(t,x2)
        plt.grid()
        plt.ylabel('x2')
        
        plt.subplot(313)
        plt.plot(t,u,'x-')
        plt.grid()
        plt.ylabel('u')
        plt.xlabel('time')
        plt.show()
Example #13
0
def run_simulation_with_inputs(time, price, pv, bldg, plot=False, usePV=True):
    """
    This function runs a simulation that uses inputs data series
    """

    # get current directory
    curr_dir = os.path.dirname(os.path.abspath(__file__))

    # compile FMU
    path = os.path.join(curr_dir, "..", "Models", "ElectricalNetwork.mop")
    jmu_model = compile_jmu('ElectricNetwork.ACnetwork', path)

    # Load the model instance into Python
    model = JMUModel(jmu_model)

    # create input data series for price and current battery
    Npoints = len(time)

    # for the simulation no power flow in the battery
    P = np.zeros(Npoints)
    Q = np.zeros(Npoints)

    # if pv panels are not used then remove power
    if usePV == False:
        pv = np.zeros(np.shape(pv))

    # Build input trajectory matrix for use in simulation
    u = np.transpose(np.vstack((t_data, P, Q, price, -np.squeeze(bldg[:,0]), -np.squeeze(bldg[:,1]), -np.squeeze(bldg[:,2]), \
                                np.squeeze(pv[:,0]), np.squeeze(pv[:,1]), np.squeeze(pv[:,2]))))

    # Solve the DAE initialization system
    model.initialize()

    # Simulate
    res = model.simulate(input=([
        'P_batt', 'Q_batt', 'price', 'P_bldg1', 'P_bldg2', 'P_bldg3', 'P_pv1',
        'P_pv2', 'P_pv3'
    ], u),
                         start_time=0.,
                         final_time=24.0 * 3600.0)

    # Extract variable profiles
    if plot:
        plotFunction(res)

    return res
Example #14
0
def run_demo(with_plots=True):
    """
    This example demonstrates how to solve optimization problems with a Lagrange 
    cost term encoded using the Optimica attribute objectiveIntegrand.
    """

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

    n_e = 50  # Number of elements
    hs = N.ones(n_e) * 1. / n_e  # Equidistant point
    n_cp = 3  # Number of collocation points
    b_f = 3 * N.ones(10)  # Blocking factors

    jmu_name = compile_jmu("LagrangeCost.OptTest",
                           curr_dir + "/files/LagrangeCost.mop")
    model = JMUModel(jmu_name)
    res = model.optimize(options={
        'n_e': n_e,
        'hs': hs,
        'n_cp': n_cp,
        'blocking_factors': b_f
    })

    x1 = res['sys.x[1]']
    x2 = res['sys.x[2]']
    u = res['sys.u']
    t = res['time']

    assert N.abs(res.final('sys.x[1]') - 0.20172085497700001) < 1e-3

    if with_plots:
        plt.figure(1)
        plt.clf()
        plt.subplot(211)
        plt.plot(t, x1)
        plt.hold(True)
        plt.ylabel('x[1], x[2]')
        plt.plot(t, x2)
        plt.grid(True)
        plt.subplot(212)
        plt.plot(t, u)
        plt.ylabel('u')
        plt.xlabel('t[s]')
        plt.grid(True)
        plt.show()
def run_demo(with_plots=True):
    """
    Static calibration of the quad tank model.
    """

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

    jmu_name = compile_jmu("QuadTank_pack.QuadTank_Static", curr_dir + "/files/QuadTank.mop")

    # Load static calibration model
    qt_static = JMUModel(jmu_name)

    # Set control inputs
    qt_static.set("u1", 2.5)
    qt_static.set("u2", 2.5)

    # Save nominal values
    a1_nom = qt_static.get("a1")
    a2_nom = qt_static.get("a2")

    init_res = qt_static.initialize(options={"stat": 1})

    print "Optimal parameter values:"
    print "a1: %2.2e (nominal: %2.2e)" % (qt_static.get("a1"), a1_nom)
    print "a2: %2.2e (nominal: %2.2e)" % (qt_static.get("a2"), a2_nom)

    assert N.abs(qt_static.get("a1") - 7.95797110936e-06) < 1e-3
    assert N.abs(qt_static.get("a2") - 7.73425542448e-06) < 1e-3
Example #16
0
def run_demo(with_plots=True):
    """
    An example on how to simulate a model using the DAE simulator. The result 
    can be compared with that of sim_rlc.py which has solved the same problem 
    using dymola. Also writes information to a file.
    """

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

    model_name = 'RLC_Circuit'
    mofile = curr_dir+'/files/RLC_Circuit.mo'
    
    jmu_name = compile_jmu(model_name, mofile)
    model = JMUModel(jmu_name)
    init_res = model.initialize()

    (E_dae,A_dae,B_dae,F_dae,g_dae,state_names,input_names,algebraic_names, \
     dx0,x0,u0,w0,t0) = linearize_dae(init_res.model)
    
    (A_ode,B_ode,g_ode,H_ode,M_ode,q_ode) = linear_dae_to_ode(
        E_dae,A_dae,B_dae,F_dae,g_dae)

    res1 = model.simulate()
    
    jmu_name = compile_jmu("RLC_Circuit_Linearized",mofile)
    lin_model = JMUModel(jmu_name)
    res2 = lin_model.simulate()
    
    c_v_1 = res1['capacitor.v']
    i_p_i_1 = res1['inductor.p.i']
    i_p1_i_1 = res1['inductor1.p.i']
    t_1 = res1['time']
    
    c_v_2 = res2['x[1]']
    i_p_i_2 = res2['x[2]']
    i_p1_i_2 = res2['x[3]']
    t_2 = res2['time']

    assert N.abs(res1.final('capacitor.v') - res2.final('x[1]')) < 1e-3
    
    if with_plots:
        p.figure(1)
        p.hold(True)
        p.subplot(311)
        p.plot(t_1,c_v_1)
        p.plot(t_2,c_v_2,'g')
        p.ylabel('c.v')
        p.legend(('original model','linearized ODE'))
        p.grid()
        p.subplot(312)
        p.plot(t_1,i_p_i_1)
        p.plot(t_2,i_p_i_2,'g')
        p.ylabel('i.p.i')
        p.grid()
        p.subplot(313)
        p.plot(t_1,i_p1_i_1)
        p.plot(t_2,i_p1_i_2,'g')
        p.ylabel('i.p1.i')
        p.grid()
        p.show()
Example #17
0
def run_demo(with_plots=True):
    """
    The model describes a minimum time control problem with coloumb friction.
    """

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

    jmu_name1 = compile_jmu("JMExamples_opt.ColoumbFriction_opt", 
        (os.path.join(curr_dir, 'files', 'JMExamples_opt.mop'), os.path.join(curr_dir, 'files', 'JMExamples.mo')))
    cf = JMUModel(jmu_name1)
    res = cf.optimize()
    
    # Extract variable profiles
    q =res['q']
    dq=res['dq']
    u =res['u'] 
    t =res['time']

    assert N.abs(res.final('q') + 1.0) < 1e-4
    assert N.abs(res.final('dq') - 0.0) < 1e-4

    if with_plots:
        plt.figure(1)
        plt.clf()
        
        plt.subplot(311)
        plt.plot(t,q)
        plt.grid()
        plt.ylabel('q')
        plt.xlabel('time')

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

        plt.subplot(313)
        plt.plot(t,u)
        plt.grid()
        plt.ylabel('u')
        plt.xlabel('time')
        
        plt.show()
Example #18
0
def run_demo(with_plots=True):
    """
    Demonstrate how to solve a dynamic optimization problem based on a Van der 
    Pol oscillator system.
    """

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

    jmu_name = compile_jmu("JMExamples_opt.VDP_Opt",
                           (curr_dir + "/files/JMExamples_opt.mop",
                            curr_dir + "/files/JMExamples.mo"))
    vdp = JMUModel(jmu_name)

    res = vdp.optimize()

    # Extract variable profiles
    x1 = res['x1']
    x2 = res['x2']
    u = res['u']
    t = res['time']
    cost = res['cost']

    assert N.abs(res.final('cost') - 2.3469089e+01) < 1e-3

    if with_plots:
        # Plot
        plt.figure(1)
        plt.clf()
        plt.subplot(311)
        plt.plot(t, x1)
        plt.grid()
        plt.ylabel('x1')

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

        plt.subplot(313)
        plt.plot(t, u)
        plt.grid()
        plt.ylabel('u')
        plt.xlabel('time')
        plt.show()
Example #19
0
def run_demo(with_plots=True):
    """
    Demonstrate how to solve a dynamic optimization problem based on a Van der 
    Pol oscillator system.
    """

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

    jmu_name = compile_jmu("JMExamples_opt.VDP_Opt", 
    (curr_dir+"/files/JMExamples_opt.mop",curr_dir+"/files/JMExamples.mo"))
    vdp = JMUModel(jmu_name)
    
    res = vdp.optimize()

    # Extract variable profiles
    x1 = res['x1']
    x2 = res['x2']
    u = res['u']
    t = res['time']
    cost = res['cost']
    
    assert N.abs(res.final('cost') - 2.3469089e+01) < 1e-3

    if with_plots:
        # Plot
        plt.figure(1)
        plt.clf()
        plt.subplot(311)
        plt.plot(t,x1)
        plt.grid()
        plt.ylabel('x1')
        
        plt.subplot(312)
        plt.plot(t,x2)
        plt.grid()
        plt.ylabel('x2')
        
        plt.subplot(313)
        plt.plot(t,u)
        plt.grid()
        plt.ylabel('u')
        plt.xlabel('time')
        plt.show()
Example #20
0
def run_demo(with_plots=True):
    """
    This example demonstrates how to solve optimization problems with a Lagrange 
    cost term encoded using the Optimica attribute objectiveIntegrand.
    """

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

    n_e = 50                  # Number of elements
    hs = N.ones(n_e)*1./n_e   # Equidistant point
    n_cp = 3                  # Number of collocation points
    b_f = 3*N.ones(10)        # Blocking factors

    jmu_name = compile_jmu("LagrangeCost.OptTest", 
        curr_dir+"/files/LagrangeCost.mop")
    model = JMUModel(jmu_name)
    res = model.optimize(
        options={'n_e':n_e,'hs':hs,'n_cp':n_cp,'blocking_factors':b_f})

    x1 = res['sys.x[1]']
    x2 = res['sys.x[2]']
    u = res['sys.u']
    t = res['time']

    assert N.abs(res.final('sys.x[1]') - 0.20172085497700001) < 1e-3  

    if with_plots:
        plt.figure(1)
        plt.clf()
        plt.subplot(211)
        plt.plot(t,x1)
        plt.hold(True)
        plt.ylabel('x[1], x[2]')
        plt.plot(t,x2)
        plt.grid(True)
        plt.subplot(212)
        plt.plot(t,u)
        plt.ylabel('u')
        plt.xlabel('t[s]')
        plt.grid(True)
        plt.show()
Example #21
0
def run_simulation_with_inputs(time, price, pv, bldg, plot = False, usePV = True):
    """
    This function runs a simulation that uses inputs data series
    """
    
    # get current directory
    curr_dir = os.path.dirname(os.path.abspath(__file__));
    
    # compile FMU
    path = os.path.join(curr_dir,"..","Models","ElectricalNetwork.mop")
    jmu_model = compile_jmu('ElectricNetwork.ACnetwork', path)

    # Load the model instance into Python
    model = JMUModel(jmu_model)
    
    # create input data series for price and current battery
    Npoints = len(time)
    
    # for the simulation no power flow in the battery
    P  = np.zeros(Npoints)
    Q  = np.zeros(Npoints)
    
    # if pv panels are not used then remove power
    if usePV == False:
        pv = np.zeros(np.shape(pv))
    
    # Build input trajectory matrix for use in simulation
    u = np.transpose(np.vstack((t_data, P, Q, price, -np.squeeze(bldg[:,0]), -np.squeeze(bldg[:,1]), -np.squeeze(bldg[:,2]), \
                                np.squeeze(pv[:,0]), np.squeeze(pv[:,1]), np.squeeze(pv[:,2]))))
    
    # Solve the DAE initialization system
    model.initialize()
    
    # Simulate
    res = model.simulate(input=(['P_batt', 'Q_batt', 'price', 'P_bldg1', 'P_bldg2', 'P_bldg3', 'P_pv1', 'P_pv2', 'P_pv3'], u), start_time=0., final_time=24.0*3600.0)
    
    # Extract variable profiles
    if plot:
        plotFunction(res)
        
    return res
Example #22
0
def run_simulation(plot = False):
    """
    This function runs a simple simulation without input data
    """
    
    # get current directory
    curr_dir = os.path.dirname(os.path.abspath(__file__));
    
    # compile FMU
    path = os.path.join(curr_dir,"..","Models","ElectricalNetwork.mop")
    jmu_model = compile_jmu('ElectricNetwork.NetworkSim', path)

    # Load the model instance into Python
    model = JMUModel(jmu_model)
  
    # Solve the DAE initialization system
    model.initialize()
    
    # Simulate
    res = model.simulate(start_time=0., final_time=24.0*3600.0)
    
    # Extract variable profiles
    Vs_init_sim = res['n.Vs']
    V1_init_sim = res['n.V1']
    V2_init_sim = res['n.V2']
    V3_init_sim = res['n.V3']
    E_init_sim = res['n.E']
    SOC_init_sim = res['n.SOC']
    Money_init_sim = res['n.Money']
    price_init_sim = res['n.price']
    t_init_sim = res['time']
    
    # plot results
    if plot:
        plotFunction(t_init_sim, Vs_init_sim, V1_init_sim, V2_init_sim, \
                 V3_init_sim, E_init_sim, SOC_init_sim, Money_init_sim, price_init_sim)
Example #23
0
def run_simulation(plot=False):
    """
    This function runs a simple simulation without input data
    """

    # get current directory
    curr_dir = os.path.dirname(os.path.abspath(__file__))

    # compile FMU
    path = os.path.join(curr_dir, "..", "Models", "ElectricalNetwork.mop")
    jmu_model = compile_jmu('ElectricNetwork.NetworkSim', path)

    # Load the model instance into Python
    model = JMUModel(jmu_model)

    # Solve the DAE initialization system
    model.initialize()

    # Simulate
    res = model.simulate(start_time=0., final_time=24.0 * 3600.0)

    # Extract variable profiles
    Vs_init_sim = res['n.Vs']
    V1_init_sim = res['n.V1']
    V2_init_sim = res['n.V2']
    V3_init_sim = res['n.V3']
    E_init_sim = res['n.E']
    SOC_init_sim = res['n.SOC']
    Money_init_sim = res['n.Money']
    price_init_sim = res['n.price']
    t_init_sim = res['time']

    # plot results
    if plot:
        plotFunction(t_init_sim, Vs_init_sim, V1_init_sim, V2_init_sim, \
                 V3_init_sim, E_init_sim, SOC_init_sim, Money_init_sim, price_init_sim)
Example #24
0
def run_demo(with_plots=True):
    """
    Distillation4 optimization model
    """

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

    # Compile the stationary initialization model into a JMU
    jmu_name = compile_jmu("JMExamples.Distillation.Distillation1Input_init",
                           curr_dir + "/files/JMExamples.mo")

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

    # Set inputs for Stationary point A
    rr_0_A = 3.0
    init_model.set('rr', rr_0_A)
    init_result = init_model.initialize()

    # 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(32):
        y_A[i] = init_result['y[' + str(i + 1) + ']'][0]
        x_A[i] = init_result['x[' + str(i + 1) + ']'][0]
        print '(' + str(i + 1) + ', %f, %f)' % (x_A[i], y_A[i])

    # Set inputs for stationary point B
    rr_0_B = 2.0
    init_model.set('rr', rr_0_B)
    init_result = init_model.initialize()

    # 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(32):
        y_B[i] = init_result['y[' + str(i + 1) + ']'][0]
        x_B[i] = init_result['x[' + str(i + 1) + ']'][0]
        print '(' + str(i + 1) + ', %f, %f)' % (x_B[i], y_B[i])

    # Set up and solve the simulation problem.

    fmu_name1 = compile_fmu("JMExamples.Distillation.Distillation1Inputstep",
                            curr_dir + "/files/JMExamples.mo")
    dist1 = load_fmu(fmu_name1)

    # Initialize the model with parameters

    # Initialize the model to stationary point A
    for i in range(32):
        dist1.set('x_init[' + str(i + 1) + ']', x_A[i])

    res = dist1.simulate(final_time=50)

    # Extract variable profiles
    x1 = res['x[1]']
    x8 = res['x[8]']
    x16 = res['x[16]']
    x24 = res['x[24]']
    x32 = res['x[32]']
    y1 = res['y[1]']
    y8 = res['y[8]']
    y16 = res['y[16]']
    y24 = res['y[24]']
    y32 = res['y[32]']
    t = res['time']
    rr = res['rr']

    print "t = ", repr(N.array(t))
    print "x1 = ", repr(N.array(x1))
    print "x8 = ", repr(N.array(x8))
    print "x16 = ", repr(N.array(x16))
    print "x32 = ", repr(N.array(x32))

    if with_plots:
        # Plot
        plt.figure()
        plt.subplot(1, 3, 1)
        plt.plot(t, x16, t, x32, t, x1, t, x8, t, x24)
        plt.title('Liquid composition')
        plt.grid(True)
        plt.ylabel('x')
        plt.subplot(1, 3, 2)
        plt.plot(t, y16, t, y32, t, y1, t, y8, t, y24)
        plt.title('Vapor composition')
        plt.grid(True)
        plt.ylabel('y')
        plt.subplot(1, 3, 3)
        plt.plot(t, rr)
        plt.title('Reflux ratio')
        plt.grid(True)
        plt.ylabel('rr')

        plt.xlabel('time')
        plt.show()
Example #25
0
def run_demo(with_plots=True):
    """
    Optimal control of the quadruple tank process.
    """
    curr_dir = os.path.dirname(os.path.abspath(__file__))

    # Compile the Optimica model to JMU
    jmu_name = compile_jmu("QuadTank_pack.QuadTank_Opt",
                           curr_dir + "/files/QuadTank.mop")

    # Load the dynamic library and XML data
    qt = JMUModel(jmu_name)

    # 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.real_x[i + 1] = y[i]
        qt.jmimodel.ode_f()
        return qt.real_dx[1:5]

    # Compute stationary state values for operating point A
    qt.real_u = u_A

    t_sim = N.linspace(0., 2000., 500)
    y_sim = integr.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.real_u = u_B

    t_sim = N.linspace(0., 2000., 500)
    y_sim = integr.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.set("x1_0", x_A[0])
    qt.set("x2_0", x_A[1])
    qt.set("x3_0", x_A[2])
    qt.set("x4_0", x_A[3])

    qt.set("x1_r", x_B[0])
    qt.set("x2_r", x_B[1])
    qt.set("x3_r", x_B[2])
    qt.set("x4_r", x_B[3])

    qt.set("u1_r", u_B[0])
    qt.set("u2_r", u_B[1])

    # Solve optimal control problem
    res = qt.optimize(options={'IPOPT_options': {'max_iter': 500}})

    # Extract variable profiles
    x1 = res['x1']
    x2 = res['x2']
    x3 = res['x3']
    x4 = res['x4']
    u1 = res['u1']
    u2 = res['u2']
    t = res['time']

    assert N.abs(res.final('cost') - 5.0333257e+02) < 1e-3

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

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

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

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

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

        plt.subplot(212)
        plt.plot(t, u2)
        plt.grid()
        plt.ylabel('u2')
Example #26
0
def run_demo(with_plots=True):
    """
    Demonstrate how to solve a simple parameter estimation problem 
    in form of a model of catalytic cracking of gas oil.
    
    Reference:
    Benchmarking Optimization Software with COPS 
    Elizabeth D. Dolan and Jorge J. More ARGONNE NATIONAL LABORATORY
    """

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

    # Compile the Optimica model to a JMU
    jmu_name = compile_jmu(
        "JMExamples_opt.CatalyticCracking_opt",
        (os.path.join(curr_dir, 'files', 'JMExamples_opt.mop'),
         os.path.join(curr_dir, 'files', 'JMExamples.mo')))

    # Load the dynamic library
    cc = JMUModel(jmu_name)

    # optimize
    opts = cc.optimize_options()
    opts['n_e'] = 20
    res = cc.optimize(options=opts)

    # Extract variable profiles
    y1 = res['sys.y1']
    y2 = res['sys.y2']
    theta1 = res['sys.theta1']
    theta2 = res['sys.theta2']
    theta3 = res['sys.theta3']
    t = res['time']

    y1m = [
        1, 0.8105, 0.6208, 0.5258, 0.4345, 0.3903, 0.3342, 0.3034, 0.2735,
        0.2405, 0.2283, 0.2071, 0.1669, 0.1530, 0.1339, 0.1265, 0.1200, 0.0990,
        0.0870, 0.077, 0.069
    ]
    y2m = [
        0, 0.2, 0.2886, 0.301, 0.3215, 0.3123, 0.2716, 0.2551, 0.2258, 0.1959,
        0.1789, 0.1457, 0.1198, 0.0909, 0.0719, 0.0561, 0.0460, 0.0280, 0.0190,
        0.0140, 0.01
    ]
    tm = [
        0, 0.025, 0.05, 0.075, 0.1, 0.125, 0.15, 0.175, 0.2, 0.225, 0.25, 0.3,
        0.35, 0.4, 0.45, 0.5, 0.55, 0.65, 0.75, 0.85, 0.95
    ]

    assert N.abs(res.final('sys.theta1') - 11.835148) < 1e-5
    assert N.abs(res.final('sys.theta2') - 8.338887) < 1e-5
    assert N.abs(res.final('sys.theta3') - 1.007536) < 1e-5

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

        plt.subplot(211)
        plt.plot(t, y1, tm, y1m, 'x')
        plt.grid()
        plt.ylabel('y1')
        plt.xlabel('time')

        plt.subplot(212)
        plt.plot(t, y2, tm, y2m, 'x')
        plt.grid()
        plt.ylabel('y2')
        plt.xlabel('time')

        plt.show()

        print("\n** Optimal parameter values: **")
        print("theta1 = %f" % res.final('sys.theta1'))
        print("theta2 = %f" % res.final('sys.theta2'))
        print("theta3 = %f" % res.final('sys.theta3'))
Example #27
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}
    }
    
    Note: This example requires Ipopt with MA27.
    """
    
    curr_dir = os.path.dirname(os.path.abspath(__file__));

    # Compile the stationary initialization model into a JMU
    jmu_name = compile_jmu("JMExamples.Distillation.Distillation1Input_init", 
    curr_dir+"/files/JMExamples.mo")

    # Load a model instance into Python
    init_model = JMUModel(jmu_name)
    
    # Set inputs for Stationary point A
    rr_0_A = 3.0
    init_model.set('rr',rr_0_A)
    init_result = init_model.initialize()
    	
    # 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(32):
        y_A[i] = init_result['y['+ str(i+1) +']'][0]
        x_A[i] = init_result['x['+ str(i+1) +']'][0]
        print '(' + str(i+1) + ', %f, %f)' %(x_A[i], y_A[i])
    
    # Set inputs for stationary point B
    rr_0_B = 2.0
    init_model.set('rr',rr_0_B)
    init_result = init_model.initialize()

    # 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(32):
        y_B[i] = init_result['y[' + str(i+1) + ']'][0]
        x_B[i] = init_result['x[' + str(i+1) + ']'][0]
        print '(' + str(i+1) + ', %f, %f)' %(x_B[i], y_B[i])

    # Set up and solve an optimal control problem. 

    # Compile the JMU
    jmu_name = compile_jmu("JMExamples_opt.Distillation1_opt", 
    (curr_dir+"/files/JMExamples.mo",curr_dir+"/files/JMExamples_opt.mop"), 
        compiler_options={'state_start_values_fixed':True}) 

    # Load the dynamic library and XML data
    model = JMUModel(jmu_name)

    # Initialize the model with parameters

    # Initialize the model to stationary point A
    for i in range(32):
        model.set('x_init[' + str(i+1) + ']', x_A[i])

    # Set the target values to stationary point B
    model.set('rr_ref',rr_0_B)
    model.set('x1_ref',x_B[0])

    # Solve the optimization problem
    opts = model.optimize_options()
    opts['hs'] = N.ones(100)*1./100  # Equidistant points
    opts['n_e'] = 100                # Number of elements
    opts['n_cp'] = 3                 # Number of collocation points in each element
    opt_res = model.optimize()

    # Extract variable profiles
    x1  = opt_res['x[1]']
    x8  = opt_res['x[8]']
    x16 = opt_res['x[16]']
    x24 = opt_res['x[24]']
    x32 = opt_res['x[32]']
    y1  = opt_res['y[1]']
    y8  = opt_res['y[8]']
    y16 = opt_res['y[16]']
    y24 = opt_res['y[24]']
    y32 = opt_res['y[32]']
    t   = opt_res['time']
    rr  = opt_res['rr']
    
    assert N.abs(opt_res.final('rr') - 2.0) < 1e-3
    
    # Plot the results
    if with_plots:
        plt.figure()
        plt.subplot(1,2,1)
        plt.plot(t,x16,t,x32,t,x1,t,x8,t,x24)
        plt.title('Liquid composition')
        plt.grid(True)
        plt.ylabel('x')
        plt.subplot(1,2,2)
        plt.plot(t,y16,t,y32,t,y1,t,y8,t,y24)
        plt.title('Vapor composition')
        plt.grid(True)
        plt.ylabel('y')
        
        plt.xlabel('time')
        plt.show()        
        
        plt.figure(3)
        plt.clf()
        plt.hold(True)
        plt.plot(t,rr)
        plt.ylabel('rr')
        plt.xlabel('t [s]')
        plt.title('Reflux ratio')

        plt.show()
Example #28
0
def run_demo(with_plots=True, with_blocking_factors = False):
    """ 
    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}
    }
    
    Note: This example requires Ipopt with MA27.
    """
    
    curr_dir = os.path.dirname(os.path.abspath(__file__));

    # Compile the stationary initialization model into a JMU
    jmu_name = compile_jmu("DISTLib.Binary_Dist_initial", 
        curr_dir+"/files/DISTLib.mo")

    # Load a model instance into Python
    init_model = JMUModel(jmu_name)
    
    # Set inputs for Stationary point A
    rr_0_A = 3.0
    init_model.set('rr',rr_0_A)
    init_result = init_model.initialize()
    
    # 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('y['+ str(i+1) +']')
        x_A[i] = init_model.get('x['+ str(i+1) +']')
        print '(' + str(i+1) + ', %f, %f)' %(x_A[i], y_A[i])
    
    # Set inputs for stationary point B
    rr_0_B = 2.0
    init_model.set('rr',rr_0_B)
    init_result = init_model.initialize()

    # 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('y[' + str(i+1) + ']')
        x_B[i] = init_model.get('x[' + str(i+1) + ']')
        print '(' + str(i+1) + ', %f, %f)' %(x_B[i], y_B[i])

    # Set up and solve an optimal control problem. 

    # Compile the JMU
    jmu_name = compile_jmu("DISTLib_Opt.Binary_Dist_Opt1", 
        (curr_dir+"/files/DISTLib.mo",curr_dir+"/files/DISTLib_Opt.mop"), 
        compiler_options={'state_start_values_fixed':True})

    # Load the dynamic library and XML data
    model = JMUModel(jmu_name)

    # Initialize the model with parameters

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

    # Set the target values to stationary point B
    model.set('rr_ref',rr_0_B)
    model.set('y1_ref',y_B[0])

    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

    # Solve the optimization problem
    if with_blocking_factors:
        # Blocking factors for control parametrization
        blocking_factors=4*N.ones(n_e/4,dtype=N.int)
        
        opt_opts = model.optimize_options()
        opt_opts['n_e'] = n_e
        opt_opts['n_cp'] = n_cp
        opt_opts['hs'] = hs
        opt_opts['blocking_factors'] = blocking_factors
        
        opt_res = model.optimize(options=opt_opts)
    else:
        opt_res = model.optimize(options={'n_e':n_e, 'n_cp':n_cp, 'hs':hs})

    # Extract variable profiles
    u1_res     = opt_res['rr']
    u1_ref_res = opt_res['rr_ref']
    y1_ref_res = opt_res['y1_ref']
    time       = opt_res['time']
    
    x_res = []
    x_ref_res = []
    for i in range(N.size(x_B)):
        x_res.append(opt_res['x[' + str(i+1) + ']'])

    y_res = []
    for i in range(N.size(x_B)):
        y_res.append(opt_res['y[' + str(i+1) + ']'])
        
    
    if with_blocking_factors:
        assert N.abs(opt_res.final('cost')/1.e1 - 2.8549683) < 1e-3
    else:
        assert N.abs(opt_res.final('cost')/1.e1 - 2.8527469) < 1e-3

    # Plot the results
    if with_plots:
        plt.figure(1)
        plt.clf()
        plt.hold(True)
        plt.subplot(311)
        plt.title('Liquid composition')
        plt.plot(time, x_res[0])
        plt.ylabel('x1')
        plt.grid()
        plt.subplot(312)
        plt.plot(time, x_res[16])
        plt.ylabel('x17')
        plt.grid()
        plt.subplot(313)
        plt.plot(time, x_res[31])
        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(time, y_res[0])
        plt.plot(time, y1_ref_res, '--')
        plt.ylabel('y1')
        plt.grid()
        plt.subplot(312)
        plt.plot(time, y_res[16])
        plt.ylabel('y17')
        plt.grid()
        plt.subplot(313)
        plt.plot(time, y_res[31])
        plt.ylabel('y32')
        plt.grid()
        plt.xlabel('t [s]')
        plt.show()
        
        
        plt.figure(3)
        plt.clf()
        plt.hold(True)
        plt.plot(time, u1_res)
        plt.ylabel('u')
        plt.plot(time, u1_ref_res, '--')
        plt.xlabel('t [s]')
        plt.title('Reflux ratio')
        plt.grid()
        plt.show()
Example #29
0
def run_demo(with_plots=True):
    """
    Optimal control of the quadruple tank process.
    """
    curr_dir = os.path.dirname(os.path.abspath(__file__));
    
    # Compile the Optimica model to JMU
    jmu_name = compile_jmu("QuadTank_pack.QuadTank_Opt", 
        curr_dir+"/files/QuadTank.mop")

    # Load the dynamic library and XML data
    qt = JMUModel(jmu_name)

    # 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.real_x[i+1] = y[i]
        qt.jmimodel.ode_f()
        return qt.real_dx[1:5]

    # Compute stationary state values for operating point A
    qt.real_u = u_A
    
    t_sim = N.linspace(0.,2000.,500)
    y_sim = integr.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.real_u = u_B
    
    t_sim = N.linspace(0.,2000.,500)
    y_sim = integr.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.set("x1_0",x_A[0])
    qt.set("x2_0",x_A[1])
    qt.set("x3_0",x_A[2])
    qt.set("x4_0",x_A[3])

    qt.set("x1_r",x_B[0])
    qt.set("x2_r",x_B[1])
    qt.set("x3_r",x_B[2])
    qt.set("x4_r",x_B[3])

    qt.set("u1_r",u_B[0])
    qt.set("u2_r",u_B[1])

    # Solve optimal control problem
    res = qt.optimize(options={'IPOPT_options':{'max_iter':500}})

    # Extract variable profiles
    x1=res['x1']
    x2=res['x2']
    x3=res['x3']
    x4=res['x4']
    u1=res['u1']
    u2=res['u2']
    t =res['time']

    assert N.abs(res.final('cost') - 5.0333257e+02) < 1e-3
    
    if with_plots:
        # Plot
        plt.figure(2)
        plt.clf()
        plt.subplot(411)
        plt.plot(t,x1)
        plt.grid()
        plt.ylabel('x1')
        
        plt.subplot(412)
        plt.plot(t,x2)
        plt.grid()
        plt.ylabel('x2')
        
        plt.subplot(413)
        plt.plot(t,x3)
        plt.grid()
        plt.ylabel('x3')
        
        plt.subplot(414)
        plt.plot(t,x4)
        plt.grid()
        plt.ylabel('x4')
        plt.show()
        
        plt.figure(3)
        plt.clf()
        plt.subplot(211)
        plt.plot(t,u1)
        plt.grid()
        plt.ylabel('u1')
        
        plt.subplot(212)
        plt.plot(t,u2)
        plt.grid()
        plt.ylabel('u2')
Example #30
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 #31
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__))

    # Compile the stationary initialization model into a DLL
    jmu_name = compile_jmu("CSTRLib.Components.Two_CSTRs_stat_init",
                           os.path.join(curr_dir, "files", "CSTRLib.mo"))

    # Load a JMU model instance
    init_model = JMUModel(jmu_name)

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

    # Solve the DAE initialization system with Ipopt
    init_result = init_model.initialize()

    # Store stationary point A
    CA1_0_A = init_model.get('CA1')
    CA2_0_A = init_model.get('CA2')
    T1_0_A = init_model.get('T1')
    T2_0_A = init_model.get('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('u1', u1_0_B)
    init_model.set('u2', u2_0_B)

    # Solve the DAE initialization system with Ipopt
    init_result = init_model.initialize()

    # Stationary point B
    CA1_0_B = init_model.get('CA1')
    CA2_0_B = init_model.get('CA2')
    T1_0_B = init_model.get('T1')
    T2_0_B = init_model.get('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.

    # Compile the Model
    jmu_name = compile_jmu("CSTR2_Opt", [
        os.path.join(curr_dir, "files", "CSTRLib.mo"),
        os.path.join(curr_dir, "files", "CSTR2_Opt.mop")
    ],
                           compiler_options={
                               'enable_variable_scaling': True,
                               'index_reduction': True
                           })

    # Load the dynamic library and XML data
    model = JMUModel(jmu_name)

    # Initialize the model with parameters

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

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

    # 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

    res = model.optimize(
        options={
            'n_e': n_e,
            'hs': hs,
            'n_cp': n_cp,
            'blocking_factors': 2 * N.ones(n_e / 2, dtype=N.int),
            'IPOPT_options': {
                'tol': 1e-4
            }
        })

    # Extract variable profiles
    CA1_res = res['cstr.two_CSTRs_Series.CA1']
    CA2_res = res['cstr.two_CSTRs_Series.CA2']
    T1_res = res['cstr.two_CSTRs_Series.T1']
    T2_res = res['cstr.two_CSTRs_Series.T2']
    u1_res = res['cstr.two_CSTRs_Series.u1']
    u2_res = res['cstr.two_CSTRs_Series.u2']
    der_u2_res = res['der_u2']

    CA1_ref_res = res['CA1_ref']
    CA2_ref_res = res['CA2_ref']

    u1_ref_res = res['u1_ref']
    u2_ref_res = res['u2_ref']

    cost = res['cost']
    time = res['time']

    assert N.abs(res.final('cost') - 1.4745648e+01) < 1e-3

    # Plot the results
    if with_plots:
        plt.figure(1)
        plt.clf()
        plt.hold(True)
        plt.subplot(211)
        plt.plot(time, CA1_res)
        plt.plot([time[0], time[-1]], [CA1_ref_res, CA1_ref_res], '--')
        plt.ylabel('Concentration reactor 1 [J/l]')
        plt.grid()
        plt.subplot(212)
        plt.plot(time, CA2_res)
        plt.plot([time[0], time[-1]], [CA2_ref_res, CA2_ref_res], '--')
        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(time, T1_res)
        plt.ylabel('Temperature reactor 1 [K]')
        plt.grid()
        plt.subplot(212)
        plt.plot(time, T2_res)
        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(time, u2_res)
        plt.ylabel('Input 2')
        plt.plot([time[0], time[-1]], [u2_ref_res, u2_ref_res], '--')
        plt.grid()
        plt.subplot(212)
        plt.plot(time, der_u2_res)
        plt.ylabel('Derivative of input 2')
        plt.xlabel('t [s]')
        plt.grid()
        plt.show()
Example #32
0
def run_demo(with_plots=True):
    """
    Example about landing an object.
    
    Reference : PROPT - Matlab Optimal Control Software (DAE, ODE)
    """

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

    jmu_name = compile_jmu(
        "JMExamples_opt.MoonLander_opt",
        (os.path.join(curr_dir, "files", "JMExamples_opt.mop"), os.path.join(curr_dir, "files", "JMExamples.mo")),
    )
    ml = JMUModel(jmu_name)

    res = ml.optimize()

    # Extract variable profiles
    h = res["h"]
    v = res["v"]
    m = res["m"]
    u = res["u"]
    t = res["time"]

    assert N.abs(res.final("u") - 0.98270) < 1e-4

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

        plt.subplot(221)
        plt.plot(t, h)
        plt.grid()
        plt.ylabel("h")
        plt.xlabel("time")
        plt.title("height")

        plt.subplot(222)
        plt.plot(t, v)
        plt.grid()
        plt.ylabel("v")
        plt.xlabel("time")
        plt.title("velocity")

        plt.subplot(223)
        plt.plot(t, m)
        plt.grid()
        plt.ylabel("m")
        plt.xlabel("time")
        plt.title("mass")

        plt.subplot(224)
        plt.plot(t, u)
        plt.grid()
        plt.ylabel("u")
        plt.xlabel("time")
        plt.title("thrust")

        plt.show()

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

    jmu_name = compile_jmu(
        "JMExamples_opt.MoonLander_opttime",
        (os.path.join(curr_dir, "files", "JMExamples_opt.mop"), os.path.join(curr_dir, "files", "JMExamples.mo")),
    )
    ml = JMUModel(jmu_name)

    res = ml.optimize()

    # Extract variable profiles
    h = res["h"]
    v = res["v"]
    m = res["m"]
    u = res["u"]
    t = res["time"]

    assert N.abs(res.final("u") - 1.22699) < 1e-4

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

        plt.subplot(221)
        plt.plot(t, h)
        plt.grid()
        plt.ylabel("h")
        plt.xlabel("time")
        plt.title("height")

        plt.subplot(222)
        plt.plot(t, v)
        plt.grid()
        plt.ylabel("v")
        plt.xlabel("time")
        plt.title("velocity")

        plt.subplot(223)
        plt.plot(t, m)
        plt.grid()
        plt.ylabel("m")
        plt.xlabel("time")
        plt.title("mass")

        plt.subplot(224)
        plt.plot(t, u)
        plt.grid()
        plt.ylabel("u")
        plt.xlabel("time")
        plt.title("thrust")

        plt.show()
Example #33
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__))

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

    # load the JMU
    init_model = JMUModel(jmu_name)

    # Set inputs for Stationary point A
    Tc_0_A = 250
    init_model.set('Tc', Tc_0_A)

    # Solve the DAE initialization system with Ipopt
    init_result = init_model.initialize()

    # Store stationary point A
    c_0_A = init_result['c'][0]
    T_0_A = init_result['T'][0]

    # 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('Tc', Tc_0_B)

    # Solve the DAE initialization system with Ipopt
    init_result = init_model.initialize()
    # Store stationary point B
    c_0_B = init_result['c'][0]
    T_0_B = init_result['T'][0]

    # 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
    # Compile the optimization initialization model
    jmu_name = compile_jmu("CSTR.CSTR_Init_Optimization",
                           os.path.join(curr_dir, "files", "CSTR.mop"))

    # Load the model
    init_sim_model = JMUModel(jmu_name)

    # Set model parameters
    init_sim_model.set('cstr.c_init', c_0_A)
    init_sim_model.set('cstr.T_init', T_0_A)
    init_sim_model.set('c_ref', c_0_B)
    init_sim_model.set('T_ref', T_0_B)
    init_sim_model.set('Tc_ref', Tc_0_B)

    res = init_sim_model.simulate(start_time=0., final_time=150.)

    # Extract variable profiles
    c_init_sim = res['cstr.c']
    T_init_sim = res['cstr.T']
    Tc_init_sim = res['cstr.Tc']
    t_init_sim = res['time']

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

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

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

    # Solve the optimal control problem
    # Compile model
    jmu_name = compile_jmu("CSTR.CSTR_Opt", curr_dir + "/files/CSTR.mop")

    # Load model
    cstr = JMUModel(jmu_name)

    # Set reference values
    cstr.set('Tc_ref', Tc_0_B)
    cstr.set('c_ref', c_0_B)
    cstr.set('T_ref', T_0_B)

    # Set initial values
    cstr.set('cstr.c_init', c_0_A)
    cstr.set('cstr.T_init', T_0_A)

    n_e = 100  # Number of elements

    # Set options
    opt_opts = cstr.optimize_options()
    opt_opts['n_e'] = n_e
    opt_opts['init_traj'] = res.result_data

    res = cstr.optimize(options=opt_opts)

    # Extract variable profiles
    c_res = res['cstr.c']
    T_res = res['cstr.T']
    Tc_res = res['cstr.Tc']
    time_res = res['time']

    c_ref = res['c_ref']
    T_ref = res['T_ref']
    Tc_ref = res['Tc_ref']

    assert N.abs(res.final('cost') / 1.e7 - 1.8585429) < 1e-3

    # Plot the results
    if with_plots:
        plt.figure(2)
        plt.clf()
        plt.hold(True)
        plt.subplot(311)
        plt.plot(time_res, c_res)
        plt.plot([time_res[0], time_res[-1]], [c_ref, c_ref], '--')
        plt.grid()
        plt.ylabel('Concentration')

        plt.subplot(312)
        plt.plot(time_res, T_res)
        plt.plot([time_res[0], time_res[-1]], [T_ref, T_ref], '--')
        plt.grid()
        plt.ylabel('Temperature')

        plt.subplot(313)
        plt.plot(time_res, Tc_res)
        plt.plot([time_res[0], time_res[-1]], [Tc_ref, Tc_ref], '--')
        plt.grid()
        plt.ylabel('Cooling temperature')
        plt.xlabel('time')
        plt.show()

    # Simulate to verify the optimal solution
    # Set up the input trajectory
    t = time_res
    u = Tc_res
    u_traj = N.transpose(N.vstack((t, u)))

    # Compile the Modelica model to a JMU
    jmu_name = compile_jmu("CSTR.CSTR", curr_dir + "/files/CSTR.mop")

    # Load model
    sim_model = JMUModel(jmu_name)

    sim_model.set('c_init', c_0_A)
    sim_model.set('T_init', T_0_A)
    sim_model.set('Tc', u[0])

    res = sim_model.simulate(start_time=0.,
                             final_time=150.,
                             input=('Tc', u_traj))

    # Extract variable profiles
    c_sim = res['c']
    T_sim = res['T']
    Tc_sim = res['Tc']
    time_sim = res['time']

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

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

        plt.subplot(313)
        plt.plot(time_res, Tc_res, '--')
        plt.plot(time_sim, Tc_sim)
        plt.legend(('optimized', 'simulated'))
        plt.grid()
        plt.ylabel('Cooling temperature')
        plt.xlabel('time')
        plt.show()
Example #34
0
def run_demo(with_plots=True):
    """
    This example demonstrates how to solve parameter estimation problmes.

    The data used in the example was recorded by Kristian Soltesz at the 
    Department of Automatic Control. 
    """
    
    curr_dir = os.path.dirname(os.path.abspath(__file__));

    # Load measurement data from file
    data = loadmat(curr_dir+'/files/qt_par_est_data.mat',appendmat=False)

    # Extract data series
    t_meas = data['t'][6000::100,0]-60
    y1_meas = data['y1_f'][6000::100,0]/100
    y2_meas = data['y2_f'][6000::100,0]/100
    y3_meas = data['y3_d'][6000::100,0]/100
    y4_meas = data['y4_d'][6000::100,0]/100
    u1 = data['u1_d'][6000::100,0]
    u2 = data['u2_d'][6000::100,0]
        
    # Plot measurements and inputs
    if with_plots:
        plt.figure(1)
        plt.clf()
        plt.subplot(2,2,1)
        plt.plot(t_meas,y3_meas)
        plt.title('x3')
        plt.grid()
        plt.subplot(2,2,2)
        plt.plot(t_meas,y4_meas)
        plt.title('x4')
        plt.grid()
        plt.subplot(2,2,3)
        plt.plot(t_meas,y1_meas)
        plt.title('x1')
        plt.xlabel('t[s]')
        plt.grid()
        plt.subplot(2,2,4)
        plt.plot(t_meas,y2_meas)
        plt.title('x2')
        plt.xlabel('t[s]')
        plt.grid()

        plt.figure(2)
        plt.clf()
        plt.subplot(2,1,1)
        plt.plot(t_meas,u1)
        plt.hold(True)
        plt.title('u1')
        plt.grid()
        plt.subplot(2,1,2)
        plt.plot(t_meas,u2)
        plt.title('u2')
        plt.xlabel('t[s]')
        plt.hold(True)
        plt.grid()

    # Build input trajectory matrix for use in simulation
    u = N.transpose(N.vstack((t_meas,u1,u2)))

    # compile FMU
    fmu_name = compile_fmu('QuadTankPack.Sim_QuadTank', 
        curr_dir+'/files/QuadTankPack.mop')

    # Load model
    model = load_fmu(fmu_name)
    
    # Simulate model response with nominal parameters
    res = model.simulate(input=(['u1','u2'],u),start_time=0.,final_time=60)

    # Load simulation result
    x1_sim = res['qt.x1']
    x2_sim = res['qt.x2']
    x3_sim = res['qt.x3']
    x4_sim = res['qt.x4']
    t_sim  = res['time']
    
    u1_sim = res['u1']
    u2_sim = res['u2']

    # Plot simulation result
    if with_plots:
        plt.figure(1)
        plt.subplot(2,2,1)
        plt.plot(t_sim,x3_sim)
        plt.subplot(2,2,2)
        plt.plot(t_sim,x4_sim)
        plt.subplot(2,2,3)
        plt.plot(t_sim,x1_sim)
        plt.subplot(2,2,4)
        plt.plot(t_sim,x2_sim)

        plt.figure(2)
        plt.subplot(2,1,1)
        plt.plot(t_sim,u1_sim,'r')
        plt.subplot(2,1,2)
        plt.plot(t_sim,u2_sim,'r')

    # Compile parameter optimization model
    jmu_name = compile_jmu("QuadTankPack.QuadTank_ParEst",
        curr_dir+"/files/QuadTankPack.mop")

    # Load the model
    qt_par_est = JMUModel(jmu_name)

    # Number of measurement points
    N_meas = N.size(u1,0)

    # Set measurement data into model
    for i in range(0,N_meas):
        qt_par_est.set("t_meas["+`i+1`+"]",t_meas[i])
        qt_par_est.set("y1_meas["+`i+1`+"]",y1_meas[i])
        qt_par_est.set("y2_meas["+`i+1`+"]",y2_meas[i])

    n_e = 30 # Numer of element in collocation algorithm

    # Get an options object for the optimization algorithm
    opt_opts = qt_par_est.optimize_options()
    # Set the number of collocation points
    opt_opts['n_e'] = n_e

    opt_opts['init_traj'] = res.result_data
    
    # Solve parameter optimization problem
    res = qt_par_est.optimize(options=opt_opts)

    # Extract optimal values of parameters
    a1_opt = res.final("qt.a1")
    a2_opt = res.final("qt.a2")

    # Print optimal parameter values
    print('a1: ' + str(a1_opt*1e4) + 'cm^2')
    print('a2: ' + str(a2_opt*1e4) + 'cm^2')

    assert N.abs(a1_opt*1.e6 - 2.6574) < 1e-3 
    assert N.abs(a2_opt*1.e6 - 2.7130) < 1e-3

    # Load state profiles
    x1_opt = res["qt.x1"]
    x2_opt = res["qt.x2"]
    x3_opt = res["qt.x3"]
    x4_opt = res["qt.x4"]
    u1_opt = res["qt.u1"]
    u2_opt = res["qt.u2"]
    t_opt  = res["time"]

    # Plot
    if with_plots:
        plt.figure(1)
        plt.subplot(2,2,1)
        plt.plot(t_opt,x3_opt,'k')
        plt.subplot(2,2,2)
        plt.plot(t_opt,x4_opt,'k')
        plt.subplot(2,2,3)
        plt.plot(t_opt,x1_opt,'k')
        plt.subplot(2,2,4)
        plt.plot(t_opt,x2_opt,'k')

    # Compile second parameter estimation model
    jmu_name = compile_jmu("QuadTankPack.QuadTank_ParEst2", 
        curr_dir+"/files/QuadTankPack.mop")

    # Load model
    qt_par_est2 = JMUModel(jmu_name)
    
    # Number of measurement points
    N_meas = N.size(u1,0)

    # Set measurement data into model
    for i in range(0,N_meas):
        qt_par_est2.set("t_meas["+`i+1`+"]",t_meas[i])
        qt_par_est2.set("y1_meas["+`i+1`+"]",y1_meas[i])
        qt_par_est2.set("y2_meas["+`i+1`+"]",y2_meas[i])
        qt_par_est2.set("y3_meas["+`i+1`+"]",y3_meas[i])
        qt_par_est2.set("y4_meas["+`i+1`+"]",y4_meas[i])

    # Solve parameter estimation problem
    res_opt2 = qt_par_est2.optimize(options=opt_opts)

    # Get optimal parameter values
    a1_opt2 = res_opt2.final("qt.a1")
    a2_opt2 = res_opt2.final("qt.a2")
    a3_opt2 = res_opt2.final("qt.a3")
    a4_opt2 = res_opt2.final("qt.a4")

    # Print optimal parameter values 
    print('a1:' + str(a1_opt2*1e4) + 'cm^2')
    print('a2:' + str(a2_opt2*1e4) + 'cm^2')
    print('a3:' + str(a3_opt2*1e4) + 'cm^2')
    print('a4:' + str(a4_opt2*1e4) + 'cm^2')

    assert N.abs(a1_opt2*1.e6 - 2.6579) < 1e-3, "Wrong value of parameter a1"  
    assert N.abs(a2_opt2*1.e6 - 2.7038) < 1e-3, "Wrong value of parameter a2"  
    assert N.abs(a3_opt2*1.e6 - 3.0031) < 1e-3, "Wrong value of parameter a3"  
    assert N.abs(a4_opt2*1.e6 - 2.9342) < 1e-3, "Wrong value of parameter a4"  

    # Extract state and input profiles
    x1_opt2 = res_opt2["qt.x1"]
    x2_opt2 = res_opt2["qt.x2"]
    x3_opt2 = res_opt2["qt.x3"]
    x4_opt2 = res_opt2["qt.x4"]
    u1_opt2 = res_opt2["qt.u1"]
    u2_opt2 = res_opt2["qt.u2"]
    t_opt2  = res_opt2["time"]

    # Plot
    if with_plots:
        plt.figure(1)
        plt.subplot(2,2,1)
        plt.plot(t_opt2,x3_opt2,'r')
        plt.subplot(2,2,2)
        plt.plot(t_opt2,x4_opt2,'r')
        plt.subplot(2,2,3)
        plt.plot(t_opt2,x1_opt2,'r')
        plt.subplot(2,2,4)
        plt.plot(t_opt2,x2_opt2,'r')
        plt.show()

    # Compute parameter standard deviations for case 1
    # compile JMU
    jmu_name = compile_jmu('QuadTankPack.QuadTank_Sens1',
                           curr_dir+'/files/QuadTankPack.mop')

    # Load model
    model = JMUModel(jmu_name)

    model.set('a1',a1_opt)
    model.set('a2',a2_opt)
    
    sens_opts = model.simulate_options()

    # Enable sensitivity computations
    sens_opts['IDA_options']['sensitivity'] = True
    #sens_opts['IDA_options']['atol'] = 1e-12

    # Simulate sensitivity equations
    sens_res = model.simulate(input=(['u1','u2'],u),start_time=0.,final_time=60, options = sens_opts)

    # Get result trajectories
    x1_sens = sens_res['x1']
    x2_sens = sens_res['x2']
    dx1da1 = sens_res['dx1/da1']
    dx1da2 = sens_res['dx1/da2']
    dx2da1 = sens_res['dx2/da1']
    dx2da2 = sens_res['dx2/da2']
    t_sens = sens_res['time']
    
    # Compute Jacobian

    # Create a trajectory object for interpolation
    traj=TrajectoryLinearInterpolation(t_sens,N.transpose(N.vstack((x1_sens,x2_sens,dx1da1,dx1da2,dx2da1,dx2da2))))

    # Jacobian
    jac = N.zeros((61*2,2))

    # Error vector
    err = N.zeros(61*2)

    # Extract Jacobian and error information
    i = 0
    for t_p in t_meas:
        vals = traj.eval(t_p)
        for j in range(2):
            for k in range(2):
                jac[i+j,k] = vals[0,2*j+k+2]
            err[i] = vals[0,0] - y1_meas[i/2]
            err[i+1] = vals[0,1] - y2_meas[i/2]
        i = i + 2

    # Compute estimated variance of measurement noice    
    v_err = N.sum(err**2)/(61*2-2)

    # Compute J^T*J
    A = N.dot(N.transpose(jac),jac)

    # Compute parameter covariance matrix
    P = v_err*N.linalg.inv(A)

    # Compute standard deviations for parameters
    sigma_a1 = N.sqrt(P[0,0])
    sigma_a2 = N.sqrt(P[1,1])

    print "a1: " + str(sens_res['a1']) + ", standard deviation: " + str(sigma_a1)
    print "a2: " + str(sens_res['a2']) + ", standard deviation: " + str(sigma_a2)

    # Compute parameter standard deviations for case 2
    # compile JMU
    jmu_name = compile_jmu('QuadTankPack.QuadTank_Sens2',
                           curr_dir+'/files/QuadTankPack.mop')

    # Load model
    model = JMUModel(jmu_name)

    model.set('a1',a1_opt2)
    model.set('a2',a2_opt2)
    model.set('a3',a3_opt2)
    model.set('a4',a4_opt2)
    
    sens_opts = model.simulate_options()

    # Enable sensitivity computations
    sens_opts['IDA_options']['sensitivity'] = True
    #sens_opts['IDA_options']['atol'] = 1e-12

    # Simulate sensitivity equations
    sens_res = model.simulate(input=(['u1','u2'],u),start_time=0.,final_time=60, options = sens_opts)

    # Get result trajectories
    x1_sens = sens_res['x1']
    x2_sens = sens_res['x2']
    x3_sens = sens_res['x3']
    x4_sens = sens_res['x4']
    
    dx1da1 = sens_res['dx1/da1']
    dx1da2 = sens_res['dx1/da2']
    dx1da3 = sens_res['dx1/da3']
    dx1da4 = sens_res['dx1/da4']

    dx2da1 = sens_res['dx2/da1']
    dx2da2 = sens_res['dx2/da2']
    dx2da3 = sens_res['dx2/da3']
    dx2da4 = sens_res['dx2/da4']

    dx3da1 = sens_res['dx3/da1']
    dx3da2 = sens_res['dx3/da2']
    dx3da3 = sens_res['dx3/da3']
    dx3da4 = sens_res['dx3/da4']

    dx4da1 = sens_res['dx4/da1']
    dx4da2 = sens_res['dx4/da2']
    dx4da3 = sens_res['dx4/da3']
    dx4da4 = sens_res['dx4/da4']
    t_sens = sens_res['time']
    
    # Compute Jacobian

    # Create a trajectory object for interpolation
    traj=TrajectoryLinearInterpolation(t_sens,N.transpose(N.vstack((x1_sens,x2_sens,x3_sens,x4_sens,
                                                                    dx1da1,dx1da2,dx1da3,dx1da4,
                                                                    dx2da1,dx2da2,dx2da3,dx2da4,
                                                                    dx3da1,dx3da2,dx3da3,dx3da4,
                                                                    dx4da1,dx4da2,dx4da3,dx4da4))))

    # Jacobian
    jac = N.zeros((61*4,4))

    # Error vector
    err = N.zeros(61*4)

    # Extract Jacobian and error information
    i = 0
    for t_p in t_meas:
        vals = traj.eval(t_p)
        for j in range(4):
            for k in range(4):
                jac[i+j,k] = vals[0,4*j+k+4]
            err[i] = vals[0,0] - y1_meas[i/4]
            err[i+1] = vals[0,1] - y2_meas[i/4]
            err[i+2] = vals[0,2] - y3_meas[i/4]
            err[i+3] = vals[0,3] - y4_meas[i/4]
        i = i + 4

    # Compute estimated variance of measurement noice    
    v_err = N.sum(err**2)/(61*4-4)

    # Compute J^T*J
    A = N.dot(N.transpose(jac),jac)

    # Compute parameter covariance matrix
    P = v_err*N.linalg.inv(A)

    # Compute standard deviations for parameters
    sigma_a1 = N.sqrt(P[0,0])
    sigma_a2 = N.sqrt(P[1,1])
    sigma_a3 = N.sqrt(P[2,2])
    sigma_a4 = N.sqrt(P[3,3])

    print "a1: " + str(sens_res['a1']) + ", standard deviation: " + str(sigma_a1)
    print "a2: " + str(sens_res['a2']) + ", standard deviation: " + str(sigma_a2)
    print "a3: " + str(sens_res['a3']) + ", standard deviation: " + str(sigma_a3)
    print "a4: " + str(sens_res['a4']) + ", standard deviation: " + str(sigma_a4)
Example #35
0
def run_demo(with_plots=True):
    """
    This is the crystallizer example from Bieglers book in section 10.3.
    """
    curr_dir = os.path.dirname(os.path.abspath(__file__));
        
    # Compile and load model
    fmu_name = compile_fmu("Crystallizer.SimulateCrystallizer", os.path.join(curr_dir, "files", "Crystallizer.mop"), 
                           compiler_options={"enable_variable_scaling":True})
    crys = load_fmu(fmu_name)
    
    # Simulate
    res = crys.simulate(final_time=25)

    time = res['time']
    Ls = res['c.Ls']
    Nc = res['c.Nc']
    L = res['c.L']
    Ac = res['c.Ac']
    Vc = res['c.Vc']
    Mc = res['c.Mc']
    Cc = res['c.Cc']
    Tc = res['c.Tc']
    
    Ta = res['Ta']
    Teq = res['c.Teq']
    deltaT = res['c.deltaT']
    Cbar = res['c.Cbar']
    
    Tj = res['c.Tj']

    if with_plots:
        plt.figure(1)
        plt.clf()
        plt.subplot(2,1,1)
        plt.plot(time,Ls)
        plt.grid()
        plt.subplot(2,1,2)
        plt.plot(time,Tj)
        plt.grid()
        plt.show()
        
        plt.figure(2)
        plt.clf()
        plt.subplot(4,1,1)
        plt.plot(time,Nc)
        plt.title('Nc')
        plt.grid()
        plt.subplot(4,1,2)
        plt.plot(time,L)
        plt.title('L')
        plt.grid()
        plt.subplot(4,1,3)
        plt.plot(time,Ac)
        plt.title('Ac')
        plt.grid()
        plt.subplot(4,1,4)
        plt.plot(time,Vc)
        plt.title('Vc')
        plt.grid()
        
        plt.figure(3)
        plt.clf()
        plt.subplot(4,1,1)
        plt.plot(time,Mc)
        plt.title('Mc')
        plt.grid()
        plt.subplot(4,1,2)
        plt.plot(time,Cc)
        plt.title('Cc')
        plt.grid()
        plt.subplot(4,1,3)
        plt.plot(time,Tc)
        plt.title('Tc')
        plt.grid()
        plt.subplot(4,1,4)
        plt.plot(time,Teq)
        plt.title('Teq')
        plt.grid()
        plt.show()

        plt.figure(4)
        plt.clf()
        plt.subplot(4,1,1)
        plt.plot(time,deltaT)
        plt.title('deltaT')
        plt.grid()
        plt.subplot(4,1,2)
        plt.plot(time,Cbar)
        plt.title('Cbar')
        plt.grid()
        plt.subplot(4,1,3)
        plt.plot(time,Teq-Tc)
        plt.title('Teq-Tc')
        plt.grid()
        plt.subplot(4,1,4)
        plt.plot(time,Ta)
        plt.title('Ta')
        plt.grid()
        plt.show()
        
    # Compile and load opt model
    jmu_name = compile_jmu("Crystallizer.OptCrystallizer",
                           os.path.join(curr_dir, "files", "Crystallizer.mop"),
                           compiler_options={"enable_variable_scaling":True})
    crys_opt = JMUModel(jmu_name)

    # Set optimization options
    opt_opts = crys_opt.optimize_options()

    n_e = 20
    opt_opts['n_e'] = n_e 
    opt_opts['init_traj'] = res.result_data
    opt_opts['blocking_factors'] = N.ones(n_e,dtype=int)
    opt_opts['IPOPT_options']['max_iter'] = 1000
    opt_opts['IPOPT_options']['tol'] = 1e-3
    opt_opts['IPOPT_options']['dual_inf_tol'] = 1e-3
    
    # Run optimization
    res_opt = crys_opt.optimize(options=opt_opts)
    
    # Get result data
    time = res_opt['time']
    Ls = res_opt['c.Ls']
    Nc = res_opt['c.Nc']
    L = res_opt['c.L']
    Ac = res_opt['c.Ac']
    Vc = res_opt['c.Vc']
    Mc = res_opt['c.Mc']
    Cc = res_opt['c.Cc']
    Tc = res_opt['c.Tc']
    
    Teq = res_opt['c.Teq']
    deltaT = res_opt['c.deltaT']
    Cbar = res_opt['c.Cbar']
    
    Tj = res_opt['c.Tj']
    
    assert N.abs(res_opt.final('c.Tj') - 10.0) < 1e-3

    if with_plots:
        plt.figure(1)
        plt.subplot(2,1,1)
        plt.hold(True)
        plt.plot(time,Ls)
        plt.subplot(2,1,2)
        plt.hold(True)
        plt.plot(time,Tj,'x-')
        
        plt.figure(2)
        plt.subplot(4,1,1)
        plt.hold(True)
        plt.plot(time,Nc)
        plt.title('Nc')
        plt.subplot(4,1,2)
        plt.hold(True)
        plt.plot(time,L)
        plt.title('L')
        plt.subplot(4,1,3)
        plt.hold(True)
        plt.plot(time,Ac)
        plt.title('Ac')
        plt.subplot(4,1,4)
        plt.hold(True)
        plt.plot(time,Vc)
        plt.title('Vc')
        
        plt.figure(3)
        plt.subplot(4,1,1)
        plt.hold(True)
        plt.plot(time,Mc)
        plt.title('Mc')
        plt.subplot(4,1,2)
        plt.hold(True)
        plt.plot(time,Cc)
        plt.title('Cc')
        plt.subplot(4,1,3)
        plt.hold(True)
        plt.plot(time,Tc)
        plt.title('Tc')
        plt.subplot(4,1,4)
        plt.hold(True)
        plt.plot(time,Teq)
        plt.title('Teq')
        plt.show()
        
        plt.figure(4)
        plt.subplot(4,1,1)
        plt.hold(True)
        plt.plot(time,deltaT)
        plt.title('deltaT')
        plt.subplot(4,1,2)
        plt.hold(True)
        plt.plot(time,Cbar)
        plt.title('Cbar')
        plt.subplot(4,1,3)
        plt.hold(True)
        plt.plot(time,Teq-Tc)
        plt.title('Teq-Tc')
        
        plt.show()
Example #36
0
def run_demo(with_plots=True):
    """
    Distillation4 optimization model
    """

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

	# Compile the stationary initialization model into a JMU
    jmu_name = compile_jmu("JMExamples.Distillation.Distillation1Input_init", 
    curr_dir+"/files/JMExamples.mo")

    # Load a model instance into Python
    init_model = JMUModel(jmu_name)
    
    # Set inputs for Stationary point A
    rr_0_A = 3.0
    init_model.set('rr',rr_0_A)
    init_result = init_model.initialize()
    	
    # 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(32):
        y_A[i] = init_result['y['+ str(i+1) +']'][0]
        x_A[i] = init_result['x['+ str(i+1) +']'][0]
        print '(' + str(i+1) + ', %f, %f)' %(x_A[i], y_A[i])
    
    # Set inputs for stationary point B
    rr_0_B = 2.0
    init_model.set('rr',rr_0_B)
    init_result = init_model.initialize()

    # 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(32):
        y_B[i] = init_result['y[' + str(i+1) + ']'][0]
        x_B[i] = init_result['x[' + str(i+1) + ']'][0]
        print '(' + str(i+1) + ', %f, %f)' %(x_B[i], y_B[i])

    # Set up and solve the simulation problem. 

    fmu_name1 = compile_fmu("JMExamples.Distillation.Distillation1Inputstep", 
    curr_dir+"/files/JMExamples.mo")
    dist1 = load_fmu(fmu_name1)

    # Initialize the model with parameters

    # Initialize the model to stationary point A
    for i in range(32):
        dist1.set('x_init[' + str(i+1) + ']', x_A[i])
		
    res = dist1.simulate(final_time=50)

    # Extract variable profiles
    x1  = res['x[1]']
    x8  = res['x[8]']
    x16	= res['x[16]']
    x24	= res['x[24]']
    x32	= res['x[32]']
    y1  = res['y[1]']
    y8  = res['y[8]']
    y16	= res['y[16]']
    y24	= res['y[24]']
    y32	= res['y[32]']
    t	= res['time']
    rr  = res['rr']
    
    print "t = ", repr(N.array(t))
    print "x1 = ", repr(N.array(x1))
    print "x8 = ", repr(N.array(x8))
    print "x16 = ", repr(N.array(x16))
    print "x32 = ", repr(N.array(x32))

    if with_plots:
        # Plot
        plt.figure()
        plt.subplot(1,3,1)
        plt.plot(t,x16,t,x32,t,x1,t,x8,t,x24)
        plt.title('Liquid composition')
        plt.grid(True)
        plt.ylabel('x')
        plt.subplot(1,3,2)
        plt.plot(t,y16,t,y32,t,y1,t,y8,t,y24)
        plt.title('Vapor composition')
        plt.grid(True)
        plt.ylabel('y')
        plt.subplot(1,3,3)
        plt.plot(t,rr)
        plt.title('Reflux ratio')
        plt.grid(True)
        plt.ylabel('rr')
		
        plt.xlabel('time')
        plt.show()
Example #37
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__));
        
    # Compile the stationary initialization model into a JMU
    jmu_name = compile_jmu("CSTR.CSTR_Init", os.path.join(curr_dir,"files", "CSTR.mop"), 
        compiler_options={"enable_variable_scaling":True})
    
    # load the JMU
    init_model = JMUModel(jmu_name)
    
    # Set inputs for Stationary point A
    Tc_0_A = 250
    init_model.set('Tc',Tc_0_A)
        
    # Solve the DAE initialization system with Ipopt
    init_result = init_model.initialize()
    
    # Store stationary point A
    c_0_A = init_result['c'][0]
    T_0_A = init_result['T'][0]
    
    # 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('Tc',Tc_0_B)
        
    # Solve the DAE initialization system with Ipopt
    init_result = init_model.initialize()
    # Store stationary point B
    c_0_B = init_result['c'][0]
    T_0_B = init_result['T'][0]

    # 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
    # Compile the optimization initialization model
    jmu_name = compile_jmu("CSTR.CSTR_Init_Optimization", 
        os.path.join(curr_dir, "files", "CSTR.mop"))

    # Load the model
    init_sim_model = JMUModel(jmu_name)

    # Set model parameters
    init_sim_model.set('cstr.c_init',c_0_A)
    init_sim_model.set('cstr.T_init',T_0_A)
    init_sim_model.set('c_ref',c_0_B)
    init_sim_model.set('T_ref',T_0_B)
    init_sim_model.set('Tc_ref',Tc_0_B)

    res = init_sim_model.simulate(start_time=0.,final_time=150.)
    
    # Extract variable profiles
    c_init_sim=res['cstr.c']
    T_init_sim=res['cstr.T']
    Tc_init_sim=res['cstr.Tc']
    t_init_sim = res['time']

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

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

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

    # Solve the optimal control problem
    # Compile model
    jmu_name = compile_jmu("CSTR.CSTR_Opt", curr_dir+"/files/CSTR.mop")

    # Load model
    cstr = JMUModel(jmu_name)

    # Set reference values
    cstr.set('Tc_ref',Tc_0_B)
    cstr.set('c_ref',c_0_B)
    cstr.set('T_ref',T_0_B)

    # Set initial values
    cstr.set('cstr.c_init',c_0_A)
    cstr.set('cstr.T_init',T_0_A)

    n_e = 100 # Number of elements 

    # Set options
    opt_opts = cstr.optimize_options()
    opt_opts['n_e'] = n_e
    opt_opts['init_traj'] = res.result_data

    res = cstr.optimize(options=opt_opts)

    # Extract variable profiles
    c_res=res['cstr.c']
    T_res=res['cstr.T']
    Tc_res=res['cstr.Tc']
    time_res = res['time']

    c_ref=res['c_ref']
    T_ref=res['T_ref']
    Tc_ref=res['Tc_ref']

    assert N.abs(res.final('cost')/1.e7 - 1.8585429) < 1e-3  

    # Plot the results
    if with_plots:
        plt.figure(2)
        plt.clf()
        plt.hold(True)
        plt.subplot(311)
        plt.plot(time_res,c_res)
        plt.plot([time_res[0],time_res[-1]],[c_ref,c_ref],'--')
        plt.grid()
        plt.ylabel('Concentration')

        plt.subplot(312)
        plt.plot(time_res,T_res)
        plt.plot([time_res[0],time_res[-1]],[T_ref,T_ref],'--')
        plt.grid()
        plt.ylabel('Temperature')

        plt.subplot(313)
        plt.plot(time_res,Tc_res)
        plt.plot([time_res[0],time_res[-1]],[Tc_ref,Tc_ref],'--')
        plt.grid()
        plt.ylabel('Cooling temperature')
        plt.xlabel('time')
        plt.show()

    # Simulate to verify the optimal solution
    # Set up the input trajectory
    t = time_res 
    u = Tc_res
    u_traj = N.transpose(N.vstack((t,u)))
    
    # Compile the Modelica model to a JMU
    jmu_name = compile_jmu("CSTR.CSTR", curr_dir+"/files/CSTR.mop")

    # Load model
    sim_model = JMUModel(jmu_name)

    sim_model.set('c_init',c_0_A)
    sim_model.set('T_init',T_0_A)
    sim_model.set('Tc',u[0])

    res = sim_model.simulate(start_time=0.,final_time=150.,
        input=('Tc',u_traj))
    
    # Extract variable profiles
    c_sim=res['c']
    T_sim=res['T']
    Tc_sim=res['Tc']
    time_sim = res['time']

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

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

        plt.subplot(313)
        plt.plot(time_res,Tc_res,'--')
        plt.plot(time_sim,Tc_sim)
        plt.legend(('optimized','simulated'))
        plt.grid()
        plt.ylabel('Cooling temperature')
        plt.xlabel('time')
        plt.show()
Example #38
0
def run_demo(with_plots=True):
    """
    This is the crystallizer example from Bieglers book in section 10.3.
    """
    curr_dir = os.path.dirname(os.path.abspath(__file__))

    # Compile and load model
    fmu_name = compile_fmu("Crystallizer.SimulateCrystallizer",
                           os.path.join(curr_dir, "files", "Crystallizer.mop"),
                           compiler_options={"enable_variable_scaling": True})
    crys = load_fmu(fmu_name)

    # Simulate
    res = crys.simulate(final_time=25)

    time = res['time']
    Ls = res['c.Ls']
    Nc = res['c.Nc']
    L = res['c.L']
    Ac = res['c.Ac']
    Vc = res['c.Vc']
    Mc = res['c.Mc']
    Cc = res['c.Cc']
    Tc = res['c.Tc']

    Ta = res['Ta']
    Teq = res['c.Teq']
    deltaT = res['c.deltaT']
    Cbar = res['c.Cbar']

    Tj = res['c.Tj']

    if with_plots:
        plt.figure(1)
        plt.clf()
        plt.subplot(2, 1, 1)
        plt.plot(time, Ls)
        plt.grid()
        plt.subplot(2, 1, 2)
        plt.plot(time, Tj)
        plt.grid()
        plt.show()

        plt.figure(2)
        plt.clf()
        plt.subplot(4, 1, 1)
        plt.plot(time, Nc)
        plt.title('Nc')
        plt.grid()
        plt.subplot(4, 1, 2)
        plt.plot(time, L)
        plt.title('L')
        plt.grid()
        plt.subplot(4, 1, 3)
        plt.plot(time, Ac)
        plt.title('Ac')
        plt.grid()
        plt.subplot(4, 1, 4)
        plt.plot(time, Vc)
        plt.title('Vc')
        plt.grid()

        plt.figure(3)
        plt.clf()
        plt.subplot(4, 1, 1)
        plt.plot(time, Mc)
        plt.title('Mc')
        plt.grid()
        plt.subplot(4, 1, 2)
        plt.plot(time, Cc)
        plt.title('Cc')
        plt.grid()
        plt.subplot(4, 1, 3)
        plt.plot(time, Tc)
        plt.title('Tc')
        plt.grid()
        plt.subplot(4, 1, 4)
        plt.plot(time, Teq)
        plt.title('Teq')
        plt.grid()
        plt.show()

        plt.figure(4)
        plt.clf()
        plt.subplot(4, 1, 1)
        plt.plot(time, deltaT)
        plt.title('deltaT')
        plt.grid()
        plt.subplot(4, 1, 2)
        plt.plot(time, Cbar)
        plt.title('Cbar')
        plt.grid()
        plt.subplot(4, 1, 3)
        plt.plot(time, Teq - Tc)
        plt.title('Teq-Tc')
        plt.grid()
        plt.subplot(4, 1, 4)
        plt.plot(time, Ta)
        plt.title('Ta')
        plt.grid()
        plt.show()

    # Compile and load opt model
    jmu_name = compile_jmu("Crystallizer.OptCrystallizer",
                           os.path.join(curr_dir, "files", "Crystallizer.mop"),
                           compiler_options={"enable_variable_scaling": True})
    crys_opt = JMUModel(jmu_name)

    # Set optimization options
    opt_opts = crys_opt.optimize_options()

    n_e = 20
    opt_opts['n_e'] = n_e
    opt_opts['init_traj'] = res.result_data
    opt_opts['blocking_factors'] = N.ones(n_e, dtype=int)
    opt_opts['IPOPT_options']['max_iter'] = 1000
    opt_opts['IPOPT_options']['tol'] = 1e-3
    opt_opts['IPOPT_options']['dual_inf_tol'] = 1e-3

    # Run optimization
    res_opt = crys_opt.optimize(options=opt_opts)

    # Get result data
    time = res_opt['time']
    Ls = res_opt['c.Ls']
    Nc = res_opt['c.Nc']
    L = res_opt['c.L']
    Ac = res_opt['c.Ac']
    Vc = res_opt['c.Vc']
    Mc = res_opt['c.Mc']
    Cc = res_opt['c.Cc']
    Tc = res_opt['c.Tc']

    Teq = res_opt['c.Teq']
    deltaT = res_opt['c.deltaT']
    Cbar = res_opt['c.Cbar']

    Tj = res_opt['c.Tj']

    assert N.abs(res_opt.final('c.Tj') - 10.0) < 1e-3

    if with_plots:
        plt.figure(1)
        plt.subplot(2, 1, 1)
        plt.hold(True)
        plt.plot(time, Ls)
        plt.subplot(2, 1, 2)
        plt.hold(True)
        plt.plot(time, Tj, 'x-')

        plt.figure(2)
        plt.subplot(4, 1, 1)
        plt.hold(True)
        plt.plot(time, Nc)
        plt.title('Nc')
        plt.subplot(4, 1, 2)
        plt.hold(True)
        plt.plot(time, L)
        plt.title('L')
        plt.subplot(4, 1, 3)
        plt.hold(True)
        plt.plot(time, Ac)
        plt.title('Ac')
        plt.subplot(4, 1, 4)
        plt.hold(True)
        plt.plot(time, Vc)
        plt.title('Vc')

        plt.figure(3)
        plt.subplot(4, 1, 1)
        plt.hold(True)
        plt.plot(time, Mc)
        plt.title('Mc')
        plt.subplot(4, 1, 2)
        plt.hold(True)
        plt.plot(time, Cc)
        plt.title('Cc')
        plt.subplot(4, 1, 3)
        plt.hold(True)
        plt.plot(time, Tc)
        plt.title('Tc')
        plt.subplot(4, 1, 4)
        plt.hold(True)
        plt.plot(time, Teq)
        plt.title('Teq')
        plt.show()

        plt.figure(4)
        plt.subplot(4, 1, 1)
        plt.hold(True)
        plt.plot(time, deltaT)
        plt.title('deltaT')
        plt.subplot(4, 1, 2)
        plt.hold(True)
        plt.plot(time, Cbar)
        plt.title('Cbar')
        plt.subplot(4, 1, 3)
        plt.hold(True)
        plt.plot(time, Teq - Tc)
        plt.title('Teq-Tc')

        plt.show()
Example #39
0
def run_demo(with_plots=True):

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

    jmu_name = compile_jmu("Orbital", curr_dir + "/files/Hohmann.mop")
    comp_opts = {
        "normalize_minimum_time_problems": False
    }  # Disable minimum time normalization
    fmux_name = compile_fmux("HohmannTransfer",
                             curr_dir + "/files/Hohmann.mop",
                             compiler_options=comp_opts)

    # Optimization
    model = CasadiModel(fmux_name)
    opts = model.optimize_options(algorithm="CasadiPseudoSpectralAlg")
    opts["n_cp"] = 40  # Number of collocation points
    opts["n_e"] = 2  # Number of phases
    opts[
        "free_phases"] = True  # The phase boundary is allowed to be changed in time
    opts["phase_options"] = [
        "t1"
    ]  # The phase boundary is connected to variable t1
    opts["link_options"] = [
        (1, "vy", "dy1"), (1, "vx", "dx1")
    ]  # Allow for discontinuities between phase 1 and 2 for vy and vx.
    # The discontinuities are connected by dy1 and dx1
    # Optimize
    res_opt = model.optimize(algorithm="CasadiPseudoSpectralAlg", options=opts)

    # Get results
    dx1, dy1, dx2, dy2 = res_opt.final("dx1"), res_opt.final(
        "dy1"), res_opt.final("dx2"), res_opt.final("dy2")
    r1, r2, my = res_opt.final("rStart"), res_opt.final(
        "rFinal"), res_opt.final("my")
    tf, t1 = res_opt.final("time"), res_opt.final("t1")

    # Verify solution using theoretical results
    # Assert dv1
    assert N.abs(
        N.sqrt(dx1**2 + dy1**2) - N.sqrt(my / r1) *
        (N.sqrt(2 * r2 / (r1 + r2)) - 1)) < 1e-1
    #Assert dv2
    assert N.abs(
        N.sqrt(dx2**2 + dy2**2) - N.sqrt(my / r2) *
        (1 - N.sqrt(2 * r1 / (r1 + r2)))) < 1e-1
    #Assert transfer time
    assert N.abs(tf - t1 - N.pi * ((r1 + r2)**3 / (8 * my))**0.5) < 1e-1

    # Verify solution by simulation
    model = JMUModel(jmu_name)

    # Retrieve the options
    opts = model.simulate_options()

    opts["ncp"] = 100
    opts["solver"] = "IDA"
    opts["initialize"] = False

    # Simulation of Phase 1
    res = model.simulate(final_time=t1, options=opts)

    x_phase_1, y_phase_1 = res["x"], res["y"]

    # Simulation of Phase 2
    model.set("vx", dx1 + res.final("vx"))
    model.set("vy", dy1 + res.final("vy"))

    res = model.simulate(start_time=t1, final_time=tf, options=opts)

    x_phase_2, y_phase_2 = res["x"], res["y"]

    # Simulation of Phase 3 (verify that we are still in orbit)
    model.set("vx", dx2 + res.final("vx"))
    model.set("vy", dy2 + res.final("vy"))

    res = model.simulate(start_time=tf, final_time=tf * 2, options=opts)

    x_phase_3, y_phase_3 = res["x"], res["y"]

    if with_plots:
        # Plot Earth
        r = 1.0
        xE = r * N.cos(N.linspace(0, 2 * N.pi, 200))
        yE = r * N.sin(N.linspace(0, 2 * N.pi, 200))
        plt.plot(xE, yE, label="Earth")

        # Plot Orbits
        r = res.final("rStart")
        xS = r * N.cos(N.linspace(0, 2 * N.pi, 200))
        yS = r * N.sin(N.linspace(0, 2 * N.pi, 200))
        plt.plot(xS, yS, label="Low Orbit")

        r = res.final("rFinal")
        xSE = r * N.cos(N.linspace(0, 2 * N.pi, 200))
        ySE = r * N.sin(N.linspace(0, 2 * N.pi, 200))
        plt.plot(xSE, ySE, label="High Orbit")

        # Plot Satellite trajectory
        x_sim = N.hstack((N.hstack((x_phase_1, x_phase_2)), x_phase_3))
        y_sim = N.hstack((N.hstack((y_phase_1, y_phase_2)), y_phase_3))

        plt.plot(x_sim, y_sim, "-", label="Satellite")

        # Plot Rocket Burns
        plt.arrow(x_phase_1[-1],
                  y_phase_1[-1],
                  0.5 * dx1,
                  0.5 * dy1,
                  width=0.01,
                  label="dv1")
        plt.arrow(x_phase_2[-1],
                  y_phase_2[-1],
                  0.5 * dx2,
                  0.5 * dy2,
                  width=0.01,
                  label="dv2")

        plt.legend()
        plt.show()
Example #40
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 #41
0
def run_demo(with_plots=True):
    """
    Example about landing an object.
    
    Reference : PROPT - Matlab Optimal Control Software (DAE, ODE)
    """

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

    jmu_name = compile_jmu(
        "JMExamples_opt.MoonLander_opt",
        (os.path.join(curr_dir, 'files', 'JMExamples_opt.mop'),
         os.path.join(curr_dir, 'files', 'JMExamples.mo')))
    ml = JMUModel(jmu_name)

    res = ml.optimize()

    # Extract variable profiles
    h = res['h']
    v = res['v']
    m = res['m']
    u = res['u']
    t = res['time']

    assert N.abs(res.final('u') - 0.98270) < 1e-4

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

        plt.subplot(221)
        plt.plot(t, h)
        plt.grid()
        plt.ylabel('h')
        plt.xlabel('time')
        plt.title('height')

        plt.subplot(222)
        plt.plot(t, v)
        plt.grid()
        plt.ylabel('v')
        plt.xlabel('time')
        plt.title('velocity')

        plt.subplot(223)
        plt.plot(t, m)
        plt.grid()
        plt.ylabel('m')
        plt.xlabel('time')
        plt.title('mass')

        plt.subplot(224)
        plt.plot(t, u)
        plt.grid()
        plt.ylabel('u')
        plt.xlabel('time')
        plt.title('thrust')

        plt.show()

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

    jmu_name = compile_jmu(
        "JMExamples_opt.MoonLander_opttime",
        (os.path.join(curr_dir, 'files', 'JMExamples_opt.mop'),
         os.path.join(curr_dir, 'files', 'JMExamples.mo')))
    ml = JMUModel(jmu_name)

    res = ml.optimize()

    # Extract variable profiles
    h = res['h']
    v = res['v']
    m = res['m']
    u = res['u']
    t = res['time']

    assert N.abs(res.final('u') - 1.22699) < 1e-4

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

        plt.subplot(221)
        plt.plot(t, h)
        plt.grid()
        plt.ylabel('h')
        plt.xlabel('time')
        plt.title('height')

        plt.subplot(222)
        plt.plot(t, v)
        plt.grid()
        plt.ylabel('v')
        plt.xlabel('time')
        plt.title('velocity')

        plt.subplot(223)
        plt.plot(t, m)
        plt.grid()
        plt.ylabel('m')
        plt.xlabel('time')
        plt.title('mass')

        plt.subplot(224)
        plt.plot(t, u)
        plt.grid()
        plt.ylabel('u')
        plt.xlabel('time')
        plt.title('thrust')

        plt.show()
Example #42
0
def run_demo(with_plots=True):
    """
    Demonstrate how to solve a simple parameter estimation problem 
    in form of a model of catalytic cracking of gas oil.
    
    Reference:
    Benchmarking Optimization Software with COPS 
    Elizabeth D. Dolan and Jorge J. More ARGONNE NATIONAL LABORATORY
    """

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

    # Compile the Optimica model to a JMU
    jmu_name = compile_jmu("JMExamples_opt.CatalyticCracking_opt",
        (os.path.join(curr_dir, 'files', 'JMExamples_opt.mop'), os.path.join(curr_dir, 'files', 'JMExamples.mo')))
    
    # Load the dynamic library
    cc = JMUModel(jmu_name)
    
    # optimize
    opts = cc.optimize_options()
    opts['n_e'] = 20
    res = cc.optimize(options=opts)
    
    # Extract variable profiles
    y1     = res['sys.y1']
    y2     = res['sys.y2']
    theta1 = res['sys.theta1']
    theta2 = res['sys.theta2']
    theta3 = res['sys.theta3']
    t      = res['time']
    
    y1m = [1, 0.8105, 0.6208, 0.5258, 0.4345, 0.3903,
    0.3342, 0.3034, 0.2735, 0.2405, 0.2283, 0.2071, 0.1669,
    0.1530, 0.1339, 0.1265, 0.1200, 0.0990, 0.0870, 0.077, 0.069];
    y2m = [0, 0.2, 0.2886, 0.301, 0.3215, 0.3123, 0.2716,
    0.2551, 0.2258, 0.1959, 0.1789, 0.1457, 0.1198, 0.0909,
    0.0719, 0.0561, 0.0460, 0.0280, 0.0190, 0.0140, 0.01];
    tm = [0, 0.025, 0.05, 0.075, 0.1, 0.125, 
    0.15, 0.175, 0.2, 0.225, 0.25, 0.3, 0.35, 0.4,
    0.45, 0.5, 0.55, 0.65, 0.75, 0.85, 0.95];

    assert N.abs(res.final('sys.theta1') - 11.835148) < 1e-5
    assert N.abs(res.final('sys.theta2') - 8.338887)  < 1e-5
    assert N.abs(res.final('sys.theta3') - 1.007536)  < 1e-5

    if with_plots:
        plt.figure(1)
        plt.clf()
        
        plt.subplot(211)
        plt.plot(t, y1, tm, y1m, 'x')
        plt.grid()
        plt.ylabel('y1')
        plt.xlabel('time')
        
        plt.subplot(212)
        plt.plot(t, y2, tm, y2m, 'x')
        plt.grid()
        plt.ylabel('y2')
        plt.xlabel('time')
        
        plt.show()
        
        print("\n** Optimal parameter values: **")
        print("theta1 = %f" %res.final('sys.theta1'))
        print("theta2 = %f" %res.final('sys.theta2'))
        print("theta3 = %f" %res.final('sys.theta3'))
Example #43
0
def run_demo(with_plots=True):
    """
    Demonstrate how to solve a dynamic optimization problem based on an inverted 
    pendulum system.
    """

    curr_dir = os.path.dirname(os.path.abspath(__file__))
    class_name = "Pendulum_pack.Pendulum_Opt"

    # compile JMU
    jmu_name = compile_jmu(class_name,
                           curr_dir + "/files/Pendulum_pack.mop",
                           compiler_options={'state_start_values_fixed': True})

    model = JMUModel(jmu_name)
    # optimize
    res = model.optimize()

    # Extract variable profiles
    theta = res['pend.theta']
    dtheta = res['pend.dtheta']
    x = res['pend.x']
    dx = res['pend.dx']
    u = res['u']
    t = res['time']

    assert N.abs(res.final('cost') - 1.2921683e-01) < 1e-3

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

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

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

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

        plt.subplot(313)
        plt.plot(t, u)
        plt.grid()
        plt.ylabel('u')
        plt.xlabel('time')
        plt.show()
Example #44
0
def run_demo(with_plots=True):
    """
    Demonstrate how to solve a simple parameter estimation problem.
    """
    
    # Locate model file
    curr_dir = os.path.dirname(os.path.abspath(__file__));
    model_path = curr_dir + "/files/ParameterEstimation_1.mop"
    
    # Compile the model into an FMU and JMU
    fmu = compile_fmu("ParEst.SecondOrder", model_path)
    jmu = compile_jmu("ParEst.ParEst", model_path)
    
    # Load the model
    sim_model = load_fmu(fmu)
    opt_model = JMUModel(jmu)
    
    # Simulate model with nominal parameters
    sim_res = sim_model.simulate(final_time=10)
        
    # Extract nominal trajectories
    t_sim = sim_res['time']
    x1_sim = sim_res['x1']
    x2_sim = sim_res['x2']

    # Get measurement data with 1 Hz and add measurement noise
    sim_model = load_fmu(fmu)
    meas_res = sim_model.simulate(final_time=10, options={'ncp': 10})
    x1_meas = meas_res['x1']
    noise = [0.01463904, 0.0139424, 0.09834249, 0.0768069, 0.01971631, 
             -0.03827911, 0.05266659, -0.02608245, 0.05270525, 0.04717024,
             0.0779514]
    t_meas = N.linspace(0, 10, 11)
    y_meas = x1_meas + noise

    if with_plots:
        # Plot simulation
        plt.close(1)
        plt.figure(1)
        plt.subplot(2, 1, 1)
        plt.plot(t_sim, x1_sim)
        plt.grid()
        plt.plot(t_meas, y_meas, 'x')
        plt.ylabel('x1')
        
        plt.subplot(2, 1, 2)
        plt.plot(t_sim, x2_sim)
        plt.grid()
        plt.ylabel('x2')
        plt.show()
    
    # Insert measurement data
    for i in xrange(11):
        opt_model.set('t[' + repr(i+1) + ']', t_meas[i])
        opt_model.set('y[' + repr(i+1) + ']', y_meas[i])
    
    # Set optimization options
    opts = opt_model.optimize_options()
    opts['n_e'] = 16
    
    # Optimize
    opt_res = opt_model.optimize(options=opts)

    # Extract variable profiles
    x1_opt = opt_res['sys.x1']
    x2_opt = opt_res['sys.x2']
    w_opt = opt_res.final('sys.w')
    z_opt = opt_res.final('sys.z')
    t_opt = opt_res['time']
    
    # Assert results
    assert N.abs(opt_res.final('sys.x1') - 1.) < 1e-2
    assert N.abs(w_opt - 1.05)  < 1e-2
    assert N.abs(z_opt - 0.45)   < 1e-2
    
    # Plot optimization result
    if with_plots:
        plt.close(2)
        plt.figure(2)
        plt.subplot(2, 1, 1)
        plt.plot(t_opt, x1_opt, 'g')
        plt.plot(t_sim, x1_sim)
        plt.plot(t_meas, y_meas, 'x')
        plt.grid()
        plt.subplot(2, 1, 2)
        plt.plot(t_opt, x2_opt, 'g')
        plt.grid()
        plt.plot(t_sim, x2_sim)
        plt.show()
        
        print("** Optimal parameter values: **")
        print("w = %f" % w_opt)
        print("z = %f" % z_opt)
Example #45
0
def run_demo(with_plots=True):
    """
    Demonstrate how to solve a dynamic optimization problem based on an inverted 
    pendulum system.
    """
    
    curr_dir = os.path.dirname(os.path.abspath(__file__));
    class_name = "Pendulum_pack.Pendulum_Opt"
    
    # compile JMU
    jmu_name = compile_jmu(class_name, curr_dir+"/files/Pendulum_pack.mop",
        compiler_options={'state_start_values_fixed':True})
    
    model = JMUModel(jmu_name)
    # optimize
    res = model.optimize()

    # Extract variable profiles
    theta = res['pend.theta']
    dtheta = res['pend.dtheta']
    x = res['pend.x']
    dx = res['pend.dx']
    u = res['u']
    t = res['time']
    
    assert N.abs(res.final('cost') - 1.2921683e-01) < 1e-3

    if with_plots:
        # Plot
        plt.figure(1)
        plt.clf()
        plt.subplot(211)
        plt.plot(t,theta)
        plt.grid()
        plt.ylabel('th')
        
        plt.subplot(212)
        plt.plot(t,theta)
        plt.grid()
        plt.ylabel('dth')
        plt.xlabel('time')
        plt.show()
        
        plt.figure(2)
        plt.clf()
        plt.subplot(311)
        plt.plot(t,x)
        plt.grid()
        plt.ylabel('x')
        
        plt.subplot(312)
        plt.plot(t,dx)
        plt.grid()
        plt.ylabel('dx')
        plt.xlabel('time')
        
        plt.subplot(313)
        plt.plot(t,u)
        plt.grid()
        plt.ylabel('u')
        plt.xlabel('time')
        plt.show()
Example #46
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__));
    
    # Compile the stationary initialization model into a DLL
    jmu_name = compile_jmu("CSTRLib.Components.Two_CSTRs_stat_init", 
        os.path.join(curr_dir, "files", "CSTRLib.mo"))

    # Load a JMU model instance
    init_model = JMUModel(jmu_name)
    
    # Set inputs for Stationary point A
    u1_0_A = 1
    u2_0_A = 1
    init_model.set('u1',u1_0_A)
    init_model.set('u2',u2_0_A)
    
    # Solve the DAE initialization system with Ipopt
    init_result = init_model.initialize()
    
    # Store stationary point A
    CA1_0_A = init_model.get('CA1')
    CA2_0_A = init_model.get('CA2')
    T1_0_A = init_model.get('T1')
    T2_0_A = init_model.get('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('u1',u1_0_B)
    init_model.set('u2',u2_0_B)
    
    # Solve the DAE initialization system with Ipopt
    init_result = init_model.initialize()
   
    # Stationary point B
    CA1_0_B = init_model.get('CA1')
    CA2_0_B = init_model.get('CA2')
    T1_0_B = init_model.get('T1')
    T2_0_B = init_model.get('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. 

    # Compile the Model
    jmu_name = compile_jmu("CSTR2_Opt", 
        [os.path.join(curr_dir, "files", "CSTRLib.mo"), os.path.join(curr_dir, "files", "CSTR2_Opt.mop")],
        compiler_options={'enable_variable_scaling':True, 'index_reduction':True})

    # Load the dynamic library and XML data
    model = JMUModel(jmu_name)

    # Initialize the model with parameters

    # Initialize the model to stationary point A
    model.set('cstr.two_CSTRs_Series.CA1_0',CA1_0_A)
    model.set('cstr.two_CSTRs_Series.CA2_0',CA2_0_A)
    model.set('cstr.two_CSTRs_Series.T1_0',T1_0_A)
    model.set('cstr.two_CSTRs_Series.T2_0',T2_0_A)
    
    # Set the target values to stationary point B
    model.set('u1_ref',u1_0_B)
    model.set('u2_ref',u2_0_B)
    model.set('CA1_ref',CA1_0_B)
    model.set('CA2_ref',CA2_0_B)
    
    # 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
    
    res = model.optimize(
        options={'n_e':n_e, 'hs':hs, 'n_cp':n_cp, 
            'blocking_factors':2*N.ones(n_e/2,dtype=N.int), 
            'IPOPT_options':{'tol':1e-4}})
        
    # Extract variable profiles
    CA1_res=res['cstr.two_CSTRs_Series.CA1']
    CA2_res=res['cstr.two_CSTRs_Series.CA2']
    T1_res=res['cstr.two_CSTRs_Series.T1']
    T2_res=res['cstr.two_CSTRs_Series.T2']
    u1_res=res['cstr.two_CSTRs_Series.u1']
    u2_res=res['cstr.two_CSTRs_Series.u2']
    der_u2_res=res['der_u2']
    
    CA1_ref_res=res['CA1_ref']
    CA2_ref_res=res['CA2_ref']
    
    u1_ref_res=res['u1_ref']
    u2_ref_res=res['u2_ref']
    
    cost=res['cost']
    time=res['time']

    assert N.abs(res.final('cost') - 1.4745648e+01) < 1e-3
    
    # Plot the results
    if with_plots:
        plt.figure(1)
        plt.clf()
        plt.hold(True)
        plt.subplot(211)
        plt.plot(time,CA1_res)
        plt.plot([time[0],time[-1]],[CA1_ref_res, CA1_ref_res],'--')
        plt.ylabel('Concentration reactor 1 [J/l]')
        plt.grid()
        plt.subplot(212)
        plt.plot(time,CA2_res)
        plt.plot([time[0],time[-1]],[CA2_ref_res, CA2_ref_res],'--')
        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(time,T1_res)
        plt.ylabel('Temperature reactor 1 [K]')
        plt.grid()
        plt.subplot(212)
        plt.plot(time,T2_res)
        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(time,u2_res)
        plt.ylabel('Input 2')
        plt.plot([time[0],time[-1]],[u2_ref_res, u2_ref_res],'--')
        plt.grid()
        plt.subplot(212)
        plt.plot(time,der_u2_res)
        plt.ylabel('Derivative of input 2')
        plt.xlabel('t [s]')
        plt.grid()
        plt.show()
Example #47
0
def run_demo(with_plots=True, with_blocking_factors=False):
    """ 
    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}
    }
    
    Note: This example requires Ipopt with MA27.
    """

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

    # Compile the stationary initialization model into a JMU
    jmu_name = compile_jmu("DISTLib.Binary_Dist_initial",
                           curr_dir + "/files/DISTLib.mo")

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

    # Set inputs for Stationary point A
    rr_0_A = 3.0
    init_model.set('rr', rr_0_A)
    init_result = init_model.initialize()

    # 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('y[' + str(i + 1) + ']')
        x_A[i] = init_model.get('x[' + str(i + 1) + ']')
        print '(' + str(i + 1) + ', %f, %f)' % (x_A[i], y_A[i])

    # Set inputs for stationary point B
    rr_0_B = 2.0
    init_model.set('rr', rr_0_B)
    init_result = init_model.initialize()

    # 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('y[' + str(i + 1) + ']')
        x_B[i] = init_model.get('x[' + str(i + 1) + ']')
        print '(' + str(i + 1) + ', %f, %f)' % (x_B[i], y_B[i])

    # Set up and solve an optimal control problem.

    # Compile the JMU
    jmu_name = compile_jmu(
        "DISTLib_Opt.Binary_Dist_Opt1",
        (curr_dir + "/files/DISTLib.mo", curr_dir + "/files/DISTLib_Opt.mop"),
        compiler_options={'state_start_values_fixed': True})

    # Load the dynamic library and XML data
    model = JMUModel(jmu_name)

    # Initialize the model with parameters

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

    # Set the target values to stationary point B
    model.set('rr_ref', rr_0_B)
    model.set('y1_ref', y_B[0])

    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

    # Solve the optimization problem
    if with_blocking_factors:
        # Blocking factors for control parametrization
        blocking_factors = 4 * N.ones(n_e / 4, dtype=N.int)

        opt_opts = model.optimize_options()
        opt_opts['n_e'] = n_e
        opt_opts['n_cp'] = n_cp
        opt_opts['hs'] = hs
        opt_opts['blocking_factors'] = blocking_factors

        opt_res = model.optimize(options=opt_opts)
    else:
        opt_res = model.optimize(options={'n_e': n_e, 'n_cp': n_cp, 'hs': hs})

    # Extract variable profiles
    u1_res = opt_res['rr']
    u1_ref_res = opt_res['rr_ref']
    y1_ref_res = opt_res['y1_ref']
    time = opt_res['time']

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

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

    if with_blocking_factors:
        assert N.abs(opt_res.final('cost') / 1.e1 - 2.8549683) < 1e-3
    else:
        assert N.abs(opt_res.final('cost') / 1.e1 - 2.8527469) < 1e-3

    # Plot the results
    if with_plots:
        plt.figure(1)
        plt.clf()
        plt.hold(True)
        plt.subplot(311)
        plt.title('Liquid composition')
        plt.plot(time, x_res[0])
        plt.ylabel('x1')
        plt.grid()
        plt.subplot(312)
        plt.plot(time, x_res[16])
        plt.ylabel('x17')
        plt.grid()
        plt.subplot(313)
        plt.plot(time, x_res[31])
        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(time, y_res[0])
        plt.plot(time, y1_ref_res, '--')
        plt.ylabel('y1')
        plt.grid()
        plt.subplot(312)
        plt.plot(time, y_res[16])
        plt.ylabel('y17')
        plt.grid()
        plt.subplot(313)
        plt.plot(time, y_res[31])
        plt.ylabel('y32')
        plt.grid()
        plt.xlabel('t [s]')
        plt.show()

        plt.figure(3)
        plt.clf()
        plt.hold(True)
        plt.plot(time, u1_res)
        plt.ylabel('u')
        plt.plot(time, u1_ref_res, '--')
        plt.xlabel('t [s]')
        plt.title('Reflux ratio')
        plt.grid()
        plt.show()
Example #48
0
def run_demo(with_plots=True):
    """
    This example demonstrates how to solve parameter estimation problmes.

    The data used in the example was recorded by Kristian Soltesz at the 
    Department of Automatic Control. 
    """

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

    # Load measurement data from file
    data = loadmat(curr_dir + '/files/qt_par_est_data.mat', appendmat=False)

    # Extract data series
    t_meas = data['t'][6000::100, 0] - 60
    y1_meas = data['y1_f'][6000::100, 0] / 100
    y2_meas = data['y2_f'][6000::100, 0] / 100
    y3_meas = data['y3_d'][6000::100, 0] / 100
    y4_meas = data['y4_d'][6000::100, 0] / 100
    u1 = data['u1_d'][6000::100, 0]
    u2 = data['u2_d'][6000::100, 0]

    # Plot measurements and inputs
    if with_plots:
        plt.figure(1)
        plt.clf()
        plt.subplot(2, 2, 1)
        plt.plot(t_meas, y3_meas)
        plt.title('x3')
        plt.grid()
        plt.subplot(2, 2, 2)
        plt.plot(t_meas, y4_meas)
        plt.title('x4')
        plt.grid()
        plt.subplot(2, 2, 3)
        plt.plot(t_meas, y1_meas)
        plt.title('x1')
        plt.xlabel('t[s]')
        plt.grid()
        plt.subplot(2, 2, 4)
        plt.plot(t_meas, y2_meas)
        plt.title('x2')
        plt.xlabel('t[s]')
        plt.grid()

        plt.figure(2)
        plt.clf()
        plt.subplot(2, 1, 1)
        plt.plot(t_meas, u1)
        plt.hold(True)
        plt.title('u1')
        plt.grid()
        plt.subplot(2, 1, 2)
        plt.plot(t_meas, u2)
        plt.title('u2')
        plt.xlabel('t[s]')
        plt.hold(True)
        plt.grid()

    # Build input trajectory matrix for use in simulation
    u = N.transpose(N.vstack((t_meas, u1, u2)))

    # compile FMU
    fmu_name = compile_fmu('QuadTankPack.Sim_QuadTank',
                           curr_dir + '/files/QuadTankPack.mop')

    # Load model
    model = load_fmu(fmu_name)

    # Simulate model response with nominal parameters
    res = model.simulate(input=(['u1', 'u2'], u), start_time=0., final_time=60)

    # Load simulation result
    x1_sim = res['qt.x1']
    x2_sim = res['qt.x2']
    x3_sim = res['qt.x3']
    x4_sim = res['qt.x4']
    t_sim = res['time']

    u1_sim = res['u1']
    u2_sim = res['u2']

    # Plot simulation result
    if with_plots:
        plt.figure(1)
        plt.subplot(2, 2, 1)
        plt.plot(t_sim, x3_sim)
        plt.subplot(2, 2, 2)
        plt.plot(t_sim, x4_sim)
        plt.subplot(2, 2, 3)
        plt.plot(t_sim, x1_sim)
        plt.subplot(2, 2, 4)
        plt.plot(t_sim, x2_sim)

        plt.figure(2)
        plt.subplot(2, 1, 1)
        plt.plot(t_sim, u1_sim, 'r')
        plt.subplot(2, 1, 2)
        plt.plot(t_sim, u2_sim, 'r')

    # Compile parameter optimization model
    jmu_name = compile_jmu("QuadTankPack.QuadTank_ParEst",
                           curr_dir + "/files/QuadTankPack.mop")

    # Load the model
    qt_par_est = JMUModel(jmu_name)

    # Number of measurement points
    N_meas = N.size(u1, 0)

    # Set measurement data into model
    for i in range(0, N_meas):
        qt_par_est.set("t_meas[" + ` i + 1 ` + "]", t_meas[i])
        qt_par_est.set("y1_meas[" + ` i + 1 ` + "]", y1_meas[i])
        qt_par_est.set("y2_meas[" + ` i + 1 ` + "]", y2_meas[i])

    n_e = 30  # Numer of element in collocation algorithm

    # Get an options object for the optimization algorithm
    opt_opts = qt_par_est.optimize_options()
    # Set the number of collocation points
    opt_opts['n_e'] = n_e

    opt_opts['init_traj'] = res.result_data

    # Solve parameter optimization problem
    res = qt_par_est.optimize(options=opt_opts)

    # Extract optimal values of parameters
    a1_opt = res.final("qt.a1")
    a2_opt = res.final("qt.a2")

    # Print optimal parameter values
    print('a1: ' + str(a1_opt * 1e4) + 'cm^2')
    print('a2: ' + str(a2_opt * 1e4) + 'cm^2')

    assert N.abs(a1_opt * 1.e6 - 2.6574) < 1e-3
    assert N.abs(a2_opt * 1.e6 - 2.7130) < 1e-3

    # Load state profiles
    x1_opt = res["qt.x1"]
    x2_opt = res["qt.x2"]
    x3_opt = res["qt.x3"]
    x4_opt = res["qt.x4"]
    u1_opt = res["qt.u1"]
    u2_opt = res["qt.u2"]
    t_opt = res["time"]

    # Plot
    if with_plots:
        plt.figure(1)
        plt.subplot(2, 2, 1)
        plt.plot(t_opt, x3_opt, 'k')
        plt.subplot(2, 2, 2)
        plt.plot(t_opt, x4_opt, 'k')
        plt.subplot(2, 2, 3)
        plt.plot(t_opt, x1_opt, 'k')
        plt.subplot(2, 2, 4)
        plt.plot(t_opt, x2_opt, 'k')

    # Compile second parameter estimation model
    jmu_name = compile_jmu("QuadTankPack.QuadTank_ParEst2",
                           curr_dir + "/files/QuadTankPack.mop")

    # Load model
    qt_par_est2 = JMUModel(jmu_name)

    # Number of measurement points
    N_meas = N.size(u1, 0)

    # Set measurement data into model
    for i in range(0, N_meas):
        qt_par_est2.set("t_meas[" + ` i + 1 ` + "]", t_meas[i])
        qt_par_est2.set("y1_meas[" + ` i + 1 ` + "]", y1_meas[i])
        qt_par_est2.set("y2_meas[" + ` i + 1 ` + "]", y2_meas[i])
        qt_par_est2.set("y3_meas[" + ` i + 1 ` + "]", y3_meas[i])
        qt_par_est2.set("y4_meas[" + ` i + 1 ` + "]", y4_meas[i])

    # Solve parameter estimation problem
    res_opt2 = qt_par_est2.optimize(options=opt_opts)

    # Get optimal parameter values
    a1_opt2 = res_opt2.final("qt.a1")
    a2_opt2 = res_opt2.final("qt.a2")
    a3_opt2 = res_opt2.final("qt.a3")
    a4_opt2 = res_opt2.final("qt.a4")

    # Print optimal parameter values
    print('a1:' + str(a1_opt2 * 1e4) + 'cm^2')
    print('a2:' + str(a2_opt2 * 1e4) + 'cm^2')
    print('a3:' + str(a3_opt2 * 1e4) + 'cm^2')
    print('a4:' + str(a4_opt2 * 1e4) + 'cm^2')

    assert N.abs(a1_opt2 * 1.e6 - 2.6579) < 1e-3, "Wrong value of parameter a1"
    assert N.abs(a2_opt2 * 1.e6 - 2.7038) < 1e-3, "Wrong value of parameter a2"
    assert N.abs(a3_opt2 * 1.e6 - 3.0031) < 1e-3, "Wrong value of parameter a3"
    assert N.abs(a4_opt2 * 1.e6 - 2.9342) < 1e-3, "Wrong value of parameter a4"

    # Extract state and input profiles
    x1_opt2 = res_opt2["qt.x1"]
    x2_opt2 = res_opt2["qt.x2"]
    x3_opt2 = res_opt2["qt.x3"]
    x4_opt2 = res_opt2["qt.x4"]
    u1_opt2 = res_opt2["qt.u1"]
    u2_opt2 = res_opt2["qt.u2"]
    t_opt2 = res_opt2["time"]

    # Plot
    if with_plots:
        plt.figure(1)
        plt.subplot(2, 2, 1)
        plt.plot(t_opt2, x3_opt2, 'r')
        plt.subplot(2, 2, 2)
        plt.plot(t_opt2, x4_opt2, 'r')
        plt.subplot(2, 2, 3)
        plt.plot(t_opt2, x1_opt2, 'r')
        plt.subplot(2, 2, 4)
        plt.plot(t_opt2, x2_opt2, 'r')
        plt.show()

    # Compute parameter standard deviations for case 1
    # compile JMU
    jmu_name = compile_jmu('QuadTankPack.QuadTank_Sens1',
                           curr_dir + '/files/QuadTankPack.mop')

    # Load model
    model = JMUModel(jmu_name)

    model.set('a1', a1_opt)
    model.set('a2', a2_opt)

    sens_opts = model.simulate_options()

    # Enable sensitivity computations
    sens_opts['IDA_options']['sensitivity'] = True
    #sens_opts['IDA_options']['atol'] = 1e-12

    # Simulate sensitivity equations
    sens_res = model.simulate(input=(['u1', 'u2'], u),
                              start_time=0.,
                              final_time=60,
                              options=sens_opts)

    # Get result trajectories
    x1_sens = sens_res['x1']
    x2_sens = sens_res['x2']
    dx1da1 = sens_res['dx1/da1']
    dx1da2 = sens_res['dx1/da2']
    dx2da1 = sens_res['dx2/da1']
    dx2da2 = sens_res['dx2/da2']
    t_sens = sens_res['time']

    # Compute Jacobian

    # Create a trajectory object for interpolation
    traj = TrajectoryLinearInterpolation(
        t_sens,
        N.transpose(
            N.vstack((x1_sens, x2_sens, dx1da1, dx1da2, dx2da1, dx2da2))))

    # Jacobian
    jac = N.zeros((61 * 2, 2))

    # Error vector
    err = N.zeros(61 * 2)

    # Extract Jacobian and error information
    i = 0
    for t_p in t_meas:
        vals = traj.eval(t_p)
        for j in range(2):
            for k in range(2):
                jac[i + j, k] = vals[0, 2 * j + k + 2]
            err[i] = vals[0, 0] - y1_meas[i / 2]
            err[i + 1] = vals[0, 1] - y2_meas[i / 2]
        i = i + 2

    # Compute estimated variance of measurement noice
    v_err = N.sum(err**2) / (61 * 2 - 2)

    # Compute J^T*J
    A = N.dot(N.transpose(jac), jac)

    # Compute parameter covariance matrix
    P = v_err * N.linalg.inv(A)

    # Compute standard deviations for parameters
    sigma_a1 = N.sqrt(P[0, 0])
    sigma_a2 = N.sqrt(P[1, 1])

    print "a1: " + str(
        sens_res['a1']) + ", standard deviation: " + str(sigma_a1)
    print "a2: " + str(
        sens_res['a2']) + ", standard deviation: " + str(sigma_a2)

    # Compute parameter standard deviations for case 2
    # compile JMU
    jmu_name = compile_jmu('QuadTankPack.QuadTank_Sens2',
                           curr_dir + '/files/QuadTankPack.mop')

    # Load model
    model = JMUModel(jmu_name)

    model.set('a1', a1_opt2)
    model.set('a2', a2_opt2)
    model.set('a3', a3_opt2)
    model.set('a4', a4_opt2)

    sens_opts = model.simulate_options()

    # Enable sensitivity computations
    sens_opts['IDA_options']['sensitivity'] = True
    #sens_opts['IDA_options']['atol'] = 1e-12

    # Simulate sensitivity equations
    sens_res = model.simulate(input=(['u1', 'u2'], u),
                              start_time=0.,
                              final_time=60,
                              options=sens_opts)

    # Get result trajectories
    x1_sens = sens_res['x1']
    x2_sens = sens_res['x2']
    x3_sens = sens_res['x3']
    x4_sens = sens_res['x4']

    dx1da1 = sens_res['dx1/da1']
    dx1da2 = sens_res['dx1/da2']
    dx1da3 = sens_res['dx1/da3']
    dx1da4 = sens_res['dx1/da4']

    dx2da1 = sens_res['dx2/da1']
    dx2da2 = sens_res['dx2/da2']
    dx2da3 = sens_res['dx2/da3']
    dx2da4 = sens_res['dx2/da4']

    dx3da1 = sens_res['dx3/da1']
    dx3da2 = sens_res['dx3/da2']
    dx3da3 = sens_res['dx3/da3']
    dx3da4 = sens_res['dx3/da4']

    dx4da1 = sens_res['dx4/da1']
    dx4da2 = sens_res['dx4/da2']
    dx4da3 = sens_res['dx4/da3']
    dx4da4 = sens_res['dx4/da4']
    t_sens = sens_res['time']

    # Compute Jacobian

    # Create a trajectory object for interpolation
    traj = TrajectoryLinearInterpolation(
        t_sens,
        N.transpose(
            N.vstack(
                (x1_sens, x2_sens, x3_sens, x4_sens, dx1da1, dx1da2, dx1da3,
                 dx1da4, dx2da1, dx2da2, dx2da3, dx2da4, dx3da1, dx3da2,
                 dx3da3, dx3da4, dx4da1, dx4da2, dx4da3, dx4da4))))

    # Jacobian
    jac = N.zeros((61 * 4, 4))

    # Error vector
    err = N.zeros(61 * 4)

    # Extract Jacobian and error information
    i = 0
    for t_p in t_meas:
        vals = traj.eval(t_p)
        for j in range(4):
            for k in range(4):
                jac[i + j, k] = vals[0, 4 * j + k + 4]
            err[i] = vals[0, 0] - y1_meas[i / 4]
            err[i + 1] = vals[0, 1] - y2_meas[i / 4]
            err[i + 2] = vals[0, 2] - y3_meas[i / 4]
            err[i + 3] = vals[0, 3] - y4_meas[i / 4]
        i = i + 4

    # Compute estimated variance of measurement noice
    v_err = N.sum(err**2) / (61 * 4 - 4)

    # Compute J^T*J
    A = N.dot(N.transpose(jac), jac)

    # Compute parameter covariance matrix
    P = v_err * N.linalg.inv(A)

    # Compute standard deviations for parameters
    sigma_a1 = N.sqrt(P[0, 0])
    sigma_a2 = N.sqrt(P[1, 1])
    sigma_a3 = N.sqrt(P[2, 2])
    sigma_a4 = N.sqrt(P[3, 3])

    print "a1: " + str(
        sens_res['a1']) + ", standard deviation: " + str(sigma_a1)
    print "a2: " + str(
        sens_res['a2']) + ", standard deviation: " + str(sigma_a2)
    print "a3: " + str(
        sens_res['a3']) + ", standard deviation: " + str(sigma_a3)
    print "a4: " + str(
        sens_res['a4']) + ", standard deviation: " + str(sigma_a4)
def run_demo(with_plots=True):
    """
    Optimization of a model that predicts the blood glucose levels of a 
    type-I diabetic. The objective is to predict the relationship between 
    insulin injection and blood glucose levels.
    
    Reference:
    S. M. Lynch and B. W. Bequette, Estimation based Model Predictive Control of Blood Glucose in 
    Type I Diabetes: A Simulation Study, Proc. 27th IEEE Northeast Bioengineering Conference, IEEE, 2001.
    
    S. M. Lynch and B. W. Bequette, Model Predictive Control of Blood Glucose in type I Diabetics 
    using Subcutaneous Glucose Measurements, Proc. ACC, Anchorage, AK, 2002.
    """
    
    curr_dir = os.path.dirname(os.path.abspath(__file__));

    jmu = compile_jmu("JMExamples_opt.BloodGlucose_opt_scaled",
        (os.path.join(curr_dir, 'files', 'JMExamples_opt.mop'), os.path.join(curr_dir, 'files', 'JMExamples.mo')))
    bg = JMUModel(jmu)
    res = bg.optimize()

    jmu_final = compile_jmu("JMExamples_opt.BloodGlucose_opt_scaled_final",
        (os.path.join(curr_dir, 'files', 'JMExamples_opt.mop'), os.path.join(curr_dir, 'files', 'JMExamples.mo')))
    bg_final = JMUModel(jmu_final)
    res_final = bg_final.optimize()

    # Extract variable profiles
    G = res['bc.G']
    X = res['bc.X']
    I = res['bc.I']
    D = res['bc.D']
    t = res['time']

    # Extract variable profiles of final result
    G_final = res_final['bc.G']
    X_final = res_final['bc.X']
    I_final = res_final['bc.I']
    D_final = res_final['bc.D']

    assert N.abs(res.final('bc.G') - 4.98964)       < 1e-4
    assert N.abs(res.final('bc.D') - 2.0)           < 1e-4
    assert N.abs(res_final.final('bc.G') - 4.99975) < 1e-4
    assert N.abs(res_final.final('bc.D') - 1.93274) < 1e-4
    
    if with_plots:
        plt.figure()
        
        plt.subplot(2,2,1)
        plt.plot(t, G)
        plt.title('Plasma Glucose Conc.')
        plt.grid(True)
        plt.ylabel('Plasma Glucose Conc. (mmol/L)')
        plt.xlabel('time')
        
        plt.subplot(2,2,2)
        plt.plot(t, X)
        plt.title('Plasma Insulin Conc.')
        plt.grid(True)
        plt.ylabel('Plasma Insulin Conc. (mu/L)')
        plt.xlabel('time')
        
        plt.subplot(2,2,3)
        plt.plot(t,I)
        plt.title('Plasma Insulin Conc.')
        plt.grid(True)
        plt.ylabel('Plasma Insulin Conc. (mu/L)')
        plt.xlabel('time')
        
        plt.subplot(2,2,4)
        plt.plot(t,D)
        plt.title('Insulin Infusion')
        plt.grid(True)
        plt.ylabel('Insulin Infusion')
        plt.xlabel('time')

        plt.show()

        plt.figure()
        
        plt.subplot(2,2,1)
        plt.plot(t,G_final)
        plt.title('Plasma Glucose Conc. final')
        plt.grid(True)
        plt.ylabel('Plasma Glucose Conc. (mmol/L)')
        plt.xlabel('time')
        
        plt.subplot(2,2,2)
        plt.plot(t,X_final)
        plt.title('Plasma Insulin Conc. final')
        plt.grid(True)
        plt.ylabel('Plasma Insulin Conc. (mu/L)')
        plt.xlabel('time')
        
        plt.subplot(2,2,3)
        plt.plot(t,I_final)
        plt.title('Plasma Insulin Conc. final')
        plt.grid(True)
        plt.ylabel('Plasma Insulin Conc. (mu/L)')
        plt.xlabel('time')
        
        plt.subplot(2,2,4)
        plt.plot(t,D_final)
        plt.title('Insulin Infusion final')
        plt.grid(True)
        plt.ylabel('Insulin Infusion')
        plt.xlabel('time')
        
        plt.show()
Example #50
0
def run_demo(with_plots=True):
    """
    Optimization of a model that predicts the blood glucose levels of a 
    type-I diabetic. The objective is to predict the relationship between 
    insulin injection and blood glucose levels.
    
    Reference:
    S. M. Lynch and B. W. Bequette, Estimation based Model Predictive Control of Blood Glucose in 
    Type I Diabetes: A Simulation Study, Proc. 27th IEEE Northeast Bioengineering Conference, IEEE, 2001.
    
    S. M. Lynch and B. W. Bequette, Model Predictive Control of Blood Glucose in type I Diabetics 
    using Subcutaneous Glucose Measurements, Proc. ACC, Anchorage, AK, 2002.
    """

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

    jmu = compile_jmu("JMExamples_opt.BloodGlucose_opt_scaled",
                      (os.path.join(curr_dir, 'files', 'JMExamples_opt.mop'),
                       os.path.join(curr_dir, 'files', 'JMExamples.mo')))
    bg = JMUModel(jmu)
    res = bg.optimize()

    jmu_final = compile_jmu(
        "JMExamples_opt.BloodGlucose_opt_scaled_final",
        (os.path.join(curr_dir, 'files', 'JMExamples_opt.mop'),
         os.path.join(curr_dir, 'files', 'JMExamples.mo')))
    bg_final = JMUModel(jmu_final)
    res_final = bg_final.optimize()

    # Extract variable profiles
    G = res['bc.G']
    X = res['bc.X']
    I = res['bc.I']
    D = res['bc.D']
    t = res['time']

    # Extract variable profiles of final result
    G_final = res_final['bc.G']
    X_final = res_final['bc.X']
    I_final = res_final['bc.I']
    D_final = res_final['bc.D']

    assert N.abs(res.final('bc.G') - 4.98964) < 1e-4
    assert N.abs(res.final('bc.D') - 2.0) < 1e-4
    assert N.abs(res_final.final('bc.G') - 4.99975) < 1e-4
    assert N.abs(res_final.final('bc.D') - 1.93274) < 1e-4

    if with_plots:
        plt.figure()

        plt.subplot(2, 2, 1)
        plt.plot(t, G)
        plt.title('Plasma Glucose Conc.')
        plt.grid(True)
        plt.ylabel('Plasma Glucose Conc. (mmol/L)')
        plt.xlabel('time')

        plt.subplot(2, 2, 2)
        plt.plot(t, X)
        plt.title('Plasma Insulin Conc.')
        plt.grid(True)
        plt.ylabel('Plasma Insulin Conc. (mu/L)')
        plt.xlabel('time')

        plt.subplot(2, 2, 3)
        plt.plot(t, I)
        plt.title('Plasma Insulin Conc.')
        plt.grid(True)
        plt.ylabel('Plasma Insulin Conc. (mu/L)')
        plt.xlabel('time')

        plt.subplot(2, 2, 4)
        plt.plot(t, D)
        plt.title('Insulin Infusion')
        plt.grid(True)
        plt.ylabel('Insulin Infusion')
        plt.xlabel('time')

        plt.show()

        plt.figure()

        plt.subplot(2, 2, 1)
        plt.plot(t, G_final)
        plt.title('Plasma Glucose Conc. final')
        plt.grid(True)
        plt.ylabel('Plasma Glucose Conc. (mmol/L)')
        plt.xlabel('time')

        plt.subplot(2, 2, 2)
        plt.plot(t, X_final)
        plt.title('Plasma Insulin Conc. final')
        plt.grid(True)
        plt.ylabel('Plasma Insulin Conc. (mu/L)')
        plt.xlabel('time')

        plt.subplot(2, 2, 3)
        plt.plot(t, I_final)
        plt.title('Plasma Insulin Conc. final')
        plt.grid(True)
        plt.ylabel('Plasma Insulin Conc. (mu/L)')
        plt.xlabel('time')

        plt.subplot(2, 2, 4)
        plt.plot(t, D_final)
        plt.title('Insulin Infusion final')
        plt.grid(True)
        plt.ylabel('Insulin Infusion')
        plt.xlabel('time')

        plt.show()