hynet.opf package

Submodules

hynet.opf.calc module

Calculation of the optimal power flow.

hynet.opf.calc.calc_opf(data, scenario_id=0, solver=None, solver_type=<SolverType.QCQP: 'QCQP'>, initial_point_generator=None, converter_loss_error_tolerance=0.0005)[source]

Calculate the optimal power flow.

This function formulates and solves the optimal power flow (OPF) problem. The solver or solver type may be specified explicitly, otherwise an appropriate solver is selected automatically.

Parameters:
  • data (DBConnection or Scenario or OPFModel) – Connection to a hynet grid database, a Scenario object, or a OPFModel object.
  • scenario_id (hynet_id_, optional) – Identifier of the scenario. This argument is ignored if data is a Scenario or OPFModel object.
  • 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). By default, an appropriate initial point generator is selected if a computationally efficient SOCR solver is installed. Set to None to skip the initial point generation.
  • converter_loss_error_tolerance (hynet_float_, optional) – Tolerance for the converter loss error in MW (default 5e-4). If None, the OPF model’s (default) setting is retained.
Returns:

result – Optimal power flow solution.

Return type:

OPFResult

hynet.opf.calc.get_default_initial_point_generator()[source]

Return the default initial point generator for the current system.

If a sufficiently efficient SOCR solver is available, the utilization of a copper plate based initial point for the solution of the nonconvex QCQP typically improves the overall performance, i.e., that the reduced number of iterations of the QCQP solver outweighs the computational cost for the initial point.

hynet.opf.initial_point module

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

class hynet.opf.initial_point.CopperPlateInitialPointGenerator(solver)[source]

Bases: hynet.system.initial_point.InitialPointGenerator

Copper plate based initial point generator for the QCQP OPF solvers.

This generator returns an initial point for the solution of the OPF QCQP that comprises the optimal dispatch of the copper plate reduction of the model. The copper plate solution is typically fast to compute and can reduce the number of iterations required to solve the nonconvex QCQP, i.e., it can improve the overall performance when solving the nonconvex problem.

solver

Return the solver for the initial point computation.

hynet.opf.model module

Optimal power flow model of hynet.

class hynet.opf.model.OPFModel(scenario, verify_scenario=True)[source]

Bases: hynet.system.model.SystemModel

Optimal power flow 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 a quadratically constrained quadratic program (QCQP) that captures the optimal power flow problem.

See also

hynet.scenario.representation.Scenario
Specification of a steady-state grid scenario.
hynet.opf.calc.calc_opf
Calculate an optimal power flow.
create_result(qcqp_result, total_time=nan, qcqp_result_pre=None)[source]

Create and return an OPF result object.

Parameters:
  • qcqp_result (hynet.qcqp.result.QCQPResult) – Solution of the OPF QCQP.
  • total_time (hynet_float_, optional) – Total time for solving the OPF, cf. hynet.opf.calc.calc_opf.
  • qcqp_result_pre (QCQPResult, optional) – Pre-solution of the OPF QCQP for converter mode detection.
Returns:

result

Return type:

hynet.opf.result.OPFResult

hynet.opf.model.select_cost_scaling(scenario)[source]

Return a suitable scaling factor for the objective of the OPF problem.

hynet.opf.result module

Representation of an optimal power flow result.

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

Bases: hynet.system.result.SystemResult

Result of an optimal power flow calculation.

Remark: In the data frames below, the respective column for the dual variables of a type of constraint (e.g., voltage drop) is only present if at least one constraint of this constraint type appears in the problem formulation.

