Skip to main content

surge_network/network/
refs.rs

1// SPDX-License-Identifier: LicenseRef-PolyForm-Noncommercial-1.0.0
2//! Stable public equipment references used by the canonical network model.
3
4use serde::{Deserialize, Serialize};
5
6use crate::network::Branch;
7
8/// Stable directional branch identity.
9///
10/// Unlike [`crate::network::BranchEquipmentKey`], this preserves authored
11/// direction so interfaces, flowgates, and equipment refs can express a signed
12/// flow convention directly.
13#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
14pub struct BranchRef {
15    pub from_bus: u32,
16    pub to_bus: u32,
17    pub circuit: String,
18}
19
20impl BranchRef {
21    pub fn new(from_bus: u32, to_bus: u32, circuit: impl Into<String>) -> Self {
22        Self {
23            from_bus,
24            to_bus,
25            circuit: circuit.into(),
26        }
27    }
28
29    pub fn matches_branch(&self, branch: &Branch) -> bool {
30        branch.from_bus == self.from_bus
31            && branch.to_bus == self.to_bus
32            && branch.circuit == self.circuit
33    }
34}
35
36impl From<(u32, u32, String)> for BranchRef {
37    fn from(value: (u32, u32, String)) -> Self {
38        Self::new(value.0, value.1, value.2)
39    }
40}
41
42impl From<&(u32, u32, String)> for BranchRef {
43    fn from(value: &(u32, u32, String)) -> Self {
44        Self::new(value.0, value.1, value.2.clone())
45    }
46}
47
48impl From<&Branch> for BranchRef {
49    fn from(value: &Branch) -> Self {
50        Self::new(value.from_bus, value.to_bus, value.circuit.clone())
51    }
52}
53
54impl From<BranchRef> for (u32, u32, String) {
55    fn from(value: BranchRef) -> Self {
56        (value.from_bus, value.to_bus, value.circuit)
57    }
58}
59
60/// A directed branch reference with an associated scalar coefficient.
61#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
62pub struct WeightedBranchRef {
63    pub branch: BranchRef,
64    pub coefficient: f64,
65}
66
67impl WeightedBranchRef {
68    pub fn new(from_bus: u32, to_bus: u32, circuit: impl Into<String>, coefficient: f64) -> Self {
69        Self {
70            branch: BranchRef::new(from_bus, to_bus, circuit),
71            coefficient,
72        }
73    }
74}
75
76#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
77pub struct GeneratorRef {
78    pub bus: u32,
79    pub id: String,
80}
81
82#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
83pub struct LoadRef {
84    pub bus: u32,
85    pub id: String,
86}
87
88#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
89pub struct FixedShuntRef {
90    pub bus: u32,
91    pub id: String,
92}
93
94#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
95pub struct SwitchedShuntRef {
96    pub bus: u32,
97    pub id: String,
98}
99
100#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
101pub struct FactsDeviceRef {
102    pub name: String,
103}
104
105#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
106pub struct HvdcLinkRef {
107    pub name: String,
108}
109
110#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
111pub struct DcGridRef {
112    pub id: u32,
113}
114
115#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
116pub struct DcConverterRef {
117    pub grid_id: u32,
118    pub id: String,
119}
120
121#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
122pub struct DcBranchRef {
123    pub grid_id: u32,
124    pub id: String,
125}
126
127#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
128#[serde(rename_all = "snake_case")]
129pub enum LccTerminalSide {
130    Rectifier,
131    Inverter,
132}
133
134#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
135pub struct LccConverterTerminalRef {
136    pub link_name: String,
137    pub terminal: LccTerminalSide,
138}
139
140#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
141pub struct InductionMachineRef {
142    pub bus: u32,
143    pub id: String,
144}
145
146#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
147pub struct BreakerRef {
148    pub bus: u32,
149    pub name: String,
150}
151
152/// Stable public reference to any outage-addressable equipment in the network.
153#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
154#[serde(tag = "kind", rename_all = "snake_case")]
155pub enum EquipmentRef {
156    Generator(GeneratorRef),
157    Branch(BranchRef),
158    Load(LoadRef),
159    Bess(GeneratorRef),
160    LccHvdcLink(HvdcLinkRef),
161    VscHvdcLink(HvdcLinkRef),
162    DcGrid(DcGridRef),
163    LccConverterTerminal(LccConverterTerminalRef),
164    DcBranch(DcBranchRef),
165    FactsDevice(FactsDeviceRef),
166    SwitchedShunt(SwitchedShuntRef),
167    FixedShunt(FixedShuntRef),
168    InductionMachine(InductionMachineRef),
169    Breaker(BreakerRef),
170}