modelica / fmi-standard

Specification of the Functional Mock-up Interface (FMI)

Home Page:https://fmi-standard.org/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Clarification on fmi2SetXXX

nik5346 opened this issue · comments

I need a clarification on when a simulation tool is allowed to call the fmi2SetXXX functions.

In version 2.0.4, page 50 is stated:

fmi2SetXXX" can be called on any variable for ModelExchange in Continuous-Time Mode

In version 2.0.4, page 90 the table states:

fmi2SetReal can be called in "instantiated", "initilization mode", "event mode", "continuous-time mode"
fmi2SetInteger can be called in "instantiated", "initilization mode", "event mode"
fmi2SetBoolean can be called in "instantiated", "initilization mode", "event mode"
fmi2SetString can be called in "instantiated", "initilization mode", "event mode"

  1. Which page is correct?
  2. If page 90 is correct: Why is it not allowed to call fmi2SetInteger, fmi2SetBoolean and fmi2SetString in continuous time?
  3. If page 90 is correct: Why was this restriction dropped in fmi3?
  4. If page 90 is correct: Since most simulations tools call fmi2SetInteger, fmi2SetBoolean and fmi2SetString in continuous time mode anyway. Why not change the standard and allow these functions to be called in continuous time mode? (For example Simulink, MapleSim and Dymola call these functions in continuous time mode.)

p 2.0.4, p. 50:

fmi2SetXXX can be called on any variable for ModelExchange in Continuous-Time Mode
• if causality = "input" and variability = "continuous"

Why is it not allowed to call fmi2SetInteger, fmi2SetBoolean and fmi2SetString in continuous time?

Discrete variables cannot be set in Continuous Time Mode.

@t-sommer
You did not understand the question.

Let's say I have a int variable. This variable is continuous (NOT DISCRETE) and is an input.

According to page 50, fmi2SetInteger can be called for this variable in continuous time mode.
But on page 90 is stated the fmi2SetInteger function for this variable can only be called in event mode.

Which page is correct?

Maybe I'm missing something in your discussion, but an fmi2Integer variable cannot be continuous, it can only change discretely (otherwise it would need to be fmi2Real to be able to represent the continuous change). Only fmi2Real variables can be of continuous variability.

@pmai
I just searched the documentation and also had a look at the XSD files. There is no restriction for the variability. Every datatype can have every variability. Therefor the fmi2Integer can be continuous.
Can you proof me wrong?

It is stated in the in the specification (variable attribute description for variability, p. 49):
"continuous": Only a variable of type = “Real” can be “continuous”.

@PTaeuberDS Thanks, I did not see that.

What is the reason for this odd decision?
What is the default variability for an fmi2Integer variable then?
The documentation says for all variables:

The default is “continuous”.

It is not an odd restriction in the sense that by definition variables of type integer are discrete: A variable is discrete if and only if there is a mapping into N (the set of natural numbers).

From a mathematical perspective it is more surprising that we treat fmi2Real as potentially continuous, since in a strict sense IEEE754 floating point numbers are of course also discrete. However experience has shown that one can profitably use floating point numbers to approximate reals, and any variable over a subset of R can be a continuous variable if the variable can take on any of the values in the subset (making it an uncountable set, which therefore cannot have a mapping to N).

The distinction between discrete and continuous variables is important because for continuous variables you can use the methods of calculus, e.g. derivatives are well-defined. For discrete variables this does not work, so one is thrown back to difference equations, etc.

Or to turn the question around: What definition of continuous do you have in mind where a continuous integer variable would make sense and what would it mean?

@pmai
I don't think your interpretation is in line with the fmi2 standard.
An integer can only represent natural numbers and a float tries to represent real numbers. Therefor you could argue, an integer is value discrete and a float is continuous in it's value representation.

However the fmi2 variability describes the time dependency of a variable (Verision 2.0.4 page 49):

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 (ModelExchange) or at a communication point (CoSimulation) and it is therefore only necessary to inquire them with fmi2GetXXX and store them at event times].

In my opinion a integer can change it's value at every given time and not only at an event. That's why I think the restriction to disallow an integer to be "continuous" is odd.

In my opinion the documentation does not clearly state if an integer can be continuous or not. There are multiple contradictory passages in the documentation.

If an integer can not be continuous what is it's default variability? It seems not to be defined?!

I am still confused and still need clarification on this issue.

Consider a feedthrough system (input directly maps to output). Both input and output are of type integer.
In order to simulate this model correctly, you would need to trigger an event at every time instant in order to get the simulation environment to call fmi2SetInteger. This is a design flaw in my opinion.

