Tao.Y
Tao.Y

Reputation: 87

How to update a variable along with simulation time in modelica?

'I am not familiar with Modelica language. here is my question: I have two Real type variables K and A, they are used to compute outputs of the model, and at each timestep I want to update K and A to recalculate the output. How can I do this?'

Upvotes: 0

Views: 1099

Answers (3)

Hans Olsson
Hans Olsson

Reputation: 12507

The model from your link https://openmodelica.org/forum/default-topic/2339-modelica-variable-behavior can be rewritten to something like that does that (except I haven't tested with OpenModelica). This indicates that you should always include code - as this was not at all clear from your description.

model TimeVarTest
  Modelica.SIunits.Time timeVar(start = 0);
  Modelica.SIunits.Time timeOut(start = 0);
  Modelica.Blocks.Tables.CombiTable1Ds tableVar(table = [0,0;1,0.5]);
  Integer state(start = 0);
algorithm 
  if state == 0 then
    // Action 
    tableVar.u := time-timeVar;
    // Transition 
  end if;
    when pre(state)==0 and time - timeVar > 1 then
      state := 1;
      timeVar := time;
    end when;

  if state == 1 then
  // Action 
  tableVar.u := 1;
  // Transition 
  end if;
  when pre(state)==1 and time - timeVar > 2 then
    state := 0;
    timeVar := time;
  end when;
equation 
  timeOut = tableVar.y[1];
annotation (
    experiment(StartTime = 0, StopTime = 10, Tolerance = 1e-06, Interval = 0.1));
end TimeVarTest;

Upvotes: 1

kabdelhak
kabdelhak

Reputation: 697

The following model showcases what i wrote in my comment. Simulating inputOutput.FullModel yields the control options you might be looking for.

Tested with OpenModelica for a simulation time of 10 seconds.

EDIT: I influenced the derivative of X instead of the variable itself because most of the time you will cause event chattering or no event at all if two variables a and b influence each other discontinuously.

package inputOutput
  model M1
    Modelica.Blocks.Interfaces.RealInput X annotation(
      Placement(visible = true, transformation(origin = {-120, 0}, extent = {{-20, -20}, {20, 20}}, rotation = 0), iconTransformation(origin = {-120, 0}, extent = {{-20, -20}, {20, 20}}, rotation = 0)));
  Modelica.Blocks.Interfaces.RealOutput K annotation(
      Placement(visible = true, transformation(origin = {110, 48}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {110, 48}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
  Modelica.Blocks.Interfaces.RealOutput A annotation(
      Placement(visible = true, transformation(origin = {110, -50}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {110, -50}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
  equation
    K = if X > 1 then 1.5 else 0.8;
    A = if X > 0 then 0.5 else -0.5;
  end M1;

  model M2
  Modelica.Blocks.Interfaces.RealInput K annotation(
      Placement(visible = true, transformation(origin = {-120, 50}, extent = {{-20, -20}, {20, 20}}, rotation = 0), iconTransformation(origin = {-120, 50}, extent = {{-20, -20}, {20, 20}}, rotation = 0)));
  Modelica.Blocks.Interfaces.RealOutput X(start=0) annotation(
      Placement(visible = true, transformation(origin = {110, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {110, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
  Modelica.Blocks.Interfaces.RealInput A annotation(
      Placement(visible = true, transformation(origin = {-120, -50}, extent = {{-20, -20}, {20, 20}}, rotation = 0), iconTransformation(origin = {-120, -50}, extent = {{-20, -20}, {20, 20}}, rotation = 0)));
  equation
    der(X) = A + sin(time)*K;
  end M2;

  model FullModel
    M1 m1 annotation(
      Placement(visible = true, transformation(origin = {-48, 4}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
    M2 m2 annotation(
      Placement(visible = true, transformation(origin = {34, 4}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
  equation
    connect(m1.A, m2.A) annotation(
      Line(points = {{-38, 0}, {22, 0}, {22, -2}, {24, -2}}, color = {0, 0, 127}));
    connect(m2.K, m1.K) annotation(
      Line(points = {{22, 10}, {-38, 10}, {-38, 8}, {-36, 8}}, color = {0, 0, 127}));
  connect(m2.X, m1.X) annotation(
      Line(points = {{46, 4}, {66, 4}, {66, 52}, {-74, 52}, {-74, 4}, {-60, 4}, {-60, 4}}, color = {0, 0, 127}));
  end FullModel;
  annotation(
    uses(Modelica(version = "3.2.2")));

end inputOutput;

Upvotes: 0

Hans Olsson
Hans Olsson

Reputation: 12507

It is unclear what you ask, but since you seem new to Modelica I would start with the most obvious solution: just give equations for K and A, like:

model M
  output Real K;
  output Real A;
  Real x;
equation
  K=2*x;
  A=Modelica.Math.sin(time);
  der(x)=1-x;
end M;

At each time-step there will be new values for K and A based on these equations. (If K and A are sampled or clocked variables it becomes more complicated.)

Upvotes: 2

Related Questions