modelicares.exps — ModelicaRes v0.8.0 Documentation
Description: Python module to set up, plot, and analyze Modelica simulations
Keywords: Modelica, Python, plot, results, simulation, experiment

### Navigation

- index
- modules |
- next |
- previous |
- ModelicaRes v0.8.0 Documentation »

# `modelicares.exps`

Set up and help run Modelica simulation experiments.

This module supports two approaches for managing simulations. The first is to create a Modelica script (using `write_script()`) and run it within a Modelica environment (see the scripts in “examples/ChuaCircuit/”), which translates and simulates the models with the prescribed settings. The second approach is to execute pre-translated models. The `run_models()` method handles this by writing to initialization file(s) (e.g, “dsin.txt”) and launching the appropriate model executables. The advantage of the first approach is that formal parameters (those that are hard-coded during translation) can be adjusted. However, the second approach is faster because it does not require a model to be recompiled when only tunable parameters (those that are not hard-coded during translation) are changed.

The first step in either case is to create a dictionary to specify model parameters and other settings for simulation experiment. A single model parameter may have multiple possible values. The dictionary is passed to the `gen_experiments()` function (see that function for a description of the dictionary format), which combines the values of all the variables (by piecewise alignment or permutation) and returns a generator to step through the experiments. Finally, the generator is passed to the `write_script()` or `run_models()` function (see first paragraph).

class `modelicares.exps.` `Experiment`

  Bases: `tuple`

  Named tuple class to represent a simulation experiment

  Instances of this class may be used in the experiments argument of `write_script()` and `run_models()`, although there are some differences in the entries (see those functions for details).

  Example:

      >>> from modelicares import *

      >>> experiment = Experiment('ChuaCircuit', params={'L.L': 18}, args={})
      >>> experiment.model
      'ChuaCircuit'

  `__repr__`()

    Return a nicely formatted representation string

  `args`

    Alias for field number 2

  `model`

    Alias for field number 0

  `params`

    Alias for field number 1

class `modelicares.exps.` `ParamDict`

  Bases: `dict`

  Dictionary that prints its items (string mapping) as nested tuple-based modifiers, formatted for Modelica

  Otherwise, this class is the same as `dict`. The underlying structure is not nested or reformatted—only the informal representation (`ParamDict.__str__()`).

  `__str__`()

    Map the `ParamDict` instance to a string using tuple-based modifiers formatted for Modelica.

    Each key is interpreted as a parameter name (including the full model path in Modelica dot notation) and each entry is a parameter value. The value may be a number (integer or float), Boolean constant (in Python format—True or False, not ‘true’ or ‘false’), string, or NumPy arrays of these. Modelica strings must be given with double quotes included (e.g., ‘“hello”’). Enumerations may be used as values (e.g., ‘Axis.x’). Values may include functions, but the entire value must be expressed as a Python string (e.g., ‘fill(true, 2, 2)’). Items with a value of None are not shown.

    Redeclarations and other prefixes must be included in the key along with the name of the instance (e.g., ‘redeclare Region regions[n_x, n_y, n_z]’). The single quotes must be explicitly included for instance names that contain symbols (e.g., “‘H+’”).

    Note that Python dictionaries do not preserve order.

    Example:

        >>> from numpy import array
        >>> from modelicares import *

        >>> d = ParamDict({'a': 1, 'b.c': array([2, 3]), 'b.d': False,
        ...                'b.e': '"hello"', 'b.f': None})
        >>> print(d)
        (a=1, b(c={2, 3}, e="hello", d=false))

        # The formal representation (and the internal structure) is unaffected:
        >>> d
        {'a': 1, 'b.c': array([2, 3]), 'b.f': None, 'b.e': '"hello"', 'b.d': False}

        # An empty dictionary prints as an empty string (not "()"):
        print(ParamDict({}))

