diff --git a/dev/.documenter-siteinfo.json b/dev/.documenter-siteinfo.json index 4620ace0..afe70f2a 100644 --- a/dev/.documenter-siteinfo.json +++ b/dev/.documenter-siteinfo.json @@ -1 +1 @@ -{"documenter":{"julia_version":"1.11.2","generation_timestamp":"2024-12-03T15:43:48","documenter_version":"1.8.0"}} \ No newline at end of file +{"documenter":{"julia_version":"1.11.2","generation_timestamp":"2024-12-05T08:58:11","documenter_version":"1.8.0"}} \ No newline at end of file diff --git a/dev/API/index.html b/dev/API/index.html index b9fe0d2d..77ab5aaf 100644 --- a/dev/API/index.html +++ b/dev/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/dev/external_inputs/index.html b/dev/external_inputs/index.html index 7c7099d0..476741af 100644 --- a/dev/external_inputs/index.html +++ b/dev/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/dev/generated/StochasticSystem.jl b/dev/generated/StochasticSystem.jl deleted file mode 100644 index 4edbe34b..00000000 --- a/dev/generated/StochasticSystem.jl +++ /dev/null @@ -1,128 +0,0 @@ -# # SDE Tutorial -# -# -# #### Topics covered in this tutorial include: -# -# - the swing equation -# - fixpoint search of ODE systems -# - constructing an SDE problem with NetworkDynamics.jl -# -# ## Example: Fluctuations in Power Grids -# -# This tutorial explains the use of stochastic differential equations (SDE's) in NetworkDynamics.jl. As an example system we will simulate fluctuations in a simple power grid model. -# -# The phase and frequency dynamics in power grids can be modeled by the swing equation. In the complex systems community this is also known as the Kuramoto model with inertia. -# -# ```math -# \begin{aligned} -# \dot \theta_i &= \omega_i \\ -# M_i \dot \omega_i &= P_i(t) - D_i \omega_i - \sum_{i=1}^N K_{ij} \sin(\theta_i - \theta_j) -# \end{aligned} -# ``` -# -# Here, $M_i$ and $D_i$ are inertia and damping parameters, $K_{ij}$ is the power capacitiy of the line and $P_i(t)$ is the power infeed at the node. We assume that this power can be separated into a constant power setpoint $P^\circ_i$ and a stochastic fluctuation. -# -# ```math -# \begin{aligned} -# P_i(t) = P^\circ_i + \sigma_i \cdot \xi_i(t) -# \end{aligned} -# ``` -# -# In this tutorial we assume the fluctuations $\xi_i(t)$ to be white Gaussian noise. Separating the deterministic and stochastic part, we can write this problem as a stochastic differential equation. -# -# ```math -# \begin{aligned} -# d\omega_i = \left[P_i - D_i \omega_i - \sum_{i=1}^N K_{ij} \sin(\theta_i - \theta_j)\right] dt + \sigma_i dW_i -# \end{aligned} -# ``` -# -# Here, $dW_i = \xi_i dt$ is the infinitesimal increment of the Wiener process. Problems of this type can be numerically solved in Julia as described in the [SDE Tutorial](https://diffeq.sciml.ai/stable/tutorials/sde_example/) of `DifferentialEquations`. -# -# ## Implementing the Swing Equation -# -# 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$. - -using NetworkDynamics, Graphs -using StochasticDiffEq, OrdinaryDiffEqTsit5 -using Plots, LaTeXStrings - -function swing_equation!(dv, v, esum, (M, P, D), t) - dv[1] = v[2] - dv[2] = 1/M *(P - D * v[2] + esum[1]) - nothing -end -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 = EdgeModel(g=AntiSymmetric(powerflow!), outdim=1, psym=[:K=>6]) - -# ## Contructing the Deterministic Dynamics -# -# For the graph structure we will use a simple 4 node ring network. - -g = watts_strogatz(4, 2, 0.0) - -# Then we can construct the `Network` of the deterministic system. - -nd = Network(g, swing_vertex, powerflow_edge) - -# ## Fixpoint Search -# -# Now we need to define the dynamic parameters of vertices and edges. -# For that, we start by creating the `NWParameter` object, pre filling it with the default values: - -p = NWParameter(nd) - -# Most of the parameters are allready set -# For the nodes we assume half of them to be net producers ($P = 1.0$) and half of them to be net consumers ($P = -1.0$) of power. - -p.v[1:4, :P] = [1, -1, 1, -1] - -# We want to simulate fluctuations around an equilibrium state of our model -# system. Therefore, we need to find a fixpoint of the determinitic system which -# can be done by using the utility function `find_fixpoint()`. As an initial guess -# we take all variables equal to zero. - -u0 = find_fixpoint(nd, p) - -ode_prob = ODEProblem(nd, uflat(u0), (0.0, 500.0), pflat(p)) -ode_sol = solve(ode_prob, Tsit5()) - -plot(ode_sol; idxs=vidxs(nd,:,:ω), ylims=(-1.0, 1.0), ylabel=L"\omega", legend=false, fmt=:png) - -# We see that this is in fact a fixpoint solution. We will later use this as an initial condition for the numerical integration of the SDE system. -# -# ## Adding a Stochastic Layer -# -# For adding the stochastic part of the dynamics we have to define a second graph layer. In our example, the fluctuations at different nodes are independent of each other. Therefore, we define a second graph with the same number of vertices but without any edges. - -h = SimpleGraph(4, 0) - -# The dynamics at the nodes has to have the same dimension as in the deterministic case. In our example we only have fluctuations in the second variable. -# FIXME: stochastic system should be simulated using symbolic indexing, this is jsut wrong in current ND! - -# function fluctuation!(dx, x, edges, p, t) -# dx[1] = 0.0 -# dx[2] = 0.05 -# end - -# 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 = VertexModel(f=fluctuation!, g=1:2, dim=2) -# nd_noise = Network(h, fluctuation_vertex, NetworkDynamics.EdgeModel[]) - -# ## Simulating the SDE -# -# Finally, we can create an `SDEProblem` and solve it with `DifferentialEquations`. - -# sde_prob = SDEProblem(nd, nd_noise, uflat(u0), (0.0, 500.0), pflat(p)) -# sde_sol = solve(sde_prob, SOSRA()) -# plot(sde_sol; idxs=vidxs(nd,:,:ω), ylims=(-1.0, 1.0), ylabel=L"\omega", legend=false, fmt=:png) - -# More details on SDE problems, e.g. how to include correlations or how to define an `EnsembleProblem`, can be found in the [documentation](https://diffeq.sciml.ai/stable/types/sde_types/) of `DifferentialEquations`. - -# This file was generated using Literate.jl, https://github.com/fredrikekre/Literate.jl diff --git a/dev/generated/cascading_failure/76f3f329.svg b/dev/generated/cascading_failure/161d6bf2.svg similarity index 95% rename from dev/generated/cascading_failure/76f3f329.svg rename to dev/generated/cascading_failure/161d6bf2.svg index 994370c0..5f44daea 100644 --- a/dev/generated/cascading_failure/76f3f329.svg +++ b/dev/generated/cascading_failure/161d6bf2.svg @@ -1,62 +1,62 @@ - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev/generated/cascading_failure/index.html b/dev/generated/cascading_failure/index.html index cf30a6e3..5eda6a9a 100644 --- a/dev/generated/cascading_failure/index.html +++ b/dev/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/dev/generated/directed_and_weighted_graphs/c8ad9394.svg b/dev/generated/directed_and_weighted_graphs/c8abeb96.svg similarity index 99% rename from dev/generated/directed_and_weighted_graphs/c8ad9394.svg rename to dev/generated/directed_and_weighted_graphs/c8abeb96.svg index abb8ded4..6ef39abc 100644 --- a/dev/generated/directed_and_weighted_graphs/c8ad9394.svg +++ b/dev/generated/directed_and_weighted_graphs/c8abeb96.svg @@ -1,132 +1,132 @@ - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev/generated/directed_and_weighted_graphs/index.html b/dev/generated/directed_and_weighted_graphs/index.html index 4f26be32..3d5a4600 100644 --- a/dev/generated/directed_and_weighted_graphs/index.html +++ b/dev/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/dev/generated/gas_network/index.html b/dev/generated/gas_network/index.html index 22154010..271fe2f0 100644 --- a/dev/generated/gas_network/index.html +++ b/dev/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/dev/generated/getting_started_with_network_dynamics/0263d71f.svg b/dev/generated/getting_started_with_network_dynamics/0263d71f.svg deleted file mode 100644 index 3ad77e82..00000000 --- a/dev/generated/getting_started_with_network_dynamics/0263d71f.svg +++ /dev/null @@ -1,82 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/dev/generated/getting_started_with_network_dynamics/06c1c102.svg b/dev/generated/getting_started_with_network_dynamics/06c1c102.svg deleted file mode 100644 index 6a2fe6f1..00000000 --- a/dev/generated/getting_started_with_network_dynamics/06c1c102.svg +++ /dev/null @@ -1,88 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/dev/generated/getting_started_with_network_dynamics/644389c4.svg b/dev/generated/getting_started_with_network_dynamics/644389c4.svg new file mode 100644 index 00000000..ebef172e --- /dev/null +++ b/dev/generated/getting_started_with_network_dynamics/644389c4.svg @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev/generated/getting_started_with_network_dynamics/7a7939af.svg b/dev/generated/getting_started_with_network_dynamics/7a7939af.svg new file mode 100644 index 00000000..ee461434 --- /dev/null +++ b/dev/generated/getting_started_with_network_dynamics/7a7939af.svg @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev/generated/getting_started_with_network_dynamics/c856318a.svg b/dev/generated/getting_started_with_network_dynamics/c856318a.svg new file mode 100644 index 00000000..122463be --- /dev/null +++ b/dev/generated/getting_started_with_network_dynamics/c856318a.svg @@ -0,0 +1,88 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev/generated/getting_started_with_network_dynamics/de4c6984.svg b/dev/generated/getting_started_with_network_dynamics/de4c6984.svg deleted file mode 100644 index 306130d9..00000000 --- a/dev/generated/getting_started_with_network_dynamics/de4c6984.svg +++ /dev/null @@ -1,60 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/dev/generated/getting_started_with_network_dynamics/index.html b/dev/generated/getting_started_with_network_dynamics/index.html index 52c9d696..a7f7071d 100644 --- a/dev/generated/getting_started_with_network_dynamics/index.html +++ b/dev/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/dev/generated/heterogeneous_system/264581af.svg b/dev/generated/heterogeneous_system/0ca44f59.svg similarity index 96% rename from dev/generated/heterogeneous_system/264581af.svg rename to dev/generated/heterogeneous_system/0ca44f59.svg index 7bd1372d..8a140258 100644 --- a/dev/generated/heterogeneous_system/264581af.svg +++ b/dev/generated/heterogeneous_system/0ca44f59.svg @@ -1,66 +1,66 @@ - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev/generated/heterogeneous_system/7a5466f4.svg b/dev/generated/heterogeneous_system/0efd6445.svg similarity index 95% rename from dev/generated/heterogeneous_system/7a5466f4.svg rename to dev/generated/heterogeneous_system/0efd6445.svg index e3eeca55..c3ced893 100644 --- a/dev/generated/heterogeneous_system/7a5466f4.svg +++ b/dev/generated/heterogeneous_system/0efd6445.svg @@ -1,62 +1,62 @@ - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev/generated/heterogeneous_system/f7ebe33e.svg b/dev/generated/heterogeneous_system/a7f71f01.svg similarity index 95% rename from dev/generated/heterogeneous_system/f7ebe33e.svg rename to dev/generated/heterogeneous_system/a7f71f01.svg index c5c0f610..f4334c21 100644 --- a/dev/generated/heterogeneous_system/f7ebe33e.svg +++ b/dev/generated/heterogeneous_system/a7f71f01.svg @@ -1,62 +1,62 @@ - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev/generated/heterogeneous_system/index.html b/dev/generated/heterogeneous_system/index.html index aba8ce81..a07fa2d4 100644 --- a/dev/generated/heterogeneous_system/index.html +++ b/dev/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/dev/generated/stress_on_truss/index.html b/dev/generated/stress_on_truss/index.html index 4a13f343..c5bd0bec 100644 --- a/dev/generated/stress_on_truss/index.html +++ b/dev/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/dev/index.html b/dev/index.html index 0310050f..0c20a895 100644 --- a/dev/index.html +++ b/dev/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,8 +52,8 @@ [dce04be8] ArgCheck v2.4.0 [ec485272] ArnoldiMethod v0.4.0 [4fba245c] ArrayInterface v7.17.1 - [4c555306] ArrayLayouts v1.10.4 - [a9b6321e] Atomix v0.1.0 + [4c555306] ArrayLayouts v1.11.0 + [a9b6321e] Atomix v0.1.0 [67c07d97] Automa v1.1.0 [13072b0f] AxisAlgorithms v1.1.0 [39de3d68] AxisArrays v0.4.7 @@ -61,11 +61,13 @@ [d1d4a3ce] BitFlags v0.1.9 [62783981] BitTwiddlingConvenienceFunctions v0.1.6 [8e7c35d0] BlockArrays v1.3.0 + [70df07ce] BracketingNonlinearSolve v1.1.0 [fa961155] CEnum v0.5.0 [2a0fbf3d] CPUSummary v0.2.6 [00ebfdb7] CSTParser v3.4.3 [159f3aea] Cairo v1.1.1 [13f3f980] CairoMakie v0.12.16 + [7057c7e9] Cassette v0.3.14 [d360d2e6] ChainRulesCore v1.25.0 [fb6a15b2] CloseOpenIntervals v0.1.13 [944b1d66] CodecZlib v0.7.6 @@ -98,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 @@ -108,7 +110,7 @@ [7c1d4256] DynamicPolynomials v0.6.1 [06fc5a27] DynamicQuantities v1.4.0 [4e289a0a] EnumX v1.0.4 - [f151be2c] EnzymeCore v0.8.7 + [f151be2c] EnzymeCore v0.8.8 [429591f6] ExactPredicates v2.2.8 [460bff9d] ExceptionUnwrapping v0.1.11 [d4d017d3] ExponentialUtilities v1.27.0 @@ -132,11 +134,12 @@ [f6369f11] ForwardDiff v0.10.38 [b38be410] FreeType v4.1.1 [663a7486] FreeTypeAbstraction v0.10.6 + [f62d2435] FunctionProperties v0.1.2 [069b7b12] FunctionWrappers v1.1.3 [77dc65aa] FunctionWrappersWrappers v0.1.3 [d9f16b24] Functors v0.5.2 [46192b85] GPUArraysCore v0.2.0 - [28b8d3ca] GR v0.73.8 + [28b8d3ca] GR v0.73.9 [c145ed77] GenericSchur v0.5.4 [68eda718] GeoFormatTypes v0.4.2 [cf35fbd7] GeoInterface v1.3.8 @@ -208,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 @@ -220,7 +223,11 @@ [f09324ee] Netpbm v1.1.1 [22e9dc34] NetworkDynamics v0.9.3 `~/work/NetworkDynamics.jl/NetworkDynamics.jl` [46757867] NetworkLayout v0.4.7 - [8913a72c] NonlinearSolve v3.15.1 + [8913a72c] NonlinearSolve v4.2.0 + [be0214bd] NonlinearSolveBase v1.3.3 + [5959db7a] NonlinearSolveFirstOrder v1.1.0 + [9a2c21bd] NonlinearSolveQuasiNewton v1.0.0 + [26075421] NonlinearSolveSpectralMethods v1.0.0 [510215fc] Observables v0.5.5 [6fe1bfb0] OffsetArrays v1.14.1 [52e1d378] OpenEXR v0.3.3 @@ -304,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 @@ -314,13 +321,12 @@ [992d4aef] Showoff v1.0.3 [73760f76] SignedDistanceFields v0.4.0 [777ac1f9] SimpleBufferStream v1.2.0 - [727e6d20] SimpleNonlinearSolve v1.12.3 + [727e6d20] SimpleNonlinearSolve v2.0.0 [699a6c99] SimpleTraits v0.9.4 [ce78b400] SimpleUnPack v1.1.0 [47aef6b3] SimpleWeightedGraphs v1.4.0 [45858cf5] Sixel v0.1.3 [a2af1166] SortingAlgorithms v1.2.1 - [9f842d2f] SparseConnectivityTracer v0.6.9 [47a9eef4] SparseDiffTools v2.23.0 [0a514795] SparseMatrixColorings v0.4.10 [e56a9233] Sparspak v0.3.9 @@ -342,7 +348,7 @@ [2efcf032] SymbolicIndexingInterface v0.3.36 [19f23fe9] SymbolicLimits v0.2.2 [d1185830] SymbolicUtils v3.7.2 - [0c5d862f] Symbolics v6.19.0 + [0c5d862f] Symbolics v6.19.0 [3783bdb8] TableTraits v1.0.1 [bd369af6] Tables v1.12.0 [62fd8b95] TensorCore v0.1.1 @@ -383,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.9+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 @@ -518,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/dev/initialization/index.html b/dev/initialization/index.html index 9fa2c21a..c24f43d8 100644 --- a/dev/initialization/index.html +++ b/dev/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/dev/mathematical_model/index.html b/dev/mathematical_model/index.html index 8dadea47..afb87f2c 100644 --- a/dev/mathematical_model/index.html +++ b/dev/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/dev/metadata/index.html b/dev/metadata/index.html index 06f937a0..01246474 100644 --- a/dev/metadata/index.html +++ b/dev/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/dev/mtk_integration/index.html b/dev/mtk_integration/index.html index abe72627..f091e016 100644 --- a/dev/mtk_integration/index.html +++ b/dev/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/dev/network_construction/index.html b/dev/network_construction/index.html index 06def29a..628d3967 100644 --- a/dev/network_construction/index.html +++ b/dev/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/dev/symbolic_indexing/10ab9dfa.svg b/dev/symbolic_indexing/10ab9dfa.svg new file mode 100644 index 00000000..fd5c058f --- /dev/null +++ b/dev/symbolic_indexing/10ab9dfa.svg @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev/symbolic_indexing/13f3fa79.svg b/dev/symbolic_indexing/13f3fa79.svg new file mode 100644 index 00000000..cf1b293e --- /dev/null +++ b/dev/symbolic_indexing/13f3fa79.svg @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev/symbolic_indexing/147c7075.svg b/dev/symbolic_indexing/147c7075.svg new file mode 100644 index 00000000..e70b6eda --- /dev/null +++ b/dev/symbolic_indexing/147c7075.svg @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev/symbolic_indexing/c458d911.svg b/dev/symbolic_indexing/c458d911.svg deleted file mode 100644 index 533b84c4..00000000 --- a/dev/symbolic_indexing/c458d911.svg +++ /dev/null @@ -1,46 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/dev/symbolic_indexing/ccb2c124.svg b/dev/symbolic_indexing/ccb2c124.svg deleted file mode 100644 index 25013507..00000000 --- a/dev/symbolic_indexing/ccb2c124.svg +++ /dev/null @@ -1,58 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/dev/symbolic_indexing/dcc19b6f.svg b/dev/symbolic_indexing/dcc19b6f.svg deleted file mode 100644 index 48555c8c..00000000 --- a/dev/symbolic_indexing/dcc19b6f.svg +++ /dev/null @@ -1,54 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/dev/symbolic_indexing/index.html b/dev/symbolic_indexing/index.html index 7cfcbaea..129f56c7 100644 --- a/dev/symbolic_indexing/index.html +++ b/dev/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) => -1.5204019120837888
-  ├─ VIndex(2, :storage) => -1.2505457761211103
-  ├─ VIndex(3, :storage) => 0.5950677171988363
-  ├─ VIndex(4, :storage) => -1.160141711237264
-  └─ VIndex(5, :storage) => 0.4635041969216972
+  ├─ VIndex(1, :storage) => 1.162619247186209
+  ├─ VIndex(2, :storage) => -1.0135900603597212
+  ├─ VIndex(3, :storage) => -0.024224902158086776
+  ├─ VIndex(4, :storage) => 0.7919748509235002
+  └─ VIndex(5, :storage) => -0.3145495580272715
  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