hynet.scenario package

Submodules

hynet.scenario.capability module

Representation of a capability region of injectors and converters.

class hynet.scenario.capability.CapRegion(p_bnd=None, q_bnd=None, lt=None, rt=None, lb=None, rb=None)[source]

Bases: object

Specification of a capability region.

The capability region is the intersection of a box and a polyhedron. Let s = [p, q]^T be the vector of active and reactive power injection. The capability region S is the intersection of S_box and S_phs, where

(1) S_box = { s in R^2: p_min <= p <= p_max, q_min <= q <= q_max }
(2) S_phd = { s in R^2: A*s <= b }.

The polyhedron S_phd is defined by the properties lt, lb, rt, and rb, which are half-spaces that are defined by a nonnegative relative offset and a slope, see the parameter description below. The parametrization in (2) can be obtained using the method get_polyhedron.

Parameters:
  • p_min (hynet_float_) – Active power lower bound in MW.
  • p_max (hynet_float_) – Active power upper bound in MW.
  • q_min (hynet_float_) – Reactive power lower bound in Mvar.
  • q_max (hynet_float_) – Reactive power upper bound in Mvar.
  • lt (HalfSpace or None) – Left-top half-space or None if omitted. This half-space is anchored at (p,q) with p = p_min and q = lt.offset * q_max. The slope must be positive.
  • rt (HalfSpace or None) – Right-top half-space or None if omitted. This half-space is anchored at (p,q) with p = p_max and q = rt.offset * q_max. The slope must be negative.
  • lb (HalfSpace or None) – Left-bottom half-space or None if omitted. This half-space is anchored at (p,q) with p = p_min and q = lb.offset * q_min. The slope must be negative.
  • rb (HalfSpace or None) – Right-bottom half-space or None if omitted. This half-space is anchored at (p,q) with p = p_max and q = rb.offset * q_min. The slope must be positive.
add_power_factor_limit(power_factor)[source]

Add a left-top and left-bottom half-space to limit the power factor.

Parameters:power_factor (hynet_float_) – Power factor limit.
copy()[source]

Return a deep copy of this capability region.

edit()[source]

Edit this capability region in the capability region visualizer.

Caution: Due to technical reasons, all open matplotlib figures are closed during this call.

Remark: In case you are using MAC OS X, please be aware of this issue with matplotlib and tkinter, which causes Python to crash if the capability region visualizer is opened. To avoid it, set matplotlib’s backend to TkAgg before importing hynet using

>>> import matplotlib
>>> matplotlib.use('TkAgg')
get_polyhedron()[source]

Returns the polyhedron formulation S_phd = { s in R^2: A*s <= b }.

Returns:
  • A (np.ndarray) – A in the formulation of the polyhedron above.
  • b (np.ndarray) – b in the formulation of the polyhedron above.
  • name (list[str]) – Abbreviation of the corresponding half-space for each row.
has_polyhedron()[source]

Return True if any of the half-spaces is set.

lb

Return the left-bottom half-space.

lt

Return the left-top half-space.

rb

Return the right-bottom half-space.

rt

Return the right-top half-space.

scale(scaling)[source]

Scale the upper and lower bound on active and reactive power.

show(operating_point=None)[source]

Show this capability region in the capability region visualizer.

Caution: Due to technical reasons, all open matplotlib figures are closed during this call.

Remark: In case you are using MAC OS X, please be aware of this issue with matplotlib and tkinter, which causes Python to crash if the capability region visualizer is opened. To avoid it, set matplotlib’s backend to TkAgg before importing hynet using

>>> import matplotlib
>>> matplotlib.use('TkAgg')
Parameters:operating_point (hynet_complex_, optional) – If provided, a marker is shown for this operating point in the P/Q-plane.
class hynet.scenario.capability.ConverterCapRegion(p_bnd=None, q_bnd=None, lt=None, rt=None, lb=None, rb=None)[source]

Bases: hynet.scenario.capability.CapRegion

Specification of a converter capability region.

The capability region is specified in terms of the apparent power flow at the respective terminal bus of the converter, see CapRegion for more information. With respect to the parameters returned by get_polyhedron and get_box_constraint, this class considers the converter state variable f = [p_fwd, p_bwd, q_src, q_dst]^T instead of the apparent power vector s = [p, q]^T considered in CapRegion.

