1 # Copyright (C) 2010-2011 Richard Lincoln
3 # Permission is hereby granted, free of charge, to any person obtaining a copy
4 # of this software and associated documentation files (the "Software"), to
5 # deal in the Software without restriction, including without limitation the
6 # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
7 # sell copies of the Software, and to permit persons to whom the Software is
8 # furnished to do so, subject to the following conditions:
10 # The above copyright notice and this permission notice shall be included in
11 # all copies or substantial portions of the Software.
13 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18 # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 from CIM14
.IEC61970
.Dynamics
.RotatingMachine
import RotatingMachine
23 class SynchronousMachine(RotatingMachine
):
24 """An electromechanical device that operates synchronously with the network. It is a single machine operating either as a generator or synchronous condenser or pump.
27 def __init__(self
, operatingMode
="condenser", type="generator_or_condenser", coolantType
="air", xQuadTrans
=0.0, condenserP
=0.0, referencePriority
=0, damping
=0.0, x0
=0.0, r2
=0.0, minQ
=0.0, xDirectSync
=0.0, maxQ
=0.0, r0
=0.0, aVRToManualLead
=0.0, x
=0.0, inertia
=0.0, coolantCondition
=0.0, manualToAVR
=0.0, r
=0.0, maxU
=0.0, xQuadSync
=0.0, qPercent
=0.0, xQuadSubtrans
=0.0, minU
=0.0, aVRToManualLag
=0.0, baseQ
=0.0, xDirectTrans
=0.0, x2
=0.0, xDirectSubtrans
=0.0, genLoad0
=None, HydroPump
=None, GeneratingUnit
=None, govHydro10
=None, PrimeMovers
=None, InitialReactiveCapabilityCurve
=None, genEquiv0
=None, ReactiveCapabilityCurves
=None, *args
, **kw_args
):
28 """Initialises a new 'SynchronousMachine' instance.
30 @param operatingMode: Current mode of operation. Values are: "condenser", "generator"
31 @param type: Modes that this synchronous machine can operate in. Values are: "generator_or_condenser", "generator", "condenser"
32 @param coolantType: Method of cooling the machine. Values are: "air", "hydrogenGas", "water"
33 @param xQuadTrans: Quadrature-axis transient reactance, also known as X'q.
34 @param condenserP: Active power consumed when in condenser mode operation.
35 @param referencePriority: Priority of unit for reference bus selection. 0 = don t care (default) 1 = highest priority. 2 is less than 1 and so on.
36 @param damping: Damping torque coefficient, a proportionality constant that, when multiplied by the angular velocity of the rotor poles with respect to the magnetic field (frequency), results in the damping torque.
37 @param x0: Zero sequence reactance of the synchronous machine.
38 @param r2: Negative sequence resistance.
39 @param minQ: Minimum reactive power limit for the unit.
40 @param xDirectSync: Direct-axis synchronous reactance. The quotient of a sustained value of that AC component of armature voltage that is produced by the total direct-axis flux due to direct-axis armature current and the value of the AC component of this current, the machine running at rated speed. (Xd)
41 @param maxQ: Maximum reactive power limit. This is the maximum (nameplate) limit for the unit.
42 @param r0: Zero sequence resistance of the synchronous machine.
43 @param aVRToManualLead: Time delay required when switching from Automatic Voltage Regulation (AVR) to Manual for a leading MVAr violation.
44 @param x: Positive sequence reactance of the synchronous machine.
45 @param inertia: The energy stored in the rotor when operating at rated speed. This value is used in the accelerating power reference frame for operator training simulator solutions.
46 @param coolantCondition: Temperature or pressure of coolant medium
47 @param manualToAVR: Time delay required when switching from Manual to Automatic Voltage Regulation. This value is used in the accelerating power reference frame for powerflow solutions
48 @param r: Positive sequence resistance of the synchronous machine.
49 @param maxU: Maximum voltage limit for the unit.
50 @param xQuadSync: Quadrature-axis synchronous reactance (Xq) , the ratio of the component of reactive armature voltage, due to the quadrature-axis component of armature current, to this component of current, under steady state conditions and at rated frequency.
51 @param qPercent: Percent of the coordinated reactive control that comes from this machine.
52 @param xQuadSubtrans: Quadrature-axis subtransient reactance, also known as X'q.
53 @param minU: Minimum voltage limit for the unit.
54 @param aVRToManualLag: Time delay required when switching from Automatic Voltage Regulation (AVR) to Manual for a lagging MVAr violation.
55 @param baseQ: Default base reactive power value. This value represents the initial reactive power that can be used by any application function.
56 @param xDirectTrans: Direct-axis transient reactance, also known as X'd.
57 @param x2: Negative sequence reactance.
58 @param xDirectSubtrans: Direct-axis subtransient reactance, also known as X'd.
60 @param HydroPump: The synchronous machine drives the turbine which moves the water from a low elevation to a higher elevation. The direction of machine rotation for pumping may or may not be the same as for generating.
61 @param GeneratingUnit: A synchronous machine may operate as a generator and as such becomes a member of a generating unit
63 @param PrimeMovers: Prime movers that drive this SynchronousMachine.
64 @param InitialReactiveCapabilityCurve: The default ReactiveCapabilityCurve for use by a SynchronousMachine
66 @param ReactiveCapabilityCurves: All available Reactive capability curves for this SynchronousMachine.
68 #: Current mode of operation. Values are: "condenser", "generator"
69 self
.operatingMode
= operatingMode
71 #: Modes that this synchronous machine can operate in. Values are: "generator_or_condenser", "generator", "condenser"
74 #: Method of cooling the machine. Values are: "air", "hydrogenGas", "water"
75 self
.coolantType
= coolantType
77 #: Quadrature-axis transient reactance, also known as X'q.
78 self
.xQuadTrans
= xQuadTrans
80 #: Active power consumed when in condenser mode operation.
81 self
.condenserP
= condenserP
83 #: Priority of unit for reference bus selection. 0 = don t care (default) 1 = highest priority. 2 is less than 1 and so on.
84 self
.referencePriority
= referencePriority
86 #: Damping torque coefficient, a proportionality constant that, when multiplied by the angular velocity of the rotor poles with respect to the magnetic field (frequency), results in the damping torque.
87 self
.damping
= damping
89 #: Zero sequence reactance of the synchronous machine.
92 #: Negative sequence resistance.
95 #: Minimum reactive power limit for the unit.
98 #: Direct-axis synchronous reactance. The quotient of a sustained value of that AC component of armature voltage that is produced by the total direct-axis flux due to direct-axis armature current and the value of the AC component of this current, the machine running at rated speed. (Xd)
99 self
.xDirectSync
= xDirectSync
101 #: Maximum reactive power limit. This is the maximum (nameplate) limit for the unit.
104 #: Zero sequence resistance of the synchronous machine.
107 #: Time delay required when switching from Automatic Voltage Regulation (AVR) to Manual for a leading MVAr violation.
108 self
.aVRToManualLead
= aVRToManualLead
110 #: Positive sequence reactance of the synchronous machine.
113 #: The energy stored in the rotor when operating at rated speed. This value is used in the accelerating power reference frame for operator training simulator solutions.
114 self
.inertia
= inertia
116 #: Temperature or pressure of coolant medium
117 self
.coolantCondition
= coolantCondition
119 #: Time delay required when switching from Manual to Automatic Voltage Regulation. This value is used in the accelerating power reference frame for powerflow solutions
120 self
.manualToAVR
= manualToAVR
122 #: Positive sequence resistance of the synchronous machine.
125 #: Maximum voltage limit for the unit.
128 #: Quadrature-axis synchronous reactance (Xq) , the ratio of the component of reactive armature voltage, due to the quadrature-axis component of armature current, to this component of current, under steady state conditions and at rated frequency.
129 self
.xQuadSync
= xQuadSync
131 #: Percent of the coordinated reactive control that comes from this machine.
132 self
.qPercent
= qPercent
134 #: Quadrature-axis subtransient reactance, also known as X'q.
135 self
.xQuadSubtrans
= xQuadSubtrans
137 #: Minimum voltage limit for the unit.
140 #: Time delay required when switching from Automatic Voltage Regulation (AVR) to Manual for a lagging MVAr violation.
141 self
.aVRToManualLag
= aVRToManualLag
143 #: Default base reactive power value. This value represents the initial reactive power that can be used by any application function.
146 #: Direct-axis transient reactance, also known as X'd.
147 self
.xDirectTrans
= xDirectTrans
149 #: Negative sequence reactance.
152 #: Direct-axis subtransient reactance, also known as X'd.
153 self
.xDirectSubtrans
= xDirectSubtrans
156 self
.genLoad0
= [] if genLoad0
is None else genLoad0
158 self
._HydroPump
= None
159 self
.HydroPump
= HydroPump
161 self
._GeneratingUnit
= None
162 self
.GeneratingUnit
= GeneratingUnit
164 self
._govHydro
10 = []
165 self
.govHydro10
= [] if govHydro10
is None else govHydro10
167 self
._PrimeMovers
= []
168 self
.PrimeMovers
= [] if PrimeMovers
is None else PrimeMovers
170 self
._InitialReactiveCapabilityCurve
= None
171 self
.InitialReactiveCapabilityCurve
= InitialReactiveCapabilityCurve
174 self
.genEquiv0
= [] if genEquiv0
is None else genEquiv0
176 self
._ReactiveCapabilityCurves
= []
177 self
.ReactiveCapabilityCurves
= [] if ReactiveCapabilityCurves
is None else ReactiveCapabilityCurves
179 super(SynchronousMachine
, self
).__init
__(*args
, **kw_args
)
181 _attrs
= ["operatingMode", "type", "coolantType", "xQuadTrans", "condenserP", "referencePriority", "damping", "x0", "r2", "minQ", "xDirectSync", "maxQ", "r0", "aVRToManualLead", "x", "inertia", "coolantCondition", "manualToAVR", "r", "maxU", "xQuadSync", "qPercent", "xQuadSubtrans", "minU", "aVRToManualLag", "baseQ", "xDirectTrans", "x2", "xDirectSubtrans"]
182 _attr_types
= {"operatingMode": str, "type": str, "coolantType": str, "xQuadTrans": float, "condenserP": float, "referencePriority": int, "damping": float, "x0": float, "r2": float, "minQ": float, "xDirectSync": float, "maxQ": float, "r0": float, "aVRToManualLead": float, "x": float, "inertia": float, "coolantCondition": float, "manualToAVR": float, "r": float, "maxU": float, "xQuadSync": float, "qPercent": float, "xQuadSubtrans": float, "minU": float, "aVRToManualLag": float, "baseQ": float, "xDirectTrans": float, "x2": float, "xDirectSubtrans": float}
183 _defaults
= {"operatingMode": "condenser", "type": "generator_or_condenser", "coolantType": "air", "xQuadTrans": 0.0, "condenserP": 0.0, "referencePriority": 0, "damping": 0.0, "x0": 0.0, "r2": 0.0, "minQ": 0.0, "xDirectSync": 0.0, "maxQ": 0.0, "r0": 0.0, "aVRToManualLead": 0.0, "x": 0.0, "inertia": 0.0, "coolantCondition": 0.0, "manualToAVR": 0.0, "r": 0.0, "maxU": 0.0, "xQuadSync": 0.0, "qPercent": 0.0, "xQuadSubtrans": 0.0, "minU": 0.0, "aVRToManualLag": 0.0, "baseQ": 0.0, "xDirectTrans": 0.0, "x2": 0.0, "xDirectSubtrans": 0.0}
184 _enums
= {"operatingMode": "SynchronousMachineOperatingMode", "type": "SynchronousMachineType", "coolantType": "CoolantType"}
185 _refs
= ["genLoad0", "HydroPump", "GeneratingUnit", "govHydro10", "PrimeMovers", "InitialReactiveCapabilityCurve", "genEquiv0", "ReactiveCapabilityCurves"]
186 _many_refs
= ["genLoad0", "govHydro10", "PrimeMovers", "genEquiv0", "ReactiveCapabilityCurves"]
188 def getgenLoad0(self
):
190 return self
._genLoad
0
192 def setgenLoad0(self
, value
):
193 for p
in self
._genLoad
0:
194 filtered
= [q
for q
in p
.synchronousMachine0
if q
!= self
]
195 self
._genLoad
0._synchronousMachine
0 = filtered
197 if self
not in r
._synchronousMachine
0:
198 r
._synchronousMachine
0.append(self
)
199 self
._genLoad
0 = value
201 genLoad0
= property(getgenLoad0
, setgenLoad0
)
203 def addgenLoad0(self
, *genLoad0
):
205 if self
not in obj
._synchronousMachine
0:
206 obj
._synchronousMachine
0.append(self
)
207 self
._genLoad
0.append(obj
)
209 def removegenLoad0(self
, *genLoad0
):
211 if self
in obj
._synchronousMachine
0:
212 obj
._synchronousMachine
0.remove(self
)
213 self
._genLoad
0.remove(obj
)
215 def getHydroPump(self
):
216 """The synchronous machine drives the turbine which moves the water from a low elevation to a higher elevation. The direction of machine rotation for pumping may or may not be the same as for generating.
218 return self
._HydroPump
220 def setHydroPump(self
, value
):
221 if self
._HydroPump
is not None:
222 self
._HydroPump
._SynchronousMachine
= None
224 self
._HydroPump
= value
225 if self
._HydroPump
is not None:
226 self
._HydroPump
.SynchronousMachine
= None
227 self
._HydroPump
._SynchronousMachine
= self
229 HydroPump
= property(getHydroPump
, setHydroPump
)
231 def getGeneratingUnit(self
):
232 """A synchronous machine may operate as a generator and as such becomes a member of a generating unit
234 return self
._GeneratingUnit
236 def setGeneratingUnit(self
, value
):
237 if self
._GeneratingUnit
is not None:
238 filtered
= [x
for x
in self
.GeneratingUnit
.SynchronousMachines
if x
!= self
]
239 self
._GeneratingUnit
._SynchronousMachines
= filtered
241 self
._GeneratingUnit
= value
242 if self
._GeneratingUnit
is not None:
243 if self
not in self
._GeneratingUnit
._SynchronousMachines
:
244 self
._GeneratingUnit
._SynchronousMachines
.append(self
)
246 GeneratingUnit
= property(getGeneratingUnit
, setGeneratingUnit
)
248 def getgovHydro10(self
):
250 return self
._govHydro
10
252 def setgovHydro10(self
, value
):
253 for p
in self
._govHydro
10:
254 filtered
= [q
for q
in p
.synchronousMachine0
if q
!= self
]
255 self
._govHydro
10._synchronousMachine
0 = filtered
257 if self
not in r
._synchronousMachine
0:
258 r
._synchronousMachine
0.append(self
)
259 self
._govHydro
10 = value
261 govHydro10
= property(getgovHydro10
, setgovHydro10
)
263 def addgovHydro10(self
, *govHydro10
):
264 for obj
in govHydro10
:
265 if self
not in obj
._synchronousMachine
0:
266 obj
._synchronousMachine
0.append(self
)
267 self
._govHydro
10.append(obj
)
269 def removegovHydro10(self
, *govHydro10
):
270 for obj
in govHydro10
:
271 if self
in obj
._synchronousMachine
0:
272 obj
._synchronousMachine
0.remove(self
)
273 self
._govHydro
10.remove(obj
)
275 def getPrimeMovers(self
):
276 """Prime movers that drive this SynchronousMachine.
278 return self
._PrimeMovers
280 def setPrimeMovers(self
, value
):
281 for p
in self
._PrimeMovers
:
282 filtered
= [q
for q
in p
.SynchronousMachines
if q
!= self
]
283 self
._PrimeMovers
._SynchronousMachines
= filtered
285 if self
not in r
._SynchronousMachines
:
286 r
._SynchronousMachines
.append(self
)
287 self
._PrimeMovers
= value
289 PrimeMovers
= property(getPrimeMovers
, setPrimeMovers
)
291 def addPrimeMovers(self
, *PrimeMovers
):
292 for obj
in PrimeMovers
:
293 if self
not in obj
._SynchronousMachines
:
294 obj
._SynchronousMachines
.append(self
)
295 self
._PrimeMovers
.append(obj
)
297 def removePrimeMovers(self
, *PrimeMovers
):
298 for obj
in PrimeMovers
:
299 if self
in obj
._SynchronousMachines
:
300 obj
._SynchronousMachines
.remove(self
)
301 self
._PrimeMovers
.remove(obj
)
303 def getInitialReactiveCapabilityCurve(self
):
304 """The default ReactiveCapabilityCurve for use by a SynchronousMachine
306 return self
._InitialReactiveCapabilityCurve
308 def setInitialReactiveCapabilityCurve(self
, value
):
309 if self
._InitialReactiveCapabilityCurve
is not None:
310 filtered
= [x
for x
in self
.InitialReactiveCapabilityCurve
.InitiallyUsedBySynchronousMachines
if x
!= self
]
311 self
._InitialReactiveCapabilityCurve
._InitiallyUsedBySynchronousMachines
= filtered
313 self
._InitialReactiveCapabilityCurve
= value
314 if self
._InitialReactiveCapabilityCurve
is not None:
315 if self
not in self
._InitialReactiveCapabilityCurve
._InitiallyUsedBySynchronousMachines
:
316 self
._InitialReactiveCapabilityCurve
._InitiallyUsedBySynchronousMachines
.append(self
)
318 InitialReactiveCapabilityCurve
= property(getInitialReactiveCapabilityCurve
, setInitialReactiveCapabilityCurve
)
320 def getgenEquiv0(self
):
322 return self
._genEquiv
0
324 def setgenEquiv0(self
, value
):
325 for p
in self
._genEquiv
0:
326 filtered
= [q
for q
in p
.synchronousMachine0
if q
!= self
]
327 self
._genEquiv
0._synchronousMachine
0 = filtered
329 if self
not in r
._synchronousMachine
0:
330 r
._synchronousMachine
0.append(self
)
331 self
._genEquiv
0 = value
333 genEquiv0
= property(getgenEquiv0
, setgenEquiv0
)
335 def addgenEquiv0(self
, *genEquiv0
):
336 for obj
in genEquiv0
:
337 if self
not in obj
._synchronousMachine
0:
338 obj
._synchronousMachine
0.append(self
)
339 self
._genEquiv
0.append(obj
)
341 def removegenEquiv0(self
, *genEquiv0
):
342 for obj
in genEquiv0
:
343 if self
in obj
._synchronousMachine
0:
344 obj
._synchronousMachine
0.remove(self
)
345 self
._genEquiv
0.remove(obj
)
347 def getReactiveCapabilityCurves(self
):
348 """All available Reactive capability curves for this SynchronousMachine.
350 return self
._ReactiveCapabilityCurves
352 def setReactiveCapabilityCurves(self
, value
):
353 for p
in self
._ReactiveCapabilityCurves
:
354 filtered
= [q
for q
in p
.SynchronousMachines
if q
!= self
]
355 self
._ReactiveCapabilityCurves
._SynchronousMachines
= filtered
357 if self
not in r
._SynchronousMachines
:
358 r
._SynchronousMachines
.append(self
)
359 self
._ReactiveCapabilityCurves
= value
361 ReactiveCapabilityCurves
= property(getReactiveCapabilityCurves
, setReactiveCapabilityCurves
)
363 def addReactiveCapabilityCurves(self
, *ReactiveCapabilityCurves
):
364 for obj
in ReactiveCapabilityCurves
:
365 if self
not in obj
._SynchronousMachines
:
366 obj
._SynchronousMachines
.append(self
)
367 self
._ReactiveCapabilityCurves
.append(obj
)
369 def removeReactiveCapabilityCurves(self
, *ReactiveCapabilityCurves
):
370 for obj
in ReactiveCapabilityCurves
:
371 if self
in obj
._SynchronousMachines
:
372 obj
._SynchronousMachines
.remove(self
)
373 self
._ReactiveCapabilityCurves
.remove(obj
)