Data Models

Parsers

PowerModelsDistribution.parse_fileFunction
parse_file(
    io::IO,
    filetype::Union{AbstractString,Missing}=missing;
    data_model::DataModel=ENGINEERING,
    import_all::Bool=false,
    bank_transformers::Bool=true,
    transformations::Vector{<:Any}=[],
    dss2eng_extensions::Vector{<:Function}=Function[],
    eng2math_extensions::Vector{<:Function}=Function[],
    eng2math_passthrough::Dict{String,Vector{String}}=Dict{String,Vector{String}}(),
    make_pu_extensions::Vector{<:Function}=Function[],
    make_pu::Bool=true,
    multinetwork::Bool=false,
    global_keys::Set{String}=Set{String}(),
    kron_reduce::Bool=true,
    phase_project::Bool=false,
    time_series::String="daily"
)::Dict{String,Any}

Parses the IOStream of a file into a PowerModelsDistribution data structure

If filetype is missing, parse_file will attempt to detect the filetype, but this may fail, and it is advised to pass the filetype if it is known.

If data_model is MATHEMATICAL, the data model type will be automatically transformed via transform_data_model.

For explanation of import_all, bank_transformers, and time_series, see parse_opendss

For explanation of dss2eng_extensions, see parse_opendss

For explanation of kron_reduce, see apply_kron_reduction!

For explanation of phase_project, see apply_phase_projection!

For explanation of multinetwork and global_keys, see make_multinetwork and transform_data_model

For explanation of eng2math_extensions and eng2math_passthrough, see transform_data_model

For explanation of make_pu and make_pu_extensions, see make_per_unit!.

source
parse_file(file::String; kwargs...)::Dict{String,Any}

Loads file into IOStream and passes it onto parse_file

source
PowerModelsDistribution.parse_dssFunction
parse_dss(filename::String)::Dict{String,Any}

Parses a OpenDSS file given by filename into a Dict{Array{Dict}}. Only supports components and options, but not commands, e.g. "plot" or "solve". Will also parse files defined inside of the originating DSS file via the "compile", "redirect" or "buscoords" commands.

source
parse_dss(io::IO)::Dict{String,Any}

Parses a OpenDSS file aleady in IO into a Dict{Array{Dict}}. Only supports components and options, but not commands, e.g. "plot" or "solve". Will also parse files defined inside of the originating DSS file via the "compile", "redirect" or "buscoords" commands.

source
PowerModelsDistribution.parse_opendssFunction
parse_opendss(
    io::IO;
    import_all::Bool=false,
    bank_transformers::Bool=true,
    time_series::String="daily",
    dss2eng_extensions::Vector{<:Function}=Function[],
)::Dict{String,Any}

Parses an IO, into raw dss dictionary via parse_dss, into the ENGINEERING DataModel

See parse_opendss

source
parse_opendss(
    data_dss::Dict{String,<:Any};
    import_all::Bool=false,
    bank_transformers::Bool=true,
    time_series::String="daily",
    dss2eng_extensions::Vector{<:Function}=Function[]
)::Dict{String,Any}

Parses a raw dss data structure (dictionary), resulting from the parsing of a DSS file, into the ENGINEERING DataModel

If import_all is true, all raw dss properties will be included in the final dictionary under "dss".

If bank_transformers is true (default), transformers that are indicated to be part of a bank in dss will be combined into a single multiphase transformer.

time_series defines which property the time series will be taken from, "daily" or "yearly". More complex parsing of time series data should be performed with dss2eng_extensions.

dss2eng_extensions

If a user wishes to parse additional components that are not yet natively supported by PowerModelsDistribution, dss2eng_extensions can be utilized. Custom user functions provided under dss2eng_extensions will be excuted after all built-in dss2eng transformations have been performed and transformers have been banked together (if bank_transformers==true). dss2eng_extension functions should have the following function signature:

dss2eng_func!(data_eng, data_dss)

where data_eng is a non-multinetwork ENGINEERING data model (i.e., time series data has not yet been expanded into a multinetwork structure), and data_dss is the raw dss data parsed by parse_dss.

source
PowerModelsDistribution.parse_jsonFunction
parse_json(file::String)

parses json files that were dumped via JSON.print (or PMD.print_file)

source
parse_json(io::IO)

parses json files that were dumped via JSON.print (or PMD.print_file)

source
PowerModelsDistribution.print_fileFunction
print_file(path::String, data::Dict{String,<:Any}; indent::Int=2)

prints a PowerModelsDistribution data structure into a JSON file

source
print_file(io::IO, data::Dict{String,<:Any}; indent::Int=2)

prints a PowerModelsDistribution data structure into a JSON file

source

Constructors

PowerModelsDistribution.add_object!Method
add_object!(data_eng::Dict{String,<:Any}, obj_type::String, obj_id::String, object::Dict{String,<:Any})

Generic add function to add components to an engineering data model

source
PowerModelsDistribution.create_al2w_transformerMethod
create_al2w_transformer(
    f_bus::String,
    t_bus::String,
    f_connections::Vector{Int},
    t_connections::Vector{Int};
    configuration::ConnConfig=WYE,
    tm_nom::Real=1.0,
    tm_lb::Union{Vector{<:Real},Missing}=missing,
    tm_ub::Union{Vector{<:Real},Missing}=missing,
    tm_set::Union{Vector{<:Real},Missing}=missing,
    tm_fix::Union{Vector{Bool},Missing}=missing,
    status::Status=ENABLED,
    kwargs...
)::Dict{String,Any}

creates a aysmmetric lossless 2-winding transformer object with some defaults

source
PowerModelsDistribution.create_busMethod
create_bus(;
    status::Status=ENABLED,
    terminals::Vector{Int}=Int[],
    grounded::Vector{Int}=Int[],
    rg::Vector{<:Real}=Float64[],
    xg::Vector{<:Real}=Float64[],
    kwargs...
)::Dict{String,Any}

creates a bus object with some defaults

source
PowerModelsDistribution.create_generatorMethod
create_generator(
    bus::String,
    connections::Vector{Int};
    configuration::ConnConfig=WYE,
    pg::Union{Vector{<:Real},Missing}=missing,
    qg::Union{Vector{<:Real},Missing}=missing,
    vg::Union{Vector{<:Real},Missing}=missing,
    pg_lb::Union{Vector{<:Real},Missing}=missing,
    pg_ub::Union{Vector{<:Real},Missing}=missing,
    qg_lb::Union{Vector{<:Real},Missing}=missing,
    qg_ub::Union{Vector{<:Real},Missing}=missing,
    control_mode::ControlMode=FREQUENCYDROOP,
    status::Status=ENABLED,
    kwargs...
)::Dict{String,Any}

creates a generator object with some defaults

source
PowerModelsDistribution.create_lineMethod
create_line(
    f_bus::String,
    t_bus::String,
    f_connections::Vector{Int},
    t_connections::Vector{Int};
    linecode::Union{String,Missing}=missing,
    rs::Union{Matrix{<:Real},Missing}=missing,
    xs::Union{Matrix{<:Real},Missing}=missing,
    g_fr::Union{Matrix{<:Real},Missing}=missing,
    b_fr::Union{Matrix{<:Real},Missing}=missing,
    g_to::Union{Matrix{<:Real},Missing}=missing,
    b_to::Union{Matrix{<:Real},Missing}=missing,
    length::Real=1.0,
    cm_ub::Union{Vector{<:Real},Missing}=missing,
    sm_ub::Union{Vector{<:Real},Missing}=missing,
    vad_lb::Union{Vector{<:Real},Missing}=missing,
    vad_ub::Union{Vector{<:Real},Missing}=missing,
    status::Status=ENABLED,
    kwargs...
)::Dict{String,Any}

Create a line with some default values

source
PowerModelsDistribution.create_linecodeMethod
create_linecode(
    rs::Matrix{<:Real},
    xs::Matrix{<:Real};
    g_fr::Union{Matrix{<:Real},Missing}=missing,
    b_fr::Union{Matrix{<:Real},Missing}=missing,
    g_to::Union{Matrix{<:Real},Missing}=missing,
    b_to::Union{Matrix{<:Real},Missing}=missing,
    cm_ub::Union{Vector{<:Real},Missing}=missing,
    kwargs...
)::Dict{String,Any}

creates a linecode with some defaults

source
PowerModelsDistribution.create_loadMethod
create_load(
    bus::String,
    connections::Vector{Int};
    configuration::ConnConfig=WYE,
    model::LoadModel=POWER,
    pd_nom::Union{Vector{<:Real},Missing}=missing,
    qd_nom::Union{Vector{<:Real},Missing}=missing,
    vm_nom::Real=1.0,
    dispatchable::Dispatchable=NO,
    status::Status=ENABLED,
    kwargs...
)::Dict{String,Any}

