gridoxide_core/shortcircuit/network.rs
1//! The network a short-circuit calculation solves, independent of the
2//! document it came from. gridoxide's `pgm::shortcircuit`
3//! builds one from a PGM document.
4
5use std::collections::HashMap;
6
7use num_complex::Complex;
8
9use crate::network::ShuntAdm3Ph;
10use crate::types::{Line3Ph, Transformer3PhSeq};
11
12/// One active `source`, reduced to the Norton equivalent a short-circuit
13/// calculation needs: an internal admittance at its node, behind a fixed EMF.
14#[derive(Clone, Copy, Debug)]
15pub struct ScSource {
16 /// The document's own `source` id.
17 pub id: u64,
18 /// Physical node index the source sits on.
19 pub node: usize,
20 /// Positive- (= negative-) sequence internal admittance, per unit.
21 pub y1: Complex<f64>,
22 /// Zero-sequence internal admittance, per unit.
23 pub y0: Complex<f64>,
24 /// `u_ref_angle`, the only part of the source's voltage specification that
25 /// survives into a short-circuit calculation — see
26 /// gridoxide's `pgm::shortcircuit::pgm_to_3ph_sc_network`.
27 pub u_ref_angle: f64,
28 /// Rated line-to-line voltage of the node this source sits on, which is
29 /// what selects its IEC 60909 voltage-scaling factor `c`.
30 pub u_rated: f64,
31}
32
33/// The network a short-circuit calculation solves: the passive circuit plus
34/// its sources as Norton equivalents.
35pub struct ScNetwork3Ph {
36 /// Physical node count. Bus `k`'s phases are rows `3k`, `3k+1`, `3k+2`.
37 pub n_nodes: usize,
38 pub lines: Vec<Line3Ph>,
39 pub transformers: Vec<Transformer3PhSeq>,
40 pub shunts: Vec<ShuntAdm3Ph>,
41 pub sources: Vec<ScSource>,
42 /// The PGM id behind each branch, in the flat order the report uses: the
43 /// lines that yield a branch, then the transformers, then the links. A
44 /// fully open line or link yields no branch and has no entry, which is why
45 /// this cannot be derived from document position.
46 pub branch_ids: Vec<u64>,
47 /// Whether each branch's `[from, to]` terminal is closed, parallel to
48 /// `branch_ids`. A line with one live terminal has already collapsed to a
49 /// self-loop on that terminal's node, which carries its current at `from`
50 /// either way; this says which PGM terminal that current belongs to.
51 pub branch_closed: Vec<[bool; 2]>,
52 /// The PGM id of each entry of `shunts`.
53 pub shunt_ids: Vec<u64>,
54 /// Node id → physical node index.
55 pub node_idx: HashMap<u64, usize>,
56 /// Per physical node, its rated line-to-line voltage — needed to convert
57 /// per-unit result voltages back to volts.
58 pub u_rated: Vec<f64>,
59 /// The three-phase base power the per-unit quantities are referred to.
60 /// Carried alongside so results can be converted back to volts and amperes
61 /// without the caller having to remember what it passed in.
62 pub s_base_va: f64,
63}