Exemple #1
0
def simulate_multiple_fmus():
    """Simulate one CYMDIST FMU coupled to a GridDyn FMU.
        
    """
    cymdist=load_fmu("CYMDIST.fmu", log_level=7)
    gridyn=load_fmu("GridDyn.fmu", log_level=7)
    
    models = [cymdist, gridyn]
    connections = [(gridyn, "VMAG_A", cymdist, "VMAG_A"),
                   (gridyn, "VMAG_B", cymdist, "VMAG_B"),
                   (gridyn, "VMAG_C", cymdist, "VMAG_C"),
                   (gridyn, "VANG_A", cymdist, "VANG_A"),
                   (gridyn, "VANG_B", cymdist, "VANG_B"),
                   (gridyn, "VANG_C", cymdist, "VANG_C"),
                   (cymdist, "KWA_800032440", gridyn, "KWA_800032440"),
                   (cymdist, "KWB_800032440", gridyn, "KWB_800032440"),
                   (cymdist, "KWC_800032440", gridyn, "KWC_800032440"),
                   (cymdist, "KVARA_800032440", gridyn, "KVARA_800032440"),
                   (cymdist, "KVARB_800032440", gridyn, "KVARB_800032440"),
                   (cymdist, "KVARC_800032440", gridyn, "KVARC_800032440"),]
    
    coupled_simulation = Master (models, connections)

    opts=coupled_simulation.simulate_options()
    opts['step_size']=1.0
    opts['logging']=True

    res=coupled_simulation.simulate(options=opts, 
                            start_time=0.0, 
                            final_time=1.0)
Exemple #2
0
    def load(self, fmu_path, output_dir):
        """Load the FMU for continued simulation in :meth:`continue_run`.
        """

        import pyfmi

        if 'log_level' in self._options:
            self.fmu = pyfmi.load_fmu(fmu_path, log_level=self.log_level)
        else:
            self.fmu = pyfmi.load_fmu(fmu_path)

        # Initialize the fmu, only call setup_experiment for FMUs 2.0
        try:
            self.fmu.setup_experiment()
            version = 2
        except AttributeError:
            version = 1

        self.fmu.initialize()

        # Copy the log file to the result directory
        log = ''
        if version == 1:
            log = self.fmu.get_identifier()
        if version == 2:
            log = self.fmu.get_name()
        log += '_log.txt'
        source = os.path.join(os.getcwd(), log)
        destination = os.path.join(output_dir, 'log%i.txt' % self.interval)
        move(source, destination)
Exemple #3
0
def simulate_cymdist_griddyn_fmus():
    """Simulate one CYMDIST FMU coupled to a dummy griddyn FMU.
        
    """
    
    # Parameters which will be arguments of the function
    start_time = 0.0
    stop_time  = 0.1
    step_size  = 0.1

    # Path to configuration file
    path_config="Z:\\thierry\\proj\\cyder_repo\\NO_SHARING\\CYMDIST\\config.json"
    cymdist_con_val_str = bytes(path_config, 'utf-8')

    cymdist=load_fmu("../fmus/CYMDIST/CYMDIST.fmu", log_level=7)
    griddyn=load_fmu("../fmus/griddyn/griddyn14bus.fmu", log_level=7)
    
    models = [cymdist, griddyn]
    connections = [(griddyn, "Bus11_VA", cymdist, "VMAG_A"),
                   (griddyn, "Bus11_VB", cymdist, "VMAG_B"),
                   (griddyn, "Bus11_VC", cymdist, "VMAG_C"),
                   (griddyn, "Bus11_VAngleA", cymdist, "VANG_A"),
                   (griddyn, "Bus11_VAngleB", cymdist, "VANG_B"),
                   (griddyn, "Bus11_VAngleC", cymdist, "VANG_C"),
                   (cymdist, "IA", griddyn, "Bus11_IA"),
                   (cymdist, "IB", griddyn, "Bus11_IB"),
                   (cymdist, "IC", griddyn, "Bus11_IC"),
                   (cymdist, "IAngleA", griddyn, "Bus11_IAngleA"),
                   (cymdist, "IAngleB", griddyn, "Bus11_IAngleB"),
                   (cymdist, "IAngleC", griddyn, "Bus11_IAngleC")]
    
    coupled_simulation = Master (models, connections)
    
    opts=coupled_simulation.simulate_options()
    opts['step_size']=step_size
    
    # Get the configuration file 
    cymdist_con_val_ref = cymdist.get_variable_valueref("_configurationFileName")

    cymdist.set("_saveToFile", 0)
    cymdist.set_string([cymdist_con_val_ref], [cymdist_con_val_str])
    
    # Set the communication step size
    cymdist.set("_communicationStepSize", step_size)
        
    # Set the value of the multiplier
    griddyn.set('multiplier', 3.0)
    
    # Run simulation
    start = datetime.now()
    res=coupled_simulation.simulate(options=opts, 
                            start_time=start_time, 
                            final_time=stop_time)
    end = datetime.now()
    
    print('This is the voltage value (VMAG_A) in Cymdist' + str(res[cymdist]['VMAG_A']))
    print('This is the current value (IA) in Cymdist' + str(res[cymdist]['IA']))
    print('Ran a coupled CYMDIST/GridDyn simulation in ' +
          str((end - start).total_seconds()) + ' seconds.')
 def test_ExtFuncShared(self):
     """ 
     Test compiling a model with external functions in a shared library. Real, Integer, and Boolean arrays.
     """
     fmu_name = compile_fmu(self.cpath, self.fpath, compiler_options={'variability_propagation':True})
     model = load_fmu(fmu_name)
     s_ceval = model.get('s')
     res = model.simulate()
     s_sim1 = res.final('s')
     
     fmu_name = compile_fmu(self.cpath, self.fpath, compiler_options={'variability_propagation':False})
     model = load_fmu(fmu_name)
     res = model.simulate()
     s_sim2 = res.final('s')
     nose.tools.assert_equals(s_sim1, s_sim2)
def run_demo(with_plots=True):
    
    curr_dir = os.path.dirname(os.path.abspath(__file__));
    class_name = 'ExtFunctions.transposeSquareMatrix'
    mofile = os.path.join(curr_dir, 'files', 'ExtFunctions.mo')
    
    # Compile and load model
    fmu_name = compile_fmu(class_name, mofile)
    model = load_fmu(fmu_name)

    # Simulate
    res = model.simulate()
    
    # Get result data
    b1_1 = res['b_out[1,1]']
    b1_2 = res['b_out[1,2]']
    b2_1 = res['b_out[2,1]']
    b2_2 = res['b_out[2,2]']
    t = res['time']

    assert N.abs(res.final('b_out[1,1]') - 1) < 1e-6
    assert N.abs(res.final('b_out[1,2]') - 3) < 1e-6
    assert N.abs(res.final('b_out[2,1]') - 2) < 1e-6
    assert N.abs(res.final('b_out[2,2]') - 4) < 1e-6 
           
    if with_plots:
        fig = p.figure()
        p.clf()
        p.plot(t, b1_1, label='b1_1')
        p.plot(t, b1_2, label='b1_2')
        p.plot(t, b2_1, label='b2_1')
        p.plot(t, b2_2, label='b2_2')
        p.legend()
        p.grid()
        p.show()
Exemple #6
0
def run_demo(with_plots=True):
    """
    This example shows how to simulate a system that contains switches. The 
    example model is simple in the sense that no reinitialization of the 
    variables is needed at the event points.
    """

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

    class_name = 'IfExpExamples.IfExpExample2'
    mofile = curr_dir+'/files/IfExpExamples.mo'

    fmu_name = compile_fmu(class_name, mofile)

    # Load the dynamic library and XML data
    model = load_fmu(fmu_name)

    # Simulate
    res = model.simulate(final_time=5.0)
    
    # Get results
    x = res['x']
    u = res['u']
    t = res['time']
    
    assert N.abs(res.final('x') - 3.5297217)    < 1e-3
    assert N.abs(res.final('u') - (-0.2836621)) < 1e-3

    if with_plots:
        fig = p.figure()
        p.plot(t, x, t, u)
        p.legend(('x','u'))
        p.show()
Exemple #7
0
def simulate_single_griddyn_fmu():
    """Simulate one griddyn FMU.
        
    """
    
    # Parameters which will be arguments of the function
    start_time = 0.0
    stop_time  = 0.1
    
    griddyn=load_fmu("../../../../NO_SHARING/griddyn/Test/griddyn.fmu", log_level=7)
    # Set the inputs
    opts=griddyn.simulate_options()
    opts['ncp']=1.0

    # Set the model name reference to be completed in Python API
    griddyn.set("power", 10)
    # Run simulation    
    start = datetime.now()
    res=griddyn.simulate(start_time=start_time, 
                        final_time=stop_time, 
                        options=opts)    
    end = datetime.now()
    
    print('This is the time value ' + str(res['time']))
    print('This is the load value ' + str(res['load']))
    print('Ran a single GridDyn simulation in ' +
          str((end - start).total_seconds()) + ' seconds.')
Exemple #8
0
def run_demo(with_plots=True):
    """
    Demonstrates how to use an JMODELICA generated FMU for sensitivity
    calculations.
    """
    curr_dir = os.path.dirname(os.path.abspath(__file__));

    fmu_name = compile_fmu("Robertson", curr_dir+"/files/Robertson.mo")
        
    model = load_fmu(fmu_name)
        
    # Get and set the options
    opts = model.simulate_options()
    opts['sensitivities'] = ["p1","p2","p3"]
    opts['ncp'] = 400

    #Simulate
    res = model.simulate(final_time=4, options=opts)

    dy1dp1 = res['dy1/dp1']
    dy2dp1 = res['dy2/dp1']
    time = res['time']
        
    nose.tools.assert_almost_equal(dy1dp1[40], -0.35590, 3)
    nose.tools.assert_almost_equal(dy2dp1[40],  3.9026e-04, 6)
    
    if with_plots:
        plt.plot(time, dy1dp1, time, dy2dp1)
        plt.legend(('dy1/dp1', 'dy2/dp1'))
        plt.show()
def run_demo(with_plots=True):
    """
    Demonstrates how to simulate an FMU with an input function.
    
    See also simulation_with_input.py
    """
    fmu_name = O.path.join(path_to_fmus_me1,'SecondOrder.fmu')

    # Create input object
    input_object = ('u', N.cos)

    # Load the dynamic library and XML data
    model = load_fmu(fmu_name)

    # Simulate
    res = model.simulate(final_time=30, input=input_object, options={'ncp':3000})

    x1_sim = res['x1']
    x2_sim = res['x2']
    u_sim = res['u']
    time_sim = res['time']
        
    assert N.abs(res.final('x1') - (-1.646485144)) < 1e-3
    assert N.abs(res.final('x2')*1.e1 - (-7.30591626709)) < 1e-3  
    assert N.abs(res.final('u')*1.e1 - (1.54251449888)) < 1e-3    

    if with_plots:
        fig = p.figure()
        p.subplot(2,1,1)
        p.plot(time_sim, x1_sim, time_sim, x2_sim)
        p.subplot(2,1,2)
        p.plot(time_sim, u_sim)
        p.show()
Exemple #10
0
def run_demo(with_plots=True):
    
    curr_dir = os.path.dirname(os.path.abspath(__file__));
    class_name = 'ExtFunctions.addTwo'
    mofile = os.path.join(curr_dir, 'files', 'ExtFunctions.mo')
    
    # Compile and load model
    fmu_name = compile_fmu(class_name, mofile)
    model = load_fmu(fmu_name)

    # Simulate
    res = model.simulate()
    
    # Load result data
    sim_a = res['a']
    sim_b = res['b']
    sim_c = res['c']
    t     = res['time']

    assert N.abs(res.final('a') - 1) < 1e-6
    assert N.abs(res.final('b') - 2) < 1e-6
    assert N.abs(res.final('c') - 3) < 1e-6

    if with_plots:
        fig = p.figure()
        p.clf()
        p.subplot(3,1,1)
        p.plot(t, sim_a)
        p.subplot(3,1,2) 
        p.plot(t, sim_b) 
        p.subplot(3,1,3)
        p.plot(t, sim_c)
        p.show()
Exemple #11
0
def run_demo(with_plots=True):
    """
    An example on how to simulate a model using the DAE simulator. The result 
    can be compared with that of sim_rlc.py which has solved the same problem 
    using dymola. Also writes information to a file.
    """

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

    class_name = 'RLC_Circuit'
    mofile = curr_dir+'/files/RLC_Circuit.mo'
    
    fmu_name = compile_fmu(class_name, mofile)
    rlc = load_fmu(fmu_name)
    
    res = rlc.simulate(final_time=30)
    
    sine_y = res['sine.y']
    resistor_v = res['resistor.v']
    inductor1_i = res['inductor1.i']
    t = res['time']

    assert N.abs(res.final('resistor.v') - 0.159255008028) < 1e-3
    
    if with_plots:
        fig = p.figure()
        p.plot(t, sine_y, t, resistor_v, t, inductor1_i)
        p.legend(('sine.y','resistor.v','inductor1.i'))
        p.show()
def run_demo(with_plots=True):
    """
    Demonstrates how to simulate an FMU with an input function.
    
    See also simulation_with_input.py
    """
    fmu_name = O.path.join(path_to_fmus, "SecondOrder.fmu")

    # Create input object
    input_object = ("u", N.cos)

    # Load the dynamic library and XML data
    model = load_fmu(fmu_name)

    # Simulate
    res = model.simulate(final_time=30, input=input_object, options={"ncp": 3000})

    x1_sim = res["x1"]
    x2_sim = res["x2"]
    u_sim = res["u"]
    time_sim = res["time"]

    assert N.abs(x1_sim[-1] - (-1.646485144)) < 1e-3

    assert N.abs(x2_sim[-1] * 1.0e1 - (-7.30591626709)) < 1e-3

    assert N.abs(u_sim[-1] * 1.0e1 - (1.54251449888)) < 1e-3

    if with_plots:
        fig = p.figure()
        p.subplot(2, 1, 1)
        p.plot(time_sim, x1_sim, time_sim, x2_sim)
        p.subplot(2, 1, 2)
        p.plot(time_sim, u_sim)
        p.show()
Exemple #13
0
    def f1(x):

        model = load_fmu(fmu_name)

        # We need to scale the inputs x down since they are scaled up 
        # versions of a1 and a2 (x = scalefactor*[a1 a2])
        a1 = x[0]/1e6
        a2 = x[1]/1e6
        
        # Set new values for a1 and a2 into the model 
        model.set('qt.a1',a1)
        model.set('qt.a2',a2)
        
        # Create options object and set verbosity to zero to disable printouts
        opts = model.simulate_options()
        opts['CVode_options']['verbosity'] = 0
        
        # Simulate model response with new parameters a1 and a2
        res = model.simulate(input=(['u1','u2'],u),start_time=0.,final_time=60,options=opts)
        
        # Load simulation result
        x1_sim = res['qt.x1']
        x2_sim = res['qt.x2']
        t_sim  = res['time']
        
        # Evaluate the objective function
        y_meas = N.vstack((y1_meas,y2_meas))
        y_sim = N.vstack((x1_sim,x2_sim))
        obj = dfo.quad_err(t_meas,y_meas,t_sim,y_sim)
        
        return obj
Exemple #14
0
def run_demo(with_plots=True, version="2.0"):	

	# Compile model
	fmu_name = compile_fmu("IBPSA.Fluid.FixedResistances.Examples.PlugFlowPipe","C:\My_Libs\modelica-ibpsa\IBPSA")
	fmu_name=("IBPSA_Fluid_FixedResistances_Examples_PlugFlowPipe.fmu")
	#print("FMU compiled",fmu_name)
	print(fmu_name)

	# Load model
	pipe = load_fmu(fmu_name)

	print("FMU loaded", pipe)

	res = pipe.simulate(final_time=100)
		
	x1 = res['Tin.offset']
	x2 = res['sou.m_flow']
	t = res['time']
		
	plt.figure(1)
	plt.plot(t, x1, t, x2)
	plt.legend(('Tin (K)','mdot (kg/s)'))
	plt.title('Pipe')
	plt.ylabel('y axis')
	plt.xlabel('Time (s)')
	plt.show()
def run_demo(with_plots=True):
    """
    Distillation2 model
    """

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

    fmu_name = compile_fmu("JMExamples.Distillation.Distillation2", 
    curr_dir+"/files/JMExamples.mo")
    dist2 = load_fmu(fmu_name)
    
    res = dist2.simulate(final_time=7200)

    # Extract variable profiles
    x16	= res['x[16]']
    x32	= res['x[32]']
    t	= res['time']
    
    print "t = ", repr(N.array(t))
    print "x16 = ", repr(N.array(x16))
    print "x32 = ", repr(N.array(x32))

    if with_plots:
        # Plot
        plt.figure(1)
        plt.plot(t,x16,t,x32)
        plt.grid()
        plt.ylabel('x')
        
        plt.xlabel('time')
        plt.show()
def furuta_dfo_cost(x):

    # We need to scale the inputs x down since they are scaled up 
    # versions of the parameters (x = scalefactor*[param1 param2])
    armFrictionCoefficient = x[0]/1e3
    pendulumFrictionCoefficient = x[1]/1e3
    
    model = load_fmu(os.path.join(curr_dir, '..', 'examples', 'files', 'FMUs', 'Furuta.fmu'))

    # Set new parameter values into the model 
    model.set('armFriction', armFrictionCoefficient)
    model.set('pendulumFriction', pendulumFrictionCoefficient)
    
    # Create options object and set verbosity to zero to disable printouts
    opts = model.simulate_options()
    opts['CVode_options']['verbosity'] = 0
    
    # Simulate model response with new parameter values
    res = model.simulate(start_time=0., final_time=40, options=opts)
    
    # Load simulation result
    phi_sim = res['armJoint.phi']
    theta_sim = res['pendulumJoint.phi']
    t_sim  = res['time']
    
    # Evaluate the objective function
    y_meas = N.vstack((phi_meas, theta_meas))
    y_sim = N.vstack((phi_sim, theta_sim))
    obj = dfo.quad_err(t_meas, y_meas, t_sim, y_sim)

    return obj
 def test_ExtFuncStatic(self):
     """ 
     Test compiling a model with external functions in a static library.
     """
     cpath = "ExtFunctionTests.ExtFunctionTest1"
     fmu_name = compile_fmu(cpath, TestExternalStatic.fpath)
     model = load_fmu(fmu_name)
Exemple #18
0
def run_demo(with_plots=True):
    """
    An example on how to simulate a model using the ODE simulator.
    """
    curr_dir = os.path.dirname(os.path.abspath(__file__));
    file_name = os.path.join(curr_dir,'files','VDP.mop')
    
    fmu_name = compile_fmu("JMExamples.VDP.VDP", 
    curr_dir+"/files/JMExamples.mo")

    model = load_fmu(fmu_name)
    
    opts = model.simulate_options()
    opts["CVode_options"]["rtol"] = 1e-6
    
    res = model.simulate(final_time=10, options=opts)

    assert N.abs(res.final('x1') - 7.34186386e-01) < 1e-3
    assert N.abs(res.final('x2') + 1.58202722)    < 1e-3
    
    x1 = res['x1']
    x2 = res['x2']
    
    if with_plots:
        plt.figure()
        plt.plot(x2, x1)
        plt.legend(('x1(x2)'))
        plt.show()
def run_demo(with_plots=True):
    """
    Demonstrates how to use PyFMI for simulation of 
    Co-Simulation FMUs (version 1.0).
    """
    fmu_name = O.path.join(path_to_fmus,'bouncingBall.fmu')
    model = load_fmu(fmu_name)
    
    res = model.simulate(final_time=2.)
    
    # Retrieve the result for the variables
    h_res = res['h']
    v_res = res['v']
    t     = res['time']

    assert N.abs(res.final('h') - (0.0424044)) < 1e-2
    
    # Plot the solution
    if with_plots:
        # Plot the height
        fig = P.figure()
        P.clf()
        P.subplot(2,1,1)
        P.plot(t, h_res)
        P.ylabel('Height (m)')
        P.xlabel('Time (s)')
        # Plot the velocity
        P.subplot(2,1,2)
        P.plot(t, v_res)
        P.ylabel('Velocity (m/s)')
        P.xlabel('Time (s)')
        P.suptitle('FMI Bouncing Ball')
        P.show()
Exemple #20
0
def run_demo(with_plots=True):
    """
    An example on how to simulate a model using a DAE simulator with Assimulo. 
    The model used is made by Maja Djačić.
    """

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

    m_name = 'SolAngles'
    mofile = curr_dir+'/files/SolAngles.mo'
    
    fmu_name = compile_fmu(m_name, mofile)
    model = load_fmu(fmu_name)
    
    res = model.simulate(final_time=86400.0, options={'ncp':86400})

    theta = res['theta']
    azim = res['azim']
    N_day = res['N_day']
    time = res['time']
    
    assert N.abs(res.final('theta') - 90.28737353) < 1e-3
    
    # Plot results
    if with_plots:
        p.figure(1)
        p.plot(time, theta)
        p.xlabel('time [s]')
        p.ylabel('theta [deg]')
        p.title('Angle of Incidence on Surface')
        p.grid()
        p.show()
Exemple #21
0
 def test_inlined_switches(self):
     """ Test a model that need in-lined switches to initialize. """
     path = os.path.join(get_files_path(), 'Modelica', 'event_init.mo')
     fmu_name = compile_fmu('Init', path)
     model = load_fmu(fmu_name)
     model.initialize()
     assert N.abs(model.get("x") - (-2.15298995))              < 1e-3
