Open casella opened 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?
Sorry, I copied a wrong variant of the model. See the edited text.
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.
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.
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.
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.
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?
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.
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
The result that we obtain currently makes no sense:
As I see it we have two options: