Data Models
Parsers
PowerModelsDistribution.parse_file
— Functionparse_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!
.
parse_file(file::String; kwargs...)::Dict{String,Any}
Loads file into IOStream and passes it onto parse_file
PowerModelsDistribution.parse_dss
— FunctionPowerModelsDistribution.parse_opendss
— Functionparse_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
parse_opendss(
data_dss::OpenDssDataModel;
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
.
PowerModelsDistribution.parse_json
— Functionparse_json(file::String)
parses json files that were dumped via JSON.print (or PMD.print_file)
parse_json(io::IO)
parses json files that were dumped via JSON.print (or PMD.print_file)
PowerModelsDistribution.print_file
— Functionprint_file(path::String, data::Dict{String,<:Any}; indent::Int=2)
prints a PowerModelsDistribution data structure into a JSON file
print_file(io::IO, data::Dict{String,<:Any}; indent::Int=2)
prints a PowerModelsDistribution data structure into a JSON file
print_file variant for InfrastructureModel that converts to Dict first
Constructors
PowerModelsDistribution.Model
— FunctionModel(model_type::DataModel)
Instantiates a PowerModelsDistribution data model
PowerModelsDistribution.add_bus!
— Functionadds a bus to provided ENGINEERING model, see create_bus
PowerModelsDistribution.add_generator!
— Functionadds a generator to provided ENGINEERING model, see create_generator
PowerModelsDistribution.add_line!
— Functionadds a line to provided ENGINEERING model, see create_line
PowerModelsDistribution.add_linecode!
— Functionadds a linecode to provided ENGINEERING model, see create_linecode
PowerModelsDistribution.add_load!
— Functionadds a load to provided ENGINEERING model, see create_load
PowerModelsDistribution.add_object!
— Methodadd_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
PowerModelsDistribution.add_shunt!
— Functionadds a shunt to provided ENGINEERING model, see create_shunt
PowerModelsDistribution.add_solar!
— Functionadds a PV to provided ENGINEERING model, see create_solar
PowerModelsDistribution.add_storage!
— Functionadds a storage to provided ENGINEERING model, see create_storage
PowerModelsDistribution.add_switch!
— Functionadds a switch to provided ENGINEERING model, see create_switch
PowerModelsDistribution.add_transformer!
— Functionadds a transformer to provided ENGINEERING model, see create_transformer
and create_al2w_transformer
PowerModelsDistribution.add_vbase_default!
— Methodadd_vbase_default!(data_eng::Dict{String,<:Any}, bus::String, vbase::Real)
Function to add default vbase for a bus
PowerModelsDistribution.add_voltage_source!
— Functionadds a voltage source to provided ENGINEERING model, see create_voltage_source
PowerModelsDistribution.add_xfmrcode!
— Functionadds a transformer code (xmfrcode) to provided ENGINEERING model, see create_xfmrcode
PowerModelsDistribution.create_al2w_transformer
— Methodcreate_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
PowerModelsDistribution.create_bus
— Methodcreate_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
PowerModelsDistribution.create_generator
— Methodcreate_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
PowerModelsDistribution.create_line
— Methodcreate_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
PowerModelsDistribution.create_linecode
— Methodcreate_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
PowerModelsDistribution.create_load
— Methodcreate_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
PowerModelsDistribution.create_shunt
— Methodcreate_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
PowerModelsDistribution.create_solar
— Methodcreate_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
PowerModelsDistribution.create_storage
— Methodcreate_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
PowerModelsDistribution.create_switch
— Methodcreate_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
PowerModelsDistribution.create_transformer
— Methodcreate_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
PowerModelsDistribution.create_voltage_source
— Methodcreate_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
PowerModelsDistribution.create_xfmrcode
— Methodcreate_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
PowerModelsDistribution.delete_component!
— Methoddelete_component!(data_eng::Dict{String,<:Any}, component_type::String, component_id::String)
deletes a component from the engineering data model
Model Transformations
PowerModelsDistribution.transform_data_model
— Functiondefault transform_data_model
ErrorException for unsupported combinations
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
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.
PowerModelsDistribution.transform_solution
— Functiontransform_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
The function must be included in
map_math2eng_extensions
, which has the form:julia Dict{String,Function}( "_map_math2eng_func!" => _map_math2eng_func!, )
"apply_to_subnetworks"
is optional, and is true by default."from"
needs to be a single object"to"
can be multiple objects or a single object
Data Transformations
PowerModelsDistribution.reduce_line_series!
— Methodreduce_line_series!(eng::Dict{String,<:Any}; remove_original_lines::Bool=false)::Dict{String,<:Any}
This is a function to merge series of lines which only connect to buses with no other connections (i.e., string of buses with no loads, generators, transformers, etc.). This function will preserve the total length of the merged lines.
If remove_original_lines
, the original lines and eliminated buses will be deleted from the data structure, otherwise the lines and buses will be DISABLED
.
PowerModelsDistribution.apply_kron_reduction!
— Methodapply_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
PowerModelsDistribution.kron_reduce_implicit_neutrals!
— Methodkron_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.
PowerModelsDistribution.add_bus_absolute_vbounds!
— Methodadd_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].
PowerModelsDistribution.add_bus_pn_pp_ng_vbounds!
— Methodadd_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.
PowerModelsDistribution.add_unit_vbounds!
— Methodadd_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.
PowerModelsDistribution.adjust_line_limits!
— Methodadjust_line_limits!(data::Dict{String,<:Any}, mult::Real)
Multiplies limits (sm_ub
and/or cm_ub
) on line objects (line
, linecode
, switch
) by a multiplier mult
PowerModelsDistribution.adjust_small_line_admittances!
— Methodadjust_small_line_admittances!(data::Dict{String,<:Any}; min_admittance_val::Real=1e-2, replace_admittance_val::Real=0.0)
Replaces admittances (gfr, gto, bfr, bto) on lines, linecodes, and switches lower than min_admittance_val
with replace_admittance_val
.
PowerModelsDistribution.adjust_small_line_impedances!
— Methodadjust_small_line_impedances!(data::Dict{String,<:Any}; min_impedance_val::Real=1e-2, replace_impedance_val::Real=0.0)
Replaces impedances (rs, xs) on lines, linecodes, and switches lower than min_impedance_val
with replace_impedance_val
.
PowerModelsDistribution.adjust_small_line_lengths!
— Methodadjust_small_line_lengths!(data::Dict{String,<:Any}; min_length_val::Real=25.0, replace_length_val::Real=0.0)
Replaces length on lines, switches lower than min_length_val
with replace_length_val
.
PowerModelsDistribution.adjust_transformer_limits!
— Methodadjust_transformer_limits!(data::Dict{String,<:Any}, mult::Real)
Multiplies limits (sm_ub
and/or cm_ub
) on transformer objects by a multiplier mult
PowerModelsDistribution.apply_voltage_angle_difference_bounds!
— Functionapply_voltage_angle_difference_bounds!(data::Dict{String,<:Any}, vad::Real=5.0)
Applies voltage angle difference bound given by vad::Real
in degrees (i.e., the allowed drift of angle from one end of a line to another) to all lines. By default, vad=5.0
.
PowerModelsDistribution.apply_voltage_bounds!
— Methodapply_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
PowerModelsDistribution.remove_all_bounds!
— Methodremove_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.
PowerModelsDistribution.remove_line_limits!
— Methodremove_line_limits!(data::Dict{String,<:Any})
Removes fields cm_ub
and sm_ub
from lines, switches, and linecodes
PowerModelsDistribution.remove_transformer_limits!
— Methodremove_transformer_limits!(data_eng::Dict{String,<:Any})
Removes field sm_ub
from transformers, xfmrcodes
Multinetworks
InfrastructureModels.ismultinetwork
— Methodismultinetwork(pm::AbstractUnbalancedPowerModel)
Checks if power model struct is multinetwork
PowerModelsDistribution.make_multinetwork
— Methodmake_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
PowerModelsDistribution.set_time_elapsed!
— Methodset_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.
PowerModelsDistribution.sort_multinetwork!
— Methodsort_multinetwork!(mn_data::Dict{String,<:Any}, times::Vector{<:Any})
Helper function to manually sort your multinetwork frames, given some pre-sorted vector of time values times
Unit conversions
PowerModelsDistribution.calc_eng_voltage_bases
— Methodcalc_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
PowerModelsDistribution.calc_math_voltage_bases
— Methodcalc_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
PowerModelsDistribution.calc_voltage_bases
— Methodcalc_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
PowerModelsDistribution.discover_eng_voltage_zones
— Methoddiscover_voltage_zones(data_model::Dict{String,<:Any})::Dict{Int,Set{Any}}
finds voltage zones by walking through the network and analyzing the transformers for a ENGINEERING data_model
PowerModelsDistribution.discover_math_voltage_zones
— Methoddiscover_math_voltage_zones(data_model::Dict{String,<:Any})::Dict{Int,Set{Any}}
finds voltage zones by walking through the network and analyzing the transformers for a MATHEMATICAL data_model
PowerModelsDistribution.discover_voltage_zones
— Methoddiscover_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
PowerModelsDistribution.make_per_unit!
— Methodmake_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 asdata_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, andvoltage_scale_factor
is the scaling factor for voltage.
PowerModelsDistribution.solution_make_si
— Methodsolution_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.
Data Checking and Correction
PowerModelsDistribution.check_branch_loops
— Methodcheck_branch_loops(data::Dict{String,<:Any})
checks that all branches connect two distinct buses
PowerModelsDistribution.check_connectivity
— Methodcheck_connectivity(data::Dict{String,<:Any})
checks that all buses are unique and other components link to valid buses
PowerModelsDistribution.check_cost_models
— Methodcheck_cost_models(pm::AbstractUnbalancedPowerModel)
Checks that all cost models are of the same type
PowerModelsDistribution.check_eng_data_model
— Methodcheck_eng_data_model(data_eng::Dict{String,<:Any})
checks the engineering data model for correct data types, required fields and applies default checks
PowerModelsDistribution.check_gen_cost_models
— Methodcheck_gen_cost_models(pm::AbstractUnbalancedPowerModel)
Checks that all generator cost models are of the same type
PowerModelsDistribution.correct_branch_directions!
— Methodcorrect_branch_directions!(data::Dict{String,<:Any})
checks that all parallel branches have the same orientation
PowerModelsDistribution.correct_bus_types!
— Methodchecks 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
PowerModelsDistribution.correct_cost_functions!
— Methodcorrect_cost_functions!(data::Dict{String,<:Any})
throws warnings if cost functions are malformed
PowerModelsDistribution.correct_json_import!
— Methodcorrect_json_import!(data::Dict{String,<:Any})
helper function to correct data imported from json
PowerModelsDistribution.correct_mc_thermal_limits!
— Methodcorrect_mc_thermal_limits!(data::Dict{String,<:Any})
checks that each branch has non-negative thermal ratings and removes zero thermal ratings
PowerModelsDistribution.correct_mc_voltage_angle_differences!
— Functioncorrect_mc_voltage_angle_differences!(data::Dict{String,<:Any}, default_pad::Real=deg2rad(10.0))
checks that voltage angle differences are within 90 deg., if not tightens to a default of 10deg (adjustable)
PowerModelsDistribution.correct_network_data!
— Methodcorrect_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!
Statistics and Analysis
PowerModelsDistribution.count_nodes
— Functioncount_nodes(data::Dict{String,<:Any})::Int
Counts number of nodes in network
count_nodes(data::Dict{String,<:Any})::Int
Counts number of nodes in network
PowerModelsDistribution.count_active_connections
— Functioncount_active_connections(data::Dict{String,<:Any})
Counts active ungrounded connections on edge components
PowerModelsDistribution.count_active_terminals
— Functioncount_active_terminals(data::Dict{String,<:Any}; count_grounded::Bool=false)
Counts active ungrounded terminals on buses
PowerModelsDistribution.identify_load_blocks
— Functionidentify_load_blocks(data::Dict{String,<:Any})
computes load blocks based on switch locations
PowerModelsDistribution.identify_blocks
— Functionidentify_blocks(data::Dict{String,<:Any})
computes connected blocks currently in the model based on switch states
PowerModelsDistribution.identify_islands
— Functionidentify_islands(data::Dict{String,<:Any})
computes component islands base only on edge and bus status
PowerModelsDistribution.calc_connected_components
— Functioncalc_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
Helper Functions
PowerModelsDistribution.iseng
— Functioniseng(data::Dict{String,Any})
Helper function to check is data is ENGINEERING model
PowerModelsDistribution.ismath
— Functionismath(data::Dict{String,Any})
Helper function to check if data is MATHEMATICAL model
PowerModelsDistribution.find_conductor_ids!
— Functionfind_conductor_ids!(data::Dict{String,Any})
Finds all conductor ids and puts a list of them under "conductor_ids" at the root level
PowerModelsDistribution.make_multiconductor!
— Functionmake_multiconductor!(data::Dict{String,<:Any}, conductors::Int)
This function is not meant to be an officially supported method for creating reasonable multiconductor data sets.
Hacky helper function to transform single-conductor network data, from, e.g., matpower/psse, into multi-conductor data.
PowerModelsDistribution.discover_voltage_zones
— Functiondiscover_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
PowerModelsDistribution.calc_voltage_bases
— Functioncalc_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
PowerModelsDistribution.apply_pmd!
— Functionapply_pmd!(func!::Function, data::Dict{String,<:Any}; apply_to_subnetworks::Bool=true, kwargs...)
Version of apply_pmd!
that supports kwargs
apply_pmd!(func!::Function, data::Dict{String,<:Any}; apply_to_subnetworks::Bool=true, kwargs...)
Version of apply_pmd!
that supports kwargs
apply_pmd!(func!::Function, data::Dict{String,<:Any}, args...; apply_to_subnetworks::Bool=true, kwargs...)
Version of apply_pmd!
that supports args and kwargs
apply_pmd!(func!::Function, ref::Dict{Symbol,<:Any}, data::Dict{String,<:Any}; apply_to_subnetworks::Bool=true)
PowerModelsDistribution wrapper for the InfrastructureModels apply!
function
PowerModelsDistribution.get_pmd_data
— Functionget_pmd_data(data::Dict{String, <:Any})
Convenience function for retrieving the power-distribution-only portion of network data