2. Compilation

In its simplest form, compilation only requires a few lines of code; importing a compiler function from JModelica.org and specifying a Modelica or Optimica model and file location. This will be demonstrated in Section 2.1. For more advanced usage there are compiler options and parameters which can be modified, this will be explained in Section 2.2. The last section in this part, Section 2.3, will go through the compilation process and how to compile a model step-by-step.

2.1. Simple compilation example

The following steps compiles a model in the JModelica.org Python interface:

  1. Import the JModelica.org compiler function compile_jmu from jmodelica.jmi.

  2. Specify the model and model file.

  3. Perform the compilation.

This is demonstrated in the following code example.

# import the compiler function
from jmodelica.jmi 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 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 model 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.2.

2.2. Compiler settings

2.2.1. compile_jmu parameters

The compile_jmu parameters can be listed with the interactive help. The compiler target, which is set with the parameter target, is further explained in Section 2.2.3.

# display the docstring for compile_jmu with the Python command 'help'
from jmodelica.jmi import compile_jmu
help(compile_jmu)

Help on function compile_jmu in module jmodelica.jmi:

compile_jmu(class_name, file_name=[], compiler='modelica', target='ipopt', 
            compiler_options={}, compile_to='.')
    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:
        - Default compiler is ModelicaCompiler.
        - Class is assumed to be in MODELICAPATH.

    * class_name and file_name is passed:
        - file_name can be a single file as a string or a list of file_names
          (strings).
        - Default compiler is ModelicaCompiler but will switch to
          OptimicaCompiler if a .mop file is found in file_name.

    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:\MyLibs\MyLib1','c:\MyLibs\MyLib2']}

    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 --
            Model file (string) or files (list of strings), can be both .mo or
            .mop files.
            Default: Empty list.

        compiler --
            'modelica' or 'optimica' depending on whether a ModelicaCompiler or
            OptimicaCompiler should be used. Set this argument if default
            behaviour should be overridden.
            Default: 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.

    Returns::

        Name of the JMU which has been created.

2.2.2. Compiler options

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 is run. Options for a compiler instance can be modified by editing the file before compiling. 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

OptionDefaultDescription
normalize_minimum_time_problemstrueWhen this option is set to true the minimum time optimal control problems encoded in Optimica are converted to fixed interval problems by scaling of the derivative variables. (Boolean option.)
enable_variable_scalingfalseIf this option is true, then the "nominal" attribute will be used to scale variables in the model. (Boolean option.)
halt_on_warningfalseIf this option is set to false one or more compiler warnings will not stop compilation of the model. (Boolean option.)
automatic_add_initial_equationstrueWhen 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_fmi_xmlfalseIf this option is true the model description part of the XML variables file will be FMI compliant. To generate an XML which will validate with FMI schema the option generate_xml_equations must also be set to false. (Boolean option.)
eliminate_alias_variablestrueIf this option is set to true, then alias variables are eliminated from the model. (Boolean option.)
extra_lib_dirs"" (Empty string)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_equationsfalseIf this option is true, then model equations are generated in XML format. (Boolean option.)
state_start_values_fixedfalseThis 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_sortingfalseIf this option is true, equations are sorted using the BLT algorithm. (Boolean option.)
index_reductionfalseIf this option is true, index reduction is performed. (Boolean option.)
enable_symbolic_diagnosistrueEnable this option to invoke the structural error diagnosis based on the matching algorithm. (Boolean option.)


2.2.3. Compiler targets

There are four compiler targets available:

  • 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 compile_model parameter target is 'ipopt' by default which will work for most cases. However, if JModelica.org has been built without Ipopt libraries the target parameter 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.

2.3. Compilation in more detail

Compiling with compile_jmu bundles quite a few steps required for the compilation. These steps will be described briefly here, for a more detailed review on the compilation steps see Section 4 in Chapter 1.

2.3.1. Create a compiler

A compiler, can be either a Modelica or Optimica compiler, is created by importing the Python classes from the compiler module. The compiler constructors do not take any arguments. This example code will create a Modelica compiler.

# import the class ModelicaCompiler from the compiler module
from jmodelica.compiler import ModelicaCompiler

# create a compiler instance
mc = ModelicaCompiler()

2.3.2. Source tree generation and flattening

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 = oc.flatten_model(model_instance)

2.3.3. Code generation

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.

# Generate code
mc.generate_code(flat_rep)

2.3.4. Generate a shared object file

Finally, the shared object file is built where the C code is linked with the JModelica.org Model Interface (JMI) runtime library. The compile_binary method takes one obligatory parameter, the name of the C file that was generated in the previous step. The parameter target must also be set here if something other than the default 'model' is wanted. In this example, target is changed to 'ipopt'. For more information on targets, see Section 2.2.3.

# Compile a shared object file
c_file = 'myPackage_myModel.c'
mc.compile_binary(c_file, target='ipopt')