diff --git a/previews/PR188/.documenter-siteinfo.json b/previews/PR188/.documenter-siteinfo.json index 64d04f3a..06c8e1db 100644 --- a/previews/PR188/.documenter-siteinfo.json +++ b/previews/PR188/.documenter-siteinfo.json @@ -1 +1 @@ -{"documenter":{"julia_version":"1.11.2","generation_timestamp":"2024-12-04T09:56:16","documenter_version":"1.8.0"}} \ No newline at end of file +{"documenter":{"julia_version":"1.11.2","generation_timestamp":"2024-12-04T16:45:08","documenter_version":"1.8.0"}} \ No newline at end of file diff --git a/previews/PR188/API/index.html b/previews/PR188/API/index.html index f3b18b7e..a7bdd58f 100644 --- a/previews/PR188/API/index.html +++ b/previews/PR188/API/index.html @@ -1,42 +1,42 @@ -API · NetworkDynamics

API

The following functions are designed for public use.

Network Construction API

NetworkDynamics.NetworkType
Network([g,] vertexf, edgef; kwarg...)

Construct a Network object from a graph g and edge and component models vertexf and edgef.

Arguments:

  • g::AbstractGraph: The graph on which the network is defined. Optional, can be ommittet if all component models have a defined graphelement. See vidx and src/dst keywors for VertexModel and EdgeModel constructors respectively.

  • vertexm: A single VertexModel or a vector of VertexModel objects. The order of the vertex models must mirror the order of the vertices(g) iterator.

  • edgem: A single EdgeModel or a vector of EdgeModel objects. The order of the edge models must mirror the order of the edges(g) iterator.

Optional keyword arguments:

  • execution=SequentialExecution{true}(): Execution model of the network. E.g. SequentialExecution, KAExecution, PolyesterExecution or ThreadedExecution.
  • aggregator=execution isa SequentialExecution ? SequentialAggregator(+) : PolyesterAggregator(+): Aggregation function applied to the edge models. E.g. SequentialAggregator, PolyesterAggregator, ThreadedAggregator, SparseAggregator.
  • check_graphelement=true: Check if the graphelement metadata is consistent with the graph.
  • dealias=false Check if the components alias eachother and create copies if necessary. This is necessary if the same component model is referenced in multiple places in the Network but you want to dynamicially asign metadata, such as initialization information to specific instances.
  • verbose=false: Show additional information during construction.
source
Network(nw::Network; g, vertexm, edgem, kwargs...)

Rebuild the Network with same graph and vertex/edge models but possibly different kwargs.

source
NetworkDynamics.dimMethod
dim(nw::Network)

Returns the number of dynamic states in the network, corresponts to the length of the flat state vector.

source
NetworkDynamics.pdimMethod
pdim(nw::Network)

Returns the number of parameters in the network, corresponts to the length of the flat parameter vector.

source

Component Models

NetworkDynamics.VertexModelMethod
VertexModel(; kwargs...)

Build a VertexModel according to the keyword arguments.

Main Arguments:

  • f=nothing: Dynamic function of the component. Can be nothing if dim is 0.
  • g: Output function of the component. Usefull helpers: StateMask
  • sym/dim: Symbolic names of the states. If dim is provided, sym is set automaticially.
  • outsym/outdim: Symbolic names of the outputs. If outdim is provided, outsym is set automaticially. Can be infered automaticially if g isa StateMask.
  • psym/pdim=0: Symbolic names of the parameters. Ifpdimis provided,psym` is set automaticially.
  • mass_matrix=I: Mass matrix of component. Can be a vector v and is then interpreted as Diagonal(v).
  • name=dim>0 ? :VertexM : :StaticVertexM: Name of the component.

Optional Arguments:

  • insym/indim: Symbolic names of the inputs. If indim is provided, insym is set automaticially.
  • vidx: Index of the vertex in the graph, enables graphless constructor.
  • ff: FeedForwardType of component. Will be typically infered from g automaticially.
  • obssym/obsf: Define additional "observable" states.
  • symmetadata/metadata: Provide prefilled metadata dictionaries.
  • extin=nothing: Define "external" inputs for the model with Network indices, i.e. extin=[VIndex(7,:x), ..]. Those inputs will be provided as another input vector f(x, in, extin, p, t) and g(y, x, in, extin, p, t).

All Symbol arguments can be used to set default values, i.e. psym=[:K=>1, :p].

source
NetworkDynamics.EdgeModelMethod
EdgeModel(; kwargs...)

Build a EdgeModel according to the keyword arguments.

Main Arguments:

  • f=nothing: Dynamic function of the component. Can be nothing if dim is 0.
  • g: Output function of the component. Usefull helpers: AntiSymmetric, Symmetric, Fiducial, Directed and StateMask.
  • sym/dim: Symbolic names of the states. If dim is provided, sym is set automaticially.
  • outsym/outdim: Symbolic names of the outputs. If outdim is provided, outsym is set automaticially. In general, outsym for edges isa named tuple (; src, dst). However, depending on the g function, it might be enough to provide a single vector or even nothing (e.g. AntiSymmetric(StateMask(1:2))). See Building EdgeModels for examples.
  • psym/pdim=0: Symbolic names of the parameters. Ifpdimis provided,psym` is set automaticially.
  • mass_matrix=I: Mass matrix of component. Can be a vector v and is then interpreted as Diagonal(v).
  • name=dim>0 ? :EdgeM : :StaticEdgeM: Name of the component.

Optional Arguments:

  • insym/indim: Symbolic names of the inputs. If indim is provided, insym is set automaticially. For edges, insym is a named tuple (; src, dst). If give as vector tuple is created automaticially.
  • src/dst: Index or name of the vertices at src and dst end. Enables graphless constructor.
  • ff: FeedForwardType of component. Will be typically infered from g automaticially.
  • obssym/obsf: Define additional "observable" states.
  • symmetadata/metadata: Provide prefilled metadata dictionaries.
  • extin=nothing: Define "external" inputs for the model with Network indices, i.e. extin=[VIndex(7,:x), ..]. Those inputs will be provided as another input vector f(x, insrc, indst, extin, p, t) and g(ysrc, ydst, x, insrc, indst, extin, p, t).

All Symbol arguments can be used to set default values, i.e. psym=[:K=>1, :p].

source

Component Models with MTK

NetworkDynamics.VertexModelMethod
VertexModel(sys::ODESystem, inputs, outputs;
-            verbose=false, name=getname(sys), extin=nothing, ff_to_constraint=true, kwargs...)

Create a VertexModel object from a given ODESystem created with ModelingToolkit. You need to provide 2 lists of symbolic names (Symbol or Vector{Symbols}):

  • inputs: names of variables in you equation representing the aggregated edge states
  • outputs: names of variables in you equation representing the node output

Additional kw arguments:

  • name: Set name of the component model. Will be lifted from the ODESystem name.
  • extin=nothing: Provide external inputs as pairs, i.e. extin=[:extvar => VIndex(1, :a)] will bound the variable extvar(t) in the equations to the state a of the first vertex.
  • ff_to_constraint=true: Controlls, whether output transformations g which depend on inputs should be transformed into constraints. Defaults to true since ND.jl does not handle vertices with FF yet.
source
NetworkDynamics.EdgeModelMethod
EdgeModel(sys::ODESystem, srcin, srcout, dstin, dstout;
-          verbose=false, name=getname(sys), extin=nothing, ff_to_constraint=false, kwargs...)

Create a EdgeModel object from a given ODESystem created with ModelingToolkit. You need to provide 4 lists of symbolic names (Symbol or Vector{Symbols}):

  • srcin: names of variables in you equation representing the node state at the source
  • dstin: names of variables in you equation representing the node state at the destination
  • srcout: names of variables in you equation representing the output at the source
  • dstout: names of variables in you equation representing the output at the destination

Additional kw arguments:

  • name: Set name of the component model. Will be lifted from the ODESystem name.
  • extin=nothing: Provide external inputs as pairs, i.e. extin=[:extvar => VIndex(1, :a)] will bound the variable extvar(t) in the equations to the state a of the first vertex.
  • ff_to_constraint=false: Controlls, whether output transformations g which depend on inputs should be transformed into constraints.
source
NetworkDynamics.EdgeModelMethod
EdgeModel(sys::ODESystem, srcin, dstin, AntiSymmetric(dstout); kwargs...)

Create a EdgeModel object from a given ODESystem created with ModelingToolkit for single sided models.

Here you only need to provide one list of output symbols: dstout. To make it clear how to handle the single-sided output definiton, you musst wrap the symbol vector in

  • AntiSymmetric(dstout),
  • Symmetric(dstout), or
  • Directed(dstout).

Additional kwargs are the same as for the double-sided EdgeModel MTK constructor.

source

Output Function Helpers/Wrappers

NetworkDynamics.StateMaskType
StateMask(i::AbstractArray)
-StateMaks(i::Number)

A StateMask is a predefined output function. It can be used to define the output of a component model by picking from the internal state.

I.e. g=StateMask(2:3) in a vertex function will output the internal states 2 and 3. In many contexts, StateMasks can be constructed implicitly by just providing the indices, e.g. g=1:2.

For EdgeModel this needs to be combined with a Directed, Symmetric, AntiSymmetric or Fiducial coupling, e.g. g=Fiducial(1:2, 3:4) forwards states 1:2 to dst and states 3:4 to src.

source

Accessors for Component Properties

NetworkDynamics.outdimFunction
outdim(c::VertexModel)::Int
-outdim(c::EdgeModel)::@NamedTuple(src::Int, dst::Int)

