pydynamicestimator.devices.avr ============================== .. py:module:: pydynamicestimator.devices.avr Attributes ---------- .. autoapisummary:: pydynamicestimator.devices.avr.AVR_REGISTRY Classes ------- .. autoapisummary:: pydynamicestimator.devices.avr.AVR pydynamicestimator.devices.avr.IEEEDC1A pydynamicestimator.devices.avr.AVRKundur_Filter pydynamicestimator.devices.avr.AVRKundur pydynamicestimator.devices.avr.AVRKundur_NoTGR pydynamicestimator.devices.avr.AVRKundur_ODE pydynamicestimator.devices.avr.SEXST Module Contents --------------- .. py:class:: AVR Bases: :py:obj:`abc.ABC` Abstract base class for Automatic Voltage Regulator models. Every AVR must expose 'Efd' -- the field-voltage coupling variable consumed by the electromagnetic equations of the synchronous machine. 'Efd' may be declared either as a differential ``state`` (when the exciter is a pure lag, e.g. IEEEDC1A) or as a device-private ``algeb`` (when the exciter has a direct-feedthrough block such as a lead-lag, so its output is algebraic; see AVRKundur). The host resolves 'Efd' wherever it lives via ``Synchronous.var_sym`` -- the machine equations are agnostic to the choice. The AVR does NOT own state arrays or DAE indices. It declares what states, private algebraics, parameters, noise values, etc. it needs, and the host Synchronous machine registers them on itself. .. py:method:: states() -> List[str] :abstractmethod: Return ordered list of differential-state names. .. py:method:: algebs() -> List[str] Return ordered list of device-private *algebraic* variable names. Default empty: most AVRs are pure-lag exciters whose output 'Efd' is a state. An exciter with a direct-feedthrough (lead-lag) block returns ['Efd'] here instead of listing it in :meth:`states`, and writes its defining residual ``0 = -Efd + `` into ``dae.g`` in :meth:`fgcall`. These ride the device-private-algebraic mechanism (``_algebs_int``). .. py:method:: algebs_units() -> Dict[str, str] Units for each private algebraic (mirrors :meth:`units`). .. py:method:: algebs_noise() -> Dict[str, float] Relative process-noise weight for each private algebraic. .. py:method:: algebs_x0() -> Dict[str, float] Initial guess for each private algebraic (Newton guess in finit). .. py:method:: units() -> List[str] :abstractmethod: Return units for each state, same length as states(). .. py:method:: params() -> Dict[str, float] :abstractmethod: Return dict of parameter names -> default values. .. py:method:: states_noise() -> Dict[str, float] :abstractmethod: Return noise specification for each state. .. py:method:: states_init_error() -> Dict[str, float] :abstractmethod: Return initial error for each state. .. py:method:: x0() -> Dict[str, float] :abstractmethod: Return default initial guess for each state. .. py:method:: descriptions() -> Dict[str, str] :abstractmethod: Return descriptions for states and params. .. py:method:: setpoints() -> Dict[str, float] :abstractmethod: Return setpoint names -> defaults (e.g., Vf_ref). .. py:method:: fgcall(host, dae: pydynamicestimator.system.Dae) -> None :abstractmethod: Write the AVR's differential equations into ``dae.f`` and, if the AVR declares private algebraics, their defining residuals into ``dae.g``. :param host: The Synchronous machine instance. Access state/algebraic indices via host.Efd, host.Rf, etc. and parameters via host.KA, etc. :param dae: The DAE system object. .. py:class:: IEEEDC1A Bases: :py:obj:`AVR` IEEEDC1A exciter and AVR model as presented in Power System Dynamics and Stability by P.W. Sauer and M.A. Pai, 2006. (page 100) States: Efd, Rf, Vr (3 states) .. py:method:: states() -> List[str] Return ordered list of differential-state names. .. py:method:: units() -> List[str] Return units for each state, same length as states(). .. py:method:: params() -> Dict[str, float] Return dict of parameter names -> default values. .. py:method:: states_noise() -> Dict[str, float] Return noise specification for each state. .. py:method:: states_init_error() -> Dict[str, float] Return initial error for each state. .. py:method:: x0() -> Dict[str, float] Return default initial guess for each state. .. py:method:: descriptions() -> Dict[str, str] Return descriptions for states and params. .. py:method:: setpoints() -> Dict[str, float] Return setpoint names -> defaults (e.g., Vf_ref). .. py:method:: fgcall(host, dae: pydynamicestimator.system.Dae) -> None Write the AVR's differential equations into ``dae.f`` and, if the AVR declares private algebraics, their defining residuals into ``dae.g``. :param host: The Synchronous machine instance. Access state/algebraic indices via host.Efd, host.Rf, etc. and parameters via host.KA, etc. :param dae: The DAE system object. .. py:class:: AVRKundur_Filter Bases: :py:obj:`AVR` AVR model used in Kundur's book (Power System Stability and Control, 1994) for the 2-area system. A filter is added to the AVR output to prevent unrealistic fast dynamics and improve numerical stability. .. py:method:: states() -> List[str] Return ordered list of differential-state names. .. py:method:: units() -> List[str] Return units for each state, same length as states(). .. py:method:: params() -> Dict[str, float] Return dict of parameter names -> default values. .. py:method:: states_noise() -> Dict[str, float] Return noise specification for each state. .. py:method:: states_init_error() -> Dict[str, float] Return initial error for each state. .. py:method:: x0() -> Dict[str, float] Return default initial guess for each state. .. py:method:: descriptions() -> Dict[str, str] Return descriptions for states and params. .. py:method:: setpoints() -> Dict[str, float] Return setpoint names -> defaults (e.g., Vf_ref). .. py:method:: fgcall(host, dae: pydynamicestimator.system.Dae) -> None Write the AVR's differential equations into ``dae.f`` and, if the AVR declares private algebraics, their defining residuals into ``dae.g``. :param host: The Synchronous machine instance. Access state/algebraic indices via host.Efd, host.Rf, etc. and parameters via host.KA, etc. :param dae: The DAE system object. .. py:class:: AVRKundur Bases: :py:obj:`AVR` Kundur 2-area AVR as a transducer + lead-lag, with the field voltage 'Efd' declared as a device-private ALGEBRAIC variable. This is :class:`AVRKundur_Filter` with the parasitic output filter removed. The filter (pole ``1/(1 + s*Tfd)``) existed only to fake the lead-lag output into a differential state; physically the lead-lag Efd = KA * (1 + s*TA) / (1 + s*TB) * (Vf_ref - Vtr) is proper-but-not-strictly-proper, so its output has a *direct feedthrough* and is genuinely algebraic. The faithful realization is one lag pole state ``Vl`` plus the algebraic output: Vtr_dot = (1/TR) (-Vtr + |V|) # transducer Vl_dot = (1/TB) (-Vl + KA (Vf_ref - Vtr)) # lag pole state 0 = -Efd + Vl (1 - TA/TB) + (TA/TB) KA (Vf_ref - Vtr) # Efd algebraic The third line is the lead feedthrough ``D = TA/TB``; one verifies ``Vl(1-TA/TB) + (TA/TB)KA(Vf_ref-Vtr) = KA(1+sTA)/(1+sTB)(Vf_ref-Vtr)``. 'Efd' is therefore exposed via :meth:`algebs` (not :meth:`states`) and rides the device-private-algebraic mechanism; the host reads it through ``Synchronous.var_sym('Efd')``. As ``Tfd -> 0`` the filtered model converges to this one (singular-perturbation limit) -- the controller-side counterpart of the SP6-DAE machine demonstration. See docs/algebraic_equations_design.md. .. py:method:: states() -> List[str] Return ordered list of differential-state names. .. py:method:: units() -> List[str] Return units for each state, same length as states(). .. py:method:: algebs() -> List[str] Return ordered list of device-private *algebraic* variable names. Default empty: most AVRs are pure-lag exciters whose output 'Efd' is a state. An exciter with a direct-feedthrough (lead-lag) block returns ['Efd'] here instead of listing it in :meth:`states`, and writes its defining residual ``0 = -Efd + `` into ``dae.g`` in :meth:`fgcall`. These ride the device-private-algebraic mechanism (``_algebs_int``). .. py:method:: algebs_units() -> Dict[str, str] Units for each private algebraic (mirrors :meth:`units`). .. py:method:: algebs_noise() -> Dict[str, float] Relative process-noise weight for each private algebraic. .. py:method:: algebs_x0() -> Dict[str, float] Initial guess for each private algebraic (Newton guess in finit). .. py:method:: params() -> Dict[str, float] Return dict of parameter names -> default values. .. py:method:: states_noise() -> Dict[str, float] Return noise specification for each state. .. py:method:: states_init_error() -> Dict[str, float] Return initial error for each state. .. py:method:: x0() -> Dict[str, float] Return default initial guess for each state. .. py:method:: descriptions() -> Dict[str, str] Return descriptions for states and params. .. py:method:: setpoints() -> Dict[str, float] Return setpoint names -> defaults (e.g., Vf_ref). .. py:method:: fgcall(host, dae: pydynamicestimator.system.Dae) -> None Write the AVR's differential equations into ``dae.f`` and, if the AVR declares private algebraics, their defining residuals into ``dae.g``. :param host: The Synchronous machine instance. Access state/algebraic indices via host.Efd, host.Rf, etc. and parameters via host.KA, etc. :param dae: The DAE system object. .. py:class:: AVRKundur_NoTGR Bases: :py:obj:`AVR` AVRKundur with the transient gain reduction (the lead-lag ``(1+sTA)/(1+sTB)``) removed: a plain high-gain static exciter with only a terminal-voltage transducer. Efd = KA * (Vf_ref - Vtr), Vtr = Vt / (1 + s*TR) States: ``Vtr`` (transducer). ``Efd`` is the algebraic output ``KA*(Vf_ref - Vtr)`` -- an instantaneous gain on the transduced error, so it is declared as a private algebraic (read by the machine via ``Synchronous.var_sym('Efd')``). Parameters: ``KA``, ``TR``. With a high ``KA`` and no TGR this exciter typically *reduces* the damping of the electromechanical modes (it can push them toward / into the RHP), which is the classic setting in which a power system stabilizer (PSS) is needed to restore damping. The PSS signal enters at the summing junction via ``host.pss_signal(dae)`` (0 when no PSS is attached). .. py:method:: states() -> List[str] Return ordered list of differential-state names. .. py:method:: units() -> List[str] Return units for each state, same length as states(). .. py:method:: algebs() -> List[str] Return ordered list of device-private *algebraic* variable names. Default empty: most AVRs are pure-lag exciters whose output 'Efd' is a state. An exciter with a direct-feedthrough (lead-lag) block returns ['Efd'] here instead of listing it in :meth:`states`, and writes its defining residual ``0 = -Efd + `` into ``dae.g`` in :meth:`fgcall`. These ride the device-private-algebraic mechanism (``_algebs_int``). .. py:method:: algebs_units() -> Dict[str, str] Units for each private algebraic (mirrors :meth:`units`). .. py:method:: algebs_noise() -> Dict[str, float] Relative process-noise weight for each private algebraic. .. py:method:: algebs_x0() -> Dict[str, float] Initial guess for each private algebraic (Newton guess in finit). .. py:method:: params() -> Dict[str, float] Return dict of parameter names -> default values. .. py:method:: states_noise() -> Dict[str, float] Return noise specification for each state. .. py:method:: states_init_error() -> Dict[str, float] Return initial error for each state. .. py:method:: x0() -> Dict[str, float] Return default initial guess for each state. .. py:method:: descriptions() -> Dict[str, str] Return descriptions for states and params. .. py:method:: setpoints() -> Dict[str, float] Return setpoint names -> defaults (e.g., Vf_ref). .. py:method:: fgcall(host, dae: pydynamicestimator.system.Dae) -> None Write the AVR's differential equations into ``dae.f`` and, if the AVR declares private algebraics, their defining residuals into ``dae.g``. :param host: The Synchronous machine instance. Access state/algebraic indices via host.Efd, host.Rf, etc. and parameters via host.KA, etc. :param dae: The DAE system object. .. py:class:: AVRKundur_ODE Bases: :py:obj:`AVR` AVR model used in Kundur's book (Power System Stability and Control, 1994) for the 2-area system example with transient gain reduction. This is the all-ODE realization of the same transducer + lead-lag controller as :class:`AVRKundur`: it carries the same loop transfer function ``KA (1+sTA)/(1+sTB)`` on the error ``e = Vf_ref - Vtr`` and the same DC gain ``KA``, but realizes the lead as a derivative of the *measurement* (states ``Efd, Vtr``; ``Efd`` is a differential state via the ``TB`` lag, so no parasitic filter is needed). The only difference from :class:`AVRKundur` is the omitted setpoint-derivative term ``KA*TA*dVf_ref/dt`` -- identically zero for a constant ``Vf_ref`` (always, here), so the two produce the same ``Efd``. :class:`AVRKundur` instead keeps ``Efd`` as an algebraic variable (the lead's direct feedthrough); :class:`AVRKundur_Filter` is :class:`AVRKundur` plus a parasitic output pole ``1/(1+sTfd)`` that turns ``Efd`` back into a state. .. py:method:: states() -> List[str] Return ordered list of differential-state names. .. py:method:: units() -> List[str] Return units for each state, same length as states(). .. py:method:: params() -> Dict[str, float] Return dict of parameter names -> default values. .. py:method:: states_noise() -> Dict[str, float] Return noise specification for each state. .. py:method:: states_init_error() -> Dict[str, float] Return initial error for each state. .. py:method:: x0() -> Dict[str, float] Return default initial guess for each state. .. py:method:: descriptions() -> Dict[str, str] Return descriptions for states and params. .. py:method:: setpoints() -> Dict[str, float] Return setpoint names -> defaults (e.g., Vf_ref). .. py:method:: fgcall(host, dae: pydynamicestimator.system.Dae) -> None Write the AVR's differential equations into ``dae.f`` and, if the AVR declares private algebraics, their defining residuals into ``dae.g``. :param host: The Synchronous machine instance. Access state/algebraic indices via host.Efd, host.Rf, etc. and parameters via host.KA, etc. :param dae: The DAE system object. .. py:class:: SEXST Bases: :py:obj:`AVR` AVR model used in Kundur's book (Power System Stability and Control, 1994) for the 2-area system example with transient gain reduction. .. py:method:: states() -> List[str] Return ordered list of differential-state names. .. py:method:: units() -> List[str] Return units for each state, same length as states(). .. py:method:: params() -> Dict[str, float] Return dict of parameter names -> default values. .. py:method:: states_noise() -> Dict[str, float] Return noise specification for each state. .. py:method:: states_init_error() -> Dict[str, float] Return initial error for each state. .. py:method:: x0() -> Dict[str, float] Return default initial guess for each state. .. py:method:: descriptions() -> Dict[str, str] Return descriptions for states and params. .. py:method:: setpoints() -> Dict[str, float] Return setpoint names -> defaults (e.g., Vf_ref). .. py:method:: fgcall(host, dae: pydynamicestimator.system.Dae) -> None Write the AVR's differential equations into ``dae.f`` and, if the AVR declares private algebraics, their defining residuals into ``dae.g``. :param host: The Synchronous machine instance. Access state/algebraic indices via host.Efd, host.Rf, etc. and parameters via host.KA, etc. :param dae: The DAE system object. .. py:data:: AVR_REGISTRY :type: Dict[str, type]