Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to initialize a record type by a function in synchronous models (modelica)

I wrote a function, with return value of type record. Normally I would initialize an instance of type record by an initial equation, using this function. But as I want to use this function in a clocked model, initial equations are not possible.

For me it seems to be the only way to initialize a variable, using the attribute start. Unfortunatelly records do not have this attribute but only its components.

Here is a simple example, showing what i wanted to do:

model RecordInitializeTest
  record simpleRecord
    Integer arg1;
    Integer arg2;
  end simpleRecord;

  function initFunc
    output simpleRecord sR;
  algorithm 
    sR.arg1 := 1;
    sR.arg2 := 2;
  end initFunc;

  model InitializeTest
    input Boolean u(start=false);
    output simpleRecord sR1;
  equation 
    if u and not previous(u) then
      sR1 =initFunc();
    else
      sR1 = previous(sR1);
    end if;
  end InitializeTest;

  InitializeTest iT;
equation 
  iT.u = sample(time > 0.5,Clock(0.1));
end RecordInitializeTest;

This model works in dymola but of course there are warnings, as iT.sR1.agr1 and iT.sR1.arg2 have no start values but are arguments to previous(). Conceputally I would like to use

output simpleRecord sR1(start=initFunc());

Has anyone an idea how to initialize sR1 in a convenient way without assignments like

output simpleRecord sR1(arg1(start=1),arg2(start=2));

as that would be inconvenient for large structured records.

Actually i want to execute a complex external impure function (instead of initFunc) only at some instances of time and initally and keep the result in between. And I explicitly don't want to use a continous time model. And I don't want to get warnings at the translation process.

like image 711
Simple Runner Avatar asked Oct 15 '22 23:10

Simple Runner


1 Answers

If I fully understood your question, only some small modifications are needed to let your example run as expected:

model RecordInitializeTest
  record simpleRecord
    Integer arg1(start=0);
    Integer arg2(start=0);
  end simpleRecord;

  function impureFunc
    output simpleRecord sR;
  algorithm 
    (sR.arg1, sR.arg2) :=Modelica.Utilities.System.getTime();
  end impureFunc;

  model ImpureTest
    input Boolean u(start=false);
    output simpleRecord sR1;
  equation 
    if firstTick() or u and not previous(u) then
      sR1 = impureFunc();
    else
      sR1 = previous(sR1);
    end if;
  end ImpureTest;

  ImpureTest iT(u=sample(time > 0.5, Clock(0.1)));
end RecordInitializeTest;

In the simulation result we see that new record values are computed exactly 2 times: At time 0 and at time 0.5:

sim-results

The changes are:

  • initFunc() is replaced by impureFunc(), to see in the result that the function is called at time 0 and time 0.5

  • To perform the initialization firstTick() is added to call the impure function at time 0

  • There are no start-value warnings anymore, since every variable in record has a dummy-start value. The actual start values do not matter, as they are set with firstTick()

Note: I never created a clocked models before, so I might have made some foolish beginner's mistake.

like image 87
marco Avatar answered Oct 21 '22 07:10

marco