Module ml4opf.formulations.ac.violation
Class interface for ACOPF constraints, objective, etc.
Classes
class ACViolation (data: dict[str, torch.Tensor])
-
OPFViolation
for ACOPFInitialize internal Module state, shared by both nn.Module and ScriptModule.
Ancestors
- OPFViolation
- torch.nn.modules.module.Module
- abc.ABC
Methods
def angle_difference(self, va: torch.Tensor) ‑> torch.Tensor
-
Compute the angle differences per branch given the voltage angles per bus.
\text{dva} = \boldsymbol{\theta}_{f} - \boldsymbol{\theta}_{t}
Args
va
:Tensor
- Voltage angles per bus ( \boldsymbol{\theta} ). (batch_size, nbus)
Returns
Tensor
- Angle differences per branch. (batch_size, nbranch)
def balance_residual(self,
pd: torch.Tensor,
qd: torch.Tensor,
pg: torch.Tensor,
qg: torch.Tensor,
vm: torch.Tensor,
pf: torch.Tensor,
pt: torch.Tensor,
qf: torch.Tensor,
qt: torch.Tensor,
clamp: bool = False,
embed_method: str = 'pad') ‑> tuple[torch.Tensor, torch.Tensor]-
Calculate the power balance residual.
Component-wise tensors are first embedded to the bus level using
embed_method
.The shunt parameters g_s, b_s are assumed to be constant, matching the reference case.
\text{p_viol} = \text{pg_bus} - \text{pd_bus} - \text{pt_bus} - \text{pf_bus} - \text{gs_bus} \times \text{vm}^2 \text{q_viol} = \text{qg_bus} - \text{qd_bus} - \text{qt_bus} - \text{qf_bus} + \text{bs_bus} \times \text{vm}^2
Args
pd
:Tensor
- Active power demand per bus. (batch_size, nbus)
qd
:Tensor
- Reactive power demand per bus. (batch_size, nbus)
pg
:Tensor
- Active power generation per generator. (batch_size, ngen)
qg
:Tensor
- Reactive power generation per generator. (batch_size, ngen)
vm
:Tensor
- Voltage magnitude per bus. (batch_size, nbus)
pf
:Tensor
- Active power flow from bus per branch. (batch_size, nbranch)
pt
:Tensor
- Active power flow to bus per branch. (batch_size, nbranch)
qf
:Tensor
- Reactive power flow from bus per branch. (batch_size, nbranch)
qt
:Tensor
- Reactive power flow to bus per branch. (batch_size, nbranch)
clamp
:bool
, optional- Apply an absolute value to the residual. Defaults to False.
embed_method
:str
, optional- Embedding method for bus-level components. Defaults to 'pad'. Must be one of 'pad', 'dense_matrix', or 'matrix. See
IncidenceMixin.*_to_bus
.
Returns
Tensor
- Power balance residual for active power. (batch_size, nbus)
Tensor
- Power balance residual for reactive power. (batch_size, nbus)
def calc_violations(self,
pd: torch.Tensor,
qd: torch.Tensor,
pg: torch.Tensor,
qg: torch.Tensor,
vm: torch.Tensor,
va: torch.Tensor | None = None,
dva: torch.Tensor | None = None,
flows: tuple[torch.Tensor, torch.Tensor, torch.Tensor, torch.Tensor] | None = None,
reduction: str | None = 'mean',
clamp: bool = True) ‑> dict[str, torch.Tensor]-
Calculate the violation of all the constraints.
The reduction is applied across the component dimension - e.g., 'mean' will do violation.mean(dim=1) where each violation is (batch, components)
Args
pd
:Tensor
- Real power demand. (batch, loads)
qd
:Tensor
- Reactive power demand. (batch, loads)
pg
:Tensor
- Real power generation. (batch, gens)
qg
:Tensor
- Reactive power generation. (batch, gens)
vm
:Tensor
- Voltage magnitude. (batch, buses)
va
:Tensor
, optional- Voltage angle. (batch, buses)
dva
:Tensor
, optional- Voltage angle difference. (batch, branches)
flows
:tuple[Tensor, Tensor, Tensor, Tensor]
, optional- Power flows. (pf, pt, qf, qt)
reduction
:str
, optional- Reduction method. Defaults to 'mean'. Must be one of 'mean', 'sum', 'none'.
clamp
:bool
, optional- Clamp the residual to be non-negative (extract violations). Defaults to True.
Returns
- dict[str, Tensor]: Dictionary of violations.
vm_lower
: Voltage magnitude lower bound violation.vm_upper
: Voltage magnitude upper bound violation.pg_lower
: Real power generation lower bound violation.pg_upper
: Real power generation upper bound violation.qg_lower
: Reactive power generation lower bound violation.qg_upper
: Reactive power generation upper bound violation.thrm_1
: Thermal limit from violation.thrm_2
: Thermal limit to violation.p_balance
: Real power balance violation.q_balance
: Reactive power balance violation.dva_lower
: Voltage angle difference lower bound violation.dva_upper
: Voltage angle difference upper bound violation. def dva_bound_residual(self, dva: torch.Tensor, clamp: bool = False) ‑> tuple[torch.Tensor, torch.Tensor]
-
Calculate the voltage angle difference bound residual.
g_{\text{lower}} = \text{angmin} - \text{dva} g_{\text{upper}} = \text{dva} - \text{angmax}
Args
dva
:Tensor
- Voltage angle difference per branch. (batch_size, nbranch)
clamp
:bool
, optional- Clamp the residual to be non-negative (extract violations). Defaults to False.
Returns
Tensor
- Lower bound residual. (batch_size, nbranch)
Tensor
- Upper bound residual. (batch_size, nbranch)
def flows_from_voltage(self, vm: torch.Tensor, dva: torch.Tensor) ‑> tuple[torch.Tensor, torch.Tensor, torch.Tensor, torch.Tensor]
-
Compute the power flows given the voltage magnitude and angle differences.
Args
vm
:Tensor
- Voltage magnitude per bus ( \mathbf{v} ). (batch_size, nbus)
dva
:Tensor
- Angle differences per branch ( \boldsymbol{\theta}_f - \boldsymbol{\theta}_t ). (batch_size, nbranch)
Returns
Tensor
- Real power flow per branch ( \mathbf{p}_f ). (batch_size, nbranch)
Tensor
- Real power flow per branch ( \mathbf{p}_t ). (batch_size, nbranch)
Tensor
- Reactive power flow per branch ( \mathbf{q}_f ). (batch_size, nbranch)
Tensor
- Reactive power flow per branch ( \mathbf{q}_t ). (batch_size, nbranch)
def flows_from_voltage_bus(self, vm: torch.Tensor, va: torch.Tensor) ‑> tuple[torch.Tensor, torch.Tensor, torch.Tensor, torch.Tensor]
-
Compute the power flows given the voltage magnitude per bus and voltage angles per bus.
This function computes angle differences then calls
ACPViolation.flows_from_voltage
. See the docstring ofACPViolation.flows_from_voltage
for more details.Args
vm
:Tensor
- Voltage magnitude per bus ( \mathbf{v} ). (batch_size, nbus)
va
:Tensor
- Voltage angle per bus ( \boldsymbol{\theta} ). (batch_size, nbus)
Returns
Tensor
- Real power flow per branch ( \mathbf{p}_f ). (batch_size, nbranch)
Tensor
- Real power flow per branch ( \mathbf{p}_t ). (batch_size, nbranch)
Tensor
- Reactive power flow per branch ( \mathbf{q}_f ). (batch_size, nbranch)
Tensor
- Reactive power flow per branch ( \mathbf{q}_t ). (batch_size, nbranch)
def objective(self, pg: torch.Tensor) ‑> torch.Tensor
-
Compute the objective function given the active power generation per generator.
Args
pg
:Tensor
- Active power generation per generator. (batch_size, ngen)
Returns
Tensor
- Objective function value. (batch_size)
def pg_bound_residual(self, pg: torch.Tensor, clamp: bool = False) ‑> tuple[torch.Tensor, torch.Tensor]
-
Calculate the active power generation bound residual.
g_{\text{lower}} = \text{pmin} - \text{pg} g_{\text{upper}} = \text{pg} - \text{pmax}
Args
pg
:Tensor
- Active power generation per generator. (batch_size, ngen)
clamp
:bool
, optional- Clamp the residual to be non-negative (extract violations). Defaults to False.
Returns
Tensor
- Lower bound residual. (batch_size, ngen)
Tensor
- Upper bound residual. (batch_size, ngen)
def qg_bound_residual(self, qg: torch.Tensor, clamp: bool = False) ‑> tuple[torch.Tensor, torch.Tensor]
-
Calculate the reactive power generation bound residual.
g_{\text{lower}} = \text{qmin} - \text{qg} g_{\text{upper}} = \text{qg} - \text{qmax}
Args
qg
:Tensor
- Reactive power generation per generator. (batch_size, ngen)
clamp
:bool
, optional- Clamp the residual to be non-negative (extract violations). Defaults to False.
Returns
Tensor
- Lower bound residual. (batch_size, ngen)
Tensor
- Upper bound residual. (batch_size, ngen)
def thermal_residual(self,
pf: torch.Tensor,
pt: torch.Tensor,
qf: torch.Tensor,
qt: torch.Tensor,
clamp: bool = False) ‑> tuple[torch.Tensor, torch.Tensor]-
Calculate the thermal limit residual.
g_{\text{thrm}_1} = \text{pf}^2 + \text{qf}^2 - \text{s1max} g_{\text{thrm}_2} = \text{pt}^2 + \text{qt}^2 - \text{s2max}
Args
pf
:Tensor
- Active power flow from bus per branch. (batch_size, nbranch)
pt
:Tensor
- Active power flow to bus per branch. (batch_size, nbranch)
qf
:Tensor
- Reactive power flow from bus per branch. (batch_size, nbranch)
qt
:Tensor
- Reactive power flow to bus per branch. (batch_size, nbranch)
clamp
:bool
, optional- Clamp the residual to be non-negative (extract violations). Defaults to False.
Returns
Tensor
- Thermal limit residual for from branch. (batch_size, nbranch)
Tensor
- Thermal limit residual for to branch. (batch_size, nbranch)
def vm_bound_residual(self, vm: torch.Tensor, clamp: bool = False) ‑> tuple[torch.Tensor, torch.Tensor]
-
Calculate the voltage magnitude bound residual.
g_{\text{lower}} = \text{vmin} - \text{vm} g_{\text{upper}} = \text{vm} - \text{vmax}
Args
vm
:Tensor
- Voltage magnitude per bus. (batch_size, nbus)
clamp
:bool
, optional- Clamp the residual to be non-negative (extract violations). Defaults to False.
Returns
Tensor
- Lower bound residual. (batch_size, nbus)
Tensor
- Upper bound residual. (batch_size, nbus)
Inherited members