Skip to content

Commit

Permalink
Sync OF4.0 IO changes from WEIS
Browse files Browse the repository at this point in the history
  • Loading branch information
dzalkind committed Sep 24, 2024
1 parent 1e0e78b commit 99d2819
Show file tree
Hide file tree
Showing 3 changed files with 186 additions and 50 deletions.
133 changes: 98 additions & 35 deletions rosco/toolbox/ofTools/fast_io/FAST_reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,23 @@ def readline_filterComments(f):
read = False
return line

def read_array(f,len,array_type=str):
def read_array(f,len,split_val=None,array_type=str):
strings = re.split(',| ',f.readline().strip())
while '' in strings: # remove empties
strings.remove('')

arr = strings[:len] # select len strings
if len is None and split_val is None:
raise Exception('Must have len or split_val to use read_array')

if len is not None:
arr = strings[:len] # select len strings
else:
arr = []
for s in strings:
if s != split_val:
arr.append(s)
else:
break

if array_type==str:
arr = [ar.replace('"','') for ar in arr] # remove quotes and commas
Expand All @@ -46,26 +57,6 @@ def fix_path(name):
new = os.path.join(new, name[i])
return new

def read_array(f,len,array_type=str):
strings = re.split(',| ',f.readline().strip())
while '' in strings: # remove empties
strings.remove('')

arr = strings[:len] # select len strings

if array_type==str:
arr = [ar.replace('"','') for ar in arr] # remove quotes and commas
elif array_type==float:
arr = [float_read(ar) for ar in arr]
elif array_type==int:
arr = [int_read(ar) for ar in arr]
elif array_type==bool:
arr = [bool_read(ar) for ar in arr]
else:
raise Exception(f"read_array with type {str(array_type)} not currently supported")

return arr

def bool_read(text):
# convert true/false strings to boolean
if 'default' in text.lower():
Expand Down Expand Up @@ -125,6 +116,7 @@ def __init__(self):
self.fst_vt['MAP'] = {}
self.fst_vt['BeamDyn'] = {}
self.fst_vt['BeamDynBlade'] = {}
self.fst_vt['WaterKin'] = {}

def set_outlist(self, vartree_head, channel_list):
""" Loop through a list of output channel names, recursively set them to True in the nested outlist dict """
Expand Down Expand Up @@ -379,6 +371,9 @@ def read_ElastoDyn(self, ed_file):
self.fst_vt['ElastoDyn']['PtfmRIner'] = float_read(f.readline().split()[0])
self.fst_vt['ElastoDyn']['PtfmPIner'] = float_read(f.readline().split()[0])
self.fst_vt['ElastoDyn']['PtfmYIner'] = float_read(f.readline().split()[0])
self.fst_vt['ElastoDyn']['PtfmXYIner'] = float_read(f.readline().split()[0])
self.fst_vt['ElastoDyn']['PtfmYZIner'] = float_read(f.readline().split()[0])
self.fst_vt['ElastoDyn']['PtfmXZIner'] = float_read(f.readline().split()[0])

# ElastoDyn Blade (blade_struc)
f.readline()
Expand All @@ -398,6 +393,13 @@ def read_ElastoDyn(self, ed_file):
self.fst_vt['ElastoDyn']['TeetSSSp'] = float_read(f.readline().split()[0])
self.fst_vt['ElastoDyn']['TeetHSSp'] = float_read(f.readline().split()[0])

# Yaw friction
f.readline()
self.fst_vt['ElastoDyn']['YawFrctMod'] = int(f.readline().split()[0])
self.fst_vt['ElastoDyn']['M_CSmax'] = float_read(f.readline().split()[0])
self.fst_vt['ElastoDyn']['M_CD'] = float_read(f.readline().split()[0])
self.fst_vt['ElastoDyn']['sig_v'] = float_read(f.readline().split()[0])

# Drivetrain (drivetrain)
f.readline()
self.fst_vt['ElastoDyn']['GBoxEff'] = float_read(f.readline().split()[0])
Expand Down Expand Up @@ -853,13 +855,12 @@ def read_AeroDyn15(self):
self.fst_vt['AeroDyn15']['Echo'] = bool_read(f.readline().split()[0])
self.fst_vt['AeroDyn15']['DTAero'] = float_read(f.readline().split()[0])
self.fst_vt['AeroDyn15']['WakeMod'] = int(f.readline().split()[0])
self.fst_vt['AeroDyn15']['AFAeroMod'] = int(f.readline().split()[0])
self.fst_vt['AeroDyn15']['TwrPotent'] = int(f.readline().split()[0])
self.fst_vt['AeroDyn15']['TwrShadow'] = int(f.readline().split()[0])
self.fst_vt['AeroDyn15']['TwrAero'] = bool_read(f.readline().split()[0])
self.fst_vt['AeroDyn15']['FrozenWake'] = bool_read(f.readline().split()[0])
self.fst_vt['AeroDyn15']['CavitCheck'] = bool_read(f.readline().split()[0])
self.fst_vt['AeroDyn15']['Buoyancy'] = bool_read(f.readline().split()[0])
self.fst_vt['AeroDyn15']['NacelleDrag'] = bool_read(f.readline().split()[0])
self.fst_vt['AeroDyn15']['CompAA'] = bool_read(f.readline().split()[0])
self.fst_vt['AeroDyn15']['AA_InputFile'] = f.readline().split()[0]

Expand All @@ -872,17 +873,29 @@ def read_AeroDyn15(self):
self.fst_vt['AeroDyn15']['Pvap'] = float_read(f.readline().split()[0])
#self.fst_vt['AeroDyn15']['FluidDepth'] = float_read(f.readline().split()[0])

f.readline()
self.fst_vt['AeroDyn15']['BEM_Mod'] = int(f.readline().split()[0])

# Blade-Element/Momentum Theory Options
f.readline()
self.fst_vt['AeroDyn15']['SkewMod'] = int_read(f.readline().split()[0])
self.fst_vt['AeroDyn15']['SkewModFactor'] = float_read(f.readline().split()[0])
self.fst_vt['AeroDyn15']['SkewMod'] = int_read(f.readline().split()[0])
self.fst_vt['AeroDyn15']['SkewMomCorr'] = bool_read(f.readline().split()[0])
self.fst_vt['AeroDyn15']['SkewRedistr_Mod'] = int_read(f.readline().split()[0])
self.fst_vt['AeroDyn15']['SkewRedistrFactor'] = float_read(f.readline().split()[0])
f.readline()
self.fst_vt['AeroDyn15']['TipLoss'] = bool_read(f.readline().split()[0])
self.fst_vt['AeroDyn15']['HubLoss'] = bool_read(f.readline().split()[0])
self.fst_vt['AeroDyn15']['TanInd'] = bool_read(f.readline().split()[0])
self.fst_vt['AeroDyn15']['AIDrag'] = bool_read(f.readline().split()[0])
self.fst_vt['AeroDyn15']['TIDrag'] = bool_read(f.readline().split()[0])
self.fst_vt['AeroDyn15']['IndToler'] = float_read(f.readline().split()[0])
self.fst_vt['AeroDyn15']['MaxIter'] = int(f.readline().split()[0])
f.readline()
self.fst_vt['AeroDyn15']['SectAvg'] = bool_read(f.readline().split()[0])
self.fst_vt['AeroDyn15']['SectAvgWeighting'] = int_read(f.readline().split()[0])
self.fst_vt['AeroDyn15']['SectAvgNPoints'] = int_read(f.readline().split()[0])
self.fst_vt['AeroDyn15']['SectAvgPsiBwd'] = float_read(f.readline().split()[0])
self.fst_vt['AeroDyn15']['SectAvgPsiFwd'] = float_read(f.readline().split()[0])


# Dynamic Blade-Element/Momentum Theory Options
Expand All @@ -896,6 +909,7 @@ def read_AeroDyn15(self):

# Beddoes-Leishman Unsteady Airfoil Aerodynamics Options
f.readline()
self.fst_vt['AeroDyn15']['AoA34'] = bool_read(f.readline().split()[0])
self.fst_vt['AeroDyn15']['UAMod'] = int(f.readline().split()[0])
self.fst_vt['AeroDyn15']['FLookup'] = bool_read(f.readline().split()[0])

