This document defines the Functional Mock-up Interface (FMI), version 3.0. This is a major release with new features compared to FMI 2.0.

FMI is a tool-independent standard to support both model exchange and co-simulation of dynamic models using a combination of XML files and C code (either compiled in DLL/shared libraries or in source code). The first version, FMI 1.0, was published in 2010. The FMI development was initiated by Daimler AG with the goal to improve the exchange of simulation models between suppliers and OEMs. As of today, development of the standard continues through the participation of many companies and research institutes. FMI 2.0 is supported by over 100 tools and is used by automotive and non-automotive organizations throughout Europe, Asia and North America.

The downloads page (https://fmi-standard.org/downloads/) provides, this specification, as well as supporting C header and XML schema files, and an FMI compliance checker. In addition, sample models (exported from different tools in FMI format) are provided to assist tool vendors to ensure compatibility with other tools, as well as a test suite to check whether connected FMUs (Function Mock-up Units) are appropriately handled by a tool.

Contact the FMI development group at contact@fmi-standard.org.

Version Date Remarks

1.0

2010-01-26

First version of FMI for Model Exchange

1.0

2010-10-12

First version of FMI for Co-Simulation

2.0

2014-07-25

Second version of FMI for Model Exchange and Co-Simulation

2.0.1

2019-10-31

Bugfix/maintenance release of FMI for Model Exchange and Co-Simulation 2.0

3.0

Third version of FMI for Model Exchange and Co-Simulation

Please report issues that you find with this specification to the public FMI issue tracking system: https://github.com/modelica/fmi-standard/issues/

2008-2011 MODELISAR consortium and
2012-2020 Modelica Association Project "FMI"

 You are free to Share - copy and redistribute the material in any medium or format Remix - remix, transform, and build upon the material for any purpose, even commercially. The licensor cannot revoke these freedoms as long as you follow the license terms. Under the following terms: Attribution - You must give appropriate credit, provide a link to the license, and indicate if changes were made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use. Share Alike - If you remix, transform, or build upon the material, you must distribute your contributions under the same license as the original.

The legal license text and disclaimer is available at:

Note

Article (3a) of this license requires that modifications of this work must clearly label, demarcate or otherwise identify that changes were made.

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.
If you have improvement suggestions, please send them to the FMI development group at contact@fmi-standard.org.

Abstract

This document defines the Functional Mock-up Interface (FMI), version 3.0 to (a) exchange dynamic models between tools and (b) define tool coupling for dynamic system simulation environments.

FMI for Basic Co-Simulation (BCS) (Section 4)

The intention is to provide an interface standard for coupling of simulation models or tools in a co-simulation environment. The data exchange between subsystems is largely restricted to discrete communication points. In the time between two communication points, the subsystems are solved independently by internal means, see below. Master algorithms control the data exchange and the synchronization between subsystems (FMUs).

Note that the master algorithm itself is not part of the FMI standard.

FMI for Hybrid Co-Simulation (HCS) (Section 5)

The Hybrid Co-Simulation interface adds a number of features primarily to allow for more sophisticated master algorithms that aim at more efficient and robust simulations. Such additional features are raising events between communication time points using synchronous and asynchronous clocks or sharing values between communication points to allow for improved interpolation of data. The master algorithm is responsible for: * advancing the overall simulation time, and * triggering execution of synchronous and asynchronous external events for a set of FMUs, and * handling events (e.g. clock ticks) signaled by the FMUs.

For both Basic Co-Simulation and Hybrid Co-Simulation the master algorithm is shielded from how the subsystem FMU advances time internally. For example, FMUs containing ODEs and exposing either of the co-simulation interfaces require to include an ODE solver inside the FMU to internally advance time between the communication points. Or, for controller code packaged as FMU, an internal scheduling algorithm will trigger tasks at the correct time and order while advancing time to the next communication point or event.

FMI for Model Exchange (ME) (Section 3)

The Model Exchange interface exposes an ODE to an external solver of an importing tool’s master algorithm. Models are described by differential, algebraic and discrete equations with time-, state- and step-events. That master algorithm, usually a DAE solver, is responsible to advance time, set states and handle events etc.

FMI for Scheduled Co-Simulation (SCS) (Section 6)

The Scheduled Co-Simulation interface exposes individual parts of a model or tasks of a control algorithm to be called from an external scheduler of an importing tool’s master algorithm. The master algorithm is responsible for: * advancing the overall simulation time, and * triggering execution of synchronous and asynchronous external events for all exposed model parts of a set of FMUs (e.g. tasks of a controller model), and * handling events (e.g. clock ticks) signaled by the FMUs.

In many ways, the Scheduled Co-Simulation 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.

The following table gives an overview of the features of the different interfaces.

Feature Model Exchange Basic Co-Simulation Hybrid Co-Simulation Scheduled Co-Simulation

Solver Included

Event Indicators

Early Return

Intermediate Value Access

Clocks

Direct Feedthrough

FMI for Co-Simulation (xCS)

Any reference to all three Co-Simulation interfaces (BCS, HCS and SCS) are referred to as Co-Simulation interface, or xCS. Writing lower-case co-simulation refers to the general concept of co-simulation.

FMI Common Concepts (Section 2)

The four interface standards have many parts in common. In particular, it is possible to utilize several instances of a model and/or a co-simulation tool and to connect them together. The interfaces are independent of the target environment because no header files are used that depend on the target environment (with exception of the data types of the target platform). This allows generating one dynamic link library that can be utilized in any environment on the same platform. A model, a co-simulation slave or the coupling part of a tool, is distributed in one ZIP file called FMU (Functional Mockup Unit) that contains several files:

1. An XML file contains the definitions of all exposed variables in the FMU and other static information. It is then possible to run the FMU on a target system without this information, in other words with no unnecessary overhead.

2. All required model equations or the access to co-simulation tools are provided with a small set of easy-to-use C functions. A new caching technique allows a more efficient evaluation of the model equations than in other approaches. These C functions can either be provided in source and/or binary form. Binary forms for different platforms can be included in the same FMU ZIP file.

3. The model equations or the co-simulation tool can be either provided directly in the FMU, or the FMU contains only a generic communication module that communicates with an external tool that evaluates or simulates the model. In the XML file, also information about the capabilities of the FMU are present, for example to characterize the ability of a Co-Simulation slave to support advanced master algorithms such as the usage of variable communication step sizes, higher order signal extrapolation, or others.

4. Further data can be included in the FMU ZIP file, especially a model icon (bitmap file), documentation files, maps and tables needed by the FMU, and/or all object libraries or dynamic link libraries that are utilized.

A growing set of tools supports FMI.

FMI 2.0.1 was a maintenance release with no new features compared to FMI 2.0. FMUs created according to FMI 2.0.1 are valid FMUs according to FMI 2.0.

FMI 2.0 was a major enhancement to FMI 1.0, that merged the FMI 1.0 Model Exchange and Co-Simulation standards and incorporates many improvements, often due to practical experience when using the FMI 1.0 standards. New features are usually optional (need neither be supported by the tool that exports an FMU, nor by the tool that imports an FMU). Details are provided in appendix A.3.1.

Conventions used in this Document

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

• Arrays appear in two forms:

• In the end-user/logical view, one- and two-dimensional arrays are used. Here the convention of linear algebra, the control community and the most important tools in this area is utilized. In other words the first element along one dimension starts at index one. In all these cases, the starting index is also explicitly mentioned at the respective definition of the array. For example, in the `modelDescription.xml` file, the set of exposed variables is defined as ordered sets where the first element is referenced with index one (these indices are, for example, used to define the sparseness structure of partial derivative matrices).

• In the implementation view, one-dimensional C arrays are used. In order to access an array element the C convention is used. For example, the first element of input argument `x` for function `setContinuousStates` is `x[0]`.

• 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` etc.).

FMI 2.0 Implementation Help

If you plan to export or import models in FMI 2.0 format, you may find the following tools/models helpful for your development (available from https://fmi-standard.org/downloads):

FMU Compliance Checker

Free software to check whether an FMI model is compliant to the FMI standard.

FMUs from other tools

In order to test the import of FMI models from other vendors in your tool, a set of test FMUs is provided.

Library to test connected FMUs

Free Modelica library to test difficult cases of connected FMI models.

FMU Software Development Kit

Free software development kit by QTronic to demonstrate basic use of FMI.

FMI Library

Free software package by Modelon that enables integration of FMI models in applications.

## 1. Overview

The FMI (Functional Mock-up Interface) defines an interface to be implemented by an executable called an FMU (Functional Mock-up Unit). The FMI functions are used (called) by a simulation environment to create one or more instances of the FMU and to simulate them, typically together with other models. An FMU may either have its own solvers (FMI for Basic Co-Simulation, Section 4) or require the simulation environment to perform numerical integration (FMI for Model Exchange, Section 3). The goal of this interface is that the calling of an FMU in a simulation environment is reasonably simple. No provisions are provided in this document for how to generate an FMU from a modeling environment.

The FMI for Model Exchange interface defines an interface to the model of a dynamic system described by differential, algebraic and discrete-time equations. It provides an interface to evaluate these equations as needed in different simulation environments, as well as in embedded control systems, with explicit or implicit integrators, and fixed or variable step-size. The interface is designed to allow the description of large models.

The FMI for Basic Co-Simulation interface is designed both for the coupling of simulation tools (simulator coupling, tool coupling), and coupling with subsystem models, which have been exported by their simulators together with its solvers as runnable code. The goal is to compute the solution of time-dependent coupled systems consisting of subsystems that are continuous in time (model components that are described by differential-algebraic equations) or are time-discrete (model components that are described by difference equations, for example discrete controllers) or both. In a block representation of the coupled system, the subsystems are represented by blocks with (internal) `state` variables `x(t)` that are connected to other subsystems (blocks) of the coupled problem by subsystem inputs `u(t)` and subsystem outputs `y(t)`.

In case of tool coupling, the modular structure of coupled problems is exploited in all stages of the simulation process beginning with the separate model setup and pre-processing for the individual subsystems in different simulation tools. During time integration, the simulation is again performed independently for all subsystems restricting the data exchange between subsystems to discrete communication points. Finally, the visualization and post-processing of simulation data can be done individually for each subsystem in its own native simulation tool or by the simulation environment.

The two interfaces have large parts in common. These parts are defined in Section 2. In particular:

• FMI Application Programming Interface (C)
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)
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, such as C++, C#, Java, or Python. Note that there are many free and commercial libraries in different programming languages to read XML files into an appropriate data structure. See for example http://en.wikipedia.org/wiki/XML#Parsers and especially the efficient open source parser SAX (http://sax.sourceforge.net/, http://en.wikipedia.org/wiki/Simple_API_for_XML).

An FMU (in other words a model without integrators, a runnable model with integrators, or a tool coupling interface) is distributed in one ZIP file. The ZIP file contains (more details are given in Section 2.3):

• The FMI Description File (in XML format).

• The C sources of the FMU, including the needed run-time libraries used in the model, and/or binaries for one or several target machines, such as Windows dynamic link libraries (.dll) or Linux shared object libraries (.so). The latter solution is especially used if the FMU provider wants 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. An FMU may contain physical parameters or geometrical dimensions, which should not be open. On the other hand, some functionality requires source code.

• Additional FMU data (such as tables or maps) in FMU specific file formats.

A schematic view of an FMU is shown in Figure 1:

Figure 1. Data flow between the environment and an FMU.

For details, see Section 3 and Section 4. Blue arrows: Information provided by the FMU. Red arrows: Information provided to the FMU.

Publications for FMI are available from https://fmi-standard.org/literature/, especially [BOA11] and [BOA12].

### 1.1. 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 interface functions. The listed issues are sorted, starting from high-level properties to low-level implementation issues.

Expressivity

The FMI provides the necessary features that Modelica®, Simulink® and SIMPACK® models can transform to an FMU. [Modelica is a registered trademark of the Modelica Association, Simulink is a registered trademark of the MathWorks Inc., SIMPACK is a registered trademark of SIMPACK AG.]

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, for example, as part of an AUTOSAR SWC. Keeping the FMU independent of the target processor increases the usability of the FMU and is even required by the AUTOSAR software component model. Implementation: Using a textual FMU (distribute the C source of the FMU).

Simulator independence

It is possible to compile, link and distribute an FMU without knowing the target simulator. 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. Implementation: Using a binary FMU. When generating a binary FMU such as a Windows dynamic link library (.dll) or a Linux shared object library (.so), the target operating system and eventually the target processor must be known. However, no run-time libraries, source files or header files of the target simulator are needed to generate the binary FMU. As a result, the binary 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 run-time libraries).

Communication between an FMU and a target simulator through the FMI does not introduce significant run-time overhead. This is achieved by a new caching technique (to avoid computing the same variables several times) and by exchanging multiple quantities with one call.

Small footprint

A compiled FMU (the executable) is small. 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 signal 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 (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 that problems which are numerically critical (for example, time and state events, multiple sample rates, stiff problems) can 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.

Implementation

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 target simulator 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, argument types and return values 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 simulator are released by the simulator. Reason: this helps to prevent memory leaks and run-time errors due to incompatible run-time 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 is encoded using C, not C++. Reason: Avoid problems with compiler and linker dependent behavior. Run FMU on embedded target.

This version of the functional mock-up interface 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, like SIMPACK, 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.2. 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.

## 2. Common Concepts

The concepts defined in this chapter are defined that are common for Model Exchange and Co-Simulation interface types. In both cases, FMI defines an input/output block of a dynamic model where the distribution of the block, the platform dependent header file, several access functions, as well as the schema files are identical. The definitions that are specific to the particular cases are defined in Section 3 and Section 4.

Below, the term FMU (Functional Mock-up Unit) will be used as common term for a model following the interface type FMI for Model Exchange, or a co-simulation slave following all or any subset of the Co-Simulation interface types (Basic Co-Simulation, Hybrid Co-Simulation or Scheduled Co-Simulation). Note that the standard supports several interface types to co-exist inside one FMU.

### 2.1. FMI Application Programming Interface

This section contains the common interface definitions to execute functions of an FMU from a C program.

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 environment that uses the FMU must guarantee that the calling sequences of functions defined in Section 3.2.3 and Section 4.2.4. are used. The FMU itself does not implement any services to support this.]

• 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 process/threads. 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.]

#### 2.1.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 defintions for constants. This header file must be used both by the FMU and by the target simulator. [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.

[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 and that are defined in Section 2, Section 3 and Section 4.

This header file includes `fmi3PlatformTypes.h` and `fmi3FunctionTypes.h`. The header file version number for which the model was compiled, can be inquired in the target simulator with `fmi3GetVersion` (see Section 2.1.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 textual 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 first variant 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>` or `<fmiModelDescription><{Basic|Hybrid|Scheduled}CoSimulation>` together with `_` at the end (see Section 3.3, Section 4.3, Section 5.3, Section 6.3).

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 tool (`needsExecutionTool = true`, see Section 4). This is particularily 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. 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).

#### 2.1.2. Platform Dependent Definitions (fmi3PlatformTypes.h)

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. [Only for source code FMUs, a change might be useful in some cases.]:

``typedef void*           fmi3Instance;             /* Pointer to 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 respective slave. This data structure is implemented by the environment that provides the FMU; in other words, the calling environment does not know its content, and the code to process it must be provided by the FMU generation environment and must be shipped with the FMU.

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

This is a pointer to a data structure in the simulation environment that calls the FMU. Using this pointer, data from the `modelDescription.xml` file [for example, mapping of `valueReference`s to variable names] can be transferred between the simulation environment and the `logMessage` function (see Section 2.1.5).

``typedef void*           fmi3FMUState;             /* Pointer to 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.1.10).

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

This is a handle to a (base type) variable value of the model. A handle uniquely identifies the value of a variable. Variables that have the same handle, always have identical values, but other parts of the variable definition might be different [for example, min/max attributes].

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 variables via this handle. Extracting concrete information about a variable is specific to the used environment that reads the Model Description File in which the value handles 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 has to return with an error ( `fmi3Status = fmi3Error`, see Section 2.1.3).

``````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             int 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            char 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             int fmi3Clock ;   /* Data type to be used with fmi3ClockActive and
fmi3ClockInactive */

/* Values for fmi3Boolean */
#define fmi3True  1
#define fmi3False 0

/* Values for fmi3Clock */
#define fmi3ClockActive   1
#define fmi3ClockInactive 0``````

These data types are the base types used in the interfaces of the C functions.

The data types `fmi3Float32`, `fmi3Float64`, `fmi3Int8`, `fmi3UInt8`, `fmi3Int16`, `fmi3UInt16`, `fmi3Int32`, `fmi3UInt32`, `fmi3Int64`, `fmi3UInt64` and `fmi3Boolean` are called "numeric types" in the following.

If an `fmi3String` or an `fmi3Binary` variable is passed as `input` argument to an FMI function and the FMU needs to use the string/binary later, the FMI function must copy the string/binary before it returns and store it in the internal FMU memory, because there is no guarantee for the lifetime of the string/binary after the function has returned.

If an `fmi3String` or an `fmi3Binary` variable is passed as `output` argument from an FMI function and the string/binary shall be used in the target environment, the target environment must copy the whole string/binary (not only the pointer). The memory of this string/binary may be deallocated by the next call to any of the FMI interface functions (the string/binary memory might also be just a buffer, that is reused).

#### 2.1.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 all functions to indicate the success of the function call:

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

Status returned by functions. The status has the following meaning

`fmi3OK`

all well.

`fmi3Warning`

things are not quite right, but the computation can continue. Function `logMessage` was called in the model (see below), and it is expected that this function has shown the prepared information message to the user.

`fmi3Discard`

this return status is only possible if explicitly defined for the corresponding function. [Functions `fmi3Set{VariableType}` are usually not performing calculations but just store the passed values in internal buffers. The actual calculation is performed by `fmi3Get{VariableType}` functions. Still `fmi3Set{VariableType}` functions could check whether the input arguments are in their validity range. If not, these functions could return with `fmi3Discard`.] (Model Exchange: `fmi3Set{VariableType}`, `fmi3SetContinuousStates`, `fmi3Get{VariableType}`, `fmi3GetDerivatives`, `fmi3GetContinuousStates`, `fmi3GetEventIndicators`; Co-Simulation: `fmi3Set{VariableType}`, `fmi3DoStep`):

For Model Exchange: It is recommended to perform a smaller step size and evaluate the model equations again, for example because an iterative solver in the model did not converge or because a function is outside of its domain [for example, `sqrt(<negative number>)`]. If this is not possible, the simulation has to be terminated.

For Co-Simulation: `fmi3Discard` is returned also if the slave is not able to return the required status information. The master has to decide if the simulation run can be continued.
In both cases, function `logMessage` was called in the FMU (see below), and it is expected that this function has shown the prepared information message to the user if the FMU was called in debug mode (`loggingOn = fmi3True`). Otherwise, `logMessage` should not show a message.

`fmi3Error`

the FMU encountered an error. The simulation cannot be continued with this FMU instance. If one of the functions returns `fmi3Error`, it can be tried to restart the simulation from a formerly stored FMU state by calling `fmi3SetFMUState`. This can be done if the capability flag `canGetAndSetFMUState = true` and `fmi3GetFMUState` was called before in non-erroneous state. If not, the simulation cannot be continued and `fmi3FreeInstance` or `fmi3Reset` must be called afterwards. [Typically, `fmi3Error` return is for non-numerical reasons, like "disk full". There may be cases where the environment can fix such errors (possibly with the help of the user), and the simulation can continue at the last consistent state set with `fmi3SetFMUState`.]
Further processing is possible after this call; especially other FMU instances are not affected. Function `logMessage` was called in the FMU (see below), and it is expected that this function has shown the prepared information message to the user.

`fmi3Fatal`

the model computations are irreparably corrupted for all FMU instances. [For example, due to a run-time exception such as access violation or integer division by zero during the execution of an fmi function]. Function `logMessage` was called in the FMU (see below), and it is expected that this function has shown the prepared information message to the user. It is not possible to call any other function for any of the FMU instances.

#### 2.1.4. Inquire Platform and Version Number of Header Files

This section documents functions to inquire information about the header files used to compile its functions.

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

Returns the version of the `fmi3Functions.h` header file which was used to compile the functions of the FMU. The function returns `fmi3Version` which is defined in this header file. The standard header file as documented in this specification has version `"3.0"` (so this function usually returns `"3.0"`).

#### 2.1.5. Creation, Destruction and Logging of FMU Instances

This section documents functions that deal with instantiation, destruction and logging of FMUs.

``````typedef fmi3Instance fmi3InstantiateModelExchangeTYPE(
fmi3String                 instanceName,
fmi3String                 instantiationToken,
fmi3String                 resourceLocation,
fmi3Boolean                visible,
fmi3Boolean                loggingOn,
fmi3InstanceEnvironment    instanceEnvironment,
fmi3CallbackLogMessage     logMessage,
fmi3CallbackAllocateMemory allocateMemory,
fmi3CallbackFreeMemory     freeMemory);

typedef fmi3Instance fmi3InstantiateBasicCoSimulationTYPE(
fmi3String                     instanceName,
fmi3String                     instantiationToken,
fmi3String                     resourceLocation,
fmi3Boolean                    visible,
fmi3Boolean                    loggingOn,
fmi3Boolean                    intermediateVariableGetRequired,
fmi3Boolean                    intermediateInternalVariableGetRequired,
fmi3Boolean                    intermediateVariableSetRequired,
fmi3InstanceEnvironment        instanceEnvironment,
fmi3CallbackLogMessage         logMessage,
fmi3CallbackAllocateMemory     allocateMemory,
fmi3CallbackFreeMemory         freeMemory,
fmi3CallbackIntermediateUpdate intermediateUpdate);

typedef fmi3Instance fmi3InstantiateHybridCoSimulationTYPE(
fmi3String                     instanceName,
fmi3String                     instantiationToken,
fmi3String                     resourceLocation,
fmi3Boolean                    visible,
fmi3Boolean                    loggingOn,
fmi3Boolean                    intermediateVariableGetRequired,
fmi3Boolean                    intermediateInternalVariableGetRequired,
fmi3Boolean                    intermediateVariableSetRequired,
fmi3InstanceEnvironment        instanceEnvironment,
fmi3CallbackLogMessage         logMessage,
fmi3CallbackAllocateMemory     allocateMemory,
fmi3CallbackFreeMemory         freeMemory,
fmi3CallbackIntermediateUpdate intermediateUpdate);

typedef fmi3Instance fmi3InstantiateScheduledCoSimulationTYPE(
fmi3String                     instanceName,
fmi3String                     instantiationToken,
fmi3String                     resourceLocation,
fmi3Boolean                    visible,
fmi3Boolean                    loggingOn,
fmi3Boolean                    intermediateVariableGetRequired,
fmi3Boolean                    intermediateInternalVariableGetRequired,
fmi3Boolean                    intermediateVariableSetRequired,
fmi3InstanceEnvironment        instanceEnvironment,
fmi3CallbackLogMessage         logMessage,
fmi3CallbackAllocateMemory     allocateMemory,
fmi3CallbackFreeMemory         freeMemory,
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`).

These instantiation functions must be called successfully before any of the following functions can be called.

`fmi3InstantiateModelExchange`

FMU with initialization and events; between events simulation of continuous systems is performed with external integrators from the environment (see Section 3). The `modelDescription.xml` has to include a `<ModelExchange>` element to allow calling `fmi3InstantiateModelExchange`.

`fmi3InstantiateBasicCoSimulation`

Black box interface for Basic Co-Simulation (see Section 4). The `modelDescription.xml` has to include a `<BasicCoSimulation>` element to allow calling `fmi3InstantiateBasicCoSimulation`.

`fmi3InstantiateHybridCoSimulation`

Black box interface for Basic Co-Simulation (see Section 5). The `modelDescription.xml` has to include a `<HybridCoSimulation>` element to allow calling `fmi3InstantiateHybridCoSimulation`.

`fmi3InstantiateScheduledCoSimulation`

Black box interface for Basic Co-Simulation (see Section 6). The `modelDescription.xml` has to include a `<ScheduledCoSimulation>` element to allow calling `fmi3InstantiateScheduledCoSimulation`.

• Argument `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. It is not allowed to provide a null pointer and this string must be non-empty (in other words, must have at least one character that is no white space). [If only one FMU is simulated, as `instanceName` attribute `modelName` or `<ModelExchange/ BasicCoSimulation/ HybridCoSimulation/ ScheduledCoSimulation modelIdentifier="..">` from the XML schema `fmi3ModelDescription` might be used.]

• Argument `instantiationToken` can be used by the FMU to check that the `modelDescription.xml` file (see Section 2.3) 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.2.1). It must be passed unchanged to the FMU, this argument must not be null.

• Argument `resourceLocation` is a URI according to the IETF RFC3986 syntax to indicate the location to the `resources` directory of the unzipped FMU archive. The following schemes must be understood by the FMU:

• Mandatory: `file` with absolute path (either including or omitting the authority component)

• Optional: `http`, `https`, `ftp`

[Example: An FMU is unzipped in directory `C:\temp\MyFMU`, then `resourceLocation` = `file:///C:/temp/MyFMU/resources` or `file:/C:/temp/MyFMU/resources`. The `fmi3InstantiateXXX` functions are then able to read all needed resources from this directory, for example maps or tables used by the FMU.]

• Argument `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 argument `loggingOn = fmi3False`, then any logging is disabled and the logger function is not called by the FMU. If argument `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.2.5).

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

• Argument `intermediateVariableGetRequired` TODO explanation required

• Argument `intermediateInternalVariableGetRequired` TODO explanation required

• Argument `intermediateVariableSetRequired` TODO explanation required

These following arguments are function pointers provided by the environment to be used by the FMU. 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.

In the default `fmi3FunctionTypes.h` file, typedefs for the function definitions are present to simplify the usage; this is non-normative. These callback functions have the following meaning:

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

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

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

• Argument `status` contains the severity of the message. If `logMessage` is called with `status = fmi3OK`, then the message is a pure information message.

• Argument `category` is the category of the message. The meaning of `category` is defined by the modeling environment that generated the FMU. Depending on this modeling environment, none, some or all allowed values of `category` for this FMU are defined in the `modelDescription.xml` file via element `<fmiModelDescription><LogCategories>`, see Section 2.2.5. Only messages are provided by function `logMessage` that have a category according to a call to `fmi3SetDebugLogging` (see below).

• Argument `message` is a string that contains the message. [Typically, this function prints the message and stores it optionally in a log file.]

All string-valued arguments passed by the FMU to the `logMessage` may be deallocated by the FMU directly after function `logMessage` returns. The environment must therefore create copies of these strings if it needs to access these strings later.
The `logMessage` function will append a line break to each message when writing messages after each other to a terminal or a file (the messages may also be shown in other ways, for example, as separate text-boxes in a GUI). The caller may include line-breaks (using "\n") within the message, but should avoid trailing line breaks.
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.]

Function `allocateMemory`
``````typedef void* (*fmi3CallbackAllocateMemory) (fmi3InstanceEnvironment instanceEnvironment,
size_t nobj,
size_t size);``````

Pointer to a function that is called in the FMU if memory needs to be allocated. If attribute `canNotUseMemoryManagementFunctions = true` in `<fmiModelDescription><ModelExchange|{Basic|Hybrid|Scheduled}CoSimulation>`, then function `allocateMemory` is not used in the FMU and a null pointer can be provided. If this attribute has a value of `false` (which is the default), the FMU must not use `malloc`, `calloc` or other memory allocation functions. One reason is that these functions might not be available for embedded systems on the target machine. Another reason is that the environment may have optimized or specialized memory allocation functions. `allocateMemory` returns a pointer to space for a vector of `nobj` objects, each of size `size` or `NULL`, if the request cannot be satisfied. The space is initialized to zero bytes. [A simple implementation is to use `calloc` from the C standard library.]

Function `freeMemory`
``````typedef void  (*fmi3CallbackFreeMemory)     (fmi3InstanceEnvironment instanceEnvironment,
void* obj);``````

Pointer to a function that must be called in the FMU if memory is freed that has been allocated with `allocateMemory`. If attribute `canNotUseMemoryManagementFunctions = true` in `<fmiModelDescription><ModelExchange|{Basic|Hybrid|Scheduled}CoSimulation>`, then function `freeMemory` is not used in the FMU and a null pointer can be provided. If a null pointer is provided as input argument `obj`, the function shall perform no action. [A simple implementation is to use `free` from the C standard library; in ANSI C89 and C99, the null pointer handling is identical as defined here.]

Function `intermediateUpdate`
``````typedef fmi3Status (*fmi3CallbackIntermediateUpdate) (
fmi3InstanceEnvironment instanceEnvironment,
fmi3Float64 intermediateUpdateTime,
fmi3Boolean eventOccurred,
fmi3Boolean clocksTicked,
fmi3Boolean intermediateVariableSetAllowed,
fmi3Boolean intermediateVariableGetAllowed,
fmi3Boolean intermediateStepFinished,
fmi3Boolean canReturnEarly);``````

This callback allows internal events of different types (e.g. associated to `output clock` ticks or intermediate variable access) to be signaled from an FMU to the Co-Simulation master. For Hybrid Co-Simulation and Scheduled Co-Simulation or if any of the intermediate variable access modes is set to `true`, the callback function `fmi3CallbackIntermediateUpdate` must be passed to `fmi3InstantiateXXX`. In other cases a `NULL` can be assigned to the `intermediateUpdate` callback.

• Argument `intermediateUpdateTime` indicates the internal time of the FMU at the time of calling the callback function.

• Argument `eventOccurred` indicates with `fmi3True`, that an internal event has occurred.

• Argument `clocksTicked` indicates with `fmi3True`, that an FMU clock has ticked.

• Argument `intermediateVariableSetAllowed` indicates with `fmi3True`, if the master algorithm is allowed to set FMU variables using `fmi3Set{VariableType}`.

• Argument `intermediateVariableGetAllowed` indicates with `fmi3True`, if the master algorithm is allowed to set FMU variables using `fmi3Get{VariableType}`.

• Argument `intermediateStepFinished` indicates with `fmi3True` that an internal step was finished.

• Argument `canReturnEarly` indicates with `fmi3True`, if the master is allowed to ask the FMU to return early from a `doStep`.

The various combinations of flags allow a Co-Simulation master algorithm to react appropriately to the needs and capabilities of the FMU.

Function `lockPreemption` and `unlockPreemption`
``````typedef void       (*fmi3CallbackLockPreemption)   ();
typedef void       (*fmi3CallbackUnlockPreemption) ();``````

To provide more options to secure the code against unwanted preemption these callback functions are defined. They can be used to prevent preemption for certain code parts enclosed by `lockPreemption` and `unlockPreemption` in Scheduled Co-Simulation. Even if the Co-Simulation master 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.

``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).

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

The function controls debug logging that is output via the logger function callback.

• If argument `loggingOn = fmi3True`, debug logging is enabled, otherwise it is switched off.

• Argument `nCategories` defines the length of the next argument `categories` If `loggingOn = fmi3True` and `nCategories = 0`, then all debug messages shall be output. If `loggingOn = fmi3True` and `nCategories > 0`, then only debug messages according to the `categories` argument shall be printed via the `logMessage` function.

• Argument vector `categories` has `nCategories` elements. The allowed values of `categories` are defined by the modeling environment that generated the FMU. Depending on the generating modeling environment, none, some or all allowed values for `categories` for this FMU are defined in the `modelDescription.xml` file via element `<fmiModelDescription><LogCategories>`, see Section 2.2.5.

#### 2.1.6. Configuration, Initialization, Termination, and Resetting an FMU

This section documents functions that deal with configuration, initialization, termination, and resetting of an FMU.

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

This function call informs the FMU to setup the experiment. This function must be called after `fmi3InstantiateXXX` and before `fmi3EnterInitializationMode` is called.

• Arguments `toleranceDefined` and `tolerance` depend on the FMI interface type:

Model Exchange

If `toleranceDefined = fmi3True`, then the model is called with a numerical integration scheme where the step size is controlled by using `tolerance` for error estimation (usually as relative 'tolerance'). In such a case all numerical algorithms used inside the model (for example, to solve non-linear algebraic equations) should also operate with an error estimation of an appropriate smaller relative tolerance.

Co-Simulation

If `toleranceDefined = fmi3True`, then the communication step size of the slave is controlled by error estimation. In case the slave utilizes a numerical integrator with variable step size and error estimation, it is suggested to use `tolerance` for the error estimation of the internal integrator (usually as relative tolerance).
An FMU for Co-Simulation might ignore this argument.

• Arguments `startTime` and `stopTime` can be used to check whether the model is valid within the given boundaries or to allocate memory which is necessary for storing results. Argument `startTime` is the `fixed` `initial` value of the `independent` variable.

[It is defined with `causality` = `independent` in the `modelDescription.xml`. If the `independent` variable is `time`, `startTime` is the starting time of initialization.]

• If argument `stopTimeDefined = fmi3True`, then `stopTime` is the defined final value of the `independent` variable. If the environment tries to compute past `stopTime` the FMU has to return `fmi3Status = fmi3Error`. If `stopTimeDefined = fmi3False`, then no final value of the `independent` variable is defined and argument `stopTime` is meaningless.

[If the `independent` variable is `time`, `stopTime` is the stop time of the simulation.]

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

Informs the FMU to enter the Configuration Mode or Reconfiguration Mode.

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

Informs the FMU to exit the Configuration Mode or Reconfiguration Mode.

``typedef fmi3Status fmi3EnterInitializationModeTYPE(fmi3Instance instance);``

Informs the FMU to enter Initialization Mode. Before calling this function, all variables with attribute `initial` = `exact` or `approx` can be set with the `fmi3Set{VariableType}` functions (the variable attributes are defined in the Model Description File, see Section 2.2.10). Setting other variables is not allowed. Furthermore, `fmi3SetupExperiment` must be called at least once before calling `fmi3EnterInitializationMode`, in order that `startTime` is defined.

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

Informs the FMU to exit Initialization Mode. For Model Exchange, this function switches off all initialization equations, and the FMU enters Event Mode implicitly; that is, all continuous-time and active discrete-time equations are available.

``typedef fmi3Status fmi3TerminateTYPE(fmi3Instance instance);``

Informs the FMU that the simulation run is terminated. After calling this function, the final values of all variables can be inquired with the `fmi3Get{VariableType}` functions. It is not allowed to call this function after one of the functions returned with a status flag of `fmi3Error` or `fmi3Fatal`.

``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, `fmi3SetupExperiment` and `fmi3EnterInitializationMode` have to be called.

#### 2.1.7. Getting and Setting Variable Values

All variables of an FMU are identified with a handle called "value reference". The handle is defined in the `modelDescription.xml` file as attribute `valueReference` in variable elements. Each variable must have a unique `valueReference`.

Variables can be scalar or 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 document order in the XML attributes. 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:

]

The actual values of the variables that are defined in the `modelDescription.xml` file can be inquired after calling `fmi3EnterInitializationMode` 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);``````

Get actual values of variables by providing their variable references. [These functions are especially used to get the actual values of output variables if a model is connected with other models. Since state derivatives are also variables, it is possible to get the value of a state derivative. This is useful when connecting FMUs together. Furthermore, the actual value of every variable defined in the `modelDescription.xml` file can be determined at the actually defined time instant (see Section 2.2.10).]

• Argument `valueReferences` is a vector of `nValueReferences` value handles that define the variables that shall be inquired.

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

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

• Argument `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 strings returned by `fmi3GetString`, as well as the binary values returned by `fmi3GetBinary`, must be copied in the target environment because the allocated memory for these strings might be deallocated by the next call to any of the fmi3 interface functions or it might be an internal string buffer that is reused.

For Model Exchange: `fmi3Status = fmi3Discard` is possible for `fmi3GetFloat32` and `fmi3GetFloat64` only, but not for `fmi3Get*Int*`, `fmi3GetBoolean`, `fmi3GetString`, `fmi3GetBinary`, because these are discrete-time variables and their values can only change at an event instant where `fmi3Discard` does not make sense.

It is also possible to set the values of certain variables at particular instants in time 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);``````

Set `parameters`, `inputs`, and `start` values, and re-initialize caching of variables that depend on these variables (see Section 2.2.10 for the exact rules on which type of variables `fmi3Set{VariableType}` can be called, as well as Section 3.2.3 in case of Model Exchange and Section 4.2.4 in case of Co-Simulation).

• Argument `valueReferences` is a vector of `nValueReferences` value handles that define the variables that shall be set.

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

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

• Argument `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.

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

Note, `fmi3Status = fmi3Discard` is possible for the `fmi3Set{VariableType}` functions.

For Co-Simulation FMUs, additional functions are defined in Section 4.2.1 to set and inquire `derivatives` of variables with respect to time in order to allow interpolation.

The value of a variable may only be accessed with the respective `fmi3Get/Set{VariableType}` for its type.

#### 2.1.8. Operation on Clocks

In the following section the operations on `clocks` are described. Clocks are defined for the evaluation of clocked model partitions and the related definition of suitable communication points. Two types of `clocks` are available, designed to address similar use cases with differences in details. One `clock` type (Synchronous Clocks) complies with the limitations imposed by the synchronous clock theory, the other clock type (Communication Point Clocks) is a general purpose co-simulation clock for providing suitable communication points for the timed evaluation of model partitions. The term `clock` and clocked is therefore used for both `clock` types. Both clock types can handle two different variants, the `input clocks` and the `output clocks`. First the two different clock types are presented with the mathematical definition of their use cases. After that the two clock variants are described. The section ends with a short description of connecting clocked FMUs.

##### 2.1.8.1. Clock Types for Evaluation of Clocked Model Partitions
###### 2.1.8.1.1. Synchronous Clocks

A set of equations that are associated to a `clock` and are executed when the corresponding `clock` is active, is called a clocked partition. A clocked partition is mathematically defined as:

$x_j=\begin{cases} x_{j-1} & \text{if subactive}\\ f_j(x_{j-1},u_j,t_j) & \text{else} \end{cases}$
$y_j=g_j(x_{j-1},u_j,t_j);$
$\text{mit } j=0,1,2,...;x_{-1}=x_{start}$

Variables $x_j$ are called `states of a clocked partition`, or `discrete-time states` and $j$ is the $j+1$th tick of the associated `clock`. Variables $u_j$ are the (external or `local`) `inputs` and $y_j$ are the (external or `local`) `outputs` of a clocked partition. A discrete-time `state` can be from any type of a variable (with exception of a `clock`) such as of type `fmi3Float64` or `fmi3Boolean`. A clocked partition is not executed during Initialization Mode, but it is executed the first time at its first `clock` tick. The associated `clock` of the model partion is synchronous to its discrete-time `states`.

