modelica / ModelicaSpecification

Specification of the Modelica Language
https://specification.modelica.org
Creative Commons Attribution Share Alike 4.0 International
98 stars 42 forks source link

decouple() operator #2010

Open modelica-trac-importer opened 5 years ago

modelica-trac-importer commented 5 years ago

Reported by jmattsson on 15 Jun 2016 13:53 UTC The "Subtask" chapter was removed with the motivation that no tool implemented it. That was not strictly true, as Dymola implemented at least the Subtask.decouple() operator. That operator has since then proved very useful, since it can greatly improve performance at a low cost to accuracy if used correctly.

I suggest reintroducing Subtask.decouple() as just decouple(), defined as returning the value its argument had at the previous time step.


Migrated-From: https://trac.modelica.org/Modelica/ticket/2010

modelica-trac-importer commented 5 years ago

Comment by jmattsson on 15 Jun 2016 13:54 UTC This may need an MCP, but I think starting with a discussion is reasonable.

modelica-trac-importer commented 5 years ago

Comment by sjoelund.se on 15 Jun 2016 14:02 UTC

I suggest reintroducing Subtask.decouple() as just decouple(), defined as returning the value its argument had at the previous time step.

I assume the last accepted step (and not any intermediate steps), and time-decouple(time) returns the delta of the two variables, so (x-decouple(x))/(time-decouple(time)) is an approximation of the derivative? Allowed for any expression or only continuous-time variables?

modelica-trac-importer commented 5 years ago

Comment by hansolsson on 15 Jun 2016 14:43 UTC Replying to [ticket:2010 jmattsson]:

I suggest reintroducing Subtask.decouple() as just decouple(), defined as returning the value its argument had at the previous time step.

I can understand the need for the operator. However, decouple() wasn't defined like that:

In Modelica 3.2 it defined boundaries between subtasks - which is important since it explains the purpose (separating the model into less dependent partitions) - not a specific implementation.

This is also important in practice, since decouple() actually works like that in Dymola (using general "partitions" not "subtasks"): if possible(*) it decouples the equations - using some approximation of the decouple-argument (not necessarily the value from the previous step). - *: "If possible" mean that y=a-decouple(a); doesn't make sense (and will return y=0 as far as I can see), since you cannot separate a and y into different partitions (since y directly depends on a).

modelica-trac-importer commented 5 years ago

Comment by jmattsson on 15 Jun 2016 14:56 UTC Replying to [comment:2 sjoelund.se]:

I assume the last accepted step (and not any intermediate steps),

Yes, that seems the most reasonable approach.

and time-decouple(time) returns the delta of the two variables, so (x-decouple(x))/(time-decouple(time)) is an approximation of the derivative?

I guess that would follow, although I don't see how it would be useful (since you could use der() instead).

Allowed for any expression or only continuous-time variables?

I'd suggest only continuous-time, since you can use pre() for discrete. As for any such expression or only variables, I'm not sure - that needs discussion.

Replying to [comment:3 hansolsson]:

I can understand the need for the operator. However, decouple() wasn't defined like that:

In Modelica 3.2 it defined boundaries between subtasks - which is important since it explains the purpose (separating the model into less dependent partitions) - not a specific implementation.

This is also important in practice, since decouple() actually works like that in Dymola (using general "partitions" not "subtasks"): if possible(*) it decouples the equations - using some approximation of the decouple-argument (not necessarily the value from the previous step).

*: "If possible" mean that y=a-decouple(a); doesn't make sense (and will return y=0 as far as I can see), since you cannot separate a and y into different partitions (since y directly depends on a).

Specifying a check that the decoupling is possible sounds good, but I don't like specifying it to use "some approximation", as that would make it harder to compare results between different tools.

I was attempting to make it independent of the old Subtask chapter and yet well-defined, but perhaps talking about "partitions" instead of "subtasks" is a better way.

modelica-trac-importer commented 5 years ago

Comment by sjoelund.se on 15 Jun 2016 15:05 UTC Replying to [comment:4 jmattsson]:

and time-decouple(time) returns the delta of the two variables, so (x-decouple(x))/(time-decouple(time)) is an approximation of the derivative? I guess that would follow, although I don't see how it would be useful (since you could use der() instead).

When you use der(x), you will always calculate x based on der(x) - if you need the opposite (approximation of der(x) for some numerical algorithm), this is useful. Granted I have only needed it very rarely, but the need has been there.

