Based on FMI 3.0, this layered standard defines how variables (especially parameters) of an FMU can be structured and grouped in a more flexible way than with the "structured naming convention" of the FMI Standard. The first version of this layered standard is focused on the definition of sampled maps.


Copyright © 2024 The Modelica Association Project FMI.

This document is licensed under the Attribution-ShareAlike 4.0 International license. The code is released under the 2-Clause BSD License. The licenses text can be found in the LICENSE.txt file that accompanies this distribution.

1. Introduction

1.1. Motivation

For many use cases, the grouping of variables gives the user a better overview about the usage of variables. For certain groupings the importing tool might be able to provide a more user-friendly interface. FMUs might use maps/functions sampled on the vertices of a grid to calculate output values. The values at these sampling points and even the locations of the sampling points might get exposed as parameter variables of the FMU to allow calibrations. However, the FMI standard only defines n-dimensional array variable but doesn’t define any relation between these variables. This layered standard defines how to group variables to represent maps. E.g., CombiTable1D or CombiTable2D blocks of the Modelica standard library used within an FMU can be exposed with this approach.

This layered standard uses terminals of the FMI 3.0 standard to represent structures like maps by grouping variables in terminals. Terminals are used to group variables and already define means to connect its variables between FMUs. Such a connections could ensure that the same map values are used by different FMUs or allow one FMU to provide the map values to be used by other FMUs.

1.2. How to Read This Document

The standard document is in HTML allowing use of in-document links. By pressing "t", the table of contents can be displayed on the left side or hidden.

In key parts of this document, non-normative examples are used to help understand the standard.

Conventions used in this document:

  • Non-normative text is given in square brackets in italic font: [Especially examples are defined in this style.]

  • The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 (regardless of formatting and capitalization).

1.3. Rough Outline of the Approach

FMI 3.0 Terminals are used to define groups of variables, especially parameters.

A special kind of parameter group defines maps on rectilinear grids (with additional semantic meaning).

2. Layered Standard Manifest File

The manifest file signals to the importer that the FMU supports this layered standard and enables the interpretation of the TerminalsAndIcons.xml file in the intended way.

Table 1 shows the content of fmi-ls-manifest.xml.

Table 1. fmiLayeredStandardManifest attribute details.
Attribute Namespace Value Description

fmi-ls-name

http://fmi-standard.org/fmi-ls-manifest

org.fmi-standard.fmi-ls-struct

Name of the layered standard in reverse domain name notation.

fmi-ls-version

http://fmi-standard.org/fmi-ls-manifest

1.0.0

Version of the layered standard. This layered standard uses semantic versioning, as defined in [PW13].

fmi-ls-description

http://fmi-standard.org/fmi-ls-manifest

Layered standard for structuring of variables

String with a brief description of the layered standard that is suitable for display to users.

An example of a manifest file for this layered standard is shown below:

<?xml version="1.0" encoding="UTF-8"?>
<fmiLayeredStandardManifest
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:noNamespaceSchemaLocation="../../schema/fmi3LayeredStandardStructManifest.xsd"
	xmlns:fmi-ls="http://fmi-standard.org/fmi-ls-manifest"
	fmi-ls:fmi-ls-name="org.fmi-standard.fmi-ls-struct"
	fmi-ls:fmi-ls-version="1.0.0"
	fmi-ls:fmi-ls-description="Layered standard for structuring of variables"/>

3. Common concepts for the representation of maps

3.1. Definitions

n-D lookup table

In the context of this layered standard, an n-D lookup table is a sampled representation of a function of n input variables \((y_1, y_2, \dots, y_m) = F(x_1, x_2, x_3, \dots, x_n)\), sampled on points of the n-dimensional domain. Such an n-D lookup table could be also called a map from the n-dimensional domain to an m-dimensional codomain.

3.1.1. Definition of terminalKind attribute values

org.fmi-standard.fmi-ls-struct.map.rectilinearGrid

for maps defined on the vertices of a rectilinear grid.

org.fmi-standard.fmi-ls-struct.map.combitable1d

for 1-d maps defined on the vertices of a rectilinear grid, stored in a single matrix.

org.fmi-standard.fmi-ls-struct.map.combitable2d

for 2-d maps defined on the vertices of a rectilinear grid, in a single matrix.

org.fmi-standard.fmi-ls-struct.map.irregular

for maps defined by unstructured tuples of ("point cloud").

3.1.2. variableKind attribute values of terminal member variables:

We want to represent a map from a domain set to a codomain by providing points in the domain set and the values they are mapped to.

org.fmi-standard.fmi-ls-struct.map.domain

For each of the n dimensions of the domain set, a 1-dimensional array variable (typically a parameter or a constant) of coordinates (along this dimension) is provided.

org.fmi-standard.fmi-ls-struct.map.domainInput

Optionally, for each domain variable at most one variable (typically an input or a local variable) can be referenced that represents the current operating point (along this dimension). If present, this variable must be listed directly after the corresponding domain. The domain_input isn’t required to be a scalar, it could be variable with several dimensions. However the size of each domainInput must be the same for each domain: For nonscalar inputs \(v=[v_1,\dots,v_n], w=[w_1, \dots, w_n], \dots\) the function is evaluated element-wise and we get an output vector \(z=[f(v_1, w_1, \dots), \dots, f(v_n, w_n, \dots)\)].

org.fmi-standard.fmi-ls-struct.map.codomain

For each of the represented points in the domain set, the values to which they are mapped are represented. [There can be multiple terminal member variables with variablKind codomain to represent multiple maps in one terminal.]

org.fmi-standard.fmi-ls-struct.map.domainOutput

Optionally, for each domain variable at most one array variable (typically an input or a local variable) can be referenced that represents calculated output value of the map. If present, a domainOutput variable must be listed directly after the corresponding codomain variable.

Additional terminal member variables can be added to the terminal as related variables but if they do not fit into one of the above categories, they shall not have a variableKind' starting with `org.fmi-standard.fmi-ls-struct.

3.1.3. Definition of map specific matchingRule

The matching rule org.fmi-standard.fmi-ls-struct.map should be used for terminals that represent maps.

Requirements for matching:

  • The number of domain entries must be the same.

  • The terminal member names, its data types and the (effective) size and of all domains (variableKind=org.fmi-standard.fmi-ls-struct.map.domain) must match.

  • If all domains match, connect all these domains.

  • Connect all codomains (variableKind=org.fmi-standard.fmi-ls-struct.map.codomain) that match.

  • Don’t connect any other terminal member variables.

[This indicates that the variableKind of the member must be considered for the connection of the individual members of the terminal.]

3.2. Structure of the FMU archive

This layered standard uses and extends the "Terminals and Icons Concept" of FMI 3.0. All information is stored in the TerminalsAndIcons.xml file in the TerminalsAndIcons folder of an FMU.

4. Maps sampled on rectilinear grids

4.1. Definitions

n-d lookup table on rectilinear grid

In the context of this layered standard, an n-D lookup table is a sampled representation of a function of n input variables \(y=F(x_1, x_2, x_3, \dots, x_n)\) sampled on the vertices of a rectilinear grid.

[In [ASAM-MCD2], such a 1-d lookup table is called a CURVE, a 2-d lookup table is called MAP, and a 3-d lookup table is called CUBOID. 4-d and 5-d lookup tables are called CUBE_4 and *CUBE\_5*, respectively. Higher dimensional lookup tables are not defined in [ASAM-MCD2].]

terminalKind

A terminal with terminalKind="org.fmi-standard.fmi-ls-struct.map.rectilinearGrid" defines a map on the vertices of a rectilinear grid.

domain

For each of the n dimensions of the lookup table, a 1-dimensional array variable (typically a parameter or a constant) containing the sampling points (along this dimension) of the lookup table must be referenced with variableKind="org.fmi-standard.fmi-ls-struct.map.domain".

codomain

For each of the m dimensions of the codomain, the sampled function values (along this dimension of the codomain) are stored in this n-dimensional array variable and references with variableKind="org.fmi-standard.fmi-ls-struct.map.codomain".