`modelicares.exps.` `gen_experiments`(models=None, params={}, args={}, design=<function fullfact at 0xa7085dc>)

  Return a generator for a set of simulation experiments using permutation or simple element-wise grouping.

  The generator yields instances of `Experiment`—named tuples of (model, params, args), where model is the name of a single model (type `str`), params is a specialized dictionary (`ParamDict`) of model parameter names and values, and arg_dict is a dictionary (`dict`) of command arguments (keyword and value) for the Modelica tool or environment.

  Arguments:

  - models: List of model names (including the full model path in Modelica dot notation)

  - params: Dictionary of model parameters

    > Each key is a variable name and each entry is a list of values. The keys must indicate the hierarchy within the model—either in Modelica dot notation or via nested dictionaries.

  - args: Dictionary of command arguments for the Modelica tool or environment (e.g., to the `simulateModel()` command in Dymola)

    > Each key is an argument name and each entry is a list of settings.

  - design: Method of generating the simulation experiments (i.e., design of experiments)

    > This is a function that returns a iterable object that contains or generates the simulation settings. Several options are available in `modelicares.doe`.

  Example 1 (element-wise list of experiments):

      >>> from modelicares import *

      >>> experiments = gen_experiments(
      ...                  ['Modelica.Electrical.Analog.Examples.ChuaCircuit']*3,
      ...                  {'L.L': [16, 18, 20], 'C2.C': [80, 100, 120]},
      ...                  design=doe.aslisted)
      >>> for experiment in experiments:
      ...     print(experiment.model + str(experiment.params))
      Modelica.Electrical.Analog.Examples.ChuaCircuit(C2(C=80), L(L=16))
      Modelica.Electrical.Analog.Examples.ChuaCircuit(C2(C=100), L(L=18))
      Modelica.Electrical.Analog.Examples.ChuaCircuit(C2(C=120), L(L=20))
      >>> # Note that the model name must be repeated in the models argument.

  Example 2 (one-factor-at-a-time; first entries are baseline):

      >>> from modelicares import *

      >>> experiments = gen_experiments(
      ...                  ['Modelica.Electrical.Analog.Examples.ChuaCircuit'],
      ...                  {'L.L': [16, 18, 20], 'C2.C': [80, 100, 120]},
      ...                  design=doe.ofat)
      >>> for experiment in experiments:
      ...     print(experiment.model + str(experiment.params))
      Modelica.Electrical.Analog.Examples.ChuaCircuit(C2(C=80), L(L=16))
      Modelica.Electrical.Analog.Examples.ChuaCircuit(C2(C=80), L(L=18))
      Modelica.Electrical.Analog.Examples.ChuaCircuit(C2(C=80), L(L=20))
      Modelica.Electrical.Analog.Examples.ChuaCircuit(C2(C=100), L(L=16))
      Modelica.Electrical.Analog.Examples.ChuaCircuit(C2(C=120), L(L=16))

  Example 3 (permutation—full-factorial design of experiments):

      >>> from modelicares import *

      >>> experiments = gen_experiments(
      ...                  ['Modelica.Electrical.Analog.Examples.ChuaCircuit'],
      ...                  {'L.L': [16, 18, 20], 'C2.C': [80, 100, 120]},
      ...                  design=doe.fullfact)
      >>> for experiment in experiments:
      ...     print(experiment.model + str(experiment.params))
      Modelica.Electrical.Analog.Examples.ChuaCircuit(C2(C=80), L(L=16))
      Modelica.Electrical.Analog.Examples.ChuaCircuit(C2(C=100), L(L=16))
      Modelica.Electrical.Analog.Examples.ChuaCircuit(C2(C=120), L(L=16))
      Modelica.Electrical.Analog.Examples.ChuaCircuit(C2(C=80), L(L=18))
      Modelica.Electrical.Analog.Examples.ChuaCircuit(C2(C=100), L(L=18))
      Modelica.Electrical.Analog.Examples.ChuaCircuit(C2(C=120), L(L=18))
      Modelica.Electrical.Analog.Examples.ChuaCircuit(C2(C=80), L(L=20))
      Modelica.Electrical.Analog.Examples.ChuaCircuit(C2(C=100), L(L=20))
      Modelica.Electrical.Analog.Examples.ChuaCircuit(C2(C=120), L(L=20))

  Example 4 (parameters given in nested form):

      >>> from modelicares import *

      >>> models = ['Modelica.Mechanics.MultiBody.Examples.Systems.RobotR3.oneAxis']
      >>> params = dict(axis=dict(motor=dict(i_max=[5, 15],
      ...                                    Ra=dict(R=[200, 300]))))
      >>> for experiment in gen_experiments(models, params):
      ...     print(experiment.model + str(experiment.params))
      Modelica.Mechanics.MultiBody.Examples.Systems.RobotR3.oneAxis(axis(motor(i_max=5, Ra(R=200))))
      Modelica.Mechanics.MultiBody.Examples.Systems.RobotR3.oneAxis(axis(motor(i_max=15, Ra(R=200))))
      Modelica.Mechanics.MultiBody.Examples.Systems.RobotR3.oneAxis(axis(motor(i_max=5, Ra(R=300))))
      Modelica.Mechanics.MultiBody.Examples.Systems.RobotR3.oneAxis(axis(motor(i_max=15, Ra(R=300))))

      >>> # Note that the underlying representation of the parameters is
      >>> # actually flat:
      >>> for experiment in gen_experiments(models, params):
      ...     experiment.params
      {'axis.motor.Ra.R': 200, 'axis.motor.i_max': 5}
      {'axis.motor.Ra.R': 200, 'axis.motor.i_max': 15}
      {'axis.motor.Ra.R': 300, 'axis.motor.i_max': 5}
      {'axis.motor.Ra.R': 300, 'axis.motor.i_max': 15}
      >>> # Also note that Python dictionaries do not preserve order (and it
      >>> # is not necessary here).

