Skip to content

Commit a82d156

Browse files
committed
start reworking the cascading failure example
1 parent a94a05a commit a82d156

File tree

1 file changed

+86
-11
lines changed

1 file changed

+86
-11
lines changed

docs/examples/cascading_failure.jl

Lines changed: 86 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,12 @@ This script can be dowloaded as a normal Julia script [here](@__NAME__.jl). #md
88
99
> [1] Schäfer, B., Witthaut, D., Timme, M., & Latora, V. (2018). Dynamically induced cascading failures in power grids. Nature communications, 9(1), 1-13. https://www.nature.com/articles/s41467-018-04287-5
1010
11+
This example has three subchaperts:
12+
- first we [define the network model](#define-the-model),
13+
- secondly, we implement [component based callbacks](#component-based-callbacks) and
14+
- thirdly we solve the problem using [systemwide callbacks](#system-wide-callbacks).
15+
16+
1117
The system is modeled using swing equation and active power edges. The nodes are
1218
characterized by the voltage angle `δ`, the active power on each line is symmetric
1319
and a function of the difference between source and destination angle `δ_src - δ_dst`.
@@ -22,6 +28,8 @@ using Test #hide
2228
import SymbolicIndexingInterface as SII
2329

2430
#=
31+
## Defining the Model
32+
2533
For the nodes we define the swing equation. State `v[1] = δ`, `v[2] = ω`.
2634
The swing equation has three parameters: `p = (P_ref, I, γ)` where `P_ref`
2735
is the power setpopint, `I` is the inertia and `γ` is the droop or damping coeficcient.
@@ -58,25 +66,92 @@ g = SimpleGraph([0 1 1 0 1;
5866
1 1 0 1 0;
5967
0 1 1 0 1;
6068
1 0 0 1 0])
61-
swing_network = Network(g, vertex, edge)
69+
nw = Network(g, vertex, edge; dealias=true)
6270

6371
#=
64-
For the parameters, we create the `NWParameter` object prefilled with default p values
72+
Note that we used `dealias=true` to automaticially generate separate
73+
`ComponentModels` for each vertex/edge. Doing so allows us to later
74+
set different metadata (callbacks, default values, etc.) for each vertex/edge.
75+
76+
We proceed by setting the default reference power for the nodes:
6577
=#
66-
p = NWParameter(swing_network)
67-
## vertices 1, 3 and 4 act as loads
68-
p.v[(1,3,4), :P_ref] .= -1
69-
## vertices 2 and 5 act as generators
70-
p.v[(2,5), :P_ref] .= 1.5
78+
set_default!(nw, VIndex(1, :P_ref), -1.0) # load
79+
set_default!(nw, VIndex(2, :P_ref), 1.5) # generator
80+
set_default!(nw, VIndex(3, :P_ref), -1.0) # load
81+
set_default!(nw, VIndex(4, :P_ref), -1.0) # load
82+
set_default!(nw, VIndex(5, :P_ref), 1.5) # generator
7183
nothing #hide #md
7284

7385
#=
7486
We can use `find_fixpoint` to find a valid initial condition of the network
7587
=#
76-
u0 = find_fixpoint(swing_network, p)
88+
u0 = find_fixpoint(nw)
89+
set_defaults!(nw, u0) # overwrite the default values with the fixpoint values
90+
nothing #hide #md
91+
92+
#=
93+
## Component-based Callbacks
94+
95+
For the component based callback we need to define a condtion and an affect.
96+
Both functions take trhee inputs:
97+
- the actual function `f`
98+
- the states which to be accessed `sym`
99+
- the parameters to be accessed `psym`
100+
=#
101+
cond = ComponentCondition([:P], [:limit]) do u, p, t
102+
abs(u[:P]) - p[:limit]
103+
end
104+
affect = ComponentAffect([], [:K]) do u, p, ctx
105+
println("Line $(ctx.eidx) tripped at t=$(ctx.integrator.t)")
106+
p[:K] = 0
107+
end
108+
edge_cb = ContinousComponentCallback(cond, affect)
109+
#=
110+
To enable the callback in simulation, we need to attach them to the individual
111+
edgemodels/vertexmodels.
112+
=#
113+
for i in 1:ne(g)
114+
edgemodel = nw[EIndex(i)]
115+
set_callback!(edgemodel, edge_cb)
116+
end
117+
nothing #hide #md
118+
119+
#=
120+
The system starts at a steady state.
121+
In order to see any dynamic, we need to fail a first line intentionally.
122+
For that we define a PresetTimecallback from DiffEqCallbacks library:
123+
=#
124+
trip_first_cb = PresetTimeCallback(1.0, integrator -> begin
125+
@info "Trip initial line 5 at t=$(integrator.t)"
126+
p = NWParameter(integrator)
127+
p.e[5,:K] = 0
128+
auto_dt_reset!(integrator)
129+
save_parameters!(integrator)
130+
end)
131+
nothing
132+
133+
#=
134+
135+
=#
136+
137+
u0 = NWState(nw)
138+
network_cb = get_callbacks(nw)
139+
all_cb = CallbackSet(network_cb, trip_first_cb)
140+
prob = ODEProblem(nw, uflat(u0), (0, 6), pflat(u0); callback=all_cb)
141+
sol = solve(prob, Tsit5());
77142
nothing #hide #md
78143

79144
#=
145+
Lastly we can plot the power on all of the powerlines:
146+
=#
147+
plot(sol; idxs=eidxs(sol, :, :P))
148+
149+
#=
150+
## System wide Callbacks
151+
152+
#
153+
154+
80155
In order to implement the line failures, we need to create a `VectorContinousCallback`.
81156
In the callback, we compare the current flow on the line with the limit. If the limit is reached,
82157
the coupling `K` is set to 0.
@@ -125,8 +200,8 @@ cache accessors to the internal states.
125200
This still isn't ideal beacuse both `getlim` and `getflow` getters will create arrays
126201
within the callback. But is far better then resolving the flat state indices every time.
127202
=#
128-
condition = let getlim = SII.getp(swing_network, epidxs(swing_network, :, :limit)),
129-
getflow = SII.getu(swing_network, eidxs(swing_network, :, :P))
203+
condition = let getlim = SII.getp(nw, epidxs(nw, :, :limit)),
204+
getflow = SII.getu(nw, eidxs(nw, :, :P))
130205
function (out, u, t, integrator)
131206
## careful, u != integrator.u
132207
## therefore construct nwstate with Network info from integrator but u
@@ -157,7 +232,7 @@ trip_first_cb = PresetTimeCallback(1.0, integrator->affect!(integrator, 5));
157232
With those components, we can create the problem and solve it.
158233
=#
159234

160-
prob = ODEProblem(swing_network, uflat(u0), (0,6), copy(pflat(p));
235+
prob = ODEProblem(nw, uflat(u0), (0,6), copy(pflat(p));
161236
callback=CallbackSet(trip_cb, trip_first_cb))
162237
Main.test_execution_styles(prob) # testing all ex styles #src
163238
sol = solve(prob, Tsit5());

0 commit comments

Comments
 (0)