Skip to content

Commit daaec94

Browse files
committed
fix mathematical model description
1 parent f3b0f5b commit daaec94

File tree

1 file changed

+40
-54
lines changed

1 file changed

+40
-54
lines changed

docs/src/mathematical_model.md

Lines changed: 40 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ and $t$ is the time. To make this compatible with the solvers used in `OrdinaryD
2323
```
2424
nw(du, u, p, t) # mutates du as an "output"
2525
```
26-
and represents the right-hand-side (RHS) of the equation above. The mass-matrix $m$ is stored in the `Network` object
26+
and represents the right-hand-side (RHS) of the equation above. The mass-matrix $M$ is stored in the `Network` object
2727
as well.
2828

2929
## Modelling the Dynamics of the System
@@ -48,19 +48,18 @@ potential variables**. When the node and edge models are placed on a graph, the
4848
the nodes receive the output of the adjacent edges as inputs and the edges receive the output of the adjacent nodes as
4949
inputs. Thus, the *flow* on the edges depends on the *potentials* at both ends as inputs. The *potentials* of the nodes
5050
depend on the incoming *flows* from all connected edges as an input. (Here, flow and potentials are meant in a
51-
conceptional and not necessarily physical way.)
51+
conceptual and not necessarily physical way.)
5252

53-
In this graphical representation of a partial network graph
5453
```@raw html
5554
<picture>
5655
<source srcset="../assets/mathmodel-dark.svg" media="(prefers-color-scheme: dark)">
5756
<img src="../assets/mathmodel.svg" width="100%" height="100%"/>
5857
</picture>
5958
```
60-
three nodes are visible (node 1, node 2 and node 3) as well as the edges connecting node 1 and node 2 ($e_{\mathrm 12}$,
61-
$e_{\mathrm 21}$). Above the network, the mass matrix equations on node 1 and node 2 ($M_{\mathrm{c}} x_{\mathrm c}$),
62-
the equations on the connecting edges ($e_{\mathrm 12}$, $e_{\mathrm 21}$), as well as the internal state vector
63-
equations of node1 and node2 ($u_1$ and $u_2$) are also shown.
59+
In this graphical representation of a partial network graph
60+
three nodes are visible (node 1, node 2 and node 3) as well as the edge connecting node 1 and node 2 ($e_{\mathrm{12}}$).
61+
Above the network, you can see the dynamical systems for both nodes 1 and 2 as well as the connecting edge.
62+
The figure shows, how the outputs of the edge appears as input of the nodes and the output of the nodes appears as input of the edge models.
6463

6564
### Vertex Models
6665
The equations of a (single-layer) full vertex model are:
@@ -106,14 +105,14 @@ In contrast to the vertex models, edge models in general have *two* inputs and *
106105
the destination end of the edge. We commonly use `src` and `dst` to describe the source and destination end of an edge,
107106
respectively.
108107

109-
!!! note "Source and Destination definitions "
110-
A source node (`src`) is the node from which the flow exits.
111-
A destination node (`dst`) is the node into which the flow enters.
112-
113108
!!! note "On the directionality of edges"
114109
Mathematically, in a system defined on an undirected graph there is no difference between edge $(1,2)$ and
115110
edge $(2,1)$, because the edge has no direction. However, from an implementation point of view we always need to
116-
have some kind of ordering, which is why we introduce the source (`src`) and destination (`dst`) terminology.
111+
have some kind of ordering. For undirected graphs, the edges are allways defined from `src -> dst` where `src < dst`
112+
(This convention matches the behavior of the `edges` iterator from `Graphs.jl`).
113+
I.e. the undirectional edge between nodes 1 and 2 will be always referenced as `1 -> 2`, never `2 -> 1`.
114+
The **source** and **destination** naming is related to this notion of directionality, it is not related to the actuall flows, i.e.
115+
a system might exists where there is a net flow from destination to source.
117116

118117
The full edge model equations are:
119118
```math
@@ -126,52 +125,40 @@ y^{\mathrm e}_{\mathrm{src}} &= g_\mathrm{src}^{\mathrm e}(u^{\mathrm e}, y^{\ma
126125
and they correspond to the Julia functions:
127126
```julia
128127
function fₑ(dxₑ, xₑ, v_src, v_dst, pₑ, t)
129-
# mutate dxᵥ
128+
# mutate dxₑ
130129
nothing
131130
end
132-
function gₑ(y_src, y_dst, xᵥ, v_src, v_dst, pₑ, t)
131+
function gₑ(y_src, y_dst, xₑ, v_src, v_dst, pₑ, t)
133132
# mutate y_src and y_dst
134133
nothing
135134
end
136-
vertf = EdgeModel(; f=fₑ, g=gₑ, mass_matrix=Mₑ, ...)
135+
edgef = EdgeModel(; f=fₑ, g=gₑ, mass_matrix=Mₑ, ...)
137136
```
138137

139-
The *inputs* of an edge connecting two nodes are the *outputs* of the nodes at both their ends. The output of each node
140-
is split into two parts:
141-
1. the *`dst`* output which is used as the input of the vertex at the destination end
142-
2. the `src` output which is used as the input of the vertex at the `src` end.
138+
Each edge has two inputs: the node outputs of the source and destination end of the edge.
139+
Similarily, they also have two outputs:
140+
1. the `dst` output which is used as the input of the vertex at the destination end
141+
2. the `src` output which is used as the input of the vertex at the source end.
143142

144-
Because a Vertex only receives flows from the edges connected to it, it does not know whether the flow it
145-
received was produced by the source or the destination end of an edge. To solve this problem a sign convention has been
146-
introduced. A positive flow represents a flow *into* the connected vertex, while a negative flow represents a flow *out*
147-
of the connected vertex.
143+
In general, the two edge outputs $y_{\mathrm{src}}$ and $y_{\mathrm{dst}}$ are **completely independent**. There is not implicit conservation law or something like that.
144+
Examples for such unbalanced systems are power lines with losses, i.e. the power flowing into the line does not match the power flowing out of the line, because some energy is lost as heat. Another example would be a gas pipeline with some internal pressure: it es entirely possible to push in gas from both ends simultaneously, which would just result in increased pressure.
145+
For the (important) special case where there is a strong correlation between source and destination output see the section on [Single Sided Edge Outputs](@ref) below.
148146

149-
When we consider $n_1$ as the source and $n_2$ as the destination, flows out of $n_1$ and into $n_2$ are negative,
150-
so $y_dst < 0$. Whereas flows out of $n_2$ and into $n_1$ are positive, so $y_src > 0$.
147+
The vertex models connected to the edge do not know whether they are at the src or dst end of the edge.
148+
Therefore, the sign convention for both outputs of an edge must be identical, typically, a positive flow represents a flow *into* the connected vertex.
151149
```
152-
y_dst < 0
153-
n_1 (src) o───────→────────o n_2 (dst)
154-
y_src > 0
155-
n_1 (src) o───────←────────o n_2 (dst)
156-
```
157-
But when we consider $n_2$ as the source and $n_1$ as the destination, flows out of $n_2$ and into $n_1$ are negative,
158-
so $y_dst < 0$. Whereas flows out of $n_1$ and into $n_2$ are positive, so $y_src > 0$.
150+
y_src ┌───────────────────┐ y_dst
151+
V_src o───←───┤ internal dynamics ├───→───o V_dst
152+
└───────────────────┘
159153
```
160-
y_src > 0
161-
$n_1$ (dst) o───────→────────o $n_2$ (src)
162-
y_dst < 0
163-
$n_1$ (dst) o───────→────────o $n_2$ (src)
164-
```
165-
166-
For undirected graphs, `Graphs.jl` chooses the direction of an edge (so which node is the `src` and which the `dst`)
167-
$v_1->v_2$ such that $v_1 < v_2$, so the edge between vertices 16 and 12 will always be an edge with source
168-
`src=12` and destination `dst=16`.
169154

155+
### Single Sided Edge Outputs
156+
Often, the edge output functions $g_\mathrm{src}$ and $g_\mathrm{dst}$ are not independent, but rather one of them is a function of the other.
157+
For example, in a system with a conservation law, the output at the source end is equal to the output at the destination end, i.e. $y_\mathrm{src} = -y_\mathrm{dst}$.
170158

159+
To accommodate such cases, we can use the concept of **single sided edge output functions**.
160+
A single sided output function only defines a founction for one of the outputs:
171161

172-
### Single Sided Edge Outputs
173-
To simplify the calculations, we split the output flows of edges into "single sided" edge output functions. That way we
174-
can split the output flows of edges into "single sided" edge output functions which simplifies the calculations:
175162
```julia
176163
function g_single(y, xᵥ, v_src, v_dst, pₑ, t)
177164
# mutate y
@@ -180,10 +167,10 @@ end
180167
```
181168

182169
There are multiple wrappers available to automatically convert them into double-sided edge output functions:
183-
- `Directed(g_single)` builds a double-sided function *which only couples* to the destination side.
184-
- `Symmetric(g_single)` builds a double-sided function in which both ends receive `y`.
185-
- `AntiSymmetric(g_single)` builds a double-sided function where the destination receives `y` and the source receives `-y`.
186-
- `Fiducial(g_single_src, g_singl_dst)` builds a double-sided edge output function based on two single sided functions.
170+
- `Directed(g_single)` builds a double-sided function *which only couples* to the destination side (i.e. $y_{dst}=y$ and $y_{src} = 0$).
171+
- `Symmetric(g_single)` builds a double-sided function in which both ends receive `y` (i.e. $y = y_{src} = y_{dst})$.
172+
- `AntiSymmetric(g_single)` builds a double-sided function where the destination receives `y` and the source receives `-y` (i.e. $y=y_{dst}=-y{src}$).
173+
- `Fiducial(g_single_src, g_single_dst)` builds a double-sided edge output function based on two single sided functions.
187174

188175

189176
## Feed Forward Behavior
@@ -214,10 +201,12 @@ transformation can be performed automatically using [`ff_to_constraint`](@ref).
214201

215202
Concretely, NetworkDynamics distinguishes between 4 types of feed forward behaviours of `g` functions based on the
216203
[`FeedForwardType`](@ref) trait.
217-
The feed forward type is inferred automatically based on the provided function `g` (by calculating the signature of the
218-
methods used over the number of arguments it is given.)
204+
The feed forward type is inferred automatically based on the provided function `g` (this is done by inspecting the available
205+
method signatures for `g`, i.e. network dynamics checks how many arguments you `g` function takes)
206+
If the automatic inference of feed forward type fails, the user may specify it explicitly using the `ff` keyword
207+
argument of the Edge/VertexModel constructor.
219208

220-
The code bloke below presents the different `g` signatures for the different feed forward types:
209+
The code block below presents the different `g` signatures for the different feed forward types:
221210

222211
**[`PureFeedForward()`](@ref)**
223212
```julia
@@ -247,6 +236,3 @@ g!(out_dst, x) # single-sided edge
247236
g!(out_src, out_dst, x) # double-sided edge
248237
g!(v_out, x) # single layer vertex
249238
```
250-
251-
If the automatic inference of feed forward type fails, the user may specify it explicitly using the `ff` keyword
252-
argument of the Edge/VertexModel constructor.

0 commit comments

Comments
 (0)