Skip to main content

surge_solution/
par.rs

1// SPDX-License-Identifier: LicenseRef-PolyForm-Noncommercial-1.0.0
2//! Phase-shifting transformer (PAR) flow-setpoint types for DC-OPF and SCED.
3
4use serde::{Deserialize, Serialize};
5
6/// A phase-shifting transformer (PAR) operating in flow-setpoint mode.
7///
8/// When included in `DcOpfOptions::par_setpoints` or `DispatchOptions::par_setpoints`,
9/// the PAR branch is removed from the passive B matrix and replaced by fixed
10/// scheduled injections at its terminal buses.  The solver then determines
11/// the remaining network angles, and the implied shift angle is computed post-solve.
12///
13/// This is the standard RTO approach for modelling manually-controlled PARs
14/// (also called Phase-Angle Regulators or TAPs) in DC market clearing.
15#[derive(Debug, Clone, Serialize, Deserialize)]
16pub struct ParSetpoint {
17    /// From-bus number (external).
18    pub from_bus: u32,
19    /// To-bus number (external).
20    pub to_bus: u32,
21    /// Circuit identifier matching `Branch::circuit`.
22    pub circuit: String,
23    /// Target MW flow from `from_bus` to `to_bus` (positive = forward direction).
24    pub target_mw: f64,
25}
26
27/// Post-solve PAR result: actual implied shift angle for a flow-setpoint PAR.
28#[derive(Debug, Clone, Serialize, Deserialize)]
29pub struct ParResult {
30    /// From-bus number (external).
31    pub from_bus: u32,
32    /// To-bus number (external).
33    pub to_bus: u32,
34    /// Circuit identifier.
35    pub circuit: String,
36    /// Target MW flow requested.
37    pub target_mw: f64,
38    /// Implied shift angle in degrees: φ = (θ_from − θ_to − target/(base × b_dc)) × (180/π)
39    ///
40    /// This is the PST angle that would produce the requested flow given the
41    /// post-optimization network angles.  Positive = from_bus leads to_bus.
42    pub implied_shift_deg: f64,
43    /// Whether the implied shift is within the branch control's radian bounds.
44    ///
45    /// `false` when the required angle exceeds the PAR's mechanical limits.
46    pub within_limits: bool,
47}