creates a load object with some defaults

source
PowerModelsDistribution.create_shuntMethod
create_shunt(
    bus::String,
    connections::Vector{Int};
    gs::Union{Matrix{<:Real},Missing}=missing,
    bs::Union{Matrix{<:Real},Missing}=missing,
    model::ShuntModel=GENERIC,
    dispatchable::Dispatchable=NO,
    status::Status=ENABLED,
    kwargs...
)::Dict{String,Any}

creates a generic shunt with some defaults

source
PowerModelsDistribution.create_solarMethod
create_solar(
    bus::String,
    connections::Vector{Int};
    configuration::ConnConfig=WYE,
    pg_lb::Union{Vector{<:Real},Missing}=missing,
    pg_ub::Union{Vector{<:Real},Missing}=missing,
    qg_lb::Union{Vector{<:Real},Missing}=missing,
    qg_ub::Union{Vector{<:Real},Missing}=missing,
    pg::Union{Vector{<:Real},Missing}=missing,
    qg::Union{Vector{<:Real},Missing}=missing,
    status::Status=ENABLED,
    kwargs...
)::Dict{String,Any}

creates a solar generator with some defaults

source
PowerModelsDistribution.create_storageMethod
create_storage(
    configuration::ConnConfig=WYE,
    energy::Real=0.0,
    energy_ub::Real=0.0,
    charge_ub::Real=0.0,
    discharge_ub::Real=0.0,
    sm_ub::Union{Real,Missing}=missing,
    cm_ub::Union{Real,Missing}=missing,
    charge_efficiency::Real=1.0,
    discharge_efficiency::Real=1.0,
    qs_lb::Union{Real,Missing}=missing,
    qs_ub::Union{Real,Missing}=missing,
    rs::Real=0.0,
    xs::Real=0.0,
    pex::Real=0.0,
    qex::Real=0.0,
    ps::Union{Real,Vector{<:Real},Missing}=missing,
    qs::Union{Real,Vector{<:Real},Missing}=missing,
    status::Status=ENABLED,
    kwargs...
    )::Dict{String,Any}

creates energy storage object with some defaults

source
PowerModelsDistribution.create_switchMethod
create_switch(
    f_bus::String,
    t_bus::String,
    f_connections::Vector{Int},
    t_connections::Vector{Int};
    cm_ub::Union{Vector{<:Real},Missing}=missing,
    sm_ub::Union{Vector{<:Real},Missing}=missing,
    linecode::Union{String,Missing}=missing,
    rs::Union{Matrix{<:Real},Missing}=missing,
    xs::Union{Matrix{<:Real},Missing}=missing,
    dispatchable::Dispatchable=NO,
    state::SwitchState=CLOSED,
    status::Status=ENABLED,
    kwargs...
)::Dict{String,Any}

creates a switch object with some defaults

source
PowerModelsDistribution.create_transformerMethod
create_transformer(
    buses::Vector{String},
    connections::Vector{Vector{Int}};
    configurations::Union{Vector{ConnConfig},Missing}=missing,
    xfmrcode::Union{String,Missing}=missing,
    xsc::Union{Vector{<:Real},Missing}=missing,
    rw::Union{Vector{<:Real},Missing}=missing,
    imag::Real=0.0,
    noloadloss::Real=0.0,
    tm_nom::Union{Vector{<:Real},Missing}=missing,
    tm_lb::Union{Vector{Vector{<:Real}},Missing}=missing,
    tm_ub::Union{Vector{Vector{<:Real}},Missing}=missing,
    tm_set::Union{Vector{Vector{<:Real}},Missing}=missing,
    tm_fix::Union{Vector{Vector{Bool}},Missing}=missing,
    polarity::Union{Vector{Int},Missing}=missing,
    vm_nom::Union{Vector{<:Real},Missing}=missing,
    sm_nom::Union{Vector{<:Real},Missing}=missing,
    status::Status=ENABLED,
    kwargs...
)::Dict{String,Any}

creates a n-winding transformer object with some defaults

