Message Boards Message Boards

5 Replies
1 Total Likes
View groups...
Share this post:

SystemModeler 4 initial equation quirk

Posted 10 years ago

Initial equations that depend upon a boolean parameter seem to work just find when executed from SystemModeler, but not when executed from SimulationCenter.

For example take this simple model

model Test
  parameter Boolean foo = false;
  Real y;
initial equation
  if foo then
  end if;
end Test;

If I set foo to true and run from SystemModeler I get 1 for y (at all times.) If I set foo to false and run from SystemModeler, I get 2 for y (at all times.) So far so good.

If however I'm over in SimulationCenter and toggle foo from within the Parameters list there is no impact when I execute the model. I get the result for whatever value of foo was set upon entering SimulationCenter.

Same goes for WSMSimulate. I tried changing foo using WSMParameterValues (i.e., WSMParameterValues -> {"foo" -> False}) and there is no impact on the run.

POSTED BY: Eric Meyers
5 Replies

Yeah, that's kind of part of the same bug. WSMSetValues actually updates the model with the new value, so the WSM kernel sees the change from the start of the translation process. When you change a parameter in Simulation Center, the model has already been built, and changes there doesn't change the model.

To achieve the same thing in Simulation Center you need to change the parameter and then click File->Save Experiment Settings... and then select to save the changed parameter in the existing model in the appearing dialog. Then you can press rebuild and get the correct behaviour.

POSTED BY: Peter Aronsson

If you use WSMSetValues to set the parameter value in the model before calling WSMSimulate, it will be forced to rebuild. This however requires that you have write permissions to the model (i.e. the model cannot be loaded from a file with read-only permissions).

For example (using the Test model above):

In[19]:= s = WSMSimulate["Test", {0, 1}];

In[20]:= s["y"][0]

Out[20]= 2.

In[21]:= WSMSetValues["Test", {"foo" -> True}]

Out[21]= {"foo" -> True}

In[22]:= s2 = 
  WSMSimulate["Test", {0, 1}, WSMParameterValues -> {"foo" -> True}];

In[23]:= s2["y"][0]

Out[23]= 1.
POSTED BY: Peter Aronsson
Posted 10 years ago

Outstanding. That works perfectly.

enter image description here

I'm a little surprised the rebuild button in SimulationCenter doesn't work as well. Maybe that's a different bug.

Anyway thanks a bunch.

POSTED BY: Eric Meyers

This is a known issue. The problem is that this parameter is a so called structural parameter, i.e. it changes the structure of the equations, in this case SystemModeler will evaluate the parameter to try to eliminate the if-equation before further processing. Thus, changing the parameter requires a rebuild. Of course the tool should detect this automatically, and this is something we will improve in the future.

A simple workaround for this case is to instead use an if-expression:

model Test
  parameter Boolean foo = false;
  Real y;
initial equation
   y = if foo then 1 else 2;
end Test;

This trick is however not possible in other cases where the equations in the different branches of the if-equation are totally different.

There are also other cases where structural parameters occur, like for instance on parameters with the annotation Evaluate=true, or for Boolean parameters used in conditional components. An example of a conditional component is the heatport connector in the electrical resistor in MSL.

POSTED BY: Peter Aronsson
Posted 10 years ago

Thanks. What you describe makes sense. Of course the simple code I used to demonstrate isn't what I'm really trying to do. I want to do something like this which probably won't work outside of SystemModeler based on your comment. It does work just fine within SystemModeler so it's not a complete loss. It was my hope I could drive models like this using WSMSimulate and I frequently need to initialize to steady-state, but not always.

model Volume
  parameter Boolean steady = false;
  Real p(start = pinit, fixed = not steady);
  Real h(start = 300);
  Real t(start = 500, fixed = not steady);
  Real rho(start = 1.5);
  Real mass(start = 3);
  Real u(start = 100);
  Real U(start = 300);
  parameter String fluid = "O2";
  parameter Real Volume = 10000;
  parameter Real pinit = 500;
  MyConnector myConnector annotation(Placement(visible = true, transformation(origin = {137.82, -0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {90, -0}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
  MyConnector myConnector1 annotation(Placement(visible = true, transformation(origin = {-136.911, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-90, -0}, extent = {{10, -10}, {-10, 10}}, rotation = 0)));
  t = Props.pht(fluid, p, h);
  u = Props.phu(fluid, p, h);
  rho = Props.phrho(fluid, p, h);
  mass = rho * Volume / 12 / 12 / 12;
  der(mass) = myConnector.m_flow + myConnector1.m_flow;
  U = u * mass;
  der(U) = myConnector.m_flow * actualStream(myConnector.h_outflow) + myConnector1.m_flow * actualStream(myConnector1.h_outflow);
  myConnector.h_outflow = h;
  myConnector.Pt = p;
  myConnector1.h_outflow = h;
  myConnector1.Pt = p;
initial equation
  if steady then
    der(mass) = 0;
    der(U) = 0;
  end if ;
end Volume;
POSTED BY: Eric Meyers
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
or Discard

Group Abstract Group Abstract