Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
rename Vertex/Edge/ComponentFunction -> Model
Browse files Browse the repository at this point in the history
rename ComponentFunction -> ComponentModel

raname more occurances

more renamings

and mooore renamings
hexaeder committed Nov 19, 2024

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
1 parent f321e1e commit 0cddcf0
Showing 45 changed files with 596 additions and 596 deletions.
2 changes: 1 addition & 1 deletion NEWS.md
Original file line number Diff line number Diff line change
@@ -8,7 +8,7 @@ Users of the package should probably read the new documentation carefully.
The most important changes are:

- Explicit split in `f` and `g` function: There is no split into `ODE` and
`Static` components anymore, verything is unified in component functions with
`Static` components anymore, everything is unified in component models with
internal function `f` and output function `g`.
- Parameters handling: Parameters are allways stored in a flat array. The
Symbolic Indexing Interfaces helps to set and retrieve parameters.
8 changes: 4 additions & 4 deletions benchmark/benchmark_compat.jl
Original file line number Diff line number Diff line change
@@ -30,22 +30,22 @@ end

function _syms_old_order(nd::Network)
syms = []
for (i,cf) in enumerate(nd.im.vertexf)
for (i,cf) in enumerate(nd.im.vertexm)
isdynamic(cf) || continue
append!(syms, collect(VIndex(i, 1:dim(cf))))
end
for (i,cf) in enumerate(nd.im.edgef)
for (i,cf) in enumerate(nd.im.edgem)
isdynamic(cf) || continue
append!(syms, collect(EIndex(i, 1:dim(cf))))
end
syms
end
function _psyms_old_order(nd::Network)
syms = []
for (i,cf) in enumerate(nd.im.vertexf)
for (i,cf) in enumerate(nd.im.vertexm)
append!(syms, collect(VPIndex(i, 1:pdim(cf))))
end
for (i,cf) in enumerate(nd.im.edgef)
for (i,cf) in enumerate(nd.im.edgem)
append!(syms, collect(EPIndex(i, 1:pdim(cf))))
end
syms
18 changes: 9 additions & 9 deletions benchmark/benchmark_models.jl
Original file line number Diff line number Diff line change
@@ -6,40 +6,40 @@ Base.@propagate_inbounds function diffusionedge!(e, v_s, v_d, _, _)
e[1] = v_s[1] - v_d[1]
nothing
end
diffusion_edge() = EdgeFunction(; g=AntiSymmetric(diffusionedge!), outdim=1, pdim=0)
diffusion_edge() = EdgeModel(; g=AntiSymmetric(diffusionedge!), outdim=1, pdim=0)

Base.@propagate_inbounds function diffusion_dedge!(de, e, v_s, v_d, _, _)
de[1] = 100.0 * (sin(v_s[1] - v_d[1]) - e[1])
de[2] = 100.0 * (sin(v_d[1] - v_s[1]) - e[2])
nothing
end
diffusion_dedge() = EdgeFunction(; f=diffusion_dedge!, dim=2, pdim=0, g=Fiducial(dst=1:1, src=2:2))
diffusion_dedge() = EdgeModel(; f=diffusion_dedge!, dim=2, pdim=0, g=Fiducial(dst=1:1, src=2:2))

Base.@propagate_inbounds function diffusionvertex!(dv, _, esum, _, _)
dv[1] = esum[1]
nothing
end
diffusion_vertex() = VertexFunction(; f=diffusionvertex!, dim=1, pdim=0, g=StateMask(1:1))
diffusion_vertex() = VertexModel(; f=diffusionvertex!, dim=1, pdim=0, g=StateMask(1:1))

####
#### inhomogenious kuramoto system
####
Base.@propagate_inbounds function kuramoto_edge!(e, θ_s, θ_d, (K,), t)
e[1] = K * sin(θ_s[1] - θ_d[1])
end
static_kuramoto_edge() = EdgeFunction(; g=AntiSymmetric(kuramoto_edge!), outdim=1, pdim=1)
static_kuramoto_edge() = EdgeModel(; g=AntiSymmetric(kuramoto_edge!), outdim=1, pdim=1)