add_power_factor_limit(power_factor)[source]

Add a left-top and left-bottom half-space to limit the power factor.

Parameters:power_factor (hynet_float_) – Power factor limit.
static get_box_constraint(cap_src, cap_dst, loss_factor_fwd, loss_factor_bwd)[source]

Return (f_lb, f_ub) of the state constraint f_lb <= f <= f_ub.

A converter comprises two capability regions, one at the source terminal and one at the destination terminal. Thus, the box constraint on the converter state variable is a combination of both as well as the conversion loss factors.

Parameters:
  • cap_src (ConverterCapRegion) – Source terminal capability region.
  • cap_dst (ConverterCapRegion) – Destination terminal capability region.
  • loss_factor_fwd (float) – Proportional loss factor for the forward flow.
  • loss_factor_bwd (float) – Proportional loss factor for the backward flow.
Returns:

  • f_lb (np.ndarray[.hynet_float_]) – Lower bound on the converter state vector.
  • f_ub (np.ndarray[.hynet_float_]) – Upper bound on the converter state vector.

get_polyhedron(terminal, loss_factor)[source]

Returns the polyhedron formulation S_phd = { f in R^4: A*f <= b }.

In addition to the half-spaces of the capability region, this polyhedron includes, for bidirectional converters with a nonnegligible capacity, an additional constraint to limit the noncomplementary operation of the converter.

Parameters:
  • terminal (str) – Terminal of the converter ('src' or 'dst') with which the capability region is associated.
  • loss_factor (float) – Proportional loss factor for (a) the backward flow if the terminal is 'src' and (b) the forward flow if the terminal is 'dst'.
Returns:

  • A (np.ndarray) – A in the formulation of the polyhedron above.
  • b (np.ndarray) – b in the formulation of the polyhedron above.
  • name (list[str]) – Abbreviation of the corresponding half-space or active power limit for each row.

class hynet.scenario.capability.HalfSpace[source]

Bases: hynet.scenario.capability.HalfSpace

Representation of a half-space in a capability region.

The half-spaces of a capability region are specified in terms of a nonnegative relative offset “offset” w.r.t. to the corresponding reactive power limit (i.e., the absolute offset is the reactive power limit multiplied by offset) and its slope “slope”. In the dimension of active power, it is anchored at the corresponding active power limit.

hynet.scenario.cost module

Representation of (injector) cost functions in hynet.

class hynet.scenario.cost.PWLFunction(samples=None, marginal_price=None)[source]

Bases: object

Representation of a piecewise linear function f: R -> R.

Parameters:samples ((numpy.ndarray[hynet_float_], numpy.ndarray[hynet_float_]), optional) – Tuple (x, y) of x- and y-coordinates of sample points of the piecewise linear function, i.e., (x[0], y[0]), ..., (x[N], y[N]).
evaluate(x)[source]

Evaluate the function at x, i.e., return y = f(x).

get_epigraph_polyhedron()[source]

Return (A, b) such that f(x) = min{z in R: z*1 >= A*x + b}.

Note that f must be convex.

is_convex()[source]

Return True if the function is convex.

marginal_price

Return the slope if the function is linear or numpy.nan otherwise.

Remark: This function requires that the linear function is specified using two sample points, i.e., the function will return numpy.nan even if three or more samples lie on a line. The latter case should be avoided anyway, as it introduces unnecessary constraints in the epigraph representation of the function.

samples

Return the tuple (x, y) of x- and y-coordinate arrays.

scale(scaling)[source]

Scale the function by scaling, i.e., f(x) -> scaling * f(x).

show()[source]

Show the piecewise linear function.

hynet.scenario.representation module

Representation of a steady-state scenario in hynet.

class hynet.scenario.representation.Scenario[source]

Bases: object

Specification of a steady-state grid scenario.