Retrieve the output dimension of the component

source
NetworkDynamics.outsymFunction

outsym(c::VertexModel)::Vector{Symbol} outsym(c::EdgeModel)::@NamedTuple{src::Vector{Symbol}, dst::Vector{Symbol}}

Retrieve the output symbols of the component.

source
NetworkDynamics.insymFunction
insym(c::VertexModel)::Vector{Symbol}
-insym(c::EdgeModel)::@NamedTuple{src::Vector{Symbol}, dst::Vector{Symbol}}

Musst be called after hasinsym/hasindim returned true. Gives the insym vector(s). For vertex model just a single vector, for edges it returns a named tuple (; src, dst) with two symbol vectors.

source

FeedForwardType-Traits

Symbolic Indexing API

Network Parameter Object

NetworkDynamics.NWParameterType
NWParameter(nw_or_nw_wraper, pflat)

Indexable wrapper for flat parameter array pflat. Needs Network or wrapper of Network, e.g. ODEProblem.

p = NWParameter(nw)
+API · NetworkDynamics

API

The following functions are designed for public use.

Network Construction API

NetworkDynamics.NetworkType
Network([g,] vertexf, edgef; kwarg...)

Construct a Network object from a graph g and edge and component models vertexf and edgef.

Arguments:

  • g::AbstractGraph: The graph on which the network is defined. Optional, can be ommittet if all component models have a defined graphelement. See vidx and src/dst keywors for VertexModel and EdgeModel constructors respectively.

  • vertexm: A single VertexModel or a vector of VertexModel objects. The order of the vertex models must mirror the order of the vertices(g) iterator.

  • edgem: A single EdgeModel or a vector of EdgeModel objects. The order of the edge models must mirror the order of the edges(g) iterator.

Optional keyword arguments:

  • execution=SequentialExecution{true}(): Execution model of the network. E.g. SequentialExecution, KAExecution, PolyesterExecution or ThreadedExecution.
  • aggregator=execution isa SequentialExecution ? SequentialAggregator(+) : PolyesterAggregator(+): Aggregation function applied to the edge models. E.g. SequentialAggregator, PolyesterAggregator, ThreadedAggregator, SparseAggregator.
  • check_graphelement=true: Check if the graphelement metadata is consistent with the graph.
  • dealias=false Check if the components alias eachother and create copies if necessary. This is necessary if the same component model is referenced in multiple places in the Network but you want to dynamicially asign metadata, such as initialization information to specific instances.
  • verbose=false: Show additional information during construction.
source
Network(nw::Network; g, vertexm, edgem, kwargs...)

Rebuild the Network with same graph and vertex/edge models but possibly different kwargs.

source
NetworkDynamics.dimMethod
dim(nw::Network)

Returns the number of dynamic states in the network, corresponts to the length of the flat state vector.

source
NetworkDynamics.pdimMethod
pdim(nw::Network)

Returns the number of parameters in the network, corresponts to the length of the flat parameter vector.

source

Component Models

NetworkDynamics.VertexModelMethod
VertexModel(; kwargs...)

Build a VertexModel according to the keyword arguments.

Main Arguments:

  • f=nothing: Dynamic function of the component. Can be nothing if dim is 0.
  • g: Output function of the component. Usefull helpers: StateMask
  • sym/dim: Symbolic names of the states. If dim is provided, sym is set automaticially.
  • outsym/outdim: Symbolic names of the outputs. If outdim is provided, outsym is set automaticially. Can be infered automaticially if g isa StateMask.
  • psym/pdim=0: Symbolic names of the parameters. Ifpdimis provided,psym` is set automaticially.
  • mass_matrix=I: Mass matrix of component. Can be a vector v and is then interpreted as Diagonal(v).
  • name=dim>0 ? :VertexM : :StaticVertexM: Name of the component.

Optional Arguments:

  • insym/indim: Symbolic names of the inputs. If indim is provided, insym is set automaticially.
  • vidx: Index of the vertex in the graph, enables graphless constructor.
  • ff: FeedForwardType of component. Will be typically infered from g automaticially.
  • obssym/obsf: Define additional "observable" states.
  • symmetadata/metadata: Provide prefilled metadata dictionaries.
  • extin=nothing: Define "external" inputs for the model with Network indices, i.e. extin=[VIndex(7,:x), ..]. Those inputs will be provided as another input vector f(x, in, extin, p, t) and g(y, x, in, extin, p, t).

All Symbol arguments can be used to set default values, i.e. psym=[:K=>1, :p].

source
NetworkDynamics.EdgeModelMethod
EdgeModel(; kwargs...)

Build a EdgeModel according to the keyword arguments.

Main Arguments:

  • f=nothing: Dynamic function of the component. Can be nothing if dim is 0.
  • g: Output function of the component. Usefull helpers: AntiSymmetric, Symmetric, Fiducial, Directed and StateMask.
  • sym/dim: Symbolic names of the states. If dim is provided, sym is set automaticially.
  • outsym/outdim: Symbolic names of the outputs. If outdim is provided, outsym is set automaticially. In general, outsym for edges isa named tuple (; src, dst). However, depending on the g function, it might be enough to provide a single vector or even nothing (e.g. AntiSymmetric(StateMask(1:2))). See Building EdgeModels for examples.
  • psym/pdim=0: Symbolic names of the parameters. Ifpdimis provided,psym` is set automaticially.
  • mass_matrix=I: Mass matrix of component. Can be a vector v and is then interpreted as Diagonal(v).
  • name=dim>0 ? :EdgeM : :StaticEdgeM: Name of the component.

Optional Arguments:

  • insym/indim: Symbolic names of the inputs. If indim is provided, insym is set automaticially. For edges, insym is a named tuple (; src, dst). If give as vector tuple is created automaticially.
  • src/dst: Index or name of the vertices at src and dst end. Enables graphless constructor.
  • ff: FeedForwardType of component. Will be typically infered from g automaticially.
  • obssym/obsf: Define additional "observable" states.
  • symmetadata/metadata: Provide prefilled metadata dictionaries.
  • extin=nothing: Define "external" inputs for the model with Network indices, i.e. extin=[VIndex(7,:x), ..]. Those inputs will be provided as another input vector f(x, insrc, indst, extin, p, t) and g(ysrc, ydst, x, insrc, indst, extin, p, t).

All Symbol arguments can be used to set default values, i.e. psym=[:K=>1, :p].

source

Component Models with MTK

NetworkDynamics.VertexModelMethod
VertexModel(sys::ODESystem, inputs, outputs;
+            verbose=false, name=getname(sys), extin=nothing, ff_to_constraint=true, kwargs...)

Create a VertexModel object from a given ODESystem created with ModelingToolkit. You need to provide 2 lists of symbolic names (Symbol or Vector{Symbols}):

  • inputs: names of variables in you equation representing the aggregated edge states
  • outputs: names of variables in you equation representing the node output

Additional kw arguments:

  • name: Set name of the component model. Will be lifted from the ODESystem name.
  • extin=nothing: Provide external inputs as pairs, i.e. extin=[:extvar => VIndex(1, :a)] will bound the variable extvar(t) in the equations to the state a of the first vertex.
  • ff_to_constraint=true: Controlls, whether output transformations g which depend on inputs should be transformed into constraints. Defaults to true since ND.jl does not handle vertices with FF yet.
source
NetworkDynamics.EdgeModelMethod
EdgeModel(sys::ODESystem, srcin, srcout, dstin, dstout;
+          verbose=false, name=getname(sys), extin=nothing, ff_to_constraint=false, kwargs...)

Create a EdgeModel object from a given ODESystem created with ModelingToolkit. You need to provide 4 lists of symbolic names (Symbol or Vector{Symbols}):

  • srcin: names of variables in you equation representing the node state at the source
  • dstin: names of variables in you equation representing the node state at the destination
  • srcout: names of variables in you equation representing the output at the source
  • dstout: names of variables in you equation representing the output at the destination

Additional kw arguments:

  • name: Set name of the component model. Will be lifted from the ODESystem name.
  • extin=nothing: Provide external inputs as pairs, i.e. extin=[:extvar => VIndex(1, :a)] will bound the variable extvar(t) in the equations to the state a of the first vertex.
  • ff_to_constraint=false: Controlls, whether output transformations g which depend on inputs should be transformed into constraints.
source
NetworkDynamics.EdgeModelMethod
EdgeModel(sys::ODESystem, srcin, dstin, AntiSymmetric(dstout); kwargs...)

Create a EdgeModel object from a given ODESystem created with ModelingToolkit for single sided models.

Here you only need to provide one list of output symbols: dstout. To make it clear how to handle the single-sided output definiton, you musst wrap the symbol vector in

  • AntiSymmetric(dstout),
  • Symmetric(dstout), or
  • Directed(dstout).

Additional kwargs are the same as for the double-sided EdgeModel MTK constructor.

source

Output Function Helpers/Wrappers

NetworkDynamics.StateMaskType
StateMask(i::AbstractArray)
+StateMaks(i::Number)

A StateMask is a predefined output function. It can be used to define the output of a component model by picking from the internal state.

I.e. g=StateMask(2:3) in a vertex function will output the internal states 2 and 3. In many contexts, StateMasks can be constructed implicitly by just providing the indices, e.g. g=1:2.

For EdgeModel this needs to be combined with a Directed, Symmetric, AntiSymmetric or Fiducial coupling, e.g. g=Fiducial(1:2, 3:4) forwards states 1:2 to dst and states 3:4 to src.

