OpenModelica / OpenModelica

OpenModelica is an open-source Modelica-based modeling and simulation environment intended for industrial and academic usage.
https://openmodelica.org
Other
840 stars 306 forks source link

Invalid models due to non-differentiable functions #8658

Open casella opened 2 years ago

casella commented 2 years ago

I recently saw commit 39088fb by @phannebohm, which introduced the derivatives of mod and rem. I am not sure what is the point of providing derivatives of functions that cannot be differentiated. This may lead to bogus results. For example, consider this MWE

model Example
  Real x(stateSelect = StateSelect.never);
  Real y(stateSelect = StateSelect.always);
equation 
  der(x) = 1;
  y = mod(x,0.5);
end Example;

The result that we obtain currently makes no sense:

immagine

As I see it we have two options:

phannebohm commented 2 years ago

I recently saw commit 39088fb by @phannebohm, which introduced the derivatives of mod and rem. I am not sure what is the point of providing derivatives of functions that cannot be differentiated.

We differentiate to get Jacobians of nonlinear systems. There the derivative is useful outside of events. Or am I missing something? We also differentiate in the new Solve module, in fact that might be a bit careless, @kabdelhak we should discuss this.

This may lead to bogus results. For example, consider this MWE

model Example
  Real x(stateSelect = StateSelect.never);
  Real y(stateSelect = StateSelect.always);
equation 
  der(x) = 1;
  y = mod(time,0.5);
end Example;

The result that we obtain currently makes no sense: [figure]

As I see it we have two options:

* since mod is not differentiable, we simply reject this model (that's what Dymola does, BTW)

* we may accept it and run the simulation until the first discontinuity of mod takes place; at that point, the simulation should abort, because mod is not differentiable in that point.

I was about to agree and be very confused by this plot, but on my machine the model produces the correct results using the current master. I only get one warning

.../Example.mo:2:3-2:42:writable] Warning: Variable x has attribute stateSelect=StateSelect.never, but was selected as a state

which is to be expected, and y becomes a dummy state.

@casella what did you do to get those results?

casella commented 2 years ago

Sorry, I copied a wrong variant of the model. See the edited text.

casella commented 2 years ago

As a further comment, I guess it makes sense to have those derivatives when those functions are involved in the RHS of ODEs. But it's definitely dangerous if they are involved in index reduction, as the edited example clearly demonstrates.

casella commented 2 years ago

BTW, but this is off-topic for this ticket, I still believe that a model where we must select a state that has StateSelect.never (as in my previously wrong MWE) should lead to an error, not to a warning. Never means never, no if's or but's 😃. I think we already had this discussion with @kabdelhak, I'm not sure what was the outcome.

bilderbuchi commented 2 years ago

I think we already had this discussion with @kabdelhak, I'm not sure what was the outcome.

Probably this comment ff. (or the whole ticket).

By the way, it would be cool if the migrated tickets (like #5459) would have, if not the whole original discussion, at least a link back to the trac issue (instead of "no description provided"). This could help keeping any crosslinks within the new system, better info on hover (issue title), and reduces manually finding the corresponding old issue.

There is also the precise issue your comment touches here (#2584), but there was not much discussion on it.

phannebohm commented 2 years ago

As a further comment, I guess it makes sense to have those derivatives when those functions are involved in the RHS of ODEs. But it's definitely dangerous if they are involved in index reduction, as the edited example clearly demonstrates.

Absolutely, I would argue that a state cannot be the result of a discontinuous calculation, meaning as soon as the mod operation triggers an event, the model should fail and report that the choice of y as state variable was bad. Perhaps already at index reduction we should prevent this choice. But I'm still confused about how to formalize this reasoning.

casella commented 2 years ago

Formally, we need to avoid differentiating discontinuous functions. However, a discontinuous function can still be continuous over a certain domain, so we differ this avoidance to runtime, triggering an exception when the function inputs get out of that domain. Is this what you were looking for?

phannebohm commented 2 years ago

I just saw https://github.com/modelica/ModelicaSpecification/issues/3200#issuecomment-1152183309 which clarifies this issue once more I think.

So basically the equation

y = mod(x,0.5);

will be differentiated to

der(y) = der(x);

and we generate an assert with the same boolean condition previously used for the zero crossing of the original equation. If that assert triggers the simulation aborts. Possibly we put a noEvent() around the differentiated expressions.