#4027 closed defect (fixed)
Missing values of final parameters in FMU export
Reported by: | Rüdiger Franke | Owned by: | Patrick Täuber |
---|---|---|---|
Priority: | blocker | Milestone: | |
Component: | FMI | Version: | v1.11.0 |
Keywords: | Cc: |
Description
The following model simulates correctly. The value of a
is not generated in the C or Cpp code, but stored in FinalParameter_init.xml
.
model FinalParameter final parameter Real a = 1; end FinalParameter;
When exported as FMU 2, then modelDescription.xml
contains:
<ScalarVariable name="a" valueReference="0" variability="fixed" causality="calculatedParameter" initial="calculated"> <Real/> </ScalarVariable>
The value of a
is lost.
Change History (19)
follow-up: 2 comment:1 by , 8 years ago
comment:2 by , 8 years ago
Replying to vitalij:
possible the issue is modul
evaluateReplaceProtectedFinalEvaluateParameters
, where OM evaluate final parameter.
It's possible to test following omc-flags:
--preOptModules-=evaluateReplaceProtectedFinalEvaluateParameters --preOptModules+=evaluateReplaceEvaluateParameters?
This is not related to the module evaluateReplaceProtectedFinalEvaluateParameters
. All the information is in the DAE, but it seems that the attributes are not exported properly for final parameters.
comment:3 by , 8 years ago
@rfranke I don't have much experience with FMI. What is the expected behavior? Should the value of a
be stored in the generated code or should the start attribute show up in the modelDescription.xml
?
comment:4 by , 8 years ago
modelDescription.xml
is correct. The expected behaviour is that the value of a
is treated in the generated code. See also the following example:
model FinalParameter2 parameter Real p = 1; final parameter Real a = 2*p; Real b = 1/a; end FinalParameter2;
The C / Cpp code assigns the constant value 0.5 to b
. This is wrong if the value of p
is changed at runtime. This is why either the final parameter a
(and b
) should be calculated in the C / Cpp code or p
should be evaluated during translation along with a
. The latter allows the same treatment for final parameter Real a
and parameter Real a annotation(Evaluate=true)
.
comment:5 by , 8 years ago
See yet another example:
model FinalParameter3 final parameter Real[:] a = {1, 2, 3}; input Integer offs = 0; Real b = 1/a[1+offs]; end FinalParameter3;
Here offs
is not known at translation time and b
is calculated at runtime. The final parameter array a
has no values though in the FMU -- resulting in division by zero.
comment:6 by , 8 years ago
According to the Modelica specification "final" parameters should not be treated in the backend like evaluated parameters (latter option in comment:4 above).
The first option given in comment:4 is correct. Final parameters are treated like calculated parameters in the backend.
See e.g. Modelica spec, section 12.6 Record Constructor Functions:
record Record2 constant c1 = 2.0; parameter Real r2 = sin(c1); final parameter Real r3 = cos(r2); end Record2
gives the record constructing function:
function Record2 input Real c2; input Real r2 := Modelica.Math.sin(c1); output Record2 'result'(c2=c2,r2=r2); protected final parameter Real r3 = Modelica.Math.cos(r2); end Record2;
This function can be called in the following way:
Record2 rec2 = Record2(c2=2, r2=2);
This makes clear that r2
can still be changed, resulting in a recalculation of r3.
In other words:
model FinalParameter4 parameter Real p = 1; final parameter Real q = 2; final parameter Real a = 2*p; end FinalParameter4;
has one paramter p
that can be changed after model translation and two calculated parameters q
and a
. q
has the hard coded value 2 and a
is calculated in the C/Cpp code.
comment:7 by , 8 years ago
Owner: | changed from | to
---|---|
Status: | new → assigned |
comment:8 by , 8 years ago
Status: | assigned → accepted |
---|
I opened a ticket on the Modelica trac 5 weeks ago to clarify the meaning of final parameter
(see here). What Rüdiger proposes corresponds to option b. However, there is some unclear behavior comparing to Dymola. We think that it should be possible to override parameters with a binding expression even though this is not possible using Dymola.
Today, I discussed this issue with Lennart again and we came up with the following conclusion:
- Final parameters should not be evaluated in the backend unless they are structural parameters. In this case all other parameters that are part of the bindings need also to be calculated during compilation, set to final, and should get reported using a notification.
- Parameters can get overridden during runtime unless they are final or protected.
- Parameters with
Evaluate=true
annotation need to be set final in order to make them unchangeable during runtime. In this case all other parameters that are part of the bindings need also to be calculated during compilation, set to final, and should get reported using a notification.
comment:9 by , 8 years ago
I just tested the model from the description and model FinalParameter3
. Both models run correctly with FMU 2.0 for me. The values of a
are stored and there is no division by zero for model FinalParameter3
. I used the following commands:
translateModelFMU(FinalParameter3, version="2.0"); getErrorString(); importFMU("FinalParameter3.fmu"); getErrorString(); loadFile("FinalParameter3_me_FMU.mo"); getErrorString(); simulate(FinalParameter3_me_FMU); getErrorString(); val(a_1_, 0.0); getErrorString(); val(a_2_, 0.0); getErrorString(); val(a_3_, 0.0); getErrorString();
Can you please provide a .mos-script to reproduce the problem?
comment:10 by , 8 years ago
@ptauber: it might be that the OM import reads the values in the modelDescription.xml file and sets them when simulating the FMI. You could try to run the FMU with the fmi checker:
https://trac.fmi-standard.org/browser/branches/public/Test_FMUs/Compliance-Checker
or import it in Dymola.
comment:11 by , 8 years ago
The relevant values are not stored in the modelDescription.xml
. But FMI checker seems to have no problems with the FMU, too:
FMU check summary: FMU reported: 0 warning(s) and error(s) Checker reported: 0 Warning(s) 0 Error(s)
comment:12 by , 8 years ago
That's interesting. FinalParameter3
works with the C runtime. The reported error can be reproduced with the Cpp runtime:
loadModel(Modelica); loadFile("FinalParameter3.mo"); setCommandLineOptions("+simCodeTarget=Cpp"); translateModelFMU(FinalParameter3, version="2.0"); getErrorString(); importFMU("FinalParameter3.fmu"); getErrorString(); loadFile("FinalParameter3_me_FMU.mo"); getErrorString(); simulate(FinalParameter3_me_FMU); getErrorString(); val(a_1_, 0.0); getErrorString(); val(a_2_, 0.0); getErrorString(); val(a_3_, 0.0); getErrorString();
It needs to be investigated what the Cpp runtime does wrong here.
In the meantime, please have a look at FinalParameter2.
loadModel(Modelica); loadFile("FinalParameter2.mo"); translateModelFMU(FinalParameter2, version="2.0"); getErrorString(); importFMU("FinalParameter2.fmu"); getErrorString(); loadFile("FinalParameter2_me_FMU.mo"); getErrorString(); simulate(FinalParameter2_me_FMU); getErrorString(); val(b, 0.0); getErrorString();
The value of b
is 0.5. If you change the parameter p
after the export of the FMU to 2, then b
will still be 0.5, instead of 0.25.
I changed p
in the file FinalParameter2_me_FMU.mo
, line 7. Do you know how to encode this in a mos script?
comment:13 by , 8 years ago
@rfranke You can use the override flag:
simulate(FinalParameter2_me_FMU, simflags="-override p=2"); getErrorString();
comment:14 by , 8 years ago
The problem with FinalParameter2.mo
is as Vitalij said above that OM evaluates the final parameters in the Backend. The default module evaluateReplaceProtectedFinalEvaluateParameters
does this in an inconsistent way. So in the case of FinalParameter2.mo
a
is evaluated with the value of p
. If you do so, you have to set p
final, too, to avoid inconsistency. This is not done so that you still can change the value of p
.
This problem is also topic of ticket:3211 and will be handled by the implementation of the concept in comment:8.
In the meantime you can deactivate the parameter evaluation with
setCommandLineOptions("--preOptModules-=evaluateReplaceProtectedFinalEvaluateParameters --preOptModules+=evaluateReplaceEvaluateParameters");
comment:15 by , 8 years ago
25249c864ee6b90431f618d4ee42d2deb580c4d1/OMCompiler
"Fix initialization problems containing parameters having implicitly fixed=false" goes into the right direction.
Unfortunately it was not discovered that this broke Cpp FMI export. See d7838200a0f2d92b7070fae39c8df573eed80f73/OMCompiler and the extended tests.
follow-up: 17 comment:16 by , 8 years ago
@rfranke Your last commit seems to fix the problem with the missing values when translating the FMU with Cpp runtime. Unfortunately, commit c8b206 leads to segmentation faults (in 4 of 5 cases on my machine) even for the simple model FinalParameter from the description (with Cpp).
comment:17 by , 8 years ago
Replying to ptaeuber:
Unfortunately, commit c8b206 leads to segmentation faults (in 4 of 5 cases on my machine) even for the simple model FinalParameter from the description (with Cpp).
Did you recompile the Cpp runtime?
Note the change in SimulationRuntime/cpp/Core/System/SimVars.cpp in the linked changeset.
Btw. I found that missing initialization of a null pointer by invoking "Simulate with Algorithmic Debugger" from OMEdit -- this shows the stack trace of the segfault.
comment:18 by , 8 years ago
Resolution: | → fixed |
---|---|
Status: | accepted → closed |
possible the issue is modul
evaluateReplaceProtectedFinalEvaluateParameters
, where OM evaluate final parameter.It's possible to test following omc-flags:
?