Parameters:
  • model (OPFModel) – Model for the processed optimal power flow 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 OPF 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 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 in $/MW. In case of exactness of the relaxation (or zero duality gap in the QCQP), these dual variables equal the locational marginal prices (LMPs) for active power, cf. [1].
    dv_bal_q: (hynet_float_)
    Dual variable or KKT multiplier of the reactive power balance constraint in $/Mvar. In case of exactness of the relaxation (or zero duality gap in the QCQP), these dual variables equal the locational marginal prices (LMPs) for reactive power, cf. [1].
    dv_v_min: (hynet_float_)
    Dual variable or KKT multiplier of the voltage lower bound in $/p.u..
    dv_v_max: (hynet_float_)
    Dual variable or KKT multiplier of the voltage upper bound in $/p.u..
  • 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 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 OPF or numpy.nan otherwise.
    dv_i_max_src: (hynet_float_)
    Dual variable or KKT multiplier of the ampacity constraint at the source bus in $/p.u. or numpy.nan if unavailable.
    dv_i_max_dst: (hynet_float_)
    Dual variable or KKT multiplier of the ampacity constraint at the destination bus in $/p.u. or numpy.nan if unavailable.
    dv_angle_min: (hynet_float_)
    Dual variable or KKT multiplier of the angle difference lower bound constraint or numpy.nan if unavailable.
    dv_angle_max: (hynet_float_)
    Dual variable or KKT multiplier of the angle difference upper bound constraint or numpy.nan if unavailable.
    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.
    dv_drop_min: (hynet_float_)
    Dual variable or KKT multiplier of the voltage drop lower bound constraint or numpy.nan if unavailable.
    dv_drop_max: (hynet_float_)
    Dual variable or KKT multiplier of the voltage drop upper bound constraint 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 the following columns:

    p_src: (hynet_complex_)
    Active power flow in MW at the source bus into the converter.
    p_dst: (hynet_complex_)
    Active power flow in MW at the destination bus into the converter.
    q_src: (hynet_complex_)
    Reactive power injection in Mvar at the source bus into the grid.
    q_dst: (hynet_complex_)
    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 OPF 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 in $/MW 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 in $/MW 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 in $/MW 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 in $/MW 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 in $/Mvar 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 in $/Mvar 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 in $/Mvar 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 in $/Mvar or numpy.nan if unavailable.
    dv_cap_src_lt: (hynet_float_)
    Dual variable or KKT multiplier of the left-top half-space of of the capability region at the source bus in $/MVA or numpy.nan if unavailable.
    dv_cap_src_rt: (hynet_float_)
    Dual variable or KKT multiplier of the right-top half-space of of the capability region at the source bus in $/MVA or numpy.nan if unavailable.
    dv_cap_src_lb: (hynet_float_)
    Dual variable or KKT multiplier of the left-bottom half-space of of the capability region at the source bus in $/MVA or numpy.nan if unavailable.
    dv_cap_src_rb: (hynet_float_)
    Dual variable or KKT multiplier of the right-bottom half-space of of the capability region at the source bus in $/MVA or numpy.nan if unavailable.
    dv_cap_dst_lt: (hynet_float_)
    Dual variable or KKT multiplier of the left-top half-space of of the capability region at the destination bus in $/MVA or numpy.nan if unavailable.
    dv_cap_dst_rt: (hynet_float_)
    Dual variable or KKT multiplier of the right-top half-space of of the capability region at the destination bus in $/MVA or numpy.nan if unavailable.
    dv_cap_dst_lb: (hynet_float_)
    Dual variable or KKT multiplier of the left-bottom half-space of of the capability region at the destination bus in $/MVA or numpy.nan if unavailable.
    dv_cap_dst_rb: (hynet_float_)
    Dual variable or KKT multiplier of the right-bottom half-space of of the capability region at the destination bus in $/MVA 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 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 in $/MW 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 in $/Mvar 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 in $/MW 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 in $/Mvar or numpy.nan if unavailable.
    dv_cap_lt: (hynet_float_)
    Dual variable or KKT multiplier of the left-top half-space of the capability region in $/MVA or numpy.nan if unavailable.
    dv_cap_rt: (hynet_float_)
    Dual variable or KKT multiplier of the right-top half-space of the capability region in $/MVA or numpy.nan if unavailable.
    dv_cap_lb: (hynet_float_)
    Dual variable or KKT multiplier of the left-bottom half-space of the capability region in $/MVA or numpy.nan if unavailable.
    dv_cap_rb: (hynet_float_)
    Dual variable or KKT multiplier of the right-bottom half-space of the capability region in $/MVA or numpy.nan if unavailable.

References

[1](1, 2, 3) 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.

hynet.opf.visual module

Visualization functionality for optimal power flow results.

hynet.opf.visual.show_ampacity_dual_profile(result, id_label=False)[source]

Show the ampacity dual variable profile for an OPF result.

For a consistent appearance in case of nonconsecutive or custom IDs, the branches are numbered consecutively starting from 1 for the labeling of the x-axis. To enforce labeling of the ticks with the IDs, set id_label=True.

Parameters:
  • result (OPFResult) – Optimal power flow result that shall be visualized.
  • id_label (bool, optional) – If True, the linear ticks are relabeled with the branch IDs.
Returns:

fig

Return type:

matplotlib.figure.Figure

hynet.opf.visual.show_branch_flow_profile(result, id_label=False)[source]

Show the branch flow profile for an OPF result.

For a consistent appearance in case of nonconsecutive or custom IDs, the branches are numbered consecutively starting from 1 for the labeling of the x-axis. To enforce labeling of the ticks with the IDs, set id_label=True.

Parameters:
  • result (OPFResult) – Optimal power flow result that shall be visualized.
  • id_label (bool, optional) – If True, the linear ticks are relabeled with the branch IDs.
Returns:

fig

Return type:

matplotlib.figure.Figure

hynet.opf.visual.show_branch_reconstruction_error(result, show_s_bal_err=True, show_p_bal_err=False, show_q_bal_err=False, show_p_dual=True, show_q_dual=True, show_z_bar_abs=False, show_z_bar_real=False, show_z_bar_imag=False)[source]

