def __init__(self, u, T1, T2, lower, upper, name=None, info='Lead-lag transfer function'): super().__init__(name=name, info=info) self.T1 = T1 self.T2 = T2 self.u = u self.lower = lower self.upper = upper self.x = State(info='State in lead-lag transfer function', tex_name="x'") self.ynl = Algeb( info='Output of lead-lag transfer function before limiter', tex_name=r'y_{nl}') self.y = Algeb( info='Output of lead-lag transfer function after limiter', tex_name=r'y') self.lim = HardLimiter(u=self.ynl, lower=self.lower, upper=self.upper) self.vars = { 'x': self.x, 'ynl': self.ynl, 'y': self.y, 'lim': self.lim }
def __init__(self, system, config): TGBase.__init__(self, system, config) self.pref = Algeb( info='Reference power input', tex_name='P_{ref}', v_str='tm0 * R', e_str='tm0 * R - pref', ) self.wd = Algeb( info='Generator under speed', unit='p.u.', tex_name=r'\omega_{dev}', v_str='0', e_str='(wref - omega) - wd', ) self.pd = Algeb(info='Pref plus under speed times gain', unit='p.u.', tex_name="P_d", v_str='tm0', e_str='(wd + pref) * gain - pd') self.LAG = LagAntiWindup( u=self.pd, K=1, T=self.T1, lower=self.VMIN, upper=self.VMAX, ) self.LL = LeadLag( u=self.LAG_x, T1=self.T2, T2=self.T3, ) self.pout.e_str = '(LL_y + Dt * wd) - pout'
def __init__(self, system, config): TestFrame.__init__(self, system, config) self.uin = Algeb( v_str=0, e_str='sin(dae_t) - uin', tex_name='u_{in}', ) self.zf = Algeb( v_str=0, e_str='Piecewise((0, dae_t <= 2), (1, dae_t <=6), (0, True)) - zf', tex_name='z_f', ) self.LGF = LagFreeze( u=self.uin, T=1.0, K=1.0, freeze=self.zf, ) self.LGAWF = LagAWFreeze( u=self.uin, T=1.0, K=1.0, lower=-0.5, upper=0.5, freeze=self.zf, )
def __init__(self, system=None, config=None): BusData.__init__(self) Model.__init__(self, system=system, config=config) self.config.add(OrderedDict((('flat_start', 0.0), ))) self.group = 'ACTopology' self.category = ['TransNode'] self.flags.update({'collate': False, 'pflow': True}) self.a = Algeb(name='a', tex_name=r'\theta', info='voltage angle', unit='rad', ) self.v = Algeb(name='v', tex_name='V', info='voltage magnitude', unit='p.u.', ) # initial values self.a.v_str = 'flat_start * 1e-8 + ' \ '(1 - flat_start) * a0' self.v.v_str = 'flat_start * 1 + ' \ '(1 - flat_start) * v0'
def __init__(self, system, config): ExcBase.__init__(self, system, config) self.LG = Lag( u=self.v, T=self.TR, K=1, info='Sensing delay', ) self.vi = Algeb( info='Total input voltages', tex_name='V_i', unit='p.u.', ) self.vi.v_str = 'vf0 / KA' self.vi.e_str = '(vref0 - LG_y) - vi' self.vref0 = PostInitService( info='Const reference voltage', tex_name='V_{ref0}', v_str='v + vf0 / KA', ) self.HLI = HardLimiter( u=self.vi, lower=self.VIMIN, upper=self.VIMAX, info='Hard limiter on input', ) self.LL = LeadLag( u='vi * HLI_zi + VIMIN * HLI_zl + VIMAX * HLI_zu', T1=self.TC, T2=self.TB, info='Lead-lag compensator', zero_out=True, ) self.LR = Lag(u=self.LL_y, T=self.TA, K=self.KA, info='Regulator') # the following uses `XadIfd` for `IIFD` in the PSS/E manual self.vfmax = Algeb( info='Upper bound of output limiter', tex_name='V_{fmax}', v_str='VRMAX - KC * XadIfd', e_str='VRMAX - KC * XadIfd - vfmax', ) self.vfmin = Algeb( info='Lower bound of output limiter', tex_name='V_{fmin}', v_str='VRMIN - KC * XadIfd', e_str='VRMIN - KC * XadIfd - vfmin', ) self.HLR = HardLimiter(u=self.LR_y, lower=self.vfmin, upper=self.vfmax, info='Hard limiter on regulator output') self.vout.e_str = 'ue * (LR_y*HLR_zi + vfmin*HLR_zl + vfmax*HLR_zu) - vout'
def __init__(self, u, T1, T2, lower, upper, name=None, tex_name=None, info=None): super().__init__(name=name, tex_name=tex_name, info=info) self.u = dummify(u) self.T1 = dummify(T1) self.T2 = dummify(T2) self.lower = lower self.upper = upper self.enforce_tex_name((self.T1, self.T2)) self.x = State(info='State in lead-lag TF', tex_name="x'", t_const=self.T2) self.ynl = Algeb(info='Output of lead-lag TF before limiter', tex_name=r'y_{nl}') self.y = Algeb(info='Output of lead-lag TF after limiter', tex_name=r'y', diag_eps=1e-6) self.lim = AntiWindup(u=self.ynl, lower=self.lower, upper=self.upper) self.vars = { 'x': self.x, 'ynl': self.ynl, 'y': self.y, 'lim': self.lim }
def __init__(self, u, K, upper, lower, no_upper=False, no_lower=False, name=None, tex_name=None, info=None): Block.__init__(self, name=name, tex_name=tex_name, info=info) self.u = dummify(u) self.K = dummify(K) self.upper = upper self.lower = lower if (no_upper and no_lower) is True: raise ValueError("no_upper or no_lower cannot both be True") self.no_lower = no_lower self.no_upper = no_upper self.x = Algeb(info='Gain output before limiter', tex_name='x') self.y = Algeb(info='Gain output after limiter', tex_name='y') self.lim = HardLimiter(u=self.x, lower=self.lower, upper=self.upper, no_upper=no_upper, no_lower=no_lower, tex_name='lim') self.vars = {'lim': self.lim, 'x': self.x, 'y': self.y}
def __init__(self, system, config): TG2Data.__init__(self) TGBase.__init__(self, system, config) self.config.add({'deadband': 0, 'hardlimit': 1}) self.config.add_extra("_help", deadband="enable input dead band", hardlimit="enable output hard limit" ) self.config.add_extra("_alt", deadband=(0, 1), hardlimit=(0, 1), ) self.config.add_extra("_tex", deadband="z_{deadband}", hardlimit="z_{hardlimit}", ) self.w_d = Algeb(info='Generator speed deviation before dead band (positive for under speed)', tex_name=r'\omega_{dev}', v_str='0', e_str='u * (wref - omega) - w_d', ) self.w_db = DeadBand(u=self.w_d, center=self.dbc, lower=self.dbl, upper=self.dbu, enable=self.config.deadband, ) self.w_dm = Algeb(info='Measured speed deviation after dead band', tex_name=r'\omega_{dm}', v_str='0', e_str='(1 - w_db_zi) * w_d + ' 'w_db_zlr * dbl + ' 'w_db_zur * dbu - ' 'w_dm') self.w_dmg = Algeb(info='Speed deviation after dead band after gain', tex_name=r'\omega_{dmG}', v_str='0', e_str='gain * w_dm - w_dmg', ) self.ll = LeadLag(u=self.w_dmg, T1=self.T1, T2=self.T2, ) self.pnl = Algeb(info='Power output before hard limiter', tex_name='P_{nl}', v_str='tm0', e_str='tm0 + ll_y - pnl', ) self.plim = HardLimiter(u=self.pnl, lower=self.pmin, upper=self.pmax, enable=self.config.hardlimit, ) self.pout.e_str = 'pnl * plim_zi + pmax * plim_zu + pmin * plim_zl - pout'
def __init__(self, system, config): ExcBase.__init__(self, system, config) self.vref = Algeb(info='Reference voltage input', tex_name='V_{ref}', unit='p.u.', v_str='v + vf0 / KA', e_str='vref0 - vref' ) self.vref0 = PostInitService(info='constant vref', v_str='vref', tex_name='V_{ref0}', ) # input excitation voltages; PSS outputs summed at vi self.vi = Algeb(info='Total input voltages', tex_name='V_i', unit='p.u.', ) self.vi.v_str = 'vf0 / KA' self.vi.e_str = '(vref - LG_y - WF_y) - vi' self.LG = Lag(u=self.v, T=self.TR, K=1, info='Sensing delay', ) self.HLI = HardLimiter(u=self.vi, lower=self.VIMIN, upper=self.VIMAX, info='Hard limiter on input', ) self.vl = Algeb(info='Input after limiter', tex_name='V_l', v_str='HLI_zi*vi + HLI_zu*VIMAX + HLI_zl*VIMIN', e_str='HLI_zi*vi + HLI_zu*VIMAX + HLI_zl*VIMIN - vl', ) self.LL = LeadLag(u=self.vl, T1=self.TC, T2=self.TB, info='Lead-lag compensator', zero_out=True) self.LR = Lag(u=self.LL_y, T=self.TA, K=self.KA, info='Regulator') self.WF = Washout(u=self.LR_y, T=self.TF, K=self.KF, info='Stablizing circuit feedback') # the following uses `XadIfd` for `IIFD` in the PSS/E manual self.vfmax = Algeb(info='Upper bound of output limiter', tex_name='V_{fmax}', v_str='VRMAX - KC * XadIfd', e_str='VRMAX - KC * XadIfd - vfmax', ) self.vfmin = Algeb(info='Lower bound of output limiter', tex_name='V_{fmin}', v_str='VRMIN - KC * XadIfd', e_str='VRMIN - KC * XadIfd - vfmin', ) self.HLR = HardLimiter(u=self.WF_y, lower=self.vfmin, upper=self.vfmax, info='Hard limiter on regulator output') self.vout.e_str = 'LR_y*HLR_zi + vfmin*HLR_zl + vfmax*HLR_zu - vout'
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=None, config=None): super().__init__(system, config) self.group = 'StaticGen' self.flags.update({'pflow': True, 'collate': True}) self.config.add(OrderedDict((('pv2pq', 0), ('npv2pq', 1)))) self.config.add_extra( "_help", pv2pq="convert PV to PQ in PFlow at Q limits", npv2pq="max. # of pv2pq conversion in each iteration", ) self.config.add_extra("_alt", pv2pq=(0, 1), npv2pq=">=0") self.config.add_extra( "_tex", pv2pq="z_{pv2pq}", ) self.a = ExtAlgeb(model='Bus', src='a', indexer=self.bus, tex_name=r'\theta') self.v = ExtAlgeb(model='Bus', src='v', indexer=self.bus, v_setter=True, tex_name=r'V') self.p = Algeb(info='actual active power generation', unit='p.u.', tex_name=r'p', diag_eps=1e-6) self.q = Algeb(info='actual reactive power generation', unit='p.u.', tex_name='q', diag_eps=1e-6) # TODO: implement switching starting from the second iteration self.qlim = SortedLimiter(u=self.q, lower=self.qmin, upper=self.qmax, enable=self.config.pv2pq, n_select=self.config.npv2pq) # variable initialization equations self.v.v_str = 'v0' self.p.v_str = 'p0' self.q.v_str = 'q0' # injections into buses have negative values self.a.e_str = "-u * p" self.v.e_str = "-u * q" # power injection equations g(y) = 0 self.p.e_str = "u * (p0 - p)" self.q.e_str = "u*(qlim_zi * (v0-v) + "\ "qlim_zl * (qmin-q) + "\ "qlim_zu * (qmax-q))"
def __init__(self, system, config): super(IEEESTModel, self).__init__(system, config) self.KST5 = ConstService(v_str='KS * T5', tex_name='KS*T5') self.SW = Switcher( u=self.MODE, options=[1, 2, 3, 4, 5, 6], ) self.signal = Algeb( tex_name='S_{in}', info='Input signal', ) # input signals: # 1 (s0) - Rotor speed deviation (p.u.) # 2 (s1) - Bus frequency deviation (p.u.) # TODO: calculate freq without reimpl. # 3 (s2) - Generator electrical power in Gen MVABase (p.u.) # TODO: allow using system.config.mva # 4 (s3) - Generator accelerating power (p.u.) # 5 (s4) - Bus voltage (p.u.) # 6 (s5) - Derivative of p.u. bus voltage # TODO: memory block for calc. of derivative self.signal.e_str = 'SW_s0 * (1-omega) + SW_s1 * 0 + SW_s2 * te + ' \ 'SW_s3 * (tm-tm0) + SW_s4 *v + SW_s5 * 0 - signal' self.F1 = Lag2ndOrd(u=self.signal, K=1, T1=self.A1, T2=self.A2) self.F2 = LeadLag2ndOrd(u=self.F1_y, T1=self.A3, T2=self.A4, T3=self.A5, T4=self.A6) self.LL1 = LeadLag(u=self.F2_y, T1=self.T1, T2=self.T2) self.LL2 = LeadLag(u=self.LL1_y, T1=self.T3, T2=self.T4) self.WO = Washout(u=self.LL2_y, T=self.T6, K=self.KST5) # WO_y == Vss self.VLIM = Limiter(u=self.WO_y, lower=self.LSMIN, upper=self.LSMAX, info='Vss limiter') self.Vss = Algeb( tex_name='V_{ss}', info='Voltage output before output limiter', e_str='VLIM_zi * WO_y + VLIM_zu * LSMAX + VLIM_zl * LSMIN - Vss') self.OLIM = Limiter(u=self.v, lower=self.VCL, upper=self.VCU, info='output limiter') # TODO: allow ignoring VCU or VCL when zero self.vsout.e_str = 'OLIM_zi * Vss - vsout'
def __init__(self): self.psid = Algeb(tex_name=r'\psi_d', v_str='psid0', e_str='u * (ra * Iq + vq) - omega * psid', ) self.psiq = Algeb(tex_name=r'\psi_q', v_str='psiq0', e_str='u * (ra * Id + vd) + omega * psiq', ) self.Id.e_str += '+ psid' self.Iq.e_str += '+ psiq'
def __init__(self, system=None, config=None): BusData.__init__(self) Model.__init__(self, system=system, config=config) # island information self.n_islanded_buses = 0 self.island_sets = list() self.islanded_buses = list( ) # list of lists containing bus uid of islands self.islands = list() # same as the above self.islanded_a = np.array([]) self.islanded_v = np.array([]) # config self.config.add(OrderedDict((('flat_start', 0), ))) self.config.add_extra( "_help", flat_start="flat start for voltages", ) self.config.add_extra( "_alt", flat_start=(0, 1), ) self.config.add_extra( "_tex", flat_start="z_{flat}", ) self.group = 'ACTopology' self.category = ['TransNode'] self.flags.update({'collate': False, 'pflow': True}) self.a = Algeb( name='a', tex_name=r'\theta', info='voltage angle', unit='rad', is_output=True, ) self.v = Algeb( name='v', tex_name='V', info='voltage magnitude', unit='p.u.', is_output=True, ) # initial values self.a.v_str = 'flat_start*1e-8 + ' \ '(1-flat_start)*a0' self.v.v_str = 'flat_start*1 + ' \ '(1-flat_start)*v0'
def __init__(self): self.psid = Algeb(info='d-axis flux', tex_name=r'\psi_d', v_str='psid0', e_str='u * (ra*Iq + vq) - psid', ) self.psiq = Algeb(info='q-axis flux', tex_name=r'\psi_q', v_str='psiq0', e_str='u * (ra*Id + vd) + psiq', ) self.Id.e_str += '+ psid' self.Iq.e_str += '+ psiq'
def __init__(self, system, config): TestFrame.__init__(self, system, config) self.Text = NumParam(default=1.0, info='Extended event time', unit='s') self.uin = Algeb( v_str=0, e_str='sin(dae_t) - uin', tex_name='u_{in}', ) self.zf = Algeb( v_str=0, e_str= 'Piecewise((0, dae_t <= 2), (1, dae_t <=6), (0, dae_t<=12), (1, dae_t<=15), ' '(0, True)) - zf', tex_name='z_f', ) self.PI = PIController(u=self.uin, kp=1, ki=0.1) self.PIF = PIFreeze(u=self.uin, kp=0.5, ki=0.5, x0=0, freeze=self.zf) self.PIAW = PITrackAW( u=self.uin, kp=0.5, ki=0.5, ks=2, lower=-0.5, upper=0.5, x0=0.0, ) self.PIAWF = PITrackAWFreeze(u=self.uin, kp=0.5, ki=0.5, ks=2, x0=0, freeze=self.zf, lower=-0.5, upper=0.5) self.ExtEvent = ExtendedEvent(u=self.zf, t_ext=self.Text, trig='rise', extend_only=True) self.ze = Algeb(v_str='ExtEvent', e_str='ExtEvent - ze')
def __init__(self, system, config): TGBase.__init__(self, system, config) self.pref = Algeb( info='Reference power input', tex_name='P_{ref}', v_str='tm0 * R', e_str='tm0 * R - pref', ) self.wd = Algeb( info='Generator under speed', unit='p.u.', tex_name=r'\omega_{dev}', v_str='0', e_str='u * (wref - omega) - wd', ) self.pd = Algeb(info='Pref plus under speed times gain', unit='p.u.', tex_name="P_d", v_str='tm0', e_str='(wd + pref) * gain - pd') self.LAG_y = State( info='State in lag transfer function', tex_name=r"x'_{LAG}", e_str='LAG_lim_zi * (1 * pd - LAG_y)', t_const=self.T1, v_str='pd', ) self.LAG_lim = AntiWindup( u=self.LAG_y, lower=self.VMIN, upper=self.VMAX, tex_name='lim_{lag}', ) self.LL_x = State(info='State in lead-lag transfer function', tex_name="x'_{LL}", v_str='LAG_y', e_str='(LAG_y - LL_x)', t_const=self.T3) self.LL_y = Algeb( info='Lead-lag Output', tex_name='y_{LL}', v_str='LAG_y', e_str='T2 / T3 * (LAG_y - LL_x) + LL_x - LL_y', ) self.pout.e_str = '(LL_y + Dt * wd) - pout'
def __init__(self, system, config): NodeData.__init__(self) Model.__init__(self, system=system, config=config) self.config.add(OrderedDict((('flat_start', 0), ))) self.config.add_extra( "_help", flat_start="flat start for voltages", ) self.config.add_extra( "_alt", flat_start=(0, 1), ) self.config.add_extra( "_tex", flat_start="z_{flat}", ) self.group = 'DCTopology' self.category = ['TransNode'] self.flags.update({'pflow': True}) self.v = Algeb( name='v', tex_name='V_{dc}', info='voltage magnitude', unit='p.u.', diag_eps=1e-6, ) self.v.v_str = 'flat_start*1 + ' \ '(1-flat_start)*v0'
def __init__(self, system, config): DC2Term.__init__(self, system, config) self.flags['pflow'] = True self.group = 'DCLink' self.C = NumParam( unit='p.u.', info='DC capacitance', non_zero=True, default=0.001, g=True, ) self.vC = State( tex_name='v_C', info='Capacitor current', unit='p.u.', v_str='0', e_str='-u * Idc / C', ) self.Idc = Algeb( tex_name='I_{dc}', info='Current from node 2 to 1', unit='p.u.', v_str='0', e_str='u * (vC - (v1 - v2)) + ' '(1 - u) * Idc', diag_eps=1e-6, ) self.v1.e_str = '-Idc' self.v2.e_str = '+Idc'
def __init__(self, system, config): DC2Term.__init__(self, system, config) self.flags['pflow'] = True self.group = 'DCLink' self.R = NumParam( unit='p.u.', info='DC line resistance', non_zero=True, default=0.01, r=True, ) self.L = NumParam( unit='p.u.', info='DC line inductance', non_zero=True, default=0.001, r=True, ) self.IL = State( tex_name='I_L', info='Inductance current', unit='p.u.', e_str='u * (v1 - v2 - R * IL) / L', v_str='(v1 - v2) / R', ) self.Idc = Algeb( tex_name='I_{dc}', info='Current from node 2 to 1', unit='p.u.', e_str='-u * IL - Idc', v_str='-u * (v1 - v2) / R', ) self.v1.e_str = '-Idc' self.v2.e_str = '+Idc'
def __init__(self, u, T1, T2, T3, T4, name=None, tex_name=None, info='2nd-order lead-lag'): super(LeadLag2ndOrd, self).__init__(name=name, tex_name=tex_name, info=info) self.u = u self.T1 = dummify(T1) self.T2 = dummify(T2) self.T3 = dummify(T3) self.T4 = dummify(T4) self.enforce_tex_name((self.T1, self.T2, self.T3, self.T4)) self.x1 = State(info='State #1 in 2nd order lead-lag', tex_name="x'", t_const=self.T2) self.x2 = State(info='State #2 in 2nd order lead-lag', tex_name="x''") self.y = Algeb(info='Output of 2nd order lead-lag', tex_name='y', diag_eps=1e-6) self.vars = {'x1': self.x1, 'x2': self.x2, 'y': self.y}
def __init__(self, system, config): ModelData.__init__(self) self.node = IdxParam( default=None, tex_name='node', info='Node index', mandatory=True, model='Node', ) self.voltage = NumParam( default=0.0, tex_name='V_0', info='Ground voltage (typically 0)', unit='p.u.', ) Model.__init__(self, system, config) self.flags.update({'pflow': True}) self.group = 'DCLink' self.v = ExtAlgeb( model='Node', src='v', indexer=self.node, e_str='-Idc', ) self.Idc = Algeb( tex_name='I_{dc}', info='Ficticious current injection from ground', e_str='u * (v - voltage)', v_str='0', diag_eps=1e-6, ) self.v.e_str = '-Idc'
def __init__(self, u, T1, T2, T3, T4, zero_out=False, name=None, tex_name=None, info=None): super(LeadLag2ndOrd, self).__init__(name=name, tex_name=tex_name, info=info) self.u = dummify(u) self.T1 = dummify(T1) self.T2 = dummify(T2) self.T3 = dummify(T3) self.T4 = dummify(T4) self.zero_out = zero_out self.enforce_tex_name((self.T1, self.T2, self.T3, self.T4)) self.x1 = State(info='State #1 in 2nd order lead-lag', tex_name="x'", t_const=self.T2) self.x2 = State(info='State #2 in 2nd order lead-lag', tex_name="x''") self.y = Algeb(info='Output of 2nd order lead-lag', tex_name='y', diag_eps=1e-6) self.vars = {'x1': self.x1, 'x2': self.x2, 'y': self.y} if self.zero_out is True: self.LT1 = LessThan(T1, dummify(0), equal=True, enable=zero_out, tex_name='LT', cache=True, z0=1, z1=0) self.LT2 = LessThan(T2, dummify(0), equal=True, enable=zero_out, tex_name='LT', cache=True, z0=1, z1=0) self.LT3 = LessThan(T4, dummify(0), equal=True, enable=zero_out, tex_name='LT', cache=True, z0=1, z1=0) self.LT4 = LessThan(T4, dummify(0), equal=True, enable=zero_out, tex_name='LT', cache=True, z0=1, z1=0) self.x2.discrete = (self.LT1, self.LT2, self.LT3, self.LT4) self.vars['LT1'] = self.LT1 self.vars['LT2'] = self.LT2 self.vars['LT3'] = self.LT3 self.vars['LT4'] = self.LT4
def __init__(self, system, config): ACEData.__init__(self) Model.__init__(self, system, config) self.flags.tds = True self.config.add(OrderedDict([('freq_model', 'BusFreq')])) self.config.add_extra( '_help', {'freq_model': 'default freq. measurement model'}) self.config.add_extra('_alt', {'freq_model': ('BusFreq', )}) self.area = ExtParam(model='Bus', src='area', indexer=self.bus, export=False) self.busf.model = self.config.freq_model self.busfreq = DeviceFinder(self.busf, link=self.bus, idx_name='bus') self.f = ExtAlgeb( model='FreqMeasurement', src='f', indexer=self.busfreq, export=False, info='Bus frequency', ) self.ace = Algeb( info='area control error', unit='MW (p.u.)', tex_name='ace', e_str='10 * bias * (f - 1) - ace', )
def setUp(self) -> None: self.n = 5 self.u1 = DummyValue(0) self.u1.v = np.zeros(self.n) self.u2 = Algeb(tex_name='u2') self.u2.v = np.array([-2, -1, 0, 1, 2])
def __init__(self, system, config): PVD1Model.__init__(self, system, config) # --- Determine whether the energy storage is in charging or discharging mode --- self.LTN = LessThan(self.Ipout_y, 0.0) # --- Add integrator. Assume that state-of-charge is the initial condition --- self.pIG = Integrator( u='-LTN_z1*(v * Ipout_y)*EtaC - LTN_z0*(v * Ipout_y)/EtaD', T=self.Tf, K='sys_mva / 3600 / En', y0=self.SOCinit, check_init=False, ) # --- Add hard limiter for SOC --- self.SOClim = HardLimiter(u=self.pIG_y, lower=self.SOCmin, upper=self.SOCmax) # --- Add Ipmax, Ipmin, and Ipcmd --- self.Ipmax.v_str = '(1-SOClim_zl)*(SWPQ_s1 * ialim + SWPQ_s0 * sqrt(Ipmaxsq0))' self.Ipmax.e_str = '(1-SOClim_zl)*(SWPQ_s1 * ialim + SWPQ_s0 * sqrt(Ipmaxsq)) - Ipmax' self.Ipmin = Algeb( info='Minimum value of Ip', v_str= '-(1-SOClim_zu) * (SWPQ_s1 * ialim + SWPQ_s0 * sqrt(Ipmaxsq0))', e_str= '-(1-SOClim_zu) * (SWPQ_s1 * ialim + SWPQ_s0 * sqrt(Ipmaxsq)) - Ipmin', ) self.Ipcmd.lim.lower = self.Ipmin self.Ipcmd.y.deps = ['Ipmin']
def __init__(self, system, config): TestFrame.__init__(self, system, config) self.uin = Algeb(v_str='-10', e_str='(dae_t - 10) - uin', tex_name='u_{in}') self.DB = DeadBand1(self.uin, center=0, lower=-5, upper=5)
def __init__(self, u, points: list, funs: list, name=None, tex_name=None, info=None): super().__init__(name=name, tex_name=tex_name, info=info) self.u = u self.points = points self.funs = funs self.y = Algeb(info='Output of piecewise function', tex_name='y') self.vars = {'y': self.y}
def __init__(self, u, K, name=None, tex_name=None, info=None): super().__init__(name=name, tex_name=tex_name, info=info) self.u = dummify(u) self.K = dummify(K) self.enforce_tex_name((self.K,)) self.y = Algeb(info='Gain output', tex_name='y') self.vars = {'y': self.y}
def setUp(self): self.lower = NumParam() self.upper = NumParam() self.u = Algeb() self.upper.v = np.array([2, 2, 2, 2, 2, 2, 2.8, 3.9]) self.u.v = np.array([-3, -1.1, -5, 0, 1, 2, 3, 10]) self.lower.v = np.array([-2, -1, 0.5, 0, 0.5, 1.5, 2, 3])