Open henrikt-ma opened 3 years ago
I suppose this is a question of the Modelica's modelling approach, not of a particular model, right?
I suppose this is a question of the Modelica's modelling approach, not of a particular model, right?
I would also guess so, and I agree that there isn't any problem here.
We have
spring.spring.c = spring.c; /* Declaration equation for fixed = true parameter 'spring.spring.c'. */
f = spring.spring.c * (s_rel - s_rel0); /* Equation from Translational.Components.Spring. */
rev.a=some function of f and gravity.
rev.a=0;
and we want to determine spring.c which has fixed=false (in addition spring.spring.c, rev.a and f are unknowns of this system of equations), which is perfectly ok. I don't see that the fixed-ness of spring.c has much relevance for this (except that if spring.c were fixed we would need to remove the last equation to have same number of unknowns and equations).
To me it seems clear that we can use all of these equations to solve for spring.c; and my only take-away is that viewing parameter bindings as initial equations seem to increase the level of confusion.
OOPS - UPDATED
Slight editing error in previous comment. See update on GitHub.
I suppose this is a question of the Modelica's modelling approach, not of a particular model, right?
The intention was to see this as a problem with this particular model, as I could see two different solutions that would involve just changing the modifications in the top level model.
Now I need to think more about @HansOlsson's way of grouping the equations…
Let me begin by answering to the conclusion before drowning in technical detail:
To me it seems clear that we can use all of these equations to solve for spring.c; and my only take-away is that viewing parameter bindings as initial equations seem to increase the level of confusion.
I don't follow; to me it looked just like you suggested a view based on solving four equations with respect to four variables?
Without seeing the light in this discussion yet, my take-away so far is that there is just more evidence that initialization is complicated, and the more we can explain it in terms of basic equations rather than special declaration equation rules, the better. That said, I don't either think this is as easy as just turning everything into basic equations.
I guess @gkurzbach would be interested in joining this discussion as it is right at the heart of our most recent Flat Modelica discussions in https://github.com/modelica/ModelicaSpecification/pull/2748, but it seems he is not a member of the project on GitHub?
We have
spring.spring.c = spring.c; /* Declaration equation for fixed = true parameter 'spring.spring.c'. */ f = spring.spring.c * (s_rel - s_rel0); /* Equation from Translational.Components.Spring. */ rev.a=some function of f and gravity. rev.a=0;
and we want to determine spring.c which has fixed=false (in addition spring.spring.c, rev.a and f are unknowns of this system of equations), which is perfectly ok. I don't see that the fixed-ness of spring.c has much relevance for this (except that if spring.c were fixed we would need to remove the last equation to have same number of unknowns and equations).
My problem with this way of thinking is that my understanding of fixed = true
vs fixed = false
collides with what I think of as the basic way of solving a potentially large set of equations: matching and identification of strong components. For anyone who doesn't immediately see what I refer to, matching and topological sorting of equations reveals the following strong components:
/* Component 1 */
rev.a = 0; -- rev.a
/* Component 2 */
rev.a = some function of f and gravity; -- f
/* Component 3 */
f = spring.spring.c * (s_rel - s_rel0); -- spring.spring.c
/* Component 4 */
spring.spring.c = spring.c; -- spring.c
However, I expect my non-final fixed = true
parameter spring.spring.c
to be solved from its declaration equation. One reason, beside vague intuition, for this is that being solved from its own declaration equation is a guarantee for being able to override the declaration equation with some other value during initialization.
This reasoning is what gave rise to this issue, because it doesn't allow the above matching of spring.spring.c
. The problem is avoided by staying away from the non-final fixed = true
declaration equation. Making it fixed = false
is the most obvious way to get rid of the matching constraint for spring.spring.c
, but it can also be seen that the above argument for having a matching constraint only applies for non-final declaration equations, so making it final is another way to get rid of the constraint (and there is no need to think in terms of alias elimination, as suggested in a comment above).
To me, it looks like a language group issue to make sure that initialization semantics are clarified so that there is no question about how it should be done in the MSL. I don't even expect modelica/ModelicaSpecification#2748 to settle this, so I think the present issue needs to be closed one way or another given the current state of the specification.
Instead of simply closing as a won't fix, we could also consider what the drawbacks would be of setting fixed = false
for spring.spring.c
while waiting for language specification clarification.
However, I expect my non-final
fixed = true
parameterspring.spring.c
to be solved from its declaration equation.
To me one interpretation is that spring.c
is unknown in a small system of equations, and we compute spring.spring.c
from its declaration equation - but within that system of equations so, we have a system with spring.c
as unknown and we then solve fora=0
(right?);
spring.spring.c:=spring.c;
f:=spring.spring.c*(s_rel-s_rel0);
a:=...;
Obviously that could be formulated in other equivalent ways, but the main conclusion is that I don't see a need to change this model.
The intuition is that spring.c is unknown, and spring.spring.c is given by spring.c - regardless of whether spring.c is known or unknown; and to me the important part is this separation of concern - you are trying to "tune" spring.c to find the correct solution where a=0 and that shouldn't change any else. If you find the correct value of spring.c it should just be a matter of setting spring.c to that, disabling fixed=false, and removing the initial equation for a.
Instead of simply closing as a won't fix, we could also consider what the drawbacks would be of setting
fixed = false
forspring.spring.c
while waiting for language specification clarification.
The specification has a comment indicating that setting fixed=false for a parameter with a binding equation should give a warning; so that temporary change would be bad.
Instead of simply closing as a won't fix, we could also consider what the drawbacks would be of setting
fixed = false
forspring.spring.c
while waiting for language specification clarification.The specification has a comment indicating that setting fixed=false for a parameter with a binding equation should give a warning; so that temporary change would be bad.
Yes, it says binding equation, but does it really mean any declaration equation, or just the case of an equation given at the original component declaration? Since what we have here illustrates that declaration equations combined with fixed = false
might actually be useful, I'm tempted to interpret the suggestion for recommended diagnostics as restrictively as possible.
Anyway, if we want to avoid the discussion about whether the warning would really be recommended or not, we can replace this approach by asking what the drawback would be of finalizing the declaration equation.
The intuition is that spring.c is unknown, and spring.spring.c is given by spring.c - regardless of whether spring.c is known or unknown; and to me the important part is this separation of concern - you are trying to "tune" spring.c to find the correct solution where a=0 and that shouldn't change any else. If you find the correct value of spring.c it should just be a matter of setting spring.c to that, disabling fixed=false, and removing the initial equation for a.
I buy this, except that I would have like to see the declaration equation relating spring.c
and spring.spring.c
being final before jumping to conclusions. Let's continue in https://github.com/modelica/ModelicaSpecification/pull/2748!
The initialization of
Modelica.Mechanics.MultiBody.Examples.Elementary.InitSpringConstant
doesn't look right, but for reasons I don't want to discuss further, we've somehow managed to get the expected initialization out of this model anyway. Now, I'd like to see how to get the same result in a proper manner.The source of the problem, as I understand it, is that the
fixed = false
set in the simulation model,doesn't get propagated down to
spring.spring.c
. This is what gets propagated inModelica.Mechanics.MultiBody.Forces.Spring
:This leaves
spring.spring.c
withfixed = true
. Hence, if we look at the two variablesspring.c
andspring.spring.c
, I think we can agree that these should be solved from the following equations (expressed using sloppy pseudo code):With
spring.spring.c
havingfixed = true
, I would not expect it to be solved from the second of these, but using its declaration equation. This means that the second equation gets overdetermined, while there is no equation to determinespring.c
.I can see two ways of making it work:
fixed = false
also onspring.spring.c
, allowing the second equation to be solved with respect to this variable, and the declaration equation to be solved in reverse.c = c
an alias relation by making it final (see below). When eliminating one of the parameter in such an alias relation, it makes sense to keep the one withfixed = false
, since we know it has a corresponding initial equation somewhere.Of the two approaches, the first corresponds to a less cryptic modification: