hynet.system package

Submodules

hynet.system.calc module

Calculate the solution of an optimization problem specified by a given model.

hynet.system.calc.calc(model, solver=None, solver_type=<SolverType.QCQP: 'QCQP'>, initial_point_generator=None)[source]

Calculate the solution of the optimization problem for the given model.

Model classes take the scenario data to build a specific optimization problem. This function takes the model to generate the specification of the optimization problem, solve the problem using the specified solver, and route the result data though the model object to generate and return an appropriate result object. The solver or solver type may be specified explicitly, otherwise an appropriate solver is selected automatically.

Parameters:
  • model (SystemModel) – Model object that generates the quadratically constrained quadratic problem (QCQP).
  • solver (SolverInterface, optional) – Solver for the QCQP problem; the default automatically selects an appropriate solver of the specified solver type.
  • solver_type (SolverType, optional) – Solver type for the automatic solver selection (default SolverType.QCQP). It is ignored if solver is not None.
  • initial_point_generator (InitialPointGenerator or None, optional) – Initial point generator for QCQP solvers (ignored for relaxation-based solvers). If None (default), the initial point generation is skipped.
Returns:

result – Result data of the solution of the optimization problem.

Return type:

SystemResult

hynet.system.calc.select_solver(solver_type)[source]

Return the most appropriate installed solver of the specified solver type.

Parameters:solver_type (SolverType) – Specification of the solver type.
Returns:solver – Selected solver interface class of the specified solver type.
Return type:SolverInterface
Raises:RuntimeError – In case no appropriate solver was found.

hynet.system.initial_point module

Initial point generation for the QCQP solvers for the OPF problem.

class hynet.system.initial_point.InitialPointGenerator[source]

Bases: abc.ABC

Abstract base class for initial point generators for the QCQP OPF solvers.

Derived classes implement the generation of an initial point for solvers that solve the nonconvex QCQP representation of the OPF problem. With the provision of an appropriate initial point, the convergence performance and “quality” of the identified local optimum may be improved.

class hynet.system.initial_point.RelaxationInitialPointGenerator(solver, rec_mse_thres=1e-08)[source]

Bases: hynet.system.initial_point.InitialPointGenerator

Relaxation-based initial point generator for QCQP solvers.

This generator returns an initial point for the solution of the QCQP that corresponds to a relaxation of the QCQP. Especially the second-order cone relaxation (SOCR solvers) is typically fast to compute and may be suitable.

solver

Return the solver for the initial point computation.

hynet.system.model module

Steady-state system model of hynet.

class hynet.system.model.SystemModel(scenario, verify_scenario=True)[source]

Bases: abc.ABC

System model for a steady-state scenario of a grid.

Based on the specification of a scenario via a Scenario object, this class provides the methods to generate the corresponding system model equations and constraints. The state variables in this system model are the bus voltage vector v, the converter state vector f, the injector state vector s, and the auxiliary variable vector z. The latter is actually not part of the system model serves for auxiliary purposes, e.g., for the reformulation of the piecewise linear active and reactive power cost functions of injectors. All state variables are considered in p.u., i.e., normalized.

This class is designed as an abstract base class for specific problem formulations, like the optimal power flow problem, and serves as a builder for the optimization problem and as a factory for the associated result objects. Central to this process are the following member functions:

  • get_problem:

    Returns the associated optimization problem as a quadratically constrained quadratic problem (QCQP). The construction of this QCQP object is defined by the following member functions:

    1. _get_objective Returns the objective function object.
    2. _get_constraint_generators Returns the constraint generation functions.
    3. get_v_bounds: Returns the bounds on the magnitudes of the elements of the bus voltage vector v.
    4. get_f_bounds: Returns the bounds on the elements of the converter state vector f.
    5. get_s_bounds: Returns the bounds on the elements of the injector state vector s.
    6. get_z_bounds: Returns the bounds on the elements of the auxiliary variable vector z.

    The methods (a) and (b) are abstract and must be implemented in a derived class to specify the optimization problem. While (c) - (e) are part of the system model and should not need any customization, (f) may be overridden. By default, the auxiliary variables are used for the reformulation of the piecewise linear active and reactive power cost functions of injectors into epigraph form as implemented in the method get_cost_epigraph_constraints. To customize the use of the auxiliary variables, dim_z and get_z_bounds (as well as get_normalization_factors) may be overridden in a derived class.

    Please note that the coefficient matrices of the constraints for the quadratic expressions in v must exhibit a sparsity pattern that corresponds to the network graph of the grid. If this is not fulfilled by a derived class, get_problem must be overridden accordingly.

  • create_result:

    This method serves as a factory for an object that appropriately represents an optimization result for the model. It is abstract and must be implemented in a derived class.