source

Accessors for Component Properties

NetworkDynamics.outdimFunction
outdim(c::VertexModel)::Int
+outdim(c::EdgeModel)::@NamedTuple(src::Int, dst::Int)

Retrieve the output dimension of the component

source
NetworkDynamics.outsymFunction

outsym(c::VertexModel)::Vector{Symbol} outsym(c::EdgeModel)::@NamedTuple{src::Vector{Symbol}, dst::Vector{Symbol}}

Retrieve the output symbols of the component.

source
NetworkDynamics.insymFunction
insym(c::VertexModel)::Vector{Symbol}
+insym(c::EdgeModel)::@NamedTuple{src::Vector{Symbol}, dst::Vector{Symbol}}

Musst be called after hasinsym/hasindim returned true. Gives the insym vector(s). For vertex model just a single vector, for edges it returns a named tuple (; src, dst) with two symbol vectors.

source

FeedForwardType-Traits

Symbolic Indexing API

Network Parameter Object

NetworkDynamics.NWParameterType
NWParameter(nw_or_nw_wraper, pflat)

Indexable wrapper for flat parameter array pflat. Needs Network or wrapper of Network, e.g. ODEProblem.

p = NWParameter(nw)
 p.v[idx, :sym] # get parameter :sym of vertex idx
 p.e[idx, :sym] # get parameter :sym of edge idx
-p[s::Union{VPIndex, EPIndex}] # get parameter for specific index

Get flat array representation using pflat(p).

source
NetworkDynamics.NWParameterMethod
NWParameter(nw_or_nw_wraper;
-            ptype=Vector{Float64}, pfill=filltype(ptype), default=true)

Creates "empty" NWParameter object for the Network/Wrapper nw with flat type ptype. The array will be prefilled with pfill (defaults to NaN).

If default=true the default parameter values attached to the network components will be loaded.

source

Network State Object

NetworkDynamics.NWStateType
NWState(nw_or_nw_wrapper, uflat, [pflat], [t])

Indexable wrapper for flat state & parameter array. Needs Network or wrapper of Network, e.g. ODEProblem.

s = NWState(nw)
+p[s::Union{VPIndex, EPIndex}] # get parameter for specific index

Get flat array representation using pflat(p).

source
NetworkDynamics.NWParameterMethod
NWParameter(nw_or_nw_wraper;
+            ptype=Vector{Float64}, pfill=filltype(ptype), default=true)

Creates "empty" NWParameter object for the Network/Wrapper nw with flat type ptype. The array will be prefilled with pfill (defaults to NaN).

If default=true the default parameter values attached to the network components will be loaded.

source

Network State Object

NetworkDynamics.NWStateType
NWState(nw_or_nw_wrapper, uflat, [pflat], [t])

Indexable wrapper for flat state & parameter array. Needs Network or wrapper of Network, e.g. ODEProblem.

s = NWState(nw)
 s.v[idx, :sym] # get state :sym of vertex idx
 s.e[idx, :sym] # get state :sym of edge idx
 s.p.v[idx, :sym] # get parameter :sym of vertex idx
 s.p.e[idx, :sym] # get parameter :sym of edge idx
-s[s::Union{VIndex, EIndex, EPIndex, VPIndex}] # get parameter for specific index

Get flat array representation using uflat(s) and pflat(s).

source
NetworkDynamics.NWStateMethod
NWState(nw_or_nw_wrapper;
+s[s::Union{VIndex, EIndex, EPIndex, VPIndex}] # get parameter for specific index

Get flat array representation using uflat(s) and pflat(s).

source
NetworkDynamics.NWStateMethod
NWState(nw_or_nw_wrapper;
         utype=Vector{Float64}, ufill=filltype(utype),
-        ptype=Vector{Float64}, pfill=filltype(ptype), default=true)

Creates "empty" NWState object for the Network/Wrapper nw with flat types utype & ptype. The arrays will be prefilled with ufill and pfill respectively (defaults to NaN).

If default=true the default state & parameter values attached to the network components will be loaded.

source
NetworkDynamics.NWStateMethod
NWState(p::NWState; utype=typeof(uflat(s)), ptype=typeof(pflat(s)))

Create NWState based on other state object, just convert types.

source
NetworkDynamics.NWStateMethod
NWState(p::NWParameter; utype=Vector{Float64}, ufill=filltype(utype), default=true)

Create NWState based on existing NWParameter object.

source
NetworkDynamics.pflatFunction
pflat(p::NWParameter)
-pflat(s::NWState)

Retrieve the wrapped flat array representation of the parameters.

source

Symbolic Indices

NetworkDynamics.VIndexType
VIndex{C,S} <: SymbolicStateIndex{C,S}
+        ptype=Vector{Float64}, pfill=filltype(ptype), default=true)

Creates "empty" NWState object for the Network/Wrapper nw with flat types utype & ptype. The arrays will be prefilled with ufill and pfill respectively (defaults to NaN).

If default=true the default state & parameter values attached to the network components will be loaded.

source
NetworkDynamics.NWStateMethod
NWState(p::NWState; utype=typeof(uflat(s)), ptype=typeof(pflat(s)))

Create NWState based on other state object, just convert types.

source
NetworkDynamics.NWStateMethod
NWState(p::NWParameter; utype=Vector{Float64}, ufill=filltype(utype), default=true)

Create NWState based on existing NWParameter object.

source
NetworkDynamics.pflatFunction
pflat(p::NWParameter)
+pflat(s::NWState)

Retrieve the wrapped flat array representation of the parameters.

source

Symbolic Indices

NetworkDynamics.VIndexType
VIndex{C,S} <: SymbolicStateIndex{C,S}
 idx = VIndex(comp, sub)

A symbolic index for a vertex state variable.

  • comp: the component index, either int or a collection of ints
  • sub: the subindex, either int, symbol or a collection of those.
VIndex(1, :P)      # vertex 1, variable :P
 VIndex(1:5, 1)     # first state of vertices 1 to 5
-VIndex(7, (:x,:y)) # states :x and :y of vertex 7

Can be used to index into objects supporting the SymbolicIndexingInterface, e.g. NWState, NWParameter or ODESolution.

See also: EIndex, VPIndex, EPIndex

source
NetworkDynamics.EIndexType
EIndex{C,S} <: SymbolicStateIndex{C,S}
 idx = EIndex(comp, sub)

A symbolic index for an edge state variable.

  • comp: the component index, either int or a collection of ints
  • sub: the subindex, either int, symbol or a collection of those.
EIndex(1, :P)      # edge 1, variable :P
 EIndex(1:5, 1)     # first state of edges 1 to 5
-EIndex(7, (:x,:y)) # states :x and :y of edge 7

Can be used to index into objects supporting the SymbolicIndexingInterface, e.g. NWState, NWParameter or ODESolution.

See also: VIndex, VPIndex, EPIndex

source
NetworkDynamics.VPIndexType
VPIndex{C,S} <: SymbolicStateIndex{C,S}
-idx = VPIndex(comp, sub)

A symbolic index into the parameter a vertex:

  • comp: the component index, either int or a collection of ints
  • sub: the subindex, either int, symbol or a collection of those.

Can be used to index into objects supporting the SymbolicIndexingInterface, e.g. NWParameter or ODEProblem.

See also: EPIndex, VIndex, EIndex

source
NetworkDynamics.EPIndexType
EPIndex{C,S} <: SymbolicStateIndex{C,S}
-idx = VEIndex(comp, sub)

A symbolic index into the parameter a vertex:

  • comp: the component index, either int or a collection of ints
  • sub: the subindex, either int, symbol or a collection of those.

Can be used to index into objects supporting the SymbolicIndexingInterface, e.g. NWParameter or ODEProblem.

See also: VPIndex, VIndex, EIndex

source

Index generators

NetworkDynamics.vidxsFunction
vidxs([inpr], components=:, variables=:) :: Vector{VIndex}

Generate vector of symbolic indexes for vertices.

  • inpr: Only needed for name matching or : access. Can be Network, sol, prob, ...
  • components: Number/Vector, :, Symbol (name matches), String/Regex (name contains)
  • variables: Symbol/Number/Vector, :, String/Regex (all sym containing)

Examples:

vidxs(nw)                 # all vertex state indices
+EIndex(7, (:x,:y)) # states :x and :y of edge 7

Can be used to index into objects supporting the SymbolicIndexingInterface, e.g. NWState, NWParameter or ODESolution.

See also: VIndex, VPIndex, EPIndex

source
NetworkDynamics.VPIndexType
VPIndex{C,S} <: SymbolicStateIndex{C,S}
+idx = VPIndex(comp, sub)

A symbolic index into the parameter a vertex:

  • comp: the component index, either int or a collection of ints
  • sub: the subindex, either int, symbol or a collection of those.

Can be used to index into objects supporting the SymbolicIndexingInterface, e.g. NWParameter or ODEProblem.

See also: EPIndex, VIndex, EIndex

source
NetworkDynamics.EPIndexType
EPIndex{C,S} <: SymbolicStateIndex{C,S}
+idx = VEIndex(comp, sub)

A symbolic index into the parameter a vertex:

  • comp: the component index, either int or a collection of ints
  • sub: the subindex, either int, symbol or a collection of those.

Can be used to index into objects supporting the SymbolicIndexingInterface, e.g. NWParameter or ODEProblem.

See also: VPIndex, VIndex, EIndex

source

Index generators

