Search code examples
modelicaopenmodelica

Modelica: parameter propagation with connectors not possible


I am working on a (Open)Modelica library for simulating chemical processes. With commercial tools it is a common approach that the mixture configuration (e.g. how many and which chemical components are involved like water, ethanol, ...) is defined once for the feed-stream and then this information is propagated via the streams to all the subsequent unit operations.

Unfortunately, so far I did not manage to use the powerful modelica language to achieve this functionality. The ideal situation would be to model a "Process" like this:

package StreamTest 
  connector Stream_Port
    parameter String componentlist[:];
    Real T, p;
  end Stream_Port;

  model Feed_model
    parameter String componentlist[:];
    Stream_Port Out(componentlist = componentlist);
    Real T, p;
  equation
    Out.T = T;
    Out.p = p;
  end Feed_model;

  model Tank_model
    parameter String componentlist[:];
    Real T,p;
    Stream_Port In(componentlist = componentlist);
  equation
    In.T = T;
    In.p = p;
  end Tank_model;

  model Process
    Feed_model Feed (componentlist = {"A", "B"});
    Tank_model Tank;
  equation
    connect(Feed.Out, Tank.In);
    Feed.Out.T = 200;
    Feed.Out.p = 1;
  end Process;
end StreamTest;

Of course this example is stripped down to the essential since nothing is done with "componentlist". In the next step "componentlist" would be used for calculating physical properties in each model, to define array sizes of molefractions etc.

The idea of propagation is as follows:

  1. The "componentlist" is defined in the instance of the Feed_model only once.
  2. The "componentlist" is set equal to the "componentlist" of the connector Stream_Port.
  3. Feed and Tank are connected and the "componentlist" is transferred to the Port "In" of Tank.
  4. Now the crucial point: Tank takes the "componentlist" from the port "In" and propagates it to the componentlist of Tank. componentlist than is used inside the tank for physical properties and array sizes and may also be propagated via some outlet-port of tank to the next unit.

Unfortunately, this does not work with Openmodelica although there is no syntactical error and I cannot see any point in the language definition this approach is not complying with. The error message is:

[StreamTest: 17:5-17:38]: Failed to deduce dimension 1 of componentlist due to missing binding equation.

Of course, I can define the "componentlist" on the level of the model "process" for each unit:

model Process
  Feed_model Feed (componentlist = {"A", "B"});
  Tank_model Tank (componentlist = {"A", "B"});
equation
  connect(Feed.Out, Tank.In);
  Feed.Out.T = 200;
  Feed.Out.p = 1;
end Process;

But then I have to do this redundantly for each and every instance of a model in "Process" -- not as elegant as I would like to implement larger process models...

Reasons for this behaviour: Parameter propagation only works "downwards" in the declaration part of a model where all the models are instantiated. When we connect models, parameter propagation can only be used for array sizes inside the port-definition. And there it is stuck: The information is not transported to the next connected unit.

Any idea, how to solve this problem? Did I miss something? Although I am quite experienced with some some similar commercial tools I am still on the learning curve of modelica...


Solution

  • In Modelica, media models are not propagated via connections (which I agree would be quite logical). Instead, they are propagated via replaceable packages from the top down. As I said, I understand that propagation of parameters via connectors is more intuitive. But the language semantics of connections only deal with values, not with types and the ability to substitute different abstract media models is pretty important because in most cases different media models are not simply parametric (value changes) but rather topology changes (type changes). This is why the replaceable package (types) mechanism is employed.