Input Formats

CommmonOPF provides three ways to construct the Network Model model:

  1. YAML file(s)
  2. JSON file(s)
  3. Julia code (manual)

Only Network and Conductor are required to build the Network. Note that the input keys are, singular, CamelCase words to align with the data type names. For example a single phase, single time step model looks like:

Network:
  substation_bus: b1

Conductor:
  - name: cond1
    busses: 
      - b1
      - b2
    r1: 0.301  # impedance has units of ohm/per-unit-length
    x1: 0.627
    length: 100
  - busses:
      - b2
      - b3
    template: cond1  # <- reuse impedance of cond1
    length: 200

Load:
  - bus: b2
    kws1: 
      - 5.6  # you can specify more loads at each bus to add time steps
    kvars1: 
      - 1.2
  - bus: b3
    kws1: 
      - 5.6
    kvars1: 
      - 1.2

The Network(fp::String) constructor excepts a path to a yaml file.

Conductor

CommonOPF.ConductorType
struct Conductor <: AbstractEdge

Interface for conductors in a Network. Fieldnames can be provided via a YAML file, JSON file, or populated manually. Conductors are specified via two busses, the impedance in ohms per-unit length, and a length value.

Single phase models

The minimum inputs for a single phase conductor look like:

Conductor:
  - busses: 
      - b1
      - b2
    r1: 0.1
    x1: 0.1
    length: 100

Note that the order of the items in the YAML file does not matter.

A conductor can also leverage a template, i.e. another conductor with a name that matches the template value so that we can re-use the impedance values:

Conductor:
  - name: cond1
    busses: 
      - b1
      - b2
    r1: 0.1
    x1: 0.1
    length: 100
  - busses:
      - b2
      - b3
    template: cond1
    length: 200

The second conductor in the conductors above will use the r0 and x0 values from cond1, scaled by the length of 200 and normalized by Zbase.

Note

The name field is optional unless a conductor.name is also the template of another conductor.

Warning

If any phases properties are set in the conductors then it is assumed that the model is multi-phase.

Multi-phase models

Multi-phase conductors can be modeled as symmetrical or asymmetrical components. Similar to OpenDSS, line impedances can be specified via the zero and positive sequence impedances, (r0, x0) and (r1, x1) respectively; or via the lower-diagonal portion of the phase-impedance matrix.

Using the Multi-phase models requires specifying phases (and the zero and positive sequence impedances) like:

Conductor:
  - busses: 
      - b1
      - b2
    phases:
      - 2
      - 3
    r0: 0.766
    x0: 1.944
    r1: 0.301
    x1: 0.627
    length: 100

When the sequence impedances are provided the phase-impedance matrix is determined using the math in Symmetrical Mutliphase Conductors.

Alternatively one can specify the rmatrix and xmatrix like:

Conductor:
  - busses: 
      - b1
      - b2
    phases:
      - 1
      - 3
    rmatrix: 
      - [0.31]
      - [0.15, 0.32]
    xmatrix:
      - [1.01]
      - [0.5, 1.05]
    length: 100
Warning

The order of the phases is assumed to match the order of the rmatrix and xmatrix. For example using the example just above the 3x3 rmatrix looks like $[0.31, 0, 0.15; 0, 0, 0; 0.15, 0, 0.32]$

Conductors also have a cmatrix attribute that is used when parsing OpenDSS models. The cmatrix is used to define ShuntAdmittance values for busses.

source

Load

CommonOPF.LoadType
@with_kw mutable struct Load <: AbstractBus

A Load input specifier, mapped from YAML, JSON, or manually populated.

The minimum required inputs include several options. All require a bus to place the load. For single phase models provide one of the following sets of values:

  • bus, kws1
  • bus, kws1, kvars1
  • bus, kws1, q_to_p
  • bus, csv

where csv is a path to a two column CSV file with a single line header like "kws1,kvars1". If only bus and kws1 are provided then the reactive load will be zero in the power flow model.

