Skip to main content

cimstructs/
LoadMotor.rs

1/// Aggregate induction motor load. This model is used to represent a fraction of an ordinary load as 'induction motor load'. It allows a load that is treated as an ordinary constant power in power flow analysis to be represented by an induction motor in dynamic simulation. This model is intended for representation of aggregations of many motors dispersed through a load represented at a high voltage bus but where there is no information on the characteristics of individual motors. Either a 'one-cage' or 'two-cage' model of the induction machine can be modelled. Magnetic saturation is not modelled. This model treats a fraction of the constant power part of a load as a motor. During initialisation, the initial power drawn by the motor is set equal to Pfrac times the constant P part of the static load. The remainder of the load is left as a static load. The reactive power demand of the motor is calculated during initialisation as a function of voltage at the load bus. This reactive power demand can be less than or greater than the constant Q component of the load. If the motor's reactive demand is greater than the constant Q component of the load, the model inserts a shunt capacitor at the terminal of the motor to bring its reactive demand down to equal the constant Q reactive load. If an induction motor load model and a static load model are both present for a load, the motor Pfrac is assumed to be subtracted from the power flow constant P load before the static load model is applied. The remainder of the load, if any, is then represented by the static load model.
2#[derive(Debug, Default, Clone, serde::Serialize, serde::Deserialize)]
3pub struct LoadMotor {
4    #[serde(flatten)]
5    pub base: super::IdentifiedObject,
6    /// Aggregate load to which this aggregate motor (dynamic) load belongs.
7    #[serde(skip_serializing_if = "Option::is_none")]
8    pub load_aggregate: Option<super::base::MridRef>,
9    /// Damping factor (D). Unit = delta P/delta speed. Typical value = 2.
10    #[serde(skip_serializing_if = "Option::is_none")]
11    pub d: Option<f64>,
12    /// Inertia constant (H) (>= 0). Typical value = 0,4.
13    #[serde(skip_serializing_if = "Option::is_none")]
14    pub h: Option<f64>,
15    /// Loading factor (Lfac). The ratio of initial P to motor MVA base. Typical value = 0,8.
16    #[serde(skip_serializing_if = "Option::is_none")]
17    pub lfac: Option<f64>,
18    /// Transient reactance (Lp). Typical value = 0,15.
19    #[serde(skip_serializing_if = "Option::is_none")]
20    pub lp: Option<f64>,
21    /// Subtransient reactance (Lpp). Typical value = 0,15.
22    #[serde(skip_serializing_if = "Option::is_none")]
23    pub lpp: Option<f64>,
24    /// Synchronous reactance (Ls). Typical value = 3,2.
25    #[serde(skip_serializing_if = "Option::is_none")]
26    pub ls: Option<f64>,
27    /// Fraction of constant-power load to be represented by this motor model (Pfrac) (>= 0,0 and <= 1,0). Typical value = 0,3.
28    #[serde(skip_serializing_if = "Option::is_none")]
29    pub pfrac: Option<f64>,
30    /// Stator resistance (Ra). Typical value = 0.
31    #[serde(skip_serializing_if = "Option::is_none")]
32    pub ra: Option<f64>,
33    /// Circuit breaker operating time (Tbkr) (>= 0). Typical value = 0,08.
34    #[serde(skip_serializing_if = "Option::is_none")]
35    pub tbkr: Option<f64>,
36    /// Transient rotor time constant (Tpo) (>= 0). Typical value = 1.
37    #[serde(skip_serializing_if = "Option::is_none")]
38    pub tpo: Option<f64>,
39    /// Subtransient rotor time constant (Tppo) (>= 0). Typical value = 0,02.
40    #[serde(skip_serializing_if = "Option::is_none")]
41    pub tppo: Option<f64>,
42    /// Voltage trip pickup time (Tv) (>= 0). Typical value = 0,1.
43    #[serde(skip_serializing_if = "Option::is_none")]
44    pub tv: Option<f64>,
45    /// Voltage threshold for tripping (Vt). Typical value = 0,7.
46    #[serde(skip_serializing_if = "Option::is_none")]
47    pub vt: Option<f64>,
48}
49impl crate::base::CimElement for LoadMotor {
50    fn mrid(&self) -> &str { &self.base.id }
51    fn type_name(&self) -> &'static str { "LoadMotor" }
52    fn as_any(&self) -> &dyn std::any::Any { self }
53    fn to_json_value(&self) -> serde_json::Value {
54        serde_json::to_value(self).unwrap_or(serde_json::Value::Null)
55    }
56    fn to_block(&self) -> crate::base::RdfBlock {
57        let mut block = self.base.to_block();
58        block.type_name = "LoadMotor".to_string();
59        if let Some(ref v) = self.load_aggregate {
60            block.fields.insert("LoadMotor.LoadAggregate".into(), crate::base::FieldValue::Resource(v.mrid.clone()));
61        }
62        if let Some(v) = self.d {
63            block.fields.insert("LoadMotor.d".into(), crate::base::FieldValue::Text(v.to_string()));
64        }
65        if let Some(v) = self.h {
66            block.fields.insert("LoadMotor.h".into(), crate::base::FieldValue::Text(v.to_string()));
67        }
68        if let Some(v) = self.lfac {
69            block.fields.insert("LoadMotor.lfac".into(), crate::base::FieldValue::Text(v.to_string()));
70        }
71        if let Some(v) = self.lp {
72            block.fields.insert("LoadMotor.lp".into(), crate::base::FieldValue::Text(v.to_string()));
73        }
74        if let Some(v) = self.lpp {
75            block.fields.insert("LoadMotor.lpp".into(), crate::base::FieldValue::Text(v.to_string()));
76        }
77        if let Some(v) = self.ls {
78            block.fields.insert("LoadMotor.ls".into(), crate::base::FieldValue::Text(v.to_string()));
79        }
80        if let Some(v) = self.pfrac {
81            block.fields.insert("LoadMotor.pfrac".into(), crate::base::FieldValue::Text(v.to_string()));
82        }
83        if let Some(v) = self.ra {
84            block.fields.insert("LoadMotor.ra".into(), crate::base::FieldValue::Text(v.to_string()));
85        }
86        if let Some(v) = self.tbkr {
87            block.fields.insert("LoadMotor.tbkr".into(), crate::base::FieldValue::Text(v.to_string()));
88        }
89        if let Some(v) = self.tpo {
90            block.fields.insert("LoadMotor.tpo".into(), crate::base::FieldValue::Text(v.to_string()));
91        }
92        if let Some(v) = self.tppo {
93            block.fields.insert("LoadMotor.tppo".into(), crate::base::FieldValue::Text(v.to_string()));
94        }
95        if let Some(v) = self.tv {
96            block.fields.insert("LoadMotor.tv".into(), crate::base::FieldValue::Text(v.to_string()));
97        }
98        if let Some(v) = self.vt {
99            block.fields.insert("LoadMotor.vt".into(), crate::base::FieldValue::Text(v.to_string()));
100        }
101        block
102    }
103}
104
105impl LoadMotor {
106    pub fn from_block(b: &crate::base::RdfBlock) -> Self {
107        let mut obj = Self::default();
108        obj.base.id.clone_from(&b.mrid);
109        for (key, val) in &b.fields {
110            match key.as_str() {
111                "LoadMotor.LoadAggregate" => {
112                    if let crate::base::FieldValue::Resource(sv) = val {
113                        obj.load_aggregate = Some(crate::base::MridRef { mrid: sv.clone() });
114                    }
115                }
116                "LoadMotor.d" => {
117                    match val {
118                        crate::base::FieldValue::Text(sv) => { if let Ok(v) = sv.trim().parse() { obj.d = Some(v); } }
119                        crate::base::FieldValue::TextList(svs) => {
120                            if let Some(sv) = svs.last() { if let Ok(v) = sv.trim().parse() { obj.d = Some(v); } }
121                        }
122                        _ => {}
123                    }
124                }
125                "LoadMotor.h" => {
126                    match val {
127                        crate::base::FieldValue::Text(sv) => { if let Ok(v) = sv.trim().parse() { obj.h = Some(v); } }
128                        crate::base::FieldValue::TextList(svs) => {
129                            if let Some(sv) = svs.last() { if let Ok(v) = sv.trim().parse() { obj.h = Some(v); } }
130                        }
131                        _ => {}
132                    }
133                }
134                "LoadMotor.lfac" => {
135                    match val {
136                        crate::base::FieldValue::Text(sv) => { if let Ok(v) = sv.trim().parse() { obj.lfac = Some(v); } }
137                        crate::base::FieldValue::TextList(svs) => {
138                            if let Some(sv) = svs.last() { if let Ok(v) = sv.trim().parse() { obj.lfac = Some(v); } }
139                        }
140                        _ => {}
141                    }
142                }
143                "LoadMotor.lp" => {
144                    match val {
145                        crate::base::FieldValue::Text(sv) => { if let Ok(v) = sv.trim().parse() { obj.lp = Some(v); } }
146                        crate::base::FieldValue::TextList(svs) => {
147                            if let Some(sv) = svs.last() { if let Ok(v) = sv.trim().parse() { obj.lp = Some(v); } }
148                        }
149                        _ => {}
150                    }
151                }
152                "LoadMotor.lpp" => {
153                    match val {
154                        crate::base::FieldValue::Text(sv) => { if let Ok(v) = sv.trim().parse() { obj.lpp = Some(v); } }
155                        crate::base::FieldValue::TextList(svs) => {
156                            if let Some(sv) = svs.last() { if let Ok(v) = sv.trim().parse() { obj.lpp = Some(v); } }
157                        }
158                        _ => {}
159                    }
160                }
161                "LoadMotor.ls" => {
162                    match val {
163                        crate::base::FieldValue::Text(sv) => { if let Ok(v) = sv.trim().parse() { obj.ls = Some(v); } }
164                        crate::base::FieldValue::TextList(svs) => {
165                            if let Some(sv) = svs.last() { if let Ok(v) = sv.trim().parse() { obj.ls = Some(v); } }
166                        }
167                        _ => {}
168                    }
169                }
170                "LoadMotor.pfrac" => {
171                    match val {
172                        crate::base::FieldValue::Text(sv) => { if let Ok(v) = sv.trim().parse() { obj.pfrac = Some(v); } }
173                        crate::base::FieldValue::TextList(svs) => {
174                            if let Some(sv) = svs.last() { if let Ok(v) = sv.trim().parse() { obj.pfrac = Some(v); } }
175                        }
176                        _ => {}
177                    }
178                }
179                "LoadMotor.ra" => {
180                    match val {
181                        crate::base::FieldValue::Text(sv) => { if let Ok(v) = sv.trim().parse() { obj.ra = Some(v); } }
182                        crate::base::FieldValue::TextList(svs) => {
183                            if let Some(sv) = svs.last() { if let Ok(v) = sv.trim().parse() { obj.ra = Some(v); } }
184                        }
185                        _ => {}
186                    }
187                }
188                "LoadMotor.tbkr" => {
189                    match val {
190                        crate::base::FieldValue::Text(sv) => { if let Ok(v) = sv.trim().parse() { obj.tbkr = Some(v); } }
191                        crate::base::FieldValue::TextList(svs) => {
192                            if let Some(sv) = svs.last() { if let Ok(v) = sv.trim().parse() { obj.tbkr = Some(v); } }
193                        }
194                        _ => {}
195                    }
196                }
197                "LoadMotor.tpo" => {
198                    match val {
199                        crate::base::FieldValue::Text(sv) => { if let Ok(v) = sv.trim().parse() { obj.tpo = Some(v); } }
200                        crate::base::FieldValue::TextList(svs) => {
201                            if let Some(sv) = svs.last() { if let Ok(v) = sv.trim().parse() { obj.tpo = Some(v); } }
202                        }
203                        _ => {}
204                    }
205                }
206                "LoadMotor.tppo" => {
207                    match val {
208                        crate::base::FieldValue::Text(sv) => { if let Ok(v) = sv.trim().parse() { obj.tppo = Some(v); } }
209                        crate::base::FieldValue::TextList(svs) => {
210                            if let Some(sv) = svs.last() { if let Ok(v) = sv.trim().parse() { obj.tppo = Some(v); } }
211                        }
212                        _ => {}
213                    }
214                }
215                "LoadMotor.tv" => {
216                    match val {
217                        crate::base::FieldValue::Text(sv) => { if let Ok(v) = sv.trim().parse() { obj.tv = Some(v); } }
218                        crate::base::FieldValue::TextList(svs) => {
219                            if let Some(sv) = svs.last() { if let Ok(v) = sv.trim().parse() { obj.tv = Some(v); } }
220                        }
221                        _ => {}
222                    }
223                }
224                "LoadMotor.vt" => {
225                    match val {
226                        crate::base::FieldValue::Text(sv) => { if let Ok(v) = sv.trim().parse() { obj.vt = Some(v); } }
227                        crate::base::FieldValue::TextList(svs) => {
228                            if let Some(sv) = svs.last() { if let Ok(v) = sv.trim().parse() { obj.vt = Some(v); } }
229                        }
230                        _ => {}
231                    }
232                }
233                "IdentifiedObject.description" => {
234                    match val {
235                        crate::base::FieldValue::Text(sv) => { obj.base.description = sv.clone(); }
236                        crate::base::FieldValue::TextList(svs) => {
237                            if let Some(sv) = svs.last() { obj.base.description = sv.clone(); }
238                        }
239                        _ => {}
240                    }
241                }
242                "IdentifiedObject.energyIdentCodeEic" => {
243                    match val {
244                        crate::base::FieldValue::Text(sv) => { obj.base.energy_ident_code_eic = sv.clone(); }
245                        crate::base::FieldValue::TextList(svs) => {
246                            if let Some(sv) = svs.last() { obj.base.energy_ident_code_eic = sv.clone(); }
247                        }
248                        _ => {}
249                    }
250                }
251                "IdentifiedObject.mRID" => {
252                    match val {
253                        crate::base::FieldValue::Text(sv) => { obj.base.m_rid = sv.clone(); }
254                        crate::base::FieldValue::TextList(svs) => {
255                            if let Some(sv) = svs.last() { obj.base.m_rid = sv.clone(); }
256                        }
257                        _ => {}
258                    }
259                }
260                "IdentifiedObject.name" => {
261                    match val {
262                        crate::base::FieldValue::Text(sv) => { obj.base.name = sv.clone(); }
263                        crate::base::FieldValue::TextList(svs) => {
264                            if let Some(sv) = svs.last() { obj.base.name = sv.clone(); }
265                        }
266                        _ => {}
267                    }
268                }
269                "IdentifiedObject.shortName" => {
270                    match val {
271                        crate::base::FieldValue::Text(sv) => { obj.base.short_name = sv.clone(); }
272                        crate::base::FieldValue::TextList(svs) => {
273                            if let Some(sv) = svs.last() { obj.base.short_name = sv.clone(); }
274                        }
275                        _ => {}
276                    }
277                }
278                _ => {}
279            }
280        }
281        obj
282    }
283}