#2209 closed defect (worksforme)
The smooth() operator should be used to influence event generation and differentiation
Reported by: | Francesco Casella | Owned by: | Willi Braun |
---|---|---|---|
Priority: | critical | Milestone: | 1.13.0 |
Component: | Run-time | Version: | trunk |
Keywords: | Cc: |
Description
The smooth() operator is currently ignored by OMC, only noEvent() is.
This is not good: noEvent was a crude procedural hack to handle conditional expressions which are known in advance to be continuous by suppressing event generation. The intent of smooth() was to replace it in a more clean and procedural way, also allowing to differentiate conditional expressions if appropriate. The smooth() operator was introduced in Modelica many years ago, and the intent in the MSL and elswhere is to replace noEvent by smooth wherever appropriate.
Bottom line: we need to support it asap if we want to claim full Modelica 3.2 compliance.
This also applies to automatic differentiation: an if expression surrounded by smooth(N, ...) can safely be differentiated if N >= 1, and returns an expression which is smooth(N-1, ...). It also applies to the smoothOrder annotation, which can be critical for some applications in mechanical and fluid systems.
Change History (3)
comment:1 by , 11 years ago
Owner: | changed from | to
---|---|
Status: | new → assigned |
comment:2 by , 11 years ago
comment:3 by , 7 years ago
Component: | Frontend → Run-time |
---|---|
Milestone: | Future → 1.13.0 |
Resolution: | → worksforme |
Status: | assigned → closed |
I ran these two models with v1.13.0-dev-155-g68350e9:
model M1 Real x; equation der(x) = if x < 1 then 2 else -x + 3; end M1; model M2 Real x; equation der(x) = smooth(0,if x < 1 then 2 else -x + 3); end M2;
While M1 generated an event at time t = 0.5, M2 did not generate any. This might be a bit crude if a high-order solver is used and the expression is only continuous but not continuously differentiable, but I guess it is as good as we can get this now.
Regarding differentiation of smooth expressions:
der(smooth(N, if cond then e1 else e2)) should be replaced by
if N > 0 : smooth(N-1, if cond then der(e1) else der(e2))
if N == 0: (if cond then der(e1) else der(e2))
Note that if N==0, the derivative of must generate an event: the derivative is well defined, but it is discontinuous when the condition switches, so it needs an event to be properly handled.
A related issue is whether we should accept der(if cond then e1 else e2) without any smooth. Dymola accepts it, but then it checks numerically that pre(e1)== e2 at the event; if not, it issues an error such as: differentiating a discontinuous expression jumping from <value of (pre(e1)> to <value of e2>, otherwise it goes on with the simulation.
This makes perfect sense: if we can infer a-posteriori that the expression is actually continuous at the event, why not exploiting this? Of course, if we use smooth, the information is already available a priori at compile time (though there might be bugs in the expression, which might turn out to be non smooth). We could think of doing the same, though we must be careful when checking two reals for equality. I guess the specification doesn't say anything about this, but I'm not 100% sure.