Skip to content

Commit 9998918

Browse files
committed
AD can handle unique blades
1 parent 6cd4271 commit 9998918

File tree

2 files changed

+96
-56
lines changed

2 files changed

+96
-56
lines changed

openfast_io/openfast_io/FAST_reader.py

+55-35
Original file line numberDiff line numberDiff line change
@@ -182,8 +182,7 @@ def __init__(self):
182182
self.fst_vt['InflowWind'] = {}
183183
self.fst_vt['AeroDyn'] = {}
184184
self.fst_vt['AeroDisk'] = {}
185-
self.fst_vt['AeroDynBlade'] = {}
186-
self.fst_vt['AeroDynPolar'] = {}
185+
self.fst_vt['AeroDynBlade'] = [{}, {}, {}] # One dict per blade, We will reduce this down to one, if all the files are the same
187186
self.fst_vt['ServoDyn'] = {}
188187
self.fst_vt['DISCON_in'] = {}
189188
self.fst_vt['HydroDyn'] = {}
@@ -1225,54 +1224,77 @@ def read_AeroDyn(self):
12251224

12261225
f.close()
12271226

1228-
self.read_AeroDynBlade()
1227+
# Improved handling for multiple AeroDyn blade files
1228+
ad_bld_file1 = os.path.join(self.FAST_directory, self.fst_vt['Fst']['AeroFile_path'], self.fst_vt['AeroDyn']['ADBlFile1'])
1229+
ad_bld_file2 = os.path.join(self.FAST_directory, self.fst_vt['Fst']['AeroFile_path'], self.fst_vt['AeroDyn']['ADBlFile2'])
1230+
ad_bld_file3 = os.path.join(self.FAST_directory, self.fst_vt['Fst']['AeroFile_path'], self.fst_vt['AeroDyn']['ADBlFile3'])
1231+
1232+
if ad_bld_file1 == ad_bld_file2 and ad_bld_file1 == ad_bld_file3:
1233+
# all blades are identical
1234+
self.read_AeroDynBlade(ad_bld_file1, BladeNumber=0)
1235+
# Copy data into the generic AeroDynBlade
1236+
self.fst_vt['AeroDynBlade'] = self.fst_vt['AeroDynBlade'][0]
1237+
elif self.fst_vt['ElastoDyn']['NumBl'] == 2 and ad_bld_file1 == ad_bld_file2:
1238+
# 2 blades are identical
1239+
self.read_AeroDynBlade(ad_bld_file1, BladeNumber=0)
1240+
self.fst_vt['AeroDynBlade'] = self.fst_vt['AeroDynBlade'][0]
1241+
else:
1242+
# all blades are different
1243+
self.read_AeroDynBlade(ad_bld_file1, BladeNumber=0)
1244+
if self.fst_vt['ElastoDyn']['NumBl'] > 1:
1245+
self.read_AeroDynBlade(ad_bld_file2, BladeNumber=1)
1246+
if self.fst_vt['ElastoDyn']['NumBl'] > 2:
1247+
self.read_AeroDynBlade(ad_bld_file3, BladeNumber=2)
1248+
else:
1249+
# we have a single blade
1250+
self.fst_vt['AeroDynBlade'] = self.fst_vt['AeroDynBlade'][0]
1251+
12291252
self.read_AeroDynPolar()
12301253
self.read_AeroDynCoord()
12311254
olaf_filename = os.path.join(self.FAST_directory, self.fst_vt['AeroDyn']['OLAFInputFileName'])
12321255
if os.path.isfile(olaf_filename):
12331256
self.read_AeroDynOLAF(olaf_filename)
12341257

1235-
def read_AeroDynBlade(self):
1258+
def read_AeroDynBlade(self, ad_blade_file, BladeNumber = 0):
12361259
# AeroDyn v5.00 Blade Definition File
12371260

1238-
ad_blade_file = os.path.join(self.FAST_directory, self.fst_vt['Fst']['AeroFile_path'], self.fst_vt['AeroDyn']['ADBlFile1'])
1261+
# ad_blade_file = os.path.join(self.FAST_directory, self.fst_vt['Fst']['AeroFile_path'], self.fst_vt['AeroDyn']['ADBlFile1'])
12391262
f = open(ad_blade_file)
12401263

