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