Modelica - 增量不符合条件
Modelica - Increment doesn't follow conditions
我正在 Wolfram System Modeler 中创建一个 Max Per Interval 模块。
为了便于解释,我将最大值设置为 10。
block HighWaterMarkPerInterval
extends Modelica.Blocks.Interfaces.SISO;
protected
Integer index;
Real currentMax;
Real endTimes[1, 45] = [30812532.2, 32037805, 33265581.8, 34493233.8, 35720861.5, 36948483, 38176307.7, 39426940.6, 40654485.4, 41882212.1, 43109672.7, 44337076, 45564265.7, 46793039.6, 48045130.9, 50749960.3, 52040090.6, 53558507.7, 54814537.3, 56331978.2, 57587753.3, 59105952.9, 60362517.8, 61879307.8, 63136031.5, 64363411.4, 65590464.3, 67738027.40000001, 84725789.8, 87831338.09999999, 89030965.40000001, 90258821.8, 91486663.5, 92714210.3, 93941727.7, 95166770.3, 97283519, 99434222.90000001, 100658067.1, 102807019, 104030032.7, 106179193, 107402090, 109550214.2, 110771545.3];
algorithm
if endTimes[1, index] < time then
index := pre(index) + 1;
currentMax := 0;
else
currentMax := 10; // Constant to until I get logic working
end if;
initial algorithm
index := 0;
equation
y = currentMax;
end HighWaterMarkPerInterval;
当 运行 时,索引立即递增到无穷大。我觉得我的逻辑有问题,但我想不通。
代码应该检查我们是否仍在间隔时间,当我们进入下一个间隔时间时,它会将 "currentMax" 值设置为零。这将重置我在另一个块中实现的最大值。
如有任何帮助,我们将不胜感激。谢谢
编辑:代码部分表单示例。
model HighWaterMarkPerInterval
annotation(Diagram(coordinateSystem(extent = {{-148.5, -105}, {148.5, 105}}, preserveAspectRatio = true, initialScale = 0.1, grid = {5, 5})));
extends Modelica.Blocks.Interfaces.SISO;
Modelica.Blocks.Math.Max maxblock(u1 = currentMax, u2 = u);
Real flybyEnds[1, 45] = [30813151,32038322,33266015, truncated for space saving...];
Integer index;
Real currentMax;
initial equation
index = 1;
currentMax = 0;
algorithm
// When we are in the interval continually grab max block output and output currentMax
when {time>=flybyEnds[1, index-1], time <=flybyEnds[1,index]} then
currentMax := pre(maxblock.y);
y := currentMax;
end when;
// When we move to the next interval reset current max and move to the next interval
when time > flybyEnds[1, index] then
currentMax := 0;
index := pre(index) + 1;
end when;
end HighWaterMarkPerInterval;
您需要使用 when
,而不是 if
。您可以在 Modelica by Example.
中找到关于两者以及它们之间差异的讨论
SO 上也讨论了这个问题 here and here。
这是一个例子(完全未经测试,但它展示了基本思想):
model HighWaterMarkPerInterval
extends Modelica.Blocks.Interfaces.SISO;
parameter Modelica.SIunits.Time sample_rate=3600;
Real flybyEnds[45] = {30813151,32038322,33266015,...};
Integer index;
Real currentMax;
initial algorithm
// Specify the first time we are interested in...
index := 1;
algorithm
// At the start of the simulation, the initial max for the current
// interval [0,30813151] is whatever u is. The initial output value
// is also the initial value for u
when initial() then
currentMax := u
y := u;
end when;
// Check at some sample rate (faster than the flyby interval!)
// if u > currentMax...
when sample(sample_rate, sample_rate) then
// New currentMax is the larger of either currentMax or u
// when the sample took place
currentMax := max(pre(currentMax), pre(u));
end when;
// At the end of the "flyby", record the maximum found since
// the last flyby and specify the next flyby index.
when time>=flybyEnd[index] then
// New output is the value of currentMax from this interval
y := pre(currentMax);
// Now reset currentMax
currentMax := pre(u);
// Increment index up to the length of flybyEnd
index := min(pre(index)+1, size(flybyEnd,1));
end when;
end HighWaterMarkPerInterval;
我正在 Wolfram System Modeler 中创建一个 Max Per Interval 模块。
为了便于解释,我将最大值设置为 10。
block HighWaterMarkPerInterval
extends Modelica.Blocks.Interfaces.SISO;
protected
Integer index;
Real currentMax;
Real endTimes[1, 45] = [30812532.2, 32037805, 33265581.8, 34493233.8, 35720861.5, 36948483, 38176307.7, 39426940.6, 40654485.4, 41882212.1, 43109672.7, 44337076, 45564265.7, 46793039.6, 48045130.9, 50749960.3, 52040090.6, 53558507.7, 54814537.3, 56331978.2, 57587753.3, 59105952.9, 60362517.8, 61879307.8, 63136031.5, 64363411.4, 65590464.3, 67738027.40000001, 84725789.8, 87831338.09999999, 89030965.40000001, 90258821.8, 91486663.5, 92714210.3, 93941727.7, 95166770.3, 97283519, 99434222.90000001, 100658067.1, 102807019, 104030032.7, 106179193, 107402090, 109550214.2, 110771545.3];
algorithm
if endTimes[1, index] < time then
index := pre(index) + 1;
currentMax := 0;
else
currentMax := 10; // Constant to until I get logic working
end if;
initial algorithm
index := 0;
equation
y = currentMax;
end HighWaterMarkPerInterval;
当 运行 时,索引立即递增到无穷大。我觉得我的逻辑有问题,但我想不通。
代码应该检查我们是否仍在间隔时间,当我们进入下一个间隔时间时,它会将 "currentMax" 值设置为零。这将重置我在另一个块中实现的最大值。
如有任何帮助,我们将不胜感激。谢谢
编辑:代码部分表单示例。
model HighWaterMarkPerInterval
annotation(Diagram(coordinateSystem(extent = {{-148.5, -105}, {148.5, 105}}, preserveAspectRatio = true, initialScale = 0.1, grid = {5, 5})));
extends Modelica.Blocks.Interfaces.SISO;
Modelica.Blocks.Math.Max maxblock(u1 = currentMax, u2 = u);
Real flybyEnds[1, 45] = [30813151,32038322,33266015, truncated for space saving...];
Integer index;
Real currentMax;
initial equation
index = 1;
currentMax = 0;
algorithm
// When we are in the interval continually grab max block output and output currentMax
when {time>=flybyEnds[1, index-1], time <=flybyEnds[1,index]} then
currentMax := pre(maxblock.y);
y := currentMax;
end when;
// When we move to the next interval reset current max and move to the next interval
when time > flybyEnds[1, index] then
currentMax := 0;
index := pre(index) + 1;
end when;
end HighWaterMarkPerInterval;
您需要使用 when
,而不是 if
。您可以在 Modelica by Example.
SO 上也讨论了这个问题 here and here。
这是一个例子(完全未经测试,但它展示了基本思想):
model HighWaterMarkPerInterval
extends Modelica.Blocks.Interfaces.SISO;
parameter Modelica.SIunits.Time sample_rate=3600;
Real flybyEnds[45] = {30813151,32038322,33266015,...};
Integer index;
Real currentMax;
initial algorithm
// Specify the first time we are interested in...
index := 1;
algorithm
// At the start of the simulation, the initial max for the current
// interval [0,30813151] is whatever u is. The initial output value
// is also the initial value for u
when initial() then
currentMax := u
y := u;
end when;
// Check at some sample rate (faster than the flyby interval!)
// if u > currentMax...
when sample(sample_rate, sample_rate) then
// New currentMax is the larger of either currentMax or u
// when the sample took place
currentMax := max(pre(currentMax), pre(u));
end when;
// At the end of the "flyby", record the maximum found since
// the last flyby and specify the next flyby index.
when time>=flybyEnd[index] then
// New output is the value of currentMax from this interval
y := pre(currentMax);
// Now reset currentMax
currentMax := pre(u);
// Increment index up to the length of flybyEnd
index := min(pre(index)+1, size(flybyEnd,1));
end when;
end HighWaterMarkPerInterval;