Skip to content

Commit e1707da

Browse files
authored
Merge pull request #29 from OpenFAST/dev
Merging dev into main
2 parents ed7d9dd + f559029 commit e1707da

36 files changed

+2551
-979
lines changed

.github/workflows/development-pipeline.yml

+3-11
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,6 @@ jobs:
2121
strategy:
2222
matrix:
2323
include:
24-
- os: ubuntu-latest
25-
python-version: 3.7
26-
python: xvfb-run python3
27-
pip_arg: ""
28-
- os: ubuntu-latest
29-
python-version: 3.8
30-
python: xvfb-run python3
31-
pip_arg: ""
3224
- os: ubuntu-latest
3325
python-version: 3.9
3426
python: xvfb-run python3
@@ -41,11 +33,11 @@ jobs:
4133
python-version: 3.12
4234
python: xvfb-run python3
4335
pip_arg: ""
44-
- os: macos-11
45-
python-version: 3.11
36+
- os: macos-13
37+
python-version: 3.12
4638
python: python3
4739
pip_arg: ""
48-
- os: windows-2019
40+
- os: windows-2022
4941
python-version: 3.11
5042
python: python
5143
pip_arg: --user

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -119,3 +119,5 @@ venv.bak/
119119
# Hidding files starting with underscore except init
120120
_*
121121
!__init__.py
122+
*.xml
123+
*.iml

data/example_files/AeroDyn_v3.0.dat