See also

hynet.scenario.representation.Scenario
Specification of a steady-state grid scenario.
hynet.system.result.SystemResult
Result of a system-model-related optimization.
hynet.system.calc.calc
Calculate the solution of the optimization problem of a model.
Y

Return the bus admittance matrix.

Y_dst

Return the destination admittance matrix.

Y_src

Return the source admittance matrix.

calc_branch_angle_difference(operating_point)[source]

Return the voltage angle difference along the branches in degrees.

Parameters:operating_point (QCQPPoint) – Operating point of the system without the normalization of the state variables, i.e., as provided by a QCQP result.
calc_branch_effective_rating(operating_point)[source]

Return the ampacity rating in MVA rating at the current bus voltages.

In the scenario data, the branch flow is limited by an ampacity rating that is specified in terms of a long-term MVA rating at a bus voltage of 1 p.u.. Correspondingly, the ampacity rating translates to a different MVA rating if the bus voltages differ from 1 p.u.. This function returns the ampacity rating in MVA at the current bus voltages, i.e., the rating at 1 p.u. times the actual voltage.

Parameters:operating_point (QCQPPoint) – Operating point of the system without the normalization of the state variables, i.e., as provided by a QCQP result.
calc_branch_flow(operating_point)[source]

Return the flow on the branches for the given operating point.

Parameters:operating_point (QCQPPoint) – Operating point of the system without the normalization of the state variables, i.e., as provided by a QCQP result.
Returns:
  • i_src (numpy.ndarray[.hynet_complex_]) – Branch current flow in p.u. at the source bus.
  • i_dst (numpy.ndarray[.hynet_complex_]) – Branch current flow in p.u. at the destination bus.
  • s_src (numpy.ndarray[.hynet_complex_]) – Branch apparent power flow in MVA at the source bus.
  • s_dst (numpy.ndarray[.hynet_complex_]) – Branch apparent power flow in MVA at the destination bus.
calc_branch_voltage_drop(operating_point)[source]

Return the relative voltage magnitude drop along the branches.

Parameters:operating_point (QCQPPoint) – Operating point of the system without the normalization of the state variables, i.e., as provided by a QCQP result.
calc_converter_flow(operating_point)[source]

Return the apparent power flow into the converters.

Parameters:operating_point (QCQPPoint) – Operating point of the system without the normalization of the state variables, i.e., as provided by a QCQP result.
Returns:
  • s_src (numpy.ndarray[.hynet_complex_]) – Apparent power flow in MVA into the converter at the source bus.
  • s_dst (numpy.ndarray[.hynet_complex_]) – Apparent power flow in MVA into the converter at the destination bus.
calc_converter_loss_error(operating_point)[source]

Return the converter loss error.

Parameters:operating_point (QCQPPoint) – Operating point of the system without the normalization of the state variables, i.e., as provided by a QCQP result.
Returns:loss_err – Loss error in MW due to noncomplementary modes of the converter.
Return type:numpy.ndarray[hynet_float_]
calc_dynamic_losses(operating_point)[source]

Return the total dynamic losses in MW for the given operating point.

Parameters:operating_point (QCQPPoint) – Operating point of the system without the normalization of the state variables, i.e., as provided by a QCQP result.
calc_injection_costs(operating_point)[source]

Return the injector’s active and reactive power injection costs in dollars.

Parameters:operating_point (QCQPPoint) – Operating point of the system without the normalization of the state variables, i.e., as provided by a QCQP result.
Returns:
  • cost_p (numpy.ndarray[.hynet_float_]) – Cost of the active power injection in dollars.
  • cost_q (numpy.ndarray[.hynet_float_]) – Cost of the reactive power injection in dollars.
calc_shunt_apparent_power(operating_point)[source]

Return the shunt apparent power in MVA for the given operating point.

Parameters:operating_point (QCQPPoint) – Operating point of the system without the normalization of the state variables, i.e., as provided by a QCQP result.
converter_loss_error_tolerance

Return the converter loss error tolerance in MW.

cost_function_scaling

Return the cost function scaling used by get_cost_epigraph_constraints.

To improve the numerical conditioning of the an optimization problem with the injector cost functions in the objective and, therewith, mitigate numerical issues with the solver, the cost functions may be scaled. This scaling must be considered when including other terms in the objective, e.g., a loss penalty.