Show the branch-related reconstruction error for an OPF result.

If the SOCR of an OPF problem is solved and the graph traversal based rank-1 approximation is used, the branch-related “contributions” to the reconstruction error (and, if present, inexactness of the relaxation) are characterized by \(\kappa_k(V^\star)\) defined in equation (24) in [1]. Especially if the scenario features the hybrid architecture and inexactness occurred, this visualization may assist in finding the cause of the pathological price profile (see also [1], Section VII, for more details).

Parameters:
  • result (OPFResult) – Optimal power flow result that shall be visualized.
  • show_s_bal_err (bool, optional) – If True (default), the maximum apparent power balance error magnitude at the adjacent buses of the branches is shown as well.
  • show_p_bal_err (bool, optional) – If True (default False), the maximum active power balance error modulus at the adjacent buses of the branches is shown as well.
  • show_q_bal_err (bool, optional) – If True (default False), the maximum reactive power balance error modulus at the adjacent buses of the branches is shown as well.
  • show_p_dual (bool, optional) – If True (default), the minimum active power balance dual variable at the adjacent buses of the branches is shown as well.
  • show_q_dual (bool, optional) – If True (default), the minimum reactive power balance dual variable at the adjacent buses of the branches is shown as well.
  • show_z_bar_abs (bool, optional) – If True (default False), the modulus of the branch series impedance is shown as well.
  • show_z_bar_real (bool, optional) – If True (default False), the modulus of the branch series resistance is shown as well.
  • show_z_bar_imag (bool, optional) – If True (default False), the modulus of the branch series reactance is shown as well.
Returns:

fig

Return type:

matplotlib.figure.Figure

References

[1](1, 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.
hynet.opf.visual.show_converter_flow_profile(result, id_label=False)[source]

Show the converter active power flow profile for an OPF result.

For a consistent appearance in case of nonconsecutive or custom IDs, the converters are numbered consecutively starting from 1 for the labeling of the x-axis. To enforce labeling of the ticks with the IDs, set id_label=True.

Parameters:
  • result (OPFResult) – Optimal power flow result that shall be visualized.
  • id_label (bool, optional) – If True, the linear ticks are relabeled with the converter IDs.
Returns:

fig

Return type:

matplotlib.figure.Figure

hynet.opf.visual.show_dispatch_profile(result, id_label=False)[source]

Show the active power injector dispatch profile for an OPF result.

For a consistent appearance in case of nonconsecutive or custom IDs, the injectors are numbered consecutively starting from 1 for the labeling of the x-axis. To enforce labeling of the ticks with the IDs, set id_label=True.

Parameters:
  • result (OPFResult) – Optimal power flow result that shall be visualized.
  • id_label (bool, optional) – If True, the linear ticks are relabeled with the injector IDs.
Returns:

fig

Return type:

matplotlib.figure.Figure

hynet.opf.visual.show_lmp_profile(result, id_label=False)[source]

Show the LMP profile or power balance dual variables for an OPF result.

For a consistent appearance in case of nonconsecutive or custom IDs, the buses are numbered consecutively starting from 1 for the labeling of the x-axis. To enforce labeling of the ticks with the IDs, set id_label=True.

Parameters:
  • result (OPFResult) – Optimal power flow result that shall be visualized.
  • id_label (bool, optional) – If True, the linear ticks are relabeled with the bus IDs.
Returns:

fig

Return type:

matplotlib.figure.Figure

hynet.opf.visual.show_power_balance_error(result, show_duals=True, split_acdc=True, id_label=False)[source]

Show the power balance error at all AC and DC buses for an OPF result.

Parameters:
  • result (OPFResult) – Optimal power flow result that shall be visualized.
  • show_duals (bool, optional) – If True (default), the active and reactive power balance dual variables are shown as well.
  • split_acdc (bool, optional) – If True (default), the results are shown separate plots for AC and DC buses. In this case, no x-axis labels are provided. Otherwise, all buses are shown in one plot and, for the x-axis labels, the buses are numbered consecutively starting from 1.
  • id_label (bool, optional) – If True (default False), the linear x-axis ticks are relabeled with the bus IDs.
Returns:

fig

Return type:

matplotlib.figure.Figure

hynet.opf.visual.show_voltage_profile(result, id_label=False)[source]

Show the voltage profile for an OPF result.

For a consistent appearance in case of nonconsecutive or custom IDs, the buses are numbered consecutively starting from 1 for the labeling of the x-axis. To enforce labeling of the ticks with the IDs, set id_label=True.

Parameters:
  • result (OPFResult) – Optimal power flow result that shall be visualized.
  • id_label (bool, optional) – If True, the linear ticks are relabeled with the bus IDs.
Returns:

fig

Return type:

matplotlib.figure.Figure

Module contents

Optimal power flow functionality in hynet.