NetworkDynamics.vidxsFunction
vidxs([inpr], components=:, variables=:) :: Vector{VIndex}

Generate vector of symbolic indexes for vertices.

  • inpr: Only needed for name matching or : access. Can be Network, sol, prob, ...
  • components: Number/Vector, :, Symbol (name matches), String/Regex (name contains)
  • variables: Symbol/Number/Vector, :, String/Regex (all sym containing)

Examples:

vidxs(nw)                 # all vertex state indices
 vidxs(1:2, :u)            # [VIndex(1, :u), VIndex(2, :u)]
 vidxs(nw, :, [:u, :v])    # [VIndex(i, :u), VIndex(i, :v) for i in 1:nv(nw)]
-vidxs(nw, "ODEVertex", :) # all symbols of all vertices with name containing "ODEVertex"
source
NetworkDynamics.eidxsFunction
vidxs([inpr], components=:, variables=:) :: Vector{EIndex}

Generate vector of symbolic indexes for edges.

  • inpr: Only needed for name matching or : access. Can be Network, sol, prob, ...
  • components: Number/Vector, :, Symbol (name matches), String/Regex (name contains)
  • variables: Symbol/Number/Vector, :, String/Regex (all sym containing)

Examples:

eidxs(nw)                # all edge state indices
+vidxs(nw, "ODEVertex", :) # all symbols of all vertices with name containing "ODEVertex"
source
NetworkDynamics.eidxsFunction
vidxs([inpr], components=:, variables=:) :: Vector{EIndex}

Generate vector of symbolic indexes for edges.

  • inpr: Only needed for name matching or : access. Can be Network, sol, prob, ...
  • components: Number/Vector, :, Symbol (name matches), String/Regex (name contains)
  • variables: Symbol/Number/Vector, :, String/Regex (all sym containing)

Examples:

eidxs(nw)                # all edge state indices
 eidxs(1:2, :u)           # [EIndex(1, :u), EIndex(2, :u)]
 eidxs(nw, :, [:u, :v])   # [EIndex(i, :u), EIndex(i, :v) for i in 1:ne(nw)]
-eidxs(nw, "FlowEdge", :) # all symbols of all edges with name containing "FlowEdge"
source
NetworkDynamics.vpidxsFunction
vpidxs([inpr], components=:, variables=:) :: Vector{VPIndex}

Generate vector of symbolic indexes for parameters. See vidxs for more information.

source
NetworkDynamics.epidxsFunction
epidxs([inpr], components=:, variables=:) :: Vector{EPIndex}

Generate vector of symbolic indexes for parameters. See eidxs for more information.

source

Metadata API

Component Metadata API

NetworkDynamics.get_graphelementFunction
get_graphelement(c::EdgeModel)::@NamedTuple{src::T, dst::T}
-get_graphelement(c::VertexModel)::Int

Retrieves the graphelement metadata for the component model. For edges this returns a named tupe (;src, dst) where both are either integers (vertex index) or symbols (vertex name).

source
NetworkDynamics.set_graphelement!Function
set_graphelement!(c::EdgeModel, src, dst)
-set_graphelement!(c::VertexModel, vidx)

Sets the graphelement metadata for the edge model. For edges this takes two arguments src and dst which are either integer (vertex index) or symbol (vertex name). For vertices it takes a single integer vidx.

source

Per-Symbol Metadata API

NetworkDynamics.set_metadata!Method
set_metadata!(c::ComponentModel, sym::Symbol, key::Symbol, value)
-set_metadata!(c::ComponentModel, sym::Symbol, pair)

Sets the metadata key for symbol sym to value.

source

Initialization

NetworkDynamics.find_fixpointFunction
find_fixpoint(nw::Network, [x0::NWState=NWState(nw)], [p::NWParameter=x0.p]; kwargs...)
+eidxs(nw, "FlowEdge", :) # all symbols of all edges with name containing "FlowEdge"
source
NetworkDynamics.vpidxsFunction
vpidxs([inpr], components=:, variables=:) :: Vector{VPIndex}

Generate vector of symbolic indexes for parameters. See vidxs for more information.

source
NetworkDynamics.epidxsFunction
epidxs([inpr], components=:, variables=:) :: Vector{EPIndex}

Generate vector of symbolic indexes for parameters. See eidxs for more information.

source

Metadata API

Component Metadata API

NetworkDynamics.get_graphelementFunction
get_graphelement(c::EdgeModel)::@NamedTuple{src::T, dst::T}
+get_graphelement(c::VertexModel)::Int

Retrieves the graphelement metadata for the component model. For edges this returns a named tupe (;src, dst) where both are either integers (vertex index) or symbols (vertex name).

source
NetworkDynamics.set_graphelement!Function
set_graphelement!(c::EdgeModel, src, dst)
+set_graphelement!(c::VertexModel, vidx)

Sets the graphelement metadata for the edge model. For edges this takes two arguments src and dst which are either integer (vertex index) or symbol (vertex name). For vertices it takes a single integer vidx.

source

Per-Symbol Metadata API

NetworkDynamics.set_metadata!Method
set_metadata!(c::ComponentModel, sym::Symbol, key::Symbol, value)
+set_metadata!(c::ComponentModel, sym::Symbol, pair)

Sets the metadata key for symbol sym to value.

source

Initialization

NetworkDynamics.find_fixpointFunction
find_fixpoint(nw::Network, [x0::NWState=NWState(nw)], [p::NWParameter=x0.p]; kwargs...)
 find_fixpoint(nw::Network, x0::AbstractVector, p::AbstractVector; kwargs...)
-find_fixpoint(nw::Network, x0::AbstractVector; kwargs...)

Convenience wrapper around SteadyStateProblem from SciML-ecosystem. Constructs and solves the steady state problem, returns found value wrapped as NWState.

source
NetworkDynamics.initialize_component!Function
initialize_component!(cf::ComponentModel; verbose=true, kwargs...)

Initialize a ComponentModel by solving the corresponding NonlinearLeastSquaresProblem. During initialization, everyting which has a default value (see Metadata) is considered "fixed". All other variables are considered "free" and are solved for. The initial guess for each variable depends on the guess value in the Metadata.

The result is stored in the ComponentModel itself. The values of the free variables are stored in the metadata field init.

The kwargs are passed to the nonlinear solver.

source
NetworkDynamics.init_residualFunction
init_residual(cf::T; t=NaN, recalc=false)

Calculates the residual |du| for the given component model for the values provided via default and init Metadata.

If recalc=false just return the residual determined in the actual initialization process.

See also initialize_component!.

source

Execution Types

NetworkDynamics.ExecutionStyleType
abstract type ExecutionStyle{buffered::Bool} end

Abstract type for execution style. The coreloop dispatches based on the Execution style stored in the network object.

  • buffered=true means that the edge input es explicitly gathered, i.e. the vertex outputs in the output buffer will be copied into a dedicated input buffer for the edges.
  • buffered=false means, that the edge inputs are not explicitly gathered, but the corloop will perform a redirected lookup into the output buffer.
source

Aggregators

NetworkDynamics.AggregatorType
abstract type Aggregator end

Abstract sypertype for aggregators. Aggregators operate on the output buffer of all components and fill the aggregation buffer with the aggregatated edge values per vertex.

All aggregators have the constructor

Aggegator(aggfun)

for example

SequentialAggreator(+)
source

Utils

NetworkDynamics.save_parameters!Function
save_parameters!(integrator::SciMLBase.DEIntegrator)

Save the current parameter values in the integrator. Call this function inside callbacks if the parameter values have changed. This will store a timeseries of said parameters in the solution object, thus alowing us to recosntruct observables which depend on time-dependet variables.

source
NetworkDynamics.ff_to_constraintFunction
ff_to_constraint(v::VertexModel)

Takes VertexModel v with feed forward and turns all algebraic output states into internal states by defining algebraic constraints contraints 0 = out - g(...). The new output function is just a StateMask into the extended internal state vector.

Returns the transformed VertexModel.

source
Base.copyMethod
copy(c::NetworkDynamics.ComponentModel)

Shallow copy of the component model. Creates a deepcopy of metadata and symmetadata but references the same objects everywhere else.

source
+find_fixpoint(nw::Network, x0::AbstractVector; kwargs...)

Convenience wrapper around SteadyStateProblem from SciML-ecosystem. Constructs and solves the steady state problem, returns found value wrapped as NWState.

source
NetworkDynamics.initialize_component!Function
initialize_component!(cf::ComponentModel; verbose=true, kwargs...)

Initialize a ComponentModel by solving the corresponding NonlinearLeastSquaresProblem. During initialization, everyting which has a default value (see Metadata) is considered "fixed". All other variables are considered "free" and are solved for. The initial guess for each variable depends on the guess value in the Metadata.

The result is stored in the ComponentModel itself. The values of the free variables are stored in the metadata field init.

The kwargs are passed to the nonlinear solver.

source
NetworkDynamics.init_residualFunction
init_residual(cf::T; t=NaN, recalc=false)

Calculates the residual |du| for the given component model for the values provided via default and init Metadata.

If recalc=false just return the residual determined in the actual initialization process.

See also initialize_component!.

source

Execution Types

NetworkDynamics.ExecutionStyleType
abstract type ExecutionStyle{buffered::Bool} end

Abstract type for execution style. The coreloop dispatches based on the Execution style stored in the network object.

  • buffered=true means that the edge input es explicitly gathered, i.e. the vertex outputs in the output buffer will be copied into a dedicated input buffer for the edges.
  • buffered=false means, that the edge inputs are not explicitly gathered, but the corloop will perform a redirected lookup into the output buffer.