Parameters:
  • id (hynet_id_) – Identifier of the scenario.
  • name (str) – Name of the scenario.
  • time (hynet_float_) – Time in hours, relative to the scenario collection start time.
  • database_uri (str) – URI of the associated hynet grid database.
  • grid_name (str) – Name of the grid.
  • base_mva (hynet_float_) – Apparent power normalization constant in MVA.
  • loss_price (hynet_float_) – Artificial price for losses in $/MWh. The corresponding cost of losses is taken into account for the minimum-cost dispatch.
  • description (str) – Description of the grid database.
  • annotation (str) – Annotation string for supplementary information.
  • bus (pandas.DataFrame) –

    Data frame with one data set per bus, indexed by the bus ID, which comprises the following columns:

    type: (BusType)
    Type of voltage waveform at the bus.
    ref: (bool)
    True if the bus serves as a reference.
    base_kv: (hynet_float_)
    Base voltage in kV.
    y_tld: (hynet_complex_)
    Shunt admittance in p.u.. For example, to add a shunt compensator that injects q Mvar and dissipates p MW at 1 p.u., set y_tld to (p + 1j*q) / base_mva.
    load: (hynet_complex_)
    Aggregated inelastic apparent power load in MVA.
    v_min: (hynet_float_)
    Voltage lower bound in p.u..
    v_max: (hynet_float_)
    Voltage upper bound in p.u..
    zone: (hynet_id_ or None)
    Zone ID or None if not available.
    annotation: (str)
    Annotation string for supplementary information.
  • branch (pandas.DataFrame) –

    Data frame with one data set per branch, indexed by the branch ID, which comprises the following columns:

    type: (BranchType)
    Type of entity modeled by the branch.
    src: (hynet_id_)
    Source bus ID.
    dst: (hynet_id_)
    Destination bus ID.
    z_bar: (hynet_complex_)
    Series impedance of the pi-equivalent in p.u..
    y_src: (hynet_complex_)
    Shunt admittance at the source side of the pi-equivalent in p.u..
    y_dst: (hynet_complex_)
    Shunt admittance at the destination side of the pi-equivalent in p.u..
    rho_src: (hynet_complex_)
    Complex voltage ratio of the ideal transformer at the source side.
    rho_dst: (hynet_complex_)
    Complex voltage ratio of the ideal transformer at the destination side.
    length: (hynet_float_)
    Line length in kilometers or numpy.nan if not available.
    rating: (hynet_float_)
    Ampacity in terms of a long-term MVA rating at a bus voltage of 1 p.u. (i.e., the current limit is rating/base_mva) or numpy.nan if omitted.
    angle_min: (hynet_float_)
    Angle difference lower bound in degrees or numpy.nan if omitted.
    angle_max: (hynet_float_)
    Angle difference upper bound in degrees or numpy.nan if omitted.
    drop_min: (hynet_float_)
    Voltage drop lower bound in percent or numpy.nan if omitted.
    drop_max: (hynet_float_)
    Voltage drop upper bound in percent or numpy.nan if omitted.
    annotation: (str)
    Annotation string for supplementary information.
  • converter (pandas.DataFrame) –

    Data frame with one data set per converter, indexed by the converter ID, which comprises the following columns:

    src: (hynet_id_)
    Source bus ID.
    dst: (hynet_id_)
    Destination bus ID.
    cap_src: (ConverterCapRegion)
    Specification of the converter’s capability region in the P/Q-plane (in MW and Mvar, respectively) at the source bus. The P-axis is the active power flow into the converter and the Q-axis is the reactive power injection into the grid.
    cap_dst: (ConverterCapRegion)
    Specification of the converter’s capability region in the P/Q-plane (in MW and Mvar, respectively) at the destination bus. The P-axis is the active power flow into the converter and the Q-axis is the reactive power injection into the grid.
    loss_fwd: (hynet_float_)
    Loss factor in percent for the forward flow of active power. This proportional loss factor describes the dynamic conversion losses if active power flows from the source bus to the destination bus.
    loss_bwd: (hynet_float_)
    Loss factor in percent for the backward flow of active power. This proportional loss factor describes the dynamic conversion losses if active power flows from the destination bus to the source bus.
    loss_fix: (hynet_float_)
    Static losses in MW (considered at the converter’s source bus).
    annotation: (str)
    Annotation string for supplementary information.
  • injector (pandas.DataFrame) –

    Data frame with one data set per injector, indexed by the injector ID, which comprises the following columns:

    type: (InjectorType)
    Type of entity modeled by the injector.
    bus: (hynet_id_)
    Terminal bus ID.
    cap: (CapRegion)
    Specification of the injector’s capability region in the P/Q-plane (in MW and Mvar, respectively).
    cost_p: (PWLFunction or None)
    Piecewise linear cost function for active power, which specifies the cost in dollars for an active power injection in MW, or None in case of zero costs.
    cost_q: (PWLFunction or None)
    Piecewise linear cost function for reactive power, which specifies the cost in dollars for a reactive power injection in Mvar, or None in case of zero costs.
    cost_start: (hynet_float_)
    Startup cost in dollars.
    cost_stop: (hynet_float_)
    Shutdown cost in dollars.
    ramp_up: (hynet_float_)
    Maximum upramping rate for active power in MW/h or numpy.nan if the upramping rate is not limited.
    ramp_down: (hynet_float_)
    Maximum downramping rate for active power in MW/h or numpy.nan if the downramping rate is not limited.
    min_up: (hynet_float_)
    Minimum uptime in hours or numpy.nan if it is not limited.
    min_down: (hynet_float_)
    Minimum downtime in hours or numpy.nan if it is not limited.
    energy_min: (hynet_float_)
    Energy lower bound in MWh or numpy.nan if it is not limited.
    energy_max: (hynet_float_)
    Energy upper bound in MWh or numpy.nan if it is not limited.
    annotation: (str)
    Annotation string for supplementary information.

