qsim_elements/
bus.rs

1//! Bus element — network nodes
2
3use qsim_core::{GridElement, StateStore};
4use serde::{Deserialize, Serialize};
5
6/// Bus type classification
7#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
8pub enum BusType {
9    /// Slack bus — reference for voltage angle, absorbs power mismatch
10    Slack,
11    /// PV bus — voltage magnitude and active power specified (generator bus)
12    PV,
13    /// PQ bus — active and reactive power specified (load bus)
14    PQ,
15}
16
17/// A bus (node) in the power network
18#[derive(Debug, Clone, Serialize, Deserialize)]
19pub struct Bus {
20    /// Bus type
21    pub bus_type: BusType,
22    /// Voltage magnitude (per-unit)
23    pub voltage_magnitude: f64,
24    /// Voltage angle (radians)
25    pub voltage_angle: f64,
26    /// Active power injection (MW, positive = generation)
27    pub active_power: f64,
28    /// Reactive power injection (MVAr, positive = generation)
29    pub reactive_power: f64,
30    /// Base voltage (kV)
31    pub base_voltage_kv: f64,
32}
33
34impl Bus {
35    /// Create a slack bus
36    pub fn slack(voltage_magnitude: f64) -> Self {
37        Self {
38            bus_type: BusType::Slack,
39            voltage_magnitude,
40            voltage_angle: 0.0,
41            active_power: 0.0,
42            reactive_power: 0.0,
43            base_voltage_kv: 1.0,
44        }
45    }
46
47    /// Create a PV bus (generator)
48    pub fn pv(voltage_magnitude: f64, active_power: f64) -> Self {
49        Self {
50            bus_type: BusType::PV,
51            voltage_magnitude,
52            voltage_angle: 0.0,
53            active_power,
54            reactive_power: 0.0,
55            base_voltage_kv: 1.0,
56        }
57    }
58
59    /// Create a PQ bus (load)
60    pub fn pq(active_power: f64, reactive_power: f64) -> Self {
61        Self {
62            bus_type: BusType::PQ,
63            voltage_magnitude: 1.0,
64            voltage_angle: 0.0,
65            active_power,
66            reactive_power,
67            base_voltage_kv: 1.0,
68        }
69    }
70}
71
72impl GridElement for Bus {
73    fn element_type(&self) -> &'static str {
74        match self.bus_type {
75            BusType::Slack => "Bus::Slack",
76            BusType::PV => "Bus::PV",
77            BusType::PQ => "Bus::PQ",
78        }
79    }
80
81    fn apply(&self, _state: &mut StateStore) {
82        // Bus state is applied during network construction
83    }
84}