How to pass multiple variables from one model to another model (inner/outer)

Viewed 597

Let's say we have the following model:

Collector:

model Collector
  Real collect_here;
annotation(defaultComponentPrefixes="inner");
end Collector;

and the following model potentially multiple times:

model Calculator
  outer Collector collector;
  Real calculatedVariable = 2*time;

equation 
  calculatedVariable = collector.collect_here;

end Calculator;

The code above works if calcModel is present only once in the system to be simulated. If the model exists more than once I get a singular system. This is demonstrated by the Example below. Changing the parameter works either gives a working or failing system.

model Example
  parameter Boolean works = true;

  inner Collector collector;
  Calculator calculator1;
  Calculator calculator2 if not works;

end Example;

Using an array inside the collector to pass multiple variables in it doesn't solve it.

Another possible way to solve this is possible by use of connectors, but I only made it work with one calcModel.

2 Answers

Using multiple instances of Calculator does brake the model, as the single variable calculatedVariable will have multiple equations trying to compute its value. Therefore Dymola complains that the system is structurally singular, in this case meaning that there are more equations than variables in the resulting system of equations.

To give a bit more of an insight: Actually checking Collector will fail, as since Modelica 3.0 every component has to be balanced (meaning it has to have as many unknowns as states), which is not the case for Collector as it does have one unknown but no equation. This strongly limits the possible applications for the inner/outer construct as basically every variable has to be computed where it is defined.

In the given example this is compensated in the overall system if exactly one Calculator is used. So this single combination will work. Although this works, it is something that should not be done - for the obvious reason of being very error-prone (and all sub-models should pass the check).

Your question on how to solve this issue actually misses a description of what the issue actually is. There are some cases in my mind that your approach could be useful for:

  1. You want to plot multiple variables from a single point, which would be collector. For this purpose "variable selections" should be the most straight-forward way to go: see Dymola Manual Vol. 1, Section "4.3.11 Matching and variable selections" on how to apply them.
  2. You want to carry out some mathematical operation on that variables. Then it could be useful to have a vectorized input of variable size. This enables an arbitrary number of connections to this input. For an example of this take a look at: Modelica.Blocks.Math.MultiSum
  3. You want to route multiple signals between different models (which is unlikely judging from your description, but still): Then expandable connectors would be a good possibility. To get an impression of what that does take a look at Modelica.Blocks.Examples.BusUsage.

Hope this helps, otherwise please specify more clearly what you actually want to achieve with your code.

Related