The length of the i-th domain vector must be equal to length of the i-th codomain dimension.

[Note: This layered standard doesn’t define how maps have to be represented in a GUI. In particular, the standard doesn’t define if the first dimension is displayed as columns or rows. However, for the example lookup tables of this document, the sampling points of first dimension of the domain are shown as a column vector, and the values of second dimension are shown as a row vector.]

4.2. Example

v

y

10.0

25.0

30.0

x

2.0

11.0

12.0

13.0

3.0

21.0

22.0

23.0

The individual variables of the example 2-dimensional map on a rectilinear grid are given in the modelDescription.xml.

...
<Float64 name="x" valueReference="1" causality="parameter" start="2.0 3.0">
  <Dimension start="2"/>
</Float64>
<Float64 name="y" valueReference="2" causality="parameter" start="10.0 25.0 30.0">
  <Dimension start="3"/>
</Float64>
<Float64 name="v" valueReference="3" causality="parameter" start="11.0 12.0 13.0 21.0 22.0 23.0">
  <Dimension start="2"/>
  <Dimension start="3"/>
</Float64>
<Int64 name="InterpolationOrder" valueReference="9" causality="parameter" start="1" />
<Float64 name="in_x" valueReference="6" causality="input" start="2.0"/>
<Float64 name="in_y" valueReference="7" causality="local" />
<Float64 name="out_v" valueReference="8" causality="local" />
...

These variables are grouped in a terminal with the terminalKind org.fmi-standard.fmi-ls-struct.map.rectilinearGrid in the TerminalsAndIcons.xml file:

<?xml version="1.0" encoding="UTF-8"?>
<fmiTerminalsAndIcons fmiVersion="3.0">
  <Terminals>
    <Terminal name="map2d" terminalKind="org.fmi-standard.fmi-ls-struct.map.rectilinearGrid" matchingRule="org.fmi-standard.fmi-ls-struct.map">
      <TerminalMemberVariable variableName="x" memberName="x" variableKind="org.fmi-standard.fmi-ls-struct.map.domain" />
      <TerminalMemberVariable variableName="in_x" memberName="in_x" variableKind="org.fmi-standard.fmi-ls-struct.domainInput" />
      <TerminalMemberVariable variableName="y" memberName="y" variableKind="org.fmi-standard.fmi-ls-struct.map.domain" />
      <TerminalMemberVariable variableName="in_y" memberName="in_y" variableKind="org.fmi-standard.fmi-ls-struct.map.domainInput" />
      <TerminalMemberVariable variableName="v" memberName="v" variableKind="org.fmi-standard.fmi-ls-struct.map.codomain" />
      <TerminalMemberVariable variableName="out_v" memberName="out_v" variableKind="org.fmi-standard.fmi-ls-struct.map.codomainOutput" />
      <TerminalMemberVariable variableName="interpolationOrder" memberName="interpolationOrder" variableKind="com.example.related" />
    </Terminal>
  </Terminals>
</fmiTerminalsAndIcons>

4.3. Referencing Modelica library Combitables

