Skip to content

Commit

Permalink
Add <Alias> element to model variables (#834)
Browse files Browse the repository at this point in the history
solves #807
  • Loading branch information
t-sommer committed Mar 11, 2020
1 parent 3a61aa0 commit ca5f9d6
Show file tree
Hide file tree
Showing 5 changed files with 90 additions and 39 deletions.
1 change: 1 addition & 0 deletions .circleci/validate_xml.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
parser = etree.XMLParser(schema=schema)

xml_files = [
'alias_example.xml',
'build_configuration.xml',
'co_simulation.xml',
'model_structure_example1.xml',
Expand Down
2 changes: 0 additions & 2 deletions docs/2_1_common_api.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -347,8 +347,6 @@ Variables can be referenced in a message with `pass:[#]<ValueReference>pass:[#]`
If the character `pass:[#]` shall be included in the message, it has to be prefixed with `pass:[#]`, so `pass:[#]` 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.]_
+
In case `pass:[#]<ValueReference>pass:[#]` points to an alias set of variables, the environment is free to pick any, or all, of the variable names in the alias set to replace the <<valueReference>>.

[[allocateMemory,`allocateMemory`]]
Function `allocateMemory`::
Expand Down
51 changes: 15 additions & 36 deletions docs/2_2_common_schema.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -608,7 +608,7 @@ _[For example, `N.m`: in this case a `Unit.name = `N.m` must be present under `U
_[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`
|[[displayUnit,`displayUnit`]] 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>`.
Expand Down Expand Up @@ -642,7 +642,7 @@ _where `tolerance` is, for example, the relative tolerance defined in `<DefaultE
|`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 or an alias of it is a continuous <<state>> variable.]_
_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
|Items of an enumeration has a sequence of `name` and `value` pairs.
Expand Down Expand Up @@ -906,7 +906,7 @@ The normalized string `variableName` is used to identify the terminal member var
_[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, which is considered aliasing according to the rules of <<aliasing-of-variables>>.
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._

Expand Down Expand Up @@ -1163,6 +1163,17 @@ It should be noted that changing a <<structuralParameter,`structural parameter`>

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 <<clock,`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:

[source, xml]
----
include::examples/alias_example.xml[tags=VariableAliases]
----

The attributes of variables are:

image::images/ScalarVariable_schema.png[width=90%, align="center"]
Expand All @@ -1181,7 +1192,7 @@ Every variable is uniquely identified within an FMU instance by this name.
[[valueReference,`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 with exception of variables that have identical values (such variables are also called alias variables). `Clock` type variables do not have alias variables and are therefore unique.
It is required to be unique for an FMU.
This attribute is `required`.

|`description`
Expand Down Expand Up @@ -1766,38 +1777,6 @@ _FMI for Co-Simulation:_
_Changing of <<tunable>> <<parameter,`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.]_

===== Aliasing of Variables [[aliasing-of-variables]]

Variables with the same <<valueReference>> are called "alias variables".
The variables that share the same <<valueReference>> are called "alias set".
The main purpose of alias variables is to enhance efficiency.
If two variables `a` and `b` are alias variables, then this is only allowed if the behavior of the FMU would be exactly the same if `a` and `b` were not treated as alias variables (that is, had different <<valueReference>>pass:[s]).
This requirement leads naturally to the following restrictions:

. Variables `a` and `b` that can both be set with `fmi3Set{VariableType}`, or variable `a` that can be set with `fmi3Set{VariableType}` and variable `b` that is defined with <<causality>> = <<independent>>, cannot be alias variables _[since these variables are <<independent>> variables and alias means that there is a constraint equation between variables (= the values are the same), these variables are no longer <<independent>>._ +
_For example, if variables `a` and `b` have <<causality>> = <<parameter>>, then the value references of `a` and `b` must be different._
_However, if variable a has <<causality>> = <<parameter>> and `b` has <<causality>> = <<calculatedParameter>> and `b := a`, then `a` and `b` can have the same value reference.]_

. At most one variable of the same alias set of variables with <<variability>> latexmath:[\neq] <<constant>> can have a <<start>> attribute _[since <<start>> variables are independent initial values.]_

. A variable with <<variability>> = <<constant>> can only be aliased to another variable with <<variability>> = <<constant>>.
It is then required that the <<start>> values of all aliased (constant) variables are identical.

. All variables of the same alias set must all have either no `<Unit>` element defined, or all of them must have the same `<Unit name>` and the same `<Unit><BaseUnit>` definitions.

. All variables of the same alias set must have the same dimensions.

The aliasing of variables only means that the `value` of the variables is always identical.
However, aliased variables may have different attributes, such as `min/max/nominal` values or description texts.
_[For example, if `v1`, `v2` are two alias variables with `v1 = v2` and `v1.max = 10` and `v2.max = 5`, then the FMU will trigger an error if either `v1` or `v2` becomes larger than 5.]_

_[The dependency definition in `fmiModelDescription.ModelStructure` is completely unrelated to the alias definition._
_In particular, the "direct dependency" definition can be a superset of the "real" direct dependency definition, even if the alias information shows that this is too conservative._
_For example, if it is stated that the <<output>> `y1` depends on <<input>> `u1` and the <<output>> `y2` depends on <<input>> `u2`, and `y1` is an alias to `y2`, then this definition is fine, although it can be deduced that in reality neither `y1` nor `y2` depend on any <<input>>.]._

_[In case of different variability among the set of alias variables, and if that set of aliases does not contain an input or parameter, the variability should be the highest of the variables in the set, e.g. continuous > discrete > tunable > fixed._
_If the set includes a parameter or input the aliases will have the stated variability of that parameter or input.]_

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:

image::images/Real_Schema_large.png[width=50%, align="center"]
Expand Down
19 changes: 19 additions & 0 deletions docs/examples/alias_example.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<fmiModelDescription
fmiVersion="3.0-dev"
modelName=""
instantiationToken=""
description=""
generationDateAndTime="2019-04-14T13:06:01Z">
<CoSimulation modelIdentifier="example"/>
<ModelVariables>
<!-- tag::VariableAliases[] -->
<Float64 name="engine.torque" valueReference="1" unit="N.m">
<Alias name="engine.torqueLbfFt" description="Engine torque in pound-foot"
displayUnit="lbf.ft"/>
</Float64>
<!-- end::VariableAliases[] -->
</ModelVariables>
<ModelStructure>
</ModelStructure>
</fmiModelDescription>
56 changes: 55 additions & 1 deletion schema/fmi3Variable.xsd
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<xs:complexType name="fmi3Float64">
<xs:complexContent>
<xs:extension base="fmi3VariableBase">
<xs:sequence>
<xs:element name="Alias" type="fmi3FloatVariableAlias" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attributeGroup ref="fmi3Float64Attributes"/>
<xs:attribute name="start">
<xs:simpleType>
Expand All @@ -56,6 +59,9 @@ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<xs:complexType name="fmi3Float32">
<xs:complexContent>
<xs:extension base="fmi3VariableBase">
<xs:sequence>
<xs:element name="Alias" type="fmi3FloatVariableAlias" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attributeGroup ref="fmi3Float32Attributes"/>
<xs:attribute name="start">
<xs:simpleType>
Expand All @@ -73,6 +79,9 @@ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<xs:complexType name="fmi3Int8">
<xs:complexContent>
<xs:extension base="fmi3VariableBase">
<xs:sequence>
<xs:element name="Alias" type="fmi3VariableAlias" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attributeGroup ref="fmi3Int8Attributes"/>
<xs:attribute name="start">
<xs:simpleType>
Expand All @@ -89,6 +98,9 @@ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<xs:complexType name="fmi3UInt8">
<xs:complexContent>
<xs:extension base="fmi3VariableBase">
<xs:sequence>
<xs:element name="Alias" type="fmi3VariableAlias" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attributeGroup ref="fmi3UInt8Attributes"/>
<xs:attribute name="start">
<xs:simpleType>
Expand All @@ -105,6 +117,9 @@ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<xs:complexType name="fmi3Int16">
<xs:complexContent>
<xs:extension base="fmi3VariableBase">
<xs:sequence>
<xs:element name="Alias" type="fmi3VariableAlias" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attributeGroup ref="fmi3Int16Attributes"/>
<xs:attribute name="start">
<xs:simpleType>
Expand All @@ -121,6 +136,9 @@ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<xs:complexType name="fmi3UInt16">
<xs:complexContent>
<xs:extension base="fmi3VariableBase">
<xs:sequence>
<xs:element name="Alias" type="fmi3VariableAlias" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attributeGroup ref="fmi3UInt16Attributes"/>
<xs:attribute name="start">
<xs:simpleType>
Expand All @@ -137,6 +155,9 @@ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<xs:complexType name="fmi3Int32">
<xs:complexContent>
<xs:extension base="fmi3VariableBase">
<xs:sequence>
<xs:element name="Alias" type="fmi3VariableAlias" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attributeGroup ref="fmi3Int32Attributes"/>
<xs:attribute name="start">
<xs:simpleType>
Expand All @@ -153,6 +174,9 @@ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<xs:complexType name="fmi3UInt32">
<xs:complexContent>
<xs:extension base="fmi3VariableBase">
<xs:sequence>
<xs:element name="Alias" type="fmi3VariableAlias" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attributeGroup ref="fmi3UInt32Attributes"/>
<xs:attribute name="start">
<xs:simpleType>
Expand All @@ -169,6 +193,9 @@ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<xs:complexType name="fmi3Int64">
<xs:complexContent>
<xs:extension base="fmi3VariableBase">
<xs:sequence>
<xs:element name="Alias" type="fmi3VariableAlias" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attributeGroup ref="fmi3Int64Attributes"/>
<xs:attribute name="start">
<xs:simpleType>
Expand All @@ -185,6 +212,9 @@ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<xs:complexType name="fmi3UInt64">
<xs:complexContent>
<xs:extension base="fmi3VariableBase">
<xs:sequence>
<xs:element name="Alias" type="fmi3VariableAlias" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attributeGroup ref="fmi3UInt64Attributes"/>
<xs:attribute name="start">
<xs:simpleType>
Expand All @@ -201,6 +231,9 @@ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<xs:complexType name="fmi3Boolean">
<xs:complexContent>
<xs:extension base="fmi3VariableBase">
<xs:sequence>
<xs:element name="Alias" type="fmi3VariableAlias" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="start">
<xs:simpleType>
<xs:list>
Expand All @@ -223,13 +256,17 @@ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
</xs:attribute>
</xs:complexType>
</xs:element>
<xs:element name="Alias" type="fmi3VariableAlias" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="fmi3Binary">
<xs:complexContent>
<xs:extension base="fmi3VariableBase">
<xs:sequence>
<xs:element name="Alias" type="fmi3VariableAlias" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="mimeType" type="xs:normalizedString" use="optional" default="application/octet-stream">
</xs:attribute>
<xs:attribute name="maxSize" type="xs:nonNegativeInteger" use="optional">
Expand All @@ -252,6 +289,9 @@ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<xs:complexType name="fmi3Enumeration">
<xs:complexContent>
<xs:extension base="fmi3EnumerationBase">
<xs:sequence>
<xs:element name="Alias" type="fmi3VariableAlias" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="declaredType" type="xs:normalizedString" use="required">
</xs:attribute>
<xs:attribute name="quantity" type="xs:normalizedString"/>
Expand All @@ -272,11 +312,25 @@ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<xs:complexType name="fmi3Clock">
<xs:complexContent>
<xs:extension base="fmi3VariableBase">
<xs:sequence>
<xs:element name="Alias" type="fmi3VariableAlias" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attributeGroup ref="fmi3ClockAttributes"/>
<xs:attribute name="start" type="xs:boolean"/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:complexType>
<xs:complexType name="fmi3VariableAlias">
<xs:attribute name="name" type="xs:normalizedString" use="required"/>
<xs:attribute name="description" type="xs:string"/>
</xs:complexType>
<xs:complexType name="fmi3FloatVariableAlias">
<xs:complexContent>
<xs:extension base="fmi3VariableAlias">
<xs:attribute name="displayUnit" type="xs:normalizedString"/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="fmi3VariableBase" abstract="true">
<xs:sequence>
<xs:element name="Dimension" minOccurs="0" maxOccurs="unbounded">
Expand Down

0 comments on commit ca5f9d6

Please sign in to comment.