Closed modelica-trac-importer closed 6 years ago
Comment by hansolsson on 18 Mar 2013 15:40 UTC This was discussed before adding it to the specification.
The form used currently in MSL is that it does not work reliably. You just tell the Modelica translator to ignore some variables when differentiating for no clear reason.
With the form in the specification you state that you ignore variables under certain conditions, and allow the Modelica translator to verify this. Compare with zeroDerivative which clearly state that the variables have zero derivative.
If you look at a typical use case you have:
function h_dT
...
algorithm
h := h_props_dT(d, T, waterBaseProp_dT(d, T, phase, region));
end h_dT;
function h_props_dT
...
algorithm
h := aux.h;
annotation (
derivative(noDerivative=aux) = h_dT_der);
end h_props_dT;
-- Thus it seems this ticket is for MSL instead; and as indicated it is possible to find those expressions in most cases.
Comment by jmattsson on 18 Mar 2013 16:02 UTC I have no opinion of where it should be fixed (MSL vs spec).
However, it would probably be a good idea to update the text in the spec to at least allow several inputs to be listed in noDerivative, and perhaps to allow a general expression instead of a function call with at least one input, as it is now.
Comment by hansolsson on 18 Mar 2013 16:42 UTC I looked more closely at the non-Media cases.
They are more problematic, both the ones that use q_qd_qdd (the relation is given by an equation instead) and the ones in Mechanics.MultiBody.Frames (the noDerivative apply to all R-records provided they satisfy the precondition that skew(R.w)=R.T*der(transpose(R.T)); and if that is not satsified everything breaks - however, there is no common formula for R).
The simplest solution would be to allow the "noDerivative=R" as well, and state that it is dangerous, and the other variant should be used if possible. (And of course that multiple noDerivative are allowed, and they must all be satisified.)
Comment by jmattsson on 19 Mar 2013 09:21 UTC Additionally, in all the examples in 12.7 and 12.8 with both annotation and algorithm, the annotation is before the algorithm (and not last in the class as the spec now requires).
Comment by jmattsson on 12 Apr 2013 09:17 UTC Updating to blocker since it concerns an incompatibility between MSL and the spec.
Comment by otter on 18 Apr 2013 17:02 UTC Had a look at Modelica.Blocks.Sources.KinematicPTP2:
Here, a simple optimization problem is solved analytically and the result is s, v=der(s), a=der(v) and all three variables are computed analytically. Via the noDerivative annotation this information is reported to the tool.
In this case, this is not necessary. I rewrote the code so that "s" is computed and the tool computes v and a by differentiation. In Dymola the generated code is identical to the previous (noDerivative) version. So, there is no efficiency issue. The code has been committed in r6265. Additionally, a test model in ModelicaTest has been extended to test the new implementation with another implementation (KinematicPTP with two integrators).
Comment by otter on 19 Apr 2013 06:33 UTC Had a look at the cases in the Rotational and Translational library:
Modelica.Mechanics.Rotational.Sources.Move, Modelica.Mechanics.Translational.Sources.Move
The goal of the Move blocks is to move a flange according to a predefined motion, given s (position), w (speed), a (acceleration). There are two applications:
To summarize, for the Translational and Rotational library it is a must that the noDerivative annotation can be used as defined in the MSL, because otherwise some existing applications at DLR and other organizations would no longer work.
Comment by otter on 19 Apr 2013 06:38 UTC Unfortunately, I do not yet understand the definition of noDerivative in the specification, chapter 12.7.1. Especially, I also do not understand the example given in this chapter. I think, the developers of this annotation should explain the specification and the example more clearly.
Comment by otter on 19 Apr 2013 06:46 UTC Replying to [comment:3 hansolsson]:
I looked more closely at the non-Media cases.
They are more problematic, both the ones that use q_qd_qdd (the relation is given by an equation instead) and the ones in Mechanics.[wiki:MultiBody].Frames (the noDerivative apply to all R-records provided they satisfy the precondition that skew(R.w)=R.T*der(transpose(R.T)); and if that is not satsified everything breaks - however, there is no common formula for R).
The simplest solution would be to allow the "noDerivative=R" as well, and state that it is dangerous, and the other variant should be used if possible. (And of course that multiple noDerivative are allowed, and they must all be satisified.)
Note, the record R has the two components T (transformation matrix) and w (angular velocity). The trick is to propagate both R and w through all connections and calculate both recursively. The cleanest way would be to only propagate R and compute w with the formula: skew(w) = T*der(transpose(T)). However, this computation is very unefficient and a tool has no chance to transform the resulting equations to the very efficient form where w is computed recursively (w(body_i) = w(body_i-1) + w(relative)). Therefore, here the noDerivative annotation is used to enhance considerably the efficiency. However, it is not practical to state the relationship between T and w in this annotation, since a tool can most likely not figure out symbolically that the two expressions (recursive relations versus formula above) are the same.
Therefore, the only way seems to be to define the noDerivative annotation as in the MSL.
I have to say that I do not understand the Medium appliciations of noDerivative. Especially, I do not understand whether it is possible to rewrite the noDerivative annotation in the safer form as defined in the Modelica specification. If this is not possible, one should eventually ONLY define the noDerivative annotation according to the usage in MSL.
Comment by hansolsson on 19 Apr 2013 13:17 UTC The sub-parts of the derivative indicate various forms of assumptions the modeler make.
The zeroDerivative indicate that some argument usually has zero derivatives; and that the differentiation of the function is made under that assumption. If the assumption is false the function itself is still valid, but we cannot use the derivative.
So what about the noDerivative – what is the assumption, and what happen if it is false?
For the Medium cases one typical case is:
function h_dT
...
algorithm
h := h_props_dT(d, T, waterBaseProp_dT(d, T, phase, region));
end h_dT;
function h_props_dT
...
algorithm
h := aux.h;
annotation (
derivative(noDerivative=aux) = h_dT_der);
end h_props_dT;
This derivative is here only valid if aux=waterBaseProp_dT(d, T, phase, region)
– anything else indicates that the function is used incorrectly. A tool could potentially verify that aux was computed in this way – except that h_props_dT lack some arguments.
Note that if aux has another value it is as far as I understand a modeling error, e.g. h_props_dT(d1, T1, waterBaseProp_dT(d2, T2, phase, region))
is just wrong – even if we do not differentiate it.
It is similar for the ones with properties – for the ones with bpro it is more complicated, since the formula is correct both if bpro is given by the boilingcurve and the dewcurve. One solution would be to have two different hvl_p variants.
Thus the Media-library could use the aux=...
variant after some minor changes in the library (the changes are in lower level functions; and ideally this should not influence users).
So in conclusion:
Thus if we want to have both forms of noDerivative I would propose:
noDerivative=input_var2
or noDerivative(input_var2=f(input_var1))
The derivative of input_var2 is excluded from the argument list of the derivative-function (if there are multiple noDerivative elements all arguments are excluded). The second variant indicates that the function (and its differentiation) is based on the assumption that input_var2=f(input_var1)
.
Skipping the 2nd variant is also possible; and we could then later think of having some other mechanism for specifying assumptions. (Assertions are not appropriate due to issues with floating point precision etc.)
Comment by jmattsson on 4 Jun 2013 08:55 UTC Needs decision for spec to match MSL.
Comment by hansolsson on 4 Jun 2013 16:12 UTC Conclusion: Change specification to be consistent with MSL.
State that this relies on assumptions on the call of the function (regardless of whether it is differentiated or not); and that the function should document these assumptions.
We might later add some form of assumption-checking in function. -- Seems to be agreement.
Comment by hansolsson on 5 Jun 2013 13:32 UTC Added in r6604
Reported by jmattsson on 18 Mar 2013 15:25 UTC Ch 12.7.1 of the current working revision of the 3.2r2 spec (as well as 3.3) says the following about
noDerivative
:noDerivative(input_var2 = f(input_var1, ...) )
The derivative function is only valid if the input argument input_var2 is computed as f(input_var1, ...). The derivative of input_var2 is excluded from the argument list of the derivative-function. [Assume that function fg is defined as a composition f(x, g(x)). When differentiating f it is useful to give the derivative under the assumption that the second argument is defined in this way:function f input Real x; input Real y; output Real z; annotation(derivative(noDerivative(y = g(x))) = f_der); algorithm ... end f;
function f_der input Real x; input Real x_der; input Real y; output Real z_der; algorithm ... end f_der;