The Modelica library defines lookup tables which are stored in a single matrix (https://doc.modelica.org/om/Modelica.Blocks.Tables.html)

4.3.1. Referencing Modelica library CombiTable1d

4.3.1.1. Example

x.0

v1

v2

v3

1.0

2.0

4.0

7.0

2.0

3.0

2.0

5.0

3.0

4.0

1.0

2.0

...
<Float64 name="combitable1d_example " valueReference="1" causality="parameter"
start="1.0 2.0 4.0 7.0
       2.0 3.0 2.0 5.0
       3.0 4.0 1.0 2.0">
  <Dimension start="3"/>
  <Dimension start="4"/>
</Float64>
<Int64 name="InterpolationOrder" valueReference="2" causality="parameter" start="1" />
<Float64 name="in_x" valueReference="3" causality="input" start="2.0"/>
<Float64 name="out_v1" valueReference="4" causality="local" />
<Float64 name="out_v3" valueReference="5" causality="local" />
...

The following example shows how to reference the Modelica library CombiTable1D matrix combitable1d_example in the TerminalsAndIcons.xml file:

<?xml version="1.0" encoding="UTF-8"?>
<fmiTerminalsAndIcons fmiVersion="3.0">
  <Terminals>
    <Terminal name="map2d" terminalKind="org.fmi-standard.fmi-ls-struct.map.combitable1d" matchingRule="org.fmi-standard.fmi-ls-struct.map">
      <TerminalMemberVariable variableName="combitable1d_example" memberName="x" variableKind="org.fmi-standard.fmi-ls-struct.map.domain" />
      <TerminalMemberVariable variableName="in_x" memberName="in_x" variableKind="org.fmi-standard.fmi-ls-struct.domainInput" />
      <TerminalMemberVariable variableName="combitable1d_example" memberName="v1" variableKind="org.fmi-standard.fmi-ls-struct.map.codomain" />
      <TerminalMemberVariable variableName="out_v1" memberName="out_v1" variableKind="org.fmi-standard.fmi-ls-struct.map.codomainOutput" />
      <TerminalMemberVariable variableName="combitable1d_example" memberName="v2" variableKind="org.fmi-standard.fmi-ls-struct.map.codomain" />
      <TerminalMemberVariable variableName="combitable1d_example" memberName="v3" variableKind="org.fmi-standard.fmi-ls-struct.map.codomain" />
      <TerminalMemberVariable variableName="out_v3" memberName="out_v3" variableKind="org.fmi-standard.fmi-ls-struct.map.codomainOutput" />
      <TerminalMemberVariable variableName="interpolationOrder" memberName="interpolationOrder" variableKind="com.example.related" />
    </Terminal>
  </Terminals>
</fmiTerminalsAndIcons>

4.3.2. Referencing Modelica library CombiTable2d

4.3.2.1. Example

1.0

2.0

3.0

1.0

1.0

3.0

5.0

2.0

2.0

4.0

6.0

...
<Float64 name="combitable2d_example" valueReference="1" causality="parameter"
start="  0 1.0 2.0 3.0
       1.0 1.0 3.0 5.0
       2.0 2.0 4.0 6.0">
  <Dimension start="3"/>
  <Dimension start="4"/>
</Float64>
<Int64 name="InterpolationOrder" valueReference="2" causality="parameter" start="1" />
<Float64 name="in_x" valueReference="3" causality="input" start="2.0"/>
<Float64 name="in_y" valueReference="4" causality="local" />
<Float64 name="out_v" valueReference="5" causality="local" />
...

The following example shows how to reference the Modelica library CombiTable2D matrix combitable2d_example in the TerminalsAndIcons.xml file:

<?xml version="1.0" encoding="UTF-8"?>
<fmiTerminalsAndIcons fmiVersion="3.0">
  <Terminals>
    <Terminal name="map2d" terminalKind="org.fmi-standard.fmi-ls-struct.map.combitable2d" matchingRule="org.fmi-standard.fmi-ls-struct.map">
      <TerminalMemberVariable variableName="combitable2d_example" memberName="x" variableKind="org.fmi-standard.fmi-ls-struct.map.domain" />
      <TerminalMemberVariable variableName="in_x" memberName="in_x" variableKind="org.fmi-standard.fmi-ls-struct.domainInput" />
      <TerminalMemberVariable variableName="combitable2d_example" memberName="y" variableKind="org.fmi-standard.fmi-ls-struct.map.domain" />
      <TerminalMemberVariable variableName="in_y" memberName="in_y" variableKind="org.fmi-standard.fmi-ls-struct.map.domainInput" />
      <TerminalMemberVariable variableName="combitable2d_example" memberName="v" variableKind="org.fmi-standard.fmi-ls-struct.map.codomain" />
      <TerminalMemberVariable variableName="out_v" memberName="out_v" variableKind="org.fmi-standard.fmi-ls-struct.map.codomainOutput" />
      <TerminalMemberVariable variableName="interpolationOrder" memberName="interpolationOrder" variableKind="com.example.related" />
    </Terminal>
  </Terminals>
</fmiTerminalsAndIcons>

5. Maps sampled on a irregular grid ("Point Cloud")

5.1. Definitions

Definition of domains and codomains as above.

For domains \(x=[x_1, x_2, \dots, x_n], y=[y_1, y_2, \dots, y_n], z=[z_1, z_2, \dots, z_n], \dots\) and codomains \(u=[u_1, u_2, \dots, u_n], v=[v_1, v_2, \dots, v_n], \dots\), the tuple \((x_i, y_i, z_i, \dots)\) gets mapped to the values \((u_i, v_i, ...)\).

All domains and codomains must have the same length.

[Note: A map on a 1 dimensional domain can be equivalently represented with a terminal of terminalKind="org.fmi-standard.fmi-ls-struct.map.irregular" or a terminal with terminalKind="org.fmi-standard.fmi-ls-struct.map.rectilinearGrid".]

ToDo add picture

5.2. Example

x

y

z

v1

v2

2.0

10.0

10.0

11.0

1.0

3.0

25.0

28.0

1.0

4.0

10.0

30.0

30.0

13.0

3.0

<?xml version="1.0" encoding="UTF-8"?>
<fmiTerminalsAndIcons fmiVersion="3.0">
  <Terminals>
    <Terminal name="points" terminalKind="org.fmi-standard.fmi-ls-struct.map.irregular" matchingRule="org.fmi-standard.fmi-ls-struct.map">
      <TerminalMemberVariable variableName="x" memberName="x" variableKind="org.fmi-standard.fmi-ls-struct.map.domain" />
      <TerminalMemberVariable variableName="in_x" memberName="in_x" variableKind="org.fmi-standard.fmi-ls-struct.domainInput" />
      <TerminalMemberVariable variableName="y" memberName="y" variableKind="org.fmi-standard.fmi-ls-struct.map.domain" />
      <TerminalMemberVariable variableName="z" memberName="z" variableKind="org.fmi-standard.fmi-ls-struct.map.domain" />
      <TerminalMemberVariable variableName="in_z" memberName="in_y" variableKind="org.fmi-standard.fmi-ls-struct.map.domainInput" />
      <TerminalMemberVariable variableName="v1" memberName="v1" variableKind="org.fmi-standard.fmi-ls-struct.map.codomain" />
      <TerminalMemberVariable variableName="v2" memberName="v2" variableKind="org.fmi-standard.fmi-ls-struct.map.codomain" />
      <TerminalMemberVariable variableName="out_v2" memberName="out_v2" variableKind="org.fmi-standard.fmi-ls-struct.map.codomainOutput" />
      <TerminalMemberVariable variableName="interpolationOrder" memberName="interpolationOrder" variableKind="com.example.related" />
    </Terminal>
  </Terminals>
</fmiTerminalsAndIcons>
...
<Float64 name="x" valueReference="1" causality="parameter" start="2.0 3.0 10.0">
  <Dimension start="3"/>
</Float64>
<Float64 name="y" valueReference="2" causality="parameter" start="10.0 25.0 30.0">
  <Dimension start="3"/>
</Float64>
<Float64 name="z" valueReference="3" causality="parameter" start="10.0 28.0 30.0">
  <Dimension start="3"/>
</Float64>
<Float64 name="v1" valueReference="4" causality="parameter" start="11.0 1.0 13.0">
  <Dimension start="3"/>
</Float64>
<Float64 name="v2" valueReference="5" causality="parameter" start="1.0 4.0 3.0">
  <Dimension start="3"/>
</Float64>
<Int64 name="InterpolationOrder" valueReference="6" causality="parameter" start="1" />
<Float64 name="in_x" valueReference="7" causality="input" start="2.0"/>
<Float64 name="in_z" valueReference="8" causality="local" />
<Float64 name="out_v2" valueReference="10" causality="local" />
...

6. Known Limitations of This Standard

General limitations:

  • todo

References