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
Scenarioobject, or aOPFModelobject. - scenario_id (hynet_id_, optional) – Identifier of the scenario. This argument is ignored if
datais aScenarioorOPFModelobject. - 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 ifsolveris notNone. - 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
Noneto skip the initial point generation. - converter_loss_error_tolerance (hynet_float_, optional) – Tolerance for the converter loss error in MW (default
5e-4). IfNone, the OPF model’s (default) setting is retained.
Returns: result – Optimal power flow solution.
Return type: See also
hynet.scenario.representation.Scenario(),hynet.opf.result.OPFResult(),hynet.reduction.copper_plate.reduce_to_copper_plate()hynet.opf.initial_point()- Initial point generators.
- data (DBConnection or Scenario or OPFModel) – Connection to a hynet grid database, a
-
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.InitialPointGeneratorCopper 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.SystemModelOptimal power flow model for a steady-state scenario of a grid.
Based on the specification of a scenario via a
Scenarioobject, 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 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.SystemResultResult 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) –
Trueif the object does not contain any result data andFalseotherwise. - 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.nanif 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.nanotherwise. - 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.nanotherwise. dv_i_max_src: (hynet_float_)- Dual variable or KKT multiplier of the ampacity constraint at the
source bus in $/p.u. or
numpy.nanif 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.nanif unavailable. dv_angle_min: (hynet_float_)- Dual variable or KKT multiplier of the angle difference lower bound
constraint or
numpy.nanif unavailable. dv_angle_max: (hynet_float_)- Dual variable or KKT multiplier of the angle difference upper bound
constraint or
numpy.nanif 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.nanif unavailable. dv_drop_min: (hynet_float_)- Dual variable or KKT multiplier of the voltage drop lower bound
constraint or
numpy.nanif unavailable. dv_drop_max: (hynet_float_)- Dual variable or KKT multiplier of the voltage drop upper bound
constraint or
numpy.nanif 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.nanif 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.nanif 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.nanif 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.nanif 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.nanif 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.nanif 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.nanif 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.nanif 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.nanif 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.nanif 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.nanif 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.nanif 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.nanif 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.nanif 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.nanif 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.nanif 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.nanif no cost function was provided. cost_q: (hynet_float_)- Cost of the reactive power injection in dollars or
numpy.nanif 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.nanif 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.nanif 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.nanif 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.nanif 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.nanif 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.nanif 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.nanif 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.nanif 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(defaultFalse), 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(defaultFalse), 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(defaultFalse), the modulus of the branch series impedance is shown as well. - show_z_bar_real (bool, optional) – If
True(defaultFalse), the modulus of the branch series resistance is shown as well. - show_z_bar_imag (bool, optional) – If
True(defaultFalse), the modulus of the branch series reactance is shown as well.
Returns: fig
Return type: matplotlib.figure.Figure
See also
hynet.opf.visual.show_power_balance_error(),hynet.scenario.representation.Scenario.verify_hybrid_architecture_conditions(),hynet.qcqp.rank1approx.GraphTraversalRank1Approximator()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(defaultFalse), 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.