Expand Down Expand Up @@ -943,6 +957,9 @@ def read_AeroDyn15(self):
self.fst_vt['AeroDyn15']['VolNac'] = float_read(f.readline().split()[0])
# data = [float(val) for val in f.readline().split(',')]
self.fst_vt['AeroDyn15']['NacCenB'] = [idx.strip() for idx in f.readline().split('NacCenB')[0].split(',')]
self.fst_vt['AeroDyn15']['NacArea'] = [idx.strip() for idx in f.readline().split('NacArea')[0].split(',')]
self.fst_vt['AeroDyn15']['NacCd'] = [idx.strip() for idx in f.readline().split('NacCd')[0].split(',')]
self.fst_vt['AeroDyn15']['NacDragAC'] = [idx.strip() for idx in f.readline().split('NacDragAC')[0].split(',')]
f.readline()
self.fst_vt['AeroDyn15']['TFinAero'] = bool_read(f.readline().split()[0])
tfa_filename = fix_path(f.readline().split()[0])[1:-1]
Expand Down Expand Up @@ -1570,7 +1587,10 @@ def read_StC(self,filename):
'''
StC_vt = {}

with open(os.path.join(self.FAST_directory, filename)) as f:
# Relative to ServoDyn?
SvD_dir = os.path.dirname(self.fst_vt['Fst']['ServoFile'])

with open(os.path.join(self.FAST_directory, SvD_dir, filename)) as f:

f.readline()
f.readline()
Expand Down Expand Up @@ -1734,6 +1754,12 @@ def read_HydroDyn(self, hd_file):
self.fst_vt['HydroDyn']['ExctnMod'] = int_read(f.readline().split()[0])
self.fst_vt['HydroDyn']['ExctnDisp'] = int_read(f.readline().split()[0])
self.fst_vt['HydroDyn']['ExctnCutOff'] = int_read(f.readline().split()[0])

self.fst_vt['HydroDyn']['PtfmYMod'] = int_read(f.readline().split()[0])
self.fst_vt['HydroDyn']['PtfmRefY'] = float_read(f.readline().split()[0])
self.fst_vt['HydroDyn']['PtfmYCutOff'] = float_read(f.readline().split()[0])
self.fst_vt['HydroDyn']['NExctnHdg'] = int_read(f.readline().split()[0])

self.fst_vt['HydroDyn']['RdtnMod'] = int_read(f.readline().split()[0])
self.fst_vt['HydroDyn']['RdtnTMax'] = float_read(f.readline().split()[0])
self.fst_vt['HydroDyn']['RdtnDT'] = float_read(f.readline().split()[0])
Expand Down Expand Up @@ -2279,7 +2305,7 @@ def read_SubDyn(self, sd_file):
self.fst_vt['SubDyn']['MPropSetID1'] = [None]*self.fst_vt['SubDyn']['NMembers']
self.fst_vt['SubDyn']['MPropSetID2'] = [None]*self.fst_vt['SubDyn']['NMembers']
self.fst_vt['SubDyn']['MType'] = [None]*self.fst_vt['SubDyn']['NMembers']
self.fst_vt['SubDyn']['COSMID'] = [None]*self.fst_vt['SubDyn']['NMembers']
self.fst_vt['SubDyn']['M_COSMID'] = [None]*self.fst_vt['SubDyn']['NMembers']
ln = f.readline().split()
ln = f.readline().split()
for i in range(self.fst_vt['SubDyn']['NMembers']):
Expand All @@ -2291,7 +2317,7 @@ def read_SubDyn(self, sd_file):
self.fst_vt['SubDyn']['MPropSetID2'][i] = int(ln[4])
self.fst_vt['SubDyn']['MType'][i] = int(ln[5])
if len(ln) > 6:
self.fst_vt['SubDyn']['COSMID'][i] = int(ln[6])
self.fst_vt['SubDyn']['M_COSMID'][i] = int(ln[6])
f.readline()
# MEMBER X-SECTION PROPERTY data 1/2
self.fst_vt['SubDyn']['NPropSets'] = int_read(f.readline().split()[0])
Expand Down Expand Up @@ -2380,7 +2406,7 @@ def read_SubDyn(self, sd_file):
f.readline()
for i in range(self.fst_vt['SubDyn']['NSpringPropSets']):
ln = f.readline().split()
self.fst_vt['SubDyn']['PropSetID'] = int(ln[0])
self.fst_vt['SubDyn']['SpringPropSetID'][i] = int(ln[0])
for j, sl in enumerate(spring_list):
self.fst_vt['SubDyn'][sl][i] = ln[j+1]

Expand Down Expand Up @@ -2443,8 +2469,18 @@ def read_SubDyn(self, sd_file):
f.readline()
# OUTPUT
self.fst_vt['SubDyn']['SumPrint'] = bool_read(f.readline().split()[0])
self.fst_vt['SubDyn']['OutCBModes'] = int_read(f.readline().split()[0])
self.fst_vt['SubDyn']['OutFEMModes'] = int_read(f.readline().split()[0])
file_pos = f.tell()
line = f.readline()
if 'OutCBModes' in line:
self.fst_vt['SubDyn']['OutCBModes'] = int_read(line.split()[0])
else:
f.seek(file_pos)
file_pos = f.tell()
line = f.readline()
if 'OutFEMModes' in line:
self.fst_vt['SubDyn']['OutFEMModes'] = int_read(line.split()[0])
else:
f.seek(file_pos)
self.fst_vt['SubDyn']['OutCOSM'] = bool_read(f.readline().split()[0])
self.fst_vt['SubDyn']['OutAll'] = bool_read(f.readline().split()[0])
self.fst_vt['SubDyn']['OutSwtch'] = int_read(f.readline().split()[0])
Expand Down Expand Up @@ -2721,8 +2757,8 @@ def read_MoorDyn(self, moordyn_file):
while data_line[0] and data_line[0][:3] != '---': # OpenFAST searches for ---, so we'll do the same
self.fst_vt['MoorDyn']['Line_ID'].append(int(data_line[0]))
self.fst_vt['MoorDyn']['LineType'].append(str(data_line[1]))
self.fst_vt['MoorDyn']['AttachA'].append(int(data_line[2]))
self.fst_vt['MoorDyn']['AttachB'].append(int(data_line[3]))
self.fst_vt['MoorDyn']['AttachA'].append(str(data_line[2]))
self.fst_vt['MoorDyn']['AttachB'].append(str(data_line[3]))
self.fst_vt['MoorDyn']['UnstrLen'].append(float(data_line[4]))
self.fst_vt['MoorDyn']['NumSegs'].append(int(data_line[5]))
self.fst_vt['MoorDyn']['Outputs'].append(str(data_line[6]))
Expand Down Expand Up @@ -2771,7 +2807,7 @@ def read_MoorDyn(self, moordyn_file):

self.fst_vt['MoorDyn']['options'].append(option_name)
if option_name in string_options:
self.fst_vt['MoorDyn'][option_name] = raw_value
self.fst_vt['MoorDyn'][option_name] = raw_value.strip('"')
else:
self.fst_vt['MoorDyn'][option_name] = float(raw_value)

Expand All @@ -2785,6 +2821,33 @@ def read_MoorDyn(self, moordyn_file):
f.close()
break

if 'WaterKin' in self.fst_vt['MoorDyn']['options']:
WaterKin_file = os.path.normpath(os.path.join(os.path.dirname(moordyn_file), self.fst_vt['MoorDyn']['WaterKin']))
self.read_WaterKin(WaterKin_file)

def read_WaterKin(self,WaterKin_file):
print('here')

f = open(WaterKin_file)
f.readline()
f.readline()
f.readline()

self.fst_vt['WaterKin']['WaveKinMod'] = int_read(f.readline().split()[0])
self.fst_vt['WaterKin']['WaveKinFile'] = f.readline().split()[0] # Will want to update this somehow with wave elevation
self.fst_vt['WaterKin']['dtWave'] = float_read(f.readline().split()[0])
self.fst_vt['WaterKin']['WaveDir'] = float_read(f.readline().split()[0])
self.fst_vt['WaterKin']['X_Type'] = int_read(f.readline().split()[0])
self.fst_vt['WaterKin']['X_Grid'] = read_array(f,None,split_val='-',array_type=float)
# re.split(',| ',f.readline().strip())
self.fst_vt['WaterKin']['Y_Type'] = int_read(f.readline().split()[0])
self.fst_vt['WaterKin']['Y_Grid'] = read_array(f,None,split_val='-',array_type=float)
self.fst_vt['WaterKin']['Z_Type'] = int_read(f.readline().split()[0])
self.fst_vt['WaterKin']['Z_Grid'] = read_array(f,None,split_val='-',array_type=float)
f.readline()
self.fst_vt['WaterKin']['CurrentMod'] = int_read(f.readline().split()[0])
f.close()

def execute(self):

self.read_MainInput()
Expand Down
13 changes: 9 additions & 4 deletions rosco/toolbox/ofTools/fast_io/FAST_wrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,13 @@ def __init__(self, **kwargs):
self.FAST_exe = None # Path to executable
self.FAST_InputFile = None # FAST input file (ext=.fst)
self.FAST_directory = None # Path to fst directory files
self.write_stdout = False

# Optional population class attributes from key word arguments
for k, w in kwargs.items():
try:
setattr(self, k, w)
except:
except Exception:
pass

super(FAST_wrapper, self).__init__()
Expand All @@ -28,9 +29,8 @@ def execute(self):
try:
if platform.system()!='Windows' and self.FAST_exe[-4:]=='.exe':
self.FAST_exe = self.FAST_exe[:-4]
except:
except Exception:
pass

exec_str = []
exec_str.append(self.FAST_exe)
exec_str.append(self.FAST_InputFile)
Expand All @@ -42,7 +42,12 @@ def execute(self):
start = time.time()
while run_idx < 2:
try:
subprocess.run(exec_str, check=True)
if self.write_stdout:
print(f'Running {" ".join(exec_str)}')
with open(self.input_file.replace('.fst','.stdOut'), "w") as f:
subprocess.run(exec_str,stdout=f, stderr=subprocess.STDOUT, check=True)
else:
subprocess.run(exec_str, check=True)
failed = False
run_idx = 2
except subprocess.CalledProcessError as e:
Expand Down
Loading

0 comments on commit 99d2819

Please sign in to comment.