Search code examples
modelicadymolaopenmodelica

Modelica - Is it possible to set name of a submodel as the value of another variable?


I’m quite noob in Modelica language and I’d appreciate any help about this simple issue. I’d like to know if it’s possible to write variables name (that depends on a submodel) as a function of other variable in order to shorten the general code. Here there is an example about what I’d like to do.

I’m considering a top-level model that includes three identical submodels (OpenTank) of the Standard Modelica Library (tank1,tank2 and tank3). I’d like to know if it’s possible to call the variable (“level”) inside the submodels from the top-level model using a loop like this way (example code is attached) or something similar instead of repeating the code three times (I’m really interested in setting this operation in the top-level model)

What would you advise me to do? Thanks in advance!

model threeTanks
  Modelica.Fluid.Vessels.OpenTank tank1;
  Modelica.Fluid.Vessels.OpenTank tank2;
  Modelica.Fluid.Vessels.OpenTank tank3;
equation
  for i in 1:3 loop
    tank(i).level= /* … */;
  end for;
end threeTanks;

Solution

  • You would need a component iterator, which is proposed in Modelica Change Proposal MCP-0021 Component Iterators. But it is not available yet and nothing has changed since 2016 if I read it correct, so don't expect to get that soon.

    With the current Modelica language version (specified in Modelica Language Specification 3.5), you must use literal names when you refer to components.
    (In Modelica, there is nothing like eval which you might know from other languages.)

    So either go for Rene Just Nielsens solution and use vectorized tanks. This works, but in the graphical view you will have only one tank. The parameter window will then accept vectors and the tank connectors will be vectorized as well.

    If you don't want that, you can also instantiate your tanks as you did and manually specify the component names over which you want to iterate:

    for item in {tank1, tank2, tank3} loop
      item.level= /* … */;
    end for;
    

    The question is also what you want to achieve. The tank already has equations to compute the level, so it's unlikely that you want to set it.

    Maybe you want to gather all levels at top in one variable. You could do that by adding this line:

    Modelica.Units.SI.Length levels[3] = {item.level for item in {tank1, tank2, tank3}};