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

draft: start work on solution inspection tools #123

Closed
wants to merge 2 commits into from
Closed

Conversation

hexaeder
Copy link
Member

This is the start of a new "solution inspection" interface which will be the base for a not-yet-relased package for interactive inspection of NetworkDynamic (and eventually PowerDynamics) solutions. Hopefully, this interface is also usefull for all sorts of solution inspection.

Goals

The main goal of this interface is to be extensible behind the "normal" ode states, so it should also support

  • edge states (both ode and static edges) (not yet implemented),
  • "observed" states, i.e. algebraic equations which have been removed by MTK/BlockSystems (not yet implemented),
  • "derived" states, which can by trivially constructed from other states.

Interface

Currently, the interface works as follows:

u_r_f = vstatef(sol, p, 17, :u_r)
plot(sol.t, u_r_f(sol.t))

returns a function, which, applyed to t (such as u_r_f(1.0) or u_r_f(0:0.1:10)) returns the value of state u_r of vertex 17 in the solution sol using p. There is also an option to get several parameters at once like

u_ri_f = vstatef(sol, p, 17, [:u_r, :u_i])

not yet implemented but also planned is to get the same state for several nodes.

u_r_f = vstatef(sol, p, 1:10, :u_r)

which makes sense performance wise because we only need to evalue the rhs of the DGL once per timestep.

"derived" states

Quite often when dealing with powergrids i find myself recalculating the same derived states again and again. Now it is possible to define "virtual" as algebraic functions of other states such as

@register_statelens :u_mag => sqrt(:u_r^2 + :u_i^2)

will allows to generate a timseries for :u_mag directly. Even better

@register_statelens r"^(.*)_arg$" => atan(s"\1_i", s"\1_r")

matches every symbol with ends with _arg so you will be able to generate argument timeseries for every pair of complex cart coordinates. Those definitions can depend on eachother

@register_statelens :_S => (:u_r + :u_i*im)*(:_i_r - :_i_i*im)
@register_statelens :_P => real(:_S)
@register_statelens :_Q => imag(:_S)

would allow direct access to S, Q and P for every node.

There is also an even more low level interface which, for example, can be used to

"observed" states

Not yet implemented in the prototype. The vertex and edge objects need two new fields: observed_sym and observed_f. The observed_f will be a function f(u, edges, p, t) which returns all the observed states for a given statevector. Should be nonbreaking, since those can be allways empty. For vertex and edge functions generated using BlockSystems/MTK this has the advantage of plotting arbtrary internal states using the same interface.

Remarks on parameters

Often, p will change during the simulations in a callback. For direct states and states which are derived from normal states this isn't a problem. However, if one wants to calculate observed states (or static edge states for that matter) it is necessary to provide the correct parameters for each time. This information is not stored in the solution object. In that PR you can use

prob = ODEProblem(nd, p, ...)
pr = PRecord(prob)
...
function affect!(integrator)
    integrator.p = ...
    record!(pr, integrator)
end
...

which keeps track of parameter changes to replay them later.

@hexaeder hexaeder marked this pull request as draft December 13, 2022 17:45
@hexaeder hexaeder force-pushed the hw/solinspect branch 2 times, most recently from ab8ba02 to 61f7a42 Compare January 2, 2023 14:59
@hexaeder
Copy link
Member Author

Turns out the correct interface for the "statelenses" is quite difficult to define therefore I don't want to include it in NetworkDynamics right know. This PR is much simpler now, doing basically two things:

It adds additional meta data fields to the Vertex/Edge types

  • name : name of the vertex
  • psym : name of the parameters
  • obsf : function to retrieve "internal" or "virtual" states, i.e. the various algebraic in between solutions for rms line models
  • obssyms : symbols of the various observed values

This all is added in a backward compatible way. However, it changes the node signatures from Vertex{F} to Vertex{F,G} where G is the type of the obsf function.

Also, I changed the naming scheme for reconstruction of edges. If you defined an edge with symbols (:i_r, :i_i) for example, the reconstructed version became (:i_r, :i_i, :i_r, :i_i). Now it its (:i_r_src, :i_i_src, :i_r_dst, :i_i_dst). This might be considered breaking.

also fix related allocation test
@hexaeder hexaeder marked this pull request as ready for review January 24, 2024 16:22
@hexaeder
Copy link
Member Author

hexaeder commented Sep 4, 2024

obsolete by #140

@hexaeder hexaeder closed this Sep 4, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant