Compiling a model is done with just a few steps; importing a compiler function from the JModelica.org Python package pymodelica, specifying a model class and file location and performing the actual compilation. This will be demonstrated in Section 2.1 for the JMU, in Section 2.2 for the FMU and in Section 2.3 for the FMUX.
For more advanced usage of the compiler functions, there are compiler options and parameters which can be modified. These will be explained in Section 2.5.
Section 2.6, will go through some parts of the compilation process and how to perform these steps one by one.
The following steps compiles a model to a JMU in the JModelica.org Python interface:
Import the JModelica.org compiler function compile_jmu from the package pymodelica.
Specify the model and model file.
Perform the compilation.
This is demonstrated in the following code example.
# Import the compiler function from pymodelica import compile_jmu # Specify Modelica model and model file model_name = 'myPackage.myModel' mo_file = 'myPackage.mo' # Compile the model, return argument is the file name of the JMU compile_jmu(model_name, mo_file) >> '.\\myPackage_myModel.jmu'
Once compilation has completed successfully a JMU file will have been created on the file system. The JMU file is essentially
a compressed file archive containing files created during compilation that are needed when instantiating a model object. Return
argument for compile_jmu is the full file path of the JMU that has just been created, this will be useful later when we want to create model objects.
More about the JMU file and loading models can be found in Section 3.
In the above example, compilation has been performed with default parameters and options. The only parameters specified are
the model class name and file. compile_jmu has several other parameters which can be modified. The different parameters, their default values and interpretation will
be explained in Section 2.5.
The steps required to compile a model to an FMU is very similar to compiling a model to a JMU:
Import the JModelica.org compiler function compile_fmu from the package pymodelica.
Specify the model and model file.
Perform the compilation.
The only difference is really the requirement on the model, it must be a pure Modelica model. The following code example demonstrates how to compile an FMU.
# Import the compiler function from pymodelica import compile_fmu # Specify Modelica model and model file model_name = 'myPackage.myModel' mo_file = 'myPackage.mo' # Compile the model, return argument is the file name of the FMU compile_fmu(model_name, mo_file) >> '.\\myPackage_myModel.fmu'
As in the JMU case, when the compilation has completed successfully an FMU file will have been created on the file system. The return argument is also the full file path of the FMU that has just been created, which will be useful later when we want to create model objects. More about the FMU file and loading models can be found in Section 3.
Compiling an FMUX follows the same principle as compiling a JMU and an FMU.
Import the JModelica.org compiler function compile_fmux from the package pymodelica.
Specify the model and model file.
Perform the compilation.
The Python code example below will perform these steps.
# Import the compiler function from pymodelica import compile_fmux # Specify Modelica model and model file model_name = 'myPackage.myModel' mo_file = 'myPackage.mo' # Compile the model, return argument is the file name of the FMUX compile_fmux(model_name, mo_file) >> '.\\myPackage_myModel.fmux'
The model to be compiled might not be in a loose .mo file, but rather part of a library consisting of a directory structure containing several Modelica files. In this case, the file within the library that contains the model should not be given on the command line. Instead, the entire library should to added to the list of libraries the compiler searches for classes in. This can be done in several ways (here library directory refers to the top directory of the library, that should have the same name as the top package in the library):
Adding the directory containing the library directory to the environment variable MODELICAPATH. The compiler will search for classes in all libraries found in any on the directories in MODELICAPATH. In this case the file_name argument of the compilation function can be omitted, assuming no additional Modelica files are needed.
Setting the 'extra_lib_dirs' compiler option to the path to the directory containing the library directory. This is equivalent to adding it to the MODELICAPATH, but only for that compilation.
Giving the path to the library directory in the file_name argument of the compilation function. This allows adding a specific library to the search list (as opposed to adding all
libraries in a specific directory).
By default, the script starting a JModelica.org Python shell sets the MODELICAPATH to the directory containing the version of the Modelica Standard Library (MSL) that is included in the installation. Thus, all classes in the MSL are available without any need to specify its location.
The Python code example below demonstrates these methods:
# Import the compiler function
from pymodelica import compile_fmu
# Compile an example model from the MSL
fmu1 = compile_fmu('Modelica.Mechanics.Rotational.Examples.First')
# Compile a model from the library MyLibrary, located in C:\MyLibs
fmu2 = compile_fmu('MyLibrary.MyModel', compiler_options = {'extra_lib_dirs':'C:\MyLibs'})
# The same as the last command, if no other libraries in C:\MyLibs are needed
fmu3 = compile_fmu('MyLibrary.MyModel', 'C:\MyLibs\MyLibrary')
The compiler function parameters can be listed with the interactive help in Python. The parameters are explained in the corresponding Python docstring which is visualized with the interactive help. This is demonstrated in the code examples below.
The parameter target, is further explained in Section 2.5.5, Section 2.5.6 and Section 2.5.7.
The compile_jmu parameters can be listed with the interactive help.
# Display the docstring for compile_jmu with the Python command 'help'
from pymodelica import compile_jmu
help(compile_jmu)
Help on function compile_jmu in module pymodelica.compiler:
compile_jmu(class_name, file_name=[], compiler='auto', target='ipopt', compiler_options={},
compile_to='.', compiler_log_level='warning')
Compile a Modelica or Optimica model to a JMU.
A model class name must be passed, all other arguments have default values.
The different scenarios are:
* Only class_name is passed:
- Class is assumed to be in MODELICAPATH.
- Default compiler is ModelicaCompiler.
* class_name and file_name is passed:
- file_name can be a single path as a string or a list of paths
(strings). The paths can be for files or libraries
- Default compiler setting is 'auto' which means that the appropriate
compiler will be selected based on model file ending, i.e.
ModelicaCompiler if .mo file and OptimicaCompiler if a .mop file is
found in file_name list.
Library directories can be added to MODELICAPATH by listing them in a
special compiler option 'extra_lib_dirs', for example:
compiler_options =
{'extra_lib_dirs':['c:\MyLibs1','c:\MyLibs2']}
Other options for the compiler should also be listed in the compiler_options
dict.
The compiler target is 'ipopt' by default which means that libraries for AD
and optimization/initialization algortihms will be available as well as the
JMI. The other targets are:
'model' --
AD and JMI is included.
'algorithm' --
AD and algorithm but no Ipopt linking.
'model_noad' --
Only JMI, that is no AD interface. (Must currently be used when
model includes external functions.)
Parameters::
class_name --
The name of the model class.
file_name --
A path (string) or paths (list of strings) to model files and/or
libraries. Supports both be .mo and .mop files.
Default: Empty list.
compiler --
'auto' if a compiler should be selected automatically depending on
file ending, 'modelica' if a ModelicaCompiler should be used or
'optimica' if a OptimicaCompiler should be used.
Default: 'auto' (i.e. depends on argument file_name)
target --
Compiler target. 'model', 'algorithm', 'ipopt' or 'model_noad'.
Default: 'ipopt'
compiler_options --
Options for the compiler.
Default: Empty dict.
compile_to --
Specify location of the compiled JMU. Directory will be created if
it does not exist.
Default: Current directory.
compiler_log_level --
Set the log level for the compiler. Valid options are 'warning'/'w',
'error'/'e' or 'info'/'i'.
Default: 'warning'
Returns::
Name of the JMU which has been created.
The compile_fmu parameters can be listed with the interactive help.
# Display the docstring for compile_fmu with the Python command 'help'
from pymodelica import compile_fmu
help(compile_fmu)
Help on function compile_fmu in module pymodelica.compiler:
compile_fmu(class_name, file_name=[], compiler='modelica', target='model_fmume',
compiler_options={}, compile_to='.', compiler_log_level='warning')
Compile a Modelica model to an FMU.
A model class name must be passed, all other arguments have default values.
The different scenarios are:
* Only class_name is passed:
- Class is assumed to be in MODELICAPATH.
* class_name and file_name is passed:
- file_name can be a single path as a string or a list of paths
(strings). The paths can be to files or libraries
Library directories can be added to MODELICAPATH by listing them in a
special compiler option 'extra_lib_dirs', for example:
compiler_options =
{'extra_lib_dirs':['c:\MyLibs1','c:\MyLibs2']}
Other options for the compiler should also be listed in the compiler_options
dict.
The compiler target is 'model_fmume' by default which means that the shared
file contains the FMI for Model Exchange API. This is currently the only
target that is possible to use.
Parameters::
class_name --
The name of the model class.
file_name --
A path (string) or paths (list of strings) to model files and/or
libraries. Supports only be .mo files.
Default: Empty list.
compiler --
The compiler used to compile the model. Currently, only ModelicaCompiler
can be used.
Default: 'modelica'
target --
Compiler target.
Default: 'model_fmume'
compiler_options --
Options for the compiler.
Default: Empty dict.
compile_to --
Specify location of the compiled FMU. Directory will be created if
it does not exist.
Default: Current directory.
compiler_log_level --
Set the log level for the compiler. Valid options are 'warning'/'w',
'error'/'e' or 'info'/'i'.
Default: 'warning'
Returns::
Name of the FMU which has been created.
The compile_fmux parameters can be listed with the interactive help.
# Display the docstring for compile_fmux with the Python command 'help'
from pymodelica import compile_fmux
help(compile_fmux)
Help on function compile_fmux in module pymodelica.compiler:
compile_fmux(class_name, file_name=[], compiler='auto', compiler_options={}, compile_to='.',
compiler_log_level='warning')
Compile a Modelica model to an FMUX.
A model class name must be passed, all other arguments have default values.
The different scenarios are:
* Only class_name is passed:
- Class is assumed to be in MODELICAPATH.
* class_name and file_name is passed:
- file_name can be a single path as a string or a list of paths
(strings). The paths can be to files or libraries
Library directories can be added to MODELICAPATH by listing them in a
special compiler option 'extra_lib_dirs', for example:
compiler_options =
{'extra_lib_dirs':['c:\MyLibs1','c:\MyLibs2']}
Other options for the compiler should also be listed in the compiler_options
dict.
Parameters::
class_name --
The name of the model class.
file_name --
A path (string) or paths (list of strings) to model files and/or
libraries. Supports both be .mo and .mop files.
Default: Empty list.
compiler --
The compiler used to compile the model.
Default: 'auto'
compiler_options --
Options for the compiler.
Default: Empty dict.
compile_to --
Specify location of the compiled FMUX. Directory will be created if
it does not exist.
Default: Current directory.
compiler_log_level --
Set the log level for the compiler. Valid options are 'warning'/'w',
'error'/'e' or 'info'/'i'.
Default: 'warning'
Returns::
Name of the FMUX which has been created.
Compiler options are read from an XML file, options.xml, which can be found in the JModelica.org installation folder under the folder Options. The options are loaded from the file when a compiler is created, that is when compile_jmu, compile_fmu or compile_fmux is run. Options for a compiler instance can be modified interactively when compiling using the parameter compiler_options. This is shown in an example compiling an Optimica model below.
# Compile with the compiler option 'enable_variable_scaling' set to True
# Specify Optimica model and model file
model_name = 'myPackage.myModel'
mo_file = 'myPackage.mop'
compile_jmu(model_name, mo_file, compiler_options={"enable_variable_scaling":True})
There are four type categories: string, real, integer and boolean. The available options, default values and description are listed in Table 4.1.
Table 4.1. Compiler options
| Option | Default | Description |
|---|---|---|
normalize_minimum_time_problems |
true |
When this option is set to true then minimum time optimal control problems encoded in Optimica are converted to fixed interval problems by scaling of the
derivative variables. (Boolean option.)
|
enable_variable_scaling |
false |
If this option is true, then the "nominal" attribute will be used to scale variables in the model. (Boolean option.)
|
halt_on_warning |
false |
If this option is set to false one or more compiler warnings will not stop compilation of the model. (Boolean option.)
|
automatic_add_initial_equations |
true |
When this option is set to true, then additional initial equations are added to the model based on a the result of a matching algorithm. Initial equations
are added for states that are not matched to an equation. (Boolean option.)
|
generate_ode_jacobian |
false |
If this option is set to true, code for computing ODE Jacobians are generated. (Boolean option.)
|
eliminate_alias_variables |
true |
If this option is true, then alias variables are eliminated from the model. (Boolean option.)
|
extra_lib_dirs |
"" |
The value of this option is appended to the value of the MODELICAPATH environment variable for determining in what directories to search for libraries. (String option.)
|
generate_xml_equations |
false |
If this option is true, then model equations are generated in XML format. (Boolean option.)
|
state_start_values_fixed |
false |
This option enables the user to specify if initial equations should be generated automatically for differentiated variables
even though the fixed attribute is equal to fixed. Setting this option to true is, however, often practical in optimization problems. (Boolean option.)
|
equation_sorting |
false |
If this option is true, equations are sorted using the BLT algorithm. (Boolean option.)
|
index_reduction |
true |
If this option is true, index reduction is performed. (Boolean option.)
|
enable_structural_diagnosis |
true |
Enable this option to invoke the structural error diagnosis based on the matching algorithm. (Boolean option.) |
compliance_as_warning |
false |
When this option is set to true, then compliance errors are treated as warnings instead. This can lead to the compiler or solver crashing. Use with caution!
(Boolean option.)
|
generate_html_diagnostics |
false |
When this option is set to true model diagnostics is generated in HTML format. This includes the flattened model, connection sets, alias sets and BLT form.
(Boolean option.)
|
generate_ode |
false |
If this option is set to true, code for solving ODEs is generated. (Boolean option.)
|
convert_free_dependent_ parameters_to_algebraics |
true |
If this option is true, free dependent parameters are converted to algebraic variables. (Boolean option.)
|
generate_dae |
true |
If this option is true, code for solving DAEs is generated. (Boolean option.)
|
generate_dae_jacobian |
false |
If this option is true, code for computing DAE Jacobians is generated. (Boolean option.)
|
export_functions |
false |
Export used Modelica functions to generated C code in a manner that is compatible with the external C interface in the Modelica Language Specification. (Boolean option.) |
export_functions_vba |
false |
If this option is true, then VBA-compatible wrappers for exported functions are created. Requires export_functions = true. (Boolean option.)
|
generate_fmi_cs_xml |
false |
If this option is true the model description part of the XML variables file will be FMI for co simulation compliant. To generate an XML which will
validate with FMI schema the option generate_xml_equations must also be false.
|
divide_by_vars_in_tearing |
false |
If this option is set to true, a less restrictive strategy is used for solving equations in the tearing algorithm. Specifically, division by parameters
and variables is permitted, by default no such divisions are made during tearing.
|
enable_tearing |
false |
If this option is set to true, tearing of equation systems is enabled.
|
generate_fmi_me_xml |
false |
If this option is true the model description part of the XML variables file will be FMI for model exchange compliant. To generate an XML which will
validate with FMI schema the option generate_xml_equations must also be false.
|
inline_functions |
false |
Perform function inlining on model after flattening. |
fmi_version |
1.0 |
FMI version to use in compilation. |
There are four compiler targets available for compile_jmu:
ipopt: Compiled model will include JMI interface, AD and linking to Ipopt libraries. There is support for optimization and initialization
algorithm.
model: Compiled model will include support for JMI interface and AD.
algorithm: Compiled model will include support for JMI interface. AD and algorithm but not link with the Ipopt libraries.
model_noad: Compiled model will only include the JMI interface.
The compiler target is 'ipopt' by default which will work for most cases. However, if JModelica.org has been built without Ipopt libraries the target would
have to be changed to any other suitable target that does not include the Ipopt libraries.
The target model_noad must be used if the model contains external equations since external equations do not work with the AD interface at the moment.
Currently, the only possible target available for compile_fmu is 'model_fmume'. With this target the compiled model will include the FMI for Model Exchange API.
Compiling with compile_jmu, compile_fmu or compile_fmux bundles quite a few steps required for the compilation from model file to JMU, FMU or FMUX. Some of these steps will be described
briefly here, for a more detailed review on the compilation steps see Section 4 in Chapter 1.
A compiler, can be either a Modelica or Optimica compiler, is created by importing the Python classes from the compiler module.
The compiler constructors only has optional arguments. These are the paths to the template XML and C files which in most cases
can be left to the default values. (Note that in the compile_fmux case the only template needed is to the Model description XML template file since no C code is produced.) This example code
will create a Modelica compiler.
# import the class ModelicaCompiler from the compiler module from pymodelica.compiler import ModelicaCompiler # create a compiler instance mc = ModelicaCompiler()
In the first step of the compilation, the model is parsed and instantiated. Then the model is transformed into a flat representation which can be used to generate C and XML code. If there are errors in the model, for example syntax or type errors, Python exceptions will be thrown during these steps.
# Parse the model and get a reference to the source root
source_root = mc.parse_model('myPackage.mo')
# Generate an instance tree representation and get a reference to the model instance
model_instance = mc.instantiate_model(source_root, 'myPackage.myModel')
# Perform flattening and get a flat representation
flat_rep = mc.flatten_model(model_instance)
The next step is the code generation which produces C code containing the model equations and a couple of XML files containing
model meta data such as variable names and types and parameter values. Note that in the compile_fmux case, only XML code is generated in this step.
# Generate code mc.generate_code(flat_rep)