3

Often, I will build Modelica models with parameters that are dependent on other parameters:

model ParameterTest
  parameter Real a = 5;
  parameter Real b = a/2;
end ParameterTest;

Here, parameter b is no longer available to be parameterized in the compiled model and I've locked in the b=a/2 relationship.

Alternatively, I could have done the following:

model ParameterTest
  parameter Real a = 5;
  parameter Real b = 5/2;
end ParameterTest;

Here, I've lost some of the traceability and logic for my default value for parameter b and I need to manually maintain/update parameter b if I were to change parameter a in the future. This is a trivial example, but potentially in a more real-world example, the equation set and logic would be more sophisticated to determine parameter b.

While the above behaviors are perfectly logical and expected, what I would often prefer is a 3rd approach that gives me the best of both worlds: specify my default value for parameter b in terms of parameter a, but maintain the ability to change/parameterize b after compilation. Also, to give some motivation here: I would say that this situation/need arises when there isn't a strict relationship between the parameters (a and b in this case), but there is a convenient/typical default relationship.

For example, if an annotation like the following existed, it would be nice:

model ParameterTest
  parameter Real a = 5;
  parameter Real b = a/2 annotation(EvaluateExpression=true); // this would effectively replace "a/2" with "2.5" prior to compilation
end ParameterTest;

Is there any known way to achieve what I'm after? Or any other thoughts/suggestions?

Matt
  • 363
  • 1
  • 7
  • There is the annotation Evaluate, would that cover your use case? If I read correctly, you want to use `Evaluate=false`, so that it can be changed after compilation. https://mbe.modelica.university/behavior/equations/annotations/#evaluate – Priyanka Mar 17 '22 at 07:39
  • @Priyanka Conceptually, yes that's what I want. But as far as I can tell, no, Evaluate=false can not and should not override the b=a/2 equation. – Matt Mar 18 '22 at 18:13

1 Answers1

2

I guess a model like the following would do what you want.

model ParameterTest
  parameter Real a = 5;
  parameter Real bVal = 0;
  parameter Real b = if evaluateExpression then a/2 else bVal;
  parameter Boolean evaluateExpression = true;
end ParameterTest;

I added a boolean parameter evaluateExpression that will influence if b get's computed or uses a parameter bVal. In OpenModelica (OMEdit) you can change the value of b by changing evaluateExpression=false and bVal to some value at simulation time.

OMEdit diagram view of a and b

AnHeuermann
  • 761
  • 3
  • 14
  • Thanks. Yes, this works. Potentially a little more parameter overhead than ideal, especially if I'm doing this for many parameters at different hierarchy levels in a big model, but it does effectively do what I requested. – Matt Mar 16 '22 at 16:56
  • Also, I would comment that in Dymola: it looks like the only change required to make the compiler happy and give equivalent functionality is to write "parameter Real bVal = 0;" – Matt Mar 16 '22 at 16:57
  • Not sure what I miss here, but parameters cannot change during simulation. And if the parameter is not evaluated during compilation, you can change it to any value between simulations anyway!? – Priyanka Mar 21 '22 at 11:57
  • Its about changing the values of parameters for a already translated/compiled Modelica model at the start of a simulation. Computed parameters (`b=a/2`) are fixed at compile time, but normal parameters (`a`) can get new start values. – AnHeuermann Mar 23 '22 at 11:07
  • Marked as solved, however, I feel something that addresses my use case in a more elegant way could be a nice addition to the language. I can't be the only one the routinely runs into situations like this. – Matt Mar 27 '22 at 22:24