create_result(qcqp_result, total_time=nan, qcqp_result_pre=None)[source]

Create and return a result object associated with this model.

This method serves as a factory for a result object. Implement this method in a derived class to return an object of an appropriately customized result class.

Parameters:
  • qcqp_result (QCQPResult) – Solution of the QCQP associated with this model.
  • total_time (hynet_float_, optional) – Total time for solving the optimization problem, cf. hynet.system.calc.calc.
  • qcqp_result_pre (QCQPResult, optional) – Pre-solution of the model’s QCQP for converter mode detection.
Returns:

result

Return type:

hynet.system.result.SystemResult

dim_f

Return the dimension of the state variable f.

dim_s

Return the dimension of the state variable s.

dim_v

Return the dimension of the state variable v.

dim_z

Return the dimension of the state variable z.

fix_converter_modes(qcqp, operating_point, set_initial_point=True)[source]

Fix the converter modes in the QCQP according to the converter net flow.

This function determines the active converter mode based on the converter net active power flow in the provided operating point and updates the upper bounds on the converter state variable in the QCQP to fix the converter mode accordingly. Therewith, the emergence of any converter loss errors is suppressed.

Parameters:
  • qcqp (QCQP) – QCQP specification for the optimization problem associated with this model, see get_problem.
  • operating_point (QCQPPoint) – Operating point of the system without the normalization of the state variables, i.e., as provided by a QCQP result. Generally, this is the initial solution of the model’s QCQP in which a nonnegligible converter loss error appeared.
  • set_initial_point (bool, optional) – If True (default), the provided operating point is set as the initial point for the QCQP with the converter state variables adjusted according to the net active power flow.
get_angle_constraints()[source]

Return the angle diff. lower and upper bound and “real-part” constraints.

get_balance_constraints()[source]

Return the active and reactive power balance constraints.

get_converter_polyhedron_constraints()[source]

Return the converter capability region polyhedron constraints.

get_cost_epigraph_constraints()[source]

Return the PWL cost function epigraph constraints.

get_destination_ampacity_constraints()[source]

Return the destination ampacity constraints.

get_drop_constraints()[source]

Return the voltage drop lower and upper bound constraints.

get_dyn_loss_function()[source]

Return (C, c) for the total dyn. loss L(v,f) = v^H C v + c^T f.

get_f_bounds()[source]

Return the converter state bounds f_lb <= f <= f_ub.

get_injector_polyhedron_constraints()[source]

Return the injector capability region polyhedron constraints.

get_normalization_factors()[source]

Return the normalization factors of the state variables.

Returns:factors – Contains the normalization factors of the state variables in the attributes v, f, s, and z.
Return type:QCQPPoint
get_problem()[source]

Return the optimization problem that is associated with this model.

Returns:qcqp – QCQP specification for the optimization problem associated with this model.
Return type:QCQP
get_real_part_constraints()[source]

Return the “real-part” constraints.

These constraints ensure a precondition assumed by the voltage angle difference constraints, i.e., that the voltage angle difference is limited to +/- 90 degrees.

get_s_bounds()[source]

Return the injector state bounds s_lb <= s <= s_ub.

get_source_ampacity_constraints()[source]

Return the source ampacity constraints.

get_v_bounds()[source]

Return the voltage magnitude bounds v_lb <= |v| <= v_ub.

Remark: The voltage magnitude bounds are captured by get_voltage_constraints and, thus, this box constraint is actually redundant and only included to provide optimization variable bounds for the solver (which, for some solvers, can improve convergence). To avoid any impact on the dual variables of the voltage magnitude constraints (which e.g. was observed with MOSEK), these box constraints are loosened w.r.t. the limits employed in get_voltage_constraints.

get_voltage_constraints()[source]

Return the voltage magnitude lower and upper bound constraints.

get_z_bounds()[source]

Return the auxiliary variable bounds z_lb <= z <= z_ub.

The lower and upper bound is set to numpy.nan if the corresponding bound should be omitted.

nodal_balance_error_tolerance

Return the relative nodal power balance error tolerance.

Threshold on the ratio of the maximum nodal apparent power balance error and the maximum individual apparent power load to consider a solution as physically valid.

scenario

Return the scenario data of the system model.

total_balance_error_tolerance

Return the relative total power balance error tolerance.

Threshold on the ratio of the total active power balance error and the total active power load to consider a solution as physically valid.

verify_converter_loss_accuracy(operating_point)[source]

Return True if the converter loss error is within the tolerance.

The converter loss error tolerance of the model is specified by the property converter_loss_error_tolerance.

