1
votes

In a continuous model, how do I save the minimum value of a variable during the simulation?

When a simulation has finished I want to display a variable T_min with a graphical annotation that shows me the lowest value of a temperature T during the simulation.

For example, if the simulated temperature T was a sine function, the desired result for the value of T_min would be:

enter image description here

In discrete code this would look something like this:

T_min := Modelica.Constants.inf "Start value";
if T < T_min then
    T_min := T;
else
    T_min := T_min;
end if;

... but I would like a continuous implementation to avoid sampling, high number of events etc.

2

2 Answers

1
votes

I'm not sure if Renes solution is optimal. The solution generates many state events generated by the two if conditions. Embedded in the following model:

model globalMinimum2 
 Real T, T_min;
 Boolean is_true;
initial equation 
 T_min = T;
equation 
 T =time/10*sin(time);
 // if statement ensures that 'T_min' doesn't integrate downwards...
 // ... whenever der(T) is negative;
 if T < T_min then
  der(T_min) = min(0, der(T));
  is_true=true; 
 else
  der(T_min) = 0;
  is_true=false;
 end if;
end globalMinimum2;

The simulation log is the following:

Integration started at T = 0 using integration method DASSL
(DAE multi-step solver (dassl/dasslrt of Petzold modified by Dynasim))
Integration terminated successfully at T = 50
  WARNING: You have many state events. It might be due to chattering.
  Enable logging of event in Simulation/Setup/Debug/Events during simulation
   CPU-time for integration      : 0.077 seconds
   CPU-time for one GRID interval: 0.154 milli-seconds
   Number of result points       : 3801
   Number of GRID   points       : 501
   Number of (successful) steps  : 2519
   Number of F-evaluations       : 4799
   Number of H-evaluations       : 18822
   Number of Jacobian-evaluations: 2121
   Number of (model) time events : 0
   Number of (U) time events     : 0
   Number of state    events     : 1650
   Number of step     events     : 0
   Minimum integration stepsize  : 1.44e-005
   Maximum integration stepsize  : 5.61
   Maximum integration order     : 3

Perhaps it is better to detect two events as given in the following example:

model unnamed_2 
  Real T;
  Real hold;
  Real T_min;
  Boolean take_signal;

initial equation 
  hold=T;
equation 
  T = time/10*sin(time);

  when (T < pre(hold)) then
    take_signal = true;
    hold = T; 
  elsewhen (der(T) >=0) then
    take_signal = false;
    hold = T; 
  end when;

  if (take_signal) then
    T_min = T; 
  else
    T_min = hold;
  end if;

end unnamed_2;

The simulation log shows that this solutions is more efficient:

Log-file of program ./dymosim
(generated: Tue May 24 14:13:38 2016)

dymosim started
... "dsin.txt" loading (dymosim input file)
... "unnamed_2.mat" creating (simulation result file)

Integration started at T = 0 using integration method DASSL
(DAE multi-step solver (dassl/dasslrt of Petzold modified by Dynasim))
Integration terminated successfully at T = 50
   CPU-time for integration      : 0.011 seconds
   CPU-time for one GRID interval: 0.022 milli-seconds
   Number of result points       : 549
   Number of GRID   points       : 501
   Number of (successful) steps  : 398
   Number of F-evaluations       : 771
   Number of H-evaluations       : 1238
   Number of Jacobian-evaluations: 373
   Number of (model) time events : 0
   Number of (U) time events     : 0
   Number of state    events     : 32
   Number of step     events     : 0
   Minimum integration stepsize  : 4.65e-006
   Maximum integration stepsize  : 3.14
   Maximum integration order     : 1
Calling terminal section
... "dsfinal.txt" creating (final states)
0
votes

It seems I was able to finde an answer to my own question simply by looking at the figure above

The code is quite simple:

model globalMinimum
  Modelica.SIunits.Temperature T, T_min;
initial equation 
  T_min = T;
equation 
  // if statement ensures that 'T_min' doesn't integrate downwards...
  // ... whenever der(T) is negative;
  der(T_min) = if T < T_min then min(0, der(T)) else 0;
end globalMinimum;