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?
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.