Skip to content
Draft
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
22 changes: 22 additions & 0 deletions docs/source/user/aerodyn/bibliography.bib
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,28 @@ @techreport{ad-Murray:2011
institution={49th AIAA Aerospace Sciences Meeting, Orlando, Florida}
}

@article{ad-Bangga:2020,
author = {Galih Bangga and Thorsten Lutz and Matthias Arnold},
title = {An improved second-order dynamic stall model for wind turbine airfoils},
year = {2020},
journal = {Wind Energy Science},
volume = {5},
number = {3},
pages = {1037--1058},
doi = {10.5194/wes-5-1037-2020}
}

@article{ad-Bangga:2023,
author = {Galih Bangga and Jason Parkinson and William Collier},
title = {Development and Validation of the IAG Dynamic Stall Model in State-Space Representation for Wind Turbine Airfoils},
year = {2023},
journal = {Energies},
volume = {16},
number = {10},
pages = {3994},
doi = {10.3390/en16103994}
}


@article{ad-hammam2022,
author = {Mohamed M. Hammam and David H. Wood},
Expand Down
2 changes: 1 addition & 1 deletion docs/source/user/aerodyn/examples/ad_primary_example.dat
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ False SectAvg - Use sector averaging (flag)
"unused" OLAFInputFileName - Input file for OLAF [used only when Wake_Mod=3]
====== Unsteady Airfoil Aerodynamics Options ====================================================
True AoA34 - Sample the angle of attack (AoA) at the 3/4 chord or the AC point {default=True} [always used]
3 UA_Mod - Unsteady Aero Model Switch (switch) {0=Quasi-steady (no UA), 2=B-L Gonzalez, 3=B-L Minnema/Pierce, 4=B-L HGM 4-states, 5=B-L HGM+vortex 5 states, 6=Oye, 7=Boeing-Vertol}
3 UA_Mod - Unsteady Aero Model Switch (switch) {0=Quasi-steady (no UA), 2=B-L Gonzalez, 3=B-L Minnema/Pierce, 4=B-L HGM 4-states, 5=B-L HGM+vortex 5 states, 6=Oye, 7=Boeing-Vertol, 9=IAG}
True FLookup - Flag to indicate whether a lookup for f' will be calculated (TRUE) or whether best-fit exponential equations will be used (FALSE); if FALSE S1-S4 must be provided in airfoil input files (flag) [used only when UA_Mod=2 or UA_Mod=3]
3 IntegrationMethod - Switch to indicate which integration method UA uses (1=RK4, 2=AB4, 3=ABM4, 4=BDF2)
0 UAStartRad - Starting radius for dynamic stall (fraction of rotor radius [0.0,1.0]) [used only when UA_Mod>0; if line is missing UAStartRad=0]
Expand Down
38 changes: 37 additions & 1 deletion docs/source/user/aerodyn/input.rst
Original file line number Diff line number Diff line change
Expand Up @@ -358,8 +358,13 @@ Most ``UA_Mod`` will require `AoA34` to be set to true. But when using quasi-ste
- ``5``: 5-states continuous-time B-L model similar to HGM with an additional state for vortex generation
- ``6``: 1-state continuous-time developed by Oye
- ``7``: discrete-time Boeing-Vertol (BV) model
- ``9``: 5-states continuous-time IAG model (first-order, state-space), with a vortex state

Linearization is supported with ``UA_Mod=4,5,6`` (which use continuous-time states) but not with the other models. The different models are described in :numref:`AD_UA`.
Linearization is supported with ``UA_Mod=4,5,6,9`` (which use continuous-time states) but not with the other models. The different models are described in :numref:`AD_UA`.

.. note::
For ``UA_Mod=9``, only the first four states are linearized; the fifth (vortex) state
is excluded, exactly as for ``UA_Mod=5``.

.. note::
Link to old inputs: If `UA_Mod>0`, then this is equivalent to the old `AFAeroMod=2`.
Expand Down Expand Up @@ -841,6 +846,37 @@ or calculating it based on the polar coefficient data in the airfoil table:
- ``C_lalpha`` is the slope of the 2D normal lift coefficient curve
in the linear region; Used for ``UA_Mod=4,6``.

- ``Ka`` is the impulsive (non-circulatory) normal-force gain of the IAG
model; used only when ``UA_Mod=9``. If the keyword ``DEFAULT`` is entered
in place of a numerical value, ``Ka`` is set to 0.75.

- ``Kv`` is the amplitude of the vortex center-of-pressure travel in the
IAG model; used only when ``UA_Mod=9``. If the keyword ``DEFAULT`` is
entered in place of a numerical value, ``Kv`` is set to 0.2.

- ``dCNdA`` is the slope of the static :math:`C_n` curve used by the IAG
model; used only when ``UA_Mod=9``. If the keyword ``DEFAULT`` is entered
in place of a numerical value, ``dCNdA`` is obtained from a linear fit to
the attached-flow region of the supplied polar. Note that ``UA_Mod=9``
uses ``dCNdA`` rather than ``C_nalpha`` or ``C_lalpha``, and that it
builds its **own** separation function by tabulating
:math:`dCNdA\,\sin(\alpha-\alpha_0)`, rather than using the
piecewise-linear fully-attached curve shared by the HGM/HGMV models. The
``f_st`` values written for ``UA_Mod=9`` are therefore **not** on a common
basis with those written for ``UA_Mod=5``.

- ``CnMax`` and ``CnMin`` are not airfoil-file inputs. They are the maximum
and minimum of the static :math:`C_n` polar, calculated at initialization,
and they set the positive and negative vortex-shedding thresholds of the
IAG model. They are reported in the unsteady-aero summary table written
when ``UA_Mod=9`` and ``SumPrint = TRUE``. A reported value of
``999.00000`` for ``CnMax`` (and ``-999.00000`` for ``CnMin``) is a
sentinel, not a physical coefficient: it means the vortex logic has been
disabled for that table, either because the model is not IAG or because
the polar has no identifiable stall peak, as for a cylinder-like table at
the blade root. Because :math:`|C_n|` can never reach 999, the shedding
trigger simply never fires and the model runs without vortex lift.

- ``T_f0`` is the initial value of the time constant associated with
*Df* in the expressions of *Df* and *f’*; if the keyword ``DEFAULT`` is
entered in place of a numerical value, ``T_f0`` is set to 3.0;
Expand Down
69 changes: 69 additions & 0 deletions docs/source/user/aerodyn/theory_ua.rst
Original file line number Diff line number Diff line change
Expand Up @@ -494,6 +494,75 @@ The moment coefficient is calculated based on values at the aerodynamic center a
where :math:`\alpha_{50}` is computed the same way as :math:`\alpha_{34}` (using the velocity at the aerodynamic center and the rotational rate of the airfoil) but using the distance from the aerodynamic center to the mid-chord (see :numref:`ua_notations`).


IAG model (UAMod=9)
~~~~~~~~~~~~~~~~~~~

The IAG model :cite:`ad-Bangga:2020,ad-Bangga:2023` is a five-state, continuous-time
Beddoes-Leishman variant. Like the HGMV model (``UA_Mod=5``) it carries two downwash memory
states :math:`x_1,x_2`, a lagged attached-flow state :math:`x_3`, a separation state
:math:`x_4`, and a vortex state :math:`x_5`. Linearization is supported, but only
:math:`x_1`-:math:`x_4` are linearized; the vortex state is excluded.

The model differs from HGM/HGMV in four ways that matter when comparing output:

**1. It uses a sinusoidal attached-flow curve, not a piecewise-linear one.** The circulatory
normal force is

.. math::
C_N^C = \frac{\mathrm{d}C_N}{\mathrm{d}\alpha}\,\sin(\alpha_E - \alpha_0)

so the model is driven by the airfoil input ``dCNdA`` rather than by ``C_nalpha`` or
``C_lalpha``, neither of which it reads. ``dCNdA`` is obtained by a linear fit to the
attached-flow region of the supplied polar unless the user overrides it.

**2. It builds its own separation function.** The ``f_st`` column used by ``UA_Mod=9`` is
tabulated by inverting the squared-Kirchhoff relation against the sinusoidal curve above,

.. math::
C_N^f = \frac{\mathrm{d}C_N}{\mathrm{d}\alpha}
\left(\frac{1+\sqrt{x_4}}{2}\right)^{2}\sin(\alpha_F-\alpha_0) + C_N^I

rather than against the piecewise-linear ``FullyAttached`` curve shared by the HGM/HGMV
models. **The** ``f_st`` **values written for** ``UA_Mod=9`` **are therefore not on a common
basis with those written for** ``UA_Mod=5``, and the two should not be compared directly.

**3. The effective and separation angles do not coincide.** Because the attached-flow
relation is sinusoidal, inverting it for :math:`\alpha_F` gives
:math:`\alpha_F = \alpha_0 + \sin(\alpha_E-\alpha_0)` under the model's linearized
inversion, so :math:`\alpha_F \neq \alpha_E` in general. For HGM the two collapse to the
same value.

**4. The** ``Cc`` **output channel is a different quantity than for the other models.**
When unsteady-aero outputs are enabled, ``UA_Mod=9`` writes the *viscous* chordwise force
evaluated at :math:`\alpha_F` with :math:`C_{d0}` removed,

.. math::
C_c = C_l^{st}(\alpha_F)\sin\alpha_F - \left[C_d^{st}(\alpha_F) - C_{d0}\right]\cos\alpha_F

which is the :math:`C_T^D` of the IAG formulation. The HGM and HGMV models instead write
:math:`C_c = C_l\sin\alpha - C_d\cos\alpha` evaluated at the instantaneous :math:`\alpha`
and **without** subtracting :math:`C_{d0}`. The two are not the same quantity and **the**
``Cc`` **column should not be compared between** ``UA_Mod=9`` **and the other models.**
This affects the reported channel only: :math:`C_l`, :math:`C_d` and :math:`C_m` are the
quantities passed to the rest of AeroDyn, and for the IAG model those are reconstructed
from :math:`C_N^D` and :math:`C_T^D` before they are returned, so loads are unaffected.

The impulsive (non-circulatory) normal force is scaled by the airfoil input ``Ka``, and the
vortex center-of-pressure travel by ``Kv``. Vortex shedding is triggered on the calculated
``CnMax``/``CnMin`` thresholds rather than on ``Cn1``/``Cn2``, which the model does not use.
``CnMax`` and ``CnMin`` are the extrema of the static :math:`C_n` polar and are reported in
the unsteady-aero summary table; values of :math:`\pm 999` there are a sentinel indicating
that no stall peak could be identified for that table and that vortex shedding is therefore
disabled for it (see :numref:`airfoil_data_input_file`).

Beyond roughly 30 degrees of incidence the separated-flow construction loses validity, so
the dynamic :math:`C_d` and :math:`C_m` are faded linearly back to their static values
between 30 and 45 degrees. This is applied before the shared UA cutout blend, so the two
compose. :math:`C_l`, :math:`C_n` and :math:`C_c` are deliberately not faded separately,
since :math:`C_l` is reconstructed from :math:`C_n` and :math:`C_c` and blending it
independently would make the three mutually inconsistent.





Expand Down
2 changes: 2 additions & 0 deletions docs/source/user/api_change.rst
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ The generalized support-structure (GS) influence model was added to AeroDyn. Thi

OLAF now selects the regularization function for the vortex particles separately from the vortex segments. The new ``RegFunctionPart`` input on line 26 of the OLAF input file controls the particle kernel, and ``RegFunction`` now applies only to the segments. Previously the particle kernel was inferred from ``RegFunction``: any regularized value gave an exponential particle kernel, while ``RegFunction=0`` gave an unregularized one. The default ``RegFunctionPart=1`` reproduces the exponential kernel, so results are unchanged for decks with ``RegFunction`` greater than 0. Decks with ``RegFunction=0`` will change: the particles are now regularized with the exponential kernel unless ``RegFunctionPart=0`` is also set. Setting ``RegFunctionPart=0`` restores an unregularized particle kernel, but with ``VelocityMethod=2`` the results will still differ from previous versions because the particle-tree far-field cutoff is no longer padded by the particle core radius when the particle kernel is unregularized.

The IAG dynamic stall model was added to AeroDyn as a new ``UA_Mod=9`` option. This change is **backwards compatible**: no lines are added to or removed from the AeroDyn primary input file (only the comment text of the existing ``UA_Mod`` line changes), and the three new airfoil-file inputs it introduces (``Ka``, ``Kv``, ``dCNdA``) are all optional and accept ``DEFAULT``, so existing airfoil files continue to work unchanged. The new airfoil inputs are placed after ``x_cp_bar`` and before ``UACutout``, and are read only when ``UA_Mod=9``.

============================================= ======== ==================== ==========================================================================================================================================================================================================================================================================================================
Added in OpenFAST `5.1.0`
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Expand Down
9 changes: 7 additions & 2 deletions modules/aerodyn/src/AeroDyn.f90
Original file line number Diff line number Diff line change
Expand Up @@ -4894,8 +4894,13 @@ SUBROUTINE ValidateInputData( InitInp, InputFileData, NumBl, calcCrvAngle, ErrSt
call SetErrStat( ErrID_Fatal, 'Wake_Mod must be 0 or 1 for linearization.', ErrStat, ErrMsg, RoutineName )
endif

if (InputFileData%UA_Init%UAMod /= UA_None .and. InputFileData%UA_Init%UAMod /= UA_HGM .and. InputFileData%UA_Init%UAMod /= UA_HGMV .and. InputFileData%UA_Init%UAMod /= UA_OYE) then
call SetErrStat( ErrID_Fatal, 'UA_Mod must be 0, 4, 5, or 6 for linearization.', ErrStat, ErrMsg, RoutineName )
! NOTE: this is a chain of exclusions, not an allowed-list, so a new model is
! REJECTED for linearization unless it is named here. UA_IAG is admitted on the
! same basis as UA_HGMV: both carry a 5th (vortex) state that is not linearized,
! and both linearize x1-x4 only (see p%lin_nx in UA_SetParameters). UA_HGMV360 is
! deliberately still absent.
if (InputFileData%UA_Init%UAMod /= UA_None .and. InputFileData%UA_Init%UAMod /= UA_HGM .and. InputFileData%UA_Init%UAMod /= UA_HGMV .and. InputFileData%UA_Init%UAMod /= UA_OYE .and. InputFileData%UA_Init%UAMod /= UA_IAG) then
call SetErrStat( ErrID_Fatal, 'UA_Mod must be 0, 4, 5, 6, or 9 for linearization.', ErrStat, ErrMsg, RoutineName )
end if

select case(InputFileData%DBEMT_Mod)
Expand Down
4 changes: 3 additions & 1 deletion modules/aerodyn/src/AeroDyn_IO.f90
Original file line number Diff line number Diff line change
Expand Up @@ -981,7 +981,7 @@ SUBROUTINE ParsePrimaryFileInfo( PriPath, InitInp, InputFile, RootName, NumBlade
! UAMod (Legacy)
call ParseVar( FileInfo_In, CurLine, "UAMod", UAMod_Old, ErrStat2, ErrMsg2, UnEc )
UAModProvided = legacyInputPresent('UAMod', CurLine, ErrStat2, ErrMsg2, 'UA_Mod=0 (AFAeroMod=1), UA_Mod>1 (AFAeroMod=2 and UA_Mod=UAMod')
! UA_Mod - Unsteady Aero Model Switch (switch) {0=Quasi-steady (no UA), 2=Gonzalez's variant (changes in Cn,Cc,Cm), 3=Minnema/Pierce variant (changes in Cc and Cm)}
! UA_Mod - Unsteady Aero Model Switch (switch) {0=Quasi-steady (no UA), 2=Gonzalez's variant (changes in Cn,Cc,Cm), 3=Minnema/Pierce variant (changes in Cc and Cm), 4=HGM, 5=HGM+vortex, 6=Oye, 7=Boeing-Vertol, 9=IAG}
call ParseVar( FileInfo_In, CurLine, "UA_Mod", InputFileData%UA_Init%UAMod, ErrStat2, ErrMsg2, UnEc )
if (newInputMissing('UA_Mod', CurLine, errStat2, errMsg2)) then
! We'll deal with it when we deal with AFAeroMod
Expand Down Expand Up @@ -2089,6 +2089,8 @@ SUBROUTINE AD_PrintSum( InputFileData, p, p_AD, u, y, NumBlades, BladeInputFileD
Msg = 'Stieg Oye dynamic stall model'
case (UA_BV)
Msg = 'Boeing-Vertol dynamic stall model (e.g. used in CACTUS)'
case (UA_IAG)
Msg = 'IAG dynamic stall model (first-order, state-space)'
case default
Msg = 'unknown'
end select
Expand Down
Loading
Loading