See also

hynet.data.interface.load_scenario
Load a scenario from a hynet grid database.
add_branch(type_, src, dst, z_bar, y_src=0.0, y_dst=0.0, rho_src=1.0, rho_dst=1.0, length=nan, rating=nan, angle_min=nan, angle_max=nan, drop_min=nan, drop_max=nan, annotation='', branch_id=None)[source]

Add a branch to this scenario.

Please refer to the documentation of the branch data frame for a description of the parameters. If branch_id is provided, this ID is used for the branch, otherwise an appropriate ID is generated.

Returns:branch_id – ID of the added branch.
Return type:hynet_id_
add_bus(type_, base_kv, v_min, v_max, ref=False, y_tld=0, load=0, zone=None, annotation='', bus_id=None)[source]

Add a bus to this scenario.

Please refer to the documentation of the bus data frame for a description of the parameters. If bus_id is provided, this ID is used for the bus, otherwise an appropriate ID is generated.

Returns:bus_id – ID of the added bus.
Return type:hynet_id_
add_compensator(bus, q_max, q_min=None, cost_q=None)[source]

Add a reactive power compensator to this scenario.

Parameters:
  • bus (hynet_id_) – Bus ID of the terminal bus for the compensator.
  • q_max (hynet_float_) – Maximum reactive power in Mvar that can be injected.
  • q_min (hynet_float_, optional) – Lower bound in Mvar (default -q_max) on the reactive power injection.
  • cost_q (PWLFunction, optional) – Piecewise linear cost function for reactive power. By default, the reactive power is provided at zero cost.
Returns:

injector_id – Injector ID of the added compensator.

Return type:

hynet_id_

add_converter(src, dst, cap_src, cap_dst, loss_fwd=0, loss_bwd=0, loss_fix=0, annotation='', converter_id=None)[source]

Add a converter to this scenario.

Please refer to the documentation of the converter data frame for a description of the parameters. If converter_id is provided, this ID is used for the converter, otherwise an appropriate ID is generated.

Returns:converter_id – ID of the added converter.
Return type:hynet_id_
add_injector(type_, bus, cap, cost_p=None, cost_q=None, cost_start=0, cost_stop=0, ramp_up=nan, ramp_down=nan, min_up=nan, min_down=nan, energy_min=nan, energy_max=nan, annotation='', injector_id=None)[source]

Add an injector to this scenario.

Please refer to the documentation of the injector data frame for a description of the parameters. If injector_id is provided, this ID is used for the injector, otherwise an appropriate ID is generated.

Returns:injector_id – ID of the added injector.
Return type:hynet_id_
analyze_cycles()[source]

Return a data frame with an analysis of cyclic connections of buses.

The information about cyclic connections of buses is relevant in the study of transitions to the hybrid architecture, which establishes exactness of the semidefinite and second-order cone relaxation of the OPF problem under normal operating conditions, cf. [1].