source
PowerModelsDistribution.create_voltage_sourceMethod
create_voltage_source(
    bus::String,
    connections::Vector{Int};
    configuration::ConnConfig=WYE,
    vm::Union{Vector{<:Real},Missing}=missing,
    va::Union{Vector{<:Real},Missing}=missing,
    vm_lb::Union{Vector{<:Real},Missing}=missing,
    vm_ub::Union{Vector{<:Real},Missing}=missing,
    rs::Union{Vector{<:Real},Missing}=missing,
    xs::Union{Vector{<:Real},Missing}=missing,
    status::Status=ENABLED,
    kwargs...
)::Dict{String,Any}

creates a voltage source with some defaults

source
PowerModelsDistribution.create_xfmrcodeMethod
create_xfmrcode(;
    configurations::Union{Vector{ConnConfig},Missing}=missing,
    xsc::Union{Vector{<:Real},Missing}=missing,
    rw::Union{Vector{<:Real},Missing}=missing,
    tm_nom::Union{Vector{<:Real},Missing}=missing,
    tm_lb::Union{Vector{Vector{<:Real}},Missing}=missing,
    tm_ub::Union{Vector{Vector{<:Real}},Missing}=missing,
    tm_set::Union{Vector{Vector{<:Real}},Missing}=missing,
    tm_fix::Union{Vector{Vector{<:Real}},Missing}=missing,
    kwargs...
)::Dict{String,Any}

creates transformer code with some defaults

source

Model Transformations

PowerModelsDistribution.transform_data_modelFunction
transform_data_model(
    data::Dict{String,<:Any};
    kron_reduce::Bool=true,
    multinetwork::Bool=false,
    global_keys::Set{String}=Set{String}(),
    eng2math_passthrough::Dict{String,<:Vector{<:String}}=Dict{String,Vector{String}}(),
    eng2math_extensions::Vector{<:Function}=Function[],
    make_pu::Bool=true,
    make_pu_extensions::Vector{<:Function}=Function[],
)::Dict{String,Any}

Transforms a data model model between ENGINEERING (high-level) and MATHEMATICAL (low-level) DataModel.

Notes

Kron reduction

If kron_reduce==true, apply_kron_reduction! and apply_phase_projection_delta! will be applied to the network data.

Phase projection

If phase_project==true, apply_phase_projection! will be applied to the network data.

Multinetwork transformations

If multinetwork==true, the data model will be transformed into a multinetwork (e.g., time series) data structure using make_multinetwork before being transformed into a MATHEMATICAL DataModel.

global_keys::Set{String} can be used to add custom top-level items to the multinetwork data structure, and will only be used in the context where multinetwork==true, and ignored otherwise.

Custom eng2math transformations

To add custom transformations between ENGINEERING and MATHEMATICAL data models, eng2math_extensions::Vector{<:Function} can be utilized to pass user-created functions, which are expected to have the signature

eng2math_func!(data_math::Dict{String,Any}, data_eng::Dict{String,Any})

where datamath and dataeng equivalent to single subnetworks in a multinetwork data structure, or a non-multinetwork data structure.

These functions are run after all built-in eng2math transformations have been performed.

Mapping back to ENGINEERING

See transform_solution

Passthrough properties

To more simply pass through some properties in the built-in eng2math transformations, eng2math_passthrough::Dict{String,Vector{String}} can be used. For example, if in the ENGINEERING model, a property called z was added to switch objects, and a property at the root level of the dictionary was added called max_switch_actions, the user could pass the following dictionary to eng2math_passthrough:

Dict{String,Vector{String}}(
    "switch" => String["z"],
    "root" => String["max_switch_actions"],
)

This will result in z showing up on the switch object in the MATHEMATICAL model. Passthrough properties will always land on the primary conversion object in the MATHEMATICAL model if that object gets converted to multiple object types, e.g., voltage_source with internal impedance will result in gen, bus, and branch objects in the MATHEMATICAL model, but passthrough properties will only land on gen.

Custom per-unit transformations

To add additional per-unit transformations, a user can supply custom functions to make_pu_extensions::Vector{<:Function}, which will only be used if make_pu==true.

See make_per_unit! for further explanation.

source
PowerModelsDistribution.transform_solutionFunction
transform_solution(
    solution_math::Dict{String,<:Any},
    data_math::Dict{String,<:Any};
    map::Union{Vector{<:Dict{String,<:Any}},Missing}=missing,
    make_si::Bool=true,
    convert_rad2deg::Bool=true,
    map_math2eng_extensions::Dict{String,<:Function}=Dict{String,Function}(),
    make_si_extensions::Vector{<:Function}=Function[],
    dimensionalize_math_extensions::Dict{String,<:Dict{String,<:Vector{<:String}}}=Dict{String,Dict{String,Vector{String}}}(),
    )::Dict{String,Any}

