Updates
Typed updates change a module in place. Each update names a component by ComponentId and gives an absolute value with an explicit unit. You apply updates as a batch, and the batch is validated as a whole before anything changes.
case = parse("case9.m")
load = ComponentId("load", case.value.loads[1].component_id) # "bus-5"
report = apply_updates!(case, [
set_load_active_power(load, ActivePower(megawatts=91.5)),
set_load_reactive_power(load, ReactivePower(megavars=31.0)),
])
report.connectivity_changed # false
report.changes[1].component_id # ComponentId("load", "bus-5")
report.changes[1].field # "load_active_power"
case.value.loads[1].p_mw # 91.5The quantity types ActivePower, ReactivePower, and ApparentPower take exactly one unit keyword: ActivePower(watts=...) or ActivePower(megawatts=...), ReactivePower(vars=...) or ReactivePower(megavars=...), ApparentPower(volt_amperes=...) or ApparentPower(megavolt_amperes=...).
Update constructors
Operating point updates:
| Function | Field changed |
|---|---|
set_load_active_power, set_load_reactive_power | a load's demand |
set_generator_active_power, set_generator_reactive_power | a generator's dispatch |
set_generator_voltage_magnitude | a generator's voltage setpoint, per unit |
set_generator_in_service, set_branch_in_service | service status |
set_transformer_tap_ratio, set_transformer_phase_shift_degrees | a transformer branch |
set_switch_closed | a switch position |
The network update is set_branch_thermal_rating. The power setters accept terminal= to address one terminal of a multiconductor element.
Applying a batch
apply_updates! validates every update before changing anything, so a batch with an unknown component or an invalid value throws PowerIOError and leaves the module as it was. On success the module's value is refreshed and case.value reflects the change; a BalancedNetwork you obtained before the call keeps the data from before it. The returned UpdateReport lists every UpdateChange and says whether a service status or switch change altered the energized topology.
Component ids for MATPOWER sources follow the reader's convention: loads and generators are "bus-N", branches are "F-T". Read the component_id field of the element rather than assuming a convention.
Aggregate demand at one bus
apply_bus_load_active_power sets the total active demand at one bus and spreads it over the loads there, which saves naming each load when a study moves demand by bus. The rule is "proportional_to_current_active_power", which keeps each load's present share, or "equal", which splits the total evenly. The module holds a calculation instance, bus_id is the source bus number, and the call reports the same UpdateReport as a batch of updates.
dc = to_dc_opf_instance(parse("case9.m"))
report = apply_bus_load_active_power(dc, 5, ActivePower(megawatts=125.0))
length(report) # one change per load moved
dc.value.network.loads[1].p_mw # 125.0
apply_bus_load_active_power(dc, 5, ActivePower(megawatts=80.0); allocation="equal")An unknown rule throws PowerIOError with code REQUEST.CAPI.ALLOCATION_UNKNOWN, a bus with no load gives VALIDATE.UPDATE.COMPONENT_UNKNOWN, and a module holding a bare network gives REQUEST.CAPI.TYPE_MISMATCH. Each leaves the module as it was.
PowerIO.ActivePower — Type
ActivePower(; watts) or ActivePower(; megawatts)Active power with an explicit unit.
PowerIO.ReactivePower — Type
ReactivePower(; vars) or ReactivePower(; megavars)Reactive power with an explicit unit.
PowerIO.ApparentPower — Type
ApparentPower(; volt_amperes) or ApparentPower(; megavolt_amperes)Apparent power with an explicit unit.
PowerIO.OperatingPointUpdate — Type
OperatingPointUpdateOne change to operating data: a load or generator setpoint, a service status, a transformer tap or phase shift, or a switch position. Construct one with set_load_active_power and the other set_* functions, then apply a batch with apply_updates!.
PowerIO.NetworkUpdate — Type
NetworkUpdateOne change to network data. set_branch_thermal_rating is the network update in this release.
PowerIO.set_load_active_power — Function
set_load_active_power(id::ComponentId, power::ActivePower; terminal=nothing)An update that sets a load's active power. terminal selects one terminal of a multiconductor load.
PowerIO.set_load_reactive_power — Function
set_load_reactive_power(id::ComponentId, power::ReactivePower; terminal=nothing)An update that sets a load's reactive power.
PowerIO.set_generator_active_power — Function
set_generator_active_power(id::ComponentId, power::ActivePower; terminal=nothing)An update that sets a generator's active power setpoint.
PowerIO.set_generator_reactive_power — Function
set_generator_reactive_power(id::ComponentId, power::ReactivePower; terminal=nothing)An update that sets a generator's reactive power setpoint.
PowerIO.set_generator_voltage_magnitude — Function
set_generator_voltage_magnitude(id::ComponentId, vm_pu::Real)An update that sets a generator's voltage setpoint in per unit.
PowerIO.set_generator_in_service — Function
set_generator_in_service(id::ComponentId, in_service::Bool)An update that sets a generator's service status.
PowerIO.set_branch_in_service — Function
set_branch_in_service(id::ComponentId, in_service::Bool)An update that sets a branch's service status.
PowerIO.set_transformer_tap_ratio — Function
set_transformer_tap_ratio(id::ComponentId, tap_ratio::Real)An update that sets a transformer branch's tap ratio.
PowerIO.set_transformer_phase_shift_degrees — Function
set_transformer_phase_shift_degrees(id::ComponentId, degrees::Real)An update that sets a transformer branch's phase shift.
PowerIO.set_switch_closed — Function
set_switch_closed(id::ComponentId, closed::Bool)An update that sets a switch position.
PowerIO.set_branch_thermal_rating — Function
set_branch_thermal_rating(id::ComponentId, rating::ApparentPower; terminal=nothing)A network update that sets a branch's thermal rating.
PowerIO.apply_updates! — Function
apply_updates!(m::PioModule, updates) -> UpdateReportValidate the whole batch of OperatingPointUpdate and NetworkUpdate values, then apply it atomically. A failed batch throws PowerIOError and leaves the module unchanged. On success m.value is refreshed; values obtained before the call keep the pre-update data.
Calls sharing the module handle are synchronized through mutation and value refresh. Values already obtained from m retain their pre-update data and remain independently readable.
PowerIO.apply_bus_load_active_power — Function
apply_bus_load_active_power(m::PioModule, bus_id::Integer, total::ActivePower;
allocation="proportional_to_current_active_power") -> UpdateReportSet the aggregate active demand at one bus to total, spreading it over the loads at that bus by the named rule. "proportional_to_current_active_power" keeps each load's share of the present demand; "equal" gives every load the same amount. Any other token throws PowerIOError with code REQUEST.CAPI.ALLOCATION_UNKNOWN.
m holds a calculation instance, such as one to_dc_opf_instance constructed. A module holding a bare network reports REQUEST.CAPI.TYPE_MISMATCH, and bus_id is the source bus number.
Like apply_updates! this validates before it changes anything, so an unknown bus or rule leaves the module untouched. On success m.value is refreshed and the returned UpdateReport lists one UpdateChange per load it moved.
PowerIO.UpdateReport — Type
UpdateReportWhat apply_updates! changed: changes::Vector{UpdateChange} and connectivity_changed, true when a service status or switch change altered the energized topology. length(report) is the number of changes.
PowerIO.UpdateChange — Type
UpdateChange(component_id, field, terminal)One change an applied batch made: the component, the field name such as "load_active_power" or "branch_thermal_rating", and the terminal when the change targeted one.