Returns:result – Data frame with the cycle analysis result for every subgrid, which comprises the following columns:
num_cycles: (hynet_int_)
Number of cycles in the subgrid.
type: (BusType)
Type of the subgrid.
buses: (pandas.Index)
Pandas index with the bus IDs of the buses that are part of the subgrid.
Return type:pandas.DataFrame

References

[1]M. Hotz and W. Utschick, “The Hybrid Transmission Grid Architecture: Benefits in Nodal Pricing,” in IEEE Trans. Power Systems, vol. 33, no. 2, pp. 1431-1442, Mar. 2018.
c_dst

Return the converter destination bus indices as a pandas series.

Remark: This property is index-based and intended for internal use.

c_src

Return the converter source bus indices as a pandas series.

Remark: This property is index-based and intended for internal use.

copy()[source]

Return a deep copy of this scenario.

e_dst

Return the branch destination bus indices as a pandas series.

Remark: This property is index-based and intended for internal use.

e_src

Return the branch source bus indices as a pandas series.

Remark: This property is index-based and intended for internal use.

ensure_reference()[source]

Automatically add a reference bus to all AC subgrids without a reference.

All AC subgrids are required to have a dedicated reference bus. However, cases may arise in which certain AC subgrids have no predefined reference, e.g., due to the partitioning or islanding of AC subgrids in a simulated branch outage. This method automatically assigns a reference bus to all AC subgrids without a reference, where the reference bus is set to the bus with the injector of highest capacity therein, if available.

get_ac_branches()[source]

Return a pandas index with the branch IDs of all AC branches.

get_ac_subgrids()[source]

Return a list with a pandas index of bus IDs for every AC subgrid.

get_branches_in_corridors(corridors)[source]

Return a pandas index of branch IDs that reside in these corridors.

Remark: This property is index-based and intended for internal use.

Parameters:corridors ((numpy.ndarray[hynet_int_], numpy.ndarray[hynet_int_])) – Tuple of NumPy arrays that state the source bus index and destination bus index of the corridors.
Returns:index – Pandas index with the branch IDs of those branches that reside in the specified corridors.
Return type:pandas.Index
get_bus_index(bus_id)[source]

Return the bus index(es) for the given (iterable of) bus identifier(s).

Remark: This result is index-based and intended for internal use.

get_dc_branches()[source]

Return a pandas index with the branch IDs of all DC branches.

get_dc_subgrids()[source]

Return a list with a pandas index of bus IDs for every DC subgrid.

get_islands()[source]

Return a list with a pandas index of bus IDs for every islanded grid.

get_parallel_branches()[source]

Return a list with a pandas index of branch IDs for parallel branches.

get_ref_buses()[source]

Return an array with the bus index of the reference buses.

Remark: This result is index-based and intended for internal use.

get_relative_loading()[source]

Return the ratio of tot. active power load to tot. active power inj. cap.

This ratio indicates the relative amount of the active power injection capacity that is utilized by the active power load of this scenario.

get_time_string()[source]

Return the scenario time stamp as Dd HH:MM:SS.

get_time_tuple()[source]

Return the scenario time stamp as (days, hours, minutes, seconds).

has_acyclic_ac_subgrids()[source]

Return True if all AC subgrids are acyclic and False otherwise.

has_acyclic_dc_subgrids()[source]

Return True if all DC subgrids are acyclic and False otherwise.

has_acyclic_subgrids()[source]

Return True if all subgrids are acyclic and False otherwise.

n_src

Return the injector terminal bus indices as a pandas series.

Remark: This property is index-based and intended for internal use.

num_branches

Return the number of branches.

num_buses

Return the number of buses.

num_converters

Return the number of converters.

num_injectors

Return the number of injectors.

remove_buses(buses)[source]

Remove the specified buses and attached branches, converters, and injectors.

Parameters:buses (Iterable[hynet_id_]) – Iterable of bus IDs that specifies the buses to be removed.
Returns:
  • branches (pandas.Index) – Removed branches, which were connected to the removed buses.
  • converters (pandas.Index) – Removed converters, which were connected to the removed buses.
  • injectors (pandas.Index) – Removed injectors, which were connected to the removed buses.