`modelicares.exps.` `modelica_array`(x)

  Return a string representing a NumPy array in Modelica format.

  Square brackets are curled and Booleans are cast to lowercase.

  Example:

      >>> from numpy import array
      >>> from modelicares import *

      >>> x = array([[1, 2], [3, 4]])
      >>> modelica_array(x)
      '{{1, 2}, {3, 4}}'

      >>> modelica_array(array([[True, True], [False, False]]))
      '{{true, true}, {false, false}}'

`modelicares.exps.` `modelica_boolean`(x)

  Return a string representing an instance of Python’s `bool` in Modelica.

  This is simply ‘true’ or ‘false’ (in lowercase).

  Example:

      >>> from modelicares import *

      >>> modelica_boolean(True)
      'true'
      >>> modelica_boolean(False)
      'false'

`modelicares.exps.` `read_params`(names, fname='dsin.txt')

  Read parameter values from an initialization or final values file.

  Arguments:

  - names: Parameter name or list of names (with full model path in Modelica dot notation)

    > A parameter name includes array indices (if any) in Modelica representation (1-base indexing); the values are scalar.

  - fname: Name of the file (may include the file path)

  Example:

      >>> from modelicares import *

      >>> read_params(['L.L', 'C1.C'], 'examples/dsin.txt')
      [18.0, 10.0]

