pydynamicestimator.devices.shaft

Attributes

SHAFT_REGISTRY

Classes

Shaft

Abstract base class for the rotor-shaft mechanics (pluggable strategy).

SingleMass

Single rigid rotor mass -- the classic swing equation. Framework default.

MultiMassShaft

Generic multi-mass (torsional) turbine-generator shaft: a linear chain of

Shaft4Mass

Four-mass turbine-generator shaft: HP -- IP -- LP -- GEN (linear chain).

Shaft5Mass

Five-mass turbine-generator shaft: HP -- IP -- LP -- GEN -- EXC (linear chain).

Module Contents

class pydynamicestimator.devices.shaft.Shaft[source]

Bases: abc.ABC

Abstract base class for the rotor-shaft mechanics (pluggable strategy).

The shaft owns the rotor angle/speed states and writes the swing (rotor motion) equations. Every shaft must expose the generator mass as the two differential states delta (rotor angle wrt the synchronous frame) and omega (the ABSOLUTE per-unit speed, = 1.0 at synchronism, NOT the deviation). Those are the names the electromagnetic model, the network current injection (gcall), the governor, the PSS and the initialisation all read, so a multi-mass (torsional) shaft adds further rotor masses (delta_<name> / omega_<name>) while keeping the generator mass on the canonical names – nothing downstream changes.

Coupling ports the shaft consumes:

  • pm – the governor’s mechanical-power output, read via host.var_sym(dae, "pm") and distributed across the turbine masses;

  • Pe – the electromagnetic air-gap power, passed into fgcall() and applied to the generator mass only.

It reads the per-machine reference-frame frequency via host._omega_ref(dae) (= 1 p.u. by default, or the estimated per-bus reference when present).

Symmetric to AVR, Governor and PSS: the shaft does NOT own state arrays or DAE indices. It declares what states / parameters / noise values it needs and the host Synchronous machine registers them on itself.

Rotor angles and speeds are inherently differential states, so – unlike the AVR/governor/PSS – a shaft declares no private algebraic variables.

abstract states() List[str][source]

Return ordered differential-state names. MUST contain ‘delta’ and ‘omega’ (the generator mass).

Return type:

List[str]

abstract units() List[str][source]

Return units for each state, same length as states().

Return type:

List[str]

abstract params() Dict[str, float][source]

Return dict of parameter names -> default values (empty for the single-mass shaft, which reuses the machine’s own H, D, f).

Return type:

Dict[str, float]

abstract states_noise() Dict[str, float][source]

Return process-noise specification for each state.

Return type:

Dict[str, float]

abstract states_init_error() Dict[str, float][source]

Return initial error for each state.

Return type:

Dict[str, float]

abstract x0() Dict[str, float][source]

Return default initial guess for each state.

Return type:

Dict[str, float]

abstract descriptions() Dict[str, str][source]

Return descriptions for states and params.

Return type:

Dict[str, str]

setpoints() Dict[str, float][source]

Return setpoint names -> defaults. The shaft mechanics have none.

Return type:

Dict[str, float]

abstract fgcall(host, dae: pydynamicestimator.system.Dae, Pe) None[source]

Write the rotor-motion (swing) differential equations into dae.f.

Parameters:
  • host – The Synchronous machine instance. Access state indices via host.delta, host.omega (generator mass) and, for a multi-mass shaft, host.delta_<name>/host.omega_<name>; inertia/damping via host.H, host.D, host.f (generator mass) and host.H_<name>, …; the governor port via host.var_sym(dae, “pm”) and the reference frequency via host._omega_ref(dae).

  • dae (pydynamicestimator.system.Dae) – The DAE system object.

  • Pe – The electromagnetic air-gap power (CasADi SX, one entry per machine), applied to the generator mass.

Return type:

None

class pydynamicestimator.devices.shaft.SingleMass[source]

Bases: Shaft

Single rigid rotor mass – the classic swing equation. Framework default.

\[\begin{split}\dot{\delta} &= 2 \pi f_n (\omega - \omega_{\text{ref}}) \\ \dot{\omega} &= \frac{1}{2H} \big( P_m - P_e - D (\omega - \omega_{\text{ref}}) - f\,\omega \big)\end{split}\]

Reuses the machine’s own inertia/damping parameters (host.H, host.D, host.f), so it declares no parameters of its own. This is byte-identical to the rotor dynamics previously hardcoded in Synchronous.rotor (the positional baselines in tests/ gate that equivalence).

states() List[str][source]

Return ordered differential-state names. MUST contain ‘delta’ and ‘omega’ (the generator mass).

Return type:

List[str]

units() List[str][source]

Return units for each state, same length as states().

Return type:

List[str]

params() Dict[str, float][source]

Return dict of parameter names -> default values (empty for the single-mass shaft, which reuses the machine’s own H, D, f).

Return type:

Dict[str, float]

states_noise() Dict[str, float][source]

Return process-noise specification for each state.

Return type:

Dict[str, float]

states_init_error() Dict[str, float][source]

Return initial error for each state.

Return type:

Dict[str, float]

x0() Dict[str, float][source]

Return default initial guess for each state.

Return type:

Dict[str, float]

descriptions() Dict[str, str][source]

Return descriptions for states and params.

Return type:

Dict[str, str]

fgcall(host, dae: pydynamicestimator.system.Dae, Pe) None[source]

Write the rotor-motion (swing) differential equations into dae.f.

Parameters:
  • host – The Synchronous machine instance. Access state indices via host.delta, host.omega (generator mass) and, for a multi-mass shaft, host.delta_<name>/host.omega_<name>; inertia/damping via host.H, host.D, host.f (generator mass) and host.H_<name>, …; the governor port via host.var_sym(dae, “pm”) and the reference frequency via host._omega_ref(dae).

  • dae (pydynamicestimator.system.Dae) – The DAE system object.

  • Pe – The electromagnetic air-gap power (CasADi SX, one entry per machine), applied to the generator mass.