set_conservative_rating()[source]

Adjust the branch rating to a conservative setting (MATPOWER compat.).

In the hynet data format, the branch rating is an ampacity rating in terms of the apparent power flow at 1 p.u. (due to reasons stated in [1], Section III), i.e., the rating divided by base_mva is the ampacity rating. In the MATPOWER format, the rating is an apparent power rating, i.e., it is independent of the voltage. To ensure feasibility w.r.t. MATPOWER’s apparent power rating, the hynet rating may be converted to a more conservative rating as described in [1], Remark 1, which is performed by this method.

References

[1](1, 2) M. Hotz and W. Utschick, “A Hybrid Transmission Grid Architecture Enabling Efficient Optimal Power Flow,” in IEEE Trans. Power Systems, vol. 31, no. 6, pp. 4504-4516, Nov. 2016.
set_minimum_series_resistance(min_resistance, branch_ids=None)[source]

Set the series resistance of the branches to a minimum of min_resistance.

Very small values of the series resistance of branches may lead to numerical issues during the solution of the OPF problem. With this method, the series resistance is enforced to be larger or equal to min_resistance.

Parameters:
  • min_resistance (float) – Minimum resistance for the series resistance of the specified branches. If a branch has a series resistance below this value, it is replaced by min_resistance.
  • branch_ids (Iterable[hynet_id_]) – Iterable of branch IDs for which the minimum series resistance shall be ensured. By default, all branches are considered.
verify(log=<bound method Logger.warning of <Logger hynet.scenario.representation (WARNING)>>)[source]

Verify the integrity and validity of the scenario.

This method performs an extensive series of checks on the scenario to ensure that the data is consistent (e.g., the references between data frames), proper (e.g., constraint limits), and valid (i.e., compliant with all preconditions as assumed by hynet).

Parameters:log (function(str) or None) – Function to log information about critical settings (default is the warning log of the module). Set to None to suppress this log output.
Raises:ValueError – In case any kind of integrity or validity violation is detected.
verify_hybrid_architecture_conditions(log=<bound method Logger.warning of <Logger hynet.scenario.representation (WARNING)>>)[source]

Return True if the hybrid architecture’s exactness results hold.

The hybrid architecture denotes a class of network topologies that, under very mild conditions, induces exactness to the semidefinite and second-order cone relaxation of the OPF problem in case that no pathological price profile emerges, see [1], [2], and [3]. This function returns True if the topological requirements of the hybrid architecture as well as the conditions on the system parameters that are utilized for the aforementioned results on exactness are satisfied for this scenario. It is assumed that the validity of the scenario is established beforehand, see Scenario.verify.

Parameters:log (function(str) or None) – Function to log information about violated conditions (default is the warning log of the module). Set to None to suppress any log output.

References

[1]M. Hotz and W. Utschick, “A Hybrid Transmission Grid Architecture Enabling Efficient Optimal Power Flow,” in IEEE Trans. Power Systems, vol. 31, no. 6, pp. 4504-4516, Nov. 2016.
[2]M. Hotz and W. Utschick, “The Hybrid Transmission Grid Architecture: Benefits in Nodal Pricing,” in IEEE Trans. Power Systems, vol. 33, no. 2, pp. 1431-1442, Mar. 2018.
[3]M. Hotz and W. Utschick, “hynet: An Optimal Power Flow Framework for Hybrid AC/DC Power Systems,” in IEEE Trans. Power Systems, vol. 35, no. 2, pp. 1036-1047, Mar. 2020.

hynet.scenario.verification module

Verification of a steady-state scenario.

hynet.scenario.verification.verify_hybrid_architecture(scr, log_function)[source]

Return True if the hybrid architecture’s exactness results hold.

This function is actually part of the Scenario class. Due to its extent, it was moved to a separate module in order to improve code readability.

hynet.scenario.verification.verify_scenario(scr, log_function)[source]

Verify the integrity and validity of the scenario.

This function is actually part of the Scenario class. Due to its extent, it was moved to a separate module in order to improve code readability.

Raises:ValueError – In case any kind of integrity or validity violation is detected.

Module contents

Representation of a steady-state scenario in hynet.