I remember needing this operator for transmission line modeling (sampling systems is just very slow) using delay() (and saying that delay breaks loops, and setting solver fixed step size to appropriate lengths). But then not necessarily for der().

modelica-trac-importer commented 5 years ago

Comment by hansolsson on 15 Jun 2016 15:15 UTC Replying to [comment:4 jmattsson]:

Replying to [comment:3 hansolsson]:

I can understand the need for the operator. However, decouple() wasn't defined like that:

In Modelica 3.2 it defined boundaries between subtasks - which is important since it explains the purpose (separating the model into less dependent partitions) - not a specific implementation.

This is also important in practice, since decouple() actually works like that in Dymola (using general "partitions" not "subtasks"): if possible(*) it decouples the equations - using some approximation of the decouple-argument (not necessarily the value from the previous step).

*: "If possible" mean that y=a-decouple(a); doesn't make sense (and will return y=0 as far as I can see), since you cannot separate a and y into different partitions (since y directly depends on a). Specifying a check that the decoupling is possible sounds good, but I don't like specifying it to use "some approximation", as that would make it harder to compare results between different tools.

One possibility would be to not describe the approximations at all, but formally only define decouple(x) as being the same as x - which is the result when you don't partition. In that way decoupling-error is similar to other forms of errors introduced by the integration-algorithm.

The second possibility would be to describe the result when y=decouple(x); allows x and y to be in different partitions (when they are in the same partition we could use y=x; - or it might be that we can do better), and just using the value from previous time-step isn't good enough in that case.

I am not sure if we have the ideal solution for that yet. The point is that standardizing on a flawed solution (using the value from the previous accepted step), will prevent us from standardizing on a better solution later on.

I was attempting to make it independent of the old Subtask chapter and yet well-defined, but perhaps talking about "partitions" instead of "subtasks" is a better way.

I believe so.

modelica-trac-importer commented 5 years ago

Comment by hansolsson on 15 Jun 2016 15:35 UTC Replying to [comment:5 sjoelund.se]:

Replying to [comment:4 jmattsson]:

and time-decouple(time) returns the delta of the two variables, so (x-decouple(x))/(time-decouple(time)) is an approximation of the derivative? I guess that would follow, although I don't see how it would be useful (since you could use der() instead).

When you use der(x), you will always calculate x based on der(x) - if you need the opposite (approximation of der(x) for some numerical algorithm), this is useful. Granted I have only needed it very rarely, but the need has been there.

I don't agree with this. When use der(x) it doesn't imply that we calculate x based on der(x):

model M
  Real x=time^3;
  Real y;
equation
  y=der(x);
end M;

Here x is computed from time^3 and y is computed based on differentiating that - without influencing the computation of x.

If the formula cannot be differentiated it is more complicated - the usual approach is to use a low-pass filter and differentiate its output (this is done indirectly in many places in MSL). The low-pass filter has a fixed frequency (independent of integrator step-size) ensuring that it is well-defined mathematically.

Allowing access to the step-size as time-decouple(time) would just create a lot more problems; and is unlikely to work as expected for different integrators.

However, with the synchronous extension you can say that a partition is using a specific integrator and step-size, and in that case the "step-size" for that partition could be used (since the integrator and step-size is part of the model; not of its solution method).

I remember needing this operator for transmission line modeling (sampling systems is just very slow) using delay() (and saying that delay breaks loops, and setting solver fixed step size to appropriate lengths). But then not necessarily for der().

I will need to investigate more about the transmission line modeling techniques to understand what we can learn from it. Do you have any good references? In general we don't want models to rely on specific integrators and step-sizes.

modelica-trac-importer commented 5 years ago

Modified by beutlich on 15 Jun 2016 15:42 UTC

modelica-trac-importer commented 5 years ago

Comment by hansolsson on 21 Jun 2016 15:58 UTC Conclusion that Modelon and Dassault Systemes works on MCP including approximation, parallelization, realtime, etc.

modelica-trac-importer commented 5 years ago

Modified by otter on 5 Aug 2016 05:59 UTC

modelica-trac-importer commented 5 years ago

Comment by hansolsson on 13 Sep 2016 09:43 UTC No work yet, seems interesting - but not for Modelica 3.4. A discussion about the strict mathematical definition: