1
votes

I was thinking about a feature that would nice to have in Modelica language (I am using OpenModelica 1.14.1).

The feature would automatically add an equation representing a sum of desired values.

The value representing the sum would be declared in the global component instantiated on the top level of a model.

Each contribution of a lower level (perhaps nested) component would be represented by a connect statement.

For this, a connector class with a flow variable could be used since it generates the right equations. inner and outer keywords could make this possible. I tried to code an example of this in the following way:

package global_sum_test

connector X_sum
flow Real x;
end X_sum;

model Global
X_sum x_sum;
Real x = x_sum.x "Variable representing the sum";
end Global;

model Local
parameter Real x=1 "Local contribution to the sum";
outer Global global "Reference to the Global instance";
X_sum x_sum;
equation
x_sum.x = -x "negative sign makes x flowing flom local into global";
connect(x_sum, global.x_sum) "Pushing local x into global sum";
end Local;

model Local_nested
parameter Real x=1 "Local contribution to the sum";
outer Global global "Reference to the global";
X_sum x_sum;
Local local "Component within another component to test nesting";
equation
x_sum.x = -x "Negative sign makes x flowing flom local into global";
connect(global.x_sum, x_sum) "Pushing local x into global sum";
end Local_nested;

model test_model
inner Global global "Instance of Global that is available to lower-level components";
Local local1 "Instance of Local";
Local_nested local2 "Instance of Local_nested with one more Local in it";
end test_model;

end global_sum_test;

This, unfortunately, does not work. When I instantiate the test_model it gives the following output (which I have appropriately commented):

class global_sum_test.test_model
  Real global.x_sum.x;
  Real global.x = global.x_sum.x "Variable representing the sum";
  parameter Real local1.x = 1.0 "Local contribution to the sum";
  Real local1.x_sum.x;
  parameter Real local2.x = 1.0 "Local contribution to the sum";
  Real local2.x_sum.x;
  parameter Real local2.local.x = 1.0 "Local contribution to the sum";
  Real local2.local.x_sum.x;
equation
  local1.x_sum.x = -local1.x "negative sign makes x flowing flom local into global";
  local2.local.x_sum.x = -local2.local.x "negative sign makes x flowing flom local into global";
  local2.x_sum.x = -local2.x "Negative sign makes x flowing flom local into global";
  global.x_sum.x + (-local1.x_sum.x) + (-local2.x_sum.x) + (-local2.local.x_sum.x) = 0.0; // <- this is correct
  local1.x_sum.x = 0.0; // <- this line should not be generated and makes system over-determined.
  local2.x_sum.x = 0.0; // <- this line should not be generated and makes system over-determined.
  local2.local.x_sum.x = 0.0; // <- this line should not be generated and makes system over-determined.
end global_sum_test.test_model;

The three lines generated at the end cause the system to be over-determined. If it would not be for those three lines it would work exaclly as I need.

Questions:

Is this expected behavior? Are the additional lines caused by using open Modelica compiler?

Is there a way to improve my code in such a way that the three additional lines do not get generated?

Can anyone please test this global_sum_test.test_model in Dymola to make sure that this issue is not specific to OpenModelica only?

Is there some other way to get the sum automatically?

2

2 Answers

2
votes

Let me answer my own question by posting an altered version of the code:

package global_sum_test
  connector X_sum
    flow Real x;
  end X_sum;

  model Global
    X_sum x_sum;
    Real x = x_sum.x;
  end Global;

  model Local
    parameter Real x = 1;
    outer Global global;
    outer X_sum x_sum "Added outer key word here";
  equation
    x_sum.x = x "Removed the negative sign from here";
    connect(x_sum, global.x_sum);
  end Local;

  model Local_nested
    parameter Real x = 1;
    outer Global global;
    outer X_sum x_sum "Added outer key word here";
    Local local;
  equation
    x_sum.x = x "Removed the negative sign from here";
    connect(global.x_sum, x_sum) ;
  end Local_nested;

  model test_model
    inner Global global;
    Local local1;
    Local_nested local2;
  end test_model;
end global_sum_test;

This instantiates correctly:

class global_sum_test.test_model
  Real global.x_sum.x;
  Real global.x = global.x_sum.x;
  parameter Real local1.x = 1.0;
  Real local1.x_sum.x;
  parameter Real local2.x = 1.0;
  Real local2.x_sum.x;
  parameter Real local2.local.x = 1.0;
  Real local2.local.x_sum.x;
equation
  local1.x_sum.x = local1.x "Removed the negative sign from here";
  local2.local.x_sum.x = local2.local.x "Removed the negative sign from here";
  local2.x_sum.x = local2.x "Removed the negative sign from here";
  global.x_sum.x + (-local1.x_sum.x) + (-local2.local.x_sum.x) + (-local2.x_sum.x) = 0.0;
end global_sum_test.test_model;

It now works as expected and gives answer global.x = 3.0.

1
votes

So I have posted a ticket to https://trac.openmodelica.org/OpenModelica/ticket/5834 and got a great reply.

There is a very good explanation of what is happening and how to do these sums very neatly (and correctly) with a minimal working example.