@pmai I don't think your interpretation is in line with the fmi2 standard.

I was not interpreting the standard, but discussing mathematical reality.

An integer can only represent natural numbers and a float tries to represent real numbers. Therefor you could argue, an integer is value discrete and a float is continuous in it's value representation.

That is what I said, except of course a float's value representation is indeed not continuous but discrete, but interpreting it as standing in for a real enables us to pretend that we are talking about continuous variables. That is the basis (and the root of a number of problems) of numerical simulation.

However the fmi2 variability describes the time dependency of a variable (Verision 2.0.4 page 49):

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 (ModelExchange) or at a communication point (CoSimulation) and it is therefore only necessary to inquire them with fmi2GetXXX and store them at event times].

In my opinion a integer can change it's value at every given time and not only at an event. That's why I think the restriction to disallow an integer to be "continuous" is odd.

It obviously cannot, since an integer changing its value, as it is a discrete variable, necessarily entails an event. Again, mathematical reality, which transcends FMI, but also directly what the standard states right there.

But again I ask, what would be the/your interpretation of a continuous integer (and hence mathematically inherently discrete) variable? Am I allowed to calculate derivatives of it against time? Interpolate it between time steps? If not, in which sense is it continuous? What are you trying to achieve that you want continuous discrete variables?

In my opinion the documentation does not clearly state if an integer can be continuous or not. There are multiple contradictory passages in the documentation.

Even if there are any contradictions, it flatly states that only reals can be continuous, that is as normative as it gets. Given that it flat out states this, and that there is no usefuly interpretation of what a continuous integer should be, I fail to see the point of trying to interpret it differently.

These areas have been refined in FMI 3.0, btw. to make some of the definitions clearer and handle the default better, but that does make the FMI 2.0 definition ambiguous enough that one should under any reasonable interpretation of the standard expect that it allows things that make no mathematical sense.

If an integer can not be continuous what is it's default variability? It seems not to be defined?!

Under the old reading it would be continuous, which would be illegal, hence you always have to specify it for non-real variables. For FMI 3.0 we changed this.

I am still confused and still need clarification on this issue.

Consider a feedthrough system (input directly maps to output). Both input and output are of type integer. In order to simulate this model correctly, you would need to trigger an event at every time instant in order to get the simulation environment to call fmi2SetInteger. This is a design flaw in my opinion.

No that is just mathematical reality: A discrete variable changing its value constitutes an event (as it is by definition a discontinuous change), and you have to handle it - especially for a feedthrough system, where this will directly trigger discontinous changes in other connected FMUs/systems. It is up to the simulator to enter event mode prior to changing discrete variables. It will do so. What is your expectation of how the simulator should handle these discontinuous changes?

I don't think you understood the concept of time discrete/continuous and value discrete/continuous variables.
A variable can be time continuous and value continuous or
a variable can be time discrete and value continuous or
a variable can be time continuous and value discrete or
a variable can be time discrete and value discrete.
All of these pairing make sense. Clearly the "sense" depends on your model.

In real world reality, all simulation tools (Simulink, MapleSim, Dymola, ...) allow fmi2SetInteger to be called in continuous time mode. Why does the "mathematical reality" not apply to these tools?

Why does the "mathematical reality" not apply to fmi3 then? I did not get that either.

I am once again asking, what the default variability for an integer variable is.
The standard allows the modelDescription.xml to look like this (note the missing variability attribute!):

...
<ScalarVariable name="Integer_input" valueReference="2" causality="input">
     <Integer start="0"/>
</ScalarVariable>
...

Here is the XSD file:

...
<xs:attribute name="variability" default="continuous">
	<xs:annotation>
		<xs:documentation>constant: value never changes
fixed: value fixed after initialization
tunable: value constant between external events
discrete: value constant between internal events
continuous: no restriction on value changes</xs:documentation>
	</xs:annotation>
	<xs:simpleType>
		<xs:restriction base="xs:normalizedString">
			<xs:enumeration value="constant"/>
			<xs:enumeration value="fixed"/>
			<xs:enumeration value="tunable"/>
			<xs:enumeration value="discrete"/>
			<xs:enumeration value="continuous"/>
		</xs:restriction>
	</xs:simpleType>
</xs:attribute>
...

The standard documentation only states

The default is “continuous”.

but since an integer can not be continuous, how should the simulation tool set the variability for this variable?

