The Functional Mock-up Interface (FMI) is a free standard that defines a container and an interface to exchange dynamic models using a combination of XML files, binaries and C code, distributed as a ZIP file. It is supported by more than 150 tools and maintained as a Modelica Association Project. Releases and issues can be found on github.com/modelica.

Copyright © 2008-2011 MODELISAR Consortium and 2012-2021 The Modelica Association Project FMI.

Attention is drawn to the possibility that some of the elements of this document may be the subject of patent rights. Modelica Association shall not be held responsible for identifying such patent rights. All contributors to this specification have signed the Corporate Contributor License Agreement of the FMI Project or the Contributor License Agreement of the Modelica Association.

1. Introduction

1.1. What is new in FMI 3.0

The FMI Design Community has improved the FMI standard to react to new requirements from the system simulation community.

Especially the ability to package control code into FMUs required some workarounds in FMI 2.0. With FMI 3.0, virtual electronic control units (vECUs) can be exported as FMU in a more natural way. Concrete features to support vECU export are:

• introduction of terminals to group variables semantically to ease connecting compatible signals,

• introduction of icons to define a graphical representation of the FMU and its terminals,

• introduction of Clocks to more exactly control timing of events and evaluation of model partitions across FMUs,

• introduction of more integer types and a 32-bit float type (see Section 2.4) to communicate native controller types to the outside,

• introduction of a binary type to support non-numeric data handling, such as complex sensor data interfaces,

• extension of variables to arrays for more efficient and natural handling of non-scalar variables,

• introduction of structural parameters that allow description and changing of array sizes, even during runtime to support advanced online calibration of control code, and

• addition of the new interface type "Scheduled Execution" (see Section 5) that allows activation of individual model partitions (or tasks) by an external scheduler, e.g. on real-time platforms.

A second need of the simulation community was address by introducing the more advanced co-simulation interface type FMI for Co-Simulation. New features, like

allow implementation of more robust and efficient co-simulation algorithms to handle the growing system simulations the community is facing.

Parallel to the new standard features, the FMI Design Community has worked on improving the standard quality by:

• modernizing the development methodology (e.g. moving to github) and a text-based source format,

• publishing the FMI Standard now primarily as html to support easier navigation within the document and viewing on a wider range of devices,

• supplying a large set of continuously validated Reference FMUs, and

• integrating within the FMI Standard only validated C-code, XML and XSD snippets to reduce redundancy and ensure correctness.

While a number of desirable features had to be postponed, the resulting FMI 3.0 is certainly a significant step forward towards meeting the most important requirements of the system simulation community for the years to come.

The asynchronous mode for FMUs known from FMI 2.0 has been removed since this mode was not supported by tools and it can be suitably replaced by Co-Simulation implementations that control the asynchronous computation of FMUs via separate tasks/threads created for each FMU.

1.2. Overview

The Functional Mock-up Interface (FMI) defines a container and an aplication programming interface (API) to exchange dynamic models using a combination of XML files, binaries and C code, distributed as a ZIP archive, the Functional Mock-up Unit (FMU). The API is used by a simulation environment, the importer, to create one or more instances of an FMU and to simulate them, typically together with other models. The FMI defines three interface types:

This document does not describe how to generate an FMU from a modeling environment.

The interface types have large parts in common, defined in Common Concepts. In particular:

• FMI Application Programming Interface (C) — Section 2.2
All required equations or tool coupling computations are evaluated by calling standardized C functions. C is used because it is the most portable programming language today and is the only programming language that can be utilized in all embedded control systems.

• FMI Description Schema (XML) — Section 2.4
The schema defines the structure and content of an XML file generated by a modeling environment. This XML file contains the definition of all variables of the FMU in a standardized way. It is then possible to run the C code in an embedded system without the overhead of the variable definition (the alternative would be to store this information in the C code and access it via function calls, but this is neither practical for embedded systems nor for large models). Furthermore, the variable definition is a complex data structure and tools should be free to determine how to represent this data structure in their programs. The selected approach allows a tool to store and access the variable definitions (without any memory or efficiency overhead of standardized access functions) in the programming language of the simulation environment.

• FMU Distribution (ZIP) — Section 2.5
An FMU is distributed in one ZIP file. The ZIP file contains the FMI Description file (XML), the binaries and libraries required to execute the FMI functions (.dll or .so files), the sources of the FMI functions (optional), and other data used by the FMU (e.g., tables or maps). It is possible for an FMU to hide the source code to secure the contained know-how or to allow a fully automatic import of the FMU in another simulation environment.

1.2.1. FMI for Model Exchange (ME)

The Model Exchange interface exposes an ODE to an external solver of an importing tool. Models are described by differential, algebraic and discrete equations with time-, state- and step-events. That integration algorithm of the importing tool, usually a DAE solver, is responsible for advancing time, setting states, handling events, etc. (See Section 3.)

Figure 1. Schematic view of data flow between user, the solver of the importer and the FMU for Model Exchange

1.2.2. FMI for Co-Simulation (CS)

The Co-Simulation interface is designed both for the coupling of simulation tools, and the coupling of subsystem models, exported by their simulators together with its solvers as runnable code. (See Section 4.)

Figure 2. Schematic view of data flow between user, the co-simulation algorithm of the importer and the FMU for Co-Simulation

1.2.3. FMI for Scheduled Execution (SE)

The Scheduled Execution interface exposes individual model partitions (e.g. tasks of a control algorithm), to be called by a scheduler that acts as external scheduler. The scheduler is responsible for advancing the overall simulation time, triggering of time-based and triggered Clocks for all exposed model partitions of a set of FMUs, and handling events (e.g. clock ticks) signaled by the FMUs.

In many ways, the Scheduled Execution interface is the equivalent of the Model Exchange interface: the first externalizes a scheduling algorithm usually found in a controller algorithm and the second interface externalizes the ODE solver. (See Section 5.)

Figure 3. Schematic view of data flow between user, the scheduler of the importer and tasks of the FMU for Scheduled Execution

1.2.4. Feature Overview of the Interface Types

Table 1 gives a non-normative overview of the features of the different interface types.

Table 1. Non-normative overview of features per interface type.
Feature Model Exchange Co-Simulation Scheduled Execution

Call `fmi3DoStep` and monitor argument `lastSuccessfulTime`

Solver Included

Not applicable

Scheduler included

Not applicable

Possibly

Event Indicators

Early Return

Includes similar or better mechanism

Intermediate Update

Includes similar or better mechanism

Signal output Clock ticks:
Inputs/Outputs:

Clocks

Direct Feedthrough

At events:
Else:

1.3. Properties and Guiding Ideas

In this section, properties are listed and some principles are defined that guided the low-level design of the FMI. This shall increase self consistency of the FMI functions. The listed issues are sorted, starting from high-level properties to low-level implementation issues.

Expressivity

The FMI provides the necessary features to package models of different domains, such as multibody and virtual ECUs, into an FMU.

Stability

The FMI is expected to be supported by many simulation tools worldwide. Implementing such support is a major investment for tool vendors. Stability and backwards compatibility of the FMI has therefore high priority. To support this, the FMI defines "capability flags" that will be used by future versions of the FMI to extend and improve the FMI in a backwards compatible way, whenever feasible.

Implementation

FMUs can be written manually or can be generated automatically from a modeling environment. Existing manually coded models can be transformed manually to a model according to the FMI standard.

Processor independence

It is possible to distribute an FMU without knowing the target processor. This allows an FMU to run on a PC, a Hardware-in-the-Loop simulation platform or as part of the controller software of an ECU. Keeping the FMU independent of the target processor increases the usability of the FMU. To be processor independent, the FMU must include its C (or C++) sources.

Simulator independence

It is possible to compile, link and distribute an FMU without knowing the environment in which the FMU will be loaded.

Reason: The standard would be much less attractive otherwise, unnecessarily restricting the later use of an FMU at compile time and forcing users to maintain simulator specific variants of an FMU. To be simulator independent, the FMU must export its implementation in self-contained binary form. This requires that the target operating system and processor be known. Once exported with binaries, the FMU can be executed by any simulator running on the target platform (provided the necessary licenses are available, if required from the model or from the used runtime libraries).

Semantic versioning

The FMI standard uses semantic version numbers, as defined in [PW13], where the standard version consists of a triple of version numbers, consisting of major version, minor version, and patch version numbers, see Section 2.6.

Version independence

FMUs with a specific major and minor version number are valid FMUs w.r.t. the same major version and any minor version because features of minor versions are optional and ignorable.

Reason: A tool can always export the greatest minor version it supports. Such an FMU can be imported into all tools supporting this major version and arbitrary minor versions. This achieves maximal longevity of FMUs protecting its value for users.

Communication between an FMU and an importer through the FMI does not introduce significant runtime overhead. This can be achieved by enabling caching of the FMU outputs and by exchanging multiple quantities with one call.

Small footprint

A compiled FMU binary requires little memory.

Reason: An FMU may run on an ECU (Electronic Control Unit, for example, a microprocessor), and ECUs have strong memory limitations. This is achieved by storing variable attributes (`name`, `unit`, etc.) and all other static information not needed for model evaluation in a separate text file (= Model Description File) that is not needed on the microprocessor where the executable might run.

Hide data structure

The FMI for Model Exchange does not prescribe a data structure (e.g., a C struct) to represent a model.

Reason: the FMI standard shall not unnecessarily restrict or prescribe a certain implementation of FMUs or simulators (whichever contains the model data) to ease implementation by different tool vendors.

Support many and nested FMUs

A simulator may run many FMUs in a single simulation run and/or multiple instances of one FMU. The inputs and outputs of these FMUs can be connected with direct feedthrough. Moreover, an FMU may contain nested FMUs.

Numerical Robustness

The FMI standard allows problems which are numerically critical (for example, `time` and `state events`, multiple sample rates, stiff problems) to be treated in a robust way.

Hide cache

A typical FMU will cache computed results for later reuse. To simplify usage and to reduce error possibilities by a simulator, the caching mechanism is hidden from the usage of the FMU.

Reason: First, the FMI should not force an FMU to implement a certain caching policy. Second, this helps to keep the FMI simple. To help implement this cache, the FMI provides explicit methods (called by the FMU environment) for setting properties that invalidate cached data. An FMU that chooses to implement a cache may maintain a set of "dirty" flags, hidden from the simulator. A get method, for example to a state, will then either trigger a computation, or return cached data, depending on the value of these flags.

Support numerical solvers

A typical importer will use numerical solvers. These solvers require vectors for `states`, `derivatives` and zero-crossing functions. The FMU directly fills the values of such vectors provided by the solvers.

Reason: minimize execution time. The exposure of these vectors conflicts somewhat with the "hide data structure" requirement, but the efficiency gain justifies this.

Explicit signature

The intended operations, arguments, and return types are made explicit in the signature. For example, an operator (such as `compute_derivatives`) is not passed as an int argument but a special function is called for this. The `const` prefix is used for any pointer that should not be changed, including `const char*` instead of `char*`.

Reason: the correct use of the FMI can be checked at compile time and allows calling of the C code in a C++ environment (which is much stricter on `const` than C is). This will help to develop FMUs that use the FMI in the intended way.

Few functions

The FMI consists of a few, "orthogonal" functions, avoiding redundant functions that could be defined in terms of others.

Reason: This leads to a compact, easy-to-use, and hence attractive API with a compact documentation.

Error handling

All FMI methods use a common set of methods to communicate errors.

Allocator must free

All memory (and other resources) allocated by the FMU are freed (released) by the FMU. Likewise, resources allocated by the importer are released by the importer.

Reason: this helps to prevent memory leaks and runtime errors due to incompatible runtime environments for different components.

Immutable strings

All strings passed as arguments or returned are read-only and must not be modified by the receiver.

Reason: This eases the reuse of strings.

Named list elements

All lists defined in the `fmi3ModelDescription.xsd` XML schema file have a string attribute `name` to a list element. This attribute must be unique with respect to all other `name` attributes of the same list.

Use C

The FMI API is written in C, not C++, to avoid problems with compiler and linker dependent behavior, and to enable the use of FMUs on embedded systems.

This version of the FMI standard does not have the following desirable properties. They might be added in a future version.

• The FMI for Model Exchange is for ordinary differential equations (ODEs) in state space form. It is not for a general differential-algebraic equation system. However, algebraic equation systems inside the FMU are supported (for example, the FMU can report to the environment to re-run the current step with a smaller step size since a solution could not be found for an algebraic equation system).

• Special features that might be useful for multibody system programs are not included.

• The interface is for simulation and for embedded systems. Properties that might be additionally needed for trajectory optimization, for example, derivatives of the model with respect to parameters during continuous integration are not included.

• No explicit definition of the variable hierarchy in the XML file.

1.4. How to Read This Document

The core of this document is the description of the state machines and their states for each of the three interface types, each interface type in its own section. Each state description starts with a brief state’s purpose, then the mathematical model in a table linking formulas with C-API functions, and finally descriptions of all allowed functions for this particular state.

To keep the descriptions brief and redundancy low, common concepts are described in the central section, including common parts of the state machines, XML schema and ZIP-file content description.

The standard document is in HTML allowing heavy use of in-document links: all state names, function names, many function arguments, XML elements and attributes are links to definitions or descriptions. By pressing "t", the table of contents can be displayed on the left side or hidden.

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, NOT RECOMMENDED, MAY, and OPTIONAL in this document are to be interpreted as described in RFC 2119.

• `{VariableType}` is used as a placeholder for all variable type names without the `fmi3` prefix (e.g. `fmi3Get``VariableType` stands for `fmi3GetUInt8`, `fmi3GetBoolean`, `fmi3GetFloat64`, `fmi3GetClock`, `fmi3GetBinary`, etc.).

2. Common Concepts

The FMI defines the following interface types: FMI for Model Exchange, Co-Simulation, and Scheduled Execution. The concepts defined in this chapter are common to at least two of these interface types. The definitions that are specific to the particular cases are defined in Section 3, Section 4, and Section 5.

The term FMU (Functional Mock-up Unit) denotes an implementation (or any mix) of interface types.

In the following, we assume that the reader is familiar with the basics of the C programming language and the basics of numerical simulation. Please refer to Appendix A for the most commonly used terms.

2.1. Mathematical Definitions

This section introduces the mathematical notation used throughout this document. It is used to describe

• ordinary differential equations in state-space representations with discontinuities (events),

• algebraic equation systems,

• discrete-time equations (sampled-data systems).

FMU and importer use variables to exchange information. The properties and semantics of variables are described in the `modelDescription.xml`. Access is possible via appropriate API functions.

The `independent` variable $\mathbf{t} \in \mathbb{T}$ [typically: time] is a tuple $\mathbf{t} = (\mathbf{t}_R,\mathbf{t}_I)$, where $\mathbf{t}_R \in \mathbb{R},\ \mathbf{t}_{I} \in \mathbb{N} = \{0, 1, 2, \ldots\}$. The real part $\mathbf{t}_R$ of this tuple is the `independent` variable of the FMU for describing the continuous-time behavior of the model between events. During continuous-time integration $\mathbf{t}_I = 0$. The integer part $\mathbf{t}_I$ of this tuple is a counter to enumerate (and therefore distinguish) the events at the same continuous-time instant $\mathbf{t}_R$. This time definition is also called "super-dense time" in literature, see, for example, [LZ07]. An ordering is defined on $\mathbb{\text{T}}$ that leads to the notation in Table 2.

 Operation Mathematical meaning Description $\mathbf{t}_1 < \mathbf{t}_2$ $(\mathbf{t}_{\mathit{R1}},\mathbf{t}_{\mathit{I1}}) < (\mathbf{t}_{\mathit{R2}}, \mathbf{t}_{\mathit{I2}})\ \Leftrightarrow \ \mathbf{t}_{\mathit{R1}} < \mathbf{t}_{\mathit{R2}}\ \textbf{or} \ \mathbf{t}_{\mathit{R1}}= \mathbf{t}_{\mathit{R2}} \ \textbf{and} \ \mathbf{t}_{\mathit{I1}} < \mathbf{t}_{\mathit{I2}}$ $\mathbf{t}_1$ is before $\mathbf{t}_2$ $\mathbf{t}_1 = \mathbf{t}_2$ $(\mathbf{t}_{\mathit{R1}},\mathbf{t}_{\mathit{I1}}) = (\mathbf{t}_{\mathit{R2}},\mathbf{t}_{\mathit{I2}}) \ \Leftrightarrow \mathbf{t}_{\mathit{R1}}= \mathbf{t}_{\mathit{R2}}\ \textbf{and} \ \mathbf{t}_{\mathit{I1}} = \mathbf{t}_{\mathit{I2}}$ $\mathbf{t}_1$ is identical to $\mathbf{t}_2$ $\mathbf{t}^{+}$ ${(\mathbf{t}_R,\mathbf{t}_I)}^{+} \Leftrightarrow (\lim_{\mathit{\epsilon \rightarrow 0}}{\left(\mathbf{t}_R + \varepsilon \right),\mathbf{t}_{\mathit{Imax}})}$ right limit at $\mathbf{t}$. $\mathbf{t}_{\mathit{Imax}}$ is the largest occurring integer index of super-dense time $^-\mathbf{t}$ $^{-}{(\mathbf{t}_R,\mathbf{t}_I)} \Leftrightarrow (\lim_{\mathit{\epsilon \rightarrow 0}}{\left( \mathbf{t}_R - \varepsilon \right),0)}$ left limit at $\mathbf{t}$ $v^+(\mathbf{t})$ $v(\mathbf{t}^+)$ value at the right limit of $\mathbf{t}$ $^{-}v(\mathbf{t})$ $v(^-\mathbf{t})$ value at the left limit of $\mathbf{t}$ $^{\bullet}v(\mathbf{t})$ $\begin{cases} ^{\bullet}v(t) \\ ^{\bullet}v(\left( \mathbf{t}_R,\mathbf{t}_I \right)) \end{cases} \Leftrightarrow \begin{cases} v(^-t) & \text{ during } v(\left( \mathbf{t}_R, 0 \right)) \text{, v not clocked } \\ v(\left( \mathbf{t}_R,\mathbf{t}_I - 1 \right)) & \text{ for } v(\left( \mathbf{t}_R,\mathbf{t}_I \right)) \text{ with } I > 0 \text{, v not clocked } \\ v \text{ at previous tick of C } & \text{ if } v \text{ for clocked variable } v \text{ of clock C} \end{cases}$ previous value

[Assume that an FMU has an event at $\mathbf{t}_R=2.1s$ and here a variable changes discontinuously. If no event iteration occurs, the time instant when the event occurs is defined as (2.1, 0), and the time instant when the integration is restarted is defined as (2.1, 1).]

The hybrid differential equations exposed by FMI for Model Exchange or wrapped by FMI for Co-Simulation are described as piecewise continuous-time systems. Discontinuities can occur at time instants $\mathbf{t}_0, \mathbf{t}_1, \ldots, \mathbf{t}_n$ where $\mathbf{t}_i < \mathbf{t}_{i+1}$. These time instants are called `events`. Events can be known beforehand (= `time events`), or are defined implicitly (= `state` and `step events`), see below. Between events, variables are either `continuous` or do not change their value. A variable is called discrete-time, if it changes its value only at an event instant. Otherwise the variable is called continuous-time. Only floating point variables can be continuous-time. The following variable subscripts are used to describe the timing behavior of the corresponding variable (for example, $\mathbf{v}_d$ is a discrete-time variable):

 Subscript Description `c` A continuous-time variable is a floating-point variable representing a continuous function of time inside each interval $\mathbf{t}_i^+ < \ ^-\mathbf{t}_{i+1}$. `d` A discrete-time variable changes its value only at an event instant $\mathbf{t} = (\mathbf{t}_i,n)$. Such a variable can change multiple times at the same continuous-time instant, but only at subsequent super-dense time instants $n \in \mathbb{N} = \{0, 1, 2, \ldots\}$. `k` A clocked variable is a discrete-time variable associated with a Clock. Clock variables synchronize events with the importer and across FMUs, they carry the information that a specific event happens. `c`+`d` A set of continuous-time and discrete-time variables. `u` Intermediate variables: a set of variables accessible in Intermediate Update Mode. In Co-simulation, these variables are continuous-time variables. `start` A variable at the start time of the simulation as defined by the argument `startTime` of `fmi3EnterInitializationMode`. `attribute=value` A set of variables which have an XML attribute-value combination as defined. [Example: $\mathbf{v}_{\mathit{initial=exact}}$ are variables defined with attribute `initial` = `exact` (see Section 2.4.7).]

At every event instant $\mathbf{t}_i$, continuous-time variables might change discontinuously (see Figure 4).

Figure 4. Piecewise-continuous variables of an FMU: continuous-time ($\mathbf{v}_c$), discrete-time ($\mathbf{v}_d$) and clocked ($\mathbf{v}_k$).

The mathematical description of an FMU uses the following variables:

 Variable Description $\mathbf{t}$ `independent` variable [typically: time] $\in \mathbb{T}$. This variable is defined with `causality` = `independent`. All other variables are functions of this independent variable. For Co-Simulation and Scheduled Execution: The i-th communication point is denoted as $\mathbf{t}_i$. The communication step size is denoted as $\mathbf{h}_i = \mathbf{t}_{i+1} - \mathbf{t}_i$. $\mathbf{v}$ A vector of all exposed variables (all variables defined in element ``, see Section 2.4.7). A subset of the variables is selected via a subscript. $\mathbf{p}$ Parameters. The symbol without a subscript references `parameters` (variables with `causality` = `parameter`). A subset of the variables is selected via a subscript. $\mathbf{u}$ Input variables. The values of these variables are defined outside of the model. Variables of this type are defined with attribute `causality` = `input`. $\mathbf{y}$ $\mathbf{y^{(j)}}$ Output variables. The values of these variables are computed in the FMU and they are designed to be used outside the FMU. Variables of this type are defined with attribute `causality` = `output`. For CS and SE: Also j-th derivatives $\mathbf{y}^{(j)}(\mathbf{t}_{i+1})$ can be provided if supported by the FMU. $\mathbf{w}$ Local variables of the FMU that must not be used for FMU connections. Variables of this type are defined with attribute `causality` = `local`. $\mathbf{z}$ A vector of floating point continuous-time variables representing the event indicators used to define `state events`. $\mathbf{x}_c$ $\mathbf{\dot{x}}_c$ A vector of floating point continuous-time variables representing the continuous-time `states`. A vector of floating point continuous-time variables representing the first derivatives of the continuous-time `states`. $\mathbf{x}_d$ $^{\bullet}\mathbf{x}_d$ $\mathbf{x}_d$ is a vector of (internal) discrete-time variables (of any type) representing the discrete-time states. ${}^{\bullet}\mathbf{x}_d$ is the value of $\mathbf{x}_d$ at the previous super-dense time instant. $\mathbf{T}_{\mathit{next}}$ At an event instant, an FMU can define the next time instant $\mathbf{T}_{\mathit{next}}$, at which the next time event occurs (see also the definition of events). Every event removes automatically a previous definition of $\mathbf{T}_{\mathit{next}}$, and it must be explicitly defined again, even if a previously defined $\mathbf{T}_{\mathit{next}}$ was not yet reached (see `fmi3UpdateDiscreteStates`). $\mathbf{r}$ A vector of Boolean variables representing relations: $\mathbf{r}_j := \mathbf{z}_j > 0$. When entering Continuous-Time Mode all relations reported via the event indicators $\mathbf{z}$ are fixed and during this mode these relations are replaced by $^{\bullet}\mathbf{r}$. Only during Initialization Mode or Event Mode the domains $\mathbf{z}_j > 0$ can change. [For more details, see Remark 3 below.] $\mathbf{b}$ Hidden data of the FMU. [For example, delay buffers in Model Exchange FMUs that are used in Continuous-Time Mode].

2.2. General Mechanisms

This section contains the common interface definitions that allow a C program to invoke the FMU functions.

Note that the following general properties hold for an FMU:

• FMI functions of one instance do not need to be thread-safe.
[For example, if the functions of one instance of an FMU are accessed from more than one thread; the multi-threaded simulation environment that uses the FMU must guarantee that there are no race conditions while invoking the FMI functions. The FMU itself does not implement any services to support this.]

• FMI callback functions are not allowed to call back into the FMU (fmi3CallbackLogMessage, fmi3CallbackLockPreemption, fmi3CallbackUnlockPreemption), except fmi3CallbackIntermediateUpdate which leads to the well-defined state Intermediate Update Mode defining which function calls back into the FMU are allowed.

• FMI functions must not change global settings which affect other processes/threads. An FMI function may change settings of the thread in which it is called (such as floating point control registers), provided these changes are restored before leaving the function or before a callback function is called.
[This property ensures that functions of different FMU instances can be called safely in any order. Additionally, they can be called in parallel provided the functions are called in different processes. If an FMI function changes for example the floating point control word of the CPU, it must restore the previous value before return of the function. For x86 CPUs, the floating point control word is set using the `fldcw` instruction. This can be used to switch on additional exceptions such as floating point division by zero. An FMU might temporarily change the floating point control word and get notified on floating point exceptions internally, but has to restore the flag and clear the floating point status word before return of the respective FMI function.]

• In general, FMI function arguments are not allowed to be `NULL`, unless explicitly allowed by the standard document where `NULL` will be assigned a specific semantic.
[For an example of `NULL` being explicitly allowed see `resourcePath`. Defensive implementations should still guard against `NULL` pointers.]

• The FMI Standard does not provide a runtime platform or portability layer. Access to operating system resources and services, such as memory and file system, must be implemented with special care because the availability of such resources and services is not guaranteed. If some resource is required by the FMU but is not available, the FMU must log what resource failed and return with error.

2.2.1. Header Files and Naming of Functions

Three header files are provided that define the interface of an FMU. In all header files the convention is used that all C function and type definitions start with the prefix `fmi3`:

`fmi3PlatformTypes.h`

contains the type definitions of the input and output arguments of the functions as well as some C preprocessor macro definitions for constants. This header file must be used both by the FMU and by the importer.
[Example of a definition in this header file:

``typedef double fmi3Float64;``

]

`fmi3FunctionTypes.h`

contains `typedef` definitions of all function prototypes of an FMU as well as enumerations for constants. This header file includes `fmi3PlatformTypes.h`. When dynamically loading an FMU, these definitions can be used to type-cast the function pointers to the respective function definition. For simplicity, the function type for each function is composed of the function name itself with the suffix `TYPE`.
[Example of a definition in this header file:

``typedef fmi3Status fmi3SetTimeTYPE(fmi3Instance, fmi3Float64);``

]

`fmi3Functions.h`

contains the function prototypes of an FMU that can be accessed in simulation environments.

This header file includes `fmi3PlatformTypes.h` and `fmi3FunctionTypes.h`. The header file version number for which the model was compiled, can be inquired by the importer with `fmi3GetVersion` (see Section 2.2.4).

[Example of a definition in this header file:

``FMI3_Export fmi3SetTimeTYPE fmi3SetTime;``

For Microsoft and Cygwin compilers `FMI3_Export` is defined as `__declspec(dllexport)` and for Gnu-Compilers as `__attribute__ ( ( visibility("default") ) )` in order to export the name for dynamic loading. Otherwise it is an empty definition.]

The goal is that both source code and binary representations of FMUs are supported and that several FMUs might be present at the same time in an executable (for example, FMU A may use an FMU B). In order for this to be possible, the names of the functions in different FMUs must be different, or function pointers must be used. To support the source code representation of FMUs, macros are provided in `fmi3Functions.h` to build the actual function names by using a function prefix that depends on how the FMU is shipped.

[These macros can be defined differently in a target specific variant of `fmi3Functions.h` to adjust them to the requirements of the supported compilers and platforms of the importing tool.]

An FMU C-file must include at the beginning a `define` of `FMI3_FUNCTION_PREFIX` with the same value as the value of the `modelIdentifier` attribute defined in `<fmiModelDescription><ModelExchange>`, `<fmiModelDescription><CoSimulation>` or `<fmiModelDescription><ScheduledExecution>` together with `_` at the end (see Section 3.4, Section 4.4, Section 5.4).

This `define` must be directly followed with an `#include "fmi3Functions.h"` statement.

Typically, FMU functions are used as follows:

``````// FMU is shipped with C source code, or with static link library
#define FMI3_FUNCTION_PREFIX MyModel_
#include "fmi3Functions.h"
< usage of the FMU functions e.g. MyModel_fmi3SetTime >

// FMU is shipped with DLL/SharedObject
#include "fmi3FunctionTypes.h"
fmi3SetTimeTYPE *myname_setTime = < load symbol "fmi3SetTime" from DLL/SharedObject >;
< usage of the FMU function pointers, e.g. myname_setTime >``````

A function that is defined as `fmi3GetFloat64` is changed by the macros to a function name as follows:

• If the FMU is shipped with C source code or with static link library:
The constructed function name is `MyModel_fmi3GetFloat64`. In other words the function name is prefixed with the model name and an `_`. A simulation environment can therefore construct the relevant function names by generating code for the actual function call. In case of a static link library, the name of the library is `MyModel.lib` on Windows and `libMyModel.a` on Linux; in other words the `modelIdentifier` attribute is used to create the library name.

• If the FMU is shipped with DLL/SharedObject:
The constructed function name is `fmi3GetFloat64`, in other words, it is not changed. [This can be realized in the case of a source code FMU with a target-specific version of `fmi3Functions.h` that does not use FMI3_FUNCTION_PREFIX to construct the function names.] A simulation environment will then dynamically load this library and will explicitly import the function symbols by providing the FMI function names as strings. The name of the library is `MyModel.dll` on Windows or `MyModel.so` on Linux; in other words the `modelIdentifier` attribute is used as library name.

[An FMU can be optionally shipped so that it basically contains only the communication to another simulation tool (`needsExecutionTool = true`, see Section 4). This is particularly common for co-simulation tasks. In this tool coupling case one DLL/Shared Object can be used for all models due to no function prefixing.]

Since `modelIdentifier` is used as prefix of a C-function name it must fulfill the restrictions on C-function names (only letters, digits and/or underscores are allowed). [For example, if `modelName = "A.B.C"`, then `modelIdentifier` might be "A_B_C".] Since `modelIdentifier` is also used as name in a file system, it must also fulfill the restrictions of the targeted operating system. Basically, this means that it should be short. These restrictions apply to all interface types and for binary and source-code FMUs. [For example, the Windows API only supports full path-names of a file up to 260 characters (see: http://msdn.microsoft.com/en-us/library/aa365247%28VS.85%29.aspx).]

In the code examples the following structure is used that holds the pointers to the FMU’s functions and instance.

``````typedef struct {

fmi3Instance instance;
fmi3GetFloat64TYPE* fmi3GetFloat64;
// ...

} FMU;``````

2.2.2. Platform Dependent Definitions

To simplify porting, no C types are used in the function interfaces, but the alias types are defined in this section. All definitions in this section are provided in the header file `fmi3PlatformTypes.h`. It is required to use this definition for all binary FMUs.

``typedef           void* fmi3Instance;             /* Pointer to the FMU instance */``

This is a pointer to an FMU specific data structure that contains the information needed to process the model equations or to process the co-simulation of the model/subsystem represented by the FMU.

``typedef           void* fmi3InstanceEnvironment;  /* Pointer to the FMU environment */``

This is a pointer to a data structure in the importer. Using this pointer, data can be transferred between the importer and callback functions it provides (see FMU State Setable).

``typedef           void* fmi3FMUState;             /* Pointer to the internal FMU state */``

This is a pointer to a data structure in the FMU that saves the internal FMU state of the actual or a previously saved time instant. This allows to restart a simulation from a saved FMU state (see Section 2.2.6.4).

``typedef        uint32_t fmi3ValueReference;       /* Handle to the value of a variable */``

This is a handle to a (base type) variable value of the model. A `fmi3ValueReference` uniquely identifies the value and other properties of a variable, except for the variable name and the display unit that may differ for `alias` variable definitions.

Structured entities, such as records, must be flattened into a set of values (scalars or arrays) of type `fmi3Float64`, `fmi3Int32`, etc. Arrays may be flattened into a set of scalars or represented directly as array values. An `fmi3ValueReference` references one such value (scalar or array). The coding of `fmi3ValueReference` is a "secret" of the environment that generated the FMU. The interface to the equations only provides access to variable values via `fmi3ValueReference`. Extracting concrete information about a variable can be done by reading the `modelDescription.xml` in which the `fmi3ValueReference` are defined. If a function in the following sections is called with a wrong `fmi3ValueReference` value [for example, setting a constant with a call to `fmi3SetFloat64`], then the function must return with an error ( `fmi3Status == fmi3Error`, see Section 2.2.3).

Listing Base types shows the base types used in the interfaces of the C functions.

Base types
``````typedef           float fmi3Float32;  /* Single precision floating point (32-bit) */
typedef          double fmi3Float64;  /* Double precision floating point (64-bit) */
typedef          int8_t fmi3Int8;     /* 8-bit signed integer */
typedef         uint8_t fmi3UInt8;    /* 8-bit unsigned integer */
typedef         int16_t fmi3Int16;    /* 16-bit signed integer */
typedef        uint16_t fmi3UInt16;   /* 16-bit unsigned integer */
typedef         int32_t fmi3Int32;    /* 32-bit signed integer */
typedef        uint32_t fmi3UInt32;   /* 32-bit unsigned integer */
typedef         int64_t fmi3Int64;    /* 64-bit signed integer */
typedef        uint64_t fmi3UInt64;   /* 64-bit unsigned integer */
typedef            bool fmi3Boolean;  /* Data type to be used with fmi3True and fmi3False */
typedef            char fmi3Char;     /* Data type for one character */
typedef const fmi3Char* fmi3String;   /* Data type for character strings
('\0' terminated, UTF-8 encoded) */
typedef         uint8_t fmi3Byte;     /* Smallest addressable unit of the machine
(typically one byte) */
typedef const fmi3Byte* fmi3Binary;   /* Data type for binary data
(out-of-band length terminated) */
typedef            bool fmi3Clock;    /* Data type to be used with fmi3ClockActive and
fmi3ClockInactive */

/* Values for fmi3Boolean */
#define fmi3True  true
#define fmi3False false

/* Values for fmi3Clock */
#define fmi3ClockActive   true
#define fmi3ClockInactive false``````

2.2.3. Status Returned by Functions

This section defines the `status` flag (an enumeration of type `fmi3Status` defined in file `fmi3FunctionTypes.h`) that is returned by functions to indicate the success of the function call:

``````typedef enum {
fmi3OK,
fmi3Warning,
fmi3Error,
fmi3Fatal,
} fmi3Status;``````

The status has the following meaning:

`fmi3OK`

The call was successful. The output argument values are defined.

`fmi3Warning`

A non-critical problem was detected, but the computation can continue. The output argument values are defined. Function `logMessage` should be called by the FMU with further information before returning this status, respecting the current logging settings.
[In certain applications, e.g. in a prototyping environment, warnings may be acceptable. For production environments warnings should be treated like errors unless they can be safely ignored.]

`fmi3Discard`

The call was not successful and the FMU is in the same state as before the call. The output argument values are not defined, but the computation can continue. Function `logMessage` should be called by the FMU with further information before returning this status, respecting the current logging settings. Advanced simulation algorithms can try alternative approaches to drive the simulation by calling the function with different arguments or calling another function. Otherwise the simulation algorithm has to treat this return code like `fmi3Error` and has to terminate the simulation.
[Examples for usage of `fmi3Discard` are

• handling of min/max violation, or

• signal numerical problems during model evaluation forcing smaller step sizes.]

`fmi3Error`

The call failed. The output argument values are undefined and the simulation cannot be continued. Function `logMessage` should be called by the FMU with further information before returning this status, respecting the current logging settings. If a function returns `fmi3Error`, it is possible to restore a previously retrieved FMU state by calling `fmi3SetFMUState`. Otherwise `fmi3FreeInstance` or `fmi3Reset` must be called. When detecting illegal arguments or a function call not allowed in the current state according to the respective state machine, the FMU must return `fmi3Error`. Other instances of this FMU are not affected by the error.

`fmi3Fatal`

The state of all instances of the model is irreparably corrupted. [For example, due to a runtime exception such as access violation or integer division by zero during the execution of an FMI function.] Function `logMessage` should be called by the FMU with further information before returning this status, respecting the current logging settings, if still possible. It is not allowed to call any other function for any instance of the FMU.

2.2.4. Inquire Version Number of Header Files

``typedef const char* fmi3GetVersionTYPE(void);``

This function returns `fmi3Version` of the `fmi3Functions.h` header file which was used to compile the functions of the FMU. This function call is allowed always and in all interface types.

The standard header file as documented in this specification has version `"3.0"`, so this function returns `"3.0"`.

This section highlights the differences of the concept of time (in general the independent variable) for the three different FMI types, ME, CS and SE. Depending on the instantiated FMI type, the importer is restricted in what functions it is allowed to call in order to drive the simulation.

In Model Exchange, time is under the sole control of the importer and its integration algorithm. The model itself receives the current time to be used in its computation with `fmi3SetTime`. In fact, time is not necessarily always advancing as solvers might need to jump back and forth in time to localize events using zero-crossings of event indicators.

In Co-Simulation, time advances in (possibly variable) steps negotiated between the co-simulation algorithm of the importer and the FMU. The importer calls `fmi3DoStep` with the `currentCommunicationPoint` and a target `communicationStepSize` (required to be larger than 0.0). During this `fmi3DoStep`, both importer and FMU might encounter events (or other situations) that require reduction of the `communicationStepSize` (potentially even down to 0.0). The FMU may use `earlyReturn` argument of the `fmi3DoStep` function to tell the importer that the FMU needs to return earlier, and the importer may use the callback `fmi3CallbackIntermediateUpdate` to signal the FMU that the latter should return earlier. The output argument `lastSuccessfulTime` of `fmi3DoStep` allows the FMU to signal the importer its current internal time.

In Scheduled Execution, time has a more discrete form. The scheduler of the importer activates specific tasks according to the time of the importer. The time itself is communicated to the FMU as `activationTime` argument of `fmi3ActivateModelPartition`.

2.2.6. Variables

FMU and importer use variables to exchange information. All variables are listed in the `modelDescription.xml` as elements of `<fmiModelDescription><ModelVariables>`.

They are identified with a unique handle called value reference.

The attribute `causality` defines the direction of the information flow with respect to the FMU (e.g. `input`, `output`, `parameter`).

A variable can be a scalar or a multi-dimensional array.

2.2.6.1. Serialization of Array Variables

When getting or setting the values of array variables, the serialization of array variable values used in C-API function calls, as well as in the XML `start` attributes, is defined as row major, i.e., dimension order from left to right for the C-API (e.g. `array[dim1][dim2]…​[dimN]`), and the document order in the XML attributes for the respective dimensions. For this serialization of array variables the sparsity pattern of the array is not taken into account. All elements of the array, including structural zeros, are serialized.

[Example: A 2D matrix

$A = \left( \begin{array}{cc} a_{11}&a_{12}\\ a_{21}&a_{22}\\ a_{31}&a_{32}\\ \end{array} \right)$

is serialized as follows:

]

2.2.6.2. Getting and Setting Variable Values

Restrictions for setting and getting of variables with certain types, causalities and variabilities are described in the state machine and state descriptions (see Section 2.3, Section 3.2 in case of Model Exchange, Section 4.2 for Co-Simulation and Section 5.2 for Scheduled Execution).

The value of a variable must be accessed with the respective `fmi3Get/Set{VariableType}` (see also `{VariableType}` and `{VariableTypeExclClock}`) for the type defined in the `modelDescription.xml`. To set or inquire variables of type `Enumeration`, `fmi3SetInt64` and `fmi3GetInt64` must be used.

The current values of the variables can be inquired with the following functions:

``````typedef fmi3Status fmi3GetFloat32TYPE(fmi3Instance instance,
const fmi3ValueReference valueReferences[],
size_t nValueReferences,
fmi3Float32 values[],
size_t nValues);

typedef fmi3Status fmi3GetFloat64TYPE(fmi3Instance instance,
const fmi3ValueReference valueReferences[],
size_t nValueReferences,
fmi3Float64 values[],
size_t nValues);

typedef fmi3Status fmi3GetInt8TYPE   (fmi3Instance instance,
const fmi3ValueReference valueReferences[],
size_t nValueReferences,
fmi3Int8 values[],
size_t nValues);

typedef fmi3Status fmi3GetUInt8TYPE  (fmi3Instance instance,
const fmi3ValueReference valueReferences[],
size_t nValueReferences,
fmi3UInt8 values[],
size_t nValues);

typedef fmi3Status fmi3GetInt16TYPE  (fmi3Instance instance,
const fmi3ValueReference valueReferences[],
size_t nValueReferences,
fmi3Int16 values[],
size_t nValues);

typedef fmi3Status fmi3GetUInt16TYPE (fmi3Instance instance,
const fmi3ValueReference valueReferences[],
size_t nValueReferences,
fmi3UInt16 values[],
size_t nValues);

typedef fmi3Status fmi3GetInt32TYPE  (fmi3Instance instance,
const fmi3ValueReference valueReferences[],
size_t nValueReferences,
fmi3Int32 values[],
size_t nValues);

typedef fmi3Status fmi3GetUInt32TYPE (fmi3Instance instance,
const fmi3ValueReference valueReferences[],
size_t nValueReferences,
fmi3UInt32 values[],
size_t nValues);

typedef fmi3Status fmi3GetInt64TYPE  (fmi3Instance instance,
const fmi3ValueReference valueReferences[],
size_t nValueReferences,
fmi3Int64 values[],
size_t nValues);

typedef fmi3Status fmi3GetUInt64TYPE (fmi3Instance instance,
const fmi3ValueReference valueReferences[],
size_t nValueReferences,
fmi3UInt64 values[],
size_t nValues);

typedef fmi3Status fmi3GetBooleanTYPE(fmi3Instance instance,
const fmi3ValueReference valueReferences[],
size_t nValueReferences,
fmi3Boolean values[],
size_t nValues);

typedef fmi3Status fmi3GetStringTYPE (fmi3Instance instance,
const fmi3ValueReference valueReferences[],
size_t nValueReferences,
fmi3String values[],
size_t nValues);

typedef fmi3Status fmi3GetBinaryTYPE (fmi3Instance instance,
const fmi3ValueReference valueReferences[],
size_t nValueReferences,
size_t sizes[],
fmi3Binary values[],
size_t nValues);

typedef fmi3Status fmi3GetClockTYPE  (fmi3Instance instance,
const fmi3ValueReference valueReferences[],
size_t nValueReferences,
fmi3Clock values[],
size_t nValues);``````
• `valueReferences` is a vector of `nValueReferences` value handles that define the variables that shall be inquired.

• `values` is a vector with the actual values of these variables.

• `sizes` is a vector with the actual sizes of the values for binary variables.

• `nValues` provides the number of values in the `values` vector (and `sizes` vector, where applicable) which is only equal to `nValueReferences` if all `valueReference`s point to scalar variables. [The passing of `nValues` is, strictly speaking, passing redundant information: The number of values can be reconstructed from the value references passed in and their corresponding variable definitions and (potentially dynamic) array sizes. It is added to ensure memory safety and other sanity checks to be preserved even in the face of potential divergence of array configuration.]

The strings returned by `fmi3GetString`, as well as the binary values returned by `fmi3GetBinary`, must be copied by the importer because the allocated memory for these strings might be deallocated or overwritten by the next call of an FMU function.

It is possible to set the values of variables using the following functions:

``````typedef fmi3Status fmi3SetFloat32TYPE(fmi3Instance instance,
const fmi3ValueReference valueReferences[],
size_t nValueReferences,
const fmi3Float32 values[],
size_t nValues);

typedef fmi3Status fmi3SetFloat64TYPE(fmi3Instance instance,
const fmi3ValueReference valueReferences[],
size_t nValueReferences,
const fmi3Float64 values[],
size_t nValues);

typedef fmi3Status fmi3SetInt8TYPE   (fmi3Instance instance,
const fmi3ValueReference valueReferences[],
size_t nValueReferences,
const fmi3Int8 values[],
size_t nValues);

typedef fmi3Status fmi3SetUInt8TYPE  (fmi3Instance instance,
const fmi3ValueReference valueReferences[],
size_t nValueReferences,
const fmi3UInt8 values[],
size_t nValues);

typedef fmi3Status fmi3SetInt16TYPE  (fmi3Instance instance,
const fmi3ValueReference valueReferences[],
size_t nValueReferences,
const fmi3Int16 values[],
size_t nValues);

typedef fmi3Status fmi3SetUInt16TYPE (fmi3Instance instance,
const fmi3ValueReference valueReferences[],
size_t nValueReferences,
const fmi3UInt16 values[],
size_t nValues);

typedef fmi3Status fmi3SetInt32TYPE  (fmi3Instance instance,
const fmi3ValueReference valueReferences[],
size_t nValueReferences,
const fmi3Int32 values[],
size_t nValues);

typedef fmi3Status fmi3SetUInt32TYPE (fmi3Instance instance,
const fmi3ValueReference valueReferences[],
size_t nValueReferences,
const fmi3UInt32 values[],
size_t nValues);

typedef fmi3Status fmi3SetInt64TYPE  (fmi3Instance instance,
const fmi3ValueReference valueReferences[],
size_t nValueReferences,
const fmi3Int64 values[],
size_t nValues);

typedef fmi3Status fmi3SetUInt64TYPE (fmi3Instance instance,
const fmi3ValueReference valueReferences[],
size_t nValueReferences,
const fmi3UInt64 values[],
size_t nValues);

typedef fmi3Status fmi3SetBooleanTYPE(fmi3Instance instance,
const fmi3ValueReference valueReferences[],
size_t nValueReferences,
const fmi3Boolean values[],
size_t nValues);

typedef fmi3Status fmi3SetStringTYPE (fmi3Instance instance,
const fmi3ValueReference valueReferences[],
size_t nValueReferences,
const fmi3String values[],
size_t nValues);

typedef fmi3Status fmi3SetBinaryTYPE (fmi3Instance instance,
const fmi3ValueReference valueReferences[],
size_t nValueReferences,
const size_t sizes[],
const fmi3Binary values[],
size_t nValues);

typedef fmi3Status fmi3SetClockTYPE  (fmi3Instance instance,
const fmi3ValueReference valueReferences[],
size_t nValueReferences,
const fmi3Clock values[],
size_t nValues);``````
• `valueReferences` is a vector of `nValueReferences` value handles that define the variables that shall be set.

• `values` is a vector with the actual values of these variables.

• `sizes` is a vector with the actual sizes of the values of binary variables.

• `nValues` provides the number of values in the `values` vector (and `sizes` vector, where applicable) which is only equal to `nValueReferences` if all `valueReference`s point to scalar variables.

With two exceptions, all variables that are allowed to be set with `fmi3Set{VariableType}` keep their respective values until the next call to `fmi3Set{VariableType}`. Exceptions:

1. Variables of type Clock must be deactivated during `fmi3UpdateDiscreteStates` by the FMU.

2. By setting the complete FMU state using `fmi3SetFMUState`, all variables are potentially changed.

All strings passed as arguments to `fmi3SetString`, as well as all binary values passed as arguments to `fmi3SetBinary`, must be copied during these function calls, because there is no guarantee of the lifetime of strings or binary values, when these functions return.

2.2.6.3. Handling min/max Range Violations

Attributes `min` and `max` can be defined for variables of float, integer or enumeration types. The question is how `fmi3Set{VariableType}`, `fmi3Get{VariableType}` shall utilize this definition. There are several conflicting requirements:
Avoiding forbidden regions (for example, if `u` is an `input` and "sqrt(u)" is computed in the FMU, `min = 0` on `u` shall guarantee that only values of `u` in the allowed regions are provided). Numerical algorithms (solvers or optimizers) do not guarantee constraints. If a variable is outside of the bounds, the solver tries to bring it back into the bounds. As a consequence, calling `fmi3Get{VariableType}` during an iteration of such a solver might return values that are not in the defined min/max region. After the iteration is finalized, it is only guaranteed that a value is within its bounds up to a certain numerical precision.
During system creation and prototyping, checks on min/max should be performed. For maximum performance on production or real-time systems, these checks might not be performed.
The approach in FMI is therefore that min/max definitions are an information from the FMU to the environment defining the region in which the FMU is designed to operate. In any case, it is expected that the FMU handles variables appropriately where the region definition is critical. For example, dividing by an `input` (so the `input` should not be in a small range of zero) or taking the square root of an `input` (so the `input` should not be negative) may either result in returning `fmi3Discard` or `fmi3Error`, or the FMU is able to handle this situation in other ways.

If the FMU is generated so that min/max shall be checked whenever meaningful (for example, for debug purposes), then the following strategy should be used:

If `fmi3Set{VariableType}` is called violating the min/max attribute settings of the corresponding variable, the following actions are performed:

If an FMU defines min/max values for integer types and `<Enumeration>` variables (`local` and `output` variables), then the expected behavior of the FMU is that `fmi3Get{VariableType}` functions return values in the defined range.

If an FMU defines min/max values, then the expected behavior of the FMU is that `fmi3Get{VariableType}` returns values at the solution (accepted steps of the integrators) in the defined range with a certain uncertainty related to the tolerances of the numerical algorithms.]

2.2.6.4. Getting and Setting the Complete FMU State

The FMU has an internal state consisting of all values that are needed to continue a simulation. This internal state consists especially of the values of the continuous states, iteration variables, `parameter` values, `input` values, delay buffers, file identifiers, and FMU internal status information. With the functions of this section, the internal FMU state can be copied and the pointer to this copy is returned to the environment. The FMU state copy can be set as actual FMU state, in order to continue the simulation from it.

[Examples for using this feature:

For variable step-size control of co-simulation algorithms (get the FMU state for every accepted communication step; if the follow-up step is not accepted, restart co-simulation from this FMU state).

For nonlinear Kalman filters (get the FMU state just before initialization; in every sample period, set new continuous states from the Kalman filter algorithm based on measured values; integrate to the next sample instant and inquire the predicted continuous states that are used in the Kalman filter algorithm as basis to set new continuous states).

For nonlinear model predictive control (get the FMU state just before initialization; in every sample period, set new continuous states from an observer, initialize and get the FMU state after initialization. From this state, perform many simulations that are restarted after the initialization with new input variables proposed by the optimizer).]

Furthermore, the FMU state can be serialized and copied in a byte vector. [This can be, for example, used to perform an expensive steady-state initialization, copy the received FMU state in a byte vector and store this vector on file. Whenever needed, the byte vector can be loaded from file and deserialized, and the simulation can be restarted from this FMU state, in other words, from the steady-state initialization.]

Function `fmi3GetFMUState`
``typedef fmi3Status fmi3GetFMUStateTYPE (fmi3Instance instance, fmi3FMUState* FMUState);``

This function makes a copy of the internal FMU state and returns a pointer to this copy in `FMUState`. If on entry `*FMUState == NULL`, a new allocation is required. If `*FMUState != NULL`, then `*FMUState` points to a previously returned `FMUState` that has not been modified since. In particular, `fmi3FreeFMUState` had not been called with this `FMUState` as an argument. [Function `fmi3GetFMUState` typically reuses the memory of this `FMUState` in this case and returns the same pointer to it, but with the actual `FMUState`.]

Function `fmi3SetFMUState`
``typedef fmi3Status fmi3SetFMUStateTYPE (fmi3Instance instance, fmi3FMUState  FMUState);``

This function copies the content of the previously copied `FMUState` back and uses it as actual new FMU state. The `FMUState` copy still exists. [The simulation is restarted at this state, when calling `fmi3SetFMUState` with `FMUState`.]

Function `fmi3FreeFMUState`
``typedef fmi3Status fmi3FreeFMUStateTYPE(fmi3Instance instance, fmi3FMUState* FMUState);``

This function frees all memory and other resources allocated with the `fmi3GetFMUState` call for this `FMUState`. The argument to this function is the `FMUState` to be freed. If a NULL pointer is provided, the call is ignored. The function returns a NULL pointer in argument `FMUState`.

These functions can be called, if the optional capability flag `canGetAndSetFMUState` is set to `true`.

Function `fmi3SerializedFMUStateSize`
``````typedef fmi3Status fmi3SerializedFMUStateSizeTYPE(fmi3Instance instance,
fmi3FMUState  FMUState,
size_t* size);``````

This function returns the `size` of the byte vector, in order that `FMUState` can be stored in it. With this information, the environment has to allocate an `fmi3Byte` vector of the required length `size`.

Function `fmi3SerializeFMUState`
``````typedef fmi3Status fmi3SerializeFMUStateTYPE     (fmi3Instance instance,
fmi3FMUState  FMUState,
fmi3Byte serializedState[],
size_t size);``````

This function serializes the data which is referenced by pointer `FMUState` and copies this data in to the byte vector `serializedState` of length `size`, that must be provided by the environment.

Function `fmi3DeSerializeFMUState`
``````typedef fmi3Status fmi3DeSerializeFMUStateTYPE   (fmi3Instance instance,
const fmi3Byte serializedState[],
size_t size,
fmi3FMUState* FMUState);``````

This function deserializes the byte vector `serializedState` of length `size`, constructs a copy of the FMU state and returns `FMUState`, the pointer to this copy.

These functions are only supported by the FMU, if the optional capability flags `canGetAndSetFMUState` and `canSerializeFMUState` in `<fmiModelDescription><ModelExchange|CoSimulation|ScheduledExecution>` in the XML file are explicitly set to `true` (see Section 3, Section 4, Section 5).

2.2.7. Selective Computation of Variables

Depending on the phase of the solver algorithm, different FMU variables need to be computed. FMI allows selective retrieval of FMU variables with specific get functions (e.g. `fmi3Get{VariableType}`, `fmi3GetEventIndicators`, `fmi3GetContinuousStateDerivatives`). This enables computation on demand with subsequent calls returning the same value until some set operation requires re-computation.

For example, during the iteration of an integrator step, only the state derivatives need to be computed, provided the `output` of a model is not connected. When localizing state events, only the computation of event indicators might be required.

Because specific set functions exist (`fmi3Set{VariableType}`, `fmi3SetTime`, `fmi3SetContinuousStates`), caching algorithms can be applied to reuse already computed values.

In all tables describing the mathematical model of a state (e.g. ContinuousTimeMode), for notational convenience one function (e.g. $\mathbf{f}_\mathit{cont}$) is defined to compute all output arguments from all inputs arguments. In an FMU, every output argument can be computed by its specific get function. Additionally, the output argument need not be a function of all input arguments, but of only a subset from it, as defined in the `modelDescription.xml` under `<ModelStructure>`.

[The functions above have the slight drawback that values must always be copied. For example, a call to `fmi3SetContinuousStates` will provide the actual states in a vector, and this function has to copy the values in to the internal model data structure so that subsequent evaluation calls can utilize these values. If this turns out to be an efficiency issue, a future release of FMI might provide additional functions to provide the address of a memory area where the variable values are present.]

2.2.8. Algebraic Loops

When connecting FMUs, loop structures can occur that might lead to linear or non-linear algebraic systems of equations, involving continuous and discrete-time variables. In order to detect and solve such systems of equations efficiently, information which `output` depends directly on which `inputs` is needed. This data is optionally provided in the `modelDescription.xml` under element `<ModelStructure>`. If this data is not provided, the worst case must be assumed: all `output` variables depend algebraically on all `input` variables.

[Example: In Figure 5 two different types of connected FMUs are shown (the "dotted lines" characterize the dependency information):

Figure 5. Calling sequences for FMUs that are connected in a loop.

Since different variables are computed in every mode and the causality of variable computation can be different in Initialization Mode as with respect to the other two modes, it might be necessary to solve different kinds of loops in the different modes. Artificial algebraic loops (see left diagram of Figure 5) can be solved in the modes Initialization Mode, Event Mode, and Continuous-Time Mode by an appropriate sequence of `fmi3Set{VariableType}` and `fmi3Get{VariableType}` calls:

``````    FMU *m1, *m2;
fmi3ValueReference vr_M1_u, vr_M1_y, vr_M2_u1, vr_M2_u2, vr_M2_y1, vr_M2_y2;
fmi3Float64 s = 0.1, M2_y1, M1_y, M2_y2;
// ...
m2->fmi3SetFloat64(m2->instance, &vr_M2_u1, 1, &s, 1);
m2->fmi3GetFloat64(m2->instance, &vr_M2_y1, 1, &M2_y1, 1);
m1->fmi3SetFloat64(m1->instance, &vr_M1_u,  1, &M2_y1, 1);
m1->fmi3GetFloat64(m1->instance, &vr_M1_y,  1, &M1_y, 1);
m2->fmi3SetFloat64(m2->instance, &vr_M2_u2, 1, &M1_y, 1);
m2->fmi3GetFloat64(m2->instance, &vr_M2_y1, 1, &M2_y2, 1);
//...``````

In the right diagram, FMU3 and FMU4 are connected in such a way that a real algebraic loop is formed. This loop might be solved iteratively, for example with a Newton method. In every iteration the iteration variable FMU4_u is provided by the solver, and via the shown sequence of `fmi3Set{VariableType}` and `fmi3Get{VariableType}` calls, the residual is computed and used by the solver to determine a new value of FMU4_u. The iteration is terminated when the residual is small enough. This method works for Initialization Mode, Event Mode, and Continuous-Time Mode.

``````    FMU *m3, *m4;
fmi3ValueReference vr_M3_u, vr_M3_y, vr_M4_u, vr_M4_y;
fmi3Float64 s, M3_y, M4_y, residual, tolerance;
bool converged = false;

while (!converged) { // start iteration
// s determined by the solver
// ...
m4->fmi3SetFloat64(m4->instance, &vr_M4_u, 1, &s, 1);
m4->fmi3GetFloat64(m4->instance, &vr_M4_y, 1, &M4_y, 1);
m3->fmi3SetFloat64(m3->instance, &vr_M3_u, 1, &M4_y, 1);
m3->fmi3GetFloat64(m3->instance, &vr_M3_y, 1, &M3_y, 1);
residual = s - M3_y; // provided to the solver
converged = residual < tolerance;
}``````

In Step Mode, `fmi3SetFMUState` is required to restore the FMU state before the next iteration with `fmi3Set{VariableType}`, `fmi3DoStep`, and `fmi3Get{VariableType}` is executed.

In Event Mode, the algorithms from above must be embedded in an event iteration:

``````    FMU *m1, *m2;  // structures that hold the functions and instances of the FMUs

m1->fmi3EnterEventMode(m1->instance, v1, v2, v3, v4, v5);
m2->fmi3EnterEventMode(m2->instance, v1, v2, v3, v4, v5);

// start event iteration
do {
// solve algebraic loop as described in the sample codes above

// introduce new instant of super-dense time
m1->fmi3UpdateDiscreteStates(m1->instance, &m1_DStatesNeedUpdate, p2, p3, p4, p5, p6);
m2->fmi3UpdateDiscreteStates(m2->instance, &m2_DStatesNeedUpdate, p2, p3, p4, p5, p6);

} while (m1_DStatesNeedUpdate || m2_DStatesNeedUpdate);

if (isCoSimulation) {
// Co-Simulation
m1->fmi3EnterStepMode(m1->instance);
m2->fmi3EnterStepMode(m2->instance);
} else {
// Model Exchange
m1->fmi3EnterContinuousTimeMode(m1->instance);
m2->fmi3EnterContinuousTimeMode(m2->instance);
}``````

When solving algebraic loops in Event Mode, limitations to variable manipulations declared with XML attribute `canHandleMultipleSetPerTimeInstant` must be considered.]

2.2.9. Clocks

FMI 3.0 specifies the behavior of a clocked FMU. FMI 3.0 does not specify how the importer uses this functionality. This allows different use cases to be implemented with different semantics.

2.2.9.1. Motivation

Clock variables synchronize events between importer and across FMUs, by

1. communicating exactly which specific event happens and

2. exactly at which time instant, independent from continuous time specified by the arguments of `fmi3SetTime` or `fmi3DoStep`.

The first point solves the issue that an FMU must know exactly which event happens during an Event Mode if several events are very close to one another.

The second point solves the issue that computing exactly when an event happens is impossible to guarantee across importer and FMUs when using floating point computations.

2.2.9.2. Clock Types

Clocks are `discrete` variables with a special semantic.

The following Clock types are described in detail after the table.

Input Clock

is a variable of type Clock with `causality` == `input`. In Model Exchange and Co-Simulation, when input Clocks tick, the importer will activate the input Clocks using `fmi3SetClock`. In Scheduled Execution, when input Clocks tick, the importer will activate the associated model partitions (but not the input Clocks) using `fmi3ActivateModelPartition`. While the importer is the source of the actual Clock activations, the timing of the Clocks is defined by the FMU, either through the `modelDescription.xml` or calling `fmi3GetInterval`, or by another Clock connected to a `triggered` input Clock.

Output Clock

is a variable of type Clock with `causality` == `output`. The attribute `interval` must be `triggered` for output Clocks. The importer calls `fmi3GetClock` to inquire the clock activation state.

Table 5. Overview of Clock types.
Clock type `causality` `interval` Related API calls and arguments Example

time-based

periodic

`input`

`constant`

clocked PI-controller with a defined constant interval

`fixed`

clocked PI-controller with an adaptable interval

`calculated`

clocked PI-controller with interval defined by fixed parameter(s) of the FMU

`tunable`

clocked PI-controller with interval defined by tunable parameter(s) of the FMU

aperiodic

`input`

`changing`

`fmi3SetClock` in Event Mode, `fmi3ActivateModelPartition` in Clock Activation Mode, `fmi3GetInterval` in Initialization Mode, `fmi3GetInterval` in both Event Mode and Clock Activation Mode if and only if this Clock ticked using `clocksTicked == fmi3True`

simulation of the behavior of a control algorithm with variable execution time, generation of pulse sequences

`countdown`

`fmi3SetClock` in Event Mode, `fmi3ActivateModelPartition` in Clock Activation Mode, `fmi3GetInterval` in Initialization Mode, in every Event Mode, and in Intermediate Update Mode. In Scheduled Execution the FMU has to inform the importer by calling `fmi3CallbackIntermediateUpdate` that the Clock is about to tick using `clocksTicked == fmi3True`

time-delayed actions after an event, for example, ignition signal some time after specific crank shaft angle

triggered

`input`

`triggered`

triggered by a hardware interrupt of an embedded system, e.g. a control algorithm, triggered by a crankshaft angle

`output`

`triggered`

crankshaft angle sensor ticking several times per revolution

Time-based Clock

is in a sense predictable and helps the importer to take its Clock ticks into account a priori. All time-based Clocks are defined to be input Clocks because the importer calls `fmi3SetClock` or `fmi3ActivateModelPartition` on these Clocks. The importer queries the FMU about when a time-based Clock should tick. The importer will then activate the Clock by calling `fmi3SetClock`, or activate the associated model partition by calling `fmi3ActivateModelPartition`.

The mathematical descriptions of time-based Clock will use the following notations:

 $\mathbf{t}_0$ The time instant at which the Clock ticks the first time. $\mathbf{t}_\mathit{i-1}$ The previous time instant, where the Clock ticked. $\mathbf{T}_{\mathit{shift}}$ The delay for the first Clock tick relative to $\mathbf{t}_{\mathit{start}}$. $\mathbf{T}_{\mathit{shift}}$ is defined differently for the different Clock types, and can be retrieved from the FMU with `fmi3GetShiftDecimal` as floating point value, or with `fmi3GetShiftFraction` as rational number `shiftCounter / resolution` (see `resolution`). $\mathbf{T}_{interval, i}$ The time interval until the next Clock tick, defined differently for the different Clock types. $\mathbf{T}_{interval, i}$ can be set with `fmi3SetIntervalDecimal` or retrieved with `fmi3GetIntervalDecimal` as floating point value, or as rational number using `fmi3SetIntervalFraction` or `fmi3GetIntervalFraction` `intervalCounter / resolution` (see `resolution`). $\mathbf{t}_\mathit{event}$ The current event time in Event Mode, or the current time in Scheduled Execution.
Periodic Clock

is a time-based Clock with a constant interval, except when `interval` == `tunable`, which indicates that the interval can change when tunable parameters change. The time instant of the first Clock tick is defined by a `shift`.

The next Clock tick at time instant $t_i$ is defined as:
\begin{align*} \mathbf{t}_0 &:= \mathbf{t}_{\mathit{start}} + \mathbf{T}_{\mathit{shift}} \\ \mathbf{t}_i &:= \mathbf{t}_{i-1} + \mathbf{T}_{interval, i} \qquad i = 1,2,3,{...} \end{align*}

 $\mathbf{T}_{interval, i} > 0$ The time interval from the previous Clock tick to the current Clock tick, specified differently for the different Clock types.
Constant periodic Clock

are time-based periodic clocks that define their `interval` and `shift` in the `modelDescription.xml`.

Fixed periodic Clock

is a time-base periodic Clock which ticks with an arbitrary, but constant interval starting after an arbitrary `shift`. The importer informs the FMU about the interval using `fmi3SetInterval`.

Calculated periodic Clock

is a time-base periodic Clock whose interval and `shift` depend on `fixed` parameters. The importer must use `fmi3GetInterval` and `fmi3GetShift` to retrieve the Clock interval and `shift` in Initialization Mode.

Tunable periodic Clock

is a time-base periodic Clock whose interval depends on `tunable` parameters. The importer must use `fmi3GetInterval` to retrieve the Clock interval in Event Mode or Clock Activation Mode, if any of the `tunable` parameters it depends on was changed. `shift` may only depend on `fixed` parameters. The importer must use `fmi3GetShift` to retrieve the Clock `shift` in Initialization Mode.

Aperiodic Clock

is a time-based Clock with an interval that can change during runtime by FMU-internal mechanisms. `fmi3GetInterval` must be called to retrieve the first interval in Initialization Mode. Calling `fmi3GetShift` is not allowed.

Changing aperiodic Clock

is a time-based Clock whose next interval is unchangeably known right after the Clock just ticked.

The next Clock tick at time instant $t_i$ is defined as:
\begin{align*} \mathbf{t}_0 &:= \mathbf{t}_{\mathit{start}} + \mathbf{T}_{interval, 0} \\ \mathbf{t}_i &:= \mathbf{t}_{i-1} + \mathbf{T}_{interval, i} \qquad i = 1,2,3,{...} \end{align*}

 $\mathbf{T}_{interval, 0} \geq 0$ The time interval from $\mathbf{t}_{\mathit{start}}$ to first Clock tick. Must be retrieved in Initialization Mode. $\mathbf{T}_{interval, i} > 0, \qquad i = 1,2,3,{...}$ The time interval from the current Clock tick to the next Clock tick. Must be retrieved in Event Mode or Clock Activation Mode if and only if the corresponding Clock ticked.
Countdown aperiodic Clock

is a time-based Clock whose next interval is not yet known right after the Clock just ticked, forcing the importer to call `fmi3GetInterval` in every Event Mode and in Intermediate Update Mode if `clocksTicked` == `fmi3True` in `fmi3CallbackIntermediateUpdate`. The return argument `qualifier` of `fmi3GetInterval` is used to indicate if the next interval is already known.

The next Clock tick at time instant $t_i$ is defined as:
\begin{align*} \mathbf{t}_0 &:= \mathbf{t}_{\mathit{start}} + \mathbf{T}_{interval, 0} \\ \mathbf{t}_i &:= \mathbf{t}_{event} + \mathbf{T}_{interval, i} \qquad i = 1,2,3,{...} \end{align*}

 $\mathbf{T}_{interval, 0} \geq 0$ The time interval from $\mathbf{t}_\mathit{start}$ to the first Clock tick. Must be retrieved in Initialization Mode. $\mathbf{T}_{interval, i} \geq 0, \qquad i = 1,2,3,{...}$ The time interval from the event time at which the argument `qualifier == fmi3IntervalChanged` of `fmi3GetInterval` to the next Clock tick.
Triggered Clock

ticks unpredictably.

Triggered input Clock

is activated with `fmi3SetClock` by the importer in Event Mode, or triggers activation of the associated model partition with `fmi3ActivateModelPartition` in Clock Activation Mode.

Triggered output Clock

is activated within the FMU and the importer must call `fmi3GetClock` in Event Mode or in Intermediate Update Mode.

[Output Clocks are intended to enable an FMU to provide a trigger to the outside world, e.g. to a `triggered input Clock` of another FMU. Note, that if intended to activate model partitions or a Clock of the same FMU calling `fmi3GetInterval` for a `countdown Clock` and evaluating the `qualifier` is recommended. An example is provided in Section 5.3.]

2.2.9.3. Model Partitions and Clocked Variables

Each Clock $\mathbf{k}$ induces a discrete system. It’s state advances at each tick of $\mathbf{k}$. Such a system, also called the model partition of $\mathbf{k}$, is written as:

\begin{align*} (\mathbf{x}_k) &:= \mathbf{f}_{disc}(^\bullet{\mathbf{x}_k}, \mathbf{u}, \mathbf{t}) \\ (\mathbf{y}_k) &:= \mathbf{f}_{event}(\mathbf{x}_k, \mathbf{u}, \mathbf{t}) \end{align*}

where:

1. $\mathbf{f}_{disc}$ denotes the state transition function and

2. $\mathbf{f}_{event}$ denotes the output function of the model partition of $\mathbf{k}$.

[Such a model partition may represent a task or an interrupt service routine of an embedded system, or a discretized part of a plant model. The name "model partition" refers to the fact that an model inside an FMU may declare multiple Clocks, each with its own partition of the overall model.]

When $\mathbf{k}$ is active (i.e., ticking) invoking the FMI functions `fmi3Get{VariableType}` on variables in the output vector $\mathbf{y}_k$ will trigger the execution of the output function $\mathbf{f}_{event}$ to compute such variables. If `providesEvaluateDiscreteStates` is `false`, then $\mathbf{f}_{disc}$ cannot be called explicitly using `fmi3EvaluateDiscreteStates`, but will be implicitly executed during $\mathbf{f}_{event}$. When `fmi3EvaluateDiscreteStates` is called, the state vector $\mathbf{x}_k$ is updated according to state transition function $\mathbf{f}_{disc}$.

[Separating $\mathbf{f}_{disc}$ from $\mathbf{f}_{event}$ allows manipulation of the current (discrete) state and compute the corresponding outputs.]

The discrete-time variables $\mathbf{x}_k$ and $\mathbf{y}_k$ are called clocked variables. A clocked variable $\mathbf{v}_k$ can acquire a new value and can be queried only when its Clock $\mathbf{k}$ is active, except during Initialization Mode. [This is common in clock semantics. See, e.g., [MLS12].] During Initialization Mode, if a clocked variable is declared as an `<InitialUnknown>`, then it must be initialized as a discrete variable. Declaring a clocked variable as an `<InitialUnknown>` is optional. Uninitialized clocked variables must be initialized in the corresponding Clock’s first tick.

A `ClockedState` is a clocked variable belonging to the state vector $\mathbf{x}_k$, whose value depends on its previous value (i.e., the value computed at the last Clock tick). Clocked states declare the `valueReference` of their previous variable using the `previous` attribute.

The association between clocked variables and their Clocks is defined by the attribute `clocks`. Clocked variables can depend on multiple Clocks. [For example, a global counter could be incremented by multiple tasks, each controlled by a different Clock.]

Clocks may depend on input Clocks. This dependency is also defined by the `clocks` attribute. [E.g. if an `output Clock` depends on an `input Clock`, then Clock ticks of the `input Clock` in Event Mode or Clock Activation Mode may create `output Clock` ticks during this event handling.]

2.2.9.4. Scheduled Execution

During Clock Activation Mode after `fmi3ActivateModelPartition` has been called for a `calculated`, `tunable` or `changing` Clock the FMU provides the information on when the Clock will tick again, i.e. when the corresponding model partition has to be scheduled the next time. To retrieve this information the importer calls `fmi3GetInterval` on the Clock.

The FMU may request to schedule another model partition even while currently a model partition is being executed. `countdown` Clocks can tick at any time during the execution of any model partition. The FMU signals their ticking by calling `fmi3CallbackIntermediateUpdate` with argument `clocksTicked` == `fmi3True`. The importer calls `fmi3GetInterval` for all countdown Clocks. If a new interval is provided, the importer initiates the scheduling of the associated model partitions with the returned `interval`. `qualifier` == `fmi3IntervalChanged` indicates that the corresponding Clock has to be scheduled.

In case more than one Clock ticks at the same time instant, the scheduler needs a priority to define the activation sequence of the associated model partitions. This ordering is defined by the `priority` attributes of the Clock.

[For real-time computation use cases, the priority information is used also for task preemption configurations. It is therefore important to restrict the number of distinct priority levels for an FMU to available priority levels on the target platform and/or to avoid unnecessary computational overhead. A common number of different priority levels is, e.g., 100 (0 to 99), as defined in Linux based operating systems.]

[The Clock priorities are local to an FMU. It is not possible for an FMU exporting tool to know in advance the priorities of other FMUs that will be connected to an FMU in a simulation setup. It is the task of the importer to derive a computational order for the computation of two or more distinct FMUs based on the local FMU Clock priorities and input-output relationships of connected FMUs.]

[For `periodic Clocks` it is recommended to derive the priorities based on a rate monotonic scheduling scheme (smallest period leads to highest priority, that is, has the smallest priority value.]

2.2.9.5. Clocks specific API

Clocks are get and set just like any other variable (see also Section 2.2.6.2):

``````typedef fmi3Status fmi3GetClockTYPE  (fmi3Instance instance,
const fmi3ValueReference valueReferences[],
size_t nValueReferences,
fmi3Clock values[],
size_t nValues);

typedef fmi3Status fmi3SetClockTYPE  (fmi3Instance instance,
const fmi3ValueReference valueReferences[],
size_t nValueReferences,
const fmi3Clock values[],
size_t nValues);``````

`fmi3SetClock` is never called in Scheduled Execution.

For some Clock types, the interval is set by the environment for the current time instant by the function `fmi3SetIntervalDecimal` or `fmi3SetIntervalFraction`. The values of the arguments `interval`, `intervalCounter`, `resolution`, `shift` and `shiftCounter` refer to the unit of the `independent` variable.

The attribute `supportsFraction` of a Clock declares, if the `fmi3SetXXXFraction` and/or `fmi3GetXXXFraction` functions are allowed to be called.

``````typedef fmi3Status fmi3SetIntervalDecimalTYPE(fmi3Instance instance,
const fmi3ValueReference valueReferences[],
size_t nValueReferences,
const fmi3Float64 intervals[],
size_t nIntervals);``````
• `valueReferences` is an array of size `nValueReferences` holding the value references of the Clock variables.

• `intervals` is an array of size `nIntervals` holding the Clock intervals to be set.

``````typedef fmi3Status fmi3SetIntervalFractionTYPE(fmi3Instance instance,
const fmi3ValueReference valueReferences[],
size_t nValueReferences,
const fmi3UInt64 intervalCounters[],
const fmi3UInt64 resolutions[],
size_t nIntervals);``````
• `valueReferences` is an array of size `nValueReferences` holding the value references of the `Clock` variables.

• `intervalCounters` and `resolutions` are arrays of size `nIntervals` holding the Clock `intervalCounter` and `resolution` to be set.

For other Clock types, the importer calls `fmi3GetIntervalDecimal` or `fmi3GetIntervalFraction` to query the next Clock interval:

``````typedef fmi3Status fmi3GetIntervalDecimalTYPE(fmi3Instance instance,
const fmi3ValueReference valueReferences[],
size_t nValueReferences,
fmi3Float64 intervals[],
fmi3IntervalQualifier qualifiers[],
size_t nIntervals);``````
• `valueReferences` is an array of size `nValueReferences` holding the value references of the `Clock` variables.

• `intervals` is an array of size `nIntervals` to retrieve the Clock intervals.

• `qualifiers` is an array of size `nIntervals` to retrieve the Clock `qualifier`.

`qualifier` describes how to treat the `interval` and `intervalCounter` arguments and is defined as:

``````typedef enum {
fmi3IntervalNotYetKnown,
fmi3IntervalUnchanged,
fmi3IntervalChanged
} fmi3IntervalQualifier;``````
``````typedef fmi3Status fmi3GetIntervalFractionTYPE(fmi3Instance instance,
const fmi3ValueReference valueReferences[],
size_t nValueReferences,
fmi3UInt64 intervalCounters[],
fmi3UInt64 resolutions[],
fmi3IntervalQualifier qualifiers[],
size_t nIntervals);``````
• `valueReferences` is an array of size `nValueReferences` holding the value references of the `Clock` variables.

• `intervalCounters` and `resolutions` are arrays of size `nIntervals` to retrieve the Clock `intervalCounter` and `resolution`.

• `qualifiers` is an array of size `nIntervals` to retrieve the Clock `qualifier`.

For some Clocks, the importer has to query the delay to the first Clock tick from the FMU using the following functions:

``````typedef fmi3Status fmi3GetShiftDecimalTYPE(fmi3Instance instance,
const fmi3ValueReference valueReferences[],
size_t nValueReferences,
fmi3Float64 shifts[],
size_t nShifts);``````
• `valueReferences` is an array of size `nValueReferences` holding the value references of the Clock variables.

• `shifts` is an array of length `nShifts` that defines the time of the first Clock tick (see `shiftCounter`).

``````typedef fmi3Status fmi3GetShiftFractionTYPE(fmi3Instance instance,
const fmi3ValueReference valueReferences[],
size_t nValueReferences,
fmi3UInt64 shiftCounters[],
fmi3UInt64 resolutions[],
size_t nShifts);``````
• `valueReferences` is an array of size `nValueReferences` holding the value references of the Clock variables.

• `shifts` and `shiftCounters` are arrays of length `nShifts` that define the time of the first Clock tick (see `shiftCounter`).

2.2.10. Dependencies of Variables

Dependencies between variables of an FMU:

The dependencies are encoded in the `modelDescription.xml` with the element `<ModelStructure>` up to `valueReference` resolution, not individual elements of array variables.

Note, that the association between clocked variables and their Clocks is defined by the attribute `clocks` in `<fmiModelDescription><ModelVariables>`.

The variable dependency information in the XML description:

• does not resolve to dependencies of individual array elements,

• does not take changing dependencies due to resizing of arrays via `structural parameters` into account,

• is independent of the FMUs current operating point and parameter settings.

An FMU can indicate via the `providesPerElementDependencies` capability flag that it is able to provide detailed dependency information at runtime through the following C-API. The dependency information returned by these functions depend on the current operating point and parameter settings.

The number of dependencies of a given variable, which may change if `structural parameters` are changed, can be retrieved by calling the following function:

``````typedef fmi3Status fmi3GetNumberOfVariableDependenciesTYPE(fmi3Instance instance,
fmi3ValueReference valueReference,
size_t* nDependencies);``````

This function returns the number of `dependencies` for a given variable.

The actual `dependencies` (of type `dependenciesKind`) can be retrieved by calling the function `fmi3GetVariableDependencies`:

``````typedef enum {
fmi3Independent,
fmi3Constant,
fmi3Fixed,
fmi3Tunable,
fmi3Discrete,
fmi3Dependent
} fmi3DependencyKind;

typedef fmi3Status fmi3GetVariableDependenciesTYPE(fmi3Instance instance,
fmi3ValueReference dependent,
size_t elementIndicesOfDependent[],
fmi3ValueReference independents[],
size_t elementIndicesOfIndependents[],
fmi3DependencyKind dependencyKinds[],
size_t nDependencies);``````

This function returns the dependency information for a single variable.

• `dependent` specifies the `valueReference` of the variable for which the dependencies should be returned.

• `nDependencies` specifies the number of dependencies that the calling environment allocated space for in the result buffers, and should correspond to value obtained by calling `fmi3GetNumberOfVariableDependencies`.

• `elementIndicesOfDependent` must point to a buffer of `size_t` values of size `nDependencies` allocated by the calling environment. It is filled in by this function with the element index of the dependent variable that dependency information is provided for. The element indices start with 1. Using the element index 0 means all elements of the variable. (Note: If an array has more than one dimension the indices are serialized in the same order as defined for values in Section 2.2.6.1.)

• `independents` must point to a buffer of `fmi3ValueReference` values of size `nDependencies` allocated by the calling environment. It is filled in by this function with the value reference of the `independent` variable that this dependency entry is dependent upon.

• `elementIndicesIndependents` must point to a buffer of `size_t` values of size `nDependencies` allocated by the calling environment. It is filled in by this function with the element index of the `independent` variable that this dependency entry is dependent upon. The element indices start with 1. Using the element index 0 means all elements of the variable. (Note: If an array has more than one dimension the indices are serialized in the same order as defined for values in Section 2.2.6.1.)

• `dependencyKinds` must point to a buffer of `dependenciesKind` values of size `nDependencies` allocated by the calling environment. It is filled in by this function with the enumeration value describing the dependency of this dependency entry.

If this function is called before the `fmi3ExitInitializationMode` call, it returns the initial dependencies. If this function is called after the `fmi3ExitInitializationMode` call, it returns the runtime dependencies. The retrieved dependency information of one variable becomes invalid as soon as a `structural parameter` linked to the variable or to any of its depending variables are set. As a consequence, if you change `structural parameters` affecting B or A, the dependency of B becomes invalid. The dependency information must change only if `structural parameters` are changed.

2.2.11. Getting Partial Derivatives

Partial derivatives can be used:

• in Newton algorithms to solve algebraic loops,

• in implicit integration algorithms in Model Exchange, and

• in iterative co-simulation algorithms.

To avoid expensive numeric approximations of these derivatives, FMI offers dedicated functions to retrieve partial derivatives for an FMU. For Model Exchange, this means computing the partial derivatives at any time instant, whereas for Co-Simulation, this means computing the partial derivatives at a communication point.

An FMU has different states and in every state an FMU might be described by different equations and different unknowns. The precise definitions are given in the mathematical descriptions of Model Exchange (Section 3.2) and Co-Simulation (Section 4.2). In every state, the general form of the FMU equations are:

$\mathbf{v}_{\mathit{unknown}} = \mathbf{f}(\mathbf{v}_{\mathit{known}}, \mathbf{v}_{\mathit{rest}}),$

where

[The variable relationships are different in different states. For example, during Continuous-Time Mode, the partial derivate of a continuous-time output y with respect to discrete-time `inputs` is undefined, because discrete-time `inputs` cannot be set between events.]

There are two access functions for partial derivatives:

with the Jacobian

$\mathbf{J} = \begin{bmatrix} \frac{\partial h_1}{\partial v_{\mathit{known},1}} & \cdots & \frac{\partial h_1}{\partial v_{\mathit{known},n}} \\ \vdots & \ddots & \vdots \\ \frac{\partial h_m}{\partial v_{\mathit{known},1}} & \cdots & \frac{\partial h_m}{\partial v_{\mathit{known},n}} \end{bmatrix}$

where $\mathbf{v}_{\mathit{known}}$ are the $n$ knowns, and $\mathbf{h}$ are the $m$ functions to calculate the $m$ unknwon variables $\mathbf{v}_{\mathit{unknwon}}$ from the knowns.

Both functions can also be used to construct the partial derivative matrices. The functions may only be called if their availability is indicated by the attributes `providesDirectionalDerivatives` and `providesAdjointDerivatives` respectively.

``````typedef fmi3Status fmi3GetDirectionalDerivativeTYPE(fmi3Instance instance,
const fmi3ValueReference unknowns[],
size_t nUnknowns,
const fmi3ValueReference knowns[],
size_t nKnowns,
const fmi3Float64 seed[],
size_t nSeed,
fmi3Float64 sensitivity[],
size_t nSensitivity);``````
``````typedef fmi3Status fmi3GetAdjointDerivativeTYPE(fmi3Instance instance,
const fmi3ValueReference unknowns[],
size_t nUnknowns,
const fmi3ValueReference knowns[],
size_t nKnowns,
const fmi3Float64 seed[],
size_t nSeed,
fmi3Float64 sensitivity[],
size_t nSensitivity);``````

Both functions have the same arguments:

• `unknowns` contains value references to the unknowns.

• `nUnknowns` contains the length of argument `unknowns`.

• `knowns` contains value references of the knowns.

• `nKnowns` contains the length of argument `knowns`.

• `seed` contains the components of the seed vector.

• `nSeed` contains the length of `seed`.

• `sensitivity` contains the components of the sensitivity vector.

• `nSensitivity` contains the length of `sensitivity`.

[Note that array variables will be serialized, so `nSeed` is only equal to `nKnowns` in the case of directional derivatives (resp., equal to `nUnknowns` in the case of adjoint derivatives) if all value references of `knowns` (resp., `unknowns`) point to scalar variables. Likewise `nSensitivity` is only equal to `nUnknowns` (resp., `nKnowns`) if all value references of `unknowns` (resp., `knowns`) point to scalar variables.]

2.2.11.1. Directional Derivatives

[Example:
Assume an FMU has the output equations

$\begin{bmatrix} y_1 \\ y_2 \end{bmatrix} = \begin{bmatrix} g_1(x, u_1, u_3, u_4) \\ g_2(x, u_1) \end{bmatrix}$

and this FMU is connected, so that ${y_1, u_1, u_3}$ appear in an algebraic loop. Then the nonlinear solver needs a Jacobian and this Jacobian can be computed (without numerical differentiation) provided the partial derivative of ${y_1}$ with respect to ${u_1}$ and ${u_3}$ is available. Depending on the environment where the FMUs are connected, these `derivatives` can be provided:

(a) with one wrapper function around function `fmi3GetDirectionalDerivative` to compute the directional derivatives with respect to these two variables (in other words, ${v_{\mathit{unknown}} = y_1}$, ${v_{\mathit{known}} = \left \{ u_1, u_3 \right \}}$), and then the environment calls this wrapper function with ${v_{\mathit{seed}} = \left \{ 1, 0 \right \}}$ to compute the partial derivative with respect to ${u_1}$ and ${v_{\mathit{seed}} = \left \{ 0, 1 \right \}}$ to compute the partial derivative with respect to ${u_3}$, or

(b) with two direct function calls of `fmi3GetDirectionalDerivative` (in other words, ${v_{\mathit{unknown}} = y_1, v_{\mathit{known}} = u_1, v_{\mathit{seed}} = 1}$; and ${v_{\mathit{unknown}} = y_1, v_{\mathit{known}} = u_3, v_{\mathit{seed}} = 1}$).

Note that a direct implementation of this function with analytic derivatives:

(a) Provides the directional derivative for all `input` variables; so in the above example: ${\Delta y_1 = \frac{\partial g_1}{\partial x} \cdot \Delta x + \frac{\partial g_1}{\partial u_1} \cdot \Delta u_1 + \frac{\partial g_1}{\partial u_3} \cdot \Delta u_3 + \frac{\partial g_1}{\partial u_4} \cdot \Delta u_4}$

(b) Initializes all seed-values to zero; so in the above example: ${\Delta x = \Delta u_1 = \Delta u_3 = \Delta u_4 = 0}$

(c) Computes the directional derivative with the seed-values provided in the function arguments; so in the above example: ${v_{\mathit{sensitivity}} = \Delta y_1 (\Delta x = 0, \Delta u_1 = 1, \Delta u_3 = 0, \Delta u_4 = 0)}$] and ${v_{\mathit{sensitivity}} = \Delta y_1 (\Delta x = 0, \Delta u_1 = 0, \Delta u_3 = 1, \Delta u_4 = 0)}$]

[Note, function `fmi3GetDirectionalDerivative` can be utilized for the following purposes:

• Numerical integrators of stiff methods need matrix ${\frac{\partial \mathbf{f}}{\partial \mathbf{x}}}$.

• If the FMU is connected with other FMUs, the partial derivatives of the state derivatives and outputs with respect to the continuous states and the `inputs` are needed in order to compute the Jacobian for the system of the connected FMUs.

• If the FMU shall be linearized, the same `derivatives` as in the previous item are needed.

• If the FMU is used as the model for an extended Kalman filter, ${\frac{\partial \mathbf{f}}{\partial \mathbf{x}}}$ and ${\frac{\partial \mathbf{g}}{\partial \mathbf{x}}}$ are needed.

If a dense matrix shall be computed, the columns of the matrix can be easily constructed by successive calls of `fmi3GetDirectionalDerivative`. For example, constructing the system Jacobian ${\mathbf{A} = \frac{\partial \mathbf{f}}{\partial \mathbf{x}}}$ as dense matrix can be performed in the following way:

``````    //   c[]      column vector

// set time, states and inputs
CHECK_STATUS(S->fmi3SetTime(s, time))
CHECK_STATUS(S->fmi3SetContinuousStates(s, x, nx))
// fmi3Set{VariableType}(s, ...)

// if required at this step, compute the Jacobian as a dense matrix
for (i = 0; i < nx; i++) {
// construct the Jacobian matrix column wise
CHECK_STATUS(S->fmi3GetDirectionalDerivative(s, vr_dx, nx, &vr_x[i], 1, &dk, 1, c, nx))
for (j = 0; j < nx; j++) {
J[j][i] = c[j];
}
}``````

If the sparsity of a matrix shall be taken into account, then the matrix can be constructed in the following way:

• The incidence information of the matrix (whether an element is zero or not zero) is extracted from the XML file from element `<ModelStructure>`.

• A so called graph coloring algorithm is employed to determine the columns of the matrix that can be computed by one call of `fmi3GetDirectionalDerivative`. Efficient graph coloring algorithms are freely available, such as library ColPack written in C/C++ (LGPL), or the routines by [CGM84]. See e.g. http://www.netlib.org/toms/618.

• For the columns determined in (2), one call to `fmi3GetDirectionalDerivative` is made. After each such call, the elements of the resulting directional derivative vector are copied into their correct locations of the partial derivative matrix.

More details and implementational notes are available from [ABL12].

Example:

Directional derivatives for higher dimension variables are almost treated in the same way. Consider, for example, an FMU which calculates its output ${Y}$ by multiplying its 2x2 input ${U}$ with a 3x2 constant gain ${K}$, with

$K= \begin{bmatrix} a, b \\ c, d \\ e, f \end{bmatrix}$

The output ${Y=K U}$ is a matrix of size 3x2. The directional derivative of an output element ${Y(i,j)}$ with respect to the input ${U}$ and the seed ${\Delta U}$ is:

$\Delta Y(i,j) = \frac{\partial Y(i,j)}{\partial U(1,1)} \cdot \Delta U(1,1) + \frac{\partial Y(i,j)}{\partial U(1,2)} \cdot \Delta U(1,2) + \frac{\partial Y(i,j)}{\partial U(2,1)} \cdot \Delta U(2,1) + \frac{\partial Y(i,j)}{\partial U(2,2)} \cdot \Delta U(2,2)$
$\Delta \mathbf{Y} = \begin{bmatrix} a \Delta U(1,1)+b \Delta U(2,1), a \Delta U(1,2)+ b \Delta U(2,2) \\ c \Delta U(1,1)+d \Delta U(2,1), c \Delta U(1,2)+ d \Delta U(2,2) \\ e \Delta U(1,1)+f \Delta U(2,1), e \Delta U(1,2)+ f \Delta U(2,2) \end{bmatrix}$

To get the directional derivative of ${Y}$ with respect to ${U(2,1)}$ the command `fmi3GetDirectionalDerivative(m, vr_Y, 1, vr_U, 1, {0.0, 0.0, 1.0, 0.0}, 4, dd, 6)` can be used where `vr_Y` and `vr_U` are references of the variable ${Y}$ and ${U}$, respectively. Note that in order to get the directional derivative of ${Y}$ with respect to ${U(2,1)}$, the seed value `{0, 0, 1.0, 0}` has been used. The retrieved directional derivative `dd` is stored in a matrix of size 3x2, so `nSensitivity` is 6.

[Adjoint derivatives are beneficial in several contexts:

• in artificial intelligence (AI) frameworks the adjoint derivatives are called "vector gradient products" (VJPs). There adjoint derivatives are used in the backpropagation process to perform gradient-based optimization of parameters using reverse mode automatic differentiation (AD), see, e.g., [BPRS15].

• in parameter estimation (see [BKF17])

Typically, reverse mode automatic differentiation (AD) is more efficient for these use cases than forward mode AD, as explained in the cited references.

If one would like to construct the full Jacobian matrix, one can use either `fmi3GetDirectionalDerivative` (to column-wise construct it) or `fmi3GetAdjointDerivative` (to row-wise construct it, possibly improved with coloring methods as mentioned above). However in the applications motivating the adjoint derivatives, one does not need the full Jacobian matrix $\mathbf{J}$, but vector $\mathbf{v}^T$ multiplied from the left to the Jacobian, i.e. $\mathbf{v}^T\mathbf{J}$. For computing the full Jacobian matrix, the column-wise construct is generally more efficient.]

Example:
Assume an FMU has the output equations

$\begin{bmatrix} y_1 \\ y_2 \end{bmatrix} = \begin{bmatrix} h_1(u_1, u_2) \\ h_2(u_1, u_2) \end{bmatrix}$

and $\left( w_1, w_2 \right)^T \cdot \mathbf{ \frac{\partial h}{\partial u} }$ for some vector $\left( w_1, w_2 \right)^T$ is needed. Then one can get this with one function call of `fmi3GetAdjointDerivative` (with arguments $\mathbf{v}_{\mathit{unknown}} = \text{valueReferences of} \left \{ y_1, y_2 \right \}, \mathbf{v}_{\mathit{known}} = \text{valueReferences of} \left \{ u_1, u_2 \right \}, \mathbf{v}_{\mathit{seed}} = \left( w_1, w_2 \right)^T$ ), while with `fmi3GetDirectionalDerivative` at least two calls would be necessary to first construct the Jacobian column-wise and then multiplying from the right with $\left( w_1, w_2 \right)^T$ .

If a dense matrix shall be computed, the rows of the matrix can be easily constructed by successive calls of `fmi3GetAdjointDerivative`. For example, constructing the system Jacobian ${\mathbf{A} = \frac{\partial \mathbf{f}}{\partial \mathbf{x}}}$ as a dense matrix can be performed in the following way:

``````    for (i = 0; i < nx; i++) {
// construct the Jacobian matrix column wise
CHECK_STATUS(S->fmi3GetAdjointDerivative(s, &vr_dx[i], 1, vr_x, nx, &dk, 1, &J[i][0], nx))
}``````

]

2.2.12. Getting Derivatives of Continuous Outputs

In FMI for Co-Simulation, the n-th `derivatives` with respect to time of continuous `outputs` can be retrieved with `fmi3GetOutputDerivatives` to allow interpolation/extrapolation of connected input variables between communication points by the importer in Intermediate Update Mode.

Whether the FMU is able to provide the `derivatives` of `outputs` is given by the unsigned integer capability flag `maxOutputDerivativeOrder` that represents the maximum order of the `output` `derivatives`. If the actual order is lower (because the order of integration algorithm is low), the retrieved value is 0.

Restrictions on calling the function are the same as for the `fmi3Get{VariableType}` function for `continuous` `outputs`. The returned values correspond to the current time of the FMU. For example, after a successful call to `fmi3DoStep`, the returned values are related to the end of the communication step.

Function `fmi3GetOutputDerivatives`
``````typedef fmi3Status fmi3GetOutputDerivativesTYPE(fmi3Instance instance,
const fmi3ValueReference valueReferences[],
size_t nValueReferences,
const fmi3Int32 orders[],
fmi3Float64 values[],
size_t nValues);``````
• `valueReferences` is a vector of value references that define the variables whose `derivatives` shall be retrieved. If multiple derivatives of a variable shall be retrieved, list the value reference multiple times.

• `nValueReferences` is the dimension of the arguments `valueReferences` and `orders`.

• `orders` contains the orders of the respective `derivative` (1 means the first `derivative`, 2 means the second `derivative`, …​, 0 is not allowed). If multiple derivatives of a variable shall be retrieved, provide a list of them in the `orders` array, corresponding to a multiply occurring value reference in the `valueReferences` array.

• `values` is a vector with the values of the `derivatives`. The order of the `values` elements is derived from a twofold serialization: the outer level corresponds to the combination of a value reference (e.g., `valueReferences[k]`) and order (e.g., `orders[k]`), and the inner level to the serialization of variables as defined in Section 2.2.6.1. The inner level does not exist for scalar variables.

• `nValues` is the size of the argument `values`. `nValues` only equals `nValueReferences` if all corresponding output variables are scalar variables.

[ Example:
Assuming an FMU has outputs $y_1$[2*3] with value reference 1, $y_2$ with value reference 2, $y_3$[2] value reference 3, $y_4$ with value reference 4 and `maxOutputDerivativeOrder`=2.
With `valueReferences`= [1, 1, 3, 3, 4, 4], and `orders`= [1, 2, 1, 2, 1, 2], `fmi3GetOutputDerivatives` will provide first and second time derivatives of the outputs y1, y3, y4, which in `values` are serialized in the following way: ((array serialization of $\dot y_1$), (array serialization of $\ddot y_1$), (array serialization of $\dot y_3$), (array serialization of $\ddot y_3$), $\dot y_4$, $\ddot y_4$)
If the internal polynomial is of order 1 and the importer inquires the second `derivative` of an `output`, the FMU will return zero.]

2.3. State Machine and Semantics

To define allowed calling sequences of FMI functions, state machines are used. Each state of the state machine corresponds to a certain phase of a simulation. All interface types share a number of states in their respective state machines. This chapter describes these common states used in at least two of the interface types. State-machine states specific to a single interface type will be described in their respective chapters.

Each state description lists the governing equations and actions and the corresponding API functions influencing these equations in a table (not defining the calling order), and also lists the allowed function calls and usage restrictions.

Figure 6. Common calling sequence for C functions of common states for all three FMI types.

The state machine is given here as UML 2.0 state machine. If a transition is labeled with one or more function names (for example, `fmi3EnterInitializationMode`, `fmi3EnterEventMode`), the transition is taken if the function call returns successfully (not `NULL` for `fmi3InstantiateXXX` or `fmi3OK` and `fmi3Warning` for all other functions). This way, importer and FMU can determine in which state the FMU is.

2.3.1. Super State: FMU State Setable

The state FMU State Setable is entered when any of the following functions is called: `fmi3InstantiateModelExchange`, `fmi3InstantiateCoSimulation` and `fmi3InstantiateScheduledExecution`. The state is left by either calling `fmi3FreeInstance` or when any of the functions called during FMU State Setable returns `fmi3Fatal`. If any function called in super state FMU State Setable returns `fmi3Error`, the FMU enters state Terminated.

Allowed Function Calls to enter this Super State
Function `fmi3InstantiateModelExchange`

This function instantiates a Model Exchange FMU (see Section 3). It is allowed to call this function only if `modelDescription.xml` includes a `<ModelExchange>` element.

Function `fmi3InstantiateCoSimulation`

This function instantiates a Co-Simulation FMU (see Section 4). It is allowed to call this function only if `modelDescription.xml` includes a `<CoSimulation>` element.

Function `fmi3InstantiateScheduledExecution`

This function instantiates a Scheduled Execution FMU (see Section 5). It is allowed to call this function only if `modelDescription.xml` includes a `<ScheduledExecution>` element.

``````typedef fmi3Instance fmi3InstantiateModelExchangeTYPE(
fmi3String                 instanceName,
fmi3String                 instantiationToken,
fmi3String                 resourcePath,
fmi3Boolean                visible,
fmi3Boolean                loggingOn,
fmi3InstanceEnvironment    instanceEnvironment,
fmi3CallbackLogMessage     logMessage);

typedef fmi3Instance fmi3InstantiateCoSimulationTYPE(
fmi3String                     instanceName,
fmi3String                     instantiationToken,
fmi3String                     resourcePath,
fmi3Boolean                    visible,
fmi3Boolean                    loggingOn,
fmi3Boolean                    eventModeUsed,
fmi3Boolean                    earlyReturnAllowed,
const fmi3ValueReference       requiredIntermediateVariables[],
size_t                         nRequiredIntermediateVariables,
fmi3InstanceEnvironment        instanceEnvironment,
fmi3CallbackLogMessage         logMessage,
fmi3CallbackIntermediateUpdate intermediateUpdate);

typedef fmi3Instance fmi3InstantiateScheduledExecutionTYPE(
fmi3String                     instanceName,
fmi3String                     instantiationToken,
fmi3String                     resourcePath,
fmi3Boolean                    visible,
fmi3Boolean                    loggingOn,
const fmi3ValueReference       requiredIntermediateVariables[],
size_t                         nRequiredIntermediateVariables,
fmi3InstanceEnvironment        instanceEnvironment,
fmi3CallbackLogMessage         logMessage,
fmi3CallbackIntermediateUpdate intermediateUpdate,
fmi3CallbackLockPreemption     lockPreemption,
fmi3CallbackUnlockPreemption   unlockPreemption);``````

These functions return a new instance of an FMU with the respective interface type. If a NULL pointer is returned, then instantiation failed. In that case, `logMessage` is called with detailed information about the reason. An FMU can be instantiated many times (provided capability flag `canBeInstantiatedOnlyOncePerProcess = false`).

The arguments of the instantiation functions are detailed as follows:

• `instanceName` is a unique identifier for the FMU instance. It is used to name the instance, for example, in error or information messages generated by one of the `fmi3XXX` functions. The argument `instanceName` must be a non empty string (in other words, must have at least one character that is not a white space). [If only one FMU is simulated, as `instanceName` attribute `modelName` or `<ModelExchange|CoSimulation|ScheduledExecution modelIdentifier="..">` from the XML schema `fmi3ModelDescription` might be used.]

• `instantiationToken` can be used by the FMU to check that the `modelDescription.xml` file (see Section 2.5) is compatible with the implementation of the FMU. It is an opaque string generated by the FMU exporter that is stored in the xml file as mandatory attribute `instantiationToken` (see Section 2.4.1). It must be passed unchanged to the FMU. This argument must not be a NULL pointer.

• `resourcePath` is the absolute file path (with a trailing file separator) of the `resources` directory of the extracted FMU archive.
[Example: An FMU is extracted to the directory `C:\temp\MyFMU`, then `resourcePath` = `C:\temp\MyFMU\resources\`.]
`resourcePath` must be `NULL`, if no resource path can be provided to the FMU, which may occur if

• the FMU does not contain a `resources` folder, or

• the environment is not able to provide the file path to the resources folder [e.g., if the environment does not have a file system. If the FMU in such a case cannot be simulated, as it depends on the resources folder, it shall terminate with an error.]

• `visible == fmi3False` defines that the interaction with the user should be reduced to a minimum (no application window, no plotting, no animation, etc.). In other words, the FMU is executed in batch mode. If `visible == fmi3True`, the FMU is executed in interactive mode, and the FMU might require to explicitly acknowledge start of simulation / instantiation / initialization (acknowledgment is non-blocking).

• If `loggingOn == fmi3False`, then any logging is disabled and the `logMessage` callback function is not called by the FMU. If `loggingOn == fmi3True`, the FMU enables a vendor defined set of `<LogCategories>`. This set should typically contain categories for messages that explain execution errors, like `fmi3Discard`, `fmi3Error` and `fmi3Fatal`. The function `fmi3SetDebugLogging` gives more detailed control about required `<LogCategories>` (see Section 2.4.5).

• If `eventModeUsed == fmi3True` the importer can handle events, otherwise `fmi3EnterEventMode` must not be called. The flag may only be `fmi3True`, if `hasEventMode == true`, otherwise the FMU must raise an error. For FMUs that have clocks, `eventModeUsed == fmi3True` is required.

• If `earlyReturnAllowed == fmi3True` the importer can handle early return. Only in this case, `fmi3DoStep` may return with `earlyReturn == fmi3True`.

• `instanceEnvironment` is a pointer that can be passed to the `fmi3CallbackIntermediateUpdate` function in order that the simulation environment can provide an efficient way to identify the FMU that called `fmi3CallbackIntermediateUpdate`.

• `requiredIntermediateVariables` is an array of the value references of all `input` variables that the simulation algorithm intends to set and all `output` variables it intends to get during intermediate updates. This set may be empty (`nRequiredIntermediateVariables` == 0) when the simulation algorithm does not intend to use intermediate update. Only the variables in `requiredIntermediateVariables` may be accessed by the simulation algorithm using `fmi3Set{VariableType}` and `fmi3Get{VariableType}` during `fmi3CallbackIntermediateUpdate` callbacks. All variables referenced in this set must be marked with the attribute `intermediateUpdate = "true"` in the model description. For Co-Simulation, these intermediate variables must be continuous-time variables.

• `nRequiredIntermediateVariables` gives the number of entries in `requiredIntermediateVariables`. If `nRequiredIntermediateVariables` is zero `requiredIntermediateVariables` is not defined.

• Callback function `logMessage`

``````typedef void  (*fmi3CallbackLogMessage) (fmi3InstanceEnvironment instanceEnvironment,
fmi3String instanceName,
fmi3Status status,
fmi3String category,
fmi3String message);``````

Pointer to a function that is called by the FMU [usually if an `fmi3XXX` function does not behave as desired].

• `instanceName` is the name of the FMU instance that calls this function.

• `status` contains the severity of the message, see `fmi3Status`. If `status == fmi3OK`, the message is a pure information message.

• `category` is the category of the message. The allowed values for `category` are defined in the `modelDescription.xml` file via the element `<LogCategories>`. `logMessage` should only be called for log categories that were enabled by a call to `fmi3SetDebugLogging` or via `loggingOn == fmi3True` in `fmi3InstantiateXXX`. If the FMU does not define any log categories, `category` must be `NULL`.

• `message` is a string that contains the message to log. It may contain line-breaks (`\n`), but should not have a trailing line break.

All string-valued arguments passed by the FMU to the `logMessage` may be deallocated by the FMU directly after function `logMessage` returns. [The simulation environment must therefore create copies of these strings if it needs to access these strings later.]
Variables can be referenced in a message with `#<ValueReference>#`. If the character `#` shall be included in the message, it has to be prefixed with `#`, so `#` is an escape character.
[Example: The message `#1365# must be larger than zero (used in IO channel ##4)` might be changed by the `logMessage` function to `body.m must be larger than zero (used in IO channel #4)` if `body.m` is the name of the variable with value reference 1365.]

• Callback function `intermediateUpdate`
See `fmi3CallbackIntermediateUpdate` for details.

• Callback function lockPreemption and unlockPreemption
See Section 5.1.2 for details.

The arguments `logMessage`, `intermediateUpdate`, `lockPreemption`, and `unlockPreemption`, are function pointers provided by the simulation environment to be used by the FMU. Each of these pointers can be NULL to indicate missing support for the respective functionality. It is not allowed to change these functions between `fmi3InstantiateXXX` and `fmi3Terminate` calls. Additionally, a pointer to the environment is provided (`instanceEnvironment`) that needs to be passed to all of the callback functions, in order that those functions can utilize data from the environment, such as mapping a `valueReference` to a string, or assigning memory to a certain FMU instance.

Allowed Function Calls
Function `fmi3SetDebugLogging`
``````typedef fmi3Status fmi3SetDebugLoggingTYPE(fmi3Instance instance,
fmi3Boolean loggingOn,
size_t nCategories,
const fmi3String categories[]);``````

The function controls the debug logging that is output via the `logMessage` callback function by the FMU.

• If `loggingOn == fmi3True`, debug logging is enabled for the log categories specified in `categories`, otherwise it is disabled.

• `nCategories` defines the length of the argument `categories`.

• If `nCategories == 0`, `loggingOn` applies to all log categories and the value of `categories` is undefined.

• `categories` is an array of `nCategories` elements. The allowed values of `categories` are defined in the modelDescription.xml via element `<LogCategories>`.

Function `fmi3Reset`
``typedef fmi3Status fmi3ResetTYPE(fmi3Instance instance);``

Is called by the environment to reset the FMU after a simulation run. The FMU goes into the same state as if `fmi3InstantiateXXX` would have been called. All variables have their default values. Before starting a new run `fmi3EnterInitializationMode` has to be called.

Function `fmi3FreeInstance`
``typedef void fmi3FreeInstanceTYPE(fmi3Instance instance);``

Disposes the given instance, unloads the loaded model, and frees all the allocated memory and other resources that have been allocated by the functions of the FMU interface. If a NULL pointer is provided for argument `instance`, the function call is ignored (does not have an effect).

Function `fmi3GetFMUState`
Function `fmi3SetFMUState`
Function `fmi3FreeFMUState`
Function `fmi3SerializedFMUStateSize`
Function `fmi3SerializeFMUState`
Function `fmi3DeSerializeFMUState`

All these allowed functions are described in Section 2.2.6.4.

2.3.2. State: Instantiated

In the state Instantiated the FMU can do one-time initializations and allocate memory.

Equations and Actions Functions Influencing Equations

Set variables $(\mathbf{v}_{\mathit{initial=exact}}$ or $\mathbf{v}_{\mathit{initial=approx}})$ and $\mathbf{v}_{\mathit{variability \neq constant}}$

`fmi3Set{VariableType}`

Get variable `start` values as defined in `modelDescription.xml`.

`fmi3Get{VariableType}`

• $\mathbf{t}_{\mathit{start}} := ($`startTime`$,0)$

• Activate initialization equations $\mathbf{f}_{\mathit{init}}$.

`fmi3EnterInitializationMode`

Allowed Function Calls
Function `fmi3Set{VariableType}`

This function can be called for variables with `variability` $\neq$ `constant` and with `initial` = `exact` or `approx`. The intention is to set `start` and guess values for these variables.

Function `fmi3EnterConfigurationMode`
``typedef fmi3Status fmi3EnterConfigurationModeTYPE(fmi3Instance instance);``

If the importer needs to change `structural parameters`, it must move the FMU into Configuration Mode using `fmi3EnterConfigurationMode`.

Function `fmi3GetNumberOfContinuousStates`
``````typedef fmi3Status fmi3GetNumberOfContinuousStatesTYPE(fmi3Instance instance,
size_t* nContinuousStates);``````

This function returns the number of continuous states.
This function can only be called in Model Exchange.

• Argument `nContinuousStates` points to the `size_t` variable that will receive the number of states.

The number of continuous states might change if a variable representing a state has a `<Dimension>` element that references a `structural parameter` (see Configuration Mode and Reconfiguration Mode). `fmi3GetNumberOfContinuousStates` must be called after such `structural parameters` changed. As long as no `structural parameters` changed, the number of states is given in the `modelDescription.xml`, alleviating the need to call this function.

Function `fmi3GetNumberOfEventIndicators`
``````typedef fmi3Status fmi3GetNumberOfEventIndicatorsTYPE(fmi3Instance instance,
size_t* nEventIndicators);``````

This function returns the number of event indicators.
This function can only be called in Model Exchange.

• Argument `nEventIndicators` points to the `size_t` variable that will receive the number of event indicators.

The initial value of `nEventIndicators` is the sum of the sizes of the variables referenced by the `<EventIndicator>` elements. The number of event indicators might change if a variable related to event indicators has a `<Dimension>` that references a `structural parameter` (see Configuration Mode and Reconfiguration Mode). `fmi3GetNumberOfEventIndicators` must be called after such `structural parameters` changed. As long as no `structural parameters` changed, the number of event indicators is given in the `modelDescription.xml`, alleviating the need to call this function.

Function `fmi3EnterInitializationMode`
``````typedef fmi3Status fmi3EnterInitializationModeTYPE(fmi3Instance instance,
fmi3Boolean toleranceDefined,
fmi3Float64 tolerance,
fmi3Float64 startTime,
fmi3Boolean stopTimeDefined,
fmi3Float64 stopTime);``````

Changes state to Initialization Mode.

2.3.3. State: Initialization Mode

The Initialization Mode is used by the simulation algorithm to compute consistent initial conditions for the overall system. Equations are active to determine the initial FMU state, as well as all `outputs` (and optionally other variables exposed by the exporting tool). Artificial or real algebraic loops over connected FMUs in Initialization Mode may be handled by using appropriate numerical algorithms.

In Initialization Mode, the FMU computes initial values at the start time $\mathbf{t}_\mathit{start}$ using function $\mathbf{f}_\mathit{init}$, not present in the other modes, for example, equations to define the `start` value for a `state` or for the derivative of a `state`.

Equations and Actions Functions Influencing Equations

Set variables $\mathbf{v}_{\mathit{initial=exact}}$
[`parameters` $\mathbf{p}$ and continuous-time `states` $\mathbf{x}_{c,\mathit{initial=exact}}$ are included here]

`fmi3Set{VariableType}`

Set continuous-time and discrete-time `inputs` $\mathbf{u}_{c+d}(\mathbf{t}_{start})$

`fmi3Set{VariableType}`

$(\mathbf{y}_{c+d}, \mathbf{\dot{x}}_c, \mathbf{x}_{c+d}, ^{\bullet}\mathbf{x}_d, \mathbf{z}, \mathbf{r}, \mathbf{w}_{c+d}, \mathbf{b}, \mathbf{T}_{\mathit{shift}}, \mathbf{T}_\mathit{interval}) := \mathbf{f}_{\mathit{init}}(\mathbf{u}_{c+d}, \mathbf{t}_{start}, \mathbf{v}_{\mathit{initial=exact}})$

• Evaluate $\mathbf{f}_{\mathit{init}}$, if no `fmi3GetXXX` function was called

• Deactivate initialization equations $\mathbf{f}_{\mathit{init}}$

• Update previous values of buffers: ${}^\bullet\mathbf{b}:=\mathbf{b}$

• Model Exchange:

• Activate event equations $\mathbf{f}_{\mathit{event}}$

• $\mathbf{t}:=(\mathbf{t}_{\mathit{start}}, 0)$

`fmi3ExitInitializationMode`

Allowed Function Calls
Function `fmi3Set{VariableType}`

This function can be called for variables with `variability` $\neq$ `constant` and with `initial` = `exact`.

Functions `fmi3Get{VariableType}`

Getting variables might trigger computations.

Function `fmi3GetContinuousStateDerivatives`

See `fmi3GetContinuousStateDerivatives` for Model Exchange only.

Function `fmi3GetContinuousStates`

In Model Exchange only:

``````typedef fmi3Status fmi3GetContinuousStatesTYPE(fmi3Instance instance,
fmi3Float64 continuousStates[],
size_t nContinuousStates);``````

Return the current continuous state vector.

• Return argument `continuousStates` contains the values for each continuous state with the same convention for the order as defined for `fmi3SetContinuousStates`.

• Argument `nContinuousStates` is the size of the `continuousStates` vector.

Function `fmi3GetNominalsOfContinuousStates`
``````typedef fmi3Status fmi3GetNominalsOfContinuousStatesTYPE(fmi3Instance instance,
fmi3Float64 nominals[],
size_t nContinuousStates);``````

Return the nominal values of the continuous `states`. This function can only be called in Model Exchange.

• Return argument `nominals` contains the nominal values for each continuous state with the same convention for the order as defined for `fmi3SetContinuousStates`. If the FMU does not have information about the nominal value of a continuous `state` `i`, a nominal value `nominals[i] == 1.0` should be returned. It is required that `nominals[i] > 0.0`.

• Argument `nContinuousStates` is the size of the `nominals` vector.

This function should always be called after calling function `fmi3UpdateDiscreteStates`, if `nominalsOfContinuousStatesChanged == fmi3True`, since then the nominal values of the continuous `states` have changed [for example, because the mapping of the continuous `states` to variables has changed because of internal dynamic state selection].

Function `fmi3GetDirectionalDerivative`

See `fmi3GetDirectionalDerivative`. This call is not allowed in Scheduled Execution.

Function `fmi3GetAdjointDerivative`

See `fmi3GetAdjointDerivative`. This call is not allowed in Scheduled Execution.

Function `fmi3GetEventIndicators`
Function `fmi3GetShiftDecimal`
Function `fmi3GetShiftFraction`
Function `fmi3GetIntervalDecimal`
Function `fmi3GetIntervalFraction`
Function `fmi3SetIntervalDecimal`
Function `fmi3SetIntervalFraction`

One of these functions must be called for all Fixed periodic Clocks.

Function `fmi3ExitInitializationMode`
``typedef fmi3Status fmi3ExitInitializationModeTYPE(fmi3Instance instance);``

Changes the state to Event Mode (ME), Step Mode (CS) or Clock Activation Mode (SE).

2.3.4. Super State: Initialized

This super state is entered by the FMU when `fmi3ExitInitializationMode` is called.

Equations and Actions Functions Influencing Equations

Activate termination equations $\mathbf{f}_{\mathit{term}}$.

`fmi3Terminate`

Allowed Function Calls
Function `fmi3GetNominalsOfContinuousStates`
Function `fmi3Terminate`
``typedef fmi3Status fmi3TerminateTYPE(fmi3Instance instance);``

Changes state to Terminated.

2.3.5. State: Event Mode

Event Mode is only available in Model Exchange and Co-Simulation. In Event Mode all continuous-time, discrete-time equations and active model partitions are evaluated.

There are multiple kinds of events that require a transition to Event Mode:

Equations and Actions Functions Influencing Equations

Set `tunable` `parameters` $\mathbf{p}_{\mathit{variability == tunable}}$

`fmi3Set{VariableType}`

Set continuous-time and discrete-time `inputs` $\mathbf{u}_{c+d}$

`fmi3Set{VariableType}`

• Activate clocks and output equations of the respective model partitions.

• Deactivate clocks and

• Reset respective clocked variables to their previous values: $\mathbf{v}_{\mathit{k}} := {}^\bullet\mathbf{v}_{\mathit{k}}$, and

• Deactivate respective model partitions in $\mathbf{f}_{\mathit{event}}$.

`fmi3SetClock`

• If `providesEvaluateDiscreteStates` is `true`, then execute state transition function of the model partitions
$(\mathbf{x}_{d}) := \mathbf{f}_{\mathit{disc}}({}^\bullet\mathbf{x}_{c+d}, \mathbf{u}_{c+d}, \mathbf{p}, {}^\bullet\mathbf{b}, \mathbf{t})$

• else function is ignored.

• For all active Clocks $\mathbf{k}$, the clocked variables $\mathbf{v}_k$ are part of the set of discrete variables $\mathbf{v}_d$ computed by $\mathbf{f}_{\mathit{disc}}$.

`fmi3EvaluateDiscreteStates`

• Computes $\mathbf{f}_{\mathit{event}}$ depending on

• if `providesEvaluateDiscreteStates` is `true`, then
$(\mathbf{y}_{c+d}, \mathbf{\dot{x}}_c, \mathbf{x}_{c}, \mathbf{z}, \mathbf{r}, \mathbf{w}_{c+d}, \mathbf{b}, \mathbf{T}_{\mathit{next}}) := \mathbf{f}_{\mathit{event}}({}^\bullet\mathbf{x}_{c+d}, \mathbf{x}_{d}, \mathbf{u}_{c+d}, \mathbf{p}, {}^\bullet\mathbf{b}, \mathbf{t})$

• else
$(\mathbf{y}_{c+d}, \mathbf{\dot{x}}_c, \mathbf{x}_{c+d}, \mathbf{z}, \mathbf{r}, \mathbf{w}_{c+d}, \mathbf{b}, \mathbf{T}_{\mathit{next}}) := \mathbf{f}_{\mathit{event}}({}^\bullet\mathbf{x}_{c+d}, \mathbf{u}_{c+d}, \mathbf{p}, {}^\bullet\mathbf{b}, \mathbf{t})$
which includes $\mathbf{f}_{\mathit{disc}}$.

• For all active Clocks $\mathbf{k}$, the clocked variables $\mathbf{v}_k$ are part of the set of discrete variables $\mathbf{v}_d$ computed by $\mathbf{f}_{\mathit{event}}$.

• Signals end of super-dense time instant.

• Compute

• $(\mathbf{T}_\mathit{interval}) := \mathbf{f}_{\mathit{update}}({}^\bullet\mathbf{x}_{c+d}, \mathbf{u}_{c+d}, \mathbf{p}, {}^\bullet\mathbf{b}, \mathbf{t})$

• Update previous values of discrete states: ${}^\bullet\mathbf{x}_d:=\mathbf{x}_d$.

• Update previous values of buffers: ${}^\bullet\mathbf{b}:=\mathbf{b}$.

• Deactivate active clocks and respective model partitions.

• Increment super-dense time: $\mathbf{t}:=(\mathbf{t}_\mathit{R}, \mathbf{t}_\mathit{I} + 1)$.

`fmi3UpdateDiscreteStates`

• Update previous values of relations: ${}^\bullet\mathbf{r}:=\mathbf{r}$.

• Deactivate event equations $\mathbf{f}_\mathit{event}$.

• Model Exchange: Activate continuous-time equations $\mathbf{f}_\mathit{cont}$.

Allowed Function Calls
Function `fmi3Set{VariableType}`

This function can be called for variables with `causality == input` and for variables with `causality == parameter` and `variability == tunable`.

Functions `fmi3Get{VariableType}`

Getting variables might trigger computations.

Function `fmi3SetClock`

For `input Clocks`, `fmi3SetClock` is called to set the activation status of `Clocks` to `fmi3ClockActive` or `fmi3ClockInactive`. During the solution of algebraic loops, the activation condition of triggered input clocks may change and therefore `fmi3SetClock` can be called multiple times per super-dense time instant. When a Clock is deactivated, the FMU must reset all clocked states of this Clock to the values computed during the last `fmi3UpdateDiscreteStates` when this Clock was active (${}^\bullet\mathbf{v}_{\mathit{k}}$).
[Rationale: a triggered output Clock $c$ may depend on some variable $v$ that is involved in an algebraic loop. As part of the iterations to solve the algebraic loop, $v$ acquires a value that activates the Clock. If the final (or some intermediate) value of $v$ no longer activates the Clock, then this Clock must be deactivated by the Importer during the same super-dense time instant.]
A Clock can only be set to inactive once activated if the attribute `canBeDeactivated == true`.
Only time-based Clocks must not be active for more than one call of `fmi3UpdateDiscreteStates` per Event Mode. The importer must ensure that coinciding time-based Clocks are activated at the same instant of super-dense time.
[The event iteration for handling discontinuities of the continuous part of the FMU should precede handling of time-based Clocks. For that reason no further constraints on activations of time-based Clocks are defined (e.g. activating at the first instant of super-dense time).]

Function `fmi3GetClock`

is used to inquire the status of Clocks.

Function `fmi3GetIntervalDecimal`
Function `fmi3GetIntervalFraction`

For `input Clocks` it is allowed to call these functions to query the next activation interval.
For changing aperiodic Clock, these functions must be called in every Event Mode where this clock was activated.
For countdown aperiodic Clock, these functions must be called in every Event Mode.
Clock intervals are computed in `fmi3UpdateDiscreteStates` (at the latest), therefore, these functions should be called after `fmi3UpdateDiscreteStates`.

Function `fmi3GetDirectionalDerivative`
Function `fmi3GetAdjointDerivative`
Function `fmi3GetContinuousStates`

This function must be called if `fmi3UpdateDiscreteStates` returned with `valuesOfContinuousStatesChanged == fmi3True`. Can only be called in Model Exchange.

Function `fmi3GetContinuousStateDerivatives`
Function `fmi3GetEventIndicators`
Function `fmi3GetNumberOfContinuousStates`
Function `fmi3GetNumberOfEventIndicators`

Can only be called in Model Exchange.

Function `fmi3EvaluateDiscreteStates`

The FMU signals the support of `fmi3EvaluateDiscreteStates` via the capability flag `providesEvaluateDiscreteStates`. Evaluate $\mathbf{f}_{\mathit{disc}}$ to obtain current values of discrete states from previous values.

``typedef fmi3Status fmi3EvaluateDiscreteStatesTYPE(fmi3Instance instance);``
Function `fmi3UpdateDiscreteStates`

When the importer converges on a solution for event handling at the current super-dense time step it calls `fmi3UpdateDiscreteStates` to determine if another event iteration is required (introducing a new super-dense time instant) or Event Mode can be exited.

``````typedef fmi3Status fmi3UpdateDiscreteStatesTYPE(fmi3Instance instance,
fmi3Boolean* discreteStatesNeedUpdate,
fmi3Boolean* terminateSimulation,
fmi3Boolean* nominalsOfContinuousStatesChanged,
fmi3Boolean* valuesOfContinuousStatesChanged,
fmi3Boolean* nextEventTimeDefined,
fmi3Float64* nextEventTime);``````
• When `discreteStatesNeedUpdate == fmi3True`, the importer must stay in Event Mode for another event iteration.

Function `fmi3EnterContinuousTimeMode`
``typedef fmi3Status fmi3EnterContinuousTimeModeTYPE(fmi3Instance instance);``

This function must be called to change from Event Mode into Continuous-Time Mode in Model Exchange.

Function `fmi3EnterStepMode`
``typedef fmi3Status fmi3EnterStepModeTYPE(fmi3Instance instance);``

This function must be called to change from Event Mode into Step Mode in Co-Simulation.

2.3.6. State: Configuration Mode

The Configuration Mode allows setting `structural parameters` for example to resize array variables. `fmi3EnterConfigurationMode` must not be called if the FMU contains no `structural parameter`.

Equations and Actions Functions Influencing Equations

Set $\mathbf{v}_{\mathit{causality=structuralParameter}}$
[`structuralParameters` with $\mathbf{p}_{\mathit{variability=fixed}}$ or $\mathbf{p}_{\mathit{variability=tunable}}$ are included here]

`fmi3Set{VariableType}`

Resize arrays with dimensions that just changed.

`fmi3ExitConfigurationMode`

Function `fmi3ExitConfigurationMode`
``typedef fmi3Status fmi3ExitConfigurationModeTYPE(fmi3Instance instance);``

Exits the Configuration Mode and returns to state Instantiated.

2.3.7. State: Reconfiguration Mode

The Reconfiguration Mode allows setting `tunable` `structural parameters` for example to resize array variables during the simulation. This state must not be entered, if the FMU contains no `tunable` `structural parameters`.

Equations and Actions Functions Influencing Equations

Set $\mathbf{v}_{\mathit{causality=structuralParameter}}$
[`structuralParameters` with $\mathbf{p}_{\mathit{variability=tunable}}$ are included here]

`fmi3Set{VariableType}`

Resize arrays with dimensions that just changed.

`fmi3ExitConfigurationMode`

2.3.8. State: Intermediate Update Mode

This state is only available in Co-Simulation and Scheduled Execution.

[The following use cases are enabled:

• Access to intermediate variables enables advanced Co-Simulation with interpolation/extrapolation techniques (such as polynomial extrapolation, Transmission Line Modeling (TLM) co-simulation, anti-alias filtering, smoothing of input among others).

• Intermediate Update Mode enables the same input approximation that was possible in FMI 2.0 with `fmi2SetInputDerivatives`, by evaluation of the approximation polynomial by the importer and not within the FMU as in FMI 2.0

• FMUs can inform the importer about an event, which occurs during an `fmi3DoStep` in case of CS (see Section 4).

• The Co-Simulation algorithm can request an early return from `fmi3DoStep`, because of an event between communication points (see Section 4.1.2).

• A model partition of a Scheduled Execution FMU calls `fmi3CallbackIntermediateUpdate` to signal clock activations with `clocksTicked == fmi3True`.

Note that the call to `fmi3CallbackIntermediateUpdate` and thus entering the Intermediate Update Mode can only be triggered by the FMU itself. The importer cannot actively trigger this and hence for some use cases (e.g. cooperative multitasking and setting of intermediate input values) it relies on the callbacks from the FMUs to be able to realize these use cases properly.]

A Co-Simulation FMU can provide values for its `output` variables at intermediate points between two consecutive communication points, and is able to receive new values for `input` variables at these intermediate points. This is typically required when the FMU uses a numerical solver to integrate the FMU’s internal state between communication points in `fmi3DoStep`. This numerical solver assumes that the inputs are continuous in the integration interval, dictated by `fmi3DoStep`. In FMI 2.0 Co-simulation, the intermediate inputs are provided by the use of extrapolations. The intermediate update functions allow FMUs to receive inputs, and provide outputs, directly to the co-simulation algorithm, in those intermediate time points.

Intermediate values for `continuous` inputs are computed by the importer for example by an extrapolation polynomial build with the output derivatives of connected FMUs. FMUs can signal with the optional attribute `recommendedIntermediateInputSmoothness` of value $k$ to the co-simulation algorithm that best convergence rates can be achieved if these approximation functions are of smoothness $C^{k}([\mathbf{t}_i, \mathbf{t}_{i+1}])$, that is k-time continuously differentiable, with $C^{0}$ meaning continuous.
[This can increase simulation speed for higher order multi-step solvers that in this case do not have to reset at communication points.]

The importer must ensure that the input approximation function $\mathbf{u}_u$ is consistent with the values of the input variable ($\mathbf{u}_u(\mathbf{t}_{i+1})= \mathbf{u}(\mathbf{t}_{i+1})$).

Due to the way numerical solvers estimate and correct the approximation error, these intermediate `output` values may be tentative or may be final. It is possible for the FMU to inform the co-simulation algorithm whether the internal solver is in a tentative state, meaning that the output values computed from that state are also tentative, or if the internal solver has successfully completed the integration step, meaning that the FMU’s internal state is final, and will never be changed in the current execution of `fmi3DoStep`. If the internal integration step has been successfully completed, the co-simulation algorithm can forward intermediate outputs to other FMUs, where they can be used, for e.g., for extrapolation, interpolation, filtering or asynchronous co-simulation.

Figure 7 summarizes the above description. It illustrates multiple intermediate internal solver steps, distinguishing between the final ones (with black-filled circles) and tentative ones (with white-filled circles). It distinguishes the level of trust that can be placed in the tentative outputs (with dashed arrows) and in final outputs (with solid arrows).

Figure 7. Overview of solver states and intermediate update during a communication step

The FMU signals the support of Intermediate Update Mode via the capability flag `providesIntermediateUpdate`. The co-simulation algorithm signals the support for Intermediate Update Mode by providing a non-NULL callback-function pointer for `intermediateUpdate`.

The FMU enters Intermediate Update Mode by calling `fmi3CallbackIntermediateUpdate` within Step Mode (CS) or Clock Activation Mode (SE) and leaves the state towards Step Mode (CS) or Clock Activation Mode (SE) when the function returns.

``````typedef void (*fmi3CallbackIntermediateUpdate) (
fmi3InstanceEnvironment instanceEnvironment,
fmi3Float64  intermediateUpdateTime,
fmi3Boolean  clocksTicked,
fmi3Boolean  intermediateVariableSetRequested,
fmi3Boolean  intermediateVariableGetAllowed,
fmi3Boolean  intermediateStepFinished,
fmi3Boolean  canReturnEarly,
fmi3Boolean* earlyReturnRequested,
fmi3Float64* earlyReturnTime);``````
Table 10. Mathematical description of Intermediate Update Mode.
Equations and Actions Functions Influencing Equations

Get intermediate variable values $\mathbf{v}_u(\mathbf{t}_u)$

`fmi3Get{VariableType}`

Get time derivatives of `continuous` `outputs` $\mathbf{y}_\mathit{c,u}^{(j)}(\mathbf{t_\mathit{u}})$.

`fmi3GetOutputDerivatives`

• Co-Simulation: Set continuous intermediate input variables $\mathbf{u}_{\mathit{c,u}}(\mathbf{t}_u)$

• Scheduled Execution: Set intermediate input variables $\mathbf{u}_u(\mathbf{t}_u)$

`fmi3Set{VariableType}`

Allowed Function Calls
Function `fmi3Get{VariableType}`

This function can be called for intermediate variables, if `intermediateVariableGetAllowed == fmi3True`. Intermediate variables are variables that are marked with attribute `intermediateUpdate = true` in the `modelDescription.xml` and have been included in the `requiredIntermediateVariables` argument to `fmi3InstantiateXXX`.

Function `fmi3Set{VariableType}`

This function can be called for intermediate input variables, if `intermediateVariableSetRequested == fmi3True`. Intermediate input variables are input variables that are marked with attribute `intermediateUpdate = true` in the `modelDescription.xml` and have been included in the `requiredIntermediateVariables` argument of `fmi3InstantiateXXX`. In Co-Simulation, `discrete` `inputs` must not be set.

There is a defined order of calling these functions: first all `fmi3Get{VariableType}` calls must be performed, then `fmi3Set{VariableType}` may be called.
[This is analogous to the calling sequence of `fmi3Get{VariableType}` and `fmi3Set{VariableType}` calls at communication points.]

Additionally to the functions listed above, Scheduled Execution allows calling the following functions:

Function `fmi3GetClock`

The scheduling algorithm uses `fmi3GetClock` to determine which clock is active.
[For efficiency, `fmi3GetClock` should only be called if `clocksTicked == fmi3True`.]
Depending on the clock activation state, the scheduling algorithm can call `fmi3Set{VariableType}` and `fmi3Get{VariableType}` for variables associated with the corresponding Clock. For an `output Clock` only the first call of `fmi3GetClock` for a specific activation of this Clock signals `fmi3ClockActive`. The FMU sets the reported activation state immediately back to `fmi3ClockInactive` for following `fmi3GetClock` calls for that Clock until this `output Clock` is activated again.

Functions `fmi3GetIntervalDecimal` & `fmi3GetIntervalFraction`

These function calls are allowed for input clocks.

[In Scheduled Execution it cannot be determined which model partition has called `fmi3CallbackIntermediateUpdate`, because multiple model partitions can be active at the same time. Since all information about which model partition to activate is coded into its corresponding clock, there is no need to know which potentially other model partition activated this clock.]

2.3.9. State: Terminated

In this state, the final values of all variables at the final time of a simulation can be retrieved.

Equations and Actions Functions Influencing Equations

$(\mathbf{y}_{c+d}, \mathbf{\dot{x}}_c, \mathbf{x}_{c+d}, \mathbf{z}, \mathbf{w}_{c+d}) := \mathbf{f}_{\mathit{term}}({}^\bullet\mathbf{x}_{c+d}, \mathbf{u}_{c+d}, \mathbf{p}, \mathbf{t})$

Allowed Function Calls
Functions `fmi3Get{VariableType}`

Getting variables might trigger computations. [If Terminated is entered because of an `fmi3Error` return value, retrieved values should only be used for debugging purposes.]

Function `fmi3GetContinuousStateDerivatives`
Function `fmi3GetContinuousStates`
Function `fmi3GetNominalsOfContinuousStates`
Function `fmi3GetEventIndicators`
Function `fmi3GetDirectionalDerivative`
Function `fmi3GetAdjointDerivative`

No restrictions.

Function `fmi3GetOutputDerivatives`

Not allowed in Model Exchange.

2.4. FMI Description Schema

All static information related to the core functionality of an FMU is stored in the text file `modelDescription.xml` in XML format as specified by the XML schema file `fmi3ModelDescription.xsd`. Especially, the FMU variables and their attributes such as `name`, `unit`, default `initial` value, etc. are stored in this file.

Additional optional information about the graphical representation and the grouping of FMU variables into terminals is stored in the optional text file `icons/terminalsAndIcons.xml` in XML format as specified by the XML schema file `fmi3TerminalsAndIcons.xsd`.

Build information for source code FMUs is provided together with a `buildDescription.xml` file in the `sources` directory that adheres to the `fmi3BuildDescription.xsd` schema file.

It is not allowed to change the `modelDescription.xml` file. [Reason: The `modelDescription.xml` file has to be consistent with the binary or source code implementations. Specifically, changes to the start values are not allowed.]

The structure of the XML files is defined with the schema file `fmi3ModelDescription.xsd` and the optional `fmi3TerminalsAndIcons.xsd` and `fmi3BuildDescription.xsd` files. These schema files utilize several helper schema files.

In this section these schema files are discussed. The normative definition are the above mentioned schema files. In the graphical representation of the schema, optional elements are marked with a dashed box (e.g., see Figure 8). The required data types (like: `xs:normalizedString`) are defined in XML Schema Part 2: Datatypes Second Edition. The types used in the FMI schema files are:

 XML Description (http://www.w3.org/TR/xmlschema-2/) Mapping to C Mapping to FMI 3.0 `double` IEEE 754 double-precision 64-bit floating point type [An IEEE 754 double-precision floating point value can have up to 17 significant digits in its decimal representation. In order to not loose precision, either an appropriate minimal printer algorithm should be used, or alternatively a number of this type should be stored in XML files with at least 17 significant digits.] `double` `fmi3Float64` `single` IEEE 754 single-precision 32-bit floating point type [An IEEE 754 single-precision floating point value can have up to 9 significant digits in its decimal representation. In order to not loose precision, either an appropriate minimal printer algorithm should be used, or alternatively a number of this type should be stored in XML files with at least 9 significant digits.] `float` `fmi3Float32` `byte` Integer number with maximum value 127 and minimum value -128 (8 bit signed integer) `int8_t` `fmi3Int8` `unsignedByte` Integer number with maximum value 255 and minimum value 0 (8 bit unsigned integer) `uint8_t` `fmi3UInt8` `short` Integer number with maximum value 32767 and minimum value -32768 (16 bit signed integer) `int16_t` `fmi3Int16` `unsignedShort` Integer number with maximum value 65535 and minimum value 0 (16 bit unsigned integer) `uint16_t` `fmi3UInt16` `int` Integer number with maximum value 2147483647 and minimum value -2147483648 (32 bit signed integer) `int32_t` `fmi3Int32` `unsignedInt` Integer number with maximum value 4294967295 and minimum value 0 (32 bit unsigned integer) `uint32_t` `fmi3UInt32` `long` Integer number with maximum value 9223372036854775807 and minimum value -9223372036854775808 (64 bit signed integer) `int64_t` `fmi3Int64` `unsignedLong` Integer number with maximum value 18446744073709551615 and minimum value 0 (64 bit unsigned integer) `uint64_t` `fmi3UInt64` `boolean` Boolean number. Legal literals: `false`, `true`, `0`, `1` `int` `fmi3Boolean` `string` Any number of characters `char*` `fmi3String` `normalizedString` String without carriage return, line feed, and tab characters `char*` `fmi3String` `hexBinary` Arbitrary hex-encoded binary data `char*` `fmi3Binary` `dateTime` Date, time and time zone (for details see XML Schema Part 2: Datatypes Second Edition). Example: `2002-10-23T12:00:00Z` (noon on October 23, 2002, Greenwich Mean Time) tool specific not defined

The first line of an XML file, such as `modelDescription.xml`, must contain the encoding scheme of the XML file. It is required that the encoding scheme is always UTF-8:

``<?xml version="1.0" encoding="UTF-8"?>``

The FMI schema files (`fmi3*.xsd`) are also stored in UTF-8.
[Note that the definition of an encoding scheme is a prerequisite in order for the XML file to contain letters outside of the 7 bit ANSI ASCII character set, such as German umlauts, or Asian characters. Furthermore, note the FMI calling interface requires that strings are encoded in UTF-8. Since the XML files are also required to be encoded in UTF-8, string variables need not to be transformed when reading from the XML files in to C string variables.].

[Note that child information items, such as elements in a sequence are ordered lists according to document order, whereas attribute information items are unordered sets (see http://www.w3.org/TR/XML-infoset/#infoitem.element). The FMI schema is based on ordered lists in a sequence and therefore parsing must preserve this order. For example, the information stored in `<ContinuousStateDerivative>` in `<ModelStructure>` is only correct if this property is fulfilled.]

All XML-based file formats defined in this standard allow optional `Annotation` elements to be inserted in all XML elements that represent entities of the underlying data model. This is achieved through the `Annotations` element:

Figure 8. Annotations Element.

Each `Annotation` element contains a required `type` attribute, which contains the namespace for that annotation. The content of the `Annotation` element can be arbitrary XML data, and can make use of XML namespaces and XML schemas for combined validation where appropriate.

The namespace mechanism for the `type` attribute is based on reverse domain notation: The originator of a specification for additional data specifies a domain name under their control as the namespace for the additional data, in order to avoid conflicts due to name collisions. The namespace is used in reverse domain notation. All namespaces under both the `org.modelica` and `org.fmi-standard` domains are reserved for use in future layered standards.

[For example, extensions defined by the Modelica Association might make use of the `org.modelica.fmi` namespace. This could lead to annotations with a `type` attribute of `org.modelica.fmi.something`, and/or extra files under the `extra/org.modelica.ssp.something` sub-directory.]

Annotations are intended to allow structured extensions of the FMI XML files, without creating conflicting extensions, or leaving ambiguities in interpretation. All annotations can safely be ignored by implementations that just implement the base FMI standard.

2.4.1. Definition of an FMU

This is the root-level schema file and is illustrated in Figure 9. The figure contains all elements in the schema file. Data is defined by attributes to these elements.

Figure 9. fmiModelDescription element.

On the top level, the schema consists of the elements detailed in Table 12. [If an optional element is present and defines a list (such as `<UnitDefinitions>`), the list must have at least one element (such as `<Unit>`).]

Table 12. fmiModelDescription element details.
Element Description

`<ModelExchange>`

If present, the FMU is based on FMI for Model Exchange (Section 3) [(in other words, the FMU includes the model or the communication to a tool that provides the model, and the environment provides the simulation engine)].

`<CoSimulation>`

If present, the FMU is based on FMI for Co-Simulation (Section 4).

`<ScheduledExecution>`

If present, the FMU is based on FMI for Scheduled Execution (Section 5).

`<UnitDefinitions>`

A global list of unit and display unit definitions [for example, used to convert display units into the units used in the model equations]. These definitions are used in the XML element `<ModelVariables>`.

`<TypeDefinitions>`

A global list of type definitions that are utilized in `<ModelVariables>`.

`<LogCategories>`

A global list of log categories that can be set to define the log information that is supported from the FMU.

`<DefaultExperiment>`

Providing default settings for the integrator, such as stop time and relative tolerance.

`<ModelVariables>`

The central FMU data structure defining all variables of the FMU that are visible/accessible via the FMU functions.

`<ModelStructure>`

Defines the structure of the model. Especially, the ordered lists of `outputs`, continuous-time `states`, initial unknowns (the unknowns during Initialization Mode) and the event indicators are defined here. For more details on `<ModelStructure>`, see Section 2.4.8. Furthermore, the dependency of the unknowns from the knowns can be optionally defined for `outputs`, continuous-time `states` and initial unknowns. [This information can be, for example, used to compute efficiently a sparse Jacobian for simulation, or to utilize the `input` / `output` dependency in order to detect that in some cases there are actually no algebraic loops when connecting FMUs together]. Dependencies for event indicators are not provided. [The calculation of derivatives of event indicators is not provided.].

`<Annotations>`

Optional annotations for the top-level element.

At least one element of `<ModelExchange>`, `<CoSimulation>` or `<ScheduledExecution>` must be present to identify the type of the FMU. If multiple elements are defined, different types of models are included in the FMU. The details of these elements are defined in Section 3, Section 4 or Section 5.

The XML attributes of `<fmiModelDescription>` are:

Table 13. fmiModelDescription attribute details.
Attribute Description

`fmiVersion`

Version of FMI that was used to generate the XML file. The value for this version is `3.0`. Future minor revisions are denoted as `3.1`, `3.2` …​

[During development prototype FMU implementations can indicate compliance with a certain development version based on the tags available at https://github.com/modelica/fmi-standard/tags. For example the value for the FMI 3.0 Alpha 2 release is `3.0-alpha.2`.]

`modelName`

The name of the model as used in the modeling environment that generated the XML file, such as `Modelica.Mechanics.Rotational.Examples.CoupledClutches`.

`instantiationToken`

The `instantiationToken` is a string that can be used by the FMU to check that the XML file is compatible with the implementation of the FMU. For this purpose the importing tool must pass the `instantiationToken` from the `modelDescription.xml` to the `fmi3InstantiateXXX` function call.

`description`

Optional string with a brief description of the model.

`author`

Optional string with the name and organization of the model author.

`version`

Optional version of the model [for example `1.0`].

`copyright`

Optional information on the intellectual property copyright for this FMU [for example `© My Company 2011`].

`license`

Optional information on the intellectual property licensing for this FMU [for example `BSD license <license text or link to license>`].

`generationTool`

Optional name of the tool that generated the XML file.

`generationDateAndTime`

Optional date and time when the XML file was generated. The format is a subset of `dateTime` and should be: `YYYY-MM-DDThh:mm:ssZ` (with one `T` between date and time; `Z` characterizes the Zulu time zone, in other words, Greenwich meantime) [for example `2009-12-08T14:33:22Z`].

Defines whether the variable names in `<ModelVariables>` and in `<TypeDefinitions>` follow a particular convention. For the details, see Section 2.4.7.5.1. Currently standardized are:

`= flat`: A list of strings (the default).

`= structured`: Hierarchical names with `.` as hierarchy separator, and with array elements and derivative characterization.

2.4.2. Definition of Capability Flags

The elements `<ModelExchange>`, `<CoSimulation>` and `<ScheduledExecution>` contain attributes representing capability flags describing which optional functionalities the FMU supports.

The following table contains capability flags common to all three interface types.

Table 14. Common capability flags.
Attribute Description

`needsExecutionTool`

If `true`, a tool is needed to execute the model and the FMU just contains the communication to this tool. [Typically, this information is only utilized for information purposes. For example, when loading an FMU with `needsExecutionTool = true`, the environment can inform the user that a tool has to be available on the computer where the model is instantiated. The name of the tool can be taken from attribute `generationTool` in `<fmiModelDescription>`.]

`canBeInstantiatedOnlyOncePerProcess`

This flag indicates cases (especially for embedded code), where only one instance per FMU is possible (multiple instantiation is default = `false`; if multiple instances are needed and the flag `canBeInstantiatedOnlyOncePerProcess = true`, the FMUs must be instantiated in different processes).

`canGetAndSetFMUState`

If `true`, the environment can inquire the internal FMU state and can restore it. That is, functions `fmi3GetFMUState`, `fmi3SetFMUState`, and `fmi3FreeFMUState` are supported by the FMU.

`canSerializeFMUState`

If `true`, the environment can serialize the internal FMU state, in other words, functions `fmi3SerializedFMUStateSize`, `fmi3SerializeFMUState`, `fmi3DeSerializeFMUState` are supported by the FMU. If this is the case, then flag `canGetAndSetFMUState` must be `true` as well.

`providesDirectionalDerivatives`

If `true`, the directional derivative of the equations can be computed with `fmi3GetDirectionalDerivative`.

`providesAdjointDerivatives`

If `true`, the adjoint derivatives of the equations can be computed with `fmi3GetAdjointDerivative`.

`providesPerElementDependencies`

The FMU is able to provide detailed dependency information at runtime using `fmi3GetNumberOfVariableDependencies` and `fmi3GetVariableDependencies`.

`maxOutputDerivativeOrder`

The FMU is able to provide `derivatives` of `outputs` with maximum order. Calling of `fmi3GetOutputDerivatives` is allowed up to the order defined by `maxOutputDerivativeOrder`. This flag is ignored in `ModelExchange`.

`providesIntermediateUpdate`

The FMU supports Intermediate Update Mode and will call `fmi3CallbackIntermediateUpdate`, if provided. This flag is ignored in `ModelExchange`.

`providesEvaluateDiscreteStates`

The FMU supports `fmi3EvaluateDiscreteStates`, if `true`. This flag is ignored in `ScheduledExecution`.

`recommendedIntermediateInputSmoothness`

A value of $k$ with $k>0$ signals to the co-simulation algorithm, that it is beneficial for the solver to receive intermediate inputs that are k-time continuously differentiable ($C^k$) on the current communication interval. $k=0$ means continuous (see Section 4.1.1).
This flag is ignored in `ModelExchange`.

2.4.3. Definition of Units

In this section, the units of the variables are defined.

[Unit support is important for technical systems since otherwise it is very easy for errors to occur. Unit handling is a difficult topic, and there seems to be no method available that is really satisfactory for all applications, such as unit check, unit conversion, unit propagation or dimensional analysis. In FMI, a pragmatic approach is used that takes into account that every software system supporting units has potentially its own specific technique to describe and utilize units.]

Element `<fmiModelDescription><UnitDefinitions>` is defined as:

Figure 10. UnitDefinitions element.

It contains one or more `Unit` definitions. If no units are defined, element `<UnitDefinitions>` must not be present.

The `name` of a `Unit` must be unique with respect to all other `<Unit>` elements. If a variable is associated with a `Unit`, the value passed to `fmi3Set{VariableType}` (resp. retrieved with `fmi3Get{VariableType}`) has this unit. [The purpose of the name is to uniquely identify a unit and, for example, use it to display the unit in menus or in plots. Since there is no standard to represent units in strings, and there are different ways how this is performed in different tools, no specific format for the string representation of the unit is required.]

The `Unit` definition consists of the exponents of the 7 SI base units `kg`, `m`, `s`, `A`, `K`, `mol`, `cd`, the exponent of the SI derived unit `rad`, and optionally a `factor` and an `offset`. [The additional `rad` base unit helps to handle the often occurring quantities in technical systems that depend on an angle.]

Figure 11. BaseUnit element.

A value $v_{unit}$ in `Unit` is converted to the base unit $v_{base}$ by the equation

$v_{base} = \texttt{factor} * v_{unit} + \texttt{if relativeQuantity then 0 else offset}$

where `factor` and `offset` are attributes of the `<BaseUnit>`, and `relativeQuantity` an attrinbute of the `TypeDefinition` of a variable.

[For example, if ${p_{\mathit{bar}}}$ is a pressure value in unit `bar`, and ${p_{\mathit{Pa}}}$ is the pressure value in `<BaseUnit>`, then

${p_{\mathit{Pa}} = 10^5 p_{\mathit{bar}}}$

and therefore, `factor = 1.0e5` and `offset = 0.0`.

In the following table several unit examples are given. Note that if in column `exponents` the definition $\frac{kg \cdot m^2}{s^2}$ is present, then the attributes of `<BaseUnit>` are `kg=1, m=2, s=-2`.

 Quantity Unit.name (examples) Unit.BaseUnit exponents factor offset Torque `N.m` ${kg \cdot m^2 / s^2}$ `1.0` `0.0` Energy `J` ${kg \cdot m^2 / s^2}$ `1.0` `0.0` Pressure `bar` ${\frac{kg}{m \cdot s^2}}$ `1.0e5` `0.0` Angle `deg` `rad` `0.01745329251994330 (= pi/180)` `0.0` Angular velocity `rad/s` `rad/s` `1.0` `0.0` Angular velocity `rpm` `rad/s` `0.1047197551196598 (= 2*pi/60)` `0.0` Frequency `Hz` `rad/s` `6.283185307179586 (= 2*pi)` `0.0` Temperature `°F` `K` `0.5555555555555556 (= 5/9)` `255.3722222222222 (= 273.15-32*5/9)` Per cent by length `%/m` `1/m` `0.01` `0.0` Parts per million `ppm` `1` `1.0e-6` `0.0` Length `km` `m` `1000` `0.0` Length `yd` `m` `0.9144` `0.0`

Note that `Hz` is typically used as `Unit.name` for a frequency quantity, but it can also be used as `<DisplayUnit>` for an angular velocity quantity (since `revolution/s`).]

The `<BaseUnit>` definitions can be utilized for different purposes (the following application examples are optional and a tool may also completely ignore the `Unit` definitions):

Unit check when connecting variables of different FMUs

When only one of `input` `v2` and `output` `v1`, connected with equation `v2 = v1`, defines a `<BaseUnit>` element, `fmi3Get{VariableType}` must be used to get the value of `v1` to then set it with `fmi3Set{VariableType}` for `v2`.

When two variables v1 and v2 are connected and for both of them `<BaseUnit>` elements are defined, then they must have identical exponents of their `<BaseUnit>`. If `factor` and `offset` are also identical, again the connection equation `v2 = v1` holds. If `factor` and `offset` are not identical, the tool may either trigger an error or, if supported, perform a conversion; in other words, use the connection equation (in this case the `relativeQuantity` of the `<TypeDefinition>`, see below, has to be taken into account in order to determine whether `offset` shall or shall not be utilized):

`factor(v1) * v1 + (if relativeQuantity(v1) then 0 else offset(v1)) = factor(v2) * v2 + (if relativeQuantity(v2) then 0 else offset(v2))`
where `relativeQuantity(v1) = relativeQuantity(v2)` is required.

As a result, wrong connections can be detected (for example, connecting a force with an angle-based variable would trigger an error) and conversions between, say, US and SI units can be either automatically performed or, if not supported, an error is triggered as well.

This approach is not satisfactory for variables belonging to different quantities that have, however, the same `<BaseUnit>`, such as quantities `Energy` and `Torque`, or `AngularVelocity` and `Frequency`. To handle such cases, quantity definitions have to be taken into account (see `<TypeDefinitions>`) and quantity names need to be standardized.

This approach allows a general treatment of units, without being forced to standardize the grammar and allowed values for units (for example, in FMI 1.0, a unit could be defined as `N.m` in one FMU and as `N*m` in another FMU, and a tool would have to reject a connection, since the units are not identical. In FMI 2.0, the connection would be accepted, provided both elements have the same `<BaseUnit>` definition).

Dimensional analysis of equations

In order to check the validity of equations in a modeling language, the defined units can be used for dimensional analysis, by using the `<BaseUnit>` definition of the respective unit. For this purpose, the `<BaseUnit>` `rad` has to be treated as `1`. Example:

\begin{align*} J \cdot \alpha = \tau \rightarrow [kg.m^2]*[rad/s^2] = [kg.m^2/s^2] & \quad \text{// o.k. ("rad" is treated as "1")} \\ J \cdot \alpha = f \rightarrow [kg.m^2]*[rad/s^2] = [kg.m/s^2] & \quad \text{// error, since dimensions do not agree} \end{align*}
Unit propagation

If unit definitions are missing for variables, they might be deduced from the equations where the variables are used. If no unit computation is needed, `rad` is propagated. If a unit computation is needed and one of the involved units has `rad` as a `<BaseUnit>`, then unit propagation is not possible. Examples:

• a = b + c, and `Unit` of c is provided, but not `Unit` of a and b:
The Unit definition of `c` (in other words, `Unit.name`, `<BaseUnit>`, `<DisplayUnit>`) is also used for `a` and `b`. For example, if BaseUnit(c) = `rad/s`, then BaseUnit(a) = BaseUnit(b) = `rad/s`.

• a = b*c, and `Unit` of a and of c is provided, but not `Unit` of b:
If `rad` is either part of the `<BaseUnit>` of `a` and/or of `c`, then the `<BaseUnit>` of `b` cannot be deduced (otherwise it can be deduced). Example: If `BaseUnit(a) = kg.m/s2` and `BaseUnit(c) = m/s2`, then the `BaseUnit(b) can be deduced to be `kg`. In such a case `Unit.name` of b cannot be deduced from the `Unit.name` of `a` and `c`, and a tool would typically construct the `Unit.name` of `b` from the deduced `<BaseUnit>`.]

A `<Unit>` can contain any number of `<DisplayUnit>` elements.

Figure 12. DisplayUnit element.

A `<DisplayUnit>` is defined by `name`, `factor`, `offset`, and `inverse`. The attribute `name` must be unique with respect to all other names of the `<DisplayUnit>` definitions of the same `Unit`. [Different `Unit` elements may have the same `<DisplayUnit>` names].
`inverse == true` is only allowed if `offset == 0`.
[Reason: no use case is known for the combination of inverse and offset, which would also be more complicated.]

A value $v_{unit}$ in `Unit` is converted to a value $v_{display}$ in `DisplayUnit` by the equation:

$v_{display} = \left\{\begin{array}{ll} \texttt{factor} * v_{unit} + \texttt{offset} &\text{if} \; \texttt{inverse == false} \\ \texttt{factor} * \frac{1}{v_{unit}} &\text{if} \; \texttt{inverse == true} \end{array}\right.$

[`offset` is needed for temperature units like `F` (Fahrenheit), `inverse` for inverse display units like `mpg` (miles per gallon) or `S` (Siemens).

For example, if ${T_K}$ is the temperature value of `Unit.name` (in `K`) and ${T_F}$ is the temperature value of `<DisplayUnit>` (in `°F`), then

$T_F = (9/5) * (T_K - 273.15) + 32$

and therefore, `factor = 1.8 (=9/5)` and `offset = -459.67 (= 32 - 273.15*9/5)`.

Both the `DisplayUnit.name` definitions as well as the `Unit.name` definitions are used in the variable elements.

Example of a definition:

``````<UnitDefinitions>
<DisplayUnit name="deg/s" factor="57.29577951308232"/>
<DisplayUnit name="rev/min" factor="9.549296585513721"/>
</Unit>
<Unit name="bar">
<BaseUnit kg="1" m="-1" s="-2" factor="1e5" offset="0"/>
</Unit>
<Unit name="L/100km">
<BaseUnit m="2" factor="1e-8"/>
<DisplayUnit name="mpg" inverse="true" factor="235.214583"/>
</Unit>
<Unit name="Re">
<BaseUnit/> <!-- unit="1" -->
<!-- (dimensionless, all exponents of BaseUnit are zero) -->
</Unit>
<Unit name="Euro/PersonYear"/>  <!-- no mapping to BaseUnit defined -->
</UnitDefinitions>``````

]

2.4.4. Definition of Types

Element `<fmiModelDescription><TypeDefinitions>` is defined as:

Figure 13. TypeDefinitions element.

This element consists of a set of `<TypeDefinition>` elements according to schema `fmi3TypeDefinition` in file `fmi3Type.xsd`. Each `<TypeDefinition>` has attributes `name` and `description`. Attribute `name` must be unique with respect to all other elements of the `<TypeDefinitions>` list. Furthermore, `name` of a `<TypeDefinition>` must be different to all `name` attributes of variables [if the same names would be used, then this would nearly always give problems when importing the FMU in an environment such as Modelica, where a type name cannot be used as instance name].

Additionally, one variable type element must be present. Each variable type has its own attributes which can be consulted in the schema. Figure 14, Figure 15, Figure 16, Figure 17, and Figure 18, are representative examples.

Figure 14. Float64Type element.
Figure 15. Int32Type element.
Figure 16. BooleanType element.
Figure 17. BinaryType element.
Figure 18. EnumerationType element.
Figure 19. ClockType element.

The type elements are referred to in variable elements to declare their type. [The alternative would be to define a type per variable. However, this would lead to a situation where, e.g., the definition of a `Torque` type would have to be repeated over and over.] The attributes and elements have the following meaning:

Table 16. Type element and attribute details.
Attribute or Element Description

`quantity`

Physical quantity of the variable. [For example, `Angle`, or `Energy`. The quantity names are not standardized]

`unit`

Unit of the variable defined with attribute `name` of `<UnitDefinitions><Unit>` that is used for the model equations. [For example, `N.m`: in this case a `Unit.name = `N.m` must be present under `<UnitDefinitions>`.] [Note that for variables that are without a unit, the element should not have a `unit` attribute.] [Giving an empty string as a `unit` attribute specifies a valid unit that needs to be defined among the unit definitions.]

`displayUnit`

Default display unit. The conversion to the `unit` is defined with the element `<fmiModelDescription><UnitDefinitions>`. If the corresponding `displayUnit` is not defined under `<UnitDefinitions><Unit><DisplayUnit>`, then `displayUnit` is ignored. It is an error if `displayUnit` is defined as variable type element, but `unit` is not, or unit is not defined under `<UnitDefinitions><Unit>`.

`mimeType`

Indicates the type of data passed as a binary. Defaults to `application/octet-stream`, which is unspecific. Implementations can use this information to provide guidance to the user about valid/useful connections.

`maxSize`

Indicates the maximum size (bytes) of the data passed as a binary.

`relativeQuantity`

If this attribute is `true`, then the `offset` of `BaseUnit` and `displayUnit` must be ignored. [For example, 10 degree Celsius = 10 Kelvin if `relativeQuantity = true` and not 283.15 Kelvin.]

`min`

Minimum value of variable (variable value $\geq$ `min`). If not defined, the minimum is the largest negative number that can be represented on the machine. The `min` definition is information from the FMU to the environment defining the region in which the FMU is designed to operate (see Section 2.2.6.3). [If, for example, an `<Enumeration>` is defined with `name1 = -4`, `name2 = 1`, `name3 = 5`, `name4 = 11` and `min = -2`, `max = 5`, then only `name2` and `name3` are allowed.]

`max`

Maximum value of variable (variable value $\leq$ `max`). If not defined, the maximum is the largest positive number that can be represented on the machine. The `max` definition is information from the FMU to the environment defining the region in which the FMU is designed to operate (see Section 2.2.6.3). [If, for example, an `<Enumeration>` is defined with `name1 = -4`, `name2 = 1`, `name3 = 5`, `name4 = 11` and `min = -2`, `max = 5`, then only `name2` and `name3` are allowed.]

`nominal`

Nominal value of variable. If not defined and no other information about the nominal value is available, then `nominal = 1` is assumed.
[The nominal value of a variable can be, for example, used to determine the absolute tolerance for this variable as needed by numerical algorithms:
`absoluteTolerance = nominal * tolerance * 0.01`
where `tolerance` is, for example, the relative tolerance defined in Section 2.4.6.]

`unbounded`

If `true`, indicates that during time integration, the variable gets a value much larger than its nominal value `nominal`. [Typical examples are the monotonically increasing rotation angles of crank shafts and the longitudinal position of a vehicle along the track in long distance simulations. This information can, for example, be used to increase numerical stability and accuracy by setting the corresponding bound for the relative error to zero (relative tolerance = 0.0), if the corresponding variable is a continuous `state` variable.]

`Item`

`<Item>` of an enumeration has a sequence of `name` and `value` pairs. The values can be any integer number but must be unique within the same enumeration (in order that the mapping between `name` and `value` is bijective). An `<Enumeration>` element must have at least one `<Item>`.

Attributes for `ClockType`

`canBeDeactivated`

`Clocks` with the attribute `canBeDeactivated == true` can be actively deactivated using `fmi3SetClock`.

`priority`

`Clocks` that have to be activated at the same time instant are ordered according to this attribute. Smaller values signal higher priorities. No ordering is defined for multiple `Clocks` with the same `priority`.

This attribute is only considered in Scheduled Execution.

`interval`

The attribute `interval` declares the clock type, see Table 5.

The values of the following float and integer attributes refer to the unit of the `independent` variable.

`intervalDecimal`

The time interval $\mathbf{T}_{interval}$ between consecutive Clock ticks.

This value must be greater than 0.0.

`shiftDecimal`

This value defines the delay of the first clock activation relative to $\mathbf{t}_{\mathit{start}}$ (`startTime`).

This value must be equal or greater than 0.0.

`supportsFraction`

This attribute defines, if the functions `fmi3GetXXXFraction` and `fmi3SetXXXFraction` are allowed to be called for all time-based Clocks.

`resolution`

Instead of defining clock timing using floating point numbers, FMI allows the definition of rational numbers using `intervalCounters` and `shiftCounters`. The `resolution` defines the minimal quanta clock timing can be resolved by.

This attribute is required for time-based periodic clocks if `supportsFraction = true` and either `intervalCounter` or `shiftCounter` is present.

`intervalCounter`

This attribute defines (together with `resolution`) the interval between consecutive clock ticks:

$\mathbf{T}_{interval} =$ `intervalCounter / resolution`.

`intervalCounter` and `resolution` have no default value.

This value must be greater than 0.

This attribute is allowed if `supportsFraction = true` and is required if interval == `constant` or interval == `fixed`.

`shiftCounter`

This value defines (together with `resolution`) the delay of the first clock activation relative to $\mathbf{t}_{\mathit{start}}$ (`startTime`):

$\mathbf{T}_{shift} =$ `shiftCounter / resolution`.

This value must be greater than 0.

This attribute is allowed if `supportsFraction = true` and is required if interval == `constant` or interval == `fixed`.

2.4.5. Definition of Log Categories

Element `<fmiModelDescription><LogCategories>` is defined as:

Figure 20. LogCategories element.

`<LogCategories>` defines an unordered set of category strings that can be utilized to define the log output via function `logMessage`, see FMU State Setable. A tool is free to use any `normalizedString` for a category value. The `name` attribute of `<Category>` must be unique with respect to all other elements of the `<LogCategories>` list.

Table 17 shows the standardized names for `<Category>`. These names should be used if a tool supports the corresponding log category. If a tool supports one of these log categories and wants to expose it, then an element `<Category>` with this name should be added to `<LogCategories>`. [To be clear, only the `<Category>` names listed under `<LogCategories>` in the XML file are known to the importer of the FMU.]

Table 17. Standard names for `<Category>`.
Category Description

`logEvents`

Log all events (during initialization and simulation).

`logSingularLinearSystems`

Log the solution of linear systems of equations if the solution is singular (and the tool picked one solution of the infinitely many solutions).

`logNonlinearSystems`

Log the solution of nonlinear systems of equations.

`logDynamicStateSelection`

Log the dynamic selection of `states`.

`logStatusWarning`

Log messages when returning `fmi3Warning` status from any function.

`logStatusDiscard`

Log messages when returning `fmi3Discard` status from any function.

`logStatusError`

Log messages when returning `fmi3Error` status from any function.

`logStatusFatal`

Log messages when returning `fmi3Fatal` status from any function.

The optional attribute `description` shall contain a description of the respective log category. [Typically, this string can be shown by a tool if more details for a log category are presented.]

[This approach to define `<LogCategories>` has the following advantages:

1. A simulation environment can present the possible log categories in a menu and the user can select the desired one (in the FMI 1.0 approach, there was no easy way for a user to figure out from a given FMU what log categories could be provided).
Note that since element `<LogCategories>` is optional, an FMU does not need to expose its log categories.

2. The log output is drastically reduced, because via `fmi3SetDebugLogging` exactly the categories are set that shall be logged and therefore the FMU only has to print the messages with the corresponding categories to the `logMessage` function. In FMI 1.0, it was necessary to provide all log output of the FMU to the `logMessage` and then a filter in the `logMessage` could select what to show to the end-user. The approach introduced in FMI 2.0 is therefore much more efficient.]

2.4.6. Definition of a Default Experiment

Element `<fmiModelDescription><DefaultExperiment>` is defined as:

Figure 21. DefaultExperiment element.

`<DefaultExperiment>` consists of the optional default start time, stop time, relative tolerance, and step size for the first simulation run. A tool may ignore this information. However, it is convenient for a user that `startTime`, `stopTime`, `tolerance` and `stepSize` have already a meaningful default value for the model at hand. Furthermore, for Co-Simulation FMUs the `stepSize` defines the preferred `communicationStepSize`. `startTime`, `stopTime` and `stepSize` refer to the unit of the `independent` variable.

2.4.7. Definition of Model Variables

2.4.7.1. Static information

The element of `<fmiModelDescription><ModelVariables>` is the central part of the model description. It provides the static information of all exposed variables and is defined as follows.

Figure 22. ModelVariables element.

The `<ModelVariables>` element consists of variable elements (see Figure 22). Variable elements can uniformly represent variables of primitive (atomic) types, like single floating point or integer variables, as well as arrays of an arbitrary (but fixed) number of dimensions. The schema definition is present in a separate file `fmi3Variable.xsd`.

2.4.7.2. Array variables and structural parameters

Variable elements representing array variables must contain at least one `<Dimension>` element. Each `<Dimension>` element specifies the size of one dimension of the array:

These two options are mutually exclusive, i.e., for each `<Dimension>` element either a `start` attribute or a `valueReference` attribute can be supplied, but not both. However different dimension sizes can be specified using different mechanisms and can have differing `variability` attributes.

All initial dimension sizes (i.e. prior to any configuration or reconfiguration) must be positive integers (i.e. not zero), so that no dimension is initially vanished.

[This allows importing tools to ignore `structural parameters` because that `start` value reflects the internal default setting of that `structural parameter`. The rationale for requiring positive start values for `structural parameters` is that this avoids importers having to deal with vanishing dimensions if they do not want to deal with them (or even with changing sizes at all). If we allowed 0 dimension sizes for initial values, tools that do not even care about changing dimension sizes must be prepared to handle vanishing dimensions.]

[ Example: `V` is a floating point vector parameter. The length of the vector depends on the `structural parameter` `len`. The default length of the vector is 7. This length can be changed in Configuration Mode because the `variability` of the `structural parameter` `len` is `fixed`. The values of `V` can be changed whenever `tunable` parameters can be changed.

``````<UInt64 name="len" valueReference= "100" causality="structuralParameter"
variability="fixed" start="7"/>
<Float32 name="V" valueReference="1" causality="parameter" variability="tunable"
start="0.1 -0.2 0.3 -0.4 0.5 -0.6 0.7">
<Dimension valueReference="100"/>
</Float32>``````

]

Changes to dimension sizes are constrained by the `min`/`max` attributes of the referenced `structural parameters`, which can be any non-negative integer, including zero. Specifying a minimum size of zero on a `structural parameter` allows any related dimension sizes to be changed to zero in Configuration Mode or Reconfiguration Mode, thus causing the respective array size to go to zero, which leaves the respective array variable without any active elements.

The actual dimension sizes of arrays are also constrained by the FMU platform, due to memory and addressing constraints: Since the API functions to access variables and their values are constrained to `size_t` individual elements, platforms with addresses of less than 64-bit width will not be able to access elements beyond their addressing limits, neither will they be able to allocate enough memory or address space to represent such arrays. For these reasons implementations must take platform-specific constraints into account when changing dimension sizes, and must be prepared to handle the inability of the FMU to adjust to the desired sizes during Configuration Mode or Reconfiguration Mode.

Changing any dimension of a variable in Configuration Mode or Reconfiguration Mode invalidates the variable’s current value (including its `start` value). It should be noted that changing a `structural parameter` might affect dimension sizes of several variables.

2.4.7.3. Alias variables

A variable can have any number of `<Alias>` elements that define a variable alias. Each variable alias has a required attribute `name` whose value must be unique among all variables and variable aliases, and an optional attribute `description`. Variable aliases of floating point variables may additionally have a `displayUnit` that follows the same rules as for variables.

[ Example:

`````` <Float64 name="engine.torque" valueReference="1" unit="N.m">
<Alias name="engine.torqueLbfFt" description="Engine torque in pound-foot"
displayUnit="lbf.ft"/>
</Float64>``````

]

2.4.7.4. Variable Attributes

The most common attributes of variables are shown in Figure 23.

Figure 23. fmi3AbstractVariable element.
Table 18. fmi3AbstractVariable attribute details.
Attribute Description

`name`

The full, unique name of the variable. Every variable is uniquely identified within an FMU instance by this name.

`valueReference`

A handle of the variable to efficiently identify the variable value in the model interface and for references within the `modelDescription.xml`. This handle is a secret of the tool that generated the C functions. It is required to be unique for an FMU. This attribute is `required`.

`description`

An optional description string describing the meaning of the variable.

`causality`

Enumeration that defines the causality of the variable. Allowed values of this enumeration:

`= parameter`: A data value that is constant during the simulation (except for `tunable` parameters, see there) and is provided by the environment and cannot be used in connections, except for parameter propagation in terminals as described in Section 2.4.9.2.6. `variability` must be `fixed` or `tunable`. These parameters can be changed independently, unlike calculated parameters. `initial` must be `exact` or not present (meaning `exact`).

`= calculatedParameter`: A data value that is constant during the simulation and is computed during initialization or when `tunable` `parameters` change. `variability` must be `fixed` or `tunable`. `initial` must be `approx`, `calculated` or not present (meaning `calculated`).

`= input`: The variable value can be provided by the importer.
[For example, the importer could forward the output of another FMU into this input.]

`= output`: The variable value can be used by the importer.
[For example, this value can be forwarded to an input of another FMU.]
The algebraic relationship to the `inputs` can be defined via the `dependencies` attribute of `<fmiModelDescription><ModelStructure><Output>`.

`= local`: Local variables are:

Setting of local variables:

`= independent`: The independent variable (usually `time` [but could also be, for example, `angle`]). All variables are a function of this `independent` variable. `variability` must be `continuous`. Exactly one variable of an FMU must be defined as `independent`. If the unit for the independent variable is not defined, it is implicitly`unit = s`. If one variable is defined as `independent`, it must be defined with a floating point type without a `start` attribute. It is not allowed to call function `fmi3Set{VariableType}` on an `independent` variable. Instead, its value is initialized with `fmi3EnterInitializationMode` and after initialization set by `fmi3SetTime` for Model Exchange and by arguments `currentCommunicationPoint` and `communicationStepSize` of `fmi3DoStep` for Co-Simulation FMUs. [The actual value can be inquired with `fmi3Get{VariableType}`.]

`= structuralParameter`: The variable value can only be changed in Configuration Mode or Reconfiguration Mode. The `variability` attribute must be `fixed` or `tunable`. The `initial` attribute must be `exact` or not present (meaning `exact`). The `start` attribute is mandatory. A `structural parameter` must not have a `<Dimension>` element. A `structural parameter` may be referenced in `<Dimension>` elements. If a `structural parameters` is referenced in `<Dimension>` elements, it must be of type `<UInt64>` and its `start` attribute must be larger than 0. The `min` attribute might still be 0.

The default of `causality` is `local`.
A continuous-time `state` or an event indicator must have `causality` = `local` or `output`, see also Section 2.4.8.

[`causality` = `calculatedParameter` and `causality` = `local` with `variability` = `fixed` or `tunable` are similar. The difference is that a `calculatedParameter` can be used in another model or FMU, whereas a `local` variable cannot. For example, when importing an FMU in a Modelica environment, a `calculatedParameter` should be imported in a `public` section as `final parameter`, whereas a `local` variable should be imported in a `protected` section of the model.]

The causality of variables of type Clock must be either `input` or `output`.

`variability`

Enumeration that defines the time dependency of the variable, in other words, it defines the time instants when a variable can change its value. [The purpose of this attribute is to define when a result value needs to be inquired and to be stored. For example, `discrete` variables change their values only at event instants (ME) or at a communication point (CS and SE) and it is therefore only necessary to inquire them with `fmi3Get{VariableType}` and store them at event times.] Allowed values of this enumeration:

`= constant`: The value of the variable never changes.

`= fixed`: The value of the variable is fixed after initialization, in other words, after `fmi3ExitInitializationMode` was called the variable value does not change anymore.

`= tunable`: The value of the variable is constant between events (ME) and between communication points (CS and SE) due to changing variables with `causality` = `parameter` and `variability` = `tunable`. Whenever a `parameter` with `variability` = `tunable` changes, an event is triggered externally (ME or CS if events are supported), or the change is performed at the next communication point (CS and SE) and the variables with `variability` = `tunable` and `causality` = `calculatedParameter` or `output` must be newly computed. [`tunable` inputs are not allowed, see Table 19.]

`= discrete`:
Model Exchange: The value of the variable is constant between external and internal events (= `time`, `state`, `step events` defined implicitly in the FMU).
Co-Simulation: By convention, the variable is from a real sampled data system and its value is only changed at communication points (including event handling). During `intermediateUpdate`, `discrete` variables are not allowed to change. [If the simulation algorithm notices a change in a discrete variable during `intermediateUpdate`, the simulation algorithm will delay the change, raise an event with `earlyReturnRequested == fmi3True` and during the communication point it can change the `discrete` variable, followed by event handling.]

`= continuous`: Only a variable of `type == fmi3GetFloat32` or `type == fmi3GetFloat64` can be `continuous`.
Model Exchange: No restrictions on value changes (see Section 4.1.1).

The default is `continuous` for variables of type `<Float32>` and `<Float64>`, and `discrete` for all other types.

For variables of type `Clock` and `clocked variables` the `variability` is always `discrete`.

[Note that the information about continuous `states` is defined with elements `<ContinuousStateDerivative>` in `<ModelStructure>`.]

`canHandleMultipleSetPerTimeInstant`

Only for variables with `variability` = `input`.
The default value is `true`. If `canHandleMultipleSetPerTimeInstant = false`, then only one `fmi3Set{VariableType}` call is allowed for this variable per super-dense time instant in Event Mode. [This flag can be set to `false` for variables where discrete-time states are directly updated when assigned ( $\mathbf{x}_\mathit{d} := f(\mathbf{x}_\mathit{d},\mathbf{u}_\mathit{c+d})$ instead of $\mathbf{x}_\mathit{d} := f({}^\bullet\mathbf{x}_\mathit{d},\mathbf{u}_\mathit{c+d})$ ). If an `output` depends on this `input` and on discrete-time states, then an algebraic loop could be formed with such an `input`. Such loops cannot be solved iteratively because of the limitation on `fmi3Set{VariableType}`. Therefore, such an `input` should not appear in an algebraic loop.]

`intermediateUpdate`

If this boolean attribute is `true`, the variable can be accessed in Intermediate Update Mode. Variables with `causality` `parameter` must not be marked with `intermediateUpdate = true`.

This attribute is ignored in Model Exchange. The default value of this attribute is `false`.

`previous`

[For example, if `previous == 3` for variable `8`, then variable `3` is the previous value of variable `8`. See also `fmi3UpdateDiscreteStates`. Note: This is reverse compared to the `derivative` attribute.]

`clocks`

If present, this variable is clocked. The value of `clocks` is a list of value references of Clock variables this variable depends on. Only variables with `variability == discrete` or `variability == tunable` can have this attribute. [Some importers might require a variable to be dependent on a single clock for technical reasons. They could reject FMUs violating this restriction.]

Table 19 shows the combinations of `variability`/`causality` settings that are allowed.

 `variability` `causality` `structural Parameter` `parameter` `calculated Parameter` `input` `output` `local` `independent` — (a) — (a) — (a) — (a) (7) (10) — (c) `fixed` data (16) (1) (3) — (d) — (e) (11) — (c) (17) (2) (4) — (d) — (e) (12) — (c) `discrete` variables — (b) — (b) — (b) (5) (8) (13) — (c) `continuous` variables — (b) — (b) — (b) (6) (9) (14) (15)

[Discussion of the combinations that are not allowed:

Table 20. Combinations of variability and causality that are not allowed and why.
Explanation why this combination is not allowed

(a)

The combinations `constant` / `structuralParameter`, `constant` / `parameter`, `constant` / `calculatedParameter` and `constant` / `input` do not make sense, since `parameters` and `inputs` are set from the environment, whereas `constant` variables have an unchangeable value.

(b)

The combinations `discrete` / `structuralParameter`, `discrete` / `parameter`, `discrete` / `calculatedParameter` , `continuous` / `structuralParameter`, `continuous` / `parameter` and `continuous` / `calculatedParameter` do not make sense, since `causality` = `structuralParameter`, `causality` = `parameter` and `causality` = `calculatedParameter` define variables that do not depend on time, whereas `discrete` and `continuous` define variables where the values can change during simulation.

(c)

For an `independent` variable only `variability` = `continuous` makes sense.

(d)

A `fixed` or `tunable` `input` has exactly the same properties as a `fixed` or `tunable` `parameter`. For simplicity, only `fixed` and `tunable` `parameters` shall be defined.

(e)

A `fixed` or `tunable` `output` has exactly the same properties as a `fixed` or `tunable` `calculatedParameter`. For simplicity, only `fixed` and `tunable` `calculatedParameters` shall be defined.

Discussion of the combinations that are allowed:

Table 21. Combinations of variability and causality that are allowed and why.
Setting Example

(1)

`fixed` `parameter`

Non-`tunable` `parameter`

(2)

`tunable` `parameter`

`Tunable` `parameter` (changing such a `parameter` triggers event handling (ME) or takes effect at the next communication point (CS and SE), and `tunable` `calculatedParameter`/`output`/`local` variables might change their values).

(3)

`fixed` `calculatedParameter`

Non-`tunable` `calculatedParameter` (variable that is computed directly or indirectly from constants or `parameters`).

(4)

`tunable` `calculatedParameter`

`Tunable` `calculatedParameter` (changing a `parameter` triggers event handling (ME) or takes effect at the next communication point (CS and SE), and `tunable` `calculatedParameter` and `tunable` `local` variables might change their values).

(5)

`discrete` `input`

`Discrete` `input` variable from another model.

(6)

`continuous` `input`

`Continuous` `input` variable from another model.

(7)

`constant` `output`

Variable where the value never changes and that can be used in another model.

(8)

`discrete` `output`

`Discrete` variable that is computed in the FMU. Can be used in another model.

(9)

`continuous` `output`

`Continuous` variable that is computed in the FMU and can be used in another model.

(10)

`constant` `local`

Variable where the value never changes. Cannot be used in another model.

(11)

`fixed` `local`

Local variable that depends on `fixed` `parameters` only and is computed in the FMU. Cannot be used in another model. After initialization, the value of this `local` variable cannot change.

(12)

`tunable` `local`

Local variable that depends on `tunable` `parameters` only and is computed in the FMU. Cannot be used in another model. The value of this `local` variable can only change during initialization and at event instants, provided a `tunable` `parameter` was changed.

(13)

`discrete` `local`

`Discrete` variable that is computed in the FMU and cannot be used in another model.

(14)

`continuous` `local`

`Continuous` variable that is computed in the FMU and cannot be used in another model.

(15)

`continuous` `independent`

All variables are a function of the continuous-time variable marked as `independent`. Usually, this is `time`.

(16)

`fixed` `structuralParameter`

`Parameter` used in `<Dimension>` element; can be changed before initialization in Configuration Mode.

(17)

`tunable` `structuralParameter`

`Parameter` used in `<Dimension>` element; can be changed before initialization in Configuration Mode and in Reconfiguration Mode.

How to treat `tunable` variables:

A `parameter` p is a variable that does not change its value during simulation, in other words, dp/dt = 0. If the `parameter` p is changing, then Dirac impulses are introduced since dp/dt of a discontinuous `constant` variable `p` is a Dirac impulse. Even if this Dirac impulse would be modeled correctly by the modeling environment, it would introduce unwanted `vibrations`. Furthermore, in many cases the model equations are derived under the assumption of a `constant` value (like mass or capacity), and the model equations would be different if `p` would be time varying.

FMI for Model Exchange:
Therefore, "tuning a (structural) `parameter`" during simulation does not mean to "change the parameter online" during simulation. Instead, this is a short hand notation for:

1. Stop the simulation at an event instant (usually, a step event, in other words, after a successful integration step).

2. Change the values of the `tunable` (structural) `parameters`. For `tunable` `structural parameters`, the Reconfiguration Mode must be entered before and left afterwards.

3. Compute all `parameters` (and sizes of variables, `states`, `derivatives`, event indicators, …​) that depend on the `tunable` (structural) `parameters`.

4. Newly start the simulation using as initial values previously stored values and the new values of the `parameters`.

Basically this means that a new simulation run is started from the previous FMU state with changed `parameter` values. With this interpretation, changing `parameters` online is "clean", as long as these changes appear at an event instant.

FMI for Co-Simulation: Changing of `tunable` `parameters` is allowed before an `fmi3DoStep` call (so, whenever an `input` can be set with `fmi3Set{VariableType}`) and before `fmi3ExitInitializationMode` is called (that is before and during Initialization Mode). The FMU internally carries out event handling if necessary.]

FMI for Scheduled Execution: Changing of `tunable` `parameters` is allowed before an `fmi3ActivateModelPartition` call (so, whenever an `input` can be set with `fmi3Set{VariableType}`) and before `fmi3ExitInitializationMode` is called (that is before and during Initialization Mode).

2.4.7.5. Type specific properties

Type specific properties are defined in the required choice element, where exactly one float, integer, boolean, binary, enumeration, or Clock, must be present in the XML file: Figure 24, Figure 25, Figure 26, Figure 27, Figure 28 and Figure 29, are representative examples.

Figure 24. Float64 element.
Figure 25. Int32 element.
Figure 26. Boolean element.
Figure 27. Binary element.
Figure 28. Enumeration element.
Figure 29. Clock element.

The attributes are defined in Table 16 and Table 18, except:

Table 22. TypeDefinition attribute details.
Attribute Description

`declaredType`

If present, name of type defined with `<TypeDefinitions><TypeDefinition>`. The value defined in the corresponding `<TypeDefinition>` (see Section 2.4.4) is used as default. [For example, if `min` is present both in variable type element of `<TypeDefinition>` and in the concrete variable type element of the variable, then the `min` of the variable is actually used.] For `<Enumeration>` the attribute `declaredType` is required because the `<Enumeration>` items are defined in `<TypeDefinitions><TypeDefinition>`. For all other types, this attribute is optional.

`initial`

Enumeration that defines how the variable is initialized, i.e. if a `fmi3Set{VariableType}` is allowed and how the FMU internally treats this value in Instantiated and Initialization Mode.

For the variable with `causality` = `independent`, the attribute `initial` must not be provided, because its start value is set with the `startTime` parameter of `fmi3EnterInitializationMode`.

The attribute `initial` for other variables can have the following values and meanings:

`= exact`: The variable is initialized with the `start` value (provided under the variable type element).

`= approx`: The `start` value provides an approximation that may be modified during initialization, e.g., if the FMU is part of an algebraic loop where the variable might be an iteration variable and `start` value is taken as initial value for an iterative solution process.

`= calculated`: The variable is calculated from other variables during initialization. It is not allowed to provide a `start` value.

[The environment decides when to use the `start` value of a variable with `causality` = `input`. Examples: * Automatic tests of FMUs are performed, and the FMU is tested by providing the `start` value as `constant` `input`. * For a Model Exchange FMU, the FMU might be part of an algebraic loop. If the `input` variable is iteration variable of this algebraic loop, then initialization starts with its `start` value.]

If `fmi3Set{VariableType}` is not called on a variable with `causality` = `input`, then the FMU must use the `start` value as value of this `input`.

`start`

Initial or guess value of variable. This value is also stored in the C functions. [Therefore, calling `fmi3Set{VariableType}` to set `start` values is only necessary, if a different value as stored in the XML file is desired. It is not allowed to change the start values in the `modelDescription.xml` file of an FMU, as this would break the consistency with the hard-coded start values in the C-Code. This could lead to unpredictable behavior of the FMU in different importing tools, as it is not mandatory to call `fmi3Set{VariableType}` to set start values during initialization. Instead it is recommended to use the SSP Standard (https://ssp-standard.org/) to handle modified parameters of FMUs or different parameter sets.]

The `start` is either a single value or a list of values. The serialization of a multi-dimensional array variable is described in Section 2.2.6.1. If only a single value is given for a multi-dimensional array, all values of the multi-dimensional array are equal to this value.

For variables of type `<String>`, the start values are not given as a list in the `start` attribute but as a sequence of `<Start>` elements with a `value` attribute.

[ Example: Start values of string array variable

``````<String name="strings" valueReference="1" causality="parameter" variability="tunable">
<Dimension start="3"/>
<Start value="First string" />
<Start value="Second string" />
<Start value="Third string" />
</String>``````

]

The interpretation of `start` is defined by variable attribute `initial`. A different `start` value can be provided with an `fmi3Set{VariableType}` function before `fmi3ExitInitializationMode` is called (but not for variables with `variability` = `constant`).

[The standard approach is to set the `start` value before `fmi3EnterInitializationMode`. However, if the initialization shall be modified in the calling environment (for example, changing from initialization of states to steady-state initialization), it is also possible to use the `start` value as iteration variable of an algebraic loop: using an additional condition in the environment, such as ${\dot{x} = 0}$ , the actual `start` value is determined.]

If `causality` = `output` or `local`, then the `start` value is either an `initial` or a `guess` value, depending on the setting of attribute `initial`.

`derivative`

If present, this variable is the derivative of variable with value reference `derivative`. [For example, if there are 10 variables and `derivative = 3` for variable 8, then variable 8 is the derivative of variable 3 with respect to the `independent` variable (usually time). This information might be especially used if an `input` or an `output` is the derivative of another `input` or `output`, or to define the `states`.]

The `state` `derivatives` of an FMU are listed as elements `<ContinuousStateDerivative>` in `<ModelStructure>`. All variables listed in this element must have attribute `derivative` (in order that the continuous-time `states` are uniquely defined).

`reinit`

Only for Model Exchange (if only a Co-Simulation FMU, this attribute must not be present. If both Model Exchange and a Co-Simulation FMU, this attribute is ignored for co-simulation):
Can only be present for a continuous-time `state`.
If `true`, `state` can be reinitialized at an event by the FMU.
If `false`, `state` will not be reinitialized at an event by the FMU.

If `initial` is not present in a type that can have that attribute, its value is defined by Table 23 based on the values of `causality` and `variability` (default underlined):

 `variability` `causality` `structural Parameter` `parameter` `calculated Parameter` `input` `output` `local` `independent` — — — — exact exact — `fixed` data exact exact calculated, approx — — calculated, approx — exact exact calculated, approx — — calculated, approx — `discrete` variables — — — exact calculated, exact, approx calculated, exact, approx — `continuous` variables — — — exact calculated, exact, approx calculated, exact, approx —

[Note: For `local` and `output` variables and `initial` = `exact`, then the variable is explicitly set in Initialization Mode. The value of the variable is either the `start` value stored in a variable element `<XXX start=YYY/>` or the value set with `fmi3Set{VariableType}` during Initialization Mode.]

2.4.7.5.1. Variable Naming Conventions

With attribute `variableNamingConvention` in `<fmiModelDescription>`, the convention is defined how the variable names have been constructed. If this information is known, the environment may be able to represent the names in a better way (for example, as a tree and not as a linear list).

In the following definitions, the EBNF is used:

```=   production rule
[ ] optional
{ } repeat zero or more times
|   or```

The names must be unique, non-empty strings.
[It is recommended that the names are visually clearly different from each other; but it is not required.]

The following conventions for scalar names are defined:

```name = Unicode-char { Unicode-char } // identical to xs:normalizedString
Unicode-char = any Unicode character without carriage return (#xD),
line feed (#xA) nor tab (#x9)```

Structured names are hierarchical using "." as a separator between hierarchies. A name consists of "_", letters and digits or may consist of any characters enclosed in single apostrophes. A name may identify an array element on every hierarchical level using "[…​]" to identify the respective array index. If an array is a leaf node of the variable hierarchy then the array can also be represented as a single variable of type array. A `derivative` of a variable is defined with `der(name)` for the first time derivative and `der(name,N)` for the N-th derivative. Examples:

```vehicle.engine.speed
resistor12.u
v_min
robot.axis.'motor #234'
der(pipe[3,4].T[14],2) // second time derivative of pipe[3,4].T[14]```

The precise syntax is:

```name            = identifier | "der(" identifier ["," unsignedInteger ] ")"
identifier      = B-name [ arrayIndices ] {"." B-name [ arrayIndices ] }
B-name          = nondigit { digit | nondigit } | Q-name
nondigit        = "pass:[_]" | letters "a" to "z" | letters "A" to "Z"
digit           = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"
Q-name          = "'" ( Q-char | escape ) { Q-char | escape } "'"
Q-char          = nondigit | digit | "!" | "#" | "" | "%" | "&" | "(" | ")" | "*" | "+" | "," | "-" | "." | "/" | ":" | ";" | "<" | ">" | "=" | "?" | "@" | "[" | "]" | "^" | "{" | "}" | "|" | "~" | " " escape = "\'" | "\"" | "\?" | "\\" | "\a" | "\b" | "\f" | "\n" | "\r" | "\t" | "\v" arrayIndices = "[" unsignedInteger {"," unsignedInteger} "]" unsignedInteger = digit { digit }``` [This definition is identical to the syntax of an identifier in Modelica version 3.2.] The tree of names is mapped to an ordered list of variable names in depth-first order. Example: ```vehicle transmission ratio outputSpeed engine inputSpeed temperature``` is mapped to the following list of variable names: ```vehicle.transmission.ratio vehicle.transmission.outputSpeed vehicle.engine.inputSpeed vehicle.engine.temperature``` All flattened array elements are given in a consecutive sequence of variables. Elements of multi-dimensional arrays are ordered according to "row major" order that is elements of the last index are given in sequence. [For example, the vector `centerOfMass` in body `arm1` is mapped to the following variables: ```robot.arm1.centerOfMass[1] robot.arm1.centerOfMass[2] robot.arm1.centerOfMass[3]``` [For example, a controller might receive 3 rpm sensors mapped to the following variables: ```transmission.rpms[0] transmission.rpms[1] transmission.rpms[2]``` For example, a table `T[4,3,2]` (first dimension 4 entries, second dimension 3 entries, third dimension 2 entries) is mapped to the following variables: ```T[1,1,1] T[1,1,2] T[1,2,1] T[1,2,2] T[1,3,1] T[1,3,2] T[2,1,1] T[2,1,2] T[2,3,1] ...``` ] It might be that not all elements of an array are present. If they are present, they are given in consecutive order in the XML file. The `variableNamingConvention` `structured` does not define if arrays are 0-based or 1-based. [FMI 3.0 introduces arrays of variables to improve handling of arrays.] 2.4.8. Definition of the Model Structure The structure of the model is defined in element `<fmiModelDescription><ModelStructure>`. It defines the dependencies between variables. The required part of the model structure defines an ordering of the `outputs`, the (exposed) `derivatives`, the event indicators, and the unknowns that are available during Initialization. A Model Exchange FMU must expose all `derivatives` of its continuous-time `states` in `<ContinuousStateDerivative>` in `<ModelStructure>` elements and must expose all event indicators in `<EventIndicator>` elements. The optional part of the model structure defines in which way `derivatives`, `outputs`, and initial unknowns depend on `inputs` and/or `parameters`, and continuous-time `states`, at the current super-dense time instant (ME) or at the current communication point (CS and SE). The listed `dependencies` declare the dependencies between whole (multi-dimensional-)variables and not individual elements of the variables. [Dependencies of individual array elements can be retrieved during runtime using `fmi3GetVariableDependencies`.] Figure 30 shows the definition of `<ModelStructure>`. Figure 30. ModelStructure element. Note that attribute `dependenciesKind` for element `<InitialUnknown>` has less enumeration values as `dependenciesKind` in the other lists, as detailed in Table 24. `<ModelStructure>` consists of the elements detailed in Table 24 (see also Figure 30; the symbols of the mathematical equations describing the dependency are defined in Section 3.1): Table 24. ModelStructure elements. Element Description `Output` Ordered list of all outputs, in other words, a list of value references where every corresponding variable must have `causality` = `output` (and every variable with `causality` = `output` must be listed here). [Note that all `output` variables are listed here, especially `discrete` and `continuous` `outputs`. The ordering of the variables in this list is defined by the exporting tool. Usually, it is best to order according to the declaration order in the source model, since then the `<Output>` list does not change if the declaration order of `outputs` in the source model is not changed. This is for example, important for linearization, in order that the interpretation of the output vector does not change for a re-exported FMU.] Attribute `dependencies` defines the dependencies of the `outputs` from the knowns at the current super-dense time instant in Event and in Continuous-Time Mode (ME) and at the current communication point (CS and SE). Attribute `dependencies` for `output` `Clocks` lists all known variables (including input clocks) that contribute to trigger a clock tick for that output clock. Beside the knowns, the `outputs` also depend on "frozen" variables (= variables which cannot be changed in the current mode) but these "frozen" variables are not listed as `dependencies`. The functional dependency is defined as (dependencies of variables that are fixed in Event and Continuous-Time Mode and at communication points are not shown): ${(\mathbf{y}_c, \mathbf{y}_d) := \mathbf{f}_{\mathit{output}}(\mathbf{x}_c, \mathbf{u}_c, \mathbf{u}_d, t, \mathbf{p}_{\mathit{tune}})}$ `ContinuousStateDerivative` Ordered list of all state derivatives, in other words, a list of value references where every corresponding variable must be a state derivative. [Note that only `continuous` floating point variables are listed here. If a `state` or a `derivative` of a `state` shall not be exposed from the FMU, or if states are not statically associated with a variable (due to dynamic state selection), then dummy variables have to be introduced, for example, `x[4]`, or `xDynamicStateSet2[5]`. The ordering of the variables in this list is defined by the exporting tool. Usually, it is best to order according to the declaration order of the `states` in the source model, since then the `<ContinuousStateDerivative>` list does not change if the declaration order of states in the source model is not changed. This is for example, important for linearization, in order that the interpretation of the state vector does not change for a re-exported FMU.] The corresponding continuous-time `states` are defined by attribute `derivative` of the corresponding variable state derivative element. [Note that higher order derivatives must be mapped to first order derivatives but the mapping definition can be preserved due to attribute `derivative`. Example: if ${\frac{\text{ds}}{\text{dt}} = v,\ \frac{\text{dv}}{\text{dt}} =f(..)}$ ,then ${\left\{ v,\ \frac{\text{dv}}{\text{dt}} \right\}}$ is the vector of state derivatives and attribute `derivative` of ${v}$ references ${s}$ , and attribute `derivative` of ${\frac{\text{dv}}{\text{dt}}}$ references ${v}$ .] For Co-Simulation, elements `<ContinuousStateDerivative>` are ignored if capability flag `providesDirectionalDerivatives` has a value of `false`, in other words, it cannot be computed. [This is the default. If an FMU supports more than Model Exchange , then the `<ContinuousStateDerivative>` elements might be present, since it is needed for Model Exchange. If the above flag is set to `false` for the Co-Simulation cases, then the `<ContinuousStateDerivative>` elements are ignored for Co-Simulation. If "inline integration" is used for a co-simulation FMU, then the model still has continuous-time `states` and just a special solver is used (internally the implementation results in a discrete-time system, but from the outside, it is still a continuous-time system).] Attribute `dependencies` defines the dependencies of the state derivatives from the knowns at the current super-dense time instant in Event and in Continuous-Time Mode (ME) and at the current communication point (CS and SE). Beside the knowns the derivatives also depend on the "frozen" variables (= variables which cannot be changed in the current mode) but these "frozen" variables are not listed as `dependencies`. The functional dependency is defined as (dependencies of variables that are fixed in Event and Continuous-Time Mode and at communication points are not shown): ${\dot{\mathbf{x}_c} := \mathbf{f}_{\mathit{der}}(\mathbf{x}_c, \mathbf{u}_c, \mathbf{u}_d, t, \mathbf{p}_{\mathit{tune}})}$ `ClockedState` A `ClockedState` is part of the discrete state of a model partition and represented by a clocked variable. To which Clock or Clocks it belongs is described by the attribute `clocks`. Each `ClockedState` must have the attribute `previous` to represent the previous value of this `ClockedState`. All clocked states must have `variability == discrete`. `InitialUnknown` Ordered list of all exposed unknowns in Initialization Mode. This list consists of all variables which - are not clocked variables and have `causality` = `output` (with `initial` = `approx` or `calculated`), or - are continuous-time `states` or state derivatives (defined with elements `<ContinuousStateDerivative>`) with `initial` = `approx` or `calculated` [if a Co-Simulation FMU does not define the `<ContinuousStateDerivative>` elements, (3) cannot be present], or - are clocked variables that the FMU wishes to initialize in initialization mode. The resulting list is not allowed to have duplicates (for example, if a `state` is also an `output`, it is included only once in the list). Attribute `dependencies` defines the dependencies of the unknowns from the knowns in Initialization Mode at the initial time. Beside the knowns the initial unknowns also depend on the "frozen" variables (= variables which cannot be changed in the current mode) but these "frozen" variables are not listed as `dependencies`. The functional dependency is defined as: ${\mathbf{v}_{\mathit{initialUnknowns}} := \mathbf{f}_{\mathit{init}}(\mathbf{u}_c, \mathbf{u}_d, t_0, \mathbf{v}_{\mathit{initial=exact}})}$ Since, `outputs`, continuous-time `states` and state derivatives are either present as knowns (if `initial` = `exact`) or as unknowns (if `initial` = `approx` or `calculated`), they can be inquired with `fmi3Get{VariableType}` in Initialization Mode. `EventIndicators` are available during Initialization Mode, however their dependencies are intended for debugging purposes only (and not for connection with other FMU’s), and therefore they must not be listed as `<InitialUnknown>`. [Example: Assume an FMU is defined in the following way: ${(\mathbf{y}_{c+d}, \dot{\mathbf{x}}_c) := \mathbf{f}_{\mathit{init}}(\mathbf{x}_c, \mathbf{u}_{c+d}, t_0, \mathbf{p})}$ ${(\mathbf{y}_{c+d}, \dot{\mathbf{x}}_c) := \mathbf{f}_{\mathit{sim}}(\mathbf{x}_c, \mathbf{u}_{c+d}, t_i, \mathbf{p})}$ Therefore, the initial state ${\mathbf{x}_c(t_0)}$ has `initial` = `exact` and the initial state derivative ${\dot{\mathbf{x}}_c(t_0)}$ has `initial` = `calculated`. The environment can still initialize this FMU in steady-state, by using ${\mathbf{x}_c(t_0)}$ as iteration variables and adding the equations ${\dot{\mathbf{x}}_c(t_0) = \mathbf{0}}$ in the environment.] `EventIndicator` An ordered list of all event indicators, in other words, a list of value references where every referenced variable must be an event indicator. The serialized and concatenated values of the variables referenced by the attribute `valueReference` form the array that can be retrieved with `fmi3GetEventIndicators`. Only `continuous` variables of type `Float32` and `Float64` can be referenced by `<EventIndicator>`. [If an event indicator shall not be exposed from the FMU, or if event indicators are not statically associated with a variable (due to dynamic event indicator selection), then dummy variables have to be introduced, for example, `eventIndicator[4]`. The ordering of the variables in this list is defined by the exporting tool.] For Co-Simulation, elements `<EventIndicator>` are ignored. [If an FMU supports both Model Exchange and Co-Simulation, then the `<EventIndicator>` elements might be present, since it is needed for Model Exchange.] Table 25. `<Output>`, `<ContinuousStateDerivative>`, `ClockedState`, `<InitialUnknown>`, and `<EventIndicator>` attribute details. Attribute Description `valueReference` The value reference of the unknown ${v_{\mathit{unknown}}}$. `dependencies` Optional attribute defining the dependencies of the unknown ${v_{\mathit{unknown}}}$ (directly or indirectly via auxiliary variables) with respect to ${\mathbf{v}_{\mathit{known}}}$. If not present, it must be assumed that the unknown depends on all knowns. If present as empty list, the unknown depends on none of the knowns. Otherwise the unknown depends on the knowns defined by the given value references. Knowns ${\mathbf{v}_{\mathit{known}}}$ in Event Mode and Continuous-Time Mode (ME) and at communication points (CS and SE) for `<Output>` and `<ContinuousStateDerivative>` elements: * inputs (variables with `causality` = `input`), * continuous states and discrete-time states, * parameters (variables with `causality` = `parameter`), * `independent` variable (usually time; `causality` = `independent`). Knowns ${\mathbf{v}_{\mathit{known}}}$ in Initialization Mode (for elements `<InitialUnknown>`): * inputs (variables with `causality` = `input`), * variables with `initial` = `exact`, [for example, `parameters` or initial `states`] * `independent` variable (usually time; `causality` = `independent`). For Co-Simulation, if the capability flag `providesDirectionalDerivatives` has a value of `false`, then `dependencies` does not list the dependency on continuous-time. In other words, the respective partial derivatives cannot be computed. `dependenciesKind` If `dependenciesKind` is present, `dependencies` must be present and must have the same number of list elements. If not present, it must be assumed that the unknown ${\mathbf{v}_{\mathit{unknow}}}$ depends on the knowns ${\mathbf{v}_{\mathit{known}}}$ without a particular structure. Otherwise, the corresponding known ${\mathbf{f}_{\mathit{known},i}}$ enters the equation as: `= dependent`: no particular structure, ${{\mathbf{f}(..,\ v}_{\mathit{known},i}}$,..) Only for floating point type unknowns ${\mathbf{v}_{\mathit{unknown}}}$: `=` `constant`: constant factor, ${c \cdot \mathbf{v}_{\mathit{known},i}}$ where ${c}$ is an expression that is evaluated before `fmi3EnterInitializationMode` is called. Only for floating point type unknowns ${\mathbf{v}_{\mathit{unknown}}}$ in Event and Continuous-Time Mode (ME) and at communication points (CS and SE), and not for `<InitialUnknown>` for Initialization Mode: `=` `fixed`: fixed factor, ${p \cdot \mathbf{v}_{\mathit{known},i}}$ where ${p}$ is an expression that is evaluated before `fmi3ExitInitializationMode` is called. `=` `tunable`: tunable factor, ${p \cdot \mathbf{v}_{\mathit{known},i}}$ where ${p}$ is an expression that is evaluated before `fmi3ExitInitializationMode` is called and in Event Mode due to event handling (ME) or at a communication point (CS and SE) `=` `discrete`: discrete factor, ${d \cdot \mathbf{v}_{\mathit{known},i}}$ where ${d}$ is an expression that is evaluated before `fmi3ExitInitializationMode` is called and in Event Mode due to an external or internal event or at a communication point (CS and SE). [Example 1: An FMU is defined by the following equations: \begin{align*} \frac{d}{\text{dt}}\begin{bmatrix} x_{1} \\ x_{2} \\ x_{3} \\ \end{bmatrix} &= \begin{bmatrix} f_{1}\left( x_{2} \right) \\ f_{2}\left( x_{1} \right) + 3 \cdot p^{2} \cdot x_{2} + 2 \cdot u_{1} + 3 \cdot u_{3} \\ f_{3}\left( x_{1},x_{3},u_{1},u_{2},u_{3} \right) \\ \end{bmatrix} \\ y &= g_1(x_2, x_3) \end{align*}, where ${u_{1}}$ is a continuous-time `input` (`variability` = `continuous`), ${u_{2}}$ is any type of `input`, ${u_{3}}$ is a floating point discrete-time `input` (`variability` = "discrete"`), and ${p}$ is a `fixed` `parameter` (`variability` = `fixed`). The initialization is defined by: $x_1 = 1.1, \frac{dx_2}{dt} = 0, y = 3.3,$ and therefore, the initialization equations are: \begin{align*} x_{2} &= \frac{1}{3 \cdot p^{2}} \cdot ( f_{2}\left( x_{1} \right) + 2 \cdot u_{1} + 3 \cdot u_{3} ) \\ x_{3} &= g_{1}^{- 1}( x_{2}, y) \end{align*} This equation system can be defined as: ``````<ModelVariables> <Float64 name="p" valueReference= "1"/> <Float64 name="u1" valueReference= "2"/> <Float64 name="u2" valueReference= "3"/> <Float64 name="u3" valueReference= "4"/> <Float64 name="x1" valueReference= "5"/> <Float64 name="x2" valueReference= "6"/> <Float64 name="x3" valueReference= "7"/> <Float64 name="der(x1)" valueReference= "8" derivative="5"/> <Float64 name="der(x2)" valueReference= "9" derivative="6"/> <Float64 name="der(x3)" valueReference="10" derivative="7"/> <Float64 name="y" valueReference="11" causality="output"/> </ModelVariables> <ModelStructure> <Output valueReference="11" dependencies="6 7"/> <ContinuousStateDerivative valueReference="8" dependencies="6"/> <ContinuousStateDerivative valueReference="9" dependencies="2 4 5 6" dependenciesKind="constant constant dependent fixed"/> <ContinuousStateDerivative valueReference="10" dependencies="2 3 4 5 6" /> <InitialUnknown valueReference="6" dependencies="2 4 5"/> <InitialUnknown valueReference="7" dependencies="2 4 5 11"/> <InitialUnknown valueReference="8"/> <InitialUnknown valueReference="10"/> <InitialUnknown valueReference="11"/> </ModelStructure>`````` Example 2: $y = \left\{ \begin{matrix} 2 \cdot u \ \mathrm{if} \ u > 0 \\ 3 \cdot u \ \mathrm{else} \\ \end{matrix}\right.$ where ${u}$ is a continuous-time `input` with `valueReference` = `1` and ${y}$ is a continuous-time `output` with `valueReference` = `2`. The definition of the model structure is then: ``````<ModelStructure> <Output valueReference="2" dependencies="1" dependenciesKind="discrete"/> <InitialUnknown valueReference="2"/> </ModelStructure>`````` [Note that ${y = d \cdot u}$ where ${d}$ changes only during Event Mode ( ${d = 2 \cdot u}$ or ${3 \cdot u\ }$ depending on relation ${u > 0}$ that changes only at Event Mode). Therefore `dependenciesKind` = `discrete`.] Example 3: $y = \left\{ \begin{matrix} 2\ \ \mathrm{if}\ \ u > 0 \\ 3\ \ \mathrm{else} \\ \end{matrix}\right.$ where ${u}$ is a continuous-time `input` with `valueReference` = `1` and ${y}$ is a continuous-time `output` with `valueReference` = `2`. The definition of the model structure is then: ``````<ModelStructure> <Output valueReference="2" dependencies="1" dependenciesKind="dependent"/> <InitialUnknown valueReference="2"/> </ModelStructure>`````` [Note that ${y = c}$ where ${c}$ changes only during Event Mode ( ${c = 2}$ or ${3\ }$ depending on relation ${u > 0}$ that changes only at Event Mode). Therefore `dependenciesKind` = `dependent` because it is not a linear relationship on ${u}$. ] Example 4: $\frac{dx}{dt}=u, y=x$ where `u` is continuous-time input value reference `1`, `y` is a continuous-time output with value reference `2` and `dxdt` is a continuous-time derivative with value reference `4`. The definition of the model structure is then: ``````<ModelVariables> <Float64 name="u" valueReference= "1"/> <Float64 name="y" valueReference= "2" causality="output"/> <Float64 name="x" valueReference= "3"/> <Float64 name="dxdt" valueReference= "4"/> </ModelVariables> <ModelStructure> <Output valueReference="2" dependencies="3" dependenciesKind="constant"/> <ContinuousStateDerivative valueReference="4" dependencies="1" dependenciesKind="constant"/> <InitialUnknown valueReference="2" dependencies="3"/> </ModelStructure>`````` Defining FMU features with the `dependencies` list: [Note that via the `dependencies` list the supported features of the FMU can be defined. Examples: 2.4.9. Definition of Terminals and Icons Terminals define semantic groups of variables to ease connecting compatible signals on the system level. This definition adds an additional layer to the interface description of the FMUs. It does not change the `causality` of the variables (i.e. inputs and outputs), but enables the definition of physical and bus-like connectors that require special handling on the system level by the importer (e.g. flow variables and bus frames). Icons define a graphical representation of an FMU and its terminals. Both features are optional and can be defined in the separate XML file `icons/terminalsAndIcons.xml`. [The usage of a separate file enables backporting of this feature to previous FMI versions.] Figure 31. fmiTerminalsAndIcons element. On the top level, the schema consists of the following elements (see Figure 31). Table 26. fmiTerminalAndIcons element details. Attribute or Element Description `fmiVersion` This attribute declares the FMI version defining the XSD of the `icons/terminalsAndIcons.xml` file. Starting with FMI 3.0, this `fmiVersion` attribute must match the `fmiVersion` attribute of element Section 2.4.1 of the `modelDescription.xml` file. If used in previous FMI versions, this attribute points to the FMI version defining this `icons/terminalsAndIcons.xml` file (e.g. XSD, file location). `<GraphicalRepresentation>` If present, contains information for importers of FMUs to draw graphical representations of the FMU in a system view. `<Terminals>` If present, this allows combining input and output variables into logical groups to ease connections on a system level and add semantic information required for system-level connections. 2.4.9.1. Definition of a Graphical Representation 2.4.9.1.1. Overview The graphical representation of the FMU and terminals are needed to more easily comprehend the meaning of connected FMUs and to help importers to display the terminals and the FMU icon in the way the exporter intended. The graphical representation is fully optional. The graphical representation of terminals is separate from the terminal definitions in the `<Terminals>` element. There are two optional elements in the `<GraphicalRepresentation>`: • The element `<CoordinateSystem>` defines the extent of the whole icon, graphical items may exceed that rectangle. • The element `<Icon>` defines the image position. Figure 32. GraphicalRepresentation element. 2.4.9.1.2. CoordinateSystem Figure 33. CoordinateSytem element. The `<CoordinateSystem>` element and its extent is used as reference for other graphical items. It also provides a scaling factor to millimeter. The coordinate system is defined by the coordinates of two points, the lower left (`x1`, `y1`) corner and the upper right (`x2`, `y2`) corner, where the coordinates of the first point shall be less than the coordinates of the second point [a first quadrant coordinate system]. The x-axis is directed to the right, the y-axis is directed upwards. [The exporting tool should define how the coordinate system unit relates to mm display or printout size. However, an importing tool might choose to use the factor from the default coordinate system extent to the actual coordinate system extent to calculate a scaling factor, to match the default icon size in the importing tool. The area defined by the coordinate system is suggested to be used as "clickable icon size" in importers. A `<Terminal>` might be placed outside of this area, therefore the visible bounding box has to be determined by the importing tool.] The coordinate system default is `x1=-100, y1=-100, x2=100, y2=100`. This extent is used if the `<CoordinateSystem>` element is missing. The default `suggestedScalingFactorTo_mm` is `0.1`. So the default coordinate system display size should be `20 mm` width and `20 mm` height. The FMU icon and all graphical representations provide the position and extent with the attributes `x1`, `y1`, `x2`, `y2`. The values of these attributes directly relate to this coordinate system and are not normalized. Flipping of the FMU icon or a terminal can be realized by setting its attributes `x2 < x1` or `y2 < y1` without changing the coordinate system. 2.4.9.1.3. Icon Figure 34. Icon element. The extent and position of the FMU icon are defined in the `<Icon>` element. The optional image file of the FMU icon is placed at the path `icons/icon.png` in the ZIP archive of the FMU. The terminals should not be visible in the image. Optionally an SVG file with path `icons/icon.svg` can be provided if also the PNG file is present. This enables high quality rendering and printing in importing tools. The point (`x1`, `y1`) maps to the left lower corner of the PNG image or SVG viewport. The point (`x2`, `y2`) maps to the right upper corner of the PNG image or SVG viewport. 2.4.9.1.4. Placement, Extent, and Painting Order of Graphical Items The clickable icon size is defined by the `<CoordinateSystem>` element. The FMU icon itself may exceed this extent (or bounding box). The bounding box of the terminals is given by the extent in the terminals element. Their location is neither limited to the extent of the icon nor the extent of the coordinate system. [An importing tool has to determine the outer bounding box enclosing all graphical items.] Transparent SVG or PNG files are allowed and wanted. The order of the elements in the XML file defines the order of painting. The first element in the `<TerminalGraphicalRepresentation>` is painted first and therefore behind the others, the last element is painted on top of the others and because of that in front of them. [So the FMU icon should be placed first in the XML file, terminal below.] 2.4.9.2. Definition of Terminals 2.4.9.2.1. Overview Terminals are fully optional and can be ignored by any importing tool. A terminal is: • a structured interface for connections to other models, • intended to be used for signal flow between models, parameter propagation, and compatibility checks of the model configuration, and • a sequence of references to variables with connection meta data. Predefined rules for variable matching in a connection are given in Table 27. Predefined variable kinds are used to describe how the terminal member variables have to be handled. Domain specific connection rules, terminals and their member variables can be provided by other standards. [Algebraic loops in systems of connected FMUs are not addressed or resolved by the terminals. The FMU standard does not require that the `causality` of the terminal member variables in connected terminals match. This must be handled by the importer. The System Structure & Parameterization Standard (SSP) refers to a `connectorKind`. This `connectorKind` is not related to the `terminalKind` or `variableKind` described in Section 2.4.9.2.2 and Section 2.4.9.2.3.] 2.4.9.2.2. Terminals Element `<fmiTerminalsAndIcons><Terminals>` is defined as: Figure 35. Terminals element. The normalized string attribute `name` of the `<Terminal>` element is the instance name of the terminal. The terminal name must be unique on each level. The normalized string attribute `matchingRule` describes the rules for variable matching in a connection of terminals. As detailed in Table 27, there are three predefined matching rules: `plug`, `bus`, and `sequence`. Other standards may define new matching rules. In order to avoid ambiguities and conflicts, rule names must follow the reverse domain notation of a domain that is controlled by the entity defining the semantics and content of the additional entries. The rule names beginning with `org.modelica` and `org.fmi-standard` are explicitly reserved for use by Modelica Association Project FMI-defined layered standards. Table 27. Predefined matching rules. `matchingRule` Description `plug` Matching of the variables is based on `memberName`. An importing tool should connect terminals only if all member variables are present and match. `bus` Matching of the variables is based on `memberName`. An importing tool may connect terminals if some or no terminal member variables are present. `sequence` Matching of the variables is based on the order of the terminal member variables. An importing tool should connect terminals only if the number of member variables matches. The normalized string `terminalKind` is an optional attribute. Other standards may define terminal kinds. It is intended that the `terminalKind` is used to define domain specific member variable sequences, member names and order, or high level restrictions for connections. [Externally defined terminal kinds should refer to a predefined `matchingRule`, if possible. Vendor specific terminal kinds should start with `_vendorName` or `_toolName` to avoid namespace clashes. Examples for `terminalKind`: `StandardXXX_Mechanical_Translational`, `Modelica.Mechanics.Translational.Interfaces.Flange_a`, `vendorNameA_customTypeA`, `_vendorNameB_customLibrary_customTypeB`. The structured naming convention of the `<ModelVariables>` is independent from the terminal names and member variable names. A tool may choose to connect terminals with a different or unknown `terminalKind`, if the `matchingRule` matches.] 2.4.9.2.3. Terminal Member Variable The `<TerminalMemberVariable>` is defined as: Figure 36. TerminalMemberVariable element. The normalized string `variableName` identifies a variable in `<ModelVariables>` which is actually connected and for which `fmi3Get{VariableType}` and `fmi3Set{VariableType}` is called. If the `matchingRule` `plug` and `bus` are used, then `memberName` is used for variable matching. Therefore, the `memberName` attribute is required for `plug` and `bus` and must be unique per terminal. The `memberName` is not required for `matchingRule` `sequence`. The normalized string `variableKind` is used to provide general information about the variable. This information defines how the connection of this variable has to be implemented (e.g. Kirchhoff’s current law or common signal flow). The predefined `variableKind` are: .Predefined kinds of variables. `variableKind` Description `signal` The values in connected terminals are intended to be equal. Restricted to `input` and `output`, `parameter` and `calculatedParameter`. [Example: Signal flow, parameter propagation, equality checks] `inflow` / `outflow` Variables which fulfill Kirchhoff’s current law. Restricted to `input` and `output`, `parameter` and `calculatedParameter`. [Example: Electric current] [The suggested variable naming scheme for the structured naming convention is <ModelVariable name> = <terminalName>.<memberName>. Not all `<ModelVariables>` which have the prefix "<terminalName>." are a member variable, and there may exist member variables which don’t have this prefix. Example 1 (suggested scheme): <ModelVariable name> is `portA.U`, <terminalName> is `portA`, <memberName> is `U`. Example 2 (suggested scheme): <ModelVariable name> is `hierarchConn.innerConn.U`, <outer terminal name> is `hierarchConn`, <inner terminal name> is `innerConn`, <memberName> is `U`. Example 3 (no prefix): <ModelVariable name> is `u`, <terminalName> is `portA`, <memberName> is `u`. Example 4 (prefix but not a member): <ModelVariable name> is `portA.u`, there is a terminal with <terminalName> `portA`, but this variable is not a terminal member. The suggested variable naming scheme for the non-structured naming convention is: <ModelVariable name> = <memberName> Matching is not restricted by `variability`, `causality` or variable type. Example: A `fixed` variable may be connected to a `tunable` variable, a variable of type `fmi3Float64` may be connected to a variable of type `fmi3Int32`. However, it is recommended that the variable types and variabilities are equal. The `matchingRule` refers to the `<TerminalMemberVariable>` on the same level only. Nested terminals can have different `matchingRule`s. There is no special handling of `derivatives`. If a `derivative` is a terminal member variable then it is considered as normal member variable. However, if a `derivative` of a terminal member variable is not terminal member, then this `derivative` information may be used by an importing tool.] 2.4.9.2.4. Terminal Stream Member Variable The `<TerminalStreamMemberVariable>` is defined as: Figure 37. TerminalStreamMemberVariable element. This element is used for variables which fulfill the balance equation for transported quantities. It is restricted to `input` and `output`, `parameter` and `calculatedParameter`. The Stream concept is described in the appendix D.3 of the Modelica specification. Only one terminal member variable with the `variableKind` `inflow` or `outflow` per terminal is allowed, if a `<TerminalStreamMemberVariable>` is present. [More sophisticated structures can be implemented using hierarchical terminals.] The attribute `inStreamVariableName` and `outStreamVariableName` are used to identify the `<ModelVariables>`. If the referenced model variables are arrays, then the size of the `inStreamVariableName` and `outStreamVariableName` has to be equal. A terminal may have more than one `<TerminalStreamMemberVariable>`. The `inStreamMemberName` and `outStreamMemberName` describe the terminal member name for matching purposes, similar to the `memberName` attribute in the `<TerminalMemberVariable>`. [An example of use for an array of stream variables is a gas mixture flow. The gas composition could be implemented as a mass fraction vector. The `outStreamVariableName` refers to $portA.q_\textit{outStream}\textit{[]}$ and the `inStreamVariableName` refers to $portA.q_\textit{inStream}\textit{[]}$ . The `inStreamMemberName` and `outStreamMemberName` are " $q_\textit{inStream}\textit{[]}$ " and " $q_\textit{outStream}\textit{[]}$ ". Balance equation for transported quantities: $0 = \sum{q_i\dot{m}_i}$ $0 = \sum{\dot{m}_i}\cdot \left\{\begin{array}{ll} q_{i, \mathit{outStream}} &\textit{if \dot{m} is outflowing through terminal i}\\ q_{i, \mathit{inStream}} &\textit{if \dot{m} is inflowing through terminal i} \end{array}\right.$ The $q_{i,\mathit{outStream}}$ is the convective quantity in case the matter flows out of the FMU. $q_{i,\mathit{inStream}}$ is the convective quantity in case the matter flows into the FMU. Both variables are present in the terminal. The outStream variable has the `causality` `output` or `calculatedParameter` because this information has to be provided by each FMU. The inStream variable has the `causality` `input` or `parameter`. To display the actual value in an importing tool, this actual value has to be selected depending on the sign of the terminal member variable with `variableKind` `inflow` or `outflow`. However, calculating the actual value is not necessary. If only two terminals with a variable are connected and their `causality` matches, then the values of the outStream variables can be forwarded to the corresponding inStream values. In Modelica the inStream variable is not directly visible, the value can only be accessed using "inStream()", therefore an additional model variable has to be added during the export. It is suggested that Modelica tools exporting an FMU derive the member name for the inStream variable according to the scheme "<outStream name>_inStream". E.g. if the outStream name is "h_outflow" then the inStream name should be "h_outflow_inStream".] 2.4.9.2.5. Terminal Graphical Representation The `<TerminalGraphicalRepresentation>` is defined as: Figure 38. TerminalGraphicalRepresentation element. The `iconBaseName` attribute is mandatory. This attribute defines the base name of the image file as a relative URI according to RFC 3986. The base URI that this relative URI is resolved against is the URI of the `icons/terminalsAndIcons.xml` file in the FMU ZIP archive. Implementations are required to support relative URIs, excluding relative URIs that move beyond the baseURI (i.e. go "up" a level via ..). Implementations are not required to support any absolute URIs and any specific URI schemes. The PNG file with the extension '.png' has to be provided. An additional SVG file with extension '.svg' is optional. [Note that this specification is functionally equivalent to looking up image sources from the icons folder of the FMU ZIP archive after dot removal from the path as per section 5.2.4 of RFC 3986.] The `defaultConnectionStrokeSize` and `defaultConnectionColor` can be provided to define the intended connection line layout in the importing tool. The stroke size is given relative to the coordinate system extent. The stroke color is given in RGB values from 0 to 255. E.g.: `255 255 0`. [Nested terminals may have a `<TerminalGraphicalRepresentation>` element. However, if and how nested terminals are displayed, is up to the importing tool.] [The order of painting of the `<TerminalGraphicalRepresentation>` of terminals on each level is equal to the order of appearance in the `<Terminal>` element. So graphical representations appearing first, are painted first, are behind graphical representations which appear below.] The `Annotations` element can be used by vendors to store additional information for the graphical representation. [It is suggested that Modelica tools store the Modelica annotation of the connector under the `type` `org.modelica.Modelica4Annotation` in the annotations of an element `connector`. The attribute `name` of the connector element is equal to the `name` attribute of the referenced `fmi3Terminal`.] [If the graphical representation is used for an `input` or `output` (e.g. a `fmi3Float64` `input` `u`), then a `<Terminal>` has to be added to the `<Terminals>` element which has one `<TerminalMemberVariable>`.] 2.4.9.2.6. General Remark on Signal [The signal `variableKind` can be applied for different use cases. The first use case is a signal flow from an `output` of one FMU to an `input` of another FMU. The `output` value has to be forwarded to the `input`. The signal flow can cause algebraic loops. If variables in connected terminals have the `causality` `output`, then an importing tool may iterate an undefined `input` of an FMU to ensure that the connected output values are equal. Another use case is the parameter propagation. If a variable in both connected terminals has the `causality` `parameter`, then an importing tool could ask the user for the value of one of those `parameters` only, and propagate this value to the other FMU. If only one of the variables has `causality` `parameter`, and the other is a `constant` `output` or `calculatedParameter`, then the importing tool could also propagate the `parameter` value without presenting a parameter to the user. One example of use would be the name of a substance flowing through a pipe. If the fluid flows from one pipe FMU to another, the substance should be the same. This substance name could be propagated over several FMUs. Finally the `variableKind` `signal` can be applied to implement compatibility checks. If for example the `variability` of the variables in connected terminals are `constant`, then the importing tool can implement an equality assertion. This is also possible with `calculated` `parameters`. One example of use would be the cross sectional flow area in pipes which is calculated from geometry parameters. A change in the cross sectional flow area is relevant for the momentum equation, and therefore the connection has to be deemed incompatible if these variables are present and unequal.] 2.4.9.2.7. General Remark on Inflow and Outflow [Flow variables have a direction and must fulfill a zero sum constraint i.e. the sum of all flow variables connected must be zero (Kirchhoff’s current law). In addition because different tools might have different direction definitions both, `inflow` and `outflow` are available as `variableKind`. For variables with `inflow` a positive value means that the flow is inwards, and for `outflow` a positive value means that the flow is outwards. For the sake of simplicity in the following $\dot{m}_i$ denotes an inflowing quantity: $0 = \sum{\dot{m}_i}$ [Connecting a single `output` `outflow` to a single `input` `inflow`, or vice versa automatically fulfills the flow constraint, while connecting two variables of the same flow type requires a negation of the variable value. `inflow` and `outflow` is only used as a sign convention for scalar flow quantities which obey Kirchhoff’s current law (sum up to zero). Other, nonscalar, quantities which also sum up to zero, like a mechanical force in 3D space according to D’Alembert’s principle, are not covered by this sign convention. This is the case since Kirchhoff’s current law only holds for scalars where a sign convention is sufficient. Other definitions are beyond the scope of this terminal specification and need clear definition in other specifications on top of this.] 2.5. FMU Distribution An FMU consists of several files, that are stored in a ZIP file with a pre-defined structure. The implementation of the simulation model represented by the FMU may be distributed in source code and/or in binary format. The FMU must be distributed with at least one implementation, in other words, either sources or one of the binaries for a particular machine. It is also possible to provide the sources and binaries for different target machines together in one ZIP file. The FMU must implement all common API functions according to Section 2.2 and the functions for at least one of the interface types. Especially it is required that all functions that are part of the specified interface type are present, even if they are only needed for optional capabilities that the FMU does not support. The behavior of those functions is unspecified, so while calling environments can rely on the functions being present, they cannot rely on any particular behavior for functions only needed for capabilities the FMU does not support. The extension of the ZIP file must be `.fmu` [, for example, `HybridVehicle.fmu`]. The compression method for all files stored in the ZIP archive must be either 8 (`deflate`), or 0 (`store`). Only files stored using compression method 8 (`deflate`) may be stored with general purpose bit 3 set. The field `version needed to extract` of the archive must not be higher than 2.0, and encryption must not be employed. The archive may not be a split or spanned ZIP archive. [These restrictions ensure broad compatibility of the archive with common ZIP processing tools and libraries.)] [Note: especially section 4.4.17 of the ZIP format specification states that backslashes "\" are forbidden as path separator, only forward slashes "/" are allowed. Non-ASCII directory names are not explicitly forbidden, but might pose a problem on different operating systems and are thus discouraged.] Every FMU is distributed with its own ZIP file. 2.5.1. Structure of the ZIP file Structure of the ZIP file ```// Structure of ZIP file of an FMU modelDescription.xml // description of FMU (required file) documentation // directory containing the documentation (optional) index.html // entry point of the documentation diagram.png // descriptive diagram view of the model (optional) diagram.svg // if provided, diagram.png is also required (optional) externalDependencies.{txt|html} // documentation of external resources required to load or simulate the FMU <other documentation files> licenses // directory for licenses (optional) license.{txt|html} // entry point for license information <license files> // for example BSD licenses icons // FMU and terminal icons (optional) terminalsAndIcons.xml // description of terminals and icons (optional) icon.png // image file of icon without terminals (optional) icon.svg // if existing the icon.png is required (optional) // all terminal and fmu icons referenced in the graphical representation sources // directory containing the C sources (optional) buildDescription.xml binaries // directory containing the binaries (optional) x86_64-windows // binaries for Windows on Intel 64-bit <modelIdentifier>.dll // shared library of the FMI implementation <other DLLs> // the DLL can include other DLLs x86_64-windows-msvc140mt // static libraries for 64-bit Windows generated <modelIdentifier>.lib // with Visual Studio 2015 with /MT flag i686-linux // binaries for Linux on Intel 32-bit <modelIdentifier>.so // shared library of the FMI implementation aarch32-linux // binaries for Linux on ARM 32-bit <modelIdentifier>.so // shared library of the FMI implementation x86_64-darwin // binaries for macOS <modelIdentifier>.dylib // shared library of the FMI implementation resources // resources used by the FMU (optional) extra // Additional (meta-)data of the FMU (optional)``` 2.5.1.1. Directory Documentation Structure of the ZIP file defines the files expected in the `documentation` directory. If the FMU depends on external resources [e.g. shared libraries, files, or servers] to be loaded or simulated `documentation/externalDependencies.{txt|html}` must be present to document these dependencies and how to provide them. 2.5.1.1.1. Directory Licenses This optional subdirectory can be used to bundle all license texts for the code, binaries or other material (documentation, content of resources folder) contained in the FMU. If it is present, it must contain either a license.spdx, `license.txt` or `license.html` file as entry point. [It is strongly recommended to include all license and copyright related information in the licenses folder of an FMU (especially but not only for contained open source software) - the `license.{txt|html}` file can serve as an entry point for describing the contained licenses. This will help the users to comply with license conditions when passing source or binary code contained in an FMU to other persons or organizations.] 2.5.1.2. Directory Icons See Section 2.4.9 for a definition of the directory `icons`. 2.5.1.3. Directory Sources A source code FMU contains the sources of the model in the `sources` directory together with a `buildDescription.xml` that contains at least one `<BuildConfiguration>` element for the supported platforms. The header files `fmi3PlatformTypes.h`, `fmi3FunctionTypes.h` and `fmi3Functions.h` are supplied by the importer to potentially reflect their specific platform and compiler tool set. Each `<BuildConfiguration>` provides the necessary information to compile and link the sources of the model into a dynamic library or as part of an executable. An FMU importing tool may not regard more than one `<BuildConfiguration>` when building the FMU for a specific `platform`. The importer chooses the matching `<BuildConfiguration>` based on the `platform` and `modelIdentifier` attributes. In order to avoid symbol name conflicts when compiling and linking multiple source code FMUs, source files should keep the exported symbols to a minimum by declaring all symbols not needed for linking as `static`. If only a single `<SourceFile>` is provided in the `<BuildConfiguration>` all symbols except for the FMI functions should be defined as `static`. This source file may include other source files that are not listed in the `<BuildConfiguration>`. It is also recommended to use a descriptive name (e.g. `<model_identifier>.c`) for this single `<SourceFile>` instead of generic names (like `all.c`, or `model.c`) in order to aid readability and reduce integration effort. Table 28. BuildConfiguration attribute details. Attribute Description `modelIdentifier` The attribute `modelIdentifier` of the `<ModelExchange>`, `<CoSimulation>` or `<ScheduledExecution>` elements this build configuration is associated with. `platform` Platform tuple of the platform the `<BuildConfiguration>` is intended for (e.g. `x86_64-linux`). All `platform` attributes defined in the `<BuildConfiguration>` elements for the same `<modelIdentifier>` must be unique. For each `platform` there can only be one matching `<BuildConfiguration>`. This attribute is optional. Thus there must not be more than one `<BuildConfiguration>` without a `platform` attribute. If a `<BuildConfiguration>` without a `platform` attribute is provided this is the fallback `<BuildConfiguration>` an importer can use if it cannot find any other `<BuildConfiguration>` with a matching `platform` attribute. `description` Description of the build configuration 2.5.1.3.1. SourceFileSet The `<SourceFileSet>` element groups source files that can be compiled with the same compiler and compiler options. Every build configuration must contain at least one `<SourceFileSet>`. An importer of the FMU has to regard every `<SourceFileSet>` of the matching `<BuildConfiguration>`. Table 29. SourceFileSet attribute details. Attribute Description `name` Name of the `<SourceFileSet>` `language` Language of the source files (e.g. `C99`, `C++11`) `compiler` The compiler to compile the sources (e.g. `VisualC`, `gcc`, `clang++`) `compilerOptions` The compiler flags that have to be used when compiling the sources (e.g. `-fno-rtti`, `/Od`) 2.5.1.3.2. SourceFile Table 30. SourceFile attribute details. Attribute Description `name` Path of the source file relative to the `sources` directory 2.5.1.3.3. PreprocessorDefinition The `<PreprocessorDefinition>` element defines a preprocessor definition that needs to be passed to the compiler when compiling the source files in the `<SourceFileSet>`. Table 31. ProcessorDefintition attribute details. Attribute Description `name` Name of the preprocessor definition `value` Value of the preprocessor definition `optional` Determines wether the definition is optional (default is `false`) `description` Description of the preprocessor definition 2.5.1.3.4. PreprocessorDefinition/Option The `<Option>` element defines a possible value for the `<PreprocessorDefinition>`. If a `<PreprocessorDefinition>` contains `<Option>` elements, its default value must be contained in the options. Table 32. PreprocessorDefintition attribute details. Attribute Description `value` Value of the preprocessor definition option `description` Description of the preprocessor definition option 2.5.1.3.5. IncludeDirectory The `<IncludeDirectory>` element defines the include directories that need to be passed to the compiler when compiling the source files in the `<SourceFileSet>`. Table 33. IncludeDirectory attribute details. Attribute Description `name` Path of the include directory relative to the `sources` directory [Note that the header files `fmi3PlatformTypes.h` and `fmi3FunctionTypes.h/fmi3Functions.h` are not included in the FMU because: `fmi3PlatformTypes.h` makes no sense in the `sources` directory, because if sources are provided, then the importer defines this header file and not the FMU. This header file is not included in the `binaries` directory, because it is implicitly defined by the platform directory (for example, `i686-windows` for a 32-bit machine or `x86_64-linux` for a 64-bit machine). `fmi3FunctionTypes.h` / `fmi3Functions.h` are not needed in the `sources` directory, because they are implicitly defined by attribute `fmiVersion` in file `modelDescription.xml`. Furthermore, in order that the C compiler can check for consistent function arguments, the header file from the importer should be used when compiling the C sources. It would therefore be counter-productive (unsafe) if this header file was present. These header files are not included in the `binaries` directory, since they are already utilized to build the executable of the simulation environment. The version number of the header file used to construct the FMU can be deduced via attribute `fmiVersion` in file `modelDescription.xml` or via function call `fmi3GetVersion`.] 2.5.1.3.6. Library The `<Library>` element defines a static library required to link the model binary. An importer of the FMU has to link every library of the matching `<BuildConfiguration>`. Table 34. Library attribute details. Attribute Description `name` Name of the library `version` Version specifier of the library as defined in PEP 440. The characters `>` (greater-than) and `<` (less-than) must be escaped as `>` and `<`. [For example `2.5`, `>=2.0,<3.0` or `>=1.0,!=1.2`]. `external` Boolean attribute that determines wether the library is contained in the `binaries/<platform_tuple>` directory (`false`) or if it has to be provided by the environment (`true`). The default is `false`. `description` Description of the library definition option 2.5.1.3.7. Examples A minimal build configuration ``````<?xml version="1.0" encoding="UTF-8"?> <fmiBuildDescription fmiVersion="3.0-beta.2"> <BuildConfiguration modelIdentifier="PIDContoller"> <SourceFileSet> <SourceFile name="PIDContoller.c"/> </SourceFileSet> </BuildConfiguration> </fmiBuildDescription>`````` Multiple complex build configurations ``````<?xml version="1.0" encoding="UTF-8"?> <fmiBuildDescription fmiVersion="3.0-beta.2"> <BuildConfiguration modelIdentifier="PlantModel" description="Build configuration for desktop platforms"> <SourceFileSet language="C99"> <SourceFile name="fmi3Functions.c"/> <SourceFile name="solver.c"/> </SourceFileSet> <SourceFileSet language="C++11"> <SourceFile name="model.c"/> <SourceFile name="logging/src/logger.c"/> <PreprocessorDefinition name="FMI_VERSION" value="3"/> <PreprocessorDefinition name="LOG_TO_FILE" optional="true"/> <PreprocessorDefinition name="LOG_LEVEL" value="0" optional="true"> <Option value="0" description="Log infos, warnings and errors"/> <Option value="1" description="Log warnings and errors"/> <Option value="2" description="Log only errors"/> </PreprocessorDefinition> <IncludeDirectory name="logging/include"/> </SourceFileSet> <Library name="hdf5" version="&gt;=1.8,!=1.8.17,&lt;1.10" external="true" description="HDF5"/> </BuildConfiguration> <BuildConfiguration modelIdentifier="PlantModel" platform="aarch64-linux"> <SourceFileSet language="C99"> <SourceFile name="fmi3Functions.c"/> </SourceFileSet> <SourceFileSet language="C++11" compiler="clang++" compilerOptions="-fno-rtti"> <SourceFile name="model.c"/> <PreprocessorDefinition name="NO_FILE_SYSTEM"/> </SourceFileSet> <Library name="libm.a" description="OpenLibm math library"/> </BuildConfiguration> </fmiBuildDescription>`````` 2.5.1.4. Directory Binaries If an FMU is run through one of its binaries all items in that binary folder must be unpacked at the same location as the binary `<modelIdentifier>.*`. 2.5.1.4.1. Platform Tuple Definition The names of the binary directories are standardized by the "platform tuple". Further names can be introduced by vendors. FMUs should contain all resources that are required to load and execute a shared library, link against a static library, or compile from source. Shared libraries should be statically linked against their dependencies [e.g. the Visual Studio C Runtime on Windows]. `RPATH="ORIGIN"` should be set when building ELF binaries to allow dynamic loading of dependencies on the target machine. All external dependencies must be documented (see Section 2.5.1.1).

The binaries must be placed in the respective <platformTuple> directory with the general format `<arch>-<sys>{-<abi>{<abi_ver>}{<abi_sub>}}`.

Architecture `<arch>`
Name Description

aarch32

ARM 32-bit Architecture

aarch64

ARM 64-bit Architecture

i386

Intel 3rd generation x86 32-bit

i586

Intel 5th generation x86 32-bit w/o SSE

i686

Intel 6th generation x86 32-bit with SSE2

x86_64

Intel/AMD x86 64-bit

Operating system `<sys>`
Name Description

darwin

Darwin (macOS, iOS, watchOS, tvOS, audioOS)

linux

Linux

windows

Microsoft Windows

Application Binary Interface (ABI) `<abi>`
Name Description

elf

ELF file format

gnu

GNU

android

Android

macho

Mach object file format

msvc

Microsoft Visual C

ABI version `<abi_ver>`
Name Description

80

Visual Studio 2005 (MSVC++ 8.0)

90

Visual Studio 2008 (MSVC++ 9.0)

100

Visual Studio 2010 (MSVC++ 10.0)

110

Visual Studio 2012 (MSVC++ 11.0)

120

Visual Studio 2013 (MSVC++ 12.0)

140

Visual Studio 2015 (MSVC++ 14.0)

141

Visual Studio 2017 (MSVC++ 15.x)

142

Visual Studio 2019 (MSVC++ 16.x)

Sub-ABI `<abi_sub>`
Name Description

md

Visual Studio with /MD

mt

Visual Studio with /MT

mdd

Visual Studio with /MDd

mtd

Visual Studio with /MTd

[Typical scenarios are to provide binaries only for one machine type (for example, on the machine where the importer is running and for which licenses of runtime libraries are available) or to provide only sources (for example, for translation and download for a particular micro-processor).]

2.5.1.4.2. Platform Tuple Examples

The following table lists the most common platform tuples for shared libraries and the corresponding FMI 2.0 platform.

Name FMI 2.0 Description

x86_64-darwin

darwin64

macOS on 64-bit x86

aarch64-darwin

macOS on Apple Silicon

i386-linux

linux32

Linux on 32-bit x86

x86_64-linux

linux64

Linux on 64-bit x86

aarch64-linux

Linux on ARM64

i386-windows

win32

Windows on 32-bit x86

x86_64-windows

win64

Windows on 64-bit x86

aarch64-windows

Windows on ARM64

2.5.1.4.3. External Libraries

If runtime libraries are needed by the FMU that have to be present on the target machine and cannot be shipped within the FMU (e.g., due to licensing issues), then automatic processing is likely impossible. In such cases special handling is needed, for example, by providing the runtime libraries at appropriate places by the receiver. The requirements and the expected processing should be documented in the `documentation` directory in this case.

2.5.1.5. Directory Resources

In the optional directory `resources`, additional data can be provided in FMU specific formats, typically for tables and maps used in the FMU. More folders can be added under `resources` (tool/model specific). For the FMU to access these resource files, the resources directory shall be available in extracted form and the absolute path to this directory is provided via argument `resourcePath` of `fmi3InstantiateXXX`. The resources directory must be available for the lifetime of the FMU instance. The FMU instance must not write to or delete the directory or parts of it.

The `resource` data must be read into the model at the latest during initialization (that is, before `fmi3ExitInitializationMode` is called). The actual file names in the ZIP file to access the data files can either be hard-coded in the generated FMU functions, or the file names can be provided as string arguments via the `fmi3SetString` function. [Note that an URI pointing to the resources directory is provided by the initialization functions. If the environment is not able to do so, a NULL pointer will be provided instead, and the FMU can react with an error, if it requires access to the content of the resources folder.] In the case of an FMU implementation of `needsExecutionTool = true` type, the `resources` directory can contain the model file in the tool specific file format.

2.5.1.6. Directory Extra

The ZIP archive may contain additional entries with the prefix `extra/` that can be used to store additional data and meta-data. In order to avoid ambiguities and conflicts, the extra files should be provided in subdirectories using a reverse domain notation of a domain that is controlled by the entity defining the semantics and content of the additional entries [(for example `extra/com.example/SimTool/meta.xml` or `extra/org.example.stdname/data.asd`)]. The use of subdirectories beginning with `org.modelica` and `org.fmi-standard` is explicitly reserved for use by MAP FMI-defined layered standards, i.e. other uses must not use subdirectory names beginning with these prefixes. It is explicitly allowed for tools and users other than the original creator of an FMU to modify, add or delete entries in the `extra/` directory without affecting the validity of the FMU in all other aspects. Specifically all validation or digital signature schemes used to protect the content of the FMU should take the variability of extra file content into account [(for example by having separate checksums or signatures for FMU core content and extra content, or not having signatures at all for extra content)].

2.5.2. Multiple Interface Types

Exporters may support multiple FMI types in one FMU, so it can be used in differently capable simulation algorithms and for different use cases. To indicate support for a specific interface type, the `<fmiModelDescription>` must have the respective element present, irrespective if a specific interface type is contained in binary or source format.

[The described multi-mode support is often based on wrapping functionality into the `fmi3DoStep` function by emulating missing features of the Model Exchange and Scheduled Execution interface types.]

```[Example of different libraries:
binaries
x86_64-windows
MyModel_ModelExchange.dll      // modelIdentifier of <ModelExchange> =
//    "MyModel_ModelExchange"
MyModel_CoSimulation.dll       // modelIdentifier of <CoSimulation> =
//    "MyModel_CoSimulation"
]```

Support of multiple interface types in one FMU is possible only, if the interface variables are identical.

2.5.3. Dependency on Installed Tool

FMI provides the means for two kinds of implementation: `needsExecutionTool = true` and `needsExecutionTool = false`. In the first case, a tool specific wrapper DLL/SharedObject/Source is part of the FMU. In the second case, all components necessary for execution of the FMU are included with the FMU.

2.5.4. Import Examples

The following code examples demonstrate how to access the FMI functions of FMUs that are implemented as a shared library or static library / source code.

2.5.4.1. Accessing FMI Functions in Shared Libraries
``````/* This example demonstrates how to import an FMU implemented as a shared library */

#ifdef _WIN32
#include <Windows.h>
#else
#include <dlfcn.h>
#endif

#include <stdlib.h>

// FMI function types
#include "fmi3FunctionTypes.h"

#define INSTANTIATION_TOKEN "{8c4e810f-3da3-4a00-8276-176fa3c9f000}"

#ifdef _WIN32
#define RESOURCE_LOCATION "file:/C:/tmp/VanDerPol"
#else
#define RESOURCE_LOCATION "file:///var/tmp/VanDerPol"
#endif

static void cb_logMessage(fmi3InstanceEnvironment instanceEnvironment, fmi3String instanceName, fmi3Status status, fmi3String category, fmi3String message) {
// log message...
}

int main(int argc, char* argv[]) {

#if defined(_WIN32)
#elif defined(__APPLE__)
void *libraryHandle = dlopen("VanDerPol/binaries/x86_64-darwin/VanDerPol.dylib", RTLD_LAZY);
#else
void *libraryHandle = dlopen("VanDerPol/binaries/x86_64-linux/VanDerPol.so", RTLD_LAZY);
#endif

if (!libraryHandle) {
return EXIT_FAILURE;
}

fmi3InstantiateModelExchangeTYPE *instantiateModelExchange = (fmi3InstantiateModelExchangeTYPE *)
#ifdef _WIN32
#else
dlsym(libraryHandle, "fmi3InstantiateModelExchange");
#endif

fmi3FreeInstanceTYPE *freeInstance = (fmi3FreeInstanceTYPE *)
#ifdef _WIN32
#else
dlsym(libraryHandle, "fmi3FreeInstance");
#endif

if (!instantiateModelExchange || !freeInstance) {
return EXIT_FAILURE;
}

fmi3Instance m = instantiateModelExchange(
"instance1",             // instance name
INSTANTIATION_TOKEN,     // instantiation token (from XML)
RESOURCE_LOCATION,       // resource location (extracted FMU)
fmi3False,               // visible
fmi3False,               // debug logging disabled
NULL,                    // instance environment
cb_logMessage);          // logger callback

if (!m) {
return EXIT_FAILURE;
}

// simulation...

freeInstance(m);

#ifdef _WIN32
FreeLibrary(libraryHandle);
#else
dlclose(libraryHandle);
#endif

return EXIT_SUCCESS;
}``````
2.5.4.2. Accessing FMI Functions in Static Libraries and Source Code
``````/* This example demonstrates how to import an FMU implemented as a static library or source code*/

// FMI function prefix (from XML)
#define FMI3_FUNCTION_PREFIX VanDerPol_
#include "fmi3Functions.h"
#undef FMI3_FUNCTION_PREFIX

#define INSTANTIATION_TOKEN "{8c4e810f-3da3-4a00-8276-176fa3c9f000}"

static void cb_logMessage(fmi3InstanceEnvironment instanceEnvironment, fmi3String instanceName, fmi3Status status, fmi3String category, fmi3String message) {
// log message
}

int main(int argc, char* argv[]) {

fmi3Instance m = VanDerPol_fmi3InstantiateModelExchange(
"instance1",             // instance name
INSTANTIATION_TOKEN,     // instantiation token (from XML)
"file:///tmp/VanDerPol", // resource location (extracted FMU)
fmi3False,               // visible
fmi3False,               // debug logging disabled
NULL,                    // instance environment
cb_logMessage);          // logger callback

// simulation ...

VanDerPol_fmi3FreeInstance(m);

return m ? EXIT_SUCCESS : EXIT_FAILURE;
}``````

2.6. Versioning and Layered Standards

The FMI standard uses semantic version numbers, as defined in [PW13], where the standard version consists of a triple of version numbers, consisting of major version, minor version, and patch version numbers [e.g. 1.2.3 for major version 1, minor version 2 and patch version 3].

• Major versions will introduce changes that are neither backward nor forward-compatible, including changes to the XML schemas to include new non-ignorable content.

• Minor versions will only contain clarifications and include new layered standards, which may add new ignorable XML content, as defined below, into the core standard document, indicating that the standard needs to be supported by all conforming implementations.

• Patch versions will only change explanatory text of the standard, make formerly defined content clearer, without any other changes to the XML schemas or other content definitions. For this reason, the version number attribute of all FMI files will only contain major and minor version numbers and not the patch version number: It should never be necessary for an importing tool to know the patch version number of the standard that the generating tool implemented.

In order to enable the backward-compatible extension of the FMI standard in minor releases and between minor releases, the FMI project intends the use of the layered standard mechanism to introduce new features in a fully backward-compatible and optional way.
A layered standard defines extensions to the base FMI standard by specifying either standardized annotations, standardized extra files in the FMU, and/or support for additional MIME types/file formats, defined in Section 2.4.4.
A layered standard can include a single or combined set of extension mechanisms from this set.
The layered standard is thus considered to be layered on top of the definitions and extensions mechanisms provided by this base standard.

Layered standards can fall into three categories:

• Layered standards defined by third parties, without any representations by the FMI project for their suitability or content, or even knowledge by the FMI project about their existence.

• Layered standards defined by third parties that are endorsed by the FMI project and listed on the FMI project website.

• Layered standards can be defined/adopted and published by the FMI project itself, making them FMI project layered standards.

Layered standards that have achieved enough adoption or importance to be included into the base standard set could be incorporated into a new minor or major release version of the base standard as an optional or mandatory appendix, making support for this layered standard optional or required for conformance with the newly published minor release version of the base standard.

3. FMI for Model Exchange

FMI for Model Exchange provides a standardized interface for solving ordinary differential equations with events (abbreviated as "hybrid ODE"). In contrast to FMI for Co-Simulation, a Model Exchange FMU implements the model algorithm only, without the required solution method.

The importer controls the data exchange and the synchronization between FMUs.

The solver algorithm itself is not part of the FMI standard.

The solver algorithm is responsible for:

• advancing the overall simulation time,

• exchange input and output data,

• computation of continuous state variables by time integration,

• triggering of input clocks, and

• handling events.

In contrast to Co-Simulation, the FMU is evaluated only at a specific time instant and not from one communication point to the next. A Model Exchange FMU might consist of discrete-time equations only, for example, describing a sampled-data controller.

FMI for Model Exchange enables the following features:

Which of the features above are supported by a specific FMU is defined by capability flags of the `modelDescription.xml` (see Section 3.4).

3.1. Concepts

3.1.1. Event Handling

Integration algorithms for differential equations assume continuous behavior of variables. In hybrid ODEs, there are points during the simulation, when this assumption is violated. A hybrid ODE solver must therefore:

An event indicator signals a state event with the change from $\mathbf{z}_j > 0$ to $\mathbf{z}_j \leq 0$ or vice versa.
[This definition is slightly different from the usual standard definition of state events: $\mathbf{z}(\mathbf{t}) \cdot \mathbf{z}(\mathbf{t}_\mathit{i-1}) \leq 0$ which has the severe drawback that the value of the event indicator at the previous event instant, $\mathbf{z}(\mathbf{t}_\mathit{i-1}) \neq 0$, must be non-zero and this condition cannot be guaranteed. The often used term "zero crossing function" for $\mathbf{z}$ is misleading (and is therefore not used in this document), since a state event is defined by a change of a domain and not by a zero crossing of a variable.]

The FMU must guarantee that after leaving Event Mode $\mathbf{z}_j \neq 0$, for example, by shifting $\mathbf{z}_j$ with a small value.
[All event indicators should be continuous between events. Furthermore, $\mathbf{z}_j$ should be scaled in the FMU with its nominal value (so all elements of the returned vector `eventIndicators` should be in the order of 1).]

Figure 39. An event occurs when the event indicator changes its domain from $\mathbf{z}>0$ to $\mathbf{z} \leq 0$ or vice versa.

During event localization the FMU might be evaluated after the switch of an event indicator. Even when an event indicator switches, its corresponding relation must stay "frozen" to assure the continuity assumption of the integration algorithm. This allows an integration algorithm to properly finish the current integration step.

In Table 4, vector $\mathbf{r}$ is used to label all relations. In Continuous-Time Mode all these relations are "frozen". This is indicated in the mathematical description of Event Mode by computing_ ${}^\bullet\mathbf{r}$ when leaving Event Mode and using ${}^\bullet\mathbf{r}$ in the right-hand side of ${\mathbf{f}_{\mathit{cont}}}$ and ${\mathbf{f}_{\mathit{comp}}}$ in mathematical description of Continuous-Time Mode.

[Example: An assignment of the form

`y = ((x1 > x2) || (x1 < x3)) ? +1 : -1;`

can be implemented in the FMU as:

```// event indicator computation:
z1 = x1 - x2;
z2 = x3 - x1;

// relations do not change in Continuous Time Mode
if Initialization Mode || Event Mode {
r1 = z1 > 0;
r2 = z2 > 0;
}
y = (r1 || r2) ? +1 : -1;```

Therefore, the original if-clause is evaluated in this form only during Initialization Mode and Event Mode. A hysteresis should be added for the event indicators to stabilize the event localization.]

3.2. State Machine for Model Exchange

The state machine in Figure 40 defines the allowed calling sequences for FMI for Model Exchange.

Figure 40. Calling sequence of Model Exchange C functions.

3.2.1. State: Continuous-Time Mode

The Continuous-Time Mode is used to compute the values of all continuous-time variables between events by numerically solving ordinary differential and algebraic equations. All discrete-time variables are fixed during this phase and the corresponding discrete-time equations are not evaluated.

In this state, the continuous-time equations are active and integrator steps are performed.

Equations and Actions Functions Influencing Equations

$\mathbf{t} := ($`time`$, 0)$

`fmi3SetTime`

Set continuous-time `inputs` $\mathbf{u}_{c}(\mathbf{t})$

`fmi3Set{VariableType}`

Set continuous-time `states` $\mathbf{x}_{c}(\mathbf{t})$

`fmi3SetFloat64`, `fmi3SetContinuousStates`

$(\mathbf{y}_{c}, \mathbf{\dot{x}}_c, \mathbf{z}, \mathbf{w}_{c}) := \mathbf{f}_{\mathit{cont}}(\mathbf{x}_{c}, {}^\bullet\mathbf{x}_{d}, \mathbf{u}_{c}, {}^\bullet\mathbf{u}_{d}, \mathbf{p}, {}^\bullet\mathbf{r}, {}^\bullet\mathbf{b}, \mathbf{t})$

• Evaluate model equations with valid values for the right-hand side:
$(\mathbf{y}_{c}, \mathbf{\dot{x}}_c, \mathbf{z}, \mathbf{w}_{c}, \mathbf{b},$`enterEventMode`$) := \mathbf{f}_{\mathit{comp}}(\mathbf{x}_{c}, {}^\bullet\mathbf{x}_{d}, \mathbf{u}_{c}, {}^\bullet\mathbf{u}_{d}, \mathbf{p}, {}^\bullet\mathbf{r}, {}^\bullet\mathbf{b}, \mathbf{t})$

• Update previous values of buffers: ${}^\bullet\mathbf{b}:=\mathbf{b}$

`fmi3CompletedIntegratorStep`

• Evaluate $\mathbf{f}_{\mathit{cont}}$, if no `fmi3GetXXX` function was called

• Deactivate continuous-time equations $\mathbf{f}_{\mathit{cont}}$

• Activate event equations $\mathbf{f}_{\mathit{event}}$

• $\mathbf{t}:=(\mathbf{t}_\mathit{R}, 0)$

`fmi3EnterEventMode`

Allowed Function Calls
Function `fmi3SetTime`
``typedef fmi3Status fmi3SetTimeTYPE(fmi3Instance instance, fmi3Float64 time);``

Set a new value for the independent variable (typically a time instant).

Function `fmi3Set{VariableType}`

Only for variables with `causality` = `input` and `variability` = `continuous`.

Functions `fmi3Get{VariableType}`

Getting variables might trigger computations.

Function `fmi3SetContinuousStates`
``````typedef fmi3Status fmi3SetContinuousStatesTYPE(fmi3Instance instance,
const fmi3Float64 continuousStates[],
size_t nContinuousStates);``````

Set new continuous state values.

Functions `fmi3Get{VariableType}`

Getting variables might trigger computations.

Function `fmi3GetContinuousStates`

Returns the current continuous state vector.

Function `fmi3GetContinuousStateDerivatives`
``````typedef fmi3Status fmi3GetContinuousStateDerivativesTYPE(fmi3Instance instance,
fmi3Float64 derivatives[],
size_t nContinuousStates);``````

Returns the first-order derivatives with respect to the independent variable (usually time) of the continuous states.

• Return argument `derivatives` contains the derivatives for each continuous state with the same convention for the order as defined for `fmi3SetContinuousStates`.

• Argument `nContinuousStates` is the size of the `derivatives` vector.

[`fmi3Status == fmi3Discard` should be returned if the FMU was not able to compute the derivatives according to $\mathbf{f}_{\mathit{cont}}$ because, for example, a numerical issue, such as division by zero, occurred.]

Function `fmi3GetEventIndicators`
``````typedef fmi3Status fmi3GetEventIndicatorsTYPE(fmi3Instance instance,
fmi3Float64 eventIndicators[],
size_t nEventIndicators);``````

Returns the event indicators signaling state events by their sign changes.

• Return argument `eventIndicators` contains the values for the event indicators in the order defined by the ordered list of elements `<EventIndicator>`.

• Argument `nEventIndicators` is the size of the `eventIndicators` vector.

[`fmi3Status == fmi3Discard` should be returned if the FMU was not able to compute the event indicators according to $\mathbf{f}_{\mathit{cont}}$ because, for example, a numerical issue, such as division by zero, occurred.]

Function `fmi3CompletedIntegratorStep`
``````typedef fmi3Status fmi3CompletedIntegratorStepTYPE(fmi3Instance instance,
fmi3Boolean  noSetFMUStatePriorToCurrentPoint,
fmi3Boolean* enterEventMode,
fmi3Boolean* terminateSimulation);``````

This function is called after every completed step of the integrator provided the capability flag `completedIntegratorStepNotNeeded = false`. The importer must have set valid values for `time`, `continuous` `inputs` and `continuous` `states` prior to calling this function to evaluate $\mathbf{f}_{\mathit{comp}}$ with valid right-hand side data.

The function `fmi3CompletedIntegratorStep` is not used to detect time events or state events, for example, by comparing event indicators of the previous with the current call of `fmi3CompletedIntegratorStep`. Time events and state events must be detected by the importer, which has to call `fmi3EnterEventMode` in these cases, even if the returning from `fmi3CompletedIntegratorStep` with `enterEventMode == fmi3False`.]

Function `fmi3EnterEventMode`
``````typedef fmi3Status fmi3EnterEventModeTYPE(fmi3Instance instance,
fmi3Boolean stepEvent,
fmi3Boolean stateEvent,
const fmi3Int32 rootsFound[],
size_t nEventIndicators,
fmi3Boolean timeEvent);``````

This function changes the state to Event Mode.

• Model Exchange only: `stepEvent == fmi3True` signals that a step event occurs.

• Model Exchange only: `stateEvent == fmi3True` signals that a state event occurs.

• Model Exchange only: `rootsFound` is an array of length `nEventIndicators` that informs the FMU which event indicator has a root.
For `i = 0, …​ nEventIndicators-1, rootsFound[i]` informs about event indicator ${\mathbf{z}_{\mathit{i}}}$:

• `rootsFound[i] == 0` no root,

• `rootsFound[i] == +1` indicates the direction of the zero-crossing from negative to positive,

• `rootsFound[i] == -1` indicates the direction of the zero-crossing from positive to negative.

If `nEventIndicators == 0` the value of `rootsFound` is not defined. The order in the `rootsFound` array is the same as in `eventIndicators` of `fmi3GetEventIndicators`.

• Model Exchange only: `nEventIndicators` contains the number of event indicators as deduced from the list `<EventIndicator>` or `0` if the importer cannot provide this information.

• `timeEvent == fmi3True` signals that this event is a time event triggered by `nextEventTime` of `fmi3UpdateDiscreteStates`.

[An input event can be detected by the FMU by keeping track of the calls of `fmi3Set{VariableType}` in Event Mode.]

Function `fmi3GetDirectionalDerivative`

Note that simulation backward in time is only allowed over continuous time intervals. As soon as an event occurs (`fmi3EnterEventMode` was called), going back in time is forbidden, because `fmi3EnterEventMode` / `fmi3UpdateDiscreteStates` can only compute the next discrete state, not the previous one.

Note that during Initialization Mode, Event Mode, and Continuous-Time Mode, `input` variables can be set with `fmi3Set{VariableType}` and output variables can be retrieved with `fmi3Get{VariableType}` interchangeably according to the model structure defined under element `<ModelStructure>` in the XML file. [For example, if one `output` `y1` depends on two `inputs` `u1`, `u2`, then these two `inputs` must be set, before `y1` can be retrieved. If additionally an `output` `y2` depends on an `input` `u3`, then `u3` can be set and `y2` can be retrieved afterwards. As a result, artificial or `real` algebraic loops over connected FMUs in any of these three modes can be handled by using appropriate numerical algorithms.]

3.3. Code Example

In the following example, the usage of the `fmi3XXX` functions is sketched in order to clarify the typical calling sequence of the functions in a simulation environment. Furthermore, it is assumed that one FMU is directly integrated in a simulation environment. If the FMU would be used inside another model, additional code is needed, especially initialization and event iteration has to be adapted.

``````    fmi3Instance s = S->fmi3InstantiateModelExchange(
"intstance1",        // instanceName
INSTANTIATION_TOKEN, // instantiationToken
NULL,                // resourceLocation
fmi3False,           // visible
fmi3False,           // loggingOn
NULL,                // instanceEnvironment
cb_logMessage        // logMessage
);

if (s == NULL) {
status = fmi3Error;
goto TERMINATE;
}

// set the start time
fmi3Float64 time = 0;

// TODO: set all variable start values (of "ScalarVariable / <type> / start")

// initialize
// determine continuous and discrete states
CHECK_STATUS(S->fmi3EnterInitializationMode(s, fmi3False, 0.0, time, fmi3True, stopTime));

// TODO: apply input

CHECK_STATUS(S->fmi3ExitInitializationMode(s));

// intial event iteration
while (discreteStatesNeedUpdate) {

CHECK_STATUS(S->fmi3UpdateDiscreteStates(
s,
&discreteStatesNeedUpdate,
&terminateSimulation,
&nominalsOfContinuousStatesChanged,
&valuesOfContinuousStatesChanged,
&nextEventTimeDefined,
&nextEventTime));

if (terminateSimulation) {
goto TERMINATE;
}
}

CHECK_STATUS(S->fmi3EnterContinuousTimeMode(s));

#if NZ > 0
// initialize previous event indicators
CHECK_STATUS(S->fmi3GetEventIndicators(s, previous_z, NZ));
#endif

#if NX > 0
// retrieve initial state x and
// nominal values of x (if absolute tolerance is needed)
CHECK_STATUS(S->fmi3GetContinuousStates(s, x, NX));
CHECK_STATUS(S->fmi3GetNominalsOfContinuousStates(s, x_nominal, NX));
#endif

// retrieve solution at t=Tstart, for example, for outputs
// S->fmi3SetFloat*/Int*/UInt*/Boolean/String/Binary(m, ...)

while (!terminateSimulation) {

// detect time event
timeEvent = nextEventTimeDefined && time >= nextEventTime;

// handle events
if (inputEvent || timeEvent || stateEvent || stepEvent) {

CHECK_STATUS(S->fmi3EnterEventMode(s, stepEvent, stateEvent, rootsFound, NZ, timeEvent));

nominalsOfContinuousStatesChanged = fmi3False;
valuesOfContinuousStatesChanged = fmi3False;

// event iteration
do {
// set inputs at super dense time point
// S->fmi3SetFloat*/Int*/UInt*/Boolean/String/Binary(m, ...)

fmi3Boolean nominalsChanged = fmi3False;
fmi3Boolean statesChanged = fmi3False;

// update discrete states
CHECK_STATUS(S->fmi3UpdateDiscreteStates(s, &discreteStatesNeedUpdate, &terminateSimulation, &nominalsChanged, &statesChanged, &nextEventTimeDefined, &nextEventTime));

// get output at super dense time point
// S->fmi3GetFloat*/Int*/UInt*/Boolean/String/Binary(m, ...)

nominalsOfContinuousStatesChanged |= nominalsChanged;
valuesOfContinuousStatesChanged |= statesChanged;

if (terminateSimulation) {
goto TERMINATE;
}

} while (discreteStatesNeedUpdate);

// enter Continuous-Time Mode
CHECK_STATUS(S->fmi3EnterContinuousTimeMode(s));

// retrieve solution at simulation (re)start
CHECK_STATUS(recordVariables(outputFile, S, s, time));

#if NX > 0
if (valuesOfContinuousStatesChanged) {
// the model signals a value change of states, retrieve them
CHECK_STATUS(S->fmi3GetContinuousStates(s, x, NX));
}

if (nominalsOfContinuousStatesChanged) {
// the meaning of states has changed; retrieve new nominal values
CHECK_STATUS(S->fmi3GetNominalsOfContinuousStates(s, x_nominal, NX));
}
#endif
}

if (time >= stopTime) {
goto TERMINATE;
}

#if NX > 0
// compute continous state derivatives
CHECK_STATUS(S->fmi3GetContinuousStateDerivatives(s, der_x, NX));
#endif
time += fixedStep;

CHECK_STATUS(S->fmi3SetTime(s, time));

// set continuous inputs at t = time
// S->fmi3SetFloat*(m, ...)

#if NX > 0
// set states at t = time and perform one step
for (size_t i = 0; i < NX; i++) {
x[i] += fixedStep * der_x[i]; // forward Euler method
}

CHECK_STATUS(S->fmi3SetContinuousStates(s, x, NX));
#endif

#if NZ > 0
// get event indicators at t = time
CHECK_STATUS(S->fmi3GetEventIndicators(s, z, NZ));

stateEvent = fmi3False;

for (size_t i = 0; i < NZ; i++) {

// check for zero crossings
if (previous_z[i] < 0 && z[i] >= 0) {
rootsFound[i] = 1;   // -\+
} else  if (previous_z[i] > 0 && z[i] <= 0) {
rootsFound[i] = -1;  // +/-
} else {
rootsFound[i] = 0;   // no zero crossing
}

stateEvent |= rootsFound[i];

previous_z[i] = z[i]; // remember the current value
}
#endif

// inform the model about an accepted step
CHECK_STATUS(S->fmi3CompletedIntegratorStep(s, fmi3True, &stepEvent, &terminateSimulation));

// get continuous output
// S->fmi3GetFloat*(m, ...)
CHECK_STATUS(recordVariables(outputFile, S, s, time));
}

TERMINATE:

if (s && status < fmi3Error) {
// retrieve final values and terminate simulation
CHECK_STATUS(recordVariables(outputFile, S, s, time));
const fmi3Status terminateStatus = S->fmi3Terminate(s);
status = max(status, terminateStatus);
}

if (s && status < fmi3Fatal) {
// clean up
S->fmi3FreeInstance(s);
}``````

In the code above errors are handled by the following definition:

``#define CHECK_STATUS(S) status = S; if (status != fmi3OK) goto TERMINATE;``

3.4. Description Schema

The common XML elements and attributes are defined in Section 2.4. Additional elements and attributes are defined subsequently. If the FMU implements the Model Exchange interface type, the element `<ModelExchange>` must be present. It is defined as:

Figure 41. ModelExchange element.

The attributes in the following table are defined on top of the common attributes and have the following meaning (all attributes are optional with exception of `modelIdentifier`):

Table 35. ModelExchange attribute details.
Attribute Description

`modelIdentifier`

Short class name according to C syntax, for example, `A_B_C`. Used as prefix for FMI functions if the functions are provided in C source code or in static libraries, but not if the functions are provided by a DLL/SharedObject. `modelIdentifier` is also used as name of the static library or DLL/SharedObject. See also Section 2.2.1.

`completedIntegratorStepNotNeeded`

If `true`, function `fmi3CompletedIntegratorStep` need not be called. If it is called, it has no effect.
If `false` (the default), the function must be called after every completed integrator step, see `fmi3CompletedIntegratorStep`.

3.4.1. Example XML Description File

When generating an FMU from the hypothetical model `MyLibrary.SpringMassDamper`, the XML file may have the following content:

``````<?xml version="1.0" encoding="UTF-8"?>
<fmiModelDescription
fmiVersion="3.0-beta.2"
modelName="MyLibrary.SpringMassDamper"
instantiationToken="{8c4e810f-3df3-4a00-8276-176fa3c9f9e0}"
description="Rotational Spring Mass Damper System"
version="1.0"
generationDateAndTime="2011-09-23T16:57:33Z"
variableNamingConvention="structured">
<ModelExchange modelIdentifier="MyLibrary_SpringMassDamper"/>
<UnitDefinitions>
<DisplayUnit name="deg" factor="57.2957795130823"/>
</Unit>
</Unit>
<Unit name="kg.m2">
<BaseUnit kg="1" m="2"/>
</Unit>
<Unit name="N.m">
<BaseUnit kg="1" m="2" s="-2"/>
</Unit>
</UnitDefinitions>
<TypeDefinitions>
<Float64Type name="Modelica.Units.SI.Inertia" quantity="MomentOfInertia" unit="kg.m2" min="0.0"/>
<Float64Type name="Modelica.Units.SI.Torque" quantity="Torque" unit="N.m"/>
</TypeDefinitions>
<DefaultExperiment startTime="0.0" stopTime="3.0" tolerance="0.0001"/>
<ModelVariables>
<Float64 name="inertia1.J" valueReference="1073741824"
description="Moment of load inertia" causality="parameter" variability="fixed"
declaredType="Modelica.Units.SI.Inertia" start="1"/>
<Float64 name="torque.tau" valueReference="536870912"
description="Accelerating torque acting at flange (= -flange.tau)" causality="input"
declaredType="Modelica.Units.SI.Torque" start="0"/>
<Float64 name="inertia1.phi" valueReference="805306368"
description="Absolute rotation angle of component" causality="output"
declaredType="Modelica.Units.SI.Angle"/>
<Float64 name="inertia1.w" valueReference="805306369"
description="Absolute angular velocity of component (= der(phi))" causality="output"
declaredType="Modelica.Units.SI.AngularVelocity"/>
<Float64 name="x[1]" valueReference="0" initial="exact" start="0"/>
<Float64 name="x[2]" valueReference="1" initial="exact" start="0"/>
<Float64 name="der(x[1])" valueReference="2" derivative="0"/>
<Float64 name="der(x[2])" valueReference="3" derivative="1"/>
</ModelVariables>
<ModelStructure>
<Output valueReference="805306368"/>
<Output valueReference="805306369"/>
<ContinuousStateDerivative valueReference="2"/>
<ContinuousStateDerivative valueReference="3"/>
<InitialUnknown valueReference="805306368"/>
<InitialUnknown valueReference="805306369"/>
<InitialUnknown valueReference="2" dependencies="0 536870912"/>
<InitialUnknown valueReference="3" dependencies="0 1"/>
</ModelStructure>
</fmiModelDescription>``````

4. FMI for Co-Simulation

FMI for Co-Simulation provides a standardized interface for execution of simulation models or tools in a co-simulation environment. In contrast to FMI for Model Exchange, a Co-Simulation FMU implements not only the model algorithm, but also the required solution method. The data exchange between FMUs is restricted to discrete communication points $\mathbf{t}_i$ (unless Intermediate Update Mode is used). In the time between two communication points (or between entering Intermediate Update Mode), the subsystem inside an FMU is solved independently by internal means. This leads to a delay for information "traveling through" the FMU, so there cannot be an immediate reaction (direct feedthrough) as in Initialization Mode, Event Mode or Continuous-Time Mode. The co-simulation algorithm of the importer controls the data exchange and the synchronization between FMUs.

The co-simulation algorithm itself is not part of the FMI standard.

The co-simulation algorithm is responsible for:

• advancing the overall simulation time,

• exchange input and output data,

• triggering of input clocks, and

• handling events.

For FMI for Co-Simulation the co-simulation algorithm is shielded from how the FMU advances time internally. [For example, FMUs containing ODEs and implementing FMI for Co-Simulation require to include an ODE solver inside the FMU to internally advance time between the communication points. As another example, FMUs representing controller code, an internal scheduling algorithm can trigger tasks at the correct time and order while advancing time to the next communication point.]

FMI for Co-Simulation enables the following features, allowing co-simulation algorithms of arbitrary sophistication:

Which of the features above are supported by a specific FMU is defined by capability flags of the `modelDescription.xml` (see Section 4.4).

4.1. Concepts

4.1.1. Smoothness, Continuity and Discontinuity

Since inputs will be set at specific communication points by the importing tool, the FMU must make assumptions about the values between these communication points, including points of intermediate updates.

Between communication points, even in Intermediate Update Mode, all changes must be assumed to be continuous. Changes to `continuous` variables are only considered discrete in Event Mode.

If a `continuous` input changes discontinuously (e.g. the actual input value deviates too much from the extrapolation polynomial), the co-simulation algorithm must raise an event (if supported) to indicate to the FMU a discontinuous change at an `continuous` input. In the case of Co-Simulation without Event Mode (see `eventModeUsed` and `hasEventMode`), detecting discrete changes to continuous input variables (for instance to reset the integration algorithm within the FMU) requires heuristics.

`Discrete` inputs keep their values between communication points. Furthermore, changing `discrete` variables at communication points will likely require special handling within the FMU. Since the FMU itself can detect such changes, the co-simulation algorithm does not need to enter Event Mode in such a case, but must do so, in case event iteration is required.

4.1.2. Early Return

A Co-Simulation FMU is allowed to stop the execution of `fmi3DoStep` and return without reaching the predefined communication time, i.e. `currentCommunicationPoint` `+` `communicationStepSize`. This mechanism is called "early return".

Early return can be used to shorten a communication step because of:

• an event happened inside the FMU which influences its outputs non-continuously.

• the importer requests the stop of the current communication step in Intermediate Update Mode. [E.g. the importer wants to stop a communication step because other parts of the simulation indicate the necessity.]

• the FMU requests an additional communication point. [E.g. the FMU wants to communicate extrema of outputs or prevent model inconsistencies, like negative pressure values, caused by extrapolation of inputs.]

For details see `earlyReturn`.

The following capability flags describe which features the FMU supports: `canReturnEarlyAfterIntermediateUpdate` and `hasEventMode`.

The argument `earlyReturnAllowed` of `fmi3InstantiateCoSimulation` signals to the FMU if the importer allows "early return".

4.2. State Machine for Co-Simulation

The state machine in Figure 42 defines the allowed calling sequences for FMI for Co-Simulation.

Figure 42. Calling sequence of Co-Simulation C functions.

Compared to FMI for Model Exchange, `fmi3ExitInitializationMode` enters directly into Step Mode. This was designed in case the Co-Simulation FMU does not support Event Mode. Importers can directly switch a Co-Simulation FMU into Event Mode without calling `fmi3DoStep` to handle events immediately after initialization.

4.2.1. State: Step Mode

The state Step Mode is used to compute the values of all variables between communication points and events and to advance time in the FMU. If the FMU is connected in loops with other models, iterations over the FMU equations requires setting the FMU to a previous communication point and repeating the `fmi3DoStep`.

Equations and Actions Functions Influencing Equations

Set `tunable` `parameters` $\mathbf{p}_{\mathit{variability == tunable}}$ .

`fmi3Set{VariableType}`

Set continuous-time and discrete-time `inputs` $\mathbf{u}_{c+d}(\mathbf{t})$.

`fmi3Set{VariableType}`

Get values of variables $\mathbf{v}(\mathbf{t})$.

`fmi3Get{VariableType}`

Get time derivatives of `continuous` `outputs` $\mathbf{y}_c^{(j)}(\mathbf{t})$.

`fmi3GetOutputDerivatives`

• $(\mathbf{y}_{c+d}, \mathbf{y}_c^{(j)}, \mathbf{x}_d, \mathbf{w}_{c+d}, \mathbf{b}, \mathbf{t}_\mathit{i+1}) := \mathbf{f}_{\mathit{doStep}}({}^{\bullet}\mathbf{x}_d, \mathbf{u}_{c+d}, {}^{\bullet}\mathbf{u}_{c,u}, \mathbf{p}, {}^{\bullet}\mathbf{b}, \mathbf{t}_i, \mathbf{h}_i)$

• Update previous values of discrete states: ${}^\bullet\mathbf{x}_d:=\mathbf{x}_d$.

• Update previous values of buffers: ${}^\bullet\mathbf{b}:=\mathbf{b}$.

• $\mathbf{t}:=(\mathbf{t}_\mathit{i+1}, 0)$

`fmi3DoStep`

$(\mathbf{v}_{u}, \mathbf{t}_u) := \mathbf{f}_{\mathit{inter}}({}^{\bullet}\mathbf{x}_d, \mathbf{u}_{c+d}, {}^{\bullet}\mathbf{u}_{c,u}, \mathbf{p}, {}^{\bullet}\mathbf{b}, \mathbf{t}_i, \mathbf{h}_i)$

`fmi3CallbackIntermediateUpdate`

Activate event equations $\mathbf{f}_{\mathit{event}}$.

`fmi3EnterEventMode`

Allowed Function Calls
Function `fmi3Set{VariableType}`

sets the values of variables with:

at time $\mathbf{t}$.

Function `fmi3Get{VariableType}`

returns values for all variables at $\mathbf{t}$. `fmi3Get{VariableType}` does not trigger an evaluation of $\mathbf{f}_\mathit{doStep}$. Therefore, algebraic loops at communication points cannot be handled by an appropriate sequence of `fmi3Get{VariableType}` and `fmi3Set{VariableType}` calls [contrary to Initialization Mode, Event Mode and Continuous-Time Mode]. Repeating a communication step requires to reset the FMU state to the previous communication point with `fmi3SetFMUState` and repeating the `fmi3DoStep` with new input values.

Calling `fmi3Get{VariableType}` is not allowed after `fmi3Set{VariableType}` without calling `fmi3DoStep` in between. [This allows for more efficient FMU implementations that avoid double buffering and allows in-place operations.]

Function `fmi3GetOutputDerivatives`

See Section 2.2.12.

Function `fmi3GetDirectionalDerivative`
Function `fmi3GetAdjointDerivative`
Function `fmi3DoStep`

The importer requests the computation of the next time step with the following function:

``````typedef fmi3Status fmi3DoStepTYPE(fmi3Instance instance,
fmi3Float64 currentCommunicationPoint,
fmi3Float64 communicationStepSize,
fmi3Boolean noSetFMUStatePriorToCurrentPoint,
fmi3Boolean* eventEncountered,
fmi3Boolean* terminateSimulation,
fmi3Boolean* earlyReturn,
fmi3Float64* lastSuccessfulTime);``````

Only `fmi3DoStep` can change the time of a Co-Simulation FMU from the outside (time advances internally during `fmi3DoStep`). Arguments referring to time inherit the the unit of the `independent` variable.

Function `fmi3CallbackIntermediateUpdate`

`fmi3CallbackIntermediateUpdate` switches the FMU itself into the Intermediate Update Mode.

Function `fmi3EnterEventMode`

Changes state to Event Mode. This function must not be called, if `fmi3InstantiateCoSimulation` signaled `eventModeUsed = fmi3False`, which can be forced by the FMU with `hasEventMode == false`.

Function `fmi3EnterConfigurationMode`

`fmi3EnterConfigurationMode` changes state to Reconfiguration Mode. `fmi3EnterConfigurationMode` must not be called if the FMU contains no `tunable` `structural parameters` (i.e. with `causality`= `structuralParameter` and `variability` = `tunable`).

4.3. Code Examples

4.3.1. Co-Simulation

In the following example, the usage of the FMI functions is sketched in order to clarify the typical calling sequence of the functions in a simulation environment. We consider two FMUs, where both have one `continuous` floating point `input` and one `continuous` floating point `output` which are connected in the following way:

Figure 43. Connection graph of FMUs.

We assume no algebraic dependency between input and `output` of each FMU. The code demonstrates the simplest importer as shown in Section 4.2:

• Constant communication step size.

• No repeating of communication steps.

• The error handling is implemented in a very rudimentary way.

``````////////////////////////////
// Initialization sub-phase
typedef fmi3Instance fmi3InstantiateCoSimulationTYPE(
fmi3String                     instanceName,
fmi3String                     instantiationToken,
fmi3String                     resourceLocation,
fmi3Boolean                    visible,
fmi3Boolean                    loggingOn,
fmi3Boolean                    eventModeUsed,
fmi3Boolean                    earlyReturnAllowed,
const fmi3ValueReference       requiredIntermediateVariables[],
size_t                         nRequiredIntermediateVariables,
fmi3InstanceEnvironment        instanceEnvironment,
fmi3CallbackLogMessage         logMessage,
fmi3CallbackIntermediateUpdate intermediateUpdate);

// instantiate both FMUs
s1 = s1_fmi3InstantiateCoSimulation("instance1",   // instanceName
guid,          // instantiationToken
NULL,          // resourceLocation
fmi3False,     // visible
fmi3False,     // loggingOn
fmi3False,     // eventModeUsed
fmi3False,     // earlyReturnAllowed
NULL,          // requiredIntermediateVariables
0,             // nRequiredIntermediateVariables
NULL,          // instanceEnvironment
cb_logMessage, // logMessage
NULL);         // intermediateUpdate

s2 = s2_fmi3InstantiateCoSimulation("instance1",   // instanceName
guid,          // instantiationToken
NULL,          // resourceLocation
fmi3False,     // visible
fmi3False,     // loggingOn
fmi3False,     // eventModeUsed
fmi3False,     // earlyReturnAllowed
NULL,          // requiredIntermediateVariables
0,             // nRequiredIntermediateVariables
NULL,          // instanceEnvironment
cb_logMessage, // logMessage
NULL);         // intermediateUpdate

if (s1 == NULL || s2 == NULL)
return EXIT_FAILURE;

// start and stop time
startTime = 0;
stopTime = 10;

// communication step size
h = 0.01;

// set all variable start values (of "ScalarVariable / <type> / start")
// s1_fmi3SetReal/Integer/Boolean/String(s1, ...);
// s2_fmi3SetReal/Integer/Boolean/String(s2, ...);

// initialize the FMUs
s1_fmi3EnterInitializationMode(s1, fmi3False, 0.0, startTime, fmi3True, stopTime);
s2_fmi3EnterInitializationMode(s2, fmi3False, 0.0, startTime, fmi3True, stopTime);

// set the input values at time = startTime
// fmi3SetReal/Integer/Boolean/String(s1, ...);
// fmi3SetReal/Integer/Boolean/String(s2, ...);

s1_fmi3ExitInitializationMode(s1);
s2_fmi3ExitInitializationMode(s2);

////////////////////////
// Simulation sub-phase
tc = startTime; // current time

while ((tc < stopTime) && (status == fmi3OK)) {

// retrieve outputs
// fmi3GetReal(s1, ..., 1, &y1);
// fmi3GetReal(s2, ..., 1, &y2);

// set inputs
// fmi3SetReal(s1, ..., 1, &y2);
// fmi3SetReal(s2, ..., 1, &y1);

// call instance s1 and check status
fmi3Boolean eventEncountered, terminateSimulation, earlyReturn;
fmi3Float64 lastSuccessfulTime;

status = s1_fmi3DoStep(s1, tc, h, fmi3True, &eventEncountered, &terminateSimulation, &earlyReturn, &lastSuccessfulTime);

if (terminateSimulation) {
printf("Instance s1 requested to terminate simulation.");
break;
}

// call instance s2 and check status as above
status = s2_fmi3DoStep(s2, tc, h, fmi3True, &eventEncountered, &terminateSimulation, &earlyReturn, &lastSuccessfulTime);

// ...

// increment current time
tc += h;
}

//////////////////////////
// Shutdown sub-phase
if (status != fmi3Error && status != fmi3Fatal) {
s1_fmi3Terminate(s1);
s2_fmi3Terminate(s2);
}

if (status != fmi3Fatal) {
s1_fmi3FreeInstance(s1);
s2_fmi3FreeInstance(s2);
}``````

4.3.2. Clocks

In the following example, the usage of the FMI functions is sketched in order to clarify the typical calling sequence of the functions in a simulation environment. We consider …​

The error handling is implemented in a very rudimentary way.

4.4. Description Schema

The common XML elements and attributes are defined in Section 2.4. Additional elements and attributes are defined subsequently. If the FMU implements the Co-Simulation interface type, the element `<CoSimulation>` must be present. It is defined as:

Figure 44. CoSimulation element.

The attributes in the following table are defined on top of the common attributes and have the following meaning (all attributes are optional with exception of `modelIdentifier`):

Table 36. CoSimulation attribute details.
Attribute Description

`modelIdentifier`

Short class name according to C syntax, for example, `A_B_C`. Used as prefix for FMI functions if the functions are provided in C source code or in static libraries, but not if the functions are provided by a DLL/SharedObject. `modelIdentifier` is also used as name of the static library or DLL/SharedObject. See also Section 2.2.1.

`canHandleVariableCommunicationStepSize`

If `canHandleVariableCommunicationStepSize = true`, then the communication step size (argument `communicationStepSize` of `fmi3DoStep`) can vary for each call.

`canReturnEarlyAfterIntermediateUpdate`

If `true`, the FMU is able to return early from `fmi3DoStep` if the co-simulation algorithm returns `earlyReturnRequested == fmi3True` from the callback `intermediateUpdate` and `canReturnEarly == fmi3True`. The default value of this capability flag is `false`.

`fixedInternalStepSize`

The fixed internal step size of the FMU (optional). + [This information can be used by the co-simulation algorithm to synchronize the communication interval with the internal step size of the FMU. The co-simulation algorithm should calculate the communication points by multiplying (`number_of_steps * step_size`) instead of repeatedly incrementing (`time += step_size`) to avoid the accumulation of numerical errors.]

`hasEventMode`

If `true` the FMU supports Event Mode. Even if this flag is `true`, the co-simulation algorithm can chose to delegate event handling to the FMU by calling `fmi3InstantiateCoSimulation` with `eventModeUsed == fmi3False`. If `eventModeUsed == fmi3True`, the co-simulation algorithm will have to actively trigger event handling in the FMU using `fmi3EnterEventMode`. `fmi3InstantiateCoSimulation` must only be called with `eventModeUsed == fmi3True` if `hasEventMode == true`. If the FMU has clocks, then `eventModeUsed == fmi3True` and the importer must call `fmi3InstantiateCoSimulation` with `eventModeUsed == fmi3True`.

Note that if `needsExecutionTool = true`, then it is required that the original tool is available to be executed during co-simulation. If `needsExecutionTool = false`, the FMU is completely contained inside the FMU in source code or binary format (DLL/SharedObject).

4.4.1. Example XML Description File

4.4.1.1. Example XML Description File with Early Return

The Example fmiModelDescription below is the same as shown in Section 3.4.1 for a Model Exchange FMU. The only differences are the replacement of the element `<ModelExchange>` with the element `<CoSimulation>` (with additional attributes), and the removal of `local` variables, which are associated with continuous `states` and their `derivatives` and presence of the capability flags `canHandleVariableCommunicationStepSize` and `canReturnEarlyAfterIntermediateUpdate` with value `true`.

Example fmiModelDescription
``````<?xml version="1.0" encoding="utf-8"?>
<fmiModelDescription
fmiVersion="3.0-beta.2"
modelName="MyLibrary.SpringMassDamper_Early_Return_example"
instantiationToken="{8c4e810f-3df3-4a00-8276-176fa3c9f9e0}"
description="Rotational Spring Mass Damper System"
version="1.0"
generationDateAndTime="2011-09-23T16:57:33Z"
variableNamingConvention="structured">
<CoSimulation
modelIdentifier="MyLibrary_SpringMassDamper"
canHandleVariableCommunicationStepSize="true"
canReturnEarlyAfterIntermediateUpdate="true"
hasEventMode="true"/>
<UnitDefinitions>
<DisplayUnit name="deg" factor="57.2957795130823"/>
</Unit>
</Unit>
<Unit name="kg.m2">
<BaseUnit kg="1" m="2"/>
</Unit>
<Unit name="N.m">
<BaseUnit kg="1" m="2" s="-2"/>
</Unit>
</UnitDefinitions>
<TypeDefinitions>
<Float64Type name="Modelica.Units.SI.Inertia" quantity="MomentOfInertia" unit="kg.m2" min="0.0"/>
<Float64Type name="Modelica.Units.SI.Torque" quantity="Torque" unit="N.m"/>
</TypeDefinitions>
<DefaultExperiment startTime="0.0" stopTime="3.0" tolerance="0.0001"/>
<ModelVariables>
<Float64 name="inertia1.J" valueReference="1073741824"
description="Moment of load inertia" causality="parameter" variability="fixed"
declaredType="Modelica.Units.SI.Inertia" start="1"/>
<Float64 name="torque.tau" valueReference="536870912"
description="Accelerating torque acting at flange (= -flange.tau)" causality="input"
declaredType="Modelica.Units.SI.Torque" start="0"/>
<Float64 name="inertia1.phi" valueReference="805306368"
description="Absolute rotation angle of component" causality="output"
declaredType="Modelica.Units.SI.Angle"/>
<Float64 name="inertia1.w" valueReference="805306369"
description="Absolute angular velocity of component (= der(phi))" causality="output"
declaredType="Modelica.Units.SI.AngularVelocity"/>
</ModelVariables>
<ModelStructure>
<Output valueReference="805306368"/>
<Output valueReference="805306369"/>
<InitialUnknown valueReference="805306368"/>
<InitialUnknown valueReference="805306369"/>
</ModelStructure>
</fmiModelDescription>``````
4.4.1.2. Example XML Description File with Clocks

The example below is the same one as shown in Section 4.4.1.1 for a Co-Simulation FMU. The only differences are, that the element `<fmiModelDescription><CoSimulation>` is present and `Clocks` are defined in the `modelDescription.xml`. The XML file may have the following content:

``//include::examples/co_simulation_clocked_cosimulation.xml[]``

5. FMI for Scheduled Execution

The Co-Simulation interface provides an indirect control over the computation of model partitions. With Scheduled Execution, a simulation algorithm can directly control the time of computation (i.e. scheduling) for such model partitions.

The Scheduled Execution interface addresses simulation use cases with the following requirements:

• At any time (even for unpredictable events), an event can be signaled to an FMU;

• If multiple FMUs share resources (e.g. control tasks), the time requirements (e.g. execution time, communication deadlines) of all model partitions have to be observed and respected;

• Time requirements may exist due to communication constraints (that are not apparent at FMU simulation level) which have to be fulfilled by the simulation algorithm;

• That requires a global evaluation order and preemption policy for all model partitions of the multiple FMUs

• Priority information provided by the FMUs has to be evaluated and merged to an overall priority for available model partitions

• Data shall move between the different FMU model partitions for the same or next activation time.

• Get/set operations must also be possible for the same activation time for different model partitions between the computation of these model partitions.

• The Scheduled Execution interface provides support for concurrent computation of model partitions (i.e. a support of multiple rates) on a single computational resource (e.g. CPU-core) of an FMU. For that a preemptive multitasking regime is intended (cooperative multitasking is not covered by this description).

[A parallel computation of model partitions is not part of the FMI 3.0 API. An FMU may still internally use parallel computation on multiple cores, but handling this is (currently) not part of the FMI standard. Such an internal parallel computation is not visible to the simulation algorithm. It is a tool vendor specific solution that has ties to the used OS and the co-simulation environment.]

5.1. Concepts

5.1.1. Timing Concepts and Clocks

The Scheduled Execution interface has a different timing concept compared to FMI for Co-Simulation. This is required to handle triggered input Clocks which may tick at a time instant that is unpredictable for the simulation algorithm. Typically, hardware I/O or virtual ECU software events belong to this category.

A simulation algorithm’s activation of a model partition will invoke the computation of the model partition defined by an input Clock for the current Clock tick time $\mathbf{t}_i$.

A model partition can only be activated once per activation time point $\mathbf{t}_i$.

During the computation of a model partition of an `input Clock` the FMU may inform the importer that an `output Clock` ticked or a `countdown Clock` has to be ticked. To do so the FMU switches into Intermediate Update Mode. Subsequently it is up to the importer to react on this information. I.e. the importer may activate potential sinks (e.g. a model partition of another FMU) connected to this `output Clock` or it may activate the model partition of the respective `countdown Clock`.

More details can be found in Clocks.

5.1.2. Preemption Support

For real-time applications the simulation time equals the real wall clock time, thus each `fmi3ActivateModelPartition` computation step has to be finished in real-time within its current period time length (computation time is not only defined by the runtime of `fmi3ActivateModelPartition` but also by the time for setting and getting variables and related operations). Usually a preemptive scheduling of the `fmi3ActivateModelPartition`, `fmi3Get{VariableType}`, `fmi3Set{VariableType}` calls is required to respect this constraint.

The FMU’s code has to be prepared for being able to correctly handle preemptive calls of `fmi3ActivateModelPartition`, `fmi3Get{VariableType}`, `fmi3Set{VariableType}`, `fmi3GetClock` and `fmi3GetIntervalDecimal`. In general for Scheduled Execution this requires a secured internal and external access to global states and variable values to ensure the correct handling of the preemption of model partition computations. [For `fmi3Get{VariableType}`, `fmi3Set{VariableType}` in particular a unique assignment of the respective variables to model partitions via its associated Clock is strongly recommended.] It is also required that the FMU reports the active state of an `output Clock` only with the first call of `fmi3GetClock` for a specific activation of this Clock and sets the reported activation state immediately back to `false` for the following `fmi3GetClock` calls for that Clock until this `output Clock` is internally activated again. Similarly for `countdown Clocks` a call to `fmi3GetIntervalDecimal` has to ensure that the Clock’s interval qualifier is reset to `fmi3IntervalUnchanged`.

If a preemptive multitasking regime is intended, an individual task (or thread — task and thread are used synonymously here) for each model partition (associated to an `input Clock`) has to be created. The task for computing each `fmi3ActivateModelPartition` is created and controlled by the simulation algorithm, not by the FMU. So the FMU exporting tool does not need to take care for that (except for preparing its code to support preemption).

[If only one single model partition is available via the interface of an FMU, preemptive calls of the related `fmi3ActivateModelPartition` function are possible by default since there are no external cross dependencies within one model partition between communication points.]

Based on the settings defined in the XML for input Clocks the simulation algorithm calls `fmi3Set{VariableType}`, `fmi3ActivateModelPartition`, or `fmi3Get{VariableType}`. Set/get calls for each task are only allowed for variables that are associated to the `input Clock` associated to that task or - here preemption issues become important - to variables that are associated to no Clock, based on the XML information.

[The recommendation is to avoid variables associated to no or more than one model partition or input Clocks as much as possible in the XML. Because they also introduce complexity it is recommended to reduce dependencies (defined in XML model structure) between variables located in different model partitions of one FMU, too.]

The simulation algorithm has no knowledge about the FMU internal communication between the model partitions of a single FMU and does not handle it.

The simulation algorithm schedules the `fmi3ActivateModelPartition` (as well as related `fmi3Get{VariableType}` and `fmi3Set{VariableType}`) calls based on given priorities for inputClocks defined in the `modelDescription.xml`.

Priority (see `priority`):

• Same priority: Model partitions (e.g. tasks) cannot preempt each other. Arbitrary evaluation order is possible for model partitions of the same priority.

• Different priorities: Model partitions of a higher priority preempt partitions of a lower priority as soon as the higher priority partition needs to be computed.

[If multiple tasks are needed to be scheduled for computation at a certain time instant a simulation algorithm must schedule a task of a higher priority always before a task of a lower priority]

An `input Clock` can hold fixed or modifiable periods, or be triggered unpredictably. Refer to chapter on Clocks for details.

Based on the period and priority definitions the exporting tool can restrict the code evaluation order. It nevertheless has to secure its code against concurrent evaluation [not against parallel evaluation, as this is not supported for model partitions of an FMU in the interface description of this mode] along the defined priority restrictions. Mostly this is required for internal inter-model-partition communication and in general for the joint use of variables that are associated to more than one model partition of the FMU. The exporting tool has to consider the effect of `triggered` 'input Clocks' and the influences of computing speed, because the exact occurrence of preemption points cannot be foreseen (within the given priority and period restrictions).

To guard certain code parts against preemption the FMU may use the callback functions fmi3CallbackLockPreemption and fmi3CallbackUnlockPreemption provided by the simulation algorithm when instantiating the FMU via `fmi3InstantiateScheduledExecution`.

[Such locks should be used with care and only if needed: Examples are given in Clock Activation Mode and Section 5.3.]

``````typedef void (*fmi3CallbackLockPreemption)   ();
typedef void (*fmi3CallbackUnlockPreemption) ();``````

Even if the scheduler does not support preemption, at least an empty implementation of these callback functions must be provided to allow the reuse of code for different modes together with an efficient preemption. [This avoids checks for NULL function pointers. A function call to a void-void function with an immediate return is hardly any overhead.]

5.2. State Machine for Scheduled Execution

This section contains the description of the Scheduled Execution interface for a C program.

The direct scheduling of model partitions based on Clock ticks requires an additional handling mode for FMUs. The FMU signals its support for direct model partition scheduling in the `modelDescription.xml` via the element `<fmiModelDescription><ScheduledExecution>`. The simulation algorithm signals to the FMU that it supports and has recognized the Clocks and model partition scheduling capabilities of the FMU by instantiating it as Scheduled Execution.

Error, reset or terminate information is a global state of the FMU. If e.g. a function returns `fmi3Discard` or `fmi3Error` this is also assumed for all active or preempted model partitions. In case of `fmi3Discard` or `fmi3Error` no repetition of the step is possible, the only possible way to go forward is to enter the Terminated state and to end or to reset the simulation or - if supported - to set the FMU back to a former state.

This section summarizes the available states and the allowed function calls in the respective states.

Figure 45. Calling sequence of Scheduled Execution C functions.

If the simulation algorithm intends to enter the state Terminated it must ensure that all tasks related to model partitions of the FMU have ended. Hence if in states Clock Activation Mode, Intermediate Update Mode, or Reconfiguration Mode a function returns `fmi3Fatal` the simulation algorithm may prematurely end all tasks related to the computation of model partitions of this FMU. If in these states a function returns `fmi3Discard` or `fmi3Error` the simulation algorithm may wait until all other tasks of the model partitions of this FMU have ended, but new tasks must not be started.

Each state of the state machine corresponds to a certain phase of a simulation. Common states are defined in Section 2.3, such as super states FMU State Setable and Initialized, states Instantiated, Configuration Mode, Reconfiguration Mode, Initialization Mode, Terminated and Intermediate Update Mode.

5.2.1. Super State: Initialized

Special to Scheduled Execution, the following additional constrains apply to the state Initialized. The FMU enters state Terminated only after all other tasks related to the computation of model partitions of this FMU have ended. After `fmi3Terminate` has been called no new tasks can be started (e.g. related to `countdown Clock` ticks) and all other function calls for this FMU must return `fmi3Error` until the state Terminated is reached.

5.2.2. State: Clock Activation Mode

The FMU enters this state when the simulation algorithm calls `fmi3ExitInitializationMode` in state Initialization Mode or `fmi3ExitConfigurationMode` in state Reconfiguration Mode.

In this state the simulation algorithm can create multiple concurrent tasks related to an FMU. In each task, the simulation algorithm can activate one or multiple model partitions of an FMU based on the defined input Clocks properties via a `fmi3ActivateModelPartition` call for each Clock.

Equations and Actions Functions Influencing Equations

Set `tunable` `parameters` $\mathbf{p}_{\mathit{variability == tunable}}$ .

`fmi3Set{VariableType}`

Set discrete-time `inputs` $\mathbf{u}_{d}(\mathbf{t})$.

`fmi3Set{VariableType}`

Get values of variables $\mathbf{v}(\mathbf{t})$.

`fmi3Get{VariableType}`

When an input Clock $\mathbf{k}_i$ ticks, activate the corresponding model partition:

• $(\mathbf{y}_\mathit{d,k_i}, \mathbf{x}_\mathit{d,k_i}, \mathbf{w}_\mathit{d,k_i}) := \mathbf{f}_{\mathit{activate}}({}^{\bullet}\mathbf{x}_\mathit{d}, \mathbf{w}_d, \mathbf{u}_\mathit{d}, \mathbf{p}, \mathbf{k_i})$

• Update previous values of discrete states of the corresponding model partition: ${}^\bullet\mathbf{x}_\mathit{d,k_i}:=\mathbf{x}_\mathit{d,k_i}$.

`fmi3ActivateModelPartition`

$(\mathbf{v}_{u}) := \mathbf{f}_{\mathit{inter}}({}^{\bullet}\mathbf{x}_d, \mathbf{u}_{d}, {}^{\bullet}\mathbf{u}_{u}, \mathbf{p} )$

`fmi3CallbackIntermediateUpdate`

Allowed Function Calls
Function `fmi3Set{VariableTypeExclClock}`

This function can be called before scheduling a model partition for variables assigned to that model partition via its associated Clock and all variables not associated to any Clock.

Function `fmi3Get{VariableTypeExclClock}`

These functions can be called after the computation of a model partition for variables assigned to that model partition via its associated Clock and all variables not associated to any Clock.

Because of real-time constraints, the computational effort has to be predictable for all operations in Scheduled Execution. Therefore, all computationally expensive operations to compute a model partition have to be contained within the `fmi3ActivateModelPartition` function. The simulation algorithm can assume that `fmi3Get{VariableTypeExclClock}` and `fmi3Set{VariableTypeExclClock}` operations are not computationally expensive. [It is recommended, to call `fmi3Set{VariableTypeExclClock}` and `fmi3Get{VariableTypeExclClock}` in the same task as `fmi3ActivateModelPartition`.]

The restrictions related to variable `causality` and `variability` defined for Step Mode in `Co-Simulation` apply.

[The reason is to avoid different interpretations of the caching, since contrary to `FMI for Model Exchange`, `fmi3ActivateModelPartition` will perform the actual calculation instead of `fmi3Get{VariableTypeExclClock}`, and therefore, dummy algebraic loops at communication points cannot be handled by an appropriate sequence of `fmi3Get{VariableTypeExclClock}` and `fmi3Set{VariableTypeExclClock}` calls as for Model Exchange.

To ensure predictable behavior every variable should be assigned uniquely to a model partition via its associated Clock. Observe two examples:

• An output variable is written by two different model partitions. The values returned by `fmi3Get` that is placed after `fmi3ActivateModelPartition` may return the values computed by the other model partition if that model partition has higher priority and preempted the task execution meanwhile.

• An input variable is read by two different model partitions. The variable values of a model partitions of lower priority may have been overwritten by a call to `fmi3Set` in the context of a task executed for a model partition of higher priority.

Note that if every variable is assigned uniquely to a model partition it is also not necessary to use `preemption locks` in the context of `fmi3Get` and `fmi3set`.]

Function `fmi3ActivateModelPartition`

Each `fmi3ActivateModelPartition` call is now associated to the computation of a (publicly disclosed, externally controlled) model partition of the model and therefore to a single defined `input Clock`.

``````typedef fmi3Status fmi3ActivateModelPartitionTYPE(fmi3Instance instance,
fmi3ValueReference clockReference,
size_t clockElementIndex,
fmi3Float64 activationTime);``````

The `fmi3ActivateModelPartition` function has the following arguments:

Consecutive calls to `fmi3ActivateModelPartition` for a `clockReference` and `clockElementIndex` (i.e. `valueReference` of Clock variable and element index into that for arrays) must have strictly monotonically increasing `activationTime` $\mathbf{t}_i$.

Function `fmi3CallbackIntermediateUpdate`

`fmi3CallbackIntermediateUpdate` switches the FMU itself into the Intermediate Update Mode. The callback may be called from concurrent tasks within `fmi3ActivateModelPartition`.

Functions `fmi3GetFMUState`, `fmi3SetFMUState`, `fmi3FreeFMUState`, `fmi3SerializedFMUStateSize`, `fmi3SerializeFMUState`, `fmi3DeSerializeFMUState`

These functions must not be called if any model partition is currently active or preempted. [This is because these functions apply to the whole FMU and not only to a specific model partition.]

5.3. Code Example

The FMU ThreeInputClocks sketches the usage of the FMI functions. The example is given in a mix of pseudo-code and C, in order to keep it small and understandable. We consider one FMU with three model partitions. Two model partitions associated to two periodic Clocks `10msClock` and `50msClock` (periods 10 ms and 50 ms) and one aperiodic `countdown clock` `AperiodicClock`.

During the execution of the model partition of Clock `10msClock` the FMU sets the `interval` for `countdown clock` `AperiodicClock` and calls `fmi3CallbackIntermediateUpdate` to invoke the execution of the corresponding model partition.

The function calls `fmi3ActivateModelPartition` are executed in the context of preemptable tasks whose priorities are derived from the respective Clock configurations of the FMU. In this example the execution of the task of `countdown clock` `AperiodicClock` is waiting for the task of Clock `10msClock` to finish. Likewise the task of `AperiodicClock` is suspended when the task of higher priority is scheduled again.

The example also depicts how a task associated to an even lower prior Clock `50msClock` is delayed several times by tasks of higher priority. Note that the point of time when the task was scheduled is the `activationTime` of `fmi3ActivateModelPartition` (…​Activate…​(`clock`, `activationTime`)).

Figure 46. Scheduled Execution Example ThreeInputClocks

5.3.1. Simulation Algorithm Implementation

To enable the computation of a Scheduled Execution FMU a simulation algorithm has to provide a task scheduler. Depending on the particular configuration the simulation algorithm sets up tasks for every `input Clock`. When executed each task calls `fmi3ActivateModelPartition` for its respective Clock. The `activationTime` is provided by the simulation algorithm. Periodic tasks can be scheduled on initialization of the simulation application. Aperiodic tasks are scheduled explicitly during the execution.

``````void ExecuteModelPartition10ms() {
fmi3SetFloat64(fmu, AInputReferences, 2, AInput, 2);
fmi3ActivateModelPartition(fmu, ClockReference10ms, ClockElementIndex, ActivationTime);
fmi3GetFloat64(fmu, AOutputReferences, 1, AOutput, 1);
}``````

The FMU requests to schedule the model partition of `AperiodicClock`. It calls `fmi3CallbackIntermediateUpdate` to enable the importer to check whether the FMU has defined a new interval for `AperiodicClock`. Evaluating the return values `qualifier` and `interval` of `fmi3GetInterval` the simulation algorithms determines if the respective task has to be scheduled and which delay has to be applied.

``````void CallbackIntermediateUpdate(fmi3InstanceEnvironment instanceEnvironment,
fmi3Float64  intermediateUpdateTime, fmi3Boolean  clocksTicked,
fmi3Boolean  intermediateVariableSetRequested, fmi3Boolean  intermediateVariableGetAllowed,
fmi3Boolean  intermediateStepFinished, fmi3Boolean  canReturnEarly,
fmi3Boolean* earlyReturnRequested, fmi3Float64* earlyReturnTime) {

fmi3Float64 interval[] = { 0.0 };
fmi3IntervalQualifier intervalQualifier[] = { fmi3IntervalNotYetKnown };
if (clocksTicked == fmi3True) {
const fmi3ValueReference aperiodicClockReferences[] = { 6 };
fmi3GetIntervalDecimal(fmu, aperiodicClockReferences, 1, interval, intervalQualifier, 1);
if (intervalQualifier[0] == fmi3IntervalChanged) {
// schedule task for AperiodicClock with a delay
}
// ask FMU if output clock has ticked
fmi3ValueReference outputClockReferences[] = { 7 };
fmi3Boolean clocksActivationState[] = { fmi3ClockInactive };
fmi3GetClock(fmu, outputClockReferences, 1, clocksActivationState, 1);
if (clocksActivationState[0]) {
}
}
}``````

5.3.2. FMU Implementation

The FMU implements `fmi3ActivateModelPartition` dispatching for every `input Clock` so the code might look like this:

``````fmi3Status fmi3ActivateModelPartition(fmi3Instance instance, fmi3ValueReference clockReference,
size_t clockElementIndex, fmi3Float64 activationTime) {

switch (clockReference) {
case 5:
// Input clock 10msClock
activateModelPartition10ms(instance, activationTime);
break;
case 6:
// Input clock AperiodicClock
activateModelPartitionAperiodic(instance, activationTime);
break;
case 8:
// Input clock 50msClock
activateModelPartition50ms(instance, activationTime);
break;
// ...
}
return fmi3OK;
}``````

In the context of the task being executed every 10 ms, the FMU initiates the scheduling of a task by setting a new interval to `countdown Clock` `AperiodicClock` and evoking `fmi3CallbackIntermediateUpdate`.

``````void activateModelPartition10ms(ModelInstance* instance, fmi3Float64 activationTime) {

fmi3Boolean conditionForCountdownClockMet = (AIn1 > AIn2);
if (conditionForCountdownClockMet) {
CountdownClockQualifier = fmi3IntervalChanged;
CountdownClockInterval = 0.0;
// inform simulation algorithm that the countdown clock has ticked
fmi3Boolean clocksTicked = fmi3True;
instance->callbackIntermediateUpdate(instance->instanceEnvironment, activationTime, clocksTicked,
fmi3False, fmi3False, fmi3False, fmi3False, NULL, NULL);
}
fmi3Boolean conditionForOutputClockMet = (AIn2 > 42.0);
if (conditionForOutputClockMet) {
// outputClock ticks
OutputClockTicked = fmi3ClockActive;
// inform simulation algorithm that output clock has ticked
fmi3Boolean clocksTicked = fmi3True;
instance->callbackIntermediateUpdate(instance->instanceEnvironment, activationTime, clocksTicked,
fmi3False, fmi3False, fmi3False, fmi3False, NULL, NULL);
}
AOut = AIn1 + AIn2;
}``````

In `fmi3GetIntervalDecimal` the Clock’s interval qualifier is reset to `fmi3IntervalUnchanged`. To ensure consistency the FMU may need to prevent preemption. In this example it is actually not needed since CallbackIntermediateUpdate is only called from one model partition.

``````fmi3Status fmi3GetIntervalDecimal(fmi3Instance instance, const fmi3ValueReference valueReferences[],
size_t nValueReferences, fmi3Float64 interval[], fmi3IntervalQualifier qualifier[], size_t nValues) {

for (int i = 0; i < nValues; i++) {
if (valueReferences[i] == 6) {
env->lockPreemption(); // Optional: Preventing preemption is actually not needed here.
interval[i] = CountdownClockInterval;
qualifier[i] = CountdownClockQualifier;
CountdownClockQualifier = fmi3IntervalUnchanged;
env->unlockPreemption();
}
else {
qualifier[i] = fmi3IntervalNotYetKnown;
}
}
return fmi3OK;
}``````

If `fmi3GetClock` is called for a certain `output Clock` the `output Clock` is reset. As for `fmi3GetIntervalDecimal` it may be necessary for the FMU to ensure that the code is not preempted. Here it is just as well not needed for the same reason.

``````fmi3Status fmi3GetClock(fmi3Instance instance, const fmi3ValueReference valueReferences[],
size_t nValueReferences, fmi3Clock values[], size_t nValues) {

for (int i = 0; i < nValues; i++) {
if (valueReferences[i] == 7) {
env->lockPreemption(); // Optional: Preventing preemption is actually not needed here.
values[i] = OutputClockTicked;
OutputClockTicked = fmi3ClockInactive;
env->unlockPreemption();
}
else {
values[i] = fmi3ClockInactive;
}
}
return fmi3OK;
}``````

5.4. Description Schema

The common XML elements and attributes are defined in Section 2.4. Additional elements and attributes are defined subsequently. If the FMU implements the Scheduled Execution interface type, the element `<ScheduledExecution>` must be present. It is defined as:

Figure 47. ScheduledExecution element.

The attribute in the following table is defined on top of the common attributes and have the following meaning (all attributes are optional with exception of `modelIdentifier`):

Table 37. ScheduledExecution attribute details.
Attribute Description

`modelIdentifier`

Short class name according to C syntax, for example, `A_B_C`. Used as prefix for FMI functions if the functions are provided in C source code or in static libraries, but not if the functions are provided by a DLL/SharedObject. `modelIdentifier` is also used as name of the static library or DLL/SharedObject. See also Section 2.2.1.

5.4.1. Example XML Description File

The simulation algorithm collects the information about the number and properties of `Clocks` supported by the FMU via analyzing the `modelDescription.xml` as defined in Section 2.4. For every `input Clock` the simulation algorithm defines a task. The properties `period` and `priority` are defined based on the `input clocks'` `period` and `priority` defined in the `modelDescription.xml`. The simulation algorithm can read from the `modelDescription.xml` that `output Clock` OutClock may tick triggered by `input Clock` 10msClock and that `input Clock` AperiodicClock is triggered by OutClock.

``````<?xml version="1.0" encoding="UTF-8"?>
<fmiModelDescription fmiVersion="3.0-beta.2" modelName="ThreeInputClocks" instantiationToken="ThreeInputClocks">
<ScheduledExecution modelIdentifier="ThreeInputClocks"/>
<LogCategories>
<Category name="logStatusError" description="Log error messages"/>
</LogCategories>
<DefaultExperiment startTime="0" stopTime="6" stepSize="0.001"/>
<ModelVariables>
<!-- Variables related to input clock 10msClock  -->
<Float64 name="AIn1" valueReference="0" causality="input" variability="discrete" clocks="5" start="0"/>
<Float64 name="AIn2" valueReference="1" causality="input" variability="discrete" clocks="5" start="0"/>
<Float64 name="AOut" valueReference="2" causality="output" variability="discrete" clocks="5"/>

<!-- Variables related to input clock AperiodicClock  -->
<Float64 name="BIn"  valueReference="3" causality="input" variability="discrete" clocks="6" start="0"/>
<Float64 name="BOut" valueReference="4" causality="output" variability="discrete" clocks="6"/>

<!-- Clock variables -->
<!-- Periodic input clock -->
<Clock name="10msClock"      valueReference="5" causality="input"  interval="constant"
priority="1" intervalCounter="10" resolution="1000"/>
<!-- Input clock that is triggered by 10msClock -->
<Clock name="AperiodicClock" valueReference="6" causality="input"  interval="countdown"
priority="2" clocks="5"/>
<!-- Output clock -->
<Clock name="OutputClock"    valueReference="7" causality="output" interval="triggered"  clocks="5"/>
<!-- Periodic input clock -->
<Clock name="50msClock"      valueReference="8" causality="input"  interval="constant"
priority="3" intervalCounter="50" resolution="1000"/>
</ModelVariables>
<ModelStructure>
<Output valueReference="2" dependencies="0 1"/>
<Output valueReference="4" dependencies="3"/>
</ModelStructure>
</fmiModelDescription>``````

References

• [ABL12] Åkesson J., Braun W., Lindholm P., and Bachmann B. (2012): Generation of Sparse Jacobians for the Functional Mockup Interface 2.0. 9th International Modelica Conference, Munich, 2012. http://www.ep.liu.se/ecp/076/018/ecp12076018.pdf

• [BPRS15] Atilim Gunes Baydin, Barak A. Pearlmutter, Alexey Andreyevich Radul, Jeffrey Mark Siskind (2015): Automatic differentiation in machine learning: a survey. https://arxiv.org/abs/1502.05767

• [BCP10] Benveniste A., Caillaud B., Pouzet M. (2010): The Fundamentals of Hybrid Systems Modelers. In 49th IEEE International Conference on Decision and Control (CDC), Atlanta, Georgia, USA, December 15-17. http://www.di.ens.fr/~pouzet/bib/cdc10.pdf

• [BOA11] Blochwitz T., Otter M., Arnold M., Bausch C., Clauß C., Elmqvist H., Junghanns A., Mauss J., Monteiro M., Neidhold T., Neumerkel D., Olsson H., Peetz J.-V., Wolf S. (2011): The Functional Mockup Interface for Tool independent Exchange of Simulation Models. 8th International Modelica Conference, Dresden 2011. http://www.ep.liu.se/ecp/063/013/ecp11063013.pdf

• [BKF17] Braun W., Kulshreshtha K., Franke R., Walther A., Bachmann B., Towards Adjoint and Directional Derivatives in FMI utilizing ADOL-C within OpenModelica, 12th International Modelica Conference, Prague, 2017. https://2017.international.conference.modelica.org/proceedings/html/submissions/ecp17132363_BraunKulshreshthaFrankeBachmannWalther.pdf

• [BOA12] Blochwitz T., Otter M., Åkesson J., Arnold M., Clauß C., Elmqvist H., Friedrich M., Junghanns A., Mauss J., Neumerkel D., Olsson H., Viel A. (2012): Functional Mockup Interface 2.0: The Standard for Tool independent Exchange of Simulation Models. 9th International Modelica Conference, Munich, 2012. http://www.ep.liu.se/ecp/076/017/ecp12076017.pdf

• [KS00] Kübler R., Schiehlen W. (2000): Two methods of simulator coupling. Mathematical and Computer Modeling of Dynamical Systems 6 pp. 93-113.

• [LZ07] Lee E.A., Zheng H. (2007): Leveraging Synchronous Language Principles for Heterogeneous Modeling and Design of Embedded Systems. EMSOFT'07, September 30-October 3, Salzburg, Austria. https://ptolemy.berkeley.edu/publications/papers/07/unifying/LeeZheng_SRUnifying.pdf

• [MS93] Mattsson S. E. and Söderlind G.: Index Reduction in Differential Algebraic Equations Using Dummy Derivatives. SIAM Journal on Scientific Computing, Vol. 14, No. 3, pp. 677692, 1993.

• [MLS12] Modelica (2012): Modelica, A Unified Object-Oriented Language for Systems Modeling. Language Specification, Version 3.3, May 9, 2012. https://www.modelica.org/documents/ModelicaSpec33.pdf

• [PZ06] Pouzet M. (2006): Lucid Synchrone. Version 3.0, Tutorial and Reference Manual. http://www.di.ens.fr/~pouzet/lucid-synchrone/

• [CGM84] Coleman, Garbow, Moré (1984): Software for estimating sparse Jacobian matrices, ACM Transactions on Mathematical Software. TOMS , vol. 10, no. 3, pp. 346-347

• [PW13] Preston-Werner, T. (2013): Semantic Versioning 2.0.0. https://semver.org/spec/v2.0.0.html

• [FBH18] Fritzson D., Braun R. and Hartford J. (2018): Composite modelling in 3-D mechanics utilizing Transmission Line Modelling (TLM) and Functional Mock-up Interface (FMI). Modeling, Idenfitication and Control, vol. 39, no. 3, pp. 179-190.

Appendix A: Glossary

 Term Description argument Refers to a function parameter. Not to be confused with parameter. capability flag Capability flags are used to indicate to the importer what optional functionality the FMU supports. clock A variable to report events or trigger events or model partitions. clock tick When the Clock ticks an event is present, otherwise the event is absent. A Clock tick causes a Clock activation at that time instant, except for input Clock ticks in Scheduled Execution, which cause an activation of the associated model partition instead. communication points Time grid for data exchange between importer and FMU(s) in a (co-)simulation environment. communication step size Distance between two subsequent communication points. continuous-time instant See time instant. co-simulation Coupling of several simulation programs in order to compute the global behavior of a system that consists of several subsystems. The subsystems are coupled in the sense that the behavior of each subsystem depends on the behavior of the remaining subsystems, so that the co-simulation must be computed in a step-by-step fashion. Each simulation program is responsible for computing the behavior of a subsystem, using the outputs produced by the other simulation programs. Synonyms: dynamic mutual-exchange, simulator coupling, and coupled simulation. direct feedthrough Direct feedthrough describes that values of output variables depend directly on values of input variables. dynamic state selection Dynamic State Selection is a method to solve differential algebraic equations (DAEs). The FMU checks whether the dynamically selected states are still numerically appropriate. If not, a new mapping between states and variables is computed. For details see [MS93]. ECU Electronic Control Unit (Microprocessor that is used to control a technical system). event Something that occurs instantaneously at a specific time or when a specific condition occurs. At an event, numerical integration is suspended and variables may change their values discontinuously. Internal events occur inside the FMU and should be signaled to the environment without any delay and can cause event handling and/or the activation of an output clock. Input clocks are activated by the environment to inform the FMU about the exact moment an event across FMUs has to be handled. See state event, step event and time event. event indicator A variable that changes sign exactly at an event. See event indicator. event iteration An importer can iteratively call `fmi3Set{VariableType}` and `fmi3Get{VariableType}` e.g. to solve algebraic loops during an event and during a super-dense time instant. When reaching a consistent state, changes to discrete variables may be triggered. Such a discrete (state) change may require another solution of an algebraic loop in the next super-dense time instant. These discontinuous changes can repeat until the participating FMUs or the master decide that no further iteration is needed. An example for a system that can be simulated with event iteration is a powertrain with multiple clutches distributed in several FMUs. The decision which clutch is open, which is closed and which is slipping can be determined with event iteration. exporter A program that creates an FMU. external scheduler See scheduler. feedthrough See direct feedthrough. FMI Functional Mock-up Interface: Interface of a functional mock-up in form of a model. In analogy to the term digital mock-up (see mock-up), functional mock-up describes a computer-based representation of the functional behaviour of a system for all kinds of analyses. FMI functions The function of the FMI C-API. FMI for co-simulation Functional Mock-up Interface for Co-Simulation: One of the MODELISAR Functional Mock-up Interface types. It connects the importer with one or more FMU. FMI for model exchange Functional Mock-up Interface for Model Exchange: One of the MODELISAR Functional Mock-up Interface types. It consists of the model description and the C API. FMU Functional Mock-up Unit: A "model class" following the interface type FMI for Model Exchange, or a model following the interface types FMI for Co-Simulation or FMI for Scheduled Execution). An FMU is one ZIP file as defined in Section 2.5. The zip file comprises essentially an XML file that defines the model variables, and a set of C function implementations (see Section 2.2). The implementations can be in source or binary form. FMU clock See Clock. importer The tool that imports or loads one or more FMUs. Also called simulation environment, environment, calling environment, (co-)simulation algorithm, target platform, target environment, integrator (in ME). independent variable All variables are a function of this `independent` variable, typically time. input event An input event occurs when a discrete input variable changes, a continuous input variable has a discontinuity or a `tunable` `parameter` changes its value. [Note that if an FMU A is connected to an FMU B, and an event is triggered for A, then potentially all `outputs` of A will be discontinuous at this time instant. It is therefore advisable to move B into Event Mode at this time instant too if an `output` of A is connected to B. This means to call `fmi3EnterEventMode` on B.] integration algorithm The numerical algorithm to solve differential equations. integrator A software component, which implements an integration algorithm. interface General: An abstraction of a software component that describes its behavior without dealing with the internal implementation. Software components communicate with each other via interfaces. interface type One of the three FMI variants "Model Exchange", "Co-simulation" or "Scheduled execution" machine epsilon Smallest floating point value. mock-up A full-sized structural, but not necessarily functional model built accurately to scale, used chiefly for study, testing, or display. In the context of computer aided design (CAD), a digital mock-up (DMU) means a computer-based representation of the product geometry with its parts, usually in 3-D, for all kinds of geometrical and mechanical analyses. model A model is a mathematical or logical representation of a system of entities, phenomena, or processes. Basically a model is a simplified abstract view of the complex reality. It can be used to compute its expected behavior under specified conditions. model description file The model description file is an XML file, which supplies a description of all properties of a model (for example, `input` / `output` variables). model description interface An interface description to write or retrieve information from the model description file. Model Description Schema An XML schema that defines how all relevant, non-executable, information about a "model class" (FMU) is stored in a text file in XML format. Most important, data for every variable is defined (variable name, handle, data type, variability, unit, etc.), see Section 2.4. model rate Inverse of time interval between two communication points associated to an exposed model partition within the FMU (i.e. Clock is defined in interface). In general multiple rates i.e. multiple model partitions can be defined for an Co-Simulation FMU. model partition Model partitions can be associated to a discrete or (piecewise) continuous part of the FMU. The computation of model partitions can be externally controlled based on Clock ticks of associated `input clocks`. Not all FMU internal model partitions have to be exposed in the Co-Simulation interface as Clock and can also be handled FMU internally (e.g. internal subsampling). Nevertheless, it is assumed that the activation of all exposed `input clocks` results in the computation of the complete FMU. As stated above, continuous parts of the FMU are also associated to model partitions that define the communication points for the `continuous` values. ODE see Ordinary Differential Equation Ordinary Differential Equation Differential equation containing one or more functions of one independent variable (typically time) and the derivatives of those functions. output points Tool internal time grid for saving output data to file (in some tools also known as "communication points" - but this term is used in a different way in FMI for Co-Simulation, see above). output step size Distance between two subsequent output points. parameter A quantity within a model, which remains constant during simulation (`fixed` `parameter`) or may change at event instances (`tunable` `parameter`). Examples are a mass, stiffness, etc. These parameters are different from calculated parameters, because they can be changed independently (according to their `variability`). runtime environment See co-simulation environment scheduled execution FMI type that externalizes the scheduler to run model partitions, potentially synchronized between more than one FMU and exchanging input and output variables accordingly. simulation Compute the behavior of one or several models under specified conditions. (see also co-simulation) simulation model see model simulation program Software to develop and/or solve simulation models. The software includes a solver, may include a user interface and methods for post processing (see also: simulation tool, simulation environment). simulation tool see simulation program simulator A simulator can include one or more simulation programs, which solve a common simulation task. simulator coupling See tool coupling. solver Software component, which includes algorithms to solve models, for example, integration algorithms and event handling methods. state The continuous `states` of a model are all variables that appear differentiated in the model and are independent from each other. The discrete-time states of a model are time-discrete variables that have two values in a model: The value of the variable from the previous event instant, and the value of the variable at the actual event instant. state event The time of state events is not known apriori. Event indicators are used to allow the importer finding the time of these state events precisely. step event Event that might occur at a completed integrator step signaled by calling `fmi3CompletedIntegratorStep`. Step events are, for example, used to change the mapping of the continuous states to variables (dynamic state selection). structural parameter A parameter influencing the size and/or dimensionality of an array variable of an FMU. super-dense time A precise definition of time taking into account iterations at an event. For an FMU, the `independent` variable time $\mathbf{t} \in \mathbb{T}$ is a tuple $\mathbf{t} = (\mathbf{t}_R, \mathbf{t}_I)$ where $\mathbf{t}_R \in \mathbb{R}, \mathbf{t}_I \in \mathbb{N} = \{0,1,2,\ldots\}$. The real part $\mathbf{t}_R$ of this tuple is the `independent` variable of the FMU for describing the continuous-time behavior of the model between events. During continuous-time integration $\mathbf{t}_I = 0$. The integer part $\mathbf{t}_I$ of this tuple is a counter to enumerate (and therefore distinguish) the events at the same continuous-time instant $\mathbf{t}_R$. super-dense time instant See time instant and super-dense time. task Special kind of model partition that is used in control code. time event Event that is defined by a predefined time instant. Since the time instant is known in advance, the integrator can select its step size so that the event point is directly reached. Therefore, this event can be handled efficiently. time instant A moment in time, either a continuous-time instant $\mathbf{t} = \mathbf{t}_R$, or a super-dense time instant $\mathbf{t} = (\mathbf{t}_R, \mathbf{t}_I)$, see also super-dense time. TLM Transmission Line Modeling A mathematical method which uses physically motivated time delays to decouple an equation system into independent parts during a specified time frame without compromising numerical stability. Also known as the bi-lateral delay line method. For more details see [FBH18]. user interface The part of the simulation program that gives the user control over the simulation and allows watching results. XML eXtensible Markup Language (www.w3.org/XML, en.wikipedia.org/wiki/XML) - An open standard to store information in text files in a structured form.

Appendix B: Acknowledgements

Until Dec. 2011, this work was carried out within the ITEA2 MODELISAR project (project number: ITEA2-07006, https://itea3.org/project/modelisar.html).

Daimler AG, DLR, ITI GmbH, Martin Luther University Halle-Wittenberg, QTronic GmbH and SIMPACK AG thank BMBF for partial funding of this work within MODELISAR (BMBF Förderkennzeichen: 01lS0800x).

Dassault Systèmes (Sweden) thanks the Swedish funding agency VINNOVA (2008-02291) for partial funding of this work within MODELISAR.

LMS Imagine and IFPEN thank DGCIS for partial funding of this work within MODELISAR.

Since Sept. 2012 until Nov. 2015, this work is partially carried out within the ITEA2 MODRIO project (project number: ITEA 2-11004, https://itea3.org/project/modrio.html).

• DLR, ITI GmbH, QTronic GmbH and SIMPACK AG thank BMBF for partial funding of this work within MODRIO (BMBF Förderkennzeichen: 01IS12022E).

• Dassault Systèmes (Sweden), Linköping University and Modelon AB thank the Swedish funding agency VINNOVA (2012—​01157) for partial funding of this work within MODRIO.

• Siemens PLM Software (France) and IFPEN thank DGCIS for partial funding of this work within MODRIO.