`modelicares.exps.` `run_models`(experiments=[(None, {}, {})], filemap={'dslog.txt': '%s_%i.log', 'dsres.mat': '%s_%i.mat'})

  Run Modelica models via pairs of executables and initialization files.

  Warning

  This function has not yet been implemented.

  Arguments:

  - experiments: Tuple or (list or generator of) tuples specifying the simulation experiment(s)

    > The first entry of each tuple is the name of the model executable. The second is a dictionary of model parameter names and values. The third is a dictionary of simulation settings (keyword and value).

    > Each tuple may be (optionally) an instance of the tuple subclass `Experiment`, which names the entries as model, params, and args. These designations are used below for clarity.

    > model may include the file path. It is not necessary to include the extension (e.g., ”.exe”). There must be a corresponding model initialization file on the same path with the same base name and the extension ”.in”. For Dymola®, the executable is the “dymosim” file (possibly renamed) and the initialization file is a renamed ‘dsin.txt’ file.

    > The keys or variable names in the params dictionary must indicate the hierarchy within the model—either in Modelica dot notation or via nested dictionaries. The items in the dictionary must correspond to parameters in the initialization file. In Dymola, these are integers or floating point numbers. Therefore, arrays must be broken into scalars by indicating the indices (Modelica 1-based indexing) in the key along with the variable name. Enumerations and Booleans must be given as their unsigned integer equivalents (e.g., 0 for False). Strings and prefixes are not supported.

    > Items with values of None in params and args are skipped.

  - filemap: Dictionary of result file mappings

    > Each key is the path/name of a file that is generated during simulation (source) and each value is the path/name it will be copied as (destination). The sources and destinations are relative to the directory indicated by the model subargument. ‘%s’ may be included in the destination to indicate the model name (model) without the full path or extension. ‘%i’ may be included to indicate the simulation number in the sequence of experiments.

  There are no return values.

`modelicares.exps.` `write_params`(params, fname='dsin.txt')

  Write parameter values to a simulation initialization file.

  Arguments:

  - params: Dictionary of parameters

    > Each key is a parameter name (including the full model path in Modelica dot notation) and each entry is a parameter value. The parameter name includes array indices (if any) in Modelica representation (1-bases indexing). The values must be representable as scalar numbers (integer or floating point). True and False (not ‘true’ and ‘false’) are automatically mapped to 1 and 0. Enumerations must be given explicitly as the unsigned integer equivalent. Strings, functions, redeclarations, etc. are not supported.

  - fname: Name of the file (may include the file path)

  Example:

      >>> from modelicares import *

      >>> write_params({'L.L': 10, 'C1.C': 15}, 'examples/dsin.txt')

  This updates the appropriate lines in “examples/dsin.txt”:

      -1      10                  0       0                  1  280   # L.L
      ...
      -1      15                  0  1.000000000000000E+100  1  280   # C1.C

