Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 32 additions & 24 deletions GridKit/Model/PhasorDynamics/Governor/Tgov1/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ Standard model of the stream turbine

Symbol | Units | Description | Typical Value | Note
------------|--------|-----------------------------------|---------------| ------
$T_{\mathrm{rate}}$ | [MW] | Turbine rating | 100.0 |
$R$ | [p.u.] | Droop Constant | 0.05 |
$T_1$ | [sec] | Valve Time Delay | 0.5 |
$T_2$ | [sec] | Turbine Numerator Time Constant | 2.5 |
Expand Down Expand Up @@ -52,53 +53,60 @@ $P_{ref}$ | [p.u.] | Reference Power | Either a constant

## Model Equations

### Differential Equations
The TGOV1 differential equations, as derived from the model diagram. Define the pre-limit derivative of $P_v$

For readability, define:
```math
f = \dfrac{1}{T_1}\left[-P_v + \dfrac{1}{R}(P_{ref} - \omega)\right]
f = -P_v + \dfrac{1}{R}(P_{ref} - \omega)
```

so that $\dot P_v$ can be written in piecewise form compactly.
### Differential Equations
The TGOV1 differential equations, as derived from the model diagram.

```math
\begin{aligned}
\dot P_{tx} &= P_v - \dfrac{1}{T_3}(P_{tx}+T_2P_v) \\
\dot P_v &=
\begin{cases}
f
& \text{if } (P_v^{\min} < P_v < P_v^{\max}) & \lor \\
& \quad (P_v \leq P_v^{\min} \land f>0) & \lor \\
& \quad(P_v \geq P_v^{\max} \land f<0) \\
0
& \text{else}
\end{cases}
0 &= -T_3 \dot P_{tx} - P_{tx} + (T_3 - T_2)P_v \\
0 &= -T_1 \dot P_v
+ \text{antiwindup}(
P_v,
f,
P_v^{\min},
P_v^{\max}
)
\end{aligned}
```