Base.@propagate_inbounds function kuramoto_vertex!(dθ, θ, esum, (ω,), t)
dθ[1] = ω + esum[1]
end
kuramoto_vertex_1d() = VertexFunction(; f=kuramoto_vertex!, pdim=1, sym=[], g=StateMask(1:1))
kuramoto_vertex_1d() = VertexModel(; f=kuramoto_vertex!, pdim=1, sym=[], g=StateMask(1:1))

Base.@propagate_inbounds function kuramoto_inertia!(dv, v, esum, (P,), t)
dv[1] = v[2]
dv[2] = P - 1.0 * v[2]
dv[2] += esum[1]
end
kuramoto_vertex_2d() = VertexFunction(; f=kuramoto_inertia!, dim=2, pdim=1, sym=[, ], g=StateMask(1:1));
kuramoto_vertex_2d() = VertexModel(; f=kuramoto_inertia!, dim=2, pdim=1, sym=[, ], g=StateMask(1:1));

####
#### powergrid model
@@ -60,7 +60,7 @@ Base.@propagate_inbounds function piline!(out_src, out_dst, src, dst, p, t)
out_src[2] = -imag(isrc)
nothing
end
piline() = EdgeFunction(; g=piline!, outsym=(;src=[:src_i_r, :src_i_i], dst=[:dst_i_r, :dst_i_i]),
piline() = EdgeModel(; g=piline!, outsym=(;src=[:src_i_r, :src_i_i], dst=[:dst_i_r, :dst_i_i]),
psym=[:L, :R, :C1, :C2])

Base.@propagate_inbounds function pq!(du, u, isum, (P,Q), t)
@@ -71,7 +71,7 @@ Base.@propagate_inbounds function pq!(du, u, isum, (P,Q), t)
du[2] = imag(uc)
nothing
end
pqnode() = VertexFunction(; f=pq!, sym=[:u_r, :u_i], g=StateMask(1:2), psym=[:P, :Q], mass_matrix=0)
pqnode() = VertexModel(; f=pq!, sym=[:u_r, :u_i], g=StateMask(1:2), psym=[:P, :Q], mass_matrix=0)

Base.@propagate_inbounds function gen!(dv, v, isum, p, T)
# unpack parameters
@@ -107,5 +107,5 @@ Base.@propagate_inbounds function gen!(dv, v, isum, p, T)

nothing
end
generator() = VertexFunction(; f=gen!, sym=[:u_r, :u_i, , ], g=StateMask(1:2),
generator() = VertexModel(; f=gen!, sym=[:u_r, :u_i, , ], g=StateMask(1:2),
psym=[:H, :P, :D, , :E_f, :T_d_dash, :T_q_dash, :X_d_dash, :X_q_dash, :X_d, :X_q])
12 changes: 6 additions & 6 deletions docs/examples/StochasticSystem.jl
Original file line number Diff line number Diff line change
@@ -42,7 +42,7 @@ Here, $dW_i = \xi_i dt$ is the infinitesimal increment of the Wiener process. Pr
## Implementing the Swing Equation
First we will implement the node and edge functions for the deterministic case
First we will implement the node and edge models for the deterministic case
without the fluctuations. We set the defaults for the inertia and damping
parameters to be $M_i = 1.0$ and $D_i = 0.1$. The default coupling strength is $K=6$.
=#
@@ -55,13 +55,13 @@ function swing_equation!(dv, v, esum, (M, P, D), t)
dv[2] = 1/M *(P - D * v[2] + esum[1])
nothing
end
swing_vertex = VertexFunction(f=swing_equation!, g=1, sym=[, ], psym=[:M=>1, :P, :D=>0.1])
swing_vertex = VertexModel(f=swing_equation!, g=1, sym=[, ], psym=[:M=>1, :P, :D=>0.1])
#-

function powerflow!(e, v_s, v_d, (K,), t)
e[1] = K * sin(v_s[1] - v_d[1])
end
powerflow_edge = EdgeFunction(g=AntiSymmetric(powerflow!), outdim=1, psym=[:K=>6])
powerflow_edge = EdgeModel(g=AntiSymmetric(powerflow!), outdim=1, psym=[:K=>6])

#=
## Contructing the Deterministic Dynamics
@@ -132,11 +132,11 @@ FIXME: stochastic system should be simulated using symbolic indexing, this is js
# nothing #hide #md

#=
Now we can construct the dynamics of the second layer by using `network_dynamics()`. Since the graph structure of the stochastic layer has no edges we can take the edge function of the deterministic case as a placeholder.
Now we can construct the dynamics of the second layer by using `network_dynamics()`. Since the graph structure of the stochastic layer has no edges we can take the edge model of the deterministic case as a placeholder.
=#

# fluctuation_vertex = VertexFunction(f=fluctuation!, g=1:2, dim=2)
# nd_noise = Network(h, fluctuation_vertex, NetworkDynamics.EdgeFunction[])
# fluctuation_vertex = VertexModel(f=fluctuation!, g=1:2, dim=2)
# nd_noise = Network(h, fluctuation_vertex, NetworkDynamics.EdgeModel[])
nothing #hide #md

#=
4 changes: 2 additions & 2 deletions docs/examples/cascading_failure.jl
Original file line number Diff line number Diff line change
@@ -37,7 +37,7 @@ function swing_equation(dv, v, esum, p,t)
dv[2] = dv[2] / I
nothing
end
vertex = VertexFunction(f=swing_equation, g=1, sym=[, ], psym=[:P_ref, :I=>1, =>0.1])
vertex = VertexModel(f=swing_equation, g=1, sym=[, ], psym=[:P_ref, :I=>1, =>0.1])

#=
Lets define a simple purely active power line whose active power flow is
@@ -48,7 +48,7 @@ We give an additonal parameter, the line limit, which we'll use later in the cal
function simple_edge(e, v_s, v_d, (K,), t)
e[1] = K * sin(v_s[1] - v_d[1])
end
edge = EdgeFunction(;g=AntiSymmetric(simple_edge), outsym=:P, psym=[:K=>1.63, :limit=>1])
edge = EdgeModel(;g=AntiSymmetric(simple_edge), outsym=:P, psym=[:K=>1.63, :limit=>1])

#=
With the definition of the graph topology we can build the `Network` object:
6 changes: 3 additions & 3 deletions docs/examples/directed_and_weighted_graphs.jl
Original file line number Diff line number Diff line change
@@ -76,7 +76,7 @@ nothing #hide #md
#=
## Setting up the ODEProblem
Defining `VertexFunction` and `EdgeFunction` is similar to the example before. The macro `Base.@propagate_inbounds` tells the compiler to inline the function and propagate the inbounds context. For more details see the julia [documentation](https://docs.julialang.org/en/v1/devdocs/boundscheck/).
Defining the `VertexModel` and `EdgeModel` is similar to the example before. The macro `Base.@propagate_inbounds` tells the compiler to inline the function and propagate the inbounds context. For more details see the julia [documentation](https://docs.julialang.org/en/v1/devdocs/boundscheck/).
=#

@@ -86,14 +86,14 @@ Base.@propagate_inbounds function fhn_electrical_vertex!(dv, v, esum, p, t)
dv[2] = (v[1] - a) * ϵ
nothing
end
vertex = VertexFunction(f=fhn_electrical_vertex!, g=1, sym=[:u, :v], psym=[:a=>0.5, =>0.05])
vertex = VertexModel(f=fhn_electrical_vertex!, g=1, sym=[:u, :v], psym=[:a=>0.5, =>0.05])
#-

Base.@propagate_inbounds function electrical_edge!(e, v_s, v_d, (w, σ), t)
e[1] = w * (v_s[1] - v_d[1]) * σ
nothing
end
electricaledge = EdgeFunction(g=Directed(electrical_edge!), outdim=1, psym=[:weight, =>0.5])
electricaledge = EdgeModel(g=Directed(electrical_edge!), outdim=1, psym=[:weight, =>0.5])
#-

fhn_network! = Network(g_directed, vertex, electricaledge)
20 changes: 10 additions & 10 deletions docs/examples/gas_network.jl
Original file line number Diff line number Diff line change
@@ -234,25 +234,25 @@ nothing #hide
To bild the Network we first need to define the components. This is a two step process:
- first create the symbolic `ODESystem` using ModelingToolkit
- secondly build a NetworkDynamics component function ([`VertexFunction`](@ref)/[`EdgeFunction`](@ref)) based on the symbolic system.
- secondly build a NetworkDynamics component model ([`VertexModel`](@ref)/[`EdgeModel`](@ref)) based on the symbolic system.
In the first step we can use the keyword arguments to pass "default" values for our parameters and states.
Those values will be automaticially transfered to the metadata of the component function the second step.
Those values will be automaticially transfered to the metadata of the component model the second step.
The second step requires to define the interface variables, i.e. what are the "input" states of your
component function and what are the "output" states.
For `VertexFunction` the input state is the aggregated flow of all connected pipes. The output state is the pressure of the node.
component model and what are the "output" states.
For `VertexModel` the input state is the aggregated flow of all connected pipes. The output state is the pressure of the node.
=#
@named v1_mtk = ConstantPressureNode(p_set=p₁_set)
v1 = VertexFunction(v1_mtk, [:q̃_nw], [:p]; name=:v1, vidx=1)
v1 = VertexModel(v1_mtk, [:q̃_nw], [:p]; name=:v1, vidx=1)
#

@named v2_mtk = VariablePressureNode(C=C₂, load_profile=load2)
v2 = VertexFunction(v2_mtk, [:q̃_nw], [:p]; name=:v2, vidx=2)
v2 = VertexModel(v2_mtk, [:q̃_nw], [:p]; name=:v2, vidx=2)
#

@named v3_mtk = VariablePressureNode(C=C₃, load_profile=load3)
v3 = VertexFunction(v3_mtk, [:q̃_nw], [:p]; name=:v3, vidx=3)
v3 = VertexModel(v3_mtk, [:q̃_nw], [:p]; name=:v3, vidx=3)

#=
For the edge Model we have two inputs: the pressure on both source and destination end.
@@ -264,9 +264,9 @@ meas that the source end will recieve the same flow, just inverted sign.
@named e13_mtk = Pipe(; L=L₁₃, sinθ=sinθ₁₃, D, A, γ, η, r, g, T, Tc, pc, Rs, c̃, ρ̃, p̃)
@named e23_mtk = Pipe(; L=L₂₃, sinθ=sinθ₂₃, D, A, γ, η, r, g, T, Tc, pc, Rs, c̃, ρ̃, p̃)

e12 = EdgeFunction(e12_mtk, [:p_src], [:p_dst], AntiSymmetric([:q̃]); name=:e12, src=1, dst=2)
e13 = EdgeFunction(e13_mtk, [:p_src], [:p_dst], AntiSymmetric([:q̃]); name=:e13, src=1, dst=3)
e23 = EdgeFunction(e23_mtk, [:p_src], [:p_dst], AntiSymmetric([:q̃]); name=:e23, src=2, dst=3)
e12 = EdgeModel(e12_mtk, [:p_src], [:p_dst], AntiSymmetric([:q̃]); name=:e12, src=1, dst=2)
e13 = EdgeModel(e13_mtk, [:p_src], [:p_dst], AntiSymmetric([:q̃]); name=:e13, src=1, dst=3)
e23 = EdgeModel(e23_mtk, [:p_src], [:p_dst], AntiSymmetric([:q̃]); name=:e23, src=2, dst=3)

#=
To build the network object we just need to pass the vertices and edges to the constructor.
20 changes: 10 additions & 10 deletions docs/examples/getting_started_with_network_dynamics.jl
Original file line number Diff line number Diff line change
@@ -33,7 +33,7 @@ From the above considerations we see that in this model the nodes do not have an
In order to bring this equation into the form required by NetworkDynamics.jl we need split the dynamics into edge and vertex parts and bring them into the correct input-output formulation.
The vertices have one internal state $v$ which is also the output. The input is
the sum over all flows of connected edges. This directly correspons to the component function definition outlined in [Mathematical Model](@ref):
the sum over all flows of connected edges. This directly correspons to the component model definition outlined in [Mathematical Model](@ref):
```math
\begin{aligned}
\dot x^\mathrm{v} &= f^{\mathrm v}(u^{\mathrm v}, \sum_k^{\text{incident}} y^{\mathrm e}_k, p^{\mathrm v}, t) &&= \sum_k^\mathrm{incident} y^\mathrm{e}_k \\
@@ -50,7 +50,7 @@ y^{\mathrm e}_{\mathrm{src}} &= g_\mathrm{src}^{\mathrm e}(u^{\mathrm e}, y^{\ma
\end{aligned}
```
### Definition of `EdgeFunction`
### Definition of `EdgeModel`
=#
function diffusionedge_g!(e_dst, v_src, v_dst, p, t)
## e_dst, v_src, v_dst are arrays, hence we use the broadcasting operator
@@ -64,12 +64,12 @@ The function `diffusionedge_g!` takes as inputs the current state of the edge `e
`diffusionedge_g!` is called a **mutating** function, since it modifies (or *mutates*) one of its inputs, namely the edge state `e`. As a convention in Julia names of mutating functions end with an `!`. The use of mutating functions reduces allocations and thereby speeds up computations. After the function call the edge's output value `e` equals the difference between its source and its destination vertex (i.e. the discrete gradient along that edge).
Notably, this function only models $g_\mathrm{dst}$. However we can wrap this single-sided output function in an [`AntiSymmetric`](@ref) output wrapper to construct the [`EdgeFunction`](@ref):
Notably, this function only models $g_\mathrm{dst}$. However we can wrap this single-sided output function in an [`AntiSymmetric`](@ref) output wrapper to construct the [`EdgeModel`](@ref):
=#
nd_diffusion_edge = EdgeFunction(; g=AntiSymmetric(diffusionedge_g!), outsym=[:flow])
nd_diffusion_edge = EdgeModel(; g=AntiSymmetric(diffusionedge_g!), outsym=[:flow])

#=
### Definition of `VertexFunction`
### Definition of `VertexModel`
For undirected graphs, the `edgefunction!` specifies the coupling from a source- to a destination vertex. The contributions of the connected edges to a single vertex are "aggregated". Default aggregation is the summation of all incident edge states. The aggregated edge state is made available via the `esum` argument of the vertex function.
=#
function diffusionvertex_f!(dv, v, esum, p, t)
@@ -84,7 +84,7 @@ Just like above the input arguments `v, esum, p, t` are mandatory for the syntax
The output function `g` is just taking part of the internal states. For that we can use the [`StateMask`](@ref) helper function `g = StateMaks(1:1)`
=#
nd_diffusion_vertex = VertexFunction(; f=diffusionvertex_f!, g=StateMask(1:1), dim=1)
nd_diffusion_vertex = VertexModel(; f=diffusionvertex_f!, g=StateMask(1:1), dim=1)


#=
@@ -104,7 +104,7 @@ nothing #hide #md
nd = Network(g, nd_diffusion_vertex, nd_diffusion_edge)

#=
The constructor `Network` combines the component function with the topological information contained in the graph **`g`** and returns an `Network` compatible with the solvers of `DifferentialEquations.jl`.
The constructor `Network` combines the component model with the topological information contained in the graph **`g`** and returns an `Network` compatible with the solvers of `DifferentialEquations.jl`.
=#

rng = StableRNG(1)
@@ -129,16 +129,16 @@ In oder to collect multiple indices we can use the helper function [`vidxs`](@re
To illustrate a very simple multi-dimensional case, in the following we simulate two independent diffusions on an identical graph. The first uses the symbol `x` and is started with initial conditions drawn from the standard normal distribution $N(0,1)$, the second uses the symbol `ϕ` with squared standard normal inital conditions.
The symbols have to be passed with the keyword **`sym`** to `VertexFunction`.
The symbols have to be passed with the keyword **`sym`** to `VertexModel`.
=#

N = 10 # number of nodes
k = 4 # average degree
g = barabasi_albert(N, k) # a little more exciting than a bare random graph

## We will have two independent diffusions on the network, hence dim = 2
nd_diffusion_vertex_2 = VertexFunction(; f=diffusionvertex_f!, g=1:2, dim=2, sym=[:x, ])
nd_diffusion_edge_2 = EdgeFunction(; g=AntiSymmetric(diffusionedge_g!), outsym=[:flow_x, :flow_ϕ])
nd_diffusion_vertex_2 = VertexModel(; f=diffusionvertex_f!, g=1:2, dim=2, sym=[:x, ])
nd_diffusion_edge_2 = EdgeModel(; g=AntiSymmetric(diffusionedge_g!), outsym=[:flow_x, :flow_ϕ])
nd_2 = Network(g, nd_diffusion_vertex_2, nd_diffusion_edge_2)

x0_2 = vec(transpose([randn(rng, N) .^ 2 randn(rng, N)])) # x ~ N(0,1)^2; ϕ ~ N(0,1)
14 changes: 7 additions & 7 deletions docs/examples/heterogeneous_system.jl
Original file line number Diff line number Diff line change
@@ -21,14 +21,14 @@ function kuramoto_edge!(e, θ_s, θ_d, (K,), t)
e[1] = K * sin(θ_s[1] - θ_d[1])
nothing
end
edge! = EdgeFunction(g=AntiSymmetric(kuramoto_edge!), outdim=1, psym=[:K=>3])
edge! = EdgeModel(g=AntiSymmetric(kuramoto_edge!), outdim=1, psym=[:K=>3])
#-

function kuramoto_vertex!(dθ, θ, esum, (ω0,), t)
dθ[1] = ω0 + esum[1]
nothing
end
vertex! = VertexFunction(f=kuramoto_vertex!, g=StateMask(1:1), sym=[], psym=[:ω0], name=:kuramoto)
vertex! = VertexModel(f=kuramoto_vertex!, g=StateMask(1:1), sym=[], psym=[:ω0], name=:kuramoto)
#-

nw = Network(g, vertex!, edge!)
@@ -78,7 +78,7 @@ function static_g(out, u, p, t)
out[1] = p[1]
nothing
end
static! = VertexFunction(g=static_g, outsym=[], psym=[:θfix => ω[1]], name=:static)
static! = VertexModel(g=static_g, outsym=[], psym=[:θfix => ω[1]], name=:static)

#=
But wait! NetworkDynamics classified this as [`PureFeedForward`](@ref), because it cannot
@@ -90,7 +90,7 @@ g(out, ins, p, t) # NoFeedForward
and since `dim(u)=0` it wrongfully assumes that the latter is meant.
We can overwrite the classification by passing the ff keyword:
=#
static! = VertexFunction(g=static_g, outsym=[], psym=[:θfix => ω[1]], ff=NoFeedForward(), name=:static)
static! = VertexModel(g=static_g, outsym=[], psym=[:θfix => ω[1]], ff=NoFeedForward(), name=:static)

#=
A Kuramoto model with inertia consists of two internal variables leading to
@@ -102,15 +102,15 @@ function kuramoto_inertia!(dv, v, esum, (ω0,), t)
nothing
end

inertia! = VertexFunction(f=kuramoto_inertia!, g=1:1, sym=[, ], psym=[:ω0], name=:inertia)
inertia! = VertexModel(f=kuramoto_inertia!, g=1:1, sym=[, ], psym=[:ω0], name=:inertia)

#=
Since now we model a system with heterogeneous node dynamics we can no longer
straightforwardly pass a single VertexFunction to the `Network` constructor but
straightforwardly pass a single VertexModel to the `Network` constructor but
instead have to hand over an Array.
=#

vertex_array = VertexFunction[vertex! for i in 1:N]
vertex_array = VertexModel[vertex! for i in 1:N]
vertex_array[1] = static!
vertex_array[5] = inertia! # index should correspond to the node's index in the graph
nw_hetero! = Network(g, vertex_array, edge!)
Loading

0 comments on commit 0cddcf0

Please sign in to comment.