At very least the undefined default variability for integer/boolean/string/enum variables should be clarified in fmi2.0.5.

In real world reality, all simulation tools (Simulink, MapleSim, Dymola, ...) allow fmi2SetInteger to be called in continuous time mode. Why does the "mathematical reality" not apply to these tools?

If they call fmi2SetInteger on a discrete variable (variability = discrete), then they are not conforming to the standard (which I suspect is not the case).

If they allow this to happen for variables of type Integer with variability = continuous that is behaviour beyond the standard, but not a conformance issue, since the relevant FMU is not conforming, thus allowing an importer to do as it pleases.

But your question was about the standard, not tools.

Why does the "mathematical reality" not apply to fmi3 then? I did not get that either.

The situation in fmi2 and fmi3 is identical; the only thing that changed is that in FMI3 the defaults are a bit nicer, for people who care about the defaults.

I am once again asking, what the default variability for an integer variable is.

And, as you have found, and has been repeatedly pointed out, it is continuous, which is illegal for Integer variables. Hence a conforming FMU must always explicitly specify a different variability, e.g. discrete.

The standard allows the modelDescription.xml to look like this:

...

<ScalarVariable name="Integer_input" valueReference="2" causality="input">

     <Integer start="0"/>

</ScalarVariable>

...

The standard only states

The default is “continuous”.

but since an integer can not be continuous, how should the simulation tool set the variability for this variable?

It should not, it can just reject the FMU as it violates the standard, specifically the clause that states that only Real variables can have variability continuous. There are many ways in which you can generate an XML that satisfies the Schema, but violates the spec (e.g. non-unique VRs, missing start values for certain variables, or present start values in other cases, etc.). This is just another case of this.

Of course an implementation is also free to handle this FMU in other ways (e.g. substitute discrete, or treat them as magical continuous discrete variables whatever that means, start WW3).

At very least this should be clarified in fmi2.0.5.

I still fail to see how one can go from

The default value is continuous.

and

Only variables of type Real can have variability continuous.

to somehow believing that the default value magically negates the other sentence or sneakily but intentionally introduces continuous discrete variables without any known semantics.

That being said, propose a clarification for 2.0.5 and it might be adopted.

If they call fmi2SetInteger on a discrete variable (variability = discrete), then they are not conforming to the standard (which I suspect is not the case).

I logged the call sequences for multiple tools. I can guarantee they all call fmi2StInteger in continuous time mode. You can check it yourself. Just wrap a logger in an FMU, or just use my feedthrough FMU with integrated logger: https://github.com/nik5346/FeedThroughFmu

The situation in fmi2 and fmi3 is identical; the only thing that changed is that in FMI3 the defaults are a bit nicer, for people who care about the defaults.

You are right about that. I overlooked it here as well.

... to somehow believing that the default value magically negates the other sentence or sneakily but intentionally introduces continuous discrete variables without any known semantics.

The XSD schema is simply wrong, when an integer can't be continuous. Thats what I say. I only use informations from the PDF to check modelDescriptions, when the rules in question are undefined in the XSD schema.

Here is the call sequence for Simulink: https://de.mathworks.com/help/simulink/ug/fmu-block-calling-sequences.html

The calling sequence for ME 2.0 clearly states the it only calls fmi2Set on continuous input. That would be correct.

So unless the variable is declared with variability continuous I would, from the above description, not expect any set calls for it outside event mode.

If the implementation deviates from this, write a bug report.

The XSD schema is simply wrong, when an integer can't be continuous. Thats what I say. I only use informations from the PDF to check modelDescriptions, when the rules in question are undefined in the XSD schema.

And that is of course the wrong approach: Nothing in the FMI standard states that just relying or even primarily relying on the schema is a valid approach. While the schema is normative as to what it specifies, it specifies very little, and most of the relevant rules are defined in the standard itself.

And what is stated there is simple, if maybe a bit inconvenient: The default is continuous, and only Real variables can be continuous. I.e. only real variables can make use of the default, everything else needs to be explicitly specified. Given that the default is primarily useful for minimising the modelDescription, and for the common use cases the set of reals is far larger than anything else, this default makes sense. Would a programmatically defined default, like in FMI3, have made even more sense? Yes, maybe, hence the change, but it comes at the cost of not being representable in XML Schema 1.0, thus has to be handled in Code after parsing.

In summary: It is not that I don't get what you are saying, I'm just saying you are wrong and have no leg to stand on, because you are approaching interpreting a standard in the wrong way.