Skip to content

Commit d04593d

Browse files
committed
test full network build from yaml
1 parent 24257bb commit d04593d

File tree

3 files changed

+101
-53
lines changed

3 files changed

+101
-53
lines changed

src/importexport.jl

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -46,17 +46,17 @@ Update the property in the parent structure.
4646
- if key is indexed (i.e. "a[1]"), it will update parent["a"][1]
4747
"""
4848
function update_parent_property!(parent, key, value)
49-
@info "Update $key -> $value"
49+
@debug "Update $key -> $value"
5050
if contains(key, ".")
5151
key_head, key_tail = split(key, ".", limit=2)
52-
@info "Found nested key $key_head -> $key_tail"
52+
@debug "Found nested key $key_head -> $key_tail"
5353
m = match(r"^(.*)\[(.*)\]$", key_head)
5454
_parent = if !isnothing(m)
5555
parent[m[1]][parse(Int, m[2])]
5656
else
5757
parent[key]
5858
end
59-
@info m
59+
@debug m
6060
update_parent_property!(_parent, key_tail, value)
6161
else
6262
m = match(r"^(.*)\[(.*)\]$", key)
@@ -106,14 +106,17 @@ end
106106
widen_container_type(container::OrderedDict{K}) where {K} = convert(OrderedDict{K,Any}, container)
107107
widen_container_type(container::Vector) = convert(Vector{Any}, container)
108108

109-
replace_in_template!(template, placeholder, model) = template
110-
function replace_in_template!(container::Union{OrderedDict,Vector}, placeholder, model)
109+
function replace_in_template(template, placeholder, model)
110+
_replace_in_template!(deepcopy(template), placeholder, model)
111+
end
112+
_replace_in_template!(template, placeholder, model) = template
113+
function _replace_in_template!(container::Union{OrderedDict,Vector}, placeholder, model)
111114
container = widen_container_type(container)
112115
for (key, value) in pairs(container)
113116
if value == placeholder
114117
container[key] = deepcopy(model)
115118
else
116-
container[key] = replace_in_template!(value, placeholder, model)
119+
container[key] = _replace_in_template!(value, placeholder, model)
117120
end
118121
end
119122
container
@@ -126,7 +129,7 @@ function apply_wrappers!(container::Union{OrderedDict,Vector})
126129
wrapper = container["WRAPPER"]
127130
delete!(container, "WRAPPER")
128131
for (key, sub) in pairs(container)
129-
container[key] = replace_in_template!(wrapper, "MODEL", sub)
132+
container[key] = replace_in_template(wrapper, "MODEL", sub)
130133
end
131134
container
132135
end
@@ -146,13 +149,13 @@ function parse_network(file)
146149
resolved_something = false
147150
for (mod, deps) in dependencies
148151
if deps resolved_models
149-
@info "Resolving $mod -> $deps"
152+
@debug "Resolving $mod -> $deps"
150153
recursive_resolve!(data["Models"], data["Models"][mod])
151154
delete!(dependencies, mod)
152155
push!(resolved_models, mod)
153156
resolved_something = true
154157
else
155-
@info "Skip $mod -> $deps"
158+
@debug "Skip $mod -> $deps"
156159
end
157160
end
158161
resolved_something && continue
@@ -191,6 +194,7 @@ function _depth_first_construct!(constructors, data::Union{OrderedDict,Vector})
191194
key ("CONSTRUCTOR", "ARGS") && continue
192195
kwargs[Symbol(key)] = value
193196
end
197+
@debug "call: $(data["CONSTRUCTOR"])(args...; $(kwargs))"
194198
return constructors[data["CONSTRUCTOR"]](args...; kwargs...)
195199
end
196200
data
@@ -199,14 +203,16 @@ end
199203
function build_network(data, constructors)
200204
vertexm = VertexModel[]
201205
for (k, v) in data["VertexModels"]
206+
@debug "Constructing VertexModel $k"
202207
vm = recursive_construct(constructors, v)
203208
set_graphelement!(vm, k)
204209
push!(vertexm, vm)
205210
end
206211

207-
edgem = EdgeModel[]
208-
for (k, v) in data["VertexModels"]
209-
vm = recursive_construct(constructors, v)
212+
edgem = EdgeModel[]
213+
for (k, v) in data["EdgeModels"]
214+
@debug "Constructing EdgeModel $k"
215+
em = recursive_construct(constructors, v)
210216

211217
m = match(r"^(.*)=>(.*)$", k)
212218
isnothing(m) && error("Edge key must be of form 'src=>dst', got $k")
@@ -216,9 +222,15 @@ function build_network(data, constructors)
216222
src = m[1]
217223
end
218224
if isnothing(dst)
219-
dst = m[1]
225+
dst = m[2]
220226
end
221-
set_graphelement!(vm, src, dst)
222-
push!(vertexm, vm)
227+
set_graphelement!(em, src => dst)
228+
push!(edgem, em)
223229
end
230+
Network(vertexm, edgem)
231+
end
232+
233+
function load_network(constructors, file)
234+
data = parse_network(file)
235+
build_network(data, constructors)
224236
end

test/importexport_test.jl

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -81,9 +81,9 @@ v3 = let
8181
end
8282

8383
v4 = let
84-
@named swing = Swing(; Pmech=2.0, M=1.0, D=1.0)
84+
@named swing2 = Swing(; Pmech=2.0, M=1.0, D=1.0)
8585
@named load = Load(; Pd=-1.0)
86-
@named swingload2 = CombinedModel(swing, load)
86+
@named swingload2 = CombinedModel(swing2, load)
8787
VertexModel(swingload2, [:Pel], [], vidx=4)
8888
end
8989

@@ -96,19 +96,36 @@ e2 = let
9696
EdgeModel(line, [:srcθ], [:dstθ], [:P]; annotation=:AntiSymmetric, src=2, dst=3)
9797
end
9898
e3 = let
99-
@named line = StaticPowerLine()
100-
EdgeModel(line, [:srcθ], [:dstθ], [:P]; annotation=:AntiSymmetric, src=3, dst=4)
99+
@named line3 = StaticPowerLine()
100+
EdgeModel(line3, [:srcθ], [:dstθ], [:P]; annotation=:AntiSymmetric, src=3, dst=4)
101101
end
102102

103-
nw = Network([v1,v2,v3,v4],[e1,e2,e3])
103+
nw1 = Network([v1,v2,v3,v4],[e1,e2,e3])
104104

105105
rng = StableRNG(1)
106-
u = randn(rng, dim(nw))
107-
du1 = [NaN for _ in 1:dim(nw)]
108-
nw(du1, u, pflat(NWState(nw)), NaN)
106+
u = randn(rng, dim(nw1))
107+
du1 = [NaN for _ in 1:dim(nw1)]
108+
nw1(du1, u, pflat(NWState(nw1)), NaN)
109109

110-
data = NetworkDynamics.parse_network("testgrid.yaml")
111-
data["VertexModels"][1]
110+
constructors = Dict(
111+
"Swing"=>Swing,
112+
"VertexModel"=>VertexModel,
113+
"Load"=>Load,
114+
"CombinedModel"=>CombinedModel,
115+
"StaticPowerLine"=>StaticPowerLine,
116+
"EdgeModel"=>EdgeModel
117+
)
118+
nw2 = NetworkDynamics.load_network(constructors, "testgrid.yaml")
112119

113-
constructors = Dict("Swing"=>Swing, "VertexModel"=>VertexModel, "Load"=>Load)
114-
NetworkDynamics.build_network(data, constructors)
120+
du2 = [NaN for _ in 1:dim(nw2)]
121+
nw2(du2, u, pflat(NWState(nw2)), NaN)
122+
@test du1 du2
123+
124+
_getname = x -> getproperty(x, :name)
125+
@test map(_getname, nw1.im.vertexm) == map(_getname, nw2.im.vertexm)
126+
@test map(_getname, nw1.im.edgem) == map(_getname, nw2.im.edgem)
127+
128+
s1 = NWState(nw1)
129+
s2 = NWState(nw2)
130+
@test uflat(s1) == uflat(s2)
131+
@test pflat(s1) == pflat(s2)

test/testgrid.yaml

Lines changed: 45 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,45 @@
11
title: Power Grid Example
22
version: "1.0"
3-
description: 6 Bus Powergrid Toy Example
3+
description: 4 Bus Powergrid Test Network
44

55
# special words are "MODEL", "CONSTRUCTOR", "ARGS", "WRAPPER"
66
Models:
77
Swing:
88
CONSTRUCTOR: Swing
9-
name: :swing
10-
Pmech: 1
11-
M: 1
9+
Pmech: 1.0
10+
M: 1.0
1211
D: 1.0
12+
name: :swing
1313

14-
Load: # base models have known constructor
14+
Load:
1515
CONSTRUCTOR: Load
16+
Pd: -42.0
1617
name: :load
17-
Pd: -1.0
1818

19-
DerivedLoad:
20-
MODEL: Models.Load
21-
Pd: 2
22-
23-
Swing_And_Load:
19+
SwingLoad:
2420
CONSTRUCTOR: CombinedModel
2521
ARGS:
26-
- Models.Swing
22+
- MODEL: Models.Swing
2723
- MODEL: Models.Load
28-
Pd: 2
29-
name: "combined model"
30-
31-
DerivedSwing_And_Load:
32-
MODEL: Models.Swing_And_Load
33-
ARGS[1].Pd: 3
24+
Pd: -2.0
25+
name: :swingload
3426

35-
DerivedSwing_And_Load2:
36-
MODEL: Models.Swing_And_Load
37-
ARGS[1]:
38-
Pd: 4
39-
name: :foo
27+
SwingLoad2:
28+
CONSTRUCTOR: CombinedModel
29+
ARGS:
30+
- MODEL: Models.Swing
31+
Pmech: 2.0
32+
- MODEL: Models.Load
33+
Pd: -1.0
4034

4135
StaticPowerLine:
4236
CONSTRUCTOR: StaticPowerLine
37+
K: 1.63
38+
name: :line
39+
40+
StaticPowerLineK05:
41+
MODEL: Models.StaticPowerLine
42+
K: 0.5
4343

4444
VertexModels:
4545
WRAPPER:
@@ -48,10 +48,29 @@ VertexModels:
4848
- MODEL
4949
- [":Pel"]
5050
- [":θ"]
51-
1:
52-
MODEL: Models.Swing
51+
1: Models.Swing
5352
2:
5453
MODEL: Models.Load
55-
Pd: 1
54+
Pd: -1.0
55+
3: Models.SwingLoad
56+
4:
57+
MODEL: Models.SwingLoad2
58+
name: :swingload2
59+
ARGS[1].name: :swing2
5660

5761
EdgeModels:
62+
WRAPPER:
63+
CONSTRUCTOR: EdgeModel
64+
ARGS:
65+
- MODEL
66+
- [":srcθ"]
67+
- [":dstθ"]
68+
- [":P"]
69+
annotation: :AntiSymmetric
70+
"1=>2": Models.StaticPowerLineK05
71+
"2=>3":
72+
MODEL: Models.StaticPowerLine
73+
K: 1.0
74+
"3=>4":
75+
MODEL: Models.StaticPowerLine
76+
name: :line3

0 commit comments

Comments
 (0)