+104
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
------- AERODYN v15 for OpenFAST INPUT FILE -----------------------------------------------
2+
NREL 5.0 MW offshore baseline aerodynamic input properties.
3+
====== General Options ============================================================================
4+
False Echo - Echo the input to "<rootname>.AD.ech"? (flag)
5+
"default" DTAero - Time interval for aerodynamic calculations {or "default"} (s)
6+
2 WakeMod - Type of wake/induction model (switch) {0=none, 1=BEMT, 2=DBEMT, 3=OLAF} [WakeMod cannot be 2 or 3 when linearizing]
7+
2 AFAeroMod - Type of blade airfoil aerodynamics model (switch) {1=steady model, 2=Beddoes-Leishman unsteady model} [AFAeroMod must be 1 when linearizing]
8+
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}
9+
0 TwrShadow - Calculate tower influence on wind based on downstream tower shadow (switch) {0=none, 1=Powles model, 2=Eames model}
10+
False TwrAero - Calculate tower aerodynamic loads? (flag)
11+
False FrozenWake - Assume frozen wake during linearization? (flag) [used only when WakeMod=1 and when linearizing]
12+
False CavitCheck - Perform cavitation check? (flag) [AFAeroMod must be 1 when CavitCheck=true]
13+
False Buoyancy - Include buoyancy effects? (flag)
14+
False CompAA - Flag to compute AeroAcoustics calculation [used only when WakeMod = 1 or 2]
15+
"unused" AA_InputFile - AeroAcoustics input file [used only when CompAA=true]
16+
====== Environmental Conditions ===================================================================
17+
"default" AirDens - Air density (kg/m^3)
18+
"default" KinVisc - Kinematic viscosity of working fluid (m^2/s)
19+
"default" SpdSound - Speed of sound in working fluid (m/s)
20+
"default" Patm - Atmospheric pressure (Pa) [used only when CavitCheck=True]
21+
"default" Pvap - Vapour pressure of working fluid (Pa) [used only when CavitCheck=True]
22+
====== Blade-Element/Momentum Theory Options ====================================================== [unused when WakeMod=0 or 3]
23+
2 SkewMod - Type of skewed-wake correction model (switch) {1=uncoupled, 2=Pitt/Peters, 3=coupled} [unused when WakeMod=0 or 3]
24+
"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]
25+
True TipLoss - Use the Prandtl tip-loss model? (flag) [unused when WakeMod=0 or 3]
26+
True HubLoss - Use the Prandtl hub-loss model? (flag) [unused when WakeMod=0 or 3]
27+
True TanInd - Include tangential induction in BEMT calculations? (flag) [unused when WakeMod=0 or 3]
28+
False AIDrag - Include the drag term in the axial-induction calculation? (flag) [unused when WakeMod=0 or 3]
29+
False TIDrag - Include the drag term in the tangential-induction calculation? (flag) [unused when WakeMod=0,3 or TanInd=FALSE]
30+
"Default" IndToler - Convergence tolerance for BEMT nonlinear solve residual equation {or "default"} (-) [unused when WakeMod=0 or 3]
31+
100 MaxIter - Maximum number of iteration steps (-) [unused when WakeMod=0]
32+
====== Dynamic Blade-Element/Momentum Theory Options ============================================== [used only when WakeMod=2]
33+
2 DBEMT_Mod - Type of dynamic BEMT (DBEMT) model {1=constant tau1, 2=time-dependent tau1} (-) [used only when WakeMod=2]
34+
4 tau1_const - Time constant for DBEMT (s) [used only when WakeMod=2 and DBEMT_Mod=1]
35+
====== OLAF -- cOnvecting LAgrangian Filaments (Free Vortex Wake) Theory Options ================== [used only when WakeMod=3]
36+
"unused" OLAFInputFileName - Input file for OLAF [used only when WakeMod=3]
37+
====== Beddoes-Leishman Unsteady Airfoil Aerodynamics Options ===================================== [used only when AFAeroMod=2]
38+
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]
39+
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]
40+
0.15 UAStartRad - Starting radius for dynamic stall (fraction of rotor radius) [used only when AFAeroMod=2]
41+
1.0 UAEndRad - Ending radius for dynamic stall (fraction of rotor radius) [used only when AFAeroMod=2]
42+
====== Airfoil Information =========================================================================
43+
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} (-)
44+
1 InCol_Alfa - The column in the airfoil tables that contains the angle of attack (-)
45+
2 InCol_Cl - The column in the airfoil tables that contains the lift coefficient (-)
46+
3 InCol_Cd - The column in the airfoil tables that contains the drag coefficient (-)
47+
4 InCol_Cm - The column in the airfoil tables that contains the pitching-moment coefficient; use zero if there is no Cm column (-)
48+
0 InCol_Cpmin - The column in the airfoil tables that contains the Cpmin coefficient; use zero if there is no Cpmin column (-)
49+
8 NumAFfiles - Number of airfoil files used (-)
50+
"../5MW_Baseline/Airfoils/Cylinder1.dat" AFNames - Airfoil file names (NumAFfiles lines) (quoted strings)
51+
"../5MW_Baseline/Airfoils/Cylinder2.dat"
52+
"../5MW_Baseline/Airfoils/DU40_A17.dat"
53+
"../5MW_Baseline/Airfoils/DU35_A17.dat"
54+
"../5MW_Baseline/Airfoils/DU30_A17.dat"
55+
"../5MW_Baseline/Airfoils/DU25_A17.dat"
56+
"../5MW_Baseline/Airfoils/DU21_A17.dat"
57+
"../5MW_Baseline/Airfoils/NACA64_A17.dat"
58+
====== Rotor/Blade Properties =====================================================================
59+
True UseBlCm - Include aerodynamic pitching moment in calculations? (flag)
60+
"../5MW_Baseline/NRELOffshrBsline5MW_AeroDyn_blade.dat" ADBlFile(1) - Name of file containing distributed aerodynamic properties for Blade #1 (-)
61+
"../5MW_Baseline/NRELOffshrBsline5MW_AeroDyn_blade.dat" ADBlFile(2) - Name of file containing distributed aerodynamic properties for Blade #2 (-) [unused if NumBl < 2]
62+
"../5MW_Baseline/NRELOffshrBsline5MW_AeroDyn_blade.dat" ADBlFile(3) - Name of file containing distributed aerodynamic properties for Blade #3 (-) [unused if NumBl < 3]
63+
====== Hub Properties ============================================================================== [used only when Buoyancy=True]
64+
0.0 VolHub - Hub volume (m^3)
65+
0.0 HubCenBx - Hub center of buoyancy x direction offset (m)
66+
====== Nacelle Properties ========================================================================== [used only when Buoyancy=True]
67+
0.0 VolNac - Nacelle volume (m^3)
68+
0,0,0 NacCenB - Position of nacelle center of buoyancy from yaw bearing in nacelle coordinates (m)
69+
====== Tail fin Aerodynamics ========================================================================
70+
False TFinAero - Calculate tail fin aerodynamics model (flag)
71+
"unused" TFinFile - Input file for tail fin aerodynamics [used only when TFinAero=True]
72+
====== Tower Influence and Aerodynamics ============================================================ [used only when TwrPotent/=0, TwrShadow/=0, TwrAero=True, or Buoyancy=True]
73+
12 NumTwrNds - Number of tower nodes used in the analysis (-) [used only when TwrPotent/=0, TwrShadow/=0, TwrAero=True, or Buoyancy=True]
74+
TwrElev TwrDiam TwrCd TwrTI TwrCb !TwrTI used only with TwrShadow=2, TwrCb used only with Buoyancy=True
75+
(m) (m) (-) (-) (-)
76+
0.0000000E+00 6.0000000E+00 1.0000000E+00 1.0000000E-01 0.0
77+
8.5261000E+00 5.7870000E+00 1.0000000E+00 1.0000000E-01 0.0
78+
1.7053000E+01 5.5740000E+00 1.0000000E+00 1.0000000E-01 0.0
79+
2.5579000E+01 5.3610000E+00 1.0000000E+00 1.0000000E-01 0.0
80+
3.4105000E+01 5.1480000E+00 1.0000000E+00 1.0000000E-01 0.0
81+
4.2633000E+01 4.9350000E+00 1.0000000E+00 1.0000000E-01 0.0
82+
5.1158000E+01 4.7220000E+00 1.0000000E+00 1.0000000E-01 0.0
83+
5.9685000E+01 4.5090000E+00 1.0000000E+00 1.0000000E-01 0.0
84+
6.8211000E+01 4.2960000E+00 1.0000000E+00 1.0000000E-01 0.0
85+
7.6738000E+01 4.0830000E+00 1.0000000E+00 1.0000000E-01 0.0
86+
8.5268000E+01 3.8700000E+00 1.0000000E+00 1.0000000E-01 0.0
87+
8.7600000E+01 3.8700000E+00 1.0000000E+00 1.0000000E-01 0.0
88+
====== Outputs ====================================================================================
89+
False SumPrint - Generate a summary file listing input options and interpolated properties to "<rootname>.AD.sum"? (flag)
90+
0 NBlOuts - Number of blade node outputs [0 - 9] (-)
91+
1 BlOutNd - Blade nodes whose values will be output (-)
92+
0 NTwOuts - Number of tower node outputs [0 - 9] (-)
93+
1 TwOutNd - Tower nodes whose values will be output (-)
94+
OutList - The next line(s) contains a list of output parameters. See OutListParameters.xlsx for a listing of available output channels, (-)
95+
"RtAeroPwr"
96+
"RtAeroCp"
97+
"RtAeroCt"
98+
END of input file (the word "END" must appear in the first 3 columns of this last OutList line)
99+
====== Outputs for all blade stations (same ending as above for B1N1.... =========================== [optional section]
100+
0 BldNd_BladesOut - Number of blades to output all node information at. Up to number of blades on turbine. (-)
101+
"All" BldNd_BlOutNd - Future feature will allow selecting a portion of the nodes to output. Not implemented yet. (-)
102+
OutListAD - The next line(s) contains a list of output parameters. See OutListParameters.xlsx for a listing of available output channels, (-)
103+
END of input file (the word "END" must appear in the first 3 columns of this last OutList line)
104+
---------------------------------------------------------------------------------------

openfast_toolbox/airfoils/Polar.py

+15-7
Original file line numberDiff line numberDiff line change
@@ -84,15 +84,18 @@ def __init__(self, filename=None, alpha=None, cl=None, cd=None, cm=None, Re=None
8484
cd = df['Cd'].values
8585
cm = df['Cm'].values
8686
if 'fs' in df.keys():
87-
print('[INFO] Using separating function from input file.')
87+
if verbose:
88+
print('[INFO] Using separating function from input file.')
8889
self.fs = df['fs'].values
8990
self._fs_lock = True
9091
if 'Cl_fs' in df.keys():
91-
print('[INFO] Using Cl fully separated from input file.')
92+
if verbose:
93+
print('[INFO] Using Cl fully separated from input file.')
9294
self.cl_fs =df['Cl_fs'].values
9395
self._cl_fs_lock = True
9496
if 'Cl_inv' in df.keys():
95-
print('[INFO] Using Cl inviscid from input file.')
97+
if verbose:
98+
print('[INFO] Using Cl inviscid from input file.')
9699
self.cl_inv = df['Cl_inv'].values
97100
self._cl_inv_lock = True
98101
# TODO we need a trigger if cl_inv provided, we should get alpha0 and slope from it
@@ -667,7 +670,7 @@ def __getCM(self, i, cmCoef, alpha, cl_ext, cd_ext, alpha_low_deg, alpha_high_de
667670
print("Angle encountered for which there is no CM table value " "(near +/-180 deg). Program will stop.")
668671
return cm_new
669672

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

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

757762
# --- cn slope
@@ -790,7 +795,8 @@ def unsteadyParams(self, window_offset=None, nMin=720):
790795
a_f07_Upp = xInter[2]
791796
a_f07_Low = xInter[0]
792797
else:
793-
print('[WARN] Polar: Cn unsteady, cn_f does not intersect cn 3 times. Intersections:{}.'.format(xInter))
798+
if verbose:
799+
print('[WARN] Polar: Cn unsteady, cn_f does not intersect cn 3 times. Intersections:{}.'.format(xInter))
794800
a_f07_Upp = abs(xInter[0])
795801
a_f07_Low = -abs(xInter[0])
796802

@@ -1745,6 +1751,8 @@ def _find_linear_region(x, y, nMin, x0=None):
17451751
iEnd = j + nMin
17461752
if x0 is not None:
17471753
sl = np.linalg.lstsq(x[iStart:iEnd], y[iStart:iEnd], rcond=None)[0][0]
1754+
if not np.isscalar(sl):
1755+
sl = sl[0]
17481756
slp[iStart, j] = sl
17491757
off[iStart, j] = x0
17501758
y_lin = x[iStart:iEnd] * sl

openfast_toolbox/airfoils/tests/test_run_Examples.py

+6-3
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,17 @@ def test_run_examples(self):
1919
# Add tests to class
2020
MyDir=os.path.dirname(__file__)
2121
files = glob.glob(os.path.join(MyDir,'../examples/[a-zA-Z]*.py'))
22-
import matplotlib.pyplot as plt
2322
print('\n--------------------------------------------------------------')
23+
import matplotlib.pyplot as plt
2424
for f in files:
25-
print('Running example script: {}'.format(f))
25+
print('Running: {}'.format(os.path.relpath(f, MyDir)))
2626
if hasattr(self,'subTest'):
2727
with self.subTest(filename=os.path.basename(f)):
2828
execfile(f, {'__name__': '__test__', 'print': lambda *_:None})
29-
plt.close('all')
29+
try:
30+
plt.close('all')
31+
except:
32+
pass
3033

3134

3235
if __name__ == '__main__':
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
"""
2+
Converts a AD3.x file to AD4.0
3+
"""
4+
import os
5+
import numpy as np
6+
from openfast_toolbox.converters.versions.aerodyn import ad30_to_ad40
7+
8+
# Get current directory so this script can be called from any location
9+
scriptDir=os.path.dirname(__file__)
10+
11+
fileold = os.path.join(scriptDir, '../../../data/example_files/AeroDyn_v3.0.dat')
12+
filenew = '_aerodyn_temp.dat'
13+
14+
if __name__ == '__main__':
15+
ad = ad30_to_ad40(fileold, filenew, verbose=True, overwrite=False)
16+
17+
if __name__ == '__test__':
18+
ad = ad30_to_ad40(fileold, filenew, verbose=False, overwrite=False)
19+
# small tests
20+
np.testing.assert_equal(ad['Wake_Mod'], 1)
21+
np.testing.assert_equal(ad['UA_Mod'], 3)
22+
np.testing.assert_equal(ad['DBEMT_Mod'], 2)
23+
os.remove(filenew)

openfast_toolbox/converters/versions/__init__.py

Whitespace-only changes.

0 commit comments

Comments
 (0)