surge_network/network/boundary.rs
1// SPDX-License-Identifier: LicenseRef-PolyForm-Noncommercial-1.0.0
2//! ENTSO-E boundary profile types — TSO-TSO interconnection points,
3//! model authority sets, and external network equivalents (EQBD/BD).
4
5use serde::{Deserialize, Serialize};
6
7/// A TSO-TSO boundary point from the ENTSO-E EQBD profile.
8///
9/// Represents an interconnection point between two control areas (typically
10/// national TSOs). The `connectivity_node_mrid` links to the CIM
11/// `ConnectivityNode` at the boundary; the resolved `bus` is filled in
12/// during network building when the CN can be mapped to a topological bus.
13#[derive(Debug, Clone, Serialize, Deserialize)]
14pub struct BoundaryPoint {
15 /// CIM mRID of the BoundaryPoint object.
16 pub mrid: String,
17 /// mRID of the ConnectivityNode at the boundary.
18 pub connectivity_node_mrid: Option<String>,
19 /// ISO 3166 country code of one side (e.g., "DE").
20 pub from_end_iso_code: Option<String>,
21 /// ISO 3166 country code of the other side (e.g., "FR").
22 pub to_end_iso_code: Option<String>,
23 /// Human-readable name of the "from" end TSO.
24 pub from_end_name: Option<String>,
25 /// Human-readable name of the "to" end TSO.
26 pub to_end_name: Option<String>,
27 /// Short TSO name for the "from" end.
28 pub from_end_name_tso: Option<String>,
29 /// Short TSO name for the "to" end.
30 pub to_end_name_tso: Option<String>,
31 /// True if this is a DC interconnection (HVDC tie).
32 pub is_direct_current: bool,
33 /// True if this boundary point is excluded from area interchange accounting.
34 pub is_excluded_from_area_interchange: bool,
35 /// Resolved bus number (set when the CN maps to a topological bus).
36 pub bus: Option<u32>,
37}
38
39/// Model authority set — TSO ownership of CIM equipment.
40///
41/// Each `ModelAuthoritySet` identifies a TSO or model authority and lists
42/// the equipment mRIDs that belong to it. Used for multi-TSO model merging
43/// (CGM assembly) to track which authority owns which equipment.
44#[derive(Debug, Clone, Serialize, Deserialize)]
45pub struct ModelAuthoritySet {
46 /// CIM mRID of the ModelAuthoritySet.
47 pub mrid: String,
48 /// TSO identifier / short name.
49 pub name: String,
50 /// Full description of the authority.
51 pub description: Option<String>,
52 /// Equipment mRIDs owned by this authority (reverse-lookup from
53 /// `IdentifiedObject.ModelAuthoritySet` references).
54 pub members: Vec<String>,
55}
56
57/// External network equivalent — represents a reduced model of a
58/// neighbouring control area or external system.
59#[derive(Debug, Clone, Serialize, Deserialize)]
60pub struct EquivalentNetworkData {
61 /// CIM mRID.
62 pub mrid: String,
63 /// Name of the equivalent network.
64 pub name: String,
65 /// Description.
66 pub description: Option<String>,
67 /// mRID of the `SubGeographicalRegion` / `GeographicalRegion` this
68 /// equivalent represents.
69 pub region_mrid: Option<String>,
70}
71
72/// External network branch equivalent — a pi-section branch representing
73/// the impedance of a reduced external network.
74///
75/// Impedances are stored in physical ohms (as in the CIM source); downstream
76/// code converts to per-unit when wiring into the admittance matrix.
77#[derive(Debug, Clone, Serialize, Deserialize)]
78pub struct EquivalentBranchData {
79 /// CIM mRID.
80 pub mrid: String,
81 /// Parent `EquivalentNetwork` mRID.
82 pub network_mrid: Option<String>,
83 /// Positive-sequence resistance (Ohm).
84 pub r_ohm: f64,
85 /// Positive-sequence reactance (Ohm).
86 pub x_ohm: f64,
87 /// Zero-sequence resistance (Ohm), if available.
88 pub r0_ohm: Option<f64>,
89 /// Zero-sequence reactance (Ohm), if available.
90 pub x0_ohm: Option<f64>,
91 /// Negative-sequence resistance (Ohm), if available.
92 pub r2_ohm: Option<f64>,
93 /// Negative-sequence reactance (Ohm), if available.
94 pub x2_ohm: Option<f64>,
95 /// Resolved from-bus number.
96 pub from_bus: Option<u32>,
97 /// Resolved to-bus number.
98 pub to_bus: Option<u32>,
99}
100
101/// External network shunt equivalent — a constant-admittance shunt
102/// representing the reduced external network contribution at a boundary bus.
103#[derive(Debug, Clone, Serialize, Deserialize)]
104pub struct EquivalentShuntData {
105 /// CIM mRID.
106 pub mrid: String,
107 /// Parent `EquivalentNetwork` mRID.
108 pub network_mrid: Option<String>,
109 /// Conductance (Siemens).
110 pub g_s: f64,
111 /// Susceptance (Siemens).
112 pub b_s: f64,
113 /// Resolved bus number.
114 pub bus: Option<u32>,
115}
116
117/// Container for all boundary and external equivalent data from the
118/// ENTSO-E EQBD/BD profile.
119///
120/// Stored on `Network::boundary_data`.
121/// Empty by default for non-CGMES cases.
122#[derive(Debug, Clone, Default, Serialize, Deserialize)]
123pub struct BoundaryData {
124 /// TSO-TSO boundary points.
125 pub boundary_points: Vec<BoundaryPoint>,
126 /// Model authority sets (TSO ownership).
127 pub model_authority_sets: Vec<ModelAuthoritySet>,
128 /// External equivalent networks.
129 pub equivalent_networks: Vec<EquivalentNetworkData>,
130 /// External equivalent branches.
131 pub equivalent_branches: Vec<EquivalentBranchData>,
132 /// External equivalent shunts.
133 pub equivalent_shunts: Vec<EquivalentShuntData>,
134}
135
136impl BoundaryData {
137 /// Returns `true` if no boundary data has been populated.
138 pub fn is_empty(&self) -> bool {
139 self.boundary_points.is_empty()
140 && self.model_authority_sets.is_empty()
141 && self.equivalent_networks.is_empty()
142 && self.equivalent_branches.is_empty()
143 && self.equivalent_shunts.is_empty()
144 }
145}