def __init__(self, system, config): Model.__init__(self, system, config) self.flags.tds = True self.group = 'RenPitch' self.rego = ExtParam( model='RenAerodynamics', src='rego', indexer=self.rea, export=False, ) self.ree = ExtParam( model='RenGovernor', src='ree', indexer=self.rego, export=False, ) self.wt = ExtAlgeb( model='RenGovernor', src='wt', indexer=self.rego, export=False, ) self.theta0 = ExtService( model='RenAerodynamics', src='theta0', indexer=self.rea, ) self.theta = ExtAlgeb(model='RenAerodynamics', src='theta', indexer=self.rea, export=False, e_str='-theta0 + LG_y') self.Pord = ExtState( model='RenExciter', src='Pord', indexer=self.ree, ) self.Pref = ExtAlgeb( model='RenExciter', src='Pref', indexer=self.ree, ) self.PIc = PIAWHardLimit( u='Pord - Pref', kp=self.Kpc, ki=self.Kic, aw_lower=self.thmin, aw_upper=self.thmax, lower=self.thmin, upper=self.thmax, tex_name='PI_c', info='PI for active power diff compensation', ) self.wref = Algeb( tex_name=r'\omega_{ref}', info='optional speed reference', e_str='wt - wref', v_str='wt', ) self.PIw = PIAWHardLimit( u='Kcc * (Pord - Pref) + wt - wref', kp=self.Kpw, ki=self.Kiw, aw_lower=self.thmin, aw_upper=self.thmax, lower=self.thmin, upper=self.thmax, tex_name='PI_w', info='PI for speed and active power deviation', ) self.LG = LagAntiWindupRate(u='PIw_y + PIc_y', T=self.Tp, K=1.0, lower=self.thmin, upper=self.thmax, rate_lower=self.dthmin, rate_upper=self.dthmax, tex_name='LG', info='Output lag anti-windup rate limiter') # remove warning when pitch angle==0 self.PIc_hl.warn_flags.pop(0) self.PIc_aw.warn_flags.pop(0) self.PIw_hl.warn_flags.pop(0) self.PIw_aw.warn_flags.pop(0) self.LG_lim.warn_flags.pop(0)
def __init__(self, system, config): Model.__init__(self, system, config) self.flags.tds = True self.group = 'RenGen' self.a = ExtAlgeb(model='Bus', src='a', indexer=self.bus, tex_name=r'\theta', info='Bus voltage angle', e_str='-Pe', ) self.v = ExtAlgeb(model='Bus', src='v', indexer=self.bus, tex_name=r'V', info='Bus voltage magnitude', e_str='-Qe', ) self.p0s = ExtService(model='StaticGen', src='p', indexer=self.gen, tex_name='P_{0s}', info='initial P of the static gen', ) self.q0s = ExtService(model='StaticGen', src='q', indexer=self.gen, tex_name='Q_{0s}', info='initial Q of the static gen', ) self.p0 = ConstService(v_str='p0s * gammap', tex_name='P_0', info='initial P of this gen', ) self.q0 = ConstService(v_str='q0s * gammaq', tex_name='Q_0', info='initial Q of this gen', ) self.ra = ExtParam(model='StaticGen', src='ra', indexer=self.gen, tex_name='r_a', export=False, ) self.xs = ExtParam(model='StaticGen', src='xs', indexer=self.gen, tex_name='x_s', export=False, ) # --- INITIALIZATION --- self.q0gt0 = ConstService('Indicator(q0> 0)', tex_name='z_{q0>0}', info='flags for q0 below zero', ) self.q0lt0 = ConstService('Indicator(q0< 0)', tex_name='z_{q0<0}', info='flags for q0 below zero', ) self.Ipcmd0 = ConstService('p0 / v', info='initial Ipcmd', tex_name='I_{pcmd0}', ) self.Iqcmd0 = ConstService('-q0 / v', info='initial Iqcmd', tex_name='I_{qcmd0}', ) self.Ipcmd = Algeb(tex_name='I_{pcmd}', info='current component for active power', e_str='Ipcmd0 - Ipcmd', v_str='Ipcmd0') self.Iqcmd = Algeb(tex_name='I_{qcmd}', info='current component for reactive power', e_str='Iqcmd0 - Iqcmd', v_str='Iqcmd0') # reactive power management # rate limiting logic (for fault recovery, although it does not detect any recovery) # - activate upper limit when q0 > 0 (self.q0gt0) # - activate lower limit when q0 < 0 (self.q0lt0) self.S1 = LagAntiWindupRate(u=self.Iqcmd, T=self.Tg, K=-1, lower=-9999, upper=9999, no_lower=True, no_upper=True, rate_lower=self.Iqrmin, rate_upper=self.Iqrmax, rate_lower_cond=self.q0lt0, rate_upper_cond=self.q0gt0, tex_name='S_1', info='Iqcmd delay', ) # output `S1_y` == `Iq` # piece-wise gain for low voltage active current mgnt. self.kLVG = ConstService(v_str='1 / (Lvpnt1 - Lvpnt0)', tex_name='k_{LVG}', ) self.LVG = Piecewise(u=self.v, points=('Lvpnt0', 'Lvpnt1'), funs=('0', '(v - Lvpnt0) * kLVG', '1'), info='Ip gain during low voltage', tex_name='L_{VG}', ) # piece-wise gain for LVPL self.kLVPL = ConstService(v_str='Lvplsw * Lvpl1 / (Brkpt - Zerox)', tex_name='k_{LVPL}', ) self.S2 = Lag(u=self.v, T=self.Tfltr, K=1.0, info='Voltage filter with no anti-windup', tex_name='S_2', ) self.LVPL = Piecewise(u=self.S2_y, points=('Zerox', 'Brkpt'), funs=('0 + 9999*(1-Lvplsw)', '(S2_y - Zerox) * kLVPL + 9999 * (1-Lvplsw)', '9999'), info='Low voltage Ipcmd upper limit', tex_name='L_{VPL}', ) self.S0 = LagAntiWindupRate(u=self.Ipcmd, T=self.Tg, K=1, upper=self.LVPL_y, rate_upper=self.Rrpwr, lower=-9999, rate_lower=-9999, no_lower=True, rate_no_lower=True, tex_name='S_0', ) # `S0_y` is the output `Ip` in the block diagram self.Ipout = Algeb(e_str='S0_y * LVG_y -Ipout', v_str='Ipcmd * LVG_y', info='Output Ip current', tex_name='I_{pout}', ) # high voltage part self.HVG = GainLimiter(u='v - Volim', K=self.Khv, info='High voltage gain block', lower=0, upper=999, no_upper=True, tex_name='H_{VG}' ) self.HVG.lim.no_warn = True self.Iqout = GainLimiter(u='S1_y- HVG_y', K=1, lower=self.Iolim, upper=9999, no_upper=True, info='Iq output block', tex_name='I^{qout}', ) # `Iqout_y` is the final Iq output self.Pe = Algeb(tex_name='P_e', info='Active power output', v_str='p0', e_str='Ipout * v - Pe') self.Qe = Algeb(tex_name='Q_e', info='Reactive power output', v_str='q0', e_str='Iqout_y * v - Qe')