Skip to content

spatialDistribution inside if-equation #3929

Description

@AnHeuermann

Question

As far as I can tell the specification isn't explicitly allowing or disallowing the usage of spatialDistribution operator inside a branch of an if-equation / if-expression. So I consider it to be allowed but bad modelling and against the intend of spatialDistribution.

Simple if-equation

Suppose we have a model like:

model SpatialDistributionBehindEvent
  "spatialDistribution() sitting inside the then-branch of a state-event
   condition. When time <= 0.5 (myCondition = false) the operator's result is not used yet,
   afterwards starts feeding the spatialDistribution operator with in0=time."

  Real x(start = 1.0, fixed = true) "Spatial coordinate fed to spatialDistribution";
  Real v = 1 "Velocity der(x)";
  Boolean myCondition = time >= 0.5 "Event that gates the spatialDistribution operator";
  Real in0 = time "Value entering on the left";
  Real out1 "Value leaving on the right";
equation
  der(x) = v;

  if myCondition then
    (, out1) = spatialDistribution(in0, 0.0, x, true,
                                   initialPoints = {0.0, 1.0},
                                   initialValues = {0.0, 0.0});
  else
    out1 = -1.0;
  end if;

  annotation (experiment(StopTime = 2.0, Tolerance = 1e-6));
end SpatialDistributionBehindEvent;

Should this be allowed? A similar effect could be accomplished by having the spatial coordinate to not change when myCondition=false.

We can probably get this to work.

Jump in spatial coordinate while spatialDistribution "off"

But if this is allowed the question becomes what about spatialDistribution that is turned on, off and back on again while the spatial distribution moves fast or with discrete jumps. What is the expected output of something like:

model SpatialDistributionBehindEventReactivate
  Real x(start = 1.0, fixed = true) "Spatial coordinate fed to spatialDistribution";
  Real v = 10 "Velocity der(x)";
  Boolean myCondition "Event that gates the spatialDistribution operator. Active on [0.5, 1.0] and [1.5, 2.0]";
  Real in0 = time "Value entering on the left";
  Real out1 "Value leaving on the right";
equation
  der(x) = v;

  myCondition = (time >= 0.5 and time <= 1.0) or
                (time >= 1.5 and time <= 2.0);

  if myCondition then
    (, out1) = spatialDistribution(in0, 0, x, true,
                                   initialPoints = {0.0, 1.0},
                                   initialValues = {0.0, 0.0});
  else
    out1 = -1.0;
  end if;

  when time >= 1.25 then
    reinit(x, pre(x) + 100);
  end when;

  annotation (experiment(StopTime = 2.0, Tolerance = 1e-6));
end SpatialDistributionBehindEventReactivate;

The jump in spatial coordinate x is huge, how should a tool be able to do any reasonable extrapolation of the stored values inside the spatialDistribution operator. There is no way e.g. reducing the ODE solver step size would help in this case.
In that case I would return a runtime error, because x changed too much and reducing the step size doesn't change this.

Context

We got a Modelica model that supposedly is working in Dymola but was failing for various reasons in OpenModelica that uses a construct like the minimal example SpatialDistributionBehindEvent above, see OpenModelica/OpenModelica#16099.
The second example is very academic, but could happen in a very similar model.

#3722 is discussing, if it should be allowed to use delay operator inside an if branch like

if sin(time)<0 then delay(x, t1) else delay(x, t2)

I think whatever comes out of that should also be applied to spatialDistribution.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions