def __init__(self, system, config): Model.__init__(self, system, config) self.group = 'TurbineGov' self.flags.update({'tds': True}) self.Sn = ExtParam( src='Sn', model='SynGen', indexer=self.syn, tex_name='S_m', info='Rated power from generator', unit='MVA', export=False, ) self.Vn = ExtParam( src='Vn', model='SynGen', indexer=self.syn, tex_name='V_m', info='Rated voltage from generator', unit='kV', export=False, ) self.tm0 = ExtService(src='tm', model='SynGen', indexer=self.syn, tex_name=r'\tau_{m0}', info='Initial mechanical input') self.omega = ExtState(src='omega', model='SynGen', indexer=self.syn, tex_name=r'\omega', info='Generator speed', unit='p.u.') self.gain = ConstService( v_str='u / R', tex_name='G', ) self.tm = ExtAlgeb( src='tm', model='SynGen', indexer=self.syn, tex_name=r'\tau_m', e_str='u * (pout - tm0)', info='Mechanical power to generator', ) self.pout = Algeb( info='Turbine final output power', tex_name='P_{out}', v_str='tm0', ) self.wref = Algeb( info='Speed reference variable', tex_name=r'\omega_{ref}', v_str='wref0', e_str='wref0 - wref', )
def __init__(self, system, config): REECA1Model.__init__(self, system, config) self.omega = ExtState(model='SynGen', src='omega', indexer=self.sg, export=False, info='generator speed', unit='pu', ) self.Pref.e_str += '- Kf * (omega - 1)'
def __init__(self, system, config): Model.__init__(self, system, config) self.group = 'Exciter' self.flags.tds = True # from synchronous generators, get Sn, Vn, bus; tm0; omega self.Sn = ExtParam( src='Sn', model='SynGen', indexer=self.syn, tex_name='S_m', info='Rated power from generator', unit='MVA', export=False, ) self.Vn = ExtParam( src='Vn', model='SynGen', indexer=self.syn, tex_name='V_m', info='Rated voltage from generator', unit='kV', export=False, ) self.vf0 = ExtService(src='vf', model='SynGen', indexer=self.syn, tex_name='v_{f0}', info='Steady state excitation voltage') self.bus = ExtParam( src='bus', model='SynGen', indexer=self.syn, tex_name='bus', info='Bus idx of the generators', export=False, vtype=str, ) self.omega = ExtState( src='omega', model='SynGen', indexer=self.syn, tex_name=r'\omega', info='Generator speed', ) self.vf = ExtAlgeb( src='vf', model='SynGen', indexer=self.syn, tex_name=r'v_f', e_str='u * (vout - vf0)', info='Excitation field voltage to generator', ) self.XadIfd = ExtAlgeb( src='XadIfd', model='SynGen', indexer=self.syn, tex_name=r'X_{ad}I_{fd}', info='Armature excitation current', ) # from bus, get a and v self.a = ExtAlgeb( model='Bus', src='a', indexer=self.bus, tex_name=r'\theta', info='Bus voltage phase angle', ) self.v = ExtAlgeb( model='Bus', src='v', indexer=self.bus, tex_name=r'V', info='Bus voltage magnitude', ) # output excitation voltage self.vout = Algeb( info='Exciter final output voltage', tex_name='v_{out}', v_str='vf0', )
def __init__(self, system, config): Model.__init__(self, system, config) self.group = 'Calculation' self.flags.update({'tds': True}) self.SynGen = BackRef(info='Back reference to SynGen idx') self.SynGenIdx = RefFlatten(ref=self.SynGen) self.M = ExtParam( model='SynGen', src='M', indexer=self.SynGenIdx, export=False, info='Linearly stored SynGen.M', ) self.wgen = ExtState( model='SynGen', src='omega', indexer=self.SynGenIdx, tex_name=r'\omega_{gen}', info='Linearly stored SynGen.omega', ) self.agen = ExtState( model='SynGen', src='delta', indexer=self.SynGenIdx, tex_name=r'\delta_{gen}', info='Linearly stored SynGen.delta', ) self.d0 = ExtService( model='SynGen', src='delta', indexer=self.SynGenIdx, tex_name=r'\delta_{gen,0}', info='Linearly stored initial delta', ) self.a0 = ExtService( model='SynGen', src='omega', indexer=self.SynGenIdx, tex_name=r'\omega_{gen,0}', info='Linearly stored initial omega', ) self.Mt = NumReduce( u=self.M, tex_name='M_t', fun=np.sum, ref=self.SynGen, info='Summation of M by COI index', ) self.Mr = NumRepeat( u=self.Mt, tex_name='M_{tr}', ref=self.SynGen, info='Repeated summation of M', ) self.Mw = ConstService(tex_name='M_w', info='Inertia weights', v_str='M/Mr') self.d0w = ConstService(tex_name=r'\delta_{gen,0,w}', v_str='d0 * Mw', info='Linearly stored weighted delta') self.a0w = ConstService(tex_name=r'\omega_{gen,0,w}', v_str='a0 * Mw', info='Linearly stored weighted omega') self.d0a = NumReduce( u=self.d0w, tex_name=r'\delta_{gen,0,avg}', fun=np.sum, ref=self.SynGen, info='Average initial delta', cache=False, ) self.a0a = NumReduce( u=self.a0w, tex_name=r'\omega_{gen,0,avg}', fun=np.sum, ref=self.SynGen, info='Average initial omega', cache=False, ) self.pidx = IdxRepeat(u=self.idx, ref=self.SynGen, info='Repeated COI.idx') # Note: # Even if d(omega) /d (omega) = 1, it is still stored as a lambda function. # When no SynGen is referencing any COI, j_update will not be called, # and Jacobian will become singular. `diag_eps = True` needs to be used. # Note: # Do not assign `v_str=1` for `omega`. Otherwise, COIs with no connected generators will # fail to initialize. self.omega = Algeb( tex_name=r'\omega_{coi}', info='COI speed', v_str='a0a', v_setter=True, e_str='-omega', diag_eps=True, ) self.delta = Algeb( tex_name=r'\delta_{coi}', info='COI rotor angle', v_str='d0a', v_setter=True, e_str='-delta', diag_eps=True, ) # Note: # `omega_sub` or `delta_sub` must not provide `v_str`. # Otherwise, values will be incorrectly summed for `omega` and `delta`. self.omega_sub = ExtAlgeb( model='COI', src='omega', e_str='Mw * wgen', indexer=self.pidx, info='COI frequency contribution of each generator') self.delta_sub = ExtAlgeb( model='COI', src='delta', e_str='Mw * agen', indexer=self.pidx, info='COI angle contribution of each generator')
def __init__(self, system, config): super().__init__(system, config) self.group = 'PSS' self.flags.update({'tds': True}) self.VCUr = Replace(self.VCU, lambda x: np.equal(x, 0.0), 999) self.VCLr = Replace(self.VCL, lambda x: np.equal(x, 0.0), -999) # retrieve indices of connected generator, bus, and bus freq self.syn = ExtParam(model='Exciter', src='syn', indexer=self.avr, export=False, info='Retrieved generator idx', dtype=str) self.bus = ExtParam( model='SynGen', src='bus', indexer=self.syn, export=False, info='Retrieved bus idx', dtype=str, default=None, ) self.buss = DataSelect(self.busr, self.bus, info='selected bus (bus or busr)') self.busfreq = DeviceFinder(self.busf, link=self.buss, idx_name='bus') # from SynGen self.Sn = ExtParam(model='SynGen', src='Sn', indexer=self.syn, tex_name='S_n', info='Generator power base', export=False) self.omega = ExtState( model='SynGen', src='omega', indexer=self.syn, tex_name=r'\omega', info='Generator speed', unit='p.u.', ) self.tm0 = ExtService( model='SynGen', src='tm', indexer=self.syn, tex_name=r'\tau_{m0}', info='Initial mechanical input', ) self.tm = ExtAlgeb( model='SynGen', src='tm', indexer=self.syn, tex_name=r'\tau_m', info='Generator mechanical input', ) self.te = ExtAlgeb( model='SynGen', src='te', indexer=self.syn, tex_name=r'\tau_e', info='Generator electrical output', ) # from Bus self.v = ExtAlgeb( model='Bus', src='v', indexer=self.buss, tex_name=r'V', info='Bus (or busr, if given) terminal voltage', ) self.v0 = ExtService( model='Bus', src='v', indexer=self.buss, tex_name="V_0", info='Initial bus voltage', ) # from BusFreq self.f = ExtAlgeb(model='FreqMeasurement', src='f', indexer=self.busfreq, export=False, info='Bus frequency') # from Exciter self.vi = ExtAlgeb(model='Exciter', src='vi', indexer=self.avr, tex_name='v_i', info='Exciter input voltage', e_str='u * vsout') self.vsout = Algeb( info='PSS output voltage to exciter', tex_name='v_{sout}', ) # `self.vsout.e_str` to be provided by specific models
def __init__(self, system, config, add_sn=True, add_tm0=True): Model.__init__(self, system, config) self.group = 'TurbineGov' self.flags.update({'tds': True}) self.Sg = ExtParam( src='Sn', model='SynGen', indexer=self.syn, tex_name='S_n', info='Rated power from generator', unit='MVA', export=False, ) if add_sn is True: self.Sn = NumSelect( self.Tn, fallback=self.Sg, tex_name='S_n', info='Turbine or Gen rating', ) self.Vn = ExtParam( src='Vn', model='SynGen', indexer=self.syn, tex_name='V_n', info='Rated voltage from generator', unit='kV', export=False, ) # Note: changing `tm0` is not allowed in any time!! if add_tm0 is True: self.tm0 = ExtService(src='tm', model='SynGen', indexer=self.syn, tex_name=r'\tau_{m0}', info='Initial mechanical input') self.omega = ExtState(src='omega', model='SynGen', indexer=self.syn, tex_name=r'\omega', info='Generator speed', unit='p.u.') # Note: changing `paux0` is allowed. # It is a way how one can input from external programs such as reinforcement learning. self.paux0 = ConstService(v_str='0', tex_name='P_{aux0}', info='const. auxiliary input') self.tm = ExtAlgeb( src='tm', model='SynGen', indexer=self.syn, tex_name=r'\tau_m', e_str='u * (pout - tm0)', info='Mechanical power interface to SynGen', ) # `paux` must be zero upon initialization self.paux = Algeb( info='Auxiliary power input', tex_name='P_{aux}', v_str='paux0', e_str='paux0 - paux', ) self.pout = Algeb( info='Turbine final output power', tex_name='P_{out}', v_str='u*tm0', ) self.wref = Algeb( info='Speed reference variable', tex_name=r'\omega_{ref}', v_str='wref0', e_str='wref0 - wref', )
def __init__(self, system, config): Model.__init__(self, system, config) self.group = 'Exciter' self.flags.tds = True # Voltage compensator idx-es self.VoltComp = BackRef() # from synchronous generators, get u, Sn, Vn, bus; tm0; omega self.ug = ExtParam( src='u', model='SynGen', indexer=self.syn, tex_name='u_g', info='Generator online status', unit='bool', export=False, ) self.ue = ConstService( v_str='u * ug', info="effective online status", tex_name='u_e', ) self.Sn = ExtParam( src='Sn', model='SynGen', indexer=self.syn, tex_name='S_m', info='Rated power from generator', unit='MVA', export=False, ) self.Vn = ExtParam( src='Vn', model='SynGen', indexer=self.syn, tex_name='V_m', info='Rated voltage from generator', unit='kV', export=False, ) self.vf0 = ExtService(src='vf', model='SynGen', indexer=self.syn, tex_name='v_{f0}', info='Steady state excitation voltage') self.bus = ExtParam( src='bus', model='SynGen', indexer=self.syn, tex_name='bus', info='Bus idx of the generators', export=False, vtype=str, ) self.omega = ExtState( src='omega', model='SynGen', indexer=self.syn, tex_name=r'\omega', info='Generator speed', is_input=True, ) self.vf = ExtAlgeb( src='vf', model='SynGen', indexer=self.syn, tex_name=r'v_f', e_str='ue * (vout - vf0)', info='Excitation field voltage to generator', ename='vf', tex_ename='v_f', is_input=False, ) self.XadIfd = ExtAlgeb( src='XadIfd', model='SynGen', indexer=self.syn, tex_name=r'X_{ad}I_{fd}', info='Armature excitation current', is_input=True, ) # from bus, get a and v self.a = ExtAlgeb( model='Bus', src='a', indexer=self.bus, tex_name=r'\theta', info='Bus voltage phase angle', is_input=True, ) self.vbus = ExtAlgeb(model='Bus', src='v', indexer=self.bus, tex_name='V', info='Bus voltage magnitude', is_input=True) # `self.v` is actually `ETERM` in other software # TODO: # Preferably, its name needs to be changed to `eterm`. # That requires updates in equations of all exciters. self.v = Algeb( info='Input to exciter (bus v or Eterm)', tex_name='E_{term}', v_str='vbus', e_str='vbus - v', v_str_add=True, ) # output excitation voltage self.vout = Algeb( info='Exciter final output voltage', tex_name='v_{out}', v_str='ue * vf0', diag_eps=True, is_output=True, )
def __init__(self, system, config): super().__init__(system, config) self.group = 'PSS' self.flags.update({'tds': True}) self.syn = ExtParam(model='Exciter', src='syn', indexer=self.avr, export=False, info='Retrieved generator idx') self.bus = ExtParam(model='SynGen', src='bus', indexer=self.syn, export=False, info='Retrieved bus idx') self.Sn = ExtParam(model='SynGen', src='Sn', indexer=self.syn, tex_name='S_n', info='Generator power base', export=False) # from SynGen self.omega = ExtState( model='SynGen', src='omega', indexer=self.syn, tex_name=r'\omega', info='Generator speed', unit='p.u.', ) self.tm0 = ExtService( model='SynGen', src='tm', indexer=self.syn, tex_name=r'\tau_{m0}', info='Initial mechanical input', ) self.tm = ExtAlgeb( model='SynGen', src='tm', indexer=self.syn, tex_name=r'\tau_m', info='Generator mechanical input', ) self.te = ExtAlgeb( model='SynGen', src='te', indexer=self.syn, tex_name=r'\tau_e', info='Generator electrical output', ) self.vf = ExtAlgeb(model='SynGen', src='vf', indexer=self.syn, tex_name='v_f', info='Generator excitation voltage', e_str='u * vsout') # from Bus #TODO: implement the optional BUSR self.v = ExtAlgeb( model='Bus', src='v', indexer=self.bus, tex_name=r'V', info='Bus (or BUSR, if given) terminal voltage', ) # from Exciter self.vsout = Algeb( info='PSS output voltage to exciter', tex_name='v_{sout}', ) # `e_str` to be provided by specific models