`modelicares.exps.` `write_script`(experiments=[(None, {}, {})], packages=[], working_dir='~/Documents/Modelica', fname='run-sims.mos', command='simulateModel', results=['dsin.txt', 'dslog.txt', 'dsres.mat', 'dymosim%x', 'dymolalg.txt'])

  Write a Modelica script to run simulations.

  Arguments:

  - experiments: Tuple or (list or generator of) tuples specifying the simulation experiment(s)

    > The first entry of each tuple is the name of the model to be simulated, including the full path in Modelica dot notation. The second is a dictionary of parameter names and values. The third is a dictionary of command arguments (keyword and value) for the Modelica tool or environment (see below for Dymola®).

    > Each tuple may be (optionally) an instance of the tuple subclass `Experiment`, which names the entries as model, params, and args. These designations are used below for clarity.

    > The keys or variable names in the params dictionary must indicate the hierarchy within the model—either in Modelica dot notation or via nested dictionaries. If model is None, then params is not used. Python values are automatically mapped to their Modelica equivalent (see `ParamDict.__str__()`). Redeclarations and other prefixes must be included in the keys along with the variable names.

    > `gen_experiments()` can be used to create a generator for this argument.

    > Items with values of None in params and args are skipped.

  - working_dir: Working directory (for the executable, log files, etc.)

    > ‘~’ may be included to represent the user directory.

  - packages: List of Modelica packages that should be preloaded or scipts that should be run

    > Each may be a “*.mo” file, a folder that contains a “package.mo” file, or a “*.mos” file. The path may be absolute or relative to working_dir. It may be necessary to include in packages the file or folder that contains the model specified by the model subargument, but the Modelica Standard Library generally does not need to be included. If an entry is a script (“*.mos”), it is run from its folder.

  - fname: Name of the script file to be written (usually in the form

      “*.mos”)

      > This may include the path (‘~’ for user directory). The results will be stored relative to the same folder. If the folder does not exist, it will be created.

  - command: Simulation or other command to the Modelica tool or environment

    > Instead of the default (‘simulateModel’), this could be ‘linearizeModel’ to create a state space representation or ‘translateModel’ to create model executables without running them.

  - results: List of files to copy to the results folder

    > Each entry is the path/name of a file that is generated during simulation. The path is relative to the working directory. ‘%x’ may be included in the filename to represent ‘.exe’ if the operating system is Windows and ‘’ otherwise. The result folders are named by the number of the simulation run and placed within the folder that contains the simulation script (fname).

  If command is ‘simulateModel’ and the Modelica environment is Dymola®, then the following keywords may be used in args (see experiments above). The defaults (shown in parentheses) are applied by Dymola®—not by this function.

  - startTime (0): Start of simulation
  - stopTime (1): End of simulation
  - numberOfIntervals (0): Number of output points
  - outputInterval (0): Distance between output points
  - method (“Dassl”): Integration method
  - tolerance (0.0001): Tolerance of integration
  - fixedstepsize (0): Fixed step size for Euler
  - resultFile (“dsres.mat”): Where to store result

  Note that problem is not listed. It is generated from model and params. If model is None, the currently/previously translated model will be simulated.

  Returns:

  1. List of model names without full model paths
  2. Directory where the script has been saved

  Example 1 (single simulation):

      >>> from modelicares import *

      >>> experiment = Experiment(model='Modelica.Electrical.Analog.Examples.ChuaCircuit',
      ...                         params={},
      ...                         args=dict(stopTime=2500))
      >>> write_script(experiment,
      ...              fname="examples/ChuaCircuit/run-sims1.mos")
      (['ChuaCircuit'], '...examples/ChuaCircuit')

  In “examples/ChuaCircuit/run-sims1.mos”:

      import Modelica.Utilities.Files.copy;
      import Modelica.Utilities.Files.createDirectory;
      Advanced.TranslationInCommandLog = true "Also include translation log in command log";
      cd(".../Documents/Modelica");
      destination = ".../examples/ChuaCircuit/";

      // Experiment 1
      ok = simulateModel("Modelica.Electrical.Analog.Examples.ChuaCircuit", stopTime=2500);
      if ok then
          savelog();
          createDirectory(destination + "1");
          copy("dsin.txt", destination + "1/dsin.txt", true);
          copy("dslog.txt", destination + "1/dslog.txt", true);
          copy("dsres.mat", destination + "1/dsres.mat", true);
          copy("dymosim", destination + "1/dymosim", true);
          copy("dymolalg.txt", destination + "1/dymolalg.txt", true);
      end if;

      exit();

  where ”...” depends on the local system.

  Example 2 (full-factorial design of experiments):

      >>> from modelicares import *

      >>> experiments = gen_experiments(
      ...     models=["Modelica.Electrical.Analog.Examples.ChuaCircuit"],
      ...     params={'L.L': [18, 20],
      ...             'C1.C': [8, 10],
      ...             'C2.C': [80, 100, 120]})
      >>> write_script(experiments, fname="examples/ChuaCircuit/run-sims2.mos")
      (['ChuaCircuit', 'ChuaCircuit', 'ChuaCircuit', 'ChuaCircuit', 'ChuaCircuit', 'ChuaCircuit', 'ChuaCircuit', 'ChuaCircuit', 'ChuaCircuit', 'ChuaCircuit', 'ChuaCircuit', 'ChuaCircuit'], '...examples/ChuaCircuit')

  In “examples/ChuaCircuit/run-sims2.mos”, there are commands to run and save results from 12 simulation experiments.

### Navigation

- index
- modules |
- next |
- previous |
- ModelicaRes v0.8.0 Documentation »