Exemple #1
0
    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',
        )
Exemple #2
0
    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)'
Exemple #3
0
    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',
        )
Exemple #4
0
    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')
Exemple #5
0
    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
Exemple #6
0
    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',
        )
Exemple #7
0
    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,
        )
Exemple #8
0
    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