Transforms solutions from MATHEMATICAL data structures, back to an ENGINEERING data structure, given a map::Vector{Dict{String,Any}}, typically which was produced automatically by transform_data_model.

Notes

If make_si==false, the solution will remain in per-unit, rather than being converted back to SI units (default). Angles will still be converted to degrees unless convert_rad2deg is utilized.

If convert_rad2deg==false, angles will remain in radians, instead of getting converted to degrees (default).

Custom SI unit conversions

See solution_make_si

Custom math2eng transformations

To enable automatically mapping back custom components solutions' to the ENGINEERING structure, eng2math_extensions added in transform_data_model should include a push of an item to the map dictionary in the data_math structure. These items should have the structure:

Dict{String,Any}(
    "from" => String,
    "to" => Union{String,Vector{String}},
    "unmap_function" => PowerModelsDistribution.function!,
    "apply_to_subnetworks" => Bool
)

Important things to note are that

  1. The function must be included in map_math2eng_extensions, which has the form:

    julia Dict{String,Function}( "_map_math2eng_func!" => _map_math2eng_func!, )

  2. "apply_to_subnetworks" is optional, and is true by default.

  3. "from" needs to be a single object

  4. "to" can be multiple objects or a single object

source

Data Transformations

PowerModelsDistribution.add_bus_absolute_vbounds!Method
add_bus_absolute_vbounds!(
    data_eng::Dict{String,Any};
    phase_lb_pu::Real=0.9,
    phase_ub_pu::Real=1.1,
    neutral_ub_pu::Real=0.3
)::Dict{String,Any}

Adds absolute (i.e. indivdially, not between a pair of terminals) voltage bounds through the 'vmlb' and 'vmub' property. Bounds are specified in per unit, and automatically converted to SI units by calculating the voltage base. If you change dataeng["settings"]["vbasesdefault"], the data model transformation will however produce inconsistent bounds in per unit. Neutral terminals are automatically detected, and set to [0,phaseubpu*vbase].

source
PowerModelsDistribution.add_bus_pn_pp_ng_vbounds!Method
add_bus_pn_pp_ng_vbounds!(data_eng::Dict{String,Any}, phase_terminals::Vector, neutral_terminal;
    pn_lb_pu::Union{Real,Missing}=missing,
    pn_ub_pu::Union{Real,Missing}=missing,
    pp_lb_pu::Union{Real,Missing}=missing,
    pp_ub_pu::Union{Real,Missing}=missing,
    ng_ub_pu::Union{Real,Missing}=missing,
)::Dict{String,Any}

Adds symmetric phase-to-neutral and phase-to-phase voltage bounds when possible for each bus through the three-phase bus syntax.

source
PowerModelsDistribution.add_start_voltage!Method
add_start_voltage!(
    data_math::Dict{String,Any};
    coordinates=:rectangular,
    uniform_v_start=missing,
    vr_default=0.0,
    vi_default=0.0,
    vm_default=0.0,
    va_default=0.0,
    epsilon::Number=1E-3,
)::Dict{String,Any}

Adds start values for the voltage to the buses. For a multinetwork data model, you can calculate the start voltages for a representative network through 'calcstartvoltage', and pass the result as 'uniformvstart' to use the same values for all networks and avoid recalculating it for each network. The argument 'epsilon' controls the offset added to ungrounded terminals which would otherwise be set to zero.

source
PowerModelsDistribution.add_start_vrvi!Method
add_start_vrvi!(data_math::Dict{String,Any}; kwargs...)

Short-hand for [`add_start_voltage`](@ref add_start_voltage) with rectangular coordinates (coordinates=:rectangular).
source
PowerModelsDistribution.add_unit_vbounds!Method
add_unit_vbounds!(
    data_eng::Dict{String,Any};
    lb_pu::Real=0.9,
    ub_pu::Real=1.1,
    delta_multiplier::Real=sqrt(3),
    unit_comp_types::Vector{<:AbstractString}=["load", "generator", "storage", "pv"],
)::Dict{String,Any}

Adds voltage bounds to the bus terminals to which units are connected. 'Units' in this context are all oneport component types specified by the argument 'unitcomptypes'. Bounds are specified in per unit, and automatically converted to SI units by calculating the voltage base. If you change dataeng["settings"]["vbasesdefault"], the data model transformation will however produce inconsistent bounds in per unit. The delta multiplier controls the scaling of bounds of delta-connected units.