CommonMath defines the [Anti-Windup](../../../../CommonMath.md#anti-windup-indicator)
target and smooth approximation.

### Algebraic Equations
The algebraic equation dictating the mechnical power output.
```math
\begin{aligned}
P_m &= \dfrac{1}{T_3}(P_{tx}+T_2P_v) - D_t \omega \\
0 &= -\dfrac{S_{\mathrm{sys}}}{T_{\mathrm{rate}}} P_m
+ \dfrac{1}{T_3}(P_{tx}+T_2P_v) - D_t \omega \\
\end{aligned}
```

In simulation the piecewise form above is replaced with a smooth approximation where $\phi$ is GridKit's smooth anti-windup indicator. See [CommonMath: Anti-Windup Indicator](../../../../CommonMath.md#anti-windup-indicator) for its definition, behavior, and design rationale.

## Initialization
At steady state we assume that $P_v$ is at or within its limits. This implies the initial conditions are a function of $P_m$ which is equal to the electric torque.
At steady state we assume that $P_v$ is at or within its limits. This implies the initial conditions are a function of the initial mechanical power converted to the TGOV1 component base.
```math
\begin{aligned}
P_{tx} &= (T_3-T_2) P_m\\
P_v &= P_m\\
\dot P_{tx} &=0\\
\dot P_v &=0\\
P^{\mathrm{tgov1}}_{m,0}
&= \dfrac{S_{\mathrm{sys}}}{T_{\mathrm{rate}}}P_{m,0} \\
P_{tx,0}
&= (T_3 - T_2)P^{\mathrm{tgov1}}_{m,0} \\
P_{v,0}
&= P^{\mathrm{tgov1}}_{m,0} \\
\dot P_{tx,0}
&= 0 \\
\dot P_{v,0}
&= 0
\end{aligned}
```

And if the reference power is a constant parameter, we can determine the value by solving the steady state equations.
```math
\begin{aligned}
P_{ref} &= R P_m\\
P_{ref,0}
&= R P^{\mathrm{tgov1}}_{m,0}
\end{aligned}
```
10 changes: 9 additions & 1 deletion GridKit/Model/PhasorDynamics/Governor/Tgov1/Tgov1.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ namespace GridKit
using Component<scalar_type, index_type>::J_rows_buffer_;
using Component<scalar_type, index_type>::J_cols_buffer_;
using Component<scalar_type, index_type>::J_vals_buffer_;
using Component<scalar_type, index_type>::va_system_base_;
using Component<scalar_type, index_type>::variable_indices_;
using Component<scalar_type, index_type>::residual_indices_;

Expand Down Expand Up @@ -113,6 +114,7 @@ namespace GridKit

private:
// Input parameters
RealT Trate_{0};
RealT R_{0};
RealT Pvmin_{0};
RealT Pvmax_{0};
Expand All @@ -121,14 +123,20 @@ namespace GridKit
RealT T3_{0};
RealT Dt_{0};

// Derived parameters
RealT va_component_base_{0};

// Input States (which can be parameters)
ScalarT pref_{0};

/// Component signal extension
ComponentSignals<ScalarT, IdxT, Tgov1InternalVariables, Tgov1ExternalVariables> signals_;

// Parameter initialization function
void initializeParameters(const ModelDataT& data);
void initializeParameters(const ModelDataT& data);
void setDerivedParams();
ScalarT toComponentBase(ScalarT value) const;
ScalarT toSystemBase(ScalarT value) const;

/* Local copies of signal variables */
std::vector<ScalarT> ws_;
Expand Down
1 change: 1 addition & 0 deletions GridKit/Model/PhasorDynamics/Governor/Tgov1/Tgov1Data.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ namespace GridKit
*/
enum class Tgov1Parameters
{
Trate, ///< Turbine-rating power base
R, ///< Droop Constant
T1, ///< Valve Time Delay
T2, ///< Turbine Numerator Time Constant
Expand Down
44 changes: 36 additions & 8 deletions GridKit/Model/PhasorDynamics/Governor/Tgov1/Tgov1Impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,10 @@ namespace GridKit
*/
template <typename scalar_type, typename index_type>
Tgov1<scalar_type, index_type>::Tgov1()
: Trate_(100.0)
{
size_ = 3;
setDerivedParams();
}

/**
Expand All @@ -44,7 +46,8 @@ namespace GridKit
*/
template <typename scalar_type, typename index_type>
Tgov1<scalar_type, index_type>::Tgov1(SignalT* pmech, SignalT* omega)
: R_(0.05),
: Trate_(100.0),
R_(0.05),
Pvmin_(0),
Pvmax_(1),
T1_(HALF<RealT>),
Expand All @@ -57,6 +60,7 @@ namespace GridKit

// 3 internal variables
size_ = 3;
setDerivedParams();
}

/**
Expand All @@ -69,6 +73,7 @@ namespace GridKit
{
initializeParameters(data);
size_ = 3;
setDerivedParams();
}

/**
Expand All @@ -82,6 +87,11 @@ namespace GridKit
template <typename scalar_type, typename index_type>
void Tgov1<scalar_type, index_type>::initializeParameters(const ModelDataT& data)
{
if (data.parameters.contains(ModelDataT::Parameters::Trate))
{
Trate_ = std::get<RealT>(data.parameters.at(ModelDataT::Parameters::Trate));
}

if (data.parameters.contains(ModelDataT::Parameters::R))
{
R_ = std::get<RealT>(data.parameters.at(ModelDataT::Parameters::R));
Expand Down Expand Up @@ -118,6 +128,24 @@ namespace GridKit
}
}

template <typename scalar_type, typename index_type>
void Tgov1<scalar_type, index_type>::setDerivedParams()
{
va_component_base_ = Trate_ * static_cast<RealT>(1.0e6);
}

template <typename scalar_type, typename index_type>
scalar_type Tgov1<scalar_type, index_type>::toComponentBase(scalar_type value) const
{
return value * va_system_base_ / va_component_base_;
}

template <typename scalar_type, typename index_type>
scalar_type Tgov1<scalar_type, index_type>::toSystemBase(scalar_type value) const
{
return value / toComponentBase(static_cast<scalar_type>(ONE<RealT>));
}

/**
* @brief Set the component ID
*/
Expand Down Expand Up @@ -199,7 +227,7 @@ namespace GridKit
// Initial mechanical = initial electric torque
if (signals_.template isAssigned<Tgov1InternalVariables::PM>())
{
p0 = y_[2]; ///<- generator needs to be initialized first
p0 = toComponentBase(y_[2]); ///<- generator needs to be initialized first
}

// Input Variables (Parameter for now)
Expand All @@ -208,7 +236,7 @@ namespace GridKit
// Internal States
y_[0] = (T3_ - T2_) * p0; // y0 - Ptx (Turbine Power )
y_[1] = p0; // y1 - Pv (Valve Position)
y_[2] = p0; // y2 - Pm (Mech Power)
y_[2] = toSystemBase(p0); // y2 - Pm (Mech Power)

// D.V. Derivative
yp_[0] = 0.0; // Ptx
Expand Down Expand Up @@ -256,15 +284,15 @@ namespace GridKit
// Set signal variable aliases
ScalarT omega = ws[0];

// The 'pre-limit' derivative of Pv
ScalarT func = (-pv + (pref_ - omega) / R_) / T1_;
// The 'pre-limit' target of Pv
ScalarT func = -pv + (pref_ - omega) / R_;

// Internal Differential Equations
f[0] = -ptx_dot + pv - (ptx + T2_ * pv) / T3_;
f[1] = -pv_dot + Math::antiwindup(pv, func, Pvmin_, Pvmax_);
f[0] = -T3_ * ptx_dot - ptx + (T3_ - T2_) * pv;
f[1] = -T1_ * pv_dot + Math::antiwindup(pv, func, Pvmin_, Pvmax_);

// Internal Algebraic Equations
f[2] = -pmech + (ptx + T2_ * pv) / T3_ - (Dt_ * omega);
f[2] = -toComponentBase(pmech) + (ptx + T2_ * pv) / T3_ - (Dt_ * omega);

return 0;
}
Expand Down
4 changes: 2 additions & 2 deletions GridKit/Model/PhasorDynamics/INPUT_FORMAT.md
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ are specified:
`Genrou` | 6th order machine model | `bus`, `pmech`\*, `speed`\*, `efd`\* | `p0`, `q0`, `H`, `D`, `Ra`, `Tdop`, `Tdopp`, `Tqop`, `Tqopp`, `Xd`, `Xdp`, `Xdpp`, `Xq`, `Xqp`, `Xqpp`, `Xl`, `S10`, `S12`, `mva` | `ir`, `ii`, `p`, `q`, `delta`, `omega`, `speed`
`Gensal` | 5th order salient-pole machine model | `bus`, `pmech`\*, `speed`\*, `efd`\* | `p0`, `q0`, `H`, `D`, `Ra`, `Tdop`, `Tdopp`, `Tqopp`, `Xd`, `Xdp`, `Xdpp`, `Xq`, `Xl`, `S10`, `S12`, `mva` | `ir`, `ii`, `p`, `q`, `delta`, `omega`, `speed`, `Eqp`, `psidp`, `psiqpp`, `psidpp`, `vd`, `vq`, `te`, `id`, `iq`
`GenClassical` | the classical machine model | `bus`, `pmech`\*, `speed`\*, `efd`\* | `p0`, `q0`, `H`, `D`, `Ra`, `Xdp`, `mva` | `ir`, `ii`, `p`, `q`, `delta`, `omega`
`Tgov1 ` | the TGOV1 governor model | `pmech`, `speed` | `R`, `T1`, `T2`, `T3`, `Pvmax`, `Pvmin`, `Dt` | `none`
`Tgov1 ` | the TGOV1 governor model | `pmech`, `speed` | `Trate`, `R`, `T1`, `T2`, `T3`, `Pvmax`, `Pvmin`, `Dt` | `none`
`Ieeet1` | the IEEET1 exciter model | `bus`, `speed`, `efd`, `vs`\* | `Tr`, `Ka`, `Ta`, `Ke`, `Te`, `Kf`, `Tf`, `Vrmin`, `Vrmax`, `E1`, `E2`, `Se1`, `Se2`, `Ispdlim` | `efd`, `ksat`
`SexsPti` | the SEXS-PTI simplified exciter model | `bus`, `efd`, `vs`\* | `Ta`, `Tb`, `Te`, `K`, `Efdmax`, `Efdmin` | `efd`
`Ieeest` | the IEEEST stabilizer model | `input`, `output` | `A1`, `A2`, `A3`, `A4`, `A5`, `A6`, `T1`, `T2`, `T3`, `T4`, `T5`, `T6`, `Ks`, `Lsmin`, `Lsmax`, `Vcl`, `Vcu`, `Tdelay` | `vss`
Expand Down Expand Up @@ -184,7 +184,7 @@ side for off-nominal transformer branches.
"devices": [
{ "class": "Branch", "ports": {"bus1":1, "bus2":2}, "id": "BR1", "params": {"R":0.0, "X":0.1, "G":0.0, "B":0.0} },
{ "class": "Genrou", "ports": {"bus":1, "speed": 1, "pmech":2, "efd":3}, "id": "DV1", "params": {"p0":1.0, "q0":0.05013, "H":3.0, "D":0.0, "Ra":0.0, "Tdop":7.0, "Tdopp":0.04, "Tqopp":0.05, "Tqop":0.75, "Xd":2.1, "Xdp":0.2, "Xdpp":0.18, "Xq":0.5, "Xqp": 0.0, "Xqpp":0.18, "Xl":0.15, "S10":0.0, "S12":0.0}, "mon": ["delta", "omega"] },
{ "class": "Tgov1", "ports": {"bus":1, "speed": 1, "pmech":2}, "id": "DV2", "params": {"R":0.05, "T1":0.5,"T2":2.5, "T3":7.5, "Pvmax":0, "Pvmin":1, "Dt":0}},
{ "class": "Tgov1", "ports": {"bus":1, "speed": 1, "pmech":2}, "id": "DV2", "params": {"Trate":100.0, "R":0.05, "T1":0.5,"T2":2.5, "T3":7.5, "Pvmax":0, "Pvmin":1, "Dt":0}},
{ "class": "Ieeet1", "ports": {"bus":1, "speed": 1, "efd":3}, "id": "DV3", "params": {"Tr":0.001, "Ka":50.0, "Ta":0.04, "Ke":-0.06, "Te":0.6, "Kf":0.09, "Tf":1.46, "Vrmin":-1, "Vrmax":1, "E1":2.8, "E2":3.373, "Se1":0.04, "Se2":0.33, "Ispdlim":0}},
{ "class": "BusFault", "ports": {"bus":1}, "id": "EVT1", "params": {"state0": false, "R":0.0, "X":1e-3} }
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -490,10 +490,10 @@ namespace GridKit
+ G_ * (vd * -std::cos(delta) + vq * std::sin(delta));

ScalarT Te = y_[12];
pmech_set_ = Te;
pmech_set_ = toSystemBase(Te);
if (signals_.template isAttached<GenrouExternalVariables::PM>())
{
signals_.template writeExternalVariable<GenrouExternalVariables::PM>(Te);
signals_.template writeExternalVariable<GenrouExternalVariables::PM>(pmech_set_);
}

efd_set_ = Eqp + Xd1_ * (id + Xd3_ * (Eqp - psidp - Xd2_ * id)) + psidpp * ksat;
Expand Down Expand Up @@ -569,7 +569,7 @@ namespace GridKit
ScalarT vi = wb[1];

// Set signal variable aliases
ScalarT pmech = ws[0];
ScalarT pmech = toMachineBase(ws[0]);
ScalarT efd = ws[1];

/* 6 Genrou differential equations */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -313,10 +313,10 @@ namespace GridKit
y_[15] = B_ * (vd * std::sin(delta) + vq * std::cos(delta))
+ G_ * (vd * -std::cos(delta) + vq * std::sin(delta));

pmech_set_ = Te;
pmech_set_ = toSystemBase(Te);
if (signals_.template isAttached<GensalExternalVariables::PM>())
{
signals_.template writeExternalVariable<GensalExternalVariables::PM>(Te);
signals_.template writeExternalVariable<GensalExternalVariables::PM>(pmech_set_);
}

efd_set_ = Eqp + Xd1_ * (id + Xd3_ * (Eqp - psidp - Xd2_ * id)) + ksat;
Expand Down Expand Up @@ -388,7 +388,7 @@ namespace GridKit
ScalarT vi = wb[1];

// Set signal variable aliases
ScalarT pmech = ws[0];
ScalarT pmech = toMachineBase(ws[0]);
ScalarT efd = ws[1];

/* 5 Gensal differential equations */
Expand Down
Loading
Loading