Exemple #22
0
    def simulate(self):
        ''' TODO: LOG all command omc '''
#         tic= timeit.default_timer()
        # Simulation process with JModelica
        fullMoFile= self.moPath+ '/'+ self.moFile
        fullMoLib= self.libPath+ '/'+ self.libFile
        '''build the fmu block from the modelica model '''
#         fmu_name= compile_fmu(self.moModel, absolutePath,
#                                compiler_options = {'extra_lib_dirs':self.libPath})
        fmu_name= compile_fmu(self.moModel, [fullMoFile, fullMoLib])
        ''' Load the model '''
        model_fmu= load_fmu(fmu_name)
    
        ''' Load the list of options for the JModelica compiler '''
        opts = model_fmu.simulate_options()
        opts['solver']= self.config.getSolver()
        opts['ncp']= self.config.getNcp()
    #     for key,value in simOpt.getOptions().items():
    #         print key,value
    #         opts[key] = value
        print opts
        result = model_fmu.simulate(start_time= self.config.getStartTime(), 
                                    final_time= self.config.getStopTime(), 
                                    options=opts)
    
#         toc= timeit.default_timer()
#         print 'Simulation time ', toc- tic
        
        return result
def run_demo(with_plots=True):
    """ 
    Example demonstrating how to use index reduction.
    """

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

    # Compile model
    fmu_name = compile_fmu("Pendulum_pack.PlanarPendulum", 
        curr_dir+"/files/Pendulum_pack.mop",compiler='optimica')

    # Load model
    model = load_fmu(fmu_name)
    
    # Options
    opts = model.simulate_options()
    opts["CVode_options"]["rtol"] = 1e-6
    
    # Load result file
    res = model.simulate(final_time=10., options=opts)

    x = res['x']
    st = res['st']
    ct = res['ct']
    err = res['err']
    y = res['y']
    vx = res['vx']
    vy = res['vy']
    t = res['time']
    maxerr = N.max(err)

    if maxerr > 1e-6:
        print "Maximum error: ", maxerr 
        assert maxerr < 1e-4
    
    assert N.abs(res.final('x') - 0.38735171)       < 1e-3
    assert N.abs(res.final('st') - 0.38733358)      < 1e-3
    assert N.abs(res.final('ct') + 0.92193964)      < 1e-3
    assert N.abs(res.final('err') - 1.96716163e-05) < 1e-3
    assert N.abs(res.final('y') + 0.92193202)       < 1e-3
    assert N.abs(res.final('vx') - 6.04839823e-01)  < 1e-3
    assert N.abs(res.final('vy') - 2.54124747e-01)  < 1e-3

    if with_plots:
        plt.figure(1)
        plt.subplot(3,1,1)
        plt.plot(t,x,t,y)
        plt.grid(True)
        plt.legend(['x','y'])
        plt.subplot(3,1,2)
        plt.plot(t,vx,t,vy)
        plt.grid(True)
        plt.legend(['vx','vy'])
        plt.subplot(3,1,3)
        plt.plot(t,err)
        plt.grid(True)
        plt.legend(['err'])
        plt.xlabel('time [s]')
        plt.show()
Exemple #24
0
def run_demo(with_plots=True):
    """
    Simulation of a model that predicts the blood glucose levels of a type-I 
    diabetic. The objective is to predict the relationship between insulin 
    injection and blood glucose levels.
    
    Reference:
     S. M. Lynch and B. W. Bequette, Estimation based Model Predictive Control of Blood Glucose in 
     Type I Diabetes: A Simulation Study, Proc. 27th IEEE Northeast Bioengineering Conference, IEEE, 2001.
     
     S. M. Lynch and B. W. Bequette, Model Predictive Control of Blood Glucose in type I Diabetics 
     using Subcutaneous Glucose Measurements, Proc. ACC, Anchorage, AK, 2002. 
    """

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

    fmu_name1 = compile_fmu("JMExamples.BloodGlucose.BloodGlucose1", os.path.join(curr_dir, "files", "JMExamples.mo"))
    bg = load_fmu(fmu_name1)

    opts = bg.simulate_options()
    opts["CVode_options"]["rtol"] = 1e-6

    res = bg.simulate(final_time=400, options=opts)

    # Extract variable profiles
    G = res["G"]
    X = res["X"]
    I = res["I"]
    t = res["time"]

    assert N.abs(res.final("G") - 19.77650) < 1e-4
    assert N.abs(res.final("X") - 14.97815) < 1e-4
    assert N.abs(res.final("I") - 2.7) < 1e-4

    if with_plots:
        plt.figure(1)

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

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

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

        plt.show()
 def __reset_model(self):
     """
     Loads the model / resets it if it's loaded.
     """
     if self.fmu == None:
         self.fmu = load_fmu(self.fmu_path)
     else:
         self.fmu.reset()
 def test_ModelicaUtilities(self):
     """ 
     Test compiling a model with external functions using the functions in ModelicaUtilities.
     """
     fpath = path(get_files_path(), 'Modelica', "ExtFunctionTests.mo")
     cpath = "ExtFunctionTests.ExtFunctionTest3"
     jmu_name = compile_fmu(cpath, fpath)
     model = load_fmu(jmu_name)
 def test_ExtFuncSharedCeval(self):
     """ 
     Test compiling a model with external functions in a shared library. Constant evaluation during compilation.
     """
     cpath = "ExtFunctionTests.ExtFunctionTest1"
     fmu_name = compile_fmu(cpath, TestExternalShared.fpath, compiler_options={'variability_propagation':True})
     model = load_fmu(fmu_name)
     nose.tools.assert_equals(model.get('c'), 3)
 def test_ExtFuncShared(self):
     """ 
     Test compiling a model with external functions in a shared library. Simple.
     """
     cpath = "ExtFunctionTests.ExtFunctionTest1"
     fmu_name = compile_fmu(cpath, TestExternalShared.fpath, compiler_options={'variability_propagation':False})
     model = load_fmu(fmu_name)
     res = model.simulate()
     nose.tools.assert_equals(res.final('c'), 3) 
    def test_ExtFuncBool(self):
        """ 
        Test compiling a model with external functions in a shared library. Boolean arrays.
        """
        fmu_name = compile_fmu(self.cpath, self.fpath, compiler_options={'variability_propagation':False})
        model = load_fmu(fmu_name)
        model.simulate()
        fmu_name = compile_fmu(self.cpath, self.fpath, compiler_options={'variability_propagation':True})
        model2 = load_fmu(fmu_name)
        model2.simulate()
        trueInd  = {1,2,3,5,8}
        falseInd = {4,6,7}
        for i in trueInd:
            assert(model.get('res[' + str(i) + ']'))
            assert(model2.get('res[' + str(i) + ']'))
        for i in falseInd:
		    assert(not model.get('res[' + str(i) + ']'))
		    assert(not model2.get('res[' + str(i) + ']'))
 def test_simulate(self):
     cpath = 'Asserts.ModelicaError'
     fmu_name = compile_fmu(cpath, TestModelicaError.fpath)
     model = load_fmu(fmu_name)
     try:
         model.simulate(final_time = 3)
         assert False, 'Simulation not stopped by calls to ModelicaError()'
     except CVodeError, e:
         assert abs(e.t - 2.0) < 0.01, 'Simulation stopped at wrong time'
def run_demo():
    """
    Demonstrate how to parse a log file from a JModelica FMU.
    """

    curr_dir = os.path.dirname(os.path.abspath(__file__))
    file_name = os.path.join(curr_dir, 'files', 'LoggerTest.mo')

    fmu_name = compile_fmu(
        'LoggerTest',
        file_name,
        compiler_log_level='i',
        compiler_options={'generate_only_initial_system': True})
    log_file_name = 'LoggerTest_log.txt'
    m = load_fmu(fmu_name, log_file_name=log_file_name)

    m.set_debug_logging(True)
    m.set('_log_level', 6)
    m.set_fmil_log_level(5)

    # Play around with the model

    m.set('u1', 3)

    print 'u1' + str(m.get('u1'))
    print 'x1' + str(m.get('x1'))
    print 'y1' + str(m.get('y1'))
    print 'z1' + str(m.get('z1'))

    m.set('y1', 0.)

    m.initialize()

    print "model initialized"

    print 'u1' + str(m.get('u1'))
    print 'x1' + str(m.get('x1'))
    print 'y1' + str(m.get('y1'))
    print 'z1' + str(m.get('z1'))

    m.set('u1', 4)

    print "Input set"

    print 'u1' + str(m.get('u1'))
    print 'x1' + str(m.get('x1'))
    print 'y1' + str(m.get('y1'))
    print 'z1' + str(m.get('z1'))

    m.get_derivatives()

    m.set('y1', 0.5)

    print "Set initial value of y1"

    print 'x1' + str(m.get('x1'))
    print 'y1' + str(m.get('y1'))
    print 'z1' + str(m.get('z1'))

    m.set('p', 0.5)

    print "Set initial value of p"

    print 'x1' + str(m.get('x1'))
    print 'y1' + str(m.get('y1'))
    print 'z1' + str(m.get('z1'))

    # Parse the log file and print some of its contents

    # Extract the log file XML contents into a pure XML file
    dest_xml_file_name = 'LoggerTest_log.xml'
    extract_jmi_log(dest_xml_file_name, log_file_name)

    # Parse the entire XML log
    log = parse_jmi_log(log_file_name)

    print
    print 'Top log node:        log =', log
    print 'Unnamed sub nodes:   log.nodes = ['
    for node in log.nodes:
        print '   ', node, ','
    print ']'
    print 'Time of first solve: log.nodes[0].t =', log.nodes[0].t

    # Gather information pertaining to equation solves
    solves = gather_solves(log)

    print
    print 'Number of solver invocations:', len(solves)
    print 'Time of first solve:', solves[0].t
    print 'Number of block solves in first solver invocation:', len(
        solves[0].block_solves)
    print 'Names of iteration variables in first block solve:', solves[
        0].block_solves[0].variables
    print 'Min bounds in first block solve:', solves[0].block_solves[0].min
    print 'Max bounds in first block solve:', solves[0].block_solves[0].max
    print 'Initial residual scaling in first block solve:', solves[
        0].block_solves[0].initial_residual_scaling
    print 'Number of iterations in first block solve:', len(
        solves[0].block_solves[0].iterations)
    print
    print 'First iteration in first block solve: '
    print '  Iteration variables:', solves[0].block_solves[0].iterations[0].ivs
    print '  Scaled residuals:', solves[0].block_solves[0].iterations[
        0].residuals
    print '  Jacobian:\n', solves[0].block_solves[0].iterations[0].jacobian
    print '  Jacobian updated in iteration:', solves[0].block_solves[
        0].iterations[0].jacobian_updated
    print '  Residual scaling factors:', solves[0].block_solves[0].iterations[
        0].residual_scaling
    print '  Residual scaling factors_updated:', solves[0].block_solves[
        0].iterations[0].residual_scaling_updated
    print '  Scaled residual norm:', solves[0].block_solves[0].iterations[
        0].scaled_residual_norm