Discrete-time `states` are listed in the `<ModelStructure>`. They can have initial values defined by xml-attributes `initial` and `start`, or the initial values are computed internally as a function of parameters.

There are two kinds of evaluation modes:

###### 2.1.8.1.2. Communication Point Clocks

In addition to the above definition also a simplified `clock` definition used only in FMI for Basic Co-Simulation is available that can be used to define the communication points of model partitions of the model (in the following such partitions are called model partitions). Such `clocks` are called Communication Point Clocks. These `clocks` are not compatible to synchronous clocks theory and must not be used together with synchronous clocks in one model.

A model partition is mathematically defined as:

$x_j=f_j(x_{j-1},u_j,t_j)$
$y_j=g_j(x_{j-1},u_j,t_j)$

Communication Point Clocks can also be defined for continuous or piecewise continuous parts of the model.

##### 2.1.8.2. Variants of Clocks

This section gives a definition of the two clock variants.

###### 2.1.8.2.1. Output Clocks

An `output clock` is a general `clock` that ticks when a time-, state- or step-event occurs in the continuous-model partition of the FMU (for Communication Point Clocks these `output clock` tick events can occour in all model partitions) and are identified based on their `clockReference` (see Section 2.1.8). It can be periodic or non-periodic.

+ [Example: If $b = x > 0$ , and a state event is defined when b changes from `false` to `true`, and b is defined as `output clock`, then this `clock` is active whenever x changes from negative to positive values.]

Since `output clocks` are ticking based on model internal information it is required in case of FMI for Co-Simulation to signal the ticking of an `output clock` to the simulation environment during a `fmi3DoStep` computation. In most cases the signaling of an `output clock` tick is a `strong event` that requires creating a communication point for exchanging additional information (i.e. variable values) with the simulation environment. Additional cases need to be handled if a `clock` tick is not associated to an event that requires the creation of a communication point for the model partition that generated the event.

[Outside of the FMU it is not known in advance when this `clock` ticks. Instead, only when the `clock` is activated by the FMU, then the environment is informed that the `clock` ticks at this time instant. It is the task of the environment to handle the messaged events appropriately based on the `clockReference` information. Example: ]

###### 2.1.8.2.2. Input Clocks

An `input clock` is a periodic or non-periodic `clock` that is defined directly or indirectly by a `clock` outside of the FMU. Its interval is initialized by the environment.

[Inside of the FMU it is not known in advance when this `clock` ticks. Instead, only when the `clock` is activated by the environment of the FMU, then the FMU is informed that the `clock` ticks at this time instant. Example: A clocked PI controller can be defined as an FMU and the input and output signal of the controller can be defined to be on the same `input clock`. In such a case, the environment deduces the `clock` ticks from the components that are connected to the PI controller (e.g. a component connected to the input, or to the output may define the relevant `clock`).]

This section gives a definition of additional clock properties.

###### 2.1.8.3.1. Periodic Clock Ticks

Either `output` or `input`, a periodic `clock` ticks at equidistant sample time points that are known a priori (defined in `modelDescription.xml`) or are alternatively determined by the environment in case of `input clocks`. Mathematically, the next `clock` tick at time instant ti is defined as:

\begin{align*} t_0 &:= t_{start} + t_{offset} \\ t_i &:= t_{i-1} + \Delta T, i = 1,2,3,{...} \end{align*}

where:

 $t_0$ The time instant in seconds at which the `clock` ticks the first time (= the base `clock` starts at the start of the simulation tstart or when the controller is switched on plus an offset time toffset (xml-attributes `shiftCounter` and `resolution`). $t_{i-1}$ The previous time instant in seconds, where the `clock` ticked. $\Delta T > 0$ The constant time interval from the previous `clock` tick to the current `clock` tick. It is defined as a rational number based on `intervalCounter` and `resolution` via `clock` variable attributes.

The interval $\Delta T$ and $t_{offset}$ must be defined for periodic `clocks` in the XML file. In case of periodic `input clocks` these values are the start interval values if they are not given by the simulation master. [This information can be used for emulating periodic `input clocks` in the Co-Simulation interface types.].

If $\Delta T$ is fixed for an FMU and cannot be changed it is a strictly periodic `clock`. The `clock` is periodic, if $\Delta T$ can be defined before calling `fmi3EnterInitializationMode` via `fmi3SetIntervalDecimal` or `fmi3SetIntervalFraction`. The `clock` is aperiodic if $\Delta T$ is not constant during a simulation run (`fmi3SetIntervalDecimal` or `fmi3SetIntervalFraction` can be called for that `clock` during Event Mode).

###### 2.1.8.3.2. Clock Priority

The `clocks` are ordered descending based on their priorities. It is nevertheless possible to define multiple `clocks` with the same priority. No ordering is defined for `clocks` of the same priority. If a computational order information is needed, different priorities for `clocks` have to be defined. The priority of a `clock` has to be defined in the `modelDescription.xml` via the `clock` variable integer attribute `priority` - smaller values have a higher priority. For periodic `clocks` it is recommended to derive the priorities based on a rate monotonic scheduling scheme (smallest period leads to highest priority (smallest priority value)).

_[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 simulation master 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 real-time computation use cases i.e. in Scheduled Co-Simulation 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. A common number of different priority levels is e.g. 100 (0 to 99) as defined in Linux based operating systems. Nevertheless, restricting the number of used distinct priority levels as much as possible is recommended to avoid unnecessary computational overhead.]_

###### 2.1.8.3.3. Clock Relationships for Communication Point Clocks

If `output clocks` and `input clocks` are defined it is possible to define a tick relationship from an `output clock` to an `input clock`. This is needed to allow for an external resource management to achieve an optimal control of model partitions. The `output clocks` and the associated `input clocks` define a union of `clocks`. In that sense, if an `output clock` ticks the associated `input clock` ticks at the same time instant in such a union. It is only meaningful to combine one or multiple `output clocks` with a single aperiodic `input clock` in such a union. It is possible to define multiple unions of `clocks`, with the maximum number defined by the number of available aperiodic `input clocks`.

 Input clock variant Output clock variant aperiodic aperiodic, periodic, strictly periodic periodic - strictly periodic -

A clock union can be defined based on the `clockReference` attribute of `input clock` variables.

##### 2.1.8.4. Connecting Clocked FMUs

When connecting imported FMUs together, `input` and `output` variables can readily be connected together only when they are defined on a `clock` with identical properties. If this is not possible, an explicit cast of one `clock` to another `clock` is typically defined in the environment.

The environment can evaluate required `clock` adaptions/casts for connections basing on the `clockReference` attribute of assigned variables [i.e. the variables that are assigned to a `clock` based on `modelDescription.xml` information].

[Example: Elementary blocks like a PI controller will have all variables on an `input clock` with identical properties. Connecting such blocks together will therefore be possible without computationally expensive clock cast operations (and the environment can readily do the computation of assigned variables of the connected blocks based on the same `clock`).]

#### 2.1.9. FMI Application Programming Interface for setting/getting Clock activation state

A `clock` is activated by the environment for the current time instant by the function `fmi3SetClock`, and the status of a `clock` can be inquired with the function `fmi3GetClock`:

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

Sets `clocks` activation status by providing the value references of the corresponding `clock` variables and their values.

• Argument `valueReferences[]` points to an array of value references of clocks to be activated or deactivated at the current time instant depending on

• argument `values[]` content: if the nth element is `fmi3ClockActive` the nth clock is activated, otherwise deactivated.

• Argument `nValueReferences` indicates the size of the parallel arrays `valueReferences[]` and `values[]` (and potentially `subactive[]`).

• Argument `subactive[]` requires evaluation of a clocked partition in subactive mode (only output equations) if the argument subactive is non NULL and `subactive[i] = fmi3True`. `subactive[i]` has no meaning for Communication Point Clocks and is ignored for such `clocks`. It is not allowed to call this function within the callback function `fmi3IntermediateUpdate`.

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

Inquires whether a set of `clocks` is active by providing the value references of the corresponding `clock` variables.

• Argument `valueReferences[]` contains a list of value references to `clocks` of the size indicated by

• argument `nValueReferences`.

• Argument `values[]` will return the activation status at the current time instant of the `clocks` referenced by `valueReferences[]`. If `values[i] = fmi3ClockActive` the `clock` is currently active, otherwise the `clock` is not active.

It is allowed to call this function within the callback function `fmi3IntermediateUpdate`. It is required for an FMU to directly internally set back the activation `state` of an output clock[i] to `fmi3ClockInactive`, if the function `fmi3GetClock` is called for a `clock[i]` and the interface is Scheduled Co-Simulation.

[This is required to allow preemption.]

A `clock` interval is set by the environment for the current time instant by the function `fmi3SetIntervalDecimal` or `fmi3SetIntervalFraction`, and it can be inquired with the function `fmi3GetIntervalDecimal` or `fmi3GetIntervalFraction`:

``````typedef fmi3Status fmi3SetIntervalDecimalTYPE(fmi3Instance instance,
const fmi3ValueReference valueReferences[],
size_t nValueReferences,
const fmi3Float64 interval[]);``````
``````typedef fmi3Status fmi3SetIntervalFractionTYPE(fmi3Instance instance,
const fmi3ValueReference valueReferences[],
size_t nValueReferences,
const fmi3UInt64 intervalCounter[],
const fmi3UInt64 resolution[]);``````
``````typedef fmi3Status fmi3GetIntervalDecimalTYPE(fmi3Instance instance,
const fmi3ValueReference valueReferences[],
size_t nValueReferences,
fmi3Float64 interval[]);``````
``````typedef fmi3Status fmi3GetIntervalFractionTYPE(fmi3Instance instance,
const fmi3ValueReference valueReferences[],
size_t nValueReferences,
fmi3UInt64 intervalCounter[],
fmi3UInt64 resolution[]);``````

Both functions inquire the interval value for the provided `clocks` (periodic or non-periodic). If the `clocks` are non-periodic, the interval has to be inquired at every `clock` tick, to define the follow-up `clock` tick.

The following table summarizes the use of the API functions by the environment for different kind of `clocks`:

 API function `Output clock` `Input clock` `fmi3GetClock` Call during Event Mode Call during Event Mode `fmi3SetClock` Call only if recomputations of clock state are needed during Event Mode. Call after entering Event Mode. Repeated calls if recomputations of clock state are needed during Event Mode. `fmi3GetIntervalDecimal` `fmi3GetIntervalFraction` Call during Event Mode Call during Event Mode `fmi3SetIntervalDecimal` `fmi3SetIntervalFraction` Don’t call. Call after first `clock` activation. (only for periodic `clocks`)

#### 2.1.10. 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-time 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 master 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 signals 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.]

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

makes a copy of the internal FMU state and returns a pointer to this copy (`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`.]

`fmi3SetFMUState`

copies the content of the previously copied `FMUState` back and uses it as actual new FMU state. The `FMUState` copy still exists.

`fmi3FreeFMUState`

frees all memory and other resources allocated with the `fmi3GetFMUState` call for this `FMUState`. The input 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 are only supported by the FMU, if the optional capability flag `canGetAndSetFMUState` in `<fmiModelDescription><ModelExchange|{Basic|Hybrid|Scheduled}CoSimulation>` in the XML file is explicitly set to `true` (see Section 3.3.1, Section 4, Section 5, Section 6).

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

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

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

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`.

`fmi3SerializeFMUState`

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.

`fmi3DeSerializeFMUState`

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

[The simulation is restarted at this state, when calling `fmi3SetFMUState` with `FMUState`.]

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

#### 2.1.11. Getting Partial Derivatives

It is optionally possible to provide evaluation of partial derivatives for an FMU. For Model Exchange, this means computing the partial derivatives at a particular time instant. For co-simulation, this means to compute the partial derivatives at a particular communication point.

The partial derivatives refer are defined as partial derivatives of certain variables of the FMU w.r.t. to other variables:

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.1) and Co-Simulation (Section 4.1). In every state, the general form of the FMU equations are:

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

where

• $\mathbf{v}_{unknonwn}$ is the vector of unknown floating point variables computed in the actual state:

• Initialization Mode: The exposed unknowns listed as elements `<ModelStructure><InitialUnknown>` that have a floating point type.

• Continuous-Time Mode (Model Exchange): The continuous-time outputs and state derivatives (= the variables listed as elements `<ModelStructure><Output>` with a floating point type and `variability` = `continuous` and the variables listed as elements `<ModelStructure><Derivative>`).

• Event Mode (Model Exchange): The same variables as in the Continuous-Time Mode and additionally variables listed as elements `<ModelStructure><Output>` with a floating point type and `variability` = `discrete`.

• Step Mode (Basic Co-Simulation and Hybrid Co-Simulation): The variables listed as elements `<ModelStructure><Output>` with a floating point type and `variability` = `continuous` or `discrete`. Each state derivative variable listed as elements `<ModelStructure><Derivative>`, if present.

• $\mathbf{v}_{known}$ is the vector of known floating point `input` variables of function h that changes its value in the actual state.

Details are described in the description of element `dependencies` in Section 2.2.11. [For example continuous-time `inputs` in Continuous-Time Mode. If a variable with `causality` = `independent` is explicitly defined under `<ModelVariables>`, a directional derivative with respect to this variable can be computed. If such a variable is not defined, the directional derivative with respect to the `independent` variable cannot be calculated].

• ${\mathbf{v}_{rest}}$ is the set of `input` variables of function h that either changes its value in the actual state but are non-floating point variables, or do not change their values in this state, but change their values in other states [for example, discrete-time `inputs` in Continuous-Time Mode].

[The variable relationships are different in different states. For example, during Continuous-Time Mode, a continuous-time output y does not depend on discrete-time `inputs` (because they are held constant between events). However, at Event Mode, y depends on discrete-time `inputs`. The function may compute the directional derivatives by numerical differentiation taking into account the sparseness of the equation system, or (preferred) by analytic derivatives.]

There are two access functions for partial derivatives:

with the Jacobian

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

where $\mathbf{v}_{known}$ are the $n$ knowns, and $\mathbf{h}$ are the $m$ functions to calculate the $m$ unknwon variables $\mathbf{v}_{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 `providesDirectionalDerivative` and `providesAdjointDerivative` 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 parameters:

• Argument `unknowns[]` contains value references to the unknowns.

• Argument `nUnknowns` contains the length of argument `unknowns[]`.

• Argument `knowns[]` contains value references of the knowns.

• Argument `nKnowns` contains the length of argument `knowns[]`.

• Argument `seed[]` contains the seed values.

• Argument `nSeed` contains the length of `seed[]`.

• Argument `sensitivity[]` contains the sensitivity values.

• Argument `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.1.11.1. Directional derivatives

[Example 1
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_{unknown} = y_1}$, ${v_{known} = \left \{ u_1, u_3 \right \}}$), and then the environment calls this wrapper function with ${v_{seed} = \left \{ 1, 0 \right \}}$ to compute the partial derivative with respect to ${u_1}$ and ${v_{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_{unknown} = y_1, v_{known} = u_1, v_{seed} = 1}$; and ${v_{unknown} = y_1, v_{known} = u_3, v_{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_{sensitivity} = \Delta y_1 (\Delta x = 0, \Delta u_1 = 1, \Delta u_3 = 0, \Delta u_4 = 0)}$] and ${v_{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:

``````// from the XML file:
//   nx       number of states
//   vr_x[]   value references of continuous states
//   vr_xd[]  value references of state derivatives
//
// variables:
//   m        model instance
//   x[]      continuous states
//   dk = 1   delta knowns
//   J[][]    Jacobian (transposed for simplicity)

// set time, states and inputs
fmi3SetTime(m, time);
fmi3SetContinuousStates(m, x, nx);
// fmi3SetFloat*/Int*/UInt*/Boolean/String/Binary(m, ...)

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

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

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

2. 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.

3. 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 2

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 artifical 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 pararameter estimation (see [BKF17])

Typically, reverse mode automatic differentiatian (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}_{unknown} = \text{valueReferences of} \left \{ y_1, y_2 \right \}, \mathbf{v}_{knwon} = \text{valueReferences of} \left \{ u_1, u_2 \right \}, \mathbf{v}_{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$ ]

#### 2.1.12. Getting Number of Event Indicators

The number of event indicators can change during simulation if it depends on one or more `tunable` `structural parameters` and can be retrieved after instantiating the FMU by calling:

``typedef fmi3Status fmi3GetNumberOfEventIndicatorsTYPE(fmi3Instance instance, size_t* nz);``

This function returns the number of event indicators. The dependency of the number of event indicators on `structural parameters` is implicitly given in the `modelDescription.xml` file. [All event indicator variables are listed as elements `<EventIndicator>` in `<ModelStructure>`. If the event indicator variable is an array variable and the `<Dimension>` element maps to a dependent variable than this dependent variable is a dependency for the number of event indicators.] If all `structural parameters` are unchanged then this dependency information can be used to calculate the initial number of states just using information given in the XML file without the need to call this C-API function.

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

#### 2.1.13. Getting Number of States

The number of `states` can change during simulation if it depends on one or more `tunable` `structural parameters` and can be retrieved after instantiating the FMU by calling:

``typedef fmi3Status fmi3GetNumberOfContinuousStatesTYPE(fmi3Instance instance, size_t* nx);``

This function returns the number of `states`. The dependency of the number of states on `structural parameters` is implicitly given in the `modelDescription.xml` file. [All state derivative variables are listed as elements `<Derivative>` in `<ModelStructure>`. Each state derivative variable maps to the corresponding state variable by the `derivative` attribute. If the state variable is an array variable and the `<Dimension>` element maps to a dependent variable than this dependent variable is a dependency for the number of states.] If all `structural parameters` are unchanged then this dependency information can be used to calculate the initial number of states just using information given in the XML file without the need to call this C-API function.

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

#### 2.1.14. Getting Number of Variable Dependencies and Variable Dependencies

The sparseness information within arrays is not given in the xml description. The sparseness muss be retrieved during run-time using the C-API functions. Zeros in the Jacobian are not necessarily due to the structure of the model. Zero in the Jacobian might be due to the current operating point (current `state`, current `inputs`) and not due to a structural independence.

The variable dependency information in the XML description does not resolve to dependencies of individual array elements, nor does it take into account changing dependencies due to resizing of arrays via `structural parameters`. 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. Note that these functions are only defined if the `providesPerElementDependencies` capability flag = `true`.

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 `fmi3DependencyKind`) can be retrieved by calling the function `fmi3GetVariableDependencies`:

``````typedef enum {
/* fmi3Independent = 0, not needed but reserved for future use */
fmi3Constant  = 1,
fmi3Fixed     = 2,
fmi3Tunable   = 3,
fmi3Discrete  = 4,
fmi3Dependent = 5
} 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.

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

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

• Argument `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).

• Argument `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.

• Argument `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).

• Argument `dependencyKinds` must point to a buffer of `fmi3DependencyKind` 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 run-time 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. FMI Description Schema

All static information related to an FMU is stored in the text file `modelDescription.xml` in XML format. Especially, the FMU variables and their attributes such as `name`, `unit`, default `initial` value, etc. are stored in this 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 this XML file is defined with the schema file `fmi3ModelDescription.xsd`. This schema file utilizes several helper schema files.

In this section these schema files are discussed. The normative definition are the above mentioned schema files. Below, optional elements are marked with a dashed box. 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 `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` `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` `byte` Integer number with maximum value 127 and minimum value -128 (8 bit signed integer) `int8_t` `unsignedByte` Integer number with maximum value 255 and minimum value 0 (8 bit unsigned integer) `uint8_t` `short` Integer number with maximum value 32767 and minimum value -32768 (16 bit signed integer) `int16_t` `unsignedShort` Integer number with maximum value 65535 and minimum value 0 (16 bit unsigned integer) `uint16_t` `int` Integer number with maximum value 2147483647 and minimum value -2147483648 (32 bit signed integer) `int32_t` `unsignedInt` Integer number with maximum value 4294967295 and minimum value 0 (32 bit unsigned integer) `uint32_t` `long` Integer number with maximum value 9223372036854775807 and minimum value -9223372036854775808 (64 bit signed integer) `int64_t` `unsignedLong` Integer number with maximum value 18446744073709551615 and minimum value 0 (64 bit unsigned integer) `uint64_t` `boolean` Boolean number. Legal literals: `false`, `true`, `0`, `1` `int` `string` Any number of characters `char*` `normalizedString` String without carriage return, line feed, and tab characters `char*` `hexBinary` Arbitrary hex-encoded binary data `char*` `dateTime` Date, time and time zone (for details see the link above). Example: `2002-10-23T12:00:00Z` (noon on October 23, 2002, Greenwich Mean Time) tool specific

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.].

The special values `NaN`, `+INF`, `-INF` for variables values are not allowed in the FMI XML files.

[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 `<ModelVariables><Derivative>` is only correct if this property is fulfilled.]

#### 2.2.1. Definition of an FMU (fmiModelDescription)

This is the root-level schema file and contains the following definition (the figure below contains all elements in the schema file. Data is defined by attributes to these elements):

On the top level, the schema consists of the following elements (see figure above). [Note that elements `<ModelVariables>` and `<ModelStructure>` are mandatory, whereas `<UnitDefinitions>`, `<TypeDefinitions>`, `<LogCategories>`, `<DefaultExperiment>`, and `<VendorAnnotation>` are optional. If an optional element is present and defines a list (such as `<UnitDefinitions>`), the list must have at least one element (such as `<Unit>`).]

Element Description

`<ModelExchange>`

If present, the FMU is based on FMI for Model Exchange [(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)].

`<BasicCoSimulation>`

If present, the FMU is based on FMI for Basic Co-Simulation [(in other words, the FMU includes the model and the simulation engine, or a communication to a tool that provides the model and the simulation engine, and the environment provides the master algorithm to run coupled FMU Co-Simulation slaves together)].

`<HybridCoSimulation>`

If present, the FMU is based on FMI for Hybrid Co-Simulation.

`<ScheduledCoSimulation>`

If present, the FMU is based on FMI for Scheduled Co-Simulation.

`<BuildConfiguration>`

If present, instructs how to compile sources of a C-code FMU.

`<UnitDefinitions>`

A global list of unit and display unit definitions [for example, 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.

`<Terminals>`

If present, this allows combining input and output signals into logical groups to ease connections on a system level.

`<GraphicalRepresentation>`

If present, contains information for authoring tools to draw graphical representations of the FMU in a system view.

`<VendorAnnotations>`

Additional data that a vendor might want to store and that other vendors might ignore.

`<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.2.11. 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.].

At least one element of `<ModelExchange>`, `<BasicCoSimulation>`, `<HybridCoSimulation>` or `<ScheduledCoSimulation>` must be present to identify the type of the FMU. If both elements are defined, different types of models are included in the FMU. The details of these elements are defined in Section 3.3.1, Section 4, Section 5 or Section 6.

The XML attributes of `<fmiModelDescription>` are:

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`].

`variableNamingConvention`

Defines whether the variable names in `<ModelVariables>` and in `<TypeDefinitions>` follow a particular convention. For the details, see Section 2.2.12. 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.2.2. Definition of Source Code (BuildConfiguration)

The `<BuildConfiguration>` provides the necessary information to compile and link the contained sources of the model into a dynamic library or as part of an executable.

Attribute Description

`modelIdentifier`

The attribute `modelIdentifier` of the `<ModelExchange>`, `<BasicCoSimulation>`, `<HybridCoSimulation>` or `<ScheduledCoSimulation>` elements this build configuration is associated with.

`platform`

Platform tuple of the platform the build configuration is intended for (e.g. `x86_64-linux`)

`description`

Description of the build configuration

##### 2.2.2.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>`.

Attribute Description

`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.2.2.1.1. SourceFile
Attribute Description

`name`

Path of the source file relative to the `sources` directory

###### 2.2.2.1.2. PreprocessorDefinition

The `<PreprocessorDefinition>` element defines a preprocessor definition that needs to be passed to the compiler when compiling the source files in the `<SourceFileSet>`.

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.2.2.1.3. 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.

Attribute Description

`value`

Value of the preprocessor definition option

`description`

Description of the preprocessor definition option

###### 2.2.2.1.4. IncludeDirectory

The `<IncludeDirectory>` element defines the include directories that need to be passed to the compiler when compiling the source files in the `<SourceFileSet>`.

Attribute Description

`name`

Path of the include directory relative to the `sources` directory

###### 2.2.2.1.5. Library

The `<Library>` element defines a static library required to link the model binary.

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.2.2.1.6. Examples
A minimal build configuration
``````<BuildConfiguration modelIdentifier="PIDContoller">
<SourceFileSet>
<SourceFile name="all.c"/>
</SourceFileSet>
</BuildConfiguration>``````
Multiple complex build configurations
``````<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="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>``````

#### 2.2.3. Definition of Units (UnitDefinitions)

[In this section, the units of the variables are (optionally) 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. The approach used here is slightly different than FMI 1.0 to reduce the need for standardized string representations.]

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

It consists of zero or more `Unit` definitions. [If no units are defined, element `<UnitDefinitions>` must not be present. If 1 or more units are defined, this element must be present.] A `Unit` is defined by its `name` attribute such as `N.m` or `N*m` or `Nm`, which must be unique with respect to all other defined elements of the `<UnitDefinitions>` list. If a variable is associated with a `Unit`, then the value of the variable has to be provided with the `fmi3Set{VariableType}` functions or else is returned by the `fmi3Get{VariableType}` functions with respect to 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 string representation of the unit is required.]

Optionally, a value given in unit `Unit` can be converted to a value with respect to unit `<BaseUnit>` utilizing the conversion `factor` and `offset` attributes:

Besides `factor` and `offset`, the `<BaseUnit>` definition consists of the exponents of the 7 SI base units `kg`, `m`, `s`, `A`, `K`, `mol`, `cd`, and of the exponent of the SI derived unit `rad`. [Depending on the analysis/operation carried out, the SI derived unit `rad` is or is not utilized, see discussion below. The additional `rad` base unit helps to handle the often occurring quantities in technical systems that depend on an angle.]

A value with respect to `Unit` (abbreviated as `Unit_value`) is converted with respect to `<BaseUnit>` (abbreviated as `BaseUnit_value`) by the equation:

`BaseUnit_value = factor * Unit_value + offset`

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

$\color{blue}{p_{Pa} = 10^5 p_{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 "$\color{blue}{kgm^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` $\color{blue}{kg \cdot m^2 / s^2}$ `1.0` `0.0` Energy `J` $\color{blue}{kg \cdot m^2 / s^2}$ `1.0` `0.0` Pressure `bar` $\color{blue}{\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):

Signal connection check

When two signals v1 and v2 are connected together, and on at least one of the signals no `<BaseUnit>` element is defined, then the connection equation "v2 = v1" holds (if v1 is an `output` of an FMU and v2 is an `input` of another FMU, with `fmi3Get{VariableType}` the value of v1 is inquired and used as value for v2 by calling `fmi3Set{VariableType}`).

When two signals v1 and v2 are connected together, 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 + offset(v1) = factor(v2) * v2 + offset(v2)`

As a result, wrong connections can be detected (for example, connecting a force with an angle signal 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.

[Note that 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 signals, they might be deduced from the equations where the signals 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>`.

]

Additionally to the unit definition, optionally a set of display units can be defined that can be utilized for `input` / `output` of a value:

A `<DisplayUnit>` is defined by `name`, `factor` and `offset`. 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)]. A value with respect to Unit (abbreviated as `Unit_value`) is converted with respect to `<DisplayUnit>` (abbreviated as `DisplayUnit_value`) by the equation:

`DisplayUnit_value = factor * Unit_value + offset`

[`offset` is, for example, needed for temperature units.]

[For example, if $\color{blue}{T_K}$ is the temperature value of `Unit.name` (in `K`) and $\color{blue}{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:

``````<Unit name="rad/s">
<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="Re">
<BaseUnit/> <!-- unit="1" -->
<!-- (dimensionless, all exponents of BaseUnit are zero) -->
</Unit>
<Unit name="Euro/PersonYear"/>  <!-- no mapping to BaseUnit defined -->``````

]

The schema definition is present in a separate file `fmi3Unit.xsd`.

#### 2.2.4. Definition of Types (TypeDefinitions)

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

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. The following are representative examples:

These definitions are used as default values in variable elements [in order that, say, the definition of a `Torque` type does not have to be repeated over and over again]. The attributes and elements have the following meaning:

Attribute or Elements 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.

`relativeQuantity`

If this attribute is `true`, then the `offset` of `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 also comment after this table.

`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 also comment after this table.

`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.2.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 `min` and `max` can be set for variables of numeric type or `<Enumeration>`. 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 (ODE-solver, optimizers. nonlinear solvers) 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.
In debug mode checks on min/max should be performed. For maximum performance on a real-time system the 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. The environment is free to utilize this information (typically, in debug mode of the environment the min/max is checked in the cases as stated above). 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 `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 for numeric types, 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.]

Clock Type Definition

Clocks are integrated in the element `<fmiModelDescription><ModelVariables>` as a variable element with the base type `fmi3Clock`. The variable sub type `fmi3Clock` provides additional attributes for defining `clocks`.

Attribute Description

`clockType`

The type of `clocks` is defined based on the mandatory attribute `clockType`. If the properties of a `clock` adhere to synchronous clock theory it is defined with `clockType = synchronousTime`. As an additional option for FMI for Hybrid Co-Simulation and FMI for Scheduled Co-Simulation discrete parts (that do not necessarily apply to synchronous clock theory) or continuous parts of the FMU can be associated to model partitions via `clocks` whose ticks define the sampling points (i.e. communication points) for the variables of these model partitions. Clocks that are defined for such cases have `clockType = communicationPoint` and have to be ignored for Model Exchange. It is not allowed to include `clocks` of different `clockType` in one FMU. `clockType` is a required attribute.

`priority`

The `clocks` are ordered descending based on their priorities. The priority of a `clock` has to be defined via the unsigned integer attribute `priority` - smaller values have a higher priority. It is possible to define multiple `clocks` with the same priority. No ordering is defined for `clocks` of the same priority. If a computational order information is needed, different priorities have to be defined.

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

`priority` is a required attribute.

`periodic`

Clocks can be periodic or non-periodic. If a `clock` is periodic the attribute `periodic = true`.

`periodic` is an optional attribute. The default value is `false`.

`strict`

If a periodic `clock` is strictly periodic, the `strict` attribute is `true`. If the optional attribute `strict` is set to `true`, then the FMU and the simulation master have to respect the predefined interval and offset. If the optional attribute `strict` is set to `false` another interval or offset can be used, derived from the current simulation setup.

`strict` is an optional attribute. The default value is `false`. It is not allowed to set `strict` to `true` if `periodic = false`.

`intervalCounter`, `shiftCounter`, `resolution`

The interval of `output` or `input` periodic `clocks` is a rational number defined with unsignedLong valued `intervalCounter` and `resolution`

`interval = intervalCounter / resolution`.

The initial tick of periodic `clocks` may be delayed by defining a `shiftCounter` (default value 0). This results in the actual

`offset = interval * shiftCounter / resolution`.

The attributes `intervalCounter`, `shiftCounter` and `resolution` are interval `start` values for periodic `clocks` and must not be used together with non-periodic `clocks`. If `strict = true` it is required to provide values for `intervalCounter`, `shiftCounter` and `resolution`.

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

#### 2.2.5. Definition of Log Categories (`LogCategories`)

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

`<LogCategories>` defines an unordered set of category strings that can be utilized to define the log output via function `logMessage`, see Section 2.1.5. 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.

There are the following standardized names for `<Category>` and 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 environment in which the FMU is called.]

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.

`logAll`

Log all messages.

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 shall be 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.2.6. Definition of a Default Experiment (DefaultExperiment)

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

`<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`.

#### 2.2.7. Definition of Terminals (Terminals)

##### 2.2.7.1. Rationale

Terminals are fully optional and can be ignored by any importing tool.

Definition `<Terminal>`: 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

• a sequence of references to variables with connection meta data

Predefined rules for variable matching in a connection are given below. Predefined variable kinds are used to describe how the member variables have to be handled. Domain specific connection rules, terminals and their member variables can be provided by other standards.

[Co-simulation errors are not addressed by the terminals. The co-simulation algorithm has to be chosen and implemented by the importing tool. Features that might be required for specific co-simulation algorithms had to be implemented by the FMU exporting tool.

Algebraic loops in systems of connected Model Exchange FMUs are not addressed or resolved by the terminals. It is not required that the `causality` of the terminal member variables in connected terminals match.

The SSP standard refers to a `connectorKind`. This `connectorKind` is not related to the `terminalKind` or `variableKind` described in the following sections.]

##### 2.2.7.2. Terminals

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

All instances of `<Terminal>` have the type `fmi3Terminal` and are listed in the `<Terminals>` sequence:

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. There are three predefined matching rules: plug, bus, and sequence. Other standards may define new matching rules. [It is recommended that vendor specific rules start with `_vendorName` or `_toolName` to avoid namespace clashes.]

There is a sequence of terminal member variables, terminal stream member variables, and nested terminals in the `<Terminal>` element. The member variables are the exchanged variables. The type of the nested terminals is `fmi3Terminal`, and they can be used to implement structured terminals.

`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.

[Other terminal kinds should refer to the predefined `matchingRule`. 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.2.7.3. Terminal Member Variable

The `<TerminalMemberVariable>` is defined as:

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 normalized string `memberName` is the representation in tools which apply name-based matching in connections. The member name has to be unique in a terminal.

The normalized string `variableName` is used to identify the terminal member variable in the list of `<ModelVariables>`. [The `name` attribute of the model variable is equal to the `variableName` of the `<TerminalMemberVariable>`. An importing tool may use the `variableName` attribute to identify a specific alias to get additional information, such as minimum, maximum, and nominal values.]

One variable can be part of several terminals.

[Tools which apply sequence based matching should also provide unique member names, so that all importing tools which use name based matching use the same member names.

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.]

The predefined variable kinds are:

`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]

##### 2.2.7.4. 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.2.7.5. 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 together 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 single signals of the same flow type requires a negation of the signal.]

##### 2.2.7.6. Terminal Stream Member Variable

The `<TerminalStreamMemberVariable>` is defined as:

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_{\textit{i, outStream}} &\textit{if \dot{m} is outflowing through terminal i}\\ q_{\textit{i, inStream}} &\textit{if \dot{m} is inflowing through terminal i} \end{array}\right.$

The $q_\textit{i, outStream}$ is the convective quantity in case the matter flows out of the FMU. $q_\textit{i, 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.2.8. Definition of a Graphical Representation (GraphicalRepresentation)

##### 2.2.8.1. Rationale

The graphical representation of the FMU and terminals are needed in order to more easily comprehend the meaning of connected FMUs and to help an importing tool 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 three optional elements in the `<GraphicalRepresentation>`:

1. The `<CoordinateSystem>` defines the extent of the whole icon (graphical items may exceed that rectangle).

2. The `<Icon>` defines an image source for the FMU.

3. The `<Terminal>` sequence contains the graphical representation of the visible terminals.

##### 2.2.8.2. CoordinateSystem

The `<CoordinateSystem>` element and its defined 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 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 print out 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 suggested to be used as "clickable icon size" in other tools. A `<Terminal>` might be placed outside of this area, so 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.2.8.3. Icon

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 `icon/icon.png` in ZIP archive of the FMU. The terminals should not be visible in the image. Optionally an SVG file can be provided if also the PNG file is present. This enables high quality rendering and printing in importing tools. This SVG file has to be placed at the path `icon/icon.svg` in the ZIP archive.

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.2.8.4. Terminals

For `fmi3Terminals` (terminals which are listed in the `<Terminals>` element) the name of the terminal in the `<GraphicalRepresentation>` is equal to the name of the terminal in the `<Terminals>` element (e.g. `port_a`). Only `Terminal` elements which are direct children of the `Terminals` element can have a graphical representation. [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>`. The name of the `<Terminal>` and the name of the `<TerminalMemberVariable>` should be equal to the name of the `input` / `output`.]

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 `icon` folder in the FMU ZIP archive. Implementations are only 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 icon folder of the FMU ZIP Archive after dot removal from the path as per section 5.2.4 of RFC 3986.]

The default connection stroke size and color 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`.

The `<VendorAnnotations>` 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 tool name `Modelica3Annotation` in the attribute `annotation` of an element `connector`. The attribute `name` of the connector element is equal to the `name` attribute of the referenced `fmi3Terminal`.]

[Only terminals from the `<Terminals>` element can have a graphical representation. For simple `inputs` / `outputs` a terminal with one member has to be added.]

##### 2.2.8.5. 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 `<GraphicalRepresentation>` 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.2.9. Definition of Vendor Annotations (VendorAnnotations)

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

`<VendorAnnotations>` consist of an ordered set of annotations that are identified by the name of the tool that can interpret the `any` element. The `any` element can be an arbitrary XML data structure defined by the tool. The attribute `name` must be unique with respect to all other elements of the `<VendorAnnotations>` list.

#### 2.2.10. Definition of Model Variables (ModelVariables)

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:

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

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 an `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. 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.

It is not possible to use a variable of type `<Clock>` in arrays, since array elements do not have individual `valueReference` and the access to `clocks` requires a unique `valueReference` information.

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>``````

The attributes of variables are:

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:

• `input`: The variable value can be provided from another model or slave. It is not allowed to define `initial`.

• `output`: The variable value can be used by another model or slave. The algebraic relationship to the `inputs` is defined via the `dependencies` attribute of `<fmiModelDescription><ModelStructure><Output>`.

• `local`: Local variable that is calculated from other variables or is a continuous-time `state` or an event indicator (see Section 2.2.11). It is not allowed to use the variable value in another model or slave.

[ Example:

``````<Variable name="spD" valueReference="126" causality="structuralParameter" variability="fixed">
<Integer start="3"/>
</Variable>``````

]

`structural parameters` that are referenced in `<Dimension>` elements may have a `min` attribute with 0 but the `start` attribute, which is mandatory for `structural parameters`, must have a value larger than 0 for `structural parameters` used in `<Dimension>` elements. [This allows importing tools to ignore `structural parameters` because that `start` value reflects the internal default setting of that `structural parameter`].

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

[`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 slave, 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.]

`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 (xCS) 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.

• `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 (also inside the slave).

• `continuous`: Only a variable of `type = fmi3GetFloat32` or `type = fmi3GetFloat64` can be `continuous`.
Model Exchange: No restrictions on value changes.
Co-Simulation: By convention, the variable is from a differential

