surge_network/network/induction_machine.rs
1// SPDX-License-Identifier: LicenseRef-PolyForm-Noncommercial-1.0.0
2//! PSS/E Induction Machine data (Issue #28).
3
4use serde::{Deserialize, Serialize};
5
6/// PSS/E induction machine (motor load) steady-state equivalent-circuit record.
7///
8/// Parsed from "INDUCTION MACHINE DATA" in PSS/E RAW v35+ files.
9/// Uses the standard T-circuit model: Ra+jXa (stator), jXm (magnetizing),
10/// R1+jX1 (rotor cage 1), R2+jX2 (rotor cage 2, double-cage only).
11///
12/// Source: PSS/E v35 Program Operation Manual §5.12.
13#[derive(Debug, Clone, Serialize, Deserialize)]
14pub struct InductionMachine {
15 /// Terminal bus number.
16 pub bus: u32,
17 /// Machine identifier (up to 2 characters).
18 pub id: String,
19 /// In-service status.
20 pub in_service: bool,
21 /// Machine base MVA (0.0 → use system base).
22 pub mbase: f64,
23 /// Rated terminal kV.
24 pub rate_kv: f64,
25 /// Active-power set-point (MW when pcode=1, power factor when pcode=2).
26 pub pset: f64,
27 /// Inertia constant H (MW·s/MVA).
28 pub h: f64,
29 /// Speed-torque coefficient A (T = A + B*w + D*w^2 + E*w^3).
30 pub a: f64,
31 /// Speed-torque coefficient B.
32 pub b: f64,
33 /// Speed-torque coefficient D.
34 pub d: f64,
35 /// Speed-torque coefficient E.
36 pub e: f64,
37 /// Locked-rotor torque multiplier F.
38 pub f_coeff: f64,
39 /// Stator resistance Ra (pu, machine base).
40 pub ra: f64,
41 /// Stator leakage reactance Xa (pu, machine base).
42 pub xa: f64,
43 /// Magnetizing reactance Xm (pu, machine base).
44 pub xm: f64,
45 /// Rotor resistance — first cage R1 (pu, machine base).
46 pub r1: f64,
47 /// Rotor reactance — first cage X1 (pu, machine base).
48 pub x1: f64,
49 /// Rotor resistance — second cage R2 (pu; 0 = single-cage).
50 pub r2: f64,
51 /// Rotor reactance — second cage X2 (pu; 0 = single-cage).
52 pub x2: f64,
53 /// Leakage reactance X3 (pu, machine base).
54 pub x3: f64,
55 /// PSS/E area number.
56 pub area: u32,
57 /// PSS/E zone number.
58 pub zone: u32,
59 /// PSS/E owner number.
60 pub owner: u32,
61 /// References Load.id on the same bus. None = bus-level (legacy).
62 #[serde(default, skip_serializing_if = "Option::is_none")]
63 pub load_id: Option<String>,
64}
65
66impl InductionMachine {
67 /// Effective machine base MVA — falls back to `system_base` when mbase == 0.
68 pub fn effective_mbase(&self, system_base: f64) -> f64 {
69 if self.mbase.abs() < 1e-10 {
70 system_base
71 } else {
72 self.mbase
73 }
74 }
75}