Skip to content

Commit

Permalink
Merge pull request #29 from OpenFAST/dev
Browse files Browse the repository at this point in the history
Merging dev into main
  • Loading branch information
rthedin authored Jan 14, 2025
2 parents ed7d9dd + f559029 commit e1707da
Show file tree
Hide file tree
Showing 36 changed files with 2,551 additions and 979 deletions.
14 changes: 3 additions & 11 deletions .github/workflows/development-pipeline.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,6 @@ jobs:
strategy:
matrix:
include:
- os: ubuntu-latest
python-version: 3.7
python: xvfb-run python3
pip_arg: ""
- os: ubuntu-latest
python-version: 3.8
python: xvfb-run python3
pip_arg: ""
- os: ubuntu-latest
python-version: 3.9
python: xvfb-run python3
Expand All @@ -41,11 +33,11 @@ jobs:
python-version: 3.12
python: xvfb-run python3
pip_arg: ""
- os: macos-11
python-version: 3.11
- os: macos-13
python-version: 3.12
python: python3
pip_arg: ""
- os: windows-2019
- os: windows-2022
python-version: 3.11
python: python
pip_arg: --user
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -119,3 +119,5 @@ venv.bak/
# Hidding files starting with underscore except init
_*
!__init__.py
*.xml
*.iml
104 changes: 104 additions & 0 deletions data/example_files/AeroDyn_v3.0.dat
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
------- AERODYN v15 for OpenFAST INPUT FILE -----------------------------------------------
NREL 5.0 MW offshore baseline aerodynamic input properties.
====== General Options ============================================================================
False Echo - Echo the input to "<rootname>.AD.ech"? (flag)
"default" DTAero - Time interval for aerodynamic calculations {or "default"} (s)
2 WakeMod - Type of wake/induction model (switch) {0=none, 1=BEMT, 2=DBEMT, 3=OLAF} [WakeMod cannot be 2 or 3 when linearizing]
2 AFAeroMod - Type of blade airfoil aerodynamics model (switch) {1=steady model, 2=Beddoes-Leishman unsteady model} [AFAeroMod must be 1 when linearizing]
0 TwrPotent - Type tower influence on wind based on potential flow around the tower (switch) {0=none, 1=baseline potential flow, 2=potential flow with Bak correction}
0 TwrShadow - Calculate tower influence on wind based on downstream tower shadow (switch) {0=none, 1=Powles model, 2=Eames model}
False TwrAero - Calculate tower aerodynamic loads? (flag)
False FrozenWake - Assume frozen wake during linearization? (flag) [used only when WakeMod=1 and when linearizing]
False CavitCheck - Perform cavitation check? (flag) [AFAeroMod must be 1 when CavitCheck=true]
False Buoyancy - Include buoyancy effects? (flag)
False CompAA - Flag to compute AeroAcoustics calculation [used only when WakeMod = 1 or 2]
"unused" AA_InputFile - AeroAcoustics input file [used only when CompAA=true]
====== Environmental Conditions ===================================================================
"default" AirDens - Air density (kg/m^3)
"default" KinVisc - Kinematic viscosity of working fluid (m^2/s)
"default" SpdSound - Speed of sound in working fluid (m/s)
"default" Patm - Atmospheric pressure (Pa) [used only when CavitCheck=True]
"default" Pvap - Vapour pressure of working fluid (Pa) [used only when CavitCheck=True]
====== Blade-Element/Momentum Theory Options ====================================================== [unused when WakeMod=0 or 3]
2 SkewMod - Type of skewed-wake correction model (switch) {1=uncoupled, 2=Pitt/Peters, 3=coupled} [unused when WakeMod=0 or 3]
"default" SkewModFactor - Constant used in Pitt/Peters skewed wake model {or "default" is 15/32*pi} (-) [used only when SkewMod=2; unused when WakeMod=0 or 3]
True TipLoss - Use the Prandtl tip-loss model? (flag) [unused when WakeMod=0 or 3]
True HubLoss - Use the Prandtl hub-loss model? (flag) [unused when WakeMod=0 or 3]
True TanInd - Include tangential induction in BEMT calculations? (flag) [unused when WakeMod=0 or 3]
False AIDrag - Include the drag term in the axial-induction calculation? (flag) [unused when WakeMod=0 or 3]
False TIDrag - Include the drag term in the tangential-induction calculation? (flag) [unused when WakeMod=0,3 or TanInd=FALSE]
"Default" IndToler - Convergence tolerance for BEMT nonlinear solve residual equation {or "default"} (-) [unused when WakeMod=0 or 3]
100 MaxIter - Maximum number of iteration steps (-) [unused when WakeMod=0]
====== Dynamic Blade-Element/Momentum Theory Options ============================================== [used only when WakeMod=2]
2 DBEMT_Mod - Type of dynamic BEMT (DBEMT) model {1=constant tau1, 2=time-dependent tau1} (-) [used only when WakeMod=2]
4 tau1_const - Time constant for DBEMT (s) [used only when WakeMod=2 and DBEMT_Mod=1]
====== OLAF -- cOnvecting LAgrangian Filaments (Free Vortex Wake) Theory Options ================== [used only when WakeMod=3]
"unused" OLAFInputFileName - Input file for OLAF [used only when WakeMod=3]
====== Beddoes-Leishman Unsteady Airfoil Aerodynamics Options ===================================== [used only when AFAeroMod=2]
3 UAMod - Unsteady Aero Model Switch (switch) {1=Baseline model (Original), 2=Gonzalez�s variant (changes in Cn,Cc,Cm), 3=Minemma/Pierce variant (changes in Cc and Cm)} [used only when AFAeroMod=2]
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 AFAeroMod=2]
0.15 UAStartRad - Starting radius for dynamic stall (fraction of rotor radius) [used only when AFAeroMod=2]
1.0 UAEndRad - Ending radius for dynamic stall (fraction of rotor radius) [used only when AFAeroMod=2]
====== Airfoil Information =========================================================================
1 AFTabMod - Interpolation method for multiple airfoil tables {1=1D interpolation on AoA (first table only); 2=2D interpolation on AoA and Re; 3=2D interpolation on AoA and UserProp} (-)
1 InCol_Alfa - The column in the airfoil tables that contains the angle of attack (-)
2 InCol_Cl - The column in the airfoil tables that contains the lift coefficient (-)
3 InCol_Cd - The column in the airfoil tables that contains the drag coefficient (-)
4 InCol_Cm - The column in the airfoil tables that contains the pitching-moment coefficient; use zero if there is no Cm column (-)
0 InCol_Cpmin - The column in the airfoil tables that contains the Cpmin coefficient; use zero if there is no Cpmin column (-)
8 NumAFfiles - Number of airfoil files used (-)
"../5MW_Baseline/Airfoils/Cylinder1.dat" AFNames - Airfoil file names (NumAFfiles lines) (quoted strings)
"../5MW_Baseline/Airfoils/Cylinder2.dat"
"../5MW_Baseline/Airfoils/DU40_A17.dat"
"../5MW_Baseline/Airfoils/DU35_A17.dat"
"../5MW_Baseline/Airfoils/DU30_A17.dat"
"../5MW_Baseline/Airfoils/DU25_A17.dat"
"../5MW_Baseline/Airfoils/DU21_A17.dat"
"../5MW_Baseline/Airfoils/NACA64_A17.dat"
====== Rotor/Blade Properties =====================================================================
True UseBlCm - Include aerodynamic pitching moment in calculations? (flag)
"../5MW_Baseline/NRELOffshrBsline5MW_AeroDyn_blade.dat" ADBlFile(1) - Name of file containing distributed aerodynamic properties for Blade #1 (-)
"../5MW_Baseline/NRELOffshrBsline5MW_AeroDyn_blade.dat" ADBlFile(2) - Name of file containing distributed aerodynamic properties for Blade #2 (-) [unused if NumBl < 2]
"../5MW_Baseline/NRELOffshrBsline5MW_AeroDyn_blade.dat" ADBlFile(3) - Name of file containing distributed aerodynamic properties for Blade #3 (-) [unused if NumBl < 3]
====== Hub Properties ============================================================================== [used only when Buoyancy=True]
0.0 VolHub - Hub volume (m^3)
0.0 HubCenBx - Hub center of buoyancy x direction offset (m)
====== Nacelle Properties ========================================================================== [used only when Buoyancy=True]
0.0 VolNac - Nacelle volume (m^3)
0,0,0 NacCenB - Position of nacelle center of buoyancy from yaw bearing in nacelle coordinates (m)
====== Tail fin Aerodynamics ========================================================================
False TFinAero - Calculate tail fin aerodynamics model (flag)
"unused" TFinFile - Input file for tail fin aerodynamics [used only when TFinAero=True]
====== Tower Influence and Aerodynamics ============================================================ [used only when TwrPotent/=0, TwrShadow/=0, TwrAero=True, or Buoyancy=True]
12 NumTwrNds - Number of tower nodes used in the analysis (-) [used only when TwrPotent/=0, TwrShadow/=0, TwrAero=True, or Buoyancy=True]
TwrElev TwrDiam TwrCd TwrTI TwrCb !TwrTI used only with TwrShadow=2, TwrCb used only with Buoyancy=True
(m) (m) (-) (-) (-)
0.0000000E+00 6.0000000E+00 1.0000000E+00 1.0000000E-01 0.0
8.5261000E+00 5.7870000E+00 1.0000000E+00 1.0000000E-01 0.0
1.7053000E+01 5.5740000E+00 1.0000000E+00 1.0000000E-01 0.0
2.5579000E+01 5.3610000E+00 1.0000000E+00 1.0000000E-01 0.0
3.4105000E+01 5.1480000E+00 1.0000000E+00 1.0000000E-01 0.0
4.2633000E+01 4.9350000E+00 1.0000000E+00 1.0000000E-01 0.0
5.1158000E+01 4.7220000E+00 1.0000000E+00 1.0000000E-01 0.0
5.9685000E+01 4.5090000E+00 1.0000000E+00 1.0000000E-01 0.0
6.8211000E+01 4.2960000E+00 1.0000000E+00 1.0000000E-01 0.0
7.6738000E+01 4.0830000E+00 1.0000000E+00 1.0000000E-01 0.0
8.5268000E+01 3.8700000E+00 1.0000000E+00 1.0000000E-01 0.0
8.7600000E+01 3.8700000E+00 1.0000000E+00 1.0000000E-01 0.0
====== Outputs ====================================================================================
False SumPrint - Generate a summary file listing input options and interpolated properties to "<rootname>.AD.sum"? (flag)
0 NBlOuts - Number of blade node outputs [0 - 9] (-)
1 BlOutNd - Blade nodes whose values will be output (-)
0 NTwOuts - Number of tower node outputs [0 - 9] (-)
1 TwOutNd - Tower nodes whose values will be output (-)
OutList - The next line(s) contains a list of output parameters. See OutListParameters.xlsx for a listing of available output channels, (-)
"RtAeroPwr"
"RtAeroCp"
"RtAeroCt"
END of input file (the word "END" must appear in the first 3 columns of this last OutList line)
====== Outputs for all blade stations (same ending as above for B1N1.... =========================== [optional section]
0 BldNd_BladesOut - Number of blades to output all node information at. Up to number of blades on turbine. (-)
"All" BldNd_BlOutNd - Future feature will allow selecting a portion of the nodes to output. Not implemented yet. (-)
OutListAD - The next line(s) contains a list of output parameters. See OutListParameters.xlsx for a listing of available output channels, (-)
END of input file (the word "END" must appear in the first 3 columns of this last OutList line)
---------------------------------------------------------------------------------------
22 changes: 15 additions & 7 deletions openfast_toolbox/airfoils/Polar.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,15 +84,18 @@ def __init__(self, filename=None, alpha=None, cl=None, cd=None, cm=None, Re=None
cd = df['Cd'].values
cm = df['Cm'].values
if 'fs' in df.keys():
print('[INFO] Using separating function from input file.')
if verbose:
print('[INFO] Using separating function from input file.')
self.fs = df['fs'].values
self._fs_lock = True
if 'Cl_fs' in df.keys():
print('[INFO] Using Cl fully separated from input file.')
if verbose:
print('[INFO] Using Cl fully separated from input file.')
self.cl_fs =df['Cl_fs'].values
self._cl_fs_lock = True
if 'Cl_inv' in df.keys():
print('[INFO] Using Cl inviscid from input file.')
if verbose:
print('[INFO] Using Cl inviscid from input file.')
self.cl_inv = df['Cl_inv'].values
self._cl_inv_lock = True
# TODO we need a trigger if cl_inv provided, we should get alpha0 and slope from it
Expand Down Expand Up @@ -667,7 +670,7 @@ def __getCM(self, i, cmCoef, alpha, cl_ext, cd_ext, alpha_low_deg, alpha_high_de
print("Angle encountered for which there is no CM table value " "(near +/-180 deg). Program will stop.")
return cm_new

def unsteadyParams(self, window_offset=None, nMin=720):
def unsteadyParams(self, window_offset=None, nMin=720, verbose=False):
"""compute unsteady aero parameters used in AeroDyn input file
TODO Questions to solve:
Expand Down Expand Up @@ -737,7 +740,8 @@ def unsteadyParams(self, window_offset=None, nMin=720):
try:
alpha0cn = _find_alpha0(alpha, cn, window, direction='up', value_if_constant = 0.)
except NoCrossingException:
print("[WARN] Polar: Cn unsteady, cannot find zero crossing with up direction, trying down direction")
if verbose:
print("[WARN] Polar: Cn unsteady, cannot find zero crossing with up direction, trying down direction")
alpha0cn = _find_alpha0(alpha, cn, window, direction='down')

# checks for inppropriate data (like cylinders)
Expand All @@ -751,7 +755,8 @@ def unsteadyParams(self, window_offset=None, nMin=720):
try:
a_MaxUpp, cn_MaxUpp, a_MaxLow, cn_MaxLow = _find_max_points(alpha, cn, alpha0, method="inflections")
except NoStallDetectedException:
print('[WARN] Polar: Cn unsteady, cannot find stall based on inflections, using min and max')
if verbose:
print('[WARN] Polar: Cn unsteady, cannot find stall based on inflections, using min and max')
a_MaxUpp, cn_MaxUpp, a_MaxLow, cn_MaxLow = _find_max_points(alpha, cn, alpha0, method="minmax")

# --- cn slope
Expand Down Expand Up @@ -790,7 +795,8 @@ def unsteadyParams(self, window_offset=None, nMin=720):
a_f07_Upp = xInter[2]
a_f07_Low = xInter[0]
else:
print('[WARN] Polar: Cn unsteady, cn_f does not intersect cn 3 times. Intersections:{}.'.format(xInter))
if verbose:
print('[WARN] Polar: Cn unsteady, cn_f does not intersect cn 3 times. Intersections:{}.'.format(xInter))
a_f07_Upp = abs(xInter[0])
a_f07_Low = -abs(xInter[0])

Expand Down Expand Up @@ -1745,6 +1751,8 @@ def _find_linear_region(x, y, nMin, x0=None):
iEnd = j + nMin
if x0 is not None:
sl = np.linalg.lstsq(x[iStart:iEnd], y[iStart:iEnd], rcond=None)[0][0]
if not np.isscalar(sl):
sl = sl[0]
slp[iStart, j] = sl
off[iStart, j] = x0
y_lin = x[iStart:iEnd] * sl
Expand Down
9 changes: 6 additions & 3 deletions openfast_toolbox/airfoils/tests/test_run_Examples.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,17 @@ def test_run_examples(self):
# Add tests to class
MyDir=os.path.dirname(__file__)
files = glob.glob(os.path.join(MyDir,'../examples/[a-zA-Z]*.py'))
import matplotlib.pyplot as plt
print('\n--------------------------------------------------------------')
import matplotlib.pyplot as plt
for f in files:
print('Running example script: {}'.format(f))
print('Running: {}'.format(os.path.relpath(f, MyDir)))
if hasattr(self,'subTest'):
with self.subTest(filename=os.path.basename(f)):
execfile(f, {'__name__': '__test__', 'print': lambda *_:None})
plt.close('all')
try:
plt.close('all')
except:
pass


if __name__ == '__main__':
Expand Down
23 changes: 23 additions & 0 deletions openfast_toolbox/converters/examples/Main_AD30_AD40.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
"""
Converts a AD3.x file to AD4.0
"""
import os
import numpy as np
from openfast_toolbox.converters.versions.aerodyn import ad30_to_ad40

# Get current directory so this script can be called from any location
scriptDir=os.path.dirname(__file__)

fileold = os.path.join(scriptDir, '../../../data/example_files/AeroDyn_v3.0.dat')
filenew = '_aerodyn_temp.dat'

if __name__ == '__main__':
ad = ad30_to_ad40(fileold, filenew, verbose=True, overwrite=False)

if __name__ == '__test__':
ad = ad30_to_ad40(fileold, filenew, verbose=False, overwrite=False)
# small tests
np.testing.assert_equal(ad['Wake_Mod'], 1)
np.testing.assert_equal(ad['UA_Mod'], 3)
np.testing.assert_equal(ad['DBEMT_Mod'], 2)
os.remove(filenew)
Empty file.
Loading

0 comments on commit e1707da

Please sign in to comment.