• `clock`: Only a variable of type `<Clock>` can have this variability.

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

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

`initial`

Enumeration that defines how the variable is initialized. It is not allowed to provide a value for `initial` if `causality` = `input` or `independent`:

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

• = `approx`: The variable is an iteration variable of an algebraic loop and the iteration at initialization starts with the `start` value.

• = `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: (a) automatic tests of FMUs are performed, and the FMU is tested by providing the `start` value as `constant` `input`. (b) 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 `causality` = `input` the value for `initial` has to be set to `exact` and it is required to provide a `start` value for describing the expected initial contidion of master `clocks` for that FMU. If an `input clock` has `fmi3True` as an `start` value the master should activate the `clock` the first time it enters Event Mode. The master can nevertheless choose different `start` values if it is not possible to fulfill the conditions in a simulation setup.

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`.

`canHandleMultipleSetPerTimeInstant`

Only for Model Exchange (if only a Co-Simulation FMU, this attribute must not be present. If both Model Exchange and Co-Simulation FMU, this attribute is ignored for co-simulation):
Only for variables with `variability` = `input` :
If present with value equals `false`, then only one `fmi3Set{VariableType}` call is allowed at one super-dense time instant (model evaluation) on this variable. That is, this `input` is not allowed to appear in a (real) algebraic loop requiring multiple calls of `fmi3Set{VariableType}` on this variable [for example, due to a Newton iteration].
[This flag must be set by FMUs where (internal) discrete-time `states` are directly updated when assigned (xd := f(xd) instead of xd = f(previous(xd)), and at least one `output` depends on this `input` and on discrete `states`.
It is strongly recommended that such an FMU checks the fulfillment of the requirement by itself during run-time, because an environment might not be able to check it; usually, there is a generic mechanism to import an FMU in an environment, but the mechanism to connect FMUs together is unrelated to the import mechanism. For example, there is no mechanism in the Modelica language to formulate connection restrictions for C functions (the FMU) called in a Modelica model.]

`clockReference`

The optional attribute `clockReference` is used to define the `clocks` this variable is assigned to. This attribute can be used in all variable sub types with restrictions based on the `clockType` attribute. The `clockReference` holds only `valueReference` information for variables with base type `fmi3Clock`.

Clock (`clockType = STClock`): If present, the variable is a clocked variable associated uniquely with the `clock` referenced by `valueReference` and defined in element `<ModelVariables>`. It is not possible to associate more than one `clock` to a variable.

Communication Point Clock (`clockType = communicationPoint`): If present, the variable is associated with the `clock` referenced by `valueReference` and defined in element `<ModelVariables>`. It is possible to associate multiple `clocks` to a variable. Variables that are assigned to a Communication Point Clock are not necessarily `clocked` in the sense of synchronous time clock theory. Such variables can also be continuous-time or discrete-time variables.

If `output clocks` and `input clocks` of `clockType = communicationPoint` are defined in the `modelDescription.xml` it is possible to define a tick relationship from a `output clock` to an aperiodic `input clock` based on `clockReference` (Section 2.1.8.3.3). This is done for aperiodic `input clocks` that have the `clockType = communicationPoint` via providing a list of `valueReference` of `output clocks` of the same FMU. If a `output clock` of this `valueReference` list ticks the master has to create a tick for the associated aperiodic `input clock` at the same time instant. It is not allowed to combine `output clocks` with periodic or strict periodic `input clocks` based on `clockReference`.

The attribute `clockReference` must not be used if `causality` = `output` for a variable.

`intermediateAccess`

If this boolean attribute is `true`, the variable can be accessed during a communication step. Variables with `causality` `parameter` must not be marked with `intermediateAccess` = `true`. This attribute is only used for Basic Co-Simulation and Hybrid Co-Simulation. The default value of this attribute is `false`.

fmi3Set{VariableType} can be called on any variable with `variability` $\neq$ `constant` before initialization (before calling `fmi3EnterInitializationMode`)

fmi3Set{VariableType} can be called on any variable with `variability` $\neq$ `constant` during initialization (after calling `fmi3EnterInitializationMode` and before `fmi3ExitInitializationMode` is called)

fmi3Set{VariableType} can be called on any variable for Model Exchange at an event instant (after calling `fmi3EnterEventMode` and before `fmi3EnterContinuousTimeMode` is called), and for Co-Simulation at every communication point,

fmi3Set{VariableType} can be called on any variable for Model Exchange in Continuous-Time Mode

If `initial` is not present, its value is defined by the following tables based on the values of `causality` and `variability`:

 `causality` structual `parameter` `parameter` `calculatedParameter` `input` `output` `local` `independent` `input` `output` `variability` data `constant` (A) or -- -- -- -- (A) (A) -- -- -- `fixed` (A) (A) (B) -- -- (B) -- -- -- `tunable` (A) (A) (B) -- -- (B) -- -- -- signals `discrete` -- -- -- (D) (C) (C) -- -- -- `continuous` -- -- -- (D) (C) (C) (E) -- -- `clocks` `clock` -- -- -- -- -- -- -- (F) (G)

with

 `initial` default possible values (A) exact exact (B) calculated approx, calculated (C) `calculated` (D) --- --- (E) --- --- (F) exact exact (G) calculated calculated

[Note: (1) If `causality` = `independent`, it is neither allowed to define a value for `initial` nor a value for start. (2) If `causality` = `input`, it is not allowed to define a value for `initial` and a value for `start` must be defined. (3) If (C) and `initial` = `exact`, then the variable is explicitly defined by its `start` value in Initialization Mode (so directly after calling `fmi3ExitInitializationMode`, the value of the variable is either the `start` value stored in a variable element `<XXX start=YYY/>` or the value provided by `fmi3Set{VariableType}`, if this function was called on this variable).]

The following combinations of `variability`/`causality` settings are allowed:

 `causality` `structuralParameter` `parameter` `calculatedParameter` `input` `output` `local` `independent` `input` `output` `variability` data `constant` -- -- (a) -- (a) -- (a) (7) (10) -- (c) -- -- `fixed` (16) (1) (3) -- (d) -- (e) (11) -- (c) -- -- `tunable` (17) (2) (4) -- (d) -- (e) (12) -- (c) -- -- signals `discrete` -- (b) -- (b) -- (b) (5) (8) (13) --(c) -- -- `continuous` -- (b) -- (b) -- (b) (6) (9) (14) (15) -- -- clocks `clock` -- -- -- -- -- -- -- 18 18

[Discussion of the combinations that are not allowed:

 Explanation why this combination is not allowed (a) The combinations `constant` / `parameter`, `constant` / `calculatedParameter` and `constant` / `input` do not make sense, since `parameters` and `inputs` are set from the environment, whereas a constant has always a 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 `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:

Setting Example

(1)

`fixed` `parameter`

Non-`tunable` `independent` `parameter`

(2)

`tunable` `parameter`

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

(3)

`fixed` `dependent` `parameter`

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

(4)

`tunable` `dependent` `parameter`

`Tunable` `dependent` `parameter` (changing an `independent` `parameter` triggers an external event (ME) or takes effect at the next communication point (xCS), and `tunable` `dependent` `parameters` 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`

`Continous` 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` structual `parameter`

`Paramter` used in `<Dimension>` element; can be changed before initialization in *Configuration Mode*

(17)

`tunable` structual `parameter`

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

(18)

`clock`

Variable that defines a `clock`

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 Basic Co-Simulation and FMI for Hybrid 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.]

Type specific properties are defined in the required choice element, where exactly one of the numeric types or an `<Enumeration>` must be present in the XML file: The following are representative examples:

The attributes are defined in Section 2.2.4 (`<TypeDefinitions>`), except:

Attribute Description

`declaredType`

If present, name of type defined with `<TypeDefinitions><TypeDefinition>`. The value defined in the corresponding `<TypeDefinition>` (see Section 2.2.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 numeric types and `<String>`, this attribute is optional. For `<Enumeration>` it is required, because the `<Enumeration>` items are defined in `<TypeDefinitions><TypeDefinition>`.

`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 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 $\color{blue}{\dot{x} = 0}$ , the actual `start` value is determined.]

`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 `<ModelStructure><Derivative>`. 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.

`min / max`

The optional attributes `min` and `max` in element `<Enumeration>` restrict the allowed values of the enumeration. The `min/max` definitions are information from the FMU to the environment defining the region in which the FMU is designed to operate, see also comment in Section 2.2.4. [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.]

With element `<Annotations>` additional, tool specific data can be defined:

With the attribute `name` of `<Tool>` the name of the tool is defined that can interpret the `any` element. The `any` element can be an arbitrary XML data structure defined by the tool. [Typically, additional data is defined here how to build up the menu for the variable, including the graphical layout and enabling/disabling an input field based on the values of other `parameters`.] The attribute `name` must be unique with respect to all other elements of the `<Annotations>` list.

#### 2.2.11. Definition of the Model Structure (ModelStructure)

The structure of the model is defined in element `<fmiModelDescription><ModelStructure>`. This structure is with respect to the underlying model equations, independently how these model equations are solved. [For example, when exporting a model in more than one FMI format; then the model structure is identical in all cases. E.g. a Basic Co-Simulation FMU has either an integrator included that solves the model equations, or the discretization formula of the integrator and the model equations are solved together ("inline integration"). In all cases the model has the same continuous-time `states`. In the case of a Model-Exchange FMU, the internal implementation is a discrete-time system, but from the outside this is still a continuous-time model that is solved with an integration method.]

The required part defines an ordering of the `outputs`, the (exposed) `derivatives`, the event indicators and defines the unknowns that are available during Initialization [Therefore, when linearizing an FMU, every tool will use the same ordering for the `outputs`, `states`, and `derivatives` for the linearized model. The ordering of the `inputs` should be performed in this case according to the ordering in `<ModelVariables>`.] A Model Exchange FMU must expose all `derivatives` of its continuous-time `states` in elements `<ModelStructure><Derivative>` and must expose all event indicators in elements `<EventIndicator>`. A Co- Simulation FMU does not need to expose these state derivatives and event indicators. [If a Basic Co-Simulation FMU exposes its state derivatives, they are usually not utilized for the co-simulation, but, for example, to linearize the FMU at a communication point.]

The optional part defines in which way `derivatives`, `outputs` and unitial unknowns depend on `inputs`, and continuous-time `states` at the current super-dense time instant (ME) or at the current communication point (xCS). [The listed `dependencies` declare the dependencies between whole (multi-dimensional-)variables and not individual elements of the variables.] [A simulation environment can utilize this information to improve the efficiency, for example, when connecting FMUs together, or when computing the partial derivative of the `derivatives` with respect to the `states` in the simulation engine.]

`<ModelStructure>` has the following definition:

Note that attribute `dependenciesKind` for element `<InitialUnknown>` has less enumeration values as `dependenciesKind` in the other lists, see below.

`<ModelStructure>` consists of the following elements (see also figures above; the symbols of the mathematical equations describing the dependency are defined in Section 3.1):

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 (xCS). Beside the knowns the `outputs` also depend on the freeze variables (= variables which cannot be changed in the current mode) but these freeze 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):
$\color{blue}{(\mathbf{y}_c, \mathbf{y}_d) := \mathbf{f}_{output}(\mathbf{x}_c, \mathbf{u}_c, \mathbf{u}_d, t, \mathbf{p}_{tune})}$

`Derivative`

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 `<ModelStructure><Derivative>` 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 $\color{blue}{\frac{\text{ds}}{\text{dt}} = v,\ \frac{\text{dv}}{\text{dt}} =f(..)}$ ,then $\color{blue}{\left\{ v,\ \frac{\text{dv}}{\text{dt}} \right\}}$ is the vector of state derivatives and attribute `derivative` of $\color{blue}{v}$ references $\color{blue}{s}$ , and attribute `derivative` of $\color{blue}{\frac{\text{dv}}{\text{dt}}}$ references $\color{blue}{v}$ .]
For Co-Simulation, elements `<Derivative>` are ignored if capability flag `providesDirectionalDerivative` 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 `<Derivative>` 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 `<Derivative>` elements are ignored for Co-Simulation. If "inline integration" is used for a co-simulation slave, 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 (xCS). Beside the knowns the derivatives also depend on the freeze variables (= variables which cannot be changed in the current mode) but these freeze 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):
$\color{blue}{\dot{\mathbf{x}_c} := \mathbf{f}_{der}(\mathbf{x}_c, \mathbf{u}_c, \mathbf{u}_d, t, \mathbf{p}_{tune})}$

`InitialUnknown`

Ordered list of all exposed unknowns in Initialization Mode. This list consists of all variables with

1. all continuous-time `states` and all state derivatives (defined with elements `<ModelStructure><Derivative>`) with `initial` = `approx` or `calculated` [if a Basic Co-Simulation FMU does not define the `<ModelStructure><Derivative>` elements, (3) cannot be present].

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 freeze variables (= variables which cannot be changed in the current mode) but these freeze variables are not listed as `dependencies`. The functional dependency is defined as:

$\color{blue}{\mathbf{v}_{initialUnknowns} := \mathbf{f}_{init}(\mathbf{u}_c, \mathbf{u}_d, t_0, \mathbf{v}_{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.

[Example: Assume an FMU is defined in the following way:

$\color{blue}{(\mathbf{y}_{c+d}, \dot{\mathbf{x}}_c) := \mathbf{f}_{init}(\mathbf{x}_c, \mathbf{u}_{c+d}, t_0, \mathbf{p})}$

$\color{blue}{(\mathbf{y}_{c+d}, \dot{\mathbf{x}}_c) := \mathbf{f}_{sim}(\mathbf{x}_c, \mathbf{u}_{c+d}, t_i, \mathbf{p})}$

Therefore, the initial state $\color{blue}{\mathbf{x}_c(t_0)}$ has `initial` = `exact` and the initial state derivative $\color{blue}{\dot{\mathbf{x}}_c(t_0)}$ has `initial` = `calculated`. The environment can still initialize this FMU in steady-state, by using $\color{blue}{\mathbf{x}_c(t_0)}$ as iteration variables and adding the equations $\color{blue}{\dot{\mathbf{x}}_c(t_0) = \mathbf{0}}$ in the environment.]

`EventIndicator`

Elements `<Output>`, `<Derivative>` and `<InitialUnknown>` have the following attributes:

Attribute Description

`valueReference`

The value reference of the unknown $\color{blue}{v_{\text{unknown}}}$.

`dependencies`

Optional attribute defining the dependencies of the unknown $\color{blue}{v_{\text{unknown}}}$ (directly or indirectly via auxiliary variables) with respect to $\color{blue}{\mathbf{v}_{\text{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 $\color{blue}{\mathbf{v}_{\text{known}}}$ in Event Mode and Continuous-Time Mode (ME) and at communication points (xCS) for `<Output>` and `<Derivative>` elements:

- inputs (variables with `causality` = `input`)

- continuous-time states

- `independent` variable (usually time; `causality` = `independent`). If an `independent` variable is not explicitly defined under variables, it is assumed that the unknown depends explicitly on the `independent` variable.

[`parameters` and `tunable` `parameters` must not be listed as knowns in this mode. This may change in a future FMI version which implies the possibility to calculate derivatives with respect to parameters.]

`Knowns` $\color{blue}{\mathbf{v}_{\text{known}}}$ in Initialization Mode (for elements `<InitialUnknown>`):

- inputs (variables with `causality` = `input`)

- variables with `initial` = `exact` [for example, `independent` `parameters` or initial `states`]

- `independent` variable (usually time; `causality` = `independent`). If an `independent` variable is not explicitly defined under variables, it is assumed that the unknown depends explicitly on the `independent` variable.

For Co-Simulation, `dependencies` does not list the dependency on continuous-time, if the capability flag `providesDirectionalDerivative` has a value of `false`. 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 $\color{blue}{v_{\text{unknown}}}$ depends on the knowns $\color{blue}{\mathbf{v}_{\text{known}}}$ without a particular structure. Otherwise, the corresponding known $\color{blue}{v_{known,i}}$ enters the equation as:

`= dependent`: no particular structure, $\color{blue}{{h(..,\ v}_{known,i}}$,..)

Only for floating point type unknowns $\color{blue}{v_{\text{unknown}}}$:

`=` `constant`: constant factor, $\color{blue}{c \cdot v_{known,i}}$ where $\color{blue}{c}$ is an expression that is evaluated before `fmi3EnterInitializationMode` is called.

Only for floating point type unknowns $\color{blue}{v_{\text{unknown}}}$ in Event and Continuous-Time Mode (ME) and at communication points (xCS), and not for `<InitialUnknown>` for Initialization Mode:

`=` `fixed`: fixed factor, $\color{blue}{p \cdot v_{known,i}}$ where $\color{blue}{p}$ is an expression that is evaluated before `fmi3ExitInitializationMode` is called.

`=` `tunable`: tunable factor, $\color{blue}{p \cdot v_{known,i}}$ where $\color{blue}{p}$ is an expression that is evaluated before `fmi3ExitInitializationMode` is called and in Event Mode due to an external event (ME) or at a communication point (xCS)

`=` `discrete`: discrete factor, $\color{blue}{d \cdot v_{known,i}}$ where $\color{blue}{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 (xCS).

[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 $\color{blue}{u_{1}}$ is a continuous-time `input` (`variability` = `continuous`), $\color{blue}{u_{2}}$ is any type of `input`, $\color{blue}{u_{3}}$ is a floating point discrete-time `input` (`variability` = "discrete"`), and $\color{blue}{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"/>
<Float64 name="der(x2)" valueReference= "9"/>
<Float64 name="der(x3)" valueReference="10"/>
<Float64 name="y"       valueReference="11"/>
</ModelVariables>
<ModelStructure>
<Output valueReference="11" dependencies="6 7"/>
<Derivative valueReference="8"  dependencies="6"/>
<Derivative valueReference="9"  dependencies="2 4 5 6" dependenciesKind="constant constant dependent fixed"/>
<Derivative 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"/>
</ModelStructure>``````

Example 2:

$y = \left\{ \begin{matrix} 2 \cdot u \ \mathrm{if} \ u > 0 \\ 3 \cdot u \ \mathrm{else} \\ \end{matrix}\right.$

where $\color{blue}{u}$ is a continuous-time `input` with `valueReference` = `1` and $\color{blue}{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"/>
</ModelStructure>``````

[Note that $\color{blue}{y = d \cdot u}$ where $\color{blue}{d}$ changes only during Event Mode ( $\color{blue}{d = 2 \cdot u}$ or $\color{blue}{3 \cdot u\ }$ depending on relation $\color{blue}{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 $\color{blue}{u}$ is a continuous-time `input` with `valueReference` = `1` and $\color{blue}{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"/>
</ModelStructure>``````

[Note that $\color{blue}{y = c}$ where $\color{blue}{c}$ changes only during Event Mode ( $\color{blue}{c = 2}$ or $\color{blue}{3\ }$ depending on relation $\color{blue}{u > 0}$ that changes only at Event Mode). Therefore `dependenciesKind` = `dependent` because it is not a linear relationship on $\color{blue}{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"/>
<Float64 name="x" valueReference= "3"/>
<Float64 name="dxdt" valueReference= "4"/>
</ModelVariables>
<ModelStructure>
<Output valueReference="2" dependencies="3" dependenciesKind="constant"/>
<Derivative valueReference="4" dependencies="1" dependenciesKind="constant"/>
<InitialUnknown valueReference="2" dependencies="3"/>
<InitialUnknown valueReference="4" dependencies="1"/>
</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.2.12. Variable Naming Conventions (variableNamingConvention)

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:

`variableNamingConvention = flat`

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

`variableNamingConvention` = structured`

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 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. ### 2.3. FMU Distribution An FMU description consists of several files. An FMU implementation may be distributed in source code and/or in binary format. All relevant files are stored in a ZIP file with a pre-defined structure. The implementation must implement all the functions for at least one of the FMI interface types. Specifically it is required that all functions specified for the specified FMI interface type are present, even if they are only needed for 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 used for the ZIP file must be `deflate` [(most free tools, such as zlib, offer only the common compression method `deflate`)]. [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. This ZIP file has the following structure: ```// 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 // image file of a descriptive diagram view of the model (optional) diagram.svg // if existing the diagram.png is required (optional) <other documentation files> licenses // Optional directory for licenses license.{txt,html} // Entry point for license information <license files> // For example BSD licenses icon // FMU and terminal 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) // all needed C sources and C header files to compile and link the FMU // with exception of: fmi3PlatformTypes.h, fmi3FunctionTypes.h and fmi3Functions.h // The files to be compiled (but not the files included from these files) // have to be reported in the XML file under the structure // <ModelExchange><BuildConfiguration><SourceFileSet><SourceFile>... 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 with <modelIdentifier>.lib // 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 // If an FMU is run through one of its binaries all items in that binary // folder are recommended to be unpacked at the same location as the binary // < modelIdentifier >.* is unpacked. If not it is likely that, if the FMU // has dependencies on those items, it will not be able to find them. resources // resources needed by the FMU // data in FMU specific files which will be read during initialization; // also more folders can be added under resources (tool/model specific). // In order for the FMU to access these resource files, the resource directory // must be available in unzipped form and the absolute path to this directory // must be reported via argument "resourceLocation" via fmi3InstantiateXXX. extra // Additional (meta-)data of the FMU (optional) // additional (meta-)data that is supposed to travel with the FMU; // see below for structure and content definition.``` An FMU has to implement all common functions (according to tables in Section 3.2.3 and Section 4.2.4). Additionally, all FMUs have to provide the respective FMU interface-type function they implement. 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 names of the binary directories are standardized by the "platform tuple". Further names can be introduced by vendors. Dynamic link libraries must include all referenced resources that are not available on a standard target machine [for example, DLLs on Windows that are built with Visual Studio should be compiled with the `/MT` option to include the required symbols from the Visual C runtime in the DLL, and not use the option `/MD` where this is not the case]. When compiling a shared object on Linux, `RPATH="$ORIGIN"` has to be set when generating the shared object in order that shared objects used from it, can be dynamically loaded.

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.0)

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 target simulator is running and for which licenses of run-time libraries are available) or to provide only sources (for example, for translation and download for a particular micro-processor). If run-time libraries cannot be shipped due to licensing, special handling is needed, for example, by providing the run-time libraries at appropriate places by the receiver.

FMI provides the means for two kinds of implementation: `needsExecutionTool = true` and `needsExecutionTool = false`. In the first case a tool specific wrapper DLL/SharedObject has to be provided as the binary, in the second a compiled or source code version of the model with its solver is stored (see Section 4 for details).

In an FMU multiple interface types might be present. If in both cases the executable part is provided as a shared library, then two different or only one library can be provided. The library names are defined in the `modelIdentifier` attribute of elements `<fmiModelDescription><ModelExchange|{Basic|Hybrid|Scheduled}CoSimulation>`:

```[Example of different libraries:
binaries
x86_64-windows
MyModel_ModelExchange.dll   // modelIdentifier of <ModelExchange> =
//    "MyModel_ModelExchange"
MyModel_CoSimulation.dll    // modelIdentifier of <CoSimulation> =
//    "MyModel_CoSimulation"
]```

The usual distribution of an FMU will be with DLLs/SharedObjects because then further automatic processing [(for example, importing into another tool)] is possible.
If run-time libraries are needed by the FMU that have to be present on the target machine, then automatic processing is likely impossible. The requirements and the expected processing should be documented in the `documentation` directory in this case.
A source-based distribution might require manual interaction in order that it can be utilized. The intention is to support platforms that are not known in advance (such as HIL-platforms or micro-controllers). Typically, in such a case the complete source code in ANSI-C is provided (for example, one C source file that includes all other needed C files with the `#include` directive). All C source file names that need to be defined in a compiler directive have to be defined in the XML file under structure `<ModelExchange><BuildConfiguration><SourceFileSet><SourceFile>`.

These files may include other files. `#include` directive with `""` should be used for header-filers distributed in the FMU instead of using `<…​>`. If default options of the compiler are sufficient, it might then be possible to automatically process such source code FMUs. In case information beyond `<BuildConfiguration>` is required to compile the FMU for specific targets, the `documentation` directory is the place to store further instructions. [As template makefile, CMake (http://www.cmake.org), a cross-platform, open-source build system might be used.]
[The sub-directory "licenses" can be used to bundle all license files. 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.]

In the mandatory directory `resources`, additional data can be provided in FMU specific formats, typically for tables and maps used in the FMU. This 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 parameters via the `fmi3SetString` function. [Note that the absolute file name of the resource directory is provided by the initialization functions.] In the case of a Basic Co-Simulation implementation of `needsExecutionTool = true` type, the `resources` directory can contain the model file in the tool specific file format.

[Note that the header files `fmi3PlatformTypes.h` and `fmi3FunctionTypes.h/fmi3Functions.h` are not included in the FMU due to the following reasons:

`fmi3PlatformTypes.h` makes no sense in the `sources` directory, because if sources are provided, then the target simulator 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 target simulator 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 target simulator executable. 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`.]

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 the extra files should be provided in subdirectories using a reverse domain name 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 seperate checksums or signatures for FMU core content and extra content, or not having signatures at all for extra content)].

### 2.4. Common Concepts for Co-Simulation

Co-simulation exploits the modular structure of coupled problems in all stages of the simulation process beginning with the separate model setup and preprocessing for the individual subsystems in different simulation tools (which can be powerful simulators as well as simple C programs). During time integration, the simulation is again performed independently for all subsystems restricting the data exchange between subsystems to discrete communication points $tc_i$. For simulator coupling, also the visualization and post-processing of simulation data is done individually for each subsystem in its own native simulation tool. In different contexts, the communication points $tc_i$, the communication steps $tc_i \rightarrow tc_{i+1}$ and the communication step sizes $hc_i := tc_{i+1} - tc_i$ are also known as sampling points (synchronization points), macro steps and sampling rates, respectively. The term "communication point" in FMI for Co-Simulation refers to the communication between subsystems in a co-simulation environment and should not be mixed with the output points for saving simulation results to file.

FMI for Co-Simulation provides 3 interface standards for the solution of time-dependent coupled systems consisting of subsystems that are continuous in time (model components that are described by non-stationary differential equations) or time-discrete (model components that are described by difference equations such as discrete controllers). In a block representation of the coupled system, the subsystems are represented by blocks with (internal) `state` variables $x(t)$ that are connected to other subsystems (blocks) of the coupled problem by subsystem `inputs` $u(t)$ and subsystem `outputs` $y(t)$. In this framework, the physical connections between subsystems are represented by mathematical coupling conditions between the inputs $u(t)$ and the `outputs` $y(t)$ of all subsystems, [KS00].

Figure 2. Data flow at communication points.

For co-simulation, two basic groups of functions have to be implemented:

1. functions for the data exchange between subsystems

2. functions for algorithmic issues to synchronize the simulation of all subsystems and to proceed in communication steps $tc_i \rightarrow tc_{i+1}$ from initial time $tc_0 := t_{start}$ to end time $tc_N := t_{stop}$

In FMI for Co-Simulation, both functions are implemented in one software component, the Co-Simulation master. The data exchange between the subsystems (slaves) is handled via the master only. There is no direct communication between the slaves. The master functionality can be implemented by a special software tool (a separate simulation backplane) or by one of the involved simulation tools. In its most general form, the coupled system may be simulated in nested co-simulation environments and FMI for Co-Simulation applies to each level of the hierarchy.

FMI for Co-Simulation defines interface routines for the communication between the master and all slaves (subsystems) in a co-simulation environment. The most common master algorithm stops at each communication point $tc_i$ the simulation (time integration) of all slaves, collects the outputs $y(tc_i)$ from all subsystems, evaluates the subsystem inputs $u(tc_i)$, distributes these subsystem inputs to the slaves and continues the (co-)simulation with the next communication step $tc_i \rightarrow tc_{i+1} = tc_i + hc$ with fixed communication step size $hc$. In each slave, an appropriate solver is used to integrate one of the subsystems for a given communication step $tc_i \rightarrow tc_{i+1}$. The most simple co-simulation algorithms approximate the (unknown) subsystem inputs $u(t), (t > tc_i))$ by frozen data $u(tc_i)$ for $tc_i \leq t < tc_{i+1}$. FMI for Co-Simulation supports this classical brute force approach as well as more sophisticated master algorithms. FMI for Co-Simulation is designed to support a very general class of master algorithms but it does not define the master algorithm itself.

The ability of slaves to support more sophisticated master algorithms is characterized by a set of capability flags inside the XML description of the slave (see Section 4). Typical examples are:

• the ability to handle variable communication step sizes $hc_i$,

• the ability to repeat a rejected communication step $tc_i \rightarrow tc_{i+1}$ with reduced communication step size,

• the ability to provide `derivatives` w.r.t. time of `outputs` to allow interpolation (Section 4.2.1),

• or the ability to provide Jacobians.

FMI for Co-Simulation is restricted to slaves with the following properties:

1. All calculated values are time-dependent functions within an a priori defined time interval $t_{start} \leq t \leq t_{stop}$ (provided `stopTimeDefined = fmi3True` when calling `fmi3SetupExperiment`).

2. All calculations (simulations) are carried out with increasing time in general. The current time $t$ is running step by step from $t_{start}$ to $t_{stop}$. The algorithm of the slave may have the property to be able to repeat the simulation of parts of $[t_{start}, t_{stop}$] or the whole time interval $[t_{start}, t_{stop}$].

3. The slave can be given a time value $tc_i, t_{start} \leq tc_i \leq t_{stop}$.

4. The slave is able to interrupt the simulation when $tc_i$ is reached.

5. During the interrupted simulation the slave (and its individual solver) can receive values for `inputs` $u(tc_i)$ and send values of outputs $y(tc_i)$.

6. Whenever the simulation in a slave is interrupted, a new time value $tc_{i+1}, tc_i \leq tc_{i+1} \leq t_{stop}$, can be given to simulate the time subinterval $tc_i < t \leq tc_{i+1}$

7. The subinterval length $hc_i$ is the communication step size of the $i^{th}$ communication step, $hc_i = tc_{i+1} - tc_i$.

The communication step size has to be greater than zero.

FMI for Co-Simulation allows a Co-Simulation flow which starts with instantiation and initialization (all slaves are prepared for computation, the communication links are established), followed by simulation (the slaves are forced to simulate a communication step), and finishes with shutdown. The details of the flow are given in the state machine of the calling sequences from master to slave (see Section 4.2.4).

#### 2.4.1. Intermediate Variable Access Support

Intermediate variable access has three main uses:

1. An FMU is able to produce valid output variables at intermediate points between two consecutive communication points. This is typically the result of an internal solver taking multiple integration steps between two consecutive communication points. The FMU exposes intermediate output variables for the master whenever they are available. These can be used for e.g. extrapolation, interpolation, filtering or asynchronous co-simulation.

2. Intermediate `input` variables for an FMU is available in the Co-Simulation master. The FMU requests updated intermediate `input` variables every time they are required by the internal solver. This can be either at temporary solver states or after successful integration steps.

3. Intermediate `input` variables for the FMU can be computed by the Co-Simulation master. The computation requires intermediate output variables from the FMU. Whenever the internal solver in the FMU needs updated intermediate `input` variables, it provides the intermediate output variables for and requests the intermediate `input` variables from the master.

Combinations of the above methods are also allowed.

• Asynchronous communication

• Anti-alias filtering

• Smoothing of inputs

#### 2.4.2. Overview of Different Co-Simulation Interfaces

In FMI version 3.0 the following new features have been added:

• signaling of `clock` ticks (i.e. events/interrupts) from the FMU to simulation environment

• signaling of `clock` ticks from simulation environment to the FMU

• definition of multiple model rates (periodic, variable/triggerable) in one FMU

• access to intermediate values of the FMU’s variables between two communication points

Please refer to the different sections for a more detailed explanation of the motivation and use of the new features.

Basic Co-Simulation

Basic Co-Simulation is a rather general approach to the simulation of coupled technical systems and coupled physical phenomena in engineering with focus on non-stationary (time-dependent) problems. The Basic Co-Simulation interface is similar to the feature set of FMI 2.0 for Co-Simulation. The asynchronous mode for FMUs has been removed since this mode was not supported by tools and it can be suitably replaced by Co-Simulation master implementations that control the asynchronous computation of FMUs via separate tasks/threads created for each FMU.

Early Return

In FMI 3.0, an FMU is allowed to stop the execution of `fmi3DoStep` and return without reaching the predefined communication instant, i.e. `currentCommunicationPoint + communicationStepSize`. This mechanism is called "early return". With the early return feature, an FMU can signal `output clock` events or internal state changes, i.e., discontinuity events to the Co-Simulation master at any time (not only at the end of `fmi3DoStep` function calls). When an internal event occurs inside the FMU at a time instant, it informs the master that a new communication point for the Co-Simulation can be created. Note that an event signal is not seen in the narrow sense of solver induced discontinuity events but in the general sense of a simulation event that has to be handled by the Co-Simulation master (e.g. state changes that require extended handling). On a multi-node architecture, in particular, significant co-simulation speed-up may be obtained if the Co-Simulation master can avoid waiting until the end of the slowest `fmi3DoStep` when many FMUs are integrating in parallel and an event occurred. To exploit such efficiency gains also the Co-Simulation master can command the FMU to return early from the current communication step. This is even helpful if the FMU or the Co-Simulation master do not support the advanced handling of events based on the Hybrid Co-Simulation functionalities. In this way multiple event types and also `output clock` ticks or interrupts can be supported based on the early return functionality and additional functionalities provided by Hybrid Co-Simulation.

Hybrid Co-Simulation

The Hybrid Co-Simulation interface provides functionalities to control and observe the ticking of clocks. For FMI for Hybrid Co-Simulation, the ticking of a clock is interpreted as an activity of the associated model partition. During simulation, the Co-Simulation master updates and manages values of inputs and outputs of FMUs and further models at communication points for each model partition. The ratio between communication points created for a model partition and time can be seen as a model rate. In that sense multiple model partitions of a model define multiple model rates in a model.

Scheduled Co-Simulation

The Hybrid Co-Simulation interface provides an indirect control over the computation of model partitions. With Scheduled Co-Simulation a simulation master can directly control the time of computation (i.e. scheduling) for such model partitions.

The Scheduled Co-Simulation interface addresses simulation use cases that require:

• That at any time (even for unpredictable events) an event can be signaled to an FMU

• If multiple FMUs share (execution) resources, 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 master

• That requires a global execution 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, if direct communication via FMUs exist.

• Get/set operations must also be possible for the same activation time for different model partitions between the computation of these model partitions.

This Co-Simulation 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 master. It is a tool vendor specific solution that has ties to the used OS and the co-simulation environment]

Intermediate Variable Access

An FMU can inform a Co-Simulation master that is able to provide intermediate output variables and/or receive intermediate input variables at any time, i.e. not only at the end of a current `fmi3DoStep` function call. It is possible for the FMU to inform the master whether the internal solver is in a temporary state or if it has just completed an internal integration step. If the internal solver is in a temporary state, intermediate output variables shall only be used for directly computing intermediate input variables. If the internal integration step is completed, the master can forward intermediate outputs to interconnected simulation units.

Coupling Scenarios
Figure 3. Co-Simulation with generated code on a single computer (for simplicity shown for one slave only).
Figure 4. Co-Simulation with tool coupling on a single computer (for simplicity shown for one slave only).

In the tool coupling case the FMU implementation wraps the FMI function calls to API calls which are provided by the simulation tool (for example, a COM or CORBA API). Additionally to the FMU the simulation tool is needed to run a co-simulation.

In its most general form, a tool coupling based co-simulation is implemented on distributed hardware with subsystems being handled by different computers with different OSs (cluster computer, computer farm, computers at different locations). The data exchange and communication between the subsystems is typically performed using one of the network communication technologies (for example, MPI, TCP/IP). The definition of this communication layer is not part of the FMI standard. However, distributed co-simulation scenarios can be implemented using FMI as shown in Figure 5.

Figure 5. Distributed co-simulation infrastructure (for simplicity shown for one slave only).

The master has to implement the communication layer. Additional parameters for establishing the network communication (for example, identification of the remote computer, port numbers, user account) are to be set via the GUI of the master. These data are not transferred via the FMI API.

For all Co-Simulation interface types intermediate variable access can be activated, if the FMU and the master supports this. More information can be found in [intermediate-variable-access].

The Co-Simulation master signals to the FMU which features shall be used for the current instance of the FMU in `fmi3InstantiateXXX`:

``````typedef fmi3Instance fmi3InstantiateModelExchangeTYPE(
fmi3String                 instanceName,
fmi3String                 instantiationToken,
fmi3String                 resourceLocation,
fmi3Boolean                visible,
fmi3Boolean                loggingOn,
fmi3InstanceEnvironment    instanceEnvironment,
fmi3CallbackLogMessage     logMessage,
fmi3CallbackAllocateMemory allocateMemory,
fmi3CallbackFreeMemory     freeMemory);

typedef fmi3Instance fmi3InstantiateBasicCoSimulationTYPE(
fmi3String                     instanceName,
fmi3String                     instantiationToken,
fmi3String                     resourceLocation,
fmi3Boolean                    visible,
fmi3Boolean                    loggingOn,
fmi3Boolean                    intermediateVariableGetRequired,
fmi3Boolean                    intermediateInternalVariableGetRequired,
fmi3Boolean                    intermediateVariableSetRequired,
fmi3InstanceEnvironment        instanceEnvironment,
fmi3CallbackLogMessage         logMessage,
fmi3CallbackAllocateMemory     allocateMemory,
fmi3CallbackFreeMemory         freeMemory,
fmi3CallbackIntermediateUpdate intermediateUpdate);

typedef fmi3Instance fmi3InstantiateHybridCoSimulationTYPE(
fmi3String                     instanceName,
fmi3String                     instantiationToken,
fmi3String                     resourceLocation,
fmi3Boolean                    visible,
fmi3Boolean                    loggingOn,
fmi3Boolean                    intermediateVariableGetRequired,
fmi3Boolean                    intermediateInternalVariableGetRequired,
fmi3Boolean                    intermediateVariableSetRequired,
fmi3InstanceEnvironment        instanceEnvironment,
fmi3CallbackLogMessage         logMessage,
fmi3CallbackAllocateMemory     allocateMemory,
fmi3CallbackFreeMemory         freeMemory,
fmi3CallbackIntermediateUpdate intermediateUpdate);

typedef fmi3Instance fmi3InstantiateScheduledCoSimulationTYPE(
fmi3String                     instanceName,
fmi3String                     instantiationToken,
fmi3String                     resourceLocation,
fmi3Boolean                    visible,
fmi3Boolean                    loggingOn,
fmi3Boolean                    intermediateVariableGetRequired,
fmi3Boolean                    intermediateInternalVariableGetRequired,
fmi3Boolean                    intermediateVariableSetRequired,
fmi3InstanceEnvironment        instanceEnvironment,
fmi3CallbackLogMessage         logMessage,
fmi3CallbackAllocateMemory     allocateMemory,
fmi3CallbackFreeMemory         freeMemory,
fmi3CallbackIntermediateUpdate intermediateUpdate,
fmi3CallbackLockPreemption     lockPreemption,
fmi3CallbackUnlockPreemption   unlockPreemption);``````

The master can only select a certain Co-Simulation interface for an FMU if the following attributes are set in the `modelDescription.xml`.

Co-Simulation interface Required attributes

Basic Co-Simulation

`canNotUseBasicCoSimulation = false`

Hybrid Co-Simulation

`providesHybridCoSimulation = true`, `canReturnEarlyAfterIntermediateUpdate = true`

Scheduled Co-Simulation

`providesScheduledCoSimulation = true`

Generally it is assumed, that a Hybrid or Scheduled Co-Simulation FMU also supports Basic Co-Simulation. If that is not possible for an FMU [(e.g. if the FMU cannot provide an emulation of `input clock` tick occurrences)], it has to include the capability flag `canNotUseBasicCoSimulation = true` in the `modelDescription.xml`.

If the FMU does not support the Co-Simulation interface selected in `fmi3InstantiateXXX` it has to return `NULL`.

Multiple Co-Simulation Interface Support in one FMU

Exporters are encouraged to support multiple Co-Simulation interfaces in one FMU, so it can be used in differently capable Co-Simulation master implementations and for different use cases. [That improves the reusability of FMUs. A common application of this multiple mode support is the reuse of FMUs for real-time and non-real-time simulations.]

The described multi mode support is based on wrapping functionality into the `fmi3DoStep` function by emulating missing features of the Co-Simulation interface, the FMU has been originally exported for.

An FMU that supports Scheduled Co-Simulation will in most cases also support Hybrid Co-Simulation.

[Wrapping towards other Co-Simulation interfaces can influence the simulation results. Depending on the model especially wrapping towards the (Basic) Co-Simulation interface may result in divergent simulation results. Especially aperiodic `input clocks` can not always be sufficiently emulated in modes that do not directly support `clocks`. Therefore it is recommended that the FMU provides logging information to the user about the influence of the current mode on simulation results, if non-optimal modes are used by the simulation environment.]

#### 2.4.3. Common Co-Simulation Application Programming Interface

##### 2.4.3.1. Intermediate Variable Access

If the Co-Simulation master signals the support for intermediate variable access and an FMU has at least one variable with `intermediateAccess` = `true`, the FMU can use the callback function `fmi3CallbackIntermediateUpdate` to communicate information back to the Co-Simulation master.

``````typedef fmi3Status (*fmi3CallbackIntermediateUpdate) (
fmi3InstanceEnvironment instanceEnvironment,
fmi3Float64 intermediateUpdateTime,
fmi3Boolean eventOccurred,
fmi3Boolean clocksTicked,
fmi3Boolean intermediateVariableSetAllowed,
fmi3Boolean intermediateVariableGetAllowed,
fmi3Boolean intermediateStepFinished,
fmi3Boolean canReturnEarly);``````

The following output arguments in `fmi3CallbackIntermediateUpdate` are used for intermediate variable access:

• `intermediateUpdateTime` is the simulation time at which the `fmi3CallbackIntermediateUpdate` callback function is called by the FMU.

• If `intermediateVariableSetAllowed = fmi3True`, the Co-Simulation master may provide intermediate `input` variables by calling `fmi3Set{VariableType}` for variables with `intermediateAccess` = `true`.

• If `intermediateVariableGetAllowed = fmi3True`, the Co-Simulation master may collect intermediate output variables by calling `fmi3Get{VariableType}` for variables with `intermediateAccess` = `true`.

• If `intermediateStepFinished = fmi3False`, the Co-Simulation master shall only use intermediate output variables to compute intermediate `input` variables at the current state.

Hence, it is important to distinguish intermediate output from successful internal integration steps from intermediate outputs valid only for temporary solver states. The Figure 6 shows an overview of the solver states and the intended use of intermediate variable access. It is not necessary that temporary solver states occur before a finished step. For example, variable step-size solvers may try longer steps first and then reduce step size before the step is finished.

Figure 6. Overview of solver states and intermediate variable access during a communication step
###### 2.4.3.1.1. Pseudo-code Example for Intermediate Variable Access

In the following example, the usage of the intermediate variable access is illustrated in order to clarify the typical calling sequence of the functions:

``````//////////////////////////
// Define callback

// Global variables
fmi3IntermediateInfo s_intermediateInfo;

// Callback
fmi3Status intermediateUpdate(fmi3ComponentEnvironment componentEnvironment, fmi3IntermediateInfo* info, fmi3Boolean* earlyReturn)
{
intermediateTime = info->intermediateTime;

//If getting intermediate output variables allowed
if (info->intermediateVariableGetAllowed) then {
//Get the output variables at time = intermediateTime
fmi3GetReal/Integer/Boolean/String(s, ...);

//If integration step in FMU solver is finished
if (info->intermediateStepFinished) then {
//Forward output variables to other FMUs or write to result files
}
}

//If setting intermediate output variables allowed
if (info->intermediateVariableSetAllowed) then {
//Compute intermediate input variables from output varibles and
//variables from other FMUs. Use latest available output
//variables, possibly from get functions above
inputVariables = ...

//Set the input variables at time = intermediateTime
fmi3SetReal/Integer/Boolean/String(s, ...);
}

//Internal execution in FMU will now continue
}

//////////////////////////
// Initialization sub-phase

// Set callback functions,
fmi3CallbackFunctions cbf;
fmi3EventInfo eventInfo;
cbf.logger = loggerFunction; // Logger function
cbf.allocateMemory = calloc;
cbf.freeMemory = free;
// Signal that early return is supported by master
cbf.intermediateUpdate = intermediateUpdate;

// Create pointer to information for identifying the FMU in callbacks
// (note: this is pseudo code, no correct pointer handling)
cbf.componentEnvironment = GUID;

//set Co-Simulation mode
fmi3CoSimulationConfiguration coSimulationConfiguration;
coSimulationConfiguration.intermediateVariableGetRequired = true;
coSimulationConfiguration.intermediateInternalVariableGetRequired = false;
coSimulationConfiguration.intermediateVariableSetRequired = true;
coSimulationConfiguration.coSimulationMode = fmi3ModeHybridCoSimulation;

// Instantiate slave
fmi3Component s = fmi3Instantiate("Tool1" , fmi3CoSimulation, GUID, "", fmi3False, fmi3False, &cbf, fmi3True, fmi3False, &coSimulationConfiguration);

if (s == NULL) then return FAILURE;

// Start and stop time
startTime = 0;
stopTime = 10;
// Communication constant step size
h = 0.01;

// Set all variable start values (of "ScalarVariable / <type> / start")
fmi3SetReal/Integer/Boolean/String(s, ...);

// Initialize slave
fmi3SetupExperiment(s, fmi3False, 0.0, startTime, fmi3True, stopTime);
fmi3EnterInitializationMode(s);

// Set the input values at time = startTime
fmi3SetReal/Integer/Boolean/String(s, ...);

fmi3ExitInitializationMode(s);

//////////////////////////
// Simulation sub-phase
tc = startTime; // Starting master time
step = h;       // Starting non-zero step size
while (tc < tStop) do
{
if (step > 0) then
{ // Continuous mode (default mode)
fmi3Bolean earlyReturn = fmi3False;
status = fmi3DoStep(s,tc,step,...);
switch () {
case (status == fmi3OK):
tc +=step;
case (status == fmi3Warning):
// Simplified code
case (status == fmi3Error or status == fmi3Fatal or status == fmi3Discard):
// Simplified code
};
}
else
{ // Event mode
fmi3NewDiscreteStates(s, s_eventInfo);
if not(s_eventInfo.newDiscreteStatesNeeded) then {
fmi3EnterContinuousMode(s);
step = h;
};
};
// Get outputs
fmi3GetReal/Integer/Boolean/String(s, ...);
// Set inputs
fmi3SetReal/Integer/Boolean/String(s, ...);
};

//////////////////////////
// Shutdown sub-phase
if ((status != fmi3Error) and (status != fmi3Fatal)) then fmi3Terminate(s);

if (status != fmi3Fatal) then fmi3FreeInstance(s1);``````

## 3. FMI for Model Exchange

This chapter contains the interface description to access the equations of a dynamic system from a C program. A schematic view of a model in FMI for Model Exchange format is shown in Figure 7:

Figure 7. Data flow between the environment and an FMU for Model Exchange

Blue arrows: Information provided by the FMU.
Red arrows : Information provided to the FMU.
$\mathbf{v}_{start}$, $\mathbf{u}$, $\mathbf{y}$, $\mathbf{w}$, $\mathbf{x}_d$ are of a numeric type or string; $\mathbf{t}$, $\mathbf{x}_c$, $\mathbf{z}$ are of floating point type.

### 3.1. Mathematical description

#### 3.1.1. Basic definitions

The goal of the Model Exchange interface is to numerically solve a system of differential, algebraic and discrete-time equations. In this version of the interface, ordinary differential equations in state-space form with events are handled (abbreviated as "hybrid ODE"). Algebraic equation systems might be contained inside the FMU. Also, the FMU might consist of discrete-time equations only, for example, describing a sampled-data controller.

The `independent` variable time $t \in \mathbb{T}$ is a tuple $t = (t_R,t_I)$, where $t_R \in \mathbb{R},\ t_{I} \in \mathbb{N} = \{0, 1, 2, \ldots\}$. The real part $t_R$ of this tuple is the `independent` variable of the FMU for describing the continuous-time behavior of the model between events. In this phase $t_I = 0$. The integer part $t_I$ of this tuple is a counter to enumerate (and therefore distinguish) the events at the same continuous-time instant $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 below. [The notation $^{\bullet}t$ is from BCP10, adapted from non-standard analysis to super-dense time, in order to precisely define the value from the previous event iteration.]

 Operation Mathematical meaning Description $t_1 < t_2$ $(t_{R1},t_{I1}) < (t_{R2}, t_{I2})\ \Leftrightarrow \ t_{R1} < t_{R2}\ \textbf{or} \ t_{R1}= t_{R2} \ \textbf{and} \ t_{I1} < t_{I2}$ $t_1$ is before $t_2$ $t_1 = t_2$ $(t_{R1},t_{I1}) = (t_{R2},t_{I2}) \ \Leftrightarrow t_{R1}= t_{R2}\ \textbf{and} \ t_{I1} = t_{I2}$ $t_1$ is identical to $t_2$ $t^{+}$ ${{(t}_{R},t_{I})}^{+} \Leftrightarrow (\lim_{\epsilon \rightarrow 0}{\left(t_{R} + \varepsilon \right),t_{Imax})}$ right limit at $t$. $t_{Imax}$ is the largest occurring integer index of super-dense time $^-t$ $^{-}{{(t}_{R},t_{I})} \Leftrightarrow (\lim_{\epsilon \rightarrow 0}{\left( t_{R} - \varepsilon \right),0)}$ left limit at $t$ $^{\bullet}t$ $^{\bullet}{\left( t_{R},t_{I} \right)\ } \Leftrightarrow \left\{ \begin{matrix} ^-t \ & \mathbf{if} \ t_I = 0 \\ (t_R, t_I - 1) \ & \mathbf{if} \ t_I > 0 \\ \end{matrix} \right.$ previous time instant (= either left limit or previous event instant). $v^+$ $v(t^+)$ value at the right limit of $t$ $^{-}v$ $v(^-t)$ value at the left limit of $t$ $^{\bullet}v$ $v(^{\bullet}t)$ previous value (= either left limit or value from the previous event)

[Assume that an FMU has an event at $t_R=2.1s$ and here a signal 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 ODEs supported by FMI are described as piecewise continuous-time systems. Discontinuities can occur at time instants $t_0, t_1, \ldots, t_n$ where $t_i < t_{i+1}$. These time instants are called `events`. Events can be known before hand (= time event), 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 indices are used to describe the timing behavior of the corresponding variable (for example, $v_d$ is a discrete-time variable).

 Index Description `x` A continuous-time variable $x(t)$, is a continuous function of time inside each interval $t_i^+ < \ ^-t_{i+1}$ `m` A piece-wise `constant` variable $m(t)$, is constant inside each interval $t_i^+ < \ ^-t_{i+1}$. `c` A Clock variable $c(t)$, is active only at particular time instants. `r` A Clocked variable $r(t)$, is a variable of a numeric type, string or enumeration associated to a `clock` $c(t)$ and therefore active only at particular time instants.

At every event instant $t_i$, variables might be discontinuous (see Figure 8).

Figure 8. Piecewise-continuous variables of an FMU: continuous-time ($v_c$) and discrete-time ($v_d$).

An event instant $t_i$ is defined by one of the following conditions that give the smallest time instant:

1. The environment of the FMU triggers an event at the current time instant because at least one discrete-time `input` changes its value, a continuous-time `input` has a discontinuous change, or a `tunable` `parameter` changes its value. Such an event is called external event. [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 adviceable to trigger an external event for B at this time instant too, if an `output` of A is connected to B. This means to call `fmi3EnterEventMode` on B.]
All the following events are internal events.

2. At a predefined time instant $t_i=(T_{next}(t_{i-1}, 0)$ that was defined at the previous event instant $t_{i-1}$ by the FMU. Such an event is called time event.

3. At a time instant, where an event indicator $z_j(t)$ changes its domain from $z_j > 0$ to $z_j \leq 0$ or from $z_j \leq 0$ to $z_j > 0$ (see Figure 9 below). More precisely: An event $t = t_i$ occurs at the smallest time instant "min t" with $t>t_{i-1}$ where "$(z_j(t)>0) \neq (z_j(t_{i-1}) >0)$". Such an event is called state event. [This definition is slightly different from the standard definition of state events: " $z_j(t) \cdot z_j(t_{i-1}) \leq 0$ ". This often used definition has the severe drawback that $z_j(t_{i-1}) \neq 0$ is required in order to be well-defined and this condition cannot be guaranteed.]. All event indicators are piecewise continuous and are collected together in one vector of floating point numbers $\mathbf{z(t)}$.

Figure 9. An event occurs when the event indicator changes its domain from $z>0$ to $z\leq 0$ or vice versa.
1. At every completed step of an integrator, `fmi3CompletedIntegratorStep` must be called (provided the capability flag `completedIntegratorStepNotNeeded` of `<ModelDescription>` is `false`). An event occurs at this time instant, if indicated by the return argument `enterEventMode = fmi3True`. Such an event is called step event. [Step events are, for example, used to dynamically change the (continuous) `states` of a model internally in the FMU, because the previous states are no longer suited numerically.]

An FMI Model-Exchange model is described by the following variables:

 Variable Description $t$ `independent` variable time $\in \mathbb{T}$. (Variable defined with `causality` = `independent`). $v$ A vector of all exposed variables (all variables defined in element ``, see Section 2.2.10). A subset of the variables is selected via a subscript. Example: $\mathbf{v}_{initial=exact}$ are variables defined with attribute `initial` = `exact` (see Section 2.2.10). These are `independent` `parameters` and start values of other variables, such as initial values for `states`, state derivatives or `outputs`. $\mathbf{p}$ Parameters that are constant during simulation. The symbol without a subscript references `independent` `parameters` (variables with `causality` = `parameter`). Dependent `parameters` (variables with `causality` = `calculatedParameter`) are denoted as $\mathbf{p}_{calculated}$. $\mathbf{u}(t)$ Input variables. The values of these variables are defined outside of the model. Variables of this type are defined with attribute `causality` = `input`. Whether the `input` is a discrete-time or continuous-time variable is defined via attribute `variability` = `discrete` or `continuous` (see Section 2.2.10). $\mathbf{y}(t)$ Output variables. The values of these variables are computed in the FMU and they are designed to be used in a model connection. For instance, output variables might be used in the environment as input values to other FMUs or other submodels. Variables of this type are defined with attribute `causality` = `output`. Whether the `output` is a discrete-time or continuous-time variable is defined via attribute `variability` = `discrete` or `continuous` (see Section 2.2.10). $\mathbf{w}(t)$ Local variables of the FMU that cannot be used for FMU connections. Variables of this type are defined with attribute `causality` = `local`, see Section 2.2.10. $\mathbf{z}(t)$ A vector of floating point continuous-time variables representing the event indicators utilized to define state events, see below. For notational convenience, an event indicator is conceptually treated as a different type of variable as an `output` or a `local` variable for the mathematical description below. In reality, event indicator is however part of the `outputs` $\mathbf{y}$ or the `local` variables $\mathbf{w}$ of an FMU. $\mathbf{x}_c(t)$ A vector of floating point continuous-time variables representing the continuous-time `states`. For notational convenience, a continuous-time `state` is conceptually treated as a different type of variable as an `output` or a `local` variable for the mathematical description below. In reality, a continuous-time `state` is however part of the `outputs` $\mathbf{y}$ or the `local` variables $\mathbf{w}$ of an FMU. $\mathbf{x}_d(t)$ $^{\bullet}\mathbf{x}_d(t)$ $\mathbf{x}_d(t)$ is a vector of (internal) discrete-time variables (of any type) representing the discrete `states`. ${}^{\bullet}\mathbf{x}_d(t)$ a is the value of $\mathbf{x}_d(t)$ at the previous super-dense time instant, so ${}^{\bullet}\mathbf{x}_d(t)=\mathbf{x}_d({}^{\bullet}t)$. Given the previous values of the discrete-time `states`, ${}^{\bullet}\mathbf{x}_d(t)$, at the actual time instant $t$, all other discrete-time variables, especially the discrete `states` $\mathbf{x}_d(t)$, can be computed. Discrete `states` are not visible in the interface of an FMU and are only introduced here to clarify the mathematical description. Formally, a discrete `state` is part of the `outputs` $\mathbf{y}$ or the `local` variables $\mathbf{w}$ of an FMU. $T_{next}(t_{i})$ At initialization or at an event insant, an FMU can define the next time instant $T_{next}$, at which the next event occurs (see also the definition of events above). Every event removes automatically a previous definition of $T_{next}$, and it must be explicitly defined again, if a previously defined $T_{next}$ was not triggered at the current event instant. $\mathbf{r}(t_i)$ A vector of Boolean variables with $r_{i} := z_{i} > 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 $\mathbf{r}$. Only during Initialization Mode or Event Mode the domains $z_{i} > 0$ can be changed. For notational convenience, $\mathbf{r} := \mathbf{z} > 0$is an abbreviation for $\mathbf{r}:=\{z_1>0, z_2>0, \ldots \}$. [For more details, see "Remark 3" below.]

#### 3.1.2. Computation Modes

Computing the solution of an FMI model means to split the solution process in different phases, and in every phase different equations and solution methods are utilized. The phases can be categorized according to the following modes:

##### 3.1.2.1. Initialization Mode

This mode is used to compute at the start time stem[t_0] initial values for continuous-time `states`, $\mathbf{x}_c(t_0)$, and for the previous (internal) discrete-time `states`, $\mathbf{x}_d(t_0)$, by utilizing extra equations not present in the other modes (for example, equations to define the `start` value for a `state` or for the derivative of a `state`).

##### 3.1.2.2. Continuous-Time Mode

This mode is used to compute the values of all floating point 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.

##### 3.1.2.3. Event Mode

This mode is used to compute new values for all continuous-time variables, as well as for all discrete-time variables that are activated at the current event instant $t$, given the values of the variables from the previous instant ${}^{\bullet}t$. This is performed by solving algebraic equations consisting of all continuous-time and all active discrete-time equations. In FMI 2.0 there is no mechanism that the FMU can provide the information whether a discrete-time variable is active or is not active (is not computed) at an event instant. Therefore, the environment has to assume that at an event instant always all discrete-time variables are computed, although internally in the FMU only a subset might be newly computed.

When connecting FMUs together, loop structures can occur that lead to particular difficulties because linear or non-linear algebraic systems of equations in floating point variables but also in Boolean or Integer variables might be present. In order to solve such systems of equations over FMUs efficiently, the dependency information is needed stating, for example, which `outputs` depend directly on `inputs`. This data is optionally provided in the XML file under element `<ModelStructure>`. If this data is not provided, the worst case must be assumed (for example, all output variables depend algebraically on all `input` variables).

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

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

In the upper diagram, FMU1 and FMU2 are connected in such a way that by an appropriate sequence of `fmi3Set{VariableType}` and `fmi3Get{VariableType}` calls, the FMU variables can be computed. In the lower diagram, FMU3 and FMU4 are connected in such a way that a real algebraic loop is present. This loop might be solved iteratively with a Newton method. In every iteration the iteration variable $u_4$ is provided by the solver, and via the shown sequence of `fmi3Set{VariableType}` and `fmi3Get{VariableType}` calls, the residue is computed and is provided back to the solver. Based on the residue a new value of $u_4$ is provided. The iteration is terminated when the residue is close to zero. These types of artifical or real algebraic loops can occur in all the different modes, such as Initialization Mode, Event Mode, and Continuous-Time Mode. 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.]

In Table 1 the equations are defined that can be evaluated in the respective mode. The following color coding is used in the table:

• grey: If a variable in an argument list is marked in grey, then this variable is not changing in this mode and just the last calculated value from the previous mode is internally used. For an input argument, it is not allowed to call `fmi3Set{VariableType}`. For an output argument, calling `fmi3Get{VariableType}` on such a variable returns always the same value in this mode.

• green: Functions marked in green are special functions to enter or leave a mode.

• blue: Equations and functions marked in blue define the actual computations to be performed in the respective mode.

[In the following table the setting of the super-dense time, ($t_R$, $t_I$), is precisely described. Tools will usually not have such a representation of time. However, super-dense time defines precisely when a new "model evaluation" starts and therefore which variable values belong to the same "model evaluation" at the same (super-dense) time instant and should be stored together.]

 Equations FMI functions Equations before Initialization Mode Set `independent` variable time $T_{R0}$ and define $t_0 := (t_{R0},0)$ `fmi3SetupExperiment` Set variables $\mathbf{v}_{initial=exact}$ and $\mathbf{v}_{initial=approx}$ that have a `start` value (`initial` = `exact` or `approx`) `fmi3Set{VariableType}` Equations during Initialization Mode Enter Initialization Mode at $t=t_0$ (activate initialization, discrete-time and continuous-time equations) `fmi3EnterInitializationMode` Set variables $\mathbf{v}_{initial=exact}$ that have a `start` value with `initial` = `exact` (`independent` `parameters` $\mathbf{p}$ and continuous-time `states` with `start` values $\mathbf{x}_{c,initial=exact}$ are included here) `fmi3Set{VariableType}` Set continuous-time and discrete-time `inputs` $\mathbf{u}(\color{grey}t_{\color{grey} 0})$ `fmi3Set{VariableType}` $\mathbf{v}_{initialUnknowns}:=f_{init}(\mathbf{u_c}, \mathbf{u_d}, \color{grey}t_{\color{grey} 0}, \mathbf{v}_{initial=exact}$) `fmi3Get{VariableType}`, `fmi3GetContinuousStates` Exit Initialization Mode (de-activate initialization equations) `fmi3ExitInitializationMode` Equations during Event Mode Enter Event Mode at $t = t_{i}$ with ${t_{i}\ : = (t}_{R},t_{I} + 1)$ if externalEvent or nextMode $\equiv$ EventMode or $t_i=(T_{next}(t_{i-1}), 0)$ or $\min_{t>t_{i-1}} t:\left\lbrack z_{j}\left( t \right) > 0\ \neq \ z_{j}\left( t_{i - 1} \right) > 0 \right\rbrack$ (activate discrete-time equations) `fmi3EnterInitializationMode` (only from Continuous-Time Mode or after calling `fmi3SetTime` if FMU has no continuous-time equations) Set `independent` `tunable` `parameters` $\mathbf{p}_{tune}$ (and do not set other `parameters` $\mathbf{p}_{other}$) `fmi3Set{VariableType}` Set continuous-time and discrete-time `inputs` $\mathbf{u}(t_i)$ `fmi3Set{VariableType}` Set continuous-time `states` $\mathbf{x}_c(t_i)$ `fmi3Set{VariableType}`, `fmi3SetContinuousStates` $(\mathbf{y}_{c+d}, \mathbf{\dot{x}}_c, \mathbf{w}_{c+d}, \mathbf{z}, \mathbf{x}_{c, reinit})=\mathbf{f}_{sim}(\mathbf{x_c}, \mathbf{u_{c+d}}, \color{grey}t_{\color{grey} i}, \mathbf{p}_{tune}, \color{grey}{\mathbf{p}_{other})}$ $\mathbf{f}_{sim}$is also a function of the internal variables ${}^\bullet\mathbf{x}_d$ `fmi3Get{VariableType}`, `fmi3GetContinuousStates`, `fmi3GetDerivatives` `fmi3GetEventIndicators` Increment super-dense time and define with `newDiscreteStatesNeeded` whether a new event iteration is required. $\qquad$if not `newDiscreteStatesNeeded`then $\qquad \qquad T_{next}=T_{next}(\mathbf{x}_c,{}^\bullet\mathbf{x}_d, \mathbf{u_{c+d}}, \color{grey}t_{\color{grey} i}, \mathbf{p}_{tune}, \color{grey}{\mathbf{p}_{other})}$ $\qquad$end if $\qquad t:=t(t_R, t_i+1)$ $\qquad {}^\bullet\mathbf{x}_d:=\mathbf{x}_d$ `fmi3NewDiscreteState` Set `independent` variable time $t_i := (T_{next},0)$ `fmi3SetTime` + (if no continuous-time equations) Equations during Continuous-Time Mode Enter Continuous-Time Mode: $\qquad \textrm{// de-activate discrete-time equations}$ $\qquad \textrm{// "freeze" variables:}$ $\qquad \mathbf{r} := \mathbf{z}>0 \qquad \textrm{//all relations}$ $\qquad \textbf{x}_d, \textbf{w}_d \qquad \textrm{//all discrete-time variables}$ `fmi3EnterContinuousTimeMode` Set `independent` variable time $t(>t_{enter mode}): t:=(t_R, 0)$ `fmi3SetTime` Set continuous-time `inputs` $\mathbf{u}_{c}(t)$ `fmi3Set{VariableType}` Set continuous-time `states` $\mathbf{x}_{c}(t)$ `fmi3Set{VariableType}`, `fmi3SetContinuousStates` $(\mathbf{y}_{c}\mathbf{,} \color{grey}{\mathbf{y}_{d}}\mathbf{,\ }{\dot{\mathbf{x}}}_{c}\mathbf{,}_{}\mathbf{w}_{c}\mathbf{,}\color{grey}{\mathbf{w}_{d}}\mathbf{,z,}\color{grey}{\mathbf{x}_{c,reinit}}):=\mathbf{f}_{sim}(\mathbf{x}_{c},\ \mathbf{u}_{c}\mathbf{,} \color{grey}{\mathbf{\ u}_{d}}, t,\color{grey}{\mathbf{p}_{tune},\mathbf{p}_{other}})$ $\qquad \mathbf{f}_{sim}$ is also a function of the internal variables ${}^\bullet\mathbf{x}_{d},\mathbf{r}$. `fmi3Get{VariableType},` `fmi3GetDerivatives,` `fmi3GetEventIndicators` Complete integrator step and return `enterEventMode` `fmi3CompletedIntegratorStep` Data types $t \in \mathbb{R}, \mathbf{p} \in \mathbb{P}^{np}, \mathbf{u}(t) \in \mathbb{P}^{nu},\mathbf{y}(t) \in \mathbb{P}^{ny}, \mathbf{x}_c(t) \in \mathbb{R}^{nxc}, \mathbf{x}_d(t) \in \mathbb{P}^{nxd}, \mathbf{w}(t) \in \mathbb{P}^{nw}, \mathbf{z}(t) \in \mathbb{R}^{nz}$ $\qquad \mathbb{R}$: floating point variable, $\mathbb{P}$: floating point or Boolean or integer or enumeration or string variable $\mathbf{f}_{init}, \mathbf{f}_{sim} \in C^0$ (=continuous functions with respect to all input arguments inside the respective mode).

[Remark 1 - Calling Sequences:

In the table above, for notational convenience in every mode one function call is defined to compute all output arguments from all inputs arguments. In reality, every scalar output argument is computed by one `fmi3Get{VariableType}` function call. Additionally, the output argument need not be a function of all input arguments, but of only a subset from it, as defined in the XML file under `<ModelStructure>`. This is essential when FMUs are connected in a loop, as shown in Figure 10. For example, since $y_{2a}$ depends only on $u_{1a}$ , but not on $u_{1b}$, it is possible to call `fmi3Set{VariableType}` to set $u_{1a}$ , and then inquire $y_{2a}$ with `fmi3Get{VariableType}` without setting $u_{1b}$ beforehand.

It is non-trivial to provide code for `fmi3Set{VariableType}`, `fmi3Get{VariableType}`, if the environment can call `fmi3Set{VariableType}` on the `inputs` in quite different orders. A simple remedy is to provide the dependency information, not according to the real functional dependency, but according to the sorted equations in the generated code. Example:

Assume an FMU is described by the following equations (`u1`, `u2` are `inputs`, `y1`, `y2` are `outputs`,`w1`, `w2` are internal variables):

```w1 = w2 + u1
w2 = u2
y1 = w1
y2 = w2```

Sorting of the equations might result in (this ordering is not unique):

```w2 := u2
y2 := w2
w1 := w2 + u1
y1 := w1```

With this ordering, the dependency should be defined as `y2 = f(u2), y1 = f(u1,u2)`. When `y2` is called first with `fmi3Get{VariableType}`, then only `u2` must be set first (since `y2 = f(u2)`), and the first two equations are evaluated. If later `y1` is inquired as well, then the first two equations are not evaluated again and only the last two equations are evaluated. On the other hand, if `y1` is inquired first, then `u1` and `u2` must be set first (since `y1 = f(u1,u2)`) and then all equations are computed. When `y2` is inquired afterwards, the cached value is returned.

If sorting of the equations in this example would instead result in the following code:

```w2 := u2
w1 := w2 + u1
y1 := w1
y2 := w2```

then the dependency should be defined as `y2 = f(u1,u2)`, `y1 = f(u1,u2)`, because `u1` and `u2` must be first set, before `y2` can be inquired with `fmi3Get{VariableType}` when executing this code.

Remark 2 - Mathematical Model of Discrete-Time FMUs:

There are many different ways discrete-time systems are described. For FMI, the following basic mathematical model for discrete-time systems is used (other description forms must be mapped, as sketched below):

At an event instant, the discrete system is described by algebraic equations as function of the previous (internal) discrete-time `states` $_{}^{\bullet}\mathbf{x}_{d}$ and the discrete-time `inputs` $\mathbf{u}_{d}$. If FMUs are connected in a loop, these algebraic equations are called iteratively, until the solution is found. If the actual discrete-time `states` $\mathbf{x}_{d}$ and the previous discrete-time `states` $_{}^{\bullet}\mathbf{x}_{d}$ are not identical, the discrete-time `states` are updated, the integer part of the time is incremented and a new event iteration is performed. Other discrete-time models must be mapped to this description form. Examples:

Synchronous systems

A synchronous system, such as Lucid Synchrone [PZ06] or Modelica 3.3 [MLS12], is called periodically, and at every sample instant the discrete-time equations are evaluated exactly once. An FMU of this type can be implemented by activating the model equations only at the first event iteration and returning always `newDiscreteStatesNeeded = fmi3False` from `fmi3NewDiscreteStates`. Furthermore, the discrete-time `states` are not updated by `fmi3NewDiscreteStates`, but as first action before the discrete-time equations are evaluated, in order that $^{\bullet}\mathbf{x}_d$ (= value at the previous `clock` tick) and $\mathbf{x}_d$ (value at the latest `clock` tick) have reasonable values between `clock` ticks.

State machines with one memory location for a state

In such a system there is only one memory location for a discrete-time `state` and not two, and therefore a discrete-time `state` is updated in the statement where it is assigned (and not in `fmi3NewDiscreteStates`). As a result, `fmi3NewDiscreteStates` is basically just used to start a new (super-dense) time instant. This is unproblematic, as long as no algebraic loops occur. FMUs of this type can therefore not be used in real algebraic loops if the involved variables depend on a discrete-time `state`. This restriction is communicated to the environment of the FMU by the `ScalarVariable` definition of the corresponding `input` with flag `canHandleMultipleSetPerTimeInstant` `= false` (so an `input` with this flag is not allowed to be called in an algebraic loop).

Remark 3 - Event Indicators / Freezing Relations:

In the above table, vector r is used to collect all relations together that are utilized in the event indicators z . _In Continuous-Time Mode all these relations are `frozen` and do not change during the evaluations in the respective mode. This is indicated in the table above by computing r when entering the Continuous-Time Mode and providing r as (internal) input argument to the evaluation functions. Example:

An equation of the form

`y = if x1 > x2 or x1 < x3 then +1 else -1;`

can be implemented in the FMU as:

```z1 := x1 - x2;
z2 := x3 - x1;
if *Initialization Mode* or *Event Mode* then
r1 := z1 > 0;
r2 := z2 > 0;
end if;
y = if r1 or r2 then +1 else -1```

Therefore, the original if-clause is evaluated in this form only during Initialization Mode and Event Mode. In Continuous-Time Mode this equation is evaluated as:

```z1 = x1 - x2;
z2 = x3 - x1
y = if r1 or r2 then +1 else -1;```

and when entering Continuous-Time Mode r1 and r2 are computed as

```r1 = z1 > 0
r2 = z2 > 0```

When z1 changes from z1 > 0 to z1 ⇐ 0 or vice versa, or z2 correspondingly, the integration is halted, and the environment must call `fmi3EnterEventMode`.

An actual implementation will pack the code in an impure function, say Greater(…​), resulting in:

`y = if Greater(x1-x2,...) or Greater(x3-x1,...) then +1 else -1;`

Furthermore, a hysteresis should be added for the event indicators.

An FMU is initialized in Initialization Mode with $\mathbf{f}_{init}(\ldots)$. The input arguments to this function consist of the `input` variables (= variables with `causality` = `input`), of the `independent` variable (= variable with `causality` = `independent`; usually the default value `time`), and of all variables that have a `start` value with (explicitly or implicitly) `initial` = `exact` in order to compute the continuous-time `states` and the output variables at the initial time $t_0$. In the above table, the variables with `initial` = `exact` are collected together in variable $\mathbf{v}_{initial=exact}$. For example, initialization might be defined by providing initial `start` values for the `states`, $\mathbf{x}_{c0}$, or by stating that the state derivatives are zero ($\dot{\mathbf{x}}_{c} = \mathbf{0}$). Initialization is a difficult topic by itself, and it is required that an FMU solves a well-defined initialization problem inside the FMU in Initialization Mode.
After calling `fmi3ExitInitializationMode`, the FMU is implicitly in Event Mode, and all discrete-time and continuous-time variables at the initial time instant $(t_R, 0)$ can be calculated. If these variables are present in an algebraic loop, iteration can be used to compute them. Once finalized, `fmi3NewDiscreteStates` must be called, and depending on the value of the return argument, the FMU either continues the event iteration at the initial time instant or switches to Continuous-Time Mode.
After switching to Continuous-Time Mode, the integration is started. Basically, in this phase the `derivatives` of the continuous `states` are computed. If FMUs and/or submodels are connected together, then the `inputs` of these models are the `outputs` of other models, and therefore, the corresponding FMU outputs must be computed. Whenever result values shall be stored, usually at output points defined before the start of the simulation, the `fmi3Get{VariableType}` function with respect to the desired variables must be called.
Continuous integration is stopped at an event instant. An event instant is determined by a time, state or step event, or by an external event triggered by the environment. In order to determine a state event, the event indicators z have to be inquired at every completed integrator step. Once the event indicators signal a change of their domain, an iteration over time is performed between the previous and the actual completed integrator step, in order to determine the time instant of the domain change up to a certain precision.
After an event is triggered, the FMU needs to be switched to Event Mode. In this mode, systems of equations over connected FMUs might be solved (similarily as in Continuous-Time Mode). Once convergence is reached, `fmi3NewDiscreteStates` must be called to increment super-dense time (and conceptually update the discrete-time `states` defined internally in the FMU by $^{\bullet}\mathbf{x}_d := \mathbf{x}_d$). Depending on the discrete-time model, a new event iteration might be needed (for example, because the FMU describes internally a state machine and transitions are still able to fire, but new `inputs` shall be taken into account).
The function calls in the table above describe precisely which input arguments are needed to compute the desired output argument(s). There is no 1:1 mapping of these mathematical functions to C functions. Instead, all input arguments are set with `fmi3Set{VariableType}` C function calls, and then the result argument(s) can be determined with the C functions defined in the right column of the above table. This technique is discussed in detail in Section 3.2.1. [In short: For efficiency reasons, all equations from the table above will usually be available in one (internal) C function. With the C functions described in the next sections, input arguments are copied into the internal model data structure only when their value has changed in the environment. With the C functions in the right column of the table above, the internal function is called in such a way that only the minimum needed equations are evaluated. Hereby, variable values calculated from previous calls can be reused. This technique is called "caching" and can significantly enhance the simulation efficiency of real-world models.]

### 3.2. Application Programming Interface

This section contains the interface description to evaluate different model parts from a C program.

#### 3.2.1. Providing Independent Variables and Re-initialization of Caching

Depending on the situation, different variables need to be computed. In order to be efficient, it is important that the interface requires only the computation of variables that are needed in the present context. 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. It might be that at the same time instant other variables are needed. For example, if an integrator step is completed, the event indicator functions need to be computed as well. If the state derivatives have already been computed at the present time instant, then it is important for efficiency that they are not newly computed in the call to compute the event indicator functions. This means, the state derivatives shall be reused from the previous call. This feature is called "caching of variables" in the sequel.
Caching requires that the model evaluation can detect when the input arguments, like time or states, have changed. This is achieved by setting them explicitly with a function call, since every such function call signals precisely a change of the corresponding variables. For this reason, this section contains functions to set the input arguments of the equation evaluation functions. This is unproblematic for time and states, but is more involved for `parameters` and `inputs`, since the latter may have different data types.

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

Set a new time instant and re-initialize caching of variables that depend on time, provided the newly provided time value is different to the previously set time value (variables that depend solely on `constants` or `parameters` need not to be newly computed in the sequel, but the previously computed values can be reused).

``````typedef fmi3Status fmi3SetContinuousStatesTYPE(fmi3Instance instance,
const fmi3Float64 x[],
size_t nx);``````

Set a new (continuous) state vector and re-initialize caching of variables that depend on the `states`.

• Argument `nx` is the length of

• argument `x[]`

and is provided for checking purposes (variables that depend solely on`constants`, `parameters`, time, and `inputs` do not need to be newly computed in the sequel, but the previously computed values can be reused). Note that the continuous `states` might also be changed in Event Mode. Note that `fmi3Status = fmi3Discard` is possible.

``fmi3Status fmi3Set{VariableType}(..);``

Set new values for (`independent`) `parameters`, `start` values and `inputs` and re-initialize caching of variables that depend on these variables. The details of these functions are defined in Section 2.1.7.

[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.]

#### 3.2.2. Evaluation of Model Equations

This section contains the core functions to evaluate the model equations. Before one of these functions can be called, the appropriate functions from the previous section have to be used, to set the input arguments to the current model evaluation.

``````typedef fmi3Status fmi3EnterEventModeTYPE(fmi3Instance instance,
fmi3Boolean inputEvent,
fmi3Boolean stepEvent,
const fmi3Int32 rootsFound[],
size_t nEventIndicators,
fmi3Boolean timeEvent);``````

The model enters Event Mode from the Continuous-Time Mode and discrete-time equations may become active (and relations are not "frozen").

The followings arguments can be set to `fmi3True` to inform the FMU why Event Mode was entered.

[These arguments are not mutually exclusive and may all be `fmi3False` if the caller cannot provide this information.]

• Argument `inputEvent` signals with `fmi3True` that an input event occurred.

• Argument `stepEvent` signals with `fmi3True` that a step event occurred.

• Argument `rootsFound[]` is an array of length `nEventIndicators`. For `i = 1, …​, nEventIndicators, rootsFound[i-1]` $\neq$ `0` if the event indicator $z_i$ has a root, and `rootsFound[i-1] == 0` if not. For the components $z_i$ for which a root was found, the sign of `rootsFound[i-1]` indicates the direction of the zero-crossing. A value of `+1` indicates that $z_i$ is increasing, while a value of `-1` indicates a decreasing $z_i$. If `nEventIndicators == 0` the value of `rootsFound` is not defined.

• Argument `nEventIndicators` contains the number of event indicators (length of `rootsFound[]`) or `0` if the caller cannot provide this information.

• Argument `timeEvent` signals with `fmi3True` that a time event occurred.

``````typedef fmi3Status fmi3NewDiscreteStatesTYPE(fmi3Instance instance,
fmi3Boolean *newDiscreteStatesNeeded,
fmi3Boolean *terminateSimulation,
fmi3Boolean *nominalsOfContinuousStatesChanged,
fmi3Boolean *valuesOfContinuousStatesChanged,
fmi3Boolean *nextEventTimeDefined,
fmi3Float64 *nextEventTime);``````

The FMU is in Event Mode and the super dense time is incremented by this call.
If the super dense time before a call to `fmi3NewDiscreteStates` was $(t_R,t_I)$, then the time instant after the call is $(t_R,t_I)$.

• If output argument `newDiscreteStatesNeeded = fmi3True`, the FMU should stay in Event Mode, and the FMU requires to set new inputs to the FMU (`fmi3Set{VariableType}` on `inputs`) to compute and get the `outputs` (`fmi3Get{VariableType}` on `outputs`) and to call `fmi3NewDiscreteStates` again. Depending on the connection with other FMUs, the environment shall

• call `fmi3Terminate`, if `terminateSimulation = fmi3True` is returned by at least one FMU,

• call `fmi3EnterContinuousTimeMode` if all FMUs return `newDiscreteStatesNeeded = fmi3False`, and

• stay in Event Mode otherwise. When the FMU is terminated, it is assumed that an appropriate message is printed by the logMessage function (see Section 2.1.5) to explain the reason for the termination.

• If output argument `terminateSimulation = fmi3True`, the FMU can signal it needs to terminate the simulation by calling `fmi3Terminate`.

• If argument `nominalsOfContinuousStatesChanged = fmi3True`, then the nominal values of the `states` have changed due to the function call and can be inquired with `fmi3GetNominalsOfContinuousStates`.

• If argument `valuesOfContinuousStatesChanged = fmi3True`, then at least one element of the continuous state vector has changed its value due to the function call.

The new values of the `states` can be inquired with `fmi3GetContinuousStates` or individually for each state for which `reinit = true` by calling `fmi3GetFloat*`. If no element of the continuous state vector has changed its value, `valuesOfContinuousStatesChanged` must return `fmi3False`. [If `fmi3True` would be returned in this case, an infinite event loop may occur.]

• If argument `nextEventTimeDefined = fmi3True`, then the simulation shall integrate at most until `time` reaches value of

• argument `nextEventTime`, and shall call `fmi3EnterEventMode` at this time instant. If integration is stopped before `nextEventTime`, for example, due to a state event, the definition of `nextEventTime` becomes obsolete.

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

The model enters Continuous-Time Mode and all discrete-time equations become inactive and all relations are "frozen".
This function has to be called when changing from Event Mode (after the global event iteration in Event Mode over all involved FMUs and other models has converged) into Continuous-Time Mode.

[This function might be used for the following purposes:

• If the FMU stores results internally on file, then the results after the initialization and/or the event has been processed can be stored.

• If the FMU contains dynamically changing states, then a new state selection might be performed with this function.]

``````typedef fmi3Status fmi3CompletedIntegratorStepTYPE(fmi3Instance instance,
fmi3Boolean noSetFMUStatePriorToCurrentPoint,
fmi3Boolean* enterEventMode,
fmi3Boolean* terminateSimulation);``````

This function must be called by the environment after every completed step of the integrator provided the capability flag `completedIntegratorStepNotNeeded = false`. Argument `noSetFMUStatePriorToCurrentPoint` is `fmi3True` if `fmi3SetFMUState` will no longer be called for time instants prior to current time in this simulation run [the FMU can use this flag to flush a result buffer].
The function returns `enterEventMode` to signal to the environment if the FMU shall call `fmi3EnterEventMode`, and it returns `terminateSimulation` to signal if the simulation shall be terminated. If `enterEventMode = fmi3False` and `terminateSimulation = fmi3False` the FMU stays in Continuous-Time Mode without calling `fmi3EnterContinuousTimeMode` again. When the integrator step is completed and the `states` are modified by the integrator afterwards (for example, correction by a BDF method), then `fmi3SetContinuousStates` has to be called with the updated states before `fmi3CompletedIntegratorStep` is called.
When the integrator step is completed and one or more event indicators change sign (with respect to the previously completed integrator step), then the integrator or the environment has to determine the time instant of the sign change that is closest to the previous completed step up to a certain precision (usually a small multiple of the machine epsilon). This is usually performed by an iteration where time is varied and `state` variables needed during the iteration are determined by interpolation. Function `fmi3CompletedIntegratorStep` must be called after this state event location procedure and not after the successful computation of the time step by the integration algorithm. The intended purpose of the function call is to indicate to the FMU that at this stage all `inputs` and `state` variables have valid (accepted) values. After `fmi3CompletedIntegratorStep` is called, it is still allowed to go back in time (calling `fmi3SetTime`) and inquire values of variables at previous time instants with `fmi3Get{VariableType}` [for example, to determine values of non-state variables at output points]. However, it is not allowed to go back in time over the previous `fmi3CompletedIntegratorStep` or the previous `fmi3EnterEventMode` call.

[This function might be used, for example, for the following purposes:

Delays:
All variables that are used in a "delay(..)" operator are stored in an appropriate buffer and the function returns with `enterEventMode = fmi3False`, and `terminateSimulation = fmi3False`.

1. Dynamic state selection:
It is checked whether the dynamically selected states are still numerically appropriate. If yes, the function returns with `enterEventMode = fmi3False` otherwise with `enterEventMode = fmi3True`. In the latter case, `fmi3EnterEventMode` has to be called and the states are dynamically changed by a subsequent `fmi3NewDiscreteStates`.

Note that this function is not used to detect time or state events, for example, by comparing event indicators of the previous with the current call of `fmi3CompletedIntegratorStep`. These types of events are detected in the environment, and the environment has to call `fmi3EnterEventMode` independently in these cases, whether the return argument `enterEventMode` of `fmi3CompletedIntegratorStep` is `fmi3True` or `fmi3False`.]

``````typedef fmi3Status fmi3GetDerivativesTYPE(fmi3Instance instance,
fmi3Float64 derivatives[],
size_t nx);``````
``````typedef fmi3Status fmi3GetEventIndicatorsTYPE(fmi3Instance instance,
fmi3Float64 eventIndicators[],
size_t ni);``````

Compute state derivatives and event indicators at the current time instant and for the current `states`. Note that `fmi3Status = fmi3Discard` is possible for both functions.

The `derivatives` are returned as a vector with `nx` elements. The ordering of the elements of the `derivatives` vector is identical to the ordering of the state vector (for example, `derivatives[2]` is the `derivative` of `x[2]`). The order of the states and derivatives is also the same as the ordered list of elements `<ModelStructure><Derivative>`. [Array variables are serialized in "row major" order, as usual.]

The event indicators are returned as a vector with `ni` elements. The order of event indicators in `eventIndicators` vector is the same as the ordered list of `<EventIndicator>` elements in `<ModelStructure>`. [Array variables are serialized in "row major" order, as usual.] A state event is triggered when the domain of an event indicator changes from $z_j > 0$ to $z_j \leq 0$ or vice versa. The FMU must guarantee that at an event restart $z_j \neq 0$, for example, by shifting $z_j$ with a small value. Furthermore, $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 "one").

``typedef fmi3Status fmi3GetContinuousStatesTYPE(fmi3Instance instance, fmi3Float64 x[], size_t nx);``

Return the new (continuous) state vector `x`.

``````typedef fmi3Status fmi3GetNominalsOfContinuousStatesTYPE(fmi3Instance instance,
fmi3Float64 nominals[],
size_t nx);``````

Return the nominal values of the continuous `states`. This function should always be called after calling function `fmi3NewDiscreteStates`, if `nominalsOfContinuousStatesChanged = fmi3True`, since then the nominal values of the continuous `states` have changed [for example, because the association of the continuous `states` to variables has changed due to internal dynamic state selection]. If the FMU does not have information about the nominal value of a continuous `state` i, a nominal value `x_nominal[i] = 1.0` should be returned. Note that it is required that `x_nominal[i] > 0.0`. [Typically, the nominal values of the continuous `states` are used to compute the absolute tolerance required by the integrator. Example:
`absoluteTolerance[i] = 0.01 * tolerance * x_nominal[i];` ]

#### 3.2.3. State Machine of Calling Sequence

Every implementation of the FMI must support calling sequences of the functions according to the following state chart:

Figure 11. Calling sequence of Model Exchange C functions in form of an UML 2.0 state machine.

The objective of the start chart is to define the allowed calling sequences for functions of the FMI: Calling sequences not accepted by the state chart are not supported by the FMI. The behavior of an FMU is undefined for such a calling sequence. For example, the state chart indicates that when an FMU for Model Exchange is in state Continuous-Time Mode, a call to `fmi3Set{VariableType}` for a `discrete` `input` is not supported. The state chart is given here as UML 2.0 state machine. If a transition is labelled with one or more function names (for example, `fmi3GetFloat64`, `fmi3GetUInt8`), this means that the transition is taken if any of these functions is successfully called. Note that the FMU can always determine in which state it is since every state is entered by a particular function call (such as `fmi3EnterEventMode`), or a particular return value (such as `fmi3Fatal`).

The transition conditions `external event`, `time event`, and `state event` are defined in Section 3.1. Each state of the state machine corresponds to a certain phase of a simulation as follows:

instantiated

In this state, `start` and guess values (= variables that have `initial` = `exact` or `approx`) set and `variability` $\neq$ `constant` can be set, this does not include inputs as they do not have an `initial` attribute.

Configuration Mode

In this state `structural parameters` with `variability` = `fixed` or `variability` = `tunable` can be changed. This state is entered from state Instantiated by calling `fmi3EnterConfigurationMode` and left back to Instantiated by calling `fmi3ExitConfigurationMode`. `fmi3EnterConfigurationMode` can only be called if the FMU contains at least one `structural parameter`

Initialization Mode

In this state, equations are active to determine all continuous-time states, as well as all `outputs` (and optionally other variables exposed by the exporting tool). The variables that can be retrieved by `fmi3Get{VariableType}` calls are (1) defined in the XML file as elements `<ModelStructure><InitialUnknown>` and (2) variables with `causality` = `output`. Variables with `initial` = `exact` and `variability` $\neq$ `constant`, as well as variables with `causality` = `input` can be set.

Continuous-Time Mode

In this state, the continuous-time model equations are active and integrator steps are performed. The event time of a state event may be determined if a domain change of at least one event indicator is detected at the end of a completed integrator step.

Event Mode

If an event is triggered in Continuous-Time Mode, Event Mode is entered by calling `fmi3EnterEventMode`. In this mode all continuous-time and discrete-time equations are active and the unknowns at an event can be computed and retrieved. After an event is completely processed, `fmi3NewDiscreteStates` must be called and depending on the return argument, `newDiscreteStatesNeeded`, the state chart stays in Event Mode or switches to Continuous-Time Mode. When the Initialization Mode is terminated with `fmi3ExitInitializationMode`, then Event Mode is directly entered, and the continuous-time and discrete-time variables at the initial time are computed based on the initial continuous-time states determined in the Initialization Mode.

Reconfiguration Mode

In this state `structural parameters` with `variability` = `tunable` can be changed. This state is entered from state Event Mode by calling `fmi3EnterConfigurationMode` and left back to Event Mode by calling `fmi3ExitConfigurationMode`. `fmi3EnterConfigurationMode` can only be called if the FMU contains at least one `structural parameter`

Terminated

In this state, the solution at the final time of a simulation can be retrieved.

Note that simulation backward in time is only allowed over continuous time intervals. As soon as an event occurrs (`fmi3EnterEventMode` was called), going back in time is forbidden, because `fmi3EnterEventMode` / `fmi3NewDiscreteStates` can only compute the next discrete state, not the previous one.

Note that during Initialization, Event, 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.]

The allowed function calls in the respective states are summarized in the following table (functions marked in "yellow" are only available for Model Exchange, the other functions are available both for Model Exchange and Co-Simulation):

 Function FMI 2.0 for Model Exchange Start, End Instantiated Initialization Mode Event Mode Continuous-Time Mode Terminated Error `fmi3GetVersion` x x x x x x x `fmi3SetDebugLogging` x x x x x x `fmi3InstantiateXXX` x `fmi3FreeInstance` x x x x x x `fmi3SetupExperiment` x `fmi3EnterInitializationMode` x `fmi3ExitInitializationMode` x `fmi3Terminate` x x `fmi3Reset` x x x x x x `fmi3GetReal` 2 x x x 7 `fmi3GetInteger` 2 x x x 7 `fmi3GetBoolean` 2 x x x 7 `fmi3GetString` 2 x x x 7 `fmi3SetReal` 1 3 4 5 `fmi3SetInteger` 1 3 4 `fmi3SetBoolean` 1 3 4 `fmi3SetString` 1 3 4 `fmi3GetFMUState` x x x x x 7 `fmi3SetFMUState` x x x x x x `fmi3FreeFMUState` x x x x x x `fmi3SerializedFMUStateSize` x x x x x x `fmi3SerializeFMUState` x x x x x x `fmi3DeSerializeFMUState` x x x x x x `fmi3GetDirectionalDerivative` x x x x 7 x x x x x x x x x x x 7 x x x x 7 x x x x 7 x x x x 7

x means: call is allowed in the corresponding state
number means: call is allowed if the indicated condition holds:
1 for a variable with `variability` $\neq$ `constant` that has `initial` = `exact` or `approx`
2 for a variable with `causality` = `output`, or continuous-time states, state derivatives or event indicators, 3 for a variable with `variability` $\neq$ `constant` that has `initial` = `exact`, or `causality` = `input`
4 for a variable with `causality` = `input`, or (`causality` = `parameter` and `variability` = `tunable`)
5 for a variable with `causality` = `input` and `variability` = `continuous`
7 always, but retrieved values are usable for debugging only

#### 3.2.4. 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.

``````m = M_fmi3InstantiateModelExchange("m", "{8c4e810f-3da3-4a00-8276-176fa3c9f000}", NULL, fmi3False, fmi3False,
NULL, cb_logMessage, cb_allocateMemory, cb_freeMemory);
// "m" is the instance name
// "M_" is the MODEL_IDENTIFIER

// set the start time
time  = tStart;

// set all variable start values (of "ScalarVariable / <type> / start") and
// set the start values at time = Tstart
// M_fmi3SetReal/Integer/Boolean/String(m, ...)

// initialize
// determine continuous and discrete states
M_fmi3SetupExperiment(m, fmi3False, 0.0, tStart, fmi3True, tEnd);
M_fmi3EnterInitializationMode(m);
M_fmi3ExitInitializationMode(m);

initialEventMode = fmi3True;
enterEventMode   = fmi3False;
timeEvent        = fmi3False;
stateEvent       = fmi3False;

// initialize previous event indicators
M_fmi3GetEventIndicators(m, previous_z, nz);

M_fmi3EnterContinuousTimeMode(m);

// retrieve initial state x and
// nominal values of x (if absolute tolerance is needed)
M_fmi3GetContinuousStates(m, x, nx);
M_fmi3GetNominalsOfContinuousStates(m, x_nominal, nx);

// retrieve solution at t=Tstart, for example, for outputs
// M_fmi3SetFloat*/Int*/UInt*/Boolean/String/Binary(m, ...)

while (!terminateSimulation) {

tNext = time + h;

// handle events
if (enterEventMode || stateEvent || timeEvent) {
fmi3Boolean nextEventTimeDefined;
fmi3Float64 nextEventTime;

if (!initialEventMode) {
// TODO: pass rootsFound
M_fmi3EnterEventMode(m, fmi3False, fmi3False, NULL, 0, timeEvent);
}

// event iteration
newDiscreteStatesNeeded = fmi3True;
valuesOfContinuousStatesChanged   = fmi3False;
nominalsOfContinuousStatesChanged = fmi3False;

while (newDiscreteStatesNeeded) {
fmi3Boolean _nominalsOfContinuousStatesChanged;
fmi3Boolean _valuesOfContinuousStatesChanged;

// set inputs at super dense time point
// M_fmi3SetFloat*/Int*/UInt*/Boolean/String/Binary(m, ...)

// update discrete states
M_fmi3NewDiscreteStates(m,
&newDiscreteStatesNeeded,
&terminateSimulation,
&_nominalsOfContinuousStatesChanged,
&_valuesOfContinuousStatesChanged,
&nextEventTimeDefined,
&nextEventTime);

// getOutput at super dense time point
// M_fmi3GetFloat*/Int*/UInt*/Boolean/String/Binary(m, ...)
valuesOfContinuousStatesChanged |= _valuesOfContinuousStatesChanged;
nominalsOfContinuousStatesChanged |= _nominalsOfContinuousStatesChanged;

if (terminateSimulation) goto TERMINATE_MODEL;
}

// enter Continuous-Time Mode
M_fmi3EnterContinuousTimeMode(m);

// retrieve solution at simulation (re)start
// M_fmi3GetFloat*/Int*/UInt*/Boolean/String/Binary(m, ...)

if (initialEventMode || valuesOfContinuousStatesChanged) {
// the model signals a value change of states, retrieve them
M_fmi3GetContinuousStates(m, x, nx);
}

if (initialEventMode || nominalsOfContinuousStatesChanged) {
// the meaning of states has changed; retrieve new nominal values
M_fmi3GetNominalsOfContinuousStates(m, x_nominal, nx);
}

if (nextEventTimeDefined) {
tNext = min(nextEventTime, tEnd);
} else {
tNext = tEnd;
}

initialEventMode = fmi3False;
}

if (time >= tEnd) {
goto TERMINATE_MODEL;
}

// compute derivatives
M_fmi3GetDerivatives(m, der_x, nx);

h = min(dt, tNext - time);
time += h;
M_fmi3SetTime(m, time);

// set continuous inputs at t = time
// M_fmi3SetFloat*(m, ...)

// set states at t = time and perform one step
for (i = 0; i < nx; i++) {
x[i] += h * der_x[i]; // forward Euler method
}

M_fmi3SetContinuousStates(m, x, nx);

// get event indicators at t = time
M_fmi3GetEventIndicators(m, z, nz);

stateEvent = fmi3False;

for (i = 0; i < nz; i++) {
stateEvent |= sign(z[i]) != sign(previous_z[i]); // detect events
previous_z[i] = z[i]; // remember the current value
}

// inform the model about an accepted step
M_fmi3CompletedIntegratorStep(m, fmi3True, &enterEventMode, &terminateSimulation);

// get continuous output
// M_fmi3GetFloat*(m, ...)
}

TERMINATE_MODEL:

// terminate simulation and retrieve final values
M_fmi3Terminate(m);

// M_fmi3GetFloat*/Int*/UInt*/Boolean/String/Binary(m, ...)

// cleanup
M_fmi3FreeInstance(m);``````

In the code above, errors are not handled. Typically, `fmi3XXX` function calls are performed in the following way:

``````status = M_fmi3GetDerivatives(m, der_x, nx);

switch (status) {
// reduce step size and try again
break;
case fmi3Error:
// clean up and stop simulation
break;
case fmi3Fatal:
// stop using the model
break;
default:
break;
}``````

The switch statement could also be stored in a macro to simplify the code.

#### 3.2.5. Clocks API

Output Clocks

For a `output clock`, the environment integrates until a continuous-time event occurs and calls `fmi3EnterEventMode`. Afterwards with function call `fmi3GetClock` the `output clocks` that became active at this event instant can be inquired by the environment.

Input Clocks

Intervall is set with the function `fmi3SetIntervalDecimal` or `fmi3SetIntervalFraction`. It is activated by the environment with the function `fmi3SetClock`.

#### 3.2.6. Handling of clock events

A `clock` event is handled by the environment in the following way:

Enter event mode

The Event Mode is entered after initialization (call to function `fmi3ExitInitializationMode`) or during simulation with a call to the function `fmi3EnterEventMode`. The FMU activates `output clocks`.

Synchronize clock activation and intervals with the environment

The `clock` activation status can be inquired with the function `fmi3GetClock`. The environment calls the function `fmi3SetClock` for periodic `clocks` and `input clocks`. Moreover the current `clock` intervals may be inquired with the function `fmi3GetIntervalDecimal` or `fmi3GetIntervalFraction` and set with the function `fmi3SetIntervalDecimal` `fmi3SetIntervalFraction`. [In the Modelica language this is the value returned by the interval() operator. The initialization of intervals is needed for `output` and `input` sample times if a `clock` ticks the first time. The FMU determines the interval itself at subsequent `clock` ticks.]

Solve algebraic loops among discrete-time equations of multiple FMUs or repeated evaluation in model-based control applications (optional)

With the `fmi3Set{VariableType}` functions the `input` variables of the clocked partition can be set. If algebraic loops are present among clocked partitions of multiple FMUs, then with the `fmi3Get{VariableType}` functions all variables on the corresponding `clock` can be inquired. The latter function call triggers the evaluation of the discrete-time equations, provided the corresponding `clock` is active at this time instant. If the corresponding `clock` is not active, the last evaluated value of the variable is returned. Clocks are automatically deactivated if the corresponding discrete-time equations have been evaluated. Before a new loop iteration is started, the environment must activate the `clocks` again and reset discrete states using the `fmi3Set{VariableType}` functions.

Leave event mode

The function `fmi3NewDiscreteStates` evaluates the discrete-time equations, provided the corresponding `clock` is active and the discrete-time equations have not already been evaluated with calls to `fmi3Get{VariableType}` functions. Clocks are automatically deactivated by `fmi3NewDiscreteStates` and by `fmi3Reset`. [This handling of discrete `states` and time events is forward compatible with FMI 2.0 for any model that could be treated with FMI 2.0 and is exported again using the new features. The environment may ignore the new functions `fmi3SetClock`, `fmi3GetClock`, `fmi3SetIntervalDecimal`, `fmi3SetIntervalFraction`, `fmi3GetIntervalDecimal` and `fmi3GetIntervalFraction`. The new functions are needed for FMUs with input sample times and to set discrete-time `states` in model-based control applications or if algebraic loops are present among discrete-time equations of multiple connected FMUs.]

### 3.3. Description Schema

This is defined in Section 2.2. Additionally, the Model Exchange-specific element `<ModelExchange>` is defined in the next section.

#### 3.3.1. Model Exchange FMU (ModelExchange)

If the XML file defines an FMU for Model Exchange, element `<ModelExchange>` must be present. It is defined as:

The following attributes are defined (all of them are optional, with exception of `modelIdentifier`):

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.1.1.

`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>`.]

`completedIntegratorStepNotNeeded`

If `true`, function `fmi3CompletedIntegratorStep` need not be called (this gives a slightly more efficient integration). If it is called, it has no effect.
If `false` (the default), the function must be called after every completed integrator step, see Section 3.2.2.

`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).

`canNotUseMemoryManagementFunctions`

If `true`, the FMU uses its own functions for memory allocation and freeing only. The callback functions `allocateMemory` and `freeMemory` given in `fmi3InstantiateXXX` are ignored.

`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.

`providesDirectionalDerivative`

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

The flags have the following default values.

boolean: `false`
unsignedInt: 0

#### 3.3.2. 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-alpha.3"
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>
<Float64 name="Modelica.SIunits.Inertia" quantity="MomentOfInertia" unit="kg.m2" min="0.0"/>
<Float64 name="Modelica.SIunits.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.SIunits.Inertia" start="1"/>
<Float64 name="torque.tau" valueReference="536870912"
description="Accelerating torque acting at flange (= -flange.tau)" causality="input"
declaredType="Modelica.SIunits.Torque" start="0"/>
<Float64 name="inertia1.phi" valueReference="805306368"
description="Absolute rotation angle of component" causality="output"
declaredType="Modelica.SIunits.Angle"/>
<Float64 name="inertia1.w" valueReference="805306369"
description="Absolute angular velocity of component (= der(phi))" causality="output"
declaredType="Modelica.SIunits.AngularVelocity"/>
<Float64 name="x[1]" valueReference="0" initial="exact"/>
<Float64 name="x[2]" valueReference="1" initial="exact"/>
<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"/>
<Derivative valueReference="2"/>
<Derivative 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 Basic Co-Simulation

This chapter defines the Functional Mock-up Interface (FMI) for the coupling of two or more simulation models in a co-simulation environment (FMI for Basic Co-Simulation). It is designed both for coupling with subsystem models, which have been exported by their simulator together with its solver as runnable code (Figure 3), and for coupling of simulation tools on a single machine (Figure 4) or as part of a distributed co-simulation (Figure 5).

### 4.1. Mathematical Description

This section contains a formal mathematical model of Co-Simulation FMUs.

_[The following fundamental assumptions are made:

The slave simulators are seen by the master simulator as purely sampled-data systems.

Such a sampled-data system consists typically of a hybrid ODE that is integrated between communication points (known as "sampled access to time continuous systems") where internal events may occur and be handled, but events are not visible from the outside of the FMU. It is assumed here that all `inputs` and all `outputs` of this hybrid ODE are floating point signals (defined with `variability` = `continuous`),

Co-Simulation FMUs can also be used for real sampled-data systems (so a sampled discrete controller; the `inputs` and `outputs` could be of type `<Float{32|64}>`, `<[U]Int{8|16|32|64}>`, `<Boolean>`, `<String>`, `<Clock>` or `<Enumeration>` with `variability` = `discrete`.) However, in FMI 3.0, Hybrid Co-Simulation (HCS) and Scheduled Co-Simulation (SCS) may likely be more suitable for this use-case.]

The communication between the master and a slave takes only place at a discrete set of time instants, called communication points.

An FMI Co-Simulation model is described by the following variables:

Variable Description

$t$

Independent variable time $\in \mathbb{R}$. (Variable defined with `causality` = `independent`).
The i-th communication point is denoted as $t = tc_i$
The communication step size is denoted as $hc_i = tc_{i+1} - tc_i$

$\mathbf{v}$

A vector of all exposed variables (all variables defined in element `<ModelVariables>`, see Section 2.2.10). A subset of the variables is selected via a subscript. Example:
$\mathbf{v}_{initial=exact}$ are variables defined with attribute `initial` = `exact`, see Section 2.2.10. These are `independent` `parameters` and `start` values of other variables, such as initial values for `states`, state derivatives or outputs.

$\mathbf{p}$

Parameters that are constant during simulation. The symbol without a subscript references `independent` `parameters` (variables with `causality` = `parameter`). Dependent `parameters` (variables with `causality` = `calculatedParameter`) are denoted as $\mathbf{p}_{calculated}$ and `tunable` `parameters` (variables with `causality` = `parameter` and `variability` = `tunable`) are denoted as $\mathbf{p}_{tune}$.

$\mathbf{u}(tc_i)$

Input variables. The values of these variables are defined outside of the model. Variables of this type are defined with attribute `causality` = `input`. Whether the `input` is a discrete-time or continuous-time variable is defined via attribute `variability` = `discrete` or `continuous` (see Section 2.2.10).

$\mathbf{y}(tc_i)$

Output variables. The values of these variables are computed in the FMU and they are designed to be used in a model connection. So output variables might be used in the environment as input values to other FMUs or other submodels. Variables of this type are defined with attribute `causality` = `output`. Via attribute `variability` = `discrete` or `continuous` it is defined whether the `output` is a discrete-time or continuous-time variable, see Section 2.2.10.

$\mathbf{w}(tc_i)$

Local variables of the FMU that cannot be used for FMU connections. Variables of this type are defined with attribute `causality` = `local` (see Section 2.2.10).

$\mathbf{x}_c(t)$

A vector of floating point continuous-time variables representing the continuous-time `states`. For notational convenience, a continuous-time `state` is conceptually treated as a different type of variable as an `output` or a `local` variable for the mathematical description below. However, at a communication point, a continuous-time `state` is part of the `outputs` or the `local` variables $\mathbf{w}$ of an FMU.

$\mathbf{x}_d(t)$
$^{\bullet}\mathbf{x}_d(t)$

$\mathbf{x}_d(t)$ is a vector of (internal) discrete-time variables (of any type) representing the (internal) discrete `states`.
$^{\bullet}\mathbf{x}_d(t)$ is the value of $\mathbf{x}_d(t)$ at the previous sample time instant, so $^{\bullet}\mathbf{x}_d(t) = \mathbf{x}_d(^{\bullet}t)$.
Given the previous values of the discrete-time `states`, $^{\bullet}\mathbf{x}_d(t)$, at the actual time instant $t$, all other discrete-time variables, especially the discrete `states` $\mathbf{x}_d(t)$, can be computed.
Discrete `states` are not visible in the interface of an FMU and are only introduced here to clarify the mathematical description. Formally, a discrete `state` is part of the `outputs` $\mathbf{y}$ or the `local` variables $\mathbf{w}$ of an FMU.

When the transient simulation of the coupled system through Co-Simulation is completed, the sequence of evaluations is the following (here $\mathbf{x} = {\lbrack \mathbf{x}_c; \mathbf{x}_d \rbrack}^T$ is the combined vector of continuous-time and discrete-time states, and $\mathbf{y} = {\lbrack \mathbf{y}_c; \mathbf{y}_d \rbrack}^T$) is the combined vector of continuous-time and discrete-time `outputs`):

Sequence of Basic Co-Simulation evaluations
$\mathrm{\text{for}}\ i = 0, \cdots, n-1 \begin{Bmatrix} \mathbf{x}_{i+1} = \Phi_i \left( \mathbf{x}_i \left\{ \mathbf{u}_i^{(j)} \right\}_{j=0,\cdots,m_{ido}}, \mathbf{p}_{tune,i}, hc_i \right) \\ \left( \left\{ \mathbf{y}^{(j)}_{i+1} \right\}_{j=0,\cdots,m_{odo}}, \mathbf{w}_{i+1}\right) = \Gamma_i \left( \mathbf{x}_i, \left\{ \mathbf{u}^{(j)}_i \right\}_{j=0,\cdots,m_{ido}}, \mathbf{p}_{tune}, hc_i \right) \end{Bmatrix}$

where $\mathbf{\Phi}_i$ and $\mathbf{\Gamma}_i$ define the system behavior for the time interval $tc_i \leq t < tc_{i+1}$, with $tc_i = tc_0 + \sum_{k=0}^{i-1}hc_k$.

[For the part of the Co-Simulation slave that is based on an ODE, a differential equation is solved between communication points:

$\dot{\mathbf{x}}_c = \mathbf{\varphi} \left( \mathbf{x}_c(t), \mathbf{u}_c(t), \mathbf{p}_{tune} \right)$

In this case, the following relationship should hold (note the use of $\mathbf{x}_{i+1}$ here):

$\frac{\partial\mathbf{\Phi_i}}{\partial hc_i} = \boldsymbol{\varphi} \left( \mathbf{x}_{c,i+1}, \sum^{m_{ido}}_{j=0} \mathbf{u}^{(j)}_{c,i} \frac{hc^j_i}{j!}, \mathbf{p}_{tune,i} \right)$

This relation is in practice inexact due to using finite precision on machines and stopping iterations early. The slave simulators are responsible for implementing $\mathbf{\Phi}_i$ and $\mathbf{\Gamma}_i$ ; for example, to handle stiff differential equations as:

$\mathbf{\Phi}_i \left( \mathbf{x}_{c,i}, \left\{ \mathbf{u}_{c,i}^{(j)} \right\}_{= 0,\cdots,m_{ido}},\ \mathbf{p}_{tune,i}, tc_i \right) = \mathbf{x}_{ci} + \left( \mathbf{I} - hc_i \frac{\partial \mathbf{\varphi}}{\partial \mathbf{x}_c} \right)^{- 1} hc_i \mathbf{\phi} \left( \mathbf{x}_{c,i}, \mathbf{u}_{c,i}, \mathbf{p}_{tune,i} \right) + O(hc_i^{2}).$

]

Definition Sequence of Basic Co-Simulation evaluations is consistent with the definition of co-simulation by [KS00].

• At the communication points, the master provides generalized inputs to the slave, which can be:

• The slave provides generalized outputs to the master, which are:

• The current output variables $\mathbf{y}_{i+1}^{(0)}$of the subsystem (same remark as above), along with some of their successive `derivatives` $\left\{ \mathbf{y}_{i+1}^{(j)} \right\}_{j=1,\cdots,m_{odo}}$(in case of continuous-time variables).

• Observation variables and `calculated` varying `parameters` $\mathbf{w}_{i+1}$, along with directional derivatives estimated at $t = tc_{i+1}$ (in case of continuous-time variables).

• Initialization: The slave being a sampled-data system, its internal states (which can be either continuous-time or discrete-time) need to be initialized at $t = tc_0$. This is performed through an auxiliary function [this relationship is defined in the XML file under elements `<ModelStructure><InitialUnknown>`]:

Computing the solution of an FMI Co-Simulation model means to split the solution process in two phases and in every phase different equations and solution methods are utilized. The phases can be categorized according to the following modes:

#### 4.1.1. Initialization Mode

This mode is used to compute at the start time $t_0$ initial values for internal variables of the Co-Simulation slave, especially for continuous-time `states`, $\mathbf{x}_d(t_0)$, and for the previous discrete-time `states`, $^{\bullet}\mathbf{x}_d(t_0)$, by utilizing extra equations not present in the other mode [for example, equations to set all `derivatives` to zero, that is, to initialize in steady-state]. If the slave is connected in loops with other models, iterations over the FMU equations are possible. Algebraic equations are solved in this mode.

#### 4.1.2. Step Mode

This mode is used to compute the values of all continuous-time and discrete-time variables at communication points by numerically solving ordinary differential, algebraic and discrete equations. If the slave is connected in loops with other models, no iterations over the FMU equations are possible.

[Note that for a Co-Simulation FMU, no super-dense time description is used at communication points.]

The equations are defined in Table 2 can be evaluated in the respective mode. The following color coding is used in the table:

 grey If a variable in an argument list is marked in grey, then this variable is not changing in this mode and just the last calculated value from the previous mode is internally used. For an input argument it is not allowed to call `fmi3Set{VariableType}`. For an output argument, calling `fmi3Get{VariableType}` on such a variable returns always the same value in this mode. green Functions marked in green are special functions to enter or leave a mode. blue Equations and functions marked in blue define the actual computations to be performed in the respective mode.
Table 2. Mathematical description of an FMU for Basic Co-Simulation.
Equations FMI functions

Equations before Initialization Mode (Instantiated in state machine)

Set and set `start` value of `independent` variable $tc_{i=0}$

`fmi3SetupExperiment`

Set variables and that have a start value (`initial` = `exact` or `approx`)

`fmi3Set{VariableType}`

Equations during Initialization Mode (Initialization Mode in state machine)

Enter Initialization Mode at (activate initialization, discrete-time and continuous-time equations)

fmi3EnterInitializationMode

Set variables $v_{initial=exact}$ and $v_{initial=approx}$ that have a `start` value with `initial` = `exact` (`independent` `parameters` $\mathbf{p}$ and continuous-time `states` with start values $\mathbf{x}_{c,initial=exact}$ are included here)

`fmi3Set{VariableType}`

Set continuous-time and discrete-time `inputs` $\mathbf{u}_{c+d}(tc_0)$ and optionally the `derivatives` of continuous-time `inputs` $\mathbf{u}_{c}^{(j)}(tc_0)$

`fmi3Set{VariableType}`
`fmi3SetInputDerivatives`

$\mathbf{v}_{InitialUnknowns} := \mathbf{f}_{init}(\mathbf{u}_c, \mathbf{u}_d, t_0, \mathbf{v}_{initial=exact})$

`fmi3Get{VariableType}`
`fmi3GetDirectionalDerivative`

Exit Initialization Mode (de-activate initialization equations)

fmi3ExitInitializationMode

Equations during Step Mode (`stepComplete`, `stepInProgress` in state machine)

Set `independent` `tunable` `parameters` $\mathbf{p}_{tune}$ (and do not set other `parameters` $\mathbf{p}_{other}$)

`fmi3Set{VariableType}`

Set continuous-time and discrete-time `inputs` $\mathbf{u}_{d+c}(tc_i)$ and optionally the `derivatives` of continuous-time `inputs` $\mathbf{u}_{c}^{(j)}(tc_i)$

`fmi3Set{VariableType}`
`fmi3SetInputDerivatives`

$\begin{matrix} tc_{i+1} := tc_i + hc_i \\ (\mathbf{y}_{c+d}, \mathbf{y}_c^{(j)}, \mathbf{w}_{c+d}) := \mathbf{f}_{doStep}(\mathbf{u}_{c+d}, \mathbf{u}_{c}^{(j)}, tc_i, hc_i, \mathbf{p}_{tune}, \mathbf{p}_{other})_{tc_i} \\ tc_i := tc_{i+1} \end{matrix}$
$\mathbf{f}_{doStep}$ is also a function of the internal variables $\mathbf{x}_c$, $^{\bullet}\mathbf{x}_d$

`fmi3DoStep`
`fmi3Get{VariableType}`
`fmi3GetOutputDerivatives`
`fmi3GetDirectionalDerivative`

Data types

$t, tc, hc \in \mathbb{R}, \mathbf{p} \in \mathbb{P}^{np}, \mathbf{u}(tc) \in \mathbb{P}^{nu}, \mathbf{y}(tc) \in \mathbb{P}^{ny}, \mathbf{x}_c(t) \in \mathbb{R}^{nxc}, \mathbf{x}_d(t) \in \mathbb{P}^{nxd}, \mathbf{w}(tc) \in \mathbb{P}^{nw}$
$\mathbb{R}$: floating point variable, $\mathbb{R}$: floating point or Boolean or integer or enumeration or string variable
$\mathbf{f}_{init}, \mathbf{f}_{out} \in C^0$ (=continuous functions with respect to all input arguments inside the respective mode).

[Remark - Calling Sequences:

In the table above, for notational convenience in Initialization Mode one function call is defined to compute all output arguments from all inputs arguments. In reality, every variable output argument is computed by one `fmi3Get{VariableType}` function call.

In Step Mode the input arguments to $\mathbf{f}_{doStep}$ are defined by calls to `fmi3Set{VariableType}` and `fmi3SetInputDerivatives` functions. The variables computed by $\mathbf{f}_{doStep}$ can be inquired by `fmi3Get{VariableType}` function calls.]

#### 4.1.3. Early Return from Current Communication Step

In the particular context of multi-FMU architectures, significant co-simulation speed-up may be obtained if the master can avoid waiting until the end of the slowest FMU step integration. If an FMU prematurely stops its current step integration computation due to an unpredictable internal event before the normal end of the step calculation, all other concurrently running FMUs may be stopped as soon as possible in order to minimize the time needed for the Co-Simulation master to resynchronize all the FMUs at the same event time.

In this context based on parallel multi-FMU calculations, the following figure illustrates different possibilities to synchronize FMUs at the same event time.

Figure 12: Different possibilities to synchronize parallel FMUs at the same event time.

Each FMU starts integration from communication point $t_{i}$ to reach the next communication point $t_{i+1}$. Assuming an unexpected internal event is detected at $t^{'}_{i+1}< t_{i+1}$ during FMU1 integration, the master is informed of this early return. So now the master would like to avoid other FMUs exceed the event time, since all FMUs should be resynchronized at the event time which will be the next new communication point.

• In the case of FMU1, the internal event time becomes the new $t_{i+1}$ time, i.e. this is the source of the event.

• In the case of FMU2, a complete rollback from $t_{i}$ to $t^{'}_{i+1}$ is necessary.

• In the case of FMU3, computation is immediately interrupted and only a partial rollback is necessary to reach $t^{'}_{i+1}$ time.

• In the case of FMU4, the current step integration has been interrupted at $t^{'}_{i+1}$ and no rollback is necessary.

Each ongoing FMU stops its integration either exactly at the broken time given by the master or immediately after its current intermediate step if this time is already out-of-date. Afterwards, a new step integration done on the FMU returns and signals the premature stop (early-return) to the master.

Due to the early-return mechanism, the overall execution time of the simulation is reduced.

### 4.2. Application Programming Interface

This section contains the interface description to access the input/output data and status information of a Co-Simulation slave from a C program.

#### 4.2.1. Variables access in Co-Simulation interface types

`Input` and `output` variables and other variables are accessed via the `fmi3Get{VariableType}` and `fmi3Set{VariableType}` functions, defined in Section 2.1.7.

In order to enable the slave to interpolate the `continuous` floating point `inputs` between communication steps, the `derivatives` of the `inputs` with respect to time can be provided. Also, higher `derivatives` can be set to allow higher order interpolation. Whether the slave is able to handle the `derivatives` of `inputs` is given by the unsigned integer capability flag `MaxInputDerivativeOrder`. It delivers the maximum order of the input `derivative`.

``````typedef fmi3Status fmi3SetInputDerivativesTYPE(fmi3Instance instance,
const fmi3ValueReference valueReferences[],
size_t nValueReferences,
const fmi3Int32 orders[],
const fmi3Float64 values[],
size_t nValues);``````
``````typedef fmi3Status fmi3GetOutputDerivativesTYPE(fmi3Instance instance,
const fmi3ValueReference valueReferences[],
size_t nValueReferences,
const fmi3Int32 orders[],
fmi3Float64 values[],
size_t nValues);``````

Both functions have the same arguments:

• Argument `valueReferences[]` is a vector of value references that define the variables whose `derivatives` shall be set or get.

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

• Argument `orders[]` contains the orders of the respective `derivative` (1 means the first `derivative`, 0 is not allowed).

• Argument `values[]` is a vector with the values of the `derivatives`.

• Argument `nValues` is the size of the argument `values[]`.

`fmi3SetInputDerivatives`

Sets the n-th time `derivative` of `input` variables. Restrictions on using the function are the same as for the `fmi3Set{VariableType}` function. Different input variables may have different interpolation order. `Inputs` and their `derivatives` are set with respect to the beginning of a communication time step.

`fmi3GetOutputDerivatives`

Retrieves the n-th `derivative` of `output` values. Restrictions on using the function are the same as for the `fmi3Get{VariableType}` function. The returned `outputs` correspond to the current slave time. E.g. after a successful call to `fmi3DoStep` the returned values are related to the end of the communication time step.

To allow interpolation/approximation of the floating point output variables between communication steps (if they are used as inputs for other slaves), the `derivatives` of the `outputs` with respect to time can be read. Whether the slave is able to provide the `derivatives` of `output` is given by the unsigned integer capability flag `maxOutputDerivativeOrder`. It delivers 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.

[Example: If the internal polynomial is of order 1 and the master inquires the second `derivative` of an `output`, the slave will return zero.]

#### 4.2.2. Computation in Co-Simulation interface types

The computation of time steps is controlled by the following function.

``````typedef fmi3Status fmi3DoStepTYPE(fmi3Instance instance,
fmi3Float64 currentCommunicationPoint,
fmi3Float64 communicationStepSize,
fmi3Boolean noSetFMUStatePriorToCurrentPoint,
fmi3Boolean* earlyReturn);``````

The computation of a time step is started.

• Argument `currentCommunicationPoint` is the current communication point of the master ($tc_i$) and

• argument `communicationStepSize` is the communication step size ($hc_i$). `comunicationStepSize` must be $> 0.0$.

• Argument `noSetFMUStatePriorToCurrentPoint` is `fmi3True` if `fmi3SetFMUState` will no longer be called for time instants prior to `currentCommunicationPoint` in this simulation run. [The slave can use this flag to flush a result buffer]

• Argument `earlyReturn` signals to the Co-Simulation master if the FMU returns early from the `doStep` call (`earlyReturn = fmi3True`) or if the `doStep` was completed successfully (`earlyReturn = fmi3False`).

The slave must integrate until time instant $tc_{i+1} = tc_i + hc_i$.

[The calling environment defines the communication points and `fmi3DoStep` must synchronize to these points by always integrating exactly to $tc_i + hc_i$. It is up to `fmi3DoStep` how to achieve this.]

At the first call to `fmi3DoStep` after `fmi3ExitInitializationMode` was called `currentCommunicationPoint` must be equal to `startTime` as set with `fmi3SetupExperiment`.

[Formally, argument `currentCommunicationPoint` is not needed. It is present in order to handle a mismatch between the master and the FMU state of the slave: The `currentCommunicationPoint` and the FMU state of the slaves defined by former `fmi3DoStep` or `fmi3SetFMUState` calls have to be consistent with respect to each other. For example, if the slave does not use the update formula for the `independent` variable as required above, $tc_{i+1} = tc_i + hc_i$ (using argument $tc_i$ = `currentCommunicationPoint` of `fmi3DoStep`) but uses internally an own update formula, such as $tc_{s,i+1} = tc_{s,i} + hc_{s,i}$ then the slave could use as time increment $\text{hc}_{s,i} := (tc_i - tc_{s,i}) + hc_i$ (instead of $\text{hc}_{s,i} := hc_i$ ) to avoid a mismatch between the master time $tc_{i+1}$ and the slave internal time $tc_{s,i+1}$ for large i.]

The function returns:

`fmi3OK`

if the communication step was computed successfully until its end.

`fmi3Discard`

if the slave computed successfully only a subinterval of the communication step. The FMU enters the `Step Discarded` state, see Section 4.2.4.9 for more information.

`fmi3Error`

the communication step could not be carried out at all. The master can try to repeat the step with other input values and/or a different communication step size in the same way as described in the `fmi3Discard` case above.

`fmi3Fatal`

if an error occurred which corrupted the FMU irreparably. See Section 2.1.3 for details. [The master should stop the simulation run immediately.]

It depends on the capabilities of the slave which parameter constellations and calling sequences are allowed (see Section 4).

#### 4.2.3. Retrieving Status Information from the Slave in Co-Simulation Interface Types

``````typedef fmi3Status fmi3GetDoStepDiscardedStatusTYPE(fmi3Instance instance,
fmi3Boolean* terminate,
fmi3Float64* lastSuccessfulTime);``````
• If argument `terminate = true`, the slave wants to terminate the simulation.

• Argument `lastSuccessfulTime` is the time instant at which the slave stopped the `fmi3DoStep` call.

#### 4.2.4. State Machine of Calling Sequence from Master to Slave in Co-Simulation Interface Types

The following state machine defines the supported calling sequences.

Figure 12. Calling sequence of Co-Simulation C functions in form of an UML 2.0 state machine.
##### 4.2.4.1. State: Slave Setable FMU State

If any function returns with `fmi3Fatal` the FMU enters the terminal state.

##### 4.2.4.2. State: Slave Under Evaluation

This super state is entered by the FMU when `fmi3InstantiateXXX` is called. If any function returns `fmi3Error` the FMU enters state Terminated.

##### 4.2.4.3. State: Slave Initialized

This super state is entered by the FMU when `fmi3ExitInitializationMode` is called. If the function `fmi3Terminate` is called, the FMU enters state Terminated.

##### 4.2.4.4. State: Instantiated

In this state the FMU can do one-time initializations and allocate memory. The FMU sets all variables to its `start` values.

Allowed Function Calls
`fmi3Set{VariableType}`

For variables with `variability` $\neq$ `constant` and for which `initial` = `exact` or `approx`. The intention is to set `start` and guess values for these variables.

Forbidden Function Calls
##### 4.2.4.5. State: Initialization Mode

This mode is used by the master to compute consistent initial conditions for overall system. Therefore iterative calls of `fmi3Set{VariableType}` and `fmi3Get{VariableType}` are allowed. In between the FMU must evaluate all relevant equations. In this way artificial or real algebraic loops over connected FMUs in Initialization Mode may be handled by using appropriate numerical algorithms.

Allowed Function Calls
`fmi3Set{VariableType}`

For variables with:

`fmi3Get{VariableType}`

For variables with `causality` = `output` or continuous-time `states` or state derivatives.

Forbidden Function Calls
##### 4.2.4.6. State: Step Mode

This state is used by the master to progress simulation time.

Allowed Function Calls

`fmi3SetInputDerivatives`, `fmi3GetDirectionalDerivative`, `fmi3GetOutputDerivatives`, `fmi3Get{VariableType}`, `fmi3Terminate`

`fmi3EnterConfigurationMode`

With this function call the Reconfiguration Mode is entered. This function must not be called if the FMU contains no `tunable` `structural parameters` (i.e. with `causality`= `structuralParameter` and `variability` = `tunable`).

`fmi3DoStep`

Within `fmi3DoStep` the FMU may call `fmi3CallbackIntermediateUpdate`

• If the function returns with `fmi3OK` or `fmi3Warning` the FMU stays in this state.

• If the function returns with `fmi3Discard` the FMU enters state Step Discarded.

`fmi3Set{VariableType}`

For variables with:

It is not allowed to call `fmi3Get{VariableType}` functions after `fmi3Set{VariableType}` functions without an `fmi3DoStep` call in between.

[The reason is to avoid different interpretations of the caching, since contrary to FMI for Model Exchange, `fmi3DoStep` will perform the actual calculation instead of `fmi3Get{VariableType}`, and therefore, dummy algebraic loops at communication points cannot be handled by an appropriate sequence of `fmi3Get{VariableType}` and, `fmi3Set{VariableType}` calls as for Model Exchange.

Examples:

Correct calling sequence Wrong calling sequence

fmi3Set{VariableType} on inputs
fmi3DoStep
fmi3Get{VariableType} on outputs
fmi3Set{VariableType} on inputs
fmi3DoStep
fmi3Get{VariableType} on outputs

fmi3Set{VariableType} on inputs
fmi3DoStep
fmi3Get{VariableType} on outputs
fmi3Set{VariableType} on inputs
fmi3Get{VariableType} on outputs // not allowed
fmi3DoStep
fmi3Get{VariableType} on outputs

]

##### 4.2.4.7. State: Intermediate Update Mode

In this state the master can retrieve information from the FMU between communication points. Functions called in this state must not return `fmi3Discard`.

The FMU enters this state by calling `fmi3CallbackIntermediateUpdate` within `fmi3DoStep` and leaves the state towards state Step Mode if the function returns `fmi3OK` or `fmi3Warning`. If the function returns `fmi3Error` the FMU enters state Terminated. If the function returns `fmi3Fatal` the FMU enters the terminal state.

Allowed Function Calls

`fmi3DoEarlyReturn`

`fmi3Set{VariableType}`, `fmi3SetInputDerivatives`

If `intermediateVariableSetAllowed = fmi3True`, the value of intermediate variables can be set. Intermediate variables are variables that are marked with attribute `intermediateAccess` = `true` in the `modelDescription.xml`.

`fmi3Get{VariableType}`, `fmi3GetOutputDerivatives`

If `intermediateVariableGetAllowed = fmi3True`, the value of intermediate variables can be retrieved. Intermediate variables are variables that are marked with attribute `intermediateAccess` = `true` in the `modelDescription.xml`.

Forbidden Function Calls

The same functions which are not allowed to be called in Step Mode must not be called in this state. Additionally the following functions must not be called `fmi3EnterConfigurationMode`, `fmi3Terminate`, `fmi3DoStep`, `fmi3GetDirectionalDerivative`.

##### 4.2.4.8. State: Reconfiguration Mode

In this state `structural parameters` with `variability` = `tunable` can be changed. This state is entered from state Step Mode by calling `fmi3EnterConfigurationMode` and left back to Step Mode by calling `fmi3ExitConfigurationMode`.

Allowed Function Calls

`fmi3ExitConfigurationMode`

`fmi3Set{VariableType}`

Only for variables with `causality` = `structuralParameter` and `variability` = `tunable`.

Forbidden Function Calls

The FMU changes into this state if it is not able to compute a communication step completely by returning `fmi3Discard` from `fmi3DoStep`. This might have been caused by numerical problems or intended stop of the simulation run. The master can call `fmi3GetDoStepDiscardedStatus` to get further information. In case of numerical problems the master may try to achieve a correct solution for example by repeating the last step with a different communication step size. [Redoing a step is only possible if the FMU state has been recorded at the beginning of the current (discarded) step with `fmi3GetFMUState`. Redoing a step is performed by calling `fmi3SetFMUState` and afterwards calling `fmi3DoStep` with the new communicationStepSize. Note that it is not possible to change `currentCommunicationPoint` in such a call.] The master can also continue from the `lastSuccessfulTime`. It does not enter into this state if the FMU returns early from a communication step caused by `fmi3DoEarlyReturn`.

Allowed Function Calls

`fmi3Terminate`, `fmi3Get{VariableType}`, `fmi3GetDirectionalDerivative`, `fmi3GetOutputDerivatives`, `fmi3SetFMUState`

`fmi3GetDoStepDiscardedStatus`

The master calls this functions to retrieve information about the reason for discarding the last communication step.

`fmi3EnterStepMode`

The `fmi3EnterStepMode` function pushes the FMU from Step Discarded to Step Mode. [In Step Mode, the master may change again FMU `inputs` and `parameters`, or push the FMU into other states] In this case, a new step may be started from `lastSuccessfulTime` which can be retrieved by the `fmi3GetDoStepDiscardedStatus` function in state Step Discarded.

Forbidden Function Calls
##### 4.2.4.10. State: Terminated

In this state, the solution at the final time of the simulation can be retrieved.

Allowed Function Calls

`fmi3Get{VariableType}`, `fmi3GetDirectionalDerivative`, `fmi3GetOutputDerivatives`

Forbidden Function Calls
##### 4.2.4.11. State: Configuration Mode

This state is entered from state Instantiated by calling `fmi3EnterConfigurationMode` and left back to Instantiated by calling `fmi3ExitConfigurationMode`.

Allowed Function Calls

`fmi3ExitConfigurationMode`

`fmi3Set{VariableType}`

Only for variables with `causality` = `structuralParameter` and `variability` = `tunable`.

Forbidden Function Calls

"yellow" are only available for Co-Simulation, the other functions are available both for Model Exchange and Co-Simulation):

 Function FMI 3.0 for Co-Simulation Start, End Instantiated Initialization Mode StepComplete StepInProgress StepDiscarded StepCanceled Terminated Error `fmi3GetVersion` x x x x x x x x x `fmi3SetDebugLogging` x x x x x x x x `fmi3InstantiateXXX` x `fmi3FreeInstance` x x x x x x x `fmi3SetupExperiment` x `fmi3EnterInitializationMode` x `fmi3ExitInitializationMode` x `fmi3Terminate` x x `fmi3Reset` x x x x x x x `fmi3GetReal` 2 x 8 7 x 7 `fmi3GetInteger` 2 x 8 7 x 7 `fmi3GetBoolean` 2 x 8 7 x 7 `fmi3GetString` 2 x 8 7 x 7 `fmi3SetReal` 1 3 6 `fmi3SetInteger` 1 3 6 `fmi3SetBoolean` 1 3 6 `fmi3SetString` 1 3 6 `fmi3GetFMUState` x x x 8 7 x 7 `fmi3SetFMUState` x x x x x x x `fmi3FreeFMUState` x x x x x x x `fmi3SerializedFMUStateSize` x x x x x x x `fmi3SerializeFMUState` x x x x x x x `fmi3DeSerializeFMUState` x x x x x x x `fmi3GetDirectionalDerivative` x x 8 7 x 7 x x x x 8 x x 7 x x x x

x means: call is allowed in the corresponding state
number means: call is allowed if the indicated condition holds:
1 for a variable with `variability` $\neq$ `constant` that has `initial` = `exact` or `approx`
2 for a variable with `causality` = `output` or continuous-time states or state derivatives (if element `<ModelStructure><Derivative>` is present)
3 for a variable with `variability` $\neq$ `constant` that has `initial` = `exact`, or `causality` = `input`
6 for a variable with `causality` = `input` or (`causality` = `parameter` and `variability` = `tunable`)
7 always, but retrieved values are usable for debugging only
8 always, but if status is other than `fmi3Terminated`, retrieved values are usable for debugging only ]_

#### 4.2.5. Code Example for Basic 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 slaves, where both have one `continuous` floating point `input` and one `continuous` floating point `output` which are connected in the following way:

Figure 13. Connection graph of the slaves.

We assume no algebraic dependency between input and `output` of each slave. The code demonstrates the simplest master algorithm as shown in Section 4.1:

1. Constant communication step size.

2. No repeating of communication steps.

3. The slaves do not support asynchronous execution of `fmi3DoStep`.

The error handling is implemented in a very rudimentary way.

``````////////////////////////////
// Initialization sub-phase

// instantiate both slaves
s1 = s1_fmi3InstantiateBasicCoSimulation("slave1", guid, NULL, fmi3False, fmi3False, fmi3False, fmi3False, fmi3False,
NULL, cb_logMessage, cb_allocateMemory, cb_freeMemory, NULL);
s2 = s2_fmi3InstantiateBasicCoSimulation("slave2", guid, NULL, fmi3False, fmi3False, fmi3False, fmi3False, fmi3False,
NULL, cb_logMessage, cb_allocateMemory, cb_freeMemory, NULL);

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 slaves
s1_fmi3SetupExperiment(s1, fmi3False, 0.0, startTime, fmi3True, stopTime);
s2_fmi3SetupExperiment(s2, fmi3False, 0.0, startTime, fmi3True, stopTime);

s1_fmi3EnterInitializationMode(s1);
s2_fmi3EnterInitializationMode(s2);

// 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 master 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 slave s1 and check status
status = s1_fmi3DoStep(s1, tc, h, fmi3True, NULL);

switch (status) {
printf("Slave s1 wants to terminate simulation.");
case fmi3Error:
case fmi3Fatal:
terminateSimulation = true;
break;
default:
break;
}

if (terminateSimulation)
break;

// call slave s2 and check status as above
status = s2_fmi3DoStep(s2, tc, h, fmi3True, NULL);

// ...

// increment master 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.2.6. Early-return Requested by the Co-Simulation Master in Co-Simulation Interface Types

The Boolean capability flag `canReturnEarlyAfterIntermediateUpdate` in the modelDescription XML file indicates whether the FMU supports the early-return feature. The default value of this capability flag is `false`. Each time an internal discontinuity or an event happens inside an FMU with capability flag `canReturnEarlyAfterIntermediateUpdate = true`, the callback function `fmi3CallbackIntermediateUpdate` is invoked by the FMU. The master can only use this early return functionality if it provides the `fmi3CallbackIntermediateUpdate` callback function pointer in the instantiate function.

``````typedef fmi3Status (*fmi3CallbackIntermediateUpdate) (
fmi3InstanceEnvironment instanceEnvironment,
fmi3Float64 intermediateUpdateTime,
fmi3Boolean eventOccurred,
fmi3Boolean clocksTicked,
fmi3Boolean intermediateVariableSetAllowed,
fmi3Boolean intermediateVariableGetAllowed,
fmi3Boolean intermediateStepFinished,
fmi3Boolean canReturnEarly);``````

The Co-Simulation master can request the FMU to end the `fmi3DoStep` at a Newtonian time instant and to do an early return by calling the `fmi3DoEarlyReturn` function inside the callback function `fmi3CallbackIntermediateUpdate`. The Co-Simulation master is only allowed to call this function, if `canReturnEarly = fmi3True`. If the master does not call `fmi3DoEarlyReturn` the FMU continues the `fmi3DoStep` computation until the next predefined communication instant (i.e., `currentCommunicationPoint + communicationStepSize`) or until the next call of `fmi3CallbackIntermediateUpdate`.

``typedef fmi3Status fmi3DoEarlyReturnTYPE(fmi3Instance instance, fmi3Float64 earlyReturnTime);``

The FMU should return early from the current `fmi3DoStep` at the time instant defined by parameter `earlyReturnTime`.

If the `earlyReturnTime` is greater than the last signaled `intermediateUpdateTime`, the FMU may integrate up to the time instant `earlyReturnTime`.

If the early return is conducted successfully by the FMU it must set the parameter `earlyReturn` to `fmi3True` in `fmi3DoStep` and return `fmi3OK`. In that case the internal simulation time of the FMU equals the value of `earlyReturnTime` of the last `fmi3DoEarlyReturn` call.

If the requested `earlyReturnTime` is less than the last signaled `intermediateUpdateTime` or the FMU can not reach the requested `earlyReturnTime` for other reasons, the FMU must set the parameter `earlyReturn` to `fmi3True` in `fmi3DoStep` and return `fmi3Discard` and enter state Step Discarded.

In state Step Discarded the Co-Simulation master can retrieve the `lastSuccessfulTime` via calling `fmi3GetDoStepDiscardedStatus`. The Co-Simulation master can decide if a rollback of the FMU to reach the `earlyReturnTime` time is required or it may continue the simulation from `lastSuccessfulTime` for that FMU. Note that Event Mode is not supported in Basic Co-Simulation and Scheduled Co-Simulation.

### 4.3. Description Schema

This is defined in Section 2.2. Additionally, the Co-Simulation specific element `Implementation` is defined in the next section.

If the XML file defines an FMU for Basic Co-Simulation, element `BasicCoSimulation` must be present. It is defined as:

These attributes have the following meaning (all attributes are optional with exception of `modelIdentifier`):

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.1.1.

`needsExecutionTool`

If `true`, a tool is needed to execute the model. The FMU just contains the communication to this tool (see Figure 4). [Typically, this information is only utilized for information purposes. For example, a Co-Simulation master can inform the user that a tool has to be available on the computer where the slave is instantiated. The name of the tool can be taken from the attribute `generationTool` in `<fmiModelDescription>`.]

`canBeInstantiatedOnlyOncePerProcess`

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

`canNotUseMemoryManagementFunctions`

If `true`, the slave uses its own functions for memory allocation and freeing only. The callback functions `allocateMemory` and `freeMemory` given in `fmi3InstantiateXXX` are ignored.

`canGetAndSetFMUState`

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

`canSerializeFMUState`

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

`providesDirectionalDerivative`

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

`canInterpolateInputs`

The slave is able to interpolate `continuous` `inputs`. Calling of `fmi3SetInputDerivatives` has an effect for the slave.

`maxOutputDerivativeOrder`

The slave is able to provide `derivatives` of `outputs` with maximum order. Calling of `fmi3GetOutputDerivatives` is allowed up to the order defined by `maxOutputDerivativeOrder`.

`canHandleVariableCommunicationStepSize`

The slave can handle variable communication step size. The communication step size (parameter communicationStepSize of `fmi3DoStep`) has not to be constant for each call.

`providesIntermediateVariableAccess`

The slave is able to provide access to selected variables during callback function call `intermediateUpdate`. The accessible variables are marked with attribute `intermediateAccess` = `true`.

`canReturnEarlyAfterIntermediateUpdate`

If `true`, the slave is able to return early from `fmi3DoStep` if master calls `fmi3DoEarlyReturn` during callback function call `intermediateUpdate` and `canReturnEarly = true` in `fmi3CallbackIntermediateUpdate`. [If set to `true` and `providesHybridCoSimulation` is set to `false`, the FMU supports the basic functionality of ending DoSteps before the planned next communication point time. This is controlled by the simulation master for avoiding unnecessary computations and roll backs of the FMU due to external events known by the simulation master]

`providesHybridCoSimulation`

If `true`, the slave can be set to Hybrid Co-Simulation during instantiation of FMU. If set to `true` also `canReturnEarlyAfterIntermediateUpdate` must be set to `true`.

`providesScheduledCoSimulation`

If `true`, the slave can instantiated as Scheduled Co-Simulation.

`canNotUseBasicCoSimulation`

If `false`, the slave can be set to Basic Co-Simulation during instantiation of the FMU. [The support of Basic Co-Simulation should be possible for most Co-Simulation FMUs, thus the default value is `false`.]

`fixedInternalStepSize`

The fixed internal step size of the FMU (optional). [This information can be used by the co-simulation master to synchronize the communication interval with the internal step size of the FMU. The co-simulation master 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.]

The flags have the following default values.
boolean: `false`
unsignedInt: `0`

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 slave is completely contained inside the FMU in source code or binary format (DLL/SharedObject).

#### 4.3.1. Example XML Description File

The example below is the same as shown in Section 3.3.2 for a Model Exchange FMU. The only difference is the replacement of the element `<ModelExchange>` with the element `<BasicCoSimulation>` (with additional attributes) and the removal of `local` variables, which are associated with continuous `states` and their `derivatives`. The XML file may have the following content:

``````<?xml version="1.0" encoding="UTF-8"?>
<fmiModelDescription
fmiVersion="3.0-alpha.3"
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">
<BasicCoSimulation
modelIdentifier="MyLibrary_SpringMassDamper"
canHandleVariableCommunicationStepSize="true"
canInterpolateInputs="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>
<Float64 name="Modelica.SIunits.Inertia" quantity="MomentOfInertia" unit="kg.m2" min="0.0"/>
<Float64 name="Modelica.SIunits.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.SIunits.Inertia" start="1"/>
<Float64 name="torque.tau" valueReference="536870912"
description="Accelerating torque acting at flange (= -flange.tau)" causality="input"
declaredType="Modelica.SIunits.Torque" start="0"/>
<Float64 name="inertia1.phi" valueReference="805306368"
description="Absolute rotation angle of component" causality="output"
declaredType="Modelica.SIunits.Angle"/>
<Float64 name="inertia1.w" valueReference="805306369"
description="Absolute angular velocity of component (= der(phi))" causality="output"
declaredType="Modelica.SIunits.AngularVelocity"/>
</ModelVariables>
<ModelStructure>
<Output valueReference="805306368"/>
<Output valueReference="805306369"/>
<InitialUnknown valueReference="805306368"/>
<InitialUnknown valueReference="805306369"/>
</ModelStructure>
</fmiModelDescription>``````

#### 4.3.2. Early Return from Current Communication Step

The simulation master collects the information about the capability of an FMU to perform an early return by analyzing the `modelDescription.xml` as defined in section Section 2.2 and Section 4.

##### 4.3.2.1. Co-Simulation FMU

In order to support the early return in `fmi3DoStep` the capability flag `canReturnEarlyAfterIntermediateUpdate` in the XML should be `true`.

##### 4.3.2.2. Example XML Description File

Here is an example of an XML of an FMU supporting early return.

``````<?xml version="1.0" encoding="utf-8"?>
<fmiModelDescription
fmiVersion="3.0-alpha.3"
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">
<BasicCoSimulation
modelIdentifier="MyLibrary_SpringMassDamper"
canHandleVariableCommunicationStepSize="true"
canReturnEarlyAfterIntermediateUpdate="true"/>
<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.SIunits.Inertia" start="1"/>
<Float64 name="torque.tau" valueReference="536870912"
description="Accelerating torque acting at flange (= -flange.tau)" causality="input"
declaredType="Modelica.SIunits.Torque" start="0"/>
<Float64 name="inertia1.phi" valueReference="805306368"
description="Absolute rotation angle of component" causality="output"
declaredType="Modelica.SIunits.Angle"/>
<Float64 name="inertia1.w" valueReference="805306369"
description="Absolute angular velocity of component (= der(phi))" causality="output"
declaredType="Modelica.SIunits.AngularVelocity"/>
</ModelVariables>
<ModelStructure>
<Output valueReference="805306368"/>
<Output valueReference="805306369"/>
<InitialUnknown valueReference="805306368"/>
<InitialUnknown valueReference="805306369"/>
</ModelStructure>
</fmiModelDescription>``````

## 5. FMI for Hybrid Co-Simulation

The notion of `clock` in FMI for Model Exchange has been extended to the FMI for Co-Simulation.

Both `output clocks` and `input clocks` are supported in Co-Simulation with `clocks`. In order to handle `input` and `output clocks` in Co-Simulation, a new Event Mode has been introduced.

The concept and the way `input` and `output clocks` are handled are very similar in Model Exchange and Co-Simulation. In order to handle `input clocks`, the Co-Simulation master schedules `input clocks` and adjusts the communication steps in such a way that `input clock` ticks become communication points. At these communication points, the FMU is pushed to the Event Mode and `input clocks` are handled.

`Output clocks`, on the other hand, are detected by the FMU. The FMU detects an `output clock` and informs the master by invoking a callback in which the event time and the event type is communicated to the master. Then FMU stops the current Co-Simulation step and returns back from `fmi3DoStep`. Then the FMU is pushed to the Event Mode and the event is handled. Note that, since output events time instants are not known in advance, at output event time instants, new communication steps are created.

### 5.2. Application Programming Interface

If the Boolean capability flag `providesHybridCoSimulation` and `canReturnEarlyAfterIntermediateUpdate = true` the Co-Simulation master can use the interface type Hybrid Co-Simulation.

#### 5.2.1. Communication of event time and input/output values

The `fmi3CallbackIntermediateUpdate` callback described in section Section 4.2.6 is also used in order to communicate the `input` and `output` and, in particular, the event and `clock` time from the FMU to the Co-Simulation master. The `fmi3CallbackIntermediateUpdate` callback allows internal events (e.g. associated to `output clock` ticks) to be signaled from an FMU to the Co-Simulation master. If the interface type is Hybrid Co-Simulation, the `fmi3CallbackIntermediateUpdate` callback must be defined in the instantiate function. In other cases a NULL pointer can be assigned to the `fmi3CallbackIntermediateUpdate` callback, for instance when the interface type is Model Exchange.

The output arguments of `fmi3CallbackIntermediateUpdate` are used to signal `output clock` ticks and internal events to the master.

``````typedef fmi3Status (*fmi3CallbackIntermediateUpdate) (
fmi3InstanceEnvironment instanceEnvironment,
fmi3Float64 intermediateUpdateTime,
fmi3Boolean eventOccurred,
fmi3Boolean clocksTicked,
fmi3Boolean intermediateVariableSetAllowed,
fmi3Boolean intermediateVariableGetAllowed,
fmi3Boolean intermediateStepFinished,
fmi3Boolean canReturnEarly);``````
• Argument `intermediateUpdateTime` is the internal simulation time of the FMU at which the callback has been called. If an event happens or a `output clock` ticks, `intermediateUpdateTime` is the time of event or `output clock` tick. If the FMU signals an `earlyReturn = fmi3True` and `fmi3OK` after returning from `fmi3DoStep` then `intermediateUpdateTime` is the internal simulation time of the FMU of the last `fmi3CallbackIntermediateUpdate` call that signaled `canReturnEarly = fmi3true`. `intermediateUpdateTime` is also the time of intermediate steps of the internal FMU solver.

The following `fmi3Boolean` variables define the reasons for the `fmi3CallbackIntermediateUpdate` call. Several variables can be set by the FMU. Default value of variables is `fmi3False`.

• When argument `eventOccurred` is `fmi3True`, the master must call `fmi3DoEarlyReturn` to do an early return and handle the event via entering Event Mode. In this case, `earlyReturnTime` argument of `fmi3DoEarlyReturn` is ignored. In Event Mode the master shall call the `fmi3NewDiscreteStates` function for gathering related information about the event that occurred at `intermediateUpdateTime`.

• When argument `clocksTicked` is `fmi3True`, it means that `fmi3GetClock` function should be called for gathering all `clock` related information about ticking `output clocks` at `intermediateUpdateTime`. If this flag is `fmi3True` the master must call `fmi3DoEarlyReturn` to do an early return and handle the `clock` event in Event Mode. In this case, `earlyReturnTime` argument of `fmi3DoEarlyReturn` is ignored.

• When argument `intermediateVariableSetAllowed` is `fmi3True`, the FMU signals that intermediate output values can be collected by the Co-Simulation master.

• When argument `intermediateVariableGetAllowed` is `fmi3True`, the FMU signals that intermediate input values can be set by the Co-Simulation master.

• When argument `intermediateStepFinished` is `fmi3True`, the FMU signals that the internal solver step for this time instant is complete.

• When argument `canReturnEarly` is `fmi3True` the master can request the FMU to return early at the current `intermediateUpdateTime` time instant via calling `fmi3DoEarlyReturn` within the callback function `fmi3CallbackIntermediateUpdate`. If `canReturnEarly` is `fmi3False` the FMU will not do the early return, regardless of the master request.

Note that only the first discontinuity event at a Newtonian time instant shall be signaled that way. But in Event Mode, there may be an event iteration at a Newtonian time instant and have super-dense time instants.

Based on the information provided by `fmi3CallbackIntermediateUpdate`, additional information about the discontinuity at that time instant can be obtained by calling `fmi3NewDiscreteStates` and `fmi3GetClock`.

The FMU must not call the callback function `fmi3CallbackIntermediateUpdate` with an `intermediateUpdateTime` that is smaller than the `intermediateUpdateTime` given in a previous call of `fmi3CallbackIntermediateUpdate` with `intermediateStepFinished = fmi3True`.

#### 5.2.2. Handling a Successful Early-Return by the Co-Simulation Master in Hybrid Co-Simulation

If the FMU is successful in conducting an early return, the return value of the `earlyReturn` argument in `fmi3DoStep` is `fmi3True`, otherwise `fmi3False`. If the FMU returns from `fmi3DoStep` with the `earlyReturn = fmi3True` the Co-Simulation master has to call `fmi3EnterEventMode` for that FMU.

``````typedef fmi3Status fmi3EnterEventModeTYPE(fmi3Instance instance,
fmi3Boolean inputEvent,
fmi3Boolean stepEvent,
const fmi3Int32 rootsFound[],
size_t nEventIndicators,
fmi3Boolean timeEvent);``````

The Co-Simulation master can also call `fmi3EnterEventMode` at communication instants to handle input events, as will be discussed in following sections.

If an FMU provides the early-return capability that includes the handling of events in Event Mode, the FMU signals this via `canReturnEarlyAfterIntermediateUpdate` and `providesHybridCoSimulation = true` in the `modelDescription.xml`. The master should indicate to the FMU that this early-return feature is also supported by the master. The Co-Simulation master signals to the FMU that it supports and has recognized the early return Co-Simulation capabilities of the FMU by calling the Co-Simulation interface type instantiate function `fmi3InstantiateHybridCoSimulation`.

The FMU stops computation at the first encountered internal event (if any) and the event time is provided through `intermediateUpdateTime`. If `fmi3DoStep` returns with `earlyReturn = fmi3True` and an event has happened, i.e. `eventOccurred = fmi3True`, then an event handling has to be done by the Co-Simulation master. In order to start event handling the Co-Simulation master has to call `fmi3EnterEventMode` for that FMU to push the FMU into Event Mode. In this mode the Co-Simulation master is supposed to catch all events through the `fmi3NewDiscreteStates` function.

If the early-return request of the Co-Simulation master is ignored by the FMU, then `fmi3DoStep` returns with `earlyReturn = fmi3False`. The master can start a resynchronization of FMUs at an event time, if the `currentCommunicationPoint` has passed the event time, the master can roll-back the FMU and repeat the step with a suitable `communicationStepSize` (if the FMU supports the roll-back).

In Event Mode and only after `fmi3DoStep` returned with `earlyReturn = fmi3True` the function `fmi3NewDiscreteStates` may be called. Only the following output arguments may be considered:

• When `newDiscreteStatesNeeded = true`, the master should stay in Event Mode and another call to `fmi3NewDiscreteStates` is required.

• When `nextEventTimeDefined = fmi3True`, an event time is available and the value is given by `nextEventTime`. This is the case when the model can report in advance the accurate time of the next predictable time event.

• When `terminateSimulation = fmi3True`, the model requested to stop integration and the Co-Simulation master should call `fmi3Terminate`.

In Event Mode it is allowed to call `fmi3Get{VariableType}` after `fmi3NewDiscreteStates` has been called and it is allowed to call `fmi3Set{VariableType}` before calling `fmi3NewDiscreteStates`. The FMU leaves Event Mode when the master calls `fmi3EnterStepMode`.

It is not allowed to call `fmi3EnterEventMode` or `fmi3EnterStepMode` for an FMU with interface type Basic Co-Simulation and Scheduled Co-Simulation.

#### 5.2.3. Co-Simulation with Clock Support in Hybrid Co-Simulation

In this section, signaling and retrieving `clock` ticks as well as the interface for supporting `clocks` in FMI for Co-Simulation will be discussed. If an FMU for Co-Simulation declares `clocks` and clocked variables in the `modelDescription.xml` file, it supports `clocks`. The Co-Simulation master should indicate the FMU that the master has recognized the `clock` capabilities of the FMU and supports the `clock` handling by calling the Hybrid Co-Simulation interface instantiation function `fmi3InstantiateHybridCoSimulation`. Note, even if no `clock` is defined by an FMU in `modelDescription.xml`, the master can instantiate a Hybrid Co-Simulation FMU to be able to use early return with event handling in Event Mode.

If an FMU provides `clocks`, but the Co-Simulation master does not support or does not want to support early-return or `clocks`, by setting the interface to Hybrid Co-Simulation, the activation of model partitions inside of the FMU has to be handled internally within `fmi3DoStep`.

[Remark: Wrapping towards other Co-Simulation interfaces can influence the simulation results. Depending on the model especially wrapping towards Hybrid Co-Simulation may result in divergent simulation results. Especially aperiodic `input clocks` can not always be sufficiently emulated in modes that do not directly support `clocks`. Therefore it is recommended that the FMU provides logging information to the user about the influence of the current mode on simulation results, if non-optimal modes are used by the simulation environment.]

``typedef fmi3Status fmi3EnterStepModeTYPE(fmi3Instance instance);``
##### 5.2.3.1. Transfer of Input / Output Values and Parameters in Hybrid Co-Simulation

If the Co-Simulation master supports `clocks`, all `input clocks` of the model should be handled and `input clock` events should be scheduled by the master. If an `output clock` ticks, the FMU calls `fmi3CallbackIntermediateUpdate` with `clocksTicked = fmi3True`. Then the master must call `fmi3DoEarlyReturn` to do an early return from `fmi3DoStep` and push the FMU into Event Mode by calling `fmi3EnterEventMode`. Once the FMU is in Event Mode, the activation status of `output clocks` are retrieved by `fmi3GetClock` function. Then `fmi3SetClock` (and `fmi3SetIntervalDecimal` or `fmi3SetIntervalFraction` if necessary) should be invoked to enable the ticked `input clocks`. Each `clock`, that ticks outside of the FMU (i.e. `input clock`), is activated for an FMU based on its `clockReference` and an associated `fmi3SetClock` in Event Mode. `fmi3SetClock` can activate multiple `clocks` with each call. An event iteration is possible. Once all `clock` events are handled for this time instant, the FMU should be pushed into Step Mode by calling `fmi3EnterStepMode`. In Step Mode, the Co-Simulation master can call `fmi3DoStep` for the time interval from the current event time instant until the next input event instant. Note that `fmi3DoStep` may not reach the next input event instant because an early return may occur.

The simulation master sets and gets `clock` variable values similar to the FMI for Model Exchange, as defined in Section 2.1.9.

##### 5.2.3.2. Computation in Hybrid Co-Simulation

Similar to FMI for Model Exchange, in order to activate `input clocks` of an FMU, it is required to push the FMU into Event Mode by calling `fmi3EnterEventMode`. If `fmi3DoStep` returns with `earlyReturn = fmi3True` and `eventOccurred = fmi3True` or `clocksTicked = fmi3True`, the FMU must be pushed into the Event Mode by calling `fmi3EnterEventMode`.

In order to retrieve the status of `output clocks`, `fmi3GetClock` and `fmi3GetIntervalDecimal` or `fmi3GetIntervalFraction` need to be called in the Event Mode. If the `fmi3DoStep` return value is `fmi3OK` and `earlyReturn = fmi3False`, the calling of `fmi3GetClock`, `fmi3GetIntervalDecimal`, `fmi3GetIntervalFraction`, `fmi3NewDiscreteStates` is only meaningful after `fmi3SetClock` in the case of super-dense time iterations are desired.

Similar to the Model Exchange case, the allowed call order is `fmi3GetClock`, `fmi3GetIntervalDecimal`, `fmi3GetIntervalFraction`, `fmi3Get{VariableType}`, `fmi3Set{VariableType}`. Function calls of this call order can be omitted.

The handling of return values of function calls is identical to Basic Co-Simulation.

If `terminateSimulation` becomes `fmi3True` after calling `fmi3NewDiscreteStates` then the co-simulation should be terminated by calling `fmi3Terminate`. Once handling of the `clock` events finished, the master calls `fmi3EnterStepMode` for that FMU to push it into Step Mode. Note that it is not allowed to call `fmi3EnterEventMode` or `fmi3EnterStepMode` in Basic and Scheduled Co-Simulation.

[Usually the Co-Simulation master should be able to derive (but is not forced to do so) the correct communication point times for `input clocks` in advance and thus it should be able to set the proper `communicationStepSize` for `fmi3DoStep`. This might not be possible if an aperiodic `input clock` of an FMU depends on the ticking of an aperiodic `output clock` of another FMU or other aperiodic tick sources.]

#### 5.2.4. State Machine of Calling Sequence from Master to Slave in Hybrid Co-Simulation

The following state machine defines the supported calling sequences.

Figure 14. Calling sequence of Hybrid Co-Simulation interface.

In this Co-Simulation interface the following functions must not be called: `fmi3ActivateModelPartition` including all functions that are specific to Model Exchange.

Unlike the state machine in section Section 4.2.4 the entry state after Initialization Mode is the Event Mode in order to allow the FMU to handle the very first discrete event. Each state of the state machine corresponds to a certain phase of a simulation as follows:

##### 5.2.4.1. State: Slave Setable FMU State

This super state in Hybrid Co-Simulation does not differ from Basic Co-Simulation described in section Section 4.2.4.1.

##### 5.2.4.2. State: Slave Under Evaluation

This super state in Hybrid Co-Simulation does not differ from Basic Co-Simulation described in section Section 4.2.4.2.

##### 5.2.4.3. State: Slave Initialized

This super state in Hybrid Co-Simulation does not differ from Basic Co-Simulation described in section Section 4.2.4.3.

##### 5.2.4.4. State: Instantiated

This super state in Hybrid Co-Simulation does not differ from Basic Co-Simulation described in section Section 4.2.4.4.

##### 5.2.4.5. State: Configuration Mode

This state in Hybrid Co-Simulation does not differ from Basic Co-Simulation described in section Section 4.2.4.11.

##### 5.2.4.6. State: Initialization Mode

This state in Hybrid Co-Simulation does not differ from Basic Co-Simulation described in section Section 4.2.4.5.

##### 5.2.4.7. State: Event Mode

The master and the FMU enter this state when the master calls `fmi3ExitInitializationMode` in state Initialization Mode or `fmi3ExitConfigurationMode` in state Reconfiguration Mode or `fmi3EnterEventMode` in state Step Mode. In order to handle discrete events and `clock` ticks, the FMU is pushed into the Event Mode by calling `fmi3EnterEventMode`

Allowed Function Calls
`fmi3Terminate`

Upon return of `fmi3NewDiscreteStates`, if `terminateSimulation = fmi3True`, the master should finish the Co-Simulation by calling `fmi3Terminate` on all FMU instances.

`fmi3EnterConfigurationMode`

With this function call the Reconfiguration Mode is entered. This function must not be called if the FMU contains no `tunable` `structural parameters` (i.e. with `causality` = `structuralParameter` and `variability` = `tunable`).

`fmi3NewDiscreteStates`

In order to handle discrete events `fmi3NewDiscreteStates` is called. When the output argument `newDiscreteStatesNeeded = fmi3True`, the FMU should stay in Event Mode and another call to `fmi3NewDiscreteStates` is required.

`fmi3EnterStepMode`

Once all events are handled and `newDiscreteStatesNeeded = fmi3False`, the FMU should be pushed to Step Mode by calling `fmi3EnterStepMode`, unless it requests to terminate the Co-Simulation by setting `terminateSimulation` to `fmi3True`. In this case, a new step can be started from the current communication point time.

`fmi3GetClock`

The status of `clocks` can be inquired by this function.

`fmi3SetClock`

For `input clocks`, `fmi3SetClock` is called after entering Event Mode to set the activation status of `clocks`. For both `input` and trigerred `clocks`, this function can be called several times, only if recomputations of clock state are needed during Event Mode.

`fmi3GetIntervalDecimal` & `fmi3GetIntervalFraction`

For both `output clocks` and `input clocks` it is allowed to call these functions during Event Mode.

`fmi3SetIntervalDecimal` & `fmi3SetIntervalFraction`

It is not allowed to call these functions for `output`, aperiodic and strictly periodic `clocks`. For `input` periodic `clocks`, these functions are called after the first `clock` activaion.

##### 5.2.4.8. State: Step Mode

This state in Hybrid Co-Simulation does not differ from Basic Co-Simulation described in section Section 4.2.4.6.

##### 5.2.4.9. State: Intermediate Update Mode

This state in Hybrid Co-Simulation differ from Basic Co-Simulation described in section Section 4.2.4.6 as following:

Allowed Function Calls
`fmi3DoEarlyReturn`

If `canReturnEarly = fmi3True`, the Co-Simulation master can request the FMU to end the `fmi3DoStep` and to do an early return by calling this function.

Forbidden Function Calls

All API functions not listed in the allowed function list, including `fmi3GetClock` and `fmi3SetClock` are forbidden in this mode.

##### 5.2.4.10. State: Reconfiguration Mode

This state in Hybrid Co-Simulation does not differ from Basic Co-Simulation described in section Section 4.2.4.8.

This state in Hybrid Co-Simulation does not differ from Basic Co-Simulation described in section Section 4.2.4.9.

##### 5.2.4.12. State: Terminated

This state in Hybrid Co-Simulation does not differ from Basic Co-Simulation described in section Section 4.2.4.10.

"yellow" are only available for Co-Simulation, the other functions are available both for Model Exchange and Co-Simulation):

 Function FMI 3.0 for Co-Simulation start, end Instantiated Configuration Mode Initialization Mode Event Mode Reconfiguration Mode Step Mode stepComplete stepInProgress Step Discarded Intermediate Update Mode stepCanceled Terminated error `fmi3GetVersion` x x x x x x x x x `fmi3SetDebugLogging` x x x x x x x x `fmi3InstantiateXXX` x `fmi3FreeInstance` x x x x x x x `fmi3SetupExperiment` x `fmi3EnterInitializationMode` x `fmi3ExitInitializationMode` x `fmi3Terminate` x x `fmi3Reset` x x x x x x x `fmi3GetReal` 2 x 8 7 x 7 `fmi3GetInteger` 2 x 8 7 x 7 `fmi3GetBoolean` 2 x 8 7 x 7 `fmi3GetString` 2 x 8 7 x 7 `fmi3SetReal` 1 3 6 `fmi3SetInteger` 1 3 6 `fmi3SetBoolean` 1 3 6 `fmi3SetString` 1 3 6 `fmi3GetFMUState` x x x 8 7 x 7 `fmi3SetFMUState` x x x x x x x `fmi3FreeFMUState` x x x x x x x `fmi3SerializedFMUStateSize` x x x x x x x `fmi3SerializeFMUState` x x x x x x x `fmi3DeSerializeFMUState` x x x x x x x `fmi3GetDirectionalDerivative` x x 8 7 x 7 x x x x 8 x x 7 x x x

]

#### 5.2.5. Code Example for Hybrid 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 …​

The error handling is implemented in a very rudimentary way.

``````  //////////////////////////
// Initialization sub-phase

fmi3EventInfo s_eventInfo;

// Set callback functions
callbacks.logMessage          = cb_logMessage;
callbacks.allocateMemory      = cb_allocateMemory;
callbacks.freeMemory          = cb_freeMemory;
// Signal that early return is supported by master
callbacks.intermediateUpdate  = cb_intermediateUpdate;
callbacks.lockPreemption      = NULL; // Preemption not active
callbacks.unlockPreemption    = NULL; // Preemption not active

// Instantiate slave
// Create pointer to information for identifying the FMU in callbacks
callbacks.instanceEnvironment = NULL;

//set Co-Simulation mode
fmi3CoSimulationConfiguration coSimulationConfiguration;
coSimulationConfiguration.intermediateVariableGetRequired         = fmi3False;
coSimulationConfiguration.intermediateInternalVariableGetRequired = fmi3False;
coSimulationConfiguration.intermediateVariableSetRequired         = fmi3False;
coSimulationConfiguration.coSimulationMode                        = fmi3ModeHybridCoSimulation;

// Instantiate slave
s = fmi3Instantiate("Slave", fmi3CoSimulation, s_GUID, NULL, &callbacks, fmi3False, fmi3True, &coSimulationConfiguration); // [TODO]: resourceLocation --> NULL?

if (s == NULL) return EXIT_FAILURE; // error

// Configuration Mode
//fmi3EnterConfigurationMode(s);
//fmi3ExitConfigurationMode(s);

// Setup Experiment
// Start and stop time
startTime = 0;
stopTime  = 10;
// Communication constant step size
h = 0.01;

// Set all variable start values (of "ScalarVariable / <type> / start")
//fmi3SetReal / Integer / Boolean / String(s, ...); // [TODO]: To be set.
//fmi3SetClock(s, ...); // [TODO]: To be set.

fmi3SetupExperiment(s, fmi3False, 0.0, startTime, fmi3True, stopTime);

// Initialization Mode
fmi3EnterInitializationMode(s);

// Set the input values at time = startTime
//fmi3SetReal / Integer / Boolean / String(s, ...); // [TODO]: To be set.
//fmi3SetClock(s, ...); // [TODO]: To be set.

fmi3ExitInitializationMode(s);

//////////////////////////
// Simulation sub-phase
tc = startTime; // Starting master time
tStop = stopTime; // Stopping master time
step = h; // Starting non-zero step size
inferredClocksTickedS = fmi3False; // [TODO]: To be set.

mode = eventMode; // [TODO]: @Masoud recheck: continuousTimeMode --> eventMode

while (tc < tStop) {
if (0 /* Inferred clock is active at current time tc */) { // [TODO]: To be set.
/*Set possible active inferred clocks to true or to false*/
if(mode == stepMode) { // [TODO]: @Masoud recheck: continuousTimeMode --> stepMode
status = fmi3EnterEventMode(s);
if ((status == fmi3Fatal) || (status == fmi3Error)) break;
mode = eventMode;
};
//fmi3SetClock(s, ...); // [TODO]: To be set.
//fmi3SetIntervalDecimal(s, ...); /*Only needed if interval changes*/ // [TODO]: To be set.
//fmi3SetIntervalFraction(s, ...); /*Only needed if interval changes*/ // [TODO]: To be set.
};

if (mode == eventMode) {
status = fmi3NewDiscreteStates(s, &s_eventInfo);
if ((status == fmi3Fatal) || (status == fmi3Error)) break;
}

if(mode == stepMode) { // [TODO]: @Masoud recheck: continuousTimeMode --> stepMode
// Step Mode (default mode)
tend = tc+step;
t = tend*2;
earlyReturn = fmi3False;
status = fmi3DoStep(s, tc, step, fmi3False, &earlyReturn); // [TODO]: noSetFMUStatePriorToCurrentPoint == fmi3False?

switch (status) {
if (discard == fmi3True) printf("Slave s wants to terminate simulation.");
case fmi3Error:
case fmi3Fatal:
terminateSimulation = fmi3True;
break;
default:
break;
}

if (terminateSimulation) break;

if(earlyReturn) {
t = s_intermediateUpdateInfo.intermediateUpdateTime;
/*rollback FMUs to earliest event time*/
fmi3EnterEventMode(s);
if ((status == fmi3Fatal) || (status == fmi3Error)) break;
mode = eventMode;
tc = t;
}
else{
tc = tend;
};
};

if(s_intermediateUpdateInfo.clocksTicked) {
//fmi3GetClock(s, ...); // [TODO]: To be set.
//fmi3GetIntervalDecimal(s, /*Intervals*/,...); // [TODO]: To be set.
//fmi3GetIntervalFraction(s, /*Intervals*/,...); // [TODO]: To be set.
};

if((mode == eventMode) && (s_eventInfo.newDiscreteStatesNeeded == fmi3False) && (1 /*no clocks from GetClock() are active*/)) { // [TODO]: To be set.
status = fmi3EnterStepMode(s); // [TODO]: @Masoud recheck: EnterContinuousTimeMode --> fmi3EnterStepMode
if ((status == fmi3Fatal) || (status == fmi3Error)) break;
mode = stepMode;
//step = min(/*Intervals*/, s_eventInfo.nextEventTime); // [TODO]: To be set.
};

// Get outputs
//fmi3GetReal/Integer/Boolean/String(s, ...); // [TODO]: To be set.
// Set inputs
//fmi3SetReal/Integer/Boolean/String(s, ...); // [TODO]: To be set.

}

//////////////////////////
// Shutdown sub-phase
if ((status != fmi3Error) && (status != fmi3Fatal)) {
fmi3Terminate(s);
}

if (status != fmi3Fatal) {
fmi3FreeInstance(s);
}``````

### 5.3. Description Schema

The Co-Simulation master collects the information about the number and properties of `clocks` supported by the FMU by analyzing the `modelDescription.xml`, see [clock-type-definition].

The definition of `clocks` is optional.

Each `input clock` that ticks outside of the FMU, is activated for an FMU based on their `valueReference`. `Output clocks` inside of an FMU signal their activation based on their `valueReference``.

[If `dependencies` (`fmi3Unknown`) are defined in the `<ModelStructure>` section of the `modelDescription.xml`, it is recommended to define such `dependencies` only within a model partition of a model (i.e. between variables that are assigned to the same `clock`).]

If `dependencies` are defined for variables across model partitions, such variables can not be assigned to a `clock` via `clockReference`.

For FMI for Co-Simulation, variables that are assigned to a model partition of the model based on `clockReference` are not necessarily `clocked`. Such variables can be continuous-time or discrete-time variables if the `clock` is of `clockType = communicationPoint`.

#### 5.3.1. Capability Flags

If the XML file defines an FMU for Hybrid Co-Simulation, element `CoSimulation` must be present as described in section Section 4.

In order to provide a Hybrid Co-Simulation, the attribute `providesHybridCoSimulation` has set to be set to `true`.

#### 5.3.2. Example XML Description File

The example below is the same one as shown in Section 4.3.1 for a Co-Simulation FMU. The only differences are, that `providesHybridCoSimulation` is set to `true` and `clocks` are defined in the `modelDescription.xml`. [TODO]: Recheck later The XML file may have the following content:

``//include::examples/co_simulation_clocked_cosimulation.xml[]``

## 6. FMI for Scheduled Co-Simulation

### 6.1. Mathematical Description

The Scheduled Co-Simulation interface has a different timing concept compared to the other two Co-Simulation interfaces. This is required to cover `clock` ticks for aperiodic `input clocks` which may tick at time instances that are not predictable in advance for the simulation master. Typically, hardware I/O or virtual ECU software events belong to this category.

A Co-Simulation master’s call for computing a model partition will compute the results of the model partition defined by an `input clock` for the current `clock` tick time $t_i$.

The result values will be computed for the current `clock` tick time (activation time) $t_i$ from the assigned `input clock` (which is known to the Co-Simulation master). Refer to the `clock` time progress definition (Section 2.1.8.1) for periodic `clocks`.

If required, the FMU can internally derive the `clock` interval $\Delta T_i$ based on the last `clock` tick time $t_{i-1}$ i.e. last activation time for this model partition.

A model partition can only be activated once per activation time point $t_i$.

Model partitions that are associated to `output clocks` will accordingly provide the result values of the model partition’s variables for the current `output clock` tick time $t_i$ of the active `output clock`. The activation of such a `output clock` is not directly controlled by the Co-Simulation master but internally by the FMU.

### 6.2. Application Programming Interface

This section contains the interface description for supporting the Scheduled Co-Simulation interface from 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 flag `providesScheduledCoSimulation = true`. The Co-Simulation master signals to the FMU that it supports and has recognized the `clock` and model partition scheduling capabilities of the FMU by instantiating it as Scheduled Co-Simulation.

If the flag `providesScheduledCoSimulation = false`, it is not allowed to use the Scheduled Co-Simulation interface.

If no `input clocks` are defined by the FMU it is not allowed to set `providesScheduledCoSimulation` to `true` in the `modelDescription.xml`.

Error, reset or terminate information is a global state of the FMU. If e.g. an 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.

#### 6.2.1. Transfer of Input / Output Values and Parameters in Scheduled Co-Simulation

The simulation master sets and gets variable values as defined in section Section 2.1.7.

Before scheduling a model partition it is allowed to set all variables assigned to that model partition via its associated `clock` (including all global variables that are not associated to a `clock`) via `fmi3Set{VariableType}`. After the computation of a model partition (call of `fmi3ActivateModelPartition` with the `clockReference` of the `clock` that is associated to the model partition) all variables that are assigned to this model partition (including all global variables that are not associated to a `clock`) can be retrieved via `fmi3Get{VariableType}`. Set/get operations have to be atomic for a single variable.

[The value of global variables can be influenced by more than one model partition if multiple model partitions are active at the same time.]

The computational effort has to be predictable, thus all computationally expensive operations needed to calculate a model partition have to be contained within the `fmi3ActivateModelPartition` function. The simulation master can assume that `fmi3Get{VariableType} and fmi3Set{VariableType}` operations are not computationally expensive. In Scheduled Co-Simulation the handling of `fmi3CallbackIntermediateUpdate` callbacks is the same as in section Section 5. The only difference is that an early return has no meaning in this mode and no additional event handling based on `fmi3NewDiscreteStates` is conducted. All internal events that shall be handled by the Co-Simulation master are signaled via `fmi3CallbackIntermediateUpdate`. [In this mode it is recommended to restrict such updates by the FMU to `output clock` ticks for reducing the computational load in real-time simulations.]

#### 6.2.2. Computation in Scheduled Co-Simulation

If this mode is set, the master has to directly control the time of computation of model partitions associated to `input clocks`. The activation states of `output clocks` are transported via `fmi3CallbackIntermediateUpdate` and `fmi3GetClock`.

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,
fmi3Float64 activationTime);``````

The `fmi3ActivateModelPartition` function has the following parameters:

Scheduling of `fmi3ActivateModelPartition` calls for each FMU is done by the simulation master. Calls are based on ticks of periodic or aperiodic `input clocks`. These `input clock` ticks can be based on `clock` ticks from FMU external sources (e.g. `output clocks` of other FMUs) or other external `clocks`/events/interrupts assigned via the simulation master configuration (such external events can be based on a potentially unpredictable process or can be just simulation time based events e.g. the planned communication point). The `fmi3ActivateModelPartition` function is not called for `output clocks` of an FMU.

The value for the `fmi3ActivateModelPartition` parameter `activationTime` is the `clock` tick time $t_i$ from the assigned `input clock` (which is known to the Co-Simulation master).

This is a different timing concept compared to `fmi3DoStep` calls. A `fmi3ActivateModelPartition` call will compute the results of the model partition defined by `clockReference` (i.e. `valueReference` of the variable that defines a `clock`) for the current `clock` tick $t_i$.

The value for the `fmi3ActivateModelPartition` parameter `activationTime` is the `clock` tick time $t_i$ from the assigned `input clock` (which is known to the Co-Simulation master). Refer to the `clock` time progress definition (Section 2.1.8.1) for periodic `clocks`.

If required, the FMU can internally derive the `clock` interval $\Delta T_i$ based on the last `clock` tick time $t_{i-1}$ i.e. last activationTime for this `clockReference` (based on last `fmi3ActivateModelPartition` call).

It is not allowed to call `fmi3ActivateModelPartition` for a `clockReference` (i.e. `valueReference` of `clock` variable) more than once for the same activationTime $t_i$.

#### 6.2.3. State Machine for Scheduled Co-Simulation

This section summarizes the available states and the allowed function calls in the respective states. All states must not be entered or exited concurrently for model partitions of an FMU but only for the whole FMU instance.

Figure 10: Calling sequence of Scheduled Co-Simulation.

The states Configuration Mode, Instantiated, Initialization Mode, and Terminated are handled in the same way as in Co-Simulation, with the exception that the generally not allowed functions of Scheduled Co-Simulation must not be called.

##### 6.2.3.1. State: Slave Settable FMU State

In all states of this super state it is allowed to call `fmi3GetFMUState`, `fmi3SetFMUState`, `fmi3FreeFMUState`, `fmi3SerializedFMUStateSize`, `fmi3SerializeFMUState`, `fmi3DeSerializeFMUState`, `fmi3Reset`, `fmi3GetVersion`, `fmi3SetDebugLogging` and `fmi3FreeInstance`.

If any function returns with `fmi3Fatal` the FMU enters the terminal state.

##### 6.2.3.2. State: Slave Under Evaluation

This super state is entered by the FMU when `fmi3InstantiateXXX` is called. If any function returns `fmi3Error` or `fmi3Discard` the FMU enters state Terminated.

##### 6.2.3.3. State: Slave Initialized

This super state is entered by the FMU when `fmi3ExitInitializatoinMode` is called. If the function `fmi3Terminate` is called, the FMU enters state Terminated from all states of this super state. 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 `output clock` ticks) and all other function calls for this FMU must return `fmi3Error` until the state Terminated is reached.

##### 6.2.3.4. State: Clock Activation Mode

The FMU enters this state when the master calls `fmi3ExitInitializationMode` in state Initialization Mode or `fmi3ExitConfigurationMode` in state Reconfiguration Mode. In this state the master can create multiple concurrent tasks related to an FMU and in each task the master can activate one or multiple `input clocks` of an FMU based on the defined `clock` properties via a `fmi3ActivateModelPartition` call for each `clock`.

Allowed Function Calls
`fmi3ActivateModelPartition`

If the function returns with `fmi3OK` or `fmi3Warning` the FMU stays in this state. In case of `fmi3Fatal` the master can prematurely end all tasks related to the computation of model partitions of this FMU. In case of `fmi3Discard` or `fmi3Error` the master must wait until all other tasks related to the computation of model partitions of this FMU have ended, but no new tasks can be started (e.g. related to `output clock` tick) and all other function calls for this FMU must also return `fmi3Discard` or `fmi3Error` until the state Terminated is reached.

It is recommended to call `fmi3Set{VariableType}` and `fmi3Get{VariableType}` in the same task as `fmi3ActivateModelPartition` for setting and retrieving variable values associated to a `clock` activation.

fmi3Set{VariableType}, `fmi3SetInputDerivatives`

Is called before the start of the computation of a model partition (i.e. before call of `fmi3ActivateModelPartition`) and only for global variables and variables associated to the `input clock` assigned to the model partition.

The restrictions related to variable `causality` and `variability` defined for Step Mode in Basic Co-Simulation apply.

If the function returns with `fmi3OK` or `fmi3Warning` the FMU stays in this state. In case the function returns `fmi3Fatal` the master can prematurely end all tasks related to the computation of model partitions of this FMU. In case the function returns `fmi3Discard` or `fmi3Error` the master must wait until all other tasks related to the computation of the model partitions of this FMU have ended, but new tasks must not be started (e.g. related to `output clock` ticks) and all other function calls for this FMU must also return `fmi3Discard` or `fmi3Error` until the state Terminated is reached.

fmi3Get{VariableType}, `fmi3GetOutputDerivatives`, `fmi3GetDirectionalDerivative``

Is called after the end of the computation of a model partition (i.e. after return of `fmi3ActivateModelPartition`) and only for global variables and variables associated to the `input clock` assigned to the model partition.

The restrictions related to variable `causality` and `variability` defined for Step Mode in Basic Co-Simulation apply.

If the function returns with `fmi3OK` or `fmi3Warning` the FMU stays in this state. In case the function returns `fmi3Fatal` the master can prematurely end all tasks related to the computation of model partitions of this FMU. In case the function returns `fmi3Discard` or `fmi3Error` the master must wait until all other tasks related to the computation of model partitions of this FMU have ended, but new tasks must not be started (e.g. related to `output clock` ticks) and all other function calls for this FMU have to also return `fmi3Discard` or `fmi3Error` until the state Terminated is reached.

It is not allowed to call `fmi3Get{VariableType}` functions after `fmi3Set{VariableType}` functions without an `fmi3ActivateModelPartition` call in between.

[The reason is to avoid different interpretations of the caching, since contrary to FMI for Model Exchange, `fmi3DoStep` will perform the actual calculation instead of `fmi3Get{VariableType}`, and therefore, dummy algebraic loops at communication points cannot be handled by an appropriate sequence of `fmi3Get{VariableType}` and, `fmi3Set{VariableType}` calls as for Model Exchange.

Example:

Correct calling sequence for a model partition of an FMU Wrong calling sequence

fmi3Set{VariableType} on inputs
fmi3ActivateModelPartition
fmi3Get{VariableType} on outputs
fmi3Set{VariableType} on inputs
fmi3ActivateModelPartition
fmi3Get{VariableType} on outputs

fmi3Set{VariableType} on inputs
fmi3ActivateModelPartition
fmi3Get{VariableType} on outputs
fmi3Set{VariableType} on inputs
fmi3Get{VariableType} on outputs // not allowed
fmi3ActivateModelPartition
fmi3Get{VariableType} on outputs

]

`fmi3CallbackIntermediateUpdate`

Only in this state the FMU is allowed to call the callback `fmi3CallbackIntermediateUpdate`. The callback may be called from concurrent tasks within `fmi3ActivateModelPartition`. The function must not return `fmi3Discard`.

`fmi3EnterConfigurationMode`

This function must not be called if the FMU contains no `structural parameters` or other tasks related to the computation of model partitions of this FMU are currently active or preempted. Thus this function can not be called concurrently for model partitions of an FMU but only for the whole FMU instance.

If the function returns with `fmi3OK` or `fmi3Warning` the FMU goes into state Reconfiguration Mode.

`fmi3Terminate`, `fmi3Reset`, `fmi3FreeInstance`

These functions can not be called concurrently for model partitions of an FMU but only for the whole FMU instance. If these functions are called while a model partition of an FMU is currently active or preempted, the FMU changes its state after the computation of all model partitions of this FMU has ended.

`fmi3GetFMUState`, `fmi3SetFMUState`, `fmi3FreeFMUState`,`fmi3SerializedFMUStateSize`, `fmi3SerializeFMUState`, `fmi3DeSerializeFMUState`

Can be called if no other task related to the computation of model partitions of this FMU is currently active or preempted and the prerequisites defined for these functions in Basic Co-Simulation are fulfilled. Thus these functions can not be called concurrently for model partitions of an FMU but only for the whole FMU instance.

Forbidden Function Calls

Additionally to the generally forbidden functions in Scheduled Co-Simulation as listed above, the following functions must not be called in this state: `fmi3ExitConfigurationMode`, `fmi3InstantiateXXX`, `fmi3SetupExperiment`, `fmi3EnterInitializationMode`, `fmi3ExitInitializationMode`, `fmi3GetDoStepDiscardedStatus`.

##### 6.2.3.5. State: Intermediate Update Mode

In this state the master can retrieve information from the FMU between communication points. Functions called in this state must not return `fmi3Discard`.

The FMU enters this state by calling `fmi3CallbackIntermediateUpdate` within `fmi3ActivateModelPartition` and leaves the state towards state Clock Activation Mode if the function returns `fmi3OK` or `fmi3Warning`. If the function returns `fmi3Error` the FMU enters state Terminated. If the function returns `fmi3Fatal` the FMU enters the terminal state.

Forbidden Function Calls

The same functions which are not allowed to be called in Clock Activation Mode must not be called in this state. Additionally the following functions must not be called `fmi3ActivateModelPartition`, `fmi3EnterConfigurationMode`, `fmi3Terminate`.

Allowed Function Calls

For a `output clock` only the first call of `fmi3GetClock` for a specific activation of this `clock` signals `fmi3True`. The FMU sets the reported activation state immediately back to `fmi3False` for the following `fmi3GetClock` calls for that `clock` (in the same or other model partitions of the FMU) until this `output clock` is internally activated again. The master can call `fmi3Set{VariableType}` and `fmi3Get{VariableType}` during the callback for variables associated to a `output clock` that is active during this callback. Also intermediate variable access is allowed as defined in Section 4.2.4.7

[Based on the FMI standard it cannot be determined which part of the code of an FMU has called the callback function `fmi3CallbackIntermediateUpdate`. This is especially the case for Scheduled Co-Simulation where multiple model partitions can be active at the same time. This causes no issues since all function call prerequisites are connected to the activation state of `clocks`, `modelDescription.xml` information and additionally available information from `fmi3CallbackIntermediateUpdate`]

##### 6.2.3.6. State: Reconfiguration Mode

In this state `structural parameters` with `variability` = `tunable` can be changed. This state is entered from state Clock Activation Mode by calling `fmi3EnterConfigurationMode` and left back to Clock Activation Mode by calling `fmi3ExitConfigurationMode`.

Allowed Function Calls
Forbidden Function Calls

Additionally to the generally forbidden functions in Scheduled Co-Simulation listed above the following functions must not be called in this state: `fmi3EnterConfigurationMode`, `fmi3InstantiateXXX`, `fmi3SetupExperiment`, `fmi3EnterInitializationMode`, `fmi3ExitInitializationMode`, `fmi3GetDoStepDiscardedStatus`, `fmi3ActivateModelPartition`,`fmi3SetInputDerivatives`, `fmi3GetDirectionalDerivative`, `fmi3GetOutputDerivatives`, `fmi3Get{VariableType}`, `fmi3DoEarlyReturn`

 Function FMI 3.0 for Scheduled Co-Simulation Start, End Instantiated Initialization Mode Configuration Mode Clock Activation Mode Reconfiguration Mode Intermediate Update Mode Terminated Error Fatal `fmi3GetVersion` `fmi3SetDebugLogging` `fmi3InstantiateXXX` `fmi3FreeInstance` `fmi3SetupExperiment` `fmi3EnterInitializationMode` `fmi3ExitInitializationMode` `fmi3Terminate` `fmi3Reset` `fmi3GetReal` `fmi3GetInteger` `fmi3GetBoolean` `fmi3GetString` `fmi3SetInteger` `fmi3SetReal` `fmi3SetBoolean` `fmi3SetString` `fmi3GetFMUState` x x x x x x `fmi3SetFMUState` x x x x x x `fmi3FreeFMUState` x x x x x x `fmi3SerializedFMUStateSize` `fmi3SerializeFMUState` `fmi3DeSerializeFMUState` `fmi3GetDirectionalDerivative`

x means: call is allowed in the corresponding state
number means: call is allowed if the indicated condition holds:
1 for a variable with `variability` $\neq$ `constant` that has `initial` = `exact` or `approx`
2 for a variable with `causality` = `output` or continuous-time states or state derivatives (if element `<ModelStructure><Derivative>` is present)
3 for a variable with `variability` = `constant` that has `initial` = `exact`, or `causality` = `input`
6 for a variable with `causality` = `input` or (`causality` = `parameter` and `variability` = `tunable`)
7 always, but retrieved values are usable for debugging only
8 always, but if status is other than `fmi3Terminated`, retrieved values are usable for debugging only ]_

#### 6.2.4. 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 for respecting this constraint.

The FMU’s code has to be prepared for being able to correctly handle preemptive calls of `fmi3ActivateModelPartition`, `fmi3Get{VariableType}`, `fmi3Set{VariableType}`. That requires a secured internal and external access to global states and variable values. Thus in Scheduled Co-Simulation a support for a correct handling of the preemption of model partition computations is required. That also requires that the FMU reports the active state of a `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.

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 master, 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 (`input clock`) 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 `input clock` settings defined in the XML the master calls `fmi3Set{VariableType}`, `fmi3ActivateModelPartition`, `fmi3Get{VariableType}` calls. 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 `clocks` (global variables), based on the XML information (see [clock-type-definition]).

[The recommendation is to avoid global variable associations as much as possible in the XML. It is also recommended to reduce dependencies (defined in XML model structure) between variables located in different model partitions of one FMU, since this also requires in most cases that the related variables have to be global variables.]

The Co-Simulation master has no knowledge about the FMU internal communication between the model partitions of a single FMU and does not handle it.

The simulation master schedules the `fmi3ActivateModelPartition` (as well as related `fmi3Get{VariableType}` and `fmi3Set{VariableType}`) calls based on given priorities for `input clocks` defined in the `modelDescription.xml`.

Priority (see [clock-type-definition]):

• Same priority: Tasks cannot preempt each other. Arbitrary execution order is possible for tasks of the same priority.

• Different priorities: Tasks of a higher priority preempt tasks of a lower priority as soon as the higher priority task needs to be computed.

[If multiple tasks are needed to be scheduled for computation at a certain time instant a master must schedule a task of a higher priority always before a task of a lower priority]

• (strict) periodic (period can be predefined by FMU or be defined by master, depending on XML information)

• aperiodic (based on external possibly unpredictable events)

Based on the period and priority definitions the exporting tool can restrict the code execution order. It nevertheless has to secure its code against concurrent execution [not against parallel execution, 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 global variables within the FMU. The exporting tool has to consider external events i.e. interrupts (if `input` aperiodic `clocks` are defined) and the influences of computing speed, so the exact preemption occurrence points cannot be foreseen (within the given priority and period restrictions).

To provide more options to secure the code against unwanted preemption new callback functions are defined that can be used to prevent preemption for certain code parts. If `providesScheduledCoSimulation = true` the default setting is that preemption is permitted. The preemption lock has to be actively locked and unlocked in the FMU’s code. Such locks should be used with care and only for securing very short code parts that cannot be secured otherwise.

A lock can be created and released to prevent preemption of that task (i.e. model partition):

``````typedef void       (*fmi3CallbackLockPreemption)   ();
typedef void       (*fmi3CallbackUnlockPreemption) ();``````

Even if the Co-Simulation master does not support preemption and Scheduled Co-Simulation, at least an empty implementation of these callback functions is required.

Example for the use of `fmi3CallbackLockPreemption` and `fmi3CallbackUnlockPreemption` callback functions in the FMU code:

``````Int16 DataBuffer[3];   // global buffer

{
...
// write data to DataBuffer
fmi3CallbackLockPreemption();
DataBuffer[0] = internal_out_RootSys1_1;
DataBuffer[1] = internal_out_RootSys1_2;
DataBuffer[2] = internal_out_RootSys1_3;
fmi3CallbackUnlockPreemption();
...
}

...
{
...
fmi3CallbackLockPreemption();
internal_in_RootSys2_1 = DataBuffer[0];
internal_in_RootSys2_2 = DataBuffer[1];
internal_in_RootSys2_3 = DataBuffer[2];
fmi3CallbackUnlockPreemption();
...
}``````

#### 6.2.5. Pseudo-code Example for Scheduled 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. The example is given in a mix of pseudo-code and C, in order to keep it small and understandable. We consider one slave with three model partitions. Two model partitions associated to two periodic `input clocks` (`clock` periods 1 ms and 2 ms) and one aperiodic `input clock`.

``````//////////////////////////
// Define callback

// Global variables
fmi3IntermediateUpdateInfo s1_intermediateInfo;

// Callback

//Remark:
//pointer for intermediateInfo has to be unique for each model partition that calls s1_triggeredClock_intermediateUpdate
//currently no clockIndex information is transported with intermediateInfo.
//Thus it is required to a) that the FMU secures (via lockPreemption, unlockPreemption) the call of fmi3GetClock()
//b) fmi3GetClock() sets back the activation state of the triggered clock
fmi3Status s1_triggeredClock_intermediateUpdate(fmi3InstanceEnvironment instance, fmi3IntermediateUpdateInfo* intermediateUpdateInfo)
{
//local variables;
fmi3Boolean triggered_clockStatesS1[];
fmi3ValueReference triggered_clockReferenceS1[];
size_t nclocks;

// Save intermediateInfo for later use
s1_intermediateInfo = *intermediateUpdateInfo;
if (s1_intermediateInfo.clocksTicked)
{
s1_fmi3GetClocks(s1, triggered_clockReferenceS1, nclocks, triggered_clockStatesS1);
s1_fmi3GetReal/Integer/Boolean/String(s1, variables_associated_to_active_triggered_clock);
}

//evaluate which triggered clocks have ticked and are associated via clockReference to inferred clocks
inferredClockReferences = getActiveClocksForFMU(ID1,triggered_clockReferenceS1,triggered_clockStatesS1);
for (index=0,count(inferredClockReferences),index++)
{
//call os function to schedule a fmi3ActivateModelPartiton() call together with associated get/set calls
//In this case clock 2 (defined in modelDescription.XML via valueReference)
//(--> see functions s1_Execute_clockIndex2 and s2_Execute_clockIndex2)
}

if (s1_intermediateInfo.clocksTicked)
{
s1_fmi3SetReal/Integer/Boolean/String(s1, variables_associated_to_active_triggered_clock);
}

}

// Set callback functions,
fmi3CallbackFunctions cbf1;
fmi3EventInfo eventInfo;

//////////////////////////
// Initialization sub-phase
fmi3Status GlobalInitialize()
{

cbf1.logger = loggerFunction; // Logger function
cbf1.allocateMemory = calloc;
cbf1.freeMemory = free;
cbf1.intermediateUpdate = s1_triggeredClock_intermediateUpdate;
cbf1.lockPreemption = lockPreemption(); // Preemption is OS specific
cbf1.unlockPreemption = unlockPreemption(); // Preemption is OS specific

// Create pointer to information for identifying the FMU in callbacks
// (note: this is pseudo code, no correct pointer handling)
cbf1.instanceEnvironment = NULL

//set Co-Simulation mode
fmi3CoSimulationConfiguration coSimulationConfiguration;
coSimulationConfiguration.intermediateVariableGetRequired = false;
coSimulationConfiguration.intermediateInternalVariableGetRequired = false;
coSimulationConfiguration.intermediateVariableSetRequired = false;
coSimulationConfiguration.coSimulationMode = fmi3ModeScheduledCoSimulation;

// Instantiate slave 1
fmi3Instance s1 = s1_fmi3Instantiate("Tool1" , fmi3CoSimulation, ID1, "", &cbf1, fmi3False, fmi3True, &coSimulationConfiguration);

if (s1 == NULL) then return FAILURE;

// Set all variable start values (of "ScalarVariable / <type> / start")
s1_fmi3SetReal/Integer/Boolean/String(s1, ...);

// Initialize slaves
s1_fmi3SetupExperiment(s1, fmi3False, 0.0, startTime, fmi3True, stopTime);

s1_fmi3EnterInitializationMode(s1);

// Set the input values at time = startTime
s1_fmi3SetReal/Integer/Boolean/String(s1, ...);

s1_fmi3ExitInitializationMode(s1);

// Get all outputs (for better readability only Real variables are used here. Handling for Integer, Boolean, String is the same)
s1_fmi3GetReal(s1, yr1_c0); // variable associated to clockIndex 0
s1_fmi3GetReal(s1, yr1_c1); // variable associated to clockIndex 1
s1_fmi3GetReal(s1, yr1_c2); // variable associated to clockIndex 2
}

//////////////////////////
// Simulation sub-phase

// Step function for 1ms task. Assuming that both FMUs contain a clock for 1ms (clockIndex=0)
fmi3Status Execute_1ms()
{
ur1_c0 = yr1_c0;

// Set inputs associated to clockIndex 0
s1_fmi3SetReal(s1, ur1_c0);

// call step functions for clockIndex 0
status1 = fmi3ModelPartitionActivation(s1, 0, activationTime, currentTime);

// Get outputs associated to clockIndex 0
s1_fmi3GetReal(s1, yr1_c0);
};

// Step function for 2ms task. Assuming that both FMUs contain a clock for 2ms (clockIndex=1)
fmi3Status Execute_2ms()
{
ur1_c1 = yr1_c1;

// Set inputs associated to clockIndex 1
s1_fmi3SetReal(s1, ur1_c1);

// call step functions for clockIndex 1
status1 = s1_fmi3ModelPartitionActivation(s1, 1, activationTime, currentTime);

// Get outputs associated to clockIndex 1
s1_fmi3GetReal(s1, yr1_c1);
}

// Step function for s1 for inferred clock with clockIndex=2.
fmi3Status s1_Execute_clockIndex2(activationTime, currentTime)
{
ur1_c2 = yr1_c2;

// Set inputs associated to clockIndex 2
s1_fmi3SetReal(s1, ur1_c2);

// call step functions for clockIndex 2
status = s1_fmi3ModelPartitionActivation(s1, 2, activationTime, currentTime);

// Get outputs associated to clockIndex 2
s1_fmi3GetReal(s1, yr1_c2);
}

//////////////////////////
// Shutdown sub-phase
fmi3Status GlobalTerminate(status)
{
if ((status1 != fmi3Error) and (status1 != fmi3Fatal)) then fmi3Terminate(s1);

if (status1 != fmi3Fatal) then fmi3FreeInstance(s1);
}``````

### 6.3. Description Schema

The simulation master collects the information about the number and properties of `clocks` supported by the FMU via analyzing the `modelDescription.xml` as defined in section 2.2. and 4.3.

Each `clock` that ticks outside of the FMU is activated for an FMU based on its `clockReference`. There is a direct one-to-one relation for a `clock` and a model partition.

If `clocks` are defined and the flag `providesScheduledCoSimulation = true`, the Co-Simulation master can use the Scheduled Co-Simulation interface. If no `input clocks` are defined, the flag `providesScheduledCoSimulation` shall not be set to `true`.

#### 6.3.1. Example XML Description File

The example below is the same one as shown in section [TBD] for a `fmi3ClockedCoSimulation` FMU.

``//include::examples/co_simulation_scheduled_execution.xml[]``

## 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

• [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

• [MG09] MODELISAR Glossary (2009): MODELISAR WP2 Glossary and Abbreviations. Version 1.0, June 9, 2009.

• [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

## Appendix A: FMI Revision History

This appendix describes the history of the FMI design and its contributors. The current version of this document is available from https://fmi-standard.org/.

The Functional Mock-up Interface development was initiated and organized by Daimler AG (from Bernd Relovsky and others) as subproject inside the ITEA2 MODELISAR project.

The development of versions 1.0 and 2.0 was performed within WP200 of MODELISAR, organized by the WP200 work package leader Dietmar Neumerkel from Daimler.

### A.1 Version 1.0 - FMI for Model Exchange

Version 1.0 of FMI for Model Exchange was released on Jan. 26, 2010.

The subgroup "FMI for Model Exchange" was headed by Martin Otter (DLR-RM). The essential part of the design of this version was performed by (alphabetical list):

• Torsten Blochwitz, ITI, Germany

• Hilding Elmqvist, Dassault Systèmes, Sweden

• Andreas Junghanns, QTronic, Germany

• Jakob Mauss, QTronic, Germany

• Hans Olsson, Dassault Systèmes, Sweden

• Martin Otter, DLR-RM, Germany

This version was evaluated with prototypes implemented for (alphabetical list):

• Dymola by Peter Nilsson, Dan Henriksson, Carl Fredrik Abelson, and Sven Erik Mattson, Dassault Systèmes,

• JModelica.org by Tove Bergdahl, Modelon AB,

• Silver by Andreas Junghanns, and Jakob Mauss, QTronic

These prototypes have been used to refine the design of "FMI for Model Exchange".

The following MODELISAR partners participated at FMI design meetings and contributed to the discussion (alphabetical list):

• Ingrid Bausch-Gall, Bausch-Gall GmbH, Munich, Germany

• Torsten Blochwitz, ITI GmbH, Dresden, Germany

• Alex Eichberger, SIMPACK AG, Gilching, Germany

• Hilding Elmqvist, Dassault Systèmes, Lund, Sweden

• Andreas Junghanns, QTronic GmbH, Berlin, Germany

• Rainer Keppler, SIMPACK AG, Gilching, Germany

• Gerd Kurzbach, ITI GmbH, Dresden, Germany

• Carsten Kübler, TWT, Germany

• Jakob Mauss, QTronic GmbH, Berlin, Germany

• Johannes Mezger, TWT, Germany

• Thomas Neidhold, ITI GmbH, Dresden, Germany

• Dietmar Neumerkel, Daimler AG, Stuttgart, Germany

• Peter Nilsson, Dassault Systèmes, Lund, Sweden

• Hans Olsson, Dassault Systèmes, Lund, Sweden

• Martin Otter, German Aerospace Center (DLR), Oberpfaffenhofen, Germany

• Antoine Viel, LMS International (Imagine), Roanne, France

• Daniel Weil, Dassault Systèmes, Grenoble, France

The following people outside of the MODELISAR consortium contributed with comments:

• Johan Åkesson, Lund University, Lund, Sweden

• Joel Andersson, KU Leuven, The Netherlands

• Roberto Parrotto, Politecnico di Milano, Italy

### A.2 Version 1.0 - FMI for Co-Simulation

Version 1.0 of FMI for Co-Simulation was released on Oct. 10, 2010.

FMI for Co-Simulation was developed in three subgroups: "Solver Coupling" headed by Martin Arnold (University Halle) and Torsten Blochwitz (ITI), "Tool Coupling" headed by Jörg-Volker Peetz (Fraunhofer SCAI), and "Control Logic" headed by Manuel Monteiro (Atego). The essential part of the design of this version was performed by (alphabetical list):

• Martin Arnold, University Halle, Germany

• Constanze Bausch, Atego Systems GmbH, Wolfsburg, Germany

• Torsten Blochwitz, ITI GmbH, Dresden, Germany

• Christoph Clauß, Fraunhofer IIS EAS, Dresden, Germany

• Manuel Monteiro, Atego Systems GmbH, Wolfsburg, Germany

• Thomas Neidhold, ITI GmbH, Dresden, Germany

• Jörg-Volker Peetz, Fraunhofer SCAI, St. Augustin, Germany

• Susann Wolf, Fraunhofer IIS EAS, Dresden, Germany

This version was evaluated with prototypes implemented for (alphabetical list):

• SimulationX by Torsten Blochwitz and Thomas Neidhold (ITI GmbH)

• Master algorithms by Christoph Clauß (Fraunhofer IIS EAS)

The following MODELISAR partners participated at FMI design meetings and contributed to the discussion (alphabetical list):

• Martin Arnold, University Halle, Germany

• Jens Bastian, Fraunhofer IIS EAS, Dresden, Germany

• Constanze Bausch, Atego Systems GmbH, Wolfsburg, Germany

• Torsten Blochwitz, ITI GmbH, Dresden, Germany

• Christoph Clauß, Fraunhofer IIS EAS, Dresden, Germany

• Manuel Monteiro, Atego Systems GmbH, Wolfsburg, Germany

• Thomas Neidhold, ITI GmbH, Dresden, Germany

• Dietmar Neumerkel, Daimler AG, Böblingen, Germany

• Martin Otter, DLR, Oberpfaffenhofen, Germany

• Jörg-Volker Peetz, Fraunhofer SCAI, St. Augustin, Germany

• Tom Schierz, University Halle, Germany

• Klaus Wolf, Fraunhofer SCAI, St. Augustin, Germany

### A.3 Version 2.0 - FMI for Model Exchange and Co-Simulation

FMI 2.0 for Model Exchange and Co-Simulation was released on July 25, 2014.

#### A.3.1 Overview

This section gives an overview about the changes with respect to versions 1.0 for Model Exchange and 1.0 for Co-Simulation:

• FMI 2.0 is not backwards compatible to FMI 1.0.

• The documents, schema and header files for Model Exchange and for Co-Simulation have been merged. Due to the merging, some conflicts had to be resolved leading to some non-backwards compatible changes with respect to FMI 1.0.

• Parameters can be declared to be `tunable` in the FMU, in other words, during simulation these `parameters` can be changed (if supported by the simulation environment).

• When enabling logging, log categories to be logged can be defined, so that the FMU only needs to generate logs of the defined categories (in FMI 1.0, logs had to be generated for all log categories and they had to be filtered afterwards). Log categories that are supported by an FMU can be optionally defined in the XML file so that a simulation environment can provide them to the user for selection.

• In order that tools can more simply support importing both FMI 1.0 and 2.0, all file and function names of FMI 2.0 start with `fmi2`, whereas they start with `fmi` for FMI 1.0.

• FMI function names are no longer prefixed with the `modelIdentifier` if used in a DLL/sharedObject. As a result, FMUs that need a tool can use a generic communication DLL, and the loading of DLLs is no longer FMU dependent.

• The different modes of an FMU are now clearly signaled with respective function calls (`fmi2EnterInitializationMode`, `fmi2EnterEventMode`, `fmi2EnterContinuousTimeMode`).

• The interfaces have been redesigned, in order that algebraic loops over connected FMUs with Real, Integer, or Boolean unknowns can now be handled reasonably not only in Continuous-Time Mode, but also in Initialization Mode and Event Mode. In FMI 1.0, algebraic loops in Initialization Mode and Even Mode could not be handled.

• The termination of every global event iteration over connected FMUs must be reported by a new function call (`fmi2EnterContinuousTimeMode`).

• The unit definitions have been improved: The tool-specific unit-name can optionally be expressed as function of the 7 SI base units and the SI derived unit `rad`. It is then possible to check units when FMUs are connected together (without standardizing unit names), or to convert variable values that are provided in different units (for the same physical quantity).

• Enumerations have an arbitrary (but unique) mapping to integers (in FMI 1.0, the mapping was automatically to 1,2,3,…​).

• The alias/negatedAlias variable definitions have been removed, to simplify the interface: If variables of the same base type (like `fmi2Real`) have the same `valueReference`, they have identical values. A simulation environment may ignore this completely (this was not possible in FMI 1.0), or can utilize this information to more efficiently store results on file.

• When instantiating an FMU, the absolute path to the FMU resource directory is now reported also in Model Exchange, in order that the FMU can read all of its resources (for example, maps, tables, …​) independently of the "current directory" of the simulation environment where the FMU is used.

• An ordering is defined for `input`, `output`, and `state` variables in the XML file of an FMU, in order for this order to be defined in the FMU, and not be (arbitrarily) selected by the simulation environment. This is essential, for example, when linearizing an FMU, or when providing `sparsity` information (see below).

• Several optional features have been added:

• The complete FMU state can be saved, restored, and serialized to a byte vector (that can be stored on file). As a result, a simulation (both for Model Exchange and for Co-Simulation) can be restarted from a saved FMU state. Rejecting steps for variable step-size Co-Simulation master algorithms is now performed with this feature (instead of the less powerful method of FMI 1.0).

• The dependency of state derivatives and of output variables from `inputs` and `states` can be defined in the XML file, in other words, the sparsity pattern for Jacobians can be defined. This allows simulating stiff FMUs with many states (> 1000 states) since sparse matrix methods can be utilized in the numerical integration method. Furthermore, it can be stated whether this dependency is linear (this allows to transform nonlinear algebraic equation systems into linear equation systems when connecting FMUs).

• Directional derivatives can be computed for derivatives of continuous-time `states` and for `outputs`. This is useful when partial derivatives of connected FMUs must be computed. If the exported FMU performs this computation analytically, then all numerical algorithms based on these partial derivatives (for example, the numerical integration method or nonlinear algebraic solvers) are more efficient and more reliable.

• Every scalar variable definition can have an additional `annotation` data structure that is arbitrary (`any` element in XML). A tool vendor can store tool-dependent information here (that other tools can ignore), for example, to store the graphical layout of parameter menus. The `<VendorAnnotations>` element was also generalized from (name, value) pairs to any XML data structure.

• Many smaller improvements have been included, due to the experience in using FMI 1.0 (for example, the `causality`/`variability` attributes have been changed and more clearly defined, the fmi2ModelFunctions.h header has been split into two header files (one for the function signature, and one for the function names), in order that the header files can be directly used both for DLLs and for source code distribution).

#### A.3.2 Main changes

This section gives the details about the changes with respect to versions 1.0 for Model Exchange and 1.0 for Co-Simulation:

In this version, the documents of version 1.0 for Model Exchange and for Co-Simulation have been merged and several new features have been added.

The following changes in FMI 2.0 are not backwards compatible due to the merging:

• File fmiModelTypes.h (in FMI for Model Exchange) has been renamed to fmi2TypesPlatform.h (the file name used in FMI for Co-Simulation).

• File fmiModelFunctions.h (in FMI for Model Exchange) has been renamed to fmi2Functions.h (the file name used in FMI for Co-Simulation), and the function prototypes in this header files have been merged from Model Exchange and from Co-Simulation). Additionally, a new header files has been added, `fmi2FunctionTypes.h` that contains a definition of the function signatures. This header file is also used in `fmi2Functions.h` (so the signature is not duplicated). The benefit is that `fmi2FunctionTypes.h` can be directly used when loading a DLL/sharedObject (in FMI 1.0, the tool providers had to provide this header file by themselves).

• Fixing ticket #47:
In FMI 1.0 for Model Exchange the attribute `version` in `<fmiModelDescription>` was defined as string, whereas in Co-Simulation it was defined as integer. This has been changed, so that version is a string.

The following backwards compatible improvements have been made in FMI 2.0:

• The FMI 1.0 documents have been merged (for example, all common definitions have been placed in the new Section 2).

The following not backwards compatible improvements have been made in FMI 2.0:

• Element `<fmiModelDescription><Implementation>` in the model description schema file has been replaced by a different structure where one hierarchical level is removed. There are now 2 elements directly under `<fmiModelDescription>`: `<ModelExchange>` and `<CoSimulation>`.
File `fmiImplementation.xsd` has been removed.
New capability flags have been introduced both for `<ModelExchange>` and for `<CoSimulation>`, such as `canGetAndSetFMUState`, `canSerializeFMUState`, etc.
Attribute `modelIdentifier` has been moved from an `<fmiModelDescription>` attribute to an attribute in `<ModelExchange>` and in `<CoSimulation>`. This allows providing different identifiers, and then an FMU may contain both distribution types with different DLL names (which correspond to the `modelIdentifier` names).
A new attribute `needsExecutionTool` has been introduced both in `<ModelExchange>` and in `<CoSimulation>` in order to define whether a tool is needed to execute the FMU. The previous elements in `CoSimulation_Tool` have been removed.

• The state machines of Model Exchange and CoSimulation have been improved. Especially, the entering of the states in this state machine are now clearly marked by corresponding function calls (`fmi2EnterInitializationMode`, `fmi2EnterEventMode`, `fmi2EnterContinuousTimeMode`).

• Fixing ticket #9:
A new element `<LogCategory>` was introduced in `<fmiModelDescription>`. This is an unordered set of strings representing the possible values of the log categories of the FMU (for example, `logEvent`).
Function `fmi2SetDebugLogging` has two new arguments to define the categories (from `<LogCategory>`) to be used in log messages.

• Fixing ticket #33:
The `causality` and `variability` attributes of a `<ScalarVariable>` have not been fully clear. This has been fixed by changing the enumeration values of `variability` from `constant`, `parameter`, `discrete`, `continuous` to `constant`, `fixed`, `tunable`, `discrete`, `continuous` and `causality` from `input`, `output`, `internal`, none" to `parameter`, `input`, `output`, `local`. This change includes now also the support of parameters that can be tuned (changed) during simulation.

• Fixing ticket #35:
In order to simplify implementation (for example, an "element event handler" is no longer needed in SAX XML parser), the only location where data is not defined by attributes, is changed to an attribute definition: Element `DirectDependency` in `ScalarVariable` is removed. The same information can now be obtained from the `InputDependency` attribute inside `<fmiModelDescription><ModelStructure><Outputs>`.

• Fixing ticket #37:
The new status flag `fmi2Terminate` is added to the Co-Simulation definition. This allows a slave to terminate the simulation run before the stop time is reached without triggering an error.

• Fixing ticket #39:
Wrong example in the previous section 2.10 of Co-Simulation has been fixed.

• Fixing ticket #41:
New types introduced in fmi2TypesPlatform.h :
`fmi2ComponentEnvironment`, `fmi2FMUState`, `fmi2Byte`.
Struct `fmi2CallbackFunctions` gets a new last argument:
`fmi2ComponentEnvironment instanceEnvironment`
The first argument of function `logMessage` is changed from type `fmi2Component` to `fmi2ComponentEnvironment`.
By these changes, a pointer to a data structure from the simulation environment is passed to the `logMessage` and allows the `logMessage`, for example, to transform a `valueReference` in the log message to a variable name.

• Fixing ticket #42:
Enumerations defined in fmi2Type.xsd are now defined with (name, value) pairs. An enumeration value must be unique within the same enumeration (to have a bijective mapping between enumeration names and values, in order that results can optionally be presented with names and not with values).
Furthermore, the `min/max` values of element `<Enumeration>` in `<TypeDefinition>` have been removed because they are meaningless.

• Fixing ticket #43:
The previous header file fmiFunctions.h is split into 2 header files, fmi2FunctionTypes.h and fmi2Functions.h, in order to simplify the dynamic loading of an FMU (the typedefs of the function prototypes defined in fmi2FunctionTypes.h can be used to type case the function pointers of the dynamic loading).

• Fixing ticket #45:
Contrary to the ticket proposal, no new function `fmiResetModel` is added. Instead 6 new functions are added to get and set the internal FMU state via a pointer and to serialize and deserialize an FMU state via a byte vector provided by the environment. For details, see Section 2.1.10. This feature allows, for example, to support more sophisticated co-simulation master algorithms which require the repetition of communication steps. Additionally, two capability flags have been added (`canGetAndSetFMUState`, `canSerializeFMUState`) in order to define whether these features are supported by the FMU.

• Fixing ticket #46:
The unit definitions have been enhanced by providing an optional mapping to the 7 SI base units and the SI derived unit `rad`, in order for a tool to be able to check whether a signal provided to the FMU or inquired by the FMU has the expected unit.

• Fixing ticket #48:
The definition of `fmiBoolean` in `fmiTypesPlatform.h` for `standard32` was changed from `char` to `int`. The main reason is to avoid unnecessary casting of Boolean types when exporting an FMU from a Modelica environment or when importing it into a Modelica environment.
The current definition of `char` for a Boolean was not meaningful, since, for example, for embedded code generation usually Booleans are packed on integers and `char` for one Boolean would also not be used. It is planned to add more supported data types to an FMU in the future, which should then also include support for packed Booleans.

• Fixing ticket #49:
Argument `fmiComponent` in function pointer `stepFinished` was changed to `fmi2ComponentEnvironment` (when `stepFinished` is called from a Co-Simulation slave and provides `fmi2ComponentEnvironment`, then this data structure provided by the environment can provide environment specific data to efficiently identify the slave that called the function).

• Fixing ticket #54:
In Section 2.3 it is now stated, that the FMU must include all referenced resources. This means especially that for Microsoft VisualStudio the option "MT" has to be used when constructing a DLL in order to include the run-time environment of VisualStudio in the DLL.

• Fixing ticket #75:
Since states are now explicitly defined in the XML file, function `fmiGetStateValueReferences` is no longer needed, as well as the special type `fmiUndefinedValueReference` that might be used as return value of this function. Therefore, both elements have been removed in FMI 2.0.

• Fixing ticket #85:
New argument `noSetFMUStatePriorToCurrentPoint` to function `fmi2CompletedIntegratorStep`, similarly to `fmi2DoStep`, in order that the FMU can flush a result buffer if necessary.

• Fixing ticket #86:
The fmi2TypesPlatform.h header file has been slightly changed: The default value of `fmi2TypesPlatform` is changed from `standard32` to `default`, since this definition holds for most platforms and compilers. Furthermore, the default type of `fmi2ValueReference` has been changed from `unsigned int` to `size_t`.

• Fixing ticket #88:
The definition of fmi2Functions.h slightly changed to improve portability (the header file can now be utilized both for Microsoft and gnu compilers, and the danger of name conflicts has been reduced).

• Fixing ticket #95:
FMI XML files need to be UTF-8 encoded (as are XML schema files and strings in the C-API), in order to simplify reading of XML files.

• Fixing ticket #113:
Changed function name `fmiTerminateSlave` to `fmi2Terminate` in order to be consistent with the other function definitions (`fmi2EnterSlaveInitializationMode`, `fmi2Terminate`).

• Fixing ticket #115:
Clarification added, that the special values `NAN`, `+INF`, `-INF`, are not allowed in the FMI XML files.

• Fixing ticket #127:
Added clarifications in section 2.1, that all C-API functions are not thread safe and that FMUs must not influence each other.

• Fixing ticket #218:
Changed all name prefixes from `fmi` to `fmi2` in *.h, *.xsd, *.png files and in the specification to avoid compiler and linker problems when supporting both FMI 1.0 and 2.0 in the same program.

• Function `fmiInitialize` was split into two functions: `fmi2EnterInitializationMode` and `fmi2ExitInitializationMode` in order that artificial or real algebraic loops over connected FMUs can be handled in an efficient way.

• Function `stepEvent` in `struct fmi2CallbackFunctions` had different locations in the FMI documentation and in the header file. This inconsistency has been corrected by using the location in the header file (at the end of the `struct`).

• The `struct fmi2CallbackFunctions` is provided as a pointer to the `struct` when instantiating an FMU, and not as the `struct` itself. This simplifies the importing of an FMU into a Modelica environment.

• Defined how to utilize the `min`/`max` attributes for `fmi2SetReal`, `fmi2SetInteger`, `fmi2GetReal`, `fmi2GetInteger` calls.

• Attributes `numberOfScalarVariables`, `numberOfContinuousStates`, `numberOfInputs`, `numberOfOutputs` available in FMI 1.0 have been removed, because they can be deduced from the remaining XML file (so in FMI 2.0 this would have been redundant information).

#### A.3.3 Contributors

The development group for this version was headed by Torsten Blochwitz (ITI). The essential part of the design of this version was performed by (alphabetical list):

• Johan Åkesson, Modelon, Sweden

• Martin Arnold, University Halle, Germany

• Torsten Blochwitz, ITI, Germany

• Christoph Clauss, Fraunhofer IIS EAS, Germany

• Hilding Elmqvist, Dassault Systèmes, Sweden

• Rüdiger Franke, ABB AG, Germany

• Markus Friedrich, SIMPACK AG, Germany

• Lev Greenberg, IBM Research, Israel

• Andreas Junghanns, QTronic, Germany

• Jakob Mauss, QTronic, Germany

• Iakov Nakhimovski, Modelon, Sweden

• Dietmar Neumerkel, Daimler AG, Germany

• Hans Olsson, Dassault Systèmes, Sweden

• Martin Otter, DLR RMC-SR, Germany

• Antoine Viel, Siemens PLM Software, France

The FMI 2.0 document was edited by Martin Otter (DLR), Torsten Blochwitz (ITI), and Martin Arnold (Uni Halle). The State Machines and tables for the Calling Sequences for Model Exchange and Co-Simulation are from Jakob Mauss (QTronic).

This version was evaluated with prototypes implemented for (alphabetical list):

• Dymola by Peter Nilsson, Karl Wernersson, and Sven Erik Mattson, Dassault Systèmes, Sweden

• FMI Compliance Checker by Iakov Nakhimovski, Modelon AB, Sweden

• LMS Imagine.Lab AMESim by Antoine Viel, Siemens PLM Software, France

• Silver by Andreas Junghanns, QTronic, Germany

• SimulationX by Torsten Blochwitz, ITI, Germany

• SCALEXIO and VEOS by Irina Zacharias, Andreas Pillekeit, dSPACE GmbH, Germany

• xMOD by Mongi ben Gaid, Bertrand Hugon, Bruno Léty, and Fabien Debertolis, IFPEN, France

These prototypes have been used to refine the design of "FMI 2.0 for Model Exchange and Co-Simulation".

The open source FMITest library (https://svn.fmi-standard.org/fmi/branches/public/Test_FMUs/_FMIModelicaTest/FMITest/help/FMITest.html) to test difficult cases of connected FMUs was implemented by Martin Otter (DLR, Germany) based on suggestions by Hilding Elmqvist (Dassault Systèmes, Sweden) and Torsten Blochwitz (ITI, Germany).

The following partners participated at FMI 2.0 design meetings and contributed to the discussion (alphabetical list):

• Johan Åkesson, Modelon, Sweden

• Martin Arnold, University Halle, Germany

• Mongi Ben-Gaid, IFP, France

• Christian Bertsch, Robert Bosch GmbH, Germany

• Torsten Blochwitz, ITI, Germany

• Christoph Clauss, Fraunhofer IIS EAS, Germany

• Alex Eichberger, SIMPACK AG, Germany

• Hilding Elmqvist, Dassault Systèmes, Sweden

• Rüdiger Franke, ABB AG, Germany

• Markus Friedrich, SIMPACK AG, Germany

• Peter Fritzson, PELAB, Sweden

• Rafael Gilles (Erbacher), dSPACE GmbH, Germany

• Lev Greenberg, IBM Research, Israel

• Anton Haumer, Modelon, Germany

• Andreas Junghanns, QTronic, Germany

• Karsten Krügel, dSPACE GmbH, Germany

• Edward Lee, Berkeley University, U.S.A.

• Bruno Loyer, Siemens PLM Software, France

• Petter Lindholm, Modelon, Sweden

• Kristin Majetta, Fraunhofer IIS EAS, Germany

• Sven Erik Mattsson, Dassault Systèmes, Sweden

• Jakob Mauss, QTronic, Germany

• Monika Mühlbauer, Siemens AG, Germany

• Dietmar Neumerkel, Daimler AG, Germany

• Peter Nilsson, Dassault Systèmes, Sweden

• Hans Olsson, Dassault Systèmes, Sweden

• Martin Otter, DLR RMC-SR, Germany

• Nicolas Pernet, IFPEN, France

• Andreas Pillekeit, dSPACE GmbH, Germany

• Bernd Relovsky, Daimler AG, Germany

• Tom Schierz, University Halle, Germany

• Stefan-Alexander Schneider, BMW, Germany

• Klaus Schuch, AVL List GmbH, Austria

• Bernhard Thiele, DLR RMC-SR, Germany

• Antoine Viel, Siemens PLM Software, France

• Karl Wernersson, Dassault Systèmes, Sweden

• Irina Zacharias, dSPACE GmbH, Germany

The following people contributed with comments (alphabetical list):

• Peter Aaronsson, MathCore, Sweden

• Bernhard Bachmann, University of Bielefeld, Germany

• Andreas Pfeiffer, DLR RMC-SR

### A.3.4 FMI 2.0.1 maintenane release: changes and contributors

The changes w.r.t. FMI 2.0 (clarifications and bugfixes) are summarized on the release page for FMI 2.0.1 https://github.com/modelica/fmi-standard/releases/tag/v2.0.1

The following partners participated at FMI 2.0.1 meetings (alphabetical list):

• Christian Bertsch, Robert Bosch GmbH, Germany

• Torsten Blochwitz, ESI ITI GmbH, Germany

• Robert Braun, Linküping University, Sweden

• Andreas Junghanns, QTronic GmbH, Germany

• Pierre R. Mai, PMSF IT Consulting, Germany

• Masoud Najafi, Altair, France

• Andreas Pillekeit, dSPACE GmbH, Germany

• Torsten Sommer, Dassault Systèmes, Germany

• Karl Wernersson, Dassault Systèmes, Sweden

For further contributors by comments please refer to the issue tracking system https://github.com/modelica/fmi-standard/milestone/3

## Appendix B: Glossary

This glossary is a subset of (MODELISAR Glossary, 2009) with some extensions.

 Term Description algorithm A formal recipe for solving a specific type of problem. application programming interface (API) A set of functions, procedures, methods or classes together with type conventions/declarations (for example, C header files) that an operating system, library or service provides to support requests made by computer programs. AUTOSAR AUTomotive Open System Architecture (www.autosar.org). Evolving standard of the automotive industry to define the implementation of embedded systems in vehicles including communication mechanisms. An important part is the standardization of C functions and macros to communicate between software components. AUTOSAR is targeted to built on top of the real-time operating system OSEK (www.osek-vdx.org, de.wikipedia.org/wiki/OSEK). The use of the AUTOSAR standard requires AUTOSAR membership. clock tick When the `clock` ticks an event is present otherwise the event is absent. For FMI for Co-Simulation the ticking of a `clock` is interpreted as an activity of the associated model partition. The ticking of a `output clock` may lead to an `input clock` tick for another FMU (has to be defined via Co-Simulation master) or for a model partition of the same FMU (is defined in `modelDescription.xml`). communication points Time grid for data exchange between master and slaves in a co-simulation environment (also known as "sampling points" or "synchronization points"). communication step size Distance between two subsequent communication points (also known as "sampling rate" or "macro step size"). co-simulation Coupling (in other words, dynamic mutualexchange and utilization of intermediate results) of several simulation programs including their numerical solvers in order to simulate a system consisting of several subsystems. co-simulation platform Software used for coupling several simulation programs for co-simulation. ECU Electronic Control Unit (Microprocessor that is used to control a sub-system in a vehicle). 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. External events occur outside the FMU and should be signaled to the FMU without any delay. 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 for Co-Simulation Functional Mock-up Interface for Co-Simulation: One of the MODELISAR functional mock-up interfaces. It connects the master solver component with one or more slave solvers. FMI for Model Exchange Functional Mock-up Interface for Model Exchange: One of the MODELISAR functional mock-up interfaces. It consists of the model description interface and the model execution interface. It connects the external model component with the solver component. FMU Functional Mock-up Unit: A "model class" from which one or more "model instances" can be instantiated for simulation. An FMU is stored in one ZIP file as defined in Section 2.3 consisting basically of one XML file that defines the model variables and a set of C functions (see Section 2.1), in source or binary form, to execute the model equations or the simulator slave. In case of tool execution, additionally, the original simulator is required to perform the co-simulation (compare Section 4) integration algorithm The numerical algorithm to solve differential equations. integrator A software component, which implements an integration algorithm. interface An abstraction of a software component that describes its behavior without dealing with the internal implementation. Software components communicate with each other via interfaces. interrupt Event connected to the tick of an `input clock` of an FMU that is caused by an external potentially random process, i.e. hardware interrupt, software interrupt. master/slave A method of communication, where one device or process has unidirectional control over one or more other devices. Once a master/slave relationship between devices or processes is established, the direction of control is always from the master to the slaves. In some systems a master is elected from a group of eligible devices, with the other devices acting in the role of slaves. 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.2. 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 sampling points (i.e. communication points) for the `continuous` values. Please note that this is only possible for `CommunicationPointClocks`. numerical solver see solver 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. slave see master/slave 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). Examples of simulation programs are: AMESim, Dymola, SIMPACK, SimulationX, SIMULINK. simulation tool see simulation program simulator A simulator can include one or more simulation programs, which solve a common simulation task. 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 `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 Event that is defined by the time instant where the domain $z > 0$ of an event indicator variable `z` is changed to $z \leq 0$, or vice versa. This definition is slightly different from the usual standard definition of state events: "$z(t)*z(t_{i-1}) \leq 0$" which has the severe drawback that the value of the event indicator at the previous event instant, $z(t_{i-1}) \neq 0$, must be non-zero and this condition cannot be guaranteed. The often used term "zero crossing function" for `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. step event Event that might occur at a completed integrator step. Since this event type is not defined by a precise time or condition, it is usually not defined by a user. A program may use it, for example, to dynamically switch between different states. A step event is handled much more efficiently than a state event, because the event is just triggered after performing a check at a completed integrator step, whereas a search procedure is needed for a state event. super-dense time A precise definition of time taking into account iterations at an event. For an FMU, the `independent` variable time $t \in \mathbb{T}$ is a tuple $t = (t_R, t_I)$ where $t_R \in \mathbb{R}, t_I \in \mathbb{N} = \{0,1,2,\ldots\}$. The real part $t_R$ of this tuple is the `independent` variable of the FMU for describing the continuous-time behavior of the model between events. In this phase $t_I = 0$. The integer part $t_I$ of this tuple is a counter to enumerate (and therefore distinguish) the events at the same continuous-time instant $t_R$. 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. 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.