OpenModelica¶
Solvers¶
The different integration methods for the C runtime are listed here. The default solver used is DASSL. The C++ runtime has support for the IDA solver and other sundials packages.
DASSL¶
This is a BDF method that selects its order (1-5) and step size at each step. It uses Newton’s method to solve the resulting system of equations. It provides Newton’s method with an initial guess by evaluating a polynomial that interpolates the last few time steps. These points are then used to calculate initial guesses for the derivatives. It has additional features like root finding functionality, and an initial condition solver for when not all initial values are given explicitly.
Runge-Kutta¶
This is the classical 4-th order Range-Kutta method based on a fixed step.
Euler¶
Standard Euler method with fixed step.
Compiler¶
The OpenModelica Compiler (OMC) is used to flatten Modelica models, transform them
and output them into a format suitable for simulation. The compiler source code is
mainly written in MetaModelica and is contained in the OMCompiler/Compiler
directory.
Model Flattening and Debugging¶
Return flat Modelica for last class in file file.mo
using MSL and SolarTherm libraries:
omc file.mo Modelica SolarTherm
Create graph dot model for DAE of class (silencing flat model output):
omc -q -d=daedumpgraphv file.mo
Use omc --help=debug
to get more debug options.
Simulation¶
The OMC SimCode module outputs the model into the target language. By default this
is C source code, but other formats can be selected with
the --simCodeTarget
flag (see also OMCompiler/Compiler/SimCode/SimCodeMain.mo
).
The simulation runtime source code is contained under OMCompiler/SimulationRuntime
.
This contains the C and C++ runtimes and several others.
C Simulation Runtime¶
The C code target is selected by default and the resulting code is generated by:
omc -q -s file.mo Modelica SolarTherm
The generated source is then compiled and linked to the C simulation runtime
library into a final executable. When the last class in the input file is
Class
, the executable is built with:
make -f Class.makefile
It is then simulated with:
./Class
Experiment annotations in Class
don’t seem to be used. The Class_init.xml
file contains model information and simulation parameters. The
C simulation runtime reads this file, so things like time intervals can be changed without
recompiling the simulation executable.
The simulation executable can accept a number of command line (call with -help
and -help=<flag>
for more information). For example to output events:
./Class -lv=LOG_EVENTS
By default the simulation will output the results into a file named Class_res.mat
,
which is a MAT-file version 4. Another optional output is a CSV file, but this
dramatically slows down the simulation.
Listed below are the source files generated in this process and an initial attempt to explain their purpose.
.makefile
Makefile for building the simulation executable. It could be manually edited if trouble with linking libraries in compilation.
_init.xml
Is an extension of the FMI standard. It has 3 main parts. The first is a high level description of the mode including the model name and number of variables. The second is the experiment parameters and the third is a list of the model variables along with their types, reference values and some parameters.
_info.json
Appears to contain similar information as that in the variables section of
Class_init.xml
..c
This contains the main function for the simulation, which puts together the simulation data (the
DATA
struct defined inSimulationRuntime/c/simulation_data.h
) from the other source files and then passes it off to the_main_SimulationRuntime
function (defined inSimulationRuntime/c/simuation/simulation_runtime.{h,cpp}
). This data contains information about the model (e.g., number of states) and callbacks for evaluating different parts of the model. The file defines functions for evaluating equations and algorithms in the model. It then builds the DAE and ODE systems from these functions which are used as callbacks._functions.{h,c}
These files appear to contain struct definitions for any records that are defined and wrapper functions for any external C code used. Included by most other files here.
_model.h
A whole heap of macros that are used for conveniently accessing things like the current value of a variable in the simulation. The macros are used in the callback functions and operate on the simulation data passed to the callback function. Included by most other files here.
_literals.h
I think just some simple string literals defined. Included by most other files here.
_includes.h
Empty in the examples examined.
_records.c
Contains some additional code for records, for example names for the record and record fields.
_01exo.c
Constructors and deconstructors for external objects.
_02nls.c
Contains nonlinear systems (haven’t observed it populated yet).
_03lsy.c
Linear systems (haven’t observed it populated yet).
_04set.c
Initial state set (haven’t observed it populated yet).
_05evt.c
Raw time, zero crossing, relation and discrete events. For zero crossings it contains a callback function that calls relevant functions defined in
.c
in order to update variables, and another callback function for checking transitions._06inz.c
Contains equation and algorithm functions for initialising variables. These equations are named with indices smaller than the functions in
.c
. Also contains function to initialise mixed systems (haven’t observed it populated yet)._07dly.c
Delay. Don’t know what this does and haven’t seen it populated.
_08bnd.c
Updates bound parameters and variable attributes start, nominal, min and max. Not sure exactly when this would be used. It contains equation and algorithm functions for this purpose with indices greater than those in
.c
._09alg.c
Collects together the functions from
.c
for the algebraic system._10asr.c
Contains functions checking and throwing asserts. These functions have indices greater than those in
_08bnd.c
._11mix.{h,c}
Contains mixed systems (haven’t observed it populated yet).
_12jac.{h,c}
Contains functions for calculating and initialising the Jacobian. It seems to always contain sparsity information. The compiler flag
--generateSymbolicJacobian
needs to be set to produce equations for the symbolic calculation of the jacobian. Additionally a compiler call with-g=Optimica
flag on anoptimization
class will produce stuff._13opt.{h,c}
Contains functions needed in optimisation like the objective and Lagrangian and for grabbing bounds from variables. Need to call compiler with
-g=Optimica
flag and have anoptimization
class to get something interesting here._14lnz.c
Linearisation. Not sure what for and haven’t seen it populated.
The C simulation runtime is located under OMCompiler/SimulationRuntime/c
.
Interesting files include:
simulation_data.h
Contains the
DATA
struct and others.simuation/simulation_runtime.{h,cpp}
Contains
_main_SimulationRuntime
function which gets called to run the simulation with the model data from the generated model code.simulation/solver/solver_main.c
The
solver_main_step
function gets called to step the simulation and then passes the stepping off to the appropriate backend solver.simulation/solver/perform_simulation.c
Contains the main simulation while loop in the function
prefixedName_performSimulation
.simulation/solver/dassl.c
Contains the DASSL related functions including the
dassl_step
function. According to a comment in the file the integrated zero crossing method is disabled and zero crossings are instead handled outside DASSL (not same thing as internal root finding, which by default is turned on). It has functions for the symbolic or numeric calculations of Jacobians. The method can be selected with the-dasslJacobian
flag, wherecoloredNumerical
is the default. See the_12jac.{h,c}
files for where the symbolic jacobian comes from (has to be enabled at during model compilation).
C++ Simulation Runtime¶
An example of C++ code generation:
omc -q -s --simCodeTarget=Cpp file.mo Modelica SolarTherm
The resulting files are slow to compile and sometimes fail for more complicated
models. The simulation parameters are passed to the executable on the command line
instead of being read from an XML file. See the Class.sh
script for an example of
the command line switches. It is able to use IDA instead of DASSL, which worked on at least
a very simple example.
Language¶
Here are some notes on different aspects of the Modelica language. Some of the quirks presented here may just be specific to OpenModelica, whereas others are part of the language specification.
Expandable Connectors¶
Expandable connectors can have some defined components:
expandable connector Bus
Real a;
end Bus;
Those that are undefined must be connected to a defined component, and the connect operator must be used:
model Model
input Real x;
input Real y;
Bus bus1;
Bus bus2;
equation
connect(x, bus1.a);
connect(y, bus1.b);
connect(bus2.b, bus1.b); // Fail: two undefined components connected
bus1.b = y; // Fail: connect must be used to construct b
end Model;
Expandable connectors cannot have flow components, but may contain non-expandable flow components.
The direction (input/output) of an expandable connector component will be determined using the normal rules with respect to the direction of the component connected to.
Discrete Equations¶
OpenModelica doesn’t yet appear to fully support having systems of equations. This error might be triggered by other issues. If in doubt put all the when
clauses in an algorithm section.