Modelica in action: how to structure models in packages

by Marco Bonvini on Thursday January 05, 2017

If you work with Modelica you should be familiar with packages. Packages are a way to organize and structure your models. In this post I will show how to structure your models in a package. The post is accompanied by an example that is included in the Github repository ModelicaInAction.

Modelica packages

If you have a look at the Modelica Standard Library MSL you’ll notice that it’s a collections of models and functions structured in packages. The same is true for all the other Modelica libraries.

Packages can be defined within a single *.mo file, otherwise they can be a collection of folders and files. Using folders and files is generally the best approach because it’s easier to manage many small files rather a very large one, also, it’s easier to track changes using a version control system, especially when working in a team.

Structuring models in packages

The folder modelica that is included in the ModelicaInAction repository contains a package called SimpleElectrical.

The package contains a collections of models representing basic electric components. Most of the components in this library were introduced in this article SW engineering meets mathematical modeling - Types and Objects

The repository is named SimpleElectrical and it’s located in the folder ModelicaInAction/modelica/.

ModelicaInAction/modelica/
├── HelloWorld.mo
└── SimpleElectrical
    ├── package.mo
    ├── package.order
    ├── Components
    │   ├── Capacitor.mo
    │   ├── Ground.mo
    │   ├── Inductor.mo
    │   ├── Resistor.mo
    │   ├── Source.mo
    │   ├── package.mo
    │   └── package.order
    ├── Connectors
    │   ├── Terminal.mo
    │   ├── package.mo
    │   └── package.order
    ├── Examples
    │   ├── RC.mo
    │   ├── package.mo
    │   └── package.order
    └── Interfaces
        ├── Bipole.mo
        ├── package.mo
        └── package.order

Each folder containing the files package.{mo,order} is a package. The file package.mo contains the actual definition of the package, while the file package.order defines the order of the elements within the package.

Packages can contain other sub-packages. A good design principle is to group models that have similar characteristics in sub-packages. For example in our case the SimpleElectrical package contains four sub-packages

  • Connectors contains the definition of the connectors used to connect components in the library,
  • Interfaces contains the definition of abstract extendable models,
  • Components contains the main electrical components such as resistances, capacitances, etc.
  • Examples contains a list of examples that showcase the use of the library.

The Modelica language specification doesn’t prescribe how packages should be called, however the names I used are a de-facto standard when working with Modelica libraries.

Anatomy of a package

Let’s have a look at the code inside the files in order to fully understand how packages work. At the top level we have the following structure of files and folders

ModelicaInAction/modelica/
└── SimpleElectrical   <-- Root-package (a folder)
    ├── package.mo
    ├── package.order  <-- Sub-package (a folder)
    ├── Components     <-- Sub-package (a folder)
    ├── Connectors     <-- Sub-package (a folder)
    └── Examples       <-- Sub-package (a folder)

This is the content of the file SimpleElectrical/package.mo

1 within ;
2 package SimpleElectrical
3   "Modelica electrical package for educational purposes"
4 end SimpleElectrical;

The first line contains the keyword within followed by a white space, this indicates that the file is not part of any sub-package. The remaining lines contain the declaration of the package SimpleElectrical. Please note that the name of the packages has to match the name of the folder containing it.

We know that the package contains four sub-packages, and each one is represented by a folder. A Modelica tool that visualizes the hierarchy of models and packages needs to know in which order display them. This is the role of the file SimpleElectrical/package.order. The file contains an ordered list of the sub-packages contained by the root-level package.

In our case the content of SimpleElectrical/package.order is

Connectors
Interfaces
Components
Examples

So far we’ve seen the structure of the top level package. But how do sub-packages work? Let’s have a look at the sub-package Components.

ModelicaInAction/modelica/
└── SimpleElectrical
    ├── package.mo
    ├── package.order
    ├── Components
    │   ├── Capacitor.mo
    │   ├── Ground.mo
    │   ├── Inductor.mo
    │   ├── Resistor.mo
    │   ├── Source.mo
    │   ├── package.mo
    │   └── package.order
    ...

Again, the folder SimpleElectrical/Components (that has the same name of the sub-package) contains the files package.{mo,order}. However, in this case the folder contains other *.mo files such as Ground.mo, Resistor.mo, etc. These files are the actual content of the sub-package.

The content of the file SimpleElectrical/Components/package.mo is

1 within SimpleElectrical;
2 package Components
3   "Package containing the electrical model
4   components"
5 end Components;

In this case Components is a sub-package, therefore the first line states that it is part of the parent package SimpleElectrical. The following lines declare the sub-package. The models contained in this package are the remaining *.mo files. Let’s have a look at Source.mo.

 1 within SimpleElectrical.Components;
 2 
 3 model Source
 4   extends SimpleElectrical.Interfaces.Bipole;
 5   parameter Modelica.SIunits.Voltage E = 10
 6     "Constant voltage source";
 7 equation
 8   // The source generates a voltage difference
 9   // between the two terminals
10   V = E;
11 end Source;

The first line declares that this model is part of the package SimpleElectrical.Components, while the following lines declare the model. Again the name of the model matches the name of the file in the file system.

As we have seen before, the folder contains a file called package.order that defines the order of the models within the package. The content of SimpleElectrical/Components/package.order is

Ground
Source
Resistor
Capacitor
Inductor

Using the package

OK, now that we know everything about packages and their structure, let’s see how to use the models they contain. For example we’re interested in simulating the model SimpleElectrical.Examples.RC that is defined in the file `SimpleElectrical/Examples/RC.mo**.

In order to simulate the model we have to inform the compiler of the existence of this new library SimpleElectrical. This can be accomplished in two ways:

  • adding the path containing the library to the environmental variable MODELICAPATH,
  • specifying the location of the library when compiling the model.

In this case the docker image provided by ModelicaInAction is built using the following command

ENV MODELICAPATH /home/docker/installed/JModelica/ThirdParty/MSL:/home/docker/modelica

that adds the path /home/docker/modelica to the environmental variable MODELICAPATH. Thanks to this the compiler will be able to automatically find the package SimpleElectrical.

Load and simulate

Once the MODELICAPATH is set, we can specify the model we’d like to compiled and simulate using the dot notation. For example the model we want to simulate is called RC and it’s located in the sub-package SimpleElectricalExamples. Using the dot notation this becomes SimpleElectrical.Examples.RC.

1 # Compile the model and save the return argument,
2 # that is the file name of the FMU
3 rc_example_fmu = compile_fmu("SimpleElectrical.Examples.RC")
4 
5 # Load the model and simulate
6 rc_example = load_fmu(rc_example_fmu)
7 res = rc_example.simulate(final_time=0.1)

and plot the results as usual

alt tag

Conclusions

After having seen all the nice features provided by Modelica, in the post titled SW engineering meets mathematical modeling - Types and Objects. we have finally learned how to actually use them.

In particular we learned how to structure Modelica models in packages, a bit of naming convention for packages, and access and simulate models inside packages using JModelica.

All the code is part of the repository ModelicaInAction. If you have questions regarding these examples please feel free to leave a comment or submit an issue/pull requesto on Github.

Disclaimer

All materials on this site are protected by copyright and intellectual property laws and are the property of Marco Bonvini. Unless stated otherwise, you may access and download the materials located on marcobonvini.com only for personal, non-commercial use.

Social Links

Location

California, US

Website powered by BlackTie, and Jekyll - © Marco Bonvini 2015-2020