API Reference
Modeling Tools
Constructors for ND Models
Those functions help you to bridge from MTK models to NetworkDynamics.jl Models:
OpPoDyn.Bus
— FunctionBus(sys::ODESystem; verbose=false, name=getname(sys), kwargs...)
Create a VertexModel from an ODESystem that satisfies the bus model interface.
Arguments
sys::ODESystem
: The system must satisfy the bus model interface (seeisbusmodel
)verbose::Bool=false
: Enable verbose output during creationname
: Name for the bus (defaults to system name)kwargs...
: Additional keyword arguments passed to the Bus constructor
Returns
- A
VertexModel
representing the bus
╔═════════════════════════╗
║ VertexModel (compiled) ║
┌────────────────────┐ Network ║ ┌────────────────────┐ ║
│MTKBus ┌─────────┐│ interface ║ │MTKBus ┌─────────┐│ ║
│ ┌┤Generator││ ║ │ ┌┤Generator││ ║
│┌──────┐│└─────────┘│ current ────→│┌──────┐│└─────────┘│ ║
Bus(││BusBar├o │) => ║ ││BusBar├o │ ║
│└──────┘│┌────┐ │ voltage ←────│└──────┘│┌────┐ │ ║
│ └┤Load│ │ ║ │ └┤Load│ │ ║
│ └────┘ │ ║ │ └────┘ │ ║
└────────────────────┘ ║ └────────────────────┘ ║
╚═════════════════════════╝
See also: MTKBus
OpPoDyn.Line
— FunctionLine(sys::ODESystem; verbose=false, name=getname(sys), kwargs...)
Create an EdgeModel from an ODESystem that satisfies the line model interface.
Arguments
sys::ODESystem
: The system must satisfy the line model interface (seeislinemodel
)verbose::Bool=false
: Enable verbose output during creationname
: Name for the line (defaults to system name)kwargs...
: Additional keyword arguments passed to the Line constructor
Returns
- An
EdgeModel
representing the line
╔══════════════════════════════╗
║ EdgeModel (compiled) ║
┌─────────────────────────────┐ src ║ ┌──────────────────────────┐ ║ dst
│MTKLine ┌───────┐ │ vertex ║ │MTKLine ┌────┐ │ ║ vertex
│ ┌┤BranchA├┐ │ ║ │ ┌┤ ├┐ │ ║
│┌───────┐│└───────┘│┌───────┐│ u ───→│┌───────┐│└────┘│┌───────┐│←─── u
Line(││LineEnd├o o┤LineEnd││) => ║ ││LineEnd├o o┤LineEnd││ ║
│└───────┘│┌───────┐│└───────┘│ i ←───│└───────┘│┌────┐│└───────┘│───→ i
│ :src └┤BranchB├┘ :dst │ ║ │ └┤ ├┘ │ ║
│ └───────┘ │ ║ │ └────┘ │ ║
└─────────────────────────────┘ ║ └──────────────────────────┘ ║
╚══════════════════════════════╝
See also: MTKLine
Basic Component Modeling
OpPoDyn.Terminal
— ConstantTerminal
A ModelingToolkit connector for electrical terminals in power system components.
Represents an electrical connection point with complex voltage and current in dq coordinates. The terminal defines the interface between power system components like buses, lines, and machines.
Variables
u_r(t)
: d-axis voltage componentu_i(t)
: q-axis voltage componenti_r(t)
: d-axis current component (flow variable)i_i(t)
: q-axis current component (flow variable)
Notes
Current variables are defined as flow variables, meaning they sum to zero at connection points according to Kirchhoff's current law.
OpPoDyn.BusBar
— Constant@named busbar = BusBar()
A ModelingToolkit model representing the physical connection point within a bus in power systems. It represents the physical busbar where all injectors and lines attach.
Within OpPoDyn.jl, it serves as an interface between the MTK world and the NetworkDynamics world: A MTK model containing a BusBar
the highest level is consdered a busmodel (see isbusmodel
) and describes the dynamics of an entire bus. It can be transformed in a VertexModel
by calling Bus
.
OpPoDyn.LineEnd
— ConstantLineEnd
A ModelingToolkit model representing one end of a transmission line in power systems. It represents the physical connection point at the end of a transmission line.
Within OpPoDyn.jl, it serves as an interface between the MTK world and the NetworkDynamics world: A MTK model containing two LineEnd
s (named :src
and :dst
) at the highest level is considered a linemodel (see islinemodel
) and describes the dynamics of an entire line. It can be transformed in an EdgeModel
by calling Line
.
OpPoDyn.MTKBus
— FunctionMTKBus(injectors...; name=:bus)
Create a ModelingToolkit bus system by connecting multiple injector components.
Constructs a bus ODESystem by connecting all provided injector components to a central BusBar
. Each injector component must satisfy the injector model interface (see isinjectormodel
).
Arguments
injectors...
: Variable number of injector components (generators, loads, etc.)name=:bus
: Name for the resulting bus system
Returns
- An
ODESystem
representing the complete bus with all connected injectors
┌────────────────────┐
│MTKBus ┌─────────┐│
│ ┌┤Generator││
┌─────────┐ ┌────┐ │┌──────┐│└─────────┘│
MTKBus(o┤Generator│, o┤Load│) => ││BusBar├o │
└─────────┘ └────┘ │└──────┘│┌────┐ │
│ └┤Load│ │
│ └────┘ │
└────────────────────┘
See also: Bus
, BusBar
, isinjectormodel
OpPoDyn.MTKLine
— FunctionMTKLine(branches...; name=:line)
Create a ModelingToolkit line system by connecting multiple branch components.
Constructs a line ODESystem by connecting all provided branch components between source and destination line ends in parallel. Each branch component must satisfy the branch model interface.
Arguments
branches...
: Variable number of branch components (transmission lines, transformers, etc.)name=:line
: Name for the resulting line system
Returns
- An
ODESystem
representing the complete line with all connected branches
┌─────────────────────────────┐
│MTKLine ┌───────┐ │
│ ┌┤BranchA├┐ │
┌───────┐ ┌───────┐ │┌───────┐│└───────┘│┌───────┐│
MTKLine(o┤BranchA├o, o┤BranchB├o) => ││LineEnd├o o┤LineEnd││
└───────┘ └───────┘ │└───────┘│┌───────┐│└───────┘│
│ :src └┤BranchB├┘ :dst │
│ └───────┘ │
└─────────────────────────────┘
See also: Line
, LineEnd
, isbranchmodel
OpPoDyn.CompositeInjector
— FunctionCompositeInjector(systems, eqs=autoconnections(systems); name=Symbol(join(getname.(systems), "_")))
Create an injector object which contains several subsystems. Every subsystem which has a terminal
will be connected to a newly created terminal of the composite injector. The subsystems are namespaced within the composite injector.
There are two options for additional connections between the subsystems:
- interconnections will be created automatically using some name-matching heuristics using
autoconnections(systems)
: It searches allBlocks.RealOutput
andBlocks.RealInput
, and tries to find a single matching output for each input. - alternatively pass connecting equations of the form
[connect(sys1.output, sys2.input)]
explicitly
For example, one could create a composite injector with three subsystems:
- a generator,
- a controller, and
- a load;
which is augmented with 2 connection equations
- one for the measurements (generator -> controller), and
- one for the actuation (controller -> generator).
The returned model contains a new terminal :terminal
at the toplevel, thus satisfying the injector interface, see isinjectormodel
). It can be used as such in the MTKBus
constructor.
┌────────────────────────────────────┐
│ CompositeInjector │
│ ╭───→───╮ measurements│
│ ┌─────────┴─┐ ┌─┴──────────┐ │
(t) │ o─┤ Generator │ │ Controller │ │
o──┼──┤ └─────────┬─┘ └─┬──────────┘ │
│ │ ╰───←───╯ actuation │
│ │ ┌──────┐ │
│ o─┤ Load │ │
│ └──────┘ │
└────────────────────────────────────┘
Helpers
OpPoDyn.isbusmodel
— Functionisbusmodel(sys::ODESystem)
Check if an ODESystem satisfies the bus model interface.
A bus model must contain a component named :busbar
that satisfies the busbar interface. Bus models represent the complete dynamics of a power system bus and can be transformed into a VertexModel
using Bus
.
┌───────────────────────────┐
│BusModel ┌────────────┐│
│ ┌─┤ Injector 1 ││
│┌────────┐ │ └────────────┘│
││ BusBar ├─o │
│└────────┘ │ │
│ :busbar └ ... │
│ │
└───────────────────────────┘
Note: The BusModel musst contain exaclty one BusBar
, the rest of the structure is free. For example, you could also put a Brach between an injector and a Busbar or have multiple injectors and controllers connected.
OpPoDyn.isinjectormodel
— Functionisinjectormodel(sys::ODESystem)
Check if an ODESystem satisfies the injector model interface.
An injector model must contain a Terminal
named :terminal
. Injector models represent components like generators, loads, and other devices that connect to a single bus. They can have arbitrary internal complexity as long as they have exactly one terminal.
(t) ┌──────────┐
o─────┤ Injector │
:terminal └──────────┘
See also: Terminal
OpPoDyn.islinemodel
— Functionislinemodel(sys::ODESystem)
Check if an ODESystem satisfies the line model interface.
A line model must contain two components named :src
and :dst
that both satisfy the line end interface. Line models represent transmission lines and can be transformed into an EdgeModel
using Line
.
┌──────────────────────────────────────┐
│LineModel ┌────────┐ │
│ ┌─┤ Branch ├─┐ │
│┌─────────┐ │ └────────┘ │ ┌─────────┐│
││ LineEnd ├─o o─┤ LineEnd ││
│└─────────┘ │ │ └─────────┘│
│ :src └ .... ┘ :dst │
│ │
└──────────────────────────────────────┘
Note: Between the LineEnd
s there can be arbeitrary structures, for example branches in series or parallel.
OpPoDyn.isbranchmodel
— Functionisbranchmodel(sys::ODESystem)
Check if an ODESystem satisfies the branch model interface.
A branch model must contain two Terminal
components named :src
and :dst
. Branch models represent two-port network elements like transmission lines, transformers, and other connecting devices.
(t) ┌────────┐ (t)
o──┤ Branch ├──o
:src └────────┘ :dst
See also: Terminal
Powerflow Tools
Powerflow Components
OpPoDyn.pfSlack
— FunctionpfSlack(; V=missing, δ=missing, u_r=missing, u_i=missing)
Create a slack bus for power flow analysis.
A slack bus maintains constant voltage magnitude and phase angle (or real and imaginary voltage components). Either provide voltage magnitude V
and phase angle δ
, or provide real and imaginary voltage components u_r
and u_i
.
OpPoDyn.pfPV
— FunctionpfPV(; P, V)
Create a PV bus for power flow analysis.
A PV bus maintains constant active power injection and voltage magnitude. The reactive power and voltage phase angle are determined by the power flow solution.
OpPoDyn.pfPQ
— FunctionpfPQ(; P=0, Q=0)
Create a PQ bus for power flow analysis.
A PQ bus has specified active and reactive power injections. The voltage magnitude and phase angle are determined by the power flow solution.
Powerflow Helpers
OpPoDyn.solve_powerflow
— Functionsolve_powerflow(nw::Network;
pfnw = powerflow_model(nw),
pfs0 = NWState(nw),
verbose=true)
Solve the power flow equations for a given network.
Uses find_fixpoint
from NetworkDynamics to solve the algebraic power flow equations.
Parameters
nw
: The dynamic network modelpfnw
: The power flow network model (default: created fromnw
)pfs0
: Initial state for the power flow calculationverbose
: Whether to print the power flow solution
Returns
- A
NWState
containing the solved power flow solution
See also initialize_from_pf
.
OpPoDyn.initialize_from_pf
— Functioninitialize_from_pf[!](
nw::Network;
verbose = true,
subverbose = false,
pfnw = powerflow_model(nw),
pfs0 = NWState(pfnw),
pfs = solve_powerflow(pfnw; pfs0, verbose),
kwargs...
)
Initialize a dynamic network model from a power flow solution.
This function performs a two-step initialization process:
- Solve the power flow equations for the network
- Use the power flow solution to initialize the dynamic model
There are two versions of this function: a mutating one (!-at the end of name) and a non-mutating version. The mutating version uses initialize_componentwise!
internally, the non-mutating one initialize_componentwise
. When the mutating version is used, NWState(nw)
after initialization will return the same initialized state again, as it is stored in the metadata.
Parameters
nw
: The dynamic network model to initializeverbose
: Whether to print information about the power flow solution (default: true)subverbose
: Whether to print detailed information during component initialization (default: false). Can be Vector [VIndex(1), EIndex(3), ...] for selective outputpfnw
: Power flow network model (default: created fromnw
usingpowerflow_model
)pfs0
: Initial state for power flow calculation (default: created frompfnw
)pfs
: Power flow solution (default: calculated usingsolve_powerflow
)- Additional keyword arguments are passed to
initialize_componentwise[!]
Returns
- A fully initialized network state
See also: solve_powerflow
, initialize_componentwise
, interface_values
OpPoDyn.show_powerflow
— Functionshow_powerflow(s::NWState/Network)
Display power flow results in a tabular format.
Extract and format power flow solution data from a network state, showing bus-level information including voltage magnitudes, phase angles, active power, and reactive power.
OpPoDyn.powerflow_model
— Functionpowerflow_model(cf::NetworkDynamics.ComponentModel)
Extract or create a power flow component model from a dynamic component model.
- If the component has
:pfmodel
metadata, use that model (after validation) - If the component is already a valid power flow model (i.e. no ODE, just constraints), return it as-is
Returns
- A component model suitable for power flow analysis (no dynamics)
Validation
The returned model must satisfy ispfmodel
criteria:
- Either no states or zero mass matrix (no dynamics)
powerflow_model(nw::Network)
Create a power flow network model from a dynamic network model.
This method applies powerflow_model
to all vertex and edge components in the network, creating a new network suitable for steady-state power flow analysis.
Returns a new Network
with the same graph structure but power flow component models
See also: solve_powerflow
OpPoDyn.ispfmodel
— Functionispfmodel(cf::NetworkDynamics.ComponentModel)
Check if a component model is suitable for power flow analysis.
A component model is considered a valid power flow model if it has no dynamics, i.e., either no states or a zero mass matrix.
Returns
true
if the component is suitable for power flow analysisfalse
otherwise
Initialization
Powerflow dependent constraints and formulas
OpPoDyn.PFInitConstraint
— Typestruct PFInitConstraint{F}
PFInitConstraint(f, sym, pfsym, dim)
A representation of an additional constraint that is applied during the initialization phase of a component. In contrast to a InitConstraint
, this constraint may access additional variables which are available in the full NWState
of the solved power flow!
Crucially, this is only necessary for constraints, which cannot be expressed in terms of the interface variables (voltages and currents).
See also: @pfinitconstraint
for a macro to create such constraints, PFInitConstraint
, set_pfinitconstraint!
, add_pfinitconstraint!
OpPoDyn.@pfinitconstraint
— Macro@pfinitconstraint expr
@pfinitconstraint begin
constraint1
constraint2
end
Create a PFInitConstraint
using macro syntax. Component variables are accessed with :symbol
and power flow state variables with @pf :symbol
. Multiple constraints can be defined in a begin...end block.
See also: PFInitConstraint
, set_pfinitconstraint!
, add_pfinitconstraint!
OpPoDyn.PFInitFormula
— Typestruct PFInitFormula{F}
PFInitFormula(f, outsym, sym, pfsym)
A representation of an initialization formula that is applied during the initialization phase of a component. In contrast to a InitFormula
, this formula may access additional variables which are available in the full NWState
of the solved power flow!
Crucially, this is only necessary for formulas, which cannot be expressed in terms of the interface variables (voltages and currents).
Similar to InitFormula, this sets defaults rather than adding constraint equations. The formula is applied early in the initialization pipeline before constraints are solved.
See also: @pfinitformula
for a macro to create such formulas, PFInitFormula
, set_pfinitformula!
, add_pfinitformula!
OpPoDyn.@pfinitformula
— Macro@pfinitformula expr
@pfinitformula begin
:var1 = expr1
:var2 = expr2
end
Create a PFInitFormula
using macro syntax. Component variables are accessed with :symbol
and power flow state variables with @pf :symbol
. Multiple formulas can be defined in a begin...end block.
Unlike constraints, formulas use assignment syntax (:var = expression
) to set variable values during initialization. The left-hand side specifies output variables, and the right-hand side can access both component variables and power flow state variables.
See also: PFInitFormula
, set_pfinitformula!
, add_pfinitformula!
OpPoDyn.copy_pf_parameters
— Functioncopy_pf_parameters(cm::ComponentModel) -> PFInitFormula
Creates a PFInitFormula
that copies all parameters from the powerflow model to the component model. This formula can then be added to the component using add_pfinitformula!
.
This is useful for components where the powerflow and dynamic models should have identical parameter values, ensuring consistency between the two models.
See also: PFInitFormula
, add_pfinitformula!
Metadata Accesors
OpPoDyn.add_pfinitformula!
— Functionadd_pfinitformula!(c::NetworkDynamics.ComponentModel, formula::PFInitFormula) -> Bool
add_pfinitformula!(nw::Network, idx::Union{VIndex,EIndex}, formula) -> Bool
Adds a new initialization formula which depends on the powerflow solution to the component. If formulas already exist, the new formula is added to the existing ones. If no formulas exist, this is equivalent to set_pfinitformula!
.
Returns true
if the formula was successfully added, false
if it already exists.
See also set_pfinitformula!
, delete_pfinitformulas!
.
OpPoDyn.set_pfinitformula!
— Functionset_pfinitformula!(c::NetworkDynamics.ComponentModel, formula; check=true)
set_pfinitformula!(nw::Network, idx::Union{VIndex,EIndex}, formula; check=true)
Sets initialization formulas which depend on the powerflow solution to the component. Accepts either a single PFInitFormula
or a tuple of PFInitFormula
objects. Overwrites any existing pf formulas. See also delete_pfinitformulas!
, add_pfinitformula!
.
OpPoDyn.has_pfinitformula
— Functionhas_pfinitformula(c::ComponentModel)
has_pfinitformula(nw::Network, idx::Union{VIndex,EIndex})
Checks if the component has an initialization formula which depends on the pf state in metadata.
See also: get_pfinitformulas
, set_pfinitformula!
.
OpPoDyn.get_pfinitformulas
— Functionget_pfinitformulas(c::NetworkDynamics.ComponentModel)
get_pfinitformulas(nw::Network, idx::Union{VIndex,EIndex})
Retrieves the initialization formulas which depend on pf state for the component model. Returns a tuple of formulas, even if only one formula is present. May error if no formulas are present. Use has_pfinitformula
to check first.
See also: has_pfinitformula
, set_pfinitformula!
.
OpPoDyn.delete_pfinitformulas!
— Functiondelete_pfinitformulas!(c::NetworkDynamics.ComponentModel)
delete_pfinitformulas!(nw::Network, idx::Union{VIndex,EIndex})
Removes the powerflow dependent initialization formula from the component model, or from a component referenced by idx
in a network. Returns true
if the formula existed and was removed, false
otherwise.
See also: set_pfinitformula!
.
OpPoDyn.add_pfinitconstraint!
— Functionadd_pfinitconstraint!(c::NetworkDynamics.ComponentModel, constraint::PFInitConstraint) -> Bool
add_pfinitconstraint!(nw::Network, idx::Union{VIndex,EIndex}, constraint) -> Bool
Adds a new initialization constraint which depends on the powerflow solution to the component. If constraints already exist, the new constraint is added to the existing ones. If no constraints exist, this is equivalent to set_pfinitconstraint!
.
Returns true
if the constraint was successfully added, false
if it already exists.
See also set_pfinitconstraint!
, delete_pfinitconstraints!
.
OpPoDyn.set_pfinitconstraint!
— Functionset_pfinitconstraint!(c::NetworkDynamics.ComponentModel, constraint; check=true)
set_pfinitconstraint!(nw::Network, idx::Union{VIndex,EIndex}, constraint; check=true)
Sets initialization constraints which depend on the powerflow solution to the component. Accepts either a single PFInitConstraint
or a tuple of PFInitConstraint
objects. Overwrites any existing pf constraints. See also delete_pfinitconstraints!
, add_pfinitconstraint!
.
OpPoDyn.has_pfinitconstraint
— Functionhas_pfinitconstraint(c::ComponentModel)
has_pfinitconstraint(nw::Network, idx::Union{VIndex,EIndex})
Checks if the component has an initialization constraint which depends on the pf state in metadata.
See also: get_pfinitconstraints
, set_pfinitconstraint!
.
OpPoDyn.get_pfinitconstraints
— Functionget_pfinitconstraints(c::NetworkDynamics.ComponentModel)
get_pfinitconstraints(nw::Network, idx::Union{VIndex,EIndex})
Retrieves the initialization constraints which depend on pf state for the component model. Returns a tuple of constraints, even if only one constraint is present. May error if no constraints are present. Use has_pfinitconstraint
to check first.
See also: has_pfinitconstraint
, set_pfinitconstraint!
.
OpPoDyn.delete_pfinitconstraints!
— Functiondelete_pfinitconstraints!(c::NetworkDynamics.ComponentModel)
delete_pfinitconstraints!(nw::Network, idx::Union{VIndex,EIndex})
Removes the powerflow dependent initialization constraint from the component model, or from a component referenced by idx
in a network. Returns true
if the constraint existed and was removed, false
otherwise.
See also: set_pfinitconstraint!
.