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
Esempio n. 3
0
    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)
Esempio n. 4
0
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
Esempio n. 5
0
    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)
Esempio n. 6
0
 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
Esempio n. 8
0
 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))
Esempio n. 14
0
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
Esempio n. 15
0
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()
Esempio n. 19
0
    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)
Esempio n. 20
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()
Esempio n. 21
0
    #~ 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":
Esempio n. 22
0
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
Esempio n. 23
0
            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()])
Esempio n. 24
0
def run_demo(with_plots=True):
    """
    This example is based on the Hicks-Ray Continuously Stirred Tank Reactors 
    (CSTR) system. The system has two states, the concentration and the 
    temperature. The control input to the system is the temperature of the 
    cooling flow in the reactor jacket. The chemical reaction in the reactor is 
    exothermic, and also temperature dependent; high temperature results in high 
    reaction rate.
    
    The 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()
Esempio n. 25
0
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
Esempio n. 26
0
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)
Esempio n. 27
0
# 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)
						
Esempio n. 28
0
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)
Esempio n. 29
0
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()
Esempio n. 32
0
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()
Esempio n. 33
0
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
Esempio n. 34
0
    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)
Esempio n. 35
0
def run_demo(with_plots=True):
    """
    This example is based on the Hicks-Ray Continuously Stirred Tank Reactors 
    (CSTR) system. The system has two states, the concentration and the 
    temperature. The control input to the system is the temperature of the 
    cooling flow in the reactor jacket. The chemical reaction in the reactor is 
    exothermic, and also temperature dependent; high temperature results in high 
    reaction rate.
    
    The 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()
Esempio n. 36
0
def run_demo(with_plots=True):
    """
    This example is based on the Hicks-Ray Continuously Stirred Tank Reactors 
    (CSTR) system. The system has two states, the concentration and the 
    temperature. The control input to the system is the temperature of the 
    cooling flow in the reactor jacket. The chemical reaction in the reactor is 
    exothermic, and also temperature dependent; high temperature results in 
    high reaction rate.

    The 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()
Esempio n. 37
0
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)
Esempio n. 38
0
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)
Esempio n. 40
0
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',