12411264
f.readline()
12421265
f.readline()
12431266
f.readline()
12441267
# Blade Properties
1245-
self.fst_vt['AeroDynBlade']['NumBlNds'] = int(f.readline().split()[0])
1246-
f.readline()
1247-
f.readline()
1248-
self.fst_vt['AeroDynBlade']['BlSpn'] = [None]*self.fst_vt['AeroDynBlade']['NumBlNds']
1249-
self.fst_vt['AeroDynBlade']['BlCrvAC'] = [None]*self.fst_vt['AeroDynBlade']['NumBlNds']
1250-
self.fst_vt['AeroDynBlade']['BlSwpAC'] = [None]*self.fst_vt['AeroDynBlade']['NumBlNds']
1251-
self.fst_vt['AeroDynBlade']['BlCrvAng'] = [None]*self.fst_vt['AeroDynBlade']['NumBlNds']
1252-
self.fst_vt['AeroDynBlade']['BlTwist'] = [None]*self.fst_vt['AeroDynBlade']['NumBlNds']
1253-
self.fst_vt['AeroDynBlade']['BlChord'] = [None]*self.fst_vt['AeroDynBlade']['NumBlNds']
1254-
self.fst_vt['AeroDynBlade']['BlAFID'] = [None]*self.fst_vt['AeroDynBlade']['NumBlNds']
1255-
self.fst_vt['AeroDynBlade']['BlCb'] = [None]*self.fst_vt['AeroDynBlade']['NumBlNds']
1256-
self.fst_vt['AeroDynBlade']['BlCenBn'] = [None]*self.fst_vt['AeroDynBlade']['NumBlNds']
1257-
self.fst_vt['AeroDynBlade']['BlCenBt'] = [None]*self.fst_vt['AeroDynBlade']['NumBlNds']
1258-
for i in range(self.fst_vt['AeroDynBlade']['NumBlNds']):
1268+
self.fst_vt['AeroDynBlade'][BladeNumber]['NumBlNds'] = int(f.readline().split()[0])
1269+
f.readline()
1270+
f.readline()
1271+
self.fst_vt['AeroDynBlade'][BladeNumber]['BlSpn'] = [None]*self.fst_vt['AeroDynBlade'][BladeNumber]['NumBlNds']
1272+
self.fst_vt['AeroDynBlade'][BladeNumber]['BlCrvAC'] = [None]*self.fst_vt['AeroDynBlade'][BladeNumber]['NumBlNds']
1273+
self.fst_vt['AeroDynBlade'][BladeNumber]['BlSwpAC'] = [None]*self.fst_vt['AeroDynBlade'][BladeNumber]['NumBlNds']
1274+
self.fst_vt['AeroDynBlade'][BladeNumber]['BlCrvAng'] = [None]*self.fst_vt['AeroDynBlade'][BladeNumber]['NumBlNds']
1275+
self.fst_vt['AeroDynBlade'][BladeNumber]['BlTwist'] = [None]*self.fst_vt['AeroDynBlade'][BladeNumber]['NumBlNds']
1276+
self.fst_vt['AeroDynBlade'][BladeNumber]['BlChord'] = [None]*self.fst_vt['AeroDynBlade'][BladeNumber]['NumBlNds']
1277+
self.fst_vt['AeroDynBlade'][BladeNumber]['BlAFID'] = [None]*self.fst_vt['AeroDynBlade'][BladeNumber]['NumBlNds']
1278+
self.fst_vt['AeroDynBlade'][BladeNumber]['BlCb'] = [None]*self.fst_vt['AeroDynBlade'][BladeNumber]['NumBlNds']
1279+
self.fst_vt['AeroDynBlade'][BladeNumber]['BlCenBn'] = [None]*self.fst_vt['AeroDynBlade'][BladeNumber]['NumBlNds']
1280+
self.fst_vt['AeroDynBlade'][BladeNumber]['BlCenBt'] = [None]*self.fst_vt['AeroDynBlade'][BladeNumber]['NumBlNds']
1281+
for i in range(self.fst_vt['AeroDynBlade'][BladeNumber]['NumBlNds']):
12591282
data = [float(val) for val in f.readline().split()]
1260-
self.fst_vt['AeroDynBlade']['BlSpn'][i] = data[0]
1261-
self.fst_vt['AeroDynBlade']['BlCrvAC'][i] = data[1]
1262-
self.fst_vt['AeroDynBlade']['BlSwpAC'][i] = data[2]
1263-
self.fst_vt['AeroDynBlade']['BlCrvAng'][i]= data[3]
1264-
self.fst_vt['AeroDynBlade']['BlTwist'][i] = data[4]
1265-
self.fst_vt['AeroDynBlade']['BlChord'][i] = data[5]
1266-
self.fst_vt['AeroDynBlade']['BlAFID'][i] = data[6]
1283+
self.fst_vt['AeroDynBlade'][BladeNumber]['BlSpn'][i] = data[0]
1284+
self.fst_vt['AeroDynBlade'][BladeNumber]['BlCrvAC'][i] = data[1]
1285+
self.fst_vt['AeroDynBlade'][BladeNumber]['BlSwpAC'][i] = data[2]
1286+
self.fst_vt['AeroDynBlade'][BladeNumber]['BlCrvAng'][i]= data[3]
1287+
self.fst_vt['AeroDynBlade'][BladeNumber]['BlTwist'][i] = data[4]
1288+
self.fst_vt['AeroDynBlade'][BladeNumber]['BlChord'][i] = data[5]
1289+
self.fst_vt['AeroDynBlade'][BladeNumber]['BlAFID'][i] = data[6]
12671290
if len(data) == 9:
1268-
self.fst_vt['AeroDynBlade']['BlCb'][i] = data[7]
1269-
self.fst_vt['AeroDynBlade']['BlCenBn'][i] = data[8]
1270-
self.fst_vt['AeroDynBlade']['BlCenBt'][i] = data[9]
1291+
self.fst_vt['AeroDynBlade'][BladeNumber]['BlCb'][i] = data[7]
1292+
self.fst_vt['AeroDynBlade'][BladeNumber]['BlCenBn'][i] = data[8]
1293+
self.fst_vt['AeroDynBlade'][BladeNumber]['BlCenBt'][i] = data[9]
12711294
else:
1272-
self.fst_vt['AeroDynBlade']['BlCb'][i] = 0.0
1273-
self.fst_vt['AeroDynBlade']['BlCenBn'][i] = 0.0
1274-
self.fst_vt['AeroDynBlade']['BlCenBt'][i] = 0.0
1275-
1295+
self.fst_vt['AeroDynBlade'][BladeNumber]['BlCb'][i] = 0.0
1296+
self.fst_vt['AeroDynBlade'][BladeNumber]['BlCenBn'][i] = 0.0
1297+
self.fst_vt['AeroDynBlade'][BladeNumber]['BlCenBt'][i] = 0.0
12761298

