JuliaEnergy / PowerDynSolve.jl

Subpackage of PowerDynamics.jl providing the functionality to solve/simulate the built models
https://juliaenergy.github.io/PowerDynamics.jl/dev/
GNU General Public License v3.0
1 stars 4 forks source link

implementation of contingencies #28

Open timziebart opened 5 years ago

timziebart commented 5 years ago

Hi @luap-pik ,cc @FHell

I thougth about your question in https://github.com/JuliaEnergy/PowerDynamicsExamples/pull/5#issuecomment-482619557 a bit more and got a rough, still abstract idea.

What do you think? And would you be up for a sample implementation?

Best, Tim


Interface:

Maybe it would be good, to define operations on a power grid, e.g. replaceNode(grid, node_number, new_node_instance) which then returns soemthing like a ModifiedGridDynamics (which somehow also encodes how the old grid realtes to the modified one). Then one could do modifications on one's own as one wants, and in a simple manner.

Furthermore, we could proide a macro for an event / contingengy

contingency = @Event t replaceNode node_number new_node_instance

which is then given as an argument for solve as well.

This would provide the user with "one good way" to do it, instead of him having to decide what makes more sense. (Attitude stolen form Python :smile_cat:.)

Implementation of the Interace

A rough sketch (not tested) for the wrapping of the event/contingengy would be:

abstract type AbstractEvent end

struct SingleEvent <: AbstractEvent
    t::Time
    event_call::Expr
end
(ev::SingleEvent)(grid) # maybe more arguments ... and I omitted typing
    eval(ev.event_call)
end

macro Event(tExpr, funcExpr, args...)
    # a bit crude, but that should work as a first test implementation
    esc(:(SingleEvent($(tExpr), $(funcExpr)( grid, $(args)... ) )))
end

Backend

And with such an interface, we can do whatever we choose in the backend. We could decide internally, whether we would do that by callbacsk to DiffEq or by concatenating multiple solutions. Side note: I realized another reason, why I did it with concatenation: During the contingency there is a different power grid (from the modeling perspective) than outside of it. As the power grid is a feature of the solution (in order to enable the handy access to the solution values), that might break things. Example: Imagine you simulate a line outage. Then you have different nodal admittance matrices over time. But where should the GridSolution instance know, when to use which ones. Hence, I implemented CompositeGridSolution, which takes care of that. And as I had to do that anyway, I found it easier to implement it without callbacks.