Source code for monee.model.phys.misoc.pf

# Branch-Flow SOCP with an ideal a:1 transformer in series with Z = r + jx.
#   W_j = W_i / a^2 - 2(r \cdot P + x \cdot Q) + |Z|^2 \cdot ell
#   P^2 + Q^2 \le (W_i / a^2) \cdot ell
# Losses are tap-free (ideal transformer is lossless). tap=1 reduces to BFM.


[docs] def active_power_loss( var_active_power_from, var_active_power_to, var_ell_pu, resistance_r ): return var_active_power_from == var_ell_pu * resistance_r - var_active_power_to
[docs] def reactive_power_loss( var_reactive_power_from, var_reactive_power_to, var_ell_pu, reactance_x ): return var_reactive_power_from == var_ell_pu * reactance_x - var_reactive_power_to
[docs] def voltage_drop( var_w_pu_i, var_w_pu_j, var_active_power_ij_pu, var_reactive_power_ij_pu, var_ell_pu, resistance_r, reactance_x, tap=1.0, ): return var_w_pu_j - ( var_w_pu_i / (tap * tap) - 2 * ( resistance_r * var_active_power_ij_pu + reactance_x * var_reactive_power_ij_pu ) + (resistance_r**2 + reactance_x**2) * var_ell_pu )
[docs] def soc_rel( var_w_pu_i, var_active_power_ij_pu, var_reactive_power_ij_pu, var_ell_pu, tap=1.0, ): r"""Rotated SOC :math:`P^2 + Q^2 \le (W/tap^2) \cdot ell`. See :func:`soc_rel_lorentz` for the Lorentz reformulation that survives non-convex MIQCP siblings.""" return ( var_active_power_ij_pu**2 + var_reactive_power_ij_pu**2 <= (var_w_pu_i / (tap * tap)) * var_ell_pu )
[docs] def soc_eq( var_w_pu_i, var_active_power_ij_pu, var_reactive_power_ij_pu, var_ell_pu, tap=1.0, ): r"""Exact (non-convex) form of :func:`soc_rel`: :math:`P^2 + Q^2 = (W/tap^2) \cdot ell`. Pins the branch-flow model to the physical surface; requires a global MIQCQP solver (SCIP, Gurobi).""" return ( var_active_power_ij_pu**2 + var_reactive_power_ij_pu**2 == (var_w_pu_i / (tap * tap)) * var_ell_pu )
[docs] def soc_rel_lorentz( var_w_pu_i, var_active_power_ij_pu, var_reactive_power_ij_pu, var_ell_pu, var_soc_sum, var_soc_diff, tap=1.0, ): r"""Lorentz form of :func:`soc_rel`: :math:`s = (W/tap^2+ell)/2`, :math:`d = (W/tap^2-ell)/2`, :math:`P^2 + Q^2 + d^2 \le s^2` (since :math:`s^2 - d^2 = (W/tap^2) \cdot ell`).""" w_p = var_w_pu_i / (tap * tap) return [ var_soc_sum == 0.5 * (w_p + var_ell_pu), # NOSONAR var_soc_diff == 0.5 * (w_p - var_ell_pu), # NOSONAR var_active_power_ij_pu**2 + var_reactive_power_ij_pu**2 + var_soc_diff**2 <= var_soc_sum**2, ]
[docs] def gap_expr( var_w_pu_i, var_active_power_ij_pu, var_reactive_power_ij_pu, var_ell_pu, tap=1.0, ): return (var_w_pu_i / (tap * tap)) * var_ell_pu - ( var_active_power_ij_pu**2 + var_reactive_power_ij_pu**2 )