source
PowerModelsDistribution.adjust_small_line_admittances!Method
adjust_small_line_admittances!(data::Dict{String,<:Any}; min_admittance_val::Float64=1e-2, replace_admittance_val::Float64=0.0)

Replaces admittances (gfr, gto, bfr, bto) on lines, linecodes, and switches lower than min_admittance_val with replace_admittance_val.

source
PowerModelsDistribution.adjust_small_line_impedances!Method
adjust_small_line_impedances!(data::Dict{String,<:Any}; min_impedance_val::Float64=1e-2, replace_impedance_val::Float64=0.0)

Replaces impedances (rs, xs) on lines, linecodes, and switches lower than min_impedance_val with replace_impedance_val.

source
PowerModelsDistribution.apply_kron_reduction!Method
apply_kron_reduction!(data::Dict{String,<:Any}; kr_phases::Union{Vector{Int},Vector{String}}=[1,2,3], kr_neutral::Union{Int,String}=4)

Applies a Kron Reduction to the network, reducing out the kr_neutral, leaving only the kr_phases

source
PowerModelsDistribution.apply_voltage_bounds!Method
apply_voltage_bounds!(data::Dict{String,<:Any}; vm_lb::Union{Real,Missing}=0.9, vm_ub::Union{Real,Missing}=1.1)

add voltage bounds to all buses based on per-unit upper (vm_ub) and lower (vm_lb), scaled by the bus's voltage based

source
PowerModelsDistribution.calc_start_voltageMethod
calc_start_voltage(
    data_math::Dict{String,Any};
    max_iter=Inf,
    epsilon::Number=1E-3
)::Dict{Tuple{Int,Any},Union{Complex,Missing}}

Calculate no-load starting values for all bus-terminals pairs.

source
PowerModelsDistribution.get_defined_busesMethod
get_defined_buses(data_eng::Dict{String,Any}; comp_types=pmd_eng_asset_types)::Vector{String}

Returns a unique list of all buses specified in the data model. The argument 'comp_types' specifies which component types are searched to build the list.

source
PowerModelsDistribution.kron_reduce_implicit_neutrals!Method
kron_reduce_implicit_neutrals!(data::Dict{String,Any})::Dict{String,Any}

Kron-reduce all (implied) neutral conductors of lines, switches and shunts, and remove any terminals which become unconnected. A line or switch conductor is considered as a neutral conductor if it is connected between two neutral terminals. A terminal is a neutral terminals if it is galvanically connected (i.e. through a line or switch) to a grounded terminal, or the neutral conductor of a wye-connected component.

source
PowerModelsDistribution.make_lossless!Method
make_lossless!(data_eng::Dict{String,<:Any})

Remove parameters from objects with loss models to make them lossless. This includes linecodes, lines, switches, xfmrcodes, transformers, voltage sources, generators, solar, and storage, which all have (or will have in the future), loss model parameters that can be omitted.

source
PowerModelsDistribution.remove_all_bounds!Method
remove_all_bounds!(data; exclude::Vector{<:String}=String["energy_ub"], exclude_asset_type::Vector{String}=String[])

Removes all fields ending in 'ub' or 'lb' that aren't required by the math model. Properties can be excluded from this removal with exclude::Vector{String}

Whole asset types (e.g., "line") can be excluded using the keyword argument exclude_asset_type::Vector{String}

By default, "energy_ub" is excluded from this removal, since it is a required properly on storage.

source
PowerModelsDistribution.transform_loops!Method
transform_loops!(
    data::Dict{String,Any};
    zero_series_impedance_threshold::Real=1E-8,
    shunt_id_prefix::AbstractString="line_loop"
)::Dict{String,Any}

Transform line loops (connected to a single bus), which are not allowed in the mathematical model. Lossy line loops are converted to equivalent shunts, and lossless ones (i.e. short-circuits) are represented by merging the short-circuited terminals. The argument 'zeroseriesimpedance_threshold' controls the threshold below which the series impedance is considered to be a short-ciruit. This is useful because OpenDSS modelers have to insert tiny impedances to represent short-circuit reactors. The addmittance to ground should be zero to trigger the short-circuit handling.

source

Multinetworks