Exemple #32
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.final('c_ref')  # extract constant value as last element
    T_ref = res.final('T_ref')
    Tc_ref = res.final('Tc_ref')

    # 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()
from pymodelica import compile_fmu
from pyfmi import load_fmu
import matplotlib.pyplot as P
import matplotlib.dates as md
import pandas as pd
import numpy as N
import matplotlib.ticker as mtick

fmu_name = compile_fmu("MultizoneVAV.UncertaintyModels.VAVReheat.Guideline36_deterministic", jvm_args='-Xmx4g', compiler_options={"generate_html_diagnostics":True},compiler_log_level='error')
model= load_fmu(fmu_name,log_level=7)
dayOfYear_start=7*(24*60*60)
hourOfDay_start=0*(60*60)
minuteOfHour_start=0*(60)

daySimRange=0*(24*60*60)
hourSimRange=12*(60*60)
minuteSimRange=0*(60)

sim_Start = dayOfYear_start+hourOfDay_start+minuteOfHour_start
SimulationRange = daySimRange+hourSimRange+minuteSimRange

res=model.simulate(start_time=sim_Start, final_time=sim_Start+SimulationRange)

# Convert from K to C
conv_K_C=273.15

# Time
t=res['time']
timestamps = pd.to_datetime(t, unit='s')

# Physical zone air temperature for the two thermal zones without noise
L_d = ot.Uniform(250.0, 260.0)
I_d = ot.Beta(2.5, 4.0-2.5, 310.0, 450.0)
distribution = ot.ComposedDistribution([E_d, F_d, I_d, L_d])
x = distribution.getMean()


f = model.getFunction()
y = f(x)
ott.assert_almost_equal(y, [12.3369])

# script
script = myStudy.getPythonScript()
print('script=', script)
exec(script)


# compare with pyfmi directly
if 0:
    import pyfmi
    import otfmi

    # print(path_fmu)
    model_fmu = model_fmu = otfmi.FMUFunction(
        path_fmu, inputs_fmu=['E', 'F', 'I', 'L'], outputs_fmu='y')

    ml = pyfmi.load_fmu(path_fmu)
    vars = ml.get_model_variables()
    for var in vars.values():
        print(var.name, var.value_reference)
        # print(ml.get_real(var.value_reference))
