I am creating a Max Per Interval block in Wolfram System Modeler.
To make it easy for me to explain, I just set the Max value to 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;
When ran, index increments to infinity right off the bat. I figure there is something wrong with my logic, but I can't figure it.
The code is supposed to check to see if we are still in the interval time, and when we cross over into the next interval time it sets the "currentMax" value to zero. Which will reset the Max value I've implemented in another block.
Any help would be appreciated. Thanks.
EDIT: Code section form example.
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;
You need to use when
, not if
. You can find a discussion about both and the differences between them in Modelica by Example.
This issue has also been discussed on SO both here and here.
Here is an example (completely untested, but it shows the basic idea):
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;