breakterminateopenmodelica

Is there any keyword that will terminate or stop the simulation when the output reaches a specific value in open modelica?


I want to stop the simulation when my output reaches a certain limit or value irrespective of the simulation time. Let's take an example my output is 'prod' a variable which has the product of two numbers stored in it. If the product of the two numbers is greater than 12 then the simulation must stop irrespective of the other values left in the array.

is there any keyword which would do this in open modelica? I tried using the break and terminate command, but the output of prod after 3 seconds reached 12 and then the plot continued for 5 seconds(which was the simulation time) and the value stored in prod was zero. I want my simulation to stop and the product is 12 and it should not calculate the product after that and shouldn't display those values in the plot as well.

model ForLoopExample;
Real A[5] = {1,2,3,4,5};
Real B[5] = {2,3,4,5,6};
Real prod[5];
Boolean test_case(start = false);
algorithm 
for i in 1:size(A,1) loop 
    prod[i]:=A[i]*B[i];
    if prod[i]>=12 then 
    test_case = true;
    break;
    end if;
end for;
when test_case then 
    terminate("product above 12");
end when;
end ForLoopExample;

Solution

  • It is a bit tricky example you have since it involves understanding of Modelica and time and the difference between algorithm and equations. The code works as expected for me (if you just adjust code text_case := true). The algorithm does all computations at the very beginning of the simulation, and sort of does not "take time". You need to make the system time discrete and for each sample interval (say 1 second) you make one round of calculation.

    I have made a crude translation of your code to a time discrete system. And I let index of A an B represent the time 1, 2,..5 seconds so we get the value of A and B for each samplePeriod.

    This algorithm works and stops at time=3 when prod = 12 i.e greater or equal than 12. In general I would not like to have code that test on equality of two real numbers, but I let it stay as is.

    Does this capture what you want?

    model ForLoopExample
       parameter Real samplePeriod = 1;
       parameter Real A[5] = {1,2,3,4,5};
       parameter Real B[5] = {2,3,4,5,6};
       Real prod (start=0, fixed=true);
       Boolean test_case(start = false, fixed=true);
    equation
       when sample(0, samplePeriod) then
          prod = A[integer(time)]*B[integer(time)];
          test_case = prod >= 12;
       end when;
       when test_case then
          terminate("product above 12");
       end when;
    end ForLoopExample;