PowerModelsDistribution.make_multinetworkMethod
make_multinetwork(
    data::Dict{String,<:Any};
    sparse::Bool=false,
    time_elapsed::Union{Missing,Real,Vector{<:Real}}=missing,
    global_keys::Set{String}=Set{String}(),
)::Dict{String,Any}

Expands a data structure into a multinetwork assuming there are time_series objects defined and assigned to some components.

If global_keys::Set{String} is defined, the global keys that will appear at the top-level of the data structure will include both the default global keys for that data model type, and additionally the keys defined in global_keys.

time_elapsed defines the time elapsed between subnetworkin hours, and can either be a single Real value, and thus a constant time between each time step, or a Vector with the same length as the number of time steps, or can be left missing, in which case time elapsed will attempt to be discovered, with a fallback on 1 hour default. Time elapsed can be adjusted later using set_time_elapsed!

make_multinetwork assumes all "time" values in "timeseries" objects to be in the same units, and will attempt to automatically sort multinetworks in the correct order. [`sortmultinetwork!`](@ref sort_multinetwork!) can be used after the fact to re-sort the subnetworks.

sparse is currently unsupported, and is only included for future compatibility

source
PowerModelsDistribution.set_time_elapsed!Method
set_time_elapsed!(data::Dict{String,<:Any}, time_elapsed::Union{Real,Vector{<:Real}})

Helper function to set time_elapsed in multinetwork data, given either some constant value of time elapsed or a Vector of time elapsed values of the same length as the number of subnetworks.

source

Unit conversions

PowerModelsDistribution.calc_eng_voltage_basesMethod
calc_eng_voltage_bases(data_model::Dict{String,<:Any}, vbase_sources::Dict{String,<:Real})::Tuple{Dict,Dict}

Calculates voltage bases for each voltage zone for buses and branches for a ENGINEERING data_model

source
PowerModelsDistribution.calc_math_voltage_basesMethod
calc_math_voltage_bases(data_model::Dict{String,<:Any}, vbase_sources::Dict{String,<:Real})::Tuple{Dict,Dict}

Calculates voltage bases for each voltage zone for buses and branches for a MATHEMATICAL data_model

source
PowerModelsDistribution.calc_voltage_basesMethod
calc_voltage_bases(data_model::Dict{String,<:Any}, vbase_sources::Dict{String,<:Real})::Tuple{Dict,Dict}

Calculates voltage bases for each voltage zone for buses and branches, attempting to automatically decern the data_model type

source
PowerModelsDistribution.discover_voltage_zonesMethod
discover_voltage_zones(data_model::Dict{String,<:Any})::Dict{Int,Set{Any}}

finds voltage zones by walking through the network and analyzing the transformers, attempting to decern the type of data_model

source
PowerModelsDistribution.make_per_unit!Method
make_per_unit!(
    data::Dict{String,Any};
    vbases::Union{Missing,Dict{String,Real}}=missing,
    sbase::Union{Missing,Real}=missing,
    make_pu_extensions::Vector{<:Function}=Function[],
)

Converts units of properties to per-unit from SI units

make_pu_extensions

To add additional per-unit transformations, a user can supply custom functions to make_pu_extensions::Vector{<:Function}, which will only be used if make_pu==true.

For example, if custom properties are added to the MATHEMATICAL model via eng2math_passthrough or eng2math_extensions, those properties will not be converted to per-unit by default, and custom rules will need to be added with functions with the signature:

rebase_pu_func!(
    nw::Dict{String,Any},
    data_math::Dict{String,Any},
    bus_vbase::Dict{String,Real},
    line_vbase::Dict{String,Real},
    sbase::Real,
    sbase_old::Real,
    voltage_scale_factor::Real
)

where,

  • nw is equivalent to the a single subnetwork in a multinetwork data structure (which may be the same as data_math, in the case of a single network),
  • data_math is the complete data structure with the global keys,
  • bus_vbase is a dictionary of the voltage bases of each bus indexed by their MATHEMATICAL model indices,
  • line_vbase is a dictionary of the voltage bases of each branch indexed by their MATHEMATICAL model indices,
  • sbase is the new power base,
  • sbase_old is the power base the data structure started with, and
  • voltage_scale_factor is the scaling factor for voltage.
source
PowerModelsDistribution.solution_make_siMethod
solution_make_si(
    solution::Dict{String,<:Any},
    math_model::Dict{String,<:Any};
    mult_sbase::Bool=true,
    mult_vbase::Bool=true,
    mult_ibase::Bool=true,
    convert_rad2deg::Bool=true,
    make_si_extensions::Vector{<:Function}=Function[],
    dimensionalize_math_extensions::Dict{String,<:Dict{String,<:Vector{<:String}}}=Dict{String,Dict{String,Vector{String}}}()
)::Dict{String,Any}

