如何在 Modelica 中更新变量和模拟时间?
How to update a variable along with simulation time in modelica?
'我不熟悉Modelica语言。这是我的问题:
我有两个 Real 类型变量 K 和 A,它们用于计算模型的输出,并且在每个时间步我都想更新 K 和 A 以重新计算输出。我该怎么做?'
不清楚你问什么,但由于你似乎是 Modelica 的新手,我会从最明显的解决方案开始:只给出 K 和 A 的方程式,例如:
model M
output Real K;
output Real A;
Real x;
equation
K=2*x;
A=Modelica.Math.sin(time);
der(x)=1-x;
end M;
在每个时间步都有基于这些方程的 K 和 A 的新值。
(如果 K 和 A 是采样或时钟变量,它会变得更复杂。)
以下模型展示了我在评论中写的内容。模拟 inputOutput.FullModel
会产生您可能正在寻找的控制选项。
使用 OpenModelica 测试了 10 秒的模拟时间。
编辑:我影响了 X
的导数而不是变量本身,因为大多数情况下,如果两个变量 a
和 b
间断地相互影响。
package inputOutput
model M1
Modelica.Blocks.Interfaces.RealInput X annotation(
Placement(visible = true, transformation(origin = {-120, 0}, extent = {{-20, -20}, {20, 20}}, rotation = 0), iconTransformation(origin = {-120, 0}, extent = {{-20, -20}, {20, 20}}, rotation = 0)));
Modelica.Blocks.Interfaces.RealOutput K annotation(
Placement(visible = true, transformation(origin = {110, 48}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {110, 48}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
Modelica.Blocks.Interfaces.RealOutput A annotation(
Placement(visible = true, transformation(origin = {110, -50}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {110, -50}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
equation
K = if X > 1 then 1.5 else 0.8;
A = if X > 0 then 0.5 else -0.5;
end M1;
model M2
Modelica.Blocks.Interfaces.RealInput K annotation(
Placement(visible = true, transformation(origin = {-120, 50}, extent = {{-20, -20}, {20, 20}}, rotation = 0), iconTransformation(origin = {-120, 50}, extent = {{-20, -20}, {20, 20}}, rotation = 0)));
Modelica.Blocks.Interfaces.RealOutput X(start=0) annotation(
Placement(visible = true, transformation(origin = {110, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {110, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
Modelica.Blocks.Interfaces.RealInput A annotation(
Placement(visible = true, transformation(origin = {-120, -50}, extent = {{-20, -20}, {20, 20}}, rotation = 0), iconTransformation(origin = {-120, -50}, extent = {{-20, -20}, {20, 20}}, rotation = 0)));
equation
der(X) = A + sin(time)*K;
end M2;
model FullModel
M1 m1 annotation(
Placement(visible = true, transformation(origin = {-48, 4}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
M2 m2 annotation(
Placement(visible = true, transformation(origin = {34, 4}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
equation
connect(m1.A, m2.A) annotation(
Line(points = {{-38, 0}, {22, 0}, {22, -2}, {24, -2}}, color = {0, 0, 127}));
connect(m2.K, m1.K) annotation(
Line(points = {{22, 10}, {-38, 10}, {-38, 8}, {-36, 8}}, color = {0, 0, 127}));
connect(m2.X, m1.X) annotation(
Line(points = {{46, 4}, {66, 4}, {66, 52}, {-74, 52}, {-74, 4}, {-60, 4}, {-60, 4}}, color = {0, 0, 127}));
end FullModel;
annotation(
uses(Modelica(version = "3.2.2")));
end inputOutput;
您的 link https://openmodelica.org/forum/default-topic/2339-modelica-variable-behavior 中的模型可以重写为类似的东西(除了我没有用 OpenModelica 测试过)。这表示您 应该始终包含代码 - 因为您的描述根本不清楚。
model TimeVarTest
Modelica.SIunits.Time timeVar(start = 0);
Modelica.SIunits.Time timeOut(start = 0);
Modelica.Blocks.Tables.CombiTable1Ds tableVar(table = [0,0;1,0.5]);
Integer state(start = 0);
algorithm
if state == 0 then
// Action
tableVar.u := time-timeVar;
// Transition
end if;
when pre(state)==0 and time - timeVar > 1 then
state := 1;
timeVar := time;
end when;
if state == 1 then
// Action
tableVar.u := 1;
// Transition
end if;
when pre(state)==1 and time - timeVar > 2 then
state := 0;
timeVar := time;
end when;
equation
timeOut = tableVar.y[1];
annotation (
experiment(StartTime = 0, StopTime = 10, Tolerance = 1e-06, Interval = 0.1));
end TimeVarTest;
'我不熟悉Modelica语言。这是我的问题: 我有两个 Real 类型变量 K 和 A,它们用于计算模型的输出,并且在每个时间步我都想更新 K 和 A 以重新计算输出。我该怎么做?'
不清楚你问什么,但由于你似乎是 Modelica 的新手,我会从最明显的解决方案开始:只给出 K 和 A 的方程式,例如:
model M
output Real K;
output Real A;
Real x;
equation
K=2*x;
A=Modelica.Math.sin(time);
der(x)=1-x;
end M;
在每个时间步都有基于这些方程的 K 和 A 的新值。 (如果 K 和 A 是采样或时钟变量,它会变得更复杂。)
以下模型展示了我在评论中写的内容。模拟 inputOutput.FullModel
会产生您可能正在寻找的控制选项。
使用 OpenModelica 测试了 10 秒的模拟时间。
编辑:我影响了 X
的导数而不是变量本身,因为大多数情况下,如果两个变量 a
和 b
间断地相互影响。
package inputOutput
model M1
Modelica.Blocks.Interfaces.RealInput X annotation(
Placement(visible = true, transformation(origin = {-120, 0}, extent = {{-20, -20}, {20, 20}}, rotation = 0), iconTransformation(origin = {-120, 0}, extent = {{-20, -20}, {20, 20}}, rotation = 0)));
Modelica.Blocks.Interfaces.RealOutput K annotation(
Placement(visible = true, transformation(origin = {110, 48}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {110, 48}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
Modelica.Blocks.Interfaces.RealOutput A annotation(
Placement(visible = true, transformation(origin = {110, -50}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {110, -50}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
equation
K = if X > 1 then 1.5 else 0.8;
A = if X > 0 then 0.5 else -0.5;
end M1;
model M2
Modelica.Blocks.Interfaces.RealInput K annotation(
Placement(visible = true, transformation(origin = {-120, 50}, extent = {{-20, -20}, {20, 20}}, rotation = 0), iconTransformation(origin = {-120, 50}, extent = {{-20, -20}, {20, 20}}, rotation = 0)));
Modelica.Blocks.Interfaces.RealOutput X(start=0) annotation(
Placement(visible = true, transformation(origin = {110, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {110, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
Modelica.Blocks.Interfaces.RealInput A annotation(
Placement(visible = true, transformation(origin = {-120, -50}, extent = {{-20, -20}, {20, 20}}, rotation = 0), iconTransformation(origin = {-120, -50}, extent = {{-20, -20}, {20, 20}}, rotation = 0)));
equation
der(X) = A + sin(time)*K;
end M2;
model FullModel
M1 m1 annotation(
Placement(visible = true, transformation(origin = {-48, 4}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
M2 m2 annotation(
Placement(visible = true, transformation(origin = {34, 4}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
equation
connect(m1.A, m2.A) annotation(
Line(points = {{-38, 0}, {22, 0}, {22, -2}, {24, -2}}, color = {0, 0, 127}));
connect(m2.K, m1.K) annotation(
Line(points = {{22, 10}, {-38, 10}, {-38, 8}, {-36, 8}}, color = {0, 0, 127}));
connect(m2.X, m1.X) annotation(
Line(points = {{46, 4}, {66, 4}, {66, 52}, {-74, 52}, {-74, 4}, {-60, 4}, {-60, 4}}, color = {0, 0, 127}));
end FullModel;
annotation(
uses(Modelica(version = "3.2.2")));
end inputOutput;
您的 link https://openmodelica.org/forum/default-topic/2339-modelica-variable-behavior 中的模型可以重写为类似的东西(除了我没有用 OpenModelica 测试过)。这表示您 应该始终包含代码 - 因为您的描述根本不清楚。
model TimeVarTest
Modelica.SIunits.Time timeVar(start = 0);
Modelica.SIunits.Time timeOut(start = 0);
Modelica.Blocks.Tables.CombiTable1Ds tableVar(table = [0,0;1,0.5]);
Integer state(start = 0);
algorithm
if state == 0 then
// Action
tableVar.u := time-timeVar;
// Transition
end if;
when pre(state)==0 and time - timeVar > 1 then
state := 1;
timeVar := time;
end when;
if state == 1 then
// Action
tableVar.u := 1;
// Transition
end if;
when pre(state)==1 and time - timeVar > 2 then
state := 0;
timeVar := time;
end when;
equation
timeOut = tableVar.y[1];
annotation (
experiment(StartTime = 0, StopTime = 10, Tolerance = 1e-06, Interval = 0.1));
end TimeVarTest;