12771299
f.close()
12781300

@@ -3211,8 +3233,6 @@ def execute(self):
32113233
# Copy data to second blade slot
32123234
self.fst_vt['BeamDyn'] = self.fst_vt['BeamDyn'][0]
32133235
self.fst_vt['BeamDynBlade'] = self.fst_vt['BeamDynBlade'][0]
3214-
# Read unique third file
3215-
self.read_BeamDyn(bd_file3, BladeNumber=2)
32163236
else:
32173237
# All blades unique or single blade
32183238
self.read_BeamDyn(bd_file1, BladeNumber=0)

openfast_io/openfast_io/FAST_writer.py

+41-21
Original file line numberDiff line numberDiff line change
@@ -674,9 +674,6 @@ def write_ElastoDynTower(self):
674674
f.close()
675675

676676
def write_BeamDyn(self, bldInd = None):
677-
# self.fst_vt['Fst']['BDBldFile(1)'] = self.FAST_namingOut + '_BeamDyn.dat'
678-
# self.fst_vt['Fst']['BDBldFile(2)'] = self.fst_vt['Fst']['BDBldFile(1)']
679-
# self.fst_vt['Fst']['BDBldFile(3)'] = self.fst_vt['Fst']['BDBldFile(1)']
680677

681678
# if we have bldInd is None,
682679
if bldInd is None:
@@ -887,8 +884,28 @@ def write_InflowWind(self):
887884
def write_AeroDyn(self):
888885
# AeroDyn v15.03
889886

887+
888+
# self.fst_vt['AeroDyn']['ADBlFile1'] = self.FAST_namingOut + '_AeroDyn_blade.dat'
889+
# self.fst_vt['AeroDyn']['ADBlFile2'] = self.fst_vt['AeroDyn']['ADBlFile1']
890+
# self.fst_vt['AeroDyn']['ADBlFile3'] = self.fst_vt['AeroDyn']['ADBlFile1']
891+
# filename = os.path.join(self.FAST_runDirectory, self.fst_vt['AeroDyn']['ADBlFile1'])
892+
893+
894+
890895
# Generate AeroDyn v15 blade input file
891-
self.write_AeroDynBlade()
896+
if isinstance(self.fst_vt['AeroDynBlade'], list):
897+
for i_adBld, adBld in enumerate(self.fst_vt['AeroDynBlade']):
898+
self.fst_vt['AeroDyn']['ADBlFile%d'%(i_adBld+1)] = self.FAST_namingOut + '_AeroDyn_blade_%d.dat'%(i_adBld+1)
899+
self.write_AeroDynBlade(bldInd = i_adBld)
900+
901+
elif isinstance(self.fst_vt['AeroDynBlade'], dict):
902+
self.fst_vt['AeroDyn']['ADBlFile1'] = self.FAST_namingOut + '_AeroDyn_blade.dat'
903+
self.fst_vt['AeroDyn']['ADBlFile2'] = self.fst_vt['AeroDyn']['ADBlFile1']
904+
self.fst_vt['AeroDyn']['ADBlFile3'] = self.fst_vt['AeroDyn']['ADBlFile1']
905+
self.write_AeroDynBlade()
906+
907+
908+
# self.write_AeroDynBlade()
892909