source

Aggregators

NetworkDynamics.AggregatorType
abstract type Aggregator end

Abstract sypertype for aggregators. Aggregators operate on the output buffer of all components and fill the aggregation buffer with the aggregatated edge values per vertex.

All aggregators have the constructor

Aggegator(aggfun)

for example

SequentialAggreator(+)
source

Utils

NetworkDynamics.save_parameters!Function
save_parameters!(integrator::SciMLBase.DEIntegrator)

Save the current parameter values in the integrator. Call this function inside callbacks if the parameter values have changed. This will store a timeseries of said parameters in the solution object, thus alowing us to recosntruct observables which depend on time-dependet variables.

source
NetworkDynamics.ff_to_constraintFunction
ff_to_constraint(v::VertexModel)

Takes VertexModel v with feed forward and turns all algebraic output states into internal states by defining algebraic constraints contraints 0 = out - g(...). The new output function is just a StateMask into the extended internal state vector.

Returns the transformed VertexModel.

source
Base.copyMethod
copy(c::NetworkDynamics.ComponentModel)

Shallow copy of the component model. Creates a deepcopy of metadata and symmetadata but references the same objects everywhere else.

source
diff --git a/previews/PR188/external_inputs/index.html b/previews/PR188/external_inputs/index.html index 49facf75..7267552e 100644 --- a/previews/PR188/external_inputs/index.html +++ b/previews/PR188/external_inputs/index.html @@ -145,4 +145,4 @@ lines!(ax2, sol, idxs=VIndex(:source, :i_source), label="source current", color=Cycled(2)); axislegend(ax2); fig -endExample block output

Using MTK for modeling, we can also inspect the currents i_load and i_source the MTK interface preserves the Observables.

+endExample block output

Using MTK for modeling, we can also inspect the currents i_load and i_source the MTK interface preserves the Observables.

diff --git a/previews/PR188/generated/cascading_failure/bd577d64.svg b/previews/PR188/generated/cascading_failure/5cce10bb.svg similarity index 95% rename from previews/PR188/generated/cascading_failure/bd577d64.svg rename to previews/PR188/generated/cascading_failure/5cce10bb.svg index 5ca2625c..206dbbc0 100644 --- a/previews/PR188/generated/cascading_failure/bd577d64.svg +++ b/previews/PR188/generated/cascading_failure/5cce10bb.svg @@ -1,62 +1,62 @@ - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/previews/PR188/generated/cascading_failure/index.html b/previews/PR188/generated/cascading_failure/index.html index e4b75bb1..5fbdea3c 100644 --- a/previews/PR188/generated/cascading_failure/index.html +++ b/previews/PR188/generated/cascading_failure/index.html @@ -70,4 +70,4 @@ Line 4 tripped at t=2.502523192233235 Line 1 tripped at t=3.1947647115093654 Line 3 tripped at t=3.3380530127462587 -Line 2 tripped at t=3.4042696241577888

Through the magic of symbolic indexing we can plot the power flows on all lines:

plot(sol; idxs=eidxs(sol,:,:P))
Example block output

This page was generated using Literate.jl.

+Line 2 tripped at t=3.4042696241577888

Through the magic of symbolic indexing we can plot the power flows on all lines:

plot(sol; idxs=eidxs(sol,:,:P))
Example block output

This page was generated using Literate.jl.

diff --git a/previews/PR188/generated/directed_and_weighted_graphs/a4591bbb.svg b/previews/PR188/generated/directed_and_weighted_graphs/9e61bf58.svg similarity index 99% rename from previews/PR188/generated/directed_and_weighted_graphs/a4591bbb.svg rename to previews/PR188/generated/directed_and_weighted_graphs/9e61bf58.svg index 75430331..d0741888 100644 --- a/previews/PR188/generated/directed_and_weighted_graphs/a4591bbb.svg +++ b/previews/PR188/generated/directed_and_weighted_graphs/9e61bf58.svg @@ -1,132 +1,132 @@ - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/previews/PR188/generated/directed_and_weighted_graphs/index.html b/previews/PR188/generated/directed_and_weighted_graphs/index.html index cd31fbfb..d0d35b06 100644 --- a/previews/PR188/generated/directed_and_weighted_graphs/index.html +++ b/previews/PR188/generated/directed_and_weighted_graphs/index.html @@ -45,4 +45,4 @@ Edge-Aggregation using SequentialAggregator(+)

Since this system is a directed one with thus directed edges, the keyword argument coupling is used to set the coupling of the edges to Directed().

Parameter handling

Some of the parameters have been declared with default values. Those default values will be used when creating the NWParameter object. We can use getindex on the parameter objects to set the missing weight values.

p = NWParameter(fhn_network!)
 p.e[1:ne(g_directed), :weight] = edge_weights

The initial conditions could be created similarly to the parameters as an indexable NWState obejct. Since we chose a random initial condition we initialize the flat array directly:

x0 = randn(StableRNG(42), dim(fhn_network!)) * 5

Solving the system

Now we are ready to create an ODEProblem. Since for some choices of parameters the FitzHugh-Nagumo model is stiff (i.e. numerically unstable), we use a solver with automated stiffness detection. Such a solver switches to a more stable solver only when the solution enters a region of phase space where the problem is numerically unstable. In this case we use Tsit5 and switch to TRBDF2 when necessary. AutoTsit5 is the switching version of the Tsit5 algorithm.

Not that we call pflat on the NWParameter object to get the flat array of parameters.

tspan = (0.0, 200.0)
 prob  = ODEProblem(fhn_network!, x0, tspan, pflat(p))
-sol = solve(prob, AutoTsit5(TRBDF2()));

Plotting

The plot of the excitatory variables shows that they synchronize for this choice of parameters.

plot(sol; idxs=vidxs(fhn_network!, :, :u), legend=false, ylim=(-5, 5), fmt=:png)
Example block output

This page was generated using Literate.jl.

+sol = solve(prob, AutoTsit5(TRBDF2()));

Plotting

The plot of the excitatory variables shows that they synchronize for this choice of parameters.

plot(sol; idxs=vidxs(fhn_network!, :, :u), legend=false, ylim=(-5, 5), fmt=:png)
Example block output

This page was generated using Literate.jl.

diff --git a/previews/PR188/generated/gas_network/index.html b/previews/PR188/generated/gas_network/index.html index bcf49b4c..5f7db3c7 100644 --- a/previews/PR188/generated/gas_network/index.html +++ b/previews/PR188/generated/gas_network/index.html @@ -221,4 +221,4 @@ end axislegend(ax, position=:rb) _fig -endExample block output

This page was generated using Literate.jl.

+endExample block output

This page was generated using Literate.jl.

diff --git a/previews/PR188/generated/getting_started_with_network_dynamics/0240d801.svg b/previews/PR188/generated/getting_started_with_network_dynamics/0240d801.svg deleted file mode 100644 index 867d7eb7..00000000 --- a/previews/PR188/generated/getting_started_with_network_dynamics/0240d801.svg +++ /dev/null @@ -1,60 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/previews/PR188/generated/getting_started_with_network_dynamics/07db374a.svg b/previews/PR188/generated/getting_started_with_network_dynamics/07db374a.svg new file mode 100644 index 00000000..d1cd3d0d --- /dev/null +++ b/previews/PR188/generated/getting_started_with_network_dynamics/07db374a.svg @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/previews/PR188/generated/getting_started_with_network_dynamics/8fadb2b3.svg b/previews/PR188/generated/getting_started_with_network_dynamics/8fadb2b3.svg deleted file mode 100644 index e610c31f..00000000 --- a/previews/PR188/generated/getting_started_with_network_dynamics/8fadb2b3.svg +++ /dev/null @@ -1,88 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/previews/PR188/generated/getting_started_with_network_dynamics/a1782553.svg b/previews/PR188/generated/getting_started_with_network_dynamics/a1782553.svg deleted file mode 100644 index b2f691e3..00000000 --- a/previews/PR188/generated/getting_started_with_network_dynamics/a1782553.svg +++ /dev/null @@ -1,82 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/previews/PR188/generated/getting_started_with_network_dynamics/b68ddef7.svg b/previews/PR188/generated/getting_started_with_network_dynamics/b68ddef7.svg new file mode 100644 index 00000000..9d2488eb --- /dev/null +++ b/previews/PR188/generated/getting_started_with_network_dynamics/b68ddef7.svg @@ -0,0 +1,88 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/previews/PR188/generated/getting_started_with_network_dynamics/d9376f93.svg b/previews/PR188/generated/getting_started_with_network_dynamics/d9376f93.svg new file mode 100644 index 00000000..61a095d7 --- /dev/null +++ b/previews/PR188/generated/getting_started_with_network_dynamics/d9376f93.svg @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/previews/PR188/generated/getting_started_with_network_dynamics/index.html b/previews/PR188/generated/getting_started_with_network_dynamics/index.html index 2f67071d..521c0b86 100644 --- a/previews/PR188/generated/getting_started_with_network_dynamics/index.html +++ b/previews/PR188/generated/getting_started_with_network_dynamics/index.html @@ -29,7 +29,7 @@ Edge-Aggregation using SequentialAggregator(+)

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)
 x0 = randn(rng, N) # random initial conditions
 ode_prob = ODEProblem(nd, x0, (0.0, 2.0))
-sol = solve(ode_prob, Tsit5());

We are solving the diffusion problem on the time interval $[0, 2]$ with the Tsit5() algorithm, which is recommended by the authors of DifferentialEquations.jl for most non-stiff problems.

plot(sol; idxs=vidxs(nd, :, :), fmt=:png)
Example block output

The plotting is straightforward. The idxs keyword allows us to pass a list of indices. Indices can be also "symbolic" indices which specify components and their symbols directly. For example idxs = VIndex(1, :v) acesses state :v of vertex 1. See Symbolic Indexing for more details.

In oder to collect multiple indices we can use the helper function vidxs and eidxs, which help to collect all symbolic indices matching a certain criteria.

Two Dimensional Extension

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 VertexModel.

N = 10 # number of nodes
+sol = solve(ode_prob, Tsit5());

We are solving the diffusion problem on the time interval $[0, 2]$ with the Tsit5() algorithm, which is recommended by the authors of DifferentialEquations.jl for most non-stiff problems.

plot(sol; idxs=vidxs(nd, :, :), fmt=:png)
Example block output

The plotting is straightforward. The idxs keyword allows us to pass a list of indices. Indices can be also "symbolic" indices which specify components and their symbols directly. For example idxs = VIndex(1, :v) acesses state :v of vertex 1. See Symbolic Indexing for more details.

In oder to collect multiple indices we can use the helper function vidxs and eidxs, which help to collect all symbolic indices matching a certain criteria.

Two Dimensional Extension

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 VertexModel.

N = 10 # number of nodes
 k = 4  # average degree
 g = barabasi_albert(N, k) # a little more exciting than a bare random graph
 
@@ -40,4 +40,4 @@
 
 x0_2 = vec(transpose([randn(rng, N) .^ 2 randn(rng, N)])) # x ~ N(0,1)^2; ϕ ~ N(0,1)
 ode_prob_2 = ODEProblem(nd_2, x0_2, (0.0, 3.0))
-sol_2 = solve(ode_prob_2, Tsit5());

Try plotting the variables ϕ_i yourself. [To write ϕ type \phi and press TAB]

plot(sol_2; idxs=vidxs(nd_2, :, :x), fmt=:png)
Example block output

Using the eidxs helper function we can also plot the flow variables

plot(sol_2; idxs=eidxs(nd_2, :, :flow_x), fmt=:png)
Example block output

Appendix: The network Laplacian $L$

The diffusion equation on a network can be rewritten as

\[\dot v_i = \sum_{j=1}^N A_{ji} v_j - d_i v_i = e_i^T A v - d_i v_i\]

where $d_i$ is the degree of node $i$ and $e_i^T$ is the $i$-th standard basis vector. Introducing the diagonal matrix $D$ that has the degree of node $i$ in its $i$-th row and the Laplacian matrix $L = D - A$ we arrive at

\[\dot v = e_i^T(A - D) v\]

and finally

\[\dot v = - L v\]

This is a linear system of ODEs and its solution is a matrix exponential. To study the asymptotic behaviour of the system it suffices to analyze the eigenspectrum of $L$. For this reason $L$ is an important construction in network science.


This page was generated using Literate.jl.

+sol_2 = solve(ode_prob_2, Tsit5());

Try plotting the variables ϕ_i yourself. [To write ϕ type \phi and press TAB]

plot(sol_2; idxs=vidxs(nd_2, :, :x), fmt=:png)
Example block output

Using the eidxs helper function we can also plot the flow variables

plot(sol_2; idxs=eidxs(nd_2, :, :flow_x), fmt=:png)
Example block output

Appendix: The network Laplacian $L$

The diffusion equation on a network can be rewritten as

\[\dot v_i = \sum_{j=1}^N A_{ji} v_j - d_i v_i = e_i^T A v - d_i v_i\]

where $d_i$ is the degree of node $i$ and $e_i^T$ is the $i$-th standard basis vector. Introducing the diagonal matrix $D$ that has the degree of node $i$ in its $i$-th row and the Laplacian matrix $L = D - A$ we arrive at

\[\dot v = e_i^T(A - D) v\]

and finally

\[\dot v = - L v\]

This is a linear system of ODEs and its solution is a matrix exponential. To study the asymptotic behaviour of the system it suffices to analyze the eigenspectrum of $L$. For this reason $L$ is an important construction in network science.


This page was generated using Literate.jl.

diff --git a/previews/PR188/generated/heterogeneous_system/cbd78674.svg b/previews/PR188/generated/heterogeneous_system/287ae6d5.svg similarity index 96% rename from previews/PR188/generated/heterogeneous_system/cbd78674.svg rename to previews/PR188/generated/heterogeneous_system/287ae6d5.svg index 8632f6ba..dd6a991c 100644 --- a/previews/PR188/generated/heterogeneous_system/cbd78674.svg +++ b/previews/PR188/generated/heterogeneous_system/287ae6d5.svg @@ -1,66 +1,66 @@ - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/previews/PR188/generated/heterogeneous_system/487a627d.svg b/previews/PR188/generated/heterogeneous_system/8a6ee668.svg similarity index 95% rename from previews/PR188/generated/heterogeneous_system/487a627d.svg rename to previews/PR188/generated/heterogeneous_system/8a6ee668.svg index c134b267..719f93c5 100644 --- a/previews/PR188/generated/heterogeneous_system/487a627d.svg +++ b/previews/PR188/generated/heterogeneous_system/8a6ee668.svg @@ -1,62 +1,62 @@ - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/previews/PR188/generated/heterogeneous_system/aea1a55c.svg b/previews/PR188/generated/heterogeneous_system/dcf14933.svg similarity index 95% rename from previews/PR188/generated/heterogeneous_system/aea1a55c.svg rename to previews/PR188/generated/heterogeneous_system/dcf14933.svg index 5b8fad54..16152a4c 100644 --- a/previews/PR188/generated/heterogeneous_system/aea1a55c.svg +++ b/previews/PR188/generated/heterogeneous_system/dcf14933.svg @@ -1,62 +1,62 @@ - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/previews/PR188/generated/heterogeneous_system/index.html b/previews/PR188/generated/heterogeneous_system/index.html index e7e74db4..5e04ff5f 100644 --- a/previews/PR188/generated/heterogeneous_system/index.html +++ b/previews/PR188/generated/heterogeneous_system/index.html @@ -44,7 +44,7 @@ tspan = (0.0, 10.0) prob = ODEProblem(nw, x0, tspan, pflat(p)) sol = solve(prob, Tsit5()) -plot(sol; ylabel="θ", fmt=:png)Example block output

Heterogeneous dynamics

Two paradigmatic modifications of the node model above are static nodes and nodes with inertia. A static node has no internal states and instead fixes the variable at a constant value.

function static_g(out, u, p, t)
+plot(sol; ylabel="θ", fmt=:png)
Example block output

Heterogeneous dynamics

Two paradigmatic modifications of the node model above are static nodes and nodes with inertia. A static node has no internal states and instead fixes the variable at a constant value.

function static_g(out, u, p, t)
     out[1] = p[1]
     nothing
 end
@@ -82,7 +82,7 @@
  p = NWParameter([-0.4375, NaN, NaN, NaN, NaN, NaN, NaN, NaN, 3.0, 3.0, 3.0, 3.0, 3.0, 3.0, 3.0, 3.0])
  t = nothing

The node with inertia is two-dimensional, hence we need to specify two initial conditions. For the first dimension we keep the initial conditions from above and insert! another one into x0 at the correct index.

For the θ states we will use the same initial conditins as before:

state.v[2:8,:θ] = x0[2:8]

We're still missing one initial condition: the second variable ω of the 5th vertex.

state.v[5,:ω] = 5

The NWState object also contains a parameter object accessible via state.p. The edge parameters are already filled with default values. The vertex parameters can be copied from our old parmeter object p.

state.p.v[2:8, :ω0] = p.v[2:8, :ω0]

For the problem construction, we need to convert the nested stuctures to flat arrays using the uflat and pflat methods.

prob_hetero = ODEProblem(nw_hetero!, uflat(state), tspan, pflat(state))
 sol_hetero = solve(prob_hetero, Tsit5());
-plot(sol_hetero)
Example block output

For clarity we plot only the variables referring to the oscillator's angle θ and color them according to their type.

colors = map(vertex_array) do vertexf
+plot(sol_hetero)
Example block output

For clarity we plot only the variables referring to the oscillator's angle θ and color them according to their type.

colors = map(vertex_array) do vertexf
     if vertexf.name == :kuramoto
         colorant"lightseagreen"
     elseif vertexf.name == :static
@@ -92,4 +92,4 @@
     end
 end
 
-plot(sol_hetero; ylabel="θ", idxs=vidxs(1:8,:θ), lc=colors', fmt=:png)
Example block output

This page was generated using Literate.jl.

+plot(sol_hetero; ylabel="θ", idxs=vidxs(1:8,:θ), lc=colors', fmt=:png)Example block output

This page was generated using Literate.jl.

diff --git a/previews/PR188/generated/stress_on_truss/index.html b/previews/PR188/generated/stress_on_truss/index.html index 3387d6c6..427da099 100644 --- a/previews/PR188/generated/stress_on_truss/index.html +++ b/previews/PR188/generated/stress_on_truss/index.html @@ -129,4 +129,4 @@ p.edge_color[] = load p.elabels = [@sprintf("%.0f", l) for l in load] fig -end
"truss.mp4"

This page was generated using Literate.jl.

+end
"truss.mp4"

This page was generated using Literate.jl.

diff --git a/previews/PR188/index.html b/previews/PR188/index.html index eb11a6ee..9ea54811 100644 --- a/previews/PR188/index.html +++ b/previews/PR188/index.html @@ -11,7 +11,7 @@ [b964fa9f] LaTeXStrings v1.4.0 [b20c7882] LinearInterpolations v0.1.4 [98b081ad] Literate v2.20.1 - [961ee093] ModelingToolkit v9.54.0 + [961ee093] ModelingToolkit v9.55.0 [22e9dc34] NetworkDynamics v0.9.3 `~/work/NetworkDynamics.jl/NetworkDynamics.jl` [127b3ac7] OrdinaryDiffEqNonlinearSolve v1.3.0 [43230ef6] OrdinaryDiffEqRosenbrock v1.3.1 @@ -19,7 +19,7 @@ [b1df2697] OrdinaryDiffEqTsit5 v1.1.0 [91a5bcdd] Plots v1.40.9 [1bc83da4] SafeTestsets v0.1.0 - [0bca4576] SciMLBase v2.65.1 + [0bca4576] SciMLBase v2.66.0 [47aef6b3] SimpleWeightedGraphs v1.4.0 [860ef19b] StableRNGs v1.0.2 [90137ffa] StaticArrays v1.9.8 @@ -52,7 +52,7 @@ [dce04be8] ArgCheck v2.4.0 [ec485272] ArnoldiMethod v0.4.0 [4fba245c] ArrayInterface v7.17.1 - [4c555306] ArrayLayouts v1.10.4 + [4c555306] ArrayLayouts v1.11.0 [a9b6321e] Atomix v0.1.0 [67c07d97] Automa v1.1.0 [13072b0f] AxisAlgorithms v1.1.0 @@ -100,7 +100,7 @@ [77a26b50] DiffEqNoiseProcess v5.24.0 [163ba53b] DiffResults v1.1.0 [b552c78f] DiffRules v1.15.1 - [a0c0ee7d] DifferentiationInterface v0.6.24 + [a0c0ee7d] DifferentiationInterface v0.6.25 [8d63f2c5] DispatchDoctor v0.4.17 [b4f34e82] Distances v0.10.12 [31c24e10] Distributions v0.25.113 @@ -211,7 +211,7 @@ [442fdcdd] Measures v0.3.2 [e1d29d7a] Missings v1.2.0 [2a8e4939] Mixers v0.1.2 - [961ee093] ModelingToolkit v9.54.0 + [961ee093] ModelingToolkit v9.55.0 [e94cdb99] MosaicViews v0.3.4 [46d2c3a1] MuladdMacro v0.2.4 [102ac46a] MultivariatePolynomials v0.5.7 @@ -311,7 +311,7 @@ [94e857df] SIMDTypes v0.1.0 [476501e8] SLEEFPirates v0.6.43 [1bc83da4] SafeTestsets v0.1.0 - [0bca4576] SciMLBase v2.65.1 + [0bca4576] SciMLBase v2.66.0 [19f34311] SciMLJacobianOperators v0.1.1 [c0aeaf25] SciMLOperators v0.3.12 [53ae85a6] SciMLStructures v1.6.1 @@ -389,11 +389,11 @@ [d7e528f0] FreeType2_jll v2.13.3+1 [559328eb] FriBidi_jll v1.0.14+0 [0656b61e] GLFW_jll v3.4.0+1 - [d2c73de3] GR_jll v0.73.8+0 + [d2c73de3] GR_jll v0.73.8+0 [78b55507] Gettext_jll v0.21.0+0 [59f7168a] Giflib_jll v5.2.2+0 [f8c6e375] Git_jll v2.47.1+0 - [7746bdde] Glib_jll v2.82.2+0 + [7746bdde] Glib_jll v2.82.2+1 [3b182d85] Graphite2_jll v1.3.14+1 [2e76f6c2] HarfBuzz_jll v8.3.1+0 [905a6f67] Imath_jll v3.1.11+0 @@ -524,4 +524,4 @@ [8e850b90] libblastrampoline_jll v5.11.0+0 [8e850ede] nghttp2_jll v1.59.0+0 [3f19e933] p7zip_jll v17.4.0+2 -Info Packages marked with and have new versions available. Those with may be upgradable, but those with are restricted by compatibility constraints from upgrading. To see why use `status --outdated -m`

Funding

Development of this project was in part funded by the German Federal Ministry for Economic Affairs and Climate Action as part of the OpPoDyn-Project (Project ID 01258425/1, 2024-2027).

+Info Packages marked with and have new versions available. Those with may be upgradable, but those with are restricted by compatibility constraints from upgrading. To see why use `status --outdated -m`

Funding

Development of this project was in part funded by the German Federal Ministry for Economic Affairs and Climate Action as part of the OpPoDyn-Project (Project ID 01258425/1, 2024-2027).

diff --git a/previews/PR188/initialization/index.html b/previews/PR188/initialization/index.html index 502f6a68..60d6ab7c 100644 --- a/previews/PR188/initialization/index.html +++ b/previews/PR188/initialization/index.html @@ -37,4 +37,4 @@ ├─ 2 inputs: [i_r=1, i_i=0.1] ├─ 2 states: [θ=0.099669, ω=3.4499e-23] ├─ 2 outputs: [u_r=1, u_i=0.1] - └─ 5 params: [M=0.005, Pm=1.01, V=1.005, D=0.1, ω_ref=0]

Which lead to a successfull initialization of states and as well as parameter :Pm. To retrieve the residual you can use init_residual.

As a quick test we can ensure that the angle indeed matches the voltag angel:

get_init(vf, :θ) ≈ atan(get_default(vf, :u_i), get_default(vf, :u_r))
true
+ └─ 5 params: [M=0.005, Pm=1.01, V=1.005, D=0.1, ω_ref=0]

Which lead to a successfull initialization of states and as well as parameter :Pm. To retrieve the residual you can use init_residual.

As a quick test we can ensure that the angle indeed matches the voltag angel:

get_init(vf, :θ) ≈ atan(get_default(vf, :u_i), get_default(vf, :u_r))
true
diff --git a/previews/PR188/mathematical_model/index.html b/previews/PR188/mathematical_model/index.html index 461bf13f..a465f464 100644 --- a/previews/PR188/mathematical_model/index.html +++ b/previews/PR188/mathematical_model/index.html @@ -45,4 +45,4 @@ g!(v_out, x, p, t) # single layer vertex

PureStateMap()

g!(outs...,          x) # abstractly
 g!(out_dst,          x) # single-sided edge
 g!(out_src, out_dst, x) # double-sided edge
-g!(v_out,            x) # single layer vertex
+g!(v_out, x) # single layer vertex diff --git a/previews/PR188/metadata/index.html b/previews/PR188/metadata/index.html index d99adb1b..15cee386 100644 --- a/previews/PR188/metadata/index.html +++ b/previews/PR188/metadata/index.html @@ -1,2 +1,2 @@ -Metadata · NetworkDynamics

Metadata

Component model such as VertexModel and EdgeModel can store metadata. We distinguish between two kinds of metadata: component metadata and symbol metadata.

Component Metadata

Component metadata is a Dict{Symbol,Any} attached to each component to store various information. Use metadata to retrieve the full dict.

To access the data, you can use the methods has_metadata, get_metadata and set_metadata! (see Component Metadata API).

Special metadata:

  • :init_residual: after Component-wise Initialization, this field stores the residual vector of the nonlinear problem.
  • :graphelement: optional field to specialize the graphelement for each component (vidx) for vertices, (;src,dst) named tuple of either vertex names or vertex indices for edges. Has special accessors has_/get_/set_graphelement.

Symbol Metadata

Each component stores symbol metadata. The symbol metadata is a Dict{Symbol, Dict{Symbol, Any}} which stores a metadate dict per symbol. Symbols are everything that appears in sym, psym, obssym and insym.

To access the data, you can use the methods has_metadata, get_metadata and set_metadata! (see Per Symbol Metadata API).

Special cases for symbol metadata are:

  • default: Stores default values for states/parameters. In initialization, those are considered fixed.
  • guess: Stores a guess for a state/parameter which needs to solved during initialization ("free" variables).
  • bounds: Store bounds for variables/parameters
  • init: Stores the solution of the "free" variables during initialization.

Fore those, there are special functions has_*, get_* and set_*!. See Per Symbol Metadata API.

Those are closely aligned to the metadata use in ModelingToolkit. They are automatically copied from the ODESystem if you use MTK models to create NetworkDynamics models.

+Metadata · NetworkDynamics

Metadata

Component model such as VertexModel and EdgeModel can store metadata. We distinguish between two kinds of metadata: component metadata and symbol metadata.

Component Metadata

Component metadata is a Dict{Symbol,Any} attached to each component to store various information. Use metadata to retrieve the full dict.

To access the data, you can use the methods has_metadata, get_metadata and set_metadata! (see Component Metadata API).

Special metadata:

  • :init_residual: after Component-wise Initialization, this field stores the residual vector of the nonlinear problem.
  • :graphelement: optional field to specialize the graphelement for each component (vidx) for vertices, (;src,dst) named tuple of either vertex names or vertex indices for edges. Has special accessors has_/get_/set_graphelement.

Symbol Metadata

Each component stores symbol metadata. The symbol metadata is a Dict{Symbol, Dict{Symbol, Any}} which stores a metadate dict per symbol. Symbols are everything that appears in sym, psym, obssym and insym.

To access the data, you can use the methods has_metadata, get_metadata and set_metadata! (see Per Symbol Metadata API).

Special cases for symbol metadata are:

  • default: Stores default values for states/parameters. In initialization, those are considered fixed.
  • guess: Stores a guess for a state/parameter which needs to solved during initialization ("free" variables).
  • bounds: Store bounds for variables/parameters
  • init: Stores the solution of the "free" variables during initialization.

Fore those, there are special functions has_*, get_* and set_*!. See Per Symbol Metadata API.

Those are closely aligned to the metadata use in ModelingToolkit. They are automatically copied from the ODESystem if you use MTK models to create NetworkDynamics models.

diff --git a/previews/PR188/mtk_integration/index.html b/previews/PR188/mtk_integration/index.html index 3961773d..0bb34fe8 100644 --- a/previews/PR188/mtk_integration/index.html +++ b/previews/PR188/mtk_integration/index.html @@ -81,4 +81,4 @@ axislegend(ax1) ax2 = Axis(fig[2,1]) plot!(ax2, sol; idxs=VIndex(:vs, :i), label="Current produced by ideal v source") -axislegend(ax2)Example block output +axislegend(ax2)Example block output diff --git a/previews/PR188/network_construction/index.html b/previews/PR188/network_construction/index.html index de4fe575..df760992 100644 --- a/previews/PR188/network_construction/index.html +++ b/previews/PR188/network_construction/index.html @@ -58,4 +58,4 @@ ├─ 1/1 inputs: src=[src₊θ] dst=[dst₊θ] ├─ 0 states: [] ├─ 1/1 outputs: src=[₋P] dst=[P] - └─ 1 param: [K=1] + └─ 1 param: [K=1] diff --git a/previews/PR188/symbolic_indexing/5cf94789.svg b/previews/PR188/symbolic_indexing/5cf94789.svg deleted file mode 100644 index 9a6fd6b2..00000000 --- a/previews/PR188/symbolic_indexing/5cf94789.svg +++ /dev/null @@ -1,62 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/previews/PR188/symbolic_indexing/67356ffd.svg b/previews/PR188/symbolic_indexing/67356ffd.svg deleted file mode 100644 index 1490d8c1..00000000 --- a/previews/PR188/symbolic_indexing/67356ffd.svg +++ /dev/null @@ -1,46 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/previews/PR188/symbolic_indexing/6ce13476.svg b/previews/PR188/symbolic_indexing/6ce13476.svg deleted file mode 100644 index dc9398f3..00000000 --- a/previews/PR188/symbolic_indexing/6ce13476.svg +++ /dev/null @@ -1,52 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/previews/PR188/symbolic_indexing/90239202.svg b/previews/PR188/symbolic_indexing/90239202.svg new file mode 100644 index 00000000..2a1de1af --- /dev/null +++ b/previews/PR188/symbolic_indexing/90239202.svg @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/previews/PR188/symbolic_indexing/921e5ae7.svg b/previews/PR188/symbolic_indexing/921e5ae7.svg new file mode 100644 index 00000000..e6e34043 --- /dev/null +++ b/previews/PR188/symbolic_indexing/921e5ae7.svg @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/previews/PR188/symbolic_indexing/a63d43a5.svg b/previews/PR188/symbolic_indexing/a63d43a5.svg new file mode 100644 index 00000000..3e76bc02 --- /dev/null +++ b/previews/PR188/symbolic_indexing/a63d43a5.svg @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/previews/PR188/symbolic_indexing/index.html b/previews/PR188/symbolic_indexing/index.html index a3f00117..899fee47 100644 --- a/previews/PR188/symbolic_indexing/index.html +++ b/previews/PR188/symbolic_indexing/index.html @@ -19,12 +19,12 @@ s.v[:,:storage] .= randn(5) prob = ODEProblem(nw, uflat(s), (0,2), pflat(s)) sol = solve(prob, Tsit5())

Those fundamental indices can be used in a lot of scenarios. Most importantly you can use them to

sol(sol.t; idxs=VIndex(1, :storage))   # extract timeseries out ouf solution object
-plot(sol; idxs=[VIndex(1, :storage), VIndex(5,:storage)]) # plot storage of two nodes
Example block output

Generate Symbolic Indices

Often, you need many individual symbolic indices. For that there are the helper methods vidxs, eidxs, vpidxs and epidxs. With the help of those methods you can generate arrays of symbolic indices:

vidxs(nw, :, :storage) # get variable "storage" for all nodes
5-element Vector{VIndex}:
+plot(sol; idxs=[VIndex(1, :storage), VIndex(5,:storage)]) # plot storage of two nodes
Example block output

Generate Symbolic Indices

Often, you need many individual symbolic indices. For that there are the helper methods vidxs, eidxs, vpidxs and epidxs. With the help of those methods you can generate arrays of symbolic indices:

vidxs(nw, :, :storage) # get variable "storage" for all nodes
5-element Vector{VIndex}:
  VIndex(1, :storage)
  VIndex(2, :storage)
  VIndex(3, :storage)
  VIndex(4, :storage)
- VIndex(5, :storage)
plot(sol; idxs=vidxs(nw, :, :storage))
Example block output

NWState and NWParameter Objects

Internally, both state and parameters of a Network are represented using flat arrays. To access the state or parameters of a network, you can use the NWState and NWParameter objects.

p = NWParameter(nw)
Parameter{Vector{Float64}} of Network (5 vertices, 8 edges)
+ VIndex(5, :storage)
plot(sol; idxs=vidxs(nw, :, :storage))
Example block output

NWState and NWParameter Objects

Internally, both state and parameters of a Network are represented using flat arrays. To access the state or parameters of a network, you can use the NWState and NWParameter objects.

p = NWParameter(nw)
Parameter{Vector{Float64}} of Network (5 vertices, 8 edges)
   ├─ EPIndex(1, :K) => 1.0
   ├─ EPIndex(2, :K) => 1.0
   ├─ EPIndex(3, :K) => 1.0
@@ -40,12 +40,12 @@
   └─ VIndex(5, :storage) => NaN
  p = NWParameter([1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0])
  t = nothing

No default values were provided in the network components, so the state array is filled with NaNs.

s[VIndex(:, :storage)] .= randn(5) # set the (initial) storage for alle nodes
NWState{Vector{Float64}} of Network (5 vertices, 8 edges)
-  ├─ VIndex(1, :storage) => -0.253551933382062
-  ├─ VIndex(2, :storage) => -0.2031739394281129
-  ├─ VIndex(3, :storage) => -1.5987902403144394
-  ├─ VIndex(4, :storage) => 0.7934991692948181
-  └─ VIndex(5, :storage) => 0.3891989380684158
+  ├─ VIndex(1, :storage) => 1.2570829613590842
+  ├─ VIndex(2, :storage) => -0.9986056813391421
+  ├─ VIndex(3, :storage) => -0.4519853550268408
+  ├─ VIndex(4, :storage) => -0.19803354031279558
+  └─ VIndex(5, :storage) => -0.28393623500331894
  p = NWParameter([1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0])
  t = nothing

For both NWState and NWParameter objects, the there is a more convenient way to access the variables and parameters.

@assert s.v[1, :storage] == s[VIndex(1, :storage)] # s.v -> access vertex states
 @assert s.e[1, :flow]    == s[EIndex(1, :flow)]    # s.e -> access edge states
-@assert s.p.e[1,:K]      == p[EPIndex(1, :K)]      # s.p -> access parameters

The NWState and NWParameter objects are mutable, thus changing them will also change the underlying wrapped flat arrays. You can allways access the flat representations by calling uflat and pflat.

Note

The NWState and NWParameter wrappers can be constructed from various objects. Fore example, within a callback you might construct p = NWParameter(integrator) to then change the parameters of the network within the callback.

Observables

Sometimes, the "states" you're interested in aren't really states in the DAE sense but rather algebraic derivations from DAE states, parameters and time – in accordance with the naming in the SciML-ecosystem those states are called Observables.

A prime example of Observables are edge/vertex-outputs, such as the flow in the edge model defined above. It is also possible to define additional Observables manually by using the obssym and obsf keyword on the EdgeModel/VertexModel constructors. When building models using ModelingToolkit, the reduced algebraic states will be preserved as observables automatically.

Observables can be accessed like any other state, for example, the flows in the network don't show up in the state array but can be accessed in all the ways discussed above, for example

plot(sol; idxs=eidxs(nw, :, :flow))
Example block output +@assert s.p.e[1,:K] == p[EPIndex(1, :K)] # s.p -> access parameters

The NWState and NWParameter objects are mutable, thus changing them will also change the underlying wrapped flat arrays. You can allways access the flat representations by calling uflat and pflat.

Note

The NWState and NWParameter wrappers can be constructed from various objects. Fore example, within a callback you might construct p = NWParameter(integrator) to then change the parameters of the network within the callback.

Observables

Sometimes, the "states" you're interested in aren't really states in the DAE sense but rather algebraic derivations from DAE states, parameters and time – in accordance with the naming in the SciML-ecosystem those states are called Observables.

A prime example of Observables are edge/vertex-outputs, such as the flow in the edge model defined above. It is also possible to define additional Observables manually by using the obssym and obsf keyword on the EdgeModel/VertexModel constructors. When building models using ModelingToolkit, the reduced algebraic states will be preserved as observables automatically.

Observables can be accessed like any other state, for example, the flows in the network don't show up in the state array but can be accessed in all the ways discussed above, for example

plot(sol; idxs=eidxs(nw, :, :flow))
Example block output