For unbalanced multiphase models one must provide one of:

  • bus, [kws1, kvars1], [kws2, kvars2], [kws3, kvars3] <– brackets imply optional pairs, depending on the phases at the load bus
  • bus, csv

where the csv has 2, 4, or 6 columns with a single line header like "kws1,kvars1,kws2,kvars2,kws3,kvars3" or "kws2,kvars2,kws3,kvars3".

Note

The kws and kvars inputs are plural because we always put the loads in vectors, even with one timestep. We do this so that the modeling packages that build on CommonOPF do not have to account for both scalar values and vector values.

Once the net::Network is defined a load can be accessed like:

ld_busses = collect(load_busses(net))
lb = ld_busses[1]  # bus keys are strings in the network
net[lb, :kws, 1]  # last index is phase integer
source
Base.getindexMethod
function Base.getindex(net::Network, bus::String, kws_kvars::Symbol, phase::Int)

Load getter for Network. Use like:

net["busname", :kws, 2]

net["busname", :kvars, 3]

The second argument must be one of :kws or :kvars. The third arbument must be one of [1,2,3]. If the "busname" exists and has a :Load dict, but the load (e.g. :kvars2) is not defined then zeros(net.Ntimesteps) is returned.

source

Capacitor

CommonOPF.CapacitorType
struct Capacitor <: AbstractBus

Required fields:

  • bus::String
  • kvar1::Real reactive power in kVaR on phase1
  • kvar2::Real reactive power in kVaR on phase2
  • kvar3::Real reactive power in kVaR on phase4

Only modeling fixed capacitors so far. Positive kvar values are injected.

source

ShuntAdmittance

CommonOPF.ShuntAdmittanceType
struct ShuntAdmittance <: AbstractBus

Required fields:

  • bus::String
  • g::Real conductance in siemens
  • b::Real susceptance in siemens
source

Transformer

CommonOPF.TransformerType
@with_kw mutable struct Transformer <: AbstractEdge
    # required values
    busses::Tuple{String, String}
    # optional values
    high_kv::Real = 1.0
    low_kv::Real = 1.0
    phases::Union{Vector{Int}, Missing} = missing
    reactance::Real = 0.0
    resistance::Real = 0.0
end
Note

For now the high_kv and low_kv values are only for reference. Throughout the modules that use CommonOPF we model in per-unit voltage. In the future we may add capability for scaling to absolute voltage in the future (in Results for example).

When phases are not provided the model is assumed to be single phase.

Series impedance defaults to zero.

source

VoltageRegulator

CommonOPF.VoltageRegulatorType
struct VoltageRegulator <: AbstractEdge
    # required values
    busses::Tuple{String, String}
    # optional values
    high_kv::Real = 1.0
    low_kv::Real = 1.0
    phases::Union{Vector{Int}, Missing} = missing
    reactance::Real = 0.0
    resistance::Real = 0.0
    vreg_pu::Union{Real, AbstractVector{<:Number}, Missing} = missing
    turn_ratio::Union{Real, Missing} = missing
end

Required fields:

  • busses::Tuple{String, String}
  • either vreg_pu::Real or turn_ratio::Real

If vreg_pu is specified then the regulator is "perfect" and the second bus in busses is fixed to the value provided for vreg_pu.

If turn_ratio is provided then the voltage across the regulator is scaled by the turn_ratio.

Examples:

Julia Dict

netdict = Dict(
    :network => Dict(:substation_bus => "1", :Sbase => 1),
    :conductors => [
        ...
    ],
    :voltage_regulators => [
        Dict(
            :busses => ("2", "3")
            :vreg_pu => 1.05
        )
    ]
)

YAML file

Network:
  substation_bus: 0
  Sbase: 1

Conductor:
    ...

VoltageRegulator:
  busses: 
    - 2
    - 3
  vreg_pu: 1.05
source