# Examples

## Simulating a model with two different parameter values

This module provides an example that illustrates the use of the python to run a Modelica simulation.

The module `buildingspy.simulate.Simulator` that can be used to automate running simulations. For example, to translate and simulate the model `Buildings.Controls.Continuous.Examples.PIDHysteresis.mo` with controller parameters `con.eOn = 1` and `con.eOn = 5`, use the following commands:

    #!/usr/bin/env python
    # -*- coding: utf-8 -*-

    from __future__ import absolute_import
    from __future__ import division
    from __future__ import print_function
    from __future__ import unicode_literals
    from io import open

    from multiprocessing import Pool
    import buildingspy.simulate.Simulator as si

    # Function to set common parameters and to run the simulation
    def simulateCase(s):
        ''' Set common parameters and run a simulation.

        :param s: A simulator object.

        '''
        s.setStopTime(86400)
        # Kill the process if it does not finish in 1 minute
        s.setTimeOut(60)
        s.showProgressBar(False)
        s.printModelAndTime()
        s.simulate()

    def main():
        ''' Main method that configures and runs all simulations
        '''
        import shutil
        # Build list of cases to run
        li = []
        # First model
        model = 'Buildings.Controls.Continuous.Examples.PIDHysteresis'
        s = si.Simulator(model, 'dymola', 'case1')
        s.addParameters({'con.eOn': 0.1})
        li.append(s)
        # second model
        s = si.Simulator(model, 'dymola', 'case2')
        s.addParameters({'con.eOn': 1})
        li.append(s)

        # Run all cases in parallel
        po = Pool()
        po.map(simulateCase, li)

        # Clean up
        shutil.rmtree('case1')
        shutil.rmtree('case2')

    # Main function
    if __name__ == '__main__':
        main()

This will run the two test cases and store the results in the directories `case1` and `case2`.

## Simulating a model with two different parameter values but without recompilation

In the above example, the value of the parameter `con.eOn` can be changed after the model has been translated. To avoid unrequired translations, the functions `buildingspy.simulate.Simulator.translate()` and `buildingspy.simulate.Simulator.simulate_translated()` can be used to translate a model, and then simulate it with different parameter values. The following commands accomplish this:

    #!/usr/bin/env python
    # -*- coding: utf-8 -*-

    from __future__ import absolute_import
    from __future__ import division
    from __future__ import print_function
    from __future__ import unicode_literals
    from io import open

    import buildingspy.simulate.Simulator as si

    # Function to set common parameters and to run the simulation
    def simulateTranslatedModel(s):
        ''' Set common parameters and run a simulation
            of an already translated model.

        :param s: A simulator object that has already been translated.

        '''
        s.setStopTime(86400)
        # Kill the process if it does not finish in 1 minute
        s.setTimeOut(60)
        s.showProgressBar(False)
        s.printModelAndTime()
        s.simulate_translated()

    def main():
        ''' Main method that configures and runs all simulations
        '''
        import copy
        import shutil

        from multiprocessing import Pool
        # Build list of cases to run
        li = []

        # First model
        model = 'Buildings.Controls.Continuous.Examples.PIDHysteresis'
        s1 = si.Simulator(model, 'dymola')
        s1.setOutputDirectory('case1')
        s1.addParameters({'con.eOn': 0.1})
        s1.setSolver('dassl')
        s1.showGUI(False)
        # Translate the model
        s1.translate()
        # Add the model to the list of models to be simulated
        li.append(s1)

        # Second model
        s2 = copy.deepcopy(s1)
        s2.setOutputDirectory('case2')
        s2.addParameters({'con.eOn': 1})
        li.append(s2)

        # Run both models in parallel
        po = Pool()
        po.map(simulateTranslatedModel, li)
        # Clean up
        # Clean up
        shutil.rmtree('case1')
        shutil.rmtree('case2')
        s1.deleteTranslateDirectory()

    # Main function
    if __name__ == '__main__':
        main()

Note

If a parameter cannot be changed after model translation, then `buildingspy.simulate.Simulator.simulate_translated()` will throw an exception.

## Plotting of Time Series

This module provides an example that illustrates the use of the python to plot results from a Dymola simulation. See also the class `buildingspy.io.postprocess.Plotter` for more advanced plotting.

The file `plotResult.py` illustrates how to plot results from a Dymola output file. To run the example, proceed as follows:

> 1. Open a terminal or dos-shell.

> 2. Set the PYTHONPATH environment variables to the directory that contains ``buildingspy`` as a subdirectory, such as

>        cd buildingspy/examples/dymola
>        export PYTHONPATH=${PYTHONPATH}:../../..

> 3. Type

>        python plotResult.py

This will execute the script `plotResult.py`, which contains the following instructions:

    #!/usr/bin/env python
    # -*- coding: utf-8 -*-

    from __future__ import absolute_import
    from __future__ import division
    from __future__ import print_function
    from __future__ import unicode_literals
    from io import open

    from builtins import range

    def main():
        ''' Main method that plots the results
        '''
        from buildingspy.io.outputfile import Reader
        import matplotlib.pyplot as plt
        import os

        # Optionally, change fonts to use LaTeX fonts
        #from matplotlib import rc
        #rc('text', usetex=True)
        #rc('font', family='serif')

        # Read results
        ofr1=Reader(os.path.join("buildingspy", "examples", "dymola", "case1", "PIDHysteresis.mat"), "dymola")
        ofr2=Reader(os.path.join("buildingspy", "examples", "dymola", "case2", "PIDHysteresis.mat"), "dymola")
        (time1, T1) = ofr1.values("cap.T")
        (time1, y1) = ofr1.values("con.y")
        (time2, T2) = ofr2.values("cap.T")
        (time2, y2) = ofr2.values("con.y")

        # Plot figure
        fig = plt.figure()
        ax = fig.add_subplot(211)

        ax.plot(time1/3600, T1-273.15, 'r', label='$T_1$')
        ax.plot(time2/3600, T2-273.15, 'b', label='$T_2$')
        ax.set_xlabel('time [h]')
        ax.set_ylabel('temperature [$^\circ$C]')
        ax.set_xticks(list(range(25)))
        ax.set_xlim([0, 24])
        ax.legend()
        ax.grid(True)

        ax = fig.add_subplot(212)
        ax.plot(time1/3600, y1, 'r', label='$y_1$')
        ax.plot(time2/3600, y2, 'b', label='$y_2$')
        ax.set_xlabel('time [h]')
        ax.set_ylabel('y [-]')
        ax.set_xticks(list(range(25)))
        ax.set_xlim([0, 24])
        ax.legend()
        ax.grid(True)

        # Save figure to file
        plt.savefig('plot.pdf')
        plt.savefig('plot.png')

        # To show the plot on the screen, uncomment the line below
        #plt.show()

    # Main function
    if __name__ == '__main__':
        main()

The script generates the following plot: