Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/dev' into f/ff
Browse files Browse the repository at this point in the history
  • Loading branch information
rthedin committed Jan 14, 2025
2 parents c5ea64e + ce9a6d2 commit a87e535
Show file tree
Hide file tree
Showing 7 changed files with 396 additions and 42 deletions.
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)
---------------------------------------------------------------------------------------
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.
138 changes: 138 additions & 0 deletions openfast_toolbox/converters/versions/aerodyn.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
from openfast_toolbox.io.fast_input_file import FASTInputFile

def ad30_to_ad40(fileold, filenew=None, verbose=True, overwrite=False):
"""
Convert AD 3.0 file to AD 4.0
NOTE: beta version.
INPUTS:
- fileold: filepath to old input file
- filenew: filepath to new input file (can be the same as old)
If None, and overwrite is false, a file with '_new' is written
- overwrite: if True, filenew = fileold
"""
if filenew is None:
if overwrite:
filenew = fileold
else:
filenew = fileold[:-4]+'_new.dat'
if verbose:
print('> Converting:', fileold)
print('> to :', filenew)
# ---
f = FASTInputFile(fileold, IComment=[1])

# --- Checking if conversion already done
try:
iExisting = [f.getID('Wake_Mod'), f.getID('BEM_Mod'), f.getID('Skew_Mod'), f.getID('SectAvg'), f.getID('AoA34')]
print('[WARN] File already converted, skipping: ', fileold)
# We still write
f.write(filenew)
return
except KeyError:
pass

# --- Extracting old data
iSkewMod = f.getID('SkewMod')
WakeMod = f.pop('WakeMod')['value']
SkewMod = f.pop('SkewMod')['value']
AFAeroMod = f.pop('AFAeroMod')['value']
UAMod = f.pop('UAMod')['value']
FrozenWake = f.pop('FrozenWake')['value']
DBEMTMod = f.pop('DBEMT_Mod')['value']
SkewModFactor = f.pop('SkewModFactor')['value']

# --- Default
BEM_Mod = 1
DBEMT_Mod = 0
AoA34 = True
SectAvg = False
SectAvgWeighting = 1
SectAvgNPoints = 'default'
Skew_Mod = 0
SkewMomCorr = False
SkewRedistr_Mod = 1
AoA34 = False
UA_Mod = 0

# --- Logic
Wake_Mod = {None:1, 0:0, 1:1, 2:1, 3:3}[WakeMod]
Skew_Mod = {None:1, 0:-1, 1:0, 2:1}[SkewMod]
UA_Mod = {None:0, 1:0, 2:UAMod}[AFAeroMod]
if WakeMod==1:
DBEMT_Mod=0
BEM_Mod=1
if WakeMod==2:
DBEMT_Mod = DBEMTMod
if FrozenWake is not None and FrozenWake:
DBEMT_Mod=-1
AoA34 = UA_Mod>0 # Legacy behavior if UA is on, use AoA34, if it's off use AoA QC


# --- Changing file
f.data[0]['value'] = '------- AERODYN INPUT FILE --------------------------------------------------------------------------'
# f.data[1]['isComment'] = True
# f.data[1]['value'] = (str(f.data[1]['value']) +' '+ str(f.data[1]['label']) + ' '+ str(f.data[1]['descr'])).strip()
f.insertKeyValAfter('DTAero', 'Wake_Mod', Wake_Mod, 'Wake/induction model (switch) {0=none, 1=BEMT, 3=OLAF} [WakeMod cannot be 2 or 3 when linearizing]')

#i = f.getID('Pvap') # NOTE might not exist for old files..
i = f.getID('TipLoss')-2
f.pop(i+1) # Remove 'BEMT comment'
f.insertComment(i+1,'====== Blade-Element/Momentum Theory Options ====================================================== [unused when WakeMod=0 or 3, except for BEM_Mod]')
f.insertKeyVal (i+2, 'BEM_Mod', BEM_Mod, 'BEM model {1=legacy NoSweepPitchTwist, 2=polar} (switch) [used for all Wake_Mod to determine output coordinate system]')
f.insertComment(i+3, '--- Skew correction')
f.insertKeyVal (i+4, 'Skew_Mod' , Skew_Mod ,'Skew model {0=No skew model, -1=Remove non-normal component for linearization, 1=skew model active}')
f.insertKeyVal (i+5, 'SkewMomCorr' , False ,'Turn the skew momentum correction on or off [used only when Skew_Mod=1]')
f.insertKeyVal (i+6, 'SkewRedistr_Mod' , 'default' ,'Type of skewed-wake correction model (switch) {0=no redistribution, 1=Glauert/Pitt/Peters, default=1} [used only when Skew_Mod=1]')
f.insertKeyVal (i+7, 'SkewRedistrFactor', SkewModFactor,'Constant used in Pitt/Peters skewed wake model {or "default" is 15/32*pi} (-) [used only when Skew_Mod=1 and SkewRedistr_Mod=1]')
f.insertComment(i+8, '--- BEM algorithm ')

i = f.getID('MaxIter')
f.pop(i+1) # Remove 'DBEMT comment'
f.insertComment(i+1, '--- Shear correction')
f.insertKeyVal(i+2, 'SectAvg' , SectAvg , 'Use sector averaging (flag)')
f.insertKeyVal(i+3, 'SectAvgWeighting' , SectAvgWeighting , 'Weighting function for sector average {1=Uniform, default=1} within a sector centered on the blade (switch) [used only when SectAvg=True] ')
f.insertKeyVal(i+4, 'SectAvgNPoints' , SectAvgNPoints , 'Number of points per sectors (-) {default=5} [used only when SectAvg=True] ')
f.insertKeyVal(i+5, 'SectAvgPsiBwd' , 'default' , 'Backward azimuth relative to blade where the sector starts (<=0) {default=-60} (deg) [used only when SectAvg=True]')
f.insertKeyVal(i+6, 'SectAvgPsiFwd' , 'default' , 'Forward azimuth relative to blade where the sector ends (>=0) {default=60} (deg) [used only when SectAvg=True]')
f.insertComment(i+7, '--- Dynamic wake/inflow')
f.insertKeyVal (i+8, 'DBEMT_Mod', DBEMT_Mod, 'Type of dynamic BEMT (DBEMT) model {0=No Dynamic Wake, -1=Frozen Wake for linearization, 1:constant tau1, 2=time-dependent tau1, 3=constant tau1 with continuous formulation} (-)')
f.data[f.getID('tau1_const')]['descr']= 'Time constant for DBEMT (s) [used only when DBEMT_Mod=1 or 3]'

#i = f.getID('OLAFInputFileName')
i = f.getID('FLookup')-2
f.pop(i+1) # Remove 'BEDDOES comment'
f.insertComment(i+1, '====== Unsteady Airfoil Aerodynamics Options ====================================================')
f.insertKeyVal (i+2, 'AoA34' , AoA34, 'Sample the angle of attack (AoA) at the 3/4 chord or the AC point {default=True} [always used]')
f.insertKeyVal (i+3, 'UA_Mod', 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}')
if verbose:
print(' -------------- New AeroDyn inputs (with new meaning):')
print('Wake_Mod : {}'.format(Wake_Mod ))
print('BEM_Mod : {}'.format(BEM_Mod ))
print('SectAvg : {}'.format(SectAvg ))
print('SectAvgWeighting : {}'.format(SectAvgWeighting ))
print('SectAvgNPoints : {}'.format(SectAvgNPoints ))
print('DBEMT_Mod : {}'.format(DBEMT_Mod ))
print('Skew_Mod : {}'.format(Skew_Mod ))
print('SkewMomCorr : {}'.format(SkewMomCorr ))
print('SkewRedistr_Mod : {}'.format(SkewRedistr_Mod ))
print('AoA34 : {}'.format(AoA34 ))
print('UA_Mod : {}'.format(UA_Mod ))
print('--------------- Old AeroDyn inputs:')
print('WakeMod: {}'.format(WakeMod))
print('SkewMod: {}'.format(SkewMod))
print('AFAeroMod: {}'.format(AFAeroMod))
print('FrozenWake:{}'.format(FrozenWake))
print('DBEMT_Mod {}'.format(DBEMTMod))
print('UAMod: {}'.format(UAMod))
print('-----------------------------------------------------')

# --- Write new file
f.write(filenew)
return f


if __name__ == '__main__':
fileold='C:/W0/Work-Old/2018-NREL/BAR-Cone-BEM/openfast-ad-neo/reg_tests/r-test/modules/aerodyn/py_ad_B1n2_OLAF/AD_old.dat'
filenew='C:/W0/Work-Old/2018-NREL/BAR-Cone-BEM/openfast-ad-neo/reg_tests/r-test/modules/aerodyn/py_ad_B1n2_OLAF/AD_conv.dat'
ad30_to_ad40(fileold, filenew)
Loading

0 comments on commit a87e535

Please sign in to comment.