def test_duals(): file_path = os.path.join(get_files_path(), 'Modelica', 'TestBackTracking.mop') op = transfer_optimization_problem("TestDuals", file_path) n_e = 10 n_cp = 1 opts = op.optimize_options() opts['n_e'] = n_e opts['n_cp'] = n_cp solver = op.prepare_optimization(options=opts) check_roundtrip(solver) solver.optimize() check_solution(solver) h = 1.0/n_e # Strange things seem to happen with the first two entries in the duals; # skip them in the comparison. # Interaction with initial constraints? l = solver.get_constraint_duals('path_ineq', tik=False) t, i, k = solver.get_constraint_points('path_ineq') l0 = t*h assert N.max(N.abs((l.ravel()-l0)[2:])) < 1e-12 l = solver.get_bound_duals('y', tik=False) t, i, k = solver.get_variable_points('y') l0 = (t-2)*h assert N.max(N.abs((l.ravel()-l0)[2:])) < 1e-12
def test_update_dependent_parameter(): file_path = os.path.join(get_files_path(), 'Modelica', 'TestWarmStart.mop') compiler_options={"eliminate_alias_parameters": True} op = transfer_optimization_problem("TestDependentParameter", file_path, compiler_options=compiler_options) solver = op.prepare_optimization() res = solver.optimize() assert solver.get('p') == 1 assert solver.get('q') == -1 assert solver.get('r') == 1 assert solver.get('s') == 1 assert N.abs(res.final('x') - N.exp(-1)) < 1e-8 solver.set('p', 2) assert solver.get('p') == 2 assert solver.get('q') == -2 assert solver.get('r') == 2 assert solver.get('s') == 4 res = solver.optimize() assert solver.get('p') == 2 assert solver.get('q') == -2 assert N.abs(res.final('x') - N.exp(-2)) < 1e-8
def __init__(self, class_name, filename, modelica_model): compiler_options = {'equation_sorting': True, 'automatic_tearing': True} self.program = transfer_optimization_problem(class_name, filename, compiler_options=compiler_options, accept_model=True) self.program.eliminateAlgebraics() self.x = [self.program.getVariable(name).getVar() for name in modelica_model.x.names] self.y = [self.program.getVariable(name).getVar() for name in modelica_model.y.names] self.u = [self.program.getVariable(name).getVar() for name in modelica_model.u.names] # self.dx_dt = [self.program.getVariable(name).getMyDerivativeVariable() # for name in self.program.getVariables(self.program.DERIVATIVE)] self.dx_dt = [self.program.getVariable(name).getMyDerivativeVariable().getVar() for name in modelica_model.x.names] self.algebraic = [g.getVar() for g in self.program.getVariables(self.program.REAL_ALGEBRAIC)] if modelica_model._all_parameters is not None: self.parameters = [self.program.getVariable(name).getVar() for name in modelica_model._all_parameters.names] else: self.parameters = None self.implicit = self.ImplicitDae(self) self.f_xu = self.init_f_xu(modelica_model)
def run_optimization(sim_res, opt_problem = 'ElectricNetwork.BuildingMngmtOpt_E'): """ This function runs an optimization problem """ from pyjmi.optimization.casadi_collocation import MeasurementData from collections import OrderedDict # Get the weather data for the building model time = np.linspace(0, 3600*24*6, 24*6*6, True) (Tamb, Tgnd, sRadS, sRadN, sRadW, sRadE, ihg, price) = getData(time, plot = False) # get current directory curr_dir = os.path.dirname(os.path.abspath(__file__)); # compile FMU path = os.path.join(curr_dir,"..","Models","ElectricalNetwork.mop") op_model = transfer_optimization_problem(opt_problem, path, compiler_options={"enable_variable_scaling":True}) # Get the inputs that should be eliminated from the optimization variables eliminated = OrderedDict() data_ihg = np.vstack([time, ihg]) eliminated['u[1]'] = data_ihg data_Tamb = np.vstack([time, Tamb]) eliminated['u[2]'] = data_Tamb data_Tgnd = np.vstack([time, Tgnd]) eliminated['u[3]'] = data_Tgnd data_sRadE = np.vstack([time, sRadE]) eliminated['u[4]'] = data_sRadE data_sRadN = np.vstack([time, sRadN]) eliminated['u[5]'] = data_sRadN data_sRadS = np.vstack([time, sRadS]) eliminated['u[6]'] = data_sRadS data_sRadW = np.vstack([time, sRadW]) eliminated['u[7]'] = data_sRadW data_price = np.vstack([time, price]) eliminated['price'] = data_price measurement_data = MeasurementData(eliminated = eliminated) # define the optimization problem opts = op_model.optimize_options() opts['n_e'] = 60*6 opts['measurement_data'] = measurement_data opts['init_traj'] = sim_res.result_data # Get the results of the optimization res = op_model.optimize(options = opts) plot_sim_res(res) return res
def _setup_MPC_solver(self, file_path, opt_name, dt, horizon, n_e, par_values, constr_viol_costs={}, mpc_options={}): op = transfer_optimization_problem( opt_name, file_path, compiler_options={'state_initial_equations': True}) op.set(par_values.keys(), par_values.values()) opt_opts = op.optimize_options() opt_opts['n_e'] = n_e opt_opts['n_cp'] = 2 opt_opts['IPOPT_options']['tol'] = 1e-10 opt_opts['IPOPT_options']['print_time'] = False if 'IPOPT_options' in mpc_options: opt_opts['IPOPT_options'].update(mpc_options['IPOPT_options']) for key in mpc_options: if key != 'IPOPT_options': opt_opts[key] = mpc_options[key] self.solver = MPC(op, opt_opts, dt, horizon, constr_viol_costs=constr_viol_costs)
def compile_OPT(self, model): problem = jmi.transfer_optimization_problem( model, self.paths, compiler_options=self.options, compiler_log_level='error') return problem
def test_nlp_variable_indices(): file_path = os.path.join(get_files_path(), 'Modelica', 'TestBackTracking.mop') op = transfer_optimization_problem("TestVariableTypes", file_path) n_e = 10 opts = op.optimize_options() opts['n_e'] = n_e opts['variable_scaling'] = False opts['blocking_factors'] = BlockingFactors({'u_bf':[1]*n_e}) res = op.optimize(options = opts) t = res['time'] solver = res.get_solver() check_roundtrip(solver) check_solution(solver) xx = solver.collocator.primal_opt var_names = ['x', 'x2', 'w', 'w2', 'u_cont', 'u_bf', 'p'] for name in var_names: inds, tv, i, k = solver.get_nlp_variable_indices(name) tinds = N.searchsorted((t[:-1]+t[1:])/2, tv) assert N.max(N.abs(t[tinds] - tv)) < 1e-12 if name == 'u_bf': # workaround for the fact that res uses the left value of u_bf # at the discontinuity point, and back tracking uses the right tinds += 1 assert N.max(N.abs(res[name][tinds] - xx[inds])) < 1e-12
def compile_OPT(self, model): problem = jmi.transfer_optimization_problem( model, self.paths, compiler_options=self.options, compiler_log_level='error' ) return problem
def test_warm_start(): file_path = os.path.join(get_files_path(), 'Modelica', 'VDP.mop') op = transfer_optimization_problem("VDP_pack.VDP_Opt2", file_path) opts = op.optimize_options() var_names = ('x1', 'x2', 'u') # Optimize without going through prepare_optimization op.set('p1', 1) # Should already be set to 1 res1c = op.optimize(options=opts) assert res1c.final('p1') == 1 op.set('p1', 2) res2c = op.optimize(options=opts) assert res2c.final('p1') == 2 # Make sure that the parameter changes have an effect assert result_distance(res1c, res2c, var_names) > 1e-2 # Optimize through prepare_optimization solver = op.prepare_optimization(options=opts) assert solver.get('p1') == 2 # Should reflect setting in op when prepare_optimization was done solver.set('p1', 1) assert solver.get('p1') == 1 res1w = solver.optimize() assert res1w.final('p1') == 1 assert result_distance(res1c, res1w, var_names) < 1e-6 res1w_stats = res1w.get_solver_statistics() solver.set('p1', 2) assert solver.get('p1') == 2 solver.set_warm_start(True) set_warm_start_options(solver, push = 1e-5) res2w = solver.optimize() assert res2w.final('p1') == 2 assert result_distance(res2c, res2w, var_names) < 1e-6 res2w2 = solver.optimize() assert res2w2.final('p1') == 2 assert result_distance(res2c, res2w2, var_names) < 1e-6 # Check that the results haven't changed assert result_distance(res1c, res1w, var_names) < 1e-6 assert result_distance(res2c, res2w, var_names) < 1e-6 assert result_distance(res2c, res2w2, var_names) < 1e-6 assert res1w_stats == res1w.get_solver_statistics() # Check that warm starting helps convergence speed # Warm starting should not need too many iterations assert res2w.get_solver_statistics()[1] < 40 # Warm starting from the right result should need very few iterations assert res2w2.get_solver_statistics()[1] < 4
def test_times(): file_path = os.path.join(get_files_path(), 'Modelica', 'VDP.mop') op = transfer_optimization_problem("VDP_pack.VDP_Opt2", file_path) resOp = op.optimize() assert abs(resOp.times['init']+resOp.times['update']+resOp.times['sol']+resOp.times['post_processing'] - resOp.times['tot']) <1e-4 solver = op.prepare_optimization() res1 = solver.optimize() res2 = solver.optimize() assert abs(res1.times['update']+res1.times['sol']+res1.times['post_processing'] - res1.times['tot']) <1e-4 assert abs(res2.times['init'] - res2.times['init']) < 1e-4
def test_get_equations(): file_path = os.path.join(get_files_path(), 'Modelica', 'TestBackTracking.mop') op = transfer_optimization_problem("TestEquations", file_path) eqkeys = {'initial':'sin', 'dae':'der', 'path_eq':'sqrt', 'path_ineq':'cos', 'point_eq':'tan', 'point_ineq':'exp'} solver = op.prepare_optimization() check_roundtrip(solver) for (eqtype, key) in eqkeys.iteritems(): eqs = solver.get_equations(eqtype) assert len(eqs) == 1 assert key in repr(eqs[0])
def _compile_transfer_problem(self): '''Compile the initialization model and transfer the optimziation problem. ''' # Compile the optimization initializaiton model self.fmupath = compile_fmu(self.mopmodelpath + '_initialize', \ self.moppath, \ compiler_options = {'extra_lib_dirs':self.Model.libraries}) kwargs = {} kwargs['fmupath'] = self.fmupath self._create_fmu(kwargs) # Transfer optimization problem to casADi self.opt_problem = transfer_optimization_problem(self.mopmodelpath + '_optimize', \ self.moppath, \ compiler_options = {'extra_lib_dirs':self.Model.libraries})
def test_find_nonfinite_jacobian_entry(): file_path = os.path.join(get_files_path(), 'Modelica', 'TestBackTracking.mop') op = transfer_optimization_problem("TestJacInf", file_path) solver = op.prepare_optimization() check_roundtrip(solver) for point in ('init', 'opt'): if point == 'opt': solver.optimize() entries = solver.find_nonfinite_jacobian_entries(point=point) assert len(entries) == 1 (eqtype, eqind, var), = entries # get the only entry and unpack it assert eqtype == 'dae' assert var == op.getVariable('x2') assert 'sqrt' in str(solver.get_equations(eqtype,eqind))
def test_code_gen(): var_names = ('x1', 'x2', 'u') func_names = ['nlp_test', 'grad_f_test', 'jac_g_test', 'hess_lag_test'] exts = ['.c'] if os.name == 'nt': exts.append('.dll') else: exts.append('.so') file_path = os.path.join(get_files_path(), 'Modelica', 'VDP.mop') op = transfer_optimization_problem("VDP_pack.VDP_Opt2", file_path) opt_opts = op.optimize_options() # Result for comparison: don't use generated code res0 = op.optimize(options=opt_opts) # First solver: generate and compile new C code solver1 = op.prepare_optimization(options=opt_opts) solver1.enable_codegen('test') # Check that files were created and compiled, and store the # time that they were last changed file_ctimes = {} for func_name in func_names: for ext in exts: file_name = func_name + ext assert os.path.isfile(file_name) file_ctimes[file_name] = os.stat(file_name).st_ctime res1 = solver1.optimize() # Second solver: use existing code generated by the first solver solver2 = op.prepare_optimization(options=opt_opts) solver2.enable_codegen('test') # Check that files weren't modified for func_name in func_names: for ext in exts: file_name = func_name + ext assert file_ctimes[file_name] == os.stat(file_name).st_ctime res2 = solver2.optimize() # Check that all solvers gave the same result assert result_distance(res0, res1, var_names) < 1e-6 assert result_distance(res0, res2, var_names) < 1e-6
def check_changed_input(model_name, signal_name, ext_data_constructor, eliminate_algebraics=False, result_mode='collocation_points'): file_path = os.path.join(get_files_path(), 'Modelica', 'TestWarmStart.mop') if eliminate_algebraics: compiler_options = { 'equation_sorting': True, 'automatic_tearing': False } else: compiler_options = {} op = transfer_optimization_problem(model_name, file_path, compiler_options=compiler_options) if eliminate_algebraics: op.eliminateAlgebraics() var_names = ('x', 'u', 'xdot') input1 = OrderedDict() data1 = N.vstack([[0, 1], [0, 1]]) input1[signal_name] = data1 opts1 = op.optimize_options() opts1['external_data'] = ext_data_constructor(input1) opts1['result_mode'] = result_mode input2 = OrderedDict() data2 = N.vstack([[0, 1], [1, 0]]) input2[signal_name] = data2 opts2 = op.optimize_options() opts2['external_data'] = ext_data_constructor(input2) opts2['result_mode'] = result_mode solver = op.prepare_optimization(options=opts1) res1 = solver.optimize() solver.set_external_variable_data(signal_name, data2) res2b = solver.optimize() res2 = op.optimize(options=opts2) assert result_distance(res1, res2, var_names) > 1e-2 assert result_distance(res2, res2b, var_names) < 1e-6
def test_set_init_traj(): """Test that OptimizationSolver.set_init_traj works""" file_path = os.path.join(get_files_path(), 'Modelica', 'VDP.mop') op = transfer_optimization_problem("VDP_pack.VDP_Opt2", file_path) res0 = op.optimize() opts = op.optimize_options() opts["IPOPT_options"]["max_iter"] = 0 solver = op.prepare_optimization(options = opts) res1 = solver.optimize() solver.set_init_traj(res0) res2 = solver.optimize() assert(N.linalg.norm(res2['x1']-res0['x1'])) <= 1e-8 assert(N.linalg.norm(res2['x2']-res0['x2'])) <= 1e-8 assert(N.linalg.norm(res1['x1']-res0['x1'])) >= 1e-4 assert(N.linalg.norm(res1['x2']-res0['x2'])) >= 1e-4
def run_demo(with_plots=True): """ Demonstrate how to solve a minimum time dynamic optimization problem based on a Van der Pol oscillator system. """ file_paths = (os.path.join(get_files_path(), "JMExamples_opt.mop"), os.path.join(get_files_path(), "JMExamples.mo")) vdp = transfer_optimization_problem("JMExamples_opt.VDP_Opt_Min_Time", file_paths) res = vdp.optimize() # Extract variable profiles x1 = res['x1'] x2 = res['x2'] u = res['u'] 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_demo(with_plots=True): """ Demonstrate how to solve a minimum time dynamic optimization problem based on a Van der Pol oscillator system. """ file_paths = (os.path.join(get_files_path(), "JMExamples_opt.mop"), os.path.join(get_files_path(), "JMExamples.mo")) vdp = transfer_optimization_problem("JMExamples_opt.VDP_Opt_Min_Time", file_paths) res = vdp.optimize() # Extract variable profiles x1=res['x1'] x2=res['x2'] u=res['u'] 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 test_linearize_dae_with_simresult(self): from pyjmi.casadi_interface import linearize_dae_with_simresult from pyjmi import transfer_optimization_problem sim_model = load_fmu(self.vdp_sim) res = sim_model.simulate() model = transfer_optimization_problem( "VDP_pack.VDP_Opt_Simple", os.path.join(path_to_mofiles, "VDP.mop")) [E, A, B, C, D, G, h, RefPoint] = linearize_dae_with_simresult(model, 0.0, res) nose.tools.assert_almost_equal(A[0, 0], 0.0) nose.tools.assert_almost_equal(A[0, 1], -1.0) nose.tools.assert_almost_equal(A[1, 0], 1.0) nose.tools.assert_almost_equal(A[1, 1], 0.0) nose.tools.assert_almost_equal(B[0, 0], 1.0) nose.tools.assert_almost_equal(B[1, 0], 0.0)
def run_demo(with_plots=True): n_e = 20 delay_n_e = 5 horizon = 1.0 delay = horizon * delay_n_e / n_e # Compile and load optimization problem file_path = os.path.join(get_files_path(), "DelayedFeedbackOpt.mop") opt = transfer_optimization_problem("DelayTest", file_path) # Set value for u2(t) when t < delay opt.getVariable('u2').setAttribute('initialGuess', 0.25) # Set algorithm options opts = opt.optimize_options() opts['n_e'] = n_e # Set delayed feedback from u1 to u2 opts['delayed_feedback'] = {'u2': ('u1', delay_n_e)} # Optimize res = opt.optimize(options=opts) # Extract variable profiles x_res = res['x'] u1_res = res['u1'] u2_res = res['u2'] time_res = res['time'] # Plot results if with_plots: plt.plot(time_res, x_res, time_res, u1_res, time_res, u2_res) plt.hold(True) plt.plot(time_res + delay, u1_res, '--') plt.hold(False) plt.legend(('x', 'u1', 'u2', 'delay(u1)')) plt.show()
#~ caus_opts['ad_hoc_scale'] = True #~ caus_opts['inline'] = False #~ caus_opts['closed_form'] = True #~ caus_opts['inline_solved'] = True if problem == "simple": uneliminable = [] if source == "strings": eqs_str = ['$x + y = 2$', '$x = 1$'] varis_str = ['$x$', '$y$'] edg_indices = [(0, 0), (0, 1), (1, 0)] else: class_name = "Simple_Opt" file_paths = "simple.mop" opts = {'eliminate_alias_variables': True, 'generate_html_diagnostics': True, 'equation_sorting': True, 'variability_propagation': False} op = transfer_optimization_problem(class_name, file_paths, compiler_options=opts) #~ op.set('p', 0.0) #~ caus_opts['uneliminable'] = ["y"] opt_opts = op.optimize_options() opt_opts['IPOPT_options']['linear_solver'] = "ma57" #~ opt_opts['order'] = "random" opt_opts['n_e'] = 50 #~ opt_opts['n_cp'] = 2 opt_opts['named_vars'] = True #~ np.random.seed(1) #~ opt_opts['write_scaled_result'] = True #~ caus_opts['linear_solver'] = "symbolicqr" caus_opts['tear_vars'] = ["y3"] caus_opts['tear_res'] = [2] elif problem == "triangular":
def run_optimization(sim_res, opt_problem = 'ElectricNetwork.BuildingMngmtOpt_E', use_battery = False, fixpars = None, n_e = 24): """ This function runs an optimization problem """ from pyjmi.optimization.casadi_collocation import MeasurementData from collections import OrderedDict # Get the weather data for the building model time = np.linspace(0, 3600*24*6, 24*6*6, True) (Tamb, Tgnd, sRadS, sRadN, sRadW, sRadE, ihg, price) = getData(time, plot = False) P_batt = 0.0*np.ones(len(time)) # get current directory curr_dir = os.path.dirname(os.path.abspath(__file__)); # compile FMU path = os.path.join(curr_dir,"..","Models","ElectricalNetwork.mop") op_model = transfer_optimization_problem(opt_problem, path, compiler_options={"enable_variable_scaling":True}) # Change parameters depending on the case if fixpars: # Set the values for the parameters op_model.set(fixpars.keys(),fixpars.values()) # Get the inputs that should be eliminated from the optimization variables eliminated = OrderedDict() data_ihg = np.vstack([time, ihg]) eliminated['u[1]'] = data_ihg data_Tamb = np.vstack([time, Tamb]) eliminated['u[2]'] = data_Tamb data_Tgnd = np.vstack([time, Tgnd]) eliminated['u[3]'] = data_Tgnd data_sRadE = np.vstack([time, sRadE]) eliminated['u[4]'] = data_sRadE data_sRadN = np.vstack([time, sRadN]) eliminated['u[5]'] = data_sRadN data_sRadS = np.vstack([time, sRadS]) eliminated['u[6]'] = data_sRadS data_sRadW = np.vstack([time, sRadW]) eliminated['u[7]'] = data_sRadW data_price = np.vstack([time, price]) eliminated['price'] = data_price if not use_battery: data_Pbatt = np.vstack([time, P_batt]) eliminated['P_batt'] = data_Pbatt measurement_data = MeasurementData(eliminated = eliminated) # define the optimization problem opts = op_model.optimize_options() opts['n_e'] = n_e opts['measurement_data'] = measurement_data opts['init_traj'] = sim_res.result_data opts["IPOPT_options"]["max_iter"] = 10000 # Get the results of the optimization res = op_model.optimize(options = opts) plot_sim_res(res) return res
rad2deg = 180. / (2*np.pi) du_bounds = {'delta_u': 2. / rad2deg} bf = BlockingFactors(factors, du_bounds=du_bounds) opt_opts['blocking_factors'] = bf # Set up optimization problems for each scheme compiler_opts = {'generate_html_diagnostics': True, 'state_initial_equations': True} ops[problem] = {} solvers[problem] = {} n_algs[problem] = {} dns_tol = 5 # Scheme 0 scheme = "0" if scheme in schemes[problem]: op = transfer_optimization_problem(class_name, file_paths, compiler_options=compiler_opts) ops[problem][scheme] = op solvers[problem][scheme] = op.prepare_optimization(options=opt_opts) n_algs[problem][scheme] = len([var for var in op.getVariables(op.REAL_ALGEBRAIC) if not var.isAlias()]) # Scheme 1 scheme = "1" if scheme in schemes[problem]: op = transfer_optimization_problem(class_name, file_paths, compiler_options=compiler_opts) caus_opts['dense_tol'] = np.inf caus_opts['tearing'] = False op = sp.BLTOptimizationProblem(op, caus_opts) ops[problem][scheme] = op solvers[problem][scheme] = op.prepare_optimization(options=opt_opts) n_algs[problem][scheme] = len([var for var in op.getVariables(op.REAL_ALGEBRAIC) if not var.isAlias()])
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 problem is solved using the CasADi-based collocation algorithm. The steps performed correspond to those demonstrated in example pyjmi.examples.cstr, where the same problem is solved using the default JMI algorithm. FMI is used for initialization and simulation purposes. The following steps are demonstrated in this example: 1. How to solve the initialization problem. The initialization model has 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. 2. How to generate an initial guess for a direct collocation method by means of simulation with a constant input. The trajectories resulting from the 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. 4. Finally the system is simulated using the optimal control profile. This step is important in order to verify that the approximation in the transcription step is sufficiently accurate. """ ### 1. Solve the initialization problem # Locate the Modelica and Optimica code file_path = os.path.join(get_files_path(), "CSTR.mop") # Compile the stationary initialization model into an FMU init_fmu = compile_fmu("CSTR.CSTR_Init", file_path) # Load the FMU init_model = load_fmu(init_fmu) # Set input for Stationary point A Tc_0_A = 250 init_model.set('Tc', Tc_0_A) # Solve the initialization problem using FMI init_model.initialize() # Store stationary point A [c_0_A, T_0_A] = init_model.get(['c', 'T']) # Print some data for stationary point A print(' *** Stationary point A ***') print('Tc = %f' % Tc_0_A) print('c = %f' % c_0_A) print('T = %f' % T_0_A) # Set inputs for Stationary point B init_model.reset() # reset the FMU so that we can initialize it again Tc_0_B = 280 init_model.set('Tc', Tc_0_B) # Solve the initialization problem using FMI init_model.initialize() # Store stationary point B [c_0_B, T_0_B] = init_model.get(['c', 'T']) # Print some data for stationary point B print(' *** Stationary point B ***') print('Tc = %f' % Tc_0_B) print('c = %f' % c_0_B) print('T = %f' % T_0_B) ### 2. Compute initial guess trajectories by means of simulation # Compile the optimization initialization model init_sim_fmu = compile_fmu("CSTR.CSTR_Init_Optimization", file_path) # Load the model init_sim_model = load_fmu(init_sim_fmu) # Set initial and reference values 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) # Simulate with constant input Tc init_res = init_sim_model.simulate(start_time=0., final_time=150.) # Extract variable profiles t_init_sim = init_res['time'] c_init_sim = init_res['cstr.c'] T_init_sim = init_res['cstr.T'] Tc_init_sim = init_res['cstr.Tc'] + N.zeros(t_init_sim.shape) # make Tc_init_sim be a vector # Plot the initial guess trajectories if with_plots: plt.close(1) plt.figure(1) plt.hold(True) plt.subplot(3, 1, 1) plt.plot(t_init_sim, c_init_sim) plt.grid() plt.ylabel('Concentration') plt.title('Initial guess obtained by simulation') plt.subplot(3, 1, 2) plt.plot(t_init_sim, T_init_sim) plt.grid() plt.ylabel('Temperature') plt.subplot(3, 1, 3) plt.plot(t_init_sim, Tc_init_sim) plt.grid() plt.ylabel('Cooling temperature') plt.xlabel('time') plt.show() ### 3. Solve the optimal control problem # Compile and load optimization problem op = transfer_optimization_problem("CSTR.CSTR_Opt2", file_path) # Set reference values op.set('Tc_ref', Tc_0_B) op.set('c_ref', float(c_0_B)) op.set('T_ref', float(T_0_B)) # Set initial values op.set('cstr.c_init', float(c_0_A)) op.set('cstr.T_init', float(T_0_A)) # Set options opt_opts = op.optimize_options() opt_opts['n_e'] = 19 # Number of elements opt_opts['init_traj'] = init_res.result_data opt_opts['nominal_traj'] = init_res.result_data opt_opts['IPOPT_options']['tol'] = 1e-10 # Solve the optimal control problem res = op.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'][0] # extract constant value as first element T_ref = res['T_ref'][0] Tc_ref = res['Tc_ref'][0] # Verify solution for testing purposes try: import casadi except: pass else: cost = float(res.solver.solver.output(casadi.NLP_SOLVER_F)) assert(N.abs(cost/1.e3 - 1.86162353098) < 1e-3) # Plot the results if with_plots: plt.close(2) plt.figure(2) plt.hold(True) plt.subplot(3, 1, 1) plt.plot(time_res, c_res) plt.plot([time_res[0], time_res[-1]], [c_ref, c_ref], '--') plt.grid() plt.ylabel('Concentration') plt.title('Optimized trajectories') 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() ### 4. Simulate to verify the optimal solution # Compile model sim_fmu = compile_fmu("CSTR.CSTR", file_path) # Load model sim_model = load_fmu(sim_fmu) # Get optimized input (_, opt_input) = res.solver.get_opt_input() # Set initial values sim_model.set('c_init', c_0_A) sim_model.set('T_init', T_0_A) # Simulate using optimized input sim_opts = sim_model.simulate_options() sim_opts['CVode_options']['rtol'] = 1e-6 sim_opts['CVode_options']['atol'] = 1e-8 res = sim_model.simulate(start_time=0., final_time=150., input=('Tc', opt_input), options=sim_opts) # Extract variable profiles c_sim = res['c'] T_sim = res['T'] Tc_sim = res['Tc'] time_sim = res['time'] # Verify results N.testing.assert_array_less(abs(c_res[-1] - c_sim[-1])/c_res[-1], 5e-1) # Plot the results if with_plots: plt.close(3) plt.figure(3) plt.hold(True) plt.subplot(3, 1, 1) plt.plot(time_res, c_res, '--') plt.plot(time_sim, c_sim) plt.legend(('optimized', 'simulated')) plt.grid(True) plt.ylabel('Concentration') plt.title('Verification') plt.subplot(3, 1, 2) plt.plot(time_res, T_res, '--') plt.plot(time_sim, T_sim) plt.grid(True) plt.ylabel('Temperature') plt.subplot(3, 1, 3) plt.plot(time_res, Tc_res, '--') plt.plot(time_sim, Tc_sim) plt.grid(True) plt.ylabel('Cooling temperature') plt.xlabel('time') plt.show()
def run_optimization(sim_res, stop_time=3600 * 24 * 6, opt_problem='ElectricNetwork.OptimizationDistrict_E', n_e=12): """ This function runs an optimization problem """ from pyjmi.optimization.casadi_collocation import MeasurementData from collections import OrderedDict # Get the weather data and other inputs for the building model time = np.linspace(0, stop_time, 36 * stop_time / 3600, True) (Tamb, Tgnd, sRadS, sRadN, sRadW, sRadE, ihg_1, ihg_2, ihg_3, price) = getData(time, plot=False) # get current directory curr_dir = os.path.dirname(os.path.abspath(__file__)) # compile FMU path = os.path.join(curr_dir, "..", "Models", "ElectricalNetwork.mop") op_model = transfer_optimization_problem( opt_problem, path, compiler_options={"enable_variable_scaling": True}) # Get the inputs that should be eliminated from the optimization variables eliminated = OrderedDict() data_ihg_1 = np.vstack([time, ihg_1]) eliminated['ihg_1'] = data_ihg_1 data_ihg_2 = np.vstack([time, ihg_2]) eliminated['ihg_2'] = data_ihg_2 data_ihg_3 = np.vstack([time, ihg_3]) eliminated['ihg_3'] = data_ihg_3 data_Tamb = np.vstack([time, Tamb]) eliminated['Tamb'] = data_Tamb data_Tgnd = np.vstack([time, Tgnd]) eliminated['Tgnd'] = data_Tgnd data_sRadE = np.vstack([time, sRadE]) eliminated['solGlobFac_E'] = data_sRadE data_sRadN = np.vstack([time, sRadN]) eliminated['solGlobFac_N'] = data_sRadN data_sRadS = np.vstack([time, sRadS]) eliminated['solGlobFac_S'] = data_sRadS data_sRadW = np.vstack([time, sRadW]) eliminated['solGlobFac_W'] = data_sRadW data_price = np.vstack([time, price]) eliminated['price'] = data_price measurement_data = MeasurementData(eliminated=eliminated) # define the optimization problem opts = op_model.optimize_options() opts['n_e'] = n_e opts['measurement_data'] = measurement_data opts['init_traj'] = sim_res.result_data opts["IPOPT_options"]["max_iter"] = 10000 # Get the results of the optimization res = op_model.optimize(options=opts) #plot_sim_res(res) return res
from pymodelica import compile_jmu room_jmu=compile_jmu('room_model_backup.RoomRadiator', '/home/hc/jmtest/room_model_backup.mo') from pyjmi import transfer_optimization_problem opt_prob = transfer_optimization_problem('room_model_backup.RoomRadiator', '/home/hc/jmtest/room_model_backup.mo', accept_model=True)
# Python script for solving the optimization problem in # Laboratory Exercise 3 in FRTN05 Nonlinear Control and Servo systems # using the software JModelica.org. from pyjmi.common.io import ResultDymolaTextual import numpy as np import matplotlib.pyplot as plt from pyjmi import transfer_optimization_problem # Create compiler and compile the pendulum model pend_opt = transfer_optimization_problem("pendulum", "pendulum.mop") # Define number of elements in the discretization grid and # number of collocation points in each element n_e = 150 n_cp = 3 # Initialize the optimization problem with the initial guess (stored in # the file 'initial_guess.txt') init_res = ResultDymolaTextual('initial_guess.txt') # Solve the optimization problem opts = pend_opt.optimize_options() opts['IPOPT_options']['max_iter'] = 1000 opts['IPOPT_options']['linear_solver'] = "mumps" opts['IPOPT_options']['tol'] = 1e-12 opts['n_e'] = n_e opts['n_cp'] = n_cp opts['init_traj'] = init_res res = pend_opt.optimize(options=opts)
plt.grid(True) plt.ylabel( 'Set point and measured values of vapour temperature at turbine inlet [K]') plt.xlabel('time [s]') plt.figure(3) plt.clf() plt.plot(time, plant_w_att) plt.grid(True) plt.ylabel('Attemperation Mass Flow [kg/s]') plt.xlabel('time [s]') #Optimization #optim = transfer_optimization_problem("StartupOptimizationAtt.StartupAttReferenceOpt",("CombinedCycle.mo","StartupOptimizationAtt.mop")) optim = transfer_optimization_problem( "StartupOptimizationAtt.StartupAtt", ("CombinedCycle.mo", "StartupOptimizationAtt.mop")) #option setting n_e = 40 n_cp = 1 opt_options = optim.optimize_options() opt_options['init_traj'] = res_fmu opt_options['n_e'] = n_e opt_options['n_cp'] = n_cp opt_options['blocking_factors'] = N.ones(n_e, dtype=int) #opt_options['result_mode'] = 'element_interpolation' #opt_options['IPOPT_options']['mu_strategy'] = 'monotone' #opt_options['IPOPT_options']['mumps_mem_percent'] = 10000 #simulation res_opt = optim.optimize(options=opt_options)
def run_demo(with_plots=True): """ This example is about moving a cart with an attached pendulum from one position to another, while starting and ending in steady state and avoiding an ellipticla obstacle for the pendulum. This example is a part of the third lab in the course FRTN05 Nonlinear Control and Servo systems at the Department of Automatic Control at Lund University, Sweden. In the lab, the trajectories generated by this script are realized by tracking them with linear MPC. The model has 4 states: Cart position and velocity, pendulum angle and angular velocity. A nearly optimal initial guess has been precomputed and is used in this script. The problem was developed by Pontus Giselsson and is published in @InProceedings{mod09pg, author = "Giselsson, Pontus and {\AA}kesson, Johan and Robertsson, Anders", title = "Optimization of a Pendulum System using {Optimica} and {Modelica}", booktitle = "7th International Modelica Conference 2009", address = "Como, Italy", year = 2009, month = sep, } """ # Create compiler and compile the pendulum model file_path = os.path.join(get_files_path(), "cart_pendulum.mop") pend_opt = transfer_optimization_problem("CartPendulum", file_path) # Define number of elements in the discretization grid and # number of collocation points in each element n_e = 150 n_cp = 3 # Initialize the optimization problem with precomputed initial guess result_file_path = os.path.join(get_files_path(), 'cart_pendulum_result.txt') init_res = ResultDymolaTextual(result_file_path) # Solve the optimization problem opts = pend_opt.optimize_options() opts['IPOPT_options']['max_iter'] = 1000 opts['IPOPT_options']['linear_solver'] = "mumps" opts['IPOPT_options']['tol'] = 1e-12 opts['n_e'] = n_e opts['n_cp'] = n_cp opts['init_traj'] = init_res res = pend_opt.optimize(options=opts) # Extract variable profiles and plot the results a_ref = res['a_ref'] x_p = res['x_p'] y_p = res['y_p'] t = res['time'] if with_plots: plt.close(1) plt.figure(1) plt.plot(t, a_ref) plt.grid() plt.title('Input signal to process ($a_{ref}$)') plt.xlabel('Time (s)') plt.ylabel('Acceleration $m/s^2$') plt.close(2) plt.figure(2) plt.plot(x_p, y_p) plt.grid() plt.title('Pendulum end-point path and obstacle') plt.xlabel('x-coordinate (m)') plt.ylabel('y-coordinate (m)') x_obst = N.linspace(-0.35, -0.25) y_obst = N.sqrt(1 - ((x_obst + 0.3) / 0.05)**2) * 0.3 - 0.4 x_track = N.linspace(-1.45, 0.1) y_track = N.zeros(N.size(x_track)) plt.plot(x_obst, y_obst) plt.plot(x_track, y_track, '--') plt.show()
def test_get_residuals(): file_path = os.path.join(get_files_path(), 'Modelica', 'TestBackTracking.mop') op = transfer_optimization_problem("TestResiduals", file_path) n_e = 10 n_cp = 3 opts = op.optimize_options() opts['n_e'] = n_e opts['n_cp'] = n_cp opts['variable_scaling'] = False opts['equation_scaling'] = True var_names = ('x', 'der(x)', 'w', 'u') eqtypes = ('initial', 'dae', 'path_eq', 'path_ineq', 'point_eq', 'point_ineq') solver = op.prepare_optimization(options=opts) check_roundtrip(solver) collocator = solver.collocator # Set random initial values N.random.seed(486151) initial = {} for var in var_names: initial[var] = N.random.rand(n_e+1, n_cp+1) inds, t, i, k = solver.get_nlp_variable_indices(var) collocator.xx_init[inds] = initial[var][i, k] x, derx, w, u = initial['x'], initial['der(x)'], initial['w'], initial['u'] # Check that the residuals match the equations in the model for eqtype in eqtypes: r1 = solver.get_residuals(eqtype, point='init', raw=True, tik=False) t, i, k = solver.get_constraint_points(eqtype) i, k = N.maximum(1, i), N.maximum(0, k) if eqtype == 'initial': r2 = 1e3*(x - 1) # x = 1; elif eqtype == 'dae': r2 = 2e4*(derx - u) # der(x) = u; elif eqtype == 'path_eq': r2 = 3e3*(w - x**2) # w = x^2; elif eqtype == 'path_ineq': r2 = 4e3*(x - u**2) # x <= u^2; elif eqtype == 'point_eq': r2 = 5e3*(x - 2) # x(finalTime) = 2; i, k = -1, -1 elif eqtype == 'point_ineq': r2 = 6e3*(-5 - x) # x(startTime) >= -5; i, k = 1, 0 r2 = r2[i, k] assert N.max(N.abs(r2 - r1.ravel())) < 1e-12*1e4 r1 = solver.get_residuals(eqtype, point='init', raw=True, scaled=True, tik=False) rs = solver.get_residual_scales(eqtype) assert N.max(N.abs(r2*rs - r1.ravel())) < 1e-12 v1 = solver.get_residuals(eqtype, point='init', raw=False, tik=False) if eqtype in ('path_ineq', 'point_ineq'): v2 = N.maximum(0, r2) else: v2 = r2 assert N.max(N.abs(v2 - v1.ravel())) < 1e-12 dest = solver.collocator.c_dests[eqtype] assert dest['n_eq'] == 1 # for this model if eqtype in ('path_ineq', 'point_ineq'): assert dest['kind'] == 'ineq' else: assert dest['kind'] == 'eq'
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. This example serves to illustrate how constraints can be added when using the CasADi-based Moving Horizon Estimator (MHE). Shows the importance of constraints when working close to a physical constraint by comparing the unconstrained MHE with the constrained one. Constraints are added by simply extending a Modelica or Optimica model and adding the constraint or by creating a Constraint to the OptimizationProblem object using setPathConstraints. The usage of point constraints is not supported and can give unpredictable results. """ #Get the name and location of the Modelica package file_path = os.path.join(get_files_path(), "CSTR.mop") #Transfer the unconstrained OptimizationProblem from the model #using "state_initial_equations" and "accept_model" unconstr_op = transfer_optimization_problem( 'CSTR.CSTR_mhe_model', file_path, accept_model=True, compiler_options={"state_initial_equations": True}) #Transfer the constrained OptimizationProblem from the Optimica model #using "state_initial_equations" constr_op = transfer_optimization_problem( 'CSTR.CSTR_mhe', file_path, accept_model=False, compiler_options={"state_initial_equations": True}) #The constraint could instead have been added using the following: #c_var = op.getVariable('c').getVar() #constr = mc.Constraint(c_var, MX(0), mc.Constraint.GEQ) #op.setPathConstraints([constr]) #Compile the FMU with the same option as for the OptimizationProblem fmu = compile_fmu('CSTR.CSTR_mhe_model', file_path, compiler_options={"state_initial_equations": True}) #Load the FMU model = load_fmu(fmu) #Define the time interval and the number of points sim_time = 3. nbr_of_points = 31 #Calculate the corresponding sample time sample_time = sim_time / (nbr_of_points - 1) #Create an array of the time points time = N.linspace(0., sim_time, nbr_of_points) ###Create noise for the measurement data #Create the discrete covariance matrices Q = N.array([[20.]]) R = N.array([[10., 0.], [0., 1.]]) #The expectations w_my = N.array([0.]) v_my = N.array([0., 0.]) ##Get the noise sequences #Process noise #Use same seed for consistent results N.random.seed(3) w = N.transpose(N.random.multivariate_normal(w_my, Q, nbr_of_points)) #Measurement noise N.random.seed(188) v = N.transpose(N.random.multivariate_normal(v_my, R, nbr_of_points)) ###Chose a control signal u = 350. * N.ones(nbr_of_points) ###Define the inputs for the MHE object ##See the documentation of the MHEOptions for more details #Create the options object MHE_opts = MHEOptions() #Process noise covariance MHE_opts['process_noise_cov'] = [('Tc', 200.)] #The names of the input signals acting as control signals MHE_opts['input_names'] = ['Tc'] #Chose what variables are measured and their covariance structure #The two definitions below are equivalent MHE_opts['measurement_cov'] = [('c', 1.), ('T', 0.1)] MHE_opts['measurement_cov'] = [(['c', 'T'], N.array([[1., 0.0], [0.0, 0.1]]))] #Error covariance matrix MHE_opts['P0_cov'] = [('c', 10.), ('T', 5.)] ##The initial guess of the states x_0_guess = dict([('c', 0.), ('T', 352.)]) #Initial value of the simulation x_0 = dict([('c', 0.), ('T', 350.)]) ##Use mhe_initial_values module or some equivalent method to get the #initial values of the state derivatives and the algebraic variables #Control signal for time step zero u_0 = {'Tc': u[0]} (dx_0, c_0) = initv.optimize_for_initial_values(unconstr_op, x_0_guess, u_0, MHE_opts) #Decide the horizon length horizon = 8 ##Create the MHE objects unconstr_MHE_object = MHE(unconstr_op, sample_time, horizon, x_0_guess, dx_0, c_0, MHE_opts) constr_MHE_object = MHE(constr_op, sample_time, horizon, x_0_guess, dx_0, c_0, MHE_opts) #Create a structure for saving the estimates unconstr_x_est = {'c': [x_0_guess['c']], 'T': [x_0_guess['T']]} constr_x_est = {'c': [x_0_guess['c']], 'T': [x_0_guess['T']]} #Create a structure for saving the simulated data x = {'c': [x_0['c']], 'T': [x_0['T']]} #Create the structure for the measured data y = {'c': [], 'T': []} #Loop over estimation and simulation for t in range(1, nbr_of_points): #Create the measurement data from the simulated data and added noise y['c'].append(x['c'][-1] + v[0, t - 1]) y['T'].append(x['T'][-1] + v[1, t - 1]) #Create list of tuples with (name, measurement) structure y_t = [('c', y['c'][-1]), ('T', y['T'][-1])] #Create list of tuples with (name, input) structure u_t = [('Tc', u[t - 1])] #Estimate constr_x_est_t = constr_MHE_object.step(u_t, y_t) unconstr_x_est_t = unconstr_MHE_object.step(u_t, y_t) #Add the results to x_est for key in constr_x_est.keys(): constr_x_est[key].append(constr_x_est_t[key]) for key in unconstr_x_est.keys(): unconstr_x_est[key].append(unconstr_x_est_t[key]) ###Prepare the simulation #Create the input object u_traj = N.transpose(N.vstack((0., u[t]))) input_object = ('Tc', u_traj) #Set the initial values of the states for (key, list) in x.items(): model.set('_start_' + key, list[-1]) #Simulate with one communication point to get the #value at the right point res = model.simulate(final_time=sample_time, input=input_object, options={'ncp': 1}) #Extract the state values from the result object for key in x.keys(): x[key].append(res[key][-1]) #reset the FMU model.reset() #Add the last measurement y['c'].append(x['c'][-1] + v[0, -1]) y['T'].append(x['T'][-1] + v[1, -1]) if with_plots: plt.close('MHE') plt.figure('MHE') plt.subplot(2, 1, 1) plt.plot(time, constr_x_est['c']) plt.plot(time, unconstr_x_est['c']) plt.plot(time, x['c'], ls='--', color='k') plt.plot(time, y['c'], ls='-', marker='+', mfc='k', mec='k', mew=1.) plt.legend(('Constrained concentration estimate', 'Unconstrained concentration estimate', 'Simulated concentration', 'Measured concentration')) plt.grid() plt.ylabel('Concentration') plt.subplot(2, 1, 2) plt.plot(time, constr_x_est['T']) plt.plot(time, unconstr_x_est['T']) plt.plot(time, x['T'], ls='--', color='k') plt.plot(time, y['T'], ls='-', marker='+', mfc='k', mec='k', mew=1.) plt.legend(('Constrained temperature estimate', 'Unconstrained temperature estimate', 'Simulated temperature', 'Measured temperature')) plt.grid() plt.ylabel('Temperature') plt.show()
def run_demo(with_plots=True): """ This example is based on the multibody mechanics fourbar1 example from the Modelica Standard Library (MSL). The MSL example has been modified by adding a torque on the first revolute joint of the pendulum as a top-level input. The considered optimization problem is to control the translation along the prismatic joint at the other end of the closed kinematic loop. This example needs the linear solver MA57 to work. """ # Compile simulation model file_paths = (os.path.join(get_files_path(), "Fourbar1.mo"), os.path.join(get_files_path(), "Fourbar1.mop")) comp_opts = { 'inline_functions': 'all', 'dynamic_states': False, 'expose_temp_vars_in_fmu': True } model = load_fmu( compile_fmu('Fourbar1.Fourbar1Sim', file_paths, compiler_options=comp_opts)) # Load trajectories that are optimal subject to a smaller torque constraint and use to generate initial guess init_path = os.path.join(get_files_path(), "fourbar1_init.txt") init_res = LocalDAECollocationAlgResult( result_data=ResultDymolaTextual(init_path)) t = init_res['time'] u = init_res['u'] u_traj = ('u', N.transpose(N.vstack((t, u)))) sim_res = model.simulate(final_time=1.0, input=u_traj) # Set up optimization op = transfer_optimization_problem('Opt', file_paths, compiler_options=comp_opts) opts = op.optimize_options() opts['IPOPT_options']['linear_solver'] = "ma57" opts['IPOPT_options']['ma57_pivtol'] = 1e-3 opts['IPOPT_options']['ma57_automatic_scaling'] = "yes" opts['IPOPT_options']['mu_strategy'] = "adaptive" opts['n_e'] = 20 opts['init_traj'] = sim_res opts['nominal_traj'] = sim_res # Solve optimization problem res = op.optimize(options=opts) # Extract solution time = res['time'] s = res['fourbar1.j2.s'] phi = res['fourbar1.j1.phi'] u = res['u'] # Verify solution for testing purposes try: import casadi except: pass else: cost = float(res.solver.solver_object.output(casadi.NLP_SOLVER_F)) N.testing.assert_allclose(cost, 1.0455646e-03, rtol=5e-3) # Plot solution if with_plots: plt.close(1) plt.figure(1) plt.subplot(3, 1, 1) plt.plot(time, s) plt.ylabel('$s$') plt.xlabel('$t$') plt.grid() plt.subplot(3, 1, 2) plt.plot(time, s) plt.ylabel('$\phi$') plt.xlabel('$t$') plt.grid() plt.subplot(3, 1, 3) plt.plot(time, u) plt.ylabel('$u$') plt.xlabel('$t$') plt.grid() plt.show()
def run_optimization(sim_res, stop_time = 3600*24*6, opt_problem = 'ElectricNetwork.OptimizationDistrict_E', n_e = 12): """ This function runs an optimization problem """ from pyjmi.optimization.casadi_collocation import MeasurementData from collections import OrderedDict # Get the weather data and other inputs for the building model time = np.linspace(0, stop_time, 36*stop_time/3600, True) (Tamb, Tgnd, sRadS, sRadN, sRadW, sRadE, ihg_1, ihg_2, ihg_3, price) = getData(time, plot = False) # get current directory curr_dir = os.path.dirname(os.path.abspath(__file__)); # compile FMU path = os.path.join(curr_dir,"..","Models","ElectricalNetwork.mop") op_model = transfer_optimization_problem(opt_problem, path, compiler_options={"enable_variable_scaling":True}) # Get the inputs that should be eliminated from the optimization variables eliminated = OrderedDict() data_ihg_1 = np.vstack([time, ihg_1]) eliminated['ihg_1'] = data_ihg_1 data_ihg_2 = np.vstack([time, ihg_2]) eliminated['ihg_2'] = data_ihg_2 data_ihg_3 = np.vstack([time, ihg_3]) eliminated['ihg_3'] = data_ihg_3 data_Tamb = np.vstack([time, Tamb]) eliminated['Tamb'] = data_Tamb data_Tgnd = np.vstack([time, Tgnd]) eliminated['Tgnd'] = data_Tgnd data_sRadE = np.vstack([time, sRadE]) eliminated['solGlobFac_E'] = data_sRadE data_sRadN = np.vstack([time, sRadN]) eliminated['solGlobFac_N'] = data_sRadN data_sRadS = np.vstack([time, sRadS]) eliminated['solGlobFac_S'] = data_sRadS data_sRadW = np.vstack([time, sRadW]) eliminated['solGlobFac_W'] = data_sRadW data_price = np.vstack([time, price]) eliminated['price'] = data_price measurement_data = MeasurementData(eliminated = eliminated) # define the optimization problem opts = op_model.optimize_options() opts['n_e'] = n_e opts['measurement_data'] = measurement_data opts['init_traj'] = sim_res.result_data opts["IPOPT_options"]["max_iter"] = 10000 # Get the results of the optimization res = op_model.optimize(options = opts) #plot_sim_res(res) return res
def setUpClass(self): """Compile the test models.""" self.compiler_opts_automatic = { 'equation_sorting': True, 'automatic_tearing': True } self.compiler_opts_manual = {} class_path = "IllustExample" file_path = os.path.join(get_files_path(), 'Modelica', 'SymbolicElimination.mop') self.model_illust = load_fmu(compile_fmu(class_path, file_path)) class_path = "IllustExampleLagrange" file_path = os.path.join(get_files_path(), 'Modelica', 'SymbolicElimination.mop') self.op_illust_automatic = transfer_optimization_problem( class_path, file_path, self.compiler_opts_automatic) self.op_illust_manual = transfer_optimization_problem( class_path, file_path, self.compiler_opts_manual) class_path = "IllustExampleLagrangeBound" file_path = os.path.join(get_files_path(), 'Modelica', 'SymbolicElimination.mop') self.op_illust_automatic_bound = transfer_optimization_problem( class_path, file_path, self.compiler_opts_automatic) self.op_illust_manual_bound = transfer_optimization_problem( class_path, file_path, self.compiler_opts_manual) class_path = "IllustExampleLagrangeConstraintAndObjective" file_path = os.path.join(get_files_path(), 'Modelica', 'SymbolicElimination.mop') self.op_illust_automatic_constraint = transfer_optimization_problem( class_path, file_path, self.compiler_opts_automatic) self.op_illust_manual_constraint = transfer_optimization_problem( class_path, file_path, self.compiler_opts_manual) class_path = "IllustExampleEst" file_path = os.path.join(get_files_path(), 'Modelica', 'SymbolicElimination.mop') self.op_illust_est_automatic = transfer_optimization_problem( class_path, file_path, self.compiler_opts_automatic) self.op_illust_est_manual = transfer_optimization_problem( class_path, file_path, self.compiler_opts_manual) class_path = "LinearLoopLagrangeConstraint" file_path = os.path.join(get_files_path(), 'Modelica', 'SymbolicElimination.mop') self.op_loop_automatic = transfer_optimization_problem( class_path, file_path, self.compiler_opts_automatic) self.op_loop_manual = transfer_optimization_problem( class_path, file_path, self.compiler_opts_manual) class_path = "DerivativeLoop" file_path = os.path.join(get_files_path(), 'Modelica', 'SymbolicElimination.mop') self.op_der_loop_automatic = transfer_optimization_problem( class_path, file_path, self.compiler_opts_automatic) self.op_der_loop_manual = transfer_optimization_problem( class_path, file_path, self.compiler_opts_manual)
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 problem is solved using the CasADi-based collocation algorithm. The steps performed correspond to those demonstrated in example pyjmi.examples.cstr, where the same problem is solved using the default JMI algorithm. FMI is used for initialization and simulation purposes. The following steps are demonstrated in this example: 1. How to solve the initialization problem. The initialization model has 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. 2. How to generate an initial guess for a direct collocation method by means of simulation with a constant input. The trajectories resulting from the 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. 4. Finally the system is simulated using the optimal control profile. This step is important in order to verify that the approximation in the transcription step is sufficiently accurate. """ ### 1. Solve the initialization problem # Locate the Modelica and Optimica code file_path = os.path.join(get_files_path(), "CSTR.mop") # Compile the stationary initialization model into an FMU init_fmu = compile_fmu("CSTR.CSTR_Init", file_path) # Load the FMU init_model = load_fmu(init_fmu) # Set input for Stationary point A Tc_0_A = 250 init_model.set('Tc', Tc_0_A) # Solve the initialization problem using FMI init_model.initialize() # Store stationary point A [c_0_A, T_0_A] = init_model.get(['c', 'T']) # Print some data for stationary point A print(' *** Stationary point A ***') print('Tc = %f' % Tc_0_A) print('c = %f' % c_0_A) print('T = %f' % T_0_A) # Set inputs for Stationary point B init_model.reset() # reset the FMU so that we can initialize it again Tc_0_B = 280 init_model.set('Tc', Tc_0_B) # Solve the initialization problem using FMI init_model.initialize() # Store stationary point B [c_0_B, T_0_B] = init_model.get(['c', 'T']) # Print some data for stationary point B print(' *** Stationary point B ***') print('Tc = %f' % Tc_0_B) print('c = %f' % c_0_B) print('T = %f' % T_0_B) ### 2. Compute initial guess trajectories by means of simulation # Compile the optimization initialization model init_sim_fmu = compile_fmu("CSTR.CSTR_Init_Optimization", file_path) # Load the model init_sim_model = load_fmu(init_sim_fmu) # Set initial and reference values 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) # Simulate with constant input Tc init_res = init_sim_model.simulate(start_time=0., final_time=150.) # Extract variable profiles t_init_sim = init_res['time'] c_init_sim = init_res['cstr.c'] T_init_sim = init_res['cstr.T'] Tc_init_sim = init_res['cstr.Tc'] # Plot the initial guess trajectories if with_plots: plt.close(1) plt.figure(1) plt.hold(True) plt.subplot(3, 1, 1) plt.plot(t_init_sim, c_init_sim) plt.grid() plt.ylabel('Concentration') plt.title('Initial guess obtained by simulation') plt.subplot(3, 1, 2) plt.plot(t_init_sim, T_init_sim) plt.grid() plt.ylabel('Temperature') plt.subplot(3, 1, 3) plt.plot(t_init_sim, Tc_init_sim) plt.grid() plt.ylabel('Cooling temperature') plt.xlabel('time') plt.show() ### 3. Solve the optimal control problem # Compile and load optimization problem op = transfer_optimization_problem("CSTR.CSTR_Opt2", file_path) # Set reference values op.set('Tc_ref', Tc_0_B) op.set('c_ref', float(c_0_B)) op.set('T_ref', float(T_0_B)) # Set initial values op.set('cstr.c_init', float(c_0_A)) op.set('cstr.T_init', float(T_0_A)) # Set options opt_opts = op.optimize_options() opt_opts['n_e'] = 19 # Number of elements opt_opts['init_traj'] = init_res.result_data opt_opts['nominal_traj'] = init_res.result_data opt_opts['IPOPT_options']['tol'] = 1e-10 # Solve the optimal control problem res = op.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'] # Verify solution for testing purposes try: import casadi except: pass else: cost = float(res.solver.solver_object.output(casadi.NLP_SOLVER_F)) assert (N.abs(cost / 1.e3 - 1.86162353098) < 1e-3) # Plot the results if with_plots: plt.close(2) plt.figure(2) plt.hold(True) plt.subplot(3, 1, 1) plt.plot(time_res, c_res) plt.plot(time_res, c_ref, '--') plt.grid() plt.ylabel('Concentration') plt.title('Optimized trajectories') plt.subplot(3, 1, 2) plt.plot(time_res, T_res) plt.plot(time_res, T_ref, '--') plt.grid() plt.ylabel('Temperature') plt.subplot(3, 1, 3) plt.plot(time_res, Tc_res) plt.plot(time_res, Tc_ref, '--') plt.grid() plt.ylabel('Cooling temperature') plt.xlabel('time') plt.show() ### 4. Simulate to verify the optimal solution # Compile model sim_fmu = compile_fmu("CSTR.CSTR", file_path) # Load model sim_model = load_fmu(sim_fmu) # Get optimized input (_, opt_input) = res.solver.get_opt_input() # Set initial values sim_model.set('c_init', c_0_A) sim_model.set('T_init', T_0_A) # Simulate using optimized input sim_opts = sim_model.simulate_options() sim_opts['CVode_options']['rtol'] = 1e-6 sim_opts['CVode_options']['atol'] = 1e-8 res = sim_model.simulate(start_time=0., final_time=150., input=('Tc', opt_input), options=sim_opts) # Extract variable profiles c_sim = res['c'] T_sim = res['T'] Tc_sim = res['Tc'] time_sim = res['time'] # Verify results N.testing.assert_array_less(abs(c_res[-1] - c_sim[-1]) / c_res[-1], 5e-1) # Plot the results if with_plots: plt.close(3) plt.figure(3) plt.hold(True) plt.subplot(3, 1, 1) plt.plot(time_res, c_res, '--') plt.plot(time_sim, c_sim) plt.legend(('optimized', 'simulated')) plt.grid(True) plt.ylabel('Concentration') plt.title('Verification') plt.subplot(3, 1, 2) plt.plot(time_res, T_res, '--') plt.plot(time_sim, T_sim) plt.grid(True) plt.ylabel('Temperature') plt.subplot(3, 1, 3) plt.plot(time_res, Tc_res, '--') plt.plot(time_sim, Tc_sim) plt.grid(True) plt.ylabel('Cooling temperature') 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 problem is solved using the CasADi-based collocation algorithm through the MPC-class. FMI is used for initialization and simulation purposes. The following steps are demonstrated in this example: 1. How to generate an initial guess for a direct collocation method by means of simulation with a constant input. The trajectories resulting from the simulation are used to initialize the variables in the transcribed NLP, in the first sample(optimization). 2. An optimal control problem is defined where the objective is to transfer the state of the system from stationary point A to point B. An MPC object for the optimization problem is created. After each sample the NLP is updated with an estimate of the states in the next sample. The estimate is done by simulating the model for one sample period with the optimal input calculated in the optimization as input. To each estimate a normally distributed noise, with the mean 0 and standard deviation 0.5% of the nominal value of each state, is added. The MPC object uses the result from the previous optimization as initial guess for the next optimization (for all but the first optimization, where the simulation result from #1 is used instead). (3.) If with_plots is True we compile the same optimization problem again and define the options so that the op has the same options and resolution as the op we solved through the MPC-class. By same resolution we mean that both op should have the same mesh and blocking factors. This allows us to compare the MPC-results to an open loop optimization. Note that the MPC-results contains noise while the open loop optimization does not. """ ### 1. Compute initial guess trajectories by means of simulation # Locate the Modelica and Optimica code file_path = os.path.join(get_files_path(), "CSTR.mop") # Compile and load the model used for simulation sim_fmu = compile_fmu("CSTR.CSTR_MPC_Model", file_path, compiler_options={"state_initial_equations":True}) sim_model = load_fmu(sim_fmu) # Define stationary point A and set initial values and inputs c_0_A = 956.271352 T_0_A = 250.051971 sim_model.set('_start_c', c_0_A) sim_model.set('_start_T', T_0_A) sim_model.set('Tc', 280) opts = sim_model.simulate_options() opts["CVode_options"]["maxh"] = 0.0 opts["ncp"] = 0 init_res = sim_model.simulate(start_time=0., final_time=150, options=opts) ### 2. Define the optimal control problem and solve it using the MPC class # Compile and load optimization problem op = transfer_optimization_problem("CSTR.CSTR_MPC", file_path, compiler_options={"state_initial_equations":True}) # Define MPC options sample_period = 3 # s horizon = 33 # Samples on the horizon n_e_per_sample = 1 # Collocation elements / sample n_e = n_e_per_sample*horizon # Total collocation elements finalTime = 150 # s number_samp_tot = int(finalTime/sample_period) # Total number of samples to do # Create blocking factors with quadratic penalty and bound on 'Tc' bf_list = [n_e_per_sample]*(horizon/n_e_per_sample) factors = {'Tc': bf_list} du_quad_pen = {'Tc': 500} du_bounds = {'Tc': 30} bf = BlockingFactors(factors, du_bounds, du_quad_pen) # Set collocation options opt_opts = op.optimize_options() opt_opts['n_e'] = n_e opt_opts['n_cp'] = 2 opt_opts['init_traj'] = init_res opt_opts['blocking_factors'] = bf if with_plots: # Compile and load a new instance of the op to compare the MPC results # with an open loop optimization op_open_loop = transfer_optimization_problem( "CSTR.CSTR_MPC", file_path, compiler_options={"state_initial_equations":True}) op_open_loop.set('_start_c', float(c_0_A)) op_open_loop.set('_start_T', float(T_0_A)) # Copy options from MPC optimization open_loop_opts = copy.deepcopy(opt_opts) # Change n_e and blocking_factors so op_open_loop gets the same # resolution as op open_loop_opts['n_e'] = number_samp_tot bf_list_ol = [n_e_per_sample]*(number_samp_tot/n_e_per_sample) factors_ol = {'Tc': bf_list_ol} bf_ol = BlockingFactors(factors_ol, du_bounds, du_quad_pen) open_loop_opts['blocking_factors'] = bf_ol open_loop_opts['IPOPT_options']['print_level'] = 0 constr_viol_costs = {'T': 1e6} # Create the MPC object MPC_object = MPC(op, opt_opts, sample_period, horizon, constr_viol_costs=constr_viol_costs, noise_seed=1) # Set initial state x_k = {'_start_c': c_0_A, '_start_T': T_0_A } # Update the state and optimize number_samp_tot times for k in range(number_samp_tot): # Update the state and compute the optimal input for next sample period MPC_object.update_state(x_k) u_k = MPC_object.sample() # Reset the model and set the new initial states before simulating # the next sample period with the optimal input u_k sim_model.reset() sim_model.set(list(x_k.keys()), list(x_k.values())) sim_res = sim_model.simulate(start_time=k*sample_period, final_time=(k+1)*sample_period, input=u_k, options=opts) # Extract state at end of sample_period from sim_res and add Gaussian # noise with mean 0 and standard deviation 0.005*(state_current_value) x_k = MPC_object.extract_states(sim_res, mean=0, st_dev=0.005) # Extract variable profiles MPC_object.print_solver_stats() complete_result = MPC_object.get_complete_results() c_res_comp = complete_result['c'] T_res_comp = complete_result['T'] Tc_res_comp = complete_result['Tc'] time_res_comp = complete_result['time'] # Verify solution for testing purposes try: import casadi except: pass else: Tc_norm = N.linalg.norm(Tc_res_comp) / N.sqrt(len(Tc_res_comp)) assert(N.abs(Tc_norm - 311.7362) < 1e-3) c_norm = N.linalg.norm(c_res_comp) / N.sqrt(len(c_res_comp)) assert(N.abs(c_norm - 653.5369) < 1e-3) T_norm = N.linalg.norm(T_res_comp) / N.sqrt(len(T_res_comp)) assert(N.abs(T_norm - 328.0852) < 1e-3) # Plot the results if with_plots: ### 3. Solve the original optimal control problem without MPC res = op_open_loop.optimize(options=open_loop_opts) c_res = res['c'] T_res = res['T'] Tc_res = res['Tc'] time_res = res['time'] # Get reference values Tc_ref = op.get('Tc_ref') T_ref = op.get('T_ref') c_ref = op.get('c_ref') # Plot plt.close('MPC') plt.figure('MPC') plt.subplot(3, 1, 1) plt.plot(time_res_comp, c_res_comp) plt.plot(time_res, c_res ) plt.plot([time_res[0],time_res[-1]],[c_ref,c_ref],'--') plt.legend(('MPC with noise', 'Open-loop without noise', 'Reference value')) plt.grid() plt.ylabel('Concentration') plt.title('Simulated trajectories') plt.subplot(3, 1, 2) plt.plot(time_res_comp, T_res_comp) plt.plot(time_res, T_res) plt.plot([time_res[0],time_res[-1]],[T_ref,T_ref], '--') plt.grid() plt.ylabel('Temperature [C]') plt.subplot(3, 1, 3) plt.step(time_res_comp, Tc_res_comp) plt.step(time_res, Tc_res) plt.plot([time_res[0],time_res[-1]],[Tc_ref,Tc_ref], '--') plt.grid() plt.ylabel('Cooling temperature [C]') plt.xlabel('time') plt.show()
plt.grid(True) plt.ylabel('Set point and measured values of vapour temperature at turbine inlet [K]') plt.xlabel('time [s]') plt.figure(3) plt.clf() plt.plot(time,plant_w_att) plt.grid(True) plt.ylabel('Attemperation Mass Flow [kg/s]') plt.xlabel('time [s]') #Optimization compiler_options={'equation_sorting':True} optim = transfer_optimization_problem("StartupOptimizationAtt.StartupAtt",("CombinedCycle.mo","StartupOptimizationAtt.mop"), compiler_options) #option setting n_e = 40 n_cp = 1 opt_options = optim.optimize_options() opt_options['init_traj'] = res_fmu opt_options['n_e'] = n_e opt_options['n_cp'] = n_cp opt_options['blocking_factors'] = N.ones(n_e, dtype=int) #opt_options['result_mode'] = 'element_interpolation' #opt_options['IPOPT_options']['mu_strategy'] = 'monotone' #opt_options['IPOPT_options']['mumps_mem_percent'] = 10000 # variable elimination eliminables = optim.getEliminableVariables() algebraics = optim.getVariables(optim.REAL_ALGEBRAIC)
def run_optimisation(model_path, tank1_outflow, tank2_outflow, tank3_outflow, h1_final, h2_final, h3_final, max_control, sim_control, h10=20.0, h20=20.0, h30=20.0, alpha1=0.5, alpha2=0.5, alpha3=0.5, ipopt_tolerance=1e-3, t_start=0, t_final=50.0, elements_number=50): """ Run optimisation of the tanks model. :param model_path: path to the Modelica/Optimica model :param tank1_outflow: outflow resistance of the 1st tanks :param tank2_outflow: outflow resistance of the 2nd tanks :param tank3_outflow: outflow resistance of the 3rd tanks :param h1_final: wanted final value of the level in 1st tank :param h2_final: wanted final value of the level in 2nd tank :param h3_final: wanted final value of the level in 3rd tank :param max_control: higher bound of the control :param sim_control: control to be used in initialisation simulation :param h10: initial condition of the level in 1st tank :param h20: initial condition of the level in 2nd tank :param h30: initial condition of the level in 3rd tank :param alpha1: flow coefficient of the 1st tank :param alpha2: flow coefficient of the 2nd tank :param alpha3: flow coefficient of the 3rd tank :param ipopt_tolerance: tolerance of the IPOPT solver :param t_start: starting time of the initial simulation :param t_final: final time of the initial simulation :param elements_number: number of elements for Finite Elements Method :return: a dictionary with optimisation results """ # 2. Compute initial guess trajectories by means of simulation # Compile the optimization initialization model init_sim_fmu = compile_fmu("TanksPkg.ThreeTanks", model_path) # Load the model simulation_model = load_fmu(init_sim_fmu) set_model_parameters(simulation_model, {'u': sim_control, "h10": h10, "h20": h20, "h30": h30, "C1": tank1_outflow, "C2": tank2_outflow, "C3": tank3_outflow, "alpha1": alpha1, "alpha2": alpha2, "alpha3": alpha3}) init_result = simulation_model.simulate(start_time=t_start, final_time=t_final) # 3. Solve the optimal control problem # Compile and load optimization problem optimisation_model = "TanksPkg.three_tanks_time_optimal" op = transfer_optimization_problem(optimisation_model, model_path) # Set parameters set_model_parameters(op, {"h10": h10, "h20": h20, "h30": h30, 'h1_final': h1_final, 'h2_final': h2_final, 'h3_final': h3_final, "C1": tank1_outflow, "C2": tank2_outflow, "C3": tank3_outflow, "alpha1": alpha1, "alpha2": alpha2, "alpha3": alpha3, 'u_max': max_control}) # Set options opt_options = op.optimize_options() opt_options['n_e'] = elements_number opt_options['variable_scaling'] = False opt_options['init_traj'] = init_result opt_options['IPOPT_options']['tol'] = ipopt_tolerance opt_options['verbosity'] = 1 # Solve the optimal control problem res = op.optimize(options=opt_options) opt_result = {"h1": res['h1'], "h2": res['h2'], "h3": res['h3'], "u": res['u'], "time": res['time']} return opt_result
def run_demo(): """ """ # Locate the model and file paths file_path = os.path.join(get_files_path(), "DrumBoiler.mop") model_name = "DrumBoilerpackage.DrumBoiler" # Load measurement data RCdata = get_test_data() measurements = RCdata['measurements'] time = RCdata['time'] # Extract control signal data from measurements inputs={} inputs['uc']= measurements.pop('uc') inputs['fc']= measurements.pop('fc') # Transfer model to Casadi interface op = transfer_optimization_problem(model_name, file_path, accept_model = True) op_opts = op.optimize_options() # Create greybox object GB = GreyBox(op, op_opts, measurements, inputs, time) # Set some variable attributes GB.set_variable_attribute(GB.get_noise_covariance_variable('E'), 'max', 100) GB.set_variable_attribute(GB.get_noise_covariance_variable('P'), 'max', 100) GB.set_variable_attribute('x10', 'initialGuess', 148) GB.set_variable_attribute('x20', 'initialGuess', 27.5) # Define null model free parameters and other parameters to free nullModelFree = set(['GreyBox_r_E', 'GreyBox_r_P', 'x10', 'x20']) optimizeParameters = set(["TD","TR","A4","distE","distP"]) # Define null model free parameters and other parameters to free nullModelFree = set(['GreyBox_r_E', 'GreyBox_r_P', 'x10', 'x20']) # Optimize null model identification = GB.identify(nullModelFree) # Create dictionaries for results testcases = [] for var in optimizeParameters: # Add var to set of free parameters testcases.append(identification.release([var])) print("=======================SUMMARY========================") results = identification.compare(testcases) # reference data nullModelReferenceCost = 5631.068823 #the cost from the null model reference = {'TD':{'cost':5466.596971, 'costred':164.471852, 'risk':0.000000},'TR':{'cost':5629.636935, 'costred':1.431888, 'risk':0.731872},'A4':{'cost':5630.900339, 'costred':0.168484, 'risk':0.996721} ,'distE':{'cost':4362.561987, 'costred':1268.506836, 'risk':0.000000},'distP':{'cost':4399.728897, 'costred':1231.339926, 'risk':0.000000}} #Create reference by running without framework tol = 1e-3 # Assert nullmodel assert(N.abs(identification.cost - nullModelReferenceCost) < tol) # Assert results for i, var in enumerate(optimizeParameters): assert(N.abs(results[i]['cost'] - reference[var]['cost']) < tol) assert(N.abs(results[i]['costred'] - reference[var]['costred']) < tol) assert(N.abs(results[i]['risk'] - reference[var]['risk']) < tol)
import numpy as np from scipy.io.matlab.mio import savemat from IPython.core.debugger import Tracer; dh = Tracer() # import the jmodelica.org python packages from pymodelica import compile_fmux from pyjmi import JMUModel from pymodelica.common.io import ResultDymolaTextual import matplotlib.pyplot as plt from pyjmi import transfer_optimization_problem # compile model with_plots = True with_plots = False object = transfer_optimization_problem('turn','turn.mop', compiler_options={"enable_variable_scaling":True}) opts = object.optimize_options() opts['IPOPT_options']['linear_solver'] = "ma27" #~ opts['IPOPT_options']['ma27_pivtol'] = 1e-3 #~ opts['IPOPT_options']['max_iter'] = 0 opts['IPOPT_options']['tol'] = 1e-9 #opts['IPOPT_options']['generate_hessian'] = True opts['n_e'] = 150 opts['n_cp'] = 3 #initGuess = ResultDymolaTextual(os.path.join(currdir,'turn_result.txt')) initGuess = ResultDymolaTextual(os.path.join(currdir,'vehicle_turn_dymola.txt')) opts['init_traj'] = initGuess state_names = ['delta', 'Twf', 'Twr',