893910
# Generate AeroDyn v15 polars
894911
self.write_AeroDynPolar()
@@ -1037,30 +1054,33 @@ def write_AeroDyn(self):
10371054
os.fsync(f)
10381055
f.close()
10391056

1040-
def write_AeroDynBlade(self):
1041-
# AeroDyn v15.00 Blade
1042-
self.fst_vt['AeroDyn']['ADBlFile1'] = self.FAST_namingOut + '_AeroDyn_blade.dat'
1043-
self.fst_vt['AeroDyn']['ADBlFile2'] = self.fst_vt['AeroDyn']['ADBlFile1']
1044-
self.fst_vt['AeroDyn']['ADBlFile3'] = self.fst_vt['AeroDyn']['ADBlFile1']
1045-
filename = os.path.join(self.FAST_runDirectory, self.fst_vt['AeroDyn']['ADBlFile1'])
1057+
def write_AeroDynBlade(self, bldInd = None):
1058+
1059+
if bldInd is None:
1060+
filename = os.path.join(self.FAST_runDirectory, self.fst_vt['AeroDyn']['ADBlFile1'])
1061+
adBld_dict = self.fst_vt['AeroDynBlade']
1062+
else:
1063+
filename = os.path.join(self.FAST_runDirectory, self.fst_vt['AeroDyn']['ADBlFile%d'%(bldInd+1)])
1064+
adBld_dict = self.fst_vt['AeroDynBlade'][bldInd]
1065+
10461066
f = open(filename, 'w')
10471067

10481068
f.write('------- AERODYN15 BLADE DEFINITION INPUT FILE -------------------------------------\n')
10491069
f.write('Generated with OpenFAST_IO\n')
10501070
f.write('====== Blade Properties =================================================================\n')
1051-
f.write('{:<11d} {:<11} {:}'.format(self.fst_vt['AeroDynBlade']['NumBlNds'], 'NumBlNds', '- Number of blade nodes used in the analysis (-)\n'))
1071+
f.write('{:<11d} {:<11} {:}'.format(adBld_dict['NumBlNds'], 'NumBlNds', '- Number of blade nodes used in the analysis (-)\n'))
10521072
f.write(' BlSpn BlCrvAC BlSwpAC BlCrvAng BlTwist BlChord BlAFID BlCb BlCenBn BlCenBt\n')
10531073
f.write(' (m) (m) (m) (deg) (deg) (m) (-) (-) (m) (m)\n')
1054-
BlSpn = self.fst_vt['AeroDynBlade']['BlSpn']
1055-
BlCrvAC = self.fst_vt['AeroDynBlade']['BlCrvAC']
1056-
BlSwpAC = self.fst_vt['AeroDynBlade']['BlSwpAC']
1057-
BlCrvAng = self.fst_vt['AeroDynBlade']['BlCrvAng']
1058-
BlTwist = self.fst_vt['AeroDynBlade']['BlTwist']
1059-
BlChord = self.fst_vt['AeroDynBlade']['BlChord']
1060-
BlAFID = self.fst_vt['AeroDynBlade']['BlAFID']
1061-
BlCb = self.fst_vt['AeroDynBlade']['BlCb']
1062-
BlCenBn = self.fst_vt['AeroDynBlade']['BlCenBn']
1063-
BlCenBt = self.fst_vt['AeroDynBlade']['BlCenBt']
1074+
BlSpn = adBld_dict['BlSpn']
1075+
BlCrvAC = adBld_dict['BlCrvAC']
1076+
BlSwpAC = adBld_dict['BlSwpAC']
1077+
BlCrvAng = adBld_dict['BlCrvAng']
1078+
BlTwist = adBld_dict['BlTwist']
1079+
BlChord = adBld_dict['BlChord']
1080+
BlAFID = adBld_dict['BlAFID']
1081+
BlCb = adBld_dict['BlCb']
1082+
BlCenBn = adBld_dict['BlCenBn']
1083+
BlCenBt = adBld_dict['BlCenBt']
10641084
for Spn, CrvAC, SwpAC, CrvAng, Twist, Chord, AFID, BlCb, BlCenBn, BlCenBt in zip(BlSpn, BlCrvAC, BlSwpAC, BlCrvAng, BlTwist, BlChord, BlAFID, BlCb, BlCenBn, BlCenBt):
10651085
f.write('{: 2.15e} {: 2.15e} {: 2.15e} {: 2.15e} {: 2.15e} {: 2.15e} {: 8d} {: 2.15e} {: 2.15e} {: 2.15e}\n'.format(Spn, CrvAC, SwpAC, CrvAng, Twist, Chord, int(AFID), BlCb, BlCenBn, BlCenBt))
10661086

0 commit comments

Comments
 (0)