Transforms solution dictionaries solution from per-unit back to SI units, requiring the original MATHEMATICAL model math_model to perform the transformation.

If mult_sbase is false, sbase variables will not be multiplied, thus remaining in per-unit

If mult_vbase is false, vbase variables will not be multiplied, thus remaining in per-unit

If mult_ibase is false, ibase variables will not be multiplied, thus remaining in per-unit

If convert_rad2deg is false, angle variables will not be multiplied, thus remaining in radians

Custom SI unit conversions

To convert custom properties not part of formulations already included within PowerModelsDistribution, users will need to either specify multiplicative factors via dimensionalize_math_extensions, or pass user functions via make_si_extensions.

The latter case requires functions with the signature

make_si_func!(nw_solution, nw_data, solution, data)

where nw_solution and nw_data are equivalent to a single subnetwork of a multinetwork structure of the solution and the data in the MATHEMATICAL format, respectively, and solution and data are the full data structures, which may be equivalent to nw_solution and nw_data, if the data is not multinetwork. Changes should be applied to nw_solution in the user functions.

For dimensionalize_math_extensions, it is possible to easily extended the SI conversions if they are straightforward conversions using vbase, sbase, ibase, or rad2deg. For example, if a custom variable cfr is added to branches, and is scaled by ibase, the following dictionary would be passed:

Dict{String,Dict{String,Vector{String}}}(
    "branch" => Dict{String,Vector{String}}(
        "ibase" => String["cfr"]
    )
)

which would ensure that this variable gets converted back to SI units upon transformation.

source

Data Checking and Correction

PowerModelsDistribution.correct_bus_types!Method

checks bus types are suitable for a power flow study, if not, fixes them. the primary checks are that all type 2 buses (i.e., PV) have a connected and active generator and there is a single type 3 bus (i.e., slack bus) with an active connected generator. assumes that the network is a single connected component

source
PowerModelsDistribution.correct_network_data!Method
correct_network_data!(data::Dict{String,Any}; make_pu::Bool=true, make_pu_extensions::Vector{<:Function}=Function[])

Makes corrections and performs checks on network data structure in either ENGINEERING or MATHEMATICAL formats, and converts to per-unit if data a is MATHEMATICAL data model.

If make_pu is false, converting to per-unit will be skipped.

Custom per-unit transformations

See make_per_unit!

source

Statistics and Analysis

PowerModelsDistribution.calc_connected_componentsFunction
calc_connected_components(data::Dict{String,<:Any}; edges::Union{Missing, Vector{<:String}}=missing, type::Union{Missing,String}=missing, check_enabled::Bool=true)::Set

computes the connected components of the network graph returns a set of sets of bus ids, each set is a connected component

source

Helper Functions

PowerModelsDistribution.discover_voltage_zonesFunction
discover_voltage_zones(data_model::Dict{String,<:Any})::Dict{Int,Set{Any}}

finds voltage zones by walking through the network and analyzing the transformers, attempting to decern the type of data_model

source
PowerModelsDistribution.calc_voltage_basesFunction
calc_voltage_bases(data_model::Dict{String,<:Any}, vbase_sources::Dict{String,<:Real})::Tuple{Dict,Dict}

Calculates voltage bases for each voltage zone for buses and branches, attempting to automatically decern the data_model type

source
PowerModelsDistribution.apply_pmd!Function
apply_pmd!(func!::Function, data::Dict{String,<:Any}; apply_to_subnetworks::Bool=true, kwargs...)

Version of apply_pmd! that supports kwargs

source
apply_pmd!(func!::Function, data::Dict{String,<:Any}; apply_to_subnetworks::Bool=true, kwargs...)

Version of apply_pmd! that supports kwargs

source
apply_pmd!(func!::Function, data::Dict{String,<:Any}, args...; apply_to_subnetworks::Bool=true, kwargs...)

Version of apply_pmd! that supports args and kwargs

source
apply_pmd!(func!::Function, ref::Dict{Symbol,<:Any}, data::Dict{String,<:Any}; apply_to_subnetworks::Bool=true)

PowerModelsDistribution wrapper for the InfrastructureModels apply! function

source