Skip to main content

cimstructs/
LoadResponseCharacteristic.rs

1/// Models the characteristic response of the load demand due to changes in system conditions such as voltage and frequency. It is not related to demand response. If LoadResponseCharacteristic.exponentModel is True, the exponential voltage or frequency dependent models are specified and used as to calculate active and reactive power components of the load model. The equations to calculate active and reactive power components of the load model are internal to the power flow calculation, hence they use different quantities depending on the use case of the data exchange. The equations for exponential voltage dependent load model injected power are: pInjection= Pnominal* (Voltage/cim:BaseVoltage.nominalVoltage) ** cim:LoadResponseCharacteristic.pVoltageExponent qInjection= Qnominal* (Voltage/cim:BaseVoltage.nominalVoltage) ** cim:LoadResponseCharacteristic.qVoltageExponent Where: 1) * means 'multiply' and ** is 'raised to power of'; 2) Pnominal and Qnominal represent the active power and reactive power at nominal voltage as any load described by the voltage exponential model shall be given at nominal voltage. This means that EnergyConsumer.p and EnergyConsumer.q are at nominal voltage. 3) After power flow is solved: -pInjection and qInjection correspond to SvPowerflow.p and SvPowerflow.q respectively. - Voltage corresponds to SvVoltage.v at the TopologicalNode where the load is connected.
2#[derive(Debug, Default, Clone, serde::Serialize, serde::Deserialize)]
3pub struct LoadResponseCharacteristic {
4    #[serde(flatten)]
5    pub base: super::IdentifiedObject,
6    /// Indicates the exponential voltage dependency model is to be used. If false, the coefficient model is to be used. The exponential voltage dependency model consist of the attributes: - pVoltageExponent - qVoltageExponent - pFrequencyExponent - qFrequencyExponent. The coefficient model consist of the attributes: - pConstantImpedance - pConstantCurrent - pConstantPower - qConstantImpedance - qConstantCurrent - qConstantPower. The sum of pConstantImpedance, pConstantCurrent and pConstantPower shall equal 1. The sum of qConstantImpedance, qConstantCurrent and qConstantPower shall equal 1.
7    #[serde(skip_serializing_if = "Option::is_none")]
8    pub exponent_model: Option<bool>,
9    /// Portion of active power load modelled as constant current.
10    #[serde(skip_serializing_if = "Option::is_none")]
11    pub p_constant_current: Option<f64>,
12    /// Portion of active power load modelled as constant impedance.
13    #[serde(skip_serializing_if = "Option::is_none")]
14    pub p_constant_impedance: Option<f64>,
15    /// Portion of active power load modelled as constant power.
16    #[serde(skip_serializing_if = "Option::is_none")]
17    pub p_constant_power: Option<f64>,
18    /// Exponent of per unit frequency effecting active power.
19    #[serde(skip_serializing_if = "Option::is_none")]
20    pub p_frequency_exponent: Option<f64>,
21    /// Exponent of per unit voltage effecting real power.
22    #[serde(skip_serializing_if = "Option::is_none")]
23    pub p_voltage_exponent: Option<f64>,
24    /// Portion of reactive power load modelled as constant current.
25    #[serde(skip_serializing_if = "Option::is_none")]
26    pub q_constant_current: Option<f64>,
27    /// Portion of reactive power load modelled as constant impedance.
28    #[serde(skip_serializing_if = "Option::is_none")]
29    pub q_constant_impedance: Option<f64>,
30    /// Portion of reactive power load modelled as constant power.
31    #[serde(skip_serializing_if = "Option::is_none")]
32    pub q_constant_power: Option<f64>,
33    /// Exponent of per unit frequency effecting reactive power.
34    #[serde(skip_serializing_if = "Option::is_none")]
35    pub q_frequency_exponent: Option<f64>,
36    /// Exponent of per unit voltage effecting reactive power.
37    #[serde(skip_serializing_if = "Option::is_none")]
38    pub q_voltage_exponent: Option<f64>,
39}
40impl crate::base::CimElement for LoadResponseCharacteristic {
41    fn mrid(&self) -> &str { &self.base.id }
42    fn type_name(&self) -> &'static str { "LoadResponseCharacteristic" }
43    fn as_any(&self) -> &dyn std::any::Any { self }
44    fn to_json_value(&self) -> serde_json::Value {
45        serde_json::to_value(self).unwrap_or(serde_json::Value::Null)
46    }
47    fn to_block(&self) -> crate::base::RdfBlock {
48        let mut block = self.base.to_block();
49        block.type_name = "LoadResponseCharacteristic".to_string();
50        if let Some(v) = self.exponent_model {
51            block.fields.insert("LoadResponseCharacteristic.exponentModel".into(), crate::base::FieldValue::Text(v.to_string()));
52        }
53        if let Some(v) = self.p_constant_current {
54            block.fields.insert("LoadResponseCharacteristic.pConstantCurrent".into(), crate::base::FieldValue::Text(v.to_string()));
55        }
56        if let Some(v) = self.p_constant_impedance {
57            block.fields.insert("LoadResponseCharacteristic.pConstantImpedance".into(), crate::base::FieldValue::Text(v.to_string()));
58        }
59        if let Some(v) = self.p_constant_power {
60            block.fields.insert("LoadResponseCharacteristic.pConstantPower".into(), crate::base::FieldValue::Text(v.to_string()));
61        }
62        if let Some(v) = self.p_frequency_exponent {
63            block.fields.insert("LoadResponseCharacteristic.pFrequencyExponent".into(), crate::base::FieldValue::Text(v.to_string()));
64        }
65        if let Some(v) = self.p_voltage_exponent {
66            block.fields.insert("LoadResponseCharacteristic.pVoltageExponent".into(), crate::base::FieldValue::Text(v.to_string()));
67        }
68        if let Some(v) = self.q_constant_current {
69            block.fields.insert("LoadResponseCharacteristic.qConstantCurrent".into(), crate::base::FieldValue::Text(v.to_string()));
70        }
71        if let Some(v) = self.q_constant_impedance {
72            block.fields.insert("LoadResponseCharacteristic.qConstantImpedance".into(), crate::base::FieldValue::Text(v.to_string()));
73        }
74        if let Some(v) = self.q_constant_power {
75            block.fields.insert("LoadResponseCharacteristic.qConstantPower".into(), crate::base::FieldValue::Text(v.to_string()));
76        }
77        if let Some(v) = self.q_frequency_exponent {
78            block.fields.insert("LoadResponseCharacteristic.qFrequencyExponent".into(), crate::base::FieldValue::Text(v.to_string()));
79        }
80        if let Some(v) = self.q_voltage_exponent {
81            block.fields.insert("LoadResponseCharacteristic.qVoltageExponent".into(), crate::base::FieldValue::Text(v.to_string()));
82        }
83        block
84    }
85}
86
87impl LoadResponseCharacteristic {
88    pub fn from_block(b: &crate::base::RdfBlock) -> Self {
89        let mut obj = Self::default();
90        obj.base.id.clone_from(&b.mrid);
91        for (key, val) in &b.fields {
92            match key.as_str() {
93                "LoadResponseCharacteristic.exponentModel" => {
94                    match val {
95                        crate::base::FieldValue::Text(sv) => { obj.exponent_model = Some(sv.trim() == "true"); }
96                        crate::base::FieldValue::TextList(svs) => {
97                            if let Some(sv) = svs.last() { obj.exponent_model = Some(sv.trim() == "true"); }
98                        }
99                        _ => {}
100                    }
101                }
102                "LoadResponseCharacteristic.pConstantCurrent" => {
103                    match val {
104                        crate::base::FieldValue::Text(sv) => { if let Ok(v) = sv.trim().parse() { obj.p_constant_current = Some(v); } }
105                        crate::base::FieldValue::TextList(svs) => {
106                            if let Some(sv) = svs.last() { if let Ok(v) = sv.trim().parse() { obj.p_constant_current = Some(v); } }
107                        }
108                        _ => {}
109                    }
110                }
111                "LoadResponseCharacteristic.pConstantImpedance" => {
112                    match val {
113                        crate::base::FieldValue::Text(sv) => { if let Ok(v) = sv.trim().parse() { obj.p_constant_impedance = Some(v); } }
114                        crate::base::FieldValue::TextList(svs) => {
115                            if let Some(sv) = svs.last() { if let Ok(v) = sv.trim().parse() { obj.p_constant_impedance = Some(v); } }
116                        }
117                        _ => {}
118                    }
119                }
120                "LoadResponseCharacteristic.pConstantPower" => {
121                    match val {
122                        crate::base::FieldValue::Text(sv) => { if let Ok(v) = sv.trim().parse() { obj.p_constant_power = Some(v); } }
123                        crate::base::FieldValue::TextList(svs) => {
124                            if let Some(sv) = svs.last() { if let Ok(v) = sv.trim().parse() { obj.p_constant_power = Some(v); } }
125                        }
126                        _ => {}
127                    }
128                }
129                "LoadResponseCharacteristic.pFrequencyExponent" => {
130                    match val {
131                        crate::base::FieldValue::Text(sv) => { if let Ok(v) = sv.trim().parse() { obj.p_frequency_exponent = Some(v); } }
132                        crate::base::FieldValue::TextList(svs) => {
133                            if let Some(sv) = svs.last() { if let Ok(v) = sv.trim().parse() { obj.p_frequency_exponent = Some(v); } }
134                        }
135                        _ => {}
136                    }
137                }
138                "LoadResponseCharacteristic.pVoltageExponent" => {
139                    match val {
140                        crate::base::FieldValue::Text(sv) => { if let Ok(v) = sv.trim().parse() { obj.p_voltage_exponent = Some(v); } }
141                        crate::base::FieldValue::TextList(svs) => {
142                            if let Some(sv) = svs.last() { if let Ok(v) = sv.trim().parse() { obj.p_voltage_exponent = Some(v); } }
143                        }
144                        _ => {}
145                    }
146                }
147                "LoadResponseCharacteristic.qConstantCurrent" => {
148                    match val {
149                        crate::base::FieldValue::Text(sv) => { if let Ok(v) = sv.trim().parse() { obj.q_constant_current = Some(v); } }
150                        crate::base::FieldValue::TextList(svs) => {
151                            if let Some(sv) = svs.last() { if let Ok(v) = sv.trim().parse() { obj.q_constant_current = Some(v); } }
152                        }
153                        _ => {}
154                    }
155                }
156                "LoadResponseCharacteristic.qConstantImpedance" => {
157                    match val {
158                        crate::base::FieldValue::Text(sv) => { if let Ok(v) = sv.trim().parse() { obj.q_constant_impedance = Some(v); } }
159                        crate::base::FieldValue::TextList(svs) => {
160                            if let Some(sv) = svs.last() { if let Ok(v) = sv.trim().parse() { obj.q_constant_impedance = Some(v); } }
161                        }
162                        _ => {}
163                    }
164                }
165                "LoadResponseCharacteristic.qConstantPower" => {
166                    match val {
167                        crate::base::FieldValue::Text(sv) => { if let Ok(v) = sv.trim().parse() { obj.q_constant_power = Some(v); } }
168                        crate::base::FieldValue::TextList(svs) => {
169                            if let Some(sv) = svs.last() { if let Ok(v) = sv.trim().parse() { obj.q_constant_power = Some(v); } }
170                        }
171                        _ => {}
172                    }
173                }
174                "LoadResponseCharacteristic.qFrequencyExponent" => {
175                    match val {
176                        crate::base::FieldValue::Text(sv) => { if let Ok(v) = sv.trim().parse() { obj.q_frequency_exponent = Some(v); } }
177                        crate::base::FieldValue::TextList(svs) => {
178                            if let Some(sv) = svs.last() { if let Ok(v) = sv.trim().parse() { obj.q_frequency_exponent = Some(v); } }
179                        }
180                        _ => {}
181                    }
182                }
183                "LoadResponseCharacteristic.qVoltageExponent" => {
184                    match val {
185                        crate::base::FieldValue::Text(sv) => { if let Ok(v) = sv.trim().parse() { obj.q_voltage_exponent = Some(v); } }
186                        crate::base::FieldValue::TextList(svs) => {
187                            if let Some(sv) = svs.last() { if let Ok(v) = sv.trim().parse() { obj.q_voltage_exponent = Some(v); } }
188                        }
189                        _ => {}
190                    }
191                }
192                "IdentifiedObject.description" => {
193                    match val {
194                        crate::base::FieldValue::Text(sv) => { obj.base.description = sv.clone(); }
195                        crate::base::FieldValue::TextList(svs) => {
196                            if let Some(sv) = svs.last() { obj.base.description = sv.clone(); }
197                        }
198                        _ => {}
199                    }
200                }
201                "IdentifiedObject.energyIdentCodeEic" => {
202                    match val {
203                        crate::base::FieldValue::Text(sv) => { obj.base.energy_ident_code_eic = sv.clone(); }
204                        crate::base::FieldValue::TextList(svs) => {
205                            if let Some(sv) = svs.last() { obj.base.energy_ident_code_eic = sv.clone(); }
206                        }
207                        _ => {}
208                    }
209                }
210                "IdentifiedObject.mRID" => {
211                    match val {
212                        crate::base::FieldValue::Text(sv) => { obj.base.m_rid = sv.clone(); }
213                        crate::base::FieldValue::TextList(svs) => {
214                            if let Some(sv) = svs.last() { obj.base.m_rid = sv.clone(); }
215                        }
216                        _ => {}
217                    }
218                }
219                "IdentifiedObject.name" => {
220                    match val {
221                        crate::base::FieldValue::Text(sv) => { obj.base.name = sv.clone(); }
222                        crate::base::FieldValue::TextList(svs) => {
223                            if let Some(sv) = svs.last() { obj.base.name = sv.clone(); }
224                        }
225                        _ => {}
226                    }
227                }
228                "IdentifiedObject.shortName" => {
229                    match val {
230                        crate::base::FieldValue::Text(sv) => { obj.base.short_name = sv.clone(); }
231                        crate::base::FieldValue::TextList(svs) => {
232                            if let Some(sv) = svs.last() { obj.base.short_name = sv.clone(); }
233                        }
234                        _ => {}
235                    }
236                }
237                _ => {}
238            }
239        }
240        obj
241    }
242}