Return type:

None

class pydynamicestimator.devices.shaft.MultiMassShaft[source]

Bases: Shaft

Generic multi-mass (torsional) turbine-generator shaft: a linear chain of lumped rotor masses connected by elastic shaft sections.

Each mass \(i\) carries an angle \(\delta_i\) and an absolute p.u. speed \(\omega_i\). With omega_b \(= 2\pi f_n\) and the reference speed \(\omega_{\text{ref}}\) (= 1 p.u.):

\[\begin{split}\dot{\delta}_i &= \omega_b (\omega_i - \omega_{\text{ref}}) \\ 2 H_i \dot{\omega}_i &= T_{m,i} - T_{e,i} - \!\!\sum_{j \sim i}\! K_{ij}(\delta_i - \delta_j) - D_i (\omega_i - \omega_{\text{ref}}) - \!\!\sum_{j \sim i}\! D_{ij}(\omega_i - \omega_j)\end{split}\]

where the sums run over the adjacent masses \(j\). The mechanical power \(T_{m,i} = F_i P_m\) is applied only to the turbine masses (fractions \(F_i\) summing to 1), and the electromagnetic air-gap power \(T_{e,i} = P_e\) only to the generator mass. The generator mass also carries the machine’s rotor friction \(f\,\omega\).

The generator mass keeps the canonical names ``delta`` / ``omega`` and reuses the machine’s own H / D / f; every other mass <name> contributes states delta_<name> / omega_<name> and parameters H_<name> (inertia) and D_<name> (self damping). Each shaft section between adjacent masses a and b contributes a stiffness K_<a>_<b> and an optional mutual damping Dm_<a>_<b> (default 0). Each turbine mass contributes a mechanical fraction F_<name>.

This base is configured by the class attributes below; concrete shafts (Shaft4Mass, Shaft5Mass) just set them. With a single mass and no sections it reduces exactly to SingleMass.

_masses: List[str] = []
_gen: str = 'gen'
_turbines: List[str] = []
_H_def: Dict[str, float]
_D_def: Dict[str, float]
_K_def: Dict[str, float]
_Dm_def: Dict[str, float]
_F_def: Dict[str, float]
_angle(m: str) str[source]
Parameters:

m (str)

Return type:

str

_speed(m: str) str[source]
Parameters:

m (str)

Return type:

str

_others() List[str][source]
Return type:

List[str]

_sections() List[Tuple[str, str]][source]
Return type:

List[Tuple[str, str]]

states() List[str][source]

Return ordered differential-state names. MUST contain ‘delta’ and ‘omega’ (the generator mass).

Return type:

List[str]

units() List[str][source]

Return units for each state, same length as states().

Return type:

List[str]

params() Dict[str, float][source]

Return dict of parameter names -> default values (empty for the single-mass shaft, which reuses the machine’s own H, D, f).

Return type:

Dict[str, float]

states_noise() Dict[str, float][source]

Return process-noise specification for each state.

Return type:

Dict[str, float]

states_init_error() Dict[str, float][source]

Return initial error for each state.

Return type:

Dict[str, float]

x0() Dict[str, float][source]

Return default initial guess for each state.

Return type:

Dict[str, float]

descriptions() Dict[str, str][source]

Return descriptions for states and params.

Return type:

Dict[str, str]

fgcall(host, dae: pydynamicestimator.system.Dae, Pe) None[source]

Write the rotor-motion (swing) differential equations into dae.f.

Parameters:
  • host – The Synchronous machine instance. Access state indices via host.delta, host.omega (generator mass) and, for a multi-mass shaft, host.delta_<name>/host.omega_<name>; inertia/damping via host.H, host.D, host.f (generator mass) and host.H_<name>, …; the governor port via host.var_sym(dae, “pm”) and the reference frequency via host._omega_ref(dae).

  • dae (pydynamicestimator.system.Dae) – The DAE system object.

  • Pe – The electromagnetic air-gap power (CasADi SX, one entry per machine), applied to the generator mass.

Return type:

None

class pydynamicestimator.devices.shaft.Shaft4Mass[source]

Bases: MultiMassShaft

Four-mass turbine-generator shaft: HP – IP – LP – GEN (linear chain).

GEN is the generator mass (carries the air-gap power Pe and the machine’s own H/D/f); HP, IP and LP are the turbine masses sharing the mechanical power Pm through the fractions F_hp/F_ip/F_lp (default 0.3/0.3/0.4). Select with shaft="Shaft4Mass" on the machine row; override any of the default H_*/K_*/F_*/D_*/Dm_* parameters in the data file.

_masses = ['hp', 'ip', 'lp', 'gen']
_gen = 'gen'
_turbines = ['hp', 'ip', 'lp']
_H_def
_K_def
_F_def
class pydynamicestimator.devices.shaft.Shaft5Mass[source]

Bases: MultiMassShaft

Five-mass turbine-generator shaft: HP – IP – LP – GEN – EXC (linear chain).

As Shaft4Mass but with an additional exciter mass (EXC) on the far side of the generator. EXC carries no mechanical and no electrical power – it is a passive inertia coupled through the GEN–EXC shaft section, relevant for the higher torsional modes. Select with shaft="Shaft5Mass".

_masses = ['hp', 'ip', 'lp', 'gen', 'exc']
_gen = 'gen'
_turbines = ['hp', 'ip', 'lp']
_H_def
_K_def
_F_def
pydynamicestimator.devices.shaft.SHAFT_REGISTRY: Dict[str, type]