如何使用 "connect" 语句自动导出在 modelica 中跨组件集声明的特定 "Real" 的总和?

How to use "connect" statements to automatically derive sum of specific "Real" declared across set of components in modelica?

我在考虑 Modelica 语言最好具备的功能(我使用的是 OpenModelica 1.14.1)。

该功能会自动添加表示所需值总和的方程式。

表示总和的值将在模型顶层实例化的 global 组件中声明。

较低级别(可能是嵌套的)组件的每个贡献都将由 connect 语句表示。

为此,可以使用带有 flow 变量的 connector class,因为它会生成正确的方程式。 innerouter 关键字可以使这成为可能。我尝试通过以下方式对此示例进行编码:

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;

不幸的是,这不起作用。 当我实例化 test_model 时,它会给出以下输出(我已对其进行了适当的评论):

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;

最后生成的三行导致系统超定。如果不是这三行,它将完全按照我的需要工作。

问题:

这是预期的行为吗?多行是使用open Modelica编译器造成的吗?

有没有一种方法可以改进我的代码,使不生成额外的三行代码?

任何人都可以在 Dymola 中测试这个 global_sum_test.test_model 以确保这个问题不只针对 OpenModelica 吗?

还有其他方法可以自动求和吗?

让我通过发布代码的更改版本来回答我自己的问题:

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;

正确实例化:

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;

它现在按预期工作并给出答案 global.x = 3.0

所以我已经向 https://trac.openmodelica.org/OpenModelica/ticket/5834 发送了一张票并得到了很好的回复。

对于正在发生的事情以及如何使用最小的工作示例非常巧妙地(正确地)进行这些求和有很好的解释。