Opened 10 years ago
Last modified 6 years ago
#3186 assigned defect
Partial binding of record sub-components in functions are lost
Reported by: | Rüdiger Franke | Owned by: | Per Östlund |
---|---|---|---|
Priority: | critical | Milestone: | 2.0.0 |
Component: | New Instantiation | Version: | trunk |
Keywords: | Cc: | Per Östlund |
Description (last modified by )
The modifiers on record S, variable s in function precalculation are lost during flattening. See the model below.
Today's test show an increase from 74 to 89 built models for the PowerSystems library, see
https://test.openmodelica.org/libraries/history/PowerSystems-trend.svg
This is due to the introduction of the workaround M3 of #3183, see
https://github.com/modelica/PowerSystems/commit/bb0593fd7db98de8af4ead2c2047a280267955ef
Interestingly no compilation error occurs. The simulations fail with divisions by zero, because the record constructor functions are not called.
See the following example:
package MissingPrecalculation record R parameter Integer nr; Real[nr] vr; end R; record S parameter Integer ns; Real[ns] vs; end S; function precalculation input R r; output S s(ns = r.nr); algorithm s.vs := 2*r.vr; end precalculation; model M3 parameter R r(nr = 2, vr = {1, 2}); record S2 = S(ns = r.nr); parameter S2 s = precalculation(r); end M3; end MissingPrecalculation;
Flattening results in:
function MissingPrecalculation.precalculation input MissingPrecalculation.R r; output MissingPrecalculation.S s; algorithm s.vs := r.vr * 2.0; end MissingPrecalculation.precalculation; class MissingPrecalculation.M3 parameter Integer r.nr = 2; parameter Real r.vr[1] = 1.0; parameter Real r.vr[2] = 2.0; parameter Integer s.ns = s.r.nr; parameter Real s.vs[1]; parameter Real s.vs[2]; end MissingPrecalculation.M3;
Couldn't the the modifier for ns be kept in the precalculation function and the function call be placed in initial equations:
function MissingPrecalculation.precalculation input MissingPrecalculation.R r; output MissingPrecalculation.S s(ns = r.nr); algorithm s.vs := r.vr * 2.0; end MissingPrecalculation.precalculation; class MissingPrecalculation.M3 parameter Integer r.nr = 2; parameter Real r.vr[1] = 1.0; parameter Real r.vr[2] = 2.0; parameter Integer s.ns(fixed = false); parameter Real s.vs[1](fixed = false); parameter Real s.vs[2](fixed = false); initial equation s = /*.MissingPrecalculation.S*/(MissingPrecalculation.precalculation(/*.MissingPrecalculation.R*/(r))); end MissingPrecalculation.M3;
Any other idea?
Change History (25)
comment:1 by , 10 years ago
Description: | modified (diff) |
---|
comment:2 by , 10 years ago
Description: | modified (diff) |
---|
comment:3 by , 10 years ago
comment:4 by , 10 years ago
It seems we handle modifiers for record components inside functions badly.
It would work if you say:
function precalculation input R r; output S s = S(ns = r.nr, vs = 2*r.vr); end precalculation;
Is not very clear for me how to handle such modifiers inside functions, I will need to think about it.
comment:5 by , 10 years ago
And, btw the record constructor function is not lost during flattening.
We evaluate the function call and replace it with the result because we need to know the array sizes inside the record components.
comment:6 by , 10 years ago
The structural part of the precalculation
function finds in its signature -- output S s(ns = r.nr)
. This is needed because S.ns is a parameter that cannot be changed in the algorithm section anymore. The other members of S
should be treated as regular model parameters that are calculated at runtime from the free parameters R r
.
Couldn't only the function signature be evaluated during flattening, while the function as such is evaluated at runtime?
See also #3182.
comment:7 by , 10 years ago
Unfortunately the current front-end design evaluates a lot of things during compile time (should only evaluate structural parameters) and it will take some time to change.
I think that the modification part of output S s(ns = r.nr);
should become an assignment s.ns = r.nr;
used to set the output structure after its declaration.
We should keep the binding and use it to set the output structure member after its declaration.
comment:8 by , 10 years ago
Owner: | changed from | to
---|---|
Status: | new → accepted |
There are 2 issues here:
record S2 = S(ns = ns);
generates a record constructor withinput Integer ns = ns;
which has wrong scoping- the binding for
output S s(ns = r.nr);
is saved inside the type of s and not as a binding for s as that is not currently possible (we can only have default bindings for the entire record variable, not for sub-components).
comment:9 by , 10 years ago
Regarding issue 1: record S2 is just a workaround anyway -- but I wonder how Fluid works then, because it modifies types of flow and heat transfer models a lot. Issue 2 might be treated by explicitly calling a record constructor for the output precalculation.s as you propose in comment:4.
This requires the treatment of two new things:
- each record member must get a value from the constructor (but please not more than a default value that is changed in the algorithm section afterwards, because the algorithm is generally not trivial)
- it results in the translation error: Looking for a function S but found a record
It appears that both issues can be treated with an operator record:
package MissingPrecalculation record R parameter Integer nr; Real[nr] vr; end R; operator record S parameter Integer ns; Real[ns] vs; encapsulated operator 'constructor' import MissingPrecalculation.S; function fromSize input Integer ns; output S s(ns = ns, vs = zeros(ns)); end fromSize; end 'constructor'; end S; function precalculation input R r; output S s = S(ns = r.nr); algorithm s.vs := 2*r.vr; end precalculation; model M5 parameter R r(nr = 2, vr = {1, 2}); parameter S s = precalculation(r); Real t = 1/s.vs[2]; end M5; end MissingPrecalculation;
comment:10 by , 10 years ago
Live could be so easy, but Modelica libs aren't. While M5 given in above is working, the real AC3ph machine models additionally replace the input parameter record. This produces again the translation error "Could not evaluate structural parameter (or constant) ns which gives dimensions of array: vs[ns]". See M6 below:
package MissingPrecalculation record R parameter Integer nr; Real[nr] vr; end R; record R1 extends R(nr = 2, vr = {1, 2}); end R1; operator record S parameter Integer ns; Real[ns] vs; encapsulated operator 'constructor' import MissingPrecalculation.S; function fromSize input Integer ns; output S s(ns = ns, vs = zeros(ns)); algorithm end fromSize; end 'constructor'; end S; function precalculation input R r; output S s = S(ns = r.nr); algorithm s.vs := 2*r.vr; end precalculation; model M5 replaceable parameter R r; parameter S s = precalculation(r); Real t = 1/s.vs[2]; end M5; model M6 extends M5(redeclare replaceable parameter R1 r); end M6; end MissingPrecalculation;
comment:11 by , 10 years ago
Description: | modified (diff) |
---|---|
Summary: | Record constructor function lost during flattening → Partial binding of record sub-components in functions are lost |
comment:12 by , 10 years ago
The commit
https://github.com/modelica/PowerSystems/commit/592eaed2e3d1c48ac35da597a4d5860675796e20
brings the lib back to its original status (see #3183). This is because the ultimate solution might require other changes anyway -- or no changes at all.
The nightly tests should now report frontend failures for the AC3ph machine models again, as opposed to simulation failures that result from the lost partial bindings.
comment:13 by , 10 years ago
Milestone: | 1.9.2 → 1.9.3 |
---|
Milestone changed to 1.9.3 since 1.9.2 was released.
comment:18 by , 8 years ago
Milestone: | 1.11.0 → 1.12.0 |
---|
Milestone moved to 1.12.0 due to 1.11.0 already being released.
comment:19 by , 7 years ago
Milestone: | 1.12.0 → Future |
---|
The milestone of this ticket has been reassigned to "Future".
If you think the issue is still valid and relevant for you, please select milestone 1.13.0 for back-end, code generation and run-time issues, or 2.0.0 for front-end issues.
If you are aware that the problem is no longer present, please select the milestone corresponding to the version of OMC you used to check that, and set the status to "worksforme".
In both cases, a short informative comment would be welcome.
comment:20 by , 6 years ago
Milestone: | Future → 2.0.0 |
---|
follow-up: 23 comment:22 by , 6 years ago
Cc: | added |
---|
comment:23 by , 6 years ago
comment:24 by , 6 years ago
Owner: | changed from | to
---|---|
Status: | accepted → assigned |
comment:25 by , 6 years ago
Component: | Frontend → New Instantiation |
---|
Here is a version of the test model that compiles and simulates with uninitialised parameters (see also all the
PowerSystems.Examples.Spot.*AC3ph.*
that compile and fail during simulation, likeDrivesAC3ph.SM_ctrlAv
orGenerationAC3ph.TurbineGenerator
):Flattening gives:
Lacking the call to
MissingPrecalculation.precalculation
and resolving s.ns only by chance, the translation warns:The simulation runs and fails with division by zero.