Parameters:operating_point (QCQPPoint) – Operating point of the system without the normalization of the state variables, i.e., as provided by a QCQP result.
verify_power_balance_accuracy(bal_err)[source]

Return True if the power balance error is within the tolerance.

The power balance error tolerance of the model is specified by the properties nodal_balance_error_tolerance and total_balance_error_tolerance.

Parameters:bal_err (numpy.ndarray[hynet_complex_]) – Power balance error in MVA at the individual buses.

hynet.system.result module

Representation of a system-model-related optimization result.

class hynet.system.result.SystemResult(model, qcqp_result, total_time=nan, qcqp_result_pre=None)[source]

Bases: object

Result of a system-model-related optimization.

Parameters:
  • model (SystemModel) – Model for the processed optimization problem.
  • empty (bool) – True if the object does not contain any result data and False otherwise.
  • solver (SolverInterface) – Solver object by which the result was obtained.
  • solver_status (SolverStatus) – Status reported by the solver.
  • solver_time (float) – Duration of the call to the solver in seconds.
  • optimal_value (float) – Optimal objective value or numpy.nan if the solver failed.
  • total_time (float or numpy.nan) – Total time for the calculation, including the modeling, solving, and result assembly. If not provided, this time is set to numpy.nan.
  • reconstruction_mse (float) – Unavailable if the result is empty and, otherwise, the mean squared error of the reconstructed bus voltages in case of a relaxation and numpy.nan otherwise.
  • bus (pandas.DataFrame, optional) –

    Unavailable if the result is empty and, otherwise, a data frame with the bus result data, indexed by the bus ID, which comprises at least the following columns:

    v: (hynet_complex_)
    Bus voltage rms phasor (AC) or bus voltage magnitude (DC).
    s_shunt: (hynet_complex_)
    Shunt apparent power in MVA. The real part constitutes the shunt losses in MW and the negated imaginary part constitutes the reactive power injection.
    bal_err: (hynet_complex_)
    Power balance residual in MVA, i.e., the evaluation of the complex-valued power balance equation at the system state. Theoretically, this should be identical to zero, but due to a limited solver accuracy and/or inexactness of the relaxation it is only approximately zero. This residual supports the assessment of solution accuracy and validity.
    dv_bal_p: (hynet_float_)
    Dual variable or KKT multiplier of the active power balance constraint.
    dv_bal_q: (hynet_float_)
    Dual variable or KKT multiplier of the reactive power balance constraint.
  • branch (pandas.DataFrame, optional) –

    Unavailable if the result is empty and, otherwise, a data frame with the branch result data, indexed by the branch ID, which comprises at least the following columns:

    s_src: (hynet_complex_)
    Apparent power flow in MVA at the source bus (measured as a flow into the branch).
    s_dst: (hynet_complex_)
    Apparent power flow in MVA at the destination bus (measured as a flow into the branch).
    i_src: (hynet_complex_)
    Current flow in p.u. at the source bus (measured as a flow into the branch).
    i_dst: (hynet_complex_)
    Current flow in p.u. at the destination bus (measured as a flow into the branch).
    v_drop: (hynet_float_)
    Relative voltage magnitude drop from the source bus to the destination bus.
    angle_diff: (hynet_float_)
    Bus voltage angle difference in degrees between the source and destination bus.
    effective_rating: (hynet_float_)
    Ampacity in terms of a long-term MVA rating at the actual bus voltage. If no rating is available, it is set to numpy.nan.
    rel_err: (hynet_float_)
    Branch-related relative reconstruction error \(\kappa_k(V^\star)\) as defined in equation (24) in [1] in case of a relaxed QCQP or numpy.nan otherwise.
    dv_real_part: (hynet_float_)
    Dual variable or KKT multiplier of the +/-90 degrees constraint on the angle difference (cf. equation (27) in [2]) or numpy.nan if unavailable.
  • converter (pandas.DataFrame) –

    Unavailable if the result is empty and, otherwise, a data frame with the converter result data, indexed by the converter ID, which comprises at least the following columns:

    p_src: (hynet_float_)
    Active power flow in MW at the source bus into the converter.
    p_dst: (hynet_float_)
    Active power flow in MW at the destination bus into the converter.
    q_src: (hynet_float_)
    Reactive power injection in Mvar at the source bus into the grid.
    q_dst: (hynet_float_)
    Reactive power injection in Mvar at the destination bus into the grid.
    loss_err: (hynet_float_)
    Loss error in MW due to noncomplementary modes of the converter.
    loss_err_pre: (hynet_float_)
    Only available if the QCQP was pre-solved to detect and fix the converter modes. Loss error in MW in the pre-solution due to noncomplementary modes of the converter.
    dv_p_fwd_min: (hynet_float_)
    Dual variable or KKT multiplier of the lower bound on the converter’s forward mode active power flow or numpy.nan if unavailable.
    dv_p_fwd_max: (hynet_float_)
    Dual variable or KKT multiplier of the upper bound on the converter’s forward mode active power flow or numpy.nan if unavailable.
    dv_p_bwd_min: (hynet_float_)
    Dual variable or KKT multiplier of the lower bound on the converter’s backward mode active power flow or numpy.nan if unavailable.
    dv_p_bwd_max: (hynet_float_)
    Dual variable or KKT multiplier of the upper bound on the converter’s backward mode active power flow or numpy.nan if unavailable.
    dv_cap_src_q_min: (hynet_float_)
    Dual variable or KKT multiplier of the reactive power lower bound of the capability region at the source bus or numpy.nan if unavailable.
    dv_cap_src_q_max: (hynet_float_)
    Dual variable or KKT multiplier of the reactive power upper bound of the capability region at the source bus or numpy.nan if unavailable.
    dv_cap_dst_q_min: (hynet_float_)
    Dual variable or KKT multiplier of the reactive power lower bound of the capability region at the destination bus or numpy.nan if unavailable.
    dv_cap_dst_q_max: (hynet_float_)
    Dual variable or KKT multiplier of the reactive power upper bound of the capability region at the destination bus or numpy.nan if unavailable.
  • injector (pandas.DataFrame) –

    Unavailable if the result is empty and, otherwise, a data frame with the injector result data, indexed by the injector ID, which comprises at least the following columns:

    s: (hynet_complex_)
    Apparent power injection in MVA.
    cost_p: (hynet_float_)
    Cost of the active power injection in dollars or numpy.nan if no cost function was provided.
    cost_q: (hynet_float_)
    Cost of the reactive power injection in dollars or numpy.nan if no cost function was provided.
    dv_cap_p_min: (hynet_float_)
    Dual variable or KKT multiplier of the active power lower bound of the capability region or numpy.nan if unavailable.
    dv_cap_q_min: (hynet_float_)
    Dual variable or KKT multiplier of the reactive power lower bound of the capability region or numpy.nan if unavailable.
    dv_cap_p_max: (hynet_float_)
    Dual variable or KKT multiplier of the active power upper bound of the capability region or numpy.nan if unavailable.
    dv_cap_q_max: (hynet_float_)
    Dual variable or KKT multiplier of the reactive power upper bound of the capability region or numpy.nan if unavailable.

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.
[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.
details

Return a formatted string with details of the system’s state.

The returned string contains a formatted table for all major entity types, which is hopefully mostly self-explaining. In the very left or right of a column, there may be an indicator:

Indicator Meaning
R Reference bus in the respective subgrid.
= The bus is a DC bus. If there is no indicator, the bus is an AC bus.
* A limit on the respective quantity is active.
> The branch is highly loaded, i.e., the flow is 90% or more of the effective rating.
T The branch is a transformer. If there is no indicator, the branch is a line/cable.
get_branch_utilization()[source]

Return a pandas Series with the branch utilization.

Returns:branch_utilization – Utilization of the branches as the ratio of the MVA branch flow over the effective rating or numpy.nan for unrated branches.
Return type:pandas.Series
get_dynamic_losses()[source]

Return the dynamic losses in MW.

get_total_injection_cost()[source]

Return the total injection cost in $/h.

get_total_losses()[source]

Return the total losses in MW.

The total losses comprise the dynamic losses and the static losses of the converters.

has_valid_converter_flows

Return True if the converter loss error is within the model’s tolerance.

has_valid_power_balance

Return True if the power balance error is within the model’s tolerance.

is_physical

Return True if the flow errors are within the model’s tolerance.

is_valid

Return True if the result is considered as valid.

For a result to be valid, the solved must have terminated with the solver status SOLVED and the converter loss error and the power balance error must be within the model’s tolerance.

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.

scenario

Return the scenario data of the system model.

hynet.system.result.ensure_result_availability(func)[source]

Decorates a result evaluation function with a result data availability check.

Functions that evaluate the result data typically require a check if the result data is available. This decorator offers a convenient and unified way to augment a result evaluation function with such a check, where the function must take a SystemResult-based object as the first argument.

Module contents

Steady-state system model representations in hynet.