qsim_elements/
generator.rs

1//! Generator element — power generation units
2
3use qsim_core::{GridElement, StateStore};
4use serde::{Deserialize, Serialize};
5
6/// A generator connected to a bus
7#[derive(Debug, Clone, Serialize, Deserialize)]
8pub struct Generator {
9    /// Connected bus index
10    pub bus: usize,
11    /// Active power output (MW)
12    pub active_power: f64,
13    /// Reactive power output (MVAr)
14    pub reactive_power: f64,
15    /// Voltage setpoint (per-unit)
16    pub voltage_setpoint: f64,
17    /// Minimum active power (MW)
18    pub p_min: f64,
19    /// Maximum active power (MW)
20    pub p_max: f64,
21    /// Minimum reactive power (MVAr)
22    pub q_min: f64,
23    /// Maximum reactive power (MVAr)
24    pub q_max: f64,
25    /// Generator status (true = in service)
26    pub in_service: bool,
27}
28
29impl Generator {
30    /// Create a new generator
31    pub fn new(bus: usize, active_power: f64, voltage_setpoint: f64) -> Self {
32        Self {
33            bus,
34            active_power,
35            reactive_power: 0.0,
36            voltage_setpoint,
37            p_min: 0.0,
38            p_max: active_power * 2.0,
39            q_min: -active_power,
40            q_max: active_power,
41            in_service: true,
42        }
43    }
44
45    /// Create a generator with limits
46    pub fn with_limits(
47        bus: usize,
48        active_power: f64,
49        voltage_setpoint: f64,
50        p_min: f64,
51        p_max: f64,
52        q_min: f64,
53        q_max: f64,
54    ) -> Self {
55        Self {
56            bus,
57            active_power,
58            reactive_power: 0.0,
59            voltage_setpoint,
60            p_min,
61            p_max,
62            q_min,
63            q_max,
64            in_service: true,
65        }
66    }
67}
68
69impl GridElement for Generator {
70    fn element_type(&self) -> &'static str {
71        "Generator"
72    }
73
74    fn apply(&self, state: &mut StateStore) {
75        if self.in_service && self.bus < state.bus_count() {
76            state.active_power[self.bus] += self.active_power;
77            state.reactive_power[self.bus] += self.reactive_power;
78        }
79    }
80}