Exemple #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.
    
    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 list(constr_x_est.keys()):
            constr_x_est[key].append(constr_x_est_t[key])
        for key in list(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 list(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 list(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()
Exemple #36
0
from pymodelica import compile_fmu
from pyfmi import load_fmu
import matplotlib.pyplot as plt
import numpy as np

fmu_name = 'IEEE_39_Buses'

name = compile_fmu(fmu_name, fmu_name + ".mo")
print('Loading model...............')
print('.........................................')
model = load_fmu(fmu_name + '.fmu')

opts = model.simulate_options()

opts['solver'] = 'CVode'  # Not necessary, default solver is CVode
#opts["ncp"] = 200 #Specify that 1000 output points should be returned
# opts['ncp'] = 1000 # Changing the number of communication points.
opts['CVode_options'][
    'discr'] = 'Adams'  # Change from using BDF to Adams / quicker
#opts['initialize'] = False #  initialize the model

opts['CVode_options']['atol'] = 1.0e-6  # Options specific for CVode
opts['CVode_options']['rtol'] = 1.0e-3  # Options specific for CVode
# opts['CVode_options']['atol'] = 1.0e-6 # Options specific for CVode

#opts['filter'] =['line_4_5.P12','line_4_5.Q12']
#opts['result_handling']='memory'
#Specifies options
# sim.discr = 'Adams'     #Sets the discretization method
# sim.iter = 'FixedPoint' #Sets the iteration method
# sim.rtol = 1.e-8        #Sets the relative tolerance
Exemple #37
0
def run_demo(with_plots=True, use_ma57=True, latex_plots=False):
    """
    This example is based on a binary distillation column. The model has 42
    states, 1083 algebraic variables and 2 control variables. The task is to
    get back to the desired steady-state after a short reflux breakdown.
    
    The example consists of the following steps:
    
    1.  Find the desired steady state by simulating ad infinitum with constant
        inputs.
    
    2.  Simulate the short reflux breakdown.

    3.  Simulate post-breakdown with constant inputs to generate an initial
        guess.

    4.  Solve the optimal control problem to get back to the desired steady
        state after the breakdown.
       
    5.  Verify the optimal trajectories by simulation.
    
    The model was developed in Moritz Diehl's PhD thesis:
    
    @PHDTHESIS{diehl2002phd,
      author = {Diehl, Moritz},
      title = {Real-Time Optimization for Large Scale Nonlinear Processes},
      school = {Heidelberg University},
      year = {2002},
      type = {Ph.{D}. thesis}
    }

    The Modelica implementation was based on the MATLAB implementation from
    John Hedengren's nonlinear model library available at:

    http://www.hedengren.net/research/models.htm

    This example needs one of the linear solvers MA27 or MA57 to work.
    The precense of MA27 or MA57 is not detected in the example, so if only 
    MA57 is present, then True must be passed in the use_ma57 argument.
    """
    ### 1. Find the desired steady state by simulating with constant inputs
    # Compile model
    file_name = (os.path.join(get_files_path(), "JMExamples.mo"),
                 os.path.join(get_files_path(), "JMExamples_opt.mop"))
    ss_fmu = compile_fmu("JMExamples.Distillation.Distillation4", file_name)
    ss_model = load_fmu(ss_fmu)

    # Set constant input and simulate
    [L_vol_ref] = ss_model.get('Vdot_L1_ref')
    [Q_ref] = ss_model.get('Q_elec_ref')
    ss_res = ss_model.simulate(final_time=500000.,
                               input=(['Q_elec', 'Vdot_L1'],
                                      lambda t: [Q_ref, L_vol_ref]))

    # Extract results
    ss_T_14 = ss_res['Temp[28]']
    T_14_ref = ss_T_14[-1]
    ss_T_28 = ss_res['Temp[14]']
    T_28_ref = ss_T_28[-1]
    ss_L_vol = ss_res['Vdot_L1']
    ss_Q = ss_res['Q_elec']
    ss_t = ss_res['time']
    abs_zero = ss_model.get('absolute_zero')
    L_fac = 1e3 * 3.6e3
    Q_fac = 1e-3

    print('T_14_ref: %.6f' % T_14_ref)
    print('T_28_ref: %.6f' % T_28_ref)

    # Plot simulation
    if with_plots:
        # Plotting options
        plt.rcParams.update({
            'font.serif': ['Times New Roman'],
            'text.usetex': latex_plots,
            'font.family': 'serif',
            'axes.labelsize': 20,
            'legend.fontsize': 16,
            'xtick.labelsize': 12,
            'font.size': 20,
            'ytick.labelsize': 14
        })
        pad = 2
        padplus = plt.rcParams['axes.labelsize'] / 2

        # Define function for custom axis scaling in plots
        def scale_axis(figure=plt, xfac=0.01, yfac=0.05):
            """
            Adjust the axis.

            The size of the axis is first changed to plt.axis('tight') and then
            scaled by (1 + xfac) horizontally and (1 + yfac) vertically.
            """
            (xmin, xmax, ymin, ymax) = figure.axis('tight')
            if figure == plt:
                figure.xlim(xmin - xfac * (xmax - xmin),
                            xmax + xfac * (xmax - xmin))
                figure.ylim(ymin - yfac * (ymax - ymin),
                            ymax + yfac * (ymax - ymin))
            else:
                figure.set_xlim(xmin - xfac * (xmax - xmin),
                                xmax + xfac * (xmax - xmin))
                figure.set_ylim(ymin - yfac * (ymax - ymin),
                                ymax + yfac * (ymax - ymin))

        # Define function for plotting the important quantities
        def plot_solution(t, T_28, T_14, Q, L_vol, fig_index, title):
            plt.close(fig_index)
            fig = plt.figure(fig_index)
            fig.subplots_adjust(wspace=0.35)

            ax = fig.add_subplot(2, 2, 1)
            bx = fig.add_subplot(2, 2, 2)
            cx = fig.add_subplot(2, 2, 3, sharex=ax)
            dx = fig.add_subplot(2, 2, 4, sharex=bx)
            width = 3

            ax.plot(t, T_28 + abs_zero, lw=width)
            ax.hold(True)
            ax.plot(t[[0, -1]], 2 * [T_28_ref + abs_zero], 'g--')
            ax.hold(False)
            ax.grid()
            if latex_plots:
                label = '$T_{28}$ [$^\circ$C]'
            else:
                label = 'T28'
            ax.set_ylabel(label, labelpad=pad)
            plt.setp(ax.get_xticklabels(), visible=False)
            scale_axis(ax)

            bx.plot(t, T_14 + abs_zero, lw=width)
            bx.hold(True)
            bx.plot(t[[0, -1]], 2 * [T_14_ref + abs_zero], 'g--')
            bx.hold(False)
            bx.grid()
            if latex_plots:
                label = '$T_{14}$ [$^\circ$C]'
            else:
                label = 'T14'
            ax.set_ylabel(label, labelpad=pad)
            plt.setp(bx.get_xticklabels(), visible=False)
            scale_axis(bx)

            cx.plot(t, Q * Q_fac, lw=width)
            cx.hold(True)
            cx.plot(t[[0, -1]], 2 * [Q_ref * Q_fac], 'g--')
            cx.hold(False)
            cx.grid()
            if latex_plots:
                ylabel = '$Q$ [kW]'
                xlabel = '$t$ [s]'
            else:
                ylabel = 'Q'
                xlabel = 't'
            cx.set_ylabel(ylabel, labelpad=pad)
            cx.set_xlabel(xlabel)
            scale_axis(cx)

            dx.plot(t, L_vol * L_fac, lw=width)
            dx.hold(True)
            dx.plot(t[[0, -1]], 2 * [L_vol_ref * L_fac], 'g--')
            dx.hold(False)
            dx.grid()
            if latex_plots:
                ylabel = '$L_{\Large \mbox{vol}}$ [l/h]'
                xlabel = '$t$ [s]'
            else:
                ylabel = 'L'
                xlabel = 't'
            dx.set_ylabel(ylabel, labelpad=pad)
            dx.set_xlabel(xlabel)
            scale_axis(dx)

            fig.suptitle(title)
            plt.show()

        # Call plot function
        plot_solution(ss_t, ss_T_28, ss_T_14, ss_Q, ss_L_vol, 1,
                      'Simulated trajectories to find steady state')

        # Plot steady state temperatures
        plt.close(2)
        plt.figure(2)
        plt.hold(True)
        for i in xrange(1, 43):
            temperature = (ss_res.final('Temp[' + ` i ` + ']') +
                           ss_res.initial('absolute_zero'))
            plt.plot(temperature, 43 - i, 'ko')
        plt.title('Steady state temperatures')
        if latex_plots:
            label = '$T$ [$^\circ$C]'
        else:
            label = 'T'
        plt.xlabel(label)
        plt.ylabel('Tray index [1]')

    ### 2. Simulate the short reflux breakdown
    # Compile model
    model_fmu = compile_fmu("JMExamples.Distillation.Distillation4", file_name)
    break_model = load_fmu(model_fmu)

    # Set initial values
    break_model.set('Q_elec_ref', Q_ref)
    break_model.set('Vdot_L1_ref', L_vol_ref)
    for i in xrange(1, 43):
        break_model.set('xA_init[%d]' % i, ss_res.final('xA[%d]' % i))

    # Define input function for broken reflux
    def input_function(time):
        if time < 700.:
            return [Q_ref, L_vol_ref]
        else:
            return [Q_ref, 0.5 / 1000. / 3600.]

    # Simulate and extract results
    break_res = break_model.simulate(final_time=1000.,
                                     input=(['Q_elec',
                                             'Vdot_L1'], input_function))
    break_T_14 = break_res['Temp[28]']
    break_T_28 = break_res['Temp[14]']
    break_L_vol = break_res['Vdot_L1']
    break_Q = break_res['Q_elec']
    break_t = break_res['time']

    # Plot simulation
    if with_plots:
        plot_solution(break_t, break_T_28, break_T_14, break_Q, break_L_vol, 3,
                      'Simulated short reflux breakdown')

    ### 3. Simulate post-breakdown with constant inputs to find initial guess
    # Compile the model
    ref_model = load_fmu(model_fmu)

    # Set initial conditions for post breakdown
    ref_model.set('Q_elec_ref', Q_ref)
    ref_model.set('Vdot_L1_ref', L_vol_ref)
    for i in xrange(1, 43):
        ref_model.set('xA_init[' + ` i ` + ']',
                      break_res.final('xA[' + ` i ` + ']'))

    # Simulate
    ref_res = ref_model.simulate(final_time=5000.,
                                 input=(['Q_elec', 'Vdot_L1'],
                                        lambda t: [Q_ref, L_vol_ref]))

    # Extract results
    ref_T_14 = ref_res['Temp[28]']
    ref_T_28 = ref_res['Temp[14]']
    ref_L_vol = ref_res['Vdot_L1']
    ref_Q = ref_res['Q_elec']
    ref_t = ref_res['time']

    # Plot initial guess
    if with_plots:
        plot_solution(ref_t, ref_T_28, ref_T_14, ref_Q, ref_L_vol, 4,
                      'Initial guess')

    ### 4. Solve optimal control problem
    # Compile optimization problem
    op = transfer_optimization_problem("JMExamples_opt.Distillation4_Opt",
                                       file_name)

    # Set initial conditions for post breakdown
    op.set('Q_elec_ref', Q_ref)
    op.set('Vdot_L1_ref', L_vol_ref)
    for i in xrange(1, 43):
        op.set('xA_init[' + ` i ` + ']', break_res.final('xA[' + ` i ` + ']'))

    # Set optimization options and solve
    opts = op.optimize_options()
    opts['init_traj'] = ref_res
    opts['nominal_traj'] = ref_res
    opts['n_e'] = 15
    opts['IPOPT_options']['linear_solver'] = "ma57" if use_ma57 else "ma27"
    opts['IPOPT_options']['mu_init'] = 1e-3
    opt_res = op.optimize(options=opts)

    # Extract results
    opt_T_14 = opt_res['Temp[28]']
    opt_T_28 = opt_res['Temp[14]']
    opt_L_vol = opt_res['Vdot_L1']
    opt_Q = opt_res['Q_elec']
    opt_t = opt_res['time']

    # Plot
    if with_plots:
        plot_solution(opt_t, opt_T_28, opt_T_14, opt_Q, opt_L_vol, 5,
                      'Optimal control')

    # Verify cost for testing purposes
    try:
        import casadi
    except:
        pass
    else:
        cost = float(opt_res.solver.solver_object.output(casadi.NLP_SOLVER_F))
        N.testing.assert_allclose(cost, 4.611038777467e-02, rtol=1e-2)

    ### 5. Verify optimization discretization by simulation
    verif_model = load_fmu(model_fmu)

    # Set initial conditions for post breakdown
    verif_model.set('Q_elec_ref', Q_ref)
    verif_model.set('Vdot_L1_ref', L_vol_ref)
    for i in xrange(1, 43):
        verif_model.set('xA_init[' + ` i ` + ']',
                        break_res.final('xA[' + ` i ` + ']'))

    # Simulate with optimal input
    verif_res = verif_model.simulate(final_time=5000.,
                                     input=opt_res.get_opt_input())

    # Extract results
    verif_T_14 = verif_res['Temp[28]']
    verif_T_28 = verif_res['Temp[14]']
    verif_L_vol = verif_res['Vdot_L1']
    verif_Q = verif_res['Q_elec']
    verif_t = verif_res['time']

    # Plot verifying simulation
    if with_plots:
        plot_solution(verif_t, verif_T_28, verif_T_14, verif_Q, verif_L_vol, 6,
                      'Simulation with optimal input')
# Using a list to exclude non-workdays for heatload data
non_workdays_file = r'L:\HVAC_ModelicaModel_Data\Commercial and Residential Hourly Load Profiles for all TMY3 Locations in the United States\SF_smalloffice_weekends+holidays.csv'
non_workdays = np.loadtxt(non_workdays_file)

hlparam_names = ['RoomLoadData', 'RoomLoadData2', 'RoomLoadData3']
n_rooms = len(hlparam_names)
hldays_set = []
for i in range(n_rooms):
    # hldays = days
    # hldays = check_workday(days,non_workdays,max_d=2)
    hldays = neighbor_days2(days, non_workdays, max_d=2, max_days=max_days)
    hldays_set.append(hldays)

for i, day in enumerate(days):
    model = load_fmu(
        fmu
    )  # if fmu already compiled, can use model = load_fmu(fileName+'.fmu')
    # model.set('_log_level', 6)
    LoadWeatherData(model, weather_file, day=day)  # set weather data
    # LoadHeatLoadData(model,load_file,day = hldays[i]) # set room heat load data
    multi_hldays = [hldays_set[j][i] for j in range(n_rooms)
                    ]  # set multiple room heat load data
    LoadMultiHeatLoadData(model,
                          load_files,
                          days=multi_hldays,
                          param_names=hlparam_names,
                          scale_factor=0.7)
    opts = model.simulate_options()
    opts['ncp'] = data_points  # Changing the number of communication points
    res = model.simulate(start_time=start_time,
                         final_time=final_time,
Exemple #39
0
def simulate_cymdist_griddyn14bus_fmus():
    """Simulate coupled GridDyn and CYMDIST FMUs.
        
    """  
    # Simulation parameters
    start_time = 0.0
    stop_time  = 300
    step_size  = 300
    
    # Path to the CYMDIST configuration file
    path_config=os.path.abspath("config.json")
    # Conversion to byte for PyFMI
    cymdist_con_val_str = bytes(path_config, 'utf-8')
    
    griddyn_input_valref=[]
    griddyn_output_valref=[] 
    griddyn_output_values=[]
    
    cymdist_input_valref=[] 
    cymdist_output_valref=[]
    cymdist_output_values=[]  
    
    cymdist = load_fmu("../fmus/CYMDIST/CYMDIST.fmu", log_level=7)
    griddyn=load_fmu("../fmus/griddyn/griddyn14bus.fmu", log_level=7)

    cymdist.setup_experiment(start_time=start_time, stop_time=stop_time)
    griddyn.setup_experiment(start_time=start_time, stop_time=stop_time)
    
    # Define the inputs
    cymdist_input_names = ['VMAG_A', 'VMAG_B', 'VMAG_C', 'VANG_A', 'VANG_B', 'VANG_C']
    cymdist_output_names = ['IA', 'IB', 'IC', 'IAngleA', 'IAngleB', 'IAngleC']
    
    griddyn_input_names = ['Bus11_IA', 'Bus11_IB', 'Bus11_IC', 
                       'Bus11_IAngleA', 'Bus11_IAngleB', 'Bus11_IAngleC']
    griddyn_output_names = ['Bus11_VA', 'Bus11_VB', 'Bus11_VC', 
                'Bus11_VAngleA', 'Bus11_VAngleB', 'Bus11_VAngleC']
    
    # Get the value references of griddyn inputs
    for elem in griddyn_input_names:
        griddyn_input_valref.append(griddyn.get_variable_valueref(elem))
    
    # Get the value references of griddyn outputs
    for elem in griddyn_output_names:
        griddyn_output_valref.append(griddyn.get_variable_valueref(elem))
    
    # Get the value references of cymdist inputs
    for elem in cymdist_input_names:
        cymdist_input_valref.append(cymdist.get_variable_valueref(elem))   
        
    # Get the value references of cymdist outputs 
    for elem in cymdist_output_names:
        cymdist_output_valref.append(cymdist.get_variable_valueref(elem))  
    
    # Set the flag to save the results
    cymdist.set("_saveToFile", 0)
    # Get the initial outputs from griddyn
    # Get value reference of the configuration file 
    cymdist_con_val_ref = cymdist.get_variable_valueref("_configurationFileName")
    
    # Set the configuration file
    cymdist.set_string([cymdist_con_val_ref], [cymdist_con_val_str])
    
    # Set the value of the multiplier
    griddyn.set('multiplier', 3.0)

    # Initialize the FMUs
    cymdist.initialize()
    griddyn.initialize()
    
    # Call event update prior to entering continuous mode.
    cymdist.event_update()
    cymdist.enter_continuous_time_mode()
    
    # Co-simulation loop
    for tim in np.arange(start_time, stop_time, step_size):
        cnt+=1
        # Get the outputs from griddyn
        griddyn_output_values = (griddyn.get_real(griddyn_output_valref))
        # set the time in cymdist
        cymdist.time = tim
        # Set the inputs of cymdist
        cymdist.set_real(cymdist_input_valref, griddyn_output_values)
        # Get the outputs of cymdist
        cymdist_output_values = (cymdist.get_real(cymdist_output_valref))
    # Terminate FMUs
    cymdist.terminate()
    griddyn.terminate()
Exemple #40
0
def simulateFMU(inputFileName, outputFileName):
    '''
	Read an input file of a specific format, update setting values, simulate the FMU, and output results.

	*Note* - Current flexibility, i.e., for time depedent inputs is not handled but could be by modifying/expanding
	this file or perhaps creating a RAVEN interface specifically for pyfmi or, preferably, the FMI standard.

	inputFileName = 'referenceInput.txt' (default)
	outputFileName = 'results.csv' (default)

	Format of inputFileName:
	Requires -
	1) the location and name of the FMU 	<--- Only one, must be the first line
	2) variables to be set by RAVEN 		<--- May include any number
	3) and variables to be output to RAVEN 	<--- May include any number

	Example:
	fmuName = 'PATHTOFMU/myFMU.fmu' <--- Must be the first line!!!
	sigma = $RAVEN-sigma$
	rho = $RAVEN-rho$
	lorenzSystem.x
	lorenzSystem.y
	'''

    # Read the input file
    with open(inputFileName, 'r') as f:
        lines = f.readlines()

    # Extract file name of FMU
    if "fmuName" in lines[0]:
        fmuName = ''.join(re.findall("'([^']*')", lines[0])).replace("'", "")
    else:
        raise ValueError(
            'fmuName must be specified in first line of input file. Found instead:\n',
            lines[0])

    # Load the FMU
    model = load_fmu(str(fmuName))

    # Initialize dictionaries
    results = {}
    for i, line in enumerate(lines):
        if i == 0:
            # Skip first line which contains fmuName
            pass
        elif '=' in line:
            # Set the new model parameters
            key, value = line.replace(' ', '').strip().split('=')
            model.set(key, value)
            #results[key] = None <-- gives warnings when run with raven. Can't add variables not specified in raven .xml file?
        else:
            # Generate key for variable to be saved
            key = line.replace(' ', '').strip()
            results[key] = None

    # Simulate
    res = model.simulate()

    # Write results to dictionary
    for key in results.keys():
        results[key] = res[key]

    # Save results to csv (column - variable, row - values)
    pd.DataFrame(results).to_csv(outputFileName, index=False)
Exemple #41
0
 def test_load_fmu(self):
     """Load an fmu."""
     model = pyfmi.load_fmu(self.path_fmu)
Exemple #42
0
def run_demo(with_plots=True):
    """
    Demonstrates how to use an JMODELICA generated FMU for sensitivity
    calculations and compares against finite differences. 
    
    Model and original code by Niklas Andersson
    """
    curr_dir = os.path.dirname(os.path.abspath(__file__));

    #Compile the model
    fmu_name = compile_fmu("SEIRSmodel", curr_dir+"/files/SEIRSmodel.mo")
    
    #Sensitivity parameters
    senspars = [5,6,7,8]
    parnames = ['p%d'%sp for sp in senspars]
    
    #Simulation interval
    t0 = 2002.
    tf = 2007.

    fmodel = load_fmu(fmu_name,enable_logging=False)

    # Get and set the options
    fopts = fmodel.simulate_options()
    fopts['CVode_options']['atol'] = 1.0e-6
    fopts['CVode_options']['rtol'] = 1.0e-6
    fopts['sensitivities'] = parnames
    fopts['ncp'] = 500

    #Simulate
    fres = fmodel.simulate(t0,tf, options=fopts)
    
    #Get the result
    dEdpt_fmu = N.array([fres['dE/dp%d' % (i)] for i in senspars]).T
            
    #Calculate Finite Differences
    theta0 = N.array([fmodel.get(name) for name in parnames])
    fopts['sensitivities'] = []
    fopts['ncp'] = 0
    dEdpt_findiff_fmu = sensfunc(objectfun_fmu,theta0,fmu_name,parnames,t0,tf,fopts,N.linspace(t0,tf,501.))
    
    #Maximum relative errors
    for ii,sp in enumerate(senspars):
        err = N.max(N.abs(dEdpt_fmu[:,ii]-dEdpt_findiff_fmu[:,ii])/N.max(dEdpt_fmu[:,ii]))
        assert err < 1.0, str(err) + " not less than " + str(1.0)
        
    #Plotting
    if with_plots:
        for ii,sp in enumerate(senspars):
            plt.figure(1)
            plt.subplot(len(senspars),1,ii)
            plt.hold(True)
            plt.plot(fres['time'],dEdpt_fmu[:,ii],'x-')
            plt.plot(fres['time'],dEdpt_findiff_fmu[:,ii],'o-')
            plt.legend(['fmu-sens','fmu-findiff'])
            plt.figure(2)
            plt.hold(True)
            plt.semilogy(fres['time'],N.abs(dEdpt_fmu[:,ii]-dEdpt_findiff_fmu[:,ii])/N.max(dEdpt_fmu[:,ii]),label=parnames[ii])
            plt.legend()
            plt.grid(True)
            plt.xlabel("Time [s]")
            plt.title("Comparison of sensitivities calculated by CVodes and by Finite differences")
        plt.show()
    def __init__(
        self,
        max_power: float,
        design_altitude: float,
        design_speed: float,
        fuel_type: float,
        strokes_nb: float,
        prop_layout: float,
    ):
        """
        Parametric Internal Combustion engine.

        It computes engine characteristics using fuel type, motor architecture
        and constant propeller efficiency using analytical model from following sources:

        :param max_power: maximum delivered mechanical power of engine (units=W)
        :param design_altitude: design altitude for cruise (units=m)
        :param design_speed: design altitude for cruise (units=m/s)
        :param fuel_type: 1.0 for gasoline and 2.0 for diesel engine and 3.0 for Jet Fuel
        :param strokes_nb: can be either 2-strockes (=2.0) or 4-strockes (=4.0)
        :param prop_layout: propulsion position in nose (=3.0) or wing (=1.0)
        """
        if fuel_type == 1.0:
            self.ref = {
                "max_power": 132480,
                "length": 0.83,
                "height": 0.57,
                "width": 0.85,
                "mass": 136,
            }  # Lycoming IO-360-B1A
        else:
            self.ref = {
                "max_power": 160000,
                "length": 0.859,
                "height": 0.659,
                "width": 0.650,
                "mass": 205,
            }  # TDA CR 1.9 16V
        self.prop_layout = prop_layout
        self.max_power = max_power
        self.design_altitude = design_altitude
        self.design_speed = design_speed
        self.fuel_type = fuel_type
        self.strokes_nb = strokes_nb
        self.idle_thrust_rate = 0.01

        # Declare sub-components attribute
        self.engine = Engine(power_SL=max_power)
        self.nacelle = None
        self.propeller = None

        # This dictionary is expected to have a Mixture coefficient for all EngineSetting values
        self.mixture_values = {
            EngineSetting.TAKEOFF: 1.5,
            EngineSetting.CLIMB: 1.5,
            EngineSetting.CRUISE: 1.0,
            EngineSetting.IDLE: 1.0,
        }

        # ... so check that all EngineSetting values are in dict
        unknown_keys = [
            key for key in EngineSetting
            if key not in self.mixture_values.keys()
        ]
        if unknown_keys:
            raise FastUnknownEngineSettingError("Unknown flight phases: %s",
                                                unknown_keys)

        # Define the FMU model used
        # noinspection PyProtectedMember
        self.model = load_fmu(
            pth.join(resources.__path__._path[0], PROPULSION_FMU))
Exemple #44
0
# Create an optimizer object based on the template and a model
optimizer_1 = template_optimizer.optimizer(model_1)
# Create an observer object based on the template and a model
observer_1 = template_observer.observer(model_1)
# Create a simulator object based on the template and a model
simulator_1 = template_simulator.simulator(model_1)
# Create a configuration
configuration_1 = core_do_mpc.configuration(model_1, optimizer_1, observer_1,
                                            simulator_1)

# Set up the solvers
configuration_1.setup_solver()

# Load FMU created from compile_fmu() or EnergyPlusToFMU
modelName = 'RKF'
model_fmu = load_fmu(modelName + '.fmu')

# Load options
opts = model_fmu.simulate_options()
# Set number of timesteps
opts['ncp'] = numSteps
# Manually initialize
opts['initialize'] = False
model_fmu.initialize(configuration_1.simulator.t0_sim * 60,
                     configuration_1.optimizer.t_end * 60)
"""
----------------------------
do-mpc: MPC loop
----------------------------
"""
start_time = time.time()
# Setup of Modelica etc
import numpy as np
import matplotlib.pyplot as plt
from pymodelica import compile_fmu
from pyfmi import load_fmu

# Define model file name and class name
model_name = 'BIOPROCESS.BatchWithNoise'
model_file = 'br13.mo'

# Compile model
fmu_model = compile_fmu(model_name, model_file)

# Load model
model = load_fmu(fmu_model)

# Simulation time
simulationTime = 7.0

# Specification of acceptable batch
t_final_max = 6.0  # h
X_final_min = 5.0  # g/L

# Initial values - changes from the model default values
model.set('bioreactor.V_0', 1.0)
model.set('bioreactor.VX_0', 2.0)
model.set('bioreactor.VS_0', 10.0)
model.set('bioreactor.VP_0', 0.0)

# Parameters
def run_demo(with_plots=True):
    """
    This example demonstrates how to solve parameter estimation problmes.

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

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

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

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

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

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

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

    # Load simulation result
    x1_sim = res['qt.x1']
    x2_sim = res['qt.x2']
    x3_sim = res['qt.x3']
    x4_sim = res['qt.x4']
    t_sim  = res['time']
    
    u1_sim = res['u1']
    u2_sim = res['u2']
    
    assert N.abs(res.final('qt.x1') - 0.05642485) < 1e-3
    assert N.abs(res.final('qt.x2') - 0.05510478) < 1e-3
    assert N.abs(res.final('qt.x3') - 0.02736532) < 1e-3
    assert N.abs(res.final('qt.x4') - 0.02789808) < 1e-3
    assert N.abs(res.final('u1') - 6.0)           < 1e-3
    assert N.abs(res.final('u2') - 5.0)           < 1e-3

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

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

    # Compile the Optimica model to an XML file
    model_name = compile_fmux("QuadTankPack.QuadTank_ParEstCasADi",
        curr_dir+"/files/QuadTankPack.mop")
    
    # Load the model
    model_casadi=CasadiModel(model_name)

    """
    The collocation algorithm minimizes, if the parameter_estimation_data
    option is set, a quadrature approximation of the integral

    \int_{t_0}^{t_f} (y(t)-y^{meas}(t))^T Q (y(t)-y^{meas}(t)) dt

    The measurement data is given as a matrix where the first
    column is time and the following column contains data corresponding
    to the variable names given in the measured_variables list.

    Notice that input trajectories used in identification experiments
    are handled using the errors in variables method, i.e., deviations
    from the measured inputs are penalized in the cost function, rather
    than forcing the inputs to follow the measurement profile exactly.
    The weighting matrix Q may be used to express that inputs are typically
    more reliable than than measured outputs.
    """
    
    # Create measurement data
    Q = N.diag([1., 1., 10., 10.])
    data_x1 = N.vstack([t_meas, y1_meas])
    data_x2 = N.vstack([t_meas, y2_meas])
    data_u1 = N.vstack([t_meas, u1])
    data_u2 = N.vstack([t_meas, u2])
    unconstrained = OrderedDict()
    unconstrained['qt.x1'] = data_x1
    unconstrained['qt.x2'] = data_x2
    unconstrained['u1'] = data_u1
    unconstrained['u2'] = data_u2
    measurement_data = MeasurementData(Q=Q, unconstrained=unconstrained)
    
    opts = model_casadi.optimize_options()
    
    opts['n_e'] = 60
    
    opts['measurement_data'] = measurement_data
    
    res = model_casadi.optimize(options=opts)
    
    # Load state profiles
    x1_opt = res["qt.x1"]
    x2_opt = res["qt.x2"]
    x3_opt = res["qt.x3"]
    x4_opt = res["qt.x4"]
    u1_opt = res["qt.u1"]
    u2_opt = res["qt.u2"]
    t_opt  = res["time"]

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

    # Print and assert optimal parameter values
    print('a1: ' + str(a1_opt*1e4) + 'cm^2')
    print('a2: ' + str(a2_opt*1e4) + 'cm^2')
    a_ref = [0.02656702, 0.02713898]
    N.testing.assert_allclose(1e4 * N.array([a1_opt, a2_opt]),
                              [0.02656702, 0.02713898], rtol=1e-4)
    
    # Plot
    if with_plots:
        plt.figure(1)
        plt.subplot(2,2,1)
        plt.plot(t_opt,x3_opt,'k')
        plt.subplot(2,2,2)
        plt.plot(t_opt,x4_opt,'k')
        plt.subplot(2,2,3)
        plt.plot(t_opt,x1_opt,'k')
        plt.subplot(2,2,4)
        plt.plot(t_opt,x2_opt,'k')

        plt.figure(2)
        plt.subplot(2,1,1)
        plt.plot(t_opt,u1_opt,'k')
        plt.subplot(2,1,2)
        plt.plot(t_opt,u2_opt,'k')
        plt.show()
Exemple #47
0
 def load(cls, path):
     model_name = basename(path)
     logger.debug('Loading model "%s"', model_name)
     model = cls(load_fmu(path, log_file_name=datetime.now().strftime(f'%Y-%m-%d_{model_name}.txt')))
     logger.debug('Successfully loaded model "%s"', model_name)
     return model
    def run_simulator (self, tool):
        
        '''
        Function for running FMUs exported from Dymola, JModelica, and OpenModelica with PyFMI.

        '''
        
        try:
            from pyfmi import load_fmu
        except BaseException:
            print ('PyFMI not installed. Test will not be be run.')
            return
        if (tool=='openmodelica' and platform.system().lower() == 'linux'):
                print ('tool={!s} is not supported on Linux'.format(tool))
                return
            
        else:
        # Export FMUs which are needed to run the cases.
            if tool == 'openmodelica':
                modPat = 'OPENMODELICALIBRARY'
                mosT = MOS_TEMPLATE_PATH_OPENMODELICA
            elif tool == 'dymola':
                modPat = 'MODELICAPATH'
                mosT = MOS_TEMPLATE_PATH_DYMOLA
            elif tool == 'jmodelica':
                # Unset environment variable
                if (os.environ.get('MODELICAPATH') is not None):
                    del os.environ['MODELICAPATH']
                modPat = None
                mosT = MOS_TEMPLATE_PATH_JMODELICA
            for version in ['2']:
                if (tool == 'openmodelica' or tool == 'jmodelica'):
                    version = str(float(version))
                for api in ['me']:
                    if (tool == 'openmodelica' and version == '1.0' and api == 'cs'):
                        print (
                            'tool={!s} with FMI version={!s} and FMI API={!s} is not supported.'.format(
                                tool, version, api))
                        continue
                    for cs_xml in ['true']:
                        if (version == '1'):
                            continue
                        Simulator_Test = simulator.SimulatorToFMU(
                            '',
                            XML_INPUT_FILE,
                            SimulatorToFMU_LIB_PATH,
                            MO_TEMPLATE_PATH,
                            mosT,
                            XSD_FILE_PATH,
                            '27',
                            python_scripts_path,
                            version,
                            api,
                            tool,
                            None,
                            modPat,
                            cs_xml,
                            'true',
                            None)

                        print (
                            'Export the simulator with tool={!s}, FMI version={!s}, FMI API={!s}'.format(
                                tool, version, api))
                        start = datetime.now()
                        Simulator_Test.print_mo()
                        Simulator_Test.generate_fmu()
                        Simulator_Test.clean_temporary()
                        Simulator_Test.rewrite_fmu()
                        end = datetime.now()
                        print(
                            'Export the simulator as an FMU in {!s} seconds.'.format(
                                (end - start).total_seconds()))
                        
                        fmu_path = os.path.join(
                        script_path, '..', 'fmus', tool, platform.system().lower())
                        print(
                            'Copy simulator.fmu to {!s}.'.format(fmu_path))
                        shutil.copy2('simulator.fmu', fmu_path)
    
        fmu_path = os.path.join(
                script_path, '..', 'fmus', tool, platform.system().lower(), 'simulator.fmu')
        # Parameters which will be arguments of the function
        start_time = 0.0
        stop_time = 5.0

        print ('Starting the simulation with {!s}'.format(tool))
        start = datetime.now()

        simulator_input_valref = []
        simulator_output_valref = []

        sim_mod = load_fmu(fmu_path, log_level=7)
        sim_mod.setup_experiment(
            start_time=start_time, stop_time=stop_time)

        # Define the inputs
        simulator_input_names = ['v']
        simulator_input_values = [220.0]
        simulator_output_names = ['i']

        # Get the value references of simulator inputs
        for elem in simulator_input_names:
            simulator_input_valref.append(
                sim_mod.get_variable_valueref(elem))

        # Get the value references of simulator outputs
        for elem in simulator_output_names:
            simulator_output_valref.append(
                sim_mod.get_variable_valueref(elem))

        # Set the flag to save the results
        sim_mod.set('_saveToFile', 'false')

        # Initialize the FMUs
        sim_mod.initialize()

        # Call event update prior to entering continuous mode.
        sim_mod.event_update()

        # Enter continuous time mode
        sim_mod.enter_continuous_time_mode()

        sim_mod.set_real(simulator_input_valref, simulator_input_values)
        
        end = datetime.now()

        print(
            'Ran a single Simulator simulation with {!s} FMU={!s} in {!s} seconds.'.format(
                tool, fmu_path, (end - start).total_seconds()))
        if not (tool=='openmodelica'):
            # PyFMI fails to get the output of an OpenModelica FMU 
            self.assertEqual(
                sim_mod.get_real(
                    sim_mod.get_variable_valueref('i')),
                1.0,
                'Values are not matching.')
            
        # Terminate FMUs
        sim_mod.terminate()
pymodelica.environ['JVM_ARGS'] = '-Xmx4096m'


sys.stdout.flush()

######################################################################
# Compile fmu
fmu_name = compile_fmu(model,
                       version="2.0",
                       compiler_log_level='warning',
                       compiler_options = {"generate_html_diagnostics" : False,
                                           "nle_solver_tol_factor": 1e-2})

######################################################################
# Load model
mod = load_fmu(fmu_name, log_level=3)

######################################################################
# Retrieve and set solver options
x_nominal = mod.nominal_continuous_states
opts = mod.simulate_options() #Retrieve the default options

opts['solver'] = 'CVode'
opts['ncp'] = 5000

if opts['solver'].lower() == 'cvode':
  # Set user-specified tolerance if it is smaller than the tolerance in the .mo file
  rtol = 1.0e-6
  x_nominal = mod.nominal_continuous_states

  if len(x_nominal) > 0:
Exemple #50
0
from pymodelica import compile_fmu
from pyfmi import load_fmu

libPath = r'C:\Users\vmg\Documents\Modelica\TRANSFORM-Library/TRANSFORM'
modelName = 'TRANSFORM.Math.Examples.ComplexMath.check_csqrt'

fmu = compile_fmu(modelName, libPath, target='cs')
model = load_fmu(fmu)

opts = model.simulate_options()
opts['time_limit'] = 60

results = model.simulate(options=opts)
#~ caus_opts['inline'] = False
#~ caus_opts['closed_form'] = True
caus_opts['dense_tol'] = 1e10
caus_opts['inline_solved'] = True

sim_res = ResultDymolaTextual(
    os.path.join(get_files_path(), "vehicle_turn_dymola.txt"))
#~ sim_res = ResultDymolaTextual("opt_asphalt.txt")
start_time = 0.
final_time = sim_res.get_variable_data('time').t[-1]
ncp = 100
class_name = "Car"
file_paths = os.path.join(get_files_path(), "vehicle_turn.mop")
opts = {'generate_html_diagnostics': True, 'state_initial_equations': True}
model = transfer_model(class_name, file_paths, compiler_options=opts)
init_fmu = load_fmu(compile_fmu(class_name, file_paths, compiler_options=opts))

# Create input data
# This would have worked if one input was not constant...
#~ columns = [0]
#~ columns += [sim_res.get_column(input_var.getName()) for input_var in model.getVariables(model.REAL_INPUT)]
#~ input = sim_res.get_data_matrix()[:, columns]

input_matrix = sim_res.get_variable_data("time").x.reshape([-1, 1])
for input_var in model.getVariables(model.REAL_INPUT):
    input_data = sim_res.get_variable_data(input_var.getName()).x.reshape(
        [-1, 1])
    if len(input_data) <= 2:
        input_data = np.array(input_matrix.shape[0] *
                              [input_data[-1]]).reshape([-1, 1])
    input_matrix = np.hstack([input_matrix, input_data])
]

print(sys.version)
print(
    all(os.path.isfile(os.path.join(moLib, "package.mo")) for moLib in moLibs))
print(os.getcwd())

# <codecell> compile model to fmu
from pymodelica import compile_fmu
model_name = 'BuildingSystems.Applications.ClimateAnalyses.FreeFloatingTemperature'
my_fmu = compile_fmu(model_name, moLibs)

# <codecell> simulate the fmu and store results
from pyfmi import load_fmu

myModel = load_fmu(my_fmu)

opts = myModel.simulate_options()
opts['solver'] = "CVode"
opts['ncp'] = 8760
opts['result_handling'] = "file"
opts["CVode_options"]['discr'] = 'BDF'
opts['CVode_options']['iter'] = 'Newton'
opts['CVode_options']['maxord'] = 5
opts['CVode_options']['atol'] = 1e-5
opts['CVode_options']['rtol'] = 1e-5

res = myModel.simulate(start_time=0.0, final_time=31530000.0, options=opts)
#res = myModel.simulate(start_time=0.0, final_time=31536000.0, options=opts)

# <codecell> plotting of the results
Exemple #53
0
from pymodelica import compile_fmu
from pyfmi import load_fmu
import matplotlib.pyplot as plt
from pyjmi.common.plotting import plot_gui  # or pyfmi.common.plotting import plot_gui

model_name = 'TestSys.HVACv6a_3room'
mo_file1 = 'C:\Users\James\OneDrive\Documents\Berkeley\HVAC\Modelica\Test\TestSys\TestSys'
mo_file2 = 'C:\Users\James\Desktop\Buildings 4.0.0'
mo_files = mo_file1 + ',' + mo_file2

# Compile fmu
fmu = compile_fmu(model_name, mo_files)

# Load fmu
model = load_fmu(fmu)
# if already compiled fmu, can use fmu from file and save time from recompiling
model = load_fmu(model_name.replace('.', '_') + '.fmu')
# model = load_fmu('TestSys_HVACv3a_weather_load.fmu') # make sure working directory is correct

# model parameters setting
model.set(param, param_val)

# res = model.simulate(final_time = 3600.)
# res = model.simulate(start_time = 0., final_time = 3600.)
opts = model.simulate_options()
# opts['solver'] = 'RodasODE'#'RungeKutta34'#'Radau5ODE'#'CVode'
opts['ncp'] = 1440  # Changing the number of communication points
res = model.simulate(options=opts, start_time=0., final_time=86400.)

plot_gui.startGUI()
Exemple #54
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)
    init_res = sim_model.simulate(start_time=0., final_time=150)

    ### 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(x_k.keys(), x_k.values())
        sim_res = sim_model.simulate(start_time=k * sample_period,
                                     final_time=(k + 1) * sample_period,
                                     input=u_k)

        # 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()
Exemple #55
0
 def test_simulate(self):
     """Simulate an fmu."""
     model = pyfmi.load_fmu(self.path_fmu)
     model.simulate(options={'silent_mode': True})
                         index=True)

#=====================================================================
# Generate variables from model
#=====================================================================
# Initialize data frame
df = gen.create_df()
file_name = os.path.join(os.path.dirname(os.path.abspath(__file__)),
                         'BESTESTHydronic')
class_name = 'BESTESTHydronic.TestCase'

# Compile the model to generate the data
fmu_path = compile_fmu(file_name=file_name, class_name=class_name)

# Load FMU
model = load_fmu(fmu_path)

# Set number of communication points
options = model.simulate_options()
options['ncp'] = len(gen.time) - 1

# Simulate
res = model.simulate(start_time=gen.time[0],
                     final_time=gen.time[-1],
                     options=options)

keysMap = {}

# Occupancy schedules
keysMap['Occupancy[1]'] = 'yOcc.y'
Exemple #57
0
 def test_reset(self):
     """Reset an fmu."""
     model = pyfmi.load_fmu(self.path_fmu)
     model.simulate(options={'silent_mode': True})
     model.reset()
     model.simulate(options={'silent_mode': True})

import os
from collections import OrderedDict
from scipy.io.matlab.mio import loadmat
import numpy as N
from pymodelica import compile_fmu
from pyfmi import load_fmu
from pyjmi import transfer_optimization_problem
from pyjmi.optimization.casadi_collocation import ExternalData
from sklearn.metrics import r2_score
import json
import scipy.interpolate as interpolate

# Compile and load FMU, which is used for simulation
model = load_fmu(compile_fmu('OrderReduction.RCOrderReduction', "OrderReduction.mop"))
# Transfer problem to CasADi Interface, which is used for estimation
op = transfer_optimization_problem("OrderReduction.reduceOrder",
 "OrderReduction.mop")
# get the model order
n = int(model.get('n'))
print(n)
#model.set_integer('n', n)


## experiment time
startTime = 0
finalTime = 172800

## Load measurement data from file
meas = pd.read_csv('LTM_2days.csv', index_col=[0])
Exemple #59
0
    sys.exit(1)

# Find the model variable output list file if present
if args.var is not None:  # Use specified variable output list file
    model_var = os.path.abspath(args.var)
    if not os.path.isfile(model_var):
        print('Error: Specified variable output list file not found:',
              model_var)
        sys.exit(1)
else:  # Look for default variable output list file
    model_var = os.path.join(model_dir, model + '.var')
    if os.path.isfile(model_var): args.var = model_var

# Load the FMU
try:
    fmu = load_fmu(model_fmu, log_level=args.log)
except Exception as err:
    if err: print('Error: ' + str(err))
    print('FMU file: ' + model_fmu)
    sys.exit(1)
fmu.set_max_log_size(2073741824)  # = 2*1024^3 (about 2GB)

# Set simulation options
opt = fmu.simulate_options()
opt['solver'] = args.solver
if args.res == 'memory':  # In-memory results: Signal files generated after simulation
    opt['result_handling'] = 'memory'
elif args.res == 'binary':  # Binary .mat results file
    opt['result_handling'] = 'binary'
    opt['result_file_name'] = model + '.mat'
elif args.res == 'csv':  # CSV results file
Exemple #60
0
    def __init__(self,
                 time_step: float = 1e-4,
                 time_start: float = 0,
                 reward_fun: Callable[[List[str], np.ndarray],
                                      float] = lambda cols, obs: 1,
                 log_level: int = logging.WARNING,
                 solver_method: str = 'LSODA',
                 max_episode_steps: Optional[int] = 200,
                 model_params: Optional[Dict[str, Union[Callable[[float],
                                                                 float],
                                                        float]]] = None,
                 model_input: Optional[Sequence[str]] = None,
                 model_output: Optional[Union[dict, Sequence[str]]] = None,
                 model_path: str = '../fmu/grid.network.fmu',
                 viz_mode: Optional[str] = 'episode',
                 viz_cols: Optional[Union[str, List[Union[str,
                                                          PlotTmpl]]]] = None,
                 history: EmptyHistory = FullHistory()):
        """
        Initialize the Environment.
        The environment can only be used after reset() is called.

        :param time_step: step size of the simulation in seconds
        :param time_start: offset of the time in seconds

        :param reward_fun:
            The function receives as a list of variable names and a np.ndarray of the values of the current observation.
            The separation is mainly for performance reasons, such that the resolution of data indices can be cached.
            It must return the reward of this timestep as float.
            It should return np.nan or -np.inf or None in case of a failiure.
            It should have no side-effects
        :param log_level: logging granularity. see logging in stdlib
        :param solver_method: solver of the scipy.integrate.solve_ivp function
        :param max_episode_steps: maximum number of episode steps.
            The end time of the episode is calculated by the time resolution and the number of steps.

            If set to None, the environment will never finish because of step sizes, but it might still stop because of
            system failiure (-inf reward)

        :param model_params: parameters of the FMU.

            dictionary of variable names and scalars or callables.
            If a callable is provided it is called every time step with the current time.
            This callable must return a float that is passed to the fmu.
        :param model_input: list of strings. Each string representing a FMU input variable.
        :param model_output: nested dictionaries containing nested lists of strings.
         The keys of the nested dictionaries will be flattened down and appended to their children and finally prepended
         to the strings in the nested lists. The strings final strings represent variables from the FMU and the nesting
         of the lists conveys structure used in the visualisation

         >>> {'inverter': {'condensator': ['i', 'v']}}

         results in

         >>> ['inverter.condensator.i', 'inverter.condensator.v']
        :param model_path: Path to the FMU
        :param viz_mode: specifies how and if to render

            - 'episode': render after the episode is finished
            - 'step': render after each time step
            - None: disable visualization
        :param viz_cols: enables specific columns while plotting
             - None: all columns will be used for vizualization (default)
             - string: will be interpret as regex. all fully matched columns names will be enabled
             - list of strings: Each string might be a unix-shell style wildcard like "*.i"
                                to match all data series ending with ".i".
             - list of PlotTmpl: Each template will result in a plot
        :param history: history to store observations and measurement (from the agent) after each step
        """
        if model_input is None:
            raise ValueError(
                'Please specify model_input variables from your OM FMU.')
        if model_output is None:
            raise ValueError(
                'Please specify model_output variables from your OM FMU.')
        if viz_mode not in self.viz_modes:
            raise ValueError(
                f'Please select one of the following viz_modes: {self.viz_modes}'
            )

        self.viz_mode = viz_mode
        logger.setLevel(log_level)
        self.solver_method = solver_method

        # load model from fmu
        model_name = basename(model_path)
        logger.debug("Loading model {}".format(model_name))
        self.model: FMUModelME2 = load_fmu(
            model_path,
            log_file_name=datetime.now().strftime(
                f'%Y-%m-%d_{model_name}.txt'))
        logger.debug("Successfully loaded model {}".format(model_name))

        # if you reward policy is different from just reward/penalty - implement custom step method
        self.reward = reward_fun
        self._failed = False

        # Parameters required by this implementation
        self.max_episode_steps = max_episode_steps
        self.time_start = time_start
        self.time_step_size = time_step
        self.time_end = np.inf if max_episode_steps is None \
            else self.time_start + max_episode_steps * self.time_step_size

        # if there are parameters, we will convert all scalars to constant functions.
        model_params = model_params or dict()
        # the "partial" is needed because of some absurd python behaviour https://stackoverflow.com/a/34021333/13310191
        self.model_parameters = {
            var:
            (val if callable(val) else partial(lambda t, val_: val_, val_=val))
            for var, val in model_params.items()
        }

        self.sim_time_interval = None
        self._state = []
        self.measurement = []
        self.record_states = viz_mode == 'episode'
        self.history = history
        self.history.cols = model_output
        self.model_input_names = model_input
        # variable names are flattened to a list if they have specified in the nested dict manner)
        self.model_output_names = self.history.cols

        self.viz_col_tmpls = []
        if viz_cols is None:
            logger.info(
                'Provide the option "viz_cols" if you wish to select only specific plots. '
                'The default behaviour is to plot all data series')
            self.viz_col_regex = '.*'
        elif isinstance(viz_cols, list):
            # strings are glob patterns that can be used in the regex
            patterns, tmpls = [], []
            for elem in viz_cols:
                if isinstance(elem, str):
                    patterns.append(translate(elem))
                elif isinstance(elem, PlotTmpl):
                    tmpls.append(elem)
                else:
                    raise ValueError(
                        '"viz_cols" list must contain only strings or PlotTmpl objects not'
                        f' {type(viz_cols)}')

            self.viz_col_regex = '|'.join(patterns)
            self.viz_col_tmpls = tmpls
        elif isinstance(viz_cols, str):
            # is directly interpret as regex
            self.viz_col_regex = viz_cols
        else:
            raise ValueError(
                '"viz_cols" must be one type Optional[Union[str, List[Union[str, PlotTmpl]]]]'
                f'and not {type(viz_cols)}')

        # OpenAI Gym requirements
        d_i, d_o = len(self.model_input_names), len(self.model_output_names)
        self.action_space = gym.spaces.Box(low=np.full(d_i, -np.inf),
                                           high=np.full(d_i, np.inf))
        self.observation_space = gym.spaces.Box(low=np.full(d_o, -np.inf),
                                                high=np.full(d_o, np.inf))