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()
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()
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()
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()
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): """ 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
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): """ 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()
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()
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()
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
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
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()
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()
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()
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()
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_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
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)
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)
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()
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')
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'))
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()
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()
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')
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()
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()
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()
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()
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): """ 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()
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()
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()
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()
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()
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()
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()
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'))
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()
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)
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()
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()
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()
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()
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()