Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extension regarding getDirectionalDerivatives() #645

Open
jph-tavella opened this issue Oct 2, 2019 · 1 comment

Comments

@jph-tavella
Copy link

commented Oct 2, 2019

This issue is not for clarification only but for extension of the possibilities for the use of the primitive getDirectionalDerivative(), also assuming its new name will be getDirectionalDerivatives().

The use case is the co-initialization of strongly coupled FMUs as we can see in power flow (electrical domain).
To success an electrical power flow, we have to calculate Jacobian for each FMU. But with the current specification of getDirectionalDerivatives(), it is not possible to get the Jacobian in one call of the function, only one call per line (getting the derivatives of all outputs regarding one input).
As the getDirectionalDerivatives() is not simply a getter, it is not possible to calculate all the lines of the matrix in parallel (e.g. from Dymola FMUs). And of course serializing the calls to the primitive is not efficient.

For this reason, we propose to improve the possibilities for calling the primitive getDirectionalDerivatives() in order to allow getting with one call all the derivatives of a vector of outputs with respect to a vector of inputs, not restricting the current usage.

With FMI 2.0 here are two examples of using the primitive to get all the derivatives of a vector of outputs (o1, o2, o3) with respect to all inputs (i1, i2). In both case two calls are necessary.

// Example 1: two sequential calls are required
getDirectionalDerivatives(sim, {ref(o1),ref(o2),ref(o3)}, 3, {ref(i1)}, 1, {1}, res1[]) // res1 = {do1/di1,do2/di1,do3/di1}  all the derivatives of outputs with respect to THE FIRST input i1
getDirectionalDerivatives(sim, {ref(o1),ref(o2),ref(o3)}, 3, {ref(i2)}, 1, {1}, res2[]) // res2 = {do1/di2,do2/di2,do3/di2}  all the derivatives of outputs with respect to THE SECOND input i2

// Example 2: two sequential calls are required
getDirectionalDerivatives(sim, {ref(o1),ref(o2),ref(o3)}, 3, {ref(i1),ref(i2)}, 2, {1,0}, res1[]) // res1 = {do1/di1,do2/di1,do3/di1} all the derivatives of outputs with respect to THE FIRST input i1
getDirectionalDerivatives(sim, {ref(o1),ref(o2),ref(o3)}, 3, {ref(i1),ref(i2)}, 2, {0,1}, res1[]) // res2 = {do1/di2,do2/di2,do3/di2} all the derivatives of outputs with respect to THE SECOND input i2

FMI 3.0 is a great opportunity to extend the possibilities for calling the getDirectionalDerivatives() and get a better batch calling for this primitive.
// Example: only one call is required
getDirectionalDerivatives(sim, {ref(o1),ref(o2),ref(o3)}, 3, {ref(i1),ref(i2)}, 2, {{1,0},{0,1}}, res[[]]) // res = {{do1/di1,do2/di1,do3/di1},{do1/di2,do2/di2,do3/di2}} all the derivatives of outputs with respect to all inputs
The idea is to provide for the seed a matrix adapted as a vector indicating the desired derivatives. Then, the result would be another matrix adapted as a vector. At this point the idea is to serialize and deserialize matrices as vectors to enhance the communication of dynamic libraries with programming languages.

Of course it is still possible to use the primitive as previously. Example:
getDirectionalDerivatives(sim, {ref(o1),ref(o2),ref(o3)}, 3, {ref(i1)}, 1, {{1}}, res1[[]]) // res1 = {{do1/di1,do2/di1,do3/di1}} all the derivatives of outputs with respect to THE FIRST input i1
getDirectionalDerivatives(sim, {ref(o1),ref(o2),ref(o3)}, 3, {ref(i2)}, 1, {{1}}, res2[[]]) // res2 = {{do1/di2,do2/di2,do3/di2}} all the derivatives of outputs with respect to THE SECOND input i2

@chrbertsch chrbertsch added this to the v3.0 milestone Oct 18, 2019
@masoud-najafi

This comment has been minimized.

Copy link
Collaborator

commented Oct 18, 2019

Please note that in FMI-3.0, Known and Unknowns variables may be Vector or even Matrix. Adding this will increase the complexity of this API, already complex.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
3 participants
You can’t perform that action at this time.