From c94e789b66e3346c5243de72531df22521838896 Mon Sep 17 00:00:00 2001 From: Mayank Chetan Date: Mon, 5 Aug 2024 22:21:58 +0000 Subject: [PATCH 001/161] update openfast_io to dev, add working main for reader & writer --- openfast_python/openfast_io/FAST_reader.py | 909 +- openfast_python/openfast_io/FAST_vars_out.py | 8948 ++++++----------- openfast_python/openfast_io/FAST_writer.py | 415 +- .../openfast_io/create_output_vars.py | 8 +- 4 files changed, 4069 insertions(+), 6211 deletions(-) diff --git a/openfast_python/openfast_io/FAST_reader.py b/openfast_python/openfast_io/FAST_reader.py index f9e909d72..7503fa7f7 100644 --- a/openfast_python/openfast_io/FAST_reader.py +++ b/openfast_python/openfast_io/FAST_reader.py @@ -21,20 +21,23 @@ def readline_filterComments(f): read = False return line -def fix_path(name): - """ split a path, then reconstruct it using os.path.join """ - name = re.split("\\\|/", name) - new = name[0] - for i in range(1,len(name)): - new = os.path.join(new, name[i]) - return new - -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 @@ -49,6 +52,14 @@ def read_array(f,len,array_type=str): return arr +def fix_path(name): + """ split a path, then reconstruct it using os.path.join """ + name = re.split("\\\|/", name) + new = name[0] + for i in range(1,len(name)): + new = os.path.join(new, name[i]) + return new + def bool_read(text): # convert true/false strings to boolean if 'default' in text.lower(): @@ -102,11 +113,13 @@ def __init__(self): self.fst_vt['ServoDyn'] = {} self.fst_vt['DISCON_in'] = {} self.fst_vt['HydroDyn'] = {} + self.fst_vt['SeaState'] = {} self.fst_vt['MoorDyn'] = {} self.fst_vt['SubDyn'] = {} 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 """ @@ -133,6 +146,24 @@ def loop_dict(vartree, search_var, branch): var = var.replace(' ', '') loop_dict(vartree_head, var, []) + def read_outlist(self,f,module): + ''' + Replacement for set_outlist that doesn't care about whether the channel is in the outlist vartree + Easier, but riskier because OpenFAST can crash + + Inputs: f - file handle + module - of OpenFAST, e.g. SubDyn, SeaState (these modules use this) + ''' + data = f.readline() + while data.split()[0] != 'END': + pattern = r'"(.*?)"' # grab only the text between quotes + data = re.findall(pattern, data)[0] + channels = data.split(',') # split on commas + channels = [c.strip() for c in channels] # strip whitespace + for c in channels: + self.fst_vt['outlist'][module][c] = True + data = f.readline() + def read_MainInput(self): # Main FAST v8.16-v8.17 Input File # Currently no differences between FASTv8.16 and OpenFAST. @@ -160,6 +191,7 @@ def read_MainInput(self): self.fst_vt['Fst']['CompInflow'] = int(f.readline().split()[0]) self.fst_vt['Fst']['CompAero'] = int(f.readline().split()[0]) self.fst_vt['Fst']['CompServo'] = int(f.readline().split()[0]) + self.fst_vt['Fst']['CompSeaState'] = int(f.readline().split()[0]) self.fst_vt['Fst']['CompHydro'] = int(f.readline().split()[0]) self.fst_vt['Fst']['CompSub'] = int(f.readline().split()[0]) self.fst_vt['Fst']['CompMooring'] = int(f.readline().split()[0]) @@ -187,6 +219,7 @@ def read_MainInput(self): self.fst_vt['Fst']['InflowFile'] = f.readline().split()[0][1:-1] self.fst_vt['Fst']['AeroFile'] = f.readline().split()[0][1:-1] self.fst_vt['Fst']['ServoFile'] = f.readline().split()[0][1:-1] + self.fst_vt['Fst']['SeaState'] = f.readline().split()[0][1:-1] self.fst_vt['Fst']['HydroFile'] = f.readline().split()[0][1:-1] self.fst_vt['Fst']['SubFile'] = f.readline().split()[0][1:-1] self.fst_vt['Fst']['MooringFile'] = f.readline().split()[0][1:-1] @@ -212,8 +245,8 @@ def read_MainInput(self): self.fst_vt['Fst']['TrimGain'] = f.readline().split()[0] self.fst_vt['Fst']['Twr_Kdmp'] = f.readline().split()[0] self.fst_vt['Fst']['Bld_Kdmp'] = f.readline().split()[0] - self.fst_vt['Fst']['NLinTimes'] = f.readline().split()[0] - self.fst_vt['Fst']['LinTimes'] = re.findall(r'[^,\s]+', f.readline())[0:2] + self.fst_vt['Fst']['NLinTimes'] = int(f.readline().split()[0]) + self.fst_vt['Fst']['LinTimes'] = read_array(f, self.fst_vt['Fst']['NLinTimes'], float) self.fst_vt['Fst']['LinInputs'] = f.readline().split()[0] self.fst_vt['Fst']['LinOutputs'] = f.readline().split()[0] self.fst_vt['Fst']['LinOutJac'] = f.readline().split()[0] @@ -341,6 +374,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() @@ -360,6 +396,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]) @@ -387,17 +430,13 @@ def read_ElastoDyn(self, ed_file): self.fst_vt['ElastoDyn']['DecFact'] = int(f.readline().split()[0]) self.fst_vt['ElastoDyn']['NTwGages'] = int(f.readline().split()[0]) if self.fst_vt['ElastoDyn']['NTwGages'] != 0: #loop over elements if there are gauges to be added, otherwise assign directly - self.fst_vt['ElastoDyn']['TwrGagNd'] = f.readline().strip().split()[:self.fst_vt['ElastoDyn']['NTwGages']] - for i, bldgag in enumerate(self.fst_vt['ElastoDyn']['TwrGagNd']): - self.fst_vt['ElastoDyn']['TwrGagNd'][i] = int(bldgag.strip(',')) + self.fst_vt['ElastoDyn']['TwrGagNd'] = read_array(f,self.fst_vt['ElastoDyn']['NTwGages'],int) else: self.fst_vt['ElastoDyn']['TwrGagNd'] = 0 f.readline() self.fst_vt['ElastoDyn']['NBlGages'] = int(f.readline().split()[0]) if self.fst_vt['ElastoDyn']['NBlGages'] != 0: - self.fst_vt['ElastoDyn']['BldGagNd'] = f.readline().strip().split()[:self.fst_vt['ElastoDyn']['NBlGages']] - for i, bldgag in enumerate(self.fst_vt['ElastoDyn']['BldGagNd']): - self.fst_vt['ElastoDyn']['BldGagNd'][i] = int(bldgag.strip(',')) + self.fst_vt['ElastoDyn']['BldGagNd'] = read_array(f,self.fst_vt['ElastoDyn']['NBlGages'],int) else: self.fst_vt['ElastoDyn']['BldGagNd'] = 0 f.readline() @@ -819,11 +858,9 @@ 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']['CompAA'] = bool_read(f.readline().split()[0]) @@ -838,10 +875,16 @@ 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]) @@ -849,6 +892,12 @@ def read_AeroDyn15(self): 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 @@ -862,6 +911,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]) @@ -1646,7 +1696,7 @@ def read_StC(self,filename): return StC_vt def read_DISCON_in(self): - # Read the Bladed style Interface controller input file, intended for ROSCO https://github.com/NREL/rosco.toolbox + # Read the Bladed style Interface controller input file, intended for ROSCO https://github.com/NREL/ROSCO_toolbox discon_in_file = os.path.normpath(os.path.join(self.FAST_directory, self.fst_vt['ServoDyn']['DLL_InFile'])) @@ -1656,7 +1706,8 @@ def read_DISCON_in(self): self.fst_vt['DISCON_in'] = read_DISCON(discon_in_file) # Some additional filename parsing - self.fst_vt['DISCON_in']['PerfFileName'] = os.path.abspath(os.path.join(self.FAST_directory, self.fst_vt['DISCON_in']['PerfFileName'])) + discon_dir = os.path.dirname(discon_in_file) + self.fst_vt['DISCON_in']['PerfFileName'] = os.path.abspath(os.path.join(discon_dir, self.fst_vt['DISCON_in']['PerfFileName'])) # Try to read rotor performance data if it is available try: @@ -1692,74 +1743,31 @@ def read_HydroDyn(self, hd_file): f.readline() self.fst_vt['HydroDyn']['Echo'] = bool_read(f.readline().split()[0]) - # ENVIRONMENTAL CONDITIONS - f.readline() - self.fst_vt['HydroDyn']['WtrDens'] = float_read(f.readline().split()[0]) - self.fst_vt['HydroDyn']['WtrDpth'] = float_read(f.readline().split()[0]) - self.fst_vt['HydroDyn']['MSL2SWL'] = float_read(f.readline().split()[0]) - - # WAVES - f.readline() - self.fst_vt['HydroDyn']['WaveMod'] = int_read(f.readline().split()[0]) - self.fst_vt['HydroDyn']['WaveStMod'] = int_read(f.readline().split()[0]) - self.fst_vt['HydroDyn']['WaveTMax'] = float_read(f.readline().split()[0]) - self.fst_vt['HydroDyn']['WaveDT'] = float_read(f.readline().split()[0]) - self.fst_vt['HydroDyn']['WaveHs'] = float_read(f.readline().split()[0]) - self.fst_vt['HydroDyn']['WaveTp'] = float_read(f.readline().split()[0]) - self.fst_vt['HydroDyn']['WavePkShp'] = float_read(f.readline().split()[0]) # default - self.fst_vt['HydroDyn']['WvLowCOff'] = float_read(f.readline().split()[0]) - self.fst_vt['HydroDyn']['WvHiCOff'] = float_read(f.readline().split()[0]) - self.fst_vt['HydroDyn']['WaveDir'] = float_read(f.readline().split()[0]) - self.fst_vt['HydroDyn']['WaveDirMod'] = int_read(f.readline().split()[0]) - self.fst_vt['HydroDyn']['WaveDirSpread'] = float_read(f.readline().split()[0]) - self.fst_vt['HydroDyn']['WaveNDir'] = int_read(f.readline().split()[0]) - self.fst_vt['HydroDyn']['WaveDirRange'] = float_read(f.readline().split()[0]) - self.fst_vt['HydroDyn']['WaveSeed1'] = int_read(f.readline().split()[0]) - self.fst_vt['HydroDyn']['WaveSeed2'] = int_read(f.readline().split()[0]) - self.fst_vt['HydroDyn']['WaveNDAmp'] = bool_read(f.readline().split()[0]) - self.fst_vt['HydroDyn']['WvKinFile'] = f.readline().split()[0][1:-1] - self.fst_vt['HydroDyn']['NWaveElev'] = int_read(f.readline().split()[0]) - self.fst_vt['HydroDyn']['WaveElevxi'] = [idx.strip() for idx in f.readline().split('WaveElevxi')[0].split(',')] - self.fst_vt['HydroDyn']['WaveElevyi'] = [idx.strip() for idx in f.readline().split('WaveElevyi')[0].split(',')] - - # 2ND-ORDER WAVES - f.readline() - self.fst_vt['HydroDyn']['WvDiffQTF'] = bool_read(f.readline().split()[0]) - self.fst_vt['HydroDyn']['WvSumQTF'] = bool_read(f.readline().split()[0]) - self.fst_vt['HydroDyn']['WvLowCOffD'] = float_read(f.readline().split()[0]) - self.fst_vt['HydroDyn']['WvHiCOffD'] = float_read(f.readline().split()[0]) - self.fst_vt['HydroDyn']['WvLowCOffS'] = float_read(f.readline().split()[0]) - self.fst_vt['HydroDyn']['WvHiCOffS'] = float_read(f.readline().split()[0]) - - # CURRENT - f.readline() - self.fst_vt['HydroDyn']['CurrMod'] = int_read(f.readline().split()[0]) - self.fst_vt['HydroDyn']['CurrSSV0'] = float_read(f.readline().split()[0]) - self.fst_vt['HydroDyn']['CurrSSDir'] = float_read(f.readline().split()[0]) - self.fst_vt['HydroDyn']['CurrNSRef'] = float_read(f.readline().split()[0]) - self.fst_vt['HydroDyn']['CurrNSV0'] = float_read(f.readline().split()[0]) - self.fst_vt['HydroDyn']['CurrNSDir'] = float_read(f.readline().split()[0]) - self.fst_vt['HydroDyn']['CurrDIV'] = float_read(f.readline().split()[0]) - self.fst_vt['HydroDyn']['CurrDIDir'] = float_read(f.readline().split()[0]) # FLOATING PLATFORM f.readline() self.fst_vt['HydroDyn']['PotMod'] = int_read(f.readline().split()[0]) 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']['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]) self.fst_vt['HydroDyn']['NBody'] = int_read(f.readline().split()[0]) self.fst_vt['HydroDyn']['NBodyMod'] = int_read(f.readline().split()[0]) - self.fst_vt['HydroDyn']['PotFile'] = os.path.normpath(os.path.join(os.path.split(hd_file)[0], f.readline().split()[0][1:-1])) - self.fst_vt['HydroDyn']['WAMITULEN'] = float_read(f.readline().split()[0]) - self.fst_vt['HydroDyn']['PtfmRefxt'] = float_read(f.readline().split()[0]) - self.fst_vt['HydroDyn']['PtfmRefyt'] = float_read(f.readline().split()[0]) - self.fst_vt['HydroDyn']['PtfmRefzt'] = float_read(f.readline().split()[0]) - self.fst_vt['HydroDyn']['PtfmRefztRot'] = float_read(f.readline().split()[0]) - self.fst_vt['HydroDyn']['PtfmVol0'] = float_read(f.readline().split()[0]) - self.fst_vt['HydroDyn']['PtfmCOBxt'] = float_read(f.readline().split()[0]) - self.fst_vt['HydroDyn']['PtfmCOByt'] = float_read(f.readline().split()[0]) + + # Get multiple potential files + pot_strings = read_array(f,self.fst_vt['HydroDyn']['NBody'],str) #re.split(',| ',f.readline().strip()) + pot_strings = [os.path.normpath(os.path.join(os.path.split(hd_file)[0],ps)) for ps in pot_strings] # make relative to hd_file + self.fst_vt['HydroDyn']['PotFile'] = pot_strings + self.fst_vt['HydroDyn']['WAMITULEN'] = read_array(f,self.fst_vt['HydroDyn']['NBody'],float) + self.fst_vt['HydroDyn']['PtfmRefxt'] = read_array(f,self.fst_vt['HydroDyn']['NBody'],float) + self.fst_vt['HydroDyn']['PtfmRefyt'] = read_array(f,self.fst_vt['HydroDyn']['NBody'],float) + self.fst_vt['HydroDyn']['PtfmRefzt'] = read_array(f,self.fst_vt['HydroDyn']['NBody'],float) + self.fst_vt['HydroDyn']['PtfmRefztRot'] = read_array(f,self.fst_vt['HydroDyn']['NBody'],float) + self.fst_vt['HydroDyn']['PtfmVol0'] = read_array(f,self.fst_vt['HydroDyn']['NBody'],float) + self.fst_vt['HydroDyn']['PtfmCOBxt'] = read_array(f,self.fst_vt['HydroDyn']['NBody'],float) + self.fst_vt['HydroDyn']['PtfmCOByt'] = read_array(f,self.fst_vt['HydroDyn']['NBody'],float) # 2ND-ORDER FLOATING PLATFORM FORCES f.readline() @@ -1779,9 +1787,14 @@ def read_HydroDyn(self, hd_file): else: raise Exception("Invalid value for fst_vt['HydroDyn']['NBodyMod']") - self.fst_vt['HydroDyn']['AddCLin'] = np.array([[float(idx) for idx in f.readline().strip().split()[:6]] for i in range(6)]) - self.fst_vt['HydroDyn']['AddBLin'] = np.array([[float(idx) for idx in f.readline().strip().split()[:6]] for i in range(6)]) - self.fst_vt['HydroDyn']['AddBQuad'] = np.array([[float(idx) for idx in f.readline().strip().split()[:6]] for i in range(6)]) + self.fst_vt['HydroDyn']['AddCLin'] = np.array([[float(idx) for idx in f.readline().strip().split()[:6*NBody]] for i in range(6)]) + self.fst_vt['HydroDyn']['AddBLin'] = np.array([[float(idx) for idx in f.readline().strip().split()[:6*NBody]] for i in range(6)]) + self.fst_vt['HydroDyn']['AddBQuad'] = np.array([[float(idx) for idx in f.readline().strip().split()[:6*NBody]] for i in range(6)]) + + #STRIP THEORY OPTIONS + f.readline() + self.fst_vt['HydroDyn']['WaveDisp'] = int_read(f.readline().split()[0]) + self.fst_vt['HydroDyn']['AMMod'] = int_read(f.readline().split()[0]) #AXIAL COEFFICIENTS f.readline() @@ -1790,14 +1803,20 @@ def read_HydroDyn(self, hd_file): self.fst_vt['HydroDyn']['AxCd'] = [None]*self.fst_vt['HydroDyn']['NAxCoef'] self.fst_vt['HydroDyn']['AxCa'] = [None]*self.fst_vt['HydroDyn']['NAxCoef'] self.fst_vt['HydroDyn']['AxCp'] = [None]*self.fst_vt['HydroDyn']['NAxCoef'] + self.fst_vt['HydroDyn']['AxFDMod'] = [None]*self.fst_vt['HydroDyn']['NAxCoef'] + self.fst_vt['HydroDyn']['AxVnCOff'] = [None]*self.fst_vt['HydroDyn']['NAxCoef'] + self.fst_vt['HydroDyn']['AxFDLoFSc'] = [None]*self.fst_vt['HydroDyn']['NAxCoef'] ln = f.readline().split() ln = f.readline().split() for i in range(self.fst_vt['HydroDyn']['NAxCoef']): ln = f.readline().split() - self.fst_vt['HydroDyn']['AxCoefID'][i] = int(ln[0]) - self.fst_vt['HydroDyn']['AxCd'][i] = float(ln[1]) - self.fst_vt['HydroDyn']['AxCa'][i] = float(ln[2]) - self.fst_vt['HydroDyn']['AxCp'][i] = float(ln[3]) + self.fst_vt['HydroDyn']['AxCoefID'][i] = int(ln[0]) + self.fst_vt['HydroDyn']['AxCd'][i] = float_read(ln[1]) + self.fst_vt['HydroDyn']['AxCa'][i] = float_read(ln[2]) + self.fst_vt['HydroDyn']['AxCp'][i] = float_read(ln[3]) + self.fst_vt['HydroDyn']['AxFDMod'][i] = float_read(ln[4]) + self.fst_vt['HydroDyn']['AxVnCOff'][i] = float_read(ln[5]) + self.fst_vt['HydroDyn']['AxFDLoFSc'][i] = float_read(ln[6]) #MEMBER JOINTS f.readline() @@ -1838,18 +1857,20 @@ def read_HydroDyn(self, hd_file): f.readline() f.readline() ln = f.readline().split() - self.fst_vt['HydroDyn']['SimplCd'] = float(ln[0]) - self.fst_vt['HydroDyn']['SimplCdMG'] = float(ln[1]) - self.fst_vt['HydroDyn']['SimplCa'] = float(ln[2]) - self.fst_vt['HydroDyn']['SimplCaMG'] = float(ln[3]) - self.fst_vt['HydroDyn']['SimplCp'] = float(ln[4]) - self.fst_vt['HydroDyn']['SimplCpMG'] = float(ln[5]) - self.fst_vt['HydroDyn']['SimplAxCd'] = float(ln[6]) - self.fst_vt['HydroDyn']['SimplAxCdMG'] = float(ln[7]) - self.fst_vt['HydroDyn']['SimplAxCa'] = float(ln[8]) - self.fst_vt['HydroDyn']['SimplAxCaMG'] = float(ln[9]) - self.fst_vt['HydroDyn']['SimplAxCp'] = float(ln[10]) - self.fst_vt['HydroDyn']['SimplAxCpMG'] = float(ln[11]) + self.fst_vt['HydroDyn']['SimplCd'] = float_read(ln[0]) + self.fst_vt['HydroDyn']['SimplCdMG'] = float_read(ln[1]) + self.fst_vt['HydroDyn']['SimplCa'] = float_read(ln[2]) + self.fst_vt['HydroDyn']['SimplCaMG'] = float_read(ln[3]) + self.fst_vt['HydroDyn']['SimplCp'] = float_read(ln[4]) + self.fst_vt['HydroDyn']['SimplCpMG'] = float_read(ln[5]) + self.fst_vt['HydroDyn']['SimplAxCd'] = float_read(ln[6]) + self.fst_vt['HydroDyn']['SimplAxCdMG'] = float_read(ln[7]) + self.fst_vt['HydroDyn']['SimplAxCa'] = float_read(ln[8]) + self.fst_vt['HydroDyn']['SimplAxCaMG'] = float_read(ln[9]) + self.fst_vt['HydroDyn']['SimplAxCp'] = float_read(ln[10]) + self.fst_vt['HydroDyn']['SimplAxCpMG'] = float_read(ln[11]) + self.fst_vt['HydroDyn']['SimplCb'] = float_read(ln[12]) + self.fst_vt['HydroDyn']['SimplCbMG'] = float_read(ln[13]) #DEPTH-BASED HYDRODYNAMIC COEFFICIENTS f.readline() @@ -1867,23 +1888,27 @@ def read_HydroDyn(self, hd_file): self.fst_vt['HydroDyn']['DpthAxCaMG'] = [None]*self.fst_vt['HydroDyn']['NCoefDpth'] self.fst_vt['HydroDyn']['DpthAxCp'] = [None]*self.fst_vt['HydroDyn']['NCoefDpth'] self.fst_vt['HydroDyn']['DpthAxCpMG'] = [None]*self.fst_vt['HydroDyn']['NCoefDpth'] + self.fst_vt['HydroDyn']['DpthCb'] = [None]*self.fst_vt['HydroDyn']['NCoefDpth'] + self.fst_vt['HydroDyn']['DpthCbMG'] = [None]*self.fst_vt['HydroDyn']['NCoefDpth'] ln = f.readline().split() ln = f.readline().split() for i in range(self.fst_vt['HydroDyn']['NCoefDpth']): ln = f.readline().split() - self.fst_vt['HydroDyn']['Dpth'][i] = float(ln[0]) - self.fst_vt['HydroDyn']['DpthCd'][i] = float(ln[1]) - self.fst_vt['HydroDyn']['DpthCdMG'][i] = float(ln[2]) - self.fst_vt['HydroDyn']['DpthCa'][i] = float(ln[3]) - self.fst_vt['HydroDyn']['DpthCaMG'][i] = float(ln[4]) - self.fst_vt['HydroDyn']['DpthCp'][i] = float(ln[5]) - self.fst_vt['HydroDyn']['DpthCpMG'][i] = float(ln[6]) - self.fst_vt['HydroDyn']['DpthAxCd'][i] = float(ln[7]) - self.fst_vt['HydroDyn']['DpthAxCdMG'][i] = float(ln[8]) - self.fst_vt['HydroDyn']['DpthAxCa'][i] = float(ln[9]) - self.fst_vt['HydroDyn']['DpthAxCaMG'][i] = float(ln[10]) - self.fst_vt['HydroDyn']['DpthAxCp'][i] = float(ln[11]) - self.fst_vt['HydroDyn']['DpthAxCpMG'][i] = float(ln[12]) + self.fst_vt['HydroDyn']['Dpth'][i] = float_read(ln[0]) + self.fst_vt['HydroDyn']['DpthCd'][i] = float_read(ln[1]) + self.fst_vt['HydroDyn']['DpthCdMG'][i] = float_read(ln[2]) + self.fst_vt['HydroDyn']['DpthCa'][i] = float_read(ln[3]) + self.fst_vt['HydroDyn']['DpthCaMG'][i] = float_read(ln[4]) + self.fst_vt['HydroDyn']['DpthCp'][i] = float_read(ln[5]) + self.fst_vt['HydroDyn']['DpthCpMG'][i] = float_read(ln[6]) + self.fst_vt['HydroDyn']['DpthAxCd'][i] = float_read(ln[7]) + self.fst_vt['HydroDyn']['DpthAxCdMG'][i] = float_read(ln[8]) + self.fst_vt['HydroDyn']['DpthAxCa'][i] = float_read(ln[9]) + self.fst_vt['HydroDyn']['DpthAxCaMG'][i] = float_read(ln[10]) + self.fst_vt['HydroDyn']['DpthAxCp'][i] = float_read(ln[11]) + self.fst_vt['HydroDyn']['DpthAxCpMG'][i] = float_read(ln[12]) + self.fst_vt['HydroDyn']['DpthCb'][i] = float_read(ln[13]) + self.fst_vt['HydroDyn']['DpthCbMG'][i] = float_read(ln[14]) #MEMBER-BASED HYDRODYNAMIC COEFFICIENTS f.readline() @@ -1913,36 +1938,44 @@ def read_HydroDyn(self, hd_file): self.fst_vt['HydroDyn']['MemberAxCp2'] = [None]*self.fst_vt['HydroDyn']['NCoefMembers'] self.fst_vt['HydroDyn']['MemberAxCpMG1'] = [None]*self.fst_vt['HydroDyn']['NCoefMembers'] self.fst_vt['HydroDyn']['MemberAxCpMG2'] = [None]*self.fst_vt['HydroDyn']['NCoefMembers'] + self.fst_vt['HydroDyn']['MemberCb1'] = [None]*self.fst_vt['HydroDyn']['NCoefMembers'] + self.fst_vt['HydroDyn']['MemberCb2'] = [None]*self.fst_vt['HydroDyn']['NCoefMembers'] + self.fst_vt['HydroDyn']['MemberCbMG1'] = [None]*self.fst_vt['HydroDyn']['NCoefMembers'] + self.fst_vt['HydroDyn']['MemberCbMG2'] = [None]*self.fst_vt['HydroDyn']['NCoefMembers'] f.readline() f.readline() for i in range(self.fst_vt['HydroDyn']['NCoefMembers']): ln = f.readline().split() self.fst_vt['HydroDyn']['MemberID_HydC'][i] = int(ln[0]) - self.fst_vt['HydroDyn']['MemberCd1'][i] = float(ln[1]) - self.fst_vt['HydroDyn']['MemberCd2'][i] = float(ln[2]) - self.fst_vt['HydroDyn']['MemberCdMG1'][i] = float(ln[3]) - self.fst_vt['HydroDyn']['MemberCdMG2'][i] = float(ln[4]) - self.fst_vt['HydroDyn']['MemberCa1'][i] = float(ln[5]) - self.fst_vt['HydroDyn']['MemberCa2'][i] = float(ln[6]) - self.fst_vt['HydroDyn']['MemberCaMG1'][i] = float(ln[7]) - self.fst_vt['HydroDyn']['MemberCaMG2'][i] = float(ln[8]) - self.fst_vt['HydroDyn']['MemberCp1'][i] = float(ln[9]) - self.fst_vt['HydroDyn']['MemberCp2'][i] = float(ln[10]) - self.fst_vt['HydroDyn']['MemberCpMG1'][i] = float(ln[11]) - self.fst_vt['HydroDyn']['MemberCpMG2'][i] = float(ln[12]) - self.fst_vt['HydroDyn']['MemberAxCd1'][i] = float(ln[13]) - self.fst_vt['HydroDyn']['MemberAxCd2'][i] = float(ln[14]) - self.fst_vt['HydroDyn']['MemberAxCdMG1'][i] = float(ln[15]) - self.fst_vt['HydroDyn']['MemberAxCdMG2'][i] = float(ln[16]) - self.fst_vt['HydroDyn']['MemberAxCa1'][i] = float(ln[17]) - self.fst_vt['HydroDyn']['MemberAxCa2'][i] = float(ln[18]) - self.fst_vt['HydroDyn']['MemberAxCaMG1'][i] = float(ln[19]) - self.fst_vt['HydroDyn']['MemberAxCaMG2'][i] = float(ln[20]) - self.fst_vt['HydroDyn']['MemberAxCp1'][i] = float(ln[21]) - self.fst_vt['HydroDyn']['MemberAxCp2'][i] = float(ln[22]) - self.fst_vt['HydroDyn']['MemberAxCpMG1'][i] = float(ln[23]) - self.fst_vt['HydroDyn']['MemberAxCpMG2'][i] = float(ln[24]) + self.fst_vt['HydroDyn']['MemberCd1'][i] = float_read(ln[1]) + self.fst_vt['HydroDyn']['MemberCd2'][i] = float_read(ln[2]) + self.fst_vt['HydroDyn']['MemberCdMG1'][i] = float_read(ln[3]) + self.fst_vt['HydroDyn']['MemberCdMG2'][i] = float_read(ln[4]) + self.fst_vt['HydroDyn']['MemberCa1'][i] = float_read(ln[5]) + self.fst_vt['HydroDyn']['MemberCa2'][i] = float_read(ln[6]) + self.fst_vt['HydroDyn']['MemberCaMG1'][i] = float_read(ln[7]) + self.fst_vt['HydroDyn']['MemberCaMG2'][i] = float_read(ln[8]) + self.fst_vt['HydroDyn']['MemberCp1'][i] = float_read(ln[9]) + self.fst_vt['HydroDyn']['MemberCp2'][i] = float_read(ln[10]) + self.fst_vt['HydroDyn']['MemberCpMG1'][i] = float_read(ln[11]) + self.fst_vt['HydroDyn']['MemberCpMG2'][i] = float_read(ln[12]) + self.fst_vt['HydroDyn']['MemberAxCd1'][i] = float_read(ln[13]) + self.fst_vt['HydroDyn']['MemberAxCd2'][i] = float_read(ln[14]) + self.fst_vt['HydroDyn']['MemberAxCdMG1'][i] = float_read(ln[15]) + self.fst_vt['HydroDyn']['MemberAxCdMG2'][i] = float_read(ln[16]) + self.fst_vt['HydroDyn']['MemberAxCa1'][i] = float_read(ln[17]) + self.fst_vt['HydroDyn']['MemberAxCa2'][i] = float_read(ln[18]) + self.fst_vt['HydroDyn']['MemberAxCaMG1'][i] = float_read(ln[19]) + self.fst_vt['HydroDyn']['MemberAxCaMG2'][i] = float_read(ln[20]) + self.fst_vt['HydroDyn']['MemberAxCp1'][i] = float_read(ln[21]) + self.fst_vt['HydroDyn']['MemberAxCp2'][i] = float_read(ln[22]) + self.fst_vt['HydroDyn']['MemberAxCpMG1'][i] = float_read(ln[23]) + self.fst_vt['HydroDyn']['MemberAxCpMG2'][i] = float_read(ln[24]) + self.fst_vt['HydroDyn']['MemberCb1'][i] = float_read(ln[25]) + self.fst_vt['HydroDyn']['MemberCb2'][i] = float_read(ln[26]) + self.fst_vt['HydroDyn']['MemberCbMG1'][i] = float_read(ln[27]) + self.fst_vt['HydroDyn']['MemberCbMG2'][i] = float_read(ln[28]) #MEMBERS f.readline() @@ -1954,6 +1987,7 @@ def read_HydroDyn(self, hd_file): self.fst_vt['HydroDyn']['MPropSetID2'] = [None]*self.fst_vt['HydroDyn']['NMembers'] self.fst_vt['HydroDyn']['MDivSize'] = [None]*self.fst_vt['HydroDyn']['NMembers'] self.fst_vt['HydroDyn']['MCoefMod'] = [None]*self.fst_vt['HydroDyn']['NMembers'] + self.fst_vt['HydroDyn']['MHstLMod'] = [None]*self.fst_vt['HydroDyn']['NMembers'] self.fst_vt['HydroDyn']['PropPot'] = [None]*self.fst_vt['HydroDyn']['NMembers'] ln = f.readline().split() ln = f.readline().split() @@ -1966,7 +2000,8 @@ def read_HydroDyn(self, hd_file): self.fst_vt['HydroDyn']['MPropSetID2'][i] = int(ln[4]) self.fst_vt['HydroDyn']['MDivSize'][i] = float(ln[5]) self.fst_vt['HydroDyn']['MCoefMod'][i] = int(ln[6]) - self.fst_vt['HydroDyn']['PropPot'][i] = bool_read(ln[7]) + self.fst_vt['HydroDyn']['MHstLMod'][i] = int(ln[7]) + self.fst_vt['HydroDyn']['PropPot'][i] = bool_read(ln[8]) #FILLED MEMBERS f.readline() @@ -1979,10 +2014,14 @@ def read_HydroDyn(self, hd_file): ln = f.readline().split() for i in range(self.fst_vt['HydroDyn']['NFillGroups']): ln = f.readline().split() - self.fst_vt['HydroDyn']['FillNumM'][i] = int(ln[0]) - self.fst_vt['HydroDyn']['FillMList'][i] = [int(j) for j in ln[1:-2]] - self.fst_vt['HydroDyn']['FillFSLoc'][i] = float(ln[-2]) - self.fst_vt['HydroDyn']['FillDens'][i] = float(ln[-1]) + n_fill = int(ln[0]) + self.fst_vt['HydroDyn']['FillNumM'][i] = n_fill + self.fst_vt['HydroDyn']['FillMList'][i] = [int(j) for j in ln[1:1+n_fill]] + self.fst_vt['HydroDyn']['FillFSLoc'][i] = float(ln[n_fill+1]) + if ln[n_fill+2] == 'DEFAULT': + self.fst_vt['HydroDyn']['FillDens'][i] = 'DEFAULT' + else: + self.fst_vt['HydroDyn']['FillDens'][i] = float(ln[n_fill+2]) #MARINE GROWTH f.readline() @@ -2046,6 +2085,112 @@ def read_HydroDyn(self, hd_file): f.close() + def read_SeaState(self, ss_file): + + f = open(ss_file) + + f.readline() + f.readline() + + self.fst_vt['SeaState']['Echo'] = bool_read(f.readline().split()[0]) + # ENVIRONMENTAL CONDITIONS + f.readline() + self.fst_vt['SeaState']['WtrDens'] = float_read(f.readline().split()[0]) + self.fst_vt['SeaState']['WtrDpth'] = float_read(f.readline().split()[0]) + self.fst_vt['SeaState']['MSL2SWL'] = float_read(f.readline().split()[0]) + + # SPATIAL DISCRETIZATION + f.readline() + self.fst_vt['SeaState']['X_HalfWidth'] = float_read(f.readline().split()[0]) + self.fst_vt['SeaState']['Y_HalfWidth'] = float_read(f.readline().split()[0]) + self.fst_vt['SeaState']['Z_Depth'] = float_read(f.readline().split()[0]) + self.fst_vt['SeaState']['NX'] = int_read(f.readline().split()[0]) + self.fst_vt['SeaState']['NY'] = int_read(f.readline().split()[0]) + self.fst_vt['SeaState']['NZ'] = int_read(f.readline().split()[0]) + + # WAVES + f.readline() + self.fst_vt['SeaState']['WaveMod'] = int_read(f.readline().split()[0]) + self.fst_vt['SeaState']['WaveStMod'] = int_read(f.readline().split()[0]) + self.fst_vt['SeaState']['WaveTMax'] = float_read(f.readline().split()[0]) + self.fst_vt['SeaState']['WaveDT'] = float_read(f.readline().split()[0]) + self.fst_vt['SeaState']['WaveHs'] = float_read(f.readline().split()[0]) + self.fst_vt['SeaState']['WaveTp'] = float_read(f.readline().split()[0]) + self.fst_vt['SeaState']['WavePkShp'] = float_read(f.readline().split()[0]) # default + self.fst_vt['SeaState']['WvLowCOff'] = float_read(f.readline().split()[0]) + self.fst_vt['SeaState']['WvHiCOff'] = float_read(f.readline().split()[0]) + self.fst_vt['SeaState']['WaveDir'] = float_read(f.readline().split()[0]) + self.fst_vt['SeaState']['WaveDirMod'] = int_read(f.readline().split()[0]) + self.fst_vt['SeaState']['WaveDirSpread'] = float_read(f.readline().split()[0]) + self.fst_vt['SeaState']['WaveNDir'] = int_read(f.readline().split()[0]) + self.fst_vt['SeaState']['WaveDirRange'] = float_read(f.readline().split()[0]) + self.fst_vt['SeaState']['WaveSeed1'] = int_read(f.readline().split()[0]) + self.fst_vt['SeaState']['WaveSeed2'] = int_read(f.readline().split()[0]) + self.fst_vt['SeaState']['WaveNDAmp'] = bool_read(f.readline().split()[0]) + self.fst_vt['SeaState']['WvKinFile'] = f.readline().split()[0][1:-1] + + # 2ND-ORDER WAVES + f.readline() + self.fst_vt['SeaState']['WvDiffQTF'] = bool_read(f.readline().split()[0]) + self.fst_vt['SeaState']['WvSumQTF'] = bool_read(f.readline().split()[0]) + self.fst_vt['SeaState']['WvLowCOffD'] = float_read(f.readline().split()[0]) + self.fst_vt['SeaState']['WvHiCOffD'] = float_read(f.readline().split()[0]) + self.fst_vt['SeaState']['WvLowCOffS'] = float_read(f.readline().split()[0]) + self.fst_vt['SeaState']['WvHiCOffS'] = float_read(f.readline().split()[0]) + + # CONSTRAINED WAVE + f.readline() + self.fst_vt['SeaState']['ConstWaveMod'] = int_read(f.readline().split()[0]) + self.fst_vt['SeaState']['CrestHmax'] = float_read(f.readline().split()[0]) + self.fst_vt['SeaState']['CrestTime'] = float_read(f.readline().split()[0]) + self.fst_vt['SeaState']['CrestXi'] = float_read(f.readline().split()[0]) + self.fst_vt['SeaState']['CrestYi'] = float_read(f.readline().split()[0]) + + # CURRENT + f.readline() + self.fst_vt['SeaState']['CurrMod'] = int_read(f.readline().split()[0]) + self.fst_vt['SeaState']['CurrSSV0'] = float_read(f.readline().split()[0]) + self.fst_vt['SeaState']['CurrSSDir'] = float_read(f.readline().split()[0]) + self.fst_vt['SeaState']['CurrNSRef'] = float_read(f.readline().split()[0]) + self.fst_vt['SeaState']['CurrNSV0'] = float_read(f.readline().split()[0]) + self.fst_vt['SeaState']['CurrNSDir'] = float_read(f.readline().split()[0]) + self.fst_vt['SeaState']['CurrDIV'] = float_read(f.readline().split()[0]) + self.fst_vt['SeaState']['CurrDIDir'] = float_read(f.readline().split()[0]) + + # MacCamy-Fuchs Diffraction Model + f.readline() + self.fst_vt['SeaState']['MCFD'] = float_read(f.readline().split()[0]) + + # OUTPUT + f.readline() + self.fst_vt['SeaState']['SeaStSum'] = bool_read(f.readline().split()[0]) + self.fst_vt['SeaState']['OutSwtch'] = int_read(f.readline().split()[0]) + self.fst_vt['SeaState']['OutFmt'] = str(f.readline().split()[0]) + self.fst_vt['SeaState']['OutSFmt'] = str(f.readline().split()[0]) + self.fst_vt['SeaState']['NWaveElev'] = int_read(f.readline().split()[0]) + self.fst_vt['SeaState']['WaveElevxi'] = [float_read(idx.strip()) for idx in f.readline().split('WaveElevxi')[0].replace(',',' ').split()] + self.fst_vt['SeaState']['WaveElevyi'] = [float_read(idx.strip()) for idx in f.readline().split('WaveElevyi')[0].replace(',',' ').split()] + self.fst_vt['SeaState']['NWaveKin'] = int_read(f.readline().split()[0]) + NWaveKin = self.fst_vt['SeaState']['NWaveKin'] + if NWaveKin: + self.fst_vt['SeaState']['WaveKinxi'] = [float_read(idx.strip()) for idx in f.readline().split('WaveKinxi')[0].replace(',',' ').split()] + self.fst_vt['SeaState']['WaveKinyi'] = [float_read(idx.strip()) for idx in f.readline().split('WaveKinyi')[0].replace(',',' ').split()] + self.fst_vt['SeaState']['WaveKinzi'] = [float_read(idx.strip()) for idx in f.readline().split('WaveKinzi')[0].replace(',',' ').split()] + else: + [f.readline() for i in range(3)] + # Unused, filled with dummy location + self.fst_vt['SeaState']['WaveKinxi'] = [0] + self.fst_vt['SeaState']['WaveKinyi'] = [0] + self.fst_vt['SeaState']['WaveKinzi'] = [0] + + + # SeaState Outlist + f.readline() + self.read_outlist(f,'SeaState') + + f.close() + + def read_SubDyn(self, sd_file): f = open(sd_file) @@ -2066,7 +2211,7 @@ def read_SubDyn(self, sd_file): self.fst_vt['SubDyn']['Nmodes'] = int_read(f.readline().split()[0]) self.fst_vt['SubDyn']['JDampings'] = float_read(f.readline().split()[0]) self.fst_vt['SubDyn']['GuyanDampMod'] = int_read(f.readline().split()[0]) - self.fst_vt['SubDyn']['RayleighDamp'] = read_array(f,2,array_type=float) + self.fst_vt['SubDyn']['RayleighDamp'] = read_array(f,2,float) self.fst_vt['SubDyn']['GuyanDampSize'] = int_read(f.readline().split()[0]) self.fst_vt['SubDyn']['GuyanDamp'] = np.array([[float(idx) for idx in f.readline().strip().split()[:6]] for i in range(self.fst_vt['SubDyn']['GuyanDampSize'])]) f.readline() @@ -2150,7 +2295,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']): @@ -2162,7 +2307,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]) @@ -2222,8 +2367,8 @@ def read_SubDyn(self, sd_file): ln = f.readline().split() self.fst_vt['SubDyn']['CablePropSetID'][i] = int(ln[0]) self.fst_vt['SubDyn']['CableEA'][i] = float(ln[1]) - self.fst_vt['SubDyn']['CableMatDens'][i] = float(ln[1]) - self.fst_vt['SubDyn']['CableT0'][i] = float(ln[1]) + self.fst_vt['SubDyn']['CableMatDens'][i] = float(ln[2]) + self.fst_vt['SubDyn']['CableT0'][i] = float(ln[3]) # RIGID LINK PROPERTIES f.readline() self.fst_vt['SubDyn']['NRigidPropSets'] = int_read(f.readline().split()[0]) @@ -2235,6 +2380,26 @@ def read_SubDyn(self, sd_file): ln = f.readline().split() self.fst_vt['SubDyn']['RigidPropSetID'][i] = int(ln[0]) self.fst_vt['SubDyn']['RigidMatDens'][i] = float(ln[1]) + # SPRING ELEMENT PROPERTIES + f.readline() + self.fst_vt['SubDyn']['NSpringPropSets'] = int_read(f.readline().split()[0]) + self.fst_vt['SubDyn']['SpringPropSetID'] = [None]*self.fst_vt['SubDyn']['NSpringPropSets'] + spring_list = ['k11','k12','k13','k14','k15','k16', + 'k22','k23','k24','k25','k26', + 'k33','k34','k35','k36', + 'k44','k45','k46', + 'k55','k56', + 'k66'] + for sl in spring_list: # init list + self.fst_vt['SubDyn'][sl] = [None]*self.fst_vt['SubDyn']['NSpringPropSets'] + f.readline() + f.readline() + for i in range(self.fst_vt['SubDyn']['NSpringPropSets']): + ln = f.readline().split() + 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] + # MEMBER COSINE MATRICES f.readline() self.fst_vt['SubDyn']['NCOSMs'] = int_read(f.readline().split()[0]) @@ -2294,6 +2459,18 @@ def read_SubDyn(self, sd_file): f.readline() # OUTPUT self.fst_vt['SubDyn']['SumPrint'] = bool_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]) @@ -2306,22 +2483,17 @@ def read_SubDyn(self, sd_file): self.fst_vt['SubDyn']['NMOutputs'] = int_read(f.readline().split()[0]) self.fst_vt['SubDyn']['MemberID_out'] = [None]*self.fst_vt['SubDyn']['NMOutputs'] self.fst_vt['SubDyn']['NOutCnt'] = [None]*self.fst_vt['SubDyn']['NMOutputs'] - self.fst_vt['SubDyn']['NodeCnt'] = [None]*self.fst_vt['SubDyn']['NMOutputs'] + self.fst_vt['SubDyn']['NodeCnt'] = [[None]]*self.fst_vt['SubDyn']['NMOutputs'] ln = f.readline().split() ln = f.readline().split() for i in range(self.fst_vt['SubDyn']['NMOutputs']): ln = f.readline().split() self.fst_vt['SubDyn']['MemberID_out'][i] = int(ln[0]) self.fst_vt['SubDyn']['NOutCnt'][i] = int(ln[1]) - self.fst_vt['SubDyn']['NodeCnt'][i] = int(ln[2]) + self.fst_vt['SubDyn']['NodeCnt'][i] = [int(node) for node in ln[2:]] f.readline() # SSOutList - data = f.readline() - while data.split()[0] != 'END': - channels = data.split('"') - channel_list = channels[1].split(',') - self.set_outlist(self.fst_vt['outlist']['SubDyn'], channel_list) - data = f.readline() + self.read_outlist(f,'SubDyn') f.close() @@ -2338,18 +2510,23 @@ def read_MAP(self, map_file): f.readline() f.readline() data_line = f.readline().strip().split() - self.fst_vt['MAP']['LineType'] = str(data_line[0]) - self.fst_vt['MAP']['Diam'] = float(data_line[1]) - self.fst_vt['MAP']['MassDenInAir'] = float(data_line[2]) - self.fst_vt['MAP']['EA'] = float(data_line[3]) - self.fst_vt['MAP']['CB'] = float(data_line[4]) - self.fst_vt['MAP']['CIntDamp'] = float(data_line[5]) - self.fst_vt['MAP']['Ca'] = float(data_line[6]) - self.fst_vt['MAP']['Cdn'] = float(data_line[7]) - self.fst_vt['MAP']['Cdt'] = float(data_line[8]) + self.fst_vt['MAP']['LineType'] = [str(data_line[0])] + self.fst_vt['MAP']['Diam'] = [float(data_line[1])] + self.fst_vt['MAP']['MassDenInAir'] = [float(data_line[2])] + self.fst_vt['MAP']['EA'] = [float(data_line[3])] + self.fst_vt['MAP']['CB'] = [float(data_line[4])] + self.fst_vt['MAP']['CIntDamp'] = [float(data_line[5])] + self.fst_vt['MAP']['Ca'] = [float(data_line[6])] + self.fst_vt['MAP']['Cdn'] = [float(data_line[7])] + self.fst_vt['MAP']['Cdt'] = [float(data_line[8])] f.readline() f.readline() f.readline() + # Init map nodes + node_types = ['Node','Type','X','Y','Z','M','B','FX','FY','FZ'] + for nt in node_types: + self.fst_vt['MAP'][nt] = [] + for i in range(2): data_node = f.readline().strip().split() self.fst_vt['MAP']['Node'].append(int(data_node[0])) @@ -2366,12 +2543,12 @@ def read_MAP(self, map_file): f.readline() f.readline() data_line_prop = f.readline().strip().split() - self.fst_vt['MAP']['Line'] = int(data_line_prop[0]) - self.fst_vt['MAP']['LineType'] = str(data_line_prop[1]) - self.fst_vt['MAP']['UnstrLen'] = float(data_line_prop[2]) - self.fst_vt['MAP']['NodeAnch'] = int(data_line_prop[3]) - self.fst_vt['MAP']['NodeFair'] = int(data_line_prop[4]) - self.fst_vt['MAP']['Flags'] = [str(val) for val in data_line_prop[5:]] + self.fst_vt['MAP']['Line'] = [int(data_line_prop[0])] + self.fst_vt['MAP']['LineType'] = [str(data_line_prop[1])] + self.fst_vt['MAP']['UnstrLen'] = [float(data_line_prop[2])] + self.fst_vt['MAP']['NodeAnch'] = [int(data_line_prop[3])] + self.fst_vt['MAP']['NodeFair'] = [int(data_line_prop[4])] + self.fst_vt['MAP']['Flags'] = [[str(val) for val in data_line_prop[5:]]] f.readline() f.readline() f.readline() @@ -2382,118 +2559,283 @@ def read_MoorDyn(self, moordyn_file): f = open(moordyn_file) + # Init optional headers so they exist for writer, even if not read + self.fst_vt['MoorDyn']['Rod_Name'] = [] + self.fst_vt['MoorDyn']['Body_ID'] = [] + self.fst_vt['MoorDyn']['Rod_ID'] = [] + self.fst_vt['MoorDyn']['ChannelID'] = [] + + # MoorDyn f.readline() f.readline() self.fst_vt['MoorDyn']['Echo'] = bool_read(f.readline().split()[0]) + data_line = f.readline() + while data_line: + + # Split and join so all headers are same when detecting next section + data_line = data_line.strip().split() + data_line = ''.join(data_line).lower() + + # Line Types + if 'linetypes' in data_line or 'linedictionary' in data_line: + f.readline() + f.readline() + + # Line types + self.fst_vt['MoorDyn']['Name'] = [] + self.fst_vt['MoorDyn']['Diam'] = [] + self.fst_vt['MoorDyn']['MassDen'] = [] + self.fst_vt['MoorDyn']['EA'] = [] + self.fst_vt['MoorDyn']['BA_zeta'] = [] + self.fst_vt['MoorDyn']['EI'] = [] + self.fst_vt['MoorDyn']['Cd'] = [] + self.fst_vt['MoorDyn']['Ca'] = [] + self.fst_vt['MoorDyn']['CdAx'] = [] + self.fst_vt['MoorDyn']['CaAx'] = [] + data_line = f.readline().strip().split() + while data_line[0] and data_line[0][:3] != '---': # OpenFAST searches for ---, so we'll do the same + self.fst_vt['MoorDyn']['Name'].append(str(data_line[0])) + self.fst_vt['MoorDyn']['Diam'].append(float(data_line[1])) + self.fst_vt['MoorDyn']['MassDen'].append(float(data_line[2])) + self.fst_vt['MoorDyn']['EA'].append(float(data_line[3])) + self.fst_vt['MoorDyn']['BA_zeta'].append(float(data_line[4])) + self.fst_vt['MoorDyn']['EI'].append(float(data_line[5])) + self.fst_vt['MoorDyn']['Cd'].append(float(data_line[6])) + self.fst_vt['MoorDyn']['Ca'].append(float(data_line[7])) + self.fst_vt['MoorDyn']['CdAx'].append(float(data_line[8])) + self.fst_vt['MoorDyn']['CaAx'].append(float(data_line[9])) + data_line = f.readline().strip().split() + data_line = ''.join(data_line) # re-join + + elif 'rodtypes' in data_line or 'roddictionary' in data_line: + data_line = f.readline() + data_line = f.readline() + + self.fst_vt['MoorDyn']['Rod_Diam'] = [] + self.fst_vt['MoorDyn']['Rod_MassDen'] = [] + self.fst_vt['MoorDyn']['Rod_Cd'] = [] + self.fst_vt['MoorDyn']['Rod_Ca'] = [] + self.fst_vt['MoorDyn']['Rod_CdEnd'] = [] + self.fst_vt['MoorDyn']['Rod_CaEnd'] = [] + + data_line = f.readline().strip().split() + while data_line[0] and data_line[0][:3] != '---': # OpenFAST searches for ---, so we'll do the same + self.fst_vt['MoorDyn']['Rod_Name'].append(data_line[0]) + self.fst_vt['MoorDyn']['Rod_Diam'].append(float(data_line[1])) + self.fst_vt['MoorDyn']['Rod_MassDen'].append(float(data_line[2])) + self.fst_vt['MoorDyn']['Rod_Cd'].append(float(data_line[3])) + self.fst_vt['MoorDyn']['Rod_Ca'].append(float(data_line[4])) + self.fst_vt['MoorDyn']['Rod_CdEnd'].append(float(data_line[5])) + self.fst_vt['MoorDyn']['Rod_CaEnd'].append(float(data_line[6])) + data_line = f.readline().strip().split() + data_line = ''.join(data_line) # re-join for reading next section uniformly + + + elif 'bodies' in data_line or 'bodylist' in data_line or 'bodyproperties' in data_line: + + f.readline() + f.readline() + self.fst_vt['MoorDyn']['Body_ID'] = [] + self.fst_vt['MoorDyn']['Body_Attachment'] = [] + self.fst_vt['MoorDyn']['X0'] = [] + self.fst_vt['MoorDyn']['Y0'] = [] + self.fst_vt['MoorDyn']['Z0'] = [] + self.fst_vt['MoorDyn']['r0'] = [] + self.fst_vt['MoorDyn']['p0'] = [] + self.fst_vt['MoorDyn']['y0'] = [] + self.fst_vt['MoorDyn']['Body_Mass'] = [] + self.fst_vt['MoorDyn']['Body_CG'] = [] + self.fst_vt['MoorDyn']['Body_I'] = [] + self.fst_vt['MoorDyn']['Body_Volume'] = [] + self.fst_vt['MoorDyn']['Body_CdA'] = [] + self.fst_vt['MoorDyn']['Body_Ca'] = [] + + data_line = f.readline().strip().split() + while data_line[0] and data_line[0][:3] != '---': # OpenFAST searches for ---, so we'll do the same + self.fst_vt['MoorDyn']['Body_ID'].append(int(data_line[0])) + self.fst_vt['MoorDyn']['Body_Attachment'].append(data_line[1]) + self.fst_vt['MoorDyn']['X0'].append(float(data_line[2])) + self.fst_vt['MoorDyn']['Y0'].append(float(data_line[3])) + self.fst_vt['MoorDyn']['Z0'].append(float(data_line[4])) + self.fst_vt['MoorDyn']['r0'].append(float(data_line[5])) + self.fst_vt['MoorDyn']['p0'].append(float(data_line[6])) + self.fst_vt['MoorDyn']['y0'].append(float(data_line[7])) + self.fst_vt['MoorDyn']['Body_Mass'].append(float(data_line[8])) + self.fst_vt['MoorDyn']['Body_CG'].append([float(dl) for dl in data_line[9].split('|')]) + self.fst_vt['MoorDyn']['Body_I'].append([float(dl) for dl in data_line[10].split('|')]) + self.fst_vt['MoorDyn']['Body_Volume'].append(float(data_line[11])) + self.fst_vt['MoorDyn']['Body_CdA'].append([float(dl) for dl in data_line[12].split('|')]) + self.fst_vt['MoorDyn']['Body_Ca'].append([float(dl) for dl in data_line[13].split('|')]) + data_line = f.readline().strip().split() + data_line = ''.join(data_line) # re-join for reading next section uniformly + + + elif 'rods' in data_line or 'rodlist' in data_line or 'rodproperties' in data_line: + f.readline() + f.readline() + self.fst_vt['MoorDyn']['Rod_ID'] = [] + self.fst_vt['MoorDyn']['Rod_Type'] = [] + self.fst_vt['MoorDyn']['Rod_Attachment'] = [] + self.fst_vt['MoorDyn']['Xa'] = [] + self.fst_vt['MoorDyn']['Ya'] = [] + self.fst_vt['MoorDyn']['Za'] = [] + self.fst_vt['MoorDyn']['Xb'] = [] + self.fst_vt['MoorDyn']['Yb'] = [] + self.fst_vt['MoorDyn']['Zb'] = [] + self.fst_vt['MoorDyn']['Rod_NumSegs'] = [] + self.fst_vt['MoorDyn']['RodOutputs'] = [] + + data_line = f.readline().strip().split() + while data_line[0] and data_line[0][:3] != '---': # OpenFAST searches for ---, so we'll do the same + self.fst_vt['MoorDyn']['Rod_ID'].append(data_line[0]) + self.fst_vt['MoorDyn']['Rod_Type'].append(data_line[1]) + self.fst_vt['MoorDyn']['Rod_Attachment'].append(data_line[2]) + self.fst_vt['MoorDyn']['Xa'].append(float(data_line[3])) + self.fst_vt['MoorDyn']['Ya'].append(float(data_line[4])) + self.fst_vt['MoorDyn']['Za'].append(float(data_line[5])) + self.fst_vt['MoorDyn']['Xb'].append(float(data_line[6])) + self.fst_vt['MoorDyn']['Yb'].append(float(data_line[7])) + self.fst_vt['MoorDyn']['Zb'].append(float(data_line[8])) + self.fst_vt['MoorDyn']['Rod_NumSegs'].append(int(data_line[9])) + self.fst_vt['MoorDyn']['RodOutputs'].append(data_line[10]) + data_line = f.readline().strip().split() + data_line = ''.join(data_line) # re-join for reading next section uniformly + + elif 'points' in data_line or 'connectionproperties' in data_line or \ + 'nodeproperties' in data_line or 'pointproperties' in data_line or \ + 'pointlist' in data_line: + + f.readline() + f.readline() + self.fst_vt['MoorDyn']['Point_ID'] = [] + self.fst_vt['MoorDyn']['Attachment'] = [] + self.fst_vt['MoorDyn']['X'] = [] + self.fst_vt['MoorDyn']['Y'] = [] + self.fst_vt['MoorDyn']['Z'] = [] + self.fst_vt['MoorDyn']['M'] = [] + self.fst_vt['MoorDyn']['V'] = [] + self.fst_vt['MoorDyn']['CdA'] = [] + self.fst_vt['MoorDyn']['CA'] = [] + data_line = f.readline().strip().split() + while data_line[0] and data_line[0][:3] != '---': # OpenFAST searches for ---, so we'll do the same + self.fst_vt['MoorDyn']['Point_ID'].append(int(data_line[0])) + self.fst_vt['MoorDyn']['Attachment'].append(str(data_line[1])) + self.fst_vt['MoorDyn']['X'].append(float(data_line[2])) + self.fst_vt['MoorDyn']['Y'].append(float(data_line[3])) + self.fst_vt['MoorDyn']['Z'].append(float(data_line[4])) + self.fst_vt['MoorDyn']['M'].append(float(data_line[5])) + self.fst_vt['MoorDyn']['V'].append(float(data_line[6])) + self.fst_vt['MoorDyn']['CdA'].append(float(data_line[7])) + self.fst_vt['MoorDyn']['CA'].append(float(data_line[8])) + data_line = f.readline().strip().split() + data_line = ''.join(data_line) # re-join for reading next section uniformly + + elif 'lines' in data_line or 'lineproperties' in data_line or 'linelist' in data_line: + f.readline() + f.readline() + + # Lines + self.fst_vt['MoorDyn']['Line_ID'] = [] + self.fst_vt['MoorDyn']['LineType'] = [] + self.fst_vt['MoorDyn']['AttachA'] = [] + self.fst_vt['MoorDyn']['AttachB'] = [] + self.fst_vt['MoorDyn']['UnstrLen'] = [] + self.fst_vt['MoorDyn']['NumSegs'] = [] + self.fst_vt['MoorDyn']['Outputs'] = [] + data_line = f.readline().strip().split() + 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']['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])) + data_line = f.readline().strip().split() + data_line = ''.join(data_line) # re-join for reading next section uniformly + + elif 'control' in data_line.lower(): + f.readline() + f.readline() + + # read optional control inputs, there are other optional MoorDyn sections/inputs + self.fst_vt['MoorDyn']['ChannelID'] = [] + self.fst_vt['MoorDyn']['Lines_Control'] = [] + + data_line = f.readline().strip().split() + while data_line[0] and data_line[0][:3] != '---': # OpenFAST searches for ---, so we'll do the same + self.fst_vt['MoorDyn']['ChannelID'].append(int(data_line[0])) + # Line(s) is a list of mooring lines, spaces are allowed between commas + control_lines = [] + for lines in data_line[1:]: + for line in lines.split(','): + control_lines.append(line.strip(',')) + + # Spaces show up in control_lines as '', remove them all + while '' in control_lines: + control_lines.remove('') + + self.fst_vt['MoorDyn']['Lines_Control'].append(control_lines) + data_line = f.readline().strip().split() + data_line = ''.join(data_line) # re-join for reading next section uniformly + + + elif 'options' in data_line: + + # MoorDyn lets options be written in any order + # Solver options + self.fst_vt['MoorDyn']['options'] = [] # keep list of MoorDyn options + + string_options = ['WaterKin'] + + data_line = f.readline().strip().split() + while data_line[0] and data_line[0][:3] != '---': # OpenFAST searches for ---, so we'll do the same + + raw_value = data_line[0] + option_name = data_line[1] + + self.fst_vt['MoorDyn']['options'].append(option_name) + if option_name in string_options: + self.fst_vt['MoorDyn'][option_name] = raw_value.strip('"') + else: + self.fst_vt['MoorDyn'][option_name] = float(raw_value) + + data_line = f.readline().strip().split() + data_line = ''.join(data_line) # re-join for reading next section uniformly + + elif 'outputs' in data_line: + + self.read_outlist(f,'MoorDyn') + + 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['MoorDyn']['Name'] = [] - self.fst_vt['MoorDyn']['Diam'] = [] - self.fst_vt['MoorDyn']['MassDen'] = [] - self.fst_vt['MoorDyn']['EA'] = [] - self.fst_vt['MoorDyn']['BA_zeta'] = [] - self.fst_vt['MoorDyn']['EI'] = [] - self.fst_vt['MoorDyn']['Cd'] = [] - self.fst_vt['MoorDyn']['Ca'] = [] - self.fst_vt['MoorDyn']['CdAx'] = [] - self.fst_vt['MoorDyn']['CaAx'] = [] - data_line = f.readline().strip().split() - while data_line[0][:3] != '---': # OpenFAST searches for ---, so we'll do the same - self.fst_vt['MoorDyn']['Name'].append(str(data_line[0])) - self.fst_vt['MoorDyn']['Diam'].append(float(data_line[1])) - self.fst_vt['MoorDyn']['MassDen'].append(float(data_line[2])) - self.fst_vt['MoorDyn']['EA'].append(float(data_line[3])) - self.fst_vt['MoorDyn']['BA_zeta'].append(float(data_line[4])) - self.fst_vt['MoorDyn']['EI'].append(float(data_line[5])) - self.fst_vt['MoorDyn']['Cd'].append(float(data_line[6])) - self.fst_vt['MoorDyn']['Ca'].append(float(data_line[7])) - self.fst_vt['MoorDyn']['CdAx'].append(float(data_line[8])) - self.fst_vt['MoorDyn']['CaAx'].append(float(data_line[9])) - data_line = f.readline().strip().split() - f.readline() - f.readline() - self.fst_vt['MoorDyn']['Point_ID'] = [] - self.fst_vt['MoorDyn']['Attachment'] = [] - self.fst_vt['MoorDyn']['X'] = [] - self.fst_vt['MoorDyn']['Y'] = [] - self.fst_vt['MoorDyn']['Z'] = [] - self.fst_vt['MoorDyn']['M'] = [] - self.fst_vt['MoorDyn']['V'] = [] - self.fst_vt['MoorDyn']['CdA'] = [] - self.fst_vt['MoorDyn']['CA'] = [] - data_line = f.readline().strip().split() - while data_line[0][:3] != '---': # OpenFAST searches for ---, so we'll do the same - self.fst_vt['MoorDyn']['Point_ID'].append(int(data_line[0])) - self.fst_vt['MoorDyn']['Attachment'].append(str(data_line[1])) - self.fst_vt['MoorDyn']['X'].append(float(data_line[2])) - self.fst_vt['MoorDyn']['Y'].append(float(data_line[3])) - self.fst_vt['MoorDyn']['Z'].append(float(data_line[4])) - self.fst_vt['MoorDyn']['M'].append(float(data_line[5])) - self.fst_vt['MoorDyn']['V'].append(float(data_line[6])) - self.fst_vt['MoorDyn']['CdA'].append(float(data_line[7])) - self.fst_vt['MoorDyn']['CA'].append(float(data_line[8])) - data_line = f.readline().strip().split() - f.readline() - f.readline() - self.fst_vt['MoorDyn']['Line_ID'] = [] - self.fst_vt['MoorDyn']['LineType'] = [] - self.fst_vt['MoorDyn']['AttachA'] = [] - self.fst_vt['MoorDyn']['AttachB'] = [] - self.fst_vt['MoorDyn']['UnstrLen'] = [] - self.fst_vt['MoorDyn']['NumSegs'] = [] - self.fst_vt['MoorDyn']['Outputs'] = [] - data_line = f.readline().strip().split() - while 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']['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])) - data_line = f.readline().strip().split() - - # read optional control inputs, there are other optional MoorDyn sections/inputs - self.fst_vt['MoorDyn']['ChannelID'] = [] - self.fst_vt['MoorDyn']['Lines_Control'] = [] - if 'CONTROL' in [dl.upper() for dl in data_line]: - f.readline() - f.readline() - data_line = f.readline().strip().split() - while data_line[0][:3] != '---': # OpenFAST searches for ---, so we'll do the same - self.fst_vt['MoorDyn']['ChannelID'].append(int(data_line[0])) - # Line(s) is a list of mooring lines, spaces are allowed between commas - control_lines = [] - for lines in data_line[1:]: - for line in lines.split(','): - control_lines.append(line.strip(',')) - - # Spaces show up in control_lines as '', remove them all - while '' in control_lines: - control_lines.remove('') - - self.fst_vt['MoorDyn']['Lines_Control'].append(control_lines) - data_line = f.readline().strip().split() - # Solver options, there are a few more optional MoorDyn inputs that can be added line 'CONTROL' - self.fst_vt['MoorDyn']['dtM'] = float_read(f.readline().split()[0]) - self.fst_vt['MoorDyn']['kbot'] = float_read(f.readline().split()[0]) - self.fst_vt['MoorDyn']['cbot'] = float_read(f.readline().split()[0]) - self.fst_vt['MoorDyn']['dtIC'] = float_read(f.readline().split()[0]) - self.fst_vt['MoorDyn']['TmaxIC'] = float_read(f.readline().split()[0]) - self.fst_vt['MoorDyn']['CdScaleIC'] = float_read(f.readline().split()[0]) - self.fst_vt['MoorDyn']['threshIC'] = float_read(f.readline().split()[0]) + 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() - - data = f.readline() - while data.split()[0] != 'END': - channels = data.strip().strip('"').strip("'") - channel_list = channels.split(',') - self.set_outlist(self.fst_vt['outlist']['MoorDyn'], channel_list) - data = f.readline() - + self.fst_vt['WaterKin']['CurrentMod'] = int_read(f.readline().split()[0]) f.close() def execute(self): @@ -2503,7 +2845,8 @@ def execute(self): self.read_ElastoDyn(ed_file) if not os.path.isabs(self.fst_vt['ElastoDyn']['BldFile1']): ed_blade_file = os.path.join(os.path.dirname(ed_file), self.fst_vt['ElastoDyn']['BldFile1']) - self.read_ElastoDynBlade(ed_blade_file) + if self.fst_vt['Fst']['CompElast'] == 1 or os.path.isfile(ed_blade_file): # If elastodyn blade is being used OR if the blade file exists + self.read_ElastoDynBlade(ed_blade_file) if not os.path.isabs(self.fst_vt['ElastoDyn']['TwrFile']): ed_tower_file = os.path.join(os.path.dirname(ed_file), self.fst_vt['ElastoDyn']['TwrFile']) self.read_ElastoDynTower(ed_tower_file) @@ -2530,6 +2873,9 @@ def execute(self): hd_file = os.path.normpath(os.path.join(self.FAST_directory, self.fst_vt['Fst']['HydroFile'])) if os.path.isfile(hd_file): self.read_HydroDyn(hd_file) + ss_file = os.path.normpath(os.path.join(self.FAST_directory, self.fst_vt['Fst']['SeaState'])) + if os.path.isfile(ss_file): + self.read_SeaState(ss_file) sd_file = os.path.normpath(os.path.join(self.FAST_directory, self.fst_vt['Fst']['SubFile'])) if os.path.isfile(sd_file): self.read_SubDyn(sd_file) @@ -2547,11 +2893,12 @@ def execute(self): if __name__=="__main__": - examples_dir = os.path.dirname( os.path.dirname( os.path.dirname( os.path.realpath(__file__) ) ) ) + os.sep + parent_dir = os.path.dirname( os.path.dirname( os.path.dirname( os.path.realpath(__file__) ) ) ) + os.sep + # Read the model fast = InputReader_OpenFAST() - fast.FAST_InputFile = 'IEA-15-240-RWT-UMaineSemi.fst' # FAST input file (ext=.fst) - fast.FAST_directory = os.path.join(examples_dir, 'examples', '01_aeroelasticse', - 'OpenFAST_models', 'IEA-15-240-RWT', - 'IEA-15-240-RWT-UMaineSemi') # Path to fst directory files - fast.execute() + fast.FAST_InputFile = '5MW_Land_BD_DLL_WTurb.fst' # FAST input file (ext=.fst) + fast.FAST_directory = os.path.join(parent_dir, 'reg_tests', 'r-test', + 'glue-codes', 'openfast', + '5MW_Land_BD_DLL_WTurb') # Path to fst directory files + fast.execute() \ No newline at end of file diff --git a/openfast_python/openfast_io/FAST_vars_out.py b/openfast_python/openfast_io/FAST_vars_out.py index 196ca88be..8d5ca4de9 100644 --- a/openfast_python/openfast_io/FAST_vars_out.py +++ b/openfast_python/openfast_io/FAST_vars_out.py @@ -1,2139 +1,284 @@ """ Generated from FAST OutListParameters.xlsx files with AeroelasticSE/src/AeroelasticSE/Util/create_output_vars.py """ -""" ElastoDyn """ -ElastoDyn = {} - -# Blade 1 Tip Motions -ElastoDyn['TipDxc1'] = True # (m); Blade 1 out-of-plane tip deflection (relative to the undeflected position); Directed along the xc1-axis -ElastoDyn['OoPDefl1'] = False # (m); Blade 1 out-of-plane tip deflection (relative to the undeflected position); Directed along the xc1-axis -ElastoDyn['TipDyc1'] = True # (m); Blade 1 in-plane tip deflection (relative to the undeflected position); Directed along the yc1-axis -ElastoDyn['IPDefl1'] = False # (m); Blade 1 in-plane tip deflection (relative to the undeflected position); Directed along the yc1-axis -ElastoDyn['TipDzc1'] = True # (m); Blade 1 axial tip deflection (relative to the undeflected position); Directed along the zc1- and zb1-axes -ElastoDyn['TipDzb1'] = True # (m); Blade 1 axial tip deflection (relative to the undeflected position); Directed along the zc1- and zb1-axes -ElastoDyn['TipDxb1'] = True # (m); Blade 1 flapwise tip deflection (relative to the undeflected position); Directed along the xb1-axis -ElastoDyn['TipDyb1'] = True # (m); Blade 1 edgewise tip deflection (relative to the undeflected position); Directed along the yb1-axis -ElastoDyn['TipALxb1'] = False # (m/s^2); Blade 1 local flapwise tip acceleration (absolute); Directed along the local xb1-axis -ElastoDyn['TipALyb1'] = False # (m/s^2); Blade 1 local edgewise tip acceleration (absolute); Directed along the local yb1-axis -ElastoDyn['TipALzb1'] = False # (m/s^2); Blade 1 local axial tip acceleration (absolute); Directed along the local zb1-axis -ElastoDyn['TipRDxb1'] = False # (deg); Blade 1 roll (angular/rotational) tip deflection (relative to the undeflected position). In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the xb1-axis -ElastoDyn['RollDefl1'] = False # (deg); Blade 1 roll (angular/rotational) tip deflection (relative to the undeflected position). In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the xb1-axis -ElastoDyn['TipRDyb1'] = False # (deg); Blade 1 pitch (angular/rotational) tip deflection (relative to the undeflected position). In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the yb1-axis -ElastoDyn['PtchDefl1'] = False # (deg); Blade 1 pitch (angular/rotational) tip deflection (relative to the undeflected position). In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the yb1-axis -ElastoDyn['TipRDzc1'] = False # (deg); Blade 1 torsional tip deflection (relative to the undeflected position). This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the zc1- and zb1-axes -ElastoDyn['TipRDzb1'] = False # (deg); Blade 1 torsional tip deflection (relative to the undeflected position). This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the zc1- and zb1-axes -ElastoDyn['TwstDefl1'] = False # (deg); Blade 1 torsional tip deflection (relative to the undeflected position). This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the zc1- and zb1-axes -ElastoDyn['TipClrnc1'] = False # (m); Blade 1 tip-to-tower clearance estimate. This is computed as the perpendicular distance from the yaw axis to the tip of blade 1 when the blade tip is below the yaw bearing. When the tip of blade 1 is above the yaw bearing, it is computed as the absolute distance from the yaw bearing to the blade tip. Please note that you should reduce this value by the tower radius to obtain the actual tower clearance.; N/A -ElastoDyn['TwrClrnc1'] = False # (m); Blade 1 tip-to-tower clearance estimate. This is computed as the perpendicular distance from the yaw axis to the tip of blade 1 when the blade tip is below the yaw bearing. When the tip of blade 1 is above the yaw bearing, it is computed as the absolute distance from the yaw bearing to the blade tip. Please note that you should reduce this value by the tower radius to obtain the actual tower clearance.; N/A -ElastoDyn['Tip2Twr1'] = False # (m); Blade 1 tip-to-tower clearance estimate. This is computed as the perpendicular distance from the yaw axis to the tip of blade 1 when the blade tip is below the yaw bearing. When the tip of blade 1 is above the yaw bearing, it is computed as the absolute distance from the yaw bearing to the blade tip. Please note that you should reduce this value by the tower radius to obtain the actual tower clearance.; N/A +""" AeroDyn """ +AeroDyn = {} -# Blade 2 Tip Motions -ElastoDyn['TipDxc2'] = True # (m); Blade 2 out-of-plane tip deflection (relative to the pitch axis); Directed along the xc2-axis -ElastoDyn['OoPDefl2'] = False # (m); Blade 2 out-of-plane tip deflection (relative to the pitch axis); Directed along the xc2-axis -ElastoDyn['TipDyc2'] = True # (m); Blade 2 in-plane tip deflection (relative to the pitch axis); Directed along the yc2-axis -ElastoDyn['IPDefl2'] = False # (m); Blade 2 in-plane tip deflection (relative to the pitch axis); Directed along the yc2-axis -ElastoDyn['TipDzc2'] = True # (m); Blade 2 axial tip deflection (relative to the pitch axis); Directed along the zc2- and zb2-axes -ElastoDyn['TipDzb2'] = True # (m); Blade 2 axial tip deflection (relative to the pitch axis); Directed along the zc2- and zb2-axes -ElastoDyn['TipDxb2'] = True # (m); Blade 2 flapwise tip deflection (relative to the pitch axis); Directed along the xb2-axis -ElastoDyn['TipDyb2'] = True # (m); Blade 2 edgewise tip deflection (relative to the pitch axis); Directed along the yb2-axis -ElastoDyn['TipALxb2'] = False # (m/s^2); Blade 2 local flapwise tip acceleration (absolute); Directed along the local xb2-axis -ElastoDyn['TipALyb2'] = False # (m/s^2); Blade 2 local edgewise tip acceleration (absolute); Directed along the local yb2-axis -ElastoDyn['TipALzb2'] = False # (m/s^2); Blade 2 local axial tip acceleration (absolute); Directed along the local zb2-axis -ElastoDyn['TipRDxb2'] = False # (deg); Blade 2 roll (angular/rotational) tip deflection (relative to the undeflected position). In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the xb2-axis -ElastoDyn['RollDefl2'] = False # (deg); Blade 2 roll (angular/rotational) tip deflection (relative to the undeflected position). In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the xb2-axis -ElastoDyn['TipRDyb2'] = False # (deg); Blade 2 pitch (angular/rotational) tip deflection (relative to the undeflected position). In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the yb2-axis -ElastoDyn['PtchDefl2'] = False # (deg); Blade 2 pitch (angular/rotational) tip deflection (relative to the undeflected position). In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the yb2-axis -ElastoDyn['TipRDzc2'] = False # (deg); Blade 2 torsional (angular/rotational) tip deflection (relative to the undeflected position). This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the zc2- and zb2-axes -ElastoDyn['TipRDzb2'] = False # (deg); Blade 2 torsional (angular/rotational) tip deflection (relative to the undeflected position). This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the zc2- and zb2-axes -ElastoDyn['TwstDefl2'] = False # (deg); Blade 2 torsional (angular/rotational) tip deflection (relative to the undeflected position). This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the zc2- and zb2-axes -ElastoDyn['TipClrnc2'] = False # (m); Blade 2 tip-to-tower clearance estimate. This is computed as the perpendicular distance from the yaw axis to the tip of blade 1 when the blade tip is below the yaw bearing. When the tip of blade 1 is above the yaw bearing, it is computed as the absolute distance from the yaw bearing to the blade tip. Please note that you should reduce this value by the tower radius to obtain the actual tower clearance.; N/A -ElastoDyn['TwrClrnc2'] = False # (m); Blade 2 tip-to-tower clearance estimate. This is computed as the perpendicular distance from the yaw axis to the tip of blade 1 when the blade tip is below the yaw bearing. When the tip of blade 1 is above the yaw bearing, it is computed as the absolute distance from the yaw bearing to the blade tip. Please note that you should reduce this value by the tower radius to obtain the actual tower clearance.; N/A -ElastoDyn['Tip2Twr2'] = False # (m); Blade 2 tip-to-tower clearance estimate. This is computed as the perpendicular distance from the yaw axis to the tip of blade 1 when the blade tip is below the yaw bearing. When the tip of blade 1 is above the yaw bearing, it is computed as the absolute distance from the yaw bearing to the blade tip. Please note that you should reduce this value by the tower radius to obtain the actual tower clearance.; N/A +# Tower +AeroDyn['TwN1VUndx'] = False # (m/s); Undisturbed x-component wind velocity at Tw node 1; local tower coordinate system +AeroDyn['TwN1VUndy'] = False # (m/s); Undisturbed y-component wind velocity at Tw node 1; local tower coordinate system +AeroDyn['TwN1VUndz'] = False # (m/s); Undisturbed z-component wind velocity at Tw node 1; local tower coordinate system +AeroDyn['TwN2VUndx'] = False # (m/s); Undisturbed x-component wind velocity at Tw node 2; local tower coordinate system +AeroDyn['TwN2VUndy'] = False # (m/s); Undisturbed y-component wind velocity at Tw node 2; local tower coordinate system +AeroDyn['TwN2VUndz'] = False # (m/s); Undisturbed z-component wind velocity at Tw node 2; local tower coordinate system +AeroDyn['TwN3VUndx'] = False # (m/s); Undisturbed x-component wind velocity at Tw node 3; local tower coordinate system +AeroDyn['TwN3VUndy'] = False # (m/s); Undisturbed y-component wind velocity at Tw node 3; local tower coordinate system +AeroDyn['TwN3VUndz'] = False # (m/s); Undisturbed z-component wind velocity at Tw node 3; local tower coordinate system +AeroDyn['TwN4VUndx'] = False # (m/s); Undisturbed x-component wind velocity at Tw node 4; local tower coordinate system +AeroDyn['TwN4VUndy'] = False # (m/s); Undisturbed y-component wind velocity at Tw node 4; local tower coordinate system +AeroDyn['TwN4VUndz'] = False # (m/s); Undisturbed z-component wind velocity at Tw node 4; local tower coordinate system +AeroDyn['TwN5VUndx'] = False # (m/s); Undisturbed x-component wind velocity at Tw node 5; local tower coordinate system +AeroDyn['TwN5VUndy'] = False # (m/s); Undisturbed y-component wind velocity at Tw node 5; local tower coordinate system +AeroDyn['TwN5VUndz'] = False # (m/s); Undisturbed z-component wind velocity at Tw node 5; local tower coordinate system +AeroDyn['TwN6VUndx'] = False # (m/s); Undisturbed x-component wind velocity at Tw node 6; local tower coordinate system +AeroDyn['TwN6VUndy'] = False # (m/s); Undisturbed y-component wind velocity at Tw node 6; local tower coordinate system +AeroDyn['TwN6VUndz'] = False # (m/s); Undisturbed z-component wind velocity at Tw node 6; local tower coordinate system +AeroDyn['TwN7VUndx'] = False # (m/s); Undisturbed x-component wind velocity at Tw node 7; local tower coordinate system +AeroDyn['TwN7VUndy'] = False # (m/s); Undisturbed y-component wind velocity at Tw node 7; local tower coordinate system +AeroDyn['TwN7VUndz'] = False # (m/s); Undisturbed z-component wind velocity at Tw node 7; local tower coordinate system +AeroDyn['TwN8VUndx'] = False # (m/s); Undisturbed x-component wind velocity at Tw node 8; local tower coordinate system +AeroDyn['TwN8VUndy'] = False # (m/s); Undisturbed y-component wind velocity at Tw node 8; local tower coordinate system +AeroDyn['TwN8VUndz'] = False # (m/s); Undisturbed z-component wind velocity at Tw node 8; local tower coordinate system +AeroDyn['TwN9VUndx'] = False # (m/s); Undisturbed x-component wind velocity at Tw node 9; local tower coordinate system +AeroDyn['TwN9VUndy'] = False # (m/s); Undisturbed y-component wind velocity at Tw node 9; local tower coordinate system +AeroDyn['TwN9VUndz'] = False # (m/s); Undisturbed z-component wind velocity at Tw node 9; local tower coordinate system +AeroDyn['TwN1STVx'] = False # (m/s); Structural translational velocity x-component at Tw node 1; local tower coordinate system +AeroDyn['TwN1STVy'] = False # (m/s); Structural translational velocity y-component at Tw node 1; local tower coordinate system +AeroDyn['TwN1STVz'] = False # (m/s); Structural translational velocity z-component at Tw node 1; local tower coordinate system +AeroDyn['TwN2STVx'] = False # (m/s); Structural translational velocity x-component at Tw node 2; local tower coordinate system +AeroDyn['TwN2STVy'] = False # (m/s); Structural translational velocity y-component at Tw node 2; local tower coordinate system +AeroDyn['TwN2STVz'] = False # (m/s); Structural translational velocity z-component at Tw node 2; local tower coordinate system +AeroDyn['TwN3STVx'] = False # (m/s); Structural translational velocity x-component at Tw node 3; local tower coordinate system +AeroDyn['TwN3STVy'] = False # (m/s); Structural translational velocity y-component at Tw node 3; local tower coordinate system +AeroDyn['TwN3STVz'] = False # (m/s); Structural translational velocity z-component at Tw node 3; local tower coordinate system +AeroDyn['TwN4STVx'] = False # (m/s); Structural translational velocity x-component at Tw node 4; local tower coordinate system +AeroDyn['TwN4STVy'] = False # (m/s); Structural translational velocity y-component at Tw node 4; local tower coordinate system +AeroDyn['TwN4STVz'] = False # (m/s); Structural translational velocity z-component at Tw node 4; local tower coordinate system +AeroDyn['TwN5STVx'] = False # (m/s); Structural translational velocity x-component at Tw node 5; local tower coordinate system +AeroDyn['TwN5STVy'] = False # (m/s); Structural translational velocity y-component at Tw node 5; local tower coordinate system +AeroDyn['TwN5STVz'] = False # (m/s); Structural translational velocity z-component at Tw node 5; local tower coordinate system +AeroDyn['TwN6STVx'] = False # (m/s); Structural translational velocity x-component at Tw node 6; local tower coordinate system +AeroDyn['TwN6STVy'] = False # (m/s); Structural translational velocity y-component at Tw node 6; local tower coordinate system +AeroDyn['TwN6STVz'] = False # (m/s); Structural translational velocity z-component at Tw node 6; local tower coordinate system +AeroDyn['TwN7STVx'] = False # (m/s); Structural translational velocity x-component at Tw node 7; local tower coordinate system +AeroDyn['TwN7STVy'] = False # (m/s); Structural translational velocity y-component at Tw node 7; local tower coordinate system +AeroDyn['TwN7STVz'] = False # (m/s); Structural translational velocity z-component at Tw node 7; local tower coordinate system +AeroDyn['TwN8STVx'] = False # (m/s); Structural translational velocity x-component at Tw node 8; local tower coordinate system +AeroDyn['TwN8STVy'] = False # (m/s); Structural translational velocity y-component at Tw node 8; local tower coordinate system +AeroDyn['TwN8STVz'] = False # (m/s); Structural translational velocity z-component at Tw node 8; local tower coordinate system +AeroDyn['TwN9STVx'] = False # (m/s); Structural translational velocity x-component at Tw node 9; local tower coordinate system +AeroDyn['TwN9STVy'] = False # (m/s); Structural translational velocity y-component at Tw node 9; local tower coordinate system +AeroDyn['TwN9STVz'] = False # (m/s); Structural translational velocity z-component at Tw node 9; local tower coordinate system +AeroDyn['TwN1Vrel'] = False # (m/s); Relative wind speed at Tw node 1; +AeroDyn['TwN2Vrel'] = False # (m/s); Relative wind speed at Tw node 2; +AeroDyn['TwN3Vrel'] = False # (m/s); Relative wind speed at Tw node 3; +AeroDyn['TwN4Vrel'] = False # (m/s); Relative wind speed at Tw node 4; +AeroDyn['TwN5Vrel'] = False # (m/s); Relative wind speed at Tw node 5; +AeroDyn['TwN6Vrel'] = False # (m/s); Relative wind speed at Tw node 6; +AeroDyn['TwN7Vrel'] = False # (m/s); Relative wind speed at Tw node 7; +AeroDyn['TwN8Vrel'] = False # (m/s); Relative wind speed at Tw node 8; +AeroDyn['TwN9Vrel'] = False # (m/s); Relative wind speed at Tw node 9; +AeroDyn['TwN1DynP'] = False # (Pa); Dynamic Pressure at Tw node 1; +AeroDyn['TwN2DynP'] = False # (Pa); Dynamic Pressure at Tw node 2; +AeroDyn['TwN3DynP'] = False # (Pa); Dynamic Pressure at Tw node 3; +AeroDyn['TwN4DynP'] = False # (Pa); Dynamic Pressure at Tw node 4; +AeroDyn['TwN5DynP'] = False # (Pa); Dynamic Pressure at Tw node 5; +AeroDyn['TwN6DynP'] = False # (Pa); Dynamic Pressure at Tw node 6; +AeroDyn['TwN7DynP'] = False # (Pa); Dynamic Pressure at Tw node 7; +AeroDyn['TwN8DynP'] = False # (Pa); Dynamic Pressure at Tw node 8; +AeroDyn['TwN9DynP'] = False # (Pa); Dynamic Pressure at Tw node 9; +AeroDyn['TwN1Re'] = False # (-); Reynolds number (in millions) at Tw node 1; +AeroDyn['TwN2Re'] = False # (-); Reynolds number (in millions) at Tw node 2; +AeroDyn['TwN3Re'] = False # (-); Reynolds number (in millions) at Tw node 3; +AeroDyn['TwN4Re'] = False # (-); Reynolds number (in millions) at Tw node 4; +AeroDyn['TwN5Re'] = False # (-); Reynolds number (in millions) at Tw node 5; +AeroDyn['TwN6Re'] = False # (-); Reynolds number (in millions) at Tw node 6; +AeroDyn['TwN7Re'] = False # (-); Reynolds number (in millions) at Tw node 7; +AeroDyn['TwN8Re'] = False # (-); Reynolds number (in millions) at Tw node 8; +AeroDyn['TwN9Re'] = False # (-); Reynolds number (in millions) at Tw node 9; +AeroDyn['TwN1M'] = False # (-); Mach number at Tw node 1; +AeroDyn['TwN2M'] = False # (-); Mach number at Tw node 2; +AeroDyn['TwN3M'] = False # (-); Mach number at Tw node 3; +AeroDyn['TwN4M'] = False # (-); Mach number at Tw node 4; +AeroDyn['TwN5M'] = False # (-); Mach number at Tw node 5; +AeroDyn['TwN6M'] = False # (-); Mach number at Tw node 6; +AeroDyn['TwN7M'] = False # (-); Mach number at Tw node 7; +AeroDyn['TwN8M'] = False # (-); Mach number at Tw node 8; +AeroDyn['TwN9M'] = False # (-); Mach number at Tw node 9; +AeroDyn['TwN1Fdx'] = False # (N/m); x-component of drag force per unit length at Tw node 1; local tower coordinate system +AeroDyn['TwN2Fdx'] = False # (N/m); x-component of drag force per unit length at Tw node 2; local tower coordinate system +AeroDyn['TwN3Fdx'] = False # (N/m); x-component of drag force per unit length at Tw node 3; local tower coordinate system +AeroDyn['TwN4Fdx'] = False # (N/m); x-component of drag force per unit length at Tw node 4; local tower coordinate system +AeroDyn['TwN5Fdx'] = False # (N/m); x-component of drag force per unit length at Tw node 5; local tower coordinate system +AeroDyn['TwN6Fdx'] = False # (N/m); x-component of drag force per unit length at Tw node 6; local tower coordinate system +AeroDyn['TwN7Fdx'] = False # (N/m); x-component of drag force per unit length at Tw node 7; local tower coordinate system +AeroDyn['TwN8Fdx'] = False # (N/m); x-component of drag force per unit length at Tw node 8; local tower coordinate system +AeroDyn['TwN9Fdx'] = False # (N/m); x-component of drag force per unit length at Tw node 9; local tower coordinate system +AeroDyn['TwN1Fdy'] = False # (N/m); y-component of drag force per unit length at Tw node 1; local tower coordinate system +AeroDyn['TwN2Fdy'] = False # (N/m); y-component of drag force per unit length at Tw node 2; local tower coordinate system +AeroDyn['TwN3Fdy'] = False # (N/m); y-component of drag force per unit length at Tw node 3; local tower coordinate system +AeroDyn['TwN4Fdy'] = False # (N/m); y-component of drag force per unit length at Tw node 4; local tower coordinate system +AeroDyn['TwN5Fdy'] = False # (N/m); y-component of drag force per unit length at Tw node 5; local tower coordinate system +AeroDyn['TwN6Fdy'] = False # (N/m); y-component of drag force per unit length at Tw node 6; local tower coordinate system +AeroDyn['TwN7Fdy'] = False # (N/m); y-component of drag force per unit length at Tw node 7; local tower coordinate system +AeroDyn['TwN8Fdy'] = False # (N/m); y-component of drag force per unit length at Tw node 8; local tower coordinate system +AeroDyn['TwN9Fdy'] = False # (N/m); y-component of drag force per unit length at Tw node 9; local tower coordinate system +AeroDyn['TwN1Fbx'] = False # (N/m); x-component of buoyant force per unit length at Tw node 1; local tower coordinate system +AeroDyn['TwN2Fbx'] = False # (N/m); x-component of buoyant force per unit length at Tw node 2; local tower coordinate system +AeroDyn['TwN3Fbx'] = False # (N/m); x-component of buoyant force per unit length at Tw node 3; local tower coordinate system +AeroDyn['TwN4Fbx'] = False # (N/m); x-component of buoyant force per unit length at Tw node 4; local tower coordinate system +AeroDyn['TwN5Fbx'] = False # (N/m); x-component of buoyant force per unit length at Tw node 5; local tower coordinate system +AeroDyn['TwN6Fbx'] = False # (N/m); x-component of buoyant force per unit length at Tw node 6; local tower coordinate system +AeroDyn['TwN7Fbx'] = False # (N/m); x-component of buoyant force per unit length at Tw node 7; local tower coordinate system +AeroDyn['TwN8Fbx'] = False # (N/m); x-component of buoyant force per unit length at Tw node 8; local tower coordinate system +AeroDyn['TwN9Fbx'] = False # (N/m); x-component of buoyant force per unit length at Tw node 9; local tower coordinate system +AeroDyn['TwN1Fby'] = False # (N/m); y-component of buoyant force per unit length at Tw node 1; local tower coordinate system +AeroDyn['TwN2Fby'] = False # (N/m); y-component of buoyant force per unit length at Tw node 2; local tower coordinate system +AeroDyn['TwN3Fby'] = False # (N/m); y-component of buoyant force per unit length at Tw node 3; local tower coordinate system +AeroDyn['TwN4Fby'] = False # (N/m); y-component of buoyant force per unit length at Tw node 4; local tower coordinate system +AeroDyn['TwN5Fby'] = False # (N/m); y-component of buoyant force per unit length at Tw node 5; local tower coordinate system +AeroDyn['TwN6Fby'] = False # (N/m); y-component of buoyant force per unit length at Tw node 6; local tower coordinate system +AeroDyn['TwN7Fby'] = False # (N/m); y-component of buoyant force per unit length at Tw node 7; local tower coordinate system +AeroDyn['TwN8Fby'] = False # (N/m); y-component of buoyant force per unit length at Tw node 8; local tower coordinate system +AeroDyn['TwN9Fby'] = False # (N/m); y-component of buoyant force per unit length at Tw node 9; local tower coordinate system +AeroDyn['TwN1Fbz'] = False # (N/m); z-component of buoyant force per unit length at Tw node 1; local tower coordinate system +AeroDyn['TwN2Fbz'] = False # (N/m); z-component of buoyant force per unit length at Tw node 2; local tower coordinate system +AeroDyn['TwN3Fbz'] = False # (N/m); z-component of buoyant force per unit length at Tw node 3; local tower coordinate system +AeroDyn['TwN4Fbz'] = False # (N/m); z-component of buoyant force per unit length at Tw node 4; local tower coordinate system +AeroDyn['TwN5Fbz'] = False # (N/m); z-component of buoyant force per unit length at Tw node 5; local tower coordinate system +AeroDyn['TwN6Fbz'] = False # (N/m); z-component of buoyant force per unit length at Tw node 6; local tower coordinate system +AeroDyn['TwN7Fbz'] = False # (N/m); z-component of buoyant force per unit length at Tw node 7; local tower coordinate system +AeroDyn['TwN8Fbz'] = False # (N/m); z-component of buoyant force per unit length at Tw node 8; local tower coordinate system +AeroDyn['TwN9Fbz'] = False # (N/m); z-component of buoyant force per unit length at Tw node 9; local tower coordinate system +AeroDyn['TwN1Mbx'] = False # (N-m/m); x-component of buoyant moment per unit length at Tw node 1; local tower coordinate system +AeroDyn['TwN2Mbx'] = False # (N-m/m); x-component of buoyant moment per unit length at Tw node 2; local tower coordinate system +AeroDyn['TwN3Mbx'] = False # (N-m/m); x-component of buoyant moment per unit length at Tw node 3; local tower coordinate system +AeroDyn['TwN4Mbx'] = False # (N-m/m); x-component of buoyant moment per unit length at Tw node 4; local tower coordinate system +AeroDyn['TwN5Mbx'] = False # (N-m/m); x-component of buoyant moment per unit length at Tw node 5; local tower coordinate system +AeroDyn['TwN6Mbx'] = False # (N-m/m); x-component of buoyant moment per unit length at Tw node 6; local tower coordinate system +AeroDyn['TwN7Mbx'] = False # (N-m/m); x-component of buoyant moment per unit length at Tw node 7; local tower coordinate system +AeroDyn['TwN8Mbx'] = False # (N-m/m); x-component of buoyant moment per unit length at Tw node 8; local tower coordinate system +AeroDyn['TwN9Mbx'] = False # (N-m/m); x-component of buoyant moment per unit length at Tw node 9; local tower coordinate system +AeroDyn['TwN1Mby'] = False # (N-m/m); y-component of buoyant moment per unit length at Tw node 1; local tower coordinate system +AeroDyn['TwN2Mby'] = False # (N-m/m); y-component of buoyant moment per unit length at Tw node 2; local tower coordinate system +AeroDyn['TwN3Mby'] = False # (N-m/m); y-component of buoyant moment per unit length at Tw node 3; local tower coordinate system +AeroDyn['TwN4Mby'] = False # (N-m/m); y-component of buoyant moment per unit length at Tw node 4; local tower coordinate system +AeroDyn['TwN5Mby'] = False # (N-m/m); y-component of buoyant moment per unit length at Tw node 5; local tower coordinate system +AeroDyn['TwN6Mby'] = False # (N-m/m); y-component of buoyant moment per unit length at Tw node 6; local tower coordinate system +AeroDyn['TwN7Mby'] = False # (N-m/m); y-component of buoyant moment per unit length at Tw node 7; local tower coordinate system +AeroDyn['TwN8Mby'] = False # (N-m/m); y-component of buoyant moment per unit length at Tw node 8; local tower coordinate system +AeroDyn['TwN9Mby'] = False # (N-m/m); y-component of buoyant moment per unit length at Tw node 9; local tower coordinate system +AeroDyn['TwN1Mbz'] = False # (N-m/m); z-component of buoyant moment per unit length at Tw node 1; local tower coordinate system +AeroDyn['TwN2Mbz'] = False # (N-m/m); z-component of buoyant moment per unit length at Tw node 2; local tower coordinate system +AeroDyn['TwN3Mbz'] = False # (N-m/m); z-component of buoyant moment per unit length at Tw node 3; local tower coordinate system +AeroDyn['TwN4Mbz'] = False # (N-m/m); z-component of buoyant moment per unit length at Tw node 4; local tower coordinate system +AeroDyn['TwN5Mbz'] = False # (N-m/m); z-component of buoyant moment per unit length at Tw node 5; local tower coordinate system +AeroDyn['TwN6Mbz'] = False # (N-m/m); z-component of buoyant moment per unit length at Tw node 6; local tower coordinate system +AeroDyn['TwN7Mbz'] = False # (N-m/m); z-component of buoyant moment per unit length at Tw node 7; local tower coordinate system +AeroDyn['TwN8Mbz'] = False # (N-m/m); z-component of buoyant moment per unit length at Tw node 8; local tower coordinate system +AeroDyn['TwN9Mbz'] = False # (N-m/m); z-component of buoyant moment per unit length at Tw node 9; local tower coordinate system -# Blade 3 Tip Motions -ElastoDyn['TipDxc3'] = True # (m); Blade 3 out-of-plane tip deflection (relative to the pitch axis); Directed along the xc3-axis -ElastoDyn['OoPDefl3'] = False # (m); Blade 3 out-of-plane tip deflection (relative to the pitch axis); Directed along the xc3-axis -ElastoDyn['TipDyc3'] = True # (m); Blade 3 in-plane tip deflection (relative to the pitch axis); Directed along the yc3-axis -ElastoDyn['IPDefl3'] = False # (m); Blade 3 in-plane tip deflection (relative to the pitch axis); Directed along the yc3-axis -ElastoDyn['TipDzc3'] = True # (m); Blade 3 axial tip deflection (relative to the pitch axis); Directed along the zc3- and zb3-axes -ElastoDyn['TipDzb3'] = True # (m); Blade 3 axial tip deflection (relative to the pitch axis); Directed along the zc3- and zb3-axes -ElastoDyn['TipDxb3'] = True # (m); Blade 3 flapwise tip deflection (relative to the pitch axis); Directed along the xb3-axis -ElastoDyn['TipDyb3'] = True # (m); Blade 3 edgewise tip deflection (relative to the pitch axis); Directed along the yb3-axis -ElastoDyn['TipALxb3'] = False # (m/s^2); Blade 3 local flapwise tip acceleration (absolute); Directed along the local xb3-axis -ElastoDyn['TipALyb3'] = False # (m/s^2); Blade 3 local edgewise tip acceleration (absolute); Directed along the local yb3-axis -ElastoDyn['TipALzb3'] = False # (m/s^2); Blade 3 local axial tip acceleration (absolute); Directed along the local zb3-axis -ElastoDyn['TipRDxb3'] = False # (deg); Blade 3 roll (angular/rotational) tip deflection (relative to the undeflected position). In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the xb3-axis -ElastoDyn['RollDefl3'] = False # (deg); Blade 3 roll (angular/rotational) tip deflection (relative to the undeflected position). In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the xb3-axis -ElastoDyn['TipRDyb3'] = False # (deg); Blade 3 pitch (angular/rotational) tip deflection (relative to the undeflected position). In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the yb3-axis -ElastoDyn['PtchDefl3'] = False # (deg); Blade 3 pitch (angular/rotational) tip deflection (relative to the undeflected position). In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the yb3-axis -ElastoDyn['TipRDzc3'] = False # (deg); Blade 3 torsional tip deflection (relative to the undeflected position). This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the zc3- and zb3-axes -ElastoDyn['TipRDzb3'] = False # (deg); Blade 3 torsional tip deflection (relative to the undeflected position). This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the zc3- and zb3-axes -ElastoDyn['TwstDefl3'] = False # (deg); Blade 3 torsional tip deflection (relative to the undeflected position). This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the zc3- and zb3-axes -ElastoDyn['TipClrnc3'] = False # (m); Blade 3 tip-to-tower clearance estimate. This is computed as the perpendicular distance from the yaw axis to the tip of blade 1 when the blade tip is below the yaw bearing. When the tip of blade 1 is above the yaw bearing, it is computed as the absolute distance from the yaw bearing to the blade tip. Please note that you should reduce this value by the tower radius to obtain the actual tower clearance.; N/A -ElastoDyn['TwrClrnc3'] = False # (m); Blade 3 tip-to-tower clearance estimate. This is computed as the perpendicular distance from the yaw axis to the tip of blade 1 when the blade tip is below the yaw bearing. When the tip of blade 1 is above the yaw bearing, it is computed as the absolute distance from the yaw bearing to the blade tip. Please note that you should reduce this value by the tower radius to obtain the actual tower clearance.; N/A -ElastoDyn['Tip2Twr3'] = False # (m); Blade 3 tip-to-tower clearance estimate. This is computed as the perpendicular distance from the yaw axis to the tip of blade 1 when the blade tip is below the yaw bearing. When the tip of blade 1 is above the yaw bearing, it is computed as the absolute distance from the yaw bearing to the blade tip. Please note that you should reduce this value by the tower radius to obtain the actual tower clearance.; N/A - -# Blade 1 Local Span Motions -ElastoDyn['Spn1ALxb1'] = False # (m/s^2); Blade 1 local flapwise acceleration (absolute) of span station 1; Directed along the local xb1-axis -ElastoDyn['Spn1ALyb1'] = False # (m/s^2); Blade 1 local edgewise acceleration (absolute) of span station 1; Directed along the local yb1-axis -ElastoDyn['Spn1ALzb1'] = False # (m/s^2); Blade 1 local axial acceleration (absolute) of span station 1; Directed along the local zb1-axis -ElastoDyn['Spn2ALxb1'] = False # (m/s^2); Blade 1 local flapwise acceleration (absolute) of span station 2; Directed along the local xb1-axis -ElastoDyn['Spn2ALyb1'] = False # (m/s^2); Blade 1 local edgewise acceleration (absolute) of span station 2; Directed along the local yb1-axis -ElastoDyn['Spn2ALzb1'] = False # (m/s^2); Blade 1 local axial acceleration (absolute) of span station 2; Directed along the local zb1-axis -ElastoDyn['Spn3ALxb1'] = False # (m/s^2); Blade 1 local flapwise acceleration (absolute) of span station 3; Directed along the local xb1-axis -ElastoDyn['Spn3ALyb1'] = False # (m/s^2); Blade 1 local edgewise acceleration (absolute) of span station 3; Directed along the local yb1-axis -ElastoDyn['Spn3ALzb1'] = False # (m/s^2); Blade 1 local axial acceleration (absolute) of span station 3; Directed along the local zb1-axis -ElastoDyn['Spn4ALxb1'] = False # (m/s^2); Blade 1 local flapwise acceleration (absolute) of span station 4; Directed along the local xb1-axis -ElastoDyn['Spn4ALyb1'] = False # (m/s^2); Blade 1 local edgewise acceleration (absolute) of span station 4; Directed along the local yb1-axis -ElastoDyn['Spn4ALzb1'] = False # (m/s^2); Blade 1 local axial acceleration (absolute) of span station 4; Directed along the local zb1-axis -ElastoDyn['Spn5ALxb1'] = False # (m/s^2); Blade 1 local flapwise acceleration (absolute) of span station 5; Directed along the local xb1-axis -ElastoDyn['Spn5ALyb1'] = False # (m/s^2); Blade 1 local edgewise acceleration (absolute) of span station 5; Directed along the local yb1-axis -ElastoDyn['Spn5ALzb1'] = False # (m/s^2); Blade 1 local axial acceleration (absolute) of span station 5; Directed along the local zb1-axis -ElastoDyn['Spn6ALxb1'] = False # (m/s^2); Blade 1 local flapwise acceleration (absolute) of span station 6; Directed along the local xb1-axis -ElastoDyn['Spn6ALyb1'] = False # (m/s^2); Blade 1 local edgewise acceleration (absolute) of span station 6; Directed along the local yb1-axis -ElastoDyn['Spn6ALzb1'] = False # (m/s^2); Blade 1 local axial acceleration (absolute) of span station 6; Directed along the local zb1-axis -ElastoDyn['Spn7ALxb1'] = False # (m/s^2); Blade 1 local flapwise acceleration (absolute) of span station 7; Directed along the local xb1-axis -ElastoDyn['Spn7ALyb1'] = False # (m/s^2); Blade 1 local edgewise acceleration (absolute) of span station 7; Directed along the local yb1-axis -ElastoDyn['Spn7ALzb1'] = False # (m/s^2); Blade 1 local axial acceleration (absolute) of span station 7; Directed along the local zb1-axis -ElastoDyn['Spn8ALxb1'] = False # (m/s^2); Blade 1 local flapwise acceleration (absolute) of span station 8; Directed along the local xb1-axis -ElastoDyn['Spn8ALyb1'] = False # (m/s^2); Blade 1 local edgewise acceleration (absolute) of span station 8; Directed along the local yb1-axis -ElastoDyn['Spn8ALzb1'] = False # (m/s^2); Blade 1 local axial acceleration (absolute) of span station 8; Directed along the local zb1-axis -ElastoDyn['Spn9ALxb1'] = False # (m/s^2); Blade 1 local flapwise acceleration (absolute) of span station 9; Directed along the local xb1-axis -ElastoDyn['Spn9ALyb1'] = False # (m/s^2); Blade 1 local edgewise acceleration (absolute) of span station 9; Directed along the local yb1-axis -ElastoDyn['Spn9ALzb1'] = False # (m/s^2); Blade 1 local axial acceleration (absolute) of span station 9; Directed along the local zb1-axis -ElastoDyn['Spn1TDxb1'] = False # (m); Blade 1 local flapwise (translational) deflection (relative to the undeflected position) of span station 1; Directed along the xb1-axis -ElastoDyn['Spn1TDyb1'] = False # (m); Blade 1 local edgewise (translational) deflection (relative to the undeflected position) of span station 1; Directed along the yb1-axis -ElastoDyn['Spn1TDzb1'] = False # (m); Blade 1 local axial (translational) deflection (relative to the undeflected position) of span station 1; Directed along the zb1-axis -ElastoDyn['Spn2TDxb1'] = False # (m); Blade 1 local flapwise (translational) deflection (relative to the undeflected position) of span station 2; Directed along the xb1-axis -ElastoDyn['Spn2TDyb1'] = False # (m); Blade 1 local edgewise (translational) deflection (relative to the undeflected position) of span station 2; Directed along the yb1-axis -ElastoDyn['Spn2TDzb1'] = False # (m); Blade 1 local axial (translational) deflection (relative to the undeflected position) of span station 2; Directed along the zb1-axis -ElastoDyn['Spn3TDxb1'] = False # (m); Blade 1 local flapwise (translational) deflection (relative to the undeflected position) of span station 3; Directed along the xb1-axis -ElastoDyn['Spn3TDyb1'] = False # (m); Blade 1 local edgewise (translational) deflection (relative to the undeflected position) of span station 3; Directed along the yb1-axis -ElastoDyn['Spn3TDzb1'] = False # (m); Blade 1 local axial (translational) deflection (relative to the undeflected position) of span station 3; Directed along the zb1-axis -ElastoDyn['Spn4TDxb1'] = False # (m); Blade 1 local flapwise (translational) deflection (relative to the undeflected position) of span station 4; Directed along the xb1-axis -ElastoDyn['Spn4TDyb1'] = False # (m); Blade 1 local edgewise (translational) deflection (relative to the undeflected position) of span station 4; Directed along the yb1-axis -ElastoDyn['Spn4TDzb1'] = False # (m); Blade 1 local axial (translational) deflection (relative to the undeflected position) of span station 4; Directed along the zb1-axis -ElastoDyn['Spn5TDxb1'] = False # (m); Blade 1 local flapwise (translational) deflection (relative to the undeflected position) of span station 5; Directed along the xb1-axis -ElastoDyn['Spn5TDyb1'] = False # (m); Blade 1 local edgewise (translational) deflection (relative to the undeflected position) of span station 5; Directed along the yb1-axis -ElastoDyn['Spn5TDzb1'] = False # (m); Blade 1 local axial (translational) deflection (relative to the undeflected position) of span station 5; Directed along the zb1-axis -ElastoDyn['Spn6TDxb1'] = False # (m); Blade 1 local flapwise (translational) deflection (relative to the undeflected position) of span station 6; Directed along the xb1-axis -ElastoDyn['Spn6TDyb1'] = False # (m); Blade 1 local edgewise (translational) deflection (relative to the undeflected position) of span station 6; Directed along the yb1-axis -ElastoDyn['Spn6TDzb1'] = False # (m); Blade 1 local axial (translational) deflection (relative to the undeflected position) of span station 6; Directed along the zb1-axis -ElastoDyn['Spn7TDxb1'] = False # (m); Blade 1 local flapwise (translational) deflection (relative to the undeflected position) of span station 7; Directed along the xb1-axis -ElastoDyn['Spn7TDyb1'] = False # (m); Blade 1 local edgewise (translational) deflection (relative to the undeflected position) of span station 7; Directed along the yb1-axis -ElastoDyn['Spn7TDzb1'] = False # (m); Blade 1 local axial (translational) deflection (relative to the undeflected position) of span station 7; Directed along the zb1-axis -ElastoDyn['Spn8TDxb1'] = False # (m); Blade 1 local flapwise (translational) deflection (relative to the undeflected position) of span station 8; Directed along the xb1-axis -ElastoDyn['Spn8TDyb1'] = False # (m); Blade 1 local edgewise (translational) deflection (relative to the undeflected position) of span station 8; Directed along the yb1-axis -ElastoDyn['Spn8TDzb1'] = False # (m); Blade 1 local axial (translational) deflection (relative to the undeflected position) of span station 8; Directed along the zb1-axis -ElastoDyn['Spn9TDxb1'] = False # (m); Blade 1 local flapwise (translational) deflection (relative to the undeflected position) of span station 9; Directed along the xb1-axis -ElastoDyn['Spn9TDyb1'] = False # (m); Blade 1 local edgewise (translational) deflection (relative to the undeflected position) of span station 9; Directed along the yb1-axis -ElastoDyn['Spn9TDzb1'] = False # (m); Blade 1 local axial (translational) deflection (relative to the undeflected position) of span station 9; Directed along the zb1-axis -ElastoDyn['Spn1RDxb1'] = False # (deg); Blade 1 local roll (angular/rotational) deflection (relative to the undeflected position) of span station 1. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local xb1-axis -ElastoDyn['Spn1RDyb1'] = False # (deg); Blade 1 local pitch (angular/rotational) deflection (relative to the undeflected position) of span station 1. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local yb1-axis -ElastoDyn['Spn1RDzb1'] = False # (deg); Blade 1 local torsional (angular/rotational) deflection (relative to the undeflected position) of span station 1. This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the local zb1-axis -ElastoDyn['Spn2RDxb1'] = False # (deg); Blade 1 local roll (angular/rotational) deflection (relative to the undeflected position) of span station 2. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local xb1-axis -ElastoDyn['Spn2RDyb1'] = False # (deg); Blade 1 local pitch (angular/rotational) deflection (relative to the undeflected position) of span station 2. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local yb1-axis -ElastoDyn['Spn2RDzb1'] = False # (deg); Blade 1 local torsional (angular/rotational) deflection (relative to the undeflected position) of span station 2. This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the local zb1-axis -ElastoDyn['Spn3RDxb1'] = False # (deg); Blade 1 local roll (angular/rotational) deflection (relative to the undeflected position) of span station 3. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local xb1-axis -ElastoDyn['Spn3RDyb1'] = False # (deg); Blade 1 local pitch (angular/rotational) deflection (relative to the undeflected position) of span station 3. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local yb1-axis -ElastoDyn['Spn3RDzb1'] = False # (deg); Blade 1 local torsional (angular/rotational) deflection (relative to the undeflected position) of span station 3. This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the local zb1-axis -ElastoDyn['Spn4RDxb1'] = False # (deg); Blade 1 local roll (angular/rotational) deflection (relative to the undeflected position) of span station 4. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local xb1-axis -ElastoDyn['Spn4RDyb1'] = False # (deg); Blade 1 local pitch (angular/rotational) deflection (relative to the undeflected position) of span station 4. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local yb1-axis -ElastoDyn['Spn4RDzb1'] = False # (deg); Blade 1 local torsional (angular/rotational) deflection (relative to the undeflected position) of span station 4. This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the local zb1-axis -ElastoDyn['Spn5RDxb1'] = False # (deg); Blade 1 local roll (angular/rotational) deflection (relative to the undeflected position) of span station 5. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local xb1-axis -ElastoDyn['Spn5RDyb1'] = False # (deg); Blade 1 local pitch (angular/rotational) deflection (relative to the undeflected position) of span station 5. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local yb1-axis -ElastoDyn['Spn5RDzb1'] = False # (deg); Blade 1 local torsional (angular/rotational) deflection (relative to the undeflected position) of span station 5. This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the local zb1-axis -ElastoDyn['Spn6RDxb1'] = False # (deg); Blade 1 local roll (angular/rotational) deflection (relative to the undeflected position) of span station 6. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local xb1-axis -ElastoDyn['Spn6RDyb1'] = False # (deg); Blade 1 local pitch (angular/rotational) deflection (relative to the undeflected position) of span station 6. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local yb1-axis -ElastoDyn['Spn6RDzb1'] = False # (deg); Blade 1 local torsional (angular/rotational) deflection (relative to the undeflected position) of span station 6. This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the local zb1-axis -ElastoDyn['Spn7RDxb1'] = False # (deg); Blade 1 local roll (angular/rotational) deflection (relative to the undeflected position) of span station 7. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local xb1-axis -ElastoDyn['Spn7RDyb1'] = False # (deg); Blade 1 local pitch (angular/rotational) deflection (relative to the undeflected position) of span station 7. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local yb1-axis -ElastoDyn['Spn7RDzb1'] = False # (deg); Blade 1 local torsional (angular/rotational) deflection (relative to the undeflected position) of span station 7. This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the local zb1-axis -ElastoDyn['Spn8RDxb1'] = False # (deg); Blade 1 local roll (angular/rotational) deflection (relative to the undeflected position) of span station 8. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local xb1-axis -ElastoDyn['Spn8RDyb1'] = False # (deg); Blade 1 local pitch (angular/rotational) deflection (relative to the undeflected position) of span station 8. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local yb1-axis -ElastoDyn['Spn8RDzb1'] = False # (deg); Blade 1 local torsional (angular/rotational) deflection (relative to the undeflected position) of span station 8. This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the local zb1-axis -ElastoDyn['Spn9RDxb1'] = False # (deg); Blade 1 local roll (angular/rotational) deflection (relative to the undeflected position) of span station 9. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local xb1-axis -ElastoDyn['Spn9RDyb1'] = False # (deg); Blade 1 local pitch (angular/rotational) deflection (relative to the undeflected position) of span station 9. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local yb1-axis -ElastoDyn['Spn9RDzb1'] = False # (deg); Blade 1 local torsional (angular/rotational) deflection (relative to the undeflected position) of span station 9. This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the local zb1-axis - -# Blade 2 Local Span Motions -ElastoDyn['Spn1ALxb2'] = False # (m/s^2); Blade 2 local flapwise acceleration (absolute) of span station 1; Directed along the local xb2-axis -ElastoDyn['Spn1ALyb2'] = False # (m/s^2); Blade 2 local edgewise acceleration (absolute) of span station 1; Directed along the local yb2-axis -ElastoDyn['Spn1ALzb2'] = False # (m/s^2); Blade 2 local axial acceleration (absolute) of span station 1; Directed along the local zb2-axis -ElastoDyn['Spn2ALxb2'] = False # (m/s^2); Blade 2 local flapwise acceleration (absolute) of span station 2; Directed along the local xb2-axis -ElastoDyn['Spn2ALyb2'] = False # (m/s^2); Blade 2 local edgewise acceleration (absolute) of span station 2; Directed along the local yb2-axis -ElastoDyn['Spn2ALzb2'] = False # (m/s^2); Blade 2 local axial acceleration (absolute) of span station 2; Directed along the local zb2-axis -ElastoDyn['Spn3ALxb2'] = False # (m/s^2); Blade 2 local flapwise acceleration (absolute) of span station 3; Directed along the local xb2-axis -ElastoDyn['Spn3ALyb2'] = False # (m/s^2); Blade 2 local edgewise acceleration (absolute) of span station 3; Directed along the local yb2-axis -ElastoDyn['Spn3ALzb2'] = False # (m/s^2); Blade 2 local axial acceleration (absolute) of span station 3; Directed along the local zb2-axis -ElastoDyn['Spn4ALxb2'] = False # (m/s^2); Blade 2 local flapwise acceleration (absolute) of span station 4; Directed along the local xb2-axis -ElastoDyn['Spn4ALyb2'] = False # (m/s^2); Blade 2 local edgewise acceleration (absolute) of span station 4; Directed along the local yb2-axis -ElastoDyn['Spn4ALzb2'] = False # (m/s^2); Blade 2 local axial acceleration (absolute) of span station 4; Directed along the local zb2-axis -ElastoDyn['Spn5ALxb2'] = False # (m/s^2); Blade 2 local flapwise acceleration (absolute) of span station 5; Directed along the local xb2-axis -ElastoDyn['Spn5ALyb2'] = False # (m/s^2); Blade 2 local edgewise acceleration (absolute) of span station 5; Directed along the local yb2-axis -ElastoDyn['Spn5ALzb2'] = False # (m/s^2); Blade 2 local axial acceleration (absolute) of span station 5; Directed along the local zb2-axis -ElastoDyn['Spn6ALxb2'] = False # (m/s^2); Blade 2 local flapwise acceleration (absolute) of span station 6; Directed along the local xb2-axis -ElastoDyn['Spn6ALyb2'] = False # (m/s^2); Blade 2 local edgewise acceleration (absolute) of span station 6; Directed along the local yb2-axis -ElastoDyn['Spn6ALzb2'] = False # (m/s^2); Blade 2 local axial acceleration (absolute) of span station 6; Directed along the local zb2-axis -ElastoDyn['Spn7ALxb2'] = False # (m/s^2); Blade 2 local flapwise acceleration (absolute) of span station 7; Directed along the local xb2-axis -ElastoDyn['Spn7ALyb2'] = False # (m/s^2); Blade 2 local edgewise acceleration (absolute) of span station 7; Directed along the local yb2-axis -ElastoDyn['Spn7ALzb2'] = False # (m/s^2); Blade 2 local axial acceleration (absolute) of span station 7; Directed along the local zb2-axis -ElastoDyn['Spn8ALxb2'] = False # (m/s^2); Blade 2 local flapwise acceleration (absolute) of span station 8; Directed along the local xb2-axis -ElastoDyn['Spn8ALyb2'] = False # (m/s^2); Blade 2 local edgewise acceleration (absolute) of span station 8; Directed along the local yb2-axis -ElastoDyn['Spn8ALzb2'] = False # (m/s^2); Blade 2 local axial acceleration (absolute) of span station 8; Directed along the local zb2-axis -ElastoDyn['Spn9ALxb2'] = False # (m/s^2); Blade 2 local flapwise acceleration (absolute) of span station 9; Directed along the local xb2-axis -ElastoDyn['Spn9ALyb2'] = False # (m/s^2); Blade 2 local edgewise acceleration (absolute) of span station 9; Directed along the local yb2-axis -ElastoDyn['Spn9ALzb2'] = False # (m/s^2); Blade 2 local axial acceleration (absolute) of span station 9; Directed along the local zb2-axis -ElastoDyn['Spn1TDxb2'] = False # (m); Blade 2 local flapwise (translational) deflection (relative to the undeflected position) of span station 1; Directed along the xb2-axis -ElastoDyn['Spn1TDyb2'] = False # (m); Blade 2 local edgewise (translational) deflection (relative to the undeflected position) of span station 1; Directed along the yb2-axis -ElastoDyn['Spn1TDzb2'] = False # (m); Blade 2 local axial (translational) deflection (relative to the undeflected position) of span station 1; Directed along the zb2-axis -ElastoDyn['Spn2TDxb2'] = False # (m); Blade 2 local flapwise (translational) deflection (relative to the undeflected position) of span station 2; Directed along the xb2-axis -ElastoDyn['Spn2TDyb2'] = False # (m); Blade 2 local edgewise (translational) deflection (relative to the undeflected position) of span station 2; Directed along the yb2-axis -ElastoDyn['Spn2TDzb2'] = False # (m); Blade 2 local axial (translational) deflection (relative to the undeflected position) of span station 2; Directed along the zb2-axis -ElastoDyn['Spn3TDxb2'] = False # (m); Blade 2 local flapwise (translational) deflection (relative to the undeflected position) of span station 3; Directed along the xb2-axis -ElastoDyn['Spn3TDyb2'] = False # (m); Blade 2 local edgewise (translational) deflection (relative to the undeflected position) of span station 3; Directed along the yb2-axis -ElastoDyn['Spn3TDzb2'] = False # (m); Blade 2 local axial (translational) deflection (relative to the undeflected position) of span station 3; Directed along the zb2-axis -ElastoDyn['Spn4TDxb2'] = False # (m); Blade 2 local flapwise (translational) deflection (relative to the undeflected position) of span station 4; Directed along the xb2-axis -ElastoDyn['Spn4TDyb2'] = False # (m); Blade 2 local edgewise (translational) deflection (relative to the undeflected position) of span station 4; Directed along the yb2-axis -ElastoDyn['Spn4TDzb2'] = False # (m); Blade 2 local axial (translational) deflection (relative to the undeflected position) of span station 4; Directed along the zb2-axis -ElastoDyn['Spn5TDxb2'] = False # (m); Blade 2 local flapwise (translational) deflection (relative to the undeflected position) of span station 5; Directed along the xb2-axis -ElastoDyn['Spn5TDyb2'] = False # (m); Blade 2 local edgewise (translational) deflection (relative to the undeflected position) of span station 5; Directed along the yb2-axis -ElastoDyn['Spn5TDzb2'] = False # (m); Blade 2 local axial (translational) deflection (relative to the undeflected position) of span station 5; Directed along the zb2-axis -ElastoDyn['Spn6TDxb2'] = False # (m); Blade 2 local flapwise (translational) deflection (relative to the undeflected position) of span station 6; Directed along the xb2-axis -ElastoDyn['Spn6TDyb2'] = False # (m); Blade 2 local edgewise (translational) deflection (relative to the undeflected position) of span station 6; Directed along the yb2-axis -ElastoDyn['Spn6TDzb2'] = False # (m); Blade 2 local axial (translational) deflection (relative to the undeflected position) of span station 6; Directed along the zb2-axis -ElastoDyn['Spn7TDxb2'] = False # (m); Blade 2 local flapwise (translational) deflection (relative to the undeflected position) of span station 7; Directed along the xb2-axis -ElastoDyn['Spn7TDyb2'] = False # (m); Blade 2 local edgewise (translational) deflection (relative to the undeflected position) of span station 7; Directed along the yb2-axis -ElastoDyn['Spn7TDzb2'] = False # (m); Blade 2 local axial (translational) deflection (relative to the undeflected position) of span station 7; Directed along the zb2-axis -ElastoDyn['Spn8TDxb2'] = False # (m); Blade 2 local flapwise (translational) deflection (relative to the undeflected position) of span station 8; Directed along the xb2-axis -ElastoDyn['Spn8TDyb2'] = False # (m); Blade 2 local edgewise (translational) deflection (relative to the undeflected position) of span station 8; Directed along the yb2-axis -ElastoDyn['Spn8TDzb2'] = False # (m); Blade 2 local axial (translational) deflection (relative to the undeflected position) of span station 8; Directed along the zb2-axis -ElastoDyn['Spn9TDxb2'] = False # (m); Blade 2 local flapwise (translational) deflection (relative to the undeflected position) of span station 9; Directed along the xb2-axis -ElastoDyn['Spn9TDyb2'] = False # (m); Blade 2 local edgewise (translational) deflection (relative to the undeflected position) of span station 9; Directed along the yb2-axis -ElastoDyn['Spn9TDzb2'] = False # (m); Blade 2 local axial (translational) deflection (relative to the undeflected position) of span station 9; Directed along the zb2-axis -ElastoDyn['Spn1RDxb2'] = False # (deg); Blade 2 local roll (angular/rotational) deflection (relative to the undeflected position) of span station 1. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local xb2-axis -ElastoDyn['Spn1RDyb2'] = False # (deg); Blade 2 local pitch (angular/rotational) deflection (relative to the undeflected position) of span station 1. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local yb2-axis -ElastoDyn['Spn1RDzb2'] = False # (deg); Blade 2 local torsional (angular/rotational) deflection (relative to the undeflected position) of span station 1. This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the local zb2-axis -ElastoDyn['Spn2RDxb2'] = False # (deg); Blade 2 local roll (angular/rotational) deflection (relative to the undeflected position) of span station 2. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local xb2-axis -ElastoDyn['Spn2RDyb2'] = False # (deg); Blade 2 local pitch (angular/rotational) deflection (relative to the undeflected position) of span station 2. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local yb2-axis -ElastoDyn['Spn2RDzb2'] = False # (deg); Blade 2 local torsional (angular/rotational) deflection (relative to the undeflected position) of span station 2. This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the local zb2-axis -ElastoDyn['Spn3RDxb2'] = False # (deg); Blade 2 local roll (angular/rotational) deflection (relative to the undeflected position) of span station 3. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local xb2-axis -ElastoDyn['Spn3RDyb2'] = False # (deg); Blade 2 local pitch (angular/rotational) deflection (relative to the undeflected position) of span station 3. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local yb2-axis -ElastoDyn['Spn3RDzb2'] = False # (deg); Blade 2 local torsional (angular/rotational) deflection (relative to the undeflected position) of span station 3. This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the local zb2-axis -ElastoDyn['Spn4RDxb2'] = False # (deg); Blade 2 local roll (angular/rotational) deflection (relative to the undeflected position) of span station 4. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local xb2-axis -ElastoDyn['Spn4RDyb2'] = False # (deg); Blade 2 local pitch (angular/rotational) deflection (relative to the undeflected position) of span station 4. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local yb2-axis -ElastoDyn['Spn4RDzb2'] = False # (deg); Blade 2 local torsional (angular/rotational) deflection (relative to the undeflected position) of span station 4. This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the local zb2-axis -ElastoDyn['Spn5RDxb2'] = False # (deg); Blade 2 local roll (angular/rotational) deflection (relative to the undeflected position) of span station 5. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local xb2-axis -ElastoDyn['Spn5RDyb2'] = False # (deg); Blade 2 local pitch (angular/rotational) deflection (relative to the undeflected position) of span station 5. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local yb2-axis -ElastoDyn['Spn5RDzb2'] = False # (deg); Blade 2 local torsional (angular/rotational) deflection (relative to the undeflected position) of span station 5. This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the local zb2-axis -ElastoDyn['Spn6RDxb2'] = False # (deg); Blade 2 local roll (angular/rotational) deflection (relative to the undeflected position) of span station 6. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local xb2-axis -ElastoDyn['Spn6RDyb2'] = False # (deg); Blade 2 local pitch (angular/rotational) deflection (relative to the undeflected position) of span station 6. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local yb2-axis -ElastoDyn['Spn6RDzb2'] = False # (deg); Blade 2 local torsional (angular/rotational) deflection (relative to the undeflected position) of span station 6. This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the local zb2-axis -ElastoDyn['Spn7RDxb2'] = False # (deg); Blade 2 local roll (angular/rotational) deflection (relative to the undeflected position) of span station 7. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local xb2-axis -ElastoDyn['Spn7RDyb2'] = False # (deg); Blade 2 local pitch (angular/rotational) deflection (relative to the undeflected position) of span station 7. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local yb2-axis -ElastoDyn['Spn7RDzb2'] = False # (deg); Blade 2 local torsional (angular/rotational) deflection (relative to the undeflected position) of span station 7. This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the local zb2-axis -ElastoDyn['Spn8RDxb2'] = False # (deg); Blade 2 local roll (angular/rotational) deflection (relative to the undeflected position) of span station 8. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local xb2-axis -ElastoDyn['Spn8RDyb2'] = False # (deg); Blade 2 local pitch (angular/rotational) deflection (relative to the undeflected position) of span station 8. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local yb2-axis -ElastoDyn['Spn8RDzb2'] = False # (deg); Blade 2 local torsional (angular/rotational) deflection (relative to the undeflected position) of span station 8. This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the local zb2-axis -ElastoDyn['Spn9RDxb2'] = False # (deg); Blade 2 local roll (angular/rotational) deflection (relative to the undeflected position) of span station 9. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local xb2-axis -ElastoDyn['Spn9RDyb2'] = False # (deg); Blade 2 local pitch (angular/rotational) deflection (relative to the undeflected position) of span station 9. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local yb2-axis -ElastoDyn['Spn9RDzb2'] = False # (deg); Blade 2 local torsional (angular/rotational) deflection (relative to the undeflected position) of span station 9. This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the local zb2-axis - -# Blade 3 Local Span Motions -ElastoDyn['Spn1ALxb3'] = False # (m/s^2); Blade 3 local flapwise acceleration (absolute) of span station 1; Directed along the local xb3-axis -ElastoDyn['Spn1ALyb3'] = False # (m/s^2); Blade 3 local edgewise acceleration (absolute) of span station 1; Directed along the local yb3-axis -ElastoDyn['Spn1ALzb3'] = False # (m/s^2); Blade 3 local axial acceleration (absolute) of span station 1; Directed along the local zb3-axis -ElastoDyn['Spn2ALxb3'] = False # (m/s^2); Blade 3 local flapwise acceleration (absolute) of span station 2; Directed along the local xb3-axis -ElastoDyn['Spn2ALyb3'] = False # (m/s^2); Blade 3 local edgewise acceleration (absolute) of span station 2; Directed along the local yb3-axis -ElastoDyn['Spn2ALzb3'] = False # (m/s^2); Blade 3 local axial acceleration (absolute) of span station 2; Directed along the local zb3-axis -ElastoDyn['Spn3ALxb3'] = False # (m/s^2); Blade 3 local flapwise acceleration (absolute) of span station 3; Directed along the local xb3-axis -ElastoDyn['Spn3ALyb3'] = False # (m/s^2); Blade 3 local edgewise acceleration (absolute) of span station 3; Directed along the local yb3-axis -ElastoDyn['Spn3ALzb3'] = False # (m/s^2); Blade 3 local axial acceleration (absolute) of span station 3; Directed along the local zb3-axis -ElastoDyn['Spn4ALxb3'] = False # (m/s^2); Blade 3 local flapwise acceleration (absolute) of span station 4; Directed along the local xb3-axis -ElastoDyn['Spn4ALyb3'] = False # (m/s^2); Blade 3 local edgewise acceleration (absolute) of span station 4; Directed along the local yb3-axis -ElastoDyn['Spn4ALzb3'] = False # (m/s^2); Blade 3 local axial acceleration (absolute) of span station 4; Directed along the local zb3-axis -ElastoDyn['Spn5ALxb3'] = False # (m/s^2); Blade 3 local flapwise acceleration (absolute) of span station 5; Directed along the local xb3-axis -ElastoDyn['Spn5ALyb3'] = False # (m/s^2); Blade 3 local edgewise acceleration (absolute) of span station 5; Directed along the local yb3-axis -ElastoDyn['Spn5ALzb3'] = False # (m/s^2); Blade 3 local axial acceleration (absolute) of span station 5; Directed along the local zb3-axis -ElastoDyn['Spn6ALxb3'] = False # (m/s^2); Blade 3 local flapwise acceleration (absolute) of span station 6; Directed along the local xb3-axis -ElastoDyn['Spn6ALyb3'] = False # (m/s^2); Blade 3 local edgewise acceleration (absolute) of span station 6; Directed along the local yb3-axis -ElastoDyn['Spn6ALzb3'] = False # (m/s^2); Blade 3 local axial acceleration (absolute) of span station 6; Directed along the local zb3-axis -ElastoDyn['Spn7ALxb3'] = False # (m/s^2); Blade 3 local flapwise acceleration (absolute) of span station 7; Directed along the local xb3-axis -ElastoDyn['Spn7ALyb3'] = False # (m/s^2); Blade 3 local edgewise acceleration (absolute) of span station 7; Directed along the local yb3-axis -ElastoDyn['Spn7ALzb3'] = False # (m/s^2); Blade 3 local axial acceleration (absolute) of span station 7; Directed along the local zb3-axis -ElastoDyn['Spn8ALxb3'] = False # (m/s^2); Blade 3 local flapwise acceleration (absolute) of span station 8; Directed along the local xb3-axis -ElastoDyn['Spn8ALyb3'] = False # (m/s^2); Blade 3 local edgewise acceleration (absolute) of span station 8; Directed along the local yb3-axis -ElastoDyn['Spn8ALzb3'] = False # (m/s^2); Blade 3 local axial acceleration (absolute) of span station 8; Directed along the local zb3-axis -ElastoDyn['Spn9ALxb3'] = False # (m/s^2); Blade 3 local flapwise acceleration (absolute) of span station 9; Directed along the local xb3-axis -ElastoDyn['Spn9ALyb3'] = False # (m/s^2); Blade 3 local edgewise acceleration (absolute) of span station 9; Directed along the local yb3-axis -ElastoDyn['Spn9ALzb3'] = False # (m/s^2); Blade 3 local axial acceleration (absolute) of span station 9; Directed along the local zb3-axis -ElastoDyn['Spn1TDxb3'] = False # (m); Blade 3 local flapwise (translational) deflection (relative to the undeflected position) of span station 1; Directed along the xb3-axis -ElastoDyn['Spn1TDyb3'] = False # (m); Blade 3 local edgewise (translational) deflection (relative to the undeflected position) of span station 1; Directed along the yb3-axis -ElastoDyn['Spn1TDzb3'] = False # (m); Blade 3 local axial (translational) deflection (relative to the undeflected position) of span station 1; Directed along the zb3-axis -ElastoDyn['Spn2TDxb3'] = False # (m); Blade 3 local flapwise (translational) deflection (relative to the undeflected position) of span station 2; Directed along the xb3-axis -ElastoDyn['Spn2TDyb3'] = False # (m); Blade 3 local edgewise (translational) deflection (relative to the undeflected position) of span station 2; Directed along the yb3-axis -ElastoDyn['Spn2TDzb3'] = False # (m); Blade 3 local axial (translational) deflection (relative to the undeflected position) of span station 2; Directed along the zb3-axis -ElastoDyn['Spn3TDxb3'] = False # (m); Blade 3 local flapwise (translational) deflection (relative to the undeflected position) of span station 3; Directed along the xb3-axis -ElastoDyn['Spn3TDyb3'] = False # (m); Blade 3 local edgewise (translational) deflection (relative to the undeflected position) of span station 3; Directed along the yb3-axis -ElastoDyn['Spn3TDzb3'] = False # (m); Blade 3 local axial (translational) deflection (relative to the undeflected position) of span station 3; Directed along the zb3-axis -ElastoDyn['Spn4TDxb3'] = False # (m); Blade 3 local flapwise (translational) deflection (relative to the undeflected position) of span station 4; Directed along the xb3-axis -ElastoDyn['Spn4TDyb3'] = False # (m); Blade 3 local edgewise (translational) deflection (relative to the undeflected position) of span station 4; Directed along the yb3-axis -ElastoDyn['Spn4TDzb3'] = False # (m); Blade 3 local axial (translational) deflection (relative to the undeflected position) of span station 4; Directed along the zb3-axis -ElastoDyn['Spn5TDxb3'] = False # (m); Blade 3 local flapwise (translational) deflection (relative to the undeflected position) of span station 5; Directed along the xb3-axis -ElastoDyn['Spn5TDyb3'] = False # (m); Blade 3 local edgewise (translational) deflection (relative to the undeflected position) of span station 5; Directed along the yb3-axis -ElastoDyn['Spn5TDzb3'] = False # (m); Blade 3 local axial (translational) deflection (relative to the undeflected position) of span station 5; Directed along the zb3-axis -ElastoDyn['Spn6TDxb3'] = False # (m); Blade 3 local flapwise (translational) deflection (relative to the undeflected position) of span station 6; Directed along the xb3-axis -ElastoDyn['Spn6TDyb3'] = False # (m); Blade 3 local edgewise (translational) deflection (relative to the undeflected position) of span station 6; Directed along the yb3-axis -ElastoDyn['Spn6TDzb3'] = False # (m); Blade 3 local axial (translational) deflection (relative to the undeflected position) of span station 6; Directed along the zb3-axis -ElastoDyn['Spn7TDxb3'] = False # (m); Blade 3 local flapwise (translational) deflection (relative to the undeflected position) of span station 7; Directed along the xb3-axis -ElastoDyn['Spn7TDyb3'] = False # (m); Blade 3 local edgewise (translational) deflection (relative to the undeflected position) of span station 7; Directed along the yb3-axis -ElastoDyn['Spn7TDzb3'] = False # (m); Blade 3 local axial (translational) deflection (relative to the undeflected position) of span station 7; Directed along the zb3-axis -ElastoDyn['Spn8TDxb3'] = False # (m); Blade 3 local flapwise (translational) deflection (relative to the undeflected position) of span station 8; Directed along the xb3-axis -ElastoDyn['Spn8TDyb3'] = False # (m); Blade 3 local edgewise (translational) deflection (relative to the undeflected position) of span station 8; Directed along the yb3-axis -ElastoDyn['Spn8TDzb3'] = False # (m); Blade 3 local axial (translational) deflection (relative to the undeflected position) of span station 8; Directed along the zb3-axis -ElastoDyn['Spn9TDxb3'] = False # (m); Blade 3 local flapwise (translational) deflection (relative to the undeflected position) of span station 9; Directed along the xb3-axis -ElastoDyn['Spn9TDyb3'] = False # (m); Blade 3 local edgewise (translational) deflection (relative to the undeflected position) of span station 9; Directed along the yb3-axis -ElastoDyn['Spn9TDzb3'] = False # (m); Blade 3 local axial (translational) deflection (relative to the undeflected position) of span station 9; Directed along the zb3-axis -ElastoDyn['Spn1RDxb3'] = False # (deg); Blade 3 local roll (angular/rotational) deflection (relative to the undeflected position) of span station 1. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local xb3-axis -ElastoDyn['Spn1RDyb3'] = False # (deg); Blade 3 local pitch (angular/rotational) deflection (relative to the undeflected position) of span station 1. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local yb3-axis -ElastoDyn['Spn1RDzb3'] = False # (deg); Blade 3 local torsional (angular/rotational) deflection (relative to the undeflected position) of span station 1. This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the local zb3-axis -ElastoDyn['Spn2RDxb3'] = False # (deg); Blade 3 local roll (angular/rotational) deflection (relative to the undeflected position) of span station 2. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local xb3-axis -ElastoDyn['Spn2RDyb3'] = False # (deg); Blade 3 local pitch (angular/rotational) deflection (relative to the undeflected position) of span station 2. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local yb3-axis -ElastoDyn['Spn2RDzb3'] = False # (deg); Blade 3 local torsional (angular/rotational) deflection (relative to the undeflected position) of span station 2. This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the local zb3-axis -ElastoDyn['Spn3RDxb3'] = False # (deg); Blade 3 local roll (angular/rotational) deflection (relative to the undeflected position) of span station 3. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local xb3-axis -ElastoDyn['Spn3RDyb3'] = False # (deg); Blade 3 local pitch (angular/rotational) deflection (relative to the undeflected position) of span station 3. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local yb3-axis -ElastoDyn['Spn3RDzb3'] = False # (deg); Blade 3 local torsional (angular/rotational) deflection (relative to the undeflected position) of span station 3. This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the local zb3-axis -ElastoDyn['Spn4RDxb3'] = False # (deg); Blade 3 local roll (angular/rotational) deflection (relative to the undeflected position) of span station 4. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local xb3-axis -ElastoDyn['Spn4RDyb3'] = False # (deg); Blade 3 local pitch (angular/rotational) deflection (relative to the undeflected position) of span station 4. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local yb3-axis -ElastoDyn['Spn4RDzb3'] = False # (deg); Blade 3 local torsional (angular/rotational) deflection (relative to the undeflected position) of span station 4. This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the local zb3-axis -ElastoDyn['Spn5RDxb3'] = False # (deg); Blade 3 local roll (angular/rotational) deflection (relative to the undeflected position) of span station 5. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local xb3-axis -ElastoDyn['Spn5RDyb3'] = False # (deg); Blade 3 local pitch (angular/rotational) deflection (relative to the undeflected position) of span station 5. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local yb3-axis -ElastoDyn['Spn5RDzb3'] = False # (deg); Blade 3 local torsional (angular/rotational) deflection (relative to the undeflected position) of span station 5. This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the local zb3-axis -ElastoDyn['Spn6RDxb3'] = False # (deg); Blade 3 local roll (angular/rotational) deflection (relative to the undeflected position) of span station 6. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local xb3-axis -ElastoDyn['Spn6RDyb3'] = False # (deg); Blade 3 local pitch (angular/rotational) deflection (relative to the undeflected position) of span station 6. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local yb3-axis -ElastoDyn['Spn6RDzb3'] = False # (deg); Blade 3 local torsional (angular/rotational) deflection (relative to the undeflected position) of span station 6. This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the local zb3-axis -ElastoDyn['Spn7RDxb3'] = False # (deg); Blade 3 local roll (angular/rotational) deflection (relative to the undeflected position) of span station 7. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local xb3-axis -ElastoDyn['Spn7RDyb3'] = False # (deg); Blade 3 local pitch (angular/rotational) deflection (relative to the undeflected position) of span station 7. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local yb3-axis -ElastoDyn['Spn7RDzb3'] = False # (deg); Blade 3 local torsional (angular/rotational) deflection (relative to the undeflected position) of span station 7. This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the local zb3-axis -ElastoDyn['Spn8RDxb3'] = False # (deg); Blade 3 local roll (angular/rotational) deflection (relative to the undeflected position) of span station 8. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local xb3-axis -ElastoDyn['Spn8RDyb3'] = False # (deg); Blade 3 local pitch (angular/rotational) deflection (relative to the undeflected position) of span station 8. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local yb3-axis -ElastoDyn['Spn8RDzb3'] = False # (deg); Blade 3 local torsional (angular/rotational) deflection (relative to the undeflected position) of span station 8. This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the local zb3-axis -ElastoDyn['Spn9RDxb3'] = False # (deg); Blade 3 local roll (angular/rotational) deflection (relative to the undeflected position) of span station 9. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local xb3-axis -ElastoDyn['Spn9RDyb3'] = False # (deg); Blade 3 local pitch (angular/rotational) deflection (relative to the undeflected position) of span station 9. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local yb3-axis -ElastoDyn['Spn9RDzb3'] = False # (deg); Blade 3 local torsional (angular/rotational) deflection (relative to the undeflected position) of span station 9. This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the local zb3-axis - -# Blade Pitch Motions -ElastoDyn['PtchPMzc1'] = False # (deg); Blade 1 pitch angle (position); Positive towards feather about the minus zc1- and minus zb1-axes -ElastoDyn['PtchPMzb1'] = False # (deg); Blade 1 pitch angle (position); Positive towards feather about the minus zc1- and minus zb1-axes -ElastoDyn['BldPitch1'] = False # (deg); Blade 1 pitch angle (position); Positive towards feather about the minus zc1- and minus zb1-axes -ElastoDyn['BlPitch1'] = False # (deg); Blade 1 pitch angle (position); Positive towards feather about the minus zc1- and minus zb1-axes -ElastoDyn['PtchPMzc2'] = False # (deg); Blade 2 pitch angle (position); Positive towards feather about the minus zc2- and minus zb2-axes -ElastoDyn['PtchPMzb2'] = False # (deg); Blade 2 pitch angle (position); Positive towards feather about the minus zc2- and minus zb2-axes -ElastoDyn['BldPitch2'] = False # (deg); Blade 2 pitch angle (position); Positive towards feather about the minus zc2- and minus zb2-axes -ElastoDyn['BlPitch2'] = False # (deg); Blade 2 pitch angle (position); Positive towards feather about the minus zc2- and minus zb2-axes -ElastoDyn['PtchPMzc3'] = False # (deg); Blade 3 pitch angle (position); Positive towards feather about the minus zc3- and minus zb3-axes -ElastoDyn['PtchPMzb3'] = False # (deg); Blade 3 pitch angle (position); Positive towards feather about the minus zc3- and minus zb3-axes -ElastoDyn['BldPitch3'] = False # (deg); Blade 3 pitch angle (position); Positive towards feather about the minus zc3- and minus zb3-axes -ElastoDyn['BlPitch3'] = False # (deg); Blade 3 pitch angle (position); Positive towards feather about the minus zc3- and minus zb3-axes - -# Teeter Motions -ElastoDyn['TeetPya'] = False # (deg); Rotor teeter angle (position); About the ya-axis -ElastoDyn['RotTeetP'] = False # (deg); Rotor teeter angle (position); About the ya-axis -ElastoDyn['TeetDefl'] = False # (deg); Rotor teeter angle (position); About the ya-axis -ElastoDyn['TeetVya'] = False # (deg/s); Rotor teeter angular velocity; About the ya-axis -ElastoDyn['RotTeetV'] = False # (deg/s); Rotor teeter angular velocity; About the ya-axis -ElastoDyn['TeetAya'] = False # (deg/s^2); Rotor teeter angular acceleration; About the ya-axis -ElastoDyn['RotTeetA'] = False # (deg/s^2); Rotor teeter angular acceleration; About the ya-axis - -# Shaft Motions -ElastoDyn['LSSTipPxa'] = False # (deg); Rotor azimuth angle (position); About the xa- and xs-axes -ElastoDyn['LSSTipPxs'] = False # (deg); Rotor azimuth angle (position); About the xa- and xs-axes -ElastoDyn['LSSTipP'] = False # (deg); Rotor azimuth angle (position); About the xa- and xs-axes -ElastoDyn['Azimuth'] = False # (deg); Rotor azimuth angle (position); About the xa- and xs-axes -ElastoDyn['LSSTipVxa'] = False # (rpm); Rotor azimuth angular speed; About the xa- and xs-axes -ElastoDyn['LSSTipVxs'] = False # (rpm); Rotor azimuth angular speed; About the xa- and xs-axes -ElastoDyn['LSSTipV'] = False # (rpm); Rotor azimuth angular speed; About the xa- and xs-axes -ElastoDyn['RotSpeed'] = False # (rpm); Rotor azimuth angular speed; About the xa- and xs-axes -ElastoDyn['LSSTipAxa'] = False # (deg/s^2); Rotor azimuth angular acceleration; About the xa- and xs-axes -ElastoDyn['LSSTipAxs'] = False # (deg/s^2); Rotor azimuth angular acceleration; About the xa- and xs-axes -ElastoDyn['LSSTipA'] = False # (deg/s^2); Rotor azimuth angular acceleration; About the xa- and xs-axes -ElastoDyn['RotAccel'] = False # (deg/s^2); Rotor azimuth angular acceleration; About the xa- and xs-axes -ElastoDyn['LSSGagPxa'] = False # (deg); Low-speed shaft strain gage azimuth angle (position) (on the gearbox side of the low-speed shaft); About the xa- and xs-axes -ElastoDyn['LSSGagPxs'] = False # (deg); Low-speed shaft strain gage azimuth angle (position) (on the gearbox side of the low-speed shaft); About the xa- and xs-axes -ElastoDyn['LSSGagP'] = False # (deg); Low-speed shaft strain gage azimuth angle (position) (on the gearbox side of the low-speed shaft); About the xa- and xs-axes -ElastoDyn['LSSGagVxa'] = False # (rpm); Low-speed shaft strain gage angular speed (on the gearbox side of the low-speed shaft); About the xa- and xs-axes -ElastoDyn['LSSGagVxs'] = False # (rpm); Low-speed shaft strain gage angular speed (on the gearbox side of the low-speed shaft); About the xa- and xs-axes -ElastoDyn['LSSGagV'] = False # (rpm); Low-speed shaft strain gage angular speed (on the gearbox side of the low-speed shaft); About the xa- and xs-axes -ElastoDyn['LSSGagAxa'] = False # (deg/s^2); Low-speed shaft strain gage angular acceleration (on the gearbox side of the low-speed shaft); About the xa- and xs-axes -ElastoDyn['LSSGagAxs'] = False # (deg/s^2); Low-speed shaft strain gage angular acceleration (on the gearbox side of the low-speed shaft); About the xa- and xs-axes -ElastoDyn['LSSGagA'] = False # (deg/s^2); Low-speed shaft strain gage angular acceleration (on the gearbox side of the low-speed shaft); About the xa- and xs-axes -ElastoDyn['HSShftV'] = False # (rpm); Angular speed of the high-speed shaft and generator; Same sign as LSSGagVxa / LSSGagVxs / LSSGagV -ElastoDyn['GenSpeed'] = False # (rpm); Angular speed of the high-speed shaft and generator; Same sign as LSSGagVxa / LSSGagVxs / LSSGagV -ElastoDyn['HSShftA'] = False # (deg/s^2); Angular acceleration of the high-speed shaft and generator; Same sign as LSSGagAxa / LSSGagAxs / LSSGagA -ElastoDyn['GenAccel'] = False # (deg/s^2); Angular acceleration of the high-speed shaft and generator; Same sign as LSSGagAxa / LSSGagAxs / LSSGagA - -# Nacelle IMU Motions -ElastoDyn['NcIMUTVxs'] = False # (m/s); Nacelle inertial measurement unit translational velocity (absolute); Directed along the xs-axis -ElastoDyn['NcIMUTVys'] = False # (m/s); Nacelle inertial measurement unit translational velocity (absolute); Directed along the ys-axis -ElastoDyn['NcIMUTVzs'] = False # (m/s); Nacelle inertial measurement unit translational velocity (absolute); Directed along the zs-axis -ElastoDyn['NcIMUTAxs'] = False # (m/s^2); Nacelle inertial measurement unit translational acceleration (absolute); Directed along the xs-axis -ElastoDyn['NcIMUTAys'] = False # (m/s^2); Nacelle inertial measurement unit translational acceleration (absolute); Directed along the ys-axis -ElastoDyn['NcIMUTAzs'] = False # (m/s^2); Nacelle inertial measurement unit translational acceleration (absolute); Directed along the zs-axis -ElastoDyn['NcIMURVxs'] = False # (deg/s); Nacelle inertial measurement unit angular (rotational) velocity (absolute); About the xs-axis -ElastoDyn['NcIMURVys'] = False # (deg/s); Nacelle inertial measurement unit angular (rotational) velocity (absolute); About the ys-axis -ElastoDyn['NcIMURVzs'] = False # (deg/s); Nacelle inertial measurement unit angular (rotational) velocity (absolute); About the zs-axis -ElastoDyn['NcIMURAxs'] = False # (deg/s^2); Nacelle inertial measurement unit angular (rotational) acceleration (absolute); About the xs-axis -ElastoDyn['NcIMURAys'] = False # (deg/s^2); Nacelle inertial measurement unit angular (rotational) acceleration (absolute); About the ys-axis -ElastoDyn['NcIMURAzs'] = False # (deg/s^2); Nacelle inertial measurement unit angular (rotational) acceleration (absolute); About the zs-axis - -# Rotor-Furl Motions -ElastoDyn['RotFurlP'] = False # (deg); Rotor-furl angle (position); About the rotor-furl axis -ElastoDyn['RotFurl'] = False # (deg); Rotor-furl angle (position); About the rotor-furl axis -ElastoDyn['RotFurlV'] = False # (deg/s); Rotor-furl angular velocity; About the rotor-furl axis -ElastoDyn['RotFurlA'] = False # (deg/s^2); Rotor-furl angular acceleration; About the rotor-furl axis - -# Tail-Furl Motions -ElastoDyn['TailFurlP'] = False # (deg); Tail-furl angle (position); About the tail-furl axis -ElastoDyn['TailFurl'] = False # (deg); Tail-furl angle (position); About the tail-furl axis -ElastoDyn['TailFurlV'] = False # (deg/s); Tail-furl angular velocity; About the tail-furl axis -ElastoDyn['TailFurlA'] = False # (deg/s^2); Tail-furl angular acceleration; About the tail-furl axis - -# Nacelle Yaw Motions -ElastoDyn['YawPzn'] = False # (deg); Nacelle yaw angle (position); About the zn- and zp-axes -ElastoDyn['YawPzp'] = False # (deg); Nacelle yaw angle (position); About the zn- and zp-axes -ElastoDyn['NacYawP'] = False # (deg); Nacelle yaw angle (position); About the zn- and zp-axes -ElastoDyn['NacYaw'] = False # (deg); Nacelle yaw angle (position); About the zn- and zp-axes -ElastoDyn['YawPos'] = False # (deg); Nacelle yaw angle (position); About the zn- and zp-axes -ElastoDyn['YawVzn'] = False # (deg/s); Nacelle yaw angular velocity; About the zn- and zp-axes -ElastoDyn['YawVzp'] = False # (deg/s); Nacelle yaw angular velocity; About the zn- and zp-axes -ElastoDyn['NacYawV'] = False # (deg/s); Nacelle yaw angular velocity; About the zn- and zp-axes -ElastoDyn['YawRate'] = False # (deg/s); Nacelle yaw angular velocity; About the zn- and zp-axes -ElastoDyn['YawAzn'] = False # (deg/s^2); Nacelle yaw angular acceleration; About the zn- and zp-axes -ElastoDyn['YawAzp'] = False # (deg/s^2); Nacelle yaw angular acceleration; About the zn- and zp-axes -ElastoDyn['NacYawA'] = False # (deg/s^2); Nacelle yaw angular acceleration; About the zn- and zp-axes -ElastoDyn['YawAccel'] = False # (deg/s^2); Nacelle yaw angular acceleration; About the zn- and zp-axes - -# Tower-Top / Yaw Bearing Motions -ElastoDyn['TwrTpTDxi'] = False # (m); Tower-top / yaw bearing fore-aft (translational) deflection (relative to the undeflected position) including all platform motions; Directed along the xi-axis -ElastoDyn['YawBrTDxi'] = False # (m); Tower-top / yaw bearing fore-aft (translational) deflection (relative to the undeflected position) including all platform motions; Directed along the xi-axis -ElastoDyn['TwrTpTDyi'] = False # (m); Tower-top / yaw bearing side-to-side (translational) deflection (relative to the undeflected position) including all platform motions; Directed along the yi-axis -ElastoDyn['YawBrTDyi'] = False # (m); Tower-top / yaw bearing side-to-side (translational) deflection (relative to the undeflected position) including all platform motions; Directed along the yi-axis -ElastoDyn['TwrTpTDzi'] = False # (m); Tower-top / yaw bearing axial (translational) deflection (relative to the undeflected position) including all platform motions; Directed along the zi-axis -ElastoDyn['YawBrTDzi'] = False # (m); Tower-top / yaw bearing axial (translational) deflection (relative to the undeflected position) including all platform motions; Directed along the zi-axis -ElastoDyn['YawBrTDxp'] = False # (m); Tower-top / yaw bearing fore-aft (translational) deflection (relative to the undeflected position); Directed along the xp-axis -ElastoDyn['YawBrTDyp'] = False # (m); Tower-top / yaw bearing side-to-side (translational) deflection (relative to the undeflected position); Directed along the yp-axis -ElastoDyn['YawBrTDzp'] = False # (m); Tower-top / yaw bearing axial (translational) deflection (relative to the undeflected position); Directed along the zp-axis -ElastoDyn['YawBrTDxt'] = False # (m); Tower-top / yaw bearing fore-aft (translational) deflection (relative to the undeflected position); Directed along the xt-axis -ElastoDyn['TTDspFA'] = False # (m); Tower-top / yaw bearing fore-aft (translational) deflection (relative to the undeflected position); Directed along the xt-axis -ElastoDyn['YawBrTDyt'] = False # (m); Tower-top / yaw bearing side-to-side (translation) deflection (relative to the undeflected position); Directed along the yt-axis -ElastoDyn['TTDspSS'] = False # (m); Tower-top / yaw bearing side-to-side (translation) deflection (relative to the undeflected position); Directed along the yt-axis -ElastoDyn['YawBrTDzt'] = False # (m); Tower-top / yaw bearing axial (translational) deflection (relative to the undeflected position); Directed along the zt-axis -ElastoDyn['TTDspAx'] = False # (m); Tower-top / yaw bearing axial (translational) deflection (relative to the undeflected position); Directed along the zt-axis -ElastoDyn['YawBrTVxp'] = False # (m/s); Tower-top / yaw bearing fore-aft (translational) velocity (absolute); Directed along the xp-axis -ElastoDyn['YawBrTVyp'] = False # (m/s); Tower-top / yaw bearing side-to-side (translational) velocity (absolute); Directed along the yp-axis -ElastoDyn['YawBrTVzp'] = False # (m/s); Tower-top / yaw bearing axial (translational) velocity (absolute); Directed along the zp-axis -ElastoDyn['YawBrTAxp'] = False # (m/s^2); Tower-top / yaw bearing fore-aft (translational) acceleration (absolute); Directed along the xp-axis -ElastoDyn['YawBrTAyp'] = False # (m/s^2); Tower-top / yaw bearing side-to-side (translational) acceleration (absolute); Directed along the yp-axis -ElastoDyn['YawBrTAzp'] = False # (m/s^2); Tower-top / yaw bearing axial (translational) acceleration (absolute); Directed along the zp-axis -ElastoDyn['YawBrRDxt'] = False # (deg); Tower-top / yaw bearing angular (rotational) roll deflection (relative to the undeflected position). In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower deflections, so that the rotation sequence does not matter.; About the xt-axis -ElastoDyn['TTDspRoll'] = False # (deg); Tower-top / yaw bearing angular (rotational) roll deflection (relative to the undeflected position). In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower deflections, so that the rotation sequence does not matter.; About the xt-axis -ElastoDyn['YawBrRDyt'] = False # (deg); Tower-top / yaw bearing angular (rotational) pitch deflection (relative to the undeflected position). In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower deflections, so that the rotation sequence does not matter.; About the yt-axis -ElastoDyn['TTDspPtch'] = False # (deg); Tower-top / yaw bearing angular (rotational) pitch deflection (relative to the undeflected position). In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower deflections, so that the rotation sequence does not matter.; About the yt-axis -ElastoDyn['YawBrRDzt'] = False # (deg); Tower-top / yaw bearing angular (rotational) torsion deflection (relative to the undeflected position). This output will always be zero for FAST simulation results. Use it for examining tower torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence.; About the zt-axis -ElastoDyn['TTDspTwst'] = False # (deg); Tower-top / yaw bearing angular (rotational) torsion deflection (relative to the undeflected position). This output will always be zero for FAST simulation results. Use it for examining tower torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence.; About the zt-axis -ElastoDyn['YawBrRVxp'] = False # (deg/s); Tower-top / yaw bearing angular (rotational) roll velocity (absolute); About the xp-axis -ElastoDyn['YawBrRVyp'] = False # (deg/s); Tower-top / yaw bearing angular (rotational) pitch velocity (absolute); About the yp-axis -ElastoDyn['YawBrRVzp'] = False # (deg/s); Tower-top / yaw bearing angular (rotational) torsion velocity. This output will always be very close to zero for FAST simulation results. Use it for examining tower torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. (absolute); About the zp-axis -ElastoDyn['YawBrRAxp'] = False # (deg/s^2); Tower-top / yaw bearing angular (rotational) roll acceleration (absolute); About the xp-axis -ElastoDyn['YawBrRAyp'] = False # (deg/s^2); Tower-top / yaw bearing angular (rotational) pitch acceleration (absolute); About the yp-axis -ElastoDyn['YawBrRAzp'] = False # (deg/s^2); Tower-top / yaw bearing angular (rotational) torsion acceleration. This output will always be very close to zero for FAST simulation results. Use it for examining tower torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. (absolute); About the zp-axis - -# Local Tower Motions -ElastoDyn['TwHt1ALxt'] = False # (m/s^2); Local tower fore-aft (translational) acceleration (absolute) of tower gage 1 ; Directed along the local xt-axis -ElastoDyn['TwHt1ALyt'] = False # (m/s^2); Local tower side-to-side (translational) acceleration (absolute) of tower gage 1 ; Directed along the local yt-axis -ElastoDyn['TwHt1ALzt'] = False # (m/s^2); Local tower axial (translational) acceleration (absolute) of tower gage 1 ; Directed along the local zt-axis -ElastoDyn['TwHt2ALxt'] = False # (m/s^2); Local tower fore-aft (translational) acceleration (absolute) of tower gage 2; Directed along the local xt-axis -ElastoDyn['TwHt2ALyt'] = False # (m/s^2); Local tower side-to-side (translational) acceleration (absolute) of tower gage 2; Directed along the local yt-axis -ElastoDyn['TwHt2ALzt'] = False # (m/s^2); Local tower axial (translational) acceleration (absolute) of tower gage 2; Directed along the local zt-axis -ElastoDyn['TwHt3ALxt'] = False # (m/s^2); Local tower fore-aft (translational) acceleration (absolute) of tower gage 3; Directed along the local xt-axis -ElastoDyn['TwHt3ALyt'] = False # (m/s^2); Local tower side-to-side (translational) acceleration (absolute) of tower gage 3; Directed along the local yt-axis -ElastoDyn['TwHt3ALzt'] = False # (m/s^2); Local tower axial (translational) acceleration (absolute) of tower gage 3; Directed along the local zt-axis -ElastoDyn['TwHt4ALxt'] = False # (m/s^2); Local tower fore-aft (translational) acceleration (absolute) of tower gage 4; Directed along the local xt-axis -ElastoDyn['TwHt4ALyt'] = False # (m/s^2); Local tower side-to-side (translational) acceleration (absolute) of tower gage 4; Directed along the local yt-axis -ElastoDyn['TwHt4ALzt'] = False # (m/s^2); Local tower axial (translational) acceleration (absolute) of tower gage 4; Directed along the local zt-axis -ElastoDyn['TwHt5ALxt'] = False # (m/s^2); Local tower fore-aft (translational) acceleration (absolute) of tower gage 5; Directed along the local xt-axis -ElastoDyn['TwHt5ALyt'] = False # (m/s^2); Local tower side-to-side (translational) acceleration (absolute) of tower gage 5; Directed along the local yt-axis -ElastoDyn['TwHt5ALzt'] = False # (m/s^2); Local tower axial (translational) acceleration (absolute) of tower gage 5; Directed along the local zt-axis -ElastoDyn['TwHt6ALxt'] = False # (m/s^2); Local tower fore-aft (translational) acceleration (absolute) of tower gage 6; Directed along the local xt-axis -ElastoDyn['TwHt6ALyt'] = False # (m/s^2); Local tower side-to-side (translational) acceleration (absolute) of tower gage 6; Directed along the local yt-axis -ElastoDyn['TwHt6ALzt'] = False # (m/s^2); Local tower axial (translational) acceleration (absolute) of tower gage 6; Directed along the local zt-axis -ElastoDyn['TwHt7ALxt'] = False # (m/s^2); Local tower fore-aft (translational) acceleration (absolute) of tower gage 7; Directed along the local xt-axis -ElastoDyn['TwHt7ALyt'] = False # (m/s^2); Local tower side-to-side (translational) acceleration (absolute) of tower gage 7; Directed along the local yt-axis -ElastoDyn['TwHt7ALzt'] = False # (m/s^2); Local tower axial (translational) acceleration (absolute) of tower gage 7; Directed along the local zt-axis -ElastoDyn['TwHt8ALxt'] = False # (m/s^2); Local tower fore-aft (translational) acceleration (absolute) of tower gage 8; Directed along the local xt-axis -ElastoDyn['TwHt8ALyt'] = False # (m/s^2); Local tower side-to-side (translational) acceleration (absolute) of tower gage 8; Directed along the local yt-axis -ElastoDyn['TwHt8ALzt'] = False # (m/s^2); Local tower axial (translational) acceleration (absolute) of tower gage 8; Directed along the local zt-axis -ElastoDyn['TwHt9ALxt'] = False # (m/s^2); Local tower fore-aft (translational) acceleration (absolute) of tower gage 9; Directed along the local xt-axis -ElastoDyn['TwHt9ALyt'] = False # (m/s^2); Local tower side-to-side (translational) acceleration (absolute) of tower gage 9; Directed along the local yt-axis -ElastoDyn['TwHt9ALzt'] = False # (m/s^2); Local tower axial (translational) acceleration (absolute) of tower gage 9; Directed along the local zt-axis -ElastoDyn['TwHt1TDxt'] = False # (m); Local tower fore-aft (translational) deflection (relative to the undeflected position) of tower gage 1; Directed along the local xt-axis -ElastoDyn['TwHt1TDyt'] = False # (m); Local tower side-to-side (translational) deflection (relative to the undeflected position) of tower gage 1; Directed along the local yt-axis -ElastoDyn['TwHt1TDzt'] = False # (m); Local tower axial (translational) deflection (relative to the undeflected position) of tower gage 1; Directed along the local zt-axis -ElastoDyn['TwHt2TDxt'] = False # (m); Local tower fore-aft (translational) deflection (relative to the undeflected position) of tower gage 2; Directed along the local xt-axis -ElastoDyn['TwHt2TDyt'] = False # (m); Local tower side-to-side (translational) deflection (relative to the undeflected position) of tower gage 2; Directed along the local yt-axis -ElastoDyn['TwHt2TDzt'] = False # (m); Local tower axial (translational) deflection (relative to the undeflected position) of tower gage 2; Directed along the local zt-axis -ElastoDyn['TwHt3TDxt'] = False # (m); Local tower fore-aft (translational) deflection (relative to the undeflected position) of tower gage 3; Directed along the local xt-axis -ElastoDyn['TwHt3TDyt'] = False # (m); Local tower side-to-side (translational) deflection (relative to the undeflected position) of tower gage 3; Directed along the local yt-axis -ElastoDyn['TwHt3TDzt'] = False # (m); Local tower axial (translational) deflection (relative to the undeflected position) of tower gage 3; Directed along the local zt-axis -ElastoDyn['TwHt4TDxt'] = False # (m); Local tower fore-aft (translational) deflection (relative to the undeflected position) of tower gage 4; Directed along the local xt-axis -ElastoDyn['TwHt4TDyt'] = False # (m); Local tower side-to-side (translational) deflection (relative to the undeflected position) of tower gage 4; Directed along the local yt-axis -ElastoDyn['TwHt4TDzt'] = False # (m); Local tower axial (translational) deflection (relative to the undeflected position) of tower gage 4; Directed along the local zt-axis -ElastoDyn['TwHt5TDxt'] = False # (m); Local tower fore-aft (translational) deflection (relative to the undeflected position) of tower gage 5; Directed along the local xt-axis -ElastoDyn['TwHt5TDyt'] = False # (m); Local tower side-to-side (translational) deflection (relative to the undeflected position) of tower gage 5; Directed along the local yt-axis -ElastoDyn['TwHt5TDzt'] = False # (m); Local tower axial (translational) deflection (relative to the undeflected position) of tower gage 5; Directed along the local zt-axis -ElastoDyn['TwHt6TDxt'] = False # (m); Local tower fore-aft (translational) deflection (relative to the undeflected position) of tower gage 6; Directed along the local xt-axis -ElastoDyn['TwHt6TDyt'] = False # (m); Local tower side-to-side (translational) deflection (relative to the undeflected position) of tower gage 6; Directed along the local yt-axis -ElastoDyn['TwHt6TDzt'] = False # (m); Local tower axial (translational) deflection (relative to the undeflected position) of tower gage 6; Directed along the local zt-axis -ElastoDyn['TwHt7TDxt'] = False # (m); Local tower fore-aft (translational) deflection (relative to the undeflected position) of tower gage 7; Directed along the local xt-axis -ElastoDyn['TwHt7TDyt'] = False # (m); Local tower side-to-side (translational) deflection (relative to the undeflected position) of tower gage 7; Directed along the local yt-axis -ElastoDyn['TwHt7TDzt'] = False # (m); Local tower axial (translational) deflection (relative to the undeflected position) of tower gage 7; Directed along the local zt-axis -ElastoDyn['TwHt8TDxt'] = False # (m); Local tower fore-aft (translational) deflection (relative to the undeflected position) of tower gage 8; Directed along the local xt-axis -ElastoDyn['TwHt8TDyt'] = False # (m); Local tower side-to-side (translational) deflection (relative to the undeflected position) of tower gage 8; Directed along the local yt-axis -ElastoDyn['TwHt8TDzt'] = False # (m); Local tower axial (translational) deflection (relative to the undeflected position) of tower gage 8; Directed along the local zt-axis -ElastoDyn['TwHt9TDxt'] = False # (m); Local tower fore-aft (translational) deflection (relative to the undeflected position) of tower gage 9; Directed along the local xt-axis -ElastoDyn['TwHt9TDyt'] = False # (m); Local tower side-to-side (translational) deflection (relative to the undeflected position) of tower gage 9; Directed along the local yt-axis -ElastoDyn['TwHt9TDzt'] = False # (m); Local tower axial (translational) deflection (relative to the undeflected position) of tower gage 9; Directed along the local zt-axis -ElastoDyn['TwHt1RDxt'] = False # (deg); Local tower angular (rotational) roll deflection (relative to the undeflected position) of tower gage 1. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower deflections, so that the rotation sequence does not matter.; About the local xt-axis -ElastoDyn['TwHt1RDyt'] = False # (deg); Local tower angular (rotational) pitch deflection (relative to the undeflected position) of tower gage 1. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower deflections, so that the rotation sequence does not matter.; About the local yt-axis -ElastoDyn['TwHt1RDzt'] = False # (deg); Local tower angular (rotational) torsion deflection (relative to the undeflected position) of tower gage 1. This output will always be zero for FAST simulation results. Use it for examining tower torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence.; About the local zt-axis -ElastoDyn['TwHt2RDxt'] = False # (deg); Local tower angular (rotational) roll deflection (relative to the undeflected position) of tower gage 2. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower deflections, so that the rotation sequence does not matter.; About the local xt-axis -ElastoDyn['TwHt2RDyt'] = False # (deg); Local tower angular (rotational) pitch deflection (relative to the undeflected position) of tower gage 2. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower deflections, so that the rotation sequence does not matter.; About the local yt-axis -ElastoDyn['TwHt2RDzt'] = False # (deg); Local tower angular (rotational) torsion deflection (relative to the undeflected position) of tower gage 2. This output will always be zero for FAST simulation results. Use it for examining tower torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence.; About the local zt-axis -ElastoDyn['TwHt3RDxt'] = False # (deg); Local tower angular (rotational) roll deflection (relative to the undeflected position) of tower gage 3. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower deflections, so that the rotation sequence does not matter.; About the local xt-axis -ElastoDyn['TwHt3RDyt'] = False # (deg); Local tower angular (rotational) pitch deflection (relative to the undeflected position) of tower gage 3. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower deflections, so that the rotation sequence does not matter.; About the local yt-axis -ElastoDyn['TwHt3RDzt'] = False # (deg); Local tower angular (rotational) torsion deflection (relative to the undeflected position) of tower gage 3. This output will always be zero for FAST simulation results. Use it for examining tower torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence.; About the local zt-axis -ElastoDyn['TwHt4RDxt'] = False # (deg); Local tower angular (rotational) roll deflection (relative to the undeflected position) of tower gage 4. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower deflections, so that the rotation sequence does not matter.; About the local xt-axis -ElastoDyn['TwHt4RDyt'] = False # (deg); Local tower angular (rotational) pitch deflection (relative to the undeflected position) of tower gage 4. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower deflections, so that the rotation sequence does not matter.; About the local yt-axis -ElastoDyn['TwHt4RDzt'] = False # (deg); Local tower angular (rotational) torsion deflection (relative to the undeflected position) of tower gage 4. This output will always be zero for FAST simulation results. Use it for examining tower torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence.; About the local zt-axis -ElastoDyn['TwHt5RDxt'] = False # (deg); Local tower angular (rotational) roll deflection (relative to the undeflected position) of tower gage 5. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower deflections, so that the rotation sequence does not matter.; About the local xt-axis -ElastoDyn['TwHt5RDyt'] = False # (deg); Local tower angular (rotational) pitch deflection (relative to the undeflected position) of tower gage 5. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower deflections, so that the rotation sequence does not matter.; About the local yt-axis -ElastoDyn['TwHt5RDzt'] = False # (deg); Local tower angular (rotational) torsion deflection (relative to the undeflected position) of tower gage 5. This output will always be zero for FAST simulation results. Use it for examining tower torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence.; About the local zt-axis -ElastoDyn['TwHt6RDxt'] = False # (deg); Local tower angular (rotational) roll deflection (relative to the undeflected position) of tower gage 6. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower deflections, so that the rotation sequence does not matter.; About the local xt-axis -ElastoDyn['TwHt6RDyt'] = False # (deg); Local tower angular (rotational) pitch deflection (relative to the undeflected position) of tower gage 6. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower deflections, so that the rotation sequence does not matter.; About the local yt-axis -ElastoDyn['TwHt6RDzt'] = False # (deg); Local tower angular (rotational) torsion deflection (relative to the undeflected position) of tower gage 6. This output will always be zero for FAST simulation results. Use it for examining tower torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence.; About the local zt-axis -ElastoDyn['TwHt7RDxt'] = False # (deg); Local tower angular (rotational) roll deflection (relative to the undeflected position) of tower gage 7. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower deflections, so that the rotation sequence does not matter.; About the local xt-axis -ElastoDyn['TwHt7RDyt'] = False # (deg); Local tower angular (rotational) pitch deflection (relative to the undeflected position) of tower gage 7. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower deflections, so that the rotation sequence does not matter.; About the local yt-axis -ElastoDyn['TwHt7RDzt'] = False # (deg); Local tower angular (rotational) torsion deflection (relative to the undeflected position) of tower gage 7. This output will always be zero for FAST simulation results. Use it for examining tower torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence.; About the local zt-axis -ElastoDyn['TwHt8RDxt'] = False # (deg); Local tower angular (rotational) roll deflection (relative to the undeflected position) of tower gage 8. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower deflections, so that the rotation sequence does not matter.; About the local xt-axis -ElastoDyn['TwHt8RDyt'] = False # (deg); Local tower angular (rotational) pitch deflection (relative to the undeflected position) of tower gage 8. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower deflections, so that the rotation sequence does not matter.; About the local yt-axis -ElastoDyn['TwHt8RDzt'] = False # (deg); Local tower angular (rotational) torsion deflection (relative to the undeflected position) of tower gage 8. This output will always be zero for FAST simulation results. Use it for examining tower torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence.; About the local zt-axis -ElastoDyn['TwHt9RDxt'] = False # (deg); Local tower angular (rotational) roll deflection (relative to the undeflected position) of tower gage 9. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower deflections, so that the rotation sequence does not matter.; About the local xt-axis -ElastoDyn['TwHt9RDyt'] = False # (deg); Local tower angular (rotational) pitch deflection (relative to the undeflected position) of tower gage 9. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower deflections, so that the rotation sequence does not matter.; About the local yt-axis -ElastoDyn['TwHt9RDzt'] = False # (deg); Local tower angular (rotational) torsion deflection (relative to the undeflected position) of tower gage 9. This output will always be zero for FAST simulation results. Use it for examining tower torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence.; About the local zt-axis -ElastoDyn['TwHt1TPxi'] = False # (m); xi-component of the translational position (relative to the inertia frame) of tower gage 1; Directed along the local xi-axis -ElastoDyn['TwHt1TPyi'] = False # (m); yi-component of the translational position (relative to the inertia frame) of tower gage 1; Directed along the local yi-axis -ElastoDyn['TwHt1TPzi'] = False # (m); zi-component of the translational position (relative to ground level [onshore] or MSL [offshore]) of tower gage 1; Directed along the local zi-axis -ElastoDyn['TwHt2TPxi'] = False # (m); xi-component of the translational position (relative to the inertia frame) of tower gage 2; Directed along the local xi-axis -ElastoDyn['TwHt2TPyi'] = False # (m); yi-component of the translational position (relative to the inertia frame) of tower gage 2; Directed along the local yi-axis -ElastoDyn['TwHt2TPzi'] = False # (m); zi-component of the translational position (relative to ground level [onshore] or MSL [offshore]) of tower gage 2; Directed along the local zi-axis -ElastoDyn['TwHt3TPxi'] = False # (m); xi-component of the translational position (relative to the inertia frame) of tower gage 3; Directed along the local xi-axis -ElastoDyn['TwHt3TPyi'] = False # (m); yi-component of the translational position (relative to the inertia frame) of tower gage 3; Directed along the local yi-axis -ElastoDyn['TwHt3TPzi'] = False # (m); zi-component of the translational position (relative to ground level [onshore] or MSL [offshore]) of tower gage 3; Directed along the local zi-axis -ElastoDyn['TwHt4TPxi'] = False # (m); xi-component of the translational position (relative to the inertia frame) of tower gage 4; Directed along the local xi-axis -ElastoDyn['TwHt4TPyi'] = False # (m); yi-component of the translational position (relative to the inertia frame) of tower gage 4; Directed along the local yi-axis -ElastoDyn['TwHt4TPzi'] = False # (m); zi-component of the translational position (relative to ground level [onshore] or MSL [offshore]) of tower gage 4; Directed along the local zi-axis -ElastoDyn['TwHt5TPxi'] = False # (m); xi-component of the translational position (relative to the inertia frame) of tower gage 5; Directed along the local xi-axis -ElastoDyn['TwHt5TPyi'] = False # (m); yi-component of the translational position (relative to the inertia frame) of tower gage 5; Directed along the local yi-axis -ElastoDyn['TwHt5TPzi'] = False # (m); zi-component of the translational position (relative to ground level [onshore] or MSL [offshore]) of tower gage 5; Directed along the local zi-axis -ElastoDyn['TwHt6TPxi'] = False # (m); xi-component of the translational position (relative to the inertia frame) of tower gage 6; Directed along the local xi-axis -ElastoDyn['TwHt6TPyi'] = False # (m); yi-component of the translational position (relative to the inertia frame) of tower gage 6; Directed along the local yi-axis -ElastoDyn['TwHt6TPzi'] = False # (m); zi-component of the translational position (relative to ground level [onshore] or MSL [offshore]) of tower gage 6; Directed along the local zi-axis -ElastoDyn['TwHt7TPxi'] = False # (m); xi-component of the translational position (relative to the inertia frame) of tower gage 7; Directed along the local xi-axis -ElastoDyn['TwHt7TPyi'] = False # (m); yi-component of the translational position (relative to the inertia frame) of tower gage 7; Directed along the local yi-axis -ElastoDyn['TwHt7TPzi'] = False # (m); zi-component of the translational position (relative to ground level [onshore] or MSL [offshore]) of tower gage 7; Directed along the local zi-axis -ElastoDyn['TwHt8TPxi'] = False # (m); xi-component of the translational position (relative to the inertia frame) of tower gage 8; Directed along the local xi-axis -ElastoDyn['TwHt8TPyi'] = False # (m); yi-component of the translational position (relative to the inertia frame) of tower gage 8; Directed along the local yi-axis -ElastoDyn['TwHt8TPzi'] = False # (m); zi-component of the translational position (relative to ground level [onshore] or MSL [offshore]) of tower gage 8; Directed along the local zi-axis -ElastoDyn['TwHt9TPxi'] = False # (m); xi-component of the translational position (relative to the inertia frame) of tower gage 9; Directed along the local xi-axis -ElastoDyn['TwHt9TPyi'] = False # (m); yi-component of the translational position (relative to the inertia frame) of tower gage 9; Directed along the local yi-axis -ElastoDyn['TwHt9TPzi'] = False # (m); zi-component of the translational position (relative to ground level [onshore] or MSL [offshore]) of tower gage 9; Directed along the local zi-axis -ElastoDyn['TwHt1RPxi'] = False # (deg); xi-component of the rotational position (relative to the inertia frame) of tower gage 1. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower and platform rotational deflections, so that the rotation sequence does not matter.; About the local xi-axis -ElastoDyn['TwHt1RPyi'] = False # (deg); yi-component of the rotational position (relative to the inertia frame) of tower gage 1. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower and platform rotational deflections, so that the rotation sequence does not matter.; About the local yi-axis -ElastoDyn['TwHt1RPzi'] = False # (deg); zi-component of the rotational position (relative to the inertia frame) of tower gage 1. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower and platform rotational deflections, so that the rotation sequence does not matter.; About the local zi-axis -ElastoDyn['TwHt2RPxi'] = False # (deg); xi-component of the rotational position (relative to the inertia frame) of tower gage 2. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower and platform rotational deflections, so that the rotation sequence does not matter.; About the local xi-axis -ElastoDyn['TwHt2RPyi'] = False # (deg); yi-component of the rotational position (relative to the inertia frame) of tower gage 2. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower and platform rotational deflections, so that the rotation sequence does not matter.; About the local yi-axis -ElastoDyn['TwHt2RPzi'] = False # (deg); zi-component of the rotational position (relative to the inertia frame) of tower gage 2. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower and platform rotational deflections, so that the rotation sequence does not matter.; About the local zi-axis -ElastoDyn['TwHt3RPxi'] = False # (deg); xi-component of the rotational position (relative to the inertia frame) of tower gage 3. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower and platform rotational deflections, so that the rotation sequence does not matter.; About the local xi-axis -ElastoDyn['TwHt3RPyi'] = False # (deg); yi-component of the rotational position (relative to the inertia frame) of tower gage 3. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower and platform rotational deflections, so that the rotation sequence does not matter.; About the local yi-axis -ElastoDyn['TwHt3RPzi'] = False # (deg); zi-component of the rotational position (relative to the inertia frame) of tower gage 3. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower and platform rotational deflections, so that the rotation sequence does not matter.; About the local zi-axis -ElastoDyn['TwHt4RPxi'] = False # (deg); xi-component of the rotational position (relative to the inertia frame) of tower gage 4. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower and platform rotational deflections, so that the rotation sequence does not matter.; About the local xi-axis -ElastoDyn['TwHt4RPyi'] = False # (deg); yi-component of the rotational position (relative to the inertia frame) of tower gage 4. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower and platform rotational deflections, so that the rotation sequence does not matter.; About the local yi-axis -ElastoDyn['TwHt4RPzi'] = False # (deg); zi-component of the rotational position (relative to the inertia frame) of tower gage 4. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower and platform rotational deflections, so that the rotation sequence does not matter.; About the local zi-axis -ElastoDyn['TwHt5RPxi'] = False # (deg); xi-component of the rotational position (relative to the inertia frame) of tower gage 5. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower and platform rotational deflections, so that the rotation sequence does not matter.; About the local xi-axis -ElastoDyn['TwHt5RPyi'] = False # (deg); yi-component of the rotational position (relative to the inertia frame) of tower gage 5. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower and platform rotational deflections, so that the rotation sequence does not matter.; About the local yi-axis -ElastoDyn['TwHt5RPzi'] = False # (deg); zi-component of the rotational position (relative to the inertia frame) of tower gage 5. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower and platform rotational deflections, so that the rotation sequence does not matter.; About the local zi-axis -ElastoDyn['TwHt6RPxi'] = False # (deg); xi-component of the rotational position (relative to the inertia frame) of tower gage 6. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower and platform rotational deflections, so that the rotation sequence does not matter.; About the local xi-axis -ElastoDyn['TwHt6RPyi'] = False # (deg); yi-component of the rotational position (relative to the inertia frame) of tower gage 6. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower and platform rotational deflections, so that the rotation sequence does not matter.; About the local yi-axis -ElastoDyn['TwHt6RPzi'] = False # (deg); zi-component of the rotational position (relative to the inertia frame) of tower gage 6. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower and platform rotational deflections, so that the rotation sequence does not matter.; About the local zi-axis -ElastoDyn['TwHt7RPxi'] = False # (deg); xi-component of the rotational position (relative to the inertia frame) of tower gage 7. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower and platform rotational deflections, so that the rotation sequence does not matter.; About the local xi-axis -ElastoDyn['TwHt7RPyi'] = False # (deg); yi-component of the rotational position (relative to the inertia frame) of tower gage 7. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower and platform rotational deflections, so that the rotation sequence does not matter.; About the local yi-axis -ElastoDyn['TwHt7RPzi'] = False # (deg); zi-component of the rotational position (relative to the inertia frame) of tower gage 7. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower and platform rotational deflections, so that the rotation sequence does not matter.; About the local zi-axis -ElastoDyn['TwHt8RPxi'] = False # (deg); xi-component of the rotational position (relative to the inertia frame) of tower gage 8. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower and platform rotational deflections, so that the rotation sequence does not matter.; About the local xi-axis -ElastoDyn['TwHt8RPyi'] = False # (deg); yi-component of the rotational position (relative to the inertia frame) of tower gage 8. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower and platform rotational deflections, so that the rotation sequence does not matter.; About the local yi-axis -ElastoDyn['TwHt8RPzi'] = False # (deg); zi-component of the rotational position (relative to the inertia frame) of tower gage 8. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower and platform rotational deflections, so that the rotation sequence does not matter.; About the local zi-axis -ElastoDyn['TwHt9RPxi'] = False # (deg); xi-component of the rotational position (relative to the inertia frame) of tower gage 9. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower and platform rotational deflections, so that the rotation sequence does not matter.; About the local xi-axis -ElastoDyn['TwHt9RPyi'] = False # (deg); yi-component of the rotational position (relative to the inertia frame) of tower gage 9. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower and platform rotational deflections, so that the rotation sequence does not matter.; About the local yi-axis -ElastoDyn['TwHt9RPzi'] = False # (deg); zi-component of the rotational position (relative to the inertia frame) of tower gage 9. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower and platform rotational deflections, so that the rotation sequence does not matter.; About the local zi-axis - -# Platform Motions -ElastoDyn['PtfmTDxt'] = False # (m); Platform horizontal surge (translational) displacement; Directed along the xt-axis -ElastoDyn['PtfmTDyt'] = False # (m); Platform horizontal sway (translational) displacement; Directed along the yt-axis -ElastoDyn['PtfmTDzt'] = False # (m); Platform vertical heave (translational) displacement; Directed along the zt-axis -ElastoDyn['PtfmTDxi'] = False # (m); Platform horizontal surge (translational) displacement; Directed along the xi-axis -ElastoDyn['PtfmSurge'] = False # (m); Platform horizontal surge (translational) displacement; Directed along the xi-axis -ElastoDyn['PtfmTDyi'] = False # (m); Platform horizontal sway (translational) displacement; Directed along the yi-axis -ElastoDyn['PtfmSway'] = False # (m); Platform horizontal sway (translational) displacement; Directed along the yi-axis -ElastoDyn['PtfmTDzi'] = False # (m); Platform vertical heave (translational) displacement; Directed along the zi-axis -ElastoDyn['PtfmHeave'] = False # (m); Platform vertical heave (translational) displacement; Directed along the zi-axis -ElastoDyn['PtfmTVxt'] = False # (m/s); Platform horizontal surge (translational) velocity; Directed along the xt-axis -ElastoDyn['PtfmTVyt'] = False # (m/s); Platform horizontal sway (translational) velocity; Directed along the yt-axis -ElastoDyn['PtfmTVzt'] = False # (m/s); Platform vertical heave (translational) velocity; Directed along the zt-axis -ElastoDyn['PtfmTVxi'] = False # (m/s); Platform horizontal surge (translational) velocity; Directed along the xi-axis -ElastoDyn['PtfmTVyi'] = False # (m/s); Platform horizontal sway (translational) velocity; Directed along the yi-axis -ElastoDyn['PtfmTVzi'] = False # (m/s); Platform vertical heave (translational) velocity; Directed along the zi-axis -ElastoDyn['PtfmTAxt'] = False # (m/s^2); Platform horizontal surge (translational) acceleration; Directed along the xt-axis -ElastoDyn['PtfmTAyt'] = False # (m/s^2); Platform horizontal sway (translational) acceleration; Directed along the yt-axis -ElastoDyn['PtfmTAzt'] = False # (m/s^2); Platform vertical heave (translational) acceleration; Directed along the zt-axis -ElastoDyn['PtfmTAxi'] = False # (m/s^2); Platform horizontal surge (translational) acceleration; Directed along the xi-axis -ElastoDyn['PtfmTAyi'] = False # (m/s^2); Platform horizontal sway (translational) acceleration; Directed along the yi-axis -ElastoDyn['PtfmTAzi'] = False # (m/s^2); Platform vertical heave (translational) acceleration; Directed along the zi-axis -ElastoDyn['PtfmRDxi'] = False # (deg); Platform roll tilt angular (rotational) displacement. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small rotational platform displacements, so that the rotation sequence does not matter.; About the xi-axis -ElastoDyn['PtfmRoll'] = False # (deg); Platform roll tilt angular (rotational) displacement. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small rotational platform displacements, so that the rotation sequence does not matter.; About the xi-axis -ElastoDyn['PtfmRDyi'] = False # (deg); Platform pitch tilt angular (rotational) displacement. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small rotational platform displacements, so that the rotation sequence does not matter.; About the yi-axis -ElastoDyn['PtfmPitch'] = False # (deg); Platform pitch tilt angular (rotational) displacement. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small rotational platform displacements, so that the rotation sequence does not matter.; About the yi-axis -ElastoDyn['PtfmRDzi'] = False # (deg); Platform yaw angular (rotational) displacement. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small rotational platform displacements, so that the rotation sequence does not matter.; About the zi-axis -ElastoDyn['PtfmYaw'] = False # (deg); Platform yaw angular (rotational) displacement. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small rotational platform displacements, so that the rotation sequence does not matter.; About the zi-axis -ElastoDyn['PtfmRVxt'] = False # (deg/s); Platform roll tilt angular (rotational) velocity; About the xt-axis -ElastoDyn['PtfmRVyt'] = False # (deg/s); Platform pitch tilt angular (rotational) velocity; About the yt-axis -ElastoDyn['PtfmRVzt'] = False # (deg/s); Platform yaw angular (rotational) velocity; About the zt-axis -ElastoDyn['PtfmRVxi'] = False # (deg/s); Platform roll tilt angular (rotational) velocity; About the xi-axis -ElastoDyn['PtfmRVyi'] = False # (deg/s); Platform pitch tilt angular (rotational) velocity; About the yi-axis -ElastoDyn['PtfmRVzi'] = False # (deg/s); Platform yaw angular (rotational) velocity; About the zi-axis -ElastoDyn['PtfmRAxt'] = False # (deg/s^2); Platform roll tilt angular (rotational) acceleration; About the xt-axis -ElastoDyn['PtfmRAyt'] = False # (deg/s^2); Platform pitch tilt angular (rotational) acceleration; About the yt-axis -ElastoDyn['PtfmRAzt'] = False # (deg/s^2); Platform yaw angular (rotational) acceleration; About the zt-axis -ElastoDyn['PtfmRAxi'] = False # (deg/s^2); Platform roll tilt angular (rotational) acceleration; About the xi-axis -ElastoDyn['PtfmRAyi'] = False # (deg/s^2); Platform pitch tilt angular (rotational) acceleration; About the yi-axis -ElastoDyn['PtfmRAzi'] = False # (deg/s^2); Platform yaw angular (rotational) acceleration; About the zi-axis - -# Blade 1 Root Loads -ElastoDyn['RootFxc1'] = False # (kN); Blade 1 out-of-plane shear force at the blade root; Directed along the xc1-axis -ElastoDyn['RootFyc1'] = False # (kN); Blade 1 in-plane shear force at the blade root; Directed along the yc1-axis -ElastoDyn['RootFzc1'] = False # (kN); Blade 1 axial force at the blade root; Directed along the zc1- and zb1-axes -ElastoDyn['RootFzb1'] = False # (kN); Blade 1 axial force at the blade root; Directed along the zc1- and zb1-axes -ElastoDyn['RootFxb1'] = False # (kN); Blade 1 flapwise shear force at the blade root; Directed along the xb1-axis -ElastoDyn['RootFyb1'] = False # (kN); Blade 1 edgewise shear force at the blade root; Directed along the yb1-axis -ElastoDyn['RootMxc1'] = False # (kN-m); Blade 1 in-plane moment (i.e., the moment caused by in-plane forces) at the blade root; About the xc1-axis -ElastoDyn['RootMIP1'] = False # (kN-m); Blade 1 in-plane moment (i.e., the moment caused by in-plane forces) at the blade root; About the xc1-axis -ElastoDyn['RootMyc1'] = False # (kN-m); Blade 1 out-of-plane moment (i.e., the moment caused by out-of-plane forces) at the blade root; About the yc1-axis -ElastoDyn['RootMOoP1'] = False # (kN-m); Blade 1 out-of-plane moment (i.e., the moment caused by out-of-plane forces) at the blade root; About the yc1-axis -ElastoDyn['RootMzc1'] = False # (kN-m); Blade 1 pitching moment at the blade root; About the zc1- and zb1-axes -ElastoDyn['RootMzb1'] = False # (kN-m); Blade 1 pitching moment at the blade root; About the zc1- and zb1-axes -ElastoDyn['RootMxb1'] = False # (kN-m); Blade 1 edgewise moment (i.e., the moment caused by edgewise forces) at the blade root; About the xb1-axis -ElastoDyn['RootMEdg1'] = False # (kN-m); Blade 1 edgewise moment (i.e., the moment caused by edgewise forces) at the blade root; About the xb1-axis -ElastoDyn['RootMyb1'] = True # (kN-m); Blade 1 flapwise moment (i.e., the moment caused by flapwise forces) at the blade root; About the yb1-axis -ElastoDyn['RootMFlp1'] = False # (kN-m); Blade 1 flapwise moment (i.e., the moment caused by flapwise forces) at the blade root; About the yb1-axis - -# Blade 2 Root Loads -ElastoDyn['RootFxc2'] = False # (kN); Blade 2 out-of-plane shear force at the blade root; Directed along the xc2-axis -ElastoDyn['RootFyc2'] = False # (kN); Blade 2 in-plane shear force at the blade root; Directed along the yc2-axis -ElastoDyn['RootFzc2'] = False # (kN); Blade 2 axial force at the blade root; Directed along the zc2- and zb2-axes -ElastoDyn['RootFzb2'] = False # (kN); Blade 2 axial force at the blade root; Directed along the zc2- and zb2-axes -ElastoDyn['RootFxb2'] = False # (kN); Blade 2 flapwise shear force at the blade root; Directed along the xb2-axis -ElastoDyn['RootFyb2'] = False # (kN); Blade 2 edgewise shear force at the blade root; Directed along the yb2-axis -ElastoDyn['RootMxc2'] = False # (kN-m); Blade 2 in-plane moment (i.e., the moment caused by in-plane forces) at the blade root; About the xc2-axis -ElastoDyn['RootMIP2'] = False # (kN-m); Blade 2 in-plane moment (i.e., the moment caused by in-plane forces) at the blade root; About the xc2-axis -ElastoDyn['RootMyc2'] = False # (kN-m); Blade 2 out-of-plane moment (i.e., the moment caused by out-of-plane forces) at the blade root; About the yc2-axis -ElastoDyn['RootMOoP2'] = False # (kN-m); Blade 2 out-of-plane moment (i.e., the moment caused by out-of-plane forces) at the blade root; About the yc2-axis -ElastoDyn['RootMzc2'] = False # (kN-m); Blade 2 pitching moment at the blade root; About the zc2- and zb2-axes -ElastoDyn['RootMzb2'] = False # (kN-m); Blade 2 pitching moment at the blade root; About the zc2- and zb2-axes -ElastoDyn['RootMxb2'] = False # (kN-m); Blade 2 edgewise moment (i.e., the moment caused by edgewise forces) at the blade root; About the xb2-axis -ElastoDyn['RootMEdg2'] = False # (kN-m); Blade 2 edgewise moment (i.e., the moment caused by edgewise forces) at the blade root; About the xb2-axis -ElastoDyn['RootMyb2'] = True # (kN-m); Blade 2 flapwise moment (i.e., the moment caused by flapwise forces) at the blade root; About the yb2-axis -ElastoDyn['RootMFlp2'] = False # (kN-m); Blade 2 flapwise moment (i.e., the moment caused by flapwise forces) at the blade root; About the yb2-axis - -# Blade 3 Root Loads -ElastoDyn['RootFxc3'] = False # (kN); Blade 3 out-of-plane shear force at the blade root; Directed along the xc3-axis -ElastoDyn['RootFyc3'] = False # (kN); Blade 3 in-plane shear force at the blade root; Directed along the yc3-axis -ElastoDyn['RootFzc3'] = False # (kN); Blade 3 axial force at the blade root; Directed along the zc3- and zb3-axes -ElastoDyn['RootFzb3'] = False # (kN); Blade 3 axial force at the blade root; Directed along the zc3- and zb3-axes -ElastoDyn['RootFxb3'] = False # (kN); Blade 3 flapwise shear force at the blade root; Directed along the xb3-axis -ElastoDyn['RootFyb3'] = False # (kN); Blade 3 edgewise shear force at the blade root; Directed along the yb3-axis -ElastoDyn['RootMxc3'] = False # (kN-m); Blade 3 in-plane moment (i.e., the moment caused by in-plane forces) at the blade root; About the xc3-axis -ElastoDyn['RootMIP3'] = False # (kN-m); Blade 3 in-plane moment (i.e., the moment caused by in-plane forces) at the blade root; About the xc3-axis -ElastoDyn['RootMyc3'] = False # (kN-m); Blade 3 out-of-plane moment (i.e., the moment caused by out-of-plane forces) at the blade root; About the yc3-axis -ElastoDyn['RootMOoP3'] = False # (kN-m); Blade 3 out-of-plane moment (i.e., the moment caused by out-of-plane forces) at the blade root; About the yc3-axis -ElastoDyn['RootMzc3'] = False # (kN-m); Blade 3 pitching moment at the blade root; About the zc3- and zb3-axes -ElastoDyn['RootMzb3'] = False # (kN-m); Blade 3 pitching moment at the blade root; About the zc3- and zb3-axes -ElastoDyn['RootMxb3'] = False # (kN-m); Blade 3 edgewise moment (i.e., the moment caused by edgewise forces) at the blade root; About the xb3-axis -ElastoDyn['RootMEdg3'] = False # (kN-m); Blade 3 edgewise moment (i.e., the moment caused by edgewise forces) at the blade root; About the xb3-axis -ElastoDyn['RootMyb3'] = True # (kN-m); Blade 3 flapwise moment (i.e., the moment caused by flapwise forces) at the blade root; About the yb3-axis -ElastoDyn['RootMFlp3'] = False # (kN-m); Blade 3 flapwise moment (i.e., the moment caused by flapwise forces) at the blade root; About the yb3-axis - -# Blade 1 Local Span Loads -ElastoDyn['Spn1MLxb1'] = False # (kN-m); Blade 1 local edgewise moment at span station 1; About the local xb1-axis -ElastoDyn['Spn1MLyb1'] = False # (kN-m); Blade 1 local flapwise moment at span station 1; About the local yb1-axis -ElastoDyn['Spn1MLzb1'] = False # (kN-m); Blade 1 local pitching moment at span station 1; About the local zb1-axis -ElastoDyn['Spn2MLxb1'] = False # (kN-m); Blade 1 local edgewise moment at span station 2; About the local xb1-axis -ElastoDyn['Spn2MLyb1'] = False # (kN-m); Blade 1 local flapwise moment at span station 2; About the local yb1-axis -ElastoDyn['Spn2MLzb1'] = False # (kN-m); Blade 1 local pitching moment at span station 2; About the local zb1-axis -ElastoDyn['Spn3MLxb1'] = False # (kN-m); Blade 1 local edgewise moment at span station 3; About the local xb1-axis -ElastoDyn['Spn3MLyb1'] = False # (kN-m); Blade 1 local flapwise moment at span station 3; About the local yb1-axis -ElastoDyn['Spn3MLzb1'] = False # (kN-m); Blade 1 local pitching moment at span station 3; About the local zb1-axis -ElastoDyn['Spn4MLxb1'] = False # (kN-m); Blade 1 local edgewise moment at span station 4; About the local xb1-axis -ElastoDyn['Spn4MLyb1'] = False # (kN-m); Blade 1 local flapwise moment at span station 4; About the local yb1-axis -ElastoDyn['Spn4MLzb1'] = False # (kN-m); Blade 1 local pitching moment at span station 4; About the local zb1-axis -ElastoDyn['Spn5MLxb1'] = False # (kN-m); Blade 1 local edgewise moment at span station 5; About the local xb1-axis -ElastoDyn['Spn5MLyb1'] = False # (kN-m); Blade 1 local flapwise moment at span station 5; About the local yb1-axis -ElastoDyn['Spn5MLzb1'] = False # (kN-m); Blade 1 local pitching moment at span station 5; About the local zb1-axis -ElastoDyn['Spn6MLxb1'] = False # (kN-m); Blade 1 local edgewise moment at span station 6; About the local xb1-axis -ElastoDyn['Spn6MLyb1'] = False # (kN-m); Blade 1 local flapwise moment at span station 6; About the local yb1-axis -ElastoDyn['Spn6MLzb1'] = False # (kN-m); Blade 1 local pitching moment at span station 6; About the local zb1-axis -ElastoDyn['Spn7MLxb1'] = False # (kN-m); Blade 1 local edgewise moment at span station 7; About the local xb1-axis -ElastoDyn['Spn7MLyb1'] = False # (kN-m); Blade 1 local flapwise moment at span station 7; About the local yb1-axis -ElastoDyn['Spn7MLzb1'] = False # (kN-m); Blade 1 local pitching moment at span station 7; About the local zb1-axis -ElastoDyn['Spn8MLxb1'] = False # (kN-m); Blade 1 local edgewise moment at span station 8; About the local xb1-axis -ElastoDyn['Spn8MLyb1'] = False # (kN-m); Blade 1 local flapwise moment at span station 8; About the local yb1-axis -ElastoDyn['Spn8MLzb1'] = False # (kN-m); Blade 1 local pitching moment at span station 8; About the local zb1-axis -ElastoDyn['Spn9MLxb1'] = False # (kN-m); Blade 1 local edgewise moment at span station 9; About the local xb1-axis -ElastoDyn['Spn9MLyb1'] = False # (kN-m); Blade 1 local flapwise moment at span station 9; About the local yb1-axis -ElastoDyn['Spn9MLzb1'] = False # (kN-m); Blade 1 local pitching moment at span station 9; About the local zb1-axis -ElastoDyn['Spn1FLxb1'] = False # (kN); Blade 1 local flapwise shear force at span station 1; Directed along the local xb1-axis -ElastoDyn['Spn1FLyb1'] = False # (kN); Blade 1 local edgewise shear force at span station 1; Directed along the local yb1-axis -ElastoDyn['Spn1FLzb1'] = False # (kN); Blade 1 local axial force at span station 1; Directed along the local zb1-axis -ElastoDyn['Spn2FLxb1'] = False # (kN); Blade 1 local flapwise shear force at span station 2; Directed along the local xb1-axis -ElastoDyn['Spn2FLyb1'] = False # (kN); Blade 1 local edgewise shear force at span station 2; Directed along the local yb1-axis -ElastoDyn['Spn2FLzb1'] = False # (kN); Blade 1 local axial force at span station 2; Directed along the local zb1-axis -ElastoDyn['Spn3FLxb1'] = False # (kN); Blade 1 local flapwise shear force at span station 3; Directed along the local xb1-axis -ElastoDyn['Spn3FLyb1'] = False # (kN); Blade 1 local edgewise shear force at span station 3; Directed along the local yb1-axis -ElastoDyn['Spn3FLzb1'] = False # (kN); Blade 1 local axial force at span station 3; Directed along the local zb1-axis -ElastoDyn['Spn4FLxb1'] = False # (kN); Blade 1 local flapwise shear force at span station 4; Directed along the local xb1-axis -ElastoDyn['Spn4FLyb1'] = False # (kN); Blade 1 local edgewise shear force at span station 4; Directed along the local yb1-axis -ElastoDyn['Spn4FLzb1'] = False # (kN); Blade 1 local axial force at span station 4; Directed along the local zb1-axis -ElastoDyn['Spn5FLxb1'] = False # (kN); Blade 1 local flapwise shear force at span station 5; Directed along the local xb1-axis -ElastoDyn['Spn5FLyb1'] = False # (kN); Blade 1 local edgewise shear force at span station 5; Directed along the local yb1-axis -ElastoDyn['Spn5FLzb1'] = False # (kN); Blade 1 local axial force at span station 5; Directed along the local zb1-axis -ElastoDyn['Spn6FLxb1'] = False # (kN); Blade 1 local flapwise shear force at span station 6; Directed along the local xb1-axis -ElastoDyn['Spn6FLyb1'] = False # (kN); Blade 1 local edgewise shear force at span station 6; Directed along the local yb1-axis -ElastoDyn['Spn6FLzb1'] = False # (kN); Blade 1 local axial force at span station 6; Directed along the local zb1-axis -ElastoDyn['Spn7FLxb1'] = False # (kN); Blade 1 local flapwise shear force at span station 7; Directed along the local xb1-axis -ElastoDyn['Spn7FLyb1'] = False # (kN); Blade 1 local edgewise shear force at span station 7; Directed along the local yb1-axis -ElastoDyn['Spn7FLzb1'] = False # (kN); Blade 1 local axial force at span station 7; Directed along the local zb1-axis -ElastoDyn['Spn8FLxb1'] = False # (kN); Blade 1 local flapwise shear force at span station 8; Directed along the local xb1-axis -ElastoDyn['Spn8FLyb1'] = False # (kN); Blade 1 local edgewise shear force at span station 8; Directed along the local yb1-axis -ElastoDyn['Spn8FLzb1'] = False # (kN); Blade 1 local axial force at span station 8; Directed along the local zb1-axis -ElastoDyn['Spn9FLxb1'] = False # (kN); Blade 1 local flapwise shear force at span station 9; Directed along the local xb1-axis -ElastoDyn['Spn9FLyb1'] = False # (kN); Blade 1 local edgewise shear force at span station 9; Directed along the local yb1-axis -ElastoDyn['Spn9FLzb1'] = False # (kN); Blade 1 local axial force at span station 9; Directed along the local zb1-axis - -# Blade 2 Local Span Loads -ElastoDyn['Spn1MLxb2'] = False # (kN-m); Blade 2 local edgewise moment at span station 1; About the local xb2-axis -ElastoDyn['Spn1MLyb2'] = False # (kN-m); Blade 2 local flapwise moment at span station 1; About the local yb2-axis -ElastoDyn['Spn1MLzb2'] = False # (kN-m); Blade 2 local pitching moment at span station 1; About the local zb2-axis -ElastoDyn['Spn2MLxb2'] = False # (kN-m); Blade 2 local edgewise moment at span station 2; About the local xb2-axis -ElastoDyn['Spn2MLyb2'] = False # (kN-m); Blade 2 local flapwise moment at span station 2; About the local yb2-axis -ElastoDyn['Spn2MLzb2'] = False # (kN-m); Blade 2 local pitching moment at span station 2; About the local zb2-axis -ElastoDyn['Spn3MLxb2'] = False # (kN-m); Blade 2 local edgewise moment at span station 3; About the local xb2-axis -ElastoDyn['Spn3MLyb2'] = False # (kN-m); Blade 2 local flapwise moment at span station 3; About the local yb2-axis -ElastoDyn['Spn3MLzb2'] = False # (kN-m); Blade 2 local pitching moment at span station 3; About the local zb2-axis -ElastoDyn['Spn4MLxb2'] = False # (kN-m); Blade 2 local edgewise moment at span station 4; About the local xb2-axis -ElastoDyn['Spn4MLyb2'] = False # (kN-m); Blade 2 local flapwise moment at span station 4; About the local yb2-axis -ElastoDyn['Spn4MLzb2'] = False # (kN-m); Blade 2 local pitching moment at span station 4; About the local zb2-axis -ElastoDyn['Spn5MLxb2'] = False # (kN-m); Blade 2 local edgewise moment at span station 5; About the local xb2-axis -ElastoDyn['Spn5MLyb2'] = False # (kN-m); Blade 2 local flapwise moment at span station 5; About the local yb2-axis -ElastoDyn['Spn5MLzb2'] = False # (kN-m); Blade 2 local pitching moment at span station 5; About the local zb2-axis -ElastoDyn['Spn6MLxb2'] = False # (kN-m); Blade 2 local edgewise moment at span station 6; About the local xb2-axis -ElastoDyn['Spn6MLyb2'] = False # (kN-m); Blade 2 local flapwise moment at span station 6; About the local yb2-axis -ElastoDyn['Spn6MLzb2'] = False # (kN-m); Blade 2 local pitching moment at span station 6; About the local zb2-axis -ElastoDyn['Spn7MLxb2'] = False # (kN-m); Blade 2 local edgewise moment at span station 7; About the local xb2-axis -ElastoDyn['Spn7MLyb2'] = False # (kN-m); Blade 2 local flapwise moment at span station 7; About the local yb2-axis -ElastoDyn['Spn7MLzb2'] = False # (kN-m); Blade 2 local pitching moment at span station 7; About the local zb2-axis -ElastoDyn['Spn8MLxb2'] = False # (kN-m); Blade 2 local edgewise moment at span station 8; About the local xb2-axis -ElastoDyn['Spn8MLyb2'] = False # (kN-m); Blade 2 local flapwise moment at span station 8; About the local yb2-axis -ElastoDyn['Spn8MLzb2'] = False # (kN-m); Blade 2 local pitching moment at span station 8; About the local zb2-axis -ElastoDyn['Spn9MLxb2'] = False # (kN-m); Blade 2 local edgewise moment at span station 9; About the local xb2-axis -ElastoDyn['Spn9MLyb2'] = False # (kN-m); Blade 2 local flapwise moment at span station 9; About the local yb2-axis -ElastoDyn['Spn9MLzb2'] = False # (kN-m); Blade 2 local pitching moment at span station 9; About the local zb2-axis -ElastoDyn['Spn1FLxb2'] = False # (kN); Blade 2 local flapwise shear force at span station 1; Directed along the local xb2-axis -ElastoDyn['Spn1FLyb2'] = False # (kN); Blade 2 local edgewise shear force at span station 1; Directed along the local yb2-axis -ElastoDyn['Spn1FLzb2'] = False # (kN); Blade 2 local axial force at span station 1; Directed along the local zb2-axis -ElastoDyn['Spn2FLxb2'] = False # (kN); Blade 2 local flapwise shear force at span station 2; Directed along the local xb2-axis -ElastoDyn['Spn2FLyb2'] = False # (kN); Blade 2 local edgewise shear force at span station 2; Directed along the local yb2-axis -ElastoDyn['Spn2FLzb2'] = False # (kN); Blade 2 local axial force at span station 2; Directed along the local zb2-axis -ElastoDyn['Spn3FLxb2'] = False # (kN); Blade 2 local flapwise shear force at span station 3; Directed along the local xb2-axis -ElastoDyn['Spn3FLyb2'] = False # (kN); Blade 2 local edgewise shear force at span station 3; Directed along the local yb2-axis -ElastoDyn['Spn3FLzb2'] = False # (kN); Blade 2 local axial force at span station 3; Directed along the local zb2-axis -ElastoDyn['Spn4FLxb2'] = False # (kN); Blade 2 local flapwise shear force at span station 4; Directed along the local xb2-axis -ElastoDyn['Spn4FLyb2'] = False # (kN); Blade 2 local edgewise shear force at span station 4; Directed along the local yb2-axis -ElastoDyn['Spn4FLzb2'] = False # (kN); Blade 2 local axial force at span station 4; Directed along the local zb2-axis -ElastoDyn['Spn5FLxb2'] = False # (kN); Blade 2 local flapwise shear force at span station 5; Directed along the local xb2-axis -ElastoDyn['Spn5FLyb2'] = False # (kN); Blade 2 local edgewise shear force at span station 5; Directed along the local yb2-axis -ElastoDyn['Spn5FLzb2'] = False # (kN); Blade 2 local axial force at span station 5; Directed along the local zb2-axis -ElastoDyn['Spn6FLxb2'] = False # (kN); Blade 2 local flapwise shear force at span station 6; Directed along the local xb2-axis -ElastoDyn['Spn6FLyb2'] = False # (kN); Blade 2 local edgewise shear force at span station 6; Directed along the local yb2-axis -ElastoDyn['Spn6FLzb2'] = False # (kN); Blade 2 local axial force at span station 6; Directed along the local zb2-axis -ElastoDyn['Spn7FLxb2'] = False # (kN); Blade 2 local flapwise shear force at span station 7; Directed along the local xb2-axis -ElastoDyn['Spn7FLyb2'] = False # (kN); Blade 2 local edgewise shear force at span station 7; Directed along the local yb2-axis -ElastoDyn['Spn7FLzb2'] = False # (kN); Blade 2 local axial force at span station 7; Directed along the local zb2-axis -ElastoDyn['Spn8FLxb2'] = False # (kN); Blade 2 local flapwise shear force at span station 8; Directed along the local xb2-axis -ElastoDyn['Spn8FLyb2'] = False # (kN); Blade 2 local edgewise shear force at span station 8; Directed along the local yb2-axis -ElastoDyn['Spn8FLzb2'] = False # (kN); Blade 2 local axial force at span station 8; Directed along the local zb2-axis -ElastoDyn['Spn9FLxb2'] = False # (kN); Blade 2 local flapwise shear force at span station 9; Directed along the local xb2-axis -ElastoDyn['Spn9FLyb2'] = False # (kN); Blade 2 local edgewise shear force at span station 9; Directed along the local yb2-axis -ElastoDyn['Spn9FLzb2'] = False # (kN); Blade 2 local axial force at span station 9; Directed along the local zb2-axis - -# Blade 3 Local Span Loads -ElastoDyn['Spn1MLxb3'] = False # (kN-m); Blade 3 local edgewise moment at span station 1; About the local xb3-axis -ElastoDyn['Spn1MLyb3'] = False # (kN-m); Blade 3 local flapwise moment at span station 1; About the local yb3-axis -ElastoDyn['Spn1MLzb3'] = False # (kN-m); Blade 3 local pitching moment at span station 1; About the local zb3-axis -ElastoDyn['Spn2MLxb3'] = False # (kN-m); Blade 3 local edgewise moment at span station 2; About the local xb3-axis -ElastoDyn['Spn2MLyb3'] = False # (kN-m); Blade 3 local flapwise moment at span station 2; About the local yb3-axis -ElastoDyn['Spn2MLzb3'] = False # (kN-m); Blade 3 local pitching moment at span station 2; About the local zb3-axis -ElastoDyn['Spn3MLxb3'] = False # (kN-m); Blade 3 local edgewise moment at span station 3; About the local xb3-axis -ElastoDyn['Spn3MLyb3'] = False # (kN-m); Blade 3 local flapwise moment at span station 3; About the local yb3-axis -ElastoDyn['Spn3MLzb3'] = False # (kN-m); Blade 3 local pitching moment at span station 3; About the local zb3-axis -ElastoDyn['Spn4MLxb3'] = False # (kN-m); Blade 3 local edgewise moment at span station 4; About the local xb3-axis -ElastoDyn['Spn4MLyb3'] = False # (kN-m); Blade 3 local flapwise moment at span station 4; About the local yb3-axis -ElastoDyn['Spn4MLzb3'] = False # (kN-m); Blade 3 local pitching moment at span station 4; About the local zb3-axis -ElastoDyn['Spn5MLxb3'] = False # (kN-m); Blade 3 local edgewise moment at span station 5; About the local xb3-axis -ElastoDyn['Spn5MLyb3'] = False # (kN-m); Blade 3 local flapwise moment at span station 5; About the local yb3-axis -ElastoDyn['Spn5MLzb3'] = False # (kN-m); Blade 3 local pitching moment at span station 5; About the local zb3-axis -ElastoDyn['Spn6MLxb3'] = False # (kN-m); Blade 3 local edgewise moment at span station 6; About the local xb3-axis -ElastoDyn['Spn6MLyb3'] = False # (kN-m); Blade 3 local flapwise moment at span station 6; About the local yb3-axis -ElastoDyn['Spn6MLzb3'] = False # (kN-m); Blade 3 local pitching moment at span station 6; About the local zb3-axis -ElastoDyn['Spn7MLxb3'] = False # (kN-m); Blade 3 local edgewise moment at span station 7; About the local xb3-axis -ElastoDyn['Spn7MLyb3'] = False # (kN-m); Blade 3 local flapwise moment at span station 7; About the local yb3-axis -ElastoDyn['Spn7MLzb3'] = False # (kN-m); Blade 3 local pitching moment at span station 7; About the local zb3-axis -ElastoDyn['Spn8MLxb3'] = False # (kN-m); Blade 3 local edgewise moment at span station 8; About the local xb3-axis -ElastoDyn['Spn8MLyb3'] = False # (kN-m); Blade 3 local flapwise moment at span station 8; About the local yb3-axis -ElastoDyn['Spn8MLzb3'] = False # (kN-m); Blade 3 local pitching moment at span station 8; About the local zb3-axis -ElastoDyn['Spn9MLxb3'] = False # (kN-m); Blade 3 local edgewise moment at span station 9; About the local xb3-axis -ElastoDyn['Spn9MLyb3'] = False # (kN-m); Blade 3 local flapwise moment at span station 9; About the local yb3-axis -ElastoDyn['Spn9MLzb3'] = False # (kN-m); Blade 3 local pitching moment at span station 9; About the local zb3-axis -ElastoDyn['Spn1FLxb3'] = False # (kN); Blade 3 local flapwise shear force at span station 1; Directed along the local xb3-axis -ElastoDyn['Spn1FLyb3'] = False # (kN); Blade 3 local edgewise shear force at span station 1; Directed along the local yb3-axis -ElastoDyn['Spn1FLzb3'] = False # (kN); Blade 3 local axial force at span station 1; Directed along the local zb3-axis -ElastoDyn['Spn2FLxb3'] = False # (kN); Blade 3 local flapwise shear force at span station 2; Directed along the local xb3-axis -ElastoDyn['Spn2FLyb3'] = False # (kN); Blade 3 local edgewise shear force at span station 2; Directed along the local yb3-axis -ElastoDyn['Spn2FLzb3'] = False # (kN); Blade 3 local axial force at span station 2; Directed along the local zb3-axis -ElastoDyn['Spn3FLxb3'] = False # (kN); Blade 3 local flapwise shear force at span station 3; Directed along the local xb3-axis -ElastoDyn['Spn3FLyb3'] = False # (kN); Blade 3 local edgewise shear force at span station 3; Directed along the local yb3-axis -ElastoDyn['Spn3FLzb3'] = False # (kN); Blade 3 local axial force at span station 3; Directed along the local zb3-axis -ElastoDyn['Spn4FLxb3'] = False # (kN); Blade 3 local flapwise shear force at span station 4; Directed along the local xb3-axis -ElastoDyn['Spn4FLyb3'] = False # (kN); Blade 3 local edgewise shear force at span station 4; Directed along the local yb3-axis -ElastoDyn['Spn4FLzb3'] = False # (kN); Blade 3 local axial force at span station 4; Directed along the local zb3-axis -ElastoDyn['Spn5FLxb3'] = False # (kN); Blade 3 local flapwise shear force at span station 5; Directed along the local xb3-axis -ElastoDyn['Spn5FLyb3'] = False # (kN); Blade 3 local edgewise shear force at span station 5; Directed along the local yb3-axis -ElastoDyn['Spn5FLzb3'] = False # (kN); Blade 3 local axial force at span station 5; Directed along the local zb3-axis -ElastoDyn['Spn6FLxb3'] = False # (kN); Blade 3 local flapwise shear force at span station 6; Directed along the local xb3-axis -ElastoDyn['Spn6FLyb3'] = False # (kN); Blade 3 local edgewise shear force at span station 6; Directed along the local yb3-axis -ElastoDyn['Spn6FLzb3'] = False # (kN); Blade 3 local axial force at span station 6; Directed along the local zb3-axis -ElastoDyn['Spn7FLxb3'] = False # (kN); Blade 3 local flapwise shear force at span station 7; Directed along the local xb3-axis -ElastoDyn['Spn7FLyb3'] = False # (kN); Blade 3 local edgewise shear force at span station 7; Directed along the local yb3-axis -ElastoDyn['Spn7FLzb3'] = False # (kN); Blade 3 local axial force at span station 7; Directed along the local zb3-axis -ElastoDyn['Spn8FLxb3'] = False # (kN); Blade 3 local flapwise shear force at span station 8; Directed along the local xb3-axis -ElastoDyn['Spn8FLyb3'] = False # (kN); Blade 3 local edgewise shear force at span station 8; Directed along the local yb3-axis -ElastoDyn['Spn8FLzb3'] = False # (kN); Blade 3 local axial force at span station 8; Directed along the local zb3-axis -ElastoDyn['Spn9FLxb3'] = False # (kN); Blade 3 local flapwise shear force at span station 9; Directed along the local xb3-axis -ElastoDyn['Spn9FLyb3'] = False # (kN); Blade 3 local edgewise shear force at span station 9; Directed along the local yb3-axis -ElastoDyn['Spn9FLzb3'] = False # (kN); Blade 3 local axial force at span station 9; Directed along the local zb3-axis - -# Hub and Rotor Loads -ElastoDyn['LSShftFxa'] = False # (kN); Low-speed shaft thrust force (this is constant along the shaft and is equivalent to the rotor thrust force); Directed along the xa- and xs-axes -ElastoDyn['LSShftFxs'] = False # (kN); Low-speed shaft thrust force (this is constant along the shaft and is equivalent to the rotor thrust force); Directed along the xa- and xs-axes -ElastoDyn['LSSGagFxa'] = False # (kN); Low-speed shaft thrust force (this is constant along the shaft and is equivalent to the rotor thrust force); Directed along the xa- and xs-axes -ElastoDyn['LSSGagFxs'] = False # (kN); Low-speed shaft thrust force (this is constant along the shaft and is equivalent to the rotor thrust force); Directed along the xa- and xs-axes -ElastoDyn['RotThrust'] = False # (kN); Low-speed shaft thrust force (this is constant along the shaft and is equivalent to the rotor thrust force); Directed along the xa- and xs-axes -ElastoDyn['LSShftFya'] = False # (kN); Rotating low-speed shaft shear force (this is constant along the shaft); Directed along the ya-axis -ElastoDyn['LSSGagFya'] = False # (kN); Rotating low-speed shaft shear force (this is constant along the shaft); Directed along the ya-axis -ElastoDyn['LSShftFza'] = False # (kN); Rotating low-speed shaft shear force (this is constant along the shaft); Directed along the za-axis -ElastoDyn['LSSGagFza'] = False # (kN); Rotating low-speed shaft shear force (this is constant along the shaft); Directed along the za-axis -ElastoDyn['LSShftFys'] = True # (kN); Nonrotating low-speed shaft shear force (this is constant along the shaft); Directed along the ys-axis -ElastoDyn['LSSGagFys'] = False # (kN); Nonrotating low-speed shaft shear force (this is constant along the shaft); Directed along the ys-axis -ElastoDyn['LSShftFzs'] = True # (kN); Nonrotating low-speed shaft shear force (this is constant along the shaft); Directed along the zs-axis -ElastoDyn['LSSGagFzs'] = False # (kN); Nonrotating low-speed shaft shear force (this is constant along the shaft); Directed along the zs-axis -ElastoDyn['LSShftMxa'] = False # (kN-m); Low-speed shaft torque (this is constant along the shaft and is equivalent to the rotor torque); About the xa- and xs-axes -ElastoDyn['LSShftMxs'] = False # (kN-m); Low-speed shaft torque (this is constant along the shaft and is equivalent to the rotor torque); About the xa- and xs-axes -ElastoDyn['LSSGagMxa'] = False # (kN-m); Low-speed shaft torque (this is constant along the shaft and is equivalent to the rotor torque); About the xa- and xs-axes -ElastoDyn['LSSGagMxs'] = False # (kN-m); Low-speed shaft torque (this is constant along the shaft and is equivalent to the rotor torque); About the xa- and xs-axes -ElastoDyn['RotTorq'] = False # (kN-m); Low-speed shaft torque (this is constant along the shaft and is equivalent to the rotor torque); About the xa- and xs-axes -ElastoDyn['LSShftTq'] = False # (kN-m); Low-speed shaft torque (this is constant along the shaft and is equivalent to the rotor torque); About the xa- and xs-axes -ElastoDyn['LSSTipMya'] = False # (kN-m); Rotating low-speed shaft bending moment at the shaft tip (teeter pin for 2-blader, apex of rotation for 3-blader); About the ya-axis -ElastoDyn['LSSTipMza'] = False # (kN-m); Rotating low-speed shaft bending moment at the shaft tip (teeter pin for 2-blader, apex of rotation for 3-blader); About the za-axis -ElastoDyn['LSSTipMys'] = True # (kN-m); Nonrotating low-speed shaft bending moment at the shaft tip (teeter pin for 2-blader, apex of rotation for 3-blader); About the ys-axis -ElastoDyn['LSSTipMzs'] = True # (kN-m); Nonrotating low-speed shaft bending moment at the shaft tip (teeter pin for 2-blader, apex of rotation for 3-blader); About the zs-axis -ElastoDyn['RotPwr'] = False # (kW); Rotor power (this is equivalent to the low-speed shaft power); N/A -ElastoDyn['LSShftPwr'] = False # (kW); Rotor power (this is equivalent to the low-speed shaft power); N/A - -# Shaft Strain Gage Loads -ElastoDyn['LSSGagMya'] = False # (kN-m); Rotating low-speed shaft bending moment at the shaft's strain gage (shaft strain gage located by input ShftGagL); About the ya-axis -ElastoDyn['LSSGagMza'] = False # (kN-m); Rotating low-speed shaft bending moment at the shaft's strain gage (shaft strain gage located by input ShftGagL); About the za-axis -ElastoDyn['LSSGagMys'] = False # (kN-m); Nonrotating low-speed shaft bending moment at the shaft's strain gage (shaft strain gage located by input ShftGagL); About the ys-axis -ElastoDyn['LSSGagMzs'] = False # (kN-m); Nonrotating low-speed shaft bending moment at the shaft's strain gage (shaft strain gage located by input ShftGagL); About the zs-axis - -# High-Speed Shaft Loads -ElastoDyn['HSShftTq'] = False # (kN-m); High-speed shaft torque (this is constant along the shaft); Same sign as LSShftTq / RotTorq / LSShftMxa / LSShftMxs / LSSGagMxa / LSSGagMxs -ElastoDyn['HSSBrTq'] = False # (kN-m); High-speed shaft brake torque (i.e., the actual moment applied to the high-speed shaft by the brake); Always positive (indicating dissipation of power) -ElastoDyn['HSShftPwr'] = False # (kW); High-speed shaft power; Same sign as HSShftTq - -# Rotor-Furl Bearing Loads -ElastoDyn['RFrlBrM'] = False # (kN-m); Rotor-furl bearing moment; About the rotor-furl axis - -# Tail-Furl Bearing Loads -ElastoDyn['TFrlBrM'] = False # (kN-m); Tail-furl bearing moment; About the tail-furl axis - -# Tower-Top / Yaw Bearing Loads -ElastoDyn['YawBrFxn'] = False # (kN); Rotating (with nacelle) tower-top / yaw bearing shear force; Directed along the xn-axis -ElastoDyn['YawBrFyn'] = False # (kN); Rotating (with nacelle) tower-top / yaw bearing shear force; Directed along the yn-axis -ElastoDyn['YawBrFzn'] = False # (kN); Tower-top / yaw bearing axial force; Directed along the zn- and zp-axes -ElastoDyn['YawBrFzp'] = False # (kN); Tower-top / yaw bearing axial force; Directed along the zn- and zp-axes -ElastoDyn['YawBrFxp'] = False # (kN); Tower-top / yaw bearing fore-aft (nonrotating) shear force; Directed along the xp-axis -ElastoDyn['YawBrFyp'] = False # (kN); Tower-top / yaw bearing side-to-side (nonrotating) shear force; Directed along the yp-axis -ElastoDyn['YawBrMxn'] = False # (kN-m); Rotating (with nacelle) tower-top / yaw bearing roll moment; About the xn-axis -ElastoDyn['YawBrMyn'] = False # (kN-m); Rotating (with nacelle) tower-top / yaw bearing pitch moment; About the yn-axis -ElastoDyn['YawBrMzn'] = False # (kN-m); Tower-top / yaw bearing yaw moment; About the zn- and zp-axes -ElastoDyn['YawBrMzp'] = False # (kN-m); Tower-top / yaw bearing yaw moment; About the zn- and zp-axes -ElastoDyn['YawBrMxp'] = False # (kN-m); Nonrotating tower-top / yaw bearing roll moment; About the xp-axis -ElastoDyn['YawBrMyp'] = False # (kN-m); Nonrotating tower-top / yaw bearing pitch moment; About the yp-axis - -# Tower Base Loads -ElastoDyn['TwrBsFxt'] = False # (kN); Tower base fore-aft shear force; Directed along the xt-axis -ElastoDyn['TwrBsFyt'] = False # (kN); Tower base side-to-side shear force; Directed along the yt-axis -ElastoDyn['TwrBsFzt'] = False # (kN); Tower base axial force; Directed along the zt-axis -ElastoDyn['TwrBsMxt'] = False # (kN-m); Tower base roll (or side-to-side) moment (i.e., the moment caused by side-to-side forces); About the xt-axis -ElastoDyn['TwrBsMyt'] = True # (kN-m); Tower base pitching (or fore-aft) moment (i.e., the moment caused by fore-aft forces); About the yt-axis -ElastoDyn['TwrBsMzt'] = False # (kN-m); Tower base yaw (or torsional) moment; About the zt-axis - -# Local Tower Loads -ElastoDyn['TwHt1MLxt'] = False # (kN-m); Local tower roll (or side-to-side) moment of tower gage 1; About the local xt-axis -ElastoDyn['TwHt1MLyt'] = False # (kN-m); Local tower pitching (or fore-aft) moment of tower gage 1; About the local yt-axis -ElastoDyn['TwHt1MLzt'] = False # (kN-m); Local tower yaw (or torsional) moment of tower gage 1; About the local zt-axis -ElastoDyn['TwHt2MLxt'] = False # (kN-m); Local tower roll (or side-to-side) moment of tower gage 2; About the local xt-axis -ElastoDyn['TwHt2MLyt'] = False # (kN-m); Local tower pitching (or fore-aft) moment of tower gage 2; About the local yt-axis -ElastoDyn['TwHt2MLzt'] = False # (kN-m); Local tower yaw (or torsional) moment of tower gage 2; About the local zt-axis -ElastoDyn['TwHt3MLxt'] = False # (kN-m); Local tower roll (or side-to-side) moment of tower gage 3; About the local xt-axis -ElastoDyn['TwHt3MLyt'] = False # (kN-m); Local tower pitching (or fore-aft) moment of tower gage 3; About the local yt-axis -ElastoDyn['TwHt3MLzt'] = False # (kN-m); Local tower yaw (or torsional) moment of tower gage 3; About the local zt-axis -ElastoDyn['TwHt4MLxt'] = False # (kN-m); Local tower roll (or side-to-side) moment of tower gage 4; About the local xt-axis -ElastoDyn['TwHt4MLyt'] = False # (kN-m); Local tower pitching (or fore-aft) moment of tower gage 4; About the local yt-axis -ElastoDyn['TwHt4MLzt'] = False # (kN-m); Local tower yaw (or torsional) moment of tower gage 4; About the local zt-axis -ElastoDyn['TwHt5MLxt'] = False # (kN-m); Local tower roll (or side-to-side) moment of tower gage 5; About the local xt-axis -ElastoDyn['TwHt5MLyt'] = False # (kN-m); Local tower pitching (or fore-aft) moment of tower gage 5; About the local yt-axis -ElastoDyn['TwHt5MLzt'] = False # (kN-m); Local tower yaw (or torsional) moment of tower gage 5; About the local zt-axis -ElastoDyn['TwHt6MLxt'] = False # (kN-m); Local tower roll (or side-to-side) moment of tower gage 6; About the local xt-axis -ElastoDyn['TwHt6MLyt'] = False # (kN-m); Local tower pitching (or fore-aft) moment of tower gage 6; About the local yt-axis -ElastoDyn['TwHt6MLzt'] = False # (kN-m); Local tower yaw (or torsional) moment of tower gage 6; About the local zt-axis -ElastoDyn['TwHt7MLxt'] = False # (kN-m); Local tower roll (or side-to-side) moment of tower gage 7; About the local xt-axis -ElastoDyn['TwHt7MLyt'] = False # (kN-m); Local tower pitching (or fore-aft) moment of tower gage 7; About the local yt-axis -ElastoDyn['TwHt7MLzt'] = False # (kN-m); Local tower yaw (or torsional) moment of tower gage 7; About the local zt-axis -ElastoDyn['TwHt8MLxt'] = False # (kN-m); Local tower roll (or side-to-side) moment of tower gage 8; About the local xt-axis -ElastoDyn['TwHt8MLyt'] = False # (kN-m); Local tower pitching (or fore-aft) moment of tower gage 8; About the local yt-axis -ElastoDyn['TwHt8MLzt'] = False # (kN-m); Local tower yaw (or torsional) moment of tower gage 8; About the local zt-axis -ElastoDyn['TwHt9MLxt'] = False # (kN-m); Local tower roll (or side-to-side) moment of tower gage 9; About the local xt-axis -ElastoDyn['TwHt9MLyt'] = False # (kN-m); Local tower pitching (or fore-aft) moment of tower gage 9; About the local yt-axis -ElastoDyn['TwHt9MLzt'] = False # (kN-m); Local tower yaw (or torsional) moment of tower gage 9; About the local zt-axis -ElastoDyn['TwHt1FLxt'] = False # (kN); Local tower roll (or side-to-side) force of tower gage 1; About the local xt-axis -ElastoDyn['TwHt1FLyt'] = False # (kN); Local tower pitching (or fore-aft) force of tower gage 1; About the local yt-axis -ElastoDyn['TwHt1FLzt'] = False # (kN); Local tower yaw (or torsional) force of tower gage 1; About the local zt-axis -ElastoDyn['TwHt2FLxt'] = False # (kN); Local tower roll (or side-to-side) force of tower gage 2; About the local xt-axis -ElastoDyn['TwHt2FLyt'] = False # (kN); Local tower pitching (or fore-aft) force of tower gage 2; About the local yt-axis -ElastoDyn['TwHt2FLzt'] = False # (kN); Local tower yaw (or torsional) force of tower gage 2; About the local zt-axis -ElastoDyn['TwHt3FLxt'] = False # (kN); Local tower roll (or side-to-side) force of tower gage 3; About the local xt-axis -ElastoDyn['TwHt3FLyt'] = False # (kN); Local tower pitching (or fore-aft) force of tower gage 3; About the local yt-axis -ElastoDyn['TwHt3FLzt'] = False # (kN); Local tower yaw (or torsional) force of tower gage 3; About the local zt-axis -ElastoDyn['TwHt4FLxt'] = False # (kN); Local tower roll (or side-to-side) force of tower gage 4; About the local xt-axis -ElastoDyn['TwHt4FLyt'] = False # (kN); Local tower pitching (or fore-aft) force of tower gage 4; About the local yt-axis -ElastoDyn['TwHt4FLzt'] = False # (kN); Local tower yaw (or torsional) force of tower gage 4; About the local zt-axis -ElastoDyn['TwHt5FLxt'] = False # (kN); Local tower roll (or side-to-side) force of tower gage 5; About the local xt-axis -ElastoDyn['TwHt5FLyt'] = False # (kN); Local tower pitching (or fore-aft) force of tower gage 5; About the local yt-axis -ElastoDyn['TwHt5FLzt'] = False # (kN); Local tower yaw (or torsional) force of tower gage 5; About the local zt-axis -ElastoDyn['TwHt6FLxt'] = False # (kN); Local tower roll (or side-to-side) force of tower gage 6; About the local xt-axis -ElastoDyn['TwHt6FLyt'] = False # (kN); Local tower pitching (or fore-aft) force of tower gage 6; About the local yt-axis -ElastoDyn['TwHt6FLzt'] = False # (kN); Local tower yaw (or torsional) force of tower gage 6; About the local zt-axis -ElastoDyn['TwHt7FLxt'] = False # (kN); Local tower roll (or side-to-side) force of tower gage 7; About the local xt-axis -ElastoDyn['TwHt7FLyt'] = False # (kN); Local tower pitching (or fore-aft) force of tower gage 7; About the local yt-axis -ElastoDyn['TwHt7FLzt'] = False # (kN); Local tower yaw (or torsional) force of tower gage 7; About the local zt-axis -ElastoDyn['TwHt8FLxt'] = False # (kN); Local tower roll (or side-to-side) force of tower gage 8; About the local xt-axis -ElastoDyn['TwHt8FLyt'] = False # (kN); Local tower pitching (or fore-aft) force of tower gage 8; About the local yt-axis -ElastoDyn['TwHt8FLzt'] = False # (kN); Local tower yaw (or torsional) force of tower gage 8; About the local zt-axis -ElastoDyn['TwHt9FLxt'] = False # (kN); Local tower roll (or side-to-side) force of tower gage 9; About the local xt-axis -ElastoDyn['TwHt9FLyt'] = False # (kN); Local tower pitching (or fore-aft) force of tower gage 9; About the local yt-axis -ElastoDyn['TwHt9FLzt'] = False # (kN); Local tower yaw (or torsional) force of tower gage 9; About the local zt-axis - -# Internal Degrees of Freedom -ElastoDyn['Q_B1E1'] = False # (m); Displacement of 1st edgewise bending-mode DOF of blade 1; -ElastoDyn['Q_B2E1'] = False # (m); Displacement of 1st edgewise bending-mode DOF of blade 2; -ElastoDyn['Q_B3E1'] = False # (m); Displacement of 1st edgewise bending-mode DOF of blade 3; -ElastoDyn['Q_B1F1'] = False # (m); Displacement of 1st flapwise bending-mode DOF of blade 1; -ElastoDyn['Q_B2F1'] = False # (m); Displacement of 1st flapwise bending-mode DOF of blade 2; -ElastoDyn['Q_B3F1'] = False # (m); Displacement of 1st flapwise bending-mode DOF of blade 3; -ElastoDyn['Q_B1F2'] = False # (m); Displacement of 2nd flapwise bending-mode DOF of blade 1; -ElastoDyn['Q_B2F2'] = False # (m); Displacement of 2nd flapwise bending-mode DOF of blade 2; -ElastoDyn['Q_B3F2'] = False # (m); Displacement of 2nd flapwise bending-mode DOF of blade 3; -ElastoDyn['Q_Teet'] = False # (rad); Displacement of hub teetering DOF; -ElastoDyn['Q_DrTr'] = False # (rad); Displacement of drivetrain rotational-flexibility DOF; -ElastoDyn['Q_GeAz'] = False # (rad); Displacement of variable speed generator DOF; -ElastoDyn['Q_RFrl'] = False # (rad); Displacement of rotor-furl DOF; -ElastoDyn['Q_TFrl'] = False # (rad); Displacement of tail-furl DOF; -ElastoDyn['Q_Yaw'] = False # (rad); Displacement of nacelle yaw DOF; -ElastoDyn['Q_TFA1'] = False # (m); Displacement of 1st tower fore-aft bending mode DOF; -ElastoDyn['Q_TSS1'] = False # (m); Displacement of 1st tower side-to-side bending mode DOF; -ElastoDyn['Q_TFA2'] = False # (m); Displacement of 2nd tower fore-aft bending mode DOF; -ElastoDyn['Q_TSS2'] = False # (m); Displacement of 2nd tower side-to-side bending mode DOF; -ElastoDyn['Q_Sg'] = False # (m); Displacement of platform horizontal surge translation DOF; -ElastoDyn['Q_Sw'] = False # (m); Displacement of platform horizontal sway translation DOF; -ElastoDyn['Q_Hv'] = False # (m); Displacement of platform vertical heave translation DOF; -ElastoDyn['Q_R'] = False # (rad); Displacement of platform roll tilt rotation DOF; -ElastoDyn['Q_P'] = False # (rad); Displacement of platform pitch tilt rotation DOF; -ElastoDyn['Q_Y'] = False # (rad); Displacement of platform yaw rotation DOF; -ElastoDyn['QD_B1E1'] = False # (m/s); Velocity of 1st edgewise bending-mode DOF of blade 1; -ElastoDyn['QD_B2E1'] = False # (m/s); Velocity of 1st edgewise bending-mode DOF of blade 2; -ElastoDyn['QD_B3E1'] = False # (m/s); Velocity of 1st edgewise bending-mode DOF of blade 3; -ElastoDyn['QD_B1F1'] = False # (m/s); Velocity of 1st flapwise bending-mode DOF of blade 1; -ElastoDyn['QD_B2F1'] = False # (m/s); Velocity of 1st flapwise bending-mode DOF of blade 2; -ElastoDyn['QD_B3F1'] = False # (m/s); Velocity of 1st flapwise bending-mode DOF of blade 3; -ElastoDyn['QD_B1F2'] = False # (m/s); Velocity of 2nd flapwise bending-mode DOF of blade 1; -ElastoDyn['QD_B2F2'] = False # (m/s); Velocity of 2nd flapwise bending-mode DOF of blade 2; -ElastoDyn['QD_B3F2'] = False # (m/s); Velocity of 2nd flapwise bending-mode DOF of blade 3; -ElastoDyn['QD_Teet'] = False # (rad/s); Velocity of hub teetering DOF; -ElastoDyn['QD_DrTr'] = False # (rad/s); Velocity of drivetrain rotational-flexibility DOF; -ElastoDyn['QD_GeAz'] = False # (rad/s); Velocity of variable speed generator DOF; -ElastoDyn['QD_RFrl'] = False # (rad/s); Velocity of rotor-furl DOF; -ElastoDyn['QD_TFrl'] = False # (rad/s); Velocity of tail-furl DOF; -ElastoDyn['QD_Yaw'] = False # (rad/s); Velocity of nacelle yaw DOF; -ElastoDyn['QD_TFA1'] = False # (m/s); Velocity of 1st tower fore-aft bending mode DOF; -ElastoDyn['QD_TSS1'] = False # (m/s); Velocity of 1st tower side-to-side bending mode DOF; -ElastoDyn['QD_TFA2'] = False # (m/s); Velocity of 2nd tower fore-aft bending mode DOF; -ElastoDyn['QD_TSS2'] = False # (m/s); Velocity of 2nd tower side-to-side bending mode DOF; -ElastoDyn['QD_Sg'] = False # (m/s); Velocity of platform horizontal surge translation DOF; -ElastoDyn['QD_Sw'] = False # (m/s); Velocity of platform horizontal sway translation DOF; -ElastoDyn['QD_Hv'] = False # (m/s); Velocity of platform vertical heave translation DOF; -ElastoDyn['QD_R'] = False # (rad/s); Velocity of platform roll tilt rotation DOF; -ElastoDyn['QD_P'] = False # (rad/s); Velocity of platform pitch tilt rotation DOF; -ElastoDyn['QD_Y'] = False # (rad/s); Velocity of platform yaw rotation DOF; -ElastoDyn['QD2_B1E1'] = False # (m/s^2); Acceleration of 1st edgewise bending-mode DOF of blade 1; -ElastoDyn['QD2_B2E1'] = False # (m/s^2); Acceleration of 1st edgewise bending-mode DOF of blade 2; -ElastoDyn['QD2_B3E1'] = False # (m/s^2); Acceleration of 1st edgewise bending-mode DOF of blade 3; -ElastoDyn['QD2_B1F1'] = False # (m/s^2); Acceleration of 1st flapwise bending-mode DOF of blade 1; -ElastoDyn['QD2_B2F1'] = False # (m/s^2); Acceleration of 1st flapwise bending-mode DOF of blade 2; -ElastoDyn['QD2_B3F1'] = False # (m/s^2); Acceleration of 1st flapwise bending-mode DOF of blade 3; -ElastoDyn['QD2_B1F2'] = False # (m/s^2); Acceleration of 2nd flapwise bending-mode DOF of blade 1; -ElastoDyn['QD2_B2F2'] = False # (m/s^2); Acceleration of 2nd flapwise bending-mode DOF of blade 2; -ElastoDyn['QD2_B3F2'] = False # (m/s^2); Acceleration of 2nd flapwise bending-mode DOF of blade 3; -ElastoDyn['QD2_Teet'] = False # (rad/s^2); Acceleration of hub teetering DOF; -ElastoDyn['QD2_DrTr'] = False # (rad/s^2); Acceleration of drivetrain rotational-flexibility DOF; -ElastoDyn['QD2_GeAz'] = False # (rad/s^2); Acceleration of variable speed generator DOF; -ElastoDyn['QD2_RFrl'] = False # (rad/s^2); Acceleration of rotor-furl DOF; -ElastoDyn['QD2_TFrl'] = False # (rad/s^2); Acceleration of tail-furl DOF; -ElastoDyn['QD2_Yaw'] = False # (rad/s^2); Acceleration of nacelle yaw DOF; -ElastoDyn['QD2_TFA1'] = False # (m/s^2); Acceleration of 1st tower fore-aft bending mode DOF; -ElastoDyn['QD2_TSS1'] = False # (m/s^2); Acceleration of 1st tower side-to-side bending mode DOF; -ElastoDyn['QD2_TFA2'] = False # (m/s^2); Acceleration of 2nd tower fore-aft bending mode DOF; -ElastoDyn['QD2_TSS2'] = False # (m/s^2); Acceleration of 2nd tower side-to-side bending mode DOF; -ElastoDyn['QD2_Sg'] = False # (m/s^2); Acceleration of platform horizontal surge translation DOF; -ElastoDyn['QD2_Sw'] = False # (m/s^2); Acceleration of platform horizontal sway translation DOF; -ElastoDyn['QD2_Hv'] = False # (m/s^2); Acceleration of platform vertical heave translation DOF; -ElastoDyn['QD2_R'] = False # (rad/s^2); Acceleration of platform roll tilt rotation DOF; -ElastoDyn['QD2_P'] = False # (rad/s^2); Acceleration of platform pitch tilt rotation DOF; -ElastoDyn['QD2_Y'] = False # (rad/s^2); Acceleration of platform yaw rotation DOF; - - -""" BeamDyn """ -BeamDyn = {} - -# Reaction Loads -BeamDyn['RootFxr'] = False # (N); x-component of the root reaction force expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system -BeamDyn['RootFyr'] = False # (N); y-component of the root reaction force expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system -BeamDyn['RootFzr'] = False # (N); z-component of the root reaction force expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system -BeamDyn['RootMxr'] = False # (N-m); x-component of the root reaction moment expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system -BeamDyn['RootMyr'] = False # (N-m); y-component of the root reaction moment expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system -BeamDyn['RootMzr'] = False # (N-m); z-component of the root reaction moment expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system - -# Tip Motions -BeamDyn['TipTDxr'] = False # (m); Tip translational deflection (relative to the undeflected position) expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system -BeamDyn['TipTDyr'] = False # (m); Tip translational deflection (relative to the undeflected position) expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system -BeamDyn['TipTDzr'] = False # (m); Tip translational deflection (relative to the undeflected position) expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system -BeamDyn['TipRDxr'] = False # (-); Tip angular/rotational deflection Wiener-Milenkovi parameter (relative to the undeflected orientation) expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system -BeamDyn['TipRDyr'] = False # (-); Tip angular/rotational deflection Wiener-Milenkovi parameter (relative to the undeflected orientation) expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system -BeamDyn['TipRDzr'] = False # (-); Tip angular/rotational deflection Wiener-Milenkovi parameter (relative to the undeflected orientation) expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system -BeamDyn['TipTVXg'] = False # (m/s); Tip translational velocities (absolute) expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system -BeamDyn['TipTVYg'] = False # (m/s); Tip translational velocities (absolute) expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system -BeamDyn['TipTVZg'] = False # (m/s); Tip translational velocities (absolute) expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system -BeamDyn['TipRVXg'] = False # (deg/s); Tip angular/rotational velocities (absolute) expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system -BeamDyn['TipRVYg'] = False # (deg/s); Tip angular/rotational velocities (absolute) expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system -BeamDyn['TipRVZg'] = False # (deg/s); Tip angular/rotational velocities (absolute) expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system -BeamDyn['TipTAXl'] = False # (m/s^2); Tip translational accelerations (absolute) expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['TipTAYl'] = False # (m/s^2); Tip translational accelerations (absolute) expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['TipTAZl'] = False # (m/s^2); Tip translational accelerations (absolute) expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['TipRAXl'] = False # (deg/s^2); Tip angular/rotational accelerations (absolute) expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['TipRAYl'] = False # (deg/s^2); Tip angular/rotational accelerations (absolute) expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['TipRAZl'] = False # (deg/s^2); Tip angular/rotational accelerations (absolute) expressed in l; l: a floating coordinate system local to the deflected beam - -# Sectional Loads -BeamDyn['N1Fxl'] = False # (N); Sectional force resultants at Node 1 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N1Fyl'] = False # (N); Sectional force resultants at Node 1 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N1Fzl'] = False # (N); Sectional force resultants at Node 1 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N2Fxl'] = False # (N); Sectional force resultants at Node 2 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N2Fyl'] = False # (N); Sectional force resultants at Node 2 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N2Fzl'] = False # (N); Sectional force resultants at Node 2 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N3Fxl'] = False # (N); Sectional force resultants at Node 3 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N3Fyl'] = False # (N); Sectional force resultants at Node 3 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N3Fzl'] = False # (N); Sectional force resultants at Node 3 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N4Fxl'] = False # (N); Sectional force resultants at Node 4 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N4Fyl'] = False # (N); Sectional force resultants at Node 4 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N4Fzl'] = False # (N); Sectional force resultants at Node 4 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N5Fxl'] = False # (N); Sectional force resultants at Node 5 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N5Fyl'] = False # (N); Sectional force resultants at Node 5 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N5Fzl'] = False # (N); Sectional force resultants at Node 5 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N6Fxl'] = False # (N); Sectional force resultants at Node 6 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N6Fyl'] = False # (N); Sectional force resultants at Node 6 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N6Fzl'] = False # (N); Sectional force resultants at Node 6 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N7Fxl'] = False # (N); Sectional force resultants at Node 7 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N7Fyl'] = False # (N); Sectional force resultants at Node 7 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N7Fzl'] = False # (N); Sectional force resultants at Node 7 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N8Fxl'] = False # (N); Sectional force resultants at Node 8 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N8Fyl'] = False # (N); Sectional force resultants at Node 8 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N8Fzl'] = False # (N); Sectional force resultants at Node 8 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N9Fxl'] = False # (N); Sectional force resultants at Node 9 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N9Fyl'] = False # (N); Sectional force resultants at Node 9 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N9Fzl'] = False # (N); Sectional force resultants at Node 9 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N1Mxl'] = False # (N-m); Sectional moment resultants at Node 1 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N1Myl'] = False # (N-m); Sectional moment resultants at Node 1 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N1Mzl'] = False # (N-m); Sectional moment resultants at Node 1 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N2Mxl'] = False # (N-m); Sectional moment resultants at Node 2 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N2Myl'] = False # (N-m); Sectional moment resultants at Node 2 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N2Mzl'] = False # (N-m); Sectional moment resultants at Node 2 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N3Mxl'] = False # (N-m); Sectional moment resultants at Node 3 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N3Myl'] = False # (N-m); Sectional moment resultants at Node 3 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N3Mzl'] = False # (N-m); Sectional moment resultants at Node 3 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N4Mxl'] = False # (N-m); Sectional moment resultants at Node 4 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N4Myl'] = False # (N-m); Sectional moment resultants at Node 4 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N4Mzl'] = False # (N-m); Sectional moment resultants at Node 4 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N5Mxl'] = False # (N-m); Sectional moment resultants at Node 5 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N5Myl'] = False # (N-m); Sectional moment resultants at Node 5 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N5Mzl'] = False # (N-m); Sectional moment resultants at Node 5 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N6Mxl'] = False # (N-m); Sectional moment resultants at Node 6 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N6Myl'] = False # (N-m); Sectional moment resultants at Node 6 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N6Mzl'] = False # (N-m); Sectional moment resultants at Node 6 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N7Mxl'] = False # (N-m); Sectional moment resultants at Node 7 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N7Myl'] = False # (N-m); Sectional moment resultants at Node 7 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N7Mzl'] = False # (N-m); Sectional moment resultants at Node 7 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N8Mxl'] = False # (N-m); Sectional moment resultants at Node 8 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N8Myl'] = False # (N-m); Sectional moment resultants at Node 8 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N8Mzl'] = False # (N-m); Sectional moment resultants at Node 8 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N9Mxl'] = False # (N-m); Sectional moment resultants at Node 9 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N9Myl'] = False # (N-m); Sectional moment resultants at Node 9 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N9Mzl'] = False # (N-m); Sectional moment resultants at Node 9 expressed in l; l: a floating coordinate system local to the deflected beam - -# Sectional Motions -BeamDyn['N1TDxr'] = False # (m); Sectional translational deflection (relative to the undeflected position) at Node 1 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system -BeamDyn['N1TDyr'] = False # (m); Sectional translational deflection (relative to the undeflected position) at Node 1 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system -BeamDyn['N1TDzr'] = False # (m); Sectional translational deflection (relative to the undeflected position) at Node 1 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system -BeamDyn['N2TDxr'] = False # (m); Sectional translational deflection (relative to the undeflected position) at Node 2 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system -BeamDyn['N2TDyr'] = False # (m); Sectional translational deflection (relative to the undeflected position) at Node 2 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system -BeamDyn['N2TDzr'] = False # (m); Sectional translational deflection (relative to the undeflected position) at Node 2 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system -BeamDyn['N3TDxr'] = False # (m); Sectional translational deflection (relative to the undeflected position) at Node 3 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system -BeamDyn['N3TDyr'] = False # (m); Sectional translational deflection (relative to the undeflected position) at Node 3 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system -BeamDyn['N3TDzr'] = False # (m); Sectional translational deflection (relative to the undeflected position) at Node 3 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system -BeamDyn['N4TDxr'] = False # (m); Sectional translational deflection (relative to the undeflected position) at Node 4 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system -BeamDyn['N4TDyr'] = False # (m); Sectional translational deflection (relative to the undeflected position) at Node 4 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system -BeamDyn['N4TDzr'] = False # (m); Sectional translational deflection (relative to the undeflected position) at Node 4 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system -BeamDyn['N5TDxr'] = False # (m); Sectional translational deflection (relative to the undeflected position) at Node 5 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system -BeamDyn['N5TDyr'] = False # (m); Sectional translational deflection (relative to the undeflected position) at Node 5 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system -BeamDyn['N5TDzr'] = False # (m); Sectional translational deflection (relative to the undeflected position) at Node 5 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system -BeamDyn['N6TDxr'] = False # (m); Sectional translational deflection (relative to the undeflected position) at Node 6 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system -BeamDyn['N6TDyr'] = False # (m); Sectional translational deflection (relative to the undeflected position) at Node 6 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system -BeamDyn['N6TDzr'] = False # (m); Sectional translational deflection (relative to the undeflected position) at Node 6 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system -BeamDyn['N7TDxr'] = False # (m); Sectional translational deflection (relative to the undeflected position) at Node 7 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system -BeamDyn['N7TDyr'] = False # (m); Sectional translational deflection (relative to the undeflected position) at Node 7 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system -BeamDyn['N7TDzr'] = False # (m); Sectional translational deflection (relative to the undeflected position) at Node 7 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system -BeamDyn['N8TDxr'] = False # (m); Sectional translational deflection (relative to the undeflected position) at Node 8 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system -BeamDyn['N8TDyr'] = False # (m); Sectional translational deflection (relative to the undeflected position) at Node 8 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system -BeamDyn['N8TDzr'] = False # (m); Sectional translational deflection (relative to the undeflected position) at Node 8 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system -BeamDyn['N9TDxr'] = False # (m); Sectional translational deflection (relative to the undeflected position) at Node 9 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system -BeamDyn['N9TDyr'] = False # (m); Sectional translational deflection (relative to the undeflected position) at Node 9 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system -BeamDyn['N9TDzr'] = False # (m); Sectional translational deflection (relative to the undeflected position) at Node 9 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system -BeamDyn['N1RDxr'] = False # (-); Sectional angular/rotational deflection Wiener-Milenkovic parameter (relative to the undeflected orientation) at Node 1 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system -BeamDyn['N1RDyr'] = False # (-); Sectional angular/rotational deflection Wiener-Milenkovic parameter (relative to the undeflected orientation) at Node 1 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system -BeamDyn['N1RDzr'] = False # (-); Sectional angular/rotational deflection Wiener-Milenkovic parameter (relative to the undeflected orientation) at Node 1 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system -BeamDyn['N2RDxr'] = False # (-); Sectional angular/rotational deflection Wiener-Milenkovic parameter (relative to the undeflected orientation) at Node 2 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system -BeamDyn['N2RDyr'] = False # (-); Sectional angular/rotational deflection Wiener-Milenkovic parameter (relative to the undeflected orientation) at Node 2 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system -BeamDyn['N2RDzr'] = False # (-); Sectional angular/rotational deflection Wiener-Milenkovic parameter (relative to the undeflected orientation) at Node 2 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system -BeamDyn['N3RDxr'] = False # (-); Sectional angular/rotational deflection Wiener-Milenkovic parameter (relative to the undeflected orientation) at Node 3 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system -BeamDyn['N3RDyr'] = False # (-); Sectional angular/rotational deflection Wiener-Milenkovic parameter (relative to the undeflected orientation) at Node 3 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system -BeamDyn['N3RDzr'] = False # (-); Sectional angular/rotational deflection Wiener-Milenkovic parameter (relative to the undeflected orientation) at Node 3 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system -BeamDyn['N4RDxr'] = False # (-); Sectional angular/rotational deflection Wiener-Milenkovic parameter (relative to the undeflected orientation) at Node 4 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system -BeamDyn['N4RDyr'] = False # (-); Sectional angular/rotational deflection Wiener-Milenkovic parameter (relative to the undeflected orientation) at Node 4 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system -BeamDyn['N4RDzr'] = False # (-); Sectional angular/rotational deflection Wiener-Milenkovic parameter (relative to the undeflected orientation) at Node 4 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system -BeamDyn['N5RDxr'] = False # (-); Sectional angular/rotational deflection Wiener-Milenkovic parameter (relative to the undeflected orientation) at Node 5 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system -BeamDyn['N5RDyr'] = False # (-); Sectional angular/rotational deflection Wiener-Milenkovic parameter (relative to the undeflected orientation) at Node 5 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system -BeamDyn['N5RDzr'] = False # (-); Sectional angular/rotational deflection Wiener-Milenkovic parameter (relative to the undeflected orientation) at Node 5 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system -BeamDyn['N6RDxr'] = False # (-); Sectional angular/rotational deflection Wiener-Milenkovic parameter (relative to the undeflected orientation) at Node 6 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system -BeamDyn['N6RDyr'] = False # (-); Sectional angular/rotational deflection Wiener-Milenkovic parameter (relative to the undeflected orientation) at Node 6 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system -BeamDyn['N6RDzr'] = False # (-); Sectional angular/rotational deflection Wiener-Milenkovic parameter (relative to the undeflected orientation) at Node 6 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system -BeamDyn['N7RDxr'] = False # (-); Sectional angular/rotational deflection Wiener-Milenkovic parameter (relative to the undeflected orientation) at Node 7 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system -BeamDyn['N7RDyr'] = False # (-); Sectional angular/rotational deflection Wiener-Milenkovic parameter (relative to the undeflected orientation) at Node 7 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system -BeamDyn['N7RDzr'] = False # (-); Sectional angular/rotational deflection Wiener-Milenkovic parameter (relative to the undeflected orientation) at Node 7 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system -BeamDyn['N8RDxr'] = False # (-); Sectional angular/rotational deflection Wiener-Milenkovic parameter (relative to the undeflected orientation) at Node 8 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system -BeamDyn['N8RDyr'] = False # (-); Sectional angular/rotational deflection Wiener-Milenkovic parameter (relative to the undeflected orientation) at Node 8 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system -BeamDyn['N8RDzr'] = False # (-); Sectional angular/rotational deflection Wiener-Milenkovic parameter (relative to the undeflected orientation) at Node 8 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system -BeamDyn['N9RDxr'] = False # (-); Sectional angular/rotational deflection Wiener-Milenkovic parameter (relative to the undeflected orientation) at Node 9 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system -BeamDyn['N9RDyr'] = False # (-); Sectional angular/rotational deflection Wiener-Milenkovic parameter (relative to the undeflected orientation) at Node 9 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system -BeamDyn['N9RDzr'] = False # (-); Sectional angular/rotational deflection Wiener-Milenkovic parameter (relative to the undeflected orientation) at Node 9 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system -BeamDyn['N1TVXg'] = False # (m/s); Sectional translational velocities (absolute) at Node 1 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system -BeamDyn['N1TVYg'] = False # (m/s); Sectional translational velocities (absolute) at Node 1 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system -BeamDyn['N1TVZg'] = False # (m/s); Sectional translational velocities (absolute) at Node 1 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system -BeamDyn['N2TVXg'] = False # (m/s); Sectional translational velocities (absolute) at Node 2 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system -BeamDyn['N2TVYg'] = False # (m/s); Sectional translational velocities (absolute) at Node 2 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system -BeamDyn['N2TVZg'] = False # (m/s); Sectional translational velocities (absolute) at Node 2 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system -BeamDyn['N3TVXg'] = False # (m/s); Sectional translational velocities (absolute) at Node 3 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system -BeamDyn['N3TVYg'] = False # (m/s); Sectional translational velocities (absolute) at Node 3 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system -BeamDyn['N3TVZg'] = False # (m/s); Sectional translational velocities (absolute) at Node 3 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system -BeamDyn['N4TVXg'] = False # (m/s); Sectional translational velocities (absolute) at Node 4 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system -BeamDyn['N4TVYg'] = False # (m/s); Sectional translational velocities (absolute) at Node 4 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system -BeamDyn['N4TVZg'] = False # (m/s); Sectional translational velocities (absolute) at Node 4 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system -BeamDyn['N5TVXg'] = False # (m/s); Sectional translational velocities (absolute) at Node 5 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system -BeamDyn['N5TVYg'] = False # (m/s); Sectional translational velocities (absolute) at Node 5 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system -BeamDyn['N5TVZg'] = False # (m/s); Sectional translational velocities (absolute) at Node 5 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system -BeamDyn['N6TVXg'] = False # (m/s); Sectional translational velocities (absolute) at Node 6 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system -BeamDyn['N6TVYg'] = False # (m/s); Sectional translational velocities (absolute) at Node 6 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system -BeamDyn['N6TVZg'] = False # (m/s); Sectional translational velocities (absolute) at Node 6 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system -BeamDyn['N7TVXg'] = False # (m/s); Sectional translational velocities (absolute) at Node 7 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system -BeamDyn['N7TVYg'] = False # (m/s); Sectional translational velocities (absolute) at Node 7 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system -BeamDyn['N7TVZg'] = False # (m/s); Sectional translational velocities (absolute) at Node 7 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system -BeamDyn['N8TVXg'] = False # (m/s); Sectional translational velocities (absolute) at Node 8 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system -BeamDyn['N8TVYg'] = False # (m/s); Sectional translational velocities (absolute) at Node 8 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system -BeamDyn['N8TVZg'] = False # (m/s); Sectional translational velocities (absolute) at Node 8 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system -BeamDyn['N9TVXg'] = False # (m/s); Sectional translational velocities (absolute) at Node 9 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system -BeamDyn['N9TVYg'] = False # (m/s); Sectional translational velocities (absolute) at Node 9 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system -BeamDyn['N9TVZg'] = False # (m/s); Sectional translational velocities (absolute) at Node 9 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system -BeamDyn['N1RVXg'] = False # (deg/s); Sectional angular/rotational velocities (absolute) at Node 1 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system -BeamDyn['N1RVYg'] = False # (deg/s); Sectional angular/rotational velocities (absolute) at Node 1 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system -BeamDyn['N1RVZg'] = False # (deg/s); Sectional angular/rotational velocities (absolute) at Node 1 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system -BeamDyn['N2RVXg'] = False # (deg/s); Sectional angular/rotational velocities (absolute) at Node 2 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system -BeamDyn['N2RVYg'] = False # (deg/s); Sectional angular/rotational velocities (absolute) at Node 2 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system -BeamDyn['N2RVZg'] = False # (deg/s); Sectional angular/rotational velocities (absolute) at Node 2 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system -BeamDyn['N3RVXg'] = False # (deg/s); Sectional angular/rotational velocities (absolute) at Node 3 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system -BeamDyn['N3RVYg'] = False # (deg/s); Sectional angular/rotational velocities (absolute) at Node 3 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system -BeamDyn['N3RVZg'] = False # (deg/s); Sectional angular/rotational velocities (absolute) at Node 3 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system -BeamDyn['N4RVXg'] = False # (deg/s); Sectional angular/rotational velocities (absolute) at Node 4 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system -BeamDyn['N4RVYg'] = False # (deg/s); Sectional angular/rotational velocities (absolute) at Node 4 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system -BeamDyn['N4RVZg'] = False # (deg/s); Sectional angular/rotational velocities (absolute) at Node 4 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system -BeamDyn['N5RVXg'] = False # (deg/s); Sectional angular/rotational velocities (absolute) at Node 5 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system -BeamDyn['N5RVYg'] = False # (deg/s); Sectional angular/rotational velocities (absolute) at Node 5 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system -BeamDyn['N5RVZg'] = False # (deg/s); Sectional angular/rotational velocities (absolute) at Node 5 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system -BeamDyn['N6RVXg'] = False # (deg/s); Sectional angular/rotational velocities (absolute) at Node 6 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system -BeamDyn['N6RVYg'] = False # (deg/s); Sectional angular/rotational velocities (absolute) at Node 6 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system -BeamDyn['N6RVZg'] = False # (deg/s); Sectional angular/rotational velocities (absolute) at Node 6 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system -BeamDyn['N7RVXg'] = False # (deg/s); Sectional angular/rotational velocities (absolute) at Node 7 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system -BeamDyn['N7RVYg'] = False # (deg/s); Sectional angular/rotational velocities (absolute) at Node 7 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system -BeamDyn['N7RVZg'] = False # (deg/s); Sectional angular/rotational velocities (absolute) at Node 7 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system -BeamDyn['N8RVXg'] = False # (deg/s); Sectional angular/rotational velocities (absolute) at Node 8 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system -BeamDyn['N8RVYg'] = False # (deg/s); Sectional angular/rotational velocities (absolute) at Node 8 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system -BeamDyn['N8RVZg'] = False # (deg/s); Sectional angular/rotational velocities (absolute) at Node 8 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system -BeamDyn['N9RVXg'] = False # (deg/s); Sectional angular/rotational velocities (absolute) at Node 9 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system -BeamDyn['N9RVYg'] = False # (deg/s); Sectional angular/rotational velocities (absolute) at Node 9 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system -BeamDyn['N9RVZg'] = False # (deg/s); Sectional angular/rotational velocities (absolute) at Node 9 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system -BeamDyn['N1TAXl'] = False # (m/s^2); Sectional translational accelerations (absolute) at Node 1 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N1TAYl'] = False # (m/s^2); Sectional translational accelerations (absolute) at Node 1 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N1TAZl'] = False # (m/s^2); Sectional translational accelerations (absolute) at Node 1 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N2TAXl'] = False # (m/s^2); Sectional translational accelerations (absolute) at Node 2 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N2TAYl'] = False # (m/s^2); Sectional translational accelerations (absolute) at Node 2 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N2TAZl'] = False # (m/s^2); Sectional translational accelerations (absolute) at Node 2 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N3TAXl'] = False # (m/s^2); Sectional translational accelerations (absolute) at Node 3 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N3TAYl'] = False # (m/s^2); Sectional translational accelerations (absolute) at Node 3 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N3TAZl'] = False # (m/s^2); Sectional translational accelerations (absolute) at Node 3 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N4TAXl'] = False # (m/s^2); Sectional translational accelerations (absolute) at Node 4 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N4TAYl'] = False # (m/s^2); Sectional translational accelerations (absolute) at Node 4 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N4TAZl'] = False # (m/s^2); Sectional translational accelerations (absolute) at Node 4 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N5TAXl'] = False # (m/s^2); Sectional translational accelerations (absolute) at Node 5 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N5TAYl'] = False # (m/s^2); Sectional translational accelerations (absolute) at Node 5 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N5TAZl'] = False # (m/s^2); Sectional translational accelerations (absolute) at Node 5 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N6TAXl'] = False # (m/s^2); Sectional translational accelerations (absolute) at Node 6 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N6TAYl'] = False # (m/s^2); Sectional translational accelerations (absolute) at Node 6 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N6TAZl'] = False # (m/s^2); Sectional translational accelerations (absolute) at Node 6 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N7TAXl'] = False # (m/s^2); Sectional translational accelerations (absolute) at Node 7 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N7TAYl'] = False # (m/s^2); Sectional translational accelerations (absolute) at Node 7 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N7TAZl'] = False # (m/s^2); Sectional translational accelerations (absolute) at Node 7 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N8TAXl'] = False # (m/s^2); Sectional translational accelerations (absolute) at Node 8 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N8TAYl'] = False # (m/s^2); Sectional translational accelerations (absolute) at Node 8 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N8TAZl'] = False # (m/s^2); Sectional translational accelerations (absolute) at Node 8 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N9TAXl'] = False # (m/s^2); Sectional translational accelerations (absolute) at Node 9 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N9TAYl'] = False # (m/s^2); Sectional translational accelerations (absolute) at Node 9 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N9TAZl'] = False # (m/s^2); Sectional translational accelerations (absolute) at Node 9 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N1RAXl'] = False # (deg/s^2); Sectional angular/rotational accelerations (absolute) at Node 1 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N1RAYl'] = False # (deg/s^2); Sectional angular/rotational accelerations (absolute) at Node 1 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N1RAZl'] = False # (deg/s^2); Sectional angular/rotational accelerations (absolute) at Node 1 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N2RAXl'] = False # (deg/s^2); Sectional angular/rotational accelerations (absolute) at Node 2 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N2RAYl'] = False # (deg/s^2); Sectional angular/rotational accelerations (absolute) at Node 2 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N2RAZl'] = False # (deg/s^2); Sectional angular/rotational accelerations (absolute) at Node 2 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N3RAXl'] = False # (deg/s^2); Sectional angular/rotational accelerations (absolute) at Node 3 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N3RAYl'] = False # (deg/s^2); Sectional angular/rotational accelerations (absolute) at Node 3 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N3RAZl'] = False # (deg/s^2); Sectional angular/rotational accelerations (absolute) at Node 3 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N4RAXl'] = False # (deg/s^2); Sectional angular/rotational accelerations (absolute) at Node 4 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N4RAYl'] = False # (deg/s^2); Sectional angular/rotational accelerations (absolute) at Node 4 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N4RAZl'] = False # (deg/s^2); Sectional angular/rotational accelerations (absolute) at Node 4 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N5RAXl'] = False # (deg/s^2); Sectional angular/rotational accelerations (absolute) at Node 5 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N5RAYl'] = False # (deg/s^2); Sectional angular/rotational accelerations (absolute) at Node 5 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N5RAZl'] = False # (deg/s^2); Sectional angular/rotational accelerations (absolute) at Node 5 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N6RAXl'] = False # (deg/s^2); Sectional angular/rotational accelerations (absolute) at Node 6 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N6RAYl'] = False # (deg/s^2); Sectional angular/rotational accelerations (absolute) at Node 6 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N6RAZl'] = False # (deg/s^2); Sectional angular/rotational accelerations (absolute) at Node 6 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N7RAXl'] = False # (deg/s^2); Sectional angular/rotational accelerations (absolute) at Node 7 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N7RAYl'] = False # (deg/s^2); Sectional angular/rotational accelerations (absolute) at Node 7 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N7RAZl'] = False # (deg/s^2); Sectional angular/rotational accelerations (absolute) at Node 7 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N8RAXl'] = False # (deg/s^2); Sectional angular/rotational accelerations (absolute) at Node 8 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N8RAYl'] = False # (deg/s^2); Sectional angular/rotational accelerations (absolute) at Node 8 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N8RAZl'] = False # (deg/s^2); Sectional angular/rotational accelerations (absolute) at Node 8 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N9RAXl'] = False # (deg/s^2); Sectional angular/rotational accelerations (absolute) at Node 9 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N9RAYl'] = False # (deg/s^2); Sectional angular/rotational accelerations (absolute) at Node 9 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N9RAZl'] = False # (deg/s^2); Sectional angular/rotational accelerations (absolute) at Node 9 expressed in l; l: a floating coordinate system local to the deflected beam - -# Applied Loads -BeamDyn['N1PFxl'] = False # (N); Applied point forces at Node 1 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N1PFyl'] = False # (N); Applied point forces at Node 1 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N1PFzl'] = False # (N); Applied point forces at Node 1 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N2PFxl'] = False # (N); Applied point forces at Node 2 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N2PFyl'] = False # (N); Applied point forces at Node 2 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N2PFzl'] = False # (N); Applied point forces at Node 2 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N3PFxl'] = False # (N); Applied point forces at Node 3 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N3PFyl'] = False # (N); Applied point forces at Node 3 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N3PFzl'] = False # (N); Applied point forces at Node 3 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N4PFxl'] = False # (N); Applied point forces at Node 4 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N4PFyl'] = False # (N); Applied point forces at Node 4 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N4PFzl'] = False # (N); Applied point forces at Node 4 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N5PFxl'] = False # (N); Applied point forces at Node 5 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N5PFyl'] = False # (N); Applied point forces at Node 5 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N5PFzl'] = False # (N); Applied point forces at Node 5 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N6PFxl'] = False # (N); Applied point forces at Node 6 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N6PFyl'] = False # (N); Applied point forces at Node 6 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N6PFzl'] = False # (N); Applied point forces at Node 6 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N7PFxl'] = False # (N); Applied point forces at Node 7 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N7PFyl'] = False # (N); Applied point forces at Node 7 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N7PFzl'] = False # (N); Applied point forces at Node 7 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N8PFxl'] = False # (N); Applied point forces at Node 8 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N8PFyl'] = False # (N); Applied point forces at Node 8 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N8PFzl'] = False # (N); Applied point forces at Node 8 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N9PFxl'] = False # (N); Applied point forces at Node 9 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N9PFyl'] = False # (N); Applied point forces at Node 9 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N9PFzl'] = False # (N); Applied point forces at Node 9 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N1PMxl'] = False # (N-m); Applied point moments at Node 1 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N1PMyl'] = False # (N-m); Applied point moments at Node 1 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N1PMzl'] = False # (N-m); Applied point moments at Node 1 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N2PMxl'] = False # (N-m); Applied point moments at Node 2 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N2PMyl'] = False # (N-m); Applied point moments at Node 2 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N2PMzl'] = False # (N-m); Applied point moments at Node 2 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N3PMxl'] = False # (N-m); Applied point moments at Node 3 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N3PMyl'] = False # (N-m); Applied point moments at Node 3 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N3PMzl'] = False # (N-m); Applied point moments at Node 3 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N4PMxl'] = False # (N-m); Applied point moments at Node 4 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N4PMyl'] = False # (N-m); Applied point moments at Node 4 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N4PMzl'] = False # (N-m); Applied point moments at Node 4 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N5PMxl'] = False # (N-m); Applied point moments at Node 5 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N5PMyl'] = False # (N-m); Applied point moments at Node 5 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N5PMzl'] = False # (N-m); Applied point moments at Node 5 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N6PMxl'] = False # (N-m); Applied point moments at Node 6 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N6PMyl'] = False # (N-m); Applied point moments at Node 6 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N6PMzl'] = False # (N-m); Applied point moments at Node 6 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N7PMxl'] = False # (N-m); Applied point moments at Node 7 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N7PMyl'] = False # (N-m); Applied point moments at Node 7 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N7PMzl'] = False # (N-m); Applied point moments at Node 7 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N8PMxl'] = False # (N-m); Applied point moments at Node 8 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N8PMyl'] = False # (N-m); Applied point moments at Node 8 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N8PMzl'] = False # (N-m); Applied point moments at Node 8 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N9PMxl'] = False # (N-m); Applied point moments at Node 9 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N9PMyl'] = False # (N-m); Applied point moments at Node 9 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N9PMzl'] = False # (N-m); Applied point moments at Node 9 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N1DFxl'] = False # (N/m); Applied distributed forces at Node 1 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N1DFyl'] = False # (N/m); Applied distributed forces at Node 1 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N1DFzl'] = False # (N/m); Applied distributed forces at Node 1 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N2DFxl'] = False # (N/m); Applied distributed forces at Node 2 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N2DFyl'] = False # (N/m); Applied distributed forces at Node 2 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N2DFzl'] = False # (N/m); Applied distributed forces at Node 2 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N3DFxl'] = False # (N/m); Applied distributed forces at Node 3 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N3DFyl'] = False # (N/m); Applied distributed forces at Node 3 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N3DFzl'] = False # (N/m); Applied distributed forces at Node 3 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N4DFxl'] = False # (N/m); Applied distributed forces at Node 4 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N4DFyl'] = False # (N/m); Applied distributed forces at Node 4 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N4DFzl'] = False # (N/m); Applied distributed forces at Node 4 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N5DFxl'] = False # (N/m); Applied distributed forces at Node 5 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N5DFyl'] = False # (N/m); Applied distributed forces at Node 5 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N5DFzl'] = False # (N/m); Applied distributed forces at Node 5 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N6DFxl'] = False # (N/m); Applied distributed forces at Node 6 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N6DFyl'] = False # (N/m); Applied distributed forces at Node 6 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N6DFzl'] = False # (N/m); Applied distributed forces at Node 6 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N7DFxl'] = False # (N/m); Applied distributed forces at Node 7 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N7DFyl'] = False # (N/m); Applied distributed forces at Node 7 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N7DFzl'] = False # (N/m); Applied distributed forces at Node 7 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N8DFxl'] = False # (N/m); Applied distributed forces at Node 8 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N8DFyl'] = False # (N/m); Applied distributed forces at Node 8 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N8DFzl'] = False # (N/m); Applied distributed forces at Node 8 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N9DFxl'] = False # (N/m); Applied distributed forces at Node 9 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N9DFyl'] = False # (N/m); Applied distributed forces at Node 9 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N9DFzl'] = False # (N/m); Applied distributed forces at Node 9 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N1DMxl'] = False # (N-m/m); Applied distributed moments at Node 1 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N1DMyl'] = False # (N-m/m); Applied distributed moments at Node 1 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N1DMzl'] = False # (N-m/m); Applied distributed moments at Node 1 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N2DMxl'] = False # (N-m/m); Applied distributed moments at Node 2 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N2DMyl'] = False # (N-m/m); Applied distributed moments at Node 2 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N2DMzl'] = False # (N-m/m); Applied distributed moments at Node 2 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N3DMxl'] = False # (N-m/m); Applied distributed moments at Node 3 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N3DMyl'] = False # (N-m/m); Applied distributed moments at Node 3 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N3DMzl'] = False # (N-m/m); Applied distributed moments at Node 3 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N4DMxl'] = False # (N-m/m); Applied distributed moments at Node 4 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N4DMyl'] = False # (N-m/m); Applied distributed moments at Node 4 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N4DMzl'] = False # (N-m/m); Applied distributed moments at Node 4 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N5DMxl'] = False # (N-m/m); Applied distributed moments at Node 5 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N5DMyl'] = False # (N-m/m); Applied distributed moments at Node 5 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N5DMzl'] = False # (N-m/m); Applied distributed moments at Node 5 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N6DMxl'] = False # (N-m/m); Applied distributed moments at Node 6 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N6DMyl'] = False # (N-m/m); Applied distributed moments at Node 6 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N6DMzl'] = False # (N-m/m); Applied distributed moments at Node 6 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N7DMxl'] = False # (N-m/m); Applied distributed moments at Node 7 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N7DMyl'] = False # (N-m/m); Applied distributed moments at Node 7 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N7DMzl'] = False # (N-m/m); Applied distributed moments at Node 7 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N8DMxl'] = False # (N-m/m); Applied distributed moments at Node 8 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N8DMyl'] = False # (N-m/m); Applied distributed moments at Node 8 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N8DMzl'] = False # (N-m/m); Applied distributed moments at Node 8 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N9DMxl'] = False # (N-m/m); Applied distributed moments at Node 9 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N9DMyl'] = False # (N-m/m); Applied distributed moments at Node 9 expressed in l; l: a floating coordinate system local to the deflected beam -BeamDyn['N9DMzl'] = False # (N-m/m); Applied distributed moments at Node 9 expressed in l; l: a floating coordinate system local to the deflected beam - -# Pitch Actuator -BeamDyn['PAngInp'] = False # (deg); Pitch angle input; -BeamDyn['PAngAct'] = False # (deg); Actual pitch angle ; -BeamDyn['PRatAct'] = False # (deg/s); Actual pitch rate; -BeamDyn['PAccAct'] = False # (deg/s^2); Actual pitch acceleration; - - -""" ServoDyn """ -ServoDyn = {} - -# Airfoil control -ServoDyn['BlAirFlC1'] = False # (-); Blade 1 airfoil control command; Same units as provided in airfoil tables of AD15 (UserProp) -ServoDyn['BlFlap1'] = False # (-); Blade 1 airfoil control command; Same units as provided in airfoil tables of AD15 (UserProp) -ServoDyn['BlAirFlC2'] = False # (-); Blade 2 airfoil control command; Same units as provided in airfoil tables of AD15 (UserProp) -ServoDyn['BlFlap2'] = False # (-); Blade 2 airfoil control command; Same units as provided in airfoil tables of AD15 (UserProp) -ServoDyn['BlAirFlC3'] = False # (-); Blade 3 airfoil control command; Same units as provided in airfoil tables of AD15 (UserProp) -ServoDyn['BlFlap3'] = False # (-); Blade 3 airfoil control command; Same units as provided in airfoil tables of AD15 (UserProp) - -# Pitch Control -ServoDyn['BlPitchC1'] = False # (deg); Blade 1 pitch angle command; Positive towards feather about the minus zc1- and minus zb1-axes -ServoDyn['BlPitchC2'] = False # (deg); Blade 2 pitch angle command; Positive towards feather about the minus zc2- and minus zb2-axes -ServoDyn['BlPitchC3'] = False # (deg); Blade 3 pitch angle command; Positive towards feather about the minus zc3- and minus zb3-axes - -# Generator and Torque Control -ServoDyn['GenTq'] = False # (kN-m); Electrical generator torque; Positive reflects power extracted and negative represents a motoring-up situation (power input) -ServoDyn['GenPwr'] = False # (kW); Electrical generator power; Same sign as GenTq - -# High Speed Shaft Brake -ServoDyn['HSSBrTqC'] = False # (kN-m); High-speed shaft brake torque command (i.e., the commanded moment applied to the high-speed shaft by the brake); Always positive (indicating dissipation of power) - -# Nacelle Yaw Control -ServoDyn['YawMomCom'] = False # (kN-m); Nacelle yaw moment command; About the zl- and zp-axes -ServoDyn['YawMom'] = False # (kN-m); Nacelle yaw moment command; About the zl- and zp-axes - -# Nacelle Structural Control (StC) -ServoDyn['NStC1_XQ'] = False # (m); Nacelle StC #1 -- X position (displacement); Relative to rest position in StC reference frame -ServoDyn['NStC1_XQD'] = False # (m/s); Nacelle StC #1 -- X velocity; Relative to nacelle in StC reference frame -ServoDyn['NStC1_YQ'] = False # (m); Nacelle StC #1 -- Y position (displacement); Relative to rest position in StC reference frame -ServoDyn['NStC1_YQD'] = False # (m/s); Nacelle StC #1 -- Y velocity; Relative to nacelle in StC reference frame -ServoDyn['NStC1_ZQ'] = False # (m); Nacelle StC #1 -- Z position (displacement); Relative to rest position in StC reference frame -ServoDyn['NStC1_ZQD'] = False # (m/s); Nacelle StC #1 -- Z velocity; Relative to nacelle in StC reference frame -ServoDyn['NStC1_Fxi'] = False # (kN); Nacelle StC #1 -- X resulting force; Inertial (global) coordinates -ServoDyn['NStC1_Fyi'] = False # (kN); Nacelle StC #1 -- Y resulting force; Inertial (global) coordinates -ServoDyn['NStC1_Fzi'] = False # (kN); Nacelle StC #1 -- Z resulting force; Inertial (global) coordinates -ServoDyn['NStC1_Mxi'] = False # (kN-m); Nacelle StC #1 -- X resulting moment; Inertial (global) coordinates -ServoDyn['NStC1_Myi'] = False # (kN-m); Nacelle StC #1 -- Y resulting moment; Inertial (global) coordinates -ServoDyn['NStC1_Mzi'] = False # (kN-m); Nacelle StC #1 -- Z resulting moment; Inertial (global) coordinates -ServoDyn['NStC1_Fxl'] = False # (kN); Nacelle StC #1 -- X resulting force; Local StC coordinates -ServoDyn['NStC1_Fyl'] = False # (kN); Nacelle StC #1 -- Y resulting force; Local StC coordinates -ServoDyn['NStC1_Fzl'] = False # (kN); Nacelle StC #1 -- Z resulting force; Local StC coordinates -ServoDyn['NStC1_Mxl'] = False # (kN-m); Nacelle StC #1 -- X resulting moment; Local StC coordinates -ServoDyn['NStC1_Myl'] = False # (kN-m); Nacelle StC #1 -- Y resulting moment; Local StC coordinates -ServoDyn['NStC1_Mzl'] = False # (kN-m); Nacelle StC #1 -- Z resulting moment; Local StC coordinates -ServoDyn['NStC2_XQ'] = False # (m); Nacelle StC #2 -- X position (displacement); Relative to rest position in StC reference frame -ServoDyn['NStC2_XQD'] = False # (m/s); Nacelle StC #2 -- X velocity; Relative to nacelle in StC reference frame -ServoDyn['NStC2_YQ'] = False # (m); Nacelle StC #2 -- Y position (displacement); Relative to rest position in StC reference frame -ServoDyn['NStC2_YQD'] = False # (m/s); Nacelle StC #2 -- Y velocity; Relative to nacelle in StC reference frame -ServoDyn['NStC2_ZQ'] = False # (m); Nacelle StC #2 -- Z position (displacement); Relative to rest position in StC reference frame -ServoDyn['NStC2_ZQD'] = False # (m/s); Nacelle StC #2 -- Z velocity; Relative to nacelle in StC reference frame -ServoDyn['NStC2_Fxi'] = False # (kN); Nacelle StC #2 -- X resulting force; Inertial (global) coordinates -ServoDyn['NStC2_Fyi'] = False # (kN); Nacelle StC #2 -- Y resulting force; Inertial (global) coordinates -ServoDyn['NStC2_Fzi'] = False # (kN); Nacelle StC #2 -- Z resulting force; Inertial (global) coordinates -ServoDyn['NStC2_Mxi'] = False # (kN-m); Nacelle StC #2 -- X resulting moment; Inertial (global) coordinates -ServoDyn['NStC2_Myi'] = False # (kN-m); Nacelle StC #2 -- Y resulting moment; Inertial (global) coordinates -ServoDyn['NStC2_Mzi'] = False # (kN-m); Nacelle StC #2 -- Z resulting moment; Inertial (global) coordinates -ServoDyn['NStC2_Fxl'] = False # (kN); Nacelle StC #2 -- X resulting force; Local StC coordinates -ServoDyn['NStC2_Fyl'] = False # (kN); Nacelle StC #2 -- Y resulting force; Local StC coordinates -ServoDyn['NStC2_Fzl'] = False # (kN); Nacelle StC #2 -- Z resulting force; Local StC coordinates -ServoDyn['NStC2_Mxl'] = False # (kN-m); Nacelle StC #2 -- X resulting moment; Local StC coordinates -ServoDyn['NStC2_Myl'] = False # (kN-m); Nacelle StC #2 -- Y resulting moment; Local StC coordinates -ServoDyn['NStC2_Mzl'] = False # (kN-m); Nacelle StC #2 -- Z resulting moment; Local StC coordinates -ServoDyn['NStC3_XQ'] = False # (m); Nacelle StC #3 -- X position (displacement); Relative to rest position in StC reference frame -ServoDyn['NStC3_XQD'] = False # (m/s); Nacelle StC #3 -- X velocity; Relative to nacelle in StC reference frame -ServoDyn['NStC3_YQ'] = False # (m); Nacelle StC #3 -- Y position (displacement); Relative to rest position in StC reference frame -ServoDyn['NStC3_YQD'] = False # (m/s); Nacelle StC #3 -- Y velocity; Relative to nacelle in StC reference frame -ServoDyn['NStC3_ZQ'] = False # (m); Nacelle StC #3 -- Z position (displacement); Relative to rest position in StC reference frame -ServoDyn['NStC3_ZQD'] = False # (m/s); Nacelle StC #3 -- Z velocity; Relative to nacelle in StC reference frame -ServoDyn['NStC3_Fxi'] = False # (kN); Nacelle StC #3 -- X resulting force; Inertial (global) coordinates -ServoDyn['NStC3_Fyi'] = False # (kN); Nacelle StC #3 -- Y resulting force; Inertial (global) coordinates -ServoDyn['NStC3_Fzi'] = False # (kN); Nacelle StC #3 -- Z resulting force; Inertial (global) coordinates -ServoDyn['NStC3_Mxi'] = False # (kN-m); Nacelle StC #3 -- X resulting moment; Inertial (global) coordinates -ServoDyn['NStC3_Myi'] = False # (kN-m); Nacelle StC #3 -- Y resulting moment; Inertial (global) coordinates -ServoDyn['NStC3_Mzi'] = False # (kN-m); Nacelle StC #3 -- Z resulting moment; Inertial (global) coordinates -ServoDyn['NStC3_Fxl'] = False # (kN); Nacelle StC #3 -- X resulting force; Local StC coordinates -ServoDyn['NStC3_Fyl'] = False # (kN); Nacelle StC #3 -- Y resulting force; Local StC coordinates -ServoDyn['NStC3_Fzl'] = False # (kN); Nacelle StC #3 -- Z resulting force; Local StC coordinates -ServoDyn['NStC3_Mxl'] = False # (kN-m); Nacelle StC #3 -- X resulting moment; Local StC coordinates -ServoDyn['NStC3_Myl'] = False # (kN-m); Nacelle StC #3 -- Y resulting moment; Local StC coordinates -ServoDyn['NStC3_Mzl'] = False # (kN-m); Nacelle StC #3 -- Z resulting moment; Local StC coordinates -ServoDyn['NStC4_XQ'] = False # (m); Nacelle StC #4 -- X position (displacement); Relative to rest position in StC reference frame -ServoDyn['NStC4_XQD'] = False # (m/s); Nacelle StC #4 -- X velocity; Relative to nacelle in StC reference frame -ServoDyn['NStC4_YQ'] = False # (m); Nacelle StC #4 -- Y position (displacement); Relative to rest position in StC reference frame -ServoDyn['NStC4_YQD'] = False # (m/s); Nacelle StC #4 -- Y velocity; Relative to nacelle in StC reference frame -ServoDyn['NStC4_ZQ'] = False # (m); Nacelle StC #4 -- Z position (displacement); Relative to rest position in StC reference frame -ServoDyn['NStC4_ZQD'] = False # (m/s); Nacelle StC #4 -- Z velocity; Relative to nacelle in StC reference frame -ServoDyn['NStC4_Fxi'] = False # (kN); Nacelle StC #4 -- X resulting force; Inertial (global) coordinates -ServoDyn['NStC4_Fyi'] = False # (kN); Nacelle StC #4 -- Y resulting force; Inertial (global) coordinates -ServoDyn['NStC4_Fzi'] = False # (kN); Nacelle StC #4 -- Z resulting force; Inertial (global) coordinates -ServoDyn['NStC4_Mxi'] = False # (kN-m); Nacelle StC #4 -- X resulting moment; Inertial (global) coordinates -ServoDyn['NStC4_Myi'] = False # (kN-m); Nacelle StC #4 -- Y resulting moment; Inertial (global) coordinates -ServoDyn['NStC4_Mzi'] = False # (kN-m); Nacelle StC #4 -- Z resulting moment; Inertial (global) coordinates -ServoDyn['NStC4_Fxl'] = False # (kN); Nacelle StC #4 -- X resulting force; Local StC coordinates -ServoDyn['NStC4_Fyl'] = False # (kN); Nacelle StC #4 -- Y resulting force; Local StC coordinates -ServoDyn['NStC4_Fzl'] = False # (kN); Nacelle StC #4 -- Z resulting force; Local StC coordinates -ServoDyn['NStC4_Mxl'] = False # (kN-m); Nacelle StC #4 -- X resulting moment; Local StC coordinates -ServoDyn['NStC4_Myl'] = False # (kN-m); Nacelle StC #4 -- Y resulting moment; Local StC coordinates -ServoDyn['NStC4_Mzl'] = False # (kN-m); Nacelle StC #4 -- Z resulting moment; Local StC coordinates - -# Tower Structural Control (StC) -ServoDyn['TStC1_XQ'] = False # (m); Tower StC #1 -- X position (displacement); Relative to rest position in StC reference frame -ServoDyn['TStC1_XQD'] = False # (m/s); Tower StC #1 -- X velocity; Relative to nacelle in StC reference frame -ServoDyn['TStC1_YQ'] = False # (m); Tower StC #1 -- Y position (displacement); Relative to rest position in StC reference frame -ServoDyn['TStC1_YQD'] = False # (m/s); Tower StC #1 -- Y velocity; Relative to nacelle in StC reference frame -ServoDyn['TStC1_ZQ'] = False # (m); Tower StC #1 -- Z position (displacement); Relative to rest position in StC reference frame -ServoDyn['TStC1_ZQD'] = False # (m/s); Tower StC #1 -- Z velocity; Relative to nacelle in StC reference frame -ServoDyn['TStC1_Fxi'] = False # (kN); Tower StC #1 -- X resulting force; Inertial (global) coordinates -ServoDyn['TStC1_Fyi'] = False # (kN); Tower StC #1 -- Y resulting force; Inertial (global) coordinates -ServoDyn['TStC1_Fzi'] = False # (kN); Tower StC #1 -- Z resulting force; Inertial (global) coordinates -ServoDyn['TStC1_Mxi'] = False # (kN-m); Tower StC #1 -- X resulting moment; Inertial (global) coordinates -ServoDyn['TStC1_Myi'] = False # (kN-m); Tower StC #1 -- Y resulting moment; Inertial (global) coordinates -ServoDyn['TStC1_Mzi'] = False # (kN-m); Tower StC #1 -- Z resulting moment; Inertial (global) coordinates -ServoDyn['TStC1_Fxl'] = False # (kN); Tower StC #1 -- X resulting force; Local StC coordinates -ServoDyn['TStC1_Fyl'] = False # (kN); Tower StC #1 -- Y resulting force; Local StC coordinates -ServoDyn['TStC1_Fzl'] = False # (kN); Tower StC #1 -- Z resulting force; Local StC coordinates -ServoDyn['TStC1_Mxl'] = False # (kN-m); Tower StC #1 -- X resulting moment; Local StC coordinates -ServoDyn['TStC1_Myl'] = False # (kN-m); Tower StC #1 -- Y resulting moment; Local StC coordinates -ServoDyn['TStC1_Mzl'] = False # (kN-m); Tower StC #1 -- Z resulting moment; Local StC coordinates -ServoDyn['TStC2_XQ'] = False # (m); Tower StC #2 -- X position (displacement); Relative to rest position in StC reference frame -ServoDyn['TStC2_XQD'] = False # (m/s); Tower StC #2 -- X velocity; Relative to nacelle in StC reference frame -ServoDyn['TStC2_YQ'] = False # (m); Tower StC #2 -- Y position (displacement); Relative to rest position in StC reference frame -ServoDyn['TStC2_YQD'] = False # (m/s); Tower StC #2 -- Y velocity; Relative to nacelle in StC reference frame -ServoDyn['TStC2_ZQ'] = False # (m); Tower StC #2 -- Z position (displacement); Relative to rest position in StC reference frame -ServoDyn['TStC2_ZQD'] = False # (m/s); Tower StC #2 -- Z velocity; Relative to nacelle in StC reference frame -ServoDyn['TStC2_Fxi'] = False # (kN); Tower StC #2 -- X resulting force; Inertial (global) coordinates -ServoDyn['TStC2_Fyi'] = False # (kN); Tower StC #2 -- Y resulting force; Inertial (global) coordinates -ServoDyn['TStC2_Fzi'] = False # (kN); Tower StC #2 -- Z resulting force; Inertial (global) coordinates -ServoDyn['TStC2_Mxi'] = False # (kN-m); Tower StC #2 -- X resulting moment; Inertial (global) coordinates -ServoDyn['TStC2_Myi'] = False # (kN-m); Tower StC #2 -- Y resulting moment; Inertial (global) coordinates -ServoDyn['TStC2_Mzi'] = False # (kN-m); Tower StC #2 -- Z resulting moment; Inertial (global) coordinates -ServoDyn['TStC2_Fxl'] = False # (kN); Tower StC #2 -- X resulting force; Local StC coordinates -ServoDyn['TStC2_Fyl'] = False # (kN); Tower StC #2 -- Y resulting force; Local StC coordinates -ServoDyn['TStC2_Fzl'] = False # (kN); Tower StC #2 -- Z resulting force; Local StC coordinates -ServoDyn['TStC2_Mxl'] = False # (kN-m); Tower StC #2 -- X resulting moment; Local StC coordinates -ServoDyn['TStC2_Myl'] = False # (kN-m); Tower StC #2 -- Y resulting moment; Local StC coordinates -ServoDyn['TStC2_Mzl'] = False # (kN-m); Tower StC #2 -- Z resulting moment; Local StC coordinates -ServoDyn['TStC3_XQ'] = False # (m); Tower StC #3 -- X position (displacement); Relative to rest position in StC reference frame -ServoDyn['TStC3_XQD'] = False # (m/s); Tower StC #3 -- X velocity; Relative to nacelle in StC reference frame -ServoDyn['TStC3_YQ'] = False # (m); Tower StC #3 -- Y position (displacement); Relative to rest position in StC reference frame -ServoDyn['TStC3_YQD'] = False # (m/s); Tower StC #3 -- Y velocity; Relative to nacelle in StC reference frame -ServoDyn['TStC3_ZQ'] = False # (m); Tower StC #3 -- Z position (displacement); Relative to rest position in StC reference frame -ServoDyn['TStC3_ZQD'] = False # (m/s); Tower StC #3 -- Z velocity; Relative to nacelle in StC reference frame -ServoDyn['TStC3_Fxi'] = False # (kN); Tower StC #3 -- X resulting force; Inertial (global) coordinates -ServoDyn['TStC3_Fyi'] = False # (kN); Tower StC #3 -- Y resulting force; Inertial (global) coordinates -ServoDyn['TStC3_Fzi'] = False # (kN); Tower StC #3 -- Z resulting force; Inertial (global) coordinates -ServoDyn['TStC3_Mxi'] = False # (kN-m); Tower StC #3 -- X resulting moment; Inertial (global) coordinates -ServoDyn['TStC3_Myi'] = False # (kN-m); Tower StC #3 -- Y resulting moment; Inertial (global) coordinates -ServoDyn['TStC3_Mzi'] = False # (kN-m); Tower StC #3 -- Z resulting moment; Inertial (global) coordinates -ServoDyn['TStC3_Fxl'] = False # (kN); Tower StC #3 -- X resulting force; Local StC coordinates -ServoDyn['TStC3_Fyl'] = False # (kN); Tower StC #3 -- Y resulting force; Local StC coordinates -ServoDyn['TStC3_Fzl'] = False # (kN); Tower StC #3 -- Z resulting force; Local StC coordinates -ServoDyn['TStC3_Mxl'] = False # (kN-m); Tower StC #3 -- X resulting moment; Local StC coordinates -ServoDyn['TStC3_Myl'] = False # (kN-m); Tower StC #3 -- Y resulting moment; Local StC coordinates -ServoDyn['TStC3_Mzl'] = False # (kN-m); Tower StC #3 -- Z resulting moment; Local StC coordinates -ServoDyn['TStC4_XQ'] = False # (m); Tower StC #4 -- X position (displacement); Relative to rest position in StC reference frame -ServoDyn['TStC4_XQD'] = False # (m/s); Tower StC #4 -- X velocity; Relative to nacelle in StC reference frame -ServoDyn['TStC4_YQ'] = False # (m); Tower StC #4 -- Y position (displacement); Relative to rest position in StC reference frame -ServoDyn['TStC4_YQD'] = False # (m/s); Tower StC #4 -- Y velocity; Relative to nacelle in StC reference frame -ServoDyn['TStC4_ZQ'] = False # (m); Tower StC #4 -- Z position (displacement); Relative to rest position in StC reference frame -ServoDyn['TStC4_ZQD'] = False # (m/s); Tower StC #4 -- Z velocity; Relative to nacelle in StC reference frame -ServoDyn['TStC4_Fxi'] = False # (kN); Tower StC #4 -- X resulting force; Inertial (global) coordinates -ServoDyn['TStC4_Fyi'] = False # (kN); Tower StC #4 -- Y resulting force; Inertial (global) coordinates -ServoDyn['TStC4_Fzi'] = False # (kN); Tower StC #4 -- Z resulting force; Inertial (global) coordinates -ServoDyn['TStC4_Mxi'] = False # (kN-m); Tower StC #4 -- X resulting moment; Inertial (global) coordinates -ServoDyn['TStC4_Myi'] = False # (kN-m); Tower StC #4 -- Y resulting moment; Inertial (global) coordinates -ServoDyn['TStC4_Mzi'] = False # (kN-m); Tower StC #4 -- Z resulting moment; Inertial (global) coordinates -ServoDyn['TStC4_Fxl'] = False # (kN); Tower StC #4 -- X resulting force; Local StC coordinates -ServoDyn['TStC4_Fyl'] = False # (kN); Tower StC #4 -- Y resulting force; Local StC coordinates -ServoDyn['TStC4_Fzl'] = False # (kN); Tower StC #4 -- Z resulting force; Local StC coordinates -ServoDyn['TStC4_Mxl'] = False # (kN-m); Tower StC #4 -- X resulting moment; Local StC coordinates -ServoDyn['TStC4_Myl'] = False # (kN-m); Tower StC #4 -- Y resulting moment; Local StC coordinates -ServoDyn['TStC4_Mzl'] = False # (kN-m); Tower StC #4 -- Z resulting moment; Local StC coordinates - -# Blade Structural Control (StC) -ServoDyn['BStC1_B1_XQ'] = False # (m); Blade StC #1 Blade #1 -- X position (displacement); Relative to rest position in StC reference frame -ServoDyn['BStC1_B1_XQD'] = False # (m/s); Blade StC #1 Blade #1 -- X velocity; Relative to nacelle in StC reference frame -ServoDyn['BStC1_B1_YQ'] = False # (m); Blade StC #1 Blade #1 -- Y position (displacement); Relative to rest position in StC reference frame -ServoDyn['BStC1_B1_YQD'] = False # (m/s); Blade StC #1 Blade #1 -- Y velocity; Relative to nacelle in StC reference frame -ServoDyn['BStC1_B1_ZQ'] = False # (m); Blade StC #1 Blade #1 -- Z position (displacement); Relative to rest position in StC reference frame -ServoDyn['BStC1_B1_ZQD'] = False # (m/s); Blade StC #1 Blade #1 -- Z velocity; Relative to nacelle in StC reference frame -ServoDyn['BStC1_B1_Fxi'] = False # (kN); Blade StC #1 Blade #1 -- X resulting force; Inertial (global) coordinates -ServoDyn['BStC1_B1_Fyi'] = False # (kN); Blade StC #1 Blade #1 -- Y resulting force; Inertial (global) coordinates -ServoDyn['BStC1_B1_Fzi'] = False # (kN); Blade StC #1 Blade #1 -- Z resulting force; Inertial (global) coordinates -ServoDyn['BStC1_B1_Mxi'] = False # (kN-m); Blade StC #1 Blade #1 -- X resulting moment; Inertial (global) coordinates -ServoDyn['BStC1_B1_Myi'] = False # (kN-m); Blade StC #1 Blade #1 -- Y resulting moment; Inertial (global) coordinates -ServoDyn['BStC1_B1_Mzi'] = False # (kN-m); Blade StC #1 Blade #1 -- Z resulting moment; Inertial (global) coordinates -ServoDyn['BStC1_B1_Fxl'] = False # (kN); Blade StC #1 Blade #1 -- X resulting force; Local StC coordinates -ServoDyn['BStC1_B1_Fyl'] = False # (kN); Blade StC #1 Blade #1 -- Y resulting force; Local StC coordinates -ServoDyn['BStC1_B1_Fzl'] = False # (kN); Blade StC #1 Blade #1 -- Z resulting force; Local StC coordinates -ServoDyn['BStC1_B1_Mxl'] = False # (kN-m); Blade StC #1 Blade #1 -- X resulting moment; Local StC coordinates -ServoDyn['BStC1_B1_Myl'] = False # (kN-m); Blade StC #1 Blade #1 -- Y resulting moment; Local StC coordinates -ServoDyn['BStC1_B1_Mzl'] = False # (kN-m); Blade StC #1 Blade #1 -- Z resulting moment; Local StC coordinates -ServoDyn['BStC2_B1_XQ'] = False # (m); Blade StC #2 Blade #1 -- X position (displacement); Relative to rest position in StC reference frame -ServoDyn['BStC2_B1_XQD'] = False # (m/s); Blade StC #2 Blade #1 -- X velocity; Relative to nacelle in StC reference frame -ServoDyn['BStC2_B1_YQ'] = False # (m); Blade StC #2 Blade #1 -- Y position (displacement); Relative to rest position in StC reference frame -ServoDyn['BStC2_B1_YQD'] = False # (m/s); Blade StC #2 Blade #1 -- Y velocity; Relative to nacelle in StC reference frame -ServoDyn['BStC2_B1_ZQ'] = False # (m); Blade StC #2 Blade #1 -- Z position (displacement); Relative to rest position in StC reference frame -ServoDyn['BStC2_B1_ZQD'] = False # (m/s); Blade StC #2 Blade #1 -- Z velocity; Relative to nacelle in StC reference frame -ServoDyn['BStC2_B1_Fxi'] = False # (kN); Blade StC #2 Blade #1 -- X resulting force; Inertial (global) coordinates -ServoDyn['BStC2_B1_Fyi'] = False # (kN); Blade StC #2 Blade #1 -- Y resulting force; Inertial (global) coordinates -ServoDyn['BStC2_B1_Fzi'] = False # (kN); Blade StC #2 Blade #1 -- Z resulting force; Inertial (global) coordinates -ServoDyn['BStC2_B1_Mxi'] = False # (kN-m); Blade StC #2 Blade #1 -- X resulting moment; Inertial (global) coordinates -ServoDyn['BStC2_B1_Myi'] = False # (kN-m); Blade StC #2 Blade #1 -- Y resulting moment; Inertial (global) coordinates -ServoDyn['BStC2_B1_Mzi'] = False # (kN-m); Blade StC #2 Blade #1 -- Z resulting moment; Inertial (global) coordinates -ServoDyn['BStC2_B1_Fxl'] = False # (kN); Blade StC #2 Blade #1 -- X resulting force; Local StC coordinates -ServoDyn['BStC2_B1_Fyl'] = False # (kN); Blade StC #2 Blade #1 -- Y resulting force; Local StC coordinates -ServoDyn['BStC2_B1_Fzl'] = False # (kN); Blade StC #2 Blade #1 -- Z resulting force; Local StC coordinates -ServoDyn['BStC2_B1_Mxl'] = False # (kN-m); Blade StC #2 Blade #1 -- X resulting moment; Local StC coordinates -ServoDyn['BStC2_B1_Myl'] = False # (kN-m); Blade StC #2 Blade #1 -- Y resulting moment; Local StC coordinates -ServoDyn['BStC2_B1_Mzl'] = False # (kN-m); Blade StC #2 Blade #1 -- Z resulting moment; Local StC coordinates -ServoDyn['BStC3_B1_XQ'] = False # (m); Blade StC #3 Blade #1 -- X position (displacement); Relative to rest position in StC reference frame -ServoDyn['BStC3_B1_XQD'] = False # (m/s); Blade StC #3 Blade #1 -- X velocity; Relative to nacelle in StC reference frame -ServoDyn['BStC3_B1_YQ'] = False # (m); Blade StC #3 Blade #1 -- Y position (displacement); Relative to rest position in StC reference frame -ServoDyn['BStC3_B1_YQD'] = False # (m/s); Blade StC #3 Blade #1 -- Y velocity; Relative to nacelle in StC reference frame -ServoDyn['BStC3_B1_ZQ'] = False # (m); Blade StC #3 Blade #1 -- Z position (displacement); Relative to rest position in StC reference frame -ServoDyn['BStC3_B1_ZQD'] = False # (m/s); Blade StC #3 Blade #1 -- Z velocity; Relative to nacelle in StC reference frame -ServoDyn['BStC3_B1_Fxi'] = False # (kN); Blade StC #3 Blade #1 -- X resulting force; Inertial (global) coordinates -ServoDyn['BStC3_B1_Fyi'] = False # (kN); Blade StC #3 Blade #1 -- Y resulting force; Inertial (global) coordinates -ServoDyn['BStC3_B1_Fzi'] = False # (kN); Blade StC #3 Blade #1 -- Z resulting force; Inertial (global) coordinates -ServoDyn['BStC3_B1_Mxi'] = False # (kN-m); Blade StC #3 Blade #1 -- X resulting moment; Inertial (global) coordinates -ServoDyn['BStC3_B1_Myi'] = False # (kN-m); Blade StC #3 Blade #1 -- Y resulting moment; Inertial (global) coordinates -ServoDyn['BStC3_B1_Mzi'] = False # (kN-m); Blade StC #3 Blade #1 -- Z resulting moment; Inertial (global) coordinates -ServoDyn['BStC3_B1_Fxl'] = False # (kN); Blade StC #3 Blade #1 -- X resulting force; Local StC coordinates -ServoDyn['BStC3_B1_Fyl'] = False # (kN); Blade StC #3 Blade #1 -- Y resulting force; Local StC coordinates -ServoDyn['BStC3_B1_Fzl'] = False # (kN); Blade StC #3 Blade #1 -- Z resulting force; Local StC coordinates -ServoDyn['BStC3_B1_Mxl'] = False # (kN-m); Blade StC #3 Blade #1 -- X resulting moment; Local StC coordinates -ServoDyn['BStC3_B1_Myl'] = False # (kN-m); Blade StC #3 Blade #1 -- Y resulting moment; Local StC coordinates -ServoDyn['BStC3_B1_Mzl'] = False # (kN-m); Blade StC #3 Blade #1 -- Z resulting moment; Local StC coordinates -ServoDyn['BStC4_B1_XQ'] = False # (m); Blade StC #4 Blade #1 -- X position (displacement); Relative to rest position in StC reference frame -ServoDyn['BStC4_B1_XQD'] = False # (m/s); Blade StC #4 Blade #1 -- X velocity; Relative to nacelle in StC reference frame -ServoDyn['BStC4_B1_YQ'] = False # (m); Blade StC #4 Blade #1 -- Y position (displacement); Relative to rest position in StC reference frame -ServoDyn['BStC4_B1_YQD'] = False # (m/s); Blade StC #4 Blade #1 -- Y velocity; Relative to nacelle in StC reference frame -ServoDyn['BStC4_B1_ZQ'] = False # (m); Blade StC #4 Blade #1 -- Z position (displacement); Relative to rest position in StC reference frame -ServoDyn['BStC4_B1_ZQD'] = False # (m/s); Blade StC #4 Blade #1 -- Z velocity; Relative to nacelle in StC reference frame -ServoDyn['BStC4_B1_Fxi'] = False # (kN); Blade StC #4 Blade #1 -- X resulting force; Inertial (global) coordinates -ServoDyn['BStC4_B1_Fyi'] = False # (kN); Blade StC #4 Blade #1 -- Y resulting force; Inertial (global) coordinates -ServoDyn['BStC4_B1_Fzi'] = False # (kN); Blade StC #4 Blade #1 -- Z resulting force; Inertial (global) coordinates -ServoDyn['BStC4_B1_Mxi'] = False # (kN-m); Blade StC #4 Blade #1 -- X resulting moment; Inertial (global) coordinates -ServoDyn['BStC4_B1_Myi'] = False # (kN-m); Blade StC #4 Blade #1 -- Y resulting moment; Inertial (global) coordinates -ServoDyn['BStC4_B1_Mzi'] = False # (kN-m); Blade StC #4 Blade #1 -- Z resulting moment; Inertial (global) coordinates -ServoDyn['BStC4_B1_Fxl'] = False # (kN); Blade StC #4 Blade #1 -- X resulting force; Local StC coordinates -ServoDyn['BStC4_B1_Fyl'] = False # (kN); Blade StC #4 Blade #1 -- Y resulting force; Local StC coordinates -ServoDyn['BStC4_B1_Fzl'] = False # (kN); Blade StC #4 Blade #1 -- Z resulting force; Local StC coordinates -ServoDyn['BStC4_B1_Mxl'] = False # (kN-m); Blade StC #4 Blade #1 -- X resulting moment; Local StC coordinates -ServoDyn['BStC4_B1_Myl'] = False # (kN-m); Blade StC #4 Blade #1 -- Y resulting moment; Local StC coordinates -ServoDyn['BStC4_B1_Mzl'] = False # (kN-m); Blade StC #4 Blade #1 -- Z resulting moment; Local StC coordinates -ServoDyn['BStC1_B2_XQ'] = False # (m); Blade StC #1 Blade #2 -- X position (displacement); Relative to rest position in StC reference frame -ServoDyn['BStC1_B2_XQD'] = False # (m/s); Blade StC #1 Blade #2 -- X velocity; Relative to nacelle in StC reference frame -ServoDyn['BStC1_B2_YQ'] = False # (m); Blade StC #1 Blade #2 -- Y position (displacement); Relative to rest position in StC reference frame -ServoDyn['BStC1_B2_YQD'] = False # (m/s); Blade StC #1 Blade #2 -- Y velocity; Relative to nacelle in StC reference frame -ServoDyn['BStC1_B2_ZQ'] = False # (m); Blade StC #1 Blade #2 -- Z position (displacement); Relative to rest position in StC reference frame -ServoDyn['BStC1_B2_ZQD'] = False # (m/s); Blade StC #1 Blade #2 -- Z velocity; Relative to nacelle in StC reference frame -ServoDyn['BStC1_B2_Fxi'] = False # (kN); Blade StC #1 Blade #2 -- X resulting force; Inertial (global) coordinates -ServoDyn['BStC1_B2_Fyi'] = False # (kN); Blade StC #1 Blade #2 -- Y resulting force; Inertial (global) coordinates -ServoDyn['BStC1_B2_Fzi'] = False # (kN); Blade StC #1 Blade #2 -- Z resulting force; Inertial (global) coordinates -ServoDyn['BStC1_B2_Mxi'] = False # (kN-m); Blade StC #1 Blade #2 -- X resulting moment; Inertial (global) coordinates -ServoDyn['BStC1_B2_Myi'] = False # (kN-m); Blade StC #1 Blade #2 -- Y resulting moment; Inertial (global) coordinates -ServoDyn['BStC1_B2_Mzi'] = False # (kN-m); Blade StC #1 Blade #2 -- Z resulting moment; Inertial (global) coordinates -ServoDyn['BStC1_B2_Fxl'] = False # (kN); Blade StC #1 Blade #2 -- X resulting force; Local StC coordinates -ServoDyn['BStC1_B2_Fyl'] = False # (kN); Blade StC #1 Blade #2 -- Y resulting force; Local StC coordinates -ServoDyn['BStC1_B2_Fzl'] = False # (kN); Blade StC #1 Blade #2 -- Z resulting force; Local StC coordinates -ServoDyn['BStC1_B2_Mxl'] = False # (kN-m); Blade StC #1 Blade #2 -- X resulting moment; Local StC coordinates -ServoDyn['BStC1_B2_Myl'] = False # (kN-m); Blade StC #1 Blade #2 -- Y resulting moment; Local StC coordinates -ServoDyn['BStC1_B2_Mzl'] = False # (kN-m); Blade StC #1 Blade #2 -- Z resulting moment; Local StC coordinates -ServoDyn['BStC2_B2_XQ'] = False # (m); Blade StC #2 Blade #2 -- X position (displacement); Relative to rest position in StC reference frame -ServoDyn['BStC2_B2_XQD'] = False # (m/s); Blade StC #2 Blade #2 -- X velocity; Relative to nacelle in StC reference frame -ServoDyn['BStC2_B2_YQ'] = False # (m); Blade StC #2 Blade #2 -- Y position (displacement); Relative to rest position in StC reference frame -ServoDyn['BStC2_B2_YQD'] = False # (m/s); Blade StC #2 Blade #2 -- Y velocity; Relative to nacelle in StC reference frame -ServoDyn['BStC2_B2_ZQ'] = False # (m); Blade StC #2 Blade #2 -- Z position (displacement); Relative to rest position in StC reference frame -ServoDyn['BStC2_B2_ZQD'] = False # (m/s); Blade StC #2 Blade #2 -- Z velocity; Relative to nacelle in StC reference frame -ServoDyn['BStC2_B2_Fxi'] = False # (kN); Blade StC #2 Blade #2 -- X resulting force; Inertial (global) coordinates -ServoDyn['BStC2_B2_Fyi'] = False # (kN); Blade StC #2 Blade #2 -- Y resulting force; Inertial (global) coordinates -ServoDyn['BStC2_B2_Fzi'] = False # (kN); Blade StC #2 Blade #2 -- Z resulting force; Inertial (global) coordinates -ServoDyn['BStC2_B2_Mxi'] = False # (kN-m); Blade StC #2 Blade #2 -- X resulting moment; Inertial (global) coordinates -ServoDyn['BStC2_B2_Myi'] = False # (kN-m); Blade StC #2 Blade #2 -- Y resulting moment; Inertial (global) coordinates -ServoDyn['BStC2_B2_Mzi'] = False # (kN-m); Blade StC #2 Blade #2 -- Z resulting moment; Inertial (global) coordinates -ServoDyn['BStC2_B2_Fxl'] = False # (kN); Blade StC #2 Blade #2 -- X resulting force; Local StC coordinates -ServoDyn['BStC2_B2_Fyl'] = False # (kN); Blade StC #2 Blade #2 -- Y resulting force; Local StC coordinates -ServoDyn['BStC2_B2_Fzl'] = False # (kN); Blade StC #2 Blade #2 -- Z resulting force; Local StC coordinates -ServoDyn['BStC2_B2_Mxl'] = False # (kN-m); Blade StC #2 Blade #2 -- X resulting moment; Local StC coordinates -ServoDyn['BStC2_B2_Myl'] = False # (kN-m); Blade StC #2 Blade #2 -- Y resulting moment; Local StC coordinates -ServoDyn['BStC2_B2_Mzl'] = False # (kN-m); Blade StC #2 Blade #2 -- Z resulting moment; Local StC coordinates -ServoDyn['BStC3_B2_XQ'] = False # (m); Blade StC #3 Blade #2 -- X position (displacement); Relative to rest position in StC reference frame -ServoDyn['BStC3_B2_XQD'] = False # (m/s); Blade StC #3 Blade #2 -- X velocity; Relative to nacelle in StC reference frame -ServoDyn['BStC3_B2_YQ'] = False # (m); Blade StC #3 Blade #2 -- Y position (displacement); Relative to rest position in StC reference frame -ServoDyn['BStC3_B2_YQD'] = False # (m/s); Blade StC #3 Blade #2 -- Y velocity; Relative to nacelle in StC reference frame -ServoDyn['BStC3_B2_ZQ'] = False # (m); Blade StC #3 Blade #2 -- Z position (displacement); Relative to rest position in StC reference frame -ServoDyn['BStC3_B2_ZQD'] = False # (m/s); Blade StC #3 Blade #2 -- Z velocity; Relative to nacelle in StC reference frame -ServoDyn['BStC3_B2_Fxi'] = False # (kN); Blade StC #3 Blade #2 -- X resulting force; Inertial (global) coordinates -ServoDyn['BStC3_B2_Fyi'] = False # (kN); Blade StC #3 Blade #2 -- Y resulting force; Inertial (global) coordinates -ServoDyn['BStC3_B2_Fzi'] = False # (kN); Blade StC #3 Blade #2 -- Z resulting force; Inertial (global) coordinates -ServoDyn['BStC3_B2_Mxi'] = False # (kN-m); Blade StC #3 Blade #2 -- X resulting moment; Inertial (global) coordinates -ServoDyn['BStC3_B2_Myi'] = False # (kN-m); Blade StC #3 Blade #2 -- Y resulting moment; Inertial (global) coordinates -ServoDyn['BStC3_B2_Mzi'] = False # (kN-m); Blade StC #3 Blade #2 -- Z resulting moment; Inertial (global) coordinates -ServoDyn['BStC3_B2_Fxl'] = False # (kN); Blade StC #3 Blade #2 -- X resulting force; Local StC coordinates -ServoDyn['BStC3_B2_Fyl'] = False # (kN); Blade StC #3 Blade #2 -- Y resulting force; Local StC coordinates -ServoDyn['BStC3_B2_Fzl'] = False # (kN); Blade StC #3 Blade #2 -- Z resulting force; Local StC coordinates -ServoDyn['BStC3_B2_Mxl'] = False # (kN-m); Blade StC #3 Blade #2 -- X resulting moment; Local StC coordinates -ServoDyn['BStC3_B2_Myl'] = False # (kN-m); Blade StC #3 Blade #2 -- Y resulting moment; Local StC coordinates -ServoDyn['BStC3_B2_Mzl'] = False # (kN-m); Blade StC #3 Blade #2 -- Z resulting moment; Local StC coordinates -ServoDyn['BStC4_B2_XQ'] = False # (m); Blade StC #4 Blade #2 -- X position (displacement); Relative to rest position in StC reference frame -ServoDyn['BStC4_B2_XQD'] = False # (m/s); Blade StC #4 Blade #2 -- X velocity; Relative to nacelle in StC reference frame -ServoDyn['BStC4_B2_YQ'] = False # (m); Blade StC #4 Blade #2 -- Y position (displacement); Relative to rest position in StC reference frame -ServoDyn['BStC4_B2_YQD'] = False # (m/s); Blade StC #4 Blade #2 -- Y velocity; Relative to nacelle in StC reference frame -ServoDyn['BStC4_B2_ZQ'] = False # (m); Blade StC #4 Blade #2 -- Z position (displacement); Relative to rest position in StC reference frame -ServoDyn['BStC4_B2_ZQD'] = False # (m/s); Blade StC #4 Blade #2 -- Z velocity; Relative to nacelle in StC reference frame -ServoDyn['BStC4_B2_Fxi'] = False # (kN); Blade StC #4 Blade #2 -- X resulting force; Inertial (global) coordinates -ServoDyn['BStC4_B2_Fyi'] = False # (kN); Blade StC #4 Blade #2 -- Y resulting force; Inertial (global) coordinates -ServoDyn['BStC4_B2_Fzi'] = False # (kN); Blade StC #4 Blade #2 -- Z resulting force; Inertial (global) coordinates -ServoDyn['BStC4_B2_Mxi'] = False # (kN-m); Blade StC #4 Blade #2 -- X resulting moment; Inertial (global) coordinates -ServoDyn['BStC4_B2_Myi'] = False # (kN-m); Blade StC #4 Blade #2 -- Y resulting moment; Inertial (global) coordinates -ServoDyn['BStC4_B2_Mzi'] = False # (kN-m); Blade StC #4 Blade #2 -- Z resulting moment; Inertial (global) coordinates -ServoDyn['BStC4_B2_Fxl'] = False # (kN); Blade StC #4 Blade #2 -- X resulting force; Local StC coordinates -ServoDyn['BStC4_B2_Fyl'] = False # (kN); Blade StC #4 Blade #2 -- Y resulting force; Local StC coordinates -ServoDyn['BStC4_B2_Fzl'] = False # (kN); Blade StC #4 Blade #2 -- Z resulting force; Local StC coordinates -ServoDyn['BStC4_B2_Mxl'] = False # (kN-m); Blade StC #4 Blade #2 -- X resulting moment; Local StC coordinates -ServoDyn['BStC4_B2_Myl'] = False # (kN-m); Blade StC #4 Blade #2 -- Y resulting moment; Local StC coordinates -ServoDyn['BStC4_B2_Mzl'] = False # (kN-m); Blade StC #4 Blade #2 -- Z resulting moment; Local StC coordinates -ServoDyn['BStC1_B3_XQ'] = False # (m); Blade StC #1 Blade #3 -- X position (displacement); Relative to rest position in StC reference frame -ServoDyn['BStC1_B3_XQD'] = False # (m/s); Blade StC #1 Blade #3 -- X velocity; Relative to nacelle in StC reference frame -ServoDyn['BStC1_B3_YQ'] = False # (m); Blade StC #1 Blade #3 -- Y position (displacement); Relative to rest position in StC reference frame -ServoDyn['BStC1_B3_YQD'] = False # (m/s); Blade StC #1 Blade #3 -- Y velocity; Relative to nacelle in StC reference frame -ServoDyn['BStC1_B3_ZQ'] = False # (m); Blade StC #1 Blade #3 -- Z position (displacement); Relative to rest position in StC reference frame -ServoDyn['BStC1_B3_ZQD'] = False # (m/s); Blade StC #1 Blade #3 -- Z velocity; Relative to nacelle in StC reference frame -ServoDyn['BStC1_B3_Fxi'] = False # (kN); Blade StC #1 Blade #3 -- X resulting force; Inertial (global) coordinates -ServoDyn['BStC1_B3_Fyi'] = False # (kN); Blade StC #1 Blade #3 -- Y resulting force; Inertial (global) coordinates -ServoDyn['BStC1_B3_Fzi'] = False # (kN); Blade StC #1 Blade #3 -- Z resulting force; Inertial (global) coordinates -ServoDyn['BStC1_B3_Mxi'] = False # (kN-m); Blade StC #1 Blade #3 -- X resulting moment; Inertial (global) coordinates -ServoDyn['BStC1_B3_Myi'] = False # (kN-m); Blade StC #1 Blade #3 -- Y resulting moment; Inertial (global) coordinates -ServoDyn['BStC1_B3_Mzi'] = False # (kN-m); Blade StC #1 Blade #3 -- Z resulting moment; Inertial (global) coordinates -ServoDyn['BStC1_B3_Fxl'] = False # (kN); Blade StC #1 Blade #3 -- X resulting force; Local StC coordinates -ServoDyn['BStC1_B3_Fyl'] = False # (kN); Blade StC #1 Blade #3 -- Y resulting force; Local StC coordinates -ServoDyn['BStC1_B3_Fzl'] = False # (kN); Blade StC #1 Blade #3 -- Z resulting force; Local StC coordinates -ServoDyn['BStC1_B3_Mxl'] = False # (kN-m); Blade StC #1 Blade #3 -- X resulting moment; Local StC coordinates -ServoDyn['BStC1_B3_Myl'] = False # (kN-m); Blade StC #1 Blade #3 -- Y resulting moment; Local StC coordinates -ServoDyn['BStC1_B3_Mzl'] = False # (kN-m); Blade StC #1 Blade #3 -- Z resulting moment; Local StC coordinates -ServoDyn['BStC2_B3_XQ'] = False # (m); Blade StC #2 Blade #3 -- X position (displacement); Relative to rest position in StC reference frame -ServoDyn['BStC2_B3_XQD'] = False # (m/s); Blade StC #2 Blade #3 -- X velocity; Relative to nacelle in StC reference frame -ServoDyn['BStC2_B3_YQ'] = False # (m); Blade StC #2 Blade #3 -- Y position (displacement); Relative to rest position in StC reference frame -ServoDyn['BStC2_B3_YQD'] = False # (m/s); Blade StC #2 Blade #3 -- Y velocity; Relative to nacelle in StC reference frame -ServoDyn['BStC2_B3_ZQ'] = False # (m); Blade StC #2 Blade #3 -- Z position (displacement); Relative to rest position in StC reference frame -ServoDyn['BStC2_B3_ZQD'] = False # (m/s); Blade StC #2 Blade #3 -- Z velocity; Relative to nacelle in StC reference frame -ServoDyn['BStC2_B3_Fxi'] = False # (kN); Blade StC #2 Blade #3 -- X resulting force; Inertial (global) coordinates -ServoDyn['BStC2_B3_Fyi'] = False # (kN); Blade StC #2 Blade #3 -- Y resulting force; Inertial (global) coordinates -ServoDyn['BStC2_B3_Fzi'] = False # (kN); Blade StC #2 Blade #3 -- Z resulting force; Inertial (global) coordinates -ServoDyn['BStC2_B3_Mxi'] = False # (kN-m); Blade StC #2 Blade #3 -- X resulting moment; Inertial (global) coordinates -ServoDyn['BStC2_B3_Myi'] = False # (kN-m); Blade StC #2 Blade #3 -- Y resulting moment; Inertial (global) coordinates -ServoDyn['BStC2_B3_Mzi'] = False # (kN-m); Blade StC #2 Blade #3 -- Z resulting moment; Inertial (global) coordinates -ServoDyn['BStC2_B3_Fxl'] = False # (kN); Blade StC #2 Blade #3 -- X resulting force; Local StC coordinates -ServoDyn['BStC2_B3_Fyl'] = False # (kN); Blade StC #2 Blade #3 -- Y resulting force; Local StC coordinates -ServoDyn['BStC2_B3_Fzl'] = False # (kN); Blade StC #2 Blade #3 -- Z resulting force; Local StC coordinates -ServoDyn['BStC2_B3_Mxl'] = False # (kN-m); Blade StC #2 Blade #3 -- X resulting moment; Local StC coordinates -ServoDyn['BStC2_B3_Myl'] = False # (kN-m); Blade StC #2 Blade #3 -- Y resulting moment; Local StC coordinates -ServoDyn['BStC2_B3_Mzl'] = False # (kN-m); Blade StC #2 Blade #3 -- Z resulting moment; Local StC coordinates -ServoDyn['BStC3_B3_XQ'] = False # (m); Blade StC #3 Blade #3 -- X position (displacement); Relative to rest position in StC reference frame -ServoDyn['BStC3_B3_XQD'] = False # (m/s); Blade StC #3 Blade #3 -- X velocity; Relative to nacelle in StC reference frame -ServoDyn['BStC3_B3_YQ'] = False # (m); Blade StC #3 Blade #3 -- Y position (displacement); Relative to rest position in StC reference frame -ServoDyn['BStC3_B3_YQD'] = False # (m/s); Blade StC #3 Blade #3 -- Y velocity; Relative to nacelle in StC reference frame -ServoDyn['BStC3_B3_ZQ'] = False # (m); Blade StC #3 Blade #3 -- Z position (displacement); Relative to rest position in StC reference frame -ServoDyn['BStC3_B3_ZQD'] = False # (m/s); Blade StC #3 Blade #3 -- Z velocity; Relative to nacelle in StC reference frame -ServoDyn['BStC3_B3_Fxi'] = False # (kN); Blade StC #3 Blade #3 -- X resulting force; Inertial (global) coordinates -ServoDyn['BStC3_B3_Fyi'] = False # (kN); Blade StC #3 Blade #3 -- Y resulting force; Inertial (global) coordinates -ServoDyn['BStC3_B3_Fzi'] = False # (kN); Blade StC #3 Blade #3 -- Z resulting force; Inertial (global) coordinates -ServoDyn['BStC3_B3_Mxi'] = False # (kN-m); Blade StC #3 Blade #3 -- X resulting moment; Inertial (global) coordinates -ServoDyn['BStC3_B3_Myi'] = False # (kN-m); Blade StC #3 Blade #3 -- Y resulting moment; Inertial (global) coordinates -ServoDyn['BStC3_B3_Mzi'] = False # (kN-m); Blade StC #3 Blade #3 -- Z resulting moment; Inertial (global) coordinates -ServoDyn['BStC3_B3_Fxl'] = False # (kN); Blade StC #3 Blade #3 -- X resulting force; Local StC coordinates -ServoDyn['BStC3_B3_Fyl'] = False # (kN); Blade StC #3 Blade #3 -- Y resulting force; Local StC coordinates -ServoDyn['BStC3_B3_Fzl'] = False # (kN); Blade StC #3 Blade #3 -- Z resulting force; Local StC coordinates -ServoDyn['BStC3_B3_Mxl'] = False # (kN-m); Blade StC #3 Blade #3 -- X resulting moment; Local StC coordinates -ServoDyn['BStC3_B3_Myl'] = False # (kN-m); Blade StC #3 Blade #3 -- Y resulting moment; Local StC coordinates -ServoDyn['BStC3_B3_Mzl'] = False # (kN-m); Blade StC #3 Blade #3 -- Z resulting moment; Local StC coordinates -ServoDyn['BStC4_B3_XQ'] = False # (m); Blade StC #4 Blade #3 -- X position (displacement); Relative to rest position in StC reference frame -ServoDyn['BStC4_B3_XQD'] = False # (m/s); Blade StC #4 Blade #3 -- X velocity; Relative to nacelle in StC reference frame -ServoDyn['BStC4_B3_YQ'] = False # (m); Blade StC #4 Blade #3 -- Y position (displacement); Relative to rest position in StC reference frame -ServoDyn['BStC4_B3_YQD'] = False # (m/s); Blade StC #4 Blade #3 -- Y velocity; Relative to nacelle in StC reference frame -ServoDyn['BStC4_B3_ZQ'] = False # (m); Blade StC #4 Blade #3 -- Z position (displacement); Relative to rest position in StC reference frame -ServoDyn['BStC4_B3_ZQD'] = False # (m/s); Blade StC #4 Blade #3 -- Z velocity; Relative to nacelle in StC reference frame -ServoDyn['BStC4_B3_Fxi'] = False # (kN); Blade StC #4 Blade #3 -- X resulting force; Inertial (global) coordinates -ServoDyn['BStC4_B3_Fyi'] = False # (kN); Blade StC #4 Blade #3 -- Y resulting force; Inertial (global) coordinates -ServoDyn['BStC4_B3_Fzi'] = False # (kN); Blade StC #4 Blade #3 -- Z resulting force; Inertial (global) coordinates -ServoDyn['BStC4_B3_Mxi'] = False # (kN-m); Blade StC #4 Blade #3 -- X resulting moment; Inertial (global) coordinates -ServoDyn['BStC4_B3_Myi'] = False # (kN-m); Blade StC #4 Blade #3 -- Y resulting moment; Inertial (global) coordinates -ServoDyn['BStC4_B3_Mzi'] = False # (kN-m); Blade StC #4 Blade #3 -- Z resulting moment; Inertial (global) coordinates -ServoDyn['BStC4_B3_Fxl'] = False # (kN); Blade StC #4 Blade #3 -- X resulting force; Local StC coordinates -ServoDyn['BStC4_B3_Fyl'] = False # (kN); Blade StC #4 Blade #3 -- Y resulting force; Local StC coordinates -ServoDyn['BStC4_B3_Fzl'] = False # (kN); Blade StC #4 Blade #3 -- Z resulting force; Local StC coordinates -ServoDyn['BStC4_B3_Mxl'] = False # (kN-m); Blade StC #4 Blade #3 -- X resulting moment; Local StC coordinates -ServoDyn['BStC4_B3_Myl'] = False # (kN-m); Blade StC #4 Blade #3 -- Y resulting moment; Local StC coordinates -ServoDyn['BStC4_B3_Mzl'] = False # (kN-m); Blade StC #4 Blade #3 -- Z resulting moment; Local StC coordinates -ServoDyn['BStC1_B4_XQ'] = False # (m); Blade StC #1 Blade #4 -- X position (displacement); Relative to rest position in StC reference frame -ServoDyn['BStC1_B4_XQD'] = False # (m/s); Blade StC #1 Blade #4 -- X velocity; Relative to nacelle in StC reference frame -ServoDyn['BStC1_B4_YQ'] = False # (m); Blade StC #1 Blade #4 -- Y position (displacement); Relative to rest position in StC reference frame -ServoDyn['BStC1_B4_YQD'] = False # (m/s); Blade StC #1 Blade #4 -- Y velocity; Relative to nacelle in StC reference frame -ServoDyn['BStC1_B4_ZQ'] = False # (m); Blade StC #1 Blade #4 -- Z position (displacement); Relative to rest position in StC reference frame -ServoDyn['BStC1_B4_ZQD'] = False # (m/s); Blade StC #1 Blade #4 -- Z velocity; Relative to nacelle in StC reference frame -ServoDyn['BStC1_B4_Fxi'] = False # (kN); Blade StC #1 Blade #4 -- X resulting force; Inertial (global) coordinates -ServoDyn['BStC1_B4_Fyi'] = False # (kN); Blade StC #1 Blade #4 -- Y resulting force; Inertial (global) coordinates -ServoDyn['BStC1_B4_Fzi'] = False # (kN); Blade StC #1 Blade #4 -- Z resulting force; Inertial (global) coordinates -ServoDyn['BStC1_B4_Mxi'] = False # (kN-m); Blade StC #1 Blade #4 -- X resulting moment; Inertial (global) coordinates -ServoDyn['BStC1_B4_Myi'] = False # (kN-m); Blade StC #1 Blade #4 -- Y resulting moment; Inertial (global) coordinates -ServoDyn['BStC1_B4_Mzi'] = False # (kN-m); Blade StC #1 Blade #4 -- Z resulting moment; Inertial (global) coordinates -ServoDyn['BStC1_B4_Fxl'] = False # (kN); Blade StC #1 Blade #4 -- X resulting force; Local StC coordinates -ServoDyn['BStC1_B4_Fyl'] = False # (kN); Blade StC #1 Blade #4 -- Y resulting force; Local StC coordinates -ServoDyn['BStC1_B4_Fzl'] = False # (kN); Blade StC #1 Blade #4 -- Z resulting force; Local StC coordinates -ServoDyn['BStC1_B4_Mxl'] = False # (kN-m); Blade StC #1 Blade #4 -- X resulting moment; Local StC coordinates -ServoDyn['BStC1_B4_Myl'] = False # (kN-m); Blade StC #1 Blade #4 -- Y resulting moment; Local StC coordinates -ServoDyn['BStC1_B4_Mzl'] = False # (kN-m); Blade StC #1 Blade #4 -- Z resulting moment; Local StC coordinates -ServoDyn['BStC2_B4_XQ'] = False # (m); Blade StC #2 Blade #4 -- X position (displacement); Relative to rest position in StC reference frame -ServoDyn['BStC2_B4_XQD'] = False # (m/s); Blade StC #2 Blade #4 -- X velocity; Relative to nacelle in StC reference frame -ServoDyn['BStC2_B4_YQ'] = False # (m); Blade StC #2 Blade #4 -- Y position (displacement); Relative to rest position in StC reference frame -ServoDyn['BStC2_B4_YQD'] = False # (m/s); Blade StC #2 Blade #4 -- Y velocity; Relative to nacelle in StC reference frame -ServoDyn['BStC2_B4_ZQ'] = False # (m); Blade StC #2 Blade #4 -- Z position (displacement); Relative to rest position in StC reference frame -ServoDyn['BStC2_B4_ZQD'] = False # (m/s); Blade StC #2 Blade #4 -- Z velocity; Relative to nacelle in StC reference frame -ServoDyn['BStC2_B4_Fxi'] = False # (kN); Blade StC #2 Blade #4 -- X resulting force; Inertial (global) coordinates -ServoDyn['BStC2_B4_Fyi'] = False # (kN); Blade StC #2 Blade #4 -- Y resulting force; Inertial (global) coordinates -ServoDyn['BStC2_B4_Fzi'] = False # (kN); Blade StC #2 Blade #4 -- Z resulting force; Inertial (global) coordinates -ServoDyn['BStC2_B4_Mxi'] = False # (kN-m); Blade StC #2 Blade #4 -- X resulting moment; Inertial (global) coordinates -ServoDyn['BStC2_B4_Myi'] = False # (kN-m); Blade StC #2 Blade #4 -- Y resulting moment; Inertial (global) coordinates -ServoDyn['BStC2_B4_Mzi'] = False # (kN-m); Blade StC #2 Blade #4 -- Z resulting moment; Inertial (global) coordinates -ServoDyn['BStC2_B4_Fxl'] = False # (kN); Blade StC #2 Blade #4 -- X resulting force; Local StC coordinates -ServoDyn['BStC2_B4_Fyl'] = False # (kN); Blade StC #2 Blade #4 -- Y resulting force; Local StC coordinates -ServoDyn['BStC2_B4_Fzl'] = False # (kN); Blade StC #2 Blade #4 -- Z resulting force; Local StC coordinates -ServoDyn['BStC2_B4_Mxl'] = False # (kN-m); Blade StC #2 Blade #4 -- X resulting moment; Local StC coordinates -ServoDyn['BStC2_B4_Myl'] = False # (kN-m); Blade StC #2 Blade #4 -- Y resulting moment; Local StC coordinates -ServoDyn['BStC2_B4_Mzl'] = False # (kN-m); Blade StC #2 Blade #4 -- Z resulting moment; Local StC coordinates -ServoDyn['BStC3_B4_XQ'] = False # (m); Blade StC #3 Blade #4 -- X position (displacement); Relative to rest position in StC reference frame -ServoDyn['BStC3_B4_XQD'] = False # (m/s); Blade StC #3 Blade #4 -- X velocity; Relative to nacelle in StC reference frame -ServoDyn['BStC3_B4_YQ'] = False # (m); Blade StC #3 Blade #4 -- Y position (displacement); Relative to rest position in StC reference frame -ServoDyn['BStC3_B4_YQD'] = False # (m/s); Blade StC #3 Blade #4 -- Y velocity; Relative to nacelle in StC reference frame -ServoDyn['BStC3_B4_ZQ'] = False # (m); Blade StC #3 Blade #4 -- Z position (displacement); Relative to rest position in StC reference frame -ServoDyn['BStC3_B4_ZQD'] = False # (m/s); Blade StC #3 Blade #4 -- Z velocity; Relative to nacelle in StC reference frame -ServoDyn['BStC3_B4_Fxi'] = False # (kN); Blade StC #3 Blade #4 -- X resulting force; Inertial (global) coordinates -ServoDyn['BStC3_B4_Fyi'] = False # (kN); Blade StC #3 Blade #4 -- Y resulting force; Inertial (global) coordinates -ServoDyn['BStC3_B4_Fzi'] = False # (kN); Blade StC #3 Blade #4 -- Z resulting force; Inertial (global) coordinates -ServoDyn['BStC3_B4_Mxi'] = False # (kN-m); Blade StC #3 Blade #4 -- X resulting moment; Inertial (global) coordinates -ServoDyn['BStC3_B4_Myi'] = False # (kN-m); Blade StC #3 Blade #4 -- Y resulting moment; Inertial (global) coordinates -ServoDyn['BStC3_B4_Mzi'] = False # (kN-m); Blade StC #3 Blade #4 -- Z resulting moment; Inertial (global) coordinates -ServoDyn['BStC3_B4_Fxl'] = False # (kN); Blade StC #3 Blade #4 -- X resulting force; Local StC coordinates -ServoDyn['BStC3_B4_Fyl'] = False # (kN); Blade StC #3 Blade #4 -- Y resulting force; Local StC coordinates -ServoDyn['BStC3_B4_Fzl'] = False # (kN); Blade StC #3 Blade #4 -- Z resulting force; Local StC coordinates -ServoDyn['BStC3_B4_Mxl'] = False # (kN-m); Blade StC #3 Blade #4 -- X resulting moment; Local StC coordinates -ServoDyn['BStC3_B4_Myl'] = False # (kN-m); Blade StC #3 Blade #4 -- Y resulting moment; Local StC coordinates -ServoDyn['BStC3_B4_Mzl'] = False # (kN-m); Blade StC #3 Blade #4 -- Z resulting moment; Local StC coordinates -ServoDyn['BStC4_B4_XQ'] = False # (m); Blade StC #4 Blade #4 -- X position (displacement); Relative to rest position in StC reference frame -ServoDyn['BStC4_B4_XQD'] = False # (m/s); Blade StC #4 Blade #4 -- X velocity; Relative to nacelle in StC reference frame -ServoDyn['BStC4_B4_YQ'] = False # (m); Blade StC #4 Blade #4 -- Y position (displacement); Relative to rest position in StC reference frame -ServoDyn['BStC4_B4_YQD'] = False # (m/s); Blade StC #4 Blade #4 -- Y velocity; Relative to nacelle in StC reference frame -ServoDyn['BStC4_B4_ZQ'] = False # (m); Blade StC #4 Blade #4 -- Z position (displacement); Relative to rest position in StC reference frame -ServoDyn['BStC4_B4_ZQD'] = False # (m/s); Blade StC #4 Blade #4 -- Z velocity; Relative to nacelle in StC reference frame -ServoDyn['BStC4_B4_Fxi'] = False # (kN); Blade StC #4 Blade #4 -- X resulting force; Inertial (global) coordinates -ServoDyn['BStC4_B4_Fyi'] = False # (kN); Blade StC #4 Blade #4 -- Y resulting force; Inertial (global) coordinates -ServoDyn['BStC4_B4_Fzi'] = False # (kN); Blade StC #4 Blade #4 -- Z resulting force; Inertial (global) coordinates -ServoDyn['BStC4_B4_Mxi'] = False # (kN-m); Blade StC #4 Blade #4 -- X resulting moment; Inertial (global) coordinates -ServoDyn['BStC4_B4_Myi'] = False # (kN-m); Blade StC #4 Blade #4 -- Y resulting moment; Inertial (global) coordinates -ServoDyn['BStC4_B4_Mzi'] = False # (kN-m); Blade StC #4 Blade #4 -- Z resulting moment; Inertial (global) coordinates -ServoDyn['BStC4_B4_Fxl'] = False # (kN); Blade StC #4 Blade #4 -- X resulting force; Local StC coordinates -ServoDyn['BStC4_B4_Fyl'] = False # (kN); Blade StC #4 Blade #4 -- Y resulting force; Local StC coordinates -ServoDyn['BStC4_B4_Fzl'] = False # (kN); Blade StC #4 Blade #4 -- Z resulting force; Local StC coordinates -ServoDyn['BStC4_B4_Mxl'] = False # (kN-m); Blade StC #4 Blade #4 -- X resulting moment; Local StC coordinates -ServoDyn['BStC4_B4_Myl'] = False # (kN-m); Blade StC #4 Blade #4 -- Y resulting moment; Local StC coordinates -ServoDyn['BStC4_B4_Mzl'] = False # (kN-m); Blade StC #4 Blade #4 -- Z resulting moment; Local StC coordinates - -# Substructure Structural Control (StC) -ServoDyn['SStC1_XQ'] = False # (m); Substructure StC #1 -- X position (displacement); Relative to rest position in StC reference frame -ServoDyn['SStC1_XQD'] = False # (m/s); Substructure StC #1 -- X velocity; Relative to nacelle in StC reference frame -ServoDyn['SStC1_YQ'] = False # (m); Substructure StC #1 -- Y position (displacement); Relative to rest position in StC reference frame -ServoDyn['SStC1_YQD'] = False # (m/s); Substructure StC #1 -- Y velocity; Relative to nacelle in StC reference frame -ServoDyn['SStC1_ZQ'] = False # (m); Substructure StC #1 -- Z position (displacement); Relative to rest position in StC reference frame -ServoDyn['SStC1_ZQD'] = False # (m/s); Substructure StC #1 -- Z velocity; Relative to nacelle in StC reference frame -ServoDyn['SStC1_Fxi'] = False # (kN); Substructure StC #1 -- X resulting force; Inertial (global) coordinates -ServoDyn['SStC1_Fyi'] = False # (kN); Substructure StC #1 -- Y resulting force; Inertial (global) coordinates -ServoDyn['SStC1_Fzi'] = False # (kN); Substructure StC #1 -- Z resulting force; Inertial (global) coordinates -ServoDyn['SStC1_Mxi'] = False # (kN-m); Substructure StC #1 -- X resulting moment; Inertial (global) coordinates -ServoDyn['SStC1_Myi'] = False # (kN-m); Substructure StC #1 -- Y resulting moment; Inertial (global) coordinates -ServoDyn['SStC1_Mzi'] = False # (kN-m); Substructure StC #1 -- Z resulting moment; Inertial (global) coordinates -ServoDyn['SStC1_Fxl'] = False # (kN); Substructure StC #1 -- X resulting force; Local StC coordinates -ServoDyn['SStC1_Fyl'] = False # (kN); Substructure StC #1 -- Y resulting force; Local StC coordinates -ServoDyn['SStC1_Fzl'] = False # (kN); Substructure StC #1 -- Z resulting force; Local StC coordinates -ServoDyn['SStC1_Mxl'] = False # (kN-m); Substructure StC #1 -- X resulting moment; Local StC coordinates -ServoDyn['SStC1_Myl'] = False # (kN-m); Substructure StC #1 -- Y resulting moment; Local StC coordinates -ServoDyn['SStC1_Mzl'] = False # (kN-m); Substructure StC #1 -- Z resulting moment; Local StC coordinates -ServoDyn['SStC2_XQ'] = False # (m); Substructure StC #2 -- X position (displacement); Relative to rest position in StC reference frame -ServoDyn['SStC2_XQD'] = False # (m/s); Substructure StC #2 -- X velocity; Relative to nacelle in StC reference frame -ServoDyn['SStC2_YQ'] = False # (m); Substructure StC #2 -- Y position (displacement); Relative to rest position in StC reference frame -ServoDyn['SStC2_YQD'] = False # (m/s); Substructure StC #2 -- Y velocity; Relative to nacelle in StC reference frame -ServoDyn['SStC2_ZQ'] = False # (m); Substructure StC #2 -- Z position (displacement); Relative to rest position in StC reference frame -ServoDyn['SStC2_ZQD'] = False # (m/s); Substructure StC #2 -- Z velocity; Relative to nacelle in StC reference frame -ServoDyn['SStC2_Fxi'] = False # (kN); Substructure StC #2 -- X resulting force; Inertial (global) coordinates -ServoDyn['SStC2_Fyi'] = False # (kN); Substructure StC #2 -- Y resulting force; Inertial (global) coordinates -ServoDyn['SStC2_Fzi'] = False # (kN); Substructure StC #2 -- Z resulting force; Inertial (global) coordinates -ServoDyn['SStC2_Mxi'] = False # (kN-m); Substructure StC #2 -- X resulting moment; Inertial (global) coordinates -ServoDyn['SStC2_Myi'] = False # (kN-m); Substructure StC #2 -- Y resulting moment; Inertial (global) coordinates -ServoDyn['SStC2_Mzi'] = False # (kN-m); Substructure StC #2 -- Z resulting moment; Inertial (global) coordinates -ServoDyn['SStC2_Fxl'] = False # (kN); Substructure StC #2 -- X resulting force; Local StC coordinates -ServoDyn['SStC2_Fyl'] = False # (kN); Substructure StC #2 -- Y resulting force; Local StC coordinates -ServoDyn['SStC2_Fzl'] = False # (kN); Substructure StC #2 -- Z resulting force; Local StC coordinates -ServoDyn['SStC2_Mxl'] = False # (kN-m); Substructure StC #2 -- X resulting moment; Local StC coordinates -ServoDyn['SStC2_Myl'] = False # (kN-m); Substructure StC #2 -- Y resulting moment; Local StC coordinates -ServoDyn['SStC2_Mzl'] = False # (kN-m); Substructure StC #2 -- Z resulting moment; Local StC coordinates -ServoDyn['SStC3_XQ'] = False # (m); Substructure StC #3 -- X position (displacement); Relative to rest position in StC reference frame -ServoDyn['SStC3_XQD'] = False # (m/s); Substructure StC #3 -- X velocity; Relative to nacelle in StC reference frame -ServoDyn['SStC3_YQ'] = False # (m); Substructure StC #3 -- Y position (displacement); Relative to rest position in StC reference frame -ServoDyn['SStC3_YQD'] = False # (m/s); Substructure StC #3 -- Y velocity; Relative to nacelle in StC reference frame -ServoDyn['SStC3_ZQ'] = False # (m); Substructure StC #3 -- Z position (displacement); Relative to rest position in StC reference frame -ServoDyn['SStC3_ZQD'] = False # (m/s); Substructure StC #3 -- Z velocity; Relative to nacelle in StC reference frame -ServoDyn['SStC3_Fxi'] = False # (kN); Substructure StC #3 -- X resulting force; Inertial (global) coordinates -ServoDyn['SStC3_Fyi'] = False # (kN); Substructure StC #3 -- Y resulting force; Inertial (global) coordinates -ServoDyn['SStC3_Fzi'] = False # (kN); Substructure StC #3 -- Z resulting force; Inertial (global) coordinates -ServoDyn['SStC3_Mxi'] = False # (kN-m); Substructure StC #3 -- X resulting moment; Inertial (global) coordinates -ServoDyn['SStC3_Myi'] = False # (kN-m); Substructure StC #3 -- Y resulting moment; Inertial (global) coordinates -ServoDyn['SStC3_Mzi'] = False # (kN-m); Substructure StC #3 -- Z resulting moment; Inertial (global) coordinates -ServoDyn['SStC3_Fxl'] = False # (kN); Substructure StC #3 -- X resulting force; Local StC coordinates -ServoDyn['SStC3_Fyl'] = False # (kN); Substructure StC #3 -- Y resulting force; Local StC coordinates -ServoDyn['SStC3_Fzl'] = False # (kN); Substructure StC #3 -- Z resulting force; Local StC coordinates -ServoDyn['SStC3_Mxl'] = False # (kN-m); Substructure StC #3 -- X resulting moment; Local StC coordinates -ServoDyn['SStC3_Myl'] = False # (kN-m); Substructure StC #3 -- Y resulting moment; Local StC coordinates -ServoDyn['SStC3_Mzl'] = False # (kN-m); Substructure StC #3 -- Z resulting moment; Local StC coordinates -ServoDyn['SStC4_XQ'] = False # (m); Substructure StC #4 -- X position (displacement); Relative to rest position in StC reference frame -ServoDyn['SStC4_XQD'] = False # (m/s); Substructure StC #4 -- X velocity; Relative to nacelle in StC reference frame -ServoDyn['SStC4_YQ'] = False # (m); Substructure StC #4 -- Y position (displacement); Relative to rest position in StC reference frame -ServoDyn['SStC4_YQD'] = False # (m/s); Substructure StC #4 -- Y velocity; Relative to nacelle in StC reference frame -ServoDyn['SStC4_ZQ'] = False # (m); Substructure StC #4 -- Z position (displacement); Relative to rest position in StC reference frame -ServoDyn['SStC4_ZQD'] = False # (m/s); Substructure StC #4 -- Z velocity; Relative to nacelle in StC reference frame -ServoDyn['SStC4_Fxi'] = False # (kN); Substructure StC #4 -- X resulting force; Inertial (global) coordinates -ServoDyn['SStC4_Fyi'] = False # (kN); Substructure StC #4 -- Y resulting force; Inertial (global) coordinates -ServoDyn['SStC4_Fzi'] = False # (kN); Substructure StC #4 -- Z resulting force; Inertial (global) coordinates -ServoDyn['SStC4_Mxi'] = False # (kN-m); Substructure StC #4 -- X resulting moment; Inertial (global) coordinates -ServoDyn['SStC4_Myi'] = False # (kN-m); Substructure StC #4 -- Y resulting moment; Inertial (global) coordinates -ServoDyn['SStC4_Mzi'] = False # (kN-m); Substructure StC #4 -- Z resulting moment; Inertial (global) coordinates -ServoDyn['SStC4_Fxl'] = False # (kN); Substructure StC #4 -- X resulting force; Local StC coordinates -ServoDyn['SStC4_Fyl'] = False # (kN); Substructure StC #4 -- Y resulting force; Local StC coordinates -ServoDyn['SStC4_Fzl'] = False # (kN); Substructure StC #4 -- Z resulting force; Local StC coordinates -ServoDyn['SStC4_Mxl'] = False # (kN-m); Substructure StC #4 -- X resulting moment; Local StC coordinates -ServoDyn['SStC4_Myl'] = False # (kN-m); Substructure StC #4 -- Y resulting moment; Local StC coordinates -ServoDyn['SStC4_Mzl'] = False # (kN-m); Substructure StC #4 -- Z resulting moment; Local StC coordinates - - - -# Flap outputs -ServoDyn['BLFLAP1'] = False # (m/s); Tower Y TMD velocity; Relative to tower -ServoDyn['BLFLAP2'] = False # (m/s); Tower Y TMD velocity; Relative to tower -ServoDyn['BLFLAP3'] = False # (m/s); Tower Y TMD velocity; Relative to tower - -""" AeroDyn """ -AeroDyn = {} - -# Tower -AeroDyn['TwN1VUndx'] = False # (m/s); Undisturbed x-component wind velocity at Tw node 1; local tower coordinate system -AeroDyn['TwN1VUndy'] = False # (m/s); Undisturbed y-component wind velocity at Tw node 1; local tower coordinate system -AeroDyn['TwN1VUndz'] = False # (m/s); Undisturbed z-component wind velocity at Tw node 1; local tower coordinate system -AeroDyn['TwN2VUndx'] = False # (m/s); Undisturbed x-component wind velocity at Tw node 2; local tower coordinate system -AeroDyn['TwN2VUndy'] = False # (m/s); Undisturbed y-component wind velocity at Tw node 2; local tower coordinate system -AeroDyn['TwN2VUndz'] = False # (m/s); Undisturbed z-component wind velocity at Tw node 2; local tower coordinate system -AeroDyn['TwN3VUndx'] = False # (m/s); Undisturbed x-component wind velocity at Tw node 3; local tower coordinate system -AeroDyn['TwN3VUndy'] = False # (m/s); Undisturbed y-component wind velocity at Tw node 3; local tower coordinate system -AeroDyn['TwN3VUndz'] = False # (m/s); Undisturbed z-component wind velocity at Tw node 3; local tower coordinate system -AeroDyn['TwN4VUndx'] = False # (m/s); Undisturbed x-component wind velocity at Tw node 4; local tower coordinate system -AeroDyn['TwN4VUndy'] = False # (m/s); Undisturbed y-component wind velocity at Tw node 4; local tower coordinate system -AeroDyn['TwN4VUndz'] = False # (m/s); Undisturbed z-component wind velocity at Tw node 4; local tower coordinate system -AeroDyn['TwN5VUndx'] = False # (m/s); Undisturbed x-component wind velocity at Tw node 5; local tower coordinate system -AeroDyn['TwN5VUndy'] = False # (m/s); Undisturbed y-component wind velocity at Tw node 5; local tower coordinate system -AeroDyn['TwN5VUndz'] = False # (m/s); Undisturbed z-component wind velocity at Tw node 5; local tower coordinate system -AeroDyn['TwN6VUndx'] = False # (m/s); Undisturbed x-component wind velocity at Tw node 6; local tower coordinate system -AeroDyn['TwN6VUndy'] = False # (m/s); Undisturbed y-component wind velocity at Tw node 6; local tower coordinate system -AeroDyn['TwN6VUndz'] = False # (m/s); Undisturbed z-component wind velocity at Tw node 6; local tower coordinate system -AeroDyn['TwN7VUndx'] = False # (m/s); Undisturbed x-component wind velocity at Tw node 7; local tower coordinate system -AeroDyn['TwN7VUndy'] = False # (m/s); Undisturbed y-component wind velocity at Tw node 7; local tower coordinate system -AeroDyn['TwN7VUndz'] = False # (m/s); Undisturbed z-component wind velocity at Tw node 7; local tower coordinate system -AeroDyn['TwN8VUndx'] = False # (m/s); Undisturbed x-component wind velocity at Tw node 8; local tower coordinate system -AeroDyn['TwN8VUndy'] = False # (m/s); Undisturbed y-component wind velocity at Tw node 8; local tower coordinate system -AeroDyn['TwN8VUndz'] = False # (m/s); Undisturbed z-component wind velocity at Tw node 8; local tower coordinate system -AeroDyn['TwN9VUndx'] = False # (m/s); Undisturbed x-component wind velocity at Tw node 9; local tower coordinate system -AeroDyn['TwN9VUndy'] = False # (m/s); Undisturbed y-component wind velocity at Tw node 9; local tower coordinate system -AeroDyn['TwN9VUndz'] = False # (m/s); Undisturbed z-component wind velocity at Tw node 9; local tower coordinate system -AeroDyn['TwN1STVx'] = False # (m/s); Structural translational velocity x-component at Tw node 1; local tower coordinate system -AeroDyn['TwN1STVy'] = False # (m/s); Structural translational velocity y-component at Tw node 1; local tower coordinate system -AeroDyn['TwN1STVz'] = False # (m/s); Structural translational velocity z-component at Tw node 1; local tower coordinate system -AeroDyn['TwN2STVx'] = False # (m/s); Structural translational velocity x-component at Tw node 2; local tower coordinate system -AeroDyn['TwN2STVy'] = False # (m/s); Structural translational velocity y-component at Tw node 2; local tower coordinate system -AeroDyn['TwN2STVz'] = False # (m/s); Structural translational velocity z-component at Tw node 2; local tower coordinate system -AeroDyn['TwN3STVx'] = False # (m/s); Structural translational velocity x-component at Tw node 3; local tower coordinate system -AeroDyn['TwN3STVy'] = False # (m/s); Structural translational velocity y-component at Tw node 3; local tower coordinate system -AeroDyn['TwN3STVz'] = False # (m/s); Structural translational velocity z-component at Tw node 3; local tower coordinate system -AeroDyn['TwN4STVx'] = False # (m/s); Structural translational velocity x-component at Tw node 4; local tower coordinate system -AeroDyn['TwN4STVy'] = False # (m/s); Structural translational velocity y-component at Tw node 4; local tower coordinate system -AeroDyn['TwN4STVz'] = False # (m/s); Structural translational velocity z-component at Tw node 4; local tower coordinate system -AeroDyn['TwN5STVx'] = False # (m/s); Structural translational velocity x-component at Tw node 5; local tower coordinate system -AeroDyn['TwN5STVy'] = False # (m/s); Structural translational velocity y-component at Tw node 5; local tower coordinate system -AeroDyn['TwN5STVz'] = False # (m/s); Structural translational velocity z-component at Tw node 5; local tower coordinate system -AeroDyn['TwN6STVx'] = False # (m/s); Structural translational velocity x-component at Tw node 6; local tower coordinate system -AeroDyn['TwN6STVy'] = False # (m/s); Structural translational velocity y-component at Tw node 6; local tower coordinate system -AeroDyn['TwN6STVz'] = False # (m/s); Structural translational velocity z-component at Tw node 6; local tower coordinate system -AeroDyn['TwN7STVx'] = False # (m/s); Structural translational velocity x-component at Tw node 7; local tower coordinate system -AeroDyn['TwN7STVy'] = False # (m/s); Structural translational velocity y-component at Tw node 7; local tower coordinate system -AeroDyn['TwN7STVz'] = False # (m/s); Structural translational velocity z-component at Tw node 7; local tower coordinate system -AeroDyn['TwN8STVx'] = False # (m/s); Structural translational velocity x-component at Tw node 8; local tower coordinate system -AeroDyn['TwN8STVy'] = False # (m/s); Structural translational velocity y-component at Tw node 8; local tower coordinate system -AeroDyn['TwN8STVz'] = False # (m/s); Structural translational velocity z-component at Tw node 8; local tower coordinate system -AeroDyn['TwN9STVx'] = False # (m/s); Structural translational velocity x-component at Tw node 9; local tower coordinate system -AeroDyn['TwN9STVy'] = False # (m/s); Structural translational velocity y-component at Tw node 9; local tower coordinate system -AeroDyn['TwN9STVz'] = False # (m/s); Structural translational velocity z-component at Tw node 9; local tower coordinate system -AeroDyn['TwN1Vrel'] = False # (m/s); Relative wind speed at Tw node 1; -AeroDyn['TwN2Vrel'] = False # (m/s); Relative wind speed at Tw node 2; -AeroDyn['TwN3Vrel'] = False # (m/s); Relative wind speed at Tw node 3; -AeroDyn['TwN4Vrel'] = False # (m/s); Relative wind speed at Tw node 4; -AeroDyn['TwN5Vrel'] = False # (m/s); Relative wind speed at Tw node 5; -AeroDyn['TwN6Vrel'] = False # (m/s); Relative wind speed at Tw node 6; -AeroDyn['TwN7Vrel'] = False # (m/s); Relative wind speed at Tw node 7; -AeroDyn['TwN8Vrel'] = False # (m/s); Relative wind speed at Tw node 8; -AeroDyn['TwN9Vrel'] = False # (m/s); Relative wind speed at Tw node 9; -AeroDyn['TwN1DynP'] = False # (Pa); Dynamic Pressure at Tw node 1; -AeroDyn['TwN2DynP'] = False # (Pa); Dynamic Pressure at Tw node 2; -AeroDyn['TwN3DynP'] = False # (Pa); Dynamic Pressure at Tw node 3; -AeroDyn['TwN4DynP'] = False # (Pa); Dynamic Pressure at Tw node 4; -AeroDyn['TwN5DynP'] = False # (Pa); Dynamic Pressure at Tw node 5; -AeroDyn['TwN6DynP'] = False # (Pa); Dynamic Pressure at Tw node 6; -AeroDyn['TwN7DynP'] = False # (Pa); Dynamic Pressure at Tw node 7; -AeroDyn['TwN8DynP'] = False # (Pa); Dynamic Pressure at Tw node 8; -AeroDyn['TwN9DynP'] = False # (Pa); Dynamic Pressure at Tw node 9; -AeroDyn['TwN1Re'] = False # (-); Reynolds number (in millions) at Tw node 1; -AeroDyn['TwN2Re'] = False # (-); Reynolds number (in millions) at Tw node 2; -AeroDyn['TwN3Re'] = False # (-); Reynolds number (in millions) at Tw node 3; -AeroDyn['TwN4Re'] = False # (-); Reynolds number (in millions) at Tw node 4; -AeroDyn['TwN5Re'] = False # (-); Reynolds number (in millions) at Tw node 5; -AeroDyn['TwN6Re'] = False # (-); Reynolds number (in millions) at Tw node 6; -AeroDyn['TwN7Re'] = False # (-); Reynolds number (in millions) at Tw node 7; -AeroDyn['TwN8Re'] = False # (-); Reynolds number (in millions) at Tw node 8; -AeroDyn['TwN9Re'] = False # (-); Reynolds number (in millions) at Tw node 9; -AeroDyn['TwN1M'] = False # (-); Mach number at Tw node 1; -AeroDyn['TwN2M'] = False # (-); Mach number at Tw node 2; -AeroDyn['TwN3M'] = False # (-); Mach number at Tw node 3; -AeroDyn['TwN4M'] = False # (-); Mach number at Tw node 4; -AeroDyn['TwN5M'] = False # (-); Mach number at Tw node 5; -AeroDyn['TwN6M'] = False # (-); Mach number at Tw node 6; -AeroDyn['TwN7M'] = False # (-); Mach number at Tw node 7; -AeroDyn['TwN8M'] = False # (-); Mach number at Tw node 8; -AeroDyn['TwN9M'] = False # (-); Mach number at Tw node 9; -AeroDyn['TwN1Fdx'] = False # (N/m); x-component of drag force per unit length at Tw node 1; local tower coordinate system -AeroDyn['TwN2Fdx'] = False # (N/m); x-component of drag force per unit length at Tw node 2; local tower coordinate system -AeroDyn['TwN3Fdx'] = False # (N/m); x-component of drag force per unit length at Tw node 3; local tower coordinate system -AeroDyn['TwN4Fdx'] = False # (N/m); x-component of drag force per unit length at Tw node 4; local tower coordinate system -AeroDyn['TwN5Fdx'] = False # (N/m); x-component of drag force per unit length at Tw node 5; local tower coordinate system -AeroDyn['TwN6Fdx'] = False # (N/m); x-component of drag force per unit length at Tw node 6; local tower coordinate system -AeroDyn['TwN7Fdx'] = False # (N/m); x-component of drag force per unit length at Tw node 7; local tower coordinate system -AeroDyn['TwN8Fdx'] = False # (N/m); x-component of drag force per unit length at Tw node 8; local tower coordinate system -AeroDyn['TwN9Fdx'] = False # (N/m); x-component of drag force per unit length at Tw node 9; local tower coordinate system -AeroDyn['TwN1Fdy'] = False # (N/m); y-component of drag force per unit length at Tw node 1; local tower coordinate system -AeroDyn['TwN2Fdy'] = False # (N/m); y-component of drag force per unit length at Tw node 2; local tower coordinate system -AeroDyn['TwN3Fdy'] = False # (N/m); y-component of drag force per unit length at Tw node 3; local tower coordinate system -AeroDyn['TwN4Fdy'] = False # (N/m); y-component of drag force per unit length at Tw node 4; local tower coordinate system -AeroDyn['TwN5Fdy'] = False # (N/m); y-component of drag force per unit length at Tw node 5; local tower coordinate system -AeroDyn['TwN6Fdy'] = False # (N/m); y-component of drag force per unit length at Tw node 6; local tower coordinate system -AeroDyn['TwN7Fdy'] = False # (N/m); y-component of drag force per unit length at Tw node 7; local tower coordinate system -AeroDyn['TwN8Fdy'] = False # (N/m); y-component of drag force per unit length at Tw node 8; local tower coordinate system -AeroDyn['TwN9Fdy'] = False # (N/m); y-component of drag force per unit length at Tw node 9; local tower coordinate system - -# Blade -AeroDyn['B1Azimuth'] = False # (deg); Azimuth angle of blade 1; -AeroDyn['B2Azimuth'] = False # (deg); Azimuth angle of blade 2; -AeroDyn['B3Azimuth'] = False # (deg); Azimuth angle of blade 3; -AeroDyn['B1Pitch'] = False # (deg); Pitch angle of blade 1; -AeroDyn['B2Pitch'] = False # (deg); Pitch angle of blade 2; -AeroDyn['B3Pitch'] = False # (deg); Pitch angle of blade 3; -AeroDyn['B1AeroFx'] = False # (N); Total blade aerodynamic load for blade 1 (force in x-direction); blade root coordinate system -AeroDyn['B1AeroFy'] = False # (N); Total blade aerodynamic load for blade 1 (force in y-direction); blade root coordinate system -AeroDyn['B1AeroFz'] = False # (N); Total blade aerodynamic load for blade 1 (force in z-direction); blade root coordinate system -AeroDyn['B1AeroMx'] = False # (N-m); Total blade aerodynamic load for blade 1 (moment in x-direction); blade root coordinate system -AeroDyn['B1AeroMy'] = False # (N-m); Total blade aerodynamic load for blade 1 (moment in y-direction); blade root coordinate system -AeroDyn['B1AeroMz'] = False # (N-m); Total blade aerodynamic load for blade 1 (moment in z-direction); blade root coordinate system -AeroDyn['B1AeroPwr'] = False # (W); Total aerodynamic power from blade 1; -AeroDyn['B2AeroFx'] = False # (N); Total blade aerodynamic load for blade 2 (force in x-direction); blade root coordinate system -AeroDyn['B2AeroFy'] = False # (N); Total blade aerodynamic load for blade 2 (force in y-direction); blade root coordinate system -AeroDyn['B2AeroFz'] = False # (N); Total blade aerodynamic load for blade 2 (force in z-direction); blade root coordinate system -AeroDyn['B2AeroMx'] = False # (N-m); Total blade aerodynamic load for blade 2 (moment in x-direction); blade root coordinate system -AeroDyn['B2AeroMy'] = False # (N-m); Total blade aerodynamic load for blade 2 (moment in y-direction); blade root coordinate system -AeroDyn['B2AeroMz'] = False # (N-m); Total blade aerodynamic load for blade 2 (moment in z-direction); blade root coordinate system -AeroDyn['B2AeroPwr'] = False # (W); Total aerodynamic power from blade 2; -AeroDyn['B3AeroFx'] = False # (N); Total blade aerodynamic load for blade 3 (force in x-direction); blade root coordinate system -AeroDyn['B3AeroFy'] = False # (N); Total blade aerodynamic load for blade 3 (force in y-direction); blade root coordinate system -AeroDyn['B3AeroFz'] = False # (N); Total blade aerodynamic load for blade 3 (force in z-direction); blade root coordinate system -AeroDyn['B3AeroMx'] = False # (N-m); Total blade aerodynamic load for blade 3 (moment in x-direction); blade root coordinate system -AeroDyn['B3AeroMy'] = False # (N-m); Total blade aerodynamic load for blade 3 (moment in y-direction); blade root coordinate system -AeroDyn['B3AeroMz'] = False # (N-m); Total blade aerodynamic load for blade 3 (moment in z-direction); blade root coordinate system -AeroDyn['B3AeroPwr'] = False # (W); Total aerodynamic power from blade 3; -AeroDyn['B4AeroFx'] = False # (N); Total blade aerodynamic load for blade 4 (force in x-direction); blade root coordinate system -AeroDyn['B4AeroFy'] = False # (N); Total blade aerodynamic load for blade 4 (force in y-direction); blade root coordinate system -AeroDyn['B4AeroFz'] = False # (N); Total blade aerodynamic load for blade 4 (force in z-direction); blade root coordinate system -AeroDyn['B4AeroMx'] = False # (N-m); Total blade aerodynamic load for blade 4 (moment in x-direction); blade root coordinate system -AeroDyn['B4AeroMy'] = False # (N-m); Total blade aerodynamic load for blade 4 (moment in y-direction); blade root coordinate system -AeroDyn['B4AeroMz'] = False # (N-m); Total blade aerodynamic load for blade 4 (moment in z-direction); blade root coordinate system -AeroDyn['B4AeroPwr'] = False # (W); Total aerodynamic power from blade 4; -AeroDyn['B1AeroFxg'] = False # (N); Total blade aerodynamic load for blade 1 (force in x-direction); global coordinate system -AeroDyn['B1AeroFyg'] = False # (N); Total blade aerodynamic load for blade 1 (force in y-direction); global coordinate system -AeroDyn['B1AeroFzg'] = False # (N); Total blade aerodynamic load for blade 1 (force in z-direction); global coordinate system -AeroDyn['B1AeroMxg'] = False # (N-m); Total blade aerodynamic load for blade 1 (moment in x-direction); global coordinate system -AeroDyn['B1AeroMyg'] = False # (N-m); Total blade aerodynamic load for blade 1 (moment in y-direction); global coordinate system -AeroDyn['B1AeroMzg'] = False # (N-m); Total blade aerodynamic load for blade 1 (moment in z-direction); global coordinate system -AeroDyn['B2AeroFxg'] = False # (N); Total blade aerodynamic load for blade 2 (force in x-direction); global coordinate system -AeroDyn['B2AeroFyg'] = False # (N); Total blade aerodynamic load for blade 2 (force in y-direction); global coordinate system -AeroDyn['B2AeroFzg'] = False # (N); Total blade aerodynamic load for blade 2 (force in z-direction); global coordinate system -AeroDyn['B2AeroMxg'] = False # (N-m); Total blade aerodynamic load for blade 2 (moment in x-direction); global coordinate system -AeroDyn['B2AeroMyg'] = False # (N-m); Total blade aerodynamic load for blade 2 (moment in y-direction); global coordinate system -AeroDyn['B2AeroMzg'] = False # (N-m); Total blade aerodynamic load for blade 2 (moment in z-direction); global coordinate system -AeroDyn['B3AeroFxg'] = False # (N); Total blade aerodynamic load for blade 3 (force in x-direction); global coordinate system -AeroDyn['B3AeroFyg'] = False # (N); Total blade aerodynamic load for blade 3 (force in y-direction); global coordinate system -AeroDyn['B3AeroFzg'] = False # (N); Total blade aerodynamic load for blade 3 (force in z-direction); global coordinate system -AeroDyn['B3AeroMxg'] = False # (N-m); Total blade aerodynamic load for blade 3 (moment in x-direction); global coordinate system -AeroDyn['B3AeroMyg'] = False # (N-m); Total blade aerodynamic load for blade 3 (moment in y-direction); global coordinate system -AeroDyn['B3AeroMzg'] = False # (N-m); Total blade aerodynamic load for blade 3 (moment in z-direction); global coordinate system -AeroDyn['B4AeroFxg'] = False # (N); Total blade aerodynamic load for blade 4 (force in x-direction); global coordinate system -AeroDyn['B4AeroFyg'] = False # (N); Total blade aerodynamic load for blade 4 (force in y-direction); global coordinate system -AeroDyn['B4AeroFzg'] = False # (N); Total blade aerodynamic load for blade 4 (force in z-direction); global coordinate system -AeroDyn['B4AeroMxg'] = False # (N-m); Total blade aerodynamic load for blade 4 (moment in x-direction); global coordinate system -AeroDyn['B4AeroMyg'] = False # (N-m); Total blade aerodynamic load for blade 4 (moment in y-direction); global coordinate system -AeroDyn['B4AeroMzg'] = False # (N-m); Total blade aerodynamic load for blade 4 (moment in z-direction); global coordinate system +# Blade +AeroDyn['B1Azimuth'] = False # (deg); Azimuth angle of blade 1; +AeroDyn['B2Azimuth'] = False # (deg); Azimuth angle of blade 2; +AeroDyn['B3Azimuth'] = False # (deg); Azimuth angle of blade 3; +AeroDyn['B1Pitch'] = False # (deg); Pitch angle of blade 1; +AeroDyn['B2Pitch'] = False # (deg); Pitch angle of blade 2; +AeroDyn['B3Pitch'] = False # (deg); Pitch angle of blade 3; +AeroDyn['B1AeroFx'] = False # (N); Total blade aerodynamic/hydrodynamic load for blade 1 (force in x-direction); blade root coordinate system +AeroDyn['B1FldFx'] = False # (N); Total blade aerodynamic/hydrodynamic load for blade 1 (force in x-direction); blade root coordinate system +AeroDyn['B1AeroFy'] = False # (N); Total blade aerodynamic/hydrodynamic load for blade 1 (force in y-direction); blade root coordinate system +AeroDyn['B1FldFy'] = False # (N); Total blade aerodynamic/hydrodynamic load for blade 1 (force in y-direction); blade root coordinate system +AeroDyn['B1AeroFz'] = False # (N); Total blade aerodynamic/hydrodynamic load for blade 1 (force in z-direction); blade root coordinate system +AeroDyn['B1FldFz'] = False # (N); Total blade aerodynamic/hydrodynamic load for blade 1 (force in z-direction); blade root coordinate system +AeroDyn['B1AeroMx'] = False # (N-m); Total blade aerodynamic/hydrodynamic load for blade 1 (moment in x-direction); blade root coordinate system +AeroDyn['B1FldMx'] = False # (N-m); Total blade aerodynamic/hydrodynamic load for blade 1 (moment in x-direction); blade root coordinate system +AeroDyn['B1AeroMy'] = False # (N-m); Total blade aerodynamic/hydrodynamic load for blade 1 (moment in y-direction); blade root coordinate system +AeroDyn['B1FldMy'] = False # (N-m); Total blade aerodynamic/hydrodynamic load for blade 1 (moment in y-direction); blade root coordinate system +AeroDyn['B1AeroMz'] = False # (N-m); Total blade aerodynamic/hydrodynamic load for blade 1 (moment in z-direction); blade root coordinate system +AeroDyn['B1FldMz'] = False # (N-m); Total blade aerodynamic/hydrodynamic load for blade 1 (moment in z-direction); blade root coordinate system +AeroDyn['B1AeroPwr'] = False # (W); Total aerodynamic/hydrodynamic power from blade 1; +AeroDyn['B1FldPwr'] = False # (W); Total aerodynamic/hydrodynamic power from blade 1; +AeroDyn['B2AeroFx'] = False # (N); Total blade aerodynamic/hydrodynamic load for blade 2 (force in x-direction); blade root coordinate system +AeroDyn['B2FldFx'] = False # (N); Total blade aerodynamic/hydrodynamic load for blade 2 (force in x-direction); blade root coordinate system +AeroDyn['B2AeroFy'] = False # (N); Total blade aerodynamic/hydrodynamic load for blade 2 (force in y-direction); blade root coordinate system +AeroDyn['B2FldFy'] = False # (N); Total blade aerodynamic/hydrodynamic load for blade 2 (force in y-direction); blade root coordinate system +AeroDyn['B2AeroFz'] = False # (N); Total blade aerodynamic/hydrodynamic load for blade 2 (force in z-direction); blade root coordinate system +AeroDyn['B2FldFz'] = False # (N); Total blade aerodynamic/hydrodynamic load for blade 2 (force in z-direction); blade root coordinate system +AeroDyn['B2AeroMx'] = False # (N-m); Total blade aerodynamic/hydrodynamic load for blade 2 (moment in x-direction); blade root coordinate system +AeroDyn['B2FldMx'] = False # (N-m); Total blade aerodynamic/hydrodynamic load for blade 2 (moment in x-direction); blade root coordinate system +AeroDyn['B2AeroMy'] = False # (N-m); Total blade aerodynamic/hydrodynamic load for blade 2 (moment in y-direction); blade root coordinate system +AeroDyn['B2FldMy'] = False # (N-m); Total blade aerodynamic/hydrodynamic load for blade 2 (moment in y-direction); blade root coordinate system +AeroDyn['B2AeroMz'] = False # (N-m); Total blade aerodynamic/hydrodynamic load for blade 2 (moment in z-direction); blade root coordinate system +AeroDyn['B2FldMz'] = False # (N-m); Total blade aerodynamic/hydrodynamic load for blade 2 (moment in z-direction); blade root coordinate system +AeroDyn['B2AeroPwr'] = False # (W); Total aerodynamic/hydrodynamic power from blade 2; +AeroDyn['B2FldPwr'] = False # (W); Total aerodynamic/hydrodynamic power from blade 2; +AeroDyn['B3AeroFx'] = False # (N); Total blade aerodynamic/hydrodynamic load for blade 3 (force in x-direction); blade root coordinate system +AeroDyn['B3FldFx'] = False # (N); Total blade aerodynamic/hydrodynamic load for blade 3 (force in x-direction); blade root coordinate system +AeroDyn['B3AeroFy'] = False # (N); Total blade aerodynamic/hydrodynamic load for blade 3 (force in y-direction); blade root coordinate system +AeroDyn['B3FldFy'] = False # (N); Total blade aerodynamic/hydrodynamic load for blade 3 (force in y-direction); blade root coordinate system +AeroDyn['B3AeroFz'] = False # (N); Total blade aerodynamic/hydrodynamic load for blade 3 (force in z-direction); blade root coordinate system +AeroDyn['B3FldFz'] = False # (N); Total blade aerodynamic/hydrodynamic load for blade 3 (force in z-direction); blade root coordinate system +AeroDyn['B3AeroMx'] = False # (N-m); Total blade aerodynamic/hydrodynamic load for blade 3 (moment in x-direction); blade root coordinate system +AeroDyn['B3FldMx'] = False # (N-m); Total blade aerodynamic/hydrodynamic load for blade 3 (moment in x-direction); blade root coordinate system +AeroDyn['B3AeroMy'] = False # (N-m); Total blade aerodynamic/hydrodynamic load for blade 3 (moment in y-direction); blade root coordinate system +AeroDyn['B3FldMy'] = False # (N-m); Total blade aerodynamic/hydrodynamic load for blade 3 (moment in y-direction); blade root coordinate system +AeroDyn['B3AeroMz'] = False # (N-m); Total blade aerodynamic/hydrodynamic load for blade 3 (moment in z-direction); blade root coordinate system +AeroDyn['B3FldMz'] = False # (N-m); Total blade aerodynamic/hydrodynamic load for blade 3 (moment in z-direction); blade root coordinate system +AeroDyn['B3AeroPwr'] = False # (W); Total aerodynamic/hydrodynamic power from blade 3; +AeroDyn['B3FldPwr'] = False # (W); Total aerodynamic/hydrodynamic power from blade 3; +AeroDyn['B4AeroFx'] = False # (N); Total blade aerodynamic/hydrodynamic load for blade 4 (force in x-direction); blade root coordinate system +AeroDyn['B4FldFx'] = False # (N); Total blade aerodynamic/hydrodynamic load for blade 4 (force in x-direction); blade root coordinate system +AeroDyn['B4AeroFy'] = False # (N); Total blade aerodynamic/hydrodynamic load for blade 4 (force in y-direction); blade root coordinate system +AeroDyn['B4FldFy'] = False # (N); Total blade aerodynamic/hydrodynamic load for blade 4 (force in y-direction); blade root coordinate system +AeroDyn['B4AeroFz'] = False # (N); Total blade aerodynamic/hydrodynamic load for blade 4 (force in z-direction); blade root coordinate system +AeroDyn['B4FldFz'] = False # (N); Total blade aerodynamic/hydrodynamic load for blade 4 (force in z-direction); blade root coordinate system +AeroDyn['B4AeroMx'] = False # (N-m); Total blade aerodynamic/hydrodynamic load for blade 4 (moment in x-direction); blade root coordinate system +AeroDyn['B4FldMx'] = False # (N-m); Total blade aerodynamic/hydrodynamic load for blade 4 (moment in x-direction); blade root coordinate system +AeroDyn['B4AeroMy'] = False # (N-m); Total blade aerodynamic/hydrodynamic load for blade 4 (moment in y-direction); blade root coordinate system +AeroDyn['B4FldMy'] = False # (N-m); Total blade aerodynamic/hydrodynamic load for blade 4 (moment in y-direction); blade root coordinate system +AeroDyn['B4AeroMz'] = False # (N-m); Total blade aerodynamic/hydrodynamic load for blade 4 (moment in z-direction); blade root coordinate system +AeroDyn['B4FldMz'] = False # (N-m); Total blade aerodynamic/hydrodynamic load for blade 4 (moment in z-direction); blade root coordinate system +AeroDyn['B4AeroPwr'] = False # (W); Total aerodynamic/hydrodynamic power from blade 4; +AeroDyn['B4FldPwr'] = False # (W); Total aerodynamic/hydrodynamic power from blade 4; +AeroDyn['B1AeroFxi'] = False # (N); Total blade aerodynamic/hydrodynamic load for blade 1 (force in x-direction); global coordinate system +AeroDyn['B1FldFxi'] = False # (N); Total blade aerodynamic/hydrodynamic load for blade 1 (force in x-direction); global coordinate system +AeroDyn['B1AeroFyi'] = False # (N); Total blade aerodynamic/hydrodynamic load for blade 1 (force in y-direction); global coordinate system +AeroDyn['B1FldFyi'] = False # (N); Total blade aerodynamic/hydrodynamic load for blade 1 (force in y-direction); global coordinate system +AeroDyn['B1AeroFzi'] = False # (N); Total blade aerodynamic/hydrodynamic load for blade 1 (force in z-direction); global coordinate system +AeroDyn['B1FldFzi'] = False # (N); Total blade aerodynamic/hydrodynamic load for blade 1 (force in z-direction); global coordinate system +AeroDyn['B1AeroMxi'] = False # (N-m); Total blade aerodynamic/hydrodynamic load for blade 1 (moment in x-direction); global coordinate system +AeroDyn['B1FldMxi'] = False # (N-m); Total blade aerodynamic/hydrodynamic load for blade 1 (moment in x-direction); global coordinate system +AeroDyn['B1AeroMyi'] = False # (N-m); Total blade aerodynamic/hydrodynamic load for blade 1 (moment in y-direction); global coordinate system +AeroDyn['B1FldMyi'] = False # (N-m); Total blade aerodynamic/hydrodynamic load for blade 1 (moment in y-direction); global coordinate system +AeroDyn['B1AeroMzi'] = False # (N-m); Total blade aerodynamic/hydrodynamic load for blade 1 (moment in z-direction); global coordinate system +AeroDyn['B1FldMzi'] = False # (N-m); Total blade aerodynamic/hydrodynamic load for blade 1 (moment in z-direction); global coordinate system +AeroDyn['B2AeroFxi'] = False # (N); Total blade aerodynamic/hydrodynamic load for blade 2 (force in x-direction); global coordinate system +AeroDyn['B2FldFxi'] = False # (N); Total blade aerodynamic/hydrodynamic load for blade 2 (force in x-direction); global coordinate system +AeroDyn['B2AeroFyi'] = False # (N); Total blade aerodynamic/hydrodynamic load for blade 2 (force in y-direction); global coordinate system +AeroDyn['B2FldFyi'] = False # (N); Total blade aerodynamic/hydrodynamic load for blade 2 (force in y-direction); global coordinate system +AeroDyn['B2AeroFzi'] = False # (N); Total blade aerodynamic/hydrodynamic load for blade 2 (force in z-direction); global coordinate system +AeroDyn['B2FldFzi'] = False # (N); Total blade aerodynamic/hydrodynamic load for blade 2 (force in z-direction); global coordinate system +AeroDyn['B2AeroMxi'] = False # (N-m); Total blade aerodynamic/hydrodynamic load for blade 2 (moment in x-direction); global coordinate system +AeroDyn['B2FldMxi'] = False # (N-m); Total blade aerodynamic/hydrodynamic load for blade 2 (moment in x-direction); global coordinate system +AeroDyn['B2AeroMyi'] = False # (N-m); Total blade aerodynamic/hydrodynamic load for blade 2 (moment in y-direction); global coordinate system +AeroDyn['B2FldMyi'] = False # (N-m); Total blade aerodynamic/hydrodynamic load for blade 2 (moment in y-direction); global coordinate system +AeroDyn['B2AeroMzi'] = False # (N-m); Total blade aerodynamic/hydrodynamic load for blade 2 (moment in z-direction); global coordinate system +AeroDyn['B2FldMzi'] = False # (N-m); Total blade aerodynamic/hydrodynamic load for blade 2 (moment in z-direction); global coordinate system +AeroDyn['B3AeroFxi'] = False # (N); Total blade aerodynamic/hydrodynamic load for blade 3 (force in x-direction); global coordinate system +AeroDyn['B3FldFxi'] = False # (N); Total blade aerodynamic/hydrodynamic load for blade 3 (force in x-direction); global coordinate system +AeroDyn['B3AeroFyi'] = False # (N); Total blade aerodynamic/hydrodynamic load for blade 3 (force in y-direction); global coordinate system +AeroDyn['B3FldFyi'] = False # (N); Total blade aerodynamic/hydrodynamic load for blade 3 (force in y-direction); global coordinate system +AeroDyn['B3AeroFzi'] = False # (N); Total blade aerodynamic/hydrodynamic load for blade 3 (force in z-direction); global coordinate system +AeroDyn['B3FldFzi'] = False # (N); Total blade aerodynamic/hydrodynamic load for blade 3 (force in z-direction); global coordinate system +AeroDyn['B3AeroMxi'] = False # (N-m); Total blade aerodynamic/hydrodynamic load for blade 3 (moment in x-direction); global coordinate system +AeroDyn['B3FldMxi'] = False # (N-m); Total blade aerodynamic/hydrodynamic load for blade 3 (moment in x-direction); global coordinate system +AeroDyn['B3AeroMyi'] = False # (N-m); Total blade aerodynamic/hydrodynamic load for blade 3 (moment in y-direction); global coordinate system +AeroDyn['B3FldMyi'] = False # (N-m); Total blade aerodynamic/hydrodynamic load for blade 3 (moment in y-direction); global coordinate system +AeroDyn['B3AeroMzi'] = False # (N-m); Total blade aerodynamic/hydrodynamic load for blade 3 (moment in z-direction); global coordinate system +AeroDyn['B3FldMzi'] = False # (N-m); Total blade aerodynamic/hydrodynamic load for blade 3 (moment in z-direction); global coordinate system +AeroDyn['B4AeroFxi'] = False # (N); Total blade aerodynamic/hydrodynamic load for blade 4 (force in x-direction); global coordinate system +AeroDyn['B4FldFxi'] = False # (N); Total blade aerodynamic/hydrodynamic load for blade 4 (force in x-direction); global coordinate system +AeroDyn['B4AeroFyi'] = False # (N); Total blade aerodynamic/hydrodynamic load for blade 4 (force in y-direction); global coordinate system +AeroDyn['B4FldFyi'] = False # (N); Total blade aerodynamic/hydrodynamic load for blade 4 (force in y-direction); global coordinate system +AeroDyn['B4AeroFzi'] = False # (N); Total blade aerodynamic/hydrodynamic load for blade 4 (force in z-direction); global coordinate system +AeroDyn['B4FldFzi'] = False # (N); Total blade aerodynamic/hydrodynamic load for blade 4 (force in z-direction); global coordinate system +AeroDyn['B4AeroMxi'] = False # (N-m); Total blade aerodynamic/hydrodynamic load for blade 4 (moment in x-direction); global coordinate system +AeroDyn['B4FldMxi'] = False # (N-m); Total blade aerodynamic/hydrodynamic load for blade 4 (moment in x-direction); global coordinate system +AeroDyn['B4AeroMyi'] = False # (N-m); Total blade aerodynamic/hydrodynamic load for blade 4 (moment in y-direction); global coordinate system +AeroDyn['B4FldMyi'] = False # (N-m); Total blade aerodynamic/hydrodynamic load for blade 4 (moment in y-direction); global coordinate system +AeroDyn['B4AeroMzi'] = False # (N-m); Total blade aerodynamic/hydrodynamic load for blade 4 (moment in z-direction); global coordinate system +AeroDyn['B4FldMzi'] = False # (N-m); Total blade aerodynamic/hydrodynamic load for blade 4 (moment in z-direction); global coordinate system # Blade Nodal outputs AeroDyn['B1N1VUndx'] = False # (m/s); x-component of undisturbed wind velocity at Blade 1, Node 1; local blade coordinate system @@ -3216,25 +1361,1807 @@ AeroDyn['B3N7Gam'] = False # (m^2/s); Circulation on blade 3 at node 7; AeroDyn['B3N8Gam'] = False # (m^2/s); Circulation on blade 3 at node 8; AeroDyn['B3N9Gam'] = False # (m^2/s); Circulation on blade 3 at node 9; +AeroDyn['B1N1Fbn'] = False # (N/m); Buoyant force normal to chord per unit length at blade 1 node 1; +AeroDyn['B1N2Fbn'] = False # (N/m); Buoyant force normal to chord per unit length at blade 1 node 2; +AeroDyn['B1N3Fbn'] = False # (N/m); Buoyant force normal to chord per unit length at blade 1 node 3; +AeroDyn['B1N4Fbn'] = False # (N/m); Buoyant force normal to chord per unit length at blade 1 node 4; +AeroDyn['B1N5Fbn'] = False # (N/m); Buoyant force normal to chord per unit length at blade 1 node 5; +AeroDyn['B1N6Fbn'] = False # (N/m); Buoyant force normal to chord per unit length at blade 1 node 6; +AeroDyn['B1N7Fbn'] = False # (N/m); Buoyant force normal to chord per unit length at blade 1 node 7; +AeroDyn['B1N8Fbn'] = False # (N/m); Buoyant force normal to chord per unit length at blade 1 node 8; +AeroDyn['B1N9Fbn'] = False # (N/m); Buoyant force normal to chord per unit length at blade 1 node 9; +AeroDyn['B2N1Fbn'] = False # (N/m); Buoyant force normal to chord per unit length at blade 2 node 1; +AeroDyn['B2N2Fbn'] = False # (N/m); Buoyant force normal to chord per unit length at blade 2 node 2; +AeroDyn['B2N3Fbn'] = False # (N/m); Buoyant force normal to chord per unit length at blade 2 node 3; +AeroDyn['B2N4Fbn'] = False # (N/m); Buoyant force normal to chord per unit length at blade 2 node 4; +AeroDyn['B2N5Fbn'] = False # (N/m); Buoyant force normal to chord per unit length at blade 2 node 5; +AeroDyn['B2N6Fbn'] = False # (N/m); Buoyant force normal to chord per unit length at blade 2 node 6; +AeroDyn['B2N7Fbn'] = False # (N/m); Buoyant force normal to chord per unit length at blade 2 node 7; +AeroDyn['B2N8Fbn'] = False # (N/m); Buoyant force normal to chord per unit length at blade 2 node 8; +AeroDyn['B2N9Fbn'] = False # (N/m); Buoyant force normal to chord per unit length at blade 2 node 9; +AeroDyn['B3N1Fbn'] = False # (N/m); Buoyant force normal to chord per unit length at blade 3 node 1; +AeroDyn['B3N2Fbn'] = False # (N/m); Buoyant force normal to chord per unit length at blade 3 node 2; +AeroDyn['B3N3Fbn'] = False # (N/m); Buoyant force normal to chord per unit length at blade 3 node 3; +AeroDyn['B3N4Fbn'] = False # (N/m); Buoyant force normal to chord per unit length at blade 3 node 4; +AeroDyn['B3N5Fbn'] = False # (N/m); Buoyant force normal to chord per unit length at blade 3 node 5; +AeroDyn['B3N6Fbn'] = False # (N/m); Buoyant force normal to chord per unit length at blade 3 node 6; +AeroDyn['B3N7Fbn'] = False # (N/m); Buoyant force normal to chord per unit length at blade 3 node 7; +AeroDyn['B3N8Fbn'] = False # (N/m); Buoyant force normal to chord per unit length at blade 3 node 8; +AeroDyn['B3N9Fbn'] = False # (N/m); Buoyant force normal to chord per unit length at blade 3 node 9; +AeroDyn['B1N1Fbt'] = False # (N/m); Buoyant force tangential to chord per unit length at blade 1 node 1; +AeroDyn['B1N2Fbt'] = False # (N/m); Buoyant force tangential to chord per unit length at blade 1 node 2; +AeroDyn['B1N3Fbt'] = False # (N/m); Buoyant force tangential to chord per unit length at blade 1 node 3; +AeroDyn['B1N4Fbt'] = False # (N/m); Buoyant force tangential to chord per unit length at blade 1 node 4; +AeroDyn['B1N5Fbt'] = False # (N/m); Buoyant force tangential to chord per unit length at blade 1 node 5; +AeroDyn['B1N6Fbt'] = False # (N/m); Buoyant force tangential to chord per unit length at blade 1 node 6; +AeroDyn['B1N7Fbt'] = False # (N/m); Buoyant force tangential to chord per unit length at blade 1 node 7; +AeroDyn['B1N8Fbt'] = False # (N/m); Buoyant force tangential to chord per unit length at blade 1 node 8; +AeroDyn['B1N9Fbt'] = False # (N/m); Buoyant force tangential to chord per unit length at blade 1 node 9; +AeroDyn['B2N1Fbt'] = False # (N/m); Buoyant force tangential to chord per unit length at blade 2 node 1; +AeroDyn['B2N2Fbt'] = False # (N/m); Buoyant force tangential to chord per unit length at blade 2 node 2; +AeroDyn['B2N3Fbt'] = False # (N/m); Buoyant force tangential to chord per unit length at blade 2 node 3; +AeroDyn['B2N4Fbt'] = False # (N/m); Buoyant force tangential to chord per unit length at blade 2 node 4; +AeroDyn['B2N5Fbt'] = False # (N/m); Buoyant force tangential to chord per unit length at blade 2 node 5; +AeroDyn['B2N6Fbt'] = False # (N/m); Buoyant force tangential to chord per unit length at blade 2 node 6; +AeroDyn['B2N7Fbt'] = False # (N/m); Buoyant force tangential to chord per unit length at blade 2 node 7; +AeroDyn['B2N8Fbt'] = False # (N/m); Buoyant force tangential to chord per unit length at blade 2 node 8; +AeroDyn['B2N9Fbt'] = False # (N/m); Buoyant force tangential to chord per unit length at blade 2 node 9; +AeroDyn['B3N1Fbt'] = False # (N/m); Buoyant force tangential to chord per unit length at blade 3 node 1; +AeroDyn['B3N2Fbt'] = False # (N/m); Buoyant force tangential to chord per unit length at blade 3 node 2; +AeroDyn['B3N3Fbt'] = False # (N/m); Buoyant force tangential to chord per unit length at blade 3 node 3; +AeroDyn['B3N4Fbt'] = False # (N/m); Buoyant force tangential to chord per unit length at blade 3 node 4; +AeroDyn['B3N5Fbt'] = False # (N/m); Buoyant force tangential to chord per unit length at blade 3 node 5; +AeroDyn['B3N6Fbt'] = False # (N/m); Buoyant force tangential to chord per unit length at blade 3 node 6; +AeroDyn['B3N7Fbt'] = False # (N/m); Buoyant force tangential to chord per unit length at blade 3 node 7; +AeroDyn['B3N8Fbt'] = False # (N/m); Buoyant force tangential to chord per unit length at blade 3 node 8; +AeroDyn['B3N9Fbt'] = False # (N/m); Buoyant force tangential to chord per unit length at blade 3 node 9; +AeroDyn['B1N1Fbs'] = False # (N/m); Buoyant spanwise force per unit length at blade 1 node 1; +AeroDyn['B1N2Fbs'] = False # (N/m); Buoyant spanwise force per unit length at blade 1 node 2; +AeroDyn['B1N3Fbs'] = False # (N/m); Buoyant spanwise force per unit length at blade 1 node 3; +AeroDyn['B1N4Fbs'] = False # (N/m); Buoyant spanwise force per unit length at blade 1 node 4; +AeroDyn['B1N5Fbs'] = False # (N/m); Buoyant spanwise force per unit length at blade 1 node 5; +AeroDyn['B1N6Fbs'] = False # (N/m); Buoyant spanwise force per unit length at blade 1 node 6; +AeroDyn['B1N7Fbs'] = False # (N/m); Buoyant spanwise force per unit length at blade 1 node 7; +AeroDyn['B1N8Fbs'] = False # (N/m); Buoyant spanwise force per unit length at blade 1 node 8; +AeroDyn['B1N9Fbs'] = False # (N/m); Buoyant spanwise force per unit length at blade 1 node 9; +AeroDyn['B2N1Fbs'] = False # (N/m); Buoyant spanwise force per unit length at blade 2 node 1; +AeroDyn['B2N2Fbs'] = False # (N/m); Buoyant spanwise force per unit length at blade 2 node 2; +AeroDyn['B2N3Fbs'] = False # (N/m); Buoyant spanwise force per unit length at blade 2 node 3; +AeroDyn['B2N4Fbs'] = False # (N/m); Buoyant spanwise force per unit length at blade 2 node 4; +AeroDyn['B2N5Fbs'] = False # (N/m); Buoyant spanwise force per unit length at blade 2 node 5; +AeroDyn['B2N6Fbs'] = False # (N/m); Buoyant spanwise force per unit length at blade 2 node 6; +AeroDyn['B2N7Fbs'] = False # (N/m); Buoyant spanwise force per unit length at blade 2 node 7; +AeroDyn['B2N8Fbs'] = False # (N/m); Buoyant spanwise force per unit length at blade 2 node 8; +AeroDyn['B2N9Fbs'] = False # (N/m); Buoyant spanwise force per unit length at blade 2 node 9; +AeroDyn['B3N1Fbs'] = False # (N/m); Buoyant spanwise force per unit length at blade 3 node 1; +AeroDyn['B3N2Fbs'] = False # (N/m); Buoyant spanwise force per unit length at blade 3 node 2; +AeroDyn['B3N3Fbs'] = False # (N/m); Buoyant spanwise force per unit length at blade 3 node 3; +AeroDyn['B3N4Fbs'] = False # (N/m); Buoyant spanwise force per unit length at blade 3 node 4; +AeroDyn['B3N5Fbs'] = False # (N/m); Buoyant spanwise force per unit length at blade 3 node 5; +AeroDyn['B3N6Fbs'] = False # (N/m); Buoyant spanwise force per unit length at blade 3 node 6; +AeroDyn['B3N7Fbs'] = False # (N/m); Buoyant spanwise force per unit length at blade 3 node 7; +AeroDyn['B3N8Fbs'] = False # (N/m); Buoyant spanwise force per unit length at blade 3 node 8; +AeroDyn['B3N9Fbs'] = False # (N/m); Buoyant spanwise force per unit length at blade 3 node 9; +AeroDyn['B1N1Mbn'] = False # (N-m/m); Buoyant moment normal to chord per unit length at blade 1 node 1; +AeroDyn['B1N2Mbn'] = False # (N-m/m); Buoyant moment normal to chord per unit length at blade 1 node 2; +AeroDyn['B1N3Mbn'] = False # (N-m/m); Buoyant moment normal to chord per unit length at blade 1 node 3; +AeroDyn['B1N4Mbn'] = False # (N-m/m); Buoyant moment normal to chord per unit length at blade 1 node 4; +AeroDyn['B1N5Mbn'] = False # (N-m/m); Buoyant moment normal to chord per unit length at blade 1 node 5; +AeroDyn['B1N6Mbn'] = False # (N-m/m); Buoyant moment normal to chord per unit length at blade 1 node 6; +AeroDyn['B1N7Mbn'] = False # (N-m/m); Buoyant moment normal to chord per unit length at blade 1 node 7; +AeroDyn['B1N8Mbn'] = False # (N-m/m); Buoyant moment normal to chord per unit length at blade 1 node 8; +AeroDyn['B1N9Mbn'] = False # (N-m/m); Buoyant moment normal to chord per unit length at blade 1 node 9; +AeroDyn['B2N1Mbn'] = False # (N-m/m); Buoyant moment normal to chord per unit length at blade 2 node 1; +AeroDyn['B2N2Mbn'] = False # (N-m/m); Buoyant moment normal to chord per unit length at blade 2 node 2; +AeroDyn['B2N3Mbn'] = False # (N-m/m); Buoyant moment normal to chord per unit length at blade 2 node 3; +AeroDyn['B2N4Mbn'] = False # (N-m/m); Buoyant moment normal to chord per unit length at blade 2 node 4; +AeroDyn['B2N5Mbn'] = False # (N-m/m); Buoyant moment normal to chord per unit length at blade 2 node 5; +AeroDyn['B2N6Mbn'] = False # (N-m/m); Buoyant moment normal to chord per unit length at blade 2 node 6; +AeroDyn['B2N7Mbn'] = False # (N-m/m); Buoyant moment normal to chord per unit length at blade 2 node 7; +AeroDyn['B2N8Mbn'] = False # (N-m/m); Buoyant moment normal to chord per unit length at blade 2 node 8; +AeroDyn['B2N9Mbn'] = False # (N-m/m); Buoyant moment normal to chord per unit length at blade 2 node 9; +AeroDyn['B3N1Mbn'] = False # (N-m/m); Buoyant moment normal to chord per unit length at blade 3 node 1; +AeroDyn['B3N2Mbn'] = False # (N-m/m); Buoyant moment normal to chord per unit length at blade 3 node 2; +AeroDyn['B3N3Mbn'] = False # (N-m/m); Buoyant moment normal to chord per unit length at blade 3 node 3; +AeroDyn['B3N4Mbn'] = False # (N-m/m); Buoyant moment normal to chord per unit length at blade 3 node 4; +AeroDyn['B3N5Mbn'] = False # (N-m/m); Buoyant moment normal to chord per unit length at blade 3 node 5; +AeroDyn['B3N6Mbn'] = False # (N-m/m); Buoyant moment normal to chord per unit length at blade 3 node 6; +AeroDyn['B3N7Mbn'] = False # (N-m/m); Buoyant moment normal to chord per unit length at blade 3 node 7; +AeroDyn['B3N8Mbn'] = False # (N-m/m); Buoyant moment normal to chord per unit length at blade 3 node 8; +AeroDyn['B3N9Mbn'] = False # (N-m/m); Buoyant moment normal to chord per unit length at blade 3 node 9; +AeroDyn['B1N1Mbt'] = False # (N-m/m); Buoyant moment tangential to chord per unit length at blade 1 node 1; +AeroDyn['B1N2Mbt'] = False # (N-m/m); Buoyant moment tangential to chord per unit length at blade 1 node 2; +AeroDyn['B1N3Mbt'] = False # (N-m/m); Buoyant moment tangential to chord per unit length at blade 1 node 3; +AeroDyn['B1N4Mbt'] = False # (N-m/m); Buoyant moment tangential to chord per unit length at blade 1 node 4; +AeroDyn['B1N5Mbt'] = False # (N-m/m); Buoyant moment tangential to chord per unit length at blade 1 node 5; +AeroDyn['B1N6Mbt'] = False # (N-m/m); Buoyant moment tangential to chord per unit length at blade 1 node 6; +AeroDyn['B1N7Mbt'] = False # (N-m/m); Buoyant moment tangential to chord per unit length at blade 1 node 7; +AeroDyn['B1N8Mbt'] = False # (N-m/m); Buoyant moment tangential to chord per unit length at blade 1 node 8; +AeroDyn['B1N9Mbt'] = False # (N-m/m); Buoyant moment tangential to chord per unit length at blade 1 node 9; +AeroDyn['B2N1Mbt'] = False # (N-m/m); Buoyant moment tangential to chord per unit length at blade 2 node 1; +AeroDyn['B2N2Mbt'] = False # (N-m/m); Buoyant moment tangential to chord per unit length at blade 2 node 2; +AeroDyn['B2N3Mbt'] = False # (N-m/m); Buoyant moment tangential to chord per unit length at blade 2 node 3; +AeroDyn['B2N4Mbt'] = False # (N-m/m); Buoyant moment tangential to chord per unit length at blade 2 node 4; +AeroDyn['B2N5Mbt'] = False # (N-m/m); Buoyant moment tangential to chord per unit length at blade 2 node 5; +AeroDyn['B2N6Mbt'] = False # (N-m/m); Buoyant moment tangential to chord per unit length at blade 2 node 6; +AeroDyn['B2N7Mbt'] = False # (N-m/m); Buoyant moment tangential to chord per unit length at blade 2 node 7; +AeroDyn['B2N8Mbt'] = False # (N-m/m); Buoyant moment tangential to chord per unit length at blade 2 node 8; +AeroDyn['B2N9Mbt'] = False # (N-m/m); Buoyant moment tangential to chord per unit length at blade 2 node 9; +AeroDyn['B3N1Mbt'] = False # (N-m/m); Buoyant moment tangential to chord per unit length at blade 3 node 1; +AeroDyn['B3N2Mbt'] = False # (N-m/m); Buoyant moment tangential to chord per unit length at blade 3 node 2; +AeroDyn['B3N3Mbt'] = False # (N-m/m); Buoyant moment tangential to chord per unit length at blade 3 node 3; +AeroDyn['B3N4Mbt'] = False # (N-m/m); Buoyant moment tangential to chord per unit length at blade 3 node 4; +AeroDyn['B3N5Mbt'] = False # (N-m/m); Buoyant moment tangential to chord per unit length at blade 3 node 5; +AeroDyn['B3N6Mbt'] = False # (N-m/m); Buoyant moment tangential to chord per unit length at blade 3 node 6; +AeroDyn['B3N7Mbt'] = False # (N-m/m); Buoyant moment tangential to chord per unit length at blade 3 node 7; +AeroDyn['B3N8Mbt'] = False # (N-m/m); Buoyant moment tangential to chord per unit length at blade 3 node 8; +AeroDyn['B3N9Mbt'] = False # (N-m/m); Buoyant moment tangential to chord per unit length at blade 3 node 9; +AeroDyn['B1N1Mbs'] = False # (N-m/m); Buoyant spanwise moment per unit length at blade 1 node 1; +AeroDyn['B1N2Mbs'] = False # (N-m/m); Buoyant spanwise moment per unit length at blade 1 node 2; +AeroDyn['B1N3Mbs'] = False # (N-m/m); Buoyant spanwise moment per unit length at blade 1 node 3; +AeroDyn['B1N4Mbs'] = False # (N-m/m); Buoyant spanwise moment per unit length at blade 1 node 4; +AeroDyn['B1N5Mbs'] = False # (N-m/m); Buoyant spanwise moment per unit length at blade 1 node 5; +AeroDyn['B1N6Mbs'] = False # (N-m/m); Buoyant spanwise moment per unit length at blade 1 node 6; +AeroDyn['B1N7Mbs'] = False # (N-m/m); Buoyant spanwise moment per unit length at blade 1 node 7; +AeroDyn['B1N8Mbs'] = False # (N-m/m); Buoyant spanwise moment per unit length at blade 1 node 8; +AeroDyn['B1N9Mbs'] = False # (N-m/m); Buoyant spanwise moment per unit length at blade 1 node 9; +AeroDyn['B2N1Mbs'] = False # (N-m/m); Buoyant spanwise moment per unit length at blade 2 node 1; +AeroDyn['B2N2Mbs'] = False # (N-m/m); Buoyant spanwise moment per unit length at blade 2 node 2; +AeroDyn['B2N3Mbs'] = False # (N-m/m); Buoyant spanwise moment per unit length at blade 2 node 3; +AeroDyn['B2N4Mbs'] = False # (N-m/m); Buoyant spanwise moment per unit length at blade 2 node 4; +AeroDyn['B2N5Mbs'] = False # (N-m/m); Buoyant spanwise moment per unit length at blade 2 node 5; +AeroDyn['B2N6Mbs'] = False # (N-m/m); Buoyant spanwise moment per unit length at blade 2 node 6; +AeroDyn['B2N7Mbs'] = False # (N-m/m); Buoyant spanwise moment per unit length at blade 2 node 7; +AeroDyn['B2N8Mbs'] = False # (N-m/m); Buoyant spanwise moment per unit length at blade 2 node 8; +AeroDyn['B2N9Mbs'] = False # (N-m/m); Buoyant spanwise moment per unit length at blade 2 node 9; +AeroDyn['B3N1Mbs'] = False # (N-m/m); Buoyant spanwise moment per unit length at blade 3 node 1; +AeroDyn['B3N2Mbs'] = False # (N-m/m); Buoyant spanwise moment per unit length at blade 3 node 2; +AeroDyn['B3N3Mbs'] = False # (N-m/m); Buoyant spanwise moment per unit length at blade 3 node 3; +AeroDyn['B3N4Mbs'] = False # (N-m/m); Buoyant spanwise moment per unit length at blade 3 node 4; +AeroDyn['B3N5Mbs'] = False # (N-m/m); Buoyant spanwise moment per unit length at blade 3 node 5; +AeroDyn['B3N6Mbs'] = False # (N-m/m); Buoyant spanwise moment per unit length at blade 3 node 6; +AeroDyn['B3N7Mbs'] = False # (N-m/m); Buoyant spanwise moment per unit length at blade 3 node 7; +AeroDyn['B3N8Mbs'] = False # (N-m/m); Buoyant spanwise moment per unit length at blade 3 node 8; +AeroDyn['B3N9Mbs'] = False # (N-m/m); Buoyant spanwise moment per unit length at blade 3 node 9; + +# Rotor +AeroDyn['RtSpeed'] = False # (rpm); Rotor speed; +AeroDyn['RtTSR'] = False # (-); Rotor tip-speed ratio; +AeroDyn['RtVAvgxh'] = False # (m/s); Rotor-disk-averaged relative wind velocity (x-component); the hub coordinate system +AeroDyn['RtVAvgyh'] = False # (m/s); Rotor-disk-averaged relative wind velocity (y-component); the hub coordinate system +AeroDyn['RtVAvgzh'] = False # (m/s); Rotor-disk-averaged relative wind velocity (z-component); the hub coordinate system +AeroDyn['RtSkew'] = False # (deg); Rotor inflow-skew angle; +AeroDyn['RtAeroFxh'] = False # (N); Total rotor aerodynamic/hydrodynamic and buoyant load (force in x direction); the hub coordinate system +AeroDyn['RtFldFxh'] = False # (N); Total rotor aerodynamic/hydrodynamic and buoyant load (force in x direction); the hub coordinate system +AeroDyn['RtAeroFyh'] = False # (N); Total rotor aerodynamic/hydrodynamic and buoyant load (force in y direction); the hub coordinate system +AeroDyn['RtFldFyh'] = False # (N); Total rotor aerodynamic/hydrodynamic and buoyant load (force in y direction); the hub coordinate system +AeroDyn['RtAeroFzh'] = False # (N); Total rotor aerodynamic/hydrodynamic and buoyant load (force in z direction); the hub coordinate system +AeroDyn['RtFldFzh'] = False # (N); Total rotor aerodynamic/hydrodynamic and buoyant load (force in z direction); the hub coordinate system +AeroDyn['RtAeroMxh'] = False # (N-m); Total rotor aerodynamic/hydrodynamic and buoyant load (moment in x direction); the hub coordinate system +AeroDyn['RtFldMxh'] = False # (N-m); Total rotor aerodynamic/hydrodynamic and buoyant load (moment in x direction); the hub coordinate system +AeroDyn['RtAeroMyh'] = False # (N-m); Total rotor aerodynamic/hydrodynamic and buoyant load (moment in y direction); the hub coordinate system +AeroDyn['RtFldMyh'] = False # (N-m); Total rotor aerodynamic/hydrodynamic and buoyant load (moment in y direction); the hub coordinate system +AeroDyn['RtAeroMzh'] = False # (N-m); Total rotor aerodynamic/hydrodynamic and buoyant load (moment in z direction); the hub coordinate system +AeroDyn['RtFldMzh'] = False # (N-m); Total rotor aerodynamic/hydrodynamic and buoyant load (moment in z direction); the hub coordinate system +AeroDyn['RtAeroPwr'] = False # (W); Rotor aerodynamic/hydrodynamic power; +AeroDyn['RtFldPwr'] = False # (W); Rotor aerodynamic/hydrodynamic power; +AeroDyn['RtArea'] = False # (m^2); Rotor swept area; +AeroDyn['RtAeroCp'] = False # (-); Rotor aerodynamic/hydrodynamic power coefficient; +AeroDyn['RtFldCp'] = False # (-); Rotor aerodynamic/hydrodynamic power coefficient; +AeroDyn['RtAeroCq'] = False # (-); Rotor aerodynamic/hydrodynamic torque coefficient; +AeroDyn['RtFldCq'] = False # (-); Rotor aerodynamic/hydrodynamic torque coefficient; +AeroDyn['RtAeroCt'] = False # (-); Rotor aerodynamic/hydrodynamic thrust coefficient; +AeroDyn['RtFldCt'] = False # (-); Rotor aerodynamic/hydrodynamic thrust coefficient; +AeroDyn['DBEMTau1'] = False # (s); time-constant used in DBEMT; +AeroDyn['RtAeroFxi'] = False # (N); Total rotor aerodynamic/hydrodynamic and buoyant load (force in x direction); global coordinate system +AeroDyn['RtFldFxi'] = False # (N); Total rotor aerodynamic/hydrodynamic and buoyant load (force in x direction); global coordinate system +AeroDyn['RtFldFxg'] = False # (N); Total rotor aerodynamic/hydrodynamic and buoyant load (force in x direction); global coordinate system +AeroDyn['RtAeroFyi'] = False # (N); Total rotor aerodynamic/hydrodynamic and buoyant load (force in y direction); global coordinate system +AeroDyn['RtFldFyi'] = False # (N); Total rotor aerodynamic/hydrodynamic and buoyant load (force in y direction); global coordinate system +AeroDyn['RtFldFyg'] = False # (N); Total rotor aerodynamic/hydrodynamic and buoyant load (force in y direction); global coordinate system +AeroDyn['RtAeroFzi'] = False # (N); Total rotor aerodynamic/hydrodynamic and buoyant load (force in z direction); global coordinate system +AeroDyn['RtFldFzi'] = False # (N); Total rotor aerodynamic/hydrodynamic and buoyant load (force in z direction); global coordinate system +AeroDyn['RtFldFzg'] = False # (N); Total rotor aerodynamic/hydrodynamic and buoyant load (force in z direction); global coordinate system +AeroDyn['RtAeroMxi'] = False # (N-m); Total rotor aerodynamic/hydrodynamic and buoyant load (moment in x direction); global coordinate system +AeroDyn['RtFldMxi'] = False # (N-m); Total rotor aerodynamic/hydrodynamic and buoyant load (moment in x direction); global coordinate system +AeroDyn['RtFldMxg'] = False # (N-m); Total rotor aerodynamic/hydrodynamic and buoyant load (moment in x direction); global coordinate system +AeroDyn['RtAeroMyi'] = False # (N-m); Total rotor aerodynamic/hydrodynamic and buoyant load (moment in y direction); global coordinate system +AeroDyn['RtFldMyi'] = False # (N-m); Total rotor aerodynamic/hydrodynamic and buoyant load (moment in y direction); global coordinate system +AeroDyn['RtFldMyg'] = False # (N-m); Total rotor aerodynamic/hydrodynamic and buoyant load (moment in y direction); global coordinate system +AeroDyn['RtAeroMzi'] = False # (N-m); Total rotor aerodynamic/hydrodynamic and buoyant load (moment in z direction); global coordinate system +AeroDyn['RtFldMzi'] = False # (N-m); Total rotor aerodynamic/hydrodynamic and buoyant load (moment in z direction); global coordinate system +AeroDyn['RtFldMzg'] = False # (N-m); Total rotor aerodynamic/hydrodynamic and buoyant load (moment in z direction); global coordinate system + +# Hub +AeroDyn['HbFbx'] = False # (N); x-component of buoyant force at hub node; the hub coordinate system +AeroDyn['HbFby'] = False # (N); y-component of buoyant force at hub node; the hub coordinate system +AeroDyn['HbFbz'] = False # (N); z-component of buoyant force at hub node; the hub coordinate system +AeroDyn['HbMbx'] = False # (N-m); x-component of buoyant moment at hub node; the hub coordinate system +AeroDyn['HbMby'] = False # (N-m); y-component of buoyant moment at hub node; the hub coordinate system +AeroDyn['HbMbz'] = False # (N-m); z-component of buoyant moment at hub node; the hub coordinate system + +# Nacelle +AeroDyn['NcFbx'] = False # (N); x-component of buoyant force at nacelle node; the nacelle coordinate system +AeroDyn['NcFby'] = False # (N); y-component of buoyant force at nacelle node; the nacelle coordinate system +AeroDyn['NcFbz'] = False # (N); z-component of buoyant force at nacelle node; the nacelle coordinate system +AeroDyn['NcMbx'] = False # (N-m); x-component of buoyant moment at nacelle node; the nacelle coordinate system +AeroDyn['NcMby'] = False # (N-m); y-component of buoyant moment at nacelle node; the nacelle coordinate system +AeroDyn['NcMbz'] = False # (N-m); z-component of buoyant moment at nacelle node; the nacelle coordinate system + +# TailFin +AeroDyn['TFAlpha'] = False # (deg); Angle of attack of tailfin; tailfin coordinate system +AeroDyn['TFMach '] = False # (-); Mach number of tailfin flow; tailfin coordinate system +AeroDyn['TFRe '] = False # (-); Reynolds number of tailfin flow; tailfin coordinate system +AeroDyn['TFVrel '] = False # (m/s); Orthogonal relative velocity norm at the tailfin reference point; tailfin coordinate system +AeroDyn['TFVundxi'] = False # (m/s); Undisturbed wind velocity at the tailfin reference point in the inertial system (x-direction); global coordinate system +AeroDyn['TFVundyi'] = False # (m/s); Undisturbed wind velocity at the tailfin reference point in the inertial system (y-direction); global coordinate system +AeroDyn['TFVundzi'] = False # (m/s); Undisturbed wind velocity at the tailfin reference point in the inertial system (z-direction); global coordinate system +AeroDyn['TFVindxi'] = False # (m/s); Induced velocity at the tailfin reference point in the inertial system (x-direction); global coordinate system +AeroDyn['TFVindyi'] = False # (m/s); Induced velocity at the tailfin reference point in the inertial system (y-direction); global coordinate system +AeroDyn['TFVindzi'] = False # (m/s); Induced velocity at the tailfin reference point in the inertial system (z-direction); global coordinate system +AeroDyn['TFVrelxi'] = False # (m/s); Relative velocity at the tailfin reference point in the inertial system (x-direction); global coordinate system +AeroDyn['TFVrelyi'] = False # (m/s); Relative velocity at the tailfin reference point in the inertial system (y-direction); global coordinate system +AeroDyn['TFVrelzi'] = False # (m/s); Relative velocity at the tailfin reference point in the inertial system (z-direction); global coordinate system +AeroDyn['TFSTVxi'] = False # (m/s); Structural velocity at the tailfin reference point in the inertial system (x-direction); global coordinate system +AeroDyn['TFSTVyi'] = False # (m/s); Structural velocity at the tailfin reference point in the inertial system (y-direction); global coordinate system +AeroDyn['TFSTVzi'] = False # (m/s); Structural velocity at the tailfin reference point in the inertial system (z-direction); global coordinate system +AeroDyn['TFFxi'] = False # (N); Force at the tailfin reference point in the inertial system (x-direction); global coordinate system +AeroDyn['TFFyi'] = False # (N); Force at the tailfin reference point in the inertial system (y-direction); global coordinate system +AeroDyn['TFFzi'] = False # (N); Force at the tailfin reference point in the inertial system (z-direction); global coordinate system +AeroDyn['TFMxi'] = False # (N-m); Moment at the tailfin reference point in the inertial system (x-direction); global coordinate system +AeroDyn['TFMyi'] = False # (N-m); Moment at the tailfin reference point in the inertial system (y-direction); global coordinate system +AeroDyn['TFMzi'] = False # (N-m); Moment at the tailfin reference point in the inertial system (z-direction); global coordinate system + + +""" BeamDyn """ +BeamDyn = {} + +# Reaction Loads +BeamDyn['RootFxr'] = False # (N); x-component of the root reaction force expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system +BeamDyn['RootFyr'] = False # (N); y-component of the root reaction force expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system +BeamDyn['RootFzr'] = False # (N); z-component of the root reaction force expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system +BeamDyn['RootMxr'] = False # (N-m); x-component of the root reaction moment expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system +BeamDyn['RootMyr'] = False # (N-m); y-component of the root reaction moment expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system +BeamDyn['RootMzr'] = False # (N-m); z-component of the root reaction moment expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system + +# Tip Motions +BeamDyn['TipTDxr'] = False # (m); Tip translational deflection (relative to the undeflected position) expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system +BeamDyn['TipTDyr'] = False # (m); Tip translational deflection (relative to the undeflected position) expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system +BeamDyn['TipTDzr'] = False # (m); Tip translational deflection (relative to the undeflected position) expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system +BeamDyn['TipRDxr'] = False # (-); Tip angular/rotational deflection Wiener-Milenkovi parameter (relative to the undeflected orientation) expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system +BeamDyn['TipRDyr'] = False # (-); Tip angular/rotational deflection Wiener-Milenkovi parameter (relative to the undeflected orientation) expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system +BeamDyn['TipRDzr'] = False # (-); Tip angular/rotational deflection Wiener-Milenkovi parameter (relative to the undeflected orientation) expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system +BeamDyn['TipTVXg'] = False # (m/s); Tip translational velocities (absolute) expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system +BeamDyn['TipTVYg'] = False # (m/s); Tip translational velocities (absolute) expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system +BeamDyn['TipTVZg'] = False # (m/s); Tip translational velocities (absolute) expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system +BeamDyn['TipRVXg'] = False # (deg/s); Tip angular/rotational velocities (absolute) expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system +BeamDyn['TipRVYg'] = False # (deg/s); Tip angular/rotational velocities (absolute) expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system +BeamDyn['TipRVZg'] = False # (deg/s); Tip angular/rotational velocities (absolute) expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system +BeamDyn['TipTAXl'] = False # (m/s^2); Tip translational accelerations (absolute) expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['TipTAYl'] = False # (m/s^2); Tip translational accelerations (absolute) expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['TipTAZl'] = False # (m/s^2); Tip translational accelerations (absolute) expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['TipRAXl'] = False # (deg/s^2); Tip angular/rotational accelerations (absolute) expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['TipRAYl'] = False # (deg/s^2); Tip angular/rotational accelerations (absolute) expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['TipRAZl'] = False # (deg/s^2); Tip angular/rotational accelerations (absolute) expressed in l; l: a floating coordinate system local to the deflected beam + +# Sectional Loads +BeamDyn['N1Fxl'] = False # (N); Sectional force resultants at Node 1 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N1Fyl'] = False # (N); Sectional force resultants at Node 1 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N1Fzl'] = False # (N); Sectional force resultants at Node 1 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N2Fxl'] = False # (N); Sectional force resultants at Node 2 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N2Fyl'] = False # (N); Sectional force resultants at Node 2 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N2Fzl'] = False # (N); Sectional force resultants at Node 2 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N3Fxl'] = False # (N); Sectional force resultants at Node 3 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N3Fyl'] = False # (N); Sectional force resultants at Node 3 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N3Fzl'] = False # (N); Sectional force resultants at Node 3 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N4Fxl'] = False # (N); Sectional force resultants at Node 4 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N4Fyl'] = False # (N); Sectional force resultants at Node 4 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N4Fzl'] = False # (N); Sectional force resultants at Node 4 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N5Fxl'] = False # (N); Sectional force resultants at Node 5 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N5Fyl'] = False # (N); Sectional force resultants at Node 5 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N5Fzl'] = False # (N); Sectional force resultants at Node 5 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N6Fxl'] = False # (N); Sectional force resultants at Node 6 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N6Fyl'] = False # (N); Sectional force resultants at Node 6 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N6Fzl'] = False # (N); Sectional force resultants at Node 6 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N7Fxl'] = False # (N); Sectional force resultants at Node 7 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N7Fyl'] = False # (N); Sectional force resultants at Node 7 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N7Fzl'] = False # (N); Sectional force resultants at Node 7 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N8Fxl'] = False # (N); Sectional force resultants at Node 8 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N8Fyl'] = False # (N); Sectional force resultants at Node 8 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N8Fzl'] = False # (N); Sectional force resultants at Node 8 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N9Fxl'] = False # (N); Sectional force resultants at Node 9 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N9Fyl'] = False # (N); Sectional force resultants at Node 9 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N9Fzl'] = False # (N); Sectional force resultants at Node 9 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N1Mxl'] = False # (N-m); Sectional moment resultants at Node 1 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N1Myl'] = False # (N-m); Sectional moment resultants at Node 1 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N1Mzl'] = False # (N-m); Sectional moment resultants at Node 1 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N2Mxl'] = False # (N-m); Sectional moment resultants at Node 2 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N2Myl'] = False # (N-m); Sectional moment resultants at Node 2 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N2Mzl'] = False # (N-m); Sectional moment resultants at Node 2 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N3Mxl'] = False # (N-m); Sectional moment resultants at Node 3 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N3Myl'] = False # (N-m); Sectional moment resultants at Node 3 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N3Mzl'] = False # (N-m); Sectional moment resultants at Node 3 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N4Mxl'] = False # (N-m); Sectional moment resultants at Node 4 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N4Myl'] = False # (N-m); Sectional moment resultants at Node 4 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N4Mzl'] = False # (N-m); Sectional moment resultants at Node 4 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N5Mxl'] = False # (N-m); Sectional moment resultants at Node 5 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N5Myl'] = False # (N-m); Sectional moment resultants at Node 5 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N5Mzl'] = False # (N-m); Sectional moment resultants at Node 5 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N6Mxl'] = False # (N-m); Sectional moment resultants at Node 6 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N6Myl'] = False # (N-m); Sectional moment resultants at Node 6 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N6Mzl'] = False # (N-m); Sectional moment resultants at Node 6 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N7Mxl'] = False # (N-m); Sectional moment resultants at Node 7 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N7Myl'] = False # (N-m); Sectional moment resultants at Node 7 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N7Mzl'] = False # (N-m); Sectional moment resultants at Node 7 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N8Mxl'] = False # (N-m); Sectional moment resultants at Node 8 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N8Myl'] = False # (N-m); Sectional moment resultants at Node 8 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N8Mzl'] = False # (N-m); Sectional moment resultants at Node 8 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N9Mxl'] = False # (N-m); Sectional moment resultants at Node 9 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N9Myl'] = False # (N-m); Sectional moment resultants at Node 9 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N9Mzl'] = False # (N-m); Sectional moment resultants at Node 9 expressed in l; l: a floating coordinate system local to the deflected beam + +# Sectional Motions +BeamDyn['N1TDxr'] = False # (m); Sectional translational deflection (relative to the undeflected position) at Node 1 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system +BeamDyn['N1TDyr'] = False # (m); Sectional translational deflection (relative to the undeflected position) at Node 1 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system +BeamDyn['N1TDzr'] = False # (m); Sectional translational deflection (relative to the undeflected position) at Node 1 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system +BeamDyn['N2TDxr'] = False # (m); Sectional translational deflection (relative to the undeflected position) at Node 2 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system +BeamDyn['N2TDyr'] = False # (m); Sectional translational deflection (relative to the undeflected position) at Node 2 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system +BeamDyn['N2TDzr'] = False # (m); Sectional translational deflection (relative to the undeflected position) at Node 2 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system +BeamDyn['N3TDxr'] = False # (m); Sectional translational deflection (relative to the undeflected position) at Node 3 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system +BeamDyn['N3TDyr'] = False # (m); Sectional translational deflection (relative to the undeflected position) at Node 3 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system +BeamDyn['N3TDzr'] = False # (m); Sectional translational deflection (relative to the undeflected position) at Node 3 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system +BeamDyn['N4TDxr'] = False # (m); Sectional translational deflection (relative to the undeflected position) at Node 4 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system +BeamDyn['N4TDyr'] = False # (m); Sectional translational deflection (relative to the undeflected position) at Node 4 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system +BeamDyn['N4TDzr'] = False # (m); Sectional translational deflection (relative to the undeflected position) at Node 4 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system +BeamDyn['N5TDxr'] = False # (m); Sectional translational deflection (relative to the undeflected position) at Node 5 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system +BeamDyn['N5TDyr'] = False # (m); Sectional translational deflection (relative to the undeflected position) at Node 5 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system +BeamDyn['N5TDzr'] = False # (m); Sectional translational deflection (relative to the undeflected position) at Node 5 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system +BeamDyn['N6TDxr'] = False # (m); Sectional translational deflection (relative to the undeflected position) at Node 6 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system +BeamDyn['N6TDyr'] = False # (m); Sectional translational deflection (relative to the undeflected position) at Node 6 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system +BeamDyn['N6TDzr'] = False # (m); Sectional translational deflection (relative to the undeflected position) at Node 6 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system +BeamDyn['N7TDxr'] = False # (m); Sectional translational deflection (relative to the undeflected position) at Node 7 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system +BeamDyn['N7TDyr'] = False # (m); Sectional translational deflection (relative to the undeflected position) at Node 7 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system +BeamDyn['N7TDzr'] = False # (m); Sectional translational deflection (relative to the undeflected position) at Node 7 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system +BeamDyn['N8TDxr'] = False # (m); Sectional translational deflection (relative to the undeflected position) at Node 8 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system +BeamDyn['N8TDyr'] = False # (m); Sectional translational deflection (relative to the undeflected position) at Node 8 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system +BeamDyn['N8TDzr'] = False # (m); Sectional translational deflection (relative to the undeflected position) at Node 8 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system +BeamDyn['N9TDxr'] = False # (m); Sectional translational deflection (relative to the undeflected position) at Node 9 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system +BeamDyn['N9TDyr'] = False # (m); Sectional translational deflection (relative to the undeflected position) at Node 9 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system +BeamDyn['N9TDzr'] = False # (m); Sectional translational deflection (relative to the undeflected position) at Node 9 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system +BeamDyn['N1RDxr'] = False # (-); Sectional angular/rotational deflection Wiener-Milenkovic parameter (relative to the undeflected orientation) at Node 1 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system +BeamDyn['N1RDyr'] = False # (-); Sectional angular/rotational deflection Wiener-Milenkovic parameter (relative to the undeflected orientation) at Node 1 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system +BeamDyn['N1RDzr'] = False # (-); Sectional angular/rotational deflection Wiener-Milenkovic parameter (relative to the undeflected orientation) at Node 1 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system +BeamDyn['N2RDxr'] = False # (-); Sectional angular/rotational deflection Wiener-Milenkovic parameter (relative to the undeflected orientation) at Node 2 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system +BeamDyn['N2RDyr'] = False # (-); Sectional angular/rotational deflection Wiener-Milenkovic parameter (relative to the undeflected orientation) at Node 2 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system +BeamDyn['N2RDzr'] = False # (-); Sectional angular/rotational deflection Wiener-Milenkovic parameter (relative to the undeflected orientation) at Node 2 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system +BeamDyn['N3RDxr'] = False # (-); Sectional angular/rotational deflection Wiener-Milenkovic parameter (relative to the undeflected orientation) at Node 3 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system +BeamDyn['N3RDyr'] = False # (-); Sectional angular/rotational deflection Wiener-Milenkovic parameter (relative to the undeflected orientation) at Node 3 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system +BeamDyn['N3RDzr'] = False # (-); Sectional angular/rotational deflection Wiener-Milenkovic parameter (relative to the undeflected orientation) at Node 3 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system +BeamDyn['N4RDxr'] = False # (-); Sectional angular/rotational deflection Wiener-Milenkovic parameter (relative to the undeflected orientation) at Node 4 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system +BeamDyn['N4RDyr'] = False # (-); Sectional angular/rotational deflection Wiener-Milenkovic parameter (relative to the undeflected orientation) at Node 4 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system +BeamDyn['N4RDzr'] = False # (-); Sectional angular/rotational deflection Wiener-Milenkovic parameter (relative to the undeflected orientation) at Node 4 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system +BeamDyn['N5RDxr'] = False # (-); Sectional angular/rotational deflection Wiener-Milenkovic parameter (relative to the undeflected orientation) at Node 5 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system +BeamDyn['N5RDyr'] = False # (-); Sectional angular/rotational deflection Wiener-Milenkovic parameter (relative to the undeflected orientation) at Node 5 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system +BeamDyn['N5RDzr'] = False # (-); Sectional angular/rotational deflection Wiener-Milenkovic parameter (relative to the undeflected orientation) at Node 5 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system +BeamDyn['N6RDxr'] = False # (-); Sectional angular/rotational deflection Wiener-Milenkovic parameter (relative to the undeflected orientation) at Node 6 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system +BeamDyn['N6RDyr'] = False # (-); Sectional angular/rotational deflection Wiener-Milenkovic parameter (relative to the undeflected orientation) at Node 6 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system +BeamDyn['N6RDzr'] = False # (-); Sectional angular/rotational deflection Wiener-Milenkovic parameter (relative to the undeflected orientation) at Node 6 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system +BeamDyn['N7RDxr'] = False # (-); Sectional angular/rotational deflection Wiener-Milenkovic parameter (relative to the undeflected orientation) at Node 7 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system +BeamDyn['N7RDyr'] = False # (-); Sectional angular/rotational deflection Wiener-Milenkovic parameter (relative to the undeflected orientation) at Node 7 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system +BeamDyn['N7RDzr'] = False # (-); Sectional angular/rotational deflection Wiener-Milenkovic parameter (relative to the undeflected orientation) at Node 7 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system +BeamDyn['N8RDxr'] = False # (-); Sectional angular/rotational deflection Wiener-Milenkovic parameter (relative to the undeflected orientation) at Node 8 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system +BeamDyn['N8RDyr'] = False # (-); Sectional angular/rotational deflection Wiener-Milenkovic parameter (relative to the undeflected orientation) at Node 8 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system +BeamDyn['N8RDzr'] = False # (-); Sectional angular/rotational deflection Wiener-Milenkovic parameter (relative to the undeflected orientation) at Node 8 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system +BeamDyn['N9RDxr'] = False # (-); Sectional angular/rotational deflection Wiener-Milenkovic parameter (relative to the undeflected orientation) at Node 9 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system +BeamDyn['N9RDyr'] = False # (-); Sectional angular/rotational deflection Wiener-Milenkovic parameter (relative to the undeflected orientation) at Node 9 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system +BeamDyn['N9RDzr'] = False # (-); Sectional angular/rotational deflection Wiener-Milenkovic parameter (relative to the undeflected orientation) at Node 9 expressed in r; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system +BeamDyn['N1TVXg'] = False # (m/s); Sectional translational velocities (absolute) at Node 1 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system +BeamDyn['N1TVYg'] = False # (m/s); Sectional translational velocities (absolute) at Node 1 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system +BeamDyn['N1TVZg'] = False # (m/s); Sectional translational velocities (absolute) at Node 1 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system +BeamDyn['N2TVXg'] = False # (m/s); Sectional translational velocities (absolute) at Node 2 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system +BeamDyn['N2TVYg'] = False # (m/s); Sectional translational velocities (absolute) at Node 2 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system +BeamDyn['N2TVZg'] = False # (m/s); Sectional translational velocities (absolute) at Node 2 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system +BeamDyn['N3TVXg'] = False # (m/s); Sectional translational velocities (absolute) at Node 3 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system +BeamDyn['N3TVYg'] = False # (m/s); Sectional translational velocities (absolute) at Node 3 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system +BeamDyn['N3TVZg'] = False # (m/s); Sectional translational velocities (absolute) at Node 3 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system +BeamDyn['N4TVXg'] = False # (m/s); Sectional translational velocities (absolute) at Node 4 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system +BeamDyn['N4TVYg'] = False # (m/s); Sectional translational velocities (absolute) at Node 4 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system +BeamDyn['N4TVZg'] = False # (m/s); Sectional translational velocities (absolute) at Node 4 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system +BeamDyn['N5TVXg'] = False # (m/s); Sectional translational velocities (absolute) at Node 5 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system +BeamDyn['N5TVYg'] = False # (m/s); Sectional translational velocities (absolute) at Node 5 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system +BeamDyn['N5TVZg'] = False # (m/s); Sectional translational velocities (absolute) at Node 5 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system +BeamDyn['N6TVXg'] = False # (m/s); Sectional translational velocities (absolute) at Node 6 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system +BeamDyn['N6TVYg'] = False # (m/s); Sectional translational velocities (absolute) at Node 6 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system +BeamDyn['N6TVZg'] = False # (m/s); Sectional translational velocities (absolute) at Node 6 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system +BeamDyn['N7TVXg'] = False # (m/s); Sectional translational velocities (absolute) at Node 7 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system +BeamDyn['N7TVYg'] = False # (m/s); Sectional translational velocities (absolute) at Node 7 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system +BeamDyn['N7TVZg'] = False # (m/s); Sectional translational velocities (absolute) at Node 7 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system +BeamDyn['N8TVXg'] = False # (m/s); Sectional translational velocities (absolute) at Node 8 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system +BeamDyn['N8TVYg'] = False # (m/s); Sectional translational velocities (absolute) at Node 8 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system +BeamDyn['N8TVZg'] = False # (m/s); Sectional translational velocities (absolute) at Node 8 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system +BeamDyn['N9TVXg'] = False # (m/s); Sectional translational velocities (absolute) at Node 9 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system +BeamDyn['N9TVYg'] = False # (m/s); Sectional translational velocities (absolute) at Node 9 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system +BeamDyn['N9TVZg'] = False # (m/s); Sectional translational velocities (absolute) at Node 9 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system +BeamDyn['N1RVXg'] = False # (deg/s); Sectional angular/rotational velocities (absolute) at Node 1 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system +BeamDyn['N1RVYg'] = False # (deg/s); Sectional angular/rotational velocities (absolute) at Node 1 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system +BeamDyn['N1RVZg'] = False # (deg/s); Sectional angular/rotational velocities (absolute) at Node 1 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system +BeamDyn['N2RVXg'] = False # (deg/s); Sectional angular/rotational velocities (absolute) at Node 2 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system +BeamDyn['N2RVYg'] = False # (deg/s); Sectional angular/rotational velocities (absolute) at Node 2 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system +BeamDyn['N2RVZg'] = False # (deg/s); Sectional angular/rotational velocities (absolute) at Node 2 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system +BeamDyn['N3RVXg'] = False # (deg/s); Sectional angular/rotational velocities (absolute) at Node 3 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system +BeamDyn['N3RVYg'] = False # (deg/s); Sectional angular/rotational velocities (absolute) at Node 3 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system +BeamDyn['N3RVZg'] = False # (deg/s); Sectional angular/rotational velocities (absolute) at Node 3 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system +BeamDyn['N4RVXg'] = False # (deg/s); Sectional angular/rotational velocities (absolute) at Node 4 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system +BeamDyn['N4RVYg'] = False # (deg/s); Sectional angular/rotational velocities (absolute) at Node 4 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system +BeamDyn['N4RVZg'] = False # (deg/s); Sectional angular/rotational velocities (absolute) at Node 4 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system +BeamDyn['N5RVXg'] = False # (deg/s); Sectional angular/rotational velocities (absolute) at Node 5 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system +BeamDyn['N5RVYg'] = False # (deg/s); Sectional angular/rotational velocities (absolute) at Node 5 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system +BeamDyn['N5RVZg'] = False # (deg/s); Sectional angular/rotational velocities (absolute) at Node 5 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system +BeamDyn['N6RVXg'] = False # (deg/s); Sectional angular/rotational velocities (absolute) at Node 6 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system +BeamDyn['N6RVYg'] = False # (deg/s); Sectional angular/rotational velocities (absolute) at Node 6 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system +BeamDyn['N6RVZg'] = False # (deg/s); Sectional angular/rotational velocities (absolute) at Node 6 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system +BeamDyn['N7RVXg'] = False # (deg/s); Sectional angular/rotational velocities (absolute) at Node 7 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system +BeamDyn['N7RVYg'] = False # (deg/s); Sectional angular/rotational velocities (absolute) at Node 7 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system +BeamDyn['N7RVZg'] = False # (deg/s); Sectional angular/rotational velocities (absolute) at Node 7 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system +BeamDyn['N8RVXg'] = False # (deg/s); Sectional angular/rotational velocities (absolute) at Node 8 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system +BeamDyn['N8RVYg'] = False # (deg/s); Sectional angular/rotational velocities (absolute) at Node 8 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system +BeamDyn['N8RVZg'] = False # (deg/s); Sectional angular/rotational velocities (absolute) at Node 8 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system +BeamDyn['N9RVXg'] = False # (deg/s); Sectional angular/rotational velocities (absolute) at Node 9 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system +BeamDyn['N9RVYg'] = False # (deg/s); Sectional angular/rotational velocities (absolute) at Node 9 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system +BeamDyn['N9RVZg'] = False # (deg/s); Sectional angular/rotational velocities (absolute) at Node 9 expressed in g; g: the global inertial frame coordinate system; when coupled to FAST, this is equivalent to FAST s global inertial frame (i) coordinate system +BeamDyn['N1TAXl'] = False # (m/s^2); Sectional translational accelerations (absolute) at Node 1 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N1TAYl'] = False # (m/s^2); Sectional translational accelerations (absolute) at Node 1 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N1TAZl'] = False # (m/s^2); Sectional translational accelerations (absolute) at Node 1 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N2TAXl'] = False # (m/s^2); Sectional translational accelerations (absolute) at Node 2 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N2TAYl'] = False # (m/s^2); Sectional translational accelerations (absolute) at Node 2 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N2TAZl'] = False # (m/s^2); Sectional translational accelerations (absolute) at Node 2 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N3TAXl'] = False # (m/s^2); Sectional translational accelerations (absolute) at Node 3 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N3TAYl'] = False # (m/s^2); Sectional translational accelerations (absolute) at Node 3 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N3TAZl'] = False # (m/s^2); Sectional translational accelerations (absolute) at Node 3 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N4TAXl'] = False # (m/s^2); Sectional translational accelerations (absolute) at Node 4 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N4TAYl'] = False # (m/s^2); Sectional translational accelerations (absolute) at Node 4 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N4TAZl'] = False # (m/s^2); Sectional translational accelerations (absolute) at Node 4 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N5TAXl'] = False # (m/s^2); Sectional translational accelerations (absolute) at Node 5 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N5TAYl'] = False # (m/s^2); Sectional translational accelerations (absolute) at Node 5 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N5TAZl'] = False # (m/s^2); Sectional translational accelerations (absolute) at Node 5 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N6TAXl'] = False # (m/s^2); Sectional translational accelerations (absolute) at Node 6 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N6TAYl'] = False # (m/s^2); Sectional translational accelerations (absolute) at Node 6 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N6TAZl'] = False # (m/s^2); Sectional translational accelerations (absolute) at Node 6 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N7TAXl'] = False # (m/s^2); Sectional translational accelerations (absolute) at Node 7 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N7TAYl'] = False # (m/s^2); Sectional translational accelerations (absolute) at Node 7 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N7TAZl'] = False # (m/s^2); Sectional translational accelerations (absolute) at Node 7 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N8TAXl'] = False # (m/s^2); Sectional translational accelerations (absolute) at Node 8 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N8TAYl'] = False # (m/s^2); Sectional translational accelerations (absolute) at Node 8 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N8TAZl'] = False # (m/s^2); Sectional translational accelerations (absolute) at Node 8 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N9TAXl'] = False # (m/s^2); Sectional translational accelerations (absolute) at Node 9 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N9TAYl'] = False # (m/s^2); Sectional translational accelerations (absolute) at Node 9 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N9TAZl'] = False # (m/s^2); Sectional translational accelerations (absolute) at Node 9 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N1RAXl'] = False # (deg/s^2); Sectional angular/rotational accelerations (absolute) at Node 1 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N1RAYl'] = False # (deg/s^2); Sectional angular/rotational accelerations (absolute) at Node 1 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N1RAZl'] = False # (deg/s^2); Sectional angular/rotational accelerations (absolute) at Node 1 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N2RAXl'] = False # (deg/s^2); Sectional angular/rotational accelerations (absolute) at Node 2 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N2RAYl'] = False # (deg/s^2); Sectional angular/rotational accelerations (absolute) at Node 2 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N2RAZl'] = False # (deg/s^2); Sectional angular/rotational accelerations (absolute) at Node 2 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N3RAXl'] = False # (deg/s^2); Sectional angular/rotational accelerations (absolute) at Node 3 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N3RAYl'] = False # (deg/s^2); Sectional angular/rotational accelerations (absolute) at Node 3 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N3RAZl'] = False # (deg/s^2); Sectional angular/rotational accelerations (absolute) at Node 3 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N4RAXl'] = False # (deg/s^2); Sectional angular/rotational accelerations (absolute) at Node 4 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N4RAYl'] = False # (deg/s^2); Sectional angular/rotational accelerations (absolute) at Node 4 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N4RAZl'] = False # (deg/s^2); Sectional angular/rotational accelerations (absolute) at Node 4 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N5RAXl'] = False # (deg/s^2); Sectional angular/rotational accelerations (absolute) at Node 5 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N5RAYl'] = False # (deg/s^2); Sectional angular/rotational accelerations (absolute) at Node 5 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N5RAZl'] = False # (deg/s^2); Sectional angular/rotational accelerations (absolute) at Node 5 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N6RAXl'] = False # (deg/s^2); Sectional angular/rotational accelerations (absolute) at Node 6 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N6RAYl'] = False # (deg/s^2); Sectional angular/rotational accelerations (absolute) at Node 6 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N6RAZl'] = False # (deg/s^2); Sectional angular/rotational accelerations (absolute) at Node 6 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N7RAXl'] = False # (deg/s^2); Sectional angular/rotational accelerations (absolute) at Node 7 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N7RAYl'] = False # (deg/s^2); Sectional angular/rotational accelerations (absolute) at Node 7 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N7RAZl'] = False # (deg/s^2); Sectional angular/rotational accelerations (absolute) at Node 7 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N8RAXl'] = False # (deg/s^2); Sectional angular/rotational accelerations (absolute) at Node 8 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N8RAYl'] = False # (deg/s^2); Sectional angular/rotational accelerations (absolute) at Node 8 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N8RAZl'] = False # (deg/s^2); Sectional angular/rotational accelerations (absolute) at Node 8 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N9RAXl'] = False # (deg/s^2); Sectional angular/rotational accelerations (absolute) at Node 9 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N9RAYl'] = False # (deg/s^2); Sectional angular/rotational accelerations (absolute) at Node 9 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N9RAZl'] = False # (deg/s^2); Sectional angular/rotational accelerations (absolute) at Node 9 expressed in l; l: a floating coordinate system local to the deflected beam + +# Applied Loads +BeamDyn['N1PFxl'] = False # (N); Applied point forces at Node 1 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N1PFyl'] = False # (N); Applied point forces at Node 1 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N1PFzl'] = False # (N); Applied point forces at Node 1 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N2PFxl'] = False # (N); Applied point forces at Node 2 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N2PFyl'] = False # (N); Applied point forces at Node 2 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N2PFzl'] = False # (N); Applied point forces at Node 2 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N3PFxl'] = False # (N); Applied point forces at Node 3 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N3PFyl'] = False # (N); Applied point forces at Node 3 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N3PFzl'] = False # (N); Applied point forces at Node 3 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N4PFxl'] = False # (N); Applied point forces at Node 4 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N4PFyl'] = False # (N); Applied point forces at Node 4 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N4PFzl'] = False # (N); Applied point forces at Node 4 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N5PFxl'] = False # (N); Applied point forces at Node 5 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N5PFyl'] = False # (N); Applied point forces at Node 5 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N5PFzl'] = False # (N); Applied point forces at Node 5 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N6PFxl'] = False # (N); Applied point forces at Node 6 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N6PFyl'] = False # (N); Applied point forces at Node 6 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N6PFzl'] = False # (N); Applied point forces at Node 6 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N7PFxl'] = False # (N); Applied point forces at Node 7 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N7PFyl'] = False # (N); Applied point forces at Node 7 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N7PFzl'] = False # (N); Applied point forces at Node 7 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N8PFxl'] = False # (N); Applied point forces at Node 8 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N8PFyl'] = False # (N); Applied point forces at Node 8 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N8PFzl'] = False # (N); Applied point forces at Node 8 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N9PFxl'] = False # (N); Applied point forces at Node 9 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N9PFyl'] = False # (N); Applied point forces at Node 9 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N9PFzl'] = False # (N); Applied point forces at Node 9 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N1PMxl'] = False # (N-m); Applied point moments at Node 1 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N1PMyl'] = False # (N-m); Applied point moments at Node 1 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N1PMzl'] = False # (N-m); Applied point moments at Node 1 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N2PMxl'] = False # (N-m); Applied point moments at Node 2 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N2PMyl'] = False # (N-m); Applied point moments at Node 2 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N2PMzl'] = False # (N-m); Applied point moments at Node 2 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N3PMxl'] = False # (N-m); Applied point moments at Node 3 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N3PMyl'] = False # (N-m); Applied point moments at Node 3 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N3PMzl'] = False # (N-m); Applied point moments at Node 3 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N4PMxl'] = False # (N-m); Applied point moments at Node 4 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N4PMyl'] = False # (N-m); Applied point moments at Node 4 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N4PMzl'] = False # (N-m); Applied point moments at Node 4 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N5PMxl'] = False # (N-m); Applied point moments at Node 5 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N5PMyl'] = False # (N-m); Applied point moments at Node 5 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N5PMzl'] = False # (N-m); Applied point moments at Node 5 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N6PMxl'] = False # (N-m); Applied point moments at Node 6 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N6PMyl'] = False # (N-m); Applied point moments at Node 6 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N6PMzl'] = False # (N-m); Applied point moments at Node 6 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N7PMxl'] = False # (N-m); Applied point moments at Node 7 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N7PMyl'] = False # (N-m); Applied point moments at Node 7 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N7PMzl'] = False # (N-m); Applied point moments at Node 7 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N8PMxl'] = False # (N-m); Applied point moments at Node 8 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N8PMyl'] = False # (N-m); Applied point moments at Node 8 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N8PMzl'] = False # (N-m); Applied point moments at Node 8 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N9PMxl'] = False # (N-m); Applied point moments at Node 9 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N9PMyl'] = False # (N-m); Applied point moments at Node 9 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N9PMzl'] = False # (N-m); Applied point moments at Node 9 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N1DFxl'] = False # (N/m); Applied distributed forces at Node 1 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N1DFyl'] = False # (N/m); Applied distributed forces at Node 1 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N1DFzl'] = False # (N/m); Applied distributed forces at Node 1 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N2DFxl'] = False # (N/m); Applied distributed forces at Node 2 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N2DFyl'] = False # (N/m); Applied distributed forces at Node 2 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N2DFzl'] = False # (N/m); Applied distributed forces at Node 2 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N3DFxl'] = False # (N/m); Applied distributed forces at Node 3 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N3DFyl'] = False # (N/m); Applied distributed forces at Node 3 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N3DFzl'] = False # (N/m); Applied distributed forces at Node 3 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N4DFxl'] = False # (N/m); Applied distributed forces at Node 4 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N4DFyl'] = False # (N/m); Applied distributed forces at Node 4 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N4DFzl'] = False # (N/m); Applied distributed forces at Node 4 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N5DFxl'] = False # (N/m); Applied distributed forces at Node 5 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N5DFyl'] = False # (N/m); Applied distributed forces at Node 5 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N5DFzl'] = False # (N/m); Applied distributed forces at Node 5 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N6DFxl'] = False # (N/m); Applied distributed forces at Node 6 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N6DFyl'] = False # (N/m); Applied distributed forces at Node 6 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N6DFzl'] = False # (N/m); Applied distributed forces at Node 6 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N7DFxl'] = False # (N/m); Applied distributed forces at Node 7 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N7DFyl'] = False # (N/m); Applied distributed forces at Node 7 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N7DFzl'] = False # (N/m); Applied distributed forces at Node 7 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N8DFxl'] = False # (N/m); Applied distributed forces at Node 8 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N8DFyl'] = False # (N/m); Applied distributed forces at Node 8 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N8DFzl'] = False # (N/m); Applied distributed forces at Node 8 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N9DFxl'] = False # (N/m); Applied distributed forces at Node 9 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N9DFyl'] = False # (N/m); Applied distributed forces at Node 9 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N9DFzl'] = False # (N/m); Applied distributed forces at Node 9 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N1DMxl'] = False # (N-m/m); Applied distributed moments at Node 1 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N1DMyl'] = False # (N-m/m); Applied distributed moments at Node 1 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N1DMzl'] = False # (N-m/m); Applied distributed moments at Node 1 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N2DMxl'] = False # (N-m/m); Applied distributed moments at Node 2 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N2DMyl'] = False # (N-m/m); Applied distributed moments at Node 2 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N2DMzl'] = False # (N-m/m); Applied distributed moments at Node 2 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N3DMxl'] = False # (N-m/m); Applied distributed moments at Node 3 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N3DMyl'] = False # (N-m/m); Applied distributed moments at Node 3 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N3DMzl'] = False # (N-m/m); Applied distributed moments at Node 3 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N4DMxl'] = False # (N-m/m); Applied distributed moments at Node 4 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N4DMyl'] = False # (N-m/m); Applied distributed moments at Node 4 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N4DMzl'] = False # (N-m/m); Applied distributed moments at Node 4 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N5DMxl'] = False # (N-m/m); Applied distributed moments at Node 5 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N5DMyl'] = False # (N-m/m); Applied distributed moments at Node 5 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N5DMzl'] = False # (N-m/m); Applied distributed moments at Node 5 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N6DMxl'] = False # (N-m/m); Applied distributed moments at Node 6 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N6DMyl'] = False # (N-m/m); Applied distributed moments at Node 6 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N6DMzl'] = False # (N-m/m); Applied distributed moments at Node 6 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N7DMxl'] = False # (N-m/m); Applied distributed moments at Node 7 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N7DMyl'] = False # (N-m/m); Applied distributed moments at Node 7 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N7DMzl'] = False # (N-m/m); Applied distributed moments at Node 7 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N8DMxl'] = False # (N-m/m); Applied distributed moments at Node 8 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N8DMyl'] = False # (N-m/m); Applied distributed moments at Node 8 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N8DMzl'] = False # (N-m/m); Applied distributed moments at Node 8 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N9DMxl'] = False # (N-m/m); Applied distributed moments at Node 9 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N9DMyl'] = False # (N-m/m); Applied distributed moments at Node 9 expressed in l; l: a floating coordinate system local to the deflected beam +BeamDyn['N9DMzl'] = False # (N-m/m); Applied distributed moments at Node 9 expressed in l; l: a floating coordinate system local to the deflected beam + +# Pitch Actuator +BeamDyn['PAngInp'] = False # (deg); Pitch angle input; +BeamDyn['PAngAct'] = False # (deg); Actual pitch angle ; +BeamDyn['PRatAct'] = False # (deg/s); Actual pitch rate; +BeamDyn['PAccAct'] = False # (deg/s^2); Actual pitch acceleration; + + +""" ElastoDyn """ +ElastoDyn = {} + +# Blade 1 Tip Motions +ElastoDyn['TipDxc1'] = True # (m); Blade 1 out-of-plane tip deflection (relative to the undeflected position); Directed along the xc1-axis +ElastoDyn['OoPDefl1'] = False # (m); Blade 1 out-of-plane tip deflection (relative to the undeflected position); Directed along the xc1-axis +ElastoDyn['TipDyc1'] = True # (m); Blade 1 in-plane tip deflection (relative to the undeflected position); Directed along the yc1-axis +ElastoDyn['IPDefl1'] = False # (m); Blade 1 in-plane tip deflection (relative to the undeflected position); Directed along the yc1-axis +ElastoDyn['TipDzc1'] = True # (m); Blade 1 axial tip deflection (relative to the undeflected position); Directed along the zc1- and zb1-axes +ElastoDyn['TipDzb1'] = True # (m); Blade 1 axial tip deflection (relative to the undeflected position); Directed along the zc1- and zb1-axes +ElastoDyn['TipDxb1'] = True # (m); Blade 1 flapwise tip deflection (relative to the undeflected position); Directed along the xb1-axis +ElastoDyn['TipDyb1'] = True # (m); Blade 1 edgewise tip deflection (relative to the undeflected position); Directed along the yb1-axis +ElastoDyn['TipALxb1'] = False # (m/s^2); Blade 1 local flapwise tip acceleration (absolute); Directed along the local xb1-axis +ElastoDyn['TipALyb1'] = False # (m/s^2); Blade 1 local edgewise tip acceleration (absolute); Directed along the local yb1-axis +ElastoDyn['TipALzb1'] = False # (m/s^2); Blade 1 local axial tip acceleration (absolute); Directed along the local zb1-axis +ElastoDyn['TipALgxb1'] = False # (m/s^2); Blade 1 local flapwise tip acceleration (relative to g); Directed along the local xb1-axis +ElastoDyn['TipALgyb1'] = False # (m/s^2); Blade 1 local edgewise tip acceleration (relative to g); Directed along the local yb1-axis +ElastoDyn['TipALgzb1'] = False # (m/s^2); Blade 1 local axial tip acceleration (relative to g); Directed along the local zb1-axis +ElastoDyn['TipRDxb1'] = False # (deg); Blade 1 roll (angular/rotational) tip deflection (relative to the undeflected position). In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the xb1-axis +ElastoDyn['RollDefl1'] = False # (deg); Blade 1 roll (angular/rotational) tip deflection (relative to the undeflected position). In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the xb1-axis +ElastoDyn['TipRDyb1'] = False # (deg); Blade 1 pitch (angular/rotational) tip deflection (relative to the undeflected position). In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the yb1-axis +ElastoDyn['PtchDefl1'] = False # (deg); Blade 1 pitch (angular/rotational) tip deflection (relative to the undeflected position). In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the yb1-axis +ElastoDyn['TipRDzc1'] = False # (deg); Blade 1 torsional tip deflection (relative to the undeflected position). This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the zc1- and zb1-axes +ElastoDyn['TipRDzb1'] = False # (deg); Blade 1 torsional tip deflection (relative to the undeflected position). This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the zc1- and zb1-axes +ElastoDyn['TwstDefl1'] = False # (deg); Blade 1 torsional tip deflection (relative to the undeflected position). This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the zc1- and zb1-axes +ElastoDyn['TipClrnc1'] = False # (m); Blade 1 tip-to-tower clearance estimate. This is computed as the perpendicular distance from the yaw axis to the tip of blade 1 when the blade tip is below the yaw bearing. When the tip of blade 1 is above the yaw bearing, it is computed as the absolute distance from the yaw bearing to the blade tip. Please note that you should reduce this value by the tower radius to obtain the actual tower clearance.; N/A +ElastoDyn['TwrClrnc1'] = False # (m); Blade 1 tip-to-tower clearance estimate. This is computed as the perpendicular distance from the yaw axis to the tip of blade 1 when the blade tip is below the yaw bearing. When the tip of blade 1 is above the yaw bearing, it is computed as the absolute distance from the yaw bearing to the blade tip. Please note that you should reduce this value by the tower radius to obtain the actual tower clearance.; N/A +ElastoDyn['Tip2Twr1'] = False # (m); Blade 1 tip-to-tower clearance estimate. This is computed as the perpendicular distance from the yaw axis to the tip of blade 1 when the blade tip is below the yaw bearing. When the tip of blade 1 is above the yaw bearing, it is computed as the absolute distance from the yaw bearing to the blade tip. Please note that you should reduce this value by the tower radius to obtain the actual tower clearance.; N/A + +# Blade 2 Tip Motions +ElastoDyn['TipDxc2'] = True # (m); Blade 2 out-of-plane tip deflection (relative to the pitch axis); Directed along the xc2-axis +ElastoDyn['OoPDefl2'] = False # (m); Blade 2 out-of-plane tip deflection (relative to the pitch axis); Directed along the xc2-axis +ElastoDyn['TipDyc2'] = True # (m); Blade 2 in-plane tip deflection (relative to the pitch axis); Directed along the yc2-axis +ElastoDyn['IPDefl2'] = False # (m); Blade 2 in-plane tip deflection (relative to the pitch axis); Directed along the yc2-axis +ElastoDyn['TipDzc2'] = True # (m); Blade 2 axial tip deflection (relative to the pitch axis); Directed along the zc2- and zb2-axes +ElastoDyn['TipDzb2'] = True # (m); Blade 2 axial tip deflection (relative to the pitch axis); Directed along the zc2- and zb2-axes +ElastoDyn['TipDxb2'] = True # (m); Blade 2 flapwise tip deflection (relative to the pitch axis); Directed along the xb2-axis +ElastoDyn['TipDyb2'] = True # (m); Blade 2 edgewise tip deflection (relative to the pitch axis); Directed along the yb2-axis +ElastoDyn['TipALxb2'] = False # (m/s^2); Blade 2 local flapwise tip acceleration (absolute); Directed along the local xb2-axis +ElastoDyn['TipALyb2'] = False # (m/s^2); Blade 2 local edgewise tip acceleration (absolute); Directed along the local yb2-axis +ElastoDyn['TipALzb2'] = False # (m/s^2); Blade 2 local axial tip acceleration (absolute); Directed along the local zb2-axis +ElastoDyn['TipALgxb2'] = False # (m/s^2); Blade 2 local flapwise tip acceleration (relative to g); Directed along the local xb2-axis +ElastoDyn['TipALgyb2'] = False # (m/s^2); Blade 2 local edgewise tip acceleration (relative to g); Directed along the local yb2-axis +ElastoDyn['TipALgzb2'] = False # (m/s^2); Blade 2 local axial tip acceleration (relative to g); Directed along the local zb2-axis +ElastoDyn['TipRDxb2'] = False # (deg); Blade 2 roll (angular/rotational) tip deflection (relative to the undeflected position). In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the xb2-axis +ElastoDyn['RollDefl2'] = False # (deg); Blade 2 roll (angular/rotational) tip deflection (relative to the undeflected position). In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the xb2-axis +ElastoDyn['TipRDyb2'] = False # (deg); Blade 2 pitch (angular/rotational) tip deflection (relative to the undeflected position). In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the yb2-axis +ElastoDyn['PtchDefl2'] = False # (deg); Blade 2 pitch (angular/rotational) tip deflection (relative to the undeflected position). In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the yb2-axis +ElastoDyn['TipRDzc2'] = False # (deg); Blade 2 torsional (angular/rotational) tip deflection (relative to the undeflected position). This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the zc2- and zb2-axes +ElastoDyn['TipRDzb2'] = False # (deg); Blade 2 torsional (angular/rotational) tip deflection (relative to the undeflected position). This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the zc2- and zb2-axes +ElastoDyn['TwstDefl2'] = False # (deg); Blade 2 torsional (angular/rotational) tip deflection (relative to the undeflected position). This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the zc2- and zb2-axes +ElastoDyn['TipClrnc2'] = False # (m); Blade 2 tip-to-tower clearance estimate. This is computed as the perpendicular distance from the yaw axis to the tip of blade 1 when the blade tip is below the yaw bearing. When the tip of blade 1 is above the yaw bearing, it is computed as the absolute distance from the yaw bearing to the blade tip. Please note that you should reduce this value by the tower radius to obtain the actual tower clearance.; N/A +ElastoDyn['TwrClrnc2'] = False # (m); Blade 2 tip-to-tower clearance estimate. This is computed as the perpendicular distance from the yaw axis to the tip of blade 1 when the blade tip is below the yaw bearing. When the tip of blade 1 is above the yaw bearing, it is computed as the absolute distance from the yaw bearing to the blade tip. Please note that you should reduce this value by the tower radius to obtain the actual tower clearance.; N/A +ElastoDyn['Tip2Twr2'] = False # (m); Blade 2 tip-to-tower clearance estimate. This is computed as the perpendicular distance from the yaw axis to the tip of blade 1 when the blade tip is below the yaw bearing. When the tip of blade 1 is above the yaw bearing, it is computed as the absolute distance from the yaw bearing to the blade tip. Please note that you should reduce this value by the tower radius to obtain the actual tower clearance.; N/A + +# Blade 3 Tip Motions +ElastoDyn['TipDxc3'] = True # (m); Blade 3 out-of-plane tip deflection (relative to the pitch axis); Directed along the xc3-axis +ElastoDyn['OoPDefl3'] = False # (m); Blade 3 out-of-plane tip deflection (relative to the pitch axis); Directed along the xc3-axis +ElastoDyn['TipDyc3'] = True # (m); Blade 3 in-plane tip deflection (relative to the pitch axis); Directed along the yc3-axis +ElastoDyn['IPDefl3'] = False # (m); Blade 3 in-plane tip deflection (relative to the pitch axis); Directed along the yc3-axis +ElastoDyn['TipDzc3'] = True # (m); Blade 3 axial tip deflection (relative to the pitch axis); Directed along the zc3- and zb3-axes +ElastoDyn['TipDzb3'] = True # (m); Blade 3 axial tip deflection (relative to the pitch axis); Directed along the zc3- and zb3-axes +ElastoDyn['TipDxb3'] = True # (m); Blade 3 flapwise tip deflection (relative to the pitch axis); Directed along the xb3-axis +ElastoDyn['TipDyb3'] = True # (m); Blade 3 edgewise tip deflection (relative to the pitch axis); Directed along the yb3-axis +ElastoDyn['TipALxb3'] = False # (m/s^2); Blade 3 local flapwise tip acceleration (absolute); Directed along the local xb3-axis +ElastoDyn['TipALyb3'] = False # (m/s^2); Blade 3 local edgewise tip acceleration (absolute); Directed along the local yb3-axis +ElastoDyn['TipALzb3'] = False # (m/s^2); Blade 3 local axial tip acceleration (absolute); Directed along the local zb3-axis +ElastoDyn['TipALgxb3'] = False # (m/s^2); Blade 3 local flapwise tip acceleration (relative to g); Directed along the local xb3-axis +ElastoDyn['TipALgyb3'] = False # (m/s^2); Blade 3 local edgewise tip acceleration (relative to g); Directed along the local yb3-axis +ElastoDyn['TipALgzb3'] = False # (m/s^2); Blade 3 local axial tip acceleration (relative to g); Directed along the local zb3-axis +ElastoDyn['TipRDxb3'] = False # (deg); Blade 3 roll (angular/rotational) tip deflection (relative to the undeflected position). In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the xb3-axis +ElastoDyn['RollDefl3'] = False # (deg); Blade 3 roll (angular/rotational) tip deflection (relative to the undeflected position). In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the xb3-axis +ElastoDyn['TipRDyb3'] = False # (deg); Blade 3 pitch (angular/rotational) tip deflection (relative to the undeflected position). In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the yb3-axis +ElastoDyn['PtchDefl3'] = False # (deg); Blade 3 pitch (angular/rotational) tip deflection (relative to the undeflected position). In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the yb3-axis +ElastoDyn['TipRDzc3'] = False # (deg); Blade 3 torsional tip deflection (relative to the undeflected position). This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the zc3- and zb3-axes +ElastoDyn['TipRDzb3'] = False # (deg); Blade 3 torsional tip deflection (relative to the undeflected position). This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the zc3- and zb3-axes +ElastoDyn['TwstDefl3'] = False # (deg); Blade 3 torsional tip deflection (relative to the undeflected position). This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the zc3- and zb3-axes +ElastoDyn['TipClrnc3'] = False # (m); Blade 3 tip-to-tower clearance estimate. This is computed as the perpendicular distance from the yaw axis to the tip of blade 1 when the blade tip is below the yaw bearing. When the tip of blade 1 is above the yaw bearing, it is computed as the absolute distance from the yaw bearing to the blade tip. Please note that you should reduce this value by the tower radius to obtain the actual tower clearance.; N/A +ElastoDyn['TwrClrnc3'] = False # (m); Blade 3 tip-to-tower clearance estimate. This is computed as the perpendicular distance from the yaw axis to the tip of blade 1 when the blade tip is below the yaw bearing. When the tip of blade 1 is above the yaw bearing, it is computed as the absolute distance from the yaw bearing to the blade tip. Please note that you should reduce this value by the tower radius to obtain the actual tower clearance.; N/A +ElastoDyn['Tip2Twr3'] = False # (m); Blade 3 tip-to-tower clearance estimate. This is computed as the perpendicular distance from the yaw axis to the tip of blade 1 when the blade tip is below the yaw bearing. When the tip of blade 1 is above the yaw bearing, it is computed as the absolute distance from the yaw bearing to the blade tip. Please note that you should reduce this value by the tower radius to obtain the actual tower clearance.; N/A + +# Blade 1 Local Span Motions +ElastoDyn['Spn1ALxb1'] = False # (m/s^2); Blade 1 local flapwise acceleration (absolute) of span station 1; Directed along the local xb1-axis +ElastoDyn['Spn1ALyb1'] = False # (m/s^2); Blade 1 local edgewise acceleration (absolute) of span station 1; Directed along the local yb1-axis +ElastoDyn['Spn1ALzb1'] = False # (m/s^2); Blade 1 local axial acceleration (absolute) of span station 1; Directed along the local zb1-axis +ElastoDyn['Spn2ALxb1'] = False # (m/s^2); Blade 1 local flapwise acceleration (absolute) of span station 2; Directed along the local xb1-axis +ElastoDyn['Spn2ALyb1'] = False # (m/s^2); Blade 1 local edgewise acceleration (absolute) of span station 2; Directed along the local yb1-axis +ElastoDyn['Spn2ALzb1'] = False # (m/s^2); Blade 1 local axial acceleration (absolute) of span station 2; Directed along the local zb1-axis +ElastoDyn['Spn3ALxb1'] = False # (m/s^2); Blade 1 local flapwise acceleration (absolute) of span station 3; Directed along the local xb1-axis +ElastoDyn['Spn3ALyb1'] = False # (m/s^2); Blade 1 local edgewise acceleration (absolute) of span station 3; Directed along the local yb1-axis +ElastoDyn['Spn3ALzb1'] = False # (m/s^2); Blade 1 local axial acceleration (absolute) of span station 3; Directed along the local zb1-axis +ElastoDyn['Spn4ALxb1'] = False # (m/s^2); Blade 1 local flapwise acceleration (absolute) of span station 4; Directed along the local xb1-axis +ElastoDyn['Spn4ALyb1'] = False # (m/s^2); Blade 1 local edgewise acceleration (absolute) of span station 4; Directed along the local yb1-axis +ElastoDyn['Spn4ALzb1'] = False # (m/s^2); Blade 1 local axial acceleration (absolute) of span station 4; Directed along the local zb1-axis +ElastoDyn['Spn5ALxb1'] = False # (m/s^2); Blade 1 local flapwise acceleration (absolute) of span station 5; Directed along the local xb1-axis +ElastoDyn['Spn5ALyb1'] = False # (m/s^2); Blade 1 local edgewise acceleration (absolute) of span station 5; Directed along the local yb1-axis +ElastoDyn['Spn5ALzb1'] = False # (m/s^2); Blade 1 local axial acceleration (absolute) of span station 5; Directed along the local zb1-axis +ElastoDyn['Spn6ALxb1'] = False # (m/s^2); Blade 1 local flapwise acceleration (absolute) of span station 6; Directed along the local xb1-axis +ElastoDyn['Spn6ALyb1'] = False # (m/s^2); Blade 1 local edgewise acceleration (absolute) of span station 6; Directed along the local yb1-axis +ElastoDyn['Spn6ALzb1'] = False # (m/s^2); Blade 1 local axial acceleration (absolute) of span station 6; Directed along the local zb1-axis +ElastoDyn['Spn7ALxb1'] = False # (m/s^2); Blade 1 local flapwise acceleration (absolute) of span station 7; Directed along the local xb1-axis +ElastoDyn['Spn7ALyb1'] = False # (m/s^2); Blade 1 local edgewise acceleration (absolute) of span station 7; Directed along the local yb1-axis +ElastoDyn['Spn7ALzb1'] = False # (m/s^2); Blade 1 local axial acceleration (absolute) of span station 7; Directed along the local zb1-axis +ElastoDyn['Spn8ALxb1'] = False # (m/s^2); Blade 1 local flapwise acceleration (absolute) of span station 8; Directed along the local xb1-axis +ElastoDyn['Spn8ALyb1'] = False # (m/s^2); Blade 1 local edgewise acceleration (absolute) of span station 8; Directed along the local yb1-axis +ElastoDyn['Spn8ALzb1'] = False # (m/s^2); Blade 1 local axial acceleration (absolute) of span station 8; Directed along the local zb1-axis +ElastoDyn['Spn9ALxb1'] = False # (m/s^2); Blade 1 local flapwise acceleration (absolute) of span station 9; Directed along the local xb1-axis +ElastoDyn['Spn9ALyb1'] = False # (m/s^2); Blade 1 local edgewise acceleration (absolute) of span station 9; Directed along the local yb1-axis +ElastoDyn['Spn9ALzb1'] = False # (m/s^2); Blade 1 local axial acceleration (absolute) of span station 9; Directed along the local zb1-axis +ElastoDyn['Spn1ALgxb1'] = False # (m/s^2); Blade 1 local flapwise acceleration (relative to g) of span station 1; Directed along the local xb1-axis +ElastoDyn['Spn1ALgyb1'] = False # (m/s^2); Blade 1 local edgewise acceleration (relative to g) of span station 1; Directed along the local yb1-axis +ElastoDyn['Spn1ALgzb1'] = False # (m/s^2); Blade 1 local axial acceleration (relative to g) of span station 1; Directed along the local zb1-axis +ElastoDyn['Spn2ALgxb1'] = False # (m/s^2); Blade 1 local flapwise acceleration (relative to g) of span station 2; Directed along the local xb1-axis +ElastoDyn['Spn2ALgyb1'] = False # (m/s^2); Blade 1 local edgewise acceleration (relative to g) of span station 2; Directed along the local yb1-axis +ElastoDyn['Spn2ALgzb1'] = False # (m/s^2); Blade 1 local axial acceleration (relative to g) of span station 2; Directed along the local zb1-axis +ElastoDyn['Spn3ALgxb1'] = False # (m/s^2); Blade 1 local flapwise acceleration (relative to g) of span station 3; Directed along the local xb1-axis +ElastoDyn['Spn3ALgyb1'] = False # (m/s^2); Blade 1 local edgewise acceleration (relative to g) of span station 3; Directed along the local yb1-axis +ElastoDyn['Spn3ALgzb1'] = False # (m/s^2); Blade 1 local axial acceleration (relative to g) of span station 3; Directed along the local zb1-axis +ElastoDyn['Spn4ALgxb1'] = False # (m/s^2); Blade 1 local flapwise acceleration (relative to g) of span station 4; Directed along the local xb1-axis +ElastoDyn['Spn4ALgyb1'] = False # (m/s^2); Blade 1 local edgewise acceleration (relative to g) of span station 4; Directed along the local yb1-axis +ElastoDyn['Spn4ALgzb1'] = False # (m/s^2); Blade 1 local axial acceleration (relative to g) of span station 4; Directed along the local zb1-axis +ElastoDyn['Spn5ALgxb1'] = False # (m/s^2); Blade 1 local flapwise acceleration (relative to g) of span station 5; Directed along the local xb1-axis +ElastoDyn['Spn5ALgyb1'] = False # (m/s^2); Blade 1 local edgewise acceleration (relative to g) of span station 5; Directed along the local yb1-axis +ElastoDyn['Spn5ALgzb1'] = False # (m/s^2); Blade 1 local axial acceleration (relative to g) of span station 5; Directed along the local zb1-axis +ElastoDyn['Spn6ALgxb1'] = False # (m/s^2); Blade 1 local flapwise acceleration (relative to g) of span station 6; Directed along the local xb1-axis +ElastoDyn['Spn6ALgyb1'] = False # (m/s^2); Blade 1 local edgewise acceleration (relative to g) of span station 6; Directed along the local yb1-axis +ElastoDyn['Spn6ALgzb1'] = False # (m/s^2); Blade 1 local axial acceleration (relative to g) of span station 6; Directed along the local zb1-axis +ElastoDyn['Spn7ALgxb1'] = False # (m/s^2); Blade 1 local flapwise acceleration (relative to g) of span station 7; Directed along the local xb1-axis +ElastoDyn['Spn7ALgyb1'] = False # (m/s^2); Blade 1 local edgewise acceleration (relative to g) of span station 7; Directed along the local yb1-axis +ElastoDyn['Spn7ALgzb1'] = False # (m/s^2); Blade 1 local axial acceleration (relative to g) of span station 7; Directed along the local zb1-axis +ElastoDyn['Spn8ALgxb1'] = False # (m/s^2); Blade 1 local flapwise acceleration (relative to g) of span station 8; Directed along the local xb1-axis +ElastoDyn['Spn8ALgyb1'] = False # (m/s^2); Blade 1 local edgewise acceleration (relative to g) of span station 8; Directed along the local yb1-axis +ElastoDyn['Spn8ALgzb1'] = False # (m/s^2); Blade 1 local axial acceleration (relative to g) of span station 8; Directed along the local zb1-axis +ElastoDyn['Spn9ALgxb1'] = False # (m/s^2); Blade 1 local flapwise acceleration (relative to g) of span station 9; Directed along the local xb1-axis +ElastoDyn['Spn9ALgyb1'] = False # (m/s^2); Blade 1 local edgewise acceleration (relative to g) of span station 9; Directed along the local yb1-axis +ElastoDyn['Spn9ALgzb1'] = False # (m/s^2); Blade 1 local axial acceleration (relative to g) of span station 9; Directed along the local zb1-axis +ElastoDyn['Spn1TDxb1'] = False # (m); Blade 1 local flapwise (translational) deflection (relative to the undeflected position) of span station 1; Directed along the xb1-axis +ElastoDyn['Spn1TDyb1'] = False # (m); Blade 1 local edgewise (translational) deflection (relative to the undeflected position) of span station 1; Directed along the yb1-axis +ElastoDyn['Spn1TDzb1'] = False # (m); Blade 1 local axial (translational) deflection (relative to the undeflected position) of span station 1; Directed along the zb1-axis +ElastoDyn['Spn2TDxb1'] = False # (m); Blade 1 local flapwise (translational) deflection (relative to the undeflected position) of span station 2; Directed along the xb1-axis +ElastoDyn['Spn2TDyb1'] = False # (m); Blade 1 local edgewise (translational) deflection (relative to the undeflected position) of span station 2; Directed along the yb1-axis +ElastoDyn['Spn2TDzb1'] = False # (m); Blade 1 local axial (translational) deflection (relative to the undeflected position) of span station 2; Directed along the zb1-axis +ElastoDyn['Spn3TDxb1'] = False # (m); Blade 1 local flapwise (translational) deflection (relative to the undeflected position) of span station 3; Directed along the xb1-axis +ElastoDyn['Spn3TDyb1'] = False # (m); Blade 1 local edgewise (translational) deflection (relative to the undeflected position) of span station 3; Directed along the yb1-axis +ElastoDyn['Spn3TDzb1'] = False # (m); Blade 1 local axial (translational) deflection (relative to the undeflected position) of span station 3; Directed along the zb1-axis +ElastoDyn['Spn4TDxb1'] = False # (m); Blade 1 local flapwise (translational) deflection (relative to the undeflected position) of span station 4; Directed along the xb1-axis +ElastoDyn['Spn4TDyb1'] = False # (m); Blade 1 local edgewise (translational) deflection (relative to the undeflected position) of span station 4; Directed along the yb1-axis +ElastoDyn['Spn4TDzb1'] = False # (m); Blade 1 local axial (translational) deflection (relative to the undeflected position) of span station 4; Directed along the zb1-axis +ElastoDyn['Spn5TDxb1'] = False # (m); Blade 1 local flapwise (translational) deflection (relative to the undeflected position) of span station 5; Directed along the xb1-axis +ElastoDyn['Spn5TDyb1'] = False # (m); Blade 1 local edgewise (translational) deflection (relative to the undeflected position) of span station 5; Directed along the yb1-axis +ElastoDyn['Spn5TDzb1'] = False # (m); Blade 1 local axial (translational) deflection (relative to the undeflected position) of span station 5; Directed along the zb1-axis +ElastoDyn['Spn6TDxb1'] = False # (m); Blade 1 local flapwise (translational) deflection (relative to the undeflected position) of span station 6; Directed along the xb1-axis +ElastoDyn['Spn6TDyb1'] = False # (m); Blade 1 local edgewise (translational) deflection (relative to the undeflected position) of span station 6; Directed along the yb1-axis +ElastoDyn['Spn6TDzb1'] = False # (m); Blade 1 local axial (translational) deflection (relative to the undeflected position) of span station 6; Directed along the zb1-axis +ElastoDyn['Spn7TDxb1'] = False # (m); Blade 1 local flapwise (translational) deflection (relative to the undeflected position) of span station 7; Directed along the xb1-axis +ElastoDyn['Spn7TDyb1'] = False # (m); Blade 1 local edgewise (translational) deflection (relative to the undeflected position) of span station 7; Directed along the yb1-axis +ElastoDyn['Spn7TDzb1'] = False # (m); Blade 1 local axial (translational) deflection (relative to the undeflected position) of span station 7; Directed along the zb1-axis +ElastoDyn['Spn8TDxb1'] = False # (m); Blade 1 local flapwise (translational) deflection (relative to the undeflected position) of span station 8; Directed along the xb1-axis +ElastoDyn['Spn8TDyb1'] = False # (m); Blade 1 local edgewise (translational) deflection (relative to the undeflected position) of span station 8; Directed along the yb1-axis +ElastoDyn['Spn8TDzb1'] = False # (m); Blade 1 local axial (translational) deflection (relative to the undeflected position) of span station 8; Directed along the zb1-axis +ElastoDyn['Spn9TDxb1'] = False # (m); Blade 1 local flapwise (translational) deflection (relative to the undeflected position) of span station 9; Directed along the xb1-axis +ElastoDyn['Spn9TDyb1'] = False # (m); Blade 1 local edgewise (translational) deflection (relative to the undeflected position) of span station 9; Directed along the yb1-axis +ElastoDyn['Spn9TDzb1'] = False # (m); Blade 1 local axial (translational) deflection (relative to the undeflected position) of span station 9; Directed along the zb1-axis +ElastoDyn['Spn1RDxb1'] = False # (deg); Blade 1 local roll (angular/rotational) deflection (relative to the undeflected position) of span station 1. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local xb1-axis +ElastoDyn['Spn1RDyb1'] = False # (deg); Blade 1 local pitch (angular/rotational) deflection (relative to the undeflected position) of span station 1. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local yb1-axis +ElastoDyn['Spn1RDzb1'] = False # (deg); Blade 1 local torsional (angular/rotational) deflection (relative to the undeflected position) of span station 1. This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the local zb1-axis +ElastoDyn['Spn2RDxb1'] = False # (deg); Blade 1 local roll (angular/rotational) deflection (relative to the undeflected position) of span station 2. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local xb1-axis +ElastoDyn['Spn2RDyb1'] = False # (deg); Blade 1 local pitch (angular/rotational) deflection (relative to the undeflected position) of span station 2. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local yb1-axis +ElastoDyn['Spn2RDzb1'] = False # (deg); Blade 1 local torsional (angular/rotational) deflection (relative to the undeflected position) of span station 2. This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the local zb1-axis +ElastoDyn['Spn3RDxb1'] = False # (deg); Blade 1 local roll (angular/rotational) deflection (relative to the undeflected position) of span station 3. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local xb1-axis +ElastoDyn['Spn3RDyb1'] = False # (deg); Blade 1 local pitch (angular/rotational) deflection (relative to the undeflected position) of span station 3. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local yb1-axis +ElastoDyn['Spn3RDzb1'] = False # (deg); Blade 1 local torsional (angular/rotational) deflection (relative to the undeflected position) of span station 3. This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the local zb1-axis +ElastoDyn['Spn4RDxb1'] = False # (deg); Blade 1 local roll (angular/rotational) deflection (relative to the undeflected position) of span station 4. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local xb1-axis +ElastoDyn['Spn4RDyb1'] = False # (deg); Blade 1 local pitch (angular/rotational) deflection (relative to the undeflected position) of span station 4. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local yb1-axis +ElastoDyn['Spn4RDzb1'] = False # (deg); Blade 1 local torsional (angular/rotational) deflection (relative to the undeflected position) of span station 4. This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the local zb1-axis +ElastoDyn['Spn5RDxb1'] = False # (deg); Blade 1 local roll (angular/rotational) deflection (relative to the undeflected position) of span station 5. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local xb1-axis +ElastoDyn['Spn5RDyb1'] = False # (deg); Blade 1 local pitch (angular/rotational) deflection (relative to the undeflected position) of span station 5. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local yb1-axis +ElastoDyn['Spn5RDzb1'] = False # (deg); Blade 1 local torsional (angular/rotational) deflection (relative to the undeflected position) of span station 5. This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the local zb1-axis +ElastoDyn['Spn6RDxb1'] = False # (deg); Blade 1 local roll (angular/rotational) deflection (relative to the undeflected position) of span station 6. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local xb1-axis +ElastoDyn['Spn6RDyb1'] = False # (deg); Blade 1 local pitch (angular/rotational) deflection (relative to the undeflected position) of span station 6. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local yb1-axis +ElastoDyn['Spn6RDzb1'] = False # (deg); Blade 1 local torsional (angular/rotational) deflection (relative to the undeflected position) of span station 6. This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the local zb1-axis +ElastoDyn['Spn7RDxb1'] = False # (deg); Blade 1 local roll (angular/rotational) deflection (relative to the undeflected position) of span station 7. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local xb1-axis +ElastoDyn['Spn7RDyb1'] = False # (deg); Blade 1 local pitch (angular/rotational) deflection (relative to the undeflected position) of span station 7. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local yb1-axis +ElastoDyn['Spn7RDzb1'] = False # (deg); Blade 1 local torsional (angular/rotational) deflection (relative to the undeflected position) of span station 7. This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the local zb1-axis +ElastoDyn['Spn8RDxb1'] = False # (deg); Blade 1 local roll (angular/rotational) deflection (relative to the undeflected position) of span station 8. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local xb1-axis +ElastoDyn['Spn8RDyb1'] = False # (deg); Blade 1 local pitch (angular/rotational) deflection (relative to the undeflected position) of span station 8. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local yb1-axis +ElastoDyn['Spn8RDzb1'] = False # (deg); Blade 1 local torsional (angular/rotational) deflection (relative to the undeflected position) of span station 8. This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the local zb1-axis +ElastoDyn['Spn9RDxb1'] = False # (deg); Blade 1 local roll (angular/rotational) deflection (relative to the undeflected position) of span station 9. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local xb1-axis +ElastoDyn['Spn9RDyb1'] = False # (deg); Blade 1 local pitch (angular/rotational) deflection (relative to the undeflected position) of span station 9. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local yb1-axis +ElastoDyn['Spn9RDzb1'] = False # (deg); Blade 1 local torsional (angular/rotational) deflection (relative to the undeflected position) of span station 9. This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the local zb1-axis + +# Blade 2 Local Span Motions +ElastoDyn['Spn1ALxb2'] = False # (m/s^2); Blade 2 local flapwise acceleration (absolute) of span station 1; Directed along the local xb2-axis +ElastoDyn['Spn1ALyb2'] = False # (m/s^2); Blade 2 local edgewise acceleration (absolute) of span station 1; Directed along the local yb2-axis +ElastoDyn['Spn1ALzb2'] = False # (m/s^2); Blade 2 local axial acceleration (absolute) of span station 1; Directed along the local zb2-axis +ElastoDyn['Spn2ALxb2'] = False # (m/s^2); Blade 2 local flapwise acceleration (absolute) of span station 2; Directed along the local xb2-axis +ElastoDyn['Spn2ALyb2'] = False # (m/s^2); Blade 2 local edgewise acceleration (absolute) of span station 2; Directed along the local yb2-axis +ElastoDyn['Spn2ALzb2'] = False # (m/s^2); Blade 2 local axial acceleration (absolute) of span station 2; Directed along the local zb2-axis +ElastoDyn['Spn3ALxb2'] = False # (m/s^2); Blade 2 local flapwise acceleration (absolute) of span station 3; Directed along the local xb2-axis +ElastoDyn['Spn3ALyb2'] = False # (m/s^2); Blade 2 local edgewise acceleration (absolute) of span station 3; Directed along the local yb2-axis +ElastoDyn['Spn3ALzb2'] = False # (m/s^2); Blade 2 local axial acceleration (absolute) of span station 3; Directed along the local zb2-axis +ElastoDyn['Spn4ALxb2'] = False # (m/s^2); Blade 2 local flapwise acceleration (absolute) of span station 4; Directed along the local xb2-axis +ElastoDyn['Spn4ALyb2'] = False # (m/s^2); Blade 2 local edgewise acceleration (absolute) of span station 4; Directed along the local yb2-axis +ElastoDyn['Spn4ALzb2'] = False # (m/s^2); Blade 2 local axial acceleration (absolute) of span station 4; Directed along the local zb2-axis +ElastoDyn['Spn5ALxb2'] = False # (m/s^2); Blade 2 local flapwise acceleration (absolute) of span station 5; Directed along the local xb2-axis +ElastoDyn['Spn5ALyb2'] = False # (m/s^2); Blade 2 local edgewise acceleration (absolute) of span station 5; Directed along the local yb2-axis +ElastoDyn['Spn5ALzb2'] = False # (m/s^2); Blade 2 local axial acceleration (absolute) of span station 5; Directed along the local zb2-axis +ElastoDyn['Spn6ALxb2'] = False # (m/s^2); Blade 2 local flapwise acceleration (absolute) of span station 6; Directed along the local xb2-axis +ElastoDyn['Spn6ALyb2'] = False # (m/s^2); Blade 2 local edgewise acceleration (absolute) of span station 6; Directed along the local yb2-axis +ElastoDyn['Spn6ALzb2'] = False # (m/s^2); Blade 2 local axial acceleration (absolute) of span station 6; Directed along the local zb2-axis +ElastoDyn['Spn7ALxb2'] = False # (m/s^2); Blade 2 local flapwise acceleration (absolute) of span station 7; Directed along the local xb2-axis +ElastoDyn['Spn7ALyb2'] = False # (m/s^2); Blade 2 local edgewise acceleration (absolute) of span station 7; Directed along the local yb2-axis +ElastoDyn['Spn7ALzb2'] = False # (m/s^2); Blade 2 local axial acceleration (absolute) of span station 7; Directed along the local zb2-axis +ElastoDyn['Spn8ALxb2'] = False # (m/s^2); Blade 2 local flapwise acceleration (absolute) of span station 8; Directed along the local xb2-axis +ElastoDyn['Spn8ALyb2'] = False # (m/s^2); Blade 2 local edgewise acceleration (absolute) of span station 8; Directed along the local yb2-axis +ElastoDyn['Spn8ALzb2'] = False # (m/s^2); Blade 2 local axial acceleration (absolute) of span station 8; Directed along the local zb2-axis +ElastoDyn['Spn9ALxb2'] = False # (m/s^2); Blade 2 local flapwise acceleration (absolute) of span station 9; Directed along the local xb2-axis +ElastoDyn['Spn9ALyb2'] = False # (m/s^2); Blade 2 local edgewise acceleration (absolute) of span station 9; Directed along the local yb2-axis +ElastoDyn['Spn9ALzb2'] = False # (m/s^2); Blade 2 local axial acceleration (absolute) of span station 9; Directed along the local zb2-axis +ElastoDyn['Spn1ALgxb2'] = False # (m/s^2); Blade 2 local flapwise acceleration (relative to g) of span station 1; Directed along the local xb2-axis +ElastoDyn['Spn1ALgyb2'] = False # (m/s^2); Blade 2 local edgewise acceleration (relative to g) of span station 1; Directed along the local yb2-axis +ElastoDyn['Spn1ALgzb2'] = False # (m/s^2); Blade 2 local axial acceleration (relative to g) of span station 1; Directed along the local zb2-axis +ElastoDyn['Spn2ALgxb2'] = False # (m/s^2); Blade 2 local flapwise acceleration (relative to g) of span station 2; Directed along the local xb2-axis +ElastoDyn['Spn2ALgyb2'] = False # (m/s^2); Blade 2 local edgewise acceleration (relative to g) of span station 2; Directed along the local yb2-axis +ElastoDyn['Spn2ALgzb2'] = False # (m/s^2); Blade 2 local axial acceleration (relative to g) of span station 2; Directed along the local zb2-axis +ElastoDyn['Spn3ALgxb2'] = False # (m/s^2); Blade 2 local flapwise acceleration (relative to g) of span station 3; Directed along the local xb2-axis +ElastoDyn['Spn3ALgyb2'] = False # (m/s^2); Blade 2 local edgewise acceleration (relative to g) of span station 3; Directed along the local yb2-axis +ElastoDyn['Spn3ALgzb2'] = False # (m/s^2); Blade 2 local axial acceleration (relative to g) of span station 3; Directed along the local zb2-axis +ElastoDyn['Spn4ALgxb2'] = False # (m/s^2); Blade 2 local flapwise acceleration (relative to g) of span station 4; Directed along the local xb2-axis +ElastoDyn['Spn4ALgyb2'] = False # (m/s^2); Blade 2 local edgewise acceleration (relative to g) of span station 4; Directed along the local yb2-axis +ElastoDyn['Spn4ALgzb2'] = False # (m/s^2); Blade 2 local axial acceleration (relative to g) of span station 4; Directed along the local zb2-axis +ElastoDyn['Spn5ALgxb2'] = False # (m/s^2); Blade 2 local flapwise acceleration (relative to g) of span station 5; Directed along the local xb2-axis +ElastoDyn['Spn5ALgyb2'] = False # (m/s^2); Blade 2 local edgewise acceleration (relative to g) of span station 5; Directed along the local yb2-axis +ElastoDyn['Spn5ALgzb2'] = False # (m/s^2); Blade 2 local axial acceleration (relative to g) of span station 5; Directed along the local zb2-axis +ElastoDyn['Spn6ALgxb2'] = False # (m/s^2); Blade 2 local flapwise acceleration (relative to g) of span station 6; Directed along the local xb2-axis +ElastoDyn['Spn6ALgyb2'] = False # (m/s^2); Blade 2 local edgewise acceleration (relative to g) of span station 6; Directed along the local yb2-axis +ElastoDyn['Spn6ALgzb2'] = False # (m/s^2); Blade 2 local axial acceleration (relative to g) of span station 6; Directed along the local zb2-axis +ElastoDyn['Spn7ALgxb2'] = False # (m/s^2); Blade 2 local flapwise acceleration (relative to g) of span station 7; Directed along the local xb2-axis +ElastoDyn['Spn7ALgyb2'] = False # (m/s^2); Blade 2 local edgewise acceleration (relative to g) of span station 7; Directed along the local yb2-axis +ElastoDyn['Spn7ALgzb2'] = False # (m/s^2); Blade 2 local axial acceleration (relative to g) of span station 7; Directed along the local zb2-axis +ElastoDyn['Spn8ALgxb2'] = False # (m/s^2); Blade 2 local flapwise acceleration (relative to g) of span station 8; Directed along the local xb2-axis +ElastoDyn['Spn8ALgyb2'] = False # (m/s^2); Blade 2 local edgewise acceleration (relative to g) of span station 8; Directed along the local yb2-axis +ElastoDyn['Spn8ALgzb2'] = False # (m/s^2); Blade 2 local axial acceleration (relative to g) of span station 8; Directed along the local zb2-axis +ElastoDyn['Spn9ALgxb2'] = False # (m/s^2); Blade 2 local flapwise acceleration (relative to g) of span station 9; Directed along the local xb2-axis +ElastoDyn['Spn9ALgyb2'] = False # (m/s^2); Blade 2 local edgewise acceleration (relative to g) of span station 9; Directed along the local yb2-axis +ElastoDyn['Spn9ALgzb2'] = False # (m/s^2); Blade 2 local axial acceleration (relative to g) of span station 9; Directed along the local zb2-axis +ElastoDyn['Spn1TDxb2'] = False # (m); Blade 2 local flapwise (translational) deflection (relative to the undeflected position) of span station 1; Directed along the xb2-axis +ElastoDyn['Spn1TDyb2'] = False # (m); Blade 2 local edgewise (translational) deflection (relative to the undeflected position) of span station 1; Directed along the yb2-axis +ElastoDyn['Spn1TDzb2'] = False # (m); Blade 2 local axial (translational) deflection (relative to the undeflected position) of span station 1; Directed along the zb2-axis +ElastoDyn['Spn2TDxb2'] = False # (m); Blade 2 local flapwise (translational) deflection (relative to the undeflected position) of span station 2; Directed along the xb2-axis +ElastoDyn['Spn2TDyb2'] = False # (m); Blade 2 local edgewise (translational) deflection (relative to the undeflected position) of span station 2; Directed along the yb2-axis +ElastoDyn['Spn2TDzb2'] = False # (m); Blade 2 local axial (translational) deflection (relative to the undeflected position) of span station 2; Directed along the zb2-axis +ElastoDyn['Spn3TDxb2'] = False # (m); Blade 2 local flapwise (translational) deflection (relative to the undeflected position) of span station 3; Directed along the xb2-axis +ElastoDyn['Spn3TDyb2'] = False # (m); Blade 2 local edgewise (translational) deflection (relative to the undeflected position) of span station 3; Directed along the yb2-axis +ElastoDyn['Spn3TDzb2'] = False # (m); Blade 2 local axial (translational) deflection (relative to the undeflected position) of span station 3; Directed along the zb2-axis +ElastoDyn['Spn4TDxb2'] = False # (m); Blade 2 local flapwise (translational) deflection (relative to the undeflected position) of span station 4; Directed along the xb2-axis +ElastoDyn['Spn4TDyb2'] = False # (m); Blade 2 local edgewise (translational) deflection (relative to the undeflected position) of span station 4; Directed along the yb2-axis +ElastoDyn['Spn4TDzb2'] = False # (m); Blade 2 local axial (translational) deflection (relative to the undeflected position) of span station 4; Directed along the zb2-axis +ElastoDyn['Spn5TDxb2'] = False # (m); Blade 2 local flapwise (translational) deflection (relative to the undeflected position) of span station 5; Directed along the xb2-axis +ElastoDyn['Spn5TDyb2'] = False # (m); Blade 2 local edgewise (translational) deflection (relative to the undeflected position) of span station 5; Directed along the yb2-axis +ElastoDyn['Spn5TDzb2'] = False # (m); Blade 2 local axial (translational) deflection (relative to the undeflected position) of span station 5; Directed along the zb2-axis +ElastoDyn['Spn6TDxb2'] = False # (m); Blade 2 local flapwise (translational) deflection (relative to the undeflected position) of span station 6; Directed along the xb2-axis +ElastoDyn['Spn6TDyb2'] = False # (m); Blade 2 local edgewise (translational) deflection (relative to the undeflected position) of span station 6; Directed along the yb2-axis +ElastoDyn['Spn6TDzb2'] = False # (m); Blade 2 local axial (translational) deflection (relative to the undeflected position) of span station 6; Directed along the zb2-axis +ElastoDyn['Spn7TDxb2'] = False # (m); Blade 2 local flapwise (translational) deflection (relative to the undeflected position) of span station 7; Directed along the xb2-axis +ElastoDyn['Spn7TDyb2'] = False # (m); Blade 2 local edgewise (translational) deflection (relative to the undeflected position) of span station 7; Directed along the yb2-axis +ElastoDyn['Spn7TDzb2'] = False # (m); Blade 2 local axial (translational) deflection (relative to the undeflected position) of span station 7; Directed along the zb2-axis +ElastoDyn['Spn8TDxb2'] = False # (m); Blade 2 local flapwise (translational) deflection (relative to the undeflected position) of span station 8; Directed along the xb2-axis +ElastoDyn['Spn8TDyb2'] = False # (m); Blade 2 local edgewise (translational) deflection (relative to the undeflected position) of span station 8; Directed along the yb2-axis +ElastoDyn['Spn8TDzb2'] = False # (m); Blade 2 local axial (translational) deflection (relative to the undeflected position) of span station 8; Directed along the zb2-axis +ElastoDyn['Spn9TDxb2'] = False # (m); Blade 2 local flapwise (translational) deflection (relative to the undeflected position) of span station 9; Directed along the xb2-axis +ElastoDyn['Spn9TDyb2'] = False # (m); Blade 2 local edgewise (translational) deflection (relative to the undeflected position) of span station 9; Directed along the yb2-axis +ElastoDyn['Spn9TDzb2'] = False # (m); Blade 2 local axial (translational) deflection (relative to the undeflected position) of span station 9; Directed along the zb2-axis +ElastoDyn['Spn1RDxb2'] = False # (deg); Blade 2 local roll (angular/rotational) deflection (relative to the undeflected position) of span station 1. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local xb2-axis +ElastoDyn['Spn1RDyb2'] = False # (deg); Blade 2 local pitch (angular/rotational) deflection (relative to the undeflected position) of span station 1. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local yb2-axis +ElastoDyn['Spn1RDzb2'] = False # (deg); Blade 2 local torsional (angular/rotational) deflection (relative to the undeflected position) of span station 1. This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the local zb2-axis +ElastoDyn['Spn2RDxb2'] = False # (deg); Blade 2 local roll (angular/rotational) deflection (relative to the undeflected position) of span station 2. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local xb2-axis +ElastoDyn['Spn2RDyb2'] = False # (deg); Blade 2 local pitch (angular/rotational) deflection (relative to the undeflected position) of span station 2. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local yb2-axis +ElastoDyn['Spn2RDzb2'] = False # (deg); Blade 2 local torsional (angular/rotational) deflection (relative to the undeflected position) of span station 2. This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the local zb2-axis +ElastoDyn['Spn3RDxb2'] = False # (deg); Blade 2 local roll (angular/rotational) deflection (relative to the undeflected position) of span station 3. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local xb2-axis +ElastoDyn['Spn3RDyb2'] = False # (deg); Blade 2 local pitch (angular/rotational) deflection (relative to the undeflected position) of span station 3. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local yb2-axis +ElastoDyn['Spn3RDzb2'] = False # (deg); Blade 2 local torsional (angular/rotational) deflection (relative to the undeflected position) of span station 3. This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the local zb2-axis +ElastoDyn['Spn4RDxb2'] = False # (deg); Blade 2 local roll (angular/rotational) deflection (relative to the undeflected position) of span station 4. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local xb2-axis +ElastoDyn['Spn4RDyb2'] = False # (deg); Blade 2 local pitch (angular/rotational) deflection (relative to the undeflected position) of span station 4. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local yb2-axis +ElastoDyn['Spn4RDzb2'] = False # (deg); Blade 2 local torsional (angular/rotational) deflection (relative to the undeflected position) of span station 4. This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the local zb2-axis +ElastoDyn['Spn5RDxb2'] = False # (deg); Blade 2 local roll (angular/rotational) deflection (relative to the undeflected position) of span station 5. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local xb2-axis +ElastoDyn['Spn5RDyb2'] = False # (deg); Blade 2 local pitch (angular/rotational) deflection (relative to the undeflected position) of span station 5. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local yb2-axis +ElastoDyn['Spn5RDzb2'] = False # (deg); Blade 2 local torsional (angular/rotational) deflection (relative to the undeflected position) of span station 5. This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the local zb2-axis +ElastoDyn['Spn6RDxb2'] = False # (deg); Blade 2 local roll (angular/rotational) deflection (relative to the undeflected position) of span station 6. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local xb2-axis +ElastoDyn['Spn6RDyb2'] = False # (deg); Blade 2 local pitch (angular/rotational) deflection (relative to the undeflected position) of span station 6. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local yb2-axis +ElastoDyn['Spn6RDzb2'] = False # (deg); Blade 2 local torsional (angular/rotational) deflection (relative to the undeflected position) of span station 6. This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the local zb2-axis +ElastoDyn['Spn7RDxb2'] = False # (deg); Blade 2 local roll (angular/rotational) deflection (relative to the undeflected position) of span station 7. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local xb2-axis +ElastoDyn['Spn7RDyb2'] = False # (deg); Blade 2 local pitch (angular/rotational) deflection (relative to the undeflected position) of span station 7. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local yb2-axis +ElastoDyn['Spn7RDzb2'] = False # (deg); Blade 2 local torsional (angular/rotational) deflection (relative to the undeflected position) of span station 7. This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the local zb2-axis +ElastoDyn['Spn8RDxb2'] = False # (deg); Blade 2 local roll (angular/rotational) deflection (relative to the undeflected position) of span station 8. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local xb2-axis +ElastoDyn['Spn8RDyb2'] = False # (deg); Blade 2 local pitch (angular/rotational) deflection (relative to the undeflected position) of span station 8. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local yb2-axis +ElastoDyn['Spn8RDzb2'] = False # (deg); Blade 2 local torsional (angular/rotational) deflection (relative to the undeflected position) of span station 8. This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the local zb2-axis +ElastoDyn['Spn9RDxb2'] = False # (deg); Blade 2 local roll (angular/rotational) deflection (relative to the undeflected position) of span station 9. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local xb2-axis +ElastoDyn['Spn9RDyb2'] = False # (deg); Blade 2 local pitch (angular/rotational) deflection (relative to the undeflected position) of span station 9. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local yb2-axis +ElastoDyn['Spn9RDzb2'] = False # (deg); Blade 2 local torsional (angular/rotational) deflection (relative to the undeflected position) of span station 9. This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the local zb2-axis + +# Blade 3 Local Span Motions +ElastoDyn['Spn1ALxb3'] = False # (m/s^2); Blade 3 local flapwise acceleration (absolute) of span station 1; Directed along the local xb3-axis +ElastoDyn['Spn1ALyb3'] = False # (m/s^2); Blade 3 local edgewise acceleration (absolute) of span station 1; Directed along the local yb3-axis +ElastoDyn['Spn1ALzb3'] = False # (m/s^2); Blade 3 local axial acceleration (absolute) of span station 1; Directed along the local zb3-axis +ElastoDyn['Spn2ALxb3'] = False # (m/s^2); Blade 3 local flapwise acceleration (absolute) of span station 2; Directed along the local xb3-axis +ElastoDyn['Spn2ALyb3'] = False # (m/s^2); Blade 3 local edgewise acceleration (absolute) of span station 2; Directed along the local yb3-axis +ElastoDyn['Spn2ALzb3'] = False # (m/s^2); Blade 3 local axial acceleration (absolute) of span station 2; Directed along the local zb3-axis +ElastoDyn['Spn3ALxb3'] = False # (m/s^2); Blade 3 local flapwise acceleration (absolute) of span station 3; Directed along the local xb3-axis +ElastoDyn['Spn3ALyb3'] = False # (m/s^2); Blade 3 local edgewise acceleration (absolute) of span station 3; Directed along the local yb3-axis +ElastoDyn['Spn3ALzb3'] = False # (m/s^2); Blade 3 local axial acceleration (absolute) of span station 3; Directed along the local zb3-axis +ElastoDyn['Spn4ALxb3'] = False # (m/s^2); Blade 3 local flapwise acceleration (absolute) of span station 4; Directed along the local xb3-axis +ElastoDyn['Spn4ALyb3'] = False # (m/s^2); Blade 3 local edgewise acceleration (absolute) of span station 4; Directed along the local yb3-axis +ElastoDyn['Spn4ALzb3'] = False # (m/s^2); Blade 3 local axial acceleration (absolute) of span station 4; Directed along the local zb3-axis +ElastoDyn['Spn5ALxb3'] = False # (m/s^2); Blade 3 local flapwise acceleration (absolute) of span station 5; Directed along the local xb3-axis +ElastoDyn['Spn5ALyb3'] = False # (m/s^2); Blade 3 local edgewise acceleration (absolute) of span station 5; Directed along the local yb3-axis +ElastoDyn['Spn5ALzb3'] = False # (m/s^2); Blade 3 local axial acceleration (absolute) of span station 5; Directed along the local zb3-axis +ElastoDyn['Spn6ALxb3'] = False # (m/s^2); Blade 3 local flapwise acceleration (absolute) of span station 6; Directed along the local xb3-axis +ElastoDyn['Spn6ALyb3'] = False # (m/s^2); Blade 3 local edgewise acceleration (absolute) of span station 6; Directed along the local yb3-axis +ElastoDyn['Spn6ALzb3'] = False # (m/s^2); Blade 3 local axial acceleration (absolute) of span station 6; Directed along the local zb3-axis +ElastoDyn['Spn7ALxb3'] = False # (m/s^2); Blade 3 local flapwise acceleration (absolute) of span station 7; Directed along the local xb3-axis +ElastoDyn['Spn7ALyb3'] = False # (m/s^2); Blade 3 local edgewise acceleration (absolute) of span station 7; Directed along the local yb3-axis +ElastoDyn['Spn7ALzb3'] = False # (m/s^2); Blade 3 local axial acceleration (absolute) of span station 7; Directed along the local zb3-axis +ElastoDyn['Spn8ALxb3'] = False # (m/s^2); Blade 3 local flapwise acceleration (absolute) of span station 8; Directed along the local xb3-axis +ElastoDyn['Spn8ALyb3'] = False # (m/s^2); Blade 3 local edgewise acceleration (absolute) of span station 8; Directed along the local yb3-axis +ElastoDyn['Spn8ALzb3'] = False # (m/s^2); Blade 3 local axial acceleration (absolute) of span station 8; Directed along the local zb3-axis +ElastoDyn['Spn9ALxb3'] = False # (m/s^2); Blade 3 local flapwise acceleration (absolute) of span station 9; Directed along the local xb3-axis +ElastoDyn['Spn9ALyb3'] = False # (m/s^2); Blade 3 local edgewise acceleration (absolute) of span station 9; Directed along the local yb3-axis +ElastoDyn['Spn9ALzb3'] = False # (m/s^2); Blade 3 local axial acceleration (absolute) of span station 9; Directed along the local zb3-axis +ElastoDyn['Spn1ALgxb3'] = False # (m/s^2); Blade 3 local flapwise acceleration (relative to g) of span station 1; Directed along the local xb3-axis +ElastoDyn['Spn1ALgyb3'] = False # (m/s^2); Blade 3 local edgewise acceleration (relative to g) of span station 1; Directed along the local yb3-axis +ElastoDyn['Spn1ALgzb3'] = False # (m/s^2); Blade 3 local axial acceleration (relative to g) of span station 1; Directed along the local zb3-axis +ElastoDyn['Spn2ALgxb3'] = False # (m/s^2); Blade 3 local flapwise acceleration (relative to g) of span station 2; Directed along the local xb3-axis +ElastoDyn['Spn2ALgyb3'] = False # (m/s^2); Blade 3 local edgewise acceleration (relative to g) of span station 2; Directed along the local yb3-axis +ElastoDyn['Spn2ALgzb3'] = False # (m/s^2); Blade 3 local axial acceleration (relative to g) of span station 2; Directed along the local zb3-axis +ElastoDyn['Spn3ALgxb3'] = False # (m/s^2); Blade 3 local flapwise acceleration (relative to g) of span station 3; Directed along the local xb3-axis +ElastoDyn['Spn3ALgyb3'] = False # (m/s^2); Blade 3 local edgewise acceleration (relative to g) of span station 3; Directed along the local yb3-axis +ElastoDyn['Spn3ALgzb3'] = False # (m/s^2); Blade 3 local axial acceleration (relative to g) of span station 3; Directed along the local zb3-axis +ElastoDyn['Spn4ALgxb3'] = False # (m/s^2); Blade 3 local flapwise acceleration (relative to g) of span station 4; Directed along the local xb3-axis +ElastoDyn['Spn4ALgyb3'] = False # (m/s^2); Blade 3 local edgewise acceleration (relative to g) of span station 4; Directed along the local yb3-axis +ElastoDyn['Spn4ALgzb3'] = False # (m/s^2); Blade 3 local axial acceleration (relative to g) of span station 4; Directed along the local zb3-axis +ElastoDyn['Spn5ALgxb3'] = False # (m/s^2); Blade 3 local flapwise acceleration (relative to g) of span station 5; Directed along the local xb3-axis +ElastoDyn['Spn5ALgyb3'] = False # (m/s^2); Blade 3 local edgewise acceleration (relative to g) of span station 5; Directed along the local yb3-axis +ElastoDyn['Spn5ALgzb3'] = False # (m/s^2); Blade 3 local axial acceleration (relative to g) of span station 5; Directed along the local zb3-axis +ElastoDyn['Spn6ALgxb3'] = False # (m/s^2); Blade 3 local flapwise acceleration (relative to g) of span station 6; Directed along the local xb3-axis +ElastoDyn['Spn6ALgyb3'] = False # (m/s^2); Blade 3 local edgewise acceleration (relative to g) of span station 6; Directed along the local yb3-axis +ElastoDyn['Spn6ALgzb3'] = False # (m/s^2); Blade 3 local axial acceleration (relative to g) of span station 6; Directed along the local zb3-axis +ElastoDyn['Spn7ALgxb3'] = False # (m/s^2); Blade 3 local flapwise acceleration (relative to g) of span station 7; Directed along the local xb3-axis +ElastoDyn['Spn7ALgyb3'] = False # (m/s^2); Blade 3 local edgewise acceleration (relative to g) of span station 7; Directed along the local yb3-axis +ElastoDyn['Spn7ALgzb3'] = False # (m/s^2); Blade 3 local axial acceleration (relative to g) of span station 7; Directed along the local zb3-axis +ElastoDyn['Spn8ALgxb3'] = False # (m/s^2); Blade 3 local flapwise acceleration (relative to g) of span station 8; Directed along the local xb3-axis +ElastoDyn['Spn8ALgyb3'] = False # (m/s^2); Blade 3 local edgewise acceleration (relative to g) of span station 8; Directed along the local yb3-axis +ElastoDyn['Spn8ALgzb3'] = False # (m/s^2); Blade 3 local axial acceleration (relative to g) of span station 8; Directed along the local zb3-axis +ElastoDyn['Spn9ALgxb3'] = False # (m/s^2); Blade 3 local flapwise acceleration (relative to g) of span station 9; Directed along the local xb3-axis +ElastoDyn['Spn9ALgyb3'] = False # (m/s^2); Blade 3 local edgewise acceleration (relative to g) of span station 9; Directed along the local yb3-axis +ElastoDyn['Spn9ALgzb3'] = False # (m/s^2); Blade 3 local axial acceleration (relative to g) of span station 9; Directed along the local zb3-axis +ElastoDyn['Spn1TDxb3'] = False # (m); Blade 3 local flapwise (translational) deflection (relative to the undeflected position) of span station 1; Directed along the xb3-axis +ElastoDyn['Spn1TDyb3'] = False # (m); Blade 3 local edgewise (translational) deflection (relative to the undeflected position) of span station 1; Directed along the yb3-axis +ElastoDyn['Spn1TDzb3'] = False # (m); Blade 3 local axial (translational) deflection (relative to the undeflected position) of span station 1; Directed along the zb3-axis +ElastoDyn['Spn2TDxb3'] = False # (m); Blade 3 local flapwise (translational) deflection (relative to the undeflected position) of span station 2; Directed along the xb3-axis +ElastoDyn['Spn2TDyb3'] = False # (m); Blade 3 local edgewise (translational) deflection (relative to the undeflected position) of span station 2; Directed along the yb3-axis +ElastoDyn['Spn2TDzb3'] = False # (m); Blade 3 local axial (translational) deflection (relative to the undeflected position) of span station 2; Directed along the zb3-axis +ElastoDyn['Spn3TDxb3'] = False # (m); Blade 3 local flapwise (translational) deflection (relative to the undeflected position) of span station 3; Directed along the xb3-axis +ElastoDyn['Spn3TDyb3'] = False # (m); Blade 3 local edgewise (translational) deflection (relative to the undeflected position) of span station 3; Directed along the yb3-axis +ElastoDyn['Spn3TDzb3'] = False # (m); Blade 3 local axial (translational) deflection (relative to the undeflected position) of span station 3; Directed along the zb3-axis +ElastoDyn['Spn4TDxb3'] = False # (m); Blade 3 local flapwise (translational) deflection (relative to the undeflected position) of span station 4; Directed along the xb3-axis +ElastoDyn['Spn4TDyb3'] = False # (m); Blade 3 local edgewise (translational) deflection (relative to the undeflected position) of span station 4; Directed along the yb3-axis +ElastoDyn['Spn4TDzb3'] = False # (m); Blade 3 local axial (translational) deflection (relative to the undeflected position) of span station 4; Directed along the zb3-axis +ElastoDyn['Spn5TDxb3'] = False # (m); Blade 3 local flapwise (translational) deflection (relative to the undeflected position) of span station 5; Directed along the xb3-axis +ElastoDyn['Spn5TDyb3'] = False # (m); Blade 3 local edgewise (translational) deflection (relative to the undeflected position) of span station 5; Directed along the yb3-axis +ElastoDyn['Spn5TDzb3'] = False # (m); Blade 3 local axial (translational) deflection (relative to the undeflected position) of span station 5; Directed along the zb3-axis +ElastoDyn['Spn6TDxb3'] = False # (m); Blade 3 local flapwise (translational) deflection (relative to the undeflected position) of span station 6; Directed along the xb3-axis +ElastoDyn['Spn6TDyb3'] = False # (m); Blade 3 local edgewise (translational) deflection (relative to the undeflected position) of span station 6; Directed along the yb3-axis +ElastoDyn['Spn6TDzb3'] = False # (m); Blade 3 local axial (translational) deflection (relative to the undeflected position) of span station 6; Directed along the zb3-axis +ElastoDyn['Spn7TDxb3'] = False # (m); Blade 3 local flapwise (translational) deflection (relative to the undeflected position) of span station 7; Directed along the xb3-axis +ElastoDyn['Spn7TDyb3'] = False # (m); Blade 3 local edgewise (translational) deflection (relative to the undeflected position) of span station 7; Directed along the yb3-axis +ElastoDyn['Spn7TDzb3'] = False # (m); Blade 3 local axial (translational) deflection (relative to the undeflected position) of span station 7; Directed along the zb3-axis +ElastoDyn['Spn8TDxb3'] = False # (m); Blade 3 local flapwise (translational) deflection (relative to the undeflected position) of span station 8; Directed along the xb3-axis +ElastoDyn['Spn8TDyb3'] = False # (m); Blade 3 local edgewise (translational) deflection (relative to the undeflected position) of span station 8; Directed along the yb3-axis +ElastoDyn['Spn8TDzb3'] = False # (m); Blade 3 local axial (translational) deflection (relative to the undeflected position) of span station 8; Directed along the zb3-axis +ElastoDyn['Spn9TDxb3'] = False # (m); Blade 3 local flapwise (translational) deflection (relative to the undeflected position) of span station 9; Directed along the xb3-axis +ElastoDyn['Spn9TDyb3'] = False # (m); Blade 3 local edgewise (translational) deflection (relative to the undeflected position) of span station 9; Directed along the yb3-axis +ElastoDyn['Spn9TDzb3'] = False # (m); Blade 3 local axial (translational) deflection (relative to the undeflected position) of span station 9; Directed along the zb3-axis +ElastoDyn['Spn1RDxb3'] = False # (deg); Blade 3 local roll (angular/rotational) deflection (relative to the undeflected position) of span station 1. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local xb3-axis +ElastoDyn['Spn1RDyb3'] = False # (deg); Blade 3 local pitch (angular/rotational) deflection (relative to the undeflected position) of span station 1. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local yb3-axis +ElastoDyn['Spn1RDzb3'] = False # (deg); Blade 3 local torsional (angular/rotational) deflection (relative to the undeflected position) of span station 1. This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the local zb3-axis +ElastoDyn['Spn2RDxb3'] = False # (deg); Blade 3 local roll (angular/rotational) deflection (relative to the undeflected position) of span station 2. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local xb3-axis +ElastoDyn['Spn2RDyb3'] = False # (deg); Blade 3 local pitch (angular/rotational) deflection (relative to the undeflected position) of span station 2. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local yb3-axis +ElastoDyn['Spn2RDzb3'] = False # (deg); Blade 3 local torsional (angular/rotational) deflection (relative to the undeflected position) of span station 2. This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the local zb3-axis +ElastoDyn['Spn3RDxb3'] = False # (deg); Blade 3 local roll (angular/rotational) deflection (relative to the undeflected position) of span station 3. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local xb3-axis +ElastoDyn['Spn3RDyb3'] = False # (deg); Blade 3 local pitch (angular/rotational) deflection (relative to the undeflected position) of span station 3. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local yb3-axis +ElastoDyn['Spn3RDzb3'] = False # (deg); Blade 3 local torsional (angular/rotational) deflection (relative to the undeflected position) of span station 3. This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the local zb3-axis +ElastoDyn['Spn4RDxb3'] = False # (deg); Blade 3 local roll (angular/rotational) deflection (relative to the undeflected position) of span station 4. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local xb3-axis +ElastoDyn['Spn4RDyb3'] = False # (deg); Blade 3 local pitch (angular/rotational) deflection (relative to the undeflected position) of span station 4. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local yb3-axis +ElastoDyn['Spn4RDzb3'] = False # (deg); Blade 3 local torsional (angular/rotational) deflection (relative to the undeflected position) of span station 4. This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the local zb3-axis +ElastoDyn['Spn5RDxb3'] = False # (deg); Blade 3 local roll (angular/rotational) deflection (relative to the undeflected position) of span station 5. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local xb3-axis +ElastoDyn['Spn5RDyb3'] = False # (deg); Blade 3 local pitch (angular/rotational) deflection (relative to the undeflected position) of span station 5. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local yb3-axis +ElastoDyn['Spn5RDzb3'] = False # (deg); Blade 3 local torsional (angular/rotational) deflection (relative to the undeflected position) of span station 5. This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the local zb3-axis +ElastoDyn['Spn6RDxb3'] = False # (deg); Blade 3 local roll (angular/rotational) deflection (relative to the undeflected position) of span station 6. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local xb3-axis +ElastoDyn['Spn6RDyb3'] = False # (deg); Blade 3 local pitch (angular/rotational) deflection (relative to the undeflected position) of span station 6. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local yb3-axis +ElastoDyn['Spn6RDzb3'] = False # (deg); Blade 3 local torsional (angular/rotational) deflection (relative to the undeflected position) of span station 6. This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the local zb3-axis +ElastoDyn['Spn7RDxb3'] = False # (deg); Blade 3 local roll (angular/rotational) deflection (relative to the undeflected position) of span station 7. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local xb3-axis +ElastoDyn['Spn7RDyb3'] = False # (deg); Blade 3 local pitch (angular/rotational) deflection (relative to the undeflected position) of span station 7. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local yb3-axis +ElastoDyn['Spn7RDzb3'] = False # (deg); Blade 3 local torsional (angular/rotational) deflection (relative to the undeflected position) of span station 7. This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the local zb3-axis +ElastoDyn['Spn8RDxb3'] = False # (deg); Blade 3 local roll (angular/rotational) deflection (relative to the undeflected position) of span station 8. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local xb3-axis +ElastoDyn['Spn8RDyb3'] = False # (deg); Blade 3 local pitch (angular/rotational) deflection (relative to the undeflected position) of span station 8. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local yb3-axis +ElastoDyn['Spn8RDzb3'] = False # (deg); Blade 3 local torsional (angular/rotational) deflection (relative to the undeflected position) of span station 8. This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the local zb3-axis +ElastoDyn['Spn9RDxb3'] = False # (deg); Blade 3 local roll (angular/rotational) deflection (relative to the undeflected position) of span station 9. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local xb3-axis +ElastoDyn['Spn9RDyb3'] = False # (deg); Blade 3 local pitch (angular/rotational) deflection (relative to the undeflected position) of span station 9. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local yb3-axis +ElastoDyn['Spn9RDzb3'] = False # (deg); Blade 3 local torsional (angular/rotational) deflection (relative to the undeflected position) of span station 9. This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the local zb3-axis + +# Blade Pitch Motions +ElastoDyn['PtchPMzc1'] = False # (deg); Blade 1 pitch angle (position); Positive towards feather about the minus zc1- and minus zb1-axes +ElastoDyn['PtchPMzb1'] = False # (deg); Blade 1 pitch angle (position); Positive towards feather about the minus zc1- and minus zb1-axes +ElastoDyn['BldPitch1'] = False # (deg); Blade 1 pitch angle (position); Positive towards feather about the minus zc1- and minus zb1-axes +ElastoDyn['BlPitch1'] = False # (deg); Blade 1 pitch angle (position); Positive towards feather about the minus zc1- and minus zb1-axes +ElastoDyn['PtchPMzc2'] = False # (deg); Blade 2 pitch angle (position); Positive towards feather about the minus zc2- and minus zb2-axes +ElastoDyn['PtchPMzb2'] = False # (deg); Blade 2 pitch angle (position); Positive towards feather about the minus zc2- and minus zb2-axes +ElastoDyn['BldPitch2'] = False # (deg); Blade 2 pitch angle (position); Positive towards feather about the minus zc2- and minus zb2-axes +ElastoDyn['BlPitch2'] = False # (deg); Blade 2 pitch angle (position); Positive towards feather about the minus zc2- and minus zb2-axes +ElastoDyn['PtchPMzc3'] = False # (deg); Blade 3 pitch angle (position); Positive towards feather about the minus zc3- and minus zb3-axes +ElastoDyn['PtchPMzb3'] = False # (deg); Blade 3 pitch angle (position); Positive towards feather about the minus zc3- and minus zb3-axes +ElastoDyn['BldPitch3'] = False # (deg); Blade 3 pitch angle (position); Positive towards feather about the minus zc3- and minus zb3-axes +ElastoDyn['BlPitch3'] = False # (deg); Blade 3 pitch angle (position); Positive towards feather about the minus zc3- and minus zb3-axes + +# Teeter Motions +ElastoDyn['TeetPya'] = False # (deg); Rotor teeter angle (position); About the ya-axis +ElastoDyn['RotTeetP'] = False # (deg); Rotor teeter angle (position); About the ya-axis +ElastoDyn['TeetDefl'] = False # (deg); Rotor teeter angle (position); About the ya-axis +ElastoDyn['TeetVya'] = False # (deg/s); Rotor teeter angular velocity; About the ya-axis +ElastoDyn['RotTeetV'] = False # (deg/s); Rotor teeter angular velocity; About the ya-axis +ElastoDyn['TeetAya'] = False # (deg/s^2); Rotor teeter angular acceleration; About the ya-axis +ElastoDyn['RotTeetA'] = False # (deg/s^2); Rotor teeter angular acceleration; About the ya-axis + +# Shaft Motions +ElastoDyn['LSSTipPxa'] = False # (deg); Rotor azimuth angle (position); About the xa- and xs-axes +ElastoDyn['LSSTipPxs'] = False # (deg); Rotor azimuth angle (position); About the xa- and xs-axes +ElastoDyn['LSSTipP'] = False # (deg); Rotor azimuth angle (position); About the xa- and xs-axes +ElastoDyn['Azimuth'] = False # (deg); Rotor azimuth angle (position); About the xa- and xs-axes +ElastoDyn['LSSTipVxa'] = False # (rpm); Rotor azimuth angular speed; About the xa- and xs-axes +ElastoDyn['LSSTipVxs'] = False # (rpm); Rotor azimuth angular speed; About the xa- and xs-axes +ElastoDyn['LSSTipV'] = False # (rpm); Rotor azimuth angular speed; About the xa- and xs-axes +ElastoDyn['RotSpeed'] = False # (rpm); Rotor azimuth angular speed; About the xa- and xs-axes +ElastoDyn['LSSTipAxa'] = False # (deg/s^2); Rotor azimuth angular acceleration; About the xa- and xs-axes +ElastoDyn['LSSTipAxs'] = False # (deg/s^2); Rotor azimuth angular acceleration; About the xa- and xs-axes +ElastoDyn['LSSTipA'] = False # (deg/s^2); Rotor azimuth angular acceleration; About the xa- and xs-axes +ElastoDyn['RotAccel'] = False # (deg/s^2); Rotor azimuth angular acceleration; About the xa- and xs-axes +ElastoDyn['LSSGagPxa'] = False # (deg); Low-speed shaft strain gage azimuth angle (position) (on the gearbox side of the low-speed shaft); About the xa- and xs-axes +ElastoDyn['LSSGagPxs'] = False # (deg); Low-speed shaft strain gage azimuth angle (position) (on the gearbox side of the low-speed shaft); About the xa- and xs-axes +ElastoDyn['LSSGagP'] = False # (deg); Low-speed shaft strain gage azimuth angle (position) (on the gearbox side of the low-speed shaft); About the xa- and xs-axes +ElastoDyn['LSSGagVxa'] = False # (rpm); Low-speed shaft strain gage angular speed (on the gearbox side of the low-speed shaft); About the xa- and xs-axes +ElastoDyn['LSSGagVxs'] = False # (rpm); Low-speed shaft strain gage angular speed (on the gearbox side of the low-speed shaft); About the xa- and xs-axes +ElastoDyn['LSSGagV'] = False # (rpm); Low-speed shaft strain gage angular speed (on the gearbox side of the low-speed shaft); About the xa- and xs-axes +ElastoDyn['LSSGagAxa'] = False # (deg/s^2); Low-speed shaft strain gage angular acceleration (on the gearbox side of the low-speed shaft); About the xa- and xs-axes +ElastoDyn['LSSGagAxs'] = False # (deg/s^2); Low-speed shaft strain gage angular acceleration (on the gearbox side of the low-speed shaft); About the xa- and xs-axes +ElastoDyn['LSSGagA'] = False # (deg/s^2); Low-speed shaft strain gage angular acceleration (on the gearbox side of the low-speed shaft); About the xa- and xs-axes +ElastoDyn['HSShftV'] = False # (rpm); Angular speed of the high-speed shaft and generator; Same sign as LSSGagVxa / LSSGagVxs / LSSGagV +ElastoDyn['GenSpeed'] = False # (rpm); Angular speed of the high-speed shaft and generator; Same sign as LSSGagVxa / LSSGagVxs / LSSGagV +ElastoDyn['HSShftA'] = False # (deg/s^2); Angular acceleration of the high-speed shaft and generator; Same sign as LSSGagAxa / LSSGagAxs / LSSGagA +ElastoDyn['GenAccel'] = False # (deg/s^2); Angular acceleration of the high-speed shaft and generator; Same sign as LSSGagAxa / LSSGagAxs / LSSGagA + +# Nacelle IMU Motions +ElastoDyn['NcIMUTVxs'] = False # (m/s); Nacelle inertial measurement unit translational velocity (absolute); Directed along the xs-axis +ElastoDyn['NcIMUTVys'] = False # (m/s); Nacelle inertial measurement unit translational velocity (absolute); Directed along the ys-axis +ElastoDyn['NcIMUTVzs'] = False # (m/s); Nacelle inertial measurement unit translational velocity (absolute); Directed along the zs-axis +ElastoDyn['NcIMUTAxs'] = False # (m/s^2); Nacelle inertial measurement unit translational acceleration (absolute); Directed along the xs-axis +ElastoDyn['NcIMUTAys'] = False # (m/s^2); Nacelle inertial measurement unit translational acceleration (absolute); Directed along the ys-axis +ElastoDyn['NcIMUTAzs'] = False # (m/s^2); Nacelle inertial measurement unit translational acceleration (absolute); Directed along the zs-axis +ElastoDyn['NcIMUTAgxs'] = False # (m/s^2); Nacelle inertial measurement unit translational acceleration (relative to g); Directed along the xs-axis +ElastoDyn['NcIMUTAgys'] = False # (m/s^2); Nacelle inertial measurement unit translational acceleration (relative to g); Directed along the ys-axis +ElastoDyn['NcIMUTAgzs'] = False # (m/s^2); Nacelle inertial measurement unit translational acceleration (relative to g); Directed along the zs-axis +ElastoDyn['NcIMURVxs'] = False # (deg/s); Nacelle inertial measurement unit angular (rotational) velocity (absolute); About the xs-axis +ElastoDyn['NcIMURVys'] = False # (deg/s); Nacelle inertial measurement unit angular (rotational) velocity (absolute); About the ys-axis +ElastoDyn['NcIMURVzs'] = False # (deg/s); Nacelle inertial measurement unit angular (rotational) velocity (absolute); About the zs-axis +ElastoDyn['NcIMURAxs'] = False # (deg/s^2); Nacelle inertial measurement unit angular (rotational) acceleration (absolute); About the xs-axis +ElastoDyn['NcIMURAys'] = False # (deg/s^2); Nacelle inertial measurement unit angular (rotational) acceleration (absolute); About the ys-axis +ElastoDyn['NcIMURAzs'] = False # (deg/s^2); Nacelle inertial measurement unit angular (rotational) acceleration (absolute); About the zs-axis + +# Rotor-Furl Motions +ElastoDyn['RotFurlP'] = False # (deg); Rotor-furl angle (position); About the rotor-furl axis +ElastoDyn['RotFurl'] = False # (deg); Rotor-furl angle (position); About the rotor-furl axis +ElastoDyn['RotFurlV'] = False # (deg/s); Rotor-furl angular velocity; About the rotor-furl axis +ElastoDyn['RotFurlA'] = False # (deg/s^2); Rotor-furl angular acceleration; About the rotor-furl axis + +# Tail-Furl Motions +ElastoDyn['TailFurlP'] = False # (deg); Tail-furl angle (position); About the tail-furl axis +ElastoDyn['TailFurl'] = False # (deg); Tail-furl angle (position); About the tail-furl axis +ElastoDyn['TailFurlV'] = False # (deg/s); Tail-furl angular velocity; About the tail-furl axis +ElastoDyn['TailFurlA'] = False # (deg/s^2); Tail-furl angular acceleration; About the tail-furl axis + +# Nacelle Yaw Motions +ElastoDyn['YawPzn'] = False # (deg); Nacelle yaw angle (position); About the zn- and zp-axes +ElastoDyn['YawPzp'] = False # (deg); Nacelle yaw angle (position); About the zn- and zp-axes +ElastoDyn['NacYawP'] = False # (deg); Nacelle yaw angle (position); About the zn- and zp-axes +ElastoDyn['NacYaw'] = False # (deg); Nacelle yaw angle (position); About the zn- and zp-axes +ElastoDyn['YawPos'] = False # (deg); Nacelle yaw angle (position); About the zn- and zp-axes +ElastoDyn['YawVzn'] = False # (deg/s); Nacelle yaw angular velocity; About the zn- and zp-axes +ElastoDyn['YawVzp'] = False # (deg/s); Nacelle yaw angular velocity; About the zn- and zp-axes +ElastoDyn['NacYawV'] = False # (deg/s); Nacelle yaw angular velocity; About the zn- and zp-axes +ElastoDyn['YawRate'] = False # (deg/s); Nacelle yaw angular velocity; About the zn- and zp-axes +ElastoDyn['YawAzn'] = False # (deg/s^2); Nacelle yaw angular acceleration; About the zn- and zp-axes +ElastoDyn['YawAzp'] = False # (deg/s^2); Nacelle yaw angular acceleration; About the zn- and zp-axes +ElastoDyn['NacYawA'] = False # (deg/s^2); Nacelle yaw angular acceleration; About the zn- and zp-axes +ElastoDyn['YawAccel'] = False # (deg/s^2); Nacelle yaw angular acceleration; About the zn- and zp-axes + +# Tower-Top / Yaw Bearing Motions +ElastoDyn['TwrTpTDxi'] = False # (m); Tower-top / yaw bearing fore-aft (translational) deflection (relative to the undeflected position) including all platform motions; Directed along the xi-axis +ElastoDyn['YawBrTDxi'] = False # (m); Tower-top / yaw bearing fore-aft (translational) deflection (relative to the undeflected position) including all platform motions; Directed along the xi-axis +ElastoDyn['TwrTpTDyi'] = False # (m); Tower-top / yaw bearing side-to-side (translational) deflection (relative to the undeflected position) including all platform motions; Directed along the yi-axis +ElastoDyn['YawBrTDyi'] = False # (m); Tower-top / yaw bearing side-to-side (translational) deflection (relative to the undeflected position) including all platform motions; Directed along the yi-axis +ElastoDyn['TwrTpTDzi'] = False # (m); Tower-top / yaw bearing axial (translational) deflection (relative to the undeflected position) including all platform motions; Directed along the zi-axis +ElastoDyn['YawBrTDzi'] = False # (m); Tower-top / yaw bearing axial (translational) deflection (relative to the undeflected position) including all platform motions; Directed along the zi-axis +ElastoDyn['YawBrTDxp'] = False # (m); Tower-top / yaw bearing fore-aft (translational) deflection (relative to the undeflected position); Directed along the xp-axis +ElastoDyn['YawBrTDyp'] = False # (m); Tower-top / yaw bearing side-to-side (translational) deflection (relative to the undeflected position); Directed along the yp-axis +ElastoDyn['YawBrTDzp'] = False # (m); Tower-top / yaw bearing axial (translational) deflection (relative to the undeflected position); Directed along the zp-axis +ElastoDyn['YawBrTDxt'] = False # (m); Tower-top / yaw bearing fore-aft (translational) deflection (relative to the undeflected position); Directed along the xt-axis +ElastoDyn['TTDspFA'] = False # (m); Tower-top / yaw bearing fore-aft (translational) deflection (relative to the undeflected position); Directed along the xt-axis +ElastoDyn['YawBrTDyt'] = False # (m); Tower-top / yaw bearing side-to-side (translation) deflection (relative to the undeflected position); Directed along the yt-axis +ElastoDyn['TTDspSS'] = False # (m); Tower-top / yaw bearing side-to-side (translation) deflection (relative to the undeflected position); Directed along the yt-axis +ElastoDyn['YawBrTDzt'] = False # (m); Tower-top / yaw bearing axial (translational) deflection (relative to the undeflected position); Directed along the zt-axis +ElastoDyn['TTDspAx'] = False # (m); Tower-top / yaw bearing axial (translational) deflection (relative to the undeflected position); Directed along the zt-axis +ElastoDyn['YawBrTVxp'] = False # (m/s); Tower-top / yaw bearing fore-aft (translational) velocity (absolute); Directed along the xp-axis +ElastoDyn['YawBrTVyp'] = False # (m/s); Tower-top / yaw bearing side-to-side (translational) velocity (absolute); Directed along the yp-axis +ElastoDyn['YawBrTVzp'] = False # (m/s); Tower-top / yaw bearing axial (translational) velocity (absolute); Directed along the zp-axis +ElastoDyn['YawBrTAxp'] = False # (m/s^2); Tower-top / yaw bearing fore-aft (translational) acceleration (absolute); Directed along the xp-axis +ElastoDyn['YawBrTAyp'] = False # (m/s^2); Tower-top / yaw bearing side-to-side (translational) acceleration (absolute); Directed along the yp-axis +ElastoDyn['YawBrTAzp'] = False # (m/s^2); Tower-top / yaw bearing axial (translational) acceleration (absolute); Directed along the zp-axis +ElastoDyn['YawBrTAgxp'] = False # (m/s^2); Tower-top / yaw bearing fore-aft (translational) acceleration (relative to g); Directed along the xp-axis +ElastoDyn['YawBrTAgyp'] = False # (m/s^2); Tower-top / yaw bearing side-to-side (translational) acceleration (relative to g); Directed along the yp-axis +ElastoDyn['YawBrTAgzp'] = False # (m/s^2); Tower-top / yaw bearing axial (translational) acceleration (relative to g); Directed along the zp-axis +ElastoDyn['YawBrRDxt'] = False # (deg); Tower-top / yaw bearing angular (rotational) roll deflection (relative to the undeflected position). In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower deflections, so that the rotation sequence does not matter.; About the xt-axis +ElastoDyn['TTDspRoll'] = False # (deg); Tower-top / yaw bearing angular (rotational) roll deflection (relative to the undeflected position). In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower deflections, so that the rotation sequence does not matter.; About the xt-axis +ElastoDyn['YawBrRDyt'] = False # (deg); Tower-top / yaw bearing angular (rotational) pitch deflection (relative to the undeflected position). In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower deflections, so that the rotation sequence does not matter.; About the yt-axis +ElastoDyn['TTDspPtch'] = False # (deg); Tower-top / yaw bearing angular (rotational) pitch deflection (relative to the undeflected position). In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower deflections, so that the rotation sequence does not matter.; About the yt-axis +ElastoDyn['YawBrRDzt'] = False # (deg); Tower-top / yaw bearing angular (rotational) torsion deflection (relative to the undeflected position). This output will always be zero for FAST simulation results. Use it for examining tower torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence.; About the zt-axis +ElastoDyn['TTDspTwst'] = False # (deg); Tower-top / yaw bearing angular (rotational) torsion deflection (relative to the undeflected position). This output will always be zero for FAST simulation results. Use it for examining tower torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence.; About the zt-axis +ElastoDyn['YawBrRVxp'] = False # (deg/s); Tower-top / yaw bearing angular (rotational) roll velocity (absolute); About the xp-axis +ElastoDyn['YawBrRVyp'] = False # (deg/s); Tower-top / yaw bearing angular (rotational) pitch velocity (absolute); About the yp-axis +ElastoDyn['YawBrRVzp'] = False # (deg/s); Tower-top / yaw bearing angular (rotational) torsion velocity. This output will always be very close to zero for FAST simulation results. Use it for examining tower torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. (absolute); About the zp-axis +ElastoDyn['YawBrRAxp'] = False # (deg/s^2); Tower-top / yaw bearing angular (rotational) roll acceleration (absolute); About the xp-axis +ElastoDyn['YawBrRAyp'] = False # (deg/s^2); Tower-top / yaw bearing angular (rotational) pitch acceleration (absolute); About the yp-axis +ElastoDyn['YawBrRAzp'] = False # (deg/s^2); Tower-top / yaw bearing angular (rotational) torsion acceleration. This output will always be very close to zero for FAST simulation results. Use it for examining tower torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. (absolute); About the zp-axis + +# Local Tower Motions +ElastoDyn['TwHt1ALxt'] = False # (m/s^2); Local tower fore-aft (translational) acceleration (absolute) of tower gage 1 ; Directed along the local xt-axis +ElastoDyn['TwHt1ALyt'] = False # (m/s^2); Local tower side-to-side (translational) acceleration (absolute) of tower gage 1 ; Directed along the local yt-axis +ElastoDyn['TwHt1ALzt'] = False # (m/s^2); Local tower axial (translational) acceleration (absolute) of tower gage 1 ; Directed along the local zt-axis +ElastoDyn['TwHt2ALxt'] = False # (m/s^2); Local tower fore-aft (translational) acceleration (absolute) of tower gage 2; Directed along the local xt-axis +ElastoDyn['TwHt2ALyt'] = False # (m/s^2); Local tower side-to-side (translational) acceleration (absolute) of tower gage 2; Directed along the local yt-axis +ElastoDyn['TwHt2ALzt'] = False # (m/s^2); Local tower axial (translational) acceleration (absolute) of tower gage 2; Directed along the local zt-axis +ElastoDyn['TwHt3ALxt'] = False # (m/s^2); Local tower fore-aft (translational) acceleration (absolute) of tower gage 3; Directed along the local xt-axis +ElastoDyn['TwHt3ALyt'] = False # (m/s^2); Local tower side-to-side (translational) acceleration (absolute) of tower gage 3; Directed along the local yt-axis +ElastoDyn['TwHt3ALzt'] = False # (m/s^2); Local tower axial (translational) acceleration (absolute) of tower gage 3; Directed along the local zt-axis +ElastoDyn['TwHt4ALxt'] = False # (m/s^2); Local tower fore-aft (translational) acceleration (absolute) of tower gage 4; Directed along the local xt-axis +ElastoDyn['TwHt4ALyt'] = False # (m/s^2); Local tower side-to-side (translational) acceleration (absolute) of tower gage 4; Directed along the local yt-axis +ElastoDyn['TwHt4ALzt'] = False # (m/s^2); Local tower axial (translational) acceleration (absolute) of tower gage 4; Directed along the local zt-axis +ElastoDyn['TwHt5ALxt'] = False # (m/s^2); Local tower fore-aft (translational) acceleration (absolute) of tower gage 5; Directed along the local xt-axis +ElastoDyn['TwHt5ALyt'] = False # (m/s^2); Local tower side-to-side (translational) acceleration (absolute) of tower gage 5; Directed along the local yt-axis +ElastoDyn['TwHt5ALzt'] = False # (m/s^2); Local tower axial (translational) acceleration (absolute) of tower gage 5; Directed along the local zt-axis +ElastoDyn['TwHt6ALxt'] = False # (m/s^2); Local tower fore-aft (translational) acceleration (absolute) of tower gage 6; Directed along the local xt-axis +ElastoDyn['TwHt6ALyt'] = False # (m/s^2); Local tower side-to-side (translational) acceleration (absolute) of tower gage 6; Directed along the local yt-axis +ElastoDyn['TwHt6ALzt'] = False # (m/s^2); Local tower axial (translational) acceleration (absolute) of tower gage 6; Directed along the local zt-axis +ElastoDyn['TwHt7ALxt'] = False # (m/s^2); Local tower fore-aft (translational) acceleration (absolute) of tower gage 7; Directed along the local xt-axis +ElastoDyn['TwHt7ALyt'] = False # (m/s^2); Local tower side-to-side (translational) acceleration (absolute) of tower gage 7; Directed along the local yt-axis +ElastoDyn['TwHt7ALzt'] = False # (m/s^2); Local tower axial (translational) acceleration (absolute) of tower gage 7; Directed along the local zt-axis +ElastoDyn['TwHt8ALxt'] = False # (m/s^2); Local tower fore-aft (translational) acceleration (absolute) of tower gage 8; Directed along the local xt-axis +ElastoDyn['TwHt8ALyt'] = False # (m/s^2); Local tower side-to-side (translational) acceleration (absolute) of tower gage 8; Directed along the local yt-axis +ElastoDyn['TwHt8ALzt'] = False # (m/s^2); Local tower axial (translational) acceleration (absolute) of tower gage 8; Directed along the local zt-axis +ElastoDyn['TwHt9ALxt'] = False # (m/s^2); Local tower fore-aft (translational) acceleration (absolute) of tower gage 9; Directed along the local xt-axis +ElastoDyn['TwHt9ALyt'] = False # (m/s^2); Local tower side-to-side (translational) acceleration (absolute) of tower gage 9; Directed along the local yt-axis +ElastoDyn['TwHt9ALzt'] = False # (m/s^2); Local tower axial (translational) acceleration (absolute) of tower gage 9; Directed along the local zt-axis +ElastoDyn['TwHt1ALgxt'] = False # (m/s^2); Local tower fore-aft (translational) acceleration (relative to g) of tower gage 1 ; Directed along the local xt-axis +ElastoDyn['TwHt1ALgyt'] = False # (m/s^2); Local tower side-to-side (translational) acceleration (relative to g) of tower gage 1 ; Directed along the local yt-axis +ElastoDyn['TwHt1ALgzt'] = False # (m/s^2); Local tower axial (translational) acceleration (relative to g) of tower gage 1 ; Directed along the local zt-axis +ElastoDyn['TwHt2ALgxt'] = False # (m/s^2); Local tower fore-aft (translational) acceleration (relative to g) of tower gage 2; Directed along the local xt-axis +ElastoDyn['TwHt2ALgyt'] = False # (m/s^2); Local tower side-to-side (translational) acceleration (relative to g) of tower gage 2; Directed along the local yt-axis +ElastoDyn['TwHt2ALgzt'] = False # (m/s^2); Local tower axial (translational) acceleration (relative to g) of tower gage 2; Directed along the local zt-axis +ElastoDyn['TwHt3ALgxt'] = False # (m/s^2); Local tower fore-aft (translational) acceleration (relative to g) of tower gage 3; Directed along the local xt-axis +ElastoDyn['TwHt3ALgyt'] = False # (m/s^2); Local tower side-to-side (translational) acceleration (relative to g) of tower gage 3; Directed along the local yt-axis +ElastoDyn['TwHt3ALgzt'] = False # (m/s^2); Local tower axial (translational) acceleration (relative to g) of tower gage 3; Directed along the local zt-axis +ElastoDyn['TwHt4ALgxt'] = False # (m/s^2); Local tower fore-aft (translational) acceleration (relative to g) of tower gage 4; Directed along the local xt-axis +ElastoDyn['TwHt4ALgyt'] = False # (m/s^2); Local tower side-to-side (translational) acceleration (relative to g) of tower gage 4; Directed along the local yt-axis +ElastoDyn['TwHt4ALgzt'] = False # (m/s^2); Local tower axial (translational) acceleration (relative to g) of tower gage 4; Directed along the local zt-axis +ElastoDyn['TwHt5ALgxt'] = False # (m/s^2); Local tower fore-aft (translational) acceleration (relative to g) of tower gage 5; Directed along the local xt-axis +ElastoDyn['TwHt5ALgyt'] = False # (m/s^2); Local tower side-to-side (translational) acceleration (relative to g) of tower gage 5; Directed along the local yt-axis +ElastoDyn['TwHt5ALgzt'] = False # (m/s^2); Local tower axial (translational) acceleration (relative to g) of tower gage 5; Directed along the local zt-axis +ElastoDyn['TwHt6ALgxt'] = False # (m/s^2); Local tower fore-aft (translational) acceleration (relative to g) of tower gage 6; Directed along the local xt-axis +ElastoDyn['TwHt6ALgyt'] = False # (m/s^2); Local tower side-to-side (translational) acceleration (relative to g) of tower gage 6; Directed along the local yt-axis +ElastoDyn['TwHt6ALgzt'] = False # (m/s^2); Local tower axial (translational) acceleration (relative to g) of tower gage 6; Directed along the local zt-axis +ElastoDyn['TwHt7ALgxt'] = False # (m/s^2); Local tower fore-aft (translational) acceleration (relative to g) of tower gage 7; Directed along the local xt-axis +ElastoDyn['TwHt7ALgyt'] = False # (m/s^2); Local tower side-to-side (translational) acceleration (relative to g) of tower gage 7; Directed along the local yt-axis +ElastoDyn['TwHt7ALgzt'] = False # (m/s^2); Local tower axial (translational) acceleration (relative to g) of tower gage 7; Directed along the local zt-axis +ElastoDyn['TwHt8ALgxt'] = False # (m/s^2); Local tower fore-aft (translational) acceleration (relative to g) of tower gage 8; Directed along the local xt-axis +ElastoDyn['TwHt8ALgyt'] = False # (m/s^2); Local tower side-to-side (translational) acceleration (relative to g) of tower gage 8; Directed along the local yt-axis +ElastoDyn['TwHt8ALgzt'] = False # (m/s^2); Local tower axial (translational) acceleration (relative to g) of tower gage 8; Directed along the local zt-axis +ElastoDyn['TwHt9ALgxt'] = False # (m/s^2); Local tower fore-aft (translational) acceleration (relative to g) of tower gage 9; Directed along the local xt-axis +ElastoDyn['TwHt9ALgyt'] = False # (m/s^2); Local tower side-to-side (translational) acceleration (relative to g) of tower gage 9; Directed along the local yt-axis +ElastoDyn['TwHt9ALgzt'] = False # (m/s^2); Local tower axial (translational) acceleration (relative to g) of tower gage 9; Directed along the local zt-axis +ElastoDyn['TwHt1TDxt'] = False # (m); Local tower fore-aft (translational) deflection (relative to the undeflected position) of tower gage 1; Directed along the local xt-axis +ElastoDyn['TwHt1TDyt'] = False # (m); Local tower side-to-side (translational) deflection (relative to the undeflected position) of tower gage 1; Directed along the local yt-axis +ElastoDyn['TwHt1TDzt'] = False # (m); Local tower axial (translational) deflection (relative to the undeflected position) of tower gage 1; Directed along the local zt-axis +ElastoDyn['TwHt2TDxt'] = False # (m); Local tower fore-aft (translational) deflection (relative to the undeflected position) of tower gage 2; Directed along the local xt-axis +ElastoDyn['TwHt2TDyt'] = False # (m); Local tower side-to-side (translational) deflection (relative to the undeflected position) of tower gage 2; Directed along the local yt-axis +ElastoDyn['TwHt2TDzt'] = False # (m); Local tower axial (translational) deflection (relative to the undeflected position) of tower gage 2; Directed along the local zt-axis +ElastoDyn['TwHt3TDxt'] = False # (m); Local tower fore-aft (translational) deflection (relative to the undeflected position) of tower gage 3; Directed along the local xt-axis +ElastoDyn['TwHt3TDyt'] = False # (m); Local tower side-to-side (translational) deflection (relative to the undeflected position) of tower gage 3; Directed along the local yt-axis +ElastoDyn['TwHt3TDzt'] = False # (m); Local tower axial (translational) deflection (relative to the undeflected position) of tower gage 3; Directed along the local zt-axis +ElastoDyn['TwHt4TDxt'] = False # (m); Local tower fore-aft (translational) deflection (relative to the undeflected position) of tower gage 4; Directed along the local xt-axis +ElastoDyn['TwHt4TDyt'] = False # (m); Local tower side-to-side (translational) deflection (relative to the undeflected position) of tower gage 4; Directed along the local yt-axis +ElastoDyn['TwHt4TDzt'] = False # (m); Local tower axial (translational) deflection (relative to the undeflected position) of tower gage 4; Directed along the local zt-axis +ElastoDyn['TwHt5TDxt'] = False # (m); Local tower fore-aft (translational) deflection (relative to the undeflected position) of tower gage 5; Directed along the local xt-axis +ElastoDyn['TwHt5TDyt'] = False # (m); Local tower side-to-side (translational) deflection (relative to the undeflected position) of tower gage 5; Directed along the local yt-axis +ElastoDyn['TwHt5TDzt'] = False # (m); Local tower axial (translational) deflection (relative to the undeflected position) of tower gage 5; Directed along the local zt-axis +ElastoDyn['TwHt6TDxt'] = False # (m); Local tower fore-aft (translational) deflection (relative to the undeflected position) of tower gage 6; Directed along the local xt-axis +ElastoDyn['TwHt6TDyt'] = False # (m); Local tower side-to-side (translational) deflection (relative to the undeflected position) of tower gage 6; Directed along the local yt-axis +ElastoDyn['TwHt6TDzt'] = False # (m); Local tower axial (translational) deflection (relative to the undeflected position) of tower gage 6; Directed along the local zt-axis +ElastoDyn['TwHt7TDxt'] = False # (m); Local tower fore-aft (translational) deflection (relative to the undeflected position) of tower gage 7; Directed along the local xt-axis +ElastoDyn['TwHt7TDyt'] = False # (m); Local tower side-to-side (translational) deflection (relative to the undeflected position) of tower gage 7; Directed along the local yt-axis +ElastoDyn['TwHt7TDzt'] = False # (m); Local tower axial (translational) deflection (relative to the undeflected position) of tower gage 7; Directed along the local zt-axis +ElastoDyn['TwHt8TDxt'] = False # (m); Local tower fore-aft (translational) deflection (relative to the undeflected position) of tower gage 8; Directed along the local xt-axis +ElastoDyn['TwHt8TDyt'] = False # (m); Local tower side-to-side (translational) deflection (relative to the undeflected position) of tower gage 8; Directed along the local yt-axis +ElastoDyn['TwHt8TDzt'] = False # (m); Local tower axial (translational) deflection (relative to the undeflected position) of tower gage 8; Directed along the local zt-axis +ElastoDyn['TwHt9TDxt'] = False # (m); Local tower fore-aft (translational) deflection (relative to the undeflected position) of tower gage 9; Directed along the local xt-axis +ElastoDyn['TwHt9TDyt'] = False # (m); Local tower side-to-side (translational) deflection (relative to the undeflected position) of tower gage 9; Directed along the local yt-axis +ElastoDyn['TwHt9TDzt'] = False # (m); Local tower axial (translational) deflection (relative to the undeflected position) of tower gage 9; Directed along the local zt-axis +ElastoDyn['TwHt1RDxt'] = False # (deg); Local tower angular (rotational) roll deflection (relative to the undeflected position) of tower gage 1. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower deflections, so that the rotation sequence does not matter.; About the local xt-axis +ElastoDyn['TwHt1RDyt'] = False # (deg); Local tower angular (rotational) pitch deflection (relative to the undeflected position) of tower gage 1. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower deflections, so that the rotation sequence does not matter.; About the local yt-axis +ElastoDyn['TwHt1RDzt'] = False # (deg); Local tower angular (rotational) torsion deflection (relative to the undeflected position) of tower gage 1. This output will always be zero for FAST simulation results. Use it for examining tower torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence.; About the local zt-axis +ElastoDyn['TwHt2RDxt'] = False # (deg); Local tower angular (rotational) roll deflection (relative to the undeflected position) of tower gage 2. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower deflections, so that the rotation sequence does not matter.; About the local xt-axis +ElastoDyn['TwHt2RDyt'] = False # (deg); Local tower angular (rotational) pitch deflection (relative to the undeflected position) of tower gage 2. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower deflections, so that the rotation sequence does not matter.; About the local yt-axis +ElastoDyn['TwHt2RDzt'] = False # (deg); Local tower angular (rotational) torsion deflection (relative to the undeflected position) of tower gage 2. This output will always be zero for FAST simulation results. Use it for examining tower torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence.; About the local zt-axis +ElastoDyn['TwHt3RDxt'] = False # (deg); Local tower angular (rotational) roll deflection (relative to the undeflected position) of tower gage 3. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower deflections, so that the rotation sequence does not matter.; About the local xt-axis +ElastoDyn['TwHt3RDyt'] = False # (deg); Local tower angular (rotational) pitch deflection (relative to the undeflected position) of tower gage 3. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower deflections, so that the rotation sequence does not matter.; About the local yt-axis +ElastoDyn['TwHt3RDzt'] = False # (deg); Local tower angular (rotational) torsion deflection (relative to the undeflected position) of tower gage 3. This output will always be zero for FAST simulation results. Use it for examining tower torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence.; About the local zt-axis +ElastoDyn['TwHt4RDxt'] = False # (deg); Local tower angular (rotational) roll deflection (relative to the undeflected position) of tower gage 4. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower deflections, so that the rotation sequence does not matter.; About the local xt-axis +ElastoDyn['TwHt4RDyt'] = False # (deg); Local tower angular (rotational) pitch deflection (relative to the undeflected position) of tower gage 4. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower deflections, so that the rotation sequence does not matter.; About the local yt-axis +ElastoDyn['TwHt4RDzt'] = False # (deg); Local tower angular (rotational) torsion deflection (relative to the undeflected position) of tower gage 4. This output will always be zero for FAST simulation results. Use it for examining tower torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence.; About the local zt-axis +ElastoDyn['TwHt5RDxt'] = False # (deg); Local tower angular (rotational) roll deflection (relative to the undeflected position) of tower gage 5. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower deflections, so that the rotation sequence does not matter.; About the local xt-axis +ElastoDyn['TwHt5RDyt'] = False # (deg); Local tower angular (rotational) pitch deflection (relative to the undeflected position) of tower gage 5. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower deflections, so that the rotation sequence does not matter.; About the local yt-axis +ElastoDyn['TwHt5RDzt'] = False # (deg); Local tower angular (rotational) torsion deflection (relative to the undeflected position) of tower gage 5. This output will always be zero for FAST simulation results. Use it for examining tower torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence.; About the local zt-axis +ElastoDyn['TwHt6RDxt'] = False # (deg); Local tower angular (rotational) roll deflection (relative to the undeflected position) of tower gage 6. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower deflections, so that the rotation sequence does not matter.; About the local xt-axis +ElastoDyn['TwHt6RDyt'] = False # (deg); Local tower angular (rotational) pitch deflection (relative to the undeflected position) of tower gage 6. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower deflections, so that the rotation sequence does not matter.; About the local yt-axis +ElastoDyn['TwHt6RDzt'] = False # (deg); Local tower angular (rotational) torsion deflection (relative to the undeflected position) of tower gage 6. This output will always be zero for FAST simulation results. Use it for examining tower torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence.; About the local zt-axis +ElastoDyn['TwHt7RDxt'] = False # (deg); Local tower angular (rotational) roll deflection (relative to the undeflected position) of tower gage 7. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower deflections, so that the rotation sequence does not matter.; About the local xt-axis +ElastoDyn['TwHt7RDyt'] = False # (deg); Local tower angular (rotational) pitch deflection (relative to the undeflected position) of tower gage 7. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower deflections, so that the rotation sequence does not matter.; About the local yt-axis +ElastoDyn['TwHt7RDzt'] = False # (deg); Local tower angular (rotational) torsion deflection (relative to the undeflected position) of tower gage 7. This output will always be zero for FAST simulation results. Use it for examining tower torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence.; About the local zt-axis +ElastoDyn['TwHt8RDxt'] = False # (deg); Local tower angular (rotational) roll deflection (relative to the undeflected position) of tower gage 8. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower deflections, so that the rotation sequence does not matter.; About the local xt-axis +ElastoDyn['TwHt8RDyt'] = False # (deg); Local tower angular (rotational) pitch deflection (relative to the undeflected position) of tower gage 8. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower deflections, so that the rotation sequence does not matter.; About the local yt-axis +ElastoDyn['TwHt8RDzt'] = False # (deg); Local tower angular (rotational) torsion deflection (relative to the undeflected position) of tower gage 8. This output will always be zero for FAST simulation results. Use it for examining tower torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence.; About the local zt-axis +ElastoDyn['TwHt9RDxt'] = False # (deg); Local tower angular (rotational) roll deflection (relative to the undeflected position) of tower gage 9. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower deflections, so that the rotation sequence does not matter.; About the local xt-axis +ElastoDyn['TwHt9RDyt'] = False # (deg); Local tower angular (rotational) pitch deflection (relative to the undeflected position) of tower gage 9. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower deflections, so that the rotation sequence does not matter.; About the local yt-axis +ElastoDyn['TwHt9RDzt'] = False # (deg); Local tower angular (rotational) torsion deflection (relative to the undeflected position) of tower gage 9. This output will always be zero for FAST simulation results. Use it for examining tower torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence.; About the local zt-axis +ElastoDyn['TwHt1TPxi'] = False # (m); xi-component of the translational position (relative to the inertia frame) of tower gage 1; Directed along the local xi-axis +ElastoDyn['TwHt1TPyi'] = False # (m); yi-component of the translational position (relative to the inertia frame) of tower gage 1; Directed along the local yi-axis +ElastoDyn['TwHt1TPzi'] = False # (m); zi-component of the translational position (relative to ground level [onshore] or MSL [offshore]) of tower gage 1; Directed along the local zi-axis +ElastoDyn['TwHt2TPxi'] = False # (m); xi-component of the translational position (relative to the inertia frame) of tower gage 2; Directed along the local xi-axis +ElastoDyn['TwHt2TPyi'] = False # (m); yi-component of the translational position (relative to the inertia frame) of tower gage 2; Directed along the local yi-axis +ElastoDyn['TwHt2TPzi'] = False # (m); zi-component of the translational position (relative to ground level [onshore] or MSL [offshore]) of tower gage 2; Directed along the local zi-axis +ElastoDyn['TwHt3TPxi'] = False # (m); xi-component of the translational position (relative to the inertia frame) of tower gage 3; Directed along the local xi-axis +ElastoDyn['TwHt3TPyi'] = False # (m); yi-component of the translational position (relative to the inertia frame) of tower gage 3; Directed along the local yi-axis +ElastoDyn['TwHt3TPzi'] = False # (m); zi-component of the translational position (relative to ground level [onshore] or MSL [offshore]) of tower gage 3; Directed along the local zi-axis +ElastoDyn['TwHt4TPxi'] = False # (m); xi-component of the translational position (relative to the inertia frame) of tower gage 4; Directed along the local xi-axis +ElastoDyn['TwHt4TPyi'] = False # (m); yi-component of the translational position (relative to the inertia frame) of tower gage 4; Directed along the local yi-axis +ElastoDyn['TwHt4TPzi'] = False # (m); zi-component of the translational position (relative to ground level [onshore] or MSL [offshore]) of tower gage 4; Directed along the local zi-axis +ElastoDyn['TwHt5TPxi'] = False # (m); xi-component of the translational position (relative to the inertia frame) of tower gage 5; Directed along the local xi-axis +ElastoDyn['TwHt5TPyi'] = False # (m); yi-component of the translational position (relative to the inertia frame) of tower gage 5; Directed along the local yi-axis +ElastoDyn['TwHt5TPzi'] = False # (m); zi-component of the translational position (relative to ground level [onshore] or MSL [offshore]) of tower gage 5; Directed along the local zi-axis +ElastoDyn['TwHt6TPxi'] = False # (m); xi-component of the translational position (relative to the inertia frame) of tower gage 6; Directed along the local xi-axis +ElastoDyn['TwHt6TPyi'] = False # (m); yi-component of the translational position (relative to the inertia frame) of tower gage 6; Directed along the local yi-axis +ElastoDyn['TwHt6TPzi'] = False # (m); zi-component of the translational position (relative to ground level [onshore] or MSL [offshore]) of tower gage 6; Directed along the local zi-axis +ElastoDyn['TwHt7TPxi'] = False # (m); xi-component of the translational position (relative to the inertia frame) of tower gage 7; Directed along the local xi-axis +ElastoDyn['TwHt7TPyi'] = False # (m); yi-component of the translational position (relative to the inertia frame) of tower gage 7; Directed along the local yi-axis +ElastoDyn['TwHt7TPzi'] = False # (m); zi-component of the translational position (relative to ground level [onshore] or MSL [offshore]) of tower gage 7; Directed along the local zi-axis +ElastoDyn['TwHt8TPxi'] = False # (m); xi-component of the translational position (relative to the inertia frame) of tower gage 8; Directed along the local xi-axis +ElastoDyn['TwHt8TPyi'] = False # (m); yi-component of the translational position (relative to the inertia frame) of tower gage 8; Directed along the local yi-axis +ElastoDyn['TwHt8TPzi'] = False # (m); zi-component of the translational position (relative to ground level [onshore] or MSL [offshore]) of tower gage 8; Directed along the local zi-axis +ElastoDyn['TwHt9TPxi'] = False # (m); xi-component of the translational position (relative to the inertia frame) of tower gage 9; Directed along the local xi-axis +ElastoDyn['TwHt9TPyi'] = False # (m); yi-component of the translational position (relative to the inertia frame) of tower gage 9; Directed along the local yi-axis +ElastoDyn['TwHt9TPzi'] = False # (m); zi-component of the translational position (relative to ground level [onshore] or MSL [offshore]) of tower gage 9; Directed along the local zi-axis +ElastoDyn['TwHt1RPxi'] = False # (deg); xi-component of the rotational position (relative to the inertia frame) of tower gage 1. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower and platform rotational deflections, so that the rotation sequence does not matter.; About the local xi-axis +ElastoDyn['TwHt1RPyi'] = False # (deg); yi-component of the rotational position (relative to the inertia frame) of tower gage 1. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower and platform rotational deflections, so that the rotation sequence does not matter.; About the local yi-axis +ElastoDyn['TwHt1RPzi'] = False # (deg); zi-component of the rotational position (relative to the inertia frame) of tower gage 1. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower and platform rotational deflections, so that the rotation sequence does not matter.; About the local zi-axis +ElastoDyn['TwHt2RPxi'] = False # (deg); xi-component of the rotational position (relative to the inertia frame) of tower gage 2. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower and platform rotational deflections, so that the rotation sequence does not matter.; About the local xi-axis +ElastoDyn['TwHt2RPyi'] = False # (deg); yi-component of the rotational position (relative to the inertia frame) of tower gage 2. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower and platform rotational deflections, so that the rotation sequence does not matter.; About the local yi-axis +ElastoDyn['TwHt2RPzi'] = False # (deg); zi-component of the rotational position (relative to the inertia frame) of tower gage 2. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower and platform rotational deflections, so that the rotation sequence does not matter.; About the local zi-axis +ElastoDyn['TwHt3RPxi'] = False # (deg); xi-component of the rotational position (relative to the inertia frame) of tower gage 3. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower and platform rotational deflections, so that the rotation sequence does not matter.; About the local xi-axis +ElastoDyn['TwHt3RPyi'] = False # (deg); yi-component of the rotational position (relative to the inertia frame) of tower gage 3. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower and platform rotational deflections, so that the rotation sequence does not matter.; About the local yi-axis +ElastoDyn['TwHt3RPzi'] = False # (deg); zi-component of the rotational position (relative to the inertia frame) of tower gage 3. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower and platform rotational deflections, so that the rotation sequence does not matter.; About the local zi-axis +ElastoDyn['TwHt4RPxi'] = False # (deg); xi-component of the rotational position (relative to the inertia frame) of tower gage 4. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower and platform rotational deflections, so that the rotation sequence does not matter.; About the local xi-axis +ElastoDyn['TwHt4RPyi'] = False # (deg); yi-component of the rotational position (relative to the inertia frame) of tower gage 4. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower and platform rotational deflections, so that the rotation sequence does not matter.; About the local yi-axis +ElastoDyn['TwHt4RPzi'] = False # (deg); zi-component of the rotational position (relative to the inertia frame) of tower gage 4. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower and platform rotational deflections, so that the rotation sequence does not matter.; About the local zi-axis +ElastoDyn['TwHt5RPxi'] = False # (deg); xi-component of the rotational position (relative to the inertia frame) of tower gage 5. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower and platform rotational deflections, so that the rotation sequence does not matter.; About the local xi-axis +ElastoDyn['TwHt5RPyi'] = False # (deg); yi-component of the rotational position (relative to the inertia frame) of tower gage 5. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower and platform rotational deflections, so that the rotation sequence does not matter.; About the local yi-axis +ElastoDyn['TwHt5RPzi'] = False # (deg); zi-component of the rotational position (relative to the inertia frame) of tower gage 5. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower and platform rotational deflections, so that the rotation sequence does not matter.; About the local zi-axis +ElastoDyn['TwHt6RPxi'] = False # (deg); xi-component of the rotational position (relative to the inertia frame) of tower gage 6. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower and platform rotational deflections, so that the rotation sequence does not matter.; About the local xi-axis +ElastoDyn['TwHt6RPyi'] = False # (deg); yi-component of the rotational position (relative to the inertia frame) of tower gage 6. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower and platform rotational deflections, so that the rotation sequence does not matter.; About the local yi-axis +ElastoDyn['TwHt6RPzi'] = False # (deg); zi-component of the rotational position (relative to the inertia frame) of tower gage 6. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower and platform rotational deflections, so that the rotation sequence does not matter.; About the local zi-axis +ElastoDyn['TwHt7RPxi'] = False # (deg); xi-component of the rotational position (relative to the inertia frame) of tower gage 7. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower and platform rotational deflections, so that the rotation sequence does not matter.; About the local xi-axis +ElastoDyn['TwHt7RPyi'] = False # (deg); yi-component of the rotational position (relative to the inertia frame) of tower gage 7. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower and platform rotational deflections, so that the rotation sequence does not matter.; About the local yi-axis +ElastoDyn['TwHt7RPzi'] = False # (deg); zi-component of the rotational position (relative to the inertia frame) of tower gage 7. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower and platform rotational deflections, so that the rotation sequence does not matter.; About the local zi-axis +ElastoDyn['TwHt8RPxi'] = False # (deg); xi-component of the rotational position (relative to the inertia frame) of tower gage 8. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower and platform rotational deflections, so that the rotation sequence does not matter.; About the local xi-axis +ElastoDyn['TwHt8RPyi'] = False # (deg); yi-component of the rotational position (relative to the inertia frame) of tower gage 8. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower and platform rotational deflections, so that the rotation sequence does not matter.; About the local yi-axis +ElastoDyn['TwHt8RPzi'] = False # (deg); zi-component of the rotational position (relative to the inertia frame) of tower gage 8. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower and platform rotational deflections, so that the rotation sequence does not matter.; About the local zi-axis +ElastoDyn['TwHt9RPxi'] = False # (deg); xi-component of the rotational position (relative to the inertia frame) of tower gage 9. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower and platform rotational deflections, so that the rotation sequence does not matter.; About the local xi-axis +ElastoDyn['TwHt9RPyi'] = False # (deg); yi-component of the rotational position (relative to the inertia frame) of tower gage 9. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower and platform rotational deflections, so that the rotation sequence does not matter.; About the local yi-axis +ElastoDyn['TwHt9RPzi'] = False # (deg); zi-component of the rotational position (relative to the inertia frame) of tower gage 9. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower and platform rotational deflections, so that the rotation sequence does not matter.; About the local zi-axis + +# Platform Motions +ElastoDyn['PtfmTDxt'] = False # (m); Platform horizontal surge (translational) displacement; Directed along the xt-axis +ElastoDyn['PtfmTDyt'] = False # (m); Platform horizontal sway (translational) displacement; Directed along the yt-axis +ElastoDyn['PtfmTDzt'] = False # (m); Platform vertical heave (translational) displacement; Directed along the zt-axis +ElastoDyn['PtfmTDxi'] = False # (m); Platform horizontal surge (translational) displacement; Directed along the xi-axis +ElastoDyn['PtfmSurge'] = False # (m); Platform horizontal surge (translational) displacement; Directed along the xi-axis +ElastoDyn['PtfmTDyi'] = False # (m); Platform horizontal sway (translational) displacement; Directed along the yi-axis +ElastoDyn['PtfmSway'] = False # (m); Platform horizontal sway (translational) displacement; Directed along the yi-axis +ElastoDyn['PtfmTDzi'] = False # (m); Platform vertical heave (translational) displacement; Directed along the zi-axis +ElastoDyn['PtfmHeave'] = False # (m); Platform vertical heave (translational) displacement; Directed along the zi-axis +ElastoDyn['PtfmTVxt'] = False # (m/s); Platform horizontal surge (translational) velocity; Directed along the xt-axis +ElastoDyn['PtfmTVyt'] = False # (m/s); Platform horizontal sway (translational) velocity; Directed along the yt-axis +ElastoDyn['PtfmTVzt'] = False # (m/s); Platform vertical heave (translational) velocity; Directed along the zt-axis +ElastoDyn['PtfmTVxi'] = False # (m/s); Platform horizontal surge (translational) velocity; Directed along the xi-axis +ElastoDyn['PtfmTVyi'] = False # (m/s); Platform horizontal sway (translational) velocity; Directed along the yi-axis +ElastoDyn['PtfmTVzi'] = False # (m/s); Platform vertical heave (translational) velocity; Directed along the zi-axis +ElastoDyn['PtfmTAxt'] = False # (m/s^2); Platform horizontal surge (translational) acceleration; Directed along the xt-axis +ElastoDyn['PtfmTAyt'] = False # (m/s^2); Platform horizontal sway (translational) acceleration; Directed along the yt-axis +ElastoDyn['PtfmTAzt'] = False # (m/s^2); Platform vertical heave (translational) acceleration; Directed along the zt-axis +ElastoDyn['PtfmTAgxt'] = False # (m/s^2); Platform horizontal surge (translational) acceleration relative to g; Directed along the xt-axis +ElastoDyn['PtfmTAgyt'] = False # (m/s^2); Platform horizontal sway (translational) acceleration relative to g; Directed along the yt-axis +ElastoDyn['PtfmTAgzt'] = False # (m/s^2); Platform vertical heave (translational) acceleration relative to g; Directed along the zt-axis +ElastoDyn['PtfmTAxi'] = False # (m/s^2); Platform horizontal surge (translational) acceleration; Directed along the xi-axis +ElastoDyn['PtfmTAyi'] = False # (m/s^2); Platform horizontal sway (translational) acceleration; Directed along the yi-axis +ElastoDyn['PtfmTAzi'] = False # (m/s^2); Platform vertical heave (translational) acceleration; Directed along the zi-axis +ElastoDyn['PtfmTAgxi'] = False # (m/s^2); Platform horizontal surge (translational) acceleration relative to g; Directed along the xi-axis +ElastoDyn['PtfmTAgyi'] = False # (m/s^2); Platform horizontal sway (translational) acceleration relative to g; Directed along the yi-axis +ElastoDyn['PtfmTAgzi'] = False # (m/s^2); Platform vertical heave (translational) acceleration relative to g; Directed along the zi-axis +ElastoDyn['PtfmRDxi'] = False # (deg); Platform roll tilt angular (rotational) displacement. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small rotational platform displacements, so that the rotation sequence does not matter.; About the xi-axis +ElastoDyn['PtfmRoll'] = False # (deg); Platform roll tilt angular (rotational) displacement. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small rotational platform displacements, so that the rotation sequence does not matter.; About the xi-axis +ElastoDyn['PtfmRDyi'] = False # (deg); Platform pitch tilt angular (rotational) displacement. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small rotational platform displacements, so that the rotation sequence does not matter.; About the yi-axis +ElastoDyn['PtfmPitch'] = False # (deg); Platform pitch tilt angular (rotational) displacement. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small rotational platform displacements, so that the rotation sequence does not matter.; About the yi-axis +ElastoDyn['PtfmRDzi'] = False # (deg); Platform yaw angular (rotational) displacement. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small rotational platform displacements, so that the rotation sequence does not matter.; About the zi-axis +ElastoDyn['PtfmYaw'] = False # (deg); Platform yaw angular (rotational) displacement. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small rotational platform displacements, so that the rotation sequence does not matter.; About the zi-axis +ElastoDyn['PtfmRVxt'] = False # (deg/s); Platform roll tilt angular (rotational) velocity; About the xt-axis +ElastoDyn['PtfmRVyt'] = False # (deg/s); Platform pitch tilt angular (rotational) velocity; About the yt-axis +ElastoDyn['PtfmRVzt'] = False # (deg/s); Platform yaw angular (rotational) velocity; About the zt-axis +ElastoDyn['PtfmRVxi'] = False # (deg/s); Platform roll tilt angular (rotational) velocity; About the xi-axis +ElastoDyn['PtfmRVyi'] = False # (deg/s); Platform pitch tilt angular (rotational) velocity; About the yi-axis +ElastoDyn['PtfmRVzi'] = False # (deg/s); Platform yaw angular (rotational) velocity; About the zi-axis +ElastoDyn['PtfmRAxt'] = False # (deg/s^2); Platform roll tilt angular (rotational) acceleration; About the xt-axis +ElastoDyn['PtfmRAyt'] = False # (deg/s^2); Platform pitch tilt angular (rotational) acceleration; About the yt-axis +ElastoDyn['PtfmRAzt'] = False # (deg/s^2); Platform yaw angular (rotational) acceleration; About the zt-axis +ElastoDyn['PtfmRAxi'] = False # (deg/s^2); Platform roll tilt angular (rotational) acceleration; About the xi-axis +ElastoDyn['PtfmRAyi'] = False # (deg/s^2); Platform pitch tilt angular (rotational) acceleration; About the yi-axis +ElastoDyn['PtfmRAzi'] = False # (deg/s^2); Platform yaw angular (rotational) acceleration; About the zi-axis + +# Blade 1 Root Loads +ElastoDyn['RootFxc1'] = False # (kN); Blade 1 out-of-plane shear force at the blade root; Directed along the xc1-axis +ElastoDyn['RootFyc1'] = False # (kN); Blade 1 in-plane shear force at the blade root; Directed along the yc1-axis +ElastoDyn['RootFzc1'] = False # (kN); Blade 1 axial force at the blade root; Directed along the zc1- and zb1-axes +ElastoDyn['RootFzb1'] = False # (kN); Blade 1 axial force at the blade root; Directed along the zc1- and zb1-axes +ElastoDyn['RootFxb1'] = False # (kN); Blade 1 flapwise shear force at the blade root; Directed along the xb1-axis +ElastoDyn['RootFyb1'] = False # (kN); Blade 1 edgewise shear force at the blade root; Directed along the yb1-axis +ElastoDyn['RootMxc1'] = False # (kN-m); Blade 1 in-plane moment (i.e., the moment caused by in-plane forces) at the blade root; About the xc1-axis +ElastoDyn['RootMIP1'] = False # (kN-m); Blade 1 in-plane moment (i.e., the moment caused by in-plane forces) at the blade root; About the xc1-axis +ElastoDyn['RootMyc1'] = False # (kN-m); Blade 1 out-of-plane moment (i.e., the moment caused by out-of-plane forces) at the blade root; About the yc1-axis +ElastoDyn['RootMOoP1'] = False # (kN-m); Blade 1 out-of-plane moment (i.e., the moment caused by out-of-plane forces) at the blade root; About the yc1-axis +ElastoDyn['RootMzc1'] = False # (kN-m); Blade 1 pitching moment at the blade root; About the zc1- and zb1-axes +ElastoDyn['RootMzb1'] = False # (kN-m); Blade 1 pitching moment at the blade root; About the zc1- and zb1-axes +ElastoDyn['RootMxb1'] = False # (kN-m); Blade 1 edgewise moment (i.e., the moment caused by edgewise forces) at the blade root; About the xb1-axis +ElastoDyn['RootMEdg1'] = False # (kN-m); Blade 1 edgewise moment (i.e., the moment caused by edgewise forces) at the blade root; About the xb1-axis +ElastoDyn['RootMyb1'] = True # (kN-m); Blade 1 flapwise moment (i.e., the moment caused by flapwise forces) at the blade root; About the yb1-axis +ElastoDyn['RootMFlp1'] = False # (kN-m); Blade 1 flapwise moment (i.e., the moment caused by flapwise forces) at the blade root; About the yb1-axis + +# Blade 2 Root Loads +ElastoDyn['RootFxc2'] = False # (kN); Blade 2 out-of-plane shear force at the blade root; Directed along the xc2-axis +ElastoDyn['RootFyc2'] = False # (kN); Blade 2 in-plane shear force at the blade root; Directed along the yc2-axis +ElastoDyn['RootFzc2'] = False # (kN); Blade 2 axial force at the blade root; Directed along the zc2- and zb2-axes +ElastoDyn['RootFzb2'] = False # (kN); Blade 2 axial force at the blade root; Directed along the zc2- and zb2-axes +ElastoDyn['RootFxb2'] = False # (kN); Blade 2 flapwise shear force at the blade root; Directed along the xb2-axis +ElastoDyn['RootFyb2'] = False # (kN); Blade 2 edgewise shear force at the blade root; Directed along the yb2-axis +ElastoDyn['RootMxc2'] = False # (kN-m); Blade 2 in-plane moment (i.e., the moment caused by in-plane forces) at the blade root; About the xc2-axis +ElastoDyn['RootMIP2'] = False # (kN-m); Blade 2 in-plane moment (i.e., the moment caused by in-plane forces) at the blade root; About the xc2-axis +ElastoDyn['RootMyc2'] = False # (kN-m); Blade 2 out-of-plane moment (i.e., the moment caused by out-of-plane forces) at the blade root; About the yc2-axis +ElastoDyn['RootMOoP2'] = False # (kN-m); Blade 2 out-of-plane moment (i.e., the moment caused by out-of-plane forces) at the blade root; About the yc2-axis +ElastoDyn['RootMzc2'] = False # (kN-m); Blade 2 pitching moment at the blade root; About the zc2- and zb2-axes +ElastoDyn['RootMzb2'] = False # (kN-m); Blade 2 pitching moment at the blade root; About the zc2- and zb2-axes +ElastoDyn['RootMxb2'] = False # (kN-m); Blade 2 edgewise moment (i.e., the moment caused by edgewise forces) at the blade root; About the xb2-axis +ElastoDyn['RootMEdg2'] = False # (kN-m); Blade 2 edgewise moment (i.e., the moment caused by edgewise forces) at the blade root; About the xb2-axis +ElastoDyn['RootMyb2'] = True # (kN-m); Blade 2 flapwise moment (i.e., the moment caused by flapwise forces) at the blade root; About the yb2-axis +ElastoDyn['RootMFlp2'] = False # (kN-m); Blade 2 flapwise moment (i.e., the moment caused by flapwise forces) at the blade root; About the yb2-axis + +# Blade 3 Root Loads +ElastoDyn['RootFxc3'] = False # (kN); Blade 3 out-of-plane shear force at the blade root; Directed along the xc3-axis +ElastoDyn['RootFyc3'] = False # (kN); Blade 3 in-plane shear force at the blade root; Directed along the yc3-axis +ElastoDyn['RootFzc3'] = False # (kN); Blade 3 axial force at the blade root; Directed along the zc3- and zb3-axes +ElastoDyn['RootFzb3'] = False # (kN); Blade 3 axial force at the blade root; Directed along the zc3- and zb3-axes +ElastoDyn['RootFxb3'] = False # (kN); Blade 3 flapwise shear force at the blade root; Directed along the xb3-axis +ElastoDyn['RootFyb3'] = False # (kN); Blade 3 edgewise shear force at the blade root; Directed along the yb3-axis +ElastoDyn['RootMxc3'] = False # (kN-m); Blade 3 in-plane moment (i.e., the moment caused by in-plane forces) at the blade root; About the xc3-axis +ElastoDyn['RootMIP3'] = False # (kN-m); Blade 3 in-plane moment (i.e., the moment caused by in-plane forces) at the blade root; About the xc3-axis +ElastoDyn['RootMyc3'] = False # (kN-m); Blade 3 out-of-plane moment (i.e., the moment caused by out-of-plane forces) at the blade root; About the yc3-axis +ElastoDyn['RootMOoP3'] = False # (kN-m); Blade 3 out-of-plane moment (i.e., the moment caused by out-of-plane forces) at the blade root; About the yc3-axis +ElastoDyn['RootMzc3'] = False # (kN-m); Blade 3 pitching moment at the blade root; About the zc3- and zb3-axes +ElastoDyn['RootMzb3'] = False # (kN-m); Blade 3 pitching moment at the blade root; About the zc3- and zb3-axes +ElastoDyn['RootMxb3'] = False # (kN-m); Blade 3 edgewise moment (i.e., the moment caused by edgewise forces) at the blade root; About the xb3-axis +ElastoDyn['RootMEdg3'] = False # (kN-m); Blade 3 edgewise moment (i.e., the moment caused by edgewise forces) at the blade root; About the xb3-axis +ElastoDyn['RootMyb3'] = True # (kN-m); Blade 3 flapwise moment (i.e., the moment caused by flapwise forces) at the blade root; About the yb3-axis +ElastoDyn['RootMFlp3'] = False # (kN-m); Blade 3 flapwise moment (i.e., the moment caused by flapwise forces) at the blade root; About the yb3-axis + +# Blade 1 Local Span Loads +ElastoDyn['Spn1MLxb1'] = False # (kN-m); Blade 1 local edgewise moment at span station 1; About the local xb1-axis +ElastoDyn['Spn1MLyb1'] = False # (kN-m); Blade 1 local flapwise moment at span station 1; About the local yb1-axis +ElastoDyn['Spn1MLzb1'] = False # (kN-m); Blade 1 local pitching moment at span station 1; About the local zb1-axis +ElastoDyn['Spn2MLxb1'] = False # (kN-m); Blade 1 local edgewise moment at span station 2; About the local xb1-axis +ElastoDyn['Spn2MLyb1'] = False # (kN-m); Blade 1 local flapwise moment at span station 2; About the local yb1-axis +ElastoDyn['Spn2MLzb1'] = False # (kN-m); Blade 1 local pitching moment at span station 2; About the local zb1-axis +ElastoDyn['Spn3MLxb1'] = False # (kN-m); Blade 1 local edgewise moment at span station 3; About the local xb1-axis +ElastoDyn['Spn3MLyb1'] = False # (kN-m); Blade 1 local flapwise moment at span station 3; About the local yb1-axis +ElastoDyn['Spn3MLzb1'] = False # (kN-m); Blade 1 local pitching moment at span station 3; About the local zb1-axis +ElastoDyn['Spn4MLxb1'] = False # (kN-m); Blade 1 local edgewise moment at span station 4; About the local xb1-axis +ElastoDyn['Spn4MLyb1'] = False # (kN-m); Blade 1 local flapwise moment at span station 4; About the local yb1-axis +ElastoDyn['Spn4MLzb1'] = False # (kN-m); Blade 1 local pitching moment at span station 4; About the local zb1-axis +ElastoDyn['Spn5MLxb1'] = False # (kN-m); Blade 1 local edgewise moment at span station 5; About the local xb1-axis +ElastoDyn['Spn5MLyb1'] = False # (kN-m); Blade 1 local flapwise moment at span station 5; About the local yb1-axis +ElastoDyn['Spn5MLzb1'] = False # (kN-m); Blade 1 local pitching moment at span station 5; About the local zb1-axis +ElastoDyn['Spn6MLxb1'] = False # (kN-m); Blade 1 local edgewise moment at span station 6; About the local xb1-axis +ElastoDyn['Spn6MLyb1'] = False # (kN-m); Blade 1 local flapwise moment at span station 6; About the local yb1-axis +ElastoDyn['Spn6MLzb1'] = False # (kN-m); Blade 1 local pitching moment at span station 6; About the local zb1-axis +ElastoDyn['Spn7MLxb1'] = False # (kN-m); Blade 1 local edgewise moment at span station 7; About the local xb1-axis +ElastoDyn['Spn7MLyb1'] = False # (kN-m); Blade 1 local flapwise moment at span station 7; About the local yb1-axis +ElastoDyn['Spn7MLzb1'] = False # (kN-m); Blade 1 local pitching moment at span station 7; About the local zb1-axis +ElastoDyn['Spn8MLxb1'] = False # (kN-m); Blade 1 local edgewise moment at span station 8; About the local xb1-axis +ElastoDyn['Spn8MLyb1'] = False # (kN-m); Blade 1 local flapwise moment at span station 8; About the local yb1-axis +ElastoDyn['Spn8MLzb1'] = False # (kN-m); Blade 1 local pitching moment at span station 8; About the local zb1-axis +ElastoDyn['Spn9MLxb1'] = False # (kN-m); Blade 1 local edgewise moment at span station 9; About the local xb1-axis +ElastoDyn['Spn9MLyb1'] = False # (kN-m); Blade 1 local flapwise moment at span station 9; About the local yb1-axis +ElastoDyn['Spn9MLzb1'] = False # (kN-m); Blade 1 local pitching moment at span station 9; About the local zb1-axis +ElastoDyn['Spn1FLxb1'] = False # (kN); Blade 1 local flapwise shear force at span station 1; Directed along the local xb1-axis +ElastoDyn['Spn1FLyb1'] = False # (kN); Blade 1 local edgewise shear force at span station 1; Directed along the local yb1-axis +ElastoDyn['Spn1FLzb1'] = False # (kN); Blade 1 local axial force at span station 1; Directed along the local zb1-axis +ElastoDyn['Spn2FLxb1'] = False # (kN); Blade 1 local flapwise shear force at span station 2; Directed along the local xb1-axis +ElastoDyn['Spn2FLyb1'] = False # (kN); Blade 1 local edgewise shear force at span station 2; Directed along the local yb1-axis +ElastoDyn['Spn2FLzb1'] = False # (kN); Blade 1 local axial force at span station 2; Directed along the local zb1-axis +ElastoDyn['Spn3FLxb1'] = False # (kN); Blade 1 local flapwise shear force at span station 3; Directed along the local xb1-axis +ElastoDyn['Spn3FLyb1'] = False # (kN); Blade 1 local edgewise shear force at span station 3; Directed along the local yb1-axis +ElastoDyn['Spn3FLzb1'] = False # (kN); Blade 1 local axial force at span station 3; Directed along the local zb1-axis +ElastoDyn['Spn4FLxb1'] = False # (kN); Blade 1 local flapwise shear force at span station 4; Directed along the local xb1-axis +ElastoDyn['Spn4FLyb1'] = False # (kN); Blade 1 local edgewise shear force at span station 4; Directed along the local yb1-axis +ElastoDyn['Spn4FLzb1'] = False # (kN); Blade 1 local axial force at span station 4; Directed along the local zb1-axis +ElastoDyn['Spn5FLxb1'] = False # (kN); Blade 1 local flapwise shear force at span station 5; Directed along the local xb1-axis +ElastoDyn['Spn5FLyb1'] = False # (kN); Blade 1 local edgewise shear force at span station 5; Directed along the local yb1-axis +ElastoDyn['Spn5FLzb1'] = False # (kN); Blade 1 local axial force at span station 5; Directed along the local zb1-axis +ElastoDyn['Spn6FLxb1'] = False # (kN); Blade 1 local flapwise shear force at span station 6; Directed along the local xb1-axis +ElastoDyn['Spn6FLyb1'] = False # (kN); Blade 1 local edgewise shear force at span station 6; Directed along the local yb1-axis +ElastoDyn['Spn6FLzb1'] = False # (kN); Blade 1 local axial force at span station 6; Directed along the local zb1-axis +ElastoDyn['Spn7FLxb1'] = False # (kN); Blade 1 local flapwise shear force at span station 7; Directed along the local xb1-axis +ElastoDyn['Spn7FLyb1'] = False # (kN); Blade 1 local edgewise shear force at span station 7; Directed along the local yb1-axis +ElastoDyn['Spn7FLzb1'] = False # (kN); Blade 1 local axial force at span station 7; Directed along the local zb1-axis +ElastoDyn['Spn8FLxb1'] = False # (kN); Blade 1 local flapwise shear force at span station 8; Directed along the local xb1-axis +ElastoDyn['Spn8FLyb1'] = False # (kN); Blade 1 local edgewise shear force at span station 8; Directed along the local yb1-axis +ElastoDyn['Spn8FLzb1'] = False # (kN); Blade 1 local axial force at span station 8; Directed along the local zb1-axis +ElastoDyn['Spn9FLxb1'] = False # (kN); Blade 1 local flapwise shear force at span station 9; Directed along the local xb1-axis +ElastoDyn['Spn9FLyb1'] = False # (kN); Blade 1 local edgewise shear force at span station 9; Directed along the local yb1-axis +ElastoDyn['Spn9FLzb1'] = False # (kN); Blade 1 local axial force at span station 9; Directed along the local zb1-axis + +# Blade 2 Local Span Loads +ElastoDyn['Spn1MLxb2'] = False # (kN-m); Blade 2 local edgewise moment at span station 1; About the local xb2-axis +ElastoDyn['Spn1MLyb2'] = False # (kN-m); Blade 2 local flapwise moment at span station 1; About the local yb2-axis +ElastoDyn['Spn1MLzb2'] = False # (kN-m); Blade 2 local pitching moment at span station 1; About the local zb2-axis +ElastoDyn['Spn2MLxb2'] = False # (kN-m); Blade 2 local edgewise moment at span station 2; About the local xb2-axis +ElastoDyn['Spn2MLyb2'] = False # (kN-m); Blade 2 local flapwise moment at span station 2; About the local yb2-axis +ElastoDyn['Spn2MLzb2'] = False # (kN-m); Blade 2 local pitching moment at span station 2; About the local zb2-axis +ElastoDyn['Spn3MLxb2'] = False # (kN-m); Blade 2 local edgewise moment at span station 3; About the local xb2-axis +ElastoDyn['Spn3MLyb2'] = False # (kN-m); Blade 2 local flapwise moment at span station 3; About the local yb2-axis +ElastoDyn['Spn3MLzb2'] = False # (kN-m); Blade 2 local pitching moment at span station 3; About the local zb2-axis +ElastoDyn['Spn4MLxb2'] = False # (kN-m); Blade 2 local edgewise moment at span station 4; About the local xb2-axis +ElastoDyn['Spn4MLyb2'] = False # (kN-m); Blade 2 local flapwise moment at span station 4; About the local yb2-axis +ElastoDyn['Spn4MLzb2'] = False # (kN-m); Blade 2 local pitching moment at span station 4; About the local zb2-axis +ElastoDyn['Spn5MLxb2'] = False # (kN-m); Blade 2 local edgewise moment at span station 5; About the local xb2-axis +ElastoDyn['Spn5MLyb2'] = False # (kN-m); Blade 2 local flapwise moment at span station 5; About the local yb2-axis +ElastoDyn['Spn5MLzb2'] = False # (kN-m); Blade 2 local pitching moment at span station 5; About the local zb2-axis +ElastoDyn['Spn6MLxb2'] = False # (kN-m); Blade 2 local edgewise moment at span station 6; About the local xb2-axis +ElastoDyn['Spn6MLyb2'] = False # (kN-m); Blade 2 local flapwise moment at span station 6; About the local yb2-axis +ElastoDyn['Spn6MLzb2'] = False # (kN-m); Blade 2 local pitching moment at span station 6; About the local zb2-axis +ElastoDyn['Spn7MLxb2'] = False # (kN-m); Blade 2 local edgewise moment at span station 7; About the local xb2-axis +ElastoDyn['Spn7MLyb2'] = False # (kN-m); Blade 2 local flapwise moment at span station 7; About the local yb2-axis +ElastoDyn['Spn7MLzb2'] = False # (kN-m); Blade 2 local pitching moment at span station 7; About the local zb2-axis +ElastoDyn['Spn8MLxb2'] = False # (kN-m); Blade 2 local edgewise moment at span station 8; About the local xb2-axis +ElastoDyn['Spn8MLyb2'] = False # (kN-m); Blade 2 local flapwise moment at span station 8; About the local yb2-axis +ElastoDyn['Spn8MLzb2'] = False # (kN-m); Blade 2 local pitching moment at span station 8; About the local zb2-axis +ElastoDyn['Spn9MLxb2'] = False # (kN-m); Blade 2 local edgewise moment at span station 9; About the local xb2-axis +ElastoDyn['Spn9MLyb2'] = False # (kN-m); Blade 2 local flapwise moment at span station 9; About the local yb2-axis +ElastoDyn['Spn9MLzb2'] = False # (kN-m); Blade 2 local pitching moment at span station 9; About the local zb2-axis +ElastoDyn['Spn1FLxb2'] = False # (kN); Blade 2 local flapwise shear force at span station 1; Directed along the local xb2-axis +ElastoDyn['Spn1FLyb2'] = False # (kN); Blade 2 local edgewise shear force at span station 1; Directed along the local yb2-axis +ElastoDyn['Spn1FLzb2'] = False # (kN); Blade 2 local axial force at span station 1; Directed along the local zb2-axis +ElastoDyn['Spn2FLxb2'] = False # (kN); Blade 2 local flapwise shear force at span station 2; Directed along the local xb2-axis +ElastoDyn['Spn2FLyb2'] = False # (kN); Blade 2 local edgewise shear force at span station 2; Directed along the local yb2-axis +ElastoDyn['Spn2FLzb2'] = False # (kN); Blade 2 local axial force at span station 2; Directed along the local zb2-axis +ElastoDyn['Spn3FLxb2'] = False # (kN); Blade 2 local flapwise shear force at span station 3; Directed along the local xb2-axis +ElastoDyn['Spn3FLyb2'] = False # (kN); Blade 2 local edgewise shear force at span station 3; Directed along the local yb2-axis +ElastoDyn['Spn3FLzb2'] = False # (kN); Blade 2 local axial force at span station 3; Directed along the local zb2-axis +ElastoDyn['Spn4FLxb2'] = False # (kN); Blade 2 local flapwise shear force at span station 4; Directed along the local xb2-axis +ElastoDyn['Spn4FLyb2'] = False # (kN); Blade 2 local edgewise shear force at span station 4; Directed along the local yb2-axis +ElastoDyn['Spn4FLzb2'] = False # (kN); Blade 2 local axial force at span station 4; Directed along the local zb2-axis +ElastoDyn['Spn5FLxb2'] = False # (kN); Blade 2 local flapwise shear force at span station 5; Directed along the local xb2-axis +ElastoDyn['Spn5FLyb2'] = False # (kN); Blade 2 local edgewise shear force at span station 5; Directed along the local yb2-axis +ElastoDyn['Spn5FLzb2'] = False # (kN); Blade 2 local axial force at span station 5; Directed along the local zb2-axis +ElastoDyn['Spn6FLxb2'] = False # (kN); Blade 2 local flapwise shear force at span station 6; Directed along the local xb2-axis +ElastoDyn['Spn6FLyb2'] = False # (kN); Blade 2 local edgewise shear force at span station 6; Directed along the local yb2-axis +ElastoDyn['Spn6FLzb2'] = False # (kN); Blade 2 local axial force at span station 6; Directed along the local zb2-axis +ElastoDyn['Spn7FLxb2'] = False # (kN); Blade 2 local flapwise shear force at span station 7; Directed along the local xb2-axis +ElastoDyn['Spn7FLyb2'] = False # (kN); Blade 2 local edgewise shear force at span station 7; Directed along the local yb2-axis +ElastoDyn['Spn7FLzb2'] = False # (kN); Blade 2 local axial force at span station 7; Directed along the local zb2-axis +ElastoDyn['Spn8FLxb2'] = False # (kN); Blade 2 local flapwise shear force at span station 8; Directed along the local xb2-axis +ElastoDyn['Spn8FLyb2'] = False # (kN); Blade 2 local edgewise shear force at span station 8; Directed along the local yb2-axis +ElastoDyn['Spn8FLzb2'] = False # (kN); Blade 2 local axial force at span station 8; Directed along the local zb2-axis +ElastoDyn['Spn9FLxb2'] = False # (kN); Blade 2 local flapwise shear force at span station 9; Directed along the local xb2-axis +ElastoDyn['Spn9FLyb2'] = False # (kN); Blade 2 local edgewise shear force at span station 9; Directed along the local yb2-axis +ElastoDyn['Spn9FLzb2'] = False # (kN); Blade 2 local axial force at span station 9; Directed along the local zb2-axis + +# Blade 3 Local Span Loads +ElastoDyn['Spn1MLxb3'] = False # (kN-m); Blade 3 local edgewise moment at span station 1; About the local xb3-axis +ElastoDyn['Spn1MLyb3'] = False # (kN-m); Blade 3 local flapwise moment at span station 1; About the local yb3-axis +ElastoDyn['Spn1MLzb3'] = False # (kN-m); Blade 3 local pitching moment at span station 1; About the local zb3-axis +ElastoDyn['Spn2MLxb3'] = False # (kN-m); Blade 3 local edgewise moment at span station 2; About the local xb3-axis +ElastoDyn['Spn2MLyb3'] = False # (kN-m); Blade 3 local flapwise moment at span station 2; About the local yb3-axis +ElastoDyn['Spn2MLzb3'] = False # (kN-m); Blade 3 local pitching moment at span station 2; About the local zb3-axis +ElastoDyn['Spn3MLxb3'] = False # (kN-m); Blade 3 local edgewise moment at span station 3; About the local xb3-axis +ElastoDyn['Spn3MLyb3'] = False # (kN-m); Blade 3 local flapwise moment at span station 3; About the local yb3-axis +ElastoDyn['Spn3MLzb3'] = False # (kN-m); Blade 3 local pitching moment at span station 3; About the local zb3-axis +ElastoDyn['Spn4MLxb3'] = False # (kN-m); Blade 3 local edgewise moment at span station 4; About the local xb3-axis +ElastoDyn['Spn4MLyb3'] = False # (kN-m); Blade 3 local flapwise moment at span station 4; About the local yb3-axis +ElastoDyn['Spn4MLzb3'] = False # (kN-m); Blade 3 local pitching moment at span station 4; About the local zb3-axis +ElastoDyn['Spn5MLxb3'] = False # (kN-m); Blade 3 local edgewise moment at span station 5; About the local xb3-axis +ElastoDyn['Spn5MLyb3'] = False # (kN-m); Blade 3 local flapwise moment at span station 5; About the local yb3-axis +ElastoDyn['Spn5MLzb3'] = False # (kN-m); Blade 3 local pitching moment at span station 5; About the local zb3-axis +ElastoDyn['Spn6MLxb3'] = False # (kN-m); Blade 3 local edgewise moment at span station 6; About the local xb3-axis +ElastoDyn['Spn6MLyb3'] = False # (kN-m); Blade 3 local flapwise moment at span station 6; About the local yb3-axis +ElastoDyn['Spn6MLzb3'] = False # (kN-m); Blade 3 local pitching moment at span station 6; About the local zb3-axis +ElastoDyn['Spn7MLxb3'] = False # (kN-m); Blade 3 local edgewise moment at span station 7; About the local xb3-axis +ElastoDyn['Spn7MLyb3'] = False # (kN-m); Blade 3 local flapwise moment at span station 7; About the local yb3-axis +ElastoDyn['Spn7MLzb3'] = False # (kN-m); Blade 3 local pitching moment at span station 7; About the local zb3-axis +ElastoDyn['Spn8MLxb3'] = False # (kN-m); Blade 3 local edgewise moment at span station 8; About the local xb3-axis +ElastoDyn['Spn8MLyb3'] = False # (kN-m); Blade 3 local flapwise moment at span station 8; About the local yb3-axis +ElastoDyn['Spn8MLzb3'] = False # (kN-m); Blade 3 local pitching moment at span station 8; About the local zb3-axis +ElastoDyn['Spn9MLxb3'] = False # (kN-m); Blade 3 local edgewise moment at span station 9; About the local xb3-axis +ElastoDyn['Spn9MLyb3'] = False # (kN-m); Blade 3 local flapwise moment at span station 9; About the local yb3-axis +ElastoDyn['Spn9MLzb3'] = False # (kN-m); Blade 3 local pitching moment at span station 9; About the local zb3-axis +ElastoDyn['Spn1FLxb3'] = False # (kN); Blade 3 local flapwise shear force at span station 1; Directed along the local xb3-axis +ElastoDyn['Spn1FLyb3'] = False # (kN); Blade 3 local edgewise shear force at span station 1; Directed along the local yb3-axis +ElastoDyn['Spn1FLzb3'] = False # (kN); Blade 3 local axial force at span station 1; Directed along the local zb3-axis +ElastoDyn['Spn2FLxb3'] = False # (kN); Blade 3 local flapwise shear force at span station 2; Directed along the local xb3-axis +ElastoDyn['Spn2FLyb3'] = False # (kN); Blade 3 local edgewise shear force at span station 2; Directed along the local yb3-axis +ElastoDyn['Spn2FLzb3'] = False # (kN); Blade 3 local axial force at span station 2; Directed along the local zb3-axis +ElastoDyn['Spn3FLxb3'] = False # (kN); Blade 3 local flapwise shear force at span station 3; Directed along the local xb3-axis +ElastoDyn['Spn3FLyb3'] = False # (kN); Blade 3 local edgewise shear force at span station 3; Directed along the local yb3-axis +ElastoDyn['Spn3FLzb3'] = False # (kN); Blade 3 local axial force at span station 3; Directed along the local zb3-axis +ElastoDyn['Spn4FLxb3'] = False # (kN); Blade 3 local flapwise shear force at span station 4; Directed along the local xb3-axis +ElastoDyn['Spn4FLyb3'] = False # (kN); Blade 3 local edgewise shear force at span station 4; Directed along the local yb3-axis +ElastoDyn['Spn4FLzb3'] = False # (kN); Blade 3 local axial force at span station 4; Directed along the local zb3-axis +ElastoDyn['Spn5FLxb3'] = False # (kN); Blade 3 local flapwise shear force at span station 5; Directed along the local xb3-axis +ElastoDyn['Spn5FLyb3'] = False # (kN); Blade 3 local edgewise shear force at span station 5; Directed along the local yb3-axis +ElastoDyn['Spn5FLzb3'] = False # (kN); Blade 3 local axial force at span station 5; Directed along the local zb3-axis +ElastoDyn['Spn6FLxb3'] = False # (kN); Blade 3 local flapwise shear force at span station 6; Directed along the local xb3-axis +ElastoDyn['Spn6FLyb3'] = False # (kN); Blade 3 local edgewise shear force at span station 6; Directed along the local yb3-axis +ElastoDyn['Spn6FLzb3'] = False # (kN); Blade 3 local axial force at span station 6; Directed along the local zb3-axis +ElastoDyn['Spn7FLxb3'] = False # (kN); Blade 3 local flapwise shear force at span station 7; Directed along the local xb3-axis +ElastoDyn['Spn7FLyb3'] = False # (kN); Blade 3 local edgewise shear force at span station 7; Directed along the local yb3-axis +ElastoDyn['Spn7FLzb3'] = False # (kN); Blade 3 local axial force at span station 7; Directed along the local zb3-axis +ElastoDyn['Spn8FLxb3'] = False # (kN); Blade 3 local flapwise shear force at span station 8; Directed along the local xb3-axis +ElastoDyn['Spn8FLyb3'] = False # (kN); Blade 3 local edgewise shear force at span station 8; Directed along the local yb3-axis +ElastoDyn['Spn8FLzb3'] = False # (kN); Blade 3 local axial force at span station 8; Directed along the local zb3-axis +ElastoDyn['Spn9FLxb3'] = False # (kN); Blade 3 local flapwise shear force at span station 9; Directed along the local xb3-axis +ElastoDyn['Spn9FLyb3'] = False # (kN); Blade 3 local edgewise shear force at span station 9; Directed along the local yb3-axis +ElastoDyn['Spn9FLzb3'] = False # (kN); Blade 3 local axial force at span station 9; Directed along the local zb3-axis + +# Hub and Rotor Loads +ElastoDyn['LSShftFxa'] = False # (kN); Low-speed shaft thrust force (this is constant along the shaft and is equivalent to the rotor thrust force); Directed along the xa- and xs-axes +ElastoDyn['LSShftFxs'] = False # (kN); Low-speed shaft thrust force (this is constant along the shaft and is equivalent to the rotor thrust force); Directed along the xa- and xs-axes +ElastoDyn['LSSGagFxa'] = False # (kN); Low-speed shaft thrust force (this is constant along the shaft and is equivalent to the rotor thrust force); Directed along the xa- and xs-axes +ElastoDyn['LSSGagFxs'] = False # (kN); Low-speed shaft thrust force (this is constant along the shaft and is equivalent to the rotor thrust force); Directed along the xa- and xs-axes +ElastoDyn['RotThrust'] = False # (kN); Low-speed shaft thrust force (this is constant along the shaft and is equivalent to the rotor thrust force); Directed along the xa- and xs-axes +ElastoDyn['LSShftFya'] = False # (kN); Rotating low-speed shaft shear force (this is constant along the shaft); Directed along the ya-axis +ElastoDyn['LSSGagFya'] = False # (kN); Rotating low-speed shaft shear force (this is constant along the shaft); Directed along the ya-axis +ElastoDyn['LSShftFza'] = False # (kN); Rotating low-speed shaft shear force (this is constant along the shaft); Directed along the za-axis +ElastoDyn['LSSGagFza'] = False # (kN); Rotating low-speed shaft shear force (this is constant along the shaft); Directed along the za-axis +ElastoDyn['LSShftFys'] = True # (kN); Nonrotating low-speed shaft shear force (this is constant along the shaft); Directed along the ys-axis +ElastoDyn['LSSGagFys'] = False # (kN); Nonrotating low-speed shaft shear force (this is constant along the shaft); Directed along the ys-axis +ElastoDyn['LSShftFzs'] = True # (kN); Nonrotating low-speed shaft shear force (this is constant along the shaft); Directed along the zs-axis +ElastoDyn['LSSGagFzs'] = False # (kN); Nonrotating low-speed shaft shear force (this is constant along the shaft); Directed along the zs-axis +ElastoDyn['LSShftMxa'] = False # (kN-m); Low-speed shaft torque (this is constant along the shaft and is equivalent to the rotor torque); About the xa- and xs-axes +ElastoDyn['LSShftMxs'] = False # (kN-m); Low-speed shaft torque (this is constant along the shaft and is equivalent to the rotor torque); About the xa- and xs-axes +ElastoDyn['LSSGagMxa'] = False # (kN-m); Low-speed shaft torque (this is constant along the shaft and is equivalent to the rotor torque); About the xa- and xs-axes +ElastoDyn['LSSGagMxs'] = False # (kN-m); Low-speed shaft torque (this is constant along the shaft and is equivalent to the rotor torque); About the xa- and xs-axes +ElastoDyn['RotTorq'] = False # (kN-m); Low-speed shaft torque (this is constant along the shaft and is equivalent to the rotor torque); About the xa- and xs-axes +ElastoDyn['LSShftTq'] = False # (kN-m); Low-speed shaft torque (this is constant along the shaft and is equivalent to the rotor torque); About the xa- and xs-axes +ElastoDyn['LSSTipMya'] = False # (kN-m); Rotating low-speed shaft bending moment at the shaft tip (teeter pin for 2-blader, apex of rotation for 3-blader); About the ya-axis +ElastoDyn['LSSTipMza'] = False # (kN-m); Rotating low-speed shaft bending moment at the shaft tip (teeter pin for 2-blader, apex of rotation for 3-blader); About the za-axis +ElastoDyn['LSSTipMys'] = True # (kN-m); Nonrotating low-speed shaft bending moment at the shaft tip (teeter pin for 2-blader, apex of rotation for 3-blader); About the ys-axis +ElastoDyn['LSSTipMzs'] = True # (kN-m); Nonrotating low-speed shaft bending moment at the shaft tip (teeter pin for 2-blader, apex of rotation for 3-blader); About the zs-axis +ElastoDyn['RotPwr'] = False # (kW); Rotor power (this is equivalent to the low-speed shaft power); N/A +ElastoDyn['LSShftPwr'] = False # (kW); Rotor power (this is equivalent to the low-speed shaft power); N/A -# Rotor -AeroDyn['RtSpeed'] = False # (rpm); Rotor speed; -AeroDyn['RtTSR'] = False # (-); Rotor tip-speed ratio; -AeroDyn['RtVAvgxh'] = False # (m/s); Rotor-disk-averaged relative wind velocity (x-component); the hub coordinate system -AeroDyn['RtVAvgyh'] = False # (m/s); Rotor-disk-averaged relative wind velocity (y-component); the hub coordinate system -AeroDyn['RtVAvgzh'] = False # (m/s); Rotor-disk-averaged relative wind velocity (z-component); the hub coordinate system -AeroDyn['RtSkew'] = False # (deg); Rotor inflow-skew angle; -AeroDyn['RtFldFxh'] = False # (N); Total rotor aerodynamic load (force in x direction); the hub coordinate system -AeroDyn['RtFldFyh'] = False # (N); Total rotor aerodynamic load (force in y direction); the hub coordinate system -AeroDyn['RtFldFzh'] = False # (N); Total rotor aerodynamic load (force in z direction); the hub coordinate system -AeroDyn['RtFldMxh'] = False # (N m); Total rotor aerodynamic load (moment in x direction); the hub coordinate system -AeroDyn['RtFldMyh'] = False # (N m); Total rotor aerodynamic load (moment in y direction); the hub coordinate system -AeroDyn['RtFldMzh'] = False # (N m); Total rotor aerodynamic load (moment in z direction); the hub coordinate system -AeroDyn['RtFldPwr'] = False # (W); Rotor aerodynamic power; -AeroDyn['RtArea'] = False # (m^2); Rotor swept area; -AeroDyn['RtFldCp'] = False # (-); Rotor aerodynamic power coefficient; -AeroDyn['RtFldCq'] = False # (-); Rotor aerodynamic torque coefficient; -AeroDyn['RtFldCt'] = False # (-); Rotor aerodynamic thrust coefficient; +# Shaft Strain Gage Loads +ElastoDyn['LSSGagMya'] = False # (kN-m); Rotating low-speed shaft bending moment at the shaft's strain gage (shaft strain gage located by input ShftGagL); About the ya-axis +ElastoDyn['LSSGagMza'] = False # (kN-m); Rotating low-speed shaft bending moment at the shaft's strain gage (shaft strain gage located by input ShftGagL); About the za-axis +ElastoDyn['LSSGagMys'] = False # (kN-m); Nonrotating low-speed shaft bending moment at the shaft's strain gage (shaft strain gage located by input ShftGagL); About the ys-axis +ElastoDyn['LSSGagMzs'] = False # (kN-m); Nonrotating low-speed shaft bending moment at the shaft's strain gage (shaft strain gage located by input ShftGagL); About the zs-axis + +# High-Speed Shaft Loads +ElastoDyn['HSShftTq'] = False # (kN-m); High-speed shaft torque (this is constant along the shaft); Same sign as LSShftTq / RotTorq / LSShftMxa / LSShftMxs / LSSGagMxa / LSSGagMxs +ElastoDyn['HSSBrTq'] = False # (kN-m); High-speed shaft brake torque (i.e., the actual moment applied to the high-speed shaft by the brake); Always positive (indicating dissipation of power) +ElastoDyn['HSShftPwr'] = False # (kW); High-speed shaft power; Same sign as HSShftTq + +# Rotor-Furl Bearing Loads +ElastoDyn['RFrlBrM'] = False # (kN-m); Rotor-furl bearing moment; About the rotor-furl axis + +# Tail-Furl Bearing Loads +ElastoDyn['TFrlBrM'] = False # (kN-m); Tail-furl bearing moment; About the tail-furl axis + +# Tower-Top / Yaw Bearing Loads +ElastoDyn['YawBrFxn'] = False # (kN); Rotating (with nacelle) tower-top / yaw bearing shear force; Directed along the xn-axis +ElastoDyn['YawBrFyn'] = False # (kN); Rotating (with nacelle) tower-top / yaw bearing shear force; Directed along the yn-axis +ElastoDyn['YawBrFzn'] = False # (kN); Tower-top / yaw bearing axial force; Directed along the zn- and zp-axes +ElastoDyn['YawBrFzp'] = False # (kN); Tower-top / yaw bearing axial force; Directed along the zn- and zp-axes +ElastoDyn['YawBrFxp'] = False # (kN); Tower-top / yaw bearing fore-aft (nonrotating) shear force; Directed along the xp-axis +ElastoDyn['YawBrFyp'] = False # (kN); Tower-top / yaw bearing side-to-side (nonrotating) shear force; Directed along the yp-axis +ElastoDyn['YawBrMxn'] = False # (kN-m); Rotating (with nacelle) tower-top / yaw bearing roll moment; About the xn-axis +ElastoDyn['YawBrMyn'] = False # (kN-m); Rotating (with nacelle) tower-top / yaw bearing pitch moment; About the yn-axis +ElastoDyn['YawBrMzn'] = False # (kN-m); Tower-top / yaw bearing yaw moment; About the zn- and zp-axes +ElastoDyn['YawBrMzp'] = False # (kN-m); Tower-top / yaw bearing yaw moment; About the zn- and zp-axes +ElastoDyn['YawBrMxp'] = False # (kN-m); Nonrotating tower-top / yaw bearing roll moment; About the xp-axis +ElastoDyn['YawBrMyp'] = False # (kN-m); Nonrotating tower-top / yaw bearing pitch moment; About the yp-axis + +# Yaw Friction +ElastoDyn['YawFriMom'] = False # (kN-m); Calculated and corrected friction torque on yaw bearing; About the zn- and zp-axes +ElastoDyn['YawFriMfp'] = False # (kN-m); Yaw friction torque to bring yaw system to a stop at current time step; About the zn- and zp-axes +ElastoDyn['YawFriMz'] = False # (kN-m); External moment on yaw bearing not including inertial contributions; About the zn- and zp-axes +ElastoDyn['OmegaYF'] = False # (deg/s); Yaw rate used in YawFriMom calculation; Directed along the zn- and zp-axes +ElastoDyn['dOmegaYF'] = False # (deg/s^2); Yaw acceleration used in YawFriMom calculation; Directed along the zn- and zp-axes + +# Tower Base Loads +ElastoDyn['TwrBsFxt'] = False # (kN); Tower base fore-aft shear force; Directed along the xt-axis +ElastoDyn['TwrBsFyt'] = False # (kN); Tower base side-to-side shear force; Directed along the yt-axis +ElastoDyn['TwrBsFzt'] = False # (kN); Tower base axial force; Directed along the zt-axis +ElastoDyn['TwrBsMxt'] = False # (kN-m); Tower base roll (or side-to-side) moment (i.e., the moment caused by side-to-side forces); About the xt-axis +ElastoDyn['TwrBsMyt'] = True # (kN-m); Tower base pitching (or fore-aft) moment (i.e., the moment caused by fore-aft forces); About the yt-axis +ElastoDyn['TwrBsMzt'] = False # (kN-m); Tower base yaw (or torsional) moment; About the zt-axis + +# Local Tower Loads +ElastoDyn['TwHt1MLxt'] = False # (kN-m); Local tower roll (or side-to-side) moment of tower gage 1; About the local xt-axis +ElastoDyn['TwHt1MLyt'] = False # (kN-m); Local tower pitching (or fore-aft) moment of tower gage 1; About the local yt-axis +ElastoDyn['TwHt1MLzt'] = False # (kN-m); Local tower yaw (or torsional) moment of tower gage 1; About the local zt-axis +ElastoDyn['TwHt2MLxt'] = False # (kN-m); Local tower roll (or side-to-side) moment of tower gage 2; About the local xt-axis +ElastoDyn['TwHt2MLyt'] = False # (kN-m); Local tower pitching (or fore-aft) moment of tower gage 2; About the local yt-axis +ElastoDyn['TwHt2MLzt'] = False # (kN-m); Local tower yaw (or torsional) moment of tower gage 2; About the local zt-axis +ElastoDyn['TwHt3MLxt'] = False # (kN-m); Local tower roll (or side-to-side) moment of tower gage 3; About the local xt-axis +ElastoDyn['TwHt3MLyt'] = False # (kN-m); Local tower pitching (or fore-aft) moment of tower gage 3; About the local yt-axis +ElastoDyn['TwHt3MLzt'] = False # (kN-m); Local tower yaw (or torsional) moment of tower gage 3; About the local zt-axis +ElastoDyn['TwHt4MLxt'] = False # (kN-m); Local tower roll (or side-to-side) moment of tower gage 4; About the local xt-axis +ElastoDyn['TwHt4MLyt'] = False # (kN-m); Local tower pitching (or fore-aft) moment of tower gage 4; About the local yt-axis +ElastoDyn['TwHt4MLzt'] = False # (kN-m); Local tower yaw (or torsional) moment of tower gage 4; About the local zt-axis +ElastoDyn['TwHt5MLxt'] = False # (kN-m); Local tower roll (or side-to-side) moment of tower gage 5; About the local xt-axis +ElastoDyn['TwHt5MLyt'] = False # (kN-m); Local tower pitching (or fore-aft) moment of tower gage 5; About the local yt-axis +ElastoDyn['TwHt5MLzt'] = False # (kN-m); Local tower yaw (or torsional) moment of tower gage 5; About the local zt-axis +ElastoDyn['TwHt6MLxt'] = False # (kN-m); Local tower roll (or side-to-side) moment of tower gage 6; About the local xt-axis +ElastoDyn['TwHt6MLyt'] = False # (kN-m); Local tower pitching (or fore-aft) moment of tower gage 6; About the local yt-axis +ElastoDyn['TwHt6MLzt'] = False # (kN-m); Local tower yaw (or torsional) moment of tower gage 6; About the local zt-axis +ElastoDyn['TwHt7MLxt'] = False # (kN-m); Local tower roll (or side-to-side) moment of tower gage 7; About the local xt-axis +ElastoDyn['TwHt7MLyt'] = False # (kN-m); Local tower pitching (or fore-aft) moment of tower gage 7; About the local yt-axis +ElastoDyn['TwHt7MLzt'] = False # (kN-m); Local tower yaw (or torsional) moment of tower gage 7; About the local zt-axis +ElastoDyn['TwHt8MLxt'] = False # (kN-m); Local tower roll (or side-to-side) moment of tower gage 8; About the local xt-axis +ElastoDyn['TwHt8MLyt'] = False # (kN-m); Local tower pitching (or fore-aft) moment of tower gage 8; About the local yt-axis +ElastoDyn['TwHt8MLzt'] = False # (kN-m); Local tower yaw (or torsional) moment of tower gage 8; About the local zt-axis +ElastoDyn['TwHt9MLxt'] = False # (kN-m); Local tower roll (or side-to-side) moment of tower gage 9; About the local xt-axis +ElastoDyn['TwHt9MLyt'] = False # (kN-m); Local tower pitching (or fore-aft) moment of tower gage 9; About the local yt-axis +ElastoDyn['TwHt9MLzt'] = False # (kN-m); Local tower yaw (or torsional) moment of tower gage 9; About the local zt-axis +ElastoDyn['TwHt1FLxt'] = False # (kN); Local tower roll (or side-to-side) force of tower gage 1; About the local xt-axis +ElastoDyn['TwHt1FLyt'] = False # (kN); Local tower pitching (or fore-aft) force of tower gage 1; About the local yt-axis +ElastoDyn['TwHt1FLzt'] = False # (kN); Local tower yaw (or torsional) force of tower gage 1; About the local zt-axis +ElastoDyn['TwHt2FLxt'] = False # (kN); Local tower roll (or side-to-side) force of tower gage 2; About the local xt-axis +ElastoDyn['TwHt2FLyt'] = False # (kN); Local tower pitching (or fore-aft) force of tower gage 2; About the local yt-axis +ElastoDyn['TwHt2FLzt'] = False # (kN); Local tower yaw (or torsional) force of tower gage 2; About the local zt-axis +ElastoDyn['TwHt3FLxt'] = False # (kN); Local tower roll (or side-to-side) force of tower gage 3; About the local xt-axis +ElastoDyn['TwHt3FLyt'] = False # (kN); Local tower pitching (or fore-aft) force of tower gage 3; About the local yt-axis +ElastoDyn['TwHt3FLzt'] = False # (kN); Local tower yaw (or torsional) force of tower gage 3; About the local zt-axis +ElastoDyn['TwHt4FLxt'] = False # (kN); Local tower roll (or side-to-side) force of tower gage 4; About the local xt-axis +ElastoDyn['TwHt4FLyt'] = False # (kN); Local tower pitching (or fore-aft) force of tower gage 4; About the local yt-axis +ElastoDyn['TwHt4FLzt'] = False # (kN); Local tower yaw (or torsional) force of tower gage 4; About the local zt-axis +ElastoDyn['TwHt5FLxt'] = False # (kN); Local tower roll (or side-to-side) force of tower gage 5; About the local xt-axis +ElastoDyn['TwHt5FLyt'] = False # (kN); Local tower pitching (or fore-aft) force of tower gage 5; About the local yt-axis +ElastoDyn['TwHt5FLzt'] = False # (kN); Local tower yaw (or torsional) force of tower gage 5; About the local zt-axis +ElastoDyn['TwHt6FLxt'] = False # (kN); Local tower roll (or side-to-side) force of tower gage 6; About the local xt-axis +ElastoDyn['TwHt6FLyt'] = False # (kN); Local tower pitching (or fore-aft) force of tower gage 6; About the local yt-axis +ElastoDyn['TwHt6FLzt'] = False # (kN); Local tower yaw (or torsional) force of tower gage 6; About the local zt-axis +ElastoDyn['TwHt7FLxt'] = False # (kN); Local tower roll (or side-to-side) force of tower gage 7; About the local xt-axis +ElastoDyn['TwHt7FLyt'] = False # (kN); Local tower pitching (or fore-aft) force of tower gage 7; About the local yt-axis +ElastoDyn['TwHt7FLzt'] = False # (kN); Local tower yaw (or torsional) force of tower gage 7; About the local zt-axis +ElastoDyn['TwHt8FLxt'] = False # (kN); Local tower roll (or side-to-side) force of tower gage 8; About the local xt-axis +ElastoDyn['TwHt8FLyt'] = False # (kN); Local tower pitching (or fore-aft) force of tower gage 8; About the local yt-axis +ElastoDyn['TwHt8FLzt'] = False # (kN); Local tower yaw (or torsional) force of tower gage 8; About the local zt-axis +ElastoDyn['TwHt9FLxt'] = False # (kN); Local tower roll (or side-to-side) force of tower gage 9; About the local xt-axis +ElastoDyn['TwHt9FLyt'] = False # (kN); Local tower pitching (or fore-aft) force of tower gage 9; About the local yt-axis +ElastoDyn['TwHt9FLzt'] = False # (kN); Local tower yaw (or torsional) force of tower gage 9; About the local zt-axis + +# Internal Degrees of Freedom +ElastoDyn['Q_B1E1'] = False # (m); Displacement of 1st edgewise bending-mode DOF of blade 1; +ElastoDyn['Q_B2E1'] = False # (m); Displacement of 1st edgewise bending-mode DOF of blade 2; +ElastoDyn['Q_B3E1'] = False # (m); Displacement of 1st edgewise bending-mode DOF of blade 3; +ElastoDyn['Q_B1F1'] = False # (m); Displacement of 1st flapwise bending-mode DOF of blade 1; +ElastoDyn['Q_B2F1'] = False # (m); Displacement of 1st flapwise bending-mode DOF of blade 2; +ElastoDyn['Q_B3F1'] = False # (m); Displacement of 1st flapwise bending-mode DOF of blade 3; +ElastoDyn['Q_B1F2'] = False # (m); Displacement of 2nd flapwise bending-mode DOF of blade 1; +ElastoDyn['Q_B2F2'] = False # (m); Displacement of 2nd flapwise bending-mode DOF of blade 2; +ElastoDyn['Q_B3F2'] = False # (m); Displacement of 2nd flapwise bending-mode DOF of blade 3; +ElastoDyn['Q_Teet'] = False # (rad); Displacement of hub teetering DOF; +ElastoDyn['Q_DrTr'] = False # (rad); Displacement of drivetrain rotational-flexibility DOF; +ElastoDyn['Q_GeAz'] = False # (rad); Displacement of variable speed generator DOF; +ElastoDyn['Q_RFrl'] = False # (rad); Displacement of rotor-furl DOF; +ElastoDyn['Q_TFrl'] = False # (rad); Displacement of tail-furl DOF; +ElastoDyn['Q_Yaw'] = False # (rad); Displacement of nacelle yaw DOF; +ElastoDyn['Q_TFA1'] = False # (m); Displacement of 1st tower fore-aft bending mode DOF; +ElastoDyn['Q_TSS1'] = False # (m); Displacement of 1st tower side-to-side bending mode DOF; +ElastoDyn['Q_TFA2'] = False # (m); Displacement of 2nd tower fore-aft bending mode DOF; +ElastoDyn['Q_TSS2'] = False # (m); Displacement of 2nd tower side-to-side bending mode DOF; +ElastoDyn['Q_Sg'] = False # (m); Displacement of platform horizontal surge translation DOF; +ElastoDyn['Q_Sw'] = False # (m); Displacement of platform horizontal sway translation DOF; +ElastoDyn['Q_Hv'] = False # (m); Displacement of platform vertical heave translation DOF; +ElastoDyn['Q_R'] = False # (rad); Displacement of platform roll tilt rotation DOF; +ElastoDyn['Q_P'] = False # (rad); Displacement of platform pitch tilt rotation DOF; +ElastoDyn['Q_Y'] = False # (rad); Displacement of platform yaw rotation DOF; +ElastoDyn['QD_B1E1'] = False # (m/s); Velocity of 1st edgewise bending-mode DOF of blade 1; +ElastoDyn['QD_B2E1'] = False # (m/s); Velocity of 1st edgewise bending-mode DOF of blade 2; +ElastoDyn['QD_B3E1'] = False # (m/s); Velocity of 1st edgewise bending-mode DOF of blade 3; +ElastoDyn['QD_B1F1'] = False # (m/s); Velocity of 1st flapwise bending-mode DOF of blade 1; +ElastoDyn['QD_B2F1'] = False # (m/s); Velocity of 1st flapwise bending-mode DOF of blade 2; +ElastoDyn['QD_B3F1'] = False # (m/s); Velocity of 1st flapwise bending-mode DOF of blade 3; +ElastoDyn['QD_B1F2'] = False # (m/s); Velocity of 2nd flapwise bending-mode DOF of blade 1; +ElastoDyn['QD_B2F2'] = False # (m/s); Velocity of 2nd flapwise bending-mode DOF of blade 2; +ElastoDyn['QD_B3F2'] = False # (m/s); Velocity of 2nd flapwise bending-mode DOF of blade 3; +ElastoDyn['QD_Teet'] = False # (rad/s); Velocity of hub teetering DOF; +ElastoDyn['QD_DrTr'] = False # (rad/s); Velocity of drivetrain rotational-flexibility DOF; +ElastoDyn['QD_GeAz'] = False # (rad/s); Velocity of variable speed generator DOF; +ElastoDyn['QD_RFrl'] = False # (rad/s); Velocity of rotor-furl DOF; +ElastoDyn['QD_TFrl'] = False # (rad/s); Velocity of tail-furl DOF; +ElastoDyn['QD_Yaw'] = False # (rad/s); Velocity of nacelle yaw DOF; +ElastoDyn['QD_TFA1'] = False # (m/s); Velocity of 1st tower fore-aft bending mode DOF; +ElastoDyn['QD_TSS1'] = False # (m/s); Velocity of 1st tower side-to-side bending mode DOF; +ElastoDyn['QD_TFA2'] = False # (m/s); Velocity of 2nd tower fore-aft bending mode DOF; +ElastoDyn['QD_TSS2'] = False # (m/s); Velocity of 2nd tower side-to-side bending mode DOF; +ElastoDyn['QD_Sg'] = False # (m/s); Velocity of platform horizontal surge translation DOF; +ElastoDyn['QD_Sw'] = False # (m/s); Velocity of platform horizontal sway translation DOF; +ElastoDyn['QD_Hv'] = False # (m/s); Velocity of platform vertical heave translation DOF; +ElastoDyn['QD_R'] = False # (rad/s); Velocity of platform roll tilt rotation DOF; +ElastoDyn['QD_P'] = False # (rad/s); Velocity of platform pitch tilt rotation DOF; +ElastoDyn['QD_Y'] = False # (rad/s); Velocity of platform yaw rotation DOF; +ElastoDyn['QD2_B1E1'] = False # (m/s^2); Acceleration of 1st edgewise bending-mode DOF of blade 1; +ElastoDyn['QD2_B2E1'] = False # (m/s^2); Acceleration of 1st edgewise bending-mode DOF of blade 2; +ElastoDyn['QD2_B3E1'] = False # (m/s^2); Acceleration of 1st edgewise bending-mode DOF of blade 3; +ElastoDyn['QD2_B1F1'] = False # (m/s^2); Acceleration of 1st flapwise bending-mode DOF of blade 1; +ElastoDyn['QD2_B2F1'] = False # (m/s^2); Acceleration of 1st flapwise bending-mode DOF of blade 2; +ElastoDyn['QD2_B3F1'] = False # (m/s^2); Acceleration of 1st flapwise bending-mode DOF of blade 3; +ElastoDyn['QD2_B1F2'] = False # (m/s^2); Acceleration of 2nd flapwise bending-mode DOF of blade 1; +ElastoDyn['QD2_B2F2'] = False # (m/s^2); Acceleration of 2nd flapwise bending-mode DOF of blade 2; +ElastoDyn['QD2_B3F2'] = False # (m/s^2); Acceleration of 2nd flapwise bending-mode DOF of blade 3; +ElastoDyn['QD2_Teet'] = False # (rad/s^2); Acceleration of hub teetering DOF; +ElastoDyn['QD2_DrTr'] = False # (rad/s^2); Acceleration of drivetrain rotational-flexibility DOF; +ElastoDyn['QD2_GeAz'] = False # (rad/s^2); Acceleration of variable speed generator DOF; +ElastoDyn['QD2_RFrl'] = False # (rad/s^2); Acceleration of rotor-furl DOF; +ElastoDyn['QD2_TFrl'] = False # (rad/s^2); Acceleration of tail-furl DOF; +ElastoDyn['QD2_Yaw'] = False # (rad/s^2); Acceleration of nacelle yaw DOF; +ElastoDyn['QD2_TFA1'] = False # (m/s^2); Acceleration of 1st tower fore-aft bending mode DOF; +ElastoDyn['QD2_TSS1'] = False # (m/s^2); Acceleration of 1st tower side-to-side bending mode DOF; +ElastoDyn['QD2_TFA2'] = False # (m/s^2); Acceleration of 2nd tower fore-aft bending mode DOF; +ElastoDyn['QD2_TSS2'] = False # (m/s^2); Acceleration of 2nd tower side-to-side bending mode DOF; +ElastoDyn['QD2_Sg'] = False # (m/s^2); Acceleration of platform horizontal surge translation DOF; +ElastoDyn['QD2_Sw'] = False # (m/s^2); Acceleration of platform horizontal sway translation DOF; +ElastoDyn['QD2_Hv'] = False # (m/s^2); Acceleration of platform vertical heave translation DOF; +ElastoDyn['QD2_R'] = False # (rad/s^2); Acceleration of platform roll tilt rotation DOF; +ElastoDyn['QD2_P'] = False # (rad/s^2); Acceleration of platform pitch tilt rotation DOF; +ElastoDyn['QD2_Y'] = False # (rad/s^2); Acceleration of platform yaw rotation DOF; """ InflowWind """ @@ -3268,6 +3195,41 @@ InflowWind['Wind9VelX'] = False # (m/s); X component of wind at user selected wind point 9; Directed along the xi-axis InflowWind['Wind9VelY'] = False # (m/s); Y component of wind at user selected wind point 9; Directed along the yi-axis InflowWind['Wind9VelZ'] = False # (m/s); Z component of wind at user selected wind point 9; Directed along the zi-axis +InflowWind['WindHubVelX'] = False # (m/s); X component of wind at (moving) hub point; Directed along the xi-axis +InflowWind['WindHubVelY'] = False # (m/s); Y component of wind at (moving) hub point; Directed along the yi-axis +InflowWind['WindHubVelZ'] = False # (m/s); Z component of wind at (moving) hub point; Directed along the zi-axis +InflowWind['WindDiskVelX'] = False # (m/s); Disk-average X component of wind (at 70% span); Directed along the xi-axis +InflowWind['WindDiskVelY'] = False # (m/s); Disk-average Y component of wind (at 70% span); Directed along the yi-axis +InflowWind['WindDiskVelZ'] = False # (m/s); Disk-average Z component of wind (at 70% span); Directed along the zi-axis + +# Wind Accelerations +InflowWind['Wind1AccX'] = False # (m/s); X component of wind at user selected wind point 1; Directed along the xi-axis +InflowWind['Wind1AccY'] = False # (m/s); Y component of wind at user selected wind point 1; Directed along the yi-axis +InflowWind['Wind1AccZ'] = False # (m/s); Z component of wind at user selected wind point 1; Directed along the zi-axis +InflowWind['Wind2AccX'] = False # (m/s); X component of wind at user selected wind point 2; Directed along the xi-axis +InflowWind['Wind2AccY'] = False # (m/s); Y component of wind at user selected wind point 2; Directed along the yi-axis +InflowWind['Wind2AccZ'] = False # (m/s); Z component of wind at user selected wind point 2; Directed along the zi-axis +InflowWind['Wind3AccX'] = False # (m/s); X component of wind at user selected wind point 3; Directed along the xi-axis +InflowWind['Wind3AccY'] = False # (m/s); Y component of wind at user selected wind point 3; Directed along the yi-axis +InflowWind['Wind3AccZ'] = False # (m/s); Z component of wind at user selected wind point 3; Directed along the zi-axis +InflowWind['Wind4AccX'] = False # (m/s); X component of wind at user selected wind point 4; Directed along the xi-axis +InflowWind['Wind4AccY'] = False # (m/s); Y component of wind at user selected wind point 4; Directed along the yi-axis +InflowWind['Wind4AccZ'] = False # (m/s); Z component of wind at user selected wind point 4; Directed along the zi-axis +InflowWind['Wind5AccX'] = False # (m/s); X component of wind at user selected wind point 5; Directed along the xi-axis +InflowWind['Wind5AccY'] = False # (m/s); Y component of wind at user selected wind point 5; Directed along the yi-axis +InflowWind['Wind5AccZ'] = False # (m/s); Z component of wind at user selected wind point 5; Directed along the zi-axis +InflowWind['Wind6AccX'] = False # (m/s); X component of wind at user selected wind point 6; Directed along the xi-axis +InflowWind['Wind6AccY'] = False # (m/s); Y component of wind at user selected wind point 6; Directed along the yi-axis +InflowWind['Wind6AccZ'] = False # (m/s); Z component of wind at user selected wind point 6; Directed along the zi-axis +InflowWind['Wind7AccX'] = False # (m/s); X component of wind at user selected wind point 7; Directed along the xi-axis +InflowWind['Wind7AccY'] = False # (m/s); Y component of wind at user selected wind point 7; Directed along the yi-axis +InflowWind['Wind7AccZ'] = False # (m/s); Z component of wind at user selected wind point 7; Directed along the zi-axis +InflowWind['Wind8AccX'] = False # (m/s); X component of wind at user selected wind point 8; Directed along the xi-axis +InflowWind['Wind8AccY'] = False # (m/s); Y component of wind at user selected wind point 8; Directed along the yi-axis +InflowWind['Wind8AccZ'] = False # (m/s); Z component of wind at user selected wind point 8; Directed along the zi-axis +InflowWind['Wind9AccX'] = False # (m/s); X component of wind at user selected wind point 9; Directed along the xi-axis +InflowWind['Wind9AccY'] = False # (m/s); Y component of wind at user selected wind point 9; Directed along the yi-axis +InflowWind['Wind9AccZ'] = False # (m/s); Z component of wind at user selected wind point 9; Directed along the zi-axis # Wind Magnitude and Direction InflowWind['Wind1VelXY'] = False # (m/s); XY (horizontal) wind magnitude at user selected wind point 1; @@ -3279,6 +3241,8 @@ InflowWind['Wind7VelXY'] = False # (m/s); XY (horizontal) wind magnitude at user selected wind point 7; InflowWind['Wind8VelXY'] = False # (m/s); XY (horizontal) wind magnitude at user selected wind point 8; InflowWind['Wind9VelXY'] = False # (m/s); XY (horizontal) wind magnitude at user selected wind point 9; +InflowWind['WindHubVelXY'] = False # (m/s); XY (horizontal) component of wind at (moving) hub point; +InflowWind['WindDiskVelXY'] = False # (m/s); XY (horizontal) component of disk-average wind (at 70% span); InflowWind['Wind1VelMag'] = False # (m/s); wind magnitude at user selected wind point 1; InflowWind['Wind2VelMag'] = False # (m/s); wind magnitude at user selected wind point 2; InflowWind['Wind3VelMag'] = False # (m/s); wind magnitude at user selected wind point 3; @@ -3288,6 +3252,8 @@ InflowWind['Wind7VelMag'] = False # (m/s); wind magnitude at user selected wind point 7; InflowWind['Wind8VelMag'] = False # (m/s); wind magnitude at user selected wind point 8; InflowWind['Wind9VelMag'] = False # (m/s); wind magnitude at user selected wind point 9; +InflowWind['WindHubVelMag'] = False # (m/s); wind magnitude at (moving) hub point; +InflowWind['WindDiskVelMag'] = False # (m/s); wind magnitude of disk-average wind (at 70% span); InflowWind['Wind1AngXY'] = False # (deg); Angle between X and Y wind velocity components at user selected wind point 1; InflowWind['Wind2AngXY'] = False # (deg); Angle between X and Y wind velocity components at user selected wind point 2; InflowWind['Wind3AngXY'] = False # (deg); Angle between X and Y wind velocity components at user selected wind point 3; @@ -3297,6 +3263,8 @@ InflowWind['Wind7AngXY'] = False # (deg); Angle between X and Y wind velocity components at user selected wind point 7; InflowWind['Wind8AngXY'] = False # (deg); Angle between X and Y wind velocity components at user selected wind point 8; InflowWind['Wind9AngXY'] = False # (deg); Angle between X and Y wind velocity components at user selected wind point 9; +InflowWind['WindHubAngXY'] = False # (deg); Angle between X and Y wind velocity components at (moving) hub point; +InflowWind['WindDiskAngXY'] = False # (deg); Angle between X and Y wind velocity components of disk-average wind (at 70% span); # Wind Sensor Measurements InflowWind['WindMeas1'] = False # (m/s); Wind measurement at sensor 1; Defined by sensor @@ -3306,47 +3274,545 @@ InflowWind['WindMeas5'] = False # (m/s); Wind measurement at sensor 5; Defined by sensor -""" WAMIT """ -WAMIT = {} +""" ServoDyn """ +ServoDyn = {} + +# Airfoil control +ServoDyn['BlAirFlC1'] = False # (-); Blade 1 airfoil control command; Same units as provided in airfoil tables of AD15 (UserProp) +ServoDyn['BlFlap1'] = False # (-); Blade 1 airfoil control command; Same units as provided in airfoil tables of AD15 (UserProp) +ServoDyn['BlAirFlC2'] = False # (-); Blade 2 airfoil control command; Same units as provided in airfoil tables of AD15 (UserProp) +ServoDyn['BlFlap2'] = False # (-); Blade 2 airfoil control command; Same units as provided in airfoil tables of AD15 (UserProp) +ServoDyn['BlAirFlC3'] = False # (-); Blade 3 airfoil control command; Same units as provided in airfoil tables of AD15 (UserProp) +ServoDyn['BlFlap3'] = False # (-); Blade 3 airfoil control command; Same units as provided in airfoil tables of AD15 (UserProp) + +# Pitch Control +ServoDyn['BlPitchC1'] = False # (deg); Blade 1 pitch angle command; Positive towards feather about the minus zc1- and minus zb1-axes +ServoDyn['BlPitchC2'] = False # (deg); Blade 2 pitch angle command; Positive towards feather about the minus zc2- and minus zb2-axes +ServoDyn['BlPitchC3'] = False # (deg); Blade 3 pitch angle command; Positive towards feather about the minus zc3- and minus zb3-axes + +# Generator and Torque Control +ServoDyn['GenTq'] = False # (kN-m); Electrical generator torque; Positive reflects power extracted and negative represents a motoring-up situation (power input) +ServoDyn['GenPwr'] = False # (kW); Electrical generator power; Same sign as GenTq + +# High Speed Shaft Brake +ServoDyn['HSSBrTqC'] = False # (kN-m); High-speed shaft brake torque command (i.e., the commanded moment applied to the high-speed shaft by the brake); Always positive (indicating dissipation of power) + +# Nacelle Yaw Control +ServoDyn['YawMomCom'] = False # (kN-m); Nacelle yaw moment command; About the zl- and zp-axes +ServoDyn['YawMom'] = False # (kN-m); Nacelle yaw moment command; About the zl- and zp-axes + +# Nacelle Structural Control (StC) +ServoDyn['NStC1_XQ'] = False # (m); Nacelle StC #1 -- X position (displacement); Relative to rest position in StC reference frame +ServoDyn['NStC1_XQD'] = False # (m/s); Nacelle StC #1 -- X velocity; Relative to nacelle in StC reference frame +ServoDyn['NStC1_YQ'] = False # (m); Nacelle StC #1 -- Y position (displacement); Relative to rest position in StC reference frame +ServoDyn['NStC1_YQD'] = False # (m/s); Nacelle StC #1 -- Y velocity; Relative to nacelle in StC reference frame +ServoDyn['NStC1_ZQ'] = False # (m); Nacelle StC #1 -- Z position (displacement); Relative to rest position in StC reference frame +ServoDyn['NStC1_ZQD'] = False # (m/s); Nacelle StC #1 -- Z velocity; Relative to nacelle in StC reference frame +ServoDyn['NStC1_Fxi'] = False # (kN); Nacelle StC #1 -- X resulting force; Inertial (global) coordinates +ServoDyn['NStC1_Fyi'] = False # (kN); Nacelle StC #1 -- Y resulting force; Inertial (global) coordinates +ServoDyn['NStC1_Fzi'] = False # (kN); Nacelle StC #1 -- Z resulting force; Inertial (global) coordinates +ServoDyn['NStC1_Mxi'] = False # (kN-m); Nacelle StC #1 -- X resulting moment; Inertial (global) coordinates +ServoDyn['NStC1_Myi'] = False # (kN-m); Nacelle StC #1 -- Y resulting moment; Inertial (global) coordinates +ServoDyn['NStC1_Mzi'] = False # (kN-m); Nacelle StC #1 -- Z resulting moment; Inertial (global) coordinates +ServoDyn['NStC1_Fxl'] = False # (kN); Nacelle StC #1 -- X resulting force; Local StC coordinates +ServoDyn['NStC1_Fyl'] = False # (kN); Nacelle StC #1 -- Y resulting force; Local StC coordinates +ServoDyn['NStC1_Fzl'] = False # (kN); Nacelle StC #1 -- Z resulting force; Local StC coordinates +ServoDyn['NStC1_Mxl'] = False # (kN-m); Nacelle StC #1 -- X resulting moment; Local StC coordinates +ServoDyn['NStC1_Myl'] = False # (kN-m); Nacelle StC #1 -- Y resulting moment; Local StC coordinates +ServoDyn['NStC1_Mzl'] = False # (kN-m); Nacelle StC #1 -- Z resulting moment; Local StC coordinates +ServoDyn['NStC2_XQ'] = False # (m); Nacelle StC #2 -- X position (displacement); Relative to rest position in StC reference frame +ServoDyn['NStC2_XQD'] = False # (m/s); Nacelle StC #2 -- X velocity; Relative to nacelle in StC reference frame +ServoDyn['NStC2_YQ'] = False # (m); Nacelle StC #2 -- Y position (displacement); Relative to rest position in StC reference frame +ServoDyn['NStC2_YQD'] = False # (m/s); Nacelle StC #2 -- Y velocity; Relative to nacelle in StC reference frame +ServoDyn['NStC2_ZQ'] = False # (m); Nacelle StC #2 -- Z position (displacement); Relative to rest position in StC reference frame +ServoDyn['NStC2_ZQD'] = False # (m/s); Nacelle StC #2 -- Z velocity; Relative to nacelle in StC reference frame +ServoDyn['NStC2_Fxi'] = False # (kN); Nacelle StC #2 -- X resulting force; Inertial (global) coordinates +ServoDyn['NStC2_Fyi'] = False # (kN); Nacelle StC #2 -- Y resulting force; Inertial (global) coordinates +ServoDyn['NStC2_Fzi'] = False # (kN); Nacelle StC #2 -- Z resulting force; Inertial (global) coordinates +ServoDyn['NStC2_Mxi'] = False # (kN-m); Nacelle StC #2 -- X resulting moment; Inertial (global) coordinates +ServoDyn['NStC2_Myi'] = False # (kN-m); Nacelle StC #2 -- Y resulting moment; Inertial (global) coordinates +ServoDyn['NStC2_Mzi'] = False # (kN-m); Nacelle StC #2 -- Z resulting moment; Inertial (global) coordinates +ServoDyn['NStC2_Fxl'] = False # (kN); Nacelle StC #2 -- X resulting force; Local StC coordinates +ServoDyn['NStC2_Fyl'] = False # (kN); Nacelle StC #2 -- Y resulting force; Local StC coordinates +ServoDyn['NStC2_Fzl'] = False # (kN); Nacelle StC #2 -- Z resulting force; Local StC coordinates +ServoDyn['NStC2_Mxl'] = False # (kN-m); Nacelle StC #2 -- X resulting moment; Local StC coordinates +ServoDyn['NStC2_Myl'] = False # (kN-m); Nacelle StC #2 -- Y resulting moment; Local StC coordinates +ServoDyn['NStC2_Mzl'] = False # (kN-m); Nacelle StC #2 -- Z resulting moment; Local StC coordinates +ServoDyn['NStC3_XQ'] = False # (m); Nacelle StC #3 -- X position (displacement); Relative to rest position in StC reference frame +ServoDyn['NStC3_XQD'] = False # (m/s); Nacelle StC #3 -- X velocity; Relative to nacelle in StC reference frame +ServoDyn['NStC3_YQ'] = False # (m); Nacelle StC #3 -- Y position (displacement); Relative to rest position in StC reference frame +ServoDyn['NStC3_YQD'] = False # (m/s); Nacelle StC #3 -- Y velocity; Relative to nacelle in StC reference frame +ServoDyn['NStC3_ZQ'] = False # (m); Nacelle StC #3 -- Z position (displacement); Relative to rest position in StC reference frame +ServoDyn['NStC3_ZQD'] = False # (m/s); Nacelle StC #3 -- Z velocity; Relative to nacelle in StC reference frame +ServoDyn['NStC3_Fxi'] = False # (kN); Nacelle StC #3 -- X resulting force; Inertial (global) coordinates +ServoDyn['NStC3_Fyi'] = False # (kN); Nacelle StC #3 -- Y resulting force; Inertial (global) coordinates +ServoDyn['NStC3_Fzi'] = False # (kN); Nacelle StC #3 -- Z resulting force; Inertial (global) coordinates +ServoDyn['NStC3_Mxi'] = False # (kN-m); Nacelle StC #3 -- X resulting moment; Inertial (global) coordinates +ServoDyn['NStC3_Myi'] = False # (kN-m); Nacelle StC #3 -- Y resulting moment; Inertial (global) coordinates +ServoDyn['NStC3_Mzi'] = False # (kN-m); Nacelle StC #3 -- Z resulting moment; Inertial (global) coordinates +ServoDyn['NStC3_Fxl'] = False # (kN); Nacelle StC #3 -- X resulting force; Local StC coordinates +ServoDyn['NStC3_Fyl'] = False # (kN); Nacelle StC #3 -- Y resulting force; Local StC coordinates +ServoDyn['NStC3_Fzl'] = False # (kN); Nacelle StC #3 -- Z resulting force; Local StC coordinates +ServoDyn['NStC3_Mxl'] = False # (kN-m); Nacelle StC #3 -- X resulting moment; Local StC coordinates +ServoDyn['NStC3_Myl'] = False # (kN-m); Nacelle StC #3 -- Y resulting moment; Local StC coordinates +ServoDyn['NStC3_Mzl'] = False # (kN-m); Nacelle StC #3 -- Z resulting moment; Local StC coordinates +ServoDyn['NStC4_XQ'] = False # (m); Nacelle StC #4 -- X position (displacement); Relative to rest position in StC reference frame +ServoDyn['NStC4_XQD'] = False # (m/s); Nacelle StC #4 -- X velocity; Relative to nacelle in StC reference frame +ServoDyn['NStC4_YQ'] = False # (m); Nacelle StC #4 -- Y position (displacement); Relative to rest position in StC reference frame +ServoDyn['NStC4_YQD'] = False # (m/s); Nacelle StC #4 -- Y velocity; Relative to nacelle in StC reference frame +ServoDyn['NStC4_ZQ'] = False # (m); Nacelle StC #4 -- Z position (displacement); Relative to rest position in StC reference frame +ServoDyn['NStC4_ZQD'] = False # (m/s); Nacelle StC #4 -- Z velocity; Relative to nacelle in StC reference frame +ServoDyn['NStC4_Fxi'] = False # (kN); Nacelle StC #4 -- X resulting force; Inertial (global) coordinates +ServoDyn['NStC4_Fyi'] = False # (kN); Nacelle StC #4 -- Y resulting force; Inertial (global) coordinates +ServoDyn['NStC4_Fzi'] = False # (kN); Nacelle StC #4 -- Z resulting force; Inertial (global) coordinates +ServoDyn['NStC4_Mxi'] = False # (kN-m); Nacelle StC #4 -- X resulting moment; Inertial (global) coordinates +ServoDyn['NStC4_Myi'] = False # (kN-m); Nacelle StC #4 -- Y resulting moment; Inertial (global) coordinates +ServoDyn['NStC4_Mzi'] = False # (kN-m); Nacelle StC #4 -- Z resulting moment; Inertial (global) coordinates +ServoDyn['NStC4_Fxl'] = False # (kN); Nacelle StC #4 -- X resulting force; Local StC coordinates +ServoDyn['NStC4_Fyl'] = False # (kN); Nacelle StC #4 -- Y resulting force; Local StC coordinates +ServoDyn['NStC4_Fzl'] = False # (kN); Nacelle StC #4 -- Z resulting force; Local StC coordinates +ServoDyn['NStC4_Mxl'] = False # (kN-m); Nacelle StC #4 -- X resulting moment; Local StC coordinates +ServoDyn['NStC4_Myl'] = False # (kN-m); Nacelle StC #4 -- Y resulting moment; Local StC coordinates +ServoDyn['NStC4_Mzl'] = False # (kN-m); Nacelle StC #4 -- Z resulting moment; Local StC coordinates + +# Tower Structural Control (StC) +ServoDyn['TStC1_XQ'] = False # (m); Tower StC #1 -- X position (displacement); Relative to rest position in StC reference frame +ServoDyn['TStC1_XQD'] = False # (m/s); Tower StC #1 -- X velocity; Relative to nacelle in StC reference frame +ServoDyn['TStC1_YQ'] = False # (m); Tower StC #1 -- Y position (displacement); Relative to rest position in StC reference frame +ServoDyn['TStC1_YQD'] = False # (m/s); Tower StC #1 -- Y velocity; Relative to nacelle in StC reference frame +ServoDyn['TStC1_ZQ'] = False # (m); Tower StC #1 -- Z position (displacement); Relative to rest position in StC reference frame +ServoDyn['TStC1_ZQD'] = False # (m/s); Tower StC #1 -- Z velocity; Relative to nacelle in StC reference frame +ServoDyn['TStC1_Fxi'] = False # (kN); Tower StC #1 -- X resulting force; Inertial (global) coordinates +ServoDyn['TStC1_Fyi'] = False # (kN); Tower StC #1 -- Y resulting force; Inertial (global) coordinates +ServoDyn['TStC1_Fzi'] = False # (kN); Tower StC #1 -- Z resulting force; Inertial (global) coordinates +ServoDyn['TStC1_Mxi'] = False # (kN-m); Tower StC #1 -- X resulting moment; Inertial (global) coordinates +ServoDyn['TStC1_Myi'] = False # (kN-m); Tower StC #1 -- Y resulting moment; Inertial (global) coordinates +ServoDyn['TStC1_Mzi'] = False # (kN-m); Tower StC #1 -- Z resulting moment; Inertial (global) coordinates +ServoDyn['TStC1_Fxl'] = False # (kN); Tower StC #1 -- X resulting force; Local StC coordinates +ServoDyn['TStC1_Fyl'] = False # (kN); Tower StC #1 -- Y resulting force; Local StC coordinates +ServoDyn['TStC1_Fzl'] = False # (kN); Tower StC #1 -- Z resulting force; Local StC coordinates +ServoDyn['TStC1_Mxl'] = False # (kN-m); Tower StC #1 -- X resulting moment; Local StC coordinates +ServoDyn['TStC1_Myl'] = False # (kN-m); Tower StC #1 -- Y resulting moment; Local StC coordinates +ServoDyn['TStC1_Mzl'] = False # (kN-m); Tower StC #1 -- Z resulting moment; Local StC coordinates +ServoDyn['TStC2_XQ'] = False # (m); Tower StC #2 -- X position (displacement); Relative to rest position in StC reference frame +ServoDyn['TStC2_XQD'] = False # (m/s); Tower StC #2 -- X velocity; Relative to nacelle in StC reference frame +ServoDyn['TStC2_YQ'] = False # (m); Tower StC #2 -- Y position (displacement); Relative to rest position in StC reference frame +ServoDyn['TStC2_YQD'] = False # (m/s); Tower StC #2 -- Y velocity; Relative to nacelle in StC reference frame +ServoDyn['TStC2_ZQ'] = False # (m); Tower StC #2 -- Z position (displacement); Relative to rest position in StC reference frame +ServoDyn['TStC2_ZQD'] = False # (m/s); Tower StC #2 -- Z velocity; Relative to nacelle in StC reference frame +ServoDyn['TStC2_Fxi'] = False # (kN); Tower StC #2 -- X resulting force; Inertial (global) coordinates +ServoDyn['TStC2_Fyi'] = False # (kN); Tower StC #2 -- Y resulting force; Inertial (global) coordinates +ServoDyn['TStC2_Fzi'] = False # (kN); Tower StC #2 -- Z resulting force; Inertial (global) coordinates +ServoDyn['TStC2_Mxi'] = False # (kN-m); Tower StC #2 -- X resulting moment; Inertial (global) coordinates +ServoDyn['TStC2_Myi'] = False # (kN-m); Tower StC #2 -- Y resulting moment; Inertial (global) coordinates +ServoDyn['TStC2_Mzi'] = False # (kN-m); Tower StC #2 -- Z resulting moment; Inertial (global) coordinates +ServoDyn['TStC2_Fxl'] = False # (kN); Tower StC #2 -- X resulting force; Local StC coordinates +ServoDyn['TStC2_Fyl'] = False # (kN); Tower StC #2 -- Y resulting force; Local StC coordinates +ServoDyn['TStC2_Fzl'] = False # (kN); Tower StC #2 -- Z resulting force; Local StC coordinates +ServoDyn['TStC2_Mxl'] = False # (kN-m); Tower StC #2 -- X resulting moment; Local StC coordinates +ServoDyn['TStC2_Myl'] = False # (kN-m); Tower StC #2 -- Y resulting moment; Local StC coordinates +ServoDyn['TStC2_Mzl'] = False # (kN-m); Tower StC #2 -- Z resulting moment; Local StC coordinates +ServoDyn['TStC3_XQ'] = False # (m); Tower StC #3 -- X position (displacement); Relative to rest position in StC reference frame +ServoDyn['TStC3_XQD'] = False # (m/s); Tower StC #3 -- X velocity; Relative to nacelle in StC reference frame +ServoDyn['TStC3_YQ'] = False # (m); Tower StC #3 -- Y position (displacement); Relative to rest position in StC reference frame +ServoDyn['TStC3_YQD'] = False # (m/s); Tower StC #3 -- Y velocity; Relative to nacelle in StC reference frame +ServoDyn['TStC3_ZQ'] = False # (m); Tower StC #3 -- Z position (displacement); Relative to rest position in StC reference frame +ServoDyn['TStC3_ZQD'] = False # (m/s); Tower StC #3 -- Z velocity; Relative to nacelle in StC reference frame +ServoDyn['TStC3_Fxi'] = False # (kN); Tower StC #3 -- X resulting force; Inertial (global) coordinates +ServoDyn['TStC3_Fyi'] = False # (kN); Tower StC #3 -- Y resulting force; Inertial (global) coordinates +ServoDyn['TStC3_Fzi'] = False # (kN); Tower StC #3 -- Z resulting force; Inertial (global) coordinates +ServoDyn['TStC3_Mxi'] = False # (kN-m); Tower StC #3 -- X resulting moment; Inertial (global) coordinates +ServoDyn['TStC3_Myi'] = False # (kN-m); Tower StC #3 -- Y resulting moment; Inertial (global) coordinates +ServoDyn['TStC3_Mzi'] = False # (kN-m); Tower StC #3 -- Z resulting moment; Inertial (global) coordinates +ServoDyn['TStC3_Fxl'] = False # (kN); Tower StC #3 -- X resulting force; Local StC coordinates +ServoDyn['TStC3_Fyl'] = False # (kN); Tower StC #3 -- Y resulting force; Local StC coordinates +ServoDyn['TStC3_Fzl'] = False # (kN); Tower StC #3 -- Z resulting force; Local StC coordinates +ServoDyn['TStC3_Mxl'] = False # (kN-m); Tower StC #3 -- X resulting moment; Local StC coordinates +ServoDyn['TStC3_Myl'] = False # (kN-m); Tower StC #3 -- Y resulting moment; Local StC coordinates +ServoDyn['TStC3_Mzl'] = False # (kN-m); Tower StC #3 -- Z resulting moment; Local StC coordinates +ServoDyn['TStC4_XQ'] = False # (m); Tower StC #4 -- X position (displacement); Relative to rest position in StC reference frame +ServoDyn['TStC4_XQD'] = False # (m/s); Tower StC #4 -- X velocity; Relative to nacelle in StC reference frame +ServoDyn['TStC4_YQ'] = False # (m); Tower StC #4 -- Y position (displacement); Relative to rest position in StC reference frame +ServoDyn['TStC4_YQD'] = False # (m/s); Tower StC #4 -- Y velocity; Relative to nacelle in StC reference frame +ServoDyn['TStC4_ZQ'] = False # (m); Tower StC #4 -- Z position (displacement); Relative to rest position in StC reference frame +ServoDyn['TStC4_ZQD'] = False # (m/s); Tower StC #4 -- Z velocity; Relative to nacelle in StC reference frame +ServoDyn['TStC4_Fxi'] = False # (kN); Tower StC #4 -- X resulting force; Inertial (global) coordinates +ServoDyn['TStC4_Fyi'] = False # (kN); Tower StC #4 -- Y resulting force; Inertial (global) coordinates +ServoDyn['TStC4_Fzi'] = False # (kN); Tower StC #4 -- Z resulting force; Inertial (global) coordinates +ServoDyn['TStC4_Mxi'] = False # (kN-m); Tower StC #4 -- X resulting moment; Inertial (global) coordinates +ServoDyn['TStC4_Myi'] = False # (kN-m); Tower StC #4 -- Y resulting moment; Inertial (global) coordinates +ServoDyn['TStC4_Mzi'] = False # (kN-m); Tower StC #4 -- Z resulting moment; Inertial (global) coordinates +ServoDyn['TStC4_Fxl'] = False # (kN); Tower StC #4 -- X resulting force; Local StC coordinates +ServoDyn['TStC4_Fyl'] = False # (kN); Tower StC #4 -- Y resulting force; Local StC coordinates +ServoDyn['TStC4_Fzl'] = False # (kN); Tower StC #4 -- Z resulting force; Local StC coordinates +ServoDyn['TStC4_Mxl'] = False # (kN-m); Tower StC #4 -- X resulting moment; Local StC coordinates +ServoDyn['TStC4_Myl'] = False # (kN-m); Tower StC #4 -- Y resulting moment; Local StC coordinates +ServoDyn['TStC4_Mzl'] = False # (kN-m); Tower StC #4 -- Z resulting moment; Local StC coordinates -# WAMIT Body Forces -WAMIT['Wave1El2'] = False # (m); 2nd order wave elevation correction; -WAMIT['Wave2El2'] = False # (m); 2nd order wave elevation correction; -WAMIT['Wave3El2'] = False # (m); 2nd order wave elevation correction; -WAMIT['Wave4El2'] = False # (m); 2nd order wave elevation correction; -WAMIT['Wave5El2'] = False # (m); 2nd order wave elevation correction; -WAMIT['Wave6El2'] = False # (m); 2nd order wave elevation correction; -WAMIT['Wave7El2'] = False # (m); 2nd order wave elevation correction; -WAMIT['Wave8El2'] = False # (m); 2nd order wave elevation correction; -WAMIT['Wave9El2'] = False # (m); 2nd order wave elevation correction; +# Blade Structural Control (StC) +ServoDyn['BStC1_B1_XQ'] = False # (m); Blade StC #1 Blade #1 -- X position (displacement); Relative to rest position in StC reference frame +ServoDyn['BStC1_B1_XQD'] = False # (m/s); Blade StC #1 Blade #1 -- X velocity; Relative to nacelle in StC reference frame +ServoDyn['BStC1_B1_YQ'] = False # (m); Blade StC #1 Blade #1 -- Y position (displacement); Relative to rest position in StC reference frame +ServoDyn['BStC1_B1_YQD'] = False # (m/s); Blade StC #1 Blade #1 -- Y velocity; Relative to nacelle in StC reference frame +ServoDyn['BStC1_B1_ZQ'] = False # (m); Blade StC #1 Blade #1 -- Z position (displacement); Relative to rest position in StC reference frame +ServoDyn['BStC1_B1_ZQD'] = False # (m/s); Blade StC #1 Blade #1 -- Z velocity; Relative to nacelle in StC reference frame +ServoDyn['BStC1_B1_Fxi'] = False # (kN); Blade StC #1 Blade #1 -- X resulting force; Inertial (global) coordinates +ServoDyn['BStC1_B1_Fyi'] = False # (kN); Blade StC #1 Blade #1 -- Y resulting force; Inertial (global) coordinates +ServoDyn['BStC1_B1_Fzi'] = False # (kN); Blade StC #1 Blade #1 -- Z resulting force; Inertial (global) coordinates +ServoDyn['BStC1_B1_Mxi'] = False # (kN-m); Blade StC #1 Blade #1 -- X resulting moment; Inertial (global) coordinates +ServoDyn['BStC1_B1_Myi'] = False # (kN-m); Blade StC #1 Blade #1 -- Y resulting moment; Inertial (global) coordinates +ServoDyn['BStC1_B1_Mzi'] = False # (kN-m); Blade StC #1 Blade #1 -- Z resulting moment; Inertial (global) coordinates +ServoDyn['BStC1_B1_Fxl'] = False # (kN); Blade StC #1 Blade #1 -- X resulting force; Local StC coordinates +ServoDyn['BStC1_B1_Fyl'] = False # (kN); Blade StC #1 Blade #1 -- Y resulting force; Local StC coordinates +ServoDyn['BStC1_B1_Fzl'] = False # (kN); Blade StC #1 Blade #1 -- Z resulting force; Local StC coordinates +ServoDyn['BStC1_B1_Mxl'] = False # (kN-m); Blade StC #1 Blade #1 -- X resulting moment; Local StC coordinates +ServoDyn['BStC1_B1_Myl'] = False # (kN-m); Blade StC #1 Blade #1 -- Y resulting moment; Local StC coordinates +ServoDyn['BStC1_B1_Mzl'] = False # (kN-m); Blade StC #1 Blade #1 -- Z resulting moment; Local StC coordinates +ServoDyn['BStC2_B1_XQ'] = False # (m); Blade StC #2 Blade #1 -- X position (displacement); Relative to rest position in StC reference frame +ServoDyn['BStC2_B1_XQD'] = False # (m/s); Blade StC #2 Blade #1 -- X velocity; Relative to nacelle in StC reference frame +ServoDyn['BStC2_B1_YQ'] = False # (m); Blade StC #2 Blade #1 -- Y position (displacement); Relative to rest position in StC reference frame +ServoDyn['BStC2_B1_YQD'] = False # (m/s); Blade StC #2 Blade #1 -- Y velocity; Relative to nacelle in StC reference frame +ServoDyn['BStC2_B1_ZQ'] = False # (m); Blade StC #2 Blade #1 -- Z position (displacement); Relative to rest position in StC reference frame +ServoDyn['BStC2_B1_ZQD'] = False # (m/s); Blade StC #2 Blade #1 -- Z velocity; Relative to nacelle in StC reference frame +ServoDyn['BStC2_B1_Fxi'] = False # (kN); Blade StC #2 Blade #1 -- X resulting force; Inertial (global) coordinates +ServoDyn['BStC2_B1_Fyi'] = False # (kN); Blade StC #2 Blade #1 -- Y resulting force; Inertial (global) coordinates +ServoDyn['BStC2_B1_Fzi'] = False # (kN); Blade StC #2 Blade #1 -- Z resulting force; Inertial (global) coordinates +ServoDyn['BStC2_B1_Mxi'] = False # (kN-m); Blade StC #2 Blade #1 -- X resulting moment; Inertial (global) coordinates +ServoDyn['BStC2_B1_Myi'] = False # (kN-m); Blade StC #2 Blade #1 -- Y resulting moment; Inertial (global) coordinates +ServoDyn['BStC2_B1_Mzi'] = False # (kN-m); Blade StC #2 Blade #1 -- Z resulting moment; Inertial (global) coordinates +ServoDyn['BStC2_B1_Fxl'] = False # (kN); Blade StC #2 Blade #1 -- X resulting force; Local StC coordinates +ServoDyn['BStC2_B1_Fyl'] = False # (kN); Blade StC #2 Blade #1 -- Y resulting force; Local StC coordinates +ServoDyn['BStC2_B1_Fzl'] = False # (kN); Blade StC #2 Blade #1 -- Z resulting force; Local StC coordinates +ServoDyn['BStC2_B1_Mxl'] = False # (kN-m); Blade StC #2 Blade #1 -- X resulting moment; Local StC coordinates +ServoDyn['BStC2_B1_Myl'] = False # (kN-m); Blade StC #2 Blade #1 -- Y resulting moment; Local StC coordinates +ServoDyn['BStC2_B1_Mzl'] = False # (kN-m); Blade StC #2 Blade #1 -- Z resulting moment; Local StC coordinates +ServoDyn['BStC3_B1_XQ'] = False # (m); Blade StC #3 Blade #1 -- X position (displacement); Relative to rest position in StC reference frame +ServoDyn['BStC3_B1_XQD'] = False # (m/s); Blade StC #3 Blade #1 -- X velocity; Relative to nacelle in StC reference frame +ServoDyn['BStC3_B1_YQ'] = False # (m); Blade StC #3 Blade #1 -- Y position (displacement); Relative to rest position in StC reference frame +ServoDyn['BStC3_B1_YQD'] = False # (m/s); Blade StC #3 Blade #1 -- Y velocity; Relative to nacelle in StC reference frame +ServoDyn['BStC3_B1_ZQ'] = False # (m); Blade StC #3 Blade #1 -- Z position (displacement); Relative to rest position in StC reference frame +ServoDyn['BStC3_B1_ZQD'] = False # (m/s); Blade StC #3 Blade #1 -- Z velocity; Relative to nacelle in StC reference frame +ServoDyn['BStC3_B1_Fxi'] = False # (kN); Blade StC #3 Blade #1 -- X resulting force; Inertial (global) coordinates +ServoDyn['BStC3_B1_Fyi'] = False # (kN); Blade StC #3 Blade #1 -- Y resulting force; Inertial (global) coordinates +ServoDyn['BStC3_B1_Fzi'] = False # (kN); Blade StC #3 Blade #1 -- Z resulting force; Inertial (global) coordinates +ServoDyn['BStC3_B1_Mxi'] = False # (kN-m); Blade StC #3 Blade #1 -- X resulting moment; Inertial (global) coordinates +ServoDyn['BStC3_B1_Myi'] = False # (kN-m); Blade StC #3 Blade #1 -- Y resulting moment; Inertial (global) coordinates +ServoDyn['BStC3_B1_Mzi'] = False # (kN-m); Blade StC #3 Blade #1 -- Z resulting moment; Inertial (global) coordinates +ServoDyn['BStC3_B1_Fxl'] = False # (kN); Blade StC #3 Blade #1 -- X resulting force; Local StC coordinates +ServoDyn['BStC3_B1_Fyl'] = False # (kN); Blade StC #3 Blade #1 -- Y resulting force; Local StC coordinates +ServoDyn['BStC3_B1_Fzl'] = False # (kN); Blade StC #3 Blade #1 -- Z resulting force; Local StC coordinates +ServoDyn['BStC3_B1_Mxl'] = False # (kN-m); Blade StC #3 Blade #1 -- X resulting moment; Local StC coordinates +ServoDyn['BStC3_B1_Myl'] = False # (kN-m); Blade StC #3 Blade #1 -- Y resulting moment; Local StC coordinates +ServoDyn['BStC3_B1_Mzl'] = False # (kN-m); Blade StC #3 Blade #1 -- Z resulting moment; Local StC coordinates +ServoDyn['BStC4_B1_XQ'] = False # (m); Blade StC #4 Blade #1 -- X position (displacement); Relative to rest position in StC reference frame +ServoDyn['BStC4_B1_XQD'] = False # (m/s); Blade StC #4 Blade #1 -- X velocity; Relative to nacelle in StC reference frame +ServoDyn['BStC4_B1_YQ'] = False # (m); Blade StC #4 Blade #1 -- Y position (displacement); Relative to rest position in StC reference frame +ServoDyn['BStC4_B1_YQD'] = False # (m/s); Blade StC #4 Blade #1 -- Y velocity; Relative to nacelle in StC reference frame +ServoDyn['BStC4_B1_ZQ'] = False # (m); Blade StC #4 Blade #1 -- Z position (displacement); Relative to rest position in StC reference frame +ServoDyn['BStC4_B1_ZQD'] = False # (m/s); Blade StC #4 Blade #1 -- Z velocity; Relative to nacelle in StC reference frame +ServoDyn['BStC4_B1_Fxi'] = False # (kN); Blade StC #4 Blade #1 -- X resulting force; Inertial (global) coordinates +ServoDyn['BStC4_B1_Fyi'] = False # (kN); Blade StC #4 Blade #1 -- Y resulting force; Inertial (global) coordinates +ServoDyn['BStC4_B1_Fzi'] = False # (kN); Blade StC #4 Blade #1 -- Z resulting force; Inertial (global) coordinates +ServoDyn['BStC4_B1_Mxi'] = False # (kN-m); Blade StC #4 Blade #1 -- X resulting moment; Inertial (global) coordinates +ServoDyn['BStC4_B1_Myi'] = False # (kN-m); Blade StC #4 Blade #1 -- Y resulting moment; Inertial (global) coordinates +ServoDyn['BStC4_B1_Mzi'] = False # (kN-m); Blade StC #4 Blade #1 -- Z resulting moment; Inertial (global) coordinates +ServoDyn['BStC4_B1_Fxl'] = False # (kN); Blade StC #4 Blade #1 -- X resulting force; Local StC coordinates +ServoDyn['BStC4_B1_Fyl'] = False # (kN); Blade StC #4 Blade #1 -- Y resulting force; Local StC coordinates +ServoDyn['BStC4_B1_Fzl'] = False # (kN); Blade StC #4 Blade #1 -- Z resulting force; Local StC coordinates +ServoDyn['BStC4_B1_Mxl'] = False # (kN-m); Blade StC #4 Blade #1 -- X resulting moment; Local StC coordinates +ServoDyn['BStC4_B1_Myl'] = False # (kN-m); Blade StC #4 Blade #1 -- Y resulting moment; Local StC coordinates +ServoDyn['BStC4_B1_Mzl'] = False # (kN-m); Blade StC #4 Blade #1 -- Z resulting moment; Local StC coordinates +ServoDyn['BStC1_B2_XQ'] = False # (m); Blade StC #1 Blade #2 -- X position (displacement); Relative to rest position in StC reference frame +ServoDyn['BStC1_B2_XQD'] = False # (m/s); Blade StC #1 Blade #2 -- X velocity; Relative to nacelle in StC reference frame +ServoDyn['BStC1_B2_YQ'] = False # (m); Blade StC #1 Blade #2 -- Y position (displacement); Relative to rest position in StC reference frame +ServoDyn['BStC1_B2_YQD'] = False # (m/s); Blade StC #1 Blade #2 -- Y velocity; Relative to nacelle in StC reference frame +ServoDyn['BStC1_B2_ZQ'] = False # (m); Blade StC #1 Blade #2 -- Z position (displacement); Relative to rest position in StC reference frame +ServoDyn['BStC1_B2_ZQD'] = False # (m/s); Blade StC #1 Blade #2 -- Z velocity; Relative to nacelle in StC reference frame +ServoDyn['BStC1_B2_Fxi'] = False # (kN); Blade StC #1 Blade #2 -- X resulting force; Inertial (global) coordinates +ServoDyn['BStC1_B2_Fyi'] = False # (kN); Blade StC #1 Blade #2 -- Y resulting force; Inertial (global) coordinates +ServoDyn['BStC1_B2_Fzi'] = False # (kN); Blade StC #1 Blade #2 -- Z resulting force; Inertial (global) coordinates +ServoDyn['BStC1_B2_Mxi'] = False # (kN-m); Blade StC #1 Blade #2 -- X resulting moment; Inertial (global) coordinates +ServoDyn['BStC1_B2_Myi'] = False # (kN-m); Blade StC #1 Blade #2 -- Y resulting moment; Inertial (global) coordinates +ServoDyn['BStC1_B2_Mzi'] = False # (kN-m); Blade StC #1 Blade #2 -- Z resulting moment; Inertial (global) coordinates +ServoDyn['BStC1_B2_Fxl'] = False # (kN); Blade StC #1 Blade #2 -- X resulting force; Local StC coordinates +ServoDyn['BStC1_B2_Fyl'] = False # (kN); Blade StC #1 Blade #2 -- Y resulting force; Local StC coordinates +ServoDyn['BStC1_B2_Fzl'] = False # (kN); Blade StC #1 Blade #2 -- Z resulting force; Local StC coordinates +ServoDyn['BStC1_B2_Mxl'] = False # (kN-m); Blade StC #1 Blade #2 -- X resulting moment; Local StC coordinates +ServoDyn['BStC1_B2_Myl'] = False # (kN-m); Blade StC #1 Blade #2 -- Y resulting moment; Local StC coordinates +ServoDyn['BStC1_B2_Mzl'] = False # (kN-m); Blade StC #1 Blade #2 -- Z resulting moment; Local StC coordinates +ServoDyn['BStC2_B2_XQ'] = False # (m); Blade StC #2 Blade #2 -- X position (displacement); Relative to rest position in StC reference frame +ServoDyn['BStC2_B2_XQD'] = False # (m/s); Blade StC #2 Blade #2 -- X velocity; Relative to nacelle in StC reference frame +ServoDyn['BStC2_B2_YQ'] = False # (m); Blade StC #2 Blade #2 -- Y position (displacement); Relative to rest position in StC reference frame +ServoDyn['BStC2_B2_YQD'] = False # (m/s); Blade StC #2 Blade #2 -- Y velocity; Relative to nacelle in StC reference frame +ServoDyn['BStC2_B2_ZQ'] = False # (m); Blade StC #2 Blade #2 -- Z position (displacement); Relative to rest position in StC reference frame +ServoDyn['BStC2_B2_ZQD'] = False # (m/s); Blade StC #2 Blade #2 -- Z velocity; Relative to nacelle in StC reference frame +ServoDyn['BStC2_B2_Fxi'] = False # (kN); Blade StC #2 Blade #2 -- X resulting force; Inertial (global) coordinates +ServoDyn['BStC2_B2_Fyi'] = False # (kN); Blade StC #2 Blade #2 -- Y resulting force; Inertial (global) coordinates +ServoDyn['BStC2_B2_Fzi'] = False # (kN); Blade StC #2 Blade #2 -- Z resulting force; Inertial (global) coordinates +ServoDyn['BStC2_B2_Mxi'] = False # (kN-m); Blade StC #2 Blade #2 -- X resulting moment; Inertial (global) coordinates +ServoDyn['BStC2_B2_Myi'] = False # (kN-m); Blade StC #2 Blade #2 -- Y resulting moment; Inertial (global) coordinates +ServoDyn['BStC2_B2_Mzi'] = False # (kN-m); Blade StC #2 Blade #2 -- Z resulting moment; Inertial (global) coordinates +ServoDyn['BStC2_B2_Fxl'] = False # (kN); Blade StC #2 Blade #2 -- X resulting force; Local StC coordinates +ServoDyn['BStC2_B2_Fyl'] = False # (kN); Blade StC #2 Blade #2 -- Y resulting force; Local StC coordinates +ServoDyn['BStC2_B2_Fzl'] = False # (kN); Blade StC #2 Blade #2 -- Z resulting force; Local StC coordinates +ServoDyn['BStC2_B2_Mxl'] = False # (kN-m); Blade StC #2 Blade #2 -- X resulting moment; Local StC coordinates +ServoDyn['BStC2_B2_Myl'] = False # (kN-m); Blade StC #2 Blade #2 -- Y resulting moment; Local StC coordinates +ServoDyn['BStC2_B2_Mzl'] = False # (kN-m); Blade StC #2 Blade #2 -- Z resulting moment; Local StC coordinates +ServoDyn['BStC3_B2_XQ'] = False # (m); Blade StC #3 Blade #2 -- X position (displacement); Relative to rest position in StC reference frame +ServoDyn['BStC3_B2_XQD'] = False # (m/s); Blade StC #3 Blade #2 -- X velocity; Relative to nacelle in StC reference frame +ServoDyn['BStC3_B2_YQ'] = False # (m); Blade StC #3 Blade #2 -- Y position (displacement); Relative to rest position in StC reference frame +ServoDyn['BStC3_B2_YQD'] = False # (m/s); Blade StC #3 Blade #2 -- Y velocity; Relative to nacelle in StC reference frame +ServoDyn['BStC3_B2_ZQ'] = False # (m); Blade StC #3 Blade #2 -- Z position (displacement); Relative to rest position in StC reference frame +ServoDyn['BStC3_B2_ZQD'] = False # (m/s); Blade StC #3 Blade #2 -- Z velocity; Relative to nacelle in StC reference frame +ServoDyn['BStC3_B2_Fxi'] = False # (kN); Blade StC #3 Blade #2 -- X resulting force; Inertial (global) coordinates +ServoDyn['BStC3_B2_Fyi'] = False # (kN); Blade StC #3 Blade #2 -- Y resulting force; Inertial (global) coordinates +ServoDyn['BStC3_B2_Fzi'] = False # (kN); Blade StC #3 Blade #2 -- Z resulting force; Inertial (global) coordinates +ServoDyn['BStC3_B2_Mxi'] = False # (kN-m); Blade StC #3 Blade #2 -- X resulting moment; Inertial (global) coordinates +ServoDyn['BStC3_B2_Myi'] = False # (kN-m); Blade StC #3 Blade #2 -- Y resulting moment; Inertial (global) coordinates +ServoDyn['BStC3_B2_Mzi'] = False # (kN-m); Blade StC #3 Blade #2 -- Z resulting moment; Inertial (global) coordinates +ServoDyn['BStC3_B2_Fxl'] = False # (kN); Blade StC #3 Blade #2 -- X resulting force; Local StC coordinates +ServoDyn['BStC3_B2_Fyl'] = False # (kN); Blade StC #3 Blade #2 -- Y resulting force; Local StC coordinates +ServoDyn['BStC3_B2_Fzl'] = False # (kN); Blade StC #3 Blade #2 -- Z resulting force; Local StC coordinates +ServoDyn['BStC3_B2_Mxl'] = False # (kN-m); Blade StC #3 Blade #2 -- X resulting moment; Local StC coordinates +ServoDyn['BStC3_B2_Myl'] = False # (kN-m); Blade StC #3 Blade #2 -- Y resulting moment; Local StC coordinates +ServoDyn['BStC3_B2_Mzl'] = False # (kN-m); Blade StC #3 Blade #2 -- Z resulting moment; Local StC coordinates +ServoDyn['BStC4_B2_XQ'] = False # (m); Blade StC #4 Blade #2 -- X position (displacement); Relative to rest position in StC reference frame +ServoDyn['BStC4_B2_XQD'] = False # (m/s); Blade StC #4 Blade #2 -- X velocity; Relative to nacelle in StC reference frame +ServoDyn['BStC4_B2_YQ'] = False # (m); Blade StC #4 Blade #2 -- Y position (displacement); Relative to rest position in StC reference frame +ServoDyn['BStC4_B2_YQD'] = False # (m/s); Blade StC #4 Blade #2 -- Y velocity; Relative to nacelle in StC reference frame +ServoDyn['BStC4_B2_ZQ'] = False # (m); Blade StC #4 Blade #2 -- Z position (displacement); Relative to rest position in StC reference frame +ServoDyn['BStC4_B2_ZQD'] = False # (m/s); Blade StC #4 Blade #2 -- Z velocity; Relative to nacelle in StC reference frame +ServoDyn['BStC4_B2_Fxi'] = False # (kN); Blade StC #4 Blade #2 -- X resulting force; Inertial (global) coordinates +ServoDyn['BStC4_B2_Fyi'] = False # (kN); Blade StC #4 Blade #2 -- Y resulting force; Inertial (global) coordinates +ServoDyn['BStC4_B2_Fzi'] = False # (kN); Blade StC #4 Blade #2 -- Z resulting force; Inertial (global) coordinates +ServoDyn['BStC4_B2_Mxi'] = False # (kN-m); Blade StC #4 Blade #2 -- X resulting moment; Inertial (global) coordinates +ServoDyn['BStC4_B2_Myi'] = False # (kN-m); Blade StC #4 Blade #2 -- Y resulting moment; Inertial (global) coordinates +ServoDyn['BStC4_B2_Mzi'] = False # (kN-m); Blade StC #4 Blade #2 -- Z resulting moment; Inertial (global) coordinates +ServoDyn['BStC4_B2_Fxl'] = False # (kN); Blade StC #4 Blade #2 -- X resulting force; Local StC coordinates +ServoDyn['BStC4_B2_Fyl'] = False # (kN); Blade StC #4 Blade #2 -- Y resulting force; Local StC coordinates +ServoDyn['BStC4_B2_Fzl'] = False # (kN); Blade StC #4 Blade #2 -- Z resulting force; Local StC coordinates +ServoDyn['BStC4_B2_Mxl'] = False # (kN-m); Blade StC #4 Blade #2 -- X resulting moment; Local StC coordinates +ServoDyn['BStC4_B2_Myl'] = False # (kN-m); Blade StC #4 Blade #2 -- Y resulting moment; Local StC coordinates +ServoDyn['BStC4_B2_Mzl'] = False # (kN-m); Blade StC #4 Blade #2 -- Z resulting moment; Local StC coordinates +ServoDyn['BStC1_B3_XQ'] = False # (m); Blade StC #1 Blade #3 -- X position (displacement); Relative to rest position in StC reference frame +ServoDyn['BStC1_B3_XQD'] = False # (m/s); Blade StC #1 Blade #3 -- X velocity; Relative to nacelle in StC reference frame +ServoDyn['BStC1_B3_YQ'] = False # (m); Blade StC #1 Blade #3 -- Y position (displacement); Relative to rest position in StC reference frame +ServoDyn['BStC1_B3_YQD'] = False # (m/s); Blade StC #1 Blade #3 -- Y velocity; Relative to nacelle in StC reference frame +ServoDyn['BStC1_B3_ZQ'] = False # (m); Blade StC #1 Blade #3 -- Z position (displacement); Relative to rest position in StC reference frame +ServoDyn['BStC1_B3_ZQD'] = False # (m/s); Blade StC #1 Blade #3 -- Z velocity; Relative to nacelle in StC reference frame +ServoDyn['BStC1_B3_Fxi'] = False # (kN); Blade StC #1 Blade #3 -- X resulting force; Inertial (global) coordinates +ServoDyn['BStC1_B3_Fyi'] = False # (kN); Blade StC #1 Blade #3 -- Y resulting force; Inertial (global) coordinates +ServoDyn['BStC1_B3_Fzi'] = False # (kN); Blade StC #1 Blade #3 -- Z resulting force; Inertial (global) coordinates +ServoDyn['BStC1_B3_Mxi'] = False # (kN-m); Blade StC #1 Blade #3 -- X resulting moment; Inertial (global) coordinates +ServoDyn['BStC1_B3_Myi'] = False # (kN-m); Blade StC #1 Blade #3 -- Y resulting moment; Inertial (global) coordinates +ServoDyn['BStC1_B3_Mzi'] = False # (kN-m); Blade StC #1 Blade #3 -- Z resulting moment; Inertial (global) coordinates +ServoDyn['BStC1_B3_Fxl'] = False # (kN); Blade StC #1 Blade #3 -- X resulting force; Local StC coordinates +ServoDyn['BStC1_B3_Fyl'] = False # (kN); Blade StC #1 Blade #3 -- Y resulting force; Local StC coordinates +ServoDyn['BStC1_B3_Fzl'] = False # (kN); Blade StC #1 Blade #3 -- Z resulting force; Local StC coordinates +ServoDyn['BStC1_B3_Mxl'] = False # (kN-m); Blade StC #1 Blade #3 -- X resulting moment; Local StC coordinates +ServoDyn['BStC1_B3_Myl'] = False # (kN-m); Blade StC #1 Blade #3 -- Y resulting moment; Local StC coordinates +ServoDyn['BStC1_B3_Mzl'] = False # (kN-m); Blade StC #1 Blade #3 -- Z resulting moment; Local StC coordinates +ServoDyn['BStC2_B3_XQ'] = False # (m); Blade StC #2 Blade #3 -- X position (displacement); Relative to rest position in StC reference frame +ServoDyn['BStC2_B3_XQD'] = False # (m/s); Blade StC #2 Blade #3 -- X velocity; Relative to nacelle in StC reference frame +ServoDyn['BStC2_B3_YQ'] = False # (m); Blade StC #2 Blade #3 -- Y position (displacement); Relative to rest position in StC reference frame +ServoDyn['BStC2_B3_YQD'] = False # (m/s); Blade StC #2 Blade #3 -- Y velocity; Relative to nacelle in StC reference frame +ServoDyn['BStC2_B3_ZQ'] = False # (m); Blade StC #2 Blade #3 -- Z position (displacement); Relative to rest position in StC reference frame +ServoDyn['BStC2_B3_ZQD'] = False # (m/s); Blade StC #2 Blade #3 -- Z velocity; Relative to nacelle in StC reference frame +ServoDyn['BStC2_B3_Fxi'] = False # (kN); Blade StC #2 Blade #3 -- X resulting force; Inertial (global) coordinates +ServoDyn['BStC2_B3_Fyi'] = False # (kN); Blade StC #2 Blade #3 -- Y resulting force; Inertial (global) coordinates +ServoDyn['BStC2_B3_Fzi'] = False # (kN); Blade StC #2 Blade #3 -- Z resulting force; Inertial (global) coordinates +ServoDyn['BStC2_B3_Mxi'] = False # (kN-m); Blade StC #2 Blade #3 -- X resulting moment; Inertial (global) coordinates +ServoDyn['BStC2_B3_Myi'] = False # (kN-m); Blade StC #2 Blade #3 -- Y resulting moment; Inertial (global) coordinates +ServoDyn['BStC2_B3_Mzi'] = False # (kN-m); Blade StC #2 Blade #3 -- Z resulting moment; Inertial (global) coordinates +ServoDyn['BStC2_B3_Fxl'] = False # (kN); Blade StC #2 Blade #3 -- X resulting force; Local StC coordinates +ServoDyn['BStC2_B3_Fyl'] = False # (kN); Blade StC #2 Blade #3 -- Y resulting force; Local StC coordinates +ServoDyn['BStC2_B3_Fzl'] = False # (kN); Blade StC #2 Blade #3 -- Z resulting force; Local StC coordinates +ServoDyn['BStC2_B3_Mxl'] = False # (kN-m); Blade StC #2 Blade #3 -- X resulting moment; Local StC coordinates +ServoDyn['BStC2_B3_Myl'] = False # (kN-m); Blade StC #2 Blade #3 -- Y resulting moment; Local StC coordinates +ServoDyn['BStC2_B3_Mzl'] = False # (kN-m); Blade StC #2 Blade #3 -- Z resulting moment; Local StC coordinates +ServoDyn['BStC3_B3_XQ'] = False # (m); Blade StC #3 Blade #3 -- X position (displacement); Relative to rest position in StC reference frame +ServoDyn['BStC3_B3_XQD'] = False # (m/s); Blade StC #3 Blade #3 -- X velocity; Relative to nacelle in StC reference frame +ServoDyn['BStC3_B3_YQ'] = False # (m); Blade StC #3 Blade #3 -- Y position (displacement); Relative to rest position in StC reference frame +ServoDyn['BStC3_B3_YQD'] = False # (m/s); Blade StC #3 Blade #3 -- Y velocity; Relative to nacelle in StC reference frame +ServoDyn['BStC3_B3_ZQ'] = False # (m); Blade StC #3 Blade #3 -- Z position (displacement); Relative to rest position in StC reference frame +ServoDyn['BStC3_B3_ZQD'] = False # (m/s); Blade StC #3 Blade #3 -- Z velocity; Relative to nacelle in StC reference frame +ServoDyn['BStC3_B3_Fxi'] = False # (kN); Blade StC #3 Blade #3 -- X resulting force; Inertial (global) coordinates +ServoDyn['BStC3_B3_Fyi'] = False # (kN); Blade StC #3 Blade #3 -- Y resulting force; Inertial (global) coordinates +ServoDyn['BStC3_B3_Fzi'] = False # (kN); Blade StC #3 Blade #3 -- Z resulting force; Inertial (global) coordinates +ServoDyn['BStC3_B3_Mxi'] = False # (kN-m); Blade StC #3 Blade #3 -- X resulting moment; Inertial (global) coordinates +ServoDyn['BStC3_B3_Myi'] = False # (kN-m); Blade StC #3 Blade #3 -- Y resulting moment; Inertial (global) coordinates +ServoDyn['BStC3_B3_Mzi'] = False # (kN-m); Blade StC #3 Blade #3 -- Z resulting moment; Inertial (global) coordinates +ServoDyn['BStC3_B3_Fxl'] = False # (kN); Blade StC #3 Blade #3 -- X resulting force; Local StC coordinates +ServoDyn['BStC3_B3_Fyl'] = False # (kN); Blade StC #3 Blade #3 -- Y resulting force; Local StC coordinates +ServoDyn['BStC3_B3_Fzl'] = False # (kN); Blade StC #3 Blade #3 -- Z resulting force; Local StC coordinates +ServoDyn['BStC3_B3_Mxl'] = False # (kN-m); Blade StC #3 Blade #3 -- X resulting moment; Local StC coordinates +ServoDyn['BStC3_B3_Myl'] = False # (kN-m); Blade StC #3 Blade #3 -- Y resulting moment; Local StC coordinates +ServoDyn['BStC3_B3_Mzl'] = False # (kN-m); Blade StC #3 Blade #3 -- Z resulting moment; Local StC coordinates +ServoDyn['BStC4_B3_XQ'] = False # (m); Blade StC #4 Blade #3 -- X position (displacement); Relative to rest position in StC reference frame +ServoDyn['BStC4_B3_XQD'] = False # (m/s); Blade StC #4 Blade #3 -- X velocity; Relative to nacelle in StC reference frame +ServoDyn['BStC4_B3_YQ'] = False # (m); Blade StC #4 Blade #3 -- Y position (displacement); Relative to rest position in StC reference frame +ServoDyn['BStC4_B3_YQD'] = False # (m/s); Blade StC #4 Blade #3 -- Y velocity; Relative to nacelle in StC reference frame +ServoDyn['BStC4_B3_ZQ'] = False # (m); Blade StC #4 Blade #3 -- Z position (displacement); Relative to rest position in StC reference frame +ServoDyn['BStC4_B3_ZQD'] = False # (m/s); Blade StC #4 Blade #3 -- Z velocity; Relative to nacelle in StC reference frame +ServoDyn['BStC4_B3_Fxi'] = False # (kN); Blade StC #4 Blade #3 -- X resulting force; Inertial (global) coordinates +ServoDyn['BStC4_B3_Fyi'] = False # (kN); Blade StC #4 Blade #3 -- Y resulting force; Inertial (global) coordinates +ServoDyn['BStC4_B3_Fzi'] = False # (kN); Blade StC #4 Blade #3 -- Z resulting force; Inertial (global) coordinates +ServoDyn['BStC4_B3_Mxi'] = False # (kN-m); Blade StC #4 Blade #3 -- X resulting moment; Inertial (global) coordinates +ServoDyn['BStC4_B3_Myi'] = False # (kN-m); Blade StC #4 Blade #3 -- Y resulting moment; Inertial (global) coordinates +ServoDyn['BStC4_B3_Mzi'] = False # (kN-m); Blade StC #4 Blade #3 -- Z resulting moment; Inertial (global) coordinates +ServoDyn['BStC4_B3_Fxl'] = False # (kN); Blade StC #4 Blade #3 -- X resulting force; Local StC coordinates +ServoDyn['BStC4_B3_Fyl'] = False # (kN); Blade StC #4 Blade #3 -- Y resulting force; Local StC coordinates +ServoDyn['BStC4_B3_Fzl'] = False # (kN); Blade StC #4 Blade #3 -- Z resulting force; Local StC coordinates +ServoDyn['BStC4_B3_Mxl'] = False # (kN-m); Blade StC #4 Blade #3 -- X resulting moment; Local StC coordinates +ServoDyn['BStC4_B3_Myl'] = False # (kN-m); Blade StC #4 Blade #3 -- Y resulting moment; Local StC coordinates +ServoDyn['BStC4_B3_Mzl'] = False # (kN-m); Blade StC #4 Blade #3 -- Z resulting moment; Local StC coordinates +ServoDyn['BStC1_B4_XQ'] = False # (m); Blade StC #1 Blade #4 -- X position (displacement); Relative to rest position in StC reference frame +ServoDyn['BStC1_B4_XQD'] = False # (m/s); Blade StC #1 Blade #4 -- X velocity; Relative to nacelle in StC reference frame +ServoDyn['BStC1_B4_YQ'] = False # (m); Blade StC #1 Blade #4 -- Y position (displacement); Relative to rest position in StC reference frame +ServoDyn['BStC1_B4_YQD'] = False # (m/s); Blade StC #1 Blade #4 -- Y velocity; Relative to nacelle in StC reference frame +ServoDyn['BStC1_B4_ZQ'] = False # (m); Blade StC #1 Blade #4 -- Z position (displacement); Relative to rest position in StC reference frame +ServoDyn['BStC1_B4_ZQD'] = False # (m/s); Blade StC #1 Blade #4 -- Z velocity; Relative to nacelle in StC reference frame +ServoDyn['BStC1_B4_Fxi'] = False # (kN); Blade StC #1 Blade #4 -- X resulting force; Inertial (global) coordinates +ServoDyn['BStC1_B4_Fyi'] = False # (kN); Blade StC #1 Blade #4 -- Y resulting force; Inertial (global) coordinates +ServoDyn['BStC1_B4_Fzi'] = False # (kN); Blade StC #1 Blade #4 -- Z resulting force; Inertial (global) coordinates +ServoDyn['BStC1_B4_Mxi'] = False # (kN-m); Blade StC #1 Blade #4 -- X resulting moment; Inertial (global) coordinates +ServoDyn['BStC1_B4_Myi'] = False # (kN-m); Blade StC #1 Blade #4 -- Y resulting moment; Inertial (global) coordinates +ServoDyn['BStC1_B4_Mzi'] = False # (kN-m); Blade StC #1 Blade #4 -- Z resulting moment; Inertial (global) coordinates +ServoDyn['BStC1_B4_Fxl'] = False # (kN); Blade StC #1 Blade #4 -- X resulting force; Local StC coordinates +ServoDyn['BStC1_B4_Fyl'] = False # (kN); Blade StC #1 Blade #4 -- Y resulting force; Local StC coordinates +ServoDyn['BStC1_B4_Fzl'] = False # (kN); Blade StC #1 Blade #4 -- Z resulting force; Local StC coordinates +ServoDyn['BStC1_B4_Mxl'] = False # (kN-m); Blade StC #1 Blade #4 -- X resulting moment; Local StC coordinates +ServoDyn['BStC1_B4_Myl'] = False # (kN-m); Blade StC #1 Blade #4 -- Y resulting moment; Local StC coordinates +ServoDyn['BStC1_B4_Mzl'] = False # (kN-m); Blade StC #1 Blade #4 -- Z resulting moment; Local StC coordinates +ServoDyn['BStC2_B4_XQ'] = False # (m); Blade StC #2 Blade #4 -- X position (displacement); Relative to rest position in StC reference frame +ServoDyn['BStC2_B4_XQD'] = False # (m/s); Blade StC #2 Blade #4 -- X velocity; Relative to nacelle in StC reference frame +ServoDyn['BStC2_B4_YQ'] = False # (m); Blade StC #2 Blade #4 -- Y position (displacement); Relative to rest position in StC reference frame +ServoDyn['BStC2_B4_YQD'] = False # (m/s); Blade StC #2 Blade #4 -- Y velocity; Relative to nacelle in StC reference frame +ServoDyn['BStC2_B4_ZQ'] = False # (m); Blade StC #2 Blade #4 -- Z position (displacement); Relative to rest position in StC reference frame +ServoDyn['BStC2_B4_ZQD'] = False # (m/s); Blade StC #2 Blade #4 -- Z velocity; Relative to nacelle in StC reference frame +ServoDyn['BStC2_B4_Fxi'] = False # (kN); Blade StC #2 Blade #4 -- X resulting force; Inertial (global) coordinates +ServoDyn['BStC2_B4_Fyi'] = False # (kN); Blade StC #2 Blade #4 -- Y resulting force; Inertial (global) coordinates +ServoDyn['BStC2_B4_Fzi'] = False # (kN); Blade StC #2 Blade #4 -- Z resulting force; Inertial (global) coordinates +ServoDyn['BStC2_B4_Mxi'] = False # (kN-m); Blade StC #2 Blade #4 -- X resulting moment; Inertial (global) coordinates +ServoDyn['BStC2_B4_Myi'] = False # (kN-m); Blade StC #2 Blade #4 -- Y resulting moment; Inertial (global) coordinates +ServoDyn['BStC2_B4_Mzi'] = False # (kN-m); Blade StC #2 Blade #4 -- Z resulting moment; Inertial (global) coordinates +ServoDyn['BStC2_B4_Fxl'] = False # (kN); Blade StC #2 Blade #4 -- X resulting force; Local StC coordinates +ServoDyn['BStC2_B4_Fyl'] = False # (kN); Blade StC #2 Blade #4 -- Y resulting force; Local StC coordinates +ServoDyn['BStC2_B4_Fzl'] = False # (kN); Blade StC #2 Blade #4 -- Z resulting force; Local StC coordinates +ServoDyn['BStC2_B4_Mxl'] = False # (kN-m); Blade StC #2 Blade #4 -- X resulting moment; Local StC coordinates +ServoDyn['BStC2_B4_Myl'] = False # (kN-m); Blade StC #2 Blade #4 -- Y resulting moment; Local StC coordinates +ServoDyn['BStC2_B4_Mzl'] = False # (kN-m); Blade StC #2 Blade #4 -- Z resulting moment; Local StC coordinates +ServoDyn['BStC3_B4_XQ'] = False # (m); Blade StC #3 Blade #4 -- X position (displacement); Relative to rest position in StC reference frame +ServoDyn['BStC3_B4_XQD'] = False # (m/s); Blade StC #3 Blade #4 -- X velocity; Relative to nacelle in StC reference frame +ServoDyn['BStC3_B4_YQ'] = False # (m); Blade StC #3 Blade #4 -- Y position (displacement); Relative to rest position in StC reference frame +ServoDyn['BStC3_B4_YQD'] = False # (m/s); Blade StC #3 Blade #4 -- Y velocity; Relative to nacelle in StC reference frame +ServoDyn['BStC3_B4_ZQ'] = False # (m); Blade StC #3 Blade #4 -- Z position (displacement); Relative to rest position in StC reference frame +ServoDyn['BStC3_B4_ZQD'] = False # (m/s); Blade StC #3 Blade #4 -- Z velocity; Relative to nacelle in StC reference frame +ServoDyn['BStC3_B4_Fxi'] = False # (kN); Blade StC #3 Blade #4 -- X resulting force; Inertial (global) coordinates +ServoDyn['BStC3_B4_Fyi'] = False # (kN); Blade StC #3 Blade #4 -- Y resulting force; Inertial (global) coordinates +ServoDyn['BStC3_B4_Fzi'] = False # (kN); Blade StC #3 Blade #4 -- Z resulting force; Inertial (global) coordinates +ServoDyn['BStC3_B4_Mxi'] = False # (kN-m); Blade StC #3 Blade #4 -- X resulting moment; Inertial (global) coordinates +ServoDyn['BStC3_B4_Myi'] = False # (kN-m); Blade StC #3 Blade #4 -- Y resulting moment; Inertial (global) coordinates +ServoDyn['BStC3_B4_Mzi'] = False # (kN-m); Blade StC #3 Blade #4 -- Z resulting moment; Inertial (global) coordinates +ServoDyn['BStC3_B4_Fxl'] = False # (kN); Blade StC #3 Blade #4 -- X resulting force; Local StC coordinates +ServoDyn['BStC3_B4_Fyl'] = False # (kN); Blade StC #3 Blade #4 -- Y resulting force; Local StC coordinates +ServoDyn['BStC3_B4_Fzl'] = False # (kN); Blade StC #3 Blade #4 -- Z resulting force; Local StC coordinates +ServoDyn['BStC3_B4_Mxl'] = False # (kN-m); Blade StC #3 Blade #4 -- X resulting moment; Local StC coordinates +ServoDyn['BStC3_B4_Myl'] = False # (kN-m); Blade StC #3 Blade #4 -- Y resulting moment; Local StC coordinates +ServoDyn['BStC3_B4_Mzl'] = False # (kN-m); Blade StC #3 Blade #4 -- Z resulting moment; Local StC coordinates +ServoDyn['BStC4_B4_XQ'] = False # (m); Blade StC #4 Blade #4 -- X position (displacement); Relative to rest position in StC reference frame +ServoDyn['BStC4_B4_XQD'] = False # (m/s); Blade StC #4 Blade #4 -- X velocity; Relative to nacelle in StC reference frame +ServoDyn['BStC4_B4_YQ'] = False # (m); Blade StC #4 Blade #4 -- Y position (displacement); Relative to rest position in StC reference frame +ServoDyn['BStC4_B4_YQD'] = False # (m/s); Blade StC #4 Blade #4 -- Y velocity; Relative to nacelle in StC reference frame +ServoDyn['BStC4_B4_ZQ'] = False # (m); Blade StC #4 Blade #4 -- Z position (displacement); Relative to rest position in StC reference frame +ServoDyn['BStC4_B4_ZQD'] = False # (m/s); Blade StC #4 Blade #4 -- Z velocity; Relative to nacelle in StC reference frame +ServoDyn['BStC4_B4_Fxi'] = False # (kN); Blade StC #4 Blade #4 -- X resulting force; Inertial (global) coordinates +ServoDyn['BStC4_B4_Fyi'] = False # (kN); Blade StC #4 Blade #4 -- Y resulting force; Inertial (global) coordinates +ServoDyn['BStC4_B4_Fzi'] = False # (kN); Blade StC #4 Blade #4 -- Z resulting force; Inertial (global) coordinates +ServoDyn['BStC4_B4_Mxi'] = False # (kN-m); Blade StC #4 Blade #4 -- X resulting moment; Inertial (global) coordinates +ServoDyn['BStC4_B4_Myi'] = False # (kN-m); Blade StC #4 Blade #4 -- Y resulting moment; Inertial (global) coordinates +ServoDyn['BStC4_B4_Mzi'] = False # (kN-m); Blade StC #4 Blade #4 -- Z resulting moment; Inertial (global) coordinates +ServoDyn['BStC4_B4_Fxl'] = False # (kN); Blade StC #4 Blade #4 -- X resulting force; Local StC coordinates +ServoDyn['BStC4_B4_Fyl'] = False # (kN); Blade StC #4 Blade #4 -- Y resulting force; Local StC coordinates +ServoDyn['BStC4_B4_Fzl'] = False # (kN); Blade StC #4 Blade #4 -- Z resulting force; Local StC coordinates +ServoDyn['BStC4_B4_Mxl'] = False # (kN-m); Blade StC #4 Blade #4 -- X resulting moment; Local StC coordinates +ServoDyn['BStC4_B4_Myl'] = False # (kN-m); Blade StC #4 Blade #4 -- Y resulting moment; Local StC coordinates +ServoDyn['BStC4_B4_Mzl'] = False # (kN-m); Blade StC #4 Blade #4 -- Z resulting moment; Local StC coordinates -# WAMIT second order Body Forces -WAMIT['WavesF2xi'] = False # (N); ; -WAMIT['WavesF2yi'] = False # (N); ; -WAMIT['WavesF2zi'] = False # (N); ; -WAMIT['WavesM2xi'] = False # (N m); ; -WAMIT['WavesM2yi'] = False # (N m); ; -WAMIT['WavesM2zi'] = False # (N m); ; +# Substructure Structural Control (StC) +ServoDyn['SStC1_XQ'] = False # (m); Substructure StC #1 -- X position (displacement); Relative to rest position in StC reference frame +ServoDyn['SStC1_XQD'] = False # (m/s); Substructure StC #1 -- X velocity; Relative to nacelle in StC reference frame +ServoDyn['SStC1_YQ'] = False # (m); Substructure StC #1 -- Y position (displacement); Relative to rest position in StC reference frame +ServoDyn['SStC1_YQD'] = False # (m/s); Substructure StC #1 -- Y velocity; Relative to nacelle in StC reference frame +ServoDyn['SStC1_ZQ'] = False # (m); Substructure StC #1 -- Z position (displacement); Relative to rest position in StC reference frame +ServoDyn['SStC1_ZQD'] = False # (m/s); Substructure StC #1 -- Z velocity; Relative to nacelle in StC reference frame +ServoDyn['SStC1_Fxi'] = False # (kN); Substructure StC #1 -- X resulting force; Inertial (global) coordinates +ServoDyn['SStC1_Fyi'] = False # (kN); Substructure StC #1 -- Y resulting force; Inertial (global) coordinates +ServoDyn['SStC1_Fzi'] = False # (kN); Substructure StC #1 -- Z resulting force; Inertial (global) coordinates +ServoDyn['SStC1_Mxi'] = False # (kN-m); Substructure StC #1 -- X resulting moment; Inertial (global) coordinates +ServoDyn['SStC1_Myi'] = False # (kN-m); Substructure StC #1 -- Y resulting moment; Inertial (global) coordinates +ServoDyn['SStC1_Mzi'] = False # (kN-m); Substructure StC #1 -- Z resulting moment; Inertial (global) coordinates +ServoDyn['SStC1_Fxl'] = False # (kN); Substructure StC #1 -- X resulting force; Local StC coordinates +ServoDyn['SStC1_Fyl'] = False # (kN); Substructure StC #1 -- Y resulting force; Local StC coordinates +ServoDyn['SStC1_Fzl'] = False # (kN); Substructure StC #1 -- Z resulting force; Local StC coordinates +ServoDyn['SStC1_Mxl'] = False # (kN-m); Substructure StC #1 -- X resulting moment; Local StC coordinates +ServoDyn['SStC1_Myl'] = False # (kN-m); Substructure StC #1 -- Y resulting moment; Local StC coordinates +ServoDyn['SStC1_Mzl'] = False # (kN-m); Substructure StC #1 -- Z resulting moment; Local StC coordinates +ServoDyn['SStC2_XQ'] = False # (m); Substructure StC #2 -- X position (displacement); Relative to rest position in StC reference frame +ServoDyn['SStC2_XQD'] = False # (m/s); Substructure StC #2 -- X velocity; Relative to nacelle in StC reference frame +ServoDyn['SStC2_YQ'] = False # (m); Substructure StC #2 -- Y position (displacement); Relative to rest position in StC reference frame +ServoDyn['SStC2_YQD'] = False # (m/s); Substructure StC #2 -- Y velocity; Relative to nacelle in StC reference frame +ServoDyn['SStC2_ZQ'] = False # (m); Substructure StC #2 -- Z position (displacement); Relative to rest position in StC reference frame +ServoDyn['SStC2_ZQD'] = False # (m/s); Substructure StC #2 -- Z velocity; Relative to nacelle in StC reference frame +ServoDyn['SStC2_Fxi'] = False # (kN); Substructure StC #2 -- X resulting force; Inertial (global) coordinates +ServoDyn['SStC2_Fyi'] = False # (kN); Substructure StC #2 -- Y resulting force; Inertial (global) coordinates +ServoDyn['SStC2_Fzi'] = False # (kN); Substructure StC #2 -- Z resulting force; Inertial (global) coordinates +ServoDyn['SStC2_Mxi'] = False # (kN-m); Substructure StC #2 -- X resulting moment; Inertial (global) coordinates +ServoDyn['SStC2_Myi'] = False # (kN-m); Substructure StC #2 -- Y resulting moment; Inertial (global) coordinates +ServoDyn['SStC2_Mzi'] = False # (kN-m); Substructure StC #2 -- Z resulting moment; Inertial (global) coordinates +ServoDyn['SStC2_Fxl'] = False # (kN); Substructure StC #2 -- X resulting force; Local StC coordinates +ServoDyn['SStC2_Fyl'] = False # (kN); Substructure StC #2 -- Y resulting force; Local StC coordinates +ServoDyn['SStC2_Fzl'] = False # (kN); Substructure StC #2 -- Z resulting force; Local StC coordinates +ServoDyn['SStC2_Mxl'] = False # (kN-m); Substructure StC #2 -- X resulting moment; Local StC coordinates +ServoDyn['SStC2_Myl'] = False # (kN-m); Substructure StC #2 -- Y resulting moment; Local StC coordinates +ServoDyn['SStC2_Mzl'] = False # (kN-m); Substructure StC #2 -- Z resulting moment; Local StC coordinates +ServoDyn['SStC3_XQ'] = False # (m); Substructure StC #3 -- X position (displacement); Relative to rest position in StC reference frame +ServoDyn['SStC3_XQD'] = False # (m/s); Substructure StC #3 -- X velocity; Relative to nacelle in StC reference frame +ServoDyn['SStC3_YQ'] = False # (m); Substructure StC #3 -- Y position (displacement); Relative to rest position in StC reference frame +ServoDyn['SStC3_YQD'] = False # (m/s); Substructure StC #3 -- Y velocity; Relative to nacelle in StC reference frame +ServoDyn['SStC3_ZQ'] = False # (m); Substructure StC #3 -- Z position (displacement); Relative to rest position in StC reference frame +ServoDyn['SStC3_ZQD'] = False # (m/s); Substructure StC #3 -- Z velocity; Relative to nacelle in StC reference frame +ServoDyn['SStC3_Fxi'] = False # (kN); Substructure StC #3 -- X resulting force; Inertial (global) coordinates +ServoDyn['SStC3_Fyi'] = False # (kN); Substructure StC #3 -- Y resulting force; Inertial (global) coordinates +ServoDyn['SStC3_Fzi'] = False # (kN); Substructure StC #3 -- Z resulting force; Inertial (global) coordinates +ServoDyn['SStC3_Mxi'] = False # (kN-m); Substructure StC #3 -- X resulting moment; Inertial (global) coordinates +ServoDyn['SStC3_Myi'] = False # (kN-m); Substructure StC #3 -- Y resulting moment; Inertial (global) coordinates +ServoDyn['SStC3_Mzi'] = False # (kN-m); Substructure StC #3 -- Z resulting moment; Inertial (global) coordinates +ServoDyn['SStC3_Fxl'] = False # (kN); Substructure StC #3 -- X resulting force; Local StC coordinates +ServoDyn['SStC3_Fyl'] = False # (kN); Substructure StC #3 -- Y resulting force; Local StC coordinates +ServoDyn['SStC3_Fzl'] = False # (kN); Substructure StC #3 -- Z resulting force; Local StC coordinates +ServoDyn['SStC3_Mxl'] = False # (kN-m); Substructure StC #3 -- X resulting moment; Local StC coordinates +ServoDyn['SStC3_Myl'] = False # (kN-m); Substructure StC #3 -- Y resulting moment; Local StC coordinates +ServoDyn['SStC3_Mzl'] = False # (kN-m); Substructure StC #3 -- Z resulting moment; Local StC coordinates +ServoDyn['SStC4_XQ'] = False # (m); Substructure StC #4 -- X position (displacement); Relative to rest position in StC reference frame +ServoDyn['SStC4_XQD'] = False # (m/s); Substructure StC #4 -- X velocity; Relative to nacelle in StC reference frame +ServoDyn['SStC4_YQ'] = False # (m); Substructure StC #4 -- Y position (displacement); Relative to rest position in StC reference frame +ServoDyn['SStC4_YQD'] = False # (m/s); Substructure StC #4 -- Y velocity; Relative to nacelle in StC reference frame +ServoDyn['SStC4_ZQ'] = False # (m); Substructure StC #4 -- Z position (displacement); Relative to rest position in StC reference frame +ServoDyn['SStC4_ZQD'] = False # (m/s); Substructure StC #4 -- Z velocity; Relative to nacelle in StC reference frame +ServoDyn['SStC4_Fxi'] = False # (kN); Substructure StC #4 -- X resulting force; Inertial (global) coordinates +ServoDyn['SStC4_Fyi'] = False # (kN); Substructure StC #4 -- Y resulting force; Inertial (global) coordinates +ServoDyn['SStC4_Fzi'] = False # (kN); Substructure StC #4 -- Z resulting force; Inertial (global) coordinates +ServoDyn['SStC4_Mxi'] = False # (kN-m); Substructure StC #4 -- X resulting moment; Inertial (global) coordinates +ServoDyn['SStC4_Myi'] = False # (kN-m); Substructure StC #4 -- Y resulting moment; Inertial (global) coordinates +ServoDyn['SStC4_Mzi'] = False # (kN-m); Substructure StC #4 -- Z resulting moment; Inertial (global) coordinates +ServoDyn['SStC4_Fxl'] = False # (kN); Substructure StC #4 -- X resulting force; Local StC coordinates +ServoDyn['SStC4_Fyl'] = False # (kN); Substructure StC #4 -- Y resulting force; Local StC coordinates +ServoDyn['SStC4_Fzl'] = False # (kN); Substructure StC #4 -- Z resulting force; Local StC coordinates +ServoDyn['SStC4_Mxl'] = False # (kN-m); Substructure StC #4 -- X resulting moment; Local StC coordinates +ServoDyn['SStC4_Myl'] = False # (kN-m); Substructure StC #4 -- Y resulting moment; Local StC coordinates +ServoDyn['SStC4_Mzl'] = False # (kN-m); Substructure StC #4 -- Z resulting moment; Local StC coordinates -# WAMIT Body Forces -WAMIT['WavesFxi'] = False # (N); ; -WAMIT['WavesFyi'] = False # (N); ; -WAMIT['WavesFzi'] = False # (N); ; -WAMIT['WavesMxi'] = False # (N m); ; -WAMIT['WavesMyi'] = False # (N m); ; -WAMIT['WavesMzi'] = False # (N m); ; -WAMIT['HdrStcFxi'] = False # (N); ; -WAMIT['HdrStcFyi'] = False # (N); ; -WAMIT['HdrStcFzi'] = False # (N); ; -WAMIT['HdrStcMxi'] = False # (N m); ; -WAMIT['HdrStcMyi'] = False # (N m); ; -WAMIT['HdrStcMzi'] = False # (N m); ; -WAMIT['RdtnFxi'] = False # (N); ; -WAMIT['RdtnFyi'] = False # (N); ; -WAMIT['RdtnFzi'] = False # (N); ; -WAMIT['RdtnMxi'] = False # (N m); ; -WAMIT['RdtnMyi'] = False # (N m); ; -WAMIT['RdtnMzi'] = False # (N m); ; """ HydroDyn """ HydroDyn = {} @@ -3869,35 +4335,6 @@ HydroDyn['B9WvsM2yi'] = False # (N-m); Second-order wave-excitation moment at the 9th WAMIT body reference point from diffraction about the global y-axis; HydroDyn['B9WvsM2zi'] = False # (N-m); Second-order wave-excitation moment at the 9th WAMIT body reference point from diffraction about the global z-axis; -# Wave Elevations -HydroDyn['Wave1Elev'] = False # (m); Total (first-order plus second-order) wave elevation (global Z height) at the 1st user-requested location (location is specified in the global coordinate system); -HydroDyn['Wave2Elev'] = False # (m); Total (first-order plus second-order) wave elevation (global Z height) at the 2nd user-requested location (location is specified in the global coordinate system); -HydroDyn['Wave3Elev'] = False # (m); Total (first-order plus second-order) wave elevation (global Z height) at the 3rd user-requested location (location is specified in the global coordinate system); -HydroDyn['Wave4Elev'] = False # (m); Total (first-order plus second-order) wave elevation (global Z height) at the 4th user-requested location (location is specified in the global coordinate system); -HydroDyn['Wave5Elev'] = False # (m); Total (first-order plus second-order) wave elevation (global Z height) at the 5th user-requested location (location is specified in the global coordinate system); -HydroDyn['Wave6Elev'] = False # (m); Total (first-order plus second-order) wave elevation (global Z height) at the 6th user-requested location (location is specified in the global coordinate system); -HydroDyn['Wave7Elev'] = False # (m); Total (first-order plus second-order) wave elevation (global Z height) at the 7th user-requested location (location is specified in the global coordinate system); -HydroDyn['Wave8Elev'] = False # (m); Total (first-order plus second-order) wave elevation (global Z height) at the 8th user-requested location (location is specified in the global coordinate system); -HydroDyn['Wave9Elev'] = False # (m); Total (first-order plus second-order) wave elevation (global Z height) at the 9th user-requested location (location is specified in the global coordinate system); -HydroDyn['Wave1Elv1'] = False # (m); First-order wave elevation (global Z height) at the 1st user-requested location (location is specified in the global coordinate system); -HydroDyn['Wave2Elv1'] = False # (m); First-order wave elevation (global Z height) at the 2nd user-requested location (location is specified in the global coordinate system); -HydroDyn['Wave3Elv1'] = False # (m); First-order wave elevation (global Z height) at the 3rd user-requested location (location is specified in the global coordinate system); -HydroDyn['Wave4Elv1'] = False # (m); First-order wave elevation (global Z height) at the 4th user-requested location (location is specified in the global coordinate system); -HydroDyn['Wave5Elv1'] = False # (m); First-order wave elevation (global Z height) at the 5th user-requested location (location is specified in the global coordinate system); -HydroDyn['Wave6Elv1'] = False # (m); First-order wave elevation (global Z height) at the 6th user-requested location (location is specified in the global coordinate system); -HydroDyn['Wave7Elv1'] = False # (m); First-order wave elevation (global Z height) at the 7th user-requested location (location is specified in the global coordinate system); -HydroDyn['Wave8Elv1'] = False # (m); First-order wave elevation (global Z height) at the 8th user-requested location (location is specified in the global coordinate system); -HydroDyn['Wave9Elv1'] = False # (m); First-order wave elevation (global Z height) at the 9th user-requested location (location is specified in the global coordinate system); -HydroDyn['Wave1Elv2'] = False # (m); Second-order wave elevation (global Z height) at the 1st user-requested location (location is specified in the global coordinate system); -HydroDyn['Wave2Elv2'] = False # (m); Second-order wave elevation (global Z height) at the 2nd user-requested location (location is specified in the global coordinate system); -HydroDyn['Wave3Elv2'] = False # (m); Second-order wave elevation (global Z height) at the 3rd user-requested location (location is specified in the global coordinate system); -HydroDyn['Wave4Elv2'] = False # (m); Second-order wave elevation (global Z height) at the 4th user-requested location (location is specified in the global coordinate system); -HydroDyn['Wave5Elv2'] = False # (m); Second-order wave elevation (global Z height) at the 5th user-requested location (location is specified in the global coordinate system); -HydroDyn['Wave6Elv2'] = False # (m); Second-order wave elevation (global Z height) at the 6th user-requested location (location is specified in the global coordinate system); -HydroDyn['Wave7Elv2'] = False # (m); Second-order wave elevation (global Z height) at the 7th user-requested location (location is specified in the global coordinate system); -HydroDyn['Wave8Elv2'] = False # (m); Second-order wave elevation (global Z height) at the 8th user-requested location (location is specified in the global coordinate system); -HydroDyn['Wave9Elv2'] = False # (m); Second-order wave elevation (global Z height) at the 9th user-requested location (location is specified in the global coordinate system); - """ Morison """ Morison = {} @@ -8182,6 +8619,33 @@ Morison['J7DynP'] = False # (Pa); ; Morison['J8DynP'] = False # (Pa); ; Morison['J9DynP'] = False # (Pa); ; +Morison['J1WaveElev'] = False # (m); total wave elevation at the X,Y location of the joint; +Morison['J2WaveElev'] = False # (m); ; +Morison['J3WaveElev'] = False # (m); ; +Morison['J4WaveElev'] = False # (m); ; +Morison['J5WaveElev'] = False # (m); ; +Morison['J6WaveElev'] = False # (m); ; +Morison['J7WaveElev'] = False # (m); ; +Morison['J8WaveElev'] = False # (m); ; +Morison['J9WaveElev'] = False # (m); ; +Morison['J1WaveElv1'] = False # (m); wave elevation at the X,Y location of the joint due to 1st order effects; +Morison['J2WaveElv1'] = False # (m); ; +Morison['J3WaveElv1'] = False # (m); ; +Morison['J4WaveElv1'] = False # (m); ; +Morison['J5WaveElv1'] = False # (m); ; +Morison['J6WaveElv1'] = False # (m); ; +Morison['J7WaveElv1'] = False # (m); ; +Morison['J8WaveElv1'] = False # (m); ; +Morison['J9WaveElv1'] = False # (m); ; +Morison['J1WaveElv2'] = False # (m); wave elevation at the X,Y location of the joint due to 2nd order effects; +Morison['J2WaveElv2'] = False # (m); ; +Morison['J3WaveElv2'] = False # (m); ; +Morison['J4WaveElv2'] = False # (m); ; +Morison['J5WaveElv2'] = False # (m); ; +Morison['J6WaveElv2'] = False # (m); ; +Morison['J7WaveElv2'] = False # (m); ; +Morison['J8WaveElv2'] = False # (m); ; +Morison['J9WaveElv2'] = False # (m); ; Morison['J1STVxi'] = False # (m/s); structural translational velocity at the joint; Morison['J2STVxi'] = False # (m/s); ; Morison['J3STVxi'] = False # (m/s); ; @@ -8509,2363 +8973,412 @@ Morison['J8FMGzi'] = False # (N); ; Morison['J9FMGzi'] = False # (N); ; -""" SubDyn """ -SubDyn = {} -# Member Forces -SubDyn['M1N1FKxe'] = False # (N); xe component of the shear at Node Nj of member Mi- Local Reference System- Static Component; -SubDyn['M1N2FKxe'] = False # (N); ; -SubDyn['M1N3FKxe'] = False # (N); ; -SubDyn['M1N4FKxe'] = False # (N); ; -SubDyn['M1N5FKxe'] = False # (N); ; -SubDyn['M1N6FKxe'] = False # (N); ; -SubDyn['M1N7FKxe'] = False # (N); ; -SubDyn['M1N8FKxe'] = False # (N); ; -SubDyn['M1N9FKxe'] = False # (N); ; -SubDyn['M2N1FKxe'] = False # (N); ; -SubDyn['M2N2FKxe'] = False # (N); ; -SubDyn['M2N3FKxe'] = False # (N); ; -SubDyn['M2N4FKxe'] = False # (N); ; -SubDyn['M2N5FKxe'] = False # (N); ; -SubDyn['M2N6FKxe'] = False # (N); ; -SubDyn['M2N7FKxe'] = False # (N); ; -SubDyn['M2N8FKxe'] = False # (N); ; -SubDyn['M2N9FKxe'] = False # (N); ; -SubDyn['M3N1FKxe'] = False # (N); ; -SubDyn['M3N2FKxe'] = False # (N); ; -SubDyn['M3N3FKxe'] = False # (N); ; -SubDyn['M3N4FKxe'] = False # (N); ; -SubDyn['M3N5FKxe'] = False # (N); ; -SubDyn['M3N6FKxe'] = False # (N); ; -SubDyn['M3N7FKxe'] = False # (N); ; -SubDyn['M3N8FKxe'] = False # (N); ; -SubDyn['M3N9FKxe'] = False # (N); ; -SubDyn['M4N1FKxe'] = False # (N); ; -SubDyn['M4N2FKxe'] = False # (N); ; -SubDyn['M4N3FKxe'] = False # (N); ; -SubDyn['M4N4FKxe'] = False # (N); ; -SubDyn['M4N5FKxe'] = False # (N); ; -SubDyn['M4N6FKxe'] = False # (N); ; -SubDyn['M4N7FKxe'] = False # (N); ; -SubDyn['M4N8FKxe'] = False # (N); ; -SubDyn['M4N9FKxe'] = False # (N); ; -SubDyn['M5N1FKxe'] = False # (N); ; -SubDyn['M5N2FKxe'] = False # (N); ; -SubDyn['M5N3FKxe'] = False # (N); ; -SubDyn['M5N4FKxe'] = False # (N); ; -SubDyn['M5N5FKxe'] = False # (N); ; -SubDyn['M5N6FKxe'] = False # (N); ; -SubDyn['M5N7FKxe'] = False # (N); ; -SubDyn['M5N8FKxe'] = False # (N); ; -SubDyn['M5N9FKxe'] = False # (N); ; -SubDyn['M6N1FKxe'] = False # (N); ; -SubDyn['M6N2FKxe'] = False # (N); ; -SubDyn['M6N3FKxe'] = False # (N); ; -SubDyn['M6N4FKxe'] = False # (N); ; -SubDyn['M6N5FKxe'] = False # (N); ; -SubDyn['M6N6FKxe'] = False # (N); ; -SubDyn['M6N7FKxe'] = False # (N); ; -SubDyn['M6N8FKxe'] = False # (N); ; -SubDyn['M6N9FKxe'] = False # (N); ; -SubDyn['M7N1FKxe'] = False # (N); ; -SubDyn['M7N2FKxe'] = False # (N); ; -SubDyn['M7N3FKxe'] = False # (N); ; -SubDyn['M7N4FKxe'] = False # (N); ; -SubDyn['M7N5FKxe'] = False # (N); ; -SubDyn['M7N6FKxe'] = False # (N); ; -SubDyn['M7N7FKxe'] = False # (N); ; -SubDyn['M7N8FKxe'] = False # (N); ; -SubDyn['M7N9FKxe'] = False # (N); ; -SubDyn['M8N1FKxe'] = False # (N); ; -SubDyn['M8N2FKxe'] = False # (N); ; -SubDyn['M8N3FKxe'] = False # (N); ; -SubDyn['M8N4FKxe'] = False # (N); ; -SubDyn['M8N5FKxe'] = False # (N); ; -SubDyn['M8N6FKxe'] = False # (N); ; -SubDyn['M8N7FKxe'] = False # (N); ; -SubDyn['M8N8FKxe'] = False # (N); ; -SubDyn['M8N9FKxe'] = False # (N); ; -SubDyn['M9N1FKxe'] = False # (N); ; -SubDyn['M9N2FKxe'] = False # (N); ; -SubDyn['M9N3FKxe'] = False # (N); ; -SubDyn['M9N4FKxe'] = False # (N); ; -SubDyn['M9N5FKxe'] = False # (N); ; -SubDyn['M9N6FKxe'] = False # (N); ; -SubDyn['M9N7FKxe'] = False # (N); ; -SubDyn['M9N8FKxe'] = False # (N); ; -SubDyn['M9N9FKxe'] = False # (N); ; -SubDyn['M1N1FKye'] = False # (N); ye component of the shear at Node Nj of member Mi- Local Reference System- Static Component; -SubDyn['M1N2FKye'] = False # (N); ; -SubDyn['M1N3FKye'] = False # (N); ; -SubDyn['M1N4FKye'] = False # (N); ; -SubDyn['M1N5FKye'] = False # (N); ; -SubDyn['M1N6FKye'] = False # (N); ; -SubDyn['M1N7FKye'] = False # (N); ; -SubDyn['M1N8FKye'] = False # (N); ; -SubDyn['M1N9FKye'] = False # (N); ; -SubDyn['M2N1FKye'] = False # (N); ; -SubDyn['M2N2FKye'] = False # (N); ; -SubDyn['M2N3FKye'] = False # (N); ; -SubDyn['M2N4FKye'] = False # (N); ; -SubDyn['M2N5FKye'] = False # (N); ; -SubDyn['M2N6FKye'] = False # (N); ; -SubDyn['M2N7FKye'] = False # (N); ; -SubDyn['M2N8FKye'] = False # (N); ; -SubDyn['M2N9FKye'] = False # (N); ; -SubDyn['M3N1FKye'] = False # (N); ; -SubDyn['M3N2FKye'] = False # (N); ; -SubDyn['M3N3FKye'] = False # (N); ; -SubDyn['M3N4FKye'] = False # (N); ; -SubDyn['M3N5FKye'] = False # (N); ; -SubDyn['M3N6FKye'] = False # (N); ; -SubDyn['M3N7FKye'] = False # (N); ; -SubDyn['M3N8FKye'] = False # (N); ; -SubDyn['M3N9FKye'] = False # (N); ; -SubDyn['M4N1FKye'] = False # (N); ; -SubDyn['M4N2FKye'] = False # (N); ; -SubDyn['M4N3FKye'] = False # (N); ; -SubDyn['M4N4FKye'] = False # (N); ; -SubDyn['M4N5FKye'] = False # (N); ; -SubDyn['M4N6FKye'] = False # (N); ; -SubDyn['M4N7FKye'] = False # (N); ; -SubDyn['M4N8FKye'] = False # (N); ; -SubDyn['M4N9FKye'] = False # (N); ; -SubDyn['M5N1FKye'] = False # (N); ; -SubDyn['M5N2FKye'] = False # (N); ; -SubDyn['M5N3FKye'] = False # (N); ; -SubDyn['M5N4FKye'] = False # (N); ; -SubDyn['M5N5FKye'] = False # (N); ; -SubDyn['M5N6FKye'] = False # (N); ; -SubDyn['M5N7FKye'] = False # (N); ; -SubDyn['M5N8FKye'] = False # (N); ; -SubDyn['M5N9FKye'] = False # (N); ; -SubDyn['M6N1FKye'] = False # (N); ; -SubDyn['M6N2FKye'] = False # (N); ; -SubDyn['M6N3FKye'] = False # (N); ; -SubDyn['M6N4FKye'] = False # (N); ; -SubDyn['M6N5FKye'] = False # (N); ; -SubDyn['M6N6FKye'] = False # (N); ; -SubDyn['M6N7FKye'] = False # (N); ; -SubDyn['M6N8FKye'] = False # (N); ; -SubDyn['M6N9FKye'] = False # (N); ; -SubDyn['M7N1FKye'] = False # (N); ; -SubDyn['M7N2FKye'] = False # (N); ; -SubDyn['M7N3FKye'] = False # (N); ; -SubDyn['M7N4FKye'] = False # (N); ; -SubDyn['M7N5FKye'] = False # (N); ; -SubDyn['M7N6FKye'] = False # (N); ; -SubDyn['M7N7FKye'] = False # (N); ; -SubDyn['M7N8FKye'] = False # (N); ; -SubDyn['M7N9FKye'] = False # (N); ; -SubDyn['M8N1FKye'] = False # (N); ; -SubDyn['M8N2FKye'] = False # (N); ; -SubDyn['M8N3FKye'] = False # (N); ; -SubDyn['M8N4FKye'] = False # (N); ; -SubDyn['M8N5FKye'] = False # (N); ; -SubDyn['M8N6FKye'] = False # (N); ; -SubDyn['M8N7FKye'] = False # (N); ; -SubDyn['M8N8FKye'] = False # (N); ; -SubDyn['M8N9FKye'] = False # (N); ; -SubDyn['M9N1FKye'] = False # (N); ; -SubDyn['M9N2FKye'] = False # (N); ; -SubDyn['M9N3FKye'] = False # (N); ; -SubDyn['M9N4FKye'] = False # (N); ; -SubDyn['M9N5FKye'] = False # (N); ; -SubDyn['M9N6FKye'] = False # (N); ; -SubDyn['M9N7FKye'] = False # (N); ; -SubDyn['M9N8FKye'] = False # (N); ; -SubDyn['M9N9FKye'] = False # (N); ; -SubDyn['M1N1FKze'] = False # (N); Axial Force at Node Nj of member Mi- Local Reference System- Static Component; -SubDyn['M1N2FKze'] = False # (N); ; -SubDyn['M1N3FKze'] = False # (N); ; -SubDyn['M1N4FKze'] = False # (N); ; -SubDyn['M1N5FKze'] = False # (N); ; -SubDyn['M1N6FKze'] = False # (N); ; -SubDyn['M1N7FKze'] = False # (N); ; -SubDyn['M1N8FKze'] = False # (N); ; -SubDyn['M1N9FKze'] = False # (N); ; -SubDyn['M2N1FKze'] = False # (N); ; -SubDyn['M2N2FKze'] = False # (N); ; -SubDyn['M2N3FKze'] = False # (N); ; -SubDyn['M2N4FKze'] = False # (N); ; -SubDyn['M2N5FKze'] = False # (N); ; -SubDyn['M2N6FKze'] = False # (N); ; -SubDyn['M2N7FKze'] = False # (N); ; -SubDyn['M2N8FKze'] = False # (N); ; -SubDyn['M2N9FKze'] = False # (N); ; -SubDyn['M3N1FKze'] = False # (N); ; -SubDyn['M3N2FKze'] = False # (N); ; -SubDyn['M3N3FKze'] = False # (N); ; -SubDyn['M3N4FKze'] = False # (N); ; -SubDyn['M3N5FKze'] = False # (N); ; -SubDyn['M3N6FKze'] = False # (N); ; -SubDyn['M3N7FKze'] = False # (N); ; -SubDyn['M3N8FKze'] = False # (N); ; -SubDyn['M3N9FKze'] = False # (N); ; -SubDyn['M4N1FKze'] = False # (N); ; -SubDyn['M4N2FKze'] = False # (N); ; -SubDyn['M4N3FKze'] = False # (N); ; -SubDyn['M4N4FKze'] = False # (N); ; -SubDyn['M4N5FKze'] = False # (N); ; -SubDyn['M4N6FKze'] = False # (N); ; -SubDyn['M4N7FKze'] = False # (N); ; -SubDyn['M4N8FKze'] = False # (N); ; -SubDyn['M4N9FKze'] = False # (N); ; -SubDyn['M5N1FKze'] = False # (N); ; -SubDyn['M5N2FKze'] = False # (N); ; -SubDyn['M5N3FKze'] = False # (N); ; -SubDyn['M5N4FKze'] = False # (N); ; -SubDyn['M5N5FKze'] = False # (N); ; -SubDyn['M5N6FKze'] = False # (N); ; -SubDyn['M5N7FKze'] = False # (N); ; -SubDyn['M5N8FKze'] = False # (N); ; -SubDyn['M5N9FKze'] = False # (N); ; -SubDyn['M6N1FKze'] = False # (N); ; -SubDyn['M6N2FKze'] = False # (N); ; -SubDyn['M6N3FKze'] = False # (N); ; -SubDyn['M6N4FKze'] = False # (N); ; -SubDyn['M6N5FKze'] = False # (N); ; -SubDyn['M6N6FKze'] = False # (N); ; -SubDyn['M6N7FKze'] = False # (N); ; -SubDyn['M6N8FKze'] = False # (N); ; -SubDyn['M6N9FKze'] = False # (N); ; -SubDyn['M7N1FKze'] = False # (N); ; -SubDyn['M7N2FKze'] = False # (N); ; -SubDyn['M7N3FKze'] = False # (N); ; -SubDyn['M7N4FKze'] = False # (N); ; -SubDyn['M7N5FKze'] = False # (N); ; -SubDyn['M7N6FKze'] = False # (N); ; -SubDyn['M7N7FKze'] = False # (N); ; -SubDyn['M7N8FKze'] = False # (N); ; -SubDyn['M7N9FKze'] = False # (N); ; -SubDyn['M8N1FKze'] = False # (N); ; -SubDyn['M8N2FKze'] = False # (N); ; -SubDyn['M8N3FKze'] = False # (N); ; -SubDyn['M8N4FKze'] = False # (N); ; -SubDyn['M8N5FKze'] = False # (N); ; -SubDyn['M8N6FKze'] = False # (N); ; -SubDyn['M8N7FKze'] = False # (N); ; -SubDyn['M8N8FKze'] = False # (N); ; -SubDyn['M8N9FKze'] = False # (N); ; -SubDyn['M9N1FKze'] = False # (N); ; -SubDyn['M9N2FKze'] = False # (N); ; -SubDyn['M9N3FKze'] = False # (N); ; -SubDyn['M9N4FKze'] = False # (N); ; -SubDyn['M9N5FKze'] = False # (N); ; -SubDyn['M9N6FKze'] = False # (N); ; -SubDyn['M9N7FKze'] = False # (N); ; -SubDyn['M9N8FKze'] = False # (N); ; -SubDyn['M9N9FKze'] = False # (N); ; -SubDyn['M1N1FMxe'] = False # (N); xe component of the shear at Node Nj of member Mi- Local Reference System- Dynamic Component; -SubDyn['M1N2FMxe'] = False # (N); ; -SubDyn['M1N3FMxe'] = False # (N); ; -SubDyn['M1N4FMxe'] = False # (N); ; -SubDyn['M1N5FMxe'] = False # (N); ; -SubDyn['M1N6FMxe'] = False # (N); ; -SubDyn['M1N7FMxe'] = False # (N); ; -SubDyn['M1N8FMxe'] = False # (N); ; -SubDyn['M1N9FMxe'] = False # (N); ; -SubDyn['M2N1FMxe'] = False # (N); ; -SubDyn['M2N2FMxe'] = False # (N); ; -SubDyn['M2N3FMxe'] = False # (N); ; -SubDyn['M2N4FMxe'] = False # (N); ; -SubDyn['M2N5FMxe'] = False # (N); ; -SubDyn['M2N6FMxe'] = False # (N); ; -SubDyn['M2N7FMxe'] = False # (N); ; -SubDyn['M2N8FMxe'] = False # (N); ; -SubDyn['M2N9FMxe'] = False # (N); ; -SubDyn['M3N1FMxe'] = False # (N); ; -SubDyn['M3N2FMxe'] = False # (N); ; -SubDyn['M3N3FMxe'] = False # (N); ; -SubDyn['M3N4FMxe'] = False # (N); ; -SubDyn['M3N5FMxe'] = False # (N); ; -SubDyn['M3N6FMxe'] = False # (N); ; -SubDyn['M3N7FMxe'] = False # (N); ; -SubDyn['M3N8FMxe'] = False # (N); ; -SubDyn['M3N9FMxe'] = False # (N); ; -SubDyn['M4N1FMxe'] = False # (N); ; -SubDyn['M4N2FMxe'] = False # (N); ; -SubDyn['M4N3FMxe'] = False # (N); ; -SubDyn['M4N4FMxe'] = False # (N); ; -SubDyn['M4N5FMxe'] = False # (N); ; -SubDyn['M4N6FMxe'] = False # (N); ; -SubDyn['M4N7FMxe'] = False # (N); ; -SubDyn['M4N8FMxe'] = False # (N); ; -SubDyn['M4N9FMxe'] = False # (N); ; -SubDyn['M5N1FMxe'] = False # (N); ; -SubDyn['M5N2FMxe'] = False # (N); ; -SubDyn['M5N3FMxe'] = False # (N); ; -SubDyn['M5N4FMxe'] = False # (N); ; -SubDyn['M5N5FMxe'] = False # (N); ; -SubDyn['M5N6FMxe'] = False # (N); ; -SubDyn['M5N7FMxe'] = False # (N); ; -SubDyn['M5N8FMxe'] = False # (N); ; -SubDyn['M5N9FMxe'] = False # (N); ; -SubDyn['M6N1FMxe'] = False # (N); ; -SubDyn['M6N2FMxe'] = False # (N); ; -SubDyn['M6N3FMxe'] = False # (N); ; -SubDyn['M6N4FMxe'] = False # (N); ; -SubDyn['M6N5FMxe'] = False # (N); ; -SubDyn['M6N6FMxe'] = False # (N); ; -SubDyn['M6N7FMxe'] = False # (N); ; -SubDyn['M6N8FMxe'] = False # (N); ; -SubDyn['M6N9FMxe'] = False # (N); ; -SubDyn['M7N1FMxe'] = False # (N); ; -SubDyn['M7N2FMxe'] = False # (N); ; -SubDyn['M7N3FMxe'] = False # (N); ; -SubDyn['M7N4FMxe'] = False # (N); ; -SubDyn['M7N5FMxe'] = False # (N); ; -SubDyn['M7N6FMxe'] = False # (N); ; -SubDyn['M7N7FMxe'] = False # (N); ; -SubDyn['M7N8FMxe'] = False # (N); ; -SubDyn['M7N9FMxe'] = False # (N); ; -SubDyn['M8N1FMxe'] = False # (N); ; -SubDyn['M8N2FMxe'] = False # (N); ; -SubDyn['M8N3FMxe'] = False # (N); ; -SubDyn['M8N4FMxe'] = False # (N); ; -SubDyn['M8N5FMxe'] = False # (N); ; -SubDyn['M8N6FMxe'] = False # (N); ; -SubDyn['M8N7FMxe'] = False # (N); ; -SubDyn['M8N8FMxe'] = False # (N); ; -SubDyn['M8N9FMxe'] = False # (N); ; -SubDyn['M9N1FMxe'] = False # (N); ; -SubDyn['M9N2FMxe'] = False # (N); ; -SubDyn['M9N3FMxe'] = False # (N); ; -SubDyn['M9N4FMxe'] = False # (N); ; -SubDyn['M9N5FMxe'] = False # (N); ; -SubDyn['M9N6FMxe'] = False # (N); ; -SubDyn['M9N7FMxe'] = False # (N); ; -SubDyn['M9N8FMxe'] = False # (N); ; -SubDyn['M9N9FMxe'] = False # (N); ; -SubDyn['M1N1FMye'] = False # (N); ye component of the shear at Node Nj of member Mi- Local Reference System- Dynamic Component; -SubDyn['M1N2FMye'] = False # (N); ; -SubDyn['M1N3FMye'] = False # (N); ; -SubDyn['M1N4FMye'] = False # (N); ; -SubDyn['M1N5FMye'] = False # (N); ; -SubDyn['M1N6FMye'] = False # (N); ; -SubDyn['M1N7FMye'] = False # (N); ; -SubDyn['M1N8FMye'] = False # (N); ; -SubDyn['M1N9FMye'] = False # (N); ; -SubDyn['M2N1FMye'] = False # (N); ; -SubDyn['M2N2FMye'] = False # (N); ; -SubDyn['M2N3FMye'] = False # (N); ; -SubDyn['M2N4FMye'] = False # (N); ; -SubDyn['M2N5FMye'] = False # (N); ; -SubDyn['M2N6FMye'] = False # (N); ; -SubDyn['M2N7FMye'] = False # (N); ; -SubDyn['M2N8FMye'] = False # (N); ; -SubDyn['M2N9FMye'] = False # (N); ; -SubDyn['M3N1FMye'] = False # (N); ; -SubDyn['M3N2FMye'] = False # (N); ; -SubDyn['M3N3FMye'] = False # (N); ; -SubDyn['M3N4FMye'] = False # (N); ; -SubDyn['M3N5FMye'] = False # (N); ; -SubDyn['M3N6FMye'] = False # (N); ; -SubDyn['M3N7FMye'] = False # (N); ; -SubDyn['M3N8FMye'] = False # (N); ; -SubDyn['M3N9FMye'] = False # (N); ; -SubDyn['M4N1FMye'] = False # (N); ; -SubDyn['M4N2FMye'] = False # (N); ; -SubDyn['M4N3FMye'] = False # (N); ; -SubDyn['M4N4FMye'] = False # (N); ; -SubDyn['M4N5FMye'] = False # (N); ; -SubDyn['M4N6FMye'] = False # (N); ; -SubDyn['M4N7FMye'] = False # (N); ; -SubDyn['M4N8FMye'] = False # (N); ; -SubDyn['M4N9FMye'] = False # (N); ; -SubDyn['M5N1FMye'] = False # (N); ; -SubDyn['M5N2FMye'] = False # (N); ; -SubDyn['M5N3FMye'] = False # (N); ; -SubDyn['M5N4FMye'] = False # (N); ; -SubDyn['M5N5FMye'] = False # (N); ; -SubDyn['M5N6FMye'] = False # (N); ; -SubDyn['M5N7FMye'] = False # (N); ; -SubDyn['M5N8FMye'] = False # (N); ; -SubDyn['M5N9FMye'] = False # (N); ; -SubDyn['M6N1FMye'] = False # (N); ; -SubDyn['M6N2FMye'] = False # (N); ; -SubDyn['M6N3FMye'] = False # (N); ; -SubDyn['M6N4FMye'] = False # (N); ; -SubDyn['M6N5FMye'] = False # (N); ; -SubDyn['M6N6FMye'] = False # (N); ; -SubDyn['M6N7FMye'] = False # (N); ; -SubDyn['M6N8FMye'] = False # (N); ; -SubDyn['M6N9FMye'] = False # (N); ; -SubDyn['M7N1FMye'] = False # (N); ; -SubDyn['M7N2FMye'] = False # (N); ; -SubDyn['M7N3FMye'] = False # (N); ; -SubDyn['M7N4FMye'] = False # (N); ; -SubDyn['M7N5FMye'] = False # (N); ; -SubDyn['M7N6FMye'] = False # (N); ; -SubDyn['M7N7FMye'] = False # (N); ; -SubDyn['M7N8FMye'] = False # (N); ; -SubDyn['M7N9FMye'] = False # (N); ; -SubDyn['M8N1FMye'] = False # (N); ; -SubDyn['M8N2FMye'] = False # (N); ; -SubDyn['M8N3FMye'] = False # (N); ; -SubDyn['M8N4FMye'] = False # (N); ; -SubDyn['M8N5FMye'] = False # (N); ; -SubDyn['M8N6FMye'] = False # (N); ; -SubDyn['M8N7FMye'] = False # (N); ; -SubDyn['M8N8FMye'] = False # (N); ; -SubDyn['M8N9FMye'] = False # (N); ; -SubDyn['M9N1FMye'] = False # (N); ; -SubDyn['M9N2FMye'] = False # (N); ; -SubDyn['M9N3FMye'] = False # (N); ; -SubDyn['M9N4FMye'] = False # (N); ; -SubDyn['M9N5FMye'] = False # (N); ; -SubDyn['M9N6FMye'] = False # (N); ; -SubDyn['M9N7FMye'] = False # (N); ; -SubDyn['M9N8FMye'] = False # (N); ; -SubDyn['M9N9FMye'] = False # (N); ; -SubDyn['M1N1FMze'] = False # (N); axial force at Node Nj of member Mi- Local Reference System- Dynamic Component; -SubDyn['M1N2FMze'] = False # (N); ; -SubDyn['M1N3FMze'] = False # (N); ; -SubDyn['M1N4FMze'] = False # (N); ; -SubDyn['M1N5FMze'] = False # (N); ; -SubDyn['M1N6FMze'] = False # (N); ; -SubDyn['M1N7FMze'] = False # (N); ; -SubDyn['M1N8FMze'] = False # (N); ; -SubDyn['M1N9FMze'] = False # (N); ; -SubDyn['M2N1FMze'] = False # (N); ; -SubDyn['M2N2FMze'] = False # (N); ; -SubDyn['M2N3FMze'] = False # (N); ; -SubDyn['M2N4FMze'] = False # (N); ; -SubDyn['M2N5FMze'] = False # (N); ; -SubDyn['M2N6FMze'] = False # (N); ; -SubDyn['M2N7FMze'] = False # (N); ; -SubDyn['M2N8FMze'] = False # (N); ; -SubDyn['M2N9FMze'] = False # (N); ; -SubDyn['M3N1FMze'] = False # (N); ; -SubDyn['M3N2FMze'] = False # (N); ; -SubDyn['M3N3FMze'] = False # (N); ; -SubDyn['M3N4FMze'] = False # (N); ; -SubDyn['M3N5FMze'] = False # (N); ; -SubDyn['M3N6FMze'] = False # (N); ; -SubDyn['M3N7FMze'] = False # (N); ; -SubDyn['M3N8FMze'] = False # (N); ; -SubDyn['M3N9FMze'] = False # (N); ; -SubDyn['M4N1FMze'] = False # (N); ; -SubDyn['M4N2FMze'] = False # (N); ; -SubDyn['M4N3FMze'] = False # (N); ; -SubDyn['M4N4FMze'] = False # (N); ; -SubDyn['M4N5FMze'] = False # (N); ; -SubDyn['M4N6FMze'] = False # (N); ; -SubDyn['M4N7FMze'] = False # (N); ; -SubDyn['M4N8FMze'] = False # (N); ; -SubDyn['M4N9FMze'] = False # (N); ; -SubDyn['M5N1FMze'] = False # (N); ; -SubDyn['M5N2FMze'] = False # (N); ; -SubDyn['M5N3FMze'] = False # (N); ; -SubDyn['M5N4FMze'] = False # (N); ; -SubDyn['M5N5FMze'] = False # (N); ; -SubDyn['M5N6FMze'] = False # (N); ; -SubDyn['M5N7FMze'] = False # (N); ; -SubDyn['M5N8FMze'] = False # (N); ; -SubDyn['M5N9FMze'] = False # (N); ; -SubDyn['M6N1FMze'] = False # (N); ; -SubDyn['M6N2FMze'] = False # (N); ; -SubDyn['M6N3FMze'] = False # (N); ; -SubDyn['M6N4FMze'] = False # (N); ; -SubDyn['M6N5FMze'] = False # (N); ; -SubDyn['M6N6FMze'] = False # (N); ; -SubDyn['M6N7FMze'] = False # (N); ; -SubDyn['M6N8FMze'] = False # (N); ; -SubDyn['M6N9FMze'] = False # (N); ; -SubDyn['M7N1FMze'] = False # (N); ; -SubDyn['M7N2FMze'] = False # (N); ; -SubDyn['M7N3FMze'] = False # (N); ; -SubDyn['M7N4FMze'] = False # (N); ; -SubDyn['M7N5FMze'] = False # (N); ; -SubDyn['M7N6FMze'] = False # (N); ; -SubDyn['M7N7FMze'] = False # (N); ; -SubDyn['M7N8FMze'] = False # (N); ; -SubDyn['M7N9FMze'] = False # (N); ; -SubDyn['M8N1FMze'] = False # (N); ; -SubDyn['M8N2FMze'] = False # (N); ; -SubDyn['M8N3FMze'] = False # (N); ; -SubDyn['M8N4FMze'] = False # (N); ; -SubDyn['M8N5FMze'] = False # (N); ; -SubDyn['M8N6FMze'] = False # (N); ; -SubDyn['M8N7FMze'] = False # (N); ; -SubDyn['M8N8FMze'] = False # (N); ; -SubDyn['M8N9FMze'] = False # (N); ; -SubDyn['M9N1FMze'] = False # (N); ; -SubDyn['M9N2FMze'] = False # (N); ; -SubDyn['M9N3FMze'] = False # (N); ; -SubDyn['M9N4FMze'] = False # (N); ; -SubDyn['M9N5FMze'] = False # (N); ; -SubDyn['M9N6FMze'] = False # (N); ; -SubDyn['M9N7FMze'] = False # (N); ; -SubDyn['M9N8FMze'] = False # (N); ; -SubDyn['M9N9FMze'] = False # (N); ; -SubDyn['M1N1MKxe'] = False # (N*m); xe component of the bending moment at Node Nj of member Mi- Local Reference System- Static Component; -SubDyn['M1N2MKxe'] = False # (N*m); ; -SubDyn['M1N3MKxe'] = False # (N*m); ; -SubDyn['M1N4MKxe'] = False # (N*m); ; -SubDyn['M1N5MKxe'] = False # (N*m); ; -SubDyn['M1N6MKxe'] = False # (N*m); ; -SubDyn['M1N7MKxe'] = False # (N*m); ; -SubDyn['M1N8MKxe'] = False # (N*m); ; -SubDyn['M1N9MKxe'] = False # (N*m); ; -SubDyn['M2N1MKxe'] = False # (N*m); ; -SubDyn['M2N2MKxe'] = False # (N*m); ; -SubDyn['M2N3MKxe'] = False # (N*m); ; -SubDyn['M2N4MKxe'] = False # (N*m); ; -SubDyn['M2N5MKxe'] = False # (N*m); ; -SubDyn['M2N6MKxe'] = False # (N*m); ; -SubDyn['M2N7MKxe'] = False # (N*m); ; -SubDyn['M2N8MKxe'] = False # (N*m); ; -SubDyn['M2N9MKxe'] = False # (N*m); ; -SubDyn['M3N1MKxe'] = False # (N*m); ; -SubDyn['M3N2MKxe'] = False # (N*m); ; -SubDyn['M3N3MKxe'] = False # (N*m); ; -SubDyn['M3N4MKxe'] = False # (N*m); ; -SubDyn['M3N5MKxe'] = False # (N*m); ; -SubDyn['M3N6MKxe'] = False # (N*m); ; -SubDyn['M3N7MKxe'] = False # (N*m); ; -SubDyn['M3N8MKxe'] = False # (N*m); ; -SubDyn['M3N9MKxe'] = False # (N*m); ; -SubDyn['M4N1MKxe'] = False # (N*m); ; -SubDyn['M4N2MKxe'] = False # (N*m); ; -SubDyn['M4N3MKxe'] = False # (N*m); ; -SubDyn['M4N4MKxe'] = False # (N*m); ; -SubDyn['M4N5MKxe'] = False # (N*m); ; -SubDyn['M4N6MKxe'] = False # (N*m); ; -SubDyn['M4N7MKxe'] = False # (N*m); ; -SubDyn['M4N8MKxe'] = False # (N*m); ; -SubDyn['M4N9MKxe'] = False # (N*m); ; -SubDyn['M5N1MKxe'] = False # (N*m); ; -SubDyn['M5N2MKxe'] = False # (N*m); ; -SubDyn['M5N3MKxe'] = False # (N*m); ; -SubDyn['M5N4MKxe'] = False # (N*m); ; -SubDyn['M5N5MKxe'] = False # (N*m); ; -SubDyn['M5N6MKxe'] = False # (N*m); ; -SubDyn['M5N7MKxe'] = False # (N*m); ; -SubDyn['M5N8MKxe'] = False # (N*m); ; -SubDyn['M5N9MKxe'] = False # (N*m); ; -SubDyn['M6N1MKxe'] = False # (N*m); ; -SubDyn['M6N2MKxe'] = False # (N*m); ; -SubDyn['M6N3MKxe'] = False # (N*m); ; -SubDyn['M6N4MKxe'] = False # (N*m); ; -SubDyn['M6N5MKxe'] = False # (N*m); ; -SubDyn['M6N6MKxe'] = False # (N*m); ; -SubDyn['M6N7MKxe'] = False # (N*m); ; -SubDyn['M6N8MKxe'] = False # (N*m); ; -SubDyn['M6N9MKxe'] = False # (N*m); ; -SubDyn['M7N1MKxe'] = False # (N*m); ; -SubDyn['M7N2MKxe'] = False # (N*m); ; -SubDyn['M7N3MKxe'] = False # (N*m); ; -SubDyn['M7N4MKxe'] = False # (N*m); ; -SubDyn['M7N5MKxe'] = False # (N*m); ; -SubDyn['M7N6MKxe'] = False # (N*m); ; -SubDyn['M7N7MKxe'] = False # (N*m); ; -SubDyn['M7N8MKxe'] = False # (N*m); ; -SubDyn['M7N9MKxe'] = False # (N*m); ; -SubDyn['M8N1MKxe'] = False # (N*m); ; -SubDyn['M8N2MKxe'] = False # (N*m); ; -SubDyn['M8N3MKxe'] = False # (N*m); ; -SubDyn['M8N4MKxe'] = False # (N*m); ; -SubDyn['M8N5MKxe'] = False # (N*m); ; -SubDyn['M8N6MKxe'] = False # (N*m); ; -SubDyn['M8N7MKxe'] = False # (N*m); ; -SubDyn['M8N8MKxe'] = False # (N*m); ; -SubDyn['M8N9MKxe'] = False # (N*m); ; -SubDyn['M9N1MKxe'] = False # (N*m); ; -SubDyn['M9N2MKxe'] = False # (N*m); ; -SubDyn['M9N3MKxe'] = False # (N*m); ; -SubDyn['M9N4MKxe'] = False # (N*m); ; -SubDyn['M9N5MKxe'] = False # (N*m); ; -SubDyn['M9N6MKxe'] = False # (N*m); ; -SubDyn['M9N7MKxe'] = False # (N*m); ; -SubDyn['M9N8MKxe'] = False # (N*m); ; -SubDyn['M9N9MKxe'] = False # (N*m); ; -SubDyn['M1N1MKye'] = False # (N*m); ye component of the bending moment at Node Nj of member Mi- Local Reference System- Static Component; -SubDyn['M1N2MKye'] = False # (N*m); ; -SubDyn['M1N3MKye'] = False # (N*m); ; -SubDyn['M1N4MKye'] = False # (N*m); ; -SubDyn['M1N5MKye'] = False # (N*m); ; -SubDyn['M1N6MKye'] = False # (N*m); ; -SubDyn['M1N7MKye'] = False # (N*m); ; -SubDyn['M1N8MKye'] = False # (N*m); ; -SubDyn['M1N9MKye'] = False # (N*m); ; -SubDyn['M2N1MKye'] = False # (N*m); ; -SubDyn['M2N2MKye'] = False # (N*m); ; -SubDyn['M2N3MKye'] = False # (N*m); ; -SubDyn['M2N4MKye'] = False # (N*m); ; -SubDyn['M2N5MKye'] = False # (N*m); ; -SubDyn['M2N6MKye'] = False # (N*m); ; -SubDyn['M2N7MKye'] = False # (N*m); ; -SubDyn['M2N8MKye'] = False # (N*m); ; -SubDyn['M2N9MKye'] = False # (N*m); ; -SubDyn['M3N1MKye'] = False # (N*m); ; -SubDyn['M3N2MKye'] = False # (N*m); ; -SubDyn['M3N3MKye'] = False # (N*m); ; -SubDyn['M3N4MKye'] = False # (N*m); ; -SubDyn['M3N5MKye'] = False # (N*m); ; -SubDyn['M3N6MKye'] = False # (N*m); ; -SubDyn['M3N7MKye'] = False # (N*m); ; -SubDyn['M3N8MKye'] = False # (N*m); ; -SubDyn['M3N9MKye'] = False # (N*m); ; -SubDyn['M4N1MKye'] = False # (N*m); ; -SubDyn['M4N2MKye'] = False # (N*m); ; -SubDyn['M4N3MKye'] = False # (N*m); ; -SubDyn['M4N4MKye'] = False # (N*m); ; -SubDyn['M4N5MKye'] = False # (N*m); ; -SubDyn['M4N6MKye'] = False # (N*m); ; -SubDyn['M4N7MKye'] = False # (N*m); ; -SubDyn['M4N8MKye'] = False # (N*m); ; -SubDyn['M4N9MKye'] = False # (N*m); ; -SubDyn['M5N1MKye'] = False # (N*m); ; -SubDyn['M5N2MKye'] = False # (N*m); ; -SubDyn['M5N3MKye'] = False # (N*m); ; -SubDyn['M5N4MKye'] = False # (N*m); ; -SubDyn['M5N5MKye'] = False # (N*m); ; -SubDyn['M5N6MKye'] = False # (N*m); ; -SubDyn['M5N7MKye'] = False # (N*m); ; -SubDyn['M5N8MKye'] = False # (N*m); ; -SubDyn['M5N9MKye'] = False # (N*m); ; -SubDyn['M6N1MKye'] = False # (N*m); ; -SubDyn['M6N2MKye'] = False # (N*m); ; -SubDyn['M6N3MKye'] = False # (N*m); ; -SubDyn['M6N4MKye'] = False # (N*m); ; -SubDyn['M6N5MKye'] = False # (N*m); ; -SubDyn['M6N6MKye'] = False # (N*m); ; -SubDyn['M6N7MKye'] = False # (N*m); ; -SubDyn['M6N8MKye'] = False # (N*m); ; -SubDyn['M6N9MKye'] = False # (N*m); ; -SubDyn['M7N1MKye'] = False # (N*m); ; -SubDyn['M7N2MKye'] = False # (N*m); ; -SubDyn['M7N3MKye'] = False # (N*m); ; -SubDyn['M7N4MKye'] = False # (N*m); ; -SubDyn['M7N5MKye'] = False # (N*m); ; -SubDyn['M7N6MKye'] = False # (N*m); ; -SubDyn['M7N7MKye'] = False # (N*m); ; -SubDyn['M7N8MKye'] = False # (N*m); ; -SubDyn['M7N9MKye'] = False # (N*m); ; -SubDyn['M8N1MKye'] = False # (N*m); ; -SubDyn['M8N2MKye'] = False # (N*m); ; -SubDyn['M8N3MKye'] = False # (N*m); ; -SubDyn['M8N4MKye'] = False # (N*m); ; -SubDyn['M8N5MKye'] = False # (N*m); ; -SubDyn['M8N6MKye'] = False # (N*m); ; -SubDyn['M8N7MKye'] = False # (N*m); ; -SubDyn['M8N8MKye'] = False # (N*m); ; -SubDyn['M8N9MKye'] = False # (N*m); ; -SubDyn['M9N1MKye'] = False # (N*m); ; -SubDyn['M9N2MKye'] = False # (N*m); ; -SubDyn['M9N3MKye'] = False # (N*m); ; -SubDyn['M9N4MKye'] = False # (N*m); ; -SubDyn['M9N5MKye'] = False # (N*m); ; -SubDyn['M9N6MKye'] = False # (N*m); ; -SubDyn['M9N7MKye'] = False # (N*m); ; -SubDyn['M9N8MKye'] = False # (N*m); ; -SubDyn['M9N9MKye'] = False # (N*m); ; -SubDyn['M1N1MKze'] = False # (N*m); Torsion moment at Node Nj of member Mi- Local Reference System- Static Component; -SubDyn['M1N2MKze'] = False # (N*m); ; -SubDyn['M1N3MKze'] = False # (N*m); ; -SubDyn['M1N4MKze'] = False # (N*m); ; -SubDyn['M1N5MKze'] = False # (N*m); ; -SubDyn['M1N6MKze'] = False # (N*m); ; -SubDyn['M1N7MKze'] = False # (N*m); ; -SubDyn['M1N8MKze'] = False # (N*m); ; -SubDyn['M1N9MKze'] = False # (N*m); ; -SubDyn['M2N1MKze'] = False # (N*m); ; -SubDyn['M2N2MKze'] = False # (N*m); ; -SubDyn['M2N3MKze'] = False # (N*m); ; -SubDyn['M2N4MKze'] = False # (N*m); ; -SubDyn['M2N5MKze'] = False # (N*m); ; -SubDyn['M2N6MKze'] = False # (N*m); ; -SubDyn['M2N7MKze'] = False # (N*m); ; -SubDyn['M2N8MKze'] = False # (N*m); ; -SubDyn['M2N9MKze'] = False # (N*m); ; -SubDyn['M3N1MKze'] = False # (N*m); ; -SubDyn['M3N2MKze'] = False # (N*m); ; -SubDyn['M3N3MKze'] = False # (N*m); ; -SubDyn['M3N4MKze'] = False # (N*m); ; -SubDyn['M3N5MKze'] = False # (N*m); ; -SubDyn['M3N6MKze'] = False # (N*m); ; -SubDyn['M3N7MKze'] = False # (N*m); ; -SubDyn['M3N8MKze'] = False # (N*m); ; -SubDyn['M3N9MKze'] = False # (N*m); ; -SubDyn['M4N1MKze'] = False # (N*m); ; -SubDyn['M4N2MKze'] = False # (N*m); ; -SubDyn['M4N3MKze'] = False # (N*m); ; -SubDyn['M4N4MKze'] = False # (N*m); ; -SubDyn['M4N5MKze'] = False # (N*m); ; -SubDyn['M4N6MKze'] = False # (N*m); ; -SubDyn['M4N7MKze'] = False # (N*m); ; -SubDyn['M4N8MKze'] = False # (N*m); ; -SubDyn['M4N9MKze'] = False # (N*m); ; -SubDyn['M5N1MKze'] = False # (N*m); ; -SubDyn['M5N2MKze'] = False # (N*m); ; -SubDyn['M5N3MKze'] = False # (N*m); ; -SubDyn['M5N4MKze'] = False # (N*m); ; -SubDyn['M5N5MKze'] = False # (N*m); ; -SubDyn['M5N6MKze'] = False # (N*m); ; -SubDyn['M5N7MKze'] = False # (N*m); ; -SubDyn['M5N8MKze'] = False # (N*m); ; -SubDyn['M5N9MKze'] = False # (N*m); ; -SubDyn['M6N1MKze'] = False # (N*m); ; -SubDyn['M6N2MKze'] = False # (N*m); ; -SubDyn['M6N3MKze'] = False # (N*m); ; -SubDyn['M6N4MKze'] = False # (N*m); ; -SubDyn['M6N5MKze'] = False # (N*m); ; -SubDyn['M6N6MKze'] = False # (N*m); ; -SubDyn['M6N7MKze'] = False # (N*m); ; -SubDyn['M6N8MKze'] = False # (N*m); ; -SubDyn['M6N9MKze'] = False # (N*m); ; -SubDyn['M7N1MKze'] = False # (N*m); ; -SubDyn['M7N2MKze'] = False # (N*m); ; -SubDyn['M7N3MKze'] = False # (N*m); ; -SubDyn['M7N4MKze'] = False # (N*m); ; -SubDyn['M7N5MKze'] = False # (N*m); ; -SubDyn['M7N6MKze'] = False # (N*m); ; -SubDyn['M7N7MKze'] = False # (N*m); ; -SubDyn['M7N8MKze'] = False # (N*m); ; -SubDyn['M7N9MKze'] = False # (N*m); ; -SubDyn['M8N1MKze'] = False # (N*m); ; -SubDyn['M8N2MKze'] = False # (N*m); ; -SubDyn['M8N3MKze'] = False # (N*m); ; -SubDyn['M8N4MKze'] = False # (N*m); ; -SubDyn['M8N5MKze'] = False # (N*m); ; -SubDyn['M8N6MKze'] = False # (N*m); ; -SubDyn['M8N7MKze'] = False # (N*m); ; -SubDyn['M8N8MKze'] = False # (N*m); ; -SubDyn['M8N9MKze'] = False # (N*m); ; -SubDyn['M9N1MKze'] = False # (N*m); ; -SubDyn['M9N2MKze'] = False # (N*m); ; -SubDyn['M9N3MKze'] = False # (N*m); ; -SubDyn['M9N4MKze'] = False # (N*m); ; -SubDyn['M9N5MKze'] = False # (N*m); ; -SubDyn['M9N6MKze'] = False # (N*m); ; -SubDyn['M9N7MKze'] = False # (N*m); ; -SubDyn['M9N8MKze'] = False # (N*m); ; -SubDyn['M9N9MKze'] = False # (N*m); ; -SubDyn['M1N1MMxe'] = False # (N*m); xe component of the bending moment at Node Nj of member Mi- Local Reference System- Dynamic Component; -SubDyn['M1N2MMxe'] = False # (N*m); ; -SubDyn['M1N3MMxe'] = False # (N*m); ; -SubDyn['M1N4MMxe'] = False # (N*m); ; -SubDyn['M1N5MMxe'] = False # (N*m); ; -SubDyn['M1N6MMxe'] = False # (N*m); ; -SubDyn['M1N7MMxe'] = False # (N*m); ; -SubDyn['M1N8MMxe'] = False # (N*m); ; -SubDyn['M1N9MMxe'] = False # (N*m); ; -SubDyn['M2N1MMxe'] = False # (N*m); ; -SubDyn['M2N2MMxe'] = False # (N*m); ; -SubDyn['M2N3MMxe'] = False # (N*m); ; -SubDyn['M2N4MMxe'] = False # (N*m); ; -SubDyn['M2N5MMxe'] = False # (N*m); ; -SubDyn['M2N6MMxe'] = False # (N*m); ; -SubDyn['M2N7MMxe'] = False # (N*m); ; -SubDyn['M2N8MMxe'] = False # (N*m); ; -SubDyn['M2N9MMxe'] = False # (N*m); ; -SubDyn['M3N1MMxe'] = False # (N*m); ; -SubDyn['M3N2MMxe'] = False # (N*m); ; -SubDyn['M3N3MMxe'] = False # (N*m); ; -SubDyn['M3N4MMxe'] = False # (N*m); ; -SubDyn['M3N5MMxe'] = False # (N*m); ; -SubDyn['M3N6MMxe'] = False # (N*m); ; -SubDyn['M3N7MMxe'] = False # (N*m); ; -SubDyn['M3N8MMxe'] = False # (N*m); ; -SubDyn['M3N9MMxe'] = False # (N*m); ; -SubDyn['M4N1MMxe'] = False # (N*m); ; -SubDyn['M4N2MMxe'] = False # (N*m); ; -SubDyn['M4N3MMxe'] = False # (N*m); ; -SubDyn['M4N4MMxe'] = False # (N*m); ; -SubDyn['M4N5MMxe'] = False # (N*m); ; -SubDyn['M4N6MMxe'] = False # (N*m); ; -SubDyn['M4N7MMxe'] = False # (N*m); ; -SubDyn['M4N8MMxe'] = False # (N*m); ; -SubDyn['M4N9MMxe'] = False # (N*m); ; -SubDyn['M5N1MMxe'] = False # (N*m); ; -SubDyn['M5N2MMxe'] = False # (N*m); ; -SubDyn['M5N3MMxe'] = False # (N*m); ; -SubDyn['M5N4MMxe'] = False # (N*m); ; -SubDyn['M5N5MMxe'] = False # (N*m); ; -SubDyn['M5N6MMxe'] = False # (N*m); ; -SubDyn['M5N7MMxe'] = False # (N*m); ; -SubDyn['M5N8MMxe'] = False # (N*m); ; -SubDyn['M5N9MMxe'] = False # (N*m); ; -SubDyn['M6N1MMxe'] = False # (N*m); ; -SubDyn['M6N2MMxe'] = False # (N*m); ; -SubDyn['M6N3MMxe'] = False # (N*m); ; -SubDyn['M6N4MMxe'] = False # (N*m); ; -SubDyn['M6N5MMxe'] = False # (N*m); ; -SubDyn['M6N6MMxe'] = False # (N*m); ; -SubDyn['M6N7MMxe'] = False # (N*m); ; -SubDyn['M6N8MMxe'] = False # (N*m); ; -SubDyn['M6N9MMxe'] = False # (N*m); ; -SubDyn['M7N1MMxe'] = False # (N*m); ; -SubDyn['M7N2MMxe'] = False # (N*m); ; -SubDyn['M7N3MMxe'] = False # (N*m); ; -SubDyn['M7N4MMxe'] = False # (N*m); ; -SubDyn['M7N5MMxe'] = False # (N*m); ; -SubDyn['M7N6MMxe'] = False # (N*m); ; -SubDyn['M7N7MMxe'] = False # (N*m); ; -SubDyn['M7N8MMxe'] = False # (N*m); ; -SubDyn['M7N9MMxe'] = False # (N*m); ; -SubDyn['M8N1MMxe'] = False # (N*m); ; -SubDyn['M8N2MMxe'] = False # (N*m); ; -SubDyn['M8N3MMxe'] = False # (N*m); ; -SubDyn['M8N4MMxe'] = False # (N*m); ; -SubDyn['M8N5MMxe'] = False # (N*m); ; -SubDyn['M8N6MMxe'] = False # (N*m); ; -SubDyn['M8N7MMxe'] = False # (N*m); ; -SubDyn['M8N8MMxe'] = False # (N*m); ; -SubDyn['M8N9MMxe'] = False # (N*m); ; -SubDyn['M9N1MMxe'] = False # (N*m); ; -SubDyn['M9N2MMxe'] = False # (N*m); ; -SubDyn['M9N3MMxe'] = False # (N*m); ; -SubDyn['M9N4MMxe'] = False # (N*m); ; -SubDyn['M9N5MMxe'] = False # (N*m); ; -SubDyn['M9N6MMxe'] = False # (N*m); ; -SubDyn['M9N7MMxe'] = False # (N*m); ; -SubDyn['M9N8MMxe'] = False # (N*m); ; -SubDyn['M9N9MMxe'] = False # (N*m); ; -SubDyn['M1N1MMye'] = False # (N*m); ye component of the bending moment at Node Nj of member Mi- Local Reference System- Dynamic Component; -SubDyn['M1N2MMye'] = False # (N*m); ; -SubDyn['M1N3MMye'] = False # (N*m); ; -SubDyn['M1N4MMye'] = False # (N*m); ; -SubDyn['M1N5MMye'] = False # (N*m); ; -SubDyn['M1N6MMye'] = False # (N*m); ; -SubDyn['M1N7MMye'] = False # (N*m); ; -SubDyn['M1N8MMye'] = False # (N*m); ; -SubDyn['M1N9MMye'] = False # (N*m); ; -SubDyn['M2N1MMye'] = False # (N*m); ; -SubDyn['M2N2MMye'] = False # (N*m); ; -SubDyn['M2N3MMye'] = False # (N*m); ; -SubDyn['M2N4MMye'] = False # (N*m); ; -SubDyn['M2N5MMye'] = False # (N*m); ; -SubDyn['M2N6MMye'] = False # (N*m); ; -SubDyn['M2N7MMye'] = False # (N*m); ; -SubDyn['M2N8MMye'] = False # (N*m); ; -SubDyn['M2N9MMye'] = False # (N*m); ; -SubDyn['M3N1MMye'] = False # (N*m); ; -SubDyn['M3N2MMye'] = False # (N*m); ; -SubDyn['M3N3MMye'] = False # (N*m); ; -SubDyn['M3N4MMye'] = False # (N*m); ; -SubDyn['M3N5MMye'] = False # (N*m); ; -SubDyn['M3N6MMye'] = False # (N*m); ; -SubDyn['M3N7MMye'] = False # (N*m); ; -SubDyn['M3N8MMye'] = False # (N*m); ; -SubDyn['M3N9MMye'] = False # (N*m); ; -SubDyn['M4N1MMye'] = False # (N*m); ; -SubDyn['M4N2MMye'] = False # (N*m); ; -SubDyn['M4N3MMye'] = False # (N*m); ; -SubDyn['M4N4MMye'] = False # (N*m); ; -SubDyn['M4N5MMye'] = False # (N*m); ; -SubDyn['M4N6MMye'] = False # (N*m); ; -SubDyn['M4N7MMye'] = False # (N*m); ; -SubDyn['M4N8MMye'] = False # (N*m); ; -SubDyn['M4N9MMye'] = False # (N*m); ; -SubDyn['M5N1MMye'] = False # (N*m); ; -SubDyn['M5N2MMye'] = False # (N*m); ; -SubDyn['M5N3MMye'] = False # (N*m); ; -SubDyn['M5N4MMye'] = False # (N*m); ; -SubDyn['M5N5MMye'] = False # (N*m); ; -SubDyn['M5N6MMye'] = False # (N*m); ; -SubDyn['M5N7MMye'] = False # (N*m); ; -SubDyn['M5N8MMye'] = False # (N*m); ; -SubDyn['M5N9MMye'] = False # (N*m); ; -SubDyn['M6N1MMye'] = False # (N*m); ; -SubDyn['M6N2MMye'] = False # (N*m); ; -SubDyn['M6N3MMye'] = False # (N*m); ; -SubDyn['M6N4MMye'] = False # (N*m); ; -SubDyn['M6N5MMye'] = False # (N*m); ; -SubDyn['M6N6MMye'] = False # (N*m); ; -SubDyn['M6N7MMye'] = False # (N*m); ; -SubDyn['M6N8MMye'] = False # (N*m); ; -SubDyn['M6N9MMye'] = False # (N*m); ; -SubDyn['M7N1MMye'] = False # (N*m); ; -SubDyn['M7N2MMye'] = False # (N*m); ; -SubDyn['M7N3MMye'] = False # (N*m); ; -SubDyn['M7N4MMye'] = False # (N*m); ; -SubDyn['M7N5MMye'] = False # (N*m); ; -SubDyn['M7N6MMye'] = False # (N*m); ; -SubDyn['M7N7MMye'] = False # (N*m); ; -SubDyn['M7N8MMye'] = False # (N*m); ; -SubDyn['M7N9MMye'] = False # (N*m); ; -SubDyn['M8N1MMye'] = False # (N*m); ; -SubDyn['M8N2MMye'] = False # (N*m); ; -SubDyn['M8N3MMye'] = False # (N*m); ; -SubDyn['M8N4MMye'] = False # (N*m); ; -SubDyn['M8N5MMye'] = False # (N*m); ; -SubDyn['M8N6MMye'] = False # (N*m); ; -SubDyn['M8N7MMye'] = False # (N*m); ; -SubDyn['M8N8MMye'] = False # (N*m); ; -SubDyn['M8N9MMye'] = False # (N*m); ; -SubDyn['M9N1MMye'] = False # (N*m); ; -SubDyn['M9N2MMye'] = False # (N*m); ; -SubDyn['M9N3MMye'] = False # (N*m); ; -SubDyn['M9N4MMye'] = False # (N*m); ; -SubDyn['M9N5MMye'] = False # (N*m); ; -SubDyn['M9N6MMye'] = False # (N*m); ; -SubDyn['M9N7MMye'] = False # (N*m); ; -SubDyn['M9N8MMye'] = False # (N*m); ; -SubDyn['M9N9MMye'] = False # (N*m); ; -SubDyn['M1N1MMze'] = False # (N*m); Torsion moment at Node Nj of member Mi- Local Reference System- Dynamic Component; -SubDyn['M1N2MMze'] = False # (N*m); ; -SubDyn['M1N3MMze'] = False # (N*m); ; -SubDyn['M1N4MMze'] = False # (N*m); ; -SubDyn['M1N5MMze'] = False # (N*m); ; -SubDyn['M1N6MMze'] = False # (N*m); ; -SubDyn['M1N7MMze'] = False # (N*m); ; -SubDyn['M1N8MMze'] = False # (N*m); ; -SubDyn['M1N9MMze'] = False # (N*m); ; -SubDyn['M2N1MMze'] = False # (N*m); ; -SubDyn['M2N2MMze'] = False # (N*m); ; -SubDyn['M2N3MMze'] = False # (N*m); ; -SubDyn['M2N4MMze'] = False # (N*m); ; -SubDyn['M2N5MMze'] = False # (N*m); ; -SubDyn['M2N6MMze'] = False # (N*m); ; -SubDyn['M2N7MMze'] = False # (N*m); ; -SubDyn['M2N8MMze'] = False # (N*m); ; -SubDyn['M2N9MMze'] = False # (N*m); ; -SubDyn['M3N1MMze'] = False # (N*m); ; -SubDyn['M3N2MMze'] = False # (N*m); ; -SubDyn['M3N3MMze'] = False # (N*m); ; -SubDyn['M3N4MMze'] = False # (N*m); ; -SubDyn['M3N5MMze'] = False # (N*m); ; -SubDyn['M3N6MMze'] = False # (N*m); ; -SubDyn['M3N7MMze'] = False # (N*m); ; -SubDyn['M3N8MMze'] = False # (N*m); ; -SubDyn['M3N9MMze'] = False # (N*m); ; -SubDyn['M4N1MMze'] = False # (N*m); ; -SubDyn['M4N2MMze'] = False # (N*m); ; -SubDyn['M4N3MMze'] = False # (N*m); ; -SubDyn['M4N4MMze'] = False # (N*m); ; -SubDyn['M4N5MMze'] = False # (N*m); ; -SubDyn['M4N6MMze'] = False # (N*m); ; -SubDyn['M4N7MMze'] = False # (N*m); ; -SubDyn['M4N8MMze'] = False # (N*m); ; -SubDyn['M4N9MMze'] = False # (N*m); ; -SubDyn['M5N1MMze'] = False # (N*m); ; -SubDyn['M5N2MMze'] = False # (N*m); ; -SubDyn['M5N3MMze'] = False # (N*m); ; -SubDyn['M5N4MMze'] = False # (N*m); ; -SubDyn['M5N5MMze'] = False # (N*m); ; -SubDyn['M5N6MMze'] = False # (N*m); ; -SubDyn['M5N7MMze'] = False # (N*m); ; -SubDyn['M5N8MMze'] = False # (N*m); ; -SubDyn['M5N9MMze'] = False # (N*m); ; -SubDyn['M6N1MMze'] = False # (N*m); ; -SubDyn['M6N2MMze'] = False # (N*m); ; -SubDyn['M6N3MMze'] = False # (N*m); ; -SubDyn['M6N4MMze'] = False # (N*m); ; -SubDyn['M6N5MMze'] = False # (N*m); ; -SubDyn['M6N6MMze'] = False # (N*m); ; -SubDyn['M6N7MMze'] = False # (N*m); ; -SubDyn['M6N8MMze'] = False # (N*m); ; -SubDyn['M6N9MMze'] = False # (N*m); ; -SubDyn['M7N1MMze'] = False # (N*m); ; -SubDyn['M7N2MMze'] = False # (N*m); ; -SubDyn['M7N3MMze'] = False # (N*m); ; -SubDyn['M7N4MMze'] = False # (N*m); ; -SubDyn['M7N5MMze'] = False # (N*m); ; -SubDyn['M7N6MMze'] = False # (N*m); ; -SubDyn['M7N7MMze'] = False # (N*m); ; -SubDyn['M7N8MMze'] = False # (N*m); ; -SubDyn['M7N9MMze'] = False # (N*m); ; -SubDyn['M8N1MMze'] = False # (N*m); ; -SubDyn['M8N2MMze'] = False # (N*m); ; -SubDyn['M8N3MMze'] = False # (N*m); ; -SubDyn['M8N4MMze'] = False # (N*m); ; -SubDyn['M8N5MMze'] = False # (N*m); ; -SubDyn['M8N6MMze'] = False # (N*m); ; -SubDyn['M8N7MMze'] = False # (N*m); ; -SubDyn['M8N8MMze'] = False # (N*m); ; -SubDyn['M8N9MMze'] = False # (N*m); ; -SubDyn['M9N1MMze'] = False # (N*m); ; -SubDyn['M9N2MMze'] = False # (N*m); ; -SubDyn['M9N3MMze'] = False # (N*m); ; -SubDyn['M9N4MMze'] = False # (N*m); ; -SubDyn['M9N5MMze'] = False # (N*m); ; -SubDyn['M9N6MMze'] = False # (N*m); ; -SubDyn['M9N7MMze'] = False # (N*m); ; -SubDyn['M9N8MMze'] = False # (N*m); ; -SubDyn['M9N9MMze'] = False # (N*m); ; +""" SeaState """ +SeaState = {} + +# Wave Elevations +SeaState['Wave1Elev'] = False # (m); Total (first-order plus second-order) wave elevation (global Z height) at the 1st user-requested location (location is specified in the global coordinate system); +SeaState['Wave2Elev'] = False # (m); Total (first-order plus second-order) wave elevation (global Z height) at the 2nd user-requested location (location is specified in the global coordinate system); +SeaState['Wave3Elev'] = False # (m); Total (first-order plus second-order) wave elevation (global Z height) at the 3rd user-requested location (location is specified in the global coordinate system); +SeaState['Wave4Elev'] = False # (m); Total (first-order plus second-order) wave elevation (global Z height) at the 4th user-requested location (location is specified in the global coordinate system); +SeaState['Wave5Elev'] = False # (m); Total (first-order plus second-order) wave elevation (global Z height) at the 5th user-requested location (location is specified in the global coordinate system); +SeaState['Wave6Elev'] = False # (m); Total (first-order plus second-order) wave elevation (global Z height) at the 6th user-requested location (location is specified in the global coordinate system); +SeaState['Wave7Elev'] = False # (m); Total (first-order plus second-order) wave elevation (global Z height) at the 7th user-requested location (location is specified in the global coordinate system); +SeaState['Wave8Elev'] = False # (m); Total (first-order plus second-order) wave elevation (global Z height) at the 8th user-requested location (location is specified in the global coordinate system); +SeaState['Wave9Elev'] = False # (m); Total (first-order plus second-order) wave elevation (global Z height) at the 9th user-requested location (location is specified in the global coordinate system); +SeaState['Wave1Elv1'] = False # (m); First-order wave elevation (global Z height) at the 1st user-requested location (location is specified in the global coordinate system); +SeaState['Wave2Elv1'] = False # (m); First-order wave elevation (global Z height) at the 2nd user-requested location (location is specified in the global coordinate system); +SeaState['Wave3Elv1'] = False # (m); First-order wave elevation (global Z height) at the 3rd user-requested location (location is specified in the global coordinate system); +SeaState['Wave4Elv1'] = False # (m); First-order wave elevation (global Z height) at the 4th user-requested location (location is specified in the global coordinate system); +SeaState['Wave5Elv1'] = False # (m); First-order wave elevation (global Z height) at the 5th user-requested location (location is specified in the global coordinate system); +SeaState['Wave6Elv1'] = False # (m); First-order wave elevation (global Z height) at the 6th user-requested location (location is specified in the global coordinate system); +SeaState['Wave7Elv1'] = False # (m); First-order wave elevation (global Z height) at the 7th user-requested location (location is specified in the global coordinate system); +SeaState['Wave8Elv1'] = False # (m); First-order wave elevation (global Z height) at the 8th user-requested location (location is specified in the global coordinate system); +SeaState['Wave9Elv1'] = False # (m); First-order wave elevation (global Z height) at the 9th user-requested location (location is specified in the global coordinate system); +SeaState['Wave1Elv2'] = False # (m); Second-order wave elevation (global Z height) at the 1st user-requested location (location is specified in the global coordinate system); +SeaState['Wave2Elv2'] = False # (m); Second-order wave elevation (global Z height) at the 2nd user-requested location (location is specified in the global coordinate system); +SeaState['Wave3Elv2'] = False # (m); Second-order wave elevation (global Z height) at the 3rd user-requested location (location is specified in the global coordinate system); +SeaState['Wave4Elv2'] = False # (m); Second-order wave elevation (global Z height) at the 4th user-requested location (location is specified in the global coordinate system); +SeaState['Wave5Elv2'] = False # (m); Second-order wave elevation (global Z height) at the 5th user-requested location (location is specified in the global coordinate system); +SeaState['Wave6Elv2'] = False # (m); Second-order wave elevation (global Z height) at the 6th user-requested location (location is specified in the global coordinate system); +SeaState['Wave7Elv2'] = False # (m); Second-order wave elevation (global Z height) at the 7th user-requested location (location is specified in the global coordinate system); +SeaState['Wave8Elv2'] = False # (m); Second-order wave elevation (global Z height) at the 8th user-requested location (location is specified in the global coordinate system); +SeaState['Wave9Elv2'] = False # (m); Second-order wave elevation (global Z height) at the 9th user-requested location (location is specified in the global coordinate system); + +# Wave Kinematics +SeaState['FVel1xi'] = False # (m/s); fluid velocity along the global x-direction at the 1st user-requested location (location is specified in the global coordinate system); +SeaState['FVel2xi'] = False # (m/s); fluid velocity along the global x-direction at the 2nd user-requested location (location is specified in the global coordinate system); +SeaState['FVel3xi'] = False # (m/s); fluid velocity along the global x-direction at the 3rd user-requested location (location is specified in the global coordinate system); +SeaState['FVel4xi'] = False # (m/s); fluid velocity along the global x-direction at the 4th user-requested location (location is specified in the global coordinate system); +SeaState['FVel5xi'] = False # (m/s); fluid velocity along the global x-direction at the 5th user-requested location (location is specified in the global coordinate system); +SeaState['FVel6xi'] = False # (m/s); fluid velocity along the global x-direction at the 6th user-requested location (location is specified in the global coordinate system); +SeaState['FVel7xi'] = False # (m/s); fluid velocity along the global x-direction at the 7th user-requested location (location is specified in the global coordinate system); +SeaState['FVel8xi'] = False # (m/s); fluid velocity along the global x-direction at the 8th user-requested location (location is specified in the global coordinate system); +SeaState['FVel9xi'] = False # (m/s); fluid velocity along the global x-direction at the 9th user-requested location (location is specified in the global coordinate system); +SeaState['FVel1yi'] = False # (m/s); fluid velocity along the global y-direction at the 1st user-requested location (location is specified in the global coordinate system); +SeaState['FVel2yi'] = False # (m/s); fluid velocity along the global y-direction at the 2nd user-requested location (location is specified in the global coordinate system); +SeaState['FVel3yi'] = False # (m/s); fluid velocity along the global y-direction at the 3rd user-requested location (location is specified in the global coordinate system); +SeaState['FVel4yi'] = False # (m/s); fluid velocity along the global y-direction at the 4th user-requested location (location is specified in the global coordinate system); +SeaState['FVel5yi'] = False # (m/s); fluid velocity along the global y-direction at the 5th user-requested location (location is specified in the global coordinate system); +SeaState['FVel6yi'] = False # (m/s); fluid velocity along the global y-direction at the 6th user-requested location (location is specified in the global coordinate system); +SeaState['FVel7yi'] = False # (m/s); fluid velocity along the global y-direction at the 7th user-requested location (location is specified in the global coordinate system); +SeaState['FVel8yi'] = False # (m/s); fluid velocity along the global y-direction at the 8th user-requested location (location is specified in the global coordinate system); +SeaState['FVel9yi'] = False # (m/s); fluid velocity along the global y-direction at the 9th user-requested location (location is specified in the global coordinate system); +SeaState['FVel1zi'] = False # (m/s); fluid velocity along the global z-direction at the 1st user-requested location (location is specified in the global coordinate system); +SeaState['FVel2zi'] = False # (m/s); fluid velocity along the global z-direction at the 2nd user-requested location (location is specified in the global coordinate system); +SeaState['FVel3zi'] = False # (m/s); fluid velocity along the global z-direction at the 3rd user-requested location (location is specified in the global coordinate system); +SeaState['FVel4zi'] = False # (m/s); fluid velocity along the global z-direction at the 4th user-requested location (location is specified in the global coordinate system); +SeaState['FVel5zi'] = False # (m/s); fluid velocity along the global z-direction at the 5th user-requested location (location is specified in the global coordinate system); +SeaState['FVel6zi'] = False # (m/s); fluid velocity along the global z-direction at the 6th user-requested location (location is specified in the global coordinate system); +SeaState['FVel7zi'] = False # (m/s); fluid velocity along the global z-direction at the 7th user-requested location (location is specified in the global coordinate system); +SeaState['FVel8zi'] = False # (m/s); fluid velocity along the global z-direction at the 8th user-requested location (location is specified in the global coordinate system); +SeaState['FVel9zi'] = False # (m/s); fluid velocity along the global z-direction at the 9th user-requested location (location is specified in the global coordinate system); +SeaState['FAcc1xi'] = False # (m/s^2); fluid acceleration along the global x-direction at the 1st user-requested location (location is specified in the global coordinate system); +SeaState['FAcc2xi'] = False # (m/s^2); fluid acceleration along the global x-direction at the 2nd user-requested location (location is specified in the global coordinate system); +SeaState['FAcc3xi'] = False # (m/s^2); fluid acceleration along the global x-direction at the 3rd user-requested location (location is specified in the global coordinate system); +SeaState['FAcc4xi'] = False # (m/s^2); fluid acceleration along the global x-direction at the 4th user-requested location (location is specified in the global coordinate system); +SeaState['FAcc5xi'] = False # (m/s^2); fluid acceleration along the global x-direction at the 5th user-requested location (location is specified in the global coordinate system); +SeaState['FAcc6xi'] = False # (m/s^2); fluid acceleration along the global x-direction at the 6th user-requested location (location is specified in the global coordinate system); +SeaState['FAcc7xi'] = False # (m/s^2); fluid acceleration along the global x-direction at the 7th user-requested location (location is specified in the global coordinate system); +SeaState['FAcc8xi'] = False # (m/s^2); fluid acceleration along the global x-direction at the 8th user-requested location (location is specified in the global coordinate system); +SeaState['FAcc9xi'] = False # (m/s^2); fluid acceleration along the global x-direction at the 9th user-requested location (location is specified in the global coordinate system); +SeaState['FAcc1yi'] = False # (m/s^2); fluid acceleration along the global y-direction at the 1st user-requested location (location is specified in the global coordinate system); +SeaState['FAcc2yi'] = False # (m/s^2); fluid acceleration along the global y-direction at the 2nd user-requested location (location is specified in the global coordinate system); +SeaState['FAcc3yi'] = False # (m/s^2); fluid acceleration along the global y-direction at the 3rd user-requested location (location is specified in the global coordinate system); +SeaState['FAcc4yi'] = False # (m/s^2); fluid acceleration along the global y-direction at the 4th user-requested location (location is specified in the global coordinate system); +SeaState['FAcc5yi'] = False # (m/s^2); fluid acceleration along the global y-direction at the 5th user-requested location (location is specified in the global coordinate system); +SeaState['FAcc6yi'] = False # (m/s^2); fluid acceleration along the global y-direction at the 6th user-requested location (location is specified in the global coordinate system); +SeaState['FAcc7yi'] = False # (m/s^2); fluid acceleration along the global y-direction at the 7th user-requested location (location is specified in the global coordinate system); +SeaState['FAcc8yi'] = False # (m/s^2); fluid acceleration along the global y-direction at the 8th user-requested location (location is specified in the global coordinate system); +SeaState['FAcc9yi'] = False # (m/s^2); fluid acceleration along the global y-direction at the 9th user-requested location (location is specified in the global coordinate system); +SeaState['FAcc1zi'] = False # (m/s^2); fluid acceleration along the global z-direction at the 1st user-requested location (location is specified in the global coordinate system); +SeaState['FAcc2zi'] = False # (m/s^2); fluid acceleration along the global z-direction at the 2nd user-requested location (location is specified in the global coordinate system); +SeaState['FAcc3zi'] = False # (m/s^2); fluid acceleration along the global z-direction at the 3rd user-requested location (location is specified in the global coordinate system); +SeaState['FAcc4zi'] = False # (m/s^2); fluid acceleration along the global z-direction at the 4th user-requested location (location is specified in the global coordinate system); +SeaState['FAcc5zi'] = False # (m/s^2); fluid acceleration along the global z-direction at the 5th user-requested location (location is specified in the global coordinate system); +SeaState['FAcc6zi'] = False # (m/s^2); fluid acceleration along the global z-direction at the 6th user-requested location (location is specified in the global coordinate system); +SeaState['FAcc7zi'] = False # (m/s^2); fluid acceleration along the global z-direction at the 7th user-requested location (location is specified in the global coordinate system); +SeaState['FAcc8zi'] = False # (m/s^2); fluid acceleration along the global z-direction at the 8th user-requested location (location is specified in the global coordinate system); +SeaState['FAcc9zi'] = False # (m/s^2); fluid acceleration along the global z-direction at the 9th user-requested location (location is specified in the global coordinate system); +SeaState['FDynP1'] = False # (Pa); fluid dynamic pressure at the 1st user-requested location (location is specified in the global coordinate system); +SeaState['FDynP2'] = False # (Pa); fluid dynamic pressure at the 2nd user-requested location (location is specified in the global coordinate system); +SeaState['FDynP3'] = False # (Pa); fluid dynamic pressure at the 3rd user-requested location (location is specified in the global coordinate system); +SeaState['FDynP4'] = False # (Pa); fluid dynamic pressure at the 4th user-requested location (location is specified in the global coordinate system); +SeaState['FDynP5'] = False # (Pa); fluid dynamic pressure at the 5th user-requested location (location is specified in the global coordinate system); +SeaState['FDynP6'] = False # (Pa); fluid dynamic pressure at the 6th user-requested location (location is specified in the global coordinate system); +SeaState['FDynP7'] = False # (Pa); fluid dynamic pressure at the 7th user-requested location (location is specified in the global coordinate system); +SeaState['FDynP8'] = False # (Pa); fluid dynamic pressure at the 8th user-requested location (location is specified in the global coordinate system); +SeaState['FDynP9'] = False # (Pa); fluid dynamic pressure at the 9th user-requested location (location is specified in the global coordinate system); +SeaState['FAccMCF1xi'] = False # (m/s^2); fluid acceleration with MCF approximation; +SeaState['FAccMCF2xi'] = False # (m/s^2); fluid acceleration with MCF approximation; +SeaState['FAccMCF3xi'] = False # (m/s^2); fluid acceleration with MCF approximation; +SeaState['FAccMCF4xi'] = False # (m/s^2); fluid acceleration with MCF approximation; +SeaState['FAccMCF5xi'] = False # (m/s^2); fluid acceleration with MCF approximation; +SeaState['FAccMCF6xi'] = False # (m/s^2); fluid acceleration with MCF approximation; +SeaState['FAccMCF7xi'] = False # (m/s^2); fluid acceleration with MCF approximation; +SeaState['FAccMCF8xi'] = False # (m/s^2); fluid acceleration with MCF approximation; +SeaState['FAccMCF9xi'] = False # (m/s^2); fluid acceleration with MCF approximation; +SeaState['FAccMCF1yi'] = False # (m/s^2); fluid acceleration with MCF approximation; +SeaState['FAccMCF2yi'] = False # (m/s^2); fluid acceleration with MCF approximation; +SeaState['FAccMCF3yi'] = False # (m/s^2); fluid acceleration with MCF approximation; +SeaState['FAccMCF4yi'] = False # (m/s^2); fluid acceleration with MCF approximation; +SeaState['FAccMCF5yi'] = False # (m/s^2); fluid acceleration with MCF approximation; +SeaState['FAccMCF6yi'] = False # (m/s^2); fluid acceleration with MCF approximation; +SeaState['FAccMCF7yi'] = False # (m/s^2); fluid acceleration with MCF approximation; +SeaState['FAccMCF8yi'] = False # (m/s^2); fluid acceleration with MCF approximation; +SeaState['FAccMCF9yi'] = False # (m/s^2); fluid acceleration with MCF approximation; +SeaState['FAccMCF1zi'] = False # (m/s^2); fluid acceleration with MCF approximation; +SeaState['FAccMCF2zi'] = False # (m/s^2); fluid acceleration with MCF approximation; +SeaState['FAccMCF3zi'] = False # (m/s^2); fluid acceleration with MCF approximation; +SeaState['FAccMCF4zi'] = False # (m/s^2); fluid acceleration with MCF approximation; +SeaState['FAccMCF5zi'] = False # (m/s^2); fluid acceleration with MCF approximation; +SeaState['FAccMCF6zi'] = False # (m/s^2); fluid acceleration with MCF approximation; +SeaState['FAccMCF7zi'] = False # (m/s^2); fluid acceleration with MCF approximation; +SeaState['FAccMCF8zi'] = False # (m/s^2); fluid acceleration with MCF approximation; +SeaState['FAccMCF9zi'] = False # (m/s^2); fluid acceleration with MCF approximation; + -# Displacements -SubDyn['M1N1TDxss'] = False # (m); xss component of the displacement at Node Nj of member Mi- SS Reference System; -SubDyn['M1N2TDxss'] = False # (m); ; -SubDyn['M1N3TDxss'] = False # (m); ; -SubDyn['M1N4TDxss'] = False # (m); ; -SubDyn['M1N5TDxss'] = False # (m); ; -SubDyn['M1N6TDxss'] = False # (m); ; -SubDyn['M1N7TDxss'] = False # (m); ; -SubDyn['M1N8TDxss'] = False # (m); ; -SubDyn['M1N9TDxss'] = False # (m); ; -SubDyn['M2N1TDxss'] = False # (m); ; -SubDyn['M2N2TDxss'] = False # (m); ; -SubDyn['M2N3TDxss'] = False # (m); ; -SubDyn['M2N4TDxss'] = False # (m); ; -SubDyn['M2N5TDxss'] = False # (m); ; -SubDyn['M2N6TDxss'] = False # (m); ; -SubDyn['M2N7TDxss'] = False # (m); ; -SubDyn['M2N8TDxss'] = False # (m); ; -SubDyn['M2N9TDxss'] = False # (m); ; -SubDyn['M3N1TDxss'] = False # (m); ; -SubDyn['M3N2TDxss'] = False # (m); ; -SubDyn['M3N3TDxss'] = False # (m); ; -SubDyn['M3N4TDxss'] = False # (m); ; -SubDyn['M3N5TDxss'] = False # (m); ; -SubDyn['M3N6TDxss'] = False # (m); ; -SubDyn['M3N7TDxss'] = False # (m); ; -SubDyn['M3N8TDxss'] = False # (m); ; -SubDyn['M3N9TDxss'] = False # (m); ; -SubDyn['M4N1TDxss'] = False # (m); ; -SubDyn['M4N2TDxss'] = False # (m); ; -SubDyn['M4N3TDxss'] = False # (m); ; -SubDyn['M4N4TDxss'] = False # (m); ; -SubDyn['M4N5TDxss'] = False # (m); ; -SubDyn['M4N6TDxss'] = False # (m); ; -SubDyn['M4N7TDxss'] = False # (m); ; -SubDyn['M4N8TDxss'] = False # (m); ; -SubDyn['M4N9TDxss'] = False # (m); ; -SubDyn['M5N1TDxss'] = False # (m); ; -SubDyn['M5N2TDxss'] = False # (m); ; -SubDyn['M5N3TDxss'] = False # (m); ; -SubDyn['M5N4TDxss'] = False # (m); ; -SubDyn['M5N5TDxss'] = False # (m); ; -SubDyn['M5N6TDxss'] = False # (m); ; -SubDyn['M5N7TDxss'] = False # (m); ; -SubDyn['M5N8TDxss'] = False # (m); ; -SubDyn['M5N9TDxss'] = False # (m); ; -SubDyn['M6N1TDxss'] = False # (m); ; -SubDyn['M6N2TDxss'] = False # (m); ; -SubDyn['M6N3TDxss'] = False # (m); ; -SubDyn['M6N4TDxss'] = False # (m); ; -SubDyn['M6N5TDxss'] = False # (m); ; -SubDyn['M6N6TDxss'] = False # (m); ; -SubDyn['M6N7TDxss'] = False # (m); ; -SubDyn['M6N8TDxss'] = False # (m); ; -SubDyn['M6N9TDxss'] = False # (m); ; -SubDyn['M7N1TDxss'] = False # (m); ; -SubDyn['M7N2TDxss'] = False # (m); ; -SubDyn['M7N3TDxss'] = False # (m); ; -SubDyn['M7N4TDxss'] = False # (m); ; -SubDyn['M7N5TDxss'] = False # (m); ; -SubDyn['M7N6TDxss'] = False # (m); ; -SubDyn['M7N7TDxss'] = False # (m); ; -SubDyn['M7N8TDxss'] = False # (m); ; -SubDyn['M7N9TDxss'] = False # (m); ; -SubDyn['M8N1TDxss'] = False # (m); ; -SubDyn['M8N2TDxss'] = False # (m); ; -SubDyn['M8N3TDxss'] = False # (m); ; -SubDyn['M8N4TDxss'] = False # (m); ; -SubDyn['M8N5TDxss'] = False # (m); ; -SubDyn['M8N6TDxss'] = False # (m); ; -SubDyn['M8N7TDxss'] = False # (m); ; -SubDyn['M8N8TDxss'] = False # (m); ; -SubDyn['M8N9TDxss'] = False # (m); ; -SubDyn['M9N1TDxss'] = False # (m); ; -SubDyn['M9N2TDxss'] = False # (m); ; -SubDyn['M9N3TDxss'] = False # (m); ; -SubDyn['M9N4TDxss'] = False # (m); ; -SubDyn['M9N5TDxss'] = False # (m); ; -SubDyn['M9N6TDxss'] = False # (m); ; -SubDyn['M9N7TDxss'] = False # (m); ; -SubDyn['M9N8TDxss'] = False # (m); ; -SubDyn['M9N9TDxss'] = False # (m); ; -SubDyn['M1N1TDyss'] = False # (m); yss component of the displacement at Node Nj of member Mi- SS Reference System; -SubDyn['M1N2TDyss'] = False # (m); ; -SubDyn['M1N3TDyss'] = False # (m); ; -SubDyn['M1N4TDyss'] = False # (m); ; -SubDyn['M1N5TDyss'] = False # (m); ; -SubDyn['M1N6TDyss'] = False # (m); ; -SubDyn['M1N7TDyss'] = False # (m); ; -SubDyn['M1N8TDyss'] = False # (m); ; -SubDyn['M1N9TDyss'] = False # (m); ; -SubDyn['M2N1TDyss'] = False # (m); ; -SubDyn['M2N2TDyss'] = False # (m); ; -SubDyn['M2N3TDyss'] = False # (m); ; -SubDyn['M2N4TDyss'] = False # (m); ; -SubDyn['M2N5TDyss'] = False # (m); ; -SubDyn['M2N6TDyss'] = False # (m); ; -SubDyn['M2N7TDyss'] = False # (m); ; -SubDyn['M2N8TDyss'] = False # (m); ; -SubDyn['M2N9TDyss'] = False # (m); ; -SubDyn['M3N1TDyss'] = False # (m); ; -SubDyn['M3N2TDyss'] = False # (m); ; -SubDyn['M3N3TDyss'] = False # (m); ; -SubDyn['M3N4TDyss'] = False # (m); ; -SubDyn['M3N5TDyss'] = False # (m); ; -SubDyn['M3N6TDyss'] = False # (m); ; -SubDyn['M3N7TDyss'] = False # (m); ; -SubDyn['M3N8TDyss'] = False # (m); ; -SubDyn['M3N9TDyss'] = False # (m); ; -SubDyn['M4N1TDyss'] = False # (m); ; -SubDyn['M4N2TDyss'] = False # (m); ; -SubDyn['M4N3TDyss'] = False # (m); ; -SubDyn['M4N4TDyss'] = False # (m); ; -SubDyn['M4N5TDyss'] = False # (m); ; -SubDyn['M4N6TDyss'] = False # (m); ; -SubDyn['M4N7TDyss'] = False # (m); ; -SubDyn['M4N8TDyss'] = False # (m); ; -SubDyn['M4N9TDyss'] = False # (m); ; -SubDyn['M5N1TDyss'] = False # (m); ; -SubDyn['M5N2TDyss'] = False # (m); ; -SubDyn['M5N3TDyss'] = False # (m); ; -SubDyn['M5N4TDyss'] = False # (m); ; -SubDyn['M5N5TDyss'] = False # (m); ; -SubDyn['M5N6TDyss'] = False # (m); ; -SubDyn['M5N7TDyss'] = False # (m); ; -SubDyn['M5N8TDyss'] = False # (m); ; -SubDyn['M5N9TDyss'] = False # (m); ; -SubDyn['M6N1TDyss'] = False # (m); ; -SubDyn['M6N2TDyss'] = False # (m); ; -SubDyn['M6N3TDyss'] = False # (m); ; -SubDyn['M6N4TDyss'] = False # (m); ; -SubDyn['M6N5TDyss'] = False # (m); ; -SubDyn['M6N6TDyss'] = False # (m); ; -SubDyn['M6N7TDyss'] = False # (m); ; -SubDyn['M6N8TDyss'] = False # (m); ; -SubDyn['M6N9TDyss'] = False # (m); ; -SubDyn['M7N1TDyss'] = False # (m); ; -SubDyn['M7N2TDyss'] = False # (m); ; -SubDyn['M7N3TDyss'] = False # (m); ; -SubDyn['M7N4TDyss'] = False # (m); ; -SubDyn['M7N5TDyss'] = False # (m); ; -SubDyn['M7N6TDyss'] = False # (m); ; -SubDyn['M7N7TDyss'] = False # (m); ; -SubDyn['M7N8TDyss'] = False # (m); ; -SubDyn['M7N9TDyss'] = False # (m); ; -SubDyn['M8N1TDyss'] = False # (m); ; -SubDyn['M8N2TDyss'] = False # (m); ; -SubDyn['M8N3TDyss'] = False # (m); ; -SubDyn['M8N4TDyss'] = False # (m); ; -SubDyn['M8N5TDyss'] = False # (m); ; -SubDyn['M8N6TDyss'] = False # (m); ; -SubDyn['M8N7TDyss'] = False # (m); ; -SubDyn['M8N8TDyss'] = False # (m); ; -SubDyn['M8N9TDyss'] = False # (m); ; -SubDyn['M9N1TDyss'] = False # (m); ; -SubDyn['M9N2TDyss'] = False # (m); ; -SubDyn['M9N3TDyss'] = False # (m); ; -SubDyn['M9N4TDyss'] = False # (m); ; -SubDyn['M9N5TDyss'] = False # (m); ; -SubDyn['M9N6TDyss'] = False # (m); ; -SubDyn['M9N7TDyss'] = False # (m); ; -SubDyn['M9N8TDyss'] = False # (m); ; -SubDyn['M9N9TDyss'] = False # (m); ; -SubDyn['M1N1TDzss'] = False # (m); zss component of the displacement at Node Nj of member Mi- SS Reference System; -SubDyn['M1N2TDzss'] = False # (m); ; -SubDyn['M1N3TDzss'] = False # (m); ; -SubDyn['M1N4TDzss'] = False # (m); ; -SubDyn['M1N5TDzss'] = False # (m); ; -SubDyn['M1N6TDzss'] = False # (m); ; -SubDyn['M1N7TDzss'] = False # (m); ; -SubDyn['M1N8TDzss'] = False # (m); ; -SubDyn['M1N9TDzss'] = False # (m); ; -SubDyn['M2N1TDzss'] = False # (m); ; -SubDyn['M2N2TDzss'] = False # (m); ; -SubDyn['M2N3TDzss'] = False # (m); ; -SubDyn['M2N4TDzss'] = False # (m); ; -SubDyn['M2N5TDzss'] = False # (m); ; -SubDyn['M2N6TDzss'] = False # (m); ; -SubDyn['M2N7TDzss'] = False # (m); ; -SubDyn['M2N8TDzss'] = False # (m); ; -SubDyn['M2N9TDzss'] = False # (m); ; -SubDyn['M3N1TDzss'] = False # (m); ; -SubDyn['M3N2TDzss'] = False # (m); ; -SubDyn['M3N3TDzss'] = False # (m); ; -SubDyn['M3N4TDzss'] = False # (m); ; -SubDyn['M3N5TDzss'] = False # (m); ; -SubDyn['M3N6TDzss'] = False # (m); ; -SubDyn['M3N7TDzss'] = False # (m); ; -SubDyn['M3N8TDzss'] = False # (m); ; -SubDyn['M3N9TDzss'] = False # (m); ; -SubDyn['M4N1TDzss'] = False # (m); ; -SubDyn['M4N2TDzss'] = False # (m); ; -SubDyn['M4N3TDzss'] = False # (m); ; -SubDyn['M4N4TDzss'] = False # (m); ; -SubDyn['M4N5TDzss'] = False # (m); ; -SubDyn['M4N6TDzss'] = False # (m); ; -SubDyn['M4N7TDzss'] = False # (m); ; -SubDyn['M4N8TDzss'] = False # (m); ; -SubDyn['M4N9TDzss'] = False # (m); ; -SubDyn['M5N1TDzss'] = False # (m); ; -SubDyn['M5N2TDzss'] = False # (m); ; -SubDyn['M5N3TDzss'] = False # (m); ; -SubDyn['M5N4TDzss'] = False # (m); ; -SubDyn['M5N5TDzss'] = False # (m); ; -SubDyn['M5N6TDzss'] = False # (m); ; -SubDyn['M5N7TDzss'] = False # (m); ; -SubDyn['M5N8TDzss'] = False # (m); ; -SubDyn['M5N9TDzss'] = False # (m); ; -SubDyn['M6N1TDzss'] = False # (m); ; -SubDyn['M6N2TDzss'] = False # (m); ; -SubDyn['M6N3TDzss'] = False # (m); ; -SubDyn['M6N4TDzss'] = False # (m); ; -SubDyn['M6N5TDzss'] = False # (m); ; -SubDyn['M6N6TDzss'] = False # (m); ; -SubDyn['M6N7TDzss'] = False # (m); ; -SubDyn['M6N8TDzss'] = False # (m); ; -SubDyn['M6N9TDzss'] = False # (m); ; -SubDyn['M7N1TDzss'] = False # (m); ; -SubDyn['M7N2TDzss'] = False # (m); ; -SubDyn['M7N3TDzss'] = False # (m); ; -SubDyn['M7N4TDzss'] = False # (m); ; -SubDyn['M7N5TDzss'] = False # (m); ; -SubDyn['M7N6TDzss'] = False # (m); ; -SubDyn['M7N7TDzss'] = False # (m); ; -SubDyn['M7N8TDzss'] = False # (m); ; -SubDyn['M7N9TDzss'] = False # (m); ; -SubDyn['M8N1TDzss'] = False # (m); ; -SubDyn['M8N2TDzss'] = False # (m); ; -SubDyn['M8N3TDzss'] = False # (m); ; -SubDyn['M8N4TDzss'] = False # (m); ; -SubDyn['M8N5TDzss'] = False # (m); ; -SubDyn['M8N6TDzss'] = False # (m); ; -SubDyn['M8N7TDzss'] = False # (m); ; -SubDyn['M8N8TDzss'] = False # (m); ; -SubDyn['M8N9TDzss'] = False # (m); ; -SubDyn['M9N1TDzss'] = False # (m); ; -SubDyn['M9N2TDzss'] = False # (m); ; -SubDyn['M9N3TDzss'] = False # (m); ; -SubDyn['M9N4TDzss'] = False # (m); ; -SubDyn['M9N5TDzss'] = False # (m); ; -SubDyn['M9N6TDzss'] = False # (m); ; -SubDyn['M9N7TDzss'] = False # (m); ; -SubDyn['M9N8TDzss'] = False # (m); ; -SubDyn['M9N9TDzss'] = False # (m); ; -SubDyn['M1N1RDxe'] = False # (rad); xe component of the rotational displacement at Node Nj of member Mi-Element Reference System; -SubDyn['M1N2RDxe'] = False # (rad); ; -SubDyn['M1N3RDxe'] = False # (rad); ; -SubDyn['M1N4RDxe'] = False # (rad); ; -SubDyn['M1N5RDxe'] = False # (rad); ; -SubDyn['M1N6RDxe'] = False # (rad); ; -SubDyn['M1N7RDxe'] = False # (rad); ; -SubDyn['M1N8RDxe'] = False # (rad); ; -SubDyn['M1N9RDxe'] = False # (rad); ; -SubDyn['M2N1RDxe'] = False # (rad); ; -SubDyn['M2N2RDxe'] = False # (rad); ; -SubDyn['M2N3RDxe'] = False # (rad); ; -SubDyn['M2N4RDxe'] = False # (rad); ; -SubDyn['M2N5RDxe'] = False # (rad); ; -SubDyn['M2N6RDxe'] = False # (rad); ; -SubDyn['M2N7RDxe'] = False # (rad); ; -SubDyn['M2N8RDxe'] = False # (rad); ; -SubDyn['M2N9RDxe'] = False # (rad); ; -SubDyn['M3N1RDxe'] = False # (rad); ; -SubDyn['M3N2RDxe'] = False # (rad); ; -SubDyn['M3N3RDxe'] = False # (rad); ; -SubDyn['M3N4RDxe'] = False # (rad); ; -SubDyn['M3N5RDxe'] = False # (rad); ; -SubDyn['M3N6RDxe'] = False # (rad); ; -SubDyn['M3N7RDxe'] = False # (rad); ; -SubDyn['M3N8RDxe'] = False # (rad); ; -SubDyn['M3N9RDxe'] = False # (rad); ; -SubDyn['M4N1RDxe'] = False # (rad); ; -SubDyn['M4N2RDxe'] = False # (rad); ; -SubDyn['M4N3RDxe'] = False # (rad); ; -SubDyn['M4N4RDxe'] = False # (rad); ; -SubDyn['M4N5RDxe'] = False # (rad); ; -SubDyn['M4N6RDxe'] = False # (rad); ; -SubDyn['M4N7RDxe'] = False # (rad); ; -SubDyn['M4N8RDxe'] = False # (rad); ; -SubDyn['M4N9RDxe'] = False # (rad); ; -SubDyn['M5N1RDxe'] = False # (rad); ; -SubDyn['M5N2RDxe'] = False # (rad); ; -SubDyn['M5N3RDxe'] = False # (rad); ; -SubDyn['M5N4RDxe'] = False # (rad); ; -SubDyn['M5N5RDxe'] = False # (rad); ; -SubDyn['M5N6RDxe'] = False # (rad); ; -SubDyn['M5N7RDxe'] = False # (rad); ; -SubDyn['M5N8RDxe'] = False # (rad); ; -SubDyn['M5N9RDxe'] = False # (rad); ; -SubDyn['M6N1RDxe'] = False # (rad); ; -SubDyn['M6N2RDxe'] = False # (rad); ; -SubDyn['M6N3RDxe'] = False # (rad); ; -SubDyn['M6N4RDxe'] = False # (rad); ; -SubDyn['M6N5RDxe'] = False # (rad); ; -SubDyn['M6N6RDxe'] = False # (rad); ; -SubDyn['M6N7RDxe'] = False # (rad); ; -SubDyn['M6N8RDxe'] = False # (rad); ; -SubDyn['M6N9RDxe'] = False # (rad); ; -SubDyn['M7N1RDxe'] = False # (rad); ; -SubDyn['M7N2RDxe'] = False # (rad); ; -SubDyn['M7N3RDxe'] = False # (rad); ; -SubDyn['M7N4RDxe'] = False # (rad); ; -SubDyn['M7N5RDxe'] = False # (rad); ; -SubDyn['M7N6RDxe'] = False # (rad); ; -SubDyn['M7N7RDxe'] = False # (rad); ; -SubDyn['M7N8RDxe'] = False # (rad); ; -SubDyn['M7N9RDxe'] = False # (rad); ; -SubDyn['M8N1RDxe'] = False # (rad); ; -SubDyn['M8N2RDxe'] = False # (rad); ; -SubDyn['M8N3RDxe'] = False # (rad); ; -SubDyn['M8N4RDxe'] = False # (rad); ; -SubDyn['M8N5RDxe'] = False # (rad); ; -SubDyn['M8N6RDxe'] = False # (rad); ; -SubDyn['M8N7RDxe'] = False # (rad); ; -SubDyn['M8N8RDxe'] = False # (rad); ; -SubDyn['M8N9RDxe'] = False # (rad); ; -SubDyn['M9N1RDxe'] = False # (rad); ; -SubDyn['M9N2RDxe'] = False # (rad); ; -SubDyn['M9N3RDxe'] = False # (rad); ; -SubDyn['M9N4RDxe'] = False # (rad); ; -SubDyn['M9N5RDxe'] = False # (rad); ; -SubDyn['M9N6RDxe'] = False # (rad); ; -SubDyn['M9N7RDxe'] = False # (rad); ; -SubDyn['M9N8RDxe'] = False # (rad); ; -SubDyn['M9N9RDxe'] = False # (rad); ; -SubDyn['M1N1RDye'] = False # (rad); ye component of the rotational displacement at Node Nj of member Mi-Element Reference System; -SubDyn['M1N2RDye'] = False # (rad); ; -SubDyn['M1N3RDye'] = False # (rad); ; -SubDyn['M1N4RDye'] = False # (rad); ; -SubDyn['M1N5RDye'] = False # (rad); ; -SubDyn['M1N6RDye'] = False # (rad); ; -SubDyn['M1N7RDye'] = False # (rad); ; -SubDyn['M1N8RDye'] = False # (rad); ; -SubDyn['M1N9RDye'] = False # (rad); ; -SubDyn['M2N1RDye'] = False # (rad); ; -SubDyn['M2N2RDye'] = False # (rad); ; -SubDyn['M2N3RDye'] = False # (rad); ; -SubDyn['M2N4RDye'] = False # (rad); ; -SubDyn['M2N5RDye'] = False # (rad); ; -SubDyn['M2N6RDye'] = False # (rad); ; -SubDyn['M2N7RDye'] = False # (rad); ; -SubDyn['M2N8RDye'] = False # (rad); ; -SubDyn['M2N9RDye'] = False # (rad); ; -SubDyn['M3N1RDye'] = False # (rad); ; -SubDyn['M3N2RDye'] = False # (rad); ; -SubDyn['M3N3RDye'] = False # (rad); ; -SubDyn['M3N4RDye'] = False # (rad); ; -SubDyn['M3N5RDye'] = False # (rad); ; -SubDyn['M3N6RDye'] = False # (rad); ; -SubDyn['M3N7RDye'] = False # (rad); ; -SubDyn['M3N8RDye'] = False # (rad); ; -SubDyn['M3N9RDye'] = False # (rad); ; -SubDyn['M4N1RDye'] = False # (rad); ; -SubDyn['M4N2RDye'] = False # (rad); ; -SubDyn['M4N3RDye'] = False # (rad); ; -SubDyn['M4N4RDye'] = False # (rad); ; -SubDyn['M4N5RDye'] = False # (rad); ; -SubDyn['M4N6RDye'] = False # (rad); ; -SubDyn['M4N7RDye'] = False # (rad); ; -SubDyn['M4N8RDye'] = False # (rad); ; -SubDyn['M4N9RDye'] = False # (rad); ; -SubDyn['M5N1RDye'] = False # (rad); ; -SubDyn['M5N2RDye'] = False # (rad); ; -SubDyn['M5N3RDye'] = False # (rad); ; -SubDyn['M5N4RDye'] = False # (rad); ; -SubDyn['M5N5RDye'] = False # (rad); ; -SubDyn['M5N6RDye'] = False # (rad); ; -SubDyn['M5N7RDye'] = False # (rad); ; -SubDyn['M5N8RDye'] = False # (rad); ; -SubDyn['M5N9RDye'] = False # (rad); ; -SubDyn['M6N1RDye'] = False # (rad); ; -SubDyn['M6N2RDye'] = False # (rad); ; -SubDyn['M6N3RDye'] = False # (rad); ; -SubDyn['M6N4RDye'] = False # (rad); ; -SubDyn['M6N5RDye'] = False # (rad); ; -SubDyn['M6N6RDye'] = False # (rad); ; -SubDyn['M6N7RDye'] = False # (rad); ; -SubDyn['M6N8RDye'] = False # (rad); ; -SubDyn['M6N9RDye'] = False # (rad); ; -SubDyn['M7N1RDye'] = False # (rad); ; -SubDyn['M7N2RDye'] = False # (rad); ; -SubDyn['M7N3RDye'] = False # (rad); ; -SubDyn['M7N4RDye'] = False # (rad); ; -SubDyn['M7N5RDye'] = False # (rad); ; -SubDyn['M7N6RDye'] = False # (rad); ; -SubDyn['M7N7RDye'] = False # (rad); ; -SubDyn['M7N8RDye'] = False # (rad); ; -SubDyn['M7N9RDye'] = False # (rad); ; -SubDyn['M8N1RDye'] = False # (rad); ; -SubDyn['M8N2RDye'] = False # (rad); ; -SubDyn['M8N3RDye'] = False # (rad); ; -SubDyn['M8N4RDye'] = False # (rad); ; -SubDyn['M8N5RDye'] = False # (rad); ; -SubDyn['M8N6RDye'] = False # (rad); ; -SubDyn['M8N7RDye'] = False # (rad); ; -SubDyn['M8N8RDye'] = False # (rad); ; -SubDyn['M8N9RDye'] = False # (rad); ; -SubDyn['M9N1RDye'] = False # (rad); ; -SubDyn['M9N2RDye'] = False # (rad); ; -SubDyn['M9N3RDye'] = False # (rad); ; -SubDyn['M9N4RDye'] = False # (rad); ; -SubDyn['M9N5RDye'] = False # (rad); ; -SubDyn['M9N6RDye'] = False # (rad); ; -SubDyn['M9N7RDye'] = False # (rad); ; -SubDyn['M9N8RDye'] = False # (rad); ; -SubDyn['M9N9RDye'] = False # (rad); ; -SubDyn['M1N1RDze'] = False # (rad); ze component of the rotational displacement at Node Nj of member Mi-Element Reference System; -SubDyn['M1N2RDze'] = False # (rad); ; -SubDyn['M1N3RDze'] = False # (rad); ; -SubDyn['M1N4RDze'] = False # (rad); ; -SubDyn['M1N5RDze'] = False # (rad); ; -SubDyn['M1N6RDze'] = False # (rad); ; -SubDyn['M1N7RDze'] = False # (rad); ; -SubDyn['M1N8RDze'] = False # (rad); ; -SubDyn['M1N9RDze'] = False # (rad); ; -SubDyn['M2N1RDze'] = False # (rad); ; -SubDyn['M2N2RDze'] = False # (rad); ; -SubDyn['M2N3RDze'] = False # (rad); ; -SubDyn['M2N4RDze'] = False # (rad); ; -SubDyn['M2N5RDze'] = False # (rad); ; -SubDyn['M2N6RDze'] = False # (rad); ; -SubDyn['M2N7RDze'] = False # (rad); ; -SubDyn['M2N8RDze'] = False # (rad); ; -SubDyn['M2N9RDze'] = False # (rad); ; -SubDyn['M3N1RDze'] = False # (rad); ; -SubDyn['M3N2RDze'] = False # (rad); ; -SubDyn['M3N3RDze'] = False # (rad); ; -SubDyn['M3N4RDze'] = False # (rad); ; -SubDyn['M3N5RDze'] = False # (rad); ; -SubDyn['M3N6RDze'] = False # (rad); ; -SubDyn['M3N7RDze'] = False # (rad); ; -SubDyn['M3N8RDze'] = False # (rad); ; -SubDyn['M3N9RDze'] = False # (rad); ; -SubDyn['M4N1RDze'] = False # (rad); ; -SubDyn['M4N2RDze'] = False # (rad); ; -SubDyn['M4N3RDze'] = False # (rad); ; -SubDyn['M4N4RDze'] = False # (rad); ; -SubDyn['M4N5RDze'] = False # (rad); ; -SubDyn['M4N6RDze'] = False # (rad); ; -SubDyn['M4N7RDze'] = False # (rad); ; -SubDyn['M4N8RDze'] = False # (rad); ; -SubDyn['M4N9RDze'] = False # (rad); ; -SubDyn['M5N1RDze'] = False # (rad); ; -SubDyn['M5N2RDze'] = False # (rad); ; -SubDyn['M5N3RDze'] = False # (rad); ; -SubDyn['M5N4RDze'] = False # (rad); ; -SubDyn['M5N5RDze'] = False # (rad); ; -SubDyn['M5N6RDze'] = False # (rad); ; -SubDyn['M5N7RDze'] = False # (rad); ; -SubDyn['M5N8RDze'] = False # (rad); ; -SubDyn['M5N9RDze'] = False # (rad); ; -SubDyn['M6N1RDze'] = False # (rad); ; -SubDyn['M6N2RDze'] = False # (rad); ; -SubDyn['M6N3RDze'] = False # (rad); ; -SubDyn['M6N4RDze'] = False # (rad); ; -SubDyn['M6N5RDze'] = False # (rad); ; -SubDyn['M6N6RDze'] = False # (rad); ; -SubDyn['M6N7RDze'] = False # (rad); ; -SubDyn['M6N8RDze'] = False # (rad); ; -SubDyn['M6N9RDze'] = False # (rad); ; -SubDyn['M7N1RDze'] = False # (rad); ; -SubDyn['M7N2RDze'] = False # (rad); ; -SubDyn['M7N3RDze'] = False # (rad); ; -SubDyn['M7N4RDze'] = False # (rad); ; -SubDyn['M7N5RDze'] = False # (rad); ; -SubDyn['M7N6RDze'] = False # (rad); ; -SubDyn['M7N7RDze'] = False # (rad); ; -SubDyn['M7N8RDze'] = False # (rad); ; -SubDyn['M7N9RDze'] = False # (rad); ; -SubDyn['M8N1RDze'] = False # (rad); ; -SubDyn['M8N2RDze'] = False # (rad); ; -SubDyn['M8N3RDze'] = False # (rad); ; -SubDyn['M8N4RDze'] = False # (rad); ; -SubDyn['M8N5RDze'] = False # (rad); ; -SubDyn['M8N6RDze'] = False # (rad); ; -SubDyn['M8N7RDze'] = False # (rad); ; -SubDyn['M8N8RDze'] = False # (rad); ; -SubDyn['M8N9RDze'] = False # (rad); ; -SubDyn['M9N1RDze'] = False # (rad); ; -SubDyn['M9N2RDze'] = False # (rad); ; -SubDyn['M9N3RDze'] = False # (rad); ; -SubDyn['M9N4RDze'] = False # (rad); ; -SubDyn['M9N5RDze'] = False # (rad); ; -SubDyn['M9N6RDze'] = False # (rad); ; -SubDyn['M9N7RDze'] = False # (rad); ; -SubDyn['M9N8RDze'] = False # (rad); ; -SubDyn['M9N9RDze'] = False # (rad); ; +""" SubDyn """ +SubDyn = {} -# Accelerations -SubDyn['M1N1TAxe'] = False # (m/s^2); xe component of the translational acceleration displacement at Node Nj of member Mi-Element Reference System; -SubDyn['M1N2TAxe'] = False # (m/s^2); ; -SubDyn['M1N3TAxe'] = False # (m/s^2); ; -SubDyn['M1N4TAxe'] = False # (m/s^2); ; -SubDyn['M1N5TAxe'] = False # (m/s^2); ; -SubDyn['M1N6TAxe'] = False # (m/s^2); ; -SubDyn['M1N7TAxe'] = False # (m/s^2); ; -SubDyn['M1N8TAxe'] = False # (m/s^2); ; -SubDyn['M1N9TAxe'] = False # (m/s^2); ; -SubDyn['M2N1TAxe'] = False # (m/s^2); ; -SubDyn['M2N2TAxe'] = False # (m/s^2); ; -SubDyn['M2N3TAxe'] = False # (m/s^2); ; -SubDyn['M2N4TAxe'] = False # (m/s^2); ; -SubDyn['M2N5TAxe'] = False # (m/s^2); ; -SubDyn['M2N6TAxe'] = False # (m/s^2); ; -SubDyn['M2N7TAxe'] = False # (m/s^2); ; -SubDyn['M2N8TAxe'] = False # (m/s^2); ; -SubDyn['M2N9TAxe'] = False # (m/s^2); ; -SubDyn['M3N1TAxe'] = False # (m/s^2); ; -SubDyn['M3N2TAxe'] = False # (m/s^2); ; -SubDyn['M3N3TAxe'] = False # (m/s^2); ; -SubDyn['M3N4TAxe'] = False # (m/s^2); ; -SubDyn['M3N5TAxe'] = False # (m/s^2); ; -SubDyn['M3N6TAxe'] = False # (m/s^2); ; -SubDyn['M3N7TAxe'] = False # (m/s^2); ; -SubDyn['M3N8TAxe'] = False # (m/s^2); ; -SubDyn['M3N9TAxe'] = False # (m/s^2); ; -SubDyn['M4N1TAxe'] = False # (m/s^2); ; -SubDyn['M4N2TAxe'] = False # (m/s^2); ; -SubDyn['M4N3TAxe'] = False # (m/s^2); ; -SubDyn['M4N4TAxe'] = False # (m/s^2); ; -SubDyn['M4N5TAxe'] = False # (m/s^2); ; -SubDyn['M4N6TAxe'] = False # (m/s^2); ; -SubDyn['M4N7TAxe'] = False # (m/s^2); ; -SubDyn['M4N8TAxe'] = False # (m/s^2); ; -SubDyn['M4N9TAxe'] = False # (m/s^2); ; -SubDyn['M5N1TAxe'] = False # (m/s^2); ; -SubDyn['M5N2TAxe'] = False # (m/s^2); ; -SubDyn['M5N3TAxe'] = False # (m/s^2); ; -SubDyn['M5N4TAxe'] = False # (m/s^2); ; -SubDyn['M5N5TAxe'] = False # (m/s^2); ; -SubDyn['M5N6TAxe'] = False # (m/s^2); ; -SubDyn['M5N7TAxe'] = False # (m/s^2); ; -SubDyn['M5N8TAxe'] = False # (m/s^2); ; -SubDyn['M5N9TAxe'] = False # (m/s^2); ; -SubDyn['M6N1TAxe'] = False # (m/s^2); ; -SubDyn['M6N2TAxe'] = False # (m/s^2); ; -SubDyn['M6N3TAxe'] = False # (m/s^2); ; -SubDyn['M6N4TAxe'] = False # (m/s^2); ; -SubDyn['M6N5TAxe'] = False # (m/s^2); ; -SubDyn['M6N6TAxe'] = False # (m/s^2); ; -SubDyn['M6N7TAxe'] = False # (m/s^2); ; -SubDyn['M6N8TAxe'] = False # (m/s^2); ; -SubDyn['M6N9TAxe'] = False # (m/s^2); ; -SubDyn['M7N1TAxe'] = False # (m/s^2); ; -SubDyn['M7N2TAxe'] = False # (m/s^2); ; -SubDyn['M7N3TAxe'] = False # (m/s^2); ; -SubDyn['M7N4TAxe'] = False # (m/s^2); ; -SubDyn['M7N5TAxe'] = False # (m/s^2); ; -SubDyn['M7N6TAxe'] = False # (m/s^2); ; -SubDyn['M7N7TAxe'] = False # (m/s^2); ; -SubDyn['M7N8TAxe'] = False # (m/s^2); ; -SubDyn['M7N9TAxe'] = False # (m/s^2); ; -SubDyn['M8N1TAxe'] = False # (m/s^2); ; -SubDyn['M8N2TAxe'] = False # (m/s^2); ; -SubDyn['M8N3TAxe'] = False # (m/s^2); ; -SubDyn['M8N4TAxe'] = False # (m/s^2); ; -SubDyn['M8N5TAxe'] = False # (m/s^2); ; -SubDyn['M8N6TAxe'] = False # (m/s^2); ; -SubDyn['M8N7TAxe'] = False # (m/s^2); ; -SubDyn['M8N8TAxe'] = False # (m/s^2); ; -SubDyn['M8N9TAxe'] = False # (m/s^2); ; -SubDyn['M9N1TAxe'] = False # (m/s^2); ; -SubDyn['M9N2TAxe'] = False # (m/s^2); ; -SubDyn['M9N3TAxe'] = False # (m/s^2); ; -SubDyn['M9N4TAxe'] = False # (m/s^2); ; -SubDyn['M9N5TAxe'] = False # (m/s^2); ; -SubDyn['M9N6TAxe'] = False # (m/s^2); ; -SubDyn['M9N7TAxe'] = False # (m/s^2); ; -SubDyn['M9N8TAxe'] = False # (m/s^2); ; -SubDyn['M9N9TAxe'] = False # (m/s^2); ; -SubDyn['M1N1TAye'] = False # (m/s^2); ye component of the translational acceleration displacement at Node Nj of member Mi-Element Reference System; -SubDyn['M1N2TAye'] = False # (m/s^2); ; -SubDyn['M1N3TAye'] = False # (m/s^2); ; -SubDyn['M1N4TAye'] = False # (m/s^2); ; -SubDyn['M1N5TAye'] = False # (m/s^2); ; -SubDyn['M1N6TAye'] = False # (m/s^2); ; -SubDyn['M1N7TAye'] = False # (m/s^2); ; -SubDyn['M1N8TAye'] = False # (m/s^2); ; -SubDyn['M1N9TAye'] = False # (m/s^2); ; -SubDyn['M2N1TAye'] = False # (m/s^2); ; -SubDyn['M2N2TAye'] = False # (m/s^2); ; -SubDyn['M2N3TAye'] = False # (m/s^2); ; -SubDyn['M2N4TAye'] = False # (m/s^2); ; -SubDyn['M2N5TAye'] = False # (m/s^2); ; -SubDyn['M2N6TAye'] = False # (m/s^2); ; -SubDyn['M2N7TAye'] = False # (m/s^2); ; -SubDyn['M2N8TAye'] = False # (m/s^2); ; -SubDyn['M2N9TAye'] = False # (m/s^2); ; -SubDyn['M3N1TAye'] = False # (m/s^2); ; -SubDyn['M3N2TAye'] = False # (m/s^2); ; -SubDyn['M3N3TAye'] = False # (m/s^2); ; -SubDyn['M3N4TAye'] = False # (m/s^2); ; -SubDyn['M3N5TAye'] = False # (m/s^2); ; -SubDyn['M3N6TAye'] = False # (m/s^2); ; -SubDyn['M3N7TAye'] = False # (m/s^2); ; -SubDyn['M3N8TAye'] = False # (m/s^2); ; -SubDyn['M3N9TAye'] = False # (m/s^2); ; -SubDyn['M4N1TAye'] = False # (m/s^2); ; -SubDyn['M4N2TAye'] = False # (m/s^2); ; -SubDyn['M4N3TAye'] = False # (m/s^2); ; -SubDyn['M4N4TAye'] = False # (m/s^2); ; -SubDyn['M4N5TAye'] = False # (m/s^2); ; -SubDyn['M4N6TAye'] = False # (m/s^2); ; -SubDyn['M4N7TAye'] = False # (m/s^2); ; -SubDyn['M4N8TAye'] = False # (m/s^2); ; -SubDyn['M4N9TAye'] = False # (m/s^2); ; -SubDyn['M5N1TAye'] = False # (m/s^2); ; -SubDyn['M5N2TAye'] = False # (m/s^2); ; -SubDyn['M5N3TAye'] = False # (m/s^2); ; -SubDyn['M5N4TAye'] = False # (m/s^2); ; -SubDyn['M5N5TAye'] = False # (m/s^2); ; -SubDyn['M5N6TAye'] = False # (m/s^2); ; -SubDyn['M5N7TAye'] = False # (m/s^2); ; -SubDyn['M5N8TAye'] = False # (m/s^2); ; -SubDyn['M5N9TAye'] = False # (m/s^2); ; -SubDyn['M6N1TAye'] = False # (m/s^2); ; -SubDyn['M6N2TAye'] = False # (m/s^2); ; -SubDyn['M6N3TAye'] = False # (m/s^2); ; -SubDyn['M6N4TAye'] = False # (m/s^2); ; -SubDyn['M6N5TAye'] = False # (m/s^2); ; -SubDyn['M6N6TAye'] = False # (m/s^2); ; -SubDyn['M6N7TAye'] = False # (m/s^2); ; -SubDyn['M6N8TAye'] = False # (m/s^2); ; -SubDyn['M6N9TAye'] = False # (m/s^2); ; -SubDyn['M7N1TAye'] = False # (m/s^2); ; -SubDyn['M7N2TAye'] = False # (m/s^2); ; -SubDyn['M7N3TAye'] = False # (m/s^2); ; -SubDyn['M7N4TAye'] = False # (m/s^2); ; -SubDyn['M7N5TAye'] = False # (m/s^2); ; -SubDyn['M7N6TAye'] = False # (m/s^2); ; -SubDyn['M7N7TAye'] = False # (m/s^2); ; -SubDyn['M7N8TAye'] = False # (m/s^2); ; -SubDyn['M7N9TAye'] = False # (m/s^2); ; -SubDyn['M8N1TAye'] = False # (m/s^2); ; -SubDyn['M8N2TAye'] = False # (m/s^2); ; -SubDyn['M8N3TAye'] = False # (m/s^2); ; -SubDyn['M8N4TAye'] = False # (m/s^2); ; -SubDyn['M8N5TAye'] = False # (m/s^2); ; -SubDyn['M8N6TAye'] = False # (m/s^2); ; -SubDyn['M8N7TAye'] = False # (m/s^2); ; -SubDyn['M8N8TAye'] = False # (m/s^2); ; -SubDyn['M8N9TAye'] = False # (m/s^2); ; -SubDyn['M9N1TAye'] = False # (m/s^2); ; -SubDyn['M9N2TAye'] = False # (m/s^2); ; -SubDyn['M9N3TAye'] = False # (m/s^2); ; -SubDyn['M9N4TAye'] = False # (m/s^2); ; -SubDyn['M9N5TAye'] = False # (m/s^2); ; -SubDyn['M9N6TAye'] = False # (m/s^2); ; -SubDyn['M9N7TAye'] = False # (m/s^2); ; -SubDyn['M9N8TAye'] = False # (m/s^2); ; -SubDyn['M9N9TAye'] = False # (m/s^2); ; -SubDyn['M1N1TAze'] = False # (m/s^2); ze component of the translational acceleration displacement at Node Nj of member Mi-Element Reference System; -SubDyn['M1N2TAze'] = False # (m/s^2); ; -SubDyn['M1N3TAze'] = False # (m/s^2); ; -SubDyn['M1N4TAze'] = False # (m/s^2); ; -SubDyn['M1N5TAze'] = False # (m/s^2); ; -SubDyn['M1N6TAze'] = False # (m/s^2); ; -SubDyn['M1N7TAze'] = False # (m/s^2); ; -SubDyn['M1N8TAze'] = False # (m/s^2); ; -SubDyn['M1N9TAze'] = False # (m/s^2); ; -SubDyn['M2N1TAze'] = False # (m/s^2); ; -SubDyn['M2N2TAze'] = False # (m/s^2); ; -SubDyn['M2N3TAze'] = False # (m/s^2); ; -SubDyn['M2N4TAze'] = False # (m/s^2); ; -SubDyn['M2N5TAze'] = False # (m/s^2); ; -SubDyn['M2N6TAze'] = False # (m/s^2); ; -SubDyn['M2N7TAze'] = False # (m/s^2); ; -SubDyn['M2N8TAze'] = False # (m/s^2); ; -SubDyn['M2N9TAze'] = False # (m/s^2); ; -SubDyn['M3N1TAze'] = False # (m/s^2); ; -SubDyn['M3N2TAze'] = False # (m/s^2); ; -SubDyn['M3N3TAze'] = False # (m/s^2); ; -SubDyn['M3N4TAze'] = False # (m/s^2); ; -SubDyn['M3N5TAze'] = False # (m/s^2); ; -SubDyn['M3N6TAze'] = False # (m/s^2); ; -SubDyn['M3N7TAze'] = False # (m/s^2); ; -SubDyn['M3N8TAze'] = False # (m/s^2); ; -SubDyn['M3N9TAze'] = False # (m/s^2); ; -SubDyn['M4N1TAze'] = False # (m/s^2); ; -SubDyn['M4N2TAze'] = False # (m/s^2); ; -SubDyn['M4N3TAze'] = False # (m/s^2); ; -SubDyn['M4N4TAze'] = False # (m/s^2); ; -SubDyn['M4N5TAze'] = False # (m/s^2); ; -SubDyn['M4N6TAze'] = False # (m/s^2); ; -SubDyn['M4N7TAze'] = False # (m/s^2); ; -SubDyn['M4N8TAze'] = False # (m/s^2); ; -SubDyn['M4N9TAze'] = False # (m/s^2); ; -SubDyn['M5N1TAze'] = False # (m/s^2); ; -SubDyn['M5N2TAze'] = False # (m/s^2); ; -SubDyn['M5N3TAze'] = False # (m/s^2); ; -SubDyn['M5N4TAze'] = False # (m/s^2); ; -SubDyn['M5N5TAze'] = False # (m/s^2); ; -SubDyn['M5N6TAze'] = False # (m/s^2); ; -SubDyn['M5N7TAze'] = False # (m/s^2); ; -SubDyn['M5N8TAze'] = False # (m/s^2); ; -SubDyn['M5N9TAze'] = False # (m/s^2); ; -SubDyn['M6N1TAze'] = False # (m/s^2); ; -SubDyn['M6N2TAze'] = False # (m/s^2); ; -SubDyn['M6N3TAze'] = False # (m/s^2); ; -SubDyn['M6N4TAze'] = False # (m/s^2); ; -SubDyn['M6N5TAze'] = False # (m/s^2); ; -SubDyn['M6N6TAze'] = False # (m/s^2); ; -SubDyn['M6N7TAze'] = False # (m/s^2); ; -SubDyn['M6N8TAze'] = False # (m/s^2); ; -SubDyn['M6N9TAze'] = False # (m/s^2); ; -SubDyn['M7N1TAze'] = False # (m/s^2); ; -SubDyn['M7N2TAze'] = False # (m/s^2); ; -SubDyn['M7N3TAze'] = False # (m/s^2); ; -SubDyn['M7N4TAze'] = False # (m/s^2); ; -SubDyn['M7N5TAze'] = False # (m/s^2); ; -SubDyn['M7N6TAze'] = False # (m/s^2); ; -SubDyn['M7N7TAze'] = False # (m/s^2); ; -SubDyn['M7N8TAze'] = False # (m/s^2); ; -SubDyn['M7N9TAze'] = False # (m/s^2); ; -SubDyn['M8N1TAze'] = False # (m/s^2); ; -SubDyn['M8N2TAze'] = False # (m/s^2); ; -SubDyn['M8N3TAze'] = False # (m/s^2); ; -SubDyn['M8N4TAze'] = False # (m/s^2); ; -SubDyn['M8N5TAze'] = False # (m/s^2); ; -SubDyn['M8N6TAze'] = False # (m/s^2); ; -SubDyn['M8N7TAze'] = False # (m/s^2); ; -SubDyn['M8N8TAze'] = False # (m/s^2); ; -SubDyn['M8N9TAze'] = False # (m/s^2); ; -SubDyn['M9N1TAze'] = False # (m/s^2); ; -SubDyn['M9N2TAze'] = False # (m/s^2); ; -SubDyn['M9N3TAze'] = False # (m/s^2); ; -SubDyn['M9N4TAze'] = False # (m/s^2); ; -SubDyn['M9N5TAze'] = False # (m/s^2); ; -SubDyn['M9N6TAze'] = False # (m/s^2); ; -SubDyn['M9N7TAze'] = False # (m/s^2); ; -SubDyn['M9N8TAze'] = False # (m/s^2); ; -SubDyn['M9N9TAze'] = False # (m/s^2); ; -SubDyn['M1N1RAxe'] = False # (rad/s^2); xe component of the rotational acceleration displacement at Node Nj of member Mi-Element Reference System; -SubDyn['M1N2RAxe'] = False # (rad/s^2); ; -SubDyn['M1N3RAxe'] = False # (rad/s^2); ; -SubDyn['M1N4RAxe'] = False # (rad/s^2); ; -SubDyn['M1N5RAxe'] = False # (rad/s^2); ; -SubDyn['M1N6RAxe'] = False # (rad/s^2); ; -SubDyn['M1N7RAxe'] = False # (rad/s^2); ; -SubDyn['M1N8RAxe'] = False # (rad/s^2); ; -SubDyn['M1N9RAxe'] = False # (rad/s^2); ; -SubDyn['M2N1RAxe'] = False # (rad/s^2); ; -SubDyn['M2N2RAxe'] = False # (rad/s^2); ; -SubDyn['M2N3RAxe'] = False # (rad/s^2); ; -SubDyn['M2N4RAxe'] = False # (rad/s^2); ; -SubDyn['M2N5RAxe'] = False # (rad/s^2); ; -SubDyn['M2N6RAxe'] = False # (rad/s^2); ; -SubDyn['M2N7RAxe'] = False # (rad/s^2); ; -SubDyn['M2N8RAxe'] = False # (rad/s^2); ; -SubDyn['M2N9RAxe'] = False # (rad/s^2); ; -SubDyn['M3N1RAxe'] = False # (rad/s^2); ; -SubDyn['M3N2RAxe'] = False # (rad/s^2); ; -SubDyn['M3N3RAxe'] = False # (rad/s^2); ; -SubDyn['M3N4RAxe'] = False # (rad/s^2); ; -SubDyn['M3N5RAxe'] = False # (rad/s^2); ; -SubDyn['M3N6RAxe'] = False # (rad/s^2); ; -SubDyn['M3N7RAxe'] = False # (rad/s^2); ; -SubDyn['M3N8RAxe'] = False # (rad/s^2); ; -SubDyn['M3N9RAxe'] = False # (rad/s^2); ; -SubDyn['M4N1RAxe'] = False # (rad/s^2); ; -SubDyn['M4N2RAxe'] = False # (rad/s^2); ; -SubDyn['M4N3RAxe'] = False # (rad/s^2); ; -SubDyn['M4N4RAxe'] = False # (rad/s^2); ; -SubDyn['M4N5RAxe'] = False # (rad/s^2); ; -SubDyn['M4N6RAxe'] = False # (rad/s^2); ; -SubDyn['M4N7RAxe'] = False # (rad/s^2); ; -SubDyn['M4N8RAxe'] = False # (rad/s^2); ; -SubDyn['M4N9RAxe'] = False # (rad/s^2); ; -SubDyn['M5N1RAxe'] = False # (rad/s^2); ; -SubDyn['M5N2RAxe'] = False # (rad/s^2); ; -SubDyn['M5N3RAxe'] = False # (rad/s^2); ; -SubDyn['M5N4RAxe'] = False # (rad/s^2); ; -SubDyn['M5N5RAxe'] = False # (rad/s^2); ; -SubDyn['M5N6RAxe'] = False # (rad/s^2); ; -SubDyn['M5N7RAxe'] = False # (rad/s^2); ; -SubDyn['M5N8RAxe'] = False # (rad/s^2); ; -SubDyn['M5N9RAxe'] = False # (rad/s^2); ; -SubDyn['M6N1RAxe'] = False # (rad/s^2); ; -SubDyn['M6N2RAxe'] = False # (rad/s^2); ; -SubDyn['M6N3RAxe'] = False # (rad/s^2); ; -SubDyn['M6N4RAxe'] = False # (rad/s^2); ; -SubDyn['M6N5RAxe'] = False # (rad/s^2); ; -SubDyn['M6N6RAxe'] = False # (rad/s^2); ; -SubDyn['M6N7RAxe'] = False # (rad/s^2); ; -SubDyn['M6N8RAxe'] = False # (rad/s^2); ; -SubDyn['M6N9RAxe'] = False # (rad/s^2); ; -SubDyn['M7N1RAxe'] = False # (rad/s^2); ; -SubDyn['M7N2RAxe'] = False # (rad/s^2); ; -SubDyn['M7N3RAxe'] = False # (rad/s^2); ; -SubDyn['M7N4RAxe'] = False # (rad/s^2); ; -SubDyn['M7N5RAxe'] = False # (rad/s^2); ; -SubDyn['M7N6RAxe'] = False # (rad/s^2); ; -SubDyn['M7N7RAxe'] = False # (rad/s^2); ; -SubDyn['M7N8RAxe'] = False # (rad/s^2); ; -SubDyn['M7N9RAxe'] = False # (rad/s^2); ; -SubDyn['M8N1RAxe'] = False # (rad/s^2); ; -SubDyn['M8N2RAxe'] = False # (rad/s^2); ; -SubDyn['M8N3RAxe'] = False # (rad/s^2); ; -SubDyn['M8N4RAxe'] = False # (rad/s^2); ; -SubDyn['M8N5RAxe'] = False # (rad/s^2); ; -SubDyn['M8N6RAxe'] = False # (rad/s^2); ; -SubDyn['M8N7RAxe'] = False # (rad/s^2); ; -SubDyn['M8N8RAxe'] = False # (rad/s^2); ; -SubDyn['M8N9RAxe'] = False # (rad/s^2); ; -SubDyn['M9N1RAxe'] = False # (rad/s^2); ; -SubDyn['M9N2RAxe'] = False # (rad/s^2); ; -SubDyn['M9N3RAxe'] = False # (rad/s^2); ; -SubDyn['M9N4RAxe'] = False # (rad/s^2); ; -SubDyn['M9N5RAxe'] = False # (rad/s^2); ; -SubDyn['M9N6RAxe'] = False # (rad/s^2); ; -SubDyn['M9N7RAxe'] = False # (rad/s^2); ; -SubDyn['M9N8RAxe'] = False # (rad/s^2); ; -SubDyn['M9N9RAxe'] = False # (rad/s^2); ; -SubDyn['M1N1RAye'] = False # (rad/s^2); ye component of the rotational acceleration displacement at Node Nj of member Mi-Element Reference System; -SubDyn['M1N2RAye'] = False # (rad/s^2); ; -SubDyn['M1N3RAye'] = False # (rad/s^2); ; -SubDyn['M1N4RAye'] = False # (rad/s^2); ; -SubDyn['M1N5RAye'] = False # (rad/s^2); ; -SubDyn['M1N6RAye'] = False # (rad/s^2); ; -SubDyn['M1N7RAye'] = False # (rad/s^2); ; -SubDyn['M1N8RAye'] = False # (rad/s^2); ; -SubDyn['M1N9RAye'] = False # (rad/s^2); ; -SubDyn['M2N1RAye'] = False # (rad/s^2); ; -SubDyn['M2N2RAye'] = False # (rad/s^2); ; -SubDyn['M2N3RAye'] = False # (rad/s^2); ; -SubDyn['M2N4RAye'] = False # (rad/s^2); ; -SubDyn['M2N5RAye'] = False # (rad/s^2); ; -SubDyn['M2N6RAye'] = False # (rad/s^2); ; -SubDyn['M2N7RAye'] = False # (rad/s^2); ; -SubDyn['M2N8RAye'] = False # (rad/s^2); ; -SubDyn['M2N9RAye'] = False # (rad/s^2); ; -SubDyn['M3N1RAye'] = False # (rad/s^2); ; -SubDyn['M3N2RAye'] = False # (rad/s^2); ; -SubDyn['M3N3RAye'] = False # (rad/s^2); ; -SubDyn['M3N4RAye'] = False # (rad/s^2); ; -SubDyn['M3N5RAye'] = False # (rad/s^2); ; -SubDyn['M3N6RAye'] = False # (rad/s^2); ; -SubDyn['M3N7RAye'] = False # (rad/s^2); ; -SubDyn['M3N8RAye'] = False # (rad/s^2); ; -SubDyn['M3N9RAye'] = False # (rad/s^2); ; -SubDyn['M4N1RAye'] = False # (rad/s^2); ; -SubDyn['M4N2RAye'] = False # (rad/s^2); ; -SubDyn['M4N3RAye'] = False # (rad/s^2); ; -SubDyn['M4N4RAye'] = False # (rad/s^2); ; -SubDyn['M4N5RAye'] = False # (rad/s^2); ; -SubDyn['M4N6RAye'] = False # (rad/s^2); ; -SubDyn['M4N7RAye'] = False # (rad/s^2); ; -SubDyn['M4N8RAye'] = False # (rad/s^2); ; -SubDyn['M4N9RAye'] = False # (rad/s^2); ; -SubDyn['M5N1RAye'] = False # (rad/s^2); ; -SubDyn['M5N2RAye'] = False # (rad/s^2); ; -SubDyn['M5N3RAye'] = False # (rad/s^2); ; -SubDyn['M5N4RAye'] = False # (rad/s^2); ; -SubDyn['M5N5RAye'] = False # (rad/s^2); ; -SubDyn['M5N6RAye'] = False # (rad/s^2); ; -SubDyn['M5N7RAye'] = False # (rad/s^2); ; -SubDyn['M5N8RAye'] = False # (rad/s^2); ; -SubDyn['M5N9RAye'] = False # (rad/s^2); ; -SubDyn['M6N1RAye'] = False # (rad/s^2); ; -SubDyn['M6N2RAye'] = False # (rad/s^2); ; -SubDyn['M6N3RAye'] = False # (rad/s^2); ; -SubDyn['M6N4RAye'] = False # (rad/s^2); ; -SubDyn['M6N5RAye'] = False # (rad/s^2); ; -SubDyn['M6N6RAye'] = False # (rad/s^2); ; -SubDyn['M6N7RAye'] = False # (rad/s^2); ; -SubDyn['M6N8RAye'] = False # (rad/s^2); ; -SubDyn['M6N9RAye'] = False # (rad/s^2); ; -SubDyn['M7N1RAye'] = False # (rad/s^2); ; -SubDyn['M7N2RAye'] = False # (rad/s^2); ; -SubDyn['M7N3RAye'] = False # (rad/s^2); ; -SubDyn['M7N4RAye'] = False # (rad/s^2); ; -SubDyn['M7N5RAye'] = False # (rad/s^2); ; -SubDyn['M7N6RAye'] = False # (rad/s^2); ; -SubDyn['M7N7RAye'] = False # (rad/s^2); ; -SubDyn['M7N8RAye'] = False # (rad/s^2); ; -SubDyn['M7N9RAye'] = False # (rad/s^2); ; -SubDyn['M8N1RAye'] = False # (rad/s^2); ; -SubDyn['M8N2RAye'] = False # (rad/s^2); ; -SubDyn['M8N3RAye'] = False # (rad/s^2); ; -SubDyn['M8N4RAye'] = False # (rad/s^2); ; -SubDyn['M8N5RAye'] = False # (rad/s^2); ; -SubDyn['M8N6RAye'] = False # (rad/s^2); ; -SubDyn['M8N7RAye'] = False # (rad/s^2); ; -SubDyn['M8N8RAye'] = False # (rad/s^2); ; -SubDyn['M8N9RAye'] = False # (rad/s^2); ; -SubDyn['M9N1RAye'] = False # (rad/s^2); ; -SubDyn['M9N2RAye'] = False # (rad/s^2); ; -SubDyn['M9N3RAye'] = False # (rad/s^2); ; -SubDyn['M9N4RAye'] = False # (rad/s^2); ; -SubDyn['M9N5RAye'] = False # (rad/s^2); ; -SubDyn['M9N6RAye'] = False # (rad/s^2); ; -SubDyn['M9N7RAye'] = False # (rad/s^2); ; -SubDyn['M9N8RAye'] = False # (rad/s^2); ; -SubDyn['M9N9RAye'] = False # (rad/s^2); ; -SubDyn['M1N1RAze'] = False # (rad/s^2); ze component of the rotational acceleration displacement at Node Nj of member Mi-Element Reference System; -SubDyn['M1N2RAze'] = False # (rad/s^2); ; -SubDyn['M1N3RAze'] = False # (rad/s^2); ; -SubDyn['M1N4RAze'] = False # (rad/s^2); ; -SubDyn['M1N5RAze'] = False # (rad/s^2); ; -SubDyn['M1N6RAze'] = False # (rad/s^2); ; -SubDyn['M1N7RAze'] = False # (rad/s^2); ; -SubDyn['M1N8RAze'] = False # (rad/s^2); ; -SubDyn['M1N9RAze'] = False # (rad/s^2); ; -SubDyn['M2N1RAze'] = False # (rad/s^2); ; -SubDyn['M2N2RAze'] = False # (rad/s^2); ; -SubDyn['M2N3RAze'] = False # (rad/s^2); ; -SubDyn['M2N4RAze'] = False # (rad/s^2); ; -SubDyn['M2N5RAze'] = False # (rad/s^2); ; -SubDyn['M2N6RAze'] = False # (rad/s^2); ; -SubDyn['M2N7RAze'] = False # (rad/s^2); ; -SubDyn['M2N8RAze'] = False # (rad/s^2); ; -SubDyn['M2N9RAze'] = False # (rad/s^2); ; -SubDyn['M3N1RAze'] = False # (rad/s^2); ; -SubDyn['M3N2RAze'] = False # (rad/s^2); ; -SubDyn['M3N3RAze'] = False # (rad/s^2); ; -SubDyn['M3N4RAze'] = False # (rad/s^2); ; -SubDyn['M3N5RAze'] = False # (rad/s^2); ; -SubDyn['M3N6RAze'] = False # (rad/s^2); ; -SubDyn['M3N7RAze'] = False # (rad/s^2); ; -SubDyn['M3N8RAze'] = False # (rad/s^2); ; -SubDyn['M3N9RAze'] = False # (rad/s^2); ; -SubDyn['M4N1RAze'] = False # (rad/s^2); ; -SubDyn['M4N2RAze'] = False # (rad/s^2); ; -SubDyn['M4N3RAze'] = False # (rad/s^2); ; -SubDyn['M4N4RAze'] = False # (rad/s^2); ; -SubDyn['M4N5RAze'] = False # (rad/s^2); ; -SubDyn['M4N6RAze'] = False # (rad/s^2); ; -SubDyn['M4N7RAze'] = False # (rad/s^2); ; -SubDyn['M4N8RAze'] = False # (rad/s^2); ; -SubDyn['M4N9RAze'] = False # (rad/s^2); ; -SubDyn['M5N1RAze'] = False # (rad/s^2); ; -SubDyn['M5N2RAze'] = False # (rad/s^2); ; -SubDyn['M5N3RAze'] = False # (rad/s^2); ; -SubDyn['M5N4RAze'] = False # (rad/s^2); ; -SubDyn['M5N5RAze'] = False # (rad/s^2); ; -SubDyn['M5N6RAze'] = False # (rad/s^2); ; -SubDyn['M5N7RAze'] = False # (rad/s^2); ; -SubDyn['M5N8RAze'] = False # (rad/s^2); ; -SubDyn['M5N9RAze'] = False # (rad/s^2); ; -SubDyn['M6N1RAze'] = False # (rad/s^2); ; -SubDyn['M6N2RAze'] = False # (rad/s^2); ; -SubDyn['M6N3RAze'] = False # (rad/s^2); ; -SubDyn['M6N4RAze'] = False # (rad/s^2); ; -SubDyn['M6N5RAze'] = False # (rad/s^2); ; -SubDyn['M6N6RAze'] = False # (rad/s^2); ; -SubDyn['M6N7RAze'] = False # (rad/s^2); ; -SubDyn['M6N8RAze'] = False # (rad/s^2); ; -SubDyn['M6N9RAze'] = False # (rad/s^2); ; -SubDyn['M7N1RAze'] = False # (rad/s^2); ; -SubDyn['M7N2RAze'] = False # (rad/s^2); ; -SubDyn['M7N3RAze'] = False # (rad/s^2); ; -SubDyn['M7N4RAze'] = False # (rad/s^2); ; -SubDyn['M7N5RAze'] = False # (rad/s^2); ; -SubDyn['M7N6RAze'] = False # (rad/s^2); ; -SubDyn['M7N7RAze'] = False # (rad/s^2); ; -SubDyn['M7N8RAze'] = False # (rad/s^2); ; -SubDyn['M7N9RAze'] = False # (rad/s^2); ; -SubDyn['M8N1RAze'] = False # (rad/s^2); ; -SubDyn['M8N2RAze'] = False # (rad/s^2); ; -SubDyn['M8N3RAze'] = False # (rad/s^2); ; -SubDyn['M8N4RAze'] = False # (rad/s^2); ; -SubDyn['M8N5RAze'] = False # (rad/s^2); ; -SubDyn['M8N6RAze'] = False # (rad/s^2); ; -SubDyn['M8N7RAze'] = False # (rad/s^2); ; -SubDyn['M8N8RAze'] = False # (rad/s^2); ; -SubDyn['M8N9RAze'] = False # (rad/s^2); ; -SubDyn['M9N1RAze'] = False # (rad/s^2); ; -SubDyn['M9N2RAze'] = False # (rad/s^2); ; -SubDyn['M9N3RAze'] = False # (rad/s^2); ; -SubDyn['M9N4RAze'] = False # (rad/s^2); ; -SubDyn['M9N5RAze'] = False # (rad/s^2); ; -SubDyn['M9N6RAze'] = False # (rad/s^2); ; -SubDyn['M9N7RAze'] = False # (rad/s^2); ; -SubDyn['M9N8RAze'] = False # (rad/s^2); ; -SubDyn['M9N9RAze'] = False # (rad/s^2); ; +# Member Forces (MxxNxChannelName) +SubDyn['FKxe'] = False # (N); ; +SubDyn['FKye'] = False # (N); ; +SubDyn['FKze'] = False # (N); ; +SubDyn['FMxe'] = False # (N); ; +SubDyn['FMye'] = False # (N); ; +SubDyn['FMze'] = False # (N); ; +SubDyn['MKxe'] = False # (N*m); ; +SubDyn['MKye'] = False # (N*m); ; +SubDyn['MKze'] = False # (N*m); ; +SubDyn['MMxe'] = False # (N*m); ; +SubDyn['MMye'] = False # (N*m); ; +SubDyn['MMze'] = False # (N*m); ; + +# Displacements (MxxNxChannelName) +SubDyn['TDxss'] = False # (m); ; +SubDyn['TDyss'] = False # (m); ; +SubDyn['TDzss'] = False # (m); ; +SubDyn['RDxe'] = False # (rad); ; +SubDyn['RDye'] = False # (rad); ; +SubDyn['RDze'] = False # (rad); ; + +# Accelerations (MxxNxChannelName) +SubDyn['TAxe'] = False # (m/s^2); ; +SubDyn['TAye'] = False # (m/s^2); ; +SubDyn['TAze'] = False # (m/s^2); ; +SubDyn['RAxe'] = False # (rad/s^2); ; +SubDyn['RAye'] = False # (rad/s^2); ; +SubDyn['RAze'] = False # (rad/s^2); ; # Reactions -SubDyn['ReactFXss'] = False # (N); Base Reaction Force along Xss; -SubDyn['ReactFYss'] = False # (N); Base Reaction Force along Yss; -SubDyn['ReactFZss'] = False # (N); Base Reaction Force along Zss; -SubDyn['ReactMXss'] = False # (Nm); Base Reaction Moment along Xss; -SubDyn['ReactMYss'] = False # (Nm); Base Reaction Moment along Yss; -SubDyn['ReactMZss'] = False # (Nm); Base Reaction Moment along Zss; -SubDyn['IntfFXss'] = False # (N); Interface Reaction Force along Xss; -SubDyn['IntfFYss'] = False # (N); Interface Reaction Force along Yss; -SubDyn['IntfFZss'] = False # (N); Interface Reaction Force along Zss; -SubDyn['IntfMXss'] = False # (Nm); Interface Reaction Moment along Xss; -SubDyn['IntfMYss'] = False # (Nm); Interface Reaction Moment along Yss; -SubDyn['IntfMZss'] = False # (Nm); Interface Reaction Moment along Zss; +SubDyn['ReactFXss'] = False # (N); ; +SubDyn['ReactFYss'] = False # (N); ; +SubDyn['ReactFZss'] = False # (N); ; +SubDyn['ReactMXss'] = False # (N*m); ; +SubDyn['ReactMYss'] = False # (N*m); ; +SubDyn['ReactMZss'] = False # (N*m); ; +SubDyn['IntfFXss'] = False # (N); ; +SubDyn['IntfFYss'] = False # (N); ; +SubDyn['IntfFZss'] = False # (N); ; +SubDyn['IntfMXss'] = False # (N*m); ; +SubDyn['IntfMYss'] = False # (N*m); ; +SubDyn['IntfMZss'] = False # (N*m); ; # Interface Deflections -SubDyn['IntfTDXss'] = False # (m); Interface Deflection along Xss; -SubDyn['IntfTDYss'] = False # (m); Interface Deflection along Yss; -SubDyn['IntfTDZss'] = False # (m); Interface Deflection along Zss; -SubDyn['IntfRDXss'] = False # (rad); Interface Angular Deflection along Xss; -SubDyn['IntfRDYss'] = False # (rad); Interface Angular Deflection along Yss; -SubDyn['IntfRDZss'] = False # (rad); Interface Angular Deflection along Zss; +SubDyn['IntfTDXss'] = False # (m); ; +SubDyn['IntfTDYss'] = False # (m); ; +SubDyn['IntfTDZss'] = False # (m); ; +SubDyn['IntfRDXss'] = False # (rad); ; +SubDyn['IntfRDYss'] = False # (rad); ; +SubDyn['IntfRDZss'] = False # (rad); ; # Interface Accelerations -SubDyn['IntfTAXss'] = False # (m/s^2); Interface Acceleration along Xss; -SubDyn['IntfTAYss'] = False # (m/s^2); Interface Acceleration along Yss; -SubDyn['IntfTAZss'] = False # (m/s^2); Interface Acceleration along Zss; -SubDyn['IntfRAXss'] = False # (rad/s^2); Interface Angular Acceleration along Xss; -SubDyn['IntfRAYss'] = False # (rad/s^2); Interface Angular Acceleration along Yss; -SubDyn['IntfRAZss'] = False # (rad/s^2); Interface Angular Acceleration along Zss; +SubDyn['IntfTAXss'] = False # (m/s^2); ; +SubDyn['IntfTAYss'] = False # (m/s^2); ; +SubDyn['IntfTAZss'] = False # (m/s^2); ; +SubDyn['IntfRAXss'] = False # (rad/s^2); ; +SubDyn['IntfRAYss'] = False # (rad/s^2); ; +SubDyn['IntfRAZss'] = False # (rad/s^2); ; + +# Modal Parameters (NameXX for mode number XX) +SubDyn['SSqm'] = False # (-); ; +SubDyn['SSqmd'] = False # (1/s); ; +SubDyn['SSqmdd'] = False # (1/s^2); ; -# Modal Parameters -SubDyn['SSqm01'] = False # (--); Modal Parameter (01-99) values; -SubDyn['SSqm02'] = False # (--); ; -SubDyn['SSqm03'] = False # (--); ; -SubDyn['SSqm04'] = False # (--); ; -SubDyn['SSqm05'] = False # (--); ; -SubDyn['SSqm06'] = False # (--); ; -SubDyn['SSqm07'] = False # (--); ; -SubDyn['SSqm08'] = False # (--); ; -SubDyn['SSqm09'] = False # (--); ; -SubDyn['SSqm10'] = False # (--); ; -SubDyn['SSqm11'] = False # (--); ; -SubDyn['SSqm12'] = False # (--); ; -SubDyn['SSqm13'] = False # (--); ; -SubDyn['SSqm14'] = False # (--); ; -SubDyn['SSqm15'] = False # (--); ; -SubDyn['SSqm16'] = False # (--); ; -SubDyn['SSqm17'] = False # (--); ; -SubDyn['SSqm18'] = False # (--); ; -SubDyn['SSqm19'] = False # (--); ; -SubDyn['SSqm20'] = False # (--); ; -SubDyn['SSqm21'] = False # (--); ; -SubDyn['SSqm22'] = False # (--); ; -SubDyn['SSqm23'] = False # (--); ; -SubDyn['SSqm24'] = False # (--); ; -SubDyn['SSqm25'] = False # (--); ; -SubDyn['SSqm26'] = False # (--); ; -SubDyn['SSqm27'] = False # (--); ; -SubDyn['SSqm28'] = False # (--); ; -SubDyn['SSqm29'] = False # (--); ; -SubDyn['SSqm30'] = False # (--); ; -SubDyn['SSqm31'] = False # (--); ; -SubDyn['SSqm32'] = False # (--); ; -SubDyn['SSqm33'] = False # (--); ; -SubDyn['SSqm34'] = False # (--); ; -SubDyn['SSqm35'] = False # (--); ; -SubDyn['SSqm36'] = False # (--); ; -SubDyn['SSqm37'] = False # (--); ; -SubDyn['SSqm38'] = False # (--); ; -SubDyn['SSqm39'] = False # (--); ; -SubDyn['SSqm40'] = False # (--); ; -SubDyn['SSqm41'] = False # (--); ; -SubDyn['SSqm42'] = False # (--); ; -SubDyn['SSqm43'] = False # (--); ; -SubDyn['SSqm44'] = False # (--); ; -SubDyn['SSqm45'] = False # (--); ; -SubDyn['SSqm46'] = False # (--); ; -SubDyn['SSqm47'] = False # (--); ; -SubDyn['SSqm48'] = False # (--); ; -SubDyn['SSqm49'] = False # (--); ; -SubDyn['SSqm50'] = False # (--); ; -SubDyn['SSqm51'] = False # (--); ; -SubDyn['SSqm52'] = False # (--); ; -SubDyn['SSqm53'] = False # (--); ; -SubDyn['SSqm54'] = False # (--); ; -SubDyn['SSqm55'] = False # (--); ; -SubDyn['SSqm56'] = False # (--); ; -SubDyn['SSqm57'] = False # (--); ; -SubDyn['SSqm58'] = False # (--); ; -SubDyn['SSqm59'] = False # (--); ; -SubDyn['SSqm60'] = False # (--); ; -SubDyn['SSqm61'] = False # (--); ; -SubDyn['SSqm62'] = False # (--); ; -SubDyn['SSqm63'] = False # (--); ; -SubDyn['SSqm64'] = False # (--); ; -SubDyn['SSqm65'] = False # (--); ; -SubDyn['SSqm66'] = False # (--); ; -SubDyn['SSqm67'] = False # (--); ; -SubDyn['SSqm68'] = False # (--); ; -SubDyn['SSqm69'] = False # (--); ; -SubDyn['SSqm70'] = False # (--); ; -SubDyn['SSqm71'] = False # (--); ; -SubDyn['SSqm72'] = False # (--); ; -SubDyn['SSqm73'] = False # (--); ; -SubDyn['SSqm74'] = False # (--); ; -SubDyn['SSqm75'] = False # (--); ; -SubDyn['SSqm76'] = False # (--); ; -SubDyn['SSqm77'] = False # (--); ; -SubDyn['SSqm78'] = False # (--); ; -SubDyn['SSqm79'] = False # (--); ; -SubDyn['SSqm80'] = False # (--); ; -SubDyn['SSqm81'] = False # (--); ; -SubDyn['SSqm82'] = False # (--); ; -SubDyn['SSqm83'] = False # (--); ; -SubDyn['SSqm84'] = False # (--); ; -SubDyn['SSqm85'] = False # (--); ; -SubDyn['SSqm86'] = False # (--); ; -SubDyn['SSqm87'] = False # (--); ; -SubDyn['SSqm88'] = False # (--); ; -SubDyn['SSqm89'] = False # (--); ; -SubDyn['SSqm90'] = False # (--); ; -SubDyn['SSqm91'] = False # (--); ; -SubDyn['SSqm92'] = False # (--); ; -SubDyn['SSqm93'] = False # (--); ; -SubDyn['SSqm94'] = False # (--); ; -SubDyn['SSqm95'] = False # (--); ; -SubDyn['SSqm96'] = False # (--); ; -SubDyn['SSqm97'] = False # (--); ; -SubDyn['SSqm98'] = False # (--); ; -SubDyn['SSqm99'] = False # (--); ; -SubDyn['SSqmd01'] = False # (1/s); Modal Parameter (01-99) time derivatives; -SubDyn['SSqmd02'] = False # (1/s); ; -SubDyn['SSqmd03'] = False # (1/s); ; -SubDyn['SSqmd04'] = False # (1/s); ; -SubDyn['SSqmd05'] = False # (1/s); ; -SubDyn['SSqmd06'] = False # (1/s); ; -SubDyn['SSqmd07'] = False # (1/s); ; -SubDyn['SSqmd08'] = False # (1/s); ; -SubDyn['SSqmd09'] = False # (1/s); ; -SubDyn['SSqmd10'] = False # (1/s); ; -SubDyn['SSqmd11'] = False # (1/s); ; -SubDyn['SSqmd12'] = False # (1/s); ; -SubDyn['SSqmd13'] = False # (1/s); ; -SubDyn['SSqmd14'] = False # (1/s); ; -SubDyn['SSqmd15'] = False # (1/s); ; -SubDyn['SSqmd16'] = False # (1/s); ; -SubDyn['SSqmd17'] = False # (1/s); ; -SubDyn['SSqmd18'] = False # (1/s); ; -SubDyn['SSqmd19'] = False # (1/s); ; -SubDyn['SSqmd20'] = False # (1/s); ; -SubDyn['SSqmd21'] = False # (1/s); ; -SubDyn['SSqmd22'] = False # (1/s); ; -SubDyn['SSqmd23'] = False # (1/s); ; -SubDyn['SSqmd24'] = False # (1/s); ; -SubDyn['SSqmd25'] = False # (1/s); ; -SubDyn['SSqmd26'] = False # (1/s); ; -SubDyn['SSqmd27'] = False # (1/s); ; -SubDyn['SSqmd28'] = False # (1/s); ; -SubDyn['SSqmd29'] = False # (1/s); ; -SubDyn['SSqmd30'] = False # (1/s); ; -SubDyn['SSqmd31'] = False # (1/s); ; -SubDyn['SSqmd32'] = False # (1/s); ; -SubDyn['SSqmd33'] = False # (1/s); ; -SubDyn['SSqmd34'] = False # (1/s); ; -SubDyn['SSqmd35'] = False # (1/s); ; -SubDyn['SSqmd36'] = False # (1/s); ; -SubDyn['SSqmd37'] = False # (1/s); ; -SubDyn['SSqmd38'] = False # (1/s); ; -SubDyn['SSqmd39'] = False # (1/s); ; -SubDyn['SSqmd40'] = False # (1/s); ; -SubDyn['SSqmd41'] = False # (1/s); ; -SubDyn['SSqmd42'] = False # (1/s); ; -SubDyn['SSqmd43'] = False # (1/s); ; -SubDyn['SSqmd44'] = False # (1/s); ; -SubDyn['SSqmd45'] = False # (1/s); ; -SubDyn['SSqmd46'] = False # (1/s); ; -SubDyn['SSqmd47'] = False # (1/s); ; -SubDyn['SSqmd48'] = False # (1/s); ; -SubDyn['SSqmd49'] = False # (1/s); ; -SubDyn['SSqmd50'] = False # (1/s); ; -SubDyn['SSqmd51'] = False # (1/s); ; -SubDyn['SSqmd52'] = False # (1/s); ; -SubDyn['SSqmd53'] = False # (1/s); ; -SubDyn['SSqmd54'] = False # (1/s); ; -SubDyn['SSqmd55'] = False # (1/s); ; -SubDyn['SSqmd56'] = False # (1/s); ; -SubDyn['SSqmd57'] = False # (1/s); ; -SubDyn['SSqmd58'] = False # (1/s); ; -SubDyn['SSqmd59'] = False # (1/s); ; -SubDyn['SSqmd60'] = False # (1/s); ; -SubDyn['SSqmd61'] = False # (1/s); ; -SubDyn['SSqmd62'] = False # (1/s); ; -SubDyn['SSqmd63'] = False # (1/s); ; -SubDyn['SSqmd64'] = False # (1/s); ; -SubDyn['SSqmd65'] = False # (1/s); ; -SubDyn['SSqmd66'] = False # (1/s); ; -SubDyn['SSqmd67'] = False # (1/s); ; -SubDyn['SSqmd68'] = False # (1/s); ; -SubDyn['SSqmd69'] = False # (1/s); ; -SubDyn['SSqmd70'] = False # (1/s); ; -SubDyn['SSqmd71'] = False # (1/s); ; -SubDyn['SSqmd72'] = False # (1/s); ; -SubDyn['SSqmd73'] = False # (1/s); ; -SubDyn['SSqmd74'] = False # (1/s); ; -SubDyn['SSqmd75'] = False # (1/s); ; -SubDyn['SSqmd76'] = False # (1/s); ; -SubDyn['SSqmd77'] = False # (1/s); ; -SubDyn['SSqmd78'] = False # (1/s); ; -SubDyn['SSqmd79'] = False # (1/s); ; -SubDyn['SSqmd80'] = False # (1/s); ; -SubDyn['SSqmd81'] = False # (1/s); ; -SubDyn['SSqmd82'] = False # (1/s); ; -SubDyn['SSqmd83'] = False # (1/s); ; -SubDyn['SSqmd84'] = False # (1/s); ; -SubDyn['SSqmd85'] = False # (1/s); ; -SubDyn['SSqmd86'] = False # (1/s); ; -SubDyn['SSqmd87'] = False # (1/s); ; -SubDyn['SSqmd88'] = False # (1/s); ; -SubDyn['SSqmd89'] = False # (1/s); ; -SubDyn['SSqmd90'] = False # (1/s); ; -SubDyn['SSqmd91'] = False # (1/s); ; -SubDyn['SSqmd92'] = False # (1/s); ; -SubDyn['SSqmd93'] = False # (1/s); ; -SubDyn['SSqmd94'] = False # (1/s); ; -SubDyn['SSqmd95'] = False # (1/s); ; -SubDyn['SSqmd96'] = False # (1/s); ; -SubDyn['SSqmd97'] = False # (1/s); ; -SubDyn['SSqmd98'] = False # (1/s); ; -SubDyn['SSqmd99'] = False # (1/s); ; -SubDyn['SSqmdd01'] = False # (1/s^2); Modal Parameter (01-99) 2nd time derivatives; -SubDyn['SSqmdd02'] = False # (1/s^2); ; -SubDyn['SSqmdd03'] = False # (1/s^2); ; -SubDyn['SSqmdd04'] = False # (1/s^2); ; -SubDyn['SSqmdd05'] = False # (1/s^2); ; -SubDyn['SSqmdd06'] = False # (1/s^2); ; -SubDyn['SSqmdd07'] = False # (1/s^2); ; -SubDyn['SSqmdd08'] = False # (1/s^2); ; -SubDyn['SSqmdd09'] = False # (1/s^2); ; -SubDyn['SSqmdd10'] = False # (1/s^2); ; -SubDyn['SSqmdd11'] = False # (1/s^2); ; -SubDyn['SSqmdd12'] = False # (1/s^2); ; -SubDyn['SSqmdd13'] = False # (1/s^2); ; -SubDyn['SSqmdd14'] = False # (1/s^2); ; -SubDyn['SSqmdd15'] = False # (1/s^2); ; -SubDyn['SSqmdd16'] = False # (1/s^2); ; -SubDyn['SSqmdd17'] = False # (1/s^2); ; -SubDyn['SSqmdd18'] = False # (1/s^2); ; -SubDyn['SSqmdd19'] = False # (1/s^2); ; -SubDyn['SSqmdd20'] = False # (1/s^2); ; -SubDyn['SSqmdd21'] = False # (1/s^2); ; -SubDyn['SSqmdd22'] = False # (1/s^2); ; -SubDyn['SSqmdd23'] = False # (1/s^2); ; -SubDyn['SSqmdd24'] = False # (1/s^2); ; -SubDyn['SSqmdd25'] = False # (1/s^2); ; -SubDyn['SSqmdd26'] = False # (1/s^2); ; -SubDyn['SSqmdd27'] = False # (1/s^2); ; -SubDyn['SSqmdd28'] = False # (1/s^2); ; -SubDyn['SSqmdd29'] = False # (1/s^2); ; -SubDyn['SSqmdd30'] = False # (1/s^2); ; -SubDyn['SSqmdd31'] = False # (1/s^2); ; -SubDyn['SSqmdd32'] = False # (1/s^2); ; -SubDyn['SSqmdd33'] = False # (1/s^2); ; -SubDyn['SSqmdd34'] = False # (1/s^2); ; -SubDyn['SSqmdd35'] = False # (1/s^2); ; -SubDyn['SSqmdd36'] = False # (1/s^2); ; -SubDyn['SSqmdd37'] = False # (1/s^2); ; -SubDyn['SSqmdd38'] = False # (1/s^2); ; -SubDyn['SSqmdd39'] = False # (1/s^2); ; -SubDyn['SSqmdd40'] = False # (1/s^2); ; -SubDyn['SSqmdd41'] = False # (1/s^2); ; -SubDyn['SSqmdd42'] = False # (1/s^2); ; -SubDyn['SSqmdd43'] = False # (1/s^2); ; -SubDyn['SSqmdd44'] = False # (1/s^2); ; -SubDyn['SSqmdd45'] = False # (1/s^2); ; -SubDyn['SSqmdd46'] = False # (1/s^2); ; -SubDyn['SSqmdd47'] = False # (1/s^2); ; -SubDyn['SSqmdd48'] = False # (1/s^2); ; -SubDyn['SSqmdd49'] = False # (1/s^2); ; -SubDyn['SSqmdd50'] = False # (1/s^2); ; -SubDyn['SSqmdd51'] = False # (1/s^2); ; -SubDyn['SSqmdd52'] = False # (1/s^2); ; -SubDyn['SSqmdd53'] = False # (1/s^2); ; -SubDyn['SSqmdd54'] = False # (1/s^2); ; -SubDyn['SSqmdd55'] = False # (1/s^2); ; -SubDyn['SSqmdd56'] = False # (1/s^2); ; -SubDyn['SSqmdd57'] = False # (1/s^2); ; -SubDyn['SSqmdd58'] = False # (1/s^2); ; -SubDyn['SSqmdd59'] = False # (1/s^2); ; -SubDyn['SSqmdd60'] = False # (1/s^2); ; -SubDyn['SSqmdd61'] = False # (1/s^2); ; -SubDyn['SSqmdd62'] = False # (1/s^2); ; -SubDyn['SSqmdd63'] = False # (1/s^2); ; -SubDyn['SSqmdd64'] = False # (1/s^2); ; -SubDyn['SSqmdd65'] = False # (1/s^2); ; -SubDyn['SSqmdd66'] = False # (1/s^2); ; -SubDyn['SSqmdd67'] = False # (1/s^2); ; -SubDyn['SSqmdd68'] = False # (1/s^2); ; -SubDyn['SSqmdd69'] = False # (1/s^2); ; -SubDyn['SSqmdd70'] = False # (1/s^2); ; -SubDyn['SSqmdd71'] = False # (1/s^2); ; -SubDyn['SSqmdd72'] = False # (1/s^2); ; -SubDyn['SSqmdd73'] = False # (1/s^2); ; -SubDyn['SSqmdd74'] = False # (1/s^2); ; -SubDyn['SSqmdd75'] = False # (1/s^2); ; -SubDyn['SSqmdd76'] = False # (1/s^2); ; -SubDyn['SSqmdd77'] = False # (1/s^2); ; -SubDyn['SSqmdd78'] = False # (1/s^2); ; -SubDyn['SSqmdd79'] = False # (1/s^2); ; -SubDyn['SSqmdd80'] = False # (1/s^2); ; -SubDyn['SSqmdd81'] = False # (1/s^2); ; -SubDyn['SSqmdd82'] = False # (1/s^2); ; -SubDyn['SSqmdd83'] = False # (1/s^2); ; -SubDyn['SSqmdd84'] = False # (1/s^2); ; -SubDyn['SSqmdd85'] = False # (1/s^2); ; -SubDyn['SSqmdd86'] = False # (1/s^2); ; -SubDyn['SSqmdd87'] = False # (1/s^2); ; -SubDyn['SSqmdd88'] = False # (1/s^2); ; -SubDyn['SSqmdd89'] = False # (1/s^2); ; -SubDyn['SSqmdd90'] = False # (1/s^2); ; -SubDyn['SSqmdd91'] = False # (1/s^2); ; -SubDyn['SSqmdd92'] = False # (1/s^2); ; -SubDyn['SSqmdd93'] = False # (1/s^2); ; -SubDyn['SSqmdd94'] = False # (1/s^2); ; -SubDyn['SSqmdd95'] = False # (1/s^2); ; -SubDyn['SSqmdd96'] = False # (1/s^2); ; -SubDyn['SSqmdd97'] = False # (1/s^2); ; -SubDyn['SSqmdd98'] = False # (1/s^2); ; -SubDyn['SSqmdd99'] = False # (1/s^2); ; - -""" MoorDyn """ -# THIS IS NOT A COMPLETE LIST! -# the "flexible naming system" discussed on page 7-8 of the documentation is not included -# http://www.matt-hall.ca/files/MoorDyn-Users-Guide-2017-08-16.pdf +""" WAMIT """ +WAMIT = {} -# also assuming that like other OpenFAST variables, it is limited to 9 output locations per veriable, i.e. FairTen1-FairTen9 +# WAMIT Body Forces +WAMIT['Wave1El2'] = False # (m); 2nd order wave elevation correction; +WAMIT['Wave2El2'] = False # (m); 2nd order wave elevation correction; +WAMIT['Wave3El2'] = False # (m); 2nd order wave elevation correction; +WAMIT['Wave4El2'] = False # (m); 2nd order wave elevation correction; +WAMIT['Wave5El2'] = False # (m); 2nd order wave elevation correction; +WAMIT['Wave6El2'] = False # (m); 2nd order wave elevation correction; +WAMIT['Wave7El2'] = False # (m); 2nd order wave elevation correction; +WAMIT['Wave8El2'] = False # (m); 2nd order wave elevation correction; +WAMIT['Wave9El2'] = False # (m); 2nd order wave elevation correction; -MoorDyn = {} -MoorDyn['FairTen1'] = False # (); ; -MoorDyn['FairTen2'] = False # (); ; -MoorDyn['FairTen3'] = False # (); ; -MoorDyn['FairTen4'] = False # (); ; -MoorDyn['FairTen5'] = False # (); ; -MoorDyn['FairTen6'] = False # (); ; -MoorDyn['FairTen7'] = False # (); ; -MoorDyn['FairTen8'] = False # (); ; -MoorDyn['FairTen9'] = False # (); ; -MoorDyn['AnchTen1'] = False # (); ; -MoorDyn['AnchTen2'] = False # (); ; -MoorDyn['AnchTen3'] = False # (); ; -MoorDyn['AnchTen4'] = False # (); ; -MoorDyn['AnchTen5'] = False # (); ; -MoorDyn['AnchTen6'] = False # (); ; -MoorDyn['AnchTen7'] = False # (); ; -MoorDyn['AnchTen8'] = False # (); ; -MoorDyn['AnchTen9'] = False # (); ; +# WAMIT second order Body Forces +WAMIT['WavesF2xi'] = False # (N); ; +WAMIT['WavesF2yi'] = False # (N); ; +WAMIT['WavesF2zi'] = False # (N); ; +WAMIT['WavesM2xi'] = False # (N m); ; +WAMIT['WavesM2yi'] = False # (N m); ; +WAMIT['WavesM2zi'] = False # (N m); ; -""" ElastoDyn_Nodes """ -ElastoDyn_Nodes = {} +# WAMIT Body Forces +WAMIT['WavesFxi'] = False # (N); ; +WAMIT['WavesFyi'] = False # (N); ; +WAMIT['WavesFzi'] = False # (N); ; +WAMIT['WavesMxi'] = False # (N m); ; +WAMIT['WavesMyi'] = False # (N m); ; +WAMIT['WavesMzi'] = False # (N m); ; +WAMIT['HdrStcFxi'] = False # (N); ; +WAMIT['HdrStcFyi'] = False # (N); ; +WAMIT['HdrStcFzi'] = False # (N); ; +WAMIT['HdrStcMxi'] = False # (N m); ; +WAMIT['HdrStcMyi'] = False # (N m); ; +WAMIT['HdrStcMzi'] = False # (N m); ; +WAMIT['RdtnFxi'] = False # (N); ; +WAMIT['RdtnFyi'] = False # (N); ; +WAMIT['RdtnFzi'] = False # (N); ; +WAMIT['RdtnMxi'] = False # (N m); ; +WAMIT['RdtnMyi'] = False # (N m); ; +WAMIT['RdtnMzi'] = False # (N m); ; -# Local Span Motions -ElastoDyn_Nodes['ALx'] = False # (m/s^2); local flapwise acceleration (absolute) of node; Directed along the local xb-axis -ElastoDyn_Nodes['Ax'] = False # (m/s^2); local flapwise acceleration (absolute) of node; Directed along the local xb-axis -ElastoDyn_Nodes['ALy'] = False # (m/s^2); local flapwise acceleration (absolute) of node; Directed along the local yb-axis -ElastoDyn_Nodes['Ay'] = False # (m/s^2); local flapwise acceleration (absolute) of node; Directed along the local yb-axis -ElastoDyn_Nodes['ALz'] = False # (m/s^2); local flapwise acceleration (absolute) of node; Directed along the local zb-axis -ElastoDyn_Nodes['Az'] = False # (m/s^2); local flapwise acceleration (absolute) of node; Directed along the local zb-axis -ElastoDyn_Nodes['TDx'] = False # (m); local flapwise (translational) deflection (relative to the undeflected position) of node; Directed along the xb-axis -ElastoDyn_Nodes['UxB'] = False # (m); local flapwise (translational) deflection (relative to the undeflected position) of node; Directed along the xb-axis -ElastoDyn_Nodes['TDy'] = False # (m); local edgewise (translational) deflection (relative to the undeflected position) of node; Directed along the yb-axis -ElastoDyn_Nodes['UyB'] = False # (m); local edgewise (translational) deflection (relative to the undeflected position) of node; Directed along the yb-axis -ElastoDyn_Nodes['TDz'] = False # (m); local axial (translational) deflection (relative to the undeflected position) of node; Directed along the zb-axis -ElastoDyn_Nodes['UzB'] = False # (m); local axial (translational) deflection (relative to the undeflected position) of node; Directed along the zb-axis -ElastoDyn_Nodes['RDx'] = False # (deg); Local rotational displacement about x-axis (relative to undeflected); About the local xb-axis -ElastoDyn_Nodes['Rx'] = False # (deg); Local rotational displacement about x-axis (relative to undeflected); About the local xb-axis -ElastoDyn_Nodes['RDy'] = False # (deg); Local rotational displacement about y-axis (relative to undeflected); About the local yb-axis -ElastoDyn_Nodes['Ry'] = False # (deg); Local rotational displacement about y-axis (relative to undeflected); About the local yb-axis -ElastoDyn_Nodes['RDz'] = False # (deg); Local rotational displacement about z-axis (relative to undeflected); About the local zb-axis -ElastoDyn_Nodes['Rz'] = False # (deg); Local rotational displacement about z-axis (relative to undeflected); About the local zb-axis +""" AeroDyn_Nodes """ +AeroDyn_Nodes = {} -# Local Span Loads -ElastoDyn_Nodes['MLx'] = False # (kN-m); local edgewise moment at node; About the local xb-axis -ElastoDyn_Nodes['Mx'] = False # (kN-m); local edgewise moment at node; About the local xb-axis -ElastoDyn_Nodes['MLy'] = False # (kN-m); local flapwise moment at node; About the local yb-axis -ElastoDyn_Nodes['My'] = False # (kN-m); local flapwise moment at node; About the local yb-axis -ElastoDyn_Nodes['MLz'] = False # (kN-m); local pitching moment at node; About the local zb-axis -ElastoDyn_Nodes['MLzNT'] = False # (kN-m); local pitching moment at node; About the local zb-axis -ElastoDyn_Nodes['MzL'] = False # (kN-m); local pitching moment at node; About the local zb-axis -ElastoDyn_Nodes['Mz'] = False # (kN-m); local pitching moment at node; About the local zb-axis -ElastoDyn_Nodes['FLx'] = False # (kN); local flapwise shear force at node; Directed along the local xb-axis -ElastoDyn_Nodes['Fx'] = False # (kN); local flapwise shear force at node; Directed along the local xb-axis -ElastoDyn_Nodes['FLy'] = False # (kN); local edgewise shear force at node; Directed along the local yb-axis -ElastoDyn_Nodes['Fy'] = False # (kN); local edgewise shear force at node; Directed along the local yb-axis -ElastoDyn_Nodes['FLz'] = False # (kN); local axial force at node; Directed along the local zb-axis -ElastoDyn_Nodes['FLzNT'] = False # (kN); local axial force at node; Directed along the local zb-axis -ElastoDyn_Nodes['FzL'] = False # (kN); local axial force at node; Directed along the local zb-axis -ElastoDyn_Nodes['Fz'] = False # (kN); local axial force at node; Directed along the local zb-axis -ElastoDyn_Nodes['MLxNT'] = False # (kN-m); Edgewise moment in local coordinate system (initial structural twist removed); About the local xb-axis -ElastoDyn_Nodes['MxL'] = False # (kN-m); Edgewise moment in local coordinate system (initial structural twist removed); About the local xb-axis -ElastoDyn_Nodes['MlyNT'] = False # (kN-m); Flapwise shear moment in local coordinate system (initial structural twist removed); About the local yb-axis -ElastoDyn_Nodes['MyL'] = False # (kN-m); Flapwise shear moment in local coordinate system (initial structural twist removed); About the local yb-axis -ElastoDyn_Nodes['FLxNT'] = False # (kN); Flapwise shear force in local coordinate system (initial structural twist removed); Directed along the local xb-axis -ElastoDyn_Nodes['FxL'] = False # (kN); Flapwise shear force in local coordinate system (initial structural twist removed); Directed along the local xb-axis -ElastoDyn_Nodes['FlyNT'] = False # (kN); Edgewise shear force in local coordinate system (initial structural twist removed); Directed along the local yb-axis -ElastoDyn_Nodes['FyL'] = False # (kN); Edgewise shear force in local coordinate system (initial structural twist removed); Directed along the local yb-axis +# Blade +AeroDyn_Nodes['VUndx'] = False # (m/s); (will be deprecated) x-component of undisturbed wind velocity at each node; ill-defined / implementation specific +AeroDyn_Nodes['VUndy'] = False # (m/s); (will be deprecated) y-component of undisturbed wind velocity at each node; ill-defined / implementation specific +AeroDyn_Nodes['VUndz'] = False # (m/s); (will be deprecated) z-component of undisturbed wind velocity at each node; ill-defined / implementation specific +AeroDyn_Nodes['VUndxi'] = False # (m/s); x-component of undisturbed wind velocity at each node; inertial/global coordinate system +AeroDyn_Nodes['VUndyi'] = False # (m/s); y-component of undisturbed wind velocity at each node; inertial/global coordinate system +AeroDyn_Nodes['VUndzi'] = False # (m/s); z-component of undisturbed wind velocity at each node; inertial/global coordinate system +AeroDyn_Nodes['VUndxp'] = False # (m/s); x-component of undisturbed wind velocity at each node; polar coordinate system +AeroDyn_Nodes['VUndyp'] = False # (m/s); y-component of undisturbed wind velocity at each node; polar coordinate system +AeroDyn_Nodes['VUndzp'] = False # (m/s); z-component of undisturbed wind velocity at each node; polar coordinate system +AeroDyn_Nodes['VUndxl'] = False # (m/s); x-component of undisturbed wind velocity at each node; local-polar coordinate system +AeroDyn_Nodes['VUndyl'] = False # (m/s); y-component of undisturbed wind velocity at each node; local-polar coordinate system +AeroDyn_Nodes['VUndzl'] = False # (m/s); z-component of undisturbed wind velocity at each node; local-polar coordinate system +AeroDyn_Nodes['VUndxa'] = False # (m/s); x-component of undisturbed wind velocity at each node; airfoil coordinate system +AeroDyn_Nodes['VUndya'] = False # (m/s); y-component of undisturbed wind velocity at each node; airfoil coordinate system +AeroDyn_Nodes['VUndza'] = False # (m/s); z-component of undisturbed wind velocity at each node; airfoil coordinate system +AeroDyn_Nodes['VDisx'] = False # (m/s); (will be deprecated) x-component of disturbed wind velocity at each node; ill-defined / implementation specific +AeroDyn_Nodes['VDisy'] = False # (m/s); (will be deprecated) y-component of disturbed wind velocity at each node; ill-defined / implementation specific +AeroDyn_Nodes['VDisz'] = False # (m/s); (will be deprecated) z-component of disturbed wind velocity at each node; ill-defined / implementation specific +AeroDyn_Nodes['VDisxi'] = False # (m/s); x-component of disturbed wind velocity at each node; inertial/global coordinate system +AeroDyn_Nodes['VDisyi'] = False # (m/s); y-component of disturbed wind velocity at each node; inertial/global coordinate system +AeroDyn_Nodes['VDiszi'] = False # (m/s); z-component of disturbed wind velocity at each node; inertial/global coordinate system +AeroDyn_Nodes['VDisxp'] = False # (m/s); x-component of disturbed wind velocity at each node; polar coordinate system +AeroDyn_Nodes['VDisyp'] = False # (m/s); y-component of disturbed wind velocity at each node; polar coordinate system +AeroDyn_Nodes['VDiszp'] = False # (m/s); z-component of disturbed wind velocity at each node; polar coordinate system +AeroDyn_Nodes['VDisxl'] = False # (m/s); x-component of disturbed wind velocity at each node; local-polar coordinate system +AeroDyn_Nodes['VDisyl'] = False # (m/s); y-component of disturbed wind velocity at each node; local-polar coordinate system +AeroDyn_Nodes['VDiszl'] = False # (m/s); z-component of disturbed wind velocity at each node; local-polar coordinate system +AeroDyn_Nodes['VDisxa'] = False # (m/s); x-component of disturbed wind velocity at each node; airfoil coordinate system +AeroDyn_Nodes['VDisya'] = False # (m/s); y-component of disturbed wind velocity at each node; airfoil coordinate system +AeroDyn_Nodes['VDisza'] = False # (m/s); z-component of disturbed wind velocity at each node; airfoil coordinate system +AeroDyn_Nodes['STVx'] = False # (m/s); (will be deprecated) x-component of structural translational velocity at each node; ill-defined / implementation specific +AeroDyn_Nodes['STVy'] = False # (m/s); (will be deprecated) y-component of structural translational velocity at each node; ill-defined / implementation specific +AeroDyn_Nodes['STVz'] = False # (m/s); (will be deprecated) z-component of structural translational velocity at each node; ill-defined / implementation specific +AeroDyn_Nodes['STVxi'] = False # (m/s); x-component of structural translational velocity at each node; inertial/global coordinate system +AeroDyn_Nodes['STVyi'] = False # (m/s); y-component of structural translational velocity at each node; inertial/global coordinate system +AeroDyn_Nodes['STVzi'] = False # (m/s); z-component of structural translational velocity at each node; inertial/global coordinate system +AeroDyn_Nodes['STVxp'] = False # (m/s); x-component of structural translational velocity at each node; polar coordinate system +AeroDyn_Nodes['STVyp'] = False # (m/s); y-component of structural translational velocity at each node; polar coordinate system +AeroDyn_Nodes['STVzp'] = False # (m/s); z-component of structural translational velocity at each node; polar coordinate system +AeroDyn_Nodes['STVxl'] = False # (m/s); x-component of structural translational velocity at each node; local-polar coordinate system +AeroDyn_Nodes['STVyl'] = False # (m/s); y-component of structural translational velocity at each node; local-polar coordinate system +AeroDyn_Nodes['STVzl'] = False # (m/s); z-component of structural translational velocity at each node; local-polar coordinate system +AeroDyn_Nodes['STVxa'] = False # (m/s); x-component of structural translational velocity at each node; airfoil coordinate system +AeroDyn_Nodes['STVya'] = False # (m/s); y-component of structural translational velocity at each node; airfoil coordinate system +AeroDyn_Nodes['STVza'] = False # (m/s); z-component of structural translational velocity at each node; airfoil coordinate system +AeroDyn_Nodes['Vindx'] = False # (m/s); (will be deprecated) Axial induced wind velocity at each node; local blade coordinate system +AeroDyn_Nodes['Vindy'] = False # (m/s); (will be deprecated) Tangential induced wind velocity at each node; local blade coordinate system +AeroDyn_Nodes['Vindxi'] = False # (m/s); x-component of induced velocity at each node ; inertial/global coordinate system +AeroDyn_Nodes['Vindyi'] = False # (m/s); y-component of induced velocity at each node; inertial/global coordinate system +AeroDyn_Nodes['Vindzi'] = False # (m/s); z-component of induced velocity at each node; inertial/global coordinate system +AeroDyn_Nodes['Vindxp'] = False # (m/s); x-component of induced velocity at each node ; polar coordinate system +AeroDyn_Nodes['Uin'] = False # (m/s); x-component of induced velocity at each node ; polar coordinate system +AeroDyn_Nodes['Vindyp'] = False # (m/s); y-component of induced velocity at each node; polar coordinate system +AeroDyn_Nodes['Uit'] = False # (m/s); y-component of induced velocity at each node; polar coordinate system +AeroDyn_Nodes['Vindzp'] = False # (m/s); z-component of induced velocity at each node; polar coordinate system +AeroDyn_Nodes['Uir'] = False # (m/s); z-component of induced velocity at each node; polar coordinate system +AeroDyn_Nodes['Vindxl'] = False # (m/s); x-component of induced velocity at each node ; local-polar coordinate system +AeroDyn_Nodes['Vindyl'] = False # (m/s); y-component of induced velocity at each node; local-polar coordinate system +AeroDyn_Nodes['Vindzl'] = False # (m/s); z-component of induced velocity at each node; local-polar coordinate system +AeroDyn_Nodes['Vindxa'] = False # (m/s); x-component of induced velocity at each node ; airfoil coordinate system +AeroDyn_Nodes['Vindya'] = False # (m/s); y-component of induced velocity at each node; airfoil coordinate system +AeroDyn_Nodes['Vindza'] = False # (m/s); z-component of induced velocity at each node; airfoil coordinate system +AeroDyn_Nodes['Vx'] = False # (m/s); (will be deprecated) Local axial velocity (VDisx - STVx); ill-defined / implementation specific +AeroDyn_Nodes['Vy'] = False # (m/s); (will be deprecated) Local tangential velocity (VDisy - STVy); ill-defined / implementation specific +AeroDyn_Nodes['VRel'] = False # (m/s); Relative wind speed at each node, computed using x-y components in the airfoil system; in xa-ya plane, airfoil coordinate system +AeroDyn_Nodes['DynP'] = False # (Pa); Dynamic pressure at each node; in xa-ya plane, airfoil coordinate system +AeroDyn_Nodes['Re'] = False # (-); Reynolds number (in millions) at each node; in xa-ya plane, airfoil coordinate system +AeroDyn_Nodes['M'] = False # (-); Mach number at each node; in xa-ya plane, airfoil coordinate system +AeroDyn_Nodes['AxInd'] = False # (-); Axial induction factor at each node; implementation specific +AeroDyn_Nodes['TnInd'] = False # (-); Tangential induction factor at each node; implementation specific +AeroDyn_Nodes['AxInd_qs'] = False # (-); Quasi-steady axial induction factor as computed within the quasi-steady BEM algorithm (before DBEMT and skew correction); implementation specific +AeroDyn_Nodes['TnInd_qs'] = False # (-); Quasi-steady tangential induction factor as computed within the quasi-steady BEM algorithm (before DBEMT and skew correction); implementation specific +AeroDyn_Nodes['Alpha'] = False # (deg); Angle of attack at each node; airfoil coordinate system +AeroDyn_Nodes['Phi'] = False # (deg); Inflow angle at each node; ill-defined / implementation specific +AeroDyn_Nodes['Theta'] = False # (deg); Pitch+Twist angle at each node; +AeroDyn_Nodes['Curve'] = False # (deg); Curvature angle at each node; +AeroDyn_Nodes['Toe'] = False # (deg); Toe angle at each node; +AeroDyn_Nodes['Cl'] = False # (-); Lift force coefficient at each node, including unsteady effects; in xa-ya plane, airfoil coordinate system +AeroDyn_Nodes['Cd'] = False # (-); Drag force coefficient at each node, including unsteady effects; in xa-ya plane, airfoil coordinate system +AeroDyn_Nodes['Cm'] = False # (-); Pitching moment coefficient at each node, including unsteady effects; about za, airfoil coordinate system +AeroDyn_Nodes['Cma'] = False # (-); Pitching moment coefficient at each node, including unsteady effects; about za, airfoil coordinate system +AeroDyn_Nodes['Cx'] = False # (-); (will be deprecated) Normal force (to plane) coefficient at each node; ill-defined / implementation specific +AeroDyn_Nodes['Cy'] = False # (-); (will be deprecated) Tangential force (to plane) coefficient at each node; ill-defined / implementation specific +AeroDyn_Nodes['Cn'] = False # (-); Normal force (to chord) coefficient at each node; airfoil coordinate system +AeroDyn_Nodes['Cxa'] = False # (-); Normal force (to chord) coefficient at each node; airfoil coordinate system +AeroDyn_Nodes['Ct'] = False # (-); Tangential force (to chord) coefficient at each node - Negative along ya!; airfoil coordinate system +AeroDyn_Nodes['Fxi'] = False # (N/m); Force per unit length in the x direction; inertial/global coordinate system +AeroDyn_Nodes['Fyi'] = False # (N/m); Force per unit length in the y direction; inertial/global coordinate system +AeroDyn_Nodes['Fzi'] = False # (N/m); Force per unit length in the z direction; inertial/global coordinate system +AeroDyn_Nodes['Mxi'] = False # (N-m/m); Moment per unit length in the x direction; inertial/global coordinate system +AeroDyn_Nodes['Myi'] = False # (N-m/m); Moment per unit length in the y direction; inertial/global coordinate system +AeroDyn_Nodes['Mzi'] = False # (N-m/m); Moment per unit length in the z direction; inertial/global coordinate system +AeroDyn_Nodes['Fxp'] = False # (N/m); Force per unit length in the x direction; polar coordinate system +AeroDyn_Nodes['Fyp'] = False # (N/m); Force per unit length in the y direction; polar coordinate system +AeroDyn_Nodes['Fzp'] = False # (N/m); Force per unit length in the z direction; polar coordinate system +AeroDyn_Nodes['Mxp'] = False # (N-m/m); Moment per unit length in the x direction; polar coordinate system +AeroDyn_Nodes['Myp'] = False # (N-m/m); Moment per unit length in the y direction; polar coordinate system +AeroDyn_Nodes['Mzp'] = False # (N-m/m); Moment per unit length in the z direction; polar coordinate system +AeroDyn_Nodes['Fxl'] = False # (N/m); Force per unit length in the x direction; local-polar coordinate system +AeroDyn_Nodes['Fyl'] = False # (N/m); Force per unit length in the y direction; local-polar coordinate system +AeroDyn_Nodes['Fzl'] = False # (N/m); Force per unit length in the z direction; local-polar coordinate system +AeroDyn_Nodes['Mxl'] = False # (N-m/m); Moment per unit length in the x direction; local-polar coordinate system +AeroDyn_Nodes['Myl'] = False # (N-m/m); Moment per unit length in the y direction; local-polar coordinate system +AeroDyn_Nodes['Mzl'] = False # (N-m/m); Moment per unit length in the z direction; local-polar coordinate system +AeroDyn_Nodes['Fl'] = False # (N/m); Lift force per unit length at each node; in xa-ya plane, airfoil coordinate system +AeroDyn_Nodes['Fd'] = False # (N/m); Drag force per unit length at each node; in xa-ya plane, airfoil coordinate system +AeroDyn_Nodes['Mm'] = False # (N-m/m); Pitching moment per unit length at each node; about za, airfoil coordinate system +AeroDyn_Nodes['Mza'] = False # (N-m/m); Pitching moment per unit length at each node; about za, airfoil coordinate system +AeroDyn_Nodes['Fx'] = False # (N/m); (will be deprecated) Normal force (to plane) per unit length at each node; ill-defined / implementation specific +AeroDyn_Nodes['Fy'] = False # (N/m); (will be deprecated) Tangential force (to plane) per unit length at each node; ill-defined / implementation specific +AeroDyn_Nodes['Fn'] = False # (N/m); Normal force (to chord) per unit length at each node; airfoil coordinate system +AeroDyn_Nodes['Fxa'] = False # (N/m); Normal force (to chord) per unit length at each node; airfoil coordinate system +AeroDyn_Nodes['Ft'] = False # (N/m); Tangential force (to chord) per unit length at each node - Negative along ya!; airfoil coordinate system +AeroDyn_Nodes['Gam'] = False # (m^2/s); Gamma -- circulation on blade; about za, airfoil coordinate system +AeroDyn_Nodes['Clrnc'] = False # (m); Tower clearance at each node (based on the absolute distance to the nearest point in the tower from blade node B#N# minus the local tower radius, in the deflected configuration); please note that this clearance is only approximate because the calculation assumes that the blade is a line with no volume (however, the calculation does use the local tower radius); when blade node B#N# is above the tower top (or below the tower base), the absolute distance to the tower top (or base) minus the local tower radius, in the deflected configuration, is output; +AeroDyn_Nodes['GeomPhi'] = False # (1/0); Geometric phi? If phi was solved using normal BEMT equations, GeomPhi = 1; otherwise, if it was solved geometrically, GeomPhi = 0.; +AeroDyn_Nodes['Chi'] = False # (deg); Skew angle (used in skewed wake correction); +AeroDyn_Nodes['UA_Flag'] = False # (-); Flag indicating if UA is turned on for this node.; +AeroDyn_Nodes['UA_x1'] = False # (rad); time-history of wake vorticity contributing to effective angle of attack; +AeroDyn_Nodes['UA_x2'] = False # (rad); time-history of wake vorticity contributing to effective angle of attack; +AeroDyn_Nodes['UA_x3'] = False # (-); dimension of cl (UAMod4) or cn (UAMod5); lagging the fully-attached coefficient; +AeroDyn_Nodes['UA_x4'] = False # (-); UAMod4 and 5 separation factor; +AeroDyn_Nodes['UA_x5'] = False # (-); UAMod5 vortex term; +AeroDyn_Nodes['Debug1'] = False # (-); Placeholders for debugging channels; +AeroDyn_Nodes['Debug2'] = False # (-); Placeholders for debugging channels; +AeroDyn_Nodes['Debug3'] = False # (-); Placeholders for debugging channels; +AeroDyn_Nodes['CpMin'] = False # (-); Pressure coefficient; +AeroDyn_Nodes['SgCav'] = False # (-); Cavitation number; +AeroDyn_Nodes['SigCr'] = False # (-); Critical cavitation number; +AeroDyn_Nodes['BEM_F_qs'] = False # (-); Tip/hub loss factor in quasi-steady BEM algorithm; +AeroDyn_Nodes['BEM_k_qs'] = False # (-); k factor in quasi-steady BEM algorithm; +AeroDyn_Nodes['BEM_kp_qs'] = False # (-); kp factor in quasi-steady BEM algorithm; +AeroDyn_Nodes['BEM_CT_qs'] = False # (-); Quasi-steady thrust coefficient as computed by the quasi-steady BEM algorithm. ; +AeroDyn_Nodes['Cl_qs'] = False # (-); Static portion of lift force coefficient at each node, without unsteady effects; in xa-ya plane, airfoil coordinate system +AeroDyn_Nodes['Cd_qs'] = False # (-); Static portion of drag force coefficient at each node, without unsteady effects; in xa-ya plane, airfoil coordinate system +AeroDyn_Nodes['Cm_qs'] = False # (-); Static portion of pitching moment coefficient at each node, without unsteady effects; about za, airfoil coordinate system +AeroDyn_Nodes['Fbxi'] = False # (N/m); Buoyancy force per unit length in the x direction; inertial/global coordinate system +AeroDyn_Nodes['Fbyi'] = False # (N/m); Buoyancy force per unit length in the y direction; inertial/global coordinate system +AeroDyn_Nodes['Fbzi'] = False # (N/m); Buoyancy force per unit length in the z direction; inertial/global coordinate system +AeroDyn_Nodes['Mbxi'] = False # (N-m/m); Buoyancy moment per unit length in the x direction; inertial/global coordinate system +AeroDyn_Nodes['Mbyi'] = False # (N-m/m); Buoyancy moment per unit length in the y direction; inertial/global coordinate system +AeroDyn_Nodes['Mbzi'] = False # (N-m/m); Buoyancy moment per unit length in the z direction; inertial/global coordinate system +AeroDyn_Nodes['Fbxp'] = False # (N/m); Buoyancy force per unit length in the x direction; polar coordinate system +AeroDyn_Nodes['Fbyp'] = False # (N/m); Buoyancy force per unit length in the y direction; polar coordinate system +AeroDyn_Nodes['Fbzp'] = False # (N/m); Buoyancy force per unit length in the z direction; polar coordinate system +AeroDyn_Nodes['Mbxp'] = False # (N-m/m); Buoyancy moment per unit length in the x direction; polar coordinate system +AeroDyn_Nodes['Mbyp'] = False # (N-m/m); Buoyancy moment per unit length in the y direction; polar coordinate system +AeroDyn_Nodes['Mbzp'] = False # (N-m/m); Buoyancy moment per unit length in the z direction; polar coordinate system +AeroDyn_Nodes['Fbxl'] = False # (N/m); Buoyancy force per unit length in the x direction; local-polar coordinate system +AeroDyn_Nodes['Fbyl'] = False # (N/m); Buoyancy force per unit length in the y direction; local-polar coordinate system +AeroDyn_Nodes['Fbzl'] = False # (N/m); Buoyancy force per unit length in the z direction; local-polar coordinate system +AeroDyn_Nodes['Mbxl'] = False # (N-m/m); Buoyancy moment per unit length in the x direction; local-polar coordinate system +AeroDyn_Nodes['Mbyl'] = False # (N-m/m); Buoyancy moment per unit length in the y direction; local-polar coordinate system +AeroDyn_Nodes['Mbzl'] = False # (N-m/m); Buoyancy moment per unit length in the z direction; local-polar coordinate system +AeroDyn_Nodes['Fbxa'] = False # (N/m); Buoyancy force per unit length in the x direction; airfoil coordinate system +AeroDyn_Nodes['Fbn'] = False # (N/m); Buoyancy force per unit length in the x direction; airfoil coordinate system +AeroDyn_Nodes['Fbya'] = False # (N/m); Buoyancy force per unit length in the y direction; airfoil coordinate system +AeroDyn_Nodes['Fbt'] = False # (N/m); Buoyancy force per unit length in the y direction; airfoil coordinate system +AeroDyn_Nodes['Fbza'] = False # (N/m); Buoyancy force per unit length in the z direction; airfoil coordinate system +AeroDyn_Nodes['Fbs'] = False # (N/m); Buoyancy force per unit length in the z direction; airfoil coordinate system +AeroDyn_Nodes['Mbxa'] = False # (N-m/m); Buoyancy moment per unit length in the x direction; airfoil coordinate system +AeroDyn_Nodes['Mbn'] = False # (N-m/m); Buoyancy moment per unit length in the x direction; airfoil coordinate system +AeroDyn_Nodes['Mbya'] = False # (N-m/m); Buoyancy moment per unit length in the y direction; airfoil coordinate system +AeroDyn_Nodes['Mbt'] = False # (N-m/m); Buoyancy moment per unit length in the y direction; airfoil coordinate system +AeroDyn_Nodes['Mbza'] = False # (N-m/m); Buoyancy moment per unit length in the z direction; airfoil coordinate system +AeroDyn_Nodes['Mbs'] = False # (N-m/m); Buoyancy moment per unit length in the z direction; airfoil coordinate system """ BeamDyn_Nodes """ @@ -11012,1279 +9525,68 @@ BeamDyn_Nodes['MFizr'] = False # (N-m); Inertial moment about z ; r: a floating reference coordinate system fixed to the root of the moving beam; when coupled to FAST for blades, this is equivalent to the IEC blade (b) coordinate system -""" AeroDyn_Nodes """ -AeroDyn_Nodes = {} +""" ElastoDyn_Nodes """ +ElastoDyn_Nodes = {} -# Blade -AeroDyn_Nodes['VUndx'] = False # (m/s); x-component of undisturbed wind velocity at each node; local blade coordinate system -AeroDyn_Nodes['VUndy'] = False # (m/s); y-component of undisturbed wind velocity at each node; local blade coordinate system -AeroDyn_Nodes['VUndz'] = False # (m/s); z-component of undisturbed wind velocity at each node; local blade coordinate system -AeroDyn_Nodes['Vundxi'] = False # (m/s); x-component of undisturbed wind velocity at each node; inertial/global coordinate system -AeroDyn_Nodes['Vundyi'] = False # (m/s); y-component of undisturbed wind velocity at each node; inertial/global coordinate system -AeroDyn_Nodes['Vundzi'] = False # (m/s); z-component of undisturbed wind velocity at each node; inertial/global coordinate system -AeroDyn_Nodes['VDisx'] = False # (m/s); x-component of disturbed wind velocity at each node; local blade coordinate system -AeroDyn_Nodes['VDisy'] = False # (m/s); y-component of disturbed wind velocity at each node; local blade coordinate system -AeroDyn_Nodes['VDisz'] = False # (m/s); z-component of disturbed wind velocity at each node; local blade coordinate system -AeroDyn_Nodes['STVx'] = False # (m/s); x-component of structural translational velocity at each node; local blade coordinate system -AeroDyn_Nodes['STVy'] = False # (m/s); y-component of structural translational velocity at each node; local blade coordinate system -AeroDyn_Nodes['STVz'] = False # (m/s); z-component of structural translational velocity at each node; local blade coordinate system -AeroDyn_Nodes['VRel'] = False # (m/s); Relvative wind speed at each node; -AeroDyn_Nodes['DynP'] = False # (Pa); Dynamic pressure at each node; -AeroDyn_Nodes['Re'] = False # (-); Reynolds number (in millions) at each node; -AeroDyn_Nodes['M'] = False # (-); Mach number at each node; -AeroDyn_Nodes['Vindx'] = False # (m/s); Axial induced wind velocity at each node; -AeroDyn_Nodes['Vindy'] = False # (m/s); Tangential induced wind velocity at each node; -AeroDyn_Nodes['AxInd'] = False # (-); Axial induction factor at each node; -AeroDyn_Nodes['TnInd'] = False # (-); Tangential induction factor at each node; -AeroDyn_Nodes['Alpha'] = False # (deg); Angle of attack at each node; -AeroDyn_Nodes['Theta'] = False # (deg); Pitch+Twist angle at each node; -AeroDyn_Nodes['Phi'] = False # (deg); Inflow angle at each node; -AeroDyn_Nodes['Curve'] = False # (deg); Curvature angle at each node; -AeroDyn_Nodes['Cl'] = False # (-); Lift force coefficient at each node, including unsteady effects; -AeroDyn_Nodes['Cd'] = False # (-); Drag force coefficient at each node, including unsteady effects; -AeroDyn_Nodes['Cm'] = False # (-); Pitching moment coefficient at each node, including unsteady effects; -AeroDyn_Nodes['Cx'] = False # (-); Normal force (to plane) coefficient at each node; -AeroDyn_Nodes['Cy'] = False # (-); Tangential force (to plane) coefficient at each node; -AeroDyn_Nodes['Cn'] = False # (-); Normal force (to chord) coefficient at each node; -AeroDyn_Nodes['Ct'] = False # (-); Tangential force (to chord) coefficient at each node; -AeroDyn_Nodes['Fl'] = False # (N/m); Lift force per unit length at each node; -AeroDyn_Nodes['Fd'] = False # (N/m); Drag force per unit length at each node; -AeroDyn_Nodes['Mm'] = False # (N-m/m); Pitching moment per unit length at each node; -AeroDyn_Nodes['Fx'] = False # (N/m); Normal force (to plane) per unit length at each node; -AeroDyn_Nodes['Fy'] = False # (N/m); Tangential force (to plane) per unit length at each node; -AeroDyn_Nodes['Fn'] = False # (N/m); Normal force (to chord) per unit length at each node; -AeroDyn_Nodes['Ft'] = False # (N/m); Tangential force (to chord) per unit length at each node; -AeroDyn_Nodes['Clrnc'] = False # (m); Tower clearance at each node (based on the absolute distance to the nearest point in the tower from blade node B#N# minus the local tower radius, in the deflected configuration); please note that this clearance is only approximate because the calculation assumes that the blade is a line with no volume (however, the calculation does use the local tower radius); when blade node B#N# is above the tower top (or below the tower base), the absolute distance to the tower top (or base) minus the local tower radius, in the deflected configuration, is output; -AeroDyn_Nodes['Vx'] = False # (m/s); Local axial velocity; -AeroDyn_Nodes['Vy'] = False # (m/s); Local tangential velocity; -AeroDyn_Nodes['GeomPhi'] = False # (1/0); Geometric phi? If phi was solved using normal BEMT equations, GeomPhi = 1; otherwise, if it was solved geometrically, GeomPhi = 0.; -AeroDyn_Nodes['Chi'] = False # (deg); Skew angle (used in skewed wake correction); -AeroDyn_Nodes['UA_Flag'] = False # (-); Flag indicating if UA is turned on for this node.; -AeroDyn_Nodes['UA_x1'] = False # (rad); time-history of wake vorticity contributing to effective angle of attack; -AeroDyn_Nodes['UA_x2'] = False # (rad); time-history of wake vorticity contributing to effective angle of attack; -AeroDyn_Nodes['UA_x3'] = False # (-); dimension of cl (UAMod4) or cn (UAMod5); lagging the fully-attached coefficient; -AeroDyn_Nodes['UA_x4'] = False # (-); UAMod4 and 5 separation factor; -AeroDyn_Nodes['UA_x5'] = False # (-); UAMod5 vortex term; -AeroDyn_Nodes['Debug1'] = False # (-); Placeholders for debugging channels; -AeroDyn_Nodes['Debug2'] = False # (-); Placeholders for debugging channels; -AeroDyn_Nodes['Debug3'] = False # (-); Placeholders for debugging channels; -AeroDyn_Nodes['CpMin'] = False # (-); Pressure coefficient; -AeroDyn_Nodes['SgCav'] = False # (-); Cavitation number; -AeroDyn_Nodes['SigCr'] = False # (-); Critical cavitation number; -AeroDyn_Nodes['Gam'] = False # (m^2/s); Gamma -- circulation on blade; -AeroDyn_Nodes['Cl_Static'] = False # (-); Static portion of lift force coefficient at each node, without unsteady effects; -AeroDyn_Nodes['Cd_Static'] = False # (-); Static portion of drag force coefficient at each node, without unsteady effects; -AeroDyn_Nodes['Cm_Static'] = False # (-); Static portion of pitching moment coefficient at each node, without unsteady effects; -AeroDyn_Nodes['Uin'] = False # (m/s); Axial induced velocity in rotating hub coordinates. Axial aligned with hub axis.; rotor plane polar hub rotating coordinates -AeroDyn_Nodes['Uit'] = False # (m/s); Tangential induced velocity in rotating hub coordinates. Tangential to the rotation plane. Perpendicular to blade aziumth.; rotor plane polar hub rotating coordinates -AeroDyn_Nodes['Uir'] = False # (m/s); Radial induced velocity in rotating hub coordinates. Radial outwards in rotation plane. Aligned with blade azimuth.; rotor plane polar hub rotating coordinates +# Local Span Motions +ElastoDyn_Nodes['ALx'] = False # (m/s^2); local flapwise acceleration (absolute) of node; Directed along the local xb-axis +ElastoDyn_Nodes['Ax'] = False # (m/s^2); local flapwise acceleration (absolute) of node; Directed along the local xb-axis +ElastoDyn_Nodes['ALy'] = False # (m/s^2); local flapwise acceleration (absolute) of node; Directed along the local yb-axis +ElastoDyn_Nodes['Ay'] = False # (m/s^2); local flapwise acceleration (absolute) of node; Directed along the local yb-axis +ElastoDyn_Nodes['ALz'] = False # (m/s^2); local flapwise acceleration (absolute) of node; Directed along the local zb-axis +ElastoDyn_Nodes['Az'] = False # (m/s^2); local flapwise acceleration (absolute) of node; Directed along the local zb-axis +ElastoDyn_Nodes['TDx'] = False # (m); local flapwise (translational) deflection (relative to the undeflected position) of node; Directed along the xb-axis +ElastoDyn_Nodes['UxB'] = False # (m); local flapwise (translational) deflection (relative to the undeflected position) of node; Directed along the xb-axis +ElastoDyn_Nodes['TDy'] = False # (m); local edgewise (translational) deflection (relative to the undeflected position) of node; Directed along the yb-axis +ElastoDyn_Nodes['UyB'] = False # (m); local edgewise (translational) deflection (relative to the undeflected position) of node; Directed along the yb-axis +ElastoDyn_Nodes['TDz'] = False # (m); local axial (translational) deflection (relative to the undeflected position) of node; Directed along the zb-axis +ElastoDyn_Nodes['UzB'] = False # (m); local axial (translational) deflection (relative to the undeflected position) of node; Directed along the zb-axis +ElastoDyn_Nodes['RDx'] = False # (deg); Local rotational displacement about x-axis (relative to undeflected); About the local xb-axis +ElastoDyn_Nodes['Rx'] = False # (deg); Local rotational displacement about x-axis (relative to undeflected); About the local xb-axis +ElastoDyn_Nodes['RDy'] = False # (deg); Local rotational displacement about y-axis (relative to undeflected); About the local yb-axis +ElastoDyn_Nodes['Ry'] = False # (deg); Local rotational displacement about y-axis (relative to undeflected); About the local yb-axis +ElastoDyn_Nodes['RDz'] = False # (deg); Local rotational displacement about z-axis (relative to undeflected); About the local zb-axis +ElastoDyn_Nodes['Rz'] = False # (deg); Local rotational displacement about z-axis (relative to undeflected); About the local zb-axis + +# Local Span Loads +ElastoDyn_Nodes['MLx'] = False # (kN-m); local edgewise moment at node; About the local xb-axis +ElastoDyn_Nodes['Mx'] = False # (kN-m); local edgewise moment at node; About the local xb-axis +ElastoDyn_Nodes['MLy'] = False # (kN-m); local flapwise moment at node; About the local yb-axis +ElastoDyn_Nodes['My'] = False # (kN-m); local flapwise moment at node; About the local yb-axis +ElastoDyn_Nodes['MLz'] = False # (kN-m); local pitching moment at node; About the local zb-axis +ElastoDyn_Nodes['MLzNT'] = False # (kN-m); local pitching moment at node; About the local zb-axis +ElastoDyn_Nodes['MzL'] = False # (kN-m); local pitching moment at node; About the local zb-axis +ElastoDyn_Nodes['Mz'] = False # (kN-m); local pitching moment at node; About the local zb-axis +ElastoDyn_Nodes['FLx'] = False # (kN); local flapwise shear force at node; Directed along the local xb-axis +ElastoDyn_Nodes['Fx'] = False # (kN); local flapwise shear force at node; Directed along the local xb-axis +ElastoDyn_Nodes['FLy'] = False # (kN); local edgewise shear force at node; Directed along the local yb-axis +ElastoDyn_Nodes['Fy'] = False # (kN); local edgewise shear force at node; Directed along the local yb-axis +ElastoDyn_Nodes['FLz'] = False # (kN); local axial force at node; Directed along the local zb-axis +ElastoDyn_Nodes['FLzNT'] = False # (kN); local axial force at node; Directed along the local zb-axis +ElastoDyn_Nodes['FzL'] = False # (kN); local axial force at node; Directed along the local zb-axis +ElastoDyn_Nodes['Fz'] = False # (kN); local axial force at node; Directed along the local zb-axis +ElastoDyn_Nodes['MLxNT'] = False # (kN-m); Edgewise moment in local coordinate system (initial structural twist removed); About the local xb-axis +ElastoDyn_Nodes['MxL'] = False # (kN-m); Edgewise moment in local coordinate system (initial structural twist removed); About the local xb-axis +ElastoDyn_Nodes['MlyNT'] = False # (kN-m); Flapwise shear moment in local coordinate system (initial structural twist removed); About the local yb-axis +ElastoDyn_Nodes['MyL'] = False # (kN-m); Flapwise shear moment in local coordinate system (initial structural twist removed); About the local yb-axis +ElastoDyn_Nodes['FLxNT'] = False # (kN); Flapwise shear force in local coordinate system (initial structural twist removed); Directed along the local xb-axis +ElastoDyn_Nodes['FxL'] = False # (kN); Flapwise shear force in local coordinate system (initial structural twist removed); Directed along the local xb-axis +ElastoDyn_Nodes['FlyNT'] = False # (kN); Edgewise shear force in local coordinate system (initial structural twist removed); Directed along the local yb-axis +ElastoDyn_Nodes['FyL'] = False # (kN); Edgewise shear force in local coordinate system (initial structural twist removed); Directed along the local yb-axis """ Final Output Dictionary """ FstOutput = {} -FstOutput['ElastoDyn'] = ElastoDyn -FstOutput['BeamDyn'] = BeamDyn -FstOutput['ServoDyn'] = ServoDyn FstOutput['AeroDyn'] = AeroDyn +FstOutput['BeamDyn'] = BeamDyn +FstOutput['ElastoDyn'] = ElastoDyn FstOutput['InflowWind'] = InflowWind -FstOutput['WAMIT'] = WAMIT +FstOutput['ServoDyn'] = ServoDyn FstOutput['HydroDyn'] = HydroDyn FstOutput['Morison'] = Morison +FstOutput['SeaState'] = SeaState FstOutput['SubDyn'] = SubDyn -FstOutput['MoorDyn'] = MoorDyn -FstOutput['ElastoDyn_Nodes'] = ElastoDyn_Nodes -FstOutput['BeamDyn_Nodes'] = BeamDyn_Nodes +FstOutput['WAMIT'] = WAMIT FstOutput['AeroDyn_Nodes'] = AeroDyn_Nodes - -""" Generated from FAST OutListParameters.xlsx files with AeroelasticSE/src/AeroelasticSE/Util/create_output_vars.py """ - - -""" OutList """ -OutList = {} - -# Wind Motions -OutList['WindVxi'] = False # (m/s); Nominally downwind component of the hub-height wind velocity; Directed along the xi-axis -OutList['uWind'] = False # (m/s); Nominally downwind component of the hub-height wind velocity; Directed along the xi-axis -OutList['WindVyi'] = False # (m/s); Cross-wind component of the hub-height wind velocity; Directed along the yi-axis -OutList['vWind'] = False # (m/s); Cross-wind component of the hub-height wind velocity; Directed along the yi-axis -OutList['WindVzi'] = False # (m/s); Vertical component of the hub-height wind velocity; Directed along the zi-axis -OutList['wWind'] = False # (m/s); Vertical component of the hub-height wind velocity; Directed along the zi-axis -OutList['TotWindV'] = False # (m/s); Total hub-height wind velocity magnitude; N/A -OutList['HorWindV'] = False # (m/s); Horizontal hub-height wind velocity magnitude; In the xi- and yi-plane -OutList['HorWndDir'] = False # (deg); Horizontal hub-height wind direction. Please note that FAST uses the opposite sign convention that AeroDyn uses. Put a "-", "_", "m", or "M" character in front of this variable name if you want to use the AeroDyn convention.; About the zi-axis -OutList['VerWndDir'] = False # (deg); Vertical hub-height wind direction; About an axis orthogonal to the zi-axis and the HorWindV-vector - -# Blade 1 Tip Motions -OutList['TipDxc1'] = True # (m); Blade 1 out-of-plane tip deflection (relative to the undeflected position); Directed along the xc1-axis -OutList['OoPDefl1'] = False # (m); Blade 1 out-of-plane tip deflection (relative to the undeflected position); Directed along the xc1-axis -OutList['TipDyc1'] = True # (m); Blade 1 in-plane tip deflection (relative to the undeflected position); Directed along the yc1-axis -OutList['IPDefl1'] = False # (m); Blade 1 in-plane tip deflection (relative to the undeflected position); Directed along the yc1-axis -OutList['TipDzc1'] = True # (m); Blade 1 axial tip deflection (relative to the undeflected position); Directed along the zc1- and zb1-axes -OutList['TipDzb1'] = True # (m); Blade 1 axial tip deflection (relative to the undeflected position); Directed along the zc1- and zb1-axes -OutList['TipDxb1'] = True # (m); Blade 1 flapwise tip deflection (relative to the undeflected position); Directed along the xb1-axis -OutList['TipDyb1'] = True # (m); Blade 1 edgewise tip deflection (relative to the undeflected position); Directed along the yb1-axis -OutList['TipALxb1'] = False # (m/s^2); Blade 1 local flapwise tip acceleration (absolute); Directed along the local xb1-axis -OutList['TipALyb1'] = False # (m/s^2); Blade 1 local edgewise tip acceleration (absolute); Directed along the local yb1-axis -OutList['TipALzb1'] = False # (m/s^2); Blade 1 local axial tip acceleration (absolute); Directed along the local zb1-axis -OutList['TipRDxb1'] = False # (deg); Blade 1 roll (angular/rotational) tip deflection (relative to the undeflected position). In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the xb1-axis -OutList['RollDefl1'] = False # (deg); Blade 1 roll (angular/rotational) tip deflection (relative to the undeflected position). In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the xb1-axis -OutList['TipRDyb1'] = False # (deg); Blade 1 pitch (angular/rotational) tip deflection (relative to the undeflected position). In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the yb1-axis -OutList['PtchDefl1'] = False # (deg); Blade 1 pitch (angular/rotational) tip deflection (relative to the undeflected position). In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the yb1-axis -OutList['TipRDzc1'] = False # (deg); Blade 1 torsional tip deflection (relative to the undeflected position). This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the zc1- and zb1-axes -OutList['TipRDzb1'] = False # (deg); Blade 1 torsional tip deflection (relative to the undeflected position). This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the zc1- and zb1-axes -OutList['TwstDefl1'] = False # (deg); Blade 1 torsional tip deflection (relative to the undeflected position). This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the zc1- and zb1-axes -OutList['TipClrnc1'] = False # (m); Blade 1 tip-to-tower clearance estimate. This is computed as the perpendicular distance from the yaw axis to the tip of blade 1 when the blade tip is below the yaw bearing. When the tip of blade 1 is above the yaw bearing, it is computed as the absolute distance from the yaw bearing to the blade tip. Please note that you should reduce this value by the tower radius to obtain the actual tower clearance.; N/A -OutList['TwrClrnc1'] = False # (m); Blade 1 tip-to-tower clearance estimate. This is computed as the perpendicular distance from the yaw axis to the tip of blade 1 when the blade tip is below the yaw bearing. When the tip of blade 1 is above the yaw bearing, it is computed as the absolute distance from the yaw bearing to the blade tip. Please note that you should reduce this value by the tower radius to obtain the actual tower clearance.; N/A -OutList['Tip2Twr1'] = False # (m); Blade 1 tip-to-tower clearance estimate. This is computed as the perpendicular distance from the yaw axis to the tip of blade 1 when the blade tip is below the yaw bearing. When the tip of blade 1 is above the yaw bearing, it is computed as the absolute distance from the yaw bearing to the blade tip. Please note that you should reduce this value by the tower radius to obtain the actual tower clearance.; N/A - -# Blade 2 Tip Motions -OutList['TipDxc2'] = True # (m); Blade 2 out-of-plane tip deflection (relative to the pitch axis); Directed along the xc2-axis -OutList['OoPDefl2'] = False # (m); Blade 2 out-of-plane tip deflection (relative to the pitch axis); Directed along the xc2-axis -OutList['TipDyc2'] = True # (m); Blade 2 in-plane tip deflection (relative to the pitch axis); Directed along the yc2-axis -OutList['IPDefl2'] = False # (m); Blade 2 in-plane tip deflection (relative to the pitch axis); Directed along the yc2-axis -OutList['TipDzc2'] = True # (m); Blade 2 axial tip deflection (relative to the pitch axis); Directed along the zc2- and zb2-axes -OutList['TipDzb2'] = True # (m); Blade 2 axial tip deflection (relative to the pitch axis); Directed along the zc2- and zb2-axes -OutList['TipDxb2'] = True # (m); Blade 2 flapwise tip deflection (relative to the pitch axis); Directed along the xb2-axis -OutList['TipDyb2'] = True # (m); Blade 2 edgewise tip deflection (relative to the pitch axis); Directed along the yb2-axis -OutList['TipALxb2'] = False # (m/s^2); Blade 2 local flapwise tip acceleration (absolute); Directed along the local xb2-axis -OutList['TipALyb2'] = False # (m/s^2); Blade 2 local edgewise tip acceleration (absolute); Directed along the local yb2-axis -OutList['TipALzb2'] = False # (m/s^2); Blade 2 local axial tip acceleration (absolute); Directed along the local zb2-axis -OutList['TipRDxb2'] = False # (deg); Blade 2 roll (angular/rotational) tip deflection (relative to the undeflected position). In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the xb2-axis -OutList['RollDefl2'] = False # (deg); Blade 2 roll (angular/rotational) tip deflection (relative to the undeflected position). In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the xb2-axis -OutList['TipRDyb2'] = False # (deg); Blade 2 pitch (angular/rotational) tip deflection (relative to the undeflected position). In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the yb2-axis -OutList['PtchDefl2'] = False # (deg); Blade 2 pitch (angular/rotational) tip deflection (relative to the undeflected position). In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the yb2-axis -OutList['TipRDzc2'] = False # (deg); Blade 2 torsional (angular/rotational) tip deflection (relative to the undeflected position). This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the zc2- and zb2-axes -OutList['TipRDzb2'] = False # (deg); Blade 2 torsional (angular/rotational) tip deflection (relative to the undeflected position). This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the zc2- and zb2-axes -OutList['TwstDefl2'] = False # (deg); Blade 2 torsional (angular/rotational) tip deflection (relative to the undeflected position). This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the zc2- and zb2-axes -OutList['TipClrnc2'] = False # (m); Blade 2 tip-to-tower clearance estimate. This is computed as the perpendicular distance from the yaw axis to the tip of blade 1 when the blade tip is below the yaw bearing. When the tip of blade 1 is above the yaw bearing, it is computed as the absolute distance from the yaw bearing to the blade tip. Please note that you should reduce this value by the tower radius to obtain the actual tower clearance.; N/A -OutList['TwrClrnc2'] = False # (m); Blade 2 tip-to-tower clearance estimate. This is computed as the perpendicular distance from the yaw axis to the tip of blade 1 when the blade tip is below the yaw bearing. When the tip of blade 1 is above the yaw bearing, it is computed as the absolute distance from the yaw bearing to the blade tip. Please note that you should reduce this value by the tower radius to obtain the actual tower clearance.; N/A -OutList['Tip2Twr2'] = False # (m); Blade 2 tip-to-tower clearance estimate. This is computed as the perpendicular distance from the yaw axis to the tip of blade 1 when the blade tip is below the yaw bearing. When the tip of blade 1 is above the yaw bearing, it is computed as the absolute distance from the yaw bearing to the blade tip. Please note that you should reduce this value by the tower radius to obtain the actual tower clearance.; N/A - -# Blade 3 Tip Motions -OutList['TipDxc3'] = True # (m); Blade 3 out-of-plane tip deflection (relative to the pitch axis); Directed along the xc3-axis -OutList['OoPDefl3'] = False # (m); Blade 3 out-of-plane tip deflection (relative to the pitch axis); Directed along the xc3-axis -OutList['TipDyc3'] = True # (m); Blade 3 in-plane tip deflection (relative to the pitch axis); Directed along the yc3-axis -OutList['IPDefl3'] = False # (m); Blade 3 in-plane tip deflection (relative to the pitch axis); Directed along the yc3-axis -OutList['TipDzc3'] = True # (m); Blade 3 axial tip deflection (relative to the pitch axis); Directed along the zc3- and zb3-axes -OutList['TipDzb3'] = True # (m); Blade 3 axial tip deflection (relative to the pitch axis); Directed along the zc3- and zb3-axes -OutList['TipDxb3'] = True # (m); Blade 3 flapwise tip deflection (relative to the pitch axis); Directed along the xb3-axis -OutList['TipDyb3'] = True # (m); Blade 3 edgewise tip deflection (relative to the pitch axis); Directed along the yb3-axis -OutList['TipALxb3'] = False # (m/s^2); Blade 3 local flapwise tip acceleration (absolute); Directed along the local xb3-axis -OutList['TipALyb3'] = False # (m/s^2); Blade 3 local edgewise tip acceleration (absolute); Directed along the local yb3-axis -OutList['TipALzb3'] = False # (m/s^2); Blade 3 local axial tip acceleration (absolute); Directed along the local zb3-axis -OutList['TipRDxb3'] = False # (deg); Blade 3 roll (angular/rotational) tip deflection (relative to the undeflected position). In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the xb3-axis -OutList['RollDefl3'] = False # (deg); Blade 3 roll (angular/rotational) tip deflection (relative to the undeflected position). In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the xb3-axis -OutList['TipRDyb3'] = False # (deg); Blade 3 pitch (angular/rotational) tip deflection (relative to the undeflected position). In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the yb3-axis -OutList['PtchDefl3'] = False # (deg); Blade 3 pitch (angular/rotational) tip deflection (relative to the undeflected position). In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the yb3-axis -OutList['TipRDzc3'] = False # (deg); Blade 3 torsional tip deflection (relative to the undeflected position). This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the zc3- and zb3-axes -OutList['TipRDzb3'] = False # (deg); Blade 3 torsional tip deflection (relative to the undeflected position). This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the zc3- and zb3-axes -OutList['TwstDefl3'] = False # (deg); Blade 3 torsional tip deflection (relative to the undeflected position). This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the zc3- and zb3-axes -OutList['TipClrnc3'] = False # (m); Blade 3 tip-to-tower clearance estimate. This is computed as the perpendicular distance from the yaw axis to the tip of blade 1 when the blade tip is below the yaw bearing. When the tip of blade 1 is above the yaw bearing, it is computed as the absolute distance from the yaw bearing to the blade tip. Please note that you should reduce this value by the tower radius to obtain the actual tower clearance.; N/A -OutList['TwrClrnc3'] = False # (m); Blade 3 tip-to-tower clearance estimate. This is computed as the perpendicular distance from the yaw axis to the tip of blade 1 when the blade tip is below the yaw bearing. When the tip of blade 1 is above the yaw bearing, it is computed as the absolute distance from the yaw bearing to the blade tip. Please note that you should reduce this value by the tower radius to obtain the actual tower clearance.; N/A -OutList['Tip2Twr3'] = False # (m); Blade 3 tip-to-tower clearance estimate. This is computed as the perpendicular distance from the yaw axis to the tip of blade 1 when the blade tip is below the yaw bearing. When the tip of blade 1 is above the yaw bearing, it is computed as the absolute distance from the yaw bearing to the blade tip. Please note that you should reduce this value by the tower radius to obtain the actual tower clearance.; N/A - -# Blade 1 Local Span Motions -OutList['Spn1ALxb1'] = False # (m/s^2); Blade 1 local flapwise acceleration (absolute) of span station 1; Directed along the local xb1-axis -OutList['Spn1ALyb1'] = False # (m/s^2); Blade 1 local edgewise acceleration (absolute) of span station 1; Directed along the local yb1-axis -OutList['Spn1ALzb1'] = False # (m/s^2); Blade 1 local axial acceleration (absolute) of span station 1; Directed along the local zb1-axis -OutList['Spn2ALxb1'] = False # (m/s^2); Blade 1 local flapwise acceleration (absolute) of span station 2; Directed along the local xb1-axis -OutList['Spn2ALyb1'] = False # (m/s^2); Blade 1 local edgewise acceleration (absolute) of span station 2; Directed along the local yb1-axis -OutList['Spn2ALzb1'] = False # (m/s^2); Blade 1 local axial acceleration (absolute) of span station 2; Directed along the local zb1-axis -OutList['Spn3ALxb1'] = False # (m/s^2); Blade 1 local flapwise acceleration (absolute) of span station 3; Directed along the local xb1-axis -OutList['Spn3ALyb1'] = False # (m/s^2); Blade 1 local edgewise acceleration (absolute) of span station 3; Directed along the local yb1-axis -OutList['Spn3ALzb1'] = False # (m/s^2); Blade 1 local axial acceleration (absolute) of span station 3; Directed along the local zb1-axis -OutList['Spn4ALxb1'] = False # (m/s^2); Blade 1 local flapwise acceleration (absolute) of span station 4; Directed along the local xb1-axis -OutList['Spn4ALyb1'] = False # (m/s^2); Blade 1 local edgewise acceleration (absolute) of span station 4; Directed along the local yb1-axis -OutList['Spn4ALzb1'] = False # (m/s^2); Blade 1 local axial acceleration (absolute) of span station 4; Directed along the local zb1-axis -OutList['Spn5ALxb1'] = False # (m/s^2); Blade 1 local flapwise acceleration (absolute) of span station 5; Directed along the local xb1-axis -OutList['Spn5ALyb1'] = False # (m/s^2); Blade 1 local edgewise acceleration (absolute) of span station 5; Directed along the local yb1-axis -OutList['Spn5ALzb1'] = False # (m/s^2); Blade 1 local axial acceleration (absolute) of span station 5; Directed along the local zb1-axis -OutList['Spn6ALxb1'] = False # (m/s^2); Blade 1 local flapwise acceleration (absolute) of span station 6; Directed along the local xb1-axis -OutList['Spn6ALyb1'] = False # (m/s^2); Blade 1 local edgewise acceleration (absolute) of span station 6; Directed along the local yb1-axis -OutList['Spn6ALzb1'] = False # (m/s^2); Blade 1 local axial acceleration (absolute) of span station 6; Directed along the local zb1-axis -OutList['Spn7ALxb1'] = False # (m/s^2); Blade 1 local flapwise acceleration (absolute) of span station 7; Directed along the local xb1-axis -OutList['Spn7ALyb1'] = False # (m/s^2); Blade 1 local edgewise acceleration (absolute) of span station 7; Directed along the local yb1-axis -OutList['Spn7ALzb1'] = False # (m/s^2); Blade 1 local axial acceleration (absolute) of span station 7; Directed along the local zb1-axis -OutList['Spn8ALxb1'] = False # (m/s^2); Blade 1 local flapwise acceleration (absolute) of span station 8; Directed along the local xb1-axis -OutList['Spn8ALyb1'] = False # (m/s^2); Blade 1 local edgewise acceleration (absolute) of span station 8; Directed along the local yb1-axis -OutList['Spn8ALzb1'] = False # (m/s^2); Blade 1 local axial acceleration (absolute) of span station 8; Directed along the local zb1-axis -OutList['Spn9ALxb1'] = False # (m/s^2); Blade 1 local flapwise acceleration (absolute) of span station 9; Directed along the local xb1-axis -OutList['Spn9ALyb1'] = False # (m/s^2); Blade 1 local edgewise acceleration (absolute) of span station 9; Directed along the local yb1-axis -OutList['Spn9ALzb1'] = False # (m/s^2); Blade 1 local axial acceleration (absolute) of span station 9; Directed along the local zb1-axis -OutList['Spn1TDxb1'] = False # (m); Blade 1 local flapwise (translational) deflection (relative to the undeflected position) of span station 1; Directed along the xb1-axis -OutList['Spn1TDyb1'] = False # (m); Blade 1 local edgewise (translational) deflection (relative to the undeflected position) of span station 1; Directed along the yb1-axis -OutList['Spn1TDzb1'] = False # (m); Blade 1 local axial (translational) deflection (relative to the undeflected position) of span station 1; Directed along the zb1-axis -OutList['Spn2TDxb1'] = False # (m); Blade 1 local flapwise (translational) deflection (relative to the undeflected position) of span station 2; Directed along the xb1-axis -OutList['Spn2TDyb1'] = False # (m); Blade 1 local edgewise (translational) deflection (relative to the undeflected position) of span station 2; Directed along the yb1-axis -OutList['Spn2TDzb1'] = False # (m); Blade 1 local axial (translational) deflection (relative to the undeflected position) of span station 2; Directed along the zb1-axis -OutList['Spn3TDxb1'] = False # (m); Blade 1 local flapwise (translational) deflection (relative to the undeflected position) of span station 3; Directed along the xb1-axis -OutList['Spn3TDyb1'] = False # (m); Blade 1 local edgewise (translational) deflection (relative to the undeflected position) of span station 3; Directed along the yb1-axis -OutList['Spn3TDzb1'] = False # (m); Blade 1 local axial (translational) deflection (relative to the undeflected position) of span station 3; Directed along the zb1-axis -OutList['Spn4TDxb1'] = False # (m); Blade 1 local flapwise (translational) deflection (relative to the undeflected position) of span station 4; Directed along the xb1-axis -OutList['Spn4TDyb1'] = False # (m); Blade 1 local edgewise (translational) deflection (relative to the undeflected position) of span station 4; Directed along the yb1-axis -OutList['Spn4TDzb1'] = False # (m); Blade 1 local axial (translational) deflection (relative to the undeflected position) of span station 4; Directed along the zb1-axis -OutList['Spn5TDxb1'] = False # (m); Blade 1 local flapwise (translational) deflection (relative to the undeflected position) of span station 5; Directed along the xb1-axis -OutList['Spn5TDyb1'] = False # (m); Blade 1 local edgewise (translational) deflection (relative to the undeflected position) of span station 5; Directed along the yb1-axis -OutList['Spn5TDzb1'] = False # (m); Blade 1 local axial (translational) deflection (relative to the undeflected position) of span station 5; Directed along the zb1-axis -OutList['Spn6TDxb1'] = False # (m); Blade 1 local flapwise (translational) deflection (relative to the undeflected position) of span station 6; Directed along the xb1-axis -OutList['Spn6TDyb1'] = False # (m); Blade 1 local edgewise (translational) deflection (relative to the undeflected position) of span station 6; Directed along the yb1-axis -OutList['Spn6TDzb1'] = False # (m); Blade 1 local axial (translational) deflection (relative to the undeflected position) of span station 6; Directed along the zb1-axis -OutList['Spn7TDxb1'] = False # (m); Blade 1 local flapwise (translational) deflection (relative to the undeflected position) of span station 7; Directed along the xb1-axis -OutList['Spn7TDyb1'] = False # (m); Blade 1 local edgewise (translational) deflection (relative to the undeflected position) of span station 7; Directed along the yb1-axis -OutList['Spn7TDzb1'] = False # (m); Blade 1 local axial (translational) deflection (relative to the undeflected position) of span station 7; Directed along the zb1-axis -OutList['Spn8TDxb1'] = False # (m); Blade 1 local flapwise (translational) deflection (relative to the undeflected position) of span station 8; Directed along the xb1-axis -OutList['Spn8TDyb1'] = False # (m); Blade 1 local edgewise (translational) deflection (relative to the undeflected position) of span station 8; Directed along the yb1-axis -OutList['Spn8TDzb1'] = False # (m); Blade 1 local axial (translational) deflection (relative to the undeflected position) of span station 8; Directed along the zb1-axis -OutList['Spn9TDxb1'] = False # (m); Blade 1 local flapwise (translational) deflection (relative to the undeflected position) of span station 9; Directed along the xb1-axis -OutList['Spn9TDyb1'] = False # (m); Blade 1 local edgewise (translational) deflection (relative to the undeflected position) of span station 9; Directed along the yb1-axis -OutList['Spn9TDzb1'] = False # (m); Blade 1 local axial (translational) deflection (relative to the undeflected position) of span station 9; Directed along the zb1-axis -OutList['Spn1RDxb1'] = False # (deg); Blade 1 local roll (angular/rotational) deflection (relative to the undeflected position) of span station 1. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local xb1-axis -OutList['Spn1RDyb1'] = False # (deg); Blade 1 local pitch (angular/rotational) deflection (relative to the undeflected position) of span station 1. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local yb1-axis -OutList['Spn1RDzb1'] = False # (deg); Blade 1 local torsional (angular/rotational) deflection (relative to the undeflected position) of span station 1. This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the local zb1-axis -OutList['Spn2RDxb1'] = False # (deg); Blade 1 local roll (angular/rotational) deflection (relative to the undeflected position) of span station 2. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local xb1-axis -OutList['Spn2RDyb1'] = False # (deg); Blade 1 local pitch (angular/rotational) deflection (relative to the undeflected position) of span station 2. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local yb1-axis -OutList['Spn2RDzb1'] = False # (deg); Blade 1 local torsional (angular/rotational) deflection (relative to the undeflected position) of span station 2. This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the local zb1-axis -OutList['Spn3RDxb1'] = False # (deg); Blade 1 local roll (angular/rotational) deflection (relative to the undeflected position) of span station 3. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local xb1-axis -OutList['Spn3RDyb1'] = False # (deg); Blade 1 local pitch (angular/rotational) deflection (relative to the undeflected position) of span station 3. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local yb1-axis -OutList['Spn3RDzb1'] = False # (deg); Blade 1 local torsional (angular/rotational) deflection (relative to the undeflected position) of span station 3. This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the local zb1-axis -OutList['Spn4RDxb1'] = False # (deg); Blade 1 local roll (angular/rotational) deflection (relative to the undeflected position) of span station 4. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local xb1-axis -OutList['Spn4RDyb1'] = False # (deg); Blade 1 local pitch (angular/rotational) deflection (relative to the undeflected position) of span station 4. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local yb1-axis -OutList['Spn4RDzb1'] = False # (deg); Blade 1 local torsional (angular/rotational) deflection (relative to the undeflected position) of span station 4. This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the local zb1-axis -OutList['Spn5RDxb1'] = False # (deg); Blade 1 local roll (angular/rotational) deflection (relative to the undeflected position) of span station 5. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local xb1-axis -OutList['Spn5RDyb1'] = False # (deg); Blade 1 local pitch (angular/rotational) deflection (relative to the undeflected position) of span station 5. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local yb1-axis -OutList['Spn5RDzb1'] = False # (deg); Blade 1 local torsional (angular/rotational) deflection (relative to the undeflected position) of span station 5. This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the local zb1-axis -OutList['Spn6RDxb1'] = False # (deg); Blade 1 local roll (angular/rotational) deflection (relative to the undeflected position) of span station 6. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local xb1-axis -OutList['Spn6RDyb1'] = False # (deg); Blade 1 local pitch (angular/rotational) deflection (relative to the undeflected position) of span station 6. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local yb1-axis -OutList['Spn6RDzb1'] = False # (deg); Blade 1 local torsional (angular/rotational) deflection (relative to the undeflected position) of span station 6. This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the local zb1-axis -OutList['Spn7RDxb1'] = False # (deg); Blade 1 local roll (angular/rotational) deflection (relative to the undeflected position) of span station 7. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local xb1-axis -OutList['Spn7RDyb1'] = False # (deg); Blade 1 local pitch (angular/rotational) deflection (relative to the undeflected position) of span station 7. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local yb1-axis -OutList['Spn7RDzb1'] = False # (deg); Blade 1 local torsional (angular/rotational) deflection (relative to the undeflected position) of span station 7. This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the local zb1-axis -OutList['Spn8RDxb1'] = False # (deg); Blade 1 local roll (angular/rotational) deflection (relative to the undeflected position) of span station 8. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local xb1-axis -OutList['Spn8RDyb1'] = False # (deg); Blade 1 local pitch (angular/rotational) deflection (relative to the undeflected position) of span station 8. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local yb1-axis -OutList['Spn8RDzb1'] = False # (deg); Blade 1 local torsional (angular/rotational) deflection (relative to the undeflected position) of span station 8. This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the local zb1-axis -OutList['Spn9RDxb1'] = False # (deg); Blade 1 local roll (angular/rotational) deflection (relative to the undeflected position) of span station 9. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local xb1-axis -OutList['Spn9RDyb1'] = False # (deg); Blade 1 local pitch (angular/rotational) deflection (relative to the undeflected position) of span station 9. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local yb1-axis -OutList['Spn9RDzb1'] = False # (deg); Blade 1 local torsional (angular/rotational) deflection (relative to the undeflected position) of span station 9. This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the local zb1-axis - -# Blade 2 Local Span Motions -OutList['Spn1ALxb2'] = False # (m/s^2); Blade 2 local flapwise acceleration (absolute) of span station 1; Directed along the local xb2-axis -OutList['Spn1ALyb2'] = False # (m/s^2); Blade 2 local edgewise acceleration (absolute) of span station 1; Directed along the local yb2-axis -OutList['Spn1ALzb2'] = False # (m/s^2); Blade 2 local axial acceleration (absolute) of span station 1; Directed along the local zb2-axis -OutList['Spn2ALxb2'] = False # (m/s^2); Blade 2 local flapwise acceleration (absolute) of span station 2; Directed along the local xb2-axis -OutList['Spn2ALyb2'] = False # (m/s^2); Blade 2 local edgewise acceleration (absolute) of span station 2; Directed along the local yb2-axis -OutList['Spn2ALzb2'] = False # (m/s^2); Blade 2 local axial acceleration (absolute) of span station 2; Directed along the local zb2-axis -OutList['Spn3ALxb2'] = False # (m/s^2); Blade 2 local flapwise acceleration (absolute) of span station 3; Directed along the local xb2-axis -OutList['Spn3ALyb2'] = False # (m/s^2); Blade 2 local edgewise acceleration (absolute) of span station 3; Directed along the local yb2-axis -OutList['Spn3ALzb2'] = False # (m/s^2); Blade 2 local axial acceleration (absolute) of span station 3; Directed along the local zb2-axis -OutList['Spn4ALxb2'] = False # (m/s^2); Blade 2 local flapwise acceleration (absolute) of span station 4; Directed along the local xb2-axis -OutList['Spn4ALyb2'] = False # (m/s^2); Blade 2 local edgewise acceleration (absolute) of span station 4; Directed along the local yb2-axis -OutList['Spn4ALzb2'] = False # (m/s^2); Blade 2 local axial acceleration (absolute) of span station 4; Directed along the local zb2-axis -OutList['Spn5ALxb2'] = False # (m/s^2); Blade 2 local flapwise acceleration (absolute) of span station 5; Directed along the local xb2-axis -OutList['Spn5ALyb2'] = False # (m/s^2); Blade 2 local edgewise acceleration (absolute) of span station 5; Directed along the local yb2-axis -OutList['Spn5ALzb2'] = False # (m/s^2); Blade 2 local axial acceleration (absolute) of span station 5; Directed along the local zb2-axis -OutList['Spn6ALxb2'] = False # (m/s^2); Blade 2 local flapwise acceleration (absolute) of span station 6; Directed along the local xb2-axis -OutList['Spn6ALyb2'] = False # (m/s^2); Blade 2 local edgewise acceleration (absolute) of span station 6; Directed along the local yb2-axis -OutList['Spn6ALzb2'] = False # (m/s^2); Blade 2 local axial acceleration (absolute) of span station 6; Directed along the local zb2-axis -OutList['Spn7ALxb2'] = False # (m/s^2); Blade 2 local flapwise acceleration (absolute) of span station 7; Directed along the local xb2-axis -OutList['Spn7ALyb2'] = False # (m/s^2); Blade 2 local edgewise acceleration (absolute) of span station 7; Directed along the local yb2-axis -OutList['Spn7ALzb2'] = False # (m/s^2); Blade 2 local axial acceleration (absolute) of span station 7; Directed along the local zb2-axis -OutList['Spn8ALxb2'] = False # (m/s^2); Blade 2 local flapwise acceleration (absolute) of span station 8; Directed along the local xb2-axis -OutList['Spn8ALyb2'] = False # (m/s^2); Blade 2 local edgewise acceleration (absolute) of span station 8; Directed along the local yb2-axis -OutList['Spn8ALzb2'] = False # (m/s^2); Blade 2 local axial acceleration (absolute) of span station 8; Directed along the local zb2-axis -OutList['Spn9ALxb2'] = False # (m/s^2); Blade 2 local flapwise acceleration (absolute) of span station 9; Directed along the local xb2-axis -OutList['Spn9ALyb2'] = False # (m/s^2); Blade 2 local edgewise acceleration (absolute) of span station 9; Directed along the local yb2-axis -OutList['Spn9ALzb2'] = False # (m/s^2); Blade 2 local axial acceleration (absolute) of span station 9; Directed along the local zb2-axis -OutList['Spn1TDxb2'] = False # (m); Blade 2 local flapwise (translational) deflection (relative to the undeflected position) of span station 1; Directed along the xb2-axis -OutList['Spn1TDyb2'] = False # (m); Blade 2 local edgewise (translational) deflection (relative to the undeflected position) of span station 1; Directed along the yb2-axis -OutList['Spn1TDzb2'] = False # (m); Blade 2 local axial (translational) deflection (relative to the undeflected position) of span station 1; Directed along the zb2-axis -OutList['Spn2TDxb2'] = False # (m); Blade 2 local flapwise (translational) deflection (relative to the undeflected position) of span station 2; Directed along the xb2-axis -OutList['Spn2TDyb2'] = False # (m); Blade 2 local edgewise (translational) deflection (relative to the undeflected position) of span station 2; Directed along the yb2-axis -OutList['Spn2TDzb2'] = False # (m); Blade 2 local axial (translational) deflection (relative to the undeflected position) of span station 2; Directed along the zb2-axis -OutList['Spn3TDxb2'] = False # (m); Blade 2 local flapwise (translational) deflection (relative to the undeflected position) of span station 3; Directed along the xb2-axis -OutList['Spn3TDyb2'] = False # (m); Blade 2 local edgewise (translational) deflection (relative to the undeflected position) of span station 3; Directed along the yb2-axis -OutList['Spn3TDzb2'] = False # (m); Blade 2 local axial (translational) deflection (relative to the undeflected position) of span station 3; Directed along the zb2-axis -OutList['Spn4TDxb2'] = False # (m); Blade 2 local flapwise (translational) deflection (relative to the undeflected position) of span station 4; Directed along the xb2-axis -OutList['Spn4TDyb2'] = False # (m); Blade 2 local edgewise (translational) deflection (relative to the undeflected position) of span station 4; Directed along the yb2-axis -OutList['Spn4TDzb2'] = False # (m); Blade 2 local axial (translational) deflection (relative to the undeflected position) of span station 4; Directed along the zb2-axis -OutList['Spn5TDxb2'] = False # (m); Blade 2 local flapwise (translational) deflection (relative to the undeflected position) of span station 5; Directed along the xb2-axis -OutList['Spn5TDyb2'] = False # (m); Blade 2 local edgewise (translational) deflection (relative to the undeflected position) of span station 5; Directed along the yb2-axis -OutList['Spn5TDzb2'] = False # (m); Blade 2 local axial (translational) deflection (relative to the undeflected position) of span station 5; Directed along the zb2-axis -OutList['Spn6TDxb2'] = False # (m); Blade 2 local flapwise (translational) deflection (relative to the undeflected position) of span station 6; Directed along the xb2-axis -OutList['Spn6TDyb2'] = False # (m); Blade 2 local edgewise (translational) deflection (relative to the undeflected position) of span station 6; Directed along the yb2-axis -OutList['Spn6TDzb2'] = False # (m); Blade 2 local axial (translational) deflection (relative to the undeflected position) of span station 6; Directed along the zb2-axis -OutList['Spn7TDxb2'] = False # (m); Blade 2 local flapwise (translational) deflection (relative to the undeflected position) of span station 7; Directed along the xb2-axis -OutList['Spn7TDyb2'] = False # (m); Blade 2 local edgewise (translational) deflection (relative to the undeflected position) of span station 7; Directed along the yb2-axis -OutList['Spn7TDzb2'] = False # (m); Blade 2 local axial (translational) deflection (relative to the undeflected position) of span station 7; Directed along the zb2-axis -OutList['Spn8TDxb2'] = False # (m); Blade 2 local flapwise (translational) deflection (relative to the undeflected position) of span station 8; Directed along the xb2-axis -OutList['Spn8TDyb2'] = False # (m); Blade 2 local edgewise (translational) deflection (relative to the undeflected position) of span station 8; Directed along the yb2-axis -OutList['Spn8TDzb2'] = False # (m); Blade 2 local axial (translational) deflection (relative to the undeflected position) of span station 8; Directed along the zb2-axis -OutList['Spn9TDxb2'] = False # (m); Blade 2 local flapwise (translational) deflection (relative to the undeflected position) of span station 9; Directed along the xb2-axis -OutList['Spn9TDyb2'] = False # (m); Blade 2 local edgewise (translational) deflection (relative to the undeflected position) of span station 9; Directed along the yb2-axis -OutList['Spn9TDzb2'] = False # (m); Blade 2 local axial (translational) deflection (relative to the undeflected position) of span station 9; Directed along the zb2-axis -OutList['Spn1RDxb2'] = False # (deg); Blade 2 local roll (angular/rotational) deflection (relative to the undeflected position) of span station 1. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local xb2-axis -OutList['Spn1RDyb2'] = False # (deg); Blade 2 local pitch (angular/rotational) deflection (relative to the undeflected position) of span station 1. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local yb2-axis -OutList['Spn1RDzb2'] = False # (deg); Blade 2 local torsional (angular/rotational) deflection (relative to the undeflected position) of span station 1. This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the local zb2-axis -OutList['Spn2RDxb2'] = False # (deg); Blade 2 local roll (angular/rotational) deflection (relative to the undeflected position) of span station 2. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local xb2-axis -OutList['Spn2RDyb2'] = False # (deg); Blade 2 local pitch (angular/rotational) deflection (relative to the undeflected position) of span station 2. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local yb2-axis -OutList['Spn2RDzb2'] = False # (deg); Blade 2 local torsional (angular/rotational) deflection (relative to the undeflected position) of span station 2. This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the local zb2-axis -OutList['Spn3RDxb2'] = False # (deg); Blade 2 local roll (angular/rotational) deflection (relative to the undeflected position) of span station 3. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local xb2-axis -OutList['Spn3RDyb2'] = False # (deg); Blade 2 local pitch (angular/rotational) deflection (relative to the undeflected position) of span station 3. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local yb2-axis -OutList['Spn3RDzb2'] = False # (deg); Blade 2 local torsional (angular/rotational) deflection (relative to the undeflected position) of span station 3. This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the local zb2-axis -OutList['Spn4RDxb2'] = False # (deg); Blade 2 local roll (angular/rotational) deflection (relative to the undeflected position) of span station 4. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local xb2-axis -OutList['Spn4RDyb2'] = False # (deg); Blade 2 local pitch (angular/rotational) deflection (relative to the undeflected position) of span station 4. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local yb2-axis -OutList['Spn4RDzb2'] = False # (deg); Blade 2 local torsional (angular/rotational) deflection (relative to the undeflected position) of span station 4. This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the local zb2-axis -OutList['Spn5RDxb2'] = False # (deg); Blade 2 local roll (angular/rotational) deflection (relative to the undeflected position) of span station 5. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local xb2-axis -OutList['Spn5RDyb2'] = False # (deg); Blade 2 local pitch (angular/rotational) deflection (relative to the undeflected position) of span station 5. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local yb2-axis -OutList['Spn5RDzb2'] = False # (deg); Blade 2 local torsional (angular/rotational) deflection (relative to the undeflected position) of span station 5. This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the local zb2-axis -OutList['Spn6RDxb2'] = False # (deg); Blade 2 local roll (angular/rotational) deflection (relative to the undeflected position) of span station 6. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local xb2-axis -OutList['Spn6RDyb2'] = False # (deg); Blade 2 local pitch (angular/rotational) deflection (relative to the undeflected position) of span station 6. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local yb2-axis -OutList['Spn6RDzb2'] = False # (deg); Blade 2 local torsional (angular/rotational) deflection (relative to the undeflected position) of span station 6. This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the local zb2-axis -OutList['Spn7RDxb2'] = False # (deg); Blade 2 local roll (angular/rotational) deflection (relative to the undeflected position) of span station 7. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local xb2-axis -OutList['Spn7RDyb2'] = False # (deg); Blade 2 local pitch (angular/rotational) deflection (relative to the undeflected position) of span station 7. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local yb2-axis -OutList['Spn7RDzb2'] = False # (deg); Blade 2 local torsional (angular/rotational) deflection (relative to the undeflected position) of span station 7. This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the local zb2-axis -OutList['Spn8RDxb2'] = False # (deg); Blade 2 local roll (angular/rotational) deflection (relative to the undeflected position) of span station 8. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local xb2-axis -OutList['Spn8RDyb2'] = False # (deg); Blade 2 local pitch (angular/rotational) deflection (relative to the undeflected position) of span station 8. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local yb2-axis -OutList['Spn8RDzb2'] = False # (deg); Blade 2 local torsional (angular/rotational) deflection (relative to the undeflected position) of span station 8. This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the local zb2-axis -OutList['Spn9RDxb2'] = False # (deg); Blade 2 local roll (angular/rotational) deflection (relative to the undeflected position) of span station 9. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local xb2-axis -OutList['Spn9RDyb2'] = False # (deg); Blade 2 local pitch (angular/rotational) deflection (relative to the undeflected position) of span station 9. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local yb2-axis -OutList['Spn9RDzb2'] = False # (deg); Blade 2 local torsional (angular/rotational) deflection (relative to the undeflected position) of span station 9. This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the local zb2-axis - -# Blade 3 Local Span Motions -OutList['Spn1ALxb3'] = False # (m/s^2); Blade 3 local flapwise acceleration (absolute) of span station 1; Directed along the local xb3-axis -OutList['Spn1ALyb3'] = False # (m/s^2); Blade 3 local edgewise acceleration (absolute) of span station 1; Directed along the local yb3-axis -OutList['Spn1ALzb3'] = False # (m/s^2); Blade 3 local axial acceleration (absolute) of span station 1; Directed along the local zb3-axis -OutList['Spn2ALxb3'] = False # (m/s^2); Blade 3 local flapwise acceleration (absolute) of span station 2; Directed along the local xb3-axis -OutList['Spn2ALyb3'] = False # (m/s^2); Blade 3 local edgewise acceleration (absolute) of span station 2; Directed along the local yb3-axis -OutList['Spn2ALzb3'] = False # (m/s^2); Blade 3 local axial acceleration (absolute) of span station 2; Directed along the local zb3-axis -OutList['Spn3ALxb3'] = False # (m/s^2); Blade 3 local flapwise acceleration (absolute) of span station 3; Directed along the local xb3-axis -OutList['Spn3ALyb3'] = False # (m/s^2); Blade 3 local edgewise acceleration (absolute) of span station 3; Directed along the local yb3-axis -OutList['Spn3ALzb3'] = False # (m/s^2); Blade 3 local axial acceleration (absolute) of span station 3; Directed along the local zb3-axis -OutList['Spn4ALxb3'] = False # (m/s^2); Blade 3 local flapwise acceleration (absolute) of span station 4; Directed along the local xb3-axis -OutList['Spn4ALyb3'] = False # (m/s^2); Blade 3 local edgewise acceleration (absolute) of span station 4; Directed along the local yb3-axis -OutList['Spn4ALzb3'] = False # (m/s^2); Blade 3 local axial acceleration (absolute) of span station 4; Directed along the local zb3-axis -OutList['Spn5ALxb3'] = False # (m/s^2); Blade 3 local flapwise acceleration (absolute) of span station 5; Directed along the local xb3-axis -OutList['Spn5ALyb3'] = False # (m/s^2); Blade 3 local edgewise acceleration (absolute) of span station 5; Directed along the local yb3-axis -OutList['Spn5ALzb3'] = False # (m/s^2); Blade 3 local axial acceleration (absolute) of span station 5; Directed along the local zb3-axis -OutList['Spn6ALxb3'] = False # (m/s^2); Blade 3 local flapwise acceleration (absolute) of span station 6; Directed along the local xb3-axis -OutList['Spn6ALyb3'] = False # (m/s^2); Blade 3 local edgewise acceleration (absolute) of span station 6; Directed along the local yb3-axis -OutList['Spn6ALzb3'] = False # (m/s^2); Blade 3 local axial acceleration (absolute) of span station 6; Directed along the local zb3-axis -OutList['Spn7ALxb3'] = False # (m/s^2); Blade 3 local flapwise acceleration (absolute) of span station 7; Directed along the local xb3-axis -OutList['Spn7ALyb3'] = False # (m/s^2); Blade 3 local edgewise acceleration (absolute) of span station 7; Directed along the local yb3-axis -OutList['Spn7ALzb3'] = False # (m/s^2); Blade 3 local axial acceleration (absolute) of span station 7; Directed along the local zb3-axis -OutList['Spn8ALxb3'] = False # (m/s^2); Blade 3 local flapwise acceleration (absolute) of span station 8; Directed along the local xb3-axis -OutList['Spn8ALyb3'] = False # (m/s^2); Blade 3 local edgewise acceleration (absolute) of span station 8; Directed along the local yb3-axis -OutList['Spn8ALzb3'] = False # (m/s^2); Blade 3 local axial acceleration (absolute) of span station 8; Directed along the local zb3-axis -OutList['Spn9ALxb3'] = False # (m/s^2); Blade 3 local flapwise acceleration (absolute) of span station 9; Directed along the local xb3-axis -OutList['Spn9ALyb3'] = False # (m/s^2); Blade 3 local edgewise acceleration (absolute) of span station 9; Directed along the local yb3-axis -OutList['Spn9ALzb3'] = False # (m/s^2); Blade 3 local axial acceleration (absolute) of span station 9; Directed along the local zb3-axis -OutList['Spn1TDxb3'] = False # (m); Blade 3 local flapwise (translational) deflection (relative to the undeflected position) of span station 1; Directed along the xb3-axis -OutList['Spn1TDyb3'] = False # (m); Blade 3 local edgewise (translational) deflection (relative to the undeflected position) of span station 1; Directed along the yb3-axis -OutList['Spn1TDzb3'] = False # (m); Blade 3 local axial (translational) deflection (relative to the undeflected position) of span station 1; Directed along the zb3-axis -OutList['Spn2TDxb3'] = False # (m); Blade 3 local flapwise (translational) deflection (relative to the undeflected position) of span station 2; Directed along the xb3-axis -OutList['Spn2TDyb3'] = False # (m); Blade 3 local edgewise (translational) deflection (relative to the undeflected position) of span station 2; Directed along the yb3-axis -OutList['Spn2TDzb3'] = False # (m); Blade 3 local axial (translational) deflection (relative to the undeflected position) of span station 2; Directed along the zb3-axis -OutList['Spn3TDxb3'] = False # (m); Blade 3 local flapwise (translational) deflection (relative to the undeflected position) of span station 3; Directed along the xb3-axis -OutList['Spn3TDyb3'] = False # (m); Blade 3 local edgewise (translational) deflection (relative to the undeflected position) of span station 3; Directed along the yb3-axis -OutList['Spn3TDzb3'] = False # (m); Blade 3 local axial (translational) deflection (relative to the undeflected position) of span station 3; Directed along the zb3-axis -OutList['Spn4TDxb3'] = False # (m); Blade 3 local flapwise (translational) deflection (relative to the undeflected position) of span station 4; Directed along the xb3-axis -OutList['Spn4TDyb3'] = False # (m); Blade 3 local edgewise (translational) deflection (relative to the undeflected position) of span station 4; Directed along the yb3-axis -OutList['Spn4TDzb3'] = False # (m); Blade 3 local axial (translational) deflection (relative to the undeflected position) of span station 4; Directed along the zb3-axis -OutList['Spn5TDxb3'] = False # (m); Blade 3 local flapwise (translational) deflection (relative to the undeflected position) of span station 5; Directed along the xb3-axis -OutList['Spn5TDyb3'] = False # (m); Blade 3 local edgewise (translational) deflection (relative to the undeflected position) of span station 5; Directed along the yb3-axis -OutList['Spn5TDzb3'] = False # (m); Blade 3 local axial (translational) deflection (relative to the undeflected position) of span station 5; Directed along the zb3-axis -OutList['Spn6TDxb3'] = False # (m); Blade 3 local flapwise (translational) deflection (relative to the undeflected position) of span station 6; Directed along the xb3-axis -OutList['Spn6TDyb3'] = False # (m); Blade 3 local edgewise (translational) deflection (relative to the undeflected position) of span station 6; Directed along the yb3-axis -OutList['Spn6TDzb3'] = False # (m); Blade 3 local axial (translational) deflection (relative to the undeflected position) of span station 6; Directed along the zb3-axis -OutList['Spn7TDxb3'] = False # (m); Blade 3 local flapwise (translational) deflection (relative to the undeflected position) of span station 7; Directed along the xb3-axis -OutList['Spn7TDyb3'] = False # (m); Blade 3 local edgewise (translational) deflection (relative to the undeflected position) of span station 7; Directed along the yb3-axis -OutList['Spn7TDzb3'] = False # (m); Blade 3 local axial (translational) deflection (relative to the undeflected position) of span station 7; Directed along the zb3-axis -OutList['Spn8TDxb3'] = False # (m); Blade 3 local flapwise (translational) deflection (relative to the undeflected position) of span station 8; Directed along the xb3-axis -OutList['Spn8TDyb3'] = False # (m); Blade 3 local edgewise (translational) deflection (relative to the undeflected position) of span station 8; Directed along the yb3-axis -OutList['Spn8TDzb3'] = False # (m); Blade 3 local axial (translational) deflection (relative to the undeflected position) of span station 8; Directed along the zb3-axis -OutList['Spn9TDxb3'] = False # (m); Blade 3 local flapwise (translational) deflection (relative to the undeflected position) of span station 9; Directed along the xb3-axis -OutList['Spn9TDyb3'] = False # (m); Blade 3 local edgewise (translational) deflection (relative to the undeflected position) of span station 9; Directed along the yb3-axis -OutList['Spn9TDzb3'] = False # (m); Blade 3 local axial (translational) deflection (relative to the undeflected position) of span station 9; Directed along the zb3-axis -OutList['Spn1RDxb3'] = False # (deg); Blade 3 local roll (angular/rotational) deflection (relative to the undeflected position) of span station 1. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local xb3-axis -OutList['Spn1RDyb3'] = False # (deg); Blade 3 local pitch (angular/rotational) deflection (relative to the undeflected position) of span station 1. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local yb3-axis -OutList['Spn1RDzb3'] = False # (deg); Blade 3 local torsional (angular/rotational) deflection (relative to the undeflected position) of span station 1. This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the local zb3-axis -OutList['Spn2RDxb3'] = False # (deg); Blade 3 local roll (angular/rotational) deflection (relative to the undeflected position) of span station 2. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local xb3-axis -OutList['Spn2RDyb3'] = False # (deg); Blade 3 local pitch (angular/rotational) deflection (relative to the undeflected position) of span station 2. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local yb3-axis -OutList['Spn2RDzb3'] = False # (deg); Blade 3 local torsional (angular/rotational) deflection (relative to the undeflected position) of span station 2. This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the local zb3-axis -OutList['Spn3RDxb3'] = False # (deg); Blade 3 local roll (angular/rotational) deflection (relative to the undeflected position) of span station 3. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local xb3-axis -OutList['Spn3RDyb3'] = False # (deg); Blade 3 local pitch (angular/rotational) deflection (relative to the undeflected position) of span station 3. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local yb3-axis -OutList['Spn3RDzb3'] = False # (deg); Blade 3 local torsional (angular/rotational) deflection (relative to the undeflected position) of span station 3. This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the local zb3-axis -OutList['Spn4RDxb3'] = False # (deg); Blade 3 local roll (angular/rotational) deflection (relative to the undeflected position) of span station 4. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local xb3-axis -OutList['Spn4RDyb3'] = False # (deg); Blade 3 local pitch (angular/rotational) deflection (relative to the undeflected position) of span station 4. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local yb3-axis -OutList['Spn4RDzb3'] = False # (deg); Blade 3 local torsional (angular/rotational) deflection (relative to the undeflected position) of span station 4. This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the local zb3-axis -OutList['Spn5RDxb3'] = False # (deg); Blade 3 local roll (angular/rotational) deflection (relative to the undeflected position) of span station 5. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local xb3-axis -OutList['Spn5RDyb3'] = False # (deg); Blade 3 local pitch (angular/rotational) deflection (relative to the undeflected position) of span station 5. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local yb3-axis -OutList['Spn5RDzb3'] = False # (deg); Blade 3 local torsional (angular/rotational) deflection (relative to the undeflected position) of span station 5. This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the local zb3-axis -OutList['Spn6RDxb3'] = False # (deg); Blade 3 local roll (angular/rotational) deflection (relative to the undeflected position) of span station 6. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local xb3-axis -OutList['Spn6RDyb3'] = False # (deg); Blade 3 local pitch (angular/rotational) deflection (relative to the undeflected position) of span station 6. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local yb3-axis -OutList['Spn6RDzb3'] = False # (deg); Blade 3 local torsional (angular/rotational) deflection (relative to the undeflected position) of span station 6. This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the local zb3-axis -OutList['Spn7RDxb3'] = False # (deg); Blade 3 local roll (angular/rotational) deflection (relative to the undeflected position) of span station 7. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local xb3-axis -OutList['Spn7RDyb3'] = False # (deg); Blade 3 local pitch (angular/rotational) deflection (relative to the undeflected position) of span station 7. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local yb3-axis -OutList['Spn7RDzb3'] = False # (deg); Blade 3 local torsional (angular/rotational) deflection (relative to the undeflected position) of span station 7. This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the local zb3-axis -OutList['Spn8RDxb3'] = False # (deg); Blade 3 local roll (angular/rotational) deflection (relative to the undeflected position) of span station 8. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local xb3-axis -OutList['Spn8RDyb3'] = False # (deg); Blade 3 local pitch (angular/rotational) deflection (relative to the undeflected position) of span station 8. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local yb3-axis -OutList['Spn8RDzb3'] = False # (deg); Blade 3 local torsional (angular/rotational) deflection (relative to the undeflected position) of span station 8. This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the local zb3-axis -OutList['Spn9RDxb3'] = False # (deg); Blade 3 local roll (angular/rotational) deflection (relative to the undeflected position) of span station 9. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local xb3-axis -OutList['Spn9RDyb3'] = False # (deg); Blade 3 local pitch (angular/rotational) deflection (relative to the undeflected position) of span station 9. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small blade deflections, so that the rotation sequence does not matter.; About the local yb3-axis -OutList['Spn9RDzb3'] = False # (deg); Blade 3 local torsional (angular/rotational) deflection (relative to the undeflected position) of span station 9. This output will always be zero for FAST simulation results. Use it for examining blade torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. Please note that this output uses the opposite of the sign convention used for blade pitch angles.; About the local zb3-axis - -# Blade Pitch Motions -OutList['PtchPMzc1'] = False # (deg); Blade 1 pitch angle (position); Positive towards feather about the minus zc1- and minus zb1-axes -OutList['PtchPMzb1'] = False # (deg); Blade 1 pitch angle (position); Positive towards feather about the minus zc1- and minus zb1-axes -OutList['BldPitch1'] = False # (deg); Blade 1 pitch angle (position); Positive towards feather about the minus zc1- and minus zb1-axes -OutList['BlPitch1'] = False # (deg); Blade 1 pitch angle (position); Positive towards feather about the minus zc1- and minus zb1-axes -OutList['PtchPMzc2'] = False # (deg); Blade 2 pitch angle (position); Positive towards feather about the minus zc2- and minus zb2-axes -OutList['PtchPMzb2'] = False # (deg); Blade 2 pitch angle (position); Positive towards feather about the minus zc2- and minus zb2-axes -OutList['BldPitch2'] = False # (deg); Blade 2 pitch angle (position); Positive towards feather about the minus zc2- and minus zb2-axes -OutList['BlPitch2'] = False # (deg); Blade 2 pitch angle (position); Positive towards feather about the minus zc2- and minus zb2-axes -OutList['PtchPMzc3'] = False # (deg); Blade 3 pitch angle (position); Positive towards feather about the minus zc3- and minus zb3-axes -OutList['PtchPMzb3'] = False # (deg); Blade 3 pitch angle (position); Positive towards feather about the minus zc3- and minus zb3-axes -OutList['BldPitch3'] = False # (deg); Blade 3 pitch angle (position); Positive towards feather about the minus zc3- and minus zb3-axes -OutList['BlPitch3'] = False # (deg); Blade 3 pitch angle (position); Positive towards feather about the minus zc3- and minus zb3-axes - -# Teeter Motions -OutList['TeetPya'] = False # (deg); Rotor teeter angle (position); About the ya-axis -OutList['RotTeetP'] = False # (deg); Rotor teeter angle (position); About the ya-axis -OutList['TeetDefl'] = False # (deg); Rotor teeter angle (position); About the ya-axis -OutList['TeetVya'] = False # (deg/s); Rotor teeter angular velocity; About the ya-axis -OutList['RotTeetV'] = False # (deg/s); Rotor teeter angular velocity; About the ya-axis -OutList['TeetAya'] = False # (deg/s^2); Rotor teeter angular acceleration; About the ya-axis -OutList['RotTeetA'] = False # (deg/s^2); Rotor teeter angular acceleration; About the ya-axis - -# Shaft Motions -OutList['LSSTipPxa'] = False # (deg); Rotor azimuth angle (position); About the xa- and xs-axes -OutList['LSSTipPxs'] = False # (deg); Rotor azimuth angle (position); About the xa- and xs-axes -OutList['LSSTipP'] = False # (deg); Rotor azimuth angle (position); About the xa- and xs-axes -OutList['Azimuth'] = False # (deg); Rotor azimuth angle (position); About the xa- and xs-axes -OutList['LSSTipVxa'] = False # (rpm); Rotor azimuth angular speed; About the xa- and xs-axes -OutList['LSSTipVxs'] = False # (rpm); Rotor azimuth angular speed; About the xa- and xs-axes -OutList['LSSTipV'] = False # (rpm); Rotor azimuth angular speed; About the xa- and xs-axes -OutList['RotSpeed'] = False # (rpm); Rotor azimuth angular speed; About the xa- and xs-axes -OutList['LSSTipAxa'] = False # (deg/s^2); Rotor azimuth angular acceleration; About the xa- and xs-axes -OutList['LSSTipAxs'] = False # (deg/s^2); Rotor azimuth angular acceleration; About the xa- and xs-axes -OutList['LSSTipA'] = False # (deg/s^2); Rotor azimuth angular acceleration; About the xa- and xs-axes -OutList['RotAccel'] = False # (deg/s^2); Rotor azimuth angular acceleration; About the xa- and xs-axes -OutList['LSSGagPxa'] = False # (deg); Low-speed shaft strain gage azimuth angle (position) (on the gearbox side of the low-speed shaft); About the xa- and xs-axes -OutList['LSSGagPxs'] = False # (deg); Low-speed shaft strain gage azimuth angle (position) (on the gearbox side of the low-speed shaft); About the xa- and xs-axes -OutList['LSSGagP'] = False # (deg); Low-speed shaft strain gage azimuth angle (position) (on the gearbox side of the low-speed shaft); About the xa- and xs-axes -OutList['LSSGagVxa'] = False # (rpm); Low-speed shaft strain gage angular speed (on the gearbox side of the low-speed shaft); About the xa- and xs-axes -OutList['LSSGagVxs'] = False # (rpm); Low-speed shaft strain gage angular speed (on the gearbox side of the low-speed shaft); About the xa- and xs-axes -OutList['LSSGagV'] = False # (rpm); Low-speed shaft strain gage angular speed (on the gearbox side of the low-speed shaft); About the xa- and xs-axes -OutList['LSSGagAxa'] = False # (deg/s^2); Low-speed shaft strain gage angular acceleration (on the gearbox side of the low-speed shaft); About the xa- and xs-axes -OutList['LSSGagAxs'] = False # (deg/s^2); Low-speed shaft strain gage angular acceleration (on the gearbox side of the low-speed shaft); About the xa- and xs-axes -OutList['LSSGagA'] = False # (deg/s^2); Low-speed shaft strain gage angular acceleration (on the gearbox side of the low-speed shaft); About the xa- and xs-axes -OutList['HSShftV'] = False # (rpm); Angular speed of the high-speed shaft and generator; Same sign as LSSGagVxa / LSSGagVxs / LSSGagV -OutList['GenSpeed'] = False # (rpm); Angular speed of the high-speed shaft and generator; Same sign as LSSGagVxa / LSSGagVxs / LSSGagV -OutList['HSShftA'] = False # (deg/s^2); Angular acceleration of the high-speed shaft and generator; Same sign as LSSGagAxa / LSSGagAxs / LSSGagA -OutList['GenAccel'] = False # (deg/s^2); Angular acceleration of the high-speed shaft and generator; Same sign as LSSGagAxa / LSSGagAxs / LSSGagA -OutList['TipSpdRat'] = False # (-); Rotor blade tip speed ratio; N/A -OutList['TSR'] = False # (-); Rotor blade tip speed ratio; N/A - -# Nacelle IMU Motions -OutList['NcIMUTVxs'] = False # (m/s); Nacelle inertial measurement unit translational velocity (absolute); Directed along the xs-axis -OutList['NcIMUTVys'] = False # (m/s); Nacelle inertial measurement unit translational velocity (absolute); Directed along the ys-axis -OutList['NcIMUTVzs'] = False # (m/s); Nacelle inertial measurement unit translational velocity (absolute); Directed along the zs-axis -OutList['NcIMUTAxs'] = False # (m/s^2); Nacelle inertial measurement unit translational acceleration (absolute); Directed along the xs-axis -OutList['NcIMUTAys'] = False # (m/s^2); Nacelle inertial measurement unit translational acceleration (absolute); Directed along the ys-axis -OutList['NcIMUTAzs'] = False # (m/s^2); Nacelle inertial measurement unit translational acceleration (absolute); Directed along the zs-axis -OutList['NcIMURVxs'] = False # (deg/s); Nacelle inertial measurement unit angular (rotational) velocity (absolute); About the xs-axis -OutList['NcIMURVys'] = False # (deg/s); Nacelle inertial measurement unit angular (rotational) velocity (absolute); About the ys-axis -OutList['NcIMURVzs'] = False # (deg/s); Nacelle inertial measurement unit angular (rotational) velocity (absolute); About the zs-axis -OutList['NcIMURAxs'] = False # (deg/s^2); Nacelle inertial measurement unit angular (rotational) acceleration (absolute); About the xs-axis -OutList['NcIMURAys'] = False # (deg/s^2); Nacelle inertial measurement unit angular (rotational) acceleration (absolute); About the ys-axis -OutList['NcIMURAzs'] = False # (deg/s^2); Nacelle inertial measurement unit angular (rotational) acceleration (absolute); About the zs-axis - -# Rotor-Furl Motions -OutList['RotFurlP'] = False # (deg); Rotor-furl angle (position); About the rotor-furl axis -OutList['RotFurl'] = False # (deg); Rotor-furl angle (position); About the rotor-furl axis -OutList['RotFurlV'] = False # (deg/s); Rotor-furl angular velocity; About the rotor-furl axis -OutList['RotFurlA'] = False # (deg/s^2); Rotor-furl angular acceleration; About the rotor-furl axis - -# Tail-Furl Motions -OutList['TailFurlP'] = False # (deg); Tail-furl angle (position); About the tail-furl axis -OutList['TailFurl'] = False # (deg); Tail-furl angle (position); About the tail-furl axis -OutList['TailFurlV'] = False # (deg/s); Tail-furl angular velocity; About the tail-furl axis -OutList['TailFurlA'] = False # (deg/s^2); Tail-furl angular acceleration; About the tail-furl axis - -# Nacelle Yaw Motions -OutList['YawPzn'] = False # (deg); Nacelle yaw angle (position); About the zn- and zp-axes -OutList['YawPzp'] = False # (deg); Nacelle yaw angle (position); About the zn- and zp-axes -OutList['NacYawP'] = False # (deg); Nacelle yaw angle (position); About the zn- and zp-axes -OutList['NacYaw'] = False # (deg); Nacelle yaw angle (position); About the zn- and zp-axes -OutList['YawPos'] = False # (deg); Nacelle yaw angle (position); About the zn- and zp-axes -OutList['YawVzn'] = False # (deg/s); Nacelle yaw angular velocity; About the zn- and zp-axes -OutList['YawVzp'] = False # (deg/s); Nacelle yaw angular velocity; About the zn- and zp-axes -OutList['NacYawV'] = False # (deg/s); Nacelle yaw angular velocity; About the zn- and zp-axes -OutList['YawRate'] = False # (deg/s); Nacelle yaw angular velocity; About the zn- and zp-axes -OutList['YawAzn'] = False # (deg/s^2); Nacelle yaw angular acceleration; About the zn- and zp-axes -OutList['YawAzp'] = False # (deg/s^2); Nacelle yaw angular acceleration; About the zn- and zp-axes -OutList['NacYawA'] = False # (deg/s^2); Nacelle yaw angular acceleration; About the zn- and zp-axes -OutList['YawAccel'] = False # (deg/s^2); Nacelle yaw angular acceleration; About the zn- and zp-axes -OutList['NacYawErr'] = False # (deg); Nacelle yaw error estimate. This is computed as follows: NacYawErr = HorWndDir - YawPzn - YawBrRDzt - PtfmRDzi. This estimate is not accurate instantaneously in the presence of significant tower deflection or platform angular (rotational) displacement since the angles used in the computation are not all defined about the same axis of rotation. However, the estimate should be useful in a yaw controller if averaged over a time scale long enough to diminish the effects of tower and platform motions (i.e., much longer than the period of oscillation).; About the zi-axis - -# Tower-Top / Yaw Bearing Motions -OutList['YawBrTDxp'] = False # (m); Tower-top / yaw bearing fore-aft (translational) deflection (relative to the undeflected position); Directed along the xp-axis -OutList['YawBrTDyp'] = False # (m); Tower-top / yaw bearing side-to-side (translational) deflection (relative to the undeflected position); Directed along the yp-axis -OutList['YawBrTDzp'] = False # (m); Tower-top / yaw bearing axial (translational) deflection (relative to the undeflected position); Directed along the zp-axis -OutList['YawBrTDxt'] = False # (m); Tower-top / yaw bearing fore-aft (translational) deflection (relative to the undeflected position); Directed along the xt-axis -OutList['TTDspFA'] = False # (m); Tower-top / yaw bearing fore-aft (translational) deflection (relative to the undeflected position); Directed along the xt-axis -OutList['YawBrTDyt'] = False # (m); Tower-top / yaw bearing side-to-side (translation) deflection (relative to the undeflected position); Directed along the yt-axis -OutList['TTDspSS'] = False # (m); Tower-top / yaw bearing side-to-side (translation) deflection (relative to the undeflected position); Directed along the yt-axis -OutList['YawBrTDzt'] = False # (m); Tower-top / yaw bearing axial (translational) deflection (relative to the undeflected position); Directed along the zt-axis -OutList['TTDspAx'] = False # (m); Tower-top / yaw bearing axial (translational) deflection (relative to the undeflected position); Directed along the zt-axis -OutList['YawBrTAxp'] = False # (m/s^2); Tower-top / yaw bearing fore-aft (translational) acceleration (absolute); Directed along the xp-axis -OutList['YawBrTAyp'] = False # (m/s^2); Tower-top / yaw bearing side-to-side (translational) acceleration (absolute); Directed along the yp-axis -OutList['YawBrTAzp'] = False # (m/s^2); Tower-top / yaw bearing axial (translational) acceleration (absolute); Directed along the zp-axis -OutList['YawBrRDxt'] = False # (deg); Tower-top / yaw bearing angular (rotational) roll deflection (relative to the undeflected position). In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower deflections, so that the rotation sequence does not matter.; About the xt-axis -OutList['TTDspRoll'] = False # (deg); Tower-top / yaw bearing angular (rotational) roll deflection (relative to the undeflected position). In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower deflections, so that the rotation sequence does not matter.; About the xt-axis -OutList['YawBrRDyt'] = False # (deg); Tower-top / yaw bearing angular (rotational) pitch deflection (relative to the undeflected position). In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower deflections, so that the rotation sequence does not matter.; About the yt-axis -OutList['TTDspPtch'] = False # (deg); Tower-top / yaw bearing angular (rotational) pitch deflection (relative to the undeflected position). In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower deflections, so that the rotation sequence does not matter.; About the yt-axis -OutList['YawBrRDzt'] = False # (deg); Tower-top / yaw bearing angular (rotational) torsion deflection (relative to the undeflected position). This output will always be zero for FAST simulation results. Use it for examining tower torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence.; About the zt-axis -OutList['TTDspTwst'] = False # (deg); Tower-top / yaw bearing angular (rotational) torsion deflection (relative to the undeflected position). This output will always be zero for FAST simulation results. Use it for examining tower torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence.; About the zt-axis -OutList['YawBrRVxp'] = False # (deg/s); Tower-top / yaw bearing angular (rotational) roll velocity (absolute); About the xp-axis -OutList['YawBrRVyp'] = False # (deg/s); Tower-top / yaw bearing angular (rotational) pitch velocity (absolute); About the yp-axis -OutList['YawBrRVzp'] = False # (deg/s); Tower-top / yaw bearing angular (rotational) torsion velocity. This output will always be very close to zero for FAST simulation results. Use it for examining tower torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. (absolute); About the zp-axis -OutList['YawBrRAxp'] = False # (deg/s^2); Tower-top / yaw bearing angular (rotational) roll acceleration (absolute); About the xp-axis -OutList['YawBrRAyp'] = False # (deg/s^2); Tower-top / yaw bearing angular (rotational) pitch acceleration (absolute); About the yp-axis -OutList['YawBrRAzp'] = False # (deg/s^2); Tower-top / yaw bearing angular (rotational) torsion acceleration. This output will always be very close to zero for FAST simulation results. Use it for examining tower torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. (absolute); About the zp-axis - -# Local Tower Motions -OutList['TwHt1ALxt'] = False # (m/s^2); Local tower fore-aft (translational) acceleration (absolute) of tower gage 1 ; Directed along the local xt-axis -OutList['TwHt1ALyt'] = False # (m/s^2); Local tower side-to-side (translational) acceleration (absolute) of tower gage 1 ; Directed along the local yt-axis -OutList['TwHt1ALzt'] = False # (m/s^2); Local tower axial (translational) acceleration (absolute) of tower gage 1 ; Directed along the local zt-axis -OutList['TwHt2ALxt'] = False # (m/s^2); Local tower fore-aft (translational) acceleration (absolute) of tower gage 2; Directed along the local xt-axis -OutList['TwHt2ALyt'] = False # (m/s^2); Local tower side-to-side (translational) acceleration (absolute) of tower gage 2; Directed along the local yt-axis -OutList['TwHt2ALzt'] = False # (m/s^2); Local tower axial (translational) acceleration (absolute) of tower gage 2; Directed along the local zt-axis -OutList['TwHt3ALxt'] = False # (m/s^2); Local tower fore-aft (translational) acceleration (absolute) of tower gage 3; Directed along the local xt-axis -OutList['TwHt3ALyt'] = False # (m/s^2); Local tower side-to-side (translational) acceleration (absolute) of tower gage 3; Directed along the local yt-axis -OutList['TwHt3ALzt'] = False # (m/s^2); Local tower axial (translational) acceleration (absolute) of tower gage 3; Directed along the local zt-axis -OutList['TwHt4ALxt'] = False # (m/s^2); Local tower fore-aft (translational) acceleration (absolute) of tower gage 4; Directed along the local xt-axis -OutList['TwHt4ALyt'] = False # (m/s^2); Local tower side-to-side (translational) acceleration (absolute) of tower gage 4; Directed along the local yt-axis -OutList['TwHt4ALzt'] = False # (m/s^2); Local tower axial (translational) acceleration (absolute) of tower gage 4; Directed along the local zt-axis -OutList['TwHt5ALxt'] = False # (m/s^2); Local tower fore-aft (translational) acceleration (absolute) of tower gage 5; Directed along the local xt-axis -OutList['TwHt5ALyt'] = False # (m/s^2); Local tower side-to-side (translational) acceleration (absolute) of tower gage 5; Directed along the local yt-axis -OutList['TwHt5ALzt'] = False # (m/s^2); Local tower axial (translational) acceleration (absolute) of tower gage 5; Directed along the local zt-axis -OutList['TwHt6ALxt'] = False # (m/s^2); Local tower fore-aft (translational) acceleration (absolute) of tower gage 6; Directed along the local xt-axis -OutList['TwHt6ALyt'] = False # (m/s^2); Local tower side-to-side (translational) acceleration (absolute) of tower gage 6; Directed along the local yt-axis -OutList['TwHt6ALzt'] = False # (m/s^2); Local tower axial (translational) acceleration (absolute) of tower gage 6; Directed along the local zt-axis -OutList['TwHt7ALxt'] = False # (m/s^2); Local tower fore-aft (translational) acceleration (absolute) of tower gage 7; Directed along the local xt-axis -OutList['TwHt7ALyt'] = False # (m/s^2); Local tower side-to-side (translational) acceleration (absolute) of tower gage 7; Directed along the local yt-axis -OutList['TwHt7ALzt'] = False # (m/s^2); Local tower axial (translational) acceleration (absolute) of tower gage 7; Directed along the local zt-axis -OutList['TwHt8ALxt'] = False # (m/s^2); Local tower fore-aft (translational) acceleration (absolute) of tower gage 8; Directed along the local xt-axis -OutList['TwHt8ALyt'] = False # (m/s^2); Local tower side-to-side (translational) acceleration (absolute) of tower gage 8; Directed along the local yt-axis -OutList['TwHt8ALzt'] = False # (m/s^2); Local tower axial (translational) acceleration (absolute) of tower gage 8; Directed along the local zt-axis -OutList['TwHt9ALxt'] = False # (m/s^2); Local tower fore-aft (translational) acceleration (absolute) of tower gage 9; Directed along the local xt-axis -OutList['TwHt9ALyt'] = False # (m/s^2); Local tower side-to-side (translational) acceleration (absolute) of tower gage 9; Directed along the local yt-axis -OutList['TwHt9ALzt'] = False # (m/s^2); Local tower axial (translational) acceleration (absolute) of tower gage 9; Directed along the local zt-axis -OutList['TwHt1TDxt'] = False # (m); Local tower fore-aft (translational) deflection (relative to the undeflected position) of tower gage 1; Directed along the local xt-axis -OutList['TwHt1TDyt'] = False # (m); Local tower side-to-side (translational) deflection (relative to the undeflected position) of tower gage 1; Directed along the local yt-axis -OutList['TwHt1TDzt'] = False # (m); Local tower axial (translational) deflection (relative to the undeflected position) of tower gage 1; Directed along the local zt-axis -OutList['TwHt2TDxt'] = False # (m); Local tower fore-aft (translational) deflection (relative to the undeflected position) of tower gage 2; Directed along the local xt-axis -OutList['TwHt2TDyt'] = False # (m); Local tower side-to-side (translational) deflection (relative to the undeflected position) of tower gage 2; Directed along the local yt-axis -OutList['TwHt2TDzt'] = False # (m); Local tower axial (translational) deflection (relative to the undeflected position) of tower gage 2; Directed along the local zt-axis -OutList['TwHt3TDxt'] = False # (m); Local tower fore-aft (translational) deflection (relative to the undeflected position) of tower gage 3; Directed along the local xt-axis -OutList['TwHt3TDyt'] = False # (m); Local tower side-to-side (translational) deflection (relative to the undeflected position) of tower gage 3; Directed along the local yt-axis -OutList['TwHt3TDzt'] = False # (m); Local tower axial (translational) deflection (relative to the undeflected position) of tower gage 3; Directed along the local zt-axis -OutList['TwHt4TDxt'] = False # (m); Local tower fore-aft (translational) deflection (relative to the undeflected position) of tower gage 4; Directed along the local xt-axis -OutList['TwHt4TDyt'] = False # (m); Local tower side-to-side (translational) deflection (relative to the undeflected position) of tower gage 4; Directed along the local yt-axis -OutList['TwHt4TDzt'] = False # (m); Local tower axial (translational) deflection (relative to the undeflected position) of tower gage 4; Directed along the local zt-axis -OutList['TwHt5TDxt'] = False # (m); Local tower fore-aft (translational) deflection (relative to the undeflected position) of tower gage 5; Directed along the local xt-axis -OutList['TwHt5TDyt'] = False # (m); Local tower side-to-side (translational) deflection (relative to the undeflected position) of tower gage 5; Directed along the local yt-axis -OutList['TwHt5TDzt'] = False # (m); Local tower axial (translational) deflection (relative to the undeflected position) of tower gage 5; Directed along the local zt-axis -OutList['TwHt6TDxt'] = False # (m); Local tower fore-aft (translational) deflection (relative to the undeflected position) of tower gage 6; Directed along the local xt-axis -OutList['TwHt6TDyt'] = False # (m); Local tower side-to-side (translational) deflection (relative to the undeflected position) of tower gage 6; Directed along the local yt-axis -OutList['TwHt6TDzt'] = False # (m); Local tower axial (translational) deflection (relative to the undeflected position) of tower gage 6; Directed along the local zt-axis -OutList['TwHt7TDxt'] = False # (m); Local tower fore-aft (translational) deflection (relative to the undeflected position) of tower gage 7; Directed along the local xt-axis -OutList['TwHt7TDyt'] = False # (m); Local tower side-to-side (translational) deflection (relative to the undeflected position) of tower gage 7; Directed along the local yt-axis -OutList['TwHt7TDzt'] = False # (m); Local tower axial (translational) deflection (relative to the undeflected position) of tower gage 7; Directed along the local zt-axis -OutList['TwHt8TDxt'] = False # (m); Local tower fore-aft (translational) deflection (relative to the undeflected position) of tower gage 8; Directed along the local xt-axis -OutList['TwHt8TDyt'] = False # (m); Local tower side-to-side (translational) deflection (relative to the undeflected position) of tower gage 8; Directed along the local yt-axis -OutList['TwHt8TDzt'] = False # (m); Local tower axial (translational) deflection (relative to the undeflected position) of tower gage 8; Directed along the local zt-axis -OutList['TwHt9TDxt'] = False # (m); Local tower fore-aft (translational) deflection (relative to the undeflected position) of tower gage 9; Directed along the local xt-axis -OutList['TwHt9TDyt'] = False # (m); Local tower side-to-side (translational) deflection (relative to the undeflected position) of tower gage 9; Directed along the local yt-axis -OutList['TwHt9TDzt'] = False # (m); Local tower axial (translational) deflection (relative to the undeflected position) of tower gage 9; Directed along the local zt-axis -OutList['TwHt1RDxt'] = False # (deg); Local tower angular (rotational) roll deflection (relative to the undeflected position) of tower gage 1. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower deflections, so that the rotation sequence does not matter.; About the local xt-axis -OutList['TwHt1RDyt'] = False # (deg); Local tower angular (rotational) pitch deflection (relative to the undeflected position) of tower gage 1. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower deflections, so that the rotation sequence does not matter.; About the local yt-axis -OutList['TwHt1RDzt'] = False # (deg); Local tower angular (rotational) torsion deflection (relative to the undeflected position) of tower gage 1. This output will always be zero for FAST simulation results. Use it for examining tower torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence.; About the local zt-axis -OutList['TwHt2RDxt'] = False # (deg); Local tower angular (rotational) roll deflection (relative to the undeflected position) of tower gage 2. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower deflections, so that the rotation sequence does not matter.; About the local xt-axis -OutList['TwHt2RDyt'] = False # (deg); Local tower angular (rotational) pitch deflection (relative to the undeflected position) of tower gage 2. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower deflections, so that the rotation sequence does not matter.; About the local yt-axis -OutList['TwHt2RDzt'] = False # (deg); Local tower angular (rotational) torsion deflection (relative to the undeflected position) of tower gage 2. This output will always be zero for FAST simulation results. Use it for examining tower torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence.; About the local zt-axis -OutList['TwHt3RDxt'] = False # (deg); Local tower angular (rotational) roll deflection (relative to the undeflected position) of tower gage 3. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower deflections, so that the rotation sequence does not matter.; About the local xt-axis -OutList['TwHt3RDyt'] = False # (deg); Local tower angular (rotational) pitch deflection (relative to the undeflected position) of tower gage 3. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower deflections, so that the rotation sequence does not matter.; About the local yt-axis -OutList['TwHt3RDzt'] = False # (deg); Local tower angular (rotational) torsion deflection (relative to the undeflected position) of tower gage 3. This output will always be zero for FAST simulation results. Use it for examining tower torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence.; About the local zt-axis -OutList['TwHt4RDxt'] = False # (deg); Local tower angular (rotational) roll deflection (relative to the undeflected position) of tower gage 4. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower deflections, so that the rotation sequence does not matter.; About the local xt-axis -OutList['TwHt4RDyt'] = False # (deg); Local tower angular (rotational) pitch deflection (relative to the undeflected position) of tower gage 4. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower deflections, so that the rotation sequence does not matter.; About the local yt-axis -OutList['TwHt4RDzt'] = False # (deg); Local tower angular (rotational) torsion deflection (relative to the undeflected position) of tower gage 4. This output will always be zero for FAST simulation results. Use it for examining tower torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence.; About the local zt-axis -OutList['TwHt5RDxt'] = False # (deg); Local tower angular (rotational) roll deflection (relative to the undeflected position) of tower gage 5. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower deflections, so that the rotation sequence does not matter.; About the local xt-axis -OutList['TwHt5RDyt'] = False # (deg); Local tower angular (rotational) pitch deflection (relative to the undeflected position) of tower gage 5. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower deflections, so that the rotation sequence does not matter.; About the local yt-axis -OutList['TwHt5RDzt'] = False # (deg); Local tower angular (rotational) torsion deflection (relative to the undeflected position) of tower gage 5. This output will always be zero for FAST simulation results. Use it for examining tower torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence.; About the local zt-axis -OutList['TwHt6RDxt'] = False # (deg); Local tower angular (rotational) roll deflection (relative to the undeflected position) of tower gage 6. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower deflections, so that the rotation sequence does not matter.; About the local xt-axis -OutList['TwHt6RDyt'] = False # (deg); Local tower angular (rotational) pitch deflection (relative to the undeflected position) of tower gage 6. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower deflections, so that the rotation sequence does not matter.; About the local yt-axis -OutList['TwHt6RDzt'] = False # (deg); Local tower angular (rotational) torsion deflection (relative to the undeflected position) of tower gage 6. This output will always be zero for FAST simulation results. Use it for examining tower torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence.; About the local zt-axis -OutList['TwHt7RDxt'] = False # (deg); Local tower angular (rotational) roll deflection (relative to the undeflected position) of tower gage 7. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower deflections, so that the rotation sequence does not matter.; About the local xt-axis -OutList['TwHt7RDyt'] = False # (deg); Local tower angular (rotational) pitch deflection (relative to the undeflected position) of tower gage 7. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower deflections, so that the rotation sequence does not matter.; About the local yt-axis -OutList['TwHt7RDzt'] = False # (deg); Local tower angular (rotational) torsion deflection (relative to the undeflected position) of tower gage 7. This output will always be zero for FAST simulation results. Use it for examining tower torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence.; About the local zt-axis -OutList['TwHt8RDxt'] = False # (deg); Local tower angular (rotational) roll deflection (relative to the undeflected position) of tower gage 8. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower deflections, so that the rotation sequence does not matter.; About the local xt-axis -OutList['TwHt8RDyt'] = False # (deg); Local tower angular (rotational) pitch deflection (relative to the undeflected position) of tower gage 8. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower deflections, so that the rotation sequence does not matter.; About the local yt-axis -OutList['TwHt8RDzt'] = False # (deg); Local tower angular (rotational) torsion deflection (relative to the undeflected position) of tower gage 8. This output will always be zero for FAST simulation results. Use it for examining tower torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence.; About the local zt-axis -OutList['TwHt9RDxt'] = False # (deg); Local tower angular (rotational) roll deflection (relative to the undeflected position) of tower gage 9. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower deflections, so that the rotation sequence does not matter.; About the local xt-axis -OutList['TwHt9RDyt'] = False # (deg); Local tower angular (rotational) pitch deflection (relative to the undeflected position) of tower gage 9. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower deflections, so that the rotation sequence does not matter.; About the local yt-axis -OutList['TwHt9RDzt'] = False # (deg); Local tower angular (rotational) torsion deflection (relative to the undeflected position) of tower gage 9. This output will always be zero for FAST simulation results. Use it for examining tower torsional deflections of ADAMS simulations run using ADAMS datasets created using the FAST-to-ADAMS preprocessor. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence.; About the local zt-axis -OutList['TwHt1TPxi'] = False # (m); xi-component of the translational position (relative to the inertia frame) of tower gage 1; Directed along the local xi-axis -OutList['TwHt1TPyi'] = False # (m); yi-component of the translational position (relative to the inertia frame) of tower gage 1; Directed along the local yi-axis -OutList['TwHt1TPzi'] = False # (m); zi-component of the translational position (relative to ground level [onshore] or MSL [offshore]) of tower gage 1; Directed along the local zi-axis -OutList['TwHt2TPxi'] = False # (m); xi-component of the translational position (relative to the inertia frame) of tower gage 2; Directed along the local xi-axis -OutList['TwHt2TPyi'] = False # (m); yi-component of the translational position (relative to the inertia frame) of tower gage 2; Directed along the local yi-axis -OutList['TwHt2TPzi'] = False # (m); zi-component of the translational position (relative to ground level [onshore] or MSL [offshore]) of tower gage 2; Directed along the local zi-axis -OutList['TwHt3TPxi'] = False # (m); xi-component of the translational position (relative to the inertia frame) of tower gage 3; Directed along the local xi-axis -OutList['TwHt3TPyi'] = False # (m); yi-component of the translational position (relative to the inertia frame) of tower gage 3; Directed along the local yi-axis -OutList['TwHt3TPzi'] = False # (m); zi-component of the translational position (relative to ground level [onshore] or MSL [offshore]) of tower gage 3; Directed along the local zi-axis -OutList['TwHt4TPxi'] = False # (m); xi-component of the translational position (relative to the inertia frame) of tower gage 4; Directed along the local xi-axis -OutList['TwHt4TPyi'] = False # (m); yi-component of the translational position (relative to the inertia frame) of tower gage 4; Directed along the local yi-axis -OutList['TwHt4TPzi'] = False # (m); zi-component of the translational position (relative to ground level [onshore] or MSL [offshore]) of tower gage 4; Directed along the local zi-axis -OutList['TwHt5TPxi'] = False # (m); xi-component of the translational position (relative to the inertia frame) of tower gage 5; Directed along the local xi-axis -OutList['TwHt5TPyi'] = False # (m); yi-component of the translational position (relative to the inertia frame) of tower gage 5; Directed along the local yi-axis -OutList['TwHt5TPzi'] = False # (m); zi-component of the translational position (relative to ground level [onshore] or MSL [offshore]) of tower gage 5; Directed along the local zi-axis -OutList['TwHt6TPxi'] = False # (m); xi-component of the translational position (relative to the inertia frame) of tower gage 6; Directed along the local xi-axis -OutList['TwHt6TPyi'] = False # (m); yi-component of the translational position (relative to the inertia frame) of tower gage 6; Directed along the local yi-axis -OutList['TwHt6TPzi'] = False # (m); zi-component of the translational position (relative to ground level [onshore] or MSL [offshore]) of tower gage 6; Directed along the local zi-axis -OutList['TwHt7TPxi'] = False # (m); xi-component of the translational position (relative to the inertia frame) of tower gage 7; Directed along the local xi-axis -OutList['TwHt7TPyi'] = False # (m); yi-component of the translational position (relative to the inertia frame) of tower gage 7; Directed along the local yi-axis -OutList['TwHt7TPzi'] = False # (m); zi-component of the translational position (relative to ground level [onshore] or MSL [offshore]) of tower gage 7; Directed along the local zi-axis -OutList['TwHt8TPxi'] = False # (m); xi-component of the translational position (relative to the inertia frame) of tower gage 8; Directed along the local xi-axis -OutList['TwHt8TPyi'] = False # (m); yi-component of the translational position (relative to the inertia frame) of tower gage 8; Directed along the local yi-axis -OutList['TwHt8TPzi'] = False # (m); zi-component of the translational position (relative to ground level [onshore] or MSL [offshore]) of tower gage 8; Directed along the local zi-axis -OutList['TwHt9TPxi'] = False # (m); xi-component of the translational position (relative to the inertia frame) of tower gage 9; Directed along the local xi-axis -OutList['TwHt9TPyi'] = False # (m); yi-component of the translational position (relative to the inertia frame) of tower gage 9; Directed along the local yi-axis -OutList['TwHt9TPzi'] = False # (m); zi-component of the translational position (relative to ground level [onshore] or MSL [offshore]) of tower gage 9; Directed along the local zi-axis -OutList['TwHt1RPxi'] = False # (deg); xi-component of the rotational position (relative to the inertia frame) of tower gage 1. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower and platform rotational deflections, so that the rotation sequence does not matter.; About the local xi-axis -OutList['TwHt1RPyi'] = False # (deg); yi-component of the rotational position (relative to the inertia frame) of tower gage 1. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower and platform rotational deflections, so that the rotation sequence does not matter.; About the local yi-axis -OutList['TwHt1RPzi'] = False # (deg); zi-component of the rotational position (relative to the inertia frame) of tower gage 1. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower and platform rotational deflections, so that the rotation sequence does not matter.; About the local zi-axis -OutList['TwHt2RPxi'] = False # (deg); xi-component of the rotational position (relative to the inertia frame) of tower gage 2. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower and platform rotational deflections, so that the rotation sequence does not matter.; About the local xi-axis -OutList['TwHt2RPyi'] = False # (deg); yi-component of the rotational position (relative to the inertia frame) of tower gage 2. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower and platform rotational deflections, so that the rotation sequence does not matter.; About the local yi-axis -OutList['TwHt2RPzi'] = False # (deg); zi-component of the rotational position (relative to the inertia frame) of tower gage 2. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower and platform rotational deflections, so that the rotation sequence does not matter.; About the local zi-axis -OutList['TwHt3RPxi'] = False # (deg); xi-component of the rotational position (relative to the inertia frame) of tower gage 3. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower and platform rotational deflections, so that the rotation sequence does not matter.; About the local xi-axis -OutList['TwHt3RPyi'] = False # (deg); yi-component of the rotational position (relative to the inertia frame) of tower gage 3. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower and platform rotational deflections, so that the rotation sequence does not matter.; About the local yi-axis -OutList['TwHt3RPzi'] = False # (deg); zi-component of the rotational position (relative to the inertia frame) of tower gage 3. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower and platform rotational deflections, so that the rotation sequence does not matter.; About the local zi-axis -OutList['TwHt4RPxi'] = False # (deg); xi-component of the rotational position (relative to the inertia frame) of tower gage 4. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower and platform rotational deflections, so that the rotation sequence does not matter.; About the local xi-axis -OutList['TwHt4RPyi'] = False # (deg); yi-component of the rotational position (relative to the inertia frame) of tower gage 4. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower and platform rotational deflections, so that the rotation sequence does not matter.; About the local yi-axis -OutList['TwHt4RPzi'] = False # (deg); zi-component of the rotational position (relative to the inertia frame) of tower gage 4. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower and platform rotational deflections, so that the rotation sequence does not matter.; About the local zi-axis -OutList['TwHt5RPxi'] = False # (deg); xi-component of the rotational position (relative to the inertia frame) of tower gage 5. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower and platform rotational deflections, so that the rotation sequence does not matter.; About the local xi-axis -OutList['TwHt5RPyi'] = False # (deg); yi-component of the rotational position (relative to the inertia frame) of tower gage 5. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower and platform rotational deflections, so that the rotation sequence does not matter.; About the local yi-axis -OutList['TwHt5RPzi'] = False # (deg); zi-component of the rotational position (relative to the inertia frame) of tower gage 5. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower and platform rotational deflections, so that the rotation sequence does not matter.; About the local zi-axis -OutList['TwHt6RPxi'] = False # (deg); xi-component of the rotational position (relative to the inertia frame) of tower gage 6. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower and platform rotational deflections, so that the rotation sequence does not matter.; About the local xi-axis -OutList['TwHt6RPyi'] = False # (deg); yi-component of the rotational position (relative to the inertia frame) of tower gage 6. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower and platform rotational deflections, so that the rotation sequence does not matter.; About the local yi-axis -OutList['TwHt6RPzi'] = False # (deg); zi-component of the rotational position (relative to the inertia frame) of tower gage 6. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower and platform rotational deflections, so that the rotation sequence does not matter.; About the local zi-axis -OutList['TwHt7RPxi'] = False # (deg); xi-component of the rotational position (relative to the inertia frame) of tower gage 7. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower and platform rotational deflections, so that the rotation sequence does not matter.; About the local xi-axis -OutList['TwHt7RPyi'] = False # (deg); yi-component of the rotational position (relative to the inertia frame) of tower gage 7. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower and platform rotational deflections, so that the rotation sequence does not matter.; About the local yi-axis -OutList['TwHt7RPzi'] = False # (deg); zi-component of the rotational position (relative to the inertia frame) of tower gage 7. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower and platform rotational deflections, so that the rotation sequence does not matter.; About the local zi-axis -OutList['TwHt8RPxi'] = False # (deg); xi-component of the rotational position (relative to the inertia frame) of tower gage 8. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower and platform rotational deflections, so that the rotation sequence does not matter.; About the local xi-axis -OutList['TwHt8RPyi'] = False # (deg); yi-component of the rotational position (relative to the inertia frame) of tower gage 8. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower and platform rotational deflections, so that the rotation sequence does not matter.; About the local yi-axis -OutList['TwHt8RPzi'] = False # (deg); zi-component of the rotational position (relative to the inertia frame) of tower gage 8. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower and platform rotational deflections, so that the rotation sequence does not matter.; About the local zi-axis -OutList['TwHt9RPxi'] = False # (deg); xi-component of the rotational position (relative to the inertia frame) of tower gage 9. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower and platform rotational deflections, so that the rotation sequence does not matter.; About the local xi-axis -OutList['TwHt9RPyi'] = False # (deg); yi-component of the rotational position (relative to the inertia frame) of tower gage 9. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower and platform rotational deflections, so that the rotation sequence does not matter.; About the local yi-axis -OutList['TwHt9RPzi'] = False # (deg); zi-component of the rotational position (relative to the inertia frame) of tower gage 9. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small tower and platform rotational deflections, so that the rotation sequence does not matter.; About the local zi-axis - -# Platform Motions -OutList['PtfmTDxt'] = False # (m); Platform horizontal surge (translational) displacement; Directed along the xt-axis -OutList['PtfmTDyt'] = False # (m); Platform horizontal sway (translational) displacement; Directed along the yt-axis -OutList['PtfmTDzt'] = False # (m); Platform vertical heave (translational) displacement; Directed along the zt-axis -OutList['PtfmTDxi'] = False # (m); Platform horizontal surge (translational) displacement; Directed along the xi-axis -OutList['PtfmSurge'] = False # (m); Platform horizontal surge (translational) displacement; Directed along the xi-axis -OutList['PtfmTDyi'] = False # (m); Platform horizontal sway (translational) displacement; Directed along the yi-axis -OutList['PtfmSway'] = False # (m); Platform horizontal sway (translational) displacement; Directed along the yi-axis -OutList['PtfmTDzi'] = False # (m); Platform vertical heave (translational) displacement; Directed along the zi-axis -OutList['PtfmHeave'] = False # (m); Platform vertical heave (translational) displacement; Directed along the zi-axis -OutList['PtfmTVxt'] = False # (m/s); Platform horizontal surge (translational) velocity; Directed along the xt-axis -OutList['PtfmTVyt'] = False # (m/s); Platform horizontal sway (translational) velocity; Directed along the yt-axis -OutList['PtfmTVzt'] = False # (m/s); Platform vertical heave (translational) velocity; Directed along the zt-axis -OutList['PtfmTVxi'] = False # (m/s); Platform horizontal surge (translational) velocity; Directed along the xi-axis -OutList['PtfmTVyi'] = False # (m/s); Platform horizontal sway (translational) velocity; Directed along the yi-axis -OutList['PtfmTVzi'] = False # (m/s); Platform vertical heave (translational) velocity; Directed along the zi-axis -OutList['PtfmTAxt'] = False # (m/s^2); Platform horizontal surge (translational) acceleration; Directed along the xt-axis -OutList['PtfmTAyt'] = False # (m/s^2); Platform horizontal sway (translational) acceleration; Directed along the yt-axis -OutList['PtfmTAzt'] = False # (m/s^2); Platform vertical heave (translational) acceleration; Directed along the zt-axis -OutList['PtfmTAxi'] = False # (m/s^2); Platform horizontal surge (translational) acceleration; Directed along the xi-axis -OutList['PtfmTAyi'] = False # (m/s^2); Platform horizontal sway (translational) acceleration; Directed along the yi-axis -OutList['PtfmTAzi'] = False # (m/s^2); Platform vertical heave (translational) acceleration; Directed along the zi-axis -OutList['PtfmRDxi'] = False # (deg); Platform roll tilt angular (rotational) displacement. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small rotational platform displacements, so that the rotation sequence does not matter.; About the xi-axis -OutList['PtfmRoll'] = False # (deg); Platform roll tilt angular (rotational) displacement. In ADAMS, it is output as an Euler angle computed as the 3rd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small rotational platform displacements, so that the rotation sequence does not matter.; About the xi-axis -OutList['PtfmRDyi'] = False # (deg); Platform pitch tilt angular (rotational) displacement. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small rotational platform displacements, so that the rotation sequence does not matter.; About the yi-axis -OutList['PtfmPitch'] = False # (deg); Platform pitch tilt angular (rotational) displacement. In ADAMS, it is output as an Euler angle computed as the 2nd rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small rotational platform displacements, so that the rotation sequence does not matter.; About the yi-axis -OutList['PtfmRDzi'] = False # (deg); Platform yaw angular (rotational) displacement. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small rotational platform displacements, so that the rotation sequence does not matter.; About the zi-axis -OutList['PtfmYaw'] = False # (deg); Platform yaw angular (rotational) displacement. In ADAMS, it is output as an Euler angle computed as the 1st rotation in the yaw-pitch-roll rotation sequence. It is not output as an Euler angle in FAST, which assumes small rotational platform displacements, so that the rotation sequence does not matter.; About the zi-axis -OutList['PtfmRVxt'] = False # (deg/s); Platform roll tilt angular (rotational) velocity; About the xt-axis -OutList['PtfmRVyt'] = False # (deg/s); Platform pitch tilt angular (rotational) velocity; About the yt-axis -OutList['PtfmRVzt'] = False # (deg/s); Platform yaw angular (rotational) velocity; About the zt-axis -OutList['PtfmRVxi'] = False # (deg/s); Platform roll tilt angular (rotational) velocity; About the xi-axis -OutList['PtfmRVyi'] = False # (deg/s); Platform pitch tilt angular (rotational) velocity; About the yi-axis -OutList['PtfmRVzi'] = False # (deg/s); Platform yaw angular (rotational) velocity; About the zi-axis -OutList['PtfmRAxt'] = False # (deg/s^2); Platform roll tilt angular (rotational) acceleration; About the xt-axis -OutList['PtfmRAyt'] = False # (deg/s^2); Platform pitch tilt angular (rotational) acceleration; About the yt-axis -OutList['PtfmRAzt'] = False # (deg/s^2); Platform yaw angular (rotational) acceleration; About the zt-axis -OutList['PtfmRAxi'] = False # (deg/s^2); Platform roll tilt angular (rotational) acceleration; About the xi-axis -OutList['PtfmRAyi'] = False # (deg/s^2); Platform pitch tilt angular (rotational) acceleration; About the yi-axis -OutList['PtfmRAzi'] = False # (deg/s^2); Platform yaw angular (rotational) acceleration; About the zi-axis - -# Blade 1 Root Loads -OutList['RootFxc1'] = False # (kN); Blade 1 out-of-plane shear force at the blade root; Directed along the xc1-axis -OutList['RootFyc1'] = False # (kN); Blade 1 in-plane shear force at the blade root; Directed along the yc1-axis -OutList['RootFzc1'] = False # (kN); Blade 1 axial force at the blade root; Directed along the zc1- and zb1-axes -OutList['RootFzb1'] = False # (kN); Blade 1 axial force at the blade root; Directed along the zc1- and zb1-axes -OutList['RootFxb1'] = False # (kN); Blade 1 flapwise shear force at the blade root; Directed along the xb1-axis -OutList['RootFyb1'] = False # (kN); Blade 1 edgewise shear force at the blade root; Directed along the yb1-axis -OutList['RootMxc1'] = False # (kN m); Blade 1 in-plane moment (i.e., the moment caused by in-plane forces) at the blade root; About the xc1-axis -OutList['RootMIP1'] = False # (kN m); Blade 1 in-plane moment (i.e., the moment caused by in-plane forces) at the blade root; About the xc1-axis -OutList['RootMyc1'] = False # (kN m); Blade 1 out-of-plane moment (i.e., the moment caused by out-of-plane forces) at the blade root; About the yc1-axis -OutList['RootMOoP1'] = False # (kN m); Blade 1 out-of-plane moment (i.e., the moment caused by out-of-plane forces) at the blade root; About the yc1-axis -OutList['RootMzc1'] = False # (kN m); Blade 1 pitching moment at the blade root; About the zc1- and zb1-axes -OutList['RootMzb1'] = False # (kN m); Blade 1 pitching moment at the blade root; About the zc1- and zb1-axes -OutList['RootMxb1'] = False # (kN m); Blade 1 edgewise moment (i.e., the moment caused by edgewise forces) at the blade root; About the xb1-axis -OutList['RootMEdg1'] = False # (kN m); Blade 1 edgewise moment (i.e., the moment caused by edgewise forces) at the blade root; About the xb1-axis -OutList['RootMyb1'] = True # (kN m); Blade 1 flapwise moment (i.e., the moment caused by flapwise forces) at the blade root; About the yb1-axis -OutList['RootMFlp1'] = False # (kN m); Blade 1 flapwise moment (i.e., the moment caused by flapwise forces) at the blade root; About the yb1-axis - -# Blade 2 Root Loads -OutList['RootFxc2'] = False # (kN); Blade 2 out-of-plane shear force at the blade root; Directed along the xc2-axis -OutList['RootFyc2'] = False # (kN); Blade 2 in-plane shear force at the blade root; Directed along the yc2-axis -OutList['RootFzc2'] = False # (kN); Blade 2 axial force at the blade root; Directed along the zc2- and zb2-axes -OutList['RootFzb2'] = False # (kN); Blade 2 axial force at the blade root; Directed along the zc2- and zb2-axes -OutList['RootFxb2'] = False # (kN); Blade 2 flapwise shear force at the blade root; Directed along the xb2-axis -OutList['RootFyb2'] = False # (kN); Blade 2 edgewise shear force at the blade root; Directed along the yb2-axis -OutList['RootMxc2'] = False # (kN m); Blade 2 in-plane moment (i.e., the moment caused by in-plane forces) at the blade root; About the xc2-axis -OutList['RootMIP2'] = False # (kN m); Blade 2 in-plane moment (i.e., the moment caused by in-plane forces) at the blade root; About the xc2-axis -OutList['RootMyc2'] = False # (kN m); Blade 2 out-of-plane moment (i.e., the moment caused by out-of-plane forces) at the blade root; About the yc2-axis -OutList['RootMOoP2'] = False # (kN m); Blade 2 out-of-plane moment (i.e., the moment caused by out-of-plane forces) at the blade root; About the yc2-axis -OutList['RootMzc2'] = False # (kN m); Blade 2 pitching moment at the blade root; About the zc2- and zb2-axes -OutList['RootMzb2'] = False # (kN m); Blade 2 pitching moment at the blade root; About the zc2- and zb2-axes -OutList['RootMxb2'] = False # (kN m); Blade 2 edgewise moment (i.e., the moment caused by edgewise forces) at the blade root; About the xb2-axis -OutList['RootMEdg2'] = False # (kN m); Blade 2 edgewise moment (i.e., the moment caused by edgewise forces) at the blade root; About the xb2-axis -OutList['RootMyb2'] = True # (kN m); Blade 2 flapwise moment (i.e., the moment caused by flapwise forces) at the blade root; About the yb2-axis -OutList['RootMFlp2'] = False # (kN m); Blade 2 flapwise moment (i.e., the moment caused by flapwise forces) at the blade root; About the yb2-axis - -# Blade 3 Root Loads -OutList['RootFxc3'] = False # (kN); Blade 3 out-of-plane shear force at the blade root; Directed along the xc3-axis -OutList['RootFyc3'] = False # (kN); Blade 3 in-plane shear force at the blade root; Directed along the yc3-axis -OutList['RootFzc3'] = False # (kN); Blade 3 axial force at the blade root; Directed along the zc3- and zb3-axes -OutList['RootFzb3'] = False # (kN); Blade 3 axial force at the blade root; Directed along the zc3- and zb3-axes -OutList['RootFxb3'] = False # (kN); Blade 3 flapwise shear force at the blade root; Directed along the xb3-axis -OutList['RootFyb3'] = False # (kN); Blade 3 edgewise shear force at the blade root; Directed along the yb3-axis -OutList['RootMxc3'] = False # (kN m); Blade 3 in-plane moment (i.e., the moment caused by in-plane forces) at the blade root; About the xc3-axis -OutList['RootMIP3'] = False # (kN m); Blade 3 in-plane moment (i.e., the moment caused by in-plane forces) at the blade root; About the xc3-axis -OutList['RootMyc3'] = False # (kN m); Blade 3 out-of-plane moment (i.e., the moment caused by out-of-plane forces) at the blade root; About the yc3-axis -OutList['RootMOoP3'] = False # (kN m); Blade 3 out-of-plane moment (i.e., the moment caused by out-of-plane forces) at the blade root; About the yc3-axis -OutList['RootMzc3'] = False # (kN m); Blade 3 pitching moment at the blade root; About the zc3- and zb3-axes -OutList['RootMzb3'] = False # (kN m); Blade 3 pitching moment at the blade root; About the zc3- and zb3-axes -OutList['RootMxb3'] = False # (kN m); Blade 3 edgewise moment (i.e., the moment caused by edgewise forces) at the blade root; About the xb3-axis -OutList['RootMEdg3'] = False # (kN m); Blade 3 edgewise moment (i.e., the moment caused by edgewise forces) at the blade root; About the xb3-axis -OutList['RootMyb3'] = True # (kN m); Blade 3 flapwise moment (i.e., the moment caused by flapwise forces) at the blade root; About the yb3-axis -OutList['RootMFlp3'] = False # (kN m); Blade 3 flapwise moment (i.e., the moment caused by flapwise forces) at the blade root; About the yb3-axis - -# Blade 1 Local Span Loads -OutList['Spn1MLxb1'] = False # (kN m); Blade 1 local edgewise moment at span station 1; About the local xb1-axis -OutList['Spn1MLyb1'] = False # (kN m); Blade 1 local flapwise moment at span station 1; About the local yb1-axis -OutList['Spn1MLzb1'] = False # (kN m); Blade 1 local pitching moment at span station 1; About the local zb1-axis -OutList['Spn2MLxb1'] = False # (kN m); Blade 1 local edgewise moment at span station 2; About the local xb1-axis -OutList['Spn2MLyb1'] = False # (kN m); Blade 1 local flapwise moment at span station 2; About the local yb1-axis -OutList['Spn2MLzb1'] = False # (kN m); Blade 1 local pitching moment at span station 2; About the local zb1-axis -OutList['Spn3MLxb1'] = False # (kN m); Blade 1 local edgewise moment at span station 3; About the local xb1-axis -OutList['Spn3MLyb1'] = False # (kN m); Blade 1 local flapwise moment at span station 3; About the local yb1-axis -OutList['Spn3MLzb1'] = False # (kN m); Blade 1 local pitching moment at span station 3; About the local zb1-axis -OutList['Spn4MLxb1'] = False # (kN m); Blade 1 local edgewise moment at span station 4; About the local xb1-axis -OutList['Spn4MLyb1'] = False # (kN m); Blade 1 local flapwise moment at span station 4; About the local yb1-axis -OutList['Spn4MLzb1'] = False # (kN m); Blade 1 local pitching moment at span station 4; About the local zb1-axis -OutList['Spn5MLxb1'] = False # (kN m); Blade 1 local edgewise moment at span station 5; About the local xb1-axis -OutList['Spn5MLyb1'] = False # (kN m); Blade 1 local flapwise moment at span station 5; About the local yb1-axis -OutList['Spn5MLzb1'] = False # (kN m); Blade 1 local pitching moment at span station 5; About the local zb1-axis -OutList['Spn6MLxb1'] = False # (kN m); Blade 1 local edgewise moment at span station 6; About the local xb1-axis -OutList['Spn6MLyb1'] = False # (kN m); Blade 1 local flapwise moment at span station 6; About the local yb1-axis -OutList['Spn6MLzb1'] = False # (kN m); Blade 1 local pitching moment at span station 6; About the local zb1-axis -OutList['Spn7MLxb1'] = False # (kN m); Blade 1 local edgewise moment at span station 7; About the local xb1-axis -OutList['Spn7MLyb1'] = False # (kN m); Blade 1 local flapwise moment at span station 7; About the local yb1-axis -OutList['Spn7MLzb1'] = False # (kN m); Blade 1 local pitching moment at span station 7; About the local zb1-axis -OutList['Spn8MLxb1'] = False # (kN m); Blade 1 local edgewise moment at span station 8; About the local xb1-axis -OutList['Spn8MLyb1'] = False # (kN m); Blade 1 local flapwise moment at span station 8; About the local yb1-axis -OutList['Spn8MLzb1'] = False # (kN m); Blade 1 local pitching moment at span station 8; About the local zb1-axis -OutList['Spn9MLxb1'] = False # (kN m); Blade 1 local edgewise moment at span station 9; About the local xb1-axis -OutList['Spn9MLyb1'] = False # (kN m); Blade 1 local flapwise moment at span station 9; About the local yb1-axis -OutList['Spn9MLzb1'] = False # (kN m); Blade 1 local pitching moment at span station 9; About the local zb1-axis -OutList['Spn1FLxb1'] = False # (kN); Blade 1 local flapwise shear force at span station 1; Directed along the local xb1-axis -OutList['Spn1FLyb1'] = False # (kN); Blade 1 local edgewise shear force at span station 1; Directed along the local yb1-axis -OutList['Spn1FLzb1'] = False # (kN); Blade 1 local axial force at span station 1; Directed along the local zb1-axis -OutList['Spn2FLxb1'] = False # (kN); Blade 1 local flapwise shear force at span station 2; Directed along the local xb1-axis -OutList['Spn2FLyb1'] = False # (kN); Blade 1 local edgewise shear force at span station 2; Directed along the local yb1-axis -OutList['Spn2FLzb1'] = False # (kN); Blade 1 local axial force at span station 2; Directed along the local zb1-axis -OutList['Spn3FLxb1'] = False # (kN); Blade 1 local flapwise shear force at span station 3; Directed along the local xb1-axis -OutList['Spn3FLyb1'] = False # (kN); Blade 1 local edgewise shear force at span station 3; Directed along the local yb1-axis -OutList['Spn3FLzb1'] = False # (kN); Blade 1 local axial force at span station 3; Directed along the local zb1-axis -OutList['Spn4FLxb1'] = False # (kN); Blade 1 local flapwise shear force at span station 4; Directed along the local xb1-axis -OutList['Spn4FLyb1'] = False # (kN); Blade 1 local edgewise shear force at span station 4; Directed along the local yb1-axis -OutList['Spn4FLzb1'] = False # (kN); Blade 1 local axial force at span station 4; Directed along the local zb1-axis -OutList['Spn5FLxb1'] = False # (kN); Blade 1 local flapwise shear force at span station 5; Directed along the local xb1-axis -OutList['Spn5FLyb1'] = False # (kN); Blade 1 local edgewise shear force at span station 5; Directed along the local yb1-axis -OutList['Spn5FLzb1'] = False # (kN); Blade 1 local axial force at span station 5; Directed along the local zb1-axis -OutList['Spn6FLxb1'] = False # (kN); Blade 1 local flapwise shear force at span station 6; Directed along the local xb1-axis -OutList['Spn6FLyb1'] = False # (kN); Blade 1 local edgewise shear force at span station 6; Directed along the local yb1-axis -OutList['Spn6FLzb1'] = False # (kN); Blade 1 local axial force at span station 6; Directed along the local zb1-axis -OutList['Spn7FLxb1'] = False # (kN); Blade 1 local flapwise shear force at span station 7; Directed along the local xb1-axis -OutList['Spn7FLyb1'] = False # (kN); Blade 1 local edgewise shear force at span station 7; Directed along the local yb1-axis -OutList['Spn7FLzb1'] = False # (kN); Blade 1 local axial force at span station 7; Directed along the local zb1-axis -OutList['Spn8FLxb1'] = False # (kN); Blade 1 local flapwise shear force at span station 8; Directed along the local xb1-axis -OutList['Spn8FLyb1'] = False # (kN); Blade 1 local edgewise shear force at span station 8; Directed along the local yb1-axis -OutList['Spn8FLzb1'] = False # (kN); Blade 1 local axial force at span station 8; Directed along the local zb1-axis -OutList['Spn9FLxb1'] = False # (kN); Blade 1 local flapwise shear force at span station 9; Directed along the local xb1-axis -OutList['Spn9FLyb1'] = False # (kN); Blade 1 local edgewise shear force at span station 9; Directed along the local yb1-axis -OutList['Spn9FLzb1'] = False # (kN); Blade 1 local axial force at span station 9; Directed along the local zb1-axis - -# Blade 2 Local Span Loads -OutList['Spn1MLxb2'] = False # (kN m); Blade 2 local edgewise moment at span station 1; About the local xb2-axis -OutList['Spn1MLyb2'] = False # (kN m); Blade 2 local flapwise moment at span station 1; About the local yb2-axis -OutList['Spn1MLzb2'] = False # (kN m); Blade 2 local pitching moment at span station 1; About the local zb2-axis -OutList['Spn2MLxb2'] = False # (kN m); Blade 2 local edgewise moment at span station 2; About the local xb2-axis -OutList['Spn2MLyb2'] = False # (kN m); Blade 2 local flapwise moment at span station 2; About the local yb2-axis -OutList['Spn2MLzb2'] = False # (kN m); Blade 2 local pitching moment at span station 2; About the local zb2-axis -OutList['Spn3MLxb2'] = False # (kN m); Blade 2 local edgewise moment at span station 3; About the local xb2-axis -OutList['Spn3MLyb2'] = False # (kN m); Blade 2 local flapwise moment at span station 3; About the local yb2-axis -OutList['Spn3MLzb2'] = False # (kN m); Blade 2 local pitching moment at span station 3; About the local zb2-axis -OutList['Spn4MLxb2'] = False # (kN m); Blade 2 local edgewise moment at span station 4; About the local xb2-axis -OutList['Spn4MLyb2'] = False # (kN m); Blade 2 local flapwise moment at span station 4; About the local yb2-axis -OutList['Spn4MLzb2'] = False # (kN m); Blade 2 local pitching moment at span station 4; About the local zb2-axis -OutList['Spn5MLxb2'] = False # (kN m); Blade 2 local edgewise moment at span station 5; About the local xb2-axis -OutList['Spn5MLyb2'] = False # (kN m); Blade 2 local flapwise moment at span station 5; About the local yb2-axis -OutList['Spn5MLzb2'] = False # (kN m); Blade 2 local pitching moment at span station 5; About the local zb2-axis -OutList['Spn6MLxb2'] = False # (kN m); Blade 2 local edgewise moment at span station 6; About the local xb2-axis -OutList['Spn6MLyb2'] = False # (kN m); Blade 2 local flapwise moment at span station 6; About the local yb2-axis -OutList['Spn6MLzb2'] = False # (kN m); Blade 2 local pitching moment at span station 6; About the local zb2-axis -OutList['Spn7MLxb2'] = False # (kN m); Blade 2 local edgewise moment at span station 7; About the local xb2-axis -OutList['Spn7MLyb2'] = False # (kN m); Blade 2 local flapwise moment at span station 7; About the local yb2-axis -OutList['Spn7MLzb2'] = False # (kN m); Blade 2 local pitching moment at span station 7; About the local zb2-axis -OutList['Spn8MLxb2'] = False # (kN m); Blade 2 local edgewise moment at span station 8; About the local xb2-axis -OutList['Spn8MLyb2'] = False # (kN m); Blade 2 local flapwise moment at span station 8; About the local yb2-axis -OutList['Spn8MLzb2'] = False # (kN m); Blade 2 local pitching moment at span station 8; About the local zb2-axis -OutList['Spn9MLxb2'] = False # (kN m); Blade 2 local edgewise moment at span station 9; About the local xb2-axis -OutList['Spn9MLyb2'] = False # (kN m); Blade 2 local flapwise moment at span station 9; About the local yb2-axis -OutList['Spn9MLzb2'] = False # (kN m); Blade 2 local pitching moment at span station 9; About the local zb2-axis -OutList['Spn1FLxb2'] = False # (kN); Blade 2 local flapwise shear force at span station 1; Directed along the local xb2-axis -OutList['Spn1FLyb2'] = False # (kN); Blade 2 local edgewise shear force at span station 1; Directed along the local yb2-axis -OutList['Spn1FLzb2'] = False # (kN); Blade 2 local axial force at span station 1; Directed along the local zb2-axis -OutList['Spn2FLxb2'] = False # (kN); Blade 2 local flapwise shear force at span station 2; Directed along the local xb2-axis -OutList['Spn2FLyb2'] = False # (kN); Blade 2 local edgewise shear force at span station 2; Directed along the local yb2-axis -OutList['Spn2FLzb2'] = False # (kN); Blade 2 local axial force at span station 2; Directed along the local zb2-axis -OutList['Spn3FLxb2'] = False # (kN); Blade 2 local flapwise shear force at span station 3; Directed along the local xb2-axis -OutList['Spn3FLyb2'] = False # (kN); Blade 2 local edgewise shear force at span station 3; Directed along the local yb2-axis -OutList['Spn3FLzb2'] = False # (kN); Blade 2 local axial force at span station 3; Directed along the local zb2-axis -OutList['Spn4FLxb2'] = False # (kN); Blade 2 local flapwise shear force at span station 4; Directed along the local xb2-axis -OutList['Spn4FLyb2'] = False # (kN); Blade 2 local edgewise shear force at span station 4; Directed along the local yb2-axis -OutList['Spn4FLzb2'] = False # (kN); Blade 2 local axial force at span station 4; Directed along the local zb2-axis -OutList['Spn5FLxb2'] = False # (kN); Blade 2 local flapwise shear force at span station 5; Directed along the local xb2-axis -OutList['Spn5FLyb2'] = False # (kN); Blade 2 local edgewise shear force at span station 5; Directed along the local yb2-axis -OutList['Spn5FLzb2'] = False # (kN); Blade 2 local axial force at span station 5; Directed along the local zb2-axis -OutList['Spn6FLxb2'] = False # (kN); Blade 2 local flapwise shear force at span station 6; Directed along the local xb2-axis -OutList['Spn6FLyb2'] = False # (kN); Blade 2 local edgewise shear force at span station 6; Directed along the local yb2-axis -OutList['Spn6FLzb2'] = False # (kN); Blade 2 local axial force at span station 6; Directed along the local zb2-axis -OutList['Spn7FLxb2'] = False # (kN); Blade 2 local flapwise shear force at span station 7; Directed along the local xb2-axis -OutList['Spn7FLyb2'] = False # (kN); Blade 2 local edgewise shear force at span station 7; Directed along the local yb2-axis -OutList['Spn7FLzb2'] = False # (kN); Blade 2 local axial force at span station 7; Directed along the local zb2-axis -OutList['Spn8FLxb2'] = False # (kN); Blade 2 local flapwise shear force at span station 8; Directed along the local xb2-axis -OutList['Spn8FLyb2'] = False # (kN); Blade 2 local edgewise shear force at span station 8; Directed along the local yb2-axis -OutList['Spn8FLzb2'] = False # (kN); Blade 2 local axial force at span station 8; Directed along the local zb2-axis -OutList['Spn9FLxb2'] = False # (kN); Blade 2 local flapwise shear force at span station 9; Directed along the local xb2-axis -OutList['Spn9FLyb2'] = False # (kN); Blade 2 local edgewise shear force at span station 9; Directed along the local yb2-axis -OutList['Spn9FLzb2'] = False # (kN); Blade 2 local axial force at span station 9; Directed along the local zb2-axis - -# Blade 3 Local Span Loads -OutList['Spn1MLxb3'] = False # (kN m); Blade 3 local edgewise moment at span station 1; About the local xb3-axis -OutList['Spn1MLyb3'] = False # (kN m); Blade 3 local flapwise moment at span station 1; About the local yb3-axis -OutList['Spn1MLzb3'] = False # (kN m); Blade 3 local pitching moment at span station 1; About the local zb3-axis -OutList['Spn2MLxb3'] = False # (kN m); Blade 3 local edgewise moment at span station 2; About the local xb3-axis -OutList['Spn2MLyb3'] = False # (kN m); Blade 3 local flapwise moment at span station 2; About the local yb3-axis -OutList['Spn2MLzb3'] = False # (kN m); Blade 3 local pitching moment at span station 2; About the local zb3-axis -OutList['Spn3MLxb3'] = False # (kN m); Blade 3 local edgewise moment at span station 3; About the local xb3-axis -OutList['Spn3MLyb3'] = False # (kN m); Blade 3 local flapwise moment at span station 3; About the local yb3-axis -OutList['Spn3MLzb3'] = False # (kN m); Blade 3 local pitching moment at span station 3; About the local zb3-axis -OutList['Spn4MLxb3'] = False # (kN m); Blade 3 local edgewise moment at span station 4; About the local xb3-axis -OutList['Spn4MLyb3'] = False # (kN m); Blade 3 local flapwise moment at span station 4; About the local yb3-axis -OutList['Spn4MLzb3'] = False # (kN m); Blade 3 local pitching moment at span station 4; About the local zb3-axis -OutList['Spn5MLxb3'] = False # (kN m); Blade 3 local edgewise moment at span station 5; About the local xb3-axis -OutList['Spn5MLyb3'] = False # (kN m); Blade 3 local flapwise moment at span station 5; About the local yb3-axis -OutList['Spn5MLzb3'] = False # (kN m); Blade 3 local pitching moment at span station 5; About the local zb3-axis -OutList['Spn6MLxb3'] = False # (kN m); Blade 3 local edgewise moment at span station 6; About the local xb3-axis -OutList['Spn6MLyb3'] = False # (kN m); Blade 3 local flapwise moment at span station 6; About the local yb3-axis -OutList['Spn6MLzb3'] = False # (kN m); Blade 3 local pitching moment at span station 6; About the local zb3-axis -OutList['Spn7MLxb3'] = False # (kN m); Blade 3 local edgewise moment at span station 7; About the local xb3-axis -OutList['Spn7MLyb3'] = False # (kN m); Blade 3 local flapwise moment at span station 7; About the local yb3-axis -OutList['Spn7MLzb3'] = False # (kN m); Blade 3 local pitching moment at span station 7; About the local zb3-axis -OutList['Spn8MLxb3'] = False # (kN m); Blade 3 local edgewise moment at span station 8; About the local xb3-axis -OutList['Spn8MLyb3'] = False # (kN m); Blade 3 local flapwise moment at span station 8; About the local yb3-axis -OutList['Spn8MLzb3'] = False # (kN m); Blade 3 local pitching moment at span station 8; About the local zb3-axis -OutList['Spn9MLxb3'] = False # (kN m); Blade 3 local edgewise moment at span station 9; About the local xb3-axis -OutList['Spn9MLyb3'] = False # (kN m); Blade 3 local flapwise moment at span station 9; About the local yb3-axis -OutList['Spn9MLzb3'] = False # (kN m); Blade 3 local pitching moment at span station 9; About the local zb3-axis -OutList['Spn1FLxb3'] = False # (kN); Blade 3 local flapwise shear force at span station 1; Directed along the local xb3-axis -OutList['Spn1FLyb3'] = False # (kN); Blade 3 local edgewise shear force at span station 1; Directed along the local yb3-axis -OutList['Spn1FLzb3'] = False # (kN); Blade 3 local axial force at span station 1; Directed along the local zb3-axis -OutList['Spn2FLxb3'] = False # (kN); Blade 3 local flapwise shear force at span station 2; Directed along the local xb3-axis -OutList['Spn2FLyb3'] = False # (kN); Blade 3 local edgewise shear force at span station 2; Directed along the local yb3-axis -OutList['Spn2FLzb3'] = False # (kN); Blade 3 local axial force at span station 2; Directed along the local zb3-axis -OutList['Spn3FLxb3'] = False # (kN); Blade 3 local flapwise shear force at span station 3; Directed along the local xb3-axis -OutList['Spn3FLyb3'] = False # (kN); Blade 3 local edgewise shear force at span station 3; Directed along the local yb3-axis -OutList['Spn3FLzb3'] = False # (kN); Blade 3 local axial force at span station 3; Directed along the local zb3-axis -OutList['Spn4FLxb3'] = False # (kN); Blade 3 local flapwise shear force at span station 4; Directed along the local xb3-axis -OutList['Spn4FLyb3'] = False # (kN); Blade 3 local edgewise shear force at span station 4; Directed along the local yb3-axis -OutList['Spn4FLzb3'] = False # (kN); Blade 3 local axial force at span station 4; Directed along the local zb3-axis -OutList['Spn5FLxb3'] = False # (kN); Blade 3 local flapwise shear force at span station 5; Directed along the local xb3-axis -OutList['Spn5FLyb3'] = False # (kN); Blade 3 local edgewise shear force at span station 5; Directed along the local yb3-axis -OutList['Spn5FLzb3'] = False # (kN); Blade 3 local axial force at span station 5; Directed along the local zb3-axis -OutList['Spn6FLxb3'] = False # (kN); Blade 3 local flapwise shear force at span station 6; Directed along the local xb3-axis -OutList['Spn6FLyb3'] = False # (kN); Blade 3 local edgewise shear force at span station 6; Directed along the local yb3-axis -OutList['Spn6FLzb3'] = False # (kN); Blade 3 local axial force at span station 6; Directed along the local zb3-axis -OutList['Spn7FLxb3'] = False # (kN); Blade 3 local flapwise shear force at span station 7; Directed along the local xb3-axis -OutList['Spn7FLyb3'] = False # (kN); Blade 3 local edgewise shear force at span station 7; Directed along the local yb3-axis -OutList['Spn7FLzb3'] = False # (kN); Blade 3 local axial force at span station 7; Directed along the local zb3-axis -OutList['Spn8FLxb3'] = False # (kN); Blade 3 local flapwise shear force at span station 8; Directed along the local xb3-axis -OutList['Spn8FLyb3'] = False # (kN); Blade 3 local edgewise shear force at span station 8; Directed along the local yb3-axis -OutList['Spn8FLzb3'] = False # (kN); Blade 3 local axial force at span station 8; Directed along the local zb3-axis -OutList['Spn9FLxb3'] = False # (kN); Blade 3 local flapwise shear force at span station 9; Directed along the local xb3-axis -OutList['Spn9FLyb3'] = False # (kN); Blade 3 local edgewise shear force at span station 9; Directed along the local yb3-axis -OutList['Spn9FLzb3'] = False # (kN); Blade 3 local axial force at span station 9; Directed along the local zb3-axis - -# Hub and Rotor Loads -OutList['LSShftFxa'] = False # (kN); Low-speed shaft thrust force (this is constant along the shaft and is equivalent to the rotor thrust force); Directed along the xa- and xs-axes -OutList['LSShftFxs'] = False # (kN); Low-speed shaft thrust force (this is constant along the shaft and is equivalent to the rotor thrust force); Directed along the xa- and xs-axes -OutList['LSSGagFxa'] = False # (kN); Low-speed shaft thrust force (this is constant along the shaft and is equivalent to the rotor thrust force); Directed along the xa- and xs-axes -OutList['LSSGagFxs'] = False # (kN); Low-speed shaft thrust force (this is constant along the shaft and is equivalent to the rotor thrust force); Directed along the xa- and xs-axes -OutList['RotThrust'] = False # (kN); Low-speed shaft thrust force (this is constant along the shaft and is equivalent to the rotor thrust force); Directed along the xa- and xs-axes -OutList['LSShftFya'] = False # (kN); Rotating low-speed shaft shear force (this is constant along the shaft); Directed along the ya-axis -OutList['LSSGagFya'] = False # (kN); Rotating low-speed shaft shear force (this is constant along the shaft); Directed along the ya-axis -OutList['LSShftFza'] = False # (kN); Rotating low-speed shaft shear force (this is constant along the shaft); Directed along the za-axis -OutList['LSSGagFza'] = False # (kN); Rotating low-speed shaft shear force (this is constant along the shaft); Directed along the za-axis -OutList['LSShftFys'] = True # (kN); Nonrotating low-speed shaft shear force (this is constant along the shaft); Directed along the ys-axis -OutList['LSSGagFys'] = False # (kN); Nonrotating low-speed shaft shear force (this is constant along the shaft); Directed along the ys-axis -OutList['LSShftFzs'] = True # (kN); Nonrotating low-speed shaft shear force (this is constant along the shaft); Directed along the zs-axis -OutList['LSSGagFzs'] = False # (kN); Nonrotating low-speed shaft shear force (this is constant along the shaft); Directed along the zs-axis -OutList['LSShftMxa'] = False # (kN m); Low-speed shaft torque (this is constant along the shaft and is equivalent to the rotor torque); About the xa- and xs-axes -OutList['LSShftMxs'] = False # (kN m); Low-speed shaft torque (this is constant along the shaft and is equivalent to the rotor torque); About the xa- and xs-axes -OutList['LSSGagMxa'] = False # (kN m); Low-speed shaft torque (this is constant along the shaft and is equivalent to the rotor torque); About the xa- and xs-axes -OutList['LSSGagMxs'] = False # (kN m); Low-speed shaft torque (this is constant along the shaft and is equivalent to the rotor torque); About the xa- and xs-axes -OutList['RotTorq'] = False # (kN m); Low-speed shaft torque (this is constant along the shaft and is equivalent to the rotor torque); About the xa- and xs-axes -OutList['LSShftTq'] = False # (kN m); Low-speed shaft torque (this is constant along the shaft and is equivalent to the rotor torque); About the xa- and xs-axes -OutList['LSSTipMya'] = False # (kN m); Rotating low-speed shaft bending moment at the shaft tip (teeter pin for 2-blader, apex of rotation for 3-blader); About the ya-axis -OutList['LSSTipMza'] = False # (kN m); Rotating low-speed shaft bending moment at the shaft tip (teeter pin for 2-blader, apex of rotation for 3-blader); About the za-axis -OutList['LSSTipMys'] = True # (kN m); Nonrotating low-speed shaft bending moment at the shaft tip (teeter pin for 2-blader, apex of rotation for 3-blader); About the ys-axis -OutList['LSSTipMzs'] = True # (kN m); Nonrotating low-speed shaft bending moment at the shaft tip (teeter pin for 2-blader, apex of rotation for 3-blader); About the zs-axis -OutList['CThrstAzm'] = False # (deg); Azimuth location of the center of thrust. This is estimated using values of LSSTipMys, LSSTipMzs, and RotThrust.; About the xa- and xs-axes -OutList['CThrstRad'] = False # (-); Dimensionless radial (arm) location of the center of thrust. This is estimated using values of LSSTipMys, LSSTipMzs, and RotThrust. (nondimensionalized using the undeflected tip radius normal to the shaft and limited to values between 0 and 1 (inclusive)); Always positive (directed radially outboard at azimuth angle CThrstAzm) -OutList['CThrstArm'] = False # (-); Dimensionless radial (arm) location of the center of thrust. This is estimated using values of LSSTipMys, LSSTipMzs, and RotThrust. (nondimensionalized using the undeflected tip radius normal to the shaft and limited to values between 0 and 1 (inclusive)); Always positive (directed radially outboard at azimuth angle CThrstAzm) -OutList['RotPwr'] = False # (kW); Rotor power (this is equivalent to the low-speed shaft power); N/A -OutList['LSShftPwr'] = False # (kW); Rotor power (this is equivalent to the low-speed shaft power); N/A -OutList['RotCq'] = False # (-); Rotor torque coefficient (this is equivalent to the low-speed shaft torque coefficient); N/A -OutList['LSShftCq'] = False # (-); Rotor torque coefficient (this is equivalent to the low-speed shaft torque coefficient); N/A -OutList['RotCp'] = False # (-); Rotor power coefficient (this is equivalent to the low-speed shaft power coefficient); N/A -OutList['LSShftCp'] = False # (-); Rotor power coefficient (this is equivalent to the low-speed shaft power coefficient); N/A -OutList['RotCt'] = False # (-); Rotor thrust coefficient (this is equivalent to the low-speed shaft thrust coefficient); N/A -OutList['LSShftCt'] = False # (-); Rotor thrust coefficient (this is equivalent to the low-speed shaft thrust coefficient); N/A - -# Shaft Strain Gage Loads -OutList['LSSGagMya'] = False # (kN m); Rotating low-speed shaft bending moment at the shaft's strain gage (shaft strain gage located by input ShftGagL); About the ya-axis -OutList['LSSGagMza'] = False # (kN m); Rotating low-speed shaft bending moment at the shaft's strain gage (shaft strain gage located by input ShftGagL); About the za-axis -OutList['LSSGagMys'] = False # (kN m); Nonrotating low-speed shaft bending moment at the shaft's strain gage (shaft strain gage located by input ShftGagL); About the ys-axis -OutList['LSSGagMzs'] = False # (kN m); Nonrotating low-speed shaft bending moment at the shaft's strain gage (shaft strain gage located by input ShftGagL); About the zs-axis - -# Generator and High-Speed Shaft Loads -OutList['HSShftTq'] = False # (kN m); High-speed shaft torque (this is constant along the shaft); Same sign as LSShftTq / RotTorq / LSShftMxa / LSShftMxs / LSSGagMxa / LSSGagMxs -OutList['HSShftPwr'] = False # (kW); High-speed shaft power; Same sign as HSShftTq -OutList['HSShftCq'] = False # (-); High-speed shaft torque coefficient; N/A -OutList['HSShftCp'] = False # (-); High-speed shaft power coefficient; N/A -OutList['GenTq'] = False # (kN m); Electrical generator torque; Positive reflects power extracted and negative represents a motoring-up situation (power input) -OutList['GenPwr'] = False # (kW); Electrical generator power; Same sign as GenTq -OutList['GenCq'] = False # (-); Electrical generator torque coefficient; N/A -OutList['GenCp'] = False # (-); Electrical generator power coefficient; N/A -OutList['HSSBrTq'] = False # (kN m); High-speed shaft brake torque (i.e., the moment applied to the high-speed shaft by the brake); Always positive (indicating dissipation of power) - -# Rotor-Furl Bearing Loads -OutList['RFrlBrM'] = False # (kN m); Rotor-furl bearing moment; About the rotor-furl axis - -# Tail-Furl Bearing Loads -OutList['TFrlBrM'] = False # (kN m); Tail-furl bearing moment; About the tail-furl axis - -# Tail Fin Aerodynamic Loads -OutList['TFinAlpha'] = False # (deg); Tail fin angle of attack. This is the angle between the relative velocity of the wind-inflow at the tail fin center-of-pressure and the tail fin chordline.; About the tail fin z-axis, which is the axis in the tail fin plane normal to the chordline -OutList['TFinCLift'] = False # (-); Tail fin dimensionless lift coefficient; N/A -OutList['TFinCDrag'] = False # (-); Tail fin dimensionless drag coefficient; N/A -OutList['TFinDnPrs'] = False # (Pa); Tail fin dynamic pressure, equal to 1/2*AirDens*Vrel^2 where Vrel is the relative velocity of the wind-inflow at the tail fin center-of-pressure; N/A -OutList['TFinCPFx'] = False # (kN); Tangential aerodynamic force at the tail fin center-of-pressure; Directed along the tail fin x-axis, which is the axis along the chordline, positive towards the trailing edge -OutList['TFinCPFy'] = False # (kN); Normal aerodynamic force at the tail fin center-of-pressure; Directed along the tail fin y-axis, which is orthogonal to the tail fin plane - -# Tower-Top / Yaw Bearing Loads -OutList['YawBrFxn'] = False # (kN); Rotating (with nacelle) tower-top / yaw bearing shear force; Directed along the xn-axis -OutList['YawBrFyn'] = False # (kN); Rotating (with nacelle) tower-top / yaw bearing shear force; Directed along the yn-axis -OutList['YawBrFzn'] = False # (kN); Tower-top / yaw bearing axial force; Directed along the zn- and zp-axes -OutList['YawBrFzp'] = False # (kN); Tower-top / yaw bearing axial force; Directed along the zn- and zp-axes -OutList['YawBrFxp'] = False # (kN); Tower-top / yaw bearing fore-aft (nonrotating) shear force; Directed along the xp-axis -OutList['YawBrFyp'] = False # (kN); Tower-top / yaw bearing side-to-side (nonrotating) shear force; Directed along the yp-axis -OutList['YawBrMxn'] = False # (kN m); Rotating (with nacelle) tower-top / yaw bearing roll moment; About the xn-axis -OutList['YawBrMyn'] = False # (kN m); Rotating (with nacelle) tower-top / yaw bearing pitch moment; About the yn-axis -OutList['YawBrMzn'] = False # (kN m); Tower-top / yaw bearing yaw moment; About the zn- and zp-axes -OutList['YawBrMzp'] = False # (kN m); Tower-top / yaw bearing yaw moment; About the zn- and zp-axes -OutList['YawMom'] = False # (kN m); Tower-top / yaw bearing yaw moment; About the zn- and zp-axes -OutList['YawBrMxp'] = False # (kN m); Nonrotating tower-top / yaw bearing roll moment; About the xp-axis -OutList['YawBrMyp'] = False # (kN m); Nonrotating tower-top / yaw bearing pitch moment; About the yp-axis - -# Tower Base Loads -OutList['TwrBsFxt'] = False # (kN); Tower base fore-aft shear force; Directed along the xt-axis -OutList['TwrBsFyt'] = False # (kN); Tower base side-to-side shear force; Directed along the yt-axis -OutList['TwrBsFzt'] = False # (kN); Tower base axial force; Directed along the zt-axis -OutList['TwrBsMxt'] = False # (kN m); Tower base roll (or side-to-side) moment (i.e., the moment caused by side-to-side forces); About the xt-axis -OutList['TwrBsMyt'] = True # (kN m); Tower base pitching (or fore-aft) moment (i.e., the moment caused by fore-aft forces); About the yt-axis -OutList['TwrBsMzt'] = False # (kN m); Tower base yaw (or torsional) moment; About the zt-axis - -# Local Tower Loads -OutList['TwHt1MLxt'] = False # (kN m); Local tower roll (or side-to-side) moment of tower gage 1; About the local xt-axis -OutList['TwHt1MLyt'] = False # (kN m); Local tower pitching (or fore-aft) moment of tower gage 1; About the local yt-axis -OutList['TwHt1MLzt'] = False # (kN m); Local tower yaw (or torsional) moment of tower gage 1; About the local zt-axis -OutList['TwHt2MLxt'] = False # (kN m); Local tower roll (or side-to-side) moment of tower gage 2; About the local xt-axis -OutList['TwHt2MLyt'] = False # (kN m); Local tower pitching (or fore-aft) moment of tower gage 2; About the local yt-axis -OutList['TwHt2MLzt'] = False # (kN m); Local tower yaw (or torsional) moment of tower gage 2; About the local zt-axis -OutList['TwHt3MLxt'] = False # (kN m); Local tower roll (or side-to-side) moment of tower gage 3; About the local xt-axis -OutList['TwHt3MLyt'] = False # (kN m); Local tower pitching (or fore-aft) moment of tower gage 3; About the local yt-axis -OutList['TwHt3MLzt'] = False # (kN m); Local tower yaw (or torsional) moment of tower gage 3; About the local zt-axis -OutList['TwHt4MLxt'] = False # (kN m); Local tower roll (or side-to-side) moment of tower gage 4; About the local xt-axis -OutList['TwHt4MLyt'] = False # (kN m); Local tower pitching (or fore-aft) moment of tower gage 4; About the local yt-axis -OutList['TwHt4MLzt'] = False # (kN m); Local tower yaw (or torsional) moment of tower gage 4; About the local zt-axis -OutList['TwHt5MLxt'] = False # (kN m); Local tower roll (or side-to-side) moment of tower gage 5; About the local xt-axis -OutList['TwHt5MLyt'] = False # (kN m); Local tower pitching (or fore-aft) moment of tower gage 5; About the local yt-axis -OutList['TwHt5MLzt'] = False # (kN m); Local tower yaw (or torsional) moment of tower gage 5; About the local zt-axis -OutList['TwHt6MLxt'] = False # (kN m); Local tower roll (or side-to-side) moment of tower gage 6; About the local xt-axis -OutList['TwHt6MLyt'] = False # (kN m); Local tower pitching (or fore-aft) moment of tower gage 6; About the local yt-axis -OutList['TwHt6MLzt'] = False # (kN m); Local tower yaw (or torsional) moment of tower gage 6; About the local zt-axis -OutList['TwHt7MLxt'] = False # (kN m); Local tower roll (or side-to-side) moment of tower gage 7; About the local xt-axis -OutList['TwHt7MLyt'] = False # (kN m); Local tower pitching (or fore-aft) moment of tower gage 7; About the local yt-axis -OutList['TwHt7MLzt'] = False # (kN m); Local tower yaw (or torsional) moment of tower gage 7; About the local zt-axis -OutList['TwHt8MLxt'] = False # (kN m); Local tower roll (or side-to-side) moment of tower gage 8; About the local xt-axis -OutList['TwHt8MLyt'] = False # (kN m); Local tower pitching (or fore-aft) moment of tower gage 8; About the local yt-axis -OutList['TwHt8MLzt'] = False # (kN m); Local tower yaw (or torsional) moment of tower gage 8; About the local zt-axis -OutList['TwHt9MLxt'] = False # (kN m); Local tower roll (or side-to-side) moment of tower gage 9; About the local xt-axis -OutList['TwHt9MLyt'] = False # (kN m); Local tower pitching (or fore-aft) moment of tower gage 9; About the local yt-axis -OutList['TwHt9MLzt'] = False # (kN m); Local tower yaw (or torsional) moment of tower gage 9; About the local zt-axis -OutList['TwHt1FLxt'] = False # (kN); Local tower roll (or side-to-side) force of tower gage 1; About the local xt-axis -OutList['TwHt1FLyt'] = False # (kN); Local tower pitching (or fore-aft) force of tower gage 1; About the local yt-axis -OutList['TwHt1FLzt'] = False # (kN); Local tower yaw (or torsional) force of tower gage 1; About the local zt-axis -OutList['TwHt2FLxt'] = False # (kN); Local tower roll (or side-to-side) force of tower gage 2; About the local xt-axis -OutList['TwHt2FLyt'] = False # (kN); Local tower pitching (or fore-aft) force of tower gage 2; About the local yt-axis -OutList['TwHt2FLzt'] = False # (kN); Local tower yaw (or torsional) force of tower gage 2; About the local zt-axis -OutList['TwHt3FLxt'] = False # (kN); Local tower roll (or side-to-side) force of tower gage 3; About the local xt-axis -OutList['TwHt3FLyt'] = False # (kN); Local tower pitching (or fore-aft) force of tower gage 3; About the local yt-axis -OutList['TwHt3FLzt'] = False # (kN); Local tower yaw (or torsional) force of tower gage 3; About the local zt-axis -OutList['TwHt4FLxt'] = False # (kN); Local tower roll (or side-to-side) force of tower gage 4; About the local xt-axis -OutList['TwHt4FLyt'] = False # (kN); Local tower pitching (or fore-aft) force of tower gage 4; About the local yt-axis -OutList['TwHt4FLzt'] = False # (kN); Local tower yaw (or torsional) force of tower gage 4; About the local zt-axis -OutList['TwHt5FLxt'] = False # (kN); Local tower roll (or side-to-side) force of tower gage 5; About the local xt-axis -OutList['TwHt5FLyt'] = False # (kN); Local tower pitching (or fore-aft) force of tower gage 5; About the local yt-axis -OutList['TwHt5FLzt'] = False # (kN); Local tower yaw (or torsional) force of tower gage 5; About the local zt-axis -OutList['TwHt6FLxt'] = False # (kN); Local tower roll (or side-to-side) force of tower gage 6; About the local xt-axis -OutList['TwHt6FLyt'] = False # (kN); Local tower pitching (or fore-aft) force of tower gage 6; About the local yt-axis -OutList['TwHt6FLzt'] = False # (kN); Local tower yaw (or torsional) force of tower gage 6; About the local zt-axis -OutList['TwHt7FLxt'] = False # (kN); Local tower roll (or side-to-side) force of tower gage 7; About the local xt-axis -OutList['TwHt7FLyt'] = False # (kN); Local tower pitching (or fore-aft) force of tower gage 7; About the local yt-axis -OutList['TwHt7FLzt'] = False # (kN); Local tower yaw (or torsional) force of tower gage 7; About the local zt-axis -OutList['TwHt8FLxt'] = False # (kN); Local tower roll (or side-to-side) force of tower gage 8; About the local xt-axis -OutList['TwHt8FLyt'] = False # (kN); Local tower pitching (or fore-aft) force of tower gage 8; About the local yt-axis -OutList['TwHt8FLzt'] = False # (kN); Local tower yaw (or torsional) force of tower gage 8; About the local zt-axis -OutList['TwHt9FLxt'] = False # (kN); Local tower roll (or side-to-side) force of tower gage 9; About the local xt-axis -OutList['TwHt9FLyt'] = False # (kN); Local tower pitching (or fore-aft) force of tower gage 9; About the local yt-axis -OutList['TwHt9FLzt'] = False # (kN); Local tower yaw (or torsional) force of tower gage 9; About the local zt-axis - -# Platform Loads -OutList['PtfmFxt'] = False # (kN); Platform horizontal surge shear force; Directed along the xt-axis -OutList['PtfmFyt'] = False # (kN); Platform horizontal sway shear force; Directed along the yt-axis -OutList['PtfmFzt'] = False # (kN); Platform vertical heave force; Directed along the zt-axis -OutList['PtfmFxi'] = False # (kN); Platform horizontal surge shear force; Directed along the xi-axis -OutList['PtfmFyi'] = False # (kN); Platform horizontal sway shear force; Directed along the yi-axis -OutList['PtfmFzi'] = False # (kN); Platform vertical heave force; Directed along the zi-axis -OutList['PtfmMxt'] = False # (kN m); Platform roll tilt moment; About the xt-axis -OutList['PtfmMyt'] = False # (kN m); Platform pitch tilt moment; About the yt-axis -OutList['PtfmMzt'] = False # (kN m); Platform yaw moment; About the zt-axis -OutList['PtfmMxi'] = False # (kN m); Platform roll tilt moment; About the xi-axis -OutList['PtfmMyi'] = False # (kN m); Platform pitch tilt moment; About the yi-axis -OutList['PtfmMzi'] = False # (kN m); Platform yaw moment; About the zi-axis - -# Mooring Line Loads -OutList['Fair1Ten'] = False # (kN); ; -OutList['Fair1Ang'] = False # (deg); ; -OutList['Anch1Ten'] = False # (kN); ; -OutList['Anch1Ang'] = False # (deg); ; -OutList['Fair2Ten'] = False # (kN); ; -OutList['Fair2Ang'] = False # (deg); ; -OutList['Anch2Ten'] = False # (kN); ; -OutList['Anch2Ang'] = False # (deg); ; -OutList['Fair3Ten'] = False # (kN); ; -OutList['Fair3Ang'] = False # (deg); ; -OutList['Anch3Ten'] = False # (kN); ; -OutList['Anch3Ang'] = False # (deg); ; -OutList['Fair4Ten'] = False # (kN); ; -OutList['Fair4Ang'] = False # (deg); ; -OutList['Anch4Ten'] = False # (kN); ; -OutList['Anch4Ang'] = False # (deg); ; -OutList['Fair5Ten'] = False # (kN); ; -OutList['Fair5Ang'] = False # (deg); ; -OutList['Anch5Ten'] = False # (kN); ; -OutList['Anch5Ang'] = False # (deg); ; -OutList['Fair6Ten'] = False # (kN); ; -OutList['Fair6Ang'] = False # (deg); ; -OutList['Anch6Ten'] = False # (kN); ; -OutList['Anch6Ang'] = False # (deg); ; -OutList['Fair7Ten'] = False # (kN); ; -OutList['Fair7Ang'] = False # (deg); ; -OutList['Anch7Ten'] = False # (kN); ; -OutList['Anch7Ang'] = False # (deg); ; -OutList['Fair8Ten'] = False # (kN); ; -OutList['Fair8Ang'] = False # (deg); ; -OutList['Anch8Ten'] = False # (kN); ; -OutList['Anch8Ang'] = False # (deg); ; -OutList['Fair9Ten'] = False # (kN); ; -OutList['Fair9Ang'] = False # (deg); ; -OutList['Anch9Ten'] = False # (kN); ; -OutList['Anch9Ang'] = False # (deg); ; - -# Wave Motions -OutList['WaveElev'] = False # (m); ; -OutList['Wave1Vxi'] = False # (m/s); ; -OutList['Wave1Vyi'] = False # (m/s); ; -OutList['Wave1Vzi'] = False # (m/s); ; -OutList['Wave1Axi'] = False # (m/s^2); ; -OutList['Wave1Ayi'] = False # (m/s^2); ; -OutList['Wave1Azi'] = False # (m/s^2); ; -OutList['Wave2Vxi'] = False # (m/s); ; -OutList['Wave2Vyi'] = False # (m/s); ; -OutList['Wave2Vzi'] = False # (m/s); ; -OutList['Wave2Axi'] = False # (m/s^2); ; -OutList['Wave2Ayi'] = False # (m/s^2); ; -OutList['Wave2Azi'] = False # (m/s^2); ; -OutList['Wave3Vxi'] = False # (m/s); ; -OutList['Wave3Vyi'] = False # (m/s); ; -OutList['Wave3Vzi'] = False # (m/s); ; -OutList['Wave3Axi'] = False # (m/s^2); ; -OutList['Wave3Ayi'] = False # (m/s^2); ; -OutList['Wave3Azi'] = False # (m/s^2); ; -OutList['Wave4Vxi'] = False # (m/s); ; -OutList['Wave4Vyi'] = False # (m/s); ; -OutList['Wave4Vzi'] = False # (m/s); ; -OutList['Wave4Axi'] = False # (m/s^2); ; -OutList['Wave4Ayi'] = False # (m/s^2); ; -OutList['Wave4Azi'] = False # (m/s^2); ; -OutList['Wave5Vxi'] = False # (m/s); ; -OutList['Wave5Vyi'] = False # (m/s); ; -OutList['Wave5Vzi'] = False # (m/s); ; -OutList['Wave5Axi'] = False # (m/s^2); ; -OutList['Wave5Ayi'] = False # (m/s^2); ; -OutList['Wave5Azi'] = False # (m/s^2); ; -OutList['Wave6Vxi'] = False # (m/s); ; -OutList['Wave6Vyi'] = False # (m/s); ; -OutList['Wave6Vzi'] = False # (m/s); ; -OutList['Wave6Axi'] = False # (m/s^2); ; -OutList['Wave6Ayi'] = False # (m/s^2); ; -OutList['Wave6Azi'] = False # (m/s^2); ; -OutList['Wave7Vxi'] = False # (m/s); ; -OutList['Wave7Vyi'] = False # (m/s); ; -OutList['Wave7Vzi'] = False # (m/s); ; -OutList['Wave7Axi'] = False # (m/s^2); ; -OutList['Wave7Ayi'] = False # (m/s^2); ; -OutList['Wave7Azi'] = False # (m/s^2); ; -OutList['Wave8Vxi'] = False # (m/s); ; -OutList['Wave8Vyi'] = False # (m/s); ; -OutList['Wave8Vzi'] = False # (m/s); ; -OutList['Wave8Axi'] = False # (m/s^2); ; -OutList['Wave8Ayi'] = False # (m/s^2); ; -OutList['Wave8Azi'] = False # (m/s^2); ; -OutList['Wave9Vxi'] = False # (m/s); ; -OutList['Wave9Vyi'] = False # (m/s); ; -OutList['Wave9Vzi'] = False # (m/s); ; -OutList['Wave9Axi'] = False # (m/s^2); ; -OutList['Wave9Ayi'] = False # (m/s^2); ; -OutList['Wave9Azi'] = False # (m/s^2); ; - -# Internal Degrees of Freedom -OutList['Q_B1E1'] = False # (m); Displacement of 1st edgewise bending-mode DOF of blade 1; -OutList['Q_B2E1'] = False # (m); Displacement of 1st edgewise bending-mode DOF of blade 2; -OutList['Q_B3E1'] = False # (m); Displacement of 1st edgewise bending-mode DOF of blade 3; -OutList['Q_B1F1'] = False # (m); Displacement of 1st flapwise bending-mode DOF of blade 1; -OutList['Q_B2F1'] = False # (m); Displacement of 1st flapwise bending-mode DOF of blade 2; -OutList['Q_B3F1'] = False # (m); Displacement of 1st flapwise bending-mode DOF of blade 3; -OutList['Q_B1F2'] = False # (m); Displacement of 2nd flapwise bending-mode DOF of blade 1; -OutList['Q_B2F2'] = False # (m); Displacement of 2nd flapwise bending-mode DOF of blade 2; -OutList['Q_B3F2'] = False # (m); Displacement of 2nd flapwise bending-mode DOF of blade 3; -OutList['Q_Teet'] = False # (rad); Displacement of hub teetering DOF; -OutList['Q_DrTr'] = False # (rad); Displacement of drivetrain rotational-flexibility DOF; -OutList['Q_GeAz'] = False # (rad); Displacement of variable speed generator DOF; -OutList['Q_RFrl'] = False # (rad); Displacement of rotor-furl DOF; -OutList['Q_TFrl'] = False # (rad); Displacement of tail-furl DOF; -OutList['Q_Yaw'] = False # (rad); Displacement of nacelle yaw DOF; -OutList['Q_TFA1'] = False # (m); Displacement of 1st tower fore-aft bending mode DOF; -OutList['Q_TSS1'] = False # (m); Displacement of 1st tower side-to-side bending mode DOF; -OutList['Q_TFA2'] = False # (m); Displacement of 2nd tower fore-aft bending mode DOF; -OutList['Q_TSS2'] = False # (m); Displacement of 2nd tower side-to-side bending mode DOF; -OutList['Q_Sg'] = False # (m); Displacement of platform horizontal surge translation DOF; -OutList['Q_Sw'] = False # (m); Displacement of platform horizontal sway translation DOF; -OutList['Q_Hv'] = False # (m); Displacement of platform vertical heave translation DOF; -OutList['Q_R'] = False # (rad); Displacement of platform roll tilt rotation DOF; -OutList['Q_P'] = False # (rad); Displacement of platform pitch tilt rotation DOF; -OutList['Q_Y'] = False # (rad); Displacement of platform yaw rotation DOF; -OutList['QD_B1E1'] = False # (m/s); Velocity of 1st edgewise bending-mode DOF of blade 1; -OutList['QD_B2E1'] = False # (m/s); Velocity of 1st edgewise bending-mode DOF of blade 2; -OutList['QD_B3E1'] = False # (m/s); Velocity of 1st edgewise bending-mode DOF of blade 3; -OutList['QD_B1F1'] = False # (m/s); Velocity of 1st flapwise bending-mode DOF of blade 1; -OutList['QD_B2F1'] = False # (m/s); Velocity of 1st flapwise bending-mode DOF of blade 2; -OutList['QD_B3F1'] = False # (m/s); Velocity of 1st flapwise bending-mode DOF of blade 3; -OutList['QD_B1F2'] = False # (m/s); Velocity of 2nd flapwise bending-mode DOF of blade 1; -OutList['QD_B2F2'] = False # (m/s); Velocity of 2nd flapwise bending-mode DOF of blade 2; -OutList['QD_B3F2'] = False # (m/s); Velocity of 2nd flapwise bending-mode DOF of blade 3; -OutList['QD_Teet'] = False # (rad/s); Velocity of hub teetering DOF; -OutList['QD_DrTr'] = False # (rad/s); Velocity of drivetrain rotational-flexibility DOF; -OutList['QD_GeAz'] = False # (rad/s); Velocity of variable speed generator DOF; -OutList['QD_RFrl'] = False # (rad/s); Velocity of rotor-furl DOF; -OutList['QD_TFrl'] = False # (rad/s); Velocity of tail-furl DOF; -OutList['QD_Yaw'] = False # (rad/s); Velocity of nacelle yaw DOF; -OutList['QD_TFA1'] = False # (m/s); Velocity of 1st tower fore-aft bending mode DOF; -OutList['QD_TSS1'] = False # (m/s); Velocity of 1st tower side-to-side bending mode DOF; -OutList['QD_TFA2'] = False # (m/s); Velocity of 2nd tower fore-aft bending mode DOF; -OutList['QD_TSS2'] = False # (m/s); Velocity of 2nd tower side-to-side bending mode DOF; -OutList['QD_Sg'] = False # (m/s); Velocity of platform horizontal surge translation DOF; -OutList['QD_Sw'] = False # (m/s); Velocity of platform horizontal sway translation DOF; -OutList['QD_Hv'] = False # (m/s); Velocity of platform vertical heave translation DOF; -OutList['QD_R'] = False # (rad/s); Velocity of platform roll tilt rotation DOF; -OutList['QD_P'] = False # (rad/s); Velocity of platform pitch tilt rotation DOF; -OutList['QD_Y'] = False # (rad/s); Velocity of platform yaw rotation DOF; -OutList['QD2_B1E1'] = False # (m/s^2); Acceleration of 1st edgewise bending-mode DOF of blade 1; -OutList['QD2_B2E1'] = False # (m/s^2); Acceleration of 1st edgewise bending-mode DOF of blade 2; -OutList['QD2_B3E1'] = False # (m/s^2); Acceleration of 1st edgewise bending-mode DOF of blade 3; -OutList['QD2_B1F1'] = False # (m/s^2); Acceleration of 1st flapwise bending-mode DOF of blade 1; -OutList['QD2_B2F1'] = False # (m/s^2); Acceleration of 1st flapwise bending-mode DOF of blade 2; -OutList['QD2_B3F1'] = False # (m/s^2); Acceleration of 1st flapwise bending-mode DOF of blade 3; -OutList['QD2_B1F2'] = False # (m/s^2); Acceleration of 2nd flapwise bending-mode DOF of blade 1; -OutList['QD2_B2F2'] = False # (m/s^2); Acceleration of 2nd flapwise bending-mode DOF of blade 2; -OutList['QD2_B3F2'] = False # (m/s^2); Acceleration of 2nd flapwise bending-mode DOF of blade 3; -OutList['QD2_Teet'] = False # (rad/s^2); Acceleration of hub teetering DOF; -OutList['QD2_DrTr'] = False # (rad/s^2); Acceleration of drivetrain rotational-flexibility DOF; -OutList['QD2_GeAz'] = False # (rad/s^2); Acceleration of variable speed generator DOF; -OutList['QD2_RFrl'] = False # (rad/s^2); Acceleration of rotor-furl DOF; -OutList['QD2_TFrl'] = False # (rad/s^2); Acceleration of tail-furl DOF; -OutList['QD2_Yaw'] = False # (rad/s^2); Acceleration of nacelle yaw DOF; -OutList['QD2_TFA1'] = False # (m/s^2); Acceleration of 1st tower fore-aft bending mode DOF; -OutList['QD2_TSS1'] = False # (m/s^2); Acceleration of 1st tower side-to-side bending mode DOF; -OutList['QD2_TFA2'] = False # (m/s^2); Acceleration of 2nd tower fore-aft bending mode DOF; -OutList['QD2_TSS2'] = False # (m/s^2); Acceleration of 2nd tower side-to-side bending mode DOF; -OutList['QD2_Sg'] = False # (m/s^2); Acceleration of platform horizontal surge translation DOF; -OutList['QD2_Sw'] = False # (m/s^2); Acceleration of platform horizontal sway translation DOF; -OutList['QD2_Hv'] = False # (m/s^2); Acceleration of platform vertical heave translation DOF; -OutList['QD2_R'] = False # (rad/s^2); Acceleration of platform roll tilt rotation DOF; -OutList['QD2_P'] = False # (rad/s^2); Acceleration of platform pitch tilt rotation DOF; -OutList['QD2_Y'] = False # (rad/s^2); Acceleration of platform yaw rotation DOF; - - -""" Final Output Dictionary """ -Fst7Output = {} -Fst7Output['OutList'] = OutList +FstOutput['BeamDyn_Nodes'] = BeamDyn_Nodes +FstOutput['ElastoDyn_Nodes'] = ElastoDyn_Nodes diff --git a/openfast_python/openfast_io/FAST_writer.py b/openfast_python/openfast_io/FAST_writer.py index 928aa68eb..97ade59eb 100644 --- a/openfast_python/openfast_io/FAST_writer.py +++ b/openfast_python/openfast_io/FAST_writer.py @@ -151,7 +151,10 @@ def execute(self): if not os.path.exists(self.FAST_runDirectory): os.makedirs(self.FAST_runDirectory) - self.write_ElastoDynBlade() + # If elastodyn blade is being used OR if the blade file exists + if self.fst_vt['Fst']['CompElast'] == 1 or os.path.isfile(self.fst_vt['ElastoDyn']['BldFile1']): + self.write_ElastoDynBlade() + self.write_ElastoDynTower() self.write_ElastoDyn() # self.write_WindWnd() @@ -176,12 +179,16 @@ def execute(self): if self.fst_vt['Fst']['CompHydro'] == 1: self.write_HydroDyn() + if self.fst_vt['Fst']['CompSeaState'] == 1: + self.write_SeaState() if self.fst_vt['Fst']['CompSub'] == 1: self.write_SubDyn() if self.fst_vt['Fst']['CompMooring'] == 1: self.write_MAP() elif self.fst_vt['Fst']['CompMooring'] == 3: self.write_MoorDyn() + if 'WaterKin' in self.fst_vt['MoorDyn']['options']: + self.write_WaterKin(os.path.join(self.FAST_runDirectory,self.fst_vt['MoorDyn']['WaterKin_file'])) if self.fst_vt['Fst']['CompElast'] == 2: self.write_BeamDyn() @@ -215,6 +222,7 @@ def write_MainInput(self): f.write('{:<22} {:<11} {:}'.format(self.fst_vt['Fst']['CompInflow'], 'CompInflow', '- Compute inflow wind velocities (switch) {0=still air; 1=InflowWind; 2=external from OpenFOAM}\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['Fst']['CompAero'], 'CompAero', '- Compute aerodynamic loads (switch) {0=None; 1=AeroDyn v14; 2=AeroDyn v15}\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['Fst']['CompServo'], 'CompServo', '- Compute control and electrical-drive dynamics (switch) {0=None; 1=ServoDyn}\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['Fst']['CompSeaState'], 'CompSeaState', '- Compute sea state information (switch) {0=None; 1=SeaState}\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['Fst']['CompHydro'], 'CompHydro', '- Compute hydrodynamic loads (switch) {0=None; 1=HydroDyn}\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['Fst']['CompSub'], 'CompSub', '- Compute sub-structural dynamics (switch) {0=None; 1=SubDyn; 2=External Platform MCKF}\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['Fst']['CompMooring'], 'CompMooring', '- Compute mooring system (switch) {0=None; 1=MAP++; 2=FEAMooring; 3=MoorDyn; 4=OrcaFlex}\n')) @@ -238,6 +246,7 @@ def write_MainInput(self): f.write('{:<22} {:<11} {:}'.format('"'+self.fst_vt['Fst']['InflowFile']+'"', 'InflowFile', '- Name of file containing inflow wind input parameters (quoted string)\n')) f.write('{:<22} {:<11} {:}'.format('"'+self.fst_vt['Fst']['AeroFile']+'"', 'AeroFile', '- Name of file containing aerodynamic input parameters (quoted string)\n')) f.write('{:<22} {:<11} {:}'.format('"'+self.fst_vt['Fst']['ServoFile']+'"', 'ServoFile', '- Name of file containing control and electrical-drive input parameters (quoted string)\n')) + f.write('{:<22} {:<11} {:}'.format('"'+self.fst_vt['Fst']['SeaState']+'"', 'SeaState', '- Name of file containing sea state input parameters (quoted string)\n')) f.write('{:<22} {:<11} {:}'.format('"'+self.fst_vt['Fst']['HydroFile']+'"', 'HydroFile', '- Name of file containing hydrodynamic input parameters (quoted string)\n')) f.write('{:<22} {:<11} {:}'.format('"'+self.fst_vt['Fst']['SubFile']+'"', 'SubFile', '- Name of file containing sub-structural input parameters (quoted string)\n')) f.write('{:<22} {:<11} {:}'.format('"'+self.fst_vt['Fst']['MooringFile']+'"', 'MooringFile', '- Name of file containing mooring system input parameters (quoted string)\n')) @@ -366,6 +375,9 @@ def write_ElastoDyn(self): f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDyn']['PtfmRIner'], 'PtfmRIner', '- Platform inertia for roll tilt rotation about the platform CM (kg m^2)\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDyn']['PtfmPIner'], 'PtfmPIner', '- Platform inertia for pitch tilt rotation about the platform CM (kg m^2)\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDyn']['PtfmYIner'], 'PtfmYIner', '- Platform inertia for yaw rotation about the platform CM (kg m^2)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDyn']['PtfmXYIner'], 'PtfmXYIner', '- Platform xy moment of inertia about the platform CM (=-int(xydm)) (kg m^2)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDyn']['PtfmYZIner'], 'PtfmYZIner', '- Platform yz moment of inertia about the platform CM (=-int(yzdm)) (kg m^2)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDyn']['PtfmXZIner'], 'PtfmXZIner', '- Platform xz moment of inertia about the platform CM (=-int(xzdm)) (kg m^2)\n')) f.write('---------------------- BLADE ---------------------------------------------------\n') f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDyn']['BldNodes'], 'BldNodes', '- Number of blade nodes (per blade) used for analysis (-)\n')) f.write('{:<22} {:<11} {:}'.format('"'+self.fst_vt['ElastoDyn']['BldFile1']+'"', 'BldFile1', '- Name of file containing properties for blade 1 (quoted string)\n')) @@ -380,6 +392,11 @@ def write_ElastoDyn(self): f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDyn']['TeetHStP'], 'TeetHStP', '- Rotor-teeter hard-stop position (degrees) [used only for 2 blades and when TeetMod=1]\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDyn']['TeetSSSp'], 'TeetSSSp', '- Rotor-teeter soft-stop linear-spring constant (N-m/rad) [used only for 2 blades and when TeetMod=1]\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDyn']['TeetHSSp'], 'TeetHSSp', '- Rotor-teeter hard-stop linear-spring constant (N-m/rad) [used only for 2 blades and when TeetMod=1]\n')) + f.write('---------------------- YAW-FRICTION --------------------------------------------\n') + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDyn']['YawFrctMod'], 'YawFrctMod', 'Yaw-friction model {0: none, 1: friction without Fz term at the yaw bearing, 2: friction includes Fz term at yaw bearing, 3: user defined model} (switch)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDyn']['M_CSmax'], 'M_CSmax', '- Maximum Coulomb friction torque (N-m)[mu_s*D_eff when YawFrctMod=1 and Fz*mu_s*D_eff when YawFrctMod=2]\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDyn']['M_CD'], 'M_CD', '- Dynamic friction moment at null yaw rate (N-m) [mu_d*D_eff when YawFrctMod=1 and Fz*mu_d*D_eff when YawFrctMod=2]\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDyn']['sig_v'], 'sig_v', '- Viscous friction coefficient (N-m/(rad/s))\n')) f.write('---------------------- DRIVETRAIN ----------------------------------------------\n') f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDyn']['GBoxEff'], 'GBoxEff', '- Gearbox efficiency (%)\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDyn']['GBRatio'], 'GBRatio', '- Gearbox ratio (-)\n')) @@ -782,11 +799,9 @@ def write_AeroDyn15(self): f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['Echo'], 'Echo', '- Echo the input to ".AD.ech"? (flag)\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['DTAero'], 'DTAero', '- Time interval for aerodynamic calculations {or "default"} (s)\n')) f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['WakeMod'], 'WakeMod', '- Type of wake/induction model (switch) {0=none, 1=BEMT, 2=DBEMT, 3=OLAF} [WakeMod cannot be 2 or 3 when linearizing]\n')) - f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['AFAeroMod'], 'AFAeroMod', '- Type of blade airfoil aerodynamics model (switch) {1=steady model, 2=Beddoes-Leishman unsteady model} [AFAeroMod must be 1 when linearizing]\n')) f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['TwrPotent'], '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}\n')) f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['TwrShadow'], 'TwrShadow', '- Calculate tower influence on wind based on downstream tower shadow (switch) {0=none, 1=Powles model, 2=Eames model}\n')) f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['TwrAero'], 'TwrAero', '- Calculate tower aerodynamic loads? (flag)\n')) - f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['FrozenWake'], 'FrozenWake', '- Assume frozen wake during linearization? (flag) [used only when WakeMod=1 and when linearizing]\n')) f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['CavitCheck'], 'CavitCheck', '- Perform cavitation check? (flag) [AFAeroMod must be 1 when CavitCheck=true]\n')) f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['Buoyancy'], 'Buoyancy', '- Include buoyancy effects? (flag)\n')) f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['CompAA'], 'CompAA', '- Flag to compute AeroAcoustics calculation [only used when WakeMod=1 or 2]\n')) @@ -798,8 +813,13 @@ def write_AeroDyn15(self): f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['Patm'], 'Patm', '- Atmospheric pressure (Pa) [used only when CavitCheck=True]\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['Pvap'], 'Pvap', '- Vapour pressure of fluid (Pa) [used only when CavitCheck=True]\n')) f.write('====== Blade-Element/Momentum Theory Options ====================================================== [unused when WakeMod=0 or 3]\n') + f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['WakeMod'], 'BEM_Mod', '- BEM model {1=legacy NoSweepPitchTwist, 2=polar} (switch) [used for all Wake_Mod to determine output coordinate system]\n')) + f.write('--- Skew correction\n') f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['SkewMod'], 'SkewMod', '- Type of skewed-wake correction model (switch) {1=uncoupled, 2=Pitt/Peters, 3=coupled} [unused when WakeMod=0 or 3]\n')) - f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['SkewModFactor'], '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]\n')) + f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['SkewMomCorr'], 'SkewMomCorr', '- Turn the skew momentum correction on or off [used only when Skew_Mod=1]\n')) + f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['SkewRedistr_Mod'], 'SkewRedistr_Mod', '- Type of skewed-wake correction model (switch) {0=no redistribution, 1=Glauert/Pitt/Peters, default=1} [used only when Skew_Mod=1]\n')) + f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['SkewRedistrFactor'], 'SkewRedistrFactor', '- Constant used in Pitt/Peters skewed wake model {or "default" is 15/32*pi} (-) [used only when Skew_Mod=1 and SkewRedistr_Mod=1]\n')) + f.write('--- BEM algorithm\n') f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['TipLoss'], 'TipLoss', '- Use the Prandtl tip-loss model? (flag) [unused when WakeMod=0 or 3]\n')) f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['HubLoss'], 'HubLoss', '- Use the Prandtl hub-loss model? (flag) [unused when WakeMod=0 or 3]\n')) f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['TanInd'], 'TanInd', '- Include tangential induction in BEMT calculations? (flag) [unused when WakeMod=0 or 3]\n')) @@ -807,6 +827,13 @@ def write_AeroDyn15(self): f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['TIDrag'], 'TIDrag', '- Include the drag term in the tangential-induction calculation? (flag) [unused when WakeMod=0,3 or TanInd=FALSE]\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['IndToler'], 'IndToler', '- Convergence tolerance for BEMT nonlinear solve residual equation {or "default"} (-) [unused when WakeMod=0 or 3]\n')) f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['MaxIter'], 'MaxIter', '- Maximum number of iteration steps (-) [unused when WakeMod=0]\n')) + f.write('--- BEM algorithm\n') + f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['SectAvg'], 'SectAvg', '- Use sector averaging (flag)\n')) + f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['SectAvgWeighting'], 'SectAvgWeighting', '- Weighting function for sector average {1=Uniform, default=1} within a sector centered on the blade (switch) [used only when SectAvg=True]\n')) + f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['SectAvgNPoints'], 'SectAvgNPoints', '- Number of points per sectors (-) {default=5} [used only when SectAvg=True]\n')) + f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['SectAvgPsiBwd'], 'SectAvgPsiBwd', '- Backward azimuth relative to blade where the sector starts (<=0) {default=-60} (deg) [used only when SectAvg=True]\n')) + f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['SectAvgPsiFwd'], 'SectAvgPsiFwd', '- Forward azimuth relative to blade where the sector ends (>=0) {default=60} (deg) [used only when SectAvg=True]\n')) + f.write('====== Dynamic Blade-Element/Momentum Theory Options ====================================================== [used only when WakeMod=2]\n') f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['DBEMT_Mod'], 'DBEMT_Mod', '- Type of dynamic BEMT (DBEMT) model {1=constant tau1, 2=time-dependent tau1, 3=constant tau1 with continuous formulation} (-) [used only when WakeMod=2]\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['tau1_const'], 'tau1_const', '- Time constant for DBEMT (s) [used only when WakeMod=2 and DBEMT_Mod=1]\n')) @@ -814,8 +841,12 @@ def write_AeroDyn15(self): olaf_file = self.FAST_namingOut + '_OLAF.dat' f.write('{!s:<22} {:<11} {:}'.format(olaf_file, 'OLAFInputFileName', '- Input file for OLAF [used only when WakeMod=3]\n')) f.write('====== Beddoes-Leishman Unsteady Airfoil Aerodynamics Options ===================================== [used only when AFAeroMod=2]\n') + f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['AoA34'], 'AoA34', "- Sample the angle of attack (AoA) at the 3/4 chord or the AC point {default=True} [always used]\n")) f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['UAMod'], 'UAMod', "- Unsteady Aero Model Switch (switch) {1=Baseline model (Original), 2=Gonzalez's variant (changes in Cn,Cc,Cm), 3=Minnema/Pierce variant (changes in Cc and Cm)} [used only when AFAeroMod=2]\n")) f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['FLookup'], '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]\n")) + if 'UAStartRad' in self.fst_vt['AeroDyn15'] and 'UAEndRad' in self.fst_vt['AeroDyn15']: + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['UAStartRad'], 'UAStartRad', '- Starting radius for dynamic stall (fraction of rotor radius) [used only when AFAeroMod=2]\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['UAEndRad'], 'UAEndRad', '- Ending radius for dynamic stall (fraction of rotor radius) [used only when AFAeroMod=2]\n')) f.write('====== Airfoil Information =========================================================================\n') f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['AFTabMod'], '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} (-)\n')) f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['InCol_Alfa'], 'InCol_Alfa', '- The column in the airfoil tables that contains the angle of attack (-)\n')) @@ -1410,7 +1441,7 @@ def write_ServoDyn(self): f.close() def write_DISCON_in(self): - # Generate Bladed style Interface controller input file, intended for ROSCO https://github.com/NREL/rosco.toolbox + # Generate Bladed style Interface controller input file, intended for ROSCO https://github.com/NREL/ROSCO_toolbox # Fill controller and turbine objects for ROSCO # - controller @@ -1460,78 +1491,25 @@ def write_HydroDyn(self): f.write('------- HydroDyn v2.03.* Input File --------------------------------------------\n') f.write('Generated with OpenFAST_IO\n') f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['HydroDyn']['Echo'], 'Echo', '- Echo the input file data (flag)\n')) - f.write('---------------------- ENVIRONMENTAL CONDITIONS --------------------------------\n') - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['HydroDyn']['WtrDens'], 'WtrDens', '- Water density (kg/m^3)\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['HydroDyn']['WtrDpth'], 'WtrDpth', '- Water depth (meters)\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['HydroDyn']['MSL2SWL'], 'MSL2SWL', '- Offset between still-water level and mean sea level (meters) [positive upward; unused when WaveMod = 6; must be zero if PotMod=1 or 2]\n')) - f.write('---------------------- WAVES ---------------------------------------------------\n') - f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['HydroDyn']['WaveMod'], 'WaveMod', '- Incident wave kinematics model {0: none=still water, 1: regular (periodic), 1P#: regular with user-specified phase, 2: JONSWAP/Pierson-Moskowitz spectrum (irregular), 3: White noise spectrum (irregular), 4: user-defined spectrum from routine UserWaveSpctrm (irregular), 5: Externally generated wave-elevation time series, 6: Externally generated full wave-kinematics time series [option 6 is invalid for PotMod/=0]} (switch)\n')) - f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['HydroDyn']['WaveStMod'], 'WaveStMod', '- Model for stretching incident wave kinematics to instantaneous free surface {0: none=no stretching, 1: vertical stretching, 2: extrapolation stretching, 3: Wheeler stretching} (switch) [unused when WaveMod=0 or when PotMod/=0]\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['HydroDyn']['WaveTMax'], 'WaveTMax', '- Analysis time for incident wave calculations (sec) [unused when WaveMod=0; determines WaveDOmega=2Pi/WaveTMax in the IFFT]\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['HydroDyn']['WaveDT'], 'WaveDT', '- Time step for incident wave calculations (sec) [unused when WaveMod=0; 0.1<=WaveDT<=1.0 recommended; determines WaveOmegaMax=Pi/WaveDT in the IFFT]\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['HydroDyn']['WaveHs'], 'WaveHs', '- Significant wave height of incident waves (meters) [used only when WaveMod=1, 2, or 3]\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['HydroDyn']['WaveTp'], 'WaveTp', '- Peak-spectral period of incident waves (sec) [used only when WaveMod=1 or 2]\n')) - if isinstance(self.fst_vt['HydroDyn']['WavePkShp'], float): - if self.fst_vt['HydroDyn']['WavePkShp'] == 0.: - WavePkShp = 'Default' - else: - WavePkShp = self.fst_vt['HydroDyn']['WavePkShp'] - else: - WavePkShp = self.fst_vt['HydroDyn']['WavePkShp'] - f.write('{:<22} {:<11} {:}'.format(WavePkShp, 'WavePkShp', '- Peak-shape parameter of incident wave spectrum (-) or DEFAULT (string) [used only when WaveMod=2; use 1.0 for Pierson-Moskowitz]\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['HydroDyn']['WvLowCOff'], 'WvLowCOff', '- Low cut-off frequency or lower frequency limit of the wave spectrum beyond which the wave spectrum is zeroed (rad/s) [unused when WaveMod=0, 1, or 6]\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['HydroDyn']['WvHiCOff'], 'WvHiCOff', '- High cut-off frequency or upper frequency limit of the wave spectrum beyond which the wave spectrum is zeroed (rad/s) [unused when WaveMod=0, 1, or 6]\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['HydroDyn']['WaveDir'], 'WaveDir', '- Incident wave propagation heading direction (degrees) [unused when WaveMod=0 or 6]\n')) - f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['HydroDyn']['WaveDirMod'], 'WaveDirMod', '- Directional spreading function {0: none, 1: COS2S} (-) [only used when WaveMod=2,3, or 4]\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['HydroDyn']['WaveDirSpread'], 'WaveDirSpread', '- Wave direction spreading coefficient ( > 0 ) (-) [only used when WaveMod=2,3, or 4 and WaveDirMod=1]\n')) - f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['HydroDyn']['WaveNDir'], 'WaveNDir', '- Number of wave directions (-) [only used when WaveMod=2,3, or 4 and WaveDirMod=1; odd number only]\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['HydroDyn']['WaveDirRange'], 'WaveDirRange', '- Range of wave directions (full range: WaveDir +/- 1/2*WaveDirRange) (degrees) [only used when WaveMod=2,3,or 4 and WaveDirMod=1]\n')) - f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['HydroDyn']['WaveSeed1'], 'WaveSeed(1)', '- First random seed of incident waves [-2147483648 to 2147483647] (-) [unused when WaveMod=0, 5, or 6]\n')) - - try: - seed2 = int(self.fst_vt['HydroDyn']['WaveSeed2']) - f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['HydroDyn']['WaveSeed2'], 'WaveSeed(2)', '- Second random seed of incident waves [-2147483648 to 2147483647] (-) [unused when WaveMod=0, 5, or 6]\n')) - except ValueError: - f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['HydroDyn']['WaveSeed2'], 'WaveSeed(2)', '- Second random seed of incident waves [-2147483648 to 2147483647] (-) [unused when WaveMod=0, 5, or 6] for intrinsic pRNG, or an alternative pRNG: "RanLux"\n')) - - f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['HydroDyn']['WaveNDAmp'], 'WaveNDAmp', '- Flag for normally distributed amplitudes (flag) [only used when WaveMod=2, 3, or 4]\n')) - f.write('{:<22} {:<11} {:}'.format('"'+self.fst_vt['HydroDyn']['WvKinFile']+'"', 'WvKinFile', '- Root name of externally generated wave data file(s) (quoted string) [used only when WaveMod=5 or 6]\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['HydroDyn']['NWaveElev'], 'NWaveElev', '- Number of points where the incident wave elevations can be computed (-) [maximum of 9 output locations]\n')) - f.write('{:<22} {:<11} {:}'.format(", ".join(self.fst_vt['HydroDyn']['WaveElevxi']), 'WaveElevxi', '- List of xi-coordinates for points where the incident wave elevations can be output (meters) [NWaveElev points, separated by commas or white space; usused if NWaveElev = 0]\n')) - f.write('{:<22} {:<11} {:}'.format(", ".join(self.fst_vt['HydroDyn']['WaveElevyi']), 'WaveElevyi', '- List of yi-coordinates for points where the incident wave elevations can be output (meters) [NWaveElev points, separated by commas or white space; usused if NWaveElev = 0]\n')) - f.write('---------------------- 2ND-ORDER WAVES ----------------------------------------- [unused with WaveMod=0 or 6]\n') - f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['HydroDyn']['WvDiffQTF'], 'WvDiffQTF', '- Full difference-frequency 2nd-order wave kinematics (flag)\n')) - f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['HydroDyn']['WvSumQTF'], 'WvSumQTF', '- Full summation-frequency 2nd-order wave kinematics (flag)\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['HydroDyn']['WvLowCOffD'], 'WvLowCOffD', '- Low frequency cutoff used in the difference-frequencies (rad/s) [Only used with a difference-frequency method]\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['HydroDyn']['WvHiCOffD'], 'WvHiCOffD', '- High frequency cutoff used in the difference-frequencies (rad/s) [Only used with a difference-frequency method]\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['HydroDyn']['WvLowCOffS'], 'WvLowCOffS', '- Low frequency cutoff used in the summation-frequencies (rad/s) [Only used with a summation-frequency method]\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['HydroDyn']['WvHiCOffS'], 'WvHiCOffS', '- High frequency cutoff used in the summation-frequencies (rad/s) [Only used with a summation-frequency method]\n')) - f.write('---------------------- CURRENT ------------------------------------------------- [unused with WaveMod=6]\n') - f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['HydroDyn']['CurrMod'], 'CurrMod', '- Current profile model {0: none=no current, 1: standard, 2: user-defined from routine UserCurrent} (switch)\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['HydroDyn']['CurrSSV0'], 'CurrSSV0', '- Sub-surface current velocity at still water level (m/s) [used only when CurrMod=1]\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['HydroDyn']['CurrSSDir'], 'CurrSSDir', '- Sub-surface current heading direction (degrees) or DEFAULT (string) [used only when CurrMod=1]\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['HydroDyn']['CurrNSRef'], 'CurrNSRef', '- Near-surface current reference depth (meters) [used only when CurrMod=1]\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['HydroDyn']['CurrNSV0'], 'CurrNSV0', '- Near-surface current velocity at still water level (m/s) [used only when CurrMod=1]\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['HydroDyn']['CurrNSDir'], 'CurrNSDir', '- Near-surface current heading direction (degrees) [used only when CurrMod=1]\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['HydroDyn']['CurrDIV'], 'CurrDIV', '- Depth-independent current velocity (m/s) [used only when CurrMod=1]\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['HydroDyn']['CurrDIDir'], 'CurrDIDir', '- Depth-independent current heading direction (degrees) [used only when CurrMod=1]\n')) f.write('---------------------- FLOATING PLATFORM --------------------------------------- [unused with WaveMod=6]\n') f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['HydroDyn']['PotMod'], 'PotMod', '- Potential-flow model {0: none=no potential flow, 1: frequency-to-time-domain transforms based on WAMIT output, 2: fluid-impulse theory (FIT)} (switch)\n')) f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['HydroDyn']['ExctnMod'], 'ExctnMod', '- Wave Excitation model {0: None, 1: DFT, 2: state-space} (switch) [only used when PotMod=1; STATE-SPACE REQUIRES *.ssexctn INPUT FILE]\n')) + f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['HydroDyn']['ExctnDisp'], 'ExctnDisp','- Method of computing Wave Excitation {0: use undisplaced position, 1: use displaced position, 2: use low-pass filtered displaced position) [only used when PotMod=1 and ExctnMod>0 and SeaState\'s WaveMod>0]} (switch)\n')) + f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['HydroDyn']['ExctnCutOff'], 'ExctnCutOff','- Method of computing Wave Excitation {0: use undisplaced position, 1: use displaced position, 2: use low-pass filtered displaced position) [only used when PotMod=1 and ExctnMod>0 and SeaState\'s WaveMod>0]} (switch)\n')) f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['HydroDyn']['RdtnMod'], 'RdtnMod', '- Radiation memory-effect model {0: no memory-effect calculation, 1: convolution, 2: state-space} (switch) [only used when PotMod=1; STATE-SPACE REQUIRES *.ss INPUT FILE]\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['HydroDyn']['RdtnTMax'], 'RdtnTMax', '- Analysis time for wave radiation kernel calculations (sec) [only used when PotMod=1; determines RdtnDOmega=Pi/RdtnTMax in the cosine transform; MAKE SURE THIS IS LONG ENOUGH FOR THE RADIATION IMPULSE RESPONSE FUNCTIONS TO DECAY TO NEAR-ZERO FOR THE GIVEN PLATFORM!]\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['HydroDyn']['RdtnDT'], 'RdtnDT', '- Time step for wave radiation kernel calculations (sec) [only used when PotMod=1; DT<=RdtnDT<=0.1 recommended; determines RdtnOmegaMax=Pi/RdtnDT in the cosine transform]\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['HydroDyn']['NBody'], 'NBody', '- Number of WAMIT bodies to be used (-) [>=1; only used when PotMod=1. If NBodyMod=1, the WAMIT data contains a vector of size 6*NBody x 1 and matrices of size 6*NBody x 6*NBody; if NBodyMod>1, there are NBody sets of WAMIT data each with a vector of size 6 x 1 and matrices of size 6 x 6]\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['HydroDyn']['NBodyMod'], 'NBodyMod', '- Body coupling model {1: include coupling terms between each body and NBody in HydroDyn equals NBODY in WAMIT, 2: neglect coupling terms between each body and NBODY=1 with XBODY=0 in WAMIT, 3: Neglect coupling terms between each body and NBODY=1 with XBODY=/0 in WAMIT} (switch) [only used when PotMod=1]\n')) - f.write('{:<22} {:<11} {:}'.format('"'+self.fst_vt['HydroDyn']['PotFile']+'"', 'PotFile', '- Root name of potential-flow model data; WAMIT output files containing the linear, nondimensionalized, hydrostatic restoring matrix (.hst), frequency-dependent hydrodynamic added mass matrix and damping matrix (.1), and frequency- and direction-dependent wave excitation force vector per unit wave amplitude (.3) (quoted string) [MAKE SURE THE FREQUENCIES INHERENT IN THESE WAMIT FILES SPAN THE PHYSICALLY-SIGNIFICANT RANGE OF FREQUENCIES FOR THE GIVEN PLATFORM; THEY MUST CONTAIN THE ZERO- AND INFINITE-FREQUENCY LIMITS!]\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['HydroDyn']['WAMITULEN'], 'WAMITULEN', '- Characteristic body length scale used to redimensionalize WAMIT output (meters) [only used when PotMod=1]\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['HydroDyn']['PtfmRefxt'], 'PtfmRefxt', '- The xt offset of the body reference point(s) from (0,0,0) (meters) [1 to NBody] [only used when PotMod=1]\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['HydroDyn']['PtfmRefyt'], 'PtfmRefyt', '- The yt offset of the body reference point(s) from (0,0,0) (meters) [1 to NBody] [only used when PotMod=1]\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['HydroDyn']['PtfmRefzt'], 'PtfmRefzt', '- The zt offset of the body reference point(s) from (0,0,0) (meters) [1 to NBody] [only used when PotMod=1. If NBodyMod=2,PtfmRefzt=0.0]\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['HydroDyn']['PtfmRefztRot'], 'PtfmRefztRot', '- The rotation about zt of the body reference frame(s) from xt/yt (degrees) [1 to NBody] [only used when PotMod=1]\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['HydroDyn']['PtfmVol0'], 'PtfmVol0', '- Displaced volume of water when the platform is in its undisplaced position (m^3) [only used when PotMod=1; USE THE SAME VALUE COMPUTED BY WAMIT AS OUTPUT IN THE .OUT FILE!]\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['HydroDyn']['PtfmCOBxt'], 'PtfmCOBxt', '- The xt offset of the center of buoyancy (COB) from the platform reference point (meters) [only used when PotMod=1]\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['HydroDyn']['PtfmCOByt'], 'PtfmCOByt', '- The yt offset of the center of buoyancy (COB) from the platform reference point (meters) [only used when PotMod=1]\n')) + f.write('{:<22} {:<11} {:}'.format(', '.join([f'"{pf}"' for pf in self.fst_vt['HydroDyn']['PotFile']]), 'PotFile', '- Root name of potential-flow model data; WAMIT output files containing the linear, nondimensionalized, hydrostatic restoring matrix (.hst), frequency-dependent hydrodynamic added mass matrix and damping matrix (.1), and frequency- and direction-dependent wave excitation force vector per unit wave amplitude (.3) (quoted string) [MAKE SURE THE FREQUENCIES INHERENT IN THESE WAMIT FILES SPAN THE PHYSICALLY-SIGNIFICANT RANGE OF FREQUENCIES FOR THE GIVEN PLATFORM; THEY MUST CONTAIN THE ZERO- AND INFINITE-FREQUENCY LIMITS!]\n')) + f.write('{:<22} {:<11} {:}'.format(', '.join([f'{val}' for val in self.fst_vt['HydroDyn']['WAMITULEN']]), 'WAMITULEN', '- Characteristic body length scale used to redimensionalize WAMIT output (meters) [only used when PotMod=1]\n')) + f.write('{:<22} {:<11} {:}'.format(', '.join([f'{val}' for val in self.fst_vt['HydroDyn']['PtfmRefxt']]), 'PtfmRefxt', '- The xt offset of the body reference point(s) from (0,0,0) (meters) [1 to NBody] [only used when PotMod=1]\n')) + f.write('{:<22} {:<11} {:}'.format(', '.join([f'{val}' for val in self.fst_vt['HydroDyn']['PtfmRefyt']]), 'PtfmRefyt', '- The yt offset of the body reference point(s) from (0,0,0) (meters) [1 to NBody] [only used when PotMod=1]\n')) + f.write('{:<22} {:<11} {:}'.format(', '.join([f'{val}' for val in self.fst_vt['HydroDyn']['PtfmRefzt']]), 'PtfmRefzt', '- The zt offset of the body reference point(s) from (0,0,0) (meters) [1 to NBody] [only used when PotMod=1. If NBodyMod=2,PtfmRefzt=0.0]\n')) + f.write('{:<22} {:<11} {:}'.format(', '.join([f'{val}' for val in self.fst_vt['HydroDyn']['PtfmRefztRot']]), 'PtfmRefztRot', '- The rotation about zt of the body reference frame(s) from xt/yt (degrees) [1 to NBody] [only used when PotMod=1]\n')) + f.write('{:<22} {:<11} {:}'.format(', '.join([f'{val}' for val in self.fst_vt['HydroDyn']['PtfmVol0']]), 'PtfmVol0', '- Displaced volume of water when the platform is in its undisplaced position (m^3) [only used when PotMod=1; USE THE SAME VALUE COMPUTED BY WAMIT AS OUTPUT IN THE .OUT FILE!]\n')) + f.write('{:<22} {:<11} {:}'.format(', '.join([f'{val}' for val in self.fst_vt['HydroDyn']['PtfmCOBxt']]), 'PtfmCOBxt', '- The xt offset of the center of buoyancy (COB) from the platform reference point (meters) [only used when PotMod=1]\n')) + f.write('{:<22} {:<11} {:}'.format(', '.join([f'{val}' for val in self.fst_vt['HydroDyn']['PtfmCOByt']]), 'PtfmCOByt', '- The yt offset of the center of buoyancy (COB) from the platform reference point (meters) [only used when PotMod=1]\n')) f.write('---------------------- 2ND-ORDER FLOATING PLATFORM FORCES ---------------------- [unused with WaveMod=0 or 6, or PotMod=0 or 2]\n') f.write('{:<22} {:<11} {:}'.format(self.fst_vt['HydroDyn']['MnDrift'], 'MnDrift', "- Mean-drift 2nd-order forces computed {0: None; [7, 8, 9, 10, 11, or 12]: WAMIT file to use} [Only one of MnDrift, NewmanApp, or DiffQTF can be non-zero]\n")) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['HydroDyn']['NewmanApp'], 'NewmanApp', "- Mean- and slow-drift 2nd-order forces computed with Newman's approximation {0: None; [7, 8, 9, 10, 11, or 12]: WAMIT file to use} [Only one of MnDrift, NewmanApp, or DiffQTF can be non-zero. Used only when WaveDirMod=0]\n")) @@ -1581,16 +1559,24 @@ def write_HydroDyn(self): else: ln = ln + "\n" f.write(ln) + + f.write('---------------------- STRIP THEORY OPTIONS --------------------------------------\n') + f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['HydroDyn']['WaveDisp'], 'WaveDisp', '- Method of computing Wave Kinematics {0- use undisplaced position, 1- use displaced position) } (switch)\n')) + f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['HydroDyn']['AMMod'], 'AMMod', '\n')) + f.write('---------------------- AXIAL COEFFICIENTS --------------------------------------\n') f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['HydroDyn']['NAxCoef'], 'NAxCoef', '- Number of axial coefficients (-)\n')) - f.write(" ".join(['{:^11s}'.format(i) for i in ['AxCoefID', 'AxCd', 'AxCa', 'AxCp']])+'\n') - f.write(" ".join(['{:^11s}'.format(i) for i in ['(-)']*4])+'\n') + f.write(" ".join(['{:^11s}'.format(i) for i in ['AxCoefID', 'AxCd', 'AxCa', 'AxCp', 'AxFDMod', 'AxVnCOff', 'AxFDLoFSc']])+'\n') + f.write(" ".join(['{:^11s}'.format(i) for i in ['(-)']*7])+'\n') for i in range(self.fst_vt['HydroDyn']['NAxCoef']): ln = [] ln.append('{:^11d}'.format(self.fst_vt['HydroDyn']['AxCoefID'][i])) ln.append('{:^11}'.format(self.fst_vt['HydroDyn']['AxCd'][i])) ln.append('{:^11}'.format(self.fst_vt['HydroDyn']['AxCa'][i])) ln.append('{:^11}'.format(self.fst_vt['HydroDyn']['AxCp'][i])) + ln.append('{:^11}'.format(self.fst_vt['HydroDyn']['AxFDMod'][i])) + ln.append('{:^11}'.format(self.fst_vt['HydroDyn']['AxVnCOff'][i])) + ln.append('{:^11}'.format(self.fst_vt['HydroDyn']['AxFDLoFSc'][i])) f.write(" ".join(ln) + '\n') f.write('---------------------- MEMBER JOINTS -------------------------------------------\n') f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['HydroDyn']['NJoints'], 'NJoints', '- Number of joints (-) [must be exactly 0 or at least 2]\n')) @@ -1616,7 +1602,7 @@ def write_HydroDyn(self): ln.append('{:^11}'.format(self.fst_vt['HydroDyn']['PropThck'][i])) f.write(" ".join(ln) + '\n') f.write('---------------------- SIMPLE HYDRODYNAMIC COEFFICIENTS (model 1) --------------\n') - f.write(" ".join(['{:^11s}'.format(i) for i in ['SimplCd', 'SimplCdMG', 'SimplCa', 'SimplCaMG', 'SimplCp', 'SimplCpMG', 'SimplAxCd', 'SimplAxCdMG', 'SimplAxCa', 'SimplAxCaMG', 'SimplAxCp', 'SimplAxCpMG']])+'\n') + f.write(" ".join(['{:^11s}'.format(i) for i in ['SimplCd', 'SimplCdMG', 'SimplCa', 'SimplCaMG', 'SimplCp', 'SimplCpMG', 'SimplAxCd', 'SimplAxCdMG', 'SimplAxCa', 'SimplAxCaMG', 'SimplAxCp', 'SimplAxCpMG', 'SimplCb', 'SimplCbMG']])+'\n') f.write(" ".join(['{:^11s}'.format(i) for i in ['(-)']*12])+'\n') ln = [] ln.append('{:^11}'.format(self.fst_vt['HydroDyn']['SimplCd'])) @@ -1631,10 +1617,12 @@ def write_HydroDyn(self): ln.append('{:^11}'.format(self.fst_vt['HydroDyn']['SimplAxCaMG'])) ln.append('{:^11}'.format(self.fst_vt['HydroDyn']['SimplAxCp'])) ln.append('{:^11}'.format(self.fst_vt['HydroDyn']['SimplAxCpMG'])) + ln.append('{:^11}'.format(self.fst_vt['HydroDyn']['SimplCb'])) + ln.append('{:^11}'.format(self.fst_vt['HydroDyn']['SimplCbMG'])) f.write(" ".join(ln) + '\n') f.write('---------------------- DEPTH-BASED HYDRODYNAMIC COEFFICIENTS (model 2) ---------\n') f.write('{:<11d} {:<11} {:}'.format(self.fst_vt['HydroDyn']['NCoefDpth'], 'NCoefDpth', '- Number of depth-dependent coefficients (-)\n')) - f.write(" ".join(['{:^11s}'.format(i) for i in ['Dpth', 'DpthCd', 'DpthCdMG', 'DpthCa', 'DpthCaMG', 'DpthCp', 'DpthCpMG', 'DpthAxCd', 'DpthAxCdMG', 'DpthAxCa', 'DpthAxCaMG', 'DpthAxCp', 'DpthAxCpMG']])+'\n') + f.write(" ".join(['{:^11s}'.format(i) for i in ['Dpth', 'DpthCd', 'DpthCdMG', 'DpthCa', 'DpthCaMG', 'DpthCp', 'DpthCpMG', 'DpthAxCd', 'DpthAxCdMG', 'DpthAxCa', 'DpthAxCaMG', 'DpthAxCp', 'DpthAxCpMG', 'DpthCb', 'DpthCbMG']])+'\n') f.write(" ".join(['{:^11s}'.format(i) for i in ['(m)', '(-)', '(-)', '(-)', '(-)', '(-)', '(-)', '(-)', '(-)', '(-)', '(-)', '(-)', '(-)']])+'\n') for i in range(self.fst_vt['HydroDyn']['NCoefDpth']): ln = [] @@ -1651,11 +1639,14 @@ def write_HydroDyn(self): ln.append('{:^11}'.format(self.fst_vt['HydroDyn']['DpthAxCaMG'][i])) ln.append('{:^11}'.format(self.fst_vt['HydroDyn']['DpthAxCp'][i])) ln.append('{:^11}'.format(self.fst_vt['HydroDyn']['DpthAxCpMG'][i])) + ln.append('{:^11}'.format(self.fst_vt['HydroDyn']['DpthCb'][i])) + ln.append('{:^11}'.format(self.fst_vt['HydroDyn']['DpthCbMG'][i])) f.write(" ".join(ln) + '\n') f.write('---------------------- MEMBER-BASED HYDRODYNAMIC COEFFICIENTS (model 3) --------\n') f.write('{:<11d} {:<11} {:}'.format(self.fst_vt['HydroDyn']['NCoefMembers'], 'NCoefMembers', '- Number of member-based coefficients (-)\n')) - f.write(" ".join(['{:^11s}'.format(i) for i in ['MemberID_HydC', 'MemberCd1', 'MemberCd2', 'MemberCdMG1', 'MemberCdMG2', 'MemberCa1', 'MemberCa2', 'MemberCaMG1', 'MemberCaMG2', 'MemberCp1', 'MemberCp2', 'MemberCpMG1', 'MemberCpMG2', 'MemberAxCd1', 'MemberAxCd2', 'MemberAxCdMG1', 'MemberAxCdMG2', 'MemberAxCa1', 'MemberAxCa2', 'MemberAxCaMG1', 'MemberAxCaMG2', 'MemberAxCp1', 'MemberAxCp2', 'MemberAxCpMG1', 'MemberAxCpMG2']])+'\n') - f.write(" ".join(['{:^11s}'.format(i) for i in ['(-)']*25])+'\n') + mem_coeff_names = ['MemberID_HydC', 'MemberCd1', 'MemberCd2', 'MemberCdMG1', 'MemberCdMG2', 'MemberCa1', 'MemberCa2', 'MemberCaMG1', 'MemberCaMG2', 'MemberCp1', 'MemberCp2', 'MemberCpMG1', 'MemberCpMG2', 'MemberAxCd1', 'MemberAxCd2', 'MemberAxCdMG1', 'MemberAxCdMG2', 'MemberAxCa1', 'MemberAxCa2', 'MemberAxCaMG1', 'MemberAxCaMG2', 'MemberAxCp1', 'MemberAxCp2', 'MemberAxCpMG1', 'MemberAxCpMG2','MemberCb1','MemberCb2','MemberCbMG1','MemberCbMG2'] + f.write(" ".join(['{:^11s}'.format(i) for i in mem_coeff_names])+'\n') + f.write(" ".join(['{:^11s}'.format(i) for i in ['(-)']*len(mem_coeff_names)])+'\n') for i in range(self.fst_vt['HydroDyn']['NCoefMembers']): ln = [] ln.append('{:^11d}'.format(self.fst_vt['HydroDyn']['MemberID_HydC'][i])) @@ -1683,10 +1674,14 @@ def write_HydroDyn(self): ln.append('{:^11}'.format(self.fst_vt['HydroDyn']['MemberAxCp2'][i])) ln.append('{:^11}'.format(self.fst_vt['HydroDyn']['MemberAxCpMG1'][i])) ln.append('{:^11}'.format(self.fst_vt['HydroDyn']['MemberAxCpMG2'][i])) + ln.append('{:^11}'.format(self.fst_vt['HydroDyn']['MemberCb1'][i])) + ln.append('{:^11}'.format(self.fst_vt['HydroDyn']['MemberCb2'][i])) + ln.append('{:^11}'.format(self.fst_vt['HydroDyn']['MemberCbMG1'][i])) + ln.append('{:^11}'.format(self.fst_vt['HydroDyn']['MemberCbMG2'][i])) f.write(" ".join(ln) + '\n') f.write('-------------------- MEMBERS -------------------------------------------------\n') f.write('{:<11d} {:<11} {:}'.format(self.fst_vt['HydroDyn']['NMembers'], 'NMembers', '- Number of members (-)\n')) - f.write(" ".join(['{:^11s}'.format(i) for i in ['MemberID', 'MJointID1', 'MJointID2', 'MPropSetID1', 'MPropSetID2', 'MDivSize', 'MCoefMod', 'PropPot']])+' ! [MCoefMod=1: use simple coeff table, 2: use depth-based coeff table, 3: use member-based coeff table] [ PropPot/=0 if member is modeled with potential-flow theory]\n') + f.write(" ".join(['{:^11s}'.format(i) for i in ['MemberID', 'MJointID1', 'MJointID2', 'MPropSetID1', 'MPropSetID2', 'MDivSize', 'MCoefMod', 'MHstLMod', 'PropPot']])+' ! [MCoefMod=1: use simple coeff table, 2: use depth-based coeff table, 3: use member-based coeff table] [ PropPot/=0 if member is modeled with potential-flow theory]\n') f.write(" ".join(['{:^11s}'.format(i) for i in ['(-)', '(-)', '(-)', '(-)', '(-)', '(m)', '(switch)', '(flag)']])+'\n') for i in range(self.fst_vt['HydroDyn']['NMembers']): ln = [] @@ -1697,6 +1692,7 @@ def write_HydroDyn(self): ln.append('{:^11d}'.format(self.fst_vt['HydroDyn']['MPropSetID2'][i])) ln.append('{:^11}'.format(self.fst_vt['HydroDyn']['MDivSize'][i])) ln.append('{:^11d}'.format(self.fst_vt['HydroDyn']['MCoefMod'][i])) + ln.append('{:^11d}'.format(self.fst_vt['HydroDyn']['MHstLMod'][i])) ln.append('{!s:^11}'.format(self.fst_vt['HydroDyn']['PropPot'][i])) f.write(" ".join(ln) + '\n') f.write("---------------------- FILLED MEMBERS ------------------------------------------\n") @@ -1747,9 +1743,116 @@ def write_HydroDyn(self): f.write('END of output channels and end of file. (the word "END" must appear in the first 3 columns of this line)\n') + f.close() - f.flush() - os.fsync(f) + def write_SeaState(self): + + # Generate HydroDyn v2.03 input file + self.fst_vt['Fst']['SeaState'] = self.FAST_namingOut + '_SeaState.dat' + hd_file = os.path.join(self.FAST_runDirectory, self.fst_vt['Fst']['SeaState']) + f = open(hd_file, 'w') + + f.write('------- SeaState v1.00.* Input File --------------------------------------------\n') + f.write('Generated with OpenFAST_IO\n') + f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['SeaState']['Echo'], 'Echo', '- Echo the input file data (flag)\n')) + + f.write('---------------------- ENVIRONMENTAL CONDITIONS --------------------------------\n') + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['SeaState']['WtrDens'],'WtrDens', '- Water density (kg/m^3)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['SeaState']['WtrDpth'],'WtrDpth', '- Water depth (meters)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['SeaState']['MSL2SWL'],'MSL2SWL', '- Offset between still-water level and mean sea level (meters) [positive upward; unused when WaveMod = 6; must be zero if PotMod=1 or 2]\n')) + + + f.write('---------------------- SPATIAL DISCRETIZATION ---------------------------------------------------\n') + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['SeaState']['X_HalfWidth'], 'X_HalfWidth', '– Half-width of the domain in the X direction (m) [>0, NOTE: X[nX] = nX*dX, where nX = {-NX+1,-NX+2,…,NX-1} and dX = X_HalfWidth/(NX-1)]\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['SeaState']['Y_HalfWidth'], 'Y_HalfWidth', '– Half-width of the domain in the Y direction (m) [>0, NOTE: Y[nY] = nY*dY, where nY = {-NY+1,-NY+2,…,NY-1} and dY = Y_HalfWidth/(NY-1)]\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['SeaState']['Z_Depth'], 'Z_Depth', '– Depth of the domain the Z direction (m) relative to SWL [0 < Z_Depth <= WtrDpth+MSL2SWL; "default": Z_Depth = WtrDpth+MSL2SWL; Z[nZ] = ( COS( nZ*dthetaZ ) – 1 )*Z_Depth, where nZ = {0,1,…NZ-1} and dthetaZ = pi/( 2*(NZ-1) )]\n')) + f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['SeaState']['NX'], 'NX', '– Number of nodes in half of the X-direction domain (-) [>=2]\n')) + f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['SeaState']['NY'], 'NY', '– Number of nodes in half of the Y-direction domain (-) [>=2]\n')) + f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['SeaState']['NZ'], 'NZ', '– Number of nodes in the Z direction (-) [>=2]\n')) + + f.write('---------------------- WAVES ---------------------------------------------------\n') + f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['SeaState']['WaveMod'], 'WaveMod', '- Incident wave kinematics model {0: none=still water, 1: regular (periodic), 1P#: regular with user-specified phase, 2: JONSWAP/Pierson-Moskowitz spectrum (irregular), 3: White noise spectrum (irregular), 4: user-defined spectrum from routine UserWaveSpctrm (irregular), 5: Externally generated wave-elevation time series, 6: Externally generated full wave-kinematics time series [option 6 is invalid for PotMod/=0]} (switch)\n')) + f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['SeaState']['WaveStMod'], 'WaveStMod', '- Model for stretching incident wave kinematics to instantaneous free surface {0: none=no stretching, 1: vertical stretching, 2: extrapolation stretching, 3: Wheeler stretching} (switch) [unused when WaveMod=0 or when PotMod/=0]\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['SeaState']['WaveTMax'], 'WaveTMax', '- Analysis time for incident wave calculations (sec) [unused when WaveMod=0; determines WaveDOmega=2Pi/WaveTMax in the IFFT]\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['SeaState']['WaveDT'], 'WaveDT', '- Time step for incident wave calculations (sec) [unused when WaveMod=0; 0.1<=WaveDT<=1.0 recommended; determines WaveOmegaMax=Pi/WaveDT in the IFFT]\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['SeaState']['WaveHs'], 'WaveHs', '- Significant wave height of incident waves (meters) [used only when WaveMod=1, 2, or 3]\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['SeaState']['WaveTp'], 'WaveTp', '- Peak-spectral period of incident waves (sec) [used only when WaveMod=1 or 2]\n')) + if isinstance(self.fst_vt['SeaState']['WavePkShp'], float): + if self.fst_vt['SeaState']['WavePkShp'] == 0.: + WavePkShp = 'Default' + else: + WavePkShp = self.fst_vt['SeaState']['WavePkShp'] + else: + WavePkShp = self.fst_vt['SeaState']['WavePkShp'] + f.write('{:<22} {:<11} {:}'.format(WavePkShp, 'WavePkShp', '- Peak-shape parameter of incident wave spectrum (-) or DEFAULT (string) [used only when WaveMod=2; use 1.0 for Pierson-Moskowitz]\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['SeaState']['WvLowCOff'], 'WvLowCOff', '- Low cut-off frequency or lower frequency limit of the wave spectrum beyond which the wave spectrum is zeroed (rad/s) [unused when WaveMod=0, 1, or 6]\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['SeaState']['WvHiCOff'], 'WvHiCOff', '- High cut-off frequency or upper frequency limit of the wave spectrum beyond which the wave spectrum is zeroed (rad/s) [unused when WaveMod=0, 1, or 6]\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['SeaState']['WaveDir'], 'WaveDir', '- Incident wave propagation heading direction (degrees) [unused when WaveMod=0 or 6]\n')) + f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['SeaState']['WaveDirMod'], 'WaveDirMod', '- Directional spreading function {0: none, 1: COS2S} (-) [only used when WaveMod=2,3, or 4]\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['SeaState']['WaveDirSpread'], 'WaveDirSpread', '- Wave direction spreading coefficient ( > 0 ) (-) [only used when WaveMod=2,3, or 4 and WaveDirMod=1]\n')) + f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['SeaState']['WaveNDir'], 'WaveNDir', '- Number of wave directions (-) [only used when WaveMod=2,3, or 4 and WaveDirMod=1; odd number only]\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['SeaState']['WaveDirRange'], 'WaveDirRange', '- Range of wave directions (full range: WaveDir +/- 1/2*WaveDirRange) (degrees) [only used when WaveMod=2,3,or 4 and WaveDirMod=1]\n')) + f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['SeaState']['WaveSeed1'], 'WaveSeed(1)', '- First random seed of incident waves [-2147483648 to 2147483647] (-) [unused when WaveMod=0, 5, or 6]\n')) + + try: + seed2 = int(self.fst_vt['SeaState']['WaveSeed2']) + f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['SeaState']['WaveSeed2'], 'WaveSeed(2)', '- Second random seed of incident waves [-2147483648 to 2147483647] (-) [unused when WaveMod=0, 5, or 6]\n')) + except ValueError: + f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['SeaState']['WaveSeed2'], 'WaveSeed(2)', '- Second random seed of incident waves [-2147483648 to 2147483647] (-) [unused when WaveMod=0, 5, or 6] for intrinsic pRNG, or an alternative pRNG: "RanLux"\n')) + + f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['SeaState']['WaveNDAmp'], 'WaveNDAmp', '- Flag for normally distributed amplitudes (flag) [only used when WaveMod=2, 3, or 4]\n')) + f.write('{:<22} {:<11} {:}'.format('"'+self.fst_vt['SeaState']['WvKinFile']+'"', 'WvKinFile', '- Root name of externally generated wave data file(s) (quoted string) [used only when WaveMod=5 or 6]\n')) + f.write('---------------------- 2ND-ORDER WAVES ----------------------------------------- [unused with WaveMod=0 or 6]\n') + f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['SeaState']['WvDiffQTF'], 'WvDiffQTF', '- Full difference-frequency 2nd-order wave kinematics (flag)\n')) + f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['SeaState']['WvSumQTF'], 'WvSumQTF', '- Full summation-frequency 2nd-order wave kinematics (flag)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['SeaState']['WvLowCOffD'], 'WvLowCOffD', '- Low frequency cutoff used in the difference-frequencies (rad/s) [Only used with a difference-frequency method]\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['SeaState']['WvHiCOffD'], 'WvHiCOffD', '- High frequency cutoff used in the difference-frequencies (rad/s) [Only used with a difference-frequency method]\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['SeaState']['WvLowCOffS'], 'WvLowCOffS', '- Low frequency cutoff used in the summation-frequencies (rad/s) [Only used with a summation-frequency method]\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['SeaState']['WvHiCOffS'], 'WvHiCOffS', '- High frequency cutoff used in the summation-frequencies (rad/s) [Only used with a summation-frequency method]\n')) + f.write('---------------------- CONSTRAINED WAVE ---------------------------------------- [Only used when WaveMod=2]\n') + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['SeaState']['ConstWaveMod'], 'ConstWaveMod', '- Contrained wave model {0: no constrained wave, 1: Specified crest elevation of 0.5*CrestHmax, 2: Specified crest height of CrestHmax}\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['SeaState']['CrestHmax'], 'CrestHmax', '- Twice the crest elevation if ConstWaveMod=1 or the crest height if ConstWaveMod=2. (m) [need CrestHmax > WaveHs; unused when ConstWaveMod=0]\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['SeaState']['CrestTime'], 'CrestTime', '- Time of the wave crest. (sec) [unused when ConstWaveMod=0]\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['SeaState']['CrestXi'], 'CrestXi', '- X-position of the wave crest. (m) [unused when ConstWaveMod=0]\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['SeaState']['CrestYi'], 'CrestYi', '- Y-position of the wave crest. (m) [unused when ConstWaveMod=0]\n')) + f.write('---------------------- CURRENT ------------------------------------------------- [unused with WaveMod=6]\n') + f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['SeaState']['CurrMod'], 'CurrMod', '- Current profile model {0: none=no current, 1: standard, 2: user-defined from routine UserCurrent} (switch)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['SeaState']['CurrSSV0'], 'CurrSSV0', '- Sub-surface current velocity at still water level (m/s) [used only when CurrMod=1]\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['SeaState']['CurrSSDir'], 'CurrSSDir', '- Sub-surface current heading direction (degrees) or DEFAULT (string) [used only when CurrMod=1]\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['SeaState']['CurrNSRef'], 'CurrNSRef', '- Near-surface current reference depth (meters) [used only when CurrMod=1]\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['SeaState']['CurrNSV0'], 'CurrNSV0', '- Near-surface current velocity at still water level (m/s) [used only when CurrMod=1]\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['SeaState']['CurrNSDir'], 'CurrNSDir', '- Near-surface current heading direction (degrees) [used only when CurrMod=1]\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['SeaState']['CurrDIV'], 'CurrDIV', '- Depth-independent current velocity (m/s) [used only when CurrMod=1]\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['SeaState']['CurrDIDir'], 'CurrDIDir', '- Depth-independent current heading direction (degrees) [used only when CurrMod=1]\n')) + f.write('---------------------- MacCamy-Fuchs Diffraction Model ------------------------- [unused with WaveMod=6]\n') + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['SeaState']['MCFD'],'MCFD', '- Diameter of members for which the MacCamy-Fuchs model is to be enable. [used only when MCFD > 0]\n')) + f.write('---------------------- OUTPUT --------------------------------------------------\n') + f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['SeaState']['SeaStSum'], 'SeaStSum', '- Output a summary file [flag]\n')) + f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['SeaState']['OutSwtch'], 'OutSwtch','- Output requested channels to: [1=SeaState.out, 2=GlueCode.out, 3=both files]\n')) + f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['SeaState']['OutFmt'], 'OutFmt','- Output format for numerical results (quoted string) [not checked for validity!]\n')) + f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['SeaState']['OutSFmt'], 'OutSFmt','- Output format for header strings (quoted string) [not checked for validity!]\n')) + f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['SeaState']['NWaveElev'], 'NWaveElev','- Number of points where the incident wave elevations can be computed (-) [maximum of 9 output locations]\n')) + f.write('{:<22} {:<11} {:}'.format(", ".join([f'{val:4.2f}' for val in self.fst_vt['SeaState']['WaveElevxi']]), 'WaveElevxi', '- List of xi-coordinates for points where the incident wave elevations can be output (meters) [NWaveElev points, separated by commas or white space; usused if NWaveElev = 0]\n')) + f.write('{:<22} {:<11} {:}'.format(", ".join([f'{val:4.2f}' for val in self.fst_vt['SeaState']['WaveElevyi']]), 'WaveElevyi', '- List of yi-coordinates for points where the incident wave elevations can be output (meters) [NWaveElev points, separated by commas or white space; usused if NWaveElev = 0]\n')) + f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['SeaState']['NWaveKin'], 'NWaveKin','- Number of points where the incident wave elevations can be computed (-) [maximum of 9 output locations]\n')) + + if self.fst_vt['SeaState']['NWaveKin'] > 0 : + f.write('{:<22} {:<11} {:}'.format(", ".join([f'{val:4.2f}' for val in self.fst_vt['SeaState']['WaveKinxi']]), 'WaveKinxi', '- List of xi-coordinates for points where the wave kinematics can be output (meters) [NWaveKin points, separated by commas or white space; usused if NWaveKin = 0]\n')) + f.write('{:<22} {:<11} {:}'.format(", ".join([f'{val:4.2f}' for val in self.fst_vt['SeaState']['WaveKinyi']]), 'WaveKinyi', '- List of yi-coordinates for points where the wave kinematics can be output (meters) [NWaveKin points, separated by commas or white space; usused if NWaveKin = 0]\n')) + f.write('{:<22} {:<11} {:}'.format(", ".join([f'{val:4.2f}' for val in self.fst_vt['SeaState']['WaveKinzi']]), 'WaveKinzi', '- List of zi-coordinates for points where the wave kinematics can be output (meters) [NWaveKin points, separated by commas or white space; usused if NWaveKin = 0]\n')) + else: + f.write('{:<11} {:}'.format('WaveKinxi', '- List of xi-coordinates for points where the wave kinematics can be output (meters) [NWaveKin points, separated by commas or white space; usused if NWaveKin = 0]\n')) + f.write('{:<11} {:}'.format('WaveKinyi', '- List of yi-coordinates for points where the wave kinematics can be output (meters) [NWaveKin points, separated by commas or white space; usused if NWaveKin = 0]\n')) + f.write('{:<11} {:}'.format('WaveKinzi', '- List of zi-coordinates for points where the wave kinematics can be output (meters) [NWaveKin points, separated by commas or white space; usused if NWaveKin = 0]\n')) + + f.write('---------------------- OUTPUT CHANNELS -----------------------------------------\n') + outlist = self.get_outlist(self.fst_vt['outlist'], ['SeaState']) + for channel_list in outlist: + for i in range(len(channel_list)): + f.write('"' + channel_list[i] + '"\n') + + f.write('END of output channels and end of file. (the word "END" must appear in the first 3 columns of this line)\n') + f.close() def write_SubDyn(self): @@ -1846,7 +1949,7 @@ def write_SubDyn(self): ln.append('{:^11d}'.format(self.fst_vt['SubDyn']['MPropSetID2'][i])) ln.append('{:^11d}'.format(self.fst_vt['SubDyn']['MType'][i])) if self.fst_vt['SubDyn']['NCOSMs'] > 0: - ln.append('{:^11d}'.format(self.fst_vt['SubDyn']['COSMID'][i])) + ln.append('{:^11d}'.format(self.fst_vt['SubDyn']['M_COSMID'][i])) f.write(" ".join(ln) + '\n') f.write('------------------ MEMBER X-SECTION PROPERTY data 1/2 [isotropic material for now: use this table for circular-tubular elements] ------------------------\n') f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['SubDyn']['NPropSets'], 'NPropSets', '- Number of structurally unique x-sections (i.e. how many groups of X-sectional properties are utilized throughout all of the members)\n')) @@ -1898,6 +2001,22 @@ def write_SubDyn(self): ln.append('{:^11d}'.format(self.fst_vt['SubDyn']['RigidPropSetID'][i])) ln.append('{:^11}'.format(self.fst_vt['SubDyn']['RigidMatDens'][i])) f.write(" ".join(ln) + '\n') + f.write('----------------------- SPRING ELEMENT PROPERTIES ------------------------------------\n') + spring_list = ['k11','k12','k13','k14','k15','k16', + 'k22','k23','k24','k25','k26', + 'k33','k34','k35','k36', + 'k44','k45','k46', + 'k55','k56', + 'k66'] + f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['SubDyn']['NSpringPropSets'], 'NSpringPropSets', '- Number of spring properties\n')) + f.write("PropSetID k11 k12 k13 k14 k15 k16 k22 k23 k24 k25 k26 k33 k34 k35 k36 k44 k45 k46 k55 k56 k66 \n") + f.write(" (-) (N/m) (N/m) (N/m) (N/rad) (N/rad) (N/rad) (N/m) (N/m) (N/rad) (N/rad) (N/rad) (N/m) (N/rad) (N/rad) (N/rad) (Nm/rad) (Nm/rad) (Nm/rad) (Nm/rad) (Nm/rad) (Nm/rad) \n") + for i in range(self.fst_vt['SubDyn']['NSpringPropSets']): + ln = [] + ln.append('{:^11d}'.format(self.fst_vt['SubDyn']['SpringPropSetID'][i])) + for sl in spring_list: + ln.append('{:^11}'.format(self.fst_vt['SubDyn'][sl][i])) + f.write(" ".join(ln) + '\n') f.write('---------------------- MEMBER COSINE MATRICES COSM(i,j) ------------------------\n') f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['SubDyn']['NCOSMs'], 'NCOSMs', '- Number of unique cosine matrices (i.e., of unique member alignments including principal axis rotations); ignored if NXPropSets=0 or 9999 in any element below\n')) f.write(" ".join(['{:^11s}'.format(i) for i in ['COSMID', 'COSM11', 'COSM12', 'COSM13', 'COSM21', 'COSM22', 'COSM23', 'COSM31', 'COSM32', 'COSM33']])+'\n') @@ -1935,6 +2054,10 @@ def write_SubDyn(self): f.write(" ".join(ln) + '\n') f.write('---------------------------- OUTPUT: SUMMARY & OUTFILE ------------------------------\n') f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['SubDyn']['SumPrint'], 'SumPrint', '- Output a Summary File (flag).It contains: matrices K,M and C-B reduced M_BB, M-BM, K_BB, K_MM(OMG^2), PHI_R, PHI_L. It can also contain COSMs if requested.\n')) + if 'OutCBModes' in self.fst_vt['SubDyn']: + f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['SubDyn']['OutCBModes'], 'OutCBModes', '- Output Guyan and Craig-Bampton modes {0 No output, 1 JSON output}, (flag)\n')) + if 'OutFEMModes' in self.fst_vt['SubDyn']: + f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['SubDyn']['OutFEMModes'], 'OutFEMModes', '- Output first 30 FEM modes {0 No output, 1 JSON output} (flag)\n')) f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['SubDyn']['OutCOSM'], 'OutCOSM', '- Output cosine matrices with the selected output member forces (flag)\n')) f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['SubDyn']['OutAll'], 'OutAll', "- [T/F] Output all members' end forces\n")) f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['SubDyn']['OutSwtch'], 'OutSwtch', '- [1/2/3] Output requested channels to: 1=.SD.out; 2=.out (generated by FAST); 3=both files.\n')) @@ -1950,7 +2073,7 @@ def write_SubDyn(self): ln = [] ln.append('{:^11d}'.format(self.fst_vt['SubDyn']['MemberID_out'][i])) ln.append('{:^11d}'.format(self.fst_vt['SubDyn']['NOutCnt'][i])) - ln.append('{:^11d}'.format(self.fst_vt['SubDyn']['NodeCnt'][i])) + ln.append(" ".join(['{:^11d}'.format(node) for node in self.fst_vt['SubDyn']['NodeCnt'][i]])) f.write(" ".join(ln) + '\n') f.write('------------------------- SDOutList: The next line(s) contains a list of output parameters that will be output in .SD.out or .out. ------\n') outlist = self.get_outlist(self.fst_vt['outlist'], ['SubDyn']) @@ -1973,11 +2096,11 @@ def write_MAP(self): f.write(" ".join(['{:<11s}'.format(i) for i in ['LineType', 'Diam', 'MassDenInAir', 'EA', 'CB', 'CIntDamp', 'Ca', 'Cdn', 'Cdt']])+'\n') f.write(" ".join(['{:<11s}'.format(i) for i in ['(-)', '(m)', '(kg/m)', '(N)', '(-)', '(Pa-s)', '(-)', '(-)', '(-)']])+'\n') ln =[] - for i in range(self.fst_vt['MAP']['NTypes']): + for i in range(1): ln = [] ln.append('{:^11}'.format(self.fst_vt['MAP']['LineType'][i])) ln.append('{:^11}'.format(self.fst_vt['MAP']['Diam'][i])) - ln.append('{:^11}'.format(self.fst_vt['MAP']['MassDen'][i])) + ln.append('{:^11}'.format(self.fst_vt['MAP']['MassDenInAir'][i])) ln.append('{:^11}'.format(self.fst_vt['MAP']['EA'][i])) ln.append('{:<11}'.format(self.fst_vt['MAP']['CB'][i])) ln.append('{:<11}'.format(self.fst_vt['MAP']['CIntDamp'][i])) @@ -2004,7 +2127,7 @@ def write_MAP(self): f.write('---------------------- LINE PROPERTIES ---------------------------------------\n') f.write(" ".join(['{:<11s}'.format(i) for i in ['Line', 'LineType', 'UnstrLen', 'NodeAnch', 'NodeFair', 'Flags']])+'\n') f.write(" ".join(['{:<11s}'.format(i) for i in ['(-)', '(-)', '(m)', '(-)', '(-)', '(-)']])+'\n') - for i in range(self.fst_vt['MAP']['NLines']): + for i in range(len(self.fst_vt['MAP']['Line'])): ln = [] ln.append('{:^11d}'.format(self.fst_vt['MAP']['Line'][i])) ln.append('{:^11}'.format(self.fst_vt['MAP']['LineType'][i])) @@ -2050,6 +2173,64 @@ def write_MoorDyn(self): ln.append('{:^11.4f}'.format(self.fst_vt['MoorDyn']['CdAx'][i])) ln.append('{:^11.4f}'.format(self.fst_vt['MoorDyn']['CaAx'][i])) f.write(" ".join(ln) + '\n') + if self.fst_vt['MoorDyn']['Rod_Name']: + f.write('----------------------- ROD TYPES ------------------------------------------\n') + f.write(" ".join(['{:^11s}'.format(i) for i in ['TypeName', 'Diam', 'Mass/m', 'Cd', 'Ca', 'CdEnd', 'CaEnd']])+'\n') + f.write(" ".join(['{:^11s}'.format(i) for i in ['(name)', '(m)', '(kg/m)', '(-)', '(-)', '(-)', '(-)']])+'\n') + for i in range(len(self.fst_vt['MoorDyn']['Rod_Name'])): + ln = [] + ln.append('{:^11}'.format(self.fst_vt['MoorDyn']['Rod_Name'][i])) + ln.append('{:^11.4f}'.format(self.fst_vt['MoorDyn']['Rod_Diam'][i])) + ln.append('{:^11.4f}'.format(self.fst_vt['MoorDyn']['Rod_MassDen'][i])) + ln.append('{:^11.4f}'.format(self.fst_vt['MoorDyn']['Rod_Cd'][i])) + ln.append('{:^11.4f}'.format(self.fst_vt['MoorDyn']['Rod_Ca'][i])) + ln.append('{:^11.4f}'.format(self.fst_vt['MoorDyn']['Rod_CdEnd'][i])) + ln.append('{:^11.4f}'.format(self.fst_vt['MoorDyn']['Rod_CaEnd'][i])) + f.write(" ".join(ln) + '\n') + + + if self.fst_vt['MoorDyn']['Body_ID']: + f.write('----------------------- BODIES ------------------------------------------\n') + f.write(" ".join(['{:^11s}'.format(i) for i in ['ID', 'Attachement', 'X0', 'Y0', 'Z0', 'r0', 'p0','y0','Mass','CG*','I*','Volume','CdA*','Ca*']])+'\n') + f.write(" ".join(['{:^11s}'.format(i) for i in ['(#)', '(word)', '(m)', '(m)', '(m)', '(deg)', '(deg)','(deg)','(kg)','(m)','(kg-m^2)','(m^3)','m^2','(kg/m^3)']])+'\n') + for i in range(len(self.fst_vt['MoorDyn']['Body_ID'])): + ln = [] + ln.append('{:^11d}'.format(self.fst_vt['MoorDyn']['Body_ID'][i])) + ln.append('{:^11}'.format(self.fst_vt['MoorDyn']['Body_Attachment'][i])) + ln.append('{:^11.4f}'.format(self.fst_vt['MoorDyn']['X0'][i])) + ln.append('{:^11.4f}'.format(self.fst_vt['MoorDyn']['Y0'][i])) + ln.append('{:^11.4f}'.format(self.fst_vt['MoorDyn']['Z0'][i])) + ln.append('{:^11.4e}'.format(self.fst_vt['MoorDyn']['r0'][i])) + ln.append('{:^11.4e}'.format(self.fst_vt['MoorDyn']['p0'][i])) + ln.append('{:^11.4e}'.format(self.fst_vt['MoorDyn']['y0'][i])) + ln.append('{:^11.4e}'.format(self.fst_vt['MoorDyn']['Body_Mass'][i])) + ln.append('|'.join(['{:^.4f}'.format(a) for a in self.fst_vt['MoorDyn']['Body_CG'][i]])) + ln.append('|'.join(['{:^.4e}'.format(a) for a in self.fst_vt['MoorDyn']['Body_I'][i]])) + ln.append('{:^11.4e}'.format(self.fst_vt['MoorDyn']['Body_Volume'][i])) + ln.append('|'.join(['{:^.4f}'.format(a) for a in self.fst_vt['MoorDyn']['Body_CdA'][i]])) + ln.append('|'.join(['{:^.4f}'.format(a) for a in self.fst_vt['MoorDyn']['Body_Ca'][i]])) + f.write(" ".join(ln) + '\n') + + if self.fst_vt['MoorDyn']['Rod_ID']: + f.write('----------------------- RODS ------------------------------------------\n') + f.write(" ".join(['{:^11s}'.format(i) for i in ['ID', 'RodType', 'Attachment', 'Xa', 'Ya', 'Za', 'Xb','Yb','Zb','NumSegs','RodOutputs']])+'\n') + f.write(" ".join(['{:^11s}'.format(i) for i in ['(#)', '(name)', '(word/ID)', '(m)', '(m)', '(m)', '(m)','(m)','(m)','(-)','(-)']])+'\n') + for i in range(len(self.fst_vt['MoorDyn']['Rod_ID'])): + ln = [] + ln.append('{:^11}'.format(self.fst_vt['MoorDyn']['Rod_ID'][i])) + ln.append('{:^11}'.format(self.fst_vt['MoorDyn']['Rod_Type'][i])) + ln.append('{:^11}'.format(self.fst_vt['MoorDyn']['Rod_Attachment'][i])) + ln.append('{:^11.4f}'.format(self.fst_vt['MoorDyn']['Xa'][i])) + ln.append('{:^11.4f}'.format(self.fst_vt['MoorDyn']['Ya'][i])) + ln.append('{:^11.4f}'.format(self.fst_vt['MoorDyn']['Za'][i])) + ln.append('{:^11.4f}'.format(self.fst_vt['MoorDyn']['Xb'][i])) + ln.append('{:^11.4f}'.format(self.fst_vt['MoorDyn']['Yb'][i])) + ln.append('{:^11.4f}'.format(self.fst_vt['MoorDyn']['Zb'][i])) + ln.append('{:^11d}'.format(self.fst_vt['MoorDyn']['Rod_NumSegs'][i])) + ln.append('{:^11}'.format(self.fst_vt['MoorDyn']['RodOutputs'][i])) + f.write(" ".join(ln) + '\n') + + f.write('---------------------- POINTS --------------------------------\n') f.write(" ".join(['{:^11s}'.format(i) for i in ['ID', 'Attachment', 'X', 'Y', 'Z', 'M', 'V', 'CdA', 'CA']])+'\n') f.write(" ".join(['{:^11s}'.format(i) for i in ['(-)', '(-)', '(m)', '(m)', '(m)', '(kg)', '(m^3)', '(m^2)', '(-)']])+'\n') @@ -2097,6 +2278,15 @@ def write_MoorDyn(self): f.write('{:<22} {:<11} {:}'.format(self.fst_vt['MoorDyn']['TmaxIC'], 'TmaxIC', '- max time for ic gen (s)\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['MoorDyn']['CdScaleIC'], 'CdScaleIC', '- factor by which to scale drag coefficients during dynamic relaxation (-)\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['MoorDyn']['threshIC'], 'threshIC', '- threshold for IC convergence (-)\n')) + if 'inertialF' in self.fst_vt['MoorDyn']['options']: + f.write('{:<22d} {:<11} {:}'.format(int(self.fst_vt['MoorDyn']['inertialF']), 'inertialF', '- Compute the inertial forces (0: no, 1: yes). Switch to 0 if you get: Warning: extreme pitch moment from body-attached Rod.\n')) + + if 'WaterKin' in self.fst_vt['MoorDyn']['options']: + self.fst_vt['MoorDyn']['WaterKin_file'] = self.FAST_namingOut + '_WaterKin.dat' + f.write('{:<22} {:<11} {:}'.format('"'+self.fst_vt['MoorDyn']['WaterKin_file']+'"', 'WaterKin', '- WaterKin input file\n')) + + + # f.write('{:^11s} {:<11} {:}'.format(self.fst_vt['MoorDyn']['WaterKin'], 'WaterKin', 'Handling of water motion (0=off, 1=on)\n')) f.write('------------------------ OUTPUTS --------------------------------------------\n') outlist = self.get_outlist(self.fst_vt['outlist'], ['MoorDyn']) for channel_list in outlist: @@ -2108,6 +2298,34 @@ def write_MoorDyn(self): f.flush() os.fsync(f) f.close() + + def write_WaterKin(self,WaterKin_file): + f = open(WaterKin_file, 'w') + + f.write('MoorDyn v2 (Feb 2022) Waves and Currents input file set up for USFLOWT\n') + f.write('Wave kinematics that will have an impact over the cans and the mooring lines.\n') + f.write('--------------------------- WAVES -------------------------------------\n') + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['WaterKin']['WaveKinMod'], 'WaveKinMod', '- type of wave input {0 no waves; 3 set up grid of wave data based on time series}\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['WaterKin']['WaveKinFile'], 'WaveKinFile', '- file containing wave elevation time series at 0,0,0\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['WaterKin']['dtWave'], 'dtWave', '- time step to use in setting up wave kinematics grid (s)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['WaterKin']['WaveDir'], 'WaveDir', '- wave heading (deg)\n')) + f.write('{:<22} {:}'.format(self.fst_vt['WaterKin']['X_Type'], '- X wave input type (0: not used; 1: list values in ascending order; 2: uniform specified by -xlim, xlim, num)\n')) + f.write('{:<22} {:}'.format(', '.join(['{:.3f}'.format(i) for i in self.fst_vt['WaterKin']['X_Grid']]), '- X wave grid point data separated by commas\n')) + f.write('{:<22} {:}'.format(self.fst_vt['WaterKin']['Y_Type'], '- Y wave input type (0: not used; 1: list values in ascending order; 2: uniform specified by -Ylim, Ylim, num)\n')) + f.write('{:<22} {:}'.format(', '.join(['{:.3f}'.format(i) for i in self.fst_vt['WaterKin']['Y_Grid']]), '- Y wave grid point data separated by commas\n')) + f.write('{:<22} {:}'.format(self.fst_vt['WaterKin']['Z_Type'], '- Z wave input type (0: not used; 1: list values in ascending order; 2: uniform specified by -Zlim, Zlim, num)\n')) + f.write('{:<22} {:}'.format(', '.join(['{:.3f}'.format(i) for i in self.fst_vt['WaterKin']['Z_Grid']]), '- Z wave grid point data separated by commas\n')) + f.write('--------------------------- CURRENT -------------------------------------\n') + f.write('0 CurrentMod - type of current input {0 no current; 1 steady current profile described below} \n') + f.write('z-depth x-current y-current\n') + f.write('(m) (m/s) (m/s)\n') + f.write('--------------------- need this line ------------------\n') + + f.flush() + os.fsync(f) + f.close() + + def write_StC(self,StC_vt,StC_filename): @@ -2215,37 +2433,28 @@ def write_StC(self,StC_vt,StC_filename): if __name__=="__main__": + from pathlib import Path + fst_update = {} fst_update['Fst', 'TMax'] = 20. fst_update['AeroDyn15', 'TwrAero'] = False - examples_dir = os.path.dirname( os.path.dirname( os.path.dirname( os.path.realpath(__file__) ) ) ) + os.sep + parent_dir = os.path.dirname( os.path.dirname( os.path.dirname( os.path.realpath(__file__) ) ) ) + os.sep + build_of_io_dir = os.path.join(parent_dir, 'build_ofio') + Path(build_of_io_dir).mkdir(parents=True, exist_ok=True) # Read the model fast = InputReader_OpenFAST() - fast.FAST_InputFile = 'IEA-15-240-RWT-UMaineSemi.fst' # FAST input file (ext=.fst) - fast.FAST_directory = os.path.join(examples_dir, 'examples', '01_aeroelasticse', - 'OpenFAST_models', 'IEA-15-240-RWT', - 'IEA-15-240-RWT-UMaineSemi') # Path to fst directory files + fast.FAST_InputFile = '5MW_Land_BD_DLL_WTurb.fst' # FAST input file (ext=.fst) + fast.FAST_directory = os.path.join(parent_dir, 'reg_tests', 'r-test', + 'glue-codes', 'openfast', + '5MW_Land_BD_DLL_WTurb') # Path to fst directory files fast.execute() # Write out the model fastout = InputWriter_OpenFAST() fastout.fst_vt = fast.fst_vt - fastout.FAST_runDirectory = 'temp/OpenFAST' - fastout.FAST_namingOut = 'iea15' + fastout.FAST_runDirectory = os.path.join(build_of_io_dir,'fast_write_main_test') + fastout.FAST_namingOut = '5MW_Land_BD_DLL_WTurb_write' fastout.update(fst_update=fst_update) fastout.execute() - - # import pickle - # with open('fst_vt.pkl','rb') as f: - # fst_vt = pickle.load(f) - - # fastout = InputWriter_OpenFAST() - # fastout.FAST_runDirectory = 'none' - - # fst_vt['TStC'][0]['NKInpSt'] = 2 - - # for i_TStC, TStC in enumerate(fst_vt['TStC']): - # fastout.write_StC(TStC,fst_vt['ServoDyn']['TStCfiles'][i_TStC]) - # print('here') diff --git a/openfast_python/openfast_io/create_output_vars.py b/openfast_python/openfast_io/create_output_vars.py index c34f60eb4..2a43ddf87 100644 --- a/openfast_python/openfast_io/create_output_vars.py +++ b/openfast_python/openfast_io/create_output_vars.py @@ -78,11 +78,11 @@ def GetOutlistParameters(fname_vars_out, xl_files_in, sheet_list, write_mode, fi try: # File Location - root_dir = os.path.dirname( os.path.dirname( ( os.path.realpath(__file__) ) ) ) + os.sep - outlist_fast_lib = os.path.join(root_dir, 'docs', 'OtherSupporting' , 'OutListParameters.xlsx') + root_dir = os.path.dirname(os.path.dirname( os.path.dirname( ( os.path.realpath(__file__) ) ) )) + os.sep + outlist_fast_lib = os.path.join(root_dir, 'docs', 'OtherSupporting' , 'OutListParameters.xls') # Sheets to grab - sheet_list = ['ElastoDyn', 'BeamDyn', 'ServoDyn', 'AeroDyn', 'InflowWind', 'WAMIT', 'HydroDyn', 'Morison', # 'SubDyn' - 'ElastoDyn_Nodes','BeamDyn_Nodes','AeroDyn_Nodes'] + sheet_list = ['AeroDyn', 'BeamDyn', 'ElastoDyn', 'InflowWind', 'ServoDyn', 'HydroDyn', 'Morison', 'SeaState', 'SubDyn', + 'AeroDyn_Nodes','BeamDyn_Nodes','ElastoDyn_Nodes'] xl_files = [outlist_fast_lib]*len(sheet_list) # Output naming fname_vars_out = 'FAST_vars_out.py' From 3313e729a446b52f83e69d8152c7db2c08af91f1 Mon Sep 17 00:00:00 2001 From: Mayank Chetan Date: Mon, 5 Aug 2024 22:22:55 +0000 Subject: [PATCH 002/161] update lib name to openfast_io --- openfast_python/pyproject.toml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/openfast_python/pyproject.toml b/openfast_python/pyproject.toml index c5da3bb4c..6bac6be63 100644 --- a/openfast_python/pyproject.toml +++ b/openfast_python/pyproject.toml @@ -1,14 +1,14 @@ [tool.poetry] -name = "octue-openfast" +name = "openfast_io" version = "3.5.4.beta-1" description = "Readers and writers for OpenFAST files." license = "Apache-2.0" authors = [ "NREL WISDEM Team ", - "dzalkind", + "Daniel Zalkind ", "Garrett Barter ", "Pietro Bortolotti ", - "Mayank Chetan", + "Mayank Chetan ", "John Jasa", ] readme = "README.md" From f5067557d62327c6424f8787b3c44a0b5e45892b Mon Sep 17 00:00:00 2001 From: Mayank Chetan Date: Mon, 5 Aug 2024 22:39:03 +0000 Subject: [PATCH 003/161] add main func to turbsim_file --- openfast_python/openfast_io/turbsim_file.py | 24 +++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/openfast_python/openfast_io/turbsim_file.py b/openfast_python/openfast_io/turbsim_file.py index 2756fff7b..90ecf9da0 100644 --- a/openfast_python/openfast_io/turbsim_file.py +++ b/openfast_python/openfast_io/turbsim_file.py @@ -127,7 +127,7 @@ def write(self, filename=None): intrng = 65535 off = np.empty((3), dtype = np.float32) scl = np.empty((3), dtype = np.float32) - info = 'Generated by TurbSimFile on {:s}.'.format(time.strftime('%d-%b-%Y at %H:%M:%S', time.localtime())) + info = 'Generated by openfast_io.TurbSimFile on {:s}.'.format(time.strftime('%d-%b-%Y at %H:%M:%S', time.localtime())) # Calculate scaling, offsets and scaling data out = np.empty(ts.shape, dtype=np.int16) outTwr = np.empty(tsTwr.shape, dtype=np.int16) @@ -316,4 +316,24 @@ def compute_rot_avg(self,R): if __name__=='__main__': - ts = TurbSimFile('../_tests/TurbSim.bts') + + from pathlib import Path + + parent_dir = os.path.dirname( os.path.dirname( os.path.dirname( os.path.realpath(__file__) ) ) ) + os.sep + + # Read the turbulence file + ts = TurbSimFile(os.path.join(parent_dir, 'reg_tests', 'r-test', + 'glue-codes', 'openfast', + '5MW_Baseline', 'Wind', + '90m_12mps_twr.bts')) # Path to fst directory files + + print(ts) + + # Modify and write the turbulence file + build_of_io_dir = os.path.join(parent_dir, 'build_ofio', 'turbsim_file_main') + Path(build_of_io_dir).mkdir(parents=True, exist_ok=True) + + ts['u'] = ts['u'] + 1.0 # adding 1 m/s to the wind speed + + ts.write(os.path.join(build_of_io_dir, '90m_12mps_twrMod.bts')) + From c54da68ac4f2efef4eef8014612171d484204108 Mon Sep 17 00:00:00 2001 From: Mayank Chetan Date: Tue, 6 Aug 2024 04:12:12 +0000 Subject: [PATCH 004/161] check if r-test is cloned --- .../openfast_io/FAST_output_reader.py | 20 +++++++++++-------- openfast_python/openfast_io/FAST_reader.py | 4 ++++ openfast_python/openfast_io/FAST_writer.py | 6 +++++- openfast_python/openfast_io/FileTools.py | 7 +++++++ 4 files changed, 28 insertions(+), 9 deletions(-) diff --git a/openfast_python/openfast_io/FAST_output_reader.py b/openfast_python/openfast_io/FAST_output_reader.py index aba932839..e6253b255 100644 --- a/openfast_python/openfast_io/FAST_output_reader.py +++ b/openfast_python/openfast_io/FAST_output_reader.py @@ -211,16 +211,20 @@ def fread(fid, n, type): if __name__=="__main__": - d,i = load_binary_output('Test18.T1.outb') - types = [] - for j in range(39): - types.append('f8') - print(type(i['attribute_names'])) - print(np.dtype({'names':tuple(i['attribute_names']), 'formats': tuple(types) })) - print(type(d)) - print(np.array(d,dtype=np.dtype({'names':tuple(i['attribute_names']), 'formats': tuple(types) }))) + from openfast_io.FileTools import check_rtest_cloned + + parent_dir = os.path.dirname( os.path.dirname( os.path.dirname( os.path.realpath(__file__) ) ) ) + os.sep + + of_outputfile = os.path.join(parent_dir, 'reg_tests', 'r-test', 'glue-codes', + 'openfast', '5MW_Land_BD_DLL_WTurb', '5MW_Land_BD_DLL_WTurb.outb') + check_rtest_cloned(of_outputfile) + + d,i,p = load_binary_output(of_outputfile) + + print(tuple(i['attribute_names'])) + print(type(d)) print(i) print(len(i['attribute_names'])) print(np.shape(d)) diff --git a/openfast_python/openfast_io/FAST_reader.py b/openfast_python/openfast_io/FAST_reader.py index 7503fa7f7..a98adba4d 100644 --- a/openfast_python/openfast_io/FAST_reader.py +++ b/openfast_python/openfast_io/FAST_reader.py @@ -2892,6 +2892,7 @@ def execute(self): self.read_BeamDyn(bd_file) if __name__=="__main__": + from openfast_io.FileTools import check_rtest_cloned parent_dir = os.path.dirname( os.path.dirname( os.path.dirname( os.path.realpath(__file__) ) ) ) + os.sep @@ -2901,4 +2902,7 @@ def execute(self): fast.FAST_directory = os.path.join(parent_dir, 'reg_tests', 'r-test', 'glue-codes', 'openfast', '5MW_Land_BD_DLL_WTurb') # Path to fst directory files + + check_rtest_cloned(os.path.join(fast.FAST_directory, fast.FAST_InputFile)) + fast.execute() \ No newline at end of file diff --git a/openfast_python/openfast_io/FAST_writer.py b/openfast_python/openfast_io/FAST_writer.py index 97ade59eb..1698deb20 100644 --- a/openfast_python/openfast_io/FAST_writer.py +++ b/openfast_python/openfast_io/FAST_writer.py @@ -6,7 +6,6 @@ import numpy as np from functools import reduce -from openfast_io.FAST_reader import InputReader_OpenFAST try: from rosco.toolbox import utilities as ROSCO_utilities @@ -2433,6 +2432,8 @@ def write_StC(self,StC_vt,StC_filename): if __name__=="__main__": + from openfast_io.FAST_reader import InputReader_OpenFAST + from openfast_io.FileTools import check_rtest_cloned from pathlib import Path fst_update = {} @@ -2449,6 +2450,9 @@ def write_StC(self,StC_vt,StC_filename): fast.FAST_directory = os.path.join(parent_dir, 'reg_tests', 'r-test', 'glue-codes', 'openfast', '5MW_Land_BD_DLL_WTurb') # Path to fst directory files + + check_rtest_cloned(os.path.join(fast.FAST_directory, fast.FAST_InputFile)) + fast.execute() # Write out the model diff --git a/openfast_python/openfast_io/FileTools.py b/openfast_python/openfast_io/FileTools.py index 9477400c4..5f753bdca 100644 --- a/openfast_python/openfast_io/FileTools.py +++ b/openfast_python/openfast_io/FileTools.py @@ -269,3 +269,10 @@ def get_dlc_label(cases, include_seed=True): def load_file_list(fname_flist): # load list of filenames from file return np.genfromtxt(fname_flist, dtype='str') + +def check_rtest_cloned(rtest_dir): + # check if the rtest directory is cloned + if not os.path.isdir(rtest_dir): + raise FileNotFoundError(f"The directory {rtest_dir} does not exist. Please clone the r-test submodule. Try running `git submodule update --init --recursive`") + + return True \ No newline at end of file From 7faa58b187667662671e36dd99ef8a3dc899ed4f Mon Sep 17 00:00:00 2001 From: Mayank Chetan Date: Tue, 6 Aug 2024 06:27:51 +0000 Subject: [PATCH 005/161] handle blank line before END in certain input files --- openfast_python/openfast_io/FAST_reader.py | 9 ++++++++- openfast_python/openfast_io/FAST_writer.py | 2 +- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/openfast_python/openfast_io/FAST_reader.py b/openfast_python/openfast_io/FAST_reader.py index a98adba4d..d4f50231b 100644 --- a/openfast_python/openfast_io/FAST_reader.py +++ b/openfast_python/openfast_io/FAST_reader.py @@ -451,7 +451,9 @@ def read_ElastoDyn(self, ed_file): self.set_outlist(self.fst_vt['outlist']['ElastoDyn'], channel_list) data = f.readline() - + else: + # there is a blank line between the outlist and the END of the file + f.readline() # ElastoDyn optional outlist try: f.readline() @@ -993,6 +995,11 @@ def read_AeroDyn15(self): # AeroDyn15 Outlist f.readline() data = f.readline() + + # Handle the case if there are blank lines befroe the END statement, check if blank line + while data.split().__len__() == 0: + data = f.readline() + while data.split()[0] != 'END': if data.find('"')>=0: channels = data.split('"') diff --git a/openfast_python/openfast_io/FAST_writer.py b/openfast_python/openfast_io/FAST_writer.py index 1698deb20..8dd35671a 100644 --- a/openfast_python/openfast_io/FAST_writer.py +++ b/openfast_python/openfast_io/FAST_writer.py @@ -421,7 +421,7 @@ def write_ElastoDyn(self): f.write('{:<22} {:<11} {:}'.format('', 'TwrGagNd', '- List of tower nodes that have strain gages [1 to TwrNodes] (-) [unused if NTwGages=0]\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDyn']['NBlGages'], 'NBlGages', '- Number of blade nodes that have strain gages for output [0 to 9] (-)\n')) if self.fst_vt['ElastoDyn']['BldGagNd'] != 0: - f.write('{:<22} {:<11} {:}'.format(', '.join(['%d'%i for i in self.fst_vt['ElastoDyn']['BldGagNd']]), 'BldGagNd', '- List of blade nodes that have strain gages [1 to BldNodes] (-) [unused if NBlGages=0]\n')) + f.write('{:<22} {:<11} {:}'.format(', '.join(['%d'%int(i) for i in self.fst_vt['ElastoDyn']['BldGagNd']]), 'BldGagNd', '- List of blade nodes that have strain gages [1 to BldNodes] (-) [unused if NBlGages=0]\n')) else: f.write('{:<22} {:<11} {:}'.format('', 'BldGagNd', '- List of blade nodes that have strain gages [1 to BldNodes] (-) [unused if NBlGages=0]\n')) f.write(' OutList - The next line(s) contains a list of output parameters. See OutListParameters.xlsx for a listing of available output channels, (-)\n') From 8f031f6fcfd4f5b5a9b590fd6703a0ac11bd45a0 Mon Sep 17 00:00:00 2001 From: Mayank Chetan Date: Tue, 6 Aug 2024 18:02:11 +0000 Subject: [PATCH 006/161] genralizing map++ read write --- openfast_python/openfast_io/FAST_reader.py | 86 +++++++++++++++------- openfast_python/openfast_io/FAST_writer.py | 12 ++- 2 files changed, 68 insertions(+), 30 deletions(-) diff --git a/openfast_python/openfast_io/FAST_reader.py b/openfast_python/openfast_io/FAST_reader.py index d4f50231b..f5f2521f0 100644 --- a/openfast_python/openfast_io/FAST_reader.py +++ b/openfast_python/openfast_io/FAST_reader.py @@ -2085,9 +2085,16 @@ def read_HydroDyn(self, hd_file): f.readline() data = f.readline() while data.split()[0] != 'END': - channels = data.split('"') - channel_list = channels[1].split(',') - self.set_outlist(self.fst_vt['outlist']['HydroDyn'], channel_list) + if data.find('"')>=0: + channels = data.split('"') + channel_list = channels[1].split(',') + else: + row_string = data.split(',') + if len(row_string)==1: + channel_list = row_string[0].split('\n')[0] + else: + channel_list = row_string + self.set_outlist(self.fst_vt['outlist']['AeroDyn'], channel_list) data = f.readline() f.close() @@ -2516,26 +2523,35 @@ def read_MAP(self, map_file): f.readline() f.readline() f.readline() + + # Init line dictionary + line_dict = ['LineType', 'Diam', 'MassDenInAir', 'EA', 'CB', 'CIntDamp', 'Ca', 'Cdn', 'Cdt'] + for ld in line_dict: + self.fst_vt['MAP'][ld] = [] + data_line = f.readline().strip().split() - self.fst_vt['MAP']['LineType'] = [str(data_line[0])] - self.fst_vt['MAP']['Diam'] = [float(data_line[1])] - self.fst_vt['MAP']['MassDenInAir'] = [float(data_line[2])] - self.fst_vt['MAP']['EA'] = [float(data_line[3])] - self.fst_vt['MAP']['CB'] = [float(data_line[4])] - self.fst_vt['MAP']['CIntDamp'] = [float(data_line[5])] - self.fst_vt['MAP']['Ca'] = [float(data_line[6])] - self.fst_vt['MAP']['Cdn'] = [float(data_line[7])] - self.fst_vt['MAP']['Cdt'] = [float(data_line[8])] - f.readline() + while data_line[0] and data_line[0][:3] != '---': # OpenFAST searches for ---, so we'll do the same + self.fst_vt['MAP']['LineType'].append( str(data_line[0])) + self.fst_vt['MAP']['Diam'].append( float_read(data_line[1])) + self.fst_vt['MAP']['MassDenInAir'].append( float_read(data_line[2])) + self.fst_vt['MAP']['EA'].append( float_read(data_line[3])) + self.fst_vt['MAP']['CB'].append( float_read(data_line[4])) + self.fst_vt['MAP']['CIntDamp'].append( float_read(data_line[5])) + self.fst_vt['MAP']['Ca'].append( float_read(data_line[6])) + self.fst_vt['MAP']['Cdn'].append( float_read(data_line[7])) + self.fst_vt['MAP']['Cdt'].append( float_read(data_line[8])) + data_line = f.readline().strip().split() + #f.readline() f.readline() f.readline() + # Init map nodes node_types = ['Node','Type','X','Y','Z','M','B','FX','FY','FZ'] for nt in node_types: self.fst_vt['MAP'][nt] = [] - for i in range(2): - data_node = f.readline().strip().split() + data_node = f.readline().strip().split() + while data_node[0] and data_node[0][:3] != '---': # OpenFAST searches for ---, so we'll do the same self.fst_vt['MAP']['Node'].append(int(data_node[0])) self.fst_vt['MAP']['Type'].append(str(data_node[1])) self.fst_vt['MAP']['X'].append(float_read(data_node[2])) @@ -2546,20 +2562,38 @@ def read_MAP(self, map_file): self.fst_vt['MAP']['FX'].append(float_read(data_node[7])) self.fst_vt['MAP']['FY'].append(float_read(data_node[8])) self.fst_vt['MAP']['FZ'].append(float_read(data_node[9])) + data_node = f.readline().strip().split() + data_node = ''.join(data_node) # re-join for reading next section uniformly + # f.readline() f.readline() f.readline() - f.readline() + + # Init line properties + line_prop = ['Line', 'LineType', 'UnstrLen', 'NodeAnch', 'NodeFair', 'Flags'] + for lp in line_prop: + self.fst_vt['MAP'][lp] = [] + data_line_prop = f.readline().strip().split() - self.fst_vt['MAP']['Line'] = [int(data_line_prop[0])] - self.fst_vt['MAP']['LineType'] = [str(data_line_prop[1])] - self.fst_vt['MAP']['UnstrLen'] = [float(data_line_prop[2])] - self.fst_vt['MAP']['NodeAnch'] = [int(data_line_prop[3])] - self.fst_vt['MAP']['NodeFair'] = [int(data_line_prop[4])] - self.fst_vt['MAP']['Flags'] = [[str(val) for val in data_line_prop[5:]]] - f.readline() - f.readline() - f.readline() - self.fst_vt['MAP']['Option'] = [str(val) for val in f.readline().strip().split()] + while data_line_prop[0] and data_line_prop[0][:3] != '---': # OpenFAST searches for ---, so we'll do the same + self.fst_vt['MAP']['Line'] .append( int(data_line_prop[0])) + self.fst_vt['MAP']['LineType'].append( str(data_line_prop[1])) + self.fst_vt['MAP']['UnstrLen'].append( float_read(data_line_prop[2])) + self.fst_vt['MAP']['NodeAnch'].append( int(data_line_prop[3])) + self.fst_vt['MAP']['NodeFair'].append( int(data_line_prop[4])) + self.fst_vt['MAP']['Flags'] .append( [str(val) for val in data_line_prop[5:]] ) + data_line_prop = f.readline().strip().split() + data_line_prop = ''.join(data_line_prop) # re-join for reading next section uniformly + # f.readline() + f.readline() + f.readline() + + self.fst_vt['MAP']['Option'] = [] # Solver options + # need to check for EOF here since we can have any number of solver options + data_solver = f.readline().strip().split() # Solver options + while len(data_solver) > 0: # stopping if we hit blank lines + self.fst_vt['MAP']['Option'].append([str(val) for val in data_solver]) + data_solver = f.readline().strip().split() + # self.fst_vt['MAP']['Option'] = [str(val) for val in f.readline().strip().split()] f.close() def read_MoorDyn(self, moordyn_file): diff --git a/openfast_python/openfast_io/FAST_writer.py b/openfast_python/openfast_io/FAST_writer.py index 8dd35671a..12c3014f7 100644 --- a/openfast_python/openfast_io/FAST_writer.py +++ b/openfast_python/openfast_io/FAST_writer.py @@ -416,7 +416,7 @@ def write_ElastoDyn(self): f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDyn']['DecFact'], 'DecFact', '- Decimation factor for tabular output {1: output every time step} (-) (currently unused)\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDyn']['NTwGages'], 'NTwGages', '- Number of tower nodes that have strain gages for output [0 to 9] (-)\n')) if self.fst_vt['ElastoDyn']['TwrGagNd'] != 0: - f.write('{:<22} {:<11} {:}'.format(', '.join(['%d'%i for i in self.fst_vt['ElastoDyn']['TwrGagNd']]), 'TwrGagNd', '- List of tower nodes that have strain gages [1 to TwrNodes] (-) [unused if NTwGages=0]\n')) + f.write('{:<22} {:<11} {:}'.format(', '.join(['%d'%int(i) for i in self.fst_vt['ElastoDyn']['TwrGagNd']]), 'TwrGagNd', '- List of tower nodes that have strain gages [1 to TwrNodes] (-) [unused if NTwGages=0]\n')) else: f.write('{:<22} {:<11} {:}'.format('', 'TwrGagNd', '- List of tower nodes that have strain gages [1 to TwrNodes] (-) [unused if NTwGages=0]\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDyn']['NBlGages'], 'NBlGages', '- Number of blade nodes that have strain gages for output [0 to 9] (-)\n')) @@ -2135,14 +2135,18 @@ def write_MAP(self): ln.append('{:^11d}'.format(self.fst_vt['MAP']['NodeFair'][i])) # ln.append('{:^11}'.format(self.fst_vt['MAP']['Outputs'][i])) # ln.append('{:^11}'.format(self.fst_vt['MAP']['CtrlChan'][i])) - # ln.append('{:<11}'.format(" ".join(self.fst_vt['MAP']['Flags']))) + ln.append('{:<11}'.format(" ".join(self.fst_vt['MAP']['Flags'][i]))) f.write(" ".join(ln) + '\n') ln =[] f.write('---------------------- SOLVER OPTIONS-----------------------------------------\n') f.write('{:<11s}'.format('Option'+'\n')) f.write('{:<11s}'.format('(-)')+'\n') - f.write("\n".join(self.fst_vt['MAP']['Option']).strip() + '\n') - + for i in range(len(self.fst_vt['MAP']['Option'])): + ln = [] + ln.append('{:<11}'.format(" ".join(self.fst_vt['MAP']['Option'][i]))) + f.write("\n".join(ln) + '\n') + ln = [] + f.write('\n') # adding a blank line after all solver options f.flush() os.fsync(f) f.close() From e18a220e2687eeaaa9d01a7eb15cab83722c7c60 Mon Sep 17 00:00:00 2001 From: Mayank Chetan Date: Tue, 6 Aug 2024 19:41:02 +0000 Subject: [PATCH 007/161] adding moordyn outputs, TODO: flexi outputs --- openfast_python/openfast_io/FAST_reader.py | 5 ++-- openfast_python/openfast_io/FAST_vars_out.py | 28 ++++++++++++++++++++ 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/openfast_python/openfast_io/FAST_reader.py b/openfast_python/openfast_io/FAST_reader.py index f5f2521f0..c2345e5c2 100644 --- a/openfast_python/openfast_io/FAST_reader.py +++ b/openfast_python/openfast_io/FAST_reader.py @@ -156,7 +156,7 @@ def read_outlist(self,f,module): ''' data = f.readline() while data.split()[0] != 'END': - pattern = r'"(.*?)"' # grab only the text between quotes + pattern = r'"?(.*?)"?' # grab only the text between quotes data = re.findall(pattern, data)[0] channels = data.split(',') # split on commas channels = [c.strip() for c in channels] # strip whitespace @@ -2891,7 +2891,8 @@ def execute(self): if not os.path.isabs(self.fst_vt['ElastoDyn']['TwrFile']): ed_tower_file = os.path.join(os.path.dirname(ed_file), self.fst_vt['ElastoDyn']['TwrFile']) self.read_ElastoDynTower(ed_tower_file) - self.read_InflowWind() + if self.fst_vt['Fst']['CompInflow'] == 1: + self.read_InflowWind() # AeroDyn version selection if self.fst_vt['Fst']['CompAero'] == 1: self.read_AeroDyn14() diff --git a/openfast_python/openfast_io/FAST_vars_out.py b/openfast_python/openfast_io/FAST_vars_out.py index 8d5ca4de9..fe47fa1fc 100644 --- a/openfast_python/openfast_io/FAST_vars_out.py +++ b/openfast_python/openfast_io/FAST_vars_out.py @@ -9574,6 +9574,33 @@ ElastoDyn_Nodes['FlyNT'] = False # (kN); Edgewise shear force in local coordinate system (initial structural twist removed); Directed along the local yb-axis ElastoDyn_Nodes['FyL'] = False # (kN); Edgewise shear force in local coordinate system (initial structural twist removed); Directed along the local yb-axis +""" MoorDyn """ +# THIS IS NOT A COMPLETE LIST! +# the "flexible naming system" discussed on page 7-8 of the documentation is not included +# http://www.matt-hall.ca/files/MoorDyn-Users-Guide-2017-08-16.pdf + +# also assuming that like other OpenFAST variables, it is limited to 9 output locations per veriable, i.e. FairTen1-FairTen9 +# TODO: Handle the flexible outputs for moordyn. This will require a different approach than the current dictionary structure. + +MoorDyn = {} +MoorDyn['FairTen1'] = False # (); ; +MoorDyn['FairTen2'] = False # (); ; +MoorDyn['FairTen3'] = False # (); ; +MoorDyn['FairTen4'] = False # (); ; +MoorDyn['FairTen5'] = False # (); ; +MoorDyn['FairTen6'] = False # (); ; +MoorDyn['FairTen7'] = False # (); ; +MoorDyn['FairTen8'] = False # (); ; +MoorDyn['FairTen9'] = False # (); ; +MoorDyn['AnchTen1'] = False # (); ; +MoorDyn['AnchTen2'] = False # (); ; +MoorDyn['AnchTen3'] = False # (); ; +MoorDyn['AnchTen4'] = False # (); ; +MoorDyn['AnchTen5'] = False # (); ; +MoorDyn['AnchTen6'] = False # (); ; +MoorDyn['AnchTen7'] = False # (); ; +MoorDyn['AnchTen8'] = False # (); ; +MoorDyn['AnchTen9'] = False # (); ; """ Final Output Dictionary """ FstOutput = {} @@ -9590,3 +9617,4 @@ FstOutput['AeroDyn_Nodes'] = AeroDyn_Nodes FstOutput['BeamDyn_Nodes'] = BeamDyn_Nodes FstOutput['ElastoDyn_Nodes'] = ElastoDyn_Nodes +FstOutput['MoorDyn'] = MoorDyn From cd1355582bbfdac20887e5a4dfeb2f346e6d8954 Mon Sep 17 00:00:00 2001 From: Mayank Chetan Date: Tue, 6 Aug 2024 21:23:09 +0000 Subject: [PATCH 008/161] inital add of ExtPtfm & Superelement --- openfast_python/openfast_io/FAST_reader.py | 278 ++++++++++++++++++- openfast_python/openfast_io/FAST_vars_out.py | 69 +++++ openfast_python/openfast_io/FAST_writer.py | 186 +++++++++++++ 3 files changed, 521 insertions(+), 12 deletions(-) diff --git a/openfast_python/openfast_io/FAST_reader.py b/openfast_python/openfast_io/FAST_reader.py index c2345e5c2..a5e6d0fdc 100644 --- a/openfast_python/openfast_io/FAST_reader.py +++ b/openfast_python/openfast_io/FAST_reader.py @@ -116,6 +116,7 @@ def __init__(self): self.fst_vt['SeaState'] = {} self.fst_vt['MoorDyn'] = {} self.fst_vt['SubDyn'] = {} + self.fst_vt['ExtPtfm'] = {} self.fst_vt['MAP'] = {} self.fst_vt['BeamDyn'] = {} self.fst_vt['BeamDynBlade'] = {} @@ -444,16 +445,34 @@ def read_ElastoDyn(self, ed_file): # Loop through output channel lines f.readline() data = f.readline() - if data != '': - while data.split()[0] != 'END': + # if data != '': + # while data.split()[0] != 'END': + # channels = data.split('"') + # channel_list = channels[1].split(',') + # self.set_outlist(self.fst_vt['outlist']['ElastoDyn'], channel_list) + + # data = f.readline() + # else: + # # there is a blank line between the outlist and the END of the file + # f.readline() + + # Handle the case if there are blank lines before the END statement, check if blank line + while data.split().__len__() == 0: + data = f.readline() + + while data.split()[0] != 'END': + if data.find('"')>=0: channels = data.split('"') channel_list = channels[1].split(',') - self.set_outlist(self.fst_vt['outlist']['ElastoDyn'], channel_list) + else: + row_string = data.split(',') + if len(row_string)==1: + channel_list = row_string[0].split('\n')[0] + else: + channel_list = row_string + self.set_outlist(self.fst_vt['outlist']['ElastoDyn'], channel_list) + data = f.readline() - data = f.readline() - else: - # there is a blank line between the outlist and the END of the file - f.readline() # ElastoDyn optional outlist try: f.readline() @@ -996,10 +1015,11 @@ def read_AeroDyn15(self): f.readline() data = f.readline() - # Handle the case if there are blank lines befroe the END statement, check if blank line + # Handle the case if there are blank lines before the END statement, check if blank line while data.split().__len__() == 0: data = f.readline() + while data.split()[0] != 'END': if data.find('"')>=0: channels = data.split('"') @@ -2513,12 +2533,243 @@ def read_SubDyn(self, sd_file): f.close() + + def read_ExtPtfm(self, ep_file): + # ExtPtfm file based on documentation here: https://openfast.readthedocs.io/en/main/source/user/extptfm/input_files.html + + + '''' + Input file for temp reference: + ---------------------- EXTPTFM INPUT FILE -------------------------------------- + Comment describing the model + ---------------------- SIMULATION CONTROL -------------------------------------- + False Echo - Echo input data to .ech (flag) + "default" DT - Communication interval for controllers (s) (or "default") + 3 IntMethod - Integration Method {1:RK4; 2:AB4, 3:ABM4} (switch) + ---------------------- REDUCTION INPUTS ---------------------------------------- + 1 FileFormat - File Format {0:Guyan; 1:FlexASCII} (switch) + "ExtPtfm_SE.dat" Red_FileName - Path of the file containing Guyan/Craig-Bampton inputs (-) + "NA" RedCst_FileName - Path of the file containing Guyan/Craig-Bampton constant inputs (-) (currently unused) + -1 NActiveDOFList - Number of active CB mode listed in ActiveDOFList, use -1 for all modes (integer) + 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25 ActiveDOFList - List of CB modes index that are active, [unused if NActiveDOFList<=0] + 0 NInitPosList - Number of initial positions listed in InitPosList, using 0 implies all DOF initialized to 0 (integer) + 0, InitPosList - List of initial positions for the CB modes [unused if NInitPosList<=0 or EquilStart=True] + 0 NInitVelList - Number of initial positions listed in InitVelList, using 0 implies all DOF initialized to 0 (integer) + 0, InitVelList - List of initial velocities for the CB modes [unused if NInitVelPosList<=0 or EquilStart=True] + ---------------------- OUTPUT -------------------------------------------------- + True SumPrint - Print summary data to .sum (flag) + 1 OutFile - Switch to determine where output will be placed: {1: in module output file only; 2: in glue code output file only; 3: both} (currently unused) + True TabDelim - Use tab delimiters in text tabular output file? (flag) (currently unused) + "ES10.3E2" OutFmt - Format used for text tabular output (except time). Resulting field should be 10 characters. (quoted string) (currently unused) + 0 TStart - Time to begin tabular output (s) (currently unused) + OutList - The next line(s) contains a list of output parameters. See OutListParameters.xlsx for a listing of available output channels, (-) + "IntrfFx" - Platform interface force - Directed along the x-direction (N) + "IntrfFy" - Platform interface force - Directed along the y-direction (N) + "IntrfFz" - Platform interface force - Directed along the z-direction (N) + "IntrfMx" - Platform interface moment - Directed along the x-direction (Nm) + "IntrfMy" - Platform interface moment - Directed along the y-direction (Nm) + "IntrfMz" - Platform interface moment - Directed along the z-direction (Nm) + "InpF_Fx" - Reduced Input force at interface point - Directed along the x-direction (N) + "InpF_Fy" - Reduced Input force at interface point - Directed along the y-direction (N) + "InpF_Fz" - Reduced Input force at interface point - Directed along the z-direction (N) + "InpF_Mx" - Reduced Input moment at interface point - Directed along the x-direction (Nm) + "InpF_My" - Reduced Input moment at interface point - Directed along the y-direction (Nm) + "InpF_Mz" - Reduced Input moment at interface point - Directed along the z-direction (Nm) + "CBQ_001" - Modal displacement of internal Craig-Bampton mode number XXX (-) + "CBQ_002" - Modal displacement of internal Craig-Bampton mode number XXX (-) + "CBQ_003" - Modal displacement of internal Craig-Bampton mode number XXX (-) + "CBQ_004" - Modal displacement of internal Craig-Bampton mode number XXX (-) + "CBQ_005" - Modal displacement of internal Craig-Bampton mode number XXX (-) + "CBQ_006" - Modal displacement of internal Craig-Bampton mode number XXX (-) + "CBQ_007" - Modal displacement of internal Craig-Bampton mode number XXX (-) + "CBQ_010" - Modal displacement of internal Craig-Bampton mode number XXX (-) + "CBQ_011" - Modal displacement of internal Craig-Bampton mode number XXX (-) + "CBQ_012" - Modal displacement of internal Craig-Bampton mode number XXX (-) + "CBQ_013" - Modal displacement of internal Craig-Bampton mode number XXX (-) + "CBQ_014" - Modal displacement of internal Craig-Bampton mode number XXX (-) + "CBQ_015" - Modal displacement of internal Craig-Bampton mode number XXX (-) + "CBQ_016" - Modal displacement of internal Craig-Bampton mode number XXX (-) + "CBQ_017" - Modal displacement of internal Craig-Bampton mode number XXX (-) + "CBQ_020" - Modal displacement of internal Craig-Bampton mode number XXX (-) + "CBQ_021" - Modal displacement of internal Craig-Bampton mode number XXX (-) + "CBQ_022" - Modal displacement of internal Craig-Bampton mode number XXX (-) + "CBQ_023" - Modal displacement of internal Craig-Bampton mode number XXX (-) + "CBQ_024" - Modal displacement of internal Craig-Bampton mode number XXX (-) + "CBQ_025" - Modal displacement of internal Craig-Bampton mode number XXX (-) + "CBF_001" - Modal force on internal Craig-Bampton mode number XXX (-) + "CBF_002" - Modal force on internal Craig-Bampton mode number XXX (-) + "CBF_003" - Modal force on internal Craig-Bampton mode number XXX (-) + "CBF_004" - Modal force on internal Craig-Bampton mode number XXX (-) + "CBF_005" - Modal force on internal Craig-Bampton mode number XXX (-) + "CBF_006" - Modal force on internal Craig-Bampton mode number XXX (-) + "CBF_007" - Modal force on internal Craig-Bampton mode number XXX (-) + "CBF_010" - Modal force on internal Craig-Bampton mode number XXX (-) + "CBF_011" - Modal force on internal Craig-Bampton mode number XXX (-) + "CBF_012" - Modal force on internal Craig-Bampton mode number XXX (-) + "CBF_013" - Modal force on internal Craig-Bampton mode number XXX (-) + "CBF_014" - Modal force on internal Craig-Bampton mode number XXX (-) + "CBF_015" - Modal force on internal Craig-Bampton mode number XXX (-) + "CBF_016" - Modal force on internal Craig-Bampton mode number XXX (-) + "CBF_017" - Modal force on internal Craig-Bampton mode number XXX (-) + "CBF_020" - Modal force on internal Craig-Bampton mode number XXX (-) + "CBF_021" - Modal force on internal Craig-Bampton mode number XXX (-) + "CBF_022" - Modal force on internal Craig-Bampton mode number XXX (-) + "CBF_023" - Modal force on internal Craig-Bampton mode number XXX (-) + "CBF_024" - Modal force on internal Craig-Bampton mode number XXX (-) + "CBF_025" - Modal force on internal Craig-Bampton mode number XXX (-) + "WavElev" - Wave elevation (m) + END of input file (the word "END" must appear in the first 3 columns of this last OutList line) + --------------------------------------------------------------------------------------- + + ''' + f = open(ep_file) + f.readline() + f.readline() + f.readline() + + # Simulation Control + self.fst_vt['ExtPtfm']['Echo'] = bool_read(f.readline().split()[0]) + self.fst_vt['ExtPtfm']['DT'] = float_read(f.readline().split()[0]) + self.fst_vt['ExtPtfm']['IntMethod'] = int_read(f.readline().split()[0]) + f.readline() + + # Reduction inputs + self.fst_vt['ExtPtfm']['FileFormat'] = int_read(f.readline().split()[0]) + self.fst_vt['ExtPtfm']['Red_FileName'] = os.path.join(os.path.dirname(ep_file), f.readline().split()[0][1:-1]) + self.fst_vt['ExtPtfm']['RedCst_FileName'] = os.path.join(os.path.dirname(ep_file), f.readline().split()[0][1:-1]) + self.fst_vt['ExtPtfm']['NActiveDOFList'] = int_read(f.readline().split()[0]) + self.fst_vt['ExtPtfm']['ActiveDOFList'] = [idx.strip() for idx in f.readline().split('ActiveDOFList')[0].split(',')] + self.fst_vt['ExtPtfm']['NInitPosList'] = int_read(f.readline().split()[0]) + self.fst_vt['ExtPtfm']['InitPosList'] = [idx.strip() for idx in f.readline().split('InitPosList')[0].split(',')] + self.fst_vt['ExtPtfm']['NInitVelList'] = int_read(f.readline().split()[0]) + self.fst_vt['ExtPtfm']['InitVelList'] = [idx.strip() for idx in f.readline().split('InitVelList')[0].split(',')] + f.readline() + + # Output + self.fst_vt['ExtPtfm']['SumPrint'] = bool_read(f.readline().split()[0]) + self.fst_vt['ExtPtfm']['OutFile'] = int_read(f.readline().split()[0]) + self.fst_vt['ExtPtfm']['TabDelim'] = bool_read(f.readline().split()[0]) + self.fst_vt['ExtPtfm']['OutFmt'] = f.readline().split()[0][1:-1] + self.fst_vt['ExtPtfm']['TStart'] = float_read(f.readline().split()[0]) + + # Loop through output channel lines + f.readline() + data = f.readline() + + # Handle the case if there are blank lines before the END statement, check if blank line + while data.split().__len__() == 0: + data = f.readline() + + while data.split()[0] != 'END': + if data.find('"')>=0: + channels = data.split('"') + channel_list = channels[1].split(',') + else: + row_string = data.split(',') + if len(row_string)==1: + channel_list = row_string[0].split('\n')[0] + else: + channel_list = row_string + self.set_outlist(self.fst_vt['outlist']['ExtPtfm'], channel_list) # TODO: Need to figure this out as we dont have a full outlist for now, similar to MoorDyn + data = f.readline() + + if self.fst_vt['ExtPtfm']['FileFormat'] == 0: + self.fst_vt['ExtPtfm']['Guyan'] = {} + # self.read_Guyan(f) # TODO: need to impliment this. An example file not found to test + elif self.fst_vt['ExtPtfm']['FileFormat'] == 1: + self.fst_vt['ExtPtfm']['FlexASCII'] = {} + self.read_Superelement(f) + + f.close() + + + def read_Superelement(self, superelement_file): + f = open(superelement_file) + + lines=f.read().splitlines() + if not detectAndReadExtPtfmSE(lines): + raise NameError('Could not read Superelement file') + + def detectAndReadExtPtfmSE(lines): + # Function based on https://github.com/OpenFAST/openfast_toolbox/blob/353643ed917d113ec8dfd765813fef7d09752757/openfast_toolbox/io/fast_input_file.py#L1932 + # Developed by Emmanuel Branlard (https://github.com/ebranlard) + + def readmat(n,m,lines,iStart): + M=np.zeros((n,m)) + for j in np.arange(n): + i=iStart+j + M[j,:]=np.array(lines[i].split()).astype(float) + return M + + if len(lines)<10: + return False + if not (lines[0][0]=='!' and lines[1][0]=='!'): + return False + if lines[1].lower().find('flex')<0: + return + if lines[2].lower().find('!dimension')<0: + return + + # --- At this stage we assume it's in the proper format + nDOFCommon = -1 + i=2 + try: + while i0: + if l[0]=='!': + if l.find('!dimension')==0: + self.fst_vt['ExtPtfm']['FlexASCII']['nDOF'] = int(l.split(':')[1]) + nDOFCommon = self.fst_vt['ExtPtfm']['FlexASCII']['nDOF'] + elif l.find('!time increment')==0: + self.fst_vt['ExtPtfm']['FlexASCII']['dt'] = float(l.split(':')[1]) + elif l.find('!total simulation time')==0: + self.fst_vt['ExtPtfm']['FlexASCII']['T'] = float(l.split(':')[1]) + elif len(l.strip())==0: + pass + else: + raise NameError('Unexcepted content found on line {}'.format(i)) + i+=1 + except NameError as e: + raise e + except: + raise + + return True + + + def read_MAP(self, map_file): # MAP++ - # TODO: this is likely not robust enough, only tested on the Hywind Spar - # additional lines in these tables are likely - f = open(map_file) f.readline() f.readline() @@ -2920,7 +3171,10 @@ def execute(self): self.read_SeaState(ss_file) sd_file = os.path.normpath(os.path.join(self.FAST_directory, self.fst_vt['Fst']['SubFile'])) if os.path.isfile(sd_file): - self.read_SubDyn(sd_file) + if self.fst_vt['Fst']['CompSub'] == 1: + self.read_SubDyn(sd_file) + elif self.fst_vt['Fst']['CompSub'] == 2: + self.read_ExtPtfm(sd_file) if self.fst_vt['Fst']['CompMooring'] == 1: # only MAP++ implemented for mooring models map_file = os.path.normpath(os.path.join(self.FAST_directory, self.fst_vt['Fst']['MooringFile'])) if os.path.isfile(map_file): diff --git a/openfast_python/openfast_io/FAST_vars_out.py b/openfast_python/openfast_io/FAST_vars_out.py index fe47fa1fc..650e10099 100644 --- a/openfast_python/openfast_io/FAST_vars_out.py +++ b/openfast_python/openfast_io/FAST_vars_out.py @@ -9602,6 +9602,74 @@ MoorDyn['AnchTen8'] = False # (); ; MoorDyn['AnchTen9'] = False # (); ; + + + + +""" ExtPtfm """ +# THIS IS NOT A COMPLETE LIST! +# Need to handle in different way based on documentaion here: https://openfast.readthedocs.io/en/main/source/user/extptfm/input_files.html#output-channels +# TODO: Handle the flexible outputs for ExtPtfm. This will require a different approach than the current dictionary structure. + +ExtPtfm = {} +ExtPtfm['IntrfFx'] = False # - Platform interface force - Directed along the x-direction (N) +ExtPtfm['IntrfFy'] = False # - Platform interface force - Directed along the y-direction (N) +ExtPtfm['IntrfFz'] = False # - Platform interface force - Directed along the z-direction (N) +ExtPtfm['IntrfMx'] = False # - Platform interface moment - Directed along the x-direction (Nm) +ExtPtfm['IntrfMy'] = False # - Platform interface moment - Directed along the y-direction (Nm) +ExtPtfm['IntrfMz'] = False # - Platform interface moment - Directed along the z-direction (Nm) +ExtPtfm['InpF_Fx'] = False # - Reduced Input force at interface point - Directed along the x-direction (N) +ExtPtfm['InpF_Fy'] = False # - Reduced Input force at interface point - Directed along the y-direction (N) +ExtPtfm['InpF_Fz'] = False # - Reduced Input force at interface point - Directed along the z-direction (N) +ExtPtfm['InpF_Mx'] = False # - Reduced Input moment at interface point - Directed along the x-direction (Nm) +ExtPtfm['InpF_My'] = False # - Reduced Input moment at interface point - Directed along the y-direction (Nm) +ExtPtfm['InpF_Mz'] = False # - Reduced Input moment at interface point - Directed along the z-direction (Nm) +ExtPtfm['CBQ_001'] = False # - Modal displacement of internal Craig-Bampton mode number XXX (-) +ExtPtfm['CBQ_002'] = False # - Modal displacement of internal Craig-Bampton mode number XXX (-) +ExtPtfm['CBQ_003'] = False # - Modal displacement of internal Craig-Bampton mode number XXX (-) +ExtPtfm['CBQ_004'] = False # - Modal displacement of internal Craig-Bampton mode number XXX (-) +ExtPtfm['CBQ_005'] = False # - Modal displacement of internal Craig-Bampton mode number XXX (-) +ExtPtfm['CBQ_006'] = False # - Modal displacement of internal Craig-Bampton mode number XXX (-) +ExtPtfm['CBQ_007'] = False # - Modal displacement of internal Craig-Bampton mode number XXX (-) +ExtPtfm['CBQ_010'] = False # - Modal displacement of internal Craig-Bampton mode number XXX (-) +ExtPtfm['CBQ_011'] = False # - Modal displacement of internal Craig-Bampton mode number XXX (-) +ExtPtfm['CBQ_012'] = False # - Modal displacement of internal Craig-Bampton mode number XXX (-) +ExtPtfm['CBQ_013'] = False # - Modal displacement of internal Craig-Bampton mode number XXX (-) +ExtPtfm['CBQ_014'] = False # - Modal displacement of internal Craig-Bampton mode number XXX (-) +ExtPtfm['CBQ_015'] = False # - Modal displacement of internal Craig-Bampton mode number XXX (-) +ExtPtfm['CBQ_016'] = False # - Modal displacement of internal Craig-Bampton mode number XXX (-) +ExtPtfm['CBQ_017'] = False # - Modal displacement of internal Craig-Bampton mode number XXX (-) +ExtPtfm['CBQ_020'] = False # - Modal displacement of internal Craig-Bampton mode number XXX (-) +ExtPtfm['CBQ_021'] = False # - Modal displacement of internal Craig-Bampton mode number XXX (-) +ExtPtfm['CBQ_022'] = False # - Modal displacement of internal Craig-Bampton mode number XXX (-) +ExtPtfm['CBQ_023'] = False # - Modal displacement of internal Craig-Bampton mode number XXX (-) +ExtPtfm['CBQ_024'] = False # - Modal displacement of internal Craig-Bampton mode number XXX (-) +ExtPtfm['CBQ_025'] = False # - Modal displacement of internal Craig-Bampton mode number XXX (-) +ExtPtfm['CBF_001'] = False # - Modal force on internal Craig-Bampton mode number XXX (-) +ExtPtfm['CBF_002'] = False # - Modal force on internal Craig-Bampton mode number XXX (-) +ExtPtfm['CBF_003'] = False # - Modal force on internal Craig-Bampton mode number XXX (-) +ExtPtfm['CBF_004'] = False # - Modal force on internal Craig-Bampton mode number XXX (-) +ExtPtfm['CBF_005'] = False # - Modal force on internal Craig-Bampton mode number XXX (-) +ExtPtfm['CBF_006'] = False # - Modal force on internal Craig-Bampton mode number XXX (-) +ExtPtfm['CBF_007'] = False # - Modal force on internal Craig-Bampton mode number XXX (-) +ExtPtfm['CBF_010'] = False # - Modal force on internal Craig-Bampton mode number XXX (-) +ExtPtfm['CBF_011'] = False # - Modal force on internal Craig-Bampton mode number XXX (-) +ExtPtfm['CBF_012'] = False # - Modal force on internal Craig-Bampton mode number XXX (-) +ExtPtfm['CBF_013'] = False # - Modal force on internal Craig-Bampton mode number XXX (-) +ExtPtfm['CBF_014'] = False # - Modal force on internal Craig-Bampton mode number XXX (-) +ExtPtfm['CBF_015'] = False # - Modal force on internal Craig-Bampton mode number XXX (-) +ExtPtfm['CBF_016'] = False # - Modal force on internal Craig-Bampton mode number XXX (-) +ExtPtfm['CBF_017'] = False # - Modal force on internal Craig-Bampton mode number XXX (-) +ExtPtfm['CBF_020'] = False # - Modal force on internal Craig-Bampton mode number XXX (-) +ExtPtfm['CBF_021'] = False # - Modal force on internal Craig-Bampton mode number XXX (-) +ExtPtfm['CBF_022'] = False # - Modal force on internal Craig-Bampton mode number XXX (-) +ExtPtfm['CBF_023'] = False # - Modal force on internal Craig-Bampton mode number XXX (-) +ExtPtfm['CBF_024'] = False # - Modal force on internal Craig-Bampton mode number XXX (-) +ExtPtfm['CBF_025'] = False # - Modal force on internal Craig-Bampton mode number XXX (-) +ExtPtfm['WavElev'] = False # - Wave elevation (m) + + + """ Final Output Dictionary """ FstOutput = {} FstOutput['AeroDyn'] = AeroDyn @@ -9618,3 +9686,4 @@ FstOutput['BeamDyn_Nodes'] = BeamDyn_Nodes FstOutput['ElastoDyn_Nodes'] = ElastoDyn_Nodes FstOutput['MoorDyn'] = MoorDyn +FstOutput['ExtPtfm'] = ExtPtfm diff --git a/openfast_python/openfast_io/FAST_writer.py b/openfast_python/openfast_io/FAST_writer.py index 12c3014f7..c107033d2 100644 --- a/openfast_python/openfast_io/FAST_writer.py +++ b/openfast_python/openfast_io/FAST_writer.py @@ -182,6 +182,8 @@ def execute(self): self.write_SeaState() if self.fst_vt['Fst']['CompSub'] == 1: self.write_SubDyn() + elif self.fst_vt['Fst']['CompSub'] == 2: + self.write_ExtPtfm() if self.fst_vt['Fst']['CompMooring'] == 1: self.write_MAP() elif self.fst_vt['Fst']['CompMooring'] == 3: @@ -2084,6 +2086,190 @@ def write_SubDyn(self): os.fsync(f) f.close() + def write_ExtPtfm(self): + # Generate ExtPtfm input file + '''' + Input file for temp reference: + ---------------------- EXTPTFM INPUT FILE -------------------------------------- + Comment describing the model + ---------------------- SIMULATION CONTROL -------------------------------------- + False Echo - Echo input data to .ech (flag) + "default" DT - Communication interval for controllers (s) (or "default") + 3 IntMethod - Integration Method {1:RK4; 2:AB4, 3:ABM4} (switch) + ---------------------- REDUCTION INPUTS ---------------------------------------- + 1 FileFormat - File Format {0:Guyan; 1:FlexASCII} (switch) + "ExtPtfm_SE.dat" Red_FileName - Path of the file containing Guyan/Craig-Bampton inputs (-) + "NA" RedCst_FileName - Path of the file containing Guyan/Craig-Bampton constant inputs (-) (currently unused) + -1 NActiveDOFList - Number of active CB mode listed in ActiveDOFList, use -1 for all modes (integer) + 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25 ActiveDOFList - List of CB modes index that are active, [unused if NActiveDOFList<=0] + 0 NInitPosList - Number of initial positions listed in InitPosList, using 0 implies all DOF initialized to 0 (integer) + 0, InitPosList - List of initial positions for the CB modes [unused if NInitPosList<=0 or EquilStart=True] + 0 NInitVelList - Number of initial positions listed in InitVelList, using 0 implies all DOF initialized to 0 (integer) + 0, InitVelList - List of initial velocities for the CB modes [unused if NInitVelPosList<=0 or EquilStart=True] + ---------------------- OUTPUT -------------------------------------------------- + True SumPrint - Print summary data to .sum (flag) + 1 OutFile - Switch to determine where output will be placed: {1: in module output file only; 2: in glue code output file only; 3: both} (currently unused) + True TabDelim - Use tab delimiters in text tabular output file? (flag) (currently unused) + "ES10.3E2" OutFmt - Format used for text tabular output (except time). Resulting field should be 10 characters. (quoted string) (currently unused) + 0 TStart - Time to begin tabular output (s) (currently unused) + OutList - The next line(s) contains a list of output parameters. See OutListParameters.xlsx for a listing of available output channels, (-) + "IntrfFx" - Platform interface force - Directed along the x-direction (N) + "IntrfFy" - Platform interface force - Directed along the y-direction (N) + "IntrfFz" - Platform interface force - Directed along the z-direction (N) + "IntrfMx" - Platform interface moment - Directed along the x-direction (Nm) + "IntrfMy" - Platform interface moment - Directed along the y-direction (Nm) + "IntrfMz" - Platform interface moment - Directed along the z-direction (Nm) + "InpF_Fx" - Reduced Input force at interface point - Directed along the x-direction (N) + "InpF_Fy" - Reduced Input force at interface point - Directed along the y-direction (N) + "InpF_Fz" - Reduced Input force at interface point - Directed along the z-direction (N) + "InpF_Mx" - Reduced Input moment at interface point - Directed along the x-direction (Nm) + "InpF_My" - Reduced Input moment at interface point - Directed along the y-direction (Nm) + "InpF_Mz" - Reduced Input moment at interface point - Directed along the z-direction (Nm) + "CBQ_001" - Modal displacement of internal Craig-Bampton mode number XXX (-) + "CBQ_002" - Modal displacement of internal Craig-Bampton mode number XXX (-) + "CBQ_003" - Modal displacement of internal Craig-Bampton mode number XXX (-) + "CBQ_004" - Modal displacement of internal Craig-Bampton mode number XXX (-) + "CBQ_005" - Modal displacement of internal Craig-Bampton mode number XXX (-) + "CBQ_006" - Modal displacement of internal Craig-Bampton mode number XXX (-) + "CBQ_007" - Modal displacement of internal Craig-Bampton mode number XXX (-) + "CBQ_010" - Modal displacement of internal Craig-Bampton mode number XXX (-) + "CBQ_011" - Modal displacement of internal Craig-Bampton mode number XXX (-) + "CBQ_012" - Modal displacement of internal Craig-Bampton mode number XXX (-) + "CBQ_013" - Modal displacement of internal Craig-Bampton mode number XXX (-) + "CBQ_014" - Modal displacement of internal Craig-Bampton mode number XXX (-) + "CBQ_015" - Modal displacement of internal Craig-Bampton mode number XXX (-) + "CBQ_016" - Modal displacement of internal Craig-Bampton mode number XXX (-) + "CBQ_017" - Modal displacement of internal Craig-Bampton mode number XXX (-) + "CBQ_020" - Modal displacement of internal Craig-Bampton mode number XXX (-) + "CBQ_021" - Modal displacement of internal Craig-Bampton mode number XXX (-) + "CBQ_022" - Modal displacement of internal Craig-Bampton mode number XXX (-) + "CBQ_023" - Modal displacement of internal Craig-Bampton mode number XXX (-) + "CBQ_024" - Modal displacement of internal Craig-Bampton mode number XXX (-) + "CBQ_025" - Modal displacement of internal Craig-Bampton mode number XXX (-) + "CBF_001" - Modal force on internal Craig-Bampton mode number XXX (-) + "CBF_002" - Modal force on internal Craig-Bampton mode number XXX (-) + "CBF_003" - Modal force on internal Craig-Bampton mode number XXX (-) + "CBF_004" - Modal force on internal Craig-Bampton mode number XXX (-) + "CBF_005" - Modal force on internal Craig-Bampton mode number XXX (-) + "CBF_006" - Modal force on internal Craig-Bampton mode number XXX (-) + "CBF_007" - Modal force on internal Craig-Bampton mode number XXX (-) + "CBF_010" - Modal force on internal Craig-Bampton mode number XXX (-) + "CBF_011" - Modal force on internal Craig-Bampton mode number XXX (-) + "CBF_012" - Modal force on internal Craig-Bampton mode number XXX (-) + "CBF_013" - Modal force on internal Craig-Bampton mode number XXX (-) + "CBF_014" - Modal force on internal Craig-Bampton mode number XXX (-) + "CBF_015" - Modal force on internal Craig-Bampton mode number XXX (-) + "CBF_016" - Modal force on internal Craig-Bampton mode number XXX (-) + "CBF_017" - Modal force on internal Craig-Bampton mode number XXX (-) + "CBF_020" - Modal force on internal Craig-Bampton mode number XXX (-) + "CBF_021" - Modal force on internal Craig-Bampton mode number XXX (-) + "CBF_022" - Modal force on internal Craig-Bampton mode number XXX (-) + "CBF_023" - Modal force on internal Craig-Bampton mode number XXX (-) + "CBF_024" - Modal force on internal Craig-Bampton mode number XXX (-) + "CBF_025" - Modal force on internal Craig-Bampton mode number XXX (-) + "WavElev" - Wave elevation (m) + END of input file (the word "END" must appear in the first 3 columns of this last OutList line) + --------------------------------------------------------------------------------------- + + ''' + + if self.fst_vt['ExtPtfm']['FileFormat'] == 0: + None + # self.write_Guyan() # TODO: need to impliment this. An example file not found to test + elif self.fst_vt['ExtPtfm']['FileFormat'] == 1: + self.write_Superelement() + + + self.fst_vt['Fst']['SubFile'] = self.FAST_namingOut + '_ExtPtfm.dat' + ep_file = os.path.join(self.FAST_runDirectory, self.fst_vt['Fst']['SubFile']) + f = open(ep_file, 'w') + + f.write('---------------------- EXTPTFM INPUT FILE --------------------------------------\n') + f.write('Comment describing the model\n') + f.write('---------------------- SIMULATION CONTROL --------------------------------------\n') + f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['ExtPtfm']['Echo'], 'Echo', '- Echo input data to .ech (flag)\n')) + f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['ExtPtfm']['DT'], 'DT', '- Communication interval for controllers (s) (or "default")\n')) + f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['ExtPtfm']['IntMethod'], 'IntMethod', '- Integration Method {1:RK4; 2:AB4, 3:ABM4} (switch)\n')) + f.write('---------------------- REDUCTION INPUTS ----------------------------------------\n') + f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['ExtPtfm']['FileFormat'], 'FileFormat', '- File Format {0:Guyan; 1:FlexASCII} (switch)\n')) + f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['ExtPtfm']['Red_FileName'], 'Red_FileName', '- Path of the file containing Guyan/Craig-Bampton inputs (-)\n')) + f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['ExtPtfm']['RedCst_FileName'], 'RedCst_FileName', '- Path of the file containing Guyan/Craig-Bampton constant inputs (-) (currently unused)\n')) + f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['ExtPtfm']['NActiveDOFList'], 'NActiveDOFList', '- Number of active CB mode listed in ActiveDOFList, use -1 for all modes (integer)\n')) + # f.write('{:<22} {:<11} {:}'.format(", ".join([str(i) for i in self.fst_vt['ExtPtfm']['ActiveDOFList']]), 'ActiveDOFList', '- List of CB modes index that are active, [unused if NActiveDOFList<=0]\n')) + if self.fst_vt['ExtPtfm']['NActiveDOFList'] > -1: + f.write('{:<22} {:<11} {:}'.format(', '.join(self.fst_vt['ExtPtfm']['ActiveDOFList'][:self.fst_vt['ExtPtfm']['NActiveDOFList']]), 'ActiveDOFList', '- List of CB modes index that are active, [unused if NActiveDOFList<=0]\n')) + else: + f.write('{:<22} {:<11} {:}'.format(', '.join(self.fst_vt['ExtPtfm']['ActiveDOFList']), 'ActiveDOFList', '- List of CB modes index that are active, [unused if NActiveDOFList<=0]\n')) + f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['ExtPtfm']['NInitPosList'], 'NInitPosList', '- Number of initial positions listed in InitPosList, using 0 implies all DOF initialized to 0 (integer)\n')) + if self.fst_vt['ExtPtfm']['NInitPosList'] > 0: + f.write('{:<22} {:<11} {:}'.format(', '.join(self.fst_vt['ExtPtfm']['InitPosList'][:self.fst_vt['ExtPtfm']['NInitPosList']]), 'InitPosList', '- List of initial positions for the CB modes [unused if NInitPosList<=0 or EquilStart=True]\n')) + else: + f.write('{:<22d} {:<11} {:}'.format(0, 'InitPosList', '- List of initial positions for the CB modes [unused if NInitPosList<=0 or EquilStart=True]\n')) + f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['ExtPtfm']['NInitVelList'], 'NInitVelList', '- Number of initial positions listed in InitVelList, using 0 implies all DOF initialized to 0 (integer)\n')) + if self.fst_vt['ExtPtfm']['NInitVelList'] > 0: + f.write('{:<22} {:<11} {:}'.format(', '.join(self.fst_vt['ExtPtfm']['InitVelList'][:self.fst_vt['ExtPtfm']['NInitVelList']]), 'InitVelList', '- List of initial velocities for the CB modes [unused if NInitVelPosList<=0 or EquilStart=True]\n')) + else: + f.write('{:<22d} {:<11} {:}'.format(0, 'InitVelList', '- List of initial velocities for the CB modes [unused if NInitVelPosList<=0 or EquilStart=True]\n')) + + f.write('---------------------- OUTPUT --------------------------------------------------\n') + f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['ExtPtfm']['SumPrint'], 'SumPrint', '- Print summary data to .sum (flag)\n')) + f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['ExtPtfm']['OutFile'], 'OutFile', '- Switch to determine where output will be placed: {1: in module output file only; 2: in glue code output file only; 3: both} (currently unused)\n')) + f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['ExtPtfm']['TabDelim'], 'TabDelim', '- Use tab delimiters in text tabular output file? (flag) (currently unused)\n')) + f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['ExtPtfm']['OutFmt'], 'OutFmt', '- Format used for text tabular output (except time). Resulting field should be 10 characters. (quoted string) (currently unused)\n')) + f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['ExtPtfm']['TStart'], 'TStart', '- Time to begin tabular output (s) (currently unused)\n')) + f.write(' OutList - The next line(s) contains a list of output parameters. See OutListParameters.xlsx for a listing of available output channels, (-)\n') + outlist = self.get_outlist(self.fst_vt['outlist'], ['ExtPtfm']) + + for channel_list in outlist: + for i in range(len(channel_list)): + f.write('"' + channel_list[i] + '"\n') + f.write('END of input file (the word "END" must appear in the first 3 columns of this last OutList line)\n') + f.flush() + os.fsync(f) + f.close() + + + + def write_Superelement(self): + + # Generate Superelement input file + self.fst_vt['ExtPtfm']['Red_FileName'] = self.FAST_namingOut + '_ExtPtfm_SE.dat' + se_file = os.path.join(self.FAST_runDirectory, self.fst_vt['ExtPtfm']['Red_FileName']) + f = open(se_file, 'w') + + f.write(toString()) + + def toString(self): + # Function based on https://github.com/OpenFAST/openfast_toolbox/blob/353643ed917d113ec8dfd765813fef7d09752757/openfast_toolbox/io/fast_input_file.py#L2034 + # Developed by Emmanuel Branlard (https://github.com/ebranlard) + s='' + s+='!Comment\n' + s+='!Comment Flex 5 Format\n' + s+='!Dimension: {}\n'.format(self.fst_vt['ExtPtfm']['FlexASCII']['nDOF']) + s+='!Time increment in simulation: {}\n'.format(self.fst_vt['ExtPtfm']['FlexASCII']['dt']) + s+='!Total simulation time in file: {}\n'.format(self.fst_vt['ExtPtfm']['FlexASCII']['T']) + + s+='\n!Mass Matrix\n' + s+='!Dimension: {}\n'.format(self.fst_vt['ExtPtfm']['FlexASCII']['nDOF']) + s+='\n'.join(''.join('{:16.8e}'.format(x) for x in y) for y in self.fst_vt['ExtPtfm']['FlexASCII']['MassMatrix']) + + s+='\n\n!Stiffness Matrix\n' + s+='!Dimension: {}\n'.format(self.fst_vt['ExtPtfm']['FlexASCII']['nDOF']) + s+='\n'.join(''.join('{:16.8e}'.format(x) for x in y) for y in self.fst_vt['ExtPtfm']['FlexASCII']['StiffnessMatrix']) + + s+='\n\n!Damping Matrix\n' + s+='!Dimension: {}\n'.format(self.fst_vt['ExtPtfm']['FlexASCII']['nDOF']) + s+='\n'.join(''.join('{:16.8e}'.format(x) for x in y) for y in self.fst_vt['ExtPtfm']['FlexASCII']['DampingMatrix']) + + s+='\n\n!Loading and Wave Elevation\n' + s+='!Dimension: 1 time column - {} force columns\n'.format(self.fst_vt['ExtPtfm']['FlexASCII']['nDOF']) + s+='\n'.join(''.join('{:16.8e}'.format(x) for x in y) for y in self.fst_vt['ExtPtfm']['FlexASCII']['Loading']) + return s + + f.flush() + os.fsync(f) + f.close() + def write_MAP(self): # Generate MAP++ input file From 847d5ab8a00de6e2e94555ecff067a18659eb4d4 Mon Sep 17 00:00:00 2001 From: Mayank Chetan Date: Tue, 6 Aug 2024 21:38:05 +0000 Subject: [PATCH 009/161] squashed bugs in ExpPtfm --- openfast_python/openfast_io/FAST_reader.py | 15 ++++---- openfast_python/openfast_io/FAST_writer.py | 43 +++++++++++----------- 2 files changed, 30 insertions(+), 28 deletions(-) diff --git a/openfast_python/openfast_io/FAST_reader.py b/openfast_python/openfast_io/FAST_reader.py index a5e6d0fdc..345a59895 100644 --- a/openfast_python/openfast_io/FAST_reader.py +++ b/openfast_python/openfast_io/FAST_reader.py @@ -2678,17 +2678,13 @@ def read_ExtPtfm(self, ep_file): # self.read_Guyan(f) # TODO: need to impliment this. An example file not found to test elif self.fst_vt['ExtPtfm']['FileFormat'] == 1: self.fst_vt['ExtPtfm']['FlexASCII'] = {} - self.read_Superelement(f) + self.read_Superelement(self.fst_vt['ExtPtfm']['Red_FileName']) f.close() def read_Superelement(self, superelement_file): - f = open(superelement_file) - - lines=f.read().splitlines() - if not detectAndReadExtPtfmSE(lines): - raise NameError('Could not read Superelement file') + def detectAndReadExtPtfmSE(lines): # Function based on https://github.com/OpenFAST/openfast_toolbox/blob/353643ed917d113ec8dfd765813fef7d09752757/openfast_toolbox/io/fast_input_file.py#L1932 @@ -2764,8 +2760,13 @@ def readmat(n,m,lines,iStart): raise return True + - + f = open(superelement_file) + lines=f.read().splitlines() + if not detectAndReadExtPtfmSE(lines): + raise NameError('Could not read Superelement file') + f.close() def read_MAP(self, map_file): # MAP++ diff --git a/openfast_python/openfast_io/FAST_writer.py b/openfast_python/openfast_io/FAST_writer.py index c107033d2..f85bbc807 100644 --- a/openfast_python/openfast_io/FAST_writer.py +++ b/openfast_python/openfast_io/FAST_writer.py @@ -157,7 +157,8 @@ def execute(self): self.write_ElastoDynTower() self.write_ElastoDyn() # self.write_WindWnd() - self.write_InflowWind() + if self.fst_vt['Fst']['CompInflow'] == 1: + self.write_InflowWind() if self.fst_vt['Fst']['CompAero'] == 1: self.write_AeroDyn14() elif self.fst_vt['Fst']['CompAero'] == 2: @@ -2216,7 +2217,7 @@ def write_ExtPtfm(self): f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['ExtPtfm']['OutFile'], 'OutFile', '- Switch to determine where output will be placed: {1: in module output file only; 2: in glue code output file only; 3: both} (currently unused)\n')) f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['ExtPtfm']['TabDelim'], 'TabDelim', '- Use tab delimiters in text tabular output file? (flag) (currently unused)\n')) f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['ExtPtfm']['OutFmt'], 'OutFmt', '- Format used for text tabular output (except time). Resulting field should be 10 characters. (quoted string) (currently unused)\n')) - f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['ExtPtfm']['TStart'], 'TStart', '- Time to begin tabular output (s) (currently unused)\n')) + f.write('{:<22f} {:<11} {:}'.format(self.fst_vt['ExtPtfm']['TStart'], 'TStart', '- Time to begin tabular output (s) (currently unused)\n')) f.write(' OutList - The next line(s) contains a list of output parameters. See OutListParameters.xlsx for a listing of available output channels, (-)\n') outlist = self.get_outlist(self.fst_vt['outlist'], ['ExtPtfm']) @@ -2232,40 +2233,40 @@ def write_ExtPtfm(self): def write_Superelement(self): - # Generate Superelement input file - self.fst_vt['ExtPtfm']['Red_FileName'] = self.FAST_namingOut + '_ExtPtfm_SE.dat' - se_file = os.path.join(self.FAST_runDirectory, self.fst_vt['ExtPtfm']['Red_FileName']) - f = open(se_file, 'w') - - f.write(toString()) - - def toString(self): + def toString(SuperElement): # Function based on https://github.com/OpenFAST/openfast_toolbox/blob/353643ed917d113ec8dfd765813fef7d09752757/openfast_toolbox/io/fast_input_file.py#L2034 # Developed by Emmanuel Branlard (https://github.com/ebranlard) s='' s+='!Comment\n' s+='!Comment Flex 5 Format\n' - s+='!Dimension: {}\n'.format(self.fst_vt['ExtPtfm']['FlexASCII']['nDOF']) - s+='!Time increment in simulation: {}\n'.format(self.fst_vt['ExtPtfm']['FlexASCII']['dt']) - s+='!Total simulation time in file: {}\n'.format(self.fst_vt['ExtPtfm']['FlexASCII']['T']) + s+='!Dimension: {}\n'.format(SuperElement['nDOF']) + s+='!Time increment in simulation: {}\n'.format(SuperElement['dt']) + s+='!Total simulation time in file: {}\n'.format(SuperElement['T']) s+='\n!Mass Matrix\n' - s+='!Dimension: {}\n'.format(self.fst_vt['ExtPtfm']['FlexASCII']['nDOF']) - s+='\n'.join(''.join('{:16.8e}'.format(x) for x in y) for y in self.fst_vt['ExtPtfm']['FlexASCII']['MassMatrix']) + s+='!Dimension: {}\n'.format(SuperElement['nDOF']) + s+='\n'.join(''.join('{:16.8e}'.format(x) for x in y) for y in SuperElement['MassMatrix']) s+='\n\n!Stiffness Matrix\n' - s+='!Dimension: {}\n'.format(self.fst_vt['ExtPtfm']['FlexASCII']['nDOF']) - s+='\n'.join(''.join('{:16.8e}'.format(x) for x in y) for y in self.fst_vt['ExtPtfm']['FlexASCII']['StiffnessMatrix']) + s+='!Dimension: {}\n'.format(SuperElement['nDOF']) + s+='\n'.join(''.join('{:16.8e}'.format(x) for x in y) for y in SuperElement['StiffnessMatrix']) s+='\n\n!Damping Matrix\n' - s+='!Dimension: {}\n'.format(self.fst_vt['ExtPtfm']['FlexASCII']['nDOF']) - s+='\n'.join(''.join('{:16.8e}'.format(x) for x in y) for y in self.fst_vt['ExtPtfm']['FlexASCII']['DampingMatrix']) + s+='!Dimension: {}\n'.format(SuperElement['nDOF']) + s+='\n'.join(''.join('{:16.8e}'.format(x) for x in y) for y in SuperElement['DampingMatrix']) s+='\n\n!Loading and Wave Elevation\n' - s+='!Dimension: 1 time column - {} force columns\n'.format(self.fst_vt['ExtPtfm']['FlexASCII']['nDOF']) - s+='\n'.join(''.join('{:16.8e}'.format(x) for x in y) for y in self.fst_vt['ExtPtfm']['FlexASCII']['Loading']) + s+='!Dimension: 1 time column - {} force columns\n'.format(SuperElement['nDOF']) + s+='\n'.join(''.join('{:16.8e}'.format(x) for x in y) for y in SuperElement['Loading']) return s + # Generate Superelement input file + self.fst_vt['ExtPtfm']['Red_FileName'] = self.FAST_namingOut + '_ExtPtfm_SE.dat' + se_file = os.path.join(self.FAST_runDirectory, self.fst_vt['ExtPtfm']['Red_FileName']) + f = open(se_file, 'w') + + f.write(toString(self.fst_vt['ExtPtfm']['FlexASCII'])) + f.flush() os.fsync(f) f.close() From 93eeaa47e439696785e7435bdc050d58843ad675 Mon Sep 17 00:00:00 2001 From: Mayank Chetan Date: Tue, 6 Aug 2024 22:07:29 +0000 Subject: [PATCH 010/161] squashed bugs in inflow, ad15, olaf --- openfast_python/openfast_io/FAST_reader.py | 10 +++++----- openfast_python/openfast_io/FAST_writer.py | 18 +++++++++--------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/openfast_python/openfast_io/FAST_reader.py b/openfast_python/openfast_io/FAST_reader.py index 345a59895..7c076396b 100644 --- a/openfast_python/openfast_io/FAST_reader.py +++ b/openfast_python/openfast_io/FAST_reader.py @@ -774,9 +774,9 @@ def read_InflowWind(self): self.fst_vt['InflowWind']['VFlowAng'] = float_read(f.readline().split()[0]) self.fst_vt['InflowWind']['VelInterpCubic'] = bool_read(f.readline().split()[0]) self.fst_vt['InflowWind']['NWindVel'] = int(f.readline().split()[0]) - self.fst_vt['InflowWind']['WindVxiList'] = float_read(f.readline().split()[0]) - self.fst_vt['InflowWind']['WindVyiList'] = float_read(f.readline().split()[0]) - self.fst_vt['InflowWind']['WindVziList'] = float_read(f.readline().split()[0]) + self.fst_vt['InflowWind']['WindVxiList'] = [idx.strip() for idx in f.readline().split('WindVxiList')[0].split(',')] + self.fst_vt['InflowWind']['WindVyiList'] = [idx.strip() for idx in f.readline().split('WindVyiList')[0].split(',')] + self.fst_vt['InflowWind']['WindVziList'] = [idx.strip() for idx in f.readline().split('WindVziList')[0].split(',')] # Parameters for Steady Wind Conditions [used only for WindType = 1] (steady_wind_params) f.readline() @@ -928,7 +928,7 @@ def read_AeroDyn15(self): # Olaf -- cOnvecting LAgrangian Filaments (Free Vortex Wake) Theory Options f.readline() - self.fst_vt['AeroDyn15']['OLAFInputFileName'] = f.readline().split()[0] + self.fst_vt['AeroDyn15']['OLAFInputFileName'] = f.readline().split()[0][1:-1] # Beddoes-Leishman Unsteady Airfoil Aerodynamics Options f.readline() @@ -1227,7 +1227,7 @@ def read_AeroDyn15OLAF(self, olaf_filename): self.fst_vt['AeroDyn15']['OLAF']['CircSolvConvCrit'] = float_read(f.readline().split()[0]) self.fst_vt['AeroDyn15']['OLAF']['CircSolvRelaxation'] = float_read(f.readline().split()[0]) self.fst_vt['AeroDyn15']['OLAF']['CircSolvMaxIter'] = int_read(f.readline().split()[0]) - self.fst_vt['AeroDyn15']['OLAF']['PrescribedCircFile'] = f.readline().split()[0] + self.fst_vt['AeroDyn15']['OLAF']['PrescribedCircFile'] = os.path.join(self.FAST_directory, f.readline().split()[0]) # unmodified by this script, hence pointing to absolute location f.readline() f.readline() f.readline() diff --git a/openfast_python/openfast_io/FAST_writer.py b/openfast_python/openfast_io/FAST_writer.py index f85bbc807..0f566d07a 100644 --- a/openfast_python/openfast_io/FAST_writer.py +++ b/openfast_python/openfast_io/FAST_writer.py @@ -702,9 +702,9 @@ def write_InflowWind(self): f.write('{:<22} {:<11} {:}'.format(self.fst_vt['InflowWind']['VFlowAng'], 'VFlowAng', '- Upflow angle (degrees) (not used for native Bladed format WindType=7)\n')) f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['InflowWind']['VelInterpCubic'], 'VelInterpCubic', '- Use cubic interpolation for velocity in time (false=linear, true=cubic) [Used with WindType=2,3,4,5,7]\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['InflowWind']['NWindVel'], 'NWindVel', '- Number of points to output the wind velocity (0 to 9)\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['InflowWind']['WindVxiList'], 'WindVxiList', '- List of coordinates in the inertial X direction (m)\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['InflowWind']['WindVyiList'], 'WindVyiList', '- List of coordinates in the inertial Y direction (m)\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['InflowWind']['WindVziList'], 'WindVziList', '- List of coordinates in the inertial Z direction (m)\n')) + f.write('{:<22} {:<11} {:}'.format(', '.join(self.fst_vt['InflowWind']['WindVxiList']), 'WindVxiList', '- List of coordinates in the inertial X direction (m)\n')) + f.write('{:<22} {:<11} {:}'.format(', '.join(self.fst_vt['InflowWind']['WindVyiList']), 'WindVyiList', '- List of coordinates in the inertial Y direction (m)\n')) + f.write('{:<22} {:<11} {:}'.format(', '.join(self.fst_vt['InflowWind']['WindVziList']), 'WindVziList', '- List of coordinates in the inertial Z direction (m)\n')) f.write('================== Parameters for Steady Wind Conditions [used only for WindType = 1] =========================\n') f.write('{:<22} {:<11} {:}'.format(self.fst_vt['InflowWind']['HWindSpeed'], 'HWindSpeed', '- Horizontal windspeed (m/s)\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['InflowWind']['RefHt'], 'RefHt', '- Reference height for horizontal wind speed (m)\n')) @@ -782,12 +782,12 @@ def write_AeroDyn15(self): self.write_AeroDyn15Polar() # Generate AeroDyn v15 airfoil coordinates - if self.fst_vt['AeroDyn15']['af_data'][1][0]['NumCoords'] != '0': + if self.fst_vt['AeroDyn15']['af_data'][0][0]['NumCoords'] != '0': # changing from ['af_data'][1] to ['af_data'][0] because we can have a single airfoil too. self.write_AeroDyn15Coord() if self.fst_vt['AeroDyn15']['WakeMod'] == 3: - if self.fst_vt['AeroDyn15']['AFAeroMod'] == 2: - raise Exception('OLAF is called with unsteady airfoil aerodynamics, but OLAF currently only supports AFAeroMod == 1') + if self.fst_vt['AeroDyn15']['UAMod'] == 2: + raise Exception('OLAF is called with unsteady airfoil aerodynamics, but OLAF currently only supports UAMod == 1') #TODO: need to check if this holds true now self.write_OLAF() # Generate AeroDyn v15.03 input file @@ -815,7 +815,7 @@ def write_AeroDyn15(self): f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['Patm'], 'Patm', '- Atmospheric pressure (Pa) [used only when CavitCheck=True]\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['Pvap'], 'Pvap', '- Vapour pressure of fluid (Pa) [used only when CavitCheck=True]\n')) f.write('====== Blade-Element/Momentum Theory Options ====================================================== [unused when WakeMod=0 or 3]\n') - f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['WakeMod'], 'BEM_Mod', '- BEM model {1=legacy NoSweepPitchTwist, 2=polar} (switch) [used for all Wake_Mod to determine output coordinate system]\n')) + f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['BEM_Mod'], 'BEM_Mod', '- BEM model {1=legacy NoSweepPitchTwist, 2=polar} (switch) [used for all Wake_Mod to determine output coordinate system]\n')) f.write('--- Skew correction\n') f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['SkewMod'], 'SkewMod', '- Type of skewed-wake correction model (switch) {1=uncoupled, 2=Pitt/Peters, 3=coupled} [unused when WakeMod=0 or 3]\n')) f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['SkewMomCorr'], 'SkewMomCorr', '- Turn the skew momentum correction on or off [used only when Skew_Mod=1]\n')) @@ -1276,9 +1276,9 @@ def write_OLAF(self): f.write('--------------------------- WAKE OPTIONS ------------------------------------------------------\n') f.write('------------------- WAKE EXTENT AND DISCRETIZATION --------------------------------------------\n') f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['OLAF']['nNWPanels'], 'nNWPanels','- Number of near-wake panels (-)\n')) - f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['OLAF']['nNWPanelsFree'], 'nNWPanelsFree','- Number of free near-wake panels (-) {default: nNWPanels}\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['OLAF']['nNWPanelsFree'], 'nNWPanelsFree','- Number of free near-wake panels (-) {default: nNWPanels}\n')) f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['OLAF']['nFWPanels'], 'nFWPanels','- Number of far-wake panels (-) {default: 0}\n')) - f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['OLAF']['nFWPanelsFree'], 'nFWPanelsFree','- Number of free far-wake panels (-) {default: nFWPanels}\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['OLAF']['nFWPanelsFree'], 'nFWPanelsFree','- Number of free far-wake panels (-) {default: nFWPanels}\n')) f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['OLAF']['FWShedVorticity'], 'FWShedVorticity','- Include shed vorticity in the far wake {default: False}\n')) f.write('------------------- WAKE REGULARIZATIONS AND DIFFUSION -----------------------------------------\n') f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['OLAF']['DiffusionMethod'], 'DiffusionMethod','- Diffusion method to account for viscous effects {0: None, 1: Core Spreading, "default": 0}\n')) From c73c16e55196a511509b9625170e8b5ccede0d85 Mon Sep 17 00:00:00 2001 From: Mayank Chetan Date: Wed, 7 Aug 2024 05:23:18 +0000 Subject: [PATCH 011/161] Abs paths to aux files --- openfast_python/openfast_io/FAST_reader.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/openfast_python/openfast_io/FAST_reader.py b/openfast_python/openfast_io/FAST_reader.py index 7c076396b..a383e96f7 100644 --- a/openfast_python/openfast_io/FAST_reader.py +++ b/openfast_python/openfast_io/FAST_reader.py @@ -414,7 +414,7 @@ def read_ElastoDyn(self, ed_file): # Furling (furling) f.readline() self.fst_vt['ElastoDyn']['Furling'] = bool_read(f.readline().split()[0]) - self.fst_vt['ElastoDyn']['FurlFile'] = f.readline().split()[0][1:-1] + self.fst_vt['ElastoDyn']['FurlFile'] = os.path.join(self.FAST_directory, f.readline().split()[0][1:-1]) # TODO: add furl file data to fst_vt, pointing to absolute path for now # Tower (tower) f.readline() @@ -1717,7 +1717,8 @@ def read_StC(self,filename): StC_vt['rho_Y'] = float_read(f.readline().split()[0]) # 1000 rho_Y - Y TLCD liquid density (kg/m^3) f.readline() # PRESCRIBED TIME SERIES StC_vt['PrescribedForcesCoord'] = int_read(f.readline().split()[0]) # 2 PrescribedForcesCoord- Prescribed forces are in global or local coordinates (switch) {1: global; 2: local} - StC_vt['PrescribedForcesFile'] = f.readline().split()[0] # "Bld-TimeForceSeries.dat" PrescribedForcesFile - Time series force and moment (7 columns of time, FX, FY, FZ, MX, MY, MZ) + # TODO: read in prescribed force time series, for now we just point to absolute path of input file + StC_vt['PrescribedForcesFile'] = os.path.join(self.FAST_directory, f.readline().split()[0][1:-1]) # "Bld-TimeForceSeries.dat" PrescribedForcesFile - Time series force and moment (7 columns of time, FX, FY, FZ, MX, MY, MZ) f.readline() return StC_vt From 9303fd50995a05e9594326c39f7347c1d80bd545 Mon Sep 17 00:00:00 2001 From: Mayank Chetan Date: Wed, 7 Aug 2024 06:09:41 +0000 Subject: [PATCH 012/161] adding double quotes to PrescribedCircFile --- openfast_python/openfast_io/FAST_reader.py | 2 +- openfast_python/openfast_io/FAST_writer.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/openfast_python/openfast_io/FAST_reader.py b/openfast_python/openfast_io/FAST_reader.py index a383e96f7..225f7e13e 100644 --- a/openfast_python/openfast_io/FAST_reader.py +++ b/openfast_python/openfast_io/FAST_reader.py @@ -1227,7 +1227,7 @@ def read_AeroDyn15OLAF(self, olaf_filename): self.fst_vt['AeroDyn15']['OLAF']['CircSolvConvCrit'] = float_read(f.readline().split()[0]) self.fst_vt['AeroDyn15']['OLAF']['CircSolvRelaxation'] = float_read(f.readline().split()[0]) self.fst_vt['AeroDyn15']['OLAF']['CircSolvMaxIter'] = int_read(f.readline().split()[0]) - self.fst_vt['AeroDyn15']['OLAF']['PrescribedCircFile'] = os.path.join(self.FAST_directory, f.readline().split()[0]) # unmodified by this script, hence pointing to absolute location + self.fst_vt['AeroDyn15']['OLAF']['PrescribedCircFile'] = os.path.join(self.FAST_directory, f.readline().split()[0][1:-1]) # unmodified by this script, hence pointing to absolute location f.readline() f.readline() f.readline() diff --git a/openfast_python/openfast_io/FAST_writer.py b/openfast_python/openfast_io/FAST_writer.py index 0f566d07a..e195c9161 100644 --- a/openfast_python/openfast_io/FAST_writer.py +++ b/openfast_python/openfast_io/FAST_writer.py @@ -1271,7 +1271,7 @@ def write_OLAF(self): f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['OLAF']['CircSolvConvCrit'], 'CircSolvConvCrit', ' - Convergence criteria {default: 0.001} [only if CircSolvMethod=1] (-)\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['OLAF']['CircSolvRelaxation'], 'CircSolvRelaxation', '- Relaxation factor {default: 0.1} [only if CircSolvMethod=1] (-)\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['OLAF']['CircSolvMaxIter'], 'CircSolvMaxIter', ' - Maximum number of iterations for circulation solving {default: 30} (-)\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['OLAF']['PrescribedCircFile'], 'PrescribedCircFile','- File containing prescribed circulation [only if CircSolvMethod=3] (quoted string)\n')) + f.write('{:<22} {:<11} {:}'.format('"'+self.fst_vt['AeroDyn15']['OLAF']['PrescribedCircFile']+'"', 'PrescribedCircFile','- File containing prescribed circulation [only if CircSolvMethod=3] (quoted string)\n')) f.write('===============================================================================================\n') f.write('--------------------------- WAKE OPTIONS ------------------------------------------------------\n') f.write('------------------- WAKE EXTENT AND DISCRETIZATION --------------------------------------------\n') From 72d2f73342f4106f9b9fa5d7a1db8c18a4d31f82 Mon Sep 17 00:00:00 2001 From: Mayank Chetan Date: Wed, 7 Aug 2024 13:45:32 +0000 Subject: [PATCH 013/161] pytest to exercise most OpenFAST modules --- .../openfast_io/test/test_of_io_pytest.py | 157 ++++++++++++++++++ 1 file changed, 157 insertions(+) create mode 100644 openfast_python/openfast_io/test/test_of_io_pytest.py diff --git a/openfast_python/openfast_io/test/test_of_io_pytest.py b/openfast_python/openfast_io/test/test_of_io_pytest.py new file mode 100644 index 000000000..da2e91fa4 --- /dev/null +++ b/openfast_python/openfast_io/test/test_of_io_pytest.py @@ -0,0 +1,157 @@ +import pytest +import os.path as osp +import subprocess, sys +import platform + +from openfast_io.FAST_reader import InputReader_OpenFAST +from openfast_io.FAST_writer import InputWriter_OpenFAST +from openfast_io.FAST_output_reader import FASTOutputFile + +from openfast_io.FileTools import check_rtest_cloned +from pathlib import Path + +REPOSITORY_ROOT = osp.dirname(osp.dirname(osp.dirname(osp.dirname(__file__)))) +RTESTS_DIR = osp.join(REPOSITORY_ROOT, "reg_tests","r-test") +TEST_DATA_DIR = osp.join(RTESTS_DIR, "glue-codes", "openfast") + +RUN_DIR = osp.join(REPOSITORY_ROOT, "build_ofio", "testSuite") +Path(RUN_DIR).mkdir(parents=True, exist_ok=True) + + +# Exercising the various OpenFAST modules +FOLDERS_TO_RUN = [ + "5MW_Land_DLL_WTurb" , # "openfast;elastodyn;aerodyn15;servodyn") + "5MW_OC3Mnpl_DLL_WTurb_WavesIrr" , # "openfast;elastodyn;aerodyn15;servodyn;hydrodyn;subdyn;offshore") + "5MW_OC3Mnpl_DLL_WTurb_WavesIrr_Restart", # "openfast;elastodyn;aerodyn15;servodyn;hydrodyn;subdyn;offshore;restart") + "5MW_ITIBarge_DLL_WTurb_WavesIrr" , # "openfast;elastodyn;aerodyn15;servodyn;hydrodyn;map;offshore") + "5MW_OC4Semi_WSt_WavesWN" , # "openfast;elastodyn;aerodyn15;servodyn;hydrodyn;moordyn;offshore") + "5MW_Land_BD_DLL_WTurb" , # "openfast;beamdyn;aerodyn15;servodyn") + "5MW_OC4Jckt_ExtPtfm" , # "openfast;elastodyn;extptfm") + "HelicalWake_OLAF" , # "openfast;aerodyn15;olaf") + "StC_test_OC4Semi" , # "openfast;servodyn;hydrodyn;moordyn;offshore;stc") + "MHK_RM1_Fixed" , # "openfast;elastodyn;aerodyn15;mhk") + "MHK_RM1_Floating" , # "openfast;elastodyn;aerodyn15;hydrodyn;moordyn;mhk") + "Tailfin_FreeYaw1DOF_PolarBased" , # "openfast;elastodyn;aerodyn15") +] + +# looking up OS for the correct executable extension +mactype = platform.system().lower() +if mactype in ["linux", "linux2", "darwin"]: + exeExt = "" +elif mactype in ["win32", "windows", "cygwin"]: #NOTE: platform.system()='Windows', sys.platform='win32' + libext = '.exe' +else: + raise ValueError('Unknown platform type: '+mactype) + +# Path to the OpenFAST executable +of_path = osp.join(REPOSITORY_ROOT,"build/glue-codes/openfast",f"openfast{exeExt}") + + +def read_action(folder): + print(f"Reading from {folder}") + + # Read input deck + fast_reader = InputReader_OpenFAST() + fast_reader.FAST_InputFile = f'{folder}.fst' # FAST input file (ext=.fst) + fast_reader.FAST_directory = osp.join(TEST_DATA_DIR, folder) # Path to fst directory files + fast_reader.execute() + + return fast_reader.fst_vt + + + +def write_action(folder, fst_vt): + print(f"Writing to {folder}, with TMax = 2.0") + + fast_writer = InputWriter_OpenFAST() + fast_writer.FAST_runDirectory = osp.join(RUN_DIR,folder) + Path(fast_writer.FAST_runDirectory).mkdir(parents=True, exist_ok=True) + fast_writer.FAST_namingOut = folder + + fast_writer.fst_vt = dict(fst_vt) + fst_vt = {} + fst_vt['Fst', 'TMax'] = 2. + fst_vt['Fst','OutFileFmt'] = 3 + fast_writer.update(fst_update=fst_vt) + fast_writer.execute() + +def run_action(folder): + # Placeholder for the actual run action + print(f"Running simulation for {folder}") + subprocess.run([of_path, str(osp.join(RUN_DIR, folder, f"{folder}.fst"))], check=True) + +def check_ascii_out(folder): + # Placeholder for the actual check action + print(f"Checking ASCII output for {folder}") + asciiOutput = osp.join(RUN_DIR, folder, f"{folder}.out") + fast_outout = FASTOutputFile(filename=asciiOutput) + +def check_binary_out(folder): + # Placeholder for the actual check action + print(f"Checking binary output for {folder}") + binaryOutput = osp.join(RUN_DIR, folder, f"{folder}.outb") + fast_outout = FASTOutputFile(filename=binaryOutput) + +# Begining of the test +def test_rtest_cloned(): + if check_rtest_cloned(TEST_DATA_DIR): + assert True, "R-tests cloned properly" + else:# stop the test if the r-tests are not cloned properly + print("R-tests not cloned properly") + sys.exit(1) + +def test_openfast_executable_exists(): + if osp.exists(of_path): + assert True, f"OpenFAST executable found at {of_path}" + else: # stop the test if the OpenFAST executable is not found + print(f"OpenFAST executable not found at {of_path}. Please build OpenFAST and try again.") + sys.exit(1) + +# # Define a list of action functions for parameterization +# actions = [ +# ("read", read_action), +# ("write", write_action), +# ("run", run_action), +# ("check", check_action), +# ] + +# Parameterize the test function to run for each folder and action +@pytest.mark.parametrize("folder", FOLDERS_TO_RUN) +# @pytest.mark.parametrize("action_name, action_func", actions) +def test_openfast_io_with_detailed_reporting(folder): + try: + # action_func(folder) + action_name = "read" + fst_vt = read_action(folder) + + action_name = "write" + write_action(folder, fst_vt) + + action_name = "run" + run_action(folder) + + action_name = "check ASCII" + check_ascii_out(folder) + + action_name = "check binary" + check_binary_out(folder) + + except Exception as e: + pytest.fail(f"Action '{action_name}' for folder '{folder}' failed with exception: {e}") + +def main(): + # Initialize any necessary setup here + + for folder in FOLDERS_TO_RUN: + print(f"Processing folder: {folder}") + + # Assuming read_action, write_action, run_action, and check_action are defined elsewhere + data = read_action(folder) + write_action(folder, data) + run_action(folder) + check_ascii_out(folder) + check_binary_out(folder) + print(f"Successfully processed folder: {folder}") + +if __name__ == "__main__": + main() \ No newline at end of file From e5cee247bafd0a89a9889128bde7309f837ddde1 Mon Sep 17 00:00:00 2001 From: Mayank Chetan Date: Wed, 7 Aug 2024 15:51:17 +0000 Subject: [PATCH 014/161] addressing AD15 warning about input format --- openfast_python/openfast_io/FAST_reader.py | 95 +------------- openfast_python/openfast_io/FAST_writer.py | 142 +++++---------------- 2 files changed, 34 insertions(+), 203 deletions(-) diff --git a/openfast_python/openfast_io/FAST_reader.py b/openfast_python/openfast_io/FAST_reader.py index 225f7e13e..13e155b3d 100644 --- a/openfast_python/openfast_io/FAST_reader.py +++ b/openfast_python/openfast_io/FAST_reader.py @@ -54,7 +54,7 @@ def read_array(f,len,split_val=None,array_type=str): def fix_path(name): """ split a path, then reconstruct it using os.path.join """ - name = re.split("\\\|/", name) + name = re.split("\\|/", name) new = name[0] for i in range(1,len(name)): new = os.path.join(new, name[i]) @@ -878,7 +878,7 @@ def read_AeroDyn15(self): f.readline() 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']['Wake_Mod'] = 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]) @@ -901,7 +901,7 @@ def read_AeroDyn15(self): # Blade-Element/Momentum Theory Options f.readline() - self.fst_vt['AeroDyn15']['SkewMod'] = int_read(f.readline().split()[0]) + self.fst_vt['AeroDyn15']['Skew_Mod'] = 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]) @@ -930,10 +930,10 @@ def read_AeroDyn15(self): f.readline() self.fst_vt['AeroDyn15']['OLAFInputFileName'] = f.readline().split()[0][1:-1] - # Beddoes-Leishman Unsteady Airfoil Aerodynamics Options + # 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']['UA_Mod'] = int(f.readline().split()[0]) self.fst_vt['AeroDyn15']['FLookup'] = bool_read(f.readline().split()[0]) file_pos = f.tell() @@ -2538,91 +2538,6 @@ def read_SubDyn(self, sd_file): def read_ExtPtfm(self, ep_file): # ExtPtfm file based on documentation here: https://openfast.readthedocs.io/en/main/source/user/extptfm/input_files.html - - '''' - Input file for temp reference: - ---------------------- EXTPTFM INPUT FILE -------------------------------------- - Comment describing the model - ---------------------- SIMULATION CONTROL -------------------------------------- - False Echo - Echo input data to .ech (flag) - "default" DT - Communication interval for controllers (s) (or "default") - 3 IntMethod - Integration Method {1:RK4; 2:AB4, 3:ABM4} (switch) - ---------------------- REDUCTION INPUTS ---------------------------------------- - 1 FileFormat - File Format {0:Guyan; 1:FlexASCII} (switch) - "ExtPtfm_SE.dat" Red_FileName - Path of the file containing Guyan/Craig-Bampton inputs (-) - "NA" RedCst_FileName - Path of the file containing Guyan/Craig-Bampton constant inputs (-) (currently unused) - -1 NActiveDOFList - Number of active CB mode listed in ActiveDOFList, use -1 for all modes (integer) - 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25 ActiveDOFList - List of CB modes index that are active, [unused if NActiveDOFList<=0] - 0 NInitPosList - Number of initial positions listed in InitPosList, using 0 implies all DOF initialized to 0 (integer) - 0, InitPosList - List of initial positions for the CB modes [unused if NInitPosList<=0 or EquilStart=True] - 0 NInitVelList - Number of initial positions listed in InitVelList, using 0 implies all DOF initialized to 0 (integer) - 0, InitVelList - List of initial velocities for the CB modes [unused if NInitVelPosList<=0 or EquilStart=True] - ---------------------- OUTPUT -------------------------------------------------- - True SumPrint - Print summary data to .sum (flag) - 1 OutFile - Switch to determine where output will be placed: {1: in module output file only; 2: in glue code output file only; 3: both} (currently unused) - True TabDelim - Use tab delimiters in text tabular output file? (flag) (currently unused) - "ES10.3E2" OutFmt - Format used for text tabular output (except time). Resulting field should be 10 characters. (quoted string) (currently unused) - 0 TStart - Time to begin tabular output (s) (currently unused) - OutList - The next line(s) contains a list of output parameters. See OutListParameters.xlsx for a listing of available output channels, (-) - "IntrfFx" - Platform interface force - Directed along the x-direction (N) - "IntrfFy" - Platform interface force - Directed along the y-direction (N) - "IntrfFz" - Platform interface force - Directed along the z-direction (N) - "IntrfMx" - Platform interface moment - Directed along the x-direction (Nm) - "IntrfMy" - Platform interface moment - Directed along the y-direction (Nm) - "IntrfMz" - Platform interface moment - Directed along the z-direction (Nm) - "InpF_Fx" - Reduced Input force at interface point - Directed along the x-direction (N) - "InpF_Fy" - Reduced Input force at interface point - Directed along the y-direction (N) - "InpF_Fz" - Reduced Input force at interface point - Directed along the z-direction (N) - "InpF_Mx" - Reduced Input moment at interface point - Directed along the x-direction (Nm) - "InpF_My" - Reduced Input moment at interface point - Directed along the y-direction (Nm) - "InpF_Mz" - Reduced Input moment at interface point - Directed along the z-direction (Nm) - "CBQ_001" - Modal displacement of internal Craig-Bampton mode number XXX (-) - "CBQ_002" - Modal displacement of internal Craig-Bampton mode number XXX (-) - "CBQ_003" - Modal displacement of internal Craig-Bampton mode number XXX (-) - "CBQ_004" - Modal displacement of internal Craig-Bampton mode number XXX (-) - "CBQ_005" - Modal displacement of internal Craig-Bampton mode number XXX (-) - "CBQ_006" - Modal displacement of internal Craig-Bampton mode number XXX (-) - "CBQ_007" - Modal displacement of internal Craig-Bampton mode number XXX (-) - "CBQ_010" - Modal displacement of internal Craig-Bampton mode number XXX (-) - "CBQ_011" - Modal displacement of internal Craig-Bampton mode number XXX (-) - "CBQ_012" - Modal displacement of internal Craig-Bampton mode number XXX (-) - "CBQ_013" - Modal displacement of internal Craig-Bampton mode number XXX (-) - "CBQ_014" - Modal displacement of internal Craig-Bampton mode number XXX (-) - "CBQ_015" - Modal displacement of internal Craig-Bampton mode number XXX (-) - "CBQ_016" - Modal displacement of internal Craig-Bampton mode number XXX (-) - "CBQ_017" - Modal displacement of internal Craig-Bampton mode number XXX (-) - "CBQ_020" - Modal displacement of internal Craig-Bampton mode number XXX (-) - "CBQ_021" - Modal displacement of internal Craig-Bampton mode number XXX (-) - "CBQ_022" - Modal displacement of internal Craig-Bampton mode number XXX (-) - "CBQ_023" - Modal displacement of internal Craig-Bampton mode number XXX (-) - "CBQ_024" - Modal displacement of internal Craig-Bampton mode number XXX (-) - "CBQ_025" - Modal displacement of internal Craig-Bampton mode number XXX (-) - "CBF_001" - Modal force on internal Craig-Bampton mode number XXX (-) - "CBF_002" - Modal force on internal Craig-Bampton mode number XXX (-) - "CBF_003" - Modal force on internal Craig-Bampton mode number XXX (-) - "CBF_004" - Modal force on internal Craig-Bampton mode number XXX (-) - "CBF_005" - Modal force on internal Craig-Bampton mode number XXX (-) - "CBF_006" - Modal force on internal Craig-Bampton mode number XXX (-) - "CBF_007" - Modal force on internal Craig-Bampton mode number XXX (-) - "CBF_010" - Modal force on internal Craig-Bampton mode number XXX (-) - "CBF_011" - Modal force on internal Craig-Bampton mode number XXX (-) - "CBF_012" - Modal force on internal Craig-Bampton mode number XXX (-) - "CBF_013" - Modal force on internal Craig-Bampton mode number XXX (-) - "CBF_014" - Modal force on internal Craig-Bampton mode number XXX (-) - "CBF_015" - Modal force on internal Craig-Bampton mode number XXX (-) - "CBF_016" - Modal force on internal Craig-Bampton mode number XXX (-) - "CBF_017" - Modal force on internal Craig-Bampton mode number XXX (-) - "CBF_020" - Modal force on internal Craig-Bampton mode number XXX (-) - "CBF_021" - Modal force on internal Craig-Bampton mode number XXX (-) - "CBF_022" - Modal force on internal Craig-Bampton mode number XXX (-) - "CBF_023" - Modal force on internal Craig-Bampton mode number XXX (-) - "CBF_024" - Modal force on internal Craig-Bampton mode number XXX (-) - "CBF_025" - Modal force on internal Craig-Bampton mode number XXX (-) - "WavElev" - Wave elevation (m) - END of input file (the word "END" must appear in the first 3 columns of this last OutList line) - --------------------------------------------------------------------------------------- - - ''' f = open(ep_file) f.readline() f.readline() diff --git a/openfast_python/openfast_io/FAST_writer.py b/openfast_python/openfast_io/FAST_writer.py index e195c9161..fde21ff4b 100644 --- a/openfast_python/openfast_io/FAST_writer.py +++ b/openfast_python/openfast_io/FAST_writer.py @@ -785,7 +785,7 @@ def write_AeroDyn15(self): if self.fst_vt['AeroDyn15']['af_data'][0][0]['NumCoords'] != '0': # changing from ['af_data'][1] to ['af_data'][0] because we can have a single airfoil too. self.write_AeroDyn15Coord() - if self.fst_vt['AeroDyn15']['WakeMod'] == 3: + if self.fst_vt['AeroDyn15']['Wake_Mod'] == 3: if self.fst_vt['AeroDyn15']['UAMod'] == 2: raise Exception('OLAF is called with unsteady airfoil aerodynamics, but OLAF currently only supports UAMod == 1') #TODO: need to check if this holds true now self.write_OLAF() @@ -800,55 +800,55 @@ def write_AeroDyn15(self): f.write('====== General Options ============================================================================\n') f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['Echo'], 'Echo', '- Echo the input to ".AD.ech"? (flag)\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['DTAero'], 'DTAero', '- Time interval for aerodynamic calculations {or "default"} (s)\n')) - f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['WakeMod'], 'WakeMod', '- Type of wake/induction model (switch) {0=none, 1=BEMT, 2=DBEMT, 3=OLAF} [WakeMod cannot be 2 or 3 when linearizing]\n')) + f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['Wake_Mod'], 'Wake_Mod', '- - Wake/induction model (switch) {0=none, 1=BEMT, 3=OLAF} [Wake_Mod cannot be 2 or 3 when linearizing]\n')) f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['TwrPotent'], '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}\n')) f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['TwrShadow'], 'TwrShadow', '- Calculate tower influence on wind based on downstream tower shadow (switch) {0=none, 1=Powles model, 2=Eames model}\n')) f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['TwrAero'], 'TwrAero', '- Calculate tower aerodynamic loads? (flag)\n')) - f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['CavitCheck'], 'CavitCheck', '- Perform cavitation check? (flag) [AFAeroMod must be 1 when CavitCheck=true]\n')) + f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['CavitCheck'], 'CavitCheck', '- Perform cavitation check? (flag) [UA_Mod must be 0 when CavitCheck=true]\n')) f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['Buoyancy'], 'Buoyancy', '- Include buoyancy effects? (flag)\n')) - f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['CompAA'], 'CompAA', '- Flag to compute AeroAcoustics calculation [only used when WakeMod=1 or 2]\n')) + f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['CompAA'], 'CompAA', '- Flag to compute AeroAcoustics calculation [used only when Wake_Mod = 1 or 2]\n')) f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['AA_InputFile'], 'AA_InputFile', '- AeroAcoustics input file [used only when CompAA=true]\n')) f.write('====== Environmental Conditions ===================================================================\n') f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['AirDens'], 'AirDens', '- Air density (kg/m^3)\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['KinVisc'], 'KinVisc', '- Kinematic air viscosity (m^2/s)\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['SpdSound'], 'SpdSound', '- Speed of sound (m/s)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['KinVisc'], 'KinVisc', '- Kinematic viscosity of working fluid (m^2/s)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['SpdSound'], 'SpdSound', '- Speed of sound in working fluid \n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['Patm'], 'Patm', '- Atmospheric pressure (Pa) [used only when CavitCheck=True]\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['Pvap'], 'Pvap', '- Vapour pressure of fluid (Pa) [used only when CavitCheck=True]\n')) - f.write('====== Blade-Element/Momentum Theory Options ====================================================== [unused when WakeMod=0 or 3]\n') + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['Pvap'], 'Pvap', '- Vapour pressure of working fluid (Pa) [used only when CavitCheck=True]\n')) + f.write('====== Blade-Element/Momentum Theory Options ====================================================== [unused when Wake_Mod=0 or 3, except for BEM_Mod]\n') f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['BEM_Mod'], 'BEM_Mod', '- BEM model {1=legacy NoSweepPitchTwist, 2=polar} (switch) [used for all Wake_Mod to determine output coordinate system]\n')) f.write('--- Skew correction\n') - f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['SkewMod'], 'SkewMod', '- Type of skewed-wake correction model (switch) {1=uncoupled, 2=Pitt/Peters, 3=coupled} [unused when WakeMod=0 or 3]\n')) + f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['Skew_Mod'], 'Skew_Mod', '- Skew model {0=No skew model, -1=Remove non-normal component for linearization, 1=skew model active}\n')) f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['SkewMomCorr'], 'SkewMomCorr', '- Turn the skew momentum correction on or off [used only when Skew_Mod=1]\n')) f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['SkewRedistr_Mod'], 'SkewRedistr_Mod', '- Type of skewed-wake correction model (switch) {0=no redistribution, 1=Glauert/Pitt/Peters, default=1} [used only when Skew_Mod=1]\n')) f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['SkewRedistrFactor'], 'SkewRedistrFactor', '- Constant used in Pitt/Peters skewed wake model {or "default" is 15/32*pi} (-) [used only when Skew_Mod=1 and SkewRedistr_Mod=1]\n')) f.write('--- BEM algorithm\n') - f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['TipLoss'], 'TipLoss', '- Use the Prandtl tip-loss model? (flag) [unused when WakeMod=0 or 3]\n')) - f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['HubLoss'], 'HubLoss', '- Use the Prandtl hub-loss model? (flag) [unused when WakeMod=0 or 3]\n')) - f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['TanInd'], 'TanInd', '- Include tangential induction in BEMT calculations? (flag) [unused when WakeMod=0 or 3]\n')) - f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['AIDrag'], 'AIDrag', '- Include the drag term in the axial-induction calculation? (flag) [unused when WakeMod=0 or 3]\n')) - f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['TIDrag'], 'TIDrag', '- Include the drag term in the tangential-induction calculation? (flag) [unused when WakeMod=0,3 or TanInd=FALSE]\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['IndToler'], 'IndToler', '- Convergence tolerance for BEMT nonlinear solve residual equation {or "default"} (-) [unused when WakeMod=0 or 3]\n')) - f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['MaxIter'], 'MaxIter', '- Maximum number of iteration steps (-) [unused when WakeMod=0]\n')) - f.write('--- BEM algorithm\n') + f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['TipLoss'], 'TipLoss', '- Use the Prandtl tip-loss model? (flag) [unused when Wake_Mod=0 or 3]\n')) + f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['HubLoss'], 'HubLoss', '- Use the Prandtl hub-loss model? (flag) [unused when Wake_Mod=0 or 3]\n')) + f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['TanInd'], 'TanInd', '- Include tangential induction in BEMT calculations? (flag) [unused when Wake_Mod=0 or 3]\n')) + f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['AIDrag'], 'AIDrag', '- Include the drag term in the axial-induction calculation? (flag) [unused when Wake_Mod=0 or 3]\n')) + f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['TIDrag'], 'TIDrag', '- Include the drag term in the tangential-induction calculation? (flag) [unused when Wake_Mod=0,3 or TanInd=FALSE]\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['IndToler'], 'IndToler', '- Convergence tolerance for BEMT nonlinear solve residual equation {or "default"} (-) [unused when Wake_Mod=0 or 3]\n')) + f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['MaxIter'], 'MaxIter', '- Maximum number of iteration steps (-) [unused when Wake_Mod=0]\n')) + f.write('--- Shear correction\n') f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['SectAvg'], 'SectAvg', '- Use sector averaging (flag)\n')) f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['SectAvgWeighting'], 'SectAvgWeighting', '- Weighting function for sector average {1=Uniform, default=1} within a sector centered on the blade (switch) [used only when SectAvg=True]\n')) f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['SectAvgNPoints'], 'SectAvgNPoints', '- Number of points per sectors (-) {default=5} [used only when SectAvg=True]\n')) f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['SectAvgPsiBwd'], 'SectAvgPsiBwd', '- Backward azimuth relative to blade where the sector starts (<=0) {default=-60} (deg) [used only when SectAvg=True]\n')) f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['SectAvgPsiFwd'], 'SectAvgPsiFwd', '- Forward azimuth relative to blade where the sector ends (>=0) {default=60} (deg) [used only when SectAvg=True]\n')) - f.write('====== Dynamic Blade-Element/Momentum Theory Options ====================================================== [used only when WakeMod=2]\n') - f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['DBEMT_Mod'], 'DBEMT_Mod', '- Type of dynamic BEMT (DBEMT) model {1=constant tau1, 2=time-dependent tau1, 3=constant tau1 with continuous formulation} (-) [used only when WakeMod=2]\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['tau1_const'], 'tau1_const', '- Time constant for DBEMT (s) [used only when WakeMod=2 and DBEMT_Mod=1]\n')) - f.write('====== OLAF -- cOnvecting LAgrangian Filaments (Free Vortex Wake) Theory Options ================== [used only when WakeMod=3]\n') + f.write('--- Dynamic wake/inflow\n') + f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['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} (-)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['tau1_const'], 'tau1_const', '- Time constant for DBEMT (s) [used only DBEMT_Mod=1 or 3]\n')) + f.write('====== OLAF -- cOnvecting LAgrangian Filaments (Free Vortex Wake) Theory Options ================== [used only when WakeM_od=3]\n') olaf_file = self.FAST_namingOut + '_OLAF.dat' - f.write('{!s:<22} {:<11} {:}'.format(olaf_file, 'OLAFInputFileName', '- Input file for OLAF [used only when WakeMod=3]\n')) - f.write('====== Beddoes-Leishman Unsteady Airfoil Aerodynamics Options ===================================== [used only when AFAeroMod=2]\n') + f.write('{!s:<22} {:<11} {:}'.format(olaf_file, 'OLAFInputFileName', '- Input file for OLAF [used only when Wake_Mod=3]\n')) + f.write('====== Unsteady Airfoil Aerodynamics Options ===================================== [used only when AFAeroMod=2]\n') f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['AoA34'], 'AoA34', "- Sample the angle of attack (AoA) at the 3/4 chord or the AC point {default=True} [always used]\n")) - f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['UAMod'], 'UAMod', "- Unsteady Aero Model Switch (switch) {1=Baseline model (Original), 2=Gonzalez's variant (changes in Cn,Cc,Cm), 3=Minnema/Pierce variant (changes in Cc and Cm)} [used only when AFAeroMod=2]\n")) - f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['FLookup'], '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]\n")) + f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['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}\n")) + f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['FLookup'], '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 UA_Mod>0]\n")) if 'UAStartRad' in self.fst_vt['AeroDyn15'] and 'UAEndRad' in self.fst_vt['AeroDyn15']: - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['UAStartRad'], 'UAStartRad', '- Starting radius for dynamic stall (fraction of rotor radius) [used only when AFAeroMod=2]\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['UAEndRad'], 'UAEndRad', '- Ending radius for dynamic stall (fraction of rotor radius) [used only when AFAeroMod=2]\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['UAStartRad'], 'UAStartRad', '- Starting radius for dynamic stall (fraction of rotor radius [0.0,1.0]) [used only when UA_Mod>0; if line is missing UAStartRad=0]\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['UAEndRad'], 'UAEndRad', '- Ending radius for dynamic stall (fraction of rotor radius [0.0,1.0]) [used only when UA_Mod>0; if line is missing UAEndRad=1]\n')) f.write('====== Airfoil Information =========================================================================\n') f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['AFTabMod'], '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} (-)\n')) f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['InCol_Alfa'], 'InCol_Alfa', '- The column in the airfoil tables that contains the angle of attack (-)\n')) @@ -878,7 +878,7 @@ def write_AeroDyn15(self): f.write('{:<22} {:<11} {:}'.format('"'+self.fst_vt['AeroDyn15']['TFinFile']+'"', 'TFinFile', '- Input file for tail fin aerodynamics [used only when TFinAero=True]\n')) f.write('====== Tower Influence and Aerodynamics ============================================================ [used only when TwrPotent/=0, TwrShadow/=0, TwrAero=True, or Buoyancy=True]\n') f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['NumTwrNds'], 'NumTwrNds', '- Number of tower nodes used in the analysis (-) [used only when TwrPotent/=0, TwrShadow/=0, TwrAero=True, or Buoyancy=True]\n')) - f.write('TwrElev TwrDiam TwrCd TwrTI TwrCb !TwrTI used only with TwrShadow=2, TwrCb used only with Buoyancy=True\n') + f.write('TwrElev TwrDiam TwrCd TwrTI TwrCb !TwrTI used only when TwrShadow=2; TwrCb used only when Buoyancy=True\n') f.write('(m) (m) (-) (-) (-)\n') for TwrElev, TwrDiam, TwrCd, TwrTI, TwrCb in zip(self.fst_vt['AeroDyn15']['TwrElev'], self.fst_vt['AeroDyn15']['TwrDiam'], self.fst_vt['AeroDyn15']['TwrCd'], self.fst_vt['AeroDyn15']['TwrTI'], self.fst_vt['AeroDyn15']['TwrCb']): f.write('{: 2.15e} {: 2.15e} {: 2.15e} {: 2.15e} {: 2.15e} \n'.format(TwrElev, TwrDiam, TwrCd, TwrTI, TwrCb)) @@ -904,7 +904,7 @@ def write_AeroDyn15(self): f.write('====== Outputs for all blade stations (same ending as above for B1N1.... =========================== [optional section]\n') f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['BldNd_BladesOut'], 'BldNd_BladesOut', '- Number of blades to output all node information at. Up to number of blades on turbine. (-)\n')) f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['BldNd_BlOutNd'], 'BldNd_BlOutNd', '- Future feature will allow selecting a portion of the nodes to output. Not implemented yet. (-)\n')) - f.write(' OutList - The next line(s) contains a list of output parameters. See OutListParameters.xlsx, AeroDyn_Nodes tab for a listing of available output channels, (-)\n') + f.write(' OutList_Nodal - The next line(s) contains a list of output parameters. See OutListParameters.xlsx, AeroDyn_Nodes tab for a listing of available output channels, (-)\n') opt_outlist = self.get_outlist(self.fst_vt['outlist'], ['AeroDyn_Nodes']) for opt_channel_list in opt_outlist: @@ -2089,90 +2089,6 @@ def write_SubDyn(self): def write_ExtPtfm(self): # Generate ExtPtfm input file - '''' - Input file for temp reference: - ---------------------- EXTPTFM INPUT FILE -------------------------------------- - Comment describing the model - ---------------------- SIMULATION CONTROL -------------------------------------- - False Echo - Echo input data to .ech (flag) - "default" DT - Communication interval for controllers (s) (or "default") - 3 IntMethod - Integration Method {1:RK4; 2:AB4, 3:ABM4} (switch) - ---------------------- REDUCTION INPUTS ---------------------------------------- - 1 FileFormat - File Format {0:Guyan; 1:FlexASCII} (switch) - "ExtPtfm_SE.dat" Red_FileName - Path of the file containing Guyan/Craig-Bampton inputs (-) - "NA" RedCst_FileName - Path of the file containing Guyan/Craig-Bampton constant inputs (-) (currently unused) - -1 NActiveDOFList - Number of active CB mode listed in ActiveDOFList, use -1 for all modes (integer) - 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25 ActiveDOFList - List of CB modes index that are active, [unused if NActiveDOFList<=0] - 0 NInitPosList - Number of initial positions listed in InitPosList, using 0 implies all DOF initialized to 0 (integer) - 0, InitPosList - List of initial positions for the CB modes [unused if NInitPosList<=0 or EquilStart=True] - 0 NInitVelList - Number of initial positions listed in InitVelList, using 0 implies all DOF initialized to 0 (integer) - 0, InitVelList - List of initial velocities for the CB modes [unused if NInitVelPosList<=0 or EquilStart=True] - ---------------------- OUTPUT -------------------------------------------------- - True SumPrint - Print summary data to .sum (flag) - 1 OutFile - Switch to determine where output will be placed: {1: in module output file only; 2: in glue code output file only; 3: both} (currently unused) - True TabDelim - Use tab delimiters in text tabular output file? (flag) (currently unused) - "ES10.3E2" OutFmt - Format used for text tabular output (except time). Resulting field should be 10 characters. (quoted string) (currently unused) - 0 TStart - Time to begin tabular output (s) (currently unused) - OutList - The next line(s) contains a list of output parameters. See OutListParameters.xlsx for a listing of available output channels, (-) - "IntrfFx" - Platform interface force - Directed along the x-direction (N) - "IntrfFy" - Platform interface force - Directed along the y-direction (N) - "IntrfFz" - Platform interface force - Directed along the z-direction (N) - "IntrfMx" - Platform interface moment - Directed along the x-direction (Nm) - "IntrfMy" - Platform interface moment - Directed along the y-direction (Nm) - "IntrfMz" - Platform interface moment - Directed along the z-direction (Nm) - "InpF_Fx" - Reduced Input force at interface point - Directed along the x-direction (N) - "InpF_Fy" - Reduced Input force at interface point - Directed along the y-direction (N) - "InpF_Fz" - Reduced Input force at interface point - Directed along the z-direction (N) - "InpF_Mx" - Reduced Input moment at interface point - Directed along the x-direction (Nm) - "InpF_My" - Reduced Input moment at interface point - Directed along the y-direction (Nm) - "InpF_Mz" - Reduced Input moment at interface point - Directed along the z-direction (Nm) - "CBQ_001" - Modal displacement of internal Craig-Bampton mode number XXX (-) - "CBQ_002" - Modal displacement of internal Craig-Bampton mode number XXX (-) - "CBQ_003" - Modal displacement of internal Craig-Bampton mode number XXX (-) - "CBQ_004" - Modal displacement of internal Craig-Bampton mode number XXX (-) - "CBQ_005" - Modal displacement of internal Craig-Bampton mode number XXX (-) - "CBQ_006" - Modal displacement of internal Craig-Bampton mode number XXX (-) - "CBQ_007" - Modal displacement of internal Craig-Bampton mode number XXX (-) - "CBQ_010" - Modal displacement of internal Craig-Bampton mode number XXX (-) - "CBQ_011" - Modal displacement of internal Craig-Bampton mode number XXX (-) - "CBQ_012" - Modal displacement of internal Craig-Bampton mode number XXX (-) - "CBQ_013" - Modal displacement of internal Craig-Bampton mode number XXX (-) - "CBQ_014" - Modal displacement of internal Craig-Bampton mode number XXX (-) - "CBQ_015" - Modal displacement of internal Craig-Bampton mode number XXX (-) - "CBQ_016" - Modal displacement of internal Craig-Bampton mode number XXX (-) - "CBQ_017" - Modal displacement of internal Craig-Bampton mode number XXX (-) - "CBQ_020" - Modal displacement of internal Craig-Bampton mode number XXX (-) - "CBQ_021" - Modal displacement of internal Craig-Bampton mode number XXX (-) - "CBQ_022" - Modal displacement of internal Craig-Bampton mode number XXX (-) - "CBQ_023" - Modal displacement of internal Craig-Bampton mode number XXX (-) - "CBQ_024" - Modal displacement of internal Craig-Bampton mode number XXX (-) - "CBQ_025" - Modal displacement of internal Craig-Bampton mode number XXX (-) - "CBF_001" - Modal force on internal Craig-Bampton mode number XXX (-) - "CBF_002" - Modal force on internal Craig-Bampton mode number XXX (-) - "CBF_003" - Modal force on internal Craig-Bampton mode number XXX (-) - "CBF_004" - Modal force on internal Craig-Bampton mode number XXX (-) - "CBF_005" - Modal force on internal Craig-Bampton mode number XXX (-) - "CBF_006" - Modal force on internal Craig-Bampton mode number XXX (-) - "CBF_007" - Modal force on internal Craig-Bampton mode number XXX (-) - "CBF_010" - Modal force on internal Craig-Bampton mode number XXX (-) - "CBF_011" - Modal force on internal Craig-Bampton mode number XXX (-) - "CBF_012" - Modal force on internal Craig-Bampton mode number XXX (-) - "CBF_013" - Modal force on internal Craig-Bampton mode number XXX (-) - "CBF_014" - Modal force on internal Craig-Bampton mode number XXX (-) - "CBF_015" - Modal force on internal Craig-Bampton mode number XXX (-) - "CBF_016" - Modal force on internal Craig-Bampton mode number XXX (-) - "CBF_017" - Modal force on internal Craig-Bampton mode number XXX (-) - "CBF_020" - Modal force on internal Craig-Bampton mode number XXX (-) - "CBF_021" - Modal force on internal Craig-Bampton mode number XXX (-) - "CBF_022" - Modal force on internal Craig-Bampton mode number XXX (-) - "CBF_023" - Modal force on internal Craig-Bampton mode number XXX (-) - "CBF_024" - Modal force on internal Craig-Bampton mode number XXX (-) - "CBF_025" - Modal force on internal Craig-Bampton mode number XXX (-) - "WavElev" - Wave elevation (m) - END of input file (the word "END" must appear in the first 3 columns of this last OutList line) - --------------------------------------------------------------------------------------- - - ''' if self.fst_vt['ExtPtfm']['FileFormat'] == 0: None From 4a4d8976091a168bb883dcf9d65f12a52b1e44e2 Mon Sep 17 00:00:00 2001 From: Mayank Chetan Date: Wed, 7 Aug 2024 16:11:49 +0000 Subject: [PATCH 015/161] removing module versions on inputfile headers --- openfast_python/openfast_io/FAST_writer.py | 32 +++++++++++----------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/openfast_python/openfast_io/FAST_writer.py b/openfast_python/openfast_io/FAST_writer.py index fde21ff4b..90ae268e4 100644 --- a/openfast_python/openfast_io/FAST_writer.py +++ b/openfast_python/openfast_io/FAST_writer.py @@ -198,7 +198,7 @@ def execute(self): self.write_MainInput() def write_MainInput(self): - # Main FAST v8.16-v8.17 Input File + # Main FAST Input File # Currently no differences between FASTv8.16 and OpenFAST. self.FAST_InputFileOut = os.path.join(self.FAST_runDirectory, self.FAST_namingOut+'.fst') @@ -292,7 +292,7 @@ def write_ElastoDyn(self): ed_file = os.path.join(self.FAST_runDirectory,self.fst_vt['Fst']['EDFile']) f = open(ed_file, 'w') - f.write('------- ELASTODYN v1.03.* INPUT FILE -------------------------------------------\n') + f.write('------- ELASTODYN INPUT FILE -------------------------------------------\n') f.write('Generated with OpenFAST_IO\n') # ElastoDyn Simulation Control (ed_sim_ctrl) @@ -463,7 +463,7 @@ def write_ElastoDynBlade(self): blade_file = os.path.join(self.FAST_runDirectory,self.fst_vt['ElastoDyn']['BldFile1']) f = open(blade_file, 'w') - f.write('------- ELASTODYN V1.00.* INDIVIDUAL BLADE INPUT FILE --------------------------\n') + f.write('------- ELASTODYN INDIVIDUAL BLADE INPUT FILE --------------------------\n') f.write('Generated with OpenFAST_IO\n') f.write('---------------------- BLADE PARAMETERS ----------------------------------------\n') f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynBlade']['NBlInpSt'], 'NBlInpSt', '- Number of blade input stations (-)\n')) @@ -514,7 +514,7 @@ def write_ElastoDynTower(self): tower_file = os.path.join(self.FAST_runDirectory,self.fst_vt['ElastoDyn']['TwrFile']) f = open(tower_file, 'w') - f.write('------- ELASTODYN V1.00.* TOWER INPUT FILE -------------------------------------\n') + f.write('------- ELASTODYN TOWER INPUT FILE -------------------------------------\n') f.write('Generated with OpenFAST_IO\n') f.write('---------------------- TOWER PARAMETERS ----------------------------------------\n') f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynTower']['NTwInpSt'], 'NTwInpSt', '- Number of input stations to specify tower geometry\n')) @@ -665,7 +665,7 @@ def write_BeamDynBlade(self): bd_blade_file = os.path.abspath(os.path.join(self.FAST_runDirectory, self.fst_vt['BeamDyn']['BldFile'])) f = open(bd_blade_file, 'w') - f.write('------- BEAMDYN V1.00.* INDIVIDUAL BLADE INPUT FILE --------------------------\n') + f.write('------- BEAMDYN INDIVIDUAL BLADE INPUT FILE --------------------------\n') f.write('Generated with OpenFAST_IO\n') f.write('---------------------- BLADE PARAMETERS --------------------------------------\n') f.write('{:<22} {:<11} {:}'.format(self.fst_vt['BeamDynBlade']['station_total'], 'station_total', '- Number of blade input stations (-)\n')) @@ -693,7 +693,7 @@ def write_InflowWind(self): inflow_file = os.path.join(self.FAST_runDirectory,self.fst_vt['Fst']['InflowFile']) f = open(inflow_file, 'w') - f.write('------- InflowWind v3.01.* INPUT FILE -------------------------------------------------------------------------\n') + f.write('------- InflowWind INPUT FILE -------------------------------------------------------------------------\n') f.write('Generated with OpenFAST_IO\n') f.write('---------------------------------------------------------------------------------------------------------------\n') f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['InflowWind']['Echo'], 'Echo', '- Echo input data to .ech (flag)\n')) @@ -795,7 +795,7 @@ def write_AeroDyn15(self): ad_file = os.path.join(self.FAST_runDirectory, self.fst_vt['Fst']['AeroFile']) f = open(ad_file, 'w') - f.write('------- AERODYN v15.03.* INPUT FILE ------------------------------------------------\n') + f.write('------- AERODYN15 INPUT FILE ------------------------------------------------\n') f.write('Generated with OpenFAST_IO\n') f.write('====== General Options ============================================================================\n') f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['Echo'], 'Echo', '- Echo the input to ".AD.ech"? (flag)\n')) @@ -925,7 +925,7 @@ def write_AeroDyn15Blade(self): filename = os.path.join(self.FAST_runDirectory, self.fst_vt['AeroDyn15']['ADBlFile1']) f = open(filename, 'w') - f.write('------- AERODYN v15.00.* BLADE DEFINITION INPUT FILE -------------------------------------\n') + f.write('------- AERODYN15 BLADE DEFINITION INPUT FILE -------------------------------------\n') f.write('Generated with OpenFAST_IO\n') f.write('====== Blade Properties =================================================================\n') f.write('{:<11d} {:<11} {:}'.format(self.fst_vt['AeroDynBlade']['NumBlNds'], 'NumBlNds', '- Number of blade nodes used in the analysis (-)\n')) @@ -969,7 +969,7 @@ def write_AeroDyn15Polar(self): af_file = os.path.join(self.FAST_runDirectory, self.fst_vt['AeroDyn15']['AFNames'][afi]) f = open(af_file, 'w') - f.write('! ------------ AirfoilInfo v1.01.x Input File ----------------------------------\n') + f.write('! ------------ AirfoilInfo Input File ----------------------------------\n') f.write('! Generated with OpenFAST_IO\n') f.write('! line\n') f.write('! line\n') @@ -1319,7 +1319,7 @@ def write_ServoDyn(self): sd_file = os.path.join(self.FAST_runDirectory,self.fst_vt['Fst']['ServoFile']) f = open(sd_file,'w') - f.write('------- SERVODYN v1.05.* INPUT FILE --------------------------------------------\n') + f.write('------- SERVODYN INPUT FILE --------------------------------------------\n') f.write('Generated with OpenFAST_IO\n') f.write('---------------------- SIMULATION CONTROL --------------------------------------\n') f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['ServoDyn']['Echo'], 'Echo', '- Echo input data to .ech (flag)\n')) @@ -1485,12 +1485,12 @@ def write_DISCON_in(self): def write_HydroDyn(self): - # Generate HydroDyn v2.03 input file + # Generate HydroDyn input file self.fst_vt['Fst']['HydroFile'] = self.FAST_namingOut + '_HydroDyn.dat' hd_file = os.path.join(self.FAST_runDirectory, self.fst_vt['Fst']['HydroFile']) f = open(hd_file, 'w') - f.write('------- HydroDyn v2.03.* Input File --------------------------------------------\n') + f.write('------- HydroDyn Input File --------------------------------------------\n') f.write('Generated with OpenFAST_IO\n') f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['HydroDyn']['Echo'], 'Echo', '- Echo the input file data (flag)\n')) f.write('---------------------- FLOATING PLATFORM --------------------------------------- [unused with WaveMod=6]\n') @@ -1749,12 +1749,12 @@ def write_HydroDyn(self): def write_SeaState(self): - # Generate HydroDyn v2.03 input file + # Generate SeaState input file self.fst_vt['Fst']['SeaState'] = self.FAST_namingOut + '_SeaState.dat' hd_file = os.path.join(self.FAST_runDirectory, self.fst_vt['Fst']['SeaState']) f = open(hd_file, 'w') - f.write('------- SeaState v1.00.* Input File --------------------------------------------\n') + f.write('------- SeaState Input File --------------------------------------------\n') f.write('Generated with OpenFAST_IO\n') f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['SeaState']['Echo'], 'Echo', '- Echo the input file data (flag)\n')) @@ -1858,12 +1858,12 @@ def write_SeaState(self): f.close() def write_SubDyn(self): - # Generate SubDyn v1.1 input file + # Generate SubDyn input file self.fst_vt['Fst']['SubFile'] = self.FAST_namingOut + '_SubDyn.dat' sd_file = os.path.join(self.FAST_runDirectory, self.fst_vt['Fst']['SubFile']) f = open(sd_file, 'w') - f.write('----------- SubDyn v1.01.x MultiMember Support Structure Input File ------------\n') + f.write('----------- SubDyn MultiMember Support Structure Input File ------------\n') f.write('Generated with OpenFAST_IO\n') f.write('-------------------------- SIMULATION CONTROL ---------------------------------\n') f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['SubDyn']['Echo'], 'Echo', '- Echo input data to ".SD.ech" (flag)\n')) From 684952d8a0bc3439093a04091c8683e7d7e0c7f7 Mon Sep 17 00:00:00 2001 From: Mayank Chetan Date: Thu, 15 Aug 2024 04:19:37 +0000 Subject: [PATCH 016/161] renaming folders to follow best practices --- {openfast_python => openfast_io}/README.md | 0 .../openfast_io/FAST_linearization_reader.py | 0 .../openfast_io/FAST_output_reader.py | 0 .../openfast_io/FAST_post.py | 0 .../openfast_io/FAST_reader.py | 0 .../openfast_io/FAST_vars_out.py | 0 .../openfast_io/FAST_writer.py | 0 .../openfast_io/FileTools.py | 0 .../openfast_io/IEC_CoeherentGusts.py | 0 .../openfast_io/StC_defaults.py | 0 .../openfast_io/__init__.py | 0 .../openfast_io/create_output_vars.py | 0 .../openfast_io/tests/test_of_io.py | 34 +++++++++++++++++-- .../openfast_io/tests}/test_of_io_pytest.py | 0 .../openfast_io/turbsim_file.py | 0 .../openfast_io/turbsim_util.py | 0 {openfast_python => openfast_io}/poetry.lock | 0 .../pyproject.toml | 11 +++++- 18 files changed, 41 insertions(+), 4 deletions(-) rename {openfast_python => openfast_io}/README.md (100%) rename {openfast_python => openfast_io}/openfast_io/FAST_linearization_reader.py (100%) rename {openfast_python => openfast_io}/openfast_io/FAST_output_reader.py (100%) rename {openfast_python => openfast_io}/openfast_io/FAST_post.py (100%) rename {openfast_python => openfast_io}/openfast_io/FAST_reader.py (100%) rename {openfast_python => openfast_io}/openfast_io/FAST_vars_out.py (100%) rename {openfast_python => openfast_io}/openfast_io/FAST_writer.py (100%) rename {openfast_python => openfast_io}/openfast_io/FileTools.py (100%) rename {openfast_python => openfast_io}/openfast_io/IEC_CoeherentGusts.py (100%) rename {openfast_python => openfast_io}/openfast_io/StC_defaults.py (100%) rename {openfast_python => openfast_io}/openfast_io/__init__.py (100%) rename {openfast_python => openfast_io}/openfast_io/create_output_vars.py (100%) rename openfast_python/openfast_io/test/test_OF_utils.py => openfast_io/openfast_io/tests/test_of_io.py (61%) rename {openfast_python/openfast_io/test => openfast_io/openfast_io/tests}/test_of_io_pytest.py (100%) rename {openfast_python => openfast_io}/openfast_io/turbsim_file.py (100%) rename {openfast_python => openfast_io}/openfast_io/turbsim_util.py (100%) rename {openfast_python => openfast_io}/poetry.lock (100%) rename {openfast_python => openfast_io}/pyproject.toml (65%) diff --git a/openfast_python/README.md b/openfast_io/README.md similarity index 100% rename from openfast_python/README.md rename to openfast_io/README.md diff --git a/openfast_python/openfast_io/FAST_linearization_reader.py b/openfast_io/openfast_io/FAST_linearization_reader.py similarity index 100% rename from openfast_python/openfast_io/FAST_linearization_reader.py rename to openfast_io/openfast_io/FAST_linearization_reader.py diff --git a/openfast_python/openfast_io/FAST_output_reader.py b/openfast_io/openfast_io/FAST_output_reader.py similarity index 100% rename from openfast_python/openfast_io/FAST_output_reader.py rename to openfast_io/openfast_io/FAST_output_reader.py diff --git a/openfast_python/openfast_io/FAST_post.py b/openfast_io/openfast_io/FAST_post.py similarity index 100% rename from openfast_python/openfast_io/FAST_post.py rename to openfast_io/openfast_io/FAST_post.py diff --git a/openfast_python/openfast_io/FAST_reader.py b/openfast_io/openfast_io/FAST_reader.py similarity index 100% rename from openfast_python/openfast_io/FAST_reader.py rename to openfast_io/openfast_io/FAST_reader.py diff --git a/openfast_python/openfast_io/FAST_vars_out.py b/openfast_io/openfast_io/FAST_vars_out.py similarity index 100% rename from openfast_python/openfast_io/FAST_vars_out.py rename to openfast_io/openfast_io/FAST_vars_out.py diff --git a/openfast_python/openfast_io/FAST_writer.py b/openfast_io/openfast_io/FAST_writer.py similarity index 100% rename from openfast_python/openfast_io/FAST_writer.py rename to openfast_io/openfast_io/FAST_writer.py diff --git a/openfast_python/openfast_io/FileTools.py b/openfast_io/openfast_io/FileTools.py similarity index 100% rename from openfast_python/openfast_io/FileTools.py rename to openfast_io/openfast_io/FileTools.py diff --git a/openfast_python/openfast_io/IEC_CoeherentGusts.py b/openfast_io/openfast_io/IEC_CoeherentGusts.py similarity index 100% rename from openfast_python/openfast_io/IEC_CoeherentGusts.py rename to openfast_io/openfast_io/IEC_CoeherentGusts.py diff --git a/openfast_python/openfast_io/StC_defaults.py b/openfast_io/openfast_io/StC_defaults.py similarity index 100% rename from openfast_python/openfast_io/StC_defaults.py rename to openfast_io/openfast_io/StC_defaults.py diff --git a/openfast_python/openfast_io/__init__.py b/openfast_io/openfast_io/__init__.py similarity index 100% rename from openfast_python/openfast_io/__init__.py rename to openfast_io/openfast_io/__init__.py diff --git a/openfast_python/openfast_io/create_output_vars.py b/openfast_io/openfast_io/create_output_vars.py similarity index 100% rename from openfast_python/openfast_io/create_output_vars.py rename to openfast_io/openfast_io/create_output_vars.py diff --git a/openfast_python/openfast_io/test/test_OF_utils.py b/openfast_io/openfast_io/tests/test_of_io.py similarity index 61% rename from openfast_python/openfast_io/test/test_OF_utils.py rename to openfast_io/openfast_io/tests/test_of_io.py index a147cd854..697f3f4c4 100644 --- a/openfast_python/openfast_io/test/test_OF_utils.py +++ b/openfast_io/openfast_io/tests/test_of_io.py @@ -7,9 +7,32 @@ from openfast_io.FAST_writer import InputWriter_OpenFAST from openfast_io.FAST_output_reader import FASTOutputFile +from openfast_io.FileTools import check_rtest_cloned +from pathlib import Path + REPOSITORY_ROOT = osp.dirname(osp.dirname(osp.dirname(osp.dirname(__file__)))) RTESTS_DIR = osp.join(REPOSITORY_ROOT, "reg_tests","r-test") -TEST_DATA_DIR = osp.join(RTESTS_DIR, "glue-codes", "openfast", "5MW_Land_DLL_WTurb") +TEST_DATA_DIR = osp.join(RTESTS_DIR, "glue-codes", "openfast") + +RUN_DIR = osp.join(REPOSITORY_ROOT, "build_ofio", "testSuite") +Path(RUN_DIR).mkdir(parents=True, exist_ok=True) + + +# Exercising the various OpenFAST modules +FOLDERS_TO_RUN = [ + "5MW_Land_DLL_WTurb" , # "openfast;elastodyn;aerodyn15;servodyn") + "5MW_OC3Mnpl_DLL_WTurb_WavesIrr" , # "openfast;elastodyn;aerodyn15;servodyn;hydrodyn;subdyn;offshore") + "5MW_OC3Mnpl_DLL_WTurb_WavesIrr_Restart", # "openfast;elastodyn;aerodyn15;servodyn;hydrodyn;subdyn;offshore;restart") + "5MW_ITIBarge_DLL_WTurb_WavesIrr" , # "openfast;elastodyn;aerodyn15;servodyn;hydrodyn;map;offshore") + "5MW_OC4Semi_WSt_WavesWN" , # "openfast;elastodyn;aerodyn15;servodyn;hydrodyn;moordyn;offshore") + "5MW_Land_BD_DLL_WTurb" , # "openfast;beamdyn;aerodyn15;servodyn") + "5MW_OC4Jckt_ExtPtfm" , # "openfast;elastodyn;extptfm") + "HelicalWake_OLAF" , # "openfast;aerodyn15;olaf") + "StC_test_OC4Semi" , # "openfast;servodyn;hydrodyn;moordyn;offshore;stc") + "MHK_RM1_Fixed" , # "openfast;elastodyn;aerodyn15;mhk") + "MHK_RM1_Floating" , # "openfast;elastodyn;aerodyn15;hydrodyn;moordyn;mhk") + "Tailfin_FreeYaw1DOF_PolarBased" , # "openfast;elastodyn;aerodyn15") +] # looking up OS for the correct executable extension mactype = platform.system().lower() @@ -27,8 +50,13 @@ class TestOFutils(unittest.TestCase): def testOF_Inputs(self): # Check if r-tests are available - if not osp.isdir(RTESTS_DIR): - Exception("The test data directory, {}, does not exist. If you haven't already, run `git submodule update --init --recursive`".format(RTESTS_DIR)) + if check_rtest_cloned(TEST_DATA_DIR): + sys.exit(1) + + # Check if OpenFAST executable is available else inform user + if not osp.exists(of_path): + print(f"OpenFAST executable not found at {of_path}. Please build OpenFAST and try again.") + sys.exit(1) # Read input deck diff --git a/openfast_python/openfast_io/test/test_of_io_pytest.py b/openfast_io/openfast_io/tests/test_of_io_pytest.py similarity index 100% rename from openfast_python/openfast_io/test/test_of_io_pytest.py rename to openfast_io/openfast_io/tests/test_of_io_pytest.py diff --git a/openfast_python/openfast_io/turbsim_file.py b/openfast_io/openfast_io/turbsim_file.py similarity index 100% rename from openfast_python/openfast_io/turbsim_file.py rename to openfast_io/openfast_io/turbsim_file.py diff --git a/openfast_python/openfast_io/turbsim_util.py b/openfast_io/openfast_io/turbsim_util.py similarity index 100% rename from openfast_python/openfast_io/turbsim_util.py rename to openfast_io/openfast_io/turbsim_util.py diff --git a/openfast_python/poetry.lock b/openfast_io/poetry.lock similarity index 100% rename from openfast_python/poetry.lock rename to openfast_io/poetry.lock diff --git a/openfast_python/pyproject.toml b/openfast_io/pyproject.toml similarity index 65% rename from openfast_python/pyproject.toml rename to openfast_io/pyproject.toml index 6bac6be63..7d53a94a1 100644 --- a/openfast_python/pyproject.toml +++ b/openfast_io/pyproject.toml @@ -1,7 +1,8 @@ [tool.poetry] name = "openfast_io" -version = "3.5.4.beta-1" +version = "4.0.0" # We can make this dynamic to use github tags using dynamic = ["version"] description = "Readers and writers for OpenFAST files." +requires-python = ">=3.9" license = "Apache-2.0" authors = [ "NREL WISDEM Team ", @@ -14,6 +15,14 @@ authors = [ readme = "README.md" packages = [{include = "openfast_io"}] +classifiers = [ + "Development Status :: 4 - Beta", + "Programming Language :: Python", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", +] [tool.poetry.dependencies] python = "^3.9" From 62ce62845ee8f95927daa8af5eb4cd48be362962 Mon Sep 17 00:00:00 2001 From: Mayank Chetan Date: Mon, 19 Aug 2024 16:26:06 +0000 Subject: [PATCH 017/161] updates to .toml & poetry lock --- openfast_io/poetry.lock | 1514 +++++++++++++++++++----------------- openfast_io/pyproject.toml | 38 +- 2 files changed, 844 insertions(+), 708 deletions(-) diff --git a/openfast_io/poetry.lock b/openfast_io/poetry.lock index 2f75252d2..969113335 100644 --- a/openfast_io/poetry.lock +++ b/openfast_io/poetry.lock @@ -1,14 +1,14 @@ -# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. [[package]] name = "anyio" -version = "4.3.0" +version = "4.4.0" description = "High level compatibility layer for multiple asynchronous event loop implementations" optional = true python-versions = ">=3.8" files = [ - {file = "anyio-4.3.0-py3-none-any.whl", hash = "sha256:048e05d0f6caeed70d731f3db756d35dcc1f35747c8c403364a8332c630441b8"}, - {file = "anyio-4.3.0.tar.gz", hash = "sha256:f75253795a87df48568485fd18cdd2a3fa5c4f7c5be8e5e36637733fce06fed6"}, + {file = "anyio-4.4.0-py3-none-any.whl", hash = "sha256:c1b2d8f46a8a812513012e1107cb0e68c17159a7a594208005a57dc776e1bdc7"}, + {file = "anyio-4.4.0.tar.gz", hash = "sha256:5aadc6a1bbb7cdb0bede386cac5e2940f5e2ff3aa20277e991cf028e0585ce94"}, ] [package.dependencies] @@ -143,32 +143,32 @@ typing-extensions = {version = ">=4.0.0", markers = "python_version < \"3.11\""} [[package]] name = "attrs" -version = "23.2.0" +version = "24.2.0" description = "Classes Without Boilerplate" optional = true python-versions = ">=3.7" files = [ - {file = "attrs-23.2.0-py3-none-any.whl", hash = "sha256:99b87a485a5820b23b879f04c2305b44b951b502fd64be915879d77a7e8fc6f1"}, - {file = "attrs-23.2.0.tar.gz", hash = "sha256:935dc3b529c262f6cf76e50877d35a4bd3c1de194fd41f47a2b7ae8f19971f30"}, + {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"}, + {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"}, ] [package.extras] -cov = ["attrs[tests]", "coverage[toml] (>=5.3)"] -dev = ["attrs[tests]", "pre-commit"] -docs = ["furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier", "zope-interface"] -tests = ["attrs[tests-no-zope]", "zope-interface"] -tests-mypy = ["mypy (>=1.6)", "pytest-mypy-plugins"] -tests-no-zope = ["attrs[tests-mypy]", "cloudpickle", "hypothesis", "pympler", "pytest (>=4.3.0)", "pytest-xdist[psutil]"] +benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] +tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] [[package]] name = "babel" -version = "2.15.0" +version = "2.16.0" description = "Internationalization utilities" optional = true python-versions = ">=3.8" files = [ - {file = "Babel-2.15.0-py3-none-any.whl", hash = "sha256:08706bdad8d0a3413266ab61bd6c34d0c28d6e1e7badf40a2cebe67644e2e1fb"}, - {file = "babel-2.15.0.tar.gz", hash = "sha256:8daf0e265d05768bc6c7a314cf1321e9a123afc328cc635c18622a2f30a04413"}, + {file = "babel-2.16.0-py3-none-any.whl", hash = "sha256:368b5b98b37c06b7daf6696391c3240c938b37767d4584413e8438c5c435fa8b"}, + {file = "babel-2.16.0.tar.gz", hash = "sha256:d1f3554ca26605fe173f3de0c65f750f5a42f924499bf134de6423582298e316"}, ] [package.extras] @@ -215,74 +215,89 @@ css = ["tinycss2 (>=1.1.0,<1.3)"] [[package]] name = "certifi" -version = "2024.2.2" +version = "2024.7.4" description = "Python package for providing Mozilla's CA Bundle." optional = true python-versions = ">=3.6" files = [ - {file = "certifi-2024.2.2-py3-none-any.whl", hash = "sha256:dc383c07b76109f368f6106eee2b593b04a011ea4d55f652c6ca24a754d1cdd1"}, - {file = "certifi-2024.2.2.tar.gz", hash = "sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f"}, + {file = "certifi-2024.7.4-py3-none-any.whl", hash = "sha256:c198e21b1289c2ab85ee4e67bb4b4ef3ead0892059901a8d5b622f24a1101e90"}, + {file = "certifi-2024.7.4.tar.gz", hash = "sha256:5a1e7645bc0ec61a09e26c36f6106dd4cf40c6db3a1fb6352b0244e7fb057c7b"}, ] [[package]] name = "cffi" -version = "1.16.0" +version = "1.17.0" description = "Foreign Function Interface for Python calling C code." optional = true python-versions = ">=3.8" files = [ - {file = "cffi-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6b3d6606d369fc1da4fd8c357d026317fbb9c9b75d36dc16e90e84c26854b088"}, - {file = "cffi-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ac0f5edd2360eea2f1daa9e26a41db02dd4b0451b48f7c318e217ee092a213e9"}, - {file = "cffi-1.16.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7e61e3e4fa664a8588aa25c883eab612a188c725755afff6289454d6362b9673"}, - {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a72e8961a86d19bdb45851d8f1f08b041ea37d2bd8d4fd19903bc3083d80c896"}, - {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5b50bf3f55561dac5438f8e70bfcdfd74543fd60df5fa5f62d94e5867deca684"}, - {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7651c50c8c5ef7bdb41108b7b8c5a83013bfaa8a935590c5d74627c047a583c7"}, - {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4108df7fe9b707191e55f33efbcb2d81928e10cea45527879a4749cbe472614"}, - {file = "cffi-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:32c68ef735dbe5857c810328cb2481e24722a59a2003018885514d4c09af9743"}, - {file = "cffi-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:673739cb539f8cdaa07d92d02efa93c9ccf87e345b9a0b556e3ecc666718468d"}, - {file = "cffi-1.16.0-cp310-cp310-win32.whl", hash = "sha256:9f90389693731ff1f659e55c7d1640e2ec43ff725cc61b04b2f9c6d8d017df6a"}, - {file = "cffi-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:e6024675e67af929088fda399b2094574609396b1decb609c55fa58b028a32a1"}, - {file = "cffi-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b84834d0cf97e7d27dd5b7f3aca7b6e9263c56308ab9dc8aae9784abb774d404"}, - {file = "cffi-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1b8ebc27c014c59692bb2664c7d13ce7a6e9a629be20e54e7271fa696ff2b417"}, - {file = "cffi-1.16.0-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ee07e47c12890ef248766a6e55bd38ebfb2bb8edd4142d56db91b21ea68b7627"}, - {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8a9d3ebe49f084ad71f9269834ceccbf398253c9fac910c4fd7053ff1386936"}, - {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e70f54f1796669ef691ca07d046cd81a29cb4deb1e5f942003f401c0c4a2695d"}, - {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5bf44d66cdf9e893637896c7faa22298baebcd18d1ddb6d2626a6e39793a1d56"}, - {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7b78010e7b97fef4bee1e896df8a4bbb6712b7f05b7ef630f9d1da00f6444d2e"}, - {file = "cffi-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c6a164aa47843fb1b01e941d385aab7215563bb8816d80ff3a363a9f8448a8dc"}, - {file = "cffi-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e09f3ff613345df5e8c3667da1d918f9149bd623cd9070c983c013792a9a62eb"}, - {file = "cffi-1.16.0-cp311-cp311-win32.whl", hash = "sha256:2c56b361916f390cd758a57f2e16233eb4f64bcbeee88a4881ea90fca14dc6ab"}, - {file = "cffi-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:db8e577c19c0fda0beb7e0d4e09e0ba74b1e4c092e0e40bfa12fe05b6f6d75ba"}, - {file = "cffi-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:fa3a0128b152627161ce47201262d3140edb5a5c3da88d73a1b790a959126956"}, - {file = "cffi-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:68e7c44931cc171c54ccb702482e9fc723192e88d25a0e133edd7aff8fcd1f6e"}, - {file = "cffi-1.16.0-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:abd808f9c129ba2beda4cfc53bde801e5bcf9d6e0f22f095e45327c038bfe68e"}, - {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88e2b3c14bdb32e440be531ade29d3c50a1a59cd4e51b1dd8b0865c54ea5d2e2"}, - {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fcc8eb6d5902bb1cf6dc4f187ee3ea80a1eba0a89aba40a5cb20a5087d961357"}, - {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b7be2d771cdba2942e13215c4e340bfd76398e9227ad10402a8767ab1865d2e6"}, - {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e715596e683d2ce000574bae5d07bd522c781a822866c20495e52520564f0969"}, - {file = "cffi-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:2d92b25dbf6cae33f65005baf472d2c245c050b1ce709cc4588cdcdd5495b520"}, - {file = "cffi-1.16.0-cp312-cp312-win32.whl", hash = "sha256:b2ca4e77f9f47c55c194982e10f058db063937845bb2b7a86c84a6cfe0aefa8b"}, - {file = "cffi-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:68678abf380b42ce21a5f2abde8efee05c114c2fdb2e9eef2efdb0257fba1235"}, - {file = "cffi-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0c9ef6ff37e974b73c25eecc13952c55bceed9112be2d9d938ded8e856138bcc"}, - {file = "cffi-1.16.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a09582f178759ee8128d9270cd1344154fd473bb77d94ce0aeb2a93ebf0feaf0"}, - {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e760191dd42581e023a68b758769e2da259b5d52e3103c6060ddc02c9edb8d7b"}, - {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:80876338e19c951fdfed6198e70bc88f1c9758b94578d5a7c4c91a87af3cf31c"}, - {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a6a14b17d7e17fa0d207ac08642c8820f84f25ce17a442fd15e27ea18d67c59b"}, - {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6602bc8dc6f3a9e02b6c22c4fc1e47aa50f8f8e6d3f78a5e16ac33ef5fefa324"}, - {file = "cffi-1.16.0-cp38-cp38-win32.whl", hash = "sha256:131fd094d1065b19540c3d72594260f118b231090295d8c34e19a7bbcf2e860a"}, - {file = "cffi-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:31d13b0f99e0836b7ff893d37af07366ebc90b678b6664c955b54561fc36ef36"}, - {file = "cffi-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:582215a0e9adbe0e379761260553ba11c58943e4bbe9c36430c4ca6ac74b15ed"}, - {file = "cffi-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b29ebffcf550f9da55bec9e02ad430c992a87e5f512cd63388abb76f1036d8d2"}, - {file = "cffi-1.16.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dc9b18bf40cc75f66f40a7379f6a9513244fe33c0e8aa72e2d56b0196a7ef872"}, - {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9cb4a35b3642fc5c005a6755a5d17c6c8b6bcb6981baf81cea8bfbc8903e8ba8"}, - {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b86851a328eedc692acf81fb05444bdf1891747c25af7529e39ddafaf68a4f3f"}, - {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c0f31130ebc2d37cdd8e44605fb5fa7ad59049298b3f745c74fa74c62fbfcfc4"}, - {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f8e709127c6c77446a8c0a8c8bf3c8ee706a06cd44b1e827c3e6a2ee6b8c098"}, - {file = "cffi-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:748dcd1e3d3d7cd5443ef03ce8685043294ad6bd7c02a38d1bd367cfd968e000"}, - {file = "cffi-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8895613bcc094d4a1b2dbe179d88d7fb4a15cee43c052e8885783fac397d91fe"}, - {file = "cffi-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed86a35631f7bfbb28e108dd96773b9d5a6ce4811cf6ea468bb6a359b256b1e4"}, - {file = "cffi-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:3686dffb02459559c74dd3d81748269ffb0eb027c39a6fc99502de37d501faa8"}, - {file = "cffi-1.16.0.tar.gz", hash = "sha256:bcb3ef43e58665bbda2fb198698fcae6776483e0c4a631aa5647806c25e02cc0"}, + {file = "cffi-1.17.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f9338cc05451f1942d0d8203ec2c346c830f8e86469903d5126c1f0a13a2bcbb"}, + {file = "cffi-1.17.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a0ce71725cacc9ebf839630772b07eeec220cbb5f03be1399e0457a1464f8e1a"}, + {file = "cffi-1.17.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c815270206f983309915a6844fe994b2fa47e5d05c4c4cef267c3b30e34dbe42"}, + {file = "cffi-1.17.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d6bdcd415ba87846fd317bee0774e412e8792832e7805938987e4ede1d13046d"}, + {file = "cffi-1.17.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8a98748ed1a1df4ee1d6f927e151ed6c1a09d5ec21684de879c7ea6aa96f58f2"}, + {file = "cffi-1.17.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0a048d4f6630113e54bb4b77e315e1ba32a5a31512c31a273807d0027a7e69ab"}, + {file = "cffi-1.17.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:24aa705a5f5bd3a8bcfa4d123f03413de5d86e497435693b638cbffb7d5d8a1b"}, + {file = "cffi-1.17.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:856bf0924d24e7f93b8aee12a3a1095c34085600aa805693fb7f5d1962393206"}, + {file = "cffi-1.17.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:4304d4416ff032ed50ad6bb87416d802e67139e31c0bde4628f36a47a3164bfa"}, + {file = "cffi-1.17.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:331ad15c39c9fe9186ceaf87203a9ecf5ae0ba2538c9e898e3a6967e8ad3db6f"}, + {file = "cffi-1.17.0-cp310-cp310-win32.whl", hash = "sha256:669b29a9eca6146465cc574659058ed949748f0809a2582d1f1a324eb91054dc"}, + {file = "cffi-1.17.0-cp310-cp310-win_amd64.whl", hash = "sha256:48b389b1fd5144603d61d752afd7167dfd205973a43151ae5045b35793232aa2"}, + {file = "cffi-1.17.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c5d97162c196ce54af6700949ddf9409e9833ef1003b4741c2b39ef46f1d9720"}, + {file = "cffi-1.17.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5ba5c243f4004c750836f81606a9fcb7841f8874ad8f3bf204ff5e56332b72b9"}, + {file = "cffi-1.17.0-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bb9333f58fc3a2296fb1d54576138d4cf5d496a2cc118422bd77835e6ae0b9cb"}, + {file = "cffi-1.17.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:435a22d00ec7d7ea533db494da8581b05977f9c37338c80bc86314bec2619424"}, + {file = "cffi-1.17.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d1df34588123fcc88c872f5acb6f74ae59e9d182a2707097f9e28275ec26a12d"}, + {file = "cffi-1.17.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:df8bb0010fdd0a743b7542589223a2816bdde4d94bb5ad67884348fa2c1c67e8"}, + {file = "cffi-1.17.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8b5b9712783415695663bd463990e2f00c6750562e6ad1d28e072a611c5f2a6"}, + {file = "cffi-1.17.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ffef8fd58a36fb5f1196919638f73dd3ae0db1a878982b27a9a5a176ede4ba91"}, + {file = "cffi-1.17.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:4e67d26532bfd8b7f7c05d5a766d6f437b362c1bf203a3a5ce3593a645e870b8"}, + {file = "cffi-1.17.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:45f7cd36186db767d803b1473b3c659d57a23b5fa491ad83c6d40f2af58e4dbb"}, + {file = "cffi-1.17.0-cp311-cp311-win32.whl", hash = "sha256:a9015f5b8af1bb6837a3fcb0cdf3b874fe3385ff6274e8b7925d81ccaec3c5c9"}, + {file = "cffi-1.17.0-cp311-cp311-win_amd64.whl", hash = "sha256:b50aaac7d05c2c26dfd50c3321199f019ba76bb650e346a6ef3616306eed67b0"}, + {file = "cffi-1.17.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:aec510255ce690d240f7cb23d7114f6b351c733a74c279a84def763660a2c3bc"}, + {file = "cffi-1.17.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2770bb0d5e3cc0e31e7318db06efcbcdb7b31bcb1a70086d3177692a02256f59"}, + {file = "cffi-1.17.0-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:db9a30ec064129d605d0f1aedc93e00894b9334ec74ba9c6bdd08147434b33eb"}, + {file = "cffi-1.17.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a47eef975d2b8b721775a0fa286f50eab535b9d56c70a6e62842134cf7841195"}, + {file = "cffi-1.17.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f3e0992f23bbb0be00a921eae5363329253c3b86287db27092461c887b791e5e"}, + {file = "cffi-1.17.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6107e445faf057c118d5050560695e46d272e5301feffda3c41849641222a828"}, + {file = "cffi-1.17.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eb862356ee9391dc5a0b3cbc00f416b48c1b9a52d252d898e5b7696a5f9fe150"}, + {file = "cffi-1.17.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:c1c13185b90bbd3f8b5963cd8ce7ad4ff441924c31e23c975cb150e27c2bf67a"}, + {file = "cffi-1.17.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:17c6d6d3260c7f2d94f657e6872591fe8733872a86ed1345bda872cfc8c74885"}, + {file = "cffi-1.17.0-cp312-cp312-win32.whl", hash = "sha256:c3b8bd3133cd50f6b637bb4322822c94c5ce4bf0d724ed5ae70afce62187c492"}, + {file = "cffi-1.17.0-cp312-cp312-win_amd64.whl", hash = "sha256:dca802c8db0720ce1c49cce1149ff7b06e91ba15fa84b1d59144fef1a1bc7ac2"}, + {file = "cffi-1.17.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:6ce01337d23884b21c03869d2f68c5523d43174d4fc405490eb0091057943118"}, + {file = "cffi-1.17.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:cab2eba3830bf4f6d91e2d6718e0e1c14a2f5ad1af68a89d24ace0c6b17cced7"}, + {file = "cffi-1.17.0-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:14b9cbc8f7ac98a739558eb86fabc283d4d564dafed50216e7f7ee62d0d25377"}, + {file = "cffi-1.17.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b00e7bcd71caa0282cbe3c90966f738e2db91e64092a877c3ff7f19a1628fdcb"}, + {file = "cffi-1.17.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:41f4915e09218744d8bae14759f983e466ab69b178de38066f7579892ff2a555"}, + {file = "cffi-1.17.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e4760a68cab57bfaa628938e9c2971137e05ce48e762a9cb53b76c9b569f1204"}, + {file = "cffi-1.17.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:011aff3524d578a9412c8b3cfaa50f2c0bd78e03eb7af7aa5e0df59b158efb2f"}, + {file = "cffi-1.17.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:a003ac9edc22d99ae1286b0875c460351f4e101f8c9d9d2576e78d7e048f64e0"}, + {file = "cffi-1.17.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ef9528915df81b8f4c7612b19b8628214c65c9b7f74db2e34a646a0a2a0da2d4"}, + {file = "cffi-1.17.0-cp313-cp313-win32.whl", hash = "sha256:70d2aa9fb00cf52034feac4b913181a6e10356019b18ef89bc7c12a283bf5f5a"}, + {file = "cffi-1.17.0-cp313-cp313-win_amd64.whl", hash = "sha256:b7b6ea9e36d32582cda3465f54c4b454f62f23cb083ebc7a94e2ca6ef011c3a7"}, + {file = "cffi-1.17.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:964823b2fc77b55355999ade496c54dde161c621cb1f6eac61dc30ed1b63cd4c"}, + {file = "cffi-1.17.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:516a405f174fd3b88829eabfe4bb296ac602d6a0f68e0d64d5ac9456194a5b7e"}, + {file = "cffi-1.17.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dec6b307ce928e8e112a6bb9921a1cb00a0e14979bf28b98e084a4b8a742bd9b"}, + {file = "cffi-1.17.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e4094c7b464cf0a858e75cd14b03509e84789abf7b79f8537e6a72152109c76e"}, + {file = "cffi-1.17.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2404f3de742f47cb62d023f0ba7c5a916c9c653d5b368cc966382ae4e57da401"}, + {file = "cffi-1.17.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3aa9d43b02a0c681f0bfbc12d476d47b2b2b6a3f9287f11ee42989a268a1833c"}, + {file = "cffi-1.17.0-cp38-cp38-win32.whl", hash = "sha256:0bb15e7acf8ab35ca8b24b90af52c8b391690ef5c4aec3d31f38f0d37d2cc499"}, + {file = "cffi-1.17.0-cp38-cp38-win_amd64.whl", hash = "sha256:93a7350f6706b31f457c1457d3a3259ff9071a66f312ae64dc024f049055f72c"}, + {file = "cffi-1.17.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:1a2ddbac59dc3716bc79f27906c010406155031a1c801410f1bafff17ea304d2"}, + {file = "cffi-1.17.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:6327b572f5770293fc062a7ec04160e89741e8552bf1c358d1a23eba68166759"}, + {file = "cffi-1.17.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbc183e7bef690c9abe5ea67b7b60fdbca81aa8da43468287dae7b5c046107d4"}, + {file = "cffi-1.17.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5bdc0f1f610d067c70aa3737ed06e2726fd9d6f7bfee4a351f4c40b6831f4e82"}, + {file = "cffi-1.17.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6d872186c1617d143969defeadac5a904e6e374183e07977eedef9c07c8953bf"}, + {file = "cffi-1.17.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0d46ee4764b88b91f16661a8befc6bfb24806d885e27436fdc292ed7e6f6d058"}, + {file = "cffi-1.17.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f76a90c345796c01d85e6332e81cab6d70de83b829cf1d9762d0a3da59c7932"}, + {file = "cffi-1.17.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0e60821d312f99d3e1569202518dddf10ae547e799d75aef3bca3a2d9e8ee693"}, + {file = "cffi-1.17.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:eb09b82377233b902d4c3fbeeb7ad731cdab579c6c6fda1f763cd779139e47c3"}, + {file = "cffi-1.17.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:24658baf6224d8f280e827f0a50c46ad819ec8ba380a42448e24459daf809cf4"}, + {file = "cffi-1.17.0-cp39-cp39-win32.whl", hash = "sha256:0fdacad9e0d9fc23e519efd5ea24a70348305e8d7d85ecbb1a5fa66dc834e7fb"}, + {file = "cffi-1.17.0-cp39-cp39-win_amd64.whl", hash = "sha256:7cbc78dc018596315d4e7841c8c3a7ae31cc4d638c9b627f87d52e8abaaf2d29"}, + {file = "cffi-1.17.0.tar.gz", hash = "sha256:f3157624b7558b914cb039fd1af735e5e8049a87c817cc215109ad1c8779df76"}, ] [package.dependencies] @@ -543,33 +558,33 @@ files = [ [[package]] name = "debugpy" -version = "1.8.1" +version = "1.8.5" description = "An implementation of the Debug Adapter Protocol for Python" optional = true python-versions = ">=3.8" files = [ - {file = "debugpy-1.8.1-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:3bda0f1e943d386cc7a0e71bfa59f4137909e2ed947fb3946c506e113000f741"}, - {file = "debugpy-1.8.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dda73bf69ea479c8577a0448f8c707691152e6c4de7f0c4dec5a4bc11dee516e"}, - {file = "debugpy-1.8.1-cp310-cp310-win32.whl", hash = "sha256:3a79c6f62adef994b2dbe9fc2cc9cc3864a23575b6e387339ab739873bea53d0"}, - {file = "debugpy-1.8.1-cp310-cp310-win_amd64.whl", hash = "sha256:7eb7bd2b56ea3bedb009616d9e2f64aab8fc7000d481faec3cd26c98a964bcdd"}, - {file = "debugpy-1.8.1-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:016a9fcfc2c6b57f939673c874310d8581d51a0fe0858e7fac4e240c5eb743cb"}, - {file = "debugpy-1.8.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd97ed11a4c7f6d042d320ce03d83b20c3fb40da892f994bc041bbc415d7a099"}, - {file = "debugpy-1.8.1-cp311-cp311-win32.whl", hash = "sha256:0de56aba8249c28a300bdb0672a9b94785074eb82eb672db66c8144fff673146"}, - {file = "debugpy-1.8.1-cp311-cp311-win_amd64.whl", hash = "sha256:1a9fe0829c2b854757b4fd0a338d93bc17249a3bf69ecf765c61d4c522bb92a8"}, - {file = "debugpy-1.8.1-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:3ebb70ba1a6524d19fa7bb122f44b74170c447d5746a503e36adc244a20ac539"}, - {file = "debugpy-1.8.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a2e658a9630f27534e63922ebf655a6ab60c370f4d2fc5c02a5b19baf4410ace"}, - {file = "debugpy-1.8.1-cp312-cp312-win32.whl", hash = "sha256:caad2846e21188797a1f17fc09c31b84c7c3c23baf2516fed5b40b378515bbf0"}, - {file = "debugpy-1.8.1-cp312-cp312-win_amd64.whl", hash = "sha256:edcc9f58ec0fd121a25bc950d4578df47428d72e1a0d66c07403b04eb93bcf98"}, - {file = "debugpy-1.8.1-cp38-cp38-macosx_11_0_x86_64.whl", hash = "sha256:7a3afa222f6fd3d9dfecd52729bc2e12c93e22a7491405a0ecbf9e1d32d45b39"}, - {file = "debugpy-1.8.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d915a18f0597ef685e88bb35e5d7ab968964b7befefe1aaea1eb5b2640b586c7"}, - {file = "debugpy-1.8.1-cp38-cp38-win32.whl", hash = "sha256:92116039b5500633cc8d44ecc187abe2dfa9b90f7a82bbf81d079fcdd506bae9"}, - {file = "debugpy-1.8.1-cp38-cp38-win_amd64.whl", hash = "sha256:e38beb7992b5afd9d5244e96ad5fa9135e94993b0c551ceebf3fe1a5d9beb234"}, - {file = "debugpy-1.8.1-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:bfb20cb57486c8e4793d41996652e5a6a885b4d9175dd369045dad59eaacea42"}, - {file = "debugpy-1.8.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:efd3fdd3f67a7e576dd869c184c5dd71d9aaa36ded271939da352880c012e703"}, - {file = "debugpy-1.8.1-cp39-cp39-win32.whl", hash = "sha256:58911e8521ca0c785ac7a0539f1e77e0ce2df753f786188f382229278b4cdf23"}, - {file = "debugpy-1.8.1-cp39-cp39-win_amd64.whl", hash = "sha256:6df9aa9599eb05ca179fb0b810282255202a66835c6efb1d112d21ecb830ddd3"}, - {file = "debugpy-1.8.1-py2.py3-none-any.whl", hash = "sha256:28acbe2241222b87e255260c76741e1fbf04fdc3b6d094fcf57b6c6f75ce1242"}, - {file = "debugpy-1.8.1.zip", hash = "sha256:f696d6be15be87aef621917585f9bb94b1dc9e8aced570db1b8a6fc14e8f9b42"}, + {file = "debugpy-1.8.5-cp310-cp310-macosx_12_0_x86_64.whl", hash = "sha256:7e4d594367d6407a120b76bdaa03886e9eb652c05ba7f87e37418426ad2079f7"}, + {file = "debugpy-1.8.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4413b7a3ede757dc33a273a17d685ea2b0c09dbd312cc03f5534a0fd4d40750a"}, + {file = "debugpy-1.8.5-cp310-cp310-win32.whl", hash = "sha256:dd3811bd63632bb25eda6bd73bea8e0521794cda02be41fa3160eb26fc29e7ed"}, + {file = "debugpy-1.8.5-cp310-cp310-win_amd64.whl", hash = "sha256:b78c1250441ce893cb5035dd6f5fc12db968cc07f91cc06996b2087f7cefdd8e"}, + {file = "debugpy-1.8.5-cp311-cp311-macosx_12_0_universal2.whl", hash = "sha256:606bccba19f7188b6ea9579c8a4f5a5364ecd0bf5a0659c8a5d0e10dcee3032a"}, + {file = "debugpy-1.8.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db9fb642938a7a609a6c865c32ecd0d795d56c1aaa7a7a5722d77855d5e77f2b"}, + {file = "debugpy-1.8.5-cp311-cp311-win32.whl", hash = "sha256:4fbb3b39ae1aa3e5ad578f37a48a7a303dad9a3d018d369bc9ec629c1cfa7408"}, + {file = "debugpy-1.8.5-cp311-cp311-win_amd64.whl", hash = "sha256:345d6a0206e81eb68b1493ce2fbffd57c3088e2ce4b46592077a943d2b968ca3"}, + {file = "debugpy-1.8.5-cp312-cp312-macosx_12_0_universal2.whl", hash = "sha256:5b5c770977c8ec6c40c60d6f58cacc7f7fe5a45960363d6974ddb9b62dbee156"}, + {file = "debugpy-1.8.5-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0a65b00b7cdd2ee0c2cf4c7335fef31e15f1b7056c7fdbce9e90193e1a8c8cb"}, + {file = "debugpy-1.8.5-cp312-cp312-win32.whl", hash = "sha256:c9f7c15ea1da18d2fcc2709e9f3d6de98b69a5b0fff1807fb80bc55f906691f7"}, + {file = "debugpy-1.8.5-cp312-cp312-win_amd64.whl", hash = "sha256:28ced650c974aaf179231668a293ecd5c63c0a671ae6d56b8795ecc5d2f48d3c"}, + {file = "debugpy-1.8.5-cp38-cp38-macosx_12_0_x86_64.whl", hash = "sha256:3df6692351172a42af7558daa5019651f898fc67450bf091335aa8a18fbf6f3a"}, + {file = "debugpy-1.8.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1cd04a73eb2769eb0bfe43f5bfde1215c5923d6924b9b90f94d15f207a402226"}, + {file = "debugpy-1.8.5-cp38-cp38-win32.whl", hash = "sha256:8f913ee8e9fcf9d38a751f56e6de12a297ae7832749d35de26d960f14280750a"}, + {file = "debugpy-1.8.5-cp38-cp38-win_amd64.whl", hash = "sha256:a697beca97dad3780b89a7fb525d5e79f33821a8bc0c06faf1f1289e549743cf"}, + {file = "debugpy-1.8.5-cp39-cp39-macosx_12_0_x86_64.whl", hash = "sha256:0a1029a2869d01cb777216af8c53cda0476875ef02a2b6ff8b2f2c9a4b04176c"}, + {file = "debugpy-1.8.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e84c276489e141ed0b93b0af648eef891546143d6a48f610945416453a8ad406"}, + {file = "debugpy-1.8.5-cp39-cp39-win32.whl", hash = "sha256:ad84b7cde7fd96cf6eea34ff6c4a1b7887e0fe2ea46e099e53234856f9d99a34"}, + {file = "debugpy-1.8.5-cp39-cp39-win_amd64.whl", hash = "sha256:7b0fe36ed9d26cb6836b0a51453653f8f2e347ba7348f2bbfe76bfeb670bfb1c"}, + {file = "debugpy-1.8.5-py2.py3-none-any.whl", hash = "sha256:55919dce65b471eff25901acf82d328bbd5b833526b6c1364bd5133754777a44"}, + {file = "debugpy-1.8.5.zip", hash = "sha256:b2112cfeb34b4507399d298fe7023a16656fc553ed5246536060ca7bd0e668d0"}, ] [[package]] @@ -617,13 +632,13 @@ files = [ [[package]] name = "exceptiongroup" -version = "1.2.1" +version = "1.2.2" description = "Backport of PEP 654 (exception groups)" optional = true python-versions = ">=3.7" files = [ - {file = "exceptiongroup-1.2.1-py3-none-any.whl", hash = "sha256:5258b9ed329c5bbdd31a309f53cbfb0b155341807f6ff7606a1e801a891b29ad"}, - {file = "exceptiongroup-1.2.1.tar.gz", hash = "sha256:a4785e48b045528f5bfe627b6ad554ff32def154f42372786903b7abcfe1aa16"}, + {file = "exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b"}, + {file = "exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc"}, ] [package.extras] @@ -645,13 +660,13 @@ tests = ["asttokens (>=2.1.0)", "coverage", "coverage-enable-subprocess", "ipyth [[package]] name = "fastjsonschema" -version = "2.19.1" +version = "2.20.0" description = "Fastest Python implementation of JSON schema" optional = true python-versions = "*" files = [ - {file = "fastjsonschema-2.19.1-py3-none-any.whl", hash = "sha256:3672b47bc94178c9f23dbb654bf47440155d4db9df5f7bc47643315f9c405cd0"}, - {file = "fastjsonschema-2.19.1.tar.gz", hash = "sha256:e3126a94bdc4623d3de4485f8d468a12f02a67921315ddc87836d6e456dc789d"}, + {file = "fastjsonschema-2.20.0-py3-none-any.whl", hash = "sha256:5875f0b0fa7a0043a91e93a9b8f793bcbbba9691e7fd83dca95c28ba26d21f0a"}, + {file = "fastjsonschema-2.20.0.tar.gz", hash = "sha256:3d48fc5300ee96f5d116f10fe6f28d938e6008f59a6a025c2649475b87f76a23"}, ] [package.extras] @@ -659,53 +674,53 @@ devel = ["colorama", "json-spec", "jsonschema", "pylint", "pytest", "pytest-benc [[package]] name = "fonttools" -version = "4.51.0" +version = "4.53.1" description = "Tools to manipulate font files" optional = true python-versions = ">=3.8" files = [ - {file = "fonttools-4.51.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:84d7751f4468dd8cdd03ddada18b8b0857a5beec80bce9f435742abc9a851a74"}, - {file = "fonttools-4.51.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:8b4850fa2ef2cfbc1d1f689bc159ef0f45d8d83298c1425838095bf53ef46308"}, - {file = "fonttools-4.51.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b5b48a1121117047d82695d276c2af2ee3a24ffe0f502ed581acc2673ecf1037"}, - {file = "fonttools-4.51.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:180194c7fe60c989bb627d7ed5011f2bef1c4d36ecf3ec64daec8302f1ae0716"}, - {file = "fonttools-4.51.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:96a48e137c36be55e68845fc4284533bda2980f8d6f835e26bca79d7e2006438"}, - {file = "fonttools-4.51.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:806e7912c32a657fa39d2d6eb1d3012d35f841387c8fc6cf349ed70b7c340039"}, - {file = "fonttools-4.51.0-cp310-cp310-win32.whl", hash = "sha256:32b17504696f605e9e960647c5f64b35704782a502cc26a37b800b4d69ff3c77"}, - {file = "fonttools-4.51.0-cp310-cp310-win_amd64.whl", hash = "sha256:c7e91abdfae1b5c9e3a543f48ce96013f9a08c6c9668f1e6be0beabf0a569c1b"}, - {file = "fonttools-4.51.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:a8feca65bab31479d795b0d16c9a9852902e3a3c0630678efb0b2b7941ea9c74"}, - {file = "fonttools-4.51.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8ac27f436e8af7779f0bb4d5425aa3535270494d3bc5459ed27de3f03151e4c2"}, - {file = "fonttools-4.51.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0e19bd9e9964a09cd2433a4b100ca7f34e34731e0758e13ba9a1ed6e5468cc0f"}, - {file = "fonttools-4.51.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b2b92381f37b39ba2fc98c3a45a9d6383bfc9916a87d66ccb6553f7bdd129097"}, - {file = "fonttools-4.51.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:5f6bc991d1610f5c3bbe997b0233cbc234b8e82fa99fc0b2932dc1ca5e5afec0"}, - {file = "fonttools-4.51.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9696fe9f3f0c32e9a321d5268208a7cc9205a52f99b89479d1b035ed54c923f1"}, - {file = "fonttools-4.51.0-cp311-cp311-win32.whl", hash = "sha256:3bee3f3bd9fa1d5ee616ccfd13b27ca605c2b4270e45715bd2883e9504735034"}, - {file = "fonttools-4.51.0-cp311-cp311-win_amd64.whl", hash = "sha256:0f08c901d3866a8905363619e3741c33f0a83a680d92a9f0e575985c2634fcc1"}, - {file = "fonttools-4.51.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:4060acc2bfa2d8e98117828a238889f13b6f69d59f4f2d5857eece5277b829ba"}, - {file = "fonttools-4.51.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:1250e818b5f8a679ad79660855528120a8f0288f8f30ec88b83db51515411fcc"}, - {file = "fonttools-4.51.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76f1777d8b3386479ffb4a282e74318e730014d86ce60f016908d9801af9ca2a"}, - {file = "fonttools-4.51.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8b5ad456813d93b9c4b7ee55302208db2b45324315129d85275c01f5cb7e61a2"}, - {file = "fonttools-4.51.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:68b3fb7775a923be73e739f92f7e8a72725fd333eab24834041365d2278c3671"}, - {file = "fonttools-4.51.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8e2f1a4499e3b5ee82c19b5ee57f0294673125c65b0a1ff3764ea1f9db2f9ef5"}, - {file = "fonttools-4.51.0-cp312-cp312-win32.whl", hash = "sha256:278e50f6b003c6aed19bae2242b364e575bcb16304b53f2b64f6551b9c000e15"}, - {file = "fonttools-4.51.0-cp312-cp312-win_amd64.whl", hash = "sha256:b3c61423f22165541b9403ee39874dcae84cd57a9078b82e1dce8cb06b07fa2e"}, - {file = "fonttools-4.51.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:1621ee57da887c17312acc4b0e7ac30d3a4fb0fec6174b2e3754a74c26bbed1e"}, - {file = "fonttools-4.51.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:e9d9298be7a05bb4801f558522adbe2feea1b0b103d5294ebf24a92dd49b78e5"}, - {file = "fonttools-4.51.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ee1af4be1c5afe4c96ca23badd368d8dc75f611887fb0c0dac9f71ee5d6f110e"}, - {file = "fonttools-4.51.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c18b49adc721a7d0b8dfe7c3130c89b8704baf599fb396396d07d4aa69b824a1"}, - {file = "fonttools-4.51.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:de7c29bdbdd35811f14493ffd2534b88f0ce1b9065316433b22d63ca1cd21f14"}, - {file = "fonttools-4.51.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:cadf4e12a608ef1d13e039864f484c8a968840afa0258b0b843a0556497ea9ed"}, - {file = "fonttools-4.51.0-cp38-cp38-win32.whl", hash = "sha256:aefa011207ed36cd280babfaa8510b8176f1a77261833e895a9d96e57e44802f"}, - {file = "fonttools-4.51.0-cp38-cp38-win_amd64.whl", hash = "sha256:865a58b6e60b0938874af0968cd0553bcd88e0b2cb6e588727117bd099eef836"}, - {file = "fonttools-4.51.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:60a3409c9112aec02d5fb546f557bca6efa773dcb32ac147c6baf5f742e6258b"}, - {file = "fonttools-4.51.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f7e89853d8bea103c8e3514b9f9dc86b5b4120afb4583b57eb10dfa5afbe0936"}, - {file = "fonttools-4.51.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:56fc244f2585d6c00b9bcc59e6593e646cf095a96fe68d62cd4da53dd1287b55"}, - {file = "fonttools-4.51.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0d145976194a5242fdd22df18a1b451481a88071feadf251221af110ca8f00ce"}, - {file = "fonttools-4.51.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:c5b8cab0c137ca229433570151b5c1fc6af212680b58b15abd797dcdd9dd5051"}, - {file = "fonttools-4.51.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:54dcf21a2f2d06ded676e3c3f9f74b2bafded3a8ff12f0983160b13e9f2fb4a7"}, - {file = "fonttools-4.51.0-cp39-cp39-win32.whl", hash = "sha256:0118ef998a0699a96c7b28457f15546815015a2710a1b23a7bf6c1be60c01636"}, - {file = "fonttools-4.51.0-cp39-cp39-win_amd64.whl", hash = "sha256:599bdb75e220241cedc6faebfafedd7670335d2e29620d207dd0378a4e9ccc5a"}, - {file = "fonttools-4.51.0-py3-none-any.whl", hash = "sha256:15c94eeef6b095831067f72c825eb0e2d48bb4cea0647c1b05c981ecba2bf39f"}, - {file = "fonttools-4.51.0.tar.gz", hash = "sha256:dc0673361331566d7a663d7ce0f6fdcbfbdc1f59c6e3ed1165ad7202ca183c68"}, + {file = "fonttools-4.53.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0679a30b59d74b6242909945429dbddb08496935b82f91ea9bf6ad240ec23397"}, + {file = "fonttools-4.53.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e8bf06b94694251861ba7fdeea15c8ec0967f84c3d4143ae9daf42bbc7717fe3"}, + {file = "fonttools-4.53.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b96cd370a61f4d083c9c0053bf634279b094308d52fdc2dd9a22d8372fdd590d"}, + {file = "fonttools-4.53.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a1c7c5aa18dd3b17995898b4a9b5929d69ef6ae2af5b96d585ff4005033d82f0"}, + {file = "fonttools-4.53.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:e013aae589c1c12505da64a7d8d023e584987e51e62006e1bb30d72f26522c41"}, + {file = "fonttools-4.53.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:9efd176f874cb6402e607e4cc9b4a9cd584d82fc34a4b0c811970b32ba62501f"}, + {file = "fonttools-4.53.1-cp310-cp310-win32.whl", hash = "sha256:c8696544c964500aa9439efb6761947393b70b17ef4e82d73277413f291260a4"}, + {file = "fonttools-4.53.1-cp310-cp310-win_amd64.whl", hash = "sha256:8959a59de5af6d2bec27489e98ef25a397cfa1774b375d5787509c06659b3671"}, + {file = "fonttools-4.53.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:da33440b1413bad53a8674393c5d29ce64d8c1a15ef8a77c642ffd900d07bfe1"}, + {file = "fonttools-4.53.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5ff7e5e9bad94e3a70c5cd2fa27f20b9bb9385e10cddab567b85ce5d306ea923"}, + {file = "fonttools-4.53.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c6e7170d675d12eac12ad1a981d90f118c06cf680b42a2d74c6c931e54b50719"}, + {file = "fonttools-4.53.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bee32ea8765e859670c4447b0817514ca79054463b6b79784b08a8df3a4d78e3"}, + {file = "fonttools-4.53.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6e08f572625a1ee682115223eabebc4c6a2035a6917eac6f60350aba297ccadb"}, + {file = "fonttools-4.53.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b21952c092ffd827504de7e66b62aba26fdb5f9d1e435c52477e6486e9d128b2"}, + {file = "fonttools-4.53.1-cp311-cp311-win32.whl", hash = "sha256:9dfdae43b7996af46ff9da520998a32b105c7f098aeea06b2226b30e74fbba88"}, + {file = "fonttools-4.53.1-cp311-cp311-win_amd64.whl", hash = "sha256:d4d0096cb1ac7a77b3b41cd78c9b6bc4a400550e21dc7a92f2b5ab53ed74eb02"}, + {file = "fonttools-4.53.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:d92d3c2a1b39631a6131c2fa25b5406855f97969b068e7e08413325bc0afba58"}, + {file = "fonttools-4.53.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3b3c8ebafbee8d9002bd8f1195d09ed2bd9ff134ddec37ee8f6a6375e6a4f0e8"}, + {file = "fonttools-4.53.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:32f029c095ad66c425b0ee85553d0dc326d45d7059dbc227330fc29b43e8ba60"}, + {file = "fonttools-4.53.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10f5e6c3510b79ea27bb1ebfcc67048cde9ec67afa87c7dd7efa5c700491ac7f"}, + {file = "fonttools-4.53.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:f677ce218976496a587ab17140da141557beb91d2a5c1a14212c994093f2eae2"}, + {file = "fonttools-4.53.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:9e6ceba2a01b448e36754983d376064730690401da1dd104ddb543519470a15f"}, + {file = "fonttools-4.53.1-cp312-cp312-win32.whl", hash = "sha256:791b31ebbc05197d7aa096bbc7bd76d591f05905d2fd908bf103af4488e60670"}, + {file = "fonttools-4.53.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ed170b5e17da0264b9f6fae86073be3db15fa1bd74061c8331022bca6d09bab"}, + {file = "fonttools-4.53.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:c818c058404eb2bba05e728d38049438afd649e3c409796723dfc17cd3f08749"}, + {file = "fonttools-4.53.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:651390c3b26b0c7d1f4407cad281ee7a5a85a31a110cbac5269de72a51551ba2"}, + {file = "fonttools-4.53.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e54f1bba2f655924c1138bbc7fa91abd61f45c68bd65ab5ed985942712864bbb"}, + {file = "fonttools-4.53.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c9cd19cf4fe0595ebdd1d4915882b9440c3a6d30b008f3cc7587c1da7b95be5f"}, + {file = "fonttools-4.53.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:2af40ae9cdcb204fc1d8f26b190aa16534fcd4f0df756268df674a270eab575d"}, + {file = "fonttools-4.53.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:35250099b0cfb32d799fb5d6c651220a642fe2e3c7d2560490e6f1d3f9ae9169"}, + {file = "fonttools-4.53.1-cp38-cp38-win32.whl", hash = "sha256:f08df60fbd8d289152079a65da4e66a447efc1d5d5a4d3f299cdd39e3b2e4a7d"}, + {file = "fonttools-4.53.1-cp38-cp38-win_amd64.whl", hash = "sha256:7b6b35e52ddc8fb0db562133894e6ef5b4e54e1283dff606fda3eed938c36fc8"}, + {file = "fonttools-4.53.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:75a157d8d26c06e64ace9df037ee93a4938a4606a38cb7ffaf6635e60e253b7a"}, + {file = "fonttools-4.53.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4824c198f714ab5559c5be10fd1adf876712aa7989882a4ec887bf1ef3e00e31"}, + {file = "fonttools-4.53.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:becc5d7cb89c7b7afa8321b6bb3dbee0eec2b57855c90b3e9bf5fb816671fa7c"}, + {file = "fonttools-4.53.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:84ec3fb43befb54be490147b4a922b5314e16372a643004f182babee9f9c3407"}, + {file = "fonttools-4.53.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:73379d3ffdeecb376640cd8ed03e9d2d0e568c9d1a4e9b16504a834ebadc2dfb"}, + {file = "fonttools-4.53.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:02569e9a810f9d11f4ae82c391ebc6fb5730d95a0657d24d754ed7763fb2d122"}, + {file = "fonttools-4.53.1-cp39-cp39-win32.whl", hash = "sha256:aae7bd54187e8bf7fd69f8ab87b2885253d3575163ad4d669a262fe97f0136cb"}, + {file = "fonttools-4.53.1-cp39-cp39-win_amd64.whl", hash = "sha256:e5b708073ea3d684235648786f5f6153a48dc8762cdfe5563c57e80787c29fbb"}, + {file = "fonttools-4.53.1-py3-none-any.whl", hash = "sha256:f1f8758a2ad110bd6432203a344269f445a2907dc24ef6bccfd0ac4e14e0d71d"}, + {file = "fonttools-4.53.1.tar.gz", hash = "sha256:e128778a8e9bc11159ce5447f76766cefbd876f44bd79aff030287254e4752c4"}, ] [package.extras] @@ -802,50 +817,50 @@ files = [ [[package]] name = "importlib-metadata" -version = "7.1.0" +version = "8.2.0" description = "Read metadata from Python packages" optional = true python-versions = ">=3.8" files = [ - {file = "importlib_metadata-7.1.0-py3-none-any.whl", hash = "sha256:30962b96c0c223483ed6cc7280e7f0199feb01a0e40cfae4d4450fc6fab1f570"}, - {file = "importlib_metadata-7.1.0.tar.gz", hash = "sha256:b78938b926ee8d5f020fc4772d487045805a55ddbad2ecf21c6d60938dc7fcd2"}, + {file = "importlib_metadata-8.2.0-py3-none-any.whl", hash = "sha256:11901fa0c2f97919b288679932bb64febaeacf289d18ac84dd68cb2e74213369"}, + {file = "importlib_metadata-8.2.0.tar.gz", hash = "sha256:72e8d4399996132204f9a16dcc751af254a48f8d1b20b9ff0f98d4a8f901e73d"}, ] [package.dependencies] zipp = ">=0.5" [package.extras] -docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] perf = ["ipython"] -testing = ["flufl.flake8", "importlib-resources (>=1.3)", "jaraco.test (>=5.4)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy", "pytest-perf (>=0.9.2)", "pytest-ruff (>=0.2.1)"] +test = ["flufl.flake8", "importlib-resources (>=1.3)", "jaraco.test (>=5.4)", "packaging", "pyfakefs", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy", "pytest-perf (>=0.9.2)", "pytest-ruff (>=0.2.1)"] [[package]] name = "importlib-resources" -version = "6.4.0" +version = "6.4.2" description = "Read resources from Python packages" optional = true python-versions = ">=3.8" files = [ - {file = "importlib_resources-6.4.0-py3-none-any.whl", hash = "sha256:50d10f043df931902d4194ea07ec57960f66a80449ff867bfe782b4c486ba78c"}, - {file = "importlib_resources-6.4.0.tar.gz", hash = "sha256:cdb2b453b8046ca4e3798eb1d84f3cce1446a0e8e7b5ef4efb600f19fc398145"}, + {file = "importlib_resources-6.4.2-py3-none-any.whl", hash = "sha256:8bba8c54a8a3afaa1419910845fa26ebd706dc716dd208d9b158b4b6966f5c5c"}, + {file = "importlib_resources-6.4.2.tar.gz", hash = "sha256:6cbfbefc449cc6e2095dd184691b7a12a04f40bc75dd4c55d31c34f174cdf57a"}, ] [package.dependencies] zipp = {version = ">=3.1.0", markers = "python_version < \"3.10\""} [package.extras] -docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-lint"] -testing = ["jaraco.test (>=5.4)", "pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy", "pytest-ruff (>=0.2.1)", "zipp (>=3.17)"] +doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +test = ["jaraco.test (>=5.4)", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy", "pytest-ruff (>=0.2.1)", "zipp (>=3.17)"] [[package]] name = "ipykernel" -version = "6.29.4" +version = "6.29.5" description = "IPython Kernel for Jupyter" optional = true python-versions = ">=3.8" files = [ - {file = "ipykernel-6.29.4-py3-none-any.whl", hash = "sha256:1181e653d95c6808039c509ef8e67c4126b3b3af7781496c7cbfb5ed938a27da"}, - {file = "ipykernel-6.29.4.tar.gz", hash = "sha256:3d44070060f9475ac2092b760123fadf105d2e2493c24848b6691a7c4f42af5c"}, + {file = "ipykernel-6.29.5-py3-none-any.whl", hash = "sha256:afdb66ba5aa354b09b91379bac28ae4afebbb30e8b39510c9690afb7a10421b5"}, + {file = "ipykernel-6.29.5.tar.gz", hash = "sha256:f093a22c4a40f8828f8e330a9c297cb93dcab13bd9678ded6de8e5cf81c56215"}, ] [package.dependencies] @@ -909,21 +924,21 @@ test-extra = ["curio", "matplotlib (!=3.2.0)", "nbformat", "numpy (>=1.22)", "pa [[package]] name = "ipywidgets" -version = "8.1.2" +version = "8.1.3" description = "Jupyter interactive widgets" optional = true python-versions = ">=3.7" files = [ - {file = "ipywidgets-8.1.2-py3-none-any.whl", hash = "sha256:bbe43850d79fb5e906b14801d6c01402857996864d1e5b6fa62dd2ee35559f60"}, - {file = "ipywidgets-8.1.2.tar.gz", hash = "sha256:d0b9b41e49bae926a866e613a39b0f0097745d2b9f1f3dd406641b4a57ec42c9"}, + {file = "ipywidgets-8.1.3-py3-none-any.whl", hash = "sha256:efafd18f7a142248f7cb0ba890a68b96abd4d6e88ddbda483c9130d12667eaf2"}, + {file = "ipywidgets-8.1.3.tar.gz", hash = "sha256:f5f9eeaae082b1823ce9eac2575272952f40d748893972956dc09700a6392d9c"}, ] [package.dependencies] comm = ">=0.1.3" ipython = ">=6.1.0" -jupyterlab-widgets = ">=3.0.10,<3.1.0" +jupyterlab-widgets = ">=3.0.11,<3.1.0" traitlets = ">=4.3.1" -widgetsnbextension = ">=4.0.10,<4.1.0" +widgetsnbextension = ">=4.0.11,<4.1.0" [package.extras] test = ["ipykernel", "jsonschema", "pytest (>=3.6.0)", "pytest-cov", "pytz"] @@ -991,24 +1006,24 @@ files = [ [[package]] name = "jsonpointer" -version = "2.4" +version = "3.0.0" description = "Identify specific nodes in a JSON document (RFC 6901)" optional = true -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*, !=3.6.*" +python-versions = ">=3.7" files = [ - {file = "jsonpointer-2.4-py2.py3-none-any.whl", hash = "sha256:15d51bba20eea3165644553647711d150376234112651b4f1811022aecad7d7a"}, - {file = "jsonpointer-2.4.tar.gz", hash = "sha256:585cee82b70211fa9e6043b7bb89db6e1aa49524340dde8ad6b63206ea689d88"}, + {file = "jsonpointer-3.0.0-py2.py3-none-any.whl", hash = "sha256:13e088adc14fca8b6aa8177c044e12701e6ad4b28ff10e65f2267a90109c9942"}, + {file = "jsonpointer-3.0.0.tar.gz", hash = "sha256:2b2d729f2091522d61c3b31f82e11870f60b68f43fbc705cb76bf4b832af59ef"}, ] [[package]] name = "jsonschema" -version = "4.22.0" +version = "4.23.0" description = "An implementation of JSON Schema validation for Python" optional = true python-versions = ">=3.8" files = [ - {file = "jsonschema-4.22.0-py3-none-any.whl", hash = "sha256:ff4cfd6b1367a40e7bc6411caec72effadd3db0bbe5017de188f2d6108335802"}, - {file = "jsonschema-4.22.0.tar.gz", hash = "sha256:5b22d434a45935119af990552c862e5d6d564e8f6601206b305a61fdf661a2b7"}, + {file = "jsonschema-4.23.0-py3-none-any.whl", hash = "sha256:fbadb6f8b144a8f8cf9f0b89ba94501d143e50411a1278633f56a7acf7fd5566"}, + {file = "jsonschema-4.23.0.tar.gz", hash = "sha256:d71497fef26351a33265337fa77ffeb82423f3ea21283cd9467bb03999266bc4"}, ] [package.dependencies] @@ -1023,11 +1038,11 @@ rfc3339-validator = {version = "*", optional = true, markers = "extra == \"forma rfc3986-validator = {version = ">0.1.0", optional = true, markers = "extra == \"format-nongpl\""} rpds-py = ">=0.7.1" uri-template = {version = "*", optional = true, markers = "extra == \"format-nongpl\""} -webcolors = {version = ">=1.11", optional = true, markers = "extra == \"format-nongpl\""} +webcolors = {version = ">=24.6.0", optional = true, markers = "extra == \"format-nongpl\""} [package.extras] format = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3987", "uri-template", "webcolors (>=1.11)"] -format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "uri-template", "webcolors (>=1.11)"] +format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "uri-template", "webcolors (>=24.6.0)"] [[package]] name = "jsonschema-specifications" @@ -1065,13 +1080,13 @@ qtconsole = "*" [[package]] name = "jupyter-client" -version = "8.6.1" +version = "8.6.2" description = "Jupyter protocol implementation and client libraries" optional = true python-versions = ">=3.8" files = [ - {file = "jupyter_client-8.6.1-py3-none-any.whl", hash = "sha256:3b7bd22f058434e3b9a7ea4b1500ed47de2713872288c0d511d19926f99b459f"}, - {file = "jupyter_client-8.6.1.tar.gz", hash = "sha256:e842515e2bab8e19186d89fdfea7abd15e39dd581f94e399f00e2af5a1652d3f"}, + {file = "jupyter_client-8.6.2-py3-none-any.whl", hash = "sha256:50cbc5c66fd1b8f65ecb66bc490ab73217993632809b6e505687de18e9dea39f"}, + {file = "jupyter_client-8.6.2.tar.gz", hash = "sha256:2bda14d55ee5ba58552a8c53ae43d215ad9868853489213f37da060ced54d8df"}, ] [package.dependencies] @@ -1084,7 +1099,7 @@ traitlets = ">=5.3" [package.extras] docs = ["ipykernel", "myst-parser", "pydata-sphinx-theme", "sphinx (>=4)", "sphinx-autodoc-typehints", "sphinxcontrib-github-alt", "sphinxcontrib-spelling"] -test = ["coverage", "ipykernel (>=6.14)", "mypy", "paramiko", "pre-commit", "pytest", "pytest-cov", "pytest-jupyter[client] (>=0.4.1)", "pytest-timeout"] +test = ["coverage", "ipykernel (>=6.14)", "mypy", "paramiko", "pre-commit", "pytest (<8.2.0)", "pytest-cov", "pytest-jupyter[client] (>=0.4.1)", "pytest-timeout"] [[package]] name = "jupyter-console" @@ -1172,13 +1187,13 @@ jupyter-server = ">=1.1.2" [[package]] name = "jupyter-server" -version = "2.14.0" +version = "2.14.2" description = "The backend—i.e. core services, APIs, and REST endpoints—to Jupyter web applications." optional = true python-versions = ">=3.8" files = [ - {file = "jupyter_server-2.14.0-py3-none-any.whl", hash = "sha256:fb6be52c713e80e004fac34b35a0990d6d36ba06fd0a2b2ed82b899143a64210"}, - {file = "jupyter_server-2.14.0.tar.gz", hash = "sha256:659154cea512083434fd7c93b7fe0897af7a2fd0b9dd4749282b42eaac4ae677"}, + {file = "jupyter_server-2.14.2-py3-none-any.whl", hash = "sha256:47ff506127c2f7851a17bf4713434208fc490955d0e8632e95014a9a9afbeefd"}, + {file = "jupyter_server-2.14.2.tar.gz", hash = "sha256:66095021aa9638ced276c248b1d81862e4c50f292d575920bbe960de1c56b12b"}, ] [package.dependencies] @@ -1203,7 +1218,7 @@ traitlets = ">=5.6.0" websocket-client = ">=1.7" [package.extras] -docs = ["ipykernel", "jinja2", "jupyter-client", "jupyter-server", "myst-parser", "nbformat", "prometheus-client", "pydata-sphinx-theme", "send2trash", "sphinx-autodoc-typehints", "sphinxcontrib-github-alt", "sphinxcontrib-openapi (>=0.8.0)", "sphinxcontrib-spelling", "sphinxemoji", "tornado", "typing-extensions"] +docs = ["ipykernel", "jinja2", "jupyter-client", "myst-parser", "nbformat", "prometheus-client", "pydata-sphinx-theme", "send2trash", "sphinx-autodoc-typehints", "sphinxcontrib-github-alt", "sphinxcontrib-openapi (>=0.8.0)", "sphinxcontrib-spelling", "sphinxemoji", "tornado", "typing-extensions"] test = ["flaky", "ipykernel", "pre-commit", "pytest (>=7.0,<9)", "pytest-console-scripts", "pytest-jupyter[server] (>=0.7)", "pytest-timeout", "requests"] [[package]] @@ -1227,13 +1242,13 @@ test = ["jupyter-server (>=2.0.0)", "pytest (>=7.0)", "pytest-jupyter[server] (> [[package]] name = "jupyterlab" -version = "4.2.0" +version = "4.2.4" description = "JupyterLab computational environment" optional = true python-versions = ">=3.8" files = [ - {file = "jupyterlab-4.2.0-py3-none-any.whl", hash = "sha256:0dfe9278e25a145362289c555d9beb505697d269c10e99909766af7c440ad3cc"}, - {file = "jupyterlab-4.2.0.tar.gz", hash = "sha256:356e9205a6a2ab689c47c8fe4919dba6c076e376d03f26baadc05748c2435dd5"}, + {file = "jupyterlab-4.2.4-py3-none-any.whl", hash = "sha256:807a7ec73637744f879e112060d4b9d9ebe028033b7a429b2d1f4fc523d00245"}, + {file = "jupyterlab-4.2.4.tar.gz", hash = "sha256:343a979fb9582fd08c8511823e320703281cd072a0049bcdafdc7afeda7f2537"}, ] [package.dependencies] @@ -1248,6 +1263,7 @@ jupyter-server = ">=2.4.0,<3" jupyterlab-server = ">=2.27.1,<3" notebook-shim = ">=0.2" packaging = "*" +setuptools = ">=40.1.0" tomli = {version = ">=1.2.2", markers = "python_version < \"3.11\""} tornado = ">=6.2.0" traitlets = "*" @@ -1257,7 +1273,7 @@ dev = ["build", "bump2version", "coverage", "hatch", "pre-commit", "pytest-cov", docs = ["jsx-lexer", "myst-parser", "pydata-sphinx-theme (>=0.13.0)", "pytest", "pytest-check-links", "pytest-jupyter", "sphinx (>=1.8,<7.3.0)", "sphinx-copybutton"] docs-screenshots = ["altair (==5.3.0)", "ipython (==8.16.1)", "ipywidgets (==8.1.2)", "jupyterlab-geojson (==3.4.0)", "jupyterlab-language-pack-zh-cn (==4.1.post2)", "matplotlib (==3.8.3)", "nbconvert (>=7.0.0)", "pandas (==2.2.1)", "scipy (==1.12.0)", "vega-datasets (==0.9.0)"] test = ["coverage", "pytest (>=7.0)", "pytest-check-links (>=0.7)", "pytest-console-scripts", "pytest-cov", "pytest-jupyter (>=0.5.3)", "pytest-timeout", "pytest-tornasync", "requests", "requests-cache", "virtualenv"] -upgrade-extension = ["copier (>=8,<10)", "jinja2-time (<0.3)", "pydantic (<2.0)", "pyyaml-include (<2.0)", "tomli-w (<2.0)"] +upgrade-extension = ["copier (>=9,<10)", "jinja2-time (<0.3)", "pydantic (<3.0)", "pyyaml-include (<3.0)", "tomli-w (<2.0)"] [[package]] name = "jupyterlab-pygments" @@ -1272,13 +1288,13 @@ files = [ [[package]] name = "jupyterlab-server" -version = "2.27.1" +version = "2.27.3" description = "A set of server components for JupyterLab and JupyterLab like applications." optional = true python-versions = ">=3.8" files = [ - {file = "jupyterlab_server-2.27.1-py3-none-any.whl", hash = "sha256:f5e26156e5258b24d532c84e7c74cc212e203bff93eb856f81c24c16daeecc75"}, - {file = "jupyterlab_server-2.27.1.tar.gz", hash = "sha256:097b5ac709b676c7284ac9c5e373f11930a561f52cd5a86e4fc7e5a9c8a8631d"}, + {file = "jupyterlab_server-2.27.3-py3-none-any.whl", hash = "sha256:e697488f66c3db49df675158a77b3b017520d772c6e1548c7d9bcc5df7944ee4"}, + {file = "jupyterlab_server-2.27.3.tar.gz", hash = "sha256:eb36caca59e74471988f0ae25c77945610b887f777255aa21f8065def9e51ed4"}, ] [package.dependencies] @@ -1298,13 +1314,13 @@ test = ["hatch", "ipykernel", "openapi-core (>=0.18.0,<0.19.0)", "openapi-spec-v [[package]] name = "jupyterlab-widgets" -version = "3.0.10" +version = "3.0.11" description = "Jupyter interactive widgets for JupyterLab" optional = true python-versions = ">=3.7" files = [ - {file = "jupyterlab_widgets-3.0.10-py3-none-any.whl", hash = "sha256:dd61f3ae7a5a7f80299e14585ce6cf3d6925a96c9103c978eda293197730cb64"}, - {file = "jupyterlab_widgets-3.0.10.tar.gz", hash = "sha256:04f2ac04976727e4f9d0fa91cdc2f1ab860f965e504c29dbd6a65c882c9d04c0"}, + {file = "jupyterlab_widgets-3.0.11-py3-none-any.whl", hash = "sha256:78287fd86d20744ace330a61625024cf5521e1c012a352ddc0a3cdc2348becd0"}, + {file = "jupyterlab_widgets-3.0.11.tar.gz", hash = "sha256:dd5ac679593c969af29c9bed054c24f26842baa51352114736756bc035deee27"}, ] [[package]] @@ -1505,40 +1521,51 @@ numpy = "*" [[package]] name = "matplotlib" -version = "3.9.0" +version = "3.9.2" description = "Python plotting package" optional = true python-versions = ">=3.9" files = [ - {file = "matplotlib-3.9.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:2bcee1dffaf60fe7656183ac2190bd630842ff87b3153afb3e384d966b57fe56"}, - {file = "matplotlib-3.9.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3f988bafb0fa39d1074ddd5bacd958c853e11def40800c5824556eb630f94d3b"}, - {file = "matplotlib-3.9.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fe428e191ea016bb278758c8ee82a8129c51d81d8c4bc0846c09e7e8e9057241"}, - {file = "matplotlib-3.9.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eaf3978060a106fab40c328778b148f590e27f6fa3cd15a19d6892575bce387d"}, - {file = "matplotlib-3.9.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:2e7f03e5cbbfacdd48c8ea394d365d91ee8f3cae7e6ec611409927b5ed997ee4"}, - {file = "matplotlib-3.9.0-cp310-cp310-win_amd64.whl", hash = "sha256:13beb4840317d45ffd4183a778685e215939be7b08616f431c7795276e067463"}, - {file = "matplotlib-3.9.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:063af8587fceeac13b0936c42a2b6c732c2ab1c98d38abc3337e430e1ff75e38"}, - {file = "matplotlib-3.9.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9a2fa6d899e17ddca6d6526cf6e7ba677738bf2a6a9590d702c277204a7c6152"}, - {file = "matplotlib-3.9.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:550cdda3adbd596078cca7d13ed50b77879104e2e46392dcd7c75259d8f00e85"}, - {file = "matplotlib-3.9.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:76cce0f31b351e3551d1f3779420cf8f6ec0d4a8cf9c0237a3b549fd28eb4abb"}, - {file = "matplotlib-3.9.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:c53aeb514ccbbcbab55a27f912d79ea30ab21ee0531ee2c09f13800efb272674"}, - {file = "matplotlib-3.9.0-cp311-cp311-win_amd64.whl", hash = "sha256:a5be985db2596d761cdf0c2eaf52396f26e6a64ab46bd8cd810c48972349d1be"}, - {file = "matplotlib-3.9.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:c79f3a585f1368da6049318bdf1f85568d8d04b2e89fc24b7e02cc9b62017382"}, - {file = "matplotlib-3.9.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:bdd1ecbe268eb3e7653e04f451635f0fb0f77f07fd070242b44c076c9106da84"}, - {file = "matplotlib-3.9.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d38e85a1a6d732f645f1403ce5e6727fd9418cd4574521d5803d3d94911038e5"}, - {file = "matplotlib-3.9.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0a490715b3b9984fa609116481b22178348c1a220a4499cda79132000a79b4db"}, - {file = "matplotlib-3.9.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8146ce83cbc5dc71c223a74a1996d446cd35cfb6a04b683e1446b7e6c73603b7"}, - {file = "matplotlib-3.9.0-cp312-cp312-win_amd64.whl", hash = "sha256:d91a4ffc587bacf5c4ce4ecfe4bcd23a4b675e76315f2866e588686cc97fccdf"}, - {file = "matplotlib-3.9.0-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:616fabf4981a3b3c5a15cd95eba359c8489c4e20e03717aea42866d8d0465956"}, - {file = "matplotlib-3.9.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:cd53c79fd02f1c1808d2cfc87dd3cf4dbc63c5244a58ee7944497107469c8d8a"}, - {file = "matplotlib-3.9.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:06a478f0d67636554fa78558cfbcd7b9dba85b51f5c3b5a0c9be49010cf5f321"}, - {file = "matplotlib-3.9.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:81c40af649d19c85f8073e25e5806926986806fa6d54be506fbf02aef47d5a89"}, - {file = "matplotlib-3.9.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:52146fc3bd7813cc784562cb93a15788be0b2875c4655e2cc6ea646bfa30344b"}, - {file = "matplotlib-3.9.0-cp39-cp39-win_amd64.whl", hash = "sha256:0fc51eaa5262553868461c083d9adadb11a6017315f3a757fc45ec6ec5f02888"}, - {file = "matplotlib-3.9.0-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:bd4f2831168afac55b881db82a7730992aa41c4f007f1913465fb182d6fb20c0"}, - {file = "matplotlib-3.9.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:290d304e59be2b33ef5c2d768d0237f5bd132986bdcc66f80bc9bcc300066a03"}, - {file = "matplotlib-3.9.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7ff2e239c26be4f24bfa45860c20ffccd118d270c5b5d081fa4ea409b5469fcd"}, - {file = "matplotlib-3.9.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:af4001b7cae70f7eaacfb063db605280058246de590fa7874f00f62259f2df7e"}, - {file = "matplotlib-3.9.0.tar.gz", hash = "sha256:e6d29ea6c19e34b30fb7d88b7081f869a03014f66fe06d62cc77d5a6ea88ed7a"}, + {file = "matplotlib-3.9.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:9d78bbc0cbc891ad55b4f39a48c22182e9bdaea7fc0e5dbd364f49f729ca1bbb"}, + {file = "matplotlib-3.9.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c375cc72229614632c87355366bdf2570c2dac01ac66b8ad048d2dabadf2d0d4"}, + {file = "matplotlib-3.9.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1d94ff717eb2bd0b58fe66380bd8b14ac35f48a98e7c6765117fe67fb7684e64"}, + {file = "matplotlib-3.9.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ab68d50c06938ef28681073327795c5db99bb4666214d2d5f880ed11aeaded66"}, + {file = "matplotlib-3.9.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:65aacf95b62272d568044531e41de26285d54aec8cb859031f511f84bd8b495a"}, + {file = "matplotlib-3.9.2-cp310-cp310-win_amd64.whl", hash = "sha256:3fd595f34aa8a55b7fc8bf9ebea8aa665a84c82d275190a61118d33fbc82ccae"}, + {file = "matplotlib-3.9.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:d8dd059447824eec055e829258ab092b56bb0579fc3164fa09c64f3acd478772"}, + {file = "matplotlib-3.9.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c797dac8bb9c7a3fd3382b16fe8f215b4cf0f22adccea36f1545a6d7be310b41"}, + {file = "matplotlib-3.9.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d719465db13267bcef19ea8954a971db03b9f48b4647e3860e4bc8e6ed86610f"}, + {file = "matplotlib-3.9.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8912ef7c2362f7193b5819d17dae8629b34a95c58603d781329712ada83f9447"}, + {file = "matplotlib-3.9.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:7741f26a58a240f43bee74965c4882b6c93df3e7eb3de160126d8c8f53a6ae6e"}, + {file = "matplotlib-3.9.2-cp311-cp311-win_amd64.whl", hash = "sha256:ae82a14dab96fbfad7965403c643cafe6515e386de723e498cf3eeb1e0b70cc7"}, + {file = "matplotlib-3.9.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:ac43031375a65c3196bee99f6001e7fa5bdfb00ddf43379d3c0609bdca042df9"}, + {file = "matplotlib-3.9.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:be0fc24a5e4531ae4d8e858a1a548c1fe33b176bb13eff7f9d0d38ce5112a27d"}, + {file = "matplotlib-3.9.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf81de2926c2db243c9b2cbc3917619a0fc85796c6ba4e58f541df814bbf83c7"}, + {file = "matplotlib-3.9.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6ee45bc4245533111ced13f1f2cace1e7f89d1c793390392a80c139d6cf0e6c"}, + {file = "matplotlib-3.9.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:306c8dfc73239f0e72ac50e5a9cf19cc4e8e331dd0c54f5e69ca8758550f1e1e"}, + {file = "matplotlib-3.9.2-cp312-cp312-win_amd64.whl", hash = "sha256:5413401594cfaff0052f9d8b1aafc6d305b4bd7c4331dccd18f561ff7e1d3bd3"}, + {file = "matplotlib-3.9.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:18128cc08f0d3cfff10b76baa2f296fc28c4607368a8402de61bb3f2eb33c7d9"}, + {file = "matplotlib-3.9.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:4876d7d40219e8ae8bb70f9263bcbe5714415acfdf781086601211335e24f8aa"}, + {file = "matplotlib-3.9.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6d9f07a80deab4bb0b82858a9e9ad53d1382fd122be8cde11080f4e7dfedb38b"}, + {file = "matplotlib-3.9.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f7c0410f181a531ec4e93bbc27692f2c71a15c2da16766f5ba9761e7ae518413"}, + {file = "matplotlib-3.9.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:909645cce2dc28b735674ce0931a4ac94e12f5b13f6bb0b5a5e65e7cea2c192b"}, + {file = "matplotlib-3.9.2-cp313-cp313-win_amd64.whl", hash = "sha256:f32c7410c7f246838a77d6d1eff0c0f87f3cb0e7c4247aebea71a6d5a68cab49"}, + {file = "matplotlib-3.9.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:37e51dd1c2db16ede9cfd7b5cabdfc818b2c6397c83f8b10e0e797501c963a03"}, + {file = "matplotlib-3.9.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:b82c5045cebcecd8496a4d694d43f9cc84aeeb49fe2133e036b207abe73f4d30"}, + {file = "matplotlib-3.9.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f053c40f94bc51bc03832a41b4f153d83f2062d88c72b5e79997072594e97e51"}, + {file = "matplotlib-3.9.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dbe196377a8248972f5cede786d4c5508ed5f5ca4a1e09b44bda889958b33f8c"}, + {file = "matplotlib-3.9.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:5816b1e1fe8c192cbc013f8f3e3368ac56fbecf02fb41b8f8559303f24c5015e"}, + {file = "matplotlib-3.9.2-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:cef2a73d06601437be399908cf13aee74e86932a5ccc6ccdf173408ebc5f6bb2"}, + {file = "matplotlib-3.9.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e0830e188029c14e891fadd99702fd90d317df294c3298aad682739c5533721a"}, + {file = "matplotlib-3.9.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:03ba9c1299c920964e8d3857ba27173b4dbb51ca4bab47ffc2c2ba0eb5e2cbc5"}, + {file = "matplotlib-3.9.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1cd93b91ab47a3616b4d3c42b52f8363b88ca021e340804c6ab2536344fad9ca"}, + {file = "matplotlib-3.9.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:6d1ce5ed2aefcdce11904fc5bbea7d9c21fff3d5f543841edf3dea84451a09ea"}, + {file = "matplotlib-3.9.2-cp39-cp39-win_amd64.whl", hash = "sha256:b2696efdc08648536efd4e1601b5fd491fd47f4db97a5fbfd175549a7365c1b2"}, + {file = "matplotlib-3.9.2-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:d52a3b618cb1cbb769ce2ee1dcdb333c3ab6e823944e9a2d36e37253815f9556"}, + {file = "matplotlib-3.9.2-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:039082812cacd6c6bec8e17a9c1e6baca230d4116d522e81e1f63a74d01d2e21"}, + {file = "matplotlib-3.9.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6758baae2ed64f2331d4fd19be38b7b4eae3ecec210049a26b6a4f3ae1c85dcc"}, + {file = "matplotlib-3.9.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:050598c2b29e0b9832cde72bcf97627bf00262adbc4a54e2b856426bb2ef0697"}, + {file = "matplotlib-3.9.2.tar.gz", hash = "sha256:96ab43906269ca64a6366934106fa01534454a69e471b7bf3d79083981aaab92"}, ] [package.dependencies] @@ -1715,13 +1742,13 @@ test = ["pytest (>=7.2)", "pytest-cov (>=4.0)"] [[package]] name = "notebook" -version = "7.2.0" +version = "7.2.1" description = "Jupyter Notebook - A web-based notebook environment for interactive computing" optional = true python-versions = ">=3.8" files = [ - {file = "notebook-7.2.0-py3-none-any.whl", hash = "sha256:b4752d7407d6c8872fc505df0f00d3cae46e8efb033b822adacbaa3f1f3ce8f5"}, - {file = "notebook-7.2.0.tar.gz", hash = "sha256:34a2ba4b08ad5d19ec930db7484fb79746a1784be9e1a5f8218f9af8656a141f"}, + {file = "notebook-7.2.1-py3-none-any.whl", hash = "sha256:f45489a3995746f2195a137e0773e2130960b51c9ac3ce257dbc2705aab3a6ca"}, + {file = "notebook-7.2.1.tar.gz", hash = "sha256:4287b6da59740b32173d01d641f763d292f49c30e7a51b89c46ba8473126341e"}, ] [package.dependencies] @@ -1800,12 +1827,12 @@ files = [ [[package]] name = "openmdao" -version = "3.32.0" +version = "3.34.2" description = "OpenMDAO framework infrastructure" optional = true python-versions = ">=3.8" files = [ - {file = "openmdao-3.32.0.tar.gz", hash = "sha256:324f8d900153cea14114a8c2a83aa3d801f7fd5e172c156a85a8208f45c3be49"}, + {file = "openmdao-3.34.2.tar.gz", hash = "sha256:3f772f74c99fc2305a872a4761589d4130396ea98a2210d9d1367fcf7fca36ab"}, ] [package.dependencies] @@ -1816,23 +1843,23 @@ requests = "*" scipy = "*" [package.extras] -all = ["aiounittest", "bokeh (>=2.4.0)", "colorama", "idna (>=3.7)", "ipympl", "ipyparallel", "jax (>=0.4.0)", "jaxlib (>=0.4.0)", "jupyter-book (==0.14)", "matplotlib", "notebook", "num2words", "numpydoc (>=1.1)", "parameterized", "playwright (>=1.20)", "pycodestyle (>=2.4.0)", "pydocstyle (==2.0.0)", "pydoe3", "sphinx-sitemap", "testflo (>=1.3.6)", "websockets (>8)"] -docs = ["idna (>=3.7)", "ipyparallel", "jupyter-book (==0.14)", "matplotlib", "numpydoc (>=1.1)", "sphinx-sitemap"] +all = ["aiounittest", "bokeh (>=2.4.0)", "colorama", "idna (>=3.7)", "ipympl", "ipyparallel", "jax (>=0.4.0)", "jaxlib (>=0.4.0)", "jinja2 (>=3.1.4)", "jupyter-book (==0.14)", "matplotlib", "notebook", "num2words", "numpydoc (>=1.1)", "parameterized", "playwright (>=1.20)", "pycodestyle (>=2.4.0)", "pydocstyle (>=2.0.0)", "pydoe3", "sphinx-sitemap", "testflo (>=1.3.6)", "tqdm (>=4.66.3)", "websockets (>8)"] +docs = ["idna (>=3.7)", "ipyparallel", "jinja2 (>=3.1.4)", "jupyter-book (==0.14)", "matplotlib", "numpydoc (>=1.1)", "sphinx-sitemap", "tqdm (>=4.66.3)"] doe = ["pydoe3"] jax = ["jax (>=0.4.0)", "jaxlib (>=0.4.0)"] notebooks = ["idna (>=3.7)", "ipympl", "notebook"] -test = ["aiounittest", "num2words", "numpydoc (>=1.1)", "parameterized", "playwright (>=1.20)", "pycodestyle (>=2.4.0)", "pydocstyle (==2.0.0)", "testflo (>=1.3.6)", "websockets (>8)"] +test = ["aiounittest", "num2words", "numpydoc (>=1.1)", "parameterized", "playwright (>=1.20)", "pycodestyle (>=2.4.0)", "pydocstyle (>=2.0.0)", "testflo (>=1.3.6)", "websockets (>8)"] visualization = ["bokeh (>=2.4.0)", "colorama", "matplotlib"] [[package]] name = "openpyxl" -version = "3.1.2" +version = "3.1.5" description = "A Python library to read/write Excel 2010 xlsx/xlsm files" optional = true -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "openpyxl-3.1.2-py2.py3-none-any.whl", hash = "sha256:f91456ead12ab3c6c2e9491cf33ba6d08357d802192379bb482f1033ade496f5"}, - {file = "openpyxl-3.1.2.tar.gz", hash = "sha256:a6f5977418eff3b2d5500d54d9db50c8277a368436f4e4f8ddb1be3422870184"}, + {file = "openpyxl-3.1.5-py2.py3-none-any.whl", hash = "sha256:5282c12b107bffeef825f4617dc029afaf41d0ea60823bbb665ef3079dc79de2"}, + {file = "openpyxl-3.1.5.tar.gz", hash = "sha256:cf0e3cf56142039133628b5acffe8ef0c12bc902d2aadd3e0fe5878dc08d1050"}, ] [package.dependencies] @@ -1851,13 +1878,13 @@ files = [ [[package]] name = "packaging" -version = "24.0" +version = "24.1" description = "Core utilities for Python packages" optional = true -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "packaging-24.0-py3-none-any.whl", hash = "sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5"}, - {file = "packaging-24.0.tar.gz", hash = "sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9"}, + {file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"}, + {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"}, ] [[package]] @@ -1868,6 +1895,7 @@ optional = false python-versions = ">=3.9" files = [ {file = "pandas-2.2.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:90c6fca2acf139569e74e8781709dccb6fe25940488755716d1d354d6bc58bce"}, + {file = "pandas-2.2.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c7adfc142dac335d8c1e0dcbd37eb8617eac386596eb9e1a1b77791cf2498238"}, {file = "pandas-2.2.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4abfe0be0d7221be4f12552995e58723c7422c80a659da13ca382697de830c08"}, {file = "pandas-2.2.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8635c16bf3d99040fdf3ca3db669a7250ddf49c55dc4aa8fe0ae0fa8d6dcc1f0"}, {file = "pandas-2.2.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:40ae1dffb3967a52203105a077415a86044a2bea011b5f321c6aa64b379a3f51"}, @@ -1881,12 +1909,14 @@ files = [ {file = "pandas-2.2.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:0cace394b6ea70c01ca1595f839cf193df35d1575986e484ad35c4aeae7266c1"}, {file = "pandas-2.2.2-cp311-cp311-win_amd64.whl", hash = "sha256:873d13d177501a28b2756375d59816c365e42ed8417b41665f346289adc68d24"}, {file = "pandas-2.2.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:9dfde2a0ddef507a631dc9dc4af6a9489d5e2e740e226ad426a05cabfbd7c8ef"}, + {file = "pandas-2.2.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:e9b79011ff7a0f4b1d6da6a61aa1aa604fb312d6647de5bad20013682d1429ce"}, {file = "pandas-2.2.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1cb51fe389360f3b5a4d57dbd2848a5f033350336ca3b340d1c53a1fad33bcad"}, {file = "pandas-2.2.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eee3a87076c0756de40b05c5e9a6069c035ba43e8dd71c379e68cab2c20f16ad"}, {file = "pandas-2.2.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:3e374f59e440d4ab45ca2fffde54b81ac3834cf5ae2cdfa69c90bc03bde04d76"}, {file = "pandas-2.2.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:43498c0bdb43d55cb162cdc8c06fac328ccb5d2eabe3cadeb3529ae6f0517c32"}, {file = "pandas-2.2.2-cp312-cp312-win_amd64.whl", hash = "sha256:d187d355ecec3629624fccb01d104da7d7f391db0311145817525281e2804d23"}, {file = "pandas-2.2.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:0ca6377b8fca51815f382bd0b697a0814c8bda55115678cbc94c30aacbb6eff2"}, + {file = "pandas-2.2.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9057e6aa78a584bc93a13f0a9bf7e753a5e9770a30b4d758b8d5f2a62a9433cd"}, {file = "pandas-2.2.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:001910ad31abc7bf06f49dcc903755d2f7f3a9186c0c040b827e522e9cef0863"}, {file = "pandas-2.2.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:66b479b0bd07204e37583c191535505410daa8df638fd8e75ae1b383851fe921"}, {file = "pandas-2.2.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:a77e9d1c386196879aa5eb712e77461aaee433e54c68cf253053a73b7e49c33a"}, @@ -1990,84 +2020,95 @@ ptyprocess = ">=0.5" [[package]] name = "pillow" -version = "10.3.0" +version = "10.4.0" description = "Python Imaging Library (Fork)" optional = true python-versions = ">=3.8" files = [ - {file = "pillow-10.3.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:90b9e29824800e90c84e4022dd5cc16eb2d9605ee13f05d47641eb183cd73d45"}, - {file = "pillow-10.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a2c405445c79c3f5a124573a051062300936b0281fee57637e706453e452746c"}, - {file = "pillow-10.3.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78618cdbccaa74d3f88d0ad6cb8ac3007f1a6fa5c6f19af64b55ca170bfa1edf"}, - {file = "pillow-10.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:261ddb7ca91fcf71757979534fb4c128448b5b4c55cb6152d280312062f69599"}, - {file = "pillow-10.3.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:ce49c67f4ea0609933d01c0731b34b8695a7a748d6c8d186f95e7d085d2fe475"}, - {file = "pillow-10.3.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:b14f16f94cbc61215115b9b1236f9c18403c15dd3c52cf629072afa9d54c1cbf"}, - {file = "pillow-10.3.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d33891be6df59d93df4d846640f0e46f1a807339f09e79a8040bc887bdcd7ed3"}, - {file = "pillow-10.3.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b50811d664d392f02f7761621303eba9d1b056fb1868c8cdf4231279645c25f5"}, - {file = "pillow-10.3.0-cp310-cp310-win32.whl", hash = "sha256:ca2870d5d10d8726a27396d3ca4cf7976cec0f3cb706debe88e3a5bd4610f7d2"}, - {file = "pillow-10.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:f0d0591a0aeaefdaf9a5e545e7485f89910c977087e7de2b6c388aec32011e9f"}, - {file = "pillow-10.3.0-cp310-cp310-win_arm64.whl", hash = "sha256:ccce24b7ad89adb5a1e34a6ba96ac2530046763912806ad4c247356a8f33a67b"}, - {file = "pillow-10.3.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:5f77cf66e96ae734717d341c145c5949c63180842a545c47a0ce7ae52ca83795"}, - {file = "pillow-10.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e4b878386c4bf293578b48fc570b84ecfe477d3b77ba39a6e87150af77f40c57"}, - {file = "pillow-10.3.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fdcbb4068117dfd9ce0138d068ac512843c52295ed996ae6dd1faf537b6dbc27"}, - {file = "pillow-10.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9797a6c8fe16f25749b371c02e2ade0efb51155e767a971c61734b1bf6293994"}, - {file = "pillow-10.3.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:9e91179a242bbc99be65e139e30690e081fe6cb91a8e77faf4c409653de39451"}, - {file = "pillow-10.3.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:1b87bd9d81d179bd8ab871603bd80d8645729939f90b71e62914e816a76fc6bd"}, - {file = "pillow-10.3.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:81d09caa7b27ef4e61cb7d8fbf1714f5aec1c6b6c5270ee53504981e6e9121ad"}, - {file = "pillow-10.3.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:048ad577748b9fa4a99a0548c64f2cb8d672d5bf2e643a739ac8faff1164238c"}, - {file = "pillow-10.3.0-cp311-cp311-win32.whl", hash = "sha256:7161ec49ef0800947dc5570f86568a7bb36fa97dd09e9827dc02b718c5643f09"}, - {file = "pillow-10.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:8eb0908e954d093b02a543dc963984d6e99ad2b5e36503d8a0aaf040505f747d"}, - {file = "pillow-10.3.0-cp311-cp311-win_arm64.whl", hash = "sha256:4e6f7d1c414191c1199f8996d3f2282b9ebea0945693fb67392c75a3a320941f"}, - {file = "pillow-10.3.0-cp312-cp312-macosx_10_10_x86_64.whl", hash = "sha256:e46f38133e5a060d46bd630faa4d9fa0202377495df1f068a8299fd78c84de84"}, - {file = "pillow-10.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:50b8eae8f7334ec826d6eeffaeeb00e36b5e24aa0b9df322c247539714c6df19"}, - {file = "pillow-10.3.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9d3bea1c75f8c53ee4d505c3e67d8c158ad4df0d83170605b50b64025917f338"}, - {file = "pillow-10.3.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:19aeb96d43902f0a783946a0a87dbdad5c84c936025b8419da0a0cd7724356b1"}, - {file = "pillow-10.3.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:74d28c17412d9caa1066f7a31df8403ec23d5268ba46cd0ad2c50fb82ae40462"}, - {file = "pillow-10.3.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:ff61bfd9253c3915e6d41c651d5f962da23eda633cf02262990094a18a55371a"}, - {file = "pillow-10.3.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d886f5d353333b4771d21267c7ecc75b710f1a73d72d03ca06df49b09015a9ef"}, - {file = "pillow-10.3.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4b5ec25d8b17217d635f8935dbc1b9aa5907962fae29dff220f2659487891cd3"}, - {file = "pillow-10.3.0-cp312-cp312-win32.whl", hash = "sha256:51243f1ed5161b9945011a7360e997729776f6e5d7005ba0c6879267d4c5139d"}, - {file = "pillow-10.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:412444afb8c4c7a6cc11a47dade32982439925537e483be7c0ae0cf96c4f6a0b"}, - {file = "pillow-10.3.0-cp312-cp312-win_arm64.whl", hash = "sha256:798232c92e7665fe82ac085f9d8e8ca98826f8e27859d9a96b41d519ecd2e49a"}, - {file = "pillow-10.3.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:4eaa22f0d22b1a7e93ff0a596d57fdede2e550aecffb5a1ef1106aaece48e96b"}, - {file = "pillow-10.3.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:cd5e14fbf22a87321b24c88669aad3a51ec052eb145315b3da3b7e3cc105b9a2"}, - {file = "pillow-10.3.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1530e8f3a4b965eb6a7785cf17a426c779333eb62c9a7d1bbcf3ffd5bf77a4aa"}, - {file = "pillow-10.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d512aafa1d32efa014fa041d38868fda85028e3f930a96f85d49c7d8ddc0383"}, - {file = "pillow-10.3.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:339894035d0ede518b16073bdc2feef4c991ee991a29774b33e515f1d308e08d"}, - {file = "pillow-10.3.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:aa7e402ce11f0885305bfb6afb3434b3cd8f53b563ac065452d9d5654c7b86fd"}, - {file = "pillow-10.3.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:0ea2a783a2bdf2a561808fe4a7a12e9aa3799b701ba305de596bc48b8bdfce9d"}, - {file = "pillow-10.3.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:c78e1b00a87ce43bb37642c0812315b411e856a905d58d597750eb79802aaaa3"}, - {file = "pillow-10.3.0-cp38-cp38-win32.whl", hash = "sha256:72d622d262e463dfb7595202d229f5f3ab4b852289a1cd09650362db23b9eb0b"}, - {file = "pillow-10.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:2034f6759a722da3a3dbd91a81148cf884e91d1b747992ca288ab88c1de15999"}, - {file = "pillow-10.3.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:2ed854e716a89b1afcedea551cd85f2eb2a807613752ab997b9974aaa0d56936"}, - {file = "pillow-10.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:dc1a390a82755a8c26c9964d457d4c9cbec5405896cba94cf51f36ea0d855002"}, - {file = "pillow-10.3.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4203efca580f0dd6f882ca211f923168548f7ba334c189e9eab1178ab840bf60"}, - {file = "pillow-10.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3102045a10945173d38336f6e71a8dc71bcaeed55c3123ad4af82c52807b9375"}, - {file = "pillow-10.3.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:6fb1b30043271ec92dc65f6d9f0b7a830c210b8a96423074b15c7bc999975f57"}, - {file = "pillow-10.3.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:1dfc94946bc60ea375cc39cff0b8da6c7e5f8fcdc1d946beb8da5c216156ddd8"}, - {file = "pillow-10.3.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b09b86b27a064c9624d0a6c54da01c1beaf5b6cadfa609cf63789b1d08a797b9"}, - {file = "pillow-10.3.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d3b2348a78bc939b4fed6552abfd2e7988e0f81443ef3911a4b8498ca084f6eb"}, - {file = "pillow-10.3.0-cp39-cp39-win32.whl", hash = "sha256:45ebc7b45406febf07fef35d856f0293a92e7417ae7933207e90bf9090b70572"}, - {file = "pillow-10.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:0ba26351b137ca4e0db0342d5d00d2e355eb29372c05afd544ebf47c0956ffeb"}, - {file = "pillow-10.3.0-cp39-cp39-win_arm64.whl", hash = "sha256:50fd3f6b26e3441ae07b7c979309638b72abc1a25da31a81a7fbd9495713ef4f"}, - {file = "pillow-10.3.0-pp310-pypy310_pp73-macosx_10_10_x86_64.whl", hash = "sha256:6b02471b72526ab8a18c39cb7967b72d194ec53c1fd0a70b050565a0f366d355"}, - {file = "pillow-10.3.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:8ab74c06ffdab957d7670c2a5a6e1a70181cd10b727cd788c4dd9005b6a8acd9"}, - {file = "pillow-10.3.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:048eeade4c33fdf7e08da40ef402e748df113fd0b4584e32c4af74fe78baaeb2"}, - {file = "pillow-10.3.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e2ec1e921fd07c7cda7962bad283acc2f2a9ccc1b971ee4b216b75fad6f0463"}, - {file = "pillow-10.3.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:4c8e73e99da7db1b4cad7f8d682cf6abad7844da39834c288fbfa394a47bbced"}, - {file = "pillow-10.3.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:16563993329b79513f59142a6b02055e10514c1a8e86dca8b48a893e33cf91e3"}, - {file = "pillow-10.3.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:dd78700f5788ae180b5ee8902c6aea5a5726bac7c364b202b4b3e3ba2d293170"}, - {file = "pillow-10.3.0-pp39-pypy39_pp73-macosx_10_10_x86_64.whl", hash = "sha256:aff76a55a8aa8364d25400a210a65ff59d0168e0b4285ba6bf2bd83cf675ba32"}, - {file = "pillow-10.3.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:b7bc2176354defba3edc2b9a777744462da2f8e921fbaf61e52acb95bafa9828"}, - {file = "pillow-10.3.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:793b4e24db2e8742ca6423d3fde8396db336698c55cd34b660663ee9e45ed37f"}, - {file = "pillow-10.3.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d93480005693d247f8346bc8ee28c72a2191bdf1f6b5db469c096c0c867ac015"}, - {file = "pillow-10.3.0-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:c83341b89884e2b2e55886e8fbbf37c3fa5efd6c8907124aeb72f285ae5696e5"}, - {file = "pillow-10.3.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:1a1d1915db1a4fdb2754b9de292642a39a7fb28f1736699527bb649484fb966a"}, - {file = "pillow-10.3.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:a0eaa93d054751ee9964afa21c06247779b90440ca41d184aeb5d410f20ff591"}, - {file = "pillow-10.3.0.tar.gz", hash = "sha256:9d2455fbf44c914840c793e89aa82d0e1763a14253a000743719ae5946814b2d"}, -] - -[package.extras] -docs = ["furo", "olefile", "sphinx (>=2.4)", "sphinx-copybutton", "sphinx-inline-tabs", "sphinx-removed-in", "sphinxext-opengraph"] + {file = "pillow-10.4.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:4d9667937cfa347525b319ae34375c37b9ee6b525440f3ef48542fcf66f2731e"}, + {file = "pillow-10.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:543f3dc61c18dafb755773efc89aae60d06b6596a63914107f75459cf984164d"}, + {file = "pillow-10.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7928ecbf1ece13956b95d9cbcfc77137652b02763ba384d9ab508099a2eca856"}, + {file = "pillow-10.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4d49b85c4348ea0b31ea63bc75a9f3857869174e2bf17e7aba02945cd218e6f"}, + {file = "pillow-10.4.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:6c762a5b0997f5659a5ef2266abc1d8851ad7749ad9a6a5506eb23d314e4f46b"}, + {file = "pillow-10.4.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:a985e028fc183bf12a77a8bbf36318db4238a3ded7fa9df1b9a133f1cb79f8fc"}, + {file = "pillow-10.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:812f7342b0eee081eaec84d91423d1b4650bb9828eb53d8511bcef8ce5aecf1e"}, + {file = "pillow-10.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:ac1452d2fbe4978c2eec89fb5a23b8387aba707ac72810d9490118817d9c0b46"}, + {file = "pillow-10.4.0-cp310-cp310-win32.whl", hash = "sha256:bcd5e41a859bf2e84fdc42f4edb7d9aba0a13d29a2abadccafad99de3feff984"}, + {file = "pillow-10.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:ecd85a8d3e79cd7158dec1c9e5808e821feea088e2f69a974db5edf84dc53141"}, + {file = "pillow-10.4.0-cp310-cp310-win_arm64.whl", hash = "sha256:ff337c552345e95702c5fde3158acb0625111017d0e5f24bf3acdb9cc16b90d1"}, + {file = "pillow-10.4.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:0a9ec697746f268507404647e531e92889890a087e03681a3606d9b920fbee3c"}, + {file = "pillow-10.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:dfe91cb65544a1321e631e696759491ae04a2ea11d36715eca01ce07284738be"}, + {file = "pillow-10.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5dc6761a6efc781e6a1544206f22c80c3af4c8cf461206d46a1e6006e4429ff3"}, + {file = "pillow-10.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5e84b6cc6a4a3d76c153a6b19270b3526a5a8ed6b09501d3af891daa2a9de7d6"}, + {file = "pillow-10.4.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:bbc527b519bd3aa9d7f429d152fea69f9ad37c95f0b02aebddff592688998abe"}, + {file = "pillow-10.4.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:76a911dfe51a36041f2e756b00f96ed84677cdeb75d25c767f296c1c1eda1319"}, + {file = "pillow-10.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:59291fb29317122398786c2d44427bbd1a6d7ff54017075b22be9d21aa59bd8d"}, + {file = "pillow-10.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:416d3a5d0e8cfe4f27f574362435bc9bae57f679a7158e0096ad2beb427b8696"}, + {file = "pillow-10.4.0-cp311-cp311-win32.whl", hash = "sha256:7086cc1d5eebb91ad24ded9f58bec6c688e9f0ed7eb3dbbf1e4800280a896496"}, + {file = "pillow-10.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cbed61494057c0f83b83eb3a310f0bf774b09513307c434d4366ed64f4128a91"}, + {file = "pillow-10.4.0-cp311-cp311-win_arm64.whl", hash = "sha256:f5f0c3e969c8f12dd2bb7e0b15d5c468b51e5017e01e2e867335c81903046a22"}, + {file = "pillow-10.4.0-cp312-cp312-macosx_10_10_x86_64.whl", hash = "sha256:673655af3eadf4df6b5457033f086e90299fdd7a47983a13827acf7459c15d94"}, + {file = "pillow-10.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:866b6942a92f56300012f5fbac71f2d610312ee65e22f1aa2609e491284e5597"}, + {file = "pillow-10.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:29dbdc4207642ea6aad70fbde1a9338753d33fb23ed6956e706936706f52dd80"}, + {file = "pillow-10.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf2342ac639c4cf38799a44950bbc2dfcb685f052b9e262f446482afaf4bffca"}, + {file = "pillow-10.4.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:f5b92f4d70791b4a67157321c4e8225d60b119c5cc9aee8ecf153aace4aad4ef"}, + {file = "pillow-10.4.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:86dcb5a1eb778d8b25659d5e4341269e8590ad6b4e8b44d9f4b07f8d136c414a"}, + {file = "pillow-10.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:780c072c2e11c9b2c7ca37f9a2ee8ba66f44367ac3e5c7832afcfe5104fd6d1b"}, + {file = "pillow-10.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:37fb69d905be665f68f28a8bba3c6d3223c8efe1edf14cc4cfa06c241f8c81d9"}, + {file = "pillow-10.4.0-cp312-cp312-win32.whl", hash = "sha256:7dfecdbad5c301d7b5bde160150b4db4c659cee2b69589705b6f8a0c509d9f42"}, + {file = "pillow-10.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:1d846aea995ad352d4bdcc847535bd56e0fd88d36829d2c90be880ef1ee4668a"}, + {file = "pillow-10.4.0-cp312-cp312-win_arm64.whl", hash = "sha256:e553cad5179a66ba15bb18b353a19020e73a7921296a7979c4a2b7f6a5cd57f9"}, + {file = "pillow-10.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8bc1a764ed8c957a2e9cacf97c8b2b053b70307cf2996aafd70e91a082e70df3"}, + {file = "pillow-10.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:6209bb41dc692ddfee4942517c19ee81b86c864b626dbfca272ec0f7cff5d9fb"}, + {file = "pillow-10.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bee197b30783295d2eb680b311af15a20a8b24024a19c3a26431ff83eb8d1f70"}, + {file = "pillow-10.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1ef61f5dd14c300786318482456481463b9d6b91ebe5ef12f405afbba77ed0be"}, + {file = "pillow-10.4.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:297e388da6e248c98bc4a02e018966af0c5f92dfacf5a5ca22fa01cb3179bca0"}, + {file = "pillow-10.4.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:e4db64794ccdf6cb83a59d73405f63adbe2a1887012e308828596100a0b2f6cc"}, + {file = "pillow-10.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:bd2880a07482090a3bcb01f4265f1936a903d70bc740bfcb1fd4e8a2ffe5cf5a"}, + {file = "pillow-10.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4b35b21b819ac1dbd1233317adeecd63495f6babf21b7b2512d244ff6c6ce309"}, + {file = "pillow-10.4.0-cp313-cp313-win32.whl", hash = "sha256:551d3fd6e9dc15e4c1eb6fc4ba2b39c0c7933fa113b220057a34f4bb3268a060"}, + {file = "pillow-10.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:030abdbe43ee02e0de642aee345efa443740aa4d828bfe8e2eb11922ea6a21ea"}, + {file = "pillow-10.4.0-cp313-cp313-win_arm64.whl", hash = "sha256:5b001114dd152cfd6b23befeb28d7aee43553e2402c9f159807bf55f33af8a8d"}, + {file = "pillow-10.4.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:8d4d5063501b6dd4024b8ac2f04962d661222d120381272deea52e3fc52d3736"}, + {file = "pillow-10.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7c1ee6f42250df403c5f103cbd2768a28fe1a0ea1f0f03fe151c8741e1469c8b"}, + {file = "pillow-10.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b15e02e9bb4c21e39876698abf233c8c579127986f8207200bc8a8f6bb27acf2"}, + {file = "pillow-10.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7a8d4bade9952ea9a77d0c3e49cbd8b2890a399422258a77f357b9cc9be8d680"}, + {file = "pillow-10.4.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:43efea75eb06b95d1631cb784aa40156177bf9dd5b4b03ff38979e048258bc6b"}, + {file = "pillow-10.4.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:950be4d8ba92aca4b2bb0741285a46bfae3ca699ef913ec8416c1b78eadd64cd"}, + {file = "pillow-10.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:d7480af14364494365e89d6fddc510a13e5a2c3584cb19ef65415ca57252fb84"}, + {file = "pillow-10.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:73664fe514b34c8f02452ffb73b7a92c6774e39a647087f83d67f010eb9a0cf0"}, + {file = "pillow-10.4.0-cp38-cp38-win32.whl", hash = "sha256:e88d5e6ad0d026fba7bdab8c3f225a69f063f116462c49892b0149e21b6c0a0e"}, + {file = "pillow-10.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:5161eef006d335e46895297f642341111945e2c1c899eb406882a6c61a4357ab"}, + {file = "pillow-10.4.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:0ae24a547e8b711ccaaf99c9ae3cd975470e1a30caa80a6aaee9a2f19c05701d"}, + {file = "pillow-10.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:298478fe4f77a4408895605f3482b6cc6222c018b2ce565c2b6b9c354ac3229b"}, + {file = "pillow-10.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:134ace6dc392116566980ee7436477d844520a26a4b1bd4053f6f47d096997fd"}, + {file = "pillow-10.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:930044bb7679ab003b14023138b50181899da3f25de50e9dbee23b61b4de2126"}, + {file = "pillow-10.4.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:c76e5786951e72ed3686e122d14c5d7012f16c8303a674d18cdcd6d89557fc5b"}, + {file = "pillow-10.4.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:b2724fdb354a868ddf9a880cb84d102da914e99119211ef7ecbdc613b8c96b3c"}, + {file = "pillow-10.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:dbc6ae66518ab3c5847659e9988c3b60dc94ffb48ef9168656e0019a93dbf8a1"}, + {file = "pillow-10.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:06b2f7898047ae93fad74467ec3d28fe84f7831370e3c258afa533f81ef7f3df"}, + {file = "pillow-10.4.0-cp39-cp39-win32.whl", hash = "sha256:7970285ab628a3779aecc35823296a7869f889b8329c16ad5a71e4901a3dc4ef"}, + {file = "pillow-10.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:961a7293b2457b405967af9c77dcaa43cc1a8cd50d23c532e62d48ab6cdd56f5"}, + {file = "pillow-10.4.0-cp39-cp39-win_arm64.whl", hash = "sha256:32cda9e3d601a52baccb2856b8ea1fc213c90b340c542dcef77140dfa3278a9e"}, + {file = "pillow-10.4.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:5b4815f2e65b30f5fbae9dfffa8636d992d49705723fe86a3661806e069352d4"}, + {file = "pillow-10.4.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:8f0aef4ef59694b12cadee839e2ba6afeab89c0f39a3adc02ed51d109117b8da"}, + {file = "pillow-10.4.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9f4727572e2918acaa9077c919cbbeb73bd2b3ebcfe033b72f858fc9fbef0026"}, + {file = "pillow-10.4.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ff25afb18123cea58a591ea0244b92eb1e61a1fd497bf6d6384f09bc3262ec3e"}, + {file = "pillow-10.4.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:dc3e2db6ba09ffd7d02ae9141cfa0ae23393ee7687248d46a7507b75d610f4f5"}, + {file = "pillow-10.4.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:02a2be69f9c9b8c1e97cf2713e789d4e398c751ecfd9967c18d0ce304efbf885"}, + {file = "pillow-10.4.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:0755ffd4a0c6f267cccbae2e9903d95477ca2f77c4fcf3a3a09570001856c8a5"}, + {file = "pillow-10.4.0-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:a02364621fe369e06200d4a16558e056fe2805d3468350df3aef21e00d26214b"}, + {file = "pillow-10.4.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:1b5dea9831a90e9d0721ec417a80d4cbd7022093ac38a568db2dd78363b00908"}, + {file = "pillow-10.4.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9b885f89040bb8c4a1573566bbb2f44f5c505ef6e74cec7ab9068c900047f04b"}, + {file = "pillow-10.4.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87dd88ded2e6d74d31e1e0a99a726a6765cda32d00ba72dc37f0651f306daaa8"}, + {file = "pillow-10.4.0-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:2db98790afc70118bd0255c2eeb465e9767ecf1f3c25f9a1abb8ffc8cfd1fe0a"}, + {file = "pillow-10.4.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:f7baece4ce06bade126fb84b8af1c33439a76d8a6fd818970215e0560ca28c27"}, + {file = "pillow-10.4.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:cfdd747216947628af7b259d274771d84db2268ca062dd5faf373639d00113a3"}, + {file = "pillow-10.4.0.tar.gz", hash = "sha256:166c1cd4d24309b30d61f79f4a9114b7b2313d7450912277855ff5dfd7cd4a06"}, +] + +[package.extras] +docs = ["furo", "olefile", "sphinx (>=7.3)", "sphinx-copybutton", "sphinx-inline-tabs", "sphinxext-opengraph"] fpx = ["olefile"] mic = ["olefile"] tests = ["check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "packaging", "pyroma", "pytest", "pytest-cov", "pytest-timeout"] @@ -2106,13 +2147,13 @@ twisted = ["twisted"] [[package]] name = "prompt-toolkit" -version = "3.0.43" +version = "3.0.47" description = "Library for building powerful interactive command lines in Python" optional = true python-versions = ">=3.7.0" files = [ - {file = "prompt_toolkit-3.0.43-py3-none-any.whl", hash = "sha256:a11a29cb3bf0a28a387fe5122cdb649816a957cd9261dcedf8c9f1fef33eacf6"}, - {file = "prompt_toolkit-3.0.43.tar.gz", hash = "sha256:3527b7af26106cbc65a040bcc84839a3566ec1b051bb0bfe953631e704b0ff7d"}, + {file = "prompt_toolkit-3.0.47-py3-none-any.whl", hash = "sha256:0d7bfa67001d5e39d02c224b663abc33687405033a8c422d0d675a5a13361d10"}, + {file = "prompt_toolkit-3.0.47.tar.gz", hash = "sha256:1e1b29cb58080b1e69f207c893a1a7bf16d127a5c30c9d17a25a5d77792e5360"}, ] [package.dependencies] @@ -2120,27 +2161,28 @@ wcwidth = "*" [[package]] name = "psutil" -version = "5.9.8" +version = "6.0.0" description = "Cross-platform lib for process and system monitoring in Python." optional = true -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" files = [ - {file = "psutil-5.9.8-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:26bd09967ae00920df88e0352a91cff1a78f8d69b3ecabbfe733610c0af486c8"}, - {file = "psutil-5.9.8-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:05806de88103b25903dff19bb6692bd2e714ccf9e668d050d144012055cbca73"}, - {file = "psutil-5.9.8-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:611052c4bc70432ec770d5d54f64206aa7203a101ec273a0cd82418c86503bb7"}, - {file = "psutil-5.9.8-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:50187900d73c1381ba1454cf40308c2bf6f34268518b3f36a9b663ca87e65e36"}, - {file = "psutil-5.9.8-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:02615ed8c5ea222323408ceba16c60e99c3f91639b07da6373fb7e6539abc56d"}, - {file = "psutil-5.9.8-cp27-none-win32.whl", hash = "sha256:36f435891adb138ed3c9e58c6af3e2e6ca9ac2f365efe1f9cfef2794e6c93b4e"}, - {file = "psutil-5.9.8-cp27-none-win_amd64.whl", hash = "sha256:bd1184ceb3f87651a67b2708d4c3338e9b10c5df903f2e3776b62303b26cb631"}, - {file = "psutil-5.9.8-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:aee678c8720623dc456fa20659af736241f575d79429a0e5e9cf88ae0605cc81"}, - {file = "psutil-5.9.8-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8cb6403ce6d8e047495a701dc7c5bd788add903f8986d523e3e20b98b733e421"}, - {file = "psutil-5.9.8-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d06016f7f8625a1825ba3732081d77c94589dca78b7a3fc072194851e88461a4"}, - {file = "psutil-5.9.8-cp36-cp36m-win32.whl", hash = "sha256:7d79560ad97af658a0f6adfef8b834b53f64746d45b403f225b85c5c2c140eee"}, - {file = "psutil-5.9.8-cp36-cp36m-win_amd64.whl", hash = "sha256:27cc40c3493bb10de1be4b3f07cae4c010ce715290a5be22b98493509c6299e2"}, - {file = "psutil-5.9.8-cp37-abi3-win32.whl", hash = "sha256:bc56c2a1b0d15aa3eaa5a60c9f3f8e3e565303b465dbf57a1b730e7a2b9844e0"}, - {file = "psutil-5.9.8-cp37-abi3-win_amd64.whl", hash = "sha256:8db4c1b57507eef143a15a6884ca10f7c73876cdf5d51e713151c1236a0e68cf"}, - {file = "psutil-5.9.8-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:d16bbddf0693323b8c6123dd804100241da461e41d6e332fb0ba6058f630f8c8"}, - {file = "psutil-5.9.8.tar.gz", hash = "sha256:6be126e3225486dff286a8fb9a06246a5253f4c7c53b475ea5f5ac934e64194c"}, + {file = "psutil-6.0.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:a021da3e881cd935e64a3d0a20983bda0bb4cf80e4f74fa9bfcb1bc5785360c6"}, + {file = "psutil-6.0.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:1287c2b95f1c0a364d23bc6f2ea2365a8d4d9b726a3be7294296ff7ba97c17f0"}, + {file = "psutil-6.0.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:a9a3dbfb4de4f18174528d87cc352d1f788b7496991cca33c6996f40c9e3c92c"}, + {file = "psutil-6.0.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:6ec7588fb3ddaec7344a825afe298db83fe01bfaaab39155fa84cf1c0d6b13c3"}, + {file = "psutil-6.0.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:1e7c870afcb7d91fdea2b37c24aeb08f98b6d67257a5cb0a8bc3ac68d0f1a68c"}, + {file = "psutil-6.0.0-cp27-none-win32.whl", hash = "sha256:02b69001f44cc73c1c5279d02b30a817e339ceb258ad75997325e0e6169d8b35"}, + {file = "psutil-6.0.0-cp27-none-win_amd64.whl", hash = "sha256:21f1fb635deccd510f69f485b87433460a603919b45e2a324ad65b0cc74f8fb1"}, + {file = "psutil-6.0.0-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:c588a7e9b1173b6e866756dde596fd4cad94f9399daf99ad8c3258b3cb2b47a0"}, + {file = "psutil-6.0.0-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ed2440ada7ef7d0d608f20ad89a04ec47d2d3ab7190896cd62ca5fc4fe08bf0"}, + {file = "psutil-6.0.0-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5fd9a97c8e94059b0ef54a7d4baf13b405011176c3b6ff257c247cae0d560ecd"}, + {file = "psutil-6.0.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e2e8d0054fc88153ca0544f5c4d554d42e33df2e009c4ff42284ac9ebdef4132"}, + {file = "psutil-6.0.0-cp36-cp36m-win32.whl", hash = "sha256:fc8c9510cde0146432bbdb433322861ee8c3efbf8589865c8bf8d21cb30c4d14"}, + {file = "psutil-6.0.0-cp36-cp36m-win_amd64.whl", hash = "sha256:34859b8d8f423b86e4385ff3665d3f4d94be3cdf48221fbe476e883514fdb71c"}, + {file = "psutil-6.0.0-cp37-abi3-win32.whl", hash = "sha256:a495580d6bae27291324fe60cea0b5a7c23fa36a7cd35035a16d93bdcf076b9d"}, + {file = "psutil-6.0.0-cp37-abi3-win_amd64.whl", hash = "sha256:33ea5e1c975250a720b3a6609c490db40dae5d83a4eb315170c4fe0d8b1f34b3"}, + {file = "psutil-6.0.0-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:ffe7fc9b6b36beadc8c322f84e1caff51e8703b88eee1da46d1e3a6ae11b4fd0"}, + {file = "psutil-6.0.0.tar.gz", hash = "sha256:8faae4f310b6d969fa26ca0545338b21f73c6b15db7c4a8d934a5482faa818f2"}, ] [package.extras] @@ -2159,13 +2201,13 @@ files = [ [[package]] name = "pure-eval" -version = "0.2.2" +version = "0.2.3" description = "Safely evaluate AST nodes without side effects" optional = true python-versions = "*" files = [ - {file = "pure_eval-0.2.2-py3-none-any.whl", hash = "sha256:01eaab343580944bc56080ebe0a674b39ec44a945e6d09ba7db3cb8cec289350"}, - {file = "pure_eval-0.2.2.tar.gz", hash = "sha256:2b45320af6dfaa1750f543d714b6d1c520a1688dec6fd24d339063ce0aaa9ac3"}, + {file = "pure_eval-0.2.3-py3-none-any.whl", hash = "sha256:1db8e35b67b3d218d818ae653e27f06c3aa420901fa7b081ca98cbedc874e0d0"}, + {file = "pure_eval-0.2.3.tar.gz", hash = "sha256:5f4e983f40564c576c7c8635ae88db5956bb2229d7e9237d03b3c0b0190eaf42"}, ] [package.extras] @@ -2184,13 +2226,13 @@ files = [ [[package]] name = "pydoe3" -version = "1.0.2" +version = "1.0.3" description = "Design of experiments for Python" optional = true python-versions = "*" files = [ - {file = "pydoe3-1.0.2-py2.py3-none-any.whl", hash = "sha256:09925e3d445f40aa720ed81bb8c816d77aaae80e2521bb285ed07244e17e54e9"}, - {file = "pydoe3-1.0.2.tar.gz", hash = "sha256:69ffd88aa81ef9df6fdf0cc7b64748ee7eb14895939c50dfd22a0e0e6a718df7"}, + {file = "pydoe3-1.0.3-py2.py3-none-any.whl", hash = "sha256:b190db474428a8d0573dfa4e39d8cb12abe3fe1dee70aeabeed1cb2ba1cbb040"}, + {file = "pydoe3-1.0.3.tar.gz", hash = "sha256:e0547d7b919dcd259abd96b91ea56f8d1a41f63efd6f393eacdbc06697d6034e"}, ] [package.dependencies] @@ -2356,158 +2398,182 @@ files = [ [[package]] name = "pyyaml" -version = "6.0.1" +version = "6.0.2" description = "YAML parser and emitter for Python" optional = true -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "PyYAML-6.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a"}, - {file = "PyYAML-6.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f"}, - {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"}, - {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"}, - {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"}, - {file = "PyYAML-6.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290"}, - {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"}, - {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"}, - {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"}, - {file = "PyYAML-6.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab"}, - {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"}, - {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"}, - {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"}, - {file = "PyYAML-6.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b"}, - {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"}, - {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, - {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, - {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, - {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, - {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, - {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, - {file = "PyYAML-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df"}, - {file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"}, - {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"}, - {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"}, - {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd"}, - {file = "PyYAML-6.0.1-cp36-cp36m-win32.whl", hash = "sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585"}, - {file = "PyYAML-6.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa"}, - {file = "PyYAML-6.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3"}, - {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27"}, - {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3"}, - {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c"}, - {file = "PyYAML-6.0.1-cp37-cp37m-win32.whl", hash = "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba"}, - {file = "PyYAML-6.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867"}, - {file = "PyYAML-6.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595"}, - {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"}, - {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"}, - {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"}, - {file = "PyYAML-6.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6"}, - {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"}, - {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"}, - {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"}, - {file = "PyYAML-6.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859"}, - {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"}, - {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"}, - {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"}, - {file = "PyYAML-6.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5"}, - {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"}, - {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"}, - {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, + {file = "PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086"}, + {file = "PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf"}, + {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237"}, + {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b"}, + {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed"}, + {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180"}, + {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68"}, + {file = "PyYAML-6.0.2-cp310-cp310-win32.whl", hash = "sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99"}, + {file = "PyYAML-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e"}, + {file = "PyYAML-6.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774"}, + {file = "PyYAML-6.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee"}, + {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c"}, + {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317"}, + {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85"}, + {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4"}, + {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e"}, + {file = "PyYAML-6.0.2-cp311-cp311-win32.whl", hash = "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5"}, + {file = "PyYAML-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44"}, + {file = "PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab"}, + {file = "PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725"}, + {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5"}, + {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425"}, + {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476"}, + {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48"}, + {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b"}, + {file = "PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4"}, + {file = "PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8"}, + {file = "PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba"}, + {file = "PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1"}, + {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133"}, + {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484"}, + {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5"}, + {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc"}, + {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652"}, + {file = "PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183"}, + {file = "PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563"}, + {file = "PyYAML-6.0.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:24471b829b3bf607e04e88d79542a9d48bb037c2267d7927a874e6c205ca7e9a"}, + {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7fded462629cfa4b685c5416b949ebad6cec74af5e2d42905d41e257e0869f5"}, + {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d84a1718ee396f54f3a086ea0a66d8e552b2ab2017ef8b420e92edbc841c352d"}, + {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9056c1ecd25795207ad294bcf39f2db3d845767be0ea6e6a34d856f006006083"}, + {file = "PyYAML-6.0.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:82d09873e40955485746739bcb8b4586983670466c23382c19cffecbf1fd8706"}, + {file = "PyYAML-6.0.2-cp38-cp38-win32.whl", hash = "sha256:43fa96a3ca0d6b1812e01ced1044a003533c47f6ee8aca31724f78e93ccc089a"}, + {file = "PyYAML-6.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:01179a4a8559ab5de078078f37e5c1a30d76bb88519906844fd7bdea1b7729ff"}, + {file = "PyYAML-6.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:688ba32a1cffef67fd2e9398a2efebaea461578b0923624778664cc1c914db5d"}, + {file = "PyYAML-6.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8786accb172bd8afb8be14490a16625cbc387036876ab6ba70912730faf8e1f"}, + {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8e03406cac8513435335dbab54c0d385e4a49e4945d2909a581c83647ca0290"}, + {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f753120cb8181e736c57ef7636e83f31b9c0d1722c516f7e86cf15b7aa57ff12"}, + {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b1fdb9dc17f5a7677423d508ab4f243a726dea51fa5e70992e59a7411c89d19"}, + {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0b69e4ce7a131fe56b7e4d770c67429700908fc0752af059838b1cfb41960e4e"}, + {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a9f8c2e67970f13b16084e04f134610fd1d374bf477b17ec1599185cf611d725"}, + {file = "PyYAML-6.0.2-cp39-cp39-win32.whl", hash = "sha256:6395c297d42274772abc367baaa79683958044e5d3835486c16da75d2a694631"}, + {file = "PyYAML-6.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:39693e1f8320ae4f43943590b49779ffb98acb81f788220ea932a6b6c51004d8"}, + {file = "pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e"}, ] [[package]] name = "pyzmq" -version = "26.0.3" +version = "26.1.0" description = "Python bindings for 0MQ" optional = true python-versions = ">=3.7" files = [ - {file = "pyzmq-26.0.3-cp310-cp310-macosx_10_15_universal2.whl", hash = "sha256:44dd6fc3034f1eaa72ece33588867df9e006a7303725a12d64c3dff92330f625"}, - {file = "pyzmq-26.0.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:acb704195a71ac5ea5ecf2811c9ee19ecdc62b91878528302dd0be1b9451cc90"}, - {file = "pyzmq-26.0.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5dbb9c997932473a27afa93954bb77a9f9b786b4ccf718d903f35da3232317de"}, - {file = "pyzmq-26.0.3-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6bcb34f869d431799c3ee7d516554797f7760cb2198ecaa89c3f176f72d062be"}, - {file = "pyzmq-26.0.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:38ece17ec5f20d7d9b442e5174ae9f020365d01ba7c112205a4d59cf19dc38ee"}, - {file = "pyzmq-26.0.3-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:ba6e5e6588e49139a0979d03a7deb9c734bde647b9a8808f26acf9c547cab1bf"}, - {file = "pyzmq-26.0.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:3bf8b000a4e2967e6dfdd8656cd0757d18c7e5ce3d16339e550bd462f4857e59"}, - {file = "pyzmq-26.0.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:2136f64fbb86451dbbf70223635a468272dd20075f988a102bf8a3f194a411dc"}, - {file = "pyzmq-26.0.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:e8918973fbd34e7814f59143c5f600ecd38b8038161239fd1a3d33d5817a38b8"}, - {file = "pyzmq-26.0.3-cp310-cp310-win32.whl", hash = "sha256:0aaf982e68a7ac284377d051c742610220fd06d330dcd4c4dbb4cdd77c22a537"}, - {file = "pyzmq-26.0.3-cp310-cp310-win_amd64.whl", hash = "sha256:f1a9b7d00fdf60b4039f4455afd031fe85ee8305b019334b72dcf73c567edc47"}, - {file = "pyzmq-26.0.3-cp310-cp310-win_arm64.whl", hash = "sha256:80b12f25d805a919d53efc0a5ad7c0c0326f13b4eae981a5d7b7cc343318ebb7"}, - {file = "pyzmq-26.0.3-cp311-cp311-macosx_10_15_universal2.whl", hash = "sha256:a72a84570f84c374b4c287183debc776dc319d3e8ce6b6a0041ce2e400de3f32"}, - {file = "pyzmq-26.0.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:7ca684ee649b55fd8f378127ac8462fb6c85f251c2fb027eb3c887e8ee347bcd"}, - {file = "pyzmq-26.0.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e222562dc0f38571c8b1ffdae9d7adb866363134299264a1958d077800b193b7"}, - {file = "pyzmq-26.0.3-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f17cde1db0754c35a91ac00b22b25c11da6eec5746431d6e5092f0cd31a3fea9"}, - {file = "pyzmq-26.0.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4b7c0c0b3244bb2275abe255d4a30c050d541c6cb18b870975553f1fb6f37527"}, - {file = "pyzmq-26.0.3-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:ac97a21de3712afe6a6c071abfad40a6224fd14fa6ff0ff8d0c6e6cd4e2f807a"}, - {file = "pyzmq-26.0.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:88b88282e55fa39dd556d7fc04160bcf39dea015f78e0cecec8ff4f06c1fc2b5"}, - {file = "pyzmq-26.0.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:72b67f966b57dbd18dcc7efbc1c7fc9f5f983e572db1877081f075004614fcdd"}, - {file = "pyzmq-26.0.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:f4b6cecbbf3b7380f3b61de3a7b93cb721125dc125c854c14ddc91225ba52f83"}, - {file = "pyzmq-26.0.3-cp311-cp311-win32.whl", hash = "sha256:eed56b6a39216d31ff8cd2f1d048b5bf1700e4b32a01b14379c3b6dde9ce3aa3"}, - {file = "pyzmq-26.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:3191d312c73e3cfd0f0afdf51df8405aafeb0bad71e7ed8f68b24b63c4f36500"}, - {file = "pyzmq-26.0.3-cp311-cp311-win_arm64.whl", hash = "sha256:b6907da3017ef55139cf0e417c5123a84c7332520e73a6902ff1f79046cd3b94"}, - {file = "pyzmq-26.0.3-cp312-cp312-macosx_10_15_universal2.whl", hash = "sha256:068ca17214038ae986d68f4a7021f97e187ed278ab6dccb79f837d765a54d753"}, - {file = "pyzmq-26.0.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:7821d44fe07335bea256b9f1f41474a642ca55fa671dfd9f00af8d68a920c2d4"}, - {file = "pyzmq-26.0.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eeb438a26d87c123bb318e5f2b3d86a36060b01f22fbdffd8cf247d52f7c9a2b"}, - {file = "pyzmq-26.0.3-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:69ea9d6d9baa25a4dc9cef5e2b77b8537827b122214f210dd925132e34ae9b12"}, - {file = "pyzmq-26.0.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7daa3e1369355766dea11f1d8ef829905c3b9da886ea3152788dc25ee6079e02"}, - {file = "pyzmq-26.0.3-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:6ca7a9a06b52d0e38ccf6bca1aeff7be178917893f3883f37b75589d42c4ac20"}, - {file = "pyzmq-26.0.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:1b7d0e124948daa4d9686d421ef5087c0516bc6179fdcf8828b8444f8e461a77"}, - {file = "pyzmq-26.0.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:e746524418b70f38550f2190eeee834db8850088c834d4c8406fbb9bc1ae10b2"}, - {file = "pyzmq-26.0.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:6b3146f9ae6af82c47a5282ac8803523d381b3b21caeae0327ed2f7ecb718798"}, - {file = "pyzmq-26.0.3-cp312-cp312-win32.whl", hash = "sha256:2b291d1230845871c00c8462c50565a9cd6026fe1228e77ca934470bb7d70ea0"}, - {file = "pyzmq-26.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:926838a535c2c1ea21c903f909a9a54e675c2126728c21381a94ddf37c3cbddf"}, - {file = "pyzmq-26.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:5bf6c237f8c681dfb91b17f8435b2735951f0d1fad10cc5dfd96db110243370b"}, - {file = "pyzmq-26.0.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:0c0991f5a96a8e620f7691e61178cd8f457b49e17b7d9cfa2067e2a0a89fc1d5"}, - {file = "pyzmq-26.0.3-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:dbf012d8fcb9f2cf0643b65df3b355fdd74fc0035d70bb5c845e9e30a3a4654b"}, - {file = "pyzmq-26.0.3-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:01fbfbeb8249a68d257f601deb50c70c929dc2dfe683b754659569e502fbd3aa"}, - {file = "pyzmq-26.0.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1c8eb19abe87029c18f226d42b8a2c9efdd139d08f8bf6e085dd9075446db450"}, - {file = "pyzmq-26.0.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:5344b896e79800af86ad643408ca9aa303a017f6ebff8cee5a3163c1e9aec987"}, - {file = "pyzmq-26.0.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:204e0f176fd1d067671157d049466869b3ae1fc51e354708b0dc41cf94e23a3a"}, - {file = "pyzmq-26.0.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:a42db008d58530efa3b881eeee4991146de0b790e095f7ae43ba5cc612decbc5"}, - {file = "pyzmq-26.0.3-cp37-cp37m-win32.whl", hash = "sha256:8d7a498671ca87e32b54cb47c82a92b40130a26c5197d392720a1bce1b3c77cf"}, - {file = "pyzmq-26.0.3-cp37-cp37m-win_amd64.whl", hash = "sha256:3b4032a96410bdc760061b14ed6a33613ffb7f702181ba999df5d16fb96ba16a"}, - {file = "pyzmq-26.0.3-cp38-cp38-macosx_10_15_universal2.whl", hash = "sha256:2cc4e280098c1b192c42a849de8de2c8e0f3a84086a76ec5b07bfee29bda7d18"}, - {file = "pyzmq-26.0.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:5bde86a2ed3ce587fa2b207424ce15b9a83a9fa14422dcc1c5356a13aed3df9d"}, - {file = "pyzmq-26.0.3-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:34106f68e20e6ff253c9f596ea50397dbd8699828d55e8fa18bd4323d8d966e6"}, - {file = "pyzmq-26.0.3-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ebbbd0e728af5db9b04e56389e2299a57ea8b9dd15c9759153ee2455b32be6ad"}, - {file = "pyzmq-26.0.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f6b1d1c631e5940cac5a0b22c5379c86e8df6a4ec277c7a856b714021ab6cfad"}, - {file = "pyzmq-26.0.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:e891ce81edd463b3b4c3b885c5603c00141151dd9c6936d98a680c8c72fe5c67"}, - {file = "pyzmq-26.0.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:9b273ecfbc590a1b98f014ae41e5cf723932f3b53ba9367cfb676f838038b32c"}, - {file = "pyzmq-26.0.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:b32bff85fb02a75ea0b68f21e2412255b5731f3f389ed9aecc13a6752f58ac97"}, - {file = "pyzmq-26.0.3-cp38-cp38-win32.whl", hash = "sha256:f6c21c00478a7bea93caaaef9e7629145d4153b15a8653e8bb4609d4bc70dbfc"}, - {file = "pyzmq-26.0.3-cp38-cp38-win_amd64.whl", hash = "sha256:3401613148d93ef0fd9aabdbddb212de3db7a4475367f49f590c837355343972"}, - {file = "pyzmq-26.0.3-cp39-cp39-macosx_10_15_universal2.whl", hash = "sha256:2ed8357f4c6e0daa4f3baf31832df8a33334e0fe5b020a61bc8b345a3db7a606"}, - {file = "pyzmq-26.0.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c1c8f2a2ca45292084c75bb6d3a25545cff0ed931ed228d3a1810ae3758f975f"}, - {file = "pyzmq-26.0.3-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:b63731993cdddcc8e087c64e9cf003f909262b359110070183d7f3025d1c56b5"}, - {file = "pyzmq-26.0.3-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:b3cd31f859b662ac5d7f4226ec7d8bd60384fa037fc02aee6ff0b53ba29a3ba8"}, - {file = "pyzmq-26.0.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:115f8359402fa527cf47708d6f8a0f8234f0e9ca0cab7c18c9c189c194dbf620"}, - {file = "pyzmq-26.0.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:715bdf952b9533ba13dfcf1f431a8f49e63cecc31d91d007bc1deb914f47d0e4"}, - {file = "pyzmq-26.0.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:e1258c639e00bf5e8a522fec6c3eaa3e30cf1c23a2f21a586be7e04d50c9acab"}, - {file = "pyzmq-26.0.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:15c59e780be8f30a60816a9adab900c12a58d79c1ac742b4a8df044ab2a6d920"}, - {file = "pyzmq-26.0.3-cp39-cp39-win32.whl", hash = "sha256:d0cdde3c78d8ab5b46595054e5def32a755fc028685add5ddc7403e9f6de9879"}, - {file = "pyzmq-26.0.3-cp39-cp39-win_amd64.whl", hash = "sha256:ce828058d482ef860746bf532822842e0ff484e27f540ef5c813d516dd8896d2"}, - {file = "pyzmq-26.0.3-cp39-cp39-win_arm64.whl", hash = "sha256:788f15721c64109cf720791714dc14afd0f449d63f3a5487724f024345067381"}, - {file = "pyzmq-26.0.3-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:2c18645ef6294d99b256806e34653e86236eb266278c8ec8112622b61db255de"}, - {file = "pyzmq-26.0.3-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7e6bc96ebe49604df3ec2c6389cc3876cabe475e6bfc84ced1bf4e630662cb35"}, - {file = "pyzmq-26.0.3-pp310-pypy310_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:971e8990c5cc4ddcff26e149398fc7b0f6a042306e82500f5e8db3b10ce69f84"}, - {file = "pyzmq-26.0.3-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d8416c23161abd94cc7da80c734ad7c9f5dbebdadfdaa77dad78244457448223"}, - {file = "pyzmq-26.0.3-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:082a2988364b60bb5de809373098361cf1dbb239623e39e46cb18bc035ed9c0c"}, - {file = "pyzmq-26.0.3-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:d57dfbf9737763b3a60d26e6800e02e04284926329aee8fb01049635e957fe81"}, - {file = "pyzmq-26.0.3-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:77a85dca4c2430ac04dc2a2185c2deb3858a34fe7f403d0a946fa56970cf60a1"}, - {file = "pyzmq-26.0.3-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:4c82a6d952a1d555bf4be42b6532927d2a5686dd3c3e280e5f63225ab47ac1f5"}, - {file = "pyzmq-26.0.3-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4496b1282c70c442809fc1b151977c3d967bfb33e4e17cedbf226d97de18f709"}, - {file = "pyzmq-26.0.3-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:e4946d6bdb7ba972dfda282f9127e5756d4f299028b1566d1245fa0d438847e6"}, - {file = "pyzmq-26.0.3-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:03c0ae165e700364b266876d712acb1ac02693acd920afa67da2ebb91a0b3c09"}, - {file = "pyzmq-26.0.3-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:3e3070e680f79887d60feeda051a58d0ac36622e1759f305a41059eff62c6da7"}, - {file = "pyzmq-26.0.3-pp38-pypy38_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:6ca08b840fe95d1c2bd9ab92dac5685f949fc6f9ae820ec16193e5ddf603c3b2"}, - {file = "pyzmq-26.0.3-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e76654e9dbfb835b3518f9938e565c7806976c07b37c33526b574cc1a1050480"}, - {file = "pyzmq-26.0.3-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:871587bdadd1075b112e697173e946a07d722459d20716ceb3d1bd6c64bd08ce"}, - {file = "pyzmq-26.0.3-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:d0a2d1bd63a4ad79483049b26514e70fa618ce6115220da9efdff63688808b17"}, - {file = "pyzmq-26.0.3-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0270b49b6847f0d106d64b5086e9ad5dc8a902413b5dbbb15d12b60f9c1747a4"}, - {file = "pyzmq-26.0.3-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:703c60b9910488d3d0954ca585c34f541e506a091a41930e663a098d3b794c67"}, - {file = "pyzmq-26.0.3-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:74423631b6be371edfbf7eabb02ab995c2563fee60a80a30829176842e71722a"}, - {file = "pyzmq-26.0.3-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:4adfbb5451196842a88fda3612e2c0414134874bffb1c2ce83ab4242ec9e027d"}, - {file = "pyzmq-26.0.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:3516119f4f9b8671083a70b6afaa0a070f5683e431ab3dc26e9215620d7ca1ad"}, - {file = "pyzmq-26.0.3.tar.gz", hash = "sha256:dba7d9f2e047dfa2bca3b01f4f84aa5246725203d6284e3790f2ca15fba6b40a"}, + {file = "pyzmq-26.1.0-cp310-cp310-macosx_10_15_universal2.whl", hash = "sha256:263cf1e36862310bf5becfbc488e18d5d698941858860c5a8c079d1511b3b18e"}, + {file = "pyzmq-26.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d5c8b17f6e8f29138678834cf8518049e740385eb2dbf736e8f07fc6587ec682"}, + {file = "pyzmq-26.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:75a95c2358fcfdef3374cb8baf57f1064d73246d55e41683aaffb6cfe6862917"}, + {file = "pyzmq-26.1.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f99de52b8fbdb2a8f5301ae5fc0f9e6b3ba30d1d5fc0421956967edcc6914242"}, + {file = "pyzmq-26.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7bcbfbab4e1895d58ab7da1b5ce9a327764f0366911ba5b95406c9104bceacb0"}, + {file = "pyzmq-26.1.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:77ce6a332c7e362cb59b63f5edf730e83590d0ab4e59c2aa5bd79419a42e3449"}, + {file = "pyzmq-26.1.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:ba0a31d00e8616149a5ab440d058ec2da621e05d744914774c4dde6837e1f545"}, + {file = "pyzmq-26.1.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:8b88641384e84a258b740801cd4dbc45c75f148ee674bec3149999adda4a8598"}, + {file = "pyzmq-26.1.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:2fa76ebcebe555cce90f16246edc3ad83ab65bb7b3d4ce408cf6bc67740c4f88"}, + {file = "pyzmq-26.1.0-cp310-cp310-win32.whl", hash = "sha256:fbf558551cf415586e91160d69ca6416f3fce0b86175b64e4293644a7416b81b"}, + {file = "pyzmq-26.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:a7b8aab50e5a288c9724d260feae25eda69582be84e97c012c80e1a5e7e03fb2"}, + {file = "pyzmq-26.1.0-cp310-cp310-win_arm64.whl", hash = "sha256:08f74904cb066e1178c1ec706dfdb5c6c680cd7a8ed9efebeac923d84c1f13b1"}, + {file = "pyzmq-26.1.0-cp311-cp311-macosx_10_15_universal2.whl", hash = "sha256:46d6800b45015f96b9d92ece229d92f2aef137d82906577d55fadeb9cf5fcb71"}, + {file = "pyzmq-26.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5bc2431167adc50ba42ea3e5e5f5cd70d93e18ab7b2f95e724dd8e1bd2c38120"}, + {file = "pyzmq-26.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b3bb34bebaa1b78e562931a1687ff663d298013f78f972a534f36c523311a84d"}, + {file = "pyzmq-26.1.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bd3f6329340cef1c7ba9611bd038f2d523cea79f09f9c8f6b0553caba59ec562"}, + {file = "pyzmq-26.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:471880c4c14e5a056a96cd224f5e71211997d40b4bf5e9fdded55dafab1f98f2"}, + {file = "pyzmq-26.1.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:ce6f2b66799971cbae5d6547acefa7231458289e0ad481d0be0740535da38d8b"}, + {file = "pyzmq-26.1.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0a1f6ea5b1d6cdbb8cfa0536f0d470f12b4b41ad83625012e575f0e3ecfe97f0"}, + {file = "pyzmq-26.1.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:b45e6445ac95ecb7d728604bae6538f40ccf4449b132b5428c09918523abc96d"}, + {file = "pyzmq-26.1.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:94c4262626424683feea0f3c34951d39d49d354722db2745c42aa6bb50ecd93b"}, + {file = "pyzmq-26.1.0-cp311-cp311-win32.whl", hash = "sha256:a0f0ab9df66eb34d58205913f4540e2ad17a175b05d81b0b7197bc57d000e829"}, + {file = "pyzmq-26.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:8efb782f5a6c450589dbab4cb0f66f3a9026286333fe8f3a084399149af52f29"}, + {file = "pyzmq-26.1.0-cp311-cp311-win_arm64.whl", hash = "sha256:f133d05aaf623519f45e16ab77526e1e70d4e1308e084c2fb4cedb1a0c764bbb"}, + {file = "pyzmq-26.1.0-cp312-cp312-macosx_10_15_universal2.whl", hash = "sha256:3d3146b1c3dcc8a1539e7cc094700b2be1e605a76f7c8f0979b6d3bde5ad4072"}, + {file = "pyzmq-26.1.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d9270fbf038bf34ffca4855bcda6e082e2c7f906b9eb8d9a8ce82691166060f7"}, + {file = "pyzmq-26.1.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:995301f6740a421afc863a713fe62c0aaf564708d4aa057dfdf0f0f56525294b"}, + {file = "pyzmq-26.1.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7eca8b89e56fb8c6c26dd3e09bd41b24789022acf1cf13358e96f1cafd8cae3"}, + {file = "pyzmq-26.1.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90d4feb2e83dfe9ace6374a847e98ee9d1246ebadcc0cb765482e272c34e5820"}, + {file = "pyzmq-26.1.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:d4fafc2eb5d83f4647331267808c7e0c5722c25a729a614dc2b90479cafa78bd"}, + {file = "pyzmq-26.1.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:58c33dc0e185dd97a9ac0288b3188d1be12b756eda67490e6ed6a75cf9491d79"}, + {file = "pyzmq-26.1.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:68a0a1d83d33d8367ddddb3e6bb4afbb0f92bd1dac2c72cd5e5ddc86bdafd3eb"}, + {file = "pyzmq-26.1.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:2ae7c57e22ad881af78075e0cea10a4c778e67234adc65c404391b417a4dda83"}, + {file = "pyzmq-26.1.0-cp312-cp312-win32.whl", hash = "sha256:347e84fc88cc4cb646597f6d3a7ea0998f887ee8dc31c08587e9c3fd7b5ccef3"}, + {file = "pyzmq-26.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:9f136a6e964830230912f75b5a116a21fe8e34128dcfd82285aa0ef07cb2c7bd"}, + {file = "pyzmq-26.1.0-cp312-cp312-win_arm64.whl", hash = "sha256:a4b7a989c8f5a72ab1b2bbfa58105578753ae77b71ba33e7383a31ff75a504c4"}, + {file = "pyzmq-26.1.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:d416f2088ac8f12daacffbc2e8918ef4d6be8568e9d7155c83b7cebed49d2322"}, + {file = "pyzmq-26.1.0-cp313-cp313-macosx_10_15_universal2.whl", hash = "sha256:ecb6c88d7946166d783a635efc89f9a1ff11c33d680a20df9657b6902a1d133b"}, + {file = "pyzmq-26.1.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:471312a7375571857a089342beccc1a63584315188560c7c0da7e0a23afd8a5c"}, + {file = "pyzmq-26.1.0-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0e6cea102ffa16b737d11932c426f1dc14b5938cf7bc12e17269559c458ac334"}, + {file = "pyzmq-26.1.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec7248673ffc7104b54e4957cee38b2f3075a13442348c8d651777bf41aa45ee"}, + {file = "pyzmq-26.1.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:0614aed6f87d550b5cecb03d795f4ddbb1544b78d02a4bd5eecf644ec98a39f6"}, + {file = "pyzmq-26.1.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:e8746ce968be22a8a1801bf4a23e565f9687088580c3ed07af5846580dd97f76"}, + {file = "pyzmq-26.1.0-cp313-cp313-musllinux_1_1_i686.whl", hash = "sha256:7688653574392d2eaeef75ddcd0b2de5b232d8730af29af56c5adf1df9ef8d6f"}, + {file = "pyzmq-26.1.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:8d4dac7d97f15c653a5fedcafa82626bd6cee1450ccdaf84ffed7ea14f2b07a4"}, + {file = "pyzmq-26.1.0-cp313-cp313-win32.whl", hash = "sha256:ccb42ca0a4a46232d716779421bbebbcad23c08d37c980f02cc3a6bd115ad277"}, + {file = "pyzmq-26.1.0-cp313-cp313-win_amd64.whl", hash = "sha256:e1e5d0a25aea8b691a00d6b54b28ac514c8cc0d8646d05f7ca6cb64b97358250"}, + {file = "pyzmq-26.1.0-cp313-cp313-win_arm64.whl", hash = "sha256:fc82269d24860cfa859b676d18850cbb8e312dcd7eada09e7d5b007e2f3d9eb1"}, + {file = "pyzmq-26.1.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:416ac51cabd54f587995c2b05421324700b22e98d3d0aa2cfaec985524d16f1d"}, + {file = "pyzmq-26.1.0-cp313-cp313t-macosx_10_15_universal2.whl", hash = "sha256:ff832cce719edd11266ca32bc74a626b814fff236824aa1aeaad399b69fe6eae"}, + {file = "pyzmq-26.1.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:393daac1bcf81b2a23e696b7b638eedc965e9e3d2112961a072b6cd8179ad2eb"}, + {file = "pyzmq-26.1.0-cp313-cp313t-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9869fa984c8670c8ab899a719eb7b516860a29bc26300a84d24d8c1b71eae3ec"}, + {file = "pyzmq-26.1.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b3b8e36fd4c32c0825b4461372949ecd1585d326802b1321f8b6dc1d7e9318c"}, + {file = "pyzmq-26.1.0-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:3ee647d84b83509b7271457bb428cc347037f437ead4b0b6e43b5eba35fec0aa"}, + {file = "pyzmq-26.1.0-cp313-cp313t-musllinux_1_1_aarch64.whl", hash = "sha256:45cb1a70eb00405ce3893041099655265fabcd9c4e1e50c330026e82257892c1"}, + {file = "pyzmq-26.1.0-cp313-cp313t-musllinux_1_1_i686.whl", hash = "sha256:5cca7b4adb86d7470e0fc96037771981d740f0b4cb99776d5cb59cd0e6684a73"}, + {file = "pyzmq-26.1.0-cp313-cp313t-musllinux_1_1_x86_64.whl", hash = "sha256:91d1a20bdaf3b25f3173ff44e54b1cfbc05f94c9e8133314eb2962a89e05d6e3"}, + {file = "pyzmq-26.1.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c0665d85535192098420428c779361b8823d3d7ec4848c6af3abb93bc5c915bf"}, + {file = "pyzmq-26.1.0-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:96d7c1d35ee4a495df56c50c83df7af1c9688cce2e9e0edffdbf50889c167595"}, + {file = "pyzmq-26.1.0-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:b281b5ff5fcc9dcbfe941ac5c7fcd4b6c065adad12d850f95c9d6f23c2652384"}, + {file = "pyzmq-26.1.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5384c527a9a004445c5074f1e20db83086c8ff1682a626676229aafd9cf9f7d1"}, + {file = "pyzmq-26.1.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:754c99a9840839375ee251b38ac5964c0f369306eddb56804a073b6efdc0cd88"}, + {file = "pyzmq-26.1.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:9bdfcb74b469b592972ed881bad57d22e2c0acc89f5e8c146782d0d90fb9f4bf"}, + {file = "pyzmq-26.1.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:bd13f0231f4788db619347b971ca5f319c5b7ebee151afc7c14632068c6261d3"}, + {file = "pyzmq-26.1.0-cp37-cp37m-win32.whl", hash = "sha256:c5668dac86a869349828db5fc928ee3f58d450dce2c85607067d581f745e4fb1"}, + {file = "pyzmq-26.1.0-cp37-cp37m-win_amd64.whl", hash = "sha256:ad875277844cfaeca7fe299ddf8c8d8bfe271c3dc1caf14d454faa5cdbf2fa7a"}, + {file = "pyzmq-26.1.0-cp38-cp38-macosx_10_15_universal2.whl", hash = "sha256:65c6e03cc0222eaf6aad57ff4ecc0a070451e23232bb48db4322cc45602cede0"}, + {file = "pyzmq-26.1.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:038ae4ffb63e3991f386e7fda85a9baab7d6617fe85b74a8f9cab190d73adb2b"}, + {file = "pyzmq-26.1.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:bdeb2c61611293f64ac1073f4bf6723b67d291905308a7de9bb2ca87464e3273"}, + {file = "pyzmq-26.1.0-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:61dfa5ee9d7df297c859ac82b1226d8fefaf9c5113dc25c2c00ecad6feeeb04f"}, + {file = "pyzmq-26.1.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f3292d384537b9918010769b82ab3e79fca8b23d74f56fc69a679106a3e2c2cf"}, + {file = "pyzmq-26.1.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:f9499c70c19ff0fbe1007043acb5ad15c1dec7d8e84ab429bca8c87138e8f85c"}, + {file = "pyzmq-26.1.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:d3dd5523ed258ad58fed7e364c92a9360d1af8a9371e0822bd0146bdf017ef4c"}, + {file = "pyzmq-26.1.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:baba2fd199b098c5544ef2536b2499d2e2155392973ad32687024bd8572a7d1c"}, + {file = "pyzmq-26.1.0-cp38-cp38-win32.whl", hash = "sha256:ddbb2b386128d8eca92bd9ca74e80f73fe263bcca7aa419f5b4cbc1661e19741"}, + {file = "pyzmq-26.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:79e45a4096ec8388cdeb04a9fa5e9371583bcb826964d55b8b66cbffe7b33c86"}, + {file = "pyzmq-26.1.0-cp39-cp39-macosx_10_15_universal2.whl", hash = "sha256:add52c78a12196bc0fda2de087ba6c876ea677cbda2e3eba63546b26e8bf177b"}, + {file = "pyzmq-26.1.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:98c03bd7f3339ff47de7ea9ac94a2b34580a8d4df69b50128bb6669e1191a895"}, + {file = "pyzmq-26.1.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:dcc37d9d708784726fafc9c5e1232de655a009dbf97946f117aefa38d5985a0f"}, + {file = "pyzmq-26.1.0-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:5a6ed52f0b9bf8dcc64cc82cce0607a3dfed1dbb7e8c6f282adfccc7be9781de"}, + {file = "pyzmq-26.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:451e16ae8bea3d95649317b463c9f95cd9022641ec884e3d63fc67841ae86dfe"}, + {file = "pyzmq-26.1.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:906e532c814e1d579138177a00ae835cd6becbf104d45ed9093a3aaf658f6a6a"}, + {file = "pyzmq-26.1.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:05bacc4f94af468cc82808ae3293390278d5f3375bb20fef21e2034bb9a505b6"}, + {file = "pyzmq-26.1.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:57bb2acba798dc3740e913ffadd56b1fcef96f111e66f09e2a8db3050f1f12c8"}, + {file = "pyzmq-26.1.0-cp39-cp39-win32.whl", hash = "sha256:f774841bb0e8588505002962c02da420bcfb4c5056e87a139c6e45e745c0e2e2"}, + {file = "pyzmq-26.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:359c533bedc62c56415a1f5fcfd8279bc93453afdb0803307375ecf81c962402"}, + {file = "pyzmq-26.1.0-cp39-cp39-win_arm64.whl", hash = "sha256:7907419d150b19962138ecec81a17d4892ea440c184949dc29b358bc730caf69"}, + {file = "pyzmq-26.1.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:b24079a14c9596846bf7516fe75d1e2188d4a528364494859106a33d8b48be38"}, + {file = "pyzmq-26.1.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:59d0acd2976e1064f1b398a00e2c3e77ed0a157529779e23087d4c2fb8aaa416"}, + {file = "pyzmq-26.1.0-pp310-pypy310_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:911c43a4117915203c4cc8755e0f888e16c4676a82f61caee2f21b0c00e5b894"}, + {file = "pyzmq-26.1.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b10163e586cc609f5f85c9b233195554d77b1e9a0801388907441aaeb22841c5"}, + {file = "pyzmq-26.1.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:28a8b2abb76042f5fd7bd720f7fea48c0fd3e82e9de0a1bf2c0de3812ce44a42"}, + {file = "pyzmq-26.1.0-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:bef24d3e4ae2c985034439f449e3f9e06bf579974ce0e53d8a507a1577d5b2ab"}, + {file = "pyzmq-26.1.0-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:2cd0f4d314f4a2518e8970b6f299ae18cff7c44d4a1fc06fc713f791c3a9e3ea"}, + {file = "pyzmq-26.1.0-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:fa25a620eed2a419acc2cf10135b995f8f0ce78ad00534d729aa761e4adcef8a"}, + {file = "pyzmq-26.1.0-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ef3b048822dca6d231d8a8ba21069844ae38f5d83889b9b690bf17d2acc7d099"}, + {file = "pyzmq-26.1.0-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:9a6847c92d9851b59b9f33f968c68e9e441f9a0f8fc972c5580c5cd7cbc6ee24"}, + {file = "pyzmq-26.1.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:c9b9305004d7e4e6a824f4f19b6d8f32b3578aad6f19fc1122aaf320cbe3dc83"}, + {file = "pyzmq-26.1.0-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:63c1d3a65acb2f9c92dce03c4e1758cc552f1ae5c78d79a44e3bb88d2fa71f3a"}, + {file = "pyzmq-26.1.0-pp38-pypy38_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:d36b8fffe8b248a1b961c86fbdfa0129dfce878731d169ede7fa2631447331be"}, + {file = "pyzmq-26.1.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:67976d12ebfd61a3bc7d77b71a9589b4d61d0422282596cf58c62c3866916544"}, + {file = "pyzmq-26.1.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:998444debc8816b5d8d15f966e42751032d0f4c55300c48cc337f2b3e4f17d03"}, + {file = "pyzmq-26.1.0-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:e5c88b2f13bcf55fee78ea83567b9fe079ba1a4bef8b35c376043440040f7edb"}, + {file = "pyzmq-26.1.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8d906d43e1592be4b25a587b7d96527cb67277542a5611e8ea9e996182fae410"}, + {file = "pyzmq-26.1.0-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:80b0c9942430d731c786545da6be96d824a41a51742e3e374fedd9018ea43106"}, + {file = "pyzmq-26.1.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:314d11564c00b77f6224d12eb3ddebe926c301e86b648a1835c5b28176c83eab"}, + {file = "pyzmq-26.1.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:093a1a3cae2496233f14b57f4b485da01b4ff764582c854c0f42c6dd2be37f3d"}, + {file = "pyzmq-26.1.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:3c397b1b450f749a7e974d74c06d69bd22dd362142f370ef2bd32a684d6b480c"}, + {file = "pyzmq-26.1.0.tar.gz", hash = "sha256:6c5aeea71f018ebd3b9115c7cb13863dd850e98ca6b9258509de1246461a7e7f"}, ] [package.dependencies] @@ -2572,13 +2638,13 @@ rpds-py = ">=0.7.0" [[package]] name = "requests" -version = "2.32.1" +version = "2.32.3" description = "Python HTTP for Humans." optional = true python-versions = ">=3.8" files = [ - {file = "requests-2.32.1-py3-none-any.whl", hash = "sha256:21ac9465cdf8c1650fe1ecde8a71669a93d4e6f147550483a2967d08396a56a5"}, - {file = "requests-2.32.1.tar.gz", hash = "sha256:eb97e87e64c79e64e5b8ac75cee9dd1f97f49e289b083ee6be96268930725685"}, + {file = "requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6"}, + {file = "requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760"}, ] [package.dependencies] @@ -2618,40 +2684,48 @@ files = [ [[package]] name = "rosco" -version = "2.9.2" +version = "2.9.4" description = "A reference open source controller toolset for wind turbine applications." optional = true python-versions = ">=3.9" files = [ - {file = "rosco-2.9.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:60c0517592c2aa91b2a9ee07e51e4f0464fc7820728f9eb28bd6a81f1195d7cf"}, - {file = "rosco-2.9.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:15d02bb5df5ee41f01dae5ed23526b10f95bcb47df822017d732df3cd50aae4c"}, - {file = "rosco-2.9.2-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3259b7aad8225854168ba9fbde9a4f2b01eadd46230e6366d49dd628476a630a"}, - {file = "rosco-2.9.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4e16d6829d08871503154ad7b8a909a9940456c90b9baf97f7e80f1bfbcbc169"}, - {file = "rosco-2.9.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:d51b8bf8f75a9ad28d6b971a03ac24db20fb976f9ed8423d952e10e19ea1c98e"}, - {file = "rosco-2.9.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7b19c1b9ffe1094f008c7865594a60ee84c383c7318b4ec8e003c8b6f32fb4c7"}, - {file = "rosco-2.9.2-cp310-cp310-win_amd64.whl", hash = "sha256:c6516482ffd15d1fdf20ab8fd495ad9e353af7bbc15098162841e1f4bd681469"}, - {file = "rosco-2.9.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d79ea0d2ff5c904734b270e5381867157d28a83dd38c05bee1243ead5cd75259"}, - {file = "rosco-2.9.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:088bfe893bae96d4f170b9058fa332ceca3d89a16f33f91f0f3003bd67e4f7dc"}, - {file = "rosco-2.9.2-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:622552efb359e12108ae3756eaa5bd29e6c473deb3cc36e99ac75975bf784941"}, - {file = "rosco-2.9.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:68fe33db823b140ee1f110338c1bd6863cb0d6c81a5d2a41bf486dece462e87e"}, - {file = "rosco-2.9.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:39549a110cb3959074d69afb76ee0638256f7b037064d947f088a4776a34b5d7"}, - {file = "rosco-2.9.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:ded6e74bcba36f5229c8ccc7b8e4a7ef1fc151971d0c9a0688abc4766b371cb6"}, - {file = "rosco-2.9.2-cp311-cp311-win_amd64.whl", hash = "sha256:04094e3fec7b8036af6c9946e6571105b3471ba985936d201ff4eaaa95033d43"}, - {file = "rosco-2.9.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:266e0686dfa50266232f82dc47d79bfdccc3181276b4e31ccd7fcc7d61155776"}, - {file = "rosco-2.9.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7ced257d0b979fb246230cdb273f20cc348606ba6fb7e0f3a760563aa0e9701e"}, - {file = "rosco-2.9.2-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:30d6f2f81e235ea2d7e60be7f850f4917d3cb720670ba7122b8b789a76df873c"}, - {file = "rosco-2.9.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:51ec350c68805e3912a465cf2383388455d11111ef89e761e7ff1fedcadf8567"}, - {file = "rosco-2.9.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:a6ff437c517337b1cf7e0e2fbe240e05c9f3ceb1aa0ab3fb3b984eaa669d4056"}, - {file = "rosco-2.9.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:eff41c9b5e01a53172d10311d8646e6c91a09f7992e7ad7b5bb7bf9ccabc1f42"}, - {file = "rosco-2.9.2-cp312-cp312-win_amd64.whl", hash = "sha256:8d77d3ce031679ff2472c4fbc12ce0f1a6aa7d531b6f6bce7a34550a67b822bd"}, - {file = "rosco-2.9.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4b1dbb3e5c6ae14cc6fbbfe7e1788ee343c14319db44d1a1428e2aaa9d40588b"}, - {file = "rosco-2.9.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:20a0094dee3eac9ab89289a413a76655829320ed801b4839489c19bbc6f209a6"}, - {file = "rosco-2.9.2-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:df83ad48ee5b7c3b5474b85415fc8bd58454cf7db1eeaeae17cda974fc62eb8f"}, - {file = "rosco-2.9.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5aa15741d31b5c330087ffb548a0a1e9e50cd49b14dddfc214bb9c2e5e502122"}, - {file = "rosco-2.9.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:32b23a81edec1740f2df2ef77384a907aced6d00f6674acbf38b52198ddd9116"}, - {file = "rosco-2.9.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:79e8fe1d9aef79e22ddd946163e188f6f7852eac319fbfe4276f811353b509f9"}, - {file = "rosco-2.9.2-cp39-cp39-win_amd64.whl", hash = "sha256:2d645a4c226d28a08bf321a89ffd29ada4f1acf747b06cbe87609274bf02fc12"}, - {file = "rosco-2.9.2.tar.gz", hash = "sha256:8acb411038508dfa5c4104b8b7b29a73a76027c40bf2ff2f673a75e0b6aa5b15"}, + {file = "rosco-2.9.4-cp310-cp310-macosx_12_0_x86_64.whl", hash = "sha256:360cf9602a6ca2deaf3d589f82646d8faf19b0b1dd2493e822d25ed8f178cdf6"}, + {file = "rosco-2.9.4-cp310-cp310-macosx_13_0_x86_64.whl", hash = "sha256:e6c30c73054dbcf6208fda022c3cf332173e1df96a9c64bbd1c9c30c94a98c47"}, + {file = "rosco-2.9.4-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:2a722946cdc5d8e1a6c1f4da95c46aaa531d35c1d7524276821a9b2944af95f2"}, + {file = "rosco-2.9.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d4419fbae21c36da45ffbb071982d47382d7262976bf1165467913f7d80d2e53"}, + {file = "rosco-2.9.4-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:37c8a91ebea113ec789aa51ca904bde82b7af2d9e2e6b3715c53055a56dd8c12"}, + {file = "rosco-2.9.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a51fa398f90123def8998c7afa09398b5c6dfbab3825c4d9ef34e915541e495e"}, + {file = "rosco-2.9.4-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:1f102178ccbe7193f095dc6214d284647f71cfc0dee2235db51fc8c31773488e"}, + {file = "rosco-2.9.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:df7015013fbcfcdd7e272269682658d0eb097048fc98188be62b41a384acf289"}, + {file = "rosco-2.9.4-cp310-cp310-win_amd64.whl", hash = "sha256:c6424b6e7e1a8b42b18e6fe9438dfacbdac3f0556e2e473d2a5653e9252c5d72"}, + {file = "rosco-2.9.4-cp311-cp311-macosx_12_0_x86_64.whl", hash = "sha256:c1eed8dc7dddc37033cf8d490c711b9f7e83a378ec59eac402fe2ddb1045b083"}, + {file = "rosco-2.9.4-cp311-cp311-macosx_13_0_x86_64.whl", hash = "sha256:fc6d49ba895cf387b160b5a08d90c71beb5c60a476957ce163a91a2b59ab5efd"}, + {file = "rosco-2.9.4-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:53157f7bb4cdf42bf6b75435f30bf03c4c848ff1f3bdf1db49f206fb25a66c1c"}, + {file = "rosco-2.9.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7e01170cd9e8ceed79ab0b500e002aa89194f9f9ccdb24f64698426e23de7fbe"}, + {file = "rosco-2.9.4-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:340c2cc66d0798d030fec04d30dda1c5c9177148032cd21acb6387c5a2d14fa6"}, + {file = "rosco-2.9.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9197b5e92646a873cb7eda951fb525e5cdfbdb907d376c1088240e8443e4f50a"}, + {file = "rosco-2.9.4-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e301ba15c1c68cac5b44af6866ea498ccbf6d777008559291854d739421687cd"}, + {file = "rosco-2.9.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:192a13b9758e0177c668d9a04e9d748bd34ab6d6e721018115874e8b24f28c8f"}, + {file = "rosco-2.9.4-cp311-cp311-win_amd64.whl", hash = "sha256:124de26ba6576eda1167f05ce81886aae76400c3d23039b21023bd52732b4d61"}, + {file = "rosco-2.9.4-cp312-cp312-macosx_12_0_x86_64.whl", hash = "sha256:03594a7ee86825e16033cc1fc157367f85b481c895c0f950c3c42866a3ec2851"}, + {file = "rosco-2.9.4-cp312-cp312-macosx_13_0_x86_64.whl", hash = "sha256:46979cf83f0d4610b4697f9621d0b78f32eff0b9ab200f94be564ed4aa73bad7"}, + {file = "rosco-2.9.4-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:d9015b462efdb1fb8629c55395d7d7d8422c11a61fd85446ff227e2e3370736b"}, + {file = "rosco-2.9.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d6c4ef213a4cce2232c9da4306bea42dedf82e72ecc18b41886c172f3bcf090c"}, + {file = "rosco-2.9.4-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d5789fd019bd98b5b3f9f6cc53eb85150e7e58255b959a581b948cb6862ada63"}, + {file = "rosco-2.9.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3121ea1e95fdc01f5bf3acf30bf2722193737691bb1824a86eca86cefbe16f51"}, + {file = "rosco-2.9.4-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:3d0753be2342f168909ada1c250a709fab283198177981783546f16c659c5107"}, + {file = "rosco-2.9.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3779e3dd06d482b94a7e11449b1f9d15a3cf1984ad9d4b104a63164cb36301a0"}, + {file = "rosco-2.9.4-cp312-cp312-win_amd64.whl", hash = "sha256:1be67ad1da9e60d11924219afa6291fbd1401c02566ab931a9d281a4d415d2c5"}, + {file = "rosco-2.9.4-cp39-cp39-macosx_12_0_x86_64.whl", hash = "sha256:d02af3d9b7fe3524148c5656031859310e76cf1c72d8caec768e57b9e3cea8ce"}, + {file = "rosco-2.9.4-cp39-cp39-macosx_13_0_x86_64.whl", hash = "sha256:3c6c058536e4a7cc21e86487b11de0988fb47b12f56ff2b778f15c80a3ef3d9c"}, + {file = "rosco-2.9.4-cp39-cp39-macosx_14_0_arm64.whl", hash = "sha256:5ddf94384bdc7cfd9e45eeaf46b00c6118d0ffa48c049d3c606412b5d0f47ebe"}, + {file = "rosco-2.9.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f69e1a7fa19a8f36e7dc34165e0a90005579c72e9b07dc49d9f0b3e67cb6d371"}, + {file = "rosco-2.9.4-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6c12e9c3cb71a206e7b8bdb831abc2992ce78a90234a6d0958a77bb76a4ca777"}, + {file = "rosco-2.9.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8ac9d5a82aed59d5b9bb2793ed6730305f949f4a976f0bf021dfe315d657da42"}, + {file = "rosco-2.9.4-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:0709999e533a205dd507fd69f42612c4859f870854e9e78f8d04aa7b0183fb14"}, + {file = "rosco-2.9.4-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:39c56a06474f60eff2386b3db00a01486408e2269d9fd742c8f4d33ba8ed97b1"}, + {file = "rosco-2.9.4-cp39-cp39-win_amd64.whl", hash = "sha256:824e9bc190b5f4c815d73f62f49918bbe61954ff83ddf1a344aa2a5e733b32d4"}, + {file = "rosco-2.9.4.tar.gz", hash = "sha256:d100a782132a301ac495dfda49a3f00c5a183bd1f529ea2d211f49c8aef56fc9"}, ] [package.dependencies] @@ -2673,110 +2747,114 @@ test = ["pytest"] [[package]] name = "rpds-py" -version = "0.18.1" +version = "0.20.0" description = "Python bindings to Rust's persistent data structures (rpds)" optional = true python-versions = ">=3.8" files = [ - {file = "rpds_py-0.18.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:d31dea506d718693b6b2cffc0648a8929bdc51c70a311b2770f09611caa10d53"}, - {file = "rpds_py-0.18.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:732672fbc449bab754e0b15356c077cc31566df874964d4801ab14f71951ea80"}, - {file = "rpds_py-0.18.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4a98a1f0552b5f227a3d6422dbd61bc6f30db170939bd87ed14f3c339aa6c7c9"}, - {file = "rpds_py-0.18.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7f1944ce16401aad1e3f7d312247b3d5de7981f634dc9dfe90da72b87d37887d"}, - {file = "rpds_py-0.18.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:38e14fb4e370885c4ecd734f093a2225ee52dc384b86fa55fe3f74638b2cfb09"}, - {file = "rpds_py-0.18.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:08d74b184f9ab6289b87b19fe6a6d1a97fbfea84b8a3e745e87a5de3029bf944"}, - {file = "rpds_py-0.18.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d70129cef4a8d979caa37e7fe957202e7eee8ea02c5e16455bc9808a59c6b2f0"}, - {file = "rpds_py-0.18.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ce0bb20e3a11bd04461324a6a798af34d503f8d6f1aa3d2aa8901ceaf039176d"}, - {file = "rpds_py-0.18.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:81c5196a790032e0fc2464c0b4ab95f8610f96f1f2fa3d4deacce6a79852da60"}, - {file = "rpds_py-0.18.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:f3027be483868c99b4985fda802a57a67fdf30c5d9a50338d9db646d590198da"}, - {file = "rpds_py-0.18.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:d44607f98caa2961bab4fa3c4309724b185b464cdc3ba6f3d7340bac3ec97cc1"}, - {file = "rpds_py-0.18.1-cp310-none-win32.whl", hash = "sha256:c273e795e7a0f1fddd46e1e3cb8be15634c29ae8ff31c196debb620e1edb9333"}, - {file = "rpds_py-0.18.1-cp310-none-win_amd64.whl", hash = "sha256:8352f48d511de5f973e4f2f9412736d7dea76c69faa6d36bcf885b50c758ab9a"}, - {file = "rpds_py-0.18.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:6b5ff7e1d63a8281654b5e2896d7f08799378e594f09cf3674e832ecaf396ce8"}, - {file = "rpds_py-0.18.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8927638a4d4137a289e41d0fd631551e89fa346d6dbcfc31ad627557d03ceb6d"}, - {file = "rpds_py-0.18.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:154bf5c93d79558b44e5b50cc354aa0459e518e83677791e6adb0b039b7aa6a7"}, - {file = "rpds_py-0.18.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:07f2139741e5deb2c5154a7b9629bc5aa48c766b643c1a6750d16f865a82c5fc"}, - {file = "rpds_py-0.18.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8c7672e9fba7425f79019db9945b16e308ed8bc89348c23d955c8c0540da0a07"}, - {file = "rpds_py-0.18.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:489bdfe1abd0406eba6b3bb4fdc87c7fa40f1031de073d0cfb744634cc8fa261"}, - {file = "rpds_py-0.18.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3c20f05e8e3d4fc76875fc9cb8cf24b90a63f5a1b4c5b9273f0e8225e169b100"}, - {file = "rpds_py-0.18.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:967342e045564cef76dfcf1edb700b1e20838d83b1aa02ab313e6a497cf923b8"}, - {file = "rpds_py-0.18.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:2cc7c1a47f3a63282ab0f422d90ddac4aa3034e39fc66a559ab93041e6505da7"}, - {file = "rpds_py-0.18.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:f7afbfee1157e0f9376c00bb232e80a60e59ed716e3211a80cb8506550671e6e"}, - {file = "rpds_py-0.18.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9e6934d70dc50f9f8ea47081ceafdec09245fd9f6032669c3b45705dea096b88"}, - {file = "rpds_py-0.18.1-cp311-none-win32.whl", hash = "sha256:c69882964516dc143083d3795cb508e806b09fc3800fd0d4cddc1df6c36e76bb"}, - {file = "rpds_py-0.18.1-cp311-none-win_amd64.whl", hash = "sha256:70a838f7754483bcdc830444952fd89645569e7452e3226de4a613a4c1793fb2"}, - {file = "rpds_py-0.18.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:3dd3cd86e1db5aadd334e011eba4e29d37a104b403e8ca24dcd6703c68ca55b3"}, - {file = "rpds_py-0.18.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:05f3d615099bd9b13ecf2fc9cf2d839ad3f20239c678f461c753e93755d629ee"}, - {file = "rpds_py-0.18.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:35b2b771b13eee8729a5049c976197ff58a27a3829c018a04341bcf1ae409b2b"}, - {file = "rpds_py-0.18.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ee17cd26b97d537af8f33635ef38be873073d516fd425e80559f4585a7b90c43"}, - {file = "rpds_py-0.18.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b646bf655b135ccf4522ed43d6902af37d3f5dbcf0da66c769a2b3938b9d8184"}, - {file = "rpds_py-0.18.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:19ba472b9606c36716062c023afa2484d1e4220548751bda14f725a7de17b4f6"}, - {file = "rpds_py-0.18.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e30ac5e329098903262dc5bdd7e2086e0256aa762cc8b744f9e7bf2a427d3f8"}, - {file = "rpds_py-0.18.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d58ad6317d188c43750cb76e9deacf6051d0f884d87dc6518e0280438648a9ac"}, - {file = "rpds_py-0.18.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e1735502458621921cee039c47318cb90b51d532c2766593be6207eec53e5c4c"}, - {file = "rpds_py-0.18.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:f5bab211605d91db0e2995a17b5c6ee5edec1270e46223e513eaa20da20076ac"}, - {file = "rpds_py-0.18.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:2fc24a329a717f9e2448f8cd1f960f9dac4e45b6224d60734edeb67499bab03a"}, - {file = "rpds_py-0.18.1-cp312-none-win32.whl", hash = "sha256:1805d5901779662d599d0e2e4159d8a82c0b05faa86ef9222bf974572286b2b6"}, - {file = "rpds_py-0.18.1-cp312-none-win_amd64.whl", hash = "sha256:720edcb916df872d80f80a1cc5ea9058300b97721efda8651efcd938a9c70a72"}, - {file = "rpds_py-0.18.1-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:c827576e2fa017a081346dce87d532a5310241648eb3700af9a571a6e9fc7e74"}, - {file = "rpds_py-0.18.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:aa3679e751408d75a0b4d8d26d6647b6d9326f5e35c00a7ccd82b78ef64f65f8"}, - {file = "rpds_py-0.18.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0abeee75434e2ee2d142d650d1e54ac1f8b01e6e6abdde8ffd6eeac6e9c38e20"}, - {file = "rpds_py-0.18.1-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ed402d6153c5d519a0faf1bb69898e97fb31613b49da27a84a13935ea9164dfc"}, - {file = "rpds_py-0.18.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:338dee44b0cef8b70fd2ef54b4e09bb1b97fc6c3a58fea5db6cc083fd9fc2724"}, - {file = "rpds_py-0.18.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7750569d9526199c5b97e5a9f8d96a13300950d910cf04a861d96f4273d5b104"}, - {file = "rpds_py-0.18.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:607345bd5912aacc0c5a63d45a1f73fef29e697884f7e861094e443187c02be5"}, - {file = "rpds_py-0.18.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:207c82978115baa1fd8d706d720b4a4d2b0913df1c78c85ba73fe6c5804505f0"}, - {file = "rpds_py-0.18.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:6d1e42d2735d437e7e80bab4d78eb2e459af48c0a46e686ea35f690b93db792d"}, - {file = "rpds_py-0.18.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:5463c47c08630007dc0fe99fb480ea4f34a89712410592380425a9b4e1611d8e"}, - {file = "rpds_py-0.18.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:06d218939e1bf2ca50e6b0ec700ffe755e5216a8230ab3e87c059ebb4ea06afc"}, - {file = "rpds_py-0.18.1-cp38-none-win32.whl", hash = "sha256:312fe69b4fe1ffbe76520a7676b1e5ac06ddf7826d764cc10265c3b53f96dbe9"}, - {file = "rpds_py-0.18.1-cp38-none-win_amd64.whl", hash = "sha256:9437ca26784120a279f3137ee080b0e717012c42921eb07861b412340f85bae2"}, - {file = "rpds_py-0.18.1-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:19e515b78c3fc1039dd7da0a33c28c3154458f947f4dc198d3c72db2b6b5dc93"}, - {file = "rpds_py-0.18.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a7b28c5b066bca9a4eb4e2f2663012debe680f097979d880657f00e1c30875a0"}, - {file = "rpds_py-0.18.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:673fdbbf668dd958eff750e500495ef3f611e2ecc209464f661bc82e9838991e"}, - {file = "rpds_py-0.18.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d960de62227635d2e61068f42a6cb6aae91a7fe00fca0e3aeed17667c8a34611"}, - {file = "rpds_py-0.18.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:352a88dc7892f1da66b6027af06a2e7e5d53fe05924cc2cfc56495b586a10b72"}, - {file = "rpds_py-0.18.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4e0ee01ad8260184db21468a6e1c37afa0529acc12c3a697ee498d3c2c4dcaf3"}, - {file = "rpds_py-0.18.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4c39ad2f512b4041343ea3c7894339e4ca7839ac38ca83d68a832fc8b3748ab"}, - {file = "rpds_py-0.18.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:aaa71ee43a703c321906813bb252f69524f02aa05bf4eec85f0c41d5d62d0f4c"}, - {file = "rpds_py-0.18.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:6cd8098517c64a85e790657e7b1e509b9fe07487fd358e19431cb120f7d96338"}, - {file = "rpds_py-0.18.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:4adec039b8e2928983f885c53b7cc4cda8965b62b6596501a0308d2703f8af1b"}, - {file = "rpds_py-0.18.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:32b7daaa3e9389db3695964ce8e566e3413b0c43e3394c05e4b243a4cd7bef26"}, - {file = "rpds_py-0.18.1-cp39-none-win32.whl", hash = "sha256:2625f03b105328729f9450c8badda34d5243231eef6535f80064d57035738360"}, - {file = "rpds_py-0.18.1-cp39-none-win_amd64.whl", hash = "sha256:bf18932d0003c8c4d51a39f244231986ab23ee057d235a12b2684ea26a353590"}, - {file = "rpds_py-0.18.1-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:cbfbea39ba64f5e53ae2915de36f130588bba71245b418060ec3330ebf85678e"}, - {file = "rpds_py-0.18.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:a3d456ff2a6a4d2adcdf3c1c960a36f4fd2fec6e3b4902a42a384d17cf4e7a65"}, - {file = "rpds_py-0.18.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7700936ef9d006b7ef605dc53aa364da2de5a3aa65516a1f3ce73bf82ecfc7ae"}, - {file = "rpds_py-0.18.1-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:51584acc5916212e1bf45edd17f3a6b05fe0cbb40482d25e619f824dccb679de"}, - {file = "rpds_py-0.18.1-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:942695a206a58d2575033ff1e42b12b2aece98d6003c6bc739fbf33d1773b12f"}, - {file = "rpds_py-0.18.1-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b906b5f58892813e5ba5c6056d6a5ad08f358ba49f046d910ad992196ea61397"}, - {file = "rpds_py-0.18.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6f8e3fecca256fefc91bb6765a693d96692459d7d4c644660a9fff32e517843"}, - {file = "rpds_py-0.18.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:7732770412bab81c5a9f6d20aeb60ae943a9b36dcd990d876a773526468e7163"}, - {file = "rpds_py-0.18.1-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:bd1105b50ede37461c1d51b9698c4f4be6e13e69a908ab7751e3807985fc0346"}, - {file = "rpds_py-0.18.1-pp310-pypy310_pp73-musllinux_1_2_i686.whl", hash = "sha256:618916f5535784960f3ecf8111581f4ad31d347c3de66d02e728de460a46303c"}, - {file = "rpds_py-0.18.1-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:17c6d2155e2423f7e79e3bb18151c686d40db42d8645e7977442170c360194d4"}, - {file = "rpds_py-0.18.1-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:6c4c4c3f878df21faf5fac86eda32671c27889e13570645a9eea0a1abdd50922"}, - {file = "rpds_py-0.18.1-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:fab6ce90574645a0d6c58890e9bcaac8d94dff54fb51c69e5522a7358b80ab64"}, - {file = "rpds_py-0.18.1-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:531796fb842b53f2695e94dc338929e9f9dbf473b64710c28af5a160b2a8927d"}, - {file = "rpds_py-0.18.1-pp38-pypy38_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:740884bc62a5e2bbb31e584f5d23b32320fd75d79f916f15a788d527a5e83644"}, - {file = "rpds_py-0.18.1-pp38-pypy38_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:998125738de0158f088aef3cb264a34251908dd2e5d9966774fdab7402edfab7"}, - {file = "rpds_py-0.18.1-pp38-pypy38_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e2be6e9dd4111d5b31ba3b74d17da54a8319d8168890fbaea4b9e5c3de630ae5"}, - {file = "rpds_py-0.18.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d0cee71bc618cd93716f3c1bf56653740d2d13ddbd47673efa8bf41435a60daa"}, - {file = "rpds_py-0.18.1-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2c3caec4ec5cd1d18e5dd6ae5194d24ed12785212a90b37f5f7f06b8bedd7139"}, - {file = "rpds_py-0.18.1-pp38-pypy38_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:27bba383e8c5231cd559affe169ca0b96ec78d39909ffd817f28b166d7ddd4d8"}, - {file = "rpds_py-0.18.1-pp38-pypy38_pp73-musllinux_1_2_i686.whl", hash = "sha256:a888e8bdb45916234b99da2d859566f1e8a1d2275a801bb8e4a9644e3c7e7909"}, - {file = "rpds_py-0.18.1-pp38-pypy38_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:6031b25fb1b06327b43d841f33842b383beba399884f8228a6bb3df3088485ff"}, - {file = "rpds_py-0.18.1-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:48c2faaa8adfacefcbfdb5f2e2e7bdad081e5ace8d182e5f4ade971f128e6bb3"}, - {file = "rpds_py-0.18.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:d85164315bd68c0806768dc6bb0429c6f95c354f87485ee3593c4f6b14def2bd"}, - {file = "rpds_py-0.18.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6afd80f6c79893cfc0574956f78a0add8c76e3696f2d6a15bca2c66c415cf2d4"}, - {file = "rpds_py-0.18.1-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fa242ac1ff583e4ec7771141606aafc92b361cd90a05c30d93e343a0c2d82a89"}, - {file = "rpds_py-0.18.1-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d21be4770ff4e08698e1e8e0bce06edb6ea0626e7c8f560bc08222880aca6a6f"}, - {file = "rpds_py-0.18.1-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5c45a639e93a0c5d4b788b2613bd637468edd62f8f95ebc6fcc303d58ab3f0a8"}, - {file = "rpds_py-0.18.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:910e71711d1055b2768181efa0a17537b2622afeb0424116619817007f8a2b10"}, - {file = "rpds_py-0.18.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b9bb1f182a97880f6078283b3505a707057c42bf55d8fca604f70dedfdc0772a"}, - {file = "rpds_py-0.18.1-pp39-pypy39_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:1d54f74f40b1f7aaa595a02ff42ef38ca654b1469bef7d52867da474243cc633"}, - {file = "rpds_py-0.18.1-pp39-pypy39_pp73-musllinux_1_2_i686.whl", hash = "sha256:8d2e182c9ee01135e11e9676e9a62dfad791a7a467738f06726872374a83db49"}, - {file = "rpds_py-0.18.1-pp39-pypy39_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:636a15acc588f70fda1661234761f9ed9ad79ebed3f2125d44be0862708b666e"}, - {file = "rpds_py-0.18.1.tar.gz", hash = "sha256:dc48b479d540770c811fbd1eb9ba2bb66951863e448efec2e2c102625328e92f"}, + {file = "rpds_py-0.20.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:3ad0fda1635f8439cde85c700f964b23ed5fc2d28016b32b9ee5fe30da5c84e2"}, + {file = "rpds_py-0.20.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9bb4a0d90fdb03437c109a17eade42dfbf6190408f29b2744114d11586611d6f"}, + {file = "rpds_py-0.20.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c6377e647bbfd0a0b159fe557f2c6c602c159fc752fa316572f012fc0bf67150"}, + {file = "rpds_py-0.20.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:eb851b7df9dda52dc1415ebee12362047ce771fc36914586b2e9fcbd7d293b3e"}, + {file = "rpds_py-0.20.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1e0f80b739e5a8f54837be5d5c924483996b603d5502bfff79bf33da06164ee2"}, + {file = "rpds_py-0.20.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5a8c94dad2e45324fc74dce25e1645d4d14df9a4e54a30fa0ae8bad9a63928e3"}, + {file = "rpds_py-0.20.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8e604fe73ba048c06085beaf51147eaec7df856824bfe7b98657cf436623daf"}, + {file = "rpds_py-0.20.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:df3de6b7726b52966edf29663e57306b23ef775faf0ac01a3e9f4012a24a4140"}, + {file = "rpds_py-0.20.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:cf258ede5bc22a45c8e726b29835b9303c285ab46fc7c3a4cc770736b5304c9f"}, + {file = "rpds_py-0.20.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:55fea87029cded5df854ca7e192ec7bdb7ecd1d9a3f63d5c4eb09148acf4a7ce"}, + {file = "rpds_py-0.20.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:ae94bd0b2f02c28e199e9bc51485d0c5601f58780636185660f86bf80c89af94"}, + {file = "rpds_py-0.20.0-cp310-none-win32.whl", hash = "sha256:28527c685f237c05445efec62426d285e47a58fb05ba0090a4340b73ecda6dee"}, + {file = "rpds_py-0.20.0-cp310-none-win_amd64.whl", hash = "sha256:238a2d5b1cad28cdc6ed15faf93a998336eb041c4e440dd7f902528b8891b399"}, + {file = "rpds_py-0.20.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:ac2f4f7a98934c2ed6505aead07b979e6f999389f16b714448fb39bbaa86a489"}, + {file = "rpds_py-0.20.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:220002c1b846db9afd83371d08d239fdc865e8f8c5795bbaec20916a76db3318"}, + {file = "rpds_py-0.20.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8d7919548df3f25374a1f5d01fbcd38dacab338ef5f33e044744b5c36729c8db"}, + {file = "rpds_py-0.20.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:758406267907b3781beee0f0edfe4a179fbd97c0be2e9b1154d7f0a1279cf8e5"}, + {file = "rpds_py-0.20.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3d61339e9f84a3f0767b1995adfb171a0d00a1185192718a17af6e124728e0f5"}, + {file = "rpds_py-0.20.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1259c7b3705ac0a0bd38197565a5d603218591d3f6cee6e614e380b6ba61c6f6"}, + {file = "rpds_py-0.20.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5c1dc0f53856b9cc9a0ccca0a7cc61d3d20a7088201c0937f3f4048c1718a209"}, + {file = "rpds_py-0.20.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:7e60cb630f674a31f0368ed32b2a6b4331b8350d67de53c0359992444b116dd3"}, + {file = "rpds_py-0.20.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:dbe982f38565bb50cb7fb061ebf762c2f254ca3d8c20d4006878766e84266272"}, + {file = "rpds_py-0.20.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:514b3293b64187172bc77c8fb0cdae26981618021053b30d8371c3a902d4d5ad"}, + {file = "rpds_py-0.20.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:d0a26ffe9d4dd35e4dfdd1e71f46401cff0181c75ac174711ccff0459135fa58"}, + {file = "rpds_py-0.20.0-cp311-none-win32.whl", hash = "sha256:89c19a494bf3ad08c1da49445cc5d13d8fefc265f48ee7e7556839acdacf69d0"}, + {file = "rpds_py-0.20.0-cp311-none-win_amd64.whl", hash = "sha256:c638144ce971df84650d3ed0096e2ae7af8e62ecbbb7b201c8935c370df00a2c"}, + {file = "rpds_py-0.20.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:a84ab91cbe7aab97f7446652d0ed37d35b68a465aeef8fc41932a9d7eee2c1a6"}, + {file = "rpds_py-0.20.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:56e27147a5a4c2c21633ff8475d185734c0e4befd1c989b5b95a5d0db699b21b"}, + {file = "rpds_py-0.20.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2580b0c34583b85efec8c5c5ec9edf2dfe817330cc882ee972ae650e7b5ef739"}, + {file = "rpds_py-0.20.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b80d4a7900cf6b66bb9cee5c352b2d708e29e5a37fe9bf784fa97fc11504bf6c"}, + {file = "rpds_py-0.20.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:50eccbf054e62a7b2209b28dc7a22d6254860209d6753e6b78cfaeb0075d7bee"}, + {file = "rpds_py-0.20.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:49a8063ea4296b3a7e81a5dfb8f7b2d73f0b1c20c2af401fb0cdf22e14711a96"}, + {file = "rpds_py-0.20.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ea438162a9fcbee3ecf36c23e6c68237479f89f962f82dae83dc15feeceb37e4"}, + {file = "rpds_py-0.20.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:18d7585c463087bddcfa74c2ba267339f14f2515158ac4db30b1f9cbdb62c8ef"}, + {file = "rpds_py-0.20.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d4c7d1a051eeb39f5c9547e82ea27cbcc28338482242e3e0b7768033cb083821"}, + {file = "rpds_py-0.20.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:e4df1e3b3bec320790f699890d41c59d250f6beda159ea3c44c3f5bac1976940"}, + {file = "rpds_py-0.20.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:2cf126d33a91ee6eedc7f3197b53e87a2acdac63602c0f03a02dd69e4b138174"}, + {file = "rpds_py-0.20.0-cp312-none-win32.whl", hash = "sha256:8bc7690f7caee50b04a79bf017a8d020c1f48c2a1077ffe172abec59870f1139"}, + {file = "rpds_py-0.20.0-cp312-none-win_amd64.whl", hash = "sha256:0e13e6952ef264c40587d510ad676a988df19adea20444c2b295e536457bc585"}, + {file = "rpds_py-0.20.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:aa9a0521aeca7d4941499a73ad7d4f8ffa3d1affc50b9ea11d992cd7eff18a29"}, + {file = "rpds_py-0.20.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:4a1f1d51eccb7e6c32ae89243cb352389228ea62f89cd80823ea7dd1b98e0b91"}, + {file = "rpds_py-0.20.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8a86a9b96070674fc88b6f9f71a97d2c1d3e5165574615d1f9168ecba4cecb24"}, + {file = "rpds_py-0.20.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6c8ef2ebf76df43f5750b46851ed1cdf8f109d7787ca40035fe19fbdc1acc5a7"}, + {file = "rpds_py-0.20.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b74b25f024b421d5859d156750ea9a65651793d51b76a2e9238c05c9d5f203a9"}, + {file = "rpds_py-0.20.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:57eb94a8c16ab08fef6404301c38318e2c5a32216bf5de453e2714c964c125c8"}, + {file = "rpds_py-0.20.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e1940dae14e715e2e02dfd5b0f64a52e8374a517a1e531ad9412319dc3ac7879"}, + {file = "rpds_py-0.20.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d20277fd62e1b992a50c43f13fbe13277a31f8c9f70d59759c88f644d66c619f"}, + {file = "rpds_py-0.20.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:06db23d43f26478303e954c34c75182356ca9aa7797d22c5345b16871ab9c45c"}, + {file = "rpds_py-0.20.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:b2a5db5397d82fa847e4c624b0c98fe59d2d9b7cf0ce6de09e4d2e80f8f5b3f2"}, + {file = "rpds_py-0.20.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5a35df9f5548fd79cb2f52d27182108c3e6641a4feb0f39067911bf2adaa3e57"}, + {file = "rpds_py-0.20.0-cp313-none-win32.whl", hash = "sha256:fd2d84f40633bc475ef2d5490b9c19543fbf18596dcb1b291e3a12ea5d722f7a"}, + {file = "rpds_py-0.20.0-cp313-none-win_amd64.whl", hash = "sha256:9bc2d153989e3216b0559251b0c260cfd168ec78b1fac33dd485750a228db5a2"}, + {file = "rpds_py-0.20.0-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:f2fbf7db2012d4876fb0d66b5b9ba6591197b0f165db8d99371d976546472a24"}, + {file = "rpds_py-0.20.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:1e5f3cd7397c8f86c8cc72d5a791071431c108edd79872cdd96e00abd8497d29"}, + {file = "rpds_py-0.20.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ce9845054c13696f7af7f2b353e6b4f676dab1b4b215d7fe5e05c6f8bb06f965"}, + {file = "rpds_py-0.20.0-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c3e130fd0ec56cb76eb49ef52faead8ff09d13f4527e9b0c400307ff72b408e1"}, + {file = "rpds_py-0.20.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4b16aa0107ecb512b568244ef461f27697164d9a68d8b35090e9b0c1c8b27752"}, + {file = "rpds_py-0.20.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:aa7f429242aae2947246587d2964fad750b79e8c233a2367f71b554e9447949c"}, + {file = "rpds_py-0.20.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:af0fc424a5842a11e28956e69395fbbeab2c97c42253169d87e90aac2886d751"}, + {file = "rpds_py-0.20.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b8c00a3b1e70c1d3891f0db1b05292747f0dbcfb49c43f9244d04c70fbc40eb8"}, + {file = "rpds_py-0.20.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:40ce74fc86ee4645d0a225498d091d8bc61f39b709ebef8204cb8b5a464d3c0e"}, + {file = "rpds_py-0.20.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:4fe84294c7019456e56d93e8ababdad5a329cd25975be749c3f5f558abb48253"}, + {file = "rpds_py-0.20.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:338ca4539aad4ce70a656e5187a3a31c5204f261aef9f6ab50e50bcdffaf050a"}, + {file = "rpds_py-0.20.0-cp38-none-win32.whl", hash = "sha256:54b43a2b07db18314669092bb2de584524d1ef414588780261e31e85846c26a5"}, + {file = "rpds_py-0.20.0-cp38-none-win_amd64.whl", hash = "sha256:a1862d2d7ce1674cffa6d186d53ca95c6e17ed2b06b3f4c476173565c862d232"}, + {file = "rpds_py-0.20.0-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:3fde368e9140312b6e8b6c09fb9f8c8c2f00999d1823403ae90cc00480221b22"}, + {file = "rpds_py-0.20.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9824fb430c9cf9af743cf7aaf6707bf14323fb51ee74425c380f4c846ea70789"}, + {file = "rpds_py-0.20.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:11ef6ce74616342888b69878d45e9f779b95d4bd48b382a229fe624a409b72c5"}, + {file = "rpds_py-0.20.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c52d3f2f82b763a24ef52f5d24358553e8403ce05f893b5347098014f2d9eff2"}, + {file = "rpds_py-0.20.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9d35cef91e59ebbeaa45214861874bc6f19eb35de96db73e467a8358d701a96c"}, + {file = "rpds_py-0.20.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d72278a30111e5b5525c1dd96120d9e958464316f55adb030433ea905866f4de"}, + {file = "rpds_py-0.20.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b4c29cbbba378759ac5786730d1c3cb4ec6f8ababf5c42a9ce303dc4b3d08cda"}, + {file = "rpds_py-0.20.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6632f2d04f15d1bd6fe0eedd3b86d9061b836ddca4c03d5cf5c7e9e6b7c14580"}, + {file = "rpds_py-0.20.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:d0b67d87bb45ed1cd020e8fbf2307d449b68abc45402fe1a4ac9e46c3c8b192b"}, + {file = "rpds_py-0.20.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:ec31a99ca63bf3cd7f1a5ac9fe95c5e2d060d3c768a09bc1d16e235840861420"}, + {file = "rpds_py-0.20.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:22e6c9976e38f4d8c4a63bd8a8edac5307dffd3ee7e6026d97f3cc3a2dc02a0b"}, + {file = "rpds_py-0.20.0-cp39-none-win32.whl", hash = "sha256:569b3ea770c2717b730b61998b6c54996adee3cef69fc28d444f3e7920313cf7"}, + {file = "rpds_py-0.20.0-cp39-none-win_amd64.whl", hash = "sha256:e6900ecdd50ce0facf703f7a00df12374b74bbc8ad9fe0f6559947fb20f82364"}, + {file = "rpds_py-0.20.0-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:617c7357272c67696fd052811e352ac54ed1d9b49ab370261a80d3b6ce385045"}, + {file = "rpds_py-0.20.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:9426133526f69fcaba6e42146b4e12d6bc6c839b8b555097020e2b78ce908dcc"}, + {file = "rpds_py-0.20.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:deb62214c42a261cb3eb04d474f7155279c1a8a8c30ac89b7dcb1721d92c3c02"}, + {file = "rpds_py-0.20.0-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fcaeb7b57f1a1e071ebd748984359fef83ecb026325b9d4ca847c95bc7311c92"}, + {file = "rpds_py-0.20.0-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d454b8749b4bd70dd0a79f428731ee263fa6995f83ccb8bada706e8d1d3ff89d"}, + {file = "rpds_py-0.20.0-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d807dc2051abe041b6649681dce568f8e10668e3c1c6543ebae58f2d7e617855"}, + {file = "rpds_py-0.20.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c3c20f0ddeb6e29126d45f89206b8291352b8c5b44384e78a6499d68b52ae511"}, + {file = "rpds_py-0.20.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b7f19250ceef892adf27f0399b9e5afad019288e9be756d6919cb58892129f51"}, + {file = "rpds_py-0.20.0-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:4f1ed4749a08379555cebf4650453f14452eaa9c43d0a95c49db50c18b7da075"}, + {file = "rpds_py-0.20.0-pp310-pypy310_pp73-musllinux_1_2_i686.whl", hash = "sha256:dcedf0b42bcb4cfff4101d7771a10532415a6106062f005ab97d1d0ab5681c60"}, + {file = "rpds_py-0.20.0-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:39ed0d010457a78f54090fafb5d108501b5aa5604cc22408fc1c0c77eac14344"}, + {file = "rpds_py-0.20.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:bb273176be34a746bdac0b0d7e4e2c467323d13640b736c4c477881a3220a989"}, + {file = "rpds_py-0.20.0-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:f918a1a130a6dfe1d7fe0f105064141342e7dd1611f2e6a21cd2f5c8cb1cfb3e"}, + {file = "rpds_py-0.20.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:f60012a73aa396be721558caa3a6fd49b3dd0033d1675c6d59c4502e870fcf0c"}, + {file = "rpds_py-0.20.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3d2b1ad682a3dfda2a4e8ad8572f3100f95fad98cb99faf37ff0ddfe9cbf9d03"}, + {file = "rpds_py-0.20.0-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:614fdafe9f5f19c63ea02817fa4861c606a59a604a77c8cdef5aa01d28b97921"}, + {file = "rpds_py-0.20.0-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fa518bcd7600c584bf42e6617ee8132869e877db2f76bcdc281ec6a4113a53ab"}, + {file = "rpds_py-0.20.0-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f0475242f447cc6cb8a9dd486d68b2ef7fbee84427124c232bff5f63b1fe11e5"}, + {file = "rpds_py-0.20.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f90a4cd061914a60bd51c68bcb4357086991bd0bb93d8aa66a6da7701370708f"}, + {file = "rpds_py-0.20.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:def7400461c3a3f26e49078302e1c1b38f6752342c77e3cf72ce91ca69fb1bc1"}, + {file = "rpds_py-0.20.0-pp39-pypy39_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:65794e4048ee837494aea3c21a28ad5fc080994dfba5b036cf84de37f7ad5074"}, + {file = "rpds_py-0.20.0-pp39-pypy39_pp73-musllinux_1_2_i686.whl", hash = "sha256:faefcc78f53a88f3076b7f8be0a8f8d35133a3ecf7f3770895c25f8813460f08"}, + {file = "rpds_py-0.20.0-pp39-pypy39_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:5b4f105deeffa28bbcdff6c49b34e74903139afa690e35d2d9e3c2c2fba18cec"}, + {file = "rpds_py-0.20.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:fdfc3a892927458d98f3d55428ae46b921d1f7543b89382fdb483f5640daaec8"}, + {file = "rpds_py-0.20.0.tar.gz", hash = "sha256:d72a210824facfdaf8768cf2d7ca25a042c30320b3020de2fa04640920d4e121"}, ] [[package]] @@ -2858,36 +2936,36 @@ files = [ [[package]] name = "scipy" -version = "1.13.0" +version = "1.13.1" description = "Fundamental algorithms for scientific computing in Python" optional = true python-versions = ">=3.9" files = [ - {file = "scipy-1.13.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ba419578ab343a4e0a77c0ef82f088238a93eef141b2b8017e46149776dfad4d"}, - {file = "scipy-1.13.0-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:22789b56a999265431c417d462e5b7f2b487e831ca7bef5edeb56efe4c93f86e"}, - {file = "scipy-1.13.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:05f1432ba070e90d42d7fd836462c50bf98bd08bed0aa616c359eed8a04e3922"}, - {file = "scipy-1.13.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b8434f6f3fa49f631fae84afee424e2483289dfc30a47755b4b4e6b07b2633a4"}, - {file = "scipy-1.13.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:dcbb9ea49b0167de4167c40eeee6e167caeef11effb0670b554d10b1e693a8b9"}, - {file = "scipy-1.13.0-cp310-cp310-win_amd64.whl", hash = "sha256:1d2f7bb14c178f8b13ebae93f67e42b0a6b0fc50eba1cd8021c9b6e08e8fb1cd"}, - {file = "scipy-1.13.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:0fbcf8abaf5aa2dc8d6400566c1a727aed338b5fe880cde64907596a89d576fa"}, - {file = "scipy-1.13.0-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:5e4a756355522eb60fcd61f8372ac2549073c8788f6114449b37e9e8104f15a5"}, - {file = "scipy-1.13.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b5acd8e1dbd8dbe38d0004b1497019b2dbbc3d70691e65d69615f8a7292865d7"}, - {file = "scipy-1.13.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9ff7dad5d24a8045d836671e082a490848e8639cabb3dbdacb29f943a678683d"}, - {file = "scipy-1.13.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:4dca18c3ffee287ddd3bc8f1dabaf45f5305c5afc9f8ab9cbfab855e70b2df5c"}, - {file = "scipy-1.13.0-cp311-cp311-win_amd64.whl", hash = "sha256:a2f471de4d01200718b2b8927f7d76b5d9bde18047ea0fa8bd15c5ba3f26a1d6"}, - {file = "scipy-1.13.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d0de696f589681c2802f9090fff730c218f7c51ff49bf252b6a97ec4a5d19e8b"}, - {file = "scipy-1.13.0-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:b2a3ff461ec4756b7e8e42e1c681077349a038f0686132d623fa404c0bee2551"}, - {file = "scipy-1.13.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6bf9fe63e7a4bf01d3645b13ff2aa6dea023d38993f42aaac81a18b1bda7a82a"}, - {file = "scipy-1.13.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1e7626dfd91cdea5714f343ce1176b6c4745155d234f1033584154f60ef1ff42"}, - {file = "scipy-1.13.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:109d391d720fcebf2fbe008621952b08e52907cf4c8c7efc7376822151820820"}, - {file = "scipy-1.13.0-cp312-cp312-win_amd64.whl", hash = "sha256:8930ae3ea371d6b91c203b1032b9600d69c568e537b7988a3073dfe4d4774f21"}, - {file = "scipy-1.13.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5407708195cb38d70fd2d6bb04b1b9dd5c92297d86e9f9daae1576bd9e06f602"}, - {file = "scipy-1.13.0-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:ac38c4c92951ac0f729c4c48c9e13eb3675d9986cc0c83943784d7390d540c78"}, - {file = "scipy-1.13.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:09c74543c4fbeb67af6ce457f6a6a28e5d3739a87f62412e4a16e46f164f0ae5"}, - {file = "scipy-1.13.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:28e286bf9ac422d6beb559bc61312c348ca9b0f0dae0d7c5afde7f722d6ea13d"}, - {file = "scipy-1.13.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:33fde20efc380bd23a78a4d26d59fc8704e9b5fd9b08841693eb46716ba13d86"}, - {file = "scipy-1.13.0-cp39-cp39-win_amd64.whl", hash = "sha256:45c08bec71d3546d606989ba6e7daa6f0992918171e2a6f7fbedfa7361c2de1e"}, - {file = "scipy-1.13.0.tar.gz", hash = "sha256:58569af537ea29d3f78e5abd18398459f195546bb3be23d16677fb26616cc11e"}, + {file = "scipy-1.13.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:20335853b85e9a49ff7572ab453794298bcf0354d8068c5f6775a0eabf350aca"}, + {file = "scipy-1.13.1-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:d605e9c23906d1994f55ace80e0125c587f96c020037ea6aa98d01b4bd2e222f"}, + {file = "scipy-1.13.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cfa31f1def5c819b19ecc3a8b52d28ffdcc7ed52bb20c9a7589669dd3c250989"}, + {file = "scipy-1.13.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f26264b282b9da0952a024ae34710c2aff7d27480ee91a2e82b7b7073c24722f"}, + {file = "scipy-1.13.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:eccfa1906eacc02de42d70ef4aecea45415f5be17e72b61bafcfd329bdc52e94"}, + {file = "scipy-1.13.1-cp310-cp310-win_amd64.whl", hash = "sha256:2831f0dc9c5ea9edd6e51e6e769b655f08ec6db6e2e10f86ef39bd32eb11da54"}, + {file = "scipy-1.13.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:27e52b09c0d3a1d5b63e1105f24177e544a222b43611aaf5bc44d4a0979e32f9"}, + {file = "scipy-1.13.1-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:54f430b00f0133e2224c3ba42b805bfd0086fe488835effa33fa291561932326"}, + {file = "scipy-1.13.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e89369d27f9e7b0884ae559a3a956e77c02114cc60a6058b4e5011572eea9299"}, + {file = "scipy-1.13.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a78b4b3345f1b6f68a763c6e25c0c9a23a9fd0f39f5f3d200efe8feda560a5fa"}, + {file = "scipy-1.13.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:45484bee6d65633752c490404513b9ef02475b4284c4cfab0ef946def50b3f59"}, + {file = "scipy-1.13.1-cp311-cp311-win_amd64.whl", hash = "sha256:5713f62f781eebd8d597eb3f88b8bf9274e79eeabf63afb4a737abc6c84ad37b"}, + {file = "scipy-1.13.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5d72782f39716b2b3509cd7c33cdc08c96f2f4d2b06d51e52fb45a19ca0c86a1"}, + {file = "scipy-1.13.1-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:017367484ce5498445aade74b1d5ab377acdc65e27095155e448c88497755a5d"}, + {file = "scipy-1.13.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:949ae67db5fa78a86e8fa644b9a6b07252f449dcf74247108c50e1d20d2b4627"}, + {file = "scipy-1.13.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:de3ade0e53bc1f21358aa74ff4830235d716211d7d077e340c7349bc3542e884"}, + {file = "scipy-1.13.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:2ac65fb503dad64218c228e2dc2d0a0193f7904747db43014645ae139c8fad16"}, + {file = "scipy-1.13.1-cp312-cp312-win_amd64.whl", hash = "sha256:cdd7dacfb95fea358916410ec61bbc20440f7860333aee6d882bb8046264e949"}, + {file = "scipy-1.13.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:436bbb42a94a8aeef855d755ce5a465479c721e9d684de76bf61a62e7c2b81d5"}, + {file = "scipy-1.13.1-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:8335549ebbca860c52bf3d02f80784e91a004b71b059e3eea9678ba994796a24"}, + {file = "scipy-1.13.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d533654b7d221a6a97304ab63c41c96473ff04459e404b83275b60aa8f4b7004"}, + {file = "scipy-1.13.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:637e98dcf185ba7f8e663e122ebf908c4702420477ae52a04f9908707456ba4d"}, + {file = "scipy-1.13.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a014c2b3697bde71724244f63de2476925596c24285c7a637364761f8710891c"}, + {file = "scipy-1.13.1-cp39-cp39-win_amd64.whl", hash = "sha256:392e4ec766654852c25ebad4f64e4e584cf19820b980bc04960bca0b0cd6eaa2"}, + {file = "scipy-1.13.1.tar.gz", hash = "sha256:095a87a0312b08dfd6a6155cbbd310a8c51800fc931b8c0b84003014b874ed3c"}, ] [package.dependencies] @@ -2914,6 +2992,22 @@ nativelib = ["pyobjc-framework-Cocoa", "pywin32"] objc = ["pyobjc-framework-Cocoa"] win32 = ["pywin32"] +[[package]] +name = "setuptools" +version = "72.2.0" +description = "Easily download, build, install, upgrade, and uninstall Python packages" +optional = true +python-versions = ">=3.8" +files = [ + {file = "setuptools-72.2.0-py3-none-any.whl", hash = "sha256:f11dd94b7bae3a156a95ec151f24e4637fb4fa19c878e4d191bfb8b2d82728c4"}, + {file = "setuptools-72.2.0.tar.gz", hash = "sha256:80aacbf633704e9c8bfa1d99fa5dd4dc59573efcf9e4042c13d3bcef91ac2ef9"}, +] + +[package.extras] +core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.text (>=3.7)", "more-itertools (>=8.8)", "ordered-set (>=3.1.1)", "packaging (>=24)", "platformdirs (>=2.6.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] +doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "mypy (==1.11.*)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy", "pytest-perf", "pytest-ruff (<0.4)", "pytest-ruff (>=0.2.1)", "pytest-ruff (>=0.3.2)", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] + [[package]] name = "simpy" version = "4.1.1" @@ -2960,13 +3054,13 @@ files = [ [[package]] name = "soupsieve" -version = "2.5" +version = "2.6" description = "A modern CSS selector implementation for Beautiful Soup." optional = true python-versions = ">=3.8" files = [ - {file = "soupsieve-2.5-py3-none-any.whl", hash = "sha256:eaa337ff55a1579b6549dc679565eac1e3d000563bcb1c8ab0d0fefbc0c2cdc7"}, - {file = "soupsieve-2.5.tar.gz", hash = "sha256:5663d5a7b3bfaeee0bc4372e7fc48f9cff4940b3eec54a6451cc5299f1097690"}, + {file = "soupsieve-2.6-py3-none-any.whl", hash = "sha256:e72c4ff06e4fb6e4b5a9f0f55fe6e81514581fca1515028625d0f299c602ccc9"}, + {file = "soupsieve-2.6.tar.gz", hash = "sha256:e2e68417777af359ec65daac1057404a3c8a5455bb8abc36f1a9866ab1a51abb"}, ] [[package]] @@ -3096,22 +3190,22 @@ files = [ [[package]] name = "tornado" -version = "6.4" +version = "6.4.1" description = "Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed." optional = true -python-versions = ">= 3.8" +python-versions = ">=3.8" files = [ - {file = "tornado-6.4-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:02ccefc7d8211e5a7f9e8bc3f9e5b0ad6262ba2fbb683a6443ecc804e5224ce0"}, - {file = "tornado-6.4-cp38-abi3-macosx_10_9_x86_64.whl", hash = "sha256:27787de946a9cffd63ce5814c33f734c627a87072ec7eed71f7fc4417bb16263"}, - {file = "tornado-6.4-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f7894c581ecdcf91666a0912f18ce5e757213999e183ebfc2c3fdbf4d5bd764e"}, - {file = "tornado-6.4-cp38-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e43bc2e5370a6a8e413e1e1cd0c91bedc5bd62a74a532371042a18ef19e10579"}, - {file = "tornado-6.4-cp38-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f0251554cdd50b4b44362f73ad5ba7126fc5b2c2895cc62b14a1c2d7ea32f212"}, - {file = "tornado-6.4-cp38-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:fd03192e287fbd0899dd8f81c6fb9cbbc69194d2074b38f384cb6fa72b80e9c2"}, - {file = "tornado-6.4-cp38-abi3-musllinux_1_1_i686.whl", hash = "sha256:88b84956273fbd73420e6d4b8d5ccbe913c65d31351b4c004ae362eba06e1f78"}, - {file = "tornado-6.4-cp38-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:71ddfc23a0e03ef2df1c1397d859868d158c8276a0603b96cf86892bff58149f"}, - {file = "tornado-6.4-cp38-abi3-win32.whl", hash = "sha256:6f8a6c77900f5ae93d8b4ae1196472d0ccc2775cc1dfdc9e7727889145c45052"}, - {file = "tornado-6.4-cp38-abi3-win_amd64.whl", hash = "sha256:10aeaa8006333433da48dec9fe417877f8bcc21f48dda8d661ae79da357b2a63"}, - {file = "tornado-6.4.tar.gz", hash = "sha256:72291fa6e6bc84e626589f1c29d90a5a6d593ef5ae68052ee2ef000dfd273dee"}, + {file = "tornado-6.4.1-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:163b0aafc8e23d8cdc3c9dfb24c5368af84a81e3364745ccb4427669bf84aec8"}, + {file = "tornado-6.4.1-cp38-abi3-macosx_10_9_x86_64.whl", hash = "sha256:6d5ce3437e18a2b66fbadb183c1d3364fb03f2be71299e7d10dbeeb69f4b2a14"}, + {file = "tornado-6.4.1-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e2e20b9113cd7293f164dc46fffb13535266e713cdb87bd2d15ddb336e96cfc4"}, + {file = "tornado-6.4.1-cp38-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8ae50a504a740365267b2a8d1a90c9fbc86b780a39170feca9bcc1787ff80842"}, + {file = "tornado-6.4.1-cp38-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:613bf4ddf5c7a95509218b149b555621497a6cc0d46ac341b30bd9ec19eac7f3"}, + {file = "tornado-6.4.1-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:25486eb223babe3eed4b8aecbac33b37e3dd6d776bc730ca14e1bf93888b979f"}, + {file = "tornado-6.4.1-cp38-abi3-musllinux_1_2_i686.whl", hash = "sha256:454db8a7ecfcf2ff6042dde58404164d969b6f5d58b926da15e6b23817950fc4"}, + {file = "tornado-6.4.1-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:a02a08cc7a9314b006f653ce40483b9b3c12cda222d6a46d4ac63bb6c9057698"}, + {file = "tornado-6.4.1-cp38-abi3-win32.whl", hash = "sha256:d9a566c40b89757c9aa8e6f032bcdb8ca8795d7c1a9762910c722b1635c9de4d"}, + {file = "tornado-6.4.1-cp38-abi3-win_amd64.whl", hash = "sha256:b24b8982ed444378d7f21d563f4180a2de31ced9d8d84443907a0a64da2072e7"}, + {file = "tornado-6.4.1.tar.gz", hash = "sha256:92d3ab53183d8c50f8204a51e6f91d18a15d5ef261e84d452800d4ff6fc504e9"}, ] [[package]] @@ -3159,13 +3253,13 @@ files = [ [[package]] name = "typing-extensions" -version = "4.11.0" +version = "4.12.2" description = "Backported and Experimental Type Hints for Python 3.8+" optional = true python-versions = ">=3.8" files = [ - {file = "typing_extensions-4.11.0-py3-none-any.whl", hash = "sha256:c1f94d72897edaf4ce775bb7558d5b79d8126906a14ea5ed1635921406c0387a"}, - {file = "typing_extensions-4.11.0.tar.gz", hash = "sha256:83f085bd5ca59c80295fc2a82ab5dac679cbe02b9f33f7d83af68e241bea51b0"}, + {file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"}, + {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, ] [[package]] @@ -3195,13 +3289,13 @@ dev = ["flake8", "flake8-annotations", "flake8-bandit", "flake8-bugbear", "flake [[package]] name = "urllib3" -version = "2.2.1" +version = "2.2.2" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = true python-versions = ">=3.8" files = [ - {file = "urllib3-2.2.1-py3-none-any.whl", hash = "sha256:450b20ec296a467077128bff42b73080516e71b56ff59a60a02bef2232c4fa9d"}, - {file = "urllib3-2.2.1.tar.gz", hash = "sha256:d0570876c61ab9e520d776c38acbbb5b05a776d3f9ff98a5c8fd5162a444cf19"}, + {file = "urllib3-2.2.2-py3-none-any.whl", hash = "sha256:a448b2f64d686155468037e1ace9f2d2199776e17f0a46610480d311f73e3472"}, + {file = "urllib3-2.2.2.tar.gz", hash = "sha256:dd505485549a7a552833da5e6063639d0d177c04f23bc3864e41e5dc5f612168"}, ] [package.extras] @@ -3223,18 +3317,18 @@ files = [ [[package]] name = "webcolors" -version = "1.13" +version = "24.8.0" description = "A library for working with the color formats defined by HTML and CSS." optional = true -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "webcolors-1.13-py3-none-any.whl", hash = "sha256:29bc7e8752c0a1bd4a1f03c14d6e6a72e93d82193738fa860cbff59d0fcc11bf"}, - {file = "webcolors-1.13.tar.gz", hash = "sha256:c225b674c83fa923be93d235330ce0300373d02885cef23238813b0d5668304a"}, + {file = "webcolors-24.8.0-py3-none-any.whl", hash = "sha256:fc4c3b59358ada164552084a8ebee637c221e4059267d0f8325b3b560f6c7f0a"}, + {file = "webcolors-24.8.0.tar.gz", hash = "sha256:08b07af286a01bcd30d583a7acadf629583d1f79bfef27dd2c2c5c263817277d"}, ] [package.extras] docs = ["furo", "sphinx", "sphinx-copybutton", "sphinx-inline-tabs", "sphinx-notfound-page", "sphinxext-opengraph"] -tests = ["pytest", "pytest-cov"] +tests = ["coverage[toml]"] [[package]] name = "webencodings" @@ -3265,51 +3359,63 @@ test = ["websockets"] [[package]] name = "widgetsnbextension" -version = "4.0.10" +version = "4.0.11" description = "Jupyter interactive widgets for Jupyter Notebook" optional = true python-versions = ">=3.7" files = [ - {file = "widgetsnbextension-4.0.10-py3-none-any.whl", hash = "sha256:d37c3724ec32d8c48400a435ecfa7d3e259995201fbefa37163124a9fcb393cc"}, - {file = "widgetsnbextension-4.0.10.tar.gz", hash = "sha256:64196c5ff3b9a9183a8e699a4227fb0b7002f252c814098e66c4d1cd0644688f"}, + {file = "widgetsnbextension-4.0.11-py3-none-any.whl", hash = "sha256:55d4d6949d100e0d08b94948a42efc3ed6dfdc0e9468b2c4b128c9a2ce3a7a36"}, + {file = "widgetsnbextension-4.0.11.tar.gz", hash = "sha256:8b22a8f1910bfd188e596fe7fc05dcbd87e810c8a4ba010bdb3da86637398474"}, ] [[package]] name = "wisdem" -version = "3.15.3" +version = "3.16.4" description = "Wind-Plant Integrated System Design & Engineering Model" optional = true python-versions = ">=3.9" files = [ - {file = "wisdem-3.15.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:47ed687a46ea7a09eca81083854d79211a809711778510a357e5be6f38eb664a"}, - {file = "wisdem-3.15.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:877b5cdf8dfec86adcf86cfea5abafed20a805fcde29e0e0d917aa94781bb6a8"}, - {file = "wisdem-3.15.3-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dc1c5bb437723b288eb3abe1e2d5de8cb9bac7df0522ece4516e2cf45ab24813"}, - {file = "wisdem-3.15.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a077b93ae2c13c83411a03060e5e075ac48f65b77c0932f7b3f88a1d87ef247b"}, - {file = "wisdem-3.15.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:d9d7a592235e3602299780bb2460cc44a50a6cd8df51d5fa64dc5e3f43434a9c"}, - {file = "wisdem-3.15.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:17ba3ef0861f75eefc3d7a0fb3e7ad61dd0b0246346b7e80f73cd330bad20bd0"}, - {file = "wisdem-3.15.3-cp310-cp310-win_amd64.whl", hash = "sha256:6f8da3bb1ea4681f0ca339d78b5718b1ec2ba53b248e4e1a169265ef033c01a1"}, - {file = "wisdem-3.15.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4187c2bb072c306c693153fccf481de3b4666a96b933b10c77222946c34603fc"}, - {file = "wisdem-3.15.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:15822097ff53bffe18e1bf9fb6479ad709cfca3e18f58ba1240d350082166163"}, - {file = "wisdem-3.15.3-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8e59a40df0672799818cce199f6006ac1bda2e78e7be2b13061893179a6f3cbc"}, - {file = "wisdem-3.15.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac5862cf972a5086bc3774f0f6fb5890421909eddee9947b930a1ef4db859076"}, - {file = "wisdem-3.15.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:b9d64f8aaddf0c0fca9160fb53111935b85ff49a9fe937f50e4214d85a3bc12c"}, - {file = "wisdem-3.15.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:a40ea5b12206e42771915e22d317de7627ab44a238db0161fd7cf11653f0ee10"}, - {file = "wisdem-3.15.3-cp311-cp311-win_amd64.whl", hash = "sha256:bffccec7be0165cdba60241f0a6c7c420422cab4a608a89ddabf9e1839ccc2a7"}, - {file = "wisdem-3.15.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:176a14302b682ff6fddb345b57ff7520af825846b2e33625a9b795fbb03a99aa"}, - {file = "wisdem-3.15.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:cb1d024ce1ae1c6834381c087977adaf6fa6f9a48fbf1a1510031d369fe854f1"}, - {file = "wisdem-3.15.3-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:aac4eef9f5dc9115b9a1acc910202c4a9453c70ff93e16a724c1f95caffeac9e"}, - {file = "wisdem-3.15.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1e791a86639a788e697737879f99cfbf0ddd7fb1c1bc105aa4198489d03bb61d"}, - {file = "wisdem-3.15.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:146dd239f9a8f7b854358b9145ed0cad11c19394a05c76573b8476177c04e138"}, - {file = "wisdem-3.15.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a2875d38104485fdd034b0d2bb106084f667fe736653d96de7ea64e81f8e3985"}, - {file = "wisdem-3.15.3-cp312-cp312-win_amd64.whl", hash = "sha256:544ce4919225f711148c766b180b7b83a1dfc77101caec29ace800ca38941891"}, - {file = "wisdem-3.15.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:19bc8feae082c8fb295685b4f8141118e0ff25492d5697680c530b8fd1993cc6"}, - {file = "wisdem-3.15.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:22c0afb6235a5068db1850ebd217831ce81f986d5ee6f38affd483ab888d974d"}, - {file = "wisdem-3.15.3-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7454d8f56279fe3c1ba179b26f03d225b4360095552b1ccfb4d6b81bc6d042b1"}, - {file = "wisdem-3.15.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e32deab7e17046a92b0cf47e902045e401a1407fc6d354d3f60e80508e2c7975"}, - {file = "wisdem-3.15.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:c675da34f2fda489c950f8f9534328928f78da64aea272f536361badfbac33be"}, - {file = "wisdem-3.15.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c9598e2e1deb51e5f853db93a5b53e40db117a402b23aa176c45bc4f55ed89c2"}, - {file = "wisdem-3.15.3-cp39-cp39-win_amd64.whl", hash = "sha256:afb3492c76efe6d4aeb62ff02c28398a341501534da44e6f6d55e838837d4713"}, - {file = "wisdem-3.15.3.tar.gz", hash = "sha256:9f19b1532fee14ebf14908ed4addaa203715c9d02112f25b37285dd148348a07"}, + {file = "wisdem-3.16.4-cp310-cp310-macosx_12_0_x86_64.whl", hash = "sha256:443d5fbd8cd7a69e50c25fecac832297e427d7975af14c5ec32caa59294b085a"}, + {file = "wisdem-3.16.4-cp310-cp310-macosx_13_0_x86_64.whl", hash = "sha256:ad0b83530964e614f430ff83ee38abe5997bca42a1279b6301d6939431042988"}, + {file = "wisdem-3.16.4-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:7c26f580e8595d5ad9a00b418feeee529c501c32634237a793f8543c8fa45140"}, + {file = "wisdem-3.16.4-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4918b98fdb74369270b53857fcf5097b41fabb43c5ea72f94dcc6a788568b190"}, + {file = "wisdem-3.16.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18784f54b14754d3b755a7e0fa5862301af8fdbb7d59e05de90ee1bbf9d9128b"}, + {file = "wisdem-3.16.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:612e1f87082fc9ba5006037f4e8c17242320873c85fc1277984b862db40a7ad0"}, + {file = "wisdem-3.16.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:e0c5b717e536b581415e7be1e01924dc2333b329d88886d38f48aadab47289ed"}, + {file = "wisdem-3.16.4-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0ae9da2ae9036791857cad3e201d526ab82bf8d8ca6e902466c8ed7ad434cc84"}, + {file = "wisdem-3.16.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:91bd15bf1298b2422a0bd98ebff8336f464726c4ab4fd4b590976ea2b2f9f6bf"}, + {file = "wisdem-3.16.4-cp310-cp310-win_amd64.whl", hash = "sha256:376b18c13db629dea4efaaaf15a973252372f1d14895a6b7312e4ada479611b1"}, + {file = "wisdem-3.16.4-cp311-cp311-macosx_12_0_x86_64.whl", hash = "sha256:2fceb88c9bf3708e5e5529711f87d541dc6479720936a0d632acccc77e94dbd1"}, + {file = "wisdem-3.16.4-cp311-cp311-macosx_13_0_x86_64.whl", hash = "sha256:d3b5e247b315c87a2773c60fb8c5feb115b51cc0713c1fd76771627463f879c0"}, + {file = "wisdem-3.16.4-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:ad4489ecc74c1f466b74d803ad7df2b33ca98b2bad4a6b4998067eea3c46511d"}, + {file = "wisdem-3.16.4-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3f6114be0bc7effb86c3ab7c993979d2081f31483d41c3dea4fd78175dd31836"}, + {file = "wisdem-3.16.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1817b5b0da867d6f488f247fd23d0376500e375b4aeae7faee6d9a40ba67caf1"}, + {file = "wisdem-3.16.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:91a86da67cf15d8fd9cb09bb6e7bfbdb9ed352ff307da7560c280440b73db008"}, + {file = "wisdem-3.16.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:b7ddc4210ef922a8146d9fa5c1aa41630b57783dc43d0a619738313c9aa17f2f"}, + {file = "wisdem-3.16.4-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:d217d222d30400ed3ec211a0f5db111566f669266faff888f35c1e3f92e456d5"}, + {file = "wisdem-3.16.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:411a41ed29b66046fb6fc852d592543ffa31adbb78cbda189272ee097b3ef282"}, + {file = "wisdem-3.16.4-cp311-cp311-win_amd64.whl", hash = "sha256:8dd09e133401ae48ac6c8182ff33c59312b87f5a3a060bde87e4a6626b0591a5"}, + {file = "wisdem-3.16.4-cp312-cp312-macosx_12_0_x86_64.whl", hash = "sha256:4d216aa76c1fb3af5796be2e13ccda7e065e12e5534278db529ad768a23b0542"}, + {file = "wisdem-3.16.4-cp312-cp312-macosx_13_0_x86_64.whl", hash = "sha256:8ac09b7105db5e74237f3d061a704648e01c5c7a2a7dab1438781d007bd7f5ce"}, + {file = "wisdem-3.16.4-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:6dcc2a9785caed8ac3ee4164bdf9073b81a2e610d325ebf34b30ce0c3ce91f14"}, + {file = "wisdem-3.16.4-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6c58820e9fc43f74f91b1f1923d8d021f713676bdd80483d321a6a16596d5252"}, + {file = "wisdem-3.16.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:71f742c28b88b49c2f15902ee348ddfdc94eb790da0092ca9c2ebf79d82e6327"}, + {file = "wisdem-3.16.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45a253d6770588949ad0c280c306880acdd5180786859bcc3b0e57055f98cf71"}, + {file = "wisdem-3.16.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:b7754915d905e3f21af618bf13618a33d02e3d45ad403d3683cf69f83ebe1f74"}, + {file = "wisdem-3.16.4-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:507fe9ecfa4b510319db67c6c37af926fbd5e5831034da08f694060defdddb79"}, + {file = "wisdem-3.16.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a037a4b36cfb3cac4b93098c6471f3a589cecde4a1d2a29f3b98c285e577bc6d"}, + {file = "wisdem-3.16.4-cp312-cp312-win_amd64.whl", hash = "sha256:4dc43e50952048f2c6ad3b9e80ecfd84c3370a888f0e2c2399059c27cf020a7d"}, + {file = "wisdem-3.16.4-cp39-cp39-macosx_12_0_x86_64.whl", hash = "sha256:60f5480f76f7dd49dc71e68e28c5b6a6681575b15c3bae4ebc3edf9b0089f8fc"}, + {file = "wisdem-3.16.4-cp39-cp39-macosx_13_0_x86_64.whl", hash = "sha256:aac7ffaf4a9a61496b8904319824e90118bdf0b8de1a1bdad029c46854aaffa7"}, + {file = "wisdem-3.16.4-cp39-cp39-macosx_14_0_arm64.whl", hash = "sha256:1a1d8a8fe0cf8440263189f51b557bbb8def021d1e9ad80c9e93d26c7a1915ed"}, + {file = "wisdem-3.16.4-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d45d13252564ce5a6b0abf0fb78586c17ab89754e4b2310db4b111d6331a389b"}, + {file = "wisdem-3.16.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:60adbdfb6b6bc4bf57f2918d527806729620ef2e82bacb60aa060aec6c519a9d"}, + {file = "wisdem-3.16.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcbf98ef6a82754f0f522027e7b3822965b87ea4ef8ce1d43c92fdb00ed969ee"}, + {file = "wisdem-3.16.4-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:a86156c358ca8c7e06d0bae67c84ae9640d29c2bd37a2d17658900813454ee20"}, + {file = "wisdem-3.16.4-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:455257441569ad1a5e0a95fa089de6bbb87e25c902ded72850d96258ef99e231"}, + {file = "wisdem-3.16.4-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:804264d51f53f8190aaf80b5477b1d0a89e2685fcbda94938d11aac0a582446d"}, + {file = "wisdem-3.16.4-cp39-cp39-win_amd64.whl", hash = "sha256:2b771ddeefa397fdb9814e9fc839798b855d3696c8ee21ce3f3e7ac805147c3e"}, + {file = "wisdem-3.16.4.tar.gz", hash = "sha256:37316bdf1b283225f88faa7e646b211c3c6e16fc071faf3b83fcfcdeccaff879"}, ] [package.dependencies] @@ -3340,7 +3446,7 @@ test = ["coveralls", "pytest", "pytest-cov"] name = "xlrd" version = "2.0.1" description = "Library for developers to extract data from Microsoft Excel (tm) .xls spreadsheet files" -optional = false +optional = true python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" files = [ {file = "xlrd-2.0.1-py2.py3-none-any.whl", hash = "sha256:6a33ee89877bd9abc1158129f6e94be74e2679636b8a205b43b85206c3f0bbdd"}, @@ -3354,23 +3460,25 @@ test = ["pytest", "pytest-cov"] [[package]] name = "zipp" -version = "3.18.2" +version = "3.20.0" description = "Backport of pathlib-compatible object wrapper for zip files" optional = true python-versions = ">=3.8" files = [ - {file = "zipp-3.18.2-py3-none-any.whl", hash = "sha256:dce197b859eb796242b0622af1b8beb0a722d52aa2f57133ead08edd5bf5374e"}, - {file = "zipp-3.18.2.tar.gz", hash = "sha256:6278d9ddbcfb1f1089a88fde84481528b07b0e10474e09dcfe53dad4069fa059"}, + {file = "zipp-3.20.0-py3-none-any.whl", hash = "sha256:58da6168be89f0be59beb194da1250516fdaa062ccebd30127ac65d30045e10d"}, + {file = "zipp-3.20.0.tar.gz", hash = "sha256:0145e43d89664cfe1a2e533adc75adafed82fe2da404b4bbb6b026c0157bdb31"}, ] [package.extras] -docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] -testing = ["big-O", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more-itertools", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-ignore-flaky", "pytest-mypy", "pytest-ruff (>=0.2.1)"] +doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +test = ["big-O", "importlib-resources", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more-itertools", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-ignore-flaky", "pytest-mypy", "pytest-ruff (>=0.2.1)"] [extras] +all = ["rosco", "xlrd"] +excel = ["xlrd"] rosco = ["rosco"] [metadata] lock-version = "2.0" python-versions = "^3.9" -content-hash = "c869eff97c77ac768580e7cc54b0b21b451f721ce307a906c541d0967808baf7" +content-hash = "40bf060d7a2035b1e08f89416ed8a5e561e2f925a03e93f2776ccaf9f92c6fdd" diff --git a/openfast_io/pyproject.toml b/openfast_io/pyproject.toml index 7d53a94a1..23c7e8fc9 100644 --- a/openfast_io/pyproject.toml +++ b/openfast_io/pyproject.toml @@ -2,39 +2,67 @@ name = "openfast_io" version = "4.0.0" # We can make this dynamic to use github tags using dynamic = ["version"] description = "Readers and writers for OpenFAST files." -requires-python = ">=3.9" license = "Apache-2.0" authors = [ "NREL WISDEM Team ", "Daniel Zalkind ", "Garrett Barter ", - "Pietro Bortolotti ", + "Pietro Bortolotti ", "Mayank Chetan ", "John Jasa", ] +maintainers = [ + "Mayank Chetan ", + "Andy Platt ", + "Derek Slaughter ", +] readme = "README.md" packages = [{include = "openfast_io"}] -classifiers = [ +classifiers = [ # Optional + # How mature is this project? Common values are + # 3 - Alpha + # 4 - Beta + # 5 - Production/Stable "Development Status :: 4 - Beta", - "Programming Language :: Python", + + # Indicate who your project is intended for + "Intended Audience :: Science/Research", + "Topic :: Scientific/Engineering", + + "License :: OSI Approved :: Apache Software License", + "Operating System :: OS Independent", + + # Specify the Python versions you support here. In particular, ensure + # that you indicate you support Python 3. These classifiers are *not* + # checked by "pip install". See instead "python_requires" below. "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3 :: Only", ] +homepage = "https://github.com/OpenFAST/openfast" +documentation = "https://openfast.readthedocs.io/en/main/" +repository = "https://github.com/OpenFAST/openfast" + +[tool.poetry.urls] +"Bug Tracker" = "https://github.com/OpenFAST/openfast/issues" + [tool.poetry.dependencies] python = "^3.9" numpy = "^1" pandas = "^2" -xlrd = "^2" +xlrd = {version = "^2", optional = true} ruamel_yaml = "^0.18" rosco = {version = "^2.9.2", optional = true} [tool.poetry.extras] rosco = ["rosco"] +excel = ["xlrd"] +all = ["rosco", "xlrd"] [build-system] From a0bed7c4b36eccbba383ee8854056863adf81577 Mon Sep 17 00:00:00 2001 From: Mayank Chetan Date: Mon, 19 Aug 2024 16:28:54 +0000 Subject: [PATCH 018/161] update .gitignore for python --- .gitignore | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.gitignore b/.gitignore index 5a524da47..e6e0553e1 100644 --- a/.gitignore +++ b/.gitignore @@ -58,3 +58,7 @@ vs-build/ #Simulink cache files varcache *.slxc + +# Python cache files +__pycache__/ +openfast_io/dist/ \ No newline at end of file From 09775e137ddbaafd83a83786d76d79bed79ab85c Mon Sep 17 00:00:00 2001 From: Mayank Chetan Date: Mon, 19 Aug 2024 16:29:41 +0000 Subject: [PATCH 019/161] testing GH Actions for test pypi upload --- .github/workflows/deploy.yml | 52 +++++++++++++++++++++++++----------- 1 file changed, 36 insertions(+), 16 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 180969d6f..9d0d7ee8d 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -12,27 +12,47 @@ on: - released jobs: - publish-to-pypi: - runs-on: ubuntu-latest - permissions: - id-token: write - contents: read + # publish-to-pypi: + # runs-on: ubuntu-latest + # permissions: + # id-token: write + # contents: read - steps: - - name: Checkout Repository - uses: actions/checkout@v4 + # steps: + # - name: Checkout Repository + # uses: actions/checkout@v4 + + # - name: Install Poetry + # uses: snok/install-poetry@v1.3.4 - - name: Install Poetry - uses: snok/install-poetry@v1.3.4 + # - name: Build a binary wheel and a source tarball + # run: poetry build + # working-directory: openfast_python - - name: Build a binary wheel and a source tarball - run: poetry build - working-directory: openfast_python + # - name: Publish package distributions to PyPI + # uses: pypa/gh-action-pypi-publish@v1.8.14 + # with: + # packages-dir: openfast_python/dist - - name: Publish package distributions to PyPI - uses: pypa/gh-action-pypi-publish@v1.8.14 +# name: Build and publish python package + +# on: +# release: +# types: [ published ] + +# jobs: + publish-to-test-pypi: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Build and publish to pypi + uses: JRubics/poetry-publish@v2.0 with: - packages-dir: openfast_python/dist + pypi_token: ${{ secrets.PYPI_TOKEN }} + package_directory: "openfast_io" + repository_name: "openfast_io" + repository_url: "https://test.pypi.org/legacy/" + docker-build-and-push: From 611f2690c89867ae557e2f7745057bd1a732717f Mon Sep 17 00:00:00 2001 From: Mayank Chetan Date: Mon, 19 Aug 2024 18:16:39 +0000 Subject: [PATCH 020/161] hatch testing --- .github/workflows/deploy.yml | 21 +- openfast_io/openfast_io/__init__.py | 6 + openfast_io/poetry.lock | 3484 --------------------------- openfast_io/pyproject.toml | 68 +- 4 files changed, 56 insertions(+), 3523 deletions(-) delete mode 100644 openfast_io/poetry.lock diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 9d0d7ee8d..3084f07ae 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -45,15 +45,24 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - name: Build and publish to pypi - uses: JRubics/poetry-publish@v2.0 + + - name: Set up Python + uses: actions/setup-python@v4 with: - pypi_token: ${{ secrets.PYPI_TOKEN }} - package_directory: "openfast_io" - repository_name: "openfast_io" - repository_url: "https://test.pypi.org/legacy/" + python-version: '3.10' + cache: 'pip' + + - name: Install Hatch + uses: pypa/hatch@install + - name: Build package + run: hatch build + - name: Publish to PyPI + env: + HATCH_INDEX_USER: __token__ + HATCH_INDEX_AUTH: ${{ secrets.PYPI_TOKEN }} + run: hatch publish -r test docker-build-and-push: runs-on: ubuntu-latest diff --git a/openfast_io/openfast_io/__init__.py b/openfast_io/openfast_io/__init__.py index e69de29bb..3b8cbcc8e 100644 --- a/openfast_io/openfast_io/__init__.py +++ b/openfast_io/openfast_io/__init__.py @@ -0,0 +1,6 @@ +try: + from ._version import __version__, __version_tuple__ + +except ImportError: + __version__ = "undefined" + __version_tuple__ = None # type: ignore \ No newline at end of file diff --git a/openfast_io/poetry.lock b/openfast_io/poetry.lock deleted file mode 100644 index 969113335..000000000 --- a/openfast_io/poetry.lock +++ /dev/null @@ -1,3484 +0,0 @@ -# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. - -[[package]] -name = "anyio" -version = "4.4.0" -description = "High level compatibility layer for multiple asynchronous event loop implementations" -optional = true -python-versions = ">=3.8" -files = [ - {file = "anyio-4.4.0-py3-none-any.whl", hash = "sha256:c1b2d8f46a8a812513012e1107cb0e68c17159a7a594208005a57dc776e1bdc7"}, - {file = "anyio-4.4.0.tar.gz", hash = "sha256:5aadc6a1bbb7cdb0bede386cac5e2940f5e2ff3aa20277e991cf028e0585ce94"}, -] - -[package.dependencies] -exceptiongroup = {version = ">=1.0.2", markers = "python_version < \"3.11\""} -idna = ">=2.8" -sniffio = ">=1.1" -typing-extensions = {version = ">=4.1", markers = "python_version < \"3.11\""} - -[package.extras] -doc = ["Sphinx (>=7)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"] -test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (>=0.17)"] -trio = ["trio (>=0.23)"] - -[[package]] -name = "appnope" -version = "0.1.4" -description = "Disable App Nap on macOS >= 10.9" -optional = true -python-versions = ">=3.6" -files = [ - {file = "appnope-0.1.4-py2.py3-none-any.whl", hash = "sha256:502575ee11cd7a28c0205f379b525beefebab9d161b7c964670864014ed7213c"}, - {file = "appnope-0.1.4.tar.gz", hash = "sha256:1de3860566df9caf38f01f86f65e0e13e379af54f9e4bee1e66b48f2efffd1ee"}, -] - -[[package]] -name = "argon2-cffi" -version = "23.1.0" -description = "Argon2 for Python" -optional = true -python-versions = ">=3.7" -files = [ - {file = "argon2_cffi-23.1.0-py3-none-any.whl", hash = "sha256:c670642b78ba29641818ab2e68bd4e6a78ba53b7eff7b4c3815ae16abf91c7ea"}, - {file = "argon2_cffi-23.1.0.tar.gz", hash = "sha256:879c3e79a2729ce768ebb7d36d4609e3a78a4ca2ec3a9f12286ca057e3d0db08"}, -] - -[package.dependencies] -argon2-cffi-bindings = "*" - -[package.extras] -dev = ["argon2-cffi[tests,typing]", "tox (>4)"] -docs = ["furo", "myst-parser", "sphinx", "sphinx-copybutton", "sphinx-notfound-page"] -tests = ["hypothesis", "pytest"] -typing = ["mypy"] - -[[package]] -name = "argon2-cffi-bindings" -version = "21.2.0" -description = "Low-level CFFI bindings for Argon2" -optional = true -python-versions = ">=3.6" -files = [ - {file = "argon2-cffi-bindings-21.2.0.tar.gz", hash = "sha256:bb89ceffa6c791807d1305ceb77dbfacc5aa499891d2c55661c6459651fc39e3"}, - {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:ccb949252cb2ab3a08c02024acb77cfb179492d5701c7cbdbfd776124d4d2367"}, - {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9524464572e12979364b7d600abf96181d3541da11e23ddf565a32e70bd4dc0d"}, - {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b746dba803a79238e925d9046a63aa26bf86ab2a2fe74ce6b009a1c3f5c8f2ae"}, - {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:58ed19212051f49a523abb1dbe954337dc82d947fb6e5a0da60f7c8471a8476c"}, - {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:bd46088725ef7f58b5a1ef7ca06647ebaf0eb4baff7d1d0d177c6cc8744abd86"}, - {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-musllinux_1_1_i686.whl", hash = "sha256:8cd69c07dd875537a824deec19f978e0f2078fdda07fd5c42ac29668dda5f40f"}, - {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:f1152ac548bd5b8bcecfb0b0371f082037e47128653df2e8ba6e914d384f3c3e"}, - {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-win32.whl", hash = "sha256:603ca0aba86b1349b147cab91ae970c63118a0f30444d4bc80355937c950c082"}, - {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-win_amd64.whl", hash = "sha256:b2ef1c30440dbbcba7a5dc3e319408b59676e2e039e2ae11a8775ecf482b192f"}, - {file = "argon2_cffi_bindings-21.2.0-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:e415e3f62c8d124ee16018e491a009937f8cf7ebf5eb430ffc5de21b900dad93"}, - {file = "argon2_cffi_bindings-21.2.0-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:3e385d1c39c520c08b53d63300c3ecc28622f076f4c2b0e6d7e796e9f6502194"}, - {file = "argon2_cffi_bindings-21.2.0-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2c3e3cc67fdb7d82c4718f19b4e7a87123caf8a93fde7e23cf66ac0337d3cb3f"}, - {file = "argon2_cffi_bindings-21.2.0-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6a22ad9800121b71099d0fb0a65323810a15f2e292f2ba450810a7316e128ee5"}, - {file = "argon2_cffi_bindings-21.2.0-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f9f8b450ed0547e3d473fdc8612083fd08dd2120d6ac8f73828df9b7d45bb351"}, - {file = "argon2_cffi_bindings-21.2.0-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:93f9bf70084f97245ba10ee36575f0c3f1e7d7724d67d8e5b08e61787c320ed7"}, - {file = "argon2_cffi_bindings-21.2.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:3b9ef65804859d335dc6b31582cad2c5166f0c3e7975f324d9ffaa34ee7e6583"}, - {file = "argon2_cffi_bindings-21.2.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d4966ef5848d820776f5f562a7d45fdd70c2f330c961d0d745b784034bd9f48d"}, - {file = "argon2_cffi_bindings-21.2.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:20ef543a89dee4db46a1a6e206cd015360e5a75822f76df533845c3cbaf72670"}, - {file = "argon2_cffi_bindings-21.2.0-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ed2937d286e2ad0cc79a7087d3c272832865f779430e0cc2b4f3718d3159b0cb"}, - {file = "argon2_cffi_bindings-21.2.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:5e00316dabdaea0b2dd82d141cc66889ced0cdcbfa599e8b471cf22c620c329a"}, -] - -[package.dependencies] -cffi = ">=1.0.1" - -[package.extras] -dev = ["cogapp", "pre-commit", "pytest", "wheel"] -tests = ["pytest"] - -[[package]] -name = "arrow" -version = "1.3.0" -description = "Better dates & times for Python" -optional = true -python-versions = ">=3.8" -files = [ - {file = "arrow-1.3.0-py3-none-any.whl", hash = "sha256:c728b120ebc00eb84e01882a6f5e7927a53960aa990ce7dd2b10f39005a67f80"}, - {file = "arrow-1.3.0.tar.gz", hash = "sha256:d4540617648cb5f895730f1ad8c82a65f2dad0166f57b75f3ca54759c4d67a85"}, -] - -[package.dependencies] -python-dateutil = ">=2.7.0" -types-python-dateutil = ">=2.8.10" - -[package.extras] -doc = ["doc8", "sphinx (>=7.0.0)", "sphinx-autobuild", "sphinx-autodoc-typehints", "sphinx_rtd_theme (>=1.3.0)"] -test = ["dateparser (==1.*)", "pre-commit", "pytest", "pytest-cov", "pytest-mock", "pytz (==2021.1)", "simplejson (==3.*)"] - -[[package]] -name = "asttokens" -version = "2.4.1" -description = "Annotate AST trees with source code positions" -optional = true -python-versions = "*" -files = [ - {file = "asttokens-2.4.1-py2.py3-none-any.whl", hash = "sha256:051ed49c3dcae8913ea7cd08e46a606dba30b79993209636c4875bc1d637bc24"}, - {file = "asttokens-2.4.1.tar.gz", hash = "sha256:b03869718ba9a6eb027e134bfdf69f38a236d681c83c160d510768af11254ba0"}, -] - -[package.dependencies] -six = ">=1.12.0" - -[package.extras] -astroid = ["astroid (>=1,<2)", "astroid (>=2,<4)"] -test = ["astroid (>=1,<2)", "astroid (>=2,<4)", "pytest"] - -[[package]] -name = "async-lru" -version = "2.0.4" -description = "Simple LRU cache for asyncio" -optional = true -python-versions = ">=3.8" -files = [ - {file = "async-lru-2.0.4.tar.gz", hash = "sha256:b8a59a5df60805ff63220b2a0c5b5393da5521b113cd5465a44eb037d81a5627"}, - {file = "async_lru-2.0.4-py3-none-any.whl", hash = "sha256:ff02944ce3c288c5be660c42dbcca0742b32c3b279d6dceda655190240b99224"}, -] - -[package.dependencies] -typing-extensions = {version = ">=4.0.0", markers = "python_version < \"3.11\""} - -[[package]] -name = "attrs" -version = "24.2.0" -description = "Classes Without Boilerplate" -optional = true -python-versions = ">=3.7" -files = [ - {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"}, - {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"}, -] - -[package.extras] -benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] -tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] - -[[package]] -name = "babel" -version = "2.16.0" -description = "Internationalization utilities" -optional = true -python-versions = ">=3.8" -files = [ - {file = "babel-2.16.0-py3-none-any.whl", hash = "sha256:368b5b98b37c06b7daf6696391c3240c938b37767d4584413e8438c5c435fa8b"}, - {file = "babel-2.16.0.tar.gz", hash = "sha256:d1f3554ca26605fe173f3de0c65f750f5a42f924499bf134de6423582298e316"}, -] - -[package.extras] -dev = ["freezegun (>=1.0,<2.0)", "pytest (>=6.0)", "pytest-cov"] - -[[package]] -name = "beautifulsoup4" -version = "4.12.3" -description = "Screen-scraping library" -optional = true -python-versions = ">=3.6.0" -files = [ - {file = "beautifulsoup4-4.12.3-py3-none-any.whl", hash = "sha256:b80878c9f40111313e55da8ba20bdba06d8fa3969fc68304167741bbf9e082ed"}, - {file = "beautifulsoup4-4.12.3.tar.gz", hash = "sha256:74e3d1928edc070d21748185c46e3fb33490f22f52a3addee9aee0f4f7781051"}, -] - -[package.dependencies] -soupsieve = ">1.2" - -[package.extras] -cchardet = ["cchardet"] -chardet = ["chardet"] -charset-normalizer = ["charset-normalizer"] -html5lib = ["html5lib"] -lxml = ["lxml"] - -[[package]] -name = "bleach" -version = "6.1.0" -description = "An easy safelist-based HTML-sanitizing tool." -optional = true -python-versions = ">=3.8" -files = [ - {file = "bleach-6.1.0-py3-none-any.whl", hash = "sha256:3225f354cfc436b9789c66c4ee030194bee0568fbf9cbdad3bc8b5c26c5f12b6"}, - {file = "bleach-6.1.0.tar.gz", hash = "sha256:0a31f1837963c41d46bbf1331b8778e1308ea0791db03cc4e7357b97cf42a8fe"}, -] - -[package.dependencies] -six = ">=1.9.0" -webencodings = "*" - -[package.extras] -css = ["tinycss2 (>=1.1.0,<1.3)"] - -[[package]] -name = "certifi" -version = "2024.7.4" -description = "Python package for providing Mozilla's CA Bundle." -optional = true -python-versions = ">=3.6" -files = [ - {file = "certifi-2024.7.4-py3-none-any.whl", hash = "sha256:c198e21b1289c2ab85ee4e67bb4b4ef3ead0892059901a8d5b622f24a1101e90"}, - {file = "certifi-2024.7.4.tar.gz", hash = "sha256:5a1e7645bc0ec61a09e26c36f6106dd4cf40c6db3a1fb6352b0244e7fb057c7b"}, -] - -[[package]] -name = "cffi" -version = "1.17.0" -description = "Foreign Function Interface for Python calling C code." -optional = true -python-versions = ">=3.8" -files = [ - {file = "cffi-1.17.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f9338cc05451f1942d0d8203ec2c346c830f8e86469903d5126c1f0a13a2bcbb"}, - {file = "cffi-1.17.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a0ce71725cacc9ebf839630772b07eeec220cbb5f03be1399e0457a1464f8e1a"}, - {file = "cffi-1.17.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c815270206f983309915a6844fe994b2fa47e5d05c4c4cef267c3b30e34dbe42"}, - {file = "cffi-1.17.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d6bdcd415ba87846fd317bee0774e412e8792832e7805938987e4ede1d13046d"}, - {file = "cffi-1.17.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8a98748ed1a1df4ee1d6f927e151ed6c1a09d5ec21684de879c7ea6aa96f58f2"}, - {file = "cffi-1.17.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0a048d4f6630113e54bb4b77e315e1ba32a5a31512c31a273807d0027a7e69ab"}, - {file = "cffi-1.17.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:24aa705a5f5bd3a8bcfa4d123f03413de5d86e497435693b638cbffb7d5d8a1b"}, - {file = "cffi-1.17.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:856bf0924d24e7f93b8aee12a3a1095c34085600aa805693fb7f5d1962393206"}, - {file = "cffi-1.17.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:4304d4416ff032ed50ad6bb87416d802e67139e31c0bde4628f36a47a3164bfa"}, - {file = "cffi-1.17.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:331ad15c39c9fe9186ceaf87203a9ecf5ae0ba2538c9e898e3a6967e8ad3db6f"}, - {file = "cffi-1.17.0-cp310-cp310-win32.whl", hash = "sha256:669b29a9eca6146465cc574659058ed949748f0809a2582d1f1a324eb91054dc"}, - {file = "cffi-1.17.0-cp310-cp310-win_amd64.whl", hash = "sha256:48b389b1fd5144603d61d752afd7167dfd205973a43151ae5045b35793232aa2"}, - {file = "cffi-1.17.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c5d97162c196ce54af6700949ddf9409e9833ef1003b4741c2b39ef46f1d9720"}, - {file = "cffi-1.17.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5ba5c243f4004c750836f81606a9fcb7841f8874ad8f3bf204ff5e56332b72b9"}, - {file = "cffi-1.17.0-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bb9333f58fc3a2296fb1d54576138d4cf5d496a2cc118422bd77835e6ae0b9cb"}, - {file = "cffi-1.17.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:435a22d00ec7d7ea533db494da8581b05977f9c37338c80bc86314bec2619424"}, - {file = "cffi-1.17.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d1df34588123fcc88c872f5acb6f74ae59e9d182a2707097f9e28275ec26a12d"}, - {file = "cffi-1.17.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:df8bb0010fdd0a743b7542589223a2816bdde4d94bb5ad67884348fa2c1c67e8"}, - {file = "cffi-1.17.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8b5b9712783415695663bd463990e2f00c6750562e6ad1d28e072a611c5f2a6"}, - {file = "cffi-1.17.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ffef8fd58a36fb5f1196919638f73dd3ae0db1a878982b27a9a5a176ede4ba91"}, - {file = "cffi-1.17.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:4e67d26532bfd8b7f7c05d5a766d6f437b362c1bf203a3a5ce3593a645e870b8"}, - {file = "cffi-1.17.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:45f7cd36186db767d803b1473b3c659d57a23b5fa491ad83c6d40f2af58e4dbb"}, - {file = "cffi-1.17.0-cp311-cp311-win32.whl", hash = "sha256:a9015f5b8af1bb6837a3fcb0cdf3b874fe3385ff6274e8b7925d81ccaec3c5c9"}, - {file = "cffi-1.17.0-cp311-cp311-win_amd64.whl", hash = "sha256:b50aaac7d05c2c26dfd50c3321199f019ba76bb650e346a6ef3616306eed67b0"}, - {file = "cffi-1.17.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:aec510255ce690d240f7cb23d7114f6b351c733a74c279a84def763660a2c3bc"}, - {file = "cffi-1.17.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2770bb0d5e3cc0e31e7318db06efcbcdb7b31bcb1a70086d3177692a02256f59"}, - {file = "cffi-1.17.0-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:db9a30ec064129d605d0f1aedc93e00894b9334ec74ba9c6bdd08147434b33eb"}, - {file = "cffi-1.17.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a47eef975d2b8b721775a0fa286f50eab535b9d56c70a6e62842134cf7841195"}, - {file = "cffi-1.17.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f3e0992f23bbb0be00a921eae5363329253c3b86287db27092461c887b791e5e"}, - {file = "cffi-1.17.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6107e445faf057c118d5050560695e46d272e5301feffda3c41849641222a828"}, - {file = "cffi-1.17.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eb862356ee9391dc5a0b3cbc00f416b48c1b9a52d252d898e5b7696a5f9fe150"}, - {file = "cffi-1.17.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:c1c13185b90bbd3f8b5963cd8ce7ad4ff441924c31e23c975cb150e27c2bf67a"}, - {file = "cffi-1.17.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:17c6d6d3260c7f2d94f657e6872591fe8733872a86ed1345bda872cfc8c74885"}, - {file = "cffi-1.17.0-cp312-cp312-win32.whl", hash = "sha256:c3b8bd3133cd50f6b637bb4322822c94c5ce4bf0d724ed5ae70afce62187c492"}, - {file = "cffi-1.17.0-cp312-cp312-win_amd64.whl", hash = "sha256:dca802c8db0720ce1c49cce1149ff7b06e91ba15fa84b1d59144fef1a1bc7ac2"}, - {file = "cffi-1.17.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:6ce01337d23884b21c03869d2f68c5523d43174d4fc405490eb0091057943118"}, - {file = "cffi-1.17.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:cab2eba3830bf4f6d91e2d6718e0e1c14a2f5ad1af68a89d24ace0c6b17cced7"}, - {file = "cffi-1.17.0-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:14b9cbc8f7ac98a739558eb86fabc283d4d564dafed50216e7f7ee62d0d25377"}, - {file = "cffi-1.17.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b00e7bcd71caa0282cbe3c90966f738e2db91e64092a877c3ff7f19a1628fdcb"}, - {file = "cffi-1.17.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:41f4915e09218744d8bae14759f983e466ab69b178de38066f7579892ff2a555"}, - {file = "cffi-1.17.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e4760a68cab57bfaa628938e9c2971137e05ce48e762a9cb53b76c9b569f1204"}, - {file = "cffi-1.17.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:011aff3524d578a9412c8b3cfaa50f2c0bd78e03eb7af7aa5e0df59b158efb2f"}, - {file = "cffi-1.17.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:a003ac9edc22d99ae1286b0875c460351f4e101f8c9d9d2576e78d7e048f64e0"}, - {file = "cffi-1.17.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ef9528915df81b8f4c7612b19b8628214c65c9b7f74db2e34a646a0a2a0da2d4"}, - {file = "cffi-1.17.0-cp313-cp313-win32.whl", hash = "sha256:70d2aa9fb00cf52034feac4b913181a6e10356019b18ef89bc7c12a283bf5f5a"}, - {file = "cffi-1.17.0-cp313-cp313-win_amd64.whl", hash = "sha256:b7b6ea9e36d32582cda3465f54c4b454f62f23cb083ebc7a94e2ca6ef011c3a7"}, - {file = "cffi-1.17.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:964823b2fc77b55355999ade496c54dde161c621cb1f6eac61dc30ed1b63cd4c"}, - {file = "cffi-1.17.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:516a405f174fd3b88829eabfe4bb296ac602d6a0f68e0d64d5ac9456194a5b7e"}, - {file = "cffi-1.17.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dec6b307ce928e8e112a6bb9921a1cb00a0e14979bf28b98e084a4b8a742bd9b"}, - {file = "cffi-1.17.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e4094c7b464cf0a858e75cd14b03509e84789abf7b79f8537e6a72152109c76e"}, - {file = "cffi-1.17.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2404f3de742f47cb62d023f0ba7c5a916c9c653d5b368cc966382ae4e57da401"}, - {file = "cffi-1.17.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3aa9d43b02a0c681f0bfbc12d476d47b2b2b6a3f9287f11ee42989a268a1833c"}, - {file = "cffi-1.17.0-cp38-cp38-win32.whl", hash = "sha256:0bb15e7acf8ab35ca8b24b90af52c8b391690ef5c4aec3d31f38f0d37d2cc499"}, - {file = "cffi-1.17.0-cp38-cp38-win_amd64.whl", hash = "sha256:93a7350f6706b31f457c1457d3a3259ff9071a66f312ae64dc024f049055f72c"}, - {file = "cffi-1.17.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:1a2ddbac59dc3716bc79f27906c010406155031a1c801410f1bafff17ea304d2"}, - {file = "cffi-1.17.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:6327b572f5770293fc062a7ec04160e89741e8552bf1c358d1a23eba68166759"}, - {file = "cffi-1.17.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbc183e7bef690c9abe5ea67b7b60fdbca81aa8da43468287dae7b5c046107d4"}, - {file = "cffi-1.17.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5bdc0f1f610d067c70aa3737ed06e2726fd9d6f7bfee4a351f4c40b6831f4e82"}, - {file = "cffi-1.17.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6d872186c1617d143969defeadac5a904e6e374183e07977eedef9c07c8953bf"}, - {file = "cffi-1.17.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0d46ee4764b88b91f16661a8befc6bfb24806d885e27436fdc292ed7e6f6d058"}, - {file = "cffi-1.17.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f76a90c345796c01d85e6332e81cab6d70de83b829cf1d9762d0a3da59c7932"}, - {file = "cffi-1.17.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0e60821d312f99d3e1569202518dddf10ae547e799d75aef3bca3a2d9e8ee693"}, - {file = "cffi-1.17.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:eb09b82377233b902d4c3fbeeb7ad731cdab579c6c6fda1f763cd779139e47c3"}, - {file = "cffi-1.17.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:24658baf6224d8f280e827f0a50c46ad819ec8ba380a42448e24459daf809cf4"}, - {file = "cffi-1.17.0-cp39-cp39-win32.whl", hash = "sha256:0fdacad9e0d9fc23e519efd5ea24a70348305e8d7d85ecbb1a5fa66dc834e7fb"}, - {file = "cffi-1.17.0-cp39-cp39-win_amd64.whl", hash = "sha256:7cbc78dc018596315d4e7841c8c3a7ae31cc4d638c9b627f87d52e8abaaf2d29"}, - {file = "cffi-1.17.0.tar.gz", hash = "sha256:f3157624b7558b914cb039fd1af735e5e8049a87c817cc215109ad1c8779df76"}, -] - -[package.dependencies] -pycparser = "*" - -[[package]] -name = "charset-normalizer" -version = "3.3.2" -description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." -optional = true -python-versions = ">=3.7.0" -files = [ - {file = "charset-normalizer-3.3.2.tar.gz", hash = "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-win32.whl", hash = "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-win32.whl", hash = "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-win32.whl", hash = "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-win32.whl", hash = "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-win_amd64.whl", hash = "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-win32.whl", hash = "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-win32.whl", hash = "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d"}, - {file = "charset_normalizer-3.3.2-py3-none-any.whl", hash = "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc"}, -] - -[[package]] -name = "colorama" -version = "0.4.6" -description = "Cross-platform colored terminal text." -optional = true -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" -files = [ - {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, - {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, -] - -[[package]] -name = "comm" -version = "0.2.2" -description = "Jupyter Python Comm implementation, for usage in ipykernel, xeus-python etc." -optional = true -python-versions = ">=3.8" -files = [ - {file = "comm-0.2.2-py3-none-any.whl", hash = "sha256:e6fb86cb70ff661ee8c9c14e7d36d6de3b4066f1441be4063df9c5009f0a64d3"}, - {file = "comm-0.2.2.tar.gz", hash = "sha256:3fd7a84065306e07bea1773df6eb8282de51ba82f77c72f9c85716ab11fe980e"}, -] - -[package.dependencies] -traitlets = ">=4" - -[package.extras] -test = ["pytest"] - -[[package]] -name = "contourpy" -version = "1.2.1" -description = "Python library for calculating contours of 2D quadrilateral grids" -optional = true -python-versions = ">=3.9" -files = [ - {file = "contourpy-1.2.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bd7c23df857d488f418439686d3b10ae2fbf9bc256cd045b37a8c16575ea1040"}, - {file = "contourpy-1.2.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5b9eb0ca724a241683c9685a484da9d35c872fd42756574a7cfbf58af26677fd"}, - {file = "contourpy-1.2.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4c75507d0a55378240f781599c30e7776674dbaf883a46d1c90f37e563453480"}, - {file = "contourpy-1.2.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:11959f0ce4a6f7b76ec578576a0b61a28bdc0696194b6347ba3f1c53827178b9"}, - {file = "contourpy-1.2.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eb3315a8a236ee19b6df481fc5f997436e8ade24a9f03dfdc6bd490fea20c6da"}, - {file = "contourpy-1.2.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:39f3ecaf76cd98e802f094e0d4fbc6dc9c45a8d0c4d185f0f6c2234e14e5f75b"}, - {file = "contourpy-1.2.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:94b34f32646ca0414237168d68a9157cb3889f06b096612afdd296003fdd32fd"}, - {file = "contourpy-1.2.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:457499c79fa84593f22454bbd27670227874cd2ff5d6c84e60575c8b50a69619"}, - {file = "contourpy-1.2.1-cp310-cp310-win32.whl", hash = "sha256:ac58bdee53cbeba2ecad824fa8159493f0bf3b8ea4e93feb06c9a465d6c87da8"}, - {file = "contourpy-1.2.1-cp310-cp310-win_amd64.whl", hash = "sha256:9cffe0f850e89d7c0012a1fb8730f75edd4320a0a731ed0c183904fe6ecfc3a9"}, - {file = "contourpy-1.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6022cecf8f44e36af10bd9118ca71f371078b4c168b6e0fab43d4a889985dbb5"}, - {file = "contourpy-1.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ef5adb9a3b1d0c645ff694f9bca7702ec2c70f4d734f9922ea34de02294fdf72"}, - {file = "contourpy-1.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6150ffa5c767bc6332df27157d95442c379b7dce3a38dff89c0f39b63275696f"}, - {file = "contourpy-1.2.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4c863140fafc615c14a4bf4efd0f4425c02230eb8ef02784c9a156461e62c965"}, - {file = "contourpy-1.2.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:00e5388f71c1a0610e6fe56b5c44ab7ba14165cdd6d695429c5cd94021e390b2"}, - {file = "contourpy-1.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d4492d82b3bc7fbb7e3610747b159869468079fe149ec5c4d771fa1f614a14df"}, - {file = "contourpy-1.2.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:49e70d111fee47284d9dd867c9bb9a7058a3c617274900780c43e38d90fe1205"}, - {file = "contourpy-1.2.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:b59c0ffceff8d4d3996a45f2bb6f4c207f94684a96bf3d9728dbb77428dd8cb8"}, - {file = "contourpy-1.2.1-cp311-cp311-win32.whl", hash = "sha256:7b4182299f251060996af5249c286bae9361fa8c6a9cda5efc29fe8bfd6062ec"}, - {file = "contourpy-1.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2855c8b0b55958265e8b5888d6a615ba02883b225f2227461aa9127c578a4922"}, - {file = "contourpy-1.2.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:62828cada4a2b850dbef89c81f5a33741898b305db244904de418cc957ff05dc"}, - {file = "contourpy-1.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:309be79c0a354afff9ff7da4aaed7c3257e77edf6c1b448a779329431ee79d7e"}, - {file = "contourpy-1.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2e785e0f2ef0d567099b9ff92cbfb958d71c2d5b9259981cd9bee81bd194c9a4"}, - {file = "contourpy-1.2.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1cac0a8f71a041aa587410424ad46dfa6a11f6149ceb219ce7dd48f6b02b87a7"}, - {file = "contourpy-1.2.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:af3f4485884750dddd9c25cb7e3915d83c2db92488b38ccb77dd594eac84c4a0"}, - {file = "contourpy-1.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9ce6889abac9a42afd07a562c2d6d4b2b7134f83f18571d859b25624a331c90b"}, - {file = "contourpy-1.2.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:a1eea9aecf761c661d096d39ed9026574de8adb2ae1c5bd7b33558af884fb2ce"}, - {file = "contourpy-1.2.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:187fa1d4c6acc06adb0fae5544c59898ad781409e61a926ac7e84b8f276dcef4"}, - {file = "contourpy-1.2.1-cp312-cp312-win32.whl", hash = "sha256:c2528d60e398c7c4c799d56f907664673a807635b857df18f7ae64d3e6ce2d9f"}, - {file = "contourpy-1.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:1a07fc092a4088ee952ddae19a2b2a85757b923217b7eed584fdf25f53a6e7ce"}, - {file = "contourpy-1.2.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:bb6834cbd983b19f06908b45bfc2dad6ac9479ae04abe923a275b5f48f1a186b"}, - {file = "contourpy-1.2.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1d59e739ab0e3520e62a26c60707cc3ab0365d2f8fecea74bfe4de72dc56388f"}, - {file = "contourpy-1.2.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd3db01f59fdcbce5b22afad19e390260d6d0222f35a1023d9adc5690a889364"}, - {file = "contourpy-1.2.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a12a813949e5066148712a0626895c26b2578874e4cc63160bb007e6df3436fe"}, - {file = "contourpy-1.2.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fe0ccca550bb8e5abc22f530ec0466136379c01321fd94f30a22231e8a48d985"}, - {file = "contourpy-1.2.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e1d59258c3c67c865435d8fbeb35f8c59b8bef3d6f46c1f29f6123556af28445"}, - {file = "contourpy-1.2.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:f32c38afb74bd98ce26de7cc74a67b40afb7b05aae7b42924ea990d51e4dac02"}, - {file = "contourpy-1.2.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d31a63bc6e6d87f77d71e1abbd7387ab817a66733734883d1fc0021ed9bfa083"}, - {file = "contourpy-1.2.1-cp39-cp39-win32.whl", hash = "sha256:ddcb8581510311e13421b1f544403c16e901c4e8f09083c881fab2be80ee31ba"}, - {file = "contourpy-1.2.1-cp39-cp39-win_amd64.whl", hash = "sha256:10a37ae557aabf2509c79715cd20b62e4c7c28b8cd62dd7d99e5ed3ce28c3fd9"}, - {file = "contourpy-1.2.1-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:a31f94983fecbac95e58388210427d68cd30fe8a36927980fab9c20062645609"}, - {file = "contourpy-1.2.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ef2b055471c0eb466033760a521efb9d8a32b99ab907fc8358481a1dd29e3bd3"}, - {file = "contourpy-1.2.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:b33d2bc4f69caedcd0a275329eb2198f560b325605810895627be5d4b876bf7f"}, - {file = "contourpy-1.2.1.tar.gz", hash = "sha256:4d8908b3bee1c889e547867ca4cdc54e5ab6be6d3e078556814a22457f49423c"}, -] - -[package.dependencies] -numpy = ">=1.20" - -[package.extras] -bokeh = ["bokeh", "selenium"] -docs = ["furo", "sphinx (>=7.2)", "sphinx-copybutton"] -mypy = ["contourpy[bokeh,docs]", "docutils-stubs", "mypy (==1.8.0)", "types-Pillow"] -test = ["Pillow", "contourpy[test-no-images]", "matplotlib"] -test-no-images = ["pytest", "pytest-cov", "pytest-xdist", "wurlitzer"] - -[[package]] -name = "control" -version = "0.9.4" -description = "Python Control Systems Library" -optional = true -python-versions = ">=3.8" -files = [ - {file = "control-0.9.4-py3-none-any.whl", hash = "sha256:ab68980abd8d35ae5015ffa090865cbbd926deea7e66d0b9a41cfd12577e63ff"}, - {file = "control-0.9.4.tar.gz", hash = "sha256:0fa57d2216b7ac4e9339c09eab6827660318a641779335864feee940bd19c9ce"}, -] - -[package.dependencies] -matplotlib = "*" -numpy = "*" -scipy = ">=1.3" - -[package.extras] -cvxopt = ["cvxopt (>=1.2.0)"] -slycot = ["slycot (>=0.4.0)"] -test = ["pytest", "pytest-timeout"] - -[[package]] -name = "cycler" -version = "0.12.1" -description = "Composable style cycles" -optional = true -python-versions = ">=3.8" -files = [ - {file = "cycler-0.12.1-py3-none-any.whl", hash = "sha256:85cef7cff222d8644161529808465972e51340599459b8ac3ccbac5a854e0d30"}, - {file = "cycler-0.12.1.tar.gz", hash = "sha256:88bb128f02ba341da8ef447245a9e138fae777f6a23943da4540077d3601eb1c"}, -] - -[package.extras] -docs = ["ipython", "matplotlib", "numpydoc", "sphinx"] -tests = ["pytest", "pytest-cov", "pytest-xdist"] - -[[package]] -name = "dearpygui" -version = "1.11.1" -description = "DearPyGui: A simple Python GUI Toolkit" -optional = true -python-versions = ">=3.7" -files = [ - {file = "dearpygui-1.11.1-cp310-cp310-macosx_10_6_x86_64.whl", hash = "sha256:b668f28aab63d8ad0b2768add4e689bedb7480e8c3390edcce7a0f5d296fd61f"}, - {file = "dearpygui-1.11.1-cp310-cp310-macosx_13_0_arm64.whl", hash = "sha256:39d099b1ca97fd7d36934a5187fc4cd868d4772e504290a70fc95eda03c5125d"}, - {file = "dearpygui-1.11.1-cp310-cp310-manylinux1_x86_64.whl", hash = "sha256:3ba12334d993b653df2d07fe34c93c4ec65e54c022066ba245cd596a18b43a68"}, - {file = "dearpygui-1.11.1-cp310-cp310-win_amd64.whl", hash = "sha256:6cf4c44db1f016ff3eab367f7bde7f169bad5f2f90b974c202808112a69a2b15"}, - {file = "dearpygui-1.11.1-cp311-cp311-macosx_10_6_x86_64.whl", hash = "sha256:cc15cd13c1aeae2847ed9c4b2201169add3efdedf564eb706f5b5896ddaa5d8a"}, - {file = "dearpygui-1.11.1-cp311-cp311-macosx_13_0_arm64.whl", hash = "sha256:9eb7d581863d39543b213252041ed25856acbfa58c57291e6acb6ccbf0c2727b"}, - {file = "dearpygui-1.11.1-cp311-cp311-manylinux1_x86_64.whl", hash = "sha256:564ff3af657f7becd059b6611e162cc9cd8148befaf8aadb10e4fb76d57df3ef"}, - {file = "dearpygui-1.11.1-cp311-cp311-win_amd64.whl", hash = "sha256:ac6e9bde61dcb3cc253da59e70fe2b743d3c3b5791d415eaa8d307f4517048ca"}, - {file = "dearpygui-1.11.1-cp312-cp312-macosx_10_6_x86_64.whl", hash = "sha256:ccf576117ed2159cd66b419458d060923c9dcebe7fe57c65b4f4c4889287845d"}, - {file = "dearpygui-1.11.1-cp312-cp312-macosx_13_0_arm64.whl", hash = "sha256:1d632e1acdaa986a8c32b57112b84685b92d9a41f18580e14d463d7ed7a52673"}, - {file = "dearpygui-1.11.1-cp312-cp312-manylinux1_x86_64.whl", hash = "sha256:ca4f7ba667f64ee682dfcb3399d9d43df6821b2d962b96b4fa4535de5776f538"}, - {file = "dearpygui-1.11.1-cp312-cp312-win_amd64.whl", hash = "sha256:8ce9881a629de72e05ca8b1ce7cefcdd77b624eb7eba6f7d6629848d84a797f6"}, - {file = "dearpygui-1.11.1-cp38-cp38-macosx_10_6_x86_64.whl", hash = "sha256:39011ccb3a3ecfe3ebccfd8c4211c2c1446abd2865cbe4ccb67dc50a7a812bfb"}, - {file = "dearpygui-1.11.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:e1dde63d20ac062530debee001ad649190a7e09622762601454c4191799f13b8"}, - {file = "dearpygui-1.11.1-cp38-cp38-win_amd64.whl", hash = "sha256:23ce7ce8e5ba24d31bd6468cc43b56f8f257ace4dce3bc5fe449c546c340893a"}, - {file = "dearpygui-1.11.1-cp39-cp39-macosx_10_6_x86_64.whl", hash = "sha256:d22285f9a5f1377d87effd1f27020eec3ae0386f7c15a4893809909b82c62b1b"}, - {file = "dearpygui-1.11.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:f632bd94772e00313d0956bb9f9822c3ebcb7aa93f135f09e2fa187f3b06cea8"}, - {file = "dearpygui-1.11.1-cp39-cp39-win_amd64.whl", hash = "sha256:0c7c4849bc674e825750be69ee480450c3589c7d159955032776aaef5e7fda58"}, -] - -[[package]] -name = "debugpy" -version = "1.8.5" -description = "An implementation of the Debug Adapter Protocol for Python" -optional = true -python-versions = ">=3.8" -files = [ - {file = "debugpy-1.8.5-cp310-cp310-macosx_12_0_x86_64.whl", hash = "sha256:7e4d594367d6407a120b76bdaa03886e9eb652c05ba7f87e37418426ad2079f7"}, - {file = "debugpy-1.8.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4413b7a3ede757dc33a273a17d685ea2b0c09dbd312cc03f5534a0fd4d40750a"}, - {file = "debugpy-1.8.5-cp310-cp310-win32.whl", hash = "sha256:dd3811bd63632bb25eda6bd73bea8e0521794cda02be41fa3160eb26fc29e7ed"}, - {file = "debugpy-1.8.5-cp310-cp310-win_amd64.whl", hash = "sha256:b78c1250441ce893cb5035dd6f5fc12db968cc07f91cc06996b2087f7cefdd8e"}, - {file = "debugpy-1.8.5-cp311-cp311-macosx_12_0_universal2.whl", hash = "sha256:606bccba19f7188b6ea9579c8a4f5a5364ecd0bf5a0659c8a5d0e10dcee3032a"}, - {file = "debugpy-1.8.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db9fb642938a7a609a6c865c32ecd0d795d56c1aaa7a7a5722d77855d5e77f2b"}, - {file = "debugpy-1.8.5-cp311-cp311-win32.whl", hash = "sha256:4fbb3b39ae1aa3e5ad578f37a48a7a303dad9a3d018d369bc9ec629c1cfa7408"}, - {file = "debugpy-1.8.5-cp311-cp311-win_amd64.whl", hash = "sha256:345d6a0206e81eb68b1493ce2fbffd57c3088e2ce4b46592077a943d2b968ca3"}, - {file = "debugpy-1.8.5-cp312-cp312-macosx_12_0_universal2.whl", hash = "sha256:5b5c770977c8ec6c40c60d6f58cacc7f7fe5a45960363d6974ddb9b62dbee156"}, - {file = "debugpy-1.8.5-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0a65b00b7cdd2ee0c2cf4c7335fef31e15f1b7056c7fdbce9e90193e1a8c8cb"}, - {file = "debugpy-1.8.5-cp312-cp312-win32.whl", hash = "sha256:c9f7c15ea1da18d2fcc2709e9f3d6de98b69a5b0fff1807fb80bc55f906691f7"}, - {file = "debugpy-1.8.5-cp312-cp312-win_amd64.whl", hash = "sha256:28ced650c974aaf179231668a293ecd5c63c0a671ae6d56b8795ecc5d2f48d3c"}, - {file = "debugpy-1.8.5-cp38-cp38-macosx_12_0_x86_64.whl", hash = "sha256:3df6692351172a42af7558daa5019651f898fc67450bf091335aa8a18fbf6f3a"}, - {file = "debugpy-1.8.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1cd04a73eb2769eb0bfe43f5bfde1215c5923d6924b9b90f94d15f207a402226"}, - {file = "debugpy-1.8.5-cp38-cp38-win32.whl", hash = "sha256:8f913ee8e9fcf9d38a751f56e6de12a297ae7832749d35de26d960f14280750a"}, - {file = "debugpy-1.8.5-cp38-cp38-win_amd64.whl", hash = "sha256:a697beca97dad3780b89a7fb525d5e79f33821a8bc0c06faf1f1289e549743cf"}, - {file = "debugpy-1.8.5-cp39-cp39-macosx_12_0_x86_64.whl", hash = "sha256:0a1029a2869d01cb777216af8c53cda0476875ef02a2b6ff8b2f2c9a4b04176c"}, - {file = "debugpy-1.8.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e84c276489e141ed0b93b0af648eef891546143d6a48f610945416453a8ad406"}, - {file = "debugpy-1.8.5-cp39-cp39-win32.whl", hash = "sha256:ad84b7cde7fd96cf6eea34ff6c4a1b7887e0fe2ea46e099e53234856f9d99a34"}, - {file = "debugpy-1.8.5-cp39-cp39-win_amd64.whl", hash = "sha256:7b0fe36ed9d26cb6836b0a51453653f8f2e347ba7348f2bbfe76bfeb670bfb1c"}, - {file = "debugpy-1.8.5-py2.py3-none-any.whl", hash = "sha256:55919dce65b471eff25901acf82d328bbd5b833526b6c1364bd5133754777a44"}, - {file = "debugpy-1.8.5.zip", hash = "sha256:b2112cfeb34b4507399d298fe7023a16656fc553ed5246536060ca7bd0e668d0"}, -] - -[[package]] -name = "decorator" -version = "5.1.1" -description = "Decorators for Humans" -optional = true -python-versions = ">=3.5" -files = [ - {file = "decorator-5.1.1-py3-none-any.whl", hash = "sha256:b8c3f85900b9dc423225913c5aace94729fe1fa9763b38939a95226f02d37186"}, - {file = "decorator-5.1.1.tar.gz", hash = "sha256:637996211036b6385ef91435e4fae22989472f9d571faba8927ba8253acbc330"}, -] - -[[package]] -name = "defusedxml" -version = "0.7.1" -description = "XML bomb protection for Python stdlib modules" -optional = true -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -files = [ - {file = "defusedxml-0.7.1-py2.py3-none-any.whl", hash = "sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61"}, - {file = "defusedxml-0.7.1.tar.gz", hash = "sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69"}, -] - -[[package]] -name = "docopt" -version = "0.6.2" -description = "Pythonic argument parser, that will make you smile" -optional = true -python-versions = "*" -files = [ - {file = "docopt-0.6.2.tar.gz", hash = "sha256:49b3a825280bd66b3aa83585ef59c4a8c82f2c8a522dbe754a8bc8d08c85c491"}, -] - -[[package]] -name = "et-xmlfile" -version = "1.1.0" -description = "An implementation of lxml.xmlfile for the standard library" -optional = true -python-versions = ">=3.6" -files = [ - {file = "et_xmlfile-1.1.0-py3-none-any.whl", hash = "sha256:a2ba85d1d6a74ef63837eed693bcb89c3f752169b0e3e7ae5b16ca5e1b3deada"}, - {file = "et_xmlfile-1.1.0.tar.gz", hash = "sha256:8eb9e2bc2f8c97e37a2dc85a09ecdcdec9d8a396530a6d5a33b30b9a92da0c5c"}, -] - -[[package]] -name = "exceptiongroup" -version = "1.2.2" -description = "Backport of PEP 654 (exception groups)" -optional = true -python-versions = ">=3.7" -files = [ - {file = "exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b"}, - {file = "exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc"}, -] - -[package.extras] -test = ["pytest (>=6)"] - -[[package]] -name = "executing" -version = "2.0.1" -description = "Get the currently executing AST node of a frame, and other information" -optional = true -python-versions = ">=3.5" -files = [ - {file = "executing-2.0.1-py2.py3-none-any.whl", hash = "sha256:eac49ca94516ccc753f9fb5ce82603156e590b27525a8bc32cce8ae302eb61bc"}, - {file = "executing-2.0.1.tar.gz", hash = "sha256:35afe2ce3affba8ee97f2d69927fa823b08b472b7b994e36a52a964b93d16147"}, -] - -[package.extras] -tests = ["asttokens (>=2.1.0)", "coverage", "coverage-enable-subprocess", "ipython", "littleutils", "pytest", "rich"] - -[[package]] -name = "fastjsonschema" -version = "2.20.0" -description = "Fastest Python implementation of JSON schema" -optional = true -python-versions = "*" -files = [ - {file = "fastjsonschema-2.20.0-py3-none-any.whl", hash = "sha256:5875f0b0fa7a0043a91e93a9b8f793bcbbba9691e7fd83dca95c28ba26d21f0a"}, - {file = "fastjsonschema-2.20.0.tar.gz", hash = "sha256:3d48fc5300ee96f5d116f10fe6f28d938e6008f59a6a025c2649475b87f76a23"}, -] - -[package.extras] -devel = ["colorama", "json-spec", "jsonschema", "pylint", "pytest", "pytest-benchmark", "pytest-cache", "validictory"] - -[[package]] -name = "fonttools" -version = "4.53.1" -description = "Tools to manipulate font files" -optional = true -python-versions = ">=3.8" -files = [ - {file = "fonttools-4.53.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0679a30b59d74b6242909945429dbddb08496935b82f91ea9bf6ad240ec23397"}, - {file = "fonttools-4.53.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e8bf06b94694251861ba7fdeea15c8ec0967f84c3d4143ae9daf42bbc7717fe3"}, - {file = "fonttools-4.53.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b96cd370a61f4d083c9c0053bf634279b094308d52fdc2dd9a22d8372fdd590d"}, - {file = "fonttools-4.53.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a1c7c5aa18dd3b17995898b4a9b5929d69ef6ae2af5b96d585ff4005033d82f0"}, - {file = "fonttools-4.53.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:e013aae589c1c12505da64a7d8d023e584987e51e62006e1bb30d72f26522c41"}, - {file = "fonttools-4.53.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:9efd176f874cb6402e607e4cc9b4a9cd584d82fc34a4b0c811970b32ba62501f"}, - {file = "fonttools-4.53.1-cp310-cp310-win32.whl", hash = "sha256:c8696544c964500aa9439efb6761947393b70b17ef4e82d73277413f291260a4"}, - {file = "fonttools-4.53.1-cp310-cp310-win_amd64.whl", hash = "sha256:8959a59de5af6d2bec27489e98ef25a397cfa1774b375d5787509c06659b3671"}, - {file = "fonttools-4.53.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:da33440b1413bad53a8674393c5d29ce64d8c1a15ef8a77c642ffd900d07bfe1"}, - {file = "fonttools-4.53.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5ff7e5e9bad94e3a70c5cd2fa27f20b9bb9385e10cddab567b85ce5d306ea923"}, - {file = "fonttools-4.53.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c6e7170d675d12eac12ad1a981d90f118c06cf680b42a2d74c6c931e54b50719"}, - {file = "fonttools-4.53.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bee32ea8765e859670c4447b0817514ca79054463b6b79784b08a8df3a4d78e3"}, - {file = "fonttools-4.53.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6e08f572625a1ee682115223eabebc4c6a2035a6917eac6f60350aba297ccadb"}, - {file = "fonttools-4.53.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b21952c092ffd827504de7e66b62aba26fdb5f9d1e435c52477e6486e9d128b2"}, - {file = "fonttools-4.53.1-cp311-cp311-win32.whl", hash = "sha256:9dfdae43b7996af46ff9da520998a32b105c7f098aeea06b2226b30e74fbba88"}, - {file = "fonttools-4.53.1-cp311-cp311-win_amd64.whl", hash = "sha256:d4d0096cb1ac7a77b3b41cd78c9b6bc4a400550e21dc7a92f2b5ab53ed74eb02"}, - {file = "fonttools-4.53.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:d92d3c2a1b39631a6131c2fa25b5406855f97969b068e7e08413325bc0afba58"}, - {file = "fonttools-4.53.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3b3c8ebafbee8d9002bd8f1195d09ed2bd9ff134ddec37ee8f6a6375e6a4f0e8"}, - {file = "fonttools-4.53.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:32f029c095ad66c425b0ee85553d0dc326d45d7059dbc227330fc29b43e8ba60"}, - {file = "fonttools-4.53.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10f5e6c3510b79ea27bb1ebfcc67048cde9ec67afa87c7dd7efa5c700491ac7f"}, - {file = "fonttools-4.53.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:f677ce218976496a587ab17140da141557beb91d2a5c1a14212c994093f2eae2"}, - {file = "fonttools-4.53.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:9e6ceba2a01b448e36754983d376064730690401da1dd104ddb543519470a15f"}, - {file = "fonttools-4.53.1-cp312-cp312-win32.whl", hash = "sha256:791b31ebbc05197d7aa096bbc7bd76d591f05905d2fd908bf103af4488e60670"}, - {file = "fonttools-4.53.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ed170b5e17da0264b9f6fae86073be3db15fa1bd74061c8331022bca6d09bab"}, - {file = "fonttools-4.53.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:c818c058404eb2bba05e728d38049438afd649e3c409796723dfc17cd3f08749"}, - {file = "fonttools-4.53.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:651390c3b26b0c7d1f4407cad281ee7a5a85a31a110cbac5269de72a51551ba2"}, - {file = "fonttools-4.53.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e54f1bba2f655924c1138bbc7fa91abd61f45c68bd65ab5ed985942712864bbb"}, - {file = "fonttools-4.53.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c9cd19cf4fe0595ebdd1d4915882b9440c3a6d30b008f3cc7587c1da7b95be5f"}, - {file = "fonttools-4.53.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:2af40ae9cdcb204fc1d8f26b190aa16534fcd4f0df756268df674a270eab575d"}, - {file = "fonttools-4.53.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:35250099b0cfb32d799fb5d6c651220a642fe2e3c7d2560490e6f1d3f9ae9169"}, - {file = "fonttools-4.53.1-cp38-cp38-win32.whl", hash = "sha256:f08df60fbd8d289152079a65da4e66a447efc1d5d5a4d3f299cdd39e3b2e4a7d"}, - {file = "fonttools-4.53.1-cp38-cp38-win_amd64.whl", hash = "sha256:7b6b35e52ddc8fb0db562133894e6ef5b4e54e1283dff606fda3eed938c36fc8"}, - {file = "fonttools-4.53.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:75a157d8d26c06e64ace9df037ee93a4938a4606a38cb7ffaf6635e60e253b7a"}, - {file = "fonttools-4.53.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4824c198f714ab5559c5be10fd1adf876712aa7989882a4ec887bf1ef3e00e31"}, - {file = "fonttools-4.53.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:becc5d7cb89c7b7afa8321b6bb3dbee0eec2b57855c90b3e9bf5fb816671fa7c"}, - {file = "fonttools-4.53.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:84ec3fb43befb54be490147b4a922b5314e16372a643004f182babee9f9c3407"}, - {file = "fonttools-4.53.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:73379d3ffdeecb376640cd8ed03e9d2d0e568c9d1a4e9b16504a834ebadc2dfb"}, - {file = "fonttools-4.53.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:02569e9a810f9d11f4ae82c391ebc6fb5730d95a0657d24d754ed7763fb2d122"}, - {file = "fonttools-4.53.1-cp39-cp39-win32.whl", hash = "sha256:aae7bd54187e8bf7fd69f8ab87b2885253d3575163ad4d669a262fe97f0136cb"}, - {file = "fonttools-4.53.1-cp39-cp39-win_amd64.whl", hash = "sha256:e5b708073ea3d684235648786f5f6153a48dc8762cdfe5563c57e80787c29fbb"}, - {file = "fonttools-4.53.1-py3-none-any.whl", hash = "sha256:f1f8758a2ad110bd6432203a344269f445a2907dc24ef6bccfd0ac4e14e0d71d"}, - {file = "fonttools-4.53.1.tar.gz", hash = "sha256:e128778a8e9bc11159ce5447f76766cefbd876f44bd79aff030287254e4752c4"}, -] - -[package.extras] -all = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "fs (>=2.2.0,<3)", "lxml (>=4.0)", "lz4 (>=1.7.4.2)", "matplotlib", "munkres", "pycairo", "scipy", "skia-pathops (>=0.5.0)", "sympy", "uharfbuzz (>=0.23.0)", "unicodedata2 (>=15.1.0)", "xattr", "zopfli (>=0.1.4)"] -graphite = ["lz4 (>=1.7.4.2)"] -interpolatable = ["munkres", "pycairo", "scipy"] -lxml = ["lxml (>=4.0)"] -pathops = ["skia-pathops (>=0.5.0)"] -plot = ["matplotlib"] -repacker = ["uharfbuzz (>=0.23.0)"] -symfont = ["sympy"] -type1 = ["xattr"] -ufo = ["fs (>=2.2.0,<3)"] -unicode = ["unicodedata2 (>=15.1.0)"] -woff = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "zopfli (>=0.1.4)"] - -[[package]] -name = "fqdn" -version = "1.5.1" -description = "Validates fully-qualified domain names against RFC 1123, so that they are acceptable to modern bowsers" -optional = true -python-versions = ">=2.7, !=3.0, !=3.1, !=3.2, !=3.3, !=3.4, <4" -files = [ - {file = "fqdn-1.5.1-py3-none-any.whl", hash = "sha256:3a179af3761e4df6eb2e026ff9e1a3033d3587bf980a0b1b2e1e5d08d7358014"}, - {file = "fqdn-1.5.1.tar.gz", hash = "sha256:105ed3677e767fb5ca086a0c1f4bb66ebc3c100be518f0e0d755d9eae164d89f"}, -] - -[[package]] -name = "h11" -version = "0.14.0" -description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1" -optional = true -python-versions = ">=3.7" -files = [ - {file = "h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761"}, - {file = "h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d"}, -] - -[[package]] -name = "httpcore" -version = "1.0.5" -description = "A minimal low-level HTTP client." -optional = true -python-versions = ">=3.8" -files = [ - {file = "httpcore-1.0.5-py3-none-any.whl", hash = "sha256:421f18bac248b25d310f3cacd198d55b8e6125c107797b609ff9b7a6ba7991b5"}, - {file = "httpcore-1.0.5.tar.gz", hash = "sha256:34a38e2f9291467ee3b44e89dd52615370e152954ba21721378a87b2960f7a61"}, -] - -[package.dependencies] -certifi = "*" -h11 = ">=0.13,<0.15" - -[package.extras] -asyncio = ["anyio (>=4.0,<5.0)"] -http2 = ["h2 (>=3,<5)"] -socks = ["socksio (==1.*)"] -trio = ["trio (>=0.22.0,<0.26.0)"] - -[[package]] -name = "httpx" -version = "0.27.0" -description = "The next generation HTTP client." -optional = true -python-versions = ">=3.8" -files = [ - {file = "httpx-0.27.0-py3-none-any.whl", hash = "sha256:71d5465162c13681bff01ad59b2cc68dd838ea1f10e51574bac27103f00c91a5"}, - {file = "httpx-0.27.0.tar.gz", hash = "sha256:a0cb88a46f32dc874e04ee956e4c2764aba2aa228f650b06788ba6bda2962ab5"}, -] - -[package.dependencies] -anyio = "*" -certifi = "*" -httpcore = "==1.*" -idna = "*" -sniffio = "*" - -[package.extras] -brotli = ["brotli", "brotlicffi"] -cli = ["click (==8.*)", "pygments (==2.*)", "rich (>=10,<14)"] -http2 = ["h2 (>=3,<5)"] -socks = ["socksio (==1.*)"] - -[[package]] -name = "idna" -version = "3.7" -description = "Internationalized Domain Names in Applications (IDNA)" -optional = true -python-versions = ">=3.5" -files = [ - {file = "idna-3.7-py3-none-any.whl", hash = "sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0"}, - {file = "idna-3.7.tar.gz", hash = "sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc"}, -] - -[[package]] -name = "importlib-metadata" -version = "8.2.0" -description = "Read metadata from Python packages" -optional = true -python-versions = ">=3.8" -files = [ - {file = "importlib_metadata-8.2.0-py3-none-any.whl", hash = "sha256:11901fa0c2f97919b288679932bb64febaeacf289d18ac84dd68cb2e74213369"}, - {file = "importlib_metadata-8.2.0.tar.gz", hash = "sha256:72e8d4399996132204f9a16dcc751af254a48f8d1b20b9ff0f98d4a8f901e73d"}, -] - -[package.dependencies] -zipp = ">=0.5" - -[package.extras] -doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] -perf = ["ipython"] -test = ["flufl.flake8", "importlib-resources (>=1.3)", "jaraco.test (>=5.4)", "packaging", "pyfakefs", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy", "pytest-perf (>=0.9.2)", "pytest-ruff (>=0.2.1)"] - -[[package]] -name = "importlib-resources" -version = "6.4.2" -description = "Read resources from Python packages" -optional = true -python-versions = ">=3.8" -files = [ - {file = "importlib_resources-6.4.2-py3-none-any.whl", hash = "sha256:8bba8c54a8a3afaa1419910845fa26ebd706dc716dd208d9b158b4b6966f5c5c"}, - {file = "importlib_resources-6.4.2.tar.gz", hash = "sha256:6cbfbefc449cc6e2095dd184691b7a12a04f40bc75dd4c55d31c34f174cdf57a"}, -] - -[package.dependencies] -zipp = {version = ">=3.1.0", markers = "python_version < \"3.10\""} - -[package.extras] -doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] -test = ["jaraco.test (>=5.4)", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy", "pytest-ruff (>=0.2.1)", "zipp (>=3.17)"] - -[[package]] -name = "ipykernel" -version = "6.29.5" -description = "IPython Kernel for Jupyter" -optional = true -python-versions = ">=3.8" -files = [ - {file = "ipykernel-6.29.5-py3-none-any.whl", hash = "sha256:afdb66ba5aa354b09b91379bac28ae4afebbb30e8b39510c9690afb7a10421b5"}, - {file = "ipykernel-6.29.5.tar.gz", hash = "sha256:f093a22c4a40f8828f8e330a9c297cb93dcab13bd9678ded6de8e5cf81c56215"}, -] - -[package.dependencies] -appnope = {version = "*", markers = "platform_system == \"Darwin\""} -comm = ">=0.1.1" -debugpy = ">=1.6.5" -ipython = ">=7.23.1" -jupyter-client = ">=6.1.12" -jupyter-core = ">=4.12,<5.0.dev0 || >=5.1.dev0" -matplotlib-inline = ">=0.1" -nest-asyncio = "*" -packaging = "*" -psutil = "*" -pyzmq = ">=24" -tornado = ">=6.1" -traitlets = ">=5.4.0" - -[package.extras] -cov = ["coverage[toml]", "curio", "matplotlib", "pytest-cov", "trio"] -docs = ["myst-parser", "pydata-sphinx-theme", "sphinx", "sphinx-autodoc-typehints", "sphinxcontrib-github-alt", "sphinxcontrib-spelling", "trio"] -pyqt5 = ["pyqt5"] -pyside6 = ["pyside6"] -test = ["flaky", "ipyparallel", "pre-commit", "pytest (>=7.0)", "pytest-asyncio (>=0.23.5)", "pytest-cov", "pytest-timeout"] - -[[package]] -name = "ipython" -version = "8.18.1" -description = "IPython: Productive Interactive Computing" -optional = true -python-versions = ">=3.9" -files = [ - {file = "ipython-8.18.1-py3-none-any.whl", hash = "sha256:e8267419d72d81955ec1177f8a29aaa90ac80ad647499201119e2f05e99aa397"}, - {file = "ipython-8.18.1.tar.gz", hash = "sha256:ca6f079bb33457c66e233e4580ebfc4128855b4cf6370dddd73842a9563e8a27"}, -] - -[package.dependencies] -colorama = {version = "*", markers = "sys_platform == \"win32\""} -decorator = "*" -exceptiongroup = {version = "*", markers = "python_version < \"3.11\""} -jedi = ">=0.16" -matplotlib-inline = "*" -pexpect = {version = ">4.3", markers = "sys_platform != \"win32\""} -prompt-toolkit = ">=3.0.41,<3.1.0" -pygments = ">=2.4.0" -stack-data = "*" -traitlets = ">=5" -typing-extensions = {version = "*", markers = "python_version < \"3.10\""} - -[package.extras] -all = ["black", "curio", "docrepr", "exceptiongroup", "ipykernel", "ipyparallel", "ipywidgets", "matplotlib", "matplotlib (!=3.2.0)", "nbconvert", "nbformat", "notebook", "numpy (>=1.22)", "pandas", "pickleshare", "pytest (<7)", "pytest (<7.1)", "pytest-asyncio (<0.22)", "qtconsole", "setuptools (>=18.5)", "sphinx (>=1.3)", "sphinx-rtd-theme", "stack-data", "testpath", "trio", "typing-extensions"] -black = ["black"] -doc = ["docrepr", "exceptiongroup", "ipykernel", "matplotlib", "pickleshare", "pytest (<7)", "pytest (<7.1)", "pytest-asyncio (<0.22)", "setuptools (>=18.5)", "sphinx (>=1.3)", "sphinx-rtd-theme", "stack-data", "testpath", "typing-extensions"] -kernel = ["ipykernel"] -nbconvert = ["nbconvert"] -nbformat = ["nbformat"] -notebook = ["ipywidgets", "notebook"] -parallel = ["ipyparallel"] -qtconsole = ["qtconsole"] -test = ["pickleshare", "pytest (<7.1)", "pytest-asyncio (<0.22)", "testpath"] -test-extra = ["curio", "matplotlib (!=3.2.0)", "nbformat", "numpy (>=1.22)", "pandas", "pickleshare", "pytest (<7.1)", "pytest-asyncio (<0.22)", "testpath", "trio"] - -[[package]] -name = "ipywidgets" -version = "8.1.3" -description = "Jupyter interactive widgets" -optional = true -python-versions = ">=3.7" -files = [ - {file = "ipywidgets-8.1.3-py3-none-any.whl", hash = "sha256:efafd18f7a142248f7cb0ba890a68b96abd4d6e88ddbda483c9130d12667eaf2"}, - {file = "ipywidgets-8.1.3.tar.gz", hash = "sha256:f5f9eeaae082b1823ce9eac2575272952f40d748893972956dc09700a6392d9c"}, -] - -[package.dependencies] -comm = ">=0.1.3" -ipython = ">=6.1.0" -jupyterlab-widgets = ">=3.0.11,<3.1.0" -traitlets = ">=4.3.1" -widgetsnbextension = ">=4.0.11,<4.1.0" - -[package.extras] -test = ["ipykernel", "jsonschema", "pytest (>=3.6.0)", "pytest-cov", "pytz"] - -[[package]] -name = "isoduration" -version = "20.11.0" -description = "Operations with ISO 8601 durations" -optional = true -python-versions = ">=3.7" -files = [ - {file = "isoduration-20.11.0-py3-none-any.whl", hash = "sha256:b2904c2a4228c3d44f409c8ae8e2370eb21a26f7ac2ec5446df141dde3452042"}, - {file = "isoduration-20.11.0.tar.gz", hash = "sha256:ac2f9015137935279eac671f94f89eb00584f940f5dc49462a0c4ee692ba1bd9"}, -] - -[package.dependencies] -arrow = ">=0.15.0" - -[[package]] -name = "jedi" -version = "0.19.1" -description = "An autocompletion tool for Python that can be used for text editors." -optional = true -python-versions = ">=3.6" -files = [ - {file = "jedi-0.19.1-py2.py3-none-any.whl", hash = "sha256:e983c654fe5c02867aef4cdfce5a2fbb4a50adc0af145f70504238f18ef5e7e0"}, - {file = "jedi-0.19.1.tar.gz", hash = "sha256:cf0496f3651bc65d7174ac1b7d043eff454892c708a87d1b683e57b569927ffd"}, -] - -[package.dependencies] -parso = ">=0.8.3,<0.9.0" - -[package.extras] -docs = ["Jinja2 (==2.11.3)", "MarkupSafe (==1.1.1)", "Pygments (==2.8.1)", "alabaster (==0.7.12)", "babel (==2.9.1)", "chardet (==4.0.0)", "commonmark (==0.8.1)", "docutils (==0.17.1)", "future (==0.18.2)", "idna (==2.10)", "imagesize (==1.2.0)", "mock (==1.0.1)", "packaging (==20.9)", "pyparsing (==2.4.7)", "pytz (==2021.1)", "readthedocs-sphinx-ext (==2.1.4)", "recommonmark (==0.5.0)", "requests (==2.25.1)", "six (==1.15.0)", "snowballstemmer (==2.1.0)", "sphinx (==1.8.5)", "sphinx-rtd-theme (==0.4.3)", "sphinxcontrib-serializinghtml (==1.1.4)", "sphinxcontrib-websupport (==1.2.4)", "urllib3 (==1.26.4)"] -qa = ["flake8 (==5.0.4)", "mypy (==0.971)", "types-setuptools (==67.2.0.1)"] -testing = ["Django", "attrs", "colorama", "docopt", "pytest (<7.0.0)"] - -[[package]] -name = "jinja2" -version = "3.1.4" -description = "A very fast and expressive template engine." -optional = true -python-versions = ">=3.7" -files = [ - {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, - {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, -] - -[package.dependencies] -MarkupSafe = ">=2.0" - -[package.extras] -i18n = ["Babel (>=2.7)"] - -[[package]] -name = "json5" -version = "0.9.25" -description = "A Python implementation of the JSON5 data format." -optional = true -python-versions = ">=3.8" -files = [ - {file = "json5-0.9.25-py3-none-any.whl", hash = "sha256:34ed7d834b1341a86987ed52f3f76cd8ee184394906b6e22a1e0deb9ab294e8f"}, - {file = "json5-0.9.25.tar.gz", hash = "sha256:548e41b9be043f9426776f05df8635a00fe06104ea51ed24b67f908856e151ae"}, -] - -[[package]] -name = "jsonpointer" -version = "3.0.0" -description = "Identify specific nodes in a JSON document (RFC 6901)" -optional = true -python-versions = ">=3.7" -files = [ - {file = "jsonpointer-3.0.0-py2.py3-none-any.whl", hash = "sha256:13e088adc14fca8b6aa8177c044e12701e6ad4b28ff10e65f2267a90109c9942"}, - {file = "jsonpointer-3.0.0.tar.gz", hash = "sha256:2b2d729f2091522d61c3b31f82e11870f60b68f43fbc705cb76bf4b832af59ef"}, -] - -[[package]] -name = "jsonschema" -version = "4.23.0" -description = "An implementation of JSON Schema validation for Python" -optional = true -python-versions = ">=3.8" -files = [ - {file = "jsonschema-4.23.0-py3-none-any.whl", hash = "sha256:fbadb6f8b144a8f8cf9f0b89ba94501d143e50411a1278633f56a7acf7fd5566"}, - {file = "jsonschema-4.23.0.tar.gz", hash = "sha256:d71497fef26351a33265337fa77ffeb82423f3ea21283cd9467bb03999266bc4"}, -] - -[package.dependencies] -attrs = ">=22.2.0" -fqdn = {version = "*", optional = true, markers = "extra == \"format-nongpl\""} -idna = {version = "*", optional = true, markers = "extra == \"format-nongpl\""} -isoduration = {version = "*", optional = true, markers = "extra == \"format-nongpl\""} -jsonpointer = {version = ">1.13", optional = true, markers = "extra == \"format-nongpl\""} -jsonschema-specifications = ">=2023.03.6" -referencing = ">=0.28.4" -rfc3339-validator = {version = "*", optional = true, markers = "extra == \"format-nongpl\""} -rfc3986-validator = {version = ">0.1.0", optional = true, markers = "extra == \"format-nongpl\""} -rpds-py = ">=0.7.1" -uri-template = {version = "*", optional = true, markers = "extra == \"format-nongpl\""} -webcolors = {version = ">=24.6.0", optional = true, markers = "extra == \"format-nongpl\""} - -[package.extras] -format = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3987", "uri-template", "webcolors (>=1.11)"] -format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "uri-template", "webcolors (>=24.6.0)"] - -[[package]] -name = "jsonschema-specifications" -version = "2023.12.1" -description = "The JSON Schema meta-schemas and vocabularies, exposed as a Registry" -optional = true -python-versions = ">=3.8" -files = [ - {file = "jsonschema_specifications-2023.12.1-py3-none-any.whl", hash = "sha256:87e4fdf3a94858b8a2ba2778d9ba57d8a9cafca7c7489c46ba0d30a8bc6a9c3c"}, - {file = "jsonschema_specifications-2023.12.1.tar.gz", hash = "sha256:48a76787b3e70f5ed53f1160d2b81f586e4ca6d1548c5de7085d1682674764cc"}, -] - -[package.dependencies] -referencing = ">=0.31.0" - -[[package]] -name = "jupyter" -version = "1.0.0" -description = "Jupyter metapackage. Install all the Jupyter components in one go." -optional = true -python-versions = "*" -files = [ - {file = "jupyter-1.0.0-py2.py3-none-any.whl", hash = "sha256:5b290f93b98ffbc21c0c7e749f054b3267782166d72fa5e3ed1ed4eaf34a2b78"}, - {file = "jupyter-1.0.0.tar.gz", hash = "sha256:d9dc4b3318f310e34c82951ea5d6683f67bed7def4b259fafbfe4f1beb1d8e5f"}, - {file = "jupyter-1.0.0.zip", hash = "sha256:3e1f86076bbb7c8c207829390305a2b1fe836d471ed54be66a3b8c41e7f46cc7"}, -] - -[package.dependencies] -ipykernel = "*" -ipywidgets = "*" -jupyter-console = "*" -nbconvert = "*" -notebook = "*" -qtconsole = "*" - -[[package]] -name = "jupyter-client" -version = "8.6.2" -description = "Jupyter protocol implementation and client libraries" -optional = true -python-versions = ">=3.8" -files = [ - {file = "jupyter_client-8.6.2-py3-none-any.whl", hash = "sha256:50cbc5c66fd1b8f65ecb66bc490ab73217993632809b6e505687de18e9dea39f"}, - {file = "jupyter_client-8.6.2.tar.gz", hash = "sha256:2bda14d55ee5ba58552a8c53ae43d215ad9868853489213f37da060ced54d8df"}, -] - -[package.dependencies] -importlib-metadata = {version = ">=4.8.3", markers = "python_version < \"3.10\""} -jupyter-core = ">=4.12,<5.0.dev0 || >=5.1.dev0" -python-dateutil = ">=2.8.2" -pyzmq = ">=23.0" -tornado = ">=6.2" -traitlets = ">=5.3" - -[package.extras] -docs = ["ipykernel", "myst-parser", "pydata-sphinx-theme", "sphinx (>=4)", "sphinx-autodoc-typehints", "sphinxcontrib-github-alt", "sphinxcontrib-spelling"] -test = ["coverage", "ipykernel (>=6.14)", "mypy", "paramiko", "pre-commit", "pytest (<8.2.0)", "pytest-cov", "pytest-jupyter[client] (>=0.4.1)", "pytest-timeout"] - -[[package]] -name = "jupyter-console" -version = "6.6.3" -description = "Jupyter terminal console" -optional = true -python-versions = ">=3.7" -files = [ - {file = "jupyter_console-6.6.3-py3-none-any.whl", hash = "sha256:309d33409fcc92ffdad25f0bcdf9a4a9daa61b6f341177570fdac03de5352485"}, - {file = "jupyter_console-6.6.3.tar.gz", hash = "sha256:566a4bf31c87adbfadf22cdf846e3069b59a71ed5da71d6ba4d8aaad14a53539"}, -] - -[package.dependencies] -ipykernel = ">=6.14" -ipython = "*" -jupyter-client = ">=7.0.0" -jupyter-core = ">=4.12,<5.0.dev0 || >=5.1.dev0" -prompt-toolkit = ">=3.0.30" -pygments = "*" -pyzmq = ">=17" -traitlets = ">=5.4" - -[package.extras] -test = ["flaky", "pexpect", "pytest"] - -[[package]] -name = "jupyter-core" -version = "5.7.2" -description = "Jupyter core package. A base package on which Jupyter projects rely." -optional = true -python-versions = ">=3.8" -files = [ - {file = "jupyter_core-5.7.2-py3-none-any.whl", hash = "sha256:4f7315d2f6b4bcf2e3e7cb6e46772eba760ae459cd1f59d29eb57b0a01bd7409"}, - {file = "jupyter_core-5.7.2.tar.gz", hash = "sha256:aa5f8d32bbf6b431ac830496da7392035d6f61b4f54872f15c4bd2a9c3f536d9"}, -] - -[package.dependencies] -platformdirs = ">=2.5" -pywin32 = {version = ">=300", markers = "sys_platform == \"win32\" and platform_python_implementation != \"PyPy\""} -traitlets = ">=5.3" - -[package.extras] -docs = ["myst-parser", "pydata-sphinx-theme", "sphinx-autodoc-typehints", "sphinxcontrib-github-alt", "sphinxcontrib-spelling", "traitlets"] -test = ["ipykernel", "pre-commit", "pytest (<8)", "pytest-cov", "pytest-timeout"] - -[[package]] -name = "jupyter-events" -version = "0.10.0" -description = "Jupyter Event System library" -optional = true -python-versions = ">=3.8" -files = [ - {file = "jupyter_events-0.10.0-py3-none-any.whl", hash = "sha256:4b72130875e59d57716d327ea70d3ebc3af1944d3717e5a498b8a06c6c159960"}, - {file = "jupyter_events-0.10.0.tar.gz", hash = "sha256:670b8229d3cc882ec782144ed22e0d29e1c2d639263f92ca8383e66682845e22"}, -] - -[package.dependencies] -jsonschema = {version = ">=4.18.0", extras = ["format-nongpl"]} -python-json-logger = ">=2.0.4" -pyyaml = ">=5.3" -referencing = "*" -rfc3339-validator = "*" -rfc3986-validator = ">=0.1.1" -traitlets = ">=5.3" - -[package.extras] -cli = ["click", "rich"] -docs = ["jupyterlite-sphinx", "myst-parser", "pydata-sphinx-theme", "sphinxcontrib-spelling"] -test = ["click", "pre-commit", "pytest (>=7.0)", "pytest-asyncio (>=0.19.0)", "pytest-console-scripts", "rich"] - -[[package]] -name = "jupyter-lsp" -version = "2.2.5" -description = "Multi-Language Server WebSocket proxy for Jupyter Notebook/Lab server" -optional = true -python-versions = ">=3.8" -files = [ - {file = "jupyter-lsp-2.2.5.tar.gz", hash = "sha256:793147a05ad446f809fd53ef1cd19a9f5256fd0a2d6b7ce943a982cb4f545001"}, - {file = "jupyter_lsp-2.2.5-py3-none-any.whl", hash = "sha256:45fbddbd505f3fbfb0b6cb2f1bc5e15e83ab7c79cd6e89416b248cb3c00c11da"}, -] - -[package.dependencies] -importlib-metadata = {version = ">=4.8.3", markers = "python_version < \"3.10\""} -jupyter-server = ">=1.1.2" - -[[package]] -name = "jupyter-server" -version = "2.14.2" -description = "The backend—i.e. core services, APIs, and REST endpoints—to Jupyter web applications." -optional = true -python-versions = ">=3.8" -files = [ - {file = "jupyter_server-2.14.2-py3-none-any.whl", hash = "sha256:47ff506127c2f7851a17bf4713434208fc490955d0e8632e95014a9a9afbeefd"}, - {file = "jupyter_server-2.14.2.tar.gz", hash = "sha256:66095021aa9638ced276c248b1d81862e4c50f292d575920bbe960de1c56b12b"}, -] - -[package.dependencies] -anyio = ">=3.1.0" -argon2-cffi = ">=21.1" -jinja2 = ">=3.0.3" -jupyter-client = ">=7.4.4" -jupyter-core = ">=4.12,<5.0.dev0 || >=5.1.dev0" -jupyter-events = ">=0.9.0" -jupyter-server-terminals = ">=0.4.4" -nbconvert = ">=6.4.4" -nbformat = ">=5.3.0" -overrides = ">=5.0" -packaging = ">=22.0" -prometheus-client = ">=0.9" -pywinpty = {version = ">=2.0.1", markers = "os_name == \"nt\""} -pyzmq = ">=24" -send2trash = ">=1.8.2" -terminado = ">=0.8.3" -tornado = ">=6.2.0" -traitlets = ">=5.6.0" -websocket-client = ">=1.7" - -[package.extras] -docs = ["ipykernel", "jinja2", "jupyter-client", "myst-parser", "nbformat", "prometheus-client", "pydata-sphinx-theme", "send2trash", "sphinx-autodoc-typehints", "sphinxcontrib-github-alt", "sphinxcontrib-openapi (>=0.8.0)", "sphinxcontrib-spelling", "sphinxemoji", "tornado", "typing-extensions"] -test = ["flaky", "ipykernel", "pre-commit", "pytest (>=7.0,<9)", "pytest-console-scripts", "pytest-jupyter[server] (>=0.7)", "pytest-timeout", "requests"] - -[[package]] -name = "jupyter-server-terminals" -version = "0.5.3" -description = "A Jupyter Server Extension Providing Terminals." -optional = true -python-versions = ">=3.8" -files = [ - {file = "jupyter_server_terminals-0.5.3-py3-none-any.whl", hash = "sha256:41ee0d7dc0ebf2809c668e0fc726dfaf258fcd3e769568996ca731b6194ae9aa"}, - {file = "jupyter_server_terminals-0.5.3.tar.gz", hash = "sha256:5ae0295167220e9ace0edcfdb212afd2b01ee8d179fe6f23c899590e9b8a5269"}, -] - -[package.dependencies] -pywinpty = {version = ">=2.0.3", markers = "os_name == \"nt\""} -terminado = ">=0.8.3" - -[package.extras] -docs = ["jinja2", "jupyter-server", "mistune (<4.0)", "myst-parser", "nbformat", "packaging", "pydata-sphinx-theme", "sphinxcontrib-github-alt", "sphinxcontrib-openapi", "sphinxcontrib-spelling", "sphinxemoji", "tornado"] -test = ["jupyter-server (>=2.0.0)", "pytest (>=7.0)", "pytest-jupyter[server] (>=0.5.3)", "pytest-timeout"] - -[[package]] -name = "jupyterlab" -version = "4.2.4" -description = "JupyterLab computational environment" -optional = true -python-versions = ">=3.8" -files = [ - {file = "jupyterlab-4.2.4-py3-none-any.whl", hash = "sha256:807a7ec73637744f879e112060d4b9d9ebe028033b7a429b2d1f4fc523d00245"}, - {file = "jupyterlab-4.2.4.tar.gz", hash = "sha256:343a979fb9582fd08c8511823e320703281cd072a0049bcdafdc7afeda7f2537"}, -] - -[package.dependencies] -async-lru = ">=1.0.0" -httpx = ">=0.25.0" -importlib-metadata = {version = ">=4.8.3", markers = "python_version < \"3.10\""} -ipykernel = ">=6.5.0" -jinja2 = ">=3.0.3" -jupyter-core = "*" -jupyter-lsp = ">=2.0.0" -jupyter-server = ">=2.4.0,<3" -jupyterlab-server = ">=2.27.1,<3" -notebook-shim = ">=0.2" -packaging = "*" -setuptools = ">=40.1.0" -tomli = {version = ">=1.2.2", markers = "python_version < \"3.11\""} -tornado = ">=6.2.0" -traitlets = "*" - -[package.extras] -dev = ["build", "bump2version", "coverage", "hatch", "pre-commit", "pytest-cov", "ruff (==0.3.5)"] -docs = ["jsx-lexer", "myst-parser", "pydata-sphinx-theme (>=0.13.0)", "pytest", "pytest-check-links", "pytest-jupyter", "sphinx (>=1.8,<7.3.0)", "sphinx-copybutton"] -docs-screenshots = ["altair (==5.3.0)", "ipython (==8.16.1)", "ipywidgets (==8.1.2)", "jupyterlab-geojson (==3.4.0)", "jupyterlab-language-pack-zh-cn (==4.1.post2)", "matplotlib (==3.8.3)", "nbconvert (>=7.0.0)", "pandas (==2.2.1)", "scipy (==1.12.0)", "vega-datasets (==0.9.0)"] -test = ["coverage", "pytest (>=7.0)", "pytest-check-links (>=0.7)", "pytest-console-scripts", "pytest-cov", "pytest-jupyter (>=0.5.3)", "pytest-timeout", "pytest-tornasync", "requests", "requests-cache", "virtualenv"] -upgrade-extension = ["copier (>=9,<10)", "jinja2-time (<0.3)", "pydantic (<3.0)", "pyyaml-include (<3.0)", "tomli-w (<2.0)"] - -[[package]] -name = "jupyterlab-pygments" -version = "0.3.0" -description = "Pygments theme using JupyterLab CSS variables" -optional = true -python-versions = ">=3.8" -files = [ - {file = "jupyterlab_pygments-0.3.0-py3-none-any.whl", hash = "sha256:841a89020971da1d8693f1a99997aefc5dc424bb1b251fd6322462a1b8842780"}, - {file = "jupyterlab_pygments-0.3.0.tar.gz", hash = "sha256:721aca4d9029252b11cfa9d185e5b5af4d54772bb8072f9b7036f4170054d35d"}, -] - -[[package]] -name = "jupyterlab-server" -version = "2.27.3" -description = "A set of server components for JupyterLab and JupyterLab like applications." -optional = true -python-versions = ">=3.8" -files = [ - {file = "jupyterlab_server-2.27.3-py3-none-any.whl", hash = "sha256:e697488f66c3db49df675158a77b3b017520d772c6e1548c7d9bcc5df7944ee4"}, - {file = "jupyterlab_server-2.27.3.tar.gz", hash = "sha256:eb36caca59e74471988f0ae25c77945610b887f777255aa21f8065def9e51ed4"}, -] - -[package.dependencies] -babel = ">=2.10" -importlib-metadata = {version = ">=4.8.3", markers = "python_version < \"3.10\""} -jinja2 = ">=3.0.3" -json5 = ">=0.9.0" -jsonschema = ">=4.18.0" -jupyter-server = ">=1.21,<3" -packaging = ">=21.3" -requests = ">=2.31" - -[package.extras] -docs = ["autodoc-traits", "jinja2 (<3.2.0)", "mistune (<4)", "myst-parser", "pydata-sphinx-theme", "sphinx", "sphinx-copybutton", "sphinxcontrib-openapi (>0.8)"] -openapi = ["openapi-core (>=0.18.0,<0.19.0)", "ruamel-yaml"] -test = ["hatch", "ipykernel", "openapi-core (>=0.18.0,<0.19.0)", "openapi-spec-validator (>=0.6.0,<0.8.0)", "pytest (>=7.0,<8)", "pytest-console-scripts", "pytest-cov", "pytest-jupyter[server] (>=0.6.2)", "pytest-timeout", "requests-mock", "ruamel-yaml", "sphinxcontrib-spelling", "strict-rfc3339", "werkzeug"] - -[[package]] -name = "jupyterlab-widgets" -version = "3.0.11" -description = "Jupyter interactive widgets for JupyterLab" -optional = true -python-versions = ">=3.7" -files = [ - {file = "jupyterlab_widgets-3.0.11-py3-none-any.whl", hash = "sha256:78287fd86d20744ace330a61625024cf5521e1c012a352ddc0a3cdc2348becd0"}, - {file = "jupyterlab_widgets-3.0.11.tar.gz", hash = "sha256:dd5ac679593c969af29c9bed054c24f26842baa51352114736756bc035deee27"}, -] - -[[package]] -name = "kiwisolver" -version = "1.4.5" -description = "A fast implementation of the Cassowary constraint solver" -optional = true -python-versions = ">=3.7" -files = [ - {file = "kiwisolver-1.4.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:05703cf211d585109fcd72207a31bb170a0f22144d68298dc5e61b3c946518af"}, - {file = "kiwisolver-1.4.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:146d14bebb7f1dc4d5fbf74f8a6cb15ac42baadee8912eb84ac0b3b2a3dc6ac3"}, - {file = "kiwisolver-1.4.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6ef7afcd2d281494c0a9101d5c571970708ad911d028137cd558f02b851c08b4"}, - {file = "kiwisolver-1.4.5-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:9eaa8b117dc8337728e834b9c6e2611f10c79e38f65157c4c38e9400286f5cb1"}, - {file = "kiwisolver-1.4.5-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ec20916e7b4cbfb1f12380e46486ec4bcbaa91a9c448b97023fde0d5bbf9e4ff"}, - {file = "kiwisolver-1.4.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:39b42c68602539407884cf70d6a480a469b93b81b7701378ba5e2328660c847a"}, - {file = "kiwisolver-1.4.5-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aa12042de0171fad672b6c59df69106d20d5596e4f87b5e8f76df757a7c399aa"}, - {file = "kiwisolver-1.4.5-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2a40773c71d7ccdd3798f6489aaac9eee213d566850a9533f8d26332d626b82c"}, - {file = "kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:19df6e621f6d8b4b9c4d45f40a66839294ff2bb235e64d2178f7522d9170ac5b"}, - {file = "kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:83d78376d0d4fd884e2c114d0621624b73d2aba4e2788182d286309ebdeed770"}, - {file = "kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:e391b1f0a8a5a10ab3b9bb6afcfd74f2175f24f8975fb87ecae700d1503cdee0"}, - {file = "kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:852542f9481f4a62dbb5dd99e8ab7aedfeb8fb6342349a181d4036877410f525"}, - {file = "kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:59edc41b24031bc25108e210c0def6f6c2191210492a972d585a06ff246bb79b"}, - {file = "kiwisolver-1.4.5-cp310-cp310-win32.whl", hash = "sha256:a6aa6315319a052b4ee378aa171959c898a6183f15c1e541821c5c59beaa0238"}, - {file = "kiwisolver-1.4.5-cp310-cp310-win_amd64.whl", hash = "sha256:d0ef46024e6a3d79c01ff13801cb19d0cad7fd859b15037aec74315540acc276"}, - {file = "kiwisolver-1.4.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:11863aa14a51fd6ec28688d76f1735f8f69ab1fabf388851a595d0721af042f5"}, - {file = "kiwisolver-1.4.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8ab3919a9997ab7ef2fbbed0cc99bb28d3c13e6d4b1ad36e97e482558a91be90"}, - {file = "kiwisolver-1.4.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fcc700eadbbccbf6bc1bcb9dbe0786b4b1cb91ca0dcda336eef5c2beed37b797"}, - {file = "kiwisolver-1.4.5-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dfdd7c0b105af050eb3d64997809dc21da247cf44e63dc73ff0fd20b96be55a9"}, - {file = "kiwisolver-1.4.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76c6a5964640638cdeaa0c359382e5703e9293030fe730018ca06bc2010c4437"}, - {file = "kiwisolver-1.4.5-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bbea0db94288e29afcc4c28afbf3a7ccaf2d7e027489c449cf7e8f83c6346eb9"}, - {file = "kiwisolver-1.4.5-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ceec1a6bc6cab1d6ff5d06592a91a692f90ec7505d6463a88a52cc0eb58545da"}, - {file = "kiwisolver-1.4.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:040c1aebeda72197ef477a906782b5ab0d387642e93bda547336b8957c61022e"}, - {file = "kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:f91de7223d4c7b793867797bacd1ee53bfe7359bd70d27b7b58a04efbb9436c8"}, - {file = "kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:faae4860798c31530dd184046a900e652c95513796ef51a12bc086710c2eec4d"}, - {file = "kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:b0157420efcb803e71d1b28e2c287518b8808b7cf1ab8af36718fd0a2c453eb0"}, - {file = "kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:06f54715b7737c2fecdbf140d1afb11a33d59508a47bf11bb38ecf21dc9ab79f"}, - {file = "kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fdb7adb641a0d13bdcd4ef48e062363d8a9ad4a182ac7647ec88f695e719ae9f"}, - {file = "kiwisolver-1.4.5-cp311-cp311-win32.whl", hash = "sha256:bb86433b1cfe686da83ce32a9d3a8dd308e85c76b60896d58f082136f10bffac"}, - {file = "kiwisolver-1.4.5-cp311-cp311-win_amd64.whl", hash = "sha256:6c08e1312a9cf1074d17b17728d3dfce2a5125b2d791527f33ffbe805200a355"}, - {file = "kiwisolver-1.4.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:32d5cf40c4f7c7b3ca500f8985eb3fb3a7dfc023215e876f207956b5ea26632a"}, - {file = "kiwisolver-1.4.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f846c260f483d1fd217fe5ed7c173fb109efa6b1fc8381c8b7552c5781756192"}, - {file = "kiwisolver-1.4.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5ff5cf3571589b6d13bfbfd6bcd7a3f659e42f96b5fd1c4830c4cf21d4f5ef45"}, - {file = "kiwisolver-1.4.5-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7269d9e5f1084a653d575c7ec012ff57f0c042258bf5db0954bf551c158466e7"}, - {file = "kiwisolver-1.4.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da802a19d6e15dffe4b0c24b38b3af68e6c1a68e6e1d8f30148c83864f3881db"}, - {file = "kiwisolver-1.4.5-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3aba7311af82e335dd1e36ffff68aaca609ca6290c2cb6d821a39aa075d8e3ff"}, - {file = "kiwisolver-1.4.5-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:763773d53f07244148ccac5b084da5adb90bfaee39c197554f01b286cf869228"}, - {file = "kiwisolver-1.4.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2270953c0d8cdab5d422bee7d2007f043473f9d2999631c86a223c9db56cbd16"}, - {file = "kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d099e745a512f7e3bbe7249ca835f4d357c586d78d79ae8f1dcd4d8adeb9bda9"}, - {file = "kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:74db36e14a7d1ce0986fa104f7d5637aea5c82ca6326ed0ec5694280942d1162"}, - {file = "kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:7e5bab140c309cb3a6ce373a9e71eb7e4873c70c2dda01df6820474f9889d6d4"}, - {file = "kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:0f114aa76dc1b8f636d077979c0ac22e7cd8f3493abbab152f20eb8d3cda71f3"}, - {file = "kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:88a2df29d4724b9237fc0c6eaf2a1adae0cdc0b3e9f4d8e7dc54b16812d2d81a"}, - {file = "kiwisolver-1.4.5-cp312-cp312-win32.whl", hash = "sha256:72d40b33e834371fd330fb1472ca19d9b8327acb79a5821d4008391db8e29f20"}, - {file = "kiwisolver-1.4.5-cp312-cp312-win_amd64.whl", hash = "sha256:2c5674c4e74d939b9d91dda0fae10597ac7521768fec9e399c70a1f27e2ea2d9"}, - {file = "kiwisolver-1.4.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3a2b053a0ab7a3960c98725cfb0bf5b48ba82f64ec95fe06f1d06c99b552e130"}, - {file = "kiwisolver-1.4.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3cd32d6c13807e5c66a7cbb79f90b553642f296ae4518a60d8d76243b0ad2898"}, - {file = "kiwisolver-1.4.5-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:59ec7b7c7e1a61061850d53aaf8e93db63dce0c936db1fda2658b70e4a1be709"}, - {file = "kiwisolver-1.4.5-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:da4cfb373035def307905d05041c1d06d8936452fe89d464743ae7fb8371078b"}, - {file = "kiwisolver-1.4.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2400873bccc260b6ae184b2b8a4fec0e4082d30648eadb7c3d9a13405d861e89"}, - {file = "kiwisolver-1.4.5-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:1b04139c4236a0f3aff534479b58f6f849a8b351e1314826c2d230849ed48985"}, - {file = "kiwisolver-1.4.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:4e66e81a5779b65ac21764c295087de82235597a2293d18d943f8e9e32746265"}, - {file = "kiwisolver-1.4.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:7931d8f1f67c4be9ba1dd9c451fb0eeca1a25b89e4d3f89e828fe12a519b782a"}, - {file = "kiwisolver-1.4.5-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:b3f7e75f3015df442238cca659f8baa5f42ce2a8582727981cbfa15fee0ee205"}, - {file = "kiwisolver-1.4.5-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:bbf1d63eef84b2e8c89011b7f2235b1e0bf7dacc11cac9431fc6468e99ac77fb"}, - {file = "kiwisolver-1.4.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:4c380469bd3f970ef677bf2bcba2b6b0b4d5c75e7a020fb863ef75084efad66f"}, - {file = "kiwisolver-1.4.5-cp37-cp37m-win32.whl", hash = "sha256:9408acf3270c4b6baad483865191e3e582b638b1654a007c62e3efe96f09a9a3"}, - {file = "kiwisolver-1.4.5-cp37-cp37m-win_amd64.whl", hash = "sha256:5b94529f9b2591b7af5f3e0e730a4e0a41ea174af35a4fd067775f9bdfeee01a"}, - {file = "kiwisolver-1.4.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:11c7de8f692fc99816e8ac50d1d1aef4f75126eefc33ac79aac02c099fd3db71"}, - {file = "kiwisolver-1.4.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:53abb58632235cd154176ced1ae8f0d29a6657aa1aa9decf50b899b755bc2b93"}, - {file = "kiwisolver-1.4.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:88b9f257ca61b838b6f8094a62418421f87ac2a1069f7e896c36a7d86b5d4c29"}, - {file = "kiwisolver-1.4.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3195782b26fc03aa9c6913d5bad5aeb864bdc372924c093b0f1cebad603dd712"}, - {file = "kiwisolver-1.4.5-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fc579bf0f502e54926519451b920e875f433aceb4624a3646b3252b5caa9e0b6"}, - {file = "kiwisolver-1.4.5-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5a580c91d686376f0f7c295357595c5a026e6cbc3d77b7c36e290201e7c11ecb"}, - {file = "kiwisolver-1.4.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cfe6ab8da05c01ba6fbea630377b5da2cd9bcbc6338510116b01c1bc939a2c18"}, - {file = "kiwisolver-1.4.5-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:d2e5a98f0ec99beb3c10e13b387f8db39106d53993f498b295f0c914328b1333"}, - {file = "kiwisolver-1.4.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:a51a263952b1429e429ff236d2f5a21c5125437861baeed77f5e1cc2d2c7c6da"}, - {file = "kiwisolver-1.4.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:3edd2fa14e68c9be82c5b16689e8d63d89fe927e56debd6e1dbce7a26a17f81b"}, - {file = "kiwisolver-1.4.5-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:74d1b44c6cfc897df648cc9fdaa09bc3e7679926e6f96df05775d4fb3946571c"}, - {file = "kiwisolver-1.4.5-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:76d9289ed3f7501012e05abb8358bbb129149dbd173f1f57a1bf1c22d19ab7cc"}, - {file = "kiwisolver-1.4.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:92dea1ffe3714fa8eb6a314d2b3c773208d865a0e0d35e713ec54eea08a66250"}, - {file = "kiwisolver-1.4.5-cp38-cp38-win32.whl", hash = "sha256:5c90ae8c8d32e472be041e76f9d2f2dbff4d0b0be8bd4041770eddb18cf49a4e"}, - {file = "kiwisolver-1.4.5-cp38-cp38-win_amd64.whl", hash = "sha256:c7940c1dc63eb37a67721b10d703247552416f719c4188c54e04334321351ced"}, - {file = "kiwisolver-1.4.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:9407b6a5f0d675e8a827ad8742e1d6b49d9c1a1da5d952a67d50ef5f4170b18d"}, - {file = "kiwisolver-1.4.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:15568384086b6df3c65353820a4473575dbad192e35010f622c6ce3eebd57af9"}, - {file = "kiwisolver-1.4.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0dc9db8e79f0036e8173c466d21ef18e1befc02de8bf8aa8dc0813a6dc8a7046"}, - {file = "kiwisolver-1.4.5-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:cdc8a402aaee9a798b50d8b827d7ecf75edc5fb35ea0f91f213ff927c15f4ff0"}, - {file = "kiwisolver-1.4.5-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:6c3bd3cde54cafb87d74d8db50b909705c62b17c2099b8f2e25b461882e544ff"}, - {file = "kiwisolver-1.4.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:955e8513d07a283056b1396e9a57ceddbd272d9252c14f154d450d227606eb54"}, - {file = "kiwisolver-1.4.5-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:346f5343b9e3f00b8db8ba359350eb124b98c99efd0b408728ac6ebf38173958"}, - {file = "kiwisolver-1.4.5-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b9098e0049e88c6a24ff64545cdfc50807818ba6c1b739cae221bbbcbc58aad3"}, - {file = "kiwisolver-1.4.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:00bd361b903dc4bbf4eb165f24d1acbee754fce22ded24c3d56eec268658a5cf"}, - {file = "kiwisolver-1.4.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7b8b454bac16428b22560d0a1cf0a09875339cab69df61d7805bf48919415901"}, - {file = "kiwisolver-1.4.5-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:f1d072c2eb0ad60d4c183f3fb44ac6f73fb7a8f16a2694a91f988275cbf352f9"}, - {file = "kiwisolver-1.4.5-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:31a82d498054cac9f6d0b53d02bb85811185bcb477d4b60144f915f3b3126342"}, - {file = "kiwisolver-1.4.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:6512cb89e334e4700febbffaaa52761b65b4f5a3cf33f960213d5656cea36a77"}, - {file = "kiwisolver-1.4.5-cp39-cp39-win32.whl", hash = "sha256:9db8ea4c388fdb0f780fe91346fd438657ea602d58348753d9fb265ce1bca67f"}, - {file = "kiwisolver-1.4.5-cp39-cp39-win_amd64.whl", hash = "sha256:59415f46a37f7f2efeec758353dd2eae1b07640d8ca0f0c42548ec4125492635"}, - {file = "kiwisolver-1.4.5-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:5c7b3b3a728dc6faf3fc372ef24f21d1e3cee2ac3e9596691d746e5a536de920"}, - {file = "kiwisolver-1.4.5-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:620ced262a86244e2be10a676b646f29c34537d0d9cc8eb26c08f53d98013390"}, - {file = "kiwisolver-1.4.5-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:378a214a1e3bbf5ac4a8708304318b4f890da88c9e6a07699c4ae7174c09a68d"}, - {file = "kiwisolver-1.4.5-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aaf7be1207676ac608a50cd08f102f6742dbfc70e8d60c4db1c6897f62f71523"}, - {file = "kiwisolver-1.4.5-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:ba55dce0a9b8ff59495ddd050a0225d58bd0983d09f87cfe2b6aec4f2c1234e4"}, - {file = "kiwisolver-1.4.5-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:fd32ea360bcbb92d28933fc05ed09bffcb1704ba3fc7942e81db0fd4f81a7892"}, - {file = "kiwisolver-1.4.5-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:5e7139af55d1688f8b960ee9ad5adafc4ac17c1c473fe07133ac092310d76544"}, - {file = "kiwisolver-1.4.5-pp38-pypy38_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:dced8146011d2bc2e883f9bd68618b8247387f4bbec46d7392b3c3b032640126"}, - {file = "kiwisolver-1.4.5-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c9bf3325c47b11b2e51bca0824ea217c7cd84491d8ac4eefd1e409705ef092bd"}, - {file = "kiwisolver-1.4.5-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:5794cf59533bc3f1b1c821f7206a3617999db9fbefc345360aafe2e067514929"}, - {file = "kiwisolver-1.4.5-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:e368f200bbc2e4f905b8e71eb38b3c04333bddaa6a2464a6355487b02bb7fb09"}, - {file = "kiwisolver-1.4.5-pp39-pypy39_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e5d706eba36b4c4d5bc6c6377bb6568098765e990cfc21ee16d13963fab7b3e7"}, - {file = "kiwisolver-1.4.5-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:85267bd1aa8880a9c88a8cb71e18d3d64d2751a790e6ca6c27b8ccc724bcd5ad"}, - {file = "kiwisolver-1.4.5-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:210ef2c3a1f03272649aff1ef992df2e724748918c4bc2d5a90352849eb40bea"}, - {file = "kiwisolver-1.4.5-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:11d011a7574eb3b82bcc9c1a1d35c1d7075677fdd15de527d91b46bd35e935ee"}, - {file = "kiwisolver-1.4.5.tar.gz", hash = "sha256:e57e563a57fb22a142da34f38acc2fc1a5c864bc29ca1517a88abc963e60d6ec"}, -] - -[[package]] -name = "markupsafe" -version = "2.1.5" -description = "Safely add untrusted strings to HTML/XML markup." -optional = true -python-versions = ">=3.7" -files = [ - {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-win32.whl", hash = "sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-win_amd64.whl", hash = "sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-win32.whl", hash = "sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-win_amd64.whl", hash = "sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-win32.whl", hash = "sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-win_amd64.whl", hash = "sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c8b29db45f8fe46ad280a7294f5c3ec36dbac9491f2d1c17345be8e69cc5928f"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec6a563cff360b50eed26f13adc43e61bc0c04d94b8be985e6fb24b81f6dcfdf"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a549b9c31bec33820e885335b451286e2969a2d9e24879f83fe904a5ce59d70a"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4f11aa001c540f62c6166c7726f71f7573b52c68c31f014c25cc7901deea0b52"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:7b2e5a267c855eea6b4283940daa6e88a285f5f2a67f2220203786dfa59b37e9"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:2d2d793e36e230fd32babe143b04cec8a8b3eb8a3122d2aceb4a371e6b09b8df"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ce409136744f6521e39fd8e2a24c53fa18ad67aa5bc7c2cf83645cce5b5c4e50"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-win32.whl", hash = "sha256:4096e9de5c6fdf43fb4f04c26fb114f61ef0bf2e5604b6ee3019d51b69e8c371"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-win_amd64.whl", hash = "sha256:4275d846e41ecefa46e2015117a9f491e57a71ddd59bbead77e904dc02b1bed2"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:656f7526c69fac7f600bd1f400991cc282b417d17539a1b228617081106feb4a"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:97cafb1f3cbcd3fd2b6fbfb99ae11cdb14deea0736fc2b0952ee177f2b813a46"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f3fbcb7ef1f16e48246f704ab79d79da8a46891e2da03f8783a5b6fa41a9532"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa9db3f79de01457b03d4f01b34cf91bc0048eb2c3846ff26f66687c2f6d16ab"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffee1f21e5ef0d712f9033568f8344d5da8cc2869dbd08d87c84656e6a2d2f68"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:5dedb4db619ba5a2787a94d877bc8ffc0566f92a01c0ef214865e54ecc9ee5e0"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:30b600cf0a7ac9234b2638fbc0fb6158ba5bdcdf46aeb631ead21248b9affbc4"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8dd717634f5a044f860435c1d8c16a270ddf0ef8588d4887037c5028b859b0c3"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-win32.whl", hash = "sha256:daa4ee5a243f0f20d528d939d06670a298dd39b1ad5f8a72a4275124a7819eff"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-win_amd64.whl", hash = "sha256:619bc166c4f2de5caa5a633b8b7326fbe98e0ccbfacabd87268a2b15ff73a029"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7a68b554d356a91cce1236aa7682dc01df0edba8d043fd1ce607c49dd3c1edcf"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:db0b55e0f3cc0be60c1f19efdde9a637c32740486004f20d1cff53c3c0ece4d2"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e53af139f8579a6d5f7b76549125f0d94d7e630761a2111bc431fd820e163b8"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:17b950fccb810b3293638215058e432159d2b71005c74371d784862b7e4683f3"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4c31f53cdae6ecfa91a77820e8b151dba54ab528ba65dfd235c80b086d68a465"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bff1b4290a66b490a2f4719358c0cdcd9bafb6b8f061e45c7a2460866bf50c2e"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:bc1667f8b83f48511b94671e0e441401371dfd0f0a795c7daa4a3cd1dde55bea"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5049256f536511ee3f7e1b3f87d1d1209d327e818e6ae1365e8653d7e3abb6a6"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-win32.whl", hash = "sha256:00e046b6dd71aa03a41079792f8473dc494d564611a8f89bbbd7cb93295ebdcf"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-win_amd64.whl", hash = "sha256:fa173ec60341d6bb97a89f5ea19c85c5643c1e7dedebc22f5181eb73573142c5"}, - {file = "MarkupSafe-2.1.5.tar.gz", hash = "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b"}, -] - -[[package]] -name = "marmot-agents" -version = "0.2.5" -description = "Agent based processs modeling." -optional = true -python-versions = "*" -files = [ - {file = "marmot-agents-0.2.5.tar.gz", hash = "sha256:d0038c28928681b74352397a357f290da00c86a10c9626219b3ae36899faa915"}, - {file = "marmot_agents-0.2.5-py3-none-any.whl", hash = "sha256:f7678a830593222436396163fb0788d9d113bf84afb956b8854aad465830c2a6"}, -] - -[package.dependencies] -numpy = "*" - -[[package]] -name = "matplotlib" -version = "3.9.2" -description = "Python plotting package" -optional = true -python-versions = ">=3.9" -files = [ - {file = "matplotlib-3.9.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:9d78bbc0cbc891ad55b4f39a48c22182e9bdaea7fc0e5dbd364f49f729ca1bbb"}, - {file = "matplotlib-3.9.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c375cc72229614632c87355366bdf2570c2dac01ac66b8ad048d2dabadf2d0d4"}, - {file = "matplotlib-3.9.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1d94ff717eb2bd0b58fe66380bd8b14ac35f48a98e7c6765117fe67fb7684e64"}, - {file = "matplotlib-3.9.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ab68d50c06938ef28681073327795c5db99bb4666214d2d5f880ed11aeaded66"}, - {file = "matplotlib-3.9.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:65aacf95b62272d568044531e41de26285d54aec8cb859031f511f84bd8b495a"}, - {file = "matplotlib-3.9.2-cp310-cp310-win_amd64.whl", hash = "sha256:3fd595f34aa8a55b7fc8bf9ebea8aa665a84c82d275190a61118d33fbc82ccae"}, - {file = "matplotlib-3.9.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:d8dd059447824eec055e829258ab092b56bb0579fc3164fa09c64f3acd478772"}, - {file = "matplotlib-3.9.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c797dac8bb9c7a3fd3382b16fe8f215b4cf0f22adccea36f1545a6d7be310b41"}, - {file = "matplotlib-3.9.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d719465db13267bcef19ea8954a971db03b9f48b4647e3860e4bc8e6ed86610f"}, - {file = "matplotlib-3.9.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8912ef7c2362f7193b5819d17dae8629b34a95c58603d781329712ada83f9447"}, - {file = "matplotlib-3.9.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:7741f26a58a240f43bee74965c4882b6c93df3e7eb3de160126d8c8f53a6ae6e"}, - {file = "matplotlib-3.9.2-cp311-cp311-win_amd64.whl", hash = "sha256:ae82a14dab96fbfad7965403c643cafe6515e386de723e498cf3eeb1e0b70cc7"}, - {file = "matplotlib-3.9.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:ac43031375a65c3196bee99f6001e7fa5bdfb00ddf43379d3c0609bdca042df9"}, - {file = "matplotlib-3.9.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:be0fc24a5e4531ae4d8e858a1a548c1fe33b176bb13eff7f9d0d38ce5112a27d"}, - {file = "matplotlib-3.9.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf81de2926c2db243c9b2cbc3917619a0fc85796c6ba4e58f541df814bbf83c7"}, - {file = "matplotlib-3.9.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6ee45bc4245533111ced13f1f2cace1e7f89d1c793390392a80c139d6cf0e6c"}, - {file = "matplotlib-3.9.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:306c8dfc73239f0e72ac50e5a9cf19cc4e8e331dd0c54f5e69ca8758550f1e1e"}, - {file = "matplotlib-3.9.2-cp312-cp312-win_amd64.whl", hash = "sha256:5413401594cfaff0052f9d8b1aafc6d305b4bd7c4331dccd18f561ff7e1d3bd3"}, - {file = "matplotlib-3.9.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:18128cc08f0d3cfff10b76baa2f296fc28c4607368a8402de61bb3f2eb33c7d9"}, - {file = "matplotlib-3.9.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:4876d7d40219e8ae8bb70f9263bcbe5714415acfdf781086601211335e24f8aa"}, - {file = "matplotlib-3.9.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6d9f07a80deab4bb0b82858a9e9ad53d1382fd122be8cde11080f4e7dfedb38b"}, - {file = "matplotlib-3.9.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f7c0410f181a531ec4e93bbc27692f2c71a15c2da16766f5ba9761e7ae518413"}, - {file = "matplotlib-3.9.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:909645cce2dc28b735674ce0931a4ac94e12f5b13f6bb0b5a5e65e7cea2c192b"}, - {file = "matplotlib-3.9.2-cp313-cp313-win_amd64.whl", hash = "sha256:f32c7410c7f246838a77d6d1eff0c0f87f3cb0e7c4247aebea71a6d5a68cab49"}, - {file = "matplotlib-3.9.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:37e51dd1c2db16ede9cfd7b5cabdfc818b2c6397c83f8b10e0e797501c963a03"}, - {file = "matplotlib-3.9.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:b82c5045cebcecd8496a4d694d43f9cc84aeeb49fe2133e036b207abe73f4d30"}, - {file = "matplotlib-3.9.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f053c40f94bc51bc03832a41b4f153d83f2062d88c72b5e79997072594e97e51"}, - {file = "matplotlib-3.9.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dbe196377a8248972f5cede786d4c5508ed5f5ca4a1e09b44bda889958b33f8c"}, - {file = "matplotlib-3.9.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:5816b1e1fe8c192cbc013f8f3e3368ac56fbecf02fb41b8f8559303f24c5015e"}, - {file = "matplotlib-3.9.2-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:cef2a73d06601437be399908cf13aee74e86932a5ccc6ccdf173408ebc5f6bb2"}, - {file = "matplotlib-3.9.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e0830e188029c14e891fadd99702fd90d317df294c3298aad682739c5533721a"}, - {file = "matplotlib-3.9.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:03ba9c1299c920964e8d3857ba27173b4dbb51ca4bab47ffc2c2ba0eb5e2cbc5"}, - {file = "matplotlib-3.9.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1cd93b91ab47a3616b4d3c42b52f8363b88ca021e340804c6ab2536344fad9ca"}, - {file = "matplotlib-3.9.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:6d1ce5ed2aefcdce11904fc5bbea7d9c21fff3d5f543841edf3dea84451a09ea"}, - {file = "matplotlib-3.9.2-cp39-cp39-win_amd64.whl", hash = "sha256:b2696efdc08648536efd4e1601b5fd491fd47f4db97a5fbfd175549a7365c1b2"}, - {file = "matplotlib-3.9.2-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:d52a3b618cb1cbb769ce2ee1dcdb333c3ab6e823944e9a2d36e37253815f9556"}, - {file = "matplotlib-3.9.2-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:039082812cacd6c6bec8e17a9c1e6baca230d4116d522e81e1f63a74d01d2e21"}, - {file = "matplotlib-3.9.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6758baae2ed64f2331d4fd19be38b7b4eae3ecec210049a26b6a4f3ae1c85dcc"}, - {file = "matplotlib-3.9.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:050598c2b29e0b9832cde72bcf97627bf00262adbc4a54e2b856426bb2ef0697"}, - {file = "matplotlib-3.9.2.tar.gz", hash = "sha256:96ab43906269ca64a6366934106fa01534454a69e471b7bf3d79083981aaab92"}, -] - -[package.dependencies] -contourpy = ">=1.0.1" -cycler = ">=0.10" -fonttools = ">=4.22.0" -importlib-resources = {version = ">=3.2.0", markers = "python_version < \"3.10\""} -kiwisolver = ">=1.3.1" -numpy = ">=1.23" -packaging = ">=20.0" -pillow = ">=8" -pyparsing = ">=2.3.1" -python-dateutil = ">=2.7" - -[package.extras] -dev = ["meson-python (>=0.13.1)", "numpy (>=1.25)", "pybind11 (>=2.6)", "setuptools (>=64)", "setuptools_scm (>=7)"] - -[[package]] -name = "matplotlib-inline" -version = "0.1.7" -description = "Inline Matplotlib backend for Jupyter" -optional = true -python-versions = ">=3.8" -files = [ - {file = "matplotlib_inline-0.1.7-py3-none-any.whl", hash = "sha256:df192d39a4ff8f21b1895d72e6a13f5fcc5099f00fa84384e0ea28c2cc0653ca"}, - {file = "matplotlib_inline-0.1.7.tar.gz", hash = "sha256:8423b23ec666be3d16e16b60bdd8ac4e86e840ebd1dd11a30b9f117f2fa0ab90"}, -] - -[package.dependencies] -traitlets = "*" - -[[package]] -name = "mistune" -version = "3.0.2" -description = "A sane and fast Markdown parser with useful plugins and renderers" -optional = true -python-versions = ">=3.7" -files = [ - {file = "mistune-3.0.2-py3-none-any.whl", hash = "sha256:71481854c30fdbc938963d3605b72501f5c10a9320ecd412c121c163a1c7d205"}, - {file = "mistune-3.0.2.tar.gz", hash = "sha256:fc7f93ded930c92394ef2cb6f04a8aabab4117a91449e72dcc8dfa646a508be8"}, -] - -[[package]] -name = "moorpy" -version = "1.0.2" -description = "A design-oriented mooring system library for Python" -optional = true -python-versions = ">=3.8" -files = [ - {file = "MoorPy-1.0.2-py3-none-any.whl", hash = "sha256:e1cb1746a18678349521655d1a2d4eb703bf8fee0731dc7a920d5229831e3026"}, - {file = "MoorPy-1.0.2.tar.gz", hash = "sha256:29965a0b50bcd2c9d5bfe835b2eff581aeaaf9ccd87087db89054338b92d1847"}, -] - -[package.dependencies] -matplotlib = "*" -numpy = "*" -pyyaml = "*" -scipy = "*" - -[package.extras] -dev = ["pre-commit"] -docs = ["sphinx", "sphinx-rtd-theme"] -test = ["pytest", "pytest-cov", "pytest-xdist"] - -[[package]] -name = "nbclient" -version = "0.10.0" -description = "A client library for executing notebooks. Formerly nbconvert's ExecutePreprocessor." -optional = true -python-versions = ">=3.8.0" -files = [ - {file = "nbclient-0.10.0-py3-none-any.whl", hash = "sha256:f13e3529332a1f1f81d82a53210322476a168bb7090a0289c795fe9cc11c9d3f"}, - {file = "nbclient-0.10.0.tar.gz", hash = "sha256:4b3f1b7dba531e498449c4db4f53da339c91d449dc11e9af3a43b4eb5c5abb09"}, -] - -[package.dependencies] -jupyter-client = ">=6.1.12" -jupyter-core = ">=4.12,<5.0.dev0 || >=5.1.dev0" -nbformat = ">=5.1" -traitlets = ">=5.4" - -[package.extras] -dev = ["pre-commit"] -docs = ["autodoc-traits", "mock", "moto", "myst-parser", "nbclient[test]", "sphinx (>=1.7)", "sphinx-book-theme", "sphinxcontrib-spelling"] -test = ["flaky", "ipykernel (>=6.19.3)", "ipython", "ipywidgets", "nbconvert (>=7.0.0)", "pytest (>=7.0,<8)", "pytest-asyncio", "pytest-cov (>=4.0)", "testpath", "xmltodict"] - -[[package]] -name = "nbconvert" -version = "7.16.4" -description = "Converting Jupyter Notebooks (.ipynb files) to other formats. Output formats include asciidoc, html, latex, markdown, pdf, py, rst, script. nbconvert can be used both as a Python library (`import nbconvert`) or as a command line tool (invoked as `jupyter nbconvert ...`)." -optional = true -python-versions = ">=3.8" -files = [ - {file = "nbconvert-7.16.4-py3-none-any.whl", hash = "sha256:05873c620fe520b6322bf8a5ad562692343fe3452abda5765c7a34b7d1aa3eb3"}, - {file = "nbconvert-7.16.4.tar.gz", hash = "sha256:86ca91ba266b0a448dc96fa6c5b9d98affabde2867b363258703536807f9f7f4"}, -] - -[package.dependencies] -beautifulsoup4 = "*" -bleach = "!=5.0.0" -defusedxml = "*" -importlib-metadata = {version = ">=3.6", markers = "python_version < \"3.10\""} -jinja2 = ">=3.0" -jupyter-core = ">=4.7" -jupyterlab-pygments = "*" -markupsafe = ">=2.0" -mistune = ">=2.0.3,<4" -nbclient = ">=0.5.0" -nbformat = ">=5.7" -packaging = "*" -pandocfilters = ">=1.4.1" -pygments = ">=2.4.1" -tinycss2 = "*" -traitlets = ">=5.1" - -[package.extras] -all = ["flaky", "ipykernel", "ipython", "ipywidgets (>=7.5)", "myst-parser", "nbsphinx (>=0.2.12)", "playwright", "pydata-sphinx-theme", "pyqtwebengine (>=5.15)", "pytest (>=7)", "sphinx (==5.0.2)", "sphinxcontrib-spelling", "tornado (>=6.1)"] -docs = ["ipykernel", "ipython", "myst-parser", "nbsphinx (>=0.2.12)", "pydata-sphinx-theme", "sphinx (==5.0.2)", "sphinxcontrib-spelling"] -qtpdf = ["pyqtwebengine (>=5.15)"] -qtpng = ["pyqtwebengine (>=5.15)"] -serve = ["tornado (>=6.1)"] -test = ["flaky", "ipykernel", "ipywidgets (>=7.5)", "pytest (>=7)"] -webpdf = ["playwright"] - -[[package]] -name = "nbformat" -version = "5.10.4" -description = "The Jupyter Notebook format" -optional = true -python-versions = ">=3.8" -files = [ - {file = "nbformat-5.10.4-py3-none-any.whl", hash = "sha256:3b48d6c8fbca4b299bf3982ea7db1af21580e4fec269ad087b9e81588891200b"}, - {file = "nbformat-5.10.4.tar.gz", hash = "sha256:322168b14f937a5d11362988ecac2a4952d3d8e3a2cbeb2319584631226d5b3a"}, -] - -[package.dependencies] -fastjsonschema = ">=2.15" -jsonschema = ">=2.6" -jupyter-core = ">=4.12,<5.0.dev0 || >=5.1.dev0" -traitlets = ">=5.1" - -[package.extras] -docs = ["myst-parser", "pydata-sphinx-theme", "sphinx", "sphinxcontrib-github-alt", "sphinxcontrib-spelling"] -test = ["pep440", "pre-commit", "pytest", "testpath"] - -[[package]] -name = "nest-asyncio" -version = "1.6.0" -description = "Patch asyncio to allow nested event loops" -optional = true -python-versions = ">=3.5" -files = [ - {file = "nest_asyncio-1.6.0-py3-none-any.whl", hash = "sha256:87af6efd6b5e897c81050477ef65c62e2b2f35d51703cae01aff2905b1852e1c"}, - {file = "nest_asyncio-1.6.0.tar.gz", hash = "sha256:6f172d5449aca15afd6c646851f4e31e02c598d553a667e38cafa997cfec55fe"}, -] - -[[package]] -name = "networkx" -version = "3.2.1" -description = "Python package for creating and manipulating graphs and networks" -optional = true -python-versions = ">=3.9" -files = [ - {file = "networkx-3.2.1-py3-none-any.whl", hash = "sha256:f18c69adc97877c42332c170849c96cefa91881c99a7cb3e95b7c659ebdc1ec2"}, - {file = "networkx-3.2.1.tar.gz", hash = "sha256:9f1bb5cf3409bf324e0a722c20bdb4c20ee39bf1c30ce8ae499c8502b0b5e0c6"}, -] - -[package.extras] -default = ["matplotlib (>=3.5)", "numpy (>=1.22)", "pandas (>=1.4)", "scipy (>=1.9,!=1.11.0,!=1.11.1)"] -developer = ["changelist (==0.4)", "mypy (>=1.1)", "pre-commit (>=3.2)", "rtoml"] -doc = ["nb2plots (>=0.7)", "nbconvert (<7.9)", "numpydoc (>=1.6)", "pillow (>=9.4)", "pydata-sphinx-theme (>=0.14)", "sphinx (>=7)", "sphinx-gallery (>=0.14)", "texext (>=0.6.7)"] -extra = ["lxml (>=4.6)", "pydot (>=1.4.2)", "pygraphviz (>=1.11)", "sympy (>=1.10)"] -test = ["pytest (>=7.2)", "pytest-cov (>=4.0)"] - -[[package]] -name = "notebook" -version = "7.2.1" -description = "Jupyter Notebook - A web-based notebook environment for interactive computing" -optional = true -python-versions = ">=3.8" -files = [ - {file = "notebook-7.2.1-py3-none-any.whl", hash = "sha256:f45489a3995746f2195a137e0773e2130960b51c9ac3ce257dbc2705aab3a6ca"}, - {file = "notebook-7.2.1.tar.gz", hash = "sha256:4287b6da59740b32173d01d641f763d292f49c30e7a51b89c46ba8473126341e"}, -] - -[package.dependencies] -jupyter-server = ">=2.4.0,<3" -jupyterlab = ">=4.2.0,<4.3" -jupyterlab-server = ">=2.27.1,<3" -notebook-shim = ">=0.2,<0.3" -tornado = ">=6.2.0" - -[package.extras] -dev = ["hatch", "pre-commit"] -docs = ["myst-parser", "nbsphinx", "pydata-sphinx-theme", "sphinx (>=1.3.6)", "sphinxcontrib-github-alt", "sphinxcontrib-spelling"] -test = ["importlib-resources (>=5.0)", "ipykernel", "jupyter-server[test] (>=2.4.0,<3)", "jupyterlab-server[test] (>=2.27.1,<3)", "nbval", "pytest (>=7.0)", "pytest-console-scripts", "pytest-timeout", "pytest-tornasync", "requests"] - -[[package]] -name = "notebook-shim" -version = "0.2.4" -description = "A shim layer for notebook traits and config" -optional = true -python-versions = ">=3.7" -files = [ - {file = "notebook_shim-0.2.4-py3-none-any.whl", hash = "sha256:411a5be4e9dc882a074ccbcae671eda64cceb068767e9a3419096986560e1cef"}, - {file = "notebook_shim-0.2.4.tar.gz", hash = "sha256:b4b2cfa1b65d98307ca24361f5b30fe785b53c3fd07b7a47e89acb5e6ac638cb"}, -] - -[package.dependencies] -jupyter-server = ">=1.8,<3" - -[package.extras] -test = ["pytest", "pytest-console-scripts", "pytest-jupyter", "pytest-tornasync"] - -[[package]] -name = "numpy" -version = "1.26.4" -description = "Fundamental package for array computing in Python" -optional = false -python-versions = ">=3.9" -files = [ - {file = "numpy-1.26.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9ff0f4f29c51e2803569d7a51c2304de5554655a60c5d776e35b4a41413830d0"}, - {file = "numpy-1.26.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2e4ee3380d6de9c9ec04745830fd9e2eccb3e6cf790d39d7b98ffd19b0dd754a"}, - {file = "numpy-1.26.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d209d8969599b27ad20994c8e41936ee0964e6da07478d6c35016bc386b66ad4"}, - {file = "numpy-1.26.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ffa75af20b44f8dba823498024771d5ac50620e6915abac414251bd971b4529f"}, - {file = "numpy-1.26.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:62b8e4b1e28009ef2846b4c7852046736bab361f7aeadeb6a5b89ebec3c7055a"}, - {file = "numpy-1.26.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a4abb4f9001ad2858e7ac189089c42178fcce737e4169dc61321660f1a96c7d2"}, - {file = "numpy-1.26.4-cp310-cp310-win32.whl", hash = "sha256:bfe25acf8b437eb2a8b2d49d443800a5f18508cd811fea3181723922a8a82b07"}, - {file = "numpy-1.26.4-cp310-cp310-win_amd64.whl", hash = "sha256:b97fe8060236edf3662adfc2c633f56a08ae30560c56310562cb4f95500022d5"}, - {file = "numpy-1.26.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4c66707fabe114439db9068ee468c26bbdf909cac0fb58686a42a24de1760c71"}, - {file = "numpy-1.26.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:edd8b5fe47dab091176d21bb6de568acdd906d1887a4584a15a9a96a1dca06ef"}, - {file = "numpy-1.26.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7ab55401287bfec946ced39700c053796e7cc0e3acbef09993a9ad2adba6ca6e"}, - {file = "numpy-1.26.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:666dbfb6ec68962c033a450943ded891bed2d54e6755e35e5835d63f4f6931d5"}, - {file = "numpy-1.26.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:96ff0b2ad353d8f990b63294c8986f1ec3cb19d749234014f4e7eb0112ceba5a"}, - {file = "numpy-1.26.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:60dedbb91afcbfdc9bc0b1f3f402804070deed7392c23eb7a7f07fa857868e8a"}, - {file = "numpy-1.26.4-cp311-cp311-win32.whl", hash = "sha256:1af303d6b2210eb850fcf03064d364652b7120803a0b872f5211f5234b399f20"}, - {file = "numpy-1.26.4-cp311-cp311-win_amd64.whl", hash = "sha256:cd25bcecc4974d09257ffcd1f098ee778f7834c3ad767fe5db785be9a4aa9cb2"}, - {file = "numpy-1.26.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b3ce300f3644fb06443ee2222c2201dd3a89ea6040541412b8fa189341847218"}, - {file = "numpy-1.26.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:03a8c78d01d9781b28a6989f6fa1bb2c4f2d51201cf99d3dd875df6fbd96b23b"}, - {file = "numpy-1.26.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9fad7dcb1aac3c7f0584a5a8133e3a43eeb2fe127f47e3632d43d677c66c102b"}, - {file = "numpy-1.26.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:675d61ffbfa78604709862923189bad94014bef562cc35cf61d3a07bba02a7ed"}, - {file = "numpy-1.26.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:ab47dbe5cc8210f55aa58e4805fe224dac469cde56b9f731a4c098b91917159a"}, - {file = "numpy-1.26.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:1dda2e7b4ec9dd512f84935c5f126c8bd8b9f2fc001e9f54af255e8c5f16b0e0"}, - {file = "numpy-1.26.4-cp312-cp312-win32.whl", hash = "sha256:50193e430acfc1346175fcbdaa28ffec49947a06918b7b92130744e81e640110"}, - {file = "numpy-1.26.4-cp312-cp312-win_amd64.whl", hash = "sha256:08beddf13648eb95f8d867350f6a018a4be2e5ad54c8d8caed89ebca558b2818"}, - {file = "numpy-1.26.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7349ab0fa0c429c82442a27a9673fc802ffdb7c7775fad780226cb234965e53c"}, - {file = "numpy-1.26.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:52b8b60467cd7dd1e9ed082188b4e6bb35aa5cdd01777621a1658910745b90be"}, - {file = "numpy-1.26.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d5241e0a80d808d70546c697135da2c613f30e28251ff8307eb72ba696945764"}, - {file = "numpy-1.26.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f870204a840a60da0b12273ef34f7051e98c3b5961b61b0c2c1be6dfd64fbcd3"}, - {file = "numpy-1.26.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:679b0076f67ecc0138fd2ede3a8fd196dddc2ad3254069bcb9faf9a79b1cebcd"}, - {file = "numpy-1.26.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:47711010ad8555514b434df65f7d7b076bb8261df1ca9bb78f53d3b2db02e95c"}, - {file = "numpy-1.26.4-cp39-cp39-win32.whl", hash = "sha256:a354325ee03388678242a4d7ebcd08b5c727033fcff3b2f536aea978e15ee9e6"}, - {file = "numpy-1.26.4-cp39-cp39-win_amd64.whl", hash = "sha256:3373d5d70a5fe74a2c1bb6d2cfd9609ecf686d47a2d7b1d37a8f3b6bf6003aea"}, - {file = "numpy-1.26.4-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:afedb719a9dcfc7eaf2287b839d8198e06dcd4cb5d276a3df279231138e83d30"}, - {file = "numpy-1.26.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95a7476c59002f2f6c590b9b7b998306fba6a5aa646b1e22ddfeaf8f78c3a29c"}, - {file = "numpy-1.26.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7e50d0a0cc3189f9cb0aeb3a6a6af18c16f59f004b866cd2be1c14b36134a4a0"}, - {file = "numpy-1.26.4.tar.gz", hash = "sha256:2a02aba9ed12e4ac4eb3ea9421c420301a0c6460d9830d74a9df87efa4912010"}, -] - -[[package]] -name = "openmdao" -version = "3.34.2" -description = "OpenMDAO framework infrastructure" -optional = true -python-versions = ">=3.8" -files = [ - {file = "openmdao-3.34.2.tar.gz", hash = "sha256:3f772f74c99fc2305a872a4761589d4130396ea98a2210d9d1367fcf7fca36ab"}, -] - -[package.dependencies] -networkx = ">=2.0" -numpy = "<2" -packaging = "*" -requests = "*" -scipy = "*" - -[package.extras] -all = ["aiounittest", "bokeh (>=2.4.0)", "colorama", "idna (>=3.7)", "ipympl", "ipyparallel", "jax (>=0.4.0)", "jaxlib (>=0.4.0)", "jinja2 (>=3.1.4)", "jupyter-book (==0.14)", "matplotlib", "notebook", "num2words", "numpydoc (>=1.1)", "parameterized", "playwright (>=1.20)", "pycodestyle (>=2.4.0)", "pydocstyle (>=2.0.0)", "pydoe3", "sphinx-sitemap", "testflo (>=1.3.6)", "tqdm (>=4.66.3)", "websockets (>8)"] -docs = ["idna (>=3.7)", "ipyparallel", "jinja2 (>=3.1.4)", "jupyter-book (==0.14)", "matplotlib", "numpydoc (>=1.1)", "sphinx-sitemap", "tqdm (>=4.66.3)"] -doe = ["pydoe3"] -jax = ["jax (>=0.4.0)", "jaxlib (>=0.4.0)"] -notebooks = ["idna (>=3.7)", "ipympl", "notebook"] -test = ["aiounittest", "num2words", "numpydoc (>=1.1)", "parameterized", "playwright (>=1.20)", "pycodestyle (>=2.4.0)", "pydocstyle (>=2.0.0)", "testflo (>=1.3.6)", "websockets (>8)"] -visualization = ["bokeh (>=2.4.0)", "colorama", "matplotlib"] - -[[package]] -name = "openpyxl" -version = "3.1.5" -description = "A Python library to read/write Excel 2010 xlsx/xlsm files" -optional = true -python-versions = ">=3.8" -files = [ - {file = "openpyxl-3.1.5-py2.py3-none-any.whl", hash = "sha256:5282c12b107bffeef825f4617dc029afaf41d0ea60823bbb665ef3079dc79de2"}, - {file = "openpyxl-3.1.5.tar.gz", hash = "sha256:cf0e3cf56142039133628b5acffe8ef0c12bc902d2aadd3e0fe5878dc08d1050"}, -] - -[package.dependencies] -et-xmlfile = "*" - -[[package]] -name = "overrides" -version = "7.7.0" -description = "A decorator to automatically detect mismatch when overriding a method." -optional = true -python-versions = ">=3.6" -files = [ - {file = "overrides-7.7.0-py3-none-any.whl", hash = "sha256:c7ed9d062f78b8e4c1a7b70bd8796b35ead4d9f510227ef9c5dc7626c60d7e49"}, - {file = "overrides-7.7.0.tar.gz", hash = "sha256:55158fa3d93b98cc75299b1e67078ad9003ca27945c76162c1c0766d6f91820a"}, -] - -[[package]] -name = "packaging" -version = "24.1" -description = "Core utilities for Python packages" -optional = true -python-versions = ">=3.8" -files = [ - {file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"}, - {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"}, -] - -[[package]] -name = "pandas" -version = "2.2.2" -description = "Powerful data structures for data analysis, time series, and statistics" -optional = false -python-versions = ">=3.9" -files = [ - {file = "pandas-2.2.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:90c6fca2acf139569e74e8781709dccb6fe25940488755716d1d354d6bc58bce"}, - {file = "pandas-2.2.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c7adfc142dac335d8c1e0dcbd37eb8617eac386596eb9e1a1b77791cf2498238"}, - {file = "pandas-2.2.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4abfe0be0d7221be4f12552995e58723c7422c80a659da13ca382697de830c08"}, - {file = "pandas-2.2.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8635c16bf3d99040fdf3ca3db669a7250ddf49c55dc4aa8fe0ae0fa8d6dcc1f0"}, - {file = "pandas-2.2.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:40ae1dffb3967a52203105a077415a86044a2bea011b5f321c6aa64b379a3f51"}, - {file = "pandas-2.2.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8e5a0b00e1e56a842f922e7fae8ae4077aee4af0acb5ae3622bd4b4c30aedf99"}, - {file = "pandas-2.2.2-cp310-cp310-win_amd64.whl", hash = "sha256:ddf818e4e6c7c6f4f7c8a12709696d193976b591cc7dc50588d3d1a6b5dc8772"}, - {file = "pandas-2.2.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:696039430f7a562b74fa45f540aca068ea85fa34c244d0deee539cb6d70aa288"}, - {file = "pandas-2.2.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8e90497254aacacbc4ea6ae5e7a8cd75629d6ad2b30025a4a8b09aa4faf55151"}, - {file = "pandas-2.2.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:58b84b91b0b9f4bafac2a0ac55002280c094dfc6402402332c0913a59654ab2b"}, - {file = "pandas-2.2.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d2123dc9ad6a814bcdea0f099885276b31b24f7edf40f6cdbc0912672e22eee"}, - {file = "pandas-2.2.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:2925720037f06e89af896c70bca73459d7e6a4be96f9de79e2d440bd499fe0db"}, - {file = "pandas-2.2.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:0cace394b6ea70c01ca1595f839cf193df35d1575986e484ad35c4aeae7266c1"}, - {file = "pandas-2.2.2-cp311-cp311-win_amd64.whl", hash = "sha256:873d13d177501a28b2756375d59816c365e42ed8417b41665f346289adc68d24"}, - {file = "pandas-2.2.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:9dfde2a0ddef507a631dc9dc4af6a9489d5e2e740e226ad426a05cabfbd7c8ef"}, - {file = "pandas-2.2.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:e9b79011ff7a0f4b1d6da6a61aa1aa604fb312d6647de5bad20013682d1429ce"}, - {file = "pandas-2.2.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1cb51fe389360f3b5a4d57dbd2848a5f033350336ca3b340d1c53a1fad33bcad"}, - {file = "pandas-2.2.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eee3a87076c0756de40b05c5e9a6069c035ba43e8dd71c379e68cab2c20f16ad"}, - {file = "pandas-2.2.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:3e374f59e440d4ab45ca2fffde54b81ac3834cf5ae2cdfa69c90bc03bde04d76"}, - {file = "pandas-2.2.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:43498c0bdb43d55cb162cdc8c06fac328ccb5d2eabe3cadeb3529ae6f0517c32"}, - {file = "pandas-2.2.2-cp312-cp312-win_amd64.whl", hash = "sha256:d187d355ecec3629624fccb01d104da7d7f391db0311145817525281e2804d23"}, - {file = "pandas-2.2.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:0ca6377b8fca51815f382bd0b697a0814c8bda55115678cbc94c30aacbb6eff2"}, - {file = "pandas-2.2.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9057e6aa78a584bc93a13f0a9bf7e753a5e9770a30b4d758b8d5f2a62a9433cd"}, - {file = "pandas-2.2.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:001910ad31abc7bf06f49dcc903755d2f7f3a9186c0c040b827e522e9cef0863"}, - {file = "pandas-2.2.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:66b479b0bd07204e37583c191535505410daa8df638fd8e75ae1b383851fe921"}, - {file = "pandas-2.2.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:a77e9d1c386196879aa5eb712e77461aaee433e54c68cf253053a73b7e49c33a"}, - {file = "pandas-2.2.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:92fd6b027924a7e178ac202cfbe25e53368db90d56872d20ffae94b96c7acc57"}, - {file = "pandas-2.2.2-cp39-cp39-win_amd64.whl", hash = "sha256:640cef9aa381b60e296db324337a554aeeb883ead99dc8f6c18e81a93942f5f4"}, - {file = "pandas-2.2.2.tar.gz", hash = "sha256:9e79019aba43cb4fda9e4d983f8e88ca0373adbb697ae9c6c43093218de28b54"}, -] - -[package.dependencies] -numpy = [ - {version = ">=1.22.4", markers = "python_version < \"3.11\""}, - {version = ">=1.23.2", markers = "python_version == \"3.11\""}, - {version = ">=1.26.0", markers = "python_version >= \"3.12\""}, -] -python-dateutil = ">=2.8.2" -pytz = ">=2020.1" -tzdata = ">=2022.7" - -[package.extras] -all = ["PyQt5 (>=5.15.9)", "SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "adbc-driver-sqlite (>=0.8.0)", "beautifulsoup4 (>=4.11.2)", "bottleneck (>=1.3.6)", "dataframe-api-compat (>=0.1.7)", "fastparquet (>=2022.12.0)", "fsspec (>=2022.11.0)", "gcsfs (>=2022.11.0)", "html5lib (>=1.1)", "hypothesis (>=6.46.1)", "jinja2 (>=3.1.2)", "lxml (>=4.9.2)", "matplotlib (>=3.6.3)", "numba (>=0.56.4)", "numexpr (>=2.8.4)", "odfpy (>=1.4.1)", "openpyxl (>=3.1.0)", "pandas-gbq (>=0.19.0)", "psycopg2 (>=2.9.6)", "pyarrow (>=10.0.1)", "pymysql (>=1.0.2)", "pyreadstat (>=1.2.0)", "pytest (>=7.3.2)", "pytest-xdist (>=2.2.0)", "python-calamine (>=0.1.7)", "pyxlsb (>=1.0.10)", "qtpy (>=2.3.0)", "s3fs (>=2022.11.0)", "scipy (>=1.10.0)", "tables (>=3.8.0)", "tabulate (>=0.9.0)", "xarray (>=2022.12.0)", "xlrd (>=2.0.1)", "xlsxwriter (>=3.0.5)", "zstandard (>=0.19.0)"] -aws = ["s3fs (>=2022.11.0)"] -clipboard = ["PyQt5 (>=5.15.9)", "qtpy (>=2.3.0)"] -compression = ["zstandard (>=0.19.0)"] -computation = ["scipy (>=1.10.0)", "xarray (>=2022.12.0)"] -consortium-standard = ["dataframe-api-compat (>=0.1.7)"] -excel = ["odfpy (>=1.4.1)", "openpyxl (>=3.1.0)", "python-calamine (>=0.1.7)", "pyxlsb (>=1.0.10)", "xlrd (>=2.0.1)", "xlsxwriter (>=3.0.5)"] -feather = ["pyarrow (>=10.0.1)"] -fss = ["fsspec (>=2022.11.0)"] -gcp = ["gcsfs (>=2022.11.0)", "pandas-gbq (>=0.19.0)"] -hdf5 = ["tables (>=3.8.0)"] -html = ["beautifulsoup4 (>=4.11.2)", "html5lib (>=1.1)", "lxml (>=4.9.2)"] -mysql = ["SQLAlchemy (>=2.0.0)", "pymysql (>=1.0.2)"] -output-formatting = ["jinja2 (>=3.1.2)", "tabulate (>=0.9.0)"] -parquet = ["pyarrow (>=10.0.1)"] -performance = ["bottleneck (>=1.3.6)", "numba (>=0.56.4)", "numexpr (>=2.8.4)"] -plot = ["matplotlib (>=3.6.3)"] -postgresql = ["SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "psycopg2 (>=2.9.6)"] -pyarrow = ["pyarrow (>=10.0.1)"] -spss = ["pyreadstat (>=1.2.0)"] -sql-other = ["SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "adbc-driver-sqlite (>=0.8.0)"] -test = ["hypothesis (>=6.46.1)", "pytest (>=7.3.2)", "pytest-xdist (>=2.2.0)"] -xml = ["lxml (>=4.9.2)"] - -[[package]] -name = "pandocfilters" -version = "1.5.1" -description = "Utilities for writing pandoc filters in python" -optional = true -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -files = [ - {file = "pandocfilters-1.5.1-py2.py3-none-any.whl", hash = "sha256:93be382804a9cdb0a7267585f157e5d1731bbe5545a85b268d6f5fe6232de2bc"}, - {file = "pandocfilters-1.5.1.tar.gz", hash = "sha256:002b4a555ee4ebc03f8b66307e287fa492e4a77b4ea14d3f934328297bb4939e"}, -] - -[[package]] -name = "parso" -version = "0.8.4" -description = "A Python Parser" -optional = true -python-versions = ">=3.6" -files = [ - {file = "parso-0.8.4-py2.py3-none-any.whl", hash = "sha256:a418670a20291dacd2dddc80c377c5c3791378ee1e8d12bffc35420643d43f18"}, - {file = "parso-0.8.4.tar.gz", hash = "sha256:eb3a7b58240fb99099a345571deecc0f9540ea5f4dd2fe14c2a99d6b281ab92d"}, -] - -[package.extras] -qa = ["flake8 (==5.0.4)", "mypy (==0.971)", "types-setuptools (==67.2.0.1)"] -testing = ["docopt", "pytest"] - -[[package]] -name = "patsy" -version = "0.5.6" -description = "A Python package for describing statistical models and for building design matrices." -optional = true -python-versions = "*" -files = [ - {file = "patsy-0.5.6-py2.py3-none-any.whl", hash = "sha256:19056886fd8fa71863fa32f0eb090267f21fb74be00f19f5c70b2e9d76c883c6"}, - {file = "patsy-0.5.6.tar.gz", hash = "sha256:95c6d47a7222535f84bff7f63d7303f2e297747a598db89cf5c67f0c0c7d2cdb"}, -] - -[package.dependencies] -numpy = ">=1.4" -six = "*" - -[package.extras] -test = ["pytest", "pytest-cov", "scipy"] - -[[package]] -name = "pexpect" -version = "4.9.0" -description = "Pexpect allows easy control of interactive console applications." -optional = true -python-versions = "*" -files = [ - {file = "pexpect-4.9.0-py2.py3-none-any.whl", hash = "sha256:7236d1e080e4936be2dc3e326cec0af72acf9212a7e1d060210e70a47e253523"}, - {file = "pexpect-4.9.0.tar.gz", hash = "sha256:ee7d41123f3c9911050ea2c2dac107568dc43b2d3b0c7557a33212c398ead30f"}, -] - -[package.dependencies] -ptyprocess = ">=0.5" - -[[package]] -name = "pillow" -version = "10.4.0" -description = "Python Imaging Library (Fork)" -optional = true -python-versions = ">=3.8" -files = [ - {file = "pillow-10.4.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:4d9667937cfa347525b319ae34375c37b9ee6b525440f3ef48542fcf66f2731e"}, - {file = "pillow-10.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:543f3dc61c18dafb755773efc89aae60d06b6596a63914107f75459cf984164d"}, - {file = "pillow-10.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7928ecbf1ece13956b95d9cbcfc77137652b02763ba384d9ab508099a2eca856"}, - {file = "pillow-10.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4d49b85c4348ea0b31ea63bc75a9f3857869174e2bf17e7aba02945cd218e6f"}, - {file = "pillow-10.4.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:6c762a5b0997f5659a5ef2266abc1d8851ad7749ad9a6a5506eb23d314e4f46b"}, - {file = "pillow-10.4.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:a985e028fc183bf12a77a8bbf36318db4238a3ded7fa9df1b9a133f1cb79f8fc"}, - {file = "pillow-10.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:812f7342b0eee081eaec84d91423d1b4650bb9828eb53d8511bcef8ce5aecf1e"}, - {file = "pillow-10.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:ac1452d2fbe4978c2eec89fb5a23b8387aba707ac72810d9490118817d9c0b46"}, - {file = "pillow-10.4.0-cp310-cp310-win32.whl", hash = "sha256:bcd5e41a859bf2e84fdc42f4edb7d9aba0a13d29a2abadccafad99de3feff984"}, - {file = "pillow-10.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:ecd85a8d3e79cd7158dec1c9e5808e821feea088e2f69a974db5edf84dc53141"}, - {file = "pillow-10.4.0-cp310-cp310-win_arm64.whl", hash = "sha256:ff337c552345e95702c5fde3158acb0625111017d0e5f24bf3acdb9cc16b90d1"}, - {file = "pillow-10.4.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:0a9ec697746f268507404647e531e92889890a087e03681a3606d9b920fbee3c"}, - {file = "pillow-10.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:dfe91cb65544a1321e631e696759491ae04a2ea11d36715eca01ce07284738be"}, - {file = "pillow-10.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5dc6761a6efc781e6a1544206f22c80c3af4c8cf461206d46a1e6006e4429ff3"}, - {file = "pillow-10.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5e84b6cc6a4a3d76c153a6b19270b3526a5a8ed6b09501d3af891daa2a9de7d6"}, - {file = "pillow-10.4.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:bbc527b519bd3aa9d7f429d152fea69f9ad37c95f0b02aebddff592688998abe"}, - {file = "pillow-10.4.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:76a911dfe51a36041f2e756b00f96ed84677cdeb75d25c767f296c1c1eda1319"}, - {file = "pillow-10.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:59291fb29317122398786c2d44427bbd1a6d7ff54017075b22be9d21aa59bd8d"}, - {file = "pillow-10.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:416d3a5d0e8cfe4f27f574362435bc9bae57f679a7158e0096ad2beb427b8696"}, - {file = "pillow-10.4.0-cp311-cp311-win32.whl", hash = "sha256:7086cc1d5eebb91ad24ded9f58bec6c688e9f0ed7eb3dbbf1e4800280a896496"}, - {file = "pillow-10.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cbed61494057c0f83b83eb3a310f0bf774b09513307c434d4366ed64f4128a91"}, - {file = "pillow-10.4.0-cp311-cp311-win_arm64.whl", hash = "sha256:f5f0c3e969c8f12dd2bb7e0b15d5c468b51e5017e01e2e867335c81903046a22"}, - {file = "pillow-10.4.0-cp312-cp312-macosx_10_10_x86_64.whl", hash = "sha256:673655af3eadf4df6b5457033f086e90299fdd7a47983a13827acf7459c15d94"}, - {file = "pillow-10.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:866b6942a92f56300012f5fbac71f2d610312ee65e22f1aa2609e491284e5597"}, - {file = "pillow-10.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:29dbdc4207642ea6aad70fbde1a9338753d33fb23ed6956e706936706f52dd80"}, - {file = "pillow-10.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf2342ac639c4cf38799a44950bbc2dfcb685f052b9e262f446482afaf4bffca"}, - {file = "pillow-10.4.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:f5b92f4d70791b4a67157321c4e8225d60b119c5cc9aee8ecf153aace4aad4ef"}, - {file = "pillow-10.4.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:86dcb5a1eb778d8b25659d5e4341269e8590ad6b4e8b44d9f4b07f8d136c414a"}, - {file = "pillow-10.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:780c072c2e11c9b2c7ca37f9a2ee8ba66f44367ac3e5c7832afcfe5104fd6d1b"}, - {file = "pillow-10.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:37fb69d905be665f68f28a8bba3c6d3223c8efe1edf14cc4cfa06c241f8c81d9"}, - {file = "pillow-10.4.0-cp312-cp312-win32.whl", hash = "sha256:7dfecdbad5c301d7b5bde160150b4db4c659cee2b69589705b6f8a0c509d9f42"}, - {file = "pillow-10.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:1d846aea995ad352d4bdcc847535bd56e0fd88d36829d2c90be880ef1ee4668a"}, - {file = "pillow-10.4.0-cp312-cp312-win_arm64.whl", hash = "sha256:e553cad5179a66ba15bb18b353a19020e73a7921296a7979c4a2b7f6a5cd57f9"}, - {file = "pillow-10.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8bc1a764ed8c957a2e9cacf97c8b2b053b70307cf2996aafd70e91a082e70df3"}, - {file = "pillow-10.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:6209bb41dc692ddfee4942517c19ee81b86c864b626dbfca272ec0f7cff5d9fb"}, - {file = "pillow-10.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bee197b30783295d2eb680b311af15a20a8b24024a19c3a26431ff83eb8d1f70"}, - {file = "pillow-10.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1ef61f5dd14c300786318482456481463b9d6b91ebe5ef12f405afbba77ed0be"}, - {file = "pillow-10.4.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:297e388da6e248c98bc4a02e018966af0c5f92dfacf5a5ca22fa01cb3179bca0"}, - {file = "pillow-10.4.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:e4db64794ccdf6cb83a59d73405f63adbe2a1887012e308828596100a0b2f6cc"}, - {file = "pillow-10.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:bd2880a07482090a3bcb01f4265f1936a903d70bc740bfcb1fd4e8a2ffe5cf5a"}, - {file = "pillow-10.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4b35b21b819ac1dbd1233317adeecd63495f6babf21b7b2512d244ff6c6ce309"}, - {file = "pillow-10.4.0-cp313-cp313-win32.whl", hash = "sha256:551d3fd6e9dc15e4c1eb6fc4ba2b39c0c7933fa113b220057a34f4bb3268a060"}, - {file = "pillow-10.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:030abdbe43ee02e0de642aee345efa443740aa4d828bfe8e2eb11922ea6a21ea"}, - {file = "pillow-10.4.0-cp313-cp313-win_arm64.whl", hash = "sha256:5b001114dd152cfd6b23befeb28d7aee43553e2402c9f159807bf55f33af8a8d"}, - {file = "pillow-10.4.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:8d4d5063501b6dd4024b8ac2f04962d661222d120381272deea52e3fc52d3736"}, - {file = "pillow-10.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7c1ee6f42250df403c5f103cbd2768a28fe1a0ea1f0f03fe151c8741e1469c8b"}, - {file = "pillow-10.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b15e02e9bb4c21e39876698abf233c8c579127986f8207200bc8a8f6bb27acf2"}, - {file = "pillow-10.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7a8d4bade9952ea9a77d0c3e49cbd8b2890a399422258a77f357b9cc9be8d680"}, - {file = "pillow-10.4.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:43efea75eb06b95d1631cb784aa40156177bf9dd5b4b03ff38979e048258bc6b"}, - {file = "pillow-10.4.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:950be4d8ba92aca4b2bb0741285a46bfae3ca699ef913ec8416c1b78eadd64cd"}, - {file = "pillow-10.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:d7480af14364494365e89d6fddc510a13e5a2c3584cb19ef65415ca57252fb84"}, - {file = "pillow-10.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:73664fe514b34c8f02452ffb73b7a92c6774e39a647087f83d67f010eb9a0cf0"}, - {file = "pillow-10.4.0-cp38-cp38-win32.whl", hash = "sha256:e88d5e6ad0d026fba7bdab8c3f225a69f063f116462c49892b0149e21b6c0a0e"}, - {file = "pillow-10.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:5161eef006d335e46895297f642341111945e2c1c899eb406882a6c61a4357ab"}, - {file = "pillow-10.4.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:0ae24a547e8b711ccaaf99c9ae3cd975470e1a30caa80a6aaee9a2f19c05701d"}, - {file = "pillow-10.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:298478fe4f77a4408895605f3482b6cc6222c018b2ce565c2b6b9c354ac3229b"}, - {file = "pillow-10.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:134ace6dc392116566980ee7436477d844520a26a4b1bd4053f6f47d096997fd"}, - {file = "pillow-10.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:930044bb7679ab003b14023138b50181899da3f25de50e9dbee23b61b4de2126"}, - {file = "pillow-10.4.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:c76e5786951e72ed3686e122d14c5d7012f16c8303a674d18cdcd6d89557fc5b"}, - {file = "pillow-10.4.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:b2724fdb354a868ddf9a880cb84d102da914e99119211ef7ecbdc613b8c96b3c"}, - {file = "pillow-10.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:dbc6ae66518ab3c5847659e9988c3b60dc94ffb48ef9168656e0019a93dbf8a1"}, - {file = "pillow-10.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:06b2f7898047ae93fad74467ec3d28fe84f7831370e3c258afa533f81ef7f3df"}, - {file = "pillow-10.4.0-cp39-cp39-win32.whl", hash = "sha256:7970285ab628a3779aecc35823296a7869f889b8329c16ad5a71e4901a3dc4ef"}, - {file = "pillow-10.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:961a7293b2457b405967af9c77dcaa43cc1a8cd50d23c532e62d48ab6cdd56f5"}, - {file = "pillow-10.4.0-cp39-cp39-win_arm64.whl", hash = "sha256:32cda9e3d601a52baccb2856b8ea1fc213c90b340c542dcef77140dfa3278a9e"}, - {file = "pillow-10.4.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:5b4815f2e65b30f5fbae9dfffa8636d992d49705723fe86a3661806e069352d4"}, - {file = "pillow-10.4.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:8f0aef4ef59694b12cadee839e2ba6afeab89c0f39a3adc02ed51d109117b8da"}, - {file = "pillow-10.4.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9f4727572e2918acaa9077c919cbbeb73bd2b3ebcfe033b72f858fc9fbef0026"}, - {file = "pillow-10.4.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ff25afb18123cea58a591ea0244b92eb1e61a1fd497bf6d6384f09bc3262ec3e"}, - {file = "pillow-10.4.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:dc3e2db6ba09ffd7d02ae9141cfa0ae23393ee7687248d46a7507b75d610f4f5"}, - {file = "pillow-10.4.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:02a2be69f9c9b8c1e97cf2713e789d4e398c751ecfd9967c18d0ce304efbf885"}, - {file = "pillow-10.4.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:0755ffd4a0c6f267cccbae2e9903d95477ca2f77c4fcf3a3a09570001856c8a5"}, - {file = "pillow-10.4.0-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:a02364621fe369e06200d4a16558e056fe2805d3468350df3aef21e00d26214b"}, - {file = "pillow-10.4.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:1b5dea9831a90e9d0721ec417a80d4cbd7022093ac38a568db2dd78363b00908"}, - {file = "pillow-10.4.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9b885f89040bb8c4a1573566bbb2f44f5c505ef6e74cec7ab9068c900047f04b"}, - {file = "pillow-10.4.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87dd88ded2e6d74d31e1e0a99a726a6765cda32d00ba72dc37f0651f306daaa8"}, - {file = "pillow-10.4.0-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:2db98790afc70118bd0255c2eeb465e9767ecf1f3c25f9a1abb8ffc8cfd1fe0a"}, - {file = "pillow-10.4.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:f7baece4ce06bade126fb84b8af1c33439a76d8a6fd818970215e0560ca28c27"}, - {file = "pillow-10.4.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:cfdd747216947628af7b259d274771d84db2268ca062dd5faf373639d00113a3"}, - {file = "pillow-10.4.0.tar.gz", hash = "sha256:166c1cd4d24309b30d61f79f4a9114b7b2313d7450912277855ff5dfd7cd4a06"}, -] - -[package.extras] -docs = ["furo", "olefile", "sphinx (>=7.3)", "sphinx-copybutton", "sphinx-inline-tabs", "sphinxext-opengraph"] -fpx = ["olefile"] -mic = ["olefile"] -tests = ["check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "packaging", "pyroma", "pytest", "pytest-cov", "pytest-timeout"] -typing = ["typing-extensions"] -xmp = ["defusedxml"] - -[[package]] -name = "platformdirs" -version = "4.2.2" -description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." -optional = true -python-versions = ">=3.8" -files = [ - {file = "platformdirs-4.2.2-py3-none-any.whl", hash = "sha256:2d7a1657e36a80ea911db832a8a6ece5ee53d8de21edd5cc5879af6530b1bfee"}, - {file = "platformdirs-4.2.2.tar.gz", hash = "sha256:38b7b51f512eed9e84a22788b4bce1de17c0adb134d6becb09836e37d8654cd3"}, -] - -[package.extras] -docs = ["furo (>=2023.9.10)", "proselint (>=0.13)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.25.2)"] -test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)"] -type = ["mypy (>=1.8)"] - -[[package]] -name = "prometheus-client" -version = "0.20.0" -description = "Python client for the Prometheus monitoring system." -optional = true -python-versions = ">=3.8" -files = [ - {file = "prometheus_client-0.20.0-py3-none-any.whl", hash = "sha256:cde524a85bce83ca359cc837f28b8c0db5cac7aa653a588fd7e84ba061c329e7"}, - {file = "prometheus_client-0.20.0.tar.gz", hash = "sha256:287629d00b147a32dcb2be0b9df905da599b2d82f80377083ec8463309a4bb89"}, -] - -[package.extras] -twisted = ["twisted"] - -[[package]] -name = "prompt-toolkit" -version = "3.0.47" -description = "Library for building powerful interactive command lines in Python" -optional = true -python-versions = ">=3.7.0" -files = [ - {file = "prompt_toolkit-3.0.47-py3-none-any.whl", hash = "sha256:0d7bfa67001d5e39d02c224b663abc33687405033a8c422d0d675a5a13361d10"}, - {file = "prompt_toolkit-3.0.47.tar.gz", hash = "sha256:1e1b29cb58080b1e69f207c893a1a7bf16d127a5c30c9d17a25a5d77792e5360"}, -] - -[package.dependencies] -wcwidth = "*" - -[[package]] -name = "psutil" -version = "6.0.0" -description = "Cross-platform lib for process and system monitoring in Python." -optional = true -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" -files = [ - {file = "psutil-6.0.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:a021da3e881cd935e64a3d0a20983bda0bb4cf80e4f74fa9bfcb1bc5785360c6"}, - {file = "psutil-6.0.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:1287c2b95f1c0a364d23bc6f2ea2365a8d4d9b726a3be7294296ff7ba97c17f0"}, - {file = "psutil-6.0.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:a9a3dbfb4de4f18174528d87cc352d1f788b7496991cca33c6996f40c9e3c92c"}, - {file = "psutil-6.0.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:6ec7588fb3ddaec7344a825afe298db83fe01bfaaab39155fa84cf1c0d6b13c3"}, - {file = "psutil-6.0.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:1e7c870afcb7d91fdea2b37c24aeb08f98b6d67257a5cb0a8bc3ac68d0f1a68c"}, - {file = "psutil-6.0.0-cp27-none-win32.whl", hash = "sha256:02b69001f44cc73c1c5279d02b30a817e339ceb258ad75997325e0e6169d8b35"}, - {file = "psutil-6.0.0-cp27-none-win_amd64.whl", hash = "sha256:21f1fb635deccd510f69f485b87433460a603919b45e2a324ad65b0cc74f8fb1"}, - {file = "psutil-6.0.0-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:c588a7e9b1173b6e866756dde596fd4cad94f9399daf99ad8c3258b3cb2b47a0"}, - {file = "psutil-6.0.0-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ed2440ada7ef7d0d608f20ad89a04ec47d2d3ab7190896cd62ca5fc4fe08bf0"}, - {file = "psutil-6.0.0-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5fd9a97c8e94059b0ef54a7d4baf13b405011176c3b6ff257c247cae0d560ecd"}, - {file = "psutil-6.0.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e2e8d0054fc88153ca0544f5c4d554d42e33df2e009c4ff42284ac9ebdef4132"}, - {file = "psutil-6.0.0-cp36-cp36m-win32.whl", hash = "sha256:fc8c9510cde0146432bbdb433322861ee8c3efbf8589865c8bf8d21cb30c4d14"}, - {file = "psutil-6.0.0-cp36-cp36m-win_amd64.whl", hash = "sha256:34859b8d8f423b86e4385ff3665d3f4d94be3cdf48221fbe476e883514fdb71c"}, - {file = "psutil-6.0.0-cp37-abi3-win32.whl", hash = "sha256:a495580d6bae27291324fe60cea0b5a7c23fa36a7cd35035a16d93bdcf076b9d"}, - {file = "psutil-6.0.0-cp37-abi3-win_amd64.whl", hash = "sha256:33ea5e1c975250a720b3a6609c490db40dae5d83a4eb315170c4fe0d8b1f34b3"}, - {file = "psutil-6.0.0-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:ffe7fc9b6b36beadc8c322f84e1caff51e8703b88eee1da46d1e3a6ae11b4fd0"}, - {file = "psutil-6.0.0.tar.gz", hash = "sha256:8faae4f310b6d969fa26ca0545338b21f73c6b15db7c4a8d934a5482faa818f2"}, -] - -[package.extras] -test = ["enum34", "ipaddress", "mock", "pywin32", "wmi"] - -[[package]] -name = "ptyprocess" -version = "0.7.0" -description = "Run a subprocess in a pseudo terminal" -optional = true -python-versions = "*" -files = [ - {file = "ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35"}, - {file = "ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220"}, -] - -[[package]] -name = "pure-eval" -version = "0.2.3" -description = "Safely evaluate AST nodes without side effects" -optional = true -python-versions = "*" -files = [ - {file = "pure_eval-0.2.3-py3-none-any.whl", hash = "sha256:1db8e35b67b3d218d818ae653e27f06c3aa420901fa7b081ca98cbedc874e0d0"}, - {file = "pure_eval-0.2.3.tar.gz", hash = "sha256:5f4e983f40564c576c7c8635ae88db5956bb2229d7e9237d03b3c0b0190eaf42"}, -] - -[package.extras] -tests = ["pytest"] - -[[package]] -name = "pycparser" -version = "2.22" -description = "C parser in Python" -optional = true -python-versions = ">=3.8" -files = [ - {file = "pycparser-2.22-py3-none-any.whl", hash = "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc"}, - {file = "pycparser-2.22.tar.gz", hash = "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6"}, -] - -[[package]] -name = "pydoe3" -version = "1.0.3" -description = "Design of experiments for Python" -optional = true -python-versions = "*" -files = [ - {file = "pydoe3-1.0.3-py2.py3-none-any.whl", hash = "sha256:b190db474428a8d0573dfa4e39d8cb12abe3fe1dee70aeabeed1cb2ba1cbb040"}, - {file = "pydoe3-1.0.3.tar.gz", hash = "sha256:e0547d7b919dcd259abd96b91ea56f8d1a41f63efd6f393eacdbc06697d6034e"}, -] - -[package.dependencies] -numpy = "*" -scipy = "*" - -[[package]] -name = "pygments" -version = "2.18.0" -description = "Pygments is a syntax highlighting package written in Python." -optional = true -python-versions = ">=3.8" -files = [ - {file = "pygments-2.18.0-py3-none-any.whl", hash = "sha256:b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a"}, - {file = "pygments-2.18.0.tar.gz", hash = "sha256:786ff802f32e91311bff3889f6e9a86e81505fe99f2735bb6d60ae0c5004f199"}, -] - -[package.extras] -windows-terminal = ["colorama (>=0.4.6)"] - -[[package]] -name = "pyparsing" -version = "3.1.2" -description = "pyparsing module - Classes and methods to define and execute parsing grammars" -optional = true -python-versions = ">=3.6.8" -files = [ - {file = "pyparsing-3.1.2-py3-none-any.whl", hash = "sha256:f9db75911801ed778fe61bb643079ff86601aca99fcae6345aa67292038fb742"}, - {file = "pyparsing-3.1.2.tar.gz", hash = "sha256:a1bac0ce561155ecc3ed78ca94d3c9378656ad4c94c1270de543f621420f94ad"}, -] - -[package.extras] -diagrams = ["jinja2", "railroad-diagrams"] - -[[package]] -name = "python-benedict" -version = "0.33.2" -description = "python-benedict is a dict subclass with keylist/keypath/keyattr support, normalized I/O operations (base64, csv, ini, json, pickle, plist, query-string, toml, xls, xml, yaml) and many utilities... for humans, obviously." -optional = true -python-versions = "*" -files = [ - {file = "python-benedict-0.33.2.tar.gz", hash = "sha256:662de43bffb4e127da2056447f8ddd7f6f5c89b72dd66d289cf9abd1cc2720c8"}, - {file = "python_benedict-0.33.2-py3-none-any.whl", hash = "sha256:50a69b601b34d4ad7b67fe94e3266ec05046bc547a4132fe43fd8fbd41aeefaa"}, -] - -[package.dependencies] -python-fsutil = ">=0.9.3,<1.0.0" -python-slugify = ">=7.0.0,<9.0.0" -requests = ">=2.26.0,<3.0.0" - -[package.extras] -all = ["python-benedict[io,parse,s3]"] -html = ["beautifulsoup4 (>=4.12.0,<5.0.0)", "python-benedict[xml]"] -io = ["python-benedict[html,toml,xls,xml,yaml]"] -parse = ["ftfy (>=6.0.0,<7.0.0)", "mailchecker (>=4.1.0,<7.0.0)", "phonenumbers (>=8.12.0,<9.0.0)", "python-dateutil (>=2.8.0,<3.0.0)"] -s3 = ["boto3 (>=1.24.89,<2.0.0)"] -toml = ["toml (>=0.10.2,<1.0.0)"] -xls = ["openpyxl (>=3.0.0,<4.0.0)", "xlrd (>=2.0.0,<3.0.0)"] -xml = ["xmltodict (>=0.12.0,<1.0.0)"] -yaml = ["pyyaml (>=6.0,<7.0)"] - -[[package]] -name = "python-dateutil" -version = "2.9.0.post0" -description = "Extensions to the standard Python datetime module" -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" -files = [ - {file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"}, - {file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"}, -] - -[package.dependencies] -six = ">=1.5" - -[[package]] -name = "python-fsutil" -version = "0.14.1" -description = "high-level file-system operations for lazy devs." -optional = true -python-versions = "*" -files = [ - {file = "python-fsutil-0.14.1.tar.gz", hash = "sha256:8fb204fa8059f37bdeee8a1dc0fff010170202ea47c4225ee71bb3c26f3997be"}, - {file = "python_fsutil-0.14.1-py3-none-any.whl", hash = "sha256:0d45e623f0f4403f674bdd8ae7aa7d24a4b3132ea45c65416bd2865e6b20b035"}, -] - -[[package]] -name = "python-json-logger" -version = "2.0.7" -description = "A python library adding a json log formatter" -optional = true -python-versions = ">=3.6" -files = [ - {file = "python-json-logger-2.0.7.tar.gz", hash = "sha256:23e7ec02d34237c5aa1e29a070193a4ea87583bb4e7f8fd06d3de8264c4b2e1c"}, - {file = "python_json_logger-2.0.7-py3-none-any.whl", hash = "sha256:f380b826a991ebbe3de4d897aeec42760035ac760345e57b812938dc8b35e2bd"}, -] - -[[package]] -name = "python-slugify" -version = "8.0.4" -description = "A Python slugify application that also handles Unicode" -optional = true -python-versions = ">=3.7" -files = [ - {file = "python-slugify-8.0.4.tar.gz", hash = "sha256:59202371d1d05b54a9e7720c5e038f928f45daaffe41dd10822f3907b937c856"}, - {file = "python_slugify-8.0.4-py2.py3-none-any.whl", hash = "sha256:276540b79961052b66b7d116620b36518847f52d5fd9e3a70164fc8c50faa6b8"}, -] - -[package.dependencies] -text-unidecode = ">=1.3" - -[package.extras] -unidecode = ["Unidecode (>=1.1.1)"] - -[[package]] -name = "pytz" -version = "2024.1" -description = "World timezone definitions, modern and historical" -optional = false -python-versions = "*" -files = [ - {file = "pytz-2024.1-py2.py3-none-any.whl", hash = "sha256:328171f4e3623139da4983451950b28e95ac706e13f3f2630a879749e7a8b319"}, - {file = "pytz-2024.1.tar.gz", hash = "sha256:2a29735ea9c18baf14b448846bde5a48030ed267578472d8955cd0e7443a9812"}, -] - -[[package]] -name = "pywin32" -version = "306" -description = "Python for Window Extensions" -optional = true -python-versions = "*" -files = [ - {file = "pywin32-306-cp310-cp310-win32.whl", hash = "sha256:06d3420a5155ba65f0b72f2699b5bacf3109f36acbe8923765c22938a69dfc8d"}, - {file = "pywin32-306-cp310-cp310-win_amd64.whl", hash = "sha256:84f4471dbca1887ea3803d8848a1616429ac94a4a8d05f4bc9c5dcfd42ca99c8"}, - {file = "pywin32-306-cp311-cp311-win32.whl", hash = "sha256:e65028133d15b64d2ed8f06dd9fbc268352478d4f9289e69c190ecd6818b6407"}, - {file = "pywin32-306-cp311-cp311-win_amd64.whl", hash = "sha256:a7639f51c184c0272e93f244eb24dafca9b1855707d94c192d4a0b4c01e1100e"}, - {file = "pywin32-306-cp311-cp311-win_arm64.whl", hash = "sha256:70dba0c913d19f942a2db25217d9a1b726c278f483a919f1abfed79c9cf64d3a"}, - {file = "pywin32-306-cp312-cp312-win32.whl", hash = "sha256:383229d515657f4e3ed1343da8be101000562bf514591ff383ae940cad65458b"}, - {file = "pywin32-306-cp312-cp312-win_amd64.whl", hash = "sha256:37257794c1ad39ee9be652da0462dc2e394c8159dfd913a8a4e8eb6fd346da0e"}, - {file = "pywin32-306-cp312-cp312-win_arm64.whl", hash = "sha256:5821ec52f6d321aa59e2db7e0a35b997de60c201943557d108af9d4ae1ec7040"}, - {file = "pywin32-306-cp37-cp37m-win32.whl", hash = "sha256:1c73ea9a0d2283d889001998059f5eaaba3b6238f767c9cf2833b13e6a685f65"}, - {file = "pywin32-306-cp37-cp37m-win_amd64.whl", hash = "sha256:72c5f621542d7bdd4fdb716227be0dd3f8565c11b280be6315b06ace35487d36"}, - {file = "pywin32-306-cp38-cp38-win32.whl", hash = "sha256:e4c092e2589b5cf0d365849e73e02c391c1349958c5ac3e9d5ccb9a28e017b3a"}, - {file = "pywin32-306-cp38-cp38-win_amd64.whl", hash = "sha256:e8ac1ae3601bee6ca9f7cb4b5363bf1c0badb935ef243c4733ff9a393b1690c0"}, - {file = "pywin32-306-cp39-cp39-win32.whl", hash = "sha256:e25fd5b485b55ac9c057f67d94bc203f3f6595078d1fb3b458c9c28b7153a802"}, - {file = "pywin32-306-cp39-cp39-win_amd64.whl", hash = "sha256:39b61c15272833b5c329a2989999dcae836b1eed650252ab1b7bfbe1d59f30f4"}, -] - -[[package]] -name = "pywinpty" -version = "2.0.13" -description = "Pseudo terminal support for Windows from Python." -optional = true -python-versions = ">=3.8" -files = [ - {file = "pywinpty-2.0.13-cp310-none-win_amd64.whl", hash = "sha256:697bff211fb5a6508fee2dc6ff174ce03f34a9a233df9d8b5fe9c8ce4d5eaf56"}, - {file = "pywinpty-2.0.13-cp311-none-win_amd64.whl", hash = "sha256:b96fb14698db1284db84ca38c79f15b4cfdc3172065b5137383910567591fa99"}, - {file = "pywinpty-2.0.13-cp312-none-win_amd64.whl", hash = "sha256:2fd876b82ca750bb1333236ce98488c1be96b08f4f7647cfdf4129dfad83c2d4"}, - {file = "pywinpty-2.0.13-cp38-none-win_amd64.whl", hash = "sha256:61d420c2116c0212808d31625611b51caf621fe67f8a6377e2e8b617ea1c1f7d"}, - {file = "pywinpty-2.0.13-cp39-none-win_amd64.whl", hash = "sha256:71cb613a9ee24174730ac7ae439fd179ca34ccb8c5349e8d7b72ab5dea2c6f4b"}, - {file = "pywinpty-2.0.13.tar.gz", hash = "sha256:c34e32351a3313ddd0d7da23d27f835c860d32fe4ac814d372a3ea9594f41dde"}, -] - -[[package]] -name = "pyyaml" -version = "6.0.2" -description = "YAML parser and emitter for Python" -optional = true -python-versions = ">=3.8" -files = [ - {file = "PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086"}, - {file = "PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf"}, - {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237"}, - {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b"}, - {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed"}, - {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180"}, - {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68"}, - {file = "PyYAML-6.0.2-cp310-cp310-win32.whl", hash = "sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99"}, - {file = "PyYAML-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e"}, - {file = "PyYAML-6.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774"}, - {file = "PyYAML-6.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee"}, - {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c"}, - {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317"}, - {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85"}, - {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4"}, - {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e"}, - {file = "PyYAML-6.0.2-cp311-cp311-win32.whl", hash = "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5"}, - {file = "PyYAML-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44"}, - {file = "PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab"}, - {file = "PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725"}, - {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5"}, - {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425"}, - {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476"}, - {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48"}, - {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b"}, - {file = "PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4"}, - {file = "PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8"}, - {file = "PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba"}, - {file = "PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1"}, - {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133"}, - {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484"}, - {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5"}, - {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc"}, - {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652"}, - {file = "PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183"}, - {file = "PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563"}, - {file = "PyYAML-6.0.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:24471b829b3bf607e04e88d79542a9d48bb037c2267d7927a874e6c205ca7e9a"}, - {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7fded462629cfa4b685c5416b949ebad6cec74af5e2d42905d41e257e0869f5"}, - {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d84a1718ee396f54f3a086ea0a66d8e552b2ab2017ef8b420e92edbc841c352d"}, - {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9056c1ecd25795207ad294bcf39f2db3d845767be0ea6e6a34d856f006006083"}, - {file = "PyYAML-6.0.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:82d09873e40955485746739bcb8b4586983670466c23382c19cffecbf1fd8706"}, - {file = "PyYAML-6.0.2-cp38-cp38-win32.whl", hash = "sha256:43fa96a3ca0d6b1812e01ced1044a003533c47f6ee8aca31724f78e93ccc089a"}, - {file = "PyYAML-6.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:01179a4a8559ab5de078078f37e5c1a30d76bb88519906844fd7bdea1b7729ff"}, - {file = "PyYAML-6.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:688ba32a1cffef67fd2e9398a2efebaea461578b0923624778664cc1c914db5d"}, - {file = "PyYAML-6.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8786accb172bd8afb8be14490a16625cbc387036876ab6ba70912730faf8e1f"}, - {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8e03406cac8513435335dbab54c0d385e4a49e4945d2909a581c83647ca0290"}, - {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f753120cb8181e736c57ef7636e83f31b9c0d1722c516f7e86cf15b7aa57ff12"}, - {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b1fdb9dc17f5a7677423d508ab4f243a726dea51fa5e70992e59a7411c89d19"}, - {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0b69e4ce7a131fe56b7e4d770c67429700908fc0752af059838b1cfb41960e4e"}, - {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a9f8c2e67970f13b16084e04f134610fd1d374bf477b17ec1599185cf611d725"}, - {file = "PyYAML-6.0.2-cp39-cp39-win32.whl", hash = "sha256:6395c297d42274772abc367baaa79683958044e5d3835486c16da75d2a694631"}, - {file = "PyYAML-6.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:39693e1f8320ae4f43943590b49779ffb98acb81f788220ea932a6b6c51004d8"}, - {file = "pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e"}, -] - -[[package]] -name = "pyzmq" -version = "26.1.0" -description = "Python bindings for 0MQ" -optional = true -python-versions = ">=3.7" -files = [ - {file = "pyzmq-26.1.0-cp310-cp310-macosx_10_15_universal2.whl", hash = "sha256:263cf1e36862310bf5becfbc488e18d5d698941858860c5a8c079d1511b3b18e"}, - {file = "pyzmq-26.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d5c8b17f6e8f29138678834cf8518049e740385eb2dbf736e8f07fc6587ec682"}, - {file = "pyzmq-26.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:75a95c2358fcfdef3374cb8baf57f1064d73246d55e41683aaffb6cfe6862917"}, - {file = "pyzmq-26.1.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f99de52b8fbdb2a8f5301ae5fc0f9e6b3ba30d1d5fc0421956967edcc6914242"}, - {file = "pyzmq-26.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7bcbfbab4e1895d58ab7da1b5ce9a327764f0366911ba5b95406c9104bceacb0"}, - {file = "pyzmq-26.1.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:77ce6a332c7e362cb59b63f5edf730e83590d0ab4e59c2aa5bd79419a42e3449"}, - {file = "pyzmq-26.1.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:ba0a31d00e8616149a5ab440d058ec2da621e05d744914774c4dde6837e1f545"}, - {file = "pyzmq-26.1.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:8b88641384e84a258b740801cd4dbc45c75f148ee674bec3149999adda4a8598"}, - {file = "pyzmq-26.1.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:2fa76ebcebe555cce90f16246edc3ad83ab65bb7b3d4ce408cf6bc67740c4f88"}, - {file = "pyzmq-26.1.0-cp310-cp310-win32.whl", hash = "sha256:fbf558551cf415586e91160d69ca6416f3fce0b86175b64e4293644a7416b81b"}, - {file = "pyzmq-26.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:a7b8aab50e5a288c9724d260feae25eda69582be84e97c012c80e1a5e7e03fb2"}, - {file = "pyzmq-26.1.0-cp310-cp310-win_arm64.whl", hash = "sha256:08f74904cb066e1178c1ec706dfdb5c6c680cd7a8ed9efebeac923d84c1f13b1"}, - {file = "pyzmq-26.1.0-cp311-cp311-macosx_10_15_universal2.whl", hash = "sha256:46d6800b45015f96b9d92ece229d92f2aef137d82906577d55fadeb9cf5fcb71"}, - {file = "pyzmq-26.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5bc2431167adc50ba42ea3e5e5f5cd70d93e18ab7b2f95e724dd8e1bd2c38120"}, - {file = "pyzmq-26.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b3bb34bebaa1b78e562931a1687ff663d298013f78f972a534f36c523311a84d"}, - {file = "pyzmq-26.1.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bd3f6329340cef1c7ba9611bd038f2d523cea79f09f9c8f6b0553caba59ec562"}, - {file = "pyzmq-26.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:471880c4c14e5a056a96cd224f5e71211997d40b4bf5e9fdded55dafab1f98f2"}, - {file = "pyzmq-26.1.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:ce6f2b66799971cbae5d6547acefa7231458289e0ad481d0be0740535da38d8b"}, - {file = "pyzmq-26.1.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0a1f6ea5b1d6cdbb8cfa0536f0d470f12b4b41ad83625012e575f0e3ecfe97f0"}, - {file = "pyzmq-26.1.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:b45e6445ac95ecb7d728604bae6538f40ccf4449b132b5428c09918523abc96d"}, - {file = "pyzmq-26.1.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:94c4262626424683feea0f3c34951d39d49d354722db2745c42aa6bb50ecd93b"}, - {file = "pyzmq-26.1.0-cp311-cp311-win32.whl", hash = "sha256:a0f0ab9df66eb34d58205913f4540e2ad17a175b05d81b0b7197bc57d000e829"}, - {file = "pyzmq-26.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:8efb782f5a6c450589dbab4cb0f66f3a9026286333fe8f3a084399149af52f29"}, - {file = "pyzmq-26.1.0-cp311-cp311-win_arm64.whl", hash = "sha256:f133d05aaf623519f45e16ab77526e1e70d4e1308e084c2fb4cedb1a0c764bbb"}, - {file = "pyzmq-26.1.0-cp312-cp312-macosx_10_15_universal2.whl", hash = "sha256:3d3146b1c3dcc8a1539e7cc094700b2be1e605a76f7c8f0979b6d3bde5ad4072"}, - {file = "pyzmq-26.1.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d9270fbf038bf34ffca4855bcda6e082e2c7f906b9eb8d9a8ce82691166060f7"}, - {file = "pyzmq-26.1.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:995301f6740a421afc863a713fe62c0aaf564708d4aa057dfdf0f0f56525294b"}, - {file = "pyzmq-26.1.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7eca8b89e56fb8c6c26dd3e09bd41b24789022acf1cf13358e96f1cafd8cae3"}, - {file = "pyzmq-26.1.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90d4feb2e83dfe9ace6374a847e98ee9d1246ebadcc0cb765482e272c34e5820"}, - {file = "pyzmq-26.1.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:d4fafc2eb5d83f4647331267808c7e0c5722c25a729a614dc2b90479cafa78bd"}, - {file = "pyzmq-26.1.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:58c33dc0e185dd97a9ac0288b3188d1be12b756eda67490e6ed6a75cf9491d79"}, - {file = "pyzmq-26.1.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:68a0a1d83d33d8367ddddb3e6bb4afbb0f92bd1dac2c72cd5e5ddc86bdafd3eb"}, - {file = "pyzmq-26.1.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:2ae7c57e22ad881af78075e0cea10a4c778e67234adc65c404391b417a4dda83"}, - {file = "pyzmq-26.1.0-cp312-cp312-win32.whl", hash = "sha256:347e84fc88cc4cb646597f6d3a7ea0998f887ee8dc31c08587e9c3fd7b5ccef3"}, - {file = "pyzmq-26.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:9f136a6e964830230912f75b5a116a21fe8e34128dcfd82285aa0ef07cb2c7bd"}, - {file = "pyzmq-26.1.0-cp312-cp312-win_arm64.whl", hash = "sha256:a4b7a989c8f5a72ab1b2bbfa58105578753ae77b71ba33e7383a31ff75a504c4"}, - {file = "pyzmq-26.1.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:d416f2088ac8f12daacffbc2e8918ef4d6be8568e9d7155c83b7cebed49d2322"}, - {file = "pyzmq-26.1.0-cp313-cp313-macosx_10_15_universal2.whl", hash = "sha256:ecb6c88d7946166d783a635efc89f9a1ff11c33d680a20df9657b6902a1d133b"}, - {file = "pyzmq-26.1.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:471312a7375571857a089342beccc1a63584315188560c7c0da7e0a23afd8a5c"}, - {file = "pyzmq-26.1.0-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0e6cea102ffa16b737d11932c426f1dc14b5938cf7bc12e17269559c458ac334"}, - {file = "pyzmq-26.1.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec7248673ffc7104b54e4957cee38b2f3075a13442348c8d651777bf41aa45ee"}, - {file = "pyzmq-26.1.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:0614aed6f87d550b5cecb03d795f4ddbb1544b78d02a4bd5eecf644ec98a39f6"}, - {file = "pyzmq-26.1.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:e8746ce968be22a8a1801bf4a23e565f9687088580c3ed07af5846580dd97f76"}, - {file = "pyzmq-26.1.0-cp313-cp313-musllinux_1_1_i686.whl", hash = "sha256:7688653574392d2eaeef75ddcd0b2de5b232d8730af29af56c5adf1df9ef8d6f"}, - {file = "pyzmq-26.1.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:8d4dac7d97f15c653a5fedcafa82626bd6cee1450ccdaf84ffed7ea14f2b07a4"}, - {file = "pyzmq-26.1.0-cp313-cp313-win32.whl", hash = "sha256:ccb42ca0a4a46232d716779421bbebbcad23c08d37c980f02cc3a6bd115ad277"}, - {file = "pyzmq-26.1.0-cp313-cp313-win_amd64.whl", hash = "sha256:e1e5d0a25aea8b691a00d6b54b28ac514c8cc0d8646d05f7ca6cb64b97358250"}, - {file = "pyzmq-26.1.0-cp313-cp313-win_arm64.whl", hash = "sha256:fc82269d24860cfa859b676d18850cbb8e312dcd7eada09e7d5b007e2f3d9eb1"}, - {file = "pyzmq-26.1.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:416ac51cabd54f587995c2b05421324700b22e98d3d0aa2cfaec985524d16f1d"}, - {file = "pyzmq-26.1.0-cp313-cp313t-macosx_10_15_universal2.whl", hash = "sha256:ff832cce719edd11266ca32bc74a626b814fff236824aa1aeaad399b69fe6eae"}, - {file = "pyzmq-26.1.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:393daac1bcf81b2a23e696b7b638eedc965e9e3d2112961a072b6cd8179ad2eb"}, - {file = "pyzmq-26.1.0-cp313-cp313t-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9869fa984c8670c8ab899a719eb7b516860a29bc26300a84d24d8c1b71eae3ec"}, - {file = "pyzmq-26.1.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b3b8e36fd4c32c0825b4461372949ecd1585d326802b1321f8b6dc1d7e9318c"}, - {file = "pyzmq-26.1.0-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:3ee647d84b83509b7271457bb428cc347037f437ead4b0b6e43b5eba35fec0aa"}, - {file = "pyzmq-26.1.0-cp313-cp313t-musllinux_1_1_aarch64.whl", hash = "sha256:45cb1a70eb00405ce3893041099655265fabcd9c4e1e50c330026e82257892c1"}, - {file = "pyzmq-26.1.0-cp313-cp313t-musllinux_1_1_i686.whl", hash = "sha256:5cca7b4adb86d7470e0fc96037771981d740f0b4cb99776d5cb59cd0e6684a73"}, - {file = "pyzmq-26.1.0-cp313-cp313t-musllinux_1_1_x86_64.whl", hash = "sha256:91d1a20bdaf3b25f3173ff44e54b1cfbc05f94c9e8133314eb2962a89e05d6e3"}, - {file = "pyzmq-26.1.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c0665d85535192098420428c779361b8823d3d7ec4848c6af3abb93bc5c915bf"}, - {file = "pyzmq-26.1.0-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:96d7c1d35ee4a495df56c50c83df7af1c9688cce2e9e0edffdbf50889c167595"}, - {file = "pyzmq-26.1.0-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:b281b5ff5fcc9dcbfe941ac5c7fcd4b6c065adad12d850f95c9d6f23c2652384"}, - {file = "pyzmq-26.1.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5384c527a9a004445c5074f1e20db83086c8ff1682a626676229aafd9cf9f7d1"}, - {file = "pyzmq-26.1.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:754c99a9840839375ee251b38ac5964c0f369306eddb56804a073b6efdc0cd88"}, - {file = "pyzmq-26.1.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:9bdfcb74b469b592972ed881bad57d22e2c0acc89f5e8c146782d0d90fb9f4bf"}, - {file = "pyzmq-26.1.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:bd13f0231f4788db619347b971ca5f319c5b7ebee151afc7c14632068c6261d3"}, - {file = "pyzmq-26.1.0-cp37-cp37m-win32.whl", hash = "sha256:c5668dac86a869349828db5fc928ee3f58d450dce2c85607067d581f745e4fb1"}, - {file = "pyzmq-26.1.0-cp37-cp37m-win_amd64.whl", hash = "sha256:ad875277844cfaeca7fe299ddf8c8d8bfe271c3dc1caf14d454faa5cdbf2fa7a"}, - {file = "pyzmq-26.1.0-cp38-cp38-macosx_10_15_universal2.whl", hash = "sha256:65c6e03cc0222eaf6aad57ff4ecc0a070451e23232bb48db4322cc45602cede0"}, - {file = "pyzmq-26.1.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:038ae4ffb63e3991f386e7fda85a9baab7d6617fe85b74a8f9cab190d73adb2b"}, - {file = "pyzmq-26.1.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:bdeb2c61611293f64ac1073f4bf6723b67d291905308a7de9bb2ca87464e3273"}, - {file = "pyzmq-26.1.0-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:61dfa5ee9d7df297c859ac82b1226d8fefaf9c5113dc25c2c00ecad6feeeb04f"}, - {file = "pyzmq-26.1.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f3292d384537b9918010769b82ab3e79fca8b23d74f56fc69a679106a3e2c2cf"}, - {file = "pyzmq-26.1.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:f9499c70c19ff0fbe1007043acb5ad15c1dec7d8e84ab429bca8c87138e8f85c"}, - {file = "pyzmq-26.1.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:d3dd5523ed258ad58fed7e364c92a9360d1af8a9371e0822bd0146bdf017ef4c"}, - {file = "pyzmq-26.1.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:baba2fd199b098c5544ef2536b2499d2e2155392973ad32687024bd8572a7d1c"}, - {file = "pyzmq-26.1.0-cp38-cp38-win32.whl", hash = "sha256:ddbb2b386128d8eca92bd9ca74e80f73fe263bcca7aa419f5b4cbc1661e19741"}, - {file = "pyzmq-26.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:79e45a4096ec8388cdeb04a9fa5e9371583bcb826964d55b8b66cbffe7b33c86"}, - {file = "pyzmq-26.1.0-cp39-cp39-macosx_10_15_universal2.whl", hash = "sha256:add52c78a12196bc0fda2de087ba6c876ea677cbda2e3eba63546b26e8bf177b"}, - {file = "pyzmq-26.1.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:98c03bd7f3339ff47de7ea9ac94a2b34580a8d4df69b50128bb6669e1191a895"}, - {file = "pyzmq-26.1.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:dcc37d9d708784726fafc9c5e1232de655a009dbf97946f117aefa38d5985a0f"}, - {file = "pyzmq-26.1.0-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:5a6ed52f0b9bf8dcc64cc82cce0607a3dfed1dbb7e8c6f282adfccc7be9781de"}, - {file = "pyzmq-26.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:451e16ae8bea3d95649317b463c9f95cd9022641ec884e3d63fc67841ae86dfe"}, - {file = "pyzmq-26.1.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:906e532c814e1d579138177a00ae835cd6becbf104d45ed9093a3aaf658f6a6a"}, - {file = "pyzmq-26.1.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:05bacc4f94af468cc82808ae3293390278d5f3375bb20fef21e2034bb9a505b6"}, - {file = "pyzmq-26.1.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:57bb2acba798dc3740e913ffadd56b1fcef96f111e66f09e2a8db3050f1f12c8"}, - {file = "pyzmq-26.1.0-cp39-cp39-win32.whl", hash = "sha256:f774841bb0e8588505002962c02da420bcfb4c5056e87a139c6e45e745c0e2e2"}, - {file = "pyzmq-26.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:359c533bedc62c56415a1f5fcfd8279bc93453afdb0803307375ecf81c962402"}, - {file = "pyzmq-26.1.0-cp39-cp39-win_arm64.whl", hash = "sha256:7907419d150b19962138ecec81a17d4892ea440c184949dc29b358bc730caf69"}, - {file = "pyzmq-26.1.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:b24079a14c9596846bf7516fe75d1e2188d4a528364494859106a33d8b48be38"}, - {file = "pyzmq-26.1.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:59d0acd2976e1064f1b398a00e2c3e77ed0a157529779e23087d4c2fb8aaa416"}, - {file = "pyzmq-26.1.0-pp310-pypy310_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:911c43a4117915203c4cc8755e0f888e16c4676a82f61caee2f21b0c00e5b894"}, - {file = "pyzmq-26.1.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b10163e586cc609f5f85c9b233195554d77b1e9a0801388907441aaeb22841c5"}, - {file = "pyzmq-26.1.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:28a8b2abb76042f5fd7bd720f7fea48c0fd3e82e9de0a1bf2c0de3812ce44a42"}, - {file = "pyzmq-26.1.0-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:bef24d3e4ae2c985034439f449e3f9e06bf579974ce0e53d8a507a1577d5b2ab"}, - {file = "pyzmq-26.1.0-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:2cd0f4d314f4a2518e8970b6f299ae18cff7c44d4a1fc06fc713f791c3a9e3ea"}, - {file = "pyzmq-26.1.0-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:fa25a620eed2a419acc2cf10135b995f8f0ce78ad00534d729aa761e4adcef8a"}, - {file = "pyzmq-26.1.0-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ef3b048822dca6d231d8a8ba21069844ae38f5d83889b9b690bf17d2acc7d099"}, - {file = "pyzmq-26.1.0-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:9a6847c92d9851b59b9f33f968c68e9e441f9a0f8fc972c5580c5cd7cbc6ee24"}, - {file = "pyzmq-26.1.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:c9b9305004d7e4e6a824f4f19b6d8f32b3578aad6f19fc1122aaf320cbe3dc83"}, - {file = "pyzmq-26.1.0-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:63c1d3a65acb2f9c92dce03c4e1758cc552f1ae5c78d79a44e3bb88d2fa71f3a"}, - {file = "pyzmq-26.1.0-pp38-pypy38_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:d36b8fffe8b248a1b961c86fbdfa0129dfce878731d169ede7fa2631447331be"}, - {file = "pyzmq-26.1.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:67976d12ebfd61a3bc7d77b71a9589b4d61d0422282596cf58c62c3866916544"}, - {file = "pyzmq-26.1.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:998444debc8816b5d8d15f966e42751032d0f4c55300c48cc337f2b3e4f17d03"}, - {file = "pyzmq-26.1.0-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:e5c88b2f13bcf55fee78ea83567b9fe079ba1a4bef8b35c376043440040f7edb"}, - {file = "pyzmq-26.1.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8d906d43e1592be4b25a587b7d96527cb67277542a5611e8ea9e996182fae410"}, - {file = "pyzmq-26.1.0-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:80b0c9942430d731c786545da6be96d824a41a51742e3e374fedd9018ea43106"}, - {file = "pyzmq-26.1.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:314d11564c00b77f6224d12eb3ddebe926c301e86b648a1835c5b28176c83eab"}, - {file = "pyzmq-26.1.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:093a1a3cae2496233f14b57f4b485da01b4ff764582c854c0f42c6dd2be37f3d"}, - {file = "pyzmq-26.1.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:3c397b1b450f749a7e974d74c06d69bd22dd362142f370ef2bd32a684d6b480c"}, - {file = "pyzmq-26.1.0.tar.gz", hash = "sha256:6c5aeea71f018ebd3b9115c7cb13863dd850e98ca6b9258509de1246461a7e7f"}, -] - -[package.dependencies] -cffi = {version = "*", markers = "implementation_name == \"pypy\""} - -[[package]] -name = "qtconsole" -version = "5.5.2" -description = "Jupyter Qt console" -optional = true -python-versions = ">=3.8" -files = [ - {file = "qtconsole-5.5.2-py3-none-any.whl", hash = "sha256:42d745f3d05d36240244a04e1e1ec2a86d5d9b6edb16dbdef582ccb629e87e0b"}, - {file = "qtconsole-5.5.2.tar.gz", hash = "sha256:6b5fb11274b297463706af84dcbbd5c92273b1f619e6d25d08874b0a88516989"}, -] - -[package.dependencies] -ipykernel = ">=4.1" -jupyter-client = ">=4.1" -jupyter-core = "*" -packaging = "*" -pygments = "*" -pyzmq = ">=17.1" -qtpy = ">=2.4.0" -traitlets = "<5.2.1 || >5.2.1,<5.2.2 || >5.2.2" - -[package.extras] -doc = ["Sphinx (>=1.3)"] -test = ["flaky", "pytest", "pytest-qt"] - -[[package]] -name = "qtpy" -version = "2.4.1" -description = "Provides an abstraction layer on top of the various Qt bindings (PyQt5/6 and PySide2/6)." -optional = true -python-versions = ">=3.7" -files = [ - {file = "QtPy-2.4.1-py3-none-any.whl", hash = "sha256:1c1d8c4fa2c884ae742b069151b0abe15b3f70491f3972698c683b8e38de839b"}, - {file = "QtPy-2.4.1.tar.gz", hash = "sha256:a5a15ffd519550a1361bdc56ffc07fda56a6af7292f17c7b395d4083af632987"}, -] - -[package.dependencies] -packaging = "*" - -[package.extras] -test = ["pytest (>=6,!=7.0.0,!=7.0.1)", "pytest-cov (>=3.0.0)", "pytest-qt"] - -[[package]] -name = "referencing" -version = "0.35.1" -description = "JSON Referencing + Python" -optional = true -python-versions = ">=3.8" -files = [ - {file = "referencing-0.35.1-py3-none-any.whl", hash = "sha256:eda6d3234d62814d1c64e305c1331c9a3a6132da475ab6382eaa997b21ee75de"}, - {file = "referencing-0.35.1.tar.gz", hash = "sha256:25b42124a6c8b632a425174f24087783efb348a6f1e0008e63cd4466fedf703c"}, -] - -[package.dependencies] -attrs = ">=22.2.0" -rpds-py = ">=0.7.0" - -[[package]] -name = "requests" -version = "2.32.3" -description = "Python HTTP for Humans." -optional = true -python-versions = ">=3.8" -files = [ - {file = "requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6"}, - {file = "requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760"}, -] - -[package.dependencies] -certifi = ">=2017.4.17" -charset-normalizer = ">=2,<4" -idna = ">=2.5,<4" -urllib3 = ">=1.21.1,<3" - -[package.extras] -socks = ["PySocks (>=1.5.6,!=1.5.7)"] -use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] - -[[package]] -name = "rfc3339-validator" -version = "0.1.4" -description = "A pure python RFC3339 validator" -optional = true -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -files = [ - {file = "rfc3339_validator-0.1.4-py2.py3-none-any.whl", hash = "sha256:24f6ec1eda14ef823da9e36ec7113124b39c04d50a4d3d3a3c2859577e7791fa"}, - {file = "rfc3339_validator-0.1.4.tar.gz", hash = "sha256:138a2abdf93304ad60530167e51d2dfb9549521a836871b88d7f4695d0022f6b"}, -] - -[package.dependencies] -six = "*" - -[[package]] -name = "rfc3986-validator" -version = "0.1.1" -description = "Pure python rfc3986 validator" -optional = true -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -files = [ - {file = "rfc3986_validator-0.1.1-py2.py3-none-any.whl", hash = "sha256:2f235c432ef459970b4306369336b9d5dbdda31b510ca1e327636e01f528bfa9"}, - {file = "rfc3986_validator-0.1.1.tar.gz", hash = "sha256:3d44bde7921b3b9ec3ae4e3adca370438eccebc676456449b145d533b240d055"}, -] - -[[package]] -name = "rosco" -version = "2.9.4" -description = "A reference open source controller toolset for wind turbine applications." -optional = true -python-versions = ">=3.9" -files = [ - {file = "rosco-2.9.4-cp310-cp310-macosx_12_0_x86_64.whl", hash = "sha256:360cf9602a6ca2deaf3d589f82646d8faf19b0b1dd2493e822d25ed8f178cdf6"}, - {file = "rosco-2.9.4-cp310-cp310-macosx_13_0_x86_64.whl", hash = "sha256:e6c30c73054dbcf6208fda022c3cf332173e1df96a9c64bbd1c9c30c94a98c47"}, - {file = "rosco-2.9.4-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:2a722946cdc5d8e1a6c1f4da95c46aaa531d35c1d7524276821a9b2944af95f2"}, - {file = "rosco-2.9.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d4419fbae21c36da45ffbb071982d47382d7262976bf1165467913f7d80d2e53"}, - {file = "rosco-2.9.4-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:37c8a91ebea113ec789aa51ca904bde82b7af2d9e2e6b3715c53055a56dd8c12"}, - {file = "rosco-2.9.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a51fa398f90123def8998c7afa09398b5c6dfbab3825c4d9ef34e915541e495e"}, - {file = "rosco-2.9.4-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:1f102178ccbe7193f095dc6214d284647f71cfc0dee2235db51fc8c31773488e"}, - {file = "rosco-2.9.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:df7015013fbcfcdd7e272269682658d0eb097048fc98188be62b41a384acf289"}, - {file = "rosco-2.9.4-cp310-cp310-win_amd64.whl", hash = "sha256:c6424b6e7e1a8b42b18e6fe9438dfacbdac3f0556e2e473d2a5653e9252c5d72"}, - {file = "rosco-2.9.4-cp311-cp311-macosx_12_0_x86_64.whl", hash = "sha256:c1eed8dc7dddc37033cf8d490c711b9f7e83a378ec59eac402fe2ddb1045b083"}, - {file = "rosco-2.9.4-cp311-cp311-macosx_13_0_x86_64.whl", hash = "sha256:fc6d49ba895cf387b160b5a08d90c71beb5c60a476957ce163a91a2b59ab5efd"}, - {file = "rosco-2.9.4-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:53157f7bb4cdf42bf6b75435f30bf03c4c848ff1f3bdf1db49f206fb25a66c1c"}, - {file = "rosco-2.9.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7e01170cd9e8ceed79ab0b500e002aa89194f9f9ccdb24f64698426e23de7fbe"}, - {file = "rosco-2.9.4-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:340c2cc66d0798d030fec04d30dda1c5c9177148032cd21acb6387c5a2d14fa6"}, - {file = "rosco-2.9.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9197b5e92646a873cb7eda951fb525e5cdfbdb907d376c1088240e8443e4f50a"}, - {file = "rosco-2.9.4-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e301ba15c1c68cac5b44af6866ea498ccbf6d777008559291854d739421687cd"}, - {file = "rosco-2.9.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:192a13b9758e0177c668d9a04e9d748bd34ab6d6e721018115874e8b24f28c8f"}, - {file = "rosco-2.9.4-cp311-cp311-win_amd64.whl", hash = "sha256:124de26ba6576eda1167f05ce81886aae76400c3d23039b21023bd52732b4d61"}, - {file = "rosco-2.9.4-cp312-cp312-macosx_12_0_x86_64.whl", hash = "sha256:03594a7ee86825e16033cc1fc157367f85b481c895c0f950c3c42866a3ec2851"}, - {file = "rosco-2.9.4-cp312-cp312-macosx_13_0_x86_64.whl", hash = "sha256:46979cf83f0d4610b4697f9621d0b78f32eff0b9ab200f94be564ed4aa73bad7"}, - {file = "rosco-2.9.4-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:d9015b462efdb1fb8629c55395d7d7d8422c11a61fd85446ff227e2e3370736b"}, - {file = "rosco-2.9.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d6c4ef213a4cce2232c9da4306bea42dedf82e72ecc18b41886c172f3bcf090c"}, - {file = "rosco-2.9.4-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d5789fd019bd98b5b3f9f6cc53eb85150e7e58255b959a581b948cb6862ada63"}, - {file = "rosco-2.9.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3121ea1e95fdc01f5bf3acf30bf2722193737691bb1824a86eca86cefbe16f51"}, - {file = "rosco-2.9.4-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:3d0753be2342f168909ada1c250a709fab283198177981783546f16c659c5107"}, - {file = "rosco-2.9.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3779e3dd06d482b94a7e11449b1f9d15a3cf1984ad9d4b104a63164cb36301a0"}, - {file = "rosco-2.9.4-cp312-cp312-win_amd64.whl", hash = "sha256:1be67ad1da9e60d11924219afa6291fbd1401c02566ab931a9d281a4d415d2c5"}, - {file = "rosco-2.9.4-cp39-cp39-macosx_12_0_x86_64.whl", hash = "sha256:d02af3d9b7fe3524148c5656031859310e76cf1c72d8caec768e57b9e3cea8ce"}, - {file = "rosco-2.9.4-cp39-cp39-macosx_13_0_x86_64.whl", hash = "sha256:3c6c058536e4a7cc21e86487b11de0988fb47b12f56ff2b778f15c80a3ef3d9c"}, - {file = "rosco-2.9.4-cp39-cp39-macosx_14_0_arm64.whl", hash = "sha256:5ddf94384bdc7cfd9e45eeaf46b00c6118d0ffa48c049d3c606412b5d0f47ebe"}, - {file = "rosco-2.9.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f69e1a7fa19a8f36e7dc34165e0a90005579c72e9b07dc49d9f0b3e67cb6d371"}, - {file = "rosco-2.9.4-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6c12e9c3cb71a206e7b8bdb831abc2992ce78a90234a6d0958a77bb76a4ca777"}, - {file = "rosco-2.9.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8ac9d5a82aed59d5b9bb2793ed6730305f949f4a976f0bf021dfe315d657da42"}, - {file = "rosco-2.9.4-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:0709999e533a205dd507fd69f42612c4859f870854e9e78f8d04aa7b0183fb14"}, - {file = "rosco-2.9.4-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:39c56a06474f60eff2386b3db00a01486408e2269d9fd742c8f4d33ba8ed97b1"}, - {file = "rosco-2.9.4-cp39-cp39-win_amd64.whl", hash = "sha256:824e9bc190b5f4c815d73f62f49918bbe61954ff83ddf1a344aa2a5e733b32d4"}, - {file = "rosco-2.9.4.tar.gz", hash = "sha256:d100a782132a301ac495dfda49a3f00c5a183bd1f529ea2d211f49c8aef56fc9"}, -] - -[package.dependencies] -control = "*" -matplotlib = "*" -numpy = "*" -pandas = "*" -pyparsing = "*" -pyYAML = "*" -pyzmq = "*" -"ruamel.yaml" = "*" -scipy = "*" -treon = "*" -wisdem = "*" - -[package.extras] -dev = ["cmake"] -test = ["pytest"] - -[[package]] -name = "rpds-py" -version = "0.20.0" -description = "Python bindings to Rust's persistent data structures (rpds)" -optional = true -python-versions = ">=3.8" -files = [ - {file = "rpds_py-0.20.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:3ad0fda1635f8439cde85c700f964b23ed5fc2d28016b32b9ee5fe30da5c84e2"}, - {file = "rpds_py-0.20.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9bb4a0d90fdb03437c109a17eade42dfbf6190408f29b2744114d11586611d6f"}, - {file = "rpds_py-0.20.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c6377e647bbfd0a0b159fe557f2c6c602c159fc752fa316572f012fc0bf67150"}, - {file = "rpds_py-0.20.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:eb851b7df9dda52dc1415ebee12362047ce771fc36914586b2e9fcbd7d293b3e"}, - {file = "rpds_py-0.20.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1e0f80b739e5a8f54837be5d5c924483996b603d5502bfff79bf33da06164ee2"}, - {file = "rpds_py-0.20.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5a8c94dad2e45324fc74dce25e1645d4d14df9a4e54a30fa0ae8bad9a63928e3"}, - {file = "rpds_py-0.20.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8e604fe73ba048c06085beaf51147eaec7df856824bfe7b98657cf436623daf"}, - {file = "rpds_py-0.20.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:df3de6b7726b52966edf29663e57306b23ef775faf0ac01a3e9f4012a24a4140"}, - {file = "rpds_py-0.20.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:cf258ede5bc22a45c8e726b29835b9303c285ab46fc7c3a4cc770736b5304c9f"}, - {file = "rpds_py-0.20.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:55fea87029cded5df854ca7e192ec7bdb7ecd1d9a3f63d5c4eb09148acf4a7ce"}, - {file = "rpds_py-0.20.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:ae94bd0b2f02c28e199e9bc51485d0c5601f58780636185660f86bf80c89af94"}, - {file = "rpds_py-0.20.0-cp310-none-win32.whl", hash = "sha256:28527c685f237c05445efec62426d285e47a58fb05ba0090a4340b73ecda6dee"}, - {file = "rpds_py-0.20.0-cp310-none-win_amd64.whl", hash = "sha256:238a2d5b1cad28cdc6ed15faf93a998336eb041c4e440dd7f902528b8891b399"}, - {file = "rpds_py-0.20.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:ac2f4f7a98934c2ed6505aead07b979e6f999389f16b714448fb39bbaa86a489"}, - {file = "rpds_py-0.20.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:220002c1b846db9afd83371d08d239fdc865e8f8c5795bbaec20916a76db3318"}, - {file = "rpds_py-0.20.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8d7919548df3f25374a1f5d01fbcd38dacab338ef5f33e044744b5c36729c8db"}, - {file = "rpds_py-0.20.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:758406267907b3781beee0f0edfe4a179fbd97c0be2e9b1154d7f0a1279cf8e5"}, - {file = "rpds_py-0.20.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3d61339e9f84a3f0767b1995adfb171a0d00a1185192718a17af6e124728e0f5"}, - {file = "rpds_py-0.20.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1259c7b3705ac0a0bd38197565a5d603218591d3f6cee6e614e380b6ba61c6f6"}, - {file = "rpds_py-0.20.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5c1dc0f53856b9cc9a0ccca0a7cc61d3d20a7088201c0937f3f4048c1718a209"}, - {file = "rpds_py-0.20.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:7e60cb630f674a31f0368ed32b2a6b4331b8350d67de53c0359992444b116dd3"}, - {file = "rpds_py-0.20.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:dbe982f38565bb50cb7fb061ebf762c2f254ca3d8c20d4006878766e84266272"}, - {file = "rpds_py-0.20.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:514b3293b64187172bc77c8fb0cdae26981618021053b30d8371c3a902d4d5ad"}, - {file = "rpds_py-0.20.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:d0a26ffe9d4dd35e4dfdd1e71f46401cff0181c75ac174711ccff0459135fa58"}, - {file = "rpds_py-0.20.0-cp311-none-win32.whl", hash = "sha256:89c19a494bf3ad08c1da49445cc5d13d8fefc265f48ee7e7556839acdacf69d0"}, - {file = "rpds_py-0.20.0-cp311-none-win_amd64.whl", hash = "sha256:c638144ce971df84650d3ed0096e2ae7af8e62ecbbb7b201c8935c370df00a2c"}, - {file = "rpds_py-0.20.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:a84ab91cbe7aab97f7446652d0ed37d35b68a465aeef8fc41932a9d7eee2c1a6"}, - {file = "rpds_py-0.20.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:56e27147a5a4c2c21633ff8475d185734c0e4befd1c989b5b95a5d0db699b21b"}, - {file = "rpds_py-0.20.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2580b0c34583b85efec8c5c5ec9edf2dfe817330cc882ee972ae650e7b5ef739"}, - {file = "rpds_py-0.20.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b80d4a7900cf6b66bb9cee5c352b2d708e29e5a37fe9bf784fa97fc11504bf6c"}, - {file = "rpds_py-0.20.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:50eccbf054e62a7b2209b28dc7a22d6254860209d6753e6b78cfaeb0075d7bee"}, - {file = "rpds_py-0.20.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:49a8063ea4296b3a7e81a5dfb8f7b2d73f0b1c20c2af401fb0cdf22e14711a96"}, - {file = "rpds_py-0.20.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ea438162a9fcbee3ecf36c23e6c68237479f89f962f82dae83dc15feeceb37e4"}, - {file = "rpds_py-0.20.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:18d7585c463087bddcfa74c2ba267339f14f2515158ac4db30b1f9cbdb62c8ef"}, - {file = "rpds_py-0.20.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d4c7d1a051eeb39f5c9547e82ea27cbcc28338482242e3e0b7768033cb083821"}, - {file = "rpds_py-0.20.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:e4df1e3b3bec320790f699890d41c59d250f6beda159ea3c44c3f5bac1976940"}, - {file = "rpds_py-0.20.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:2cf126d33a91ee6eedc7f3197b53e87a2acdac63602c0f03a02dd69e4b138174"}, - {file = "rpds_py-0.20.0-cp312-none-win32.whl", hash = "sha256:8bc7690f7caee50b04a79bf017a8d020c1f48c2a1077ffe172abec59870f1139"}, - {file = "rpds_py-0.20.0-cp312-none-win_amd64.whl", hash = "sha256:0e13e6952ef264c40587d510ad676a988df19adea20444c2b295e536457bc585"}, - {file = "rpds_py-0.20.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:aa9a0521aeca7d4941499a73ad7d4f8ffa3d1affc50b9ea11d992cd7eff18a29"}, - {file = "rpds_py-0.20.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:4a1f1d51eccb7e6c32ae89243cb352389228ea62f89cd80823ea7dd1b98e0b91"}, - {file = "rpds_py-0.20.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8a86a9b96070674fc88b6f9f71a97d2c1d3e5165574615d1f9168ecba4cecb24"}, - {file = "rpds_py-0.20.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6c8ef2ebf76df43f5750b46851ed1cdf8f109d7787ca40035fe19fbdc1acc5a7"}, - {file = "rpds_py-0.20.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b74b25f024b421d5859d156750ea9a65651793d51b76a2e9238c05c9d5f203a9"}, - {file = "rpds_py-0.20.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:57eb94a8c16ab08fef6404301c38318e2c5a32216bf5de453e2714c964c125c8"}, - {file = "rpds_py-0.20.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e1940dae14e715e2e02dfd5b0f64a52e8374a517a1e531ad9412319dc3ac7879"}, - {file = "rpds_py-0.20.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d20277fd62e1b992a50c43f13fbe13277a31f8c9f70d59759c88f644d66c619f"}, - {file = "rpds_py-0.20.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:06db23d43f26478303e954c34c75182356ca9aa7797d22c5345b16871ab9c45c"}, - {file = "rpds_py-0.20.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:b2a5db5397d82fa847e4c624b0c98fe59d2d9b7cf0ce6de09e4d2e80f8f5b3f2"}, - {file = "rpds_py-0.20.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5a35df9f5548fd79cb2f52d27182108c3e6641a4feb0f39067911bf2adaa3e57"}, - {file = "rpds_py-0.20.0-cp313-none-win32.whl", hash = "sha256:fd2d84f40633bc475ef2d5490b9c19543fbf18596dcb1b291e3a12ea5d722f7a"}, - {file = "rpds_py-0.20.0-cp313-none-win_amd64.whl", hash = "sha256:9bc2d153989e3216b0559251b0c260cfd168ec78b1fac33dd485750a228db5a2"}, - {file = "rpds_py-0.20.0-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:f2fbf7db2012d4876fb0d66b5b9ba6591197b0f165db8d99371d976546472a24"}, - {file = "rpds_py-0.20.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:1e5f3cd7397c8f86c8cc72d5a791071431c108edd79872cdd96e00abd8497d29"}, - {file = "rpds_py-0.20.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ce9845054c13696f7af7f2b353e6b4f676dab1b4b215d7fe5e05c6f8bb06f965"}, - {file = "rpds_py-0.20.0-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c3e130fd0ec56cb76eb49ef52faead8ff09d13f4527e9b0c400307ff72b408e1"}, - {file = "rpds_py-0.20.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4b16aa0107ecb512b568244ef461f27697164d9a68d8b35090e9b0c1c8b27752"}, - {file = "rpds_py-0.20.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:aa7f429242aae2947246587d2964fad750b79e8c233a2367f71b554e9447949c"}, - {file = "rpds_py-0.20.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:af0fc424a5842a11e28956e69395fbbeab2c97c42253169d87e90aac2886d751"}, - {file = "rpds_py-0.20.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b8c00a3b1e70c1d3891f0db1b05292747f0dbcfb49c43f9244d04c70fbc40eb8"}, - {file = "rpds_py-0.20.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:40ce74fc86ee4645d0a225498d091d8bc61f39b709ebef8204cb8b5a464d3c0e"}, - {file = "rpds_py-0.20.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:4fe84294c7019456e56d93e8ababdad5a329cd25975be749c3f5f558abb48253"}, - {file = "rpds_py-0.20.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:338ca4539aad4ce70a656e5187a3a31c5204f261aef9f6ab50e50bcdffaf050a"}, - {file = "rpds_py-0.20.0-cp38-none-win32.whl", hash = "sha256:54b43a2b07db18314669092bb2de584524d1ef414588780261e31e85846c26a5"}, - {file = "rpds_py-0.20.0-cp38-none-win_amd64.whl", hash = "sha256:a1862d2d7ce1674cffa6d186d53ca95c6e17ed2b06b3f4c476173565c862d232"}, - {file = "rpds_py-0.20.0-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:3fde368e9140312b6e8b6c09fb9f8c8c2f00999d1823403ae90cc00480221b22"}, - {file = "rpds_py-0.20.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9824fb430c9cf9af743cf7aaf6707bf14323fb51ee74425c380f4c846ea70789"}, - {file = "rpds_py-0.20.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:11ef6ce74616342888b69878d45e9f779b95d4bd48b382a229fe624a409b72c5"}, - {file = "rpds_py-0.20.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c52d3f2f82b763a24ef52f5d24358553e8403ce05f893b5347098014f2d9eff2"}, - {file = "rpds_py-0.20.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9d35cef91e59ebbeaa45214861874bc6f19eb35de96db73e467a8358d701a96c"}, - {file = "rpds_py-0.20.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d72278a30111e5b5525c1dd96120d9e958464316f55adb030433ea905866f4de"}, - {file = "rpds_py-0.20.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b4c29cbbba378759ac5786730d1c3cb4ec6f8ababf5c42a9ce303dc4b3d08cda"}, - {file = "rpds_py-0.20.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6632f2d04f15d1bd6fe0eedd3b86d9061b836ddca4c03d5cf5c7e9e6b7c14580"}, - {file = "rpds_py-0.20.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:d0b67d87bb45ed1cd020e8fbf2307d449b68abc45402fe1a4ac9e46c3c8b192b"}, - {file = "rpds_py-0.20.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:ec31a99ca63bf3cd7f1a5ac9fe95c5e2d060d3c768a09bc1d16e235840861420"}, - {file = "rpds_py-0.20.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:22e6c9976e38f4d8c4a63bd8a8edac5307dffd3ee7e6026d97f3cc3a2dc02a0b"}, - {file = "rpds_py-0.20.0-cp39-none-win32.whl", hash = "sha256:569b3ea770c2717b730b61998b6c54996adee3cef69fc28d444f3e7920313cf7"}, - {file = "rpds_py-0.20.0-cp39-none-win_amd64.whl", hash = "sha256:e6900ecdd50ce0facf703f7a00df12374b74bbc8ad9fe0f6559947fb20f82364"}, - {file = "rpds_py-0.20.0-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:617c7357272c67696fd052811e352ac54ed1d9b49ab370261a80d3b6ce385045"}, - {file = "rpds_py-0.20.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:9426133526f69fcaba6e42146b4e12d6bc6c839b8b555097020e2b78ce908dcc"}, - {file = "rpds_py-0.20.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:deb62214c42a261cb3eb04d474f7155279c1a8a8c30ac89b7dcb1721d92c3c02"}, - {file = "rpds_py-0.20.0-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fcaeb7b57f1a1e071ebd748984359fef83ecb026325b9d4ca847c95bc7311c92"}, - {file = "rpds_py-0.20.0-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d454b8749b4bd70dd0a79f428731ee263fa6995f83ccb8bada706e8d1d3ff89d"}, - {file = "rpds_py-0.20.0-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d807dc2051abe041b6649681dce568f8e10668e3c1c6543ebae58f2d7e617855"}, - {file = "rpds_py-0.20.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c3c20f0ddeb6e29126d45f89206b8291352b8c5b44384e78a6499d68b52ae511"}, - {file = "rpds_py-0.20.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b7f19250ceef892adf27f0399b9e5afad019288e9be756d6919cb58892129f51"}, - {file = "rpds_py-0.20.0-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:4f1ed4749a08379555cebf4650453f14452eaa9c43d0a95c49db50c18b7da075"}, - {file = "rpds_py-0.20.0-pp310-pypy310_pp73-musllinux_1_2_i686.whl", hash = "sha256:dcedf0b42bcb4cfff4101d7771a10532415a6106062f005ab97d1d0ab5681c60"}, - {file = "rpds_py-0.20.0-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:39ed0d010457a78f54090fafb5d108501b5aa5604cc22408fc1c0c77eac14344"}, - {file = "rpds_py-0.20.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:bb273176be34a746bdac0b0d7e4e2c467323d13640b736c4c477881a3220a989"}, - {file = "rpds_py-0.20.0-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:f918a1a130a6dfe1d7fe0f105064141342e7dd1611f2e6a21cd2f5c8cb1cfb3e"}, - {file = "rpds_py-0.20.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:f60012a73aa396be721558caa3a6fd49b3dd0033d1675c6d59c4502e870fcf0c"}, - {file = "rpds_py-0.20.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3d2b1ad682a3dfda2a4e8ad8572f3100f95fad98cb99faf37ff0ddfe9cbf9d03"}, - {file = "rpds_py-0.20.0-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:614fdafe9f5f19c63ea02817fa4861c606a59a604a77c8cdef5aa01d28b97921"}, - {file = "rpds_py-0.20.0-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fa518bcd7600c584bf42e6617ee8132869e877db2f76bcdc281ec6a4113a53ab"}, - {file = "rpds_py-0.20.0-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f0475242f447cc6cb8a9dd486d68b2ef7fbee84427124c232bff5f63b1fe11e5"}, - {file = "rpds_py-0.20.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f90a4cd061914a60bd51c68bcb4357086991bd0bb93d8aa66a6da7701370708f"}, - {file = "rpds_py-0.20.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:def7400461c3a3f26e49078302e1c1b38f6752342c77e3cf72ce91ca69fb1bc1"}, - {file = "rpds_py-0.20.0-pp39-pypy39_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:65794e4048ee837494aea3c21a28ad5fc080994dfba5b036cf84de37f7ad5074"}, - {file = "rpds_py-0.20.0-pp39-pypy39_pp73-musllinux_1_2_i686.whl", hash = "sha256:faefcc78f53a88f3076b7f8be0a8f8d35133a3ecf7f3770895c25f8813460f08"}, - {file = "rpds_py-0.20.0-pp39-pypy39_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:5b4f105deeffa28bbcdff6c49b34e74903139afa690e35d2d9e3c2c2fba18cec"}, - {file = "rpds_py-0.20.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:fdfc3a892927458d98f3d55428ae46b921d1f7543b89382fdb483f5640daaec8"}, - {file = "rpds_py-0.20.0.tar.gz", hash = "sha256:d72a210824facfdaf8768cf2d7ca25a042c30320b3020de2fa04640920d4e121"}, -] - -[[package]] -name = "ruamel-yaml" -version = "0.18.6" -description = "ruamel.yaml is a YAML parser/emitter that supports roundtrip preservation of comments, seq/map flow style, and map key order" -optional = false -python-versions = ">=3.7" -files = [ - {file = "ruamel.yaml-0.18.6-py3-none-any.whl", hash = "sha256:57b53ba33def16c4f3d807c0ccbc00f8a6081827e81ba2491691b76882d0c636"}, - {file = "ruamel.yaml-0.18.6.tar.gz", hash = "sha256:8b27e6a217e786c6fbe5634d8f3f11bc63e0f80f6a5890f28863d9c45aac311b"}, -] - -[package.dependencies] -"ruamel.yaml.clib" = {version = ">=0.2.7", markers = "platform_python_implementation == \"CPython\" and python_version < \"3.13\""} - -[package.extras] -docs = ["mercurial (>5.7)", "ryd"] -jinja2 = ["ruamel.yaml.jinja2 (>=0.2)"] - -[[package]] -name = "ruamel-yaml-clib" -version = "0.2.8" -description = "C version of reader, parser and emitter for ruamel.yaml derived from libyaml" -optional = false -python-versions = ">=3.6" -files = [ - {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:b42169467c42b692c19cf539c38d4602069d8c1505e97b86387fcf7afb766e1d"}, - {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-macosx_13_0_arm64.whl", hash = "sha256:07238db9cbdf8fc1e9de2489a4f68474e70dffcb32232db7c08fa61ca0c7c462"}, - {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:fff3573c2db359f091e1589c3d7c5fc2f86f5bdb6f24252c2d8e539d4e45f412"}, - {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-manylinux_2_24_aarch64.whl", hash = "sha256:aa2267c6a303eb483de8d02db2871afb5c5fc15618d894300b88958f729ad74f"}, - {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:840f0c7f194986a63d2c2465ca63af8ccbbc90ab1c6001b1978f05119b5e7334"}, - {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:024cfe1fc7c7f4e1aff4a81e718109e13409767e4f871443cbff3dba3578203d"}, - {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-win32.whl", hash = "sha256:c69212f63169ec1cfc9bb44723bf2917cbbd8f6191a00ef3410f5a7fe300722d"}, - {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-win_amd64.whl", hash = "sha256:cabddb8d8ead485e255fe80429f833172b4cadf99274db39abc080e068cbcc31"}, - {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:bef08cd86169d9eafb3ccb0a39edb11d8e25f3dae2b28f5c52fd997521133069"}, - {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-macosx_13_0_arm64.whl", hash = "sha256:b16420e621d26fdfa949a8b4b47ade8810c56002f5389970db4ddda51dbff248"}, - {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:25c515e350e5b739842fc3228d662413ef28f295791af5e5110b543cf0b57d9b"}, - {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-manylinux_2_24_aarch64.whl", hash = "sha256:1707814f0d9791df063f8c19bb51b0d1278b8e9a2353abbb676c2f685dee6afe"}, - {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:46d378daaac94f454b3a0e3d8d78cafd78a026b1d71443f4966c696b48a6d899"}, - {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:09b055c05697b38ecacb7ac50bdab2240bfca1a0c4872b0fd309bb07dc9aa3a9"}, - {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-win32.whl", hash = "sha256:53a300ed9cea38cf5a2a9b069058137c2ca1ce658a874b79baceb8f892f915a7"}, - {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-win_amd64.whl", hash = "sha256:c2a72e9109ea74e511e29032f3b670835f8a59bbdc9ce692c5b4ed91ccf1eedb"}, - {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:ebc06178e8821efc9692ea7544aa5644217358490145629914d8020042c24aa1"}, - {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-macosx_13_0_arm64.whl", hash = "sha256:edaef1c1200c4b4cb914583150dcaa3bc30e592e907c01117c08b13a07255ec2"}, - {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d176b57452ab5b7028ac47e7b3cf644bcfdc8cacfecf7e71759f7f51a59e5c92"}, - {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-manylinux_2_24_aarch64.whl", hash = "sha256:1dc67314e7e1086c9fdf2680b7b6c2be1c0d8e3a8279f2e993ca2a7545fecf62"}, - {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:3213ece08ea033eb159ac52ae052a4899b56ecc124bb80020d9bbceeb50258e9"}, - {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:aab7fd643f71d7946f2ee58cc88c9b7bfc97debd71dcc93e03e2d174628e7e2d"}, - {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-win32.whl", hash = "sha256:5c365d91c88390c8d0a8545df0b5857172824b1c604e867161e6b3d59a827eaa"}, - {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-win_amd64.whl", hash = "sha256:1758ce7d8e1a29d23de54a16ae867abd370f01b5a69e1a3ba75223eaa3ca1a1b"}, - {file = "ruamel.yaml.clib-0.2.8-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:a5aa27bad2bb83670b71683aae140a1f52b0857a2deff56ad3f6c13a017a26ed"}, - {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c58ecd827313af6864893e7af0a3bb85fd529f862b6adbefe14643947cfe2942"}, - {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-macosx_12_0_arm64.whl", hash = "sha256:f481f16baec5290e45aebdc2a5168ebc6d35189ae6fea7a58787613a25f6e875"}, - {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-manylinux_2_24_aarch64.whl", hash = "sha256:77159f5d5b5c14f7c34073862a6b7d34944075d9f93e681638f6d753606c6ce6"}, - {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:7f67a1ee819dc4562d444bbafb135832b0b909f81cc90f7aa00260968c9ca1b3"}, - {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:4ecbf9c3e19f9562c7fdd462e8d18dd902a47ca046a2e64dba80699f0b6c09b7"}, - {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:87ea5ff66d8064301a154b3933ae406b0863402a799b16e4a1d24d9fbbcbe0d3"}, - {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-win32.whl", hash = "sha256:75e1ed13e1f9de23c5607fe6bd1aeaae21e523b32d83bb33918245361e9cc51b"}, - {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-win_amd64.whl", hash = "sha256:3f215c5daf6a9d7bbed4a0a4f760f3113b10e82ff4c5c44bec20a68c8014f675"}, - {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1b617618914cb00bf5c34d4357c37aa15183fa229b24767259657746c9077615"}, - {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-macosx_12_0_arm64.whl", hash = "sha256:a6a9ffd280b71ad062eae53ac1659ad86a17f59a0fdc7699fd9be40525153337"}, - {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-manylinux_2_24_aarch64.whl", hash = "sha256:305889baa4043a09e5b76f8e2a51d4ffba44259f6b4c72dec8ca56207d9c6fe1"}, - {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:700e4ebb569e59e16a976857c8798aee258dceac7c7d6b50cab63e080058df91"}, - {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:e2b4c44b60eadec492926a7270abb100ef9f72798e18743939bdbf037aab8c28"}, - {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:e79e5db08739731b0ce4850bed599235d601701d5694c36570a99a0c5ca41a9d"}, - {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-win32.whl", hash = "sha256:955eae71ac26c1ab35924203fda6220f84dce57d6d7884f189743e2abe3a9fbe"}, - {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-win_amd64.whl", hash = "sha256:56f4252222c067b4ce51ae12cbac231bce32aee1d33fbfc9d17e5b8d6966c312"}, - {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:03d1162b6d1df1caa3a4bd27aa51ce17c9afc2046c31b0ad60a0a96ec22f8001"}, - {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:bba64af9fa9cebe325a62fa398760f5c7206b215201b0ec825005f1b18b9bccf"}, - {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-manylinux_2_24_aarch64.whl", hash = "sha256:a1a45e0bb052edf6a1d3a93baef85319733a888363938e1fc9924cb00c8df24c"}, - {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:da09ad1c359a728e112d60116f626cc9f29730ff3e0e7db72b9a2dbc2e4beed5"}, - {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:184565012b60405d93838167f425713180b949e9d8dd0bbc7b49f074407c5a8b"}, - {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a75879bacf2c987c003368cf14bed0ffe99e8e85acfa6c0bfffc21a090f16880"}, - {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-win32.whl", hash = "sha256:84b554931e932c46f94ab306913ad7e11bba988104c5cff26d90d03f68258cd5"}, - {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-win_amd64.whl", hash = "sha256:25ac8c08322002b06fa1d49d1646181f0b2c72f5cbc15a85e80b4c30a544bb15"}, - {file = "ruamel.yaml.clib-0.2.8.tar.gz", hash = "sha256:beb2e0404003de9a4cab9753a8805a8fe9320ee6673136ed7f04255fe60bb512"}, -] - -[[package]] -name = "scipy" -version = "1.13.1" -description = "Fundamental algorithms for scientific computing in Python" -optional = true -python-versions = ">=3.9" -files = [ - {file = "scipy-1.13.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:20335853b85e9a49ff7572ab453794298bcf0354d8068c5f6775a0eabf350aca"}, - {file = "scipy-1.13.1-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:d605e9c23906d1994f55ace80e0125c587f96c020037ea6aa98d01b4bd2e222f"}, - {file = "scipy-1.13.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cfa31f1def5c819b19ecc3a8b52d28ffdcc7ed52bb20c9a7589669dd3c250989"}, - {file = "scipy-1.13.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f26264b282b9da0952a024ae34710c2aff7d27480ee91a2e82b7b7073c24722f"}, - {file = "scipy-1.13.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:eccfa1906eacc02de42d70ef4aecea45415f5be17e72b61bafcfd329bdc52e94"}, - {file = "scipy-1.13.1-cp310-cp310-win_amd64.whl", hash = "sha256:2831f0dc9c5ea9edd6e51e6e769b655f08ec6db6e2e10f86ef39bd32eb11da54"}, - {file = "scipy-1.13.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:27e52b09c0d3a1d5b63e1105f24177e544a222b43611aaf5bc44d4a0979e32f9"}, - {file = "scipy-1.13.1-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:54f430b00f0133e2224c3ba42b805bfd0086fe488835effa33fa291561932326"}, - {file = "scipy-1.13.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e89369d27f9e7b0884ae559a3a956e77c02114cc60a6058b4e5011572eea9299"}, - {file = "scipy-1.13.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a78b4b3345f1b6f68a763c6e25c0c9a23a9fd0f39f5f3d200efe8feda560a5fa"}, - {file = "scipy-1.13.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:45484bee6d65633752c490404513b9ef02475b4284c4cfab0ef946def50b3f59"}, - {file = "scipy-1.13.1-cp311-cp311-win_amd64.whl", hash = "sha256:5713f62f781eebd8d597eb3f88b8bf9274e79eeabf63afb4a737abc6c84ad37b"}, - {file = "scipy-1.13.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5d72782f39716b2b3509cd7c33cdc08c96f2f4d2b06d51e52fb45a19ca0c86a1"}, - {file = "scipy-1.13.1-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:017367484ce5498445aade74b1d5ab377acdc65e27095155e448c88497755a5d"}, - {file = "scipy-1.13.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:949ae67db5fa78a86e8fa644b9a6b07252f449dcf74247108c50e1d20d2b4627"}, - {file = "scipy-1.13.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:de3ade0e53bc1f21358aa74ff4830235d716211d7d077e340c7349bc3542e884"}, - {file = "scipy-1.13.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:2ac65fb503dad64218c228e2dc2d0a0193f7904747db43014645ae139c8fad16"}, - {file = "scipy-1.13.1-cp312-cp312-win_amd64.whl", hash = "sha256:cdd7dacfb95fea358916410ec61bbc20440f7860333aee6d882bb8046264e949"}, - {file = "scipy-1.13.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:436bbb42a94a8aeef855d755ce5a465479c721e9d684de76bf61a62e7c2b81d5"}, - {file = "scipy-1.13.1-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:8335549ebbca860c52bf3d02f80784e91a004b71b059e3eea9678ba994796a24"}, - {file = "scipy-1.13.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d533654b7d221a6a97304ab63c41c96473ff04459e404b83275b60aa8f4b7004"}, - {file = "scipy-1.13.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:637e98dcf185ba7f8e663e122ebf908c4702420477ae52a04f9908707456ba4d"}, - {file = "scipy-1.13.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a014c2b3697bde71724244f63de2476925596c24285c7a637364761f8710891c"}, - {file = "scipy-1.13.1-cp39-cp39-win_amd64.whl", hash = "sha256:392e4ec766654852c25ebad4f64e4e584cf19820b980bc04960bca0b0cd6eaa2"}, - {file = "scipy-1.13.1.tar.gz", hash = "sha256:095a87a0312b08dfd6a6155cbbd310a8c51800fc931b8c0b84003014b874ed3c"}, -] - -[package.dependencies] -numpy = ">=1.22.4,<2.3" - -[package.extras] -dev = ["cython-lint (>=0.12.2)", "doit (>=0.36.0)", "mypy", "pycodestyle", "pydevtool", "rich-click", "ruff", "types-psutil", "typing_extensions"] -doc = ["jupyterlite-pyodide-kernel", "jupyterlite-sphinx (>=0.12.0)", "jupytext", "matplotlib (>=3.5)", "myst-nb", "numpydoc", "pooch", "pydata-sphinx-theme (>=0.15.2)", "sphinx (>=5.0.0)", "sphinx-design (>=0.4.0)"] -test = ["array-api-strict", "asv", "gmpy2", "hypothesis (>=6.30)", "mpmath", "pooch", "pytest", "pytest-cov", "pytest-timeout", "pytest-xdist", "scikit-umfpack", "threadpoolctl"] - -[[package]] -name = "send2trash" -version = "1.8.3" -description = "Send file to trash natively under Mac OS X, Windows and Linux" -optional = true -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" -files = [ - {file = "Send2Trash-1.8.3-py3-none-any.whl", hash = "sha256:0c31227e0bd08961c7665474a3d1ef7193929fedda4233843689baa056be46c9"}, - {file = "Send2Trash-1.8.3.tar.gz", hash = "sha256:b18e7a3966d99871aefeb00cfbcfdced55ce4871194810fc71f4aa484b953abf"}, -] - -[package.extras] -nativelib = ["pyobjc-framework-Cocoa", "pywin32"] -objc = ["pyobjc-framework-Cocoa"] -win32 = ["pywin32"] - -[[package]] -name = "setuptools" -version = "72.2.0" -description = "Easily download, build, install, upgrade, and uninstall Python packages" -optional = true -python-versions = ">=3.8" -files = [ - {file = "setuptools-72.2.0-py3-none-any.whl", hash = "sha256:f11dd94b7bae3a156a95ec151f24e4637fb4fa19c878e4d191bfb8b2d82728c4"}, - {file = "setuptools-72.2.0.tar.gz", hash = "sha256:80aacbf633704e9c8bfa1d99fa5dd4dc59573efcf9e4042c13d3bcef91ac2ef9"}, -] - -[package.extras] -core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.text (>=3.7)", "more-itertools (>=8.8)", "ordered-set (>=3.1.1)", "packaging (>=24)", "platformdirs (>=2.6.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] -doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "mypy (==1.11.*)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy", "pytest-perf", "pytest-ruff (<0.4)", "pytest-ruff (>=0.2.1)", "pytest-ruff (>=0.3.2)", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] - -[[package]] -name = "simpy" -version = "4.1.1" -description = "Event discrete, process based simulation for Python." -optional = true -python-versions = ">=3.8" -files = [ - {file = "simpy-4.1.1-py3-none-any.whl", hash = "sha256:7c5ae380240fd2238671160e4830956f8055830a8317edf5c05e495b3823cd88"}, - {file = "simpy-4.1.1.tar.gz", hash = "sha256:06d0750a7884b11e0e8e20ce0bc7c6d4ed5f1743d456695340d13fdff95001a6"}, -] - -[[package]] -name = "six" -version = "1.16.0" -description = "Python 2 and 3 compatibility utilities" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" -files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, -] - -[[package]] -name = "sniffio" -version = "1.3.1" -description = "Sniff out which async library your code is running under" -optional = true -python-versions = ">=3.7" -files = [ - {file = "sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2"}, - {file = "sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc"}, -] - -[[package]] -name = "sortedcontainers" -version = "2.4.0" -description = "Sorted Containers -- Sorted List, Sorted Dict, Sorted Set" -optional = true -python-versions = "*" -files = [ - {file = "sortedcontainers-2.4.0-py2.py3-none-any.whl", hash = "sha256:a163dcaede0f1c021485e957a39245190e74249897e2ae4b2aa38595db237ee0"}, - {file = "sortedcontainers-2.4.0.tar.gz", hash = "sha256:25caa5a06cc30b6b83d11423433f65d1f9d76c4c6a0c90e3379eaa43b9bfdb88"}, -] - -[[package]] -name = "soupsieve" -version = "2.6" -description = "A modern CSS selector implementation for Beautiful Soup." -optional = true -python-versions = ">=3.8" -files = [ - {file = "soupsieve-2.6-py3-none-any.whl", hash = "sha256:e72c4ff06e4fb6e4b5a9f0f55fe6e81514581fca1515028625d0f299c602ccc9"}, - {file = "soupsieve-2.6.tar.gz", hash = "sha256:e2e68417777af359ec65daac1057404a3c8a5455bb8abc36f1a9866ab1a51abb"}, -] - -[[package]] -name = "stack-data" -version = "0.6.3" -description = "Extract data from python stack frames and tracebacks for informative displays" -optional = true -python-versions = "*" -files = [ - {file = "stack_data-0.6.3-py3-none-any.whl", hash = "sha256:d5558e0c25a4cb0853cddad3d77da9891a08cb85dd9f9f91b9f8cd66e511e695"}, - {file = "stack_data-0.6.3.tar.gz", hash = "sha256:836a778de4fec4dcd1dcd89ed8abff8a221f58308462e1c4aa2a3cf30148f0b9"}, -] - -[package.dependencies] -asttokens = ">=2.1.0" -executing = ">=1.2.0" -pure-eval = "*" - -[package.extras] -tests = ["cython", "littleutils", "pygments", "pytest", "typeguard"] - -[[package]] -name = "statsmodels" -version = "0.14.2" -description = "Statistical computations and models for Python" -optional = true -python-versions = ">=3.9" -files = [ - {file = "statsmodels-0.14.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:df5d6f95c46f0341da6c79ee7617e025bf2b371e190a8e60af1ae9cabbdb7a97"}, - {file = "statsmodels-0.14.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a87ef21fadb445b650f327340dde703f13aec1540f3d497afb66324499dea97a"}, - {file = "statsmodels-0.14.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5827a12e3ede2b98a784476d61d6bec43011fedb64aa815f2098e0573bece257"}, - {file = "statsmodels-0.14.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10f2b7611a61adb7d596a6d239abdf1a4d5492b931b00d5ed23d32844d40e48e"}, - {file = "statsmodels-0.14.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c254c66142f1167b4c7d031cf8db55294cc62ff3280e090fc45bd10a7f5fd029"}, - {file = "statsmodels-0.14.2-cp310-cp310-win_amd64.whl", hash = "sha256:0e46e9d59293c1af4cc1f4e5248f17e7e7bc596bfce44d327c789ac27f09111b"}, - {file = "statsmodels-0.14.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:50fcb633987779e795142f51ba49fb27648d46e8a1382b32ebe8e503aaabaa9e"}, - {file = "statsmodels-0.14.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:876794068abfaeed41df71b7887000031ecf44fbfa6b50d53ccb12ebb4ab747a"}, - {file = "statsmodels-0.14.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7a91f6c4943de13e3ce2e20ee3b5d26d02bd42300616a421becd53756f5deb37"}, - {file = "statsmodels-0.14.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4864a1c4615c5ea5f2e3b078a75bdedc90dd9da210a37e0738e064b419eccee2"}, - {file = "statsmodels-0.14.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:afbd92410e0df06f3d8c4e7c0e2e71f63f4969531f280fb66059e2ecdb6e0415"}, - {file = "statsmodels-0.14.2-cp311-cp311-win_amd64.whl", hash = "sha256:8e004cfad0e46ce73fe3f3812010c746f0d4cfd48e307b45c14e9e360f3d2510"}, - {file = "statsmodels-0.14.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:eb0ba1ad3627705f5ae20af6b2982f500546d43892543b36c7bca3e2f87105e7"}, - {file = "statsmodels-0.14.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:90fd2f0110b73fc3fa5a2f21c3ca99b0e22285cccf38e56b5b8fd8ce28791b0f"}, - {file = "statsmodels-0.14.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac780ad9ff552773798829a0b9c46820b0faa10e6454891f5e49a845123758ab"}, - {file = "statsmodels-0.14.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:55d1742778400ae67acb04b50a2c7f5804182f8a874bd09ca397d69ed159a751"}, - {file = "statsmodels-0.14.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:f870d14a587ea58a3b596aa994c2ed889cc051f9e450e887d2c83656fc6a64bf"}, - {file = "statsmodels-0.14.2-cp312-cp312-win_amd64.whl", hash = "sha256:f450fcbae214aae66bd9d2b9af48e0f8ba1cb0e8596c6ebb34e6e3f0fec6542c"}, - {file = "statsmodels-0.14.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:201c3d00929c4a67cda1fe05b098c8dcf1b1eeefa88e80a8f963a844801ed59f"}, - {file = "statsmodels-0.14.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9edefa4ce08e40bc1d67d2f79bc686ee5e238e801312b5a029ee7786448c389a"}, - {file = "statsmodels-0.14.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:29c78a7601fdae1aa32104c5ebff2e0b72c26f33e870e2f94ab1bcfd927ece9b"}, - {file = "statsmodels-0.14.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f36494df7c03d63168fccee5038a62f469469ed6a4dd6eaeb9338abedcd0d5f5"}, - {file = "statsmodels-0.14.2-cp39-cp39-win_amd64.whl", hash = "sha256:8875823bdd41806dc853333cc4e1b7ef9481bad2380a999e66ea42382cf2178d"}, - {file = "statsmodels-0.14.2.tar.gz", hash = "sha256:890550147ad3a81cda24f0ba1a5c4021adc1601080bd00e191ae7cd6feecd6ad"}, -] - -[package.dependencies] -numpy = ">=1.22.3" -packaging = ">=21.3" -pandas = ">=1.4,<2.1.0 || >2.1.0" -patsy = ">=0.5.6" -scipy = ">=1.8,<1.9.2 || >1.9.2" - -[package.extras] -build = ["cython (>=0.29.33)"] -develop = ["colorama", "cython (>=0.29.33)", "cython (>=3.0.10,<4)", "flake8", "isort", "joblib", "matplotlib (>=3)", "pytest (>=7.3.0,<8)", "pytest-cov", "pytest-randomly", "pytest-xdist", "pywinpty", "setuptools-scm[toml] (>=8.0,<9.0)"] -docs = ["ipykernel", "jupyter-client", "matplotlib", "nbconvert", "nbformat", "numpydoc", "pandas-datareader", "sphinx"] - -[[package]] -name = "terminado" -version = "0.18.1" -description = "Tornado websocket backend for the Xterm.js Javascript terminal emulator library." -optional = true -python-versions = ">=3.8" -files = [ - {file = "terminado-0.18.1-py3-none-any.whl", hash = "sha256:a4468e1b37bb318f8a86514f65814e1afc977cf29b3992a4500d9dd305dcceb0"}, - {file = "terminado-0.18.1.tar.gz", hash = "sha256:de09f2c4b85de4765f7714688fff57d3e75bad1f909b589fde880460c753fd2e"}, -] - -[package.dependencies] -ptyprocess = {version = "*", markers = "os_name != \"nt\""} -pywinpty = {version = ">=1.1.0", markers = "os_name == \"nt\""} -tornado = ">=6.1.0" - -[package.extras] -docs = ["myst-parser", "pydata-sphinx-theme", "sphinx"] -test = ["pre-commit", "pytest (>=7.0)", "pytest-timeout"] -typing = ["mypy (>=1.6,<2.0)", "traitlets (>=5.11.1)"] - -[[package]] -name = "text-unidecode" -version = "1.3" -description = "The most basic Text::Unidecode port" -optional = true -python-versions = "*" -files = [ - {file = "text-unidecode-1.3.tar.gz", hash = "sha256:bad6603bb14d279193107714b288be206cac565dfa49aa5b105294dd5c4aab93"}, - {file = "text_unidecode-1.3-py2.py3-none-any.whl", hash = "sha256:1311f10e8b895935241623731c2ba64f4c455287888b18189350b67134a822e8"}, -] - -[[package]] -name = "tinycss2" -version = "1.3.0" -description = "A tiny CSS parser" -optional = true -python-versions = ">=3.8" -files = [ - {file = "tinycss2-1.3.0-py3-none-any.whl", hash = "sha256:54a8dbdffb334d536851be0226030e9505965bb2f30f21a4a82c55fb2a80fae7"}, - {file = "tinycss2-1.3.0.tar.gz", hash = "sha256:152f9acabd296a8375fbca5b84c961ff95971fcfc32e79550c8df8e29118c54d"}, -] - -[package.dependencies] -webencodings = ">=0.4" - -[package.extras] -doc = ["sphinx", "sphinx_rtd_theme"] -test = ["pytest", "ruff"] - -[[package]] -name = "tomli" -version = "2.0.1" -description = "A lil' TOML parser" -optional = true -python-versions = ">=3.7" -files = [ - {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, - {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, -] - -[[package]] -name = "tornado" -version = "6.4.1" -description = "Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed." -optional = true -python-versions = ">=3.8" -files = [ - {file = "tornado-6.4.1-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:163b0aafc8e23d8cdc3c9dfb24c5368af84a81e3364745ccb4427669bf84aec8"}, - {file = "tornado-6.4.1-cp38-abi3-macosx_10_9_x86_64.whl", hash = "sha256:6d5ce3437e18a2b66fbadb183c1d3364fb03f2be71299e7d10dbeeb69f4b2a14"}, - {file = "tornado-6.4.1-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e2e20b9113cd7293f164dc46fffb13535266e713cdb87bd2d15ddb336e96cfc4"}, - {file = "tornado-6.4.1-cp38-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8ae50a504a740365267b2a8d1a90c9fbc86b780a39170feca9bcc1787ff80842"}, - {file = "tornado-6.4.1-cp38-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:613bf4ddf5c7a95509218b149b555621497a6cc0d46ac341b30bd9ec19eac7f3"}, - {file = "tornado-6.4.1-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:25486eb223babe3eed4b8aecbac33b37e3dd6d776bc730ca14e1bf93888b979f"}, - {file = "tornado-6.4.1-cp38-abi3-musllinux_1_2_i686.whl", hash = "sha256:454db8a7ecfcf2ff6042dde58404164d969b6f5d58b926da15e6b23817950fc4"}, - {file = "tornado-6.4.1-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:a02a08cc7a9314b006f653ce40483b9b3c12cda222d6a46d4ac63bb6c9057698"}, - {file = "tornado-6.4.1-cp38-abi3-win32.whl", hash = "sha256:d9a566c40b89757c9aa8e6f032bcdb8ca8795d7c1a9762910c722b1635c9de4d"}, - {file = "tornado-6.4.1-cp38-abi3-win_amd64.whl", hash = "sha256:b24b8982ed444378d7f21d563f4180a2de31ced9d8d84443907a0a64da2072e7"}, - {file = "tornado-6.4.1.tar.gz", hash = "sha256:92d3ab53183d8c50f8204a51e6f91d18a15d5ef261e84d452800d4ff6fc504e9"}, -] - -[[package]] -name = "traitlets" -version = "5.14.3" -description = "Traitlets Python configuration system" -optional = true -python-versions = ">=3.8" -files = [ - {file = "traitlets-5.14.3-py3-none-any.whl", hash = "sha256:b74e89e397b1ed28cc831db7aea759ba6640cb3de13090ca145426688ff1ac4f"}, - {file = "traitlets-5.14.3.tar.gz", hash = "sha256:9ed0579d3502c94b4b3732ac120375cda96f923114522847de4b3bb98b96b6b7"}, -] - -[package.extras] -docs = ["myst-parser", "pydata-sphinx-theme", "sphinx"] -test = ["argcomplete (>=3.0.3)", "mypy (>=1.7.0)", "pre-commit", "pytest (>=7.0,<8.2)", "pytest-mock", "pytest-mypy-testing"] - -[[package]] -name = "treon" -version = "0.1.4" -description = "Testing framework for Jupyter Notebooks" -optional = true -python-versions = ">=3" -files = [ - {file = "treon-0.1.4-py3-none-any.whl", hash = "sha256:ab7f54c7f45ee38ee27f9022e065a7fc261f09b36dc595f619393a0548d93a17"}, - {file = "treon-0.1.4.tar.gz", hash = "sha256:6c31a1701036ee8a746adcc9ca59640269c01e887ea13ccc675680d39705d4f4"}, -] - -[package.dependencies] -docopt = "*" -jupyter = "*" -jupyter-client = "*" -nbconvert = "*" - -[[package]] -name = "types-python-dateutil" -version = "2.9.0.20240316" -description = "Typing stubs for python-dateutil" -optional = true -python-versions = ">=3.8" -files = [ - {file = "types-python-dateutil-2.9.0.20240316.tar.gz", hash = "sha256:5d2f2e240b86905e40944dd787db6da9263f0deabef1076ddaed797351ec0202"}, - {file = "types_python_dateutil-2.9.0.20240316-py3-none-any.whl", hash = "sha256:6b8cb66d960771ce5ff974e9dd45e38facb81718cc1e208b10b1baccbfdbee3b"}, -] - -[[package]] -name = "typing-extensions" -version = "4.12.2" -description = "Backported and Experimental Type Hints for Python 3.8+" -optional = true -python-versions = ">=3.8" -files = [ - {file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"}, - {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, -] - -[[package]] -name = "tzdata" -version = "2024.1" -description = "Provider of IANA time zone data" -optional = false -python-versions = ">=2" -files = [ - {file = "tzdata-2024.1-py2.py3-none-any.whl", hash = "sha256:9068bc196136463f5245e51efda838afa15aaeca9903f49050dfa2679db4d252"}, - {file = "tzdata-2024.1.tar.gz", hash = "sha256:2674120f8d891909751c38abcdfd386ac0a5a1127954fbc332af6b5ceae07efd"}, -] - -[[package]] -name = "uri-template" -version = "1.3.0" -description = "RFC 6570 URI Template Processor" -optional = true -python-versions = ">=3.7" -files = [ - {file = "uri-template-1.3.0.tar.gz", hash = "sha256:0e00f8eb65e18c7de20d595a14336e9f337ead580c70934141624b6d1ffdacc7"}, - {file = "uri_template-1.3.0-py3-none-any.whl", hash = "sha256:a44a133ea12d44a0c0f06d7d42a52d71282e77e2f937d8abd5655b8d56fc1363"}, -] - -[package.extras] -dev = ["flake8", "flake8-annotations", "flake8-bandit", "flake8-bugbear", "flake8-commas", "flake8-comprehensions", "flake8-continuation", "flake8-datetimez", "flake8-docstrings", "flake8-import-order", "flake8-literal", "flake8-modern-annotations", "flake8-noqa", "flake8-pyproject", "flake8-requirements", "flake8-typechecking-import", "flake8-use-fstring", "mypy", "pep8-naming", "types-PyYAML"] - -[[package]] -name = "urllib3" -version = "2.2.2" -description = "HTTP library with thread-safe connection pooling, file post, and more." -optional = true -python-versions = ">=3.8" -files = [ - {file = "urllib3-2.2.2-py3-none-any.whl", hash = "sha256:a448b2f64d686155468037e1ace9f2d2199776e17f0a46610480d311f73e3472"}, - {file = "urllib3-2.2.2.tar.gz", hash = "sha256:dd505485549a7a552833da5e6063639d0d177c04f23bc3864e41e5dc5f612168"}, -] - -[package.extras] -brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] -h2 = ["h2 (>=4,<5)"] -socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] -zstd = ["zstandard (>=0.18.0)"] - -[[package]] -name = "wcwidth" -version = "0.2.13" -description = "Measures the displayed width of unicode strings in a terminal" -optional = true -python-versions = "*" -files = [ - {file = "wcwidth-0.2.13-py2.py3-none-any.whl", hash = "sha256:3da69048e4540d84af32131829ff948f1e022c1c6bdb8d6102117aac784f6859"}, - {file = "wcwidth-0.2.13.tar.gz", hash = "sha256:72ea0c06399eb286d978fdedb6923a9eb47e1c486ce63e9b4e64fc18303972b5"}, -] - -[[package]] -name = "webcolors" -version = "24.8.0" -description = "A library for working with the color formats defined by HTML and CSS." -optional = true -python-versions = ">=3.8" -files = [ - {file = "webcolors-24.8.0-py3-none-any.whl", hash = "sha256:fc4c3b59358ada164552084a8ebee637c221e4059267d0f8325b3b560f6c7f0a"}, - {file = "webcolors-24.8.0.tar.gz", hash = "sha256:08b07af286a01bcd30d583a7acadf629583d1f79bfef27dd2c2c5c263817277d"}, -] - -[package.extras] -docs = ["furo", "sphinx", "sphinx-copybutton", "sphinx-inline-tabs", "sphinx-notfound-page", "sphinxext-opengraph"] -tests = ["coverage[toml]"] - -[[package]] -name = "webencodings" -version = "0.5.1" -description = "Character encoding aliases for legacy web content" -optional = true -python-versions = "*" -files = [ - {file = "webencodings-0.5.1-py2.py3-none-any.whl", hash = "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78"}, - {file = "webencodings-0.5.1.tar.gz", hash = "sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923"}, -] - -[[package]] -name = "websocket-client" -version = "1.8.0" -description = "WebSocket client for Python with low level API options" -optional = true -python-versions = ">=3.8" -files = [ - {file = "websocket_client-1.8.0-py3-none-any.whl", hash = "sha256:17b44cc997f5c498e809b22cdf2d9c7a9e71c02c8cc2b6c56e7c2d1239bfa526"}, - {file = "websocket_client-1.8.0.tar.gz", hash = "sha256:3239df9f44da632f96012472805d40a23281a991027ce11d2f45a6f24ac4c3da"}, -] - -[package.extras] -docs = ["Sphinx (>=6.0)", "myst-parser (>=2.0.0)", "sphinx-rtd-theme (>=1.1.0)"] -optional = ["python-socks", "wsaccel"] -test = ["websockets"] - -[[package]] -name = "widgetsnbextension" -version = "4.0.11" -description = "Jupyter interactive widgets for Jupyter Notebook" -optional = true -python-versions = ">=3.7" -files = [ - {file = "widgetsnbextension-4.0.11-py3-none-any.whl", hash = "sha256:55d4d6949d100e0d08b94948a42efc3ed6dfdc0e9468b2c4b128c9a2ce3a7a36"}, - {file = "widgetsnbextension-4.0.11.tar.gz", hash = "sha256:8b22a8f1910bfd188e596fe7fc05dcbd87e810c8a4ba010bdb3da86637398474"}, -] - -[[package]] -name = "wisdem" -version = "3.16.4" -description = "Wind-Plant Integrated System Design & Engineering Model" -optional = true -python-versions = ">=3.9" -files = [ - {file = "wisdem-3.16.4-cp310-cp310-macosx_12_0_x86_64.whl", hash = "sha256:443d5fbd8cd7a69e50c25fecac832297e427d7975af14c5ec32caa59294b085a"}, - {file = "wisdem-3.16.4-cp310-cp310-macosx_13_0_x86_64.whl", hash = "sha256:ad0b83530964e614f430ff83ee38abe5997bca42a1279b6301d6939431042988"}, - {file = "wisdem-3.16.4-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:7c26f580e8595d5ad9a00b418feeee529c501c32634237a793f8543c8fa45140"}, - {file = "wisdem-3.16.4-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4918b98fdb74369270b53857fcf5097b41fabb43c5ea72f94dcc6a788568b190"}, - {file = "wisdem-3.16.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18784f54b14754d3b755a7e0fa5862301af8fdbb7d59e05de90ee1bbf9d9128b"}, - {file = "wisdem-3.16.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:612e1f87082fc9ba5006037f4e8c17242320873c85fc1277984b862db40a7ad0"}, - {file = "wisdem-3.16.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:e0c5b717e536b581415e7be1e01924dc2333b329d88886d38f48aadab47289ed"}, - {file = "wisdem-3.16.4-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0ae9da2ae9036791857cad3e201d526ab82bf8d8ca6e902466c8ed7ad434cc84"}, - {file = "wisdem-3.16.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:91bd15bf1298b2422a0bd98ebff8336f464726c4ab4fd4b590976ea2b2f9f6bf"}, - {file = "wisdem-3.16.4-cp310-cp310-win_amd64.whl", hash = "sha256:376b18c13db629dea4efaaaf15a973252372f1d14895a6b7312e4ada479611b1"}, - {file = "wisdem-3.16.4-cp311-cp311-macosx_12_0_x86_64.whl", hash = "sha256:2fceb88c9bf3708e5e5529711f87d541dc6479720936a0d632acccc77e94dbd1"}, - {file = "wisdem-3.16.4-cp311-cp311-macosx_13_0_x86_64.whl", hash = "sha256:d3b5e247b315c87a2773c60fb8c5feb115b51cc0713c1fd76771627463f879c0"}, - {file = "wisdem-3.16.4-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:ad4489ecc74c1f466b74d803ad7df2b33ca98b2bad4a6b4998067eea3c46511d"}, - {file = "wisdem-3.16.4-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3f6114be0bc7effb86c3ab7c993979d2081f31483d41c3dea4fd78175dd31836"}, - {file = "wisdem-3.16.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1817b5b0da867d6f488f247fd23d0376500e375b4aeae7faee6d9a40ba67caf1"}, - {file = "wisdem-3.16.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:91a86da67cf15d8fd9cb09bb6e7bfbdb9ed352ff307da7560c280440b73db008"}, - {file = "wisdem-3.16.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:b7ddc4210ef922a8146d9fa5c1aa41630b57783dc43d0a619738313c9aa17f2f"}, - {file = "wisdem-3.16.4-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:d217d222d30400ed3ec211a0f5db111566f669266faff888f35c1e3f92e456d5"}, - {file = "wisdem-3.16.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:411a41ed29b66046fb6fc852d592543ffa31adbb78cbda189272ee097b3ef282"}, - {file = "wisdem-3.16.4-cp311-cp311-win_amd64.whl", hash = "sha256:8dd09e133401ae48ac6c8182ff33c59312b87f5a3a060bde87e4a6626b0591a5"}, - {file = "wisdem-3.16.4-cp312-cp312-macosx_12_0_x86_64.whl", hash = "sha256:4d216aa76c1fb3af5796be2e13ccda7e065e12e5534278db529ad768a23b0542"}, - {file = "wisdem-3.16.4-cp312-cp312-macosx_13_0_x86_64.whl", hash = "sha256:8ac09b7105db5e74237f3d061a704648e01c5c7a2a7dab1438781d007bd7f5ce"}, - {file = "wisdem-3.16.4-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:6dcc2a9785caed8ac3ee4164bdf9073b81a2e610d325ebf34b30ce0c3ce91f14"}, - {file = "wisdem-3.16.4-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6c58820e9fc43f74f91b1f1923d8d021f713676bdd80483d321a6a16596d5252"}, - {file = "wisdem-3.16.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:71f742c28b88b49c2f15902ee348ddfdc94eb790da0092ca9c2ebf79d82e6327"}, - {file = "wisdem-3.16.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45a253d6770588949ad0c280c306880acdd5180786859bcc3b0e57055f98cf71"}, - {file = "wisdem-3.16.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:b7754915d905e3f21af618bf13618a33d02e3d45ad403d3683cf69f83ebe1f74"}, - {file = "wisdem-3.16.4-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:507fe9ecfa4b510319db67c6c37af926fbd5e5831034da08f694060defdddb79"}, - {file = "wisdem-3.16.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a037a4b36cfb3cac4b93098c6471f3a589cecde4a1d2a29f3b98c285e577bc6d"}, - {file = "wisdem-3.16.4-cp312-cp312-win_amd64.whl", hash = "sha256:4dc43e50952048f2c6ad3b9e80ecfd84c3370a888f0e2c2399059c27cf020a7d"}, - {file = "wisdem-3.16.4-cp39-cp39-macosx_12_0_x86_64.whl", hash = "sha256:60f5480f76f7dd49dc71e68e28c5b6a6681575b15c3bae4ebc3edf9b0089f8fc"}, - {file = "wisdem-3.16.4-cp39-cp39-macosx_13_0_x86_64.whl", hash = "sha256:aac7ffaf4a9a61496b8904319824e90118bdf0b8de1a1bdad029c46854aaffa7"}, - {file = "wisdem-3.16.4-cp39-cp39-macosx_14_0_arm64.whl", hash = "sha256:1a1d8a8fe0cf8440263189f51b557bbb8def021d1e9ad80c9e93d26c7a1915ed"}, - {file = "wisdem-3.16.4-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d45d13252564ce5a6b0abf0fb78586c17ab89754e4b2310db4b111d6331a389b"}, - {file = "wisdem-3.16.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:60adbdfb6b6bc4bf57f2918d527806729620ef2e82bacb60aa060aec6c519a9d"}, - {file = "wisdem-3.16.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcbf98ef6a82754f0f522027e7b3822965b87ea4ef8ce1d43c92fdb00ed969ee"}, - {file = "wisdem-3.16.4-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:a86156c358ca8c7e06d0bae67c84ae9640d29c2bd37a2d17658900813454ee20"}, - {file = "wisdem-3.16.4-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:455257441569ad1a5e0a95fa089de6bbb87e25c902ded72850d96258ef99e231"}, - {file = "wisdem-3.16.4-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:804264d51f53f8190aaf80b5477b1d0a89e2685fcbda94938d11aac0a582446d"}, - {file = "wisdem-3.16.4-cp39-cp39-win_amd64.whl", hash = "sha256:2b771ddeefa397fdb9814e9fc839798b855d3696c8ee21ce3f3e7ac805147c3e"}, - {file = "wisdem-3.16.4.tar.gz", hash = "sha256:37316bdf1b283225f88faa7e646b211c3c6e16fc071faf3b83fcfcdeccaff879"}, -] - -[package.dependencies] -dearpygui = "*" -jsonschema = "*" -marmot-agents = ">=0.2.5" -moorpy = "*" -numpy = ">=1.26" -openmdao = ">=3.31" -openpyxl = "*" -pandas = "*" -pydoe3 = "*" -python-benedict = "*" -pyyaml = "*" -"ruamel.yaml" = "*" -scipy = "*" -simpy = "*" -sortedcontainers = "*" -statsmodels = "*" - -[package.extras] -dev = ["meson", "ninja", "swig"] -docs = ["sphinx", "sphinx-jsonschema", "sphinx-rtd-theme (>=1.3)", "sphinxcontrib-bibtex"] -opt = ["nlopt", "pyoptsparse"] -test = ["coveralls", "pytest", "pytest-cov"] - -[[package]] -name = "xlrd" -version = "2.0.1" -description = "Library for developers to extract data from Microsoft Excel (tm) .xls spreadsheet files" -optional = true -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" -files = [ - {file = "xlrd-2.0.1-py2.py3-none-any.whl", hash = "sha256:6a33ee89877bd9abc1158129f6e94be74e2679636b8a205b43b85206c3f0bbdd"}, - {file = "xlrd-2.0.1.tar.gz", hash = "sha256:f72f148f54442c6b056bf931dbc34f986fd0c3b0b6b5a58d013c9aef274d0c88"}, -] - -[package.extras] -build = ["twine", "wheel"] -docs = ["sphinx"] -test = ["pytest", "pytest-cov"] - -[[package]] -name = "zipp" -version = "3.20.0" -description = "Backport of pathlib-compatible object wrapper for zip files" -optional = true -python-versions = ">=3.8" -files = [ - {file = "zipp-3.20.0-py3-none-any.whl", hash = "sha256:58da6168be89f0be59beb194da1250516fdaa062ccebd30127ac65d30045e10d"}, - {file = "zipp-3.20.0.tar.gz", hash = "sha256:0145e43d89664cfe1a2e533adc75adafed82fe2da404b4bbb6b026c0157bdb31"}, -] - -[package.extras] -doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] -test = ["big-O", "importlib-resources", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more-itertools", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-ignore-flaky", "pytest-mypy", "pytest-ruff (>=0.2.1)"] - -[extras] -all = ["rosco", "xlrd"] -excel = ["xlrd"] -rosco = ["rosco"] - -[metadata] -lock-version = "2.0" -python-versions = "^3.9" -content-hash = "40bf060d7a2035b1e08f89416ed8a5e561e2f925a03e93f2776ccaf9f92c6fdd" diff --git a/openfast_io/pyproject.toml b/openfast_io/pyproject.toml index 23c7e8fc9..540edae12 100644 --- a/openfast_io/pyproject.toml +++ b/openfast_io/pyproject.toml @@ -1,23 +1,27 @@ -[tool.poetry] +[build-system] +requires = ["hatchling", "hatch-vcs"] +build-backend = "hatchling.build" + +[project] name = "openfast_io" -version = "4.0.0" # We can make this dynamic to use github tags using dynamic = ["version"] +dynamic = ["version"] description = "Readers and writers for OpenFAST files." -license = "Apache-2.0" +license = {file = "../LICENSE"} authors = [ - "NREL WISDEM Team ", - "Daniel Zalkind ", - "Garrett Barter ", - "Pietro Bortolotti ", - "Mayank Chetan ", - "John Jasa", + { name = "NREL WISDEM Team", email = "systems.engineering@nrel.gov" }, + { name = "Daniel Zalkind", email = "daniel.zalkind@nrel.gov" }, + { name = "Garrett Barter", email = "garrett.barter@nrel.gov" }, + { name = "Pietro Bortolotti", email = "pietro.bortolotti@nrel.gov" }, + { name = "Mayank Chetan", email = "mayank.chetan@nrel.gov" }, + { name = "John Jasa" }, ] maintainers = [ - "Mayank Chetan ", - "Andy Platt ", - "Derek Slaughter ", -] + {name = "Mayank Chetan", email = "mayank.chetan@nrel.gov" }, + {name = "Andy Platt", email = "andy.platt@nrel.gov" }, + {name = "Derek Slaughter", email = "derek.slaughter@nrel.gov" }, +] readme = "README.md" -packages = [{include = "openfast_io"}] +requires-python = ">3.10" classifiers = [ # Optional # How mature is this project? Common values are @@ -43,28 +47,26 @@ classifiers = [ # Optional "Programming Language :: Python :: 3 :: Only", ] -homepage = "https://github.com/OpenFAST/openfast" -documentation = "https://openfast.readthedocs.io/en/main/" -repository = "https://github.com/OpenFAST/openfast" - -[tool.poetry.urls] +[project.urls] +"homepage" = "https://github.com/OpenFAST/openfast" +"documentation" = "https://openfast.readthedocs.io/en/main/" +"repository" = "https://github.com/OpenFAST/openfast" "Bug Tracker" = "https://github.com/OpenFAST/openfast/issues" -[tool.poetry.dependencies] -python = "^3.9" -numpy = "^1" -pandas = "^2" -xlrd = {version = "^2", optional = true} -ruamel_yaml = "^0.18" -rosco = {version = "^2.9.2", optional = true} +dependencies = [ + "numpy^1.0", + "pandas^2.0", + "ruamel_yaml^0.18", + ] +[project.optional-dependencies] -[tool.poetry.extras] -rosco = ["rosco"] -excel = ["xlrd"] -all = ["rosco", "xlrd"] +rosco = ["rosco^2.9.2"] +xlrd = ["xlrd^2"] +all = ["rosco^2.9.2", "xlrd^2"] +[tool.hatch.version] +source = "vcs" -[build-system] -requires = ["poetry-core"] -build-backend = "poetry.core.masonry.api" +[tool.hatch.build.hooks.vcs] +version-file = "openfast_io/_version.py" \ No newline at end of file From bf28ac6c86971d6690a9f532e50f575c0671f236 Mon Sep 17 00:00:00 2001 From: Mayank Chetan Date: Mon, 19 Aug 2024 18:19:02 +0000 Subject: [PATCH 021/161] cd since not in main folder --- .github/workflows/deploy.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 3084f07ae..15b65834f 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -55,6 +55,9 @@ jobs: - name: Install Hatch uses: pypa/hatch@install + - name: cd to openfast_io + run: cd openfast_io + - name: Build package run: hatch build From a6edae75cefc427235655ba1a51ca8b7d313ae1b Mon Sep 17 00:00:00 2001 From: Mayank Chetan Date: Mon, 19 Aug 2024 18:27:41 +0000 Subject: [PATCH 022/161] change workdie --- .github/workflows/deploy.yml | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 15b65834f..f32fb51be 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -4,12 +4,14 @@ # repository. The build cache is stored in GitHub actions. name: deploy -on: - workflow_dispatch: +# on: + # workflow_dispatch: - release: - types: - - released + # release: + # types: + # - released +on: + push: jobs: # publish-to-pypi: @@ -43,6 +45,7 @@ jobs: # jobs: publish-to-test-pypi: runs-on: ubuntu-latest + steps: - uses: actions/checkout@v3 @@ -55,17 +58,17 @@ jobs: - name: Install Hatch uses: pypa/hatch@install - - name: cd to openfast_io - run: cd openfast_io - name: Build package run: hatch build + working-directory: openfast_io - name: Publish to PyPI env: HATCH_INDEX_USER: __token__ HATCH_INDEX_AUTH: ${{ secrets.PYPI_TOKEN }} run: hatch publish -r test + working-directory: openfast_io docker-build-and-push: runs-on: ubuntu-latest From 2f49937d112c53b0957d7dbb231b0c8ca2981bf0 Mon Sep 17 00:00:00 2001 From: Mayank Chetan Date: Mon, 19 Aug 2024 18:42:33 +0000 Subject: [PATCH 023/161] change version --- openfast_io/pyproject.toml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/openfast_io/pyproject.toml b/openfast_io/pyproject.toml index 540edae12..971f0b265 100644 --- a/openfast_io/pyproject.toml +++ b/openfast_io/pyproject.toml @@ -4,7 +4,8 @@ build-backend = "hatchling.build" [project] name = "openfast_io" -dynamic = ["version"] +# dynamic = ["version"] +version = "4.0.0.a1" description = "Readers and writers for OpenFAST files." license = {file = "../LICENSE"} authors = [ From ab956613b6057ce88db4a1b4d982431389cdc556 Mon Sep 17 00:00:00 2001 From: Mayank Chetan Date: Mon, 19 Aug 2024 18:44:53 +0000 Subject: [PATCH 024/161] change version --- openfast_io/pyproject.toml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/openfast_io/pyproject.toml b/openfast_io/pyproject.toml index 971f0b265..5aa62d7e5 100644 --- a/openfast_io/pyproject.toml +++ b/openfast_io/pyproject.toml @@ -55,16 +55,16 @@ classifiers = [ # Optional "Bug Tracker" = "https://github.com/OpenFAST/openfast/issues" dependencies = [ - "numpy^1.0", - "pandas^2.0", - "ruamel_yaml^0.18", + "numpy>1.0", + "pandas>2.0", + "ruamel_yaml>0.18", ] [project.optional-dependencies] -rosco = ["rosco^2.9.2"] -xlrd = ["xlrd^2"] -all = ["rosco^2.9.2", "xlrd^2"] +rosco = ["rosco>2.9.2"] +xlrd = ["xlrd>2"] +all = ["rosco>2.9.2", "xlrd>2"] [tool.hatch.version] source = "vcs" From d628e475fa4c1d20a32e09621570b5ac58f7bc00 Mon Sep 17 00:00:00 2001 From: Mayank Chetan Date: Mon, 19 Aug 2024 18:47:13 +0000 Subject: [PATCH 025/161] change version --- openfast_io/openfast_io/_version.py | 16 ++++++++++++++++ openfast_io/pyproject.toml | 14 ++++++++------ 2 files changed, 24 insertions(+), 6 deletions(-) create mode 100644 openfast_io/openfast_io/_version.py diff --git a/openfast_io/openfast_io/_version.py b/openfast_io/openfast_io/_version.py new file mode 100644 index 000000000..2d1bd5f0f --- /dev/null +++ b/openfast_io/openfast_io/_version.py @@ -0,0 +1,16 @@ +# file generated by setuptools_scm +# don't change, don't track in version control +TYPE_CHECKING = False +if TYPE_CHECKING: + from typing import Tuple, Union + VERSION_TUPLE = Tuple[Union[int, str], ...] +else: + VERSION_TUPLE = object + +version: str +__version__: str +__version_tuple__: VERSION_TUPLE +version_tuple: VERSION_TUPLE + +__version__ = version = '4.0.0a1' +__version_tuple__ = version_tuple = (4, 0, 0) diff --git a/openfast_io/pyproject.toml b/openfast_io/pyproject.toml index 5aa62d7e5..3aea7c931 100644 --- a/openfast_io/pyproject.toml +++ b/openfast_io/pyproject.toml @@ -48,17 +48,19 @@ classifiers = [ # Optional "Programming Language :: Python :: 3 :: Only", ] -[project.urls] -"homepage" = "https://github.com/OpenFAST/openfast" -"documentation" = "https://openfast.readthedocs.io/en/main/" -"repository" = "https://github.com/OpenFAST/openfast" -"Bug Tracker" = "https://github.com/OpenFAST/openfast/issues" - dependencies = [ "numpy>1.0", "pandas>2.0", "ruamel_yaml>0.18", ] + +[project.urls] +homepage = "https://github.com/OpenFAST/openfast" +documentation = "https://openfast.readthedocs.io/en/main/" +repository = "https://github.com/OpenFAST/openfast" +Issues = "https://github.com/OpenFAST/openfast/issues" + + [project.optional-dependencies] From 839e4b59c94af57a1b06c67877946d90d49975b0 Mon Sep 17 00:00:00 2001 From: Mayank Chetan Date: Fri, 23 Aug 2024 20:15:55 +0000 Subject: [PATCH 026/161] prepping to add pytest to cmake --- openfast_io/openfast_io/tests/conftest.py | 24 ++++ .../openfast_io/tests/test_of_io_pytest.py | 121 +++++++++++------- 2 files changed, 96 insertions(+), 49 deletions(-) create mode 100644 openfast_io/openfast_io/tests/conftest.py diff --git a/openfast_io/openfast_io/tests/conftest.py b/openfast_io/openfast_io/tests/conftest.py new file mode 100644 index 000000000..3d3fcc03b --- /dev/null +++ b/openfast_io/openfast_io/tests/conftest.py @@ -0,0 +1,24 @@ +import pytest +import os.path as osp +import platform + +# looking up OS for the correct executable extension +mactype = platform.system().lower() +if mactype in ["linux", "linux2", "darwin"]: + exeExt = "" +elif mactype in ["win32", "windows", "cygwin"]: #NOTE: platform.system()='Windows', sys.platform='win32' + libext = '.exe' +else: + raise ValueError('Unknown platform type: '+mactype) + +REPOSITORY_ROOT = osp.dirname(osp.dirname(osp.dirname(osp.dirname(__file__)))) +BUILD_DIR = osp.join(REPOSITORY_ROOT, "build_ofio", "testSuite") + +# Path to the OpenFAST executable +OF_PATH = osp.join(REPOSITORY_ROOT,"build/glue-codes/openfast",f"openfast{exeExt}") + +def pytest_addoption(parser): + parser.addoption("--executable", action="store", default=OF_PATH, help="Path to the OpenFAST executable") + parser.addoption("--source_dir", action="store", default=REPOSITORY_ROOT, help="Path to the openfast repository") + parser.addoption("--build_dir", action="store", default=BUILD_DIR, help="Path to the test data directory") + diff --git a/openfast_io/openfast_io/tests/test_of_io_pytest.py b/openfast_io/openfast_io/tests/test_of_io_pytest.py index da2e91fa4..d7bd4e9dd 100644 --- a/openfast_io/openfast_io/tests/test_of_io_pytest.py +++ b/openfast_io/openfast_io/tests/test_of_io_pytest.py @@ -1,7 +1,7 @@ import pytest import os.path as osp import subprocess, sys -import platform + from openfast_io.FAST_reader import InputReader_OpenFAST from openfast_io.FAST_writer import InputWriter_OpenFAST @@ -10,61 +10,71 @@ from openfast_io.FileTools import check_rtest_cloned from pathlib import Path -REPOSITORY_ROOT = osp.dirname(osp.dirname(osp.dirname(osp.dirname(__file__)))) -RTESTS_DIR = osp.join(REPOSITORY_ROOT, "reg_tests","r-test") -TEST_DATA_DIR = osp.join(RTESTS_DIR, "glue-codes", "openfast") +from conftest import REPOSITORY_ROOT, BUILD_DIR, OF_PATH -RUN_DIR = osp.join(REPOSITORY_ROOT, "build_ofio", "testSuite") -Path(RUN_DIR).mkdir(parents=True, exist_ok=True) +Path(BUILD_DIR).mkdir(parents=True, exist_ok=True) # Exercising the various OpenFAST modules FOLDERS_TO_RUN = [ "5MW_Land_DLL_WTurb" , # "openfast;elastodyn;aerodyn15;servodyn") - "5MW_OC3Mnpl_DLL_WTurb_WavesIrr" , # "openfast;elastodyn;aerodyn15;servodyn;hydrodyn;subdyn;offshore") - "5MW_OC3Mnpl_DLL_WTurb_WavesIrr_Restart", # "openfast;elastodyn;aerodyn15;servodyn;hydrodyn;subdyn;offshore;restart") - "5MW_ITIBarge_DLL_WTurb_WavesIrr" , # "openfast;elastodyn;aerodyn15;servodyn;hydrodyn;map;offshore") - "5MW_OC4Semi_WSt_WavesWN" , # "openfast;elastodyn;aerodyn15;servodyn;hydrodyn;moordyn;offshore") - "5MW_Land_BD_DLL_WTurb" , # "openfast;beamdyn;aerodyn15;servodyn") - "5MW_OC4Jckt_ExtPtfm" , # "openfast;elastodyn;extptfm") - "HelicalWake_OLAF" , # "openfast;aerodyn15;olaf") - "StC_test_OC4Semi" , # "openfast;servodyn;hydrodyn;moordyn;offshore;stc") - "MHK_RM1_Fixed" , # "openfast;elastodyn;aerodyn15;mhk") - "MHK_RM1_Floating" , # "openfast;elastodyn;aerodyn15;hydrodyn;moordyn;mhk") - "Tailfin_FreeYaw1DOF_PolarBased" , # "openfast;elastodyn;aerodyn15") + # "5MW_OC3Mnpl_DLL_WTurb_WavesIrr" , # "openfast;elastodyn;aerodyn15;servodyn;hydrodyn;subdyn;offshore") + # "5MW_OC3Mnpl_DLL_WTurb_WavesIrr_Restart", # "openfast;elastodyn;aerodyn15;servodyn;hydrodyn;subdyn;offshore;restart") + # "5MW_ITIBarge_DLL_WTurb_WavesIrr" , # "openfast;elastodyn;aerodyn15;servodyn;hydrodyn;map;offshore") + # "5MW_OC4Semi_WSt_WavesWN" , # "openfast;elastodyn;aerodyn15;servodyn;hydrodyn;moordyn;offshore") + # "5MW_Land_BD_DLL_WTurb" , # "openfast;beamdyn;aerodyn15;servodyn") + # "5MW_OC4Jckt_ExtPtfm" , # "openfast;elastodyn;extptfm") + # "HelicalWake_OLAF" , # "openfast;aerodyn15;olaf") + # "StC_test_OC4Semi" , # "openfast;servodyn;hydrodyn;moordyn;offshore;stc") + # "MHK_RM1_Fixed" , # "openfast;elastodyn;aerodyn15;mhk") + # "MHK_RM1_Floating" , # "openfast;elastodyn;aerodyn15;hydrodyn;moordyn;mhk") + # "Tailfin_FreeYaw1DOF_PolarBased" , # "openfast;elastodyn;aerodyn15") ] -# looking up OS for the correct executable extension -mactype = platform.system().lower() -if mactype in ["linux", "linux2", "darwin"]: - exeExt = "" -elif mactype in ["win32", "windows", "cygwin"]: #NOTE: platform.system()='Windows', sys.platform='win32' - libext = '.exe' -else: - raise ValueError('Unknown platform type: '+mactype) -# Path to the OpenFAST executable -of_path = osp.join(REPOSITORY_ROOT,"build/glue-codes/openfast",f"openfast{exeExt}") +''' +parser.add_argument("caseName", metavar="Case-Name", type=str, nargs=1, help="The name of the test case.") +parser.add_argument("executable", metavar="NotUsed", type=str, nargs=1, help="Not used in this script, but kept for API compatibility.") +parser.add_argument("sourceDirectory", metavar="path/to/openfast_repo", type=str, nargs=1, help="The path to the OpenFAST repository.") +parser.add_argument("buildDirectory", metavar="path/to/openfast_repo/build", type=str, nargs=1, help="The path to the OpenFAST repository build directory.") +''' + + +# def pytest_addoption(parser): +# parser.addoption("--executable", action="store", default=OF_PATH, help="Path to the OpenFAST executable") +# parser.addoption("--source_dir", action="store", default=REPOSITORY_ROOT, help="Path to the r-test directory") +# parser.addoption("--build_dir", action="store", default=BUILD_DIR, help="Path to the test data directory") + +def getPaths(OF_PATH = OF_PATH, REPOSITORY_ROOT = REPOSITORY_ROOT, BUILD_DIR = BUILD_DIR): -def read_action(folder): + return { + "executable": OF_PATH, + "source_dir": REPOSITORY_ROOT, + "build_dir": BUILD_DIR, + "rtest_dir": osp.join(REPOSITORY_ROOT, "reg_tests", "r-test"), + "test_data_dir": osp.join(REPOSITORY_ROOT, "reg_tests", "r-test", "glue-codes", "openfast") + } + + +def read_action(folder, path_dict = getPaths()): print(f"Reading from {folder}") # Read input deck fast_reader = InputReader_OpenFAST() fast_reader.FAST_InputFile = f'{folder}.fst' # FAST input file (ext=.fst) - fast_reader.FAST_directory = osp.join(TEST_DATA_DIR, folder) # Path to fst directory files + fast_reader.FAST_directory = osp.join(path_dict['test_data_dir'], folder) # Path to fst directory files fast_reader.execute() return fast_reader.fst_vt -def write_action(folder, fst_vt): +def write_action(folder, fst_vt, path_dict = getPaths()): print(f"Writing to {folder}, with TMax = 2.0") fast_writer = InputWriter_OpenFAST() - fast_writer.FAST_runDirectory = osp.join(RUN_DIR,folder) + fast_writer.FAST_runDirectory = osp.join(path_dict['build_dir'],folder) Path(fast_writer.FAST_runDirectory).mkdir(parents=True, exist_ok=True) fast_writer.FAST_namingOut = folder @@ -75,36 +85,43 @@ def write_action(folder, fst_vt): fast_writer.update(fst_update=fst_vt) fast_writer.execute() -def run_action(folder): +def run_action(folder, path_dict = getPaths()): # Placeholder for the actual run action print(f"Running simulation for {folder}") - subprocess.run([of_path, str(osp.join(RUN_DIR, folder, f"{folder}.fst"))], check=True) + subprocess.run([OF_PATH, str(osp.join(path_dict['build_dir'], folder, f"{folder}.fst"))], check=True) -def check_ascii_out(folder): +def check_ascii_out(folder, path_dict = getPaths()): # Placeholder for the actual check action print(f"Checking ASCII output for {folder}") - asciiOutput = osp.join(RUN_DIR, folder, f"{folder}.out") + asciiOutput = osp.join(path_dict['build_dir'], folder, f"{folder}.out") fast_outout = FASTOutputFile(filename=asciiOutput) -def check_binary_out(folder): +def check_binary_out(folder, path_dict = getPaths()): # Placeholder for the actual check action print(f"Checking binary output for {folder}") - binaryOutput = osp.join(RUN_DIR, folder, f"{folder}.outb") + binaryOutput = osp.join(path_dict['build_dir'], folder, f"{folder}.outb") fast_outout = FASTOutputFile(filename=binaryOutput) # Begining of the test -def test_rtest_cloned(): - if check_rtest_cloned(TEST_DATA_DIR): +def test_rtest_cloned(request): + + REPOSITORY_ROOT = osp.join(request.config.getoption("--source_dir")) + path_dict = getPaths(REPOSITORY_ROOT=REPOSITORY_ROOT) + + if check_rtest_cloned(path_dict['test_data_dir']): assert True, "R-tests cloned properly" else:# stop the test if the r-tests are not cloned properly print("R-tests not cloned properly") sys.exit(1) -def test_openfast_executable_exists(): - if osp.exists(of_path): - assert True, f"OpenFAST executable found at {of_path}" +def test_openfast_executable_exists(request): + + path_dict = getPaths(OF_PATH=osp.join(request.config.getoption("--executable"))) + + if osp.exists(path_dict['executable']): + assert True, f"OpenFAST executable found at {path_dict['executable']}" else: # stop the test if the OpenFAST executable is not found - print(f"OpenFAST executable not found at {of_path}. Please build OpenFAST and try again.") + print(f"OpenFAST executable not found at {path_dict['executable']}. Please build OpenFAST and try again.") sys.exit(1) # # Define a list of action functions for parameterization @@ -118,23 +135,29 @@ def test_openfast_executable_exists(): # Parameterize the test function to run for each folder and action @pytest.mark.parametrize("folder", FOLDERS_TO_RUN) # @pytest.mark.parametrize("action_name, action_func", actions) -def test_openfast_io_with_detailed_reporting(folder): +def test_openfast_io_with_detailed_reporting(folder, request): + + path_dict = getPaths(OF_PATH=osp.join(request.config.getoption("--executable")), + REPOSITORY_ROOT=osp.join(request.config.getoption("--source_dir")), + BUILD_DIR=osp.join(request.config.getoption("--build_dir"))) + + try: # action_func(folder) action_name = "read" - fst_vt = read_action(folder) + fst_vt = read_action(folder, path_dict = path_dict) action_name = "write" - write_action(folder, fst_vt) + write_action(folder, fst_vt, path_dict = path_dict) action_name = "run" - run_action(folder) + run_action(folder, path_dict = path_dict) action_name = "check ASCII" - check_ascii_out(folder) + check_ascii_out(folder, path_dict = path_dict) action_name = "check binary" - check_binary_out(folder) + check_binary_out(folder, path_dict = path_dict) except Exception as e: pytest.fail(f"Action '{action_name}' for folder '{folder}' failed with exception: {e}") From df70883786ed3d5edab44be1e82c6296e7cc5af3 Mon Sep 17 00:00:00 2001 From: Mayank Chetan Date: Fri, 23 Aug 2024 20:16:09 +0000 Subject: [PATCH 027/161] prepping to add pytest to cmake --- .../openfast_io/tests/test_of_io_pytest.py | 24 ------------------- 1 file changed, 24 deletions(-) diff --git a/openfast_io/openfast_io/tests/test_of_io_pytest.py b/openfast_io/openfast_io/tests/test_of_io_pytest.py index d7bd4e9dd..f8fc5200b 100644 --- a/openfast_io/openfast_io/tests/test_of_io_pytest.py +++ b/openfast_io/openfast_io/tests/test_of_io_pytest.py @@ -33,19 +33,6 @@ -''' -parser.add_argument("caseName", metavar="Case-Name", type=str, nargs=1, help="The name of the test case.") -parser.add_argument("executable", metavar="NotUsed", type=str, nargs=1, help="Not used in this script, but kept for API compatibility.") -parser.add_argument("sourceDirectory", metavar="path/to/openfast_repo", type=str, nargs=1, help="The path to the OpenFAST repository.") -parser.add_argument("buildDirectory", metavar="path/to/openfast_repo/build", type=str, nargs=1, help="The path to the OpenFAST repository build directory.") -''' - - -# def pytest_addoption(parser): -# parser.addoption("--executable", action="store", default=OF_PATH, help="Path to the OpenFAST executable") -# parser.addoption("--source_dir", action="store", default=REPOSITORY_ROOT, help="Path to the r-test directory") -# parser.addoption("--build_dir", action="store", default=BUILD_DIR, help="Path to the test data directory") - def getPaths(OF_PATH = OF_PATH, REPOSITORY_ROOT = REPOSITORY_ROOT, BUILD_DIR = BUILD_DIR): return { @@ -56,7 +43,6 @@ def getPaths(OF_PATH = OF_PATH, REPOSITORY_ROOT = REPOSITORY_ROOT, BUILD_DIR = B "test_data_dir": osp.join(REPOSITORY_ROOT, "reg_tests", "r-test", "glue-codes", "openfast") } - def read_action(folder, path_dict = getPaths()): print(f"Reading from {folder}") @@ -68,8 +54,6 @@ def read_action(folder, path_dict = getPaths()): return fast_reader.fst_vt - - def write_action(folder, fst_vt, path_dict = getPaths()): print(f"Writing to {folder}, with TMax = 2.0") @@ -124,14 +108,6 @@ def test_openfast_executable_exists(request): print(f"OpenFAST executable not found at {path_dict['executable']}. Please build OpenFAST and try again.") sys.exit(1) -# # Define a list of action functions for parameterization -# actions = [ -# ("read", read_action), -# ("write", write_action), -# ("run", run_action), -# ("check", check_action), -# ] - # Parameterize the test function to run for each folder and action @pytest.mark.parametrize("folder", FOLDERS_TO_RUN) # @pytest.mark.parametrize("action_name, action_func", actions) From 1b9ed0bfe4d4dccea989f70877a4e96e6e3eff08 Mon Sep 17 00:00:00 2001 From: Mayank Chetan Date: Fri, 23 Aug 2024 22:22:52 +0000 Subject: [PATCH 028/161] working pytest with cmakegit status! :D --- .gitignore | 1 - openfast_io/openfast_io/FAST_writer.py | 26 +- .../openfast_io/tests/test_of_io_pytest.py | 24 +- reg_tests/CMakeLists.txt | 2 +- reg_tests/CTestList.cmake | 417 +++++++++--------- requirements.txt | 3 +- 6 files changed, 244 insertions(+), 229 deletions(-) diff --git a/.gitignore b/.gitignore index e6e0553e1..7377fec94 100644 --- a/.gitignore +++ b/.gitignore @@ -60,5 +60,4 @@ varcache *.slxc # Python cache files -__pycache__/ openfast_io/dist/ \ No newline at end of file diff --git a/openfast_io/openfast_io/FAST_writer.py b/openfast_io/openfast_io/FAST_writer.py index 90ae268e4..8144b74ab 100644 --- a/openfast_io/openfast_io/FAST_writer.py +++ b/openfast_io/openfast_io/FAST_writer.py @@ -786,8 +786,8 @@ def write_AeroDyn15(self): self.write_AeroDyn15Coord() if self.fst_vt['AeroDyn15']['Wake_Mod'] == 3: - if self.fst_vt['AeroDyn15']['UAMod'] == 2: - raise Exception('OLAF is called with unsteady airfoil aerodynamics, but OLAF currently only supports UAMod == 1') #TODO: need to check if this holds true now + if self.fst_vt['AeroDyn15']['UA_Mod'] == 2: + raise Exception('OLAF is called with unsteady airfoil aerodynamics, but OLAF currently only supports UA_Mod == 1') #TODO: need to check if this holds true now self.write_OLAF() # Generate AeroDyn v15.03 input file @@ -1013,7 +1013,7 @@ def write_AeroDyn15Polar(self): f.write('{:<22f} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['af_data'][afi][tab]['alpha0'], 'alpha0', '! 0-lift angle of attack, depends on airfoil.\n')) f.write('{:<22f} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['af_data'][afi][tab]['alpha1'], 'alpha1', '! Angle of attack at f=0.7, (approximately the stall angle) for AOA>alpha0. (deg)\n')) f.write('{:<22f} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['af_data'][afi][tab]['alpha2'], 'alpha2', '! Angle of attack at f=0.7, (approximately the stall angle) for AOA1]\n')) - f.write('{:<22f} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['af_data'][afi][tab]['S2'], 'S2', '! Constant in the f curve best-fit for AOA> alpha1; by definition it depends on the airfoil. [ignored if UAMod<>1]\n')) - f.write('{:<22f} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['af_data'][afi][tab]['S3'], 'S3', '! Constant in the f curve best-fit for alpha2<=AOA< alpha0; by definition it depends on the airfoil. [ignored if UAMod<>1]\n')) - f.write('{:<22f} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['af_data'][afi][tab]['S4'], 'S4', '! Constant in the f curve best-fit for AOA< alpha2; by definition it depends on the airfoil. [ignored if UAMod<>1]\n')) + f.write('{:<22f} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['af_data'][afi][tab]['S1'], 'S1', '! Constant in the f curve best-fit for alpha0<=AOA<=alpha1; by definition it depends on the airfoil. [ignored if UA_Mod<>1]\n')) + f.write('{:<22f} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['af_data'][afi][tab]['S2'], 'S2', '! Constant in the f curve best-fit for AOA> alpha1; by definition it depends on the airfoil. [ignored if UA_Mod<>1]\n')) + f.write('{:<22f} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['af_data'][afi][tab]['S3'], 'S3', '! Constant in the f curve best-fit for alpha2<=AOA< alpha0; by definition it depends on the airfoil. [ignored if UA_Mod<>1]\n')) + f.write('{:<22f} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['af_data'][afi][tab]['S4'], 'S4', '! Constant in the f curve best-fit for AOA< alpha2; by definition it depends on the airfoil. [ignored if UA_Mod<>1]\n')) f.write('{:<22f} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['af_data'][afi][tab]['Cn1'], 'Cn1', '! Critical value of C0n at leading edge separation. It should be extracted from airfoil data at a given Mach and Reynolds number. It can be calculated from the static value of Cn at either the break in the pitching moment or the loss of chord force at the onset of stall. It is close to the condition of maximum lift of the airfoil at low Mach numbers.\n')) f.write('{:<22f} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['af_data'][afi][tab]['Cn2'], 'Cn2', '! As Cn1 for negative AOAs.\n')) # f.write('{: 22f} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['af_data'][afi]['St_sh'], 'St_sh', "! Strouhal's shedding frequency constant. [default = 0.19]\n")) f.write(float_default_out(self.fst_vt['AeroDyn15']['af_data'][afi][tab]['St_sh']) + ' {:<11} {:}'.format('St_sh', "! Strouhal's shedding frequency constant. [default = 0.19]\n")) f.write('{:<22f} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['af_data'][afi][tab]['Cd0'], 'Cd0', '! 2D drag coefficient value at 0-lift.\n')) f.write('{:<22f} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['af_data'][afi][tab]['Cm0'], 'Cm0', '! 2D pitching moment coefficient about 1/4-chord location, at 0-lift, positive if nose up. [If the aerodynamics coefficients table does not include a column for Cm, this needs to be set to 0.0]\n')) - f.write('{:<22f} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['af_data'][afi][tab]['k0'], 'k0', '! Constant in the \\hat(x)_cp curve best-fit; = (\\hat(x)_AC-0.25). [ignored if UAMod<>1]\n')) - f.write('{:<22f} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['af_data'][afi][tab]['k1'], 'k1', '! Constant in the \\hat(x)_cp curve best-fit. [ignored if UAMod<>1]\n')) - f.write('{:<22f} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['af_data'][afi][tab]['k2'], 'k2', '! Constant in the \\hat(x)_cp curve best-fit. [ignored if UAMod<>1]\n')) - f.write('{:<22f} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['af_data'][afi][tab]['k3'], 'k3', '! Constant in the \\hat(x)_cp curve best-fit. [ignored if UAMod<>1]\n')) - f.write('{:<22f} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['af_data'][afi][tab]['k1_hat'], 'k1_hat', '! Constant in the expression of Cc due to leading edge vortex effects. [ignored if UAMod<>1]\n')) - f.write(float_default_out(self.fst_vt['AeroDyn15']['af_data'][afi][tab]['x_cp_bar']) + ' {:<11} {:}'.format('x_cp_bar', '! Constant in the expression of \\hat(x)_cp^v. [ignored if UAMod<>1, default = 0.2]\n')) + f.write('{:<22f} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['af_data'][afi][tab]['k0'], 'k0', '! Constant in the \\hat(x)_cp curve best-fit; = (\\hat(x)_AC-0.25). [ignored if UA_Mod<>1]\n')) + f.write('{:<22f} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['af_data'][afi][tab]['k1'], 'k1', '! Constant in the \\hat(x)_cp curve best-fit. [ignored if UA_Mod<>1]\n')) + f.write('{:<22f} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['af_data'][afi][tab]['k2'], 'k2', '! Constant in the \\hat(x)_cp curve best-fit. [ignored if UA_Mod<>1]\n')) + f.write('{:<22f} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['af_data'][afi][tab]['k3'], 'k3', '! Constant in the \\hat(x)_cp curve best-fit. [ignored if UA_Mod<>1]\n')) + f.write('{:<22f} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['af_data'][afi][tab]['k1_hat'], 'k1_hat', '! Constant in the expression of Cc due to leading edge vortex effects. [ignored if UA_Mod<>1]\n')) + f.write(float_default_out(self.fst_vt['AeroDyn15']['af_data'][afi][tab]['x_cp_bar']) + ' {:<11} {:}'.format('x_cp_bar', '! Constant in the expression of \\hat(x)_cp^v. [ignored if UA_Mod<>1, default = 0.2]\n')) f.write(float_default_out(self.fst_vt['AeroDyn15']['af_data'][afi][tab]['UACutout']) + ' {:<11} {:}'.format('UACutout', '! Angle of attack above which unsteady aerodynamics are disabled (deg). [Specifying the string "Default" sets UACutout to 45 degrees]\n')) f.write(float_default_out(self.fst_vt['AeroDyn15']['af_data'][afi][tab]['filtCutOff']) + ' {:<11} {:}'.format('filtCutOff', '! Cut-off frequency (-3 dB corner frequency) for low-pass filtering the AoA input to UA, as well as the 1st and 2nd derivatives (Hz) [default = 20]\n')) diff --git a/openfast_io/openfast_io/tests/test_of_io_pytest.py b/openfast_io/openfast_io/tests/test_of_io_pytest.py index f8fc5200b..7dbf0e6cd 100644 --- a/openfast_io/openfast_io/tests/test_of_io_pytest.py +++ b/openfast_io/openfast_io/tests/test_of_io_pytest.py @@ -18,17 +18,17 @@ # Exercising the various OpenFAST modules FOLDERS_TO_RUN = [ "5MW_Land_DLL_WTurb" , # "openfast;elastodyn;aerodyn15;servodyn") - # "5MW_OC3Mnpl_DLL_WTurb_WavesIrr" , # "openfast;elastodyn;aerodyn15;servodyn;hydrodyn;subdyn;offshore") - # "5MW_OC3Mnpl_DLL_WTurb_WavesIrr_Restart", # "openfast;elastodyn;aerodyn15;servodyn;hydrodyn;subdyn;offshore;restart") - # "5MW_ITIBarge_DLL_WTurb_WavesIrr" , # "openfast;elastodyn;aerodyn15;servodyn;hydrodyn;map;offshore") - # "5MW_OC4Semi_WSt_WavesWN" , # "openfast;elastodyn;aerodyn15;servodyn;hydrodyn;moordyn;offshore") - # "5MW_Land_BD_DLL_WTurb" , # "openfast;beamdyn;aerodyn15;servodyn") - # "5MW_OC4Jckt_ExtPtfm" , # "openfast;elastodyn;extptfm") - # "HelicalWake_OLAF" , # "openfast;aerodyn15;olaf") - # "StC_test_OC4Semi" , # "openfast;servodyn;hydrodyn;moordyn;offshore;stc") - # "MHK_RM1_Fixed" , # "openfast;elastodyn;aerodyn15;mhk") - # "MHK_RM1_Floating" , # "openfast;elastodyn;aerodyn15;hydrodyn;moordyn;mhk") - # "Tailfin_FreeYaw1DOF_PolarBased" , # "openfast;elastodyn;aerodyn15") + "5MW_OC3Mnpl_DLL_WTurb_WavesIrr" , # "openfast;elastodyn;aerodyn15;servodyn;hydrodyn;subdyn;offshore") + "5MW_OC3Mnpl_DLL_WTurb_WavesIrr_Restart", # "openfast;elastodyn;aerodyn15;servodyn;hydrodyn;subdyn;offshore;restart") + "5MW_ITIBarge_DLL_WTurb_WavesIrr" , # "openfast;elastodyn;aerodyn15;servodyn;hydrodyn;map;offshore") + "5MW_OC4Semi_WSt_WavesWN" , # "openfast;elastodyn;aerodyn15;servodyn;hydrodyn;moordyn;offshore") + "5MW_Land_BD_DLL_WTurb" , # "openfast;beamdyn;aerodyn15;servodyn") + "5MW_OC4Jckt_ExtPtfm" , # "openfast;elastodyn;extptfm") + "HelicalWake_OLAF" , # "openfast;aerodyn15;olaf") + "StC_test_OC4Semi" , # "openfast;servodyn;hydrodyn;moordyn;offshore;stc") + "MHK_RM1_Fixed" , # "openfast;elastodyn;aerodyn15;mhk") + "MHK_RM1_Floating" , # "openfast;elastodyn;aerodyn15;hydrodyn;moordyn;mhk") + "Tailfin_FreeYaw1DOF_PolarBased" , # "openfast;elastodyn;aerodyn15") ] @@ -72,7 +72,7 @@ def write_action(folder, fst_vt, path_dict = getPaths()): def run_action(folder, path_dict = getPaths()): # Placeholder for the actual run action print(f"Running simulation for {folder}") - subprocess.run([OF_PATH, str(osp.join(path_dict['build_dir'], folder, f"{folder}.fst"))], check=True) + subprocess.run([path_dict['executable'], str(osp.join(path_dict['build_dir'], folder, f"{folder}.fst"))], check=True) def check_ascii_out(folder, path_dict = getPaths()): # Placeholder for the actual check action diff --git a/reg_tests/CMakeLists.txt b/reg_tests/CMakeLists.txt index 9d51bb262..cf01f37be 100644 --- a/reg_tests/CMakeLists.txt +++ b/reg_tests/CMakeLists.txt @@ -84,7 +84,7 @@ add_subdirectory("${CMAKE_CURRENT_LIST_DIR}/r-test") # build and seed the test directories with the data they need to run the tests file(MAKE_DIRECTORY ${CTEST_BINARY_DIR}) -foreach(regTest glue-codes/openfast glue-codes/openfast-cpp modules/aerodyn modules/beamdyn modules/hydrodyn modules/inflowwind modules/moordyn modules/subdyn) +foreach(regTest glue-codes/openfast glue-codes/openfast-cpp modules/aerodyn modules/beamdyn modules/hydrodyn modules/inflowwind modules/moordyn modules/subdyn openfastio) file(MAKE_DIRECTORY ${CTEST_BINARY_DIR}/${regTest}) endforeach() diff --git a/reg_tests/CTestList.cmake b/reg_tests/CTestList.cmake index 557b784b3..058abb12d 100644 --- a/reg_tests/CTestList.cmake +++ b/reg_tests/CTestList.cmake @@ -274,209 +274,224 @@ endfunction(py_md_regression) # add_test(${TESTNAME} ${Python_EXECUTABLE} ${test_module} ${input_file} ) # endfunction(py_openfast_library_regression) +# Python-based OpenFAST IO Library tests +function(py_openfast_io_library_pytest TESTNAME LABEL) + set(module "-m") + set(pytest "pytest") + set(pytestVerbose "--verbose") + set(py_test_file "${CMAKE_CURRENT_LIST_DIR}/../openfast_io/openfast_io/tests/test_of_io_pytest.py") + set(executable "--executable=${CTEST_OPENFAST_EXECUTABLE}") + set(source_dir "--source_dir=${CMAKE_CURRENT_LIST_DIR}/..") + set(build_dir "--build_dir=${CTEST_BINARY_DIR}/openfast_io/") + add_test(${TESTNAME} ${Python_EXECUTABLE} ${module} ${pytest} ${pytestVerbose} ${py_test_file} ${executable} ${source_dir} ${build_dir}) +endfunction(py_openfast_io_library_pytest) + #=============================================================================== # Regression tests #=============================================================================== -# OpenFAST regression tests -of_regression("AWT_YFix_WSt" "openfast;elastodyn;aerodyn15;servodyn") -of_regression("AWT_WSt_StartUp_HighSpShutDown" "openfast;elastodyn;aerodyn15;servodyn") -of_regression("AWT_YFree_WSt" "openfast;elastodyn;aerodyn15;servodyn") -of_regression("AWT_YFree_WTurb" "openfast;elastodyn;aerodyn15;servodyn") -of_regression("AWT_WSt_StartUpShutDown" "openfast;elastodyn;aerodyn15;servodyn") -of_regression("AOC_WSt" "openfast;elastodyn;aerodyn15;servodyn") -of_regression("AOC_YFree_WTurb" "openfast;elastodyn;aerodyn15;servodyn") -of_regression("AOC_YFix_WSt" "openfast;elastodyn;aerodyn15;servodyn") -of_regression("UAE_Dnwind_YRamp_WSt" "openfast;elastodyn;aerodyn15;servodyn") -of_regression("UAE_Upwind_Rigid_WRamp_PwrCurve" "openfast;elastodyn;aerodyn15;servodyn") -of_regression("WP_VSP_WTurb_PitchFail" "openfast;elastodyn;aerodyn15;servodyn") -of_regression("WP_VSP_ECD" "openfast;elastodyn;aerodyn15;servodyn") -of_regression("WP_VSP_WTurb" "openfast;elastodyn;aerodyn15;servodyn") -of_regression("SWRT_YFree_VS_EDG01" "openfast;elastodyn;aerodyn15;servodyn") -of_regression("SWRT_YFree_VS_EDC01" "openfast;elastodyn;aerodyn15;servodyn") -of_regression("SWRT_YFree_VS_WTurb" "openfast;elastodyn;aerodyn15;servodyn") -of_regression("5MW_Land_DLL_WTurb" "openfast;elastodyn;aerodyn15;servodyn") -of_regression("5MW_OC3Mnpl_DLL_WTurb_WavesIrr" "openfast;elastodyn;aerodyn15;servodyn;hydrodyn;subdyn;offshore") -of_regression("5MW_OC3Mnpl_DLL_WTurb_WavesIrr_Restart" "openfast;elastodyn;aerodyn15;servodyn;hydrodyn;subdyn;offshore;restart") -of_regression("5MW_OC3Trpd_DLL_WSt_WavesReg" "openfast;elastodyn;aerodyn15;servodyn;hydrodyn;subdyn;offshore") -of_regression("5MW_OC4Jckt_DLL_WTurb_WavesIrr_MGrowth" "openfast;elastodyn;aerodyn15;servodyn;hydrodyn;subdyn;offshore") -of_regression("5MW_ITIBarge_DLL_WTurb_WavesIrr" "openfast;elastodyn;aerodyn15;servodyn;hydrodyn;map;offshore") -of_regression("5MW_TLP_DLL_WTurb_WavesIrr_WavesMulti" "openfast;elastodyn;aerodyn15;servodyn;hydrodyn;map;offshore") -of_regression("5MW_OC3Spar_DLL_WTurb_WavesIrr" "openfast;elastodyn;aerodyn15;servodyn;hydrodyn;map;offshore") -of_regression("5MW_OC4Semi_WSt_WavesWN" "openfast;elastodyn;aerodyn15;servodyn;hydrodyn;moordyn;offshore") -of_regression("5MW_Land_BD_DLL_WTurb" "openfast;beamdyn;aerodyn15;servodyn") -of_regression("5MW_Land_BD_Init" "openfast;beamdyn;aerodyn15;servodyn") -of_regression("5MW_OC4Jckt_ExtPtfm" "openfast;elastodyn;extptfm") -of_regression("HelicalWake_OLAF" "openfast;aerodyn15;olaf") -of_regression("EllipticalWing_OLAF" "openfast;aerodyn15;olaf") -of_regression("StC_test_OC4Semi" "openfast;servodyn;hydrodyn;moordyn;offshore;stc") -of_regression("MHK_RM1_Fixed" "openfast;elastodyn;aerodyn15;mhk") -of_regression("MHK_RM1_Floating" "openfast;elastodyn;aerodyn15;hydrodyn;moordyn;mhk") -of_regression("Tailfin_FreeYaw1DOF_PolarBased" "openfast;elastodyn;aerodyn15") -of_regression("Tailfin_FreeYaw1DOF_Unsteady" "openfast;elastodyn;aerodyn15") - -of_aeromap_regression("5MW_Land_AeroMap" "aeromap;elastodyn;aerodyn15") - -# OpenFAST C++ API test -if(BUILD_OPENFAST_CPP_API) - of_cpp_interface_regression("5MW_Land_DLL_WTurb_cpp" "openfast;fastlib;cpp") -endif() - -# OpenFAST C++ Driver test for OpenFAST Library -# This tests the FAST Library and FAST_Library.h -if(BUILD_OPENFAST_CPP_DRIVER) - of_fastlib_regression("AWT_YFree_WSt" "fastlib;elastodyn;aerodyn15;servodyn") -endif(BUILD_OPENFAST_CPP_DRIVER) - -# OpenFAST Python API test -of_regression_py("5MW_Land_DLL_WTurb_py" "openfast;fastlib;python;elastodyn;aerodyn15;servodyn") -of_regression_py("5MW_ITIBarge_DLL_WTurb_WavesIrr_py" "openfast;fastlib;python;elastodyn;aerodyn15;servodyn;hydrodyn;map;offshore") -of_regression_py("5MW_TLP_DLL_WTurb_WavesIrr_WavesMulti_py" "openfast;fastlib;python;elastodyn;aerodyn15;servodyn;hydrodyn;map;offshore") -of_regression_py("5MW_OC3Spar_DLL_WTurb_WavesIrr_py" "openfast;fastlib;python;elastodyn;aerodyn15;servodyn;hydrodyn;map;offshore") -of_regression_py("5MW_OC4Semi_WSt_WavesWN_py" "openfast;fastlib;python;elastodyn;aerodyn15;servodyn;hydrodyn;moordyn;offshore") -of_regression_py("5MW_Land_BD_DLL_WTurb_py" "openfast;fastlib;python;beamdyn;aerodyn15;servodyn") -of_regression_py("HelicalWake_OLAF_py" "openfast;fastlib;python;aerodyn15;olaf") -of_regression_py("EllipticalWing_OLAF_py" "openfast;fastlib;python;aerodyn15;olaf") - -# AeroAcoustic regression test -of_regression_aeroacoustic("IEA_LB_RWT-AeroAcoustics" "openfast;aerodyn15;aeroacoustics") - -# Linearized OpenFAST regression tests -of_regression_linear("Fake5MW_AeroLin_B1_UA4_DBEMT3" "-highpass=0.05" "openfast;linear;elastodyn;aerodyn") -of_regression_linear("Fake5MW_AeroLin_B3_UA6" "-highpass=0.05" "openfast;linear;elastodyn;aerodyn") -of_regression_linear("WP_Stationary_Linear" "" "openfast;linear;elastodyn") -of_regression_linear("Ideal_Beam_Fixed_Free_Linear" "-highpass=0.10" "openfast;linear;beamdyn") -of_regression_linear("Ideal_Beam_Free_Free_Linear" "-highpass=0.10" "openfast;linear;beamdyn") -of_regression_linear("5MW_Land_Linear_Aero" "-highpass=0.25" "openfast;linear;elastodyn;servodyn;aerodyn") -of_regression_linear("5MW_Land_Linear_Aero_CalcSteady" "-highpass=0.25" "openfast;linear;elastodyn;servodyn;aerodyn") -of_regression_linear("5MW_Land_BD_Linear" "" "openfast;linear;beamdyn;servodyn") -of_regression_linear("5MW_Land_BD_Linear_Aero" "-highpass=0.25" "openfast;linear;beamdyn;servodyn;aerodyn") -of_regression_linear("5MW_OC4Semi_Linear" "" "openfast;linear;hydrodyn;servodyn;map") -of_regression_linear("5MW_OC4Semi_MD_Linear" "" "openfast;linear;hydrodyn;servodyn;moordyn") -of_regression_linear("StC_test_OC4Semi_Linear_Nac" "" "openfast;linear;servodyn;stc") -of_regression_linear("StC_test_OC4Semi_Linear_Tow" "" "openfast;linear;servodyn;stc") -of_regression_linear("WP_Stationary_Linear" "" "openfast;linear;elastodyn") -of_regression_linear("5MW_OC3Spar_Linear" "" "openfast;linear;map;hydrodyn") -of_regression_linear("5MW_OC3Mnpl_Linear" "" "openfast;linear;hydrodyn;servodyn;moordyn") - -# FAST Farm regression tests -if(BUILD_FASTFARM) - ff_regression("TSinflow" "fastfarm") - ff_regression("LESinflow" "fastfarm") -# ff_regression("Uninflow_curl" "fastfarm") - ff_regression("TSinflow_curl" "fastfarm") - ff_regression("ModAmb_3" "fastfarm") -endif() - -# AeroDyn regression tests -ad_regression("ad_timeseries_shutdown" "aerodyn;bem") -ad_regression("ad_EllipticalWingInf_OLAF" "aerodyn;bem") -ad_regression("ad_HelicalWakeInf_OLAF" "aerodyn;bem") -ad_regression("ad_Kite_OLAF" "aerodyn;bem") -ad_regression("ad_MultipleHAWT" "aerodyn;bem") -ad_regression("ad_QuadRotor_OLAF" "aerodyn;bem") -ad_regression("ad_VerticalAxis_OLAF" "aerodyn;bem") -ad_regression("ad_MHK_RM1_Fixed" "aerodyn;bem;mhk") -ad_regression("ad_MHK_RM1_Floating" "aerodyn;bem;mhk") -ad_regression("ad_BAR_CombinedCases" "aerodyn;bem") # NOTE: doing BAR at the end to avoid copy errors -ad_regression("ad_BAR_OLAF" "aerodyn;bem") -ad_regression("ad_BAR_SineMotion" "aerodyn;bem") -ad_regression("ad_BAR_SineMotion_UA4_DBEMT3" "aerodyn;bem") -ad_regression("ad_BAR_RNAMotion" "aerodyn;bem") -ad_regression("ad_B1n2_OLAF" "aerodyn;OLAF") -py_ad_regression("py_ad_5MW_OC4Semi_WSt_WavesWN" "aerodyn;bem;python") -py_ad_regression("py_ad_B1n2_OLAF" "aerodyn;OLAF;python") - -# UnsteadyAero -ua_regression("ua_redfreq" "unsteadyaero") - -# BeamDyn regression tests -bd_regression("bd_5MW_dynamic" "beamdyn;dynamic") -bd_regression("bd_5MW_dynamic_gravity_Az00" "beamdyn;dynamic") -bd_regression("bd_5MW_dynamic_gravity_Az90" "beamdyn;dynamic") -bd_regression("bd_curved_beam" "beamdyn;static") -bd_regression("bd_isotropic_rollup" "beamdyn;static") -bd_regression("bd_static_cantilever_beam" "beamdyn;static") -bd_regression("bd_static_twisted_with_k1" "beamdyn;static") - -# HydroDyn regression tests -hd_regression("hd_5MW_ITIBarge_DLL_WTurb_WavesIrr" "hydrodyn;offshore") -hd_regression("hd_5MW_OC3Spar_DLL_WTurb_WavesIrr" "hydrodyn;offshore") -hd_regression("hd_5MW_OC4Semi_WSt_WavesWN" "hydrodyn;offshore") -hd_regression("hd_5MW_TLP_DLL_WTurb_WavesIrr_WavesMulti" "hydrodyn;offshore") -hd_regression("hd_TaperCylinderPitchMoment" "hydrodyn;offshore") -hd_regression("hd_NBodyMod1" "hydrodyn;offshore") -hd_regression("hd_NBodyMod2" "hydrodyn;offshore") -hd_regression("hd_NBodyMod3" "hydrodyn;offshore") -hd_regression("hd_WaveStMod1" "hydrodyn;offshore") -hd_regression("hd_WaveStMod2" "hydrodyn;offshore") -hd_regression("hd_WaveStMod3" "hydrodyn;offshore") -hd_regression("hd_MHstLMod2" "hydrodyn;offshore") -hd_regression("hd_MHstLMod1_compare" "hydrodyn;offshore") -hd_regression("hd_MHstLMod2_compare" "hydrodyn;offshore") -hd_regression("hd_MCF_WaveStMod0" "hydrodyn;offshore") -hd_regression("hd_MCF_WaveStMod1" "hydrodyn;offshore") -hd_regression("hd_MCF_WaveStMod2" "hydrodyn;offshore") -hd_regression("hd_MCF_WaveStMod3" "hydrodyn;offshore") -hd_regression("hd_ExctnMod1_ExctnDisp1" "hydrodyn;offshore") -hd_regression("hd_ExctnMod1_ExctnDisp2" "hydrodyn;offshore") - -# Py-HydroDyn regression tests -py_hd_regression("py_hd_5MW_OC4Semi_WSt_WavesWN" "hydrodyn;offshore;python") - -# SubDyn regression tests -sd_regression("SD_Cable_5Joints" "subdyn;offshore") -sd_regression("SD_PendulumDamp" "subdyn;offshore") -sd_regression("SD_Rigid" "subdyn;offshore") -sd_regression("SD_SparHanging" "subdyn;offshore") -sd_regression("SD_AnsysComp1_PinBeam" "subdyn;offshore") # TODO Issue #855 -sd_regression("SD_AnsysComp2_Cable" "subdyn;offshore") -sd_regression("SD_AnsysComp3_PinBeamCable" "subdyn;offshore") # TODO Issue #855 -sd_regression("SD_Spring_Case1" "subdyn;offshore") -sd_regression("SD_Spring_Case2" "subdyn;offshore") -sd_regression("SD_Spring_Case3" "subdyn;offshore") -sd_regression("SD_Revolute_Joint" "subdyn;offshore") -sd_regression("SD_2Beam_Spring" "subdyn;offshore") -sd_regression("SD_2Beam_Cantilever" "subdyn;offshore") -# TODO test below are bugs, should be added when fixed -# sd_regression("SD_Force" "subdyn;offshore") -# sd_regression("SD_AnsysComp4_UniversalCableRigid" "subdyn;offshore") -# sd_regression("SD_Rigid2Interf_Cables" "subdyn;offshore") - -# InflowWind regression tests -ifw_regression("ifw_turbsimff" "inflowwind") -ifw_regression("ifw_uniform" "inflowwind") -ifw_regression("ifw_nativeBladed" "inflowwind") -ifw_regression("ifw_BoxExceed" "inflowwind") -ifw_regression("ifw_BoxExceedTwr" "inflowwind") -ifw_regression("ifw_HAWC" "inflowwind") - -# Py-InflowWind regression tests -py_ifw_regression("py_ifw_turbsimff" "inflowwind;python") - -# SeaState regression tests -seast_regression("seastate_1" "seastate") -seast_regression("seastate_wr_kin1" "seastate") -seast_regression("seastate_CNW1" "seastate") -seast_regression("seastate_CNW2" "seastate") -seast_regression("seastate_WaveMod7_WaveStMod1" "seastate") -seast_regression("seastate_WaveMod7_WaveStMod2" "seastate") -seast_regression("seastate_WaveMod7_WaveStMod3" "seastate") -seast_regression("seastate_wavemod5" "seastate") # place at end since it reads outputs generated by seastate_wr_kin1 - -# MoorDyn regression tests -md_regression("md_5MW_OC4Semi" "moordyn") -md_regression("md_lineFail" "moordyn") -md_regression("md_BodiesAndRods" "moordyn") -md_regression("md_bodyDrag" "moordyn") -md_regression("md_cable" "moordyn") -md_regression("md_case2" "moordyn") -md_regression("md_case5" "moordyn") -md_regression("md_float" "moordyn") -md_regression("md_horizontal" "moordyn") -md_regression("md_no_line" "moordyn") -md_regression("md_vertical" "moordyn") -py_md_regression("py_md_5MW_OC4Semi" "moordyn;python") -# the following tests are excessively slow in double precision, so skip these in normal testing -#md_regression("md_Single_Line_Quasi_Static_Test" "moordyn") +# # OpenFAST regression tests +# of_regression("AWT_YFix_WSt" "openfast;elastodyn;aerodyn15;servodyn") +# of_regression("AWT_WSt_StartUp_HighSpShutDown" "openfast;elastodyn;aerodyn15;servodyn") +# of_regression("AWT_YFree_WSt" "openfast;elastodyn;aerodyn15;servodyn") +# of_regression("AWT_YFree_WTurb" "openfast;elastodyn;aerodyn15;servodyn") +# of_regression("AWT_WSt_StartUpShutDown" "openfast;elastodyn;aerodyn15;servodyn") +# of_regression("AOC_WSt" "openfast;elastodyn;aerodyn15;servodyn") +# of_regression("AOC_YFree_WTurb" "openfast;elastodyn;aerodyn15;servodyn") +# of_regression("AOC_YFix_WSt" "openfast;elastodyn;aerodyn15;servodyn") +# of_regression("UAE_Dnwind_YRamp_WSt" "openfast;elastodyn;aerodyn15;servodyn") +# of_regression("UAE_Upwind_Rigid_WRamp_PwrCurve" "openfast;elastodyn;aerodyn15;servodyn") +# of_regression("WP_VSP_WTurb_PitchFail" "openfast;elastodyn;aerodyn15;servodyn") +# of_regression("WP_VSP_ECD" "openfast;elastodyn;aerodyn15;servodyn") +# of_regression("WP_VSP_WTurb" "openfast;elastodyn;aerodyn15;servodyn") +# of_regression("SWRT_YFree_VS_EDG01" "openfast;elastodyn;aerodyn15;servodyn") +# of_regression("SWRT_YFree_VS_EDC01" "openfast;elastodyn;aerodyn15;servodyn") +# of_regression("SWRT_YFree_VS_WTurb" "openfast;elastodyn;aerodyn15;servodyn") +# of_regression("5MW_Land_DLL_WTurb" "openfast;elastodyn;aerodyn15;servodyn") +# of_regression("5MW_OC3Mnpl_DLL_WTurb_WavesIrr" "openfast;elastodyn;aerodyn15;servodyn;hydrodyn;subdyn;offshore") +# of_regression("5MW_OC3Mnpl_DLL_WTurb_WavesIrr_Restart" "openfast;elastodyn;aerodyn15;servodyn;hydrodyn;subdyn;offshore;restart") +# of_regression("5MW_OC3Trpd_DLL_WSt_WavesReg" "openfast;elastodyn;aerodyn15;servodyn;hydrodyn;subdyn;offshore") +# of_regression("5MW_OC4Jckt_DLL_WTurb_WavesIrr_MGrowth" "openfast;elastodyn;aerodyn15;servodyn;hydrodyn;subdyn;offshore") +# of_regression("5MW_ITIBarge_DLL_WTurb_WavesIrr" "openfast;elastodyn;aerodyn15;servodyn;hydrodyn;map;offshore") +# of_regression("5MW_TLP_DLL_WTurb_WavesIrr_WavesMulti" "openfast;elastodyn;aerodyn15;servodyn;hydrodyn;map;offshore") +# of_regression("5MW_OC3Spar_DLL_WTurb_WavesIrr" "openfast;elastodyn;aerodyn15;servodyn;hydrodyn;map;offshore") +# of_regression("5MW_OC4Semi_WSt_WavesWN" "openfast;elastodyn;aerodyn15;servodyn;hydrodyn;moordyn;offshore") +# of_regression("5MW_Land_BD_DLL_WTurb" "openfast;beamdyn;aerodyn15;servodyn") +# of_regression("5MW_Land_BD_Init" "openfast;beamdyn;aerodyn15;servodyn") +# of_regression("5MW_OC4Jckt_ExtPtfm" "openfast;elastodyn;extptfm") +# of_regression("HelicalWake_OLAF" "openfast;aerodyn15;olaf") +# of_regression("EllipticalWing_OLAF" "openfast;aerodyn15;olaf") +# of_regression("StC_test_OC4Semi" "openfast;servodyn;hydrodyn;moordyn;offshore;stc") +# of_regression("MHK_RM1_Fixed" "openfast;elastodyn;aerodyn15;mhk") +# of_regression("MHK_RM1_Floating" "openfast;elastodyn;aerodyn15;hydrodyn;moordyn;mhk") +# of_regression("Tailfin_FreeYaw1DOF_PolarBased" "openfast;elastodyn;aerodyn15") +# of_regression("Tailfin_FreeYaw1DOF_Unsteady" "openfast;elastodyn;aerodyn15") + +# of_aeromap_regression("5MW_Land_AeroMap" "aeromap;elastodyn;aerodyn15") + +# # OpenFAST C++ API test +# if(BUILD_OPENFAST_CPP_API) +# of_cpp_interface_regression("5MW_Land_DLL_WTurb_cpp" "openfast;fastlib;cpp") +# endif() + +# # OpenFAST C++ Driver test for OpenFAST Library +# # This tests the FAST Library and FAST_Library.h +# if(BUILD_OPENFAST_CPP_DRIVER) +# of_fastlib_regression("AWT_YFree_WSt" "fastlib;elastodyn;aerodyn15;servodyn") +# endif(BUILD_OPENFAST_CPP_DRIVER) + +# # OpenFAST Python API test +# of_regression_py("5MW_Land_DLL_WTurb_py" "openfast;fastlib;python;elastodyn;aerodyn15;servodyn") +# of_regression_py("5MW_ITIBarge_DLL_WTurb_WavesIrr_py" "openfast;fastlib;python;elastodyn;aerodyn15;servodyn;hydrodyn;map;offshore") +# of_regression_py("5MW_TLP_DLL_WTurb_WavesIrr_WavesMulti_py" "openfast;fastlib;python;elastodyn;aerodyn15;servodyn;hydrodyn;map;offshore") +# of_regression_py("5MW_OC3Spar_DLL_WTurb_WavesIrr_py" "openfast;fastlib;python;elastodyn;aerodyn15;servodyn;hydrodyn;map;offshore") +# of_regression_py("5MW_OC4Semi_WSt_WavesWN_py" "openfast;fastlib;python;elastodyn;aerodyn15;servodyn;hydrodyn;moordyn;offshore") +# of_regression_py("5MW_Land_BD_DLL_WTurb_py" "openfast;fastlib;python;beamdyn;aerodyn15;servodyn") +# of_regression_py("HelicalWake_OLAF_py" "openfast;fastlib;python;aerodyn15;olaf") +# of_regression_py("EllipticalWing_OLAF_py" "openfast;fastlib;python;aerodyn15;olaf") + +# # AeroAcoustic regression test +# of_regression_aeroacoustic("IEA_LB_RWT-AeroAcoustics" "openfast;aerodyn15;aeroacoustics") + +# # Linearized OpenFAST regression tests +# of_regression_linear("Fake5MW_AeroLin_B1_UA4_DBEMT3" "-highpass=0.05" "openfast;linear;elastodyn;aerodyn") +# of_regression_linear("Fake5MW_AeroLin_B3_UA6" "-highpass=0.05" "openfast;linear;elastodyn;aerodyn") +# of_regression_linear("WP_Stationary_Linear" "" "openfast;linear;elastodyn") +# of_regression_linear("Ideal_Beam_Fixed_Free_Linear" "-highpass=0.10" "openfast;linear;beamdyn") +# of_regression_linear("Ideal_Beam_Free_Free_Linear" "-highpass=0.10" "openfast;linear;beamdyn") +# of_regression_linear("5MW_Land_Linear_Aero" "-highpass=0.25" "openfast;linear;elastodyn;servodyn;aerodyn") +# of_regression_linear("5MW_Land_Linear_Aero_CalcSteady" "-highpass=0.25" "openfast;linear;elastodyn;servodyn;aerodyn") +# of_regression_linear("5MW_Land_BD_Linear" "" "openfast;linear;beamdyn;servodyn") +# of_regression_linear("5MW_Land_BD_Linear_Aero" "-highpass=0.25" "openfast;linear;beamdyn;servodyn;aerodyn") +# of_regression_linear("5MW_OC4Semi_Linear" "" "openfast;linear;hydrodyn;servodyn;map") +# of_regression_linear("5MW_OC4Semi_MD_Linear" "" "openfast;linear;hydrodyn;servodyn;moordyn") +# of_regression_linear("StC_test_OC4Semi_Linear_Nac" "" "openfast;linear;servodyn;stc") +# of_regression_linear("StC_test_OC4Semi_Linear_Tow" "" "openfast;linear;servodyn;stc") +# of_regression_linear("WP_Stationary_Linear" "" "openfast;linear;elastodyn") +# of_regression_linear("5MW_OC3Spar_Linear" "" "openfast;linear;map;hydrodyn") +# of_regression_linear("5MW_OC3Mnpl_Linear" "" "openfast;linear;hydrodyn;servodyn;moordyn") + +# # FAST Farm regression tests +# if(BUILD_FASTFARM) +# ff_regression("TSinflow" "fastfarm") +# ff_regression("LESinflow" "fastfarm") +# # ff_regression("Uninflow_curl" "fastfarm") +# ff_regression("TSinflow_curl" "fastfarm") +# ff_regression("ModAmb_3" "fastfarm") +# endif() + +# # AeroDyn regression tests +# ad_regression("ad_timeseries_shutdown" "aerodyn;bem") +# ad_regression("ad_EllipticalWingInf_OLAF" "aerodyn;bem") +# ad_regression("ad_HelicalWakeInf_OLAF" "aerodyn;bem") +# ad_regression("ad_Kite_OLAF" "aerodyn;bem") +# ad_regression("ad_MultipleHAWT" "aerodyn;bem") +# ad_regression("ad_QuadRotor_OLAF" "aerodyn;bem") +# ad_regression("ad_VerticalAxis_OLAF" "aerodyn;bem") +# ad_regression("ad_MHK_RM1_Fixed" "aerodyn;bem;mhk") +# ad_regression("ad_MHK_RM1_Floating" "aerodyn;bem;mhk") +# ad_regression("ad_BAR_CombinedCases" "aerodyn;bem") # NOTE: doing BAR at the end to avoid copy errors +# ad_regression("ad_BAR_OLAF" "aerodyn;bem") +# ad_regression("ad_BAR_SineMotion" "aerodyn;bem") +# ad_regression("ad_BAR_SineMotion_UA4_DBEMT3" "aerodyn;bem") +# ad_regression("ad_BAR_RNAMotion" "aerodyn;bem") +# ad_regression("ad_B1n2_OLAF" "aerodyn;OLAF") +# py_ad_regression("py_ad_5MW_OC4Semi_WSt_WavesWN" "aerodyn;bem;python") +# py_ad_regression("py_ad_B1n2_OLAF" "aerodyn;OLAF;python") + +# # UnsteadyAero +# ua_regression("ua_redfreq" "unsteadyaero") + +# # BeamDyn regression tests +# bd_regression("bd_5MW_dynamic" "beamdyn;dynamic") +# bd_regression("bd_5MW_dynamic_gravity_Az00" "beamdyn;dynamic") +# bd_regression("bd_5MW_dynamic_gravity_Az90" "beamdyn;dynamic") +# bd_regression("bd_curved_beam" "beamdyn;static") +# bd_regression("bd_isotropic_rollup" "beamdyn;static") +# bd_regression("bd_static_cantilever_beam" "beamdyn;static") +# bd_regression("bd_static_twisted_with_k1" "beamdyn;static") + +# # HydroDyn regression tests +# hd_regression("hd_5MW_ITIBarge_DLL_WTurb_WavesIrr" "hydrodyn;offshore") +# hd_regression("hd_5MW_OC3Spar_DLL_WTurb_WavesIrr" "hydrodyn;offshore") +# hd_regression("hd_5MW_OC4Semi_WSt_WavesWN" "hydrodyn;offshore") +# hd_regression("hd_5MW_TLP_DLL_WTurb_WavesIrr_WavesMulti" "hydrodyn;offshore") +# hd_regression("hd_TaperCylinderPitchMoment" "hydrodyn;offshore") +# hd_regression("hd_NBodyMod1" "hydrodyn;offshore") +# hd_regression("hd_NBodyMod2" "hydrodyn;offshore") +# hd_regression("hd_NBodyMod3" "hydrodyn;offshore") +# hd_regression("hd_WaveStMod1" "hydrodyn;offshore") +# hd_regression("hd_WaveStMod2" "hydrodyn;offshore") +# hd_regression("hd_WaveStMod3" "hydrodyn;offshore") +# hd_regression("hd_MHstLMod2" "hydrodyn;offshore") +# hd_regression("hd_MHstLMod1_compare" "hydrodyn;offshore") +# hd_regression("hd_MHstLMod2_compare" "hydrodyn;offshore") +# hd_regression("hd_MCF_WaveStMod0" "hydrodyn;offshore") +# hd_regression("hd_MCF_WaveStMod1" "hydrodyn;offshore") +# hd_regression("hd_MCF_WaveStMod2" "hydrodyn;offshore") +# hd_regression("hd_MCF_WaveStMod3" "hydrodyn;offshore") +# hd_regression("hd_ExctnMod1_ExctnDisp1" "hydrodyn;offshore") +# hd_regression("hd_ExctnMod1_ExctnDisp2" "hydrodyn;offshore") + +# # Py-HydroDyn regression tests +# py_hd_regression("py_hd_5MW_OC4Semi_WSt_WavesWN" "hydrodyn;offshore;python") + +# # SubDyn regression tests +# sd_regression("SD_Cable_5Joints" "subdyn;offshore") +# sd_regression("SD_PendulumDamp" "subdyn;offshore") +# sd_regression("SD_Rigid" "subdyn;offshore") +# sd_regression("SD_SparHanging" "subdyn;offshore") +# sd_regression("SD_AnsysComp1_PinBeam" "subdyn;offshore") # TODO Issue #855 +# sd_regression("SD_AnsysComp2_Cable" "subdyn;offshore") +# sd_regression("SD_AnsysComp3_PinBeamCable" "subdyn;offshore") # TODO Issue #855 +# sd_regression("SD_Spring_Case1" "subdyn;offshore") +# sd_regression("SD_Spring_Case2" "subdyn;offshore") +# sd_regression("SD_Spring_Case3" "subdyn;offshore") +# sd_regression("SD_Revolute_Joint" "subdyn;offshore") +# sd_regression("SD_2Beam_Spring" "subdyn;offshore") +# sd_regression("SD_2Beam_Cantilever" "subdyn;offshore") +# # TODO test below are bugs, should be added when fixed +# # sd_regression("SD_Force" "subdyn;offshore") +# # sd_regression("SD_AnsysComp4_UniversalCableRigid" "subdyn;offshore") +# # sd_regression("SD_Rigid2Interf_Cables" "subdyn;offshore") + +# # InflowWind regression tests +# ifw_regression("ifw_turbsimff" "inflowwind") +# ifw_regression("ifw_uniform" "inflowwind") +# ifw_regression("ifw_nativeBladed" "inflowwind") +# ifw_regression("ifw_BoxExceed" "inflowwind") +# ifw_regression("ifw_BoxExceedTwr" "inflowwind") +# ifw_regression("ifw_HAWC" "inflowwind") + +# # Py-InflowWind regression tests +# py_ifw_regression("py_ifw_turbsimff" "inflowwind;python") + +# # SeaState regression tests +# seast_regression("seastate_1" "seastate") +# seast_regression("seastate_wr_kin1" "seastate") +# seast_regression("seastate_CNW1" "seastate") +# seast_regression("seastate_CNW2" "seastate") +# seast_regression("seastate_WaveMod7_WaveStMod1" "seastate") +# seast_regression("seastate_WaveMod7_WaveStMod2" "seastate") +# seast_regression("seastate_WaveMod7_WaveStMod3" "seastate") +# seast_regression("seastate_wavemod5" "seastate") # place at end since it reads outputs generated by seastate_wr_kin1 + +# # MoorDyn regression tests +# md_regression("md_5MW_OC4Semi" "moordyn") +# md_regression("md_lineFail" "moordyn") +# md_regression("md_BodiesAndRods" "moordyn") +# md_regression("md_bodyDrag" "moordyn") +# md_regression("md_cable" "moordyn") +# md_regression("md_case2" "moordyn") +# md_regression("md_case5" "moordyn") +# md_regression("md_float" "moordyn") +# md_regression("md_horizontal" "moordyn") +# md_regression("md_no_line" "moordyn") +# md_regression("md_vertical" "moordyn") +# py_md_regression("py_md_5MW_OC4Semi" "moordyn;python") +# # the following tests are excessively slow in double precision, so skip these in normal testing +# #md_regression("md_Single_Line_Quasi_Static_Test" "moordyn") + +# OpenFAST IO Library regression tests +py_openfast_io_library_pytest("openfast_io_library" "openfast_io;python") \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index 21752feaf..ad406e055 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,5 @@ # Python dependencies used for testing numpy vtk -Bokeh>=2.4,!=3.0.0,!=3.0.1,!=3.0.2,!=3.0.3 \ No newline at end of file +Bokeh>=2.4,!=3.0.0,!=3.0.1,!=3.0.2,!=3.0.3 +pytest \ No newline at end of file From e5a5abdf8ccceb91608de85ecb2b627941c96e6c Mon Sep 17 00:00:00 2001 From: Mayank Chetan Date: Fri, 23 Aug 2024 23:02:30 +0000 Subject: [PATCH 029/161] oops --- reg_tests/CTestList.cmake | 404 +++++++++++++++++++------------------- 1 file changed, 202 insertions(+), 202 deletions(-) diff --git a/reg_tests/CTestList.cmake b/reg_tests/CTestList.cmake index 058abb12d..1d321848b 100644 --- a/reg_tests/CTestList.cmake +++ b/reg_tests/CTestList.cmake @@ -291,207 +291,207 @@ endfunction(py_openfast_io_library_pytest) # Regression tests #=============================================================================== -# # OpenFAST regression tests -# of_regression("AWT_YFix_WSt" "openfast;elastodyn;aerodyn15;servodyn") -# of_regression("AWT_WSt_StartUp_HighSpShutDown" "openfast;elastodyn;aerodyn15;servodyn") -# of_regression("AWT_YFree_WSt" "openfast;elastodyn;aerodyn15;servodyn") -# of_regression("AWT_YFree_WTurb" "openfast;elastodyn;aerodyn15;servodyn") -# of_regression("AWT_WSt_StartUpShutDown" "openfast;elastodyn;aerodyn15;servodyn") -# of_regression("AOC_WSt" "openfast;elastodyn;aerodyn15;servodyn") -# of_regression("AOC_YFree_WTurb" "openfast;elastodyn;aerodyn15;servodyn") -# of_regression("AOC_YFix_WSt" "openfast;elastodyn;aerodyn15;servodyn") -# of_regression("UAE_Dnwind_YRamp_WSt" "openfast;elastodyn;aerodyn15;servodyn") -# of_regression("UAE_Upwind_Rigid_WRamp_PwrCurve" "openfast;elastodyn;aerodyn15;servodyn") -# of_regression("WP_VSP_WTurb_PitchFail" "openfast;elastodyn;aerodyn15;servodyn") -# of_regression("WP_VSP_ECD" "openfast;elastodyn;aerodyn15;servodyn") -# of_regression("WP_VSP_WTurb" "openfast;elastodyn;aerodyn15;servodyn") -# of_regression("SWRT_YFree_VS_EDG01" "openfast;elastodyn;aerodyn15;servodyn") -# of_regression("SWRT_YFree_VS_EDC01" "openfast;elastodyn;aerodyn15;servodyn") -# of_regression("SWRT_YFree_VS_WTurb" "openfast;elastodyn;aerodyn15;servodyn") -# of_regression("5MW_Land_DLL_WTurb" "openfast;elastodyn;aerodyn15;servodyn") -# of_regression("5MW_OC3Mnpl_DLL_WTurb_WavesIrr" "openfast;elastodyn;aerodyn15;servodyn;hydrodyn;subdyn;offshore") -# of_regression("5MW_OC3Mnpl_DLL_WTurb_WavesIrr_Restart" "openfast;elastodyn;aerodyn15;servodyn;hydrodyn;subdyn;offshore;restart") -# of_regression("5MW_OC3Trpd_DLL_WSt_WavesReg" "openfast;elastodyn;aerodyn15;servodyn;hydrodyn;subdyn;offshore") -# of_regression("5MW_OC4Jckt_DLL_WTurb_WavesIrr_MGrowth" "openfast;elastodyn;aerodyn15;servodyn;hydrodyn;subdyn;offshore") -# of_regression("5MW_ITIBarge_DLL_WTurb_WavesIrr" "openfast;elastodyn;aerodyn15;servodyn;hydrodyn;map;offshore") -# of_regression("5MW_TLP_DLL_WTurb_WavesIrr_WavesMulti" "openfast;elastodyn;aerodyn15;servodyn;hydrodyn;map;offshore") -# of_regression("5MW_OC3Spar_DLL_WTurb_WavesIrr" "openfast;elastodyn;aerodyn15;servodyn;hydrodyn;map;offshore") -# of_regression("5MW_OC4Semi_WSt_WavesWN" "openfast;elastodyn;aerodyn15;servodyn;hydrodyn;moordyn;offshore") -# of_regression("5MW_Land_BD_DLL_WTurb" "openfast;beamdyn;aerodyn15;servodyn") -# of_regression("5MW_Land_BD_Init" "openfast;beamdyn;aerodyn15;servodyn") -# of_regression("5MW_OC4Jckt_ExtPtfm" "openfast;elastodyn;extptfm") -# of_regression("HelicalWake_OLAF" "openfast;aerodyn15;olaf") -# of_regression("EllipticalWing_OLAF" "openfast;aerodyn15;olaf") -# of_regression("StC_test_OC4Semi" "openfast;servodyn;hydrodyn;moordyn;offshore;stc") -# of_regression("MHK_RM1_Fixed" "openfast;elastodyn;aerodyn15;mhk") -# of_regression("MHK_RM1_Floating" "openfast;elastodyn;aerodyn15;hydrodyn;moordyn;mhk") -# of_regression("Tailfin_FreeYaw1DOF_PolarBased" "openfast;elastodyn;aerodyn15") -# of_regression("Tailfin_FreeYaw1DOF_Unsteady" "openfast;elastodyn;aerodyn15") - -# of_aeromap_regression("5MW_Land_AeroMap" "aeromap;elastodyn;aerodyn15") - -# # OpenFAST C++ API test -# if(BUILD_OPENFAST_CPP_API) -# of_cpp_interface_regression("5MW_Land_DLL_WTurb_cpp" "openfast;fastlib;cpp") -# endif() - -# # OpenFAST C++ Driver test for OpenFAST Library -# # This tests the FAST Library and FAST_Library.h -# if(BUILD_OPENFAST_CPP_DRIVER) -# of_fastlib_regression("AWT_YFree_WSt" "fastlib;elastodyn;aerodyn15;servodyn") -# endif(BUILD_OPENFAST_CPP_DRIVER) - -# # OpenFAST Python API test -# of_regression_py("5MW_Land_DLL_WTurb_py" "openfast;fastlib;python;elastodyn;aerodyn15;servodyn") -# of_regression_py("5MW_ITIBarge_DLL_WTurb_WavesIrr_py" "openfast;fastlib;python;elastodyn;aerodyn15;servodyn;hydrodyn;map;offshore") -# of_regression_py("5MW_TLP_DLL_WTurb_WavesIrr_WavesMulti_py" "openfast;fastlib;python;elastodyn;aerodyn15;servodyn;hydrodyn;map;offshore") -# of_regression_py("5MW_OC3Spar_DLL_WTurb_WavesIrr_py" "openfast;fastlib;python;elastodyn;aerodyn15;servodyn;hydrodyn;map;offshore") -# of_regression_py("5MW_OC4Semi_WSt_WavesWN_py" "openfast;fastlib;python;elastodyn;aerodyn15;servodyn;hydrodyn;moordyn;offshore") -# of_regression_py("5MW_Land_BD_DLL_WTurb_py" "openfast;fastlib;python;beamdyn;aerodyn15;servodyn") -# of_regression_py("HelicalWake_OLAF_py" "openfast;fastlib;python;aerodyn15;olaf") -# of_regression_py("EllipticalWing_OLAF_py" "openfast;fastlib;python;aerodyn15;olaf") - -# # AeroAcoustic regression test -# of_regression_aeroacoustic("IEA_LB_RWT-AeroAcoustics" "openfast;aerodyn15;aeroacoustics") - -# # Linearized OpenFAST regression tests -# of_regression_linear("Fake5MW_AeroLin_B1_UA4_DBEMT3" "-highpass=0.05" "openfast;linear;elastodyn;aerodyn") -# of_regression_linear("Fake5MW_AeroLin_B3_UA6" "-highpass=0.05" "openfast;linear;elastodyn;aerodyn") -# of_regression_linear("WP_Stationary_Linear" "" "openfast;linear;elastodyn") -# of_regression_linear("Ideal_Beam_Fixed_Free_Linear" "-highpass=0.10" "openfast;linear;beamdyn") -# of_regression_linear("Ideal_Beam_Free_Free_Linear" "-highpass=0.10" "openfast;linear;beamdyn") -# of_regression_linear("5MW_Land_Linear_Aero" "-highpass=0.25" "openfast;linear;elastodyn;servodyn;aerodyn") -# of_regression_linear("5MW_Land_Linear_Aero_CalcSteady" "-highpass=0.25" "openfast;linear;elastodyn;servodyn;aerodyn") -# of_regression_linear("5MW_Land_BD_Linear" "" "openfast;linear;beamdyn;servodyn") -# of_regression_linear("5MW_Land_BD_Linear_Aero" "-highpass=0.25" "openfast;linear;beamdyn;servodyn;aerodyn") -# of_regression_linear("5MW_OC4Semi_Linear" "" "openfast;linear;hydrodyn;servodyn;map") -# of_regression_linear("5MW_OC4Semi_MD_Linear" "" "openfast;linear;hydrodyn;servodyn;moordyn") -# of_regression_linear("StC_test_OC4Semi_Linear_Nac" "" "openfast;linear;servodyn;stc") -# of_regression_linear("StC_test_OC4Semi_Linear_Tow" "" "openfast;linear;servodyn;stc") -# of_regression_linear("WP_Stationary_Linear" "" "openfast;linear;elastodyn") -# of_regression_linear("5MW_OC3Spar_Linear" "" "openfast;linear;map;hydrodyn") -# of_regression_linear("5MW_OC3Mnpl_Linear" "" "openfast;linear;hydrodyn;servodyn;moordyn") - -# # FAST Farm regression tests -# if(BUILD_FASTFARM) -# ff_regression("TSinflow" "fastfarm") -# ff_regression("LESinflow" "fastfarm") -# # ff_regression("Uninflow_curl" "fastfarm") -# ff_regression("TSinflow_curl" "fastfarm") -# ff_regression("ModAmb_3" "fastfarm") -# endif() - -# # AeroDyn regression tests -# ad_regression("ad_timeseries_shutdown" "aerodyn;bem") -# ad_regression("ad_EllipticalWingInf_OLAF" "aerodyn;bem") -# ad_regression("ad_HelicalWakeInf_OLAF" "aerodyn;bem") -# ad_regression("ad_Kite_OLAF" "aerodyn;bem") -# ad_regression("ad_MultipleHAWT" "aerodyn;bem") -# ad_regression("ad_QuadRotor_OLAF" "aerodyn;bem") -# ad_regression("ad_VerticalAxis_OLAF" "aerodyn;bem") -# ad_regression("ad_MHK_RM1_Fixed" "aerodyn;bem;mhk") -# ad_regression("ad_MHK_RM1_Floating" "aerodyn;bem;mhk") -# ad_regression("ad_BAR_CombinedCases" "aerodyn;bem") # NOTE: doing BAR at the end to avoid copy errors -# ad_regression("ad_BAR_OLAF" "aerodyn;bem") -# ad_regression("ad_BAR_SineMotion" "aerodyn;bem") -# ad_regression("ad_BAR_SineMotion_UA4_DBEMT3" "aerodyn;bem") -# ad_regression("ad_BAR_RNAMotion" "aerodyn;bem") -# ad_regression("ad_B1n2_OLAF" "aerodyn;OLAF") -# py_ad_regression("py_ad_5MW_OC4Semi_WSt_WavesWN" "aerodyn;bem;python") -# py_ad_regression("py_ad_B1n2_OLAF" "aerodyn;OLAF;python") - -# # UnsteadyAero -# ua_regression("ua_redfreq" "unsteadyaero") - -# # BeamDyn regression tests -# bd_regression("bd_5MW_dynamic" "beamdyn;dynamic") -# bd_regression("bd_5MW_dynamic_gravity_Az00" "beamdyn;dynamic") -# bd_regression("bd_5MW_dynamic_gravity_Az90" "beamdyn;dynamic") -# bd_regression("bd_curved_beam" "beamdyn;static") -# bd_regression("bd_isotropic_rollup" "beamdyn;static") -# bd_regression("bd_static_cantilever_beam" "beamdyn;static") -# bd_regression("bd_static_twisted_with_k1" "beamdyn;static") - -# # HydroDyn regression tests -# hd_regression("hd_5MW_ITIBarge_DLL_WTurb_WavesIrr" "hydrodyn;offshore") -# hd_regression("hd_5MW_OC3Spar_DLL_WTurb_WavesIrr" "hydrodyn;offshore") -# hd_regression("hd_5MW_OC4Semi_WSt_WavesWN" "hydrodyn;offshore") -# hd_regression("hd_5MW_TLP_DLL_WTurb_WavesIrr_WavesMulti" "hydrodyn;offshore") -# hd_regression("hd_TaperCylinderPitchMoment" "hydrodyn;offshore") -# hd_regression("hd_NBodyMod1" "hydrodyn;offshore") -# hd_regression("hd_NBodyMod2" "hydrodyn;offshore") -# hd_regression("hd_NBodyMod3" "hydrodyn;offshore") -# hd_regression("hd_WaveStMod1" "hydrodyn;offshore") -# hd_regression("hd_WaveStMod2" "hydrodyn;offshore") -# hd_regression("hd_WaveStMod3" "hydrodyn;offshore") -# hd_regression("hd_MHstLMod2" "hydrodyn;offshore") -# hd_regression("hd_MHstLMod1_compare" "hydrodyn;offshore") -# hd_regression("hd_MHstLMod2_compare" "hydrodyn;offshore") -# hd_regression("hd_MCF_WaveStMod0" "hydrodyn;offshore") -# hd_regression("hd_MCF_WaveStMod1" "hydrodyn;offshore") -# hd_regression("hd_MCF_WaveStMod2" "hydrodyn;offshore") -# hd_regression("hd_MCF_WaveStMod3" "hydrodyn;offshore") -# hd_regression("hd_ExctnMod1_ExctnDisp1" "hydrodyn;offshore") -# hd_regression("hd_ExctnMod1_ExctnDisp2" "hydrodyn;offshore") - -# # Py-HydroDyn regression tests -# py_hd_regression("py_hd_5MW_OC4Semi_WSt_WavesWN" "hydrodyn;offshore;python") - -# # SubDyn regression tests -# sd_regression("SD_Cable_5Joints" "subdyn;offshore") -# sd_regression("SD_PendulumDamp" "subdyn;offshore") -# sd_regression("SD_Rigid" "subdyn;offshore") -# sd_regression("SD_SparHanging" "subdyn;offshore") -# sd_regression("SD_AnsysComp1_PinBeam" "subdyn;offshore") # TODO Issue #855 -# sd_regression("SD_AnsysComp2_Cable" "subdyn;offshore") -# sd_regression("SD_AnsysComp3_PinBeamCable" "subdyn;offshore") # TODO Issue #855 -# sd_regression("SD_Spring_Case1" "subdyn;offshore") -# sd_regression("SD_Spring_Case2" "subdyn;offshore") -# sd_regression("SD_Spring_Case3" "subdyn;offshore") -# sd_regression("SD_Revolute_Joint" "subdyn;offshore") -# sd_regression("SD_2Beam_Spring" "subdyn;offshore") -# sd_regression("SD_2Beam_Cantilever" "subdyn;offshore") -# # TODO test below are bugs, should be added when fixed -# # sd_regression("SD_Force" "subdyn;offshore") -# # sd_regression("SD_AnsysComp4_UniversalCableRigid" "subdyn;offshore") -# # sd_regression("SD_Rigid2Interf_Cables" "subdyn;offshore") - -# # InflowWind regression tests -# ifw_regression("ifw_turbsimff" "inflowwind") -# ifw_regression("ifw_uniform" "inflowwind") -# ifw_regression("ifw_nativeBladed" "inflowwind") -# ifw_regression("ifw_BoxExceed" "inflowwind") -# ifw_regression("ifw_BoxExceedTwr" "inflowwind") -# ifw_regression("ifw_HAWC" "inflowwind") - -# # Py-InflowWind regression tests -# py_ifw_regression("py_ifw_turbsimff" "inflowwind;python") - -# # SeaState regression tests -# seast_regression("seastate_1" "seastate") -# seast_regression("seastate_wr_kin1" "seastate") -# seast_regression("seastate_CNW1" "seastate") -# seast_regression("seastate_CNW2" "seastate") -# seast_regression("seastate_WaveMod7_WaveStMod1" "seastate") -# seast_regression("seastate_WaveMod7_WaveStMod2" "seastate") -# seast_regression("seastate_WaveMod7_WaveStMod3" "seastate") -# seast_regression("seastate_wavemod5" "seastate") # place at end since it reads outputs generated by seastate_wr_kin1 - -# # MoorDyn regression tests -# md_regression("md_5MW_OC4Semi" "moordyn") -# md_regression("md_lineFail" "moordyn") -# md_regression("md_BodiesAndRods" "moordyn") -# md_regression("md_bodyDrag" "moordyn") -# md_regression("md_cable" "moordyn") -# md_regression("md_case2" "moordyn") -# md_regression("md_case5" "moordyn") -# md_regression("md_float" "moordyn") -# md_regression("md_horizontal" "moordyn") -# md_regression("md_no_line" "moordyn") -# md_regression("md_vertical" "moordyn") -# py_md_regression("py_md_5MW_OC4Semi" "moordyn;python") -# # the following tests are excessively slow in double precision, so skip these in normal testing -# #md_regression("md_Single_Line_Quasi_Static_Test" "moordyn") +# OpenFAST regression tests +of_regression("AWT_YFix_WSt" "openfast;elastodyn;aerodyn15;servodyn") +of_regression("AWT_WSt_StartUp_HighSpShutDown" "openfast;elastodyn;aerodyn15;servodyn") +of_regression("AWT_YFree_WSt" "openfast;elastodyn;aerodyn15;servodyn") +of_regression("AWT_YFree_WTurb" "openfast;elastodyn;aerodyn15;servodyn") +of_regression("AWT_WSt_StartUpShutDown" "openfast;elastodyn;aerodyn15;servodyn") +of_regression("AOC_WSt" "openfast;elastodyn;aerodyn15;servodyn") +of_regression("AOC_YFree_WTurb" "openfast;elastodyn;aerodyn15;servodyn") +of_regression("AOC_YFix_WSt" "openfast;elastodyn;aerodyn15;servodyn") +of_regression("UAE_Dnwind_YRamp_WSt" "openfast;elastodyn;aerodyn15;servodyn") +of_regression("UAE_Upwind_Rigid_WRamp_PwrCurve" "openfast;elastodyn;aerodyn15;servodyn") +of_regression("WP_VSP_WTurb_PitchFail" "openfast;elastodyn;aerodyn15;servodyn") +of_regression("WP_VSP_ECD" "openfast;elastodyn;aerodyn15;servodyn") +of_regression("WP_VSP_WTurb" "openfast;elastodyn;aerodyn15;servodyn") +of_regression("SWRT_YFree_VS_EDG01" "openfast;elastodyn;aerodyn15;servodyn") +of_regression("SWRT_YFree_VS_EDC01" "openfast;elastodyn;aerodyn15;servodyn") +of_regression("SWRT_YFree_VS_WTurb" "openfast;elastodyn;aerodyn15;servodyn") +of_regression("5MW_Land_DLL_WTurb" "openfast;elastodyn;aerodyn15;servodyn") +of_regression("5MW_OC3Mnpl_DLL_WTurb_WavesIrr" "openfast;elastodyn;aerodyn15;servodyn;hydrodyn;subdyn;offshore") +of_regression("5MW_OC3Mnpl_DLL_WTurb_WavesIrr_Restart" "openfast;elastodyn;aerodyn15;servodyn;hydrodyn;subdyn;offshore;restart") +of_regression("5MW_OC3Trpd_DLL_WSt_WavesReg" "openfast;elastodyn;aerodyn15;servodyn;hydrodyn;subdyn;offshore") +of_regression("5MW_OC4Jckt_DLL_WTurb_WavesIrr_MGrowth" "openfast;elastodyn;aerodyn15;servodyn;hydrodyn;subdyn;offshore") +of_regression("5MW_ITIBarge_DLL_WTurb_WavesIrr" "openfast;elastodyn;aerodyn15;servodyn;hydrodyn;map;offshore") +of_regression("5MW_TLP_DLL_WTurb_WavesIrr_WavesMulti" "openfast;elastodyn;aerodyn15;servodyn;hydrodyn;map;offshore") +of_regression("5MW_OC3Spar_DLL_WTurb_WavesIrr" "openfast;elastodyn;aerodyn15;servodyn;hydrodyn;map;offshore") +of_regression("5MW_OC4Semi_WSt_WavesWN" "openfast;elastodyn;aerodyn15;servodyn;hydrodyn;moordyn;offshore") +of_regression("5MW_Land_BD_DLL_WTurb" "openfast;beamdyn;aerodyn15;servodyn") +of_regression("5MW_Land_BD_Init" "openfast;beamdyn;aerodyn15;servodyn") +of_regression("5MW_OC4Jckt_ExtPtfm" "openfast;elastodyn;extptfm") +of_regression("HelicalWake_OLAF" "openfast;aerodyn15;olaf") +of_regression("EllipticalWing_OLAF" "openfast;aerodyn15;olaf") +of_regression("StC_test_OC4Semi" "openfast;servodyn;hydrodyn;moordyn;offshore;stc") +of_regression("MHK_RM1_Fixed" "openfast;elastodyn;aerodyn15;mhk") +of_regression("MHK_RM1_Floating" "openfast;elastodyn;aerodyn15;hydrodyn;moordyn;mhk") +of_regression("Tailfin_FreeYaw1DOF_PolarBased" "openfast;elastodyn;aerodyn15") +of_regression("Tailfin_FreeYaw1DOF_Unsteady" "openfast;elastodyn;aerodyn15") + +of_aeromap_regression("5MW_Land_AeroMap" "aeromap;elastodyn;aerodyn15") + +# OpenFAST C++ API test +if(BUILD_OPENFAST_CPP_API) + of_cpp_interface_regression("5MW_Land_DLL_WTurb_cpp" "openfast;fastlib;cpp") +endif() + +# OpenFAST C++ Driver test for OpenFAST Library +# This tests the FAST Library and FAST_Library.h +if(BUILD_OPENFAST_CPP_DRIVER) + of_fastlib_regression("AWT_YFree_WSt" "fastlib;elastodyn;aerodyn15;servodyn") +endif(BUILD_OPENFAST_CPP_DRIVER) + +# OpenFAST Python API test +of_regression_py("5MW_Land_DLL_WTurb_py" "openfast;fastlib;python;elastodyn;aerodyn15;servodyn") +of_regression_py("5MW_ITIBarge_DLL_WTurb_WavesIrr_py" "openfast;fastlib;python;elastodyn;aerodyn15;servodyn;hydrodyn;map;offshore") +of_regression_py("5MW_TLP_DLL_WTurb_WavesIrr_WavesMulti_py" "openfast;fastlib;python;elastodyn;aerodyn15;servodyn;hydrodyn;map;offshore") +of_regression_py("5MW_OC3Spar_DLL_WTurb_WavesIrr_py" "openfast;fastlib;python;elastodyn;aerodyn15;servodyn;hydrodyn;map;offshore") +of_regression_py("5MW_OC4Semi_WSt_WavesWN_py" "openfast;fastlib;python;elastodyn;aerodyn15;servodyn;hydrodyn;moordyn;offshore") +of_regression_py("5MW_Land_BD_DLL_WTurb_py" "openfast;fastlib;python;beamdyn;aerodyn15;servodyn") +of_regression_py("HelicalWake_OLAF_py" "openfast;fastlib;python;aerodyn15;olaf") +of_regression_py("EllipticalWing_OLAF_py" "openfast;fastlib;python;aerodyn15;olaf") + +# AeroAcoustic regression test +of_regression_aeroacoustic("IEA_LB_RWT-AeroAcoustics" "openfast;aerodyn15;aeroacoustics") + +# Linearized OpenFAST regression tests +of_regression_linear("Fake5MW_AeroLin_B1_UA4_DBEMT3" "-highpass=0.05" "openfast;linear;elastodyn;aerodyn") +of_regression_linear("Fake5MW_AeroLin_B3_UA6" "-highpass=0.05" "openfast;linear;elastodyn;aerodyn") +of_regression_linear("WP_Stationary_Linear" "" "openfast;linear;elastodyn") +of_regression_linear("Ideal_Beam_Fixed_Free_Linear" "-highpass=0.10" "openfast;linear;beamdyn") +of_regression_linear("Ideal_Beam_Free_Free_Linear" "-highpass=0.10" "openfast;linear;beamdyn") +of_regression_linear("5MW_Land_Linear_Aero" "-highpass=0.25" "openfast;linear;elastodyn;servodyn;aerodyn") +of_regression_linear("5MW_Land_Linear_Aero_CalcSteady" "-highpass=0.25" "openfast;linear;elastodyn;servodyn;aerodyn") +of_regression_linear("5MW_Land_BD_Linear" "" "openfast;linear;beamdyn;servodyn") +of_regression_linear("5MW_Land_BD_Linear_Aero" "-highpass=0.25" "openfast;linear;beamdyn;servodyn;aerodyn") +of_regression_linear("5MW_OC4Semi_Linear" "" "openfast;linear;hydrodyn;servodyn;map") +of_regression_linear("5MW_OC4Semi_MD_Linear" "" "openfast;linear;hydrodyn;servodyn;moordyn") +of_regression_linear("StC_test_OC4Semi_Linear_Nac" "" "openfast;linear;servodyn;stc") +of_regression_linear("StC_test_OC4Semi_Linear_Tow" "" "openfast;linear;servodyn;stc") +of_regression_linear("WP_Stationary_Linear" "" "openfast;linear;elastodyn") +of_regression_linear("5MW_OC3Spar_Linear" "" "openfast;linear;map;hydrodyn") +of_regression_linear("5MW_OC3Mnpl_Linear" "" "openfast;linear;hydrodyn;servodyn;moordyn") + +# FAST Farm regression tests +if(BUILD_FASTFARM) + ff_regression("TSinflow" "fastfarm") + ff_regression("LESinflow" "fastfarm") +# ff_regression("Uninflow_curl" "fastfarm") + ff_regression("TSinflow_curl" "fastfarm") + ff_regression("ModAmb_3" "fastfarm") +endif() + +# AeroDyn regression tests +ad_regression("ad_timeseries_shutdown" "aerodyn;bem") +ad_regression("ad_EllipticalWingInf_OLAF" "aerodyn;bem") +ad_regression("ad_HelicalWakeInf_OLAF" "aerodyn;bem") +ad_regression("ad_Kite_OLAF" "aerodyn;bem") +ad_regression("ad_MultipleHAWT" "aerodyn;bem") +ad_regression("ad_QuadRotor_OLAF" "aerodyn;bem") +ad_regression("ad_VerticalAxis_OLAF" "aerodyn;bem") +ad_regression("ad_MHK_RM1_Fixed" "aerodyn;bem;mhk") +ad_regression("ad_MHK_RM1_Floating" "aerodyn;bem;mhk") +ad_regression("ad_BAR_CombinedCases" "aerodyn;bem") # NOTE: doing BAR at the end to avoid copy errors +ad_regression("ad_BAR_OLAF" "aerodyn;bem") +ad_regression("ad_BAR_SineMotion" "aerodyn;bem") +ad_regression("ad_BAR_SineMotion_UA4_DBEMT3" "aerodyn;bem") +ad_regression("ad_BAR_RNAMotion" "aerodyn;bem") +ad_regression("ad_B1n2_OLAF" "aerodyn;OLAF") +py_ad_regression("py_ad_5MW_OC4Semi_WSt_WavesWN" "aerodyn;bem;python") +py_ad_regression("py_ad_B1n2_OLAF" "aerodyn;OLAF;python") + +# UnsteadyAero +ua_regression("ua_redfreq" "unsteadyaero") + +# BeamDyn regression tests +bd_regression("bd_5MW_dynamic" "beamdyn;dynamic") +bd_regression("bd_5MW_dynamic_gravity_Az00" "beamdyn;dynamic") +bd_regression("bd_5MW_dynamic_gravity_Az90" "beamdyn;dynamic") +bd_regression("bd_curved_beam" "beamdyn;static") +bd_regression("bd_isotropic_rollup" "beamdyn;static") +bd_regression("bd_static_cantilever_beam" "beamdyn;static") +bd_regression("bd_static_twisted_with_k1" "beamdyn;static") + +# HydroDyn regression tests +hd_regression("hd_5MW_ITIBarge_DLL_WTurb_WavesIrr" "hydrodyn;offshore") +hd_regression("hd_5MW_OC3Spar_DLL_WTurb_WavesIrr" "hydrodyn;offshore") +hd_regression("hd_5MW_OC4Semi_WSt_WavesWN" "hydrodyn;offshore") +hd_regression("hd_5MW_TLP_DLL_WTurb_WavesIrr_WavesMulti" "hydrodyn;offshore") +hd_regression("hd_TaperCylinderPitchMoment" "hydrodyn;offshore") +hd_regression("hd_NBodyMod1" "hydrodyn;offshore") +hd_regression("hd_NBodyMod2" "hydrodyn;offshore") +hd_regression("hd_NBodyMod3" "hydrodyn;offshore") +hd_regression("hd_WaveStMod1" "hydrodyn;offshore") +hd_regression("hd_WaveStMod2" "hydrodyn;offshore") +hd_regression("hd_WaveStMod3" "hydrodyn;offshore") +hd_regression("hd_MHstLMod2" "hydrodyn;offshore") +hd_regression("hd_MHstLMod1_compare" "hydrodyn;offshore") +hd_regression("hd_MHstLMod2_compare" "hydrodyn;offshore") +hd_regression("hd_MCF_WaveStMod0" "hydrodyn;offshore") +hd_regression("hd_MCF_WaveStMod1" "hydrodyn;offshore") +hd_regression("hd_MCF_WaveStMod2" "hydrodyn;offshore") +hd_regression("hd_MCF_WaveStMod3" "hydrodyn;offshore") +hd_regression("hd_ExctnMod1_ExctnDisp1" "hydrodyn;offshore") +hd_regression("hd_ExctnMod1_ExctnDisp2" "hydrodyn;offshore") + +# Py-HydroDyn regression tests +py_hd_regression("py_hd_5MW_OC4Semi_WSt_WavesWN" "hydrodyn;offshore;python") + +# SubDyn regression tests +sd_regression("SD_Cable_5Joints" "subdyn;offshore") +sd_regression("SD_PendulumDamp" "subdyn;offshore") +sd_regression("SD_Rigid" "subdyn;offshore") +sd_regression("SD_SparHanging" "subdyn;offshore") +sd_regression("SD_AnsysComp1_PinBeam" "subdyn;offshore") # TODO Issue #855 +sd_regression("SD_AnsysComp2_Cable" "subdyn;offshore") +sd_regression("SD_AnsysComp3_PinBeamCable" "subdyn;offshore") # TODO Issue #855 +sd_regression("SD_Spring_Case1" "subdyn;offshore") +sd_regression("SD_Spring_Case2" "subdyn;offshore") +sd_regression("SD_Spring_Case3" "subdyn;offshore") +sd_regression("SD_Revolute_Joint" "subdyn;offshore") +sd_regression("SD_2Beam_Spring" "subdyn;offshore") +sd_regression("SD_2Beam_Cantilever" "subdyn;offshore") +# TODO test below are bugs, should be added when fixed +# sd_regression("SD_Force" "subdyn;offshore") +# sd_regression("SD_AnsysComp4_UniversalCableRigid" "subdyn;offshore") +# sd_regression("SD_Rigid2Interf_Cables" "subdyn;offshore") + +# InflowWind regression tests +ifw_regression("ifw_turbsimff" "inflowwind") +ifw_regression("ifw_uniform" "inflowwind") +ifw_regression("ifw_nativeBladed" "inflowwind") +ifw_regression("ifw_BoxExceed" "inflowwind") +ifw_regression("ifw_BoxExceedTwr" "inflowwind") +ifw_regression("ifw_HAWC" "inflowwind") + +# Py-InflowWind regression tests +py_ifw_regression("py_ifw_turbsimff" "inflowwind;python") + +# SeaState regression tests +seast_regression("seastate_1" "seastate") +seast_regression("seastate_wr_kin1" "seastate") +seast_regression("seastate_CNW1" "seastate") +seast_regression("seastate_CNW2" "seastate") +seast_regression("seastate_WaveMod7_WaveStMod1" "seastate") +seast_regression("seastate_WaveMod7_WaveStMod2" "seastate") +seast_regression("seastate_WaveMod7_WaveStMod3" "seastate") +seast_regression("seastate_wavemod5" "seastate") # place at end since it reads outputs generated by seastate_wr_kin1 + +# MoorDyn regression tests +md_regression("md_5MW_OC4Semi" "moordyn") +md_regression("md_lineFail" "moordyn") +md_regression("md_BodiesAndRods" "moordyn") +md_regression("md_bodyDrag" "moordyn") +md_regression("md_cable" "moordyn") +md_regression("md_case2" "moordyn") +md_regression("md_case5" "moordyn") +md_regression("md_float" "moordyn") +md_regression("md_horizontal" "moordyn") +md_regression("md_no_line" "moordyn") +md_regression("md_vertical" "moordyn") +py_md_regression("py_md_5MW_OC4Semi" "moordyn;python") +# the following tests are excessively slow in double precision, so skip these in normal testing +#md_regression("md_Single_Line_Quasi_Static_Test" "moordyn") # OpenFAST IO Library regression tests -py_openfast_io_library_pytest("openfast_io_library" "openfast_io;python") \ No newline at end of file +py_openfast_io_library_pytest("openfast_io_library" "openfast;openfast_io;python") \ No newline at end of file From 0ef25bc566456caeb324cc411a2df63733602802 Mon Sep 17 00:00:00 2001 From: Mayank Chetan Date: Fri, 23 Aug 2024 23:44:02 +0000 Subject: [PATCH 030/161] adding openfast_io GH Actions --- .github/workflows/automated-dev-tests.yml | 43 +++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/.github/workflows/automated-dev-tests.yml b/.github/workflows/automated-dev-tests.yml index 6f9958f13..46884aedd 100644 --- a/.github/workflows/automated-dev-tests.yml +++ b/.github/workflows/automated-dev-tests.yml @@ -600,6 +600,49 @@ jobs: !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/UAE_VI !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/WP_Baseline + rtest-openfast_io: + runs-on: ubuntu-22.04 + needs: build-openfast-release + steps: + - name: Cache the workspace + uses: actions/cache@v4 + with: + path: ${{runner.workspace}} + key: build-openfast-release-${{ github.sha }} + - name: Setup Python + uses: actions/setup-python@v5 + with: + python-version: '3.11' + - name: Install dependencies + run: | + pip install -r requirements.txt + sudo apt-get update -y + sudo apt-get install -y libopenblas-dev libopenblas-openmp-dev + sudo apt-get install -y libhdf5-dev libnetcdf-dev libopenmpi-dev libyaml-cpp-dev + - name: Configure Tests + working-directory: ${{runner.workspace}}/openfast/build + run: | + cmake \ + -DPython_ROOT_DIR:STRING=${{env.pythonLocation}} \ + -DBUILD_TESTING:BOOL=ON \ + -DCTEST_PLOT_ERRORS:BOOL=ON \ + ${GITHUB_WORKSPACE} + cmake --build . --target regression_test_controllers + - name: Run openfast_io tests + working-directory: ${{runner.workspace}}/openfast/build + run: | + ctest -VV -j4 \ + -L openfast_io \ + -LE "cpp|linear|python|fastlib|aeromap" \ + -E "5MW_OC4Semi_WSt_WavesWN|5MW_OC3Mnpl_DLL_WTurb_WavesIrr|5MW_OC4Jckt_DLL_WTurb_WavesIrr_MGrowth|5MW_OC3Trpd_DLL_WSt_WavesReg|5MW_Land_BD_DLL_WTurb" + - name: Failing test artifacts + uses: actions/upload-artifact@v4 + if: failure() + with: + name: rtest-OF + path: | + ${{runner.workspace}}/openfast/build/reg_tests/openfast_io + rtest-OF-simulink: runs-on: ubuntu-22.04 From 9a44fa826d89d1cb98202d202a89e9dccf90f917 Mon Sep 17 00:00:00 2001 From: Mayank Chetan Date: Sat, 24 Aug 2024 04:57:06 +0000 Subject: [PATCH 031/161] working GH A --- .github/workflows/automated-dev-tests.yml | 4 +--- openfast_io/openfast_io/tests/test_of_io_pytest.py | 7 +++++-- reg_tests/CTestList.cmake | 1 + 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/.github/workflows/automated-dev-tests.yml b/.github/workflows/automated-dev-tests.yml index 46884aedd..aa373df20 100644 --- a/.github/workflows/automated-dev-tests.yml +++ b/.github/workflows/automated-dev-tests.yml @@ -632,9 +632,7 @@ jobs: working-directory: ${{runner.workspace}}/openfast/build run: | ctest -VV -j4 \ - -L openfast_io \ - -LE "cpp|linear|python|fastlib|aeromap" \ - -E "5MW_OC4Semi_WSt_WavesWN|5MW_OC3Mnpl_DLL_WTurb_WavesIrr|5MW_OC4Jckt_DLL_WTurb_WavesIrr_MGrowth|5MW_OC3Trpd_DLL_WSt_WavesReg|5MW_Land_BD_DLL_WTurb" + -L openfast_io - name: Failing test artifacts uses: actions/upload-artifact@v4 if: failure() diff --git a/openfast_io/openfast_io/tests/test_of_io_pytest.py b/openfast_io/openfast_io/tests/test_of_io_pytest.py index 7dbf0e6cd..8f2eae318 100644 --- a/openfast_io/openfast_io/tests/test_of_io_pytest.py +++ b/openfast_io/openfast_io/tests/test_of_io_pytest.py @@ -12,7 +12,6 @@ from conftest import REPOSITORY_ROOT, BUILD_DIR, OF_PATH -Path(BUILD_DIR).mkdir(parents=True, exist_ok=True) # Exercising the various OpenFAST modules @@ -57,6 +56,10 @@ def read_action(folder, path_dict = getPaths()): def write_action(folder, fst_vt, path_dict = getPaths()): print(f"Writing to {folder}, with TMax = 2.0") + # check if the folder exists, if not, mostly being called not from cmake, so create it + if not osp.exists(osp.join(path_dict['build_dir'])): + Path(path_dict['build_dir']).mkdir(parents=True, exist_ok=True) + fast_writer = InputWriter_OpenFAST() fast_writer.FAST_runDirectory = osp.join(path_dict['build_dir'],folder) Path(fast_writer.FAST_runDirectory).mkdir(parents=True, exist_ok=True) @@ -111,7 +114,7 @@ def test_openfast_executable_exists(request): # Parameterize the test function to run for each folder and action @pytest.mark.parametrize("folder", FOLDERS_TO_RUN) # @pytest.mark.parametrize("action_name, action_func", actions) -def test_openfast_io_with_detailed_reporting(folder, request): +def test_openfast_io_read_write_run_outRead(folder, request): path_dict = getPaths(OF_PATH=osp.join(request.config.getoption("--executable")), REPOSITORY_ROOT=osp.join(request.config.getoption("--source_dir")), diff --git a/reg_tests/CTestList.cmake b/reg_tests/CTestList.cmake index 1d321848b..27e87c351 100644 --- a/reg_tests/CTestList.cmake +++ b/reg_tests/CTestList.cmake @@ -284,6 +284,7 @@ function(py_openfast_io_library_pytest TESTNAME LABEL) set(source_dir "--source_dir=${CMAKE_CURRENT_LIST_DIR}/..") set(build_dir "--build_dir=${CTEST_BINARY_DIR}/openfast_io/") add_test(${TESTNAME} ${Python_EXECUTABLE} ${module} ${pytest} ${pytestVerbose} ${py_test_file} ${executable} ${source_dir} ${build_dir}) + set_tests_properties(${TESTNAME} PROPERTIES TIMEOUT 5400 WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" LABELS "${LABEL}") endfunction(py_openfast_io_library_pytest) From 852471b5ecf8ac5d973c3624bb2940c8b11b0a24 Mon Sep 17 00:00:00 2001 From: Mayank Chetan Date: Sat, 24 Aug 2024 05:15:30 +0000 Subject: [PATCH 032/161] Install the openfast_io library in GH Action --- .github/workflows/automated-dev-tests.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/automated-dev-tests.yml b/.github/workflows/automated-dev-tests.yml index aa373df20..ec280481d 100644 --- a/.github/workflows/automated-dev-tests.yml +++ b/.github/workflows/automated-dev-tests.yml @@ -619,6 +619,10 @@ jobs: sudo apt-get update -y sudo apt-get install -y libopenblas-dev libopenblas-openmp-dev sudo apt-get install -y libhdf5-dev libnetcdf-dev libopenmpi-dev libyaml-cpp-dev + - name: Install openfast_io + working-directory: ${{runner.workspace}}/openfast_io + run: | + pip install -e . - name: Configure Tests working-directory: ${{runner.workspace}}/openfast/build run: | From f3136d9467437a630c43a2c8559f8dc89b826d15 Mon Sep 17 00:00:00 2001 From: Mayank Chetan Date: Sat, 24 Aug 2024 05:32:34 +0000 Subject: [PATCH 033/161] correcting path to openfast_io from runner workspace --- .github/workflows/automated-dev-tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/automated-dev-tests.yml b/.github/workflows/automated-dev-tests.yml index ec280481d..116f5233e 100644 --- a/.github/workflows/automated-dev-tests.yml +++ b/.github/workflows/automated-dev-tests.yml @@ -620,7 +620,7 @@ jobs: sudo apt-get install -y libopenblas-dev libopenblas-openmp-dev sudo apt-get install -y libhdf5-dev libnetcdf-dev libopenmpi-dev libyaml-cpp-dev - name: Install openfast_io - working-directory: ${{runner.workspace}}/openfast_io + working-directory: ${{runner.workspace}}/openfast/openfast_io run: | pip install -e . - name: Configure Tests From 19501cc9067c46537ccecc4079677c1d0f8b404d Mon Sep 17 00:00:00 2001 From: Mayank Chetan Date: Sat, 24 Aug 2024 14:46:51 +0000 Subject: [PATCH 034/161] add log file --- openfast_io/openfast_io/tests/test_of_io_pytest.py | 1 + 1 file changed, 1 insertion(+) diff --git a/openfast_io/openfast_io/tests/test_of_io_pytest.py b/openfast_io/openfast_io/tests/test_of_io_pytest.py index 8f2eae318..ee2ca1842 100644 --- a/openfast_io/openfast_io/tests/test_of_io_pytest.py +++ b/openfast_io/openfast_io/tests/test_of_io_pytest.py @@ -75,6 +75,7 @@ def write_action(folder, fst_vt, path_dict = getPaths()): def run_action(folder, path_dict = getPaths()): # Placeholder for the actual run action print(f"Running simulation for {folder}") + command = [path_dict['executable'], str(osp.join(path_dict['build_dir'], folder, f"{folder}.fst")), f"> {folder}.log"] subprocess.run([path_dict['executable'], str(osp.join(path_dict['build_dir'], folder, f"{folder}.fst"))], check=True) def check_ascii_out(folder, path_dict = getPaths()): From 53147f4a1fcd3cbb6b3f562cc50354f16fd3b461 Mon Sep 17 00:00:00 2001 From: Mayank Chetan Date: Sat, 24 Aug 2024 22:05:31 +0000 Subject: [PATCH 035/161] adding log files to openfast_io pytest --- openfast_io/openfast_io/tests/test_of_io_pytest.py | 6 ++++-- reg_tests/CMakeLists.txt | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/openfast_io/openfast_io/tests/test_of_io_pytest.py b/openfast_io/openfast_io/tests/test_of_io_pytest.py index ee2ca1842..01b987782 100644 --- a/openfast_io/openfast_io/tests/test_of_io_pytest.py +++ b/openfast_io/openfast_io/tests/test_of_io_pytest.py @@ -75,8 +75,10 @@ def write_action(folder, fst_vt, path_dict = getPaths()): def run_action(folder, path_dict = getPaths()): # Placeholder for the actual run action print(f"Running simulation for {folder}") - command = [path_dict['executable'], str(osp.join(path_dict['build_dir'], folder, f"{folder}.fst")), f"> {folder}.log"] - subprocess.run([path_dict['executable'], str(osp.join(path_dict['build_dir'], folder, f"{folder}.fst"))], check=True) + command = [f"{path_dict['executable']}", f"{osp.join(path_dict['build_dir'], folder, f'{folder}.fst')}"] + with open(osp.join(path_dict['build_dir'], folder, f'{folder}.log'), 'w') as f: + subprocess.run(command, check=True, stdout=f, stderr=subprocess.STDOUT) + f.close() def check_ascii_out(folder, path_dict = getPaths()): # Placeholder for the actual check action diff --git a/reg_tests/CMakeLists.txt b/reg_tests/CMakeLists.txt index cf01f37be..92afa0336 100644 --- a/reg_tests/CMakeLists.txt +++ b/reg_tests/CMakeLists.txt @@ -84,7 +84,7 @@ add_subdirectory("${CMAKE_CURRENT_LIST_DIR}/r-test") # build and seed the test directories with the data they need to run the tests file(MAKE_DIRECTORY ${CTEST_BINARY_DIR}) -foreach(regTest glue-codes/openfast glue-codes/openfast-cpp modules/aerodyn modules/beamdyn modules/hydrodyn modules/inflowwind modules/moordyn modules/subdyn openfastio) +foreach(regTest glue-codes/openfast glue-codes/openfast-cpp modules/aerodyn modules/beamdyn modules/hydrodyn modules/inflowwind modules/moordyn modules/subdyn openfast_io) file(MAKE_DIRECTORY ${CTEST_BINARY_DIR}/${regTest}) endforeach() From bd8fef25fb333bff31e710f786de9beadd773d2d Mon Sep 17 00:00:00 2001 From: Mayank Chetan Date: Sat, 24 Aug 2024 23:53:20 +0000 Subject: [PATCH 036/161] lets get dll location --- .github/workflows/automated-dev-tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/automated-dev-tests.yml b/.github/workflows/automated-dev-tests.yml index 116f5233e..9667b5091 100644 --- a/.github/workflows/automated-dev-tests.yml +++ b/.github/workflows/automated-dev-tests.yml @@ -587,7 +587,7 @@ jobs: -E "5MW_OC4Semi_WSt_WavesWN|5MW_OC3Mnpl_DLL_WTurb_WavesIrr|5MW_OC4Jckt_DLL_WTurb_WavesIrr_MGrowth|5MW_OC3Trpd_DLL_WSt_WavesReg|5MW_Land_BD_DLL_WTurb" - name: Failing test artifacts uses: actions/upload-artifact@v4 - if: failure() + # if: failure() with: name: rtest-OF path: | From 36d43d3e62fa1015e07ef301d14279c44d367eab Mon Sep 17 00:00:00 2001 From: Mayank Chetan Date: Sun, 25 Aug 2024 01:39:07 +0000 Subject: [PATCH 037/161] artifact name conflict --- .github/workflows/automated-dev-tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/automated-dev-tests.yml b/.github/workflows/automated-dev-tests.yml index 9667b5091..837c3a91f 100644 --- a/.github/workflows/automated-dev-tests.yml +++ b/.github/workflows/automated-dev-tests.yml @@ -641,7 +641,7 @@ jobs: uses: actions/upload-artifact@v4 if: failure() with: - name: rtest-OF + name: rtest-openfast_io path: | ${{runner.workspace}}/openfast/build/reg_tests/openfast_io From 721b529fb4960b7d5c425b0e75fe63d548fdaf29 Mon Sep 17 00:00:00 2001 From: Mayank Chetan Date: Mon, 26 Aug 2024 18:19:54 +0000 Subject: [PATCH 038/161] fixed DLL paths in all three test approaches --- openfast_io/openfast_io/tests/conftest.py | 2 +- .../openfast_io/tests/test_of_io_pytest.py | 36 ++++++++++++++----- reg_tests/CTestList.cmake | 4 +-- 3 files changed, 31 insertions(+), 11 deletions(-) diff --git a/openfast_io/openfast_io/tests/conftest.py b/openfast_io/openfast_io/tests/conftest.py index 3d3fcc03b..f4421a851 100644 --- a/openfast_io/openfast_io/tests/conftest.py +++ b/openfast_io/openfast_io/tests/conftest.py @@ -12,7 +12,7 @@ raise ValueError('Unknown platform type: '+mactype) REPOSITORY_ROOT = osp.dirname(osp.dirname(osp.dirname(osp.dirname(__file__)))) -BUILD_DIR = osp.join(REPOSITORY_ROOT, "build_ofio", "testSuite") +BUILD_DIR = osp.join(REPOSITORY_ROOT, "build/reg_tests") # Path to the OpenFAST executable OF_PATH = osp.join(REPOSITORY_ROOT,"build/glue-codes/openfast",f"openfast{exeExt}") diff --git a/openfast_io/openfast_io/tests/test_of_io_pytest.py b/openfast_io/openfast_io/tests/test_of_io_pytest.py index 01b987782..e8b21565f 100644 --- a/openfast_io/openfast_io/tests/test_of_io_pytest.py +++ b/openfast_io/openfast_io/tests/test_of_io_pytest.py @@ -37,9 +37,10 @@ def getPaths(OF_PATH = OF_PATH, REPOSITORY_ROOT = REPOSITORY_ROOT, BUILD_DIR = B return { "executable": OF_PATH, "source_dir": REPOSITORY_ROOT, - "build_dir": BUILD_DIR, + "build_dir": BUILD_DIR, # Location of the reg_tests directory inside the build directory created by the user "rtest_dir": osp.join(REPOSITORY_ROOT, "reg_tests", "r-test"), - "test_data_dir": osp.join(REPOSITORY_ROOT, "reg_tests", "r-test", "glue-codes", "openfast") + "test_data_dir": osp.join(REPOSITORY_ROOT, "reg_tests", "r-test", "glue-codes", "openfast"), + "discon_dir": osp.join(BUILD_DIR, "glue-codes", "openfast", "5MW_Baseline", "ServoData"), } def read_action(folder, path_dict = getPaths()): @@ -57,11 +58,11 @@ def write_action(folder, fst_vt, path_dict = getPaths()): print(f"Writing to {folder}, with TMax = 2.0") # check if the folder exists, if not, mostly being called not from cmake, so create it - if not osp.exists(osp.join(path_dict['build_dir'])): + if not osp.exists(osp.join(path_dict['build_dir'],'openfast_io')): Path(path_dict['build_dir']).mkdir(parents=True, exist_ok=True) fast_writer = InputWriter_OpenFAST() - fast_writer.FAST_runDirectory = osp.join(path_dict['build_dir'],folder) + fast_writer.FAST_runDirectory = osp.join(path_dict['build_dir'],'openfast_io',folder) Path(fast_writer.FAST_runDirectory).mkdir(parents=True, exist_ok=True) fast_writer.FAST_namingOut = folder @@ -69,27 +70,31 @@ def write_action(folder, fst_vt, path_dict = getPaths()): fst_vt = {} fst_vt['Fst', 'TMax'] = 2. fst_vt['Fst','OutFileFmt'] = 3 + # check if the case needs ServoDyn + if 'DLL_FileName' in fast_writer.fst_vt['ServoDyn']: + # Copy the DISCON name and add the path to the build location + fst_vt['ServoDyn', 'DLL_FileName'] = osp.join(path_dict['discon_dir'], osp.basename(fast_writer.fst_vt['ServoDyn']['DLL_FileName'])) fast_writer.update(fst_update=fst_vt) fast_writer.execute() def run_action(folder, path_dict = getPaths()): # Placeholder for the actual run action print(f"Running simulation for {folder}") - command = [f"{path_dict['executable']}", f"{osp.join(path_dict['build_dir'], folder, f'{folder}.fst')}"] - with open(osp.join(path_dict['build_dir'], folder, f'{folder}.log'), 'w') as f: + command = [f"{path_dict['executable']}", f"{osp.join(path_dict['build_dir'],'openfast_io', folder, f'{folder}.fst')}"] + with open(osp.join(path_dict['build_dir'],'openfast_io', folder, f'{folder}.log'), 'w') as f: subprocess.run(command, check=True, stdout=f, stderr=subprocess.STDOUT) f.close() def check_ascii_out(folder, path_dict = getPaths()): # Placeholder for the actual check action print(f"Checking ASCII output for {folder}") - asciiOutput = osp.join(path_dict['build_dir'], folder, f"{folder}.out") + asciiOutput = osp.join(path_dict['build_dir'],'openfast_io', folder, f"{folder}.out") fast_outout = FASTOutputFile(filename=asciiOutput) def check_binary_out(folder, path_dict = getPaths()): # Placeholder for the actual check action print(f"Checking binary output for {folder}") - binaryOutput = osp.join(path_dict['build_dir'], folder, f"{folder}.outb") + binaryOutput = osp.join(path_dict['build_dir'],'openfast_io', folder, f"{folder}.outb") fast_outout = FASTOutputFile(filename=binaryOutput) # Begining of the test @@ -104,6 +109,18 @@ def test_rtest_cloned(request): print("R-tests not cloned properly") sys.exit(1) +def test_DLLs_exist(request): + + path_dict = getPaths(OF_PATH=osp.join(request.config.getoption("--build_dir"))) + + # Check if the DISCON.dll file exists + DISCON_DLL = osp.join(path_dict['discon_dir'], "DISCON.dll") + if osp.exists(DISCON_DLL): + assert True, f"DISCON.dll found at {DISCON_DLL}" + else: # stop the test if the DISCON.dll is not found + print(f"DISCON.dll not found at {DISCON_DLL}. Please build with ''' make regression_test_controllers ''' and try again.") + sys.exit(1) + def test_openfast_executable_exists(request): path_dict = getPaths(OF_PATH=osp.join(request.config.getoption("--executable"))) @@ -114,6 +131,8 @@ def test_openfast_executable_exists(request): print(f"OpenFAST executable not found at {path_dict['executable']}. Please build OpenFAST and try again.") sys.exit(1) + + # Parameterize the test function to run for each folder and action @pytest.mark.parametrize("folder", FOLDERS_TO_RUN) # @pytest.mark.parametrize("action_name, action_func", actions) @@ -148,6 +167,7 @@ def main(): # Initialize any necessary setup here for folder in FOLDERS_TO_RUN: + print(" ") print(f"Processing folder: {folder}") # Assuming read_action, write_action, run_action, and check_action are defined elsewhere diff --git a/reg_tests/CTestList.cmake b/reg_tests/CTestList.cmake index 27e87c351..ff22f4d68 100644 --- a/reg_tests/CTestList.cmake +++ b/reg_tests/CTestList.cmake @@ -282,7 +282,7 @@ function(py_openfast_io_library_pytest TESTNAME LABEL) set(py_test_file "${CMAKE_CURRENT_LIST_DIR}/../openfast_io/openfast_io/tests/test_of_io_pytest.py") set(executable "--executable=${CTEST_OPENFAST_EXECUTABLE}") set(source_dir "--source_dir=${CMAKE_CURRENT_LIST_DIR}/..") - set(build_dir "--build_dir=${CTEST_BINARY_DIR}/openfast_io/") + set(build_dir "--build_dir=${CTEST_BINARY_DIR}") add_test(${TESTNAME} ${Python_EXECUTABLE} ${module} ${pytest} ${pytestVerbose} ${py_test_file} ${executable} ${source_dir} ${build_dir}) set_tests_properties(${TESTNAME} PROPERTIES TIMEOUT 5400 WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" LABELS "${LABEL}") endfunction(py_openfast_io_library_pytest) @@ -495,4 +495,4 @@ py_md_regression("py_md_5MW_OC4Semi" "moordyn;python") #md_regression("md_Single_Line_Quasi_Static_Test" "moordyn") # OpenFAST IO Library regression tests -py_openfast_io_library_pytest("openfast_io_library" "openfast;openfast_io;python") \ No newline at end of file +py_openfast_io_library_pytest("openfast_io_library" "openfast_io;python") \ No newline at end of file From 7086f900ee1887f0f32607c4d86c4568896e2849 Mon Sep 17 00:00:00 2001 From: Mayank Chetan Date: Mon, 26 Aug 2024 19:10:08 +0000 Subject: [PATCH 039/161] commenting out furl --- openfast_io/openfast_io/tests/test_of_io_pytest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openfast_io/openfast_io/tests/test_of_io_pytest.py b/openfast_io/openfast_io/tests/test_of_io_pytest.py index e8b21565f..90dd5dd90 100644 --- a/openfast_io/openfast_io/tests/test_of_io_pytest.py +++ b/openfast_io/openfast_io/tests/test_of_io_pytest.py @@ -27,7 +27,7 @@ "StC_test_OC4Semi" , # "openfast;servodyn;hydrodyn;moordyn;offshore;stc") "MHK_RM1_Fixed" , # "openfast;elastodyn;aerodyn15;mhk") "MHK_RM1_Floating" , # "openfast;elastodyn;aerodyn15;hydrodyn;moordyn;mhk") - "Tailfin_FreeYaw1DOF_PolarBased" , # "openfast;elastodyn;aerodyn15") + # "Tailfin_FreeYaw1DOF_PolarBased" , # "openfast;elastodyn;aerodyn15") # lets wait for furl to be included in fst_vt ] From ac925e99ec2d6753139dc72c8e8fa7124de82f9b Mon Sep 17 00:00:00 2001 From: Mayank Chetan Date: Mon, 26 Aug 2024 19:35:54 +0000 Subject: [PATCH 040/161] remove openfast_io from rtest-interfaces --- .github/workflows/automated-dev-tests.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/automated-dev-tests.yml b/.github/workflows/automated-dev-tests.yml index 837c3a91f..5c8579f65 100644 --- a/.github/workflows/automated-dev-tests.yml +++ b/.github/workflows/automated-dev-tests.yml @@ -534,7 +534,8 @@ jobs: - name: Run Interface / API tests working-directory: ${{runner.workspace}}/openfast/build run: | - ctest -VV -L "cpp|python|fastlib" + ctest -VV -L "cpp|python|fastlib" \ + -LE "openfast_io" - name: Failing test artifacts uses: actions/upload-artifact@v4 if: failure() From 692ddb2ea1b8dc658c0506d4024670bf71f5a2c2 Mon Sep 17 00:00:00 2001 From: Mayank Chetan Date: Mon, 26 Aug 2024 20:08:29 +0000 Subject: [PATCH 041/161] revert artifacts being saved --- .github/workflows/automated-dev-tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/automated-dev-tests.yml b/.github/workflows/automated-dev-tests.yml index 5c8579f65..a84037a4e 100644 --- a/.github/workflows/automated-dev-tests.yml +++ b/.github/workflows/automated-dev-tests.yml @@ -588,7 +588,7 @@ jobs: -E "5MW_OC4Semi_WSt_WavesWN|5MW_OC3Mnpl_DLL_WTurb_WavesIrr|5MW_OC4Jckt_DLL_WTurb_WavesIrr_MGrowth|5MW_OC3Trpd_DLL_WSt_WavesReg|5MW_Land_BD_DLL_WTurb" - name: Failing test artifacts uses: actions/upload-artifact@v4 - # if: failure() + if: failure() with: name: rtest-OF path: | From d0ef089c16c28782e9287d862f73f3c073444783 Mon Sep 17 00:00:00 2001 From: Mayank Chetan Date: Mon, 26 Aug 2024 20:59:57 +0000 Subject: [PATCH 042/161] updating warning wrt OLAF and UA use --- openfast_io/openfast_io/FAST_writer.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openfast_io/openfast_io/FAST_writer.py b/openfast_io/openfast_io/FAST_writer.py index 8144b74ab..859818457 100644 --- a/openfast_io/openfast_io/FAST_writer.py +++ b/openfast_io/openfast_io/FAST_writer.py @@ -786,8 +786,8 @@ def write_AeroDyn15(self): self.write_AeroDyn15Coord() if self.fst_vt['AeroDyn15']['Wake_Mod'] == 3: - if self.fst_vt['AeroDyn15']['UA_Mod'] == 2: - raise Exception('OLAF is called with unsteady airfoil aerodynamics, but OLAF currently only supports UA_Mod == 1') #TODO: need to check if this holds true now + if self.fst_vt['AeroDyn15']['UA_Mod'] > 0: + raise Exception('OLAF is called with unsteady airfoil aerodynamics, but OLAF currently only supports UA_Mod == 0') #TODO: need to check if this holds true now self.write_OLAF() # Generate AeroDyn v15.03 input file From 98b751107889e9d68979eb841ee9c0a35bbf71f9 Mon Sep 17 00:00:00 2001 From: Mayank Chetan Date: Tue, 27 Aug 2024 04:32:39 +0000 Subject: [PATCH 043/161] API updates without ADsk & SED --- openfast_io/openfast_io/FAST_reader.py | 41 +++++++++++-- openfast_io/openfast_io/FAST_writer.py | 80 +++++++++++++++----------- 2 files changed, 83 insertions(+), 38 deletions(-) diff --git a/openfast_io/openfast_io/FAST_reader.py b/openfast_io/openfast_io/FAST_reader.py index 13e155b3d..bd8b1bcc0 100644 --- a/openfast_io/openfast_io/FAST_reader.py +++ b/openfast_io/openfast_io/FAST_reader.py @@ -795,7 +795,7 @@ def read_InflowWind(self): self.fst_vt['InflowWind']['FileName_BTS'] = os.path.join(os.path.split(inflow_file)[0], f.readline().split()[0][1:-1]) # Parameters for Binary Bladed-style Full-Field files [used only for WindType = 4] (bladed_wind_params) f.readline() - self.fst_vt['InflowWind']['FilenameRoot'] = f.readline().split()[0][1:-1] + self.fst_vt['InflowWind']['FilenameRoot'] = os.path.join(os.path.split(inflow_file)[0], f.readline().split()[0][1:-1]) self.fst_vt['InflowWind']['TowerFile'] = bool_read(f.readline().split()[0]) # Parameters for HAWC-format binary files [Only used with WindType = 5] (hawc_wind_params) @@ -835,9 +835,9 @@ def read_InflowWind(self): self.fst_vt['InflowWind']['NumPulseGate'] = int(f.readline().split()[0]) self.fst_vt['InflowWind']['PulseSpacing'] = float_read(f.readline().split()[0]) self.fst_vt['InflowWind']['NumBeam'] = int(f.readline().split()[0]) - self.fst_vt['InflowWind']['FocalDistanceX'] = float_read(f.readline().split()[0]) - self.fst_vt['InflowWind']['FocalDistanceY'] = float_read(f.readline().split()[0]) - self.fst_vt['InflowWind']['FocalDistanceZ'] = float_read(f.readline().split()[0]) + self.fst_vt['InflowWind']['FocalDistanceX'] = [idx.strip() for idx in f.readline().split('NacCenB')[0].split(',')] + self.fst_vt['InflowWind']['FocalDistanceY'] = [idx.strip() for idx in f.readline().split('NacCenB')[0].split(',')] + self.fst_vt['InflowWind']['FocalDistanceZ'] = [idx.strip() for idx in f.readline().split('NacCenB')[0].split(',')] self.fst_vt['InflowWind']['RotorApexOffsetPos'] = [idx.strip() for idx in f.readline().split('RotorApexOffsetPos')[0].split(',')] self.fst_vt['InflowWind']['URefLid'] = float_read(f.readline().split()[0]) self.fst_vt['InflowWind']['MeasurementInterval'] = float_read(f.readline().split()[0]) @@ -884,6 +884,7 @@ def read_AeroDyn15(self): self.fst_vt['AeroDyn15']['TwrAero'] = 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] @@ -935,6 +936,7 @@ def read_AeroDyn15(self): self.fst_vt['AeroDyn15']['AoA34'] = bool_read(f.readline().split()[0]) self.fst_vt['AeroDyn15']['UA_Mod'] = int(f.readline().split()[0]) self.fst_vt['AeroDyn15']['FLookup'] = bool_read(f.readline().split()[0]) + self.fst_vt['AeroDyn15']['IntegrationMethod'] = int(f.readline().split()[0]) file_pos = f.tell() line = f.readline() @@ -980,6 +982,10 @@ 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('NacCenB')[0].split(',')] + self.fst_vt['AeroDyn15']['NacCd'] = [idx.strip() for idx in f.readline().split('NacCenB')[0].split(',')] + self.fst_vt['AeroDyn15']['NacDragAC'] = [idx.strip() for idx in f.readline().split('NacCenB')[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] @@ -1763,6 +1769,27 @@ def read_DISCON_in(self): else: del self.fst_vt['DISCON_in'] + def read_spd_trq(self, file): + ''' + read the speed-torque curve data to the fst_vt + ''' + spd_trq = {} + + f = open(os.path.normpath(os.path.join(self.FAST_directory, file))) + + spd_trq['header'] = f.readline().strip()[0] + + # handle arbritraty number of rows and two columns: RPM and Torque + data = f.readlines() + spd_trq['RPM'] = [float(line.split()[0]) for line in data] + spd_trq['Torque'] = [float(line.split()[1]) for line in data] + f.close() + + self.fst_vt['spd_trq'] = spd_trq + + + + def read_HydroDyn(self, hd_file): f = open(hd_file) @@ -2522,7 +2549,7 @@ def read_SubDyn(self, sd_file): ln = f.readline().split() ln = f.readline().split() for i in range(self.fst_vt['SubDyn']['NMOutputs']): - ln = f.readline().split() + ln = f.readline().split('!')[0].split() # allows for comments self.fst_vt['SubDyn']['MemberID_out'][i] = int(ln[0]) self.fst_vt['SubDyn']['NOutCnt'][i] = int(ln[1]) self.fst_vt['SubDyn']['NodeCnt'][i] = [int(node) for node in ln[2:]] @@ -3080,6 +3107,8 @@ def execute(self): self.fst_vt['SStC'].append(self.read_StC(StC_file)) if ROSCO: self.read_DISCON_in() + if self.fst_vt['ServoDyn']['VSContrl'] == 3: # user-defined from routine UserVSCont refered + self.read_spd_trq('spd_trq.dat') hd_file = os.path.normpath(os.path.join(self.FAST_directory, self.fst_vt['Fst']['HydroFile'])) if os.path.isfile(hd_file): self.read_HydroDyn(hd_file) @@ -3116,6 +3145,6 @@ def execute(self): 'glue-codes', 'openfast', '5MW_Land_BD_DLL_WTurb') # Path to fst directory files - check_rtest_cloned(os.path.join(fast.FAST_directory, fast.FAST_InputFile)) + check_rtest_cloned(os.path.join(fast.FAST_directory)) fast.execute() \ No newline at end of file diff --git a/openfast_io/openfast_io/FAST_writer.py b/openfast_io/openfast_io/FAST_writer.py index 859818457..a8daf36d8 100644 --- a/openfast_io/openfast_io/FAST_writer.py +++ b/openfast_io/openfast_io/FAST_writer.py @@ -176,6 +176,8 @@ def execute(self): self.write_StC(TStC,self.fst_vt['ServoDyn']['TStCfiles'][i_TStC]) for i_SStC, SStC in enumerate(self.fst_vt['SStC']): self.write_StC(SStC,self.fst_vt['ServoDyn']['SStCfiles'][i_SStC]) + if self.fst_vt['ServoDyn']['VSContrl'] == 3: # user-defined from routine UserVSCont refered + self.write_spd_trq() if self.fst_vt['Fst']['CompHydro'] == 1: self.write_HydroDyn() @@ -220,9 +222,9 @@ def write_MainInput(self): f.write('{:<22} {:<11} {:}'.format(self.fst_vt['Fst']['DT_UJac'], 'DT_UJac', '- Time between calls to get Jacobians (s)\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['Fst']['UJacSclFact'], 'UJacSclFact', '- Scaling factor used in Jacobians (-)\n')) f.write('---------------------- FEATURE SWITCHES AND FLAGS ------------------------------\n') - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['Fst']['CompElast'], 'CompElast', '- Compute structural dynamics (switch) {1=ElastoDyn; 2=ElastoDyn + BeamDyn for blades}\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['Fst']['CompElast'], 'CompElast', '- Compute structural dynamics (switch) {1=ElastoDyn; 2=ElastoDyn + BeamDyn for blades; 3=Simplified ElastoDyn}\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['Fst']['CompInflow'], 'CompInflow', '- Compute inflow wind velocities (switch) {0=still air; 1=InflowWind; 2=external from OpenFOAM}\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['Fst']['CompAero'], 'CompAero', '- Compute aerodynamic loads (switch) {0=None; 1=AeroDyn v14; 2=AeroDyn v15}\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['Fst']['CompAero'], 'CompAero', '- Compute aerodynamic loads (switch) {0=None; 1=AeroDisk; 2=AeroDyn; 3=ExtLoads}\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['Fst']['CompServo'], 'CompServo', '- Compute control and electrical-drive dynamics (switch) {0=None; 1=ServoDyn}\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['Fst']['CompSeaState'], 'CompSeaState', '- Compute sea state information (switch) {0=None; 1=SeaState}\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['Fst']['CompHydro'], 'CompHydro', '- Compute hydrodynamic loads (switch) {0=None; 1=HydroDyn}\n')) @@ -259,7 +261,7 @@ def write_MainInput(self): f.write('{:<22} {:<11} {:}'.format(self.fst_vt['Fst']['ChkptTime'], 'ChkptTime', '- Amount of time between creating checkpoint files for potential restart (s)\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['Fst']['DT_Out'], 'DT_Out', '- Time step for tabular output (s) (or "default")\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['Fst']['TStart'], 'TStart', '- Time to begin tabular output (s)\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['Fst']['OutFileFmt'], 'OutFileFmt', '- Format for tabular (time-marching) output file (switch) {1: text file [.out], 2: binary file [.outb], 3: both}\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['Fst']['OutFileFmt'], 'OutFileFmt', '- Format for tabular (time-marching) output file (switch) {1: text file [.out], 2: binary file [.outb], 3: both 1 and 2, 4: uncompressed binary [.outb], 5: both 1 and 4}\n')) f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['Fst']['TabDelim'], 'TabDelim', '- Use tab delimiters in text tabular output file? (flag) {uses spaces if false}\n')) f.write('{:<22} {:<11} {:}'.format('"'+self.fst_vt['Fst']['OutFmt']+'"', 'OutFmt', '- Format used for text tabular output, excluding the time channel. Resulting field should be 10 characters. (quoted string)\n')) f.write('---------------------- LINEARIZATION -------------------------------------------\n') @@ -277,10 +279,10 @@ def write_MainInput(self): f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['Fst']['LinOutJac'], 'LinOutJac', '- Include full Jacobians in linearization output (for debug) (flag) [unused if Linearize=False; used only if LinInputs=LinOutputs=2]\n')) f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['Fst']['LinOutMod'], 'LinOutMod', '- Write module-level linearization output files in addition to output for full system? (flag) [unused if Linearize=False]\n')) f.write('---------------------- VISUALIZATION ------------------------------------------\n') - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['Fst']['WrVTK'], 'WrVTK', '- VTK visualization data output: (switch) {0=none; 1=initialization data only; 2=animation}\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['Fst']['WrVTK'], 'WrVTK', '- VTK visualization data output: (switch) {0=none; 1=initialization data only; 2=animation; 3=mode shapes}\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['Fst']['VTK_type'], 'VTK_type', '- Type of VTK visualization data: (switch) {1=surfaces; 2=basic meshes (lines/points); 3=all meshes (debug)} [unused if WrVTK=0]\n')) f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['Fst']['VTK_fields'], 'VTK_fields', '- Write mesh fields to VTK data files? (flag) {true/false} [unused if WrVTK=0]\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['Fst']['VTK_fps'], 'VTK_fps', '- Frame rate for VTK output (frames per second){will use closest integer multiple of DT} [used only if WrVTK=2]\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['Fst']['VTK_fps'], 'VTK_fps', '-Frame rate for VTK output (frames per second){will use closest integer multiple of DT} [used only if WrVTK=2 or WrVTK=3]\n')) f.flush() os.fsync(f) @@ -299,7 +301,7 @@ def write_ElastoDyn(self): f.write('---------------------- SIMULATION CONTROL --------------------------------------\n') f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['ElastoDyn']['Echo'], 'Echo', '- Echo input data to ".ech" (flag)\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDyn']['Method'], 'Method', '- Integration method: {1: RK4, 2: AB4, or 3: ABM4} (-)\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDyn']['DT'], 'DT', 'Integration time step (s)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDyn']['DT'], 'DT', '- Integration time step (s)\n')) f.write('---------------------- DEGREES OF FREEDOM --------------------------------------\n') f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['ElastoDyn']['FlapDOF1'], 'FlapDOF1', '- First flapwise blade mode DOF (flag)\n')) f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['ElastoDyn']['FlapDOF2'], 'FlapDOF2', '- Second flapwise blade mode DOF (flag)\n')) @@ -395,7 +397,7 @@ def write_ElastoDyn(self): f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDyn']['TeetSSSp'], 'TeetSSSp', '- Rotor-teeter soft-stop linear-spring constant (N-m/rad) [used only for 2 blades and when TeetMod=1]\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDyn']['TeetHSSp'], 'TeetHSSp', '- Rotor-teeter hard-stop linear-spring constant (N-m/rad) [used only for 2 blades and when TeetMod=1]\n')) f.write('---------------------- YAW-FRICTION --------------------------------------------\n') - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDyn']['YawFrctMod'], 'YawFrctMod', 'Yaw-friction model {0: none, 1: friction without Fz term at the yaw bearing, 2: friction includes Fz term at yaw bearing, 3: user defined model} (switch)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDyn']['YawFrctMod'], 'YawFrctMod', '- Yaw-friction model {0: none, 1: friction without Fz term at the yaw bearing, 2: friction includes Fz term at yaw bearing, 3: user defined model} (switch)\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDyn']['M_CSmax'], 'M_CSmax', '- Maximum Coulomb friction torque (N-m)[mu_s*D_eff when YawFrctMod=1 and Fz*mu_s*D_eff when YawFrctMod=2]\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDyn']['M_CD'], 'M_CD', '- Dynamic friction moment at null yaw rate (N-m) [mu_d*D_eff when YawFrctMod=1 and Fz*mu_d*D_eff when YawFrctMod=2]\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDyn']['sig_v'], 'sig_v', '- Viscous friction coefficient (N-m/(rad/s))\n')) @@ -583,19 +585,19 @@ def write_BeamDyn(self): f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['BeamDyn']['QuasiStaticInit'], 'QuasiStaticInit', '- Use quasistatic pre-conditioning with centripetal accelerations in initialization (flag) [dynamic solve only]\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['BeamDyn']['rhoinf'], 'rhoinf', '- Numerical damping parameter for generalized-alpha integrator\n')) f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['BeamDyn']['quadrature'], 'quadrature', '- Quadrature method: 1=Gaussian; 2=Trapezoidal (switch)\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['BeamDyn']['refine'], 'refine', '- Refinement factor for trapezoidal quadrature (-). DEFAULT = 1 [used only when quadrature=2]\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['BeamDyn']['n_fact'], 'n_fact', '- Factorization frequency (-). DEFAULT = 5\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['BeamDyn']['refine'], 'refine', '- Refinement factor for trapezoidal quadrature (-) [DEFAULT = 1; used only when quadrature=2]\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['BeamDyn']['n_fact'], 'n_fact', '- Factorization frequency for the Jacobian in N-R iteration(-) [DEFAULT = 5]\n')) f.write(float_default_out(self.fst_vt['BeamDyn']['DTBeam']) + ' {:<11} {:}'.format('DTBeam', '- Time step size (s).\n')) - f.write(int_default_out(self.fst_vt['BeamDyn']['load_retries']) + ' {:<11} {:}'.format('load_retries', '- Number of factored load retries before quitting the aimulation\n')) + f.write(int_default_out(self.fst_vt['BeamDyn']['load_retries']) + ' {:<11} {:}'.format('load_retries', '- Number of factored load retries before quitting the aimulation [DEFAULT = 20]\n')) f.write(int_default_out(self.fst_vt['BeamDyn']['NRMax']) + ' {:<11} {:}'.format('NRMax', '- Max number of iterations in Newton-Ralphson algorithm (-). DEFAULT = 10\n')) - f.write(float_default_out(self.fst_vt['BeamDyn']['stop_tol']) + ' {:<11} {:}'.format('stop_tol', '- Tolerance for stopping criterion (-)\n')) + f.write(float_default_out(self.fst_vt['BeamDyn']['stop_tol']) + ' {:<11} {:}'.format('stop_tol', '- Tolerance for stopping criterion (-) [DEFAULT = 1E-5]\n')) print('----------') print(self.fst_vt['BeamDyn']['tngt_stf_fd'], type(self.fst_vt['BeamDyn']['tngt_stf_fd'])) - f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['BeamDyn']['tngt_stf_fd'], 'tngt_stf_fd', '- Flag to use finite differenced tangent stiffness matrix (-)\n')) - f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['BeamDyn']['tngt_stf_comp'], 'tngt_stf_comp', '- Flag to compare analytical finite differenced tangent stiffness matrix (-)\n')) - f.write(float_default_out(self.fst_vt['BeamDyn']['tngt_stf_pert']) + ' {:<11} {:}'.format('tngt_stf_pert', '- perturbation size for finite differencing (-)\n')) - f.write(float_default_out(self.fst_vt['BeamDyn']['tngt_stf_difftol']) + ' {:<11} {:}'.format('tngt_stf_difftol', '- Maximum allowable relative difference between analytical and fd tangent stiffness (-)\n')) + f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['BeamDyn']['tngt_stf_fd'], 'tngt_stf_fd', '- Use finite differenced tangent stiffness matrix? (flag)\n')) + f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['BeamDyn']['tngt_stf_comp'], 'tngt_stf_comp', '- Compare analytical finite differenced tangent stiffness matrix? (flag)\n')) + f.write(float_default_out(self.fst_vt['BeamDyn']['tngt_stf_pert']) + ' {:<11} {:}'.format('tngt_stf_pert', '- Perturbation size for finite differencing (-) [DEFAULT = 1E-6]\n')) + f.write(float_default_out(self.fst_vt['BeamDyn']['tngt_stf_difftol']) + ' {:<11} {:}'.format('tngt_stf_difftol', '- Maximum allowable relative difference between analytical and fd tangent stiffness (-); [DEFAULT = 0.1]\n')) f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['BeamDyn']['RotStates'], 'RotStates', '- Orient states in the rotating frame during linearization? (flag) [used only when linearizing]\n')) f.write('---------------------- GEOMETRY PARAMETER --------------------------------------\n') f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['BeamDyn']['member_total'], 'member_total', '- Total number of members (-)\n')) @@ -748,9 +750,9 @@ def write_InflowWind(self): f.write('{:<22} {:<11} {:}'.format(self.fst_vt['InflowWind']['NumPulseGate'], 'NumPulseGate', '- Number of lidar measurement gates (used when SensorType = 3)\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['InflowWind']['PulseSpacing'], 'PulseSpacing', '- Distance between range gates (m) (used when SensorType = 3)\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['InflowWind']['NumBeam'], 'NumBeam', '- Number of lidar measurement beams (0-5)(used when SensorType = 1)\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['InflowWind']['FocalDistanceX'], 'FocalDistanceX', '- Focal distance co-ordinates of the lidar beam in the x direction (relative to hub height) (only first coordinate used for SensorType 2 and 3) (m)\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['InflowWind']['FocalDistanceY'], 'FocalDistanceY', '- Focal distance co-ordinates of the lidar beam in the y direction (relative to hub height) (only first coordinate used for SensorType 2 and 3) (m)\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['InflowWind']['FocalDistanceZ'], 'FocalDistanceZ', '- Focal distance co-ordinates of the lidar beam in the z direction (relative to hub height) (only first coordinate used for SensorType 2 and 3) (m)\n')) + f.write('{:<22} {:<11} {:}'.format(', '.join(np.array(self.fst_vt['InflowWind']['FocalDistanceX'], dtype=str)), 'FocalDistanceX', '- Focal distance co-ordinates of the lidar beam in the x direction (relative to hub height) (only first coordinate used for SensorType 2 and 3) (m)\n')) + f.write('{:<22} {:<11} {:}'.format(', '.join(np.array(self.fst_vt['InflowWind']['FocalDistanceY'], dtype=str)), 'FocalDistanceY', '- Focal distance co-ordinates of the lidar beam in the y direction (relative to hub height) (only first coordinate used for SensorType 2 and 3) (m)\n')) + f.write('{:<22} {:<11} {:}'.format(', '.join(np.array(self.fst_vt['InflowWind']['FocalDistanceZ'], dtype=str)), 'FocalDistanceZ', '- Focal distance co-ordinates of the lidar beam in the z direction (relative to hub height) (only first coordinate used for SensorType 2 and 3) (m)\n')) f.write('{:<22} {:<11} {:}'.format(', '.join(np.array(self.fst_vt['InflowWind']['RotorApexOffsetPos'], dtype=str)), 'RotorApexOffsetPos', '- Offset of the lidar from hub height (m)\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['InflowWind']['URefLid'], 'URefLid', '- Reference average wind speed for the lidar[m/s]\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['InflowWind']['MeasurementInterval'], 'MeasurementInterval', '- Time between each measurement [s]\n')) @@ -800,18 +802,19 @@ def write_AeroDyn15(self): f.write('====== General Options ============================================================================\n') f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['Echo'], 'Echo', '- Echo the input to ".AD.ech"? (flag)\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['DTAero'], 'DTAero', '- Time interval for aerodynamic calculations {or "default"} (s)\n')) - f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['Wake_Mod'], 'Wake_Mod', '- - Wake/induction model (switch) {0=none, 1=BEMT, 3=OLAF} [Wake_Mod cannot be 2 or 3 when linearizing]\n')) + f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['Wake_Mod'], 'Wake_Mod', '- Wake/induction model (switch) {0=none, 1=BEMT, 3=OLAF} [Wake_Mod cannot be 2 or 3 when linearizing]\n')) f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['TwrPotent'], '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}\n')) f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['TwrShadow'], 'TwrShadow', '- Calculate tower influence on wind based on downstream tower shadow (switch) {0=none, 1=Powles model, 2=Eames model}\n')) f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['TwrAero'], 'TwrAero', '- Calculate tower aerodynamic loads? (flag)\n')) f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['CavitCheck'], 'CavitCheck', '- Perform cavitation check? (flag) [UA_Mod must be 0 when CavitCheck=true]\n')) f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['Buoyancy'], 'Buoyancy', '- Include buoyancy effects? (flag)\n')) + f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['NacelleDrag'], 'NacelleDrag', '- Include Nacelle Drag effects? (flag)\n')) f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['CompAA'], 'CompAA', '- Flag to compute AeroAcoustics calculation [used only when Wake_Mod = 1 or 2]\n')) f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['AA_InputFile'], 'AA_InputFile', '- AeroAcoustics input file [used only when CompAA=true]\n')) f.write('====== Environmental Conditions ===================================================================\n') f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['AirDens'], 'AirDens', '- Air density (kg/m^3)\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['KinVisc'], 'KinVisc', '- Kinematic viscosity of working fluid (m^2/s)\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['SpdSound'], 'SpdSound', '- Speed of sound in working fluid \n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['SpdSound'], 'SpdSound', '- Speed of sound in working fluid (m/s)\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['Patm'], 'Patm', '- Atmospheric pressure (Pa) [used only when CavitCheck=True]\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['Pvap'], 'Pvap', '- Vapour pressure of working fluid (Pa) [used only when CavitCheck=True]\n')) f.write('====== Blade-Element/Momentum Theory Options ====================================================== [unused when Wake_Mod=0 or 3, except for BEM_Mod]\n') @@ -838,14 +841,15 @@ def write_AeroDyn15(self): f.write('--- Dynamic wake/inflow\n') f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['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} (-)\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['tau1_const'], 'tau1_const', '- Time constant for DBEMT (s) [used only DBEMT_Mod=1 or 3]\n')) - f.write('====== OLAF -- cOnvecting LAgrangian Filaments (Free Vortex Wake) Theory Options ================== [used only when WakeM_od=3]\n') + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['tau1_const'], 'tau1_const', '- Time constant for DBEMT (s) [used only when DBEMT_Mod=1 or 3]\n')) + f.write('====== OLAF -- cOnvecting LAgrangian Filaments (Free Vortex Wake) Theory Options ================== [used only when Wake_Mod=3]\n') olaf_file = self.FAST_namingOut + '_OLAF.dat' f.write('{!s:<22} {:<11} {:}'.format(olaf_file, 'OLAFInputFileName', '- Input file for OLAF [used only when Wake_Mod=3]\n')) - f.write('====== Unsteady Airfoil Aerodynamics Options ===================================== [used only when AFAeroMod=2]\n') + f.write('====== Unsteady Airfoil Aerodynamics Options ===================================== \n') f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['AoA34'], 'AoA34', "- Sample the angle of attack (AoA) at the 3/4 chord or the AC point {default=True} [always used]\n")) f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['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}\n")) f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['FLookup'], '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 UA_Mod>0]\n")) + f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['IntegrationMethod'], 'IntegrationMethod', "- Switch to indicate which integration method UA uses (1=RK4, 2=AB4, 3=ABM4, 4=BDF2)\n")) if 'UAStartRad' in self.fst_vt['AeroDyn15'] and 'UAEndRad' in self.fst_vt['AeroDyn15']: f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['UAStartRad'], 'UAStartRad', '- Starting radius for dynamic stall (fraction of rotor radius [0.0,1.0]) [used only when UA_Mod>0; if line is missing UAStartRad=0]\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['UAEndRad'], 'UAEndRad', '- Ending radius for dynamic stall (fraction of rotor radius [0.0,1.0]) [used only when UA_Mod>0; if line is missing UAEndRad=1]\n')) @@ -870,9 +874,12 @@ def write_AeroDyn15(self): f.write('====== Hub Properties ============================================================================== [used only when Buoyancy=True]\n') f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['VolHub'], 'VolHub', '- Hub volume (m^3)\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['HubCenBx'], 'HubCenBx', '- Hub center of buoyancy x direction offset (m)\n')) - f.write('====== Nacelle Properties ========================================================================== [used only when Buoyancy=True]\n') + f.write('====== Nacelle Properties ========================================================================== used only when Buoyancy=True or NacelleDrag=True]\n') f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['VolNac'], 'VolNac', '- Nacelle volume (m^3)\n')) f.write('{:<22} {:<11} {:}'.format(', '.join(np.array(self.fst_vt['AeroDyn15']['NacCenB'], dtype=str)), 'NacCenB', '- Position of nacelle center of buoyancy from yaw bearing in nacelle coordinates (m)\n')) + f.write('{:<22} {:<11} {:}'.format(', '.join(np.array(self.fst_vt['AeroDyn15']['NacCenB'], dtype=str)), 'NacArea', '- Projected area of the nacelle in X, Y, Z in the nacelle coordinate system (m^2)\n')) + f.write('{:<22} {:<11} {:}'.format(', '.join(np.array(self.fst_vt['AeroDyn15']['NacCenB'], dtype=str)), 'NacCd', '- Drag coefficient for the nacelle areas defined above (-)\n')) + f.write('{:<22} {:<11} {:}'.format(', '.join(np.array(self.fst_vt['AeroDyn15']['NacCenB'], dtype=str)), 'NacDragAC', '- Position of aerodynamic center of nacelle drag in nacelle coordinates (m)\n')) f.write('====== Tail Fin Aerodynamics ========================================================================\n') f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['TFinAero'], 'TFinAero', '- Calculate tail fin aerodynamics model (flag)\n')) f.write('{:<22} {:<11} {:}'.format('"'+self.fst_vt['AeroDyn15']['TFinFile']+'"', 'TFinFile', '- Input file for tail fin aerodynamics [used only when TFinAero=True]\n')) @@ -1379,19 +1386,19 @@ def write_ServoDyn(self): f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ServoDyn']['YawManRat'], 'YawManRat', '- Yaw maneuver rate (in absolute value) (deg/s)\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ServoDyn']['NacYawF'], 'NacYawF', '- Final yaw angle for override yaw maneuvers (degrees)\n')) f.write('---------------------- Aerodynamic Flow Control -------------------------------------\n') - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ServoDyn']['AfCmode'], 'AfCmode', '- Airfoil control mode {0- none, 1- cosine wave cycle, 4- user-defined from Simulink/Labview, 5- user-defined from Bladed-style DLL}\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ServoDyn']['AfCmode'], 'AfCmode', '- Airfoil control mode {0: none, 1: cosine wave cycle, 4: user-defined from Simulink/Labview, 5: user-defined from Bladed-style DLL} (switch)\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ServoDyn']['AfC_Mean'], 'AfC_Mean', '- Mean level for sinusoidal cycling or steady value (-) [used only with AfCmode==1]\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ServoDyn']['AfC_Amp'], 'AfC_Amp', '- Amplitude for for cosine cycling of flap signal (AfC = AfC_Amp*cos(Azimuth+phase)+AfC_mean) (-) [used only with AfCmode==1]\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ServoDyn']['AfC_Phase'], 'AfC_phase', '- Phase relative to the blade azimuth (0 is vertical) for for cosine cycling of flap signal (deg) [used only with AfCmode==1]\n')) f.write('---------------------- STRUCTURAL CONTROL ---------------------------------------\n') f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ServoDyn']['NumBStC'], 'NumBStC', '- Number of blade structural controllers (integer)\n')) - f.write('{!s:<22} {:<11} {:}'.format('"' + '" "'.join(self.fst_vt['ServoDyn']['BStCfiles']) + '"', 'BStCfiles', '- Name of the file for blade tuned mass damper (quoted string) [unused when CompNTMD is false]\n')) + f.write('{!s:<22} {:<11} {:}'.format('"' + '" "'.join(self.fst_vt['ServoDyn']['BStCfiles']) + '"', 'BStCfiles', '- Name of the files for blade structural controllers (quoted strings) [unused when NumBStC==0]\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ServoDyn']['NumNStC'], 'NumNStC', '- Number of nacelle structural controllers (integer)\n')) - f.write('{!s:<22} {:<11} {:}'.format('"' + '" "'.join(self.fst_vt['ServoDyn']['NStCfiles']) + '"', 'NStCfiles', '- Name of the file for nacelle tuned mass damper (quoted string) [unused when CompNTMD is false]\n')) + f.write('{!s:<22} {:<11} {:}'.format('"' + '" "'.join(self.fst_vt['ServoDyn']['NStCfiles']) + '"', 'NStCfiles', '- Name of the files for nacelle structural controllers (quoted strings) [unused when NumNStC==0]\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ServoDyn']['NumTStC'], 'NumTStC', '- Number of tower structural controllers (integer)\n')) - f.write('{!s:<22} {:<11} {:}'.format('"' + '" "'.join(self.fst_vt['ServoDyn']['TStCfiles']) + '"', 'TStCfiles', '- Name of the file for tower tuned mass damper (quoted string) [unused when CompNTMD is false]\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ServoDyn']['NumSStC'], 'NumSStC', '- Number of sbustructure structural controllers (integer)\n')) - f.write('{!s:<22} {:<11} {:}'.format('"' + '" "'.join(self.fst_vt['ServoDyn']['SStCfiles']) + '"', 'SStCfiles', '- Name of the file for sbustructure tuned mass damper (quoted string) [unused when CompNTMD is false]\n')) + f.write('{!s:<22} {:<11} {:}'.format('"' + '" "'.join(self.fst_vt['ServoDyn']['TStCfiles']) + '"', 'TStCfiles', '- Name of the files for tower structural controllers (quoted strings) [unused when NumTStC==0]\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ServoDyn']['NumSStC'], 'NumSStC', '- Number of substructure structural controllers (integer)\n')) + f.write('{!s:<22} {:<11} {:}'.format('"' + '" "'.join(self.fst_vt['ServoDyn']['SStCfiles']) + '"', 'SStCfiles', '- Name of the files for substructure structural controllers (quoted strings) [unused when NumSStC==0]\n')) f.write('---------------------- CABLE CONTROL ---------------------------------------- \n') f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ServoDyn']['CCmode'], 'CCmode', '- Cable control mode {0- none, 4- user-defined from Simulink/Labview, 5- user-defineAfC_phased from Bladed-style DLL}\n')) f.write('---------------------- BLADED INTERFACE ---------------------------------------- [used only with Bladed Interface]\n') @@ -1400,7 +1407,7 @@ def write_ServoDyn(self): f.write('{:<22} {:<11} {:}'.format('"'+self.fst_vt['ServoDyn']['DLL_ProcName']+'"', 'DLL_ProcName', '- Name of procedure in DLL to be called (-) [case sensitive; used only with DLL Interface]\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ServoDyn']['DLL_DT'], 'DLL_DT', '- Communication interval for dynamic library (s) (or "default") [used only with Bladed Interface]\n')) f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['ServoDyn']['DLL_Ramp'], 'DLL_Ramp', '- Whether a linear ramp should be used between DLL_DT time steps [introduces time shift when true] (flag) [used only with Bladed Interface]\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ServoDyn']['BPCutoff'], 'BPCutoff', '- Cuttoff frequency for low-pass filter on blade pitch from DLL (Hz) [used only with Bladed Interface]\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ServoDyn']['BPCutoff'], 'BPCutoff', '- Cutoff frequency for low-pass filter on blade pitch from DLL (Hz) [used only with Bladed Interface]\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ServoDyn']['NacYaw_North'], 'NacYaw_North', '- Reference yaw angle of the nacelle when the upwind end points due North (deg) [used only with Bladed Interface]\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ServoDyn']['Ptch_Cntrl'], 'Ptch_Cntrl', '- Record 28: Use individual pitch control {0: collective pitch; 1: individual pitch control} (switch) [used only with Bladed Interface]\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ServoDyn']['Ptch_SetPnt'], 'Ptch_SetPnt', '- Record 5: Below-rated pitch angle set-point (deg) [used only with Bladed Interface]\n')) @@ -1483,6 +1490,15 @@ def write_DISCON_in(self): rosco_vt=self.fst_vt['DISCON_in'] ) + def write_spd_trq(self): + # generate the spd_trq.dat file when VSContrl == 3 + spd_trq_file = os.path.join(self.FAST_runDirectory, 'spd_trq.dat') + f = open(spd_trq_file, 'w') + + f.write('{:}'.format(self.fst_vt['spd_trq']['header'], '\n')) + for i in range(len(self.fst_vt['spd_trq']['RPM'])): + f.write('{:<22f} {:<22f} {:}'.format(self.fst_vt['spd_trq']['RPM'][i], self.fst_vt['spd_trq']['Torque'][i], '\n')) + def write_HydroDyn(self): # Generate HydroDyn input file @@ -1773,7 +1789,7 @@ def write_SeaState(self): f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['SeaState']['NZ'], 'NZ', '– Number of nodes in the Z direction (-) [>=2]\n')) f.write('---------------------- WAVES ---------------------------------------------------\n') - f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['SeaState']['WaveMod'], 'WaveMod', '- Incident wave kinematics model {0: none=still water, 1: regular (periodic), 1P#: regular with user-specified phase, 2: JONSWAP/Pierson-Moskowitz spectrum (irregular), 3: White noise spectrum (irregular), 4: user-defined spectrum from routine UserWaveSpctrm (irregular), 5: Externally generated wave-elevation time series, 6: Externally generated full wave-kinematics time series [option 6 is invalid for PotMod/=0]} (switch)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['SeaState']['WaveMod'], 'WaveMod', '- Incident wave kinematics model {0: none=still water, 1: regular (periodic), 1P#: regular with user-specified phase, 2: JONSWAP/Pierson-Moskowitz spectrum (irregular), 3: White noise spectrum (irregular), 4: user-defined spectrum from routine UserWaveSpctrm (irregular), 5: Externally generated wave-elevation time series, 6: Externally generated full wave-kinematics time series [option 6 is invalid for PotMod/=0]} (switch)\n')) f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['SeaState']['WaveStMod'], 'WaveStMod', '- Model for stretching incident wave kinematics to instantaneous free surface {0: none=no stretching, 1: vertical stretching, 2: extrapolation stretching, 3: Wheeler stretching} (switch) [unused when WaveMod=0 or when PotMod/=0]\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['SeaState']['WaveTMax'], 'WaveTMax', '- Analysis time for incident wave calculations (sec) [unused when WaveMod=0; determines WaveDOmega=2Pi/WaveTMax in the IFFT]\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['SeaState']['WaveDT'], 'WaveDT', '- Time step for incident wave calculations (sec) [unused when WaveMod=0; 0.1<=WaveDT<=1.0 recommended; determines WaveOmegaMax=Pi/WaveDT in the IFFT]\n')) From d3f0c30fe29e7fe4add8f0dbdc5fdfc53d7e96d0 Mon Sep 17 00:00:00 2001 From: Mayank Chetan Date: Wed, 28 Aug 2024 04:31:06 +0000 Subject: [PATCH 044/161] added SED & ADsk to read/write, updated outlist reading --- openfast_io/openfast_io/FAST_output_reader.py | 12 +- openfast_io/openfast_io/FAST_reader.py | 213 ++++++++++++++++-- openfast_io/openfast_io/FAST_vars_out.py | 75 ++++++ openfast_io/openfast_io/FAST_writer.py | 193 +++++++++++++++- openfast_io/openfast_io/create_output_vars.py | 18 +- 5 files changed, 483 insertions(+), 28 deletions(-) diff --git a/openfast_io/openfast_io/FAST_output_reader.py b/openfast_io/openfast_io/FAST_output_reader.py index e6253b255..d81ba9798 100644 --- a/openfast_io/openfast_io/FAST_output_reader.py +++ b/openfast_io/openfast_io/FAST_output_reader.py @@ -103,15 +103,15 @@ def toDataFrame(self): return df -def load_ascii_output(filename): +def load_ascii_output(filename, headerLines = 8, descriptionLine = 4, attributeLine = 6, unitLine = 7, delimiter = None): with open(filename) as f: info = {} info['name'] = os.path.splitext(os.path.basename(filename))[0] - header = [f.readline() for _ in range(8)] - info['description'] = header[4].strip() - info['attribute_names'] = header[6].split() - info['attribute_units'] = [unit[1:-1] for unit in header[7].split()] #removing "()" - data = np.array([line.split() for line in f.readlines()], dtype=float) + header = [f.readline() for _ in range(headerLines)] + info['description'] = header[descriptionLine].strip() + info['attribute_names'] = header[attributeLine].strip().split(delimiter) + info['attribute_units'] = [unit[1:-1] for unit in header[unitLine].strip().split(delimiter)] #removing "()" + data = np.array([line.split(delimiter) for line in f.readlines()], dtype=float) return data, info def load_binary_output(filename): diff --git a/openfast_io/openfast_io/FAST_reader.py b/openfast_io/openfast_io/FAST_reader.py index bd8b1bcc0..ed150fd4f 100644 --- a/openfast_io/openfast_io/FAST_reader.py +++ b/openfast_io/openfast_io/FAST_reader.py @@ -3,6 +3,7 @@ from functools import reduce import operator from openfast_io.FAST_vars_out import FstOutput +from openfast_io.FAST_output_reader import load_ascii_output try: from rosco.toolbox.utilities import read_DISCON, load_from_txt @@ -102,11 +103,13 @@ def __init__(self): self.fst_vt['Fst'] = {} self.fst_vt['outlist'] = FstOutput self.fst_vt['ElastoDyn'] = {} + self.fst_vt['SimpleElastoDyn'] = {} self.fst_vt['ElastoDynBlade'] = {} self.fst_vt['ElastoDynTower'] = {} self.fst_vt['InflowWind'] = {} self.fst_vt['AeroDyn15'] = {} self.fst_vt['AeroDyn14'] = {} + self.fst_vt['AeroDisk'] = {} self.fst_vt['AeroDynBlade'] = {} self.fst_vt['AeroDynTower'] = {} self.fst_vt['AeroDynPolar'] = {} @@ -147,7 +150,7 @@ def loop_dict(vartree, search_var, branch): var = var.replace(' ', '') loop_dict(vartree_head, var, []) - def read_outlist(self,f,module): + def read_outlist_freeForm(self,f,module): ''' Replacement for set_outlist that doesn't care about whether the channel is in the outlist vartree Easier, but riskier because OpenFAST can crash @@ -165,6 +168,28 @@ def read_outlist(self,f,module): self.fst_vt['outlist'][module][c] = True data = f.readline() + def read_outlist(self,f,module): + ''' + Read the outlist section of the FAST input file, genralized for most modules + + Inputs: f - file handle + module - of OpenFAST, e.g. ElastoDyn, ServoDyn, AeroDyn, AeroDisk, etc. + + ''' + data = f.readline().split()[0] # to counter if we dont have any quotes + while data != 'END': + if data.find('"')>=0: + channels = data.split('"') + channel_list = channels[1].split(',') + else: + row_string = data.split(',') + if len(row_string)==1: + channel_list = [row_string[0].split('\n')[0]] + else: + channel_list = row_string + self.set_outlist(self.fst_vt['outlist'][module], channel_list) + data = f.readline().split()[0] # to counter if we dont have any quotes + def read_MainInput(self): # Main FAST v8.16-v8.17 Input File # Currently no differences between FASTv8.16 and OpenFAST. @@ -499,6 +524,109 @@ def read_ElastoDyn(self, ed_file): f.close() + def read_SimpleElastoDyn(self, sed_file): + # Read the Simplified ElastoDyn input file + ''' + Here is the format of the Simplified ElastoDyn input file: + + ------- SIMPLIFIED ELASTODYN INPUT FILE ---------------------------------------- + Test case input file for SED (not representative of any model) + ---------------------- SIMULATION CONTROL -------------------------------------- + True Echo - Echo input data to ".ech" (flag) + 3 IntMethod - Integration method: {1: RK4, 2: AB4, or 3: ABM4} (-) + "default" DT - Integration time step (s) + ---------------------- DEGREES OF FREEDOM -------------------------------------- + True GenDOF - Generator DOF (flag) + True YawDOF - Yaw degree of freedom -- controlled by controller (flag) + ---------------------- INITIAL CONDITIONS -------------------------------------- + 0 Azimuth - Initial azimuth angle for blades (degrees) + 0 BlPitch - Blades initial pitch (degrees) + 12.1 RotSpeed - Initial or fixed rotor speed (rpm) + 0 NacYaw - Initial or fixed nacelle-yaw angle (degrees) + 0 PtfmPitch - Fixed pitch tilt rotational displacement of platform (degrees) + ---------------------- TURBINE CONFIGURATION ----------------------------------- + 3 NumBl - Number of blades (-) + 63 TipRad - The distance from the rotor apex to the blade tip (meters) + 1.5 HubRad - The distance from the rotor apex to the blade root (meters) + -2.5 PreCone - Blades cone angle (degrees) + -5.0191 OverHang - Distance from yaw axis to rotor apex [3 blades] or teeter pin [2 blades] (meters) + -5 ShftTilt - Rotor shaft tilt angle (degrees) + 1.96256 Twr2Shft - Vertical distance from the tower-top to the rotor shaft (meters) + 87.6 TowerHt - Height of tower above ground level [onshore] or MSL [offshore] (meters) + ---------------------- MASS AND INERTIA ---------------------------------------- + 38677052 RotIner - Rot inertia about rotor axis [blades + hub] (kg m^2) + 534.116 GenIner - Generator inertia about HSS (kg m^2) + ---------------------- DRIVETRAIN ---------------------------------------------- + 97 GBoxRatio - Gearbox ratio (-) + ---------------------- OUTPUT -------------------------------------------------- + OutList - The next line(s) contains a list of output parameters. See OutListParameters.xlsx for a listing of available output channels, (-) + "BlPitch1" + "BlPitch2" + "BlPitch3" + "Azimuth" - Blades azimuth angle (deg) + "RotSpeed" - Low-speed shaft rotational speed (rpm) + "RotAcc" - Low-speed shaft rotational acceleration (rad/s^2) + "GenSpeed" - High-speed shaft rotational speed (rpm) + "GenAcc" - High-speed shaft rotational acceleration (rad/s^2) + "Yaw" - Commanded yaw angle + "YawRate" - Commanded yaw angle rate + "RotPwr" + "RotTorq" + END of input file (the word "END" must appear in the first 3 columns of this last OutList line) + ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + ''' + f = open(sed_file) + + f.readline() + f.readline() + f.readline() + self.fst_vt['SimpleElastoDyn']['Echo'] = bool_read(f.readline().split()[0]) + self.fst_vt['SimpleElastoDyn']['IntMethod'] = int_read(f.readline().split()[0]) + self.fst_vt['SimpleElastoDyn']['DT'] = float_read(f.readline().split()[0]) + + # Degrees of Freedom + f.readline() + self.fst_vt['SimpleElastoDyn']['GenDOF'] = bool_read(f.readline().split()[0]) + self.fst_vt['SimpleElastoDyn']['YawDOF'] = bool_read(f.readline().split()[0]) + + # Initial Conditions + f.readline() + self.fst_vt['SimpleElastoDyn']['Azimuth'] = float_read(f.readline().split()[0]) + self.fst_vt['SimpleElastoDyn']['BlPitch'] = float_read(f.readline().split()[0]) + self.fst_vt['SimpleElastoDyn']['RotSpeed'] = float_read(f.readline().split()[0]) + self.fst_vt['SimpleElastoDyn']['NacYaw'] = float_read(f.readline().split()[0]) + self.fst_vt['SimpleElastoDyn']['PtfmPitch'] = float_read(f.readline().split()[0]) + + # Turbine Configuration + f.readline() + self.fst_vt['SimpleElastoDyn']['NumBl'] = int_read(f.readline().split()[0]) + self.fst_vt['SimpleElastoDyn']['TipRad'] = float_read(f.readline().split()[0]) + self.fst_vt['SimpleElastoDyn']['HubRad'] = float_read(f.readline().split()[0]) + self.fst_vt['SimpleElastoDyn']['PreCone'] = float_read(f.readline().split()[0]) + self.fst_vt['SimpleElastoDyn']['OverHang'] = float_read(f.readline().split()[0]) + self.fst_vt['SimpleElastoDyn']['ShftTilt'] = float_read(f.readline().split()[0]) + self.fst_vt['SimpleElastoDyn']['Twr2Shft'] = float_read(f.readline().split()[0]) + self.fst_vt['SimpleElastoDyn']['TowerHt'] = float_read(f.readline().split()[0]) + + # Mass and Inertia + f.readline() + self.fst_vt['SimpleElastoDyn']['RotIner'] = float_read(f.readline().split()[0]) + self.fst_vt['SimpleElastoDyn']['GenIner'] = float_read(f.readline().split()[0]) + + # Drivetrain + f.readline() + self.fst_vt['SimpleElastoDyn']['GBoxRatio'] = float_read(f.readline().split()[0]) + + # Output + f.readline() + f.readline() + + self.read_outlist(f,'SimpleElastoDyn') + + f.close() + + + def read_ElastoDynBlade(self, blade_file): # ElastoDyn v1.00 Blade Input File # Currently no differences between FASTv8.16 and OpenFAST. @@ -1440,6 +1568,60 @@ def read_AeroDyn14Polar(self, aerodynFile): return airfoil + def read_AeroDisk(self): + '''' + Reading the AeroDisk input file. + ''' + + aDisk_file = os.path.join(self.FAST_directory, self.fst_vt['Fst']['AeroFile']) + f = open(aDisk_file) + f.readline() + f.readline() + f.readline() + + # Simulation Control + self.fst_vt['AeroDisk']['Echo'] = bool_read(f.readline().split()[0]) + self.fst_vt['AeroDisk']['DT'] = float_read(f.readline().split()[0]) + + # Environmental Conditions + f.readline() + self.fst_vt['AeroDisk']['AirDens'] = float_read(f.readline().split()[0]) + + # Actuator Disk Properties + f.readline() + self.fst_vt['AeroDisk']['RotorRad'] = float_read(f.readline().split()[0]) + + # read InColNames - Input column headers (string) {may include a combination of "TSR, RtSpd, VRel, Pitch, Skew"} (up to 4 columns) + # Read between the quotes + self.fst_vt['AeroDisk']['InColNames'] = read_array(f, len = None, split_val=',', array_type=str) + # read InColDims - Number of unique values in each column (-) (must have same number of columns as InColName) [each >=2] + self.fst_vt['AeroDisk']['InColDims'] = read_array(f, len=len(self.fst_vt['AeroDisk']['InColNames']), array_type=int) + + # read the contents table of the CSV file referenced next + # if the next line starts with an @, then it is a file reference + line = f.readline() + if line[0] == '@': + self.fst_vt['AeroDisk']['actuatorDiskFile'] = os.path.join(self.FAST_directory, line[1:].strip()) + + # using the load_ascii_output function to read the CSV file, ;) + data, info = load_ascii_output(self.fst_vt['AeroDisk']['actuatorDiskFile'], headerLines=3, + descriptionLine=0, attributeLine=1, unitLine=2, delimiter = ',') + self.fst_vt['AeroDisk']['actuatorDiskTable'] = {'dsc': info['description'], + 'attr': info['attribute_names'], + 'units': info['attribute_units'], + 'data': data} + else: + raise Exception('Expecting a file reference to the actuator disk CSV file') + + # read the output list + f.readline() + f.readline() + + self.read_outlist(f,'AeroDisk') + + f.close() + + def read_ServoDyn(self): # ServoDyn v1.05 Input File # Currently no differences between FASTv8.16 and OpenFAST. @@ -2248,7 +2430,7 @@ def read_SeaState(self, ss_file): # SeaState Outlist f.readline() - self.read_outlist(f,'SeaState') + self.read_outlist_freeForm(f,'SeaState') f.close() @@ -2555,7 +2737,7 @@ def read_SubDyn(self, sd_file): self.fst_vt['SubDyn']['NodeCnt'][i] = [int(node) for node in ln[2:]] f.readline() # SSOutList - self.read_outlist(f,'SubDyn') + self.read_outlist_freeForm(f,'SubDyn') f.close() @@ -3042,7 +3224,7 @@ def read_MoorDyn(self, moordyn_file): elif 'outputs' in data_line: - self.read_outlist(f,'MoorDyn') + self.read_outlist_freeForm(f,'MoorDyn') f.close() break @@ -3078,19 +3260,24 @@ def execute(self): self.read_MainInput() ed_file = os.path.join(self.FAST_directory, self.fst_vt['Fst']['EDFile']) - self.read_ElastoDyn(ed_file) - if not os.path.isabs(self.fst_vt['ElastoDyn']['BldFile1']): - ed_blade_file = os.path.join(os.path.dirname(ed_file), self.fst_vt['ElastoDyn']['BldFile1']) - if self.fst_vt['Fst']['CompElast'] == 1 or os.path.isfile(ed_blade_file): # If elastodyn blade is being used OR if the blade file exists - self.read_ElastoDynBlade(ed_blade_file) - if not os.path.isabs(self.fst_vt['ElastoDyn']['TwrFile']): - ed_tower_file = os.path.join(os.path.dirname(ed_file), self.fst_vt['ElastoDyn']['TwrFile']) - self.read_ElastoDynTower(ed_tower_file) + + if self.fst_vt['Fst']['CompElast'] == 3: # SimpleElastoDyn + self.read_SimpleElastoDyn(ed_file) + else: + self.read_ElastoDyn(ed_file) + if not os.path.isabs(self.fst_vt['ElastoDyn']['BldFile1']): + ed_blade_file = os.path.join(os.path.dirname(ed_file), self.fst_vt['ElastoDyn']['BldFile1']) + if self.fst_vt['Fst']['CompElast'] == 1 or os.path.isfile(ed_blade_file): # If elastodyn blade is being used OR if the blade file exists + self.read_ElastoDynBlade(ed_blade_file) + if not os.path.isabs(self.fst_vt['ElastoDyn']['TwrFile']): + ed_tower_file = os.path.join(os.path.dirname(ed_file), self.fst_vt['ElastoDyn']['TwrFile']) + self.read_ElastoDynTower(ed_tower_file) + if self.fst_vt['Fst']['CompInflow'] == 1: self.read_InflowWind() # AeroDyn version selection if self.fst_vt['Fst']['CompAero'] == 1: - self.read_AeroDyn14() + self.read_AeroDisk() elif self.fst_vt['Fst']['CompAero'] == 2: self.read_AeroDyn15() diff --git a/openfast_io/openfast_io/FAST_vars_out.py b/openfast_io/openfast_io/FAST_vars_out.py index 650e10099..8b3ac8568 100644 --- a/openfast_io/openfast_io/FAST_vars_out.py +++ b/openfast_io/openfast_io/FAST_vars_out.py @@ -9668,6 +9668,79 @@ ExtPtfm['CBF_025'] = False # - Modal force on internal Craig-Bampton mode number XXX (-) ExtPtfm['WavElev'] = False # - Wave elevation (m) +""" AeroDisk """ +AeroDisk = {} + +# All channels +AeroDisk['ADSpeed'] = False # (rpm); Actuator disk rotational speed; +AeroDisk['ADTSR'] = False # (-); Actuator disk tip-speed ratio; +AeroDisk['ADPitch'] = False # (deg); Actuator disk collective blade-pitch angle; +AeroDisk['ADVWindx'] = False # (m/s); Actuator-disk-average wind velocity; local coordinate system - X +AeroDisk['ADVWindy'] = False # (m/s); Actuator-disk-average wind velocity; local coordinate system - Y +AeroDisk['ADVWindz'] = False # (m/s); Actuator-disk-average wind velocity; local coordinate system - Z +AeroDisk['ADVWindxi'] = False # (m/s); Actuator-disk-average wind velocity; global (inertial) coordinate system - X +AeroDisk['ADVWindyi'] = False # (m/s); Actuator-disk-average wind velocity; global (inertial) coordinate system - Y +AeroDisk['ADVWindzi'] = False # (m/s); Actuator-disk-average wind velocity; global (inertial) coordinate system - Z +AeroDisk['ADSTVx'] = False # (m/s); Actuator-disk structural translation velocity; local coordinate system - X +AeroDisk['ADSTVy'] = False # (m/s); Actuator-disk structural translation velocity; local coordinate system - Y +AeroDisk['ADSTVz'] = False # (m/s); Actuator-disk structural translation velocity; local coordinate system - Z +AeroDisk['ADSTVxi'] = False # (m/s); Actuator-disk structural translation velocity; global (inertial) coordinate system - X +AeroDisk['ADSTVyi'] = False # (m/s); Actuator-disk structural translation velocity; global (inertial) coordinate system - Y +AeroDisk['ADSTVzi'] = False # (m/s); Actuator-disk structural translation velocity; global (inertial) coordinate system - Z +AeroDisk['ADVRel'] = False # (m/s); Actuator-disk -average relative wind speed; +AeroDisk['ADSkew'] = False # (deg); Actuator-disk inflow-skew angle; +AeroDisk['ADYawErr'] = False # (deg); Actuator-disk yaw-error angle; +AeroDisk['ADCp'] = False # (-); Actuator-disk coeficent of power; +AeroDisk['ADCt'] = False # (-); Actuator-disk coeficent of thrust; +AeroDisk['ADCq'] = False # (-); Actuator-disk coeficent of torque; +AeroDisk['ADFx'] = False # (N); Actuator-disk aerodynamic force; local coordinate system - X +AeroDisk['ADFy'] = False # (N); Actuator-disk aerodynamic force; local coordinate system - Y +AeroDisk['ADFz'] = False # (N); Actuator-disk aerodynamic force; local coordinate system - Z +AeroDisk['ADFxi'] = False # (N); Actuator-disk aerodynamic force; global (inertial) coordinate system - X +AeroDisk['ADFyi'] = False # (N); Actuator-disk aerodynamic force; global (inertial) coordinate system - Y +AeroDisk['ADFzi'] = False # (N); Actuator-disk aerodynamic force; global (inertial) coordinate system - Z +AeroDisk['ADMx'] = False # (N-m); Actuator-disk aerodynamic moment; local coordinate system - X +AeroDisk['ADMy'] = False # (N-m); Actuator-disk aerodynamic moment; local coordinate system - Y +AeroDisk['ADMz'] = False # (N-m); Actuator-disk aerodynamic moment; local coordinate system - Z +AeroDisk['ADMxi'] = False # (N-m); Actuator-disk aerodynamic moment; global (inertial) coordinate system - X +AeroDisk['ADMyi'] = False # (N-m); Actuator-disk aerodynamic moment; global (inertial) coordinate system - Y +AeroDisk['ADMzi'] = False # (N-m); Actuator-disk aerodynamic moment; global (inertial) coordinate system - Z +AeroDisk['ADPower'] = False # (W); Actuator-disk power; + + +""" SimpleElastoDyn """ +SimpleElastoDyn = {} + +# Outputs +SimpleElastoDyn['Azimuth'] = False # (deg); Rotor azimuth angle (position); +SimpleElastoDyn['RotSpeed'] = False # (rpm); Rotor azimuth angular speed; +SimpleElastoDyn['LSSTipVxa'] = False # (rpm); Rotor azimuth angular speed; +SimpleElastoDyn['LSSTipVxs'] = False # (rpm); Rotor azimuth angular speed; +SimpleElastoDyn['LSSTipV'] = False # (rpm); Rotor azimuth angular speed; +SimpleElastoDyn['RotAcc'] = False # (deg/s^2); Rotor azimuth angular acceleration; +SimpleElastoDyn['LSSTipAxs'] = False # (deg/s^2); Rotor azimuth angular acceleration; +SimpleElastoDyn['LSSTipA'] = False # (deg/s^2); Rotor azimuth angular acceleration; +SimpleElastoDyn['LSSTipAxa'] = False # (deg/s^2); Rotor azimuth angular acceleration; +SimpleElastoDyn['GenSpeed'] = False # (rpm); Angular speed of the high-speed shaft and generator; +SimpleElastoDyn['HSShftV'] = False # (rpm); Angular speed of the high-speed shaft and generator; +SimpleElastoDyn['GenAcc'] = False # (deg/s^2); Angular acceleration of the high-speed shaft and generator; +SimpleElastoDyn['HSShftA'] = False # (deg/s^2); Angular acceleration of the high-speed shaft and generator; +SimpleElastoDyn['Yaw'] = False # (deg); Commanded yaw position from controller; +SimpleElastoDyn['YawRate'] = False # (deg/s); commanded yaw rate from controller; + +# Blade Pitch Motions +SimpleElastoDyn['BldPitch1'] = False # (deg); Blade 1 pitch angle (position); Positive towards feather about the minus zc1- and minus zb1-axes +SimpleElastoDyn['BlPitch1'] = False # (deg); Blade 1 pitch angle (position); Positive towards feather about the minus zc1- and minus zb1-axes +SimpleElastoDyn['BldPitch2'] = False # (deg); Blade 2 pitch angle (position); Positive towards feather about the minus zc2- and minus zb2-axes +SimpleElastoDyn['BlPitch2'] = False # (deg); Blade 2 pitch angle (position); Positive towards feather about the minus zc2- and minus zb2-axes +SimpleElastoDyn['BldPitch3'] = False # (deg); Blade 3 pitch angle (position); Positive towards feather about the minus zc3- and minus zb3-axes +SimpleElastoDyn['BlPitch3'] = False # (deg); Blade 3 pitch angle (position); Positive towards feather about the minus zc3- and minus zb3-axes + +# Hub and Rotor Loads +SimpleElastoDyn['RotTorq'] = False # (kN-m); Low-speed shaft torque (this is constant along the shaft and is equivalent to the rotor torque); About the xa- and xs-axes +SimpleElastoDyn['LSShftTq'] = False # (kN-m); Low-speed shaft torque (this is constant along the shaft and is equivalent to the rotor torque); About the xa- and xs-axes +SimpleElastoDyn['RotPwr'] = False # (kW); Rotor power (this is equivalent to the low-speed shaft power); N/A +SimpleElastoDyn['LSShftPwr'] = False # (kW); Rotor power (this is equivalent to the low-speed shaft power); N/A """ Final Output Dictionary """ @@ -9687,3 +9760,5 @@ FstOutput['ElastoDyn_Nodes'] = ElastoDyn_Nodes FstOutput['MoorDyn'] = MoorDyn FstOutput['ExtPtfm'] = ExtPtfm +FstOutput['AeroDisk'] = AeroDisk +FstOutput['SimpleElastoDyn'] = SimpleElastoDyn \ No newline at end of file diff --git a/openfast_io/openfast_io/FAST_writer.py b/openfast_io/openfast_io/FAST_writer.py index a8daf36d8..5a38effa5 100644 --- a/openfast_io/openfast_io/FAST_writer.py +++ b/openfast_io/openfast_io/FAST_writer.py @@ -150,17 +150,20 @@ def execute(self): if not os.path.exists(self.FAST_runDirectory): os.makedirs(self.FAST_runDirectory) - # If elastodyn blade is being used OR if the blade file exists - if self.fst_vt['Fst']['CompElast'] == 1 or os.path.isfile(self.fst_vt['ElastoDyn']['BldFile1']): - self.write_ElastoDynBlade() + if self.fst_vt['Fst']['CompElast'] == 3: # Simplified ElastoDyn + self.write_SimpleElastoDyn() + else: + # If elastodyn blade is being used OR if the blade file exists + if self.fst_vt['Fst']['CompElast'] == 1 or os.path.isfile(self.fst_vt['ElastoDyn']['BldFile1']): + self.write_ElastoDynBlade() - self.write_ElastoDynTower() - self.write_ElastoDyn() + self.write_ElastoDynTower() + self.write_ElastoDyn() # self.write_WindWnd() if self.fst_vt['Fst']['CompInflow'] == 1: self.write_InflowWind() if self.fst_vt['Fst']['CompAero'] == 1: - self.write_AeroDyn14() + self.write_AeroDisk() elif self.fst_vt['Fst']['CompAero'] == 2: self.write_AeroDyn15() @@ -457,10 +460,108 @@ def write_ElastoDyn(self): os.fsync(f) f.close() + def write_SimpleElastoDyn(self): + ''' + Here is the format of the Simplified ElastoDyn input file: + + ------- SIMPLIFIED ELASTODYN INPUT FILE ---------------------------------------- + Test case input file for SED (not representative of any model) + ---------------------- SIMULATION CONTROL -------------------------------------- + True Echo - Echo input data to ".ech" (flag) + 3 IntMethod - Integration method: {1: RK4, 2: AB4, or 3: ABM4} (-) + "default" DT - Integration time step (s) + ---------------------- DEGREES OF FREEDOM -------------------------------------- + True GenDOF - Generator DOF (flag) + True YawDOF - Yaw degree of freedom -- controlled by controller (flag) + ---------------------- INITIAL CONDITIONS -------------------------------------- + 0 Azimuth - Initial azimuth angle for blades (degrees) + 0 BlPitch - Blades initial pitch (degrees) + 12.1 RotSpeed - Initial or fixed rotor speed (rpm) + 0 NacYaw - Initial or fixed nacelle-yaw angle (degrees) + 0 PtfmPitch - Fixed pitch tilt rotational displacement of platform (degrees) + ---------------------- TURBINE CONFIGURATION ----------------------------------- + 3 NumBl - Number of blades (-) + 63 TipRad - The distance from the rotor apex to the blade tip (meters) + 1.5 HubRad - The distance from the rotor apex to the blade root (meters) + -2.5 PreCone - Blades cone angle (degrees) + -5.0191 OverHang - Distance from yaw axis to rotor apex [3 blades] or teeter pin [2 blades] (meters) + -5 ShftTilt - Rotor shaft tilt angle (degrees) + 1.96256 Twr2Shft - Vertical distance from the tower-top to the rotor shaft (meters) + 87.6 TowerHt - Height of tower above ground level [onshore] or MSL [offshore] (meters) + ---------------------- MASS AND INERTIA ---------------------------------------- + 38677052 RotIner - Rot inertia about rotor axis [blades + hub] (kg m^2) + 534.116 GenIner - Generator inertia about HSS (kg m^2) + ---------------------- DRIVETRAIN ---------------------------------------------- + 97 GBoxRatio - Gearbox ratio (-) + ---------------------- OUTPUT -------------------------------------------------- + OutList - The next line(s) contains a list of output parameters. See OutListParameters.xlsx for a listing of available output channels, (-) + "BlPitch1" + "BlPitch2" + "BlPitch3" + "Azimuth" - Blades azimuth angle (deg) + "RotSpeed" - Low-speed shaft rotational speed (rpm) + "RotAcc" - Low-speed shaft rotational acceleration (rad/s^2) + "GenSpeed" - High-speed shaft rotational speed (rpm) + "GenAcc" - High-speed shaft rotational acceleration (rad/s^2) + "Yaw" - Commanded yaw angle + "YawRate" - Commanded yaw angle rate + "RotPwr" + "RotTorq" + END of input file (the word "END" must appear in the first 3 columns of this last OutList line) + ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + ''' + self.fst_vt['Fst']['EDFile'] = self.FAST_namingOut + '_SimpleElastoDyn.dat' + sed_file = os.path.join(self.FAST_runDirectory,self.fst_vt['Fst']['EDFile']) + f = open(sed_file, 'w') + + f.write('------- SIMPLIFIED ELASTODYN INPUT FILE ----------------------------------------\n') + f.write('Generated with OpenFAST_IO\n') + f.write('---------------------- SIMULATION CONTROL --------------------------------------\n') + f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['SimpleElastoDyn']['Echo'], 'Echo', '- Echo input data to ".ech" (flag)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['SimpleElastoDyn']['IntMethod'], 'IntMethod', '- Integration method: {1: RK4, 2: AB4, or 3: ABM4} (-)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['SimpleElastoDyn']['DT'], 'DT', '- Integration time step (s)\n')) + f.write('---------------------- DEGREES OF FREEDOM --------------------------------------\n') + f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['SimpleElastoDyn']['GenDOF'], 'GenDOF', '- Generator DOF (flag)\n')) + f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['SimpleElastoDyn']['YawDOF'], 'YawDOF', '- Yaw degree of freedom -- controlled by controller (flag)\n')) + f.write('---------------------- INITIAL CONDITIONS --------------------------------------\n') + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['SimpleElastoDyn']['Azimuth'], 'Azimuth', '- Initial azimuth angle for blades (degrees)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['SimpleElastoDyn']['BlPitch'], 'BlPitch', '- Blades initial pitch (degrees)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['SimpleElastoDyn']['RotSpeed'], 'RotSpeed', '- Initial or fixed rotor speed (rpm)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['SimpleElastoDyn']['NacYaw'], 'NacYaw', '- Initial or fixed nacelle-yaw angle (degrees)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['SimpleElastoDyn']['PtfmPitch'], 'PtfmPitch', '- Fixed pitch tilt rotational displacement of platform (degrees)\n')) + f.write('---------------------- TURBINE CONFIGURATION -----------------------------------\n') + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['SimpleElastoDyn']['NumBl'], 'NumBl', '- Number of blades (-)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['SimpleElastoDyn']['TipRad'], 'TipRad', '- The distance from the rotor apex to the blade tip (meters)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['SimpleElastoDyn']['HubRad'], 'HubRad', '- The distance from the rotor apex to the blade root (meters)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['SimpleElastoDyn']['PreCone'], 'PreCone', '- Blades cone angle (degrees)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['SimpleElastoDyn']['OverHang'], 'OverHang', '- Distance from yaw axis to rotor apex [3 blades] or teeter pin [2 blades] (meters)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['SimpleElastoDyn']['ShftTilt'], 'ShftTilt', '- Rotor shaft tilt angle (degrees)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['SimpleElastoDyn']['Twr2Shft'], 'Twr2Shft', '- Vertical distance from the tower-top to the rotor shaft (meters)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['SimpleElastoDyn']['TowerHt'], 'TowerHt', '- Height of tower above ground level [onshore] or MSL [offshore] (meters)\n')) + f.write('---------------------- MASS AND INERTIA ----------------------------------------\n') + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['SimpleElastoDyn']['RotIner'], 'RotIner', '- Rot inertia about rotor axis [blades + hub] (kg m^2)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['SimpleElastoDyn']['GenIner'], 'GenIner', '- Generator inertia about HSS (kg m^2)\n')) + f.write('---------------------- DRIVETRAIN ----------------------------------------------\n') + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['SimpleElastoDyn']['GBoxRatio'], 'GBoxRatio', '- Gearbox ratio (-)\n')) + f.write('---------------------- OUTPUT --------------------------------------------------\n') + f.write(' OutList - The next line(s) contains a list of output parameters. See OutListParameters.xlsx for a listing of available output channels, (-)\n') + + outlist = self.get_outlist(self.fst_vt['outlist'], ['SimpleElastoDyn']) + for channel_list in outlist: + for i in range(len(channel_list)): + f.write('"' + channel_list[i] + '"\n') + + f.write('END of input file (the word "END" must appear in the first 3 columns of this last OutList line)\n') + f.write('---------------------------------------------------------------------------------------\n') + + f.flush() + os.fsync(f) + f.close() + def write_ElastoDynBlade(self): self.fst_vt['ElastoDyn']['BldFile1'] = self.FAST_namingOut + '_ElastoDyn_blade.dat' - self.fst_vt['ElastoDyn']['BldFile2'] = self.fst_vt['ElastoDyn']['BldFile1'] + self.fst_vt['ElastoDyn']['BldFile2'] = self.fst_vt['ElastoDyn']['BldFile1'] # TODO: have the possibility of different blade files self.fst_vt['ElastoDyn']['BldFile3'] = self.fst_vt['ElastoDyn']['BldFile1'] blade_file = os.path.join(self.FAST_runDirectory,self.fst_vt['ElastoDyn']['BldFile1']) f = open(blade_file, 'w') @@ -1319,6 +1420,84 @@ def write_OLAF(self): os.fsync(f) f.close() + def write_AeroDisk(self): + # Writing the aeroDisk input file + '''' + example input file: + + --- AERO DISK INPUT FILE ------- + NREL 5MW actuator disk input file + --- SIMULATION CONTROL --------- + true echo - Echo input data to ".ADsk.ech" (flag) + "default" DT - Integration time step (s) + --- ENVIRONMENTAL CONDITIONS --- + 1.225 AirDens - Air density (kg/m^3) (or "default") + --- ACTUATOR DISK PROPERTIES --- + 63.0 RotorRad - Rotor radius (m) (or "default") + "TSR, RtSpd , VRel, Skew , Pitch" InColNames - Input column headers (string) {may include a combination of "TSR, RtSpd, VRel, Pitch, Skew"} (up to 4 columns) [choose TSR or RtSpd,VRel; if Skew is absent, Skew is modeled as (COS(Skew))^2] + 48, 0, 0, 0, 104 InColDims - Number of unique values in each column (-) (must have same number of columns as InColName) [each >=2] + @CpCtCq.csv + --- OUTPUTS -------------------- + OutList - The next line(s) contains a list of output parameters. See OutListParameters.xlsx for a listing of available output channels, (-) + ADSpeed ! Actuator disk rotational speed (rpm) + ADTSR ! Actuator disk tip-speed ratio (-) + ADPitch ! Actuator-disk collective blade-pitch angle (deg) + ADVWindx ! Actuator-disk-averaged wind velocity (x) in the local coordinate system (m/s) + ADVWindy ! Actuator-disk-averaged wind velocity (y) in the local coordinate system (m/s) + ADVWindz + + ''' + self.fst_vt['Fst']['AeroFile'] = self.FAST_namingOut + '_AeroDisk.dat' + adisk_file = os.path.join(self.FAST_runDirectory,self.fst_vt['Fst']['AeroFile']) + f = open(adisk_file,'w') + + f.write('--- AERO DISK INPUT FILE -------\n') + f.write('Generated with OpenFAST_IO\n') + f.write('--- SIMULATION CONTROL ---------\n') + f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDisk']['Echo'], 'Echo', '- Echo input data to ".ADsk.ech" (flag)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDisk']['DT'], 'DT', '- Integration time step (s)\n')) + f.write('--- ENVIRONMENTAL CONDITIONS ---\n') + f.write('{:<22f} {:<11} {:}'.format(self.fst_vt['AeroDisk']['AirDens'], 'AirDens', '- Air density (kg/m^3) (or "default")\n')) + f.write('--- ACTUATOR DISK PROPERTIES ---\n') + f.write('{:<22f} {:<11} {:}'.format(self.fst_vt['AeroDisk']['RotorRad'], 'RotorRad', '- Rotor radius (m) (or "default")\n')) + f.write('{:<22} {:<11} {:}'.format(', '.join(['%s'%i for i in self.fst_vt['AeroDisk']['InColNames']]), 'InColNames', '- Input column headers (string) {may include a combination of "TSR, RtSpd, VRel, Pitch, Skew"} (up to 4 columns) [choose TSR or RtSpd,VRel; if Skew is absent, Skew is modeled as (COS(Skew))^2]\n')) + f.write('{:<22} {:<11} {:}'.format(', '.join(['%s'%i for i in self.fst_vt['AeroDisk']['InColDims']]), 'InColDims', '- Number of unique values in each column (-) (must have same number of columns as InColName) [each >=2]\n')) + self.write_AeroDiskProp() + f.write('@{:<22} {:}'.format(self.fst_vt['AeroDisk']['actuatorDiskFile'], '\n')) + f.write('--- OUTPUTS --------------------\n') + f.write('{:<22} {:<11} {:}'.format('OutList', 'OutList', '- The next line(s) contains a list of output parameters. See OutListParameters.xlsx for a listing of available output channels, (-)\n')) + + outlist = self.get_outlist(self.fst_vt['outlist'], ['AeroDisk']) + for channel_list in outlist: + for i in range(len(channel_list)): + f.write('"' + channel_list[i] + '"\n') + + f.write('END of input file (the word "END" must appear in the first 3 columns of this last OutList line)\n') + f.write('---------------------------------------------------------------------------------------\n') + + f.flush() + os.fsync(f) + f.close() + + def write_AeroDiskProp(self): + # Writing the aeroDiskProp input file + + self.fst_vt['AeroDisk']['actuatorDiskFile'] = self.FAST_namingOut + '_AeroDiskProp.csv' + adiskprop_file = os.path.join(self.FAST_runDirectory,self.fst_vt['AeroDisk']['actuatorDiskFile']) + f = open(adiskprop_file,'w') + + f.write('{:<22} {:}'.format(self.fst_vt['AeroDisk']['actuatorDiskTable']['dsc'],'\n')) + f.write('{:<22} {:}'.format(', '.join(['%s'%i for i in self.fst_vt['AeroDisk']['actuatorDiskTable']['attr']]), '\n')) + f.write('{:<22} {:}'.format(', '.join(['%s'%i for i in self.fst_vt['AeroDisk']['actuatorDiskTable']['units']]), '\n')) + for idx in range(len(self.fst_vt['AeroDisk']['actuatorDiskTable']['data'])): + f.write('{:<22} {:}'.format(', '.join(['%.6f'%i for i in self.fst_vt['AeroDisk']['actuatorDiskTable']['data'][idx]]), '\n')) + + f.flush() + os.fsync(f) + f.close() + + + def write_ServoDyn(self): # ServoDyn v1.05 Input File diff --git a/openfast_io/openfast_io/create_output_vars.py b/openfast_io/openfast_io/create_output_vars.py index 2a43ddf87..9f3d43ea0 100644 --- a/openfast_io/openfast_io/create_output_vars.py +++ b/openfast_io/openfast_io/create_output_vars.py @@ -81,8 +81,22 @@ def GetOutlistParameters(fname_vars_out, xl_files_in, sheet_list, write_mode, fi root_dir = os.path.dirname(os.path.dirname( os.path.dirname( ( os.path.realpath(__file__) ) ) )) + os.sep outlist_fast_lib = os.path.join(root_dir, 'docs', 'OtherSupporting' , 'OutListParameters.xls') # Sheets to grab - sheet_list = ['AeroDyn', 'BeamDyn', 'ElastoDyn', 'InflowWind', 'ServoDyn', 'HydroDyn', 'Morison', 'SeaState', 'SubDyn', - 'AeroDyn_Nodes','BeamDyn_Nodes','ElastoDyn_Nodes'] + sheet_list = [ + 'AeroDyn', + 'BeamDyn', + 'ElastoDyn', + 'InflowWind', + 'ServoDyn', + 'HydroDyn', + 'Morison', + 'SeaState', + 'SubDyn', + 'AeroDyn_Nodes', + 'BeamDyn_Nodes', + 'ElastoDyn_Nodes', + 'AeroDisk', + 'SimpleElastoDyn', + ] xl_files = [outlist_fast_lib]*len(sheet_list) # Output naming fname_vars_out = 'FAST_vars_out.py' From bb7f142d94b64b0c557e0f10ab9a8f0cbe59181d Mon Sep 17 00:00:00 2001 From: Mayank Chetan Date: Wed, 28 Aug 2024 13:21:28 +0000 Subject: [PATCH 045/161] expanding tests to (almost) all openfast glue-code r-tests --- .../openfast_io/tests/test_of_io_pytest.py | 53 ++++++++++++++----- 1 file changed, 41 insertions(+), 12 deletions(-) diff --git a/openfast_io/openfast_io/tests/test_of_io_pytest.py b/openfast_io/openfast_io/tests/test_of_io_pytest.py index 90dd5dd90..4e8fd553c 100644 --- a/openfast_io/openfast_io/tests/test_of_io_pytest.py +++ b/openfast_io/openfast_io/tests/test_of_io_pytest.py @@ -16,18 +16,46 @@ # Exercising the various OpenFAST modules FOLDERS_TO_RUN = [ - "5MW_Land_DLL_WTurb" , # "openfast;elastodyn;aerodyn15;servodyn") - "5MW_OC3Mnpl_DLL_WTurb_WavesIrr" , # "openfast;elastodyn;aerodyn15;servodyn;hydrodyn;subdyn;offshore") - "5MW_OC3Mnpl_DLL_WTurb_WavesIrr_Restart", # "openfast;elastodyn;aerodyn15;servodyn;hydrodyn;subdyn;offshore;restart") - "5MW_ITIBarge_DLL_WTurb_WavesIrr" , # "openfast;elastodyn;aerodyn15;servodyn;hydrodyn;map;offshore") - "5MW_OC4Semi_WSt_WavesWN" , # "openfast;elastodyn;aerodyn15;servodyn;hydrodyn;moordyn;offshore") - "5MW_Land_BD_DLL_WTurb" , # "openfast;beamdyn;aerodyn15;servodyn") - "5MW_OC4Jckt_ExtPtfm" , # "openfast;elastodyn;extptfm") - "HelicalWake_OLAF" , # "openfast;aerodyn15;olaf") - "StC_test_OC4Semi" , # "openfast;servodyn;hydrodyn;moordyn;offshore;stc") - "MHK_RM1_Fixed" , # "openfast;elastodyn;aerodyn15;mhk") - "MHK_RM1_Floating" , # "openfast;elastodyn;aerodyn15;hydrodyn;moordyn;mhk") - # "Tailfin_FreeYaw1DOF_PolarBased" , # "openfast;elastodyn;aerodyn15") # lets wait for furl to be included in fst_vt + "AWT_YFix_WSt" , # "openfast;elastodyn;aerodyn;servodyn") + "AWT_WSt_StartUp_HighSpShutDown" , # "openfast;elastodyn;aerodyn;servodyn") + "AWT_YFree_WSt" , # "openfast;elastodyn;aerodyn;servodyn") + "AWT_YFree_WTurb" , # "openfast;elastodyn;aerodyn;servodyn") + "AWT_WSt_StartUpShutDown" , # "openfast;elastodyn;aerodyn;servodyn") + "AOC_WSt" , # "openfast;elastodyn;aerodyn;servodyn") + "AOC_YFree_WTurb" , # "openfast;elastodyn;aerodyn;servodyn") + "AOC_YFix_WSt" , # "openfast;elastodyn;aerodyn;servodyn") + "UAE_Dnwind_YRamp_WSt" , # "openfast;elastodyn;aerodyn;servodyn") + "UAE_Upwind_Rigid_WRamp_PwrCurve" , # "openfast;elastodyn;aerodyn;servodyn") + "WP_VSP_WTurb_PitchFail" , # "openfast;elastodyn;aerodyn;servodyn") + "WP_VSP_ECD" , # "openfast;elastodyn;aerodyn;servodyn") + "WP_VSP_WTurb" , # "openfast;elastodyn;aerodyn;servodyn") + "SWRT_YFree_VS_EDG01" , # "openfast;elastodyn;aerodyn;servodyn") + "SWRT_YFree_VS_EDC01" , # "openfast;elastodyn;aerodyn;servodyn") + "SWRT_YFree_VS_WTurb" , # "openfast;elastodyn;aerodyn;servodyn") + "5MW_Land_DLL_WTurb" , # "openfast;elastodyn;aerodyn;servodyn") + "5MW_Land_DLL_WTurb_ADsk" , + "5MW_Land_DLL_WTurb_ADsk_SED" , + "5MW_Land_DLL_WTurb_SED" , + "5MW_Land_DLL_WTurb_wNacDrag" , # "openfast;elastodyn;aerodyn;servodyn") + "5MW_OC3Mnpl_DLL_WTurb_WavesIrr" , # "openfast;elastodyn;aerodyn;servodyn;hydrodyn;subdyn;offshore") + "5MW_OC3Mnpl_DLL_WTurb_WavesIrr_Restart" , # "openfast;elastodyn;aerodyn;servodyn;hydrodyn;subdyn;offshore;restart") + "5MW_OC3Trpd_DLL_WSt_WavesReg" , # "openfast;elastodyn;aerodyn;servodyn;hydrodyn;subdyn;offshore") + "5MW_OC4Jckt_DLL_WTurb_WavesIrr_MGrowth" , # "openfast;elastodyn;aerodyn;servodyn;hydrodyn;subdyn;offshore") + "5MW_ITIBarge_DLL_WTurb_WavesIrr" , # "openfast;elastodyn;aerodyn;servodyn;hydrodyn;map;offshore") + "5MW_TLP_DLL_WTurb_WavesIrr_WavesMulti" , # "openfast;elastodyn;aerodyn;servodyn;hydrodyn;map;offshore") + "5MW_OC3Spar_DLL_WTurb_WavesIrr" , # "openfast;elastodyn;aerodyn;servodyn;hydrodyn;map;offshore") + "5MW_OC4Semi_WSt_WavesWN" , # "openfast;elastodyn;aerodyn;servodyn;hydrodyn;moordyn;offshore") + "5MW_Land_BD_DLL_WTurb" , # "openfast;beamdyn;aerodyn;servodyn") + "5MW_Land_BD_Init" , # "openfast;beamdyn;aerodyn;servodyn") + "5MW_OC4Jckt_ExtPtfm" , # "openfast;elastodyn;extptfm") + "HelicalWake_OLAF" , # "openfast;aerodyn;olaf") + "EllipticalWing_OLAF" , # "openfast;aerodyn;olaf") + "StC_test_OC4Semi" , # "openfast;servodyn;hydrodyn;moordyn;offshore;stc") + "MHK_RM1_Fixed" , # "openfast;elastodyn;aerodyn;mhk") + "MHK_RM1_Floating" , # "openfast;elastodyn;aerodyn;hydrodyn;moordyn;mhk") + "MHK_RM1_Floating_wNacDrag" , # "openfast;elastodyn;aerodyn;hydrodyn;moordyn;mhk") + "Tailfin_FreeYaw1DOF_PolarBased" , # "openfast;elastodyn;aerodyn") + "Tailfin_FreeYaw1DOF_Unsteady" , # "openfast;elastodyn;aerodyn") ] @@ -69,6 +97,7 @@ def write_action(folder, fst_vt, path_dict = getPaths()): fast_writer.fst_vt = dict(fst_vt) fst_vt = {} fst_vt['Fst', 'TMax'] = 2. + fst_vt['Fst', 'TStart'] = 0. fst_vt['Fst','OutFileFmt'] = 3 # check if the case needs ServoDyn if 'DLL_FileName' in fast_writer.fst_vt['ServoDyn']: From c546c3b174d208525c5bf8d835501434f5201c51 Mon Sep 17 00:00:00 2001 From: Mayank Chetan Date: Thu, 29 Aug 2024 04:07:19 +0000 Subject: [PATCH 046/161] arbritrary comment lines in AF files --- openfast_io/openfast_io/FAST_reader.py | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/openfast_io/openfast_io/FAST_reader.py b/openfast_io/openfast_io/FAST_reader.py index ed150fd4f..efe10823f 100644 --- a/openfast_io/openfast_io/FAST_reader.py +++ b/openfast_io/openfast_io/FAST_reader.py @@ -1326,24 +1326,24 @@ def read_AeroDyn15Coord(self): self.fst_vt['AeroDyn15']['af_coord'].append({}) if not (self.fst_vt['AeroDyn15']['af_data'][afi][0]['NumCoords'] == 0 or self.fst_vt['AeroDyn15']['af_data'][afi][0]['NumCoords'] == '0'): coord_filename = af_filename[0:af_filename.rfind(os.sep)] + os.sep + self.fst_vt['AeroDyn15']['af_data'][afi][0]['NumCoords'][2:-1] + f = open(coord_filename) - n_coords = int_read(readline_filterComments(f).split()[0]) - x = np.zeros(n_coords) - y = np.zeros(n_coords) - f.readline() - f.readline() - f.readline() - self.fst_vt['AeroDyn15']['ac'][afi] = float(f.readline().split()[0]) - f.readline() - f.readline() - f.readline() - for j in range(n_coords - 1): - x[j], y[j] = f.readline().split() + lines = f.readlines() + f.close() + lines = [line for line in lines if not line.strip().startswith('!')] + n_coords = int(lines[0].split()[0]) + + x = np.zeros(n_coords-1) + y = np.zeros(n_coords-1) + + self.fst_vt['AeroDyn15']['ac'][afi] = float(lines[1].split()[0]) + + for j in range(2, n_coords+1): + x[j - 2], y[j - 2] = map(float, lines[j].split()) self.fst_vt['AeroDyn15']['af_coord'][afi]['x'] = x self.fst_vt['AeroDyn15']['af_coord'][afi]['y'] = y - f.close() def read_AeroDyn15OLAF(self, olaf_filename): From 87893570b49463512673291b65d036ad32191d95 Mon Sep 17 00:00:00 2001 From: Mayank Chetan Date: Fri, 30 Aug 2024 22:49:51 +0000 Subject: [PATCH 047/161] adding large angle yaw & bug fix for AD15 nac yaw, thanks to @DanZ --- openfast_io/openfast_io/FAST_reader.py | 16 ++++++++++------ openfast_io/openfast_io/FAST_writer.py | 19 ++++++++++--------- .../openfast_io/tests/test_of_io_pytest.py | 6 +++--- 3 files changed, 23 insertions(+), 18 deletions(-) diff --git a/openfast_io/openfast_io/FAST_reader.py b/openfast_io/openfast_io/FAST_reader.py index efe10823f..76f75a3e6 100644 --- a/openfast_io/openfast_io/FAST_reader.py +++ b/openfast_io/openfast_io/FAST_reader.py @@ -1111,9 +1111,9 @@ def read_AeroDyn15(self): # 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('NacCenB')[0].split(',')] - self.fst_vt['AeroDyn15']['NacCd'] = [idx.strip() for idx in f.readline().split('NacCenB')[0].split(',')] - self.fst_vt['AeroDyn15']['NacDragAC'] = [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] @@ -1987,6 +1987,10 @@ 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]) @@ -2446,7 +2450,7 @@ def read_SubDyn(self, sd_file): self.fst_vt['SubDyn']['SDdeltaT'] = float_read(f.readline().split()[0]) self.fst_vt['SubDyn']['IntMethod'] = int_read(f.readline().split()[0]) self.fst_vt['SubDyn']['SttcSolve'] = bool_read(f.readline().split()[0]) - self.fst_vt['SubDyn']['GuyanLoadCorrection'] = bool_read(f.readline().split()[0]) + # self.fst_vt['SubDyn']['GuyanLoadCorrection'] = bool_read(f.readline().split()[0]) f.readline() # FEA and CRAIG-BAMPTON PARAMETERS self.fst_vt['SubDyn']['FEMMod'] = int_read(f.readline().split()[0]) @@ -3165,8 +3169,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])) diff --git a/openfast_io/openfast_io/FAST_writer.py b/openfast_io/openfast_io/FAST_writer.py index 5a38effa5..8e36871f1 100644 --- a/openfast_io/openfast_io/FAST_writer.py +++ b/openfast_io/openfast_io/FAST_writer.py @@ -692,9 +692,6 @@ def write_BeamDyn(self): f.write(int_default_out(self.fst_vt['BeamDyn']['load_retries']) + ' {:<11} {:}'.format('load_retries', '- Number of factored load retries before quitting the aimulation [DEFAULT = 20]\n')) f.write(int_default_out(self.fst_vt['BeamDyn']['NRMax']) + ' {:<11} {:}'.format('NRMax', '- Max number of iterations in Newton-Ralphson algorithm (-). DEFAULT = 10\n')) f.write(float_default_out(self.fst_vt['BeamDyn']['stop_tol']) + ' {:<11} {:}'.format('stop_tol', '- Tolerance for stopping criterion (-) [DEFAULT = 1E-5]\n')) - print('----------') - print(self.fst_vt['BeamDyn']['tngt_stf_fd'], type(self.fst_vt['BeamDyn']['tngt_stf_fd'])) - f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['BeamDyn']['tngt_stf_fd'], 'tngt_stf_fd', '- Use finite differenced tangent stiffness matrix? (flag)\n')) f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['BeamDyn']['tngt_stf_comp'], 'tngt_stf_comp', '- Compare analytical finite differenced tangent stiffness matrix? (flag)\n')) f.write(float_default_out(self.fst_vt['BeamDyn']['tngt_stf_pert']) + ' {:<11} {:}'.format('tngt_stf_pert', '- Perturbation size for finite differencing (-) [DEFAULT = 1E-6]\n')) @@ -978,9 +975,9 @@ def write_AeroDyn15(self): f.write('====== Nacelle Properties ========================================================================== used only when Buoyancy=True or NacelleDrag=True]\n') f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['VolNac'], 'VolNac', '- Nacelle volume (m^3)\n')) f.write('{:<22} {:<11} {:}'.format(', '.join(np.array(self.fst_vt['AeroDyn15']['NacCenB'], dtype=str)), 'NacCenB', '- Position of nacelle center of buoyancy from yaw bearing in nacelle coordinates (m)\n')) - f.write('{:<22} {:<11} {:}'.format(', '.join(np.array(self.fst_vt['AeroDyn15']['NacCenB'], dtype=str)), 'NacArea', '- Projected area of the nacelle in X, Y, Z in the nacelle coordinate system (m^2)\n')) - f.write('{:<22} {:<11} {:}'.format(', '.join(np.array(self.fst_vt['AeroDyn15']['NacCenB'], dtype=str)), 'NacCd', '- Drag coefficient for the nacelle areas defined above (-)\n')) - f.write('{:<22} {:<11} {:}'.format(', '.join(np.array(self.fst_vt['AeroDyn15']['NacCenB'], dtype=str)), 'NacDragAC', '- Position of aerodynamic center of nacelle drag in nacelle coordinates (m)\n')) + f.write('{:<22} {:<11} {:}'.format(', '.join(np.array(self.fst_vt['AeroDyn15']['NacArea'], dtype=str)), 'NacArea', '- Projected area of the nacelle in X, Y, Z in the nacelle coordinate system (m^2)\n')) + f.write('{:<22} {:<11} {:}'.format(', '.join(np.array(self.fst_vt['AeroDyn15']['NacCd'], dtype=str)), 'NacCd', '- Drag coefficient for the nacelle areas defined above (-)\n')) + f.write('{:<22} {:<11} {:}'.format(', '.join(np.array(self.fst_vt['AeroDyn15']['NacDragAC'], dtype=str)), 'NacDragAC', '- Position of aerodynamic center of nacelle drag in nacelle coordinates (m)\n')) f.write('====== Tail Fin Aerodynamics ========================================================================\n') f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['TFinAero'], 'TFinAero', '- Calculate tail fin aerodynamics model (flag)\n')) f.write('{:<22} {:<11} {:}'.format('"'+self.fst_vt['AeroDyn15']['TFinFile']+'"', 'TFinFile', '- Input file for tail fin aerodynamics [used only when TFinAero=True]\n')) @@ -1693,6 +1690,10 @@ def write_HydroDyn(self): f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['HydroDyn']['ExctnMod'], 'ExctnMod', '- Wave Excitation model {0: None, 1: DFT, 2: state-space} (switch) [only used when PotMod=1; STATE-SPACE REQUIRES *.ssexctn INPUT FILE]\n')) f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['HydroDyn']['ExctnDisp'], 'ExctnDisp','- Method of computing Wave Excitation {0: use undisplaced position, 1: use displaced position, 2: use low-pass filtered displaced position) [only used when PotMod=1 and ExctnMod>0 and SeaState\'s WaveMod>0]} (switch)\n')) f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['HydroDyn']['ExctnCutOff'], 'ExctnCutOff','- Method of computing Wave Excitation {0: use undisplaced position, 1: use displaced position, 2: use low-pass filtered displaced position) [only used when PotMod=1 and ExctnMod>0 and SeaState\'s WaveMod>0]} (switch)\n')) + f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['HydroDyn']['PtfmYMod'], 'PtfmYMod', '- - Model for large platform yaw offset {0: Static reference yaw offset based on PtfmRefY, 1: dynamic reference yaw offset based on low-pass filtering the PRP yaw motion with cutoff frequency PtfmYCutOff} (switch)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['HydroDyn']['PtfmRefY'], 'PtfmRefY', '- Constant (if PtfmYMod=0) or initial (if PtfmYMod=1) platform reference yaw offset (deg)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['HydroDyn']['PtfmYCutOff'], 'PtfmYCutOff', '- Cutoff frequency for the low-pass filtering of PRP yaw motion when PtfmYMod=1 [unused when PtfmYMod=0] (Hz)\n')) + f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['HydroDyn']['NExctnHdg'], 'NExctnHdg', '- Number of evenly distributed platform yaw/heading angles over the range of [-180, 180) deg for which the wave excitation shall be computed [only used when PtfmYMod=1] (-)\n')) f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['HydroDyn']['RdtnMod'], 'RdtnMod', '- Radiation memory-effect model {0: no memory-effect calculation, 1: convolution, 2: state-space} (switch) [only used when PotMod=1; STATE-SPACE REQUIRES *.ss INPUT FILE]\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['HydroDyn']['RdtnTMax'], 'RdtnTMax', '- Analysis time for wave radiation kernel calculations (sec) [only used when PotMod=1; determines RdtnDOmega=Pi/RdtnTMax in the cosine transform; MAKE SURE THIS IS LONG ENOUGH FOR THE RADIATION IMPULSE RESPONSE FUNCTIONS TO DECAY TO NEAR-ZERO FOR THE GIVEN PLATFORM!]\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['HydroDyn']['RdtnDT'], 'RdtnDT', '- Time step for wave radiation kernel calculations (sec) [only used when PotMod=1; DT<=RdtnDT<=0.1 recommended; determines RdtnOmegaMax=Pi/RdtnDT in the cosine transform]\n')) @@ -2065,7 +2066,7 @@ def write_SubDyn(self): f.write('{:<22} {:<11} {:}'.format(self.fst_vt['SubDyn']['SDdeltaT'], 'SDdeltaT', '- Local Integration Step. If "default", the glue-code integration step will be used.\n')) f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['SubDyn']['IntMethod'], 'IntMethod', '- Integration Method [1/2/3/4 = RK4/AB4/ABM4/AM2].\n')) f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['SubDyn']['SttcSolve'], 'SttcSolve', '- Solve dynamics about static equilibrium point\n')) - f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['SubDyn']['GuyanLoadCorrection'], 'GuyanLoadCorrection', '- Include extra moment from lever arm at interface and rotate FEM for floating.\n')) + # f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['SubDyn']['GuyanLoadCorrection'], 'GuyanLoadCorrection', '- Include extra moment from lever arm at interface and rotate FEM for floating.\n')) f.write('-------------------- FEA and CRAIG-BAMPTON PARAMETERS---------------------------\n') f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['SubDyn']['FEMMod'], 'FEMMod', '- FEM switch: element model in the FEM. [1= Euler-Bernoulli(E-B); 2=Tapered E-B (unavailable); 3= 2-node Timoshenko; 4= 2-node tapered Timoshenko (unavailable)]\n')) f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['SubDyn']['NDiv'], 'NDiv', '- Number of sub-elements per member\n')) @@ -2554,8 +2555,8 @@ def write_MoorDyn(self): ln = [] ln.append('{:^11d}'.format(self.fst_vt['MoorDyn']['Line_ID'][i])) ln.append('{:^11}'.format(self.fst_vt['MoorDyn']['LineType'][i])) - ln.append('{:^11d}'.format(self.fst_vt['MoorDyn']['AttachA'][i])) - ln.append('{:^11d}'.format(self.fst_vt['MoorDyn']['AttachB'][i])) + ln.append('{:^11}'.format(self.fst_vt['MoorDyn']['AttachA'][i])) + ln.append('{:^11}'.format(self.fst_vt['MoorDyn']['AttachB'][i])) ln.append('{:^11.4f}'.format(self.fst_vt['MoorDyn']['UnstrLen'][i])) ln.append('{:^11d}'.format(self.fst_vt['MoorDyn']['NumSegs'][i])) ln.append('{:^11}'.format(self.fst_vt['MoorDyn']['Outputs'][i])) diff --git a/openfast_io/openfast_io/tests/test_of_io_pytest.py b/openfast_io/openfast_io/tests/test_of_io_pytest.py index 4e8fd553c..eb9fb1ba0 100644 --- a/openfast_io/openfast_io/tests/test_of_io_pytest.py +++ b/openfast_io/openfast_io/tests/test_of_io_pytest.py @@ -33,9 +33,9 @@ "SWRT_YFree_VS_EDC01" , # "openfast;elastodyn;aerodyn;servodyn") "SWRT_YFree_VS_WTurb" , # "openfast;elastodyn;aerodyn;servodyn") "5MW_Land_DLL_WTurb" , # "openfast;elastodyn;aerodyn;servodyn") - "5MW_Land_DLL_WTurb_ADsk" , - "5MW_Land_DLL_WTurb_ADsk_SED" , - "5MW_Land_DLL_WTurb_SED" , + # "5MW_Land_DLL_WTurb_ADsk" , + # "5MW_Land_DLL_WTurb_ADsk_SED" , + # "5MW_Land_DLL_WTurb_SED" , "5MW_Land_DLL_WTurb_wNacDrag" , # "openfast;elastodyn;aerodyn;servodyn") "5MW_OC3Mnpl_DLL_WTurb_WavesIrr" , # "openfast;elastodyn;aerodyn;servodyn;hydrodyn;subdyn;offshore") "5MW_OC3Mnpl_DLL_WTurb_WavesIrr_Restart" , # "openfast;elastodyn;aerodyn;servodyn;hydrodyn;subdyn;offshore;restart") From c76641415fc0ca132d073f4a0489992fb55da797 Mon Sep 17 00:00:00 2001 From: Mayank Chetan Date: Tue, 3 Sep 2024 18:57:15 +0000 Subject: [PATCH 048/161] remove AD14, change AeroDyn15 --> AeroDyn, and some cleanup --- openfast_io/openfast_io/FAST_reader.py | 534 +++++------------ openfast_io/openfast_io/FAST_writer.py | 607 +++++++------------- openfast_io/openfast_io/tests/test_of_io.py | 2 +- 3 files changed, 354 insertions(+), 789 deletions(-) diff --git a/openfast_io/openfast_io/FAST_reader.py b/openfast_io/openfast_io/FAST_reader.py index 76f75a3e6..ae64daafc 100644 --- a/openfast_io/openfast_io/FAST_reader.py +++ b/openfast_io/openfast_io/FAST_reader.py @@ -107,7 +107,7 @@ def __init__(self): self.fst_vt['ElastoDynBlade'] = {} self.fst_vt['ElastoDynTower'] = {} self.fst_vt['InflowWind'] = {} - self.fst_vt['AeroDyn15'] = {} + self.fst_vt['AeroDyn'] = {} self.fst_vt['AeroDyn14'] = {} self.fst_vt['AeroDisk'] = {} self.fst_vt['AeroDynBlade'] = {} @@ -526,55 +526,6 @@ def read_ElastoDyn(self, ed_file): def read_SimpleElastoDyn(self, sed_file): # Read the Simplified ElastoDyn input file - ''' - Here is the format of the Simplified ElastoDyn input file: - - ------- SIMPLIFIED ELASTODYN INPUT FILE ---------------------------------------- - Test case input file for SED (not representative of any model) - ---------------------- SIMULATION CONTROL -------------------------------------- - True Echo - Echo input data to ".ech" (flag) - 3 IntMethod - Integration method: {1: RK4, 2: AB4, or 3: ABM4} (-) - "default" DT - Integration time step (s) - ---------------------- DEGREES OF FREEDOM -------------------------------------- - True GenDOF - Generator DOF (flag) - True YawDOF - Yaw degree of freedom -- controlled by controller (flag) - ---------------------- INITIAL CONDITIONS -------------------------------------- - 0 Azimuth - Initial azimuth angle for blades (degrees) - 0 BlPitch - Blades initial pitch (degrees) - 12.1 RotSpeed - Initial or fixed rotor speed (rpm) - 0 NacYaw - Initial or fixed nacelle-yaw angle (degrees) - 0 PtfmPitch - Fixed pitch tilt rotational displacement of platform (degrees) - ---------------------- TURBINE CONFIGURATION ----------------------------------- - 3 NumBl - Number of blades (-) - 63 TipRad - The distance from the rotor apex to the blade tip (meters) - 1.5 HubRad - The distance from the rotor apex to the blade root (meters) - -2.5 PreCone - Blades cone angle (degrees) - -5.0191 OverHang - Distance from yaw axis to rotor apex [3 blades] or teeter pin [2 blades] (meters) - -5 ShftTilt - Rotor shaft tilt angle (degrees) - 1.96256 Twr2Shft - Vertical distance from the tower-top to the rotor shaft (meters) - 87.6 TowerHt - Height of tower above ground level [onshore] or MSL [offshore] (meters) - ---------------------- MASS AND INERTIA ---------------------------------------- - 38677052 RotIner - Rot inertia about rotor axis [blades + hub] (kg m^2) - 534.116 GenIner - Generator inertia about HSS (kg m^2) - ---------------------- DRIVETRAIN ---------------------------------------------- - 97 GBoxRatio - Gearbox ratio (-) - ---------------------- OUTPUT -------------------------------------------------- - OutList - The next line(s) contains a list of output parameters. See OutListParameters.xlsx for a listing of available output channels, (-) - "BlPitch1" - "BlPitch2" - "BlPitch3" - "Azimuth" - Blades azimuth angle (deg) - "RotSpeed" - Low-speed shaft rotational speed (rpm) - "RotAcc" - Low-speed shaft rotational acceleration (rad/s^2) - "GenSpeed" - High-speed shaft rotational speed (rpm) - "GenAcc" - High-speed shaft rotational acceleration (rad/s^2) - "Yaw" - Commanded yaw angle - "YawRate" - Commanded yaw angle rate - "RotPwr" - "RotTorq" - END of input file (the word "END" must appear in the first 3 columns of this last OutList line) - ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - ''' f = open(sed_file) f.readline() @@ -994,7 +945,7 @@ def read_InflowWind(self): f.close() - def read_AeroDyn15(self): + def read_AeroDyn(self): # AeroDyn v15.03 ad_file = os.path.join(self.FAST_directory, self.fst_vt['Fst']['AeroFile']) @@ -1004,148 +955,148 @@ def read_AeroDyn15(self): f.readline() f.readline() f.readline() - 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']['Wake_Mod'] = 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']['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] + self.fst_vt['AeroDyn']['Echo'] = bool_read(f.readline().split()[0]) + self.fst_vt['AeroDyn']['DTAero'] = float_read(f.readline().split()[0]) + self.fst_vt['AeroDyn']['Wake_Mod'] = int(f.readline().split()[0]) + self.fst_vt['AeroDyn']['TwrPotent'] = int(f.readline().split()[0]) + self.fst_vt['AeroDyn']['TwrShadow'] = int(f.readline().split()[0]) + self.fst_vt['AeroDyn']['TwrAero'] = bool_read(f.readline().split()[0]) + self.fst_vt['AeroDyn']['CavitCheck'] = bool_read(f.readline().split()[0]) + self.fst_vt['AeroDyn']['Buoyancy'] = bool_read(f.readline().split()[0]) + self.fst_vt['AeroDyn']['NacelleDrag'] = bool_read(f.readline().split()[0]) + self.fst_vt['AeroDyn']['CompAA'] = bool_read(f.readline().split()[0]) + self.fst_vt['AeroDyn']['AA_InputFile'] = f.readline().split()[0] # Environmental Conditions f.readline() - self.fst_vt['AeroDyn15']['AirDens'] = float_read(f.readline().split()[0]) - self.fst_vt['AeroDyn15']['KinVisc'] = float_read(f.readline().split()[0]) - self.fst_vt['AeroDyn15']['SpdSound'] = float_read(f.readline().split()[0]) - self.fst_vt['AeroDyn15']['Patm'] = float_read(f.readline().split()[0]) - self.fst_vt['AeroDyn15']['Pvap'] = float_read(f.readline().split()[0]) - #self.fst_vt['AeroDyn15']['FluidDepth'] = float_read(f.readline().split()[0]) + self.fst_vt['AeroDyn']['AirDens'] = float_read(f.readline().split()[0]) + self.fst_vt['AeroDyn']['KinVisc'] = float_read(f.readline().split()[0]) + self.fst_vt['AeroDyn']['SpdSound'] = float_read(f.readline().split()[0]) + self.fst_vt['AeroDyn']['Patm'] = float_read(f.readline().split()[0]) + self.fst_vt['AeroDyn']['Pvap'] = float_read(f.readline().split()[0]) + #self.fst_vt['AeroDyn']['FluidDepth'] = float_read(f.readline().split()[0]) f.readline() - self.fst_vt['AeroDyn15']['BEM_Mod'] = int(f.readline().split()[0]) + self.fst_vt['AeroDyn']['BEM_Mod'] = int(f.readline().split()[0]) # Blade-Element/Momentum Theory Options f.readline() - self.fst_vt['AeroDyn15']['Skew_Mod'] = 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]) + self.fst_vt['AeroDyn']['Skew_Mod'] = int_read(f.readline().split()[0]) + self.fst_vt['AeroDyn']['SkewMomCorr'] = bool_read(f.readline().split()[0]) + self.fst_vt['AeroDyn']['SkewRedistr_Mod'] = int_read(f.readline().split()[0]) + self.fst_vt['AeroDyn']['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]) + self.fst_vt['AeroDyn']['TipLoss'] = bool_read(f.readline().split()[0]) + self.fst_vt['AeroDyn']['HubLoss'] = bool_read(f.readline().split()[0]) + self.fst_vt['AeroDyn']['TanInd'] = bool_read(f.readline().split()[0]) + self.fst_vt['AeroDyn']['AIDrag'] = bool_read(f.readline().split()[0]) + self.fst_vt['AeroDyn']['TIDrag'] = bool_read(f.readline().split()[0]) + self.fst_vt['AeroDyn']['IndToler'] = float_read(f.readline().split()[0]) + self.fst_vt['AeroDyn']['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]) + self.fst_vt['AeroDyn']['SectAvg'] = bool_read(f.readline().split()[0]) + self.fst_vt['AeroDyn']['SectAvgWeighting'] = int_read(f.readline().split()[0]) + self.fst_vt['AeroDyn']['SectAvgNPoints'] = int_read(f.readline().split()[0]) + self.fst_vt['AeroDyn']['SectAvgPsiBwd'] = float_read(f.readline().split()[0]) + self.fst_vt['AeroDyn']['SectAvgPsiFwd'] = float_read(f.readline().split()[0]) # Dynamic Blade-Element/Momentum Theory Options f.readline() - self.fst_vt['AeroDyn15']['DBEMT_Mod'] = int(f.readline().split()[0]) - self.fst_vt['AeroDyn15']['tau1_const'] = float_read(f.readline().split()[0]) + self.fst_vt['AeroDyn']['DBEMT_Mod'] = int(f.readline().split()[0]) + self.fst_vt['AeroDyn']['tau1_const'] = float_read(f.readline().split()[0]) # Olaf -- cOnvecting LAgrangian Filaments (Free Vortex Wake) Theory Options f.readline() - self.fst_vt['AeroDyn15']['OLAFInputFileName'] = f.readline().split()[0][1:-1] + self.fst_vt['AeroDyn']['OLAFInputFileName'] = f.readline().split()[0][1:-1] # Unsteady Airfoil Aerodynamics Options f.readline() - self.fst_vt['AeroDyn15']['AoA34'] = bool_read(f.readline().split()[0]) - self.fst_vt['AeroDyn15']['UA_Mod'] = int(f.readline().split()[0]) - self.fst_vt['AeroDyn15']['FLookup'] = bool_read(f.readline().split()[0]) - self.fst_vt['AeroDyn15']['IntegrationMethod'] = int(f.readline().split()[0]) + self.fst_vt['AeroDyn']['AoA34'] = bool_read(f.readline().split()[0]) + self.fst_vt['AeroDyn']['UA_Mod'] = int(f.readline().split()[0]) + self.fst_vt['AeroDyn']['FLookup'] = bool_read(f.readline().split()[0]) + self.fst_vt['AeroDyn']['IntegrationMethod'] = int(f.readline().split()[0]) file_pos = f.tell() line = f.readline() if 'UAStartRad' in line: - self.fst_vt['AeroDyn15']['UAStartRad'] = float_read(line.split()[0]) + self.fst_vt['AeroDyn']['UAStartRad'] = float_read(line.split()[0]) else: f.seek(file_pos) file_pos = f.tell() line = f.readline() if 'UAEndRad' in line: - self.fst_vt['AeroDyn15']['UAEndRad'] = float_read(line.split()[0]) + self.fst_vt['AeroDyn']['UAEndRad'] = float_read(line.split()[0]) else: f.seek(file_pos) # Airfoil Information f.readline() - self.fst_vt['AeroDyn15']['AFTabMod'] = int(f.readline().split()[0]) - self.fst_vt['AeroDyn15']['InCol_Alfa'] = int(f.readline().split()[0]) - self.fst_vt['AeroDyn15']['InCol_Cl'] = int(f.readline().split()[0]) - self.fst_vt['AeroDyn15']['InCol_Cd'] = int(f.readline().split()[0]) - self.fst_vt['AeroDyn15']['InCol_Cm'] = int(f.readline().split()[0]) - self.fst_vt['AeroDyn15']['InCol_Cpmin'] = int(f.readline().split()[0]) - self.fst_vt['AeroDyn15']['NumAFfiles'] = int(f.readline().split()[0]) - self.fst_vt['AeroDyn15']['AFNames'] = [None] * self.fst_vt['AeroDyn15']['NumAFfiles'] - for i in range(self.fst_vt['AeroDyn15']['NumAFfiles']): + self.fst_vt['AeroDyn']['AFTabMod'] = int(f.readline().split()[0]) + self.fst_vt['AeroDyn']['InCol_Alfa'] = int(f.readline().split()[0]) + self.fst_vt['AeroDyn']['InCol_Cl'] = int(f.readline().split()[0]) + self.fst_vt['AeroDyn']['InCol_Cd'] = int(f.readline().split()[0]) + self.fst_vt['AeroDyn']['InCol_Cm'] = int(f.readline().split()[0]) + self.fst_vt['AeroDyn']['InCol_Cpmin'] = int(f.readline().split()[0]) + self.fst_vt['AeroDyn']['NumAFfiles'] = int(f.readline().split()[0]) + self.fst_vt['AeroDyn']['AFNames'] = [None] * self.fst_vt['AeroDyn']['NumAFfiles'] + for i in range(self.fst_vt['AeroDyn']['NumAFfiles']): af_filename = fix_path(f.readline().split()[0])[1:-1] - self.fst_vt['AeroDyn15']['AFNames'][i] = os.path.abspath(os.path.join(self.FAST_directory, self.fst_vt['Fst']['AeroFile_path'], af_filename)) + self.fst_vt['AeroDyn']['AFNames'][i] = os.path.abspath(os.path.join(self.FAST_directory, self.fst_vt['Fst']['AeroFile_path'], af_filename)) # Rotor/Blade Properties f.readline() - self.fst_vt['AeroDyn15']['UseBlCm'] = bool_read(f.readline().split()[0]) - self.fst_vt['AeroDyn15']['ADBlFile1'] = f.readline().split()[0][1:-1] - self.fst_vt['AeroDyn15']['ADBlFile2'] = f.readline().split()[0][1:-1] - self.fst_vt['AeroDyn15']['ADBlFile3'] = f.readline().split()[0][1:-1] + self.fst_vt['AeroDyn']['UseBlCm'] = bool_read(f.readline().split()[0]) + self.fst_vt['AeroDyn']['ADBlFile1'] = f.readline().split()[0][1:-1] + self.fst_vt['AeroDyn']['ADBlFile2'] = f.readline().split()[0][1:-1] + self.fst_vt['AeroDyn']['ADBlFile3'] = f.readline().split()[0][1:-1] # Hub, nacelle, and tail fin aerodynamics f.readline() - self.fst_vt['AeroDyn15']['VolHub'] = float_read(f.readline().split()[0]) - self.fst_vt['AeroDyn15']['HubCenBx'] = float_read(f.readline().split()[0]) + self.fst_vt['AeroDyn']['VolHub'] = float_read(f.readline().split()[0]) + self.fst_vt['AeroDyn']['HubCenBx'] = float_read(f.readline().split()[0]) f.readline() - self.fst_vt['AeroDyn15']['VolNac'] = float_read(f.readline().split()[0]) + self.fst_vt['AeroDyn']['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['AeroDyn']['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(',')] + self.fst_vt['AeroDyn']['NacArea'] = [idx.strip() for idx in f.readline().split('NacArea')[0].split(',')] + self.fst_vt['AeroDyn']['NacCd'] = [idx.strip() for idx in f.readline().split('NacCd')[0].split(',')] + self.fst_vt['AeroDyn']['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]) + self.fst_vt['AeroDyn']['TFinAero'] = bool_read(f.readline().split()[0]) tfa_filename = fix_path(f.readline().split()[0])[1:-1] - self.fst_vt['AeroDyn15']['TFinFile'] = os.path.abspath(os.path.join(self.FAST_directory, tfa_filename)) + self.fst_vt['AeroDyn']['TFinFile'] = os.path.abspath(os.path.join(self.FAST_directory, tfa_filename)) # Tower Influence and Aerodynamics f.readline() - self.fst_vt['AeroDyn15']['NumTwrNds'] = int(f.readline().split()[0]) + self.fst_vt['AeroDyn']['NumTwrNds'] = int(f.readline().split()[0]) f.readline() f.readline() - self.fst_vt['AeroDyn15']['TwrElev'] = [None]*self.fst_vt['AeroDyn15']['NumTwrNds'] - self.fst_vt['AeroDyn15']['TwrDiam'] = [None]*self.fst_vt['AeroDyn15']['NumTwrNds'] - self.fst_vt['AeroDyn15']['TwrCd'] = [None]*self.fst_vt['AeroDyn15']['NumTwrNds'] - self.fst_vt['AeroDyn15']['TwrTI'] = [None]*self.fst_vt['AeroDyn15']['NumTwrNds'] - self.fst_vt['AeroDyn15']['TwrCb'] = [None]*self.fst_vt['AeroDyn15']['NumTwrNds'] - for i in range(self.fst_vt['AeroDyn15']['NumTwrNds']): + self.fst_vt['AeroDyn']['TwrElev'] = [None]*self.fst_vt['AeroDyn']['NumTwrNds'] + self.fst_vt['AeroDyn']['TwrDiam'] = [None]*self.fst_vt['AeroDyn']['NumTwrNds'] + self.fst_vt['AeroDyn']['TwrCd'] = [None]*self.fst_vt['AeroDyn']['NumTwrNds'] + self.fst_vt['AeroDyn']['TwrTI'] = [None]*self.fst_vt['AeroDyn']['NumTwrNds'] + self.fst_vt['AeroDyn']['TwrCb'] = [None]*self.fst_vt['AeroDyn']['NumTwrNds'] + for i in range(self.fst_vt['AeroDyn']['NumTwrNds']): data = [float(val) for val in f.readline().split()] - self.fst_vt['AeroDyn15']['TwrElev'][i] = data[0] - self.fst_vt['AeroDyn15']['TwrDiam'][i] = data[1] - self.fst_vt['AeroDyn15']['TwrCd'][i] = data[2] - self.fst_vt['AeroDyn15']['TwrTI'][i] = data[3] - self.fst_vt['AeroDyn15']['TwrCb'][i] = data[4] + self.fst_vt['AeroDyn']['TwrElev'][i] = data[0] + self.fst_vt['AeroDyn']['TwrDiam'][i] = data[1] + self.fst_vt['AeroDyn']['TwrCd'][i] = data[2] + self.fst_vt['AeroDyn']['TwrTI'][i] = data[3] + self.fst_vt['AeroDyn']['TwrCb'][i] = data[4] # Outputs f.readline() - self.fst_vt['AeroDyn15']['SumPrint'] = bool_read(f.readline().split()[0]) - self.fst_vt['AeroDyn15']['NBlOuts'] = int(f.readline().split()[0]) - self.fst_vt['AeroDyn15']['BlOutNd'] = [idx.strip() for idx in f.readline().split('BlOutNd')[0].split(',')] - self.fst_vt['AeroDyn15']['NTwOuts'] = int(f.readline().split()[0]) - self.fst_vt['AeroDyn15']['TwOutNd'] = [idx.strip() for idx in f.readline().split('TwOutNd')[0].split(',')] + self.fst_vt['AeroDyn']['SumPrint'] = bool_read(f.readline().split()[0]) + self.fst_vt['AeroDyn']['NBlOuts'] = int(f.readline().split()[0]) + self.fst_vt['AeroDyn']['BlOutNd'] = [idx.strip() for idx in f.readline().split('BlOutNd')[0].split(',')] + self.fst_vt['AeroDyn']['NTwOuts'] = int(f.readline().split()[0]) + self.fst_vt['AeroDyn']['TwOutNd'] = [idx.strip() for idx in f.readline().split('TwOutNd')[0].split(',')] - # AeroDyn15 Outlist + # AeroDyn Outlist f.readline() data = f.readline() @@ -1167,11 +1118,11 @@ def read_AeroDyn15(self): self.set_outlist(self.fst_vt['outlist']['AeroDyn'], channel_list) data = f.readline() - # AeroDyn15 optional outlist + # AeroDyn optional outlist try: f.readline() - self.fst_vt['AeroDyn15']['BldNd_BladesOut'] = int(f.readline().split()[0]) - self.fst_vt['AeroDyn15']['BldNd_BlOutNd'] = f.readline().split()[0] + self.fst_vt['AeroDyn']['BldNd_BladesOut'] = int(f.readline().split()[0]) + self.fst_vt['AeroDyn']['BldNd_BlOutNd'] = f.readline().split()[0] f.readline() data = f.readline() @@ -1193,17 +1144,17 @@ def read_AeroDyn15(self): f.close() - self.read_AeroDyn15Blade() - self.read_AeroDyn15Polar() - self.read_AeroDyn15Coord() - olaf_filename = os.path.join(self.FAST_directory, self.fst_vt['AeroDyn15']['OLAFInputFileName']) + self.read_AeroDynBlade() + self.read_AeroDynPolar() + self.read_AeroDynCoord() + olaf_filename = os.path.join(self.FAST_directory, self.fst_vt['AeroDyn']['OLAFInputFileName']) if os.path.isfile(olaf_filename): - self.read_AeroDyn15OLAF(olaf_filename) + self.read_AeroDynOLAF(olaf_filename) - def read_AeroDyn15Blade(self): + def read_AeroDynBlade(self): # AeroDyn v5.00 Blade Definition File - ad_blade_file = os.path.join(self.FAST_directory, self.fst_vt['Fst']['AeroFile_path'], self.fst_vt['AeroDyn15']['ADBlFile1']) + ad_blade_file = os.path.join(self.FAST_directory, self.fst_vt['Fst']['AeroFile_path'], self.fst_vt['AeroDyn']['ADBlFile1']) f = open(ad_blade_file) f.readline() @@ -1232,13 +1183,13 @@ def read_AeroDyn15Blade(self): f.close() - def read_AeroDyn15Polar(self): + def read_AeroDynPolar(self): # AirfoilInfo v1.01 - self.fst_vt['AeroDyn15']['af_data'] = [None]*self.fst_vt['AeroDyn15']['NumAFfiles'] + self.fst_vt['AeroDyn']['af_data'] = [None]*self.fst_vt['AeroDyn']['NumAFfiles'] - for afi, af_filename in enumerate(self.fst_vt['AeroDyn15']['AFNames']): + for afi, af_filename in enumerate(self.fst_vt['AeroDyn']['AFNames']): f = open(af_filename) # print af_filename @@ -1249,7 +1200,7 @@ def read_AeroDyn15Polar(self): polar['NumCoords'] = readline_filterComments(f).split()[0] polar['BL_file'] = readline_filterComments(f).split()[0] polar['NumTabs'] = int_read(readline_filterComments(f).split()[0]) - self.fst_vt['AeroDyn15']['af_data'][afi] = [None]*polar['NumTabs'] + self.fst_vt['AeroDyn']['af_data'][afi] = [None]*polar['NumTabs'] for tab in range(polar['NumTabs']): # For multiple tables polar['Re'] = float_read(readline_filterComments(f).split()[0]) * 1.e+6 @@ -1302,30 +1253,30 @@ def read_AeroDyn15Polar(self): polar['Cpmin'] = [None]*polar['NumAlf'] for i in range(polar['NumAlf']): data = [float(val) for val in readline_filterComments(f).split()] - if self.fst_vt['AeroDyn15']['InCol_Alfa'] > 0: - polar['Alpha'][i] = data[self.fst_vt['AeroDyn15']['InCol_Alfa']-1] - if self.fst_vt['AeroDyn15']['InCol_Cl'] > 0: - polar['Cl'][i] = data[self.fst_vt['AeroDyn15']['InCol_Cl']-1] - if self.fst_vt['AeroDyn15']['InCol_Cd'] > 0: - polar['Cd'][i] = data[self.fst_vt['AeroDyn15']['InCol_Cd']-1] - if self.fst_vt['AeroDyn15']['InCol_Cm'] > 0: - polar['Cm'][i] = data[self.fst_vt['AeroDyn15']['InCol_Cm']-1] - if self.fst_vt['AeroDyn15']['InCol_Cpmin'] > 0: - polar['Cpmin'][i] = data[self.fst_vt['AeroDyn15']['InCol_Cpmin']-1] - - self.fst_vt['AeroDyn15']['af_data'][afi][tab] = copy.copy(polar) # For multiple tables + if self.fst_vt['AeroDyn']['InCol_Alfa'] > 0: + polar['Alpha'][i] = data[self.fst_vt['AeroDyn']['InCol_Alfa']-1] + if self.fst_vt['AeroDyn']['InCol_Cl'] > 0: + polar['Cl'][i] = data[self.fst_vt['AeroDyn']['InCol_Cl']-1] + if self.fst_vt['AeroDyn']['InCol_Cd'] > 0: + polar['Cd'][i] = data[self.fst_vt['AeroDyn']['InCol_Cd']-1] + if self.fst_vt['AeroDyn']['InCol_Cm'] > 0: + polar['Cm'][i] = data[self.fst_vt['AeroDyn']['InCol_Cm']-1] + if self.fst_vt['AeroDyn']['InCol_Cpmin'] > 0: + polar['Cpmin'][i] = data[self.fst_vt['AeroDyn']['InCol_Cpmin']-1] + + self.fst_vt['AeroDyn']['af_data'][afi][tab] = copy.copy(polar) # For multiple tables f.close() - def read_AeroDyn15Coord(self): + def read_AeroDynCoord(self): - self.fst_vt['AeroDyn15']['af_coord'] = [] - self.fst_vt['AeroDyn15']['ac'] = np.zeros(len(self.fst_vt['AeroDyn15']['AFNames'])) + self.fst_vt['AeroDyn']['af_coord'] = [] + self.fst_vt['AeroDyn']['ac'] = np.zeros(len(self.fst_vt['AeroDyn']['AFNames'])) - for afi, af_filename in enumerate(self.fst_vt['AeroDyn15']['AFNames']): - self.fst_vt['AeroDyn15']['af_coord'].append({}) - if not (self.fst_vt['AeroDyn15']['af_data'][afi][0]['NumCoords'] == 0 or self.fst_vt['AeroDyn15']['af_data'][afi][0]['NumCoords'] == '0'): - coord_filename = af_filename[0:af_filename.rfind(os.sep)] + os.sep + self.fst_vt['AeroDyn15']['af_data'][afi][0]['NumCoords'][2:-1] + for afi, af_filename in enumerate(self.fst_vt['AeroDyn']['AFNames']): + self.fst_vt['AeroDyn']['af_coord'].append({}) + if not (self.fst_vt['AeroDyn']['af_data'][afi][0]['NumCoords'] == 0 or self.fst_vt['AeroDyn']['af_data'][afi][0]['NumCoords'] == '0'): + coord_filename = af_filename[0:af_filename.rfind(os.sep)] + os.sep + self.fst_vt['AeroDyn']['af_data'][afi][0]['NumCoords'][2:-1] f = open(coord_filename) lines = f.readlines() @@ -1336,238 +1287,65 @@ def read_AeroDyn15Coord(self): x = np.zeros(n_coords-1) y = np.zeros(n_coords-1) - self.fst_vt['AeroDyn15']['ac'][afi] = float(lines[1].split()[0]) + self.fst_vt['AeroDyn']['ac'][afi] = float(lines[1].split()[0]) for j in range(2, n_coords+1): x[j - 2], y[j - 2] = map(float, lines[j].split()) - self.fst_vt['AeroDyn15']['af_coord'][afi]['x'] = x - self.fst_vt['AeroDyn15']['af_coord'][afi]['y'] = y + self.fst_vt['AeroDyn']['af_coord'][afi]['x'] = x + self.fst_vt['AeroDyn']['af_coord'][afi]['y'] = y - def read_AeroDyn15OLAF(self, olaf_filename): + def read_AeroDynOLAF(self, olaf_filename): - self.fst_vt['AeroDyn15']['OLAF'] = {} + self.fst_vt['AeroDyn']['OLAF'] = {} f = open(olaf_filename) f.readline() f.readline() f.readline() - self.fst_vt['AeroDyn15']['OLAF']['IntMethod'] = int_read(f.readline().split()[0]) - self.fst_vt['AeroDyn15']['OLAF']['DTfvw'] = float_read(f.readline().split()[0]) - self.fst_vt['AeroDyn15']['OLAF']['FreeWakeStart'] = float_read(f.readline().split()[0]) - self.fst_vt['AeroDyn15']['OLAF']['FullCircStart'] = float_read(f.readline().split()[0]) + self.fst_vt['AeroDyn']['OLAF']['IntMethod'] = int_read(f.readline().split()[0]) + self.fst_vt['AeroDyn']['OLAF']['DTfvw'] = float_read(f.readline().split()[0]) + self.fst_vt['AeroDyn']['OLAF']['FreeWakeStart'] = float_read(f.readline().split()[0]) + self.fst_vt['AeroDyn']['OLAF']['FullCircStart'] = float_read(f.readline().split()[0]) f.readline() - self.fst_vt['AeroDyn15']['OLAF']['CircSolvMethod'] = int_read(f.readline().split()[0]) - self.fst_vt['AeroDyn15']['OLAF']['CircSolvConvCrit'] = float_read(f.readline().split()[0]) - self.fst_vt['AeroDyn15']['OLAF']['CircSolvRelaxation'] = float_read(f.readline().split()[0]) - self.fst_vt['AeroDyn15']['OLAF']['CircSolvMaxIter'] = int_read(f.readline().split()[0]) - self.fst_vt['AeroDyn15']['OLAF']['PrescribedCircFile'] = os.path.join(self.FAST_directory, f.readline().split()[0][1:-1]) # unmodified by this script, hence pointing to absolute location + self.fst_vt['AeroDyn']['OLAF']['CircSolvMethod'] = int_read(f.readline().split()[0]) + self.fst_vt['AeroDyn']['OLAF']['CircSolvConvCrit'] = float_read(f.readline().split()[0]) + self.fst_vt['AeroDyn']['OLAF']['CircSolvRelaxation'] = float_read(f.readline().split()[0]) + self.fst_vt['AeroDyn']['OLAF']['CircSolvMaxIter'] = int_read(f.readline().split()[0]) + self.fst_vt['AeroDyn']['OLAF']['PrescribedCircFile'] = os.path.join(self.FAST_directory, f.readline().split()[0][1:-1]) # unmodified by this script, hence pointing to absolute location f.readline() f.readline() f.readline() - self.fst_vt['AeroDyn15']['OLAF']['nNWPanels'] = int_read(f.readline().split()[0]) - self.fst_vt['AeroDyn15']['OLAF']['nNWPanelsFree'] = int_read(f.readline().split()[0]) - self.fst_vt['AeroDyn15']['OLAF']['nFWPanels'] = int_read(f.readline().split()[0]) - self.fst_vt['AeroDyn15']['OLAF']['nFWPanelsFree'] = int_read(f.readline().split()[0]) - self.fst_vt['AeroDyn15']['OLAF']['FWShedVorticity'] = bool_read(f.readline().split()[0]) + self.fst_vt['AeroDyn']['OLAF']['nNWPanels'] = int_read(f.readline().split()[0]) + self.fst_vt['AeroDyn']['OLAF']['nNWPanelsFree'] = int_read(f.readline().split()[0]) + self.fst_vt['AeroDyn']['OLAF']['nFWPanels'] = int_read(f.readline().split()[0]) + self.fst_vt['AeroDyn']['OLAF']['nFWPanelsFree'] = int_read(f.readline().split()[0]) + self.fst_vt['AeroDyn']['OLAF']['FWShedVorticity'] = bool_read(f.readline().split()[0]) f.readline() - self.fst_vt['AeroDyn15']['OLAF']['DiffusionMethod'] = int_read(f.readline().split()[0]) - self.fst_vt['AeroDyn15']['OLAF']['RegDeterMethod'] = int_read(f.readline().split()[0]) - self.fst_vt['AeroDyn15']['OLAF']['RegFunction'] = int_read(f.readline().split()[0]) - self.fst_vt['AeroDyn15']['OLAF']['WakeRegMethod'] = int_read(f.readline().split()[0]) - self.fst_vt['AeroDyn15']['OLAF']['WakeRegFactor'] = float(f.readline().split()[0]) - self.fst_vt['AeroDyn15']['OLAF']['WingRegFactor'] = float(f.readline().split()[0]) - self.fst_vt['AeroDyn15']['OLAF']['CoreSpreadEddyVisc'] = int(f.readline().split()[0]) + self.fst_vt['AeroDyn']['OLAF']['DiffusionMethod'] = int_read(f.readline().split()[0]) + self.fst_vt['AeroDyn']['OLAF']['RegDeterMethod'] = int_read(f.readline().split()[0]) + self.fst_vt['AeroDyn']['OLAF']['RegFunction'] = int_read(f.readline().split()[0]) + self.fst_vt['AeroDyn']['OLAF']['WakeRegMethod'] = int_read(f.readline().split()[0]) + self.fst_vt['AeroDyn']['OLAF']['WakeRegFactor'] = float(f.readline().split()[0]) + self.fst_vt['AeroDyn']['OLAF']['WingRegFactor'] = float(f.readline().split()[0]) + self.fst_vt['AeroDyn']['OLAF']['CoreSpreadEddyVisc'] = int(f.readline().split()[0]) f.readline() - self.fst_vt['AeroDyn15']['OLAF']['TwrShadowOnWake'] = bool_read(f.readline().split()[0]) - self.fst_vt['AeroDyn15']['OLAF']['ShearModel'] = int_read(f.readline().split()[0]) + self.fst_vt['AeroDyn']['OLAF']['TwrShadowOnWake'] = bool_read(f.readline().split()[0]) + self.fst_vt['AeroDyn']['OLAF']['ShearModel'] = int_read(f.readline().split()[0]) f.readline() - self.fst_vt['AeroDyn15']['OLAF']['VelocityMethod'] = int_read(f.readline().split()[0]) - self.fst_vt['AeroDyn15']['OLAF']['TreeBranchFactor']= float_read(f.readline().split()[0]) - self.fst_vt['AeroDyn15']['OLAF']['PartPerSegment'] = int_read(f.readline().split()[0]) + self.fst_vt['AeroDyn']['OLAF']['VelocityMethod'] = int_read(f.readline().split()[0]) + self.fst_vt['AeroDyn']['OLAF']['TreeBranchFactor']= float_read(f.readline().split()[0]) + self.fst_vt['AeroDyn']['OLAF']['PartPerSegment'] = int_read(f.readline().split()[0]) f.readline() f.readline() - self.fst_vt['AeroDyn15']['OLAF']['WrVTk'] = int_read(f.readline().split()[0]) - self.fst_vt['AeroDyn15']['OLAF']['nVTKBlades'] = int_read(f.readline().split()[0]) - self.fst_vt['AeroDyn15']['OLAF']['VTKCoord'] = int_read(f.readline().split()[0]) - self.fst_vt['AeroDyn15']['OLAF']['VTK_fps'] = float_read(f.readline().split()[0]) - self.fst_vt['AeroDyn15']['OLAF']['nGridOut'] = int_read(f.readline().split()[0]) + self.fst_vt['AeroDyn']['OLAF']['WrVTk'] = int_read(f.readline().split()[0]) + self.fst_vt['AeroDyn']['OLAF']['nVTKBlades'] = int_read(f.readline().split()[0]) + self.fst_vt['AeroDyn']['OLAF']['VTKCoord'] = int_read(f.readline().split()[0]) + self.fst_vt['AeroDyn']['OLAF']['VTK_fps'] = float_read(f.readline().split()[0]) + self.fst_vt['AeroDyn']['OLAF']['nGridOut'] = int_read(f.readline().split()[0]) f.readline() f.close() - def read_AeroDyn14(self): - # AeroDyn v14.04 - - ad_file = os.path.join(self.FAST_directory, self.fst_vt['Fst']['AeroFile']) - f = open(ad_file) - # AeroDyn file header (aerodyn) - f.readline() - f.readline() - self.fst_vt['AeroDyn14']['StallMod'] = f.readline().split()[0] - self.fst_vt['AeroDyn14']['UseCm'] = f.readline().split()[0] - self.fst_vt['AeroDyn14']['InfModel'] = f.readline().split()[0] - self.fst_vt['AeroDyn14']['IndModel'] = f.readline().split()[0] - self.fst_vt['AeroDyn14']['AToler'] = float_read(f.readline().split()[0]) - self.fst_vt['AeroDyn14']['TLModel'] = f.readline().split()[0] - self.fst_vt['AeroDyn14']['HLModel'] = f.readline().split()[0] - self.fst_vt['AeroDyn14']['TwrShad'] = int(f.readline().split()[0]) - if self.fst_vt['AeroDyn14']['TwrShad'] > 0: - self.fst_vt['AeroDyn14']['TwrPotent'] = bool_read(f.readline().split()[0]) - self.fst_vt['AeroDyn14']['TwrShadow'] = bool_read(f.readline().split()[0]) - self.fst_vt['AeroDyn14']['TwrFile'] = f.readline().split()[0].replace('"','').replace("'",'') - self.fst_vt['AeroDyn14']['CalcTwrAero'] = bool_read(f.readline().split()[0]) - else: - self.fst_vt['AeroDyn14']['ShadHWid'] = float_read(f.readline().split()[0]) - self.fst_vt['AeroDyn14']['T_Shad_Refpt'] = float_read(f.readline().split()[0]) - self.fst_vt['AeroDyn14']['AirDens'] = float_read(f.readline().split()[0]) - self.fst_vt['AeroDyn14']['KinVisc'] = float_read(f.readline().split()[0]) - self.fst_vt['AeroDyn14']['DTAero'] = float_read(f.readline().split()[0]) - - # AeroDyn Blade Properties (blade_aero) - self.fst_vt['AeroDyn14']['NumFoil'] = int(f.readline().split()[0]) - self.fst_vt['AeroDyn14']['FoilNm'] = [None] * self.fst_vt['AeroDyn14']['NumFoil'] - for i in range(self.fst_vt['AeroDyn14']['NumFoil']): - af_filename = f.readline().split()[0] - af_filename = fix_path(af_filename) - self.fst_vt['AeroDyn14']['FoilNm'][i] = af_filename[1:-1] - - self.fst_vt['AeroDynBlade']['BldNodes'] = int(f.readline().split()[0]) - f.readline() - self.fst_vt['AeroDynBlade']['RNodes'] = [None] * self.fst_vt['AeroDynBlade']['BldNodes'] - self.fst_vt['AeroDynBlade']['AeroTwst'] = [None] * self.fst_vt['AeroDynBlade']['BldNodes'] - self.fst_vt['AeroDynBlade']['DRNodes'] = [None] * self.fst_vt['AeroDynBlade']['BldNodes'] - self.fst_vt['AeroDynBlade']['Chord'] = [None] * self.fst_vt['AeroDynBlade']['BldNodes'] - self.fst_vt['AeroDynBlade']['NFoil'] = [None] * self.fst_vt['AeroDynBlade']['BldNodes'] - self.fst_vt['AeroDynBlade']['PrnElm'] = [None] * self.fst_vt['AeroDynBlade']['BldNodes'] - for i in range(self.fst_vt['AeroDynBlade']['BldNodes']): - data = f.readline().split() - self.fst_vt['AeroDynBlade']['RNodes'][i] = float_read(data[0]) - self.fst_vt['AeroDynBlade']['AeroTwst'][i] = float_read(data[1]) - self.fst_vt['AeroDynBlade']['DRNodes'][i] = float_read(data[2]) - self.fst_vt['AeroDynBlade']['Chord'][i] = float_read(data[3]) - self.fst_vt['AeroDynBlade']['NFoil'][i] = int(data[4]) - self.fst_vt['AeroDynBlade']['PrnElm'][i] = data[5] - - f.close() - - # create airfoil objects - self.fst_vt['AeroDynBlade']['af_data'] = [] - for i in range(self.fst_vt['AeroDyn14']['NumFoil']): - self.fst_vt['AeroDynBlade']['af_data'].append(self.read_AeroDyn14Polar(os.path.join(self.FAST_directory,self.fst_vt['AeroDyn14']['FoilNm'][i]))) - - # tower - if self.fst_vt['AeroDyn14']['TwrShad'] > 0: - self.read_AeroDyn14Tower() - - def read_AeroDyn14Tower(self): - # AeroDyn v14.04 Tower - - ad_tower_file = os.path.join(self.FAST_directory, self.fst_vt['AeroDyn14']['TwrFile']) - f = open(ad_tower_file) - - f.readline() - f.readline() - self.fst_vt['AeroDynTower']['NTwrHt'] = int(f.readline().split()[0]) - self.fst_vt['AeroDynTower']['NTwrRe'] = int(f.readline().split()[0]) - self.fst_vt['AeroDynTower']['NTwrCD'] = int(f.readline().split()[0]) - self.fst_vt['AeroDynTower']['Tower_Wake_Constant'] = float_read(f.readline().split()[0]) - - f.readline() - f.readline() - self.fst_vt['AeroDynTower']['TwrHtFr'] = [None]*self.fst_vt['AeroDynTower']['NTwrHt'] - self.fst_vt['AeroDynTower']['TwrWid'] = [None]*self.fst_vt['AeroDynTower']['NTwrHt'] - self.fst_vt['AeroDynTower']['NTwrCDCol'] = [None]*self.fst_vt['AeroDynTower']['NTwrHt'] - for i in range(self.fst_vt['AeroDynTower']['NTwrHt']): - data = [float(val) for val in f.readline().split()] - self.fst_vt['AeroDynTower']['TwrHtFr'][i] = data[0] - self.fst_vt['AeroDynTower']['TwrWid'][i] = data[1] - self.fst_vt['AeroDynTower']['NTwrCDCol'][i] = data[2] - - f.readline() - f.readline() - self.fst_vt['AeroDynTower']['TwrRe'] = [None]*self.fst_vt['AeroDynTower']['NTwrRe'] - self.fst_vt['AeroDynTower']['TwrCD'] = np.zeros((self.fst_vt['AeroDynTower']['NTwrRe'], self.fst_vt['AeroDynTower']['NTwrCD'])) - for i in range(self.fst_vt['AeroDynTower']['NTwrRe']): - data = [float(val) for val in f.readline().split()] - self.fst_vt['AeroDynTower']['TwrRe'][i] = data[0] - self.fst_vt['AeroDynTower']['TwrCD'][i,:] = data[1:] - - f.close() - - def read_AeroDyn14Polar(self, aerodynFile): - # AeroDyn v14 Airfoil Polar Input File - - # open aerodyn file - f = open(aerodynFile, 'r') - - airfoil = copy.copy(self.fst_vt['AeroDynPolar']) - - # skip through header - airfoil['description'] = f.readline().rstrip() # remove newline - f.readline() - airfoil['number_tables'] = int(f.readline().split()[0]) - - IDParam = [float_read(val) for val in f.readline().split()[0:airfoil['number_tables']]] - StallAngle = [float_read(val) for val in f.readline().split()[0:airfoil['number_tables']]] - f.readline() - f.readline() - f.readline() - ZeroCn = [float_read(val) for val in f.readline().split()[0:airfoil['number_tables']]] - CnSlope = [float_read(val) for val in f.readline().split()[0:airfoil['number_tables']]] - CnPosStall = [float_read(val) for val in f.readline().split()[0:airfoil['number_tables']]] - CnNegStall = [float_read(val) for val in f.readline().split()[0:airfoil['number_tables']]] - alphaCdMin = [float_read(val) for val in f.readline().split()[0:airfoil['number_tables']]] - CdMin = [float_read(val) for val in f.readline().split()[0:airfoil['number_tables']]] - - data = [] - airfoil['af_tables'] = [] - while True: - line = f.readline() - if 'EOT' in line: - break - line = [float_read(s) for s in line.split()] - if len(line) < 1: - break - data.append(line) - - # loop through tables - for i in range(airfoil['number_tables']): - polar = {} - polar['IDParam'] = IDParam[i] - polar['StallAngle'] = StallAngle[i] - polar['ZeroCn'] = ZeroCn[i] - polar['CnSlope'] = CnSlope[i] - polar['CnPosStall'] = CnPosStall[i] - polar['CnNegStall'] = CnNegStall[i] - polar['alphaCdMin'] = alphaCdMin[i] - polar['CdMin'] = CdMin[i] - - alpha = [] - cl = [] - cd = [] - cm = [] - # read polar information line by line - for datai in data: - if len(datai) == airfoil['number_tables']*3+1: - alpha.append(datai[0]) - cl.append(datai[1 + 3*i]) - cd.append(datai[2 + 3*i]) - cm.append(datai[3 + 3*i]) - elif len(datai) == airfoil['number_tables']*2+1: - alpha.append(datai[0]) - cl.append(datai[1 + 2*i]) - cd.append(datai[2 + 2*i]) - - polar['alpha'] = alpha - polar['cl'] = cl - polar['cd'] = cd - polar['cm'] = cm - airfoil['af_tables'].append(polar) - - f.close() - - return airfoil - def read_AeroDisk(self): '''' Reading the AeroDisk input file. @@ -3283,7 +3061,7 @@ def execute(self): if self.fst_vt['Fst']['CompAero'] == 1: self.read_AeroDisk() elif self.fst_vt['Fst']['CompAero'] == 2: - self.read_AeroDyn15() + self.read_AeroDyn() if self.fst_vt['Fst']['CompServo'] == 1: self.read_ServoDyn() diff --git a/openfast_io/openfast_io/FAST_writer.py b/openfast_io/openfast_io/FAST_writer.py index 8e36871f1..dac96def1 100644 --- a/openfast_io/openfast_io/FAST_writer.py +++ b/openfast_io/openfast_io/FAST_writer.py @@ -165,7 +165,7 @@ def execute(self): if self.fst_vt['Fst']['CompAero'] == 1: self.write_AeroDisk() elif self.fst_vt['Fst']['CompAero'] == 2: - self.write_AeroDyn15() + self.write_AeroDyn() if self.fst_vt['Fst']['CompServo'] == 1: if 'DISCON_in' in self.fst_vt and ROSCO: @@ -461,55 +461,8 @@ def write_ElastoDyn(self): f.close() def write_SimpleElastoDyn(self): - ''' - Here is the format of the Simplified ElastoDyn input file: - - ------- SIMPLIFIED ELASTODYN INPUT FILE ---------------------------------------- - Test case input file for SED (not representative of any model) - ---------------------- SIMULATION CONTROL -------------------------------------- - True Echo - Echo input data to ".ech" (flag) - 3 IntMethod - Integration method: {1: RK4, 2: AB4, or 3: ABM4} (-) - "default" DT - Integration time step (s) - ---------------------- DEGREES OF FREEDOM -------------------------------------- - True GenDOF - Generator DOF (flag) - True YawDOF - Yaw degree of freedom -- controlled by controller (flag) - ---------------------- INITIAL CONDITIONS -------------------------------------- - 0 Azimuth - Initial azimuth angle for blades (degrees) - 0 BlPitch - Blades initial pitch (degrees) - 12.1 RotSpeed - Initial or fixed rotor speed (rpm) - 0 NacYaw - Initial or fixed nacelle-yaw angle (degrees) - 0 PtfmPitch - Fixed pitch tilt rotational displacement of platform (degrees) - ---------------------- TURBINE CONFIGURATION ----------------------------------- - 3 NumBl - Number of blades (-) - 63 TipRad - The distance from the rotor apex to the blade tip (meters) - 1.5 HubRad - The distance from the rotor apex to the blade root (meters) - -2.5 PreCone - Blades cone angle (degrees) - -5.0191 OverHang - Distance from yaw axis to rotor apex [3 blades] or teeter pin [2 blades] (meters) - -5 ShftTilt - Rotor shaft tilt angle (degrees) - 1.96256 Twr2Shft - Vertical distance from the tower-top to the rotor shaft (meters) - 87.6 TowerHt - Height of tower above ground level [onshore] or MSL [offshore] (meters) - ---------------------- MASS AND INERTIA ---------------------------------------- - 38677052 RotIner - Rot inertia about rotor axis [blades + hub] (kg m^2) - 534.116 GenIner - Generator inertia about HSS (kg m^2) - ---------------------- DRIVETRAIN ---------------------------------------------- - 97 GBoxRatio - Gearbox ratio (-) - ---------------------- OUTPUT -------------------------------------------------- - OutList - The next line(s) contains a list of output parameters. See OutListParameters.xlsx for a listing of available output channels, (-) - "BlPitch1" - "BlPitch2" - "BlPitch3" - "Azimuth" - Blades azimuth angle (deg) - "RotSpeed" - Low-speed shaft rotational speed (rpm) - "RotAcc" - Low-speed shaft rotational acceleration (rad/s^2) - "GenSpeed" - High-speed shaft rotational speed (rpm) - "GenAcc" - High-speed shaft rotational acceleration (rad/s^2) - "Yaw" - Commanded yaw angle - "YawRate" - Commanded yaw angle rate - "RotPwr" - "RotTorq" - END of input file (the word "END" must appear in the first 3 columns of this last OutList line) - ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - ''' + # Write the simple ElastoDyn file + self.fst_vt['Fst']['EDFile'] = self.FAST_namingOut + '_SimpleElastoDyn.dat' sed_file = os.path.join(self.FAST_runDirectory,self.fst_vt['Fst']['EDFile']) f = open(sed_file, 'w') @@ -751,13 +704,6 @@ def write_BeamDyn(self): os.fsync(f) f.close() - # f.write('{:<22} {:<11} {:}'.format(self.fst_vt['BeamDyn'][''], '', '\n')) - # f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['BeamDyn'][''], '', '\n')) - # f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['BeamDyn'][''], '', '\n')) - # f.write('{: 2.15e} {:<11} {:}'.format(self.fst_vt['BeamDyn'][''], '', '\n')) - # f.write(float_default_out(self.fst_vt['BeamDyn']['']) + ' {:<11} {:}'.format('', '\n')) - # f.write(int_default_out(self.fst_vt['BeamDyn']['']) + ' {:<11} {:}'.format('', '\n')) - def write_BeamDynBlade(self): # bd_blade_file = self.fst_vt['BeamDyn']['BldFile'] @@ -872,128 +818,128 @@ def write_InflowWind(self): os.fsync(f) f.close() - def write_AeroDyn15(self): + def write_AeroDyn(self): # AeroDyn v15.03 # Generate AeroDyn v15 blade input file - self.write_AeroDyn15Blade() + self.write_AeroDynBlade() # Generate AeroDyn v15 polars - self.write_AeroDyn15Polar() + self.write_AeroDynPolar() # Generate AeroDyn v15 airfoil coordinates - if self.fst_vt['AeroDyn15']['af_data'][0][0]['NumCoords'] != '0': # changing from ['af_data'][1] to ['af_data'][0] because we can have a single airfoil too. - self.write_AeroDyn15Coord() + if self.fst_vt['AeroDyn']['af_data'][0][0]['NumCoords'] != '0': # changing from ['af_data'][1] to ['af_data'][0] because we can have a single airfoil too. + self.write_AeroDynCoord() - if self.fst_vt['AeroDyn15']['Wake_Mod'] == 3: - if self.fst_vt['AeroDyn15']['UA_Mod'] > 0: + if self.fst_vt['AeroDyn']['Wake_Mod'] == 3: + if self.fst_vt['AeroDyn']['UA_Mod'] > 0: raise Exception('OLAF is called with unsteady airfoil aerodynamics, but OLAF currently only supports UA_Mod == 0') #TODO: need to check if this holds true now self.write_OLAF() # Generate AeroDyn v15.03 input file - self.fst_vt['Fst']['AeroFile'] = self.FAST_namingOut + '_AeroDyn15.dat' + self.fst_vt['Fst']['AeroFile'] = self.FAST_namingOut + '_AeroDyn.dat' ad_file = os.path.join(self.FAST_runDirectory, self.fst_vt['Fst']['AeroFile']) f = open(ad_file, 'w') f.write('------- AERODYN15 INPUT FILE ------------------------------------------------\n') f.write('Generated with OpenFAST_IO\n') f.write('====== General Options ============================================================================\n') - f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['Echo'], 'Echo', '- Echo the input to ".AD.ech"? (flag)\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['DTAero'], 'DTAero', '- Time interval for aerodynamic calculations {or "default"} (s)\n')) - f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['Wake_Mod'], 'Wake_Mod', '- Wake/induction model (switch) {0=none, 1=BEMT, 3=OLAF} [Wake_Mod cannot be 2 or 3 when linearizing]\n')) - f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['TwrPotent'], '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}\n')) - f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['TwrShadow'], 'TwrShadow', '- Calculate tower influence on wind based on downstream tower shadow (switch) {0=none, 1=Powles model, 2=Eames model}\n')) - f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['TwrAero'], 'TwrAero', '- Calculate tower aerodynamic loads? (flag)\n')) - f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['CavitCheck'], 'CavitCheck', '- Perform cavitation check? (flag) [UA_Mod must be 0 when CavitCheck=true]\n')) - f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['Buoyancy'], 'Buoyancy', '- Include buoyancy effects? (flag)\n')) - f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['NacelleDrag'], 'NacelleDrag', '- Include Nacelle Drag effects? (flag)\n')) - f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['CompAA'], 'CompAA', '- Flag to compute AeroAcoustics calculation [used only when Wake_Mod = 1 or 2]\n')) - f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['AA_InputFile'], 'AA_InputFile', '- AeroAcoustics input file [used only when CompAA=true]\n')) + f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn']['Echo'], 'Echo', '- Echo the input to ".AD.ech"? (flag)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn']['DTAero'], 'DTAero', '- Time interval for aerodynamic calculations {or "default"} (s)\n')) + f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn']['Wake_Mod'], 'Wake_Mod', '- Wake/induction model (switch) {0=none, 1=BEMT, 3=OLAF} [Wake_Mod cannot be 2 or 3 when linearizing]\n')) + f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn']['TwrPotent'], '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}\n')) + f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn']['TwrShadow'], 'TwrShadow', '- Calculate tower influence on wind based on downstream tower shadow (switch) {0=none, 1=Powles model, 2=Eames model}\n')) + f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn']['TwrAero'], 'TwrAero', '- Calculate tower aerodynamic loads? (flag)\n')) + f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn']['CavitCheck'], 'CavitCheck', '- Perform cavitation check? (flag) [UA_Mod must be 0 when CavitCheck=true]\n')) + f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn']['Buoyancy'], 'Buoyancy', '- Include buoyancy effects? (flag)\n')) + f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn']['NacelleDrag'], 'NacelleDrag', '- Include Nacelle Drag effects? (flag)\n')) + f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn']['CompAA'], 'CompAA', '- Flag to compute AeroAcoustics calculation [used only when Wake_Mod = 1 or 2]\n')) + f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn']['AA_InputFile'], 'AA_InputFile', '- AeroAcoustics input file [used only when CompAA=true]\n')) f.write('====== Environmental Conditions ===================================================================\n') - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['AirDens'], 'AirDens', '- Air density (kg/m^3)\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['KinVisc'], 'KinVisc', '- Kinematic viscosity of working fluid (m^2/s)\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['SpdSound'], 'SpdSound', '- Speed of sound in working fluid (m/s)\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['Patm'], 'Patm', '- Atmospheric pressure (Pa) [used only when CavitCheck=True]\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['Pvap'], 'Pvap', '- Vapour pressure of working fluid (Pa) [used only when CavitCheck=True]\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn']['AirDens'], 'AirDens', '- Air density (kg/m^3)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn']['KinVisc'], 'KinVisc', '- Kinematic viscosity of working fluid (m^2/s)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn']['SpdSound'], 'SpdSound', '- Speed of sound in working fluid (m/s)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn']['Patm'], 'Patm', '- Atmospheric pressure (Pa) [used only when CavitCheck=True]\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn']['Pvap'], 'Pvap', '- Vapour pressure of working fluid (Pa) [used only when CavitCheck=True]\n')) f.write('====== Blade-Element/Momentum Theory Options ====================================================== [unused when Wake_Mod=0 or 3, except for BEM_Mod]\n') - f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['BEM_Mod'], 'BEM_Mod', '- BEM model {1=legacy NoSweepPitchTwist, 2=polar} (switch) [used for all Wake_Mod to determine output coordinate system]\n')) + f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn']['BEM_Mod'], 'BEM_Mod', '- BEM model {1=legacy NoSweepPitchTwist, 2=polar} (switch) [used for all Wake_Mod to determine output coordinate system]\n')) f.write('--- Skew correction\n') - f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['Skew_Mod'], 'Skew_Mod', '- Skew model {0=No skew model, -1=Remove non-normal component for linearization, 1=skew model active}\n')) - f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['SkewMomCorr'], 'SkewMomCorr', '- Turn the skew momentum correction on or off [used only when Skew_Mod=1]\n')) - f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['SkewRedistr_Mod'], 'SkewRedistr_Mod', '- Type of skewed-wake correction model (switch) {0=no redistribution, 1=Glauert/Pitt/Peters, default=1} [used only when Skew_Mod=1]\n')) - f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['SkewRedistrFactor'], 'SkewRedistrFactor', '- Constant used in Pitt/Peters skewed wake model {or "default" is 15/32*pi} (-) [used only when Skew_Mod=1 and SkewRedistr_Mod=1]\n')) + f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn']['Skew_Mod'], 'Skew_Mod', '- Skew model {0=No skew model, -1=Remove non-normal component for linearization, 1=skew model active}\n')) + f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn']['SkewMomCorr'], 'SkewMomCorr', '- Turn the skew momentum correction on or off [used only when Skew_Mod=1]\n')) + f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn']['SkewRedistr_Mod'], 'SkewRedistr_Mod', '- Type of skewed-wake correction model (switch) {0=no redistribution, 1=Glauert/Pitt/Peters, default=1} [used only when Skew_Mod=1]\n')) + f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn']['SkewRedistrFactor'], 'SkewRedistrFactor', '- Constant used in Pitt/Peters skewed wake model {or "default" is 15/32*pi} (-) [used only when Skew_Mod=1 and SkewRedistr_Mod=1]\n')) f.write('--- BEM algorithm\n') - f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['TipLoss'], 'TipLoss', '- Use the Prandtl tip-loss model? (flag) [unused when Wake_Mod=0 or 3]\n')) - f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['HubLoss'], 'HubLoss', '- Use the Prandtl hub-loss model? (flag) [unused when Wake_Mod=0 or 3]\n')) - f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['TanInd'], 'TanInd', '- Include tangential induction in BEMT calculations? (flag) [unused when Wake_Mod=0 or 3]\n')) - f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['AIDrag'], 'AIDrag', '- Include the drag term in the axial-induction calculation? (flag) [unused when Wake_Mod=0 or 3]\n')) - f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['TIDrag'], 'TIDrag', '- Include the drag term in the tangential-induction calculation? (flag) [unused when Wake_Mod=0,3 or TanInd=FALSE]\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['IndToler'], 'IndToler', '- Convergence tolerance for BEMT nonlinear solve residual equation {or "default"} (-) [unused when Wake_Mod=0 or 3]\n')) - f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['MaxIter'], 'MaxIter', '- Maximum number of iteration steps (-) [unused when Wake_Mod=0]\n')) + f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn']['TipLoss'], 'TipLoss', '- Use the Prandtl tip-loss model? (flag) [unused when Wake_Mod=0 or 3]\n')) + f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn']['HubLoss'], 'HubLoss', '- Use the Prandtl hub-loss model? (flag) [unused when Wake_Mod=0 or 3]\n')) + f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn']['TanInd'], 'TanInd', '- Include tangential induction in BEMT calculations? (flag) [unused when Wake_Mod=0 or 3]\n')) + f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn']['AIDrag'], 'AIDrag', '- Include the drag term in the axial-induction calculation? (flag) [unused when Wake_Mod=0 or 3]\n')) + f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn']['TIDrag'], 'TIDrag', '- Include the drag term in the tangential-induction calculation? (flag) [unused when Wake_Mod=0,3 or TanInd=FALSE]\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn']['IndToler'], 'IndToler', '- Convergence tolerance for BEMT nonlinear solve residual equation {or "default"} (-) [unused when Wake_Mod=0 or 3]\n')) + f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn']['MaxIter'], 'MaxIter', '- Maximum number of iteration steps (-) [unused when Wake_Mod=0]\n')) f.write('--- Shear correction\n') - f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['SectAvg'], 'SectAvg', '- Use sector averaging (flag)\n')) - f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['SectAvgWeighting'], 'SectAvgWeighting', '- Weighting function for sector average {1=Uniform, default=1} within a sector centered on the blade (switch) [used only when SectAvg=True]\n')) - f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['SectAvgNPoints'], 'SectAvgNPoints', '- Number of points per sectors (-) {default=5} [used only when SectAvg=True]\n')) - f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['SectAvgPsiBwd'], 'SectAvgPsiBwd', '- Backward azimuth relative to blade where the sector starts (<=0) {default=-60} (deg) [used only when SectAvg=True]\n')) - f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['SectAvgPsiFwd'], 'SectAvgPsiFwd', '- Forward azimuth relative to blade where the sector ends (>=0) {default=60} (deg) [used only when SectAvg=True]\n')) + f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn']['SectAvg'], 'SectAvg', '- Use sector averaging (flag)\n')) + f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn']['SectAvgWeighting'], 'SectAvgWeighting', '- Weighting function for sector average {1=Uniform, default=1} within a sector centered on the blade (switch) [used only when SectAvg=True]\n')) + f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn']['SectAvgNPoints'], 'SectAvgNPoints', '- Number of points per sectors (-) {default=5} [used only when SectAvg=True]\n')) + f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn']['SectAvgPsiBwd'], 'SectAvgPsiBwd', '- Backward azimuth relative to blade where the sector starts (<=0) {default=-60} (deg) [used only when SectAvg=True]\n')) + f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn']['SectAvgPsiFwd'], 'SectAvgPsiFwd', '- Forward azimuth relative to blade where the sector ends (>=0) {default=60} (deg) [used only when SectAvg=True]\n')) f.write('--- Dynamic wake/inflow\n') - f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['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} (-)\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['tau1_const'], 'tau1_const', '- Time constant for DBEMT (s) [used only when DBEMT_Mod=1 or 3]\n')) + f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn']['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} (-)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn']['tau1_const'], 'tau1_const', '- Time constant for DBEMT (s) [used only when DBEMT_Mod=1 or 3]\n')) f.write('====== OLAF -- cOnvecting LAgrangian Filaments (Free Vortex Wake) Theory Options ================== [used only when Wake_Mod=3]\n') olaf_file = self.FAST_namingOut + '_OLAF.dat' f.write('{!s:<22} {:<11} {:}'.format(olaf_file, 'OLAFInputFileName', '- Input file for OLAF [used only when Wake_Mod=3]\n')) f.write('====== Unsteady Airfoil Aerodynamics Options ===================================== \n') - f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['AoA34'], 'AoA34', "- Sample the angle of attack (AoA) at the 3/4 chord or the AC point {default=True} [always used]\n")) - f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['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}\n")) - f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['FLookup'], '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 UA_Mod>0]\n")) - f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['IntegrationMethod'], 'IntegrationMethod', "- Switch to indicate which integration method UA uses (1=RK4, 2=AB4, 3=ABM4, 4=BDF2)\n")) - if 'UAStartRad' in self.fst_vt['AeroDyn15'] and 'UAEndRad' in self.fst_vt['AeroDyn15']: - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['UAStartRad'], 'UAStartRad', '- Starting radius for dynamic stall (fraction of rotor radius [0.0,1.0]) [used only when UA_Mod>0; if line is missing UAStartRad=0]\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['UAEndRad'], 'UAEndRad', '- Ending radius for dynamic stall (fraction of rotor radius [0.0,1.0]) [used only when UA_Mod>0; if line is missing UAEndRad=1]\n')) + f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn']['AoA34'], 'AoA34', "- Sample the angle of attack (AoA) at the 3/4 chord or the AC point {default=True} [always used]\n")) + f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn']['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}\n")) + f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn']['FLookup'], '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 UA_Mod>0]\n")) + f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn']['IntegrationMethod'], 'IntegrationMethod', "- Switch to indicate which integration method UA uses (1=RK4, 2=AB4, 3=ABM4, 4=BDF2)\n")) + if 'UAStartRad' in self.fst_vt['AeroDyn'] and 'UAEndRad' in self.fst_vt['AeroDyn']: + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn']['UAStartRad'], 'UAStartRad', '- Starting radius for dynamic stall (fraction of rotor radius [0.0,1.0]) [used only when UA_Mod>0; if line is missing UAStartRad=0]\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn']['UAEndRad'], 'UAEndRad', '- Ending radius for dynamic stall (fraction of rotor radius [0.0,1.0]) [used only when UA_Mod>0; if line is missing UAEndRad=1]\n')) f.write('====== Airfoil Information =========================================================================\n') - f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['AFTabMod'], '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} (-)\n')) - f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['InCol_Alfa'], 'InCol_Alfa', '- The column in the airfoil tables that contains the angle of attack (-)\n')) - f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['InCol_Cl'], 'InCol_Cl', '- The column in the airfoil tables that contains the lift coefficient (-)\n')) - f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['InCol_Cd'], 'InCol_Cd', '- The column in the airfoil tables that contains the drag coefficient (-)\n')) - f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['InCol_Cm'], 'InCol_Cm', '- The column in the airfoil tables that contains the pitching-moment coefficient; use zero if there is no Cm column (-)\n')) - f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['InCol_Cpmin'], 'InCol_Cpmin', '- The column in the airfoil tables that contains the Cpmin coefficient; use zero if there is no Cpmin column (-)\n')) - f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['NumAFfiles'], 'NumAFfiles', '- Number of airfoil files used (-)\n')) - for i in range(self.fst_vt['AeroDyn15']['NumAFfiles']): + f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn']['AFTabMod'], '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} (-)\n')) + f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn']['InCol_Alfa'], 'InCol_Alfa', '- The column in the airfoil tables that contains the angle of attack (-)\n')) + f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn']['InCol_Cl'], 'InCol_Cl', '- The column in the airfoil tables that contains the lift coefficient (-)\n')) + f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn']['InCol_Cd'], 'InCol_Cd', '- The column in the airfoil tables that contains the drag coefficient (-)\n')) + f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn']['InCol_Cm'], 'InCol_Cm', '- The column in the airfoil tables that contains the pitching-moment coefficient; use zero if there is no Cm column (-)\n')) + f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn']['InCol_Cpmin'], 'InCol_Cpmin', '- The column in the airfoil tables that contains the Cpmin coefficient; use zero if there is no Cpmin column (-)\n')) + f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn']['NumAFfiles'], 'NumAFfiles', '- Number of airfoil files used (-)\n')) + for i in range(self.fst_vt['AeroDyn']['NumAFfiles']): if i == 0: - f.write('"' + self.fst_vt['AeroDyn15']['AFNames'][i] + '" AFNames - Airfoil file names (NumAFfiles lines) (quoted strings)\n') + f.write('"' + self.fst_vt['AeroDyn']['AFNames'][i] + '" AFNames - Airfoil file names (NumAFfiles lines) (quoted strings)\n') else: - f.write('"' + self.fst_vt['AeroDyn15']['AFNames'][i] + '"\n') + f.write('"' + self.fst_vt['AeroDyn']['AFNames'][i] + '"\n') f.write('====== Rotor/Blade Properties =====================================================================\n') - f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['UseBlCm'], 'UseBlCm', '- Include aerodynamic pitching moment in calculations? (flag)\n')) - f.write('{:<22} {:<11} {:}'.format('"'+self.fst_vt['AeroDyn15']['ADBlFile1']+'"', 'ADBlFile(1)', '- Name of file containing distributed aerodynamic properties for Blade #1 (-)\n')) - f.write('{:<22} {:<11} {:}'.format('"'+self.fst_vt['AeroDyn15']['ADBlFile2']+'"', 'ADBlFile(2)', '- Name of file containing distributed aerodynamic properties for Blade #2 (-) [unused if NumBl < 2]\n')) - f.write('{:<22} {:<11} {:}'.format('"'+self.fst_vt['AeroDyn15']['ADBlFile3']+'"', 'ADBlFile(3)', '- Name of file containing distributed aerodynamic properties for Blade #3 (-) [unused if NumBl < 3]\n')) + f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn']['UseBlCm'], 'UseBlCm', '- Include aerodynamic pitching moment in calculations? (flag)\n')) + f.write('{:<22} {:<11} {:}'.format('"'+self.fst_vt['AeroDyn']['ADBlFile1']+'"', 'ADBlFile(1)', '- Name of file containing distributed aerodynamic properties for Blade #1 (-)\n')) + f.write('{:<22} {:<11} {:}'.format('"'+self.fst_vt['AeroDyn']['ADBlFile2']+'"', 'ADBlFile(2)', '- Name of file containing distributed aerodynamic properties for Blade #2 (-) [unused if NumBl < 2]\n')) + f.write('{:<22} {:<11} {:}'.format('"'+self.fst_vt['AeroDyn']['ADBlFile3']+'"', 'ADBlFile(3)', '- Name of file containing distributed aerodynamic properties for Blade #3 (-) [unused if NumBl < 3]\n')) f.write('====== Hub Properties ============================================================================== [used only when Buoyancy=True]\n') - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['VolHub'], 'VolHub', '- Hub volume (m^3)\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['HubCenBx'], 'HubCenBx', '- Hub center of buoyancy x direction offset (m)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn']['VolHub'], 'VolHub', '- Hub volume (m^3)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn']['HubCenBx'], 'HubCenBx', '- Hub center of buoyancy x direction offset (m)\n')) f.write('====== Nacelle Properties ========================================================================== used only when Buoyancy=True or NacelleDrag=True]\n') - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['VolNac'], 'VolNac', '- Nacelle volume (m^3)\n')) - f.write('{:<22} {:<11} {:}'.format(', '.join(np.array(self.fst_vt['AeroDyn15']['NacCenB'], dtype=str)), 'NacCenB', '- Position of nacelle center of buoyancy from yaw bearing in nacelle coordinates (m)\n')) - f.write('{:<22} {:<11} {:}'.format(', '.join(np.array(self.fst_vt['AeroDyn15']['NacArea'], dtype=str)), 'NacArea', '- Projected area of the nacelle in X, Y, Z in the nacelle coordinate system (m^2)\n')) - f.write('{:<22} {:<11} {:}'.format(', '.join(np.array(self.fst_vt['AeroDyn15']['NacCd'], dtype=str)), 'NacCd', '- Drag coefficient for the nacelle areas defined above (-)\n')) - f.write('{:<22} {:<11} {:}'.format(', '.join(np.array(self.fst_vt['AeroDyn15']['NacDragAC'], dtype=str)), 'NacDragAC', '- Position of aerodynamic center of nacelle drag in nacelle coordinates (m)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn']['VolNac'], 'VolNac', '- Nacelle volume (m^3)\n')) + f.write('{:<22} {:<11} {:}'.format(', '.join(np.array(self.fst_vt['AeroDyn']['NacCenB'], dtype=str)), 'NacCenB', '- Position of nacelle center of buoyancy from yaw bearing in nacelle coordinates (m)\n')) + f.write('{:<22} {:<11} {:}'.format(', '.join(np.array(self.fst_vt['AeroDyn']['NacArea'], dtype=str)), 'NacArea', '- Projected area of the nacelle in X, Y, Z in the nacelle coordinate system (m^2)\n')) + f.write('{:<22} {:<11} {:}'.format(', '.join(np.array(self.fst_vt['AeroDyn']['NacCd'], dtype=str)), 'NacCd', '- Drag coefficient for the nacelle areas defined above (-)\n')) + f.write('{:<22} {:<11} {:}'.format(', '.join(np.array(self.fst_vt['AeroDyn']['NacDragAC'], dtype=str)), 'NacDragAC', '- Position of aerodynamic center of nacelle drag in nacelle coordinates (m)\n')) f.write('====== Tail Fin Aerodynamics ========================================================================\n') - f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['TFinAero'], 'TFinAero', '- Calculate tail fin aerodynamics model (flag)\n')) - f.write('{:<22} {:<11} {:}'.format('"'+self.fst_vt['AeroDyn15']['TFinFile']+'"', 'TFinFile', '- Input file for tail fin aerodynamics [used only when TFinAero=True]\n')) + f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn']['TFinAero'], 'TFinAero', '- Calculate tail fin aerodynamics model (flag)\n')) + f.write('{:<22} {:<11} {:}'.format('"'+self.fst_vt['AeroDyn']['TFinFile']+'"', 'TFinFile', '- Input file for tail fin aerodynamics [used only when TFinAero=True]\n')) f.write('====== Tower Influence and Aerodynamics ============================================================ [used only when TwrPotent/=0, TwrShadow/=0, TwrAero=True, or Buoyancy=True]\n') - f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['NumTwrNds'], 'NumTwrNds', '- Number of tower nodes used in the analysis (-) [used only when TwrPotent/=0, TwrShadow/=0, TwrAero=True, or Buoyancy=True]\n')) + f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn']['NumTwrNds'], 'NumTwrNds', '- Number of tower nodes used in the analysis (-) [used only when TwrPotent/=0, TwrShadow/=0, TwrAero=True, or Buoyancy=True]\n')) f.write('TwrElev TwrDiam TwrCd TwrTI TwrCb !TwrTI used only when TwrShadow=2; TwrCb used only when Buoyancy=True\n') f.write('(m) (m) (-) (-) (-)\n') - for TwrElev, TwrDiam, TwrCd, TwrTI, TwrCb in zip(self.fst_vt['AeroDyn15']['TwrElev'], self.fst_vt['AeroDyn15']['TwrDiam'], self.fst_vt['AeroDyn15']['TwrCd'], self.fst_vt['AeroDyn15']['TwrTI'], self.fst_vt['AeroDyn15']['TwrCb']): + for TwrElev, TwrDiam, TwrCd, TwrTI, TwrCb in zip(self.fst_vt['AeroDyn']['TwrElev'], self.fst_vt['AeroDyn']['TwrDiam'], self.fst_vt['AeroDyn']['TwrCd'], self.fst_vt['AeroDyn']['TwrTI'], self.fst_vt['AeroDyn']['TwrCb']): f.write('{: 2.15e} {: 2.15e} {: 2.15e} {: 2.15e} {: 2.15e} \n'.format(TwrElev, TwrDiam, TwrCd, TwrTI, TwrCb)) f.write('====== Outputs ====================================================================================\n') - f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['SumPrint'], 'SumPrint', '- Generate a summary file listing input options and interpolated properties to ".AD.sum"? (flag)\n')) - f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['NBlOuts'], 'NBlOuts', '- Number of blade node outputs [0 - 9] (-)\n')) - f.write('{:<22} {:<11} {:}'.format(', '.join(self.fst_vt['AeroDyn15']['BlOutNd']), 'BlOutNd', '- Blade nodes whose values will be output (-)\n')) - f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['NTwOuts'], 'NTwOuts', '- Number of tower node outputs [0 - 9] (-)\n')) - if self.fst_vt['AeroDyn15']['NTwOuts'] != 0: - f.write('{:<22} {:<11} {:}'.format(', '.join(self.fst_vt['AeroDyn15']['TwOutNd']), 'TwOutNd', '- Tower nodes whose values will be output (-)\n')) + f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn']['SumPrint'], 'SumPrint', '- Generate a summary file listing input options and interpolated properties to ".AD.sum"? (flag)\n')) + f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn']['NBlOuts'], 'NBlOuts', '- Number of blade node outputs [0 - 9] (-)\n')) + f.write('{:<22} {:<11} {:}'.format(', '.join(self.fst_vt['AeroDyn']['BlOutNd']), 'BlOutNd', '- Blade nodes whose values will be output (-)\n')) + f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn']['NTwOuts'], 'NTwOuts', '- Number of tower node outputs [0 - 9] (-)\n')) + if self.fst_vt['AeroDyn']['NTwOuts'] != 0: + f.write('{:<22} {:<11} {:}'.format(', '.join(self.fst_vt['AeroDyn']['TwOutNd']), 'TwOutNd', '- Tower nodes whose values will be output (-)\n')) else: f.write('{:<22} {:<11} {:}'.format(0, 'TwOutNd', '- Tower nodes whose values will be output (-)\n')) f.write(' OutList - The next line(s) contains a list of output parameters. See OutListParameters.xlsx for a listing of available output channels, (-)\n') @@ -1005,10 +951,10 @@ def write_AeroDyn15(self): f.write('END of input file (the word "END" must appear in the first 3 columns of this last OutList line)\n') # Optional nodal output section - if 'BldNd_BladesOut' in self.fst_vt['AeroDyn15']: + if 'BldNd_BladesOut' in self.fst_vt['AeroDyn']: f.write('====== Outputs for all blade stations (same ending as above for B1N1.... =========================== [optional section]\n') - f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['BldNd_BladesOut'], 'BldNd_BladesOut', '- Number of blades to output all node information at. Up to number of blades on turbine. (-)\n')) - f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['BldNd_BlOutNd'], 'BldNd_BlOutNd', '- Future feature will allow selecting a portion of the nodes to output. Not implemented yet. (-)\n')) + f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn']['BldNd_BladesOut'], 'BldNd_BladesOut', '- Number of blades to output all node information at. Up to number of blades on turbine. (-)\n')) + f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn']['BldNd_BlOutNd'], 'BldNd_BlOutNd', '- Future feature will allow selecting a portion of the nodes to output. Not implemented yet. (-)\n')) f.write(' OutList_Nodal - The next line(s) contains a list of output parameters. See OutListParameters.xlsx, AeroDyn_Nodes tab for a listing of available output channels, (-)\n') opt_outlist = self.get_outlist(self.fst_vt['outlist'], ['AeroDyn_Nodes']) @@ -1022,12 +968,12 @@ def write_AeroDyn15(self): os.fsync(f) f.close() - def write_AeroDyn15Blade(self): + def write_AeroDynBlade(self): # AeroDyn v15.00 Blade - self.fst_vt['AeroDyn15']['ADBlFile1'] = self.FAST_namingOut + '_AeroDyn15_blade.dat' - self.fst_vt['AeroDyn15']['ADBlFile2'] = self.fst_vt['AeroDyn15']['ADBlFile1'] - self.fst_vt['AeroDyn15']['ADBlFile3'] = self.fst_vt['AeroDyn15']['ADBlFile1'] - filename = os.path.join(self.FAST_runDirectory, self.fst_vt['AeroDyn15']['ADBlFile1']) + self.fst_vt['AeroDyn']['ADBlFile1'] = self.FAST_namingOut + '_AeroDyn_blade.dat' + self.fst_vt['AeroDyn']['ADBlFile2'] = self.fst_vt['AeroDyn']['ADBlFile1'] + self.fst_vt['AeroDyn']['ADBlFile3'] = self.fst_vt['AeroDyn']['ADBlFile1'] + filename = os.path.join(self.FAST_runDirectory, self.fst_vt['AeroDyn']['ADBlFile1']) f = open(filename, 'w') f.write('------- AERODYN15 BLADE DEFINITION INPUT FILE -------------------------------------\n') @@ -1050,7 +996,7 @@ def write_AeroDyn15Blade(self): os.fsync(f) f.close() - def write_AeroDyn15Polar(self): + def write_AeroDynPolar(self): # Airfoil Info v1.01 if not os.path.isdir(os.path.join(self.FAST_runDirectory,'Airfoils')): @@ -1065,13 +1011,13 @@ def write_AeroDyn15Polar(self): print("Error tring to make '%s'!"%os.path.join(self.FAST_runDirectory,'Airfoils')) - self.fst_vt['AeroDyn15']['NumAFfiles'] = len(self.fst_vt['AeroDyn15']['af_data']) - self.fst_vt['AeroDyn15']['AFNames'] = ['']*self.fst_vt['AeroDyn15']['NumAFfiles'] + self.fst_vt['AeroDyn']['NumAFfiles'] = len(self.fst_vt['AeroDyn']['af_data']) + self.fst_vt['AeroDyn']['AFNames'] = ['']*self.fst_vt['AeroDyn']['NumAFfiles'] - for afi in range(int(self.fst_vt['AeroDyn15']['NumAFfiles'])): + for afi in range(int(self.fst_vt['AeroDyn']['NumAFfiles'])): - self.fst_vt['AeroDyn15']['AFNames'][afi] = os.path.join('Airfoils', self.FAST_namingOut + '_AeroDyn15_Polar_%02d.dat'%afi) - af_file = os.path.join(self.FAST_runDirectory, self.fst_vt['AeroDyn15']['AFNames'][afi]) + self.fst_vt['AeroDyn']['AFNames'][afi] = os.path.join('Airfoils', self.FAST_namingOut + '_AeroDyn_Polar_%02d.dat'%afi) + af_file = os.path.join(self.FAST_runDirectory, self.fst_vt['AeroDyn']['AFNames'][afi]) f = open(af_file, 'w') f.write('! ------------ AirfoilInfo Input File ----------------------------------\n') @@ -1079,91 +1025,91 @@ def write_AeroDyn15Polar(self): f.write('! line\n') f.write('! line\n') f.write('! ------------------------------------------------------------------------------\n') - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['af_data'][afi][0]['InterpOrd'], 'InterpOrd', '! Interpolation order to use for quasi-steady table lookup {1=linear; 3=cubic spline; "default"} [default=3]\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['af_data'][afi][0]['NonDimArea'], 'NonDimArea', '! The non-dimensional area of the airfoil (area/chord^2) (set to 1.0 if unsure or unneeded)\n')) - if self.fst_vt['AeroDyn15']['af_data'][afi][0]['NumCoords'] != '0': + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn']['af_data'][afi][0]['InterpOrd'], 'InterpOrd', '! Interpolation order to use for quasi-steady table lookup {1=linear; 3=cubic spline; "default"} [default=3]\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn']['af_data'][afi][0]['NonDimArea'], 'NonDimArea', '! The non-dimensional area of the airfoil (area/chord^2) (set to 1.0 if unsure or unneeded)\n')) + if self.fst_vt['AeroDyn']['af_data'][afi][0]['NumCoords'] != '0': f.write('@"{:}_AF{:02d}_Coords.txt" {:<11} {:}'.format(self.FAST_namingOut, afi, 'NumCoords', '! The number of coordinates in the airfoil shape file. Set to zero if coordinates not included.\n')) else: f.write('{:<22d} {:<11} {:}'.format(0, 'NumCoords', '! The number of coordinates in the airfoil shape file. Set to zero if coordinates not included.\n')) f.write('AF{:02d}_BL.txt {:<11} {:}'.format(afi, 'BL_file', '! The file name including the boundary layer characteristics of the profile. Ignored if the aeroacoustic module is not called.\n')) - # f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['af_data'][afi][0]['NumTabs'], 'NumTabs', '! Number of airfoil tables in this file. Each table must have lines for Re and Ctrl.\n')) + # f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn']['af_data'][afi][0]['NumTabs'], 'NumTabs', '! Number of airfoil tables in this file. Each table must have lines for Re and Ctrl.\n')) # Check if we have multiple tables per airfoil # if yes, allocate the number of airfoils to the respective radial stations - if self.fst_vt['AeroDyn15']['AFTabMod'] == 2: - num_tab = len(self.fst_vt['AeroDyn15']['af_data'][afi]) - elif self.fst_vt['AeroDyn15']['AFTabMod'] == 3: - # for tab_orig in range(self.fst_vt['AeroDyn15']['af_data'][afi][0]['NumTabs'] - 1): - if len( self.fst_vt['AeroDyn15']['af_data'][afi]) == 1 or \ - self.fst_vt['AeroDyn15']['af_data'][afi][0]['Ctrl'] == self.fst_vt['AeroDyn15']['af_data'][afi][1]['Ctrl']: + if self.fst_vt['AeroDyn']['AFTabMod'] == 2: + num_tab = len(self.fst_vt['AeroDyn']['af_data'][afi]) + elif self.fst_vt['AeroDyn']['AFTabMod'] == 3: + # for tab_orig in range(self.fst_vt['AeroDyn']['af_data'][afi][0]['NumTabs'] - 1): + if len( self.fst_vt['AeroDyn']['af_data'][afi]) == 1 or \ + self.fst_vt['AeroDyn']['af_data'][afi][0]['Ctrl'] == self.fst_vt['AeroDyn']['af_data'][afi][1]['Ctrl']: num_tab = 1 # assume that all Ctrl angles of the flaps are identical if the first two are -> no flaps! else: - num_tab = self.fst_vt['AeroDyn15']['af_data'][afi][0]['NumTabs'] + num_tab = self.fst_vt['AeroDyn']['af_data'][afi][0]['NumTabs'] else: num_tab = 1 - # f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['af_data'][afi][0]['NumTabs'], 'NumTabs','! Number of airfoil tables in this file. Each table must have lines for Re and Ctrl.\n')) + # f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn']['af_data'][afi][0]['NumTabs'], 'NumTabs','! Number of airfoil tables in this file. Each table must have lines for Re and Ctrl.\n')) f.write('{:<22d} {:<11} {:}'.format(num_tab, 'NumTabs','! Number of airfoil tables in this file. Each table must have lines for Re and Ctrl.\n')) - # for tab in range(self.fst_vt['AeroDyn15']['af_data'][afi][0]['NumTabs']): # For writing multiple tables (different Re or Ctrl values) + # for tab in range(self.fst_vt['AeroDyn']['af_data'][afi][0]['NumTabs']): # For writing multiple tables (different Re or Ctrl values) for tab in range(num_tab): # For writing multiple tables (different Re or Ctrl values) f.write('! ------------------------------------------------------------------------------\n') f.write("! data for table %i \n" % (tab + 1)) f.write('! ------------------------------------------------------------------------------\n') - f.write('{:<22f} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['af_data'][afi][tab]['Re']*1.e-6, 'Re', '! Reynolds number in millions\n')) - f.write('{:<22d} {:<11} {:}'.format(int(self.fst_vt['AeroDyn15']['af_data'][afi][tab]['Ctrl']), 'Ctrl', '! Control setting (must be 0 for current AirfoilInfo)\n')) - f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['af_data'][afi][tab]['InclUAdata'], 'InclUAdata', '! Is unsteady aerodynamics data included in this table? If TRUE, then include 30 UA coefficients below this line\n')) + f.write('{:<22f} {:<11} {:}'.format(self.fst_vt['AeroDyn']['af_data'][afi][tab]['Re']*1.e-6, 'Re', '! Reynolds number in millions\n')) + f.write('{:<22d} {:<11} {:}'.format(int(self.fst_vt['AeroDyn']['af_data'][afi][tab]['Ctrl']), 'Ctrl', '! Control setting (must be 0 for current AirfoilInfo)\n')) + f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn']['af_data'][afi][tab]['InclUAdata'], 'InclUAdata', '! Is unsteady aerodynamics data included in this table? If TRUE, then include 30 UA coefficients below this line\n')) f.write('!........................................\n') - if self.fst_vt['AeroDyn15']['af_data'][afi][tab]['InclUAdata']: - f.write('{:<22f} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['af_data'][afi][tab]['alpha0'], 'alpha0', '! 0-lift angle of attack, depends on airfoil.\n')) - f.write('{:<22f} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['af_data'][afi][tab]['alpha1'], 'alpha1', '! Angle of attack at f=0.7, (approximately the stall angle) for AOA>alpha0. (deg)\n')) - f.write('{:<22f} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['af_data'][afi][tab]['alpha2'], 'alpha2', '! Angle of attack at f=0.7, (approximately the stall angle) for AOA1]\n')) - f.write('{:<22f} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['af_data'][afi][tab]['S2'], 'S2', '! Constant in the f curve best-fit for AOA> alpha1; by definition it depends on the airfoil. [ignored if UA_Mod<>1]\n')) - f.write('{:<22f} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['af_data'][afi][tab]['S3'], 'S3', '! Constant in the f curve best-fit for alpha2<=AOA< alpha0; by definition it depends on the airfoil. [ignored if UA_Mod<>1]\n')) - f.write('{:<22f} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['af_data'][afi][tab]['S4'], 'S4', '! Constant in the f curve best-fit for AOA< alpha2; by definition it depends on the airfoil. [ignored if UA_Mod<>1]\n')) - f.write('{:<22f} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['af_data'][afi][tab]['Cn1'], 'Cn1', '! Critical value of C0n at leading edge separation. It should be extracted from airfoil data at a given Mach and Reynolds number. It can be calculated from the static value of Cn at either the break in the pitching moment or the loss of chord force at the onset of stall. It is close to the condition of maximum lift of the airfoil at low Mach numbers.\n')) - f.write('{:<22f} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['af_data'][afi][tab]['Cn2'], 'Cn2', '! As Cn1 for negative AOAs.\n')) - # f.write('{: 22f} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['af_data'][afi]['St_sh'], 'St_sh', "! Strouhal's shedding frequency constant. [default = 0.19]\n")) - f.write(float_default_out(self.fst_vt['AeroDyn15']['af_data'][afi][tab]['St_sh']) + ' {:<11} {:}'.format('St_sh', "! Strouhal's shedding frequency constant. [default = 0.19]\n")) - f.write('{:<22f} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['af_data'][afi][tab]['Cd0'], 'Cd0', '! 2D drag coefficient value at 0-lift.\n')) - f.write('{:<22f} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['af_data'][afi][tab]['Cm0'], 'Cm0', '! 2D pitching moment coefficient about 1/4-chord location, at 0-lift, positive if nose up. [If the aerodynamics coefficients table does not include a column for Cm, this needs to be set to 0.0]\n')) - f.write('{:<22f} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['af_data'][afi][tab]['k0'], 'k0', '! Constant in the \\hat(x)_cp curve best-fit; = (\\hat(x)_AC-0.25). [ignored if UA_Mod<>1]\n')) - f.write('{:<22f} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['af_data'][afi][tab]['k1'], 'k1', '! Constant in the \\hat(x)_cp curve best-fit. [ignored if UA_Mod<>1]\n')) - f.write('{:<22f} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['af_data'][afi][tab]['k2'], 'k2', '! Constant in the \\hat(x)_cp curve best-fit. [ignored if UA_Mod<>1]\n')) - f.write('{:<22f} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['af_data'][afi][tab]['k3'], 'k3', '! Constant in the \\hat(x)_cp curve best-fit. [ignored if UA_Mod<>1]\n')) - f.write('{:<22f} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['af_data'][afi][tab]['k1_hat'], 'k1_hat', '! Constant in the expression of Cc due to leading edge vortex effects. [ignored if UA_Mod<>1]\n')) - f.write(float_default_out(self.fst_vt['AeroDyn15']['af_data'][afi][tab]['x_cp_bar']) + ' {:<11} {:}'.format('x_cp_bar', '! Constant in the expression of \\hat(x)_cp^v. [ignored if UA_Mod<>1, default = 0.2]\n')) - f.write(float_default_out(self.fst_vt['AeroDyn15']['af_data'][afi][tab]['UACutout']) + ' {:<11} {:}'.format('UACutout', '! Angle of attack above which unsteady aerodynamics are disabled (deg). [Specifying the string "Default" sets UACutout to 45 degrees]\n')) - f.write(float_default_out(self.fst_vt['AeroDyn15']['af_data'][afi][tab]['filtCutOff']) + ' {:<11} {:}'.format('filtCutOff', '! Cut-off frequency (-3 dB corner frequency) for low-pass filtering the AoA input to UA, as well as the 1st and 2nd derivatives (Hz) [default = 20]\n')) + if self.fst_vt['AeroDyn']['af_data'][afi][tab]['InclUAdata']: + f.write('{:<22f} {:<11} {:}'.format(self.fst_vt['AeroDyn']['af_data'][afi][tab]['alpha0'], 'alpha0', '! 0-lift angle of attack, depends on airfoil.\n')) + f.write('{:<22f} {:<11} {:}'.format(self.fst_vt['AeroDyn']['af_data'][afi][tab]['alpha1'], 'alpha1', '! Angle of attack at f=0.7, (approximately the stall angle) for AOA>alpha0. (deg)\n')) + f.write('{:<22f} {:<11} {:}'.format(self.fst_vt['AeroDyn']['af_data'][afi][tab]['alpha2'], 'alpha2', '! Angle of attack at f=0.7, (approximately the stall angle) for AOA1]\n')) + f.write('{:<22f} {:<11} {:}'.format(self.fst_vt['AeroDyn']['af_data'][afi][tab]['S2'], 'S2', '! Constant in the f curve best-fit for AOA> alpha1; by definition it depends on the airfoil. [ignored if UA_Mod<>1]\n')) + f.write('{:<22f} {:<11} {:}'.format(self.fst_vt['AeroDyn']['af_data'][afi][tab]['S3'], 'S3', '! Constant in the f curve best-fit for alpha2<=AOA< alpha0; by definition it depends on the airfoil. [ignored if UA_Mod<>1]\n')) + f.write('{:<22f} {:<11} {:}'.format(self.fst_vt['AeroDyn']['af_data'][afi][tab]['S4'], 'S4', '! Constant in the f curve best-fit for AOA< alpha2; by definition it depends on the airfoil. [ignored if UA_Mod<>1]\n')) + f.write('{:<22f} {:<11} {:}'.format(self.fst_vt['AeroDyn']['af_data'][afi][tab]['Cn1'], 'Cn1', '! Critical value of C0n at leading edge separation. It should be extracted from airfoil data at a given Mach and Reynolds number. It can be calculated from the static value of Cn at either the break in the pitching moment or the loss of chord force at the onset of stall. It is close to the condition of maximum lift of the airfoil at low Mach numbers.\n')) + f.write('{:<22f} {:<11} {:}'.format(self.fst_vt['AeroDyn']['af_data'][afi][tab]['Cn2'], 'Cn2', '! As Cn1 for negative AOAs.\n')) + # f.write('{: 22f} {:<11} {:}'.format(self.fst_vt['AeroDyn']['af_data'][afi]['St_sh'], 'St_sh', "! Strouhal's shedding frequency constant. [default = 0.19]\n")) + f.write(float_default_out(self.fst_vt['AeroDyn']['af_data'][afi][tab]['St_sh']) + ' {:<11} {:}'.format('St_sh', "! Strouhal's shedding frequency constant. [default = 0.19]\n")) + f.write('{:<22f} {:<11} {:}'.format(self.fst_vt['AeroDyn']['af_data'][afi][tab]['Cd0'], 'Cd0', '! 2D drag coefficient value at 0-lift.\n')) + f.write('{:<22f} {:<11} {:}'.format(self.fst_vt['AeroDyn']['af_data'][afi][tab]['Cm0'], 'Cm0', '! 2D pitching moment coefficient about 1/4-chord location, at 0-lift, positive if nose up. [If the aerodynamics coefficients table does not include a column for Cm, this needs to be set to 0.0]\n')) + f.write('{:<22f} {:<11} {:}'.format(self.fst_vt['AeroDyn']['af_data'][afi][tab]['k0'], 'k0', '! Constant in the \\hat(x)_cp curve best-fit; = (\\hat(x)_AC-0.25). [ignored if UA_Mod<>1]\n')) + f.write('{:<22f} {:<11} {:}'.format(self.fst_vt['AeroDyn']['af_data'][afi][tab]['k1'], 'k1', '! Constant in the \\hat(x)_cp curve best-fit. [ignored if UA_Mod<>1]\n')) + f.write('{:<22f} {:<11} {:}'.format(self.fst_vt['AeroDyn']['af_data'][afi][tab]['k2'], 'k2', '! Constant in the \\hat(x)_cp curve best-fit. [ignored if UA_Mod<>1]\n')) + f.write('{:<22f} {:<11} {:}'.format(self.fst_vt['AeroDyn']['af_data'][afi][tab]['k3'], 'k3', '! Constant in the \\hat(x)_cp curve best-fit. [ignored if UA_Mod<>1]\n')) + f.write('{:<22f} {:<11} {:}'.format(self.fst_vt['AeroDyn']['af_data'][afi][tab]['k1_hat'], 'k1_hat', '! Constant in the expression of Cc due to leading edge vortex effects. [ignored if UA_Mod<>1]\n')) + f.write(float_default_out(self.fst_vt['AeroDyn']['af_data'][afi][tab]['x_cp_bar']) + ' {:<11} {:}'.format('x_cp_bar', '! Constant in the expression of \\hat(x)_cp^v. [ignored if UA_Mod<>1, default = 0.2]\n')) + f.write(float_default_out(self.fst_vt['AeroDyn']['af_data'][afi][tab]['UACutout']) + ' {:<11} {:}'.format('UACutout', '! Angle of attack above which unsteady aerodynamics are disabled (deg). [Specifying the string "Default" sets UACutout to 45 degrees]\n')) + f.write(float_default_out(self.fst_vt['AeroDyn']['af_data'][afi][tab]['filtCutOff']) + ' {:<11} {:}'.format('filtCutOff', '! Cut-off frequency (-3 dB corner frequency) for low-pass filtering the AoA input to UA, as well as the 1st and 2nd derivatives (Hz) [default = 20]\n')) f.write('!........................................\n') f.write('! Table of aerodynamics coefficients\n') - f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['af_data'][afi][tab]['NumAlf'], 'NumAlf', '! Number of data lines in the following table\n')) + f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn']['af_data'][afi][tab]['NumAlf'], 'NumAlf', '! Number of data lines in the following table\n')) f.write('! Alpha Cl Cd Cm\n') f.write('! (deg) (-) (-) (-)\n') - polar_map = [self.fst_vt['AeroDyn15']['InCol_Alfa'], self.fst_vt['AeroDyn15']['InCol_Cl'], self.fst_vt['AeroDyn15']['InCol_Cd'], self.fst_vt['AeroDyn15']['InCol_Cm'], self.fst_vt['AeroDyn15']['InCol_Cpmin']] + polar_map = [self.fst_vt['AeroDyn']['InCol_Alfa'], self.fst_vt['AeroDyn']['InCol_Cl'], self.fst_vt['AeroDyn']['InCol_Cd'], self.fst_vt['AeroDyn']['InCol_Cm'], self.fst_vt['AeroDyn']['InCol_Cpmin']] polar_map.remove(0) polar_map = [i-1 for i in polar_map] - alpha = np.asarray(self.fst_vt['AeroDyn15']['af_data'][afi][tab]['Alpha']) - cl = np.asarray(self.fst_vt['AeroDyn15']['af_data'][afi][tab]['Cl']) - cd = np.asarray(self.fst_vt['AeroDyn15']['af_data'][afi][tab]['Cd']) - cm = np.asarray(self.fst_vt['AeroDyn15']['af_data'][afi][tab]['Cm']) - cpmin = np.asarray(self.fst_vt['AeroDyn15']['af_data'][afi][tab]['Cpmin']) + alpha = np.asarray(self.fst_vt['AeroDyn']['af_data'][afi][tab]['Alpha']) + cl = np.asarray(self.fst_vt['AeroDyn']['af_data'][afi][tab]['Cl']) + cd = np.asarray(self.fst_vt['AeroDyn']['af_data'][afi][tab]['Cd']) + cm = np.asarray(self.fst_vt['AeroDyn']['af_data'][afi][tab]['Cm']) + cpmin = np.asarray(self.fst_vt['AeroDyn']['af_data'][afi][tab]['Cpmin']) if alpha[0] != -180.: print('Airfoil number ' + str(afi) + ' tab number ' + str(tab) + ' has the min angle of attack different than -180 deg, and equal to ' + str(alpha[0]) + ' deg. This is changed to -180 deg now.') @@ -1181,9 +1127,9 @@ def write_AeroDyn15Polar(self): print('Airfoil number ' + str(afi) + ' tab number ' + str(tab) + ' has the moment coefficient different between +-180 deg. This is changed to be the same now.') cm[0] = cm[-1] - if self.fst_vt['AeroDyn15']['InCol_Cm'] == 0: + if self.fst_vt['AeroDyn']['InCol_Cm'] == 0: cm = np.zeros_like(cl) - if self.fst_vt['AeroDyn15']['InCol_Cpmin'] == 0: + if self.fst_vt['AeroDyn']['InCol_Cpmin'] == 0: cpmin = np.zeros_like(cl) polar = np.column_stack((alpha, cl, cd, cm, cpmin)) polar = polar[:,polar_map] @@ -1196,25 +1142,25 @@ def write_AeroDyn15Polar(self): os.fsync(f) f.close() - def write_AeroDyn15Coord(self): + def write_AeroDynCoord(self): - self.fst_vt['AeroDyn15']['AFNames_coord'] = ['']*self.fst_vt['AeroDyn15']['NumAFfiles'] + self.fst_vt['AeroDyn']['AFNames_coord'] = ['']*self.fst_vt['AeroDyn']['NumAFfiles'] - for afi in range(int(self.fst_vt['AeroDyn15']['NumAFfiles'])): - self.fst_vt['AeroDyn15']['AFNames_coord'][afi] = os.path.join('Airfoils', self.FAST_namingOut + '_AF%02d_Coords.txt'%afi) + for afi in range(int(self.fst_vt['AeroDyn']['NumAFfiles'])): + self.fst_vt['AeroDyn']['AFNames_coord'][afi] = os.path.join('Airfoils', self.FAST_namingOut + '_AF%02d_Coords.txt'%afi) - x = self.fst_vt['AeroDyn15']['af_coord'][afi]['x'] - y = self.fst_vt['AeroDyn15']['af_coord'][afi]['y'] + x = self.fst_vt['AeroDyn']['af_coord'][afi]['x'] + y = self.fst_vt['AeroDyn']['af_coord'][afi]['y'] coord = np.vstack((x, y)).T - af_file = os.path.join(self.FAST_runDirectory, self.fst_vt['AeroDyn15']['AFNames_coord'][afi]) + af_file = os.path.join(self.FAST_runDirectory, self.fst_vt['AeroDyn']['AFNames_coord'][afi]) f = open(af_file, 'w') f.write('{: 22d} {:<11} {:}'.format(len(x)+1, 'NumCoords', '! The number of coordinates in the airfoil shape file (including an extra coordinate for airfoil reference). Set to zero if coordinates not included.\n')) f.write('! ......... x-y coordinates are next if NumCoords > 0 .............\n') f.write('! x-y coordinate of airfoil reference\n') f.write('! x/c y/c\n') - f.write('{: 5f} 0\n'.format(self.fst_vt['AeroDyn15']['ac'][afi])) + f.write('{: 5f} 0\n'.format(self.fst_vt['AeroDyn']['ac'][afi])) f.write('! coordinates of airfoil shape\n') f.write('! interpolation to 200 points\n') f.write('! x/c y/c\n') @@ -1225,140 +1171,6 @@ def write_AeroDyn15Coord(self): os.fsync(f) f.close() - def write_AeroDyn14(self): - - # ======= Airfoil Files ======== - # make directory for airfoil files - if not os.path.isdir(os.path.join(self.FAST_runDirectory,'AeroData')): - try: - os.mkdir(os.path.join(self.FAST_runDirectory,'AeroData')) - except: - try: - time.sleep(random.random()) - if not os.path.isdir(os.path.join(self.FAST_runDirectory,'AeroData')): - os.mkdir(os.path.join(self.FAST_runDirectory,'AeroData')) - except: - print("Error tring to make '%s'!"%os.path.join(self.FAST_runDirectory,'AeroData')) - - # create write airfoil objects to files - for i in range(self.fst_vt['AeroDyn14']['NumFoil']): - af_name = os.path.join(self.FAST_runDirectory, 'AeroData', 'Airfoil' + str(i) + '.dat') - self.fst_vt['AeroDyn14']['FoilNm'][i] = os.path.join('AeroData', 'Airfoil' + str(i) + '.dat') - self.write_AeroDyn14Polar(af_name, i) - - self.fst_vt['Fst']['AeroFile'] = self.FAST_namingOut + '_AeroDyn14.dat' - ad_file = os.path.join(self.FAST_runDirectory,self.fst_vt['Fst']['AeroFile']) - f = open(ad_file,'w') - - # create Aerodyn Tower - if self.fst_vt['AeroDyn14']['TwrShad'] > 0: - self.write_AeroDyn14Tower() - - # ======= Aerodyn Input File ======== - f.write('AeroDyn v14.04.* INPUT FILE\n\n') - - # f.write('{:}\n'.format(self.fst_vt['aerodyn']['SysUnits'])) - f.write('{:}\n'.format(self.fst_vt['AeroDyn14']['StallMod'])) - - f.write('{:}\n'.format(self.fst_vt['AeroDyn14']['UseCm'])) - f.write('{:}\n'.format(self.fst_vt['AeroDyn14']['InfModel'])) - f.write('{:}\n'.format(self.fst_vt['AeroDyn14']['IndModel'])) - f.write('{: 2.15e}\n'.format(self.fst_vt['AeroDyn14']['AToler'])) - f.write('{:}\n'.format(self.fst_vt['AeroDyn14']['TLModel'])) - f.write('{:}\n'.format(self.fst_vt['AeroDyn14']['HLModel'])) - f.write('{:}\n'.format(self.fst_vt['AeroDyn14']['TwrShad'])) - if self.fst_vt['AeroDyn14']['TwrShad'] > 0: - f.write('{:}\n'.format(self.fst_vt['AeroDyn14']['TwrPotent'])) - f.write('{:}\n'.format(self.fst_vt['AeroDyn14']['TwrShadow'])) - f.write('{:}\n'.format(self.fst_vt['AeroDyn14']['TwrFile'])) - f.write('{:}\n'.format(self.fst_vt['AeroDyn14']['CalcTwrAero'])) - else: - f.write('{: 2.15e}\n'.format(self.fst_vt['AeroDyn14']['ShadHWid'])) - f.write('{: 2.15e}\n'.format(self.fst_vt['AeroDyn14']['T_Shad_Refpt'])) - - f.write('{: 2.15e}\n'.format(self.fst_vt['AeroDyn14']['AirDens'])) - - f.write('{: 2.15e}\n'.format(self.fst_vt['AeroDyn14']['KinVisc'])) - - f.write('{:2}\n'.format(self.fst_vt['AeroDyn14']['DTAero'])) - - - f.write('{:2}\n'.format(self.fst_vt['AeroDyn14']['NumFoil'])) - for i in range (self.fst_vt['AeroDyn14']['NumFoil']): - f.write('"{:}"\n'.format(self.fst_vt['AeroDyn14']['FoilNm'][i])) - - f.write('{:2}\n'.format(self.fst_vt['AeroDynBlade']['BldNodes'])) - rnodes = self.fst_vt['AeroDynBlade']['RNodes'] - twist = self.fst_vt['AeroDynBlade']['AeroTwst'] - drnodes = self.fst_vt['AeroDynBlade']['DRNodes'] - chord = self.fst_vt['AeroDynBlade']['Chord'] - nfoil = self.fst_vt['AeroDynBlade']['NFoil'] - prnelm = self.fst_vt['AeroDynBlade']['PrnElm'] - f.write('Nodal properties\n') - for r, t, dr, c, a, p in zip(rnodes, twist, drnodes, chord, nfoil, prnelm): - f.write('{: 2.15e}\t{: 2.15e}\t{: 2.15e}\t{: 2.15e}\t{:5}\t{:}\n'.format(r, t, dr, c, a, p)) - - f.flush() - os.fsync(f) - f.close() - - def write_AeroDyn14Tower(self): - # AeroDyn v14.04 Tower - self.fst_vt['AeroDyn14']['TwrFile'] = self.FAST_namingOut + '_AeroDyn14_tower.dat' - filename = os.path.join(self.FAST_runDirectory, self.fst_vt['AeroDyn14']['TwrFile']) - f = open(filename, 'w') - - f.write('AeroDyn tower file, Aerodyn v14.04 formatting\n') - f.write('Generated with OpenFAST_IO\n') - f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDynTower']['NTwrHt'], 'NTwrHt', '- Number of tower input height stations listed (-)\n')) - f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDynTower']['NTwrRe'], 'NTwrRe', '- Number of tower Re values (-)\n')) - f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDynTower']['NTwrCD'], 'NTwrCD', '- Number of tower CD columns (-) Note: For current versions, this MUST be 1\n')) - f.write('{: 2.15e} {:<11} {:}'.format(self.fst_vt['AeroDynTower']['Tower_Wake_Constant'], 'Tower_Wake_Constant', '- Tower wake constant (-) {0.0: full potential flow, 0.1: Bak model}\n')) - f.write('---------------------- DISTRIBUTED TOWER PROPERTIES ----------------------------\n') - f.write('TwrHtFr TwrWid NTwrCDCol\n') - for HtFr, Wid, CDId in zip(self.fst_vt['AeroDynTower']['TwrHtFr'], self.fst_vt['AeroDynTower']['TwrWid'], self.fst_vt['AeroDynTower']['NTwrCDCol']): - f.write('{: 2.15e} {: 2.15e} {:d}\n'.format(HtFr, Wid, int(CDId))) - f.write('---------------------- Re v CD PROPERTIES --------------------------------------\n') - f.write('TwrRe '+ ' '.join(['TwrCD%d'%(i+1) for i in range(self.fst_vt['AeroDynTower']['NTwrCD'])]) +'\n') - for Re, CD in zip(self.fst_vt['AeroDynTower']['TwrRe'], self.fst_vt['AeroDynTower']['TwrCD']): - f.write('% 2.15e' %Re + ' '.join(['% 2.15e'%cdi for cdi in CD]) + '\n') - - f.flush() - os.fsync(f) - f.close() - - def write_AeroDyn14Polar(self, filename, a_i): - # AeroDyn v14 Airfoil Polar Input File - - f = open(filename, 'w') - f.write('AeroDyn airfoil file, Aerodyn v14.04 formatting\n') - f.write('Generated with OpenFAST_IO\n') - - f.write('{:9d}\t{:}'.format(self.fst_vt['AeroDynBlade']['af_data'][a_i]['number_tables'], 'Number of airfoil tables in this file\n')) - for i in range(self.fst_vt['AeroDynBlade']['af_data'][a_i]['number_tables']): - param = self.fst_vt['AeroDynBlade']['af_data'][a_i]['af_tables'][i] - f.write('{:9g}\t{:}'.format(i, 'Table ID parameter\n')) - f.write('{: f}\t{:}'.format(param['StallAngle'], 'Stall angle (deg)\n')) - f.write('{: f}\t{:}'.format(0, 'No longer used, enter zero\n')) - f.write('{: f}\t{:}'.format(0, 'No longer used, enter zero\n')) - f.write('{: f}\t{:}'.format(0, 'No longer used, enter zero\n')) - f.write('{: f}\t{:}'.format(param['ZeroCn'], 'Angle of attack for zero Cn for linear Cn curve (deg)\n')) - f.write('{: f}\t{:}'.format(param['CnSlope'], 'Cn slope for zero lift for linear Cn curve (1/rad)\n')) - f.write('{: f}\t{:}'.format(param['CnPosStall'], 'Cn at stall value for positive angle of attack for linear Cn curve\n')) - f.write('{: f}\t{:}'.format(param['CnNegStall'], 'Cn at stall value for negative angle of attack for linear Cn curve\n')) - f.write('{: f}\t{:}'.format(param['alphaCdMin'], 'Angle of attack for minimum CD (deg)\n')) - f.write('{: f}\t{:}'.format(param['CdMin'], 'Minimum CD value\n')) - if param['cm']: - for a, cl, cd, cm in zip(param['alpha'], param['cl'], param['cd'], param['cm']): - f.write('{: 6e} {: 6e} {: 6e} {: 6e}\n'.format(a, cl, cd, cm)) - else: - for a, cl, cd in zip(param['alpha'], param['cl'], param['cd']): - f.write('{: 6e} {: 6e} {: 6e}\n'.format(a, cl, cd)) - - f.flush() - os.fsync(f) - f.close() - def write_OLAF(self): olaf_file = os.path.join(self.FAST_runDirectory, self.FAST_namingOut + '_OLAF.dat') @@ -1367,46 +1179,46 @@ def write_OLAF(self): f.write('--------------------------- OLAF (cOnvecting LAgrangian Filaments) INPUT FILE -----------------\n') f.write('Generated by OpenFAST_IO\n') f.write('--------------------------- GENERAL OPTIONS ---------------------------------------------------\n') - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['OLAF']['IntMethod'], 'IntMethod', '- Integration method {1: RK4, 5: Forward Euler 1st order, default: 5} (switch)\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['OLAF']['DTfvw'], 'DTfvw', '- Time interval for wake propagation. {default: dtaero} (s)\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['OLAF']['FreeWakeStart'], 'FreeWakeStart', '- Time when wake is free. (-) value = always free. {default: 0.0} (s)\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['OLAF']['FullCircStart'], 'FullCircStart', '- Time at which full circulation is reached. {default: 0.0} (s)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn']['OLAF']['IntMethod'], 'IntMethod', '- Integration method {1: RK4, 5: Forward Euler 1st order, default: 5} (switch)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn']['OLAF']['DTfvw'], 'DTfvw', '- Time interval for wake propagation. {default: dtaero} (s)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn']['OLAF']['FreeWakeStart'], 'FreeWakeStart', '- Time when wake is free. (-) value = always free. {default: 0.0} (s)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn']['OLAF']['FullCircStart'], 'FullCircStart', '- Time at which full circulation is reached. {default: 0.0} (s)\n')) f.write('--------------------------- CIRCULATION SPECIFICATIONS ----------------------------------------\n') - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['OLAF']['CircSolvMethod'], 'CircSolvingMethod', '- Circulation solving method {1: Cl-Based, 2: No-Flow Through, 3: Prescribed, default: 1 }(switch)\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['OLAF']['CircSolvConvCrit'], 'CircSolvConvCrit', ' - Convergence criteria {default: 0.001} [only if CircSolvMethod=1] (-)\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['OLAF']['CircSolvRelaxation'], 'CircSolvRelaxation', '- Relaxation factor {default: 0.1} [only if CircSolvMethod=1] (-)\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['OLAF']['CircSolvMaxIter'], 'CircSolvMaxIter', ' - Maximum number of iterations for circulation solving {default: 30} (-)\n')) - f.write('{:<22} {:<11} {:}'.format('"'+self.fst_vt['AeroDyn15']['OLAF']['PrescribedCircFile']+'"', 'PrescribedCircFile','- File containing prescribed circulation [only if CircSolvMethod=3] (quoted string)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn']['OLAF']['CircSolvMethod'], 'CircSolvingMethod', '- Circulation solving method {1: Cl-Based, 2: No-Flow Through, 3: Prescribed, default: 1 }(switch)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn']['OLAF']['CircSolvConvCrit'], 'CircSolvConvCrit', ' - Convergence criteria {default: 0.001} [only if CircSolvMethod=1] (-)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn']['OLAF']['CircSolvRelaxation'], 'CircSolvRelaxation', '- Relaxation factor {default: 0.1} [only if CircSolvMethod=1] (-)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn']['OLAF']['CircSolvMaxIter'], 'CircSolvMaxIter', ' - Maximum number of iterations for circulation solving {default: 30} (-)\n')) + f.write('{:<22} {:<11} {:}'.format('"'+self.fst_vt['AeroDyn']['OLAF']['PrescribedCircFile']+'"', 'PrescribedCircFile','- File containing prescribed circulation [only if CircSolvMethod=3] (quoted string)\n')) f.write('===============================================================================================\n') f.write('--------------------------- WAKE OPTIONS ------------------------------------------------------\n') f.write('------------------- WAKE EXTENT AND DISCRETIZATION --------------------------------------------\n') - f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['OLAF']['nNWPanels'], 'nNWPanels','- Number of near-wake panels (-)\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['OLAF']['nNWPanelsFree'], 'nNWPanelsFree','- Number of free near-wake panels (-) {default: nNWPanels}\n')) - f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['OLAF']['nFWPanels'], 'nFWPanels','- Number of far-wake panels (-) {default: 0}\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['OLAF']['nFWPanelsFree'], 'nFWPanelsFree','- Number of free far-wake panels (-) {default: nFWPanels}\n')) - f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['OLAF']['FWShedVorticity'], 'FWShedVorticity','- Include shed vorticity in the far wake {default: False}\n')) + f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn']['OLAF']['nNWPanels'], 'nNWPanels','- Number of near-wake panels (-)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn']['OLAF']['nNWPanelsFree'], 'nNWPanelsFree','- Number of free near-wake panels (-) {default: nNWPanels}\n')) + f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn']['OLAF']['nFWPanels'], 'nFWPanels','- Number of far-wake panels (-) {default: 0}\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn']['OLAF']['nFWPanelsFree'], 'nFWPanelsFree','- Number of free far-wake panels (-) {default: nFWPanels}\n')) + f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn']['OLAF']['FWShedVorticity'], 'FWShedVorticity','- Include shed vorticity in the far wake {default: False}\n')) f.write('------------------- WAKE REGULARIZATIONS AND DIFFUSION -----------------------------------------\n') - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['OLAF']['DiffusionMethod'], 'DiffusionMethod','- Diffusion method to account for viscous effects {0: None, 1: Core Spreading, "default": 0}\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['OLAF']['RegDeterMethod'], 'RegDeterMethod','- Method to determine the regularization parameters {0: Manual, 1: Optimized, 2: Chord, 3: Span, default: 0 }\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['OLAF']['RegFunction'], 'RegFunction','- Viscous diffusion function {0: None, 1: Rankine, 2: LambOseen, 3: Vatistas, 4: Denominator, "default": 3} (switch)\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['OLAF']['WakeRegMethod'], 'WakeRegMethod','- Wake regularization method {1: Constant, 2: Stretching, 3: Age, default: 3} (switch)\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['OLAF']['WakeRegFactor'], 'WakeRegFactor','- Wake regularization factor (m)\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['OLAF']['WingRegFactor'], 'WingRegFactor','- Wing regularization factor (m)\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['OLAF']['CoreSpreadEddyVisc'], 'CoreSpreadEddyVisc','- Eddy viscosity in core spreading methods, typical values 1-1000\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn']['OLAF']['DiffusionMethod'], 'DiffusionMethod','- Diffusion method to account for viscous effects {0: None, 1: Core Spreading, "default": 0}\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn']['OLAF']['RegDeterMethod'], 'RegDeterMethod','- Method to determine the regularization parameters {0: Manual, 1: Optimized, 2: Chord, 3: Span, default: 0 }\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn']['OLAF']['RegFunction'], 'RegFunction','- Viscous diffusion function {0: None, 1: Rankine, 2: LambOseen, 3: Vatistas, 4: Denominator, "default": 3} (switch)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn']['OLAF']['WakeRegMethod'], 'WakeRegMethod','- Wake regularization method {1: Constant, 2: Stretching, 3: Age, default: 3} (switch)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn']['OLAF']['WakeRegFactor'], 'WakeRegFactor','- Wake regularization factor (m)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn']['OLAF']['WingRegFactor'], 'WingRegFactor','- Wing regularization factor (m)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn']['OLAF']['CoreSpreadEddyVisc'], 'CoreSpreadEddyVisc','- Eddy viscosity in core spreading methods, typical values 1-1000\n')) f.write('------------------- WAKE TREATMENT OPTIONS ---------------------------------------------------\n') - f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['OLAF']['TwrShadowOnWake'], 'TwrShadowOnWake','- Include tower flow disturbance effects on wake convection {default:false} [only if TwrPotent or TwrShadow]\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['OLAF']['ShearModel'], 'ShearModel','- Shear Model {0: No treatment, 1: Mirrored vorticity, default: 0}\n')) + f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn']['OLAF']['TwrShadowOnWake'], 'TwrShadowOnWake','- Include tower flow disturbance effects on wake convection {default:false} [only if TwrPotent or TwrShadow]\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn']['OLAF']['ShearModel'], 'ShearModel','- Shear Model {0: No treatment, 1: Mirrored vorticity, default: 0}\n')) f.write('------------------- SPEEDUP OPTIONS -----------------------------------------------------------\n') - f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['OLAF']['VelocityMethod'], 'VelocityMethod','- Method to determine the velocity {1:Segment N^2, 2:Particle tree, 3:Particle N^2, 4:Segment tree, default: 2}\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['OLAF']['TreeBranchFactor'], 'TreeBranchFactor','- Branch radius fraction above which a multipole calculation is used {default: 1.5} [only if VelocityMethod=2,4]\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['OLAF']['PartPerSegment'], 'PartPerSegment','- Number of particles per segment {default: 1} [only if VelocityMethod=2,3]\n')) + f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn']['OLAF']['VelocityMethod'], 'VelocityMethod','- Method to determine the velocity {1:Segment N^2, 2:Particle tree, 3:Particle N^2, 4:Segment tree, default: 2}\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn']['OLAF']['TreeBranchFactor'], 'TreeBranchFactor','- Branch radius fraction above which a multipole calculation is used {default: 1.5} [only if VelocityMethod=2,4]\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn']['OLAF']['PartPerSegment'], 'PartPerSegment','- Number of particles per segment {default: 1} [only if VelocityMethod=2,3]\n')) f.write('===============================================================================================\n') f.write('--------------------------- OUTPUT OPTIONS ---------------------------------------------------\n') - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['OLAF']['WrVTk'], 'WrVTk','- Outputs Visualization Toolkit (VTK) (independent of .fst option) {0: NoVTK, 1: Write VTK at VTK_fps, 2: Write VTK at init and final, default: 0} (flag)\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['OLAF']['nVTKBlades'], 'nVTKBlades','- Number of blades for which VTK files are exported {0: No VTK per blade, n: VTK for blade 1 to n, default: 0} (-) \n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['OLAF']['VTKCoord'], 'VTKCoord','- Coordinate system used for VTK export. {1: Global, 2: Hub, 3: Both, default: 1} \n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['OLAF']['VTK_fps'], 'VTK_fps','- Frame rate for VTK output (frames per second) {"all" for all glue code timesteps, "default" for all OLAF timesteps} [only if WrVTK=1]\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['OLAF']['nGridOut'], 'nGridOut','- Number of grid outputs\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn']['OLAF']['WrVTk'], 'WrVTk','- Outputs Visualization Toolkit (VTK) (independent of .fst option) {0: NoVTK, 1: Write VTK at VTK_fps, 2: Write VTK at init and final, default: 0} (flag)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn']['OLAF']['nVTKBlades'], 'nVTKBlades','- Number of blades for which VTK files are exported {0: No VTK per blade, n: VTK for blade 1 to n, default: 0} (-) \n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn']['OLAF']['VTKCoord'], 'VTKCoord','- Coordinate system used for VTK export. {1: Global, 2: Hub, 3: Both, default: 1} \n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn']['OLAF']['VTK_fps'], 'VTK_fps','- Frame rate for VTK output (frames per second) {"all" for all glue code timesteps, "default" for all OLAF timesteps} [only if WrVTK=1]\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn']['OLAF']['nGridOut'], 'nGridOut','- Number of grid outputs\n')) f.write('GridName GridType TStart TEnd DTGrid XStart XEnd nX YStart YEnd nY ZStart ZEnd nZ\n') f.write('(-) (-) (s) (s) (s) (m) (m) (-) (m) (m) (-) (m) (m) (-)\n') f.write('===============================================================================================\n') @@ -1419,31 +1231,6 @@ def write_OLAF(self): def write_AeroDisk(self): # Writing the aeroDisk input file - '''' - example input file: - - --- AERO DISK INPUT FILE ------- - NREL 5MW actuator disk input file - --- SIMULATION CONTROL --------- - true echo - Echo input data to ".ADsk.ech" (flag) - "default" DT - Integration time step (s) - --- ENVIRONMENTAL CONDITIONS --- - 1.225 AirDens - Air density (kg/m^3) (or "default") - --- ACTUATOR DISK PROPERTIES --- - 63.0 RotorRad - Rotor radius (m) (or "default") - "TSR, RtSpd , VRel, Skew , Pitch" InColNames - Input column headers (string) {may include a combination of "TSR, RtSpd, VRel, Pitch, Skew"} (up to 4 columns) [choose TSR or RtSpd,VRel; if Skew is absent, Skew is modeled as (COS(Skew))^2] - 48, 0, 0, 0, 104 InColDims - Number of unique values in each column (-) (must have same number of columns as InColName) [each >=2] - @CpCtCq.csv - --- OUTPUTS -------------------- - OutList - The next line(s) contains a list of output parameters. See OutListParameters.xlsx for a listing of available output channels, (-) - ADSpeed ! Actuator disk rotational speed (rpm) - ADTSR ! Actuator disk tip-speed ratio (-) - ADPitch ! Actuator-disk collective blade-pitch angle (deg) - ADVWindx ! Actuator-disk-averaged wind velocity (x) in the local coordinate system (m/s) - ADVWindy ! Actuator-disk-averaged wind velocity (y) in the local coordinate system (m/s) - ADVWindz - - ''' self.fst_vt['Fst']['AeroFile'] = self.FAST_namingOut + '_AeroDisk.dat' adisk_file = os.path.join(self.FAST_runDirectory,self.fst_vt['Fst']['AeroFile']) f = open(adisk_file,'w') @@ -2741,7 +2528,7 @@ def write_StC(self,StC_vt,StC_filename): fst_update = {} fst_update['Fst', 'TMax'] = 20. - fst_update['AeroDyn15', 'TwrAero'] = False + fst_update['AeroDyn', 'TwrAero'] = False parent_dir = os.path.dirname( os.path.dirname( os.path.dirname( os.path.realpath(__file__) ) ) ) + os.sep build_of_io_dir = os.path.join(parent_dir, 'build_ofio') diff --git a/openfast_io/openfast_io/tests/test_of_io.py b/openfast_io/openfast_io/tests/test_of_io.py index 697f3f4c4..453a23340 100644 --- a/openfast_io/openfast_io/tests/test_of_io.py +++ b/openfast_io/openfast_io/tests/test_of_io.py @@ -78,7 +78,7 @@ def testOF_Inputs(self): fast_writer.fst_vt = dict(fast_reader.fst_vt) fst_vt = {} fst_vt['Fst', 'TMax'] = 2. - fst_vt['AeroDyn15', 'TwrAero'] = False + fst_vt['AeroDyn', 'TwrAero'] = False fst_vt['Fst','CompMooring'] = 0 fst_vt['Fst','CompServo'] = 0 fst_vt['Fst','OutFileFmt'] = 3 From 662ee35b179d832d0361164b36219aa2a773f47c Mon Sep 17 00:00:00 2001 From: Mayank Chetan Date: Thu, 5 Sep 2024 15:02:27 +0000 Subject: [PATCH 049/161] remove old test --- openfast_io/openfast_io/tests/test_of_io.py | 122 -------------------- 1 file changed, 122 deletions(-) delete mode 100644 openfast_io/openfast_io/tests/test_of_io.py diff --git a/openfast_io/openfast_io/tests/test_of_io.py b/openfast_io/openfast_io/tests/test_of_io.py deleted file mode 100644 index 453a23340..000000000 --- a/openfast_io/openfast_io/tests/test_of_io.py +++ /dev/null @@ -1,122 +0,0 @@ -import unittest -import os.path as osp -import subprocess, sys -import platform - -from openfast_io.FAST_reader import InputReader_OpenFAST -from openfast_io.FAST_writer import InputWriter_OpenFAST -from openfast_io.FAST_output_reader import FASTOutputFile - -from openfast_io.FileTools import check_rtest_cloned -from pathlib import Path - -REPOSITORY_ROOT = osp.dirname(osp.dirname(osp.dirname(osp.dirname(__file__)))) -RTESTS_DIR = osp.join(REPOSITORY_ROOT, "reg_tests","r-test") -TEST_DATA_DIR = osp.join(RTESTS_DIR, "glue-codes", "openfast") - -RUN_DIR = osp.join(REPOSITORY_ROOT, "build_ofio", "testSuite") -Path(RUN_DIR).mkdir(parents=True, exist_ok=True) - - -# Exercising the various OpenFAST modules -FOLDERS_TO_RUN = [ - "5MW_Land_DLL_WTurb" , # "openfast;elastodyn;aerodyn15;servodyn") - "5MW_OC3Mnpl_DLL_WTurb_WavesIrr" , # "openfast;elastodyn;aerodyn15;servodyn;hydrodyn;subdyn;offshore") - "5MW_OC3Mnpl_DLL_WTurb_WavesIrr_Restart", # "openfast;elastodyn;aerodyn15;servodyn;hydrodyn;subdyn;offshore;restart") - "5MW_ITIBarge_DLL_WTurb_WavesIrr" , # "openfast;elastodyn;aerodyn15;servodyn;hydrodyn;map;offshore") - "5MW_OC4Semi_WSt_WavesWN" , # "openfast;elastodyn;aerodyn15;servodyn;hydrodyn;moordyn;offshore") - "5MW_Land_BD_DLL_WTurb" , # "openfast;beamdyn;aerodyn15;servodyn") - "5MW_OC4Jckt_ExtPtfm" , # "openfast;elastodyn;extptfm") - "HelicalWake_OLAF" , # "openfast;aerodyn15;olaf") - "StC_test_OC4Semi" , # "openfast;servodyn;hydrodyn;moordyn;offshore;stc") - "MHK_RM1_Fixed" , # "openfast;elastodyn;aerodyn15;mhk") - "MHK_RM1_Floating" , # "openfast;elastodyn;aerodyn15;hydrodyn;moordyn;mhk") - "Tailfin_FreeYaw1DOF_PolarBased" , # "openfast;elastodyn;aerodyn15") -] - -# looking up OS for the correct executable extension -mactype = platform.system().lower() -if mactype in ["linux", "linux2", "darwin"]: - exeExt = "" -elif mactype in ["win32", "windows", "cygwin"]: #NOTE: platform.system()='Windows', sys.platform='win32' - libext = '.exe' -else: - raise ValueError('Unknown platform type: '+mactype) - -# Path to the OpenFAST executable -of_path = osp.join(REPOSITORY_ROOT,"build/glue-codes/openfast",f"openfast{exeExt}") - -class TestOFutils(unittest.TestCase): - def testOF_Inputs(self): - - # Check if r-tests are available - if check_rtest_cloned(TEST_DATA_DIR): - sys.exit(1) - - # Check if OpenFAST executable is available else inform user - if not osp.exists(of_path): - print(f"OpenFAST executable not found at {of_path}. Please build OpenFAST and try again.") - sys.exit(1) - - - # Read input deck - fast_reader = InputReader_OpenFAST() - fast_writer = InputWriter_OpenFAST() - fast_reader.FAST_InputFile = '5MW_Land_DLL_WTurb.fst' # FAST input file (ext=.fst) - fast_reader.FAST_directory = TEST_DATA_DIR # Path to fst directory files - fast_writer.FAST_runDirectory = osp.join('temp','OpenFAST') - fast_writer.FAST_namingOut = 'nrel5mw' - - with self.subTest('Reading', i=0): - try: - fast_reader.execute() - self.assertTrue(True) - except: - self.assertEqual('Reading','Success') - - # Test the OF writer - fast_writer.fst_vt = dict(fast_reader.fst_vt) - fst_vt = {} - fst_vt['Fst', 'TMax'] = 2. - fst_vt['AeroDyn', 'TwrAero'] = False - fst_vt['Fst','CompMooring'] = 0 - fst_vt['Fst','CompServo'] = 0 - fst_vt['Fst','OutFileFmt'] = 3 - fast_writer.update(fst_update=fst_vt) - - with self.subTest('Writing', i=1): - try: - fast_writer.execute() - self.assertTrue(True) - except: - self.assertEqual('Writing','Success') - - with self.subTest('Running', i=2): - try: - subprocess.run([of_path, str(osp.join(fast_writer.FAST_runDirectory, fast_writer.FAST_namingOut+'.fst'))]) - self.assertTrue(True) - except: - self.assertEqual('Running','Success') - - def testOF_Outputs(self): - # Read output deck - asciiOutput = osp.join('temp','OpenFAST',f'nrel5mw.out') - binaryOutput = osp.join('temp','OpenFAST',f'nrel5mw.outb') - - with self.subTest('Reading ASCII output', i=0): - try: - fast_outout = FASTOutputFile(filename=asciiOutput) - self.assertTrue(True) - except: - self.assertEqual('Writing','Success') - - with self.subTest('Reading Binary output', i=1): - try: - fast_outout = FASTOutputFile(filename=binaryOutput) - self.assertTrue(True) - except: - self.assertEqual('Writing','Success') - - -if __name__ == "__main__": - unittest.main() From 3d709e918051112794241aa0ce9fbeb4ef114242 Mon Sep 17 00:00:00 2001 From: Mayank Chetan Date: Fri, 6 Sep 2024 04:42:24 +0000 Subject: [PATCH 050/161] AF coord changes + SubDyn api removal --- openfast_io/openfast_io/FAST_reader.py | 10 ++- openfast_io/openfast_io/FAST_writer.py | 17 ++-- .../openfast_io/tests/test_of_io_pytest.py | 80 +++++++++---------- 3 files changed, 59 insertions(+), 48 deletions(-) diff --git a/openfast_io/openfast_io/FAST_reader.py b/openfast_io/openfast_io/FAST_reader.py index ae64daafc..b56cb93f0 100644 --- a/openfast_io/openfast_io/FAST_reader.py +++ b/openfast_io/openfast_io/FAST_reader.py @@ -1196,7 +1196,13 @@ def read_AeroDynPolar(self): polar = {} polar['InterpOrd'] = int_read(readline_filterComments(f).split()[0]) - polar['NonDimArea'] = float_read(readline_filterComments(f).split()[0]) + temp = readline_filterComments(f).split() + if temp[1] == "RelThickness": + polar['RelThickness'] = float_read(temp[0]) + polar['NonDimArea'] = float_read(readline_filterComments(f).split()[0]) + else: + polar['NonDimArea'] = float_read(temp[0]) + # polar['NonDimArea'] = float_read(readline_filterComments(f).split()[0]) polar['NumCoords'] = readline_filterComments(f).split()[0] polar['BL_file'] = readline_filterComments(f).split()[0] polar['NumTabs'] = int_read(readline_filterComments(f).split()[0]) @@ -2233,7 +2239,7 @@ def read_SubDyn(self, sd_file): # FEA and CRAIG-BAMPTON PARAMETERS self.fst_vt['SubDyn']['FEMMod'] = int_read(f.readline().split()[0]) self.fst_vt['SubDyn']['NDiv'] = int_read(f.readline().split()[0]) - self.fst_vt['SubDyn']['CBMod'] = bool_read(f.readline().split()[0]) + # self.fst_vt['SubDyn']['CBMod'] = bool_read(f.readline().split()[0]) self.fst_vt['SubDyn']['Nmodes'] = int_read(f.readline().split()[0]) self.fst_vt['SubDyn']['JDampings'] = float_read(f.readline().split()[0]) self.fst_vt['SubDyn']['GuyanDampMod'] = int_read(f.readline().split()[0]) diff --git a/openfast_io/openfast_io/FAST_writer.py b/openfast_io/openfast_io/FAST_writer.py index dac96def1..839f366bc 100644 --- a/openfast_io/openfast_io/FAST_writer.py +++ b/openfast_io/openfast_io/FAST_writer.py @@ -828,8 +828,10 @@ def write_AeroDyn(self): self.write_AeroDynPolar() # Generate AeroDyn v15 airfoil coordinates - if self.fst_vt['AeroDyn']['af_data'][0][0]['NumCoords'] != '0': # changing from ['af_data'][1] to ['af_data'][0] because we can have a single airfoil too. - self.write_AeroDynCoord() + # some polars may have airfoil coordinates, need to account for all possible scenarios + if any([self.fst_vt['AeroDyn']['af_data'][i][0]['NumCoords'] != '0' for i in range(len(self.fst_vt['AeroDyn']['af_data']))]): + af_coords = [i for i in range(len(self.fst_vt['AeroDyn']['af_data'])) if self.fst_vt['AeroDyn']['af_data'][i][0]['NumCoords'] != '0'] + self.write_AeroDynCoord(af_coords) if self.fst_vt['AeroDyn']['Wake_Mod'] == 3: if self.fst_vt['AeroDyn']['UA_Mod'] > 0: @@ -1026,6 +1028,9 @@ def write_AeroDynPolar(self): f.write('! line\n') f.write('! ------------------------------------------------------------------------------\n') f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn']['af_data'][afi][0]['InterpOrd'], 'InterpOrd', '! Interpolation order to use for quasi-steady table lookup {1=linear; 3=cubic spline; "default"} [default=3]\n')) + if 'RelThickness' in self.fst_vt['AeroDyn']['af_data'][afi][0]: + f.write('{:<22f} {:<11} {:}'.format(self.fst_vt['AeroDyn']['af_data'][afi][0]['RelThickness'], 'RelThickness', '! The non-dimensional thickness of the airfoil (thickness/chord) [only used if UAMod=7] [default=0.2] (-)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn']['af_data'][afi][0]['NonDimArea'], 'NonDimArea', '! The non-dimensional area of the airfoil (area/chord^2) (set to 1.0 if unsure or unneeded)\n')) if self.fst_vt['AeroDyn']['af_data'][afi][0]['NumCoords'] != '0': f.write('@"{:}_AF{:02d}_Coords.txt" {:<11} {:}'.format(self.FAST_namingOut, afi, 'NumCoords', '! The number of coordinates in the airfoil shape file. Set to zero if coordinates not included.\n')) @@ -1142,11 +1147,11 @@ def write_AeroDynPolar(self): os.fsync(f) f.close() - def write_AeroDynCoord(self): + def write_AeroDynCoord(self, af_coord): self.fst_vt['AeroDyn']['AFNames_coord'] = ['']*self.fst_vt['AeroDyn']['NumAFfiles'] - for afi in range(int(self.fst_vt['AeroDyn']['NumAFfiles'])): + for afi in af_coord: self.fst_vt['AeroDyn']['AFNames_coord'][afi] = os.path.join('Airfoils', self.FAST_namingOut + '_AF%02d_Coords.txt'%afi) x = self.fst_vt['AeroDyn']['af_coord'][afi]['x'] @@ -1857,8 +1862,8 @@ def write_SubDyn(self): f.write('-------------------- FEA and CRAIG-BAMPTON PARAMETERS---------------------------\n') f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['SubDyn']['FEMMod'], 'FEMMod', '- FEM switch: element model in the FEM. [1= Euler-Bernoulli(E-B); 2=Tapered E-B (unavailable); 3= 2-node Timoshenko; 4= 2-node tapered Timoshenko (unavailable)]\n')) f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['SubDyn']['NDiv'], 'NDiv', '- Number of sub-elements per member\n')) - f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['SubDyn']['CBMod'], 'CBMod', '- [T/F] If True perform C-B reduction, else full FEM dofs will be retained. If True, select Nmodes to retain in C-B reduced system.\n')) - f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['SubDyn']['Nmodes'], 'Nmodes', '- Number of internal modes to retain (ignored if CBMod=False). If Nmodes=0 --> Guyan Reduction.\n')) + # f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['SubDyn']['CBMod'], 'CBMod', '- [T/F] If True perform C-B reduction, else full FEM dofs will be retained. If True, select Nmodes to retain in C-B reduced system.\n')) + f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['SubDyn']['Nmodes'], 'Nmodes', '- Number of internal modes to retain. If Nmodes=0 --> Guyan Reduction. If Nmodes<0 --> retain all modes.\n')) JDampings = self.fst_vt['SubDyn']['JDampings'] if isinstance(JDampings, float): diff --git a/openfast_io/openfast_io/tests/test_of_io_pytest.py b/openfast_io/openfast_io/tests/test_of_io_pytest.py index eb9fb1ba0..64596b025 100644 --- a/openfast_io/openfast_io/tests/test_of_io_pytest.py +++ b/openfast_io/openfast_io/tests/test_of_io_pytest.py @@ -16,46 +16,46 @@ # Exercising the various OpenFAST modules FOLDERS_TO_RUN = [ - "AWT_YFix_WSt" , # "openfast;elastodyn;aerodyn;servodyn") - "AWT_WSt_StartUp_HighSpShutDown" , # "openfast;elastodyn;aerodyn;servodyn") - "AWT_YFree_WSt" , # "openfast;elastodyn;aerodyn;servodyn") - "AWT_YFree_WTurb" , # "openfast;elastodyn;aerodyn;servodyn") - "AWT_WSt_StartUpShutDown" , # "openfast;elastodyn;aerodyn;servodyn") - "AOC_WSt" , # "openfast;elastodyn;aerodyn;servodyn") - "AOC_YFree_WTurb" , # "openfast;elastodyn;aerodyn;servodyn") - "AOC_YFix_WSt" , # "openfast;elastodyn;aerodyn;servodyn") - "UAE_Dnwind_YRamp_WSt" , # "openfast;elastodyn;aerodyn;servodyn") - "UAE_Upwind_Rigid_WRamp_PwrCurve" , # "openfast;elastodyn;aerodyn;servodyn") - "WP_VSP_WTurb_PitchFail" , # "openfast;elastodyn;aerodyn;servodyn") - "WP_VSP_ECD" , # "openfast;elastodyn;aerodyn;servodyn") - "WP_VSP_WTurb" , # "openfast;elastodyn;aerodyn;servodyn") - "SWRT_YFree_VS_EDG01" , # "openfast;elastodyn;aerodyn;servodyn") - "SWRT_YFree_VS_EDC01" , # "openfast;elastodyn;aerodyn;servodyn") - "SWRT_YFree_VS_WTurb" , # "openfast;elastodyn;aerodyn;servodyn") - "5MW_Land_DLL_WTurb" , # "openfast;elastodyn;aerodyn;servodyn") - # "5MW_Land_DLL_WTurb_ADsk" , - # "5MW_Land_DLL_WTurb_ADsk_SED" , - # "5MW_Land_DLL_WTurb_SED" , - "5MW_Land_DLL_WTurb_wNacDrag" , # "openfast;elastodyn;aerodyn;servodyn") - "5MW_OC3Mnpl_DLL_WTurb_WavesIrr" , # "openfast;elastodyn;aerodyn;servodyn;hydrodyn;subdyn;offshore") - "5MW_OC3Mnpl_DLL_WTurb_WavesIrr_Restart" , # "openfast;elastodyn;aerodyn;servodyn;hydrodyn;subdyn;offshore;restart") - "5MW_OC3Trpd_DLL_WSt_WavesReg" , # "openfast;elastodyn;aerodyn;servodyn;hydrodyn;subdyn;offshore") - "5MW_OC4Jckt_DLL_WTurb_WavesIrr_MGrowth" , # "openfast;elastodyn;aerodyn;servodyn;hydrodyn;subdyn;offshore") - "5MW_ITIBarge_DLL_WTurb_WavesIrr" , # "openfast;elastodyn;aerodyn;servodyn;hydrodyn;map;offshore") - "5MW_TLP_DLL_WTurb_WavesIrr_WavesMulti" , # "openfast;elastodyn;aerodyn;servodyn;hydrodyn;map;offshore") - "5MW_OC3Spar_DLL_WTurb_WavesIrr" , # "openfast;elastodyn;aerodyn;servodyn;hydrodyn;map;offshore") - "5MW_OC4Semi_WSt_WavesWN" , # "openfast;elastodyn;aerodyn;servodyn;hydrodyn;moordyn;offshore") - "5MW_Land_BD_DLL_WTurb" , # "openfast;beamdyn;aerodyn;servodyn") - "5MW_Land_BD_Init" , # "openfast;beamdyn;aerodyn;servodyn") - "5MW_OC4Jckt_ExtPtfm" , # "openfast;elastodyn;extptfm") - "HelicalWake_OLAF" , # "openfast;aerodyn;olaf") - "EllipticalWing_OLAF" , # "openfast;aerodyn;olaf") - "StC_test_OC4Semi" , # "openfast;servodyn;hydrodyn;moordyn;offshore;stc") - "MHK_RM1_Fixed" , # "openfast;elastodyn;aerodyn;mhk") - "MHK_RM1_Floating" , # "openfast;elastodyn;aerodyn;hydrodyn;moordyn;mhk") - "MHK_RM1_Floating_wNacDrag" , # "openfast;elastodyn;aerodyn;hydrodyn;moordyn;mhk") - "Tailfin_FreeYaw1DOF_PolarBased" , # "openfast;elastodyn;aerodyn") - "Tailfin_FreeYaw1DOF_Unsteady" , # "openfast;elastodyn;aerodyn") + "AWT_YFix_WSt" , # "openfast;elastodyn;aerodyn;servodyn" + "AWT_WSt_StartUp_HighSpShutDown" , # "openfast;elastodyn;aerodyn;servodyn" + "AWT_YFree_WSt" , # "openfast;elastodyn;aerodyn;servodyn" + "AWT_YFree_WTurb" , # "openfast;elastodyn;aerodyn;servodyn" + "AWT_WSt_StartUpShutDown" , # "openfast;elastodyn;aerodyn;servodyn" + "AOC_WSt" , # "openfast;elastodyn;aerodyn;servodyn" + "AOC_YFree_WTurb" , # "openfast;elastodyn;aerodyn;servodyn" + "AOC_YFix_WSt" , # "openfast;elastodyn;aerodyn;servodyn" + "UAE_Dnwind_YRamp_WSt" , # "openfast;elastodyn;aerodyn;servodyn" + "UAE_Upwind_Rigid_WRamp_PwrCurve" , # "openfast;elastodyn;aerodyn;servodyn" + "WP_VSP_WTurb_PitchFail" , # "openfast;elastodyn;aerodyn;servodyn" + "WP_VSP_ECD" , # "openfast;elastodyn;aerodyn;servodyn" + "WP_VSP_WTurb" , # "openfast;elastodyn;aerodyn;servodyn" + "SWRT_YFree_VS_EDG01" , # "openfast;elastodyn;aerodyn;servodyn" + "SWRT_YFree_VS_EDC01" , # "openfast;elastodyn;aerodyn;servodyn" + "SWRT_YFree_VS_WTurb" , # "openfast;elastodyn;aerodyn;servodyn" + "5MW_Land_DLL_WTurb" , # "openfast;elastodyn;aerodyn;servodyn" + "5MW_Land_DLL_WTurb_wNacDrag" , # "openfast;elastodyn;aerodyn;servodyn" + "5MW_OC3Mnpl_DLL_WTurb_WavesIrr" , # "openfast;elastodyn;aerodyn;servodyn;hydrodyn;subdyn;offshore" + "5MW_OC3Mnpl_DLL_WTurb_WavesIrr_Restart" , # "openfast;elastodyn;aerodyn;servodyn;hydrodyn;subdyn;offshore;restart" + "5MW_OC3Trpd_DLL_WSt_WavesReg" , # "openfast;elastodyn;aerodyn;servodyn;hydrodyn;subdyn;offshore" + "5MW_OC4Jckt_DLL_WTurb_WavesIrr_MGrowth" , # "openfast;elastodyn;aerodyn;servodyn;hydrodyn;subdyn;offshore" + "5MW_ITIBarge_DLL_WTurb_WavesIrr" , # "openfast;elastodyn;aerodyn;servodyn;hydrodyn;map;offshore" + "5MW_TLP_DLL_WTurb_WavesIrr_WavesMulti" , # "openfast;elastodyn;aerodyn;servodyn;hydrodyn;map;offshore" + "5MW_OC3Spar_DLL_WTurb_WavesIrr" , # "openfast;elastodyn;aerodyn;servodyn;hydrodyn;map;offshore" + "5MW_OC4Semi_WSt_WavesWN" , # "openfast;elastodyn;aerodyn;servodyn;hydrodyn;moordyn;offshore" + "5MW_Land_BD_DLL_WTurb" , # "openfast;beamdyn;aerodyn;servodyn" + "5MW_Land_BD_Init" , # "openfast;beamdyn;aerodyn;servodyn" + "5MW_OC4Jckt_ExtPtfm" , # "openfast;elastodyn;extptfm" + "HelicalWake_OLAF" , # "openfast;aerodyn;olaf" + "EllipticalWing_OLAF" , # "openfast;aerodyn;olaf" + "StC_test_OC4Semi" , # "openfast;servodyn;hydrodyn;moordyn;offshore;stc" + "MHK_RM1_Fixed" , # "openfast;elastodyn;aerodyn;mhk" + "MHK_RM1_Floating" , # "openfast;elastodyn;aerodyn;hydrodyn;moordyn;mhk" + "MHK_RM1_Floating_wNacDrag" , # "openfast;elastodyn;aerodyn;hydrodyn;moordyn;mhk" + "Tailfin_FreeYaw1DOF_PolarBased" , # "openfast;elastodyn;aerodyn" + "Tailfin_FreeYaw1DOF_Unsteady" , # "openfast;elastodyn;aerodyn" + "5MW_Land_DLL_WTurb_ADsk" , # "openfast;elastodyn;aerodisk" + "5MW_Land_DLL_WTurb_ADsk_SED" , # "openfast;simple-elastodyn;aerodisk" + "5MW_Land_DLL_WTurb_SED" , # "openfast;simple-elastodyn;aerodyn" ] From 794dfcb24b57f1604ea96c07560452733de79311 Mon Sep 17 00:00:00 2001 From: Mayank Chetan Date: Fri, 6 Sep 2024 05:21:16 +0000 Subject: [PATCH 051/161] bug fix with FocalDistanceX in inflowind reader --- openfast_io/openfast_io/FAST_reader.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/openfast_io/openfast_io/FAST_reader.py b/openfast_io/openfast_io/FAST_reader.py index b56cb93f0..5728360bf 100644 --- a/openfast_io/openfast_io/FAST_reader.py +++ b/openfast_io/openfast_io/FAST_reader.py @@ -914,9 +914,9 @@ def read_InflowWind(self): self.fst_vt['InflowWind']['NumPulseGate'] = int(f.readline().split()[0]) self.fst_vt['InflowWind']['PulseSpacing'] = float_read(f.readline().split()[0]) self.fst_vt['InflowWind']['NumBeam'] = int(f.readline().split()[0]) - self.fst_vt['InflowWind']['FocalDistanceX'] = [idx.strip() for idx in f.readline().split('NacCenB')[0].split(',')] - self.fst_vt['InflowWind']['FocalDistanceY'] = [idx.strip() for idx in f.readline().split('NacCenB')[0].split(',')] - self.fst_vt['InflowWind']['FocalDistanceZ'] = [idx.strip() for idx in f.readline().split('NacCenB')[0].split(',')] + self.fst_vt['InflowWind']['FocalDistanceX'] = [idx.strip() for idx in f.readline().split('FocalDistanceX')[0].split(',')] + self.fst_vt['InflowWind']['FocalDistanceY'] = [idx.strip() for idx in f.readline().split('FocalDistanceY')[0].split(',')] + self.fst_vt['InflowWind']['FocalDistanceZ'] = [idx.strip() for idx in f.readline().split('FocalDistanceZ')[0].split(',')] self.fst_vt['InflowWind']['RotorApexOffsetPos'] = [idx.strip() for idx in f.readline().split('RotorApexOffsetPos')[0].split(',')] self.fst_vt['InflowWind']['URefLid'] = float_read(f.readline().split()[0]) self.fst_vt['InflowWind']['MeasurementInterval'] = float_read(f.readline().split()[0]) From 8342fee48b8e07b56ccdb1dd2ccd623da09c58e9 Mon Sep 17 00:00:00 2001 From: Mayank Chetan Date: Sat, 7 Sep 2024 06:28:51 +0000 Subject: [PATCH 052/161] adding fst_vt compare, significant testing robustness increase --- openfast_io/openfast_io/FileTools.py | 86 ++++++++++++++++++- .../openfast_io/tests/test_of_io_pytest.py | 37 +++++++- openfast_io/pyproject.toml | 1 + 3 files changed, 122 insertions(+), 2 deletions(-) diff --git a/openfast_io/openfast_io/FileTools.py b/openfast_io/openfast_io/FileTools.py index 5f753bdca..2fe3cbb10 100644 --- a/openfast_io/openfast_io/FileTools.py +++ b/openfast_io/openfast_io/FileTools.py @@ -4,6 +4,7 @@ import numpy as np import yaml from functools import reduce +from deepdiff import DeepDiff try: import ruamel_yaml as ry except Exception: @@ -275,4 +276,87 @@ def check_rtest_cloned(rtest_dir): if not os.path.isdir(rtest_dir): raise FileNotFoundError(f"The directory {rtest_dir} does not exist. Please clone the r-test submodule. Try running `git submodule update --init --recursive`") - return True \ No newline at end of file + return True + + +def remove_nested_keys(dictionary, keys_to_remove): + for key in keys_to_remove: + if key in dictionary: + del dictionary[key] + + for value in dictionary.values(): + if isinstance(value, dict): + remove_nested_keys(value, keys_to_remove) + + return dictionary + +def cleanup_fstvt(fst_vt, ignoreVars=None, removeFileRef=False, removeArrayProps=False): + # sanitize the dictionaries from numpy data types + fst_vt = remove_numpy(fst_vt) + + if removeFileRef: # not fair to compare file paths + fileVars = ['af_coord', 'Filename_Uni', 'FileName_BTS', 'FileName_u', 'FileName_v', 'FileName_w', # TODO: orgainze these logically + 'AFNames', 'ADBlFile1', 'ADBlFile2', 'ADBlFile3', 'NumCoords', + 'DLL_FileName','DLL_InFile','af_data', + 'PerfFileName', + 'InflowFile', + 'AeroFile', + 'BldFile1', 'BldFile2', 'BldFile3', + 'TwrFile', + 'EDFile', + 'ServoFile', + 'BldFile', + 'SeaStateFile', + 'HydroFile', + 'SubFile', + 'MooringFile', + 'Red_FileName', + 'PrescribedForcesFile', + 'actuatorDiskFile', + 'BDBldFile(1)', 'BDBldFile(2)', 'BDBldFile(3)', + 'OLAFInputFileName', + 'EDFile_path', + 'BDBldFile(1_path)', + 'BDBldFile(2_path)', + 'BDBldFile(3_path)', + 'InflowFile_path', + 'AeroFile_path', + 'ServoFile_path', + 'HydroFile_path', + 'SubFile_path', + 'MooringFile_path', + 'IceFile_path', + 'description', + ] + fst_vt = remove_nested_keys(fst_vt, fileVars) + + if removeArrayProps: # we can have different array properties, if run through different tools + arrayVars = ['BlSpn', 'BlCrvAC','BlSwpAC','BlCrvAng','BlTwist','BlChord','BlAFID', + 'ac','PC_GS_KP','PC_GS_KI','WE_FOPoles','beam_stiff','attr','units'] + + fst_vt = remove_nested_keys(fst_vt, arrayVars) + + if ignoreVars is not None: + fst_vt = remove_nested_keys(fst_vt, ignoreVars) + + return fst_vt + +def compare_fst_vt(fst_vt1, fst_vt2, ignoreVars = None, removeFileRef=False, removeArrayProps=False, print_diff=False): + # Compare two FAST variable trees + + # sanitize the dictionaries from numpy data types + fst_vt1 = cleanup_fstvt(fst_vt1, ignoreVars, removeFileRef, removeArrayProps) + fst_vt2 = cleanup_fstvt(fst_vt2, ignoreVars, removeFileRef, removeArrayProps) + + diff = DeepDiff(fst_vt1, fst_vt2, ignore_numeric_type_changes=True, + # ignore_string_case=True, + # verbose_level = 2 + ) + + if diff == {}: + print('No differences found between the two fst_vt.') + + if print_diff: + print(diff.pretty()) + + return diff diff --git a/openfast_io/openfast_io/tests/test_of_io_pytest.py b/openfast_io/openfast_io/tests/test_of_io_pytest.py index 64596b025..b7353344c 100644 --- a/openfast_io/openfast_io/tests/test_of_io_pytest.py +++ b/openfast_io/openfast_io/tests/test_of_io_pytest.py @@ -7,7 +7,7 @@ from openfast_io.FAST_writer import InputWriter_OpenFAST from openfast_io.FAST_output_reader import FASTOutputFile -from openfast_io.FileTools import check_rtest_cloned +from openfast_io.FileTools import check_rtest_cloned, compare_fst_vt from pathlib import Path from conftest import REPOSITORY_ROOT, BUILD_DIR, OF_PATH @@ -126,6 +126,37 @@ def check_binary_out(folder, path_dict = getPaths()): binaryOutput = osp.join(path_dict['build_dir'],'openfast_io', folder, f"{folder}.outb") fast_outout = FASTOutputFile(filename=binaryOutput) +def check_fst_vt_with_source(folder, path_dict = getPaths()): + print(f"Checking the fst_vt with the source for {folder}") + + # creating the two InputReader_OpenFAST objects + fast_reader1 = InputReader_OpenFAST() # for the source + fast_reader1.FAST_InputFile = f'{folder}.fst' # FAST input file (ext=.fst) + fast_reader1.FAST_directory = osp.join(path_dict['test_data_dir'], folder) # Path to fst directory files + fast_reader1.execute() + + fast_reader2 = InputReader_OpenFAST() # for the build + fast_reader2.FAST_InputFile = f'{folder}.fst' # FAST input file (ext=.fst) + fast_reader2.FAST_directory = osp.join(path_dict['build_dir'],'openfast_io',folder) # Path to fst directory files + fast_reader2.execute() + + # List of acceptable differences + acceptable_diff = [ + 'TMax', # TMax is updated in the write_action + 'TStart', # TStart is updated in the write_action + 'OutFileFmt', # OutFileFmt is updated in the write_action # TODO check why its not being removed + ] + + + # compare the two fst_vt + diff = compare_fst_vt(fast_reader1.fst_vt, fast_reader2.fst_vt, ignoreVars = acceptable_diff, + removeFileRef=True, removeArrayProps=True, print_diff=True) + + if diff: + pytest.fail(f"fst_vt for {folder} is not matching with the source") + + + # Begining of the test def test_rtest_cloned(request): @@ -189,6 +220,9 @@ def test_openfast_io_read_write_run_outRead(folder, request): action_name = "check binary" check_binary_out(folder, path_dict = path_dict) + action_name = "check fst_vt" + check_fst_vt_with_source(folder, path_dict = path_dict) + except Exception as e: pytest.fail(f"Action '{action_name}' for folder '{folder}' failed with exception: {e}") @@ -205,6 +239,7 @@ def main(): run_action(folder) check_ascii_out(folder) check_binary_out(folder) + check_fst_vt_with_source(folder) print(f"Successfully processed folder: {folder}") if __name__ == "__main__": diff --git a/openfast_io/pyproject.toml b/openfast_io/pyproject.toml index 3aea7c931..58b6991b5 100644 --- a/openfast_io/pyproject.toml +++ b/openfast_io/pyproject.toml @@ -52,6 +52,7 @@ dependencies = [ "numpy>1.0", "pandas>2.0", "ruamel_yaml>0.18", + "deepdiff>8.0", ] [project.urls] From 862b4b5a227306f862293868b2a009d9a3d2a18c Mon Sep 17 00:00:00 2001 From: Mayank Chetan Date: Sat, 7 Sep 2024 06:29:32 +0000 Subject: [PATCH 053/161] bug fixes caught by fst_vt compare --- openfast_io/openfast_io/FAST_reader.py | 156 +++++++++++++------------ openfast_io/openfast_io/FAST_writer.py | 38 +++--- 2 files changed, 100 insertions(+), 94 deletions(-) diff --git a/openfast_io/openfast_io/FAST_reader.py b/openfast_io/openfast_io/FAST_reader.py index 5728360bf..7d19d866e 100644 --- a/openfast_io/openfast_io/FAST_reader.py +++ b/openfast_io/openfast_io/FAST_reader.py @@ -91,6 +91,15 @@ def int_read(text): except: return str(text) +def quoted_read(text): + # read a line, if the first part is quoted, return the quoted part, otherwise return the unquoted part + if '"' in text: + return text.split('"')[1] + elif "'" in text: + return text.split("'")[1] + else: + return text + class InputReader_OpenFAST(object): """ OpenFAST input file reader """ @@ -203,7 +212,7 @@ def read_MainInput(self): # Simulation Control (fst_sim_ctrl) f.readline() self.fst_vt['Fst']['Echo'] = bool_read(f.readline().split()[0]) - self.fst_vt['Fst']['AbortLevel'] = f.readline().split()[0][1:-1] + self.fst_vt['Fst']['AbortLevel'] = quoted_read(f.readline().split()[0]) self.fst_vt['Fst']['TMax'] = float_read(f.readline().split()[0]) self.fst_vt['Fst']['DT'] = float_read(f.readline().split()[0]) self.fst_vt['Fst']['InterpOrder'] = int(f.readline().split()[0]) @@ -238,18 +247,18 @@ def read_MainInput(self): # Input Files (input_files) f.readline() - self.fst_vt['Fst']['EDFile'] = f.readline().split()[0][1:-1] - self.fst_vt['Fst']['BDBldFile(1)'] = f.readline().split()[0][1:-1] - self.fst_vt['Fst']['BDBldFile(2)'] = f.readline().split()[0][1:-1] - self.fst_vt['Fst']['BDBldFile(3)'] = f.readline().split()[0][1:-1] - self.fst_vt['Fst']['InflowFile'] = f.readline().split()[0][1:-1] - self.fst_vt['Fst']['AeroFile'] = f.readline().split()[0][1:-1] - self.fst_vt['Fst']['ServoFile'] = f.readline().split()[0][1:-1] - self.fst_vt['Fst']['SeaState'] = f.readline().split()[0][1:-1] - self.fst_vt['Fst']['HydroFile'] = f.readline().split()[0][1:-1] - self.fst_vt['Fst']['SubFile'] = f.readline().split()[0][1:-1] - self.fst_vt['Fst']['MooringFile'] = f.readline().split()[0][1:-1] - self.fst_vt['Fst']['IceFile'] = f.readline().split()[0][1:-1] + self.fst_vt['Fst']['EDFile'] = quoted_read(f.readline().split()[0]) + self.fst_vt['Fst']['BDBldFile(1)'] = quoted_read(f.readline().split()[0]) + self.fst_vt['Fst']['BDBldFile(2)'] = quoted_read(f.readline().split()[0]) + self.fst_vt['Fst']['BDBldFile(3)'] = quoted_read(f.readline().split()[0]) + self.fst_vt['Fst']['InflowFile'] = quoted_read(f.readline().split()[0]) + self.fst_vt['Fst']['AeroFile'] = quoted_read(f.readline().split()[0]) + self.fst_vt['Fst']['ServoFile'] = quoted_read(f.readline().split()[0]) + self.fst_vt['Fst']['SeaStateFile'] = quoted_read(f.readline().split()[0]) + self.fst_vt['Fst']['HydroFile'] = quoted_read(f.readline().split()[0]) + self.fst_vt['Fst']['SubFile'] = quoted_read(f.readline().split()[0]) + self.fst_vt['Fst']['MooringFile'] = quoted_read(f.readline().split()[0]) + self.fst_vt['Fst']['IceFile'] = quoted_read(f.readline().split()[0]) # FAST Output Parameters (fst_output_params) f.readline() @@ -260,7 +269,7 @@ def read_MainInput(self): self.fst_vt['Fst']['TStart'] = float_read(f.readline().split()[0]) self.fst_vt['Fst']['OutFileFmt'] = int(f.readline().split()[0]) self.fst_vt['Fst']['TabDelim'] = bool_read(f.readline().split()[0]) - self.fst_vt['Fst']['OutFmt'] = f.readline().split()[0][1:-1] + self.fst_vt['Fst']['OutFmt'] = quoted_read(f.readline().split()[0]) # Fst f.readline() @@ -272,7 +281,7 @@ def read_MainInput(self): self.fst_vt['Fst']['Twr_Kdmp'] = f.readline().split()[0] self.fst_vt['Fst']['Bld_Kdmp'] = f.readline().split()[0] self.fst_vt['Fst']['NLinTimes'] = int(f.readline().split()[0]) - self.fst_vt['Fst']['LinTimes'] = read_array(f, self.fst_vt['Fst']['NLinTimes'], float) + self.fst_vt['Fst']['LinTimes'] = read_array(f, self.fst_vt['Fst']['NLinTimes'], array_type=float) self.fst_vt['Fst']['LinInputs'] = f.readline().split()[0] self.fst_vt['Fst']['LinOutputs'] = f.readline().split()[0] self.fst_vt['Fst']['LinOutJac'] = f.readline().split()[0] @@ -407,9 +416,9 @@ def read_ElastoDyn(self, ed_file): # ElastoDyn Blade (blade_struc) f.readline() self.fst_vt['ElastoDyn']['BldNodes'] = int(f.readline().split()[0]) - self.fst_vt['ElastoDyn']['BldFile1'] = f.readline().split()[0][1:-1] - self.fst_vt['ElastoDyn']['BldFile2'] = f.readline().split()[0][1:-1] - self.fst_vt['ElastoDyn']['BldFile3'] = f.readline().split()[0][1:-1] + self.fst_vt['ElastoDyn']['BldFile1'] = quoted_read(f.readline().split()[0]) + self.fst_vt['ElastoDyn']['BldFile2'] = quoted_read(f.readline().split()[0]) + self.fst_vt['ElastoDyn']['BldFile3'] = quoted_read(f.readline().split()[0]) # Rotor-Teeter (rotor_teeter) f.readline() @@ -439,30 +448,30 @@ def read_ElastoDyn(self, ed_file): # Furling (furling) f.readline() self.fst_vt['ElastoDyn']['Furling'] = bool_read(f.readline().split()[0]) - self.fst_vt['ElastoDyn']['FurlFile'] = os.path.join(self.FAST_directory, f.readline().split()[0][1:-1]) # TODO: add furl file data to fst_vt, pointing to absolute path for now + self.fst_vt['ElastoDyn']['FurlFile'] = os.path.join(self.FAST_directory, quoted_read(f.readline().split()[0])) # TODO: add furl file data to fst_vt, pointing to absolute path for now # Tower (tower) f.readline() self.fst_vt['ElastoDyn']['TwrNodes'] = int(f.readline().split()[0]) - self.fst_vt['ElastoDyn']['TwrFile'] = f.readline().split()[0][1:-1] + self.fst_vt['ElastoDyn']['TwrFile'] = quoted_read(f.readline().split()[0]) # ED Output Parameters (ed_out_params) f.readline() self.fst_vt['ElastoDyn']['SumPrint'] = bool_read(f.readline().split()[0]) self.fst_vt['ElastoDyn']['OutFile'] = int(f.readline().split()[0]) self.fst_vt['ElastoDyn']['TabDelim'] = bool_read(f.readline().split()[0]) - self.fst_vt['ElastoDyn']['OutFmt'] = f.readline().split()[0][1:-1] + self.fst_vt['ElastoDyn']['OutFmt'] = quoted_read(f.readline().split()[0]) self.fst_vt['ElastoDyn']['TStart'] = float_read(f.readline().split()[0]) self.fst_vt['ElastoDyn']['DecFact'] = int(f.readline().split()[0]) self.fst_vt['ElastoDyn']['NTwGages'] = int(f.readline().split()[0]) if self.fst_vt['ElastoDyn']['NTwGages'] != 0: #loop over elements if there are gauges to be added, otherwise assign directly - self.fst_vt['ElastoDyn']['TwrGagNd'] = read_array(f,self.fst_vt['ElastoDyn']['NTwGages'],int) + self.fst_vt['ElastoDyn']['TwrGagNd'] = read_array(f,self.fst_vt['ElastoDyn']['NTwGages'], array_type=int) else: self.fst_vt['ElastoDyn']['TwrGagNd'] = 0 f.readline() self.fst_vt['ElastoDyn']['NBlGages'] = int(f.readline().split()[0]) if self.fst_vt['ElastoDyn']['NBlGages'] != 0: - self.fst_vt['ElastoDyn']['BldGagNd'] = read_array(f,self.fst_vt['ElastoDyn']['NBlGages'],int) + self.fst_vt['ElastoDyn']['BldGagNd'] = read_array(f,self.fst_vt['ElastoDyn']['NBlGages'], array_type=int) else: self.fst_vt['ElastoDyn']['BldGagNd'] = 0 f.readline() @@ -756,9 +765,9 @@ def read_BeamDyn(self, bd_file): #---------------------- OUTPUTS ------------------------------------------------- f.readline() self.fst_vt['BeamDyn']['SumPrint'] = bool_read(f.readline().split()[0]) - self.fst_vt['BeamDyn']['OutFmt'] = f.readline().split()[0][1:-1] + self.fst_vt['BeamDyn']['OutFmt'] = quoted_read(f.readline().split()[0]) self.fst_vt['BeamDyn']['NNodeOuts'] = int_read(f.readline().split()[0]) - self.fst_vt['BeamDyn']['OutNd'] = [idx.strip() for idx in f.readline().split('NNodeOuts')[0].split(',')] + self.fst_vt['BeamDyn']['OutNd'] = [idx.strip() for idx in f.readline().split('OutNd')[0].split(',')] # BeamDyn Outlist f.readline() data = f.readline() @@ -865,23 +874,23 @@ def read_InflowWind(self): # Parameters for Uniform wind file [used only for WindType = 2] (uniform_wind_params) f.readline() - self.fst_vt['InflowWind']['Filename_Uni'] = os.path.join(os.path.split(inflow_file)[0], f.readline().split()[0][1:-1]) + self.fst_vt['InflowWind']['Filename_Uni'] = os.path.join(os.path.split(inflow_file)[0], quoted_read(f.readline().split()[0])) self.fst_vt['InflowWind']['RefHt_Uni'] = float_read(f.readline().split()[0]) self.fst_vt['InflowWind']['RefLength'] = float_read(f.readline().split()[0]) # Parameters for Binary TurbSim Full-Field files [used only for WindType = 3] (turbsim_wind_params) f.readline() - self.fst_vt['InflowWind']['FileName_BTS'] = os.path.join(os.path.split(inflow_file)[0], f.readline().split()[0][1:-1]) + self.fst_vt['InflowWind']['FileName_BTS'] = os.path.join(os.path.split(inflow_file)[0], quoted_read(f.readline().split()[0])) # Parameters for Binary Bladed-style Full-Field files [used only for WindType = 4] (bladed_wind_params) f.readline() - self.fst_vt['InflowWind']['FilenameRoot'] = os.path.join(os.path.split(inflow_file)[0], f.readline().split()[0][1:-1]) + self.fst_vt['InflowWind']['FilenameRoot'] = os.path.join(os.path.split(inflow_file)[0], quoted_read(f.readline().split()[0])) self.fst_vt['InflowWind']['TowerFile'] = bool_read(f.readline().split()[0]) # Parameters for HAWC-format binary files [Only used with WindType = 5] (hawc_wind_params) f.readline() - self.fst_vt['InflowWind']['FileName_u'] = os.path.normpath(os.path.join(os.path.split(inflow_file)[0], f.readline().split()[0][1:-1])) - self.fst_vt['InflowWind']['FileName_v'] = os.path.normpath(os.path.join(os.path.split(inflow_file)[0], f.readline().split()[0][1:-1])) - self.fst_vt['InflowWind']['FileName_w'] = os.path.normpath(os.path.join(os.path.split(inflow_file)[0], f.readline().split()[0][1:-1])) + self.fst_vt['InflowWind']['FileName_u'] = os.path.normpath(os.path.join(os.path.split(inflow_file)[0], quoted_read(f.readline().split()[0]))) + self.fst_vt['InflowWind']['FileName_v'] = os.path.normpath(os.path.join(os.path.split(inflow_file)[0], quoted_read(f.readline().split()[0]))) + self.fst_vt['InflowWind']['FileName_w'] = os.path.normpath(os.path.join(os.path.split(inflow_file)[0], quoted_read(f.readline().split()[0]))) self.fst_vt['InflowWind']['nx'] = int(f.readline().split()[0]) self.fst_vt['InflowWind']['ny'] = int(f.readline().split()[0]) self.fst_vt['InflowWind']['nz'] = int(f.readline().split()[0]) @@ -1008,7 +1017,7 @@ def read_AeroDyn(self): # Olaf -- cOnvecting LAgrangian Filaments (Free Vortex Wake) Theory Options f.readline() - self.fst_vt['AeroDyn']['OLAFInputFileName'] = f.readline().split()[0][1:-1] + self.fst_vt['AeroDyn']['OLAFInputFileName'] = quoted_read(f.readline().split()[0]) # Unsteady Airfoil Aerodynamics Options f.readline() @@ -1049,9 +1058,9 @@ def read_AeroDyn(self): # Rotor/Blade Properties f.readline() self.fst_vt['AeroDyn']['UseBlCm'] = bool_read(f.readline().split()[0]) - self.fst_vt['AeroDyn']['ADBlFile1'] = f.readline().split()[0][1:-1] - self.fst_vt['AeroDyn']['ADBlFile2'] = f.readline().split()[0][1:-1] - self.fst_vt['AeroDyn']['ADBlFile3'] = f.readline().split()[0][1:-1] + self.fst_vt['AeroDyn']['ADBlFile1'] = quoted_read(f.readline().split()[0]) + self.fst_vt['AeroDyn']['ADBlFile2'] = quoted_read(f.readline().split()[0]) + self.fst_vt['AeroDyn']['ADBlFile3'] = quoted_read(f.readline().split()[0]) # Hub, nacelle, and tail fin aerodynamics f.readline() @@ -1318,7 +1327,7 @@ def read_AeroDynOLAF(self, olaf_filename): self.fst_vt['AeroDyn']['OLAF']['CircSolvConvCrit'] = float_read(f.readline().split()[0]) self.fst_vt['AeroDyn']['OLAF']['CircSolvRelaxation'] = float_read(f.readline().split()[0]) self.fst_vt['AeroDyn']['OLAF']['CircSolvMaxIter'] = int_read(f.readline().split()[0]) - self.fst_vt['AeroDyn']['OLAF']['PrescribedCircFile'] = os.path.join(self.FAST_directory, f.readline().split()[0][1:-1]) # unmodified by this script, hence pointing to absolute location + self.fst_vt['AeroDyn']['OLAF']['PrescribedCircFile'] = os.path.join(self.FAST_directory, quoted_read(f.readline().split()[0])) # unmodified by this script, hence pointing to absolute location f.readline() f.readline() f.readline() @@ -1377,9 +1386,10 @@ def read_AeroDisk(self): # read InColNames - Input column headers (string) {may include a combination of "TSR, RtSpd, VRel, Pitch, Skew"} (up to 4 columns) # Read between the quotes - self.fst_vt['AeroDisk']['InColNames'] = read_array(f, len = None, split_val=',', array_type=str) + self.fst_vt['AeroDisk']['InColNames'] = [x.strip() for x in quoted_read(f.readline().split('InColNames')[0]).split(',')] + # read InColDims - Number of unique values in each column (-) (must have same number of columns as InColName) [each >=2] - self.fst_vt['AeroDisk']['InColDims'] = read_array(f, len=len(self.fst_vt['AeroDisk']['InColNames']), array_type=int) + self.fst_vt['AeroDisk']['InColDims'] = [int(x) for x in f.readline().split('InColDims')[0].split(',')] # read the contents table of the CSV file referenced next # if the next line starts with an @, then it is a file reference @@ -1500,13 +1510,13 @@ def read_ServoDyn(self): # Structural Control f.readline() self.fst_vt['ServoDyn']['NumBStC'] = int(f.readline().split()[0]) - self.fst_vt['ServoDyn']['BStCfiles'] = read_array(f,self.fst_vt['ServoDyn']['NumBStC'],str) + self.fst_vt['ServoDyn']['BStCfiles'] = read_array(f,self.fst_vt['ServoDyn']['NumBStC'], array_type=str) self.fst_vt['ServoDyn']['NumNStC'] = int(f.readline().split()[0]) - self.fst_vt['ServoDyn']['NStCfiles'] = read_array(f,self.fst_vt['ServoDyn']['NumNStC'],str) + self.fst_vt['ServoDyn']['NStCfiles'] = read_array(f,self.fst_vt['ServoDyn']['NumNStC'], array_type=str) self.fst_vt['ServoDyn']['NumTStC'] = int(f.readline().split()[0]) - self.fst_vt['ServoDyn']['TStCfiles'] = read_array(f,self.fst_vt['ServoDyn']['NumTStC'],str) + self.fst_vt['ServoDyn']['TStCfiles'] = read_array(f,self.fst_vt['ServoDyn']['NumTStC'], array_type=str) self.fst_vt['ServoDyn']['NumSStC'] = int(f.readline().split()[0]) - self.fst_vt['ServoDyn']['SStCfiles'] = read_array(f,self.fst_vt['ServoDyn']['NumSStC'],str) + self.fst_vt['ServoDyn']['SStCfiles'] = read_array(f,self.fst_vt['ServoDyn']['NumSStC'], array_type=str) # Initialize Struct Control trees self.fst_vt['BStC'] = [] * self.fst_vt['ServoDyn']['NumBStC'] @@ -1521,12 +1531,12 @@ def read_ServoDyn(self): # Bladed Interface and Torque-Speed Look-Up Table (bladed_interface) f.readline() if self.path2dll == '' or self.path2dll == None: - self.fst_vt['ServoDyn']['DLL_FileName'] = os.path.abspath(os.path.normpath(os.path.join(os.path.split(sd_file)[0], f.readline().split()[0][1:-1]))) + self.fst_vt['ServoDyn']['DLL_FileName'] = os.path.abspath(os.path.normpath(os.path.join(os.path.split(sd_file)[0], quoted_read(f.readline().split()[0])))) else: f.readline() self.fst_vt['ServoDyn']['DLL_FileName'] = self.path2dll - self.fst_vt['ServoDyn']['DLL_InFile'] = os.path.abspath(os.path.normpath(os.path.join(os.path.split(sd_file)[0], f.readline().split()[0][1:-1]))) - self.fst_vt['ServoDyn']['DLL_ProcName'] = f.readline().split()[0][1:-1] + self.fst_vt['ServoDyn']['DLL_InFile'] = os.path.abspath(os.path.normpath(os.path.join(os.path.split(sd_file)[0], quoted_read(f.readline().split()[0])))) + self.fst_vt['ServoDyn']['DLL_ProcName'] = quoted_read(f.readline().split()[0]) dll_dt_line = f.readline().split()[0] try: self.fst_vt['ServoDyn']['DLL_DT'] = float_read(dll_dt_line) @@ -1565,7 +1575,7 @@ def read_ServoDyn(self): self.fst_vt['ServoDyn']['SumPrint'] = bool_read(f.readline().split()[0]) self.fst_vt['ServoDyn']['OutFile'] = int(f.readline().split()[0]) self.fst_vt['ServoDyn']['TabDelim'] = bool_read(f.readline().split()[0]) - self.fst_vt['ServoDyn']['OutFmt'] = f.readline().split()[0][1:-1] + self.fst_vt['ServoDyn']['OutFmt'] = quoted_read(f.readline().split()[0]) self.fst_vt['ServoDyn']['TStart'] = float_read(f.readline().split()[0]) # ServoDyn Outlist @@ -1606,8 +1616,8 @@ def read_StC(self,filename): StC_vt['StC_Z_DSP'] = float_read(f.readline().split()[0]) # 0 StC_Z_DSP - StC Z initial displacement (m) [relative to at rest position; used only when StC_DOF_MODE=1 and StC_Z_DOF=TRUE] StC_vt['StC_Z_PreLd'] = f.readline().split()[0] # "none" StC_Z_PreLd - StC Z prefloat_read(f.readline().split()[0]) #-load (N) {"gravity" to offset for gravity load; "none" or 0 to turn off} [used only when StC_DOF_MODE=1 and StC_Z_DOF=TRUE] f.readline() # StC CONFIGURATION - StC_vt['StC_X_NSP'] = float_read(f.readline().split()[0]) # 0 StC_X_NSP - Negative stop position (minimum X mass displacement) (m) - StC_vt['StC_X_PSP'] = float_read(f.readline().split()[0]) # 0 StC_X_PSP - Positive stop position (maximum X mass displacement) (m) + StC_vt['StC_X_PSP'] = float_read(f.readline().split()[0]) # 0 StC_X_PSP - Positive stop position (minimum X mass displacement) (m) + StC_vt['StC_X_NSP'] = float_read(f.readline().split()[0]) # 0 StC_X_NSP - Negative stop position (maximum X mass displacement) (m) StC_vt['StC_Y_PSP'] = float_read(f.readline().split()[0]) # 0 StC_Y_PSP - Positive stop position (maximum Y mass displacement) (m) StC_vt['StC_Y_NSP'] = float_read(f.readline().split()[0]) # 0 StC_Y_NSP - Negative stop position (minimum Y mass displacement) (m) StC_vt['StC_Z_PSP'] = float_read(f.readline().split()[0]) # 0 StC_Z_PSP - Positive stop position (maximum Z mass displacement) (m) [used only when StC_DOF_MODE=1 and StC_Z_DOF=TRUE] @@ -1690,7 +1700,7 @@ def read_StC(self,filename): f.readline() # PRESCRIBED TIME SERIES StC_vt['PrescribedForcesCoord'] = int_read(f.readline().split()[0]) # 2 PrescribedForcesCoord- Prescribed forces are in global or local coordinates (switch) {1: global; 2: local} # TODO: read in prescribed force time series, for now we just point to absolute path of input file - StC_vt['PrescribedForcesFile'] = os.path.join(self.FAST_directory, f.readline().split()[0][1:-1]) # "Bld-TimeForceSeries.dat" PrescribedForcesFile - Time series force and moment (7 columns of time, FX, FY, FZ, MX, MY, MZ) + StC_vt['PrescribedForcesFile'] = os.path.join(self.FAST_directory, quoted_read(f.readline().split()[0])) # "Bld-TimeForceSeries.dat" PrescribedForcesFile - Time series force and moment (7 columns of time, FX, FY, FZ, MX, MY, MZ) f.readline() return StC_vt @@ -1743,7 +1753,7 @@ def read_spd_trq(self, file): f = open(os.path.normpath(os.path.join(self.FAST_directory, file))) - spd_trq['header'] = f.readline().strip()[0] + spd_trq['header'] = f.readline() # handle arbritraty number of rows and two columns: RPM and Torque data = f.readlines() @@ -1785,14 +1795,14 @@ def read_HydroDyn(self, hd_file): pot_strings = read_array(f,self.fst_vt['HydroDyn']['NBody'],str) #re.split(',| ',f.readline().strip()) pot_strings = [os.path.normpath(os.path.join(os.path.split(hd_file)[0],ps)) for ps in pot_strings] # make relative to hd_file self.fst_vt['HydroDyn']['PotFile'] = pot_strings - self.fst_vt['HydroDyn']['WAMITULEN'] = read_array(f,self.fst_vt['HydroDyn']['NBody'],float) - self.fst_vt['HydroDyn']['PtfmRefxt'] = read_array(f,self.fst_vt['HydroDyn']['NBody'],float) - self.fst_vt['HydroDyn']['PtfmRefyt'] = read_array(f,self.fst_vt['HydroDyn']['NBody'],float) - self.fst_vt['HydroDyn']['PtfmRefzt'] = read_array(f,self.fst_vt['HydroDyn']['NBody'],float) - self.fst_vt['HydroDyn']['PtfmRefztRot'] = read_array(f,self.fst_vt['HydroDyn']['NBody'],float) - self.fst_vt['HydroDyn']['PtfmVol0'] = read_array(f,self.fst_vt['HydroDyn']['NBody'],float) - self.fst_vt['HydroDyn']['PtfmCOBxt'] = read_array(f,self.fst_vt['HydroDyn']['NBody'],float) - self.fst_vt['HydroDyn']['PtfmCOByt'] = read_array(f,self.fst_vt['HydroDyn']['NBody'],float) + self.fst_vt['HydroDyn']['WAMITULEN'] = read_array(f,self.fst_vt['HydroDyn']['NBody'], array_type=float) + self.fst_vt['HydroDyn']['PtfmRefxt'] = read_array(f,self.fst_vt['HydroDyn']['NBody'], array_type=float) + self.fst_vt['HydroDyn']['PtfmRefyt'] = read_array(f,self.fst_vt['HydroDyn']['NBody'], array_type=float) + self.fst_vt['HydroDyn']['PtfmRefzt'] = read_array(f,self.fst_vt['HydroDyn']['NBody'], array_type=float) + self.fst_vt['HydroDyn']['PtfmRefztRot'] = read_array(f,self.fst_vt['HydroDyn']['NBody'], array_type=float) + self.fst_vt['HydroDyn']['PtfmVol0'] = read_array(f,self.fst_vt['HydroDyn']['NBody'], array_type=float) + self.fst_vt['HydroDyn']['PtfmCOBxt'] = read_array(f,self.fst_vt['HydroDyn']['NBody'], array_type=float) + self.fst_vt['HydroDyn']['PtfmCOByt'] = read_array(f,self.fst_vt['HydroDyn']['NBody'], array_type=float) # 2ND-ORDER FLOATING PLATFORM FORCES f.readline() @@ -2090,14 +2100,8 @@ def read_HydroDyn(self, hd_file): self.fst_vt['HydroDyn']['HDSum'] = bool_read(f.readline().split()[0]) self.fst_vt['HydroDyn']['OutAll'] = bool_read(f.readline().split()[0]) self.fst_vt['HydroDyn']['OutSwtch'] = int_read(f.readline().split()[0]) - self.fst_vt['HydroDyn']['OutFmt'] = str(f.readline().split()[0]) - self.fst_vt['HydroDyn']['OutSFmt'] = str(f.readline().split()[0]) - - self.fst_vt['HydroDyn']['HDSum'] - self.fst_vt['HydroDyn']['OutAll'] - self.fst_vt['HydroDyn']['OutSwtch'] - self.fst_vt['HydroDyn']['OutFmt'] - self.fst_vt['HydroDyn']['OutSFmt'] + self.fst_vt['HydroDyn']['OutFmt'] = quoted_read(f.readline().split()[0]) + self.fst_vt['HydroDyn']['OutSFmt'] = quoted_read(f.readline().split()[0]) # HydroDyn Outlist f.readline() @@ -2159,7 +2163,7 @@ def read_SeaState(self, ss_file): self.fst_vt['SeaState']['WaveSeed1'] = int_read(f.readline().split()[0]) self.fst_vt['SeaState']['WaveSeed2'] = int_read(f.readline().split()[0]) self.fst_vt['SeaState']['WaveNDAmp'] = bool_read(f.readline().split()[0]) - self.fst_vt['SeaState']['WvKinFile'] = f.readline().split()[0][1:-1] + self.fst_vt['SeaState']['WvKinFile'] = quoted_read(f.readline().split()[0]) # 2ND-ORDER WAVES f.readline() @@ -2197,8 +2201,8 @@ def read_SeaState(self, ss_file): f.readline() self.fst_vt['SeaState']['SeaStSum'] = bool_read(f.readline().split()[0]) self.fst_vt['SeaState']['OutSwtch'] = int_read(f.readline().split()[0]) - self.fst_vt['SeaState']['OutFmt'] = str(f.readline().split()[0]) - self.fst_vt['SeaState']['OutSFmt'] = str(f.readline().split()[0]) + self.fst_vt['SeaState']['OutFmt'] = quoted_read(f.readline().split()[0]) + self.fst_vt['SeaState']['OutSFmt'] = quoted_read(f.readline().split()[0]) self.fst_vt['SeaState']['NWaveElev'] = int_read(f.readline().split()[0]) self.fst_vt['SeaState']['WaveElevxi'] = [float_read(idx.strip()) for idx in f.readline().split('WaveElevxi')[0].replace(',',' ').split()] self.fst_vt['SeaState']['WaveElevyi'] = [float_read(idx.strip()) for idx in f.readline().split('WaveElevyi')[0].replace(',',' ').split()] @@ -2243,7 +2247,7 @@ def read_SubDyn(self, sd_file): self.fst_vt['SubDyn']['Nmodes'] = int_read(f.readline().split()[0]) self.fst_vt['SubDyn']['JDampings'] = float_read(f.readline().split()[0]) self.fst_vt['SubDyn']['GuyanDampMod'] = int_read(f.readline().split()[0]) - self.fst_vt['SubDyn']['RayleighDamp'] = read_array(f,2,float) + self.fst_vt['SubDyn']['RayleighDamp'] = read_array(f,2,array_type=float) self.fst_vt['SubDyn']['GuyanDampSize'] = int_read(f.readline().split()[0]) self.fst_vt['SubDyn']['GuyanDamp'] = np.array([[float(idx) for idx in f.readline().strip().split()[:6]] for i in range(self.fst_vt['SubDyn']['GuyanDampSize'])]) f.readline() @@ -2508,8 +2512,8 @@ def read_SubDyn(self, sd_file): self.fst_vt['SubDyn']['OutSwtch'] = int_read(f.readline().split()[0]) self.fst_vt['SubDyn']['TabDelim'] = bool_read(f.readline().split()[0]) self.fst_vt['SubDyn']['OutDec'] = int_read(f.readline().split()[0]) - self.fst_vt['SubDyn']['OutFmt'] = f.readline().split()[0] - self.fst_vt['SubDyn']['OutSFmt'] = f.readline().split()[0] + self.fst_vt['SubDyn']['OutFmt'] = quoted_read(f.readline().split()[0]) + self.fst_vt['SubDyn']['OutSFmt'] = quoted_read(f.readline().split()[0]) f.readline() # MEMBER OUTPUT LIST self.fst_vt['SubDyn']['NMOutputs'] = int_read(f.readline().split()[0]) @@ -2548,8 +2552,8 @@ def read_ExtPtfm(self, ep_file): # Reduction inputs self.fst_vt['ExtPtfm']['FileFormat'] = int_read(f.readline().split()[0]) - self.fst_vt['ExtPtfm']['Red_FileName'] = os.path.join(os.path.dirname(ep_file), f.readline().split()[0][1:-1]) - self.fst_vt['ExtPtfm']['RedCst_FileName'] = os.path.join(os.path.dirname(ep_file), f.readline().split()[0][1:-1]) + self.fst_vt['ExtPtfm']['Red_FileName'] = os.path.join(os.path.dirname(ep_file), quoted_read(f.readline().split()[0])) + self.fst_vt['ExtPtfm']['RedCst_FileName'] = os.path.join(os.path.dirname(ep_file), quoted_read(f.readline().split()[0])) self.fst_vt['ExtPtfm']['NActiveDOFList'] = int_read(f.readline().split()[0]) self.fst_vt['ExtPtfm']['ActiveDOFList'] = [idx.strip() for idx in f.readline().split('ActiveDOFList')[0].split(',')] self.fst_vt['ExtPtfm']['NInitPosList'] = int_read(f.readline().split()[0]) @@ -2562,7 +2566,7 @@ def read_ExtPtfm(self, ep_file): self.fst_vt['ExtPtfm']['SumPrint'] = bool_read(f.readline().split()[0]) self.fst_vt['ExtPtfm']['OutFile'] = int_read(f.readline().split()[0]) self.fst_vt['ExtPtfm']['TabDelim'] = bool_read(f.readline().split()[0]) - self.fst_vt['ExtPtfm']['OutFmt'] = f.readline().split()[0][1:-1] + self.fst_vt['ExtPtfm']['OutFmt'] = quoted_read(f.readline().split()[0]) self.fst_vt['ExtPtfm']['TStart'] = float_read(f.readline().split()[0]) # Loop through output channel lines @@ -3087,7 +3091,7 @@ def execute(self): hd_file = os.path.normpath(os.path.join(self.FAST_directory, self.fst_vt['Fst']['HydroFile'])) if os.path.isfile(hd_file): self.read_HydroDyn(hd_file) - ss_file = os.path.normpath(os.path.join(self.FAST_directory, self.fst_vt['Fst']['SeaState'])) + ss_file = os.path.normpath(os.path.join(self.FAST_directory, self.fst_vt['Fst']['SeaStateFile'])) if os.path.isfile(ss_file): self.read_SeaState(ss_file) sd_file = os.path.normpath(os.path.join(self.FAST_directory, self.fst_vt['Fst']['SubFile'])) diff --git a/openfast_io/openfast_io/FAST_writer.py b/openfast_io/openfast_io/FAST_writer.py index 839f366bc..5906afa2e 100644 --- a/openfast_io/openfast_io/FAST_writer.py +++ b/openfast_io/openfast_io/FAST_writer.py @@ -197,7 +197,7 @@ def execute(self): if 'WaterKin' in self.fst_vt['MoorDyn']['options']: self.write_WaterKin(os.path.join(self.FAST_runDirectory,self.fst_vt['MoorDyn']['WaterKin_file'])) - if self.fst_vt['Fst']['CompElast'] == 2: + if self.fst_vt['Fst']['CompElast'] == 2 or 'Echo' in self.fst_vt['BeamDyn']: self.write_BeamDyn() self.write_MainInput() @@ -253,7 +253,7 @@ def write_MainInput(self): f.write('{:<22} {:<11} {:}'.format('"'+self.fst_vt['Fst']['InflowFile']+'"', 'InflowFile', '- Name of file containing inflow wind input parameters (quoted string)\n')) f.write('{:<22} {:<11} {:}'.format('"'+self.fst_vt['Fst']['AeroFile']+'"', 'AeroFile', '- Name of file containing aerodynamic input parameters (quoted string)\n')) f.write('{:<22} {:<11} {:}'.format('"'+self.fst_vt['Fst']['ServoFile']+'"', 'ServoFile', '- Name of file containing control and electrical-drive input parameters (quoted string)\n')) - f.write('{:<22} {:<11} {:}'.format('"'+self.fst_vt['Fst']['SeaState']+'"', 'SeaState', '- Name of file containing sea state input parameters (quoted string)\n')) + f.write('{:<22} {:<11} {:}'.format('"'+self.fst_vt['Fst']['SeaStateFile']+'"', 'SeaStateFile', '- Name of file containing sea state input parameters (quoted string)\n')) f.write('{:<22} {:<11} {:}'.format('"'+self.fst_vt['Fst']['HydroFile']+'"', 'HydroFile', '- Name of file containing hydrodynamic input parameters (quoted string)\n')) f.write('{:<22} {:<11} {:}'.format('"'+self.fst_vt['Fst']['SubFile']+'"', 'SubFile', '- Name of file containing sub-structural input parameters (quoted string)\n')) f.write('{:<22} {:<11} {:}'.format('"'+self.fst_vt['Fst']['MooringFile']+'"', 'MooringFile', '- Name of file containing mooring system input parameters (quoted string)\n')) @@ -264,7 +264,7 @@ def write_MainInput(self): f.write('{:<22} {:<11} {:}'.format(self.fst_vt['Fst']['ChkptTime'], 'ChkptTime', '- Amount of time between creating checkpoint files for potential restart (s)\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['Fst']['DT_Out'], 'DT_Out', '- Time step for tabular output (s) (or "default")\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['Fst']['TStart'], 'TStart', '- Time to begin tabular output (s)\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['Fst']['OutFileFmt'], 'OutFileFmt', '- Format for tabular (time-marching) output file (switch) {1: text file [.out], 2: binary file [.outb], 3: both 1 and 2, 4: uncompressed binary [.outb], 5: both 1 and 4}\n')) + f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['Fst']['OutFileFmt'], 'OutFileFmt', '- Format for tabular (time-marching) output file (switch) {1: text file [.out], 2: binary file [.outb], 3: both 1 and 2, 4: uncompressed binary [.outb], 5: both 1 and 4}\n')) f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['Fst']['TabDelim'], 'TabDelim', '- Use tab delimiters in text tabular output file? (flag) {uses spaces if false}\n')) f.write('{:<22} {:<11} {:}'.format('"'+self.fst_vt['Fst']['OutFmt']+'"', 'OutFmt', '- Format used for text tabular output, excluding the time channel. Resulting field should be 10 characters. (quoted string)\n')) f.write('---------------------- LINEARIZATION -------------------------------------------\n') @@ -735,7 +735,7 @@ def write_BeamDynBlade(self): f.write('\n') def write_InflowWind(self): - self.fst_vt['Fst']['InflowFile'] = self.FAST_namingOut + '_InflowFile.dat' + self.fst_vt['Fst']['InflowFile'] = self.FAST_namingOut + '_InflowWind.dat' inflow_file = os.path.join(self.FAST_runDirectory,self.fst_vt['Fst']['InflowFile']) f = open(inflow_file, 'w') @@ -940,10 +940,11 @@ def write_AeroDyn(self): f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn']['NBlOuts'], 'NBlOuts', '- Number of blade node outputs [0 - 9] (-)\n')) f.write('{:<22} {:<11} {:}'.format(', '.join(self.fst_vt['AeroDyn']['BlOutNd']), 'BlOutNd', '- Blade nodes whose values will be output (-)\n')) f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn']['NTwOuts'], 'NTwOuts', '- Number of tower node outputs [0 - 9] (-)\n')) - if self.fst_vt['AeroDyn']['NTwOuts'] != 0: - f.write('{:<22} {:<11} {:}'.format(', '.join(self.fst_vt['AeroDyn']['TwOutNd']), 'TwOutNd', '- Tower nodes whose values will be output (-)\n')) - else: - f.write('{:<22} {:<11} {:}'.format(0, 'TwOutNd', '- Tower nodes whose values will be output (-)\n')) + # if self.fst_vt['AeroDyn']['NTwOuts'] != 0: # TODO its weird that tower nodes is treated differently than blade nodes + # f.write('{:<22} {:<11} {:}'.format(', '.join(self.fst_vt['AeroDyn']['TwOutNd']), 'TwOutNd', '- Tower nodes whose values will be output (-)\n')) + # else: + # f.write('{:<22} {:<11} {:}'.format(0, 'TwOutNd', '- Tower nodes whose values will be output (-)\n')) + f.write('{:<22} {:<11} {:}'.format(', '.join(self.fst_vt['AeroDyn']['TwOutNd']), 'TwOutNd', '- Tower nodes whose values will be output (-)\n')) f.write(' OutList - The next line(s) contains a list of output parameters. See OutListParameters.xlsx for a listing of available output channels, (-)\n') outlist = self.get_outlist(self.fst_vt['outlist'], ['AeroDyn']) @@ -1249,7 +1250,7 @@ def write_AeroDisk(self): f.write('{:<22f} {:<11} {:}'.format(self.fst_vt['AeroDisk']['AirDens'], 'AirDens', '- Air density (kg/m^3) (or "default")\n')) f.write('--- ACTUATOR DISK PROPERTIES ---\n') f.write('{:<22f} {:<11} {:}'.format(self.fst_vt['AeroDisk']['RotorRad'], 'RotorRad', '- Rotor radius (m) (or "default")\n')) - f.write('{:<22} {:<11} {:}'.format(', '.join(['%s'%i for i in self.fst_vt['AeroDisk']['InColNames']]), 'InColNames', '- Input column headers (string) {may include a combination of "TSR, RtSpd, VRel, Pitch, Skew"} (up to 4 columns) [choose TSR or RtSpd,VRel; if Skew is absent, Skew is modeled as (COS(Skew))^2]\n')) + f.write('"{:<22}" {:<11} {:}'.format(', '.join(['%s'%i for i in self.fst_vt['AeroDisk']['InColNames']]), 'InColNames', '- Input column headers (string) {may include a combination of "TSR, RtSpd, VRel, Pitch, Skew"} (up to 4 columns) [choose TSR or RtSpd,VRel; if Skew is absent, Skew is modeled as (COS(Skew))^2]\n')) f.write('{:<22} {:<11} {:}'.format(', '.join(['%s'%i for i in self.fst_vt['AeroDisk']['InColDims']]), 'InColDims', '- Number of unique values in each column (-) (must have same number of columns as InColName) [each >=2]\n')) self.write_AeroDiskProp() f.write('@{:<22} {:}'.format(self.fst_vt['AeroDisk']['actuatorDiskFile'], '\n')) @@ -1738,8 +1739,8 @@ def write_HydroDyn(self): def write_SeaState(self): # Generate SeaState input file - self.fst_vt['Fst']['SeaState'] = self.FAST_namingOut + '_SeaState.dat' - hd_file = os.path.join(self.FAST_runDirectory, self.fst_vt['Fst']['SeaState']) + self.fst_vt['Fst']['SeaStateFile'] = self.FAST_namingOut + '_SeaState.dat' + hd_file = os.path.join(self.FAST_runDirectory, self.fst_vt['Fst']['SeaStateFile']) f = open(hd_file, 'w') f.write('------- SeaState Input File --------------------------------------------\n') @@ -1822,14 +1823,14 @@ def write_SeaState(self): f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['SeaState']['OutFmt'], 'OutFmt','- Output format for numerical results (quoted string) [not checked for validity!]\n')) f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['SeaState']['OutSFmt'], 'OutSFmt','- Output format for header strings (quoted string) [not checked for validity!]\n')) f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['SeaState']['NWaveElev'], 'NWaveElev','- Number of points where the incident wave elevations can be computed (-) [maximum of 9 output locations]\n')) - f.write('{:<22} {:<11} {:}'.format(", ".join([f'{val:4.2f}' for val in self.fst_vt['SeaState']['WaveElevxi']]), 'WaveElevxi', '- List of xi-coordinates for points where the incident wave elevations can be output (meters) [NWaveElev points, separated by commas or white space; usused if NWaveElev = 0]\n')) - f.write('{:<22} {:<11} {:}'.format(", ".join([f'{val:4.2f}' for val in self.fst_vt['SeaState']['WaveElevyi']]), 'WaveElevyi', '- List of yi-coordinates for points where the incident wave elevations can be output (meters) [NWaveElev points, separated by commas or white space; usused if NWaveElev = 0]\n')) + f.write('{:<22} {:<11} {:}'.format(", ".join([f'{val:f}' for val in self.fst_vt['SeaState']['WaveElevxi']]), 'WaveElevxi', '- List of xi-coordinates for points where the incident wave elevations can be output (meters) [NWaveElev points, separated by commas or white space; usused if NWaveElev = 0]\n')) + f.write('{:<22} {:<11} {:}'.format(", ".join([f'{val:f}' for val in self.fst_vt['SeaState']['WaveElevyi']]), 'WaveElevyi', '- List of yi-coordinates for points where the incident wave elevations can be output (meters) [NWaveElev points, separated by commas or white space; usused if NWaveElev = 0]\n')) f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['SeaState']['NWaveKin'], 'NWaveKin','- Number of points where the incident wave elevations can be computed (-) [maximum of 9 output locations]\n')) if self.fst_vt['SeaState']['NWaveKin'] > 0 : - f.write('{:<22} {:<11} {:}'.format(", ".join([f'{val:4.2f}' for val in self.fst_vt['SeaState']['WaveKinxi']]), 'WaveKinxi', '- List of xi-coordinates for points where the wave kinematics can be output (meters) [NWaveKin points, separated by commas or white space; usused if NWaveKin = 0]\n')) - f.write('{:<22} {:<11} {:}'.format(", ".join([f'{val:4.2f}' for val in self.fst_vt['SeaState']['WaveKinyi']]), 'WaveKinyi', '- List of yi-coordinates for points where the wave kinematics can be output (meters) [NWaveKin points, separated by commas or white space; usused if NWaveKin = 0]\n')) - f.write('{:<22} {:<11} {:}'.format(", ".join([f'{val:4.2f}' for val in self.fst_vt['SeaState']['WaveKinzi']]), 'WaveKinzi', '- List of zi-coordinates for points where the wave kinematics can be output (meters) [NWaveKin points, separated by commas or white space; usused if NWaveKin = 0]\n')) + f.write('{:<22} {:<11} {:}'.format(", ".join([f'{val:f}' for val in self.fst_vt['SeaState']['WaveKinxi']]), 'WaveKinxi', '- List of xi-coordinates for points where the wave kinematics can be output (meters) [NWaveKin points, separated by commas or white space; usused if NWaveKin = 0]\n')) + f.write('{:<22} {:<11} {:}'.format(", ".join([f'{val:f}' for val in self.fst_vt['SeaState']['WaveKinyi']]), 'WaveKinyi', '- List of yi-coordinates for points where the wave kinematics can be output (meters) [NWaveKin points, separated by commas or white space; usused if NWaveKin = 0]\n')) + f.write('{:<22} {:<11} {:}'.format(", ".join([f'{val:f}' for val in self.fst_vt['SeaState']['WaveKinzi']]), 'WaveKinzi', '- List of zi-coordinates for points where the wave kinematics can be output (meters) [NWaveKin points, separated by commas or white space; usused if NWaveKin = 0]\n')) else: f.write('{:<11} {:}'.format('WaveKinxi', '- List of xi-coordinates for points where the wave kinematics can be output (meters) [NWaveKin points, separated by commas or white space; usused if NWaveKin = 0]\n')) f.write('{:<11} {:}'.format('WaveKinyi', '- List of yi-coordinates for points where the wave kinematics can be output (meters) [NWaveKin points, separated by commas or white space; usused if NWaveKin = 0]\n')) @@ -1938,8 +1939,9 @@ def write_SubDyn(self): ln.append('{:^11d}'.format(self.fst_vt['SubDyn']['MPropSetID1'][i])) ln.append('{:^11d}'.format(self.fst_vt['SubDyn']['MPropSetID2'][i])) ln.append('{:^11d}'.format(self.fst_vt['SubDyn']['MType'][i])) - if self.fst_vt['SubDyn']['NCOSMs'] > 0: - ln.append('{:^11d}'.format(self.fst_vt['SubDyn']['M_COSMID'][i])) + # Need to change M_COSMID None elements to -1 + self.fst_vt['SubDyn']['M_COSMID'][i] = -1 if self.fst_vt['SubDyn']['M_COSMID'][i] is None else self.fst_vt['SubDyn']['M_COSMID'][i] + ln.append('{:^11d}'.format(self.fst_vt['SubDyn']['M_COSMID'][i])) f.write(" ".join(ln) + '\n') f.write('------------------ MEMBER X-SECTION PROPERTY data 1/2 [isotropic material for now: use this table for circular-tubular elements] ------------------------\n') f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['SubDyn']['NPropSets'], 'NPropSets', '- Number of structurally unique x-sections (i.e. how many groups of X-sectional properties are utilized throughout all of the members)\n')) From 7ba57ede25fd24b6fb26555d2dfa0cfd88b477de Mon Sep 17 00:00:00 2001 From: Mayank Chetan Date: Mon, 9 Sep 2024 15:18:06 +0000 Subject: [PATCH 054/161] new tests for lib robustness, verifying fst_vt --- openfast_io/openfast_io/FAST_reader.py | 94 ++++++++++++--- openfast_io/openfast_io/FAST_writer.py | 56 ++++++--- .../openfast_io/tests/test_of_io_pytest.py | 107 ++++++++++++++++-- 3 files changed, 217 insertions(+), 40 deletions(-) diff --git a/openfast_io/openfast_io/FAST_reader.py b/openfast_io/openfast_io/FAST_reader.py index 7d19d866e..2e05752ea 100644 --- a/openfast_io/openfast_io/FAST_reader.py +++ b/openfast_io/openfast_io/FAST_reader.py @@ -14,15 +14,38 @@ def readline_filterComments(f): - read = True - while read: - line = f.readline().strip() - if len(line)>0: - if line[0] != '!': - read = False - return line + """ + Filter out comments and empty lines from a file + + Args: + f: file handle + + Returns: + line: next line in the file that is not a comment or empty + """ + read = True + while read: + line = f.readline().strip() + if len(line)>0: + if line[0] != '!': + read = False + return line def read_array(f,len,split_val=None,array_type=str): + """ + Read an array of values from a line in a file + + Args: + f: file handle + len: number of values to read + split_val: value to stop reading at + array_type: type of values to return + + Returns: + arr: list of values read from the file line with the specified type + """ + + strings = re.split(',| ',f.readline().strip()) while '' in strings: # remove empties strings.remove('') @@ -54,7 +77,15 @@ def read_array(f,len,split_val=None,array_type=str): return arr def fix_path(name): - """ split a path, then reconstruct it using os.path.join """ + """ + split a path, then reconstruct it using os.path.join + + Args: + name: path to fix + + Returns: + new: reconstructed path + """ name = re.split("\\|/", name) new = name[0] for i in range(1,len(name)): @@ -62,7 +93,15 @@ def fix_path(name): return new def bool_read(text): - # convert true/false strings to boolean + """ + Read a boolean value from a string + + Args: + text: string to read + + Returns: + True if the string is 'true', False otherwise + """ if 'default' in text.lower(): return str(text) else: @@ -72,7 +111,15 @@ def bool_read(text): return False def float_read(text): - # return float with error handing for "default" values + """ + Read a float value from a string, with error handling for 'default' values + + Args: + text: string to read + + Returns: + float value if the string can be converted, string otherwise + """ if 'default' in text.lower(): return str(text) else: @@ -82,7 +129,15 @@ def float_read(text): return str(text) def int_read(text): - # return int with error handing for "default" values + """ + Read an integer value from a string, with error handling for 'default' values + + Args: + text: string to read + + Returns: + int value if the string can be converted, string otherwise + """ if 'default' in text.lower(): return str(text) else: @@ -92,7 +147,16 @@ def int_read(text): return str(text) def quoted_read(text): - # read a line, if the first part is quoted, return the quoted part, otherwise return the unquoted part + """ + Read a quoted value from a string (i.e. a value between quotes) + + Args: + text: string to read + + Returns: + quoted value if the string is quoted, unquoted value otherwise + + """ if '"' in text: return text.split('"')[1] elif "'" in text: @@ -2555,11 +2619,11 @@ def read_ExtPtfm(self, ep_file): self.fst_vt['ExtPtfm']['Red_FileName'] = os.path.join(os.path.dirname(ep_file), quoted_read(f.readline().split()[0])) self.fst_vt['ExtPtfm']['RedCst_FileName'] = os.path.join(os.path.dirname(ep_file), quoted_read(f.readline().split()[0])) self.fst_vt['ExtPtfm']['NActiveDOFList'] = int_read(f.readline().split()[0]) - self.fst_vt['ExtPtfm']['ActiveDOFList'] = [idx.strip() for idx in f.readline().split('ActiveDOFList')[0].split(',')] + self.fst_vt['ExtPtfm']['ActiveDOFList'] = read_array(f,None,split_val='ActiveDOFList',array_type=int) self.fst_vt['ExtPtfm']['NInitPosList'] = int_read(f.readline().split()[0]) - self.fst_vt['ExtPtfm']['InitPosList'] = [idx.strip() for idx in f.readline().split('InitPosList')[0].split(',')] + self.fst_vt['ExtPtfm']['InitPosList'] = read_array(f,None,split_val='InitPosList',array_type=float) self.fst_vt['ExtPtfm']['NInitVelList'] = int_read(f.readline().split()[0]) - self.fst_vt['ExtPtfm']['InitVelList'] = [idx.strip() for idx in f.readline().split('InitVelList')[0].split(',')] + self.fst_vt['ExtPtfm']['InitVelList'] = read_array(f,None,split_val='InitVelList',array_type=float) f.readline() # Output diff --git a/openfast_io/openfast_io/FAST_writer.py b/openfast_io/openfast_io/FAST_writer.py index 5906afa2e..7fa0083d5 100644 --- a/openfast_io/openfast_io/FAST_writer.py +++ b/openfast_io/openfast_io/FAST_writer.py @@ -15,7 +15,14 @@ def auto_format(f, var): - # Error handling for variables with 'Default' options + """ + Error handling for variables with 'Default' options + + args: + f: file object + var: variable to write to file + + """ if isinstance(var, str): f.write('{:}\n'.format(var)) elif isinstance(var, int): @@ -24,21 +31,46 @@ def auto_format(f, var): f.write('{: 2.15e}\n'.format(var)) def float_default_out(val): - # formatted float output when 'default' is an option + """ + Formatted float output when 'default' is an option + + args: + val: value to be formatted + + returns: + formatted value + """ if type(val) is float: return '{: 22f}'.format(val) else: return '{:<22}'.format(val) def int_default_out(val): - # formatted int output when 'default' is an option + """ + Formatted int output when 'default' is an option + + args: + val: value to be formatted + + returns: + formatted value + """ if type(val) is float: return '{:<22d}'.format(val) else: return '{:<22}'.format(val) -# given a list of nested dictionary keys, return the dict at that point def get_dict(vartree, branch): + """ + Given a list of nested dictionary keys, return the dictionary at that point + + args: + vartree: dictionary to search + branch: list of keys to search + + returns: + dictionary at the specified branch + """ return reduce(operator.getitem, branch, vartree) class InputWriter_OpenFAST(object): @@ -2102,21 +2134,11 @@ def write_ExtPtfm(self): f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['ExtPtfm']['Red_FileName'], 'Red_FileName', '- Path of the file containing Guyan/Craig-Bampton inputs (-)\n')) f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['ExtPtfm']['RedCst_FileName'], 'RedCst_FileName', '- Path of the file containing Guyan/Craig-Bampton constant inputs (-) (currently unused)\n')) f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['ExtPtfm']['NActiveDOFList'], 'NActiveDOFList', '- Number of active CB mode listed in ActiveDOFList, use -1 for all modes (integer)\n')) - # f.write('{:<22} {:<11} {:}'.format(", ".join([str(i) for i in self.fst_vt['ExtPtfm']['ActiveDOFList']]), 'ActiveDOFList', '- List of CB modes index that are active, [unused if NActiveDOFList<=0]\n')) - if self.fst_vt['ExtPtfm']['NActiveDOFList'] > -1: - f.write('{:<22} {:<11} {:}'.format(', '.join(self.fst_vt['ExtPtfm']['ActiveDOFList'][:self.fst_vt['ExtPtfm']['NActiveDOFList']]), 'ActiveDOFList', '- List of CB modes index that are active, [unused if NActiveDOFList<=0]\n')) - else: - f.write('{:<22} {:<11} {:}'.format(', '.join(self.fst_vt['ExtPtfm']['ActiveDOFList']), 'ActiveDOFList', '- List of CB modes index that are active, [unused if NActiveDOFList<=0]\n')) + f.write('{:<22} {:<11} {:}'.format(', '.join([f'{val}' for val in self.fst_vt['ExtPtfm']['ActiveDOFList']]), 'ActiveDOFList', '- List of CB modes index that are active, [unused if NActiveDOFList<=0]\n')) f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['ExtPtfm']['NInitPosList'], 'NInitPosList', '- Number of initial positions listed in InitPosList, using 0 implies all DOF initialized to 0 (integer)\n')) - if self.fst_vt['ExtPtfm']['NInitPosList'] > 0: - f.write('{:<22} {:<11} {:}'.format(', '.join(self.fst_vt['ExtPtfm']['InitPosList'][:self.fst_vt['ExtPtfm']['NInitPosList']]), 'InitPosList', '- List of initial positions for the CB modes [unused if NInitPosList<=0 or EquilStart=True]\n')) - else: - f.write('{:<22d} {:<11} {:}'.format(0, 'InitPosList', '- List of initial positions for the CB modes [unused if NInitPosList<=0 or EquilStart=True]\n')) + f.write('{:<22} {:<11} {:}'.format(', '.join([f'{val}' for val in self.fst_vt['ExtPtfm']['InitPosList']]), 'InitPosList', '- List of initial positions for the CB modes [unused if NInitPosList<=0 or EquilStart=True]\n')) f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['ExtPtfm']['NInitVelList'], 'NInitVelList', '- Number of initial positions listed in InitVelList, using 0 implies all DOF initialized to 0 (integer)\n')) - if self.fst_vt['ExtPtfm']['NInitVelList'] > 0: - f.write('{:<22} {:<11} {:}'.format(', '.join(self.fst_vt['ExtPtfm']['InitVelList'][:self.fst_vt['ExtPtfm']['NInitVelList']]), 'InitVelList', '- List of initial velocities for the CB modes [unused if NInitVelPosList<=0 or EquilStart=True]\n')) - else: - f.write('{:<22d} {:<11} {:}'.format(0, 'InitVelList', '- List of initial velocities for the CB modes [unused if NInitVelPosList<=0 or EquilStart=True]\n')) + f.write('{:<22} {:<11} {:}'.format(', '.join([f'{val}' for val in self.fst_vt['ExtPtfm']['InitVelList']]), 'InitVelList', '- List of initial velocities for the CB modes [unused if NInitVelPosList<=0 or EquilStart=True]\n')) f.write('---------------------- OUTPUT --------------------------------------------------\n') f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['ExtPtfm']['SumPrint'], 'SumPrint', '- Print summary data to .sum (flag)\n')) diff --git a/openfast_io/openfast_io/tests/test_of_io_pytest.py b/openfast_io/openfast_io/tests/test_of_io_pytest.py index b7353344c..c8ad87742 100644 --- a/openfast_io/openfast_io/tests/test_of_io_pytest.py +++ b/openfast_io/openfast_io/tests/test_of_io_pytest.py @@ -62,6 +62,18 @@ def getPaths(OF_PATH = OF_PATH, REPOSITORY_ROOT = REPOSITORY_ROOT, BUILD_DIR = BUILD_DIR): + """ + Function to get the paths for the OpenFAST executable, source directory, build directory, r-test directory, and test data directory + + Args: + OF_PATH (str): Path to the OpenFAST executable + REPOSITORY_ROOT (str): Path to the OpenFAST repository + BUILD_DIR (str): Path to the build directory + + Returns: + dict: Dictionary containing the paths + """ + return { "executable": OF_PATH, "source_dir": REPOSITORY_ROOT, @@ -72,6 +84,17 @@ def getPaths(OF_PATH = OF_PATH, REPOSITORY_ROOT = REPOSITORY_ROOT, BUILD_DIR = B } def read_action(folder, path_dict = getPaths()): + """ + Function to read the input deck for a given folder + + Args: + folder (str): r-test folder name + path_dict (dict): Dictionary containing the paths. Default is getPaths() + + Returns: + dict: OpenFAST VariableTree + + """ print(f"Reading from {folder}") # Read input deck @@ -83,6 +106,15 @@ def read_action(folder, path_dict = getPaths()): return fast_reader.fst_vt def write_action(folder, fst_vt, path_dict = getPaths()): + """ + Function to write the input deck for a given folder + + Args: + folder (str): r-test folder name + fst_vt (dict): OpenFAST VariableTree + path_dict (dict): Dictionary containing the paths. Default is getPaths() + + """ print(f"Writing to {folder}, with TMax = 2.0") # check if the folder exists, if not, mostly being called not from cmake, so create it @@ -107,7 +139,14 @@ def write_action(folder, fst_vt, path_dict = getPaths()): fast_writer.execute() def run_action(folder, path_dict = getPaths()): - # Placeholder for the actual run action + """ + Function to run the simulation for a given folder + + Args: + folder (str): r-test folder name + path_dict (dict): Dictionary containing the paths. Default is getPaths() + + """ print(f"Running simulation for {folder}") command = [f"{path_dict['executable']}", f"{osp.join(path_dict['build_dir'],'openfast_io', folder, f'{folder}.fst')}"] with open(osp.join(path_dict['build_dir'],'openfast_io', folder, f'{folder}.log'), 'w') as f: @@ -115,18 +154,39 @@ def run_action(folder, path_dict = getPaths()): f.close() def check_ascii_out(folder, path_dict = getPaths()): - # Placeholder for the actual check action + """ + Function to read the ASCII output for a given folder + + Args: + folder (str): r-test folder name + path_dict (dict): Dictionary containing the paths. Default is getPaths() + """ print(f"Checking ASCII output for {folder}") asciiOutput = osp.join(path_dict['build_dir'],'openfast_io', folder, f"{folder}.out") fast_outout = FASTOutputFile(filename=asciiOutput) def check_binary_out(folder, path_dict = getPaths()): - # Placeholder for the actual check action + """ + Function to read the binary output for a given folder + + Args: + folder (str): r-test folder name + path_dict (dict): Dictionary containing the paths. Default is getPaths() + """ print(f"Checking binary output for {folder}") binaryOutput = osp.join(path_dict['build_dir'],'openfast_io', folder, f"{folder}.outb") fast_outout = FASTOutputFile(filename=binaryOutput) def check_fst_vt_with_source(folder, path_dict = getPaths()): + + """ + Function to check the fst_vt with the source for a given folder + + Args: + folder (str): r-test folder name + path_dict (dict): Dictionary containing the paths. Default is getPaths() + """ + print(f"Checking the fst_vt with the source for {folder}") # creating the two InputReader_OpenFAST objects @@ -144,7 +204,7 @@ def check_fst_vt_with_source(folder, path_dict = getPaths()): acceptable_diff = [ 'TMax', # TMax is updated in the write_action 'TStart', # TStart is updated in the write_action - 'OutFileFmt', # OutFileFmt is updated in the write_action # TODO check why its not being removed + 'OutFileFmt', # OutFileFmt is updated in the write_action ] @@ -159,6 +219,12 @@ def check_fst_vt_with_source(folder, path_dict = getPaths()): # Begining of the test def test_rtest_cloned(request): + """ + Function to check if the r-tests are cloned properly + + Args: + request (fixture): pytest request + """ REPOSITORY_ROOT = osp.join(request.config.getoption("--source_dir")) path_dict = getPaths(REPOSITORY_ROOT=REPOSITORY_ROOT) @@ -170,6 +236,12 @@ def test_rtest_cloned(request): sys.exit(1) def test_DLLs_exist(request): + """ + Function to check if the DISCON.dll file exists + + Args: + request (fixture): pytest request + """ path_dict = getPaths(OF_PATH=osp.join(request.config.getoption("--build_dir"))) @@ -182,6 +254,12 @@ def test_DLLs_exist(request): sys.exit(1) def test_openfast_executable_exists(request): + """ + Function to check if the OpenFAST executable exists + + Args: + request (fixture): pytest request + """ path_dict = getPaths(OF_PATH=osp.join(request.config.getoption("--executable"))) @@ -195,8 +273,14 @@ def test_openfast_executable_exists(request): # Parameterize the test function to run for each folder and action @pytest.mark.parametrize("folder", FOLDERS_TO_RUN) -# @pytest.mark.parametrize("action_name, action_func", actions) -def test_openfast_io_read_write_run_outRead(folder, request): +def test_openfast_io_read_write_run_readOut_verify(folder, request): + """ + Function to test the read, write, run, check ASCII, check binary, and check fst_vt for a given folder + + Args: + folder (str): r-test folder name + request (fixture): pytest request + """ path_dict = getPaths(OF_PATH=osp.join(request.config.getoption("--executable")), REPOSITORY_ROOT=osp.join(request.config.getoption("--source_dir")), @@ -204,7 +288,6 @@ def test_openfast_io_read_write_run_outRead(folder, request): try: - # action_func(folder) action_name = "read" fst_vt = read_action(folder, path_dict = path_dict) @@ -227,13 +310,17 @@ def test_openfast_io_read_write_run_outRead(folder, request): pytest.fail(f"Action '{action_name}' for folder '{folder}' failed with exception: {e}") def main(): + """ + Main function to run the test for all the folders + """ + # Initialize any necessary setup here for folder in FOLDERS_TO_RUN: print(" ") print(f"Processing folder: {folder}") - # Assuming read_action, write_action, run_action, and check_action are defined elsewhere + # Assuming read_action, write_action, run_action, check_ascii_out, check_binary_out, and check_fst_vt_with_source are defined elsewhere data = read_action(folder) write_action(folder, data) run_action(folder) @@ -243,4 +330,8 @@ def main(): print(f"Successfully processed folder: {folder}") if __name__ == "__main__": + """ + Run the main function if the script is run directly or through VSCode debugger + """ + main() \ No newline at end of file From e16301684584fc5e237e1c9e7cb0d16cb86c27cd Mon Sep 17 00:00:00 2001 From: Mayank Chetan Date: Mon, 9 Sep 2024 15:49:47 +0000 Subject: [PATCH 055/161] remove np.float_ for numpy >2.0 --- openfast_io/openfast_io/FileTools.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openfast_io/openfast_io/FileTools.py b/openfast_io/openfast_io/FileTools.py index 2fe3cbb10..2335314e4 100644 --- a/openfast_io/openfast_io/FileTools.py +++ b/openfast_io/openfast_io/FileTools.py @@ -37,7 +37,7 @@ def loop_dict(vartree, branch): if data_type in [np.int_, np.intc, np.intp, np.int8, np.int16, np.int32, np.int64, np.uint8, np.uint16, np.uint32, np.uint64]: get_dict(fst_vt, branch_i[:-1])[branch_i[-1]] = int(get_dict(fst_vt, branch_i[:-1])[branch_i[-1]]) - elif data_type in [np.single, np.double, np.longdouble, np.csingle, np.cdouble, np.float_, np.float16, np.float32, np.float64, np.complex64, np.complex128]: + elif data_type in [np.single, np.double, np.longdouble, np.csingle, np.cdouble, np.float16, np.float32, np.float64, np.complex64, np.complex128]: get_dict(fst_vt, branch_i[:-1])[branch_i[-1]] = float(get_dict(fst_vt, branch_i[:-1])[branch_i[-1]]) elif data_type in [np.bool_]: get_dict(fst_vt, branch_i[:-1])[branch_i[-1]] = bool(get_dict(fst_vt, branch_i[:-1])[branch_i[-1]]) From e7344080204edb0eeb0ef0744d689aabde05bff0 Mon Sep 17 00:00:00 2001 From: Mayank Chetan Date: Tue, 24 Sep 2024 18:18:07 +0000 Subject: [PATCH 056/161] extinflow --- openfast_io/openfast_io/FAST_writer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openfast_io/openfast_io/FAST_writer.py b/openfast_io/openfast_io/FAST_writer.py index 7fa0083d5..16dbc4544 100644 --- a/openfast_io/openfast_io/FAST_writer.py +++ b/openfast_io/openfast_io/FAST_writer.py @@ -258,7 +258,7 @@ def write_MainInput(self): f.write('{:<22} {:<11} {:}'.format(self.fst_vt['Fst']['UJacSclFact'], 'UJacSclFact', '- Scaling factor used in Jacobians (-)\n')) f.write('---------------------- FEATURE SWITCHES AND FLAGS ------------------------------\n') f.write('{:<22} {:<11} {:}'.format(self.fst_vt['Fst']['CompElast'], 'CompElast', '- Compute structural dynamics (switch) {1=ElastoDyn; 2=ElastoDyn + BeamDyn for blades; 3=Simplified ElastoDyn}\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['Fst']['CompInflow'], 'CompInflow', '- Compute inflow wind velocities (switch) {0=still air; 1=InflowWind; 2=external from OpenFOAM}\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['Fst']['CompInflow'], 'CompInflow', '- Compute inflow wind velocities (switch) {0=still air; 1=InflowWind; 2=external from ExtInflow}\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['Fst']['CompAero'], 'CompAero', '- Compute aerodynamic loads (switch) {0=None; 1=AeroDisk; 2=AeroDyn; 3=ExtLoads}\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['Fst']['CompServo'], 'CompServo', '- Compute control and electrical-drive dynamics (switch) {0=None; 1=ServoDyn}\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['Fst']['CompSeaState'], 'CompSeaState', '- Compute sea state information (switch) {0=None; 1=SeaState}\n')) From 1c96c43f4bdf22738b7d702dc4c094b3f639d484 Mon Sep 17 00:00:00 2001 From: Mayank Chetan Date: Tue, 8 Oct 2024 21:34:06 +0000 Subject: [PATCH 057/161] first pypi test --- .github/workflows/deploy.yml | 4 ++-- .gitignore | 3 ++- openfast_io/openfast_io/FAST_writer.py | 1 - openfast_io/openfast_io/_version.py | 16 ---------------- openfast_io/pyproject.toml | 8 +++----- 5 files changed, 7 insertions(+), 25 deletions(-) delete mode 100644 openfast_io/openfast_io/_version.py diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index f32fb51be..7d58129e5 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -52,7 +52,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v4 with: - python-version: '3.10' + python-version: '3.12' cache: 'pip' - name: Install Hatch @@ -66,7 +66,7 @@ jobs: - name: Publish to PyPI env: HATCH_INDEX_USER: __token__ - HATCH_INDEX_AUTH: ${{ secrets.PYPI_TOKEN }} + HATCH_INDEX_AUTH: ${{ secrets.PYPI_TEST_TOKEN }} run: hatch publish -r test working-directory: openfast_io diff --git a/.gitignore b/.gitignore index 7377fec94..dd46aacb9 100644 --- a/.gitignore +++ b/.gitignore @@ -60,4 +60,5 @@ varcache *.slxc # Python cache files -openfast_io/dist/ \ No newline at end of file +openfast_io/dist/ +openfast_io/openfast_io/_version.py \ No newline at end of file diff --git a/openfast_io/openfast_io/FAST_writer.py b/openfast_io/openfast_io/FAST_writer.py index 16dbc4544..865e62706 100644 --- a/openfast_io/openfast_io/FAST_writer.py +++ b/openfast_io/openfast_io/FAST_writer.py @@ -236,7 +236,6 @@ def execute(self): def write_MainInput(self): # Main FAST Input File - # Currently no differences between FASTv8.16 and OpenFAST. self.FAST_InputFileOut = os.path.join(self.FAST_runDirectory, self.FAST_namingOut+'.fst') diff --git a/openfast_io/openfast_io/_version.py b/openfast_io/openfast_io/_version.py deleted file mode 100644 index 2d1bd5f0f..000000000 --- a/openfast_io/openfast_io/_version.py +++ /dev/null @@ -1,16 +0,0 @@ -# file generated by setuptools_scm -# don't change, don't track in version control -TYPE_CHECKING = False -if TYPE_CHECKING: - from typing import Tuple, Union - VERSION_TUPLE = Tuple[Union[int, str], ...] -else: - VERSION_TUPLE = object - -version: str -__version__: str -__version_tuple__: VERSION_TUPLE -version_tuple: VERSION_TUPLE - -__version__ = version = '4.0.0a1' -__version_tuple__ = version_tuple = (4, 0, 0) diff --git a/openfast_io/pyproject.toml b/openfast_io/pyproject.toml index 58b6991b5..c6072393f 100644 --- a/openfast_io/pyproject.toml +++ b/openfast_io/pyproject.toml @@ -9,12 +9,10 @@ version = "4.0.0.a1" description = "Readers and writers for OpenFAST files." license = {file = "../LICENSE"} authors = [ + {name = "Mayank Chetan", email = "mayank.chetan@nrel.gov" }, + {name = "Andy Platt", email = "andy.platt@nrel.gov" }, + {name = "Derek Slaughter", email = "derek.slaughter@nrel.gov" }, { name = "NREL WISDEM Team", email = "systems.engineering@nrel.gov" }, - { name = "Daniel Zalkind", email = "daniel.zalkind@nrel.gov" }, - { name = "Garrett Barter", email = "garrett.barter@nrel.gov" }, - { name = "Pietro Bortolotti", email = "pietro.bortolotti@nrel.gov" }, - { name = "Mayank Chetan", email = "mayank.chetan@nrel.gov" }, - { name = "John Jasa" }, ] maintainers = [ {name = "Mayank Chetan", email = "mayank.chetan@nrel.gov" }, From dce15eafd9eb6abb5722b4e4c62469fcdd9093d4 Mon Sep 17 00:00:00 2001 From: Mayank Chetan Date: Wed, 9 Oct 2024 17:20:32 +0000 Subject: [PATCH 058/161] adding keyring dependancy fot hatch --- .github/workflows/deploy.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 7d58129e5..c133c9e13 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -58,6 +58,8 @@ jobs: - name: Install Hatch uses: pypa/hatch@install + - name: Install dependencies + run: pip install keyring - name: Build package run: hatch build From bbded1bf7484f23781730f3bc91527fad4a51293 Mon Sep 17 00:00:00 2001 From: Derek Slaughter Date: Mon, 4 Nov 2024 14:05:24 +0000 Subject: [PATCH 059/161] CMAKE_INSTALL_PREFIX was incorrectly being prepended to the install directory for the ftnmod folder which caused it to be in the wrong place when importing OpenFAST as a library in AMR-Wind --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b2dc54651..329915326 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -232,8 +232,8 @@ endforeach(IDIR IN ITEMS ${OPENFAST_MODULES}) add_subdirectory(glue-codes) # Install fortran .mod files also to installation directory -install(DIRECTORY ${CMAKE_Fortran_MODULE_DIRECTORY}/ - DESTINATION ${CMAKE_INSTALL_PREFIX}/include/openfast/ +install(DIRECTORY ${CMAKE_Fortran_MODULE_DIRECTORY} + DESTINATION include/openfast/ FILES_MATCHING PATTERN "*.mod" ) From 309832aa26edc2ecf8e895958886773b2cc14226 Mon Sep 17 00:00:00 2001 From: andrew-platt Date: Mon, 4 Nov 2024 10:06:00 -0700 Subject: [PATCH 060/161] Docker: typo was preventing docker build upload to GH --- .github/workflows/deploy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 180969d6f..b94a541b1 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -77,7 +77,7 @@ jobs: file: ${{ env.DOCKERFILE_PATH }} platforms: linux/amd64,linux/aarch64 tags: | - ${{ env.GH_REGISTRY }}:${{ steps.extract-tag.outputs.openfast-tag }},${{ env.DOCKERHUB_REPOSITORY }}:latest + ${{ env.GH_REGISTRY }}:${{ steps.extract-tag.outputs.openfast-tag }},${{ env.GH_REGISTRY }}:latest # ${{ env.DOCKERHUB_REPOSITORY }}:${{ steps.extract-tag.outputs.openfast-tag }},${{ env.DOCKERHUB_REPOSITORY }}:latest push: true cache-from: type=gha From a6268d3cb4d18e186555b557273baa14720e3a85 Mon Sep 17 00:00:00 2001 From: Derek Slaughter Date: Tue, 5 Nov 2024 16:46:57 +0000 Subject: [PATCH 061/161] Remove OpenMP statements from AeroDyn_Inflow.f90 because it causes compilation to fail when using the Intel oneAPI 2024.1.0 compiler --- modules/aerodyn/src/AeroDyn_Inflow.f90 | 4 ---- 1 file changed, 4 deletions(-) diff --git a/modules/aerodyn/src/AeroDyn_Inflow.f90 b/modules/aerodyn/src/AeroDyn_Inflow.f90 index 6dd777366..17ad2f4bb 100644 --- a/modules/aerodyn/src/AeroDyn_Inflow.f90 +++ b/modules/aerodyn/src/AeroDyn_Inflow.f90 @@ -488,16 +488,12 @@ subroutine ADI_CalcOutput_IW(t, u_IfW, IW, errStat, errMsg) call InflowWind_CalcOutput(t, u_IfW, IW%p, IW%x, IW%xd, IW%z, IW%OtherSt, IW%y, IW%m, errStat2, errMsg2) call SetErrStat(errStat2, errMsg2, errStat, errMsg, 'ADI_CalcOutput_IW') else - !$OMP PARALLEL DEFAULT(SHARED) - !$OMP DO PRIVATE(j,z) schedule(runtime) do j=1,size(u_IfW%PositionXYZ,2) z = u_IfW%PositionXYZ(3,j) IW%y%VelocityUVW(1,j) = IW%HWindSpeed*(z/IW%RefHt)**IW%PLExp IW%y%VelocityUVW(2,j) = 0.0_ReKi !V IW%y%VelocityUVW(3,j) = 0.0_ReKi !W end do - !$OMP END DO - !$OMP END PARALLEL endif end subroutine ADI_CalcOutput_IW !---------------------------------------------------------------------------------------------------------------------------------- From ee1726c348941662371b9823e4420c2464c9dc96 Mon Sep 17 00:00:00 2001 From: Mayank Chetan Date: Wed, 6 Nov 2024 15:30:12 -0700 Subject: [PATCH 062/161] change to tag tracking --- .github/workflows/deploy.yml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index b94a541b1..f28aee59c 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -41,7 +41,7 @@ jobs: env: DOCKERFILE_PATH: share/docker/Dockerfile DOCKERHUB_REPOSITORY: nrel/openfast - GH_REGISTRY: ghcr.io/OpenFAST/openfast + GH_REGISTRY: ghcr.io/openfast/openfast permissions: contents: read packages: write @@ -68,7 +68,11 @@ jobs: - name: Extract tag from release candidate branch name id: extract-tag - run: echo "openfast-tag=$(expr substr "${{ github.head_ref }}" 4 100)" >> $GITHUB_OUTPUT + run: | + TAG="${{ github.event.release.tag_name }}" + CLEAN_TAG="${TAG#v}" + echo "openfast-tag=$CLEAN_TAG" >> $GITHUB_OUTPUT + echo "Extracted tag $CLEAN_TAG" - name: Build and push to registry uses: docker/build-push-action@v5 From 3acba023b3280424a7abbdc9706f6b0b8f00b2eb Mon Sep 17 00:00:00 2001 From: Mayank Chetan Date: Fri, 8 Nov 2024 11:08:40 -0700 Subject: [PATCH 063/161] repository name must be lowercase --- .github/workflows/build-docker-image-manual.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-docker-image-manual.yml b/.github/workflows/build-docker-image-manual.yml index 608bd0230..a017443a0 100644 --- a/.github/workflows/build-docker-image-manual.yml +++ b/.github/workflows/build-docker-image-manual.yml @@ -20,9 +20,9 @@ jobs: timeout-minutes: 300 env: DOCKERFILE_PATH: share/docker/Dockerfile - DOCKERFILE_PERMALINK: https://raw.githubusercontent.com/OpenFAST/openfast/main/share/docker/Dockerfile + DOCKERFILE_PERMALINK: https://raw.githubusercontent.com/openfast/openfast/main/share/docker/Dockerfile DOCKERHUB_REPOSITORY: nrel/openfast - GH_REGISTRY: ghcr.io/OpenFAST/openfast + GH_REGISTRY: ghcr.io/openfast/openfast permissions: contents: read packages: write From 15bafa4d4830749b6cff6fa0f89278f7fd1c5180 Mon Sep 17 00:00:00 2001 From: andrew-platt Date: Thu, 14 Nov 2024 16:36:26 -0700 Subject: [PATCH 064/161] AD bugfix: Segmentation fault with ifx When OLAF was used with the AeroDyn Driver compiled with ifx (IFX) 2023.2.0 20230622 (release only), there would be a segmentation fault when SetInputsForFVW was called. The root issue was that passing an array of `u` as `(/u/)` doesn't work correctly with this compiler. So to work around this, the SetInputsForFVW routine was reworked to only operate on a single `u`. In my opinion this is a hack of a solution to accomodate a compiler bug. --- modules/aerodyn/src/AeroDyn.f90 | 52 ++++++++++++++++----------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/modules/aerodyn/src/AeroDyn.f90 b/modules/aerodyn/src/AeroDyn.f90 index e631ea3fc..658f12bce 100644 --- a/modules/aerodyn/src/AeroDyn.f90 +++ b/modules/aerodyn/src/AeroDyn.f90 @@ -1623,8 +1623,10 @@ subroutine AD_UpdateStates( t, n, u, utimes, p, x, xd, z, OtherState, m, errStat else ! Call the FVW sub module ! This needs to extract the inputs from the AD data types (mesh) and copy pieces for the FVW module - call SetInputsForFVW(p, u, m, errStat2, errMsg2) - call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + do i=1,size(u) + call SetInputsForFVW(p, u(i), i, m, errStat2, errMsg2) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + enddo ! Note: the setup is handled above in the SetInputs routine call FVW_UpdateStates( t, n, m%FVW_u, utimes, p%FVW, x%FVW, xd%FVW, z%FVW, OtherState%FVW, p%AFI, m%FVW, ErrStat2, ErrMsg2 ) call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) @@ -1696,7 +1698,7 @@ subroutine AD_CalcOutput( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMsg, if (p%WakeMod == WakeMod_FVW) then ! This needs to extract the inputs from the AD data types (mesh) and copy pieces for the FVW module - call SetInputsForFVW(p, (/u/), m, errStat2, errMsg2) + call SetInputsForFVW(p, u, 1, m, errStat2, errMsg2) call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ! Calculate Outputs at time t CALL FVW_CalcOutput( t, m%FVW_u(1), p%FVW, x%FVW, xd%FVW, z%FVW, OtherState%FVW, m%FVW_y, m%FVW, ErrStat2, ErrMsg2 ) @@ -3091,10 +3093,11 @@ subroutine Calculate_MeshOrientation_LiftingLine(p, u, m, thetaBladeNds, toeBlad end subroutine Calculate_MeshOrientation_LiftingLine !---------------------------------------------------------------------------------------------------------------------------------- !> This subroutine sets m%FVW_u(indx). -subroutine SetInputsForFVW(p, u, m, errStat, errMsg) +subroutine SetInputsForFVW(p, u, tIndx, m, errStat, errMsg) type(AD_ParameterType), intent(in ) :: p !< AD parameters - type(AD_InputType), intent(in ) :: u(:) !< AD Inputs at Time + type(AD_InputType), intent(in ) :: u !< AD Inputs at Time + integer(intKi), intent(in ) :: tIndx !< index of m%FVW_u() array type(AD_MiscVarType), intent(inout) :: m !< Misc/optimization variables integer(IntKi), intent( out) :: ErrStat !< Error status of the operation character(*), intent( out) :: ErrMsg !< Error message if ErrStat /= ErrID_None @@ -3102,7 +3105,6 @@ subroutine SetInputsForFVW(p, u, m, errStat, errMsg) real(R8Ki) :: x_hat_disk(3) real(R8Ki), allocatable :: thetaBladeNds(:,:) - integer(intKi) :: tIndx integer(intKi) :: iR ! Loop on rotors integer(intKi) :: j, k ! loop counter for blades integer(intKi) :: ErrStat2 @@ -3113,55 +3115,54 @@ subroutine SetInputsForFVW(p, u, m, errStat, errMsg) ErrStat = ErrID_None ErrMsg = "" - do tIndx=1,size(u) do iR =1, size(p%rotors) allocate(thetaBladeNds(p%rotors(iR)%NumBlNds, p%rotors(iR)%NumBlades)) ! Get disk average values and orientations ! NOTE: needed because it sets m%V_diskAvg and m%V_dot_x, needed by CalcOutput.. - call DiskAvgValues(p%rotors(iR), u(tIndx)%rotors(iR), m%rotors(iR), x_hat_disk) ! also sets m%V_diskAvg and m%V_dot_x + call DiskAvgValues(p%rotors(iR), u%rotors(iR), m%rotors(iR), x_hat_disk) ! also sets m%V_diskAvg and m%V_dot_x if (p%rotors(iR)%AeroProjMod==APM_BEM_NoSweepPitchTwist) then - call Calculate_MeshOrientation_NoSweepPitchTwist(p%rotors(iR),u(tIndx)%rotors(iR), m%rotors(iR), thetaBladeNds,ErrStat=ErrStat2,ErrMsg=ErrMsg2) ! sets m%orientationAnnulus, m%Curve + call Calculate_MeshOrientation_NoSweepPitchTwist(p%rotors(iR),u%rotors(iR), m%rotors(iR), thetaBladeNds,ErrStat=ErrStat2,ErrMsg=ErrMsg2) ! sets m%orientationAnnulus, m%Curve else if (p%rotors(iR)%AeroProjMod==APM_LiftingLine) then - call Calculate_MeshOrientation_LiftingLine (p%rotors(iR),u(tIndx)%rotors(iR), m%rotors(iR), thetaBladeNds,ErrStat=ErrStat2,ErrMsg=ErrMsg2) ! sets m%orientationAnnulus, m%Curve + call Calculate_MeshOrientation_LiftingLine (p%rotors(iR),u%rotors(iR), m%rotors(iR), thetaBladeNds,ErrStat=ErrStat2,ErrMsg=ErrMsg2) ! sets m%orientationAnnulus, m%Curve endif - call StorePitchAndAzimuth(p%rotors(iR), u(tIndx)%rotors(iR), m%rotors(iR), ErrStat2, ErrMsg2) + call StorePitchAndAzimuth(p%rotors(iR), u%rotors(iR), m%rotors(iR), ErrStat2, ErrMsg2) call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) if (ErrStat >= AbortErrLev) return - + ! Rather than use a meshcopy, we will just copy what we need to the WingsMesh ! NOTE: MeshCopy requires the source mesh to be INOUT intent ! NOTE2: If we change the WingsMesh to not be identical to the BladeMotion mesh, add the mapping stuff here. do k=1,p%rotors(iR)%NumBlades iW=p%FVW%Bld2Wings(iR,k) - - if ( u(tIndx)%rotors(iR)%BladeMotion(k)%nNodes /= m%FVW_u(tIndx)%WingsMesh(iW)%nNodes ) then + + if ( u%rotors(iR)%BladeMotion(k)%nNodes /= m%FVW_u(tIndx)%WingsMesh(iW)%nNodes ) then call SetErrStat(ErrID_Fatal,"WingsMesh contains different number of nodes than the BladeMotion mesh",ErrStat,ErrMsg,RoutineName) return endif m%FVW%W(iW)%PitchAndTwist(:) = thetaBladeNds(:,k) ! local pitch + twist (aerodyanmic + elastic) angle of the jth node in the kth blade - m%FVW_u(tIndx)%WingsMesh(iW)%TranslationDisp = u(tIndx)%rotors(iR)%BladeMotion(k)%TranslationDisp - m%FVW_u(tIndx)%WingsMesh(iW)%Orientation = u(tIndx)%rotors(iR)%BladeMotion(k)%Orientation - m%FVW_u(tIndx)%WingsMesh(iW)%TranslationVel = u(tIndx)%rotors(iR)%BladeMotion(k)%TranslationVel - m%FVW_u(tIndx)%rotors(iR)%HubPosition = u(tIndx)%rotors(iR)%HubMotion%Position(:,1) + u(tIndx)%rotors(iR)%HubMotion%TranslationDisp(:,1) - m%FVW_u(tIndx)%rotors(iR)%HubOrientation = u(tIndx)%rotors(iR)%HubMotion%Orientation(:,:,1) - + m%FVW_u(tIndx)%WingsMesh(iW)%TranslationDisp = u%rotors(iR)%BladeMotion(k)%TranslationDisp + m%FVW_u(tIndx)%WingsMesh(iW)%Orientation = u%rotors(iR)%BladeMotion(k)%Orientation + m%FVW_u(tIndx)%WingsMesh(iW)%TranslationVel = u%rotors(iR)%BladeMotion(k)%TranslationVel + m%FVW_u(tIndx)%rotors(iR)%HubPosition = u%rotors(iR)%HubMotion%Position(:,1) + u%rotors(iR)%HubMotion%TranslationDisp(:,1) + m%FVW_u(tIndx)%rotors(iR)%HubOrientation = u%rotors(iR)%HubMotion%Orientation(:,:,1) + ! Inputs for dynamic stall (see SetInputsForBEMT) do j=1,p%rotors(iR)%NumBlNds ! inputs for CUA, section pitch/torsion rate - m%FVW_u(tIndx)%W(iW)%omega_z(j) = dot_product( u(tIndx)%rotors(iR)%BladeMotion(k)%RotationVel( :,j), m%rotors(iR)%orientationAnnulus(3,:,j,k) ) ! rotation of no-sweep-pitch coordinate system around z of the jth node in the kth blade + m%FVW_u(tIndx)%W(iW)%omega_z(j) = dot_product( u%rotors(iR)%BladeMotion(k)%RotationVel( :,j), m%rotors(iR)%orientationAnnulus(3,:,j,k) ) ! rotation of no-sweep-pitch coordinate system around z of the jth node in the kth blade end do !j=nodes enddo ! k blades if (allocated(thetaBladeNds)) deallocate(thetaBladeNds) enddo ! iR, rotors - + if (ALLOCATED(m%FVW_u(tIndx)%V_wind)) then - m%FVW_u(tIndx)%V_wind = u(tIndx)%InflowWakeVel + m%FVW_u(tIndx)%V_wind = u%InflowWakeVel ! Applying tower shadow to V_wind based on r_wind positions ! NOTE: m%DisturbedInflow also contains tower shadow and we need it for CalcOutput if (p%FVW%TwrShadowOnWake) then do iR =1, size(p%rotors) if (p%rotors(iR)%TwrPotent /= TwrPotent_none .or. p%rotors(iR)%TwrShadow /= TwrShadow_none) then - call TwrInflArray( p%rotors(iR), u(tIndx)%rotors(iR), m%rotors(iR), m%FVW%r_wind, m%FVW_u(tIndx)%V_wind, ErrStat2, ErrMsg2 ) + call TwrInflArray( p%rotors(iR), u%rotors(iR), m%rotors(iR), m%FVW%r_wind, m%FVW_u(tIndx)%V_wind, ErrStat2, ErrMsg2 ) call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) if (ErrStat >= AbortErrLev) return endif @@ -3170,14 +3171,13 @@ subroutine SetInputsForFVW(p, u, m, errStat, errMsg) endif do iR =1, size(p%rotors) ! Disturbed inflow for UA on Lifting line Mesh Points - call SetDisturbedInflow(p%rotors(iR), p, u(tIndx)%rotors(iR), m%rotors(iR), errStat2, errMsg2) + call SetDisturbedInflow(p%rotors(iR), p, u%rotors(iR), m%rotors(iR), errStat2, errMsg2) call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) do k=1,p%rotors(iR)%NumBlades iW=p%FVW%Bld2Wings(iR,k) m%FVW_u(tIndx)%W(iW)%Vwnd_LL(1:3,:) = m%rotors(iR)%DisturbedInflow(1:3,:,k) enddo enddo - enddo end subroutine SetInputsForFVW !---------------------------------------------------------------------------------------------------------------------------------- From d4ea5ffb8df45b0228c33aab651dfb5b9ddb7b2d Mon Sep 17 00:00:00 2001 From: andrew-platt Date: Fri, 15 Nov 2024 14:40:48 -0700 Subject: [PATCH 065/161] ADI bugfix: BoxExceed was not enabled for OLAF with ADI Neither the C-bindings nor AD driver could use the BoxExceedAllow option with OLAF --- modules/aerodyn/src/AeroDyn_Inflow.f90 | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/modules/aerodyn/src/AeroDyn_Inflow.f90 b/modules/aerodyn/src/AeroDyn_Inflow.f90 index 17ad2f4bb..c83971db0 100644 --- a/modules/aerodyn/src/AeroDyn_Inflow.f90 +++ b/modules/aerodyn/src/AeroDyn_Inflow.f90 @@ -4,7 +4,7 @@ module AeroDyn_Inflow use NWTC_Library use AeroDyn_Inflow_Types use AeroDyn_Types - use AeroDyn, only: AD_Init, AD_ReInit, AD_CalcOutput, AD_UpdateStates, AD_End + use AeroDyn, only: AD_Init, AD_ReInit, AD_CalcOutput, AD_UpdateStates, AD_End, AD_BoxExceedPointsIdx use AeroDyn, only: AD_NumWindPoints, AD_GetExternalWind, AD_SetExternalWindPositions use AeroDyn_IO, only: AD_SetVTKSurface use InflowWind, only: InflowWind_Init, InflowWind_CalcOutput, InflowWind_End @@ -344,6 +344,11 @@ subroutine ADI_InitInflowWind(Root, i_IW, u_AD, o_AD, IW, dt, InitOutData, errSt InitInData%InputFileName = i_IW%InputFile InitInData%Linearize = i_IW%Linearize InitInData%UseInputFile = i_IW%UseInputFile + ! Box exceed allow for OLAF poitns + if (allocated(o_AD%WakeLocationPoints)) then + InitInData%BoxExceedAllowF = .true. + InitInData%BoxExceedAllowIdx = min(InitInData%BoxExceedAllowIdx, AD_BoxExceedPointsIdx(u_AD, o_AD)) + endif if (.not. i_IW%UseInputFile) then call NWTC_Library_Copyfileinfotype( i_IW%PassedFileData, InitInData%PassedFileData, MESH_NEWCOPY, errStat2, errMsg2 ); if (Failed()) return endif From 901e3b325a42dc7768c75846aa22bd908690e1d0 Mon Sep 17 00:00:00 2001 From: andrew-platt Date: Fri, 22 Nov 2024 15:12:36 -0700 Subject: [PATCH 066/161] Incorrect initial value for `BoxExceedAllowIdx` This was introduced in PR #2518. The result was that anytime the driver was used with OLAF, all points were allowed outside the box, not just the wake as intended. --- modules/aerodyn/src/AeroDyn_Inflow.f90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/aerodyn/src/AeroDyn_Inflow.f90 b/modules/aerodyn/src/AeroDyn_Inflow.f90 index c83971db0..0418fa019 100644 --- a/modules/aerodyn/src/AeroDyn_Inflow.f90 +++ b/modules/aerodyn/src/AeroDyn_Inflow.f90 @@ -347,7 +347,7 @@ subroutine ADI_InitInflowWind(Root, i_IW, u_AD, o_AD, IW, dt, InitOutData, errSt ! Box exceed allow for OLAF poitns if (allocated(o_AD%WakeLocationPoints)) then InitInData%BoxExceedAllowF = .true. - InitInData%BoxExceedAllowIdx = min(InitInData%BoxExceedAllowIdx, AD_BoxExceedPointsIdx(u_AD, o_AD)) + InitInData%BoxExceedAllowIdx = AD_BoxExceedPointsIdx(u_AD, o_AD) endif if (.not. i_IW%UseInputFile) then call NWTC_Library_Copyfileinfotype( i_IW%PassedFileData, InitInData%PassedFileData, MESH_NEWCOPY, errStat2, errMsg2 ); if (Failed()) return From 5bbddd98e934ad61fbd3900fcface1ec94841886 Mon Sep 17 00:00:00 2001 From: andrew-platt Date: Fri, 22 Nov 2024 15:18:31 -0700 Subject: [PATCH 067/161] Fix error in BoxExceedAllowIdx in glue code IfW defaults this to -1, so if OLAF is used it would simply pass -1 for the index rather than the correct location from the AD_BoxExceedPointsIdx routine. --- modules/openfast-library/src/FAST_Subs.f90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/openfast-library/src/FAST_Subs.f90 b/modules/openfast-library/src/FAST_Subs.f90 index 7fc3954ec..e23cfe2e0 100644 --- a/modules/openfast-library/src/FAST_Subs.f90 +++ b/modules/openfast-library/src/FAST_Subs.f90 @@ -578,7 +578,7 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, ! Wake -- we allow the wake positions to exceed the wind box if (allocated(AD%OtherSt(STATE_CURR)%WakeLocationPoints)) then Init%InData_IfW%BoxExceedAllowF = .true. - Init%InData_IfW%BoxExceedAllowIdx = min(Init%InData_IfW%BoxExceedAllowIdx, AD_BoxExceedPointsIdx(AD%Input(1), AD%OtherSt(STATE_CURR))) + Init%InData_IfW%BoxExceedAllowIdx = AD_BoxExceedPointsIdx(AD%Input(1), AD%OtherSt(STATE_CURR)) endif END IF From 239316f415234380ce149a2ef8c7d01d5b9a5305 Mon Sep 17 00:00:00 2001 From: andrew-platt Date: Sat, 23 Nov 2024 16:48:08 -0700 Subject: [PATCH 068/161] bugfix: IfW rotor points for disk average incorrect The calculations for the rotor disk average wind speed use a set of point projected on the disk perpindular to the hub at ~0.7 rotor radius in the hub YZ plane. However, the indices for this calculation were incorrect and projected the points onto disk in the hub XY plane. This was discovered after one of the cases used in the curled wake paper failed to run correctly with 3.5.4 for a turbine very close to the back edge of the high resolution domain. Also added some additional information about the location of points causing outside box bound errors. --- modules/inflowwind/src/IfW_FlowField.f90 | 8 +++++--- modules/inflowwind/src/InflowWind_Subs.f90 | 6 +++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/modules/inflowwind/src/IfW_FlowField.f90 b/modules/inflowwind/src/IfW_FlowField.f90 index a71b75dff..d20e1815d 100644 --- a/modules/inflowwind/src/IfW_FlowField.f90 +++ b/modules/inflowwind/src/IfW_FlowField.f90 @@ -1591,6 +1591,7 @@ subroutine Grid4DField_GetVel(G4D, Time, Position, Velocity, ErrStat, ErrMsg) real(ReKi) :: P(3, 16) ! Point values real(ReKi) :: tmp integer(IntKi) :: i + character(60) :: PtLoc ErrStat = ErrID_None ErrMsg = "" @@ -1627,11 +1628,12 @@ subroutine Grid4DField_GetVel(G4D, Time, Position, Velocity, ErrStat, ErrMsg) do i = 1, 4 if (Indx_Lo(i) <= 0) then Indx_Lo(i) = 1 - call SetErrStat(ErrID_Fatal, 'Outside the grid bounds.', ErrStat, ErrMsg, RoutineName) + write(PtLoc,'(A1,3(f8.2,A1))') '(',Position(1),',',Position(2),',',Position(3),')' + call SetErrStat(ErrID_Fatal, 'Outside the grid bounds: '//trim(PtLoc), ErrStat, ErrMsg, RoutineName) return elseif (Indx_Lo(i) >= G4D%n(i)) then - Indx_Lo(i) = max(G4D%n(i) - 1, 1) ! make sure it's a valid index - call SetErrStat(ErrID_Fatal, 'Outside the grid bounds.', ErrStat, ErrMsg, RoutineName) + write(PtLoc,'(A1,3(f8.2,A1))') '(',Position(1),',',Position(2),',',Position(3),')' + call SetErrStat(ErrID_Fatal, 'Outside the grid bounds: '//trim(PtLoc), ErrStat, ErrMsg, RoutineName) return end if Indx_Hi(i) = min(Indx_Lo(i) + 1, G4D%n(i)) ! make sure it's a valid index diff --git a/modules/inflowwind/src/InflowWind_Subs.f90 b/modules/inflowwind/src/InflowWind_Subs.f90 index de910b24c..8b5a18b0c 100644 --- a/modules/inflowwind/src/InflowWind_Subs.f90 +++ b/modules/inflowwind/src/InflowWind_Subs.f90 @@ -1047,9 +1047,9 @@ SUBROUTINE InflowWind_SetParameters( InitInp, InputFileData, p, m, ErrStat, ErrM do i=1,IfW_NumPtsAvg theta = pi +(i-1)*TwoPi/IfW_NumPtsAvg - p%PositionAvg(1,i) = R*cos(theta) - p%PositionAvg(2,i) = R*sin(theta) - p%PositionAvg(3,i) = 0.0_ReKi + p%PositionAvg(1,i) = 0.0_ReKi ! Hub X (perpindicular to rotor plane) + p%PositionAvg(2,i) = R*cos(theta) ! Hub Y + p%PositionAvg(3,i) = R*sin(theta) ! Hub Z (in vertical plane when azimuth=0) end do p%OutputAccel = InitInp%OutputAccel From ce8351ea2fbb356ae105d6e38ae00a630268c305 Mon Sep 17 00:00:00 2001 From: andrew-platt Date: Mon, 25 Nov 2024 13:05:51 -0700 Subject: [PATCH 069/161] IfW: use single point for disk average if no radius given --- modules/inflowwind/src/InflowWind_Subs.f90 | 39 +++++++++++++--------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/modules/inflowwind/src/InflowWind_Subs.f90 b/modules/inflowwind/src/InflowWind_Subs.f90 index 8b5a18b0c..c8349ffbd 100644 --- a/modules/inflowwind/src/InflowWind_Subs.f90 +++ b/modules/inflowwind/src/InflowWind_Subs.f90 @@ -967,6 +967,7 @@ SUBROUTINE InflowWind_SetParameters( InitInp, InputFileData, p, m, ErrStat, ErrM ! Temporary variables INTEGER(IntKi) :: TmpErrStat !< Temporary error status for subroutine and function calls CHARACTER(ErrMsgLen) :: TmpErrMsg !< Temporary error message for subroutine and function calls + integer(IntKi) :: NumPtsAvg !< Number of points to use for disk average vel (1 if no radius) ! Local variables INTEGER(IntKi) :: I !< Generic counter @@ -1029,28 +1030,34 @@ SUBROUTINE InflowWind_SetParameters( InitInp, InputFileData, p, m, ErrStat, ErrM CALL AllocAry( m%y_Hub%VelocityUVW, 3, 1, "Array of velocities for hub values", TmpErrStat, TmpErrMsg ) CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - CALL AllocAry( m%u_Avg%PositionXYZ, 3, IfW_NumPtsAvg, "Array of positions for rotor-averaged values", TmpErrStat, TmpErrMsg ) + ! Disk Velocity calculations + if (InitInp%RadAvg < 0.0_ReKi) then + NumPtsAvg = 1_IntKi ! Use only hub point + else + NumPtsAvg = IfW_NumPtsAvg ! Use a field of points for disk average calculations + endif + + CALL AllocAry( m%u_Avg%PositionXYZ, 3, NumPtsAvg, "Array of positions for rotor-averaged values", TmpErrStat, TmpErrMsg ) CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - CALL AllocAry( m%y_Avg%VelocityUVW, 3, IfW_NumPtsAvg, "Array of velocities for rotor-averaged values", TmpErrStat, TmpErrMsg ) + CALL AllocAry( m%y_Avg%VelocityUVW, 3, NumPtsAvg, "Array of velocities for rotor-averaged values", TmpErrStat, TmpErrMsg ) CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - CALL AllocAry( p%PositionAvg, 3, IfW_NumPtsAvg, "Array of positions for computing average wind speed", TmpErrStat, TmpErrMsg ) + CALL AllocAry( p%PositionAvg, 3, NumPtsAvg, "Array of positions for computing average wind speed", TmpErrStat, TmpErrMsg ) CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) IF ( ErrStat>= AbortErrLev ) RETURN if (InitInp%RadAvg < 0.0_ReKi) then - R = max(1.0_ReKi, InputFileData%Uniform_RefLength)/2.0_ReKi ! We'll use this as a guess for the rotor radius + p%PositionAvg = 0.0_ReKi ! Use only hub else - R = InitInp%RadAvg + ! Calculate a ring of points at 70 rotor radius + R = InitInp%RadAvg * 0.7_ReKi !70% radius + do i=1,NumPtsAvg + theta = pi +(i-1)*TwoPi/NumPtsAvg + p%PositionAvg(1,i) = 0.0_ReKi ! Hub X (perpindicular to rotor plane) + p%PositionAvg(2,i) = R*cos(theta) ! Hub Y + p%PositionAvg(3,i) = R*sin(theta) ! Hub Z (in vertical plane when azimuth=0) + end do end if - R = R * 0.7_ReKi !70% radius - - do i=1,IfW_NumPtsAvg - theta = pi +(i-1)*TwoPi/IfW_NumPtsAvg - p%PositionAvg(1,i) = 0.0_ReKi ! Hub X (perpindicular to rotor plane) - p%PositionAvg(2,i) = R*cos(theta) ! Hub Y - p%PositionAvg(3,i) = R*sin(theta) ! Hub Z (in vertical plane when azimuth=0) - end do p%OutputAccel = InitInp%OutputAccel @@ -1709,17 +1716,17 @@ SUBROUTINE InflowWind_GetSpatialAverage( Time, InputData, p, x, xd, z, OtherStat m%u_Avg%HubPosition = InputData%HubPosition m%u_Avg%HubOrientation = InputData%HubOrientation - do i=1,IfW_NumPtsAvg + do i=1,size(m%u_Avg%PositionXYZ,DIM=2) m%u_Avg%PositionXYZ(:,i) = matmul(InputData%HubOrientation,p%PositionAvg(:,i)) + InputData%HubPosition end do CALL CalculateOutput( Time, m%u_Avg, p, x, xd, z, OtherStates, m%y_Avg, m, FillWrOut, ErrStat2, ErrMsg2 ) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - do i=1,IfW_NumPtsAvg + do i=1,size(m%u_Avg%PositionXYZ,DIM=2) MeanVelocity = MeanVelocity + m%y_Avg%VelocityUVW(:,i) end do - MeanVelocity = MeanVelocity / REAL(IfW_NumPtsAvg,ReKi) + MeanVelocity = MeanVelocity / REAL(size(m%u_Avg%PositionXYZ,DIM=2),ReKi) RETURN From 28c15b043687229ecc46890470a4fde955a283d7 Mon Sep 17 00:00:00 2001 From: andrew-platt Date: Mon, 25 Nov 2024 13:37:53 -0700 Subject: [PATCH 070/161] Update AD14 cases using disk average velocity --- reg_tests/r-test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reg_tests/r-test b/reg_tests/r-test index f282c79af..a820ba376 160000 --- a/reg_tests/r-test +++ b/reg_tests/r-test @@ -1 +1 @@ -Subproject commit f282c79af7152d20ec7becb7a7c9edbf65cca71c +Subproject commit a820ba376e4f38413e01cacf461eaf5eb3c21154 From 84537f7d017aeef70170c4b1e89a87b5e61fb73c Mon Sep 17 00:00:00 2001 From: andrew-platt Date: Mon, 25 Nov 2024 15:27:41 -0700 Subject: [PATCH 071/161] FF: increase number of output planes to 999 --- glue-codes/fast-farm/src/FAST_Farm_Subs.f90 | 14 +++++++------- modules/awae/src/AWAE.f90 | 8 ++++---- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/glue-codes/fast-farm/src/FAST_Farm_Subs.f90 b/glue-codes/fast-farm/src/FAST_Farm_Subs.f90 index 1ee45ea21..0727b70b0 100644 --- a/glue-codes/fast-farm/src/FAST_Farm_Subs.f90 +++ b/glue-codes/fast-farm/src/FAST_Farm_Subs.f90 @@ -44,7 +44,7 @@ MODULE FAST_Farm_Subs integer, parameter :: maxOutputPoints = 9 - integer, parameter :: maxOutputPlanes = 99 ! Allow up to 99 outpt planes + integer, parameter :: maxOutputPlanes = 999 ! Allow up to 999 outpt planes CONTAINS @@ -1140,7 +1140,7 @@ SUBROUTINE Farm_ReadPrimaryFile( InputFile, p, WD_InitInp, AWAE_InitInp, SC_Init end if ! NOutDisWindXY - Number of XY planes for output of disturbed wind data across the low-resolution domain to .Low.DisXY..t.vtk (-) [0 to 9]: - CALL ReadVar( UnIn, InputFile, AWAE_InitInp%NOutDisWindXY, "NOutDisWindXY", "Number of XY planes for output of disturbed wind data across the low-resolution domain to .Low.DisXY..t.vtk (-) [0 to 99]", ErrStat2, ErrMsg2, UnEc) + CALL ReadVar( UnIn, InputFile, AWAE_InitInp%NOutDisWindXY, "NOutDisWindXY", "Number of XY planes for output of disturbed wind data across the low-resolution domain to .Low.DisXY..t.vtk (-) [0 to 999]", ErrStat2, ErrMsg2, UnEc) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) if ( ErrStat >= AbortErrLev ) then call cleanup() @@ -1163,7 +1163,7 @@ SUBROUTINE Farm_ReadPrimaryFile( InputFile, p, WD_InitInp, AWAE_InitInp, SC_Init end if ! NOutDisWindYZ - Number of YZ planes for output of disturbed wind data across the low-resolution domain to .Low.DisYZ..t.vtk (-) [0 to 9]: - CALL ReadVar( UnIn, InputFile, AWAE_InitInp%NOutDisWindYZ, "NOutDisWindYZ", "Number of YZ planes for output of disturbed wind data across the low-resolution domain to .Low.DisYZ..t.vtk (-) [0 to 99]", ErrStat2, ErrMsg2, UnEc) + CALL ReadVar( UnIn, InputFile, AWAE_InitInp%NOutDisWindYZ, "NOutDisWindYZ", "Number of YZ planes for output of disturbed wind data across the low-resolution domain to .Low.DisYZ..t.vtk (-) [0 to 999]", ErrStat2, ErrMsg2, UnEc) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) if ( ErrStat >= AbortErrLev ) then call cleanup() @@ -1186,7 +1186,7 @@ SUBROUTINE Farm_ReadPrimaryFile( InputFile, p, WD_InitInp, AWAE_InitInp, SC_Init end if ! NOutDisWindXZ - Number of XZ planes for output of disturbed wind data across the low-resolution domain to .Low/DisXZ..t.vtk (-) [0 to 9]: - CALL ReadVar( UnIn, InputFile, AWAE_InitInp%NOutDisWindXZ, "NOutDisWindXZ", "Number of XZ planes for output of disturbed wind data across the low-resolution domain to .Low/DisXZ..t.vtk (-) [0 to 99]", ErrStat2, ErrMsg2, UnEc) + CALL ReadVar( UnIn, InputFile, AWAE_InitInp%NOutDisWindXZ, "NOutDisWindXZ", "Number of XZ planes for output of disturbed wind data across the low-resolution domain to .Low/DisXZ..t.vtk (-) [0 to 999]", ErrStat2, ErrMsg2, UnEc) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) if ( ErrStat >= AbortErrLev ) then call cleanup() @@ -1546,9 +1546,9 @@ SUBROUTINE Farm_ValidateInput( p, WD_InitInp, AWAE_InitInp, SC_InitInp, ErrStat, AWAE_InitInp%WrDisDT = p%DT_low * n_disDT_dt - if (AWAE_InitInp%NOutDisWindXY < 0 .or. AWAE_InitInp%NOutDisWindXY > maxOutputPlanes ) CALL SetErrStat( ErrID_Fatal, 'NOutDisWindXY must be in the range [0, 99].', ErrStat, ErrMsg, RoutineName ) - if (AWAE_InitInp%NOutDisWindYZ < 0 .or. AWAE_InitInp%NOutDisWindYZ > maxOutputPlanes ) CALL SetErrStat( ErrID_Fatal, 'NOutDisWindYZ must be in the range [0, 99].', ErrStat, ErrMsg, RoutineName ) - if (AWAE_InitInp%NOutDisWindXZ < 0 .or. AWAE_InitInp%NOutDisWindXZ > maxOutputPlanes ) CALL SetErrStat( ErrID_Fatal, 'NOutDisWindXZ must be in the range [0, 99].', ErrStat, ErrMsg, RoutineName ) + if (AWAE_InitInp%NOutDisWindXY < 0 .or. AWAE_InitInp%NOutDisWindXY > maxOutputPlanes ) CALL SetErrStat( ErrID_Fatal, 'NOutDisWindXY must be in the range [0, 999].', ErrStat, ErrMsg, RoutineName ) + if (AWAE_InitInp%NOutDisWindYZ < 0 .or. AWAE_InitInp%NOutDisWindYZ > maxOutputPlanes ) CALL SetErrStat( ErrID_Fatal, 'NOutDisWindYZ must be in the range [0, 999].', ErrStat, ErrMsg, RoutineName ) + if (AWAE_InitInp%NOutDisWindXZ < 0 .or. AWAE_InitInp%NOutDisWindXZ > maxOutputPlanes ) CALL SetErrStat( ErrID_Fatal, 'NOutDisWindXZ must be in the range [0, 999].', ErrStat, ErrMsg, RoutineName ) if (p%NOutDist < 0 .or. p%NOutDist > maxOutputPoints ) then CALL SetErrStat( ErrID_Fatal, 'NOutDist must be in the range [0, 9].', ErrStat, ErrMsg, RoutineName ) else diff --git a/modules/awae/src/AWAE.f90 b/modules/awae/src/AWAE.f90 index 86c882e23..29fc54311 100644 --- a/modules/awae/src/AWAE.f90 +++ b/modules/awae/src/AWAE.f90 @@ -1613,7 +1613,7 @@ subroutine AWAE_CalcOutput( t, u, p, x, xd, z, OtherState, y, m, errStat, errMsg character(ErrMsgLen) :: errMsg2 character(*), parameter :: RoutineName = 'AWAE_CalcOutput' integer(intKi) :: n, n_high - character(2) :: PlaneNumStr ! 2 digit number of the output plane + character(3) :: PlaneNumStr ! 2 digit number of the output plane CHARACTER(1024) :: FileName INTEGER(IntKi) :: Un ! unit number of opened file @@ -1651,7 +1651,7 @@ subroutine AWAE_CalcOutput( t, u, p, x, xd, z, OtherState, y, m, errStat, errMsg ! XY plane slices do k = 1,p%NOutDisWindXY - write(PlaneNumStr, '(i2.2)') k + write(PlaneNumStr, '(i3.3)') k call ExtractSlice( XYSlice, p%OutDisWindZ(k), p%Z0_low, p%nZ_low, p%nX_low, p%nY_low, p%dZ_low, m%Vdist_low_full, m%outVizXYPlane(:,:,:,1)) ! Create the output vtk file with naming /Low/DisXY.t.vtk FileName = trim(p%OutFileVTKRoot)//".Low.DisXY"//PlaneNumStr//"."//trim(Tstr)//".vtk" @@ -1665,7 +1665,7 @@ subroutine AWAE_CalcOutput( t, u, p, x, xd, z, OtherState, y, m, errStat, errMsg ! YZ plane slices do k = 1,p%NOutDisWindYZ - write(PlaneNumStr, '(i2.2)') k + write(PlaneNumStr, '(i3.3)') k call ExtractSlice( YZSlice, p%OutDisWindX(k), p%X0_low, p%nX_low, p%nY_low, p%nZ_low, p%dX_low, m%Vdist_low_full, m%outVizYZPlane(:,:,:,1)) ! Create the output vtk file with naming /Low/DisYZ.t.vtk FileName = trim(p%OutFileVTKRoot)//".Low.DisYZ"//PlaneNumStr//"."//trim(Tstr)//".vtk" @@ -1679,7 +1679,7 @@ subroutine AWAE_CalcOutput( t, u, p, x, xd, z, OtherState, y, m, errStat, errMsg ! XZ plane slices do k = 1,p%NOutDisWindXZ - write(PlaneNumStr, '(i2.2)') k + write(PlaneNumStr, '(i3.3)') k call ExtractSlice( XZSlice, p%OutDisWindY(k), p%Y0_low, p%nY_low, p%nX_low, p%nZ_low, p%dY_low, m%Vdist_low_full, m%outVizXZPlane(:,:,:,1)) ! Create the output vtk file with naming /Low/DisXZ.t.vtk FileName = trim(p%OutFileVTKRoot)//".Low.DisXZ"//PlaneNumStr//"."//trim(Tstr)//".vtk" From 17ac3c7658bcfcfb71ba3d07ea3b68cc808a8e20 Mon Sep 17 00:00:00 2001 From: Andy Platt Date: Tue, 26 Nov 2024 08:57:24 -0700 Subject: [PATCH 072/161] AWAE: update comment Co-authored-by: Derek Slaughter --- modules/awae/src/AWAE.f90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/awae/src/AWAE.f90 b/modules/awae/src/AWAE.f90 index 29fc54311..5a19a7315 100644 --- a/modules/awae/src/AWAE.f90 +++ b/modules/awae/src/AWAE.f90 @@ -1613,7 +1613,7 @@ subroutine AWAE_CalcOutput( t, u, p, x, xd, z, OtherState, y, m, errStat, errMsg character(ErrMsgLen) :: errMsg2 character(*), parameter :: RoutineName = 'AWAE_CalcOutput' integer(intKi) :: n, n_high - character(3) :: PlaneNumStr ! 2 digit number of the output plane + character(3) :: PlaneNumStr ! 3 digit number of the output plane CHARACTER(1024) :: FileName INTEGER(IntKi) :: Un ! unit number of opened file From ada86f4b8d5c106a73ec5771408f73270ca4be63 Mon Sep 17 00:00:00 2001 From: Derek Slaughter Date: Tue, 26 Nov 2024 16:11:22 +0000 Subject: [PATCH 073/161] Add BUILD_OPENFAST_CFD_DRIVER to build C++ driver for CFD interface (AMR-Wind/Nalu-Wind) --- .github/workflows/automated-dev-tests.yml | 1 + CMakeLists.txt | 1 + glue-codes/openfast-cpp/CMakeLists.txt | 2 +- reg_tests/CTestList.cmake | 2 +- 4 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/automated-dev-tests.yml b/.github/workflows/automated-dev-tests.yml index 7ca5d3dff..1b370ab80 100644 --- a/.github/workflows/automated-dev-tests.yml +++ b/.github/workflows/automated-dev-tests.yml @@ -199,6 +199,7 @@ jobs: -DBUILD_FASTFARM:BOOL=ON \ -DBUILD_OPENFAST_CPP_API:BOOL=ON \ -DBUILD_OPENFAST_CPP_DRIVER:BOOL=ON \ + -DBUILD_OPENFAST_CFD_DRIVER:BOOL=ON \ -DBUILD_SHARED_LIBS:BOOL=OFF \ -DBUILD_TESTING:BOOL=ON \ -DCTEST_PLOT_ERRORS:BOOL=ON \ diff --git a/CMakeLists.txt b/CMakeLists.txt index 329915326..88cdeb08e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -45,6 +45,7 @@ option(ORCA_DLL_LOAD "Enable OrcaFlex Library Load" on) option(BUILD_FASTFARM "Enable building FAST.Farm" off) option(BUILD_OPENFAST_CPP_API "Enable building OpenFAST - C++ API" off) option(BUILD_OPENFAST_CPP_DRIVER "Enable building OpenFAST C++ driver using C++ API" off) +option(BUILD_OPENFAST_CFD_DRIVER "Enable building OpenFAST CFD driver using C++ CFD API" off) option(BUILD_OPENFAST_SIMULINK_API "Enable building OpenFAST for use with Simulink" off) option(OPENMP "Enable OpenMP support" off) option(USE_LOCAL_STATIC_LAPACK "Enable downloading and building static LAPACK and BLAS libs" off) diff --git a/glue-codes/openfast-cpp/CMakeLists.txt b/glue-codes/openfast-cpp/CMakeLists.txt index 6405e48cc..f85f91e1e 100644 --- a/glue-codes/openfast-cpp/CMakeLists.txt +++ b/glue-codes/openfast-cpp/CMakeLists.txt @@ -56,7 +56,7 @@ install(TARGETS openfastcpplib ) # Build driver if requested -if (BUILD_OPENFAST_CPP_DRIVER) +if (BUILD_OPENFAST_CFD_DRIVER) find_package(yaml-cpp REQUIRED) add_executable(openfastcpp src/FAST_Prog.cpp) diff --git a/reg_tests/CTestList.cmake b/reg_tests/CTestList.cmake index 360133f86..b9c6dbf88 100644 --- a/reg_tests/CTestList.cmake +++ b/reg_tests/CTestList.cmake @@ -285,7 +285,7 @@ of_regression("MHK_RM1_Floating" "openfast;elastodyn;aerod of_regression("Tailfin_FreeYaw1DOF_PolarBased" "openfast;elastodyn;aerodyn15") # OpenFAST C++ API test -if(BUILD_OPENFAST_CPP_API) +if(BUILD_OPENFAST_CFD_DRIVER) of_cpp_interface_regression("5MW_Land_DLL_WTurb_cpp" "openfast;fastlib;cpp") endif() From dbfff8cddec3f797a2205997c4a746b486aa33f0 Mon Sep 17 00:00:00 2001 From: Derek Slaughter Date: Tue, 26 Nov 2024 17:03:07 +0000 Subject: [PATCH 074/161] Use CPP driver for CFD and LIB for the openfastlib C++ interface --- .github/workflows/automated-dev-tests.yml | 2 +- glue-codes/openfast-cpp/CMakeLists.txt | 2 +- glue-codes/openfast/CMakeLists.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/automated-dev-tests.yml b/.github/workflows/automated-dev-tests.yml index 1b370ab80..92402268b 100644 --- a/.github/workflows/automated-dev-tests.yml +++ b/.github/workflows/automated-dev-tests.yml @@ -198,8 +198,8 @@ jobs: -DVARIABLE_TRACKING=OFF \ -DBUILD_FASTFARM:BOOL=ON \ -DBUILD_OPENFAST_CPP_API:BOOL=ON \ + -DBUILD_OPENFAST_LIB_DRIVER:BOOL=ON \ -DBUILD_OPENFAST_CPP_DRIVER:BOOL=ON \ - -DBUILD_OPENFAST_CFD_DRIVER:BOOL=ON \ -DBUILD_SHARED_LIBS:BOOL=OFF \ -DBUILD_TESTING:BOOL=ON \ -DCTEST_PLOT_ERRORS:BOOL=ON \ diff --git a/glue-codes/openfast-cpp/CMakeLists.txt b/glue-codes/openfast-cpp/CMakeLists.txt index f85f91e1e..6405e48cc 100644 --- a/glue-codes/openfast-cpp/CMakeLists.txt +++ b/glue-codes/openfast-cpp/CMakeLists.txt @@ -56,7 +56,7 @@ install(TARGETS openfastcpplib ) # Build driver if requested -if (BUILD_OPENFAST_CFD_DRIVER) +if (BUILD_OPENFAST_CPP_DRIVER) find_package(yaml-cpp REQUIRED) add_executable(openfastcpp src/FAST_Prog.cpp) diff --git a/glue-codes/openfast/CMakeLists.txt b/glue-codes/openfast/CMakeLists.txt index bc2e13233..402a790f6 100644 --- a/glue-codes/openfast/CMakeLists.txt +++ b/glue-codes/openfast/CMakeLists.txt @@ -33,7 +33,7 @@ endif() install(TARGETS openfast RUNTIME DESTINATION bin) -if(BUILD_OPENFAST_CPP_DRIVER) +if(BUILD_OPENFAST_LIB_DRIVER) add_executable(openfast_cpp_driver src/FAST_Prog.cpp src/FastLibAPI.cpp) target_link_libraries(openfast_cpp_driver openfastlib) From 9df336380a139f1359622ec4f3a761b3a320c503 Mon Sep 17 00:00:00 2001 From: Derek Slaughter Date: Tue, 26 Nov 2024 17:31:28 +0000 Subject: [PATCH 075/161] Missed an instance of BUILD_OPENFAST_LIB_DRIVER --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 88cdeb08e..0bd22f12a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -44,8 +44,8 @@ option(FPE_TRAP_ENABLED "Enable FPE trap in compiler options" off) option(ORCA_DLL_LOAD "Enable OrcaFlex Library Load" on) option(BUILD_FASTFARM "Enable building FAST.Farm" off) option(BUILD_OPENFAST_CPP_API "Enable building OpenFAST - C++ API" off) -option(BUILD_OPENFAST_CPP_DRIVER "Enable building OpenFAST C++ driver using C++ API" off) -option(BUILD_OPENFAST_CFD_DRIVER "Enable building OpenFAST CFD driver using C++ CFD API" off) +option(BUILD_OPENFAST_CPP_DRIVER "Enable building OpenFAST C++ driver using C++ CFD API" off) +option(BUILD_OPENFAST_LIB_DRIVER "Enable building OpenFAST driver using C++ Library API" off) option(BUILD_OPENFAST_SIMULINK_API "Enable building OpenFAST for use with Simulink" off) option(OPENMP "Enable OpenMP support" off) option(USE_LOCAL_STATIC_LAPACK "Enable downloading and building static LAPACK and BLAS libs" off) From 4943c199f30ccc00fe8ee610620951d606236188 Mon Sep 17 00:00:00 2001 From: andrew-platt Date: Wed, 27 Nov 2024 16:24:22 -0700 Subject: [PATCH 076/161] Update r-test pointer --- reg_tests/r-test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reg_tests/r-test b/reg_tests/r-test index a820ba376..d9691df03 160000 --- a/reg_tests/r-test +++ b/reg_tests/r-test @@ -1 +1 @@ -Subproject commit a820ba376e4f38413e01cacf461eaf5eb3c21154 +Subproject commit d9691df0339bbc718c63e1de8a1aaa642e978398 From 61549fcc2d9d638d74df6fa7eb304841a1447478 Mon Sep 17 00:00:00 2001 From: andrew-platt Date: Tue, 10 Dec 2024 14:38:32 -0700 Subject: [PATCH 077/161] Add `!$OMP critical` directives around some GetNewUnit/Open*File calls --- modules/aerodyn/src/AeroDyn_IO.f90 | 4 ++ modules/aerodyn/src/UnsteadyAero.f90 | 16 ++++--- modules/awae/src/AWAE_IO.f90 | 2 + modules/beamdyn/src/BeamDyn_IO.f90 | 6 +++ modules/elastodyn/src/ElastoDyn.f90 | 8 ++-- modules/elastodyn/src/ElastoDyn_IO.f90 | 39 +++++++-------- modules/hydrodyn/src/HydroDyn_Output.f90 | 8 ++++ modules/hydrodyn/src/Morison_Output.f90 | 2 + modules/hydrodyn/src/WAMIT2.f90 | 37 +++++---------- modules/inflowwind/src/InflowWind_IO.f90 | 34 +++++++------ modules/inflowwind/src/InflowWind_Subs.f90 | 2 + modules/nwtc-library/src/NWTC_IO.f90 | 8 ++++ modules/nwtc-library/src/VTK.f90 | 12 +++-- modules/openfast-library/src/FAST_Solver.f90 | 10 ++++ modules/openfast-library/src/FAST_Subs.f90 | 50 +++++++++++++------- modules/servodyn/src/ServoDyn_IO.f90 | 2 + modules/subdyn/src/SubDyn.f90 | 5 ++ 17 files changed, 155 insertions(+), 90 deletions(-) diff --git a/modules/aerodyn/src/AeroDyn_IO.f90 b/modules/aerodyn/src/AeroDyn_IO.f90 index 24e56b0ab..532fc55d2 100644 --- a/modules/aerodyn/src/AeroDyn_IO.f90 +++ b/modules/aerodyn/src/AeroDyn_IO.f90 @@ -1080,6 +1080,7 @@ SUBROUTINE ReadBladeInputs ( ADBlFile, BladeKInputFileData, AeroProjMod, UnEc, E ErrMsg = "" UnIn = -1 + !$OMP critical(filename) CALL GetNewUnit( UnIn, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) @@ -1087,6 +1088,7 @@ SUBROUTINE ReadBladeInputs ( ADBlFile, BladeKInputFileData, AeroProjMod, UnEc, E ! Open the input file for blade K. CALL OpenFInpFile ( UnIn, ADBlFile, ErrStat2, ErrMsg2 ) + !$OMP end critical(filename) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF ( ErrStat >= AbortErrLev ) RETURN @@ -1324,8 +1326,10 @@ SUBROUTINE AD_PrintSum( InputFileData, p, p_AD, u, y, ErrStat, ErrMsg ) ! Open the summary file and give it a heading. + !$OMP critical(filename) CALL GetNewUnit( UnSu, ErrStat, ErrMsg ) CALL OpenFOutFile ( UnSu, TRIM( p%RootName )//'.sum', ErrStat, ErrMsg ) + !$OMP end critical(filename) IF ( ErrStat >= AbortErrLev ) RETURN ! Heading: diff --git a/modules/aerodyn/src/UnsteadyAero.f90 b/modules/aerodyn/src/UnsteadyAero.f90 index 84f0addf1..a6686580f 100644 --- a/modules/aerodyn/src/UnsteadyAero.f90 +++ b/modules/aerodyn/src/UnsteadyAero.f90 @@ -1328,10 +1328,12 @@ subroutine UA_Init( InitInp, u, p, x, xd, OtherState, y, m, Interval, & p%Delim ='' if (p%NumOuts > 0) then + !$OMP critical(filename) CALL GetNewUnit( p%unOutFile, ErrStat2, ErrMsg2 ) - call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - if (ErrStat >= AbortErrLev) return - CALL OpenFOutFile ( p%unOutFile, trim(InitInp%OutRootName)//'.UA.out', ErrStat2, ErrMsg2 ) + if (ErrStat2 < AbortErrLev) then + CALL OpenFOutFile ( p%unOutFile, trim(InitInp%OutRootName)//'.UA.out', ErrStat2, ErrMsg2 ) + endif + !$OMP end critical(filename) call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) if (ErrStat >= AbortErrLev) return @@ -3685,10 +3687,12 @@ subroutine UA_WriteAFIParamsToFile(InitInp, AFInfo, ErrStat, ErrMsg) ChanName(i) = 'c_Rate'; ChanUnit(i) = '(-/rad)'; i = i+1; ChanName(i) = 'c_RateUpper'; ChanUnit(i) = '(-/rad)'; i = i+1; + !$OMP critical(filename) CALL GetNewUnit( unOutFile, ErrStat, ErrMsg ) - IF ( ErrStat /= ErrID_None ) RETURN - - CALL OpenFOutFile ( unOutFile, trim(InitInp%OutRootName)//'.UA.sum', ErrStat2, ErrMsg2 ) + if (ErrStat < AbortErrLev) then + CALL OpenFOutFile ( unOutFile, trim(InitInp%OutRootName)//'.UA.sum', ErrStat2, ErrMsg2 ) + endif + !$OMP end critical(filename) call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) if (ErrStat >= AbortErrLev) return diff --git a/modules/awae/src/AWAE_IO.f90 b/modules/awae/src/AWAE_IO.f90 index 5d89f4097..a4b2720cf 100644 --- a/modules/awae/src/AWAE_IO.f90 +++ b/modules/awae/src/AWAE_IO.f90 @@ -548,8 +548,10 @@ SUBROUTINE AWAE_PrintSum( p, u, y, ErrStat, ErrMsg ) ! Open the summary file and give it a heading. + !$OMP critical(fileopen) CALL GetNewUnit( UnSu, ErrStat, ErrMsg ) CALL OpenFOutFile ( UnSu, TRIM( p%OutFileRoot )//'.sum', ErrStat, ErrMsg ) + !$OMP end critical(fileopen) IF ( ErrStat >= AbortErrLev ) RETURN diff --git a/modules/beamdyn/src/BeamDyn_IO.f90 b/modules/beamdyn/src/BeamDyn_IO.f90 index 15ed92d7d..d50d33312 100644 --- a/modules/beamdyn/src/BeamDyn_IO.f90 +++ b/modules/beamdyn/src/BeamDyn_IO.f90 @@ -588,9 +588,11 @@ SUBROUTINE BD_ReadPrimaryFile(InputFile,InputFileData,OutFileRoot,UnEc,ErrStat,E CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + !$OMP critical(filename) CALL GetNewUnit(UnIn,ErrStat2,ErrMsg2) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) CALL OpenFInpFile(UnIn,InputFile,ErrStat2,ErrMsg2) + !$OMP end critical(filename) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) IF (ErrStat >= AbortErrLev) then call cleanup() @@ -1048,9 +1050,11 @@ SUBROUTINE BD_ReadBladeFile(BldFile,BladeInputFileData,UnEc,ErrStat,ErrMsg) ErrStat = ErrID_None ErrMsg = "" + !$OMP critical(filename) CALL GetNewUnit(UnIn,ErrStat2,ErrMsg2) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) CALL OpenFInpFile (UnIn,BldFile,ErrStat2,ErrMsg2) + !$OMP end critical(filename) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) if (ErrStat >= AbortErrLev) then return @@ -1940,8 +1944,10 @@ SUBROUTINE BD_PrintSum( p, x, OtherState, m, InitInp, ErrStat, ErrMsg ) ! Open the summary file and give it a heading. + !$OMP critical(filename) CALL GetNewUnit( UnSu, ErrStat, ErrMsg ) CALL OpenFOutFile ( UnSu, TRIM( InitInp%RootName )//'.sum.yaml', ErrStat, ErrMsg ) + !$OMP end critical(filename) IF ( ErrStat >= AbortErrLev ) RETURN ! Heading: diff --git a/modules/elastodyn/src/ElastoDyn.f90 b/modules/elastodyn/src/ElastoDyn.f90 index 28db59d3d..061dbb3c1 100644 --- a/modules/elastodyn/src/ElastoDyn.f90 +++ b/modules/elastodyn/src/ElastoDyn.f90 @@ -9634,10 +9634,12 @@ SUBROUTINE ED_PrintSum( p, OtherState, ErrStat, ErrMsg ) ! Open the summary file and give it a heading. + !$OMP critical(filename) CALL GetNewUnit( UnSu, ErrStat, ErrMsg ) - IF ( ErrStat /= ErrID_None ) RETURN - - CALL OpenFOutFile ( UnSu, TRIM( p%RootName )//'.sum', ErrStat, ErrMsg ) + if (ErrStat < AbortErrLev) then + CALL OpenFOutFile ( UnSu, TRIM( p%RootName )//'.sum', ErrStat, ErrMsg ) + endif + !$OMP end critical(filename) IF ( ErrStat /= ErrID_None ) RETURN diff --git a/modules/elastodyn/src/ElastoDyn_IO.f90 b/modules/elastodyn/src/ElastoDyn_IO.f90 index 698c57fe1..6e793c5c0 100644 --- a/modules/elastodyn/src/ElastoDyn_IO.f90 +++ b/modules/elastodyn/src/ElastoDyn_IO.f90 @@ -1582,12 +1582,13 @@ SUBROUTINE ReadBladeFile ( BldFile, BladeKInputFileData, UnEc, ErrStat, ErrMsg ) ErrMsg = "" UnIn = -1 + !$OMP critical(filename) CALL GetNewUnit( UnIn, ErrStat2, ErrMsg2 ) - - + IF (ErrStat2 < AbortErrLev) THEN ! Open the input file for blade K. - - CALL OpenFInpFile ( UnIn, BldFile, ErrStat2, ErrMsg2 ) + CALL OpenFInpFile ( UnIn, BldFile, ErrStat2, ErrMsg2 ) + ENDIF + !$OMP end critical(filename) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) IF ( ErrStat >= AbortErrLev ) THEN CALL Cleanup() @@ -1888,13 +1889,13 @@ SUBROUTINE ReadBladeMeshFileAD( BladeKInputFileMesh, MeshFile, UnEc, ErrStat, Er ! Get an available unit number for the file. + !$OMP critical(filename) CALL GetNewUnit( UnIn, ErrStat, ErrMsg ) - IF ( ErrStat >= AbortErrLev ) RETURN - - + IF ( ErrStat < AbortErrLev ) THEN ! Open the AeroDyn input file. - - CALL OpenFInpFile ( UnIn, MeshFile, ErrStat2, ErrMsg2 ) + CALL OpenFInpFile ( UnIn, MeshFile, ErrStat2, ErrMsg2 ) + ENDIF + !$OMP end critical(filename) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) IF ( ErrStat >= AbortErrLev ) THEN CALL Cleanup() @@ -2179,12 +2180,13 @@ SUBROUTINE ReadTowerFile( TwrFile, InputFileData, UnEc, ErrStat, ErrMsg ) ErrMsg = "" + !$OMP critical(filename) CALL GetNewUnit( UnIn, ErrStat, ErrMsg ) - IF ( ErrStat >= AbortErrLev ) RETURN - + IF ( ErrStat < AbortErrLev ) THEN ! Open the tower input file. - - CALL OpenFInpFile ( UnIn, TwrFile, ErrStat2, ErrMsg2 ) + CALL OpenFInpFile ( UnIn, TwrFile, ErrStat2, ErrMsg2 ) + ENDIF + !$OMP end critical(filename) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) IF ( ErrStat >= AbortErrLev ) THEN CALL Cleanup() @@ -2521,14 +2523,13 @@ SUBROUTINE ReadPrimaryFile( InputFile, InputFileData, BldFile, FurlFile, TwrFile ! Get an available unit number for the file. - + !$OMP critical(filename) CALL GetNewUnit( UnIn, ErrStat, ErrMsg ) - IF ( ErrStat >= AbortErrLev ) RETURN - - + IF ( ErrStat < AbortErrLev ) THEN ! Open the Primary input file. - - CALL OpenFInpFile ( UnIn, InputFile, ErrStat2, ErrMsg2 ) + CALL OpenFInpFile ( UnIn, InputFile, ErrStat2, ErrMsg2 ) + ENDIF + !$OMP end critical(filename) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) IF ( ErrStat >= AbortErrLev ) THEN CALL Cleanup() diff --git a/modules/hydrodyn/src/HydroDyn_Output.f90 b/modules/hydrodyn/src/HydroDyn_Output.f90 index a48f6429e..39addf340 100644 --- a/modules/hydrodyn/src/HydroDyn_Output.f90 +++ b/modules/hydrodyn/src/HydroDyn_Output.f90 @@ -979,9 +979,11 @@ SUBROUTINE HDOut_OpenSum( UnSum, SummaryName, HD_Prog, ErrStat, ErrMsg ) ErrMsg = "" + !$OMP critical(fileopen) CALL GetNewUnit( UnSum ) CALL OpenFOutFile ( UnSum, SummaryName, ErrStat, ErrMsg ) + !$OMP end critical(fileopen) IF (ErrStat >=AbortErrLev) RETURN @@ -1033,10 +1035,12 @@ SUBROUTINE HDOut_WriteWvKinFiles( Rootname, HD_Prog, NStepWave, NNodes, NWaveEle DO iFile = 1,7 + !$OMP critical(fileopen) CALL GetNewUnit( UnWv ) WvName = Rootname // TRIM(extension(iFile)) CALL OpenFOutFile ( UnWv, WvName, ErrStat, ErrMsg ) + !$OMP end critical(fileopen) IF (ErrStat >=AbortErrLev) RETURN @@ -1084,10 +1088,12 @@ SUBROUTINE HDOut_WriteWvKinFiles( Rootname, HD_Prog, NStepWave, NNodes, NWaveEle IF ( NWaveElev > 0 ) THEN + !$OMP critical(fileopen) CALL GetNewUnit( UnWv ) WvName = Rootname // '.Elev' CALL OpenFOutFile ( UnWv, WvName, ErrStat, ErrMsg ) + !$OMP end critical(fileopen) IF (ErrStat >=AbortErrLev) RETURN @@ -1463,9 +1469,11 @@ SUBROUTINE HDOut_OpenOutput( HydroDyn_ProgDesc, OutRootName, p, InitOut, ErrSta ! Open the file for output OutFileName = TRIM(OutRootName)//'.HD.out' + !$OMP critical(fileopen) CALL GetNewUnit( p%UnOutFile ) CALL OpenFOutFile ( p%UnOutFile, OutFileName, ErrStat, ErrMsg ) + !$OMP end critical(fileopen) IF (ErrStat >=AbortErrLev) RETURN diff --git a/modules/hydrodyn/src/Morison_Output.f90 b/modules/hydrodyn/src/Morison_Output.f90 index 4ec1db451..d98a4565d 100644 --- a/modules/hydrodyn/src/Morison_Output.f90 +++ b/modules/hydrodyn/src/Morison_Output.f90 @@ -6610,9 +6610,11 @@ SUBROUTINE MrsnOut_OpenOutput( ProgName, OutRootName, p, InitOut, ErrStat, ErrM ! Open the file for output OutFileName = TRIM(OutRootName)//'.MRSN.out' + !$OMP critical(fileopen) CALL GetNewUnit( p%UnOutFile ) CALL OpenFOutFile ( p%UnOutFile, OutFileName, ErrStat, ErrMsg ) + !$OMP end critical(fileopen) IF (ErrStat >=AbortErrLev) RETURN diff --git a/modules/hydrodyn/src/WAMIT2.f90 b/modules/hydrodyn/src/WAMIT2.f90 index 47653312a..8cfe1026b 100644 --- a/modules/hydrodyn/src/WAMIT2.f90 +++ b/modules/hydrodyn/src/WAMIT2.f90 @@ -3649,20 +3649,13 @@ SUBROUTINE Read_DataFile3D( InitInp, Filename3D, Data3D, ErrStat, Errmsg ) !------------------------------------------------------------------------------ ! Find a unit number to use + !$OMP critical(fileopen) CALL GetNewUnit(UnitDataFile,ErrStatTmp,ErrMsgTmp) - CALL SetErrStat( ErrStatTmp, ErrMsgTmp, ErrStat, ErrMsg, RoutineName) - IF ( ErrStat >= AbortErrLev ) THEN - IF (ALLOCATED(TmpRealArr)) DEALLOCATE(TmpRealArr,STAT=ErrStatTmp) - IF (ALLOCATED(RawData3D)) DEALLOCATE(RawData3D,STAT=ErrStatTmp) - IF (ALLOCATED(RawData3DTmp)) DEALLOCATE(RawData3DTmp,STAT=ErrStatTmp) - IF (ALLOCATED(TmpDataRow)) DEALLOCATE(TmpDataRow,STAT=ErrStatTmp) - IF (ALLOCATED(TmpWvFreq1)) DEALLOCATE(TmpWvFreq1,STAT=ErrStatTmp) - CALL CleanUp - RETURN - ENDIF - - ! Open the file - CALL OpenFInpFile( UnitDataFile, TRIM(Filename3D), ErrStat, ErrMsg ) ! Open file containing mean drift information + if (ErrStatTmp < AbortErrLev) then + ! Open the file + CALL OpenFInpFile( UnitDataFile, TRIM(Filename3D), ErrStat, ErrMsg ) ! Open file containing mean drift information + endif + !$OMP end critical(fileopen) CALL SetErrStat( ErrStatTmp, ErrMsgTmp, ErrStat, ErrMsg, RoutineName) IF ( ErrStat >= AbortErrLev ) THEN CLOSE( UnitDataFile ) @@ -4423,21 +4416,13 @@ SUBROUTINE Read_DataFile4D( InitInp, Filename4D, Data4D, ErrStat, Errmsg ) !------------------------------------------------------------------------------ ! Find a unit number to use + !$OMP critical(fileopen) CALL GetNewUnit(UnitDataFile,ErrStatTmp,ErrMsgTmp) - CALL SetErrStat( ErrStatTmp, ErrMsgTmp, ErrStat, ErrMsg, RoutineName) - IF ( ErrStat >= AbortErrLev ) THEN - IF (ALLOCATED(RawData4D)) DEALLOCATE(RawData4D,STAT=ErrStatTmp) - IF (ALLOCATED(RawData4DTmp)) DEALLOCATE(RawData4DTmp,STAT=ErrStatTmp) - IF (ALLOCATED(TmpRealArr)) DEALLOCATE(TmpRealArr,STAT=ErrStatTmp) - IF (ALLOCATED(TmpDataRow)) DEALLOCATE(TmpDataRow,STAT=ErrStatTmp) - IF (ALLOCATED(TmpWvFreq1)) DEALLOCATE(TmpWvFreq1,STAT=ErrStatTmp) - IF (ALLOCATED(TmpWvFreq2)) DEALLOCATE(TmpWvFreq2,STAT=ErrStatTmp) - CALL CleanUp - RETURN - ENDIF - + if (ErrStatTmp < AbortErrLev) then ! Open the file - CALL OpenFInpFile( UnitDataFile, TRIM(Filename4D), ErrStat, ErrMsg ) ! Open file containing mean drift information + CALL OpenFInpFile( UnitDataFile, TRIM(Filename4D), ErrStat, ErrMsg ) ! Open file containing mean drift information + endif + !$OMP end critical(fileopen) CALL SetErrStat( ErrStatTmp, ErrMsgTmp, ErrStat, ErrMsg, RoutineName) IF ( ErrStat >= AbortErrLev ) THEN CLOSE( UnitDataFile ) diff --git a/modules/inflowwind/src/InflowWind_IO.f90 b/modules/inflowwind/src/InflowWind_IO.f90 index e1b0f6454..b74a2e514 100644 --- a/modules/inflowwind/src/InflowWind_IO.f90 +++ b/modules/inflowwind/src/InflowWind_IO.f90 @@ -518,12 +518,13 @@ subroutine IfW_TurbSim_Init(InitInp, SumFileUnit, G3D, FileDat, ErrStat, ErrMsg) !---------------------------------------------------------------------------- ! Get a unit number to use for the wind file + !$OMP critical(fileopen) call GetNewUnit(WindFileUnit, TmpErrStat, TmpErrMsg) - call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) - if (ErrStat >= AbortErrLev) return - - ! Open binary file - call OpenBInpFile(WindFileUnit, TRIM(InitInp%WindFileName), TmpErrStat, TmpErrMsg) + if (TmpErrStat < AbortErrLev) then + ! Open binary file + call OpenBInpFile(WindFileUnit, TRIM(InitInp%WindFileName), TmpErrStat, TmpErrMsg) + endif + !$OMP end critical(fileopen) call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) if (ErrStat >= AbortErrLev) return @@ -883,16 +884,17 @@ subroutine IfW_HAWC_Init(InitInp, SumFileUnit, G3D, FileDat, ErrStat, ErrMsg) TRIM(Num2LStr(G3D%GridBase + G3D%ZHWid*2))// & ' m above ground) with a characteristic wind speed of '//TRIM(Num2LStr(G3D%MeanWS))//' m/s. ') - ! Get a unit number to use for the wind file - call GetNewUnit(WindFileUnit, TmpErrStat, TmpErrMsg) - call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) - if (ErrStat >= AbortErrLev) return - ! Loop through wind components (X, Y, Z) do IC = 1, G3D%NComp - ! Open wind file for this component - call OpenBInpFile(WindFileUnit, InitInp%WindFileName(IC), TmpErrStat, TmpErrMsg) + ! Get a unit number to use for the wind file + !$OMP critical(fileopen) + call GetNewUnit(WindFileUnit, TmpErrStat, TmpErrMsg) + if (TmpErrStat < AbortErrLev) then + ! Open wind file for this component + call OpenBInpFile(WindFileUnit, InitInp%WindFileName(IC), TmpErrStat, TmpErrMsg) + endif + !$OMP end critical(fileopen) call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) if (ErrStat >= AbortErrLev) return @@ -1132,16 +1134,18 @@ subroutine IfW_Bladed_Init(InitInp, SumFileUnit, InitOut, G3D, FileDat, ErrStat, end if ! Get a unit number to use + !$OMP critical(fileopen) call GetNewUnit(UnitWind, TmpErrStat, TmpErrMsg) - call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) - if (ErrStat >= AbortErrLev) return + if (TmpErrStat < AbortErrLev) then !---------------------------------------------------------------------------- ! Open the binary file, read its "header" (first 2-byte integer) to ! determine what format binary file it is, and close it. !---------------------------------------------------------------------------- - call OpenBInpFile(UnitWind, TRIM(BinFileName), TmpErrStat, TmpErrMsg) + call OpenBInpFile(UnitWind, TRIM(BinFileName), TmpErrStat, TmpErrMsg) + endif + !$OMP end critical(fileopen) call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) if (ErrStat >= AbortErrLev) return diff --git a/modules/inflowwind/src/InflowWind_Subs.f90 b/modules/inflowwind/src/InflowWind_Subs.f90 index c8349ffbd..e99dae437 100644 --- a/modules/inflowwind/src/InflowWind_Subs.f90 +++ b/modules/inflowwind/src/InflowWind_Subs.f90 @@ -1575,8 +1575,10 @@ SUBROUTINE InflowWind_OpenSumFile( SumFileUnit, SummaryName, IfW_Prog, WindType, ErrMsg = "" SumFileUnit = -1 + !$OMP critical(fileopen) CALL GetNewUnit( SumFileUnit ) CALL OpenFOutFile ( SumFileUnit, SummaryName, ErrStat, ErrMsg ) + !$OMP end critical(fileopen) IF (ErrStat >=AbortErrLev) RETURN diff --git a/modules/nwtc-library/src/NWTC_IO.f90 b/modules/nwtc-library/src/NWTC_IO.f90 index 931aaf76e..656f46840 100644 --- a/modules/nwtc-library/src/NWTC_IO.f90 +++ b/modules/nwtc-library/src/NWTC_IO.f90 @@ -2409,6 +2409,7 @@ SUBROUTINE OpenEcho ( Un, OutFile, ErrStat, ErrMsg, ProgVer ) ! Get a unit number for the echo file: + !$OMP critical(fileopenNWTCio) IF ( Un < 0 ) THEN CALL GetNewUnit( Un, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2,ErrStat, ErrMsg, RoutineName ) @@ -2419,6 +2420,7 @@ SUBROUTINE OpenEcho ( Un, OutFile, ErrStat, ErrMsg, ProgVer ) CALL OpenFOutFile( Un, OutFile, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2,ErrStat, ErrMsg, RoutineName ) + !$OMP end critical(fileopenNWTCio) IF ( ErrStat >= AbortErrLev ) RETURN @@ -4615,11 +4617,13 @@ RECURSIVE SUBROUTINE ReadComFile ( FileInfo, FileIndx, AryInd, StartLine, LastLi RETURN END IF + !$OMP critical(fileopenNWTCio) CALL GetNewUnit ( UnIn, ErrStatLcl, ErrMsg2 ) CALL SetErrStat( ErrStatLcl, ErrMsg2, ErrStat, ErrMsg, RoutineName ) CALL OpenFInpFile ( UnIn, FileInfo%FileList(FileIndx), ErrStatLcl, ErrMsg2 ) CALL SetErrStat( ErrStatLcl, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + !$OMP end critical(fileopenNWTCio) IF ( ErrStat >= AbortErrLev ) RETURN @@ -6410,9 +6414,11 @@ RECURSIVE SUBROUTINE ScanComFile ( FirstFile, ThisFile, LastFile, StartLine, Las ! Open the input file. UnIn = -1 + !$OMP critical(fileopenNWTCio) CALL GetNewUnit ( UnIn, ErrStatLcl, ErrMsg2 ) CALL OpenFInpFile ( UnIn, Filename, ErrStatLcl, ErrMsg2 ) + !$OMP end critical(fileopenNWTCio) IF ( ErrStatLcl /= 0 ) THEN CALL SetErrStat( ErrStatLcl, ErrMsg2, ErrStat, ErrMsg, RoutineName ) CALL Cleanup() @@ -6720,6 +6726,7 @@ SUBROUTINE WrBinFAST(FileName, FileID, DescStr, ChanName, ChanUnit, TimeData, Al ! Generate the unit number for the binary file UnIn = 0 + !$OMP critical(fileopenNWTCio) CALL GetNewUnit( UnIn, ErrStat2, ErrMsg2 ) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) @@ -6729,6 +6736,7 @@ SUBROUTINE WrBinFAST(FileName, FileID, DescStr, ChanName, ChanUnit, TimeData, Al CALL OpenBOutFile ( UnIn, TRIM(FileName), ErrStat2, ErrMsg2 ) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + !$OMP end critical(fileopenNWTCio) IF ( ErrStat >= AbortErrLev ) THEN CALL Cleanup() RETURN diff --git a/modules/nwtc-library/src/VTK.f90 b/modules/nwtc-library/src/VTK.f90 index fb57a5781..0083582ca 100644 --- a/modules/nwtc-library/src/VTK.f90 +++ b/modules/nwtc-library/src/VTK.f90 @@ -94,8 +94,10 @@ SUBROUTINE WrVTK_header( FileName, NumberOfPoints, NumberOfLines, NumberOfPolys, INTEGER(IntKi) , INTENT( OUT) :: ErrStat !< error level/status of OpenFOutFile operation CHARACTER(*) , INTENT( OUT) :: ErrMsg !< message when error occurs + !$OMP critical(fileopen) CALL GetNewUnit( Un, ErrStat, ErrMsg ) CALL OpenFOutFile ( Un, TRIM(FileName), ErrStat, ErrMsg ) + !$OMP end critical(fileopen) if (ErrStat >= AbortErrLev) return ! Write a VTP mesh file (Polygonal VTK file) with positions and polygons (surfaces) @@ -158,10 +160,10 @@ SUBROUTINE ReadVTK_SP_info( FileName, descr, dims, origin, gridSpacing, vecLabel closeOnReturn = .FALSE. END IF - !$OMP critical + !$OMP critical(fileopen) CALL GetNewUnit( Un, ErrStat, ErrMsg ) CALL OpenFInpFile ( Un, TRIM(FileName), ErrStat, ErrMsg ) - !$OMP end critical + !$OMP end critical(fileopen) if (ErrStat >= AbortErrLev) return CALL ReadCom( Un, FileName, 'File header: Module Version (line 1)', ErrStat2, ErrMsg2, 0 ) @@ -360,10 +362,10 @@ SUBROUTINE WrVTK_SP_header( FileName, descr, Un, ErrStat, ErrMsg ) INTEGER(IntKi) , INTENT( OUT) :: ErrStat !< error level/status of OpenFOutFile operation CHARACTER(*) , INTENT( OUT) :: ErrMsg !< message when error occurs - !$OMP critical + !$OMP critical(fileopen) CALL GetNewUnit( Un, ErrStat, ErrMsg ) CALL OpenFOutFile ( Un, TRIM(FileName), ErrStat, ErrMsg ) - !$OMP end critical + !$OMP end critical(fileopen) if (ErrStat >= AbortErrLev) return WRITE(Un,'(A)') '# vtk DataFile Version 3.0' @@ -451,6 +453,7 @@ logical function vtk_new_ascii_file(filename,label,mvtk) logical :: b if (.not. mvtk%bFileOpen) then + !$OMP critical(fileopen) CALL GetNewUnit( mvtk%vtk_unit ) if (mvtk%bBinary) then ! Fortran 2003 stream, otherwise intel fortran ! @@ -466,6 +469,7 @@ logical function vtk_new_ascii_file(filename,label,mvtk) else open(mvtk%vtk_unit,file=trim(adjustl(filename)),iostat=iostatvar,action="write",status='replace') endif + !$OMP end critical(fileopen) if (iostatvar == 0) then if (mvtk%bBinary) then write(mvtk%vtk_unit)'# vtk DataFile Version 3.0'//NewLine diff --git a/modules/openfast-library/src/FAST_Solver.f90 b/modules/openfast-library/src/FAST_Solver.f90 index 1f6653285..01138be3f 100644 --- a/modules/openfast-library/src/FAST_Solver.f90 +++ b/modules/openfast-library/src/FAST_Solver.f90 @@ -1839,8 +1839,10 @@ SUBROUTINE ED_HD_InputOutputSolve( this_time, p_FAST, calcJacobian & #ifdef OUTPUT_ADDEDMASS UnAM = -1 + !$OMP critical(fileopen) CALL GetNewUnit( UnAM, ErrStat, ErrMsg ) CALL OpenFOutFile( UnAM, TRIM(p_FAST%OutFileRoot)//'.AddedMassMatrix', ErrStat2, ErrMsg2) + !$OMP end critical(fileopen) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) IF ( ErrStat >= AbortErrLev ) THEN CALL CleanUp() @@ -1853,8 +1855,10 @@ SUBROUTINE ED_HD_InputOutputSolve( this_time, p_FAST, calcJacobian & #endif #ifdef OUTPUT_JACOBIAN UnJac = -1 + !$OMP critical(fileopen) CALL GetNewUnit( UnJac, ErrStat2, ErrMsg2 ) CALL OpenFOutFile( UnJac, TRIM(p_FAST%OutFileRoot)//'.'//TRIM(num2lstr(this_time))//'.Jacobian2', ErrStat2, ErrMsg2) + !$OMP end critical(fileopen) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) IF ( ErrStat >= AbortErrLev ) THEN CALL CleanUp() @@ -2608,8 +2612,10 @@ SUBROUTINE FullOpt1_InputOutputSolve( this_time, p_FAST, calcJacobian & #ifdef OUTPUT_ADDEDMASS IF (p_FAST%CompHydro == Module_HD ) THEN UnAM = -1 + !$OMP critical(fileopen) CALL GetNewUnit( UnAM, ErrStat2, ErrMsg2 ) CALL OpenFOutFile( UnAM, TRIM(p_FAST%OutFileRoot)//'.AddedMassMatrix', ErrStat2, ErrMsg2) + !$OMP end critical(fileopen) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) IF ( ErrStat >= AbortErrLev ) RETURN @@ -2621,8 +2627,10 @@ SUBROUTINE FullOpt1_InputOutputSolve( this_time, p_FAST, calcJacobian & #endif #ifdef OUTPUT_JACOBIAN UnJac = -1 + !$OMP critical(fileopen) CALL GetNewUnit( UnJac, ErrStat2, ErrMsg2 ) CALL OpenFOutFile( UnJac, TRIM(p_FAST%OutFileRoot)//'.'//TRIM(num2lstr(this_time))//'.Jacobian', ErrStat2, ErrMsg2) + !$OMP end critical(fileopen) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) IF ( ErrStat >= AbortErrLev ) RETURN @@ -5095,8 +5103,10 @@ SUBROUTINE CalcOutputs_And_SolveForInputs( n_t_global, this_time, this_state, ca #ifdef OUTPUT_MASS_MATRIX if (n_t_global == 0) then UnMM = -1 + !$OMP critical(fileopen) CALL GetNewUnit( UnMM, ErrStat2, ErrMsg2 ) CALL OpenFOutFile( UnMM, TRIM(p_FAST%OutFileRoot)//'.EDMassMatrix', ErrStat2, ErrMsg2) + !$OMP end critical(fileopen) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) IF ( ErrStat >= AbortErrLev ) RETURN CALL WrMatrix(ED%m%AugMat,UnMM, p_FAST%OutFmt) diff --git a/modules/openfast-library/src/FAST_Subs.f90 b/modules/openfast-library/src/FAST_Subs.f90 index e23cfe2e0..9e0af8c93 100644 --- a/modules/openfast-library/src/FAST_Subs.f90 +++ b/modules/openfast-library/src/FAST_Subs.f90 @@ -2280,11 +2280,13 @@ SUBROUTINE FAST_InitOutput( p_FAST, y_FAST, Init, ErrStat, ErrMsg ) y_FAST%OutFmt_a = trim(y_FAST%OutFmt_a)//','//trim(num2lstr(y_FAST%ActualChanLen - p_FAST%FmtWidth))//'x' end if + !$OMP critical(fileopen) CALL GetNewUnit( y_FAST%UnOu, ErrStat, ErrMsg ) - IF ( ErrStat >= AbortErrLev ) RETURN - - CALL OpenFOutFile ( y_FAST%UnOu, TRIM(p_FAST%OutFileRoot)//'.out', ErrStat, ErrMsg ) - IF ( ErrStat >= AbortErrLev ) RETURN + IF ( ErrStat < AbortErrLev ) then + CALL OpenFOutFile ( y_FAST%UnOu, TRIM(p_FAST%OutFileRoot)//'.out', ErrStat, ErrMsg ) + ENDIF + !$OMP end critical(fileopen) + IF ( ErrStat >= AbortErrLev ) RETURN ! Add some file information: @@ -2415,18 +2417,18 @@ SUBROUTINE FAST_ReadPrimaryFile( InputFile, p, m_FAST, OverrideAbortErrLev, ErrS ! Get an available unit number for the file. + !$OMP critical(fileopen) CALL GetNewUnit( UnIn, ErrStat, ErrMsg ) - IF ( ErrStat >= AbortErrLev ) RETURN - - + if ( ErrStat < AbortErrLev ) then ! Open the Primary input file. - - CALL OpenFInpFile ( UnIn, InputFile, ErrStat2, ErrMsg2 ) + CALL OpenFInpFile ( UnIn, InputFile, ErrStat2, ErrMsg2 ) CALL SetErrStat( ErrStat2, ErrMsg2,ErrStat,ErrMsg,RoutineName) - if ( ErrStat >= AbortErrLev ) then - call cleanup() - RETURN - end if + endif + !$OMP end critical(fileopen) + if ( ErrStat >= AbortErrLev ) then + call cleanup() + RETURN + end if ! Read the lines up/including to the "Echo" simulation control variable @@ -3929,11 +3931,13 @@ SUBROUTINE FAST_WrSum( p_FAST, y_FAST, MeshMapData, ErrStat, ErrMsg ) ! Get a unit number and open the file: + !$OMP critical(fileopen) CALL GetNewUnit( y_FAST%UnSum, ErrStat, ErrMsg ) - IF ( ErrStat >= AbortErrLev ) RETURN - - CALL OpenFOutFile ( y_FAST%UnSum, TRIM(p_FAST%OutFileRoot)//'.sum', ErrStat, ErrMsg ) - IF ( ErrStat >= AbortErrLev ) RETURN + if ( ErrStat < AbortErrLev ) then + CALL OpenFOutFile ( y_FAST%UnSum, TRIM(p_FAST%OutFileRoot)//'.sum', ErrStat, ErrMsg ) + endif + !$OMP end critical(fileopen) + IF ( ErrStat >= AbortErrLev ) RETURN ! Add some file information: @@ -6173,8 +6177,10 @@ SUBROUTINE WriteInputMeshesToFile(u_ED, u_AD, u_SD, u_HD, u_MAP, u_BD, FileName, ! Open the binary output file: unOut=-1 + !$OMP critical(fileopen) CALL GetNewUnit( unOut, ErrStat, ErrMsg ) CALL OpenBOutFile ( unOut, TRIM(FileName), ErrStat, ErrMsg ) + !$OMP end critical(fileopen) IF (ErrStat /= ErrID_None) RETURN ! note that I'm not doing anything with the errors here, so it won't tell @@ -6252,9 +6258,11 @@ SUBROUTINE WriteMotionMeshesToFile(time, y_ED, u_SD, y_SD, u_HD, u_MAP, y_BD, u_ ! Open the binary output file and write a header: if (unOut<0) then + !$OMP critical(fileopen) CALL GetNewUnit( unOut, ErrStat, ErrMsg ) CALL OpenBOutFile ( unOut, TRIM(FileName), ErrStat, ErrMsg ) + !$OMP end critical(fileopen) IF (ErrStat /= ErrID_None) RETURN ! Add a file identification number (in case we ever have to change this): @@ -7045,8 +7053,10 @@ SUBROUTINE FAST_CreateCheckpoint_T(t_initial, n_t_global, NumTurbines, Turbine, IF ( unOut < 0 ) THEN + !$OMP critical(fileopen) CALL GetNewUnit( unOut, ErrStat2, ErrMsg2 ) CALL OpenBOutFile ( unOut, FileName, ErrStat2, ErrMsg2) + !$OMP end critical(fileopen) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) if (ErrStat >= AbortErrLev ) then call cleanup() @@ -7213,9 +7223,11 @@ SUBROUTINE FAST_RestoreFromCheckpoint_T(t_initial, n_t_global, NumTurbines, Turb IF ( unIn < 0 ) THEN + !$OMP critical(fileopen) CALL GetNewUnit( unIn, ErrStat2, ErrMsg2 ) CALL OpenBInpFile ( unIn, FileName, ErrStat2, ErrMsg2) + !$OMP end critical(fileopen) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) IF (ErrStat >= AbortErrLev ) RETURN @@ -7617,9 +7629,11 @@ SUBROUTINE ReadModeShapeMatlabFile(p_FAST, ErrStat, ErrMsg) ErrMsg = "" ! Open data file. + !$OMP critical(fileopen) CALL GetNewUnit( UnIn, ErrStat2, ErrMsg2 ) CALL OpenBInpFile ( UnIn, trim(p_FAST%VTK_modes%MatlabFileName), ErrStat2, ErrMsg2 ) + !$OMP end critical(fileopen) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) IF (ErrStat >= AbortErrLev) RETURN @@ -7743,9 +7757,11 @@ SUBROUTINE ReadModeShapeFile(p_FAST, InputFile, ErrStat, ErrMsg, checkpointOnly) CALL GetPath( InputFile, PriPath ) ! Input files will be relative to the path where the primary input file is located. ! Open data file. + !$OMP critical(fileopen) CALL GetNewUnit( UnIn, ErrStat2, ErrMsg2 ) CALL OpenFInpFile ( UnIn, InputFile, ErrStat2, ErrMsg2 ) + !$OMP end critical(fileopen) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) IF (ErrStat >= AbortErrLev) RETURN diff --git a/modules/servodyn/src/ServoDyn_IO.f90 b/modules/servodyn/src/ServoDyn_IO.f90 index cb900579e..373440979 100644 --- a/modules/servodyn/src/ServoDyn_IO.f90 +++ b/modules/servodyn/src/ServoDyn_IO.f90 @@ -2400,8 +2400,10 @@ subroutine InitializeSummaryFile(InputFileData,OutfileRoot,UnSum,ErrStat,ErrMsg) ErrStat = ErrID_None ErrMsg = '' if ( InputFileData%SumPrint ) then + !$OMP critical(fileopen) call GetNewUnit( UnSum ) CALL OpenEcho ( UnSum, TRIM(OutFileRoot)//'.sum', ErrStat2, ErrMsg2 ) + !$OMP end critical(fileopen) CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) IF (ErrStat >= AbortErrLev) RETURN else diff --git a/modules/subdyn/src/SubDyn.f90 b/modules/subdyn/src/SubDyn.f90 index 1258379d0..e2f7bc7e8 100644 --- a/modules/subdyn/src/SubDyn.f90 +++ b/modules/subdyn/src/SubDyn.f90 @@ -866,9 +866,11 @@ SUBROUTINE SD_Input(SDInputFile, Init, p, ErrStat,ErrMsg) UnEc = -1 Echo = .FALSE. +!$OMP critical(fileopen) CALL GetNewUnit( UnIn ) CALL OpenFInpfile(UnIn, TRIM(SDInputFile), ErrStat2, ErrMsg2) +!$OMP end critical(fileopen) IF ( ErrStat2 /= ErrID_None ) THEN Call Fatal('Could not open SubDyn input file') @@ -3470,6 +3472,7 @@ END SUBROUTINE OutModes !> Write the common part of the JSON file (Nodes, Connectivity, Element prop) +!FIXME: error handling is broken here!!! SUBROUTINE WriteJSONCommon(FileName, Init, p, m, InitInput, FileKind, UnSum, ErrStat, ErrMsg) use JSON, only: json_write_array TYPE(SD_InitType), INTENT(INOUT) :: Init !< Input data for initialization routine @@ -3491,8 +3494,10 @@ SUBROUTINE WriteJSONCommon(FileName, Init, p, m, InitInput, FileKind, UnSum, Err ! --- Create file and get unit UnSum = -1 ! we haven't opened the summary file, yet. + !$OMP critical(fileopen) call GetNewUnit( UnSum ) call OpenFOutFile ( UnSum, FileName, ErrStat2, ErrMsg2 ) + !$OMP end critical(fileopen) write(UnSum, '(A)')'{' ! --- Misc From 6bacfca574416e1837e9fd0ad99b6e251059c0c1 Mon Sep 17 00:00:00 2001 From: Derek Slaughter Date: Wed, 11 Dec 2024 21:53:38 +0000 Subject: [PATCH 078/161] Modify NWTC_IO's GetWords function to handle quoted strings properly --- modules/nwtc-library/src/NWTC_IO.f90 | 117 +++++++++++++++------------ 1 file changed, 67 insertions(+), 50 deletions(-) diff --git a/modules/nwtc-library/src/NWTC_IO.f90 b/modules/nwtc-library/src/NWTC_IO.f90 index 931aaf76e..a248bf54f 100644 --- a/modules/nwtc-library/src/NWTC_IO.f90 +++ b/modules/nwtc-library/src/NWTC_IO.f90 @@ -62,7 +62,7 @@ MODULE NWTC_IO CHARACTER(99) :: ProgVer = ' ' !< The version (including date) of the calling program. DO NOT USE THIS IN NEW PROGRAMS CHARACTER(1), PARAMETER :: Tab = CHAR( 9 ) !< The tab character. CHARACTER(*), PARAMETER :: CommChars = '!#%' !< Comment characters that mark the end of useful input - INTEGER(IntKi), PARAMETER :: NWTC_SizeOfNumWord = 200 !< maximum length of the words containing numeric input (for ParseVar routines) + INTEGER(IntKi), PARAMETER :: NWTC_SizeOfNumWord = 256 !< maximum length of the words containing numeric input (for ParseVar routines) ! Parameters for writing to echo files (in this module only) @@ -2068,70 +2068,87 @@ SUBROUTINE GetWords ( Line, Words, NumWords, NumFound ) INTEGER, INTENT(IN) :: NumWords !< The maximum number of words to look for (and size of Words) CHARACTER(*), INTENT(IN) :: Line !< The string to search. - CHARACTER(*), INTENT(OUT) :: Words(NumWords) !< The array of found words. + CHARACTER(*), INTENT(OUT) :: Words(:) !< The array of found words. INTEGER, OPTIONAL, INTENT(OUT) :: NumFound !< The number of words found - ! Local declarations. - - INTEGER :: Ch ! Character position within the string. - INTEGER :: IW ! Word index. - INTEGER :: NextWhite ! The location of the next whitespace in the string. + INTEGER :: iWord ! Word index. + INTEGER :: i ! Character index in line. + INTEGER :: iChar ! Character index in word. + CHARACTER(len=1) :: Char ! Current character + LOGICAL :: InQuotes ! Flag indicating text is within quotes + ! If no text on line, return + if (len_trim(Line) == 0) return + ! Let's prefill the array with blanks. + do iWord = 1, NumWords + Words(iWord) = ' ' + end do - ! Let's prefill the array with blanks. - - DO IW=1,NumWords - Words(IW) = ' ' - END DO ! IW + ! Initialize number of words found to zero if present + if (present(NumFound)) NumFound = 0 - IW = 0 + ! If no text on line, return + if (len_trim(Line) == 0) return + ! Initialize word index to first word + iWord = 1 - ! Let's make sure we have text on this line. - - IF ( LEN_TRIM( Line ) > 0 ) THEN - - ! Parse words separated by any combination of spaces, tabs, commas, - ! semicolons, single quotes, and double quotes ("whitespace"). - - Ch = 0 - - DO - - NextWhite = SCAN( Line(Ch+1:) , ' ,;''"'//Tab ) - - IF ( NextWhite > 1 ) THEN - - IW = IW + 1 - Words(IW) = Line(Ch+1:Ch+NextWhite-1) - if (NextWhite > len(words(iw)) ) then - call ProgWarn('Error reading field from file. There are too many characters in the input file to store in the field. Value may be truncated.') - end if - - IF ( IW == NumWords ) EXIT - - Ch = Ch + NextWhite - - ELSE IF ( NextWhite == 1 ) THEN - - Ch = Ch + 1 + ! Initialize index within word + iChar = 0 + + ! Initialize in quotes to false + InQuotes = .false. + + ! Loop through characters in line + do i = 1, len_trim(line) + + ! Get current character + Char = Line(i:i) + + ! Select based on character + select case (Char) + case ('"', "'") ! Double quotes, single quotes + if (InQuotes) then + InQuotes = .false. + if (iChar > 0) then + iWord = iWord + 1 + iChar = 0 + end if + else + InQuotes = .true. + end if + cycle + + case (' ', ',', ';', Tab) ! Whitespace, comma, semicolon + if (.not. InQuotes) then + if (iChar > 0) then + iWord = iWord + 1 + iChar = 0 + end if + cycle + end if + end select - CYCLE + ! If sufficient words have been collected, exit loop + if (iWord > NumWords) exit - ELSE + ! Increment character index + iChar = iChar + 1 - EXIT + ! If index is larger than length of word, continue + if (iChar > len(words(iWord))) then + call ProgWarn('Error reading field from file. There are too many characters in the input file to store in the field. Value may be truncated.') + cycle + end if - END IF + ! Add character to word + Words(iWord)(iChar:iChar) = Char - END DO - - END IF + end do - IF (PRESENT(NumFound)) NumFound = IW + if (present(NumFound)) NumFound = iWord - RETURN END SUBROUTINE GetWords !======================================================================= !> This routine converts an ASCII array of integers into an equivalent string From 4c6aad12795000b63cbdd82d1e398d5259df4c73 Mon Sep 17 00:00:00 2001 From: Derek Slaughter Date: Wed, 11 Dec 2024 21:55:42 +0000 Subject: [PATCH 079/161] Use NumWords for length of array --- modules/nwtc-library/src/NWTC_IO.f90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/nwtc-library/src/NWTC_IO.f90 b/modules/nwtc-library/src/NWTC_IO.f90 index a248bf54f..e9a2da695 100644 --- a/modules/nwtc-library/src/NWTC_IO.f90 +++ b/modules/nwtc-library/src/NWTC_IO.f90 @@ -2068,7 +2068,7 @@ SUBROUTINE GetWords ( Line, Words, NumWords, NumFound ) INTEGER, INTENT(IN) :: NumWords !< The maximum number of words to look for (and size of Words) CHARACTER(*), INTENT(IN) :: Line !< The string to search. - CHARACTER(*), INTENT(OUT) :: Words(:) !< The array of found words. + CHARACTER(*), INTENT(OUT) :: Words(NumWords) !< The array of found words. INTEGER, OPTIONAL, INTENT(OUT) :: NumFound !< The number of words found INTEGER :: iWord ! Word index. From 7ffff7ebc09ca02f946cdc329fed1ad4e91a11e6 Mon Sep 17 00:00:00 2001 From: Derek Slaughter Date: Thu, 12 Dec 2024 15:29:58 +0000 Subject: [PATCH 080/161] GetWords: always break on ',' and ';' --- modules/nwtc-library/src/NWTC_IO.f90 | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/modules/nwtc-library/src/NWTC_IO.f90 b/modules/nwtc-library/src/NWTC_IO.f90 index e9a2da695..500dcde4f 100644 --- a/modules/nwtc-library/src/NWTC_IO.f90 +++ b/modules/nwtc-library/src/NWTC_IO.f90 @@ -2120,7 +2120,8 @@ SUBROUTINE GetWords ( Line, Words, NumWords, NumFound ) end if cycle - case (' ', ',', ';', Tab) ! Whitespace, comma, semicolon + case (' ', Tab) ! Whitespace + ! If between quotes, keep whitespace; otherwise separate words if (.not. InQuotes) then if (iChar > 0) then iWord = iWord + 1 @@ -2128,6 +2129,14 @@ SUBROUTINE GetWords ( Line, Words, NumWords, NumFound ) end if cycle end if + + case (',', ';') ! Comma, semicolon + ! Always separate words on these characters + if (iChar > 0) then + iWord = iWord + 1 + iChar = 0 + end if + cycle end select ! If sufficient words have been collected, exit loop @@ -2138,7 +2147,7 @@ SUBROUTINE GetWords ( Line, Words, NumWords, NumFound ) ! If index is larger than length of word, continue if (iChar > len(words(iWord))) then - call ProgWarn('Error reading field from file. There are too many characters in the input file to store in the field. Value may be truncated.') + call ProgWarn('Error reading field from file. There are too many characters in the input file to store in the field. Value may be truncated. '//Line) cycle end if From 892756db5d0b86480d74fb2ee832b38a1b7984d8 Mon Sep 17 00:00:00 2001 From: Derek Slaughter Date: Thu, 12 Dec 2024 16:46:57 +0000 Subject: [PATCH 081/161] Add IgnoreQuotes arg to GetWords and add IsPath arg to ParseChVar --- modules/nwtc-library/src/NWTC_IO.f90 | 34 +++++++++++++++++++++------- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/modules/nwtc-library/src/NWTC_IO.f90 b/modules/nwtc-library/src/NWTC_IO.f90 index 500dcde4f..602fad45d 100644 --- a/modules/nwtc-library/src/NWTC_IO.f90 +++ b/modules/nwtc-library/src/NWTC_IO.f90 @@ -2061,7 +2061,7 @@ END SUBROUTINE GetTokens !! It uses spaces, tabs, commas, semicolons, single quotes, and double quotes ("whitespace") !! as word separators. If there aren't NumWords in the line, the remaining array elements will remain empty. !! Use CountWords (nwtc_io::countwords) to count the number of words in a line. - SUBROUTINE GetWords ( Line, Words, NumWords, NumFound ) + SUBROUTINE GetWords ( Line, Words, NumWords, NumFound, IgnoreQuotes ) ! Argument declarations. @@ -2070,16 +2070,25 @@ SUBROUTINE GetWords ( Line, Words, NumWords, NumFound ) CHARACTER(*), INTENT(IN) :: Line !< The string to search. CHARACTER(*), INTENT(OUT) :: Words(NumWords) !< The array of found words. INTEGER, OPTIONAL, INTENT(OUT) :: NumFound !< The number of words found + LOGICAL, OPTIONAL, INTENT(OUT) :: IgnoreQuotes !< Flag to ignore quotes (process as whitespace) INTEGER :: iWord ! Word index. INTEGER :: i ! Character index in line. INTEGER :: iChar ! Character index in word. CHARACTER(len=1) :: Char ! Current character LOGICAL :: InQuotes ! Flag indicating text is within quotes + LOGICAL :: IgnoreQuotesLoc ! Local flag to ignore quotes ! If no text on line, return if (len_trim(Line) == 0) return + ! If ignore quotes is present, set local flag, otherwise true + if (present(IgnoreQuotes)) then + IgnoreQuotesLoc = IgnoreQuotes + else + IgnoreQuotesLoc = .true. + end if + ! Let's prefill the array with blanks. do iWord = 1, NumWords Words(iWord) = ' ' @@ -2109,9 +2118,11 @@ SUBROUTINE GetWords ( Line, Words, NumWords, NumFound ) ! Select based on character select case (Char) case ('"', "'") ! Double quotes, single quotes - if (InQuotes) then + if (IgnoreQuotesLoc .or. InQuotes) then InQuotes = .false. if (iChar > 0) then + ! If requested number of words found, exit + if (iWord == NumWords) exit iWord = iWord + 1 iChar = 0 end if @@ -2124,6 +2135,8 @@ SUBROUTINE GetWords ( Line, Words, NumWords, NumFound ) ! If between quotes, keep whitespace; otherwise separate words if (.not. InQuotes) then if (iChar > 0) then + ! If requested number of words found, exit + if (iWord == NumWords) exit iWord = iWord + 1 iChar = 0 end if @@ -2133,15 +2146,14 @@ SUBROUTINE GetWords ( Line, Words, NumWords, NumFound ) case (',', ';') ! Comma, semicolon ! Always separate words on these characters if (iChar > 0) then + ! If requested number of words found, exit + if (iWord == NumWords) exit iWord = iWord + 1 iChar = 0 end if cycle end select - ! If sufficient words have been collected, exit loop - if (iWord > NumWords) exit - ! Increment character index iChar = iChar + 1 @@ -2910,7 +2922,7 @@ END SUBROUTINE ParseCom !! !! WARNING: This routine assumes the "words" containing the variable name and value are <= 20 characters. \n !! Use ParseVar (nwtc_io::parsevar) instead of directly calling a specific routine in the generic interface. - SUBROUTINE ParseChVar ( FileInfo, LineNum, ExpVarName, Var, ErrStat, ErrMsg, UnEc ) + SUBROUTINE ParseChVar ( FileInfo, LineNum, ExpVarName, Var, ErrStat, ErrMsg, UnEc, IsPath ) ! Arguments declarations. @@ -2919,6 +2931,7 @@ SUBROUTINE ParseChVar ( FileInfo, LineNum, ExpVarName, Var, ErrStat, ErrMsg, UnE INTEGER(IntKi), INTENT(INOUT) :: LineNum !< The number of the line to parse. INTEGER, INTENT(IN), OPTIONAL :: UnEc !< I/O unit for echo file. If present and > 0, write to UnEc. + LOGICAL, INTENT(IN), OPTIONAL :: IsPath !< Flag indicating that string is a path. CHARACTER(*), INTENT(OUT) :: Var !< The variable to receive the input value. CHARACTER(*), INTENT(OUT) :: ErrMsg !< The error message, if ErrStat /= 0. @@ -2931,6 +2944,7 @@ SUBROUTINE ParseChVar ( FileInfo, LineNum, ExpVarName, Var, ErrStat, ErrMsg, UnE INTEGER(IntKi) :: ErrStatLcl ! Error status local to this routine. INTEGER(IntKi) :: NameIndx ! The index into the Words array that points to the variable name. + LOGICAL :: IgnoreQuotes CHARACTER(NWTC_SizeOfNumWord) :: Words (2) ! The two "words" parsed from the line. CHARACTER(ErrMsgLen) :: ErrMsg2 @@ -2950,8 +2964,12 @@ SUBROUTINE ParseChVar ( FileInfo, LineNum, ExpVarName, Var, ErrStat, ErrMsg, UnE RETURN END IF - - CALL GetWords ( FileInfo%Lines(LineNum), Words, 2 ) ! Read the first two words in Line. + if (present(IsPath)) then + IgnoreQuotes = .not. IsPath + else + IgnoreQuotes = .true. + end if + CALL GetWords ( FileInfo%Lines(LineNum), Words, 2, IgnoreQuotes=IgnoreQuotes ) ! Read the first two words in Line. IF ( Words(2) == '' .and. (LEN_TRIM(ExpVarName) > 0) ) THEN CALL SetErrStat ( ErrID_Fatal, 'A fatal error occurred when parsing data from "' & //TRIM( FileInfo%FileList(FileInfo%FileIndx(LineNum)) )//'".'//NewLine// & From f77571df724e24c505ba2f5d3dd27444f129451f Mon Sep 17 00:00:00 2001 From: Derek Slaughter Date: Thu, 12 Dec 2024 16:47:19 +0000 Subject: [PATCH 082/161] Add IsPath=.true. where ParseVar is used to parse a file path --- modules/aerodyn/src/AeroDyn_Driver_Subs.f90 | 4 ++-- modules/aerodyn/src/AeroDyn_IO.f90 | 6 +++--- modules/aerodyn/src/AirfoilInfo.f90 | 2 +- modules/hydrodyn/src/HydroDyn_Input.f90 | 2 +- modules/inflowwind/src/InflowWind_Subs.f90 | 12 ++++++------ modules/servodyn/src/ServoDyn_IO.f90 | 6 +++--- modules/servodyn/src/StrucCtrl.f90 | 2 +- 7 files changed, 17 insertions(+), 17 deletions(-) diff --git a/modules/aerodyn/src/AeroDyn_Driver_Subs.f90 b/modules/aerodyn/src/AeroDyn_Driver_Subs.f90 index 8227a8252..a43ae3356 100644 --- a/modules/aerodyn/src/AeroDyn_Driver_Subs.f90 +++ b/modules/aerodyn/src/AeroDyn_Driver_Subs.f90 @@ -958,7 +958,7 @@ subroutine Dvr_ReadInputFile(fileName, dvr, errStat, errMsg ) call ParseVar(FileInfo_In, CurLine, "analysisType", dvr%analysisType, errStat2, errMsg2, unEc); if (Failed()) return call ParseVar(FileInfo_In, CurLine, "tMax" , dvr%tMax , errStat2, errMsg2, unEc); if (Failed()) return call ParseVar(FileInfo_In, CurLine, "dt" , dvr%dt , errStat2, errMsg2, unEc); if (Failed()) return - call ParseVar(FileInfo_In, CurLine, "AeroFile" , dvr%AD_InputFile, errStat2, errMsg2, unEc); if (Failed()) return + call ParseVar(FileInfo_In, CurLine, "AeroFile" , dvr%AD_InputFile, errStat2, errMsg2, unEc, IsPath=.true.); if (Failed()) return ! --- Environmental conditions call ParseCom(FileInfo_In, CurLine, Line, errStat2, errMsg2, unEc); if (Failed()) return @@ -973,7 +973,7 @@ subroutine Dvr_ReadInputFile(fileName, dvr, errStat, errMsg ) ! --- Inflow data call ParseCom(FileInfo_In, CurLine, Line, errStat2, errMsg2, unEc); if (Failed()) return call ParseVar(FileInfo_In, CurLine, "compInflow", dvr%IW_InitInp%compInflow , errStat2, errMsg2, unEc); if (Failed()) return - call ParseVar(FileInfo_In, CurLine, "InflowFile", dvr%IW_InitInp%InputFile, errStat2, errMsg2, unEc); if (Failed()) return + call ParseVar(FileInfo_In, CurLine, "InflowFile", dvr%IW_InitInp%InputFile, errStat2, errMsg2, unEc, IsPath=.true.); if (Failed()) return if (dvr%IW_InitInp%compInflow==0) then call ParseVar(FileInfo_In, CurLine, "HWindSpeed", dvr%IW_InitInp%HWindSpeed , errStat2, errMsg2, unEc); if (Failed()) return call ParseVar(FileInfo_In, CurLine, "RefHt" , dvr%IW_InitInp%RefHt , errStat2, errMsg2, unEc); if (Failed()) return diff --git a/modules/aerodyn/src/AeroDyn_IO.f90 b/modules/aerodyn/src/AeroDyn_IO.f90 index 24e56b0ab..815e14745 100644 --- a/modules/aerodyn/src/AeroDyn_IO.f90 +++ b/modules/aerodyn/src/AeroDyn_IO.f90 @@ -730,7 +730,7 @@ SUBROUTINE ParsePrimaryFileInfo( PriPath, InitInp, InputFile, RootName, NumBlade call ParseVar( FileInfo_In, CurLine, "CompAA", InputFileData%CompAA, ErrStat2, ErrMsg2, UnEc ) if (Failed()) return ! AA_InputFile - Aeroacoustics input file - call ParseVar( FileInfo_In, CurLine, "AA_InputFile", InputFileData%AA_InputFile, ErrStat2, ErrMsg2, UnEc ) + call ParseVar( FileInfo_In, CurLine, "AA_InputFile", InputFileData%AA_InputFile, ErrStat2, ErrMsg2, UnEc, IsPath=.true. ) if (Failed()) return IF ( PathIsRelative( InputFileData%AA_InputFile ) ) InputFileData%AA_InputFile = TRIM(PriPath)//TRIM(InputFileData%AA_InputFile) @@ -802,7 +802,7 @@ SUBROUTINE ParsePrimaryFileInfo( PriPath, InitInp, InputFile, RootName, NumBlade if ( InputFileData%Echo ) WRITE(UnEc, '(A)') FileInfo_In%Lines(CurLine) ! Write section break to echo CurLine = CurLine + 1 ! OLAFInputFileName - Input file for OLAF [used only when WakeMod=3] - call ParseVar( FileInfo_In, CurLine, "OLAFInputFileName", InputFileData%FVWFileName, ErrStat2, ErrMsg2, UnEc ) + call ParseVar( FileInfo_In, CurLine, "OLAFInputFileName", InputFileData%FVWFileName, ErrStat2, ErrMsg2, UnEc, IsPath=.true. ) if (Failed()) return IF ( PathIsRelative( InputFileData%FVWFileName ) ) InputFileData%FVWFileName = TRIM(PriPath)//TRIM(InputFileData%FVWFileName) @@ -906,7 +906,7 @@ SUBROUTINE ParsePrimaryFileInfo( PriPath, InitInp, InputFile, RootName, NumBlade ! NOTE: being nice with legacy input file. Uncomment in next release call ParseVar(FileInfo_In, CurLine, "TFinAero", InputFileData%rotors(iR)%TFinAero, ErrStat2, ErrMsg2, UnEc); if (ErrStat2==ErrID_None) then - call ParseVar(FileInfo_In, CurLine, "TFinFile", InputFileData%rotors(iR)%TFinFile, ErrStat2, ErrMsg2, UnEc); if (Failed()) return + call ParseVar(FileInfo_In, CurLine, "TFinFile", InputFileData%rotors(iR)%TFinFile, ErrStat2, ErrMsg2, UnEc, IsPath=.true.); if (Failed()) return InputFileData%rotors(iR)%TFinFile = trim(PriPath) // trim(InputFileData%rotors(iR)%TFinFile) else call LegacyWarning('Tail Fin section (TFinAero, TFinFile) is missing from input file.') diff --git a/modules/aerodyn/src/AirfoilInfo.f90 b/modules/aerodyn/src/AirfoilInfo.f90 index 477d46ca5..7d3d0742e 100644 --- a/modules/aerodyn/src/AirfoilInfo.f90 +++ b/modules/aerodyn/src/AirfoilInfo.f90 @@ -479,7 +479,7 @@ SUBROUTINE ReadAFfile ( InitInp, NumCoefsIn, p, ErrStat, ErrMsg, UnEc ) ENDIF ! Reading Boundary layer file for aeroacoustics - CALL ParseVar ( FileInfo, CurLine, 'BL_file' , p%BL_file , ErrStat2, ErrMsg2, UnEc ) + CALL ParseVar ( FileInfo, CurLine, 'BL_file' , p%BL_file , ErrStat2, ErrMsg2, UnEc, IsPath=.true. ) IF (ErrStat2 >= AbortErrLev) p%BL_file = "NOT_SET_IN_AIRFOIL_FILE" !CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) IF ( PathIsRelative( p%BL_file ) ) p%BL_file=trim(PriPath)//trim(p%BL_file) diff --git a/modules/hydrodyn/src/HydroDyn_Input.f90 b/modules/hydrodyn/src/HydroDyn_Input.f90 index a9fe94018..8c5cd4dab 100644 --- a/modules/hydrodyn/src/HydroDyn_Input.f90 +++ b/modules/hydrodyn/src/HydroDyn_Input.f90 @@ -359,7 +359,7 @@ SUBROUTINE HydroDyn_ParseInput( InputFileName, OutRootName, defWtrDens, defWtrDp if (Failed()) return; ! WvKinFile - call ParseVar( FileInfo_In, CurLine, 'WvKinFile', InputFileData%Waves%WvKinFile, ErrStat2, ErrMsg2, UnEc ) + call ParseVar( FileInfo_In, CurLine, 'WvKinFile', InputFileData%Waves%WvKinFile, ErrStat2, ErrMsg2, UnEc, IsPath=.true. ) if (Failed()) return; ! NWaveElev diff --git a/modules/inflowwind/src/InflowWind_Subs.f90 b/modules/inflowwind/src/InflowWind_Subs.f90 index c8349ffbd..4f4169a1f 100644 --- a/modules/inflowwind/src/InflowWind_Subs.f90 +++ b/modules/inflowwind/src/InflowWind_Subs.f90 @@ -317,7 +317,7 @@ SUBROUTINE InflowWind_ParseInputFileInfo( InputFileData, InFileInfo, PriPath, In !------------------------------------------------------------------------------------------------- CurLine = CurLine + 1 ! Skip section break - CALL ParseVar( InFileInfo, CurLine, "FileName_Uni", InputFileData%Uniform_FileName, TmpErrStat, TmpErrMsg, UnEc ) + CALL ParseVar( InFileInfo, CurLine, "FileName_Uni", InputFileData%Uniform_FileName, TmpErrStat, TmpErrMsg, UnEc, IsPath=.true. ) if (Failed()) return IF ( PathIsRelative( InputFileData%Uniform_FileName ) ) InputFileData%Uniform_FileName = TRIM(PriPath)//TRIM(InputFileData%Uniform_FileName) IF ( FixedWindFileRootName ) THEN ! .TRUE. when FAST.Farm uses multiple instances of InflowWind for ambient wind data @@ -339,7 +339,7 @@ SUBROUTINE InflowWind_ParseInputFileInfo( InputFileData, InFileInfo, PriPath, In !------------------------------------------------------------------------------------------------- CurLine = CurLine + 1 ! Skip section break - CALL ParseVar( InFileInfo, CurLine, "FileName_BTS", InputFileData%TSFF_FileName, TmpErrStat, TmpErrMsg, UnEc ) + CALL ParseVar( InFileInfo, CurLine, "FileName_BTS", InputFileData%TSFF_FileName, TmpErrStat, TmpErrMsg, UnEc, IsPath=.true. ) if (Failed()) return IF ( PathIsRelative( InputFileData%TSFF_FileName ) ) InputFileData%TSFF_FileName = TRIM(PriPath)//TRIM(InputFileData%TSFF_FileName) IF ( FixedWindFileRootName ) THEN ! .TRUE. when FAST.Farm uses multiple instances of InflowWind for ambient wind data @@ -355,7 +355,7 @@ SUBROUTINE InflowWind_ParseInputFileInfo( InputFileData, InFileInfo, PriPath, In !------------------------------------------------------------------------------------------------- CurLine = CurLine + 1 ! Skip section break - CALL ParseVar( InFileInfo, CurLine, "FilenameRoot", InputFileData%BladedFF_FileName, TmpErrStat, TmpErrMsg, UnEc ) + CALL ParseVar( InFileInfo, CurLine, "FilenameRoot", InputFileData%BladedFF_FileName, TmpErrStat, TmpErrMsg, UnEc, IsPath=.true. ) if (Failed()) return IF ( PathIsRelative( InputFileData%BladedFF_FileName ) ) InputFileData%BladedFF_FileName = TRIM(PriPath)//TRIM(InputFileData%BladedFF_FileName) @@ -383,15 +383,15 @@ SUBROUTINE InflowWind_ParseInputFileInfo( InputFileData, InFileInfo, PriPath, In !------------------------------------------------------------------------------------------------- CurLine = CurLine + 1 ! Skip section break - CALL ParseVar( InFileInfo, CurLine, "FileName_u", InputFileData%HAWC_FileName_u, TmpErrStat, TmpErrMsg, UnEc ) + CALL ParseVar( InFileInfo, CurLine, "FileName_u", InputFileData%HAWC_FileName_u, TmpErrStat, TmpErrMsg, UnEc, IsPath=.true. ) if (Failed()) return IF ( PathIsRelative( InputFileData%HAWC_FileName_u ) ) InputFileData%HAWC_FileName_u = TRIM(PriPath)//TRIM(InputFileData%HAWC_FileName_u) - CALL ParseVar( InFileInfo, CurLine, "FileName_v", InputFileData%HAWC_FileName_v, TmpErrStat, TmpErrMsg, UnEc ) + CALL ParseVar( InFileInfo, CurLine, "FileName_v", InputFileData%HAWC_FileName_v, TmpErrStat, TmpErrMsg, UnEc, IsPath=.true. ) if (Failed()) return IF ( PathIsRelative( InputFileData%HAWC_FileName_v ) ) InputFileData%HAWC_FileName_v = TRIM(PriPath)//TRIM(InputFileData%HAWC_FileName_v) - CALL ParseVar( InFileInfo, CurLine, "FileName_w", InputFileData%HAWC_FileName_w, TmpErrStat, TmpErrMsg, UnEc ) + CALL ParseVar( InFileInfo, CurLine, "FileName_w", InputFileData%HAWC_FileName_w, TmpErrStat, TmpErrMsg, UnEc, IsPath=.true. ) if (Failed()) return IF ( PathIsRelative( InputFileData%HAWC_FileName_w ) ) InputFileData%HAWC_FileName_w = TRIM(PriPath)//TRIM(InputFileData%HAWC_FileName_w) diff --git a/modules/servodyn/src/ServoDyn_IO.f90 b/modules/servodyn/src/ServoDyn_IO.f90 index cb900579e..1cbee9c9e 100644 --- a/modules/servodyn/src/ServoDyn_IO.f90 +++ b/modules/servodyn/src/ServoDyn_IO.f90 @@ -1332,15 +1332,15 @@ subroutine ParseInputFileInfo( PriPath, InputFile, OutFileRoot, FileInfo_In, Inp if ( InputFileData%Echo ) WRITE(UnEcho, '(A)') FileInfo_In%Lines(CurLine) ! Write section break to echo CurLine = CurLine + 1 ! DLL_FileName - Name/location of the dynamic library {.dll [Windows] or .so [Linux]} in the Bladed-DLL format (-) [used only with Bladed Interface] - call ParseVar( FileInfo_In, CurLine, 'DLL_FileName', InputFileData%DLL_FileName, ErrStat2, ErrMsg2, UnEcho ) + call ParseVar( FileInfo_In, CurLine, 'DLL_FileName', InputFileData%DLL_FileName, ErrStat2, ErrMsg2, UnEcho, IsPath=.true. ) if (Failed()) return; IF ( PathIsRelative( InputFileData%DLL_FileName ) ) InputFileData%DLL_FileName = TRIM(PriPath)//TRIM(InputFileData%DLL_FileName) ! DLL_InFile - Name of input file sent to the DLL (-) [used only with Bladed Interface] - call ParseVar( FileInfo_In, CurLine, 'DLL_InFile', InputFileData%DLL_InFile, ErrStat2, ErrMsg2, UnEcho ) + call ParseVar( FileInfo_In, CurLine, 'DLL_InFile', InputFileData%DLL_InFile, ErrStat2, ErrMsg2, UnEcho, IsPath=.true. ) if (Failed()) return; IF ( PathIsRelative( InputFileData%DLL_InFile ) ) InputFileData%DLL_InFile = TRIM(PriPath)//TRIM(InputFileData%DLL_InFile) ! DLL_ProcName - Name of procedure in DLL to be called (-) [case sensitive; used only with DLL Interface] - call ParseVar( FileInfo_In, CurLine, 'DLL_ProcName', InputFileData%DLL_ProcName, ErrStat2, ErrMsg2, UnEcho ) + call ParseVar( FileInfo_In, CurLine, 'DLL_ProcName', InputFileData%DLL_ProcName, ErrStat2, ErrMsg2, UnEcho, IsPath=.true. ) if (Failed()) return; ! DLL_DT - Communication interval for dynamic library (s) (or "default") [used only with Bladed Interface] call ParseVarWDefault( FileInfo_In, CurLine, 'DLL_DT', InputFileData%DLL_DT, InputFileData%DT, ErrStat2, ErrMsg2, UnEcho ) diff --git a/modules/servodyn/src/StrucCtrl.f90 b/modules/servodyn/src/StrucCtrl.f90 index 60c9efd53..0c0cea0da 100644 --- a/modules/servodyn/src/StrucCtrl.f90 +++ b/modules/servodyn/src/StrucCtrl.f90 @@ -2115,7 +2115,7 @@ SUBROUTINE StC_ParseInputFileInfo( PriPath, InputFile, RootName, NumMeshPts, Fil call ParseVar( FileInfo_In, Curline, 'PrescribedForcesCoordSys', InputFileData%PrescribedForcesCoordSys, ErrStat2, ErrMsg2 ) If (Failed()) return; ! Prescribed input time series - call ParseVar( FileInfo_In, Curline, 'PrescribedForcesFile', InputFileData%PrescribedForcesFile, ErrStat2, ErrMsg2 ) + call ParseVar( FileInfo_In, Curline, 'PrescribedForcesFile', InputFileData%PrescribedForcesFile, ErrStat2, ErrMsg2, IsPath=.true. ) if (Failed()) return; if ( PathIsRelative( InputFileData%PrescribedForcesFile ) ) InputFileData%PrescribedForcesFile = TRIM(PriPath)//TRIM(InputFileData%PrescribedForcesFile) From 2e1d8e02da6470fb630c49f4bd105011418c9d3f Mon Sep 17 00:00:00 2001 From: Lu Wang Date: Thu, 12 Dec 2024 14:04:58 -0700 Subject: [PATCH 083/161] ED: Expand yaw-friction modeling to include quadratic viscous friction and additional Coulomb-friction terms proportional to yaw-bearing shear force and bending moment --- modules/elastodyn/src/ElastoDyn.f90 | 69 ++++++++++++-------- modules/elastodyn/src/ElastoDyn_IO.f90 | 50 +++++++++++++- modules/elastodyn/src/ElastoDyn_Registry.txt | 17 ++++- 3 files changed, 101 insertions(+), 35 deletions(-) diff --git a/modules/elastodyn/src/ElastoDyn.f90 b/modules/elastodyn/src/ElastoDyn.f90 index 297db8684..ad40583f6 100644 --- a/modules/elastodyn/src/ElastoDyn.f90 +++ b/modules/elastodyn/src/ElastoDyn.f90 @@ -1247,11 +1247,12 @@ SUBROUTINE ED_CalcOutput( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMsg ) m%AllOuts( YawBrMxp) = DOT_PRODUCT( MomBNcRt, m%CoordSys%b1 ) m%AllOuts( YawBrMyp) = -DOT_PRODUCT( MomBNcRt, m%CoordSys%b3 ) m%AllOuts(YawFriMom) = OtherState%Mfhat*0.001_ReKi !KBF add YawFricMom as an output based on HSSBrTq (kN-m) - m%AllOuts(YawFriMfp) = OtherState%YawFriMfp*0.001_ReKi - m%AllOuts(YawFriMz) = m%YawFriMz*0.001_ReKi - m%FrcONcRt = m%AllOuts( YawBrFzn)*1000_ReKi - m%AllOuts(OmegaYF) = OtherState%OmegaTn*R2D - m%AllOuts(dOmegaYF) = OtherState%OmegaDotTn*R2D + m%AllOuts(YawFriMfp) = OtherState%YawFriMfp*0.001_ReKi + m%AllOuts(YawFriMz) = m%YawFriMz*0.001_ReKi + m%FrcONcRt = (/m%AllOuts( YawBrFxn),m%AllOuts( YawBrFyn),m%AllOuts( YawBrFzn)/) * 1000_ReKi + m%MomONcRt = (/m%AllOuts( YawBrMxn),m%AllOuts( YawBrMyn),m%AllOuts( YawBrMzn)/) * 1000_ReKi + m%AllOuts(OmegaYF) = OtherState%OmegaTn*R2D + m%AllOuts(dOmegaYF) = OtherState%OmegaDotTn*R2D ! Tower Base Loads: @@ -1874,8 +1875,7 @@ SUBROUTINE ED_CalcContStateDeriv( t, u, p, x, xd, z, OtherState, m, dxdt, ErrSta INTEGER(IntKi) :: ErrStat2 ! The error status code CHARACTER(ErrMsgLen) :: ErrMsg2 ! The error message, if an error occurred CHARACTER(*), PARAMETER :: RoutineName = 'ED_CalcContStateDeriv' - Real(R8Ki) :: YawFriMz ! Loops through some or all of the DOFs. - Real(R8Ki) :: Fz ! Loops through some or all of the DOFs. + Real(R8Ki) :: YawFriMz ! External loading on yaw bearing not including inertial contributions ! Initialize ErrStat @@ -1917,11 +1917,10 @@ SUBROUTINE ED_CalcContStateDeriv( t, u, p, x, xd, z, OtherState, m, dxdt, ErrSta CALL RFurling( t, p, x%QT(DOF_RFrl), x%QDT(DOF_RFrl), m%RtHS%RFrlMom ) ! Compute moment from rotor-furl springs and dampers, RFrlMom CALL TFurling( t, p, x%QT(DOF_TFrl), x%QDT(DOF_TFrl), m%RtHS%TFrlMom ) ! Compute moment from tail-furl springs and dampers, TFrlMom ! Compute the yaw friction torque - Fz= m%FrcONcRt !YawBrFzn force from CalcOutput YawFriMz=DOT_PRODUCT( m%RtHS%MomBNcRtt, m%CoordSys%d2 ) + u%YawMom m%YawFriMz = YawFriMz - CALL YawFriction( t, p, Fz, YawFriMz, OtherState%OmegaTn, OtherState%OmegaDotTn, m%RtHS%YawFriMom ) !Compute yaw Friction #RRD + CALL YawFriction( t, p, m%FrcONcRt, m%MomONcRt, YawFriMz, OtherState%OmegaTn, OtherState%OmegaDotTn, m%RtHS%YawFriMom ) !Compute yaw Friction #RRD !bjj: note m%RtHS%GBoxEffFac needed in OtherState only to fix HSSBrTrq (and used in FillAugMat) @@ -3334,10 +3333,16 @@ SUBROUTINE SetPrimaryParameters( InitInp, p, InputFileData, ErrStat, ErrMsg ) p%TeetHSSp = 0.0 END IF + ! Yaw friction model inputs p%YawFrctMod = InputFileData%YawFrctMod - p%M_CD = InputFileData%M_CD - p%M_CSmax = InputFileData%M_CSmax - p%sig_v = InputFileData%sig_v + p%M_CD = InputFileData%M_CD + p%M_FCD = InputFileData%M_FCD + p%M_MCD = InputFileData%M_MCD + p%M_CSmax = InputFileData%M_CSmax + p%M_FCSmax = InputFileData%M_FCSmax + p%M_MCSmax = InputFileData%M_MCSmax + p%sig_v = InputFileData%sig_v + p%sig_v2 = InputFileData%sig_v2 CALL AllocAry( p%TipMass, p%NumBl, 'TipMass', ErrStat, ErrMsg ) @@ -6403,24 +6408,24 @@ SUBROUTINE Teeter( t, p, TeetDef, TeetRate, TeetMom ) END SUBROUTINE Teeter !---------------------------------------------------------------------------------------------------------------------------------- !> This routine computes the Yaw Friction Torque due to yaw rate and acceleration. -SUBROUTINE YawFriction( t, p, Fz, Mzz, Omg, OmgDot, YawFriMf ) +SUBROUTINE YawFriction( t, p, F, M, Mzz, Omg, OmgDot, YawFriMf ) !.................................................................................................................................. ! Passed Variables: REAL(DbKi), INTENT(IN) :: t !< simulation time TYPE(ED_ParameterType), INTENT(IN) :: p !< parameters from the structural dynamics module - REAL(R8Ki), INTENT(IN ) :: Fz, Mzz !< Effective yaw bearing force and external yaw bearing torque - REAL(R8Ki), INTENT(IN ) :: Omg !< The yaw rate (rotational speed), x%QDT(DOF_Yaw). - REAL(R8Ki), INTENT(IN ) :: OmgDot !< The yaw acceleration (derivative of rotational speed), x%QD2T(DOF_Yaw). - - REAL(ReKi), INTENT(OUT) :: YawFriMf !< The total friction torque (Coulomb + viscous). + REAL(R8Ki), INTENT(IN ) :: F(3), M(3) !< Effective yaw bearing force and moment + REAL(R8Ki), INTENT(IN ) :: Mzz !< External yaw bearing torque + REAL(R8Ki), INTENT(IN ) :: Omg !< The yaw rate (rotational speed), x%QDT(DOF_Yaw). + REAL(R8Ki), INTENT(IN ) :: OmgDot !< The yaw acceleration (derivative of rotational speed), x%QD2T(DOF_Yaw). + REAL(ReKi), INTENT(OUT) :: YawFriMf !< The total friction torque (Coulomb + viscous). ! Local variables: - REAL(ReKi) :: temp ! It takes teh value of Fz or -1. + REAL(ReKi) :: temp, Fs, Mb ! It takes the value of Fz or -1. SELECT CASE ( p%YawFrctMod ) - ! Yaw-friction model {0: none, 1: does not use Fz at yaw bearing, 2: does, 3: user defined model} (switch) + ! Yaw-friction model {0: none, 1: does not use F and M at yaw bearing, 2: does, 3: user defined model} (switch) CASE ( 0_IntKi ) ! None! @@ -6428,28 +6433,34 @@ SUBROUTINE YawFriction( t, p, Fz, Mzz, Omg, OmgDot, YawFriMf ) YawFriMf = 0.0_ReKi - CASE ( 1_IntKi, 2_IntKi ) ! 1= no Fz use. 2=Fz used + CASE ( 1_IntKi, 2_IntKi ) ! 1 = F and M not used. 2 = F and M used + + temp = -1.0_ReKi ! In the case of YawFrctMod=1 + Fs = 0.0_ReKi + Mb = 0.0_ReKi - temp = -1.0_ReKi !In the case of YawFrctMod=1 - IF (p%YawFrctMod .EQ. 2) THEN - temp = MIN(0.0_R8Ki, Fz) !In the case of YawFrctMod=2 + temp = MIN(0.0_R8Ki, F(3)) ! In the case of YawFrctMod=2 + Fs = SQRT(F(1)**2+F(2)**2) ! Effective shear force on yaw bearing + Mb = SQRT(M(1)**2+M(2)**2) ! Effective bending moment on yaw bearing ENDIF IF (EqualRealNos( Omg, 0.0_R8Ki ) )THEN - YawFriMf = -MIN(real(p%M_CD,ReKi) * ABS(temp), ABS(real(Mzz,ReKi))) * SIGN(1.0_ReKi, real(Mzz,ReKi)) IF (EqualRealNos( OmgDot, 0.0_R8Ki )) THEN - YawFriMf = -MIN(real(p%M_CSmax,ReKi) * ABS(temp), ABS(real(Mzz,ReKi))) * SIGN(1.0_ReKi, real(Mzz,ReKi)) + YawFriMf = -MIN( real(p%M_CSmax,ReKi) * ABS(temp) + real(p%M_FCSmax,ReKi) * Fs + real(p%M_MCSmax,ReKi) * Mb, ABS(real(Mzz,ReKi)) ) * SIGN(1.0_ReKi, real(Mzz,ReKi)) + ELSE + YawFriMf = -MIN( real(p%M_CD, ReKi) * ABS(temp) + real(p%M_FCD, ReKi) * Fs + real(p%M_MCD, ReKi) * Mb, ABS(real(Mzz,ReKi)) ) * SIGN(1.0_ReKi, real(Mzz,ReKi)) ENDIF ELSE - YawFriMf = real(p%M_CD,ReKi) * temp * sign(1.0_ReKi, real(Omg,ReKi)) - real(p%sig_v,ReKi) * real(Omg,ReKi) + YawFriMf = ( real(p%M_CD,ReKi) * temp - real(p%M_FCD,ReKi) * Fs - real(p%M_MCD,ReKi) * Mb ) * sign(1.0_ReKi, real(Omg,ReKi)) & ! Coulomb friction + - real(p%sig_v,ReKi) * real(Omg,ReKi) - real(p%sig_v2,ReKi) * real(Omg,ReKi) * ABS(real(Omg,ReKi)) ! Viscous friction ENDIF - CASE ( 3_IntKi ) ! User-defined YawFriMf model. >>>> NOT IMPLEMENTED YET + CASE ( 3_IntKi ) ! User-defined YawFriMf model. >>>> NOT IMPLEMENTED YET - CALL UserYawFrict ( t, Fz, Mzz, Omg, OmgDot, p%RootName, YawFriMf ) + CALL UserYawFrict ( t, F, M, Mzz, Omg, OmgDot, p%RootName, YawFriMf ) END SELECT diff --git a/modules/elastodyn/src/ElastoDyn_IO.f90 b/modules/elastodyn/src/ElastoDyn_IO.f90 index 23054a48c..e892c00ef 100644 --- a/modules/elastodyn/src/ElastoDyn_IO.f90 +++ b/modules/elastodyn/src/ElastoDyn_IO.f90 @@ -3259,7 +3259,7 @@ SUBROUTINE ReadPrimaryFile( InputFile, InputFileData, BldFile, FurlFile, TwrFile RETURN END IF - !---------------------- YAW-FRICTION -------------------------------------------- + !---------------------- YAW-FRICTION -------------------------------------------- CALL ReadCom( UnIn, InputFile, 'Section Header: Yaw-Friction', ErrStat2, ErrMsg2, UnEc ) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) IF ( ErrStat >= AbortErrLev ) THEN @@ -3283,6 +3283,22 @@ SUBROUTINE ReadPrimaryFile( InputFile, InputFileData, BldFile, FurlFile, TwrFile RETURN END IF + ! M_FCSmax - Maximum Coulomb friction torque proportional to yaw bearing shear force (N-m): + CALL ReadVar( UnIn, InputFile, InputFileData%M_FCSmax, "M_FCSmax", "Maximum Coulomb friction torque proportional to yaw bearing shear force (N-m)", ErrStat2, ErrMsg2, UnEc) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + IF ( ErrStat >= AbortErrLev ) THEN + CALL Cleanup() + RETURN + END IF + + ! M_MCSmax - Maximum Coulomb friction torque proportional to yaw bearing bending moment (N-m): + CALL ReadVar( UnIn, InputFile, InputFileData%M_MCSmax, "M_MCSmax", "Maximum Coulomb friction torque proportional to yaw bearing bending moment (N-m)", ErrStat2, ErrMsg2, UnEc) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + IF ( ErrStat >= AbortErrLev ) THEN + CALL Cleanup() + RETURN + END IF + ! M_CD - Dynamic friction moment at null yaw rate (N-m): CALL ReadVar( UnIn, InputFile, InputFileData%M_CD, "M_CD", "Dynamic friction moment at null yaw rate (N-m)", ErrStat2, ErrMsg2, UnEc) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) @@ -3291,14 +3307,37 @@ SUBROUTINE ReadPrimaryFile( InputFile, InputFileData, BldFile, FurlFile, TwrFile RETURN END IF - ! sig_v - Viscous friction coefficiant (N-m s/rad): - CALL ReadVar( UnIn, InputFile, InputFileData%sig_v, "sig_v", "Viscous friction coefficient (N-m/(rad/s))", ErrStat2, ErrMsg2, UnEc) + ! M_FCD - Dynamic friction moment at null yaw rate proportional to yaw bearing shear force (N-m): + CALL ReadVar( UnIn, InputFile, InputFileData%M_FCD, "M_FCD", "Dynamic friction moment at null yaw rate proportional to yaw bearing shear force (N-m)", ErrStat2, ErrMsg2, UnEc) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) IF ( ErrStat >= AbortErrLev ) THEN CALL Cleanup() RETURN END IF + ! M_MCD - Dynamic friction moment at null yaw rate proportional to yaw bearing bending moment (N-m): + CALL ReadVar( UnIn, InputFile, InputFileData%M_MCD, "M_MCD", "Dynamic friction moment at null yaw rate proportional to yaw bearing bending moment (N-m)", ErrStat2, ErrMsg2, UnEc) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + IF ( ErrStat >= AbortErrLev ) THEN + CALL Cleanup() + RETURN + END IF + + ! sig_v - Linear viscous friction coefficiant (N-m s/rad): + CALL ReadVar( UnIn, InputFile, InputFileData%sig_v, "sig_v", "Linear viscous friction coefficient (N-m/(rad/s))", ErrStat2, ErrMsg2, UnEc) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + IF ( ErrStat >= AbortErrLev ) THEN + CALL Cleanup() + RETURN + END IF + + ! sig_v2 - Quadratic viscous friction coefficiant (N-m (s/rad)^2): + CALL ReadVar( UnIn, InputFile, InputFileData%sig_v2, "sig_v2", "Quadratic viscous friction coefficient (N-m/(rad/s)^2)", ErrStat2, ErrMsg2, UnEc) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + IF ( ErrStat >= AbortErrLev ) THEN + CALL Cleanup() + RETURN + END IF !---------------------- DRIVETRAIN ---------------------------------------------- CALL ReadCom( UnIn, InputFile, 'Section Header: Drivetrain', ErrStat2, ErrMsg2, UnEc ) @@ -4332,8 +4371,13 @@ SUBROUTINE ValidatePrimaryData( InputFileData, BD4Blades, Linearize, MHK, ErrSta ( InputFileData%YawFrctMod /= 2_IntKi ) .AND. ( InputFileData%YawFrctMod /= 3_IntKi )) & CALL SetErrStat( ErrID_Fatal, 'YawFrctMod must be 0, 1, 2, or 3',ErrStat,ErrMsg,RoutineName) IF ( InputFileData%M_CD < 0_R8Ki ) CALL SetErrStat( ErrID_Fatal, 'M_CD must be greater than or equal to 0.',ErrStat,ErrMsg,RoutineName ) + IF ( InputFileData%M_FCD < 0_R8Ki ) CALL SetErrStat( ErrID_Fatal, 'M_FCD must be greater than or equal to 0.',ErrStat,ErrMsg,RoutineName ) + IF ( InputFileData%M_MCD < 0_R8Ki ) CALL SetErrStat( ErrID_Fatal, 'M_MCD must be greater than or equal to 0.',ErrStat,ErrMsg,RoutineName ) IF ( InputFileData%M_CSmax < 0_R8Ki ) CALL SetErrStat( ErrID_Fatal, 'M_CSmax must be greater than or equal to 0.',ErrStat,ErrMsg,RoutineName ) + IF ( InputFileData%M_FCSmax < 0_R8Ki ) CALL SetErrStat( ErrID_Fatal, 'M_FCSmax must be greater than or equal to 0.',ErrStat,ErrMsg,RoutineName ) + IF ( InputFileData%M_MCSmax < 0_R8Ki ) CALL SetErrStat( ErrID_Fatal, 'M_MCSmax must be greater than or equal to 0.',ErrStat,ErrMsg,RoutineName ) IF ( InputFileData%sig_v < 0_R8Ki ) CALL SetErrStat( ErrID_Fatal, 'sig_v must be greater than or equal to 0.',ErrStat,ErrMsg,RoutineName ) + IF ( InputFileData%sig_v2 < 0_R8Ki ) CALL SetErrStat( ErrID_Fatal, 'sig_v2 must be greater than or equal to 0.',ErrStat,ErrMsg,RoutineName ) !bjj: since ED doesn't actually use OutFmt at this point, I'm going to remove this check and warning message !!!! ! Check that InputFileData%OutFmt is a valid format specifier and will fit over the column headings diff --git a/modules/elastodyn/src/ElastoDyn_Registry.txt b/modules/elastodyn/src/ElastoDyn_Registry.txt index 0ffcb4130..1dd0780be 100644 --- a/modules/elastodyn/src/ElastoDyn_Registry.txt +++ b/modules/elastodyn/src/ElastoDyn_Registry.txt @@ -169,8 +169,13 @@ typedef ^ ED_InputFile ReKi TeetSSSp - - - "Rotor-teeter soft-stop linear-spring typedef ^ ED_InputFile ReKi TeetHSSp - - - "Rotor-teeter hard-stop linear-spring constant" N-m/rad typedef ^ ED_InputFile IntKi YawFrctMod - - - "Identifier for YawFrctMod (0 [no friction], 1 [does not use Fz at bearing], 2 [does use Fz at bearing], or 3 [user defined model]" - typedef ^ ED_InputFile R8Ki M_CD - - - "Dynamic friction moment at null yaw rate" N-m +typedef ^ ED_InputFile R8Ki M_FCD - - - "Dynamic friction moment at null yaw rate proportional to yaw bearing shear force" N-m +typedef ^ ED_InputFile R8Ki M_MCD - - - "Dynamic friction moment at null yaw rate proportional to yaw bearing bending moment" N-m typedef ^ ED_InputFile R8Ki M_CSMAX - - - "Maximum Coulomb friction torque" N-m -typedef ^ ED_InputFile R8Ki sig_v - - - "Viscous friction coefficient" N-m/(rad/s) +typedef ^ ED_InputFile R8Ki M_FCSMAX - - - "Maximum Coulomb friction torque proportional to yaw bearing shear force" N-m +typedef ^ ED_InputFile R8Ki M_MCSMAX - - - "Maximum Coulomb friction torque proportional to yaw bearing bending moment" N-m +typedef ^ ED_InputFile R8Ki sig_v - - - "Linear viscous friction coefficient" N-m/(rad/s) +typedef ^ ED_InputFile R8Ki sig_v2 - - - "Quadratic viscous friction coefficient" N-m/(rad/s)^2 typedef ^ ED_InputFile ReKi GBoxEff - - - "Gearbox efficiency" % typedef ^ ED_InputFile ReKi GBRatio - - - "Gearbox ratio" - typedef ^ ED_InputFile ReKi DTTorSpr - - - "Drivetrain torsional spring" N-m/rad @@ -543,7 +548,8 @@ typedef ^ MiscVarType ReKi OgnlGeAzRo {:} - - "Original DOF_GeAz row in AugMat" typedef ^ MiscVarType R8Ki QD2T {:} - - "Solution (acceleration) vector; the first time derivative of QDT" typedef ^ MiscVarType Logical IgnoreMod - - - "whether to ignore the modulo in ED outputs (necessary for linearization perturbations)" - typedef ^ MiscVarType ReKi OgnlYawRow {:} - - "Original DOF_Yaw row in AugMat" - -typedef ^ MiscVarType ReKi FrcONcRt - - - "Fz acting on yaw bearing including inertial contributions" N +typedef ^ MiscVarType ReKi FrcONcRt 3 - - "Force acting on yaw bearing including inertial contributions" N +typedef ^ MiscVarType ReKi MomONcRt 3 - - "Moment acting on yaw bearing including inertial contributions" N-m typedef ^ MiscVarType ReKi YawFriMz - - - "External loading on yaw bearing not including inertial contributions" N-m # ..... Parameters ................................................................................................................ @@ -781,8 +787,13 @@ typedef ^ ParameterType LOGICAL BD4Blades - - - "flag to determine if BeamDyn is typedef ^ ParameterType LOGICAL RigidAero - - - "flag to determine if ElastoDyn if blades are rigid for aero -- when AeroDisk is used" - typedef ^ ParameterType IntKi YawFrctMod - - - "Identifier for YawFrctMod (0 [no friction], 1 [does not use Fz at bearing], or 2 [does use Fz at bearing]" - typedef ^ ParameterType R8Ki M_CD - - - "Dynamic friction moment at null yaw rate" N-m +typedef ^ ParameterType R8Ki M_FCD - - - "Dynamic friction moment at null yaw rate proportional to yaw bearing shear force" N-m +typedef ^ ParameterType R8Ki M_MCD - - - "Dynamic friction moment at null yaw rate proportional to yaw bearing bending moment" N-m typedef ^ ParameterType R8Ki M_CSMAX - - - "Maximum Coulomb friction torque" N-m -typedef ^ ParameterType R8Ki sig_v - - - "Viscous friction coefficient" N-m/(rad/s) +typedef ^ ParameterType R8Ki M_FCSMAX - - - "Maximum Coulomb friction torque proportional to yaw bearing shear force" N-m +typedef ^ ParameterType R8Ki M_MCSMAX - - - "Maximum Coulomb friction torque proportional to yaw bearing bending moment" N-m +typedef ^ ParameterType R8Ki sig_v - - - "Linear viscous friction coefficient" N-m/(rad/s) +typedef ^ ParameterType R8Ki sig_v2 - - - "Quadratic viscous friction coefficient" N-m/(rad/s)^2 #typedef ^ ParameterType R8Ki thr_omg - - - "Yaw rate stiction threshold" rad/s #typedef ^ ParameterType R8Ki thr_omgdot - - - "Yaw acceleration stiction threshold" rad/s^2 From fce5c223ae0d01a4eed18ecb90f0a9aa92a0dc89 Mon Sep 17 00:00:00 2001 From: Derek Slaughter Date: Thu, 12 Dec 2024 21:47:52 +0000 Subject: [PATCH 084/161] Allow , and ; in quoted words --- modules/nwtc-library/src/NWTC_IO.f90 | 29 +++++++++------------------- 1 file changed, 9 insertions(+), 20 deletions(-) diff --git a/modules/nwtc-library/src/NWTC_IO.f90 b/modules/nwtc-library/src/NWTC_IO.f90 index 602fad45d..b69b375d2 100644 --- a/modules/nwtc-library/src/NWTC_IO.f90 +++ b/modules/nwtc-library/src/NWTC_IO.f90 @@ -2079,6 +2079,9 @@ SUBROUTINE GetWords ( Line, Words, NumWords, NumFound, IgnoreQuotes ) LOGICAL :: InQuotes ! Flag indicating text is within quotes LOGICAL :: IgnoreQuotesLoc ! Local flag to ignore quotes + ! Initialize number of words found to zero if present + if (present(NumFound)) NumFound = 0 + ! If no text on line, return if (len_trim(Line) == 0) return @@ -2089,17 +2092,11 @@ SUBROUTINE GetWords ( Line, Words, NumWords, NumFound, IgnoreQuotes ) IgnoreQuotesLoc = .true. end if - ! Let's prefill the array with blanks. + ! Let's prefill the array with blanks do iWord = 1, NumWords Words(iWord) = ' ' end do - ! Initialize number of words found to zero if present - if (present(NumFound)) NumFound = 0 - - ! If no text on line, return - if (len_trim(Line) == 0) return - ! Initialize word index to first word iWord = 1 @@ -2121,7 +2118,7 @@ SUBROUTINE GetWords ( Line, Words, NumWords, NumFound, IgnoreQuotes ) if (IgnoreQuotesLoc .or. InQuotes) then InQuotes = .false. if (iChar > 0) then - ! If requested number of words found, exit + ! If requested number of words found, exit; otherwise, new word if (iWord == NumWords) exit iWord = iWord + 1 iChar = 0 @@ -2131,11 +2128,12 @@ SUBROUTINE GetWords ( Line, Words, NumWords, NumFound, IgnoreQuotes ) end if cycle - case (' ', Tab) ! Whitespace - ! If between quotes, keep whitespace; otherwise separate words + ! Word separator + case (',', ';', ' ', Tab) ! Comma, semicolon, space, tab + ! If in quotes, keep these in word if (.not. InQuotes) then if (iChar > 0) then - ! If requested number of words found, exit + ! If requested number of words found, exit; otherwise, new word if (iWord == NumWords) exit iWord = iWord + 1 iChar = 0 @@ -2143,15 +2141,6 @@ SUBROUTINE GetWords ( Line, Words, NumWords, NumFound, IgnoreQuotes ) cycle end if - case (',', ';') ! Comma, semicolon - ! Always separate words on these characters - if (iChar > 0) then - ! If requested number of words found, exit - if (iWord == NumWords) exit - iWord = iWord + 1 - iChar = 0 - end if - cycle end select ! Increment character index From 9717fe9caa8b0075696f39292dd36f3abfe66c61 Mon Sep 17 00:00:00 2001 From: Lu Wang Date: Thu, 12 Dec 2024 16:45:58 -0700 Subject: [PATCH 085/161] ED: For Yaw-bearing friction, add a new OmgCut input to define the region where the quadratic viscous friction should be linearized --- modules/elastodyn/src/ElastoDyn.f90 | 21 ++++++++++---------- modules/elastodyn/src/ElastoDyn_IO.f90 | 9 +++++++++ modules/elastodyn/src/ElastoDyn_Registry.txt | 2 ++ 3 files changed, 22 insertions(+), 10 deletions(-) diff --git a/modules/elastodyn/src/ElastoDyn.f90 b/modules/elastodyn/src/ElastoDyn.f90 index ad40583f6..759f9ef2a 100644 --- a/modules/elastodyn/src/ElastoDyn.f90 +++ b/modules/elastodyn/src/ElastoDyn.f90 @@ -3343,6 +3343,7 @@ SUBROUTINE SetPrimaryParameters( InitInp, p, InputFileData, ErrStat, ErrMsg ) p%M_MCSmax = InputFileData%M_MCSmax p%sig_v = InputFileData%sig_v p%sig_v2 = InputFileData%sig_v2 + p%OmgCut = InputFileData%OmgCut CALL AllocAry( p%TipMass, p%NumBl, 'TipMass', ErrStat, ErrMsg ) @@ -6421,7 +6422,7 @@ SUBROUTINE YawFriction( t, p, F, M, Mzz, Omg, OmgDot, YawFriMf ) REAL(ReKi), INTENT(OUT) :: YawFriMf !< The total friction torque (Coulomb + viscous). ! Local variables: - REAL(ReKi) :: temp, Fs, Mb ! It takes the value of Fz or -1. + REAL(ReKi) :: temp, Fs, Mb, Mf_vis ! temp takes the value of Fz or -1. SELECT CASE ( p%YawFrctMod ) @@ -6429,10 +6430,8 @@ SUBROUTINE YawFriction( t, p, F, M, Mzz, Omg, OmgDot, YawFriMf ) CASE ( 0_IntKi ) ! None! - YawFriMf = 0.0_ReKi - CASE ( 1_IntKi, 2_IntKi ) ! 1 = F and M not used. 2 = F and M used temp = -1.0_ReKi ! In the case of YawFrctMod=1 @@ -6445,27 +6444,29 @@ SUBROUTINE YawFriction( t, p, F, M, Mzz, Omg, OmgDot, YawFriMf ) Mb = SQRT(M(1)**2+M(2)**2) ! Effective bending moment on yaw bearing ENDIF - IF (EqualRealNos( Omg, 0.0_R8Ki ) )THEN + IF (EqualRealNos( Omg, 0.0_R8Ki )) THEN IF (EqualRealNos( OmgDot, 0.0_R8Ki )) THEN YawFriMf = -MIN( real(p%M_CSmax,ReKi) * ABS(temp) + real(p%M_FCSmax,ReKi) * Fs + real(p%M_MCSmax,ReKi) * Mb, ABS(real(Mzz,ReKi)) ) * SIGN(1.0_ReKi, real(Mzz,ReKi)) ELSE YawFriMf = -MIN( real(p%M_CD, ReKi) * ABS(temp) + real(p%M_FCD, ReKi) * Fs + real(p%M_MCD, ReKi) * Mb, ABS(real(Mzz,ReKi)) ) * SIGN(1.0_ReKi, real(Mzz,ReKi)) ENDIF ELSE - YawFriMf = ( real(p%M_CD,ReKi) * temp - real(p%M_FCD,ReKi) * Fs - real(p%M_MCD,ReKi) * Mb ) * sign(1.0_ReKi, real(Omg,ReKi)) & ! Coulomb friction - - real(p%sig_v,ReKi) * real(Omg,ReKi) - real(p%sig_v2,ReKi) * real(Omg,ReKi) * ABS(real(Omg,ReKi)) ! Viscous friction + ! Viscous friction + IF ( ABS(Omg) > p%OmgCut ) THEN ! Full quadratic viscous friction + Mf_vis = - real(p%sig_v,ReKi) * real(Omg,ReKi) - real(p%sig_v2,ReKi) * real(Omg,ReKi) * ABS(real(Omg,ReKi)) + ELSE ! Linearized viscous friction + Mf_vis = - ( real(p%sig_v,ReKi) + real(p%sig_v2,ReKi) * real(p%OmgCut,ReKi) ) * real(Omg,ReKi) + ENDIF + YawFriMf = ( real(p%M_CD,ReKi) * temp - real(p%M_FCD,ReKi) * Fs - real(p%M_MCD,ReKi) * Mb ) * sign(1.0_ReKi, real(Omg,ReKi)) & ! Coulomb friction + + Mf_vis ENDIF - CASE ( 3_IntKi ) ! User-defined YawFriMf model. >>>> NOT IMPLEMENTED YET - CALL UserYawFrict ( t, F, M, Mzz, Omg, OmgDot, p%RootName, YawFriMf ) - END SELECT - RETURN END SUBROUTINE YawFriction !---------------------------------------------------------------------------------------------------------------------------------- diff --git a/modules/elastodyn/src/ElastoDyn_IO.f90 b/modules/elastodyn/src/ElastoDyn_IO.f90 index e892c00ef..5bcd9a63b 100644 --- a/modules/elastodyn/src/ElastoDyn_IO.f90 +++ b/modules/elastodyn/src/ElastoDyn_IO.f90 @@ -3339,6 +3339,14 @@ SUBROUTINE ReadPrimaryFile( InputFile, InputFileData, BldFile, FurlFile, TwrFile RETURN END IF + ! OmgCut - Yaw angular velocity cutoff below which viscous friction is to be linearized (rad/s): + CALL ReadVar( UnIn, InputFile, InputFileData%OmgCut, "OmgCut", "Nacelle yaw angular velocity cutoff below which viscous friction is to be linearized (rad/s)", ErrStat2, ErrMsg2, UnEc) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + IF ( ErrStat >= AbortErrLev ) THEN + CALL Cleanup() + RETURN + END IF + !---------------------- DRIVETRAIN ---------------------------------------------- CALL ReadCom( UnIn, InputFile, 'Section Header: Drivetrain', ErrStat2, ErrMsg2, UnEc ) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) @@ -4378,6 +4386,7 @@ SUBROUTINE ValidatePrimaryData( InputFileData, BD4Blades, Linearize, MHK, ErrSta IF ( InputFileData%M_MCSmax < 0_R8Ki ) CALL SetErrStat( ErrID_Fatal, 'M_MCSmax must be greater than or equal to 0.',ErrStat,ErrMsg,RoutineName ) IF ( InputFileData%sig_v < 0_R8Ki ) CALL SetErrStat( ErrID_Fatal, 'sig_v must be greater than or equal to 0.',ErrStat,ErrMsg,RoutineName ) IF ( InputFileData%sig_v2 < 0_R8Ki ) CALL SetErrStat( ErrID_Fatal, 'sig_v2 must be greater than or equal to 0.',ErrStat,ErrMsg,RoutineName ) + IF ( InputFileData%OmgCut < 0_R8Ki ) CALL SetErrStat( ErrID_Fatal, 'OmgCut must be greater than or equal to 0.',ErrStat,ErrMsg,RoutineName ) !bjj: since ED doesn't actually use OutFmt at this point, I'm going to remove this check and warning message !!!! ! Check that InputFileData%OutFmt is a valid format specifier and will fit over the column headings diff --git a/modules/elastodyn/src/ElastoDyn_Registry.txt b/modules/elastodyn/src/ElastoDyn_Registry.txt index 1dd0780be..2210e9b57 100644 --- a/modules/elastodyn/src/ElastoDyn_Registry.txt +++ b/modules/elastodyn/src/ElastoDyn_Registry.txt @@ -176,6 +176,7 @@ typedef ^ ED_InputFile R8Ki M_FCSMAX - - - "Maximum typedef ^ ED_InputFile R8Ki M_MCSMAX - - - "Maximum Coulomb friction torque proportional to yaw bearing bending moment" N-m typedef ^ ED_InputFile R8Ki sig_v - - - "Linear viscous friction coefficient" N-m/(rad/s) typedef ^ ED_InputFile R8Ki sig_v2 - - - "Quadratic viscous friction coefficient" N-m/(rad/s)^2 +typedef ^ ED_InputFile R8Ki OmgCut - - - "Nacelle yaw angular velocity cutoff below which viscous friction is to be linearized" rad/s typedef ^ ED_InputFile ReKi GBoxEff - - - "Gearbox efficiency" % typedef ^ ED_InputFile ReKi GBRatio - - - "Gearbox ratio" - typedef ^ ED_InputFile ReKi DTTorSpr - - - "Drivetrain torsional spring" N-m/rad @@ -794,6 +795,7 @@ typedef ^ ParameterType R8Ki M_FCSMAX - - - "Maximum typedef ^ ParameterType R8Ki M_MCSMAX - - - "Maximum Coulomb friction torque proportional to yaw bearing bending moment" N-m typedef ^ ParameterType R8Ki sig_v - - - "Linear viscous friction coefficient" N-m/(rad/s) typedef ^ ParameterType R8Ki sig_v2 - - - "Quadratic viscous friction coefficient" N-m/(rad/s)^2 +typedef ^ ParameterType R8Ki OmgCut - - - "Nacelle yaw angular velocity cutoff below which viscous friction is to be linearized" rad/s #typedef ^ ParameterType R8Ki thr_omg - - - "Yaw rate stiction threshold" rad/s #typedef ^ ParameterType R8Ki thr_omgdot - - - "Yaw acceleration stiction threshold" rad/s^2 From e815575349922cb3fbbad8878860dd8e0752c498 Mon Sep 17 00:00:00 2001 From: Lu Wang Date: Sat, 14 Dec 2024 14:40:17 -0700 Subject: [PATCH 086/161] ED: Update the arguments of UserYawFrict to match the updated YawFriction subroutine --- modules/elastodyn/src/ED_UserSubs.f90 | 5 +- modules/elastodyn/src/ElastoDyn_Types.f90 | 58 +++++++++++++++++++++-- 2 files changed, 58 insertions(+), 5 deletions(-) diff --git a/modules/elastodyn/src/ED_UserSubs.f90 b/modules/elastodyn/src/ED_UserSubs.f90 index 47e2abd8f..29825d65f 100644 --- a/modules/elastodyn/src/ED_UserSubs.f90 +++ b/modules/elastodyn/src/ED_UserSubs.f90 @@ -101,7 +101,7 @@ SUBROUTINE UserTeet ( TeetDef, TeetRate, ZTime, DirRoot, TeetMom ) RETURN END SUBROUTINE UserTeet !======================================================================= -SUBROUTINE UserYawFrict ( ZTime, Fz, Mzz, Omg, OmgDot, DirRoot, YawFriMf ) +SUBROUTINE UserYawFrict ( ZTime, F, M, Mzz, Omg, OmgDot, DirRoot, YawFriMf ) ! This is a dummy routine for holding the place of a user-specified ! Yaw Friction. Modify this code to create your own device. @@ -115,7 +115,8 @@ SUBROUTINE UserYawFrict ( ZTime, Fz, Mzz, Omg, OmgDot, DirRoot, YawFriMf ) ! Passed Variables: REAL(DbKi), INTENT(IN ) :: ZTime ! Current simulation time, sec. -REAL(R8Ki), INTENT(IN ) :: Fz, Mzz ! Yaw Bering normal force (positive if upward) and torque, N and N*m +REAL(R8Ki), INTENT(IN ) :: F(3),M(3) ! Yaw bearing force and moment N and N*m +REAL(R8Ki), INTENT(IN ) :: Mzz ! External axial yaw bearing torque N*m REAL(R8Ki), INTENT(IN ) :: Omg ! Yaw rotational speed, rad/s. REAL(R8Ki), INTENT(IN ) :: OmgDot ! Yaw rotational acceleration, rad/s^2. diff --git a/modules/elastodyn/src/ElastoDyn_Types.f90 b/modules/elastodyn/src/ElastoDyn_Types.f90 index db494845e..adc0c3f8c 100644 --- a/modules/elastodyn/src/ElastoDyn_Types.f90 +++ b/modules/elastodyn/src/ElastoDyn_Types.f90 @@ -191,8 +191,14 @@ MODULE ElastoDyn_Types REAL(ReKi) :: TeetHSSp = 0.0_ReKi !< Rotor-teeter hard-stop linear-spring constant [N-m/rad] INTEGER(IntKi) :: YawFrctMod = 0_IntKi !< Identifier for YawFrctMod (0 [no friction], 1 [does not use Fz at bearing], 2 [does use Fz at bearing], or 3 [user defined model] [-] REAL(R8Ki) :: M_CD = 0.0_R8Ki !< Dynamic friction moment at null yaw rate [N-m] + REAL(R8Ki) :: M_FCD = 0.0_R8Ki !< Dynamic friction moment at null yaw rate proportional to yaw bearing shear force [N-m] + REAL(R8Ki) :: M_MCD = 0.0_R8Ki !< Dynamic friction moment at null yaw rate proportional to yaw bearing bending moment [N-m] REAL(R8Ki) :: M_CSMAX = 0.0_R8Ki !< Maximum Coulomb friction torque [N-m] - REAL(R8Ki) :: sig_v = 0.0_R8Ki !< Viscous friction coefficient [N-m/(rad/s)] + REAL(R8Ki) :: M_FCSMAX = 0.0_R8Ki !< Maximum Coulomb friction torque proportional to yaw bearing shear force [N-m] + REAL(R8Ki) :: M_MCSMAX = 0.0_R8Ki !< Maximum Coulomb friction torque proportional to yaw bearing bending moment [N-m] + REAL(R8Ki) :: sig_v = 0.0_R8Ki !< Linear viscous friction coefficient [N-m/(rad/s)] + REAL(R8Ki) :: sig_v2 = 0.0_R8Ki !< Quadratic viscous friction coefficient [N-m/(rad/s)^2] + REAL(R8Ki) :: OmgCut = 0.0_R8Ki !< Nacelle yaw angular velocity cutoff below which viscous friction is to be linearized [rad/s] REAL(ReKi) :: GBoxEff = 0.0_ReKi !< Gearbox efficiency [%] REAL(ReKi) :: GBRatio = 0.0_ReKi !< Gearbox ratio [-] REAL(ReKi) :: DTTorSpr = 0.0_ReKi !< Drivetrain torsional spring [N-m/rad] @@ -552,7 +558,8 @@ MODULE ElastoDyn_Types REAL(R8Ki) , DIMENSION(:), ALLOCATABLE :: QD2T !< Solution (acceleration) vector; the first time derivative of QDT [-] LOGICAL :: IgnoreMod = .false. !< whether to ignore the modulo in ED outputs (necessary for linearization perturbations) [-] REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: OgnlYawRow !< Original DOF_Yaw row in AugMat [-] - REAL(ReKi) :: FrcONcRt = 0.0_ReKi !< Fz acting on yaw bearing including inertial contributions [N] + REAL(ReKi) , DIMENSION(1:3) :: FrcONcRt = 0.0_ReKi !< Force acting on yaw bearing including inertial contributions [N] + REAL(ReKi) , DIMENSION(1:3) :: MomONcRt = 0.0_ReKi !< Moment acting on yaw bearing including inertial contributions [N-m] REAL(ReKi) :: YawFriMz = 0.0_ReKi !< External loading on yaw bearing not including inertial contributions [N-m] END TYPE ED_MiscVarType ! ======================= @@ -795,8 +802,14 @@ MODULE ElastoDyn_Types LOGICAL :: RigidAero = .false. !< flag to determine if ElastoDyn if blades are rigid for aero -- when AeroDisk is used [-] INTEGER(IntKi) :: YawFrctMod = 0_IntKi !< Identifier for YawFrctMod (0 [no friction], 1 [does not use Fz at bearing], or 2 [does use Fz at bearing] [-] REAL(R8Ki) :: M_CD = 0.0_R8Ki !< Dynamic friction moment at null yaw rate [N-m] + REAL(R8Ki) :: M_FCD = 0.0_R8Ki !< Dynamic friction moment at null yaw rate proportional to yaw bearing shear force [N-m] + REAL(R8Ki) :: M_MCD = 0.0_R8Ki !< Dynamic friction moment at null yaw rate proportional to yaw bearing bending moment [N-m] REAL(R8Ki) :: M_CSMAX = 0.0_R8Ki !< Maximum Coulomb friction torque [N-m] - REAL(R8Ki) :: sig_v = 0.0_R8Ki !< Viscous friction coefficient [N-m/(rad/s)] + REAL(R8Ki) :: M_FCSMAX = 0.0_R8Ki !< Maximum Coulomb friction torque proportional to yaw bearing shear force [N-m] + REAL(R8Ki) :: M_MCSMAX = 0.0_R8Ki !< Maximum Coulomb friction torque proportional to yaw bearing bending moment [N-m] + REAL(R8Ki) :: sig_v = 0.0_R8Ki !< Linear viscous friction coefficient [N-m/(rad/s)] + REAL(R8Ki) :: sig_v2 = 0.0_R8Ki !< Quadratic viscous friction coefficient [N-m/(rad/s)^2] + REAL(R8Ki) :: OmgCut = 0.0_R8Ki !< Nacelle yaw angular velocity cutoff below which viscous friction is to be linearized [rad/s] INTEGER(IntKi) :: BldNd_NumOuts = 0_IntKi !< Number of requested output channels per blade node (ED_AllBldNdOuts) [-] INTEGER(IntKi) :: BldNd_TotNumOuts = 0_IntKi !< Total number of requested output channels of blade node information (BldNd_NumOuts * BldNd_BlOutNd * BldNd_BladesOut -- ED_AllBldNdOuts) [-] TYPE(OutParmType) , DIMENSION(:), ALLOCATABLE :: BldNd_OutParam !< Names and units (and other characteristics) of all requested output parameters [-] @@ -1709,8 +1722,14 @@ subroutine ED_CopyInputFile(SrcInputFileData, DstInputFileData, CtrlCode, ErrSta DstInputFileData%TeetHSSp = SrcInputFileData%TeetHSSp DstInputFileData%YawFrctMod = SrcInputFileData%YawFrctMod DstInputFileData%M_CD = SrcInputFileData%M_CD + DstInputFileData%M_FCD = SrcInputFileData%M_FCD + DstInputFileData%M_MCD = SrcInputFileData%M_MCD DstInputFileData%M_CSMAX = SrcInputFileData%M_CSMAX + DstInputFileData%M_FCSMAX = SrcInputFileData%M_FCSMAX + DstInputFileData%M_MCSMAX = SrcInputFileData%M_MCSMAX DstInputFileData%sig_v = SrcInputFileData%sig_v + DstInputFileData%sig_v2 = SrcInputFileData%sig_v2 + DstInputFileData%OmgCut = SrcInputFileData%OmgCut DstInputFileData%GBoxEff = SrcInputFileData%GBoxEff DstInputFileData%GBRatio = SrcInputFileData%GBRatio DstInputFileData%DTTorSpr = SrcInputFileData%DTTorSpr @@ -2078,8 +2097,14 @@ subroutine ED_PackInputFile(RF, Indata) call RegPack(RF, InData%TeetHSSp) call RegPack(RF, InData%YawFrctMod) call RegPack(RF, InData%M_CD) + call RegPack(RF, InData%M_FCD) + call RegPack(RF, InData%M_MCD) call RegPack(RF, InData%M_CSMAX) + call RegPack(RF, InData%M_FCSMAX) + call RegPack(RF, InData%M_MCSMAX) call RegPack(RF, InData%sig_v) + call RegPack(RF, InData%sig_v2) + call RegPack(RF, InData%OmgCut) call RegPack(RF, InData%GBoxEff) call RegPack(RF, InData%GBRatio) call RegPack(RF, InData%DTTorSpr) @@ -2278,8 +2303,14 @@ subroutine ED_UnPackInputFile(RF, OutData) call RegUnpack(RF, OutData%TeetHSSp); if (RegCheckErr(RF, RoutineName)) return call RegUnpack(RF, OutData%YawFrctMod); if (RegCheckErr(RF, RoutineName)) return call RegUnpack(RF, OutData%M_CD); if (RegCheckErr(RF, RoutineName)) return + call RegUnpack(RF, OutData%M_FCD); if (RegCheckErr(RF, RoutineName)) return + call RegUnpack(RF, OutData%M_MCD); if (RegCheckErr(RF, RoutineName)) return call RegUnpack(RF, OutData%M_CSMAX); if (RegCheckErr(RF, RoutineName)) return + call RegUnpack(RF, OutData%M_FCSMAX); if (RegCheckErr(RF, RoutineName)) return + call RegUnpack(RF, OutData%M_MCSMAX); if (RegCheckErr(RF, RoutineName)) return call RegUnpack(RF, OutData%sig_v); if (RegCheckErr(RF, RoutineName)) return + call RegUnpack(RF, OutData%sig_v2); if (RegCheckErr(RF, RoutineName)) return + call RegUnpack(RF, OutData%OmgCut); if (RegCheckErr(RF, RoutineName)) return call RegUnpack(RF, OutData%GBoxEff); if (RegCheckErr(RF, RoutineName)) return call RegUnpack(RF, OutData%GBRatio); if (RegCheckErr(RF, RoutineName)) return call RegUnpack(RF, OutData%DTTorSpr); if (RegCheckErr(RF, RoutineName)) return @@ -4959,6 +4990,7 @@ subroutine ED_CopyMisc(SrcMiscData, DstMiscData, CtrlCode, ErrStat, ErrMsg) DstMiscData%OgnlYawRow = SrcMiscData%OgnlYawRow end if DstMiscData%FrcONcRt = SrcMiscData%FrcONcRt + DstMiscData%MomONcRt = SrcMiscData%MomONcRt DstMiscData%YawFriMz = SrcMiscData%YawFriMz end subroutine @@ -5018,6 +5050,7 @@ subroutine ED_PackMisc(RF, Indata) call RegPack(RF, InData%IgnoreMod) call RegPackAlloc(RF, InData%OgnlYawRow) call RegPack(RF, InData%FrcONcRt) + call RegPack(RF, InData%MomONcRt) call RegPack(RF, InData%YawFriMz) if (RegCheckErr(RF, RoutineName)) return end subroutine @@ -5042,6 +5075,7 @@ subroutine ED_UnPackMisc(RF, OutData) call RegUnpack(RF, OutData%IgnoreMod); if (RegCheckErr(RF, RoutineName)) return call RegUnpackAlloc(RF, OutData%OgnlYawRow); if (RegCheckErr(RF, RoutineName)) return call RegUnpack(RF, OutData%FrcONcRt); if (RegCheckErr(RF, RoutineName)) return + call RegUnpack(RF, OutData%MomONcRt); if (RegCheckErr(RF, RoutineName)) return call RegUnpack(RF, OutData%YawFriMz); if (RegCheckErr(RF, RoutineName)) return end subroutine @@ -5985,8 +6019,14 @@ subroutine ED_CopyParam(SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMsg) DstParamData%RigidAero = SrcParamData%RigidAero DstParamData%YawFrctMod = SrcParamData%YawFrctMod DstParamData%M_CD = SrcParamData%M_CD + DstParamData%M_FCD = SrcParamData%M_FCD + DstParamData%M_MCD = SrcParamData%M_MCD DstParamData%M_CSMAX = SrcParamData%M_CSMAX + DstParamData%M_FCSMAX = SrcParamData%M_FCSMAX + DstParamData%M_MCSMAX = SrcParamData%M_MCSMAX DstParamData%sig_v = SrcParamData%sig_v + DstParamData%sig_v2 = SrcParamData%sig_v2 + DstParamData%OmgCut = SrcParamData%OmgCut DstParamData%BldNd_NumOuts = SrcParamData%BldNd_NumOuts DstParamData%BldNd_TotNumOuts = SrcParamData%BldNd_TotNumOuts if (allocated(SrcParamData%BldNd_OutParam)) then @@ -6492,8 +6532,14 @@ subroutine ED_PackParam(RF, Indata) call RegPack(RF, InData%RigidAero) call RegPack(RF, InData%YawFrctMod) call RegPack(RF, InData%M_CD) + call RegPack(RF, InData%M_FCD) + call RegPack(RF, InData%M_MCD) call RegPack(RF, InData%M_CSMAX) + call RegPack(RF, InData%M_FCSMAX) + call RegPack(RF, InData%M_MCSMAX) call RegPack(RF, InData%sig_v) + call RegPack(RF, InData%sig_v2) + call RegPack(RF, InData%OmgCut) call RegPack(RF, InData%BldNd_NumOuts) call RegPack(RF, InData%BldNd_TotNumOuts) call RegPack(RF, allocated(InData%BldNd_OutParam)) @@ -6757,8 +6803,14 @@ subroutine ED_UnPackParam(RF, OutData) call RegUnpack(RF, OutData%RigidAero); if (RegCheckErr(RF, RoutineName)) return call RegUnpack(RF, OutData%YawFrctMod); if (RegCheckErr(RF, RoutineName)) return call RegUnpack(RF, OutData%M_CD); if (RegCheckErr(RF, RoutineName)) return + call RegUnpack(RF, OutData%M_FCD); if (RegCheckErr(RF, RoutineName)) return + call RegUnpack(RF, OutData%M_MCD); if (RegCheckErr(RF, RoutineName)) return call RegUnpack(RF, OutData%M_CSMAX); if (RegCheckErr(RF, RoutineName)) return + call RegUnpack(RF, OutData%M_FCSMAX); if (RegCheckErr(RF, RoutineName)) return + call RegUnpack(RF, OutData%M_MCSMAX); if (RegCheckErr(RF, RoutineName)) return call RegUnpack(RF, OutData%sig_v); if (RegCheckErr(RF, RoutineName)) return + call RegUnpack(RF, OutData%sig_v2); if (RegCheckErr(RF, RoutineName)) return + call RegUnpack(RF, OutData%OmgCut); if (RegCheckErr(RF, RoutineName)) return call RegUnpack(RF, OutData%BldNd_NumOuts); if (RegCheckErr(RF, RoutineName)) return call RegUnpack(RF, OutData%BldNd_TotNumOuts); if (RegCheckErr(RF, RoutineName)) return if (allocated(OutData%BldNd_OutParam)) deallocate(OutData%BldNd_OutParam) From 4cb25d84310e831c784cf2c1c48f7cad7de962e5 Mon Sep 17 00:00:00 2001 From: Lu Wang Date: Sat, 14 Dec 2024 18:09:33 -0700 Subject: [PATCH 087/161] ED: Fix single-precision build with extended yaw-friction modeling --- modules/elastodyn/src/ED_UserSubs.f90 | 2 +- modules/elastodyn/src/ElastoDyn.f90 | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/elastodyn/src/ED_UserSubs.f90 b/modules/elastodyn/src/ED_UserSubs.f90 index 29825d65f..42372a428 100644 --- a/modules/elastodyn/src/ED_UserSubs.f90 +++ b/modules/elastodyn/src/ED_UserSubs.f90 @@ -115,7 +115,7 @@ SUBROUTINE UserYawFrict ( ZTime, F, M, Mzz, Omg, OmgDot, DirRoot, YawFriMf ) ! Passed Variables: REAL(DbKi), INTENT(IN ) :: ZTime ! Current simulation time, sec. -REAL(R8Ki), INTENT(IN ) :: F(3),M(3) ! Yaw bearing force and moment N and N*m +REAL(ReKi), INTENT(IN ) :: F(3),M(3) ! Yaw bearing force and moment N and N*m REAL(R8Ki), INTENT(IN ) :: Mzz ! External axial yaw bearing torque N*m REAL(R8Ki), INTENT(IN ) :: Omg ! Yaw rotational speed, rad/s. REAL(R8Ki), INTENT(IN ) :: OmgDot ! Yaw rotational acceleration, rad/s^2. diff --git a/modules/elastodyn/src/ElastoDyn.f90 b/modules/elastodyn/src/ElastoDyn.f90 index 759f9ef2a..cbfdace5c 100644 --- a/modules/elastodyn/src/ElastoDyn.f90 +++ b/modules/elastodyn/src/ElastoDyn.f90 @@ -6415,7 +6415,7 @@ SUBROUTINE YawFriction( t, p, F, M, Mzz, Omg, OmgDot, YawFriMf ) ! Passed Variables: REAL(DbKi), INTENT(IN) :: t !< simulation time TYPE(ED_ParameterType), INTENT(IN) :: p !< parameters from the structural dynamics module - REAL(R8Ki), INTENT(IN ) :: F(3), M(3) !< Effective yaw bearing force and moment + REAL(ReKi), INTENT(IN ) :: F(3), M(3) !< Effective yaw bearing force and moment REAL(R8Ki), INTENT(IN ) :: Mzz !< External yaw bearing torque REAL(R8Ki), INTENT(IN ) :: Omg !< The yaw rate (rotational speed), x%QDT(DOF_Yaw). REAL(R8Ki), INTENT(IN ) :: OmgDot !< The yaw acceleration (derivative of rotational speed), x%QD2T(DOF_Yaw). @@ -6439,7 +6439,7 @@ SUBROUTINE YawFriction( t, p, F, M, Mzz, Omg, OmgDot, YawFriMf ) Mb = 0.0_ReKi IF (p%YawFrctMod .EQ. 2) THEN - temp = MIN(0.0_R8Ki, F(3)) ! In the case of YawFrctMod=2 + temp = MIN(0.0_ReKi, F(3)) ! In the case of YawFrctMod=2 Fs = SQRT(F(1)**2+F(2)**2) ! Effective shear force on yaw bearing Mb = SQRT(M(1)**2+M(2)**2) ! Effective bending moment on yaw bearing ENDIF From f42d536fc58a8657529a61f37a94ed1afaad6255 Mon Sep 17 00:00:00 2001 From: Lu Wang Date: Sat, 14 Dec 2024 18:10:42 -0700 Subject: [PATCH 088/161] Update r-test pointer --- reg_tests/r-test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reg_tests/r-test b/reg_tests/r-test index 16f421779..b3824f2d3 160000 --- a/reg_tests/r-test +++ b/reg_tests/r-test @@ -1 +1 @@ -Subproject commit 16f42177996ce19556d7848b72a123764a6c7297 +Subproject commit b3824f2d3a4cd4cb826aa4ac95b6e39a99e66d43 From b7f3f0993ce4db71bdc621b92de40e7a8d0bcc3a Mon Sep 17 00:00:00 2001 From: Emmanuel Branlard Date: Sun, 15 Dec 2024 12:04:09 -0500 Subject: [PATCH 089/161] AD: projection method should now depend on BEM_Mod --- modules/aerodyn/src/AeroDyn.f90 | 2 +- modules/openfast-library/src/FAST_Subs.f90 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/aerodyn/src/AeroDyn.f90 b/modules/aerodyn/src/AeroDyn.f90 index 252ebfa97..d43664041 100644 --- a/modules/aerodyn/src/AeroDyn.f90 +++ b/modules/aerodyn/src/AeroDyn.f90 @@ -3154,7 +3154,7 @@ subroutine SetInputsForBEMT(p, p_AD, u, RotInflow, m, indx, errStat, errMsg) !.......................... ! Set main geometry parameters (orientatioAnnulus, Twist, Toe, Cant, rLocal) !.......................... - ! TODO (EB): For harmonization between BEM and OLAF we should always compute R_li, r_Local, Twist, Toe, Cant + ! TODO (EB): For harmonization between BEM and OLAF we should always compute R_li, r_Local, Twist, Toe, Cant, drdz ! BEM would then switch below between an "orientationMomentum", either Annulus (R_li) or NoPitchSweepPitch (R_wi) if (p%AeroProjMod==APM_BEM_NoSweepPitchTwist .or. p%AeroProjMod==APM_LiftingLine) then diff --git a/modules/openfast-library/src/FAST_Subs.f90 b/modules/openfast-library/src/FAST_Subs.f90 index 9de6c3a71..816441536 100644 --- a/modules/openfast-library/src/FAST_Subs.f90 +++ b/modules/openfast-library/src/FAST_Subs.f90 @@ -732,7 +732,7 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, SED, BD, S endif ! Note: not passing tailfin position and orientation at init - Init%InData_AD%rotors(1)%AeroProjMod = APM_BEM_NoSweepPitchTwist + Init%InData_AD%rotors(1)%AeroProjMod = -1 ! -1 means AeroDyn will decide based on BEM_Mod ! Set pointers to flowfield IF (p_FAST%CompInflow == Module_IfW) Init%InData_AD%FlowField => Init%OutData_IfW%FlowField From 3d6fdd56cbbc0de85d366f1fe4d4bdc0c053882e Mon Sep 17 00:00:00 2001 From: Lu Wang Date: Sun, 15 Dec 2024 14:50:57 -0700 Subject: [PATCH 090/161] ED: Update ED documentation for the extended yaw-friction model --- .../user/elastodyn/figs/YawFrictionModel.jpg | Bin 12169 -> 78139 bytes docs/source/user/elastodyn/input.rst | 20 ++++-- docs/source/user/elastodyn/theory.rst | 63 +++++++++++++----- 3 files changed, 62 insertions(+), 21 deletions(-) diff --git a/docs/source/user/elastodyn/figs/YawFrictionModel.jpg b/docs/source/user/elastodyn/figs/YawFrictionModel.jpg index aa39021ee78577eedfdf67cb8cc94123caed3eaa..4a89c6ca0ae4dc814dbdd732aea2fba61a44da8e 100644 GIT binary patch literal 78139 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

~U?iD!q(8t^&)9-sua{63K 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 literal 12169 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 E0j@VqeE Date: Sun, 15 Dec 2024 15:00:41 -0700 Subject: [PATCH 091/161] ED: Update theory.rst to correct formatting errors --- docs/source/user/elastodyn/theory.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/source/user/elastodyn/theory.rst b/docs/source/user/elastodyn/theory.rst index 7808e50c7..936cb8427 100644 --- a/docs/source/user/elastodyn/theory.rst +++ b/docs/source/user/elastodyn/theory.rst @@ -168,7 +168,7 @@ The yaw-friction moment as a function of yaw rate (:math:`\omega`) is shown belo Yaw-friction model -When ``YawFrctMod``=1, the maximum static or dynamic Coulomb friction does not depend on the external load on the yaw bearing. The yaw-friction torque :math:`M_f` can be calculated as follows. +When ``YawFrctMod`` = 1, the maximum static or dynamic Coulomb friction does not depend on the external load on the yaw bearing. The yaw-friction torque :math:`M_f` can be calculated as follows. If :math:`\omega\neq0`, we have dynamic friction of the form .. math:: @@ -201,13 +201,13 @@ If :math:`\omega=0` and :math:`\dot{\omega}=0`, we have static Coulomb friction where :math:`\mu_s` is the static Coulomb friction coefficient. The product :math:`\mu_s\bar{D}` is specified in the input file through ``M_CSmax``. -When ``YawFrctMod``=2, the maximum static or dynamic Coulomb friction depends on the external load on the yaw bearing, with proportional contributions from :math:`|F_z|`, the magnitude of the bearing axial load, if :math:`F_z<0`, from the bearing shear force magnitude, :math:`\sqrt{F_x^2+F_y^2}`, and from the bearing bending moment magnitude, :math:`\sqrt{M_x^2+M_y^2}`. +When ``YawFrctMod`` = 2, the maximum static or dynamic Coulomb friction depends on the external load on the yaw bearing, with proportional contributions from :math:`|F_z|`, the magnitude of the bearing axial load, if :math:`F_z<0`, from the bearing shear force magnitude, :math:`\sqrt{F_x^2+F_y^2}`, and from the bearing bending moment magnitude, :math:`\sqrt{M_x^2+M_y^2}`. If :math:`\omega\neq0`, we have dynamic friction of the form .. math:: M_f = \left(\mu_d\bar{D}\text{min}(0,F_z)-\mu_{df}\bar{D}\sqrt{F_x^2+F_y^2}-\mu_{dm}\sqrt{M_x^2+M_y^2}\right)\times\text{sign}(\omega) - M_{f,vis}, -where :math:`M_{f,vis}` is defined in the same way as when ``YawFrctMod``=1. The product :math:`\mu_{df}\bar{D}` and :math:`\mu_{dm}` are specified in the input file through ``M_FCD`` and ``M_MCD``, respectively. +where :math:`M_{f,vis}` is defined in the same way as when ``YawFrctMod`` = 1. The product :math:`\mu_{df}\bar{D}` and :math:`\mu_{dm}` are specified in the input file through ``M_FCD`` and ``M_MCD``, respectively. If :math:`\omega=0` and :math:`\dot{\omega}\neq 0`, we have a modified dynamic Coulomb friction of the form .. math:: @@ -216,14 +216,14 @@ If :math:`\omega=0` and :math:`\dot{\omega}\neq 0`, we have a modified dynamic C If :math:`\omega=0` and :math:`\dot{\omega}=0`, we have static Coulomb friction of the form .. math:: - M_f = -\text{min}\left(\mu_s\bar{D}|\text{min}(0,F_z)| + \mu_{sf}\bar{D}\sqrt{F_x^2+F_y^2} + \mu_{sm}\sqrt{M_x^2+M_y^2},|M_z|\right)\times\text{sign}(M_z). + M_f = -\text{min}\left(\mu_s\bar{D}|\text{min}(0,F_z)| + \mu_{sf}\bar{D}\sqrt{F_x^2+F_y^2} + \mu_{sm}\sqrt{M_x^2+M_y^2},|M_z|\right)\times\text{sign}(M_z), where the product :math:`\mu_{sf}\bar{D}` and :math:`\mu_{sm}` are specified in the input file through ``M_FCSmax`` and ``M_MCSmax``, respectively. The static 'stiction' (where the static contribution exceeds the dynamic Coulomb friction) is only applied if both the yaw rotational velocity and acceleration at the current time-step are zero. The static portion of the friction is omitted if the rotational acceleration is not null. This is to account for the fact that a 'warm' joint may not feel stiction when crossing through zero velocity in a dynamic sense :cite:`ed-hammam2023`. -When :math:`\omega=0`, the yaw-bearing static or dynamic friction is formulated such that the frictional resistance opposes the external applied moment, :math:M_z`, without overcoming it. +When :math:`\omega=0`, the yaw-bearing static or dynamic friction is formulated such that the frictional resistance opposes the external applied moment, :math:`M_z`, without overcoming it. .. _ed_dev_notes: From c37912c36a68d450537a0e1a959d26567c2df1ac Mon Sep 17 00:00:00 2001 From: Lu Wang Date: Sun, 15 Dec 2024 17:24:14 -0700 Subject: [PATCH 092/161] ED: Additional input checks to make sure the static Coulomb friction coefficients for the yaw bearing are greater than or equal to their dynamic counterparts --- modules/elastodyn/src/ElastoDyn_IO.f90 | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/modules/elastodyn/src/ElastoDyn_IO.f90 b/modules/elastodyn/src/ElastoDyn_IO.f90 index 5bcd9a63b..5e32e39bd 100644 --- a/modules/elastodyn/src/ElastoDyn_IO.f90 +++ b/modules/elastodyn/src/ElastoDyn_IO.f90 @@ -4378,15 +4378,20 @@ SUBROUTINE ValidatePrimaryData( InputFileData, BD4Blades, Linearize, MHK, ErrSta IF ( ( InputFileData%YawFrctMod /= 0_IntKi ) .AND. ( InputFileData%YawFrctMod /= 1_IntKi ) .AND. & ( InputFileData%YawFrctMod /= 2_IntKi ) .AND. ( InputFileData%YawFrctMod /= 3_IntKi )) & CALL SetErrStat( ErrID_Fatal, 'YawFrctMod must be 0, 1, 2, or 3',ErrStat,ErrMsg,RoutineName) - IF ( InputFileData%M_CD < 0_R8Ki ) CALL SetErrStat( ErrID_Fatal, 'M_CD must be greater than or equal to 0.',ErrStat,ErrMsg,RoutineName ) - IF ( InputFileData%M_FCD < 0_R8Ki ) CALL SetErrStat( ErrID_Fatal, 'M_FCD must be greater than or equal to 0.',ErrStat,ErrMsg,RoutineName ) - IF ( InputFileData%M_MCD < 0_R8Ki ) CALL SetErrStat( ErrID_Fatal, 'M_MCD must be greater than or equal to 0.',ErrStat,ErrMsg,RoutineName ) - IF ( InputFileData%M_CSmax < 0_R8Ki ) CALL SetErrStat( ErrID_Fatal, 'M_CSmax must be greater than or equal to 0.',ErrStat,ErrMsg,RoutineName ) + IF ( InputFileData%M_CD < 0_R8Ki ) CALL SetErrStat( ErrID_Fatal, 'M_CD must be greater than or equal to 0.', ErrStat,ErrMsg,RoutineName ) + IF ( InputFileData%M_FCD < 0_R8Ki ) CALL SetErrStat( ErrID_Fatal, 'M_FCD must be greater than or equal to 0.', ErrStat,ErrMsg,RoutineName ) + IF ( InputFileData%M_MCD < 0_R8Ki ) CALL SetErrStat( ErrID_Fatal, 'M_MCD must be greater than or equal to 0.', ErrStat,ErrMsg,RoutineName ) + IF ( InputFileData%M_CSmax < 0_R8Ki ) CALL SetErrStat( ErrID_Fatal, 'M_CSmax must be greater than or equal to 0.', ErrStat,ErrMsg,RoutineName ) IF ( InputFileData%M_FCSmax < 0_R8Ki ) CALL SetErrStat( ErrID_Fatal, 'M_FCSmax must be greater than or equal to 0.',ErrStat,ErrMsg,RoutineName ) IF ( InputFileData%M_MCSmax < 0_R8Ki ) CALL SetErrStat( ErrID_Fatal, 'M_MCSmax must be greater than or equal to 0.',ErrStat,ErrMsg,RoutineName ) - IF ( InputFileData%sig_v < 0_R8Ki ) CALL SetErrStat( ErrID_Fatal, 'sig_v must be greater than or equal to 0.',ErrStat,ErrMsg,RoutineName ) - IF ( InputFileData%sig_v2 < 0_R8Ki ) CALL SetErrStat( ErrID_Fatal, 'sig_v2 must be greater than or equal to 0.',ErrStat,ErrMsg,RoutineName ) - IF ( InputFileData%OmgCut < 0_R8Ki ) CALL SetErrStat( ErrID_Fatal, 'OmgCut must be greater than or equal to 0.',ErrStat,ErrMsg,RoutineName ) + IF ( InputFileData%sig_v < 0_R8Ki ) CALL SetErrStat( ErrID_Fatal, 'sig_v must be greater than or equal to 0.', ErrStat,ErrMsg,RoutineName ) + IF ( InputFileData%sig_v2 < 0_R8Ki ) CALL SetErrStat( ErrID_Fatal, 'sig_v2 must be greater than or equal to 0.', ErrStat,ErrMsg,RoutineName ) + IF ( InputFileData%OmgCut < 0_R8Ki ) CALL SetErrStat( ErrID_Fatal, 'OmgCut must be greater than or equal to 0.', ErrStat,ErrMsg,RoutineName ) + + ! The static Coulomb friction coefficients must be greater than or equal to their dynamic counterparts. + IF ( InputFileData%M_CSmax < InputFileData%M_CD ) CALL SetErrStat( ErrID_Fatal, 'M_CSmax must be greater than or equal to M_CD.', ErrStat,ErrMsg,RoutineName ) + IF ( InputFileData%M_FCSmax < InputFileData%M_FCD ) CALL SetErrStat( ErrID_Fatal, 'M_FCSmax must be greater than or equal to M_FCD.',ErrStat,ErrMsg,RoutineName ) + IF ( InputFileData%M_MCSmax < InputFileData%M_MCD ) CALL SetErrStat( ErrID_Fatal, 'M_MCSmax must be greater than or equal to M_MCD.',ErrStat,ErrMsg,RoutineName ) !bjj: since ED doesn't actually use OutFmt at this point, I'm going to remove this check and warning message !!!! ! Check that InputFileData%OutFmt is a valid format specifier and will fit over the column headings From 3408f0f7a95afb11d0a1ed1e11a2f4cbb164e5e3 Mon Sep 17 00:00:00 2001 From: andrew-platt Date: Mon, 16 Dec 2024 10:17:17 -0700 Subject: [PATCH 093/161] docs: minor format fix --- docs/source/user/elastodyn/theory.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/user/elastodyn/theory.rst b/docs/source/user/elastodyn/theory.rst index 936cb8427..ae881d842 100644 --- a/docs/source/user/elastodyn/theory.rst +++ b/docs/source/user/elastodyn/theory.rst @@ -158,7 +158,7 @@ The total moment on the given degree of freedom is: .. _ed_yawfriction_theory: Yaw-friction model ------------- +------------------ A yaw-friction model is implemented in ElastoDyn based on a Coulomb-viscous approach. The yaw-friction moment as a function of yaw rate (:math:`\omega`) is shown below in :numref:`figYawFriction` From a62d8772ee378d1ebb44a8f8c3d5beae9e8293d6 Mon Sep 17 00:00:00 2001 From: Derek Slaughter Date: Mon, 16 Dec 2024 17:57:17 +0000 Subject: [PATCH 094/161] Use INTENT(IN) for IgnoreQuotes in GetWords (NWTC_IO) --- modules/nwtc-library/src/NWTC_IO.f90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/nwtc-library/src/NWTC_IO.f90 b/modules/nwtc-library/src/NWTC_IO.f90 index b69b375d2..25565afe9 100644 --- a/modules/nwtc-library/src/NWTC_IO.f90 +++ b/modules/nwtc-library/src/NWTC_IO.f90 @@ -2070,7 +2070,7 @@ SUBROUTINE GetWords ( Line, Words, NumWords, NumFound, IgnoreQuotes ) CHARACTER(*), INTENT(IN) :: Line !< The string to search. CHARACTER(*), INTENT(OUT) :: Words(NumWords) !< The array of found words. INTEGER, OPTIONAL, INTENT(OUT) :: NumFound !< The number of words found - LOGICAL, OPTIONAL, INTENT(OUT) :: IgnoreQuotes !< Flag to ignore quotes (process as whitespace) + LOGICAL, OPTIONAL, INTENT(IN) :: IgnoreQuotes !< Flag to ignore quotes (process as whitespace) INTEGER :: iWord ! Word index. INTEGER :: i ! Character index in line. From 09b1e426812bc8301e8bc90f9205906dc5b36832 Mon Sep 17 00:00:00 2001 From: andrew-platt Date: Mon, 16 Dec 2024 10:44:29 -0700 Subject: [PATCH 095/161] docs: ed, minor formatting of equations. --- docs/source/user/elastodyn/theory.rst | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/source/user/elastodyn/theory.rst b/docs/source/user/elastodyn/theory.rst index ae881d842..d4756dd0c 100644 --- a/docs/source/user/elastodyn/theory.rst +++ b/docs/source/user/elastodyn/theory.rst @@ -172,51 +172,51 @@ When ``YawFrctMod`` = 1, the maximum static or dynamic Coulomb friction does not If :math:`\omega\neq0`, we have dynamic friction of the form .. math:: - M_f = -(\mu_d\bar{D})\times\text{sign}(\omega) - M_{f,vis}, + M_f = -(\mu_d\bar{D})\cdot\textrm{sign}(\omega) - M_{f,vis}, where :math:`\bar{D}` is the effective yaw-bearing diameter and :math:`\mu_d` is the dynamic Coulomb friction coefficient. Their product, :math:`\mu_d\bar{D}`, is specified in the input file through ``M_CD``. The first term on the right-hand side is the dynamic Coulomb friction. The viscous friction, :math:`M_{f,vis}`, is of the form .. math:: - M_{f,vis} = \sigma_v\omega + \sigma_{v2}\omega|\omega|\text{ if }|\omega|\ge\omega_c, + M_{f,vis} = \sigma_v\omega + \sigma_{v2}\omega\left|\omega\right|\qquad\qquad\text{if}~\left|\omega\right|\ge\omega_c, or .. math:: - M_{f,vis} = (\sigma_v + \sigma_{v2}\omega_c)\omega\text{ if }|\omega|\le\omega_c, + M_{f,vis} = (\sigma_v + \sigma_{v2}\omega_c)\omega\qquad\qquad\text{if}~\left|\omega\right|\le\omega_c, where :math:`\sigma_v` and :math:`\sigma_{v2}` are the linear and quadratic viscous friction coefficients and :math:`\omega_c` is the cutoff yaw rate below which viscous friction is linearized. Setting :math:`\omega_c=0` disables the linearization of viscous friction. If :math:`\omega=0` and :math:`\dot{\omega}\neq 0`, we have a slightly modified dynamic Coulomb friction of the form .. math:: - M_f = -\text{min}(\mu_d\bar{D},|M_z|)\times\text{sign}(M_z), + M_f = -\textrm{min}\!\left(\mu_d\bar{D},\left|M_z\right|\right)\cdot\textrm{sign}(M_z), where :math:`M_z` is the external yaw torque. If :math:`\omega=0` and :math:`\dot{\omega}=0`, we have static Coulomb friction of the form .. math:: - M_f = -\text{min}(\mu_s\bar{D},|M_z|)\times\text{sign}(M_z), + M_f = -\textrm{min}\!\left(\mu_s\bar{D},\left|M_z\right|\right)\cdot\textrm{sign}(M_z), where :math:`\mu_s` is the static Coulomb friction coefficient. The product :math:`\mu_s\bar{D}` is specified in the input file through ``M_CSmax``. -When ``YawFrctMod`` = 2, the maximum static or dynamic Coulomb friction depends on the external load on the yaw bearing, with proportional contributions from :math:`|F_z|`, the magnitude of the bearing axial load, if :math:`F_z<0`, from the bearing shear force magnitude, :math:`\sqrt{F_x^2+F_y^2}`, and from the bearing bending moment magnitude, :math:`\sqrt{M_x^2+M_y^2}`. +When ``YawFrctMod`` = 2, the maximum static or dynamic Coulomb friction depends on the external load on the yaw bearing, with proportional contributions from :math:`\left|F_z\right|`, the magnitude of the bearing axial load, if :math:`F_z<0`, from the bearing shear force magnitude, :math:`\sqrt{F_x^2+F_y^2}`, and from the bearing bending moment magnitude, :math:`\sqrt{M_x^2+M_y^2}`. If :math:`\omega\neq0`, we have dynamic friction of the form .. math:: - M_f = \left(\mu_d\bar{D}\text{min}(0,F_z)-\mu_{df}\bar{D}\sqrt{F_x^2+F_y^2}-\mu_{dm}\sqrt{M_x^2+M_y^2}\right)\times\text{sign}(\omega) - M_{f,vis}, + M_f = \left(\mu_d\bar{D}\cdot\textrm{min}\!\left(0,F_z\right)-\mu_{df}\bar{D}\sqrt{F_x^2+F_y^2}-\mu_{dm}\sqrt{M_x^2+M_y^2}\right)\cdot\textrm{sign}(\omega) - M_{f,vis}, where :math:`M_{f,vis}` is defined in the same way as when ``YawFrctMod`` = 1. The product :math:`\mu_{df}\bar{D}` and :math:`\mu_{dm}` are specified in the input file through ``M_FCD`` and ``M_MCD``, respectively. If :math:`\omega=0` and :math:`\dot{\omega}\neq 0`, we have a modified dynamic Coulomb friction of the form .. math:: - M_f = -\text{min}\left(\mu_d\bar{D}|\text{min}(0,F_z)| + \mu_{df}\bar{D}\sqrt{F_x^2+F_y^2} + \mu_{dm}\sqrt{M_x^2+M_y^2},|M_z|\right)\times\text{sign}(M_z). + M_f = -\textrm{min}\!\left(\mu_d\bar{D}\left|\textrm{min}(0,F_z)\right| + \mu_{df}\bar{D}\sqrt{F_x^2+F_y^2} + \mu_{dm}\sqrt{M_x^2+M_y^2},\left|M_z\right|\right)\cdot\textrm{sign}(M_z). If :math:`\omega=0` and :math:`\dot{\omega}=0`, we have static Coulomb friction of the form .. math:: - M_f = -\text{min}\left(\mu_s\bar{D}|\text{min}(0,F_z)| + \mu_{sf}\bar{D}\sqrt{F_x^2+F_y^2} + \mu_{sm}\sqrt{M_x^2+M_y^2},|M_z|\right)\times\text{sign}(M_z), + M_f = -\textrm{min}\!\left(\mu_s\bar{D}\left|\textrm{min}(0,F_z)\right| + \mu_{sf}\bar{D}\sqrt{F_x^2+F_y^2} + \mu_{sm}\sqrt{M_x^2+M_y^2},\left|M_z\right|\right)\cdot\textrm{sign}(M_z), where the product :math:`\mu_{sf}\bar{D}` and :math:`\mu_{sm}` are specified in the input file through ``M_FCSmax`` and ``M_MCSmax``, respectively. From 0e99c524043c8dfedc5200a025811d4513364acf Mon Sep 17 00:00:00 2001 From: Derek Slaughter Date: Tue, 17 Dec 2024 15:12:41 +0000 Subject: [PATCH 096/161] Change openfast_cpp_driver to openfast_lib_driver to better separate openfast-cpp from the OpenFAST library C++ driver --- .github/workflows/automated-dev-tests.yml | 2 +- glue-codes/openfast/CMakeLists.txt | 6 +++--- reg_tests/CMakeLists.txt | 2 +- reg_tests/CTestList.cmake | 10 +++++----- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/.github/workflows/automated-dev-tests.yml b/.github/workflows/automated-dev-tests.yml index 92402268b..9028693e2 100644 --- a/.github/workflows/automated-dev-tests.yml +++ b/.github/workflows/automated-dev-tests.yml @@ -243,7 +243,7 @@ jobs: - name: Build OpenFAST C-Interfaces working-directory: ${{runner.workspace}}/openfast/build run: | - cmake --build . --target openfastlib openfast_cpp_driver openfastcpp aerodyn_inflow_c_binding moordyn_c_binding ifw_c_binding hydrodyn_c_binding regression_test_controllers + cmake --build . --target openfastlib openfast_lib_driver openfastcpp aerodyn_inflow_c_binding moordyn_c_binding ifw_c_binding hydrodyn_c_binding regression_test_controllers - name: Cache the workspace uses: actions/cache@v4 with: diff --git a/glue-codes/openfast/CMakeLists.txt b/glue-codes/openfast/CMakeLists.txt index 402a790f6..a742b5972 100644 --- a/glue-codes/openfast/CMakeLists.txt +++ b/glue-codes/openfast/CMakeLists.txt @@ -34,10 +34,10 @@ install(TARGETS openfast RUNTIME DESTINATION bin) if(BUILD_OPENFAST_LIB_DRIVER) - add_executable(openfast_cpp_driver src/FAST_Prog.cpp src/FastLibAPI.cpp) - target_link_libraries(openfast_cpp_driver openfastlib) + add_executable(openfast_lib_driver src/FAST_Prog.cpp src/FastLibAPI.cpp) + target_link_libraries(openfast_lib_driver openfastlib) - install(TARGETS openfast_cpp_driver + install(TARGETS openfast_lib_driver RUNTIME DESTINATION bin) endif() diff --git a/reg_tests/CMakeLists.txt b/reg_tests/CMakeLists.txt index 268e188f9..70cbf6717 100644 --- a/reg_tests/CMakeLists.txt +++ b/reg_tests/CMakeLists.txt @@ -42,7 +42,7 @@ option(CTEST_NO_RUN_FLAG "Complete the regression test comparison but do not ex # Set the OpenFAST executable configuration option and default set(CTEST_OPENFAST_EXECUTABLE "${CMAKE_BINARY_DIR}/glue-codes/openfast/openfast${CMAKE_EXECUTABLE_SUFFIX}" CACHE FILEPATH "Specify the OpenFAST executable to use in testing.") -if(BUILD_OPENFAST_CPP_API) +if(BUILD_OPENFAST_CPP_DRIVER) # Set the OpenFAST executable configuration option and default set(CTEST_OPENFASTCPP_EXECUTABLE "${CMAKE_BINARY_DIR}/glue-codes/openfast-cpp/openfastcpp${CMAKE_EXECUTABLE_SUFFIX}" CACHE FILEPATH "Specify the OpenFAST C++ executable to use in testing.") endif() diff --git a/reg_tests/CTestList.cmake b/reg_tests/CTestList.cmake index b9c6dbf88..163fa4f35 100644 --- a/reg_tests/CTestList.cmake +++ b/reg_tests/CTestList.cmake @@ -85,7 +85,7 @@ endfunction(of_regression) function(of_fastlib_regression TESTNAME LABEL) set(TEST_SCRIPT "${CMAKE_CURRENT_LIST_DIR}/executeOpenfastRegressionCase.py") - set(OPENFAST_EXECUTABLE "${CMAKE_BINARY_DIR}/glue-codes/openfast/openfast_cpp_driver") + set(OPENFAST_EXECUTABLE "${CMAKE_BINARY_DIR}/glue-codes/openfast/openfast_lib_driver") set(SOURCE_DIRECTORY "${CMAKE_CURRENT_LIST_DIR}/..") set(BUILD_DIRECTORY "${CTEST_BINARY_DIR}/glue-codes/openfast") regression(${TEST_SCRIPT} ${OPENFAST_EXECUTABLE} ${SOURCE_DIRECTORY} ${BUILD_DIRECTORY} "${TESTNAME}_fastlib" "${LABEL}" ${TESTNAME}) @@ -285,15 +285,15 @@ of_regression("MHK_RM1_Floating" "openfast;elastodyn;aerod of_regression("Tailfin_FreeYaw1DOF_PolarBased" "openfast;elastodyn;aerodyn15") # OpenFAST C++ API test -if(BUILD_OPENFAST_CFD_DRIVER) +if(BUILD_OPENFAST_CPP_DRIVER) of_cpp_interface_regression("5MW_Land_DLL_WTurb_cpp" "openfast;fastlib;cpp") endif() -# OpenFAST C++ Driver test for OpenFAST Library +# OpenFAST Driver test for OpenFAST C++ Library # This tests the FAST Library and FAST_Library.h -if(BUILD_OPENFAST_CPP_DRIVER) +if(BUILD_OPENFAST_LIB_DRIVER) of_fastlib_regression("AWT_YFree_WSt" "fastlib;elastodyn;aerodyn15;servodyn") -endif(BUILD_OPENFAST_CPP_DRIVER) +endif() # OpenFAST Python API test of_regression_py("5MW_Land_DLL_WTurb_py" "openfast;fastlib;python;elastodyn;aerodyn15;servodyn") From 8193c7a732aa9af48d57449b88618d04d0c19fef Mon Sep 17 00:00:00 2001 From: andrew-platt Date: Wed, 18 Dec 2024 14:48:49 -0700 Subject: [PATCH 097/161] Disable LiDAR in IfW at FAST.Farm level --- modules/inflowwind/src/InflowWind.f90 | 11 ++++++++++- modules/inflowwind/src/InflowWind.txt | 1 + modules/inflowwind/src/InflowWind_Types.f90 | 7 +++++++ modules/openfast-library/src/FAST_Subs.f90 | 1 + 4 files changed, 19 insertions(+), 1 deletion(-) diff --git a/modules/inflowwind/src/InflowWind.f90 b/modules/inflowwind/src/InflowWind.f90 index 103ddb948..9c0c0276f 100644 --- a/modules/inflowwind/src/InflowWind.f90 +++ b/modules/inflowwind/src/InflowWind.f90 @@ -224,7 +224,16 @@ SUBROUTINE InflowWind_Init( InitInp, InputGuess, p, ContStates, DiscStates, Cons p%lidar%PulseSpacing = InputFileData%PulseSpacing p%lidar%URefLid = InputFileData%URefLid p%lidar%ConsiderHubMotion = InputFileData%ConsiderHubMotion - + + ! Disable Lidar if not allowed (FAST.Farm doesn't allow this) + if (InitInp%LidarDisable) then + if (p%lidar%SensorType /= SensorType_None) then + call WrScr(' WARNING: LiDAR cannot be used with this instance of InflowWind (not usable with FAST.Farm).') + call WrScr(' --> Disabling LiDAR.') + p%lidar%SensorType = SensorType_None + end if + endif + CALL Lidar_Init( InitInp, InputGuess, p, ContStates, DiscStates, ConstrStateGuess, OtherStates, & y, m, TimeInterval, InitOutData, TmpErrStat, TmpErrMsg ) diff --git a/modules/inflowwind/src/InflowWind.txt b/modules/inflowwind/src/InflowWind.txt index 3ab094098..5fbe8e6c0 100644 --- a/modules/inflowwind/src/InflowWind.txt +++ b/modules/inflowwind/src/InflowWind.txt @@ -101,6 +101,7 @@ typedef ^ ^ ReKi WtrDpth typedef ^ ^ ReKi MSL2SWL - - - "Mean sea level to still water level" m typedef ^ ^ IntKi BoxExceedAllowIdx - -1 - "Extrapolate winds outside box starting at this index (for OLAF wakes and LidarSim)" - typedef ^ ^ LOGICAL BoxExceedAllowF - .FALSE. - "Flag to allow Extrapolation winds outside box starting at this index (for OLAF wakes and LidarSim)" - +typedef ^ ^ LOGICAL LidarDisable - .true. - "Disable LiDAR for this instance of InflowWind? (FAST.Farm not compatible)" - # Init Output diff --git a/modules/inflowwind/src/InflowWind_Types.f90 b/modules/inflowwind/src/InflowWind_Types.f90 index 605bfe222..8ac1bfc93 100644 --- a/modules/inflowwind/src/InflowWind_Types.f90 +++ b/modules/inflowwind/src/InflowWind_Types.f90 @@ -119,6 +119,7 @@ MODULE InflowWind_Types REAL(ReKi) :: MSL2SWL !< Mean sea level to still water level [m] INTEGER(IntKi) :: BoxExceedAllowIdx = -1 !< Extrapolate winds outside box starting at this index (for OLAF wakes and LidarSim) [-] LOGICAL :: BoxExceedAllowF = .FALSE. !< Flag to allow Extrapolation winds outside box starting at this index (for OLAF wakes and LidarSim) [-] + LOGICAL :: LidarDisable = .true. !< Disable LiDAR for this instance of InflowWind? (FAST.Farm not compatible) [-] END TYPE InflowWind_InitInputType ! ======================= ! ========= InflowWind_InitOutputType ======= @@ -1110,6 +1111,7 @@ SUBROUTINE InflowWind_CopyInitInput( SrcInitInputData, DstInitInputData, CtrlCod DstInitInputData%MSL2SWL = SrcInitInputData%MSL2SWL DstInitInputData%BoxExceedAllowIdx = SrcInitInputData%BoxExceedAllowIdx DstInitInputData%BoxExceedAllowF = SrcInitInputData%BoxExceedAllowF + DstInitInputData%LidarDisable = SrcInitInputData%LidarDisable END SUBROUTINE InflowWind_CopyInitInput SUBROUTINE InflowWind_DestroyInitInput( InitInputData, ErrStat, ErrMsg, DEALLOCATEpointers ) @@ -1263,6 +1265,7 @@ SUBROUTINE InflowWind_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat Re_BufSz = Re_BufSz + 1 ! MSL2SWL Int_BufSz = Int_BufSz + 1 ! BoxExceedAllowIdx Int_BufSz = Int_BufSz + 1 ! BoxExceedAllowF + Int_BufSz = Int_BufSz + 1 ! LidarDisable IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -1438,6 +1441,8 @@ SUBROUTINE InflowWind_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat Int_Xferred = Int_Xferred + 1 IntKiBuf(Int_Xferred) = TRANSFER(InData%BoxExceedAllowF, IntKiBuf(1)) Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = TRANSFER(InData%LidarDisable, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 END SUBROUTINE InflowWind_PackInitInput SUBROUTINE InflowWind_UnPackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) @@ -1662,6 +1667,8 @@ SUBROUTINE InflowWind_UnPackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrS Int_Xferred = Int_Xferred + 1 OutData%BoxExceedAllowF = TRANSFER(IntKiBuf(Int_Xferred), OutData%BoxExceedAllowF) Int_Xferred = Int_Xferred + 1 + OutData%LidarDisable = TRANSFER(IntKiBuf(Int_Xferred), OutData%LidarDisable) + Int_Xferred = Int_Xferred + 1 END SUBROUTINE InflowWind_UnPackInitInput SUBROUTINE InflowWind_CopyInitOutput( SrcInitOutputData, DstInitOutputData, CtrlCode, ErrStat, ErrMsg ) diff --git a/modules/openfast-library/src/FAST_Subs.f90 b/modules/openfast-library/src/FAST_Subs.f90 index 9e0af8c93..09f532a02 100644 --- a/modules/openfast-library/src/FAST_Subs.f90 +++ b/modules/openfast-library/src/FAST_Subs.f90 @@ -583,6 +583,7 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, END IF ! lidar + Init%InData_IfW%LidarDisable = .false. ! allowed with OF, but not FF Init%InData_IfW%lidar%Tmax = p_FAST%TMax Init%InData_IfW%lidar%HubPosition = ED%y%HubPtMotion%Position(:,1) From 5c30c4233999af01b46bca7f88296efda271c954 Mon Sep 17 00:00:00 2001 From: andrew-platt Date: Wed, 18 Dec 2024 15:45:40 -0700 Subject: [PATCH 098/161] Update release notes and changelog for 3.5.5 --- docs/changelogs/v3.5.5.md | 105 ++++++++++++++++++++++++++++++++ docs/conf.py | 2 +- docs/source/user/api_change.rst | 6 ++ 3 files changed, 112 insertions(+), 1 deletion(-) create mode 100644 docs/changelogs/v3.5.5.md diff --git a/docs/changelogs/v3.5.5.md b/docs/changelogs/v3.5.5.md new file mode 100644 index 000000000..8043f3a3b --- /dev/null +++ b/docs/changelogs/v3.5.5.md @@ -0,0 +1,105 @@ +**Feature or improvement description** +Pull request to merge `rc-3.5.5` into `main` and create a tagged release for v3.5.5. + +See the milestone and project pages for additional information + + https://github.com/OpenFAST/openfast/milestone/15 + +Test results, if applicable +See GitHub Actions + +### Release checklist: +- [ ] Update the documentation version in docs/conf.py +- [ ] Update the versions in docs/source/user/api_change.rst +- [ ] Verify readthedocs builds correctly +- [ ] Create a tag in OpenFAST +- [ ] Create a merge commit in r-test and add a corresponding annotated tag +- [ ] Compile executables for Windows builds + - [ ] AeroDyn_Driver_x64.exe + - [ ] AeroDyn_Driver_x64_OpenMP.exe + - [ ] AeroDyn_Inflow_C_Binding_x64.dll + - [ ] AeroDyn_Inflow_C_Binding_x64_OpenMP.dll + - [ ] BeamDyn_Driver_x64.exe + - [ ] DISCON.dll (x64) + - [ ] DISCON_ITIBarge.dll (x64) + - [ ] DISCON_OC3Hywind.dll (x64) + - [ ] DISCON_SC.dll (x64) + - [ ] FAST.Farm_x64.exe + - [ ] FAST.Farm_x64_OMP.exe + - [ ] FAST_SFunc.mexw64 + - [ ] HydroDynDriver_x64.exe + - [ ] HydroDyn_C_Binding_x64.dll + - [ ] IfW_C_Binding_x64.dll + - [ ] InflowWind_Driver_x64.exe + - [ ] InflowWind_Driver_x64_OpenMP.exe + - [ ] MoorDyn_Driver_x64.exe + - [ ] MoorDyn_C_Binding_x64.dll + - [ ] OpenFAST-Simulink_x64.dll + - [ ] openfast_x64.exe + - [ ] Turbsim_x64.exe + +# Changelog + +## Overview + +This release includes performance + + + +## General + +### Build systems + +#2497 `CMAKE_INSTALL_PREFIX` was incorrectly being prepended to the install direcotry (@deslaughter) Derek Slaughter + +#2564 Create `BUILD_OPENFAST_LIB_DRIVER` flag for the OpenFAST C++ Library Interface (not CFD) (@deslaughter) + + +### Docker + +#2498 Docker: typo was preventing docker build upload to GH (@andrew-platt) + + + +## Solvers + +### FAST.Farm + +#2536 FAST.Farm: increase number of output planes to 999 (@andrew-platt) + +#2554 Add `!$OMP critical` directives around some `GetNewUnit/Open*File` to reduce probability of file unit conflicts (@andrew-platt) + +#2569 Disable LiDAR in IfW at FAST.Farm level (@andrew-platt) + + +## Module changes + +### AeroDyn + +#2501 Remove `$OMP` directives from `AeroDyn_Inflow` due to Intel compiler bug (@deslaughter) + +#2516 AD bugfix: Segmentation fault with ifx compiler (@andrew-platt) + + +### InflowWind + +#2518, #2530 ADI bugfix: BoxExceed was not enabled for OLAF with ADI (@andrew-platt) + +#2532 bugfix: IfW rotor points for disk average incorrect (@andrew-platt) + + +### NWTC-Library + +#2558 Allow ParseVar to parse file paths containing spaces. (@deslaughter) + + + + +## Input file changes + +No input files change with this release as this only includes minor bugfixes (input files are identical across all 3.5.x releases). + +Full list of changes: https://openfast.readthedocs.io/en/main/source/user/api_change.html + +Full input file sets: https://github.com/OpenFAST/r-test/tree/v3.5.5 (example input files from the regression testing) + diff --git a/docs/conf.py b/docs/conf.py index f1b3d9f22..a1ce01011 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -130,7 +130,7 @@ def runDoxygen(sourcfile, doxyfileIn, doxyfileOut): # The short X.Y version. version = u'3.5' # The full version, including alpha/beta/rc tags. -release = u'v3.5.4' +release = u'v3.5.5' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/docs/source/user/api_change.rst b/docs/source/user/api_change.rst index cf16f2fe4..242ab07a0 100644 --- a/docs/source/user/api_change.rst +++ b/docs/source/user/api_change.rst @@ -9,6 +9,12 @@ The changes are tabulated according to the module input file, line number, and f The line number corresponds to the resulting line number after all changes are implemented. Thus, be sure to implement each in order so that subsequent line numbers are correct. +OpenFAST v3.5.4 to OpenFAST v3.5.5 +---------------------------------- + +No input file changes were made. + + OpenFAST v3.5.3 to OpenFAST v3.5.4 ---------------------------------- From c553ffcdb83f72d6df792966376032a0ffaa18c1 Mon Sep 17 00:00:00 2001 From: andrew-platt Date: Fri, 8 Nov 2024 13:09:33 -0700 Subject: [PATCH 099/161] AD: variable name change in ad_dvr_subs for clarity --- modules/aerodyn/src/AeroDyn_Driver_Subs.f90 | 126 ++++++++++---------- 1 file changed, 63 insertions(+), 63 deletions(-) diff --git a/modules/aerodyn/src/AeroDyn_Driver_Subs.f90 b/modules/aerodyn/src/AeroDyn_Driver_Subs.f90 index 0d3b1d295..ddba204fd 100644 --- a/modules/aerodyn/src/AeroDyn_Driver_Subs.f90 +++ b/modules/aerodyn/src/AeroDyn_Driver_Subs.f90 @@ -1689,12 +1689,12 @@ subroutine Dvr_WriteOutputs(nt, t, dvr, out, yADI, errStat, errMsg) end subroutine Dvr_WriteOutputs !---------------------------------------------------------------------------------------------------------------------------------- !> This subroutine sets up the information needed for plotting VTK surfaces. -subroutine setVTKParameters(p_FAST, dvr, ADI, errStat, errMsg, dirname) - type(Dvr_Outputs), intent(inout) :: p_FAST !< The parameters of the glue code - type(Dvr_SimData), target, intent(inout) :: dvr ! intent(out) only so that we can save FmtWidth in dvr%out%ActualChanLen - type(ADI_Data), target, intent(in ) :: ADI ! Input data for initialization (intent out for getting AD WriteOutput names/units) - integer(IntKi), intent( out) :: errStat !< Error status of the operation - character(*), intent( out) :: errMsg !< Error message if errStat /= ErrID_None +subroutine setVTKParameters(DVR_Outs, dvr, ADI, errStat, errMsg, dirname) + type(Dvr_Outputs), intent(inout) :: DVR_Outs !< The parameters of the glue code + type(Dvr_SimData), target, intent(inout) :: dvr ! intent(out) only so that we can save FmtWidth in dvr%out%ActualChanLen + type(ADI_Data), target, intent(in ) :: ADI ! Input data for initialization (intent out for getting AD WriteOutput names/units) + integer(IntKi), intent( out) :: errStat !< Error status of the operation + character(*), intent( out) :: errMsg !< Error message if errStat /= ErrID_None character(*), optional,intent(in ) :: dirname real(SiKi) :: RefPoint(3), RefLengths(2) real(SiKi) :: x, y @@ -1726,19 +1726,19 @@ subroutine setVTKParameters(p_FAST, dvr, ADI, errStat, errMsg, dirname) ! get the name of the output directory for vtk files (in a subdirectory called "vtk" of the output directory), and ! create the VTK directory if it does not exist - call GetPath ( p_FAST%root, p_FAST%VTK_OutFileRoot, vtkroot ) ! the returned p_FAST%VTK_OutFileRoot includes a file separator character at the end - p_FAST%VTK_OutFileRoot = trim(p_FAST%VTK_OutFileRoot) // trim(dir) - call MKDIR( trim(p_FAST%VTK_OutFileRoot) ) - p_FAST%VTK_OutFileRoot = trim( p_FAST%VTK_OutFileRoot ) // PathSep // trim(vtkroot) + call GetPath ( DVR_Outs%root, DVR_Outs%VTK_OutFileRoot, vtkroot ) ! the returned DVR_Outs%VTK_OutFileRoot includes a file separator character at the end + DVR_Outs%VTK_OutFileRoot = trim(DVR_Outs%VTK_OutFileRoot) // trim(dir) + call MKDIR( trim(DVR_Outs%VTK_OutFileRoot) ) + DVR_Outs%VTK_OutFileRoot = trim( DVR_Outs%VTK_OutFileRoot ) // PathSep // trim(vtkroot) ! calculate the number of digits in 'y_FAST%NOutSteps' (Maximum number of output steps to be written) ! this will be used to pad the write-out step in the VTK filename with zeros in calls to MeshWrVTK() - p_FAST%VTK_tWidth = max(9, CEILING( log10( real(dvr%numSteps+1, ReKi) / p_FAST%n_VTKTime ) ) + 1) ! NOTE: at least 9, if user changes dt/and tmax + DVR_Outs%VTK_tWidth = max(9, CEILING( log10( real(dvr%numSteps+1, ReKi) / DVR_Outs%n_VTKTime ) ) + 1) ! NOTE: at least 9, if user changes dt/and tmax - if (allocated(p_FAST%VTK_Surface)) then + if (allocated(DVR_Outs%VTK_Surface)) then return ! The surfaces were already computed (for combined cases) endif - allocate(p_FAST%VTK_Surface(dvr%numTurbines)) + allocate(DVR_Outs%VTK_Surface(dvr%numTurbines)) ! --- Find dimensions for all objects to determine "Ground" and typical dimensions MaxBladeLength = 0 MaxTwrLength = 0 @@ -1779,7 +1779,7 @@ subroutine setVTKParameters(p_FAST, dvr, ADI, errStat, errMsg, dirname) enddo ! Loop on turbine ! Get radius for ground (blade length + hub radius): - GroundRad = MaxBladeLength + MaxTwrLength+ p_FAST%VTKHubRad + GroundRad = MaxBladeLength + MaxTwrLength+ DVR_Outs%VTKHubRad ! write the ground or seabed reference polygon: RefPoint(1:2) = dvr%WT(1)%originInit(1:2) do iWT=2,dvr%numTurbines @@ -1789,37 +1789,37 @@ subroutine setVTKParameters(p_FAST, dvr, ADI, errStat, errMsg, dirname) RefPoint(3) = 0.0_ReKi RefLengths = GroundRad + sqrt((WorldBoxMax(1)-WorldBoxMin(1))**2 + (WorldBoxMax(2)-WorldBoxMin(2))**2) - call WrVTK_Ground (RefPoint, RefLengths, trim(p_FAST%VTK_OutFileRoot) // '.GroundSurface', errStat2, errMsg2 ) + call WrVTK_Ground (RefPoint, RefLengths, trim(DVR_Outs%VTK_OutFileRoot) // '.GroundSurface', errStat2, errMsg2 ) ! --- Create surfaces for Nacelle, Base, Tower, Blades do iWT=1,dvr%numTurbines wt => dvr%wt(iWT) - p_FAST%VTK_Surface(iWT)%NumSectors = 25 + DVR_Outs%VTK_Surface(iWT)%NumSectors = 25 ! Create nacelle box - p_FAST%VTK_Surface(iWT)%NacelleBox(:,1) = (/ p_FAST%VTKNacDim(1) , p_FAST%VTKNacDim(2)+p_FAST%VTKNacDim(5), p_FAST%VTKNacDim(3) /) - p_FAST%VTK_Surface(iWT)%NacelleBox(:,2) = (/ p_FAST%VTKNacDim(1)+p_FAST%VTKNacDim(4), p_FAST%VTKNacDim(2)+p_FAST%VTKNacDim(5), p_FAST%VTKNacDim(3) /) - p_FAST%VTK_Surface(iWT)%NacelleBox(:,3) = (/ p_FAST%VTKNacDim(1)+p_FAST%VTKNacDim(4), p_FAST%VTKNacDim(2) , p_FAST%VTKNacDim(3) /) - p_FAST%VTK_Surface(iWT)%NacelleBox(:,4) = (/ p_FAST%VTKNacDim(1) , p_FAST%VTKNacDim(2) , p_FAST%VTKNacDim(3) /) - p_FAST%VTK_Surface(iWT)%NacelleBox(:,5) = (/ p_FAST%VTKNacDim(1) , p_FAST%VTKNacDim(2) , p_FAST%VTKNacDim(3)+p_FAST%VTKNacDim(6) /) - p_FAST%VTK_Surface(iWT)%NacelleBox(:,6) = (/ p_FAST%VTKNacDim(1)+p_FAST%VTKNacDim(4), p_FAST%VTKNacDim(2) , p_FAST%VTKNacDim(3)+p_FAST%VTKNacDim(6) /) - p_FAST%VTK_Surface(iWT)%NacelleBox(:,7) = (/ p_FAST%VTKNacDim(1)+p_FAST%VTKNacDim(4), p_FAST%VTKNacDim(2)+p_FAST%VTKNacDim(5), p_FAST%VTKNacDim(3)+p_FAST%VTKNacDim(6) /) - p_FAST%VTK_Surface(iWT)%NacelleBox(:,8) = (/ p_FAST%VTKNacDim(1) , p_FAST%VTKNacDim(2)+p_FAST%VTKNacDim(5), p_FAST%VTKNacDim(3)+p_FAST%VTKNacDim(6) /) + DVR_Outs%VTK_Surface(iWT)%NacelleBox(:,1) = (/ DVR_Outs%VTKNacDim(1) , DVR_Outs%VTKNacDim(2)+DVR_Outs%VTKNacDim(5), DVR_Outs%VTKNacDim(3) /) + DVR_Outs%VTK_Surface(iWT)%NacelleBox(:,2) = (/ DVR_Outs%VTKNacDim(1)+DVR_Outs%VTKNacDim(4), DVR_Outs%VTKNacDim(2)+DVR_Outs%VTKNacDim(5), DVR_Outs%VTKNacDim(3) /) + DVR_Outs%VTK_Surface(iWT)%NacelleBox(:,3) = (/ DVR_Outs%VTKNacDim(1)+DVR_Outs%VTKNacDim(4), DVR_Outs%VTKNacDim(2) , DVR_Outs%VTKNacDim(3) /) + DVR_Outs%VTK_Surface(iWT)%NacelleBox(:,4) = (/ DVR_Outs%VTKNacDim(1) , DVR_Outs%VTKNacDim(2) , DVR_Outs%VTKNacDim(3) /) + DVR_Outs%VTK_Surface(iWT)%NacelleBox(:,5) = (/ DVR_Outs%VTKNacDim(1) , DVR_Outs%VTKNacDim(2) , DVR_Outs%VTKNacDim(3)+DVR_Outs%VTKNacDim(6) /) + DVR_Outs%VTK_Surface(iWT)%NacelleBox(:,6) = (/ DVR_Outs%VTKNacDim(1)+DVR_Outs%VTKNacDim(4), DVR_Outs%VTKNacDim(2) , DVR_Outs%VTKNacDim(3)+DVR_Outs%VTKNacDim(6) /) + DVR_Outs%VTK_Surface(iWT)%NacelleBox(:,7) = (/ DVR_Outs%VTKNacDim(1)+DVR_Outs%VTKNacDim(4), DVR_Outs%VTKNacDim(2)+DVR_Outs%VTKNacDim(5), DVR_Outs%VTKNacDim(3)+DVR_Outs%VTKNacDim(6) /) + DVR_Outs%VTK_Surface(iWT)%NacelleBox(:,8) = (/ DVR_Outs%VTKNacDim(1) , DVR_Outs%VTKNacDim(2)+DVR_Outs%VTKNacDim(5), DVR_Outs%VTKNacDim(3)+DVR_Outs%VTKNacDim(6) /) ! Create base box (using towerbase or nacelle dime) - BaseBoxDim = minval(p_FAST%VTKNacDim(4:6))/2 + BaseBoxDim = minval(DVR_Outs%VTKNacDim(4:6))/2 if (size(ADI%m%VTK_Surfaces(iWT)%TowerRad)>0) then BaseBoxDim = ADI%m%VTK_Surfaces(iWT)%TowerRad(1) endif - p_FAST%VTK_Surface(iWT)%BaseBox(:,1) = (/ -BaseBoxDim , -BaseBoxDim+2*BaseBoxDim, -BaseBoxDim /) - p_FAST%VTK_Surface(iWT)%BaseBox(:,2) = (/ -BaseBoxDim+2*BaseBoxDim, -BaseBoxDim+2*BaseBoxDim, -BaseBoxDim /) - p_FAST%VTK_Surface(iWT)%BaseBox(:,3) = (/ -BaseBoxDim+2*BaseBoxDim, -BaseBoxDim , -BaseBoxDim /) - p_FAST%VTK_Surface(iWT)%BaseBox(:,4) = (/ -BaseBoxDim , -BaseBoxDim , -BaseBoxDim /) - p_FAST%VTK_Surface(iWT)%BaseBox(:,5) = (/ -BaseBoxDim , -BaseBoxDim , -BaseBoxDim+2*BaseBoxDim /) - p_FAST%VTK_Surface(iWT)%BaseBox(:,6) = (/ -BaseBoxDim+2*BaseBoxDim, -BaseBoxDim , -BaseBoxDim+2*BaseBoxDim /) - p_FAST%VTK_Surface(iWT)%BaseBox(:,7) = (/ -BaseBoxDim+2*BaseBoxDim, -BaseBoxDim+2*BaseBoxDim, -BaseBoxDim+2*BaseBoxDim /) - p_FAST%VTK_Surface(iWT)%BaseBox(:,8) = (/ -BaseBoxDim , -BaseBoxDim+2*BaseBoxDim, -BaseBoxDim+2*BaseBoxDim /) + DVR_Outs%VTK_Surface(iWT)%BaseBox(:,1) = (/ -BaseBoxDim , -BaseBoxDim+2*BaseBoxDim, -BaseBoxDim /) + DVR_Outs%VTK_Surface(iWT)%BaseBox(:,2) = (/ -BaseBoxDim+2*BaseBoxDim, -BaseBoxDim+2*BaseBoxDim, -BaseBoxDim /) + DVR_Outs%VTK_Surface(iWT)%BaseBox(:,3) = (/ -BaseBoxDim+2*BaseBoxDim, -BaseBoxDim , -BaseBoxDim /) + DVR_Outs%VTK_Surface(iWT)%BaseBox(:,4) = (/ -BaseBoxDim , -BaseBoxDim , -BaseBoxDim /) + DVR_Outs%VTK_Surface(iWT)%BaseBox(:,5) = (/ -BaseBoxDim , -BaseBoxDim , -BaseBoxDim+2*BaseBoxDim /) + DVR_Outs%VTK_Surface(iWT)%BaseBox(:,6) = (/ -BaseBoxDim+2*BaseBoxDim, -BaseBoxDim , -BaseBoxDim+2*BaseBoxDim /) + DVR_Outs%VTK_Surface(iWT)%BaseBox(:,7) = (/ -BaseBoxDim+2*BaseBoxDim, -BaseBoxDim+2*BaseBoxDim, -BaseBoxDim+2*BaseBoxDim /) + DVR_Outs%VTK_Surface(iWT)%BaseBox(:,8) = (/ -BaseBoxDim , -BaseBoxDim+2*BaseBoxDim, -BaseBoxDim+2*BaseBoxDim /) enddo ! iWT, turbines @@ -1827,12 +1827,12 @@ end subroutine SetVTKParameters !---------------------------------------------------------------------------------------------------------------------------------- !> This routine writes a minimal subset of meshes with surfaces to VTK-formatted files. It doesn't bother with !! returning an error code. -subroutine WrVTK_Surfaces(t_global, ADI, FED, p_FAST, VTK_count) +subroutine WrVTK_Surfaces(t_global, ADI, FED, DVR_Outs, VTK_count) use FVW_IO, only: WrVTK_FVW real(DbKi), intent(in ) :: t_global !< Current global time type(FED_Data), target, intent(in ) :: FED !< Elastic wind turbine data (Fake ElastoDyn) type(ADI_Data), intent(in ) :: ADI !< Input data for initialization (intent out for getting AD WriteOutput names/units) - type(Dvr_Outputs), intent(in ) :: p_FAST !< Parameters for the glue code + type(Dvr_Outputs), intent(in ) :: DVR_Outs !< Parameters for the glue code integer(IntKi) , intent(in ) :: VTK_count logical, parameter :: OutputFields = .FALSE. ! due to confusion about what fields mean on a surface, we are going to just output the basic meshes if people ask for fields integer(IntKi) :: errStat2 @@ -1843,7 +1843,7 @@ subroutine WrVTK_Surfaces(t_global, ADI, FED, p_FAST, VTK_count) type(RotFED), pointer :: y_ED ! Alias to shorten notation ! AeroDyn surfaces (Blades, Hub, Tower) - call AD_WrVTK_Surfaces(ADI%u(2)%AD, ADI%y%AD, p_FAST%VTKRefPoint, ADI%m%VTK_Surfaces, VTK_count, p_FAST%VTK_OutFileRoot, p_FAST%VTK_tWidth, 25, p_FAST%VTKHubRad) + call AD_WrVTK_Surfaces(ADI%u(2)%AD, ADI%y%AD, DVR_Outs%VTKRefPoint, ADI%m%VTK_Surfaces, VTK_count, DVR_Outs%VTK_OutFileRoot, DVR_Outs%VTK_tWidth, 25, DVR_Outs%VTKHubRad) ! Elastic info nWT = size(FED%WT) @@ -1856,25 +1856,25 @@ subroutine WrVTK_Surfaces(t_global, ADI, FED, p_FAST, VTK_count) y_ED => FED%WT(iWT) ! Base - call MeshWrVTK_PointSurface (p_FAST%VTKRefPoint, y_ED%PlatformPtMesh, trim(p_FAST%VTK_OutFileRoot)//trim(sWT)//'.BaseSurface', & - VTK_count, OutputFields, errStat2, errMsg2, p_FAST%VTK_tWidth , verts = p_FAST%VTK_Surface(iWT)%BaseBox) + call MeshWrVTK_PointSurface (DVR_Outs%VTKRefPoint, y_ED%PlatformPtMesh, trim(DVR_Outs%VTK_OutFileRoot)//trim(sWT)//'.BaseSurface', & + VTK_count, OutputFields, errStat2, errMsg2, DVR_Outs%VTK_tWidth , verts = DVR_Outs%VTK_Surface(iWT)%BaseBox) if (y_ED%numBlades>0) then ! Nacelle - call MeshWrVTK_PointSurface (p_FAST%VTKRefPoint, y_ED%NacelleMotion, trim(p_FAST%VTK_OutFileRoot)//trim(sWT)//'.NacelleSurface', & - VTK_count, OutputFields, errStat2, errMsg2, p_FAST%VTK_tWidth , verts = p_FAST%VTK_Surface(iWT)%NacelleBox) + call MeshWrVTK_PointSurface (DVR_Outs%VTKRefPoint, y_ED%NacelleMotion, trim(DVR_Outs%VTK_OutFileRoot)//trim(sWT)//'.NacelleSurface', & + VTK_count, OutputFields, errStat2, errMsg2, DVR_Outs%VTK_tWidth , verts = DVR_Outs%VTK_Surface(iWT)%NacelleBox) endif - if (p_FAST%WrVTK>1) then + if (DVR_Outs%WrVTK>1) then ! --- animations ! Tower base - call MeshWrVTK_PointSurface (p_FAST%VTKRefPoint, y_ED%TwrPtMesh, trim(p_FAST%VTK_OutFileRoot)//trim(sWT)//'.TwrBaseSurface', & - VTK_count, OutputFields, errStat2, errMsg2, p_FAST%VTK_tWidth , & - NumSegments=p_FAST%VTK_Surface(iWT)%NumSectors, radius=p_FAST%VTKHubRad) + call MeshWrVTK_PointSurface (DVR_Outs%VTKRefPoint, y_ED%TwrPtMesh, trim(DVR_Outs%VTK_OutFileRoot)//trim(sWT)//'.TwrBaseSurface', & + VTK_count, OutputFields, errStat2, errMsg2, DVR_Outs%VTK_tWidth , & + NumSegments=DVR_Outs%VTK_Surface(iWT)%NumSectors, radius=DVR_Outs%VTKHubRad) if (ADI%u(2)%AD%rotors(iWT)%TowerMotion%nNodes>0) then - call MeshWrVTK_PointSurface (p_FAST%VTKRefPoint, y_ED%TwrPtMeshAD, trim(p_FAST%VTK_OutFileRoot)//trim(sWT)//'.TwrBaseSurfaceAD', & - VTK_count, OutputFields, errStat2, errMsg2, p_FAST%VTK_tWidth , & - NumSegments=p_FAST%VTK_Surface(iWT)%NumSectors, radius=p_FAST%VTKHubRad) + call MeshWrVTK_PointSurface (DVR_Outs%VTKRefPoint, y_ED%TwrPtMeshAD, trim(DVR_Outs%VTK_OutFileRoot)//trim(sWT)//'.TwrBaseSurfaceAD', & + VTK_count, OutputFields, errStat2, errMsg2, DVR_Outs%VTK_tWidth , & + NumSegments=DVR_Outs%VTK_Surface(iWT)%NumSectors, radius=DVR_Outs%VTKHubRad) endif endif enddo @@ -1882,18 +1882,18 @@ subroutine WrVTK_Surfaces(t_global, ADI, FED, p_FAST, VTK_count) ! Free wake if (allocated(ADI%m%AD%FVW_u)) then if (allocated(ADI%m%AD%FVW_u(1)%WingsMesh)) then - call WrVTK_FVW(ADI%p%AD%FVW, ADI%x(1)%AD%FVW, ADI%z(1)%AD%FVW, ADI%m%AD%FVW, trim(p_FAST%VTK_OutFileRoot)//'.FVW', VTK_count, p_FAST%VTK_tWidth, bladeFrame=.FALSE.) ! bladeFrame==.FALSE. to output in global coords + call WrVTK_FVW(ADI%p%AD%FVW, ADI%x(1)%AD%FVW, ADI%z(1)%AD%FVW, ADI%m%AD%FVW, trim(DVR_Outs%VTK_OutFileRoot)//'.FVW', VTK_count, DVR_Outs%VTK_tWidth, bladeFrame=.FALSE.) ! bladeFrame==.FALSE. to output in global coords end if end if end subroutine WrVTK_Surfaces !> This routine writes a minimal subset of meshes with surfaces to VTK-formatted files. It doesn't bother with !! returning an error code. -subroutine WrVTK_Lines(t_global, ADI, FED, p_FAST, VTK_count) +subroutine WrVTK_Lines(t_global, ADI, FED, DVR_Outs, VTK_count) use FVW_IO, only: WrVTK_FVW REAL(DbKi), INTENT(IN ) :: t_global !< Current global time type(ADI_Data), intent(in ) :: ADI !< Input data for initialization (intent out for getting AD WriteOutput names/units) type(FED_Data), target, intent(in ) :: FED !< Elastic wind turbine data (Fake ElastoDyn) - TYPE(Dvr_Outputs), INTENT(IN ) :: p_FAST !< Parameters for the glue code + TYPE(Dvr_Outputs), INTENT(IN ) :: DVR_Outs !< Parameters for the glue code INTEGER(IntKi) , INTENT(IN ) :: VTK_count logical, parameter :: OutputFields = .TRUE. INTEGER(IntKi) :: k @@ -1905,7 +1905,7 @@ subroutine WrVTK_Lines(t_global, ADI, FED, p_FAST, VTK_count) type(RotFED), pointer :: y_ED ! Alias to shorten notation ! AeroDyn surfaces (Blades, Tower) - call AD_WrVTK_LinesPoints(ADI%u(2)%AD, ADI%y%AD, p_FAST%VTKRefPoint, VTK_count, p_FAST%VTK_OutFileRoot, p_FAST%VTK_tWidth) + call AD_WrVTK_LinesPoints(ADI%u(2)%AD, ADI%y%AD, DVR_Outs%VTKRefPoint, VTK_count, DVR_Outs%VTK_OutFileRoot, DVR_Outs%VTK_tWidth) ! Elastic info nWT = size(FED%WT) @@ -1917,34 +1917,34 @@ subroutine WrVTK_Lines(t_global, ADI, FED, p_FAST, VTK_count) endif y_ED => FED%WT(iWT) - if (p_FAST%WrVTK_Type==2) then ! only if not doing surfaces + if (DVR_Outs%WrVTK_Type==2) then ! only if not doing surfaces ! Base - call MeshWrVTK_PointSurface (p_FAST%VTKRefPoint, y_ED%PlatformPtMesh, trim(p_FAST%VTK_OutFileRoot)//trim(sWT)//'.BaseSurface', & - VTK_count, OutputFields, errStat2, errMsg2, p_FAST%VTK_tWidth , verts = p_FAST%VTK_Surface(iWT)%BaseBox) + call MeshWrVTK_PointSurface (DVR_Outs%VTKRefPoint, y_ED%PlatformPtMesh, trim(DVR_Outs%VTK_OutFileRoot)//trim(sWT)//'.BaseSurface', & + VTK_count, OutputFields, errStat2, errMsg2, DVR_Outs%VTK_tWidth , verts = DVR_Outs%VTK_Surface(iWT)%BaseBox) endif if (y_ED%numBlades>0) then ! Nacelle - call MeshWrVTK( p_FAST%VTKRefPoint, y_ED%NacelleMotion, trim(p_FAST%VTK_OutFileRoot)//trim(sWT)//'.Nacelle', & - VTK_count, OutputFields, errStat2, errMsg2, p_FAST%VTK_tWidth ) + call MeshWrVTK( DVR_Outs%VTKRefPoint, y_ED%NacelleMotion, trim(DVR_Outs%VTK_OutFileRoot)//trim(sWT)//'.Nacelle', & + VTK_count, OutputFields, errStat2, errMsg2, DVR_Outs%VTK_tWidth ) endif - if (p_FAST%WrVTK>1) then + if (DVR_Outs%WrVTK>1) then ! --- animations ! Tower base - call MeshWrVTK(p_FAST%VTKRefPoint, y_ED%TwrPtMesh, trim(p_FAST%VTK_OutFileRoot)//trim(sWT)//'.TwrBase', & - VTK_count, OutputFields, errStat2, errMsg2, p_FAST%VTK_tWidth ) + call MeshWrVTK(DVR_Outs%VTKRefPoint, y_ED%TwrPtMesh, trim(DVR_Outs%VTK_OutFileRoot)//trim(sWT)//'.TwrBase', & + VTK_count, OutputFields, errStat2, errMsg2, DVR_Outs%VTK_tWidth ) if (ADI%u(2)%AD%rotors(iWT)%TowerMotion%nNodes>0) then - call MeshWrVTK(p_FAST%VTKRefPoint, y_ED%TwrPtMeshAD, trim(p_FAST%VTK_OutFileRoot)//trim(sWT)//'.TwrBaseAD', & - VTK_count, OutputFields, errStat2, errMsg2, p_FAST%VTK_tWidth ) + call MeshWrVTK(DVR_Outs%VTKRefPoint, y_ED%TwrPtMeshAD, trim(DVR_Outs%VTK_OutFileRoot)//trim(sWT)//'.TwrBaseAD', & + VTK_count, OutputFields, errStat2, errMsg2, DVR_Outs%VTK_tWidth ) endif endif enddo ! Free wake (only write this here if doing line meshes only -- FVW is written with surface outputs) - if (allocated(ADI%m%AD%FVW_u) .and. p_FAST%WrVTK_Type==2) then + if (allocated(ADI%m%AD%FVW_u) .and. DVR_Outs%WrVTK_Type==2) then if (allocated(ADI%m%AD%FVW_u(1)%WingsMesh)) then - call WrVTK_FVW(ADI%p%AD%FVW, ADI%x(1)%AD%FVW, ADI%z(1)%AD%FVW, ADI%m%AD%FVW, trim(p_FAST%VTK_OutFileRoot)//'.FVW', VTK_count, p_FAST%VTK_tWidth, bladeFrame=.FALSE.) ! bladeFrame==.FALSE. to output in global coords + call WrVTK_FVW(ADI%p%AD%FVW, ADI%x(1)%AD%FVW, ADI%z(1)%AD%FVW, ADI%m%AD%FVW, trim(DVR_Outs%VTK_OutFileRoot)//'.FVW', VTK_count, DVR_Outs%VTK_tWidth, bladeFrame=.FALSE.) ! bladeFrame==.FALSE. to output in global coords end if end if end subroutine WrVTK_Lines From 7a0fd2d2c5928dad0b47701ee20356c85a42cae9 Mon Sep 17 00:00:00 2001 From: andrew-platt Date: Wed, 18 Dec 2024 20:22:27 -0700 Subject: [PATCH 100/161] AD: remove redundant library from CMakeLists.txt --- modules/aerodyn/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/aerodyn/CMakeLists.txt b/modules/aerodyn/CMakeLists.txt index 859dd1e15..3ace5a80d 100644 --- a/modules/aerodyn/CMakeLists.txt +++ b/modules/aerodyn/CMakeLists.txt @@ -101,7 +101,7 @@ target_link_libraries(unsteadyaero_driver basicaerolib lindynlib versioninfolib) add_library(aerodyn_inflow_c_binding SHARED src/AeroDyn_Inflow_C_Binding.f90 ) -target_link_libraries(aerodyn_inflow_c_binding adilib aerodyn_driver_subs versioninfolib) +target_link_libraries(aerodyn_inflow_c_binding aerodyn_driver_subs versioninfolib) if(APPLE OR UNIX) target_compile_definitions(aerodyn_inflow_c_binding PRIVATE IMPLICIT_DLLEXPORT) endif() From 9ad219779fa58acf0adca0fb0a3f861bf6023b93 Mon Sep 17 00:00:00 2001 From: andrew-platt Date: Wed, 18 Dec 2024 20:28:22 -0700 Subject: [PATCH 101/161] ADI_c: add WrVTK_DT input for skipping timesteps for VTK outputs --- .../python-lib/aerodyn_inflow_library.py | 3 + .../aerodyn/src/AeroDyn_Driver_Registry.txt | 11 +-- modules/aerodyn/src/AeroDyn_Driver_Subs.f90 | 2 +- modules/aerodyn/src/AeroDyn_Driver_Types.f90 | 14 +-- .../aerodyn/src/AeroDyn_Inflow_C_Binding.f90 | 89 +++++++++++++------ reg_tests/r-test | 2 +- 6 files changed, 81 insertions(+), 40 deletions(-) diff --git a/modules/aerodyn/python-lib/aerodyn_inflow_library.py b/modules/aerodyn/python-lib/aerodyn_inflow_library.py index fe3cf33d9..859265342 100644 --- a/modules/aerodyn/python-lib/aerodyn_inflow_library.py +++ b/modules/aerodyn/python-lib/aerodyn_inflow_library.py @@ -107,6 +107,7 @@ def __init__(self, library_path): # VTK self.WrVTK = 0 # default of no vtk output self.WrVTK_Type = 1 # default of surface meshes + self.WrVTK_DT = 0.0 # default to all self.VTKNacDim = np.array([-2.5,-2.5,0,10,5,5], dtype="float32") # default nacelle dimension for VTK surface rendering [x0,y0,z0,Lx,Ly,Lz] (m) self.VTKHubRad = 1.5 # default hub radius for VTK surface rendering @@ -213,6 +214,7 @@ def _initialize_routines(self): POINTER(c_int), # storeHHVel POINTER(c_int), # WrVTK POINTER(c_int), # WrVTK_Type + POINTER(c_double), # WrVTK_DT -- 0 or negative to do every step POINTER(c_float), # VTKNacDim POINTER(c_float), # VTKHubRad POINTER(c_int), # wrOuts -- file format for writing outputs @@ -398,6 +400,7 @@ def adi_init(self, AD_input_string_array, IfW_input_string_array): byref(c_int(self.storeHHVel)), # IN: storeHHVel byref(c_int(self.WrVTK)), # IN: WrVTK byref(c_int(self.WrVTK_Type)), # IN: WrVTK_Type + byref(c_double(self.WrVTK_DT)), # IN: WrVTK_DT VTKNacDim_c, # IN: VTKNacDim byref(c_float(self.VTKHubRad)), # IN: VTKHubRad byref(c_int(self.wrOuts)), # IN: wrOuts -- file format for writing outputs diff --git a/modules/aerodyn/src/AeroDyn_Driver_Registry.txt b/modules/aerodyn/src/AeroDyn_Driver_Registry.txt index f36db0bc0..47c55804f 100644 --- a/modules/aerodyn/src/AeroDyn_Driver_Registry.txt +++ b/modules/aerodyn/src/AeroDyn_Driver_Registry.txt @@ -45,17 +45,18 @@ typedef ^ ^ character(25) Fmt_a typedef ^ ^ character(1) delim - - - "column delimiter" "-" typedef ^ ^ character(20) outFmt - - - "Format specifier" "-" typedef ^ ^ IntKi fileFmt - - - "Output format 1=Text, 2=Binary, 3=Both" "-" -typedef ^ ^ IntKi wrVTK - - - "0= no vtk, 1=init only, 2=animation" "-" +typedef ^ ^ IntKi WrVTK - - - "0= no vtk, 1=init only, 2=animation" "-" typedef ^ ^ IntKi WrVTK_Type - - - "Flag for VTK output type (1=surface, 2=line, 3=both)" - typedef ^ ^ character(1024) Root - - - "Output file rootname" "-" -typedef ^ ^ character(1024) VTK_OutFileRoot - - - "Output file rootname for vtk" "-" +typedef ^ ^ character(1024) VTK_OutFileRoot - - - "Output file rootname for vtk (includes directory)" "-" typedef ^ ^ character(ChanLen) WriteOutputHdr {:} - - "Channel headers" "-" typedef ^ ^ character(ChanLen) WriteOutputUnt {:} - - "Channel units" "-" typedef ^ ^ ReKi storage ::: - - "nTurbines x nChannel x nTime" typedef ^ ^ ReKi outLine : - - "Output line to be written to disk" typedef ^ ^ DvrVTK_SurfaceType VTK_surface : - - "Data for VTK surface visualization" -typedef ^ ^ INTEGER VTK_tWidth - - - "Width of number of files for leading zeros in file name format" - -typedef ^ ^ INTEGER n_VTKTime - - - "Number of time steps between writing VTK files" - +typedef ^ ^ IntKi VTK_tWidth - - - "Width of number of files for leading zeros in file name format" - +typedef ^ ^ IntKi n_VTKTime - - - "Number of time steps between writing VTK files" - +typedef ^ ^ DbKi VTK_DT - - - "Write VTK time step" - typedef ^ ^ SiKi VTKHubRad - - - "Hub radius for visualization" m typedef ^ ^ ReKi VTKNacDim 6 - - "Nacelle dimensions for visualization" m typedef ^ ^ SiKi VTKRefPoint 3 - - "RefPoint for VTK outputs" @@ -149,7 +150,7 @@ typedef ^ ^ IntKi iCase typedef ^ ^ ReKi timeSeries :: - - "Times series inputs when AnalysisType=1, 6 columns, Time, WndSpeed, ShearExp, RotSpd, Pitch, Yaw" "-" typedef ^ ^ IntKi iTimeSeries - - - "Stored index to optimize time interpolation" - typedef ^ ^ character(1024) root - - - "Output file rootname" "-" -typedef ^ ^ Dvr_Outputs out - - - "data for driver output file" "-" +typedef ^ ^ Dvr_Outputs out - - - "data for driver output file" "-" typedef ^ ^ ADI_IW_InputData IW_InitInp - - - "" - # ..... Data to wrap the driver .......................................................................................................... diff --git a/modules/aerodyn/src/AeroDyn_Driver_Subs.f90 b/modules/aerodyn/src/AeroDyn_Driver_Subs.f90 index ddba204fd..da8cd4bb0 100644 --- a/modules/aerodyn/src/AeroDyn_Driver_Subs.f90 +++ b/modules/aerodyn/src/AeroDyn_Driver_Subs.f90 @@ -469,7 +469,7 @@ subroutine Init_ADI_ForDriver(iCase, ADI, dvr, FED, dt, errStat, errMsg) InitInp%IW_InitInp%FilePassingMethod = 0_IntKi ! read input file instead of passed file data ! AeroDyn InitInp%AD%Gravity = 9.80665_ReKi - InitInp%AD%RootName = dvr%out%Root ! 'C:/Work/XFlow/' + InitInp%AD%RootName = dvr%out%Root InitInp%AD%InputFile = dvr%AD_InputFile InitInp%AD%MHK = dvr%MHK InitInp%AD%defFldDens = dvr%FldDens diff --git a/modules/aerodyn/src/AeroDyn_Driver_Types.f90 b/modules/aerodyn/src/AeroDyn_Driver_Types.f90 index 8d3153e0a..f1122aded 100644 --- a/modules/aerodyn/src/AeroDyn_Driver_Types.f90 +++ b/modules/aerodyn/src/AeroDyn_Driver_Types.f90 @@ -68,10 +68,10 @@ MODULE AeroDyn_Driver_Types character(1) :: delim !< column delimiter [-] character(20) :: outFmt !< Format specifier [-] INTEGER(IntKi) :: fileFmt = 0_IntKi !< Output format 1=Text, 2=Binary, 3=Both [-] - INTEGER(IntKi) :: wrVTK = 0_IntKi !< 0= no vtk, 1=init only, 2=animation [-] + INTEGER(IntKi) :: WrVTK = 0_IntKi !< 0= no vtk, 1=init only, 2=animation [-] INTEGER(IntKi) :: WrVTK_Type = 0_IntKi !< Flag for VTK output type (1=surface, 2=line, 3=both) [-] character(1024) :: Root !< Output file rootname [-] - character(1024) :: VTK_OutFileRoot !< Output file rootname for vtk [-] + character(1024) :: VTK_OutFileRoot !< Output file rootname for vtk (includes directory) [-] character(ChanLen) , DIMENSION(:), ALLOCATABLE :: WriteOutputHdr !< Channel headers [-] character(ChanLen) , DIMENSION(:), ALLOCATABLE :: WriteOutputUnt !< Channel units [-] REAL(ReKi) , DIMENSION(:,:,:), ALLOCATABLE :: storage !< nTurbines x nChannel x nTime [-] @@ -79,6 +79,7 @@ MODULE AeroDyn_Driver_Types TYPE(DvrVTK_SurfaceType) , DIMENSION(:), ALLOCATABLE :: VTK_surface !< Data for VTK surface visualization [-] INTEGER(IntKi) :: VTK_tWidth = 0_IntKi !< Width of number of files for leading zeros in file name format [-] INTEGER(IntKi) :: n_VTKTime = 0_IntKi !< Number of time steps between writing VTK files [-] + REAL(DbKi) :: VTK_DT = 0.0_R8Ki !< Write VTK time step [-] REAL(SiKi) :: VTKHubRad = 0.0_R4Ki !< Hub radius for visualization [m] REAL(ReKi) , DIMENSION(1:6) :: VTKNacDim = 0.0_ReKi !< Nacelle dimensions for visualization [m] REAL(SiKi) , DIMENSION(1:3) :: VTKRefPoint = 0.0_R4Ki !< RefPoint for VTK outputs [-] @@ -346,7 +347,7 @@ subroutine AD_Dvr_CopyDvr_Outputs(SrcDvr_OutputsData, DstDvr_OutputsData, CtrlCo DstDvr_OutputsData%delim = SrcDvr_OutputsData%delim DstDvr_OutputsData%outFmt = SrcDvr_OutputsData%outFmt DstDvr_OutputsData%fileFmt = SrcDvr_OutputsData%fileFmt - DstDvr_OutputsData%wrVTK = SrcDvr_OutputsData%wrVTK + DstDvr_OutputsData%WrVTK = SrcDvr_OutputsData%WrVTK DstDvr_OutputsData%WrVTK_Type = SrcDvr_OutputsData%WrVTK_Type DstDvr_OutputsData%Root = SrcDvr_OutputsData%Root DstDvr_OutputsData%VTK_OutFileRoot = SrcDvr_OutputsData%VTK_OutFileRoot @@ -416,6 +417,7 @@ subroutine AD_Dvr_CopyDvr_Outputs(SrcDvr_OutputsData, DstDvr_OutputsData, CtrlCo end if DstDvr_OutputsData%VTK_tWidth = SrcDvr_OutputsData%VTK_tWidth DstDvr_OutputsData%n_VTKTime = SrcDvr_OutputsData%n_VTKTime + DstDvr_OutputsData%VTK_DT = SrcDvr_OutputsData%VTK_DT DstDvr_OutputsData%VTKHubRad = SrcDvr_OutputsData%VTKHubRad DstDvr_OutputsData%VTKNacDim = SrcDvr_OutputsData%VTKNacDim DstDvr_OutputsData%VTKRefPoint = SrcDvr_OutputsData%VTKRefPoint @@ -478,7 +480,7 @@ subroutine AD_Dvr_PackDvr_Outputs(RF, Indata) call RegPack(RF, InData%delim) call RegPack(RF, InData%outFmt) call RegPack(RF, InData%fileFmt) - call RegPack(RF, InData%wrVTK) + call RegPack(RF, InData%WrVTK) call RegPack(RF, InData%WrVTK_Type) call RegPack(RF, InData%Root) call RegPack(RF, InData%VTK_OutFileRoot) @@ -497,6 +499,7 @@ subroutine AD_Dvr_PackDvr_Outputs(RF, Indata) end if call RegPack(RF, InData%VTK_tWidth) call RegPack(RF, InData%n_VTKTime) + call RegPack(RF, InData%VTK_DT) call RegPack(RF, InData%VTKHubRad) call RegPack(RF, InData%VTKNacDim) call RegPack(RF, InData%VTKRefPoint) @@ -523,7 +526,7 @@ subroutine AD_Dvr_UnPackDvr_Outputs(RF, OutData) call RegUnpack(RF, OutData%delim); if (RegCheckErr(RF, RoutineName)) return call RegUnpack(RF, OutData%outFmt); if (RegCheckErr(RF, RoutineName)) return call RegUnpack(RF, OutData%fileFmt); if (RegCheckErr(RF, RoutineName)) return - call RegUnpack(RF, OutData%wrVTK); if (RegCheckErr(RF, RoutineName)) return + call RegUnpack(RF, OutData%WrVTK); if (RegCheckErr(RF, RoutineName)) return call RegUnpack(RF, OutData%WrVTK_Type); if (RegCheckErr(RF, RoutineName)) return call RegUnpack(RF, OutData%Root); if (RegCheckErr(RF, RoutineName)) return call RegUnpack(RF, OutData%VTK_OutFileRoot); if (RegCheckErr(RF, RoutineName)) return @@ -546,6 +549,7 @@ subroutine AD_Dvr_UnPackDvr_Outputs(RF, OutData) end if call RegUnpack(RF, OutData%VTK_tWidth); if (RegCheckErr(RF, RoutineName)) return call RegUnpack(RF, OutData%n_VTKTime); if (RegCheckErr(RF, RoutineName)) return + call RegUnpack(RF, OutData%VTK_DT); if (RegCheckErr(RF, RoutineName)) return call RegUnpack(RF, OutData%VTKHubRad); if (RegCheckErr(RF, RoutineName)) return call RegUnpack(RF, OutData%VTKNacDim); if (RegCheckErr(RF, RoutineName)) return call RegUnpack(RF, OutData%VTKRefPoint); if (RegCheckErr(RF, RoutineName)) return diff --git a/modules/aerodyn/src/AeroDyn_Inflow_C_Binding.f90 b/modules/aerodyn/src/AeroDyn_Inflow_C_Binding.f90 index b2523e14c..c0a327699 100644 --- a/modules/aerodyn/src/AeroDyn_Inflow_C_Binding.f90 +++ b/modules/aerodyn/src/AeroDyn_Inflow_C_Binding.f90 @@ -125,17 +125,18 @@ MODULE AeroDyn_Inflow_C_BINDING ! the glue code. However, here we do not pass state information through the ! interface and therefore must store it here analogously to how it is handled ! in the OpenFAST glue code. - integer(IntKi) :: n_Global ! global timestep - integer(IntKi) :: n_VTK ! VTK timestep - real(DbKi) :: InputTimePrev ! input time of last UpdateStates call + integer(IntKi) :: n_Global ! global timestep + integer(IntKi) :: n_VTK ! VTK timestep + real(DbKi) :: InputTimePrev ! input time of last UpdateStates call + real(DbKi) :: InputTimePrev_Calc ! input time of last CalcOutput call ! Note that we are including the previous state info here (not done in OF this way) - integer(IntKi), parameter :: STATE_LAST = 0 ! Index for previous state (not needed in OF, but necessary here) - integer(IntKi), parameter :: STATE_CURR = 1 ! Index for current state - integer(IntKi), parameter :: STATE_PRED = 2 ! Index for predicted state + integer(IntKi), parameter :: STATE_LAST = 0 ! Index for previous state (not needed in OF, but necessary here) + integer(IntKi), parameter :: STATE_CURR = 1 ! Index for current state + integer(IntKi), parameter :: STATE_PRED = 2 ! Index for predicted state ! Note the indexing is different on inputs (no clue why, but thats how OF handles it) - integer(IntKi), parameter :: INPUT_LAST = 3 ! Index for previous input at t-dt - integer(IntKi), parameter :: INPUT_CURR = 2 ! Index for current input at t - integer(IntKi), parameter :: INPUT_PRED = 1 ! Index for predicted input at t+dt + integer(IntKi), parameter :: INPUT_LAST = 3 ! Index for previous input at t-dt + integer(IntKi), parameter :: INPUT_CURR = 2 ! Index for current input at t + integer(IntKi), parameter :: INPUT_PRED = 1 ! Index for predicted input at t+dt !------------------------------------------------------------------------------------ ! Meshes for motions and loads @@ -387,7 +388,8 @@ SUBROUTINE ADI_C_Init( ADinputFilePassed, ADinputFileString_C, ADinputFileString defPatm_C, defPvap_C, WtrDpth_C, MSL2SWL_C, & InterpOrder_C, DT_C, TMax_C, & storeHHVel, & - WrVTK_in, WrVTK_inType, VTKNacDim_in, VTKHubRad_in, & + WrVTK_in, WrVTK_inType, WrVTK_inDT, & + VTKNacDim_in, VTKHubRad_in, & wrOuts_C, DT_Outs_C, & NumChannels_C, OutputChannelNames_C, OutputChannelUnits_C, & ErrStat_C, ErrMsg_C) BIND (C, NAME='ADI_C_Init') @@ -423,6 +425,7 @@ SUBROUTINE ADI_C_Init( ADinputFilePassed, ADinputFileString_C, ADinputFileString ! VTK integer(c_int), intent(in ) :: WrVTK_in !< Write VTK outputs [0: none, 1: init only, 2: animation] integer(c_int), intent(in ) :: WrVTK_inType !< Write VTK outputs as [1: surface, 2: lines, 3: both] + real(c_double), intent(in ) :: WrVTK_inDT !< Timestep between VTK writes real(c_float), intent(in ) :: VTKNacDim_in(6) !< Nacelle dimension passed in for VTK surface rendering [0,y0,z0,Lx,Ly,Lz] (m) real(c_float), intent(in ) :: VTKHubrad_in !< Hub radius for VTK surface rendering integer(c_int), intent(in ) :: wrOuts_C !< Write ADI output file @@ -554,18 +557,19 @@ SUBROUTINE ADI_C_Init( ADinputFilePassed, ADinputFileString_C, ADinputFileString Sim%root = trim(OutRootName) ! Timekeeping n_Global = 0_IntKi ! Assume we are on timestep 0 at start - n_VTK = -1_IntKi ! Set VTK output to T=0 at first call + n_VTK = -1_IntKi ! counter advance just before writing ! Interpolation order InterpOrder = int(InterpOrder_C, IntKi) ! VTK outputs WrOutputsData%WrVTK = int(WrVTK_in, IntKi) WrOutputsData%WrVTK_Type = int(WrVTK_inType, IntKi) + WrOutputsData%VTK_dt = real(WrVTK_inDT, DbKi) WrOutputsData%VTKNacDim = real(VTKNacDim_in, SiKi) WrOutputsData%VTKHubrad = real(VTKHubrad_in, SiKi) WrOutputsData%VTKRefPoint = (/ 0.0_ReKi, 0.0_ReKi, 0.0_ReKi /) !TODO: should this be an input? WrOutputsData%root = trim(OutRootName) - WrOutputsData%n_VTKTime = 1 ! output every timestep + WrOutputsData%n_VTKTime = 1 ! output every timestep ! Write outputs to file WrOutputsData%fileFmt = int(wrOuts_C, IntKi) @@ -658,15 +662,18 @@ SUBROUTINE ADI_C_Init( ADinputFilePassed, ADinputFileString_C, ADinputFileString ! us to use, e.g., quadratic interpolation that effectively acts as a zeroth-order extrapolation and first-order extrapolation ! for the first and second time steps. (The interpolation order in the ExtrapInput routines are determined as ! order = SIZE(Input) + ! Tracking of previous input times + ! Since we may run correction steps, there are some things we don't want to do !------------------------------------------------------------- do i=2,InterpOrder+1 call ADI_CopyInput (ADI%u(1), ADI%u(i), MESH_NEWCOPY, Errstat2, ErrMsg2) if (Failed()) return enddo do i = 1, InterpOrder + 1 - ADI%InputTimes(i) = 0.0_DbKi - (i - 1) * Sim%dT ! assume start at T=0 + ADI%InputTimes(i) = 0.0_DbKi - (i - 1) * Sim%dT ! assume start at T=0 enddo - InputTimePrev = ADI%InputTimes(1) - Sim%dT ! Initialize for UpdateStates + InputTimePrev = ADI%InputTimes(1) - Sim%dT ! Initialize for UpdateStates + InputTimePrev_Calc = ADI%InputTimes(1) - Sim%dT ! Initialize for CalcOutput !------------------------------------------------------------- ! copy of ADI inputs. AD_SetInputMotion will set this mesh. When CalcOutput is called, @@ -806,6 +813,19 @@ subroutine ValidateSetInputs(ErrStat3,ErrMsg3) call SetErrStat(ErrID_Warn,"Requested DT_Outs is not an integer multiple of DT. Changing DT_Outs to "//trim(Num2LStr(WrOutputsData%DT_Outs))//".",ErrStat3,ErrMsg3,RoutineName) endif endif + if (WrOutputsData%WrVTK > 1_IntKi) then ! only if writing during simulation is requested (ignore init or no outputs) + ! If a smaller timestep between outputs is requested than the simulation runs at, change to DT + if (WrOutputsData%VTK_DT < Sim%dT) then + WrOutputsData%VTK_DT = Sim%dT + call SetErrStat(ErrID_Warn,"Requested VTK_DT is smaller than timestep DT. Setting VTK_DT to DT.",ErrStat3,ErrMsg3,RoutineName) + endif + ! If not an integer multiple of DT, adjust + WrOutputsData%n_VTKtime = NINT( WrOutputsData%VTK_DT / Sim%dT ) + if (.NOT. EqualRealNos( WrOutputsData%VTK_DT, Sim%dT * WrOutputsData%n_VTKtime )) then + WrOutputsData%VTK_DT = real(WrOutputsData%n_VTKtime, DbKi) * Sim%dT + call SetErrStat(ErrID_Warn,"Requested VTK_DT is not an integer multiple of DT. Changing VTK_DT to "//trim(Num2LStr(WrOutputsData%VTK_DT))//".",ErrStat3,ErrMsg3,RoutineName) + endif + endif end subroutine ValidateSetInputs !> allocate data storage for file outputs @@ -875,6 +895,7 @@ subroutine ShowPassedData() call WrScr(" storeHHVel "//TmpFlag ) call WrScr(" WrVTK_in "//trim(Num2LStr( WrVTK_in )) ) call WrScr(" WrVTK_inType "//trim(Num2LStr( WrVTK_inType )) ) + call WrScr(" WrVTK_inDT "//trim(Num2LStr( WrVTK_inDT )) ) call WrScr("-----------------------------------------------------------") end subroutine ShowPassedData @@ -1049,7 +1070,16 @@ SUBROUTINE ADI_C_CalcOutput(Time_C, & ! write outputs !------------------------------------------------------- ! Write VTK if requested (animation=2) - if (WrOutputsData%WrVTK > 1_IntKi) call WrVTK_Meshes(ADI%u(1)%AD%rotors(:),(/0.0_SiKi,0.0_SiKi,0.0_SiKi/),ErrStat2,ErrMsg2) + if (WrOutputsData%WrVTK > 1_IntKi) then + ! Check if writing this step (note this may overwrite if we rerun a step in a correction loop) + if ( mod( n_Global, WrOutputsData%n_VTKTime ) == 0 ) THEN + ! increment the current VTK output number if not a correction step, otherwise overwrite previous + if (.not. EqualRealNos( real(Time,DbKi), InputTimePrev_Calc ) ) then + n_VTK = n_VTK + 1_IntKi ! Increment for this write + endif + call WrVTK_Meshes(ADI%u(1)%AD%rotors(:),(/0.0_SiKi,0.0_SiKi,0.0_SiKi/),ErrStat2,ErrMsg2) + endif + endif if (WrOutputsData%fileFmt > idFmtNone) then !FIXME: need some way to overwrite the correction timesteps (for text file)! @@ -1059,6 +1089,9 @@ SUBROUTINE ADI_C_CalcOutput(Time_C, & ! Set error status call SetErr(ErrStat,ErrMsg,ErrStat_C,ErrMsg_C) + ! Store info what time we just ran calcs for + InputTimePrev_Calc = Time + CONTAINS logical function Failed() CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) @@ -2254,7 +2287,7 @@ subroutine WrVTK_Points(ErrStat3,ErrMsg3) ! Blade point motion (structural mesh from driver) do iBlade=1,Sim%WT(iWT)%NumBlades - call MeshWrVTK(RefPoint, BldStrMotionMesh(iWT)%Mesh(iBlade), trim(WrOutputsData%VTK_OutFileRoot)//trim(sWT)//'.BldStrMotionMesh'//trim(num2lstr(iBlade)), n_Global, .true., ErrStat3, ErrMsg3, WrOutputsData%VTK_tWidth) + call MeshWrVTK(RefPoint, BldStrMotionMesh(iWT)%Mesh(iBlade), trim(WrOutputsData%VTK_OutFileRoot)//trim(sWT)//'.BldStrMotionMesh'//trim(num2lstr(iBlade)), n_VTK, .true., ErrStat3, ErrMsg3, WrOutputsData%VTK_tWidth) if (ErrStat3 >= AbortErrLev) return enddo @@ -2262,20 +2295,20 @@ subroutine WrVTK_Points(ErrStat3,ErrMsg3) if (allocated(rot_u(iWT)%BladeRootMotion)) then do iBlade=1,Sim%WT(iWT)%NumBlades if (rot_u(iWT)%BladeRootMotion(iBlade)%Committed) then - call MeshWrVTK(RefPoint, rot_u(iWT)%BladeRootMotion(iBlade), trim(WrOutputsData%VTK_OutFileRoot)//trim(sWT)//'.BladeRootMotion'//trim(num2lstr(iBlade)), n_Global, .true., ErrStat3, ErrMsg3, WrOutputsData%VTK_tWidth) + call MeshWrVTK(RefPoint, rot_u(iWT)%BladeRootMotion(iBlade), trim(WrOutputsData%VTK_OutFileRoot)//trim(sWT)//'.BladeRootMotion'//trim(num2lstr(iBlade)), n_VTK, .true., ErrStat3, ErrMsg3, WrOutputsData%VTK_tWidth) if (ErrStat3 >= AbortErrLev) return endif enddo endif ! Nacelle (structural point input - if ( rot_u(iWT)%NacelleMotion%Committed ) call MeshWrVTK(RefPoint, rot_u(iWT)%NacelleMotion, trim(WrOutputsData%VTK_OutFileRoot)//trim(sWT)//'.NacelleMotion', n_Global, .true., ErrStat3, ErrMsg3, WrOutputsData%VTK_tWidth) + if ( rot_u(iWT)%NacelleMotion%Committed ) call MeshWrVTK(RefPoint, rot_u(iWT)%NacelleMotion, trim(WrOutputsData%VTK_OutFileRoot)//trim(sWT)//'.NacelleMotion', n_VTK, .true., ErrStat3, ErrMsg3, WrOutputsData%VTK_tWidth) if (ErrStat3 >= AbortErrLev) return ! Free wake if (allocated(ADI%m%AD%FVW_u) .and. iWT==1) then if (allocated(ADI%m%AD%FVW_u(1)%WingsMesh)) then - call WrVTK_FVW(ADI%p%AD%FVW, ADI%x(STATE_CURR)%AD%FVW, ADI%z(STATE_CURR)%AD%FVW, ADI%m%AD%FVW, trim(WrOutputsData%VTK_OutFileRoot)//'.FVW', n_Global, WrOutputsData%VTK_tWidth, bladeFrame=.FALSE.) ! bladeFrame==.FALSE. to output in global coords + call WrVTK_FVW(ADI%p%AD%FVW, ADI%x(STATE_CURR)%AD%FVW, ADI%z(STATE_CURR)%AD%FVW, ADI%m%AD%FVW, trim(WrOutputsData%VTK_OutFileRoot)//'.FVW', n_VTK, WrOutputsData%VTK_tWidth, bladeFrame=.FALSE.) ! bladeFrame==.FALSE. to output in global coords endif end if end subroutine WrVTK_Points @@ -2291,11 +2324,11 @@ subroutine WrVTK_Surfaces(ErrStat3,ErrMsg3) ErrMsg3 = '' ! TODO: use this routine when it is moved out of the driver and into ADI - ! call AD_WrVTK_Surfaces(ADI%u(1)%AD, ADI%y%AD, RefPoint, ADI%m%VTK_Surfaces, n_Global, WrOutputsData%Root, WrOutputsData%VTK_tWidth, 25, WrOutputsData%VTKHubRad) + ! call AD_WrVTK_Surfaces(ADI%u(1)%AD, ADI%y%AD, RefPoint, ADI%m%VTK_Surfaces, n_VTK, WrOutputsData%Root, WrOutputsData%VTK_tWidth, 25, WrOutputsData%VTKHubRad) ! Nacelle if ( rot_u(iWT)%NacelleMotion%Committed ) then - call MeshWrVTK_PointSurface (RefPoint, rot_u(iWT)%NacelleMotion, trim(WrOutputsData%VTK_OutFileRoot)//trim(sWT)//'.NacelleSurface', n_Global, & + call MeshWrVTK_PointSurface (RefPoint, rot_u(iWT)%NacelleMotion, trim(WrOutputsData%VTK_OutFileRoot)//trim(sWT)//'.NacelleSurface', n_VTK, & OutputFields, errStat3, errMsg3, WrOutputsData%VTK_tWidth, verts=WrOutputsData%VTK_Surface(iWT)%NacelleBox) if (ErrStat3 >= AbortErrLev) return endif @@ -2303,14 +2336,14 @@ subroutine WrVTK_Surfaces(ErrStat3,ErrMsg3) ! Tower if (rot_u(iWT)%TowerMotion%Committed) then call MeshWrVTK_Ln2Surface (RefPoint, rot_u(iWT)%TowerMotion, trim(WrOutputsData%VTK_OutFileRoot)//trim(sWT)//'.TowerSurface', & - n_Global, OutputFields, errStat3, errMsg3, WrOutputsData%VTK_tWidth, numSectors, ADI%m%VTK_Surfaces(iWT)%TowerRad ) + n_VTK, OutputFields, errStat3, errMsg3, WrOutputsData%VTK_tWidth, numSectors, ADI%m%VTK_Surfaces(iWT)%TowerRad ) if (ErrStat3 >= AbortErrLev) return endif ! Hub if (rot_u(iWT)%HubMotion%Committed) then call MeshWrVTK_PointSurface (RefPoint, rot_u(iWT)%HubMotion, trim(WrOutputsData%VTK_OutFileRoot)//trim(sWT)//'.HubSurface', & - n_Global, OutputFields, errStat3, errMsg3, WrOutputsData%VTK_tWidth, & + n_VTK, OutputFields, errStat3, errMsg3, WrOutputsData%VTK_tWidth, & NumSegments=numSectors, radius=WrOutputsData%VTKHubRad) if (ErrStat3 >= AbortErrLev) return endif @@ -2320,7 +2353,7 @@ subroutine WrVTK_Surfaces(ErrStat3,ErrMsg3) do iBlade=1,Sim%WT(iWT)%NumBlades if (rot_u(iWT)%BladeMotion(iBlade)%Committed) then call MeshWrVTK_Ln2Surface (RefPoint, rot_u(iWT)%BladeMotion(iBlade), trim(WrOutputsData%VTK_OutFileRoot)//trim(sWT)//'.Blade'//trim(num2lstr(iBlade))//'Surface', & - n_Global, OutputFields, errStat3, errMsg3, WrOutputsData%VTK_tWidth , verts=ADI%m%VTK_Surfaces(iWT)%BladeShape(iBlade)%AirfoilCoords, & + n_VTK, OutputFields, errStat3, errMsg3, WrOutputsData%VTK_tWidth , verts=ADI%m%VTK_Surfaces(iWT)%BladeShape(iBlade)%AirfoilCoords, & Sib=ADI%y%AD%rotors(iWT)%BladeLoad(iBlade) ) if (ErrStat3 >= AbortErrLev) return endif @@ -2336,22 +2369,22 @@ subroutine WrVTK_Lines(ErrStat3,ErrMsg3) ErrMsg3 = '' ! Tower - if (rot_u(iWT)%TowerMotion%Committed) call MeshWrVTK(RefPoint, rot_u(iWT)%TowerMotion, trim(WrOutputsData%VTK_OutFileRoot)//trim(sWT)//'.Tower', n_Global, .true., ErrStat3, ErrMsg3, WrOutputsData%VTK_tWidth) + if (rot_u(iWT)%TowerMotion%Committed) call MeshWrVTK(RefPoint, rot_u(iWT)%TowerMotion, trim(WrOutputsData%VTK_OutFileRoot)//trim(sWT)//'.Tower', n_VTK, .true., ErrStat3, ErrMsg3, WrOutputsData%VTK_tWidth) if (ErrStat3 >= AbortErrLev) return ! Nacelle meshes - if (rot_u(iWT)%NacelleMotion%Committed) call MeshWrVTK(RefPoint, rot_u(iWT)%NacelleMotion, trim(WrOutputsData%VTK_OutFileRoot)//trim(sWT)//'.Nacelle', n_Global, .true., ErrStat3, ErrMsg3, WrOutputsData%VTK_tWidth) + if (rot_u(iWT)%NacelleMotion%Committed) call MeshWrVTK(RefPoint, rot_u(iWT)%NacelleMotion, trim(WrOutputsData%VTK_OutFileRoot)//trim(sWT)//'.Nacelle', n_VTK, .true., ErrStat3, ErrMsg3, WrOutputsData%VTK_tWidth) if (ErrStat3 >= AbortErrLev) return ! Hub - if (rot_u(iWT)%HubMotion%Committed) call MeshWrVTK(RefPoint, rot_u(iWT)%HubMotion, trim(WrOutputsData%VTK_OutFileRoot)//trim(sWT)//'.Hub', n_Global, .true., ErrStat3, ErrMsg3, WrOutputsData%VTK_tWidth) + if (rot_u(iWT)%HubMotion%Committed) call MeshWrVTK(RefPoint, rot_u(iWT)%HubMotion, trim(WrOutputsData%VTK_OutFileRoot)//trim(sWT)//'.Hub', n_VTK, .true., ErrStat3, ErrMsg3, WrOutputsData%VTK_tWidth) if (ErrStat3 >= AbortErrLev) return ! Blades if (allocated(rot_u(iWT)%BladeMotion)) then do iBlade=1,Sim%WT(iWT)%NumBlades if (rot_u(iWT)%BladeMotion(iBlade)%Committed) then - call MeshWrVTK(RefPoint, rot_u(iWT)%BladeMotion(iBlade), trim(WrOutputsData%VTK_OutFileRoot)//trim(sWT)//'.Blade'//trim(num2lstr(iBlade)), n_Global, .true., ErrStat3, ErrMsg3, WrOutputsData%VTK_tWidth) + call MeshWrVTK(RefPoint, rot_u(iWT)%BladeMotion(iBlade), trim(WrOutputsData%VTK_OutFileRoot)//trim(sWT)//'.Blade'//trim(num2lstr(iBlade)), n_VTK, .true., ErrStat3, ErrMsg3, WrOutputsData%VTK_tWidth) if (ErrStat3 >= AbortErrLev) return endif enddo diff --git a/reg_tests/r-test b/reg_tests/r-test index b3824f2d3..4e4a8e461 160000 --- a/reg_tests/r-test +++ b/reg_tests/r-test @@ -1 +1 @@ -Subproject commit b3824f2d3a4cd4cb826aa4ac95b6e39a99e66d43 +Subproject commit 4e4a8e461d04fb41e59ce92a7175871a000a891b From ffbaba9eaf1c0f41824fc4bbb9344668321985a0 Mon Sep 17 00:00:00 2001 From: andrew-platt Date: Wed, 18 Dec 2024 21:11:28 -0700 Subject: [PATCH 102/161] ADI_c: add vtk output directory to interface --- .../aerodyn/python-lib/aerodyn_inflow_library.py | 4 ++++ modules/aerodyn/src/AeroDyn_Inflow_C_Binding.f90 | 13 ++++++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/modules/aerodyn/python-lib/aerodyn_inflow_library.py b/modules/aerodyn/python-lib/aerodyn_inflow_library.py index 859265342..eed6155ca 100644 --- a/modules/aerodyn/python-lib/aerodyn_inflow_library.py +++ b/modules/aerodyn/python-lib/aerodyn_inflow_library.py @@ -157,6 +157,7 @@ def __init__(self, library_path): # If HD writes a file (echo, summary, or other), use this for the # root of the file name. self.outRootName = "Output_ADIlib_default" + self.outVTKdir = "" # Set to specify a directory relative to the input files (created if doesn't exist) # _initialize_routines() ------------------------------------------------------------------------------------------------------------ def _initialize_routines(self): @@ -200,6 +201,7 @@ def _initialize_routines(self): POINTER(c_char_p), # IfW input file as string POINTER(c_int), # IfW input file string length POINTER(c_char), # OutRootName + POINTER(c_char), # OutVTKdir POINTER(c_float), # gravity POINTER(c_float), # defFldDens POINTER(c_float), # defKinVisc @@ -372,6 +374,7 @@ def adi_init(self, AD_input_string_array, IfW_input_string_array): # Rootname for ADI output files (echo etc). _outRootName_c = create_string_buffer((self.outRootName.ljust(self.default_str_c_len)).encode('utf-8')) + _outVTKdir_c = create_string_buffer((self.outVTKdir.ljust(self.default_str_c_len)).encode('utf-8')) # Flatten arrays to pass # [x2,y1,z1, x2,y2,z2 ...] @@ -386,6 +389,7 @@ def adi_init(self, AD_input_string_array, IfW_input_string_array): c_char_p(IfW_input_string), # IN: IfW input file as string (or filename if IfWinputPass is false) byref(c_int(IfW_input_string_length)), # IN: IfW input file string length _outRootName_c, # IN: rootname for ADI file writing + _outVTKdir_c, # IN: directory for vtk output files (relative to input file) byref(c_float(self.gravity)), # IN: gravity byref(c_float(self.defFldDens)), # IN: defFldDens byref(c_float(self.defKinVisc)), # IN: defKinVisc diff --git a/modules/aerodyn/src/AeroDyn_Inflow_C_Binding.f90 b/modules/aerodyn/src/AeroDyn_Inflow_C_Binding.f90 index c0a327699..e8de9efdd 100644 --- a/modules/aerodyn/src/AeroDyn_Inflow_C_Binding.f90 +++ b/modules/aerodyn/src/AeroDyn_Inflow_C_Binding.f90 @@ -384,6 +384,7 @@ end subroutine ADI_C_PreInit !=============================================================================================================== SUBROUTINE ADI_C_Init( ADinputFilePassed, ADinputFileString_C, ADinputFileStringLength_C, & IfWinputFilePassed, IfWinputFileString_C, IfWinputFileStringLength_C, OutRootName_C, & + OutVTKDir_C, & gravity_C, defFldDens_C, defKinVisc_C, defSpdSound_C, & defPatm_C, defPvap_C, WtrDpth_C, MSL2SWL_C, & InterpOrder_C, DT_C, TMax_C, & @@ -406,6 +407,7 @@ SUBROUTINE ADI_C_Init( ADinputFilePassed, ADinputFileString_C, ADinputFileString type(c_ptr), intent(in ) :: IfWinputFileString_C !< Input file as a single string with lines deliniated by C_NULL_CHAR integer(c_int), intent(in ) :: IfWinputFileStringLength_C !< lenght of the input file string character(kind=c_char), intent(in ) :: OutRootName_C(IntfStrLen) !< Root name to use for echo files and other + character(kind=c_char), intent(in ) :: OutVTKDir_C(IntfStrLen) !< Directory to put all vtk output ! Environmental real(c_float), intent(in ) :: gravity_C !< Gravitational acceleration (m/s^2) real(c_float), intent(in ) :: defFldDens_C !< Air density (kg/m^3) @@ -447,6 +449,7 @@ SUBROUTINE ADI_C_Init( ADinputFilePassed, ADinputFileString_C, ADinputFileString character(ErrMsgLen) :: ErrMsg !< aggregated error message integer(IntKi) :: ErrStat2 !< temporary error status from a call character(ErrMsgLen) :: ErrMsg2 !< temporary error message from a call + character(IntfStrLen) :: OutVTKdir !< Output directory for files (relative to current location) integer(IntKi) :: i,j,k !< generic index variables integer(IntKi) :: iWT !< current turbine number (iterate through during setup for ADI_Init call) integer(IntKi) :: AeroProjMod !< for checking that all turbines use the same AeroProjMod @@ -497,6 +500,10 @@ SUBROUTINE ADI_C_Init( ADinputFilePassed, ADinputFileString_C, ADinputFileString i = INDEX(OutRootName,C_NULL_CHAR) - 1 ! if this has a c null character at the end... if ( i > 0 ) OutRootName = OutRootName(1:I) ! remove it + ! OutVTKdir -- output directory + OutVTKdir = TRANSFER( OutVTKdir_C, OutVTKdir ) + i = INDEX(OutVTKdir,C_NULL_CHAR) - 1 ! if this has a c null character at the end... + if ( i > 0 ) OutVTKdir = OutVTKdir(1:I) ! remove it ! For debugging the interface: if (DebugLevel > 0) then @@ -645,7 +652,10 @@ SUBROUTINE ADI_C_Init( ADinputFilePassed, ADinputFileString_C, ADinputFileString call SetupMotionLoadsInterfaceMeshes(); if (Failed()) return ! setup meshes if (WrOutputsData%WrVTK > 0_IntKi) then - call setVTKParameters(WrOutputsData, Sim, ADI, ErrStat2, ErrMsg2, 'vtk-ADI') + if (len_trim(OutVTKdir) <= 0) then + OutVTKdir = 'vtk-ADI' + endif + call setVTKParameters(WrOutputsData, Sim, ADI, ErrStat2, ErrMsg2, OutVTKdir) if (Failed()) return endif ! write meshes for this rotor @@ -873,6 +883,7 @@ subroutine ShowPassedData() call WrScr(" IfWinputFileString_C (ptr addr)"//trim(Num2LStr(LOC(IfWinputFileString_C))) ) call WrScr(" IfWinputFileStringLength_C "//trim(Num2LStr( IfWinputFileStringLength_C )) ) call WrScr(" OutRootName "//trim(OutRootName) ) + call WrScr(" OutVTKDir "//trim(OutVTKDir) ) call WrScr(" Environment variables") call WrScr(" gravity_C "//trim(Num2LStr( gravity_C )) ) call WrScr(" defFldDens_C "//trim(Num2LStr( defFldDens_C )) ) From 15cad72dab3afea045757d8e5c3b76393737db8f Mon Sep 17 00:00:00 2001 From: andrew-platt Date: Wed, 18 Dec 2024 21:24:21 -0700 Subject: [PATCH 103/161] ADI_c: handle absolute or relative vtk output paths --- modules/aerodyn/src/AeroDyn_Driver_Subs.f90 | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/modules/aerodyn/src/AeroDyn_Driver_Subs.f90 b/modules/aerodyn/src/AeroDyn_Driver_Subs.f90 index da8cd4bb0..27cc9ba0f 100644 --- a/modules/aerodyn/src/AeroDyn_Driver_Subs.f90 +++ b/modules/aerodyn/src/AeroDyn_Driver_Subs.f90 @@ -1727,7 +1727,11 @@ subroutine setVTKParameters(DVR_Outs, dvr, ADI, errStat, errMsg, dirname) ! get the name of the output directory for vtk files (in a subdirectory called "vtk" of the output directory), and ! create the VTK directory if it does not exist call GetPath ( DVR_Outs%root, DVR_Outs%VTK_OutFileRoot, vtkroot ) ! the returned DVR_Outs%VTK_OutFileRoot includes a file separator character at the end - DVR_Outs%VTK_OutFileRoot = trim(DVR_Outs%VTK_OutFileRoot) // trim(dir) + if (PathIsRelative(trim(dir))) then + DVR_Outs%VTK_OutFileRoot = trim(DVR_Outs%VTK_OutFileRoot) // trim(dir) + else + DVR_Outs%VTK_OutFileRoot = trim(dir) + endif call MKDIR( trim(DVR_Outs%VTK_OutFileRoot) ) DVR_Outs%VTK_OutFileRoot = trim( DVR_Outs%VTK_OutFileRoot ) // PathSep // trim(vtkroot) ! calculate the number of digits in 'y_FAST%NOutSteps' (Maximum number of output steps to be written) From 1ac5f8966c8c66fcf89bd277855c36dfa1cdc1f4 Mon Sep 17 00:00:00 2001 From: andrew-platt Date: Thu, 19 Dec 2024 00:25:02 -0700 Subject: [PATCH 104/161] ADI: add GetDiskAvgVel routine --- .../aerodyn/src/AeroDyn_Inflow_C_Binding.f90 | 115 +++++++++++++++++- 1 file changed, 114 insertions(+), 1 deletion(-) diff --git a/modules/aerodyn/src/AeroDyn_Inflow_C_Binding.f90 b/modules/aerodyn/src/AeroDyn_Inflow_C_Binding.f90 index e8de9efdd..7c319f031 100644 --- a/modules/aerodyn/src/AeroDyn_Inflow_C_Binding.f90 +++ b/modules/aerodyn/src/AeroDyn_Inflow_C_Binding.f90 @@ -24,6 +24,7 @@ MODULE AeroDyn_Inflow_C_BINDING USE AeroDyn_Inflow_Types USE AeroDyn_Driver_Types, only: Dvr_SimData, Dvr_Outputs USE AeroDyn_Driver_Subs, only: Dvr_InitializeOutputs, Dvr_WriteOutputs, SetVTKParameters !, WrVTK_Surfaces, WrVTK_Lines, WrVTK_Ground + USE IfW_FlowField, only: IfW_FlowField_GetVelAcc USE NWTC_Library USE VersionInfo @@ -39,6 +40,7 @@ MODULE AeroDyn_Inflow_C_BINDING PUBLIC :: ADI_C_SetupRotor ! Initial node positions etc for a rotor PUBLIC :: ADI_C_SetRotorMotion ! Set motions for a given rotor PUBLIC :: ADI_C_GetRotorLoads ! Retrieve loads for a given rotor + PUBLIC :: ADI_C_GetDiskAvgVel ! Get the disk average velocity for the rotor !------------------------------------------------------------------------------------ ! Version info for display @@ -96,7 +98,7 @@ MODULE AeroDyn_Inflow_C_BINDING integer(IntKi) :: InterpOrder !------------------------------ ! Primary ADI data derived data types - type(ADI_Data) :: ADI + type(ADI_Data), target :: ADI !< all ADI data (target for using pointers to simplify code) type(ADI_InitInputType) :: InitInp !< Initialization data type(ADI_InitOutputType) :: InitOutData !< Initial output data -- Names, units, and version info. type(ADI_InputType) :: ADI_u !< ADI inputs -- set by AD_SetInputMotion. Copied as needed (necessary for correction steps) @@ -138,6 +140,17 @@ MODULE AeroDyn_Inflow_C_BINDING integer(IntKi), parameter :: INPUT_CURR = 2 ! Index for current input at t integer(IntKi), parameter :: INPUT_PRED = 1 ! Index for predicted input at t+dt + !------------------------------- + ! Variables for disk average velocity calculations + integer(IntKi), parameter :: NumPtsDiskAvg = 144 + type :: DiskAvgVelData_Type + real(ReKi) :: DiskWindPosRel(3,NumPtsDiskAvg) + real(ReKi) :: DiskWindPosAbs(3,NumPtsDiskAvg) + real(ReKi) :: DiskWindVel(3,NumPtsDiskAvg) + real(ReKi) :: DiskAvgVel(3) + end type DiskAvgVelData_Type + type(DiskAvgVelData_Type), allocatable :: DiskAvgVelVars(:) + !------------------------------------------------------------------------------------ ! Meshes for motions and loads ! Meshes are used within AD to handle all motions and loads. Rather than directly @@ -304,6 +317,10 @@ subroutine ADI_C_PreInit(NumTurbines_C, TransposeDCM_in, PointLoadOutput_in, Deb if (allocated(InitInp%AD%rotors)) deallocate(InitInp%AD%rotors) allocate(InitInp%AD%rotors(Sim%NumTurbines),stat=errStat2); if (Failed0('rotors')) return + ! allocate data storage for DiskAvgVel retrieval + if (allocated(DiskAvgVelVars)) deallocate(DiskAvgVelVars) + allocate(DiskAvgVelVars(Sim%NumTurbines), STAT=ErrStat2); if (Failed0('DiskAvgVelVars')) return + ! Allocate data storage for turbine info if (allocated(Sim%WT)) deallocate(Sim%WT) allocate(Sim%WT(Sim%NumTurbines),stat=errStat2); if (Failed0('wind turbines')) return @@ -666,6 +683,12 @@ SUBROUTINE ADI_C_Init( ADinputFilePassed, ADinputFileString_C, ADinputFileString if (Failed()) return endif + ! Setup points for calculating disk average velocity + do iWT=1,Sim%NumTurbines + call SetDiskAvgPoints(iWT) + if (Failed()) return + enddo + !------------------------------------------------------------- ! Setup other prior timesteps ! We fill InputTimes with negative times, but the Input values are identical for each of those times; this allows @@ -986,6 +1009,24 @@ subroutine CheckNodes(iWT) ! - some checks on hub/nacelle being near middle of the rotor? Not sure if that matters end subroutine CheckNodes + !> Setup points for disk average velocity calculations + subroutine SetDiskAvgPoints(iWT) + integer(IntKi), intent(in) :: iWT + integer(IntKi) :: i,BlNds + real(ReKi) :: R,theta,BLength + ! Calculate relative points on disk (do this once up front to save computational time). + ! NOTE: this is in the XY plane, and will be multiplied by the hub orientation vector + BlNds = ADI%p%AD%rotors(iWT)%NumBlNds + BLength = TwoNorm(ADI%u(1)%AD%rotors(iWT)%BladeMotion(1)%Position(:,BlNds) - ADI%u(1)%AD%rotors(iWT)%HubMotion%Position(:,1)) + R = real(BLength,ReKi) * 0.7_reKi !70% radius + do i=1,NumPtsDiskAvg + theta = pi +(i-1)*TwoPi/NumPtsDiskAvg + DiskAvgVelVars(iWT)%DiskWindPosRel(1,i) = 0.0_ReKi ! Hub X (perpindicular to rotor plane) + DiskAvgVelVars(iWT)%DiskWindPosRel(2,i) = R*cos(theta) ! Hub Y + DiskAvgVelVars(iWT)%DiskWindPosRel(3,i) = R*sin(theta) ! Hub Z (in vertical plane when azimuth=0) + end do + end subroutine SetDiskAvgPoints + END SUBROUTINE ADI_C_Init @@ -1948,6 +1989,76 @@ end subroutine ShowPassedData end subroutine ADI_C_GetRotorLoads +!=============================================================================================================== +!--------------------------------------------- GetDiskAvgVel --------------------------------------------------- +!=============================================================================================================== +!> Get the disk average velocity for a single rotor (uses the IfW DiskAvgVel routine) +subroutine ADI_C_GetDiskAvgVel(iWT_C, & + DiskAvgVel_C, & + ErrStat_C, ErrMsg_C) BIND (C, NAME='ADI_C_GetDiskAvgVel') + implicit none +#ifndef IMPLICIT_DLLEXPORT +!DEC$ ATTRIBUTES DLLEXPORT :: ADI_C_GetDiskAvgVel +!GCC$ ATTRIBUTES DLLEXPORT :: ADI_C_GetDiskAvgVel +#endif + integer(c_int), intent(in ) :: iWT_C !< Wind turbine / rotor number + real(c_float), intent( out) :: DiskAvgVel_C(3) !< Wind speed vector for disk average [Vx,Vy,Vz] -- (m/s) (global) + integer(c_int), intent( out) :: ErrStat_C + character(kind=c_char), intent( out) :: ErrMsg_C(ErrMsgLen_C) + + ! Local variables + type(MeshType), pointer :: Hub ! HubMotion mesh pointer, for simplicity in code reading + integer(IntKi) :: iWT !< current wind turbine / rotor + integer(IntKi) :: i + integer(IntKi), parameter :: StartNode = 1 ! so all points are calculated + real(ReKi), allocatable :: NoAcc(:,:) ! Placeholder array not used when accelerations not required. + real(ReKi) :: DiskAvgVel(3) !< Wind speed vector for disk average [Vx,Vy,Vz] -- (m/s) (global) + integer(IntKi) :: ErrStat !< aggregated error status + character(ErrMsgLen) :: ErrMsg !< aggregated error message + character(*), parameter :: RoutineName = 'ADI_C_GetDiskAvgVel' !< for error handling + + ! Initialize error handling + ErrStat = ErrID_None + ErrMsg = "" + + ! For debugging the interface: + if (DebugLevel > 0) then + call ShowPassedData() + endif + + ! current turbine number + iWT = int(iWT_c, IntKi) + + ! pointer to make code more readable + Hub => ADI%u(1)%AD%rotors(iWT)%HubMotion + + ! Calculate Disk Avg Velocity + do i=1,NumPtsDiskAvg + DiskAvgVelVars(iWT)%DiskWindPosAbs(:,i) = real(Hub%Position(1:3,1)+Hub%TranslationDisp(1:3,1),ReKi) & + + matmul(real(Hub%Orientation(1:3,1:3,1),ReKi),DiskAvgVelVars(iWT)%DiskWindPosRel(:,i)) + enddo + call IfW_FlowField_GetVelAcc(ADI%m%IW%p%FlowField, StartNode, InputTimePrev_Calc, DiskAvgVelVars(iWT)%DiskWindPosAbs, DiskAvgVelVars(iWT)%DiskWindVel, NoAcc, ErrStat, ErrMsg) + + ! calculate average + DiskAvgVel = sum(DiskAvgVelVars(iWT)%DiskWindVel, dim=2) / REAL(NumPtsDiskAvg,SiKi) + DiskAvgVel_C = real(DiskAvgVel, c_float) + + ! Set error status + call SetErr(ErrStat,ErrMsg,ErrStat_C,ErrMsg_C) + +CONTAINS + !> This subroutine prints out all the variables that are passed in. Use this only + !! for debugging the interface on the Fortran side. + subroutine ShowPassedData() + call WrSCr("") + call WrScr("-----------------------------------------------------------") + call WrScr("Interface debugging: Variables passed in through interface") + call WrScr(" ADI_C_GetDiskAvgVel -- rotor "//trim(Num2LStr(iWT_c))) + call WrScr("-----------------------------------------------------------") + end subroutine ShowPassedData +end subroutine ADI_C_GetDiskAvgVel + + !=================================================================================================================================== ! Internal routines for setting meshes etc. !=================================================================================================================================== @@ -2490,6 +2601,8 @@ subroutine ClearTmpStorage() ! if (allocated(NacMotionMesh )) call ClearMeshArr1(NacMotionMesh ) ! if (allocated(NacLoadMesh )) call ClearMeshArr1(NacLoadMesh ) if (allocated(Map_BldStrMotion_2_AD_Blade )) call ClearMeshMapArr2(Map_BldStrMotion_2_AD_Blade ) + ! other stuff + if (allocated(DiskAvgVelVars)) deallocate(DiskAvgVelVars) contains subroutine ClearMeshArr1(MeshName) type(MeshType), allocatable :: MeshName(:) From d4d680158b7f198b04cee7aafd992c964c345b7a Mon Sep 17 00:00:00 2001 From: andrew-platt Date: Thu, 19 Dec 2024 00:25:28 -0700 Subject: [PATCH 105/161] ADsk: correction to disk average velocity equations See PR #2532 for details --- modules/aerodisk/src/AeroDisk.f90 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/aerodisk/src/AeroDisk.f90 b/modules/aerodisk/src/AeroDisk.f90 index 13de16bfb..e6257ac2d 100644 --- a/modules/aerodisk/src/AeroDisk.f90 +++ b/modules/aerodisk/src/AeroDisk.f90 @@ -172,9 +172,9 @@ subroutine SetDiskAvgPoints(ErrStat3,ErrMsg3) R = real(p%RotorRad,ReKi) * 0.7_reKi !70% radius do i=1,ADsk_NumPtsDiskAvg theta = pi +(i-1)*TwoPi/ADsk_NumPtsDiskAvg - p%DiskWindPosRel(1,i) = R*cos(theta) - p%DiskWindPosRel(2,i) = R*sin(theta) - p%DiskWindPosRel(3,i) = 0.0_ReKi + p%DiskWindPosRel(1,i) = 0.0_ReKi ! Hub X (perpindicular to rotor plane) + p%DiskWindPosRel(2,i) = R*cos(theta) ! Hub Y + p%DiskWindPosRel(3,i) = R*sin(theta) ! Hub Z (in vertical plane when azimuth=0) end do end subroutine SetDiskAvgPoints From 2052f625cfffe8e1d431fa329e9e2df437bcc0fa Mon Sep 17 00:00:00 2001 From: andrew-platt Date: Thu, 19 Dec 2024 09:05:02 -0700 Subject: [PATCH 106/161] ADI: add GetDiskAvgVel to regression test --- .../python-lib/aerodyn_inflow_library.py | 42 ++++++++++++++++++- reg_tests/r-test | 2 +- 2 files changed, 41 insertions(+), 3 deletions(-) diff --git a/modules/aerodyn/python-lib/aerodyn_inflow_library.py b/modules/aerodyn/python-lib/aerodyn_inflow_library.py index eed6155ca..22e4a8730 100644 --- a/modules/aerodyn/python-lib/aerodyn_inflow_library.py +++ b/modules/aerodyn/python-lib/aerodyn_inflow_library.py @@ -271,6 +271,15 @@ def _initialize_routines(self): self.ADI_C_GetRotorLoads.restype = c_int + self.ADI_C_GetDiskAvgVel.argtypes = [ + POINTER(c_int), # iturb + POINTER(c_float), # Disk average vel vector + POINTER(c_int), # ErrStat_C + POINTER(c_char) # ErrMsg_C + ] + self.ADI_C_GetDiskAvgVel.restype = c_int + + self.ADI_C_CalcOutput.argtypes = [ POINTER(c_double), # Time_C POINTER(c_float), # Output Channel Values @@ -497,7 +506,7 @@ def adi_setrotormotion(self, iturb, \ self.check_error() - # adi_calcOutput ------------------------------------------------------------------------------------------------------------ + # adi_getrotorloads --------------------------------------------------------------------------------------------------------- def adi_getrotorloads(self, iturb, meshFrcMom, hhVel=None): # Resulting Forces/moments -- [Fx1,Fy1,Fz1,Mx1,My1,Mz1, Fx2,Fy2,Fz2,Mx2,My2,Mz2 ...] _meshFrc_flat_c = (c_float * (6 * self.numMeshPts))(0.0,) @@ -532,6 +541,28 @@ def adi_getrotorloads(self, iturb, meshFrcMom, hhVel=None): hhVel[1] = _hhVel_flat_c[1] hhVel[2] = _hhVel_flat_c[2] + + # adi_getdiskavgvel --------------------------------------------------------------------------------------------------------- + def adi_getdiskavgvel(self, iturb, diskAvgVel): + # Resulting disk average velocity [Vx,Vy,Vz] + _diskAvgVel_flat_c = (c_float * 3)(0.0,) + + # Run ADI_GetDiskAvgVel + self.ADI_C_GetDiskAvgVel( + c_int(iturb), # IN: iturb -- current turbine number + _diskAvgVel_flat_c, # OUT: disk average velocity [Vx, Vy, Vz] + byref(self.error_status_c), # OUT: ErrStat_C + self.error_message_c # OUT: ErrMsg_C + ) + + self.check_error() + + ## Disk average wind speed + diskAvgVel[0] = _diskAvgVel_flat_c[0] + diskAvgVel[1] = _diskAvgVel_flat_c[1] + diskAvgVel[2] = _diskAvgVel_flat_c[2] + + # adi_calcOutput ------------------------------------------------------------------------------------------------------------ def adi_calcOutput(self, time, outputChannelValues): @@ -914,6 +945,9 @@ def __init__(self,filename,numMeshPts): self.DbgFile.write(f_string.format(f_num+"Mx" )) self.DbgFile.write(f_string.format(f_num+"My" )) self.DbgFile.write(f_string.format(f_num+"Mz" )) + self.DbgFile.write(f_string.format(f_num+"DskAvgVx" )) + self.DbgFile.write(f_string.format(f_num+"DskAvgVy" )) + self.DbgFile.write(f_string.format(f_num+"DskAvgVz" )) self.DbgFile.write("\n") self.DbgFile.write(" (s) ") for i in range(1,self.numMeshPts+1): @@ -941,10 +975,13 @@ def __init__(self,filename,numMeshPts): self.DbgFile.write(f_string.format("(N-m)" )) self.DbgFile.write(f_string.format("(N-m)" )) self.DbgFile.write(f_string.format("(N-m)" )) + self.DbgFile.write(f_string.format("(m/s)" )) + self.DbgFile.write(f_string.format("(m/s)" )) + self.DbgFile.write(f_string.format("(m/s)" )) self.DbgFile.write("\n") self.opened = True - def write(self,t,meshPos,meshVel,meshAcc,meshFrc): + def write(self,t,meshPos,meshVel,meshAcc,meshFrc,DiskAvgVel): t_string = "{:10.4f}" f_string3 = "{:25.7e}"*3 f_string6 = "{:25.7e}"*6 @@ -954,6 +991,7 @@ def write(self,t,meshPos,meshVel,meshAcc,meshFrc): self.DbgFile.write(f_string6.format(*meshVel[i,:])) self.DbgFile.write(f_string6.format(*meshAcc[i,:])) self.DbgFile.write(f_string6.format(*meshFrc[i,:])) + self.DbgFile.write(f_string3.format(*DiskAvgVel[:])) self.DbgFile.write("\n") def end(self): diff --git a/reg_tests/r-test b/reg_tests/r-test index 4e4a8e461..03c239dc7 160000 --- a/reg_tests/r-test +++ b/reg_tests/r-test @@ -1 +1 @@ -Subproject commit 4e4a8e461d04fb41e59ce92a7175871a000a891b +Subproject commit 03c239dc79b7c1e493701bb2ea909d3ec89bd274 From a8fe70e498f7827bc6fdda4c8e34247427ddb08b Mon Sep 17 00:00:00 2001 From: andrew-platt Date: Thu, 19 Dec 2024 09:40:06 -0700 Subject: [PATCH 107/161] IfW: change logic flag for LidarEnabled --- modules/inflowwind/src/InflowWind.f90 | 2 +- modules/inflowwind/src/InflowWind.txt | 2 +- modules/inflowwind/src/InflowWind_Types.f90 | 10 +++++----- modules/openfast-library/src/FAST_Subs.f90 | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/modules/inflowwind/src/InflowWind.f90 b/modules/inflowwind/src/InflowWind.f90 index 9c0c0276f..a0ddc5e71 100644 --- a/modules/inflowwind/src/InflowWind.f90 +++ b/modules/inflowwind/src/InflowWind.f90 @@ -226,7 +226,7 @@ SUBROUTINE InflowWind_Init( InitInp, InputGuess, p, ContStates, DiscStates, Cons p%lidar%ConsiderHubMotion = InputFileData%ConsiderHubMotion ! Disable Lidar if not allowed (FAST.Farm doesn't allow this) - if (InitInp%LidarDisable) then + if (.not. InitInp%LidarEnabled) then if (p%lidar%SensorType /= SensorType_None) then call WrScr(' WARNING: LiDAR cannot be used with this instance of InflowWind (not usable with FAST.Farm).') call WrScr(' --> Disabling LiDAR.') diff --git a/modules/inflowwind/src/InflowWind.txt b/modules/inflowwind/src/InflowWind.txt index 5fbe8e6c0..c4ea6c56e 100644 --- a/modules/inflowwind/src/InflowWind.txt +++ b/modules/inflowwind/src/InflowWind.txt @@ -101,7 +101,7 @@ typedef ^ ^ ReKi WtrDpth typedef ^ ^ ReKi MSL2SWL - - - "Mean sea level to still water level" m typedef ^ ^ IntKi BoxExceedAllowIdx - -1 - "Extrapolate winds outside box starting at this index (for OLAF wakes and LidarSim)" - typedef ^ ^ LOGICAL BoxExceedAllowF - .FALSE. - "Flag to allow Extrapolation winds outside box starting at this index (for OLAF wakes and LidarSim)" - -typedef ^ ^ LOGICAL LidarDisable - .true. - "Disable LiDAR for this instance of InflowWind? (FAST.Farm not compatible)" - +typedef ^ ^ LOGICAL LidarEnabled - .false. - "Enable LiDAR for this instance of InflowWind? (FAST.Farm, ADI, and InflowWind driver/library are not compatible)" - # Init Output diff --git a/modules/inflowwind/src/InflowWind_Types.f90 b/modules/inflowwind/src/InflowWind_Types.f90 index 8ac1bfc93..a4384becf 100644 --- a/modules/inflowwind/src/InflowWind_Types.f90 +++ b/modules/inflowwind/src/InflowWind_Types.f90 @@ -119,7 +119,7 @@ MODULE InflowWind_Types REAL(ReKi) :: MSL2SWL !< Mean sea level to still water level [m] INTEGER(IntKi) :: BoxExceedAllowIdx = -1 !< Extrapolate winds outside box starting at this index (for OLAF wakes and LidarSim) [-] LOGICAL :: BoxExceedAllowF = .FALSE. !< Flag to allow Extrapolation winds outside box starting at this index (for OLAF wakes and LidarSim) [-] - LOGICAL :: LidarDisable = .true. !< Disable LiDAR for this instance of InflowWind? (FAST.Farm not compatible) [-] + LOGICAL :: LidarEnabled = .false. !< Enable LiDAR for this instance of InflowWind? (FAST.Farm, ADI, and InflowWind driver/library are not compatible) [-] END TYPE InflowWind_InitInputType ! ======================= ! ========= InflowWind_InitOutputType ======= @@ -1111,7 +1111,7 @@ SUBROUTINE InflowWind_CopyInitInput( SrcInitInputData, DstInitInputData, CtrlCod DstInitInputData%MSL2SWL = SrcInitInputData%MSL2SWL DstInitInputData%BoxExceedAllowIdx = SrcInitInputData%BoxExceedAllowIdx DstInitInputData%BoxExceedAllowF = SrcInitInputData%BoxExceedAllowF - DstInitInputData%LidarDisable = SrcInitInputData%LidarDisable + DstInitInputData%LidarEnabled = SrcInitInputData%LidarEnabled END SUBROUTINE InflowWind_CopyInitInput SUBROUTINE InflowWind_DestroyInitInput( InitInputData, ErrStat, ErrMsg, DEALLOCATEpointers ) @@ -1265,7 +1265,7 @@ SUBROUTINE InflowWind_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat Re_BufSz = Re_BufSz + 1 ! MSL2SWL Int_BufSz = Int_BufSz + 1 ! BoxExceedAllowIdx Int_BufSz = Int_BufSz + 1 ! BoxExceedAllowF - Int_BufSz = Int_BufSz + 1 ! LidarDisable + Int_BufSz = Int_BufSz + 1 ! LidarEnabled IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -1441,7 +1441,7 @@ SUBROUTINE InflowWind_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat Int_Xferred = Int_Xferred + 1 IntKiBuf(Int_Xferred) = TRANSFER(InData%BoxExceedAllowF, IntKiBuf(1)) Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = TRANSFER(InData%LidarDisable, IntKiBuf(1)) + IntKiBuf(Int_Xferred) = TRANSFER(InData%LidarEnabled, IntKiBuf(1)) Int_Xferred = Int_Xferred + 1 END SUBROUTINE InflowWind_PackInitInput @@ -1667,7 +1667,7 @@ SUBROUTINE InflowWind_UnPackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrS Int_Xferred = Int_Xferred + 1 OutData%BoxExceedAllowF = TRANSFER(IntKiBuf(Int_Xferred), OutData%BoxExceedAllowF) Int_Xferred = Int_Xferred + 1 - OutData%LidarDisable = TRANSFER(IntKiBuf(Int_Xferred), OutData%LidarDisable) + OutData%LidarEnabled = TRANSFER(IntKiBuf(Int_Xferred), OutData%LidarEnabled) Int_Xferred = Int_Xferred + 1 END SUBROUTINE InflowWind_UnPackInitInput diff --git a/modules/openfast-library/src/FAST_Subs.f90 b/modules/openfast-library/src/FAST_Subs.f90 index 09f532a02..7aec9c44f 100644 --- a/modules/openfast-library/src/FAST_Subs.f90 +++ b/modules/openfast-library/src/FAST_Subs.f90 @@ -583,7 +583,7 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, END IF ! lidar - Init%InData_IfW%LidarDisable = .false. ! allowed with OF, but not FF + Init%InData_IfW%LidarEnabled = .true. ! allowed with OF, but not FF Init%InData_IfW%lidar%Tmax = p_FAST%TMax Init%InData_IfW%lidar%HubPosition = ED%y%HubPtMotion%Position(:,1) From 0b4a550e2e6b1b23f7e0ac58afd7772622c3e22e Mon Sep 17 00:00:00 2001 From: andrew-platt Date: Thu, 19 Dec 2024 11:55:29 -0700 Subject: [PATCH 108/161] Update v3.5.5.md with summary --- docs/changelogs/v3.5.5.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/changelogs/v3.5.5.md b/docs/changelogs/v3.5.5.md index 8043f3a3b..0ac516dbc 100644 --- a/docs/changelogs/v3.5.5.md +++ b/docs/changelogs/v3.5.5.md @@ -42,7 +42,9 @@ See GitHub Actions ## Overview -This release includes performance +This release includes multiple small bug-fixes for compilation with CMake, compilation with the IFX compilers, file opening issues when OpenMP is used, and a couple of infrequent segmentation faults from improper usage. One minor feature improvement is the increase in the number of output planes available in _FAST.Farm_ from 99 to 999. + +We recommend all users currently using any 3.5.x version to update to this version. There are no input files changes or API changes for calling from other codes since version 3.5.0. From 2a84dde5e3d2cd3daa58e80482b543caab0beef5 Mon Sep 17 00:00:00 2001 From: Guillaume Jacquenot Date: Sat, 21 Dec 2024 16:10:21 +0100 Subject: [PATCH 109/161] :pencil: Replaced np.sqrt with square comparison to speed up comparison --- openfast_python/openfast_io/turbsim_file.py | 34 ++++++++++----------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/openfast_python/openfast_io/turbsim_file.py b/openfast_python/openfast_io/turbsim_file.py index 2756fff7b..2e8acf4ad 100644 --- a/openfast_python/openfast_io/turbsim_file.py +++ b/openfast_python/openfast_io/turbsim_file.py @@ -16,13 +16,13 @@ File=dict class TurbSimFile(File): - """ + """ Read/write a TurbSim turbulence file (.bts). The object behaves as a dictionary. Main keys --------- - 'u': velocity field, shape (3 x nt x ny x nz) - - 'y', 'z', 't': space and time coordinates + - 'y', 'z', 't': space and time coordinates - 'dt', 'ID', 'info' - 'zTwr', 'uTwr': tower coordinates and field if present (3 x nt x nTwr) - 'zHub', 'uHub': height and velocity at a reference point (usually not hub) @@ -36,7 +36,7 @@ class TurbSimFile(File): ts = TurbSimFile('Turb.bts') print(ts.keys()) - print(ts['u'].shape) + print(ts['u'].shape) """ @@ -55,7 +55,7 @@ def __init__(self,filename=None, **kwargs): self.read(filename, **kwargs) def read(self, filename=None, header_only=False): - """ read BTS file, with field: + """ read BTS file, with field: u (3 x nt x ny x nz) uTwr (3 x nt x nTwr) """ @@ -69,7 +69,7 @@ def read(self, filename=None, header_only=False): raise EmptyFileError('File is empty:',self.filename) scl = np.zeros(3, np.float32); off = np.zeros(3, np.float32) - with open(self.filename, mode='rb') as f: + with open(self.filename, mode='rb') as f: # Reading header info ID, nz, ny, nTwr, nt = struct.unpack('0) @@ -95,7 +95,7 @@ def read(self, filename=None, header_only=False): self['info'] = info self['ID'] = ID self['dt'] = dt - self['y'] = np.arange(ny)*dy + self['y'] = np.arange(ny)*dy self['y'] -= np.mean(self['y']) # y always centered on 0 self['z'] = np.arange(nz)*dz +zBottom self['t'] = np.arange(nt)*dt @@ -104,7 +104,7 @@ def read(self, filename=None, header_only=False): self['uHub'] = uHub def write(self, filename=None): - """ + """ write a BTS file, using the following keys: 'u','z','y','t','uTwr' u (3 x nt x ny x nz) uTwr (3 x nt x nTwr) @@ -151,7 +151,7 @@ def write(self, filename=None): # Providing estimates of uHub and zHub even if these fields are not used zHub,uHub, bHub = self.hubValues() - with open(self.filename, mode='wb') as f: + with open(self.filename, mode='wb') as f: f.write(struct.pack(' Date: Sat, 21 Dec 2024 16:16:05 +0100 Subject: [PATCH 110/161] :wrench: Used list comprehension to speed u_rot creation --- openfast_python/openfast_io/turbsim_file.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/openfast_python/openfast_io/turbsim_file.py b/openfast_python/openfast_io/turbsim_file.py index 2e8acf4ad..26c60daea 100644 --- a/openfast_python/openfast_io/turbsim_file.py +++ b/openfast_python/openfast_io/turbsim_file.py @@ -308,9 +308,7 @@ def compute_rot_avg(self, R): yy, zz = np.meshgrid(self['y'], self['z']) rotor_ind = (yy**2 + (zz - z_hub)**2) < R**2 - u_rot = [] - for u_plane in u_: - u_rot.append(u_plane[rotor_ind].mean()) + u_rot = [u_plane[rotor_ind].mean() for u_plane in u_] self['rot_avg'][i,:] = u_rot From 1b97110a2354d935eaf53a6a5c0d9abf3aaaf4c2 Mon Sep 17 00:00:00 2001 From: Guillaume Jacquenot Date: Sat, 21 Dec 2024 16:18:20 +0100 Subject: [PATCH 111/161] :wrench: Removed unused variables and wrongly declared --- openfast_python/openfast_io/turbsim_file.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/openfast_python/openfast_io/turbsim_file.py b/openfast_python/openfast_io/turbsim_file.py index 26c60daea..e852ea838 100644 --- a/openfast_python/openfast_io/turbsim_file.py +++ b/openfast_python/openfast_io/turbsim_file.py @@ -264,8 +264,6 @@ def __repr__(self): def toDataFrame(self): dfs={} - ny = len(self['y']) - nz = len(self['y']) # Index at mid box iy,iz = self._iMid() From ab386f4003c77c6c05dc7cec3336ee1803710a8c Mon Sep 17 00:00:00 2001 From: Guillaume Jacquenot Date: Sat, 21 Dec 2024 17:04:12 +0100 Subject: [PATCH 112/161] :sparkle: Added a dedicated entrypoint --- openfast_python/openfast_io/turbsim_file.py | 25 ++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/openfast_python/openfast_io/turbsim_file.py b/openfast_python/openfast_io/turbsim_file.py index e852ea838..9cd6ed1e8 100644 --- a/openfast_python/openfast_io/turbsim_file.py +++ b/openfast_python/openfast_io/turbsim_file.py @@ -5,6 +5,7 @@ """ import pandas as pd import numpy as np +import argparse import os import struct import time @@ -311,5 +312,27 @@ def compute_rot_avg(self, R): self['rot_avg'][i,:] = u_rot +def main(): + # Create argument parser + parser = argparse.ArgumentParser( + description="Read an OpenFAST .bts wind field files") + parser.add_argument( + "input_file", + type=str, + help="Path to the input .bts file." + ) + + # Parse arguments + args = parser.parse_args() + + # Process input and output files + input_file = args.input_file + # ts = TurbSimFile('../_tests/TurbSim.bts') + ts = TurbSimFile(input_file) + df = ts.toDataFrame() + print(df['VertProfile'].info()) + print(df['MidLine'].info()) + + if __name__=='__main__': - ts = TurbSimFile('../_tests/TurbSim.bts') + main() From acf173968b21b0ea8cc4bf3e099fa88f34872f60 Mon Sep 17 00:00:00 2001 From: andrew-platt Date: Sat, 21 Dec 2024 16:25:47 -0700 Subject: [PATCH 113/161] SeaState: Add `OMP critical` around file open `!$ OMP critical` directives were added to all other modules in the 3.5.5 updates, but new modules don't include these --- modules/seastate/src/SeaState_Input.f90 | 2 +- modules/seastate/src/SeaState_Output.f90 | 22 +++++++++++++++------- modules/seastate/src/UserWaves.f90 | 20 ++++++++++++-------- 3 files changed, 28 insertions(+), 16 deletions(-) diff --git a/modules/seastate/src/SeaState_Input.f90 b/modules/seastate/src/SeaState_Input.f90 index 71daf185e..0ddedbaff 100644 --- a/modules/seastate/src/SeaState_Input.f90 +++ b/modules/seastate/src/SeaState_Input.f90 @@ -271,7 +271,7 @@ subroutine SeaSt_ParseInput( InputFileName, OutRootName, defWtrDens, defWtrDpth, if (Failed()) return; ! WvKinFile - call ParseVar( FileInfo_In, CurLine, 'WvKinFile', InputFileData%Waves%WvKinFile, ErrStat2, ErrMsg2, UnEc ) + call ParseVar( FileInfo_In, CurLine, 'WvKinFile', InputFileData%Waves%WvKinFile, ErrStat2, ErrMsg2, UnEc, IsPath=.true. ) if (Failed()) return; !------------------------------------------------------------------------------------------------- diff --git a/modules/seastate/src/SeaState_Output.f90 b/modules/seastate/src/SeaState_Output.f90 index 96ff2d0f0..dc202ce5a 100644 --- a/modules/seastate/src/SeaState_Output.f90 +++ b/modules/seastate/src/SeaState_Output.f90 @@ -280,10 +280,12 @@ SUBROUTINE SeaStOut_WriteWvKinFiles( Rootname, SeaSt_Prog, WaveField, WaveDT, X_ DO iFile = 1,7 - CALL GetNewUnit( UnWv ) WvName = TRIM(Rootname) // TRIM(extension(iFile)) + !$OMP critical(fileopen) + CALL GetNewUnit( UnWv ) CALL OpenFOutFile ( UnWv, WvName, ErrStat, ErrMsg ) + !$OMP end critical(fileopen) IF (ErrStat >=AbortErrLev) RETURN call WriteWvKinHeader( UnWv, iFile, Delim, SeaSt_Prog, waveDT, -z_gridPts(1), NGrid, deltaGrid ) @@ -330,11 +332,11 @@ SUBROUTINE SeaStOut_WriteWvKinFiles( Rootname, SeaSt_Prog, WaveField, WaveDT, X_ END DO ! WaveElevation Grid - - CALL GetNewUnit( UnWv ) - WvName = TRIM(Rootname) // '.Elev' + !$OMP critical(fileopen) + CALL GetNewUnit( UnWv ) CALL OpenFOutFile ( UnWv, WvName, ErrStat, ErrMsg ) + !$OMP end critical(fileopen) IF (ErrStat >=AbortErrLev) RETURN @@ -444,13 +446,15 @@ subroutine SeaStOut_WriteWaveElev0( Rootname, NStepWave, NGrid, WaveElev1, WaveE ErrMsg = "" Frmt = '(F12.4,ES12.4e2)' Frmt2 = '(2(A12))' - CALL GetNewUnit( UnWv ) WvName = TRIM(Rootname) // '.Elev' i = NGrid(1) / 2 + 1 j = NGrid(2) / 2 + 1 + !$OMP critical(fileopen) + CALL GetNewUnit( UnWv ) CALL OpenFOutFile ( UnWv, WvName, ErrStat, ErrMsg ) + !$OMP end critical(fileopen) IF (ErrStat >=AbortErrLev) RETURN ! WRITE (UnWv,'(A)', IOSTAT=ErrStat) 'This wave elevation (0,0) file was generated by '//TRIM( SeaSt_Prog%Name )//& ! ' '//TRIM( SeaSt_Prog%Ver )//' on '//CurDate()//' at '//CurTime()//'.' @@ -718,9 +722,11 @@ SUBROUTINE SeaStOut_OpenOutput( SeaSt_ProgDesc, OutRootName, p, InitOut, ErrSta ! Open the file for output OutFileName = TRIM(OutRootName)//'.out' + + !$OMP critical(fileopen) CALL GetNewUnit( p%UnOutFile ) - CALL OpenFOutFile ( p%UnOutFile, OutFileName, ErrStat, ErrMsg ) + !$OMP end critical(fileopen) IF (ErrStat >=AbortErrLev) RETURN @@ -1011,9 +1017,11 @@ SUBROUTINE SeaStOut_WrSummaryFile(InitInp, InputFileData, p, ErrStat, ErrMsg ) SummaryName = trim(InitInp%OutRootName)//'.sum' UnSum = -1 - CALL GetNewUnit( UnSum ) + !$OMP critical(fileopen) + CALL GetNewUnit( UnSum ) CALL OpenFOutFile ( UnSum, SummaryName, ErrStat2, ErrMsg2 ) + !$OMP end critical(fileopen) CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) IF (ErrStat >=AbortErrLev) RETURN diff --git a/modules/seastate/src/UserWaves.f90 b/modules/seastate/src/UserWaves.f90 index 12eed126e..4dbb0c79b 100644 --- a/modules/seastate/src/UserWaves.f90 +++ b/modules/seastate/src/UserWaves.f90 @@ -144,14 +144,14 @@ SUBROUTINE WaveElev_ReadFile ( InitInp, WaveElevData, ErrStat, ErrMsg ) ErrStat = ErrID_None ErrMsg = "" - ! Get a unit number for reading in the file - CALL GetNewUnit( WaveElevUnit ) - ! Assemble the filename for the wave elevation data. WaveElevData%FileName = TRIM(InitInp%WvKinFile)//'.Elev' ! Open the file containing the wave elevation timeseries + !$OMP critical(fileopen) + CALL GetNewUnit( WaveElevUnit ) CALL OpenFInpFile( WaveElevUnit, WaveElevData%FileName, ErrStatTmp, ErrMsgTmp ) + !$OMP end critical(fileopen) CALL SetErrStat( ErrStatTmp, ErrMsgTmp, ErrStat,ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) THEN CLOSE ( WaveElevUnit ) @@ -492,11 +492,13 @@ SUBROUTINE UserWaves_Init ( InitInp, InitOut, WaveField, ErrStat, ErrMsg ) ! Read the first file and set the initial values of the DO iFile = 1,7 - CALL GetNewUnit( UnWv ) FileName = TRIM(InitInp%WvKinFile) // TRIM(extension(iFile)) + !$OMP critical(fileopen) + CALL GetNewUnit( UnWv ) CALL OpenFInpFile ( UnWv, FileName, ErrStatTmp, ErrMsgTmp ) + !$OMP end critical(fileopen) IF ( ErrStatTmp /= 0 ) THEN ErrMsgTmp = 'Failed to open wave kinematics file, ' // TRIM(FileName) CALL SetErrStat( ErrID_Fatal, ErrMsgTmp, ErrStat, ErrMsg, RoutineName ) @@ -552,11 +554,13 @@ SUBROUTINE UserWaves_Init ( InitInp, InitOut, WaveField, ErrStat, ErrMsg ) end do ! WaveElev - CALL GetNewUnit( UnWv ) FileName = TRIM(InitInp%WvKinFile) // '.Elev' + !$OMP critical(fileopen) + CALL GetNewUnit( UnWv ) CALL OpenFInpFile ( UnWv, FileName, ErrStatTmp, ErrMsgTmp ) + !$OMP end critical(fileopen) IF ( ErrStatTmp /= 0 ) THEN ErrMsgTmp = 'Failed to open wave elevation file, ' // TRIM(FileName) CALL SetErrStat( ErrID_Fatal, ErrMsgTmp, ErrStat, ErrMsg, RoutineName ) @@ -691,14 +695,14 @@ SUBROUTINE WaveComp_ReadFile ( InitInp, WaveDOmega, WaveCompData, ErrStat, ErrMs ErrStat = ErrID_None ErrMsg = "" - ! Get a unit number for reading in the file - CALL GetNewUnit( WaveCompUnit ) - ! Assemble the filename for the wave component data. WaveCompData%FileName = TRIM(InitInp%WvKinFile) ! Open the file containing the list of wave components + !$OMP critical(fileopen) + CALL GetNewUnit( WaveCompUnit ) CALL OpenFInpFile( WaveCompUnit, WaveCompData%FileName, ErrStatTmp, ErrMsgTmp ) + !$OMP end critical(fileopen) CALL SetErrStat( ErrStatTmp, ErrMsgTmp, ErrStat,ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) THEN CALL CleanUpError() From cad9c8456a3b629adce8f5679d189cde1db328e6 Mon Sep 17 00:00:00 2001 From: andrew-platt Date: Sun, 22 Dec 2024 14:30:06 -0700 Subject: [PATCH 114/161] ADsk: update reg test results after correcting DiskAvgVel --- reg_tests/r-test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reg_tests/r-test b/reg_tests/r-test index b3824f2d3..ba6813f1f 160000 --- a/reg_tests/r-test +++ b/reg_tests/r-test @@ -1 +1 @@ -Subproject commit b3824f2d3a4cd4cb826aa4ac95b6e39a99e66d43 +Subproject commit ba6813f1f241411eef2783f29fa644c5080a1d8a From f12abe7332b33d28bb168a2e0780eb1ae6e6deb4 Mon Sep 17 00:00:00 2001 From: andrew-platt Date: Sun, 22 Dec 2024 14:35:04 -0700 Subject: [PATCH 115/161] IfW: add VTK slice in XY output to driver This allows visualizing a slice through hub-height (or other height) when compairing with a simulation. --- modules/inflowwind/src/InflowWind_Driver.f90 | 17 ++++ .../inflowwind/src/InflowWind_Driver_Subs.f90 | 81 +++++++++++++++++++ .../src/InflowWind_Driver_Types.f90 | 3 + modules/inflowwind/src/InflowWind_IO.f90 | 78 +++++++++++++++++- reg_tests/r-test | 2 +- 5 files changed, 179 insertions(+), 2 deletions(-) diff --git a/modules/inflowwind/src/InflowWind_Driver.f90 b/modules/inflowwind/src/InflowWind_Driver.f90 index 2ca88e84f..ded55401b 100644 --- a/modules/inflowwind/src/InflowWind_Driver.f90 +++ b/modules/inflowwind/src/InflowWind_Driver.f90 @@ -505,6 +505,23 @@ PROGRAM InflowWind_Driver END IF END IF + + IF (SettingsFlags%XYslice) THEN + CALL IfW_WriteXYslice( InflowWind_p%FlowField, InflowWind_InitInp%RootName, Settings%XYslice_height, ErrStat, ErrMsg ) + IF (ErrStat > ErrID_None) THEN + CALL WrScr( TRIM(ErrMsg) ) + IF ( ErrStat >= AbortErrLev ) THEN + CALL DriverCleanup() + CALL ProgAbort( ErrMsg ) + ELSEIF ( IfWDriver_Verbose >= 7_IntKi ) THEN + CALL WrScr(NewLine//' IfW_WriteXYslice returned: ErrStat: '//TRIM(Num2LStr(ErrStat))) + END IF + ELSE IF ( IfWDriver_Verbose >= 5_IntKi ) THEN + CALL WrScr(NewLine//'IfW_WriteXYslice CALL returned without errors.'//NewLine) + END IF + END IF + + !-------------------------------------------------------------------------------------------------------------------------------- !-=-=- Other Setup -=-=- !-------------------------------------------------------------------------------------------------------------------------------- diff --git a/modules/inflowwind/src/InflowWind_Driver_Subs.f90 b/modules/inflowwind/src/InflowWind_Driver_Subs.f90 index 186b3435d..d06ec0378 100644 --- a/modules/inflowwind/src/InflowWind_Driver_Subs.f90 +++ b/modules/inflowwind/src/InflowWind_Driver_Subs.f90 @@ -1308,6 +1308,40 @@ SUBROUTINE ReadDvrIptFile( DvrFileName, DvrFlags, DvrSettings, ProgInfo, ErrStat ENDIF + !------------------------------------------------------------------------------------------------- + ! XY slice output + !------------------------------------------------------------------------------------------------- + + ! Header + CALL ReadCom( UnIn, FileName,' XY slice output, comment line', ErrStatTmp, ErrMsgTmp, UnEchoLocal ) + IF ( ErrStatTmp /= ErrID_None ) THEN + CALL SetErrStat(ErrID_Fatal,ErrMsgTmp,ErrStat,ErrMsg,RoutineName) + CALL CleanupEchoFile( EchoFileContents, UnEchoLocal ) + CLOSE( UnIn ) + RETURN + ENDIF + + + ! XYslice -- Output a VTK slice in XY + CALL ReadVar( UnIn, FileName,DvrFlags%XYslice,'XYslice',' VTK slice in XY?', & + ErrStatTmp,ErrMsgTmp, UnEchoLocal ) + IF ( ErrStatTmp /= ErrID_None ) THEN + CALL SetErrStat(ErrID_Fatal,ErrMsgTmp,ErrStat,ErrMsg,RoutineName) + CALL CleanupEchoFile( EchoFileContents, UnEchoLocal ) + CLOSE( UnIn ) + RETURN + ENDIF + + ! XYslice_height -- Height for XY slice + CALL ReadVar( UnIn, FileName,DvrSettings%XYslice_height,'XYslice_height',' VTK slice height', & + ErrStatTmp,ErrMsgTmp, UnEchoLocal ) + IF ( ErrStatTmp /= ErrID_None ) THEN + CALL SetErrStat(ErrID_Fatal,ErrMsgTmp,ErrStat,ErrMsg,RoutineName) + CALL CleanupEchoFile( EchoFileContents, UnEchoLocal ) + CLOSE( UnIn ) + RETURN + ENDIF + ! Close the echo and input file CALL CleanupEchoFile( EchoFileContents, UnEchoLocal ) @@ -2623,6 +2657,49 @@ subroutine IfW_WriteVTK(FF, FileRootName, ErrStat, ErrMsg) end subroutine IfW_WriteVTK +subroutine IfW_WriteXYslice(FF, FileRootName, XYslice_height, ErrStat, ErrMsg) + type(FlowFieldType), intent(in) :: FF !< Parameters + character(*), intent(in) :: FileRootName !< RootName for output files + real(ReKi), intent(in) :: XYslice_height + integer(IntKi), intent(out) :: ErrStat !< Error status of the operation + character(*), intent(out) :: ErrMsg !< Error message if ErrStat /= ErrID_None + + character(*), parameter :: RoutineName = "IfW_WriteXYslice" + type(Grid3DFieldType) :: G3D + integer(IntKi) :: unit + integer(IntKi) :: ErrStat2 + character(ErrMsgLen) :: ErrMsg2 + + ErrStat = ErrID_None + ErrMsg = "" + + ! Get new unit for writing file + call GetNewUnit(unit, ErrStat2, ErrMsg2) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + + ! Switch based on field type + select case (FF%FieldType) + + case (Uniform_FieldType) + call Uniform_to_Grid3D(FF%Uniform, FF%VelInterpCubic, G3D, ErrStat2, ErrMsg2) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + if (ErrStat < AbortErrLev) then + call Grid3D_WriteVTKsliceXY(G3D, FileRootName, XYslice_height, unit, ErrStat2, ErrMsg2) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + end if + + case (Grid3D_FieldType) + call Grid3D_WriteVTKsliceXY(FF%Grid3D, FileRootName, XYslice_height, unit, ErrStat, ErrMsg) + + case default + ErrStat = ErrID_Warn + ErrMsg = RoutineName//': Field type '//TRIM(Num2LStr(FF%FieldType))// & + ' cannot be converted to VTK format.' + end select +end subroutine IfW_WriteXYslice + + !> This routine exists only to support the development of the module. It will not be needed after the module is complete. SUBROUTINE printSettings( DvrFlags, DvrSettings ) ! The arguments @@ -2671,6 +2748,10 @@ SUBROUTINE printSettings( DvrFlags, DvrSettings ) CALL WrScr(' FFTOutputInit: '//FLAG(DvrSettings%FFTOutput%Initialized)// ' Unit #: '//TRIM(Num2LStr(DvrSettings%FFTOutput%Unit))) CALL WrScr(' PointsVelOutputInit: '//FLAG(DvrSettings%PointsVelOutput%Initialized)// ' Unit #: '//TRIM(Num2LStr(DvrSettings%PointsVelOutput%Unit))) CALL WrScr(' PointsAccOutputInit: '//FLAG(DvrSettings%PointsVelOutput%Initialized)// ' Unit #: '//TRIM(Num2LStr(DvrSettings%PointsVelOutput%Unit))) + CALL WrScr(' XYslice: '//FLAG(DvrFlags%XYslice)) +if (DvrFlags%XYslice) then + CALL WrScr(' XYslice_height '//TRIM(Num2LStr(DvrSettings%XYslice_height))) +end if END SUBROUTINE printSettings diff --git a/modules/inflowwind/src/InflowWind_Driver_Types.f90 b/modules/inflowwind/src/InflowWind_Driver_Types.f90 index 669303cf6..c16a2ceb6 100644 --- a/modules/inflowwind/src/InflowWind_Driver_Types.f90 +++ b/modules/inflowwind/src/InflowWind_Driver_Types.f90 @@ -76,6 +76,8 @@ MODULE InflowWind_Driver_Types LOGICAL :: WrBladed = .FALSE. !< Requested file conversion to Bladed format? LOGICAL :: WrVTK = .FALSE. !< Requested file output as VTK? LOGICAL :: WrUniform = .FALSE. !< Requested file output as Uniform wind format? + + LOGICAL :: XYslice = .FALSE. !< Take XY slice at one elevation END TYPE IfWDriver_Flags @@ -105,6 +107,7 @@ MODULE InflowWind_Driver_Types TYPE(OutputFile) :: FFTOutput TYPE(OutputFile) :: PointsVelOutput + REAL(ReKi) :: XYslice_height = 0.0_ReKi !< height to take XY slice END TYPE IfWDriver_Settings diff --git a/modules/inflowwind/src/InflowWind_IO.f90 b/modules/inflowwind/src/InflowWind_IO.f90 index 35fbd4d6d..e4859a300 100644 --- a/modules/inflowwind/src/InflowWind_IO.f90 +++ b/modules/inflowwind/src/InflowWind_IO.f90 @@ -39,7 +39,8 @@ module InflowWind_IO public :: Uniform_WriteHH, & Grid3D_WriteBladed, & Grid3D_WriteHAWC, & - Grid3D_WriteVTK + Grid3D_WriteVTK, & + Grid3D_WriteVTKsliceXY type(ProgDesc), parameter :: InflowWind_IO_Ver = ProgDesc('InflowWind_IO', '', '') @@ -2943,4 +2944,79 @@ subroutine Grid3D_WriteHAWC(G3D, FileRootName, unit, ErrStat, ErrMsg) end subroutine Grid3D_WriteHAWC + +subroutine Grid3D_WriteVTKsliceXY(G3D, FileRootName, XYslice_height, unit, ErrStat, ErrMsg) + + type(Grid3DFieldType), intent(in) :: G3D !< Parameters + character(*), intent(in) :: FileRootName !< RootName for output files + real(ReKi), intent(in) :: XYslice_height + integer(IntKi), intent(in) :: unit !< Error status of the operation + integer(IntKi), intent(out) :: ErrStat !< Error status of the operation + character(*), intent(out) :: ErrMsg !< Error message if ErrStat /= ErrID_None + + character(*), parameter :: RoutineName = 'Grid3D_WriteVTKsliceXY' + character(1024) :: RootPathName + character(1024) :: FileName + character(3) :: ht_str + integer :: it !< time index for slice + integer :: ix + integer :: iy + integer :: iz + real(ReKi) :: time !< time for this slice + real(ReKi) :: ht !< nearest grid slice elevation + integer(IntKi) :: ErrStat2 + character(ErrMsgLen) :: ErrMsg2 + + call GetPath(FileRootName, RootPathName) + RootPathName = trim(RootPathName)//PathSep//"vtk" + call MkDir(trim(RootPathName)) ! make this directory if it doesn't already exist + + ! get indices for this slice + iz = nint((G3D%GridBase + XYslice_height)*G3D%InvDZ) + ht = real(iz,ReKi) / G3D%InvDZ + G3D%GridBase ! nearest height index + write(ht_str,'(i3)') nint(ht) + + ! check for errors in slice height + if (iz <= 0_IntKi) then + call SetErrStat(ErrID_Warn,"No grid points near XY slice height of "//trim(num2lstr(XYslice_height))//". Skipping writing slice file.",ErrStat,ErrMsg,RoutineName) + return + endif + + ! Loop through time steps + do it = 1, G3D%NSteps + + time = real(it - 1, ReKi)*G3D%DTime + + ! Create the output vtk file with naming /vtk/DisYZ.t.vtk + FileName = trim(RootPathName)//PathSep//"DisXY.Z"//ht_str//".t"//trim(num2lstr(it))//".vtp" + + ! see WrVTK_SP_header + call OpenFOutFile(unit, TRIM(FileName), ErrStat2, ErrMsg2) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + + write (unit, '(A)') '# vtk DataFile Version 3.0' + write (unit, '(A)') "InflowWind XY Slice at T= "//trim(num2lstr(time))//" s" + write (unit, '(A)') 'ASCII' + write (unit, '(A)') 'DATASET STRUCTURED_POINTS' + + ! Note: gridVals must be stored such that the left-most dimension is X + ! and the right-most dimension is Z (see WrVTK_SP_vectors3D) + write (unit, '(A,3(i5,1X))') 'DIMENSIONS ', G3D%NSteps, G3D%NYGrids, 1 + write (unit, '(A,3(f10.2,1X))') 'ORIGIN ', G3D%InitXPosition+time*G3D%MeanWS, -G3D%YHWid, ht + write (unit, '(A,3(f10.2,1X))') 'SPACING ', -G3D%Dtime*G3D%MeanWS, 1.0_ReKi/G3D%InvDY, 0.0_ReKi + write (unit, '(A,i9)') 'POINT_DATA ', G3D%NSteps*G3D%NYGrids + write (unit, '(A)') 'VECTORS DisXY float' + + do iy = 1, G3D%NYGrids + do ix = 1, G3D%NSteps ! time and X are interchangeable + write (unit, '(3(f10.2,1X))') G3D%Vel(:, iy, iz, ix) + end do + end do + + enddo + + close (unit) +end subroutine Grid3D_WriteVTKsliceXY + end module InflowWind_IO diff --git a/reg_tests/r-test b/reg_tests/r-test index b3824f2d3..a26a6276a 160000 --- a/reg_tests/r-test +++ b/reg_tests/r-test @@ -1 +1 @@ -Subproject commit b3824f2d3a4cd4cb826aa4ac95b6e39a99e66d43 +Subproject commit a26a6276ac192bfc5b3ef4338e9cff3f175a4210 From 257bd1cb11ddeed7035d2a815622c896706f3c17 Mon Sep 17 00:00:00 2001 From: andrew-platt Date: Wed, 21 Jun 2023 14:54:49 -0600 Subject: [PATCH 116/161] IfW: improve error handling on XY plane export --- modules/inflowwind/src/InflowWind_IO.f90 | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/modules/inflowwind/src/InflowWind_IO.f90 b/modules/inflowwind/src/InflowWind_IO.f90 index e4859a300..8b813628b 100644 --- a/modules/inflowwind/src/InflowWind_IO.f90 +++ b/modules/inflowwind/src/InflowWind_IO.f90 @@ -2967,6 +2967,9 @@ subroutine Grid3D_WriteVTKsliceXY(G3D, FileRootName, XYslice_height, unit, ErrSt integer(IntKi) :: ErrStat2 character(ErrMsgLen) :: ErrMsg2 + ErrStat = ErrID_None + ErrMsg = "" + call GetPath(FileRootName, RootPathName) RootPathName = trim(RootPathName)//PathSep//"vtk" call MkDir(trim(RootPathName)) ! make this directory if it doesn't already exist @@ -2977,7 +2980,7 @@ subroutine Grid3D_WriteVTKsliceXY(G3D, FileRootName, XYslice_height, unit, ErrSt write(ht_str,'(i3)') nint(ht) ! check for errors in slice height - if (iz <= 0_IntKi) then + if (iz <= 0_IntKi .or. iz > G3D%NZGrids) then call SetErrStat(ErrID_Warn,"No grid points near XY slice height of "//trim(num2lstr(XYslice_height))//". Skipping writing slice file.",ErrStat,ErrMsg,RoutineName) return endif @@ -3007,16 +3010,16 @@ subroutine Grid3D_WriteVTKsliceXY(G3D, FileRootName, XYslice_height, unit, ErrSt write (unit, '(A,3(f10.2,1X))') 'SPACING ', -G3D%Dtime*G3D%MeanWS, 1.0_ReKi/G3D%InvDY, 0.0_ReKi write (unit, '(A,i9)') 'POINT_DATA ', G3D%NSteps*G3D%NYGrids write (unit, '(A)') 'VECTORS DisXY float' - + do iy = 1, G3D%NYGrids do ix = 1, G3D%NSteps ! time and X are interchangeable write (unit, '(3(f10.2,1X))') G3D%Vel(:, iy, iz, ix) end do end do + close (unit) enddo - close (unit) end subroutine Grid3D_WriteVTKsliceXY end module InflowWind_IO From 487e4647d15d2c0de19318876100d4c6a47921b9 Mon Sep 17 00:00:00 2001 From: andrew-platt Date: Sun, 22 Dec 2024 14:36:55 -0700 Subject: [PATCH 117/161] IfW: add registry file for driver For generating InflowWind_Driver_Types.f90 --- modules/inflowwind/CMakeLists.txt | 1 + .../src/InflowWind_Driver_Registry.txt | 91 +++ .../src/InflowWind_Driver_Types.f90 | 598 +++++++++++++++--- vs-build/InflowWind/InflowWind_driver.vfproj | 17 + vs-build/RunRegistry.bat | 6 + 5 files changed, 622 insertions(+), 91 deletions(-) create mode 100644 modules/inflowwind/src/InflowWind_Driver_Registry.txt diff --git a/modules/inflowwind/CMakeLists.txt b/modules/inflowwind/CMakeLists.txt index 8e5b3c2e3..1e9b3a306 100644 --- a/modules/inflowwind/CMakeLists.txt +++ b/modules/inflowwind/CMakeLists.txt @@ -19,6 +19,7 @@ if (GENERATE_TYPES) generate_f90_types(src/InflowWind_IO.txt ${CMAKE_CURRENT_LIST_DIR}/src/InflowWind_IO_Types.f90 -noextrap) generate_f90_types(src/Lidar.txt ${CMAKE_CURRENT_LIST_DIR}/src/Lidar_Types.f90) generate_f90_types(src/InflowWind.txt ${CMAKE_CURRENT_LIST_DIR}/src/InflowWind_Types.f90) + generate_f90_types(src/InflowWind_Driver_Registry.txt ${CMAKE_CURRENT_LIST_DIR}/src/InflowWind_Driver_Types.f90 -noextrap) endif() # InflowWind object library diff --git a/modules/inflowwind/src/InflowWind_Driver_Registry.txt b/modules/inflowwind/src/InflowWind_Driver_Registry.txt new file mode 100644 index 000000000..3863019d7 --- /dev/null +++ b/modules/inflowwind/src/InflowWind_Driver_Registry.txt @@ -0,0 +1,91 @@ +#---------------------------------------------------------------------------------------------------------------------------------- +# Registry for IfW_Interp, creates MODULE IfW_Interp_Types +# Module IfW_Interp_Types contains all of the user-defined types needed in IfW_FF. It also contains copy, destroy, pack, and +# unpack routines associated with each defined data types. +#---------------------------------------------------------------------------------------------------------------------------------- +# keyword +#---------------------------------------------------------------------------------------------------------------------------------- + +include Registry_NWTC_Library.txt + +#---------------------------------------------------------------------------------------------------------------------------------- +typedef InflowWind_Driver OutputFile character(1024) Name - "" - "Filename for output from points read in from points file" - +typedef ^ ^ integer Unit - -1 - "Unit number for the output file for the Points file output" - +typedef ^ ^ logical Initialized - .false. - "Flag indicating that file has been initialized" - + +# This contains flags to note if the settings were made. This same data structure is +# used both during the driver input file and the command line options. +# +# NOTE: The WindFileType is only set if it is given as a command line option. Otherwise +# it is handled internally by InflowWInd. +# +# NOTE: The wind direction is specified by the InflowWind input file. +#---------------------------------------------------------------------------------------------------------------------------------- +typedef InflowWind_Driver IfWDriver_Flags logical DvrIptFile - .false. - "Was an input file name given on the command line?" - +typedef ^ ^ logical IfWIptFile - .false. - "Was an InflowWind input file requested?" - +typedef ^ ^ logical Summary - .false. - "create a summary at command line? (data extents in the wind file)" - +typedef ^ ^ logical SummaryFile - .false. - "create a summary file of the output?" - +typedef ^ ^ logical TStart - .false. - "specified a start time" - +typedef ^ ^ logical NumTimeSteps - .false. - "specified a number of timesteps to process" - +typedef ^ ^ logical NumTimeStepsDefault - .false. - "specified a 'DEFAULT' for number of timesteps to process" - +typedef ^ ^ logical DT - .false. - "specified a resolution in time" - +typedef ^ ^ logical DTDefault - .false. - "specified a 'DEFAULT' for the time resolution" - + +typedef ^ ^ logical FFTcalc - .false. - "do an FFT" - + +typedef ^ ^ logical WindGrid - .false. - "Requested output of wind data on a grid -- input file option only" - +typedef ^ ^ logical XRange - .false. - "specified a range of x -- command line option only -- stored as GridCtrCoord and GridDelta" - +typedef ^ ^ logical YRange - .false. - "specified a range of y -- command line option only -- stored as GridCtrCoord and GridDelta" - +typedef ^ ^ logical ZRange - .false. - "specified a range of z -- command line option only -- stored as GridCtrCoord and GridDelta" - +typedef ^ ^ logical Dx - .false. - "specified a resolution in x -- command line option only, 0.0 otherwise" - +typedef ^ ^ logical Dy - .false. - "speficied a resolution in y" - +typedef ^ ^ logical Dz - .false. - "specified a resolution in z" - + +typedef ^ ^ logical PointsFile - .false. - "points filename to read in" - +typedef ^ ^ logical OutputAccel - .false. - "flag to calculate and output wind acceleration in addition to velocity" - + +typedef ^ ^ logical Verbose - .false. - "Verbose error reporting" - +typedef ^ ^ logical VVerbose - .false. - "Very Verbose error reporting" - +typedef ^ ^ logical BoxExceedAllowF - .false. - "set flag to allow exceeding wind box boundaries for FF files (for diagnostic purposes)" - + +typedef ^ ^ logical WrHAWC - .false. - "Requested file conversion to HAWC2 format?" - +typedef ^ ^ logical WrBladed - .false. - "Requested file conversion to Bladed format?" - +typedef ^ ^ logical WrVTK - .false. - "Requested file output as VTK?" - +typedef ^ ^ logical WrUniform - .false. - "Requested file output as Uniform wind format?" - + +typedef ^ ^ logical XYslice - .false. - "Take XY slice at one elevation" - + + + +# This contains all the settings (possible passed in arguments). +#---------------------------------------------------------------------------------------------------------------------------------- +typedef InflowWind_Driver IfWDriver_Settings character(1024) DvrIptFileName - "" - "Driver input file name" - +typedef ^ ^ character(1024) IfWIptFileName - "" - "Filename of InflowWind input file to read (if no driver input file)" - +typedef ^ ^ character(1024) SummaryFileName - "" - "Filename for the summary information output" - + +typedef ^ ^ character(1024) PointsFileName - "" - "Filename of points file to read in" - + +typedef ^ ^ IntKi NumTimeSteps - 0 - "Number of timesteps" - +typedef ^ ^ DbKi DT - 0.0_DbKi - "resolution of time" s +typedef ^ ^ DbKi TStart - 0.0_DbKi - "range of time -- end time converted from TRange (command line option only)" s + +typedef ^ ^ ReKi FFTcoord(1:3) - 0.0_ReKi - "(x,y,z) coordinate to do an FFT at" (m) + +typedef ^ ^ ReKi GridDelta(1:3) - 0.0_ReKi - "(GridDx,GridDy,GridDz) -- grid point spacing" (m) +typedef ^ ^ IntKi GridN(1:3) - 1_IntKi - "(GridNx,GridNy,GridNz) -- number of grid points" - + +typedef ^ ^ ReKi XRange(1:2) - 0.0_ReKi - "Range in the x-direction for the gridded data" (m) +typedef ^ ^ ReKi YRange(1:2) - 0.0_ReKi - "Range in the y-direction for the gridded data" (m) +typedef ^ ^ ReKi ZRange(1:2) - 0.0_ReKi - "Range in the z-direction for the gridded data" (m) + +typedef ^ ^ ProgDesc ProgInfo - - - "Program info" - +typedef ^ ^ OutputFile WindGridOutput - - - "Wind grid file handling" - +typedef ^ ^ OutputFile FFTOutput - - - "FFT file handling" - +typedef ^ ^ OutputFile PointsVelOutput - - - "Points output velocity file handling" - + +typedef ^ ^ IntKi NOutWindXY - 0 - "Number of XY planes for output .XY.t.vtk [0 to 9]" - +typedef ^ ^ ReKi OutWindZ : - - "Z coordinates of XY planes for output [1 to NOutWindXY] [unused for NOutWindXY=0]" (m) +typedef ^ ^ IntKi NOutWindXZ - 0 - "Number of YZ planes for output .YZ.t.vtk [0 to 9]" - +typedef ^ ^ ReKi OutWindY : - - "Y coordinates of YZ planes for output [1 to NOutWindYZ] [unused for NOutWindYZ=0]" (m) +typedef ^ ^ IntKi NOutWindYZ - 0 - "Number of YZ planes for output .YZ.t.vtk [0 to 9]" - +typedef ^ ^ ReKi OutWindX : - - "X coordinates of YZ planes for output [1 to NOutWindYZ] [unused for NOutWindYZ=0]" (m) diff --git a/modules/inflowwind/src/InflowWind_Driver_Types.f90 b/modules/inflowwind/src/InflowWind_Driver_Types.f90 index c16a2ceb6..7babb42de 100644 --- a/modules/inflowwind/src/InflowWind_Driver_Types.f90 +++ b/modules/inflowwind/src/InflowWind_Driver_Types.f90 @@ -1,114 +1,530 @@ -!********************************************************************************************************************************** +!STARTOFREGISTRYGENERATEDFILE 'InflowWind_Driver_Types.f90' ! -! MODULE: IfW_Driver_Types - This module contains types used by the InflowWind Driver program to store arguments passed in +! WARNING This file is generated automatically by the FAST registry. +! Do not edit. Your changes to this file will be lost. ! -! The types listed here are used within the InflowWind Driver program to store the settings. These settings are read in as -! command line arguments, then stored within these types. +! FAST Registry +!********************************************************************************************************************************* +! InflowWind_Driver_Types +!................................................................................................................................. +! This file is part of InflowWind_Driver. ! -!********************************************************************************************************************************** +! Copyright (C) 2012-2016 National Renewable Energy Laboratory ! -!.................................................................................................................................. -! LICENSING -! Copyright (C) 2015 National Renewable Energy Laboratory +! Licensed under the Apache License, Version 2.0 (the "License"); +! you may not use this file except in compliance with the License. +! You may obtain a copy of the License at ! -! This file is part of InflowWind. +! http://www.apache.org/licenses/LICENSE-2.0 ! -! InflowWind is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as -! published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. +! Unless required by applicable law or agreed to in writing, software +! distributed under the License is distributed on an "AS IS" BASIS, +! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +! See the License for the specific language governing permissions and +! limitations under the License. ! -! This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty -! of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. ! -! You should have received a copy of the GNU General Public License along with InflowWind. -! If not, see . +! W A R N I N G : This file was automatically generated from the FAST registry. Changes made to this file may be lost. ! -!********************************************************************************************************************************** - +!********************************************************************************************************************************* +!> This module contains the user-defined types needed in InflowWind_Driver. It also contains copy, destroy, pack, and +!! unpack routines associated with each defined data type. This code is automatically generated by the FAST Registry. MODULE InflowWind_Driver_Types +!--------------------------------------------------------------------------------------------------------------------------------- +USE NWTC_Library +IMPLICIT NONE +! ========= OutputFile ======= + TYPE, PUBLIC :: OutputFile + character(1024) :: Name !< Filename for output from points read in from points file [-] + INTEGER(IntKi) :: Unit = -1 !< Unit number for the output file for the Points file output [-] + LOGICAL :: Initialized = .false. !< Flag indicating that file has been initialized [-] + END TYPE OutputFile +! ======================= +! ========= IfWDriver_Flags ======= + TYPE, PUBLIC :: IfWDriver_Flags + LOGICAL :: DvrIptFile = .false. !< Was an input file name given on the command line? [-] + LOGICAL :: IfWIptFile = .false. !< Was an InflowWind input file requested? [-] + LOGICAL :: Summary = .false. !< create a summary at command line? (data extents in the wind file) [-] + LOGICAL :: SummaryFile = .false. !< create a summary file of the output? [-] + LOGICAL :: TStart = .false. !< specified a start time [-] + LOGICAL :: NumTimeSteps = .false. !< specified a number of timesteps to process [-] + LOGICAL :: NumTimeStepsDefault = .false. !< specified a 'DEFAULT' for number of timesteps to process [-] + LOGICAL :: DT = .false. !< specified a resolution in time [-] + LOGICAL :: DTDefault = .false. !< specified a 'DEFAULT' for the time resolution [-] + LOGICAL :: FFTcalc = .false. !< do an FFT [-] + LOGICAL :: WindGrid = .false. !< Requested output of wind data on a grid -- input file option only [-] + LOGICAL :: XRange = .false. !< specified a range of x -- command line option only -- stored as GridCtrCoord and GridDelta [-] + LOGICAL :: YRange = .false. !< specified a range of y -- command line option only -- stored as GridCtrCoord and GridDelta [-] + LOGICAL :: ZRange = .false. !< specified a range of z -- command line option only -- stored as GridCtrCoord and GridDelta [-] + LOGICAL :: Dx = .false. !< specified a resolution in x -- command line option only, 0.0 otherwise [-] + LOGICAL :: Dy = .false. !< speficied a resolution in y [-] + LOGICAL :: Dz = .false. !< specified a resolution in z [-] + LOGICAL :: PointsFile = .false. !< points filename to read in [-] + LOGICAL :: OutputAccel = .false. !< flag to calculate and output wind acceleration in addition to velocity [-] + LOGICAL :: Verbose = .false. !< Verbose error reporting [-] + LOGICAL :: VVerbose = .false. !< Very Verbose error reporting [-] + LOGICAL :: BoxExceedAllowF = .false. !< set flag to allow exceeding wind box boundaries for FF files (for diagnostic purposes) [-] + LOGICAL :: WrHAWC = .false. !< Requested file conversion to HAWC2 format? [-] + LOGICAL :: WrBladed = .false. !< Requested file conversion to Bladed format? [-] + LOGICAL :: WrVTK = .false. !< Requested file output as VTK? [-] + LOGICAL :: WrUniform = .false. !< Requested file output as Uniform wind format? [-] + LOGICAL :: XYslice = .false. !< Take XY slice at one elevation [-] + END TYPE IfWDriver_Flags +! ======================= +! ========= IfWDriver_Settings ======= + TYPE, PUBLIC :: IfWDriver_Settings + character(1024) :: DvrIptFileName !< Driver input file name [-] + character(1024) :: IfWIptFileName !< Filename of InflowWind input file to read (if no driver input file) [-] + character(1024) :: SummaryFileName !< Filename for the summary information output [-] + character(1024) :: PointsFileName !< Filename of points file to read in [-] + INTEGER(IntKi) :: NumTimeSteps = 0 !< Number of timesteps [-] + REAL(DbKi) :: DT = 0.0_DbKi !< resolution of time [s] + REAL(DbKi) :: TStart = 0.0_DbKi !< range of time -- end time converted from TRange (command line option only) [s] + REAL(ReKi) :: FFTcoord(1:3) = 0.0_ReKi !< (x,y,z) coordinate to do an FFT at [(m)] + REAL(ReKi) :: GridDelta(1:3) = 0.0_ReKi !< (GridDx,GridDy,GridDz) -- grid point spacing [(m)] + INTEGER(IntKi) :: GridN(1:3) = 1_IntKi !< (GridNx,GridNy,GridNz) -- number of grid points [-] + REAL(ReKi) :: XRange(1:2) = 0.0_ReKi !< Range in the x-direction for the gridded data [(m)] + REAL(ReKi) :: YRange(1:2) = 0.0_ReKi !< Range in the y-direction for the gridded data [(m)] + REAL(ReKi) :: ZRange(1:2) = 0.0_ReKi !< Range in the z-direction for the gridded data [(m)] + TYPE(ProgDesc) :: ProgInfo !< Program info [-] + TYPE(OutputFile) :: WindGridOutput !< Wind grid file handling [-] + TYPE(OutputFile) :: FFTOutput !< FFT file handling [-] + TYPE(OutputFile) :: PointsVelOutput !< Points output velocity file handling [-] + INTEGER(IntKi) :: NOutWindXY = 0 !< Number of XY planes for output .XY.t.vtk [0 to 9] [-] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: OutWindZ !< Z coordinates of XY planes for output [1 to NOutWindXY] [unused for NOutWindXY=0] [(m)] + INTEGER(IntKi) :: NOutWindXZ = 0 !< Number of YZ planes for output .YZ.t.vtk [0 to 9] [-] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: OutWindY !< Y coordinates of YZ planes for output [1 to NOutWindYZ] [unused for NOutWindYZ=0] [(m)] + INTEGER(IntKi) :: NOutWindYZ = 0 !< Number of YZ planes for output .YZ.t.vtk [0 to 9] [-] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: OutWindX !< X coordinates of YZ planes for output [1 to NOutWindYZ] [unused for NOutWindYZ=0] [(m)] + END TYPE IfWDriver_Settings +! ======================= +CONTAINS - USE NWTC_Library - USE InflowWind_Types - - IMPLICIT NONE - - TYPE OutputFile - LOGICAL :: Initialized = .FALSE. !< Flag indicating that file has been initialized - CHARACTER(1024) :: Name = "" !< Filename for output from points read in from points file - INTEGER(IntKi) :: Unit = -1 !< Unit number for the output file for the Points file output - END TYPE - - !> This contains flags to note if the settings were made. This same data structure is - !! used both during the driver input file and the command line options. - !! - !! NOTE: The WindFileType is only set if it is given as a command line option. Otherwise - !! it is handled internally by InflowWInd. - !! - !! NOTE: The wind direction is specified by the InflowWind input file. - TYPE :: IfWDriver_Flags - LOGICAL :: DvrIptFile = .FALSE. !< Was an input file name given on the command line? - LOGICAL :: IfWIptFile = .FALSE. !< Was an InflowWind input file requested? - LOGICAL :: Summary = .FALSE. !< create a summary at command line? (data extents in the wind file) - LOGICAL :: SummaryFile = .FALSE. !< create a summary file of the output? - LOGICAL :: TStart = .FALSE. !< specified a start time - LOGICAL :: NumTimeSteps = .FALSE. !< specified a number of timesteps to process - LOGICAL :: NumTimeStepsDefault = .FALSE. !< specified a 'DEFAULT' for number of timesteps to process - LOGICAL :: DT = .FALSE. !< specified a resolution in time - LOGICAL :: DTDefault = .FALSE. !< specified a 'DEFAULT' for the time resolution - - LOGICAL :: FFTcalc = .FALSE. !< do an FFT - - LOGICAL :: WindGrid = .FALSE. !< Requested output of wind data on a grid -- input file option only - LOGICAL :: XRange = .FALSE. !< specified a range of x -- command line option only -- stored as GridCtrCoord and GridDelta - LOGICAL :: YRange = .FALSE. !< specified a range of y -- command line option only -- stored as GridCtrCoord and GridDelta - LOGICAL :: ZRange = .FALSE. !< specified a range of z -- command line option only -- stored as GridCtrCoord and GridDelta - LOGICAL :: Dx = .FALSE. !< specified a resolution in x -- command line option only, 0.0 otherwise - LOGICAL :: Dy = .FALSE. !< speficied a resolution in y - LOGICAL :: Dz = .FALSE. !< specified a resolution in z - - LOGICAL :: PointsFile = .FALSE. !< points filename to read in - LOGICAL :: OutputAccel = .FALSE. !< flag to calculate and output wind acceleration in addition to velocity - - LOGICAL :: Verbose = .FALSE. !< Verbose error reporting - LOGICAL :: VVerbose = .FALSE. !< Very Verbose error reporting - LOGICAL :: BoxExceedAllowF = .FALSE. !< set flag to allow exceeding wind box boundaries for FF files (for diagnostic purposes) - - LOGICAL :: WrHAWC = .FALSE. !< Requested file conversion to HAWC2 format? - LOGICAL :: WrBladed = .FALSE. !< Requested file conversion to Bladed format? - LOGICAL :: WrVTK = .FALSE. !< Requested file output as VTK? - LOGICAL :: WrUniform = .FALSE. !< Requested file output as Uniform wind format? +subroutine InflowWind_Driver_CopyOutputFile(SrcOutputFileData, DstOutputFileData, CtrlCode, ErrStat, ErrMsg) + type(OutputFile), intent(in) :: SrcOutputFileData + type(OutputFile), intent(inout) :: DstOutputFileData + integer(IntKi), intent(in ) :: CtrlCode + integer(IntKi), intent( out) :: ErrStat + character(*), intent( out) :: ErrMsg + character(*), parameter :: RoutineName = 'InflowWind_Driver_CopyOutputFile' + ErrStat = ErrID_None + ErrMsg = '' + DstOutputFileData%Name = SrcOutputFileData%Name + DstOutputFileData%Unit = SrcOutputFileData%Unit + DstOutputFileData%Initialized = SrcOutputFileData%Initialized +end subroutine - LOGICAL :: XYslice = .FALSE. !< Take XY slice at one elevation - END TYPE IfWDriver_Flags +subroutine InflowWind_Driver_DestroyOutputFile(OutputFileData, ErrStat, ErrMsg) + type(OutputFile), intent(inout) :: OutputFileData + integer(IntKi), intent( out) :: ErrStat + character(*), intent( out) :: ErrMsg + character(*), parameter :: RoutineName = 'InflowWind_Driver_DestroyOutputFile' + ErrStat = ErrID_None + ErrMsg = '' +end subroutine +subroutine InflowWind_Driver_PackOutputFile(Buf, Indata) + type(PackBuffer), intent(inout) :: Buf + type(OutputFile), intent(in) :: InData + character(*), parameter :: RoutineName = 'InflowWind_Driver_PackOutputFile' + if (Buf%ErrStat >= AbortErrLev) return + call RegPack(Buf, InData%Name) + call RegPack(Buf, InData%Unit) + call RegPack(Buf, InData%Initialized) + if (RegCheckErr(Buf, RoutineName)) return +end subroutine - ! This contains all the settings (possible passed in arguments). - TYPE :: IfWDriver_Settings - CHARACTER(1024) :: DvrIptFileName = "" !< Driver input file name - CHARACTER(1024) :: IfWIptFileName = "" !< Filename of InflowWind input file to read (if no driver input file) - CHARACTER(1024) :: SummaryFileName = "" !< Filename for the summary information output +subroutine InflowWind_Driver_UnPackOutputFile(Buf, OutData) + type(PackBuffer), intent(inout) :: Buf + type(OutputFile), intent(inout) :: OutData + character(*), parameter :: RoutineName = 'InflowWind_Driver_UnPackOutputFile' + if (Buf%ErrStat /= ErrID_None) return + call RegUnpack(Buf, OutData%Name) + if (RegCheckErr(Buf, RoutineName)) return + call RegUnpack(Buf, OutData%Unit) + if (RegCheckErr(Buf, RoutineName)) return + call RegUnpack(Buf, OutData%Initialized) + if (RegCheckErr(Buf, RoutineName)) return +end subroutine - CHARACTER(1024) :: PointsFileName = "" !< Filename of points file to read in - - INTEGER(IntKi) :: NumTimeSteps = 0 !< Number of timesteps - REAL(DbKi) :: DT = 0.0_DbKi !< resolution of time - REAL(DbKi) :: TStart = 0.0_DbKi !< range of time -- end time converted from TRange (command line option only) +subroutine InflowWind_Driver_CopyIfWDriver_Flags(SrcIfWDriver_FlagsData, DstIfWDriver_FlagsData, CtrlCode, ErrStat, ErrMsg) + type(IfWDriver_Flags), intent(in) :: SrcIfWDriver_FlagsData + type(IfWDriver_Flags), intent(inout) :: DstIfWDriver_FlagsData + integer(IntKi), intent(in ) :: CtrlCode + integer(IntKi), intent( out) :: ErrStat + character(*), intent( out) :: ErrMsg + character(*), parameter :: RoutineName = 'InflowWind_Driver_CopyIfWDriver_Flags' + ErrStat = ErrID_None + ErrMsg = '' + DstIfWDriver_FlagsData%DvrIptFile = SrcIfWDriver_FlagsData%DvrIptFile + DstIfWDriver_FlagsData%IfWIptFile = SrcIfWDriver_FlagsData%IfWIptFile + DstIfWDriver_FlagsData%Summary = SrcIfWDriver_FlagsData%Summary + DstIfWDriver_FlagsData%SummaryFile = SrcIfWDriver_FlagsData%SummaryFile + DstIfWDriver_FlagsData%TStart = SrcIfWDriver_FlagsData%TStart + DstIfWDriver_FlagsData%NumTimeSteps = SrcIfWDriver_FlagsData%NumTimeSteps + DstIfWDriver_FlagsData%NumTimeStepsDefault = SrcIfWDriver_FlagsData%NumTimeStepsDefault + DstIfWDriver_FlagsData%DT = SrcIfWDriver_FlagsData%DT + DstIfWDriver_FlagsData%DTDefault = SrcIfWDriver_FlagsData%DTDefault + DstIfWDriver_FlagsData%FFTcalc = SrcIfWDriver_FlagsData%FFTcalc + DstIfWDriver_FlagsData%WindGrid = SrcIfWDriver_FlagsData%WindGrid + DstIfWDriver_FlagsData%XRange = SrcIfWDriver_FlagsData%XRange + DstIfWDriver_FlagsData%YRange = SrcIfWDriver_FlagsData%YRange + DstIfWDriver_FlagsData%ZRange = SrcIfWDriver_FlagsData%ZRange + DstIfWDriver_FlagsData%Dx = SrcIfWDriver_FlagsData%Dx + DstIfWDriver_FlagsData%Dy = SrcIfWDriver_FlagsData%Dy + DstIfWDriver_FlagsData%Dz = SrcIfWDriver_FlagsData%Dz + DstIfWDriver_FlagsData%PointsFile = SrcIfWDriver_FlagsData%PointsFile + DstIfWDriver_FlagsData%OutputAccel = SrcIfWDriver_FlagsData%OutputAccel + DstIfWDriver_FlagsData%Verbose = SrcIfWDriver_FlagsData%Verbose + DstIfWDriver_FlagsData%VVerbose = SrcIfWDriver_FlagsData%VVerbose + DstIfWDriver_FlagsData%BoxExceedAllowF = SrcIfWDriver_FlagsData%BoxExceedAllowF + DstIfWDriver_FlagsData%WrHAWC = SrcIfWDriver_FlagsData%WrHAWC + DstIfWDriver_FlagsData%WrBladed = SrcIfWDriver_FlagsData%WrBladed + DstIfWDriver_FlagsData%WrVTK = SrcIfWDriver_FlagsData%WrVTK + DstIfWDriver_FlagsData%WrUniform = SrcIfWDriver_FlagsData%WrUniform + DstIfWDriver_FlagsData%XYslice = SrcIfWDriver_FlagsData%XYslice +end subroutine - REAL(ReKi) :: FFTcoord(1:3) = 0.0_ReKi !< (x,y,z) coordinate to do an FFT at +subroutine InflowWind_Driver_DestroyIfWDriver_Flags(IfWDriver_FlagsData, ErrStat, ErrMsg) + type(IfWDriver_Flags), intent(inout) :: IfWDriver_FlagsData + integer(IntKi), intent( out) :: ErrStat + character(*), intent( out) :: ErrMsg + character(*), parameter :: RoutineName = 'InflowWind_Driver_DestroyIfWDriver_Flags' + ErrStat = ErrID_None + ErrMsg = '' +end subroutine - REAL(ReKi) :: GridDelta(1:3) = 0.0_ReKi !< (GridDx,GridDy,GridDz) -- grid point spacing - INTEGER(IntKi) :: GridN(1:3) = 1_IntKi !< (GridNx,GridNy,GridNz) -- number of grid points +subroutine InflowWind_Driver_PackIfWDriver_Flags(Buf, Indata) + type(PackBuffer), intent(inout) :: Buf + type(IfWDriver_Flags), intent(in) :: InData + character(*), parameter :: RoutineName = 'InflowWind_Driver_PackIfWDriver_Flags' + if (Buf%ErrStat >= AbortErrLev) return + call RegPack(Buf, InData%DvrIptFile) + call RegPack(Buf, InData%IfWIptFile) + call RegPack(Buf, InData%Summary) + call RegPack(Buf, InData%SummaryFile) + call RegPack(Buf, InData%TStart) + call RegPack(Buf, InData%NumTimeSteps) + call RegPack(Buf, InData%NumTimeStepsDefault) + call RegPack(Buf, InData%DT) + call RegPack(Buf, InData%DTDefault) + call RegPack(Buf, InData%FFTcalc) + call RegPack(Buf, InData%WindGrid) + call RegPack(Buf, InData%XRange) + call RegPack(Buf, InData%YRange) + call RegPack(Buf, InData%ZRange) + call RegPack(Buf, InData%Dx) + call RegPack(Buf, InData%Dy) + call RegPack(Buf, InData%Dz) + call RegPack(Buf, InData%PointsFile) + call RegPack(Buf, InData%OutputAccel) + call RegPack(Buf, InData%Verbose) + call RegPack(Buf, InData%VVerbose) + call RegPack(Buf, InData%BoxExceedAllowF) + call RegPack(Buf, InData%WrHAWC) + call RegPack(Buf, InData%WrBladed) + call RegPack(Buf, InData%WrVTK) + call RegPack(Buf, InData%WrUniform) + call RegPack(Buf, InData%XYslice) + if (RegCheckErr(Buf, RoutineName)) return +end subroutine - REAL(ReKi) :: XRange(1:2) = 0.0_ReKi !< Range in the x-direction for the gridded data - REAL(ReKi) :: YRange(1:2) = 0.0_ReKi !< Range in the y-direction for the gridded data - REAL(ReKi) :: ZRange(1:2) = 0.0_ReKi !< Range in the z-direction for the gridded data +subroutine InflowWind_Driver_UnPackIfWDriver_Flags(Buf, OutData) + type(PackBuffer), intent(inout) :: Buf + type(IfWDriver_Flags), intent(inout) :: OutData + character(*), parameter :: RoutineName = 'InflowWind_Driver_UnPackIfWDriver_Flags' + if (Buf%ErrStat /= ErrID_None) return + call RegUnpack(Buf, OutData%DvrIptFile) + if (RegCheckErr(Buf, RoutineName)) return + call RegUnpack(Buf, OutData%IfWIptFile) + if (RegCheckErr(Buf, RoutineName)) return + call RegUnpack(Buf, OutData%Summary) + if (RegCheckErr(Buf, RoutineName)) return + call RegUnpack(Buf, OutData%SummaryFile) + if (RegCheckErr(Buf, RoutineName)) return + call RegUnpack(Buf, OutData%TStart) + if (RegCheckErr(Buf, RoutineName)) return + call RegUnpack(Buf, OutData%NumTimeSteps) + if (RegCheckErr(Buf, RoutineName)) return + call RegUnpack(Buf, OutData%NumTimeStepsDefault) + if (RegCheckErr(Buf, RoutineName)) return + call RegUnpack(Buf, OutData%DT) + if (RegCheckErr(Buf, RoutineName)) return + call RegUnpack(Buf, OutData%DTDefault) + if (RegCheckErr(Buf, RoutineName)) return + call RegUnpack(Buf, OutData%FFTcalc) + if (RegCheckErr(Buf, RoutineName)) return + call RegUnpack(Buf, OutData%WindGrid) + if (RegCheckErr(Buf, RoutineName)) return + call RegUnpack(Buf, OutData%XRange) + if (RegCheckErr(Buf, RoutineName)) return + call RegUnpack(Buf, OutData%YRange) + if (RegCheckErr(Buf, RoutineName)) return + call RegUnpack(Buf, OutData%ZRange) + if (RegCheckErr(Buf, RoutineName)) return + call RegUnpack(Buf, OutData%Dx) + if (RegCheckErr(Buf, RoutineName)) return + call RegUnpack(Buf, OutData%Dy) + if (RegCheckErr(Buf, RoutineName)) return + call RegUnpack(Buf, OutData%Dz) + if (RegCheckErr(Buf, RoutineName)) return + call RegUnpack(Buf, OutData%PointsFile) + if (RegCheckErr(Buf, RoutineName)) return + call RegUnpack(Buf, OutData%OutputAccel) + if (RegCheckErr(Buf, RoutineName)) return + call RegUnpack(Buf, OutData%Verbose) + if (RegCheckErr(Buf, RoutineName)) return + call RegUnpack(Buf, OutData%VVerbose) + if (RegCheckErr(Buf, RoutineName)) return + call RegUnpack(Buf, OutData%BoxExceedAllowF) + if (RegCheckErr(Buf, RoutineName)) return + call RegUnpack(Buf, OutData%WrHAWC) + if (RegCheckErr(Buf, RoutineName)) return + call RegUnpack(Buf, OutData%WrBladed) + if (RegCheckErr(Buf, RoutineName)) return + call RegUnpack(Buf, OutData%WrVTK) + if (RegCheckErr(Buf, RoutineName)) return + call RegUnpack(Buf, OutData%WrUniform) + if (RegCheckErr(Buf, RoutineName)) return + call RegUnpack(Buf, OutData%XYslice) + if (RegCheckErr(Buf, RoutineName)) return +end subroutine - TYPE(ProgDesc) :: ProgInfo !< Program info - TYPE(OutputFile) :: WindGridOutput - TYPE(OutputFile) :: FFTOutput - TYPE(OutputFile) :: PointsVelOutput +subroutine InflowWind_Driver_CopyIfWDriver_Settings(SrcIfWDriver_SettingsData, DstIfWDriver_SettingsData, CtrlCode, ErrStat, ErrMsg) + type(IfWDriver_Settings), intent(in) :: SrcIfWDriver_SettingsData + type(IfWDriver_Settings), intent(inout) :: DstIfWDriver_SettingsData + integer(IntKi), intent(in ) :: CtrlCode + integer(IntKi), intent( out) :: ErrStat + character(*), intent( out) :: ErrMsg + integer(IntKi) :: LB(1), UB(1) + integer(IntKi) :: ErrStat2 + character(ErrMsgLen) :: ErrMsg2 + character(*), parameter :: RoutineName = 'InflowWind_Driver_CopyIfWDriver_Settings' + ErrStat = ErrID_None + ErrMsg = '' + DstIfWDriver_SettingsData%DvrIptFileName = SrcIfWDriver_SettingsData%DvrIptFileName + DstIfWDriver_SettingsData%IfWIptFileName = SrcIfWDriver_SettingsData%IfWIptFileName + DstIfWDriver_SettingsData%SummaryFileName = SrcIfWDriver_SettingsData%SummaryFileName + DstIfWDriver_SettingsData%PointsFileName = SrcIfWDriver_SettingsData%PointsFileName + DstIfWDriver_SettingsData%NumTimeSteps = SrcIfWDriver_SettingsData%NumTimeSteps + DstIfWDriver_SettingsData%DT = SrcIfWDriver_SettingsData%DT + DstIfWDriver_SettingsData%TStart = SrcIfWDriver_SettingsData%TStart + DstIfWDriver_SettingsData%FFTcoord(1:3) = SrcIfWDriver_SettingsData%FFTcoord(1:3) + DstIfWDriver_SettingsData%GridDelta(1:3) = SrcIfWDriver_SettingsData%GridDelta(1:3) + DstIfWDriver_SettingsData%GridN(1:3) = SrcIfWDriver_SettingsData%GridN(1:3) + DstIfWDriver_SettingsData%XRange(1:2) = SrcIfWDriver_SettingsData%XRange(1:2) + DstIfWDriver_SettingsData%YRange(1:2) = SrcIfWDriver_SettingsData%YRange(1:2) + DstIfWDriver_SettingsData%ZRange(1:2) = SrcIfWDriver_SettingsData%ZRange(1:2) + call NWTC_Library_CopyProgDesc(SrcIfWDriver_SettingsData%ProgInfo, DstIfWDriver_SettingsData%ProgInfo, CtrlCode, ErrStat2, ErrMsg2) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + call InflowWind_Driver_CopyOutputFile(SrcIfWDriver_SettingsData%WindGridOutput, DstIfWDriver_SettingsData%WindGridOutput, CtrlCode, ErrStat2, ErrMsg2) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + call InflowWind_Driver_CopyOutputFile(SrcIfWDriver_SettingsData%FFTOutput, DstIfWDriver_SettingsData%FFTOutput, CtrlCode, ErrStat2, ErrMsg2) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + call InflowWind_Driver_CopyOutputFile(SrcIfWDriver_SettingsData%PointsVelOutput, DstIfWDriver_SettingsData%PointsVelOutput, CtrlCode, ErrStat2, ErrMsg2) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + DstIfWDriver_SettingsData%NOutWindXY = SrcIfWDriver_SettingsData%NOutWindXY + if (allocated(SrcIfWDriver_SettingsData%OutWindZ)) then + LB(1:1) = lbound(SrcIfWDriver_SettingsData%OutWindZ) + UB(1:1) = ubound(SrcIfWDriver_SettingsData%OutWindZ) + if (.not. allocated(DstIfWDriver_SettingsData%OutWindZ)) then + allocate(DstIfWDriver_SettingsData%OutWindZ(LB(1):UB(1)), stat=ErrStat2) + if (ErrStat2 /= 0) then + call SetErrStat(ErrID_Fatal, 'Error allocating DstIfWDriver_SettingsData%OutWindZ.', ErrStat, ErrMsg, RoutineName) + return + end if + end if + DstIfWDriver_SettingsData%OutWindZ = SrcIfWDriver_SettingsData%OutWindZ + end if + DstIfWDriver_SettingsData%NOutWindXZ = SrcIfWDriver_SettingsData%NOutWindXZ + if (allocated(SrcIfWDriver_SettingsData%OutWindY)) then + LB(1:1) = lbound(SrcIfWDriver_SettingsData%OutWindY) + UB(1:1) = ubound(SrcIfWDriver_SettingsData%OutWindY) + if (.not. allocated(DstIfWDriver_SettingsData%OutWindY)) then + allocate(DstIfWDriver_SettingsData%OutWindY(LB(1):UB(1)), stat=ErrStat2) + if (ErrStat2 /= 0) then + call SetErrStat(ErrID_Fatal, 'Error allocating DstIfWDriver_SettingsData%OutWindY.', ErrStat, ErrMsg, RoutineName) + return + end if + end if + DstIfWDriver_SettingsData%OutWindY = SrcIfWDriver_SettingsData%OutWindY + end if + DstIfWDriver_SettingsData%NOutWindYZ = SrcIfWDriver_SettingsData%NOutWindYZ + if (allocated(SrcIfWDriver_SettingsData%OutWindX)) then + LB(1:1) = lbound(SrcIfWDriver_SettingsData%OutWindX) + UB(1:1) = ubound(SrcIfWDriver_SettingsData%OutWindX) + if (.not. allocated(DstIfWDriver_SettingsData%OutWindX)) then + allocate(DstIfWDriver_SettingsData%OutWindX(LB(1):UB(1)), stat=ErrStat2) + if (ErrStat2 /= 0) then + call SetErrStat(ErrID_Fatal, 'Error allocating DstIfWDriver_SettingsData%OutWindX.', ErrStat, ErrMsg, RoutineName) + return + end if + end if + DstIfWDriver_SettingsData%OutWindX = SrcIfWDriver_SettingsData%OutWindX + end if +end subroutine - REAL(ReKi) :: XYslice_height = 0.0_ReKi !< height to take XY slice - END TYPE IfWDriver_Settings +subroutine InflowWind_Driver_DestroyIfWDriver_Settings(IfWDriver_SettingsData, ErrStat, ErrMsg) + type(IfWDriver_Settings), intent(inout) :: IfWDriver_SettingsData + integer(IntKi), intent( out) :: ErrStat + character(*), intent( out) :: ErrMsg + integer(IntKi) :: ErrStat2 + character(ErrMsgLen) :: ErrMsg2 + character(*), parameter :: RoutineName = 'InflowWind_Driver_DestroyIfWDriver_Settings' + ErrStat = ErrID_None + ErrMsg = '' + call NWTC_Library_DestroyProgDesc(IfWDriver_SettingsData%ProgInfo, ErrStat2, ErrMsg2) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + call InflowWind_Driver_DestroyOutputFile(IfWDriver_SettingsData%WindGridOutput, ErrStat2, ErrMsg2) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + call InflowWind_Driver_DestroyOutputFile(IfWDriver_SettingsData%FFTOutput, ErrStat2, ErrMsg2) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + call InflowWind_Driver_DestroyOutputFile(IfWDriver_SettingsData%PointsVelOutput, ErrStat2, ErrMsg2) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + if (allocated(IfWDriver_SettingsData%OutWindZ)) then + deallocate(IfWDriver_SettingsData%OutWindZ) + end if + if (allocated(IfWDriver_SettingsData%OutWindY)) then + deallocate(IfWDriver_SettingsData%OutWindY) + end if + if (allocated(IfWDriver_SettingsData%OutWindX)) then + deallocate(IfWDriver_SettingsData%OutWindX) + end if +end subroutine +subroutine InflowWind_Driver_PackIfWDriver_Settings(Buf, Indata) + type(PackBuffer), intent(inout) :: Buf + type(IfWDriver_Settings), intent(in) :: InData + character(*), parameter :: RoutineName = 'InflowWind_Driver_PackIfWDriver_Settings' + if (Buf%ErrStat >= AbortErrLev) return + call RegPack(Buf, InData%DvrIptFileName) + call RegPack(Buf, InData%IfWIptFileName) + call RegPack(Buf, InData%SummaryFileName) + call RegPack(Buf, InData%PointsFileName) + call RegPack(Buf, InData%NumTimeSteps) + call RegPack(Buf, InData%DT) + call RegPack(Buf, InData%TStart) + call RegPack(Buf, InData%FFTcoord(1:3)) + call RegPack(Buf, InData%GridDelta(1:3)) + call RegPack(Buf, InData%GridN(1:3)) + call RegPack(Buf, InData%XRange(1:2)) + call RegPack(Buf, InData%YRange(1:2)) + call RegPack(Buf, InData%ZRange(1:2)) + call NWTC_Library_PackProgDesc(Buf, InData%ProgInfo) + call InflowWind_Driver_PackOutputFile(Buf, InData%WindGridOutput) + call InflowWind_Driver_PackOutputFile(Buf, InData%FFTOutput) + call InflowWind_Driver_PackOutputFile(Buf, InData%PointsVelOutput) + call RegPack(Buf, InData%NOutWindXY) + call RegPack(Buf, allocated(InData%OutWindZ)) + if (allocated(InData%OutWindZ)) then + call RegPackBounds(Buf, 1, lbound(InData%OutWindZ), ubound(InData%OutWindZ)) + call RegPack(Buf, InData%OutWindZ) + end if + call RegPack(Buf, InData%NOutWindXZ) + call RegPack(Buf, allocated(InData%OutWindY)) + if (allocated(InData%OutWindY)) then + call RegPackBounds(Buf, 1, lbound(InData%OutWindY), ubound(InData%OutWindY)) + call RegPack(Buf, InData%OutWindY) + end if + call RegPack(Buf, InData%NOutWindYZ) + call RegPack(Buf, allocated(InData%OutWindX)) + if (allocated(InData%OutWindX)) then + call RegPackBounds(Buf, 1, lbound(InData%OutWindX), ubound(InData%OutWindX)) + call RegPack(Buf, InData%OutWindX) + end if + if (RegCheckErr(Buf, RoutineName)) return +end subroutine +subroutine InflowWind_Driver_UnPackIfWDriver_Settings(Buf, OutData) + type(PackBuffer), intent(inout) :: Buf + type(IfWDriver_Settings), intent(inout) :: OutData + character(*), parameter :: RoutineName = 'InflowWind_Driver_UnPackIfWDriver_Settings' + integer(IntKi) :: LB(1), UB(1) + integer(IntKi) :: stat + logical :: IsAllocAssoc + if (Buf%ErrStat /= ErrID_None) return + call RegUnpack(Buf, OutData%DvrIptFileName) + if (RegCheckErr(Buf, RoutineName)) return + call RegUnpack(Buf, OutData%IfWIptFileName) + if (RegCheckErr(Buf, RoutineName)) return + call RegUnpack(Buf, OutData%SummaryFileName) + if (RegCheckErr(Buf, RoutineName)) return + call RegUnpack(Buf, OutData%PointsFileName) + if (RegCheckErr(Buf, RoutineName)) return + call RegUnpack(Buf, OutData%NumTimeSteps) + if (RegCheckErr(Buf, RoutineName)) return + call RegUnpack(Buf, OutData%DT) + if (RegCheckErr(Buf, RoutineName)) return + call RegUnpack(Buf, OutData%TStart) + if (RegCheckErr(Buf, RoutineName)) return + call RegUnpack(Buf, OutData%FFTcoord(1:3)) + if (RegCheckErr(Buf, RoutineName)) return + call RegUnpack(Buf, OutData%GridDelta(1:3)) + if (RegCheckErr(Buf, RoutineName)) return + call RegUnpack(Buf, OutData%GridN(1:3)) + if (RegCheckErr(Buf, RoutineName)) return + call RegUnpack(Buf, OutData%XRange(1:2)) + if (RegCheckErr(Buf, RoutineName)) return + call RegUnpack(Buf, OutData%YRange(1:2)) + if (RegCheckErr(Buf, RoutineName)) return + call RegUnpack(Buf, OutData%ZRange(1:2)) + if (RegCheckErr(Buf, RoutineName)) return + call NWTC_Library_UnpackProgDesc(Buf, OutData%ProgInfo) ! ProgInfo + call InflowWind_Driver_UnpackOutputFile(Buf, OutData%WindGridOutput) ! WindGridOutput + call InflowWind_Driver_UnpackOutputFile(Buf, OutData%FFTOutput) ! FFTOutput + call InflowWind_Driver_UnpackOutputFile(Buf, OutData%PointsVelOutput) ! PointsVelOutput + call RegUnpack(Buf, OutData%NOutWindXY) + if (RegCheckErr(Buf, RoutineName)) return + if (allocated(OutData%OutWindZ)) deallocate(OutData%OutWindZ) + call RegUnpack(Buf, IsAllocAssoc) + if (RegCheckErr(Buf, RoutineName)) return + if (IsAllocAssoc) then + call RegUnpackBounds(Buf, 1, LB, UB) + if (RegCheckErr(Buf, RoutineName)) return + allocate(OutData%OutWindZ(LB(1):UB(1)),stat=stat) + if (stat /= 0) then + call SetErrStat(ErrID_Fatal, 'Error allocating OutData%OutWindZ.', Buf%ErrStat, Buf%ErrMsg, RoutineName) + return + end if + call RegUnpack(Buf, OutData%OutWindZ) + if (RegCheckErr(Buf, RoutineName)) return + end if + call RegUnpack(Buf, OutData%NOutWindXZ) + if (RegCheckErr(Buf, RoutineName)) return + if (allocated(OutData%OutWindY)) deallocate(OutData%OutWindY) + call RegUnpack(Buf, IsAllocAssoc) + if (RegCheckErr(Buf, RoutineName)) return + if (IsAllocAssoc) then + call RegUnpackBounds(Buf, 1, LB, UB) + if (RegCheckErr(Buf, RoutineName)) return + allocate(OutData%OutWindY(LB(1):UB(1)),stat=stat) + if (stat /= 0) then + call SetErrStat(ErrID_Fatal, 'Error allocating OutData%OutWindY.', Buf%ErrStat, Buf%ErrMsg, RoutineName) + return + end if + call RegUnpack(Buf, OutData%OutWindY) + if (RegCheckErr(Buf, RoutineName)) return + end if + call RegUnpack(Buf, OutData%NOutWindYZ) + if (RegCheckErr(Buf, RoutineName)) return + if (allocated(OutData%OutWindX)) deallocate(OutData%OutWindX) + call RegUnpack(Buf, IsAllocAssoc) + if (RegCheckErr(Buf, RoutineName)) return + if (IsAllocAssoc) then + call RegUnpackBounds(Buf, 1, LB, UB) + if (RegCheckErr(Buf, RoutineName)) return + allocate(OutData%OutWindX(LB(1):UB(1)),stat=stat) + if (stat /= 0) then + call SetErrStat(ErrID_Fatal, 'Error allocating OutData%OutWindX.', Buf%ErrStat, Buf%ErrMsg, RoutineName) + return + end if + call RegUnpack(Buf, OutData%OutWindX) + if (RegCheckErr(Buf, RoutineName)) return + end if +end subroutine END MODULE InflowWind_Driver_Types +!ENDOFREGISTRYGENERATEDFILE diff --git a/vs-build/InflowWind/InflowWind_driver.vfproj b/vs-build/InflowWind/InflowWind_driver.vfproj index 3f4cd8d25..6d3c65f6f 100644 --- a/vs-build/InflowWind/InflowWind_driver.vfproj +++ b/vs-build/InflowWind/InflowWind_driver.vfproj @@ -152,6 +152,23 @@ + + + + + + + + + + + + + + + + + diff --git a/vs-build/RunRegistry.bat b/vs-build/RunRegistry.bat index 8a65be2a5..db72464a1 100644 --- a/vs-build/RunRegistry.bat +++ b/vs-build/RunRegistry.bat @@ -142,6 +142,12 @@ SET Output_Loc=%CURR_LOC% %REGISTRY% "%CURR_LOC%\%ModuleName%.txt" -I "%NWTC_Lib_Loc%" -I "%CURR_LOC%" -noextrap -O "%Output_Loc%" GOTO checkError +:InflowWind_Driver +SET CURR_LOC=%IfW_Loc% +SET Output_Loc=%CURR_LOC% +%REGISTRY% "%CURR_LOC%\%ModuleName%_Registry.txt" -I "%NWTC_Lib_Loc%" -I "%CURR_LOC%" -noextrap -O "%Output_Loc%" +GOTO checkError + :ExternalInflow SET CURR_LOC=%ExtInfw_Loc% SET Output_Loc=%CURR_LOC% From ebdce3ad3c5ccb830af88c49e39da0b559a165b4 Mon Sep 17 00:00:00 2001 From: andrew-platt Date: Sun, 22 Dec 2024 14:39:08 -0700 Subject: [PATCH 118/161] IfW: compactify the driver input file reading, change vars for VTK planes output --- modules/inflowwind/src/InflowWind_Driver.f90 | 115 ++-- .../inflowwind/src/InflowWind_Driver_Subs.f90 | 494 ++++-------------- 2 files changed, 157 insertions(+), 452 deletions(-) diff --git a/modules/inflowwind/src/InflowWind_Driver.f90 b/modules/inflowwind/src/InflowWind_Driver.f90 index ded55401b..a4411c9d4 100644 --- a/modules/inflowwind/src/InflowWind_Driver.f90 +++ b/modules/inflowwind/src/InflowWind_Driver.f90 @@ -419,20 +419,7 @@ PROGRAM InflowWind_Driver InflowWind_p%FlowField%Grid3D%BoxExceedAllowDrv = .true. end if - ! Make sure no errors occured that give us reason to terminate now. - IF ( ErrStat >= AbortErrLev ) THEN - CALL DriverCleanup() - CALL ProgAbort( ErrMsg ) - ELSEIF ( ErrStat /= ErrID_None ) THEN - IF ( IfWDriver_Verbose >= 7_IntKi ) THEN - CALL WrScr(NewLine//' InflowWind_Init returned: ErrStat: '//TRIM(Num2LStr(ErrStat))// & - NewLine//' ErrMsg: '//TRIM(ErrMsg)//NewLine) - ELSEIF ( ErrStat >= ErrID_Warn ) THEN - CALL ProgWarn( ErrMsg ) - ELSE - CALL WrScr(TRIM(ErrMsg)) - ENDIF - ENDIF + call CheckCallErr('InflowWind_Init') @@ -443,82 +430,50 @@ PROGRAM InflowWind_Driver ! Convert InflowWind file to HAWC format IF (SettingsFlags%WrHAWC) THEN CALL IfW_WriteHAWC( InflowWind_p%FlowField, InflowWind_InitInp%RootName, ErrStat, ErrMsg ) - IF (ErrStat > ErrID_None) THEN - CALL WrScr( TRIM(ErrMsg) ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL DriverCleanup() - CALL ProgAbort( ErrMsg ) - ELSEIF ( IfWDriver_Verbose >= 7_IntKi ) THEN - CALL WrScr(NewLine//' IfW_WriteHAWC returned: ErrStat: '//TRIM(Num2LStr(ErrStat))) - END IF - ELSE IF ( IfWDriver_Verbose >= 5_IntKi ) THEN - CALL WrScr(NewLine//'IfW_WriteHAWC CALL returned without errors.'//NewLine) - END IF + call CheckCallErr('IfW_WriteHAWC') END IF ! Convert InflowWind file to Native Bladed format IF (SettingsFlags%WrBladed) THEN CALL IfW_WriteBladed( InflowWind_p%FlowField, InflowWind_InitInp%RootName, ErrStat, ErrMsg ) - IF (ErrStat > ErrID_None) THEN - CALL WrScr( TRIM(ErrMsg) ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL DriverCleanup() - CALL ProgAbort( ErrMsg ) - ELSEIF ( IfWDriver_Verbose >= 7_IntKi ) THEN - CALL WrScr(NewLine//' InflowWind_Convert2Bladed returned: ErrStat: '//TRIM(Num2LStr(ErrStat))) - END IF - ELSE IF ( IfWDriver_Verbose >= 5_IntKi ) THEN - CALL WrScr(NewLine//'InflowWind_Convert2Bladed CALL returned without errors.'//NewLine) - END IF + call CheckCallErr('IfW_WriteBladed') END IF + IF (SettingsFlags%WrVTK) THEN CALL IfW_WriteVTK( InflowWind_p%FlowField, InflowWind_InitInp%RootName, ErrStat, ErrMsg ) - IF (ErrStat > ErrID_None) THEN - CALL WrScr( TRIM(ErrMsg) ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL DriverCleanup() - CALL ProgAbort( ErrMsg ) - ELSEIF ( IfWDriver_Verbose >= 7_IntKi ) THEN - CALL WrScr(NewLine//' IfW_WriteVTK returned: ErrStat: '//TRIM(Num2LStr(ErrStat))) - END IF - ELSE IF ( IfWDriver_Verbose >= 5_IntKi ) THEN - CALL WrScr(NewLine//'IfW_WriteVTK CALL returned without errors.'//NewLine) - END IF - + call CheckCallErr('IfW_WriteVTK') END IF IF (SettingsFlags%WrUniform) THEN CALL IfW_WriteUniform( InflowWind_p%FlowField, InflowWind_InitInp%RootName, ErrStat, ErrMsg ) - IF (ErrStat > ErrID_None) THEN - CALL WrScr( TRIM(ErrMsg) ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL DriverCleanup() - CALL ProgAbort( ErrMsg ) - ELSEIF ( IfWDriver_Verbose >= 7_IntKi ) THEN - CALL WrScr(NewLine//' IfW_WriteUniform returned: ErrStat: '//TRIM(Num2LStr(ErrStat))) - END IF - ELSE IF ( IfWDriver_Verbose >= 5_IntKi ) THEN - CALL WrScr(NewLine//'IfW_WriteUniform CALL returned without errors.'//NewLine) - END IF + call CheckCallErr('IfW_WriteUniform') END IF - IF (SettingsFlags%XYslice) THEN - CALL IfW_WriteXYslice( InflowWind_p%FlowField, InflowWind_InitInp%RootName, Settings%XYslice_height, ErrStat, ErrMsg ) - IF (ErrStat > ErrID_None) THEN - CALL WrScr( TRIM(ErrMsg) ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL DriverCleanup() - CALL ProgAbort( ErrMsg ) - ELSEIF ( IfWDriver_Verbose >= 7_IntKi ) THEN - CALL WrScr(NewLine//' IfW_WriteXYslice returned: ErrStat: '//TRIM(Num2LStr(ErrStat))) - END IF - ELSE IF ( IfWDriver_Verbose >= 5_IntKi ) THEN - CALL WrScr(NewLine//'IfW_WriteXYslice CALL returned without errors.'//NewLine) - END IF + IF (Settings%NOutWindXY>0) THEN + do i=1,Settings%NOutWindXY + CALL IfW_WriteXYslice( InflowWind_p%FlowField, InflowWind_InitInp%RootName, Settings%OutWindZ(i), ErrStat, ErrMsg ) + call CheckCallErr('IfW_WriteXYslice'//trim(Num2LStr(i))) + enddo + END IF + + + IF (Settings%NOutWindXZ>0) THEN + do i=1,Settings%NOutWindXZ +! CALL IfW_WriteXZslice( InflowWind_p%FlowField, InflowWind_InitInp%RootName, Settings%OutWindY(i), ErrStat, ErrMsg ) +! call CheckCallErr('IfW_WriteXZslice'//trim(Num2LStr(i))) + enddo + END IF + + + IF (Settings%NOutWindYZ>0) THEN + do i=1,Settings%NOutWindYZ +! CALL IfW_WriteYZslice( InflowWind_p%FlowField, InflowWind_InitInp%RootName, Settings%OutWindX(i), ErrStat, ErrMsg ) +! call CheckCallErr('IfW_WriteYZslice'//trim(Num2LStr(i))) + enddo END IF @@ -959,6 +914,22 @@ SUBROUTINE DriverCleanup() END SUBROUTINE DriverCleanup + subroutine CheckCallErr(RoutineName) + character(*), intent(in) :: RoutineName + if (ErrStat > ErrID_None) then + call WrScr( trim(ErrMsg) ) + if ( ErrStat >= AbortErrLev ) then + call DriverCleanup() + call ProgAbort( ErrMsg ) + elseif ( IfWDriver_Verbose >= 7_IntKi ) then + call WrScr(NewLine//' '//trim(RoutineName)//' returned: ErrStat: '//TRIM(Num2LStr(ErrStat))) + endif + elseif ( IfWDriver_Verbose >= 5_IntKi ) then + CALL WrScr(NewLine//trim(RoutineName)//' CALL returned without errors.'//NewLine) + endif + end subroutine CheckCallErr + + END PROGRAM InflowWind_Driver diff --git a/modules/inflowwind/src/InflowWind_Driver_Subs.f90 b/modules/inflowwind/src/InflowWind_Driver_Subs.f90 index d06ec0378..6bc47eeae 100644 --- a/modules/inflowwind/src/InflowWind_Driver_Subs.f90 +++ b/modules/inflowwind/src/InflowWind_Driver_Subs.f90 @@ -734,18 +734,12 @@ SUBROUTINE ReadDvrIptFile( DvrFileName, DvrFlags, DvrSettings, ProgInfo, ErrStat ! Initialize the echo file unit to -1 which is the default to prevent echoing, we will alter this based on user input UnEchoLocal = -1 - FileName = TRIM(DvrFileName) + ErrStat = ErrID_None + ErrMsg = "" CALL GetNewUnit( UnIn ) - CALL OpenFInpFile( UnIn, FileName, ErrStatTmp, ErrMsgTmp ) - IF ( ErrStatTmp /= ErrID_None ) THEN - CALL SetErrStat(ErrID_Fatal,' Failed to open InflowWind Driver input file: '//FileName, & - ErrStat,ErrMsg,RoutineName) - CLOSE( UnIn ) - RETURN - ENDIF - + CALL OpenFInpFile( UnIn, FileName, ErrStatTmp, ErrMsgTmp ); if (Failed()) return CALL WrScr( 'Opening InflowWind Driver input file: '//FileName ) @@ -754,30 +748,9 @@ SUBROUTINE ReadDvrIptFile( DvrFileName, DvrFlags, DvrSettings, ProgInfo, ErrStat !------------------------------------------------------------------------------------------------- ! File header !------------------------------------------------------------------------------------------------- - - CALL ReadCom( UnIn, FileName,' InflowWind Driver input file header line 1', ErrStatTmp, ErrMsgTmp ) - IF ( ErrStatTmp /= ErrID_None ) THEN - CALL SetErrStat(ErrID_Fatal,ErrMsgTmp,ErrStat,ErrMsg,RoutineName) - CLOSE( UnIn ) - RETURN - ENDIF - - - CALL ReadCom( UnIn, FileName, 'InflowWind Driver input file header line 2', ErrStatTmp, ErrMsgTmp ) - IF ( ErrStatTmp /= ErrID_None ) THEN - CALL SetErrStat(ErrID_Fatal,ErrMsgTmp,ErrStat,ErrMsg,RoutineName) - CLOSE( UnIn ) - RETURN - ENDIF - - - ! Echo Input Files. - CALL ReadVar ( UnIn, FileName, EchoFileContents, 'Echo', 'Echo Input', ErrStatTmp, ErrMsgTmp ) - IF ( ErrStatTmp /= ErrID_None ) THEN - CALL SetErrStat(ErrID_Fatal,ErrMsgTmp,ErrStat,ErrMsg,RoutineName) - CLOSE( UnIn ) - RETURN - ENDIF + CALL ReadCom( UnIn, FileName,' InflowWind Driver input file header line 1', ErrStatTmp, ErrMsgTmp ); if (Failed()) return + CALL ReadCom( UnIn, FileName, 'InflowWind Driver input file header line 2', ErrStatTmp, ErrMsgTmp ); if (Failed()) return + CALL ReadVar ( UnIn, FileName, EchoFileContents, 'Echo', 'Echo Input', ErrStatTmp, ErrMsgTmp ); if (Failed()) return ! If we are Echoing the input then we should re-read the first three lines so that we can echo them @@ -788,44 +761,15 @@ SUBROUTINE ReadDvrIptFile( DvrFileName, DvrFlags, DvrSettings, ProgInfo, ErrStat EchoFileName = TRIM(FileName)//'.ech' CALL GetNewUnit( UnEchoLocal ) - CALL OpenEcho ( UnEchoLocal, EchoFileName, ErrStatTmp, ErrMsgTmp, ProgInfo ) - IF ( ErrStatTmp /= ErrID_None ) THEN - CALL SetErrStat(ErrID_Fatal,ErrMsgTmp,ErrStat,ErrMsg,RoutineName) - CLOSE( UnIn ) - RETURN - ENDIF - + CALL OpenEcho ( UnEchoLocal, EchoFileName, ErrStatTmp, ErrMsgTmp, ProgInfo ); if (Failed()) return REWIND(UnIn) ! Reread and echo - CALL ReadCom( UnIn, FileName,' InflowWind Driver input file header line 1', ErrStatTmp, ErrMsgTmp, UnEchoLocal ) - IF ( ErrStatTmp /= ErrID_None ) THEN - CALL SetErrStat(ErrID_Fatal, ErrMsgTmp,ErrStat,ErrMsg,RoutineName) - CALL CleanupEchoFile( EchoFileContents, UnEchoLocal ) - CLOSE( UnIn ) - RETURN - ENDIF - - - CALL ReadCom( UnIn, FileName, 'InflowWind Driver input file header line 2', ErrStatTmp, ErrMsgTmp, UnEchoLocal ) - IF ( ErrStatTmp /= ErrID_None ) THEN - CALL SetErrStat(ErrID_Fatal,ErrMsgTmp,ErrStat,ErrMsg,RoutineName) - CALL CleanupEchoFile( EchoFileContents, UnEchoLocal ) - CLOSE( UnIn ) - RETURN - ENDIF - - - ! Echo Input Files. - CALL ReadVar ( UnIn, FileName, EchoFileContents, 'Echo', 'Echo Input', ErrStatTmp, ErrMsgTmp, UnEchoLocal ) - IF ( ErrStatTmp /= ErrID_None ) THEN - CALL SetErrStat(ErrID_Fatal,ErrMsgTmp,ErrStat,ErrMsg,RoutineName) - CALL CleanupEchoFile( EchoFileContents, UnEchoLocal ) - CLOSE( UnIn ) - RETURN - ENDIF + CALL ReadCom( UnIn, FileName,' InflowWind Driver input file header line 1', ErrStatTmp, ErrMsgTmp, UnEchoLocal ); if (Failed()) return + CALL ReadCom( UnIn, FileName, 'InflowWind Driver input file header line 2', ErrStatTmp, ErrMsgTmp, UnEchoLocal ); if (Failed()) return + CALL ReadVar ( UnIn, FileName, EchoFileContents, 'Echo', 'Echo Input', ErrStatTmp, ErrMsgTmp, UnEchoLocal ); if (Failed()) return @@ -835,78 +779,30 @@ SUBROUTINE ReadDvrIptFile( DvrFileName, DvrFlags, DvrSettings, ProgInfo, ErrStat !------------------------------------------------------------------------------------------------- ! Driver setup section !------------------------------------------------------------------------------------------------- - - ! Header - CALL ReadCom( UnIn, FileName,' Driver setup section, comment line', ErrStatTmp, ErrMsgTmp, UnEchoLocal ) - IF ( ErrStatTmp /= ErrID_None ) THEN - CALL SetErrStat(ErrID_Fatal,ErrMsgTmp,ErrStat,ErrMsg,RoutineName) - CALL CleanupEchoFile( EchoFileContents, UnEchoLocal ) - CLOSE( UnIn ) - RETURN - ENDIF - + CALL ReadCom( UnIn, FileName,' Driver setup section, comment line', ErrStatTmp, ErrMsgTmp, UnEchoLocal ); if (Failed()) return ! Name of InflowWind input file - CALL ReadVar( UnIn, FileName,DvrSettings%IfWIptFileName,'IfWIptFileName',' InflowWind input filename', & - ErrStatTmp,ErrMsgTmp, UnEchoLocal ) - IF ( ErrStatTmp /= ErrID_None ) THEN - CALL SetErrStat(ErrID_Fatal,ErrMsgTmp,ErrStat,ErrMsg,RoutineName) - CALL CleanupEchoFile( EchoFileContents, UnEchoLocal ) - CLOSE( UnIn ) - RETURN - ELSE - DvrFlags%IfWIptFile = .TRUE. - ENDIF - + CALL ReadVar( UnIn, FileName,DvrSettings%IfWIptFileName,'IfWIptFileName',' InflowWind input filename', ErrStatTmp,ErrMsgTmp, UnEchoLocal ); if (Failed()) return + DvrFlags%IfWIptFile = .TRUE. IF ( PathIsRelative( DvrSettings%IfWIptFileName ) ) DvrSettings%IfWIptFileName = TRIM(PriPath)//TRIM(DvrSettings%IfWIptFileName) !------------------------------------------------------------------------------------------------- ! File Conversion Options section !------------------------------------------------------------------------------------------------- - - ! Header - CALL ReadCom( UnIn, FileName,'File Conversion Options Section Header', ErrStatTmp, ErrMsgTmp, UnEchoLocal ) - CALL SetErrStat(ErrStatTmp, ErrMsgTmp,ErrStat,ErrMsg,RoutineName) - - ! WrHAWC - CALL ReadVar( UnIn, FileName, DvrFlags%WrHAWC, 'WrHAWC', 'Convert wind data to HAWC2 format?', ErrStatTmp, ErrMsgTmp, UnEchoLocal ) - CALL SetErrStat(ErrStatTmp, ErrMsgTmp,ErrStat,ErrMsg,RoutineName) - - ! WrBladed - CALL ReadVar( UnIn, FileName, DvrFlags%WrBladed, 'WrBladed', 'Convert wind data to Bladed format?', ErrStatTmp, ErrMsgTmp, UnEchoLocal ) - CALL SetErrStat(ErrStatTmp, ErrMsgTmp,ErrStat,ErrMsg,RoutineName) - - ! WrVTK - CALL ReadVar( UnIn, FileName, DvrFlags%WrVTK, 'WrVTK', 'Convert wind data to VTK format?', ErrStatTmp, ErrMsgTmp, UnEchoLocal ) - CALL SetErrStat(ErrStatTmp, ErrMsgTmp,ErrStat,ErrMsg,RoutineName) - - ! WrUniform - CALL ReadVar( UnIn, FileName, DvrFlags%WrUniform, 'WrUniform', 'Convert wind data to Uniform Wind format?', ErrStatTmp, ErrMsgTmp, UnEchoLocal ) - CALL SetErrStat(ErrStatTmp, ErrMsgTmp,ErrStat,ErrMsg,RoutineName) + CALL ReadCom( UnIn, FileName,'File Conversion Options Section Header', ErrStatTmp, ErrMsgTmp, UnEchoLocal ); if (Failed()) return + CALL ReadVar( UnIn, FileName, DvrFlags%WrHAWC, 'WrHAWC', 'Convert wind data to HAWC2 format?', ErrStatTmp, ErrMsgTmp, UnEchoLocal ); if (Failed()) return + CALL ReadVar( UnIn, FileName, DvrFlags%WrBladed, 'WrBladed', 'Convert wind data to Bladed format?', ErrStatTmp, ErrMsgTmp, UnEchoLocal ); if (Failed()) return + CALL ReadVar( UnIn, FileName, DvrFlags%WrVTK, 'WrVTK', 'Convert wind data to VTK format?', ErrStatTmp, ErrMsgTmp, UnEchoLocal ); if (Failed()) return + CALL ReadVar( UnIn, FileName, DvrFlags%WrUniform, 'WrUniform','Convert wind data to Uniform Wind format?', ErrStatTmp, ErrMsgTmp, UnEchoLocal ); if (Failed()) return - IF ( ErrStat >= AbortErrLev ) THEN - CALL CleanupEchoFile( EchoFileContents, UnEchoLocal ) - CLOSE( UnIn ) - RETURN - ENDIF - !------------------------------------------------------------------------------------------------- ! Tests of Interpolation Options section !------------------------------------------------------------------------------------------------- - CALL ReadCom( UnIn, FileName,'Tests of Interpolation Options Section Header', ErrStatTmp, ErrMsgTmp, UnEchoLocal ) - CALL SetErrStat(ErrStatTmp, ErrMsgTmp,ErrStat,ErrMsg,RoutineName) - + CALL ReadCom( UnIn, FileName,'Tests of Interpolation Options Section Header', ErrStatTmp, ErrMsgTmp, UnEchoLocal ); if (Failed()) return ! Number of timesteps - CALL ReadVar( UnIn, FileName,NumTimeStepsChr,'NumTimeStepsChr',' Character string for number of timesteps to read.', & - ErrStatTmp,ErrMsgTmp, UnEchoLocal ) - IF ( ErrStatTmp /= ErrID_None ) THEN - CALL SetErrStat(ErrID_Fatal,ErrMsgTmp,ErrStat,ErrMsg,RoutineName) - CALL CleanupEchoFile( EchoFileContents, UnEchoLocal ) - CLOSE( UnIn ) - RETURN - ENDIF + CALL ReadVar( UnIn, FileName,NumTimeStepsChr,'NumTimeStepsChr',' Number of timesteps to read.', ErrStatTmp,ErrMsgTmp, UnEchoLocal ); if (Failed()) return ! Check if we asked for the DEFAULT (use what is in the file) CALL Conv2UC( NumTimeStepsChr ) @@ -918,8 +814,7 @@ SUBROUTINE ReadDvrIptFile( DvrFileName, DvrFlags, DvrSettings, ProgInfo, ErrStat ! make sure that it was appropriately interpretted. READ (NumTimeStepsChr,*,IOSTAT=IOS) DvrSettings%NumTimeSteps IF ( IOS /= 0 ) THEN ! problem in the read, so parse the error. - CALL CheckIOS ( IOS, '', 'NumTimeSteps',NumType, ErrStatTmp, ErrMsgTmp ) - RETURN + CALL CheckIOS ( IOS, '', 'NumTimeSteps',NumType, ErrStatTmp, ErrMsgTmp ); if (Failed()) return ELSE ! Was ok, so set the flags DvrFlags%NumTimeSteps = .TRUE. DvrFlags%NumTimeStepsDefault = .FALSE. @@ -928,27 +823,11 @@ SUBROUTINE ReadDvrIptFile( DvrFileName, DvrFlags, DvrSettings, ProgInfo, ErrStat ! TStart -- start time - CALL ReadVar( UnIn, FileName,DvrSettings%TStart,'TStart',' Time in wind file to start parsing.', & - ErrStatTmp,ErrMsgTmp, UnEchoLocal ) - IF ( ErrStatTmp /= ErrID_None ) THEN - CALL SetErrStat(ErrID_Fatal,ErrMsgTmp,ErrStat,ErrMsg,RoutineName) - CALL CleanupEchoFile( EchoFileContents, UnEchoLocal ) - CLOSE( UnIn ) - RETURN - ELSE - DvrFlags%TStart = .TRUE. - ENDIF - + CALL ReadVar( UnIn, FileName,DvrSettings%TStart,'TStart',' Time in wind file to start parsing.', ErrStatTmp,ErrMsgTmp, UnEchoLocal ); if (Failed()) return + DvrFlags%TStart = .TRUE. ! DT -- Timestep size for the driver to take (or DEFAULT for what the file contains) - CALL ReadVar( UnIn, FileName,DTChr,'DTChr',' Character string for Timestep size for the driver to take (or DEFAULT for what the file contains).', & - ErrStatTmp,ErrMsgTmp, UnEchoLocal ) - IF ( ErrStatTmp /= ErrID_None ) THEN - CALL SetErrStat(ErrID_Fatal,ErrMsgTmp,ErrStat,ErrMsg,RoutineName) - CALL CleanupEchoFile( EchoFileContents, UnEchoLocal ) - CLOSE( UnIn ) - RETURN - ENDIF + CALL ReadVar( UnIn, FileName,DTChr,'DTChr',' Character string for Timestep', ErrStatTmp,ErrMsgTmp, UnEchoLocal ); if (Failed()) return ! Check if we asked for the DEFAULT (use what is in the file) CALL Conv2UC( DTChr ) @@ -960,8 +839,7 @@ SUBROUTINE ReadDvrIptFile( DvrFileName, DvrFlags, DvrSettings, ProgInfo, ErrStat ! make sure that it was appropriately interpretted. READ (DTChr,*,IOSTAT=IOS) DvrSettings%DT IF ( IOS /= 0 ) THEN ! problem in the read, so parse the error. - CALL CheckIOS ( IOS, '', 'DT',NumType, ErrStatTmp, ErrMsgTmp ) - RETURN + CALL CheckIOS ( IOS, '', 'DT',NumType, ErrStatTmp, ErrMsgTmp ); if (Failed()) return ELSE ! Was ok, so set the flags DvrFlags%DT = .TRUE. DvrFlags%DTDefault = .FALSE. @@ -969,213 +847,75 @@ SUBROUTINE ReadDvrIptFile( DvrFileName, DvrFlags, DvrSettings, ProgInfo, ErrStat ENDIF - ! Summarize the extents in the windfile - CALL ReadVar( UnIn, FileName,DvrFlags%Summary,'Summary',' Summarize data extents in the windfile', & - ErrStatTmp,ErrMsgTmp, UnEchoLocal ) - IF ( ErrStatTmp /= ErrID_None ) THEN - CALL SetErrStat(ErrID_Fatal,ErrMsgTmp,ErrStat,ErrMsg,RoutineName) - CALL CleanupEchoFile( EchoFileContents, UnEchoLocal ) - CLOSE( UnIn ) - RETURN -! ELSE -! DvrFlags%Summary = .TRUE. - ENDIF - - - ! Summarize everything in a summary file/ - CALL ReadVar( UnIn, FileName,DvrFlags%SummaryFile,'SummaryFile',' Summarize the results in a .sum file', & - ErrStatTmp,ErrMsgTmp, UnEchoLocal ) - IF ( ErrStatTmp /= ErrID_None ) THEN - CALL SetErrStat(ErrID_Fatal,ErrMsgTmp,ErrStat,ErrMsg,RoutineName) - CALL CleanupEchoFile( EchoFileContents, UnEchoLocal ) - CLOSE( UnIn ) - RETURN -! ELSE -! DvrFlags%SummaryFile = .TRUE. - ENDIF + ! Summary info + CALL ReadVar( UnIn, FileName,DvrFlags%Summary, 'Summary', ' Summarize data extents in the windfile', ErrStatTmp,ErrMsgTmp, UnEchoLocal ); if (Failed()) return + CALL ReadVar( UnIn, FileName,DvrFlags%SummaryFile,'SummaryFile',' Summarize the results in a .sum file', ErrStatTmp,ErrMsgTmp, UnEchoLocal ); if (Failed()) return ! Flag to allow sampling outside grid - CALL ReadVar( UnIn, FileName,DvrFlags%BoxExceedAllowF,'BoxExceedAllow',' Allow point sampling outside grid', & - ErrStatTmp,ErrMsgTmp, UnEchoLocal ) - IF ( ErrStatTmp /= ErrID_None ) THEN - CALL SetErrStat(ErrID_Fatal,ErrMsgTmp,ErrStat,ErrMsg,RoutineName) - CALL CleanupEchoFile( EchoFileContents, UnEchoLocal ) - CLOSE( UnIn ) - RETURN - ENDIF + CALL ReadVar( UnIn, FileName,DvrFlags%BoxExceedAllowF,'BoxExceedAllow',' Allow point sampling outside grid', ErrStatTmp,ErrMsgTmp, UnEchoLocal ); if (Failed()) return + #ifdef UNUSED_INPUTFILE_LINES !------------------------------------------------------------------------------------------------- ! FFT calculations !------------------------------------------------------------------------------------------------- - - ! Header - CALL ReadCom( UnIn, FileName,' FFT calculations, comment line', ErrStatTmp, ErrMsgTmp, UnEchoLocal ) - IF ( ErrStatTmp /= ErrID_None ) THEN - CALL SetErrStat(ErrID_Fatal,ErrMsgTmp,ErrStat,ErrMsg,RoutineName) - CALL CleanupEchoFile( EchoFileContents, UnEchoLocal ) - CLOSE( UnIn ) - RETURN - ENDIF - - - ! FFTcalc -- FFTcalc of the windfield needed. - CALL ReadVar( UnIn, FileName,DvrFlags%FFTcalc,'FFTcalc',' Perform an FFT?', & - ErrStatTmp,ErrMsgTmp, UnEchoLocal ) - IF ( ErrStatTmp /= ErrID_None ) THEN - CALL SetErrStat(ErrID_Fatal,ErrMsgTmp,ErrStat,ErrMsg,RoutineName) - CALL CleanupEchoFile( EchoFileContents, UnEchoLocal ) - CLOSE( UnIn ) - RETURN - ENDIF - + CALL ReadCom( UnIn, FileName,' FFT calculations, comment line', ErrStatTmp, ErrMsgTmp, UnEchoLocal ); if (Failed()) return + CALL ReadVar( UnIn, FileName,DvrFlags%FFTcalc,'FFTcalc',' Perform an FFT?', ErrStatTmp,ErrMsgTmp, UnEchoLocal ); if (Failed()) return ! Read the coordinate for the FFT if the flag is set, otherwise skip the line IF ( DvrFlags%FFTcalc ) THEN ! FFTcoord -- The coordinates to perform the FFT at - CALL ReadAry ( UnIn, FileName, DvrSettings%FFTcoord, 3, 'FFTcoord', & - 'FFT coordinate', ErrStatTmp, ErrMsgTmp, UnEchoLocal) - IF ( ErrStat /= ErrID_None ) THEN - CALL SetErrStat( ErrID_Fatal,ErrMsgTmp,ErrStat,ErrMsg,RoutineName) - CALL CleanupEchoFile( EchoFileContents, UnEchoLocal ) - CLOSE( UnIn ) - RETURN - ENDIF + CALL ReadAry ( UnIn, FileName, DvrSettings%FFTcoord, 3, 'FFTcoord', 'FFT coordinate', ErrStatTmp, ErrMsgTmp, UnEchoLocal); if (Failed()) return ELSE - CALL ReadCom( UnIn, FileName,' Skipping the FFT coordinate since not doint an FFT.', ErrStatTmp, ErrMsgTmp, UnEchoLocal ) - IF ( ErrStatTmp /= ErrID_None ) THEN - CALL SetErrStat(ErrID_Fatal,ErrMsgTmp,ErrStat,ErrMsg,RoutineName) - CALL CleanupEchoFile( EchoFileContents, UnEchoLocal ) - CLOSE( UnIn ) - RETURN - ENDIF + CALL ReadCom( UnIn, FileName,' Skipping the FFT coordinate since not doint an FFT.', ErrStatTmp, ErrMsgTmp, UnEchoLocal ); if (Failed()) return ENDIF - #endif + !------------------------------------------------------------------------------------------------- ! points file input !------------------------------------------------------------------------------------------------- - - ! Header line - CALL ReadCom( UnIn, FileName,' Points file input, comment line', ErrStatTmp, ErrMsgTmp, UnEchoLocal ) - IF ( ErrStatTmp /= ErrID_None ) THEN - CALL SetErrStat(ErrID_Fatal,ErrMsgTmp,ErrStat,ErrMsg,RoutineName) - CALL CleanupEchoFile( EchoFileContents, UnEchoLocal ) - CLOSE( UnIn ) - RETURN - ENDIF - - - ! PointsFile -- Read a points file - CALL ReadVar( UnIn, FileName,DvrFlags%PointsFile,'PointsFile',' Read a points file?', & - ErrStatTmp,ErrMsgTmp, UnEchoLocal ) - - IF ( ErrStatTmp /= ErrID_None ) THEN - CALL SetErrStat(ErrID_Fatal,ErrMsgTmp,ErrStat,ErrMsg,RoutineName) - CALL CleanupEchoFile( EchoFileContents, UnEchoLocal ) - CLOSE( UnIn ) - RETURN - ENDIF - - - ! Points input file (unused if .not. DvrFlags%PointsFile) - CALL ReadVar( UnIn, FileName,DvrSettings%PointsFileName,'PointsFileName',' Points file input filename', & - ErrStatTmp,ErrMsgTmp, UnEchoLocal ) - IF ( ErrStatTmp /= ErrID_None ) THEN - CALL SetErrStat(ErrID_Fatal,ErrMsgTmp,ErrStat,ErrMsg,RoutineName) - CALL CleanupEchoFile( EchoFileContents, UnEchoLocal ) - CLOSE( UnIn ) - RETURN - ENDIF - + CALL ReadCom( UnIn, FileName,' Points file input, comment line', ErrStatTmp, ErrMsgTmp, UnEchoLocal ); if (Failed()) return + CALL ReadVar( UnIn, FileName,DvrFlags%PointsFile, 'PointsFile', ' Read a points file?', ErrStatTmp,ErrMsgTmp, UnEchoLocal ); if (Failed()) return + CALL ReadVar( UnIn, FileName,DvrSettings%PointsFileName,'PointsFileName',' Points file input filename', ErrStatTmp,ErrMsgTmp, UnEchoLocal ); if (Failed()) return IF ( PathIsRelative( DvrSettings%PointsFileName ) ) DvrSettings%PointsFileName = TRIM(PriPath)//TRIM(DvrSettings%PointsFileName) ! CalcAccel - calculate wind acceleration (unused if .not. DvrFlags%PointsFile) - CALL ReadVar( UnIn, FileName,DvrFlags%OutputAccel, 'CalcAccel', ' Calc and output wind acceleration', & - ErrStatTmp,ErrMsgTmp, UnEchoLocal ) - IF ( ErrStatTmp /= ErrID_None ) THEN - CALL SetErrStat(ErrID_Fatal,ErrMsgTmp,ErrStat,ErrMsg,RoutineName) - CALL CleanupEchoFile( EchoFileContents, UnEchoLocal ) - CLOSE( UnIn ) - RETURN - ENDIF + CALL ReadVar( UnIn, FileName,DvrFlags%OutputAccel, 'CalcAccel', ' Calc and output wind acceleration', ErrStatTmp,ErrMsgTmp, UnEchoLocal ); if (Failed()) return + !------------------------------------------------------------------------------------------------- ! gridded data output !------------------------------------------------------------------------------------------------- - - ! Header - CALL ReadCom( UnIn, FileName,' Gridded data output, comment line', ErrStatTmp, ErrMsgTmp, UnEchoLocal ) - IF ( ErrStatTmp /= ErrID_None ) THEN - CALL SetErrStat(ErrID_Fatal,ErrMsgTmp,ErrStat,ErrMsg,RoutineName) - CALL CleanupEchoFile( EchoFileContents, UnEchoLocal ) - CLOSE( UnIn ) - RETURN - ENDIF - + CALL ReadCom( UnIn, FileName,' Gridded data output, comment line', ErrStatTmp, ErrMsgTmp, UnEchoLocal ); if (Failed()) return ! WindGrid -- Gridded data output - CALL ReadVar( UnIn, FileName,DvrFlags%WindGrid,'WindGrid',' Output a grid of data?', & - ErrStatTmp,ErrMsgTmp, UnEchoLocal ) - IF ( ErrStatTmp /= ErrID_None ) THEN - CALL SetErrStat(ErrID_Fatal,ErrMsgTmp,ErrStat,ErrMsg,RoutineName) - CALL CleanupEchoFile( EchoFileContents, UnEchoLocal ) - CLOSE( UnIn ) - RETURN - ENDIF + CALL ReadVar( UnIn, FileName,DvrFlags%WindGrid,'WindGrid',' Output a grid of data?', ErrStatTmp,ErrMsgTmp, UnEchoLocal ); if (Failed()) return - ! Read the coordinate for the FFT if the flag is set, otherwise skip the line + ! Read the coordinate for the WindGrid if the flag is set, otherwise skip the line IF ( DvrFlags%WindGrid ) THEN ! GridCtrCoord -- The coordinates to center the gridded data at - CALL ReadAry ( UnIn, FileName, GridCtrCoord, 3, 'GridCtrCoord', & - 'Coordinate of the center of the gridded data', ErrStatTmp, ErrMsgTmp, UnEchoLocal) - IF ( ErrStat /= ErrID_None ) THEN - CALL SetErrStat( ErrID_Fatal,ErrMsgTmp,ErrStat,ErrMsg,RoutineName) - CALL CleanupEchoFile( EchoFileContents, UnEchoLocal ) - CLOSE( UnIn ) - RETURN - ENDIF + CALL ReadAry ( UnIn, FileName, GridCtrCoord, 3, 'GridCtrCoord', 'Coordinate of the center of the gridded data', ErrStatTmp, ErrMsgTmp, UnEchoLocal); if (Failed()) return ! Read the DY and DZ stepsize - CALL ReadAry ( UnIn, FileName, TmpRealAr3, 3, 'GridDX, GridDY, GridDZ', & - 'GridDX, GridDY, GridDZ', ErrStatTmp, ErrMsgTmp, UnEchoLocal) - IF ( ErrStat /= ErrID_None ) THEN - CALL SetErrStat( ErrID_Fatal,ErrMsgTmp,ErrStat,ErrMsg,RoutineName) - CALL CleanupEchoFile( EchoFileContents, UnEchoLocal ) - CLOSE( UnIn ) - RETURN - ENDIF + CALL ReadAry ( UnIn, FileName, TmpRealAr3, 3, 'GridDX, GridDY, GridDZ', 'GridDX, GridDY, GridDZ', ErrStatTmp, ErrMsgTmp, UnEchoLocal); if (Failed()) return ! Save the DY and DZ values - DvrSettings%GridDelta(1) = abs(TmpRealAr3(1)) ! X direction - DvrSettings%GridDelta(2) = abs(TmpRealAr3(2)) ! Y direction - DvrSettings%GridDelta(3) = abs(TmpRealAr3(3)) ! Z direction + DvrSettings%GridDelta(1:3) = abs(TmpRealAr3(1:3)) DvrFlags%Dx = .TRUE. ! read in value for the X direction gridding DvrFlags%Dy = .TRUE. ! read in value for the Y direction gridding DvrFlags%Dz = .TRUE. ! read in value for the Z direction gridding ! Read the number of points in the Y and Z directions - CALL ReadAry ( UnIn, FileName, TmpIntAr3, 3, 'GridNx, GridNY, GridNZ', & - 'GridNx, GridNY, GridNZ', ErrStatTmp, ErrMsgTmp, UnEchoLocal) - IF ( ErrStat /= ErrID_None ) THEN - CALL SetErrStat( ErrID_Fatal,ErrMsgTmp,ErrStat,ErrMsg,RoutineName) - CALL CleanupEchoFile( EchoFileContents, UnEchoLocal ) - CLOSE( UnIn ) - RETURN - ENDIF + CALL ReadAry ( UnIn, FileName, DvrSettings%GridN, 3, 'GridNx, GridNY, GridNZ', 'GridNx, GridNY, GridNZ', ErrStatTmp, ErrMsgTmp, UnEchoLocal ); if (Failed()) return ! Save the GridNY and GridNZ values - DvrSettings%GridN(1) = TmpIntAr3(1) ! X direction - DvrSettings%GridN(2) = TmpIntAr3(2) ! Y direction - DvrSettings%GridN(3) = TmpIntAr3(3) ! Z direction - DvrFlags%XRange = .TRUE. ! read in value for the X direction gridding - DvrFlags%YRange = .TRUE. ! read in value for the Y direction gridding - DvrFlags%ZRange = .TRUE. ! read in value for the Z direction gridding - + DvrFlags%XRange = .TRUE. ! read in value for the X direction gridding + DvrFlags%YRange = .TRUE. ! read in value for the Y direction gridding + DvrFlags%ZRange = .TRUE. ! read in value for the Z direction gridding ! Check that valid values of Dx, Dy, and Dz were read in. @@ -1269,10 +1009,8 @@ SUBROUTINE ReadDvrIptFile( DvrFileName, DvrFlags, DvrSettings, ProgInfo, ErrStat DvrFlags%ZRange = .TRUE. ENDIF - ELSE ! read these lines as comments (actually, we don't need to read them) - DvrSettings%GridDelta = 0.0_ReKi DvrFlags%Dx = .FALSE. DvrFlags%Dy = .FALSE. @@ -1284,68 +1022,47 @@ SUBROUTINE ReadDvrIptFile( DvrFileName, DvrFlags, DvrSettings, ProgInfo, ErrStat DvrFlags%ZRange = .FALSE. ! Skip the next three entries of the gridded data section. - CALL ReadCom( UnIn, FileName,' Skipping the gridded data section since not calculating it.', ErrStatTmp, ErrMsgTmp, UnEchoLocal ) - IF ( ErrStatTmp /= ErrID_None ) THEN - CALL SetErrStat(ErrID_Fatal,ErrMsgTmp,ErrStat,ErrMsg,RoutineName) - CALL CleanupEchoFile( EchoFileContents, UnEchoLocal ) - CLOSE( UnIn ) - RETURN - ENDIF - CALL ReadCom( UnIn, FileName,' Skipping the gridded data section since not calculating it.', ErrStatTmp, ErrMsgTmp, UnEchoLocal ) - IF ( ErrStatTmp /= ErrID_None ) THEN - CALL SetErrStat(ErrID_Fatal,ErrMsgTmp,ErrStat,ErrMsg,RoutineName) - CALL CleanupEchoFile( EchoFileContents, UnEchoLocal ) - CLOSE( UnIn ) - RETURN - ENDIF - CALL ReadCom( UnIn, FileName,' Skipping the gridded data section since not calculating it.', ErrStatTmp, ErrMsgTmp, UnEchoLocal ) - IF ( ErrStatTmp /= ErrID_None ) THEN - CALL SetErrStat(ErrID_Fatal,ErrMsgTmp,ErrStat,ErrMsg,RoutineName) - CALL CleanupEchoFile( EchoFileContents, UnEchoLocal ) - CLOSE( UnIn ) - RETURN - ENDIF + CALL ReadCom( UnIn, FileName,' Skipping the gridded data section since not calculating it.', ErrStatTmp, ErrMsgTmp, UnEchoLocal ); if (Failed()) return + CALL ReadCom( UnIn, FileName,' Skipping the gridded data section since not calculating it.', ErrStatTmp, ErrMsgTmp, UnEchoLocal ); if (Failed()) return + CALL ReadCom( UnIn, FileName,' Skipping the gridded data section since not calculating it.', ErrStatTmp, ErrMsgTmp, UnEchoLocal ); if (Failed()) return ENDIF !------------------------------------------------------------------------------------------------- - ! XY slice output + ! VTK output slices !------------------------------------------------------------------------------------------------- - - ! Header - CALL ReadCom( UnIn, FileName,' XY slice output, comment line', ErrStatTmp, ErrMsgTmp, UnEchoLocal ) - IF ( ErrStatTmp /= ErrID_None ) THEN - CALL SetErrStat(ErrID_Fatal,ErrMsgTmp,ErrStat,ErrMsg,RoutineName) - CALL CleanupEchoFile( EchoFileContents, UnEchoLocal ) - CLOSE( UnIn ) - RETURN - ENDIF - - - ! XYslice -- Output a VTK slice in XY - CALL ReadVar( UnIn, FileName,DvrFlags%XYslice,'XYslice',' VTK slice in XY?', & - ErrStatTmp,ErrMsgTmp, UnEchoLocal ) - IF ( ErrStatTmp /= ErrID_None ) THEN - CALL SetErrStat(ErrID_Fatal,ErrMsgTmp,ErrStat,ErrMsg,RoutineName) - CALL CleanupEchoFile( EchoFileContents, UnEchoLocal ) - CLOSE( UnIn ) - RETURN - ENDIF - - ! XYslice_height -- Height for XY slice - CALL ReadVar( UnIn, FileName,DvrSettings%XYslice_height,'XYslice_height',' VTK slice height', & - ErrStatTmp,ErrMsgTmp, UnEchoLocal ) - IF ( ErrStatTmp /= ErrID_None ) THEN - CALL SetErrStat(ErrID_Fatal,ErrMsgTmp,ErrStat,ErrMsg,RoutineName) - CALL CleanupEchoFile( EchoFileContents, UnEchoLocal ) - CLOSE( UnIn ) - RETURN - ENDIF + CALL ReadCom( UnIn, FileName,' VTK output slices, comment line', ErrStatTmp, ErrMsgTmp, UnEchoLocal ); if (Failed()) return + + ! NOutWindXY -- Number of XY planes for output .XY.t.vtk (-) [0 to 9] + CALL ReadVar( UnIn, FileName,DvrSettings%NOutWindXY, 'NOutWindXY','Number of VTK slices in XY?', ErrStatTmp,ErrMsgTmp, UnEchoLocal ); if (Failed()) return + if (DvrSettings%NOutWindXY > 0_IntKi) then + CALL AllocAry( DvrSettings%OutWindZ, DvrSettings%NOutWindXY, "Z coordinates of XY planes for output", ErrStatTmp,ErrMsgTmp ); if (Failed()) return + CALL ReadAry( UnIn, FileName,DvrSettings%OutWindZ,DvrSettings%NOutWindXY,'OutWindZ','Z coordinates', ErrStatTmp,ErrMsgTmp, UnEchoLocal ); if (Failed()) return + else + CALL ReadCom( UnIn, FileName,' Skipping OutWindZ', ErrStatTmp,ErrMsgTmp,UnEchoLocal); if (Failed()) return + endif + + ! NOutWindXZ -- Number of XZ planes for output .XZ.t.vtk (-) [0 to 9] + CALL ReadVar( UnIn, FileName,DvrSettings%NOutWindXZ, 'NOutWindXZ','Number of VTK slices in XZ?', ErrStatTmp,ErrMsgTmp, UnEchoLocal ); if (Failed()) return + if (DvrSettings%NOutWindXZ > 0_IntKi) then + CALL AllocAry( DvrSettings%OutWindY, DvrSettings%NOutWindXZ, "Y coordinates of XZ planes for output",ErrStatTmp,ErrMsgTmp ); if (Failed()) return + CALL ReadAry( UnIn, FileName,DvrSettings%OutWindY,DvrSettings%NOutWindXZ,'OutWindY','Y coordinates' ,ErrStatTmp,ErrMsgTmp, UnEchoLocal ); if (Failed()) return + else + CALL ReadCom( UnIn, FileName,' Skipping OutWindY', ErrStatTmp,ErrMsgTmp,UnEchoLocal); if (Failed()) return + endif + + ! NOutWindYZ -- Number of YZ planes for output .YZ.t.vtk (-) [0 to 9] + CALL ReadVar( UnIn, FileName,DvrSettings%NOutWindYZ, 'NOutWindYZ','Number of VTK slices in YZ?', ErrStatTmp,ErrMsgTmp, UnEchoLocal ); if (Failed()) return + if (DvrSettings%NOutWindYZ > 0_IntKi) then + CALL AllocAry( DvrSettings%OutWindX, DvrSettings%NOutWindYZ, "X coordinates of YZ planes for output", ErrStatTmp,ErrMsgTmp ); if (Failed()) return + CALL ReadAry( UnIn, FileName,DvrSettings%OutWindX,DvrSettings%NOutWindYZ,'OutWindX','X coordinates', ErrStatTmp,ErrMsgTmp, UnEchoLocal ); if (Failed()) return + else + CALL ReadCom( UnIn, FileName,' Skipping OutWindX', ErrStatTmp,ErrMsgTmp,UnEchoLocal); if (Failed()) return + endif ! Close the echo and input file - CALL CleanupEchoFile( EchoFileContents, UnEchoLocal ) - CLOSE( UnIn ) + CALL Cleanup() CONTAINS @@ -1353,17 +1070,19 @@ SUBROUTINE ReadDvrIptFile( DvrFileName, DvrFlags, DvrSettings, ProgInfo, ErrStat !---------------------------------------------------------------------------------------------------- !> The routine cleans up the module echo file and resets the NWTC_Library, reattaching it to !! any existing echo information - SUBROUTINE CleanupEchoFile( EchoFlag, UnEcho) - LOGICAL, INTENT(IN ) :: EchoFlag ! local version of echo flag - INTEGER(IntKi), INTENT(IN ) :: UnEcho ! echo unit number - - ! Close this module's echo file - IF ( EchoFlag ) THEN - CLOSE(UnEcho) + subroutine Cleanup() + ! Close this module's echo file + IF ( EchoFileContents ) THEN + CLOSE(UnEchoLocal) ENDIF - END SUBROUTINE CleanupEchoFile - - + if (UnIn > 1) close(UnIn) + end subroutine Cleanup + !------------------------------------------------------------------------------------------------- + logical function Failed() + CALL SetErrStat( ErrStatTmp, ErrMsgTmp, ErrStat, ErrMsg, RoutineName ) + Failed = ErrStat >= AbortErrLev + if (Failed) CALL Cleanup() + end function Failed END SUBROUTINE ReadDvrIptFile @@ -2748,10 +2467,25 @@ SUBROUTINE printSettings( DvrFlags, DvrSettings ) CALL WrScr(' FFTOutputInit: '//FLAG(DvrSettings%FFTOutput%Initialized)// ' Unit #: '//TRIM(Num2LStr(DvrSettings%FFTOutput%Unit))) CALL WrScr(' PointsVelOutputInit: '//FLAG(DvrSettings%PointsVelOutput%Initialized)// ' Unit #: '//TRIM(Num2LStr(DvrSettings%PointsVelOutput%Unit))) CALL WrScr(' PointsAccOutputInit: '//FLAG(DvrSettings%PointsVelOutput%Initialized)// ' Unit #: '//TRIM(Num2LStr(DvrSettings%PointsVelOutput%Unit))) - CALL WrScr(' XYslice: '//FLAG(DvrFlags%XYslice)) -if (DvrFlags%XYslice) then - CALL WrScr(' XYslice_height '//TRIM(Num2LStr(DvrSettings%XYslice_height))) -end if + call WrScr(' NOutWindXY: '//trim(Num2LStr(DvrSettings%NOutWindXY))) + if (DvrSettings%NOutWindXY>0) then + do i=1,DvrSettings%NOutWindXY + call WrScr(' z location '//trim(Num2LStr(i))//': '//trim(Num2LStr(DvrSettings%OutWindZ(i)))) + enddo + endif + call WrScr(' NOutWindXZ: '//trim(Num2LStr(DvrSettings%NOutWindXZ))) + if (DvrSettings%NOutWindXZ>0) then + do i=1,DvrSettings%NOutWindXZ + call WrScr(' y location '//trim(Num2LStr(i))//': '//trim(Num2LStr(DvrSettings%OutWindY(i)))) + enddo + endif + call WrScr(' NOutWindYZ: '//trim(Num2LStr(DvrSettings%NOutWindYZ))) + if (DvrSettings%NOutWindYZ>0) then + do i=1,DvrSettings%NOutWindYZ + call WrScr(' x location '//trim(Num2LStr(i))//': '//trim(Num2LStr(DvrSettings%OutWindX(i)))) + enddo + endif + END SUBROUTINE printSettings From e950eb76d9c33aa250fcd735b5da88278b716970 Mon Sep 17 00:00:00 2001 From: andrew-platt Date: Sat, 9 Nov 2024 17:45:00 -0700 Subject: [PATCH 119/161] vs-build: revert IfW project to dev version --- vs-build/InflowWind/InflowWind_driver.vfproj | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/vs-build/InflowWind/InflowWind_driver.vfproj b/vs-build/InflowWind/InflowWind_driver.vfproj index 6d3c65f6f..3f4cd8d25 100644 --- a/vs-build/InflowWind/InflowWind_driver.vfproj +++ b/vs-build/InflowWind/InflowWind_driver.vfproj @@ -152,23 +152,6 @@ - - - - - - - - - - - - - - - - - From c9bae97e1630531158666644c9f5adfad87da5e1 Mon Sep 17 00:00:00 2001 From: andrew-platt Date: Sun, 22 Dec 2024 14:39:24 -0700 Subject: [PATCH 120/161] IfW: update driver test case after merging dev into branch --- .../user/inflowwind/examples/inflowwind_driver_example.inp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/docs/source/user/inflowwind/examples/inflowwind_driver_example.inp b/docs/source/user/inflowwind/examples/inflowwind_driver_example.inp index ada6a1542..6f10820ae 100644 --- a/docs/source/user/inflowwind/examples/inflowwind_driver_example.inp +++ b/docs/source/user/inflowwind/examples/inflowwind_driver_example.inp @@ -24,4 +24,11 @@ InflowWind driver input file. 6,0,15 GridCtrCoord -- coordinate of center of grid (m) 1,1,0 GridDx,GridDY,GridDZ -- Step size of grid (m) 1,1,0 GridNx,GridNY,GridNZ -- number of grid points in X, Y and Z directions (-) +---- Output VTK slices ------------------------------------------------------ + 0 NOutWindXY -- Number of XY planes for output .XY.t.vtk (-) [0 to 9] + 90 OutWindZ -- Z coordinates of XY planes for output (m) [1 to NOutWindXY] [unused for NOutWindXY=0] + 0 NOutWindXZ -- Number of XZ planes for output .YZ.t.vtk (-) [0 to 9] + 0 OutWindY -- Y coordinates of XZ planes for output (m) [1 to NOutWindXZ] [unused for NOutWindXZ=0] + 0 NOutWindYZ -- Number of YZ planes for output .YZ.t.vtk (-) [0 to 9] + 0 OutWindX -- X coordinates of YZ planes for output (m) [1 to NOutWindYZ] [unused for NOutWindYZ=0] END of driver input file From 48fddd16dc052bdba9ca00655c207d0ed96ad469 Mon Sep 17 00:00:00 2001 From: andrew-platt Date: Mon, 11 Nov 2024 17:41:52 -0700 Subject: [PATCH 121/161] IfW driver: cleanup -vv printing to screen --- modules/inflowwind/src/InflowWind_Driver.f90 | 23 +++++++++++++++----- 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/modules/inflowwind/src/InflowWind_Driver.f90 b/modules/inflowwind/src/InflowWind_Driver.f90 index a4411c9d4..ab7278f85 100644 --- a/modules/inflowwind/src/InflowWind_Driver.f90 +++ b/modules/inflowwind/src/InflowWind_Driver.f90 @@ -116,8 +116,23 @@ PROGRAM InflowWind_Driver CALL CPU_TIME( Timer(1) ) ! Set some CLSettings to null/default values - CLSettings%ProgInfo = ProgInfo - Settings%ProgInfo = ProgInfo + CLSettings%ProgInfo = ProgInfo + Settings%ProgInfo = ProgInfo + ! Set the filenames to empty strings -- otherwise prints garbage with the -vv option + CLSettings%DvrIptFileName = '' + CLSettings%IfWIptFileName = '' + CLSettings%SummaryFileName = '' + CLSettings%PointsFileName = '' + CLSettings%WindGridOutput%Name = '' + CLSettings%FFTOutput%Name = '' + CLSettings%PointsVelOutput%Name = '' + Settings%DvrIptFileName = '' + Settings%IfWIptFileName = '' + Settings%SummaryFileName = '' + Settings%PointsFileName = '' + Settings%WindGridOutput%Name = '' + Settings%FFTOutput%Name = '' + Settings%PointsVelOutput%Name = '' !-------------------------------------------------------------------------------------------------------------------------------- !-=-=- Parse the command line inputs -=-=- @@ -423,10 +438,6 @@ PROGRAM InflowWind_Driver - ! Let user know we returned from the InflowWind code if verbose - IF ( IfWDriver_Verbose >= 5_IntKi ) CALL WrScr(NewLine//'InflowWind_Init CALL returned without errors.'//NewLine) - - ! Convert InflowWind file to HAWC format IF (SettingsFlags%WrHAWC) THEN CALL IfW_WriteHAWC( InflowWind_p%FlowField, InflowWind_InitInp%RootName, ErrStat, ErrMsg ) From 464b01ef69900f55b21ab43f551ba1abf8ca9f82 Mon Sep 17 00:00:00 2001 From: andrew-platt Date: Mon, 11 Nov 2024 17:42:41 -0700 Subject: [PATCH 122/161] IfW: add path handling for xyslice output (hardcoded for now) --- modules/inflowwind/src/InflowWind_Driver.f90 | 9 +++-- .../inflowwind/src/InflowWind_Driver_Subs.f90 | 29 +++++++------- modules/inflowwind/src/InflowWind_IO.f90 | 39 +++++++++++-------- 3 files changed, 43 insertions(+), 34 deletions(-) diff --git a/modules/inflowwind/src/InflowWind_Driver.f90 b/modules/inflowwind/src/InflowWind_Driver.f90 index ab7278f85..0a4413d02 100644 --- a/modules/inflowwind/src/InflowWind_Driver.f90 +++ b/modules/inflowwind/src/InflowWind_Driver.f90 @@ -39,6 +39,9 @@ PROGRAM InflowWind_Driver TYPE( ProgDesc ), PARAMETER :: ProgInfo = ProgDesc("InflowWind_Driver","","") INTEGER(IntKi) :: IfWDriver_Verbose = 5 ! Verbose level. 0 = none, 5 = some, 10 = lots + ! output paths hard coded + CHARACTER(*), PARAMETER :: VTKsliceDir = "vtk" ! Directory to place the output VTK slices + ! Types needed here (from InflowWind module) TYPE(InflowWind_InitInputType) :: InflowWind_InitInp ! Data for initialization -- this is where the input info goes TYPE(InflowWind_InputType) :: InflowWind_u1 ! input -- contains xyz coords of interest -- set 1 @@ -466,7 +469,7 @@ PROGRAM InflowWind_Driver IF (Settings%NOutWindXY>0) THEN do i=1,Settings%NOutWindXY - CALL IfW_WriteXYslice( InflowWind_p%FlowField, InflowWind_InitInp%RootName, Settings%OutWindZ(i), ErrStat, ErrMsg ) + CALL IfW_WriteXYslice( InflowWind_p%FlowField, InflowWind_InitInp%RootName, VTKsliceDir, Settings%OutWindZ(i), ErrStat, ErrMsg ) call CheckCallErr('IfW_WriteXYslice'//trim(Num2LStr(i))) enddo END IF @@ -474,7 +477,7 @@ PROGRAM InflowWind_Driver IF (Settings%NOutWindXZ>0) THEN do i=1,Settings%NOutWindXZ -! CALL IfW_WriteXZslice( InflowWind_p%FlowField, InflowWind_InitInp%RootName, Settings%OutWindY(i), ErrStat, ErrMsg ) +! CALL IfW_WriteXZslice( InflowWind_p%FlowField, InflowWind_InitInp%RootName, VTKsliceDir, Settings%OutWindY(i), ErrStat, ErrMsg ) ! call CheckCallErr('IfW_WriteXZslice'//trim(Num2LStr(i))) enddo END IF @@ -482,7 +485,7 @@ PROGRAM InflowWind_Driver IF (Settings%NOutWindYZ>0) THEN do i=1,Settings%NOutWindYZ -! CALL IfW_WriteYZslice( InflowWind_p%FlowField, InflowWind_InitInp%RootName, Settings%OutWindX(i), ErrStat, ErrMsg ) +! CALL IfW_WriteYZslice( InflowWind_p%FlowField, InflowWind_InitInp%RootName, VTKsliceDir, Settings%OutWindX(i), ErrStat, ErrMsg ) ! call CheckCallErr('IfW_WriteYZslice'//trim(Num2LStr(i))) enddo END IF diff --git a/modules/inflowwind/src/InflowWind_Driver_Subs.f90 b/modules/inflowwind/src/InflowWind_Driver_Subs.f90 index 6bc47eeae..041fb3096 100644 --- a/modules/inflowwind/src/InflowWind_Driver_Subs.f90 +++ b/modules/inflowwind/src/InflowWind_Driver_Subs.f90 @@ -2376,18 +2376,19 @@ subroutine IfW_WriteVTK(FF, FileRootName, ErrStat, ErrMsg) end subroutine IfW_WriteVTK -subroutine IfW_WriteXYslice(FF, FileRootName, XYslice_height, ErrStat, ErrMsg) - type(FlowFieldType), intent(in) :: FF !< Parameters - character(*), intent(in) :: FileRootName !< RootName for output files - real(ReKi), intent(in) :: XYslice_height - integer(IntKi), intent(out) :: ErrStat !< Error status of the operation - character(*), intent(out) :: ErrMsg !< Error message if ErrStat /= ErrID_None - - character(*), parameter :: RoutineName = "IfW_WriteXYslice" - type(Grid3DFieldType) :: G3D - integer(IntKi) :: unit - integer(IntKi) :: ErrStat2 - character(ErrMsgLen) :: ErrMsg2 +subroutine IfW_WriteXYslice(FF, FileRootName, vtk_dir, XYslice_height, ErrStat, ErrMsg) + type(FlowFieldType), intent(in ) :: FF !< Parameters + character(*), intent(in ) :: FileRootName !< RootName for output files + character(*), intent(in ) :: vtk_dir !< Directory for vtk slice outputs + real(ReKi), intent(in ) :: XYslice_height + integer(IntKi), intent( out) :: ErrStat !< Error status of the operation + character(*), intent( out) :: ErrMsg !< Error message if ErrStat /= ErrID_None + + character(*), parameter :: RoutineName = "IfW_WriteXYslice" + type(Grid3DFieldType) :: G3D + integer(IntKi) :: unit + integer(IntKi) :: ErrStat2 + character(ErrMsgLen) :: ErrMsg2 ErrStat = ErrID_None ErrMsg = "" @@ -2404,12 +2405,12 @@ subroutine IfW_WriteXYslice(FF, FileRootName, XYslice_height, ErrStat, ErrMsg) call Uniform_to_Grid3D(FF%Uniform, FF%VelInterpCubic, G3D, ErrStat2, ErrMsg2) call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) if (ErrStat < AbortErrLev) then - call Grid3D_WriteVTKsliceXY(G3D, FileRootName, XYslice_height, unit, ErrStat2, ErrMsg2) + call Grid3D_WriteVTKsliceXY(G3D, FileRootName, vtk_dir, XYslice_height, unit, ErrStat2, ErrMsg2) call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) end if case (Grid3D_FieldType) - call Grid3D_WriteVTKsliceXY(FF%Grid3D, FileRootName, XYslice_height, unit, ErrStat, ErrMsg) + call Grid3D_WriteVTKsliceXY(FF%Grid3D, FileRootName, vtk_dir, XYslice_height, unit, ErrStat, ErrMsg) case default ErrStat = ErrID_Warn diff --git a/modules/inflowwind/src/InflowWind_IO.f90 b/modules/inflowwind/src/InflowWind_IO.f90 index 8b813628b..4c30d9d2e 100644 --- a/modules/inflowwind/src/InflowWind_IO.f90 +++ b/modules/inflowwind/src/InflowWind_IO.f90 @@ -2945,23 +2945,23 @@ subroutine Grid3D_WriteHAWC(G3D, FileRootName, unit, ErrStat, ErrMsg) end subroutine Grid3D_WriteHAWC -subroutine Grid3D_WriteVTKsliceXY(G3D, FileRootName, XYslice_height, unit, ErrStat, ErrMsg) - - type(Grid3DFieldType), intent(in) :: G3D !< Parameters - character(*), intent(in) :: FileRootName !< RootName for output files - real(ReKi), intent(in) :: XYslice_height - integer(IntKi), intent(in) :: unit !< Error status of the operation - integer(IntKi), intent(out) :: ErrStat !< Error status of the operation - character(*), intent(out) :: ErrMsg !< Error message if ErrStat /= ErrID_None +!> This subroutine writes a VTK slice in the XY plane at a designated height (rounds to nearest point) +!! This feature is mostly useful for testing when a grid is needed for comparison elsewhere +subroutine Grid3D_WriteVTKsliceXY(G3D, FileRootName, vtk_dir, XYslice_height, unit, ErrStat, ErrMsg) + type(Grid3DFieldType), intent(in ) :: G3D !< Parameters + character(*), intent(in ) :: FileRootName !< RootName for output files + character(*), intent(in ) :: vtk_dir !< directory for vtk file for output files + real(ReKi), intent(in ) :: XYslice_height + integer(IntKi), intent(in ) :: unit !< Error status of the operation + integer(IntKi), intent( out) :: ErrStat !< Error status of the operation + character(*), intent( out) :: ErrMsg !< Error message if ErrStat /= ErrID_None character(*), parameter :: RoutineName = 'Grid3D_WriteVTKsliceXY' character(1024) :: RootPathName character(1024) :: FileName character(3) :: ht_str - integer :: it !< time index for slice - integer :: ix - integer :: iy - integer :: iz + character(8) :: t_str, t_fmt + integer :: it, ix, iy, iz, twidth real(ReKi) :: time !< time for this slice real(ReKi) :: ht !< nearest grid slice elevation integer(IntKi) :: ErrStat2 @@ -2971,13 +2971,17 @@ subroutine Grid3D_WriteVTKsliceXY(G3D, FileRootName, XYslice_height, unit, ErrSt ErrMsg = "" call GetPath(FileRootName, RootPathName) - RootPathName = trim(RootPathName)//PathSep//"vtk" + RootPathName = trim(RootPathName)//PathSep//vtk_dir call MkDir(trim(RootPathName)) ! make this directory if it doesn't already exist ! get indices for this slice iz = nint((G3D%GridBase + XYslice_height)*G3D%InvDZ) ht = real(iz,ReKi) / G3D%InvDZ + G3D%GridBase ! nearest height index - write(ht_str,'(i3)') nint(ht) + write(ht_str,'(i0.3)') nint(ht) + + ! get width of string for time + twidth=ceiling(log10(real(G3D%NSteps))) + t_fmt='(i0.'//trim(Num2LStr(twidth))//')' ! check for errors in slice height if (iz <= 0_IntKi .or. iz > G3D%NZGrids) then @@ -2987,11 +2991,13 @@ subroutine Grid3D_WriteVTKsliceXY(G3D, FileRootName, XYslice_height, unit, ErrSt ! Loop through time steps do it = 1, G3D%NSteps - time = real(it - 1, ReKi)*G3D%DTime + ! time string + write(t_str,t_fmt) it + ! Create the output vtk file with naming /vtk/DisYZ.t.vtk - FileName = trim(RootPathName)//PathSep//"DisXY.Z"//ht_str//".t"//trim(num2lstr(it))//".vtp" + FileName = trim(RootPathName)//PathSep//"DisXY.Z"//ht_str//".t"//trim(t_str)//".vtp" ! see WrVTK_SP_header call OpenFOutFile(unit, TRIM(FileName), ErrStat2, ErrMsg2) @@ -3019,7 +3025,6 @@ subroutine Grid3D_WriteVTKsliceXY(G3D, FileRootName, XYslice_height, unit, ErrSt close (unit) enddo - end subroutine Grid3D_WriteVTKsliceXY end module InflowWind_IO From 7c165d9dbcbb95f06cbe9c8168981e4f75eea758 Mon Sep 17 00:00:00 2001 From: andrew-platt Date: Sun, 22 Dec 2024 14:45:26 -0700 Subject: [PATCH 123/161] Replace IfW_driver_types.f90 -- bad merge after rebase --- .../src/InflowWind_Driver_Types.f90 | 355 +++++++----------- 1 file changed, 129 insertions(+), 226 deletions(-) diff --git a/modules/inflowwind/src/InflowWind_Driver_Types.f90 b/modules/inflowwind/src/InflowWind_Driver_Types.f90 index 7babb42de..6768f6381 100644 --- a/modules/inflowwind/src/InflowWind_Driver_Types.f90 +++ b/modules/inflowwind/src/InflowWind_Driver_Types.f90 @@ -123,28 +123,25 @@ subroutine InflowWind_Driver_DestroyOutputFile(OutputFileData, ErrStat, ErrMsg) ErrMsg = '' end subroutine -subroutine InflowWind_Driver_PackOutputFile(Buf, Indata) - type(PackBuffer), intent(inout) :: Buf +subroutine InflowWind_Driver_PackOutputFile(RF, Indata) + type(RegFile), intent(inout) :: RF type(OutputFile), intent(in) :: InData character(*), parameter :: RoutineName = 'InflowWind_Driver_PackOutputFile' - if (Buf%ErrStat >= AbortErrLev) return - call RegPack(Buf, InData%Name) - call RegPack(Buf, InData%Unit) - call RegPack(Buf, InData%Initialized) - if (RegCheckErr(Buf, RoutineName)) return + if (RF%ErrStat >= AbortErrLev) return + call RegPack(RF, InData%Name) + call RegPack(RF, InData%Unit) + call RegPack(RF, InData%Initialized) + if (RegCheckErr(RF, RoutineName)) return end subroutine -subroutine InflowWind_Driver_UnPackOutputFile(Buf, OutData) - type(PackBuffer), intent(inout) :: Buf +subroutine InflowWind_Driver_UnPackOutputFile(RF, OutData) + type(RegFile), intent(inout) :: RF type(OutputFile), intent(inout) :: OutData character(*), parameter :: RoutineName = 'InflowWind_Driver_UnPackOutputFile' - if (Buf%ErrStat /= ErrID_None) return - call RegUnpack(Buf, OutData%Name) - if (RegCheckErr(Buf, RoutineName)) return - call RegUnpack(Buf, OutData%Unit) - if (RegCheckErr(Buf, RoutineName)) return - call RegUnpack(Buf, OutData%Initialized) - if (RegCheckErr(Buf, RoutineName)) return + if (RF%ErrStat /= ErrID_None) return + call RegUnpack(RF, OutData%Name); if (RegCheckErr(RF, RoutineName)) return + call RegUnpack(RF, OutData%Unit); if (RegCheckErr(RF, RoutineName)) return + call RegUnpack(RF, OutData%Initialized); if (RegCheckErr(RF, RoutineName)) return end subroutine subroutine InflowWind_Driver_CopyIfWDriver_Flags(SrcIfWDriver_FlagsData, DstIfWDriver_FlagsData, CtrlCode, ErrStat, ErrMsg) @@ -194,100 +191,73 @@ subroutine InflowWind_Driver_DestroyIfWDriver_Flags(IfWDriver_FlagsData, ErrStat ErrMsg = '' end subroutine -subroutine InflowWind_Driver_PackIfWDriver_Flags(Buf, Indata) - type(PackBuffer), intent(inout) :: Buf +subroutine InflowWind_Driver_PackIfWDriver_Flags(RF, Indata) + type(RegFile), intent(inout) :: RF type(IfWDriver_Flags), intent(in) :: InData character(*), parameter :: RoutineName = 'InflowWind_Driver_PackIfWDriver_Flags' - if (Buf%ErrStat >= AbortErrLev) return - call RegPack(Buf, InData%DvrIptFile) - call RegPack(Buf, InData%IfWIptFile) - call RegPack(Buf, InData%Summary) - call RegPack(Buf, InData%SummaryFile) - call RegPack(Buf, InData%TStart) - call RegPack(Buf, InData%NumTimeSteps) - call RegPack(Buf, InData%NumTimeStepsDefault) - call RegPack(Buf, InData%DT) - call RegPack(Buf, InData%DTDefault) - call RegPack(Buf, InData%FFTcalc) - call RegPack(Buf, InData%WindGrid) - call RegPack(Buf, InData%XRange) - call RegPack(Buf, InData%YRange) - call RegPack(Buf, InData%ZRange) - call RegPack(Buf, InData%Dx) - call RegPack(Buf, InData%Dy) - call RegPack(Buf, InData%Dz) - call RegPack(Buf, InData%PointsFile) - call RegPack(Buf, InData%OutputAccel) - call RegPack(Buf, InData%Verbose) - call RegPack(Buf, InData%VVerbose) - call RegPack(Buf, InData%BoxExceedAllowF) - call RegPack(Buf, InData%WrHAWC) - call RegPack(Buf, InData%WrBladed) - call RegPack(Buf, InData%WrVTK) - call RegPack(Buf, InData%WrUniform) - call RegPack(Buf, InData%XYslice) - if (RegCheckErr(Buf, RoutineName)) return + if (RF%ErrStat >= AbortErrLev) return + call RegPack(RF, InData%DvrIptFile) + call RegPack(RF, InData%IfWIptFile) + call RegPack(RF, InData%Summary) + call RegPack(RF, InData%SummaryFile) + call RegPack(RF, InData%TStart) + call RegPack(RF, InData%NumTimeSteps) + call RegPack(RF, InData%NumTimeStepsDefault) + call RegPack(RF, InData%DT) + call RegPack(RF, InData%DTDefault) + call RegPack(RF, InData%FFTcalc) + call RegPack(RF, InData%WindGrid) + call RegPack(RF, InData%XRange) + call RegPack(RF, InData%YRange) + call RegPack(RF, InData%ZRange) + call RegPack(RF, InData%Dx) + call RegPack(RF, InData%Dy) + call RegPack(RF, InData%Dz) + call RegPack(RF, InData%PointsFile) + call RegPack(RF, InData%OutputAccel) + call RegPack(RF, InData%Verbose) + call RegPack(RF, InData%VVerbose) + call RegPack(RF, InData%BoxExceedAllowF) + call RegPack(RF, InData%WrHAWC) + call RegPack(RF, InData%WrBladed) + call RegPack(RF, InData%WrVTK) + call RegPack(RF, InData%WrUniform) + call RegPack(RF, InData%XYslice) + if (RegCheckErr(RF, RoutineName)) return end subroutine -subroutine InflowWind_Driver_UnPackIfWDriver_Flags(Buf, OutData) - type(PackBuffer), intent(inout) :: Buf +subroutine InflowWind_Driver_UnPackIfWDriver_Flags(RF, OutData) + type(RegFile), intent(inout) :: RF type(IfWDriver_Flags), intent(inout) :: OutData character(*), parameter :: RoutineName = 'InflowWind_Driver_UnPackIfWDriver_Flags' - if (Buf%ErrStat /= ErrID_None) return - call RegUnpack(Buf, OutData%DvrIptFile) - if (RegCheckErr(Buf, RoutineName)) return - call RegUnpack(Buf, OutData%IfWIptFile) - if (RegCheckErr(Buf, RoutineName)) return - call RegUnpack(Buf, OutData%Summary) - if (RegCheckErr(Buf, RoutineName)) return - call RegUnpack(Buf, OutData%SummaryFile) - if (RegCheckErr(Buf, RoutineName)) return - call RegUnpack(Buf, OutData%TStart) - if (RegCheckErr(Buf, RoutineName)) return - call RegUnpack(Buf, OutData%NumTimeSteps) - if (RegCheckErr(Buf, RoutineName)) return - call RegUnpack(Buf, OutData%NumTimeStepsDefault) - if (RegCheckErr(Buf, RoutineName)) return - call RegUnpack(Buf, OutData%DT) - if (RegCheckErr(Buf, RoutineName)) return - call RegUnpack(Buf, OutData%DTDefault) - if (RegCheckErr(Buf, RoutineName)) return - call RegUnpack(Buf, OutData%FFTcalc) - if (RegCheckErr(Buf, RoutineName)) return - call RegUnpack(Buf, OutData%WindGrid) - if (RegCheckErr(Buf, RoutineName)) return - call RegUnpack(Buf, OutData%XRange) - if (RegCheckErr(Buf, RoutineName)) return - call RegUnpack(Buf, OutData%YRange) - if (RegCheckErr(Buf, RoutineName)) return - call RegUnpack(Buf, OutData%ZRange) - if (RegCheckErr(Buf, RoutineName)) return - call RegUnpack(Buf, OutData%Dx) - if (RegCheckErr(Buf, RoutineName)) return - call RegUnpack(Buf, OutData%Dy) - if (RegCheckErr(Buf, RoutineName)) return - call RegUnpack(Buf, OutData%Dz) - if (RegCheckErr(Buf, RoutineName)) return - call RegUnpack(Buf, OutData%PointsFile) - if (RegCheckErr(Buf, RoutineName)) return - call RegUnpack(Buf, OutData%OutputAccel) - if (RegCheckErr(Buf, RoutineName)) return - call RegUnpack(Buf, OutData%Verbose) - if (RegCheckErr(Buf, RoutineName)) return - call RegUnpack(Buf, OutData%VVerbose) - if (RegCheckErr(Buf, RoutineName)) return - call RegUnpack(Buf, OutData%BoxExceedAllowF) - if (RegCheckErr(Buf, RoutineName)) return - call RegUnpack(Buf, OutData%WrHAWC) - if (RegCheckErr(Buf, RoutineName)) return - call RegUnpack(Buf, OutData%WrBladed) - if (RegCheckErr(Buf, RoutineName)) return - call RegUnpack(Buf, OutData%WrVTK) - if (RegCheckErr(Buf, RoutineName)) return - call RegUnpack(Buf, OutData%WrUniform) - if (RegCheckErr(Buf, RoutineName)) return - call RegUnpack(Buf, OutData%XYslice) - if (RegCheckErr(Buf, RoutineName)) return + if (RF%ErrStat /= ErrID_None) return + call RegUnpack(RF, OutData%DvrIptFile); if (RegCheckErr(RF, RoutineName)) return + call RegUnpack(RF, OutData%IfWIptFile); if (RegCheckErr(RF, RoutineName)) return + call RegUnpack(RF, OutData%Summary); if (RegCheckErr(RF, RoutineName)) return + call RegUnpack(RF, OutData%SummaryFile); if (RegCheckErr(RF, RoutineName)) return + call RegUnpack(RF, OutData%TStart); if (RegCheckErr(RF, RoutineName)) return + call RegUnpack(RF, OutData%NumTimeSteps); if (RegCheckErr(RF, RoutineName)) return + call RegUnpack(RF, OutData%NumTimeStepsDefault); if (RegCheckErr(RF, RoutineName)) return + call RegUnpack(RF, OutData%DT); if (RegCheckErr(RF, RoutineName)) return + call RegUnpack(RF, OutData%DTDefault); if (RegCheckErr(RF, RoutineName)) return + call RegUnpack(RF, OutData%FFTcalc); if (RegCheckErr(RF, RoutineName)) return + call RegUnpack(RF, OutData%WindGrid); if (RegCheckErr(RF, RoutineName)) return + call RegUnpack(RF, OutData%XRange); if (RegCheckErr(RF, RoutineName)) return + call RegUnpack(RF, OutData%YRange); if (RegCheckErr(RF, RoutineName)) return + call RegUnpack(RF, OutData%ZRange); if (RegCheckErr(RF, RoutineName)) return + call RegUnpack(RF, OutData%Dx); if (RegCheckErr(RF, RoutineName)) return + call RegUnpack(RF, OutData%Dy); if (RegCheckErr(RF, RoutineName)) return + call RegUnpack(RF, OutData%Dz); if (RegCheckErr(RF, RoutineName)) return + call RegUnpack(RF, OutData%PointsFile); if (RegCheckErr(RF, RoutineName)) return + call RegUnpack(RF, OutData%OutputAccel); if (RegCheckErr(RF, RoutineName)) return + call RegUnpack(RF, OutData%Verbose); if (RegCheckErr(RF, RoutineName)) return + call RegUnpack(RF, OutData%VVerbose); if (RegCheckErr(RF, RoutineName)) return + call RegUnpack(RF, OutData%BoxExceedAllowF); if (RegCheckErr(RF, RoutineName)) return + call RegUnpack(RF, OutData%WrHAWC); if (RegCheckErr(RF, RoutineName)) return + call RegUnpack(RF, OutData%WrBladed); if (RegCheckErr(RF, RoutineName)) return + call RegUnpack(RF, OutData%WrVTK); if (RegCheckErr(RF, RoutineName)) return + call RegUnpack(RF, OutData%WrUniform); if (RegCheckErr(RF, RoutineName)) return + call RegUnpack(RF, OutData%XYslice); if (RegCheckErr(RF, RoutineName)) return end subroutine subroutine InflowWind_Driver_CopyIfWDriver_Settings(SrcIfWDriver_SettingsData, DstIfWDriver_SettingsData, CtrlCode, ErrStat, ErrMsg) @@ -296,7 +266,7 @@ subroutine InflowWind_Driver_CopyIfWDriver_Settings(SrcIfWDriver_SettingsData, D integer(IntKi), intent(in ) :: CtrlCode integer(IntKi), intent( out) :: ErrStat character(*), intent( out) :: ErrMsg - integer(IntKi) :: LB(1), UB(1) + integer(B4Ki) :: LB(1), UB(1) integer(IntKi) :: ErrStat2 character(ErrMsgLen) :: ErrMsg2 character(*), parameter :: RoutineName = 'InflowWind_Driver_CopyIfWDriver_Settings' @@ -396,135 +366,68 @@ subroutine InflowWind_Driver_DestroyIfWDriver_Settings(IfWDriver_SettingsData, E end if end subroutine -subroutine InflowWind_Driver_PackIfWDriver_Settings(Buf, Indata) - type(PackBuffer), intent(inout) :: Buf +subroutine InflowWind_Driver_PackIfWDriver_Settings(RF, Indata) + type(RegFile), intent(inout) :: RF type(IfWDriver_Settings), intent(in) :: InData character(*), parameter :: RoutineName = 'InflowWind_Driver_PackIfWDriver_Settings' - if (Buf%ErrStat >= AbortErrLev) return - call RegPack(Buf, InData%DvrIptFileName) - call RegPack(Buf, InData%IfWIptFileName) - call RegPack(Buf, InData%SummaryFileName) - call RegPack(Buf, InData%PointsFileName) - call RegPack(Buf, InData%NumTimeSteps) - call RegPack(Buf, InData%DT) - call RegPack(Buf, InData%TStart) - call RegPack(Buf, InData%FFTcoord(1:3)) - call RegPack(Buf, InData%GridDelta(1:3)) - call RegPack(Buf, InData%GridN(1:3)) - call RegPack(Buf, InData%XRange(1:2)) - call RegPack(Buf, InData%YRange(1:2)) - call RegPack(Buf, InData%ZRange(1:2)) - call NWTC_Library_PackProgDesc(Buf, InData%ProgInfo) - call InflowWind_Driver_PackOutputFile(Buf, InData%WindGridOutput) - call InflowWind_Driver_PackOutputFile(Buf, InData%FFTOutput) - call InflowWind_Driver_PackOutputFile(Buf, InData%PointsVelOutput) - call RegPack(Buf, InData%NOutWindXY) - call RegPack(Buf, allocated(InData%OutWindZ)) - if (allocated(InData%OutWindZ)) then - call RegPackBounds(Buf, 1, lbound(InData%OutWindZ), ubound(InData%OutWindZ)) - call RegPack(Buf, InData%OutWindZ) - end if - call RegPack(Buf, InData%NOutWindXZ) - call RegPack(Buf, allocated(InData%OutWindY)) - if (allocated(InData%OutWindY)) then - call RegPackBounds(Buf, 1, lbound(InData%OutWindY), ubound(InData%OutWindY)) - call RegPack(Buf, InData%OutWindY) - end if - call RegPack(Buf, InData%NOutWindYZ) - call RegPack(Buf, allocated(InData%OutWindX)) - if (allocated(InData%OutWindX)) then - call RegPackBounds(Buf, 1, lbound(InData%OutWindX), ubound(InData%OutWindX)) - call RegPack(Buf, InData%OutWindX) - end if - if (RegCheckErr(Buf, RoutineName)) return + if (RF%ErrStat >= AbortErrLev) return + call RegPack(RF, InData%DvrIptFileName) + call RegPack(RF, InData%IfWIptFileName) + call RegPack(RF, InData%SummaryFileName) + call RegPack(RF, InData%PointsFileName) + call RegPack(RF, InData%NumTimeSteps) + call RegPack(RF, InData%DT) + call RegPack(RF, InData%TStart) + call RegPack(RF, InData%FFTcoord(1:3)) + call RegPack(RF, InData%GridDelta(1:3)) + call RegPack(RF, InData%GridN(1:3)) + call RegPack(RF, InData%XRange(1:2)) + call RegPack(RF, InData%YRange(1:2)) + call RegPack(RF, InData%ZRange(1:2)) + call NWTC_Library_PackProgDesc(RF, InData%ProgInfo) + call InflowWind_Driver_PackOutputFile(RF, InData%WindGridOutput) + call InflowWind_Driver_PackOutputFile(RF, InData%FFTOutput) + call InflowWind_Driver_PackOutputFile(RF, InData%PointsVelOutput) + call RegPack(RF, InData%NOutWindXY) + call RegPackAlloc(RF, InData%OutWindZ) + call RegPack(RF, InData%NOutWindXZ) + call RegPackAlloc(RF, InData%OutWindY) + call RegPack(RF, InData%NOutWindYZ) + call RegPackAlloc(RF, InData%OutWindX) + if (RegCheckErr(RF, RoutineName)) return end subroutine -subroutine InflowWind_Driver_UnPackIfWDriver_Settings(Buf, OutData) - type(PackBuffer), intent(inout) :: Buf +subroutine InflowWind_Driver_UnPackIfWDriver_Settings(RF, OutData) + type(RegFile), intent(inout) :: RF type(IfWDriver_Settings), intent(inout) :: OutData character(*), parameter :: RoutineName = 'InflowWind_Driver_UnPackIfWDriver_Settings' - integer(IntKi) :: LB(1), UB(1) + integer(B4Ki) :: LB(1), UB(1) integer(IntKi) :: stat logical :: IsAllocAssoc - if (Buf%ErrStat /= ErrID_None) return - call RegUnpack(Buf, OutData%DvrIptFileName) - if (RegCheckErr(Buf, RoutineName)) return - call RegUnpack(Buf, OutData%IfWIptFileName) - if (RegCheckErr(Buf, RoutineName)) return - call RegUnpack(Buf, OutData%SummaryFileName) - if (RegCheckErr(Buf, RoutineName)) return - call RegUnpack(Buf, OutData%PointsFileName) - if (RegCheckErr(Buf, RoutineName)) return - call RegUnpack(Buf, OutData%NumTimeSteps) - if (RegCheckErr(Buf, RoutineName)) return - call RegUnpack(Buf, OutData%DT) - if (RegCheckErr(Buf, RoutineName)) return - call RegUnpack(Buf, OutData%TStart) - if (RegCheckErr(Buf, RoutineName)) return - call RegUnpack(Buf, OutData%FFTcoord(1:3)) - if (RegCheckErr(Buf, RoutineName)) return - call RegUnpack(Buf, OutData%GridDelta(1:3)) - if (RegCheckErr(Buf, RoutineName)) return - call RegUnpack(Buf, OutData%GridN(1:3)) - if (RegCheckErr(Buf, RoutineName)) return - call RegUnpack(Buf, OutData%XRange(1:2)) - if (RegCheckErr(Buf, RoutineName)) return - call RegUnpack(Buf, OutData%YRange(1:2)) - if (RegCheckErr(Buf, RoutineName)) return - call RegUnpack(Buf, OutData%ZRange(1:2)) - if (RegCheckErr(Buf, RoutineName)) return - call NWTC_Library_UnpackProgDesc(Buf, OutData%ProgInfo) ! ProgInfo - call InflowWind_Driver_UnpackOutputFile(Buf, OutData%WindGridOutput) ! WindGridOutput - call InflowWind_Driver_UnpackOutputFile(Buf, OutData%FFTOutput) ! FFTOutput - call InflowWind_Driver_UnpackOutputFile(Buf, OutData%PointsVelOutput) ! PointsVelOutput - call RegUnpack(Buf, OutData%NOutWindXY) - if (RegCheckErr(Buf, RoutineName)) return - if (allocated(OutData%OutWindZ)) deallocate(OutData%OutWindZ) - call RegUnpack(Buf, IsAllocAssoc) - if (RegCheckErr(Buf, RoutineName)) return - if (IsAllocAssoc) then - call RegUnpackBounds(Buf, 1, LB, UB) - if (RegCheckErr(Buf, RoutineName)) return - allocate(OutData%OutWindZ(LB(1):UB(1)),stat=stat) - if (stat /= 0) then - call SetErrStat(ErrID_Fatal, 'Error allocating OutData%OutWindZ.', Buf%ErrStat, Buf%ErrMsg, RoutineName) - return - end if - call RegUnpack(Buf, OutData%OutWindZ) - if (RegCheckErr(Buf, RoutineName)) return - end if - call RegUnpack(Buf, OutData%NOutWindXZ) - if (RegCheckErr(Buf, RoutineName)) return - if (allocated(OutData%OutWindY)) deallocate(OutData%OutWindY) - call RegUnpack(Buf, IsAllocAssoc) - if (RegCheckErr(Buf, RoutineName)) return - if (IsAllocAssoc) then - call RegUnpackBounds(Buf, 1, LB, UB) - if (RegCheckErr(Buf, RoutineName)) return - allocate(OutData%OutWindY(LB(1):UB(1)),stat=stat) - if (stat /= 0) then - call SetErrStat(ErrID_Fatal, 'Error allocating OutData%OutWindY.', Buf%ErrStat, Buf%ErrMsg, RoutineName) - return - end if - call RegUnpack(Buf, OutData%OutWindY) - if (RegCheckErr(Buf, RoutineName)) return - end if - call RegUnpack(Buf, OutData%NOutWindYZ) - if (RegCheckErr(Buf, RoutineName)) return - if (allocated(OutData%OutWindX)) deallocate(OutData%OutWindX) - call RegUnpack(Buf, IsAllocAssoc) - if (RegCheckErr(Buf, RoutineName)) return - if (IsAllocAssoc) then - call RegUnpackBounds(Buf, 1, LB, UB) - if (RegCheckErr(Buf, RoutineName)) return - allocate(OutData%OutWindX(LB(1):UB(1)),stat=stat) - if (stat /= 0) then - call SetErrStat(ErrID_Fatal, 'Error allocating OutData%OutWindX.', Buf%ErrStat, Buf%ErrMsg, RoutineName) - return - end if - call RegUnpack(Buf, OutData%OutWindX) - if (RegCheckErr(Buf, RoutineName)) return - end if + if (RF%ErrStat /= ErrID_None) return + call RegUnpack(RF, OutData%DvrIptFileName); if (RegCheckErr(RF, RoutineName)) return + call RegUnpack(RF, OutData%IfWIptFileName); if (RegCheckErr(RF, RoutineName)) return + call RegUnpack(RF, OutData%SummaryFileName); if (RegCheckErr(RF, RoutineName)) return + call RegUnpack(RF, OutData%PointsFileName); if (RegCheckErr(RF, RoutineName)) return + call RegUnpack(RF, OutData%NumTimeSteps); if (RegCheckErr(RF, RoutineName)) return + call RegUnpack(RF, OutData%DT); if (RegCheckErr(RF, RoutineName)) return + call RegUnpack(RF, OutData%TStart); if (RegCheckErr(RF, RoutineName)) return + call RegUnpack(RF, OutData%FFTcoord(1:3)); if (RegCheckErr(RF, RoutineName)) return + call RegUnpack(RF, OutData%GridDelta(1:3)); if (RegCheckErr(RF, RoutineName)) return + call RegUnpack(RF, OutData%GridN(1:3)); if (RegCheckErr(RF, RoutineName)) return + call RegUnpack(RF, OutData%XRange(1:2)); if (RegCheckErr(RF, RoutineName)) return + call RegUnpack(RF, OutData%YRange(1:2)); if (RegCheckErr(RF, RoutineName)) return + call RegUnpack(RF, OutData%ZRange(1:2)); if (RegCheckErr(RF, RoutineName)) return + call NWTC_Library_UnpackProgDesc(RF, OutData%ProgInfo) ! ProgInfo + call InflowWind_Driver_UnpackOutputFile(RF, OutData%WindGridOutput) ! WindGridOutput + call InflowWind_Driver_UnpackOutputFile(RF, OutData%FFTOutput) ! FFTOutput + call InflowWind_Driver_UnpackOutputFile(RF, OutData%PointsVelOutput) ! PointsVelOutput + call RegUnpack(RF, OutData%NOutWindXY); if (RegCheckErr(RF, RoutineName)) return + call RegUnpackAlloc(RF, OutData%OutWindZ); if (RegCheckErr(RF, RoutineName)) return + call RegUnpack(RF, OutData%NOutWindXZ); if (RegCheckErr(RF, RoutineName)) return + call RegUnpackAlloc(RF, OutData%OutWindY); if (RegCheckErr(RF, RoutineName)) return + call RegUnpack(RF, OutData%NOutWindYZ); if (RegCheckErr(RF, RoutineName)) return + call RegUnpackAlloc(RF, OutData%OutWindX); if (RegCheckErr(RF, RoutineName)) return end subroutine END MODULE InflowWind_Driver_Types !ENDOFREGISTRYGENERATEDFILE From 8c06da374a98a909bcc4522789511bdbdde38c62 Mon Sep 17 00:00:00 2001 From: andrew-platt Date: Sun, 22 Dec 2024 15:19:27 -0700 Subject: [PATCH 124/161] IfW driver: remove inputs not programmed yet --- modules/inflowwind/src/InflowWind_Driver.f90 | 17 ++++----- .../inflowwind/src/InflowWind_Driver_Subs.f90 | 35 ++++++++++--------- reg_tests/r-test | 2 +- 3 files changed, 28 insertions(+), 26 deletions(-) diff --git a/modules/inflowwind/src/InflowWind_Driver.f90 b/modules/inflowwind/src/InflowWind_Driver.f90 index 0a4413d02..42b29d1d1 100644 --- a/modules/inflowwind/src/InflowWind_Driver.f90 +++ b/modules/inflowwind/src/InflowWind_Driver.f90 @@ -475,20 +475,21 @@ PROGRAM InflowWind_Driver END IF - IF (Settings%NOutWindXZ>0) THEN - do i=1,Settings%NOutWindXZ +!FIXME: future developent +! IF (Settings%NOutWindXZ>0) THEN +! do i=1,Settings%NOutWindXZ ! CALL IfW_WriteXZslice( InflowWind_p%FlowField, InflowWind_InitInp%RootName, VTKsliceDir, Settings%OutWindY(i), ErrStat, ErrMsg ) ! call CheckCallErr('IfW_WriteXZslice'//trim(Num2LStr(i))) - enddo - END IF +! enddo +! END IF - IF (Settings%NOutWindYZ>0) THEN - do i=1,Settings%NOutWindYZ +! IF (Settings%NOutWindYZ>0) THEN +! do i=1,Settings%NOutWindYZ ! CALL IfW_WriteYZslice( InflowWind_p%FlowField, InflowWind_InitInp%RootName, VTKsliceDir, Settings%OutWindX(i), ErrStat, ErrMsg ) ! call CheckCallErr('IfW_WriteYZslice'//trim(Num2LStr(i))) - enddo - END IF +! enddo +! END IF !-------------------------------------------------------------------------------------------------------------------------------- diff --git a/modules/inflowwind/src/InflowWind_Driver_Subs.f90 b/modules/inflowwind/src/InflowWind_Driver_Subs.f90 index 041fb3096..98d7fdf29 100644 --- a/modules/inflowwind/src/InflowWind_Driver_Subs.f90 +++ b/modules/inflowwind/src/InflowWind_Driver_Subs.f90 @@ -1042,23 +1042,24 @@ SUBROUTINE ReadDvrIptFile( DvrFileName, DvrFlags, DvrSettings, ProgInfo, ErrStat CALL ReadCom( UnIn, FileName,' Skipping OutWindZ', ErrStatTmp,ErrMsgTmp,UnEchoLocal); if (Failed()) return endif - ! NOutWindXZ -- Number of XZ planes for output .XZ.t.vtk (-) [0 to 9] - CALL ReadVar( UnIn, FileName,DvrSettings%NOutWindXZ, 'NOutWindXZ','Number of VTK slices in XZ?', ErrStatTmp,ErrMsgTmp, UnEchoLocal ); if (Failed()) return - if (DvrSettings%NOutWindXZ > 0_IntKi) then - CALL AllocAry( DvrSettings%OutWindY, DvrSettings%NOutWindXZ, "Y coordinates of XZ planes for output",ErrStatTmp,ErrMsgTmp ); if (Failed()) return - CALL ReadAry( UnIn, FileName,DvrSettings%OutWindY,DvrSettings%NOutWindXZ,'OutWindY','Y coordinates' ,ErrStatTmp,ErrMsgTmp, UnEchoLocal ); if (Failed()) return - else - CALL ReadCom( UnIn, FileName,' Skipping OutWindY', ErrStatTmp,ErrMsgTmp,UnEchoLocal); if (Failed()) return - endif - - ! NOutWindYZ -- Number of YZ planes for output .YZ.t.vtk (-) [0 to 9] - CALL ReadVar( UnIn, FileName,DvrSettings%NOutWindYZ, 'NOutWindYZ','Number of VTK slices in YZ?', ErrStatTmp,ErrMsgTmp, UnEchoLocal ); if (Failed()) return - if (DvrSettings%NOutWindYZ > 0_IntKi) then - CALL AllocAry( DvrSettings%OutWindX, DvrSettings%NOutWindYZ, "X coordinates of YZ planes for output", ErrStatTmp,ErrMsgTmp ); if (Failed()) return - CALL ReadAry( UnIn, FileName,DvrSettings%OutWindX,DvrSettings%NOutWindYZ,'OutWindX','X coordinates', ErrStatTmp,ErrMsgTmp, UnEchoLocal ); if (Failed()) return - else - CALL ReadCom( UnIn, FileName,' Skipping OutWindX', ErrStatTmp,ErrMsgTmp,UnEchoLocal); if (Failed()) return - endif +!FIXME: future development +! ! NOutWindXZ -- Number of XZ planes for output .XZ.t.vtk (-) [0 to 9] +! CALL ReadVar( UnIn, FileName,DvrSettings%NOutWindXZ, 'NOutWindXZ','Number of VTK slices in XZ?', ErrStatTmp,ErrMsgTmp, UnEchoLocal ); if (Failed()) return +! if (DvrSettings%NOutWindXZ > 0_IntKi) then +! CALL AllocAry( DvrSettings%OutWindY, DvrSettings%NOutWindXZ, "Y coordinates of XZ planes for output",ErrStatTmp,ErrMsgTmp ); if (Failed()) return +! CALL ReadAry( UnIn, FileName,DvrSettings%OutWindY,DvrSettings%NOutWindXZ,'OutWindY','Y coordinates' ,ErrStatTmp,ErrMsgTmp, UnEchoLocal ); if (Failed()) return +! else +! CALL ReadCom( UnIn, FileName,' Skipping OutWindY', ErrStatTmp,ErrMsgTmp,UnEchoLocal); if (Failed()) return +! endif +! +! ! NOutWindYZ -- Number of YZ planes for output .YZ.t.vtk (-) [0 to 9] +! CALL ReadVar( UnIn, FileName,DvrSettings%NOutWindYZ, 'NOutWindYZ','Number of VTK slices in YZ?', ErrStatTmp,ErrMsgTmp, UnEchoLocal ); if (Failed()) return +! if (DvrSettings%NOutWindYZ > 0_IntKi) then +! CALL AllocAry( DvrSettings%OutWindX, DvrSettings%NOutWindYZ, "X coordinates of YZ planes for output", ErrStatTmp,ErrMsgTmp ); if (Failed()) return +! CALL ReadAry( UnIn, FileName,DvrSettings%OutWindX,DvrSettings%NOutWindYZ,'OutWindX','X coordinates', ErrStatTmp,ErrMsgTmp, UnEchoLocal ); if (Failed()) return +! else +! CALL ReadCom( UnIn, FileName,' Skipping OutWindX', ErrStatTmp,ErrMsgTmp,UnEchoLocal); if (Failed()) return +! endif ! Close the echo and input file diff --git a/reg_tests/r-test b/reg_tests/r-test index a26a6276a..5641aabb0 160000 --- a/reg_tests/r-test +++ b/reg_tests/r-test @@ -1 +1 @@ -Subproject commit a26a6276ac192bfc5b3ef4338e9cff3f175a4210 +Subproject commit 5641aabb0c8dd542d7e3d45e69e52077cc12e902 From 40202bb071e11b4994247a830381093a0e43f088 Mon Sep 17 00:00:00 2001 From: andrew-platt Date: Sun, 22 Dec 2024 15:58:59 -0700 Subject: [PATCH 125/161] Update pointer after PR #2201 --- reg_tests/r-test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reg_tests/r-test b/reg_tests/r-test index 5641aabb0..d641aeb7d 160000 --- a/reg_tests/r-test +++ b/reg_tests/r-test @@ -1 +1 @@ -Subproject commit 5641aabb0c8dd542d7e3d45e69e52077cc12e902 +Subproject commit d641aeb7df530a0249b0679ac5de6829069c58c4 From 355419ced651d37799133d46b7ceb4cc5791b4a9 Mon Sep 17 00:00:00 2001 From: andrew-platt Date: Sun, 22 Dec 2024 17:43:34 -0700 Subject: [PATCH 126/161] IfW: if AD is used, set BoxExceedAllow to true Ideally, we would set this after we initialize AD and decide based on if OLAF is used. But IfW is initialized before AD now, so we don't know if OLAF will need this info. --- modules/aerodyn/src/AeroDyn.f90 | 2 +- modules/aerodyn/src/AeroDyn_Inflow.f90 | 4 ++++ modules/openfast-library/src/FAST_Subs.f90 | 7 +++++++ 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/modules/aerodyn/src/AeroDyn.f90 b/modules/aerodyn/src/AeroDyn.f90 index d43664041..7109a5f2a 100644 --- a/modules/aerodyn/src/AeroDyn.f90 +++ b/modules/aerodyn/src/AeroDyn.f90 @@ -1929,7 +1929,7 @@ subroutine AD_CalcWind_Rotor(t, u, FlowField, p, RotInflow, StartNode, ErrStat, contains logical function Failed() - call SetErrStat(errStat2, errMsg2, errStat, errMsg, 'AD_CalcWind') + call SetErrStat(errStat2, errMsg2, errStat, errMsg, 'AD_CalcWindRotor') Failed = errStat >= AbortErrLev end function Failed end subroutine diff --git a/modules/aerodyn/src/AeroDyn_Inflow.f90 b/modules/aerodyn/src/AeroDyn_Inflow.f90 index 5da3f6b8d..3f212d78e 100644 --- a/modules/aerodyn/src/AeroDyn_Inflow.f90 +++ b/modules/aerodyn/src/AeroDyn_Inflow.f90 @@ -388,6 +388,10 @@ subroutine ADI_InitInflowWind(Root, i_IW, u_AD, o_AD, IW, dt, InitOutData, errSt endif InitInData%RootName = trim(Root)//'.IfW' InitInData%MHK = i_IW%MHK + ! OLAF might be used in AD, in which case we need to allow out of bounds for some calcs. To do that + ! the average values for the entire wind profile must be calculated and stored (we don't know if OLAF + ! is used until after AD_Init below). + InitInData%BoxExceedAllow = .true. CALL InflowWind_Init( InitInData, IW%u, IW%p, & IW%x, IW%xd, IW%z, IW%OtherSt, & IW%y, IW%m, dt, InitOutData, errStat2, errMsg2 ) diff --git a/modules/openfast-library/src/FAST_Subs.f90 b/modules/openfast-library/src/FAST_Subs.f90 index 816441536..9a8db0b26 100644 --- a/modules/openfast-library/src/FAST_Subs.f90 +++ b/modules/openfast-library/src/FAST_Subs.f90 @@ -520,6 +520,13 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, SED, BD, S Init%InData_IfW%Use4Dext = .false. END IF + ! OLAF might be used in AD, in which case we need to allow out of bounds for some calcs. To do that + ! the average values for the entire wind profile must be calculated and stored (we don't know if OLAF + ! is used until after AD_Init below). + if (p_FAST%CompAero == Module_AD) then + Init%InData_IfW%BoxExceedAllow = .true. + endif + CALL InflowWind_Init( Init%InData_IfW, IfW%Input(1), IfW%p, IfW%x(STATE_CURR), IfW%xd(STATE_CURR), IfW%z(STATE_CURR), & IfW%OtherSt(STATE_CURR), IfW%y, IfW%m, p_FAST%dt_module( MODULE_IfW ), Init%OutData_IfW, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) From 8d983acb5b358ba907f533baa8f5e416f04e4393 Mon Sep 17 00:00:00 2001 From: Derek Slaughter Date: Tue, 27 Aug 2024 12:43:58 +0000 Subject: [PATCH 127/161] Fix bug in Calculate_C_alpha (AirfoilInfo.f90) --- modules/aerodyn/src/AirfoilInfo.f90 | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/modules/aerodyn/src/AirfoilInfo.f90 b/modules/aerodyn/src/AirfoilInfo.f90 index 5cde187db..ad76c2c68 100644 --- a/modules/aerodyn/src/AirfoilInfo.f90 +++ b/modules/aerodyn/src/AirfoilInfo.f90 @@ -1195,8 +1195,13 @@ SUBROUTINE Calculate_C_alpha(alpha, Cn, Cl, Default_Cn_alpha, Default_Cl_alpha, A(:,1) = alpha A(:,2) = 1.0_ReKi - B(:,1) = Cn - B(:,2) = Cl + if (size(Cn) == 1) then + B(:,1) = Cn(1) + B(:,2) = Cl(1) + else + B(:,1) = Cn + B(:,2) = Cl + end if CALL LAPACK_gels('N', A, B, ErrStat, ErrMsg) From ea8e9caa99e12fc0172382ba99716a06d9400856 Mon Sep 17 00:00:00 2001 From: andrew-platt Date: Wed, 25 Sep 2024 12:14:09 -0600 Subject: [PATCH 128/161] FF: fix segfault when MD shared moorings not initialized --- glue-codes/fast-farm/src/FAST_Farm_Subs.f90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/glue-codes/fast-farm/src/FAST_Farm_Subs.f90 b/glue-codes/fast-farm/src/FAST_Farm_Subs.f90 index 813a3243c..606742092 100644 --- a/glue-codes/fast-farm/src/FAST_Farm_Subs.f90 +++ b/glue-codes/fast-farm/src/FAST_Farm_Subs.f90 @@ -1841,7 +1841,7 @@ subroutine FARM_End(farm, ErrStat, ErrMsg) !-------------- ! 6. End farm-level MoorDyn - if (farm%p%MooringMod == 3) then + if (farm%p%MooringMod == 3 .and. allocated(farm%MD%Input)) then call MD_End(farm%MD%Input(1), farm%MD%p, farm%MD%x, farm%MD%xd, farm%MD%z, farm%MD%OtherSt, farm%MD%y, farm%MD%m, ErrStat2, ErrMsg2) call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) !TODO: any related items need to be cleared? From 841bb9c222d59b4da3d6baab3005c58efbae0d2c Mon Sep 17 00:00:00 2001 From: andrew-platt Date: Sun, 22 Dec 2024 20:37:28 -0700 Subject: [PATCH 129/161] ADI python: fix type for a logical flag --- modules/aerodyn/python-lib/aerodyn_inflow_library.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/aerodyn/python-lib/aerodyn_inflow_library.py b/modules/aerodyn/python-lib/aerodyn_inflow_library.py index 22e4a8730..a0cae3d52 100644 --- a/modules/aerodyn/python-lib/aerodyn_inflow_library.py +++ b/modules/aerodyn/python-lib/aerodyn_inflow_library.py @@ -70,8 +70,8 @@ def __init__(self, library_path): self.ended = False # For error handling at end # Input file handling - self.ADinputPass = True # Assume passing of input file as a string - self.IfWinputPass = True # Assume passing of input file as a string + self.ADinputPass = 1 # Assume passing of input file as a string + self.IfWinputPass = 1 # Assume passing of input file as a string # Create buffers for class data self.abort_error_level = 4 From 19ba345c01943609f950ddff80d8241b77e2a601 Mon Sep 17 00:00:00 2001 From: andrew-platt Date: Sun, 22 Dec 2024 21:23:55 -0700 Subject: [PATCH 130/161] ADI_c: update comment on debuglevel --- modules/aerodyn/src/AeroDyn_Inflow_C_Binding.f90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/aerodyn/src/AeroDyn_Inflow_C_Binding.f90 b/modules/aerodyn/src/AeroDyn_Inflow_C_Binding.f90 index 7c319f031..48f0d4601 100644 --- a/modules/aerodyn/src/AeroDyn_Inflow_C_Binding.f90 +++ b/modules/aerodyn/src/AeroDyn_Inflow_C_Binding.f90 @@ -290,9 +290,9 @@ subroutine ADI_C_PreInit(NumTurbines_C, TransposeDCM_in, PointLoadOutput_in, Deb endif ! check valid debug level - if (DebugLevel < 0_IntKi .or. DebugLevel > 4_IntKi) then + if (DebugLevel < 0_IntKi) then ErrStat2 = ErrID_Fatal - ErrMsg2 = "Interface debug level must be between 0 and 4"//NewLine// & + ErrMsg2 = "Interface debug level must be 0 or greater"//NewLine// & " 0 - none"//NewLine// & " 1 - some summary info and variables passed through interface"//NewLine// & " 2 - above + all position/orientation info"//NewLine// & From eab6ed1ea05e006a72e79070163964e59ad29cd4 Mon Sep 17 00:00:00 2001 From: andrew-platt Date: Sun, 22 Dec 2024 22:20:15 -0700 Subject: [PATCH 131/161] IfW_c: update interface - Add debuglevel (only partially completed) - update regression test - remove the passing of the uniform wind file (might be able to remove some stuff from IfW) - other updates to more closely match structure of ADI_c - some linting --- .../python-lib/inflowwind_library.py | 46 +++-- modules/inflowwind/src/IfW_C_Binding.f90 | 194 +++++++++++++----- .../executeInflowwindPyRegressionCase.py | 2 +- reg_tests/r-test | 2 +- 4 files changed, 170 insertions(+), 74 deletions(-) diff --git a/modules/inflowwind/python-lib/inflowwind_library.py b/modules/inflowwind/python-lib/inflowwind_library.py index 26e6eb599..bc741443e 100644 --- a/modules/inflowwind/python-lib/inflowwind_library.py +++ b/modules/inflowwind/python-lib/inflowwind_library.py @@ -52,6 +52,10 @@ class InflowWindLib(CDLL): # here. error_msg_c_len = 1025 + # NOTE: the length of the name used for any output file written by the + # IfW Fortran code is 1025. + default_str_c_len = 1025 + def __init__(self, library_path): super().__init__(library_path) self.library_path = library_path @@ -59,6 +63,9 @@ def __init__(self, library_path): self._initialize_routines() self.ended = False # For error handling at end + # Input file handling + self.IfWinputPass = 1 # Assume passing of input file as a string + # Create buffers for class data self.abort_error_level = 4 self.error_status_c = c_int(0) @@ -84,18 +91,27 @@ def __init__(self, library_path): self.numChannels = 0 # Number of channels returned + # flags + self.debuglevel = 0 # 0-4 levels + + # OutRootName + # If HD writes a file (echo, summary, or other), use this for the + # root of the file name. + self.outRootName = "Output_ifwlib_default" + def _initialize_routines(self): """ Initialize the Python handles to necessary routines in the InflowWind library. """ self.IfW_C_Init.argtypes = [ + POINTER(c_int), # IfW input file passed as string POINTER(c_char_p), # input file string POINTER(c_int), # input file string length - POINTER(c_char_p), # uniform file string - POINTER(c_int), # uniform file string length + POINTER(c_char), # OutRootName POINTER(c_int), # numWindPts POINTER(c_double), # dt + POINTER(c_int), # debuglevel POINTER(c_int), # number of channels POINTER(c_char), # output channel names POINTER(c_char), # output channel units @@ -121,29 +137,29 @@ def _initialize_routines(self): self.IfW_C_End.restype = c_int - def ifw_init(self, input_string_array, uniform_string_array): + def ifw_init(self, IfW_input_string_array): """ Call the initialization routine in the InflowWind library. """ # Set up inputs: Pass single NULL joined string - input_string = '\x00'.join(input_string_array) - input_string = input_string.encode('utf-8') - input_string_length = len(input_string) - - uniform_string = '\x00'.join(uniform_string_array) - uniform_string = uniform_string.encode('utf-8') - uniform_string_length = len(uniform_string) - + IfW_input_string = '\x00'.join(IfW_input_string_array) + IfW_input_string = IfW_input_string.encode('utf-8') + IfW_input_string_length = len(IfW_input_string) + + # Rootname for ADI output files (echo etc). + _outRootName_c = create_string_buffer((self.outRootName.ljust(self.default_str_c_len)).encode('utf-8')) + self._numChannels_c = c_int(0) self.IfW_C_Init( - c_char_p(input_string), # IN: input file string - byref(c_int(input_string_length)), # IN: input file string length - c_char_p(uniform_string), # IN: uniform file string - byref(c_int(uniform_string_length)), # IN: uniform file string length + byref(c_int(self.IfWinputPass)), # IN: IfW input file is passed + c_char_p(IfW_input_string), # IN: input file string + byref(c_int(IfW_input_string_length)), # IN: input file string length + _outRootName_c, # IN: rootname for ADI file writing byref(c_int(self.numWindPts)), # IN: number of wind points byref(c_double(self.dt)), # IN: time step (dt) + byref(c_int(self.debuglevel)), # IN: debuglevel byref(self._numChannels_c), # OUT: number of channels self._channel_names_c, # OUT: output channel names as c_char self._channel_units_c, # OUT: output channel units as c_char diff --git a/modules/inflowwind/src/IfW_C_Binding.f90 b/modules/inflowwind/src/IfW_C_Binding.f90 index 5c9c8ef56..8299d6010 100644 --- a/modules/inflowwind/src/IfW_C_Binding.f90 +++ b/modules/inflowwind/src/IfW_C_Binding.f90 @@ -32,26 +32,39 @@ MODULE InflowWind_C_BINDING PUBLIC :: IfW_C_CalcOutput PUBLIC :: IfW_C_End + !------------------------------------------------------------------------------------ ! Version info for display type(ProgDesc), parameter :: version = ProgDesc( 'InflowWind library', '', '' ) - ! Accessible to all routines inside module - TYPE(InflowWind_InputType) , SAVE :: InputData !< Inputs to InflowWind - TYPE(InflowWind_InitInputType) , SAVE :: InitInp - TYPE(InflowWind_InitOutputType) , SAVE :: InitOutData !< Initial output data -- Names, units, and version info. - TYPE(InflowWind_ParameterType) , SAVE :: p !< Parameters - TYPE(InflowWind_ContinuousStateType) , SAVE :: ContStates !< Initial continuous states - TYPE(InflowWind_DiscreteStateType) , SAVE :: DiscStates !< Initial discrete states - TYPE(InflowWind_ConstraintStateType) , SAVE :: ConstrStates !< Constraint states at Time - TYPE(InflowWind_OtherStateType) , SAVE :: OtherStates !< Initial other/optimization states - TYPE(InflowWind_OutputType) , SAVE :: y !< Initial output (outputs are not calculated; only the output mesh is initialized) - TYPE(InflowWind_MiscVarType) , SAVE :: m !< Misc variables for optimization (not copied in glue code) - - ! This must exactly match the value in the Python interface. We are not using the variable 'ErrMsgLen' - ! so that we avoid issues if ErrMsgLen changes in the NWTC Library. If the value of ErrMsgLen does change - ! in the NWTC Library, ErrMsgLen_C (and the equivalent value in the Python interface) can be updated - ! to be equivalent to ErrMsgLen + 1, but the logic exists to correctly handle different lengths of the strings - integer(IntKi), parameter :: ErrMsgLen_C=1025 ! Numerical equivalent of ErrMsgLen + 1 + !------------------------------------------------------------------------------------ + ! Debugging: DebugLevel -- passed at PreInit + ! 0 - none + ! 1 - some summary info + ! 2 - above + all position/orientation info + ! 3 - above + input files (if direct passed) + ! 4 - above + meshes + integer(IntKi) :: DebugLevel = 0 + + !------------------------------------------------------------------------------------ + ! Primary IfW data derived types + type(InflowWind_InputType) :: InputData !< Inputs to InflowWind + type(InflowWind_InitInputType) :: InitInp + type(InflowWind_InitOutputType) :: InitOutData !< Initial output data -- Names, units, and version info. + type(InflowWind_ParameterType) :: p !< Parameters + type(InflowWind_ContinuousStateType) :: ContStates !< Initial continuous states + type(InflowWind_DiscreteStateType) :: DiscStates !< Initial discrete states + type(InflowWind_ConstraintStateType) :: ConstrStates !< Constraint states at Time + type(InflowWind_OtherStateType) :: OtherStates !< Initial other/optimization states + type(InflowWind_OutputType) :: y !< Initial output (outputs are not calculated; only the output mesh is initialized) + type(InflowWind_MiscVarType) :: m !< Misc variables for optimization (not copied in glue code) + + !------------------------------------------------------------------------------------ + ! Error handling + ! This must exactly match the value in the python-lib. If ErrMsgLen changes at + ! some point in the nwtc-library, this should be updated, but the logic exists + ! to correctly handle different lengths of the strings + integer(IntKi), parameter :: ErrMsgLen_C = 1025 + integer(IntKi), parameter :: IntfStrLen = 1025 ! length of other strings through the C interface @@ -78,35 +91,39 @@ end subroutine SetErr !=============================================================================================================== !--------------------------------------------- IFW INIT -------------------------------------------------------- !=============================================================================================================== -SUBROUTINE IfW_C_Init(InputFileString_C, InputFileStringLength_C, InputUniformString_C, InputUniformStringLength_C, NumWindPts_C, DT_C, NumChannels_C, OutputChannelNames_C, OutputChannelUnits_C, ErrStat_C, ErrMsg_C) BIND (C, NAME='IfW_C_Init') +SUBROUTINE IfW_C_Init(IfWinputFilePassed, IfWinputFileString_C, IfWinputFileStringLength_C, OutRootName_C, & + NumWindPts_C, DT_C, DebugLevel_in, NumChannels_C, OutputChannelNames_C, OutputChannelUnits_C, & + ErrStat_C, ErrMsg_C) BIND (C, NAME='IfW_C_Init') IMPLICIT NONE #ifndef IMPLICIT_DLLEXPORT !DEC$ ATTRIBUTES DLLEXPORT :: IfW_C_Init !GCC$ ATTRIBUTES DLLEXPORT :: IfW_C_Init #endif - TYPE(C_PTR) , INTENT(IN ) :: InputFileString_C - INTEGER(C_INT) , INTENT(IN ) :: InputFileStringLength_C - TYPE(C_PTR) , INTENT(IN ) :: InputUniformString_C - INTEGER(C_INT) , INTENT(IN ) :: InputUniformStringLength_C - INTEGER(C_INT) , INTENT(IN ) :: NumWindPts_C - REAL(C_DOUBLE) , INTENT(IN ) :: DT_C - INTEGER(C_INT) , INTENT( OUT) :: NumChannels_C - CHARACTER(KIND=C_CHAR) , INTENT( OUT) :: OutputChannelNames_C(ChanLen*MaxOutPts+1) - CHARACTER(KIND=C_CHAR) , INTENT( OUT) :: OutputChannelUnits_C(ChanLen*MaxOutPts+1) - INTEGER(C_INT) , INTENT( OUT) :: ErrStat_C - CHARACTER(KIND=C_CHAR) , INTENT( OUT) :: ErrMsg_C(ErrMsgLen_C) - - ! Local Variables - CHARACTER(kind=C_char, len=InputFileStringLength_C), POINTER :: InputFileString !< Input file as a single string with NULL chracter separating lines - CHARACTER(kind=C_char, len=InputUniformStringLength_C), POINTER :: UniformFileString !< Input file as a single string with NULL chracter separating lines -- Uniform wind file - - REAL(DbKi) :: TimeInterval - INTEGER :: ErrStat !< aggregated error message - CHARACTER(ErrMsgLen) :: ErrMsg !< aggregated error message - INTEGER :: ErrStat2 !< temporary error status from a call - CHARACTER(ErrMsgLen) :: ErrMsg2 !< temporary error message from a call - INTEGER :: i,j,k - character(*), parameter :: RoutineName = 'IfW_C_Init' !< for error handling + integer(c_int), intent(in ) :: IfWinputFilePassed !< Write VTK outputs [0: none, 1: init only, 2: animation] + type(c_ptr), intent(in ) :: IfWinputFileString_C !< Input file as a single string with lines deliniated by C_NULL_CHAR + integer(c_int), intent(in ) :: IfWinputFileStringLength_C !< lenght of the input file string + character(kind=c_char), intent(in ) :: OutRootName_C(IntfStrLen) !< Root name to use for echo files and other + integer(c_int), intent(in ) :: NumWindPts_C + real(c_double), intent(in ) :: DT_C + integer(c_int), intent(in ) :: DebugLevel_in + integer(c_int), intent( out) :: NumChannels_C + character(kind=c_char), intent( out) :: OutputChannelNames_C(ChanLen*MaxOutPts+1) + character(kind=c_char), intent( out) :: OutputChannelUnits_C(ChanLen*MaxOutPts+1) + integer(c_int), intent( out) :: ErrStat_C + character(kind=c_char), intent( out) :: ErrMsg_C(ErrMsgLen_C) + + ! local variables + character(IntfStrLen) :: OutRootName !< Root name to use for echo files and other + character(IntfStrLen) :: TmpFileName !< Temporary file name if not passing AD or IfW input file contents directly + character(kind=c_char, len=IfWinputFileStringLength_C), pointer :: IfWinputFileString !< Input file as a single string with NULL chracter separating lines + + real(DbKi) :: TimeInterval + integer :: ErrStat !< aggregated error message + character(ErrMsgLen) :: ErrMsg !< aggregated error message + integer :: ErrStat2 !< temporary error status from a call + character(ErrMsgLen) :: ErrMsg2 !< temporary error message from a call + integer :: i,j,k + character(*), parameter :: RoutineName = 'IfW_C_Init' !< for error handling ! Initialize error handling ErrStat = ErrID_None @@ -116,26 +133,65 @@ SUBROUTINE IfW_C_Init(InputFileString_C, InputFileStringLength_C, InputUniformSt CALL DispCopyrightLicense( version%Name ) CALL DispCompileRuntimeInfo( version%Name ) + + ! interface debugging + DebugLevel = int(DebugLevel_in,IntKi) + + ! Input files + OutRootName = TRANSFER( OutRootName_C, OutRootName ) + i = INDEX(OutRootName,C_NULL_CHAR) - 1 ! if this has a c null character at the end... + if ( i > 0 ) OutRootName = OutRootName(1:I) ! remove it + + ! if non-zero, show all passed data here. Then check valid values + if (DebugLevel /= 0_IntKi) then + call WrScr(" Interface debugging level "//trim(Num2Lstr(DebugLevel))//" requested.") + call ShowPassedData() + endif + ! check valid debug level + if (DebugLevel < 0_IntKi) then + ErrStat2 = ErrID_Fatal + ErrMsg2 = "Interface debug level must be 0 or greater"//NewLine// & + " 0 - none"//NewLine// & + " 1 - some summary info and variables passed through interface"//NewLine// & + " 2 - above + all position/orientation info"//NewLine// & + " 3 - above + input files (if direct passed)"//NewLine// & + " 4 - above + meshes" + if (Failed()) return; + endif + + ! For debugging the interface: + if (DebugLevel > 0) then + call ShowPassedData() + endif + ! Get fortran pointer to C_NULL_CHAR deliniated input file as a string - CALL C_F_pointer(InputFileString_C, InputFileString) - CALL C_F_pointer(InputUniformString_C, UniformFileString) - - ! Store string-inputs as type FileInfoType within InflowWind_InitInputType - CALL InitFileInfo(InputFileString, InitInp%PassedFileInfo, ErrStat2, ErrMsg2); if (Failed()) return - InitInp%FilePassingMethod = 1_IntKi ! read file and pass as FileInfoType structure - - ! store Uniform File strings if they are non-zero sized - if (len(UniformFileString) > 1) then - CALL InitFileInfo(UniformFileString, InitInp%WindType2Info, ErrStat2, ErrMsg2); if (Failed()) return - InitInp%WindType2UseInputFile = .FALSE. - else ! Default to reading from disk - InitInp%WindType2UseInputFile = .TRUE. + CALL C_F_pointer(IfWinputFileString_C, IfWinputFileString) + + ! Format IfW input file contents + if (IfWinputFilePassed==1_c_int) then + InitInp%FilePassingMethod = 1_IntKi ! Don't try to read an input -- use passed data instead (blades and AF tables not passed) using FileInfoType + InitInp%InputFileName = "passed_ifw_file" ! not actually used + call InitFileInfo(IfWinputFileString, InitInp%PassedFileInfo, ErrStat2, ErrMsg2); if (Failed()) return + else + InitInp%FilePassingMethod = 0_IntKi ! Read input info from a primary input file + i = min(IntfStrLen,IfWinputFileStringLength_C) + TmpFileName = '' + TmpFileName(1:i) = IfWinputFileString(1:i) + i = INDEX(TmpFileName,C_NULL_CHAR) - 1 ! if this has a c null character at the end... + if ( i > 0 ) TmpFileName = TmpFileName(1:I) ! remove it + InitInp%InputFileName = TmpFileName + endif + + ! For diagnostic purposes, the following can be used to display the contents + ! of the InFileInfo data structure. + ! CU is the screen -- system dependent. + if (DebugLevel >= 3) then + if (IfWinputFilePassed==1_c_int) call Print_FileInfo_Struct( CU, InitInp%PassedFileInfo ) endif ! Set other inputs for calling InflowWind_Init - InitInp%NumWindPoints = NumWindPts_C - InitInp%InputFileName = "passed_ifw_file" ! dummy - InitInp%RootName = "ifwRoot" ! used for making echo files + InitInp%NumWindPoints = int(NumWindPts_C, IntKi) + InitInp%RootName = OutRootName ! used for making echo files TimeInterval = REAL(DT_C, DbKi) ! Call the main subroutine InflowWind_Init - only need InitInp and TimeInterval as inputs, the rest are set by InflowWind_Init @@ -174,6 +230,30 @@ logical function Failed() end function Failed subroutine Cleanup() ! NOTE: we are ignoring any error reporting from here end subroutine Cleanup + + !> This subroutine prints out all the variables that are passed in. Use this only + !! for debugging the interface on the Fortran side. + subroutine ShowPassedData() + character(1) :: TmpFlag + integer :: i,j + call WrSCr("") + call WrScr("-----------------------------------------------------------") + call WrScr("Interface debugging: Variables passed in through interface") + call WrScr(" ADI_C_Init") + call WrScr(" --------------------------------------------------------") + call WrScr(" FileInfo") + TmpFlag="F"; if (IfWinputFilePassed==1_c_int) TmpFlag="T" + call WrScr(" IfWinputFilePassed_C "//TmpFlag ) + call WrScr(" IfWinputFileString_C (ptr addr)"//trim(Num2LStr(LOC(IfWinputFileString_C))) ) + call WrScr(" IfWinputFileStringLength_C "//trim(Num2LStr( IfWinputFileStringLength_C )) ) + call WrScr(" OutRootName "//trim(OutRootName) ) + call WrScr(" Input variables") + call WrScr(" NumWindPts_C "//trim(Num2LStr( NumWindPts_C)) ) + call WrScr(" Time variables") + call WrScr(" DT_C "//trim(Num2LStr( DT_C )) ) + call WrScr("-----------------------------------------------------------") + end subroutine ShowPassedData + END SUBROUTINE IfW_C_Init !=============================================================================================================== diff --git a/reg_tests/executeInflowwindPyRegressionCase.py b/reg_tests/executeInflowwindPyRegressionCase.py index 0f5bdca26..6990257a4 100644 --- a/reg_tests/executeInflowwindPyRegressionCase.py +++ b/reg_tests/executeInflowwindPyRegressionCase.py @@ -101,7 +101,7 @@ ### Run inflowwind on the test case if not noExec: - caseInputFile = os.path.join(testBuildDirectory, "inflowWind_testDriver.py") + caseInputFile = os.path.join(testBuildDirectory, "py_ifw_driver.py") returnCode = openfastDrivers.runInflowwindDriverCase(caseInputFile, executable) if returnCode != 0: sys.exit(returnCode*10) diff --git a/reg_tests/r-test b/reg_tests/r-test index d641aeb7d..28cdf7ba6 160000 --- a/reg_tests/r-test +++ b/reg_tests/r-test @@ -1 +1 @@ -Subproject commit d641aeb7df530a0249b0679ac5de6829069c58c4 +Subproject commit 28cdf7ba6fcf36b6a97d17ad42b372a33281cdb6 From 24e2e500617110adf2a2fd69b547829240ef2073 Mon Sep 17 00:00:00 2001 From: andrew-platt Date: Sun, 22 Dec 2024 22:35:04 -0700 Subject: [PATCH 132/161] IfW_uniform: remove file passing option --- modules/inflowwind/src/InflowWind.f90 | 2 - modules/inflowwind/src/InflowWind.txt | 2 - modules/inflowwind/src/InflowWind_IO.f90 | 8 +-- modules/inflowwind/src/InflowWind_IO.txt | 1 - .../inflowwind/src/InflowWind_IO_Types.f90 | 12 ---- modules/inflowwind/src/InflowWind_Subs.f90 | 2 +- modules/inflowwind/src/InflowWind_Types.f90 | 12 ---- .../inflowwind/tests/test_uniform_wind.F90 | 68 +------------------ 8 files changed, 4 insertions(+), 103 deletions(-) diff --git a/modules/inflowwind/src/InflowWind.f90 b/modules/inflowwind/src/InflowWind.f90 index 14ac13d75..a8a23fe52 100644 --- a/modules/inflowwind/src/InflowWind.f90 +++ b/modules/inflowwind/src/InflowWind.f90 @@ -255,8 +255,6 @@ SUBROUTINE InflowWind_Init( InitInp, InputGuess, p, ContStates, DiscStates, Cons Uniform_InitInput%RefHt = InputFileData%Uniform_RefHt Uniform_InitInput%RefLength = InputFileData%Uniform_RefLength Uniform_InitInput%PropagationDir = InputFileData%PropagationDir - Uniform_InitInput%UseInputFile = InitInp%WindType2UseInputFile - Uniform_InitInput%PassedFileInfo = InitInp%WindType2Info p%FlowField%FieldType = Uniform_FieldType call IfW_UniformWind_Init(Uniform_InitInput, SumFileUnit, p%FlowField%Uniform, InitOutData%WindFileInfo, TmpErrStat, TmpErrMsg); if (Failed()) return diff --git a/modules/inflowwind/src/InflowWind.txt b/modules/inflowwind/src/InflowWind.txt index 3dd63deba..6f9296583 100644 --- a/modules/inflowwind/src/InflowWind.txt +++ b/modules/inflowwind/src/InflowWind.txt @@ -91,8 +91,6 @@ typedef ^ ^ CHARACTER(1024) RootName typedef ^ ^ IntKi FilePassingMethod - 0 - "Method for file passing {0: None (read from file), 1: as FileInfoType to parse, 2: as InputFileType already parsed}" - typedef ^ ^ FileInfoType PassedFileInfo - - - "If we don't use the input file, pass everything through this [FilePassingMethod = 1]" - typedef ^ ^ InflowWind_InputFile PassedFileData - - - "If we don't use the input file, pass everything through this [FilePassingMethod = 2]" - -typedef ^ ^ LOGICAL WindType2UseInputFile - .TRUE. - "Flag for toggling file based IO in wind type 2." - -typedef ^ ^ FileInfoType WindType2Info - - - "Optional slot for wind type 2 data if file IO is not used." - typedef ^ ^ LOGICAL OutputAccel - .FALSE. - "Flag to output wind acceleration" - typedef ^ ^ Lidar_InitInputType lidar - - - "InitInput for lidar data" - typedef ^ ^ Grid4D_InitInputType FDext - - - "InitInput for 4D external wind data" - diff --git a/modules/inflowwind/src/InflowWind_IO.f90 b/modules/inflowwind/src/InflowWind_IO.f90 index 4c30d9d2e..44c2e03f8 100644 --- a/modules/inflowwind/src/InflowWind_IO.f90 +++ b/modules/inflowwind/src/InflowWind_IO.f90 @@ -182,12 +182,8 @@ subroutine IfW_UniformWind_Init(InitInp, SumFileUnit, UF, FileDat, ErrStat, ErrM UF%RefHeight = InitInp%RefHt UF%RefLength = InitInp%RefLength - ! Read wind data from file or init input data - if (InitInp%UseInputFile) then - call ProcessComFile(InitInp%WindFileName, WindFileInfo, TmpErrStat, TmpErrMsg) - else - call NWTC_Library_CopyFileInfoType(InitInp%PassedFileInfo, WindFileInfo, MESH_NEWCOPY, TmpErrStat, TmpErrMsg) - end if + ! Read wind data from file + call ProcessComFile(InitInp%WindFileName, WindFileInfo, TmpErrStat, TmpErrMsg) call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) if (ErrStat >= AbortErrLev) return diff --git a/modules/inflowwind/src/InflowWind_IO.txt b/modules/inflowwind/src/InflowWind_IO.txt index 1405c9490..ca305a221 100644 --- a/modules/inflowwind/src/InflowWind_IO.txt +++ b/modules/inflowwind/src/InflowWind_IO.txt @@ -40,7 +40,6 @@ typedef ^ ^ ReKi RefHt typedef ^ ^ ReKi RefLength - - - "Reference length for linear horizontal and vertical sheer" - typedef ^ ^ ReKi PropagationDir - - - "Direction of wind propagation" radians typedef ^ ^ logical UseInputFile - .true. - "Flag for toggling file based IO in wind type 2." - -typedef ^ ^ FileInfoType PassedFileInfo - - - "Optional slot for wind type 2 data if file IO is not used." - #---------------------------------------------------------------------------------------------------------------------------------- typedef ^ Grid3D_InitInputType IntKi ScaleMethod - 0 - "Turbulence scaling method [0=none, 1=direct scaling, 2= calculate scaling factor based on a desired standard deviation]" - diff --git a/modules/inflowwind/src/InflowWind_IO_Types.f90 b/modules/inflowwind/src/InflowWind_IO_Types.f90 index c3bf300a5..7d88b26c3 100644 --- a/modules/inflowwind/src/InflowWind_IO_Types.f90 +++ b/modules/inflowwind/src/InflowWind_IO_Types.f90 @@ -70,7 +70,6 @@ MODULE InflowWind_IO_Types REAL(ReKi) :: RefLength = 0.0_ReKi !< Reference length for linear horizontal and vertical sheer [-] REAL(ReKi) :: PropagationDir = 0.0_ReKi !< Direction of wind propagation [radians] LOGICAL :: UseInputFile = .true. !< Flag for toggling file based IO in wind type 2. [-] - TYPE(FileInfoType) :: PassedFileInfo !< Optional slot for wind type 2 data if file IO is not used. [-] END TYPE Uniform_InitInputType ! ======================= ! ========= Grid3D_InitInputType ======= @@ -281,8 +280,6 @@ subroutine InflowWind_IO_CopyUniform_InitInputType(SrcUniform_InitInputTypeData, integer(IntKi), intent(in ) :: CtrlCode integer(IntKi), intent( out) :: ErrStat character(*), intent( out) :: ErrMsg - integer(IntKi) :: ErrStat2 - character(ErrMsgLen) :: ErrMsg2 character(*), parameter :: RoutineName = 'InflowWind_IO_CopyUniform_InitInputType' ErrStat = ErrID_None ErrMsg = '' @@ -291,22 +288,15 @@ subroutine InflowWind_IO_CopyUniform_InitInputType(SrcUniform_InitInputTypeData, DstUniform_InitInputTypeData%RefLength = SrcUniform_InitInputTypeData%RefLength DstUniform_InitInputTypeData%PropagationDir = SrcUniform_InitInputTypeData%PropagationDir DstUniform_InitInputTypeData%UseInputFile = SrcUniform_InitInputTypeData%UseInputFile - call NWTC_Library_CopyFileInfoType(SrcUniform_InitInputTypeData%PassedFileInfo, DstUniform_InitInputTypeData%PassedFileInfo, CtrlCode, ErrStat2, ErrMsg2) - call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - if (ErrStat >= AbortErrLev) return end subroutine subroutine InflowWind_IO_DestroyUniform_InitInputType(Uniform_InitInputTypeData, ErrStat, ErrMsg) type(Uniform_InitInputType), intent(inout) :: Uniform_InitInputTypeData integer(IntKi), intent( out) :: ErrStat character(*), intent( out) :: ErrMsg - integer(IntKi) :: ErrStat2 - character(ErrMsgLen) :: ErrMsg2 character(*), parameter :: RoutineName = 'InflowWind_IO_DestroyUniform_InitInputType' ErrStat = ErrID_None ErrMsg = '' - call NWTC_Library_DestroyFileInfoType(Uniform_InitInputTypeData%PassedFileInfo, ErrStat2, ErrMsg2) - call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) end subroutine subroutine InflowWind_IO_PackUniform_InitInputType(RF, Indata) @@ -319,7 +309,6 @@ subroutine InflowWind_IO_PackUniform_InitInputType(RF, Indata) call RegPack(RF, InData%RefLength) call RegPack(RF, InData%PropagationDir) call RegPack(RF, InData%UseInputFile) - call NWTC_Library_PackFileInfoType(RF, InData%PassedFileInfo) if (RegCheckErr(RF, RoutineName)) return end subroutine @@ -333,7 +322,6 @@ subroutine InflowWind_IO_UnPackUniform_InitInputType(RF, OutData) call RegUnpack(RF, OutData%RefLength); if (RegCheckErr(RF, RoutineName)) return call RegUnpack(RF, OutData%PropagationDir); if (RegCheckErr(RF, RoutineName)) return call RegUnpack(RF, OutData%UseInputFile); if (RegCheckErr(RF, RoutineName)) return - call NWTC_Library_UnpackFileInfoType(RF, OutData%PassedFileInfo) ! PassedFileInfo end subroutine subroutine InflowWind_IO_CopyGrid3D_InitInputType(SrcGrid3D_InitInputTypeData, DstGrid3D_InitInputTypeData, CtrlCode, ErrStat, ErrMsg) diff --git a/modules/inflowwind/src/InflowWind_Subs.f90 b/modules/inflowwind/src/InflowWind_Subs.f90 index 72421f99c..e583535f8 100644 --- a/modules/inflowwind/src/InflowWind_Subs.f90 +++ b/modules/inflowwind/src/InflowWind_Subs.f90 @@ -699,7 +699,7 @@ SUBROUTINE InflowWind_ValidateInput( InitInp, InputFileData, ErrStat, ErrMsg ) CALL Steady_ValidateInput() CASE ( Uniform_WindNumber ) - IF ( InitInp%WindType2UseInputFile ) CALL Uniform_ValidateInput() + CALL Uniform_ValidateInput() CASE ( TSFF_WindNumber ) CALL TSFF_ValidateInput() diff --git a/modules/inflowwind/src/InflowWind_Types.f90 b/modules/inflowwind/src/InflowWind_Types.f90 index 529267f23..d73ce28f2 100644 --- a/modules/inflowwind/src/InflowWind_Types.f90 +++ b/modules/inflowwind/src/InflowWind_Types.f90 @@ -110,8 +110,6 @@ MODULE InflowWind_Types INTEGER(IntKi) :: FilePassingMethod = 0 !< Method for file passing {0: None (read from file), 1: as FileInfoType to parse, 2: as InputFileType already parsed} [-] TYPE(FileInfoType) :: PassedFileInfo !< If we don't use the input file, pass everything through this [FilePassingMethod = 1] [-] TYPE(InflowWind_InputFile) :: PassedFileData !< If we don't use the input file, pass everything through this [FilePassingMethod = 2] [-] - LOGICAL :: WindType2UseInputFile = .TRUE. !< Flag for toggling file based IO in wind type 2. [-] - TYPE(FileInfoType) :: WindType2Info !< Optional slot for wind type 2 data if file IO is not used. [-] LOGICAL :: OutputAccel = .FALSE. !< Flag to output wind acceleration [-] TYPE(Lidar_InitInputType) :: lidar !< InitInput for lidar data [-] TYPE(Grid4D_InitInputType) :: FDext !< InitInput for 4D external wind data [-] @@ -511,10 +509,6 @@ subroutine InflowWind_CopyInitInput(SrcInitInputData, DstInitInputData, CtrlCode call InflowWind_CopyInputFile(SrcInitInputData%PassedFileData, DstInitInputData%PassedFileData, CtrlCode, ErrStat2, ErrMsg2) call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) if (ErrStat >= AbortErrLev) return - DstInitInputData%WindType2UseInputFile = SrcInitInputData%WindType2UseInputFile - call NWTC_Library_CopyFileInfoType(SrcInitInputData%WindType2Info, DstInitInputData%WindType2Info, CtrlCode, ErrStat2, ErrMsg2) - call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - if (ErrStat >= AbortErrLev) return DstInitInputData%OutputAccel = SrcInitInputData%OutputAccel call Lidar_CopyInitInput(SrcInitInputData%lidar, DstInitInputData%lidar, CtrlCode, ErrStat2, ErrMsg2) call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) @@ -542,8 +536,6 @@ subroutine InflowWind_DestroyInitInput(InitInputData, ErrStat, ErrMsg) call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) call InflowWind_DestroyInputFile(InitInputData%PassedFileData, ErrStat2, ErrMsg2) call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - call NWTC_Library_DestroyFileInfoType(InitInputData%WindType2Info, ErrStat2, ErrMsg2) - call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) call Lidar_DestroyInitInput(InitInputData%lidar, ErrStat2, ErrMsg2) call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) call InflowWind_IO_DestroyGrid4D_InitInputType(InitInputData%FDext, ErrStat2, ErrMsg2) @@ -565,8 +557,6 @@ subroutine InflowWind_PackInitInput(RF, Indata) call RegPack(RF, InData%FilePassingMethod) call NWTC_Library_PackFileInfoType(RF, InData%PassedFileInfo) call InflowWind_PackInputFile(RF, InData%PassedFileData) - call RegPack(RF, InData%WindType2UseInputFile) - call NWTC_Library_PackFileInfoType(RF, InData%WindType2Info) call RegPack(RF, InData%OutputAccel) call Lidar_PackInitInput(RF, InData%lidar) call InflowWind_IO_PackGrid4D_InitInputType(RF, InData%FDext) @@ -593,8 +583,6 @@ subroutine InflowWind_UnPackInitInput(RF, OutData) call RegUnpack(RF, OutData%FilePassingMethod); if (RegCheckErr(RF, RoutineName)) return call NWTC_Library_UnpackFileInfoType(RF, OutData%PassedFileInfo) ! PassedFileInfo call InflowWind_UnpackInputFile(RF, OutData%PassedFileData) ! PassedFileData - call RegUnpack(RF, OutData%WindType2UseInputFile); if (RegCheckErr(RF, RoutineName)) return - call NWTC_Library_UnpackFileInfoType(RF, OutData%WindType2Info) ! WindType2Info call RegUnpack(RF, OutData%OutputAccel); if (RegCheckErr(RF, RoutineName)) return call Lidar_UnpackInitInput(RF, OutData%lidar) ! lidar call InflowWind_IO_UnpackGrid4D_InitInputType(RF, OutData%FDext) ! FDext diff --git a/modules/inflowwind/tests/test_uniform_wind.F90 b/modules/inflowwind/tests/test_uniform_wind.F90 index 914ea60b8..4294396b0 100644 --- a/modules/inflowwind/tests/test_uniform_wind.F90 +++ b/modules/inflowwind/tests/test_uniform_wind.F90 @@ -16,8 +16,7 @@ module test_uniform_wind subroutine test_uniform_wind_suite(testsuite) type(unittest_type), allocatable, intent(out) :: testsuite(:) testsuite = [ & - new_unittest("test_uniform_wind_input", test_uniform_wind_input), & - new_unittest("test_uniform_wind_direct_data", test_uniform_wind_direct_data) & + new_unittest("test_uniform_wind_input", test_uniform_wind_input) & ] end subroutine @@ -44,70 +43,5 @@ subroutine test_uniform_wind_input(error) end subroutine -subroutine test_uniform_wind_direct_data(error) - type(error_type), allocatable, intent(out) :: error - - ! Types for setting up module - type(InflowWind_InitInputType) :: InitInp !< Input data for initialization - type(InflowWind_InputType) :: InputGuess !< An initial guess for the input; the input mesh must be defined - type(InflowWind_ParameterType) :: p !< Parameters - type(InflowWind_ContinuousStateType) :: ContStates !< Initial continuous states - type(InflowWind_DiscreteStateType) :: DiscStates !< Initial discrete states - type(InflowWind_ConstraintStateType) :: ConstrStateGuess !< Initial guess of the constraint states - type(InflowWind_OtherStateType) :: OtherStates !< Initial other/optimization states - type(InflowWind_OutputType) :: y !< Initial output (outputs are not calculated; only the output mesh is initialized) - type(InflowWind_MiscVarType) :: m !< Misc variables for optimization (not copied in glue code) - real(DbKi) :: TimeInterval !< Coupling time interval in seconds: InflowWind does not change this. - type(InflowWind_InitOutputType) :: InitOutData - - ! Variables for testing - integer :: ErrStat - character(ErrMsgLen) :: ErrMsg - type(FileInfoType) :: InFileInfo - type(FileInfoType) :: WindType2Info - character(1024), dimension(6) :: data = [ & - '! Wind file for sheared 18 m/s wind with 30 degree direction. ', & - '! Time Wind Wind Vert. Horiz. Vert. LinV Gust ', & - '! Speed Dir Speed Shear Shear Shear Speed ', & - ' 0.0 12.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ', & - ' 0.1 12.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ', & - ' 999.9 12.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ' & - ] - - ! Error handling - integer(IntKi) :: TmpErrStat - character(ErrMsgLen) :: TmpErrMsg !< temporary error message - - InFileInfo = getInputFileDataWindType2() - call InitFileInfo(data, WindType2Info, ErrStat, ErrMsg) - - ! For diagnostic purposes, the following can be used to display the contents - ! of the InFileInfo data structure. - ! call Print_FileInfo_Struct( CU, InFileInfo ) ! CU is the screen -- different number on different systems. - - ! Variable definitions - InitInp%InputFileName = "" - InitInp%NumWindPoints = 5 - InitInp%FilePassingMethod = 1_IntKi - InitInp%RootName = "" - InitInp%PassedFileInfo = InFileInfo - InitInp%WindType2UseInputFile = .false. - InitInp%WindType2Info = WindType2Info - - call InflowWind_Init(InitInp, InputGuess, p, ContStates, DiscStates, & - ConstrStateGuess, OtherStates, y, m, TimeInterval, & - InitOutData, TmpErrStat, TmpErrMsg) - - ! Results - call check(error, TmpErrStat, ErrID_None, message='Error message: '//trim(TmpErrMsg)//NewLine//'ErrStat: '); if (allocated(error)) return - call check(error, p%FlowField%Uniform%Time(1), 0.0_ReKi); if (allocated(error)) return - call check(error, p%FlowField%Uniform%Time(2), 0.1_ReKi); if (allocated(error)) return - call check(error, p%FlowField%Uniform%Time(3), 999.9_ReKi); if (allocated(error)) return - - call check(error, p%FlowField%Uniform%VelH(1), 12.0_ReKi); if (allocated(error)) return - call check(error, p%FlowField%Uniform%VelH(2), 12.0_ReKi); if (allocated(error)) return - call check(error, p%FlowField%Uniform%VelH(3), 12.0_ReKi); if (allocated(error)) return - -end subroutine end module From af7898ce7444c7a9e573e4324d99c39f98cc3f43 Mon Sep 17 00:00:00 2001 From: andrew-platt Date: Mon, 23 Dec 2024 00:10:59 -0700 Subject: [PATCH 133/161] FF: add visualization of shared mooring lines --- docs/source/user/api_change.rst | 25 ++++++------ docs/source/user/fast.farm/InputFiles.rst | 4 ++ glue-codes/fast-farm/src/FAST_Farm_IO.f90 | 1 + .../fast-farm/src/FAST_Farm_Registry.txt | 4 ++ glue-codes/fast-farm/src/FAST_Farm_Subs.f90 | 38 ++++++++++++++++++- glue-codes/fast-farm/src/FAST_Farm_Types.f90 | 16 ++++++++ reg_tests/CTestList.cmake | 13 ++++--- reg_tests/r-test | 2 +- 8 files changed, 82 insertions(+), 21 deletions(-) diff --git a/docs/source/user/api_change.rst b/docs/source/user/api_change.rst index 30d3a351f..90ff8d2aa 100644 --- a/docs/source/user/api_change.rst +++ b/docs/source/user/api_change.rst @@ -38,18 +38,19 @@ SubDyn 56\* SubDyn 57\* NSpringPropSets 0 - Number of spring properties SubDyn 58\* PropSetID k11 k12 k13 k14 k15 k16 k22 k23 k24 k25 k26 k33 k34 k35 k36 k44 k45 k46 k55 k56 k66 SubDyn 59\* (-) (N/m) (N/m) (N/m) (N/rad) (N/rad) (N/rad) (N/m) (N/m) (N/rad) (N/rad) (N/rad) (N/m) (N/rad) (N/rad) (N/rad) (Nm/rad) (Nm/rad) (Nm/rad) (Nm/rad) (Nm/rad) (Nm/rad) -FAST.Farm 47 RotorDiamRef 125 RotorDiamRef - Reference turbine rotor diameter for wake calculations (m) [>0.0] -FAST.Farm 57 k_vAmb DEFAULT k_vAmb - Calibrated parameters for the influence of the ambient turbulence in the eddy viscosity (set of 5 parameters: k, FMin, DMin, DMax, Exp) (-) [>=0.0, >=0.0 and <=1.0, >=0.0, >DMin, >0.0] or DEFAULT [DEFAULT=0.05, 1.0, 0.0, 1.0, 0.01] -FAST.Farm 58 kvShr DEFAULT k_vShr - Calibrated parameters for the influence of the shear layer in the eddy viscosity (set of 5 parameters: k, FMin, DMin, DMax, Exp) (-) [>=0.0, >=0.0 and <=1.0, >=0.0, >DMin, >0.0] or DEFAULT [DEFAULT=0.016, 0.2, 3.0, 25.0, 0.1] -FAST.Farm 59-66 --removed-- -FAST.Farm 71 --- WAKE-ADDED TURBULENCE --- -FAST.Farm 72 WAT 2 WAT - Switch between wake-added turbulence box options {0: no wake added turbulence, 1: predefined turbulence box, 2: user defined turbulence box} (switch) -FAST.Farm 73 WAT_BoxFile "../WAT_MannBoxDB/FFDB_D100_512x512x64.u" WAT_BoxFile - Filepath to the file containing the u-component of the turbulence box (either predefined or user-defined) (quoted string) -FAST.Farm 74 WAT_NxNyNz 512, 512, 64 WAT_NxNyNz - Number of points in the x, y, and z directions of the WAT_BoxFile [used only if WAT=2, derived value if WAT=1] (-) -FAST.Farm 75 WAT_DxDyDz 5.0, 5.0, 5.0 WAT_DxDyDz - Distance (in meters) between points in the x, y, and z directions of the WAT_BoxFile [used only if WAT=2, derived value if WAT=1] (m) -FAST.Farm 76 WAT_ScaleBox default WAT_ScaleBox - Flag to scale the input turbulence box to zero mean and unit standard deviation at every node [DEFAULT=False] (flag) -FAST.Farm 77 WAT_k_Def default WAT_k_Def - Calibrated parameters for the influence of the maximum wake deficit on wake-added turbulence (set of 5 parameters: k_Def, FMin, DMin, DMax, Exp) (-) [>=0.0, >=0.0 and <=1.0, >=0.0, >DMin, >0.0] or DEFAULT [DEFAULT=[0.6, 0.0, 0.0, 2.0, 1.0 ]] -FAST.Farm 78 WAT_k_Grad default WAT_k_Grad - Calibrated parameters for the influence of the radial velocity gradient of the wake deficit on wake-added turbulence (set of 5 parameters: k_Grad, FMin, DMin, DMax, Exp) (-) [>=0.0, >=0.0 and <=1.0, >=0.0, >DMin, >0.0] or DEFAULT [DEFAULT=[3.0, 0.0, 0.0, 12.0, 0.65] +FAST.Farm 16 WrMooringVis true WrMooringVis - Write shared mooring visualization, at DT_Mooring timestep (-) [only used for Mod_SharedMooring=3] +FAST.Farm 48 RotorDiamRef 125 RotorDiamRef - Reference turbine rotor diameter for wake calculations (m) [>0.0] +FAST.Farm 58 k_vAmb DEFAULT k_vAmb - Calibrated parameters for the influence of the ambient turbulence in the eddy viscosity (set of 5 parameters: k, FMin, DMin, DMax, Exp) (-) [>=0.0, >=0.0 and <=1.0, >=0.0, >DMin, >0.0] or DEFAULT [DEFAULT=0.05, 1.0, 0.0, 1.0, 0.01] +FAST.Farm 59 kvShr DEFAULT k_vShr - Calibrated parameters for the influence of the shear layer in the eddy viscosity (set of 5 parameters: k, FMin, DMin, DMax, Exp) (-) [>=0.0, >=0.0 and <=1.0, >=0.0, >DMin, >0.0] or DEFAULT [DEFAULT=0.016, 0.2, 3.0, 25.0, 0.1] +FAST.Farm 60-66 --removed-- +FAST.Farm 72 --- WAKE-ADDED TURBULENCE --- +FAST.Farm 73 WAT 2 WAT - Switch between wake-added turbulence box options {0: no wake added turbulence, 1: predefined turbulence box, 2: user defined turbulence box} (switch) +FAST.Farm 74 WAT_BoxFile "../WAT_MannBoxDB/FFDB_D100_512x512x64.u" WAT_BoxFile - Filepath to the file containing the u-component of the turbulence box (either predefined or user-defined) (quoted string) +FAST.Farm 75 WAT_NxNyNz 512, 512, 64 WAT_NxNyNz - Number of points in the x, y, and z directions of the WAT_BoxFile [used only if WAT=2, derived value if WAT=1] (-) +FAST.Farm 76 WAT_DxDyDz 5.0, 5.0, 5.0 WAT_DxDyDz - Distance (in meters) between points in the x, y, and z directions of the WAT_BoxFile [used only if WAT=2, derived value if WAT=1] (m) +FAST.Farm 77 WAT_ScaleBox default WAT_ScaleBox - Flag to scale the input turbulence box to zero mean and unit standard deviation at every node [DEFAULT=False] (flag) +FAST.Farm 78 WAT_k_Def default WAT_k_Def - Calibrated parameters for the influence of the maximum wake deficit on wake-added turbulence (set of 5 parameters: k_Def, FMin, DMin, DMax, Exp) (-) [>=0.0, >=0.0 and <=1.0, >=0.0, >DMin, >0.0] or DEFAULT [DEFAULT=[0.6, 0.0, 0.0, 2.0, 1.0 ]] +FAST.Farm 79 WAT_k_Grad default WAT_k_Grad - Calibrated parameters for the influence of the radial velocity gradient of the wake deficit on wake-added turbulence (set of 5 parameters: k_Grad, FMin, DMin, DMax, Exp) (-) [>=0.0, >=0.0 and <=1.0, >=0.0, >DMin, >0.0] or DEFAULT [DEFAULT=[3.0, 0.0, 0.0, 12.0, 0.65] AeroDyn 80\* NacArea 0, 0, 0 NacArea - Projected area of the nacelle in X, Y, Z in the nacelle coordinate system (m^2) AeroDyn 81\* NacCd 0, 0, 0 NacCd - Drag coefficient for the nacelle areas defined above (-) AeroDyn 82\* NacDragAC 0, 0, 0 NacDragAC - Position of aerodynamic center of nacelle drag in nacelle coordinates (m) diff --git a/docs/source/user/fast.farm/InputFiles.rst b/docs/source/user/fast.farm/InputFiles.rst index 665c6e3b7..e8b0decb2 100644 --- a/docs/source/user/fast.farm/InputFiles.rst +++ b/docs/source/user/fast.farm/InputFiles.rst @@ -138,6 +138,10 @@ documentation for details on the input file at the farm level. **DT_Mooring** (sec) sets the timestep for the shared mooring connections with MoorDyn. +**WrMooringVis** [swithch] Write shared mooring line visualization, at +DT_Mooring timestep + + .. _FF:Input:VTK: Ambient Wind: Precursor in Visualization Toolkit Format diff --git a/glue-codes/fast-farm/src/FAST_Farm_IO.f90 b/glue-codes/fast-farm/src/FAST_Farm_IO.f90 index 8b7937b2a..7f5822cf0 100644 --- a/glue-codes/fast-farm/src/FAST_Farm_IO.f90 +++ b/glue-codes/fast-farm/src/FAST_Farm_IO.f90 @@ -643,6 +643,7 @@ SUBROUTINE Farm_ReadPrimaryFile( InputFile, p, WD_InitInp, AWAE_InitInp, SC_Init CALL ReadVar( UnIn, InputFile, p%MD_FileName, "MD_FileName", "Name/location of the dynamic library {.dll [Windows] or .so [Linux]} containing the Super Controller algorithms (quoated string)", ErrStat2, ErrMsg2, UnEc); if (Failed()) return IF ( PathIsRelative( p%MD_FileName ) ) p%MD_FileName = TRIM(PriPath)//TRIM(p%MD_FileName) CALL ReadVar( UnIn, InputFile, p%DT_mooring, "DT_Mooring", "Time step for farm-levem mooring coupling with each turbine [used only when Mod_SharedMooring > 0] (s) [>0.0]", ErrStat2, ErrMsg2, UnEc); if (Failed()) return + CALL ReadVar( UnIn, InputFile, p%WrMooringVis, "MooringVis","Write shared mooring visualization, at DT_Mooring timestep (-) [only used for Mod_SharedMooring=3]", ErrStat2, ErrMsg2, UnEc); if (Failed()) return !---------------------- AMBIENT WIND: PRECURSOR IN VTK FORMAT --------------------------------------------- CALL ReadCom( UnIn, InputFile, 'Section Header: Ambient Wind: Precursor in VTK Format', ErrStat2, ErrMsg2, UnEc ); if (Failed()) return diff --git a/glue-codes/fast-farm/src/FAST_Farm_Registry.txt b/glue-codes/fast-farm/src/FAST_Farm_Registry.txt index 02e90e21b..a05215d21 100644 --- a/glue-codes/fast-farm/src/FAST_Farm_Registry.txt +++ b/glue-codes/fast-farm/src/FAST_Farm_Registry.txt @@ -41,6 +41,7 @@ typedef ^ ParameterType LOGICAL UseSC - typedef ^ ParameterType ReKi WT_Position {:}{:} - - "X-Y-Z position of each wind turbine; index 1 = XYZ; index 2 = turbine number" meters typedef ^ ParameterType IntKi WaveFieldMod - - - "Wave field handling (-) (switch) {0: use individual HydroDyn inputs without adjustment, 1: adjust wave phases based on turbine offsets from farm origin}" - typedef ^ ParameterType IntKi MooringMod - - - "Mod_SharedMooring is a flag for array-level mooring. (switch) {0: none, 3: yes/MoorDyn}" - +typedef ^ ParameterType logical WrMooringVis - - - "Write shared mooring visualization (-) [only used for Mod_SharedMooring=3]" - typedef ^ ParameterType CHARACTER(1024) MD_FileName - - - "Name/location of the farm-level MoorDyn input file" - typedef ^ ParameterType DbKi DT_mooring - - - "Time step for farm-levem mooring coupling with each turbine [used only when Mod_SharedMooring > 0]" seconds typedef ^ ParameterType IntKi n_mooring - - - "Number of FAST and MoorDyn time steps per FAST.Farm timestep when mooring > 0" - @@ -157,6 +158,9 @@ typedef ^ ^ DbKi InputTimes {:} - typedef ^ ^ MD_OutputType y - - - "System outputs" typedef ^ ^ MD_MiscVarType m - - - "Misc/optimization variables" typedef ^ ^ logical IsInitialized - .FALSE. - "Has MD_Init been called" +typedef ^ ^ IntKi VTK_count - 0 - "Counter for VTK output of shared moorings" +typedef ^ ^ IntKi VTK_TWidth - - - "width for VTK_count field in output name" +typedef ^ ^ character(1024) VTK_OutFileRoot - - - "Rootfilename for VTK output" # ..... WAT InflowWind data ............................................................................................ typedef ^ WAT_IfW_data InflowWind_ContinuousStateType x - - - "Continuous states" typedef ^ ^ InflowWind_DiscreteStateType xd - - - "Discrete states" diff --git a/glue-codes/fast-farm/src/FAST_Farm_Subs.f90 b/glue-codes/fast-farm/src/FAST_Farm_Subs.f90 index 606742092..0a7f1a60b 100644 --- a/glue-codes/fast-farm/src/FAST_Farm_Subs.f90 +++ b/glue-codes/fast-farm/src/FAST_Farm_Subs.f90 @@ -783,6 +783,7 @@ SUBROUTINE Farm_InitMD( farm, ErrStat, ErrMsg ) type(MD_InitInputType) :: MD_InitInp type(MD_InitOutputType) :: MD_InitOut + character(1025) :: Path, FileRoot ! for vtk outputs INTEGER(IntKi) :: nt ! loop counter for rotor number INTEGER(IntKi) :: ErrStat2 ! Temporary Error status CHARACTER(ErrMsgLen) :: ErrMsg2 ! Temporary Error message @@ -844,6 +845,14 @@ SUBROUTINE Farm_InitMD( farm, ErrStat, ErrMsg ) MD_InitInp%rhoW = 1025.0 MD_InitInp%WtrDepth = 0.0 !TODO: eventually connect this to a global depth input variable <<< + ! Visualization of shared moorings + if (farm%p%WrMooringVis) then + MD_InitInp%VisMeshes=.true. + farm%MD%VTK_Count = 0 + call GetPath ( MD_InitInp%RootName, Path, FileRoot ) ! the returned DVR_Outs%VTK_OutFileRoot includes a file separator character at the end + farm%MD%VTK_OutFileRoot = trim(Path)//PathSep//'vtk'//PathSep//trim(FileRoot) + farm%MD%VTK_TWidth = 5 !FIXME: this should be set based on sim length + endif ! allocate MoorDyn inputs (assuming size 2 for linear interpolation/extrapolation... > ALLOCATE( farm%MD%Input( 2 ), farm%MD%InputTimes( 2 ), STAT = ErrStat2 ) @@ -1006,7 +1015,7 @@ subroutine FARM_MD_Increment(t, n, farm, ErrStat, ErrMsg) end if end do - + contains logical function Failed() @@ -1657,7 +1666,7 @@ subroutine FARM_CalcOutput(t, farm, ErrStat, ErrMsg) INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message - INTEGER(IntKi) :: nt + INTEGER(IntKi) :: nt,j INTEGER(IntKi) :: ErrStat2 ! Temporary Error status CHARACTER(ErrMsgLen) :: ErrMsg2 ! Temporary Error message CHARACTER(*), PARAMETER :: RoutineName = 'FARM_CalcOutput' @@ -1755,6 +1764,31 @@ subroutine FARM_CalcOutput(t, farm, ErrStat, ErrMsg) call Farm_WriteOutput(n, t, farm, ErrStat2, ErrMsg2) call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + !....................................................................................... + ! Write shared moorings visualization + !....................................................................................... + + ! Write visualization meshes + if (farm%p%MooringMod == 3) then + if (farm%MD%p%VisMeshes) then + if (allocated(farm%MD%y%VisLinesMesh)) then + do j=1,size(farm%MD%y%VisLinesMesh) + if (farm%MD%y%VisLinesMesh(j)%Committed) then + call MeshWrVTK((/0.0_SiKi,0.0_SiKi,0.0_SiKi/), farm%MD%y%VisLinesMesh(j), trim(farm%MD%VTK_OutFileRoot)//'.MD_Line'//trim(Num2LStr(j)), farm%MD%VTK_count, .false., ErrSTat2, ErrMsg2, farm%MD%VTK_tWidth ) + endif + enddo + endif + if (allocated(farm%MD%y%VisRodsMesh)) then + do j=1,size(farm%MD%y%VisRodsMesh) + if (farm%MD%y%VisRodsMesh(j)%Committed) then + call MeshWrVTK((/0.0_SiKi,0.0_SiKi,0.0_SiKi/), farm%MD%y%VisRodsMesh(j), trim(farm%MD%VTK_OutFileRoot)//'.MD_Rod'//trim(Num2LStr(j)), farm%MD%VTK_count, .false., ErrSTat2, ErrMsg2, farm%MD%VTK_tWidth ) + endif + enddo + endif + farm%MD%VTK_Count = farm%MD%VTK_Count + 1 + endif + endif + ! write(*,*) 'Total Farm_CO-serial took '//trim(num2lstr(omp_get_wtime()-tm1))//' seconds.' end subroutine FARM_CalcOutput diff --git a/glue-codes/fast-farm/src/FAST_Farm_Types.f90 b/glue-codes/fast-farm/src/FAST_Farm_Types.f90 index a03b686f1..f2a0fce0e 100644 --- a/glue-codes/fast-farm/src/FAST_Farm_Types.f90 +++ b/glue-codes/fast-farm/src/FAST_Farm_Types.f90 @@ -60,6 +60,7 @@ MODULE FAST_Farm_Types REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: WT_Position !< X-Y-Z position of each wind turbine; index 1 = XYZ; index 2 = turbine number [meters] INTEGER(IntKi) :: WaveFieldMod = 0_IntKi !< Wave field handling (-) (switch) {0: use individual HydroDyn inputs without adjustment, 1: adjust wave phases based on turbine offsets from farm origin} [-] INTEGER(IntKi) :: MooringMod = 0_IntKi !< Mod_SharedMooring is a flag for array-level mooring. (switch) {0: none, 3: yes/MoorDyn} [-] + LOGICAL :: WrMooringVis = .false. !< Write shared mooring visualization (-) [only used for Mod_SharedMooring=3] [-] CHARACTER(1024) :: MD_FileName !< Name/location of the farm-level MoorDyn input file [-] REAL(DbKi) :: DT_mooring = 0.0_R8Ki !< Time step for farm-levem mooring coupling with each turbine [used only when Mod_SharedMooring > 0] [seconds] INTEGER(IntKi) :: n_mooring = 0_IntKi !< Number of FAST and MoorDyn time steps per FAST.Farm timestep when mooring > 0 [-] @@ -185,6 +186,9 @@ MODULE FAST_Farm_Types TYPE(MD_OutputType) :: y !< System outputs [-] TYPE(MD_MiscVarType) :: m !< Misc/optimization variables [-] LOGICAL :: IsInitialized = .FALSE. !< Has MD_Init been called [-] + INTEGER(IntKi) :: VTK_count = 0 !< Counter for VTK output of shared moorings [-] + INTEGER(IntKi) :: VTK_TWidth = 0_IntKi !< width for VTK_count field in output name [-] + character(1024) :: VTK_OutFileRoot !< Rootfilename for VTK output [-] END TYPE MD_Data ! ======================= ! ========= WAT_IfW_data ======= @@ -249,6 +253,7 @@ subroutine Farm_CopyParam(SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMsg) end if DstParamData%WaveFieldMod = SrcParamData%WaveFieldMod DstParamData%MooringMod = SrcParamData%MooringMod + DstParamData%WrMooringVis = SrcParamData%WrMooringVis DstParamData%MD_FileName = SrcParamData%MD_FileName DstParamData%DT_mooring = SrcParamData%DT_mooring DstParamData%n_mooring = SrcParamData%n_mooring @@ -452,6 +457,7 @@ subroutine Farm_PackParam(RF, Indata) call RegPackAlloc(RF, InData%WT_Position) call RegPack(RF, InData%WaveFieldMod) call RegPack(RF, InData%MooringMod) + call RegPack(RF, InData%WrMooringVis) call RegPack(RF, InData%MD_FileName) call RegPack(RF, InData%DT_mooring) call RegPack(RF, InData%n_mooring) @@ -534,6 +540,7 @@ subroutine Farm_UnPackParam(RF, OutData) call RegUnpackAlloc(RF, OutData%WT_Position); if (RegCheckErr(RF, RoutineName)) return call RegUnpack(RF, OutData%WaveFieldMod); if (RegCheckErr(RF, RoutineName)) return call RegUnpack(RF, OutData%MooringMod); if (RegCheckErr(RF, RoutineName)) return + call RegUnpack(RF, OutData%WrMooringVis); if (RegCheckErr(RF, RoutineName)) return call RegUnpack(RF, OutData%MD_FileName); if (RegCheckErr(RF, RoutineName)) return call RegUnpack(RF, OutData%DT_mooring); if (RegCheckErr(RF, RoutineName)) return call RegUnpack(RF, OutData%n_mooring); if (RegCheckErr(RF, RoutineName)) return @@ -1257,6 +1264,9 @@ subroutine Farm_CopyMD_Data(SrcMD_DataData, DstMD_DataData, CtrlCode, ErrStat, E call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) if (ErrStat >= AbortErrLev) return DstMD_DataData%IsInitialized = SrcMD_DataData%IsInitialized + DstMD_DataData%VTK_count = SrcMD_DataData%VTK_count + DstMD_DataData%VTK_TWidth = SrcMD_DataData%VTK_TWidth + DstMD_DataData%VTK_OutFileRoot = SrcMD_DataData%VTK_OutFileRoot end subroutine subroutine Farm_DestroyMD_Data(MD_DataData, ErrStat, ErrMsg) @@ -1326,6 +1336,9 @@ subroutine Farm_PackMD_Data(RF, Indata) call MD_PackOutput(RF, InData%y) call MD_PackMisc(RF, InData%m) call RegPack(RF, InData%IsInitialized) + call RegPack(RF, InData%VTK_count) + call RegPack(RF, InData%VTK_TWidth) + call RegPack(RF, InData%VTK_OutFileRoot) if (RegCheckErr(RF, RoutineName)) return end subroutine @@ -1361,6 +1374,9 @@ subroutine Farm_UnPackMD_Data(RF, OutData) call MD_UnpackOutput(RF, OutData%y) ! y call MD_UnpackMisc(RF, OutData%m) ! m call RegUnpack(RF, OutData%IsInitialized); if (RegCheckErr(RF, RoutineName)) return + call RegUnpack(RF, OutData%VTK_count); if (RegCheckErr(RF, RoutineName)) return + call RegUnpack(RF, OutData%VTK_TWidth); if (RegCheckErr(RF, RoutineName)) return + call RegUnpack(RF, OutData%VTK_OutFileRoot); if (RegCheckErr(RF, RoutineName)) return end subroutine subroutine Farm_CopyWAT_IfW_data(SrcWAT_IfW_dataData, DstWAT_IfW_dataData, CtrlCode, ErrStat, ErrMsg) diff --git a/reg_tests/CTestList.cmake b/reg_tests/CTestList.cmake index 8d48adcc3..19ad3797a 100644 --- a/reg_tests/CTestList.cmake +++ b/reg_tests/CTestList.cmake @@ -386,12 +386,13 @@ of_regression_linear("5MW_OC3Mnpl_Linear" "" "openfas # FAST Farm regression tests if(BUILD_FASTFARM) - ff_regression("TSinflow" "fastfarm") - ff_regression("LESinflow" "fastfarm") -# ff_regression("Uninflow_curl" "fastfarm") - ff_regression("TSinflow_curl" "fastfarm") - ff_regression("ModAmb_3" "fastfarm") - ff_regression("TSinflowADskSED" "fastfarm;aerodisk;simple-elastodyn") + ff_regression("TSinflow" "fastfarm") + ff_regression("LESinflow" "fastfarm") +# ff_regression("Uninflow_curl" "fastfarm") + ff_regression("TSinflow_curl" "fastfarm") + ff_regression("ModAmb_3" "fastfarm") + ff_regression("TSinflowADskSED" "fastfarm;aerodisk;simple-elastodyn") + ff_regression("MD_Shared" "fastfarm;moordyn") endif() # AeroDyn regression tests diff --git a/reg_tests/r-test b/reg_tests/r-test index d641aeb7d..b69e2fe2f 160000 --- a/reg_tests/r-test +++ b/reg_tests/r-test @@ -1 +1 @@ -Subproject commit d641aeb7df530a0249b0679ac5de6829069c58c4 +Subproject commit b69e2fe2f1deffdbd8c56e6064d5322a29335ec4 From d0bab792b5d1281204b79e522d238729a588c940 Mon Sep 17 00:00:00 2001 From: andrew-platt Date: Mon, 23 Dec 2024 01:09:43 -0700 Subject: [PATCH 134/161] FF: update MD_Shared output files, update WrMooringVis description --- reg_tests/r-test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reg_tests/r-test b/reg_tests/r-test index b69e2fe2f..aabbd8935 160000 --- a/reg_tests/r-test +++ b/reg_tests/r-test @@ -1 +1 @@ -Subproject commit b69e2fe2f1deffdbd8c56e6064d5322a29335ec4 +Subproject commit aabbd893534c434e48a4421258b97455bbd5183a From 57c559902467d8a0a671155bb8fc8663cada62ae Mon Sep 17 00:00:00 2001 From: andrew-platt Date: Mon, 23 Dec 2024 09:46:48 -0700 Subject: [PATCH 135/161] Update pointer to r-test dev --- reg_tests/r-test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reg_tests/r-test b/reg_tests/r-test index b586d4ca9..abf2b8fbb 160000 --- a/reg_tests/r-test +++ b/reg_tests/r-test @@ -1 +1 @@ -Subproject commit b586d4ca9638e05770d8f7b91a5aaa085ca500ee +Subproject commit abf2b8fbb90efab593b4fd3547bfd356b1c22677 From d4bb80de68a6460e566f51c32198b7e8a7a13e38 Mon Sep 17 00:00:00 2001 From: Mayank Chetan Date: Mon, 23 Dec 2024 17:26:27 +0000 Subject: [PATCH 136/161] updating yaw friction model --- openfast_io/openfast_io/FAST_reader.py | 14 ++++++++++---- openfast_io/openfast_io/FAST_writer.py | 14 ++++++++++---- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/openfast_io/openfast_io/FAST_reader.py b/openfast_io/openfast_io/FAST_reader.py index 2e05752ea..cf3742683 100644 --- a/openfast_io/openfast_io/FAST_reader.py +++ b/openfast_io/openfast_io/FAST_reader.py @@ -497,10 +497,16 @@ def read_ElastoDyn(self, ed_file): # 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]) + 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_FCSmax'] = float_read(f.readline().split()[0]) + self.fst_vt['ElastoDyn']['M_MCSmax'] = float_read(f.readline().split()[0]) + self.fst_vt['ElastoDyn']['M_CD'] = float_read(f.readline().split()[0]) + self.fst_vt['ElastoDyn']['M_FCD'] = float_read(f.readline().split()[0]) + self.fst_vt['ElastoDyn']['M_MCD'] = float_read(f.readline().split()[0]) + self.fst_vt['ElastoDyn']['sig_v'] = float_read(f.readline().split()[0]) + self.fst_vt['ElastoDyn']['sig_v2'] = float_read(f.readline().split()[0]) + self.fst_vt['ElastoDyn']['OmgCut'] = float_read(f.readline().split()[0]) # Drivetrain (drivetrain) f.readline() diff --git a/openfast_io/openfast_io/FAST_writer.py b/openfast_io/openfast_io/FAST_writer.py index 865e62706..582dddfec 100644 --- a/openfast_io/openfast_io/FAST_writer.py +++ b/openfast_io/openfast_io/FAST_writer.py @@ -431,10 +431,16 @@ def write_ElastoDyn(self): f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDyn']['TeetSSSp'], 'TeetSSSp', '- Rotor-teeter soft-stop linear-spring constant (N-m/rad) [used only for 2 blades and when TeetMod=1]\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDyn']['TeetHSSp'], 'TeetHSSp', '- Rotor-teeter hard-stop linear-spring constant (N-m/rad) [used only for 2 blades and when TeetMod=1]\n')) f.write('---------------------- YAW-FRICTION --------------------------------------------\n') - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDyn']['YawFrctMod'], 'YawFrctMod', '- Yaw-friction model {0: none, 1: friction without Fz term at the yaw bearing, 2: friction includes Fz term at yaw bearing, 3: user defined model} (switch)\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDyn']['M_CSmax'], 'M_CSmax', '- Maximum Coulomb friction torque (N-m)[mu_s*D_eff when YawFrctMod=1 and Fz*mu_s*D_eff when YawFrctMod=2]\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDyn']['M_CD'], 'M_CD', '- Dynamic friction moment at null yaw rate (N-m) [mu_d*D_eff when YawFrctMod=1 and Fz*mu_d*D_eff when YawFrctMod=2]\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDyn']['sig_v'], 'sig_v', '- Viscous friction coefficient (N-m/(rad/s))\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDyn']['YawFrctMod'], 'YawFrctMod', '- Yaw-friction model {0: none, 1: friction independent of yaw-bearing force and bending moment, 2: friction with Coulomb terms depending on yaw-bearing force and bending moment, 3: user defined model} (switch)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDyn']['M_CSmax'], 'M_CSmax', '- Maximum static Coulomb friction torque (N-m) [M_CSmax when YawFrctMod=1; |Fz|*M_CSmax when YawFrctMod=2 and Fz<0]\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDyn']['M_FCSmax'], 'M_FCSmax', '- Maximum static Coulomb friction torque proportional to yaw bearing shear force (N-m) [sqrt(Fx^2+Fy^2)*M_FCSmax; only used when YawFrctMod=2]\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDyn']['M_MCSmax'], 'M_MCSmax', '- Maximum static Coulomb friction torque proportional to yaw bearing bending moment (N-m) [sqrt(Mx^2+My^2)*M_MCSmax; only used when YawFrctMod=2]\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDyn']['M_CD'], 'M_CD', '- Dynamic Coulomb friction moment (N-m) [M_CD when YawFrctMod=1; |Fz|*M_CD when YawFrctMod=2 and Fz<0]\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDyn']['M_FCD'], 'M_FCD', '- Dynamic Coulomb friction moment proportional to yaw bearing shear force (N-m) [sqrt(Fx^2+Fy^2)*M_FCD; only used when YawFrctMod=2]\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDyn']['M_MCD'], 'M_MCD', '- Dynamic Coulomb friction moment proportional to yaw bearing bending moment (N-m) [sqrt(Mx^2+My^2)*M_MCD; only used when YawFrctMod=2]\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDyn']['sig_v'], 'sig_v', '- Linear viscous friction coefficient (N-m/(rad/s))\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDyn']['sig_v2'], 'sig_v2', '- Quadratic viscous friction coefficient (N-m/(rad/s)^2)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDyn']['OmgCut'], 'OmgCut', '- Yaw angular velocity cutoff below which viscous friction is linearized (rad/s)\n')) f.write('---------------------- DRIVETRAIN ----------------------------------------------\n') f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDyn']['GBoxEff'], 'GBoxEff', '- Gearbox efficiency (%)\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDyn']['GBRatio'], 'GBRatio', '- Gearbox ratio (-)\n')) From 6f0c48a3ec5522f26f497a6549e282a683fe84e1 Mon Sep 17 00:00:00 2001 From: andrew-platt Date: Mon, 23 Dec 2024 11:31:38 -0700 Subject: [PATCH 137/161] FF testing: add optional argument for file to test against --- docs/source/user/fast.farm/InputFiles.rst | 2 +- reg_tests/CTestList.cmake | 19 ++++++++++--------- reg_tests/executeFASTFarmRegressionCase.py | 12 ++++++++++-- 3 files changed, 21 insertions(+), 12 deletions(-) diff --git a/docs/source/user/fast.farm/InputFiles.rst b/docs/source/user/fast.farm/InputFiles.rst index e8b0decb2..7acb740a6 100644 --- a/docs/source/user/fast.farm/InputFiles.rst +++ b/docs/source/user/fast.farm/InputFiles.rst @@ -139,7 +139,7 @@ documentation for details on the input file at the farm level. MoorDyn. **WrMooringVis** [swithch] Write shared mooring line visualization, at -DT_Mooring timestep +the globale FAST.Farm time step .. _FF:Input:VTK: diff --git a/reg_tests/CTestList.cmake b/reg_tests/CTestList.cmake index 19ad3797a..84250f7af 100644 --- a/reg_tests/CTestList.cmake +++ b/reg_tests/CTestList.cmake @@ -121,12 +121,13 @@ function(of_regression_aeroacoustic TESTNAME LABEL) endfunction(of_regression_aeroacoustic) # FAST Farm -function(ff_regression TESTNAME LABEL) +function(ff_regression TESTNAME OTHER_FLAGS LABEL) set(TEST_SCRIPT "${CMAKE_CURRENT_LIST_DIR}/executeFASTFarmRegressionCase.py") set(FASTFARM_EXECUTABLE "${CTEST_FASTFARM_EXECUTABLE}") set(SOURCE_DIRECTORY "${CMAKE_CURRENT_LIST_DIR}/..") set(BUILD_DIRECTORY "${CTEST_BINARY_DIR}/glue-codes/fast-farm") - regression(${TEST_SCRIPT} ${FASTFARM_EXECUTABLE} ${SOURCE_DIRECTORY} ${BUILD_DIRECTORY} " " ${TESTNAME} "${LABEL}" " ") + set(OTHER_FLAGS "${OTHER_FLAGS}") # Set name of file to compare, otherwise default + regression(${TEST_SCRIPT} ${FASTFARM_EXECUTABLE} ${SOURCE_DIRECTORY} ${BUILD_DIRECTORY} " " ${TESTNAME} "${LABEL}" "${OTHER_FLAGS}") endfunction(ff_regression) # openfast linearized @@ -386,13 +387,13 @@ of_regression_linear("5MW_OC3Mnpl_Linear" "" "openfas # FAST Farm regression tests if(BUILD_FASTFARM) - ff_regression("TSinflow" "fastfarm") - ff_regression("LESinflow" "fastfarm") -# ff_regression("Uninflow_curl" "fastfarm") - ff_regression("TSinflow_curl" "fastfarm") - ff_regression("ModAmb_3" "fastfarm") - ff_regression("TSinflowADskSED" "fastfarm;aerodisk;simple-elastodyn") - ff_regression("MD_Shared" "fastfarm;moordyn") + ff_regression("TSinflow" "" "fastfarm") + ff_regression("LESinflow" "" "fastfarm") +# ff_regression("Uninflow_curl" "" "fastfarm") + ff_regression("TSinflow_curl" "" "fastfarm") + ff_regression("ModAmb_3" "" "fastfarm") + ff_regression("TSinflowADskSED" "" "fastfarm;aerodisk;simple-elastodyn") + ff_regression("MD_Shared" "-compFile=FAST.Farm.FarmMD.MD" "fastfarm;moordyn") endif() # AeroDyn regression tests diff --git a/reg_tests/executeFASTFarmRegressionCase.py b/reg_tests/executeFASTFarmRegressionCase.py index c218b76ef..44f3a19d3 100644 --- a/reg_tests/executeFASTFarmRegressionCase.py +++ b/reg_tests/executeFASTFarmRegressionCase.py @@ -54,6 +54,7 @@ parser.add_argument("-p", "-plot", dest="plot", action='store_true', help="bool to include plots in failed cases") parser.add_argument("-n", "-no-exec", dest="noExec", action='store_true', help="bool to prevent execution of the test cases") parser.add_argument("-v", "-verbose", dest="verbose", action='store_true', help="bool to include verbose system output") +parser.add_argument("-compFile", dest="compFile", metavar="comparison-file", type=str, nargs='?', const='arg_was_not_given', help="File to use for comparison (no extension)") args = parser.parse_args() @@ -66,6 +67,13 @@ plotError = args.plot noExec = args.noExec verbose = args.verbose +# file to use for comparison (ending not included) +if args.compFile is None: + compFile = caseName +elif args.compFile == 'arg_was_not_given': + compFile = caseName +else: + compFile = args.compFile # validate inputs rtl.validateExeOrExit(executable) @@ -129,8 +137,8 @@ sys.exit(returnCode*10) ### Build the filesystem navigation variables for running the regression test -localOutFile = os.path.join(testBuildDirectory, caseName + ".out") -baselineOutFile = os.path.join(targetOutputDirectory, caseName + ".out") +localOutFile = os.path.join(testBuildDirectory, compFile + ".out") +baselineOutFile = os.path.join(targetOutputDirectory, compFile + ".out") rtl.validateFileOrExit(localOutFile) rtl.validateFileOrExit(baselineOutFile) From eaac34606533b8f626e6429467196bca4b4b4736 Mon Sep 17 00:00:00 2001 From: andrew-platt Date: Mon, 23 Dec 2024 11:35:18 -0700 Subject: [PATCH 138/161] FF docs: fix typo --- docs/source/user/fast.farm/InputFiles.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/user/fast.farm/InputFiles.rst b/docs/source/user/fast.farm/InputFiles.rst index 7acb740a6..9ecce9ce0 100644 --- a/docs/source/user/fast.farm/InputFiles.rst +++ b/docs/source/user/fast.farm/InputFiles.rst @@ -139,7 +139,7 @@ documentation for details on the input file at the farm level. MoorDyn. **WrMooringVis** [swithch] Write shared mooring line visualization, at -the globale FAST.Farm time step +the global FAST.Farm time step .. _FF:Input:VTK: From 1e81a9a60e50c0269b52acdb5a993ea2bf7c6918 Mon Sep 17 00:00:00 2001 From: Mayank Chetan Date: Mon, 23 Dec 2024 12:27:24 -0700 Subject: [PATCH 139/161] updating keyring --- .github/workflows/deploy.yml | 2 +- openfast_io/pyproject.toml | 9 ++++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index c133c9e13..073355f39 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -59,7 +59,7 @@ jobs: uses: pypa/hatch@install - name: Install dependencies - run: pip install keyring + run: pip install keyring[file] - name: Build package run: hatch build diff --git a/openfast_io/pyproject.toml b/openfast_io/pyproject.toml index c6072393f..1b6ef2d8e 100644 --- a/openfast_io/pyproject.toml +++ b/openfast_io/pyproject.toml @@ -71,4 +71,11 @@ all = ["rosco>2.9.2", "xlrd>2"] source = "vcs" [tool.hatch.build.hooks.vcs] -version-file = "openfast_io/_version.py" \ No newline at end of file +version-file = "openfast_io/_version.py" + +[settings.publish] +index = "test" + +[settings.publish.indexes.test] +auth = "keyring" +keyring-backend = "keyring.backends.file.PlaintextKeyring" \ No newline at end of file From 663e2c198ce4f879ff2336a1364c7445a7faf9fa Mon Sep 17 00:00:00 2001 From: Mayank Chetan Date: Mon, 23 Dec 2024 12:39:49 -0700 Subject: [PATCH 140/161] reverting project tomel --- openfast_io/pyproject.toml | 7 ------- 1 file changed, 7 deletions(-) diff --git a/openfast_io/pyproject.toml b/openfast_io/pyproject.toml index 1b6ef2d8e..b1cee5ae5 100644 --- a/openfast_io/pyproject.toml +++ b/openfast_io/pyproject.toml @@ -72,10 +72,3 @@ source = "vcs" [tool.hatch.build.hooks.vcs] version-file = "openfast_io/_version.py" - -[settings.publish] -index = "test" - -[settings.publish.indexes.test] -auth = "keyring" -keyring-backend = "keyring.backends.file.PlaintextKeyring" \ No newline at end of file From 9ffa4c72489b5d9d288689bf0c83dd31acedc56e Mon Sep 17 00:00:00 2001 From: Mayank Chetan Date: Mon, 23 Dec 2024 12:43:32 -0700 Subject: [PATCH 141/161] version change 4 test --- openfast_io/pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openfast_io/pyproject.toml b/openfast_io/pyproject.toml index b1cee5ae5..9261c67ed 100644 --- a/openfast_io/pyproject.toml +++ b/openfast_io/pyproject.toml @@ -5,7 +5,7 @@ build-backend = "hatchling.build" [project] name = "openfast_io" # dynamic = ["version"] -version = "4.0.0.a1" +version = "4.0.0.b1" description = "Readers and writers for OpenFAST files." license = {file = "../LICENSE"} authors = [ From 2f44ccdd6a77027209349c51b06e6ed1ca606070 Mon Sep 17 00:00:00 2001 From: Mayank Chetan Date: Mon, 23 Dec 2024 12:51:22 -0700 Subject: [PATCH 142/161] testing pipi on main repo --- .github/workflows/deploy.yml | 45 ++++++++++-------------------------- 1 file changed, 12 insertions(+), 33 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 073355f39..3caf7d4da 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -4,45 +4,17 @@ # repository. The build cache is stored in GitHub actions. name: deploy -# on: +on: + push: + # workflow_dispatch: # release: # types: # - released -on: - push: - -jobs: - # publish-to-pypi: - # runs-on: ubuntu-latest - # permissions: - # id-token: write - # contents: read - # steps: - # - name: Checkout Repository - # uses: actions/checkout@v4 - # - name: Install Poetry - # uses: snok/install-poetry@v1.3.4 - - # - name: Build a binary wheel and a source tarball - # run: poetry build - # working-directory: openfast_python - - # - name: Publish package distributions to PyPI - # uses: pypa/gh-action-pypi-publish@v1.8.14 - # with: - # packages-dir: openfast_python/dist - -# name: Build and publish python package - -# on: -# release: -# types: [ published ] - -# jobs: +jobs: publish-to-test-pypi: runs-on: ubuntu-latest @@ -65,13 +37,20 @@ jobs: run: hatch build working-directory: openfast_io - - name: Publish to PyPI + - name: Publish to PyPI test env: HATCH_INDEX_USER: __token__ HATCH_INDEX_AUTH: ${{ secrets.PYPI_TEST_TOKEN }} run: hatch publish -r test working-directory: openfast_io + # - name: Publish to PyPI + # env: + # HATCH_INDEX_USER: __token__ + # HATCH_INDEX_AUTH: ${{ secrets.PYPI_TOKEN }} + # run: hatch publish + # working-directory: openfast_io + docker-build-and-push: runs-on: ubuntu-latest timeout-minutes: 300 From bbe7c562302eee2b70d556f8278ecde8b28e7334 Mon Sep 17 00:00:00 2001 From: Mayank Chetan Date: Mon, 23 Dec 2024 13:05:57 -0700 Subject: [PATCH 143/161] worflow dispatch based --- .github/workflows/deploy.yml | 12 +++++------- openfast_io/README.md | 3 --- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 3caf7d4da..f54f92cff 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -5,13 +5,11 @@ name: deploy on: - push: - - # workflow_dispatch: - - # release: - # types: - # - released + workflow_dispatch: + + release: + types: + - released jobs: diff --git a/openfast_io/README.md b/openfast_io/README.md index e7becb746..796c7a563 100644 --- a/openfast_io/README.md +++ b/openfast_io/README.md @@ -1,8 +1,5 @@ # OpenFAST python readers/writers -> [!CAUTION] -> The `openfast_io` package on PyPI is currently called `octue-openfast` but will soon be renamed. - This package is a python wrapper comprising readers and writers for converting OpenFAST files to/from python objects. It was originally written for [WEIS](https://github.com/WISDEM/WEIS/tree/77a878d7989b8c1d07d2244135ccd308a193a924/weis/aeroelasticse) and has been ported over to OpenFAST to make it more widely accessible. From fd07cf6df699ca6538c84f2cc92170390ce11e44 Mon Sep 17 00:00:00 2001 From: Mayank Chetan Date: Mon, 23 Dec 2024 13:24:06 -0700 Subject: [PATCH 144/161] print summary of turbsim --- openfast_io/openfast_io/turbsim_file.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/openfast_io/openfast_io/turbsim_file.py b/openfast_io/openfast_io/turbsim_file.py index e1a41da92..631036319 100644 --- a/openfast_io/openfast_io/turbsim_file.py +++ b/openfast_io/openfast_io/turbsim_file.py @@ -329,9 +329,7 @@ def main(): input_file = args.input_file # ts = TurbSimFile('../_tests/TurbSim.bts') ts = TurbSimFile(input_file) - df = ts.toDataFrame() - print(df['VertProfile'].info()) - print(df['MidLine'].info()) + print(f'{ts}') if __name__=='__main__': From 00db7af9d072a1855eb13ee5a3988dbb354da087 Mon Sep 17 00:00:00 2001 From: Mayank Chetan Date: Mon, 23 Dec 2024 14:33:23 -0700 Subject: [PATCH 145/161] updating docs --- .github/workflows/deploy.yml | 41 ++++++++++++++++----- docs/OtherSupporting/OutListParameters.xls | Bin 0 -> 3198464 bytes docs/source/install/index.rst | 22 ++++++++--- openfast_io/README.md | 41 +++++++++++++++++---- 4 files changed, 83 insertions(+), 21 deletions(-) create mode 100644 docs/OtherSupporting/OutListParameters.xls diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 3f426e2d4..87240dbce 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -13,9 +13,9 @@ on: jobs: - publish-to-test-pypi: + publish-to-pypi-test: runs-on: ubuntu-latest - + if: github.event_name == 'workflow_dispatch' steps: - uses: actions/checkout@v3 @@ -42,16 +42,39 @@ jobs: run: hatch publish -r test working-directory: openfast_io - # - name: Publish to PyPI - # env: - # HATCH_INDEX_USER: __token__ - # HATCH_INDEX_AUTH: ${{ secrets.PYPI_TOKEN }} - # run: hatch publish - # working-directory: openfast_io + publish-to-pypi: + runs-on: ubuntu-latest + if: github.event_name == 'release' + steps: + - uses: actions/checkout@v3 + + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: '3.12' + cache: 'pip' + + - name: Install Hatch + uses: pypa/hatch@install + + - name: Install dependencies + run: pip install keyring[file] + + - name: Build package + run: hatch build + working-directory: openfast_io + + - name: Publish to PyPI + env: + HATCH_INDEX_USER: __token__ + HATCH_INDEX_AUTH: ${{ secrets.PYPI_TOKEN }} + run: hatch publish + working-directory: openfast_io docker-build-and-push: runs-on: ubuntu-latest - timeout-minutes: 300 + if: github.event_name == 'release' + timeout-minutes: 500 env: DOCKERFILE_PATH: share/docker/Dockerfile DOCKERHUB_REPOSITORY: nrel/openfast diff --git a/docs/OtherSupporting/OutListParameters.xls b/docs/OtherSupporting/OutListParameters.xls new file mode 100644 index 0000000000000000000000000000000000000000..73ff40c46cf43c65c504e5e321aa0e656e1721ff GIT binary patch literal 3198464 zcmeFaeQ;#ibszR-_G4yu`LRoi-yi!p+GZ^fQIKYAcc9y%MIC^M2 z0G(}gW4jxJj}pUmRp>wBNKr^zu1HKG$5N%rvE@isN=`)yrK*&jKh{pFB9{||Wy^`; zN=k`iD^4Y)Qat&cb3gmN*WK^F+l}GQ^pIFw+;`6J+iWWyX^Mp5MJof2rTocs7HdS^Ui5XC6Nb`1ulkUck?b z`1vw^zJi~Z@bgvtEaK-1ey-wY2|w5Hvy7jY@pBzNH}Lb5`1u-sZsKPJKdbn81wU)} z`8s~q@w0)SP5iuypIi8O4L{$&&+GVk13y27pKs#lr}6VG{M^RR&)_G*&lY|v_}Rt} zs`Nnpd+Z__^3g|vH(vRB7k)1|A3S<72>uCv|0fUAUqSFc;pdydLGU4{zFKKET8*7{ z_{z>swGxM~w&G?uq<>eq4AD6%!|$Gh-JBZ>E(V_sJ{o)uW%*ceA^3RkOb`Yi2|gS= z5qu(eI`~X*DR@utzTnB=2jG1QG{pM>{_h9*zkid_euw}2Wjwk2oqu`m?ssbI^RV?G zI2U~5{8yRo=lH*u_`mPNf6oQK%{+g=Ia9%>gCBwZV(<$n7iC>IcQuHDT2KwPf+qe; z6#x88D1L;pT?~GQD%zzSKf?3gCH)mJ-~CRnx=?NVQ}mY7Ut@dF=6ph@`%-6%u zbD-!|+lTv7kj8prP|H1)C`Y<&f1)qNi+w4+(ud+)@KVp({&Uo2x(`JFie7C?7?1VE zc)SnBdGy16QhM7dY5lRD7(WUgM*k)$)ETq-98rjN$)fo5!=DTuK{bU4rZRlp&gYz7q$36Vw;b=`JOy5@?ci zE_gO5As|svo()yWy)c?*4d;!~a`daQ^)+`L5;p)h;-{(Ix-4IRE3R_WCco`H8>$MDXx0GW~~j{?5)1pZ?*~!Nb4J`H#bgF#Z1v0{$oL z^KrPd?EK4J@}JGj$3R}>|4Ruk`xm@>X8!wCzU~*o&flZ*e?M45@@dsi-`ko0gvx)P z$q$hPtf-gHPn72qiawG50hO=yDf$aW;iCM%AN&lGXeNRGl*-rT|Bt1fCH)Vcdg{YZ zd>HNWOPv2fMGt(@E~332M-0x=KPs51w~wj(-^Tzr_=?sKqHHGpBgkjJgtrX-C;bwo z$p^8P>Gz{^Tuw@M=6|9ypA3@zb>IM;T8sX5;Mn;#4)PN?^wyhIPLYp?WMK5KL+)4# zhe*y5cxHL*e7iiz$N%|X2Ywg?UlrNGqk?qQ18 zf*v@T`6yLpzK!#VE;x3+jbrBnC$pTOxAK4X;!gxWi!Af+jo=^eee!R7`{G3K?T&n+ zI3K(h^%C!aK|q5z41b<|A4ZJl(+p&iP7D~Zx-n2eoFqK#%0OMwNdnov6T<~p25J;1 z31o&&43E1qkmGZbKoP@Rgs8H(`u0>xdBK2d5j<5=lbC`q7j2f@#B2hTNzq@_H%o=EfG3R9X zdOwC&6Xjh8!^7NhGbK>Rr3XL!;ScYsKKF>sL-yTJ{`>aDB=E+tfH#K){AxbnKlo?= zm!m3f4GZ|SK>;Tn3k}|!?Cy0}hA(P{oFlHwt_%~d43n-5FS;^(xr2c!ZukFl>4=C~ zLCc#a8O~pn16CUPsot3eDdz#X`%-U^={z8%awkaAtY!dWVsolG>7vtmqlhN#ouY)p zRNm?D{GWeccgZx!SO>@tf=4^Ot^&FHcYA>>bb`Frr6hO%_y<-={+)!godd`P?QCCq z=}woDyz}pBkPFh;e&;*i(ax5do%CVnJ!a+M5&wHUBk$W6lZAQ#w05Ch$}ZHO{K=oB z3iZ-UFQp1)=cz(bo-9+K3T5Y|3pL(Rs6YL77jP~jdmrxAj@6lGBHju8xm%t#5 zhH61?!VdF)uTYV`)!&5G9Z~cekh1{?9!#3AI-n^1$pOY zZxEU^?F*80{z;vDwgUuzWb1@xCA#Z`raAkTB;M%_LUWUSLEgF98w4wW{Xt6Q-XNdr z0Kp&GI-!Y|?mD5V;=a|1cY1@+v{_$}cW(9u`E(wTQn@$CGaVrKBU>jlx71xHG`-!o zI`K|#5SrWW3-Zp*-XKrs0V$PxgM7XN1b<}fq;qB@*#Uo|1Ei}z=?y~bLOFEO8zjsF zQY!Zb`9cQ>{>at|%@B6C6IxE`Tb+2PHwdla^aXk6W^a(s54iz~tREVOeEfBNowvGd`1-p4f&gu!A^!T;i*9<*tP0knD! z_!l0IcYgFw{{_psKz0k!&(I7DiFqn1rj!+e3_aO=B?^;+;SG$Nzh_n4d_BnMsS8>>-9; zEbX0} zfBT(3$`bMwFdqu7i-y>s)O-~EGZF&|Hg$*{ENdWf+t?VX#y{g3|FY%!lmipj9Fat|@KrM+|W z&;G%0WsCVFiJ9$fX(7bS=CHI<`7iygf0!-iQ%NxymiD zSlU<*F}9_Z%Kz0r{N-#hPbbA>SlZTE z0cu-F5WKzpA7+Do-hje3lAsd_P}?4G`rxnsoovuA7*JS35_Bp7YPWt6{6D|AoCSI@ z7(>_#u0-44ySUKV^5;Hr_o3hlw%Tm#(3mw6lP&%vHdA3tcQvY24r@`n+Ngi;;-BjT zJpbXlPXuD~dL=l-7WN23uWHc15R7JcXe2=bXrfIG^=RUY1w2aYTzE(`E$2XN|8=qB zug5z6`u_R%W5+8-r&ssl%A4WUxK{h##qT7_^^v=eqg;C!3|4|SF*Ll2R1N>LOGT4p zJn*m$U6qPv#vawB5`U>uiN92-#9!aX+}ju5e(3J^E{2^&dE_AoxeAr+<9`uE(fIb^ z;PTs#f_5xH`zTJ#7}_xSDMW&w);tq$KMbDFCwLyddl5W`I62Vdv2P_f(HxU+UjWBs zg5$#7_oO&FWql}kj~jdyxT_Z00X zm1m@dfk&bJ_XG;^Hrny`E^c*VoPQjhjxgFNRDk-a zs6f;E%H7h`ya@v0FXe8wzySAI-A~>u96lNMGqLbB-Xs!Vrx%SwLc56#0ZxE2ukp)I-?a0<>5S?yvA3R&BF=}TUy`6PU>Ac{fUmV7&jYBC-v{*6yPWRjOJ+HtFmsdHnwBXJ{jEpDos>g z6c4JcH;KRgGn98BxDrSElK-iHKw0lqS&ILu;J<#9CiNZ*uGOMeTS)sz@M?<|Lf&sO z75zto+PB4{jq3hEEw;Fx3V!|Hphu4d%ZnSEx0j>l{&#Wk@DKiY9GQ=!jytu+(QDQE z_IGhy@#1@Fb?~X+m1ZScuEobU>g~9>6IEiW()AC~!;8U2+`J=7^knd}|DDLYezGlf z^8Vmo{p()@-GyMK(X6%_P}7saxBirt#)viAXh&_py)XFtpQpLMM}v*SEmp>*;Ga!X z&c}oGc)xK6zHcI|){+!l6HWBGDz*mQo?&*AlbB%M2|m3-u^wjy@0ra;P!ECr#^Z0mDQ_@o1gp? z@rRx87Z{#M?=rl4Ea5LOyn4KbDg?7sIQjUE+j9%o%FE^HncG)qXP0hIKfiG8_LYSz zbGH}DrRS%v%ug?0xpw9DnMdT3?FVQAd%#PMC8AG1r>adYe60%PQ#aox2$P z9#HZB;Ln0Ed}Z!j@PB-V3w;$Wzl-rBqQlsmtK;x{uhy&W7DiQ9H}{&Y_TuS2@?MVX zR}bXxx6nfPd+n$xGB)2r-LE&AWahVMG=^k-d#Tz)8(!boxY85^8ykB&?W+ewE0S*! zEhhn`vo|UG=Ela$(eBDgWTmM{GXK=dKb85L)dNk>X)9mRQ$EwLMwQp2qifA3Fjp%# zR$g6SJSKXXKC#k*o@s7bG`B38TZU%S!r5FjG@FYSjfJym;cNm2YFKOU?4vkUlWgnc ziOD@Nxu+)gROj9@2)B++u0gnE5N;WSTN(jXQMgDd1XRl8Y6MizscSN*fw2t7O%S(~^eMQWnx$7N-r3mW6yRi_?b2 z$g=8Hvg*ZYCCjQ8@^!s9ZD@=vt6redvdUJyI4#S=X^Dfht{0~bjjk8+wJc5>8Y9c9 zSJ|o;rcweU9!^Ufq;8Y9c97ihGs8LM8LmgV8J#6eoui_?Zi*9-Yt7N-r3k!96u#;O;m zl`N}X$k+Aaw4pJwta^b)%bK<7#c5d{PD>o5b-g%kXmq`huVr!C&=^@(y=JX?aazf; z>V9o%L0Z>~(}qUZ3;9|WrwxsfWz}oWsu!n~EUR9~ z*Y)DGp)sV>w5$cIUYwTY;k3j-TGxxyhDO&5`C1mI4ULgy)oa137pIjht6s?0_2RUl zF|w?Bfkw#MjH)#b*NCkuP4RkjxmsVW9qiEnlhRk0n$fOG->mM?Fo^TlmQPIbSW+z2 z*P1PiOg8n%1S3vXAJK{=jVol5#uc1|?o3h>KyxY=l`+W@hTUV^@$NX@fW{`qdEovU z|FO@1tVQF7n06jP#uA1gI#tps^%Mn=c~GZLvG_(?jq5j$uD5A0)27;r^of-|)oC=G zl{Pd`zRE|S*EBRRu<{L!g+oDH(^xnNtQv;`v7(`XtJ4+^1x+ho(;$#(9147jh60>U zTR0S?tb9#_z@c#{&?p)TC^~K7P*AY)H4PlK#v#Y9Xvl%)5X&iD~iiRANPFpzSWUPEmgO0Cp$WbU7atJzY;ZUcx^7+kS^Qd{H zwal*;BFV27B54R#48e*aSYau*V)=%OeuDSFE6wHOx=GS2s>nStxhFbz#n7%Cn_NS? za&mwk!U%Yev(k3{smZ@((cH3VZW$W9fN6TXfmvybX33&ivS^l=M!e0hN89M$;;nm8 zr*4r)X&&s4tFB+s?x3RGL4|y)cmZELmM`FVqhD4p>6~r}8cM5|ZcfX5ywtBLUZigw zN07YUz_ft;{g(VqZ4Oz)tLTwlIgT**0D4Rq2m*4SiU4U1jx@k!b&hp)j&*g8`K1kH z>r2}EQc`+fN>Y8-+LgVvmD38no2fL#EtMu0NiXc1OZx2;tm;K|eaXB++ewRn*|-?u z{Z%G)G4R?35&Zs&QkWzW$XrFRV%~s}R0K$B0#Q?9TM;#tNlgGvN!%5v$|N9n;YxM;f{&+A`_Eoc1fbcVxB_fqxE!pvm;-)s_MbjTC>ik0V$j& z(@<%OtsFX!t15M(Q>RrJG9)gZ8W&@dE2nkwcugg4oz_2yEd#Y^I}WEphzM62Jadi- zZk2npQHg5d#z9n953xkBdZmVr7PrC|!>P_cOPzm~JO7;S{Bx%B&)LpD=Q{tK@BDK? zm%Nl&@=};Cxn?P6vXnDep!(Ir{VO%pw5-|Js_4K<9XMD|c85C+rSde(SHco@er@bU zxcg8(0|aIXv3DU3F+ZqsKfvy%(VU>cqsn|5xQ(N@IkDL|2%ihltRWU5FcG_}C@>pM zHr>Gm0ixc_t0+lzn@1f@X8z{JHQX+#1#d zb{frnRWejvSsJ+wv_Q1o!jg^3v>K5gY5G!_LEq8no%H1_`i>T7dg$-^;Z_*cw?U5` z5TZah{2`ig1B$pj~C7A1ab$4%K;~>Ubh+t7QVmQ%OsvY?e&V+Pp zXMPT)iMG5FwWLrK$25Eg7)-)$eg;6}lgCgRr>MODT#KSI{r*;oQyBRp52j1+0G#_- zq(g1{;dnUt%KBu8EUWK_<2k5Gxv0vysHSsK&E%q*%|$hri)ua>)j~M_7tnNjad;3l zqkVE3t*};YwP7r&DI|LN*Fa`eo_ZR>vD*-%1X0(z;60-SZUPn zV3$0tc3x)lJEUcnu(87|(H*#lXbaA!!RzH=WiP7N<64WP(bD3sD2)+TZG};-)d&w; zC{nu-?#6YpZBc^dMib^=hfu@|MR6x?R(DRq>P{F@t=d)EHP%#;LIB>0YSnE7%F^Wc zl3KYBxi;Z`bQ0Fl>sxJbhDX)*9+$fow^=opuB|Rz3dbsB_|YbS0O3Rbu zD@m|J=xr+w7f5(BsxSn4Wi4*C!Z8w4tygM?yr+j$eQD)V2v-zd+OO6RTbIUh3j;4w zh5Hg{>iH}rat*D$#$k=xjPQUoc8QgLX&k?sjYCjCz&?sOJvolW=Ji9Afn_DzA;7X( z?|)Xrpb%gJGbQm8jVafm=F9Q#wr3uynD8LZ6x`^ec)h(b$=wU4x>Dwqba%IBuY3OuI<$;6a1S ze!zn#vc2&xHc}}mlM|*{deMlg)(0g9ZyHJr>Ie;$7K|9vd^xMqtyh#(uOMM@%c@C- zP3M%-MPXZ_CKh;yU3-D!m9Devl)|EY@hQSH;#HQx)5^Yyngl z2`j_un59I=)C8(yb`q#^nT}a99kYb?wL50Qc&v^|Orm4bo2l%QW!)vq1MiY$)mKE9 zENfdUBMJ_#OKLHqOO|z)EQhAya@upZE?HJxl7v}ZvK$VwONyFUYU;4)oK?u~@0djD z?2_feT{77ly8w5Ty+FTFCDy%BmDn_D0aPryBzt2y(Hk{^>W!TQs$8ZwmQ8OgCwgPT zZmix&OrkfIaa&K;K%h(QXrSJrsTB->Ia*G6@|QgMeak=XDSyV3f7X+K&Xa%MlYc?; zcg8Ds`zgk6?57yNv7ci6#(s+N8~Z87Z|tWSzp9Q707;9#1_f^b`%)Cfb9=IPWo7wK%P>onkRdvHu z^_tF9r9$Q{ovEZDliu&K37gAWMm6iZrgUmjagQdrxxAPLqooa+5R>zSjpk*{lw+bY zY*lybVbmh+lCa|lOBgEMGHD@?tM?@%&#sVEJyLPpGf(0eE zAC1dTZC#@^)FLUAz)K97Wx)E3=>ct8f)ZpxKOKA>B|z6oKeP*g9-x-TPB7Wov+k#L z`5t$`Jr8BV{3v!eTn@!Pd~`cxV2w6Tqjr=E{TYOdh7)~`GN{jmsRE^x*4dcV9#(Qp zCGBQHC%qn?iifa~&CR9O!SZ6ZjUKmIfFj%2$R<1KBwIYrCOZ{mnCoDnG!xlTS1Cxy0|tlPc=SlbY$slL|reWb|V>wIqt)i$s>N7l|w+j^OK+%RQWt zI&IW(1}|(KHn9*mMynz%aaKO6jfdOS7N$Zg@jg~&a3Me@;}KRqdhy}dtmeZK3zk(N zZZD27kJ^h3%BGDY8&t0BRy`ILimuLtC`UHkiJ+5!I17EJ3*f0BELjEat0Co*rn)d? zX-Dzk*jQf8C>E#Iv;C1v>)Ct`t!J~zMoIUyj<(=2P)Bc&ZH0bMZ3^FI>!^u-i-m|9 z1!@t_#}GDnx`B*U>Bw#hF)ZuPgL8zsDNcmHX7`vWz}88hGTAz@o1kC0Y(8Af+`nu# z0}NOVY&+I7unLRyOe_>u;xH1+FI&80riuLukfNCMG-yu-G%@X4SjK|PGlo}8gY}o8 zCn$T$unMIo?s_uFLap3bo5HBjgm$$^2q!>=Uco$bCxKcWQ~;>exTzI47wuQsZ;&fY zYfs@`+uo(Ea4ciFb}*%zBC)j8vl6=2B{L)4lfg7aNjF7FPBZswijtWt?kU46lxtIT zt{Y(E9LIL0CNxDSfm+ToO;OTKAz!p|HU(`rQ%zCQO_5kq$X9D?aiAxIX^OIL3N_>3 zuPLl)`<^m%Q6=B2*9BH! z{X9n&nA&KN0_#_oEHJh2AqCd2n#OPDtxKAtUxCvc{Yqv0X5LbzIr^0<&C#z^#&6~= zRhpw;snQ(%N@e_J-cqGG`jslp(XUj-Z{{sknxkK-(j5ItW&CE|Ql&Zil`75AuT;im z<}Fp4qhG1g9Q{g_cA5RWT$-a_sSJl&4eM8`Ea!)#PCT5~&QF2$D{vN=+HsNs>sOa7 zFtq_D1=g>c#%1QMOPZr!fzurQN@ZMT-cqGG`jslp(XUj-W#%nanxkK-(j5ItWn5<7 zQl&Zil`75AuT;im<}Fp4qhG1g9Q{gVTxQ-ocg4ql2M|8NE~%l%MdSzesg-h2xy z#@A@4ev{Xi^eR5;KoX($%%=>Anc|L>e(W3Ad<&}xi#4p?w4fhxSSK9A*)yQG>7@=U zW3B3e*y@O_k3uC_f3?=7x8xZ|F%5;cB(q}N`RFBjR7a89bkZWi{f_DoOvj8NEl-C# zI3`116TxXpI;YUYiJ-$~`~nttaTKvQH;OIlHO5Dm>f&VQIJ8ISHrsq|lh#F4!L9kp zY>Pgw^GGB6;fZ(%TfqtsZWlN`_$*Y=MU=Ioklou7%jYn=ZctEXJV6^haE7WbmX7MX zXwUHlBWlnsuU%1@{E14hDp*>gs?h*XXef zXqUBXopO{@F6k%A=~8<-DP)(%rH-Y7HA%{JDK8zPC|cff!SW_$x|Da?qrB4v%bS$x zQr;Pl^3D`2Z&Id9d1pP!J6o{4NtrI?o%1N~T*2}tWxAAi-lM$p1GQ5FP(MyXf8<)c>PJQD% zyg2@j{irx=a}B4l>8=La)mv%o;~sfB8QtQ;spaN&sN`cC0p}ssOt6Qa;BxB6EsXi& zdL@Q97D6Y?y9xpp9k{<79_>|ecSwW*D30@oEsQ>Eq1aDi>WSUIID_BbliN*F62t8V zcuC%VL?`7Zf70ku3^c}m9F$qY#$a9ccaJjv7o$u)Wa5+Drh&q- zs%Yv+ydB}1f>XS)@SOl;7Z`KxW9t;30mIwLVXfVo3}2;d586xuz6U=WexQ9#a$xYj@lS@;*y9;GsfoFZTXNc1)!49KvNLnHR+()sNh|x z(e&t2Q@EAE-3r3BT1=y37&%=&!9BsK5|>Yi{@OU;UXKed#Eloc?c7|7A#SO_s8e<^ z(K)#5wWJO%9*Hf$ehcKPx+8NQ~76CmJ-ws84= zl0!MaWSP~C3G_CeQC#)1DodM3VO&n(QlufAOJQ72 z;Zmd_oJ(O`PT^9dA)HHLTu$Lqq#>M3k#;%GJ(VEV)OJOzMnuhR+}4f7u{~NR)|W2x zHQ}MYE?NG`H!;U8HwbyLtAe0oU#<}HHcACSM-<|gzFJF7+=*3gb2-Y1c7r7vbq8+>Tb=!LDfDE>0WC z&1`*$;vZlu09LK{v#)Hi?-xQZAxv7m7t7jW$y>@4OTS`U0ewe;%ZVjbNP}fz*Nb*; zExNRgSE@1lrJ8UON;!&g{m^9=pld8Ye}GL4Scu;_tWgysUIxO_dz%(*Q6u^y1X!_K zbUVcAG(0KhMd@a^3bx7P1_NwJi0h5RU3~JPfu(3TvT93w{vqDk!IpI1&LGx?>4rJ2 zl6~=sBJ3-lj3+PSV-46&LuinIeF9R~_$WmKVt2wutAcG8tby^#t?pZZ)y~xP?Mgka zvd`S~vD00My|LC`(CzMm#9rXkMNzI*+3qf(YgKUlm8+QR-NkfmmM+fVW_PHrC8iD0 zUEr>Dhs#!R7o1nmb=`ZO={I@bgR>qzHtF1(?G2)Ln|eC$d%M+DuVRltrgFt5AR{&R zX097W*R1Z%%B8nA}}_dVsZ^9&BxA24CBm0oHbAu(h2Xd~Ih3Slijb)^=|2wVfMa zZRZAC+xfxQc7A}hogZv%7Y1M3g#p%fVfLK48J9_nP!|YwimDFBF2K##gShZa0Fz!#b6XHjV|y zb#)<5V!hVBwWPmPUU0N-VetdQGD%7aIqy^ITYbhEf2&8ux9D_e>I!`E;Uqf8IVKm< z53q!WMhQz3yfBOvx9A`~rnwRoS@>~TJ|1sl8MTLsh9&j@*S^TlV%2bU44+p<87UNr z`;~Zhhiy#G)sgkcW3=k1F`p0RFyf- zlzS6rNin7yi<3+HrE)UJ0aTr845YYh7F~C6CgY&t=uH z+(}2T@jxnLD{ddfI1Kze*M5p_&BC|kTlBSi>R72uwYJqK-Gw%=%nYZu)xg#jiuj#- zEaXLIr~Bitsoe+YymX^jrGd59YNblomg(EY`d?+1<{p1lA@iMHMS)YyR*8k;*EbbU+Tpo?#c8QR#d&5W2ZjQGKcUm8*uOu#N6F1Fm zzJ<@BQ7?lfh!3Nolq<*bgK3;LA57EvsK&~13ocdfmuiaDUb^s&_A$iAP)>z!)Icw; z$Gh+mIGRpZ3DEWjtm;P?w8DVk6ekW3uzdk%z_|lslM(?`>rmPFXEQFcOIsbT^h({8 zmolL*bh*SX4fpvjlqtwx#=3~QR*rXFkk`Xa98u*>eVcOhy%BnOOS;b^ zT$49Zt?wY%sWE$xtLxZH5T2pgYc#iO*wr!lhJ7`cetya~%c=WE;FY<2bTt7YPX`iS zmg}@tgm1=^uB)QZp-o+N?GD*3*Q&T8&g!1sDYvmH#HRcO8}p=&n=UG$x})zh-K@x$ z1cX!1m7ZO!HkaUnpS=Y=eyc?HCtz0#{XwIY0qS=@^M*>T%;T=gjP#9+T4k5bU5Hp7 zf%4_+^$uK~ej-e}Q2KJXUbr@c7|piE zpXQqp*UX3f@O4n}EkORDA6ynbSS7sQGJRo__Xyx`IJM>Dh=(AY#3McY!1r$i2i%^b zfHyQrNenN_d2pPYZ@r{?Ahsi6u?Rz*RCCF%rs;ls9lOuq0d7s)!Pcinv#bzEsfsr2 z_YYjyqd+Y9${R!D%V45A_h1Fr>T`=d2r?gmE5l;@6*Zene!nbJ4rOL@$uHS;<-#43 zs|{=`!wpL(xH0LdPA(RHXaAs4rvZ<2ynBaR6MHePTy2L;pd9mb5L|6GTCE8;HWbrB2 zm*((wJBzrUXz7Hm4vKLVQMiV2OcY+4xO6$ZbesOOkN=?KURt>nR`zgT4q`q9Z@T(M z=@y26Cu&xsE$sJ$SI1>WJ0V>eb0oGs5;PmD5@qh~nVjfZOVvb1D;NoAt#{SQBSCOP zoeaP4$lr(b`=KD1ogBwivp4D(jaRqBtJp_aM@+fe#3&sV_#m2xBMt4L#4gV!%%^q& zwzKK7pomXwvu!ilsx7#-~Lz&MyG-*x4I+XdWLzC7ttV5a4Iy7lPvw3vAO-gJ-Co+9vrB79wIkYZ~Nh8d9R7AthRAO+!jl`J_ZEt!YS!DxZ{Sr8NyHQRR~ot+b{gC8~T< zqLtP(q(qfZO0?3a?RlE?tMKTUUMjncGkHwP;{a>JRD!k3&^MD6Lk3$at#r}g7UMZ} z@p2|xLZU-qO9@to!j_5^HYw4eu;t=~Ef*_nQldj)r;8VMx>#Y85*-RVQ@pS<#R{90 z=up_%;)R_pR@kIOhr-SkFYH{g!X_m;6n4INVdsk#HYw4eunWZtyHKpK3mCA^PmceU zAXp}+jJM>Ks9lS;!VMl$(?rTqqxmMLo*KB;vvwj5Jzb)aINos@wZr{7P8(tI4CkJ( zNK=0^lm`}@I7=p{qU!NcSiz8f7q4h^y>B~ewkN|e>@KL_l>(>4=ztU*g~T<$?HIQV zRpN;WoaR%w@%};kM|1BjeShNzP7l&dSmtFFNLpe zTnk@Wz4>~${K|T`{OZk{6C1B@Y+hRlm#cgn8H_< z!_Dj0i1F3UwO2Pc!mEp`;gxIQ%8iYi*A|yR@@Noz{q~iqNO4sD0DU~Rz z#ME+0amhqk=4|53DL-0jZZSxDN7m4hv5U^&^6h0MuT#({2IlbHJm#fmb`*209RI-hShu^Jg4EgCCK0^vle1^q-N}Uu_=NQOi{4A!E%?h39s+c0o=IEFxPI4vWkkZ}c7>=HD zW;#o!w;cH7twuCY?8;&@&`9n|mbPwGZja#l;HL>~z zVPEW0NDk_}(@~iW7432tYHMSpP5w+5a(YLy=`bo-tW;tgAl91;^1A5atn^Y-P%6D* zWU=P)6vbJ)6*z~~tODnBHd7e|&dHip;GC>w+&PidaLUc0gC%KlxjI;JlCPJ$!~Ggb z@=lircbp{XaC=yyNC5%R?CRa2sL#bF>{oRxf7L8;_)vsiQZ zYjU~;S-TZDht#YB=k(WE1s zNstT`$>-@%k)+5MD!Oy^blnIQNlxSRdxeVbTs`F>R3tgI&(0Ala`9$|imt4ELq%84 zuA!nUNB2z$5PG7JgueHKv0ZguqCs$w~h!ze}tgR`W zG*`!9I(GHbCR^t#JeCcZK2J~x=&At{hrtV>SjEvU*%wI9WfcO_O}wO+)6fih$*n|| zB59D;G)SMecRClpv_J5^g(zVjrAnuu?9=$pwvmuB^{;hG>2OqouF}+5>F!Kxbv6w} z+YiW#l`Y#uTH7Yl+J2`k8l*K1(r0JC<+HS`@|kp&@>$vM^jYd|`b=~;eO9`gIZNHm zoQdvc&PsQ)XQ{i{Gtu4bS?O->EOj?`Cc2wDE8WeXrS9g>M0fLNrMrc*)ZN0F=x#xd zb!Mz_4AOcWgR~y&%vv-^YZ|0A&74Jpw5CB?)682mNNXCTHO+!WgS4hWTGLFen|BAK zH4W05rex6|t!a?fG-ZnhX-$K)rkS>Akk&LvYnmC025C)$w5FN0Xpq)4NNbuoiw0>; zgS4iZw`h>oG)QZj1&ao0O@p+inc7@Csp@yMwNrWx$JvP?y@vOi5>O{LddwQgqagZq z5wiv+t*cSmL^Wi7dDGBLTUDL0Xpq)8vlb1~8V6}jGiT8tt!d^h8pzepV% zosTkTdSGfAVCsCNHT{A`gS4hWnwxNFGbyEE+6RFTt>oolmYl$cR`Tg#mYl$cR`Qu) zmYl$cR`S_lmYl$cR`R)FmYl$cR`U5_mYl$cR`P{mmRt?drq)edKwA5Jq;*^dpGMkNTGP--TjkT}+DhB`nwLh}iiSqoR$9~3NL%I8NZU$-25&rSu|%xg z=w*e0%vg7P6t%RQ6gI$#_zp>DTCKD&y`nOB9iFMMvum)@S=u2@r*|6t5F4zVY4p5D z02dN1qv8hcxGYW;&cZGaaU@HAEfK-20j7aQ@76n6B0kbx3pYXQso2Gt(ix zve2l(x#JDQzpQX=qAY<w5_zJp($;ZPgB}f8Z;llmS_F>xsHuy z8BgSVbH)=n&HO6`zb@mvPpIc7Xijly4qx-aSM9W_`}jB}Uv7uX?+$BiT%_|V?!3Wy zPwbAutuVOhtWM{&#F-;~O@OtrjgNgUE-kKX;EF7T)(V@4bTJRHif7wVJ8H$aVy4o> zXG=S7rlgWgv>OwG5Z9{Vcq=Z3ZZ(=`eaH6e=Q?gj$h-rbcS$<8NpkO&N6p@)A3}R0 zhi=7w(tD{~+AXXPd&z4Dv1N6FOE$r6uOGK??;m|G6K&a6pV-6>P`Xbu!X=XR@Y*4L zWl~(f2rRO5b-Q8IY8~#=@#}ru{Uv*ssW)zHYc=SyCUG-*N+RwG11}xc-p8GeadYxl zb0}AKUaRY-cfHz|#Hziqsm-q=|AK@0w2fW2OI}0y({pmHQ9_f;8&_~ku=r5fa|({W z_E>0d>@XT;i*NWhrL~NdeA<2D_%p7eYwyvmh@v~EFQh}&>3W9by>uYN5o|q z*a5UAzoi;~im!yO$t!=dTEAEy?U1%HsEQTTsD^8j zT6FJq!3_>#xN6F7UX1Ri4Gw3q&UN+%fj6X)K@?k&zCR5DFLNV<7#T#JzHY#q+wk%^ zGKi5u7=yse^2i`Y24M^WFZUyZ7#V~y2uwzd3}R#u#vm|xGBSvfK^TL;WY5STetZog zI+uAthuLMV*HY3;-@R{te%Ea&5T|z{oNdszlUr)Arn+3W+zw60K8xP>@_@{{Nyi12 zym^lRu3s0QXCEmVU#OyUIyf*_rw>;}+1JJUEPao3oKMF-tKTCX=hLyz0{BSB`E=~F z20qepJ{|ikgO7BaPscth;rE}8v#!9kM&N2w*BQQu+?(A7!+a4Lj*fj^L`FK!=PL@l zi0F5ak&g4}*ykN&q~m-#_IU>x={TQ`ecnMvI?ktKpLdXvj`Qi*=N)9E<9s^yc?Y@w zbc}1rQlH_tx9=c@?$8;~WlO`Es2`4wecnMvI?m@SeBMDuI?ktKpLdXvj`Qi*=N)9E z<9s^yc?TKkIG>Jv-a$q>&ZlFacaZKn<~;)K%HEJ~%X~Kt;Cx<0x-0r!sbhIBHGL$e ztkWk}`c$RqQ|?w;)9^=hBrktN$D}n4e?&*-^G9?{TGQ}HbYwn%M8~8x4Sz&O=JQ8% zOj^_MM|5O9eXdfKnLnsw@^!uVBRVplKcZvOnub53BlGzqIwq}Y_-=2R&v$#9w5H*^ zy=6Y%?QPPUhVS;4`FyvxNoyLu+gs-I-QFgxY4~n$na_87o3y6kyS-&T-|cPEnuhQ8 zmic_Qw@GUnzS~>o^WEMit!emfZ<)_`dz&<9^tJD0c^l^t@0d3q(NV&N_yL$HeaE~K zHvF$1DM>@rq4{Eu5;jB~nhy~vVZ+j4x>`fjVcO`2s6+E1qG9VWU9BPN(0r^%RcnYk zG~Xan!iHss>1qv8hvs8Fs#-(Tq4@@p5;iOyrmHnX9h#5zsA>&ShvpkZO4zV;n6B0k zb!a};qpCGT9hz?tDPhCXVY*sF)S>xUkE+%Xb!fgpq=XGihv{k!QHSOmM5wX zkrFm69WLk#*_9;zen#f4FrypqtBtzzXFpO39_mGuKA#l0H_NHscTnoPY?K9?3xYDu z*c_!wZ{_UzZIzB&{GjB~p~4^ELxrgxH&mDAv+#RwHc@-`xRip2>e74^JaTDaK9>e1 zk6hZwrHPxEeD+z4Tw0DRD18(>a%nkT8k9V8X(N}WFPFPf7hl4=OkYkl-;GOu29kDQ z9@6Je@97cxdp=6zJp$_Ne7;eH&*rg_U(4y&pyZKX8~HWi*L=1Tj)rPEhH5?v9=Wuf zE)7Z^xwMf>6E4kX=kCa*<#1^}3Ld$%oGuMY9=WuUOA{{5XQTYcrR8vGJ_;VWw45#t zN*=kikxLUU&F5Uo$ff0QX+8=bxwM=v4N4xlw2?~_F3slz*vO^jaA`gY9=WufE)7Z^ zxwIc&m!{8C9&eR&`ov0~sx+Uilr%_d8a`Vo^Z9J0NoyKDTPgGTY^6zS8a`Vo^Z9J0 zNoyKDTPgGTY^6zS8a`Vo^Z9J0NoyM9>w59oN=d_KD@|I{@Yzb4&u1%5TGQ~^N}11R zD@|I{@Yzb4&u1%5TGQ~^N}11RD@|I{@Yzb4&u1%5TGQ~^N}11RD@|I{@Yzb4&u1%5 zTGQ~^N}11RD@|I{@Yzb4&u1%5TGQ~^N}11RD@__S`fO$CEYDUdVME+IZ_ZXKVZ+)x zZ;p&ANkcq;kZ!Oc>d>66R5k0OL*64GB0u)V7u`>tuGd+jpRKkX(!*sQVs6%rSQB`Y* zIy46?m9SyyFkP)7>d>4-RMi@y4$T2eC2UwaOjm1&Iy5H{RkenwLvz4V2^*FU)72WH z4$T2eRjncF&>XN-!iJ?obHGwb8tQ2zpYwn3_Bkx2;Gv#I@=@@+eGW@0cyz!rj%a`Q zVXIo-OwPON%QT;XyM#Xf`TwtJP?Fe21{utzzL?Esk1oSZ}m(!`xof z#(&Ii_rq2!z6;kl;18O_VPl7D(5mj%!%CxmC$96?*g?1*?lhXA*oQ9qR8-%s#jQzw z{!baiP+gkO`M;4%%P}qQqu`NC%Q-DSI$%kkU>vzLcCJ3>|3)q?hfDKO@W`d*bZMgl zmLr!Iw%TIzgwN5xkxR?r(tH#=a%nkT+URWM$faqQ=5zFK?zTv|?-cF)gN z@*V-YIWKG;*5#a;m?ztg+L)DNXF zEJs5%Jyi2K|2J}JIb52Lf=4bbr%M|hupGHG?b3YC|BYN)4wvSm;E_wq>C#3AEJrR) zyELEke~ zc*y(J3VjDcfbK@Sn5*;H+IMffnJB!exAV75-pHX_u~X0paX1tvGxIM#dzeQ4r50Cci#Bg^ zhOv$FK4*>y?7V%HJMu5tLs84W3}tKB$iI-=9N759XG77*zx44hKFWOn{mYBNhr*y; zy@L}g4L*+2^?L)BlNript&x)%sFU&8;xlqGeVmMsavwk^5Uy?*nR22oIZ>CLsHdH%XPl^Kov7!WsOO!i7c{jxm7K42 z@=%-B$wO^gCl9r0ojla0b@EWV>BQ(e54LH`Jk-Wc$~pRuDR&-fQ|>&}rrdd`-O4@l zV({Tm+hHDj)B1U+jb-JbHddR5dg>EFuvBe|eP~gwA+HKO-I|&}M{0F@TI%_<%ulD2 zepBDe+}ew=*}01YEyh+V##S!IHeHNurWo67F}As4Z1cs~7Bri347r-yw3`!~X*VY} z({4^|rrn&_OuIR;nRatxGwtTYX4*};i(KtCrJLJ{tzdH(lxD2NsgTA>oY;(&II$Tk zabh!8;>2dG#EC6!CHmg`Ue4UGsj+h|Hq+crY{s~p*o>7pu^B6IVl!6a#Ad9-iOpDv z6PvLTCpOdE$^|(#w-cLbZYMU=+)iw!xt-Wdb33t_=5}H;&F#cyn%jxZG`I34j?L}F zW}4fH%`~?Yn`v$*Hq+crY^J%L*i3UfvCU&tFJ?4Kp><_GCQ$bGqx!afTJHIDD(fje z7I~$%R>h>v)hR1YAN5oD<+&ihJKT!HE!?fP9pbBO5hiQ4PcXSttzcHCiOHYK z^mPE7g2Y)Zne*WwxL)1eo7gyr!L+d#?X<(2jcB_C_}8POmBv1%eJ*nPN^|A(;8B(R z@gP`@Dsc_dM<>xyxZl{P`DR()_XYu%7;{GTHV$2WG6-Id>v1z8!O%yz*=W)Pl6))+ z5!!{g(v04WKWK!YFpB(%AUJqt^>F`6EqpO7KOO|(wOZ6_H7R=ygHRY3xj3s<2ms=xq+s$c^Ys)7WVE?k9aQ3VDlR0SKL zP!%M=OyMfbh$=8Zp(@w_g{mL{W(!wgR#brj3RS@dC{zUrFju$=bD|0iP^bzvK%pu~ zfce5zm={%GfI?NU0SZ+?0xT4+!h)y*0~D%)4N#~G3mA}4=-b%5b^Ij^vf9l<1pX#P zvW~q4I_lZ+(2jrx=Oh=79rm(uPIKYd(Jzft@~u}%)QfPu>Sf`0)l1@(ed|>g^&%Xv zdRaJL^^!Q#zV(_G^&%XvdRaJL^^!OYw@WmDT5? zR<@LnTD1_Sq}K5Ik6%0?w?@-ThfUt@q^Ac&rzzziRc(`lR5eTvQq?LsNL7>MAXROV zgH$y{4pP+$IY<{Ur$d9+_4rxpA}94mZMzlL5BIllQQR2zyzOIdj&7zJ@0hF+TqQTI zlHe-4ag_zvv>Vs7;F@vcnh{*HZd|j1YtD^pPH@e;am@>^1vjn*nl?l$uY5EJRwC?i zlnreAKS5IJK~fSVN8}4u0ZbrLuXVC%r3-*4tu}i$Z+urNwEs!#{`rQ7wfGT-Fl>|iD z1EMS-rad601;mU8#EgKL^?;Za5OW?7a{^-C17co4EOCmvO-z&mrd1fi zm{ws3V_JnFjA<2yFs4-)!kAWJ2xD4>A&hAih9Jk!i?5g^yE3(Sikl|edk6wDB^G+< zD2(`|Ij^FY`jYViYq>8OnZuPSUhTwsmRR-Vl_g6ck(7FpkX>FW_avb;fh$vT@#%$> zm&Vy0y%v>Pf0CQ+FNdq0t58BAS*uWxB-VhuB(V;sR>e|`7m}>KSP}6;qJ;_6PAp7# zA<_B(ki`0c7ZOd=14&HNdm+(mIgrF`xfc>mS_4T;T6-bUCB-=9mkZjBJL$WRN6!v5<5+Gg_v`jxF+cN!- zY|HdRvMtjO$+k>CB-=9mkZjBJL$WQ?4~Z?agOi7m6V z>JiNq5?f};Cz>lHw#<@GG*?J$nI)fSu8`O=OFq$DA+cqae4@ERvMsZi_f<$@ATGBG z6^iBx$+k?tGTD~thh$r(AChgEen_@u`XSkt>4#)nrXP}RnZ>-XvM1Xz{g73mG%wrHyzCRr6%t!!*(aJSB(}`5Pc&CZ zY?)=BXs(dhGRr>ETp_V#mVKhRLSoA-`$Thv#Fkn1iRKE)w#;JQS0S;_l$Pm-WLu^m zl5LrONVaAAA=#Gchh$r(AChgEen_@u`XSkt>FRx73_cx-Dd8~7JYC_$^r=F!&C?Ib zHcvk!+dTb{Z1eO(vdz;E$u>_vB-=dwkk~wFQgf-=I$lUk$LF7nS5umvIBbz+8a9iG4r6O-%Pxfg{j zJM_V^?a&9uwnHBr+YWtjY&-P9vF*?Y$F@Ts9NP|kaBMp~g&iiQ(hJ$44~}hzJ~*}= z`rz1h=!0Y1p%0F2hdwyA9s1zdcIbn{c1RQF1^sGj3dj?O?T{wTJ#p9$Y0BIahwYFi z%sp|~4r#jF6Nl}PCd)l>*bZr`+!KfGkS5AKacny*;#afm&Z9~|2beQ<0$^ue+1&?%<{6GNd z2qpmexcWc<>7XV6`JDJb0O>d<0QrFSKmaYnJ^^52Ufj>H2Loss_Fw=l!yXKvW!QrO zv!2nu@Js3dCuuoywiHUYU!yXKvW!QrOvxpk>^H0kn*JFo0~_n7;QOj_7$SYGrJH9~dATHzxE42FS*Znf-wQve(8G z|G)s*urb#^FhDkJO!^NDkPREN{{sVL!^SeezyK}7_6q|UhCLWS%diInXc_ik04>8F z44`G$g8{S*doX~OVGjn-GVH+sT88Zx0x}GHFo2d}4+hXO?7;w9hCLWS%diInXc_ik z04>8F44`G$g8^j2#)^e^2+&h?G!(%O>45>VVPg$rV1R7cSj-q0AR9JTH3kOAhK=Qo zfdR5%W1VAQfNa=U@E8~%8#Y!x1_o#uwqFRyFzmqqT82FsK+CWP185ocU;r({9t@ym z*n^WTqLm((wPAlCN?xWAmGBp#zdz9T$tEk zXzRZV6B`BX^LJt5hNn&aE==6Gv|}|7Q}QLriHRGR_M*B-;>M+or!Gv~xU|dEg^3%N zwv@UsapThdQ5Pm|T-q$^!o-bBJ40QVR7lFjlngsgOe(ZEF{$w3#H2!m6O#%9PE5+x zJ25GD?!=^AwiAR z8IrCvH-mDcxfzrT&CQ_PXKn`NI&(89x0#zkxy;-Q%3bDWpewksy#rTpKcC|Y?u6GA zyts(lotLiThFo07?aoV=a)TF_a=Y`=)!g94)!gp9bU`9TI{ z;<9dcUb?ayytuO4otJF`17H_k?U+d}mUoNrvTa~E+>Mv^2n3yX!wbVy!r4GDH0}n_ ziqU6kHZYZ5gqLjtv*ty3*)}jiUWAuz19Ra;c-b~E?OlYIZ38phMR@u0X9Sj&Pp5AE zPec*AB^tLH_a&q+0D!REmyo^#0K)0Mg!DB45YF@^q;CR%aJDZYeHj3RbA1Wv`v4%E z?@LHu2>{_jUqV(mymePX}noaJag@gsgD*wZ4R`a5%BPgsgCQtiFV-aJZ+w zgsgD*qP~Qza5$d6gsgCQnZAU4G=pYa@fqLaN!%lUT*Y?|@yB5WANuWgxw^VXqX;t} z!l2pLBFud9f@WchF!ON>nvE^O%x5fUR<;N;AFQC+*&@t*nu2C&i!k#M3Yx7g!pufO zv$ihG+BK>>d5bW!k4a)@QhiFzbU`MVR$zts>0&h*lA1eJ-mAvp$Sf zgxL-^CuMwy37-#%>+OOurx=1Ac#0v|(We-K9fFD>*m0;Bf*p*CA=nYA7=j&^iXqss z$qgYZKovujr(#oHzGOsl1j);nj2o_eDq6VmsTkqPry_$ZpNa>rd@2gK z@+sf%%BMWOE1&Z7n|1hkOr|B@ZgM&MLd?qJ7h+a!zYw$X{e_rS04T()qCg>L6$%P5 zt9Vd|Sp@|r=450j#H_+YA!ZdL3NfodQHWVZi$csQWE5gnaib8k3Lb@+RRnQjPKJ>} z%qo^-FuxdlA`CF=b6ClAWJDj5jPjWM;7?PVo#f{tyDpurXQ1Kx*gNg~c z8B`qT%aHW_xfztd&&{BGd~OEi*K;!{U!I#m`S08e%4g?hP<}c$gYwON8I(g**Ldb; zP(C;}gL1jK8I+sN&7fRsZU*H}b2BIxnwvqn&D;#iRc`LZ?dWsz1Lj}cJi=!qPX`v|Kpj|=3w2;o zPSk-#xlsoe$QO?wXMY+=)EJ=szz@l8L1B-I14lK&8IcFC0s{@O2 zt`029y*jWgT;P3mQ)_$Gr-R@|eW%tq>grhqZ7C0JNzj(_(3S=5bRODiK|7O&c1F<7 z=AoSxv~ziA=LGG19@=?9yO4*L+X8!bdeLgvNVwR&n1`0z0y}c@&~jT~15O@VZVT+U z$wSL+f$cSUXt^!0nch)!2(x`!;F|?1aff%WZ+Zjd^If zEwH^Y4=uL^b~xst<+i{k$2_#$7TD*QhnCv{TOISza$8`xV;)*H2)ugOyc6SnnSMuY zKEcRu&RvIqxf#>|FgJr5{^e#+gTLGiYUr1nK@I$JGpJ!-ZU!~z%gvyMe0>?TSCbnL zb2F&nUTy|8*vrkJhI+Xf)IcvcgBs@LW>AB?+ze`nmzzNi@cJ@n7brIa=4McXyW9+F zXqTHo4eW9=s9{}h1~sV5&7g*Kxf#@eE;oZZ$9T1dJqtIhJMD0%(X7N_r4jG!R4Y|% z+{>6=6o=zVPE6|Lq7#!kvgpL5&MG=FsY8lROzL!^6O%fY=)|PXBRVmugNV79v`dvI z5S^IR(L*ODb==U2Nu4uvVp0bTotV_gLMJA5q|k{;oh5W)Qilk0F=@9ePY*gVsbhmq zOzOO#6O%e9=)|N>2s$yTqk&FL>P(;$lR6CO#H8IaZ6#Z3M!QaK*@a2FWfvyxmR*>% zTXtd6ZrO!NyJZ(9?Ur4bv|Dyz(r!5qQ_3y7Flo2!!ld1@3zK%sE=<}jyD(|D?82no zvI~=T%PvgXE$3lMxn&n7?Ur4bv|Dyz(r$U1t`NxKkyO33Yj%;QU9$_5cFitK+BLf{ zY1h1u-Ct|fc4ePVKIpIknGr=G2bcnNxdjXHMfsr|h(r*`_eIhBW;QUh{l zPVN4kIdu$h=G1|}nNvpsXHFdsoH=z&aOTv3!I@J>hvV5GSZy@-anfGQsEoB6;Xy5` z$KyGpL}3ISEea#(s8JX}M~}h?I*JrV(9xtYf{rSM5p;AZjG&{8GeRob6h_cdr!az! zK7|o<6e^6Mqfuc59hC|r=;%}!K}V^=2s&ChBc!5MVFVq$3M1$!Rv1A?v%&~Esuf1i z(XB9oj&g+&bhImsprhW&mpV?w6pVacC_4Iiq38(cg`%UN7mALAUMM;mdZFlu=!K%A zq8EyejD=8A(a{SV={ssTYclrd}vIqI#j|sOp8HBdZsRj;>xPI>Oeo-YYA6jplaV_sYTuISZMinxh8C8^YW>kUEnNh_;XGRtNoEcTb%gw0#IB#FTsX}K)71x{@RVZ_2RME?s zQN=1}Miri%8C67bW>i7QnNh`^+>FUkJYGv5MXUM&mRI@8FdJ7Wz-?Sl~IQPS4JHITp4u;aAnjXz?D&l09QsG0`fAZ zLVzoy4gs!=Is~{f>JZ?{s6&7&qYeSCj5-9kGU^cE%BVv?UdB`iaAnjXz?D&l09QsG z0$dq&2ykW8A;6VUhX7Yb9Rge#RR~zwFQqrO=Z*u#xK%JH#;qbkF>VzWigByhP>fpz zh+^C-N)+Q(p`sYKiWhF&$)Hh;TSbmy+$ww&<5n@G7`F-}#kf^8DaNfrN-=H~SBi0~ z;Nr%ej4;KxRhTKptzu0vZWVBfajU3Pj9Z1CV%#eJ6ysJws2I13M9arm_UX2XK6ga& zLs5~*4@E^NKNJy4x%a89HbgO7wk z_jN@bigUuHky7E<8%c*`ZzLU-y^(Zi_D0g-*&9iRXm2DProEALsP;zE;kqzVDr9>j z>9FmMq(iqik`CYANIHajBk3^ijif`lHmi0p-; zqp=r?j>KLlItmv;Nkw2U6dirNP;}(=LeWvz3q?my4x%uQ!s8zTQYW0(&FrC|npR6^Xr(bTsxx(h=Dk zNk?UGBpsQ(k#uzSM$!@58%alLZzLV53nQhXwKtNE*xpDwYI`H;$nA}!qqjGbj^N%% zI*NNE=}7L4v~V#9*4wuh@9ZA$%_G@pH<}aM)z+I6(VZAKF2~zpGpYX?|!beTR zJ8`X1skTqTvEzwKWB;I0$Bm!k8s)?lH$}llW&=18(*_oZ#3G=$IbU46-VOJu{Rsh zc1t}vX{yv|^RER#^GjhA;>%IcF78fk#yfE{uJcz1aF0Q?9<}4Jb<%3b`{7RY7!84| z^V)lH*n|}N>?x)98+V9zD~|SG2#@ySI&RfFJg5oc<;9Inx^^$zszuvz>oPd1tq}i@ z-#V<`iEx~ytuSv~yDF%{u`N1omMFkX5Lm6PgmXcfs;1(Wqxkrs8Mj&}K(!t=!DqFv z6Q9+h`T1}wMBj4CJ8C-%3dX(#?Z()*q?wG;5>}3tO{{3^SUGJzf%T~BLAcVO?+=sx z;IGXkrsWjVa_W@$ky_VJ*O%1O^(FOm^VTCuLcB=YLaBefG1_wbHL_s~+4Gx1E zQqABw{4|0#(rr9%;8}zxVXz&?>)trK?YP&(0S+zQ8{tyZIU*v5sJ9eUb*K`=)3-NRbce6HDOs}{(^{qw=O z-QY`Bt#(o8MzAGyN~I&skq(5Gckq|cR0uscxVGDPO07V;3sJKZ{7`y7cmaPOvA(F5 zM1KekPz#Wzgg%#p#b6`Y3@&rd96wWE5w zMP~)!EoNxk`n&%7wV53vta9;+ieQHCKphz7W?!f=gJ-iL@5+ySyxZPs`sk z^7pL#Jtu$9%ijy~_tf&K#1X&C^6zQ+dq)1AmA~iY?|J!q0l(oaY8|7AR0t0-Y=f;! zM{V3R4IQ{PE625I+jeEt%3-{MT~vN*MOG$1T+*t!2d+rnO1N@MDE#YSJ!zDWi!Ocjx83{KFINBPJvpJHzhahJq#83TLE3B87I4#v%il`7uS-^5FPB|M0l(SF>M^p3~zHA#oXAsJM zvFj3Oc157U3%g9b!HJTWj6@?SL?HvvLPpt3Mj~La3?K>_NC+9zUNRCvfn@+u$Us8K znDLU4aQrL-h(ZPuLdL9@jD&M%89)>=kPtHFyksOCILiQ{kb#7dG4CZK;iOpx5QPjR zgp36*83{+sGJq&#Ao0fTpSQc-S^D3E$=|y`kmwipt{{odbMFe0=wbJ+Ac<~x?+TLW ztM{%Ti4HACEeN4s>(h@5#8H~~<~U08-jpcOq`04;%wVbn0bd9z`wL3A7cM_wMU9XU zf~NfiCEN!K0;~{(gb+02FDT(2SP)=^AS8sKS${!^?$3e%D+D1S1kL#iN_1})1Xv*m z2_b0SUr?g^vLL_;K}ZNe3;u!<-IE0YRtQ4kjotSK!Q#O|t%}tko@3_@wuVV^+^(b^ z95kv}hUAIz?$hIv@uVgbr<^F|fl72j#VDYFAfU>5pc37Tp};7hkPuMQd7u&uKP_ucU5}kpez$l=Q5Kwb@pc3ZJP+$~LNC>F;JWvUPW+*TU zC?o{bLLR7u$uble1r!njYHAJhk@&1>r-_RB@P0OmsYqd?n2V%DDHm3@kxDE;2&{50 ztZXZlSbz{%)48y+%~WCmLSW70!pgQ&i3JFOHJb}7+fXGIAOzN2F05=zl~{lfSo68C zvQ1TD0YYFc3{V@^&t#x+IMsI0CSgA28Eu6(Dc~ zU^zcvrs*m`;0VC!{D7JEs{nx`0B7<8W*V^q1dafl%@3Gq$qEoS0&p%rV5T`MK;Q_# z`TT&HHmv}GBLElj17;ew0tAi#oLUl#LRp5L%M~xlt^y!|SaLwjHf@OrAc0tRK+Lvn zi3lKpIPHL#ZQK$OKmu{b0WsUUB_eL1RZ2=hhvx4V{B}Uw=dDo z%_~!@Q&(%vdPSs5R=RAZr>*pim7cZIb5?rZN-yYi$&!T&ovnN$tF&rll~#?c(yEbF zS~aptt43C7)yOJavdWgM@~V+lwq%v1Ec&tl>7s1OD_io)mb|i*_wn<=X5$EJN0nNP zbtKwliZ;DM`$EI1%W6;3*j7Y4Hyd?s8MQGjq%j4v$ju{lK*X&!cKFe&8}@lpJGL2~ zt%6!C+^^OTTl_?AJR$MTXuEodov4z@Y(uFu>O0llLt%L1FW?)|G0H+FCGC&*uA0(g z7i*(lI|-wMgJ$Enx=)*Bx8h242qr2H_PSKCZ;s43j9RV3eQdR3JEn)cAC@-4Mq#a5 zr;W|H*1g^c?_eX|ejJYNp)Rm?+A!ORwA}!V5|OSK%FTOlSpfvU1uJF{p`CW)ARMFp zxY$E|WaX3E$Az@6N>3mVhnJ4g22de)<~+tx!p7i18Ar*h;P-)Xl-Ty}ALA$w&^XEu zx^a~6Gvk;Zpm9t;=*BU9pBcx@0F7hjK{t+>`^-3I2WT9#54v&8-e<-!H$dZB^Y@u?EDX>%79MotSh!D&L*M){Fyp{f;)87*q=5Tl5=?#SVc6*QU>gT1;Qn}@RmL&6nK0~pe9(>KewhhV#xb~= zFl>c=(2e7MnF&+IF}Rs9?2UfVjpKfq2~)-~xS23)mVeNV<9?Y5Q^qm4nJ}E3c+idG zewhhV#?f^q%y|+FM`<2(VeuQag{(XJ?US(Guj#KTl-G6Y4VhX8GJPTqxBufzZt@a;C;0V61;4)dhPYsa z%6-GW2dncc$*%BSZj)4?ud9R*Q}Pv)d60e+)#1xgHf3$fzG5;@*DEnV7qyx86_a`7 zUWoy^5HsT|Ci5J=5(9K0X4Y3s=HYxL2IxY}oUfS76Z=XG(1n~x-3o#46 zVlvP6D=|P9Vy39`uiD+y#Rc^2qvQ+tiXr6+N&}IV*-@1&h!FKE4@6dGZ&k7&LdcpP zh^)*mt7JihkTo+9S(*J-$$|(WYjz;AGCQx51rb8lTn|~iM?im6rf2rrbuu%Mn95rR}y^JV*|H-hllkleLbcX;+DF zT#o|Fubs%NFI0))XUE=L4f&oHs`bhVfpjf;Hi)eD$|>=7EqgXET8g!O9s0({)H3wF zce34VY@gJlecTZ*zBiPpguyr=jEvH|V4M<0MlBpL&=mM8R=>LRQ3#p>ApI)S59E|U z`qic<$l?l`=4xhjqHXG^`?!7t1`EGI*Rs)lB)CSUS3?2ugb*|8Rvht^5Hl)T7!i%Q zt=?TBU&Hq=r*8fK299fd(m!o}}R?_OV((Y(>H_b+) zC3m~Jn;@REJ+{WGYIe7#*we;lS9gs}8UukOD>Wd%0l+E(CX-2PCX@6*rVsiH^jZI; z-2KFHk4PjuA~M6lmTAVC>2(m{zZ;R)&y5=ykHy*Vp4{1Rdo`vUw#l<$F6B{4`hq<9 z>P^K{a@2ph{x`Dz%2tkA|1V|zl}#GF{?3N&*D*ueuj_Bp{`UHtw4dug-LU;noA&Ga zo3y{Z{wD3``nwypf46DBuD?n9+v{)Aey+c_Vf*)*_Urnaw7u=J2u79v$`wyD->-w9tzrFq@?dST38@B(jX}_+&N&DODZ_<9Qf3#uykDB)D z`kS=Bz5XWcKl;b;@AlVgBIRL=7T{CA7J6bK?@&Z;iEwdAL+t!D|522%Qsgr7K?~cL zB3IQW3(Gl`_Lm};nGRamz7)CaaL~f`rO0JygBG?gMJ`Jkw6J|Ca+%7Yh3!j`%N7PL zY+s7}j6G;!`%>g*%|Q$65T!=;#d~@7=O4?7BYhFPj4?9#UA%d-Jkj^kxuL<$u*S~t zHPrrv@pSkaYW1?l?(j9#)@6;o;cMu@rL3_(d<{LElQj;8ub~G}vc}=?HS~~0);Joz zhJAzj2;BZ}aHkoMl%WsG9lVBpgW`I_*RXF;AG$l3Vc(!Wns@LT_6_O-dVt***Ld3c2KDj7gV(TcP#;n}cn$jo^-;!y*RXF; zA9y@?4f_W5k;sGBuy0TwoIH39`v&##%7fRiZ%`k?Ja`Sd=&zS=zqouX2ZWc)>!rTA z`{ek$C4NDfpMQAwTFx`^;IQMRW7ngjj$MzwI(9v}>)7?^v18Yx(~ez_emizOy6)KZ z=)Hs2TXEpA>(PhDu17Z>yBzJ^K0B_2}wj*Q2+OU5^ewc0Kp`w_hB8rxX8y_C9QJclBY5yP2;pZr2E$ zuN`pQ$XC}{zqtGNu*KcBhb``IJ#29|>0yhzH}@>QYRSVEcPAdUxEt`W#oc#@E$((Z zY;kwlVT-%D4qMzkb=cx=r9F$UI_R*)-8hFW?tVFJakt4~i@Q4xTii`?*y8Sm!xnc7 z9JcrouBwo?-^k?g)%TaL-oN_t<5J>pj=%r>Qse(wbbX!3XZpg7AI)!$zn52L9A7Ta z-|7$Ni_ebVT+bhMu6KPrZ(b#$zpp>KT|_Lhwg=kcPE_ZL@kKz(ukSgxQs zIs0&`NsrIu)*=yx0|m2v`S+Im_0M%G?w{fM=1W$l%=4_W(f%f(`^zW(@U zcN#9Q1pFYch|)CD z&(n+T&hzigW-k~2QvbO*zc@R+;*rZExm@nu^6X42`*Ekc{lRSZLVlciVcie&>UKiy zjdIz;$L8}!KA(O3#rdh6-+X4}B!85BtG4sz_(WdY)k!W(zdDztAIYa&04yg!wF3KA zd3N^x+hh4X>6yLmOD^j>zP>&_`RhBGzg=7(|1&wys;~X}SFgU8+G<|@)!u-=B@2AJ zl-GRy;{1)ibx4{aFXL)2A&vav!{v7iA?oL`bQD?O&SJ7_zc|x>PW7L6`p-xG=SKfI z|FOO+?DCy#9WHHpB-VTK?ZxHkj%B1@a!Np2c6h`$4md)ajdRdwSM+t{e7TH|+WO?)@9qm*rab ztiHMIU#@-omOI{54_d+bAUhlM`5*uCkN zQojEd(L$~vJej}$cKL7Szj&jc^Y7)7;H!%>c~_oXdZr!x97Xu~PhY&6FaAbeB&d$} zgL#u@{%7+i|9XBQuQj_AyI9COz~0QI&{|pE3eYfeOmx#;@5eus-u&pvkAD1E9Oa8| zm;Xuzo4;PrPaesIZ+1=cm1sJ=AOE%f?sIu57s5#k^vCMoJo_uT%=oQbyQUv%f^u5( zTH7p*_{}qYK#n+%URj`CDn@E=eAC|iLm@u@_?29#`D>(emysdh!%1|i>(U*(%Hg<>o@yE*d?_J<-@L}+m0{`FJa2ZQh?|y5w;J5O-pd9MISc={M zwOrgT9bDc}D4kG-f%HiJ;!=N6v>x6a(z{>3w(RAX*1(rv-d@UhKbM~T?Df^}-pWAo zOTDUsa{|4n{&(|7Z_h4XOBXx2kl|~2F4vtrp8ub-KX^O))7gA>J^OaHkk7ZXv)RS$ z_3T(a=d#|Ya$bTKr-r2GzvgC#Q_o*#+EK6yItJ#hGPvdv9e=Yz0y=6X^ zNSFUGdoP(6vW_w@@yD zx@TzJGqes%zQmF*vE)lEDWc`XlE0GiM-FlMGHP7YZHKGr$RmT~BYB1HJl=w9uNswo z{(fr0c)v+J0=LVLAZnA}pFALpf z3t2N1*I;j&Piw~W=O-V}WNQ7>v*RoIv3V|sLNb$8)5DDH`3YJg%iZ)W*X)dw+n(i` z-Ez|GmJ@4_;Ayi1Pn#Wh+U!7SRnO*~c6XpOZr}>d4wNH_LcM>PX8Q$x|1!-cqYW>fqYd)eZ1U24WF%?Sa%U%Asr^RoM%C%*ynRn{>v%*D%hvo zm~tp~e0FjE)=u^#$H&*7$?5JZORpz#p54fAtoJT`(^~pgm%h!GzV)SLo+X6eeEj@( zciO)FY4&C-WoNHxcWmFQFK@IBH_?X0>Dz_vzv4E;UVHWBt+wIz^WShkO!Zqsx)b7y zkU6J(Z7)B5DQ6O`k6p@b$a>~Mx|eT7)|_CHX>?Jr;bU@pgk`cJI)UQcW5G02_uo`3c6kG(yf z{_0!#iLe$*)InUw!=L zs~2+U#F}ebD`yh0+TD4c{1zdG^*3Y{j#Rnx z_e1~t;o83+_}>rK{(ay7zQ6YGd;a&mwSV9BzwfU7`&0k>)3tx!@xSk^{reOD`xE{9 z-=EEXu8#wdM-6y*6X8b>pT`1nuQ`{M8`)(K{`T36U%Z-sF3%L0Kes17$i(2qLN7S| zOc0B+x$f@ypUXX9@5EtGuI6%X_k~>cFF%LLVceUu4@()1PfiwR3z^o61Iurj@}(ie zm3(K?=J^l*;^hzLkK`saP5bD{<3EwRykrC3$=Q--5hUG_q#LX+yAA6<-E4jNTCo1^ zX6wt>j`jC8TVJ{r*5BW3ed)GX|6sHAr7W=i;b!Yg*o@&J?o!xn{igrOJqw$y-}E23gJHAvoBkvBGiUwZuI)bq)^GaH?%Mt{VEv~5?5^!U1J-Z)&+gj( zGhqFu|Lm^qKLgfp`p@3l{v$hQrT^^R(|`8X_MZXkH~nXCZT}gte$#*U*7lzP>&q_E z{|*Ud`)mDY!1}TX)?YV% z4OqYFKl^L@&w%xt{o@)9U~T^yuzu5j4%YUc0qZyY=U}b>3|LpY^c079O(XK~(9_@Q{;L)K+M@^(>mXKM`5iw$BJ#Ryene|)>HD=cH z8`PLt&pANTvj>crS!eXrm|17p)RmBQ$$Yr7upd9?4*fk%fP9W{|w3i4^CFk)t{6l%<@l|qe~ zwNj`tvsMZ;trSMgtd&BInYB`=F|$?*HD=aIfu@zhh?%ugs4=rv3N>cdN}`qN&~(cdN}yJzMnHN7)HP@c%trjxe?8u)GJ@shUqdkxIJv#8{(4(U!lG5>rndK)1*O*yO z^Sj2(a_ZeRW|q_8jV7hz5i`rlX4jZmP5`^c%yLrJHD;C*rHv+~;}J8{fM&NXJ1Q)r_7WcEk)E1{H6vxJn7N6aqe;~KL|`MAdHQa-M+-BLb{CgtN1GfVln z#>`Sat}(Nek88{<<`SajV9&e5i?8qxW>#O8Z%4zxW>#{J{WwoS{Oa`XxF1XkM=z}@aWK^qbAa7 zK|UF1JYr@UXk24v8E9N%W*KN)V`i-uWR`)(BW9L?#x-V^fyOmvmVw4KX4Yy!W*KNa zVrCg=Tw`V#Xk24v8E9N%W~~%t)=FW-%vvebm{}`@8Z&F9P-AAT6lhv0jF?#~g&H$! zrBGvLtrTj^td#;yD}@m=Yo$no=&47$9_@Lw@6mxrhaMd@kyZ-wX{9h? zW~~%z%&e6{jhVGls4=rv3N)=0M$D|0LXDZVQm8SrRthy{)=Gh`qN(6mw*F|$?*HD=aIp~lQwDb$!*D+QWX3L|FLN}@^dTl@br9+UB9CcMEP%k1bf2%ko{8{uAr`w<>Qco^XkL#d?* z9U(_)p*lj2(?WHG9I1us2su`xDn%8cBjj)`R7c1GTd0nZL$**IAqQ<#rMeIgY<3)K;F>=vpcb%gxx7pf!VOhKrQkaGo8rQRZRgq$u2)e&;S zAXG=lDT7cQAwQ!~mBNeA5%N1lsE&|d4?=Z>oYN205pt%Ts#IWvj*wH?p*liNFo)_0 zIqe&&BjjW(RVl>?9U*5sLv@6lgACOXa%M18N67g)Rpp9Gtx0{9$WktY=T)lmG@Z-i z^DBL_j$KyGsS_68vBeQTZNA{kcc3o<^6$eYI zx}^t8>bj)|ODemi2TN+(bt&#v94smCmL4oA@RlAdDe;ybEGcr=rOI1zu%ymgda$I@ zTY9jh)?0e8q}p9ax!Z%T^fZX*jFrV$S&Ws%SXqpf#aLO4m4z6!%s5!6W$M8~EmIE` zYMFYlP|MI!%Z!7CTBaT>)H3y8p_Zu!3$+X#wahqJsAcNGLM>Ad7HXM#uu#j;QOk^j zg<7T_EYvdfV4;?&2Me_f9kt9jSg2*{!9p!l4;E^fdazK-&{4~bgN0hA9xT){^~%1I9RA<>cK)SQx6tunR>8L%g|BFjDv+*rXDQRGWB4gmZ=8|wG17#Y!8KN zYMHUtGGk>i)>>w)EXG>PjFrV$YZ)A^xRBfm^f zeHqj;^8L%hZE~T855VW*jWkGWB4gmZ=8| zwM;!&sAcG=WyZlmEmIE`YMFYlP|MVVg<6J=T4o$9)H3y8p_Zu!3$;u=Sg2*_sAa~% zLM>Ad7HXM#uu#j?gN0g#j#_3MEYvdfV4;?&2Me`KJy@t^=vK>e4fB6_|6%yE)~z;v zC@!n`p}5D=B#)&GJ(ebUEM@4iG|6Kr!zQ+p_gFUHV<~x$gJr|F>%p?&+x1}C@ZIQE z@*W4vO5XKgS;@N|EGv1}gJmV(=vML`2g^#{^i)>=l4T4o$9I~4b2f`wY<^1(taQx6tu89Hj2aj;O! z)PsdurXDQRGWB4gmZ77T83zlsOg&hrW$M8~EmIE`Y8g6enQ^dC%hZE~TBaT>)H3y8 zp_ZYemKg^NwM;!&sAcNGLM>Ad7HSzfYMF7cP|MVVg<7T_EYvdfV4;?wqm~&53$;u= zSg2*{!9p!l4;E?}I%=75uu#j?gN0hA9xT){^cK)iQx6vE89M5jaj;O&)Pse3rXDQRGxcDho}r_j83zmXOg&hrXX?R1 zJyQ=B>KQufnQ^dC&(wp3dZr#M)HC&9p`LG-|490$JQM3m9!}casV>jUkY|WBzhFI= z$JRGLR7LnS!rch>BHWMgAi~24j~GgMN4OKABV?K#sv~5Q9jYT_iXEyWq^haP{5nEM z$Pd7wIzoN|4%HD-%Aq4jiE)09j*#DmLv@7wIvlDa-I6_Cr&&HuTLVh?7 z)e-X3aj1@vA@=!~_6Q3-*%hH6s0xCiAQ%dQp&%Fvf}tP~TIn%#gp8}PfFop74b>4c zriSVW8BwWP=>cJ-$Iua0dQ=@@rAO5fR(ez&VWkJvN{^u-BdqkOI>Jg1 zs+Ar?M_B1mb%d23RYzFqQFVls9#ktmhK{h(qv{ANJ*tkd(xd7KD?O-IdJG+5rAO5f zR(ez&VWmga5mtIot@Ic=!b*>-BdqkOI>Jhisw1rQpjzoMbcB^2RYzFqQFVls9#uzJ z>G2W{sSAdJU?_FLP!J5IE*J`eq0|LKK_Il!W9SGgJ*tkd(xd7KD?O@?u+oESrN___ zawN+(Sm|*A-wG=|s=gIgdQ^QYtn{E-=`nPKl^#_`Sm{x9gq0puM_B1WwbEng2rE6R zjIf@6s*bSIgKDM6&=FR8R2^ZZN7WHldQ=@@r3ckYkD(*1^r$+*N{^}|tn{cl z!b%USl^#P!Sm{x9gq0puM_B1mb%d23R4YA(jIf@6s*bSIqv{APyAC6% zEj?Eqp{3`lBee7yRZGu9M`-D}>If}8R~@0H=c*&L^cq!5&qGIO>AC6%Ej?Eqp{3`l zBee7yRZGu9M`-D}>If}8R~@0H=c*&L^cq!5&qGIO>AC6%Ej?Eqp{3`lBee7yRZGu9 zM`-D}>If}8R~@0H=c*&L^cq!5&qGIO>AC6%Ej?Eqp{3`lBdqi=7U}`#FBl4fp&%Fv zf}tQ73WA{^7zzTRl^#P!=&0ulI6_A~R~@0Fo~w?~QLj<0^nkF^W9SGgJ*tkd(xd7K zD?O@?u+oESrN___R(ez&VWmga5mtIs9bu&h)k=?{BdqkOI>Jhisw1rQs5-(*52}?O zLq}NYQFVls9#uzJ=}~orl^#?pJ%*03(xd7KD?O@?u+pRI2rE6PR(cE_VWmga5mtIs z9bu(M)e%;DP_6VBI>Jhisw1rQs5-(*kE$cA^e`4$=`j=pL#Ydff?z0h!B7wkr7jo> z0-=>2Ln%Fmj<8XWsv~UFqv{A7^{6_+N)M`)9z#c1=}~orl^#_`Sm{x9gq0ptD?Nse zu+pRI2rE6RjIf@6s8)Im9bu(M)e%;DR2^ZZN7WHldQh$O7&^jAkE$cA^r$+* zN{^}|tn{E-=`nPKl^#_`Sm{x9gq0puM_B1WwbEng2rE6RjIf@6s*bSIgKDM6 z&=FR8R2^ZZN7WHldQ=^urT6*A#GkhmO#)cGVGD)~-52%i2{(XjwO^mbHhD(6V;b z5n9%+Izr3ZRYz!9H>#GkhmO#)cGVGD)~-52%i2{(XjwO^mbHhD(6V;b5n9%+Izr3Z zRYz!9H>#GkhmO#)cGVGD)~-52%i2{(XjwO^mbHhD(6V;b5n9%+Izr3ZRYzD^-)LE{ zyy~-{tTCKFk)znp8A|gRO7j^?^BGF>8A|gRO7js~Su>P9#Ly8|)>Iu~Wlhx)R@PJ< zVPy@~%9^1gtgNXz!pfSeBdn~cI>O2ts+BcEM_5@?b%d2QRYzD^Q+0%uHB>8WhK{hZ zrs@bQYpRa0vZm??D{H7$)(jnCWlhx)R@PJO4D zsw1qdp;}opbcB^PRYzD^Q+0%uHC0DgSwpq5X6OhjYpRa0vZm??D{HEbu(H0@vR--h zZb4b&P{GQYp_Da4X+A?KYlhN%hEmoHrTGZ0tQksK;{pLa63{uYFXR}V1H0-Noddh- z7@Y$*s+Be{R@w|5VWmyg5mwq%9bu(S)e%Jhusw1qlsXD?+o2nzMw4qvQ zGjxQNHdRMhX;XECl{QsJSZPDG(q`xgD{ZQdu+paL2rF%>ju}`#3S5|a4*9B2oEAWjPQt|)OLhB5k8I35mMKoIzs9?R7Xf% zQyM~PT}S8$x%enlN64i|p*lh?JPOqja@i48sp|+G zA=ey*>Ik{wC{#zt^+usOLasKVDs>&9Bji$}P#qx`8inczxy&e3N61A+RHd#Xbc9@C z6sjZS`l3)BAy*fL>Ik{Eh^p1~jn?(hBk?Wj8V3wAX20-bYH2@JX+J}0KSOChLuo%l zX+J`%YlgCm7&<}@#Y1(39EykP2ssoF)e%IkcAs*bR_rs@c*Yp7P& z3>{&0P1O-r*Hj&0bxqX~R@YFit{FPQ>YAz}tgfj#!s?o;Bdo5WT3s`Agw-`wM_64` zb%fP5RYzD|L$$hQ=m@K8s*bR_rs@c*YpRa0x`t|X&Cn56*Hj&0bxqX~R@YP=VRa4F z>YAY=tgfj#!s?o;Bdo5eI>PE2s@3(a*7eXs@h$2aM+;Wh45j@HrRW$+`x#2nF_iW* zl%hjub>IkcAs*bR_hH7=q&=FSGR2^Y;P1O-r*Hj&0bq&?(nxP}CuBkf0>YAz} ztgfj#!s;5T)ipy$SY1>IkcAs*bR_rs@c*Yp7P& z3>{&0P1O-r*Hj&0bxqX~R@b;h*rwR>!mKyF2jXv*XZo&iJa2IG)8oy(ea}A^Xmf90 zE0(#i>oTwKSZ2c>%gn-KnGbs`bBiXniMPix^Y&O~FdhfXCf=?G%ckD02g@ekjc&7V zkAtOGUXf)Ja9<|2%ckJ2$9CBy-1XQln}#>K&BHwomd(Un50=fvT@RMc#$6AV&Bq(v zCgdIm%ckV62g@eqt_RDe<*o%p>#y6eHRsd}T^T;1bf*=*hQVA*`#^2A2sIOoMu`U>eY28jNGR zU>eke1=FA&ESLuMV8Jw?!!#HN3#LImSTGIh!GdW}4;D-VI!uFcuwWY0g9X!|9xRv! z^cN6(P!ASN13FBDaj;+-)Pn`npdKuk2K8XUG@!#Y7zYcc zK|NS74eG&yX;2RqOygEfqh|^+xoPlFM>mSG78hgPD8_0UjCG?Jt7$OSjY165V63LW zI9McN6(P!ASNgL<%F8qi@HjDv+E4eG&yX;2RqOoMu`U>eY28jOPl)1V$Km7EFVBuwWX{VH%8s1=FA&ESLuMV8Jw~2MeYF9j3uJ zSTGIh!GdW}4;D;=daz&`&|w;kg9X!|9xRv!^cN6(P!ASN zgL<&+w1XUhyxnkmGX5k)Ge3F3V|P0X(HsLk(Q|(u%XtWoWy0mLoQd#Qrd%G&xripV zlMx=v#Li%p>96s`x$PExoYEIUon=ysmM<6zmD3fF^W=PFzemYuC|Jy>?WqS5Vy zg~!3NQx>iV%T8Lj9xOX;;d-#_#6_dqnG27DW#=wj50;(1a6MRd{=)TO*%^#Rw^JA% z2g^=kxE?G!jp2H*>_mp^!Lm~sjc(^MJPwwf&2T+fc0R-PVA&ZB*Mnu}G#VYQaigxW z(fni^*T8`fT!XQ06=QV`#=2FE)irM92?BF_g1{5~<-q@@&Vl9N9E^1@GFInc96UG& z_29uds0Rzq0Ugf4I9PBF>cN6@P!ATIgL<&w9MIt$jDrQ|pdKtZ2lZgVIj9E<&H)|H z!8llO4(h>zb5IW!oP&C>;2hB59E^hn=b#=eI0yA$!8xc03(f%@&cQfXa1QFhf^$$0 z7Mz26u;3if;T(*E1?Qk1EI0@CV8J=42Mf*t9nQfxSa1&N!Gd#84;Gw*da&Re(BT}n z>Kq$QQnqmp9R0vK80%IsR_9=>Tg6zNgRyQEV|5M0a1F+~2N|ntFb)=6gL<&w8q|XY z*MJV!U>q#C2K8XUHK+#*u0cIma1H2i4aUKOYfujsT!VVB;2P9}1=oNM*I*nhxCZrL z!8ND{3$8&uSa1#Ka1F-6f@@F@7F>gRu;3chg9X=s4%c8DEVu^sV8J!02Mex2Jy>uJ z=x`0j!Gdd04;Ea5da&Rc)Pn`rfDYGS94xp7^O8Hb32 zrDq&M50;*B2t8PO#v$}z=@|#=dd4B*VCfl$(1WFC96}G4o^c30SbD~Rx}I@}I9Phd zA@pGB8Hdn=rDq&M50;*Bpsr^eA`X_GaR@zFdd4C2VCfl$(1WFC9H{FVhlqovXB8L%hZE~T855VW*jWkGWB4gmZ=8|wM;!&sAcG=WyZlmEmIE`YMFYl zP|MVVg<6J=T4o$9)H3y8p_Zu!3$;u=Sg2*_sAa~%LM>Ad7HXM#uu#j?gN0h=7_Ifi zSXqpAd7HXM#uu#j?gN0g#j#_3MEdBYA?LjSb znbp_Zu!3$;u=Sg2*{!9p!VM=diB7HXM#uu#j?gN0hA z9xT){bks8AV4;?&2Me`KJy@t^>cK)SLq{z$4i;*edazK-)PsdurXDQRGIZ23<6xnd zsRs+SOg&hrW$M8~Ekj2wGY%GNnR>8L%hZE~TBaT>t>tGgJ}&>S-d_TaPfz7KrFX|y zSMxU)mnU*x?+1D3&&6DC8hW>Q_j+;pFRt`n-}h(7CyRHB^XvJ=8~fwpM+cyNB$8%ZNP=br`Oz4ij;()L}vomO4!6!BU3_Jy_~6 z)YV}k4wgDh=)qEl2|ZZqFrf!a9frC(OvJ%bhY3Ac>M)@POC2WkV5!4USBHr>Sn4pL z2TL6$^kAvOgdQw)80zXU5eG{hCiGyb!-O6zb(qkDr4B<~9VX&nsl$XGEOnUBgQX4= zda&RyH|j7wzZ!g6hrw}6{fU)iY#BdnKy0;kzOV2HY z9xOe#5PGom+(PKVg2N!c&PTWm9EN(Z;4svK1&5&?EI15wI1J-p$$3KO!eO{fY!@7c zdTbXQhI(ul90ocZhHrg2PY`790jT z9ENeQ;4svK1&5&?EI17HV8LOa!(kW)3l2j)Sa2BX!Ggn34;CB-Ivj>^u;4J%g9V47 z9xONv^)Y7;7am);+*jE0MA80mN_^##)Jtb#F5c z7LH-42MfnA)Psd%80c^q#=(NaP!ARyhI+8zFw}zuhk*`wU-Vdb9!tOXSa=>wzxP;JO>Fh-vGjY7gJnky zt_RDG7+epQ9Wl5bEUV{6w<89RgQaIZ*aoX-UnaK8>e=Uc3C|)y4ADCv0YZruE##KdUicnR?n^n%j&t&t)4v&mesTC!LoXG zJy=%Ht_RENxzVkjJr0)Dv+KdKdUicnR?n^n%j&t&t)4v&mesTC!LoXGJy=%Ht_REN zxzVkjJr0)Dv+KdKdUicnR?Dsj3$=_R34K=JGyfGqS=6;3GFBF2?T3t&#aR11V`U*m zEi(?5p23V|f@Nc~uNy2In_Ul)H3y8 zp_ZYemKg^NwM;!&sAcNGLM>Ad7HS#eHENl$vKVVWWUMU4+7B5ki?Q}Y#>zsBT4t<$ zo^h}+E>jN{#%1ck!njO5Sg2*_sAa~%LM>Ad7HXM#u=Ljmwi&gIWl+nEW4lnx)MFo_ zmZ`@+L@iSf7HSzfYMF7cp_Zu!3$;u=Sg2*{!9p!VM=diB7HXM#uu#j?gN0hA9xT){bks8A zV4;?&2Me`KJy@t^>cO&F_N$GhZ+I*$kEI`aEG&kGT@RMkvg^UJ zT6R5HR?CfUwd`@Qtd?C5mR!B(``>EWmx=GoYT5PpzO0rT-D=t6=o?nct_RC%+4W#q zExR5ptK~+wTJ|_tR?Dsj%WB#6U|B7@9xSWnMz>n_I9OK8t_RC%+4W#qExR5ptK~+w zTJ|_tR?Dsj%WB#6U|B7@9xT){#%mjw{knT)QP;k~SXqp z)H3y8p_Zu!3$+X#wahqJsAcNGLM>AdmRyPJ`yaK;Wnv$qmZ77T8OQg9TBaV~7iyV$ zuu#j?gN0g#j#_3MEYvdfV4;?&2Me`KJy@t^=%{7J!9p!l4;E^fdazK-)PsduhK^ch z94yo_^4tbK#AvKVXMV5}_0+7B5k3o&Y$vGzm8!9p!l z4;E^fdazK-)PsduhK^ch94tG=ZrXra<}$HesAcN0U8rT~sAa~nU8rU1u@6zp)Psdu zrXDQRGIZ23<6xndsRs+SOg&hrW$M9_tLpuGK`mn$)H37Php1)h@qM9|smJ$)TBaT> z)G~C`GUH&OmZ=8|wM;!&sAcNGLM=l_Ei(=lYMFYlP|MVVg<7T_EYvb|)H35>p_Zu! z3$;u=Sg2*{VExf-_FrEt&#yl_TYR@ToB#IsyT$y^<(d2Mj<1&|SM$Fke}3}y$K`)9 zo8fsxve3oJ^7>|ed~KKV{P()DF0~^|>F3ktbGP~2Yd-gz&x7Xku=zY{KA(JjW9#oU zpHG|5-R5(z`P^?l51P-z=JTleeDd{elLwzqoB!TzKKGi>{pRza`8;eskDAXX@_O}u z&aFN^Ia!=7E@hv{+g$H#xh!d0-hA#hpL@;ce)D%HRN6qIGd2zb!!RGU6^SRr6 z?lqtL&F4Y$dDwg&HJ?x9#m>mnYh%_@I&5TGh-+E?5ni-L1Mx>b$X=X&4 z8Ifj2q?r*(X6a8m$?m(i6F0k1R&RD;6X`pUq3K)35$XGn5$PMo5$U^+5$W5-5ovR< z$@+$6MEVYMM4B0qW=5o$5ou;bni-L1Mx>ds$#{1&+YC)JBht)>G&3U2j7T#h(#*HZ ze;}PltqkvIwldI{$65zxAn)UYBCn7{An)QsAg_-^An)NrAg_)@An)KqVDFu665d#5 zNr=E+2djUQgi!2Nu&PKxDE1myRU{!4Nr;NIw@~Vz?2UmM*h?-ou(t(jU@y4Tz}^(7 zfxX;P1A9xL2KM@hKb*}L=ck`7-n?0yT+d&BxM;ne5hp%9Rqga{-d0!fHK5+aa<2qYl_Nr*raB9MgKA59<$p-4gm zk`RF;L?8(fNJ0dX5P?0!SBAcI`vW(iVu$E6d3DdoO`ZtkZZ`ySD=7lG&kcdxM2bM} za6=%sk0KBpHbicsLm&weNJ0dX5P>8_APEsjLIjc!fh5F+NJ0dX5P>8_APEsjLIjc! zfh0sA2~jJuhh<*Bw| zizOnxffEl znGtDbM4B0qW=5o$5ou=hOnZAHOiA9nXf>#>VAR0g+o*xOzY2=Ivr!d!cNG+SU!yAW z-YO`P5Vd2kQPe-lOR=EXD-@fAQ0(=IO+qO4>cl1?6iJAt+RNdZgi!3=b4@}h_TITB zAryP(T$2zRkLz^*quFfr(zPqytunKdE8}ekdnB{EMw2;06UmIOiDZ7zL^7LeBAFXB zk<#!bYGy<-18E}73{5j5(#(i7Ga}85NHZhS%-AB$j7T#h(#(i7Ga}85NHZhS%!o9z z9r%9n{>AcK4upUG_KV~1^mF<4i_5N|(nC11!x0=0qe!?aV`IYQa-ElG}xR6(~$u`Sv9cM!}?)&BS zw-+C-=XbX4)w-1L2e*}ZS9jT8tV?@3WGCL2@!y}#o`3z@AN|Ew&z{@YD&6Wg%X9np z+Wx(i7hu@8e*EEy2#>BF%kjhY^4;RIlMDGmkL3vS!MVlw~!?ehF|{^I!U z`SSY1sm!nBzrI{v%E6cH+J6^+e)9F=?04V%WH$TVH}gl|UR*A3FV3%z&mPae*LB~; zx|aQNekHTjlWW1)-{0GT?UN?g&IGx3np{sO$n~_zwL3ws-6q%G1iAK_T>BH`+HZ0l zOpxoK$#pnEuEQqR(FD1U{=w{T|A({auhOIcVD|5ca3KG~|NQ_J z5{UNjNgz)Xh<5!+AiD`fYhn_}UINi#nFO+*K(vY`fgB_dEw4!+hY3XMZW74RDx@jw zC(q8`{_dNvW;6LbTg+cCuD@R_&gZ|gQRW*A58v^W?#acw_ZR1Kcypx(B{EF)3?v1) zePAib?E_6gZXb9Ga{EA3klP2Qg4{k(73B7Tt04E$f7^TK^LNXulZy{mpS6x9N8H0K z`Frkr+&X{HT~FKP|L=PD4}L3ZUftZxSVrt10rc#k?EyV|XiLDNcNe`ozLfnle|vfH z{q?u=?-$Fr-*R?1Vo$y4-BW8hj#RskUuoWM9EEh4f;+<9;EV+oGr3XtcVrc2X zl8YExda&do2G`{xhE^Obxrm{q2TLv#Zt2023x!*Hu;d~J*X5xCtvFb6%Wq2$mfVon z(t{;8@U-+`$wdsV%SHdKI9PI_a7z!CTwK`FgC!Rvwe(=gMGUUXMGUPtSaK0VOAnS@ z#L&`%B^NQY^kB(F46e&X46Qg=auGvI50+fS(9(k?7csQ-V97-cuFFLXtvFb65kpH4 zmR!Wp(t{-zF|_nx$wdsV%S8;WI9PHKLrV{qT*T1QgC!R+wDe%f1xcb0c@*(l)8GlQ z(N?8fh0CMh8jN+T80%Is)~#Z!Tg6znim`4LVz>t5V96!Pt!08Gmn66JV96!PEj?Ir zNwVv34Y1%EjDrQ&pdKu^2K8XUHK+#*t^pmc!8llO4eG&yYfujsT!VVB;2O~38jOPl z*PtFOxCZrL!8ND{3$6hjuE981a1H9gf@@F@7F>gRu;3cd;TnvC1=pY+EVu^sV8J!0 z2MewN9j?JRSa1#M!Gdd04;Ea5da&Rc(BT@4g9X>19xS*9^OoMT-U>eke1=FA&ESLuMV8Jw?!!#HN3#LIm zSTGIh!GdW}4;D-VI!uFcuwWY0g9X!|9xRv!^cN6(P!ASN z13FBDaj;+-)Pn`npdKuk2K8XUG@!#Y7zYccK|NS74eG&yX;262Y~-Be-SJOme>k7X zBhosv;Ze^#6K2nJxNA=KM7FJPqo#UW;yB~erwP0py?0wX7G^wZ&w{=4f=@C~H;#C> z74Nm;{Z@R?iVs`yk;m%B%qdTkYsJCRiC-)eES>m;9xR>sg&r(*W9oVc7jdxEjYAKX zx^d{iQa27gSn9^q)r}(#mb!81!BRI4Jy`0-p$ALdn7X=g#KBTG4n0`v#-RsG-8l4M zsT)&QH;y=1>c*i5OWip1V5u929xQcZ>gvW32TR>J^kAtQhaN0-IO1Tb z8;2e&b>q;3rEVO0u+)vIs~blgEOq11gQad9da%@uLl2f7!s$~A#5*>3$*sHthn4US z#=32cb=w&0wlUUiW31c8Sho!^yo0gsN5;Az83#*`cN6{K!zFda&Rf)Pn`@pdKuE2XuG`<6yx%s0Rz)K|NUT4(h>zcR+`CFb)>H zgL<&w9n^yb@1Pzmcn5TN2jgJDJE#W>-a$QB@DA$1f_L1icWi#hvz2$?=n~$+SnHXw zZX08*XU4j1jJ2K_>$V|=cQ97(V66L*aj@VW)Pn`@pdKuE2XuG`<6!A5kSurymx=9y zcTkV*f_G4l?Sgkehj%az7QBOcu;3lkg9Y!P9xQkVba)5jV8J`62MgXoJy`G#>cN6{ zK!zFda&Rf)Pn`@pdKuE2XuG`<6yx%s0Rz)K|NUT4(h>zcR+`CFb)>HgL<&w z9n^yb@1Pzmcn5TN2jgJDJE#W>-a$QB@DA!=UG~mXc+LBd;yQRdDSPvInLv9EaB84E z&R78TDWP1MezpCs-o~J%1!#?QAdkf~J(dpSv6!aE(t$h{)AU$6P!pR$dn~5uaj%lUEc0E{T(5?r|47$%lUEc0E{T(5?r|47$%lUEc0E{T(5?r|47$%lUEc0E{T(5?r|4({X*6mgJkeRC@Z!C|Kz;z?`ZCh8!Jbqg7*gD}=DWULOtSho-{ z9E7nt2xHxwjDux|c&-P_4)I(MmL1|XIvfN!;UJ8I1qY!X+XV-q9@_;6p&r`>2Z0U; zVH_+t2=!pWL8u1{4njRxa1iKl5XQlRgHR6^9E5tX;2_k41qXo+2Vop6I0*G%!9l18 z3l2g(Sa1;Na1h49f`d>G7950nu;3ung9QhH4hLZzEI0`DV8KDC2MZ2DJy>uM=x`9m z!GeQO4;CDRda&Ri)Pn^Fxm5?*_8@302f@K79E7n}HDldE##+^kbqg75RWsHtL<|RE ztPa9h_a@_D!9l183l2g(Sa1;Na1h49vPojYf`f3G*e*B-_1G>r2=&-5I0$q&2;G7950nu;3ung9QhH4hLZzEI0`DV8KDC2MZ2D zJy>uM=x`9m!GeQO4;CDRda&Ri)Pn^Ffer^@94t5p^xAk@M7CvuDC$E7~E;?C8=SM$z|ziTcwy|Vj?xs9@k@Nh7`;cYct!7Fq%YBfrmqu2 zq%Y7zq^}Y~q%Y4yq^}V}q-<;-Ubo52(D15F)ig6Syk=81%?u5%*i=n3L(|OIKD>~R znW5puf6NRGFa2X?Xn5ftGv6+MA$P7ld-01`c4v%5J916n>4&q$)m-jbeg8r3ig|bO zo!nE&H=G^IJ)A%Pvialu(aw)|e*D8HJ3oAK`1sLm_KWlD#anq`kSzc6o72mS)8;Wc zUtJuZ+U+%ue*6RZ|Ht|Sf$Q1q)rH*7DVGTNO5e6uI+K;=$7dIE->$w}?d{oxoK>2C z{OpvsiO%0#Uc8&XzK|=)-(OtI9Xx6~a$@Ft+ZuVG&hovkd2wmaZEDaPVsAbT_I69` z-}LQd9HGsRU+W#po!u-hE^oNoU=MH1y!q_mnYWuW{}F5FbLr=;$A?LEeg5RvA1>c6 z{#5RYUh^WrCs)^VRNZS`b4?f5{UDD&kTl;P-)xu#d(#^8^MyR%Y{N9zLDra;7iVX3 zlgdk}THXM!J!W-t?&(U+1H`&Z%c~ME7jG7qi*tFAqTR8*0ifwO0|D}EgwLORbNu}V zpr*471lc~*hil0b2wts!q*wE1$nHK#JA^(`YwLX2VNLsPx6jw^BeK2A=p%X@$Qv#1 z+1Ty63p%Fkl{fNx_|VNM<6_!|I$Xr zpUih2YsKs&gIQlv>^y5*HkkFLiQcqx&tSHiA@4rjr3VdW-Bs=$cy+r;cj>zT9n5yt z4`$s}?}EDBqPz56kbQxJ2D5IaY%tpyG??|}3)hi+0|v9ceCBw2%=*CNx|t3bPqV@7>E-Cb?5PcAPm{r{FDZ7OwJjUW`qD&idV0@bwwfXDKHa77 z4gqT>Ox;!PjxpVC(p~y4KnJs@>j$&$s&_%%ZqZ%(E=Vo!>7c=^n<*R2B;SCUSzo?z z9mzLfFzd_L?jyZ}*=n-wx{K}P{=uvdI<5;f(7wT}54uTr8akM*vhN?vo(>+&`f|3r z)zHDLFK4@J4I0c=6Hd{+1`TF?;7z*NpuwyUJg%GRfU%nmX1j7CeB{h**9NoQWH9SX zik)X|%LcQ)G|`)O?-|TiGvwW;yY$^5z#44N1zj_&byvPS+H^Zicj>z*9oBZ&4{P03 z?}EA=q`UN8kec7_pkb|>DI3-#-+*DQFJJhN}vP-K0AW9oAOa_YZ5kgNL=gob7HkbXe=l+3s3{hPBm%Q*^IE!&)DBlP)%B zSnC6i>t^c2d)ctIH-1>#vtey78P@ueV&_@gvSF<+P4uR{dxo{u40-qIE`4_hum;~Z ztaVquJKA(ROn2$KC>_@J)(>mlRqukj9i+RogMKpmqxsB#7E}k^8#K0c(`93ue~k*Kuqo_YZ4* z&~aU;f%Xk+eb7z1)6ijUm3{xPwm*1S>&w~hRzruizMSo@HE38{O*lpO8Z@l+fj8-5 zgNC&}@VIWKPJECJYX{?pwF4X04w7N5FDZ7OwJjUg`qD&iI=E+8Tg{MnpYGCkhX8Bv zeZyLJ<-4Ozx5IRozKhaf?O^?|)?M{3sM|rhOWy^l`5g=z*1DOpVNLQ47}omoh5tyt z0mE8fzIJcv9oANpZP#&ZC-)C)eb8}TsDbtkYkkm7y3^2MZIylhuy!zbSnJE#?p8yG zwZ5F~t~F>_TTM7c_Zl>;^?^6(VuOaYKJd71rcQjA4Qq$vhqXf+)((?ltuHBdp0zC- z*80*!Z#ukZSX<4Icc1RkcZUFL@O{HtcjddIO}E2zm%fYAVeN4Ju-0AmE~wi0*P1wLb8;Zl+Fr zlnrY~LL~lB}XINX!kawT%(szddYw&%;T6g8UqfNKN zbeF!1(qZjr{jk9n}|?au@MEw^PqgKP>bi z2J-%Rc@_G_x!gYZ{!(sDJwE-x{OWr7=FR!y>gosf{R3`IFy%clG?q$K`A3`pe6!>(4GOPvz~k-^ zH?7a{fQM7*{+Gx0>h<}3^%KCGY9PMJ0Nz#u@r4oiLUyS<`z+g~d};lRl z*6!o=W*;rE=QloR3%Wb~#S?q}+k>_M-+~ppc5Jg9JR#=Mn^yOJfA-;OeziEcI6p;) ze_Yh#y(MNlpQa`FR=g!Lvyi+~VTe@da(hVni zy2nRO^eS62ZlYJv5}gz5Y%tO5Hf8N3Wc?5xz;P434S+D80FImJZ2*Mn5IB0Gw?bSQ z=-2M!^#=~of{_!w30lzI>7yrl6SN>kPwUuIP4re;HvH6v8NHU+R1>`oS`tSnwoj&- z=xxxF?zc1DL~o@jn->qiuIVOv6Ev;+{Y^K~o1kf}FLcO6Z-tl~o9_&n==G&*?YJQm zy}oqajqRW4t>#J<+&`{ z{ft>T(YudXInld^IdY=c%`(|UPxtu9iC$$(#!d7JTB37;ryET4x=mR-30d#D0US5c z+W-jj3E;Si-UdLJj=pAq(9x5<73${4tI>jylf4OA(B1K)CwmjLAVyH@+*3{VR$4Z0 zvS%%sYO=RMOX4WSS~AsSZ-bU}zn$qOdn--Zym)ME7FV2ZvNu7~y5HY)lf4O=*7`z+ zO!iiY$z<>8kjY+Oy4H>xGTG}(*WK9u$=+(d{NTJ<`u@qD?vnn=ULO?ug!8Up(B8>j z9~66TI8-N7y}# z|75QZytYsEgZn3Yec-kIDh2OWPxe-xR;Jz0n3a>g`J1M_C- z`zLz3OZq2zeNgNZ&bfv`dnbB*Q0%$kP@PEiPV`ox_fPb8HDB*UuPS-)f2syM|bLgV$8~k-hIr< ziQYZTkrTacmdPf1y2nRO^eS62ZlYJv5}gz5Z7|X6Hf7{Q55RE~y$ygcpV-226TJ<9 zFdYI%PxMxZn;)x23r0@#CTKx-r;ncKP0)fEJ*}TjHPKsX*|>?GwPdP^-Ucm+BNS`N zR1>`oTGIV?rkm)kG-dPRv2l6QiQZOC(`y7~XBV&Kc>vunak|;wR_#O6THorB+1?5< zneFWjneFwZYwfrpv%S7_-Hq*^?XBj^kItK=@1O1IF6p1`^+B;uIPn?=?VauQL9yqC zLv=RQJKI}@-ap&h(|o{-lX|@XM275THQ$}UH!AY)r5okQ$F`maQ|$t54^Td z^@ICodwt-w{VE0TSI_oVo@lM3iZLr^d-pLbXM6WBN6z-TStgt9=^h_B+pBEJxY=Go zOLStezrk#;+mw;BJpjke_BH^*d}0g7&Gt3`!gL56J=*6Q_c1^Xi4|mnQpeX(v;1M$HwJJXL}Pg zt^55=H_@A*X{|4G$V6|2m`wEchfMVP(zSNnkcnPjy6(pIPxMyvfz!=XBn>YeDVLhqmG?Q6c?iC$m6R&UaLy%W8@e68-J^R51g z-fF@@{VAXJD7b&3*9TtPr~1MD6TLq0+J2RS52`16EAM#F0mYb=6TSPGl@q;tm?I~8 z-7J$$^mLDpoaj}yWZXorpd~sdIM`sK*KNwki5`ICCVCqHVLq{i<0g6=0AV@=j-KeP z5H~+ojTVfY=uOaq?oJ;)(VL(JF?w1*n`)xB(z0bR z?Mye(TWQMX#be|0q!Yafn%4dPrkm(Z(6rVUI%J}^LQE!l2SX-$ed$^|ZpcKhFI{(I z`zLy<`SJtvX6gGUdb&&cCwhHQ>=VwphCzELdVNsrx#3WqNcB$iR-yM#^bRy%??kUJ zU#mB1zTSymU%pm%()m{ZL~k|Wp#Buo9=k?h#Tw1;l-@tv>!YvjSV6xJ+&|mv1F!8| zDfqB@wzu-?Bi+l!teoxL$E=*~-NPI?+v{eTY__L+eB^AevL)kYdj&1giNWCpv%PLp zM$YyC95>tB00{GmEgU!7+W-jDA#n6;Z-uyGj%)Yvdbf`jjGXOF(1PwxA3fWfpan66 zT0fg=wztxVJ_H>u@&-VJD z*eBzly|cYODE8cNsLrN(XM3yA`)7NHny+`Z*O#x=n>1hVY_Bh0t2^m@tADn)ns88m z%BMXF?w{!Of!Fq_esKRpuMfPoU!~xq>WSXU%K&viF=pjN?>=VbMDHHv$cbJz%VZNh z-Qy!CdX+61H_dL3gK*p6E@`f*3umV^1~FTWQ(2iJrA&s)^nPEr}x(Yspj-y$xE@{dT6C z=&dwm^Ww2_dD4mA1WoIHf74C$CTLpg3mr1iTOlSBy`v!$y}op<9XDj6*O#ulvHcUh z)qMGZd9(EW6FuD}{S&=DDE0~GT*IKf6TLnt_S|r&PNaG#daKa&ha6VXny+`F*O#x= zn>1hVM6WMjt2^m@tAC=mns88m%BMXF?w{!Of!Fq_esKRpuMfPoU)>AVBO`l>^v=iS z$!zxP)=PEod8aOW?8+;T?Y)_!-XgtoQ%=N}5ZicLPQ>0P@rCTw>z=)uz9n+=Q9GJ& z^YBgR?)Mivw-4Wh_#*6WTBE!7$~#SlbZ@&x;Im_Sb-3<)V8{0H@z~hcAdc02Z1)~d?C#a^-Ft<&UH8_F9^btuXhL_tkMG_SG$FnSyDw;T_g=X$dsO!ZacuV< zPmJ9R;@Ivzp4i>1-FrN-yI03|?-k;9-CH+$eD|K93EllZzI#v51bh+ya5nqx@pp^)PtO+L z9bYdm&aeLO+3eNDwLItc(VOMv)%9l=m#2%%`TMgESM#gZFF%j%r=R(P>&+j%#WQIC za{ldN`S#oE$L$}1K3pv>Kf7G~&4v@%3VUbtCJ)dpvm?^+fCMdmHs^+3$NB^_0i&dmDA$`upBSoqYVhw^5HE zf8X1vhXKFuZB#FxxQ+7LqPqH%pPqg9Y}2&E@lEqq6&P#N zs-rDhRcoa?|J$0&bUwY8ZrrR|Gu^mZwQjm`vuf>h<7UBh~fHPnrpRcodjH>=i7 zH*Qveo&G1Y*{@#yYX14f>CODlm*5P># zMKY4DzwmjgY&gX;RW_Whc{!WClyftBo@Ve?=2tt*PMRVqHkN06CQ6EJZY4!Gc=h$i zC8HaUZky<(|Mlh9{OilFZznEJ;iTE`?955C-`T6bkrRHG$LCjP z)~}>eM(>{Wg*1I$?3n5EVwW_1>Y4YhXY4<(o_X)`zrOUpzLdXyv$_wDPflc#eL1dF z*YC%g+}M{jxv@Y0s#S3t?T%jOnw)T_@+K$TsXm$Y$Po7VrMTMrFZI;>_j0EE`r`fk zNAsKG@8_=<$1;Mwoxi!bTzq!?=6e3!r@`R;F|37uRxd zHvN=t(nf4*Pm?xcQ-hkc5t~}nq>b3rq$X{|rZzQcBc9qd0vpb5CT+>4el=+$ws5R9 z$8!(wSkpCP3&)zS5nDLcbdA`;v8HRp7LGMtBerm?=^C-=p_TZ=bdA`;tfp(k7G|~P z2=C#|YPv>jVOG;MVhgjHt`S?9)pU*6!mOri#1>{XT_d(ItLYlCg;`D4h)vDvYBu}g z;{5t@`TB!ht#W-~Kf^6f<+`8mmRBbiS9<-0|2%i~t^Ce8KRdpWTaEO0z02cM{T1>2 zLVlXu`SJW%ehECi`2PIr`f_pnZmz!(9-p5q^oKva*hhXZluL=^zaEHs_(`Y-pM<*q zNvM0Dgu44ls82r$b?1{%pOjIb9DNFx$f$KLkx}bhBBR#1L`JQ1iHut35*fA5B{FKA zOJvkSmpJ?+E|E|RT_T|tx@2 zEp&;5TIdo9wa_IJYN1Oc)Iyg?sD&<(PzzmR|C6{xLM?QOgj(nl3ANBA5^AAKB-BEe zNT`J_kx&a=BB2(##NH=y38mUK0{5IaEwqYcgA1)9p%z+2LM^n4gj#473ANBF5^AAU zB-BEy*!?6{kx&a=BB2(#L_#feiG*6{5(%}?B@$|(OC;1nmq@6EF7fn}xI{uNbcuvo z=n@IF&?ORTp-UvxLYGLWg)Wg$3tb|i7P`dFCvk~{TIdo9wa_IJYN1Oc)Iyg?sD&<( zPzzlmp%%JCLM?QOC!fS65^AAKB-BEeNT`J_kx&a=BB2(#L_#feiG*6{5(%}?B|gao zm`@UFp-UvxLYGLWg)Wg$3tb|i7P>@2Ep&;5TIdo9waz8vTI^47nRZ64bBT;v=MovU z&LuKxol9iYI+w_(buN)n>s%tE7P>@oL08?)96wH|g)Wg$3tb|i7P>@2Ep&;5TIdo9 zwa_IJ>gF!-li456XZo(C><+A~d@2Ep&;5TIdo9wa_IJYN1Oc)Iyg? zF6b(BiG*6{5(%}?B@$|(OC;1nmq@6EE|E|RT_T|tx@2Ep&JQTIgDY89W z=M)*W&M7kLic?JJ5*fA5B{FKAOJvkSmq;!pD|Cs3TIdo9wa_IJYN1Oc)Iyg?sD&<( zPzzlmp%%JCLM?QO@2Ep&;5TIdo9wa_IJYN1Oc)Iyg?uIDOriG*6{5(%}?B@$|(OC;1nmq@6EE|E|R zT_T|txoVCy@k_|4jiiBEd6$!P_DiUg;RV36xt4J>DDzu7(T4)ss zwa_XOYN1Oc)Iyg?sD&<(Pzzlmp%%JCLM?QO@2Ep&;5TIdo9wa_IJYN1Oc)Iyg?sD&<(PzzlmxuC1iB@$|(OC;1n zmq@6EE|E|RT_T|tx@2Ep&;5TIdo9wa_J! z3%a&(iJ#2=@qE_vj)4SSXcY;y&?*vYp;aW*LaRuqg;tSJ3#}rd7FtC@EwqZ{s;+IU zqQ@l?YN1Oc)Iyg?sD&<(Pzzlmp%%JCLM?QOgj(nl3ANBAk_);DT_T|txk@2Ep&;5TIdo9wa_IJYN1Oc)Iyg?sD&<(T+mhM5(%}?B@$|(OC;1nmq@6E zE|E|RT_T|tx@oJy)SiB-BEeNT`J_ zkx&a=BB2(#L_#feiG*6{5(%}?B@$|(OC;BG6}m)1Ep&;5TIdo9wa_IJYN1Oc)Iyg? zsD&<(Pzzlmp%%JCay?g}OC;1nmq@6EE|E|RT_T|txs%tE*11GR zt#gTtTIUiC_5ODZ)LBKg!F5)VQR}QCqZV34a#2^IRV36xt4OGYR*_H(ts@2Ep&;5TIdo9wa_IJYN1Oc7jzZ6L_#feiG*6{ z5(%}?B@$|(OC;1nmq@6EE|E|RT_T|tx@o zL06$mB-BEeNT`J_kx&a=BB2(#L_#feiG*6{5(%}?B@$|(OC%R`6}m)1Ep&;5x{XT= zdB;G4F0_h-T4)sswa_XOYN1sm)IzIBsC8D6J&&?$75fw3FP~AnR`F2Ou2nn~wd)cO zMeVx8Ls7df@le#ROFR^{>ks%tE*11GRt#gTtTIUiOwaz6n zYMo1D)H;{QsD&<(T+mhM5(%}?B@$|(OC;1nmq@6EE|E|RT_T|tx@2Ep&;5TIdqV1zm+Mkx&a=BB2(#L_#feiG*6{5(%}?B@$|( zOC;1nmq@6EE|FZ&Rp=54wa_IJYN1Oc)Iyg?sD&<(Pzzlmp%%JCLM?QOgj(nl$pu|2 zE;02x1`=|iQzXV)bc%#p=oAUH&?%COx>lTG!fPg;B-BEe zNT`J_kx&a=BB2(#L_#feiG*6{5(%}?B@$|(OC;BG6}m)1Ep&;5TIdo9wa_IJYN1Oc z)Iyg?sD&<(Pzzlmp%%JC@>IP-mq@6EE|E|RT_T|tx@2Ep&;5TIdo9wa_IJYN1Oc)Iyg?sD&<(T+dbL5(%}?B@$|(OC;1nmq@6EE|E|R zT_T|tx@2Ep&@2-Nq#bykp== zf-ba*gj#473ANBF5^AAUBv*A6T17%Fw2FjUXcY;y&?*w@Hde8iUwykczMP*O-z+ZY zZ!Rw9m&d2e@2Ep&;5TIdo9 zwa_IJYN1Oc)Iyg?sD&<(PzzlmxuC1iB@$|(OC;1nmq@6EE|E|RT_T|tx@2Ep&;5TIdo9wa_J!3%UwjBB2(#L_#feiG*6{5(%}? zB@$|(OC;1nmq@6EE|E|RT_U-ltI#D9YN1Oc)Iyg?sD&<(Pzzlmp%%JCLM?QOgj(nl z3ANBAk|*jFxV)bc%#p=oAUH&?ypXp;IK(I;Y5@2Ep&;5TIdqV^<0H6kx&a=BB2(#L_#feiG*6{5(%}?B@$|( zOC;1nmq@6EE|FZ%Rp=54wa_IJYN1Oc)Iyg?sD&<(Pzzlmp%%JCLM?QOgj(nl$@N@? zE|E|RT_T|tx@2Ep&;5TIdo9wa_IJYN1Oc z)Iyg?sD&

$&cK$3US~B$tvET17%Fw2FjUXcY;y&?*vYp;aW*LaRuqg;tSJ3#}r# zsH@N=5^AAKB-BEeNT`J_kx&a=BB2(#L_#feiG*6{5(%}=C9>yHc3on3!pn^^YS$$m zirRIFhoW{};-RQrmv|^@*Cif`+I5MCqIO;4p{QM#n39@3Rj@2Ep&;5TIdo9wa_IJYN1Oc)Iyg? zsD&<(PzzlmxuC1iB@$|(OC;1nmq@6EE|E|RT_T|tx@2-Nq$`ykj6i7g|L^EwqZ{s;)w-NT`KYkx&b*BB2&qMM5pKiiBEd6$y14 ztLS;hKte5aiG*6{63JCvg)Wg$3tb|i7P>@2Ep&;5TIdo9wa_IJYN1Oc)Iyg?sD&<( zT+mhM5(%}?B@$|(OC;1nmq@6EE|E|RT_T|tx@2 zEp&;5TIdo9waz87C+gL?L`JQ1iHut35*fA5B{FKAOJvkKm&mAfE|F2|Tq2_ux@2Ep&;5TIdo9wa_J!>$wVDBB2(#L_#feiG*6{5(%}?B@$|(OC;1nmq@6E zE|E|RT_U-jtI#D9YN1Oc)Iyg?sD&<(Pzzlmp%%JCLM?QOgj(nl3ANBAlIyt&T_T|t zx@2Ep&;5TIdo9wa_IJYN1Oc)Iyg?sD&<( zQ0rVGdlY5YC7w=rERckD*11GOz5g8pbyksWaGh0T)H@2Ep&;5TIdo9wa_IJYN1Oc z)Iyg?F6b(BiG*6{5(%}?B@$|(OC;1nmq@6EE|E|RT_T|tx@2Ep& zxx2d^$?h{t?{yc(jNw5XjsXu)RI8;Hpp$`bz%UGWX3mPtWOt#-%t2L3wC2!P=u0x0 zl+=1lr5_{SwO0fcCk^#SK5Osl^{idwe@A3-C6HQN38WTR0;$E7Kx%O%kXl>`q!w2K zsl}B*YHuaw_Etiv#g)JdUB#6^YH=ly zT3iXF7FPnP#g#y6aV3yiTnVHWR|2WUmB0&K#g#y6aV3yiTnVHWR|2WUl|X87C6HQN z38WTR0;$E7zzbc)l|X87C6HQN38WTR0;$E7Kx%O%kXl>`q!w2Ksl}DR3th#PKx%O% zkXl>`q!w2Ksl}B*YH=lyT3iXF7FPnP#g)JdUB#6^YH=lyT3iXF7FPnP#g#y6aV3!Y z$x0mkI|h(kTneNXmjW+!6_*03#ic-MaVd~mTneNXmjbE9r9kQ@OL5@$D!oN&aV3yi zTnW6?Ra^72CmAF>wT#0L?&Xu@U>RgFyrOuVO zR_a`dYo*SWxK`?1i6c|>g?hb}P-<@_l-gSfrS?`rslAm@YHuZ!+FJ>w_Etiv#g)MO zT*Z|@YH=lyT3iXF7FPnP#g#y6aV3yiTnVHWR|2WUmB9O4#g#y6aV3yiTnVHWR|2WU zl|X87C6HQN38WTR0;$E7!24Xql|X87C6HQN38WTR;>Xm#{W}JVQ-K>UP6bknQ-Rdt zR3NoD6?mzuI2A}OP6bknQ-RdtR3Npu5=bqs1X7DDfz;wkAhoy>c%iGf5=bqs1X7DD zfz;wkAhoy>NG+}eQj05r)Z$7YwYU;^p{uwONG+}eQj05r)Z$7YwYU;UEv^Joiz|WD z;z}U3xDt4wtGE(KEv^Joiz|WD;z}U3xDrS$t^`txD}mJFN+7kk5_qAjxDrS$t^`tx zD}mJFN+7kk5=bqs1X7DDfz;wkAhoy>_(HwnN+7kk5=bqs1X7DDfz;wkAhoy>NG+}e zQj05r)ZR+y3-x*{q14_=D7Ci|O6{$LQhO_*)ZR)cwYL&V?X84Tiz|T_x{51-)MO>j z_#Fdp5nY@Lq!y`q!w2Ksl}DR3th#PKx%O%kXl>`q!w2K zsl}B*YH=lyT3iXF7FPnP#g)JdUB#6^YH=lyT3iXF7FPnP#g#y6aV3yiTnVHWR|2WU zmB0&K#g#y6aV3yiTnVHWR|2WUl|X87C6HQN38WTR0;$E7zzbc)l|X87C6HQN38WTR z0;$E7Kx%O%kXl>`q!w2Ksh_OG!M|fb-$yx@;)|Pn3+A;_=TclNbuPuVQs+`!D|If# zwNmF&Tq|`h#kErBQXHA8Z`JFqgi`0`q!w2Ksl}DR`&`A9Kx%O%kXl>`q!w2Ksl}B*YH=lyT3iXF7FPnP z#g)MOT*Z|@YH=lyT3iXF7FPnP#g#y6aV3yiTnVHWR|2WUmB9O4#g#y6aV3yiTnVHW zR|2WUl|X87C6HQN38WTR0;$E7!24Xql|X87C6HQN38WTR0;$E7Kx%O%eoXz_zhj^{ z6}aKzR3NoD6?mzuI2A}OP6bknQ-RdtR3NoD6-X^k1yYMEfz;wkAhoy>c&V$n5=bqs z1X7DDfz;wkAhoy>NG+}eQj05r)Z$7YwYU=aR=wg%Ahoy>NG+}eQj05r)Z$7YwYU;U zEv^Joiz|WD-b(0O^?ECz)ZR)cwYL&V?X84Tdn=*T-byI7w-QS2t%OpGD}fifiYtNC z;z}U3xDrS$t^`txD}mJFN+7kk5=bqs1X7DDffu@pD}mJFN+7kk5=bqs1X7DDfz;wk zAhoy>NG+}eQj05r7rKfofz;wkAhoy>NG+}eQj05r)Z$7YwYU;UEv^Joiz|T_x{51- z)Z$7YwYU;UO;+Od9f6NG+}eQa@RV-@keDzdt{{e0cxm?_SBlPcQ%SczS$z z_`~V~O^{PF$EA5LF?c>ebE?%OZlKR&&jUViuC%in$T`1IA|>FehYrw{KQ-oN|i z^z{7jcsl<}Fn@Es;JFo744!jw#o)OZR}7w`amC=d8&?dT({aV%xgJ*xo&$1lu)c3^ z{!QbG!PNoL9ajfL!PNm#aCJZwTpbVvR|iDF)d5j(cR=taSa(1W+#L`EcLxN)-2p*x zcR&!_9S{U}2L!?00YPwgK=6{-dO%*^5jf``puRwQcSR7~T@eI#R|LV`6+v)!MG)Lw z5d?Qv1i{@E!AoT86*+4_5ZoOQ1a}7n!QBBtaCblu+#L`EcLxN)-2p*xcR=uJS$9AX z+#L`EcLxN)-2p*xcR&!_9S{U}2L!?00YPwgK=9UCcR&!_9S{U}2L!?00YPwgKoHy= z5CnGz1i{?_L2!3K@IqR5KoHy=5CnGz1i{?_L2!3K5ZoOQ1a}7n!QBBtaCboPu3C3M z5ZoOQ1a}7n!QBBtaCblu+#L`EcLxN)-2p*xcR=tOTX#SZ+#L`EcLxN)-2p*xcR&!_ z9S{U}2L!?00YPwgK=2iV-2p*xcR&!_9S{U}2L!?00YUI)Kz@8j;M_N@zd(9-MG)Lw z5d>FPL|;KzT@eLWS46?p6;W_?MHF0J5e08nARxH}*S?hXioy90vP*t!FP;O>ARxH}*S?hXioy90vY?tmb; zJ0J+|4hVv~1A^Dsx&wmX?tmb;J0J+|4hVv~1A^f0fFQU#APDXb2!guAR zxH}*S?hXioy90vP*t!FP;O>ARxH}*S?hXioy90vY?tmb;J0J+|4hVv~1A^Dsx&wmX z3kT%&9f8ZflI<tUNLwM$Q6U zcn-)FgXe%;F?bHh!NK}!#rZdoD+bTMfm|`TIw1O^t`3NTs{^9o>VPP?Iv@(J4v2!g z1A^Dsx&wmX?tmb;J0J+|4hVv~1A^f0fFQU#APDXb2!guARxH}*S?hXio zy90vP*t!FP;O>ARxH}*S?hXioy90vY?tmcp`~ms#dju~3-EChWy}Kd^?yd;lW$Ug8 zg1ak%;O>ebxVs_D{|Tn2!gu< zg5d6eAhCnHMZ`6AhARxH}*S?hXioy90vY z?ttJmw(fu+xH}*S?hXioy90vY?tmb;J0J+|4hVv~1A^f0fZ#Q@?tmb;J0J+|4hVv~ z1A^f0fFQU#APDXb2!guCnHMZ`6AhARxH}*S?hXioy90vY>VTa8?Wn)L)wiQwF?bHh z6@%x1TrqeK$Q6UkbHly90vY?tmb;J0J+| z4hVv~1A^f0fFQU#APDXb2wr3B4hVv~1A^f0fFQU#APDXb2!guARxH}*S?hXiEW9tqGg1ZBP;O>ARxH}*S z?hXioy90vY?tmb;J0J+|4hUXj>kbHly90vY?tmb;J0J+|4hVv~1A^f0fFQU#APDXb z2wr3B4hVv~1A^f0fFQU#APDXb2!guARxH}*S?hXioy90vY?tmb;J0N(A ztvetH?hXioy90vY?tmb;J0J+|4hVv~1A^f0fFQU#Ab5+dJ0J+|4hVv~1A^f0fFQU# zAPDXb2!gubJO|{8!E->a7(55$iotV0 zt{6NAee^M8VYoQE+uY6kHt;1y=_|!PNm#aCJZwTpbVvcLxM-v2_Oo z!QBBtaCblu+#L`EcLxN)-2p*xcR&!_9S{U}2Lx}ibq55&-2p*xcR&!_9S{Wn#els2 zl7Yw5+oS)Ei}db_Ah^3C2=1;3g1ak%SJ}ENg5d6oAh^3C2=1;3g8yPg3Il@R?tmb; zJ0J+|4hVv~1AAR zxH}*S?hXioy90vP*t!FP;O>ARxH}*S?hXioy90vY?tmb;J0J+|4hVv~1A^Dsx&wmX z?tmb;J0J+|4hVv~1A^f0fFQU#APDXb2!guARxH}*S?hXiEW9tqGg1ZBP;O>ARxH}*S?hXioy90vY?tmb;J0J+|4hUXj>kbHl zy90vY?tmb;J0J+|4hVv~1A^f0fFQU#APDXb2wr3B4hVv~1A^f0fFQU#APDXb2!gu< zg5d6eAh(fi?MFFIDR|LV` z6+v)!Mer_LcSR7~T@eI#R|LV`6+v)!MG)NmYY2k71A^f0fFQU!Ao`}#IUxUdtFK7C zV(=W0D+bR2xnl4fkShky0l8xE9FQvp&jGn&@EnkXgZ0&l)d5lP{2Ry>@3=Z3y5s7A zD7ZQx3a$=_f~y0f;Oc-VxH}+tjjcN%2<{FDg1ZBP;O>ARxH}*S?hXioy90vY?tmb; zJ0N(CtvetH?hXioy90vY?tmb;J0J+|4hVv~1A^f0fFQU#Ab5?fJ0J+|4hVv~1A^f0 zfFQU#APDXb2!guAR zxH}+tjjcN%eebxVs{F zm#w=Z2<{FDg1ZBP;O>ARxH}*S?hXioy90vY?tmb;J0N(CtvetH?hXioy90vY?tmb; zJ0J+|4hVv~1A^f0fFQU#Ab5?fJ0J+|4hVv~1A^f0fFQU#APDXb2!guARxH}*S?hXioy90vY?tmb;J0J+|4hVv~ z1A^Dsx&wmX?tmb;J0J+|4hVv~1A^f0fc$mv>pKGPKfb(s`r*93yCQ#`{^#KCiXgbV zB6ydryCMkgt_Xs=D}vzeiXgbVA_(rT2!guARxH}+tjjcN%2<{FDg1ZBP;O>ARxH}*S?hXioy90vY?tmb; zJ0N(CtvetH?hXioy90vY?tmb;J0J+|4hVv~1A^f0fFQU#Ab5?fJ0J+|4hVv~1A^f0 zfFQU#APDXb2!guAR zxH=%`e>>_gZ}sh{R}7v5a>d{|AXf~Y19HXSIUrXIo&$2l;5i^y44wmWaIn5rasCbD ziox@5Al2a4cLW~aeS3QN^Lc%BMfB%gT@eLWS46?p6;W_?MHF0J5e0Ww1n;tSR|LV` z6+v)!KoHy=5CnGz1i{?_L2!3K5ZoOQ1a}7nud#Ip1i{?_L2!3K5ZoOQ1a}7n!QBBt zaCblu+#L`EcLxNov2_Oo!QBBtaCblu+#L`EcLxN)-2p*xcR&!_9S{U}2L!LNbq55& z-2p*xcR&!_9S{U}2L!?00YPwgKoHy=5CnGz1h27m2L!?00YPwgKoHy=5CnGz1i{?_ zL2!3K5ZoOQ1a}7nud#Ip1i{?_L2!3K5ZoOQ1a}7n!QBBtaCblu+#L`EcLxNov2_Oo z!QBBtaCblu+#L`EcLxN)-2p*xcR>CW{Q8c-cTXQ*KFk*dx-0Uh^v?u$R|M~}byozz z-4#J_cSR7~T@eI#R|LV`6+v)!MG)K_5CnGz1YfP#9S{U}2L!?00YPwgKoHy=5CnGz z1i{?_L2!3K5L_J)eYIkBKondZ5CvBUM8VYoQE+uY6kHt;1y=_|!PNm#aCboP8e4Zj z5ZoOQ1a}7n!QBBtaCblu+#L`EcLxN)-2p*xcR=tOTX#SZ+#L`EcLxN)-2p*xcR&!_ z9S{U}2L!?00YPwgK=2w{cR&!_9S{U}2L!?00YPwgKoHy=5CnGz1i{?_L2!3K@ETip zKoHy=5CnGz1i{?_L2!3K5ZoOQ1a}7n!QBBtaCboP8e4Zj5ZoOQ1a}AI`{37i1fCvF z56_=DukWr1Zo9i82=1;3g1ak%;O>ebxVs{Fm#w=Z2=1;3g1ak%;O>ARxH}*S?hXio zy90vY?tmb;J0N(CtvetH?hXioy90vY?tmb;J0J+|4hVv~1A^f0fFQU#Ab5?fJ0J+| z4hVv~1A^f0fFQU#APDXb2!gubJO|{8 z!E->a7(55$iotV0t{6NA`>#hibyDNg=?usC|yCMkgt_Xs= zD}vzeiXgbTBBw79+#L|S%hnwb1a}7n!QBBtaCblu+#L`EcLxN)-2p*xcR&!_9T2?6 z)*TQ8cLxN)-2p*xcR&!_9S{U}2L!?00YPwgKoHy=5WL3L9S{U}2L!?00YPwgKoHy= z5CnGz1i{?_L2!3K5ZoOQyvEiY5CnGz1i{?_L2!3K5ZoOQ1a}7n!QBBtaCblu+#L|S z#?~DW1a}7n!QBBtaCblu+#L`EcLxN)-2p*xcR&!_9T0r0Vs}6g+#L`EcLxN)-2p*x zcR&!_9S{U}2L!?00YPweK=iGO)d5j(bwCtc9S{YV2IR+g1fHHB9#2ZIu84xGE27}) ziYU0cA`0%V2;ODut_Xs=D}vzeiXgbOBBvh*1i{?_L2!3K5ZoOQ1a}7n!QBDDYi!*C zL2!3K5ZoOQ1a}7n!QBBtaCblu+#L`EcLxN)-2uUCY~2AtaCblu+#L`EcLxN)-2p*x zcR&!_9S{U}2L!?00l{l*-2p*xcR&!_9S{U}2L!?00YPwgKoHy=5CnGz1i{?_!E0>Y z0YPwgKoHy=5CnGz1i{?_L2!3K5ZoOQ1a}7n!QBDDYi!*CL2!3K5ZoOQ1a}7n!QBBt zaCblu+#L`EcLxN)-2uUCY~2AtaCblu+#L`EcLxN)-2p*xcR&!_9S{U}2L!>#56J5~ z0`DH)zx(Eo=X`jVt-B%!?yd-eyDNg=?usC|yCMkgt_Xs=D}vzeiXiy-75R$+IsYqC ze{rj?NWEh49FQvp&jGn&@EnjU2G0SxV(=W0D+bR2xnl4fkb{Hu)r#|PAXf~Ye*?K< zaCJcRM_nBd1y=_|!PNm#aCJZwTpbVvcLxNov2_Oo!QBBtaCblu+#L`EcLxN)-2p*x zcR&!_9S{U}2L!LNbq55&-2p*xcR&!_9S{U}2L!?00YPwgKoHy=5CnGz1h27m2L!?0 z0YPwgKoHy=5CnGz1i{?_L2!3K5ZoOQ1a}7nud#Ip1i{?_L2!3K5ZoOQ1a}7n!QBBt zaCblu+#L`EcLxNov2_Oo!QBBtaCblu+#L`EA37kf?+AST{NeQBFV6YCKzesY5Zql6 z1b0^i!QBkbHl zy90vY?tmb;J0J+|4hVv~1A^f0fFQU#APDXb2wr3B4hVv~1A^f0fFQU#APDXb2!gu< zg5d6eAhARxH=&ER>kUo zD7ZQx3a$=_f~y0f;Oc-VxH=#Tt`3NTs{^9o?ttJmw(fu+xH}*S?hXioy90vY?tmb; zJ0J+|4hVv~1A^f0fZ#Q@?tmb;J0J+|4hVv~1A^f0fFQU#APDXb2!gu9#5a1^SwoScSR7~T@eI#R|LV`6+v)!MG)Lw5d?Qv1i{@E!Mkint;pvG z1i{?_L2!3K5ZoOQ1a}7n!QBBtaCblu+#L`EcLxNov2_Oo!QBBtaCblu+#L`EcLxN) z-2p*xcR&!_9S{U}2L!LNbq55&-2p*xcR&!_9S{U}2L!?00YPwgKoHy=5CnGz1h27m z2L!?00YPwgKoHy=5CnGz1i{?_L2!3K5ZoOQ1a}7nud#Ip1i{?_L2!3K5ZoOQ1a}7n z!QBBtaCblu+#L`ER|n+$Z%6&&R^N_##o#$0R}7v5a>d{|AXf~Y19HXSIUrXIo&$2l z;5i@%2kToE=iflC7(D+5a>d~4fas69Iv@(J4v2ye7?9U@1b+A7%in$T*>gUnS64*A z)fG{2cSZ0nTX#he++7g_cUJ_#-4#J_cSR6Y0YPwg zKoHy=5CnGz1i{?_L2!3K5ZoOQ1a}7n!QBDDYi!*CL2!3K5ZoOQ1a}7n!QBBtaCblu z+#L`EcLxN)-2uUCY~2AtaCblu+#L`EcLxN)-2p*xcR&!_9S{U}2L!?00l{l*-2p*x zHXwie9)XwB3(onF-dzy{cUJ_#-4#J_cSR7~T@eI#R|LV`6~R|4c2@+!*@`?qc|Z`{ z9S{U}2L!?00YPwgKoHy=5CnGz1i{q-(N`;02SmZu0a0*uKondZ5CvBUM8VYoQE+uY z6kHt;1$PGoud#Ip1i{?_L2!3K5ZoOQ1a}7n!QBBtaCblu+#L`EcLxNov2_Oo!QBBt zaCblu+#L`EcLxN)-2p*xcR&!_9S{U}2L!LNbq55&-2p*xcR&!_9S{U}2L!?00YPwg zKoHy=5CnGz1h27m2L!?00YPwgKoHy=5CnGz1i{?_L2!3K5ZoOQ1a}7nud#Ip1i{?_ zL2!3K5ZoOQ1a}7n!QBBt@OnUA-w`;y`}WKCKXK0Y7U|s;L2!3P@Ge_-MG)Lw5d?Qv z1i{@EL2!3P5Zql61g}@*tN}rAcR&!_9T2?B)*TQ8cLxN)-2p*xcR&!_9S{U}2L!?0 z0YPwgKoHy=5WL3L9S{U}2L!?00YPwgKoHy=5CnGz1i{?_L2!3K5d6u2{2y=L{9n&6 z@4h)bK0N&4^!xW8zk2@o{^bvU^_$?%|MJt{9D$tDAA+1ZAA+2s9)g?-9)g^59fF+N z9DnfL37jjv3A(vGba#?jDmsJ;XS#=?|RmV#|+o}V( ztvZm~ssp*LI*{9{1G%j_klU&Qxve^o+p6RBlx@|4+*TdPZPkI?RvpM~)q&hr9ms9f zf!tOd$Zgf}BE`1qKyIrJOgL*4&=7#IP%|C9ms9ff!tOd z$Zgeu+*TdPZPkI?RvpM~)q&hr9p}>9ssp*LI*{j9{q-Gz=MSe3?;hTN|8J(Ao*y1h zUx2&qJCNJH1G()xklVfkx$QfU+rHx%b=!9!w|xil+`fNWbs)D@2Xb3=Ah%Tqa$9vE zw^avnTXh`xZL1FCw(3A`s}AJ0>OgL*4&=7#KyIrJ)R)mRTpwubs?8k7jjv3A(vGba#?jDmsJ;XS#=?|RmaiPw(3A`s}AJ0>OgL*4&=7# zKyIrJOgL*j#H^^)q&hr9mvb7 z{`!uKyLdEOgL*4&=7#KyIrJOgL*4&=7#KyIrJOgL*4&=7#IF;H~9ms9ff!tOd$Zgeu+*TdPZPkI?RvpM~ z)q&hr9j8*;ssp*LI*^;HzrG{z!*>UOyX`xW+r9(2?K_a$z5}`KJCNJH<7jHzcObWY z2XfQ*AF2-Iw(3A`s}AJ0>OgL*4&=7#KyIs!PxEc74&=7#KyIrJOd~5u21tVt1jfS>OwB7F66T6LN2Q=OgL*4&=7#IGWm49ms9ff!tOd$Zgeu+*TdPZPkI?RvpM~)q&hr9Y<5! zssp*LI*{9{1G%j_klU&Qxve^o+o}V(tvZm~s^e5@TXi6}RR?lgbs)D@2Xb3=Ah%Tq za$9vEw^avnTXmdDZL1FCw(3A`tNz95^&NqCPYOgL* z4&=7#KyIrJNuL(RvpM~)q&hr9ms9ff!tOd$Zgeu+*TdP zZPkI?RvkxE+o}V(tvZm~ssp*LI*{9{1G%j_klU&Qxve^o+p6PeYFl+6w^avnTXi6} zRR?lgbs)D@2Xb3=Ah%Tqa$9vAO>L_VOgL*4&=7#KyIs! zqp5Axf!tOd$Zgeu+*TdPZPkI?RvpM~)q&hr9ms9faWu89I*{9{1G%j_klU&Qxve^o z+o}V(tvZm~ssp*LI!>jwRR?lgbs)D@2Xb3=Ah%Tqa$9vEw^avnTXi6}RmTVUwp9mm zTXi6}RsR$6^&Nqqd^_O$)2=^pKZD%%9ms9pf!y{T$Zg+&T=rd`=3Dk%$YtM!T=rea z<+KaAth$iPstdWSx{%AN3%RX2j;6L%2Xb3=Ah%Tqa$9vEw^avnTXi6}RR?lgbs)D@ z$I;Zb>OgL*4&=7#KyIrJNuL(RvpM~)q&hr9ms9ff!tOd z$Zgeu+*TdPZPkI?RvkxE+o}V(tvZm~ssp*LI*{9{1G%j_klU&Qxve^o+p6PeYFl+6 zw^avnTXi6}RR?lgbs)D@2Xb3=Ah%Tqa$9vAO>L_VOgL* z4&=7#KyIs!qp5Axf!tOd$Zgeu+*TdPZPkI?RvpM~)q&hr9ms9faWu89I*{9{1G%j_ zklU&Qxve^o+o}V(tvZm~ssp*K`uQI){nhawFg*l0t9}S_R{apOgL*4&=7#IGWm49ms9ff!tOd$Zgeu+*TdP zZPkI?RvpM~)q&hr9Y<5!ssp*LI*{9{1G%j_klU&Qxve^o+o}V(tvZm~s^e&CTXi6} zRR?lgbs)D@2Xb3=Ah%Tqa$9vEw^avnTXh^wZL1FCw(3A`s}AJ0>OgL*4&=7#KyIrJ zOgL*4&=7#KrXAU5ArRmF66T6LN2Q= zOyX-j#H^^)q&hr9ms9fKZksMN8q!+S>Wuq1Kxg)`$y!q z??7(*4&=7)KyLdEOgL*4&=7#KyIrJNuL(RvpM~)q&hr9ms9ff!tOd$Zgeu+*TdPZPkI?RvkxE+o}V(tvZm~ zssp*LI*{9{1G%j_klU&Qxve^o+p6PeYFl+6w^avnTXi6}RR?lgbs)D@2Xb3=Ah%Tq za$9vAO>L_VOgL*4&=7#KrX9({-;d;@%T@f9)g@zKLk0e zeh6|_{Sf4=`XR_!^+S-e>W3g_)z3!igM4$<4?)gVKLoj~x^8?~bs?8k7jjv3A(vGb za#?jDw^hff)VAtCZmSODw(3A`s}AJ0>OgL*4&=7#KyIrJ zBVXSUc)RWU-{!vE_8rJ=-+|or9ms9pf!y{TM^oFr1G()xklVfkxve^o+o}V(tvZm~ zssp*LI*{9{<7jGIbs)D@2Xb3=Ah%Tqa$9vEw^avnTXi6}RR?lgbsSA?s}AJ0>OgL* z4&=7#KyIrJOgL*4&=7#KyIrJ zuKM=Rq*cV;q>tQ-P6aH50B&50BrjXL_VOgL*4&=7#KyIs! zqp5Axf!tOd$Zgeu+*TdPZPkI?RvpM~)q&hr9ms9faWu89I*{9{1G%j_klU&Qxve^o z+o}V(tvZm~ssp*K`uU$S{pInWGCc%2t9}S_R{apOwB7F66T6LT;;$qp5Axf!tOd$Zgeu+*TdP zZPkI?RvpM~)q&hr9ms9faWu89I*{9{1G%j_klU&Qxve^o+o}V(tvZm~ssp*LI!>jw zRR?lgbs)D@2Xb3=Ah%Tqa$9vEw^avnTXi6}RmZ8+w(3A`s}AJ0>OlTQ)qnfuKb+ot z|8~In|5yR;w(mf0`wrx`??7(*4&=7)IGWn_9ms9pf!y{T$iL|OMO6oKTXi6}RR?lg zbs)D@2Xb3=98GPj4&=7#KyIrJOgL*j-#n<)q&hr9ms9f zf!tOd$Zgeu+*TdPZPkI?RvpM~)p0bntvZm~ssp*LI*{9{1G%j_klU&Qxve^o+o}V( ztvWuOgL*4&=7#KyIrJNuL(RvpM~)q&hr9ms9ff!tOd$Zgeu z+*TdPZPkI?Rvo8O+o}V(tvZm~ssp*LI*{9{1G%j_klU&Qxve^o+p6PKYFl+6w^avn zTXi5msrql<{JYb+Z|uJXc3XEKw{-_{TX!J0bq8`=cbrUZ>kj0$?m%wq4&*0wKfCHc zZmSODw(3A`s}AJ0>OgL*j+3cv)q&hr9ms9ff!tOd$Zgeu+*TdPZPkI?RvpM~)p0Vl ztvZm~ssp*LI*{9{1G%j_klU&Qxve^o+o}V(tor#MGW~~hpW{N#svm-!RX+qdt9}S_ zR{apcf0<)ek`~tFEhDR$a(t)rDMEUC3qCgOgL*j+3cv z)q&hr9ms9ff!tOd$Zgeu+*TdPZPkI?RvpM~)p07dtvZm~ssp*LI*{9{1G%j_klU&Q zxve^o+o}V(tvXJnwp9mmTXi6}RR{8us$cSQz!$)7>kj0$?m%wq4&=7(KyK@flc{ap zf!x*|$Zg$${G{&Z9x8kRNuI&RvpM~)q&hr9ms9ff!tOd z$Zgeu+*TdPZPkI?Rvn+^+g2UOZPkI?RvpM~)q&hr9ms9ff!tOd$ZgeuTvlD5OgL* z4&=7#KyIrJkj0$ z?l_s+)*Z-g-GSWJ9mr4We(uWwZ-Lxa9ms9ff!tOd$ZgeuTvlBl2%S~`#kv0<7jjnp z5ag`-A;?+vLy)uThahLw4?)hVAA+1!KLk0eel}8{OgL*4&=7#KyIrJOgL*4&=7#IF;H~9ms9ff!tOd$WN+%$;$y> z0K2U_klVTgxve{p+qwg}tvf!;x2-#n+qwg}tvisP)cxF};xB;QRvpM~)q&hr9ms9f zfm~KypXFOtUC3qCgOgL*4&=7#KyIrJOgL*4&=7#KyIrJNu6!RvpM~)q&hr9ms9ff!tOd$Zgeu+*TdPZPkHXR$U(komKzh+(SblXVniu z&Z-}RoK^qgl9vN?^Rw=UTOgL*4&=7#IGNg39ms9ff!tOd$Zgeu+*TdPZPkI?RvpM~)q&hr9Vb)Ussp*L zI*{9{1G%j_klU&Qxve^o+o}V(tvZm~s^es8TXi6}RR?lgbs)D@2Xb3=Ah%Tqa$9vE zw^avnTXmdFZL1FCw(3A`s}AJ0>OgL*4&=7#KyIrJn`NB?l_s+)*Z-g-GSWJ z9mr4WesOgL*4&=7#KyIrJOgL*4&=7#KyIrJ;q>tM_51Jt!^hLt&mT@7e*C|9dVY93>BEt;^S?Qi zJWn1I~EA+SRk-tfxwOh z0y`E6$8xbiVE;*=wL4(P?tmS;19t2V*s(ic$L@d~y90LY4$k>vcfgL_0XudF?ART! zV|T!g-2ppx2kh7#uw!>{a2UG-cI*z=u{&VL?tmS;19t2V*s(ic$L@d~yMvR+*d4HA zcfgL_0XudF?ART!V|T!g-2ppx2kh7#9Bsz#fE~L7cI*z=u{&VL?tmS;19t2V*s(ic z$L`>)GW)54o4O-*>W<-wmJ2-re-2ppx2kh7# zuw!??j@eL);cM&;*s(ic$L@d~y90LY4%o3fV8`x&9lHZ|><$iJ zV|T!g-2ppx2kh7#uw!??j@XPmqK_RYUPy?K21?djqD z$Cr0cU;XfX0;lJ%PcOgw@Z%?>7bPD7lN}2Lb}SIsu|QzQ0)ZV11a>SC*s(xh#{%K- zHFgK=*d4HAcfgL_0XudF?ART!V|T!g-2ppx2Zyh*J7CA|fE~L7cI*z=u{&VL?tmS; z19t2V*s(h}e2v`!J9Y=`*d4HAcfgL_0XudF?ART!V|T!g-NE5&><-wmJ7CA|fE~L7 zcI*z=u{&VL?tmS;19t2V4qsz;z>eJkJ9Y=`*d4HAcfgL_0XudF?ART!V|Q@)8oL8_ z><-wmJ7CA|fE~L7cI*z=u{&VL?tmS;gTvR@9k63}z>eJkJ9Y=`*d4HAcfgL_0XudF z?ARTAvO9JM?ART!V|T!g-2ppx2kh7#uw!??j@<-wmJ7CA|fE~L7cI*z=u{&VL z?tmS;19s}p`CnY{>x=*Wx7gF2W7*T4W7*T4W7*T4W7*T4W7*T4W7*T4W7*T4%h~#1 z_k8Xg%TC?Vb*Ju#ow_4->WK)|L&X9)APgQNdd7yIDCx- z0y`E6>{uYMV}Zbq1p+%32<%uOuonVNcfgL_!QpG{4%o3fV8`x&9lHZ|><-wmJ7CA| zfE~L7cI*xgUt@Q`j@eJkJ9Y=`*d4HAcX0R`y90LY4%o3fV8`x& z9lHZ|><-wmJ7CA|fE~Mo!`Ijyuw!??j@eJkJ9Y=`*c}|c#_oU} zy90LY4%o3fV8`x&9lHZ|><-wmJ7CA|;P5qe2kh7#uw!??j@eJk zJ9Y<$udzE|$L@d~y90LY4%o3fV8`x&9lHZ|><-wmJNRIC><-wmJ7CA|fE~L7cI*z= zu{&VL?tmS;19s|;KG>bQBX;VJ*r_{Wr|yWIx+8Y#j@YR?pJ%_mBk<#I7f1#Ae87+F zSRfp}#sYyI3j}s75ZJLmV8;T19Sa0@ED+eSJ7CA|;P5qe2kh7#uw!??j@eJkJ9Y<$udzE|$L@d~y90LY4%o3fV8`x&9lHZ|><-wmJ2-re-2ppx2kh7# zuw!??j@eL);cM&;*s(ic$L@d~y90LY4%o3fV8`x&9lHZ|><$iJ zV|T!g-2ppx2kh7#uw!??j@5B$ zJ>5B$J>5B$J>5B$J>5B$J>5B$J>9vStq*ml?ub2~JI7vk>W;2Ebw}*f9kEk)#HKqx zeviQKAHRA2>ix?fP7jY?zyJO}d^~;q{9%4V`ZuR{PY{3_!SC*c9k=hC5)V51%i{ z_!_$dcI*z=u{&VL?tmS;19t2V*s(ic$L@d~yMx2m*d4HAcfgL_0XudF?ART!V|T!g z-2ppx2kh7#9KOcxfE~L7cI*z=u{&VL?tmS;19t2V*s(ic$L`?pHFgK=*d4HAcfgL_ z0XudF?ART!V|T!g-2ppx2Zyh*J7CA|fE~L7cI*z=u{&VL?tmS;19t2V*s(kKWOwWi z*s(ic$L@d~y90LY4%o3fV8`x&9lHZ|>W)6tow_4->WeL);cM&;*s(ic$L@d~ zy90LY4%o3fV8`x&9lHZ|><$iJV|T!g-2ppx2kh7#uw!??j@h=U8^?j{Zzicf?NJ z5&MtsyuKsw;mh|=kEgfC{-LJ=>Ecs?#Eu2R;cF}q*s(xh#{z*J3j}s75ZLL%N8bPt zyMybF-2ppx2Zyh*J7CA|fE~L7cI*z=u{&VL?tmS;19t2V*s(h}e2v`!J9Y=`*d4HA zcfgL_0XudF?ART!V|T!g-NE5&><-wmJ7CA|fE~L7cI*z=u{&VL?tmS;19t2V4qsz; zz>eJkJ9Y=`*d4HAcfgL_0XudF?ART!V|Q@)8oL8_><-wmJ7CA|fE~L7cI*z=u{&VL z?tmS;gTvR@9k63}z>eJkJ9Y=`*d4HAcfgL_0XudF?ARR~zQ*o=9lHZ|><-wmJ7CA| zfE~L7cI*z=u{&VL?%<-wmJ7CA|fE~L7cI*xgUt@Q`j@eJkJ9Y=`*d4HAcX0R`y90LY4%o3fV8`x&9lHZ|><-wmJ7CA|fE~Mo z!`Ijyuw!??j@eJkJ9Y=`*c}|c#_oU}y90LY4%o3fV8`x&9lHZ| z><-wmJ7CA|;P5qe2kh7#uw!??j@eJkJ9Y<$udzE|$L@d~y90LY z4%o3fV8`x&9lHZ|><-weJLi9M!7q#7TyQLVx^pahx^pahx^pahx^pahx^pahx^pah zx^p>OAL^dZonzVaxpOQ#bw__DsXK%H+c*F7>CK17ci)~K-hX^~_w>~d-zRW-{`&Ot zyFY%rz_EWYsX*i6Ke_HyAhA<{#Eu2R;cF}q*s(xh#{z*J3j}uT4%o3fV8`x&9lHZ| z><$iJV|T!g-2ppx2kh7#uw!??j@eJkJ9Y=`*d4G_cl4p|)E%)?cf?NJ5&IK& ze)tN3i(gn0KlMlK)E}`^f5cAx5j*w=XRon8V8{M|9s2|JC;nXS4%o3fV8`x&9lHZ| z><-wmJ2-od-2ppx2kh7#uw!??j@eL)*=y_$*s(ic$L@d~y90LY z4%o3fV8`x&9lHZ|><-ReV|T!g-2ppx2kh7#uw!??j@@{`=?ART!V|T!g-2ppx2kh7# zuw!??j@EzK$CCn5fy7P)5<3-0>{KAJQ-Q>e1;XKL zED+eSKwvKfn(lxdy90LY4%o3fV8`x&9lHZ|><$iJV|T!g-2ppx2kh7#uw!??j@eJkJ9Y=`*d4G_cl4p|)E%)?cRtU4eMjKO-!6~}^!b1v*{MKcrvizc3M6(akl3j} zV#fmE@HG|)>{uYMV|T!g-2ppx2kh7#uw!??j@{ z_!_$dcI*z=u{&VL?tmS;19t2V*s(ic$L@d~yMx2m*d4HAcfgL_0XudF?ART!V|T!g z-2ppx2kh7#9KOcxfE~L7cI*z=u{&VL?tmS;19t2V*s(icr|#(61*SW{D1LLnvFz#2 zvFz#2vFz#2vFz#2vFz#2vFz#2vFz#20G7{eSp)`uh39{DkyxPVb%`P7lxDJ$-!n@c8cA)5H6ZFQ0q4;FEw;#!dy&A51Ec z*r`Bbrvizc3M6(c5Ds5sfxxCf=ky!w^x^Xb*s(ic$L@d~y90LY4%o3fV8`y@@HKV^ z?ART!V|T!g-2ppx2kh7#uw!??j@{_!_$dcI*z= zu{&VL?tmS;19t2V*s(ic$L@d~yMx2m*d4HAcfgL_0XudF?ART!V|T!g-2ppx2kh7# ze6l-s2kh7#uw!??j@eJkJ9S4N>Q3ExeMdk6sX$_<0*RdpBz7v0 z*r`Bbrvizc3M6(c5Ds5cf!=~0y90LY4%o3fV8`x&9lHZ|><-wmJ7CA|;P5qe2kh7# zuw!??j@eJkJ9Y<$udzE|$L@d~y90LY4%o3fV8`x&9lHZ|><-wm zJ2-re-2ppx2kh7#uw!??j@eL);cM&;*s(ic$L@d~y90LY4%o3f zV8`x&9lHZ|><$iJV|T!g-2ppx2kh7#uw!??j@CA81rj?INbFP~u~UJ>P6ZM>76^y0^Dl0TeuEvm19t2V*s(ic$L@d~ zy90LY4%o3fV8`y@@HKV^?ART!V|T!g-2ppx2kh7#uw!??j@{_!_$dcI*z=u{&VL?tmS;19t2V*s(ic$L@d~yMx2m*d4HAcfgL_0XudF z?ART!V|T!g-2ppx2kh7#e6l-s2kh7#uw!??j@eJk`+Rp^-x2uy zuNTlKyHkP0P6ZM>6-ew7wB)egTvR@9k63}z>eJkJ9Y=` z*d4HAcfgL_0XudF?ARR~zQ*o=9lHZ|><-wmJ7CA|fE~L7cI*z=u{&VL?%?n>b_eX( z9k63}z>eJkJ9Y=`*d4HAcfgL_0XudFhp(|aV8`x&9lHZ|><-wmJ7CA|fE~L7cI*z= zu{$_?jokq|b_eX(9k63}z>eJkJ9Y=`*d4HAcfgL_!QpG{4%o3fV8`x&9lHZ|><-wm zJ7CA|fE~L7cI*xgUt@Q`j@eJkJ9Y=`*d4HAcX0R`y90LY4%o3f zV8`x&9lHZ|><-wmJ7CA|fc=R(|K-h_|NQ^FfA`JlyLbQkc*bv!KL3jgesd&xnsX?6 zigPG>dUGgxYI7)hT5~9RN^>ZBI&%>E^&NqCPhb7;H3FySuTL+(`{S1iT+G+!x#uJ2 zP;}^xt~&Ha=+GOXLvMr*y%9R}M(EHRp;KjW(wZs*bgB%{sWL#P$^e}z19Ykk(5W&& zr^*1GDuV;oR2iUCWq?kV0XkI%=u{b?Q)Pfol>s_c2Iy27oU5kF0G%oWbgB%{sWL#P z$^e}z19Ykk(5W&&r^?_sHB|=aR2iUCWq?kV0XkI%=u{b?Q)Pfol>s_c2B)a0GC-%w z0G%oWbgB%{sWL#P$^e}z19Ykk(5W&wJWZ7WI#mYfR2iUCWq?kV0XkI%=u{b?Q)Pfo zmBE>5stnMnGC-%w0G%oWbgB%{sWL#P$^e}z19Ykkj!IKyfKHVGI#mYfR2iUCWq?kV z0XkI%=u{b?Q)Te+>r@$_Q)Pfol>s_c2Iy27pi^alPL%;VRR(A%^ZJg!Ij_#>Q`ez4 zLWkZ69eN{l=#9{!H$sQr2pxJObm)!H@a8OKa8#Nq19Ykk(5W&&r^*1GDg$(?4A7}E zK&Q$8ohpN)(o`9sQ)Pfol>s_c2Iy27pi^alPL%;VRR-u(861_S$^e}z19Ykk(5W&& zr^*1GDg$(?4A7}EK&Q&!s5Dgu=u{b?Q)Pfol>s_c2Iy27pi^alPL%;VRR%|;sWL#P z$^e}z19Ykk(5W&&r^*1GDg$(?4A7}EI4Vt*0XkI%=u{b?Q)Pfol>s_c2Iy27pi^al zPL;t?X{rp+sWL#P$^e}z19Ykk(5W&&r^*1GDg$(?430`uWq?kV0XkI%=u{b?Q)Pfo zl>s_c2Iy27phIQO{}zCM>U|5qq3Eg1q3Eg1q3Eg1q3Eg1q3Eg1q3Eg1q3Eg1W$4#; z1Rfqw`n2?X)Lh2@3G{r_9EuLT(H}_YjnJVtLWkZ69eN{l=#9{cH$U_mN2RGUK&Q$8 zohk!#stnMnGC-%w0G%oWbgB%{sWLb!O_c#URR-u(8K6^TfKHVGI#mYfR2iUCWq?kV z!BJ_d4A7}EK&Q$8ohk!#stnMnGC-%w0G%oWbgB%FN>gQkPL%;VRR-u(8K6^TfKHVG zI#mYfR2iUCWpGrQDg$(?4A7}EK&Q$8ohk!#stnMnGC-%w0G%p>qta9vpi^alPL%;V zRR-u(8K6^TfKHVGI#mYfR2dwVrpf@FDg$(?4A7}EK&Q$8ohk!#stnMnGC-%w;HWfJ z2Iy27pi^alPL%;VRR-u(8K6^TfKHVGI#mXrmQIxcI#mYfR2iUCWq?kV0XkI%=u{b? zQ)Pe-mC*;Ke{*_$N8m4i$H2ws^x}u!2pxJObm)!Hp*KQ@-UuCfBXsDE(5W{#Dh(es zZ-Gvg0XkI%=u{b?Q)Pfol>s_c2Iy27pi^aVRGKOSbgB%{sWL#P$^e}z19Ykk(5W&& zr^*1GDubiaR2iUCWq?kV0XkI%=u{b?Q)Pfol>s_c2Iy279F?ZZ0G%oWbgB%{sWL#P z$^e}z19Ykk(5W&&r^?`{G*t%ZR2iUCWq?kV0XkI%=u{b?Q)Pfol>s_c21li-GC-%w z0G%oWbgB%{sWL#P$^e}z19Ykk(5W&wDovFEI#mYfR2iUCWq?kV0XkI%=u{b?Q)Pfo zmBCSIstnMnGC-%w0G%oWbgB%{sWL#P$^e}z19Yg&`QHNY>)y8j9EzUG9EzUG9EzUG z9EzUG9EzUG9EzUG9EzUGT#VKSrRP)Tv*_1%1YZ7ddU*W${a5c_KAygQ{&4#6?&1Br zZ%$9o7kvxBXZc%n=#BnVLT`i)y%9R}M(EHRp+j$kPQAfV=^5Uz*Fev|on5XB(5W&& zr^*1GDg$(?4A7}EK&Q$8ohpN)(o`9sQ)Pfol>s_c2Iy27pi^alPL%;VRR-u(861_S z$^e}z19Ykk(5W&&r^*1GDg$(?4A7}EK&Q&!s5Dgu=u{b?Q)Pfol>s_c2Iy27pi^al zPL%;VRR%|;sWL#P$^e}z19Ykk(5W&&r^*1GDg$(?4A7}EI4Vt*0XkI%=u{b?Q)Pfo zl>s_c2Iy27pi^alPL;t?X{rp+sWL#P$^e}z19Ykk(5W&&r^*1GDg$(?430`uWq?kV z0XkI%=u{b?Q)Pfol>s_c2Iy27pi^b=Y3WoMpi^alPL%;VRR-u(8K6^TfKHVGI#mYf zP#JwtI#lKr{p0T%I6XXn_w@1Q!{fVePY>@uzPx+->hbjbr=9=u3kEJe&(x)d-UuCf zBXsDE(4jX%hu#PsdLwk|4US4vZ-7pf0XkI%=u{b?Q)Pfol>s_c2Iy27pi^aVRGKOS zbgB%{sWL#P$^e}z19Ykk(5W&&r^*1GDubiaR2iUCWq?kV0XkI%=u{b?Q)Pfol>s_c z2Iy279F?ZZ0G%oWbgB%{sWL#P$^e}z19Ykk(5W&&r^?`{G*t%ZR2iUCWq?kV0XkI% z=u{b?Q)Pfol>s_c21li-GC-%w0G%oWbgB%{sWL#P$^e}z19Ykk(5W&wDovFEI#mYf zR2iUCWq?kV0XkI%=u{b?Q)PfomBCSIstnMnGC-%w0G%oWbgB%{sWL#P$^e}z19Yg& z`QHNYtKPQ&9EzUG9EzUG9EzUG9EzUG9EzUG9EzUG9EzUGT#VKSrRP)TQ1rh&WnSMA zc>4Z@fJ6DAH~Lcvy%9R}M(EHRp+j$k4!sdN^#(_!sW(9Xn>RaUfKHVGI#mYfR2iUC zWq?kV0XkI%=u{aTm8Qx7ohk!#stnMnGC-%w0G%oWbgB%{sWL#P%HXIpRR-u(8K6^T zfKHVGI#mYfR2iUCWq?kV0XkI%N2RGUK&Q$8ohk!#stnMnGC-%w0G%oWbgB%{sWLb! zO_c#URR-u(8K6^TfKHVGI#mYfR2iUCWq?kV!BJ_d4A7}EK&Q$8ohk!#stnMnGC-%w z0G%oWbgB%FN>gQkPL%;VRR-u(8K6^TfKHVGI#mYfR2iUCWpGrQDg$(?4A7}EK&Q$8 zohk!#stnMnGC-%w0G%p>PfMrD0G%oWbgB%{sWL#P$^e}z19Ykk(5W&&hsx-K(xEa! zU!ctEI|85k9RuQr-UuCfBXsDE(4jX%hu#PsdLwk|4US4vZ-BnQo6jl(bgB%{sWL#P z$^e}z19Ykk(5W&&r^?`{G*t%ZR2iUCWq?kV0XkI%=u{b?Q)Pfol>s_c21li-GC-%w z0G%oWbgB%{sWL#P$^e}z19Ykk(5W&wDovFEI#mYfR2iUCWq?kV0XkI%=u{b?Q)Pfo zmBCSIstnMnGC-%w0G%oWbgB%{sWL#P$^e}z19Ykkj!IKyfKHVGI#mYfR2iUCWq?kV z0XkI%=u{b?Q)O^enkoZystnMnGC-%w0G%oWbgB%{sWL#P$^e}zgQL<^8K6^TfKHVG zI#mYfR2iUCWq?kV0XkI%=unySzXjkQd*1?ZD0(V$D0(V$D0(V$D0(V$D0(V$D0(V$ zD0(V$FuJRs_c2Iy27pi^al zPL%;VRR-u(8K6^TfKHXcQE93S(5W&&r^*1GDg$(?4A7}EK&Q$8ohk!#stk@wQ)Pfo zl>s_c2Iy27pi^alPL%;VRR-u(8K6^Ta8#Nq19Ykk(5W&&r^*1GDg$(?4A7}EK&Q$8 zohpN)(o`9sQ)Pfol>s_c2Iy27pi^alPL%;VRR-u(8GKqgRR-u(8K6^TfKHVGI#mYf zR2iUCWq?kV0XkGhACwN25js>x=uedS;Y$QAecwm;P#d8`ZG;ZB5jxaH=ujJ>Q*Cfk znrZ`dstwSeXmhbLK&Q$8ohk!#stnMnGC-%w0G%p>lhRZfpi^alPL%;VRR-u(8K6^T zfKHVGI#mYfR2iIs_c2Iy27pi^alPL%;VRR-u(8K6^TfKHXcNolGK(5W&&r^*1GDg$(?4A7}EK&Q$8 zohk!#stis_Q)Pfol>s_c2Iy27pi^alPL%;VRR-u(8K6UD&i@jCUtW5`A@o${Q1n#h zQ1n#hQ1n#hQ1n#hQ1n#hQ1n#hQ1n#hVzfRdJ)bg%qC;hL)fX%C`illWoIbpJc>nI3 z)6?_A<4OF`8=*sQgbuwCI`l^9&>NvsZ*WwadINOo4bT^R^NBJ*r^*1GDg$(?4A7}E zK&Q$8ohpN)(o`9sQ)Pfol>s_c2Iy27pi^alPL%;VRR-u(861_S$^e}z19Ykk(5W&& zr^*1GDg$(?4A7}EK&Q&!s5Dgu=u{b?Q)Pfol>s_c2Iy27pi^alPL%;VRR%|;sWL#P z$^e}z19Ykk(5W&&r^*1GDg$(?4A7}EI4Vt*0XkI%=u{b?Q)Pfol>s_c2Iy27pi^al zPL;t?X{rp+sWL#P$^e}z19Ykk(5W&&r^*1GDg$(?430`uWq?kV0XkI%=u{b?Q)Pfo zl>s_c2Iy27pi^b=Vd+#Epi^alPL%;VRR-u(8K6^TfKHVGI#mYfP#JwtI#fpJP#K{^ zWj=%c?VJDU^ydA?mv>KJJ)Yi%-h77tXLRU|(4jX%hu#PsdLwk|4US4vZ-7p{0Xp>t z=u{b?Q)Pfol>s_c2Iy27pi^aVRGKOSbgB%{sWL#P$^e}z19Ykk(5W&&r^*1GDubia zR2iUCWq?kV0XkI%=u{b?Q)Pfol>s_c2Iy279F?ZZ0G%oWbgB%{sWL#P$^e}z19Ykk z(5W&&r^?`{G*t%ZR2iUCWq?kV0XkI%=u{b?Q)Pfol>s_c21li-GC-%w0G%oWbgB%{ zsWL#P$^e}z19Ykk(5W&wDovFEI#mYfR2iUCWq?kV0XkI%=u{b?Q)PfomBCSIstnMn zGC-%w0G%oWbgB%{sWL#P$^e}z19Yg2KB_;J`G?-O033>*${dQG${dQG${dQG${dQG z${dQG${dQG%3O@r2c<)0gq}~CL$5kiMpylbGMis9AbhBe(4jU$huR1oY9n;24Ngi^ zZGcX-0Xo$N=ufn{^wIkT(5W&&r^*1GDg$(?4A7}EI4Mn)0XkI%=u{b?Q)Pfol>s_c z2Iy27pi^alPL;t)X{rp+sWL#P$^e}z19Ykk(5W&&r^*1GDg$(?3{FZ@Wq?kV0XkI% z=u{b?Q)Pfol>s_c2Iy27pi^aVQkp6QbgB%{sWL#P$^e}z19Ykk(5W&&r^*1GDua{K zR2iUCWq?kV0XkI%=u{b?Q)Pfol>s_c2Iy27oRp@@0G%oWbgB%{sWL#P$^e}z19Ykk z(5W&&r^?`@G*t%ZR2iUCWq?kV0XkI%=u{b?Q)Pfol>s_c1|ODAl>s_c2Iy27pi^al zPL%;VRR-u(8K6^TfDV;;`Y&=)K7 znO`v=e&~(Rp*KQ@-UuCfBXsHwj!IK+fKI&uI`szVi@lk@V&E;%sWL#P$^e}z19Ykk z(5W&wDovFEI#mYfR2iUCWq?kV0XkI%=u{b?Q)PfomBCSIstnMnGC-%w0G%oWbgB%{ zsWL#P$^e}z19Ykkj!IKyfKHVGI#mYfR2iUCWq?kV0XkI%=u{b?Q)O^enkoZystnMn zGC-%w0G%oWbgB%{sWL#P$^e}zgQL<^8K6^TfKHVGI#mYfR2iUCWq?kV0XkI%=u{aT zm8Qx7ohk!#stnMnGC-%w0G%oWbgB%{sWL#P%HXIpRR-u(8K6^TfKHVGI#mYfR2iUC zWq?kV0XkIX{4W9c#igG_6nZLiD0(V$D0(V$D0(V$D0(V$D0(V$D0(V$D0(V$G5U+M zUjaB29V(-%4wVr)ROU12`6~uOZ$88S^XnX;H$sQr2pxJObm|R`O6T9sesSreMjv`l zy}?zd-T<9?19Ykk(5W&&r^*1GDg$(?430`uWq?kV0XkI%=u{b?Q)Pfol>s_c2Iy27 zpi^aVRGKOSbgB%{sWL#P$^e}z19Ykk(5W&&r^*1GDubiaR2iUCWq?kV0XkI%=u{b? zQ)Pfol>s_c2Iy279F?ZZ0G%oWbgB%{sWL#P$^e}z19Ykk(5W&&r^?`{G*t%ZR2iUC zWq?kV0XkI%=u{b?Q)Pfol>s_c21li-GC-%w0G%oWbgB%{sWL#P$^e}z19Ykk(5W&w zDovFEI#mYfR2iUCWq?kV0XkI%=u{b?Q)PfomBFW_Q)Pfol>s_c2Iy27pi^alPL%;V zRR-u(8K6UD^g-!R8KFaEgbtMvI#fpJPn6mGiUHw6ZG;ZB5jxaH=u{h=l&0DMooWMg zstwSoHb8%(&82T!==%jyWpLH0GC-%w0G%p>lhRZfpi^alPL%;VRR-u(8K6^TfKHVG zI#mYfR2iIs_c z2Iy27pi^alPL%;VRR-u(8K6^TfKHXcNolGK(5W&&r^*1GDg$(?4A7}EK&Q$8ohk!# zstis_Q)Pfol>s_c2Iy27pi^alPL%;VRR-u(8K6UD^hy1x%omrQ6$m|*ITSsWITSsW zITSsWITSsWITSsWITSsWITSsWxfrd_Nr%b^9V#PqsEp8|GD2Uh%x8YZfcT*|LWkZ6 z9eN{l>J5%cQ*VGyy#YG)2I$lqpfC1j{)z#8;XYDkF5LjL@MnLWjzH2L0PN|Nivm zZ~PvBi{BLa4FAvQ&>NvcZ-h?0!BJ`I4bZ7KK&RdSoq7Xw>J8B0qefpakSc?#PL%;V zRR%|;sWL#P$^e}z19Ykk(5W&&r^*1GDg$(?4A7}EI4Vt*0XkI%=u{b?Q)Pfol>s_c z2Iy27pi^alPL;t?X{rp+sWL#P$^e}z19Ykk(5W&&r^*1GDg$(?430`uWq?kV0XkI% z=u{b?Q)Pfol>s_c2Iy27pi^aVRGKOSbgB%{sWL#P$^e}z19Ykk(5W&&r^*1GDubia zR2iUCWq?kV0XkI%=u{b?Q)Pfol>s_c2Iy279F?ZZ0G%oWbgB%{sWL#P$^e}z19Ykk z(5W&&f1=E<-n{w0-~H?3>EZpmZy#SCKb*dP{&0GD{_g4H%ZJBz-+uo;|M>Fm>8r=n z_h&uNU!Pun_u zF8IM&fD3+b7T|&(oCUbx2WJ6({lhm1oc{+jOK?HzEWrgoI7@KB56%+&>im10kAVw* zaF*bLADkt);0I?3F8IM&f(w3d7T|&(oCUbx2WJ5;_`z9#f7}+}f*+g(xZnq80WSE# zS%3?Ea2DW#ADjia;0I>`F8IM&fD3+b7T}lL0$lKevj7+T;4HueKR63;!4J*?T=0Xl z02ln=EWianI16yW56%Mo!?pky{NOCW1wS|oaKR7G0$lKevj7+T;4HueKR63;!4J*? zT=0Xl0KeE4;DR5V1-Re`X8|tw!C8O{esC7xf*+g(xZnq80WSE#S%3?Ea2DW;Z2>O$ z!C8O{esC7xf*+g(xZnq80WSE#S%3?Ea2DW#ADjjF;{SW|=D+=?ub#jC@6S(j}_y6_r!~3UyKK=gjo9D0Izx?6! zAD^CIPVb+-`sQ~JKm5;Mz9;<4^N08U~wreE5<0zy2xj zhyRna|25S2Nv{$A{LS;1-{Ze}e*W-%?7Nr8)5kx2e0lu#@8Oo_KNEzL*mUEI=q)ZWD{%}4EB+|qp1-o-7=NA0ig?@@afw=^HMcX3PeQF|A+ zG#|A;<6C`MkZ0Tbj??ySSzKy#3YvJ#X*g zmge*JE^cW)Z|~xk=JWP0ZfQPh@8Xu`qxLRtX+CQ2;+E#4_AYK|K5GB*{vNe=aZB@2 zdl$DfAGLRJOY>2C7q>JYwRdq#^HF;jw=^HMcX3PeQF|A+G#|CUyuU~7UEI=q)ZWD{ z%}4EB+|qp1-o-7=N9|qQ(tOn3#VyT8?Ooi`eAM2>EzL*mKiuD=_AYK|K5Fmcmgb}O zE^cW)YVYEf=A-s5ZfQPh@8Xu`qxNTcORw(;T>2TA`MmvE-q)qKG@rM>xWDJ^UEI=q z-rmJ6&FAf1+|qpB-o-7==j~nG(tO_D#VyU}?Ooi`eAM2>EzL*m7x(w5y^C9#kJ`Jq zrTM76i(8tH+Pk==`KY~%TbhsBySSzKsJ)9@nvdFZZt1_?-~Cp)!uFicLI3P; zX+CQ2;+E#4_AYK|K5Fmcmgb}OE^cW)YVYEf=A-s5ZfQPh@8Xu`Kh>V|q2ZtXb7?+m z@8Xu`qxLRtX+CQ2;+E#4_AYK|K5Fmcmgb}OE^cW)YVYEf=A-s5ZfQPh&-uLY-`S(~ zXLd`k?+E<)ccT4kmdl$DfpSO2$OY?bq7q>K@w|8+%^Lcw0w=|!( zcX3Ped3(->hX2l2C z7q>JYwdZ_j`0wmddl$DfAGLRJOY>2C7q>JYwRdq#^HF;jw=^HMcX3PeQF|A+G#|Bh zaZB@2d(MZ3|IQw@cX3PeQF|A+G#|BhaZB@2dl$DfAGLRJOY>2C7q>JYwRdq#^HF;j zw=^HM=X_rH@9a@~7q>JYwRdq#^HF;jw=^HMKbu>6eMcbqy_@rS`?I;PJYwRdq#^HF;jw=^HMcX3PeQF|A+G#|BhaZB@2 zdl$DfAGPP)(to+XFSGdB-_m^4p7S~ApZzV(N9|qQ(tOn3#VyT8?Ooi`eAM2>EzL*m zUEI=q)ZWD{%}4EB+|vA~+H*cM{Ih>9%}4EB+|qp1-o-7=N9|qQ(tOn3#VyT8?Ooi` zeAM2>EzL*m&)}9`-w`-{_wHXG|5I|TKA*QggZs*FX+Cey`Oxs++4J@;ZfQPm@8Xu` z^Y$)oX+Cf7;+E#~_AYK|K5y^hmge*JE^cW)YVYEf=A-tU4-NmFJ!2C7q>JYwLf`F|L>bO|Lw28 z%;KxZr~zsoF1OPd;0kD;ql$K zr-%0+U*0`^^>}(aAC5oyG2hNb%*WY{E@D1_Zgdgzk#VDom?M9qi$|M2nU z@!L)@=3>n&x!Og{#k$c&%*DFVMa;#z(M8O~`pFOLbc#9uS@1>|F&FDb7cm#>Mi(&` z>qZwb$LdBGF~{mg7cs}`Mi(*1>P8na$Lc3P?r@EP8na$LdBGF~{mg7cs}` zMi(*1>P8na$Lc5FSG>kp-RL6bSl#F%=2+e6BIa1#=pyD=-RL6bSl#F%=2+e6BIa1# z=pyD=-RO<4`7hXSbP;o`ZgdfItZsA>bF6N35p%3=bP;o`ZgdfItZsA>bF9v}h|m0{ z>+8Q6TDXWgR_DBSR=9{cRyVqc*RgtiN8sgmAHMwIo!;-?-F^S``nK;sfAjq1_unk= zxmO1Ye;jkMZgdfIv2Jt`bFpr85p%I_bP;p0ZgdgzuUF^1_EoTBF4m1MVlLK=E@J-m z>P8na$LdBGF~{mg7cs}`Mi(*1>P8na$LdBGF~{nhH@@m)b)$=zV|Am8m}7OLijj#Gx-RL6bSl#F%=2+e6BIa1#=pyD=-RL6bSl#F% z=2+e6BIa1#=pyD=o%6<5eXMSD5p%3=bP;o`ZgdfItZsA>bF6N35p%3=bP;o`ZgdfI ztZsA>bF9vJ+C4YSpbFpr85p%I_bP;p0ZgdfIv2Jt`bFpr85p%I_ zbP;p0ZuHvMe1G9a7cs}`Mi(*1>P8na$LdBGF~{mg7cs}`Mi(*1>P8na$LgGm_{{H) zxc=**g^QSDbbF6N35p%3=bP;o`ZgdfItZsA>bF6N35p%3=bP;o`&UxdjK2|rnh&fg_x`;Ve zH@b*9RyVqcIaW8ih&fg_x`;VeH@b*9RyVqcIacSq@pb-Ky}l#x-MfE%JnMIa&3|!q z?3J8-5p%I_bP;p0ZgdfIv2Jt`bFpr85p%I_bP;p0ZgdfIv2Jt`bFt2O?d$x-I(sMP zSl#F%=2+e6BIa1#=pyD=-RL6bSl#F%=2+e6BIa1#=pyD=-RL6bSe^66SADE*bP;o` zZgdfItZsA>bF6N35p%3=bP;o`ZgdfItZsA>bF6N35p%3=^v2ixo7IgjVvf~~E@F<= zjV@x2)r~GNcdx%*{;1z0 ze_-;QrJsDk?7-x?Mb}K819Z*gxjNTOo>OzpY1e5KdZ{(tJ;ZcC0UOVZ05jsCT?q@|^w zCH17#(h{jDj+p-m4R5LoT{AsW6}zf9)dgOt76>GZPy|08(@Az&nNG6H%FHBp`8dl%?Pog4E-TYXc3GKDvdhYJl3iA&lkBoGon&L>;adds z?){H`!%ny2)KW((+KlkBoGon)7l=_I?XOefi8Wje_&E7M7KS(#3<%gS_;T~?-(+~w0O%Q(p{E7M7K zS(#3<%gS_;T~?-(?6NYQWS5ocB)hCkC)s6XI>}u=&9aP>?6NYQWS5ocB)hCkC)s6X zI>|08(@Az&nNG6H%5;)lR;H8O<|08(@E}9dFC5o zcl7DBhpJ2`xy$Ehwyf-58o2RW<7g)fl)teu?PQmgX(zj^Ogq_SW!lLuE7MMPS($dS z%gPKUclkKWmYe#|08(@Az&nNG6H%5;*ue4J$&C)s6XI>|08(@Az&nNG6H%5;)lR;H8evND}y zmzC)xyR1wnxy#2{mT{6@R;H8evND}ymzC)xyR1wn*=1!q$u29?Np@M8PO{6&bdtM# zoMjm&*=1!q$u29?Np@M8PO{6&bdp_Grjx8I`!fPBFTZ*Ea{t-o<<;{Sub*CD?7w;U z=KA85{+0hjEpXb&y8QB$X(zj^Ogq`-XIl8bf_GV&cCyRLw3A&{rk(7vGVNrSm1!rt ztV}1_Wo0_a#>#)(+xz+Z7q8x4fA{p|%Xj-vf4I1M`lpNM``6!Hy?t}Nug`HjyO8Hz zeEaQ-XTy(t?tk+7^6Hg*`1*4H`HMII_~~%S{?*gxFZ8$9m(MTu4?o|({C5BP?bSCg zUSI5g{^;Q=9MH3ts6cO8q5?f=i3;?ZB`VNUmZ(7QSfTo-_voQUg8=S-_voQUg8=S-_voQUg8=S-_voQUf>$y zK7G3QeR_!s+|x@`;C*_D3f$96RN#Gji3;4)OH|-}dWj0$(@RvqecGQ9_KNbB`R=FFHwOv z>m@31PcKn{H|r%Ta8EB$fj8?VDsWFPQ2{sW&zGpc`}6`8;y%4Zg~j)D+^3hghQ;@E z+^3hghQ;@E+^3hghQ;@E+@}|~hPY23FMgk1q5}8y5*2u#UZMi`^b!?#pI)K@_w*7K zc%NRP0{8S16?mUsq5|*J3si{v^b!>o-_voQUg8=S-_voQUg8=S-_voQUg8=S-_voQ zUf>$yK7F+KeR_!s+|x@`;C*_D3f$96RN#Gji3;4)OH|-}dWj0$(@Rv~eR_!syiYGs zA@0*lR9JjZ$9;Nw;o|q{B`R=FFHwQ_ z=_M*~PcKn{_vs}na8EB$f%oYpDsWFPQGxgAB`WYfy+DPyPcKnn@jdPPv_B)T{jf&r&3cIni|^@pQ@zABEWW4XKE1>>EWW4XKE1>> zEWW4XK7H{2?d|>c^7``Xv*GJYKI>n2a&__Y>Gg{rF82TY;`Q_WH{W0AOHkswPJXuk z;`OtaZ}sg{f7*X@ef9R4zT`yTdh+V>`o-nz{im8X{I=Jd{co=>U+usBUWZ&feYHxP zZ+^D_&D(2zMap$K%gf7WI)Mu6Tsp`2Wh(2hPWj7`dj6Lq_3ST4>givO)RVs)smFgg zQjh*}q#pj|NIm#}=WhW|Uwz}RxVr5QK>wcH1%9?4mcFlV$GYvVke2_`m3IEqm3H>i zm3I2mm3H#em3I8om3H*gm3H{km3Hv&@9ll^{e`|v@b&el|61QU*sONQx^G`zyw;Zt zzIc6o@%qh+>v#M9{=n~A5`TKF?;^a|zZxRDzj4rCIJnNp4|%flhdkNYL!RvPAy0Pl zkS9BS$desCn@?;15dwair`t0K6%Ztz6J^l0k#nqM8=>!rB)kn_!loNYej zbn_u6n-4kOe8|z}Lk>3|a`4}^xTWp;^wq`nMfPn2f4+e~+rXc0;7>O2#~b*g4gBE- z{^0rE-q)W!yL|QiW3+_@yA6Urp(4)9(dfcGu1aqHc;z{X8?-vS%A+kFe%Wuwj9ZXb4|-K)S|Hrl-k+-0NPtH510+Pw^z+E=ly$alAqur~(T{hai3fyI* z-K)S|Hrl-k+-0NPtH510+Pw;F+-Uzq|KsTGn~SSY|Ha8<+f>#IvWn!nn=e0%-9K4zs4K{7yYH~aivv(N4|`}AJ3PwqAQ_+GP*?lt@H zUb7GGH9JAhCVma}8EY&knt%a*fa zwQM;%R?C*NW3_BKJ66k0bRql;KFTh5Lpv*qkqGF#4$C3A4EC9~!1STbAAjwQ3@ z>{v2e&W_cxMKcYL^+xwT}2NgeQpP>Cr z{|<8XVDHnLx5uLoo_YSkGtWMF=IIB|Jo(_6#~(cN=!0h-e(=nLzv?UDhNbeq%`K~m z`M!8P``~x0$@$!OtI6R&kG7f|2DIJe@Sp7_hy83fIoxNv$zeX*O%CtbZgSkH&bNB0 zVv%e&ITp!wlVg!=H#ru`c9Ua~Y&SU;$##=tk!&|P7Rh##W09QQXOV0-ITp!wlVg!= zH#ru`c9Ua~Y&SU;$##=tk!&|P7Rh##W09QRXOV0-ITp!wlVg!=H#ru`c9Ua~Y&SU; z$##=tk!&|P7Rh##W09QPXOV0-ITp!wlVg!=H#ru`c9Ua~Y&SU;$##=tk!&|P7Rh## zW04%+XOV0-ITp!wlVg!=H#ru`c9Ua~Y&SU;$##=tk!&|P7Rh##W04%)XOV0-ITp!w zlVg!=H#ru`c9Ua~Y&SU;$##=tk!&|P7Rh##W04%*XOV0-ITp!wlVg!=H#ru`c9Ua~ zY&SU;$##=tk!&|P7Rh##W04%(XOV0-ITp!wlVg!=H#ru`c9Ua~Y&SU;$##=tk!&|P z7RkXUa}U!d58nQ6c$jwDAI#nH5$);`+=os)|ImqNA3E{$Lnoem=)~g>op|)26AwRh z;_$@{?HT?20{O4?MK0gy6Sw}_f%h*z^LHS=|NgV5KVH1~@B8;V$Z!fO=)iU2+>3b*s!@a%l|EFKSeKl14V)#CqRq4n7 z?WDF#|8Sx2^3wOw{4cEadi)lU;oBBws`N{G@|%A)ciJawnY^Md=*e&91wGkc3F*32V^-=3*7g{WT_xj@M`i1^+<|pHK zQ0R*)E-$b2eVI?MFW#)r_-_7;Px6fG8Sm$3e0}4LU;X&vf83<{)#b31dXZnfo1ao; z<&^jHQ>w0*^2;Az{ug_D|A)W#b67s}4SLyC{qp^K{Hq_!_+1&lf7zDA;ml4tynQEO zTO78!!+9pF@NnFbu?i3WI9=&Ja??s5CeGKGtn|Y_PFK2XY+C8V#Q7SNm45ignU&ry zIaYda(l4hgxm~(ue6jaW_xI`sSx=iT=XNzW6`EPj6KPmzhku+|&TDN=R!*5N=ZUVE zqUF54tiB}G%f4)-q#X0Ba?G##vOStvwntkm+oPsoIM3weKAK&&M>EUTM{ZiS!^HU- zlVy7}vus^s)3O~V&exbM+oQQ<+b(&2HEG6l*|tl+amIATwhOsw#>|SHsKQ!0np?3G zSvh68Vkf#{%6i2PjaaQ-jr)p~lD=XGRqJEcEB1J1#U5|5VvpO39nLd(rH^M@ab@#$?4F&#YM2*tBAYiSsokEB1J9#kNbHUrm}ZU9s)bZ=5k*vF$=`nlZCt zC#tZPj^|eFL{?6juGopLn6h56LnBtJQRBX1rKGReLDl*gt=NC6H++|W)<2EAErx%k zEHcD!W!=@mn?v|2It-JYs8?rs{NKcBkf)VZ#si=H=F{nMx2@*Yw7K(REsqC&J$L@w zR`P1v-1)JN#{(4@^ezYe@`X-USUdjR-0?MEI!MbJ+VSt_j<4a8$7==u54Y>-D{CyE zj4(5y3d#xZ=O$D|F=1T0tIHqOF*ahS()uZ=U1lU zTCU7?!8abCE3*l?>G;XYoan*2aeC#-oCwMZxiTk;V#0c54wt`Lb*tn$zMkuqIVf5m zGv(3(ssqZaRLlGADYlZk$rNGADv^Laxk- zqL{E=nX804u95M6KaSTcbCpor-@9iH$&xGcj`?&r(HBEL9R|*)TsbWitzOx-GKY}K zmD!Te?JLLGbmsgM&m02g%=tIn&7DhU&Of=EJC*Wo-Y#^0&9u6E3>@<>kG&UxiTk;V#0c54wt|3!{O4_GO;Io1>^A<=<%89sKcchBSJ#nxH@Vk?=TO4~K7iHmsN14|<0aeQ~h=&o8h3`TqEa zmtP$GM=0=Ek2c41whAn;TH{sKliwWPGUvwhTI=fV*ll&!Yroe0`qsKP?t@xaCVgAo z^`5AcWZ1HiTbi_9US7YL`|j4clf8nu?{A%3Gv}nPw$4Ahqvmmi*TM?Lw@t31XC}YD zb#hfboviIug=mKXz6aDktE}P);QNpRav*gI5)Qv z=hj6znLF7^oLe#fvOlkHpSXl^Sh z?{B}Aj^?*gD-cWTC^wwNu<$ce0f{DYp{qZrV!i6t~u$Y$Z>cY$X=1 z%d#%%ac*uU&aJC*Iybix=hj6znLF7^oLeD{*oaJu^AC5+_&H)5+_t)VjCY z9V6^_rBPcpMLC%}*-D&SHDf_r z^kge>auq!@IkyrgSJl(W>#fwfx7r;e>|1G+*|$)!lcshwl4Zf+&k-L#b~{pR;dt~=RE zo;2A?EL@kRm-O&80`+3`81{zuTJ2(Qe6KY;x4d<3U6^${S@&c+-K-mndYpXY`=yEK znaR1GSh=d6PF`=PvHSHckRRmM-mXJlQ@z?wBkXr3MZoEHTEAcNHQo5JwA%BCfkXHC)=sL+~eHb zN}O9wzHWzcZf+&ct&4Ipce0f@w`#_McHzmLiIc17naR18IJv5xPF`=N*1gs4Xbk~e zZ>6T1Y~MMh*-D<2TZwfy zZKZaKTkB4?k|#~J5)0R5S(o%UH@6b!)>S#3n_G!<>!O^@oopq}t(vi*Eqbz*IJt_R znVegRldJ0Kl+-COOB5%!Qb%IqPpsm8(Ukf#VZ-Ae2COIvKEc)zsTO07UFtsZXY zw~{C2R^psZTdAGm*1D6eKa9x&lNsn`LD{*dJmD9Po zl{mL9%E{cxR^r^M84KE?CtHb=tLT}@xs^D%s-8|>Z>83~)$SN!-%6v*zLlD49K7C2 z%6r5AwZG~8Qv3hEH@r1Lz>D`wN9(xh52D`ieyJ6RfM->?m3kO%|Bv|wQMK;P@0Z#+ z=IZ8FV%<$!$j6Qt;E80S=J>z&dsgFxph@e=jK-8+`1?yb0=GgbE{@7 zXp5d~B~GrQXC~)X;^eA&I(fa7TK87FV}yMxjWYXIYN~PYdMhdZO}Eney;580H>_H0 zrTBkKtF6=ugiH5e+X}>z_N3fOoU`e!)J}10-N{|alX5Gu?xwBOPH}79$yV~D$yQ?F zx-9FG9_Qv(;@r9_r*m^Fac*6dlev?v#JN>77PLiAwh|{-(KC~CD{*pFJ)OMXO09dV z-7&(xl}4F;D>c#SJ5+*b1QLjRXv@&-b$@|tKBiezLiFq zeJeH9IC#C46#s@#fZp_8seK~xE&(szD;=-jv-l&XH@sJB1tQ>CRc@sohTEqeZxB`M z-uzyvonx+UZY9>;w3RIV=J!gjJK0K}G}%flT$g2C(&OCRN}O9)<#cXtCC;sjax!6Rh2d}r1;@@;Dt=}uP zm43sjz3siyYAdw@;nF?WwgR!FJt?;m=WMzwwNu<$cXC(qq})oZyJ;)6Q`}m2vXwk( zvXxl4F3Y;4$GN$cIJd6K>D=5(oLd*=WbR}uac*|eY9DNuYr>Q45PCr$Pf3)i(-*Y!9z_Y>#Vr8%9O`-yYw z%ACxd>?h8xnz5=ada|E5xr&~docoEBtLo|G^?qvITWygM_Wd-bqR8scFm`E z5;?Biu2LK3=6O|R&U=5$yec#1X`A%gHIB5Y&$u|DAOEyZ<%nFdja< zFuU6I4(QISefWp`tCP*Ii1?U7TYtkhP0g-$AHHd|`+KTp*I%0+du#aD{Wn+JwA%fR zRX10gtag3Q@rKpjdJ!KP?Jd-2O=mYryQmwd-LTp{tuCXw+K2CenqPerkyw5H9)M5h zcF9C#&bwi?Ph`ft^=emR{V!a{1-D-9!?mnd`|4W(#$$9BXbWz5{5-qb^(N)ct9|%# zfZ@c$$>vvkJZSF4Z&>Xk%vSKl-+ zF1Yn-m!`hjSKl-+9)vmV?cV6wo7Y+<39!@sD+T&e9TkXRa2+XcOAHHd| z`|Ag0*I%0+t9|%7ft#ysTJ8Qaf}5*NR=fUT{SB+V^jZ7th}8>rbET|9beV{<#0e{=xpI`KQC_pN^(~I-dUNWcsJm z>7UM~e>$K3>CyhD|L)%2FMs~**};!5{-3?QZ(qKB@qGX3vu77CFRpYcm#_DqzP!{I zxn6&Fu|Ixw>;8|QJ%4d^@oXf=Z}>gXm+ZcMb8+?A)y2Pkt8d)Bc)qW1$Q|c@(nl}e z?7#W`;@OLDUx-&*$~o6xcDn!Oo#wy#^uxs*zJC7G5p#6)6B2WL{oPNeGbcYKF{eKz zF=sy|G3P%eF^?WzOtZhkA78Z5Q6C-m(Mcbj_R(1%o%hkBK00`}I^SU*9re+1AD#5k zX&;^S(Rm*|dUscQe)m(d=NT~{&z@(*d^~%e5%clvc}C2~v*#HxAJ3j=#C$w^o)Po$ z?0H7a0``2z82J9DWO_4VKA!2#i1~P?HzVfbncj?;k7s%_VjjZuzS#S#{k`@(8(Y4! zno;!eoNq?V$8)|JF$*}~>V5h99whtdsE>~O=%kNM`{=BX&im-mIQsp?OTFVCYG~BL zuSPBWYShB7MlJkm)WWYuE&OWK!mmax{A$#~uSPBWYShB7MlJkm)WWYuE&OWK!mmax z{A#4|+ms%3^@n}bx}oD*H#BP9(5Q7oqt*?LS~oOOH~#O{Q;#3ouljtfCmtUrWPv-& zhY4BWuJU0*7PzB)n2-hTCLbo`A?_q`6ZtS93*10HOvnN^j}H^Fz>VV$LT0l20*`P% zOvuMEw3&{497CHC@^K7pM##r8v>72E$Ixbkd>liY5%O^iZAQq)F|?UT{&5U#M##r8 zv>72E$Ixbkd>liY5%O^iZAQq)F|-*WAIH#UgnS%Bn-Q{rq5TuR?SB03_1_Kr>nu)YH+?9Jo>k*_ps03y?*-Y#k2kI^+}F5Z?7))pN{{7et{jgvE~As zYh%p?_R+?g3v8K;*Y{O93=O8Rim5ADM}qdolLXHV82*tz`HpUnBcE?>O99!_$&I>`WzDmbp- zq=M55&MG*s;86ul><{(-_~Y>MT)%jA@!5AT-dtZ^z1!D%`Sa6%yx9NY zQuBwOMb}SPzrMbD@y%QR1h`(7@x^$dmG|`ZpI%-JGoD^wKYjL(?UaY@zeiv0?LF72 zU%weXc&4MC=?BCA&Ch>z`TY1(^=1Fr>jqCg{TKT$pZ@7j!%vJ4pCbGA?aP<%KJz)h z(`U<`U8yAzeIns|K{TRr|ko7-#&e&>u3j_{AcaJ6JO88kNejb zSFd!VeSGoF+dm!X+X()C_^J8tE?;Vuy%~PreE<2tSjw~Sp1yv4@$${;@Zq-Zc}Mz8 z>fapv{Nn2Jmp|$^<-hT79bH{sUYB3_ZvT5`edN3K@O>Zt>c{nPeZa5Y>qD|*fxrLr z)o{e&SZqD?!Q)?jHV?L!ZsV@oeL8eZY7&|5a!EulDwCTCM;2>Sum_efeCzclq}E`?uF`)Q{i&;$MFA z^6y?BtcQo|;qXGW1CH0jllAa)Jv>_v&)368tKpZ|y~LN-y~LN-y~LN-y~LN-y~LN- zy~LN-y~LN-y~LN-Ly6yB|NO@{fB0%B(S}2bHXKT{;ZULthZ1c#lxV}DL>mqz+OU^+ zvM%xDt6t*CSG~lOuX>3mU-c4CzUn2OeAP=l`Kp(A^3_=4?=N)~aQ!k9`+I|z5Z)2vC`|m_7W?-{%bGsb!&*^heOC*~!?A>iV+jw(5+05vJRD1SIF|5m zEaBl;LThT}5FQRM!tZ|Z)q%{fj}E`s`!Dx98eW|7h~dQbYt+uHQ9H9n?aW90%o?>bYt+uHQ9H9n?aUgr zGi%h&tWi6&M(xbU{mdG*Gi%h&tWi6&M(xZRwKHqf&a6>8vqtUAC;iMCwKHqf&a6>8 zvqtUA8nrWP)XuC?JF`aZ%%}a#8nrWP)XuC?JF`aZ%o?>bYt+uHQ9H9n?aXKW%o?>b zYt+uHQ9H9n?aUgrGi%h&tWi6&M(xb!{mdG*Gi%h&tWi6&M(xZRwKHqf&a6>8vqtUA zkNTN4YG>A{omr!HW{ujJHEL(psGV7(c4m#*nGbXyZ);q)@jhy27TeCOQ9H9n?aUgr zGi%h&tWi7jVL!7*?aUgrGi%h&tWi6&M(xZRwKHqf&a6>8^HD#uM(xZRwKHqf&a6>8 zvqtUA8nrWP)XuC?JM(crvqtUA8nrWP)XuC?JF`aZ%o?>bYt+uHQ9JWVKeI;d%o?>b zYt+uHQ9H9n?aUgrGi%h&tWi7jX+N_@?aUgrGi%h&tWi6&M(xZRwKHqf&a6>8^I1Q$ zM(xZRwKHqf&a6>8vqtUA8nrWP)XuC?JM(!zvqtUA8nrWP)XuC?JF`aZ%o?>bYt+uH zQ9JXaerAo@nKf!>)~KCXqjqME+L<+KXV$2lS))h#aarA9Uie=GwWkNaz0`ZE{ZIbY z+iyPI|ApR%U0nSqx?%f|Lk_vnAO7RvpH1m~;|gnU{o?wogI|9>?6+|==o?3azHv0@ z8%Kk_aWv=~M}xj`H0T>g!N@nd zUSo9~hreE3$5Foyjam(j+I48uYG~B1L!(whqjnt{wHg|=>p1Gyp;5aIje3pMb?9%s z#_Brsw_am)9r|0ZvAT|5)zGM2heoZ2M(sK@YBe-!*P&6X zp;5bzlYSiHR*H~SL{?==(u0wz8HCET5zx5ic>p1DxaoVp#qgF$sb{!hE8XC3h z(5ThWs9lFft%gSJI!^m_Xw&iH8g71p;4=$QM(R}S`Cfbb!gOTXw(JkN zjn#GNZ@tFqI?nrbJnGk>QLCX*yAF+74UO7$Xw+(G)UHFLRzst99gq5TXwJ4r|fF$EE1u<5KkSaVdKExD-8nT#6n(E=3O?m!gM{OVOiR^r#j+szr}#(W6@Q zs1`k{MUQIHqgwR17Co*-k89E6TJ*RUJ+4KMYtiFc^tcv1sYOp}(UV&Aq!vA?MNewc zlUnqo7Cos&PixWBTJ*FQJ*`DgYthqM^t2W|twm33(X(3gtQI}1MbB!{vs(157Coy) z&uY=LTJ*dYJ+DR2Yti#s^t={5uSL&m(eqmLycT^_i$1DFAJw9dYSBlv=%ZTnQ7!tY z7Jc-1u%drB`2FJ-Z~ich4*Te+kBoPf=&X;<`{+?0`OHuHnLYBEJ@T17@|ivI znLYBEJ@T17@|ivInZNF5_Q+@U$Y=J*XZFZv_Q+@U$Y=J*XZGk|cy8Cau^Juqza96{ zNgti|(ODmz_tB$1@|msvaQK@?KC?$YvqwI&M?SMhKC?$YvqwI&M?SOF`^+Bs%pUp7 z9{J23`OF^q%pUp79{J2)>kZZ4K7a0~qq+$`J_vjm_$csk;FG|ofzJY;2Yv*s+e%>S z(aj}z>d`GGc9^IaTrykv;!0SF0n0j=#3Z8m&&kCM;bmt15dUXE+uUlAP>d}oXcEpgg+mIKMPY&__KKG34az(J>k#dsVDsTApBXFdcvQ@Q&0G_cWGKZ~cH@MrPV6aIV{{wxeV!tiHd=n;lL z3qy}E{8<=!go{7xVLSZUxacu1dW?%6VZFthd&!r5B%9Y^}wIa zQ;+<4_<@1-J;29M6FgcxJldF=;L+x(2_9{pn&8pqsRte{9v*E>J@9Dr)B}$;Pd)Hx z^V9>677vd$rXF~-dFp{jo2MRlw0Y`*M~jC?8&eNF+C25Zqs>zfJlZ_(qm8Kt z9&Mg_;L+x(2Oe#ndf?IG;nBv_1CKUOJ@9Dr)B}$;Pd)Hx@$hJ4>VZd_ryh8;dFp{j zn};4{*plh>zYXEh#?T`ko+u1G!tg|4=n;k|3R6#bG&8jHAVV8d4>GiQ>OqD!Pd&)c z;=`kbanBHDf5M~1vp?a{;@KZ$XxC?d!k?L;bv!b(G5doIZJzx>hBnXsAVZ4}e->tc zkfD7%^&mr=rygWz^VEY3Ek68Nn0k<*eLVFbLz|}_WN7o$gA6S`{8^ZKkfD7%^&mr= zrygWz^VEY3Ek68Nn0k<*eLVFbLz|}_WN7o$gA6S`{8^ZKkfD7%^&mr=rygWz^VEY3 zEk68Nn0k<*eLVFbLz|}_WN7o$gA6@P7&@MrVX1Ai8e{A^4; z$j|1f2l?4N^&mf+rylsTc=)q1^&mf+ryk^I^VEaBJ>k#H&(eeZY)n1K&*rHI`Pn@6AU}%_e-_65LYVyte-_XFgg=XC zf5M-|vp?a_%+Jz`{A|qrAU~UDe~_Qevp>ks;=`YrpUtyB;m<&;B4kn`eKJpT&niGe4VWf5M-2Jo^*=ES~)de-_XFgg-MsOAqq1 zG5dr3Y@Yo=em2kkAU}%_e`bC*&;Eoz>v;Aj{8>Ev6aFlo{Rw|&ewH5OXJhsU`Pn@C zgZyls{Xu>nJ}OLq7KZ-_qd&sXBaHqCLys`}BMd#lr9b+BG5p!M=rJyOjEf%QqQ|)C zF)n(HiymX@fj^6fKO0jI{MkJ9z@N=i5B%9Y^}wISBR?Bc5Aw5l>Op=sPd&)b=BWq% zEFSsUn0nyP=BWq%Y@T}H&*rHI{wyB(*_e8epUqPb^0RsBL4Gz*J@9Ao$j`>q1AjJ8 zJ@9Aq)B}GuPd)Hw@yO4{)PwwNo_dg<%~KEZvw7-)KZ{3xHl`l__KNH zfj^5!em15a`(Z!c=jj!nfY0Ik)Ms( zALM8A><{v@dG-hSS$z1jF#Ch&&pw`dke|&{5Aw5l>Op=MAO6hzY@V-I__L1Z>lOYi zp08KzfJlZ_L54O@J;>1JsRte{9v*E>J;>1J zsRtR_JoO+$o2MRlw0LA_W9orNo2MRlw0Y`*N1LY}c(izAXk+R@hBi+<$k67g2N~Kt z^}wUWBSRZg4?NmD^}wUeQx81aJoUh%#Un!-Qx7t`(Z!c=jj!nHgGo@C@3R{XvE{&;B4on`eKJp~Z(k zGeetaf5M-2Jo^*=ES~)de-_XFgg-MwOAnqw8?!&i(B|16WN7p34>Gj)@MmUd^XyOf zvyNwf!k@*nKjF{f*`M%dW@zcbGiYP>2N~Kt`-2Q^p8dfy=;7-T=+DCNA7S)I7Hcvh9XYt6-#?*uSY@T|MpUqPb^0RsBfj^5!em15a__KNHfj^t49{96)>VZFt zM}9V@9^_~9)PwwNo_dg<%~KEjSv>NyG4;To%~KEj**x{YpUqPb{8>EmvoZA`Kbxl> ztc@C@3= zQxEd9dFnxaHcvgs&*Hks=Gh`(Z!j%RjQ$8ik1+ZpT=eM6 zyx`BqMUQdOV_ftY7d^&Bk8#msT=W=I5Bym?{Mnd#;Lql%2mWlHdf?CIsR#Zn9{Jgr zdXS&ZQxEd9dFnxaHcvh9XYuf7W9mVEHcvgs&*rHI`Pn@6z@NnOp=sPd&)b=BWq%EFSsUn0nyP=BWq%Y@T}H&*rHI{wyB( z*_e8epUqPb^0RsBL4Gz*J@9Ao$j`>q1AjJ8J@9Aq)B}Gu4?W7S#h>++gz#r$=n)S; z6owvQ_@OZL2*VGBsVDrI`B{39pN**p`Pn@6AU~U@9^_~7;m^XjUkI~5;m_jPpYUh# z>`(Z!c=jj!nfY0Ik)Ms(ALM8A><{v@dG-hSS$z02^Rs#OC;VB*vp?a_;@O|@XYuS$ z_%rjf^x*lkG5dr3Y@Yo=em2kkAU}%_e`bC*&;Eoz>v;Aj{8>Ev6aFlo{gFTOGXl~O z9xY5w;nCu$DLh&{HHAlur>5{|W@za{hBoGFh74_GiQ>OqD!Pd&)c!&k!6qlKYI7_XNw^a$hi5{4dOyk5f4BV1lDeUU6Y+PLU3E_#fM z9^<0Nxacu1dW?%6W9orNi-$)WQx81aJoUh%%~KCN+C25Zqs1db8&eN5w0Y`5hBi+< z$k67g2OcdR8QPe7;L+x(2Oe#ndf?IKsRte{9vRx0dXS;bQx7tP7&@MrVX1AjJ8J@9Ao$k4{rgA8q+dXS;b zQx7t8Mb6-eH}LZ*%*4n!w-d_M;Lx63_Zf| zLt*L(e`bc39%N`^>OqD!Pd&)c=BWo6T73AkFzy$^>`(Z!c=jj!Sv>m_{w$vT34dmW zmR@9NWA+Cb+C2M%3~iqML53C|{w&P?;2E@!rygWz^VEY3ZJv6Np~Z(kGeeu_>lOa2 z=O=J;=|-><{v@dG-hS**yD$ z{5<>=0sUDRua_|TBMd#l=#Mb;2%|s3&?8*>qaQGUKN}Z4#zl{D(PLcn7#BUpMUQdO zV@y5pXYuf7W9orFo2MT5vw7-)Kbxl>__KKAXJhI?el|}%$j|1f2l?4N^}wIS!=H_* z2l?4N^&mf+ryk^I^V9=>7LWXFOg->t^V9=>Hcvh9XYVVfH8dSv>m_{w$vT34a#P{)9g>KT9w2voZUF{A`~6 zL4G#R{vbb#4}WHUHqZWqKkIn*C;VAF`xE{wp8W}bW`33)JcBl7e~_Qevp>ks=GhE!hn`eKJpUtyB$j{=#pM|-< z@ch}wQxEd9dFnxaHcvgs&*Ho!>G`?y)YJXB@jX9xOg-J7 zJ5N2`pF2-I-Jd&8J>8!h-}7_F)YJ2G=c%XX=gw14&(EEwp6<_$@AgoR6dFtu@ z+HggKo}W9Wo}QmOPdz<9cb(2-@P5l{k$6P}_LwBA%>KVH8 z>`~9qjSr7rXXwteN8!;ro;?bW7SA4qM~i2V!lTz2y6Nf9pgU%NdWP;i`_nUY=h>g0 zp&K6_z0S~`XMe(@bv*kM9xa~z36B=f{)9)bGj!9_Gjzx7PtVYuXMcKz?mYX`Gj!v_ zqt_X_^XyM}^g2WL7LN>VOg->t^V9=>Hcvh9XYCd1$Pd)t^bmyt3KZ9<3_%k!K^dLhU zQ%`>e-Oooo$k3ioJ;>1F!=Ht5{}Sfw75*%quUGi9c)niY&*J%dg+C7&di<@fcD=~Y z(jWdTOg-Vx;;AS6Sv>WGKQlk8et!nt^o2i*r=IX<@zfLkES`G8pP8Sf2l?5U>j(MS zJl7BMvw5x`E!hn`eKJ zpUtyB$j{=#pP8S{bAN?DGe7%y>Op=sPd&)b^|w^U*F$+0ua_|N2%|s3c)f(7M;Nb{ zF!TtQ*Gs=80Dm?vdW?%6VZF-rylsTdFp{bi-$iOQxE*vJoUhz%~KEj**x{YpT#3T8&ePb z**x{YpUqPb{MkJ9z@Nn7LWXFOg+fY=BWqy**x_iKbxl>__KKAXJhJtKbxl>WGKZ~cH@Mq;&>Op>1zrvq|sVDqd zJoSV>i>IFOXXRPyL4KB=@MmG_34az(J>k#dsVDrI`C0XmpN+Ymk)O?TJtIGx=Xyqd z79ajB%>E!h`*`X>el|}%$j|1f2l-ii_%rjfd9LU1XC2SiEBskJU$5|I@qE3)pP8Sf zr+)@|$g{@mPyY-@=h+|RXU}JUke};ssf_1Sp2h1WjQ$8ik1+Zp3_Zf=k1+HIm;UIt z1mMrcMUQdOV_ftY7d^&Bk8#msT=W=I5Bym?^0P7Zz@N=i5B%9Y^}wIaQxE)EJp9?1 zdf?CIsR#aSo_gTV=BWq%EFS)BOg->t^V9=>Hcvh9XY z__KNHfj^5!em15aP7&@MrPJ&&Je){A`|jke|&{5Aw5l=uv(x`B}de0Dm@y9`W!) zVdxQt9|}W{F#J%MdcvQXpQT6nnV%8x->3;0+B`KOLz|~2WN7i>(ZaZA2(w4w(c;;o z@M!VuQFyd?_9#4BnU;Exp`|}OT9|smqs3ECc(i!x36EB$r5{(t~Hv#_SI=w0ZUi8QMJigA6S`JenEWJo^(K zt>f9B@M!VuPk6L=^hX&M9xaUZEDSxu=#Mb;2%|s3&?Aig2p2v2EdhA6anWO3^cWXC z#zl{D(PLcn7#BUp)B}GO4}UhM9{96)>VZF-rylsTdFp{bi-$iOQxE*vJoUhz%~KEj z**x{YpT)zUjj0FzY@T}H&*rHI{%oFl;LqaW&&JdPe>P7&@MrVX1AjJ8J@9Ao$k4{r zgA8q+dXS;bQx7tIr{lhL#>YgEpofk#dsVDqdd6s&RpQR`KS(tjlpT$#8__KKG34d0er5@yG=?Q-p zrk?O;@zfLkES`G8pP8RkANkps>lyjkJl8Ywvw5y(Op=sPd&)b z=BWqyS$z02^Rs#GukdFb&(|ybSv+5_@MrOSy~3ZFpQQ)SppDrdqu&yMKN}Z4#zl{D(PLcn7#BUpMUQdO zV@y5pXYuf7W9orFo2MT5vw7-)Kbxl>__KKUvoZC+pUqPb{MkJ9z@N=i5Bym?{Mnd# z;Lql%2mWlHdf?CIsR#Zn9{y}hJ@9Aq)B}GuPd)Hw^V9=>7LWXFOg+fY=BWqy**x_i zKbxl>__KKUvoZA`Kbxl>Op=sPd&)b=BWqyS$z1jFzy$^>`(Z!c=jj!Sv>m_{w$vT34d0er5@yG=?{Mvrk?O; z@zfLkES`G8pOt5+2l-ig!k>kyC;VAF^@Kl*r=IX<m_{wyB-QGSI#3u8SCLys`} zBMd#l=#Mb;2%|s3MUQ?<0RC)T^cWXC#zl{D(PLcn7#BUpMUOG{z@Np#pN**p{%oFl z;Lql%2mWlHdf?CE;m^j@1AjJ8J@9Aq)B}GuPd)Hw@$hG3>VZF-rylsTdFp{bo2MT5 zvv~NkG4;To%~KEj**x{YpUqPb{8>EmvoZA`Kbxl>E)GHmf^eYZb6+8BDo!xM#}M;M+c3_Zf|L}BU)k7kCJ9%N`^>OqD!Pd&)c=BWo6 zT6}o4Fzy+`>`!>Kc=jheT0Hv`9xa~z36EB$r59j4=l;So4)c7y!k=|M zzFy(a;`w@oKQlwC9-cuPvp>kt=Gh-)X!Gn3GIaedmEjq*F;amE_#fM9^<0Nxacu1dW?%6VZF-rylsTdFp{bo2MT5vv~NkG4;To%~KEj**x{YpUqPb{8>Ew*_e9Z z&*rHI{%oFl;Lql%2mUM`8QPe7kfF^}4>GiQ>OqD!Pd)Hw@$hG3>OqD!Pd&)c=BWo6 z+C25ZpT#3X8&ePb**x{YpUqPb{MkJ9z@Nnk#7)D!+Jo_fNc#ZyoCGxM|RBR?B+JtIGx=XyqdHqZ5p z{475Fnfci~*K_!@j%REw*_e9Z&*rHI z{%oFl;Lql%2mUM`{%lM=@MrVX1AjJ8J@9Aq)B}GO4}UhM9{96)>VZF-rylsTdFp{b zi${JorXJ*H^VEaEmvoZC+pUqPb{MkJ9z@N=i5Bym?^0P7ZAU~U@ z9^_~9)PwwNo_gTV;*pOp=sPd&)b;=`YXala5|f5M-|vp?a_;@O|@XYuS$ z__OjX^&me>fB3U7^@Kl*r=IX<@zfLktUOCS$j{Of{wz#A;m_i!C;VAF^@Kkw&r%Qa zv-E^N3sX<{vv}$We-=+Y;m^#^s*n6^%=L`?Y@X{G`Pn?zGxD?e@MmH62hX2-1_tT7jN)eDjhdH9XCB4H$5FU zJsmea9XCB4H$5FwPxt4>cYp4fdb&S%o_e}JcbKX;ybx<5C*`*X+C)BU;g)YJXB z^VHM*x%1T1{kieopF5_W?$4d4p6<_`r=IT5ou{7e&yDZ?+%ffZfA0Lr`ZEIkZ(Kv& zqdU(v)IGZK-J?6^n(iLmd9La1(VeHB?$Mp6p6=0&?;hPT^>mN!JoR*s?mYE$kM2D6 zbdPR)_vntPr$6K9JoR*s?mYE$kM2D6bdPR)_vntPr+akgsi%8%=c%WAbmyt3d-TXF z!?q0FG4zPXnihs0VeBzs=n=*q6NVmP>@j6z>gm6y()9HV-7)p_4BdI^=^487)YCI` z=+0A5&(Mtz zk5;Coo}Qum@zm2Zbmyt3XXwsTPtVYe506%+rJkOl`|;G%Gj!*vC;VCGr=IXh}!YG533a#?g81_x_Bd^W5+K8As>2-@~8R z8M+-G{w$vT34a#P{)9h^XMe(+^=BMSPx!Nrr=IX<@zfLkES`G8pOs;uM;Pl_ z7_XNw^a$hi5{4dOyk5f4BV1lD{gwdy*|_L2E_#fM9^<0Nxacu1dW?%6W9orFi-$iO zQx7t@VdxRY>&5&mJ;=|-)YE^D zaC|*=JoWV7BkVl&^xq@wJoSV>Ge1iY^0P7fgZyls{Xu><&;B4kiw}Qhem2kkgg@(e z_9y&VJo^*=ES~)de`bD`9^_|Z_6PadJo|(EY@Yo=eik48%=~Pg{Rw~8@$66dvv~F= z{8>Ev6aK7x%l(D?EPdh6!qgM~ES`G8pT$#8`1AT1bX)&;z9Bu~&%)Fb{w$t)!k@)c zPxv$Qv+9RG3v>O1Ka1!334a#P^%MTg{H*%O&&FIo$j|24ALM8A><{v@dGts5wd802 zwhGpdc<2#Ee}th&82u539%1xHxaiSu2_Qck7d^&Bk8#msT=WqgZylsdXS&ZQxEd9dFp{bi${JorXKjSdFp{bo2MT5vw7-)KZ{3xHl`lrXYv;Aj{8>Ev6aFlo{Rw|&ewH3Qe>P@+ke|)7KgiGK*&pO*@!`+H z$Q#1!Px!NV_9y&VJo^*=ES~)de^#EQ9^_}~4}TV>p73Y!)D!+Jo_fNcm2asB`B{3x zpM|L>{8>Epgg=X?p73YpXVu5^4P&k!Jl`67LN>VOg->u^V9>6Hcvh9 zX!Fzqj~0&%ZA?AL(B`QJ8QMJcAVZs{9(c5Pc(gI~z@yDm4?NmD^}wUeQx7~^JUrT% zdf?IKsRtfyo_gTX=BWoBEgl|iOg->u^V9>6Hcvh9X!Fzqj~0&%ZA?AL(B`QJ8QMJc zAVZsn9%a~)q4iq<$k4{nBOab83_Zf|L}BO=h9?SBPk1ylwDcfD8&eN5w0Y`5hBi+< z$k5`$qlIzL5N3bEqs6m7$k0AN`xE}G`Rq^lGc&Z#hYW4Z{vbn}XMd2P&9gtq(Bi|N zh1nlGgZA;%gA8q+dXS;bQx7t<`0!_DX!Cr%!k=|KU$5|I@qE3)pT+a_3V&9nWq**N zr7!$hn0msW#ZyoCvv}$We^#cY9%N|g34a!*p73Y!)D!+Jo_fNcm1(I58CrV6pM|L> z{8>Epgg=X?p73X8Xw^rCHs*RphBnXjj0|m_>lqpPxO@(J$k4{Ny zG4;To%~KEj**x{YpUqPb{8>Ew*_e9Z&*rHI{%oFl;Lql%2mUM`{%lM=@MrVX1AjJ8 zJ@9Aq)B}GO4}UhM9{96)>VZF-rylsTdFp{bi${JorXJ*H^VEa`(YJ^Rx8e8MHC`gZyls{Xu><&;B4kiw}Pm=K4W?_VLt%{A`|jke|&{ z5Aw74@MmG_L4Nk})PwwNo_dg<%~KEZv-t35Vd_DC_VLt%{A`|jke|&{5Aw74@Mq>{ z^IXs2&pMv#Is92X*K_!@c&umTSNO9q`XdZI!sw4M^a!Ir!q6j({s=O=J;=|-)PwwNo_dg<%~KEZv-t35Vcai-*`M%d@$66dvv~F={8>Ev z6aLKnEWOCj#_SLBvw8Lh`Pn@CgZwN${8^a&!SiPyPd&)b=BWqy**x_iKZ_54W_~u$ z*DL&4$Mf|He-_WzEBskJU$5|I=4a_ael})*ke|)7KgiGK*&pO*@!`+R&*s^m@Mj&* z{)9h^XMe(<#j`)*&&QR2? zX9Ro;~$E_#fM9^<0Nxacu1 zdW?%6%~KCDw0Y`* zM~jC?8&eN5w0Y`5hBi+<$k67g2OcdR8QPe7;L+x(2Oe#ndf?IKsRte{9vRx0dXS;b zQx7tGiQ z>VZd#hesPz4>GiQ>OqD!Pd&)c=AlO!wq$61w?8tpG4zOs9|}W{F#J#$dW7MJ!qgM~ z%nU6($k4{rgA8q+dXS;bQx7t<`0!_8+%JULpYUh#>`(Z!c=jj!Sv>m_{>%(5y~xnU z><==udG-ex+C2M%3@twVnHkzV`xE}GjQ$8ik8tUaeoFxUY+U@%xacu1dW?%6t^V9=>Hcvh9XYVZF-rylsTc;she>Op=sPd&)b=BWqy**x{YpT#3T8&ePb**x{YpUqPb{MkJ9 zz@Nn$d`spN*kMJp51?dW7MJ!q6iOKNO~(@Mq>{=|O%rrXJ*H z^VEaINwi)VkrpT)C3;m_jPpYUhqXX!{>A^E- zWA+F6**yD${A`~6L4Fn={>=Prp8W}b*7595__KKSC;VAF`lI{`e-_665{4dO^hX$a zgwY>i=n+PLgo_^imH_VZFthd&!r5B%9Y^}wIa zQxE*vJoUhz#Uno(QxEd9dFnxaHcvgs&*rHI{wyB;Y)n1K&*rHI`Pn@6AU~U@9{96( zVZF-rylsTc;she>Op=sPd&)b=BWqy**x{YpT#3T8&ePb**x{Y zpUqPb{MkJ9z@Nnc7`-A*!p8Y|7HqZVbKZ_54W_~u${)9j4 zc=jj!Sv>m_{w$vT34dmOmL5ERHfDd2pUtyB$j|24ALM88;m^#^=GmX{XC2S}gg=XC zf8@{njDTyfN8!=T&^jK^ppDrhWN7p35i+!S_6QkTe0Vf7w0ZU@JX*)IN8!=p*`x4i z@$64{G&8jH;2E?r`-2Q^p8Y|FHqZVbL)YI^8J;=U-&5%r{ZZzH9%1xH7XZ-~YJ&J(Y?FPpo**Q}Lju;z3WvgPw{9JrxgnDyE*%qu2cC(G^qA=+Tv@ zp3$Q#Pd%eYSDt!Ck6!a*hOU@;#tdC~>KQY1<*8@P(3Pj2(WBS=n4v4Cp3$Q#Pd%eY zSDt!CkFGrRj2^w_#|&LD^^6(1^3*eC=*m;in4v3AJ)=jj`7uLROg*DVSDt!CkFGrR zj2XJ})HC|?njbTC#ndxq=*m;in4v3AJ!6KhJoSwJyynLYT`~2H{#<$L8U4BP)HC{X z<*8@%=QTfO=!&Ul%+Qsmo-spLo_fX%U3utHh8;3==Y`>i!q6iOKNN-@Vfdji^a#Tb zg{f!E&}%*8cR^Q7J>z#lSDt#t?}Dy8^^D&IU3uyWe^#btf5r^Go*(|)GIZtHpD{yM zp8Xj!^qLQUZW+4r>`(Z!j%RxUzirJqrLsy>t88dX{*`M(l z^qLQUZuz`(Z!j%R+k zY+Uph7d^&Bk8#msT=W__KNHfj^5!em15aNyG4&uno2MS+XY7LWXFOg->t^V9=>Hcvh9XYxUzH6Q-W{471l&&Jd< zK7+33qaNgE&!-;bXYt|B!nl74^YsdU7SGo!{8>C-ukdH_e7(Y-nV+Q>`PrELL4G#R z{vbb_XMd2N#fLu&vp?fA==JLn{;cEKpYUh#>`(Z!c=jj!nfY0Ik)Ms(ALM8A><{v@ zdG-hSS$z1jF#9t;e_r<|{8`7dKjF{f*`M%d@$66dGxM|bB0n3mKgiGK*&pO*^Xw1u zv-t35VfJTy{=Du___K~@f5M-|vp?a_;?W=FSNO9q^ax|W3!^{6&?Aig2t$uB`XgNQ z=(hym&&EZManWO3^cWXC#zl{D(PLcn7*h}YSv>NyG4&uno2MS+XYP7&@MrVX1AjJ8J@9Ao$j`>qgZylsdXS&ZQxEd9dFp{bi-$iOQxE*vJoUhz z%~KEj**x{YpT#3T8&ePRvw7-4el|}%$j|1f2mUM`{%lM=@MrVX1AjJ8J@9Aq)B}GO zkNj**J;=}IsR#MlJoO+yo2MT5vv~NkG4;To%~KEj**x{YpUp#$@@w&DeYZdS*%*4n z!w-d_M;Lx63_Zf|Lt*L(e`bD`9^_|Z>Op=sPd&)b=BWqyS$z02^Rs#OC;VB*vp?a_ z;@O|@XYuS$__OjX?q9;x6aFlodcvQ@Q&0G__($zC0xd(R2jS7o(B`QrJX*(7Q+Tv^ zY6_1Q&mM(GGeb)cGPE(*5HhrRt|4S-^ISv7(Bi|RnW4?IKjG0jp8W}r7SH~KM~i2F z!lRj?r3V?>nEgS9HqZVbLz`!RkfFtgM>9j4XMe(@bv*kM9xa~z36B=f{)9&}LrV`b zv@!dG3~iqML54QZ{vbp5-&5)PO_>&ZUKsrmh8|(`M;Lm9(H~*x5ib4FZwbJojf)=R zqQ|)CF)n(Hiyq^m$GGS*rXF~-cw}f}>VZd_ryh8;dFp{jo2MRlw0L;5G4;Ts%~KCN z+C25Zqs>zf{8>CQv@!L-pUqPb{MkJ9z@N=i5Bym?GPE)EAVZs{9%N|q)PoFdo_gTV z;*p_^sR#aSo_gTV=BWq%Y@T}H&*G7xjj0D2+C23jLz|}_WN7o$1Ai8e3~fw3@MrVX z1AjJ8J@9Aq)B}GOj|^>0J;>1JsRtR_JoO+$n};4{*pi|3-Tv@rW9ShNKNN-@Vfdji z^a#Tbg{dd}nHgGokfDvK2N~Kt^&mr=rygWz@!`+HxL*jfKjF{f*`M%d@$66dvv~F= z{8^cndXS-|Km1vkdcvQ@Q&0G_cxKMmp05}3vw6N=$j{=#pP8S{ z^YsdU*7595__KKSC;VAF`xE}m{470q25rp#AU~UDe~_Qevp>ks;=`YrpUtyB;mVZF-rylsTdFp{bi${Jo zrXJ*H^VEaEmvoZC+pUqPb{MkJ9z@N=i5Bym?^0P7ZAU~U@9^_~9 z)PwwNo_gTV;*p z{8>Epgg=X?p73YpXVpi3Hs{^ISjS&pMv3SNOAdzFy(a;`w@oKQli|51v08vp>ks=Gh`(Z!j%R{S$z+5d;V;U z^{jl0{s=>lF#015J;LaZF!TtQ{^+*^;LpZIk8#msT=WEw z*_e9Z&*rHI{%oFl;Lql%2mUM`{%lM=@MrVX1AjJ8J@9Aq)B}GOkNj**J;=}IsR#Ml zJoO+yo2MT5vv~NkG4&uno2MS+XY7LWXFOg->t^V9=>Hcvh9XYmBOZPz3_Zf|Lt*F!oMRl zPfhrDgyyLU|Blc+HHAkj)8d{XOg-Vz;;AP*T0HfHM~kPP@MvXP>OqFq^@K+YQ%`ub zcbv*kM9xa~z36B=f z{)9&}LrV{yK^wC_$k685A7p6r><==u`0!|EX!Gn(c(jgZf5M~1vp?a{;@O|@Xl7{X z!82%M_6Hf-Jo|$TZJzx>h87JX$>ZqYMj=7RG)Th8|(` zM;Lm9(H~*x5k`N6iyr-!05Y_3(PLcn7#BUpMUQdOV_ftY7d^(*1Ai6|e>SEb__KNH zfj^t49{96)>VZFthd&!r5B%9Y^}wIaQxE*vJoUhz#Un!-Qx7tGiQ>OqD!Pd)Hw@yO7|)B}Gu zPd)Hw^V9=>Hcvh9XYt6;#?*rhZJv6Nq0LhdGPHT>fj^5!hBl@i__KNHfj^t49{96) z=uw6({;cozhd&!bk9hc@F!Tt+4~3ye7=9>BJ>k#H&(ecu(8kn*XVB)U2hX6*QxBd& ziw}Pm#{EK={Rw{-&;Eozi)VkrpT)C3;m^vm)Pwvi{o&8T)D!+Jo_fNc#ZyoCGxM|R zBR?DS^+J9&&({n2**sq_Op=sPd&)b=BWqyS$z02^Rs!bpYUfL z&(|ybSv+5_@MrOSy~3ZFpQQ)SppDrd{8`7dKjF{f z*`M%d@$66dGxM|b;2E?r`-A*!p8Y|7HqZVbKlk5KY0sehZ>dy_{wVK4k1+Zp3_Zf= zk1+HIm;UIt1mMrcWq%nLJ;p_kanWO3^cWXC#zl`Y^}wIS!=H_*2mWlHdf?CIsR#aS zo_gTV;^EK6)B}GuPd)Hw^V9=>Hcvh9XYt6-#?*uSY@T|MpUqPb^0RsBfj^6fKO0jI z^0RsBL4Gz*J;=}IsR#Zn9{Jgrdf?CIsR#aSo_gTV=BWq%EFSsUn0k<(%~KEZvw7-4 zel|}%@MrPJ&&JdPe>P7&@MrVX1AjJ8J@9Ao$j`>qgZylsdXS&ZQxEd9dFWAoE%{l$ z6@dI~3_arEhr-Y!3_lcx9%1;QF!h8#Ge1iY^0P7ZAU~U@9^_~9)PwviKKxl2_X}b6 zC;VAF`xE{wp8W}b7SH~KKP%5t5Aw70hd&EbPx!NV>Ir`qPd(w!%+IQi{A|qE3;EeR zUoYfm^L)LKpT&niGe4W>>lOa2lF#020^ys$);LpZI zk8#msT=WEw*_e9Z&*rHI{%oFl;Lql%2mUM`{%lM=@MrVX z1AjJ8J@9Aq)B}GOkNj**J;=}IsR#MlJoO+yo2MT5vv}lZW9orFo2MT5vw7-)Kbxl> z__KKAXJhI?el|}%$j|1f2l?4N^}wISBR?Bc5B%9Y^}wIaQxE*vJoUhz#VbGaGXnk_ zH6cTrrzT`*^VEb4ZJwIo(c+Pzjj0D7ZJv7I(dMZK9&H|alwpfU>%0Bo(ZlaiW`Dw?#j`)*(c;;k z@M!VuPk6L4E%hKnOMiH@F!h8-i>IFOXz|n&9?cA``pD46e7%sN&GYp_hBnXF3mIB` zc(gG4gJ;k_o_dg>%~KCDw0Y`5h87nA)~$Mf|Hj~36@D?C~}U$5|JW@zcb zGiYP>2N~Kt`-2Q^p8Y|F79SqX3~iqM34hk{>`(Z!c=jj!Sv>m_{>%(5J$MFf%>E!l zn`eKJq0O^D$k6?_RN6D={#z;)qd&^L&?Aig2t$uB`XdZI!o5FN@mnel_x;sy*VAy< z({R_*aM#mt*VAy<(=hcEe>PwIxnb%l{@i%#DgNAe>M8!*cp5o7qr=H@^ji;XC&yA;^;?L$whHjX8N``Jc^^^?VcPw8bHmhA@^j;X^@Kkw z&$2%yKYM=obIs3lt6of zm+$-A;5)mlb@n-PW}iKCXXcjjv#+1c&f`{LIi%<)kD ztagrv>SwicJXAlco#UbW3_I1&Dsw!PpViLsP<~cB$3yv9?Gz8{SC^mhTLP4yRi=1g zr+f&R;(<*05HiIBneriIj;EBL{q^VG7R2MOKby?)xa-em=Xl)pXR~uW?)tOZOZl1W zXT(GGv&tNgyZ&r^91qpcisyK!eull2pSgZkJMXVjeuh8quTp-7o%dHMKf})ZtCXL) zenvd*`m^@Gl%HYecuM&hc8;f%pJC^CO8J@VXT(GGv&y``sD4&E?=PyK)z15i>Sx$X z`I+lywe$We``dRH957p1Gm+~`Ys(&DJJf-{$JMXVjeuka*S1CWk&ikvB zpSgZUyi`A{%=?S#XSMVAQ2nfS9v`ZoVK3!p$UHvo`m@gGQhtU%k54H-!_MPV%FnRV z_@I8J{0y1mflT`gGK~*piU%@{4`hl5GK~*p7Y}|*fbz4-E*_O#JSw|*RCe*G?BY?` z#iO!|M`ezO@-ysIKda2~Q2nfSj)&@JwR1dFKdYVNq5KRx)z2z(Jd~f+&hb!wRy)T- z`C08859MdrseV?Ob=XfYbtDWPa z9IbYW2Q{qA(RjB%t8u3yMtul{KDL=!X z$ETE^VdwEFpnP?^W4l%KhVR)3C%YG}1{JXAx&Udqpqd4Ew2t^PbdR70zs zCGuO~+=kY1!XZZ8{DdlI_dH$60GweKnO8J>SwicJd~edr~Irk$3ykA+BqJo zpViLsQ2nfSj)(Fy>{LIi%<)iuRy)T-`C08859MdIb3BxvVW;|8WsZmHXSH)YR6nbo zmTR)3C%>SwicJXAlco#UbU8TL|shRpF${jB~R57p0V z=Xj`oRy)T-^)u|H{LJ;U+Ijwz@-x@Z>d)~|{j7G5hw5k8OZl1WXSH)YrTh$kp3kNH z3_H)~QhtV==W{7PbN!5X=o+-jyuYY^Ry&Um)z50@@uB(|_ELW4`dRHfKBfE&e;%Jw zeukaLr<9*zr}07kO8FTw&1c9I4`do2$P^D`8Xw3M4`do2$SxlImH_2vm0dh4yLeP~ z@u=+LQQ5_#vWrJ$7mvyu59MdrDL<>s@lbwNJI6!$S?wGTSwicJXAlco#UbW3_Im#l{p@&pViLs zQ2nfSj)&@JwR1d_pJAu^S!Irg^0V4G9;%E({ET<|Q+`&N;(?v=A!LdNGUY?a6c1#|hmbj*Qhw(88Szm4tTM+#^|RVJ z9;%Swic zJXAlco#UbU8TL|s=K5LfJU*rT41bhYUg;UhE_YrLp8M8IUdTzP3YG{=?9?H>b=XfYbtDWPa9IbYahjKLRR70!G@lXw|c8-T? zXti@ZR70zs;z14TYH0jc0M*bcQ#`O!PJ~SHK&G4snc{&=IT13)Q_9g?Ln9ulp;hL1 zsD@TM$3r!=+BqJopG*<7@j#~WflTp0rtyJH@j#~Wf$ZYJZwXL- zR@ud)vWrJ$7mvy=9+h1@D!X`8cJZjp@lbw-o$|BF91rDZwR1d_pViLsP<~cB$3yuU zcB-FM=6I-nRy)T-^|RVJ9;%m88WRGka>Jc`5AT|pHhB?oyVt?pJC_mDdlIbpAj$B z&nolyQ2nfS9v`Zo)z0HX^)u|H{LJ;U+If6R`5FE^KBfE&JC9E(Kf})BQ_9a=KO-Kx z2CXuW57p0V=kcNXS?xSNR6oOB%FkRstDVQEl%L_x<5SAdu=Dto@-yr_KBfH3^)uq3 zYtSn5_)z_j}O()YUlBx`dRHfK2$&RZ>jXQ@NcP@Oyh%km*Rm;;{%!EflT8Anc{)$#s|M8 zK>1l^mk(8T@u=+LQQ5_#vWrJ$7mvy=9+f#B%FnP|q5Q0Nj)(HI+BqJ|&uZs* zC_lqa^|Q(x57p0V=Xj`oRy)T-^|RVJ9?H+KQ~j(m$3yv9?Hmu~XSH)Yl%Lhk@lbw- zo$6SvWH9@r@#LZ)~iQ$B=D@j#}02$|z4m88VL#U4K@8j)&@JwR1dFKdYVNq52v2Qhw(8 zS?#>PO8FW7yuV8M8Ft=ZrTh##@2^sR=K2}&(Di4Pd3>mTRy&Um)z50@@uB(|_ELW4 z`dRHfKBfE&e;%JweukaLr<9*z=kY1!XRe{LUm%<)hSt#*!wYG}1{JXAxgo#UY#4Ljv%l{p@&q1Ddu zPz|kij)!V!wR1d_qhY5ST4j!hab=XfYbtDWPa91T0w&?<90R70zs}T9 z>^wfD{0uvfPboih4UKrIhE|!!hiYiG^Y~B=t#%$Cs-a;o*wx41@;Hoe6)iiBBMP|bS5HHtdcTU?{4V7Np!oEHYZPhC zTU?_^Xx`!)MJn?a*C>)$VL^rI1=lEQOK)+FqN?;3*C^^qZ;6er^~phm*r*7xQ4wOJ zBE&{Th>eO68xwE;)$c8g|yVQq^`4kEZl zU2+hMYt$tNvA9NEauADa)Fp?tEiO5T;2L$wK`gFOmmI|68g#0i)VsSln$w4fxr!F~&#r4!B z2eG)Gy5z79N3iRuOAcajJ$1=JEUu?6If%ve)Fp>?IA~o@U2+hM>#0i)VsSln$w4fx zr!F~&CF|)0J?^x^gsi6~WR04T_0)u{Q4_MBnvgYWLe^6gT%&n%P)nX1OmL0n$-ykH z(L6br#Wk8I2eY_F^W>nGJUN))8qJe~SzM!eaxjZ)G*1p@agFB5K`nW5Fu^sNCkL~* zM)Txg7T0K=9L(Yx&69&#^5kHGYcx*|W^s+?$-ykH(L6br#Wk8I2estM!35W6o*c~L z8qJe~SzM!eaxjZ)G*1p{$&-T#uF*U>n8h`kCkL~*M)Txg7T0K=9MqC02NPVQd2%p| zYcx*|W^s+?$-ykH(L6b*B~K0}xJL8jU>4VCo*c~L8qJe~Sz@D7?q?YZ77=1{5Fs`y zLQD=K#70Gk$w7qJs0cARh~OG^$w6v=*JxfjXgDr86sHwtagFAcgIQdodF7xMmmH+_ zca7$igSok$=9Pn4T%&pAU>4VCUOA}6B?qbfU88yBU~aC_ymBy$Yc#JM%;Fl&D+jf> z#3_A#NvADst2*Sp1SHmEUu?6K}h}Ydg>B{ zSX@tCf)I=AsY?)IaXobjLh66lQB{SX@tCf{^;(_0%N@vACYP>Om~7r>=Ssi|eVY9>n5$>XL)h|E{Ml zIf%veG(WXK3J{CysY?!GaXrnG!|IN%;u{MSvPMnFdTK(}s0mq5O~@KGA?v9LS)(Ro zJyju34koxp^WrOP(A|aE<24!7Q%PJUN)fHJT>}v$#g{ z}wdBdc1lMSu9L(Yx&69&!T%&n%FpFz6 zPY!CylY|yK`gFOmmK75!Zn%(|yLCz*zqj}|^jk@F@ zZmv<69K_-pb;&_2u2Gj9{n)4o zF*%43lY#0i)VsSln$w4fxr!F~&#r4!B z2dVvCPhD~li|eUN4q|aVb;&_2uBR?Jh{g5PB?qbfT~A$d5R2=nOAcajJ$1=JEUu?6 zIY{mAdg_vcSX@tCauAE_sY?!GaXod(K`e{MhtPE1K!<(|=|}Tm_F+ns)YhDNHlL@; z=JPUTvwAjXxaQ`ejtL>OEFb9W)6YTs9O~;sBP*Ay^UCGQuyVOFv@B6&%Mw+#EK%jk zOt~^su7q+oz&l#o`a65N`||CkHGReQTDQHf*lu<{&CaJ8J`+PYr@McH(Bzx&$TtfI z;V`XGgjFkfN%4_z>0xon_9cOJGulXF3UUnwsc_-H+OXRkKjVxPq5$; zUK4zpmo?2D=$swGhOVuh?UhzHXq9c9{hKOqsI+d`(%Uo8xmm}u05%MC7DA&J=6PYh z7Z!M7p%)f;VX+tH4!U+4ywK={d0v?Bg#}(%=!HdISnP$lL%vZjG~q>X`>w9EUW-FwV+Z!M z!NsN0x22<_{phq~Z$}rxxHcopJm;YGq0Y@)`!}_AbqyAr{hNBX_VvrOMlfwX9UC@u zwn>bKg>Zh+pBP;0)$od4Mx4u3sBGy$ACS35a6BHZw_ls3j^irrF^wEoX+>8yci`WS z-p=lgm1{e?dfG4=7~drWoj3$9mKIUjs8$jX!t3ul2>ottAK5+?DY~a0@Q(KO!OFFr zeQgro-~zG($zZH(Tlv9@9m3a zcja9`zC$JuX6#V1AP=={TQRq3{lMZ72IjQ&Y~Iq-Ewcp^WBt~i!B%W$yJ-vZ&erbE z{tBkhMjY?0m{Hp*-IA5&W-JZ0u{2~XjkU2fW-Rk+W0{w+%&(1Qe#Ww(HkJh$%fi}N z7G^AqYGYZHu`I5QWpT!WSvQDTH(2wmtA(YQb+xb*v#u7FV%F8dQp~zqSc+L!3rjKU zYGEm6T`erdtQ*3t8>)HM)xuKDx>{I@Syu~7G3#n!DP~~&8fo(RS0hb60c)hm zXJCyq#S|RG6dYl>-I*y^6HPG%YoaNpU`;f6@@rmS6HPJwYN9EoUrjW{^s9-cn0__U z6w_}A({F@zcW0(wO*F;ytBIzVel^h))2}9)V*1rYQ%t{_Xo~4q6HPJwYNC>~+bxUbvE2Gh^Xw7IuXEcqGMz_>a zx0FVi-t_+ zpYQJ|CPc$1hrF@A6T;K^5voIUetI)Hqj-OXq4sjdRtwbgnkkI9H8J=W0WZbJe(Xt~S;0E8BajqJd&eg^m=c;k(Ty3mzt{Rul)y5j< zs&VOD)f%9G88R%@0R64q8}a3a+%_?aI-ov$MJ-StzM>we4_{Fe)Q7LA3+lsH)CTq8 zE9!&#@D(*eefWwxp+-K-<#K~eRx8wpuc#O5!&lS{_2Db(hWhXowL^XQiu$2Gd_@gW zAHJfFs1ILJOVr3``CjL<))V#ND{6}R@D+7MefWynqCR{@eNi92qQcFs$h4TT~PseOp?)w{`Y)jC|MP2v;0xASud=8c2$oq6U(pkf?#A zs2*w{DN2SKNQye429lyUsDY%Y2u4FPtPH4uq*(iFASo978c2#&z6O$FX|I8#SkG%9 zDHib>NQ#xa29jdA9u3K`HM$0pVqvaASssM8c2$Dw+518v8{omSYc}*DVEh5 zNOZE{+`V~y_Zh`9YF}TB_5yxg$ns^iE@b)gS{Jf>nXL<1zTDP@EMIo(LY6PTbs@`_ z;kuCJ%W-XFrDeG;Wcl)37qWbrt_xYdT-SvxU$*N)mM`CRAO@$S5_KXh z%85D=79~ZU2#d0!PJ~5iQ76Kpyr>glQDW4IuqZQXB^*|2)QPYtH|j)KlpJ*;EXs~L z5f-IKod}EaqfUfH2~sD*q711MVNr_o;Q`+KE`xZ%-!54s9->TM@o!#V3rkUS)WT9! z8nv(#eL z#kyMyOR?D2!XmS7Wj`JbT(%`{T@$zZ@ie4bn+7(;&B0=GC~h_v4$Xx_bK&40J?zz2 zT8;ROn!Kwie-n{DhUgwWtk|Q6dXGR)ck%q;=s5>-&ic>|IlB0;#!g4)9wwCddIav1_2r2eGA$1v%?`nfQ;~rd>Vq6L*T7^BLrp> zr`!zQb^y!>k&TEM0%nBJhGUR5>}7Nqixq7czT-xWGIp#xdwpF#gaR7`Y=l6!2O9!x zgjh$0VJPQ}7-Z4KVNqf@fg2&p?c#=j8zIaz4#V2g+S%3A*)3a5OS-mfYTX}iee2%X zg?9mNz+2h+TidSI7vjNfLudEQ5c;z%96)#mtFybczoXJO*w^2&c{ibGZf)CCsZ#?c9r== zKTw(oR<*1i=)4#&wC(TR+J?gs2X{S3DsN-3&TaUi%G(&Ka~poFu<*4sH4Sv0gE#2v zn@;PHq%zLInmPSgWSm1aa}Mi!^FZgh@>XMgxmmqB-#l15>9F2657kcUyN|*V&#UUc z{rYbo{>AsP`mbnk^>L37e_A-tTowQKf{4#XrLh_$CY1rsWkVwiNFQd~xt#ns%p z5hqRRw7GR7UbeecUdof20((&uz~S_!ghL7U6m8o+LEESw*Q~|&`&k{izN3FzM@Khy zs+@eU)we?z89q+ZzI14AfRy&aou+;2$nj2PJpp{mcU4zr^>=RWn6sg?3op#>XqRcY zvVS#RlH3GM%iKGVqP@MMr{>Cn=4Y>qDt+Xt#4a0sdD06j=SMM zCGG}}yYW9I?naJ#-hWEm^EmGL|0!|L=eQUAr^LO0<6iim68A!md(nSN+>1Ew#s4XB zFUBt$th%~mTctJoIRq@Ma=~U+XLld&p~HV2JzM)`?}n9fs8jq}<{p{^;M!HbL|{>H z{tY|e-{AZkcfh~V`On({|9Q@T{to!hcm4}@z<+`BU$_JQ3!VR>9q?b|{1@+l|42KP zD-M)Hwo|i`1HbCPB}d=zdBMB6#L%$Q3=JiQ#+_zpEHTX6X@+?vhWR_qFu%mGV5b=t zlo%H7G{eFY!=jyLSX5$IywePealJRoC8->O>wPQxvlN0$zs`^6RN>aJ9k+(Ut#LbU zjfLC1?YPY=+~#k`ZGPdlU^{LL3b%#Zaa&lpE!vLTqQY(QcHGKi&xg7$PBP@#k$!ag zNY}l_dxL=uI}FUq>)2xB4g<6LHUj7EFfc1HBXIr>1G5S*0vGHsFe|YlaN!OEvl=G? z7ws@GD>5Q*@eTvUGy7h$t+Tgnt6W6Jj}ytRZrj@1)zLmj&iM3)yt;4+XJ!9ct(%v@ z&@vbA#U75^+J_7E_~K$1wsdMpR1LLIH4s%}EmVy}HLn(`c|XFiH-oaq~DDN68^|Z_Y7qlpInE=N$7#$szS|&aq&W98xpq91BOuA$4@l zv1pVWQd{R7i$}?^c%ST|XN7*U5X2Ybvf5lI*SPJqZhM_=H#i^J&V6J%_i1!KvYq?L zcJ4FJ`N($eBip&peCH$ExsPn;J`0?WZ0A0*o%<|wKC+$r$ae0t$oa^2?jzf|&tm5z z+qsWyufw-Av$l11bye1P;CJ%2;C1e}NuYf;-t8VQ_R1{<_!@rXuix=2qPTkiKL>YY z2%wsS-`m55%=XF&mCnsuy7U()v-J?aA=uW5U(_3^(b9bsJJ#q(WTl%cc8qM75LV+> zgMm)l7|b_@@{NHl_({DjJze;t8)k0O;NjpL%Jzd_}m+c~KWV;9(*)9^34!fB0 zjciAVNrzQT`NmMbF`#28rhH?lb>)r?rn~6h-`m>Vmz95|@5bX%G7@QNSnESt8sMEH z#n;37g@5)r*qMC}+2_C()7$5eeGYV)-ad!ybD-7q_Bqsg>IlP|{S>EuV}dlIUvBxk z4B|*mm-~XQ?(W&v4JZ6C<(UKh=XA?WOG`%}Zo$Pjdn4sjv&%$-*Ffi-VRwe*;AB)4 z0}gf`H|*B1?E(!qB)HOk+Ywwg?cteCdu(LW9vj)T7n9C*G36WCv=@_3doi`*rCP~F zp{n0xwdxP0#;(uOqp>olB2#7dY1@Umr-mcGq6C8(!QkwRP%Y#);pm>%AD)%(8{=+2 zPQS3-igl{8wNJiu8<;a#e23d7XHIg_}M^ z8GeM73)c#k44l*5e#JF?10h_vwY9Hv4(_LG#jn0*!-Da%uleu`*7AeBt$jtbGD$7C zYdm!6na!2fu8sIcx_{H=%B=MrIB~?UUqjuZ-^2FFb;7ou-u%Z_5QRW`y1NFk+0vZ_ z^vqH~Zm|D9i3;~NwDfe~n8d$!mD}$%n3rvCJsgYK`kt-*m7&({?0_>zm_;kHx5{I9 z@aw^|@KRablkx?A{2^hQDd&v9|pDmV8lH_v+{d{%8#$vOc^Nd`xe09Qv%$L-2xbTN`Sj_8vxw8gJZ>R-Pxg-a9_?- zA~-1Abn}!5j;d*3i}qgs9g=^WRnt7E+p1|A=u#j3cS!ziR!#GuZfBYy*@emMHqzuO zkAa`m%_DFn=ZH<#?eR(c1Fc|964)f$9zk-V?TU4BN#%T`i`_6LXP;NeQwOrh6-~%x zxP_#pbIS>va1VP|Pap0~$Z{8E;K+FjRGOeH3klWLpgJmqt9Jr_#noE?!qu~@x9kjR zSqo6-mlNKwyZ9;lt{>E8VdNeiUqOMgtP9NYDLGy~H{)|WcFX#KP7G7_>}lJeT)#jL zD({Nn$E-pJcO2>t6on4$IMf|6fZ~?+&IT8--BrFr5#zS@oxpO)&FhDD0?RRDkhf$5 zmVFG#2Rf2{3}zpyglAXgnSBh&2RyTn!R$ko@NCUIvyUP9fM@nGn0*Yj;si~KhWrly zVdr-HhoI9(j*(%;z2y>z{OTHNH`~~V<6~w268x+hl+liwFtZOj`(R-o$n68pJ`n9l z<{7?esIWts^J8@|yW@v4+H?LU$B#8g3JU$LxS>uttmj$SQ9bC?gN65iQx_zNCz4=0 zCqWp6x*$R8g*qeAAHT~;8eJsWZ{n$Urp`!Iosnefg2Wgdg`2hG9_>sd{NQf}kyVaSg5jU79LoL6o$E5@Iy z!Ptd?^>Xz%?@qBjw7ww*)iCPrkEQ}gQ4so}wlu2b{t)T#OP=+y9FM%SqYb?VfDdUUEB%qd}dC3ICr z*RzFn>e<42^lW%AqwCb7I(2GMJvuc!n9+4=ah*D~xE`Gr}A<=RBk6)bL@`4H3JHzB)Z zWJ0!2P004C3E4h1A={@WWc$>FY@eEt?Nbx7eQH9sPff`7sR`LWH6h!lCS?26glwOh zknK|wvVB^t-T5`O(H)XS>6r73?vN}>$DC&rd1iPpqw7>rt>wXtu2V(nnDdOHQ^SK9 zU8jcc@zHgvC>?9))bL6iyIx=t0PW6m>*PD$ywqV1gKi&~a!9O!expcjVvs_{jLxFykE zKexG~wQp;$-V=|T>O1iUJi1|cd*4!^p|!2smi9`kTbwZHg`q8S^H9&Wj@~)_JzH=K z{$T4i+}q#UEB8stZH04MH{h)@)avZ*ek*(7$b5aB?Hy=lj(qME=eZ+uX8U7j0>u5) z*^R0F((Tc8QeT^>@Qtk-J1TQ4tC@7vJsn1jo0fdEJKx=5jMzb*aa23GMB0G6a6M5L-Fc}xTeh9uuUEJF zP0*`bxu93KazU?d<$_+_$_2f;l?!@xD;MQ*l3)va96t6RAsjSl64G#UkIGz!va6r|B8NTX4ZMx!8&MnM`K>c<^( z7xZt~EY-E!9_&9QOxdHbk)Pa-X&AkI(zb^>mqU*`8&QgFt`skttf2Boak<^vmhOmL zHUiDI*1?@%!MD0Gm}})Uqzz9dZtB4MJ9mNv?~WhdMWx?ay$#MR!{4P7hl&cZ1T9>2hQ zG4P^roIBwKj!<@N!9d~Jzm8sc*|^>3&MlSR(il(2+VBR@-p=(~<#io>cueB_&3H;@ zZ4(}1kic-8Y6l)MLqBj|KNMMiD;U506(6`yw%sttXBawz+b*^k!wp-&WBfxC^riXj z19OKxb(r6q-rn1)=W=-d0E3ZhI&fPYIvDrK7uP$*Pu$ywPY0UVYHEskOViqf3teCCgWB>F8)b7+ZL~ zd8<6Y*^alo%FAK(c313seI6AvV#)HBRV(q-2s`4I^EufQt9p;SQeM#6-?r(PvS(XQ zS62s;Dble1O5L0-;+8!)iFB}J`D%H&#lYbOj$Tg7k457*9J=)3++mNV;DN9;1>N9w z9oH6)L)&$fS4-ppcH-f!ja@zKF*JCoVRo5I9)v9Y;)KLepaypwC9kWnwuW{bwQd(d z$s@^ldOP1m*{f{Q&%npG9OuBnd}An^7xL!&d}}an=}QL?9-ditdpK(-fB#MK`xnIn z%^5kK>&35XaCn{i1p6F)=2zbpsXGO$!` zVCplcJRjTHCQBx6-`1br$vpe;+=IJ)3bTp+=Ep(Tn&n z4_2ZoIV=RcpT$A6RN27pIB=GBwQKg7i*79K$~K)^-tuQ^dFUngmbdzux)E)nQ!UuN zP@>P9HuSe#^JEx1K8!gCFF;2M4WBzJgb(1&Q)gWq!UE)t-wcNEAjV+ZBO!bn_=kQU z!e90d;kQ%AgmE)Mc*tHy>Wu!nwl z&)BeVuMn>M{Mhh1*zf(>*zjo#*)PV83*W;Y|NG(N!sqdM=(2I)ThPzHbX@q=fg$|r zo^jzM@I3mNap51>DW7<3T=+foKYLs?(yJ&-*w}|XYhRB zS6(naoCv?Kyc(Z~|E9N&55K`UeChq;!yeN@nEA-~Fb{D)|Lfz!tr(AaKOP^>$5QjX zJtlx)g+F5ae|+^`;bzQ(UwwA3a0%jm;_%7g--u_I8zzT$U>v4BHaVO< zIfQ>LoDv>EKlgm~l&}%)AMpDr0b)4voV~-BFn*1%q6*%l8czBHn8!O$~>ko%^><4UdB7-=CTqzK-!c|0h$!lZfjDf1etrBHk}e zn-=DyAKj--3-81HJho+8Sb=d|b@{Y#E#&WBH7)!DypIh{3y)*JJ$4g5A^+r!)50T= ze{wfIAwT}mv~WA*$G?D2$iMvlv~VNjU;Y}OkbnF4X`vnRZ+D*_+9Cg8|LI{lv? z^l&@m@n6Iz z9zG$@xMaUD9`ebZ`-P)1FHXO9Kb?1{KNp`k-d=h0eqkZ@>!OeE7aqd+zvJ=!!Z_@| z&y2^xgU^!>oe?g?__a-(j{gy-{Q_=5=_FbTtbO*6u>b7zD}(2PMI8XMXXoNVu{ zK2yTP@Xx#c`1R)X7o2{D>W@+VvHI_GRC5D-@;^r+D}->|m}kTCiSg1Freb)mdf%x3 z9tH0W`sWv?AMLhhMV4QlKHF_Khl9hoiu6@5WM`K>uwE)VY?mw%ipoEtr^>> zf4*^g{y8SRdE!y{AMg?WoYI&ZE&|8y;hCD1L%3nQj7LxznKyiEB6gn1c^wWFMxJ4wbQ3gNEs3g(>^( z1KrqCyGS&{bg~!AezI4~I+?j;9S+Q4I?VrJIwa^}IwUjF{R?|V_Qd4yH;kW1GIEo{ zZO_Ui8MDdZ3A4#)O%7OW(C^t{SNLZ8EzElP8888|Z#Y>#pL}x68Dq{^I_9o$@R%@O zXm`bKogAiMY%^&Bq`Sc-LM2Cmn3L=R@i2pq) z93wnFmfe(MU!&M9Qb=U7QzwW0updQ|-FZfM65W3olI+N{@OO;bWEV~j|7Sxp723(+ z?LbZf70p!@sDF?(Vl zcLV2cC~tl~{Hn`VS7UNa+n;FcNTS$E9{XT5Jm znEcTh;X9w15pMbFjIiF6p%?zE>W`=7Hni&R< zoEe@yXJ&X2Ud;WbG_+_;wNIsfCP$M$5fSHJN3S2(slq+df04GkmkWLh_X&%D(mEED(j?tDC?x0EbCCa4%5ksRQAKU#4sJ|<6$~kp37Lt0c9P| zQHJSc?JN7q3Ru=jN-gVT{VVHa-7D*4y({Zvoh$2PeJkr^T`TLPFf8kEJ~m8;bKhY) zoWBjz9a7TCS}T8+=)ajXCY&2C#w5z5v0-^w6QyyG)<$VOq;*l602Y~}8EzLytIQ^| zd1;u5iS#fk5IN$`3uo%zrO@w!Q|nz6xlFN0*`XSagmVRdPlV>v&=vA6exX&0>}HxEhW#)(Meyg0jvr)(ONad8mkWLS&Vr zJY&T;gY|f0l@ZTIKt`!4oM5cG5bG|)D!DBi0m%~?D=v(H^+aRcHL^-E-4x_%nCva7 zmWvVCl~{L;tZ+8giOMP$&15f5jI2^wHwC$BCah9A7pzh`7b7q+vP!PXVwIY&8ssN3 zgmt&bDrI(4kl(}*R;i{7R;i{7*4-kj95)&3?#e1Zl_9J$GqZ7(Q;((~zl|ZRyA$i~ z#JYQAm3*18?xC#mlNrK_%SXn#hq5j<);)-I4`SUTvP#CySY^GdhLem{R=X@#DM_2c z$;P@TvF=H%dq!5t*%|93Wj)1M%PRgZ)BAfIAfKw z&}ul>Smm4`8-c0HdY-XPCDy6LIyJJ&8lJIEQ`V}nPK&J5l(pGdrxEKkVx1OQr3%Pc z>kML@L98<(tJE?XtDL7-LyNJ_jI20!0qaG^ zI+Ivu66?&!D%DWNy1%lnHrD+k>;B4mv9az?tosw|{*hJcsf_giWtA^%CBGgJSr1TF z`F>Wi_5s9t0I?nrS*0S&SPxXzb;f#NWIa$>FEQ2wiSp_wA zAZ5MGSPvrBgNXH@$SPG~#(J=_UT&-hM^;=)#ooHYSPv%FgNgOv$SQSZ#(IddUTLg{ zMAk!;wbfV;A=X2P^$=zK4r(9KKe<|lLu z61s&6-J*nUaYA=eLMNAZ%VT;JycoSjrGvTdZ@B?80(?LdML3T8d>ES$XMkIlWN#ttcOL` z!<1DnvPrCm5$j>ZdRSzYqbOrNTv<06>*100aAlR(VG8Tv#CkZf9v)fcILug&P}ZxA z^@zxNgtA_3tVa;*5yW~#WR)X1V?9z?yNvb7$a>wA>(R<8w>Qd+J36u+t*rRITF3QhVm+EzkB+RfBI_(= z?KRd}k#&}`_8IFeVx2{-vm&cxv@F)y%Gz(Nvm@(lW!-A5vx#*!vCfXHk`pu5W0dt; zW0kKUvs&>OWtFehWo8{itj7@RF_BfWYQ}o3vJM!le5IMO9;>W_#(FHV9!sppMpnto z8S8P%I%KTJMb_h#^*Uocj#!T)*5e|pWcG}8jW1T~+bBJ|LWR-43*5f0qtS%Yr3Cendv7QiFPf*rp8|w+gdIGVY5Lsn? z%2-cS*5?@OiIMe0Wqq!(o=B`G66=YPRaUr+b*{4BXsmN1>s)1hp0Um)*15zwH?qna znXxt~>+_AZA+k0o>kEvvfmj=ewIQ;~Dx0x3D(ef4wK1|bD(j1kwUJmGiM27Z$~v8~ z&QsQ#jCEdQou{nwJ((O^^N4jGvCfOEveIX)^OaR@OOTv3KeEnO)|VRVd}5tXtn(wQ z)Cw8v0%d)fu`Y!QfINLgPU^>TJ6BfN+h7ez*?b~47r%J>>XE{=?gmGQMvpEE8d#>J6Q zYNd?vBxRJFOk^*e6d6xa#@9!E&Ug|ro)j6S(#jZ5R>n6N^5n>PvNGNr^*Q6o#CURK zlsYYAJVhDbXvk9{<0;B0H^WHmr|901aXf_>Pl=3DT|}^ ziScx0l=G~Lo@edsIo8VH|H^sR8HlW0OD{?2mL_z|61wFH-I)npQ$lxELU(pTcTPfg zZbElnLRU@bniIMe3ElY#-31BVg$dotgl<(r*OJg(l+dkC=q^s^)+BUm6S{Q?-6aX# zr3u|-3Ekxh-4!LB9HnPKmmL{r=#g=o9RX*=BjXG`GTt8b`H^u39T{iDV@+mn#<)Zo zZ#SfT)0Ji9CCd1YsLvUfDC2}NS^iiO8D;Kgj7ydA4nr=Dj7ydAol&1NE+t0!-YmNc zEk{nq2pMN=cN%h8WL&0S&0`kb+e7@H!aWQ>ea z?ue>}`wV$jWIRh5-y8Kg<5|RbR%ARoGM=rB_Z#x;$auCgzAx%?#?8qqDDvR+P zWqiPp=S0SHl=1yhpEI6AjORo~$#ogyxytyUA@^N8`h$S8R>W2`FULxz;QHnO9zs*E3w`kb*!jMc~}Svq5E zR>qGQvN<0@tRoFP|5 z##PGr`KZqsR}tf?$SCV-#@M2aUod1#WNcB!FGhXN*g}jgkx^FVjPW96{E{K%HsfrD zU!;s*j{2POB4WHKGRm5sF|Jm|M-90;GOkv}uS9*$xSAMOM@Fd#GRBLQ@vDZsI5J+W zj9-iTobh5}yf`vSJ&`f4QO2(ua!q7hqm18(`kZkMF|LV>QjKJcYnAbvhFlvN*DB+; zqCRI_ON?tHqtr4P<2q&hwjtL=#&yd0ov6$@q1C9 zGhRZBmqbRXqcX-zmGS$AyfiXis*FE?Ue10lrL)vamG!ZR$?FQK#4^^)l=X+^aam-& zOj&!*gf0t~oA zI7%{pM@LES=aAmYna}-u$~R2@JZ5LMvoj_+^SKi3qyEHNh(C4@Uu#0QKA~$%=;T3# zGG9kRw;`e1n9yxX=sFX+s}j1a6S}U1ZgWD{ozV3pbXyX-YZAKNgsv~4>rd#mCUn;( zblVcTfrM@_p&Lr*u1n~ikM>_?0^UACHos|5wH%NN_So ztKq-QvsH1wh?2*(5>DoEHT<`Eu2xnDDL-B^0*Gd$#GQ;|6`sT6!(WHdE5rV$+1@re>BgHiu+TP zJZ>Z5WH}kwoaZg0aX{SC%LH_-eI0Sin}999@j%S$zRp*PV?NNxI3fdaa#x{Ij$P+GS6!i zcXyOL?i#{L9;}9UnP;!!?unAe^%72UWi`CpJo^-PZPYtlE+<3ILY1B@P6~$rnm>AqIqt*gS_6_mL=h+z{bpEvbf&n&)+j zdpJrScOBtmy{U$enddVU_wgus+%pI#Yf?3Q!aSd;xKBpOlREB(-K36Ngzra2|5xg`8_<5a?s|4Y_nd_8xe48k z3ElG&y5}c!FG%QKn9#i_p}Q%edvQYdl7#N13Ej&Qx|b((uSn=#nb5r|p?h^g_nL(6 zwF%wp61vwXbZW|wIGO9!@MZISuHqhzlE*!l zaB@6U!&l7nM#X(KN*;G3;pCX9hOe3D^Az{>D0$rT2q(u?HGIQ7pRc%YM#a7hSq+--;a{Vy$HC;VbVTX zWh2LVHT=LlZ&KW2QS!K(2q(Fq8h&V=FIL=-qU3QeCY|9iIT^?gm98m zs^O>R`BKIGEJ_~tQo>2z!Fi2&zD#kCN6F(}MmWh$IIl6!mn-fUQS!K#6Hf9M&TGu` z6^i?1lsxVggp(YH^BVJfrQ&`aC69Y0;Uo{@yv96VrMTZl$>Ux{ILVbbuQAV8EAIDE z^0-$MPVy66_Xfhr8i4Z}^SoJce~*&K-Ap)HCvaY4 zo^Mp#KcnPvZzPz)W25BTdkf)Y-NJV(=J{5|jgOMYy_ImXw&A-M^SniIyF|(3Zi%>h)^TscWw`R4 z2)8D5wkWMai?=qp{>H?^c$ovAkPZ_BPzRm1RzpJj=U@ z;qFtG6Qkr=?jsh-XLz#CSl+8F(+u}sWtkf#*(-wdTaIvv`P+1N%+y|9qQI!0?l{KUq))?+XiaW?WKcu+DQSz;Sh{jV^ zooZNXEDtHm!G?QCSx${~gWtKr$#XZ7D_6?a3FeBJn2ob68z8?1%T(s)V+sD@`5?sLj=eUyYHuNyx{ zET1D5$r;t~Ov8O%S)LIkVae;p&lAh%iAAzZHC$)7FDT1Ul!PU(8^1s-U!d`nyi^T? zhWnzj3`9v-^1AVh#PUUAkxW(%+YI+5Ww|y=!jjjGUm}(-5sT!$YS?PHFDpxblzjd7 zWn%drH?kEXMUjKcSSiVZ*@-=1IY`Cu}OIMVHC9nU!Ml4?=mai+z)rR}JvRoA$qr3TxPiMDa)l%5|(@&`yR1;kH+Qu%5sU} zzOO9nq9iQ&I`(~H`987yKv~ur?gz@UCQ8DRuVX(TmLCwyW6E-|;T}_#)lm|bd>wm? zSRSKs`Ju90WVjzHOG}i5C11yWNGv}jmLDn0D#QIqSyo0#Sn_r3N5t|YVv+h|Y1oKW zMy~Vx7@T~aN9yV+dq`cKSI@(1W^Wm3Tk7hcfW2H-|1_cdSwi>ogzoW#?!OYcUnF$@ zozVR0f|0bLqpVe@XdHzyy2S>@{en~hvhO6Na^Zb?KDpB&dUlC4@^J+NMJb$gY z!=mJIzb2gIf@(P2Jb$COBckMSzagCD3%nQ8Jb$aWqoU+-za^aHlxjHIJb$OSSyA%1 z-w{soPBqLn&)+NVm?(MN?+GWlsTz(o&;L=}aZ&QP{~?^@uWFcMo_|o>@lo=)KM+oG zTs53vo_|!_iBa;nKN3#zU^UD&&p#=(dBAn#PYG^di|5e<)DEapO zmvE9#t6{!*{#kJgqU3RZCYSU4X2vt6N)=6N*?zF;baY{hSSaS{}gvdlsxYL2q)`AH7qgD zzbkHOlsxY5gp;+T8kU*oKNPn-N*?zQ!pVA54QHC?KNZ&$C6D_j;bcv!hO^A`Uy3_B zN*?zw!pXW-4dkfi29hA@=oX{Oo(n;=?`Bx3iHsiw>IoDYcB|rc1 z%M7lLlR1iS70q*u;x34i$BiMJ%wv2XXr5ygw=zl|H9eTHEcA`Ns8MP zC6Aj#ILSNJAitn2du%VoT@@vd+lz3Lo2ubz^PH@>t|)ojWWq`Qs)o(xIYn{ZQS!Jc zgp(Xs4L#<$x8k-$$>a7Woa8}V12xZm6xSOikK2cEk}Giq);#xBoctcOjMBa|ulFUK zQS!Lygp=HjEAQsH zpW>boC6C*WaFX9~-QPTCDDL_wdE5-b$r^xf9n5p4;%RHEC(0;j&J2as?ETKC*p*td> zJ2Ig=Dxo_%p_`S^%}(f!N$8GE=#ES1<|K5-Cv+zybSEZsa}&CTgsw56o0rhdPv{mT zbPE%@MG4*Fgzlt-?&O5-l!WfogzmJ2?(~vQaAe*YPi`vk5b$lqvUZ%5l)W1YIu`*9<8`H zN6F)kCY&6f)$kVcoTa$8M#Yxe3n-o979NyC+H>cLL!gf8kkS^E^>;_eRO%P9&Vkyy<5^+z zT%@>%qvUam2q$X*o)tFF#ftlQlss-R;bfh_v%=UBYoUAu^R@gjGQQT*u64cVbcR@mTVM4bup<9*EwIp;GC3LG3x{DLKH3{9?gl=6zcS%Bb zX+n2dLU(yWcST7j^_a{*JS%K7{tTV}k4DMQ|1;wJ7o5ydJS%LTOBDCjD0$ox!pS_w zv%==NRB>OAlE*D2oXmARD{P+26!*<2dE7F>$?JHqQ$b_xmV$+y#V_9EWFx&GSOV{UJ&ocOl^<58_#2^IWO8KSjyo zRuWEfC7u;F&sB>1bCf)872zbG;#pzyY*E}_qvUZdgp-_$XNAr4BE>xsC6Bv^aFUnt ztgv~mR@~pCqIq-G0%018yh9x-a5j`T7qYV&GQn)jgOMYT|zinZ}6<$6bl`%XM69LbpDlYfI?b6S|IsZbL%1F`?U(&~+wsS0!{;Cv;s2-R6X@JE7}I z=(Z$u*Ccek30+@8*PqaBP3W#o=(Z(v0}0(=LN}DqU6;^3BcXd{LU(;a_pFjm>M@yr z)iB9s{FOTY_llCA|5wKOFF2W_xIfN3TNO7YN*>orIGM+|Kh8YYD{h}CdE9!!$y~?% zapu{kIC=IgOTqQ~# z*GV`z&a2^2^SnxNhegTbt|FY|0^A>Go>wdGh$wm7)r6CLf&1gkvrBPDMakp32q!rO z_s5y%X2s2llE-Z(oa7zcA7`H3iaRDs9@kAc$xXOF&OCb*cU+V_u7_}vzi@w?d2UhM z@lo=)ErgRChx_Bq^BTpS7$uLphH#Pxaeth7_A0I+N*>osILVc`Kh8Y+6gMwQ9@j@W z$)~tK&OG}Sw;)O$*H1Xfxwt>hJhv)tQItGxE8!$BjdtPGtVK#Esc`L z4G~V(65JnWp4TaEd6YcvI>O0%gZtym^BIb3ijv1YgK)AY;r=-De5T^gj*`bclW?+b z;r=-Dyk2qVM#AZ zx`gia3EdkKx|OGzg+kjy{aA7?ZE2A%&aqU7iQ4RQVp zPUa}?k2B9_EAE0QdEB!JC-WHh$C>AI6t^-;9`_u=$y~?%apw74#kEAq$SF^v1;%=1NxyD~~1_aef{agO`r%=0G2t&ft& z-9$La1-L)XJYTH1_9%JWiwP(B0{6$6=Svi~Axa+i62eJN!ToXO`BKGgijv2@lyH)F zaDSY6zD#jfMakn{MmWh$xIfN3U#_^WD0$q=2`Bjr_s5y%D-_oqC69Xr;Uvf5{y6h| zrQ)_k$>Uy0ILU*!Kh8W~rMTWGdEBcAC%F>$$C>A=71tjnk9#%YB%k8`IP-js;;xO7 z$GwJdl5=r?oO!-haRX8ExYrU+@-ps^Gtbv4ZYW9~_d3E!?#BIb=J|TXJtImU_j_wI!5-h}Qw3Eh1O-Fp+d`xCnNC3FuYbnj2-9!%&ykkEZF zq5Dum_fSIj;e_rZ3Ef8%x`z|GkCk*%kIDSQ{c$$q-=_2bWl{3;|7~&p3r^-J?vFFi zTNU?;D0$qigp+xU`{T^>HpRUvN*;F`;bgAk{y6h|yW(CGC69YM;pBM0{c+}byW(CK zC6BwEaB|Gx{y6h|hvME4C69Xt;pDi&{c+}bhvMECC6BvXe{y6izOL1?DlE>XeI62O7f1G*Vt+?Bw9nin}999(NDnB&Xp1IP-kB;_i%+$Gw|yl6P=_oO#}> zxVxj|arY8Vaue>4Gtc)Z?w%-l+_Y+QXCGL+i&-W?rfhc+0`v@ob6!*uO=L3p+FiIZx0O2I( z;{G`Ee81v87$uK;Kj9=VD0t+#hG2A5z@MqvUZPBAl!fxIfN3A5z>WqvUZ95l+?;+#hG2A6DG| zWADx5x0<*2|GRk}G?(NpNm5CYR8mQjHzi4uG^?aiNs=T9Ns=US9302NaUAn3At5B0 z$vh9oJdfXXU3=}-dfk@q=kxh}`u_Lhan5mF>$$J@-gmFp+WUUr>)h6w^2gnq9Ebaj z%*QEtACFsS${%-MavbhSG9Rbp{XFh5Q~tR7ljCsTlKD6#SM#{_ru=cMljCr2lleF$ zAK-CMn)1gzV8?CE=eRZU^NXM39t^yP0`K9#TN`+f1m3#9do=JK3%thzZ++lB5qM7q z-cy0MA@H6Kyp4hPOyF$_yk`UNxxjlq@LmYK7X$C5zP>4eko?J%C((mt z&P{7ClKjP#C()T@vQ29*k^Ie+C(*BEmQ8CflPt*hj-d~}oV-ft;xfIawO2@%HRUtW z+htx&Yp;?lZ_1PC_%flUwap|en(`#>12U7Qwbw{iHswj&9b^hkYp;{6YRZ$iXUN={ z*4`jl-BeEEi3tB5>i_P)1#QcBAE*DsZ(@_5So}ovR^YuIc<%(>yMgy!;JqJs9|Ycq zf%j41eH?h71m35C_n*M~Ebu-Lye|Up%fS08@V*YbZvyYz!22%nz7M<~0`JGb`zi2# z4!mCi@7KWlE%1IX^01@d6i+72bdA5s6<^a-zT!b*RmyCc*4`qC?<34=p2S*}X)>+7 zO|p(DPhthj{Fv6>Az9CqC$X+&VoYoAl5AkglUVICBc`?YNH#L%N$dfc3e(#AB%7G> zBzA_(fobgnl1)u{68l9azqIxt$!4ZJiCrYKURwKzWQi$HVsDiecF@|#B%7P^Bz9bB zVMncfLb8P^PhuaI7IxCwrzBgN@+5Yr%xr1xKO|e3@+9`GOlfKDGm@=Mfvlk4L9(4GPh!{0?3LEOB-!4SC(#RJ+DdC*k?df~ljsmKU!}FL zNp>{lN%RewsM6XuBs-b%B)W;rP-*R3lATR?5}AT6=x8$Uq_v+(_BQ27^f{Su z(%LU1`;F@Q=YT@lKRySP3B0m_S1$0%2VRB1s~C8d0rWAgxs=InI{*%e(OONC6HR#%J6Yy>v{sAcBvYQm{+3A|t<@$u*_0=->t%LFYuk{V zYRZ%71v0IpwK^oHnerq$gv{q?tuDzKraXzhArm=Tt4DICDNmxC$PA9w>XV#h%9H3Z zGIgW11|(;j@+3Ns%-LwIA;~$WJc)iJlQmjvL~^bvPohi7EREJ0lbmPDljvPCJ)^ZI zBQx8`#|iTuRk-v{gvc+CTE$G~e5csm7N%fQ(;O!N7oda+0!0QrtT?4OM;O!H5-2-pm zA`f?WtUsA_(KTMe6~Dw(zT!b*RmyCO)^;Gd)RZT&R%Mz+Yt2b6Gv!IFV3}Xh+Kwcb zoAM;qwM?vNtp&*yraXz&E;A}x+lk~#Q=Y^gkf{`{wIsR9lqaz>WDZ4ZJCnT3lqa!Y zWb#C7tw>&O%9GedGHar>T}WPG%9GezGF_sz)+DboGJc*qwb0J#WjpPlcJc<1+lOS4aPx3}n zp2V(~*$=JlPVy#GonW44LBv+gAB)XK$VrXq| zl50$P61_{NFSOQ$A9#HN z?|{JT8+Zo>UcbOQDDX-H@8G~YB=GtN-hjY6H1Gxn-eG|^DDVysyupEYMBohxydwi| zXy6?cc*6qk=)fBuc*hiZxVvNh$)tp?@g7|98%*UZ9wb(!%tmOfC&`VbJc+d`(-2zg zMRJoVPhthj{Dao^Bl(;uPhwrm#Dms)lYGIHC$ZXP#zAZQlYGgPC$R@)szGagNWNmq zlh_$D$Dp+XNNzUeN$eMyT+muylCPWcBzBR^DroIMl5d*wB=(j}Cupr7$+t~;5<5=j z5wvy?$#+e868lgl5VTfG@_kdD#O{=t1FaoQ@sE0mdfz}3){LGXmvFl}aKx>DR{KAwc(FO0ptV6Hzcb}YbQ75m(Awc7e=y}q^ca~B(Ar>ntZd4Y=!r5Ppta#7tD5p8I;G49Xzdu1)lKE()_e{aAwRMB zIbdYqjS9Tcfj1`b#s=QFz&keZ#s}Vnz?&F&#|7S`z&k$hCI{Y>z?&L)Cj{QKz?&X; zGXn3#z?&I(Ck5WDz&kncW(VFWfj1}cP7S=dfp=Pwhr2u0pUem78Xv(GU(-~+;z43n z%6x#Phz#pe1O)* zl5Awklh^|?AE32yB%7G>BzA_(2WahBl1)u{68lBw1GF}tWHVEq#4eKg0If|RSz^kQ z*jq9mptXr4o15|^cAU%yXze(XElhb5`%vZsv^I%kOH-c2?v(ietsPIYl_^hR&&qs& z)+Uo|ZOW6_$ub|HwJ9XqnDQj{x6B7;i zNpv2W57634B)ggNB>Iue2WV{;$?m2+i7qAc0a`nmWDirGMDHps^wipHlD$lM5*@9y zu%FgWA=%rMC(-9*K0s@8NcJ)1NpwG%5764FB>S53BzmIE2WV|B$$q9hiB2i=0a`na zWT~l~+?vk;^W-NMKL?y1c=H4AjKEtEcxMLQ!oWK#@Xijra{_Ns;GG+Iiv#bxz*`b{ z=Lg=>z`G#umIdC0fww&HE(*LAfp>A>tqiRo*@AAO=YmtY$JJz4f z2k07~#}$8wseHwQ#Hy6}0Ii))a)2pMVy()2fY#=d9B9guSiv$MptUnd4l?CQtZSJM z(Aol$gH3r7t6k;;w00)RA*MWuJs|S|T3bkRs3}ikXUKej*3Ke1%#=raXy#DDweYTTF7CDNkZ| z%6x#<&LcVAlqa!gWj;V_OGr*M+o+$GHTDzR& zB2%73rjLlk z!24(5-4J;H3cMQw@85xUQ{dekc((-Jt$}x2;N2d0cLd&@fp=Hn-5q%M1m3-YcVFP$ zA9$++?|~u@cXzBmnGeu4eg#+j5>xq#2Z>cF^8s4BlH^iTp2S*}`2ek5MRJ)bPhthj ze1O*eMsm3+Phwrme1O)jCb`0tC$ZXPK0s@KC%Mv;C$R@)K0s^NkX&WTlh_$DAE32= zki5*4C$V2-K0s^NlDyoMC$WoUK0s^Nk-Wl`C$YC=K0s^Nlf255C$ZyXK0s^#Bzd(d zkTM9(_nO#;G9RF|8%SPb%9GfgG9RF|f04Y_lqa!gWj;V_HjUqJz1>W<4 z_d?*k7F$H<-#-JV>lcnGev~ zgCsYa@+8)(%m--gA(ER+c@isF<^#0$Fv;gkc@pbd<^#00mgEbjJc-pV^8s3Wgyc)6 zJc&IZ^8s30NAeX@p2W_O`2ejwN^-L)Ph!8we1O&-Bl)^1PhuCze1O&-C;6r+PhxM$ ze1O*0lYHBhC$ZyXK0s?vkbKvaC$SG@K0s?vl6>EkC$T$aK0s?vk^In4_N%R7l5762sl3$tf zBszr52WahClHZu}B>INT2Wag%lHZx~B)W;r2Wahil0TU8Bzla@2WagDl0TX9Bs!1G z2Wag@lE0YpB>Iue2WagjlE0bqB)XK$2WahOl7$-CQ{>B>56GV>(Ys_mKx?m%ENjYV zqNB-tfYx3mS>BW<(dT47Kx>;xRy5^FbU&F7(AsMxE1U8pdZNq+Xzg{9RZV#kol@ol zwDtzc>ZWpXYd#0ODL=9JIpD3pdpq#n3A}d$@4di#Kkz;XyblBKqrm$(@IDE=PXq5i zf%jS9eI9sU1m2f{_f_D19eCda-nW7GUEqBmcs~T*kAe47;QbtUzXaZ|f%jYB{a)nZ z?vC{*^8vcX-{gv~X)0gwAh9ZCK0s@4k*saXlUS=VAE33jN!BstNvvR*5762>B- zB-XXe2WahGk_}9G602S21GM%Y$wsC;i9I0m0a|;XWD`@K#LkfU0IhvMvZ*OgV!z0I zfYv@F+02wDv5RCrKx-e7EHULt>@ArO(Avi&o15|^cAU%yXzde{Elhb5`%vZswDu{< zmZm(3-6`_{TKf;lR;E0OJuCA8TKkM-Yg3-YPL}xqt$j|ijVVuJf6IJ;*1jOw&Xgyy z>t#MbYhRLVZ_1PC1u`F?wXaBaFy%>f2$>Ji+SepIn(`$2hRg?O?HiJvOnDOBMCJpu z_ASZIraXxrBl7`T`;KH6Q=UZUk@*0veNVERDNmvw$$Ws;ejwT1lqb=pWIjM^Ka%WW z%9H3_rG=ha`-x;PQ=UXeD=qA&wVz4$Hswk5Ihha8+Ak#gnDQjLpUekn?N^e0O?eVM zQRV}*_8ZB5raXyGDf0nZ`<-N|shr%J&jE#Ue|!!o6L@6I7chz^fN{^#iX#;57`qMuFEj@R|hPwt?3) z@U{!QW`VbTk%zlG)}PD==o&AS=&{`Ri159}mYgOh0v{shnKvSN? z3YPf*t(7A=$do6su4O(zYvoA}HswjIc9{>*S_P6rOnDM}K;{FqR*~dTQ=Y`mkof?u zRU$delqa!YWIjM^l}Qdap2Uum`2ej|BRR&D zC$SG@K0s^LNscq+N$gIU571f-lH*Nz5_?wW1GH9?s^0Ik&`ImwhKvA<M=~FvwMHc8 zn(`#Nl*|Wctue`YraXz>CG!DVYeI6qDNmxK$$Ws;wk5g1lqb>WWIjM^O-U{^;ah% z&{|89t4w(kJ45CJw6-(J%S?F^`$gshwAPB`<)%D|T_p1XTHA%>6{b9iy(RMjT5C=6 zDpQ`sj+6NSt?f$kYEz!XK9uYwbv0Z_1O{ z$ub|HwcSYGV9Jx&-!dPdwe}=$H04R`dYKQ<+U_K8GUZA10+|ocS_hK1nDQh#gvr8UBDNmwH$$Ws;_9nT;lqb=Xsr*)S4?>lJ45CJv~~c=&89qw{UY-LTI);lbyJ?iE|U2GtsO}6 zO;eu4-jewMt@R`Mwkc0y$H{zv)(#^1t|?DqAIf}y)=EjfZ_1O{oiZPwwS!51Xv&k= zvoar`wL?gLY|4|^$ub|Hwf-bOHRVa{ZgWz?&9$(*tit;GGzFGXw9Wz?&6#CkNi_z&j=I<^#gn#xx^NUTbk57633lC@2F5^GiF1GF}ZWF1qU#0r-A0IiKCS zwky znGev~86*dp@+8)^%m-*~0m;FpJc-pV^8s2rljIOnp2QxI`2ejgBstWSC$TeRK0s?{ zksM~qlh`jZAE33fNe(yVN$et-5762kh0$6&m*f~z zp2R+s`2ejgCOOWOC$T$aK0s^dksNQzli0H|AE31*Bqy5kBzCgQ2Wahll9Nn%68l@` z1GKi3a;hm$q8G?~fYz3goMy_C=nyg=ptTE0&M@Uk^bMI0(Asj6 zGfjCC-9+XCw0056S*ARR9wYMsT3bPKwkc1d^T>RF)-EPF$CM}0k7PbTYb#04HRVZk zDVYz@+9f3Cnerrhm&^xfZ57G+raXy`Ci4MWyOiVtQ=UYhllcIxT}E=DDNmyN$$Ws; z{zCF>Q=UXml=%RyT~2b5DNmwP%6x#<{z`JOshr%J&jDA+Pb_{8xH9mr3cSAs-qnHk z_rSX*@ct2a*9P8ofp>l2{WI`x2)us<-i?9x@4&k$@NN#gTLSOaz`HH*ZV$XW0`Jbi zyDRYS4!nB;@7}<>FYxXUyw!pCK#_;LJJz4f2k08Vf-8QBseHwQ#Hy6}0Igj~a;Yg# zVy()2fYz=exy+O&v4UkjKx=;^x!jZ|v94u4Kxj zptWmAt}^9G>qD#qqfY$CNxyFrHtQol@olwDthWCr#z#)_e|F zBR{eDIpD#-dnoW84!pI2_ekKa3%o}I@3FvpJn+^B-V=fMWZ*p&cpC!m>A>31qE2cb&ogwo9T6>h_W>cQTev$bAtvyEabyJ?iE|U2G ztvyciO;eu4-jewMt*s~dwkc0y$H{zv)}A2wt|?DqAIf}y)}AE!z9~;)cglQ#)}A8y zp(#&d&&qs&);5s**pw%+lVv_YYfqE>)RZT&zhyo^Ya2;^X3CS;^)erzwP#3vVak)} z1u`F?wM`_yGUZ8h2$>Ji+Os6TG38104Ve$n+H)koGX-+9{F~~rkI+qIK0s^Fll;My zC(&bMK0s?Pko?J%C((IiK0s?PlKjP#C((~&K0s?Pk^Ie+C()&3K0s?Pla$NgHN4FE zfc%QkyJS8O?eWXQsx7+_6Eu7rgCy?J_o!hKe6~Z;H|)WJMi8Kymtfdy})}v@IDB< z4+HO`!23AxJ_)=}1Mfe9_gUb59(Z2_-j{**Rp5Occ;5uxw}JOv;C&x>KLp;7f%jA3 z{Tz6|1m3TK_gmooUgV)GVg1Q`fUfa3x#DY@%2zx{tV)>=(ArxhYn$>U)~d`0Xzgv1 zbxe5@D_G_OwDu0kdZs*ybuIG&T6>pd15=*FYM1!{t-VLGktt7N56FCg*4`)C#FQto zGh{wMYaftoYRZ$?FESsXwGT-)Gv!I_BAE}++D9ZyOnDM}OXdT#_A$xkraXxqC-VVX z`-Ef*Q=Y^=l=%RyeM+*WDNkZ|%6x#<{zI~rDNkb0%6x#qJc+&` z^8s4>hGZvGomPol@je1O)zBiY52C((IiK0s^Vlk8^7ljuh>AE31# zNOm{nNpvZh5763=Bzu_hBzl+32WagllD$lM5*vacymq9@9HfYyE^+0T?G(J5sf!8eXwlDHcF^8s2bLvnyA zPhzdge1O)EUVh_lC zfYvIK9BRsw*cmb(ptVXQhneyu_KVC1Xst5I;if!^T_p1XTB|~GgegyAZ&0Ik&^Io^~fv1esIKx;Kg zPBi67>|~h_&{{2$lT3LM`&;G%v{swsWK*8Ru9x`$t!+bcswq#R7sz~o*6NU)X3CT3 z5HcU2wYnr{nDQk0hRg?OtscplraXymBJ%-St50&4DNmxu$b5j-8jzfA%9H3kG9RF| zh9u{h@+A6^%m-+#5y`oxJc%wP^8s3GOmdznPoj6pe1O)PkeqMIljvwNAE32uNiHzu zN%T3H571guk_%0F65UVc1GKgs$+Jy)56}1FuWqbq&03fwxcKbq~CKi#*)jvHoN}K-YK)SNsxF z`HBaLRVniUTHAr-Qd6G9T9x?#tu-gP%#^zt~TXKbSaq+(AwT4*O>AodY8-xXsrv$ zhfH}A9Zlu~wAPj6T2r1xpOg6jt#u>0&Xgz7{bW8sYx|IV%#MzJpuj5) zyn_SpkihF7cmo3O(7+oQc!vevpujsk@CFCo5rH=(@Qw_;p@DZ);0+7BqXTbv;2l%s z;qH$0C-VWi#(QwZZ!ndwc#v3?G9RF|o+LM#@+8)(%m-+#7s*YgJc$)7^8s4hkK}Wv zJc)HJ^8s4xP4Wd(p2TXG`2el$Px2*Gp2QxI`2el;A^D0aPhw}te1O&tAi3F;C$V2- zK0s@INxp8%lh{QvAE31ZNxo^ylh|7_AE32DS{K1qb(PLyjKx>0Z{$$FN=sYqXptU1N{$k3L=tnXiptT_+e>3GtbSaq+(AtqC z3$^w81Il|6y-Vf;v^JDvSyP@wN0a#gtsOWeu8xweA18-d5 z9UFM#18+j$O$@x_0&h~_9Upj;18+*;O%1#g0&iO2O%J>ofp=oy%?!Mg0&iB}og8?x z1Mif;n-h4a2HxDjJFUpW-5u*s<^yz%kKl^0X)0gwAh9ZCK0s?DN!B*yNvu_w5762u zl66dZ5-V8d1GF}pWIa=!#JZOG0IiK7*}#-1vD#%mKx<=3HZtW&>;ah%(AqeXO-y+b zJ45CJw011XrlvfJ{UY-LS{qNYnJG_V7s-5p)+UfFG380@EtwC{+C-AgO?eVKPUZu& zb{xqTraXy#DDweYn?$muDNkZ|%6x#INT z2WV{u$xfy`iEbkE0a`neWM@;JM30gA0Ikg=*~OG6(RpM(Kx-$F>}JZ7=tnXiptV^f zyPNVPx|GZZXzgT@JxqBLy-Vf;v^JY$FH@dGN0a#gt(`)$w<%Ae&&hm%*5;7xW6G20 zelj1RwNpv@ArO(ApxBqfB`cJ5J^Uw017ZF{V6;eJJw*T3bwVoGDLYcglQ#*3Kh2-jpY? zXJtM>YfDH@H04R`WSI}p+W90Wners|x6B7N4 zv^#o%JpXBJ8Oe^OJc$lbT4_q@+7)RX`!jsE+V;?DNmxu z$TOwZR*>v$%9H3krG;i%yO`wOraXy$Bu}4OTS>BuDNmwHl@?00b_vO@raXz>CC{l^ zTSc;)DNmxKl@^+7?NXBanDQk0oIKHL?J|XIEw>t11DDrT3$NH0Zd%DK2;EL~MDqry+u_{Xot+aL}$^A@u5^Gi7 z7i#S)lD$oN5-Yg0&{}JMBe}mRPhwrmJ4mfvO|p+EPhz!~7TRd-?<5Z}?OH%2q7gP`+ZJ7w@0gr}8AI z)W3Ml08{xfSS#4Q@+7FW8%Yi{da3(29TJc(W*Pl8&zmENlI&+32NsiQXnpf?B(mSJrsBk2j1Gi zdnEAI1>U29_gLUP9(d~m?}@;BGVq=XybXc(bl`0ayk`P$Q{X)tc+Umi^MUt5;Jp}l zF9qJqf%i(_y&8C%1MjuKdp+>pDDu#|vHoP@S=aa)uK1az@)Zvft5PPOwe}#%S*ARR zwJH7(Y*U`Z3YLjytvyU~jww%KUCYF?*4C1oYs!;Y?K1JKwMR(KGv!I_fzrb1 zT3bhQz9~;)XOtGs(AuLU7nt%S_KQqBYwam+Y6Siv&!thIMY-e<~_Sl2S~thIMZt~TXK ztah1r*4ld{*O>Ao_JB-0YwdlK51H~Lc7{wmYwZJ)YfX6)`$Z<6we}&&b*4OtT_h9F zTKkCPW2QWby(JURTKkyfdQ+anj+2RJt$jlBNmHK0K9osOt$j*zgDFp9cgm!w*8W3s zqbW~f&&s5z);=S-$&@FtlVws=YoC*R&XgyyzhzQXYhRFj!IUSl>t#|@YhRLl$&@G2 z3uIDMYhRIk#gr$}A!JfiYhRPxY|4}98!{=XwQoqiZpxGBCNe3iwQotjY08u6F)}Ht zweLv2ZOW7AJTfV&weLy3Ys!=8M=~j@wI4{nZ_1PCQZgy3wI4}-Xv&l5T{0=EwVz0S zY|4}9Xfi3PwVz3TYRZ%7b22HawO>enX3CT3ex-#5TKkn`LsK9dsX|YbPlin4w_#08 zc@mvcKJU@m@62p!Dkrz*b3mcOAD;ut1YX&|D;Id>1Fu5hRSdjJfmb>3ssvuuz^fK` z)dR0a;MEMgT7g$P@U{uOI)PU=@ahF#{lIGwcnt%uQQ$QWye5ISZQwNxyzK(7S>SD7 zKZRpz}{$PDqry+u`1;=My-`0Sz^kQSgZ2Mq1MWhY;MYvSi$mnpw`Nf zY+=fiSl99?pVrEgY-!4qSncweht?{PY-P%m*aPxOhSn;QY;DSu*ctNqgw`sNY-7rk z*e~*_gVrjOY-h@o*hTVLg4U{#Y;Vew*jw@mf!3;$>|n~1*l{x9rnPD$JDTz&_MuF; zX{|cRPNqDG-6<1pTB|{_vnfwv&&q_G)@qXMV#<@)$ui-lwOS;*ners|w@kQctv1Q- zraXyVFB5KB+lFKhQ=UXGkO?=f)gjr-lqb<4WWr5rbxHO%Iv3^i#4=h8kr*-4w|D|6hwP zB|lwjjkBL_%9H3_^3%1}B>U;6Jc*7bpG#?NTat&E@+A74d>W;-rX&ZL@+7*Sd>W;- z?MMzZ=1a(18>K`YY})m z1zyX*+d1%B1>P=!*E;Za4ZJpi*EaCl1>SCf*FNxe54;Y6w@2W047@!9uT$Xd6?mNk zZ|}hC5_nw$uUp{l6L{SNZ{H#hcXzBm`BYWccnMeh5L5Yz2Z>cFpQ>tY2a-cgc@k?? zK2_CPbCSbMc@isFK2_D)jwFYh@+8)^e5$Io79>ZQ@+4Nfe5$Iook)%{@lqa#blUwN4}#nDQh#k9-=XwY^9# zH04S3Bl$E+Yn@4+ZOW7AQu1k(*7hd3$do71yX4a-t#u)}*pw&H(d5%8t#u{2#FQt| z=j78Ut#u>0)RZUD{p8aqt?ff{nJG`AC(5T$TI)`7xhYSgQ_81NTHBZ83R5|`HJ<}| z$WJVO4(J(py#jB)!0R1&`v+d1z&jxD`Uc*Cf!8na4hp=|z&kkb4hg*efj1!V4h_74 zfp=Ko4GO%&18;EP9T9j#0`JJc8ya{=1>Ug0J38=&2i`G79`5c~fAXoSuJImR@heT` zD;^|PrF^QYwVotbnersos(h-dwO%AIGv!IFVEI&4Yx|MB+>|G=uH{ozt@S2(g(**B zwU-vI)Y|?euQKIH>;d^yRcn1nUTw;g*ctMvs@4u5d5tMgV!z0zs#@zy@>)}##4eIg zRkd~?$?Hvd5_?NNRn=NQk~f(0BzBy9s;aevNZx45lh}vysjAjWN#112lh~c|sjAiv zCV7h~Ph!u?r>a^zgye0eJc*qwpGIk|Kgl~xc@q0uK8@1a0Frl^@+5Y>d>W;-LrLCa z%9H2?@@bUT29mtblqb<44){Y{%!IUS_=j78Utqmi&(Ud3A{p8aqtsPBrlPOQ4C(5T$S{qLC zIa8iQr<6~lv~~>17fj{k)_e{aAwRMBIbdYqjS9Tcfj1`b#s=QFz&keZ#s}Vnz?&F& z#|7S`z&k$hCI{Y>z?&L)Cj{QKz?&X;GXn3#z?&I(Ck5WDz&kncW(VFWfj1}cP7S=d zfp=Pwhr2u0pM0vSYkUM({7a_t6%P`tQa)AH+DMYGnDQjns(h-dwNWHDoAM-9uzaej zwb3MBH|0sJYxz`FYhy^hY08sW?eeLr*2a>2+mt7<2jo*#t&Jo3t|?DqXUM0jT055H z`=&gJ{UV>LYHd8p4^4RzyGTA&)!GD-ADaT1e{V4MmVBzJwTUD@HRVa{IQdjnYsZoN z%#s)-_hC>lHZx~ zB=)y_|BlwClKjDxC$a10`**Z<0?D6Dc@n)qzJEt+(@6ee%9H32^8Gtnn@;jKQ=UZM zkni8o+6WO-AbMCXz3-_hDhBrBTo zB>Itj|BlvXk*sXWlju_N{X1GanPgQ{o<#4G@88kdY?9SYc@iB>zPChcr;w~^%9H4G z^1UTmn?tg;DNmyN$@i9M?NpL=OnDMLQNFiCYja7~Gv!HiO8MRrt(``)fvKF_n$H3A z;w^8@dUz*`V_X9nKFz&k7O&JMhD0&h{^of~+I1Mj@RTM~HZ2j0@ayCCqE z1>S{$w>_lqa#bWI91>i%7OHY(+OHTk7Nf^ zp2VJ&=>)AUA=%NCC$W=dIzemalk8;5li1%fouIX)Bs-h(BzC<_Cur>gl3h%B61_mC z6STIBWH(cuM2C>+1g%|2vb!lyqHoA_g4ULk>|x52=q56qptXxg_A=#3^ca~=(Ao-; zy-j%%okykn(`z% zn#>1i?NXA5nDQk0oXiJk?J|-BOnDOBPv!%(_7{=^O?eVMQRV}*b~(vGraXyGDf0nZ z`zy)8rgCy?J_lSOKe6~Z;L5W_6_s_t)A@Kec zcsB;#zXR_k`QD)7*YD=QyCv{$4ZPa|@AkmEBk=AFyt@ML?!dbz@a_$~`vUL&z*`-7 z4-|R0yJP*ye1NX;E4bo^n95f?NUTbk5763`B!`;vB-X0T2WagolEX}S5-V8d1GM%x zlEY1T66;##1GIKE$q}YJiPbLi0b2Vz$x)^}i9I0m0b09;`s{v(AvL9PBZ06>{*!)(Ate8XPELNcCyR|Xzkx5XPWZlO(aj!+D#;9 zneyb#Bv01b%_L`=^5iWfPtn>fBdzsbL6tYI?w>{lQayzZvN3xkI zkoblRWZqA5ihjG){UoQFDlg>zb8`~MeXPf==5Z$|xthmKGv$w4&EMnX$34K~rYrdX zkDFo2ANPPAhbM)%|F7RLkbaXus+#lL2Rauz^E>g@$j>jn(>)k?4+Y-CfwwmB9tpg4 zf%jpDDtr1u>RzoxbDR@T>mAeu*1se4#TRH?yh^|!3t$X zEz!>LAdkDql;1ZGa^K9<v#EJca;`qYsw=`S*FK5!jwx)`IJYJ z6zoTtZqt-?Ou0~xTgQ}DrhLk}Bn3NIep{k{evdL`xgPf@Q!X`yKilR?VwcPBPE6td zSJJ{1$T@mu*!wbDX9|CQ=W6ET{0Wzt!f|Vx00KA+)bwZahsFlUgL2$EBP9ayTz10?zQB&*LmEnO1{qHZZqYNdp&st-r#Y! zEBOYGyTg<}?hQK*PllVSWZym2r?BPk&hpHMCqDe|7Pn8Kxw=_xi^5aPn?-kPcy9&X z+ky8^;Jq7o?*-obf%ie+eHeHj1>VPj_etP=8hHN+yw3vf^T7K;{``uctiKGruLAGu z!22ffz74$Z0`L34`yudt47{HL@8`h#CGdU?yx#)v_aYBZhHr{jt8k~T_&2%!?=t1r z|C_e{aok%xZqaGkUGgm+cdjXa+*>>@e=>ZV$1PU!Z60@?DSzDC$#L)SxFt%y!{g33 z<&S$OIqqE^w^Ye@dE5o2{BiFl*Y_TeTc+fDJnlkM{&&h{CT@6omX8I$idh2;B8;Yl)ohx9p*yI*Uc^SITf{BfW2jPhq=bgEi~ z2bBDR$E`8tkNYAy4&AI);Xx(8uY)9=FkyKkkR*ICOiNeO2;D z9=FMqKkmomINT9r5?0Bdc-(WQ{Bb`e$KkF~tMI&%Kl8X3O!?z}PL9K!MWzdt{DsH8 zWXd1+OL83UJ~C^ld)t&ht_+XMf0Kdpl1WM>%ksE)P5I->Cdc92Wv)`m zay;&RQ~tPecHE1F>V@|5o27301l+xBox&aR&aP1C!LK7P$Zwhpg>&U!DtE5@9%9R1 zy$ajOwUxtA6vO$;aCTkEtL6P{wmkIfY-86MY0O=ud^H4 z|EWq3$^jJxtyWfk37~&nD*rqB*T#kV)tVIEYSg4~V#_9lG98-~9@w`@p@#5fh{{KW`)dU6A`n<-#x5eYxr2Q3LiphJI`MyYj#1)0rns{?|@r%gaBuDRa719xPu^ z{<*&V=M2&d_}?vs9>>4l-*;#C&#f%w!+m#g|9o(vS)p7>_F@#|?6&-sdsoW4j51Ow z!@qIXg~A^E>)Czt|1DFvta3~F&z7T$|Eb#^xpTOjXVt=~@@n9(!zmn)Pj94`O*bDRT?FE4*zU$RA4kk1vKue61)h@^U3wEW7w%=7Z|_*dDQ z{2%$RAx7I^qGDCTMe9$u?r4zFXeCp+X1-Zp_Jzxwb06v zE=esXdwWZ2IXTlTRW3`9F3;3oHMP8@mY1L0zi^$VqGxP5*YZhfc}v9}&CaO;Q?Hk! zaSatLwE|OrlAngxxB^qV>Th<@hqjz+1xv*)&r;=eme=*4nu=FE_i?VjXllhI6+eAT zDtcS?3ZPG9M^|F%4VqfXQY-OXf78@TNou7ewUVWx(`2cYnffnHt!$~4lUJZJQ*RUs zuSex1wX&t6S7oVHnEG!`tzxNFn3}%=Rg%;yNoo~KMYqdR<$J5-b-hVbt6FN+XwS0ogH0+skdn=o;z|MsreeHk)+m0QfpW$x_)+aO{U(isWmONX7UQu zWa=II3e-$eYg#Jq8(FHn^OZlXJ2e&e@!a>Xfc!h3#LrV}C8@Z#XS)D*p6uw_Oub7} zYg=mVWDV3#QfnuvwJjC*t}JyMrv9$o1y66ek8{0SuX!7$=ACexBy}50#oaGE8Xb5* zp^V(-&|T_SY8{^IJ(^l4Nv)Hl*0EGMHBGI{)N-0y*HY^;^(^)CV-Rp`|uVUV(;8%{yVkB(8z-+o<0Q3llG@l(@idgB z$~ziauMcTz6H9H9yaG*_n)j?GNoo^I#q(5_x-C;5*3@k+b=%|>*fvSsHc8#qQt?EV zr8Z^iT1{i#B~9JI_S_Ck zeOyy_NK$u5Qg^Ua?13y5zkwN0sG_OOEwwpQ*K2C?B(-^x+T2pHi?Y-mnfinrjaOht zOWl#F73HVl71)uf`5k@7By~qi#XihZTQK!WO>JSREtpzaQ(GjdEt1q0mWrL6rS8Pk zr!;jZOWld7RW)^|Bz31Gbtg+jFUV3`GIfKdwzSli$t%#3srenfWs=&`QqfJa)Sa37 zw5INCsXHgHz|KkP&PnRdmWqCqrM6<~Mon#HsjZS%pjDFEDoJf+spx1~>Ml%uMpJjO z)LoKSU>Bz5cl2G7)LkqUJuypd&D2erir;DGKJI7v8fcxQwoX!8TPnJ0cJ!`HeO6QP zJJQ@oYQ6?`O;UGFQg^jf^yTd6HcWj^Q`=Z-o8%Q}!_@qa-X=+HW2xxuS!!FRKCh{5 zEwyd32HGa6ZIjftmWq2rmfDV~FKB8zOKq2|fp$r1yCk)prQ+_ArS8VmI@(=!v((*~ z`l9?a^nu-&T2tP_XDWZ!oGH8ydr8j=_oytnJ(KHda(hc|&*YaixqXt{-p&`v?Rma= zGVXL)^6pH2MStS%mb^QYU)AK@nVk2o-6eT|O?>a3B;$UWC3j%*W=-y3$sL&dnkIKh zk~<{H9g<|+b+hC>nEbjX?_tS%F!>El-XlrgBT3#PN$zOL9hv;5CUj)-U!*1D73`S2 zA|08Y_p**jddDOkPXXC^@5%JHG<{E|U#{tUCa=n#N&22i`kqNTo+q;OPE3DW(>pQ! zubSQ|d1X2!>7A1FPDwhROtSR7nEsBW;~uw{z26|2YPLew($#_c2lJ{ovdz!qrCGVZQ8ha~ zovEEPwY#NuXX?kA+C53_o}_lSR6N0Esrxdunx^h+srxeZ6HVQhsh^t4do<2)U#8-{ z+ycIr`@g@B8(PT!9$vuTxx)YANW7QpA!k?oUan{0^$NWG0l=6n z2426wJ1Fo<1MlF#J0$S>2i}0dJ2dbH2Hs(THz@GrBZ)u!84V7+BLZ(o;2jxwLj&)q zz#A5LM+e^Uz&obM!;0=9UbZ`WaCcPK-O} z|BpHOJ&>m2bGq!e-q=N1>V8bEr>Xl{>V8bEuc`Yn^*`Dl_On#HI{Ps-f6~HU%#wRE zxq&A4w&dPSZm7wa_=M=J333=pUI!e+2FO>-;(!d^5=S%`zOi!OY#8we}(MN z=Uw@&Qb4q_4&ScFqSdxv{<)2QWFm zgC4+SO!?tD4`4F>3H>Qc?aS1rn%dV=`!aPqP3_Cn{7%$2N$qQ?=x|x;flO_psRvr> zflS@je0;uw6>wmZc%UVsKW0QfCN|R}`&nW?CT?$jp4cx*>}QGSu36$iO#E8^qziNpGnU7cDd(G*etSIS*Qp;b3{+5dSRF*2ARY__KO_hCU zK2m?s)B#EAfFyN*rQ%MPr5?)Eo%B^Wl&L>z)}eeAT3XG27I zz60%i2Qu|1{TTy!zWHt)n4}K0RNQg1)WewivmA|Ge3+#k#?)Ul^)RO9?>!G=D*kON z*)jPF8)T`2nEI=x4zkoiO#Mw$2PLV4lGH(VuDI)G=Xy9(f7evZUgbXi#0qn>m3MfO zdU%q0xTWH`Av=07Q_INFxSGM1I+*8LR#OKjse_q{Z!^q}$zK6Hd1R?aFtwbf9$~3R zFtxm<9+9LTk)$4B=Za^SEOiJ|D`@HvOC7@0ikdnkNga};4zW}`{bZ>}GPRPX9%-pZ zGBsZVM=~{kw|!*tx*ln%cz()KhcdOYrVh2#p-j!!z|bUhXp%bAQtJYznS~k zTlpF|hN=1Q7LG|?*JGH9_hhB+Jz4%<3-7ZA@^Ac8_P#6o@A$nN-jj`xvnzg2HZt%= z1>Weu8xweA18-d59UFM#18+j$O$@x_0&h~_9ZyeQX#Ay9oRjILQ=C%*Z))J35O~u9 zZ+hU(2)q*mZ)V_~6nL`&@8rOn9eAe%-kiXbo5dg2kSy{)c&8P4=<6fI%XYyC?v9$e zJ4V><7{NW4_p%Ym?ii8mjuE!!u!6JHkxZ?nsUt0QBvbQVHZn;anWT=iRP2E)bre%; zYw9RV9mUkVmyJqNM=>?OpN+Cq?4m4nG*h?H)X|nYnyGm&8=a(%PEto(D)wQPib?DN zg*uu##!|;HHSc9(lGHIt>KIGKPR>%tGPRXHDUG$%u}s}Xd_19!WorJ^JT`e<$66|S zL6$m>sjW42oTZLq>aLnPE=e7iq>i&xbdxOgSf;koqmN~3U3oolhQ~6wt<~_nm_Ici zo4g9gS~7Z4mOP%x?eu)d+xd=XYCZiK<9WXM`>^rJ`Hr_#bhRvX0#kR>)Crb4fvNR1 zbwZLlAxWKJspyMY>O`it*DIaK)CQV0k;%JT%|A6yOp+&BGP-M)d>oTI==mOJ=X)Ge z8|u$Ej^~>{H6NFx9%rfO&spjurY@EDGw2hOEOio7m+SkSNleZE#3nHn|7PFpnEaU$ z9X?Avo~e82xgKw+$4ly=g^uRu?;nq6qWp`0nRvXNC+-hf;$$Z7rAJP-#K}C*&gSQd zlO=ILVQ=xV{w6c=BE3r7VY1XIOzomaPqEY~OzmoZo;ro8`TsL;N|K6uRF*oGsonJG zsg^pGsr#6pr%q)m-r?a~r!uvX{CVQl#a%8-Jt0e#HxZeiKi8a)rJA3op1{;Oa=%6D z2}vsMlUeFCrgqn(r`fqqOH!xt&mTF{lGJHQD(U5^=tEtm1bvjdfn4h2P^yC$o zo}|vO)EP|esYlPS)EP|eWqzJIBT1c+q@HN0Co*+EJ^DmTJ&~!s&CgR$Oj1uwQt`Zy zy#h0ty1yPh(^6+LwU7CE>dYi{W|E30jx6;grXHY2pJb^gC8;ObpVmo9>Pbl|o>{Wg zSxoJ#sk1C~R+2i)QfDQpvyxOi^<=3hGxa>(b0=Hs$xOY_{QMO-IY~X4srin@b5oW& zo2g6m=-HM!o2kpp&r@e7sk52dSoap5yt33&n0me*eTt=?!qf}Q&r?rHQcp=z@$8nR z&S7d3{b_S7bq-UvH9t?ClcdgJYEz}~^p~Zc%GB-5&-=isOl@Xh^l{TszmfOf4}#Po0~j&P`JB1e%@eX-wTgk3P*(Ph)Cx^YhfxlGM{I74OA*yZ2)G zJ1zh2YoNRv`>+1Sd$Dws7#b)IQCZBG}r!)CdO+GzIK0Qf3 zJxRto&64Lcc_&StZ^`qSyh@YjGdX{jo1Y}lPm;0Pv*a_F+)|UzkmLcp{xg`ov-o&5 z&R}x>yVWx!xxf9Jtj}O_-gy^T@&YEe(&Pn}ynxBOX!3$2c|nrAAW6o~%g*^sCb!n) zGcEZ{Chw}rXC}#KCdp?e$=JVH@Ai)`K%-vy(CLMo5}4p`D{x*o5{Ot^4Ur9*-7%*NisT8mV6GA zJ81GbmV6GA^R;mflk?xXo|C-J=OoGKYgzIlChwuii!6B&lk>H)C`n$FBri&m(H*no zbD7*xlh3u}bD5m4jdPRabCcwAlVtSREO{}L_tfOYmb{qB`Px{VBri^0=fz1fI(3$O z9+Nw1@_Ckg9+UI6abA*qUXpxXl8km`0vU4i(ogt1K!uwxY z_T8(6#yiHc^7oPImy>_`yZPnKuOLT`l6{f!6-8AnU<#_Te4kPF*YCgce}CPpup_oi z3;7vq8kQ@R>{ufISYb`$9)&Uu%M?oRzhacjjjkffujy6!_d=zz9pwLHQs~+Hu&HCm zj*;V9O`CfBE+suj&p2`9j49Jf#!Q%gT*@5agJlg9$S2tqo+)oG3Ti23U9tf!uBDP)i=2CMEtUW5 zT4ryhYZ;1b!Ob(fmdd=AoAp{M+qG0qt_8bUzEVZ61&e;m8mnyABIll5OBH`DBMLIH zl&`S~|D%gJcG8qlvdUUbm^^mcj0qzr?egaf4o?8tg;n8&-KrN>#V)K$a$(uG<=mzh zRwcQxDt2LVA<2cwxAkn<^Zvq4{(o^{Tz$A9W*1hK7k0Z|SXH~Q>9z0s{Pr8&HjIJVO)xM7RxTI8ZYcly|8L_VcB;E-KCe3eP>YK z?y4mhR?RLi)uxk~@|x#lr>-{*z``GJVFh6XhN{O;+8EX(K03pTryJf4l8f zw`;1-Yr0#nsk&WLb*{qvnyM#luX=J#**6y91}oQ)TvLtsn*OBe{V%SG3lPu3*`HGl zUei5#O*QPAY9!Z`eP2@E{%R!GRKxz9cWn~vwn-_S$ zUSMsz!0bD$@(a}Ouo4Q7PPLN@tZf&F?-=!Mahv!8|Ewu)r3>T|#aqVg0=MA>uGR}I z{yMD(%+DWSw@EH;8@o8UnB?N>_>0>|ej9|l^uV!`;#+iyJqS)4i>@e-v3w%j^3DQp zXtOh}!!ur^XI97lNa}FSJ!pP@#&vkc`6G87J7YP+S(Y?dUUdho@#*UjXdhFyGB~!+gOr3Jl*lB#nf?q>q z=UAWTxK7WdzMW(C)nt#FpPys>?NjBgM`MCM{Nj6AMGW(V@{CUesB`4W1I>{6M8z(ts+6gCS@BQ$L zn(QPS@+8;m$uzW+Y{-**LVPr^hRJ)shCESxB{iP$8``TWCzhOOBY&a?7W&}T?88T) zLyF$@m5dxaZOWLFCyzXS!swE5Q>Kj``(M4|!>^UHD`>o{lwkwb` zPOhLybOn6O`CnZD?-}@&U3LXccm*5u3YypzG)b;NzkE*DRFmWin%EV{87Eh;t-pf7 z^4mGCB0kjoH!k6S@DPLFHfEQDZ@ueZcv>%~_*?JtO_6=;UH%Z0ed}GmDY9?9!|s*S zPcElvbUE20%vQS`t}pzeG`k#p-CqB~M!lTkuiMKnC;Pg+{GD9(b$j{cWM8+3%aPMh zE@!*wa! z$mu7S)68Fv{7cob*bdHGR$KQA&+Inko7VADj+gt@f7P|{OX=()@U?>d3(x9B6o0K? zei7N%3g*A3%Dz@GzliK>1#uB_(#b_^A6-P&wf+x#?*VT`(QW${8B7ba0!j{&1VKba z!fsfwKsGt&jEV$7R7^-V=bW=*&RG$2Rsg}c)KSuKBF zaQO3>|AWg{_598#y}VK1&>9$8!x9aLW<9SJkC1w@bJyw4trz;#;zRJ#om-F2m=zy_ zm+stpp-=TYlXhurkta^&iYg8UQ}aVnz)lqgOSf2H`VmAmd(|Q3Lsm(w?<} zjC*ND#fSePBcB0fQqYA6}KrWrL188wuQ)(1VEv^JD% z@Ul@Hy$!<==W9>d_{&jQHjRC<{)p?3nLXyM!%C-v#W_D-Br@J#K2|uOIOx%P4B4XzIm{gyX(nX?&vjMU;F>B z+XjYL^w;kEe?C?Duk>{z!z&K2n7(Et{r^Arx{>Ca;!IHSHUeA*T^YST1lJ6Q>|O9` zcALSFzFAzwAC(KE*O$l@qJQzakyGS2#g&R=){KJ>oLR5TrFSaeL&kmL*_{g2+(K;A z?~mdg2q;i`A2|w?mcx-(s^OYpsfLSkr5biZsfIe0YDl59F1SunS`Mf9OEsJwFV%2% zxm3g1*-{N>H%m2~)hg9+4y{zfX{S;RCw59ToJA?saLS@o!zqGluB&`*>1Tv*Kq;=*~6iVNp?w?e77aGvb}bWJ&z z4*$4tUZkRx7pb^}owyT}ialGT;%17xJ65TEc7&G?j-NQae_;`e4OBO$92)fovd7py?J+jh~ll_ zYN&tum2b1~;j&}mPSKLM*qHfnu`#P1E;eR9T-8h5sp`YEyv&Ddd6^H_@-iQ;oF(ow z_2GJ1-dzx)*oW(7iNlFb)Du^y5_h_m#5JkRhig*V_Ha!q^Wh3m;?7VXuKQ#@T=&U* zxbBnraA75JXQ~gEQ}XV@5W#nGh~UHR45%lrS0wH%{T;4SWIkM_$b7g;k@;{LAaQ4_ zZ%gvwT^gAW7XUIJPR1wh9QEN8eBNCYqS%Mi@QM3U>xr}Di91(I;+%Nq!}~C@?cuz5 z=ELdg#GR);oTSctc;iLp!-?w5hf~OjEBAv9_7YAU=Uu-L!S|Rlaq>8EUuZpXRyT3| zwIt5vWNBJ<&VZsx;@*2E1^A5O1kKAc|7d^o+D`EYtOaRb$dlbU%qC`7RjCp8oI zmDUp{6%#jDOX5^w=EJGPY8E1fi%$ntztbLu+JcjSa1dp*1zMW`?$lp*1(O7KYZ+&{`Q< zYeU=B(ApSUTSME;(ApVVdqdmZ&^j2}9){M@(DpR6y$o${L+fN{`xshhL+etap}p1f zTF%|BM?6kAWye2GIA!eyC!Df&gJU%39#9|NtC0C{S|{`2v`*&3ah!9Ps}Cnn3hw$4 z#Xg)o$$U80bM6i;iBlAruOV#@rztWY+C$DgsJ=$zYec?A8OT1rUC4)ao^z|z*PMKKlR)NcPCoPnId_%%T8Qta5XHV0Gqf^8^WWb$@^&}0 z9)^}Tw4R36%g_pj*4xnf7}~yu*4NO=4XvM{_4m`?(lcWN3~iujyuQodC*Zvc>1^#_ zLmOgf{(9I(-eHF3Z|~ix+z3M(X=tMiZM32JyV*C|##loeSE8XG!ts}LYxMZg^r`FfGB7x~bJbM9^R6~y;Wh~jz{$cJ{GbMI=&-sI~|+v`m} z^aVNhp8EQbuMhe9kPrPu&b_a`eZ}`dh~j$gOFr}|IrpKK>`T7Bw7tIML%)-AAE~dL ze0Yj?HXf9d4}DY4eXPEI;`<~-v9BNb`it*VE!m%Z{b_ss$u~fJpQ&#E`38`00Qt}l zmbuTp59eS8ddkM zA-?a`H$r?rgeb1(2=a{--;Y{yB>C_Z>1@A@B;P3U{iHrTC%WL$?cq7mnGes2_BYz= z`M}ZQ`&oT>5_G}+5~A2QntWr#_p6q~vz{{_p7oqd}GNs zPJF+sZ=Cr42vO`C7krqr&G@(HZ0VV{jpuQgvyJ!L_s@W$dBX%ln`mg03~jQZO)<2o zhBnR6rW@LRhPJ<<9bjlP4DCQen`vmX3~jcd%`vot3~jEV%`>!v4Q;-m9b#yQ8roro zw!qL1H?$)R?MOpA%FvE3(J=SI@t1Rd>JdMlj{ou0ZpMe>A3hwTIro?PCXjCe`6iGL z$8pa6t-gukbN;eCm=no2k$gDTbFPAxoJ77!Kl0)E!&!g1ANkPEb8Zv$?N7e_$+tiG&==&~rs_LDe4B+R-rfP^Lw}KT zn`_A#+d_Q@lJ7wB9Y{X(I|Y~XKHO!1XZ{xC*qkYZn#!B$3576o zndu4sW*{B;&`TBEmP)|$eT#%yM3_Z{SwujeR&ZM>0nhR+5@r)&HW6kM0X<;BZLNek zfiOo1+h`VZh%ko;=r0RyTP5Hby~R2lLz zg!x36PXvq#1y@T6cz$k?aEK5FXcmVM;SeHV3@NzUO2D&ni-bdoa3~QDB?3mAf~%th zJQue}IE)B~5#cZ*V0f~%_pJlnQNz_V>L!VyF`f(RHX3$C6Ljtm4m$F|@GX%*=Ycs-8L^z5F7=;V2ffDe1+9CnZr_BgQ6XEDUz}&OFT=(60KA9=Ff9gN} zgSqEIUz5_g=P`!1$j}xW+7d%sYG}(0ZMmVXFtlS0?Knd_-q21kv=a^OBttvd&`vS5 zQw{AjLp$Bj&M>qy4ecyLJKNCCF|>0H?L0#}-_R~FviGVg)aJwjBSs*ME!cfg(84;Ed0WG-Tnkxa%kuBC?IT4lN`PvZ9^3MP9Pt8tDM_SOP)x+6KQ)Vk`Fyv&b3qD zN#r|;d?%3)ySKrCv+dV{aJx?Yddd8gVpe0Ws-zl`cQ^<$jGw1eD->Kxo(@(Sg zc`EtP!{%H^^_?cZJwp`xP9qN`_>`-CX=ok>3Q_&L{EOP)nOJYO{1-dW_ssE~7A)OR-d&L-d4?P^22 z#?Y=cw3UW-ouOTCXg3(zjfQrUq1|j~w;0;3hIX5w-EL@i7}}kNc9)^uZD{ux+P#K$ zpP}7vXb%|LgNF8yXkEiysF>g3_{+IIdi-BP$NwdC{9h7|fB0~W=G?yOyHtFALln2S zOUZ}hIOoc>S#YD2aCIPD zErijU#nnW(nh0pe1vf?s*95{fM7V|s*AM}%zTn0x;o3mBmI&7p;aVb~k0`itN>~{P zD}^v#vsg)ll|(>~Qg9QLa9to=M}+H$a2*lQ{}kLrC0ri}*AwA-B3w@d^i~BoNeMRu z!VN;0tXbSZgd2!}zOCShf2eu{W)O#op9umSZT?_P(5Yjtd9})sqMPYt>4xItrc%J+3D45@_@-->FWAb4` zTWx5M7}}$T_L!kPZfH*!+LMO%l%YLsXwMkhvxfGZp*?SCFBsa3hW3)7tueHh4Q;KV ztuwS&4DD4zd(F_+8`|rlEu_0J-Y~Q`4ec#Md)v_7DbX-b#qn2g!?h)>3N2w3wS-mF z5>|zl00NFyKmSw0!-4QH5gsPO!$iQb?dN|=SRDwfg)mB6<7y(TCIVVQ!HrhJBZ2S; z5gsAJBSb*E@$)|=JQ@g(65&xIJW2$#GC%)Q!efE(m=MNk7LO6(F(RN%7TkCxJRS&- z6X9_pJWd3(U_bv;!V`h;1QDJf!V^S5d-wA{B|I4jPYPj@X7MBuo+JW#hk~1|gr@@G zDIz>Ygr|srzQoV}l<;&QJWYhBiSRTL(DV5DpAw!4glB{>O|y802+t4!{ZzqCSHiP_ z@GKFYCBm~rK(FTKe@b{R5S}B#b3}NK2yc!6v3gHmV;#DHNN(78&1$U?t zUJHcRi0~Q_ULyiVKR^Fd!umj1PlWYESWg6um45!Ggx3S%bs-$CS-eh!*M*R-701Y0 za7QTNjX-#V2yYPK4I*G1F1RC=@Ma*qNrX3v@Fo#3Y8Tv5N_Z;}-V(ymn#Eg0c#8-a z;|p$~65bAkw~6pJ5#A;OW&{Oyj1t}ngm;MW4iVl71k8h1$vpVqneG1TGMERy>uXYa zp7%XNd*9GLFtiU1?IT0`*w8*Pv`-D~Gei5_(7rIVFAeQ0L;Kp$zA>~7C97euPro&^ z?+opGL;JzdeiV&Y9sML)*Kp1h+x^+lelfIP4ed8W``ys~Ftk4n?Jq<7yF|k*7RO(~ zEz*|oZfFVbN=sPm^8CA=R9 z?-SvDBD_xow1k3Nri2dy;R7Ko*DO9D!Use^yD7L8O877kJ|x12MEH;hXk`U=tP(y7 zgpY{u5fMHj0@`H39jAnk1L0#K9Ish?OoWe#fEHYECn({QK=_0RpAg{_BA~q&+=)u~ zG!Q-|!ly*|lnCe@3hpE&d=?0w3E^bT;xi(AMg;UF1$T-PJ`aS?iSRiQJ|_Zto`O47 z310-l7ex4i2wxBZ{Zzr7ri3p8;Y%T$u33CZgfEGJUajEHP{LP%@D&lhBEnZhKp$9e zXDZ?AK=_&nUlZYLBA~}CxU-b-O(1+DgtIk^Z;0>>5jF_n93^ZBgbhU4K!goM_*Mw# zD&gBe_?8IY65(4Sd?$qSl<-|3d?$qSHH+_v@EsAp7s3Tf_&yN6C&Kqc_?`$q2;o8{ z{16B~5a9fI-_h#(g?zt|?-%m@D!zs4`&E3$geb1(ujKnpe2cW?Z{+)p zw)Y$Peiz?j_5Du1-^uqo`Th{!67~HdzNI0G>-h)y{uJLbE%_(;{-o{wNxr|tw_JUH zk?$|^{YAdN#kWFze~a(f5XJTUJNPgQ?fkzu3$<26VdmoBox0K4*b0VL(a|+Fm8{p*`f>$?B_2zRKjQOg^-k zoI6E*Rm68{h~j!yAs^aR&Yh+utCFuOZLcc%(DrifboEsuUp4YoBOlsl&YhvY>f$>y zL~%WOG6abb4&5zX{c!L=m-6C_q60zbKhH~j+lcSV5XJS}hJ5IA{d23d z=SZn_1vC(=-+d0rIy@*d^^zgb|4?dfSkKdeLIqG zNAm4RK8zDNcfI;*iSLFG#r3R3K8z(fccYf9O}^T+z1rl%c$0HCsjm+C>X5Gv`7kEs z+|BCSNqo12D6Z#Dgm+Fm2_q0RW`*{QEF`5Ke2G5OH0{Bv#9*F<~|geb0O6Y`<$`R870$)@CM zO51BnKD1B&97^>yBVRM}H6tI|uzxP3`gRfD!y$_6xeNKw&i(TbwPbVhHK*-0Cm;F( z|2#tVwIE*$^0goz`V0SjK=rj0-(w+)>)BF#Z~6zI3M;-3$wC0miN6>YB-`Oxp= z+!N|+O}^ITYfV1%P5!xp>f2R(PlYJ1=dR>K|K*<#s3qHwuMKUl4f)W=<=ivsYfHYi zT6HF_T+0%KJ>Z% zxq|B3U3@QvD6Z%3&GPHuB^)|FVhPJPv^)<9| zL+fW~{S9q^p$#;&L54Qi(1sY=P(vGLXu}O{grSWzv{8mO+R(-r+E_yySE6CO!||7M z@96R0m5%?ebo_S>$3J{HM*VXI)z?jY?}aFCZ{5g;V`;?Uj=ceN)bTufBfd>qowR-Zy@;wk`H}l&i$gkLE`&0L~%U_kq`Z8&i$q(2a|6wZErC7 z(C6md@9G;uz9HlrLO%4%IroS9hKldc5XJQzN(&t)FFtmxH@f~K9jB=9=ZHl2yEzvMGkC%P1iDo~Z_QiPG zhvUP(fNz5MHdWsQ@=YM$1o9!LGPi~I;eLmSp0e@%4wJl^xSX;ld3N5_^buAkP4evG zo69D7ZsL4V`7Sa(SKCQE&`3K6ajrX{CH$*uKwQ>5g!AwtRYom5k$S0IVzsdf;|94+Q zy3W6L6!kvR@0|*$Lk)fn>5wh5xRU?e7VcB<-^rrake;8#Rs3BUD>uo?!X?-DH4 zitij{FX~=e&R@&lNGrZ`l)c4wj+E+vYEjX*y1eTWB8&&= zJ;)V(i_6~gRLT4NQ**Q=T5IO3b zc?Eig?0qU##n)X+RwZ9mx<9Nc`KpPphx)3KuNwKPk*~VXKj25MjTh&w#H^ z`PGo^_0p0x$X7%5OX{mZzD>keP~Rrx+k||ZkZ)7*^;X}el3$+?#r52j@w7t#9x4HQGs&8}hZBD+;$%o!3d+z=gp0e>V?B^f8PUXtRh+lC1LKNqc6L$LC z_L}1BuO(}euO`*0Ci%7$-vIS(Nxm(~wm?yI~>1-W?tyY<)zC(DKr~ zi+(zzY$ueFT5>z7%cu~=lZNo|1D@ z)K^<5Q$rN*m)b%}-(ZU|Eu+*C$~5)WAxa%NUeZsx4pA@)W|WS<5oIT$>_ild zn;B(iq3ov=KX3J)N}AEmLP^J^or!{xHlx%P%Kl2JOO(1qsT(NxHd;sS@}20cyLXFE z6XW0HeZOA%2Y30_^R7+P~fYhh?D4Xu@- zwKlX}4XusWO6R+64Q)3=YiDTf4Q+Qr>tJYm7+Oa|+fy{2KksFf+uP7O8QMOE*4fay zlxUdG)$>}`8tO@FI6zxNJ!%d0s5R6JtpOAqu^FYlP-ZBlK2homCG9=y69vb3Mrk0F z1C`Q%C=H0xfGB7c8Kt36W-6s2Q5q7ZAyLqdGD;(%%u-4tq0A0Z+N_q|hEia=q z7Rns;H6}`9sY}{>HYN(%YDQ@yl!KJggeXmj(u62z-5I5+Q06M7DN&jVCG9<%5(WK1 zMrkILc}i(Ulx9R}MilfQ8D$rt9ITXGh_VY&b|DJ-oQ%?3DD#!loG8tOk{)%GROQN7B%qXpda+p$D5v3LFmsUba-;$2L zGo!Q?$^xadCQ56fv?dCA+l;cSP!3nhu0+|DD7z8`{c}cXBa|bQ(uOE)Xuq@}3VQU6 z(pD%(Dy1z^+7hKLQ7{H%l--1Klu~vh%5Fs2jVKs3GDWWty6i5LW0bNxQFbTF?nJ>@mQgwgWsy=k5Tyg{mkvb1=$BFU z5Xxeu>_L=0h_VM!FkWVqjzU?Yl#WE{NR*C5!3dkJ>)X>)HvUeym#~*AdoN)x3laMC zv?4%pl(LUdjt^0s(LO>+@BH6~D4m6Jg8DiWr8Cu~Gf_GdrHfEbR7w}3bRkL?qI3xq z%(8d(rzvMtES)$1=W(NGu8kRWSARUza9u0-|An)T-3+bF&=N!IZfHFWEpKQ&4Xu}< z6%4Jnq4hDeeMRFLW?!RRxuNwlwEq6nEZu(t3~ivH4KlRBhBm~|h8o&1LmO^rBMfb% zp^Y-M(S|n0(8e0txDpM0Mpv)-HEP-#x=L#}IYe>G>?*Axy~nki_)gK1-N@ICT2VLh zm5J|E^_7vYjC^I}^H=nIJx^0#BEHi@6xTBmUwUs#ck!K}CA*WaJ8iE!`Fe=&O!f63 zUk~#2AYWd5XQ?kQzOzGwdZu%|JmuF@eCKG%p5*H(+e>{t$=6GK=c=z4`FfGB7x@a} zJ5PND@)gKep!|A^?|k+3CSPyz^(J2*@m-+4KIH2|zCPqbe^KTx^gdh{-q%w$9xwZP zwcK5#?7p7uSEq$2J~sLaI~_0k`s<6?h+Zy~OVn2`luJVtQ_6`_PLzH^xlDcigmQU^ zVoE=v^dky-wQ_fb`ubBw{b_IYCrW>!pdT!ES1M%yWi)^&1Bfz!DCjxM-Bn5%NErXejNMp+p%<6pR_=?nb2yql|_TWf)P05e1`6xw}az z!zrWTL>W$$;Y7i>RPJt8$_Sy{5~6s&j1WrNjz$m#BU!n-Red9ca$AUE%1EM&Bnrm9 za(BD>MhWGP5XF>HL>WaCjF#o@PW6qZj7HOb8BLVYM8Wu4?(R~`7|Li2QN|Eu3{fy5 zm%F=_GL|wLOO&xh8A}w5;pOfgrHm8Gy&;PC%Q&H=?Py$}VD>s+&Jq8scT2=`)PFsr z#q4#wuTAOfYl5LoG_*;EHrddo7}``rn`UU!4Q)R|+uzU*FtizlcA%lnG_+ZUHrvqV z7}`OGHrLSR8QQ^yHs8<=F|ExqCo;6NK_$h+@hFqD&wPj`4E$koqQ4%bZBRL5(TZI z+^tf|B+6(KQ6>>(5>e2O%H6|CnM@f?Cdy=@OeP9iUb$PXlqo`aBt-FknIe>QJeWch zwAFI=sQRV~<*^XOl&M6SN))v2a`(9UrU~VV5XF>fM43hu^athcN%c*qjHc6mnNF1H zL_rTy?w(T0ew5LEMA?rh`w<0wPPuzpDf?4K`x9kqgh0mMU+`YLH}ItURKI%%4jxGW)o#LQP888yR}N0Bb0R^ ziucPLp``6-4pA@$l)G2dcaTtC4N*)vh$sgU1*1l}drf_Fg|a?GF=Z}M<`Mc4iQS)jt(IT#>;Z|j`|K2%DW+oDTfl}P@-UjEqCv!?=YdfAEKCY z7*P%*3dZDe_ksErP(}-Azbqii0-|6PFLxg*<#5XAaH1Sel*5UFalhPsq?98lqa%oN z1W}G43T6uB?qj7KDU?q_6z`WKg_5?TBZ-2!MY;P_eMbr9vk=9Uqlj`8Q7{`Rcb}{8 zXrX)&qL^|tQH~B2%)`6>7tbQcvvSPC7y8E?f5!8MfM53krxeqQd9{=b5|pn4Pkpa1p0 z`00de?ea6k9|oJqvJiyLYa~97mWgbU#TET;)@_jwzpvyE;US%~7`KowY?#GW{9(M% z^RVaw%TBON#I?v`zwn|0wkJOoakH_%Vb32W{>LYeVF5p-x1eFaRP#%7&CsN;ThiZKUCb<aHQa<- zs^ON}QVloAdX4rKZg(x!aPw+4m+e0c@%TX-EZ&}g!?K$j<`1Ic?<)EU(C`pd^3jM8 zRrb-y5LNL$9HT{FRUZw~-{CMWb9ejy;qnmL^v0KmDtgr~{_thsM=Q*`${tsYu=rz% zKZuJFZn&=!euqUP=`G=vgo0(3C|OA;Rkb8qa^5XfN^uEEweY)`QduY$E2Xkfs%y#0 zLRqGi;)0SI;de2micqR4rHc5LtFMahMe=SF^`Q^Ra;Pf4P1ILad@Iz41tod6srsst zubTLN)lZMJfNsi`H4 z3re;OQS949e2b1Men$9|{HGG4xSquYC22i372jeli3KHjw=6{PrS-&uk}SW?#J5CC zVnIpXEe{cVX+5!^B=c=9zNPv(V9{mXZKWAuc}d=#>APPXXT{|uTZi9);#Z%_@3s)i zVIcx#8!fqoP|i}y7P7Cm4Zn*iIiXyp6fAPgyX~|jmZRj|*-G)tBYd=d_#IQK`kGbJ z-_;c64a%%3%pJn-z&uBp#ic4chTnmiwm9^(W$qDALEGNaGdFJAX!D6XM7Ok+Y^j#g zut+8EYKI85uM?tpOIr(NvQoAd%1&AmOIGr3=MaHXH$*XI8=+jHlx>7kPfKC}OWxHF z5hx8p6jQbpN_C}dE53$Wa$ETX8igqKZ704>)rUnYdDmD=ZYRDbA&Pz5i|;pWYgm?& zcTKhA_Tp<6BKXoavxE5lR38?iatHA>4^iyfQGEU{Ifk+HB=1^i$sNVlGDNYj zmiSg^>%wA_ygNQb*q>=VvDhT5XKnEvt0l3#B=1fL5qxPqvAiVn)e+xuS`rIN^6tbC z!I#z(3raHIPU2gp`Ryb}K`YG&3rh0tTs`)&pd{~Fhu?vcw(XsTvOp<23uRX=i3KHj zcb-zPpd|0wgx@hGZk2U~dATy{3bU>Hu)HMi4)vovdL1k;$-CXc?_y?MKMO6kbezDL zC>Ij3*rfPHs`Qc~)WQD0fBk!ZY2MFN>-poTbf#5bG@hw85Us1v!T;zit)ZbcGPK5q z*2K`78d@_$!>!_e7DRPvZfLlTyR;l`$}ZJ#i?!EiriB}(OEuj79M80{|8O&N>HaG& zHsSsEf8Syg-hcn!EjGb8a-;t&as1blw$VlYA&Qv|iP=b)mnyT7F!xelBVq0xA}~9JC}uVyW@BO2P-bJH z?4v#`I?4NoWfXI0OnbR8QJM&4Go>^UN*DEE(MjHQ4N+W|CPZl}l;8a)hJDslDBaYD zMJIVz79vp6QLrgdnhE7Er8E;tqP}KA=^mn((u^p(2&JlKgheNL*F$|+bmIHe5XF>T zh|*jrC+UdQTqvi8D9#9rPO^-e6QzYvPF5clo#fqVAp#}M2#ZcKN(-X26v`>;!=jVC zJ3T~kMp$%`QCbqEl~9)JerYAgU{Bo>Sb~yw7ib&B5|q5_6@CY1IaWgjB1(u@Z z-6gsuEJew_`C%za_Q~xgTe?^4+fFD0l!B!wd3UK&uoNZxeubqd8KoUj+6!f{Qm_;y z@5*%_U@1!WZ3|0LGD>@*>@Jk?O2JZ;yt_>6f~6=~Mp%lHQFa%~eVS1Rp-fT=mZId{ zzW`w0ESw>ijl2P^`N=Km_q!cVg$-67GE?A0^ zWrU?D8Kt98?$?a=6w1L$*;6Q2DrHZ~XiuW-NtC^Wa;Q?UbS3ZlYesufMp(L%)dfpe z5|`FxZ=ozv%HBe`O6!89D_KTZx{^__bR}^QXhxlcvRo-xx{`NSD+Nnevd;)hS27Bg zu4I&bgmRoxuyiHw253h6P)1m~l2Nd9C8Kl}%2`Um(v`fsM(cv5D_KTZx{^__bS05X z6KH>3gmSJ@uyiHwu2l+_u4EZu=}Jby(v>0wbM_f>(Q&Y!lMj|Z#hH8dcTvUfGp+Pr zm~(dZwJDv$;=FpPR%U3vKi;TZcSGx8Xn8~HX=uF+tzc-q4Xux%?Q3X#4XxbJ`Wae( zLmOad0}XAEp$#^)A%-^8(1sb>a6=nmXd?}6l%b6_v@wP@*3ib4XlM;M{t|bAwgxO+ z$-9BtGP_dC#L|_lHFOQF0TdjuiMvKASjduhE458wAxqXWv5+OBbQ8)$+SlM1Puz7% z!LpXTyG|)s){?bMENjUqWkf-%@ZUm|;=g5k-yqG%kK#T`&nIG$OGd#pp~R(iK|4y^ zy-MjWl@&imnvBwiDCpM`_n}hu70OV}XkW@` zU!v?w6!e6NJ40vnScH>zH-#w92#avCy7U!FI#Wd7nYatphebGfcXNp1jIanNqm&Z` zy=~&IQXdxK`27+hP||jUMK~FyA5qXhC+!aBP_znC6pR{)J4=07gp+r7gecAk zi*Pc^AfcqQGmJBdyI6f#gp+r7hA7Smi*Pc^V4`4T^8K#*um~sb?g~+y5fdVG&N=-4~)bBP_znC?kY|n^-WaVN6ckrRu{XoV>d~ zL~%w~gp*N55(T4p;#R5;i*WMpfe^(RVG&M78ATL~`-wYOeOQE(cMpar&IpTeGRkP7 zq@x;U3W>W+eOQE(cMpXq&IpTeGRhdDU~b{ZY4u?dPTs8wQJfJL;bfGtM8Rw%ap$QI zi*WMp;Sj|cVG&M787Gug{xkX~Z~hzaYg0Pso?vJb4Q-O4O*XVChBnpErWx9F(H8m< z#sBCz`~3`Ue?vRK&}JCgfrd8I&}JFhY(tx4Xa^bETtk~@Xa^hGd_z0L&<-`U!whYK zp&f2$M;O|XhIW*p9bKZKufg$`xXbnU$0D4(TOFdfWnvLd)*8l#)&L5Q*u-70J}kn? zyGKG4w@fU;$tV+uf@3^!=c^BkaPsca5XCJMi*Pc^M4_a!Gqj4tU7@~7LU}AiaYk5# zlTjuS1??ztH>hv2P#zCaoDmk`WR%H7LCf>sa@03PC{Kha&S(lzrU)gSDWa_=?n?Dd z70Qz#iZhx@l&M5P>-OJI)Hh8iPlYJX2#avCjHVF<{Xyau>wPEFg|d&o>V>0Vy398> z(b*>!;bdnorwb*WDWV5STz&On5strJ5F*qiy_W@xa5Bn%L_wdExCZLmUnreI1j^(7 z?l05~i*Pc^{zO49mAHoL!y=r#+dD*{q#0omPDVLEDCtZQ{aWH0sSk^A{9|cD6la7* zI2mOIQP2}6uCe;C2*+Om2~nI87U5)+1BrsZGx7I@7IViUoV@E6qBtWg!pSHzg_6z` z(c31jsrs-8$6rSYQJfJL;bfFqL_zuRbio$-BNGiZj9@ zoQ$$SD64cfk5N2vyQvS0aQu~z5XBi`5l%)qoG2Lg6W30CScK!RHiRh72#ats$`M4t zOd)Z*s}GBC{2Bfb#Tj7{PDVLWDCr1`xkchSs1J*9{8{x7#Tj7{PDVM3D42~TZV&Zg z5sp6t7@{~MEW*hsM+eG3IS*gxYvb?1pn2{whPKGi7K_%^*FBpfFEO;GqGfm4;ynB^ zqug>sTVZ&QHOd`lXvZ7g6O3{v8rn&Q_hh5oDL!@oJ%;wdsiJYdry1o=H#DrBD7{bS zOrspG%9L*RY{PqwQ4ZH)O1O2T9y$^&Kme!$TBj zbSzPh6-qi&M4ywmG3q-`C`&>VXLKAw?=+zt6{0w!(};4KP|}&==|Y*RzSD)WJVbFurxWFLqMRX=Y3e&eD5r!d z&gcxHoI#W`g)&`zXA0%$5XBjtNt82%vPx%)X9;CL^_?Y@6(Ncq_$;*8EF%GpFYM<@rV?;N2l3{jlXIYc=}DCtb`T%pWR-?>6LHbiko=Mv>yqMRp` z1J!q)P)-X`oY8qiIgcpk3uUJI&KJrtA&N6PpD5=GB^_Ze5Xvm|T_BX>LKJ6o0Z}d> z%7sFit-cF|a(am3j4mX~g+#&JqRc(&j~?6uc9Capd=J>gvL!rx6SItqWlOi}RmO|u zd`)`i{l&7S^xnveWlI=^G0Xn1J}@=A^Q4j7DSnBsjh{7znGa^bmm1n-hIYB3U14Zf z8roHccD12hV`$eJ+Db#a&d{zmv>OcVMnk*F&~7%gTMX@1L%Yq;Za1_$4DC)syUWn- zHne*T?OsE>&(Q8SvHFp4VOr3Xs+|XOQ%?xrQ>jhA7tvC7n&82TA0i1K6L}3gsT9TuT{UOO$Jgf<7m4$7@|y3T32bw30Gf zNtBgDK`-U6xhv&5q1>x=xsEcrjwsg&C7n&8U-Q>cm2$mM?o-P3l+pD>xt=KK3H|*d zO1VKOqco!%D5D#QasyG&cls;$O1V)e_iJ5lq>OGP%8f!vXOrk{{S_>w+$59-lyVbg zbQ4i-A`1HF#NDKnn}sr3GrE~Fx|t|969qkb;_g$*Ekb!v>v9WabPG{#5y~n*y5cy) z7~t<4Rm!bGc}OX@QbxBDNlybXJR%u;s zr;KhV%I!i)XOkG268EA~?hwkuO1XnFx`QZp5Cvmd;$BwDokAI_8Qn=4-AR-?iGtBD zaqlSQE}^W}y4*z>-9?nUgp$rCFlC+{u1|z9{;PPHM|(2xMi-Q*04%iLpoE$5u3OT z>U&ryFNG*>nGX}?VWQv|Pu#ESTP>6|A&Oh(YND(r3R*?tK2_f%LU}nvaYm02!ycwc6qi2cotWZ|zOc6a{;(k!yb3%D5L~%yX5#>3epzloFpXz&FC~t=- z&gglfJWmw#wu$>veJ=>*oe;$ty+D)~gp$q_(LX2dNA7^u+z8 zzL$jZUWnq1ULwj%M8O!4xUbZ=Mkw!xD9&gNQPv10ohf3}NZe2Ads!$SgecDFWum-H z6pS;8`&)f$h4NvD;*8c3Wi3%KG9|9I-dnX!C<8(SO8S(ObwWv>3A0Wp=}Zx0S>o!b z?-ij83=t^lGf!S2$}2>{=$E*i)c2}T289TeCqjhlU};@mB?`vN#O(;_9jIb)gImQJm51M0uSk7{&b^cItaW zD8oV&XY>Y9-VjPU!eZR_ci5@#O`!}AQJm46M0t}am?`)>?9}&`P)39(&gdU&!#BSREt^fpo67D_t8Vm9LMuv6bVLKzjJIHPxn@=l=qlk@O*eQiqbI(g5~ z-Z!)l4DCZh`^eBfHndL+?NdYh%+NkJv@ZFgiqW%Y2tw!@Hq1fPy2|-zloT_k=PgL~+Y}k0|d6C7mha825LIs_%WFj15uT zGT$f4`$R#j@OO%;?*pNX3sIcW2SoXRC}>CiPEqxJD3tLbiZl9Ocq7RtmB#Tk7}l#hvm*6r^URo^E+cj*-#0=zAVhIS-w@>+ zqM(2FcZ#ZSgHUFK2$U`LZ081{RM6vWgHY0$B6@Uxr>OeA70Q7j0%dEZd`pyXiGne} z-(jb|?}RclM4)V|l<$c09Z@i9_&e;>_q|YNg(%MGd!l?Vlys(uamL?ar@kMAGCM?Z zMn4ec2clqPO5EP+`%x%!LKJ88BT;@N3dXX;byD9?LOCczaYjE8nEejy4**u-^F->*VBI7D$qzY^tFp`UY?$$7Z1jGu>hrFkU!qS8B%D;ni085+K2mU^ogcFHiovX zp>1bq+Z);rhPI=j)iSi&hE~VWb~3b`4Xtj8h8Z+&eokCokAGJIcU&J4qPS(c3h~{% zu0s6mkP1TSslEzAIWk0X%d9|@3Ph8-xXLRlE1IHSr$sZ5kALg}NvDndCXL~%w{h*Cu;4{JtMg|e^u zstRRMh~kW@5~V6pstKj9`l<jg^jF^|LRl7~IHOI7vI$YpOO?6D{olBkaZ}IS_+G}%id*ts z7LKsZWJ{0goNcoT*ixBZ_1;Xjl-|p@nQZB6{Tw$J${?j|E|kZVvbj*wry_1nl+B5< zg;0hnWecH<*R5|Ml=L}|TM%UnqU3}!Q7Jj0Jg#-gQARnUVDVzfP;TU$zy> z(^{8pDWh$PvaL|Q)r>GwCGJ?IY$udwl(HRVv>j2lBMQd0#GRm&?S(Q)Guoaq+MX!e z69uE8e@cl`b`Z+5T9+LtqaBE{gHXQHj4*!s)%r@=Q7F$TWk_imI9Q-pCm9n!?UevnmOd0J=l%0k0gJy)ehJUu0 zQtArjC8gA*jOr4lZlL^UcYinXz3#vB2X}hc^R+3RCDu2z28Pzq&>9(9V?%3VXiW{R znW61sXw40+g`u@Hv{r`J+R%12v^Iv;*3fn{w04Hp-q3b8v<`;0hoN;ev^@=NFGJhg z&^j5~K8DuW(7Kdpm@(k^OWbO04fUioOx2cIk6LCuY7O;5YXAjDY~r3*N`0ZM(Kc0| zT4sHs)ECN++A?vBC+;PsG!V+mN@+kXvjI^W5CyFwach;*P$<(hqlT1GL!vY!3ffWP z-c?E?p{&)qG@^_e5v7q(e$tH4@)GxfQW^_ool+W8MvaNmm?&tg{+>OhG!e>l&8P`w z)PyKah=SIgxEe6=+_cgL47TSQZGbtMlFfbk|^j26St}QS_!3oh~kV|5v7$-(wQRq&ctn_zScr% z5TZDv)+7bn0K;kN?Z#SVd2~nKUZbaFQC>S*ox4HV-38iU>;*8o6rJYdH znIguS#BHa(_CjeEqBx`WL}^bHj7KV6khmSyw~tWThA7TxAEN9-6wECWS51ALg|b_S;*2^I zr87}58%f-j>gytub|H#0>Ozz*Lcs|8PoC}W>T6Rv5ASAZWuoyN$cdqKH?$sxmN&GX zhStl_3WnC((E1qKzJ}J<(8>+1pP}{lpNFf!`(=Qk4K%bthBnyHh8WsVLmOsj!wqeO zp^Y@OQKDh(pL479j+)ViHpbA#ipEz_#)+2Qd4m}=j=#j!(&N9Yw1)N}id$w^Y7JdO zYXAjDY~re`ubWVI4^iAQyAh=uQE-g=6Sm zJ&4jnDCtZQZ8dSXsV^^-&q5SulqX7_C}`b@yIp-fh4Oib;*5F{r6*C)A0+M$_4N|U z7a@u>>P3`ZLP=+e=s^;9r}_#)`7%UtMg^i2h=M*Rad)Y&w@|(cQJhh4qVy&Tda1qLir{{aYp+RWnZG8C-hI8S6^SDYzR@DQD36; zB?|gZzh+T=(6?rub)u93sIa=Kce&_N`Ij|puYY>`94H( zM*WG>pC|)_@}T+#2<3+m#TgAC$^fCHGsS^Ic}RT&h4N#F;*16oWgt-o31yY~1_|Y- z5XBh{BFZ453>M16>KiPSpFXEc;3Ly0m>D37Xdm{5KTQJm2*q6`yCI#V1jl*iOJTqwVXD9&g&QHB#`gisz= z-w2`n5u!Mw5kwh5l#xPtLVY8J@@I(Rj7Ab=q);$ZtWdG4!zk|8V)zkll<=PPgrbf& z#1?g2WByCYqvXs=I!28m@~A+5(EUc3%|Djrq%CQ&@9#>i3iv>sJs!cjFw zjw=6^ReG*5a#ZcAXO_pvQRR*LJKPV0SvmTuG5>Q^{kJ@-FuskIW9b>~iN?wingNJi~jiQEtAW;jQD??}=3+|^N{@!g}lwnG=XIfhah}{rkX_GEpd1lroW8=0u`QBnn!Ef1-?1 zCJCjgQYKMGlZY}&DCwC6v?G5lS1FT)QcWq7DWl0mnM@S4JpXPorA!e@b)`(9jHVD} z3Q^Ej{nKrfGF2!wlrohvno5+ZLP^gopmqD}%1W6glueW}jWU`>lxajke~`F!N|`Q{ zO_eg8GMY}5=|n*flDJotvY${kQ_6mn(SAhPPble`1@t+IdsQj>3uSYq>`xi(Pn7+M zf?g_duPNmKp=_a)11O^dh;jf?(61$Ky;5cfC8v}bl+g^L%n(X?W&u56;$BzEfkLUN zlmjWF1Br4VQP6iL?hU2P6v~!LnMoPVB+5*pptnujn@X7_l&zF9i!z!;lvzSa&n(Oq z%3DgAEtIX5GMh4*O_bS0nIn|9l`=;t+bCrYWi*EK|RP<_hIqrOXw|c1oE`8OqVu`KXuAu9g0T~n1wuJM zeG7y#BSfIQs+0vpIb0|hZ9zF)C+g=1dd^Yi(ZYOFnMV`zXkmU8d?^!i@AmS(~ z(Ri+RyrG?7XeS!lNrrZ^p`BuAryAO6hIYE4ondHa8roTgcDA9NV`%4!#{2I)qa2Rd z((CDHZKWDoOX)Fmkx}mA5)Hitj=wVZjQ<<$e4%eC8~1g`Nc+LJ5;%^L_H&T7pJSx` z%ncEGsd*ua+xa4);Cl=xi-dBpmRuy1`5}rai=-7!RNrEu;9CRTd|x3ouCB0WNy(GsC}vuu5-P-cV(eboY`EEUSzN?A&jrIgV! zp-ffEGO5eqN?9h9ca*Y>D9b3LLMh9Ia%70GUyce9KBIK+t`N$2rK}Lj z(OPnaP|z!3&##cW91|i?(w-9iLz#Ql|BYknSkK(}m^x0jRNr@IpdBad_chPsguO`F z$4Q=_Yn_f4Ujy|WPrl>Dw^)70lkWuaHB{dT?2%Po#RD zD86)U&`IK}tG<)ScM{d}B=VgszIy6AnS3WxJx?azDdOv(_bHqrzCA;PPdwe9r;zVd z@$I1{PbJ@}RL@h%cbfP*s_!)NoksOMjeMtzueRoQy7)fS{dv0hmg?tly7<1-&;1PX z)luIWbrn^7f@yx)ymup zn%RYBW)}$?V;wTPNHRN7*%!%{P6`n+J2^ygW)}6;yXo4UMw|CeHVw!FbBN9 z2F|}W@?8GY$aVY=|GkRFBL%YGyZZx!;MB{np&HnSNTC(c=7DKz$&~7ud+YRjwL%Y+^?lQEy zi<VNe7`aOnruV@SX_tmW2eFpD-Lwi6p|44(#`=C+op%M-4<`S>@=bd_IF~Sx6 zQ}y`2gpU79sD)nYKZ`Pd1-IDuTjFD}-{E`mPYl*&&K4S5VeyNoDSN z|2KNvE6uF0k}Yl6x|ruxeoOx8t06+x--QTUx>dJ(m24@!7w~GKe6J<17RnDH0_DdL zfpWW2t|rPgLitHcUL%yBLj=k%Ap+%2rCdXlYlSje_uaL!w?5JF@LKug&Q;&FzE9P+QhevBZzcJz6W>_%T_?WJ)OVfu&R5@cLa|%0*i82BCbeb-6((7l+@)lpBSD9u<@ug>s3Oypb}xQ7D&& z-^G-hgwnTVk#dvx%0q-tEZy@r$(~4O%IFmn*H25{EWZ9Bf-l|kHxX zFhuaBd;S*kp?CFfvD0jC72g-Smu{8((t6%1zI3LH9@xLPPJOqD?@RUFCcdeG@_lfTs_1!0XBAxqVyz}pBRNwvL`&NDTi|<@3>U%(Z->L5b@vT(f z1LVWFnYcmfdr*AetM5Uo=Y!%)=l&R56E|3W4~g#w^*u!Od?@%ZkMx~`pGOwwgP2J+ z^8evaaTXc>JDyjvj(OxNzhysppgF+9qVYU(wP-wtdc@EkHMGYJ4Nuo7oxkEda;b(h z>ZRIKhW50fJ!5Fk8XCR{m2LxLb*YB$6{XsX{_`ubhW4_dtu?fDhW3h~y=rK$ z8QOY7d)?69Ftj%f?JYxlTQvTj@J>lNjBu;G=HFlC_iQne8HyhNtEj!L3dcW6KI|Q3 z?nVDMW>gP*%Et4^)xzFF*{h{({iN*G!oE)1@@iqHqswZ!y6}?v9uZ0|M5y7FZp_C^nqbG^- zq)=W~-%~=V9U^4(r&6AxjGiLOQ$%@MD0P(bwAAGM7+Jq5Q3s zXDFj*i1Lh3)~fGWq0|o%GV-s_kyi37W%Mjjo+Zk2LTR9s=cF#)ER^Rcqvwe798sPZ zN)x3#FO-T(d7d(Qo+!@?Wu5w75K7Y!A)`u4d4V!|fhaE!1^ummGOtozl)6+_%8QiI zi$r;mDCnX6b8MCJl2EEBX{BvxT z^0L&Wno?e-j9w{Xy%`hs+3oSvZ+#DrHo!B%Bwu{4-KR zgp4**%4?L-YeadCC>SyQ{9h^Sr7oK*Wj$rIo+#^yf-%-VQB*0f3uOzXyiOUtPL$V$ zvR-`{mHiV%LxhZSN_m4adV?r$5C!A7f1;>T-jur3RLYx_(VIkhlPDPZ{r4&TX7ZL$ zx`qhfQ_>OkEuy?7lyro}T*1FLQhjd=rCW$VNk`bXiSjm4FuO?Hf$DolC}kl6B^_bk zA<8>}f_ZgKxkjJOtBW({|Fyp{uYT9prgUETo@hKLdfzDbfuVh9ct0}AeQao-7~W5f za-SL6=Z5zSquiH<_LbrN+9>ypp=~g{-x}qd`hX}O2qm2tjjw)#F5N}mwL8GTBWPl?gLtiqH7y= zamcaB@f=Q0|aYQsf;}+tUXtM|(CI$hS`CPmiayyh<9iKTdAB|WiHo>*y5tc)jC))On| ziIw-nDtKZQJ+VrjSY=PFiYFF$VpTn{YMxkiPppQ<_%nhvJ+WGeTzU^fZBM;Ao>*N^ zZaq)E`kq(=Pj0HGUYaM?(36{d6iUoz?I@Hszgd9Qe-5w_c}seWmO(@rFe@flTulgXr(A) zr@hw^@~WuvkSoPoRE3l(q{wJ%?{$Q{K$VAGDc+)hlzNy#Qf`jNeN1(Y0B zZiJFUEy^J!hZN~~_TCjxa#dLdC6`*1OG>UP(MnPJs=apwlsr{#f|5rq$|EI@6zSde z-W5>tRk;~TKD8*HlzdWTJh0EdpcJTb3zPzCQ2{9hszfVA8A0sxFDQko+zO?TT2x3% zAt^HE*n3w%X{5?+P#RH-8j;e76d9%Ly(^$JR%JPq#?+$5q%>9~S}Dr7X761ArHLxH zLuo=SYC=jAQe-5w_pX4_RFylRG^G|bC8a4TGIoaMGAPYdnd?fjQk>&T@#ogfREbuK zGTPcZV4!AmRkpd3DBE2rt~4h_#%Fs64Ag9)%AIIY3vJO3w=J%;AVo&>(0q=XEmhg? zO7Rx8)W;>dO4?GDXr(A~Kxn=|UMp4pbftKUT9ML<6qz;bH*p}ZwJLX^MXjkttx0K3 zip(>i`3g!KRSvjPyhUwDX`@QCQk0n~G`o=3R+WRU6mL;mQreOtb6IG1Bd?t*E6}2L z)S`Bzv?E1kKl`~=D95Psmn+3vbPOrSs1mIdWxfo}*T`$H%HOUOZ&7XlqH8fSi-+b{P$*!Qe>qNn(v`>QRT2J#aq;clrE}7GpwvFLh~*1x~g)- zmEtYxN=jE!WHn;HMFx4@RJj)|>P9W8`yYnzOr8 zZ|JVQAzCTQ85^1(p!871zI>!g4^^T$y9X&fNRe|qG(SQqQsqAM%p&TUMWhswBE2Fs zKS2pqu@&@KLTXV+N~lV-Qj~sVKko;nrz$0(^rRN`B&8=Q((^*|JCt6k+>aLZq89Zc zr57pES3~m$l-{b8!m;$G7WF2jw<^&}QF?c1_Co2SN@*y4s6~B9=|hT)2cg*qrLQV? zqeXqGMSV%>ONxvj_Pb!P_kOA@btM_e&v7MLokiCa`>7JG6lKh@-@k&I{Z+Z$l|(t$ zmEuZ&Qe>2}-xYzH$EtFlD~U4QmEy{=q{z5tzf}x12dHwRE5%zhKp&T=MFUicR*Etb z+Hdkg-au9EaHV*Q29h$66d611w`U=5kSh1PQoKcjNEt+mjJEb0tB^NXm1V9JZ_!{< z2CEXS6lHw2-x7tqA*$TzO7RvAA!P_DGNRjWWMt<>0Xap%EREbuKGMCwJenZ|!RaUrCyhS5P8A*!Fe)ikekT*(|hg>P% zqEV!bB1Ps)`weHv8?DMMt`u+4Xi`S260HrIzg-7;$E&i+mEtWro|NNBk+nr=8X#|iDz~{(yhRg8nV?EE!^&zTG^xltL6w!R z6mQW9q@3WC|K>XUM0>?I`Fi+7Pi&GWCf~B0oI6=#{FzPprr+fEpr7K2o$86n_gp6D z%DoDcV^cjbxf@|}J-H`ga!l?wm>iRP0Vc=f9)QWQv+Yka`TiZ}cw*;zV$(gb8J^gA zp4j=G*ae>0Oi%1WPi&Sac9ADG+Y`Gu5wquT@oNW{cw(0(#bh0RqK$QI&?so2bfiSBm${iKI+aC0Z#?QY9UElT^9amEt{f5-F2NIZ2fa z z`EWKW>x6guiDszi4bnL>L%O%=Isq_poeRi1)!8nxjxRiZnJoJPu2 zRpd_IqD)ogX(&^vMN?IY?kF;ql+#t|h)3dd&3hKg>6#Zk@~3NFbYF{Un%5b5(=_in zoOv;lP#eUKfc^7J4^mtyVdC|}PLdug_Co~tL zMYA+7dOT;*an7PVnVCW}3wal5Ui5fgM8|m%<;m<7nv0M(Tl1pFb2c64Y|4`v&c4Ef zQR8AAHP+#LxmcBI_{`$Ps;qb0;?JCAP7L*~r84$hqRNY?d5J33poIB4Gle;P=*SpdayUG)jdj%%v${hofV{-q$>GR=Dhd6#LwiS8zJ8RgB@yynQ8t9cudH&^rScO~g>(f%&i zyhg~ooR0Hy&5Op2%V~e}G|%3`N?SCKj&q*oMWe(#%DY1Inj!BBI?gLJFB%uFpu8(J zFBf@NYTm18(UqDPJ)T!;UUdJUt28ekc~@!PYskAw^P9&IOtmJ)R3F?;6c3K;AWUoY!bx^mtxF zc`{xUnQiv0lXd(;s~o+KU!-;jdy(32;4xUFc4=4AF&s6o)x3VLRMMX9Z=&Y4npf79 z;(3cTZ$5g$;uKkrzlEBMb?8ohex2rRLe1-R?-g7ro_D?G^+w+H zn)eQBUaxr-T`8V-gXUe2qrO3p`d!q#L6w@A_ij+-J-1DiUvZznC8{iivP6~lQFDnZ zwV*6f>?Iw42pV zbtSParlZy^n%Cczf+~d zyDB@}Hc_JU^bS>SgmQ-}pQGj-s?>vWhbmvVZE@vJRc?lIrz&5f=AEj1E?N2i~_Jk+) zq$l>2C$`!Xd)gCw#uIzi6MN1Rd)^a!!4q5KiLLd-)_G#a)2KF*14GAh+apSnx?R5Q0N>J3tJg({1otWf0})Lfx`ssWT0s1$qjo!265C?hmU~jl*pl4EP>y${D#v2mN>#o^-bz(E zxKdnMNy@#dEP#2hw)#8d-K*yJt|TK#XIF}w_mX*^nngIW`&9V>dH3m&b#h8sBtSE>0M@>Z#t4s(^7{oS^>xr$5~JB!SAYf7Ja z#O~qfKJ%#VcNETsM|DrX!+uov^oJ|O_w=al=>;6`W2%gW@|Y@nk@uJ?`&=omJVuI) z*Y-{^P##xhKk^<|RBfPz52b3pNIe@$;s6|icGmq$8d_t8qXpzhb_8tsS zo>b)^lqac0Pm=N^DKd-L`^`XkN|nE$JVh;fij=2Fk$J~ng@dwMmA|2^rWUOxWwk16 z(IT0tLURd}r&T!w4&%3&za zQj4A?u6q#{DvjocXsu+Aa@Of&{^Q1gaipRZ2ox zOD$SU%34xnDhtld_%^S)JHV z5kq-Vl`>FXq!ztM%8O2sb@>o?Z;BivEAQd>d$|3d{7yuR*W|wc$-4X{do;=G%9lN{ z4W8I5p4diD>{U`hPXEl=!iPi&JX_Kqj^t|#`MC-%N4_JJq1*%SNF z6Wij6edLLK?1^pl#6I!FKJ~;t^Tf7!V%t5j9iG_dp4b;jFl)_(pL%FC*hgYq)<%$G@dnG`w4?Pp%0Y*3{lMGN^Q>8ML*QiCWk@A`<8_*)@-S$1oP+nK13Y6EWMX!_cIw>+9 z*iXJdc|(-|${W<8H%NJd6d6J6JwveyeN&Y;@s8d%RjG`*_f1u76Lj8sQ2}D@7=8tMV|Ew^gYIj zCQ>%360H?$`4RJq!xWh%7>)LJY(-c31y2a zk3!i(E!slL7E)wpviE(2@{ua3JT^bsi^sS>ReWiGS#T7>ekDnCN`m|FBPDIb#} zv!8vg1ZAr#k3rc=E!s-TR#IfXwD%N*@`)<%LivPR^a&}Ss1mIdWrnr)@q_ZIDnCK_ zlv?yDDW8%ebFzKj2IVtV9*6Q7wdgZaJ|jhDaeGfh^TdAl#QyNa_IhIbJhAo_O~Z?$P@d=6FcmQ9Z8DGI{Zr; zv-fpHZ}?Js!;|O@UsBKfl6u3Jt~ZGCl`7Mre5J|kp#jjPF0p)8| zeunZj^~|qH`I?k(R5=gIH>x}Z7++iu9u*^SM1Tx$d~rnnz!E{8slg8f(OF zbx&2XCjB-$#s6s;z|Q)L{K?^LOdyzf-0;YxAkJ5s(^WdfA%RjG-*?^UVg zN^#|TQhrcnDwH2osg1lJs6{{MV;5a_{6UpyHTk0|XF&N;l{!#Erj}PV7Dsuq3os>?IvY6 zDL<<+7s}77G=TCmwdiM3ekSD?Rj!5diz=y5exVlqLdq|yM61bPRkOAA{iN(CMdmhp*EJ}As*(%kPioPh zr2MH$w3?LJ(7s9u<$x-AP!3Rw4v=zy6q!Hm-Nm3BR3#tEL2A)KQVx<%m;cmEF)??Uw7<|H-xOqpx@CotR4=y-F*y5tc)jC))On| ziIw-nDtKZQJ+VrjSY=PFiYFF$VzR19US(JF#AMx)Tu)Xn$uU`(B*$cZk{pw@M{-P7 z63H=H7bM4ImQRk!oSht#894bFlgy{d^<;KTj>%k?9Fv(V9+UO4v5%?!3<=hx#=ekc z@9cy%seBPxZ&P5`n~9pTI*YD58haZCd!JVHOgUriCrY4{P~{gWB~)nyr9{cNQi2pY z$L;4!proj>8cK>PO`xQZl0u5~3i~MzC?!?d45cKss3a*RRf$%L(vR$CI-rzNOQEh*krWx%LNgaiB~?CxQi)nr ziIhsJL@PxZ2}5%^l*+374y7`+s4^*)Ns+PBekKP>6;+;tQiWPng_J6!$Y>jyE1(3b zd<-R^76qgPszfWrs;XQGrK&1_K&eVCs!B>#QmUzP6_jeKtc6mIT2zgcYNS+GWj>VZ zs%(W)omy0#lSpcd62r3NWARapR~rYdWo)T9>GB&8-PwN$wV zN-b4Bfl`ZFREv~aszfWr+NvysQd^aMP-;_)YLil%lsc*`f>KA77ogOk7S$o84k>k2 zxfV)YRX&AMms(Vpl)9=!E5&-MEQV4~mHklaQH$!4Qje7Ss$2)9zADc{sZTAcPfC4K zWEL;7-#nJMUemyuM_;c=)jf^Dnlx4S)Xe6|yql_fYVJz$Yb2?Qa?N}4Jy zke8-POIM03X{0n%}wCtMaRD z(b22yqgT-XQzTlG%PKp=9!-4ZBe6_REXxzi_QY~Lv0P6q&lAh{#0osILQkxbC)U^# zYvPGD^~9QaV$D6V7M@s3Ppp+E*4h(mu<%lT(tt3q$c(B9A%y&;2oW(M_!4A&b(ku%o5J_IFGm3B}vsb^-Al1Yl3 z<8~bgB}!7UhwWM~d`r`#n!k@>S^! zC7)W9Pf9*1G9H9x1(X6+x2%ziclN;_4Kh0=~%)Q*&Pq{!?Sn(MJ9Jw}z! zuqHi5l_FdtIYt%R1YJcQqe`?=l=;$*bx_)?@+Xw`s`P}?o|N{a$P8=W+YP0IDz8H6 zph|Bj9Z2awipgzGK<@B7fL5p4nXNdE$T!{CsJhI zx8F+!rL!s

(Debta`VDY8g!Kcg+m< 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

?e}3iax){{Ep0TWPg#2VD$M#7I0(%BL|3NT%*q~ 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

LC%$=s@S-Q2ovZe2H9m(&c#WKL#?)?MM& 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 literal 0 HcmV?d00001 diff --git a/docs/source/install/index.rst b/docs/source/install/index.rst index b394ed808..6bd5b81ab 100644 --- a/docs/source/install/index.rst +++ b/docs/source/install/index.rst @@ -217,17 +217,29 @@ You can also build your own custom images using our `Dockerfile` or base your im Install the ``openfast_io`` python wrapper ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The ``openfast_io`` python package is a wrapper comprising readers and writers for converting OpenFAST files to/from -python objects. You can install it with: +python objects. -.. code-block:: +To use `openfast_io` as a library for incorporation into other scripts or tools, it is available via (assuming that you have already setup your python environment): + +.. code-block:: bash pip install openfast_io -or +These instructions are for interaction directly with the `openfast_io` source code. + +1. Follow this step only if you have not cloned the OpenFAST repo: + +.. code-block:: bash + + git clone https://github.com/OpenFAST/OpenFAST.git + cd OpenFAST -.. code-block:: +2. Assuming you are within the OpenFAST directory: + +.. code-block:: bash - poetry add openfast_io + cd openfast_io + pip install -e . For more information and installation options, see the `OpenFAST Python readme `_. diff --git a/openfast_io/README.md b/openfast_io/README.md index 796c7a563..4d1d77dfd 100644 --- a/openfast_io/README.md +++ b/openfast_io/README.md @@ -4,21 +4,48 @@ This package is a python wrapper comprising readers and writers for converting O was originally written for [WEIS](https://github.com/WISDEM/WEIS/tree/77a878d7989b8c1d07d2244135ccd308a193a924/weis/aeroelasticse) and has been ported over to OpenFAST to make it more widely accessible. ## Installation -Run either +Installation with [Anaconda](https://www.anaconda.com) is the recommended approach because of the ability to create self-contained environments suitable for testing and analysis. + +### Installation as a "library" + +To use `openfast_io` as a library for incorporation into other scripts or tools, it is available via (assuming that you have already setup your python environment): + ```shell pip install openfast_io ``` -or -```shell -poetry add openfast_io -``` + +### Installation as an editable library + +These instructions are for interaction directly with the `openfast_io` source code. + +0. Follow this step only if you have not cloned the OpenFAST repo. + ```shell + git clone https://github.com/OpenFAST/OpenFAST.git + cd OpenFAST + ``` + +1. Assuming you are within the OpenFAST directory. + ```shell + cd openfast_io + pip install -e . + ``` + +2. To test `openfast_io`, OpenFAST must be compiled within the build folder, then run: + + ```shell + cd tests + pytest test_of_io_pytest.py + ``` ### Extra options [ROSCO](https://github.com/NREL/ROSCO) can be installed as an optional dependency. Run either ```shell pip install openfast_io[rosco] ``` -or + +## Development and testing +To contribute to the development of `openfast_io`, install additioal depemndancies using: + ```shell -poetry add -E rosco openfast_io +pip install -e ".[all]" ``` From 4c76a0eabdf23acf9845cfd1ab54a6d0d5db8aaf Mon Sep 17 00:00:00 2001 From: Mayank Chetan Date: Mon, 23 Dec 2024 14:34:16 -0700 Subject: [PATCH 146/161] Revert "updating docs" This reverts commit 00db7af9d072a1855eb13ee5a3988dbb354da087. --- .github/workflows/deploy.yml | 41 +++++---------------- docs/OtherSupporting/OutListParameters.xls | Bin 3198464 -> 0 bytes docs/source/install/index.rst | 22 +++-------- openfast_io/README.md | 41 ++++----------------- 4 files changed, 21 insertions(+), 83 deletions(-) delete mode 100644 docs/OtherSupporting/OutListParameters.xls diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 87240dbce..3f426e2d4 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -13,9 +13,9 @@ on: jobs: - publish-to-pypi-test: + publish-to-test-pypi: runs-on: ubuntu-latest - if: github.event_name == 'workflow_dispatch' + steps: - uses: actions/checkout@v3 @@ -42,39 +42,16 @@ jobs: run: hatch publish -r test working-directory: openfast_io - publish-to-pypi: - runs-on: ubuntu-latest - if: github.event_name == 'release' - steps: - - uses: actions/checkout@v3 - - - name: Set up Python - uses: actions/setup-python@v4 - with: - python-version: '3.12' - cache: 'pip' - - - name: Install Hatch - uses: pypa/hatch@install - - - name: Install dependencies - run: pip install keyring[file] - - - name: Build package - run: hatch build - working-directory: openfast_io - - - name: Publish to PyPI - env: - HATCH_INDEX_USER: __token__ - HATCH_INDEX_AUTH: ${{ secrets.PYPI_TOKEN }} - run: hatch publish - working-directory: openfast_io + # - name: Publish to PyPI + # env: + # HATCH_INDEX_USER: __token__ + # HATCH_INDEX_AUTH: ${{ secrets.PYPI_TOKEN }} + # run: hatch publish + # working-directory: openfast_io docker-build-and-push: runs-on: ubuntu-latest - if: github.event_name == 'release' - timeout-minutes: 500 + timeout-minutes: 300 env: DOCKERFILE_PATH: share/docker/Dockerfile DOCKERHUB_REPOSITORY: nrel/openfast diff --git a/docs/OtherSupporting/OutListParameters.xls b/docs/OtherSupporting/OutListParameters.xls deleted file mode 100644 index 73ff40c46cf43c65c504e5e321aa0e656e1721ff..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3198464 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 z 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

(Debta`VDY8g!Kcg+m< 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

?e}3iax){{Ep0TWPg#2VD$M#7I0(%BL|3NT%*q~ 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

LC%$=s@S-Q2ovZe2H9m(&c#WKL#?)?MM& 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 diff --git a/docs/source/install/index.rst b/docs/source/install/index.rst index 6bd5b81ab..b394ed808 100644 --- a/docs/source/install/index.rst +++ b/docs/source/install/index.rst @@ -217,29 +217,17 @@ You can also build your own custom images using our `Dockerfile` or base your im Install the ``openfast_io`` python wrapper ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The ``openfast_io`` python package is a wrapper comprising readers and writers for converting OpenFAST files to/from -python objects. +python objects. You can install it with: -To use `openfast_io` as a library for incorporation into other scripts or tools, it is available via (assuming that you have already setup your python environment): - -.. code-block:: bash +.. code-block:: pip install openfast_io -These instructions are for interaction directly with the `openfast_io` source code. - -1. Follow this step only if you have not cloned the OpenFAST repo: - -.. code-block:: bash - - git clone https://github.com/OpenFAST/OpenFAST.git - cd OpenFAST +or -2. Assuming you are within the OpenFAST directory: - -.. code-block:: bash +.. code-block:: - cd openfast_io - pip install -e . + poetry add openfast_io For more information and installation options, see the `OpenFAST Python readme `_. diff --git a/openfast_io/README.md b/openfast_io/README.md index 4d1d77dfd..796c7a563 100644 --- a/openfast_io/README.md +++ b/openfast_io/README.md @@ -4,48 +4,21 @@ This package is a python wrapper comprising readers and writers for converting O was originally written for [WEIS](https://github.com/WISDEM/WEIS/tree/77a878d7989b8c1d07d2244135ccd308a193a924/weis/aeroelasticse) and has been ported over to OpenFAST to make it more widely accessible. ## Installation -Installation with [Anaconda](https://www.anaconda.com) is the recommended approach because of the ability to create self-contained environments suitable for testing and analysis. - -### Installation as a "library" - -To use `openfast_io` as a library for incorporation into other scripts or tools, it is available via (assuming that you have already setup your python environment): - +Run either ```shell pip install openfast_io ``` - -### Installation as an editable library - -These instructions are for interaction directly with the `openfast_io` source code. - -0. Follow this step only if you have not cloned the OpenFAST repo. - ```shell - git clone https://github.com/OpenFAST/OpenFAST.git - cd OpenFAST - ``` - -1. Assuming you are within the OpenFAST directory. - ```shell - cd openfast_io - pip install -e . - ``` - -2. To test `openfast_io`, OpenFAST must be compiled within the build folder, then run: - - ```shell - cd tests - pytest test_of_io_pytest.py - ``` +or +```shell +poetry add openfast_io +``` ### Extra options [ROSCO](https://github.com/NREL/ROSCO) can be installed as an optional dependency. Run either ```shell pip install openfast_io[rosco] ``` - -## Development and testing -To contribute to the development of `openfast_io`, install additioal depemndancies using: - +or ```shell -pip install -e ".[all]" +poetry add -E rosco openfast_io ``` From 2d9eddea42ec99c31a4a90beff5d894d3089d316 Mon Sep 17 00:00:00 2001 From: andrew-platt Date: Mon, 23 Dec 2024 14:34:49 -0700 Subject: [PATCH 147/161] FF: incorrect default for FF comparison file --- reg_tests/executeFASTFarmRegressionCase.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/reg_tests/executeFASTFarmRegressionCase.py b/reg_tests/executeFASTFarmRegressionCase.py index 44f3a19d3..ce092f851 100644 --- a/reg_tests/executeFASTFarmRegressionCase.py +++ b/reg_tests/executeFASTFarmRegressionCase.py @@ -69,9 +69,9 @@ verbose = args.verbose # file to use for comparison (ending not included) if args.compFile is None: - compFile = caseName + compFile = "FAST.Farm" elif args.compFile == 'arg_was_not_given': - compFile = caseName + compFile = "FAST.Farm" else: compFile = args.compFile From 80bb3af413e911f1b5a0ef9869ecc398f731dbe5 Mon Sep 17 00:00:00 2001 From: Mayank Chetan Date: Mon, 23 Dec 2024 14:35:48 -0700 Subject: [PATCH 148/161] updating docs and actions --- .github/workflows/deploy.yml | 41 +++++++++++++++++++++++++++-------- docs/source/install/index.rst | 22 ++++++++++++++----- openfast_io/README.md | 41 +++++++++++++++++++++++++++++------ openfast_io/pyproject.toml | 2 +- 4 files changed, 84 insertions(+), 22 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 3f426e2d4..87240dbce 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -13,9 +13,9 @@ on: jobs: - publish-to-test-pypi: + publish-to-pypi-test: runs-on: ubuntu-latest - + if: github.event_name == 'workflow_dispatch' steps: - uses: actions/checkout@v3 @@ -42,16 +42,39 @@ jobs: run: hatch publish -r test working-directory: openfast_io - # - name: Publish to PyPI - # env: - # HATCH_INDEX_USER: __token__ - # HATCH_INDEX_AUTH: ${{ secrets.PYPI_TOKEN }} - # run: hatch publish - # working-directory: openfast_io + publish-to-pypi: + runs-on: ubuntu-latest + if: github.event_name == 'release' + steps: + - uses: actions/checkout@v3 + + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: '3.12' + cache: 'pip' + + - name: Install Hatch + uses: pypa/hatch@install + + - name: Install dependencies + run: pip install keyring[file] + + - name: Build package + run: hatch build + working-directory: openfast_io + + - name: Publish to PyPI + env: + HATCH_INDEX_USER: __token__ + HATCH_INDEX_AUTH: ${{ secrets.PYPI_TOKEN }} + run: hatch publish + working-directory: openfast_io docker-build-and-push: runs-on: ubuntu-latest - timeout-minutes: 300 + if: github.event_name == 'release' + timeout-minutes: 500 env: DOCKERFILE_PATH: share/docker/Dockerfile DOCKERHUB_REPOSITORY: nrel/openfast diff --git a/docs/source/install/index.rst b/docs/source/install/index.rst index b394ed808..6bd5b81ab 100644 --- a/docs/source/install/index.rst +++ b/docs/source/install/index.rst @@ -217,17 +217,29 @@ You can also build your own custom images using our `Dockerfile` or base your im Install the ``openfast_io`` python wrapper ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The ``openfast_io`` python package is a wrapper comprising readers and writers for converting OpenFAST files to/from -python objects. You can install it with: +python objects. -.. code-block:: +To use `openfast_io` as a library for incorporation into other scripts or tools, it is available via (assuming that you have already setup your python environment): + +.. code-block:: bash pip install openfast_io -or +These instructions are for interaction directly with the `openfast_io` source code. + +1. Follow this step only if you have not cloned the OpenFAST repo: + +.. code-block:: bash + + git clone https://github.com/OpenFAST/OpenFAST.git + cd OpenFAST -.. code-block:: +2. Assuming you are within the OpenFAST directory: + +.. code-block:: bash - poetry add openfast_io + cd openfast_io + pip install -e . For more information and installation options, see the `OpenFAST Python readme `_. diff --git a/openfast_io/README.md b/openfast_io/README.md index 796c7a563..4d1d77dfd 100644 --- a/openfast_io/README.md +++ b/openfast_io/README.md @@ -4,21 +4,48 @@ This package is a python wrapper comprising readers and writers for converting O was originally written for [WEIS](https://github.com/WISDEM/WEIS/tree/77a878d7989b8c1d07d2244135ccd308a193a924/weis/aeroelasticse) and has been ported over to OpenFAST to make it more widely accessible. ## Installation -Run either +Installation with [Anaconda](https://www.anaconda.com) is the recommended approach because of the ability to create self-contained environments suitable for testing and analysis. + +### Installation as a "library" + +To use `openfast_io` as a library for incorporation into other scripts or tools, it is available via (assuming that you have already setup your python environment): + ```shell pip install openfast_io ``` -or -```shell -poetry add openfast_io -``` + +### Installation as an editable library + +These instructions are for interaction directly with the `openfast_io` source code. + +0. Follow this step only if you have not cloned the OpenFAST repo. + ```shell + git clone https://github.com/OpenFAST/OpenFAST.git + cd OpenFAST + ``` + +1. Assuming you are within the OpenFAST directory. + ```shell + cd openfast_io + pip install -e . + ``` + +2. To test `openfast_io`, OpenFAST must be compiled within the build folder, then run: + + ```shell + cd tests + pytest test_of_io_pytest.py + ``` ### Extra options [ROSCO](https://github.com/NREL/ROSCO) can be installed as an optional dependency. Run either ```shell pip install openfast_io[rosco] ``` -or + +## Development and testing +To contribute to the development of `openfast_io`, install additioal depemndancies using: + ```shell -poetry add -E rosco openfast_io +pip install -e ".[all]" ``` diff --git a/openfast_io/pyproject.toml b/openfast_io/pyproject.toml index 9261c67ed..0ceb04bbb 100644 --- a/openfast_io/pyproject.toml +++ b/openfast_io/pyproject.toml @@ -5,7 +5,7 @@ build-backend = "hatchling.build" [project] name = "openfast_io" # dynamic = ["version"] -version = "4.0.0.b1" +version = "4.0.0" description = "Readers and writers for OpenFAST files." license = {file = "../LICENSE"} authors = [ From 024e00e1521f208e8b8cdae20f2916d66adb9961 Mon Sep 17 00:00:00 2001 From: andrew-platt Date: Mon, 23 Dec 2024 15:31:02 -0700 Subject: [PATCH 149/161] Add release notes from v2.4 - v3.4.1 These were copied from the GitHub releases page. This will make it simpler to sort through what commits in the history for dev were in older releases and not part of the 4.0.0 release --- docs/changelogs/v2.4.0.md | 38 +++++++++++++++++++++ docs/changelogs/v2.5.0.md | 57 +++++++++++++++++++++++++++++++ docs/changelogs/v2.6.0.md | 30 +++++++++++++++++ docs/changelogs/v3.0.0.md | 67 +++++++++++++++++++++++++++++++++++++ docs/changelogs/v3.1.0.md | 66 ++++++++++++++++++++++++++++++++++++ docs/changelogs/v3.2.0.md | 60 +++++++++++++++++++++++++++++++++ docs/changelogs/v3.2.1.md | 9 +++++ docs/changelogs/v3.3.0.md | 48 +++++++++++++++++++++++++++ docs/changelogs/v3.4.0.md | 70 +++++++++++++++++++++++++++++++++++++++ docs/changelogs/v3.4.1.md | 11 ++++++ 10 files changed, 456 insertions(+) create mode 100644 docs/changelogs/v2.4.0.md create mode 100644 docs/changelogs/v2.5.0.md create mode 100644 docs/changelogs/v2.6.0.md create mode 100644 docs/changelogs/v3.0.0.md create mode 100644 docs/changelogs/v3.1.0.md create mode 100644 docs/changelogs/v3.2.0.md create mode 100644 docs/changelogs/v3.2.1.md create mode 100644 docs/changelogs/v3.3.0.md create mode 100644 docs/changelogs/v3.4.0.md create mode 100644 docs/changelogs/v3.4.1.md diff --git a/docs/changelogs/v2.4.0.md b/docs/changelogs/v2.4.0.md new file mode 100644 index 000000000..a273a8c3a --- /dev/null +++ b/docs/changelogs/v2.4.0.md @@ -0,0 +1,38 @@ +### General +- #428 Improve CLI for OpenFAST (`openfast -v` and `openfast -h`) +- #350 Add offshore linearization capability +- #488 Improve Line2-to-Line2 or Line2-to-Point mapping +- #508 Support RANLUX as an optional pRNG +- #373 Support for channel names up to 20 characters +- #373 Allow mode shape visualization - [docs](https://github.com/OpenFAST/matlab-toolbox#mode-shapes-visualization) +- #373 Find a periodic steady-state trim solution where linearization will be performed +- Update documentation +- Bug fixes + +### AeroDyn +- #477 Add free vortex wake module - [docs](https://openfast.readthedocs.io/en/master/source/user/aerodyn-olaf/index.html) +- #515 Add aeroacoustics module - [docs](https://openfast.readthedocs.io/en/master/source/user/aerodyn-aeroacoustics/index.html) +- #373 Allow channel outputs at every blade node - [docs](https://openfast.readthedocs.io/en/master/source/user/aerodyn/input.html#ad-nodal-outputs) + +### BeamDyn +- #373 Allow channel outputs at every blade node - [docs](https://openfast.readthedocs.io/en/master/source/user/beamdyn/input_files.html#bd-nodal-outputs) + +### ElastoDyn +- #453 Bug fix: the rotational speed was doubled in the rotational velocity field of the blade output mesh +- #461 Add output channel for translational displacements of tower top at yaw bearing relative to the reference position +- #373 Allow channel outputs at every blade node - [docs](https://openfast.readthedocs.io/en/master/source/user/elastodyn/input.html#ed-nodal-outputs) + +### ExtPtfm +- #344 Use Craig-Bampton reduction of support structures for sequential load calculations + +### InflowWind +- #437 Add new HAWC wind profile input type for reading wind conditions without mean wind speed +- #437 Allow to shift the HAWC wind upstream or downstream + +### ServoDyn +- #456 Properly support yaw rate command integration from controller +- #460 Fix an issue in updating the states when a yaw maneuver is beginning + +### r-test +- #456 Update 5MW BeamDyn blade damping models + diff --git a/docs/changelogs/v2.5.0.md b/docs/changelogs/v2.5.0.md new file mode 100644 index 000000000..0661a1b90 --- /dev/null +++ b/docs/changelogs/v2.5.0.md @@ -0,0 +1,57 @@ +### General +In v2.5.0, the `master` branch will become `main` and this will serve as the "trunk" or primary branch for OpenFAST. This is in line with current best practices in naming conventions (see [here](https://github.com/github/renaming)). + +### AeroDyn +- #538 Update AeroDyn to allow for linearized dynamic stall and dynamic inflow models +- #538 Disable BEM if TSR <= 1, blend BEM and non-BEM when 1 < TSR < 2, output the proportion of BEM in GeomPhi output channel +- #590 [BugFix] VTK folder location, Vx sign for OLAF +- #594 [BugFix] Close a file that was opened but not closed +- #623 [BugFix] Allocate array to size 0 before getting its size +- #627 [BugFix] Fix logic for setting size of arrays for airfoil tables + +### BeamDyn +- #560 Expand and improve BeamDyn unit tests +- #564 Documentation updates: Add BD OpenFAST solve section +- #576 Replace cubic spline with least squares fit +- #619 [BugFix] Regenerate Types files after registry file changes + +### FAST Library +- #550 Make channel length consistent between C and Fortran sides of interface +- #616 Fix potential memory leak and expand error handling + +### HydroDyn +- #582 Use RANLUX pRNG in offshore floating regression test cases +- #586 Hd Driver - Add Morrison mesh and standalone driver test cases +- #602 Vectorize a section of VariousWaves_Init (also #606) + +### InflowWind +- #578 InflowWind Updates (vertical flow angle, Bladed support, negetive height) +- #596 Add support for initializing InflowWind with string inputs + +### MoorDyn +- #565 Add active tensioning capabilities in MoorDyn +- #604 [BugFix] Fix position and tension node outputs +- #619 [BugFix] Regenerate Types files after registry file changes + +### NWTC Library +- #588 Add NWTC Library infrastructure for parsing inputs as strings +- #603 [BugFix] Fix order of variables declaration + +### Simulink +- #545 Support for GNU compiler on Linux systems +- #577 Updated examples for OpenFAST-Simulink Interface +- #616 Fix potential memory leak and add more error handling + +### Documentation +- #558 Refer to conda for installation ([docs](https://openfast.readthedocs.io/en/dev/source/install/index.html#download-binaries)) +- #559 Update unit test guidance ([docs](https://openfast.readthedocs.io/en/dev/source/testing/unit_test.html)) +- #614 [BugFix] Fix api_change.rst ([docs](https://openfast.readthedocs.io/en/dev/source/user/api_change.html)) + +### Build system +- #547 [BugFix] cmake configuration for Linux + Intel + Debug +- #583 CMake: set CMP0074 policy explicitly to avoid warnings +- #595 Disable gfortran stack-reuse compiler option +- #610 Prevent variable tracking in large Fortran modules + +### Testing +- #579 #599 #610 Improve GH Actions diff --git a/docs/changelogs/v2.6.0.md b/docs/changelogs/v2.6.0.md new file mode 100644 index 000000000..9eedaeb57 --- /dev/null +++ b/docs/changelogs/v2.6.0.md @@ -0,0 +1,30 @@ +This release includes the following major enhancements: +- Support for flexible floating platforms and expansion of linearization capability (#537) + +### AeroDyn +#645 Add Eames tower shadow model to AD15 +#643 Support primary input file parsing through strings + +### BeamDyn +#615 [BugFix] Initialized error variables +#636 Add unit tests for BD_ComputeIniNodalCrv + +### HydroDyn +#537 Flexible floating platforms +#615 Morison performance improvement +#634 Fix HydroDyn linearization matrix multiplication using unallocated arrays + +### InflowWind +#642 [BugFix] Reenable InflowWind echo file lost in #596 + +### NWTC Library +#615 NWTC Lib bug fixes + +### Simulink Interface +#641 [BugFix] Simulink error message overwrite + +### Testing +#637 Use default runner and GFortran 10 +#635 Use Intel 2021 Toolset for regression test + + diff --git a/docs/changelogs/v3.0.0.md b/docs/changelogs/v3.0.0.md new file mode 100644 index 000000000..de79528b8 --- /dev/null +++ b/docs/changelogs/v3.0.0.md @@ -0,0 +1,67 @@ +This release includes the following major enhancements: +- FAST.Farm (#584) +- ServoDyn structural control submodule (#607) + +### AeroDyn +#597 AD/AA: Add new TE definition, improve airfoil thickness calculation, simplify input +#647 Add ability to turn unsteady aero back on during a simulation +#648 OLAF improvements for WEIS +#672 Preliminary support for multiple rotors in AeroDyn +#728 AllBldOuts more forgiving and support for 0 + +### BeamDyn +#677 BD Driver bug fix and expand BeamDyn unit testing + +### ElastoDyn +#589 Allow one-blade turbine model +#653 Add YawBrTV[xyz]p output channels +#736 AllBldOuts more forgiving and support for 0 + +### FAST.Farm +#584 Incorporate FAST.Farm to OpenFAST +#726 Build FAST.Farm when configured via BUILD_FASTFARM +#749 Add Missing Attribute for sc_end in the FAST.Farm Super Controller + +### HydroDyn +#687 [BugFix] incorrect pitch/roll moments on tapered elements crossing water line +#713 [BugFix] Uninitialized variables in HydroDyn::Morisson calculations + +### NWTC Library +#668 [BugFix] Sys files for MATLAB +#683 Big fix in NWTC Library unit tests + +### OpenFAST Library +#744 Avoid gfortran 11 error in FAST_Solver.f90 + +### ServoDyn +#607 ServoDyn Structural control submodule (formerly TMD) +#690 [BugFix] Rename Structural Control driver program +#739 [BugFix] Logic error in glue code for StC loads on SD with no HD + +### Documentation +#678 Add documentation on input file parsing +#682 Update installation instructions +#696 Update the api_change for MoorDyn after PR #565 + +### C++ Inteface +#703 [BugFix] unallocated AD%y%Rotors when AD14 is used with cpp interface +#709 Remove unused import to C++ driver code + +### Simulink interface +#702 [BugFix] Correct the expected format of the output channel names array + +### Build systems +#698 Configure runtime path linking when using shared libraries +#706 Automate incrementing the dev-label conda build +#725 Updated linking dependencies for newer version of Visual Studio +#727 Update rules for Intel OneAPI compiler detection + +### Testing +#670 Enable regression tests for the C++ API +#686 Bug fix for regression tests without C++ API enabled +#689 Enable types generation in CI +#691 Add SubDyn and AeroDyn drivers regression tests to github action +#717 GH Actions: run module tests with debug build +#718 [BugFix] Raise an error if reg test results contain NaN or infinity +#741 CTest: Add FF reg tests when FF build is enabled + diff --git a/docs/changelogs/v3.1.0.md b/docs/changelogs/v3.1.0.md new file mode 100644 index 000000000..1b97e1696 --- /dev/null +++ b/docs/changelogs/v3.1.0.md @@ -0,0 +1,66 @@ +# Release Notes + +### General +#707 Add environmental variables to driver input files +#734 OpenFAST Registry algorithm change: simplify USE statements +Others (#826, #835, #836, #911, #918, #971, #1019) + +### AeroDyn +#688 AeroDyn driver update for multiple wind turbines, with arbitrary motions and geometries +#729 New features for unsteady aerodynamics modeling +#834 Fix AD Driver unallocated variable error with GCC 11 +#863 AeroDyn cleanup +#917 AD15: add nodal outputs for VUnd{xyz}i in global coords +#919 Segment treecode +#920 Update in Computing Default Unsteady Airfoil Coefficients +#922 [BugFix] Minor bugfix in AirfoilInfo +#982 [BugFix] AD15 nacelle reference position was set to hub position +#1001 Remove conditional statement for initialization of BEMT variable +#1009 [BugFix] Nacelle position set inconsistently by glue code and AeroDyn driver + +### BeamDyn +#996 [BugFix] BeamDyn nodal outputs occasionally segfaulted + +### FAST Farm +#839 Fix Bug in FAST.Farm Causing Wake Bounce-Back +#860 Fix some memory leaks in FAST.Farm +#895 [BugFix] incorrect init of aggregated output index arrays in FAST.Farm +#923 [BugFix] error handling in AWAE module + +### HydroDyn +#756 HydroDyn primary input file passing and parsing +#831 HydroDyn Input/Output meshes: change from SWL to MSL for consistency with OF glue code +#838 [BugFix] segmentation fault in HD linearization +#915 [BugFix] Incorrect reference frame used in HD for WAMIT/WAMIT2 +#998 Fix HydroDyn summary file nodal data is incorrect when Member is flipped + +### InflowWind +#720 inflowWind C-bound interface and python wrapper +#769 Fix issue with interpolation that could cause a segmentation fault +#929 Fix issue with uninitialized variables in InflowWind's Direct Scaling method + +### NWTC Library +#1002 Increase line length in FileInfo parsing methods + +### OpenFAST Library +#716 [BugFix] Fix C++ API for restart, Error handling in FAST Library, and AeroDyn echo file lock +#958 Lin: CalcSteady, forcing linearization at end of simulation + +### ServoDyn +#664 Extended Bladed DLL interface, improved summary file including DLL channel usage, and cable controls for MD and SD +#902 Fixes for Intel in debug mode +#930 Stop OpenFAST for Simulink simulation when trim solution has been found + +### SubDyn +#859 Various improvements to SubDyn + +### Documentation +#740 Guidelines for performance considerations with Fortran +#753 Migrate the HydroDyn Manual to readthedocs +#805 Include legacy documentation in pdf and MS Word format - General & ElastoDyn +#828 Add instructions for adding new regression test cases +#858 Documentation for ExtPtfm +#951 Corrected the description of SkewModFactor in Documentation +#1020 Document AD outputs + + diff --git a/docs/changelogs/v3.2.0.md b/docs/changelogs/v3.2.0.md new file mode 100644 index 000000000..9866c1ff1 --- /dev/null +++ b/docs/changelogs/v3.2.0.md @@ -0,0 +1,60 @@ +# Release Notes + +### General +#866 Include legacy documentation in pdf and MS Word format - Modules +#1021 Reg_tests python scripts: fix issue where directory returned is empty +#1062 Add documentation for community contribution +#1169 Update git-module urls +#1158 Update orientation differences in linear trim solution +#1177 Add documentation on 3D rotations in linearization +#1178 Corrections for 3.2.0 release + +### AeroDyn +#932 BugFix: UA update states that were not updated +#1032 AD: added more nodal outputs for debugging UA +#1039 [BugFix] Nacelle motion not passed between AeroDyn driver and AeroDyn +#1043 AeroDyn: combine some FVW and BEMT output calculations +#1045 OLAF: check for division by zero to avoid invalid calculations +#1141 Move AD module reg tests to a standalone job + +### BeamDyn +#1050 Fix aeroelastic stability analysis with BeamDyn + +### FAST.Farm +#1107 Fix Time-Step Delay in Super Controller within FAST.Farm + +### HydroDyn +#806 C-bindings interface for HydroDyn +#1047 Fix HydroDyn Jacobian outputs when LinOutJac is True +#1108 BugFix: Checks to populate matrix input to Newman's app were reversed +#1173 Bug Fix: rotation matrix perturbation with small angles was wrong + +### InflowWind +#1144 BugFix: Fix typo in DLLEXPORT attributes for IfW C interface + +### MAP++ +#1048 MAP: small fix based on MAP 1.3 +#1168 Fix MAP linearization operating point + +### NWTC Library +#1050 Fix aeroelastic stability analysis with BeamDyn -- changes to the library routines for angle perturbations during linearization +#1124 Updates to VersionInfo module and its dependencies +#1157 Fix for binary file compression + +### OpenFAST Library +#962 Add a Python glue-code interface +#1057 FAST Library: add access to hub position and velocity + +### ServoDyn +#803 Linearization of ServoDyn Structural control elements +#1074 [BugFix] ServoDyn StC control signal channels were not zeroed properly +#1089 BugFix: Fix API change line numbers +#1101 BugFix: ServoDyn API change docs +#1140 Add non-rotating hub forces to Bladed Interface +#1160 Correction to documentation on Extended Bladed DLL interface + +### TurbSim +#887 TurbSim modifications + + + diff --git a/docs/changelogs/v3.2.1.md b/docs/changelogs/v3.2.1.md new file mode 100644 index 000000000..ad926bb6e --- /dev/null +++ b/docs/changelogs/v3.2.1.md @@ -0,0 +1,9 @@ +# Release Notes + +This release contains the following bug fixes: + +#1201 Include stdexcept in FastLibAPI driver +#1180 Add conditional compile for C++ / C definitions in OpenFAST Library +Revert #1169 Update git-module urls + + diff --git a/docs/changelogs/v3.3.0.md b/docs/changelogs/v3.3.0.md new file mode 100644 index 000000000..5f9daf90e --- /dev/null +++ b/docs/changelogs/v3.3.0.md @@ -0,0 +1,48 @@ +# Release Notes + +### General +#1183 Fix bugs and issues in the online documentation +#1248 OpenFAST Registry: allow pointers + +### AeroDyn +#1000 Updates of Unsteady Aero (UAMod=4) and DBEMT (DBEMT_Mod=3) for linearization +#1037 Bug fix: BEMT was disabled for negative inflow +#1042 AD: merge more of `TwrInfl` and `TwrInflArray` routines +#1061 Fix AeroDyn WriteOutput linearization (and cleanup some code) +#1078 Enable cavitation calculation and outputs using FVW +#1188 AD15 driver: add visualization option for line meshes in addition to surfaces +#1239 AeroAcoustics: fix BL-thickness for heavily-tripped airfoil + +### HydroDyn +#999 Fix HD added mass on member end (Close #992) +#1230 HD: increase max length of line read from kinematics files + +### MoorDyn +#1086 MoorDyn v2 + shared moorings + wave propagation in FAST.Farm + +### MAP++ +#1186 MAP: allow keyword `fixed` and `fix` + +### NWTC Library +#1254 NWTC Library and WriteOutput updates + +### Build System +#1198 Option to disable variable tracking with GNU compiler +#1228 r-test: Remove -m64 in CMAKE_Fortran_FLAG from r-test + +### Testing System +#1203 Add parallel branches to GitHub Actions +#1217 Consolidate regression test baseline set +#1222 Improvements to regression test python scripts +#1244 Reg-test scripts modification to help avoid race condition and cleanup of caselist +#1264 GitHub Workflow: adding build-all-debug-single to check type errors + +### C++ API +#1176 Simulink: add documentation of inputs to FAST_Library.h +#1211 Use dt_out when storing OpenFAST outputs in Python interface +#1227 Seg Fault due to hub model and external inflow + +### Linearization +#1199 Small improvements for -VTKLin visualization outputs + + diff --git a/docs/changelogs/v3.4.0.md b/docs/changelogs/v3.4.0.md new file mode 100644 index 000000000..014942180 --- /dev/null +++ b/docs/changelogs/v3.4.0.md @@ -0,0 +1,70 @@ +# Release Notes + +OpenFAST v3.4.0 includes several major new features and bug fixes. New features include a new curled-wake model in FAST.Farm (#931), buoyancy calculations in AeroDyn 15 for MHK turbines (#957), rotor and tail furling (#1277), and new library interfaces for AeroDyn 15 and MoorDyn to couple with other codes (#1110 & #848). One major bug fix is changing the CFD coupling to use only the AeroDyn 15 mesh information -- this had led to some discrepancies in CFD results (#1324). + +The full set of changes included in this version are further documented in the following listed pull requests. + + +### General +#889 Add a super-controller library target to CMake +#1303 Small reorganization and clean up FAST.Farm r-test input files, upload of artifact +#1311 NWTC_IO: nullifying DLL (on restart) if not present when packing +#1318 Allow Registry to generate extrap/interp routines for types without module nickname +#1327 add version info to c-binding libraries +#1332 Documentation fixes +#1357 CI: exclude bokeh 3.0.[0-3] -- broken plots +#1376 Add `regression_tests` to the ALL target. + +### Documentation +#1267 OLAF: documentation: updated guidelines and using nFWPanels instead of WakeLength +#1406 Update example InflowWind and FAST.Farm input files + +### Visualization +#1319 Cleanup OpenFAST VTK output for HydroDyn +#1321 Add safety checks to VTK output +#1330 VTKLin: being more forgiving with number of modes +#1333 NWTC_Lib: Adding Yaml and VTK to library (moved from SD and AD) + +### FAST.Farm +#931 Implementation of the curled-wake model in FAST.Farm +#1263 FAST.Farm WriteOutput: fix for Windows Intel OMP build +#1304 API changes for future curl wake implementation, WD restructuring (Cq, OMP, skew filt) +#1305 FF: Cartesian grid for AWAE and WD outputs +#1310 FF: additional OpenMP parallelizations in FAST.Farm +#1328 FF: update of guidelines for Curled wake dr and DT_low + +### OpenFAST +#1275 Linear Trim Solution Improvements (Linearization) + +### AeroDyn +#957 Calculate buoyancy for an MHK turbine +#1110 New AeroDynInflow module with c-bindings interface +#1276 Bug Fix: OLAF: particles are NaN when vortex segments have zero length +#1277 Reactivating rotor furling and tailfin aerodynamics (ElastoDyn also) +#1283 Add new projection method and BEM methods +#1293 Minor error handling and code cleanup (OLAF) +#1317 Fix for Visual Studio builds with ADI +#1347 AeroDyn/UnsteadyAero_Driver: Fix for bug #1346 +#1355 OLAF: Adding free near wake panels +#1356 AeroDyn/UnsteadyAero_Driver: Fix for bug #1346 +#1369 UA: adding UA_Driver outputs, fix separation function for UAMod=6, and adding r-tests + +### BeamDyn +#1335 BeamDyn: output summary file in yaml format + +### InflowWind +#1240 Improvements to the InflowWind disk averaged velocity calculations +#1266 Temporarily removing InflowWind parallelization + +### MoorDyn +#848 MoorDyn v2 C-bindings interface +#1371 MoorDyn bending bugfix and message updates for v2 + +### OpenFOAM +#1324 CFD coupling to use AD15 mesh only +#1365 OpFM: [bugfix] test for warning condition was broken +#1372 [BugFix] the DEBUG_OPENFOAM preprocessor directive was never updated for multiple AD15 rotors + +### TurbSim +#1361 TurbSim: User-defined time series updates + diff --git a/docs/changelogs/v3.4.1.md b/docs/changelogs/v3.4.1.md new file mode 100644 index 000000000..7bfeb1a94 --- /dev/null +++ b/docs/changelogs/v3.4.1.md @@ -0,0 +1,11 @@ +# Release Notes + +OpenFAST 3.4.1 is a minor release to revert a channel name change in AeroDyn 15. This also contains minor fixes for documentation builds. + +### Documentation +#1442 `[BugFix] Doxygen builds failing on rtd, and locally. Documentation builds on readthedocs and local were failing due to a change in the backend of sphinx. This fixes local builds, but does not fix readthedocs builds. As a temporary workaround, doxygen is disabled on readthedocs. + +### AeroDyn15 +#1428 AD15: revert to Aero names for output channels (Fld is now an alias). This fixes an issue introduced in v3.4.0 (#957) + + From cc4ba09e9b078ad18798d254a0eec2ca6d3c9d18 Mon Sep 17 00:00:00 2001 From: Mayank Chetan Date: Mon, 23 Dec 2024 22:53:38 -0700 Subject: [PATCH 150/161] matching comments to r-test dev --- openfast_io/openfast_io/FAST_reader.py | 28 ++-- openfast_io/openfast_io/FAST_writer.py | 204 +++++++++++++------------ openfast_io/openfast_io/FileTools.py | 2 +- 3 files changed, 123 insertions(+), 111 deletions(-) diff --git a/openfast_io/openfast_io/FAST_reader.py b/openfast_io/openfast_io/FAST_reader.py index cf3742683..72bf38087 100644 --- a/openfast_io/openfast_io/FAST_reader.py +++ b/openfast_io/openfast_io/FAST_reader.py @@ -181,10 +181,8 @@ def __init__(self): self.fst_vt['ElastoDynTower'] = {} self.fst_vt['InflowWind'] = {} self.fst_vt['AeroDyn'] = {} - self.fst_vt['AeroDyn14'] = {} self.fst_vt['AeroDisk'] = {} self.fst_vt['AeroDynBlade'] = {} - self.fst_vt['AeroDynTower'] = {} self.fst_vt['AeroDynPolar'] = {} self.fst_vt['ServoDyn'] = {} self.fst_vt['DISCON_in'] = {} @@ -290,7 +288,7 @@ def read_MainInput(self): self.fst_vt['Fst']['CompInflow'] = int(f.readline().split()[0]) self.fst_vt['Fst']['CompAero'] = int(f.readline().split()[0]) self.fst_vt['Fst']['CompServo'] = int(f.readline().split()[0]) - self.fst_vt['Fst']['CompSeaState'] = int(f.readline().split()[0]) + self.fst_vt['Fst']['CompSeaSt'] = int(f.readline().split()[0]) self.fst_vt['Fst']['CompHydro'] = int(f.readline().split()[0]) self.fst_vt['Fst']['CompSub'] = int(f.readline().split()[0]) self.fst_vt['Fst']['CompMooring'] = int(f.readline().split()[0]) @@ -318,7 +316,7 @@ def read_MainInput(self): self.fst_vt['Fst']['InflowFile'] = quoted_read(f.readline().split()[0]) self.fst_vt['Fst']['AeroFile'] = quoted_read(f.readline().split()[0]) self.fst_vt['Fst']['ServoFile'] = quoted_read(f.readline().split()[0]) - self.fst_vt['Fst']['SeaStateFile'] = quoted_read(f.readline().split()[0]) + self.fst_vt['Fst']['SeaStFile'] = quoted_read(f.readline().split()[0]) self.fst_vt['Fst']['HydroFile'] = quoted_read(f.readline().split()[0]) self.fst_vt['Fst']['SubFile'] = quoted_read(f.readline().split()[0]) self.fst_vt['Fst']['MooringFile'] = quoted_read(f.readline().split()[0]) @@ -940,11 +938,11 @@ def read_InflowWind(self): f.readline() self.fst_vt['InflowWind']['HWindSpeed'] = float_read(f.readline().split()[0]) self.fst_vt['InflowWind']['RefHt'] = float_read(f.readline().split()[0]) - self.fst_vt['InflowWind']['PLexp'] = float_read(f.readline().split()[0]) + self.fst_vt['InflowWind']['PLExp'] = float_read(f.readline().split()[0]) # Parameters for Uniform wind file [used only for WindType = 2] (uniform_wind_params) f.readline() - self.fst_vt['InflowWind']['Filename_Uni'] = os.path.join(os.path.split(inflow_file)[0], quoted_read(f.readline().split()[0])) + self.fst_vt['InflowWind']['FileName_Uni'] = os.path.join(os.path.split(inflow_file)[0], quoted_read(f.readline().split()[0])) self.fst_vt['InflowWind']['RefHt_Uni'] = float_read(f.readline().split()[0]) self.fst_vt['InflowWind']['RefLength'] = float_read(f.readline().split()[0]) @@ -953,7 +951,7 @@ def read_InflowWind(self): self.fst_vt['InflowWind']['FileName_BTS'] = os.path.join(os.path.split(inflow_file)[0], quoted_read(f.readline().split()[0])) # Parameters for Binary Bladed-style Full-Field files [used only for WindType = 4] (bladed_wind_params) f.readline() - self.fst_vt['InflowWind']['FilenameRoot'] = os.path.join(os.path.split(inflow_file)[0], quoted_read(f.readline().split()[0])) + self.fst_vt['InflowWind']['FileNameRoot'] = os.path.join(os.path.split(inflow_file)[0], quoted_read(f.readline().split()[0])) self.fst_vt['InflowWind']['TowerFile'] = bool_read(f.readline().split()[0]) # Parameters for HAWC-format binary files [Only used with WindType = 5] (hawc_wind_params) @@ -1250,6 +1248,9 @@ def read_AeroDynBlade(self): self.fst_vt['AeroDynBlade']['BlTwist'] = [None]*self.fst_vt['AeroDynBlade']['NumBlNds'] self.fst_vt['AeroDynBlade']['BlChord'] = [None]*self.fst_vt['AeroDynBlade']['NumBlNds'] self.fst_vt['AeroDynBlade']['BlAFID'] = [None]*self.fst_vt['AeroDynBlade']['NumBlNds'] + self.fst_vt['AeroDynBlade']['BlCb'] = [None]*self.fst_vt['AeroDynBlade']['NumBlNds'] + self.fst_vt['AeroDynBlade']['BlCenBn'] = [None]*self.fst_vt['AeroDynBlade']['NumBlNds'] + self.fst_vt['AeroDynBlade']['BlCenBt'] = [None]*self.fst_vt['AeroDynBlade']['NumBlNds'] for i in range(self.fst_vt['AeroDynBlade']['NumBlNds']): data = [float(val) for val in f.readline().split()] self.fst_vt['AeroDynBlade']['BlSpn'][i] = data[0] @@ -1259,6 +1260,15 @@ def read_AeroDynBlade(self): self.fst_vt['AeroDynBlade']['BlTwist'][i] = data[4] self.fst_vt['AeroDynBlade']['BlChord'][i] = data[5] self.fst_vt['AeroDynBlade']['BlAFID'][i] = data[6] + if len(data) == 9: + self.fst_vt['AeroDynBlade']['BlCb'][i] = data[7] + self.fst_vt['AeroDynBlade']['BlCenBn'][i] = data[8] + self.fst_vt['AeroDynBlade']['BlCenBt'][i] = data[9] + else: + self.fst_vt['AeroDynBlade']['BlCb'][i] = 0.0 + self.fst_vt['AeroDynBlade']['BlCenBn'][i] = 0.0 + self.fst_vt['AeroDynBlade']['BlCenBt'][i] = 0.0 + f.close() @@ -1289,7 +1299,7 @@ def read_AeroDynPolar(self): for tab in range(polar['NumTabs']): # For multiple tables polar['Re'] = float_read(readline_filterComments(f).split()[0]) * 1.e+6 - polar['Ctrl'] = int_read(readline_filterComments(f).split()[0]) + polar['UserProp'] = int_read(readline_filterComments(f).split()[0]) polar['InclUAdata'] = bool_read(readline_filterComments(f).split()[0]) # Unsteady Aero Data @@ -3161,7 +3171,7 @@ def execute(self): hd_file = os.path.normpath(os.path.join(self.FAST_directory, self.fst_vt['Fst']['HydroFile'])) if os.path.isfile(hd_file): self.read_HydroDyn(hd_file) - ss_file = os.path.normpath(os.path.join(self.FAST_directory, self.fst_vt['Fst']['SeaStateFile'])) + ss_file = os.path.normpath(os.path.join(self.FAST_directory, self.fst_vt['Fst']['SeaStFile'])) if os.path.isfile(ss_file): self.read_SeaState(ss_file) sd_file = os.path.normpath(os.path.join(self.FAST_directory, self.fst_vt['Fst']['SubFile'])) diff --git a/openfast_io/openfast_io/FAST_writer.py b/openfast_io/openfast_io/FAST_writer.py index 582dddfec..e993752f1 100644 --- a/openfast_io/openfast_io/FAST_writer.py +++ b/openfast_io/openfast_io/FAST_writer.py @@ -216,7 +216,7 @@ def execute(self): if self.fst_vt['Fst']['CompHydro'] == 1: self.write_HydroDyn() - if self.fst_vt['Fst']['CompSeaState'] == 1: + if self.fst_vt['Fst']['CompSeaSt'] == 1: self.write_SeaState() if self.fst_vt['Fst']['CompSub'] == 1: self.write_SubDyn() @@ -260,7 +260,7 @@ def write_MainInput(self): f.write('{:<22} {:<11} {:}'.format(self.fst_vt['Fst']['CompInflow'], 'CompInflow', '- Compute inflow wind velocities (switch) {0=still air; 1=InflowWind; 2=external from ExtInflow}\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['Fst']['CompAero'], 'CompAero', '- Compute aerodynamic loads (switch) {0=None; 1=AeroDisk; 2=AeroDyn; 3=ExtLoads}\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['Fst']['CompServo'], 'CompServo', '- Compute control and electrical-drive dynamics (switch) {0=None; 1=ServoDyn}\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['Fst']['CompSeaState'], 'CompSeaState', '- Compute sea state information (switch) {0=None; 1=SeaState}\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['Fst']['CompSeaSt'], 'CompSeaSt', '- Compute sea state information (switch) {0=None; 1=SeaState}\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['Fst']['CompHydro'], 'CompHydro', '- Compute hydrodynamic loads (switch) {0=None; 1=HydroDyn}\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['Fst']['CompSub'], 'CompSub', '- Compute sub-structural dynamics (switch) {0=None; 1=SubDyn; 2=External Platform MCKF}\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['Fst']['CompMooring'], 'CompMooring', '- Compute mooring system (switch) {0=None; 1=MAP++; 2=FEAMooring; 3=MoorDyn; 4=OrcaFlex}\n')) @@ -284,7 +284,7 @@ def write_MainInput(self): f.write('{:<22} {:<11} {:}'.format('"'+self.fst_vt['Fst']['InflowFile']+'"', 'InflowFile', '- Name of file containing inflow wind input parameters (quoted string)\n')) f.write('{:<22} {:<11} {:}'.format('"'+self.fst_vt['Fst']['AeroFile']+'"', 'AeroFile', '- Name of file containing aerodynamic input parameters (quoted string)\n')) f.write('{:<22} {:<11} {:}'.format('"'+self.fst_vt['Fst']['ServoFile']+'"', 'ServoFile', '- Name of file containing control and electrical-drive input parameters (quoted string)\n')) - f.write('{:<22} {:<11} {:}'.format('"'+self.fst_vt['Fst']['SeaStateFile']+'"', 'SeaStateFile', '- Name of file containing sea state input parameters (quoted string)\n')) + f.write('{:<22} {:<11} {:}'.format('"'+self.fst_vt['Fst']['SeaStFile']+'"', 'SeaStFile', '- Name of file containing sea state input parameters (quoted string)\n')) f.write('{:<22} {:<11} {:}'.format('"'+self.fst_vt['Fst']['HydroFile']+'"', 'HydroFile', '- Name of file containing hydrodynamic input parameters (quoted string)\n')) f.write('{:<22} {:<11} {:}'.format('"'+self.fst_vt['Fst']['SubFile']+'"', 'SubFile', '- Name of file containing sub-structural input parameters (quoted string)\n')) f.write('{:<22} {:<11} {:}'.format('"'+self.fst_vt['Fst']['MooringFile']+'"', 'MooringFile', '- Name of file containing mooring system input parameters (quoted string)\n')) @@ -393,12 +393,12 @@ def write_ElastoDyn(self): f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDyn']['NcIMUyn'], 'NcIMUyn', '- Lateral distance from the tower-top to the nacelle IMU (meters)\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDyn']['NcIMUzn'], 'NcIMUzn', '- Vertical distance from the tower-top to the nacelle IMU (meters)\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDyn']['Twr2Shft'], 'Twr2Shft', '- Vertical distance from the tower-top to the rotor shaft (meters)\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDyn']['TowerHt'], 'TowerHt', '- Height of tower above ground level [onshore] or MSL [offshore] (meters)\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDyn']['TowerBsHt'], 'TowerBsHt', '- Height of tower base above ground level [onshore] or MSL [offshore] (meters)\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDyn']['PtfmCMxt'], 'PtfmCMxt', '- Downwind distance from the ground level [onshore] or MSL [offshore] to the platform CM (meters)\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDyn']['PtfmCMyt'], 'PtfmCMyt', '- Lateral distance from the ground level [onshore] or MSL [offshore] to the platform CM (meters)\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDyn']['PtfmCMzt'], 'PtfmCMzt', '- Vertical distance from the ground level [onshore] or MSL [offshore] to the platform CM (meters)\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDyn']['PtfmRefzt'], 'PtfmRefzt', '- Vertical distance from the ground level [onshore] or MSL [offshore] to the platform reference point (meters)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDyn']['TowerHt'], 'TowerHt', '- Height of tower relative to ground level [onshore], MSL [offshore wind or floating MHK], or seabed [fixed MHK] (meters)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDyn']['TowerBsHt'], 'TowerBsHt', '- Height of tower base relative to ground level [onshore], MSL [offshore wind or floating MHK], or seabed [fixed MHK] (meters)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDyn']['PtfmCMxt'], 'PtfmCMxt', '- Downwind distance from the ground level [onshore], MSL [offshore wind or floating MHK], or seabed [fixed MHK] to the platform CM (meters)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDyn']['PtfmCMyt'], 'PtfmCMyt', '- Lateral distance from the ground level [onshore], MSL [offshore wind or floating MHK], or seabed [fixed MHK] to the platform CM (meters)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDyn']['PtfmCMzt'], 'PtfmCMzt', '- Vertical distance from the ground level [onshore], MSL [offshore wind or floating MHK], or seabed [fixed MHK] to the platform CM (meters)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDyn']['PtfmRefzt'], 'PtfmRefzt', '- Vertical distance from the ground level [onshore], MSL [offshore wind or floating MHK], or seabed [fixed MHK] to the platform reference point (meters)\n')) f.write('---------------------- MASS AND INERTIA ----------------------------------------\n') f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDyn']['TipMass(1)'], 'TipMass(1)', '- Tip-brake mass, blade 1 (kg)\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDyn']['TipMass(2)'], 'TipMass(2)', '- Tip-brake mass, blade 2 (kg)\n')) @@ -418,9 +418,9 @@ def write_ElastoDyn(self): f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDyn']['PtfmXZIner'], 'PtfmXZIner', '- Platform xz moment of inertia about the platform CM (=-int(xzdm)) (kg m^2)\n')) f.write('---------------------- BLADE ---------------------------------------------------\n') f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDyn']['BldNodes'], 'BldNodes', '- Number of blade nodes (per blade) used for analysis (-)\n')) - f.write('{:<22} {:<11} {:}'.format('"'+self.fst_vt['ElastoDyn']['BldFile1']+'"', 'BldFile1', '- Name of file containing properties for blade 1 (quoted string)\n')) - f.write('{:<22} {:<11} {:}'.format('"'+self.fst_vt['ElastoDyn']['BldFile2']+'"', 'BldFile2', '- Name of file containing properties for blade 2 (quoted string)\n')) - f.write('{:<22} {:<11} {:}'.format('"'+self.fst_vt['ElastoDyn']['BldFile3']+'"', 'BldFile3', '- Name of file containing properties for blade 3 (quoted string) [unused for 2 blades]\n')) + f.write('{:<22} {:<11} {:}'.format('"'+self.fst_vt['ElastoDyn']['BldFile1']+'"', 'BldFile(1)', '- Name of file containing properties for blade 1 (quoted string)\n')) + f.write('{:<22} {:<11} {:}'.format('"'+self.fst_vt['ElastoDyn']['BldFile2']+'"', 'BldFile(2)', '- Name of file containing properties for blade 2 (quoted string)\n')) + f.write('{:<22} {:<11} {:}'.format('"'+self.fst_vt['ElastoDyn']['BldFile3']+'"', 'BldFile(3)', '- Name of file containing properties for blade 3 (quoted string) [unused for 2 blades]\n')) f.write('---------------------- ROTOR-TEETER --------------------------------------------\n') f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDyn']['TeetMod'], 'TeetMod', '- Rotor-teeter spring/damper model {0: none, 1: standard, 2: user-defined from routine UserTeet} (switch) [unused for 3 blades]\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDyn']['TeetDmpP'], 'TeetDmpP', '- Rotor-teeter damper position (degrees) [used only for 2 blades and when TeetMod=1]\n')) @@ -477,11 +477,11 @@ def write_ElastoDyn(self): for i in range(len(channel_list)): f.write('"' + channel_list[i] + '"\n') - f.write('END of input file (the word "END" must appear in the first 3 columns of this last OutList line)\n') + f.write('END of OutList section (the word "END" must appear in the first 3 columns of the last OutList line)\n') # Optional nodal output section if 'BldNd_BladesOut' in self.fst_vt['ElastoDyn']: - f.write('====== Outputs for all blade stations (same ending as above for B1N1.... =========================== [optional section]\n') + f.write('====== Outputs for all blade stations (same ending as above for Spn1.... =========================== [optional section]\n') f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['ElastoDyn']['BldNd_BladesOut'], 'BldNd_BladesOut', '- Number of blades to output all node information at. Up to number of blades on turbine. (-)\n')) f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['ElastoDyn']['BldNd_BlOutNd'], 'BldNd_BlOutNd', '- Future feature will allow selecting a portion of the nodes to output. Not implemented yet. (-)\n')) f.write(' OutList - The next line(s) contains a list of output parameters. See OutListParameters.xlsx, ElastoDyn_Nodes tab for a listing of available output channels, (-)\n') @@ -490,7 +490,7 @@ def write_ElastoDyn(self): for opt_channel_list in opt_outlist: for i in range(len(opt_channel_list)): f.write('"' + opt_channel_list[i] + '"\n') - f.write('END of input file (the word "END" must appear in the first 3 columns of this last OutList line)\n') + f.write('END (the word "END" must appear in the first 3 columns of this last OutList line in the optional nodal output section)\n') f.write('---------------------------------------------------------------------------------------\n') f.flush() @@ -541,7 +541,7 @@ def write_SimpleElastoDyn(self): for i in range(len(channel_list)): f.write('"' + channel_list[i] + '"\n') - f.write('END of input file (the word "END" must appear in the first 3 columns of this last OutList line)\n') + f.write('END of input file (the word "END" must appear in the first 3 columns of the last OutList line)\n') f.write('---------------------------------------------------------------------------------------\n') f.flush() @@ -560,12 +560,12 @@ def write_ElastoDynBlade(self): f.write('Generated with OpenFAST_IO\n') f.write('---------------------- BLADE PARAMETERS ----------------------------------------\n') f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynBlade']['NBlInpSt'], 'NBlInpSt', '- Number of blade input stations (-)\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynBlade']['BldFlDmp1'], 'BldFlDmp1', '- Blade flap mode #1 structural damping in percent of critical (%)\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynBlade']['BldFlDmp2'], 'BldFlDmp2', '- Blade flap mode #2 structural damping in percent of critical (%)\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynBlade']['BldEdDmp1'], 'BldEdDmp1', '- Blade edge mode #1 structural damping in percent of critical (%)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynBlade']['BldFlDmp1'], 'BldFlDmp(1)', '- Blade flap mode #1 structural damping in percent of critical (%)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynBlade']['BldFlDmp2'], 'BldFlDmp(2)', '- Blade flap mode #2 structural damping in percent of critical (%)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynBlade']['BldEdDmp1'], 'BldEdDmp(1)', '- Blade edge mode #1 structural damping in percent of critical (%)\n')) f.write('---------------------- BLADE ADJUSTMENT FACTORS --------------------------------\n') - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynBlade']['FlStTunr1'], 'FlStTunr1', '- Blade flapwise modal stiffness tuner, 1st mode (-)\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynBlade']['FlStTunr2'], 'FlStTunr2', '- Blade flapwise modal stiffness tuner, 2nd mode (-)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynBlade']['FlStTunr1'], 'FlStTunr(1)', '- Blade flapwise modal stiffness tuner, 1st mode (-)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynBlade']['FlStTunr2'], 'FlStTunr(2)', '- Blade flapwise modal stiffness tuner, 2nd mode (-)\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynBlade']['AdjBlMs'], 'AdjBlMs', '- Factor to adjust blade mass density (-)\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynBlade']['AdjFlSt'], 'AdjFlSt', '- Factor to adjust blade flap stiffness (-)\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynBlade']['AdjEdSt'], 'AdjEdSt', '- Factor to adjust blade edge stiffness (-)\n')) @@ -680,7 +680,7 @@ def write_BeamDyn(self): f.write('{:<22} {:<11} {:}'.format(self.fst_vt['BeamDyn']['n_fact'], 'n_fact', '- Factorization frequency for the Jacobian in N-R iteration(-) [DEFAULT = 5]\n')) f.write(float_default_out(self.fst_vt['BeamDyn']['DTBeam']) + ' {:<11} {:}'.format('DTBeam', '- Time step size (s).\n')) f.write(int_default_out(self.fst_vt['BeamDyn']['load_retries']) + ' {:<11} {:}'.format('load_retries', '- Number of factored load retries before quitting the aimulation [DEFAULT = 20]\n')) - f.write(int_default_out(self.fst_vt['BeamDyn']['NRMax']) + ' {:<11} {:}'.format('NRMax', '- Max number of iterations in Newton-Ralphson algorithm (-). DEFAULT = 10\n')) + f.write(int_default_out(self.fst_vt['BeamDyn']['NRMax']) + ' {:<11} {:}'.format('NRMax', '- Max number of iterations in Newton-Raphson algorithm (-). [DEFAULT = 10]\n')) f.write(float_default_out(self.fst_vt['BeamDyn']['stop_tol']) + ' {:<11} {:}'.format('stop_tol', '- Tolerance for stopping criterion (-) [DEFAULT = 1E-5]\n')) f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['BeamDyn']['tngt_stf_fd'], 'tngt_stf_fd', '- Use finite differenced tangent stiffness matrix? (flag)\n')) f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['BeamDyn']['tngt_stf_comp'], 'tngt_stf_comp', '- Compare analytical finite differenced tangent stiffness matrix? (flag)\n')) @@ -721,7 +721,7 @@ def write_BeamDyn(self): for channel_list in outlist: for i in range(len(channel_list)): f.write('"' + channel_list[i] + '"\n') - f.write('END of input file (the word "END" must appear in the first 3 columns of this last OutList line)\n') + f.write('END of input file (the word "END" must appear in the first 3 columns of the last OutList line)\n') # Optional nodal output section if 'BldNd_BlOutNd' in self.fst_vt['BeamDyn']: @@ -734,7 +734,7 @@ def write_BeamDyn(self): for opt_channel_list in opt_outlist: for i in range(len(opt_channel_list)): f.write('"' + opt_channel_list[i] + '"\n') - f.write('END of input file (the word "END" must appear in the first 3 columns of this last OutList line)\n') + f.write('END of input file (the word "END" must appear in the first 3 columns of the last OutList line)\n') f.write('---------------------------------------------------------------------------------------') f.flush() @@ -781,7 +781,7 @@ def write_InflowWind(self): f.write('---------------------------------------------------------------------------------------------------------------\n') f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['InflowWind']['Echo'], 'Echo', '- Echo input data to .ech (flag)\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['InflowWind']['WindType'], 'WindType', '- switch for wind file type (1=steady; 2=uniform; 3=binary TurbSim FF; 4=binary Bladed-style FF; 5=HAWC format; 6=User defined; 7=native Bladed FF)\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['InflowWind']['PropagationDir'], 'PropagationDir', '- Direction of wind propagation (meteoroligical rotation from aligned with X (positive rotates towards -Y) -- degrees)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['InflowWind']['PropagationDir'], 'PropagationDir', '- Direction of wind propagation (meteoroligical rotation from aligned with X (positive rotates towards -Y) -- degrees) (not used for native Bladed format WindType=7)\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['InflowWind']['VFlowAng'], 'VFlowAng', '- Upflow angle (degrees) (not used for native Bladed format WindType=7)\n')) f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['InflowWind']['VelInterpCubic'], 'VelInterpCubic', '- Use cubic interpolation for velocity in time (false=linear, true=cubic) [Used with WindType=2,3,4,5,7]\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['InflowWind']['NWindVel'], 'NWindVel', '- Number of points to output the wind velocity (0 to 9)\n')) @@ -789,18 +789,18 @@ def write_InflowWind(self): f.write('{:<22} {:<11} {:}'.format(', '.join(self.fst_vt['InflowWind']['WindVyiList']), 'WindVyiList', '- List of coordinates in the inertial Y direction (m)\n')) f.write('{:<22} {:<11} {:}'.format(', '.join(self.fst_vt['InflowWind']['WindVziList']), 'WindVziList', '- List of coordinates in the inertial Z direction (m)\n')) f.write('================== Parameters for Steady Wind Conditions [used only for WindType = 1] =========================\n') - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['InflowWind']['HWindSpeed'], 'HWindSpeed', '- Horizontal windspeed (m/s)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['InflowWind']['HWindSpeed'], 'HWindSpeed', '- Horizontal wind speed (m/s)\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['InflowWind']['RefHt'], 'RefHt', '- Reference height for horizontal wind speed (m)\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['InflowWind']['PLexp'], 'PLexp', '- Power law exponent (-)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['InflowWind']['PLExp'], 'PLExp', '- Power law exponent (-)\n')) f.write('================== Parameters for Uniform wind file [used only for WindType = 2] ============================\n') - f.write('{:<22} {:<11} {:}'.format('"'+self.fst_vt['InflowWind']['Filename_Uni']+'"', 'Filename_Uni', '- Filename of time series data for uniform wind field. (-)\n')) + f.write('{:<22} {:<11} {:}'.format('"'+self.fst_vt['InflowWind']['FileName_Uni']+'"', 'FileName_Uni', '- Filename of time series data for uniform wind field. (-)\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['InflowWind']['RefHt_Uni'], 'RefHt_Uni', '- Reference height for horizontal wind speed (m)\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['InflowWind']['RefLength'], 'RefLength', '- Reference length for linear horizontal and vertical sheer (-)\n')) f.write('================== Parameters for Binary TurbSim Full-Field files [used only for WindType = 3] ==============\n') f.write('{:<22} {:<11} {:}'.format('"'+self.fst_vt['InflowWind']['FileName_BTS']+'"', 'FileName_BTS', '- Name of the Full field wind file to use (.bts)\n')) - f.write('================== Parameters for Binary Bladed-style Full-Field files [used only for WindType = 4] =========\n') - f.write('{:<22} {:<11} {:}'.format('"'+self.fst_vt['InflowWind']['FilenameRoot']+'"', 'FilenameRoot', '- Rootname of the full-field wind file to use (.wnd, .sum)\n')) - f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['InflowWind']['TowerFile'], 'TowerFile', '- Have tower file (.twr) (flag)\n')) + f.write('================== Parameters for Binary Bladed-style Full-Field files [used only for WindType = 4 or WindType = 7] =========\n') + f.write('{:<22} {:<11} {:}'.format('"'+self.fst_vt['InflowWind']['FileNameRoot']+'"', 'FileNameRoot', '- WindType=4: Rootname of the full-field wind file to use (.wnd, .sum); WindType=7: name of the intermediate file with wind scaling values\n')) + f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['InflowWind']['TowerFile'], 'TowerFile', '- Have tower file (.twr) (flag) ignored when WindType = 7\n')) f.write('================== Parameters for HAWC-format binary files [Only used with WindType = 5] =====================\n') f.write('{:<22} {:<11} {:}'.format('"'+self.fst_vt['InflowWind']['FileName_u']+'"', 'FileName_u', '- name of the file containing the u-component fluctuating wind (.bin)\n')) f.write('{:<22} {:<11} {:}'.format('"'+self.fst_vt['InflowWind']['FileName_v']+'"', 'FileName_v', '- name of the file containing the v-component fluctuating wind (.bin)\n')) @@ -837,8 +837,8 @@ def write_InflowWind(self): f.write('{:<22} {:<11} {:}'.format(', '.join(np.array(self.fst_vt['InflowWind']['RotorApexOffsetPos'], dtype=str)), 'RotorApexOffsetPos', '- Offset of the lidar from hub height (m)\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['InflowWind']['URefLid'], 'URefLid', '- Reference average wind speed for the lidar[m/s]\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['InflowWind']['MeasurementInterval'], 'MeasurementInterval', '- Time between each measurement [s]\n')) - f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['InflowWind']['LidRadialVel'], 'LidRadialVel', '- TRUE => return radial component, FALSE => return x direction estimate\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['InflowWind']['ConsiderHubMotion'], 'ConsiderHubMotion', '- Flag whether to consider the hub motions impact on Lidar measurements\n')) + f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['InflowWind']['LidRadialVel'], 'LidRadialVel', '- TRUE => return radial component, FALSE => return \'x\' direction estimate\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['InflowWind']['ConsiderHubMotion'], 'ConsiderHubMotion', '- Flag whether to consider the hub motion\'s impact on Lidar measurements\n')) f.write('====================== OUTPUT ==================================================\n') f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['InflowWind']['SumPrint'], 'SumPrint', '- Print summary data to .IfW.sum (flag)\n')) f.write('OutList - The next line(s) contains a list of output parameters. See OutListParameters.xlsx for a listing of available output channels, (-)\n') @@ -848,7 +848,7 @@ def write_InflowWind(self): for i in range(len(channel_list)): f.write('"' + channel_list[i] + '"\n') - f.write('END of input file (the word "END" must appear in the first 3 columns of this last OutList line)\n') + f.write('END of input file (the word "END" must appear in the first 3 columns of the last OutList line)\n') f.write('---------------------------------------------------------------------------------------\n') f.flush() @@ -957,7 +957,7 @@ def write_AeroDyn(self): f.write('====== Hub Properties ============================================================================== [used only when Buoyancy=True]\n') f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn']['VolHub'], 'VolHub', '- Hub volume (m^3)\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn']['HubCenBx'], 'HubCenBx', '- Hub center of buoyancy x direction offset (m)\n')) - f.write('====== Nacelle Properties ========================================================================== used only when Buoyancy=True or NacelleDrag=True]\n') + f.write('====== Nacelle Properties ========================================================================== [used only when Buoyancy=True or NacelleDrag=True]\n') f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn']['VolNac'], 'VolNac', '- Nacelle volume (m^3)\n')) f.write('{:<22} {:<11} {:}'.format(', '.join(np.array(self.fst_vt['AeroDyn']['NacCenB'], dtype=str)), 'NacCenB', '- Position of nacelle center of buoyancy from yaw bearing in nacelle coordinates (m)\n')) f.write('{:<22} {:<11} {:}'.format(', '.join(np.array(self.fst_vt['AeroDyn']['NacArea'], dtype=str)), 'NacArea', '- Projected area of the nacelle in X, Y, Z in the nacelle coordinate system (m^2)\n')) @@ -988,7 +988,7 @@ def write_AeroDyn(self): for channel_list in outlist: for i in range(len(channel_list)): f.write('"' + channel_list[i] + '"\n') - f.write('END of input file (the word "END" must appear in the first 3 columns of this last OutList line)\n') + f.write('END of input file (the word "END" must appear in the first 3 columns of the last OutList line)\n') # Optional nodal output section if 'BldNd_BladesOut' in self.fst_vt['AeroDyn']: @@ -1001,7 +1001,7 @@ def write_AeroDyn(self): for opt_channel_list in opt_outlist: for i in range(len(opt_channel_list)): f.write('"' + opt_channel_list[i] + '"\n') - f.write('END of input file (the word "END" must appear in the first 3 columns of this last OutList line)\n') + f.write('END of input file (the word "END" must appear in the first 3 columns of the last OutList line)\n') f.write('---------------------------------------------------------------------------------------\n') f.flush() @@ -1020,8 +1020,8 @@ def write_AeroDynBlade(self): f.write('Generated with OpenFAST_IO\n') f.write('====== Blade Properties =================================================================\n') f.write('{:<11d} {:<11} {:}'.format(self.fst_vt['AeroDynBlade']['NumBlNds'], 'NumBlNds', '- Number of blade nodes used in the analysis (-)\n')) - f.write(' BlSpn BlCrvAC BlSwpAC BlCrvAng BlTwist BlChord BlAFID\n') - f.write(' (m) (m) (m) (deg) (deg) (m) (-)\n') + f.write(' BlSpn BlCrvAC BlSwpAC BlCrvAng BlTwist BlChord BlAFID BlCb BlCenBn BlCenBt\n') + f.write(' (m) (m) (m) (deg) (deg) (m) (-) (-) (m) (m)\n') BlSpn = self.fst_vt['AeroDynBlade']['BlSpn'] BlCrvAC = self.fst_vt['AeroDynBlade']['BlCrvAC'] BlSwpAC = self.fst_vt['AeroDynBlade']['BlSwpAC'] @@ -1029,8 +1029,11 @@ def write_AeroDynBlade(self): BlTwist = self.fst_vt['AeroDynBlade']['BlTwist'] BlChord = self.fst_vt['AeroDynBlade']['BlChord'] BlAFID = self.fst_vt['AeroDynBlade']['BlAFID'] - for Spn, CrvAC, SwpAC, CrvAng, Twist, Chord, AFID in zip(BlSpn, BlCrvAC, BlSwpAC, BlCrvAng, BlTwist, BlChord, BlAFID): - f.write('{: 2.15e} {: 2.15e} {: 2.15e} {: 2.15e} {: 2.15e} {: 2.15e} {: 8d}\n'.format(Spn, CrvAC, SwpAC, CrvAng, Twist, Chord, int(AFID))) + BlCb = self.fst_vt['AeroDynBlade']['BlCb'] + BlCenBn = self.fst_vt['AeroDynBlade']['BlCenBn'] + BlCenBt = self.fst_vt['AeroDynBlade']['BlCenBt'] + for Spn, CrvAC, SwpAC, CrvAng, Twist, Chord, AFID, BlCb, BlCenBn, BlCenBt in zip(BlSpn, BlCrvAC, BlSwpAC, BlCrvAng, BlTwist, BlChord, BlAFID, BlCb, BlCenBn, BlCenBt): + 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)) f.flush() os.fsync(f) @@ -1075,7 +1078,7 @@ def write_AeroDynPolar(self): else: f.write('{:<22d} {:<11} {:}'.format(0, 'NumCoords', '! The number of coordinates in the airfoil shape file. Set to zero if coordinates not included.\n')) f.write('AF{:02d}_BL.txt {:<11} {:}'.format(afi, 'BL_file', '! The file name including the boundary layer characteristics of the profile. Ignored if the aeroacoustic module is not called.\n')) - # f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn']['af_data'][afi][0]['NumTabs'], 'NumTabs', '! Number of airfoil tables in this file. Each table must have lines for Re and Ctrl.\n')) + # f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn']['af_data'][afi][0]['NumTabs'], 'NumTabs', '! Number of airfoil tables in this file. Each table must have lines for Re and UserProp.\n')) # Check if we have multiple tables per airfoil @@ -1085,22 +1088,22 @@ def write_AeroDynPolar(self): elif self.fst_vt['AeroDyn']['AFTabMod'] == 3: # for tab_orig in range(self.fst_vt['AeroDyn']['af_data'][afi][0]['NumTabs'] - 1): if len( self.fst_vt['AeroDyn']['af_data'][afi]) == 1 or \ - self.fst_vt['AeroDyn']['af_data'][afi][0]['Ctrl'] == self.fst_vt['AeroDyn']['af_data'][afi][1]['Ctrl']: - num_tab = 1 # assume that all Ctrl angles of the flaps are identical if the first two are -> no flaps! + self.fst_vt['AeroDyn']['af_data'][afi][0]['UserProp'] == self.fst_vt['AeroDyn']['af_data'][afi][1]['UserProp']: + num_tab = 1 # assume that all UserProp angles of the flaps are identical if the first two are -> no flaps! else: num_tab = self.fst_vt['AeroDyn']['af_data'][afi][0]['NumTabs'] else: num_tab = 1 - # f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn']['af_data'][afi][0]['NumTabs'], 'NumTabs','! Number of airfoil tables in this file. Each table must have lines for Re and Ctrl.\n')) - f.write('{:<22d} {:<11} {:}'.format(num_tab, 'NumTabs','! Number of airfoil tables in this file. Each table must have lines for Re and Ctrl.\n')) + # f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn']['af_data'][afi][0]['NumTabs'], 'NumTabs','! Number of airfoil tables in this file. Each table must have lines for Re and UserProp.\n')) + f.write('{:<22d} {:<11} {:}'.format(num_tab, 'NumTabs','! Number of airfoil tables in this file. Each table must have lines for Re and UserProp.\n')) - # for tab in range(self.fst_vt['AeroDyn']['af_data'][afi][0]['NumTabs']): # For writing multiple tables (different Re or Ctrl values) - for tab in range(num_tab): # For writing multiple tables (different Re or Ctrl values) + # for tab in range(self.fst_vt['AeroDyn']['af_data'][afi][0]['NumTabs']): # For writing multiple tables (different Re or UserProp values) + for tab in range(num_tab): # For writing multiple tables (different Re or UserProp values) f.write('! ------------------------------------------------------------------------------\n') f.write("! data for table %i \n" % (tab + 1)) f.write('! ------------------------------------------------------------------------------\n') f.write('{:<22f} {:<11} {:}'.format(self.fst_vt['AeroDyn']['af_data'][afi][tab]['Re']*1.e-6, 'Re', '! Reynolds number in millions\n')) - f.write('{:<22d} {:<11} {:}'.format(int(self.fst_vt['AeroDyn']['af_data'][afi][tab]['Ctrl']), 'Ctrl', '! Control setting (must be 0 for current AirfoilInfo)\n')) + f.write('{:<22d} {:<11} {:}'.format(int(self.fst_vt['AeroDyn']['af_data'][afi][tab]['UserProp']), 'UserProp', '! User property (control) setting\n')) f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn']['af_data'][afi][tab]['InclUAdata'], 'InclUAdata', '! Is unsteady aerodynamics data included in this table? If TRUE, then include 30 UA coefficients below this line\n')) f.write('!........................................\n') if self.fst_vt['AeroDyn']['af_data'][afi][tab]['InclUAdata']: @@ -1136,7 +1139,7 @@ def write_AeroDynPolar(self): f.write('{:<22f} {:<11} {:}'.format(self.fst_vt['AeroDyn']['af_data'][afi][tab]['k1_hat'], 'k1_hat', '! Constant in the expression of Cc due to leading edge vortex effects. [ignored if UA_Mod<>1]\n')) f.write(float_default_out(self.fst_vt['AeroDyn']['af_data'][afi][tab]['x_cp_bar']) + ' {:<11} {:}'.format('x_cp_bar', '! Constant in the expression of \\hat(x)_cp^v. [ignored if UA_Mod<>1, default = 0.2]\n')) f.write(float_default_out(self.fst_vt['AeroDyn']['af_data'][afi][tab]['UACutout']) + ' {:<11} {:}'.format('UACutout', '! Angle of attack above which unsteady aerodynamics are disabled (deg). [Specifying the string "Default" sets UACutout to 45 degrees]\n')) - f.write(float_default_out(self.fst_vt['AeroDyn']['af_data'][afi][tab]['filtCutOff']) + ' {:<11} {:}'.format('filtCutOff', '! Cut-off frequency (-3 dB corner frequency) for low-pass filtering the AoA input to UA, as well as the 1st and 2nd derivatives (Hz) [default = 20]\n')) + f.write(float_default_out(self.fst_vt['AeroDyn']['af_data'][afi][tab]['filtCutOff']) + ' {:<11} {:}'.format('filtCutOff', '! Reduced frequency cut-off for low-pass filtering the AoA input to UA, as well as the 1st and 2nd derivatives (-) [default = 0.5]\n')) f.write('!........................................\n') f.write('! Table of aerodynamics coefficients\n') @@ -1299,7 +1302,7 @@ def write_AeroDisk(self): for i in range(len(channel_list)): f.write('"' + channel_list[i] + '"\n') - f.write('END of input file (the word "END" must appear in the first 3 columns of this last OutList line)\n') + f.write('END of input file (the word "END" must appear in the first 3 columns of the last OutList line)\n') f.write('---------------------------------------------------------------------------------------\n') f.flush() @@ -1393,7 +1396,7 @@ def write_ServoDyn(self): f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ServoDyn']['NacYawF'], 'NacYawF', '- Final yaw angle for override yaw maneuvers (degrees)\n')) f.write('---------------------- Aerodynamic Flow Control -------------------------------------\n') f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ServoDyn']['AfCmode'], 'AfCmode', '- Airfoil control mode {0: none, 1: cosine wave cycle, 4: user-defined from Simulink/Labview, 5: user-defined from Bladed-style DLL} (switch)\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ServoDyn']['AfC_Mean'], 'AfC_Mean', '- Mean level for sinusoidal cycling or steady value (-) [used only with AfCmode==1]\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ServoDyn']['AfC_Mean'], 'AfC_Mean', '- Mean level for cosine cycling or steady value (-) [used only with AfCmode==1]\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ServoDyn']['AfC_Amp'], 'AfC_Amp', '- Amplitude for for cosine cycling of flap signal (AfC = AfC_Amp*cos(Azimuth+phase)+AfC_mean) (-) [used only with AfCmode==1]\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ServoDyn']['AfC_Phase'], 'AfC_phase', '- Phase relative to the blade azimuth (0 is vertical) for for cosine cycling of flap signal (deg) [used only with AfCmode==1]\n')) f.write('---------------------- STRUCTURAL CONTROL ---------------------------------------\n') @@ -1406,7 +1409,7 @@ def write_ServoDyn(self): f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ServoDyn']['NumSStC'], 'NumSStC', '- Number of substructure structural controllers (integer)\n')) f.write('{!s:<22} {:<11} {:}'.format('"' + '" "'.join(self.fst_vt['ServoDyn']['SStCfiles']) + '"', 'SStCfiles', '- Name of the files for substructure structural controllers (quoted strings) [unused when NumSStC==0]\n')) f.write('---------------------- CABLE CONTROL ---------------------------------------- \n') - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ServoDyn']['CCmode'], 'CCmode', '- Cable control mode {0- none, 4- user-defined from Simulink/Labview, 5- user-defineAfC_phased from Bladed-style DLL}\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ServoDyn']['CCmode'], 'CCmode', '- Cable control mode {0: none, 4: user-defined from Simulink/Labview, 5: user-defined from Bladed-style DLL} (switch)\n')) f.write('---------------------- BLADED INTERFACE ---------------------------------------- [used only with Bladed Interface]\n') f.write('{:<22} {:<11} {:}'.format('"'+self.fst_vt['ServoDyn']['DLL_FileName']+'"', 'DLL_FileName', '- Name/location of the dynamic library {.dll [Windows] or .so [Linux]} in the Bladed-DLL format (-) [used only with Bladed Interface]\n')) f.write('{:<22} {:<11} {:}'.format('"'+self.fst_vt['ServoDyn']['DLL_InFile']+'"', 'DLL_InFile', '- Name of input file sent to the DLL (-) [used only with Bladed Interface]\n')) @@ -1448,7 +1451,7 @@ def write_ServoDyn(self): for i in range(len(channel_list)): f.write('"' + channel_list[i] + '"\n') - f.write('END of input file (the word "END" must appear in the first 3 columns of this last OutList line)\n') + f.write('END of input file (the word "END" must appear in the first 3 columns of the last OutList line)\n') f.write('---------------------------------------------------------------------------------------\n') f.flush() @@ -1517,33 +1520,33 @@ def write_HydroDyn(self): f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['HydroDyn']['Echo'], 'Echo', '- Echo the input file data (flag)\n')) f.write('---------------------- FLOATING PLATFORM --------------------------------------- [unused with WaveMod=6]\n') f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['HydroDyn']['PotMod'], 'PotMod', '- Potential-flow model {0: none=no potential flow, 1: frequency-to-time-domain transforms based on WAMIT output, 2: fluid-impulse theory (FIT)} (switch)\n')) - f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['HydroDyn']['ExctnMod'], 'ExctnMod', '- Wave Excitation model {0: None, 1: DFT, 2: state-space} (switch) [only used when PotMod=1; STATE-SPACE REQUIRES *.ssexctn INPUT FILE]\n')) + f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['HydroDyn']['ExctnMod'], 'ExctnMod', '- Wave-excitation model {0: no wave-excitation calculation, 1: DFT, 2: state-space} (switch) [only used when PotMod=1; STATE-SPACE REQUIRES *.ssexctn INPUT FILE]\n')) f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['HydroDyn']['ExctnDisp'], 'ExctnDisp','- Method of computing Wave Excitation {0: use undisplaced position, 1: use displaced position, 2: use low-pass filtered displaced position) [only used when PotMod=1 and ExctnMod>0 and SeaState\'s WaveMod>0]} (switch)\n')) - f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['HydroDyn']['ExctnCutOff'], 'ExctnCutOff','- Method of computing Wave Excitation {0: use undisplaced position, 1: use displaced position, 2: use low-pass filtered displaced position) [only used when PotMod=1 and ExctnMod>0 and SeaState\'s WaveMod>0]} (switch)\n')) - f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['HydroDyn']['PtfmYMod'], 'PtfmYMod', '- - Model for large platform yaw offset {0: Static reference yaw offset based on PtfmRefY, 1: dynamic reference yaw offset based on low-pass filtering the PRP yaw motion with cutoff frequency PtfmYCutOff} (switch)\n')) + f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['HydroDyn']['ExctnCutOff'], 'ExctnCutOff','- Cutoff (corner) frequency of the low-pass time-filtered displaced position (Hz) [>0.0] [used only when PotMod=1, ExctnMod>0, and ExctnDisp=2]) [only used when PotMod=1 and ExctnMod>0 and SeaState\'s WaveMod>0]} (switch)\n')) + f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['HydroDyn']['PtfmYMod'], 'PtfmYMod', '- Model for large platform yaw offset {0: Static reference yaw offset based on PtfmRefY, 1: dynamic reference yaw offset based on low-pass filtering the PRP yaw motion with cutoff frequency PtfmYCutOff} (switch)\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['HydroDyn']['PtfmRefY'], 'PtfmRefY', '- Constant (if PtfmYMod=0) or initial (if PtfmYMod=1) platform reference yaw offset (deg)\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['HydroDyn']['PtfmYCutOff'], 'PtfmYCutOff', '- Cutoff frequency for the low-pass filtering of PRP yaw motion when PtfmYMod=1 [unused when PtfmYMod=0] (Hz)\n')) f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['HydroDyn']['NExctnHdg'], 'NExctnHdg', '- Number of evenly distributed platform yaw/heading angles over the range of [-180, 180) deg for which the wave excitation shall be computed [only used when PtfmYMod=1] (-)\n')) f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['HydroDyn']['RdtnMod'], 'RdtnMod', '- Radiation memory-effect model {0: no memory-effect calculation, 1: convolution, 2: state-space} (switch) [only used when PotMod=1; STATE-SPACE REQUIRES *.ss INPUT FILE]\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['HydroDyn']['RdtnTMax'], 'RdtnTMax', '- Analysis time for wave radiation kernel calculations (sec) [only used when PotMod=1; determines RdtnDOmega=Pi/RdtnTMax in the cosine transform; MAKE SURE THIS IS LONG ENOUGH FOR THE RADIATION IMPULSE RESPONSE FUNCTIONS TO DECAY TO NEAR-ZERO FOR THE GIVEN PLATFORM!]\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['HydroDyn']['RdtnDT'], 'RdtnDT', '- Time step for wave radiation kernel calculations (sec) [only used when PotMod=1; DT<=RdtnDT<=0.1 recommended; determines RdtnOmegaMax=Pi/RdtnDT in the cosine transform]\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['HydroDyn']['RdtnTMax'], 'RdtnTMax', '- Analysis time for wave radiation kernel calculations (sec) [only used when PotMod=1 and RdtnMod>0; determines RdtnDOmega=Pi/RdtnTMax in the cosine transform; MAKE SURE THIS IS LONG ENOUGH FOR THE RADIATION IMPULSE RESPONSE FUNCTIONS TO DECAY TO NEAR-ZERO FOR THE GIVEN PLATFORM!]\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['HydroDyn']['RdtnDT'], 'RdtnDT', '- Time step for wave radiation kernel calculations (sec) [only used when PotMod=1 and ExctnMod>0 or RdtnMod>0; DT<=RdtnDT<=0.1 recommended; determines RdtnOmegaMax=Pi/RdtnDT in the cosine transform]\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['HydroDyn']['NBody'], 'NBody', '- Number of WAMIT bodies to be used (-) [>=1; only used when PotMod=1. If NBodyMod=1, the WAMIT data contains a vector of size 6*NBody x 1 and matrices of size 6*NBody x 6*NBody; if NBodyMod>1, there are NBody sets of WAMIT data each with a vector of size 6 x 1 and matrices of size 6 x 6]\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['HydroDyn']['NBodyMod'], 'NBodyMod', '- Body coupling model {1: include coupling terms between each body and NBody in HydroDyn equals NBODY in WAMIT, 2: neglect coupling terms between each body and NBODY=1 with XBODY=0 in WAMIT, 3: Neglect coupling terms between each body and NBODY=1 with XBODY=/0 in WAMIT} (switch) [only used when PotMod=1]\n')) - f.write('{:<22} {:<11} {:}'.format(', '.join([f'"{pf}"' for pf in self.fst_vt['HydroDyn']['PotFile']]), 'PotFile', '- Root name of potential-flow model data; WAMIT output files containing the linear, nondimensionalized, hydrostatic restoring matrix (.hst), frequency-dependent hydrodynamic added mass matrix and damping matrix (.1), and frequency- and direction-dependent wave excitation force vector per unit wave amplitude (.3) (quoted string) [MAKE SURE THE FREQUENCIES INHERENT IN THESE WAMIT FILES SPAN THE PHYSICALLY-SIGNIFICANT RANGE OF FREQUENCIES FOR THE GIVEN PLATFORM; THEY MUST CONTAIN THE ZERO- AND INFINITE-FREQUENCY LIMITS!]\n')) - f.write('{:<22} {:<11} {:}'.format(', '.join([f'{val}' for val in self.fst_vt['HydroDyn']['WAMITULEN']]), 'WAMITULEN', '- Characteristic body length scale used to redimensionalize WAMIT output (meters) [only used when PotMod=1]\n')) + f.write('{:<22} {:<11} {:}'.format(', '.join([f'"{pf}"' for pf in self.fst_vt['HydroDyn']['PotFile']]), 'PotFile', '- Root name of potential-flow model data; WAMIT output files containing the linear, nondimensionalized, hydrostatic restoring matrix (.hst), frequency-dependent hydrodynamic added mass matrix and damping matrix (.1), and frequency- and direction-dependent wave excitation force vector per unit wave amplitude (.3) (quoted string) [1 to NBody if NBodyMod>1] [MAKE SURE THE FREQUENCIES INHERENT IN THESE WAMIT FILES SPAN THE PHYSICALLY-SIGNIFICANT RANGE OF FREQUENCIES FOR THE GIVEN PLATFORM; THEY MUST CONTAIN THE ZERO- AND INFINITE-FREQUENCY LIMITS!]\n')) + f.write('{:<22} {:<11} {:}'.format(', '.join([f'{val}' for val in self.fst_vt['HydroDyn']['WAMITULEN']]), 'WAMITULEN', '- Characteristic body length scale used to redimensionalize WAMIT output (meters) [1 to NBody if NBodyMod>1] [only used when PotMod=1]\n')) f.write('{:<22} {:<11} {:}'.format(', '.join([f'{val}' for val in self.fst_vt['HydroDyn']['PtfmRefxt']]), 'PtfmRefxt', '- The xt offset of the body reference point(s) from (0,0,0) (meters) [1 to NBody] [only used when PotMod=1]\n')) f.write('{:<22} {:<11} {:}'.format(', '.join([f'{val}' for val in self.fst_vt['HydroDyn']['PtfmRefyt']]), 'PtfmRefyt', '- The yt offset of the body reference point(s) from (0,0,0) (meters) [1 to NBody] [only used when PotMod=1]\n')) f.write('{:<22} {:<11} {:}'.format(', '.join([f'{val}' for val in self.fst_vt['HydroDyn']['PtfmRefzt']]), 'PtfmRefzt', '- The zt offset of the body reference point(s) from (0,0,0) (meters) [1 to NBody] [only used when PotMod=1. If NBodyMod=2,PtfmRefzt=0.0]\n')) f.write('{:<22} {:<11} {:}'.format(', '.join([f'{val}' for val in self.fst_vt['HydroDyn']['PtfmRefztRot']]), 'PtfmRefztRot', '- The rotation about zt of the body reference frame(s) from xt/yt (degrees) [1 to NBody] [only used when PotMod=1]\n')) - f.write('{:<22} {:<11} {:}'.format(', '.join([f'{val}' for val in self.fst_vt['HydroDyn']['PtfmVol0']]), 'PtfmVol0', '- Displaced volume of water when the platform is in its undisplaced position (m^3) [only used when PotMod=1; USE THE SAME VALUE COMPUTED BY WAMIT AS OUTPUT IN THE .OUT FILE!]\n')) - f.write('{:<22} {:<11} {:}'.format(', '.join([f'{val}' for val in self.fst_vt['HydroDyn']['PtfmCOBxt']]), 'PtfmCOBxt', '- The xt offset of the center of buoyancy (COB) from the platform reference point (meters) [only used when PotMod=1]\n')) - f.write('{:<22} {:<11} {:}'.format(', '.join([f'{val}' for val in self.fst_vt['HydroDyn']['PtfmCOByt']]), 'PtfmCOByt', '- The yt offset of the center of buoyancy (COB) from the platform reference point (meters) [only used when PotMod=1]\n')) + f.write('{:<22} {:<11} {:}'.format(', '.join([f'{val}' for val in self.fst_vt['HydroDyn']['PtfmVol0']]), 'PtfmVol0', '- Displaced volume of water when the body is in its undisplaced position (m^3) [1 to NBody] [only used when PotMod=1; USE THE SAME VALUE COMPUTED BY WAMIT AS OUTPUT IN THE .OUT FILE!]\n')) + f.write('{:<22} {:<11} {:}'.format(', '.join([f'{val}' for val in self.fst_vt['HydroDyn']['PtfmCOBxt']]), 'PtfmCOBxt', '- The xt offset of the center of buoyancy (COB) from (0,0) (meters) [1 to NBody] [only used when PotMod=1]\n')) + f.write('{:<22} {:<11} {:}'.format(', '.join([f'{val}' for val in self.fst_vt['HydroDyn']['PtfmCOByt']]), 'PtfmCOByt', '- The yt offset of the center of buoyancy (COB) from (0,0) (meters) [1 to NBody] [only used when PotMod=1]\n')) f.write('---------------------- 2ND-ORDER FLOATING PLATFORM FORCES ---------------------- [unused with WaveMod=0 or 6, or PotMod=0 or 2]\n') f.write('{:<22} {:<11} {:}'.format(self.fst_vt['HydroDyn']['MnDrift'], 'MnDrift', "- Mean-drift 2nd-order forces computed {0: None; [7, 8, 9, 10, 11, or 12]: WAMIT file to use} [Only one of MnDrift, NewmanApp, or DiffQTF can be non-zero]\n")) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['HydroDyn']['NewmanApp'], 'NewmanApp', "- Mean- and slow-drift 2nd-order forces computed with Newman's approximation {0: None; [7, 8, 9, 10, 11, or 12]: WAMIT file to use} [Only one of MnDrift, NewmanApp, or DiffQTF can be non-zero. Used only when WaveDirMod=0]\n")) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['HydroDyn']['DiffQTF'], 'DiffQTF', "- Full difference-frequency 2nd-order forces computed with full QTF {0: None; [10, 11, or 12]: WAMIT file to use} [Only one of MnDrift, NewmanApp, or DiffQTF can be non-zero]\n")) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['HydroDyn']['SumQTF'], 'SumQTF', "- Full summation -frequency 2nd-order forces computed with full QTF {0: None; [10, 11, or 12]: WAMIT file to use}\n")) - f.write('---------------------- PLATFORM ADDITIONAL STIFFNESS AND DAMPING --------------\n') + f.write('---------------------- PLATFORM ADDITIONAL STIFFNESS AND DAMPING -------------- [unused with PotMod=0 or 2]\n') for j in range(6): if type(self.fst_vt['HydroDyn']['AddF0'][j]) == float: ln = '{:14} '.format(self.fst_vt['HydroDyn']['AddF0'][j]) @@ -1563,7 +1566,7 @@ def write_HydroDyn(self): except: ln = " ".join(['{:14}'.format(i) for i in self.fst_vt['HydroDyn']['AddCLin'][j]]) if j == 0: - ln = ln + " AddCLin - Additional linear stiffness (N/m, N/rad, N-m/m, N-m/rad)\n" + ln = ln + " AddCLin - Additional linear stiffness (N/m, N/rad, N-m/m, N-m/rad) [If NBodyMod=1, one size 6*NBody x 6*NBody matrix; if NBodyMod>1, NBody size 6 x 6 matrices]\n" else: ln = ln + "\n" f.write(ln) @@ -1573,7 +1576,7 @@ def write_HydroDyn(self): except: ln = " ".join(['{:14}'.format(i) for i in self.fst_vt['HydroDyn']['AddBLin'][j]]) if j == 0: - ln = ln + " AddBLin - Additional linear damping(N/(m/s), N/(rad/s), N-m/(m/s), N-m/(rad/s))\n" + ln = ln + " AddBLin - Additional linear damping(N/(m/s), N/(rad/s), N-m/(m/s), N-m/(rad/s)) [If NBodyMod=1, one size 6*NBody x 6*NBody matrix; if NBodyMod>1, NBody size 6 x 6 matrices]\n" else: ln = ln + "\n" f.write(ln) @@ -1583,14 +1586,14 @@ def write_HydroDyn(self): except: ln = " ".join(['{:14}'.format(i) for i in self.fst_vt['HydroDyn']['AddBQuad'][j]]) if j == 0: - ln = ln + " AddBQuad - Additional quadratic drag(N/(m/s)^2, N/(rad/s)^2, N-m(m/s)^2, N-m/(rad/s)^2)\n" + ln = ln + " AddBQuad - Additional quadratic drag(N/(m/s)^2, N/(rad/s)^2, N-m(m/s)^2, N-m/(rad/s)^2) [If NBodyMod=1, one size 6*NBody x 6*NBody matrix; if NBodyMod>1, NBody size 6 x 6 matrices]\n" else: ln = ln + "\n" f.write(ln) f.write('---------------------- STRIP THEORY OPTIONS --------------------------------------\n') - f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['HydroDyn']['WaveDisp'], 'WaveDisp', '- Method of computing Wave Kinematics {0- use undisplaced position, 1- use displaced position) } (switch)\n')) - f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['HydroDyn']['AMMod'], 'AMMod', '\n')) + f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['HydroDyn']['WaveDisp'], 'WaveDisp', '- Method of computing Wave Kinematics {0: use undisplaced position, 1: use displaced position) } (switch)\n')) + f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['HydroDyn']['AMMod'], 'AMMod', '- Method of computing distributed added-mass force. (0: Only and always on nodes below SWL at the undisplaced position. 2: Up to the instantaneous free surface) [overwrite to 0 when WaveMod = 0 or 6 or when WaveStMod = 0 in SeaState]\n')) f.write('---------------------- AXIAL COEFFICIENTS --------------------------------------\n') f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['HydroDyn']['NAxCoef'], 'NAxCoef', '- Number of axial coefficients (-)\n')) @@ -1631,7 +1634,7 @@ def write_HydroDyn(self): f.write(" ".join(ln) + '\n') f.write('---------------------- SIMPLE HYDRODYNAMIC COEFFICIENTS (model 1) --------------\n') f.write(" ".join(['{:^11s}'.format(i) for i in ['SimplCd', 'SimplCdMG', 'SimplCa', 'SimplCaMG', 'SimplCp', 'SimplCpMG', 'SimplAxCd', 'SimplAxCdMG', 'SimplAxCa', 'SimplAxCaMG', 'SimplAxCp', 'SimplAxCpMG', 'SimplCb', 'SimplCbMG']])+'\n') - f.write(" ".join(['{:^11s}'.format(i) for i in ['(-)']*12])+'\n') + f.write(" ".join(['{:^11s}'.format(i) for i in ['(-)']*14])+'\n') ln = [] ln.append('{:^11}'.format(self.fst_vt['HydroDyn']['SimplCd'])) ln.append('{:^11}'.format(self.fst_vt['HydroDyn']['SimplCdMG'])) @@ -1710,7 +1713,7 @@ def write_HydroDyn(self): f.write('-------------------- MEMBERS -------------------------------------------------\n') f.write('{:<11d} {:<11} {:}'.format(self.fst_vt['HydroDyn']['NMembers'], 'NMembers', '- Number of members (-)\n')) f.write(" ".join(['{:^11s}'.format(i) for i in ['MemberID', 'MJointID1', 'MJointID2', 'MPropSetID1', 'MPropSetID2', 'MDivSize', 'MCoefMod', 'MHstLMod', 'PropPot']])+' ! [MCoefMod=1: use simple coeff table, 2: use depth-based coeff table, 3: use member-based coeff table] [ PropPot/=0 if member is modeled with potential-flow theory]\n') - f.write(" ".join(['{:^11s}'.format(i) for i in ['(-)', '(-)', '(-)', '(-)', '(-)', '(m)', '(switch)', '(flag)']])+'\n') + f.write(" ".join(['{:^11s}'.format(i) for i in ['(-)', '(-)', '(-)', '(-)', '(-)', '(m)', '(switch)', '(switch)', '(flag)']])+'\n') for i in range(self.fst_vt['HydroDyn']['NMembers']): ln = [] ln.append('{:^11d}'.format(self.fst_vt['HydroDyn']['MemberID'][i])) @@ -1745,8 +1748,8 @@ def write_HydroDyn(self): ln.append('{:^11}'.format(self.fst_vt['HydroDyn']['MGDens'][i])) f.write(" ".join(ln) + '\n') f.write("---------------------- MEMBER OUTPUT LIST --------------------------------------\n") - f.write('{:<11d} {:<11} {:}'.format(self.fst_vt['HydroDyn']['NMOutputs'], 'NMOutputs', '- Number of member outputs (-) [must be < 10]\n')) - f.write(" ".join(['{:^11s}'.format(i) for i in ['MemberID_out', 'NOutLoc', 'NodeLocs']])+'\n') + f.write('{:<11d} {:<11} {:}'.format(self.fst_vt['HydroDyn']['NMOutputs'], 'NMOutputs', '- Number of member outputs (-) [must be <=99]\n')) + f.write(" ".join(['{:^11s}'.format(i) for i in ['MemberID_out', 'NOutLoc', 'NodeLocs [NOutLoc < 10; node locations are normalized distance from the start of the member, and must be >=0 and <= 1] [unused if NMOutputs=0]']])+'\n') f.write(" ".join(['{:^11s}'.format(i) for i in ['(-)']*3])+'\n') for i in range(self.fst_vt['HydroDyn']['NMOutputs']): ln = [] @@ -1776,8 +1779,8 @@ def write_HydroDyn(self): def write_SeaState(self): # Generate SeaState input file - self.fst_vt['Fst']['SeaStateFile'] = self.FAST_namingOut + '_SeaState.dat' - hd_file = os.path.join(self.FAST_runDirectory, self.fst_vt['Fst']['SeaStateFile']) + self.fst_vt['Fst']['SeaStFile'] = self.FAST_namingOut + '_SeaState.dat' + hd_file = os.path.join(self.FAST_runDirectory, self.fst_vt['Fst']['SeaStFile']) f = open(hd_file, 'w') f.write('------- SeaState Input File --------------------------------------------\n') @@ -1786,7 +1789,7 @@ def write_SeaState(self): f.write('---------------------- ENVIRONMENTAL CONDITIONS --------------------------------\n') f.write('{:<22} {:<11} {:}'.format(self.fst_vt['SeaState']['WtrDens'],'WtrDens', '- Water density (kg/m^3)\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['SeaState']['WtrDpth'],'WtrDpth', '- Water depth (meters)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['SeaState']['WtrDpth'],'WtrDpth', '- Water depth (meters) relative to MSL\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['SeaState']['MSL2SWL'],'MSL2SWL', '- Offset between still-water level and mean sea level (meters) [positive upward; unused when WaveMod = 6; must be zero if PotMod=1 or 2]\n')) @@ -1802,7 +1805,7 @@ def write_SeaState(self): f.write('{:<22} {:<11} {:}'.format(self.fst_vt['SeaState']['WaveMod'], 'WaveMod', '- Incident wave kinematics model {0: none=still water, 1: regular (periodic), 1P#: regular with user-specified phase, 2: JONSWAP/Pierson-Moskowitz spectrum (irregular), 3: White noise spectrum (irregular), 4: user-defined spectrum from routine UserWaveSpctrm (irregular), 5: Externally generated wave-elevation time series, 6: Externally generated full wave-kinematics time series [option 6 is invalid for PotMod/=0]} (switch)\n')) f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['SeaState']['WaveStMod'], 'WaveStMod', '- Model for stretching incident wave kinematics to instantaneous free surface {0: none=no stretching, 1: vertical stretching, 2: extrapolation stretching, 3: Wheeler stretching} (switch) [unused when WaveMod=0 or when PotMod/=0]\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['SeaState']['WaveTMax'], 'WaveTMax', '- Analysis time for incident wave calculations (sec) [unused when WaveMod=0; determines WaveDOmega=2Pi/WaveTMax in the IFFT]\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['SeaState']['WaveDT'], 'WaveDT', '- Time step for incident wave calculations (sec) [unused when WaveMod=0; 0.1<=WaveDT<=1.0 recommended; determines WaveOmegaMax=Pi/WaveDT in the IFFT]\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['SeaState']['WaveDT'], 'WaveDT', '- Time step for incident wave calculations (sec) [unused when WaveMod=0 or 7; 0.1<=WaveDT<=1.0 recommended; determines WaveOmegaMax=Pi/WaveDT in the IFFT]\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['SeaState']['WaveHs'], 'WaveHs', '- Significant wave height of incident waves (meters) [used only when WaveMod=1, 2, or 3]\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['SeaState']['WaveTp'], 'WaveTp', '- Peak-spectral period of incident waves (sec) [used only when WaveMod=1 or 2]\n')) if isinstance(self.fst_vt['SeaState']['WavePkShp'], float): @@ -1815,7 +1818,7 @@ def write_SeaState(self): f.write('{:<22} {:<11} {:}'.format(WavePkShp, 'WavePkShp', '- Peak-shape parameter of incident wave spectrum (-) or DEFAULT (string) [used only when WaveMod=2; use 1.0 for Pierson-Moskowitz]\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['SeaState']['WvLowCOff'], 'WvLowCOff', '- Low cut-off frequency or lower frequency limit of the wave spectrum beyond which the wave spectrum is zeroed (rad/s) [unused when WaveMod=0, 1, or 6]\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['SeaState']['WvHiCOff'], 'WvHiCOff', '- High cut-off frequency or upper frequency limit of the wave spectrum beyond which the wave spectrum is zeroed (rad/s) [unused when WaveMod=0, 1, or 6]\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['SeaState']['WaveDir'], 'WaveDir', '- Incident wave propagation heading direction (degrees) [unused when WaveMod=0 or 6]\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['SeaState']['WaveDir'], 'WaveDir', '- Incident wave propagation heading direction (degrees) [unused when WaveMod=0, 6 or 7]\n')) f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['SeaState']['WaveDirMod'], 'WaveDirMod', '- Directional spreading function {0: none, 1: COS2S} (-) [only used when WaveMod=2,3, or 4]\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['SeaState']['WaveDirSpread'], 'WaveDirSpread', '- Wave direction spreading coefficient ( > 0 ) (-) [only used when WaveMod=2,3, or 4 and WaveDirMod=1]\n')) f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['SeaState']['WaveNDir'], 'WaveNDir', '- Number of wave directions (-) [only used when WaveMod=2,3, or 4 and WaveDirMod=1; odd number only]\n')) @@ -1826,10 +1829,10 @@ def write_SeaState(self): seed2 = int(self.fst_vt['SeaState']['WaveSeed2']) f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['SeaState']['WaveSeed2'], 'WaveSeed(2)', '- Second random seed of incident waves [-2147483648 to 2147483647] (-) [unused when WaveMod=0, 5, or 6]\n')) except ValueError: - f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['SeaState']['WaveSeed2'], 'WaveSeed(2)', '- Second random seed of incident waves [-2147483648 to 2147483647] (-) [unused when WaveMod=0, 5, or 6] for intrinsic pRNG, or an alternative pRNG: "RanLux"\n')) + f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['SeaState']['WaveSeed2'], 'WaveSeed(2)', '- Second random seed of incident waves [-2147483648 to 2147483647] (-) for intrinsic pRNG, or an alternative pRNG: "RanLux" (-) [unused when WaveMod=0, 5, or 6]\n')) f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['SeaState']['WaveNDAmp'], 'WaveNDAmp', '- Flag for normally distributed amplitudes (flag) [only used when WaveMod=2, 3, or 4]\n')) - f.write('{:<22} {:<11} {:}'.format('"'+self.fst_vt['SeaState']['WvKinFile']+'"', 'WvKinFile', '- Root name of externally generated wave data file(s) (quoted string) [used only when WaveMod=5 or 6]\n')) + f.write('{:<22} {:<11} {:}'.format('"'+self.fst_vt['SeaState']['WvKinFile']+'"', 'WvKinFile', '- Root name of externally generated wave data file(s) (quoted string) [used only when WaveMod=5, 6 or 7]\n')) f.write('---------------------- 2ND-ORDER WAVES ----------------------------------------- [unused with WaveMod=0 or 6]\n') f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['SeaState']['WvDiffQTF'], 'WvDiffQTF', '- Full difference-frequency 2nd-order wave kinematics (flag)\n')) f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['SeaState']['WvSumQTF'], 'WvSumQTF', '- Full summation-frequency 2nd-order wave kinematics (flag)\n')) @@ -1837,12 +1840,12 @@ def write_SeaState(self): f.write('{:<22} {:<11} {:}'.format(self.fst_vt['SeaState']['WvHiCOffD'], 'WvHiCOffD', '- High frequency cutoff used in the difference-frequencies (rad/s) [Only used with a difference-frequency method]\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['SeaState']['WvLowCOffS'], 'WvLowCOffS', '- Low frequency cutoff used in the summation-frequencies (rad/s) [Only used with a summation-frequency method]\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['SeaState']['WvHiCOffS'], 'WvHiCOffS', '- High frequency cutoff used in the summation-frequencies (rad/s) [Only used with a summation-frequency method]\n')) - f.write('---------------------- CONSTRAINED WAVE ---------------------------------------- [Only used when WaveMod=2]\n') - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['SeaState']['ConstWaveMod'], 'ConstWaveMod', '- Contrained wave model {0: no constrained wave, 1: Specified crest elevation of 0.5*CrestHmax, 2: Specified crest height of CrestHmax}\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['SeaState']['CrestHmax'], 'CrestHmax', '- Twice the crest elevation if ConstWaveMod=1 or the crest height if ConstWaveMod=2. (m) [need CrestHmax > WaveHs; unused when ConstWaveMod=0]\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['SeaState']['CrestTime'], 'CrestTime', '- Time of the wave crest. (sec) [unused when ConstWaveMod=0]\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['SeaState']['CrestXi'], 'CrestXi', '- X-position of the wave crest. (m) [unused when ConstWaveMod=0]\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['SeaState']['CrestYi'], 'CrestYi', '- Y-position of the wave crest. (m) [unused when ConstWaveMod=0]\n')) + f.write('---------------------- CONSTRAINED WAVES ----------------------------------------\n') + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['SeaState']['ConstWaveMod'], 'ConstWaveMod', '- Constrained wave model: 0=none; 1=Constrained wave with specified crest elevation, alpha; 2=Constrained wave with guaranteed peak-to-trough crest height, HCrest (flag)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['SeaState']['CrestHmax'], 'CrestHmax', '- Crest height (2*alpha for ConstWaveMod=1 or HCrest for ConstWaveMod=2), must be larger than WaveHs (m) [unused when ConstWaveMod=0]\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['SeaState']['CrestTime'], 'CrestTime', '- Time at which the crest appears (s) [unused when ConstWaveMod=0]\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['SeaState']['CrestXi'], 'CrestXi', '- X-position of the crest. (m) [unused when ConstWaveMod=0]\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['SeaState']['CrestYi'], 'CrestYi', '- Y-position of the crest. (m) [unused when ConstWaveMod=0]\n')) f.write('---------------------- CURRENT ------------------------------------------------- [unused with WaveMod=6]\n') f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['SeaState']['CurrMod'], 'CurrMod', '- Current profile model {0: none=no current, 1: standard, 2: user-defined from routine UserCurrent} (switch)\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['SeaState']['CurrSSV0'], 'CurrSSV0', '- Sub-surface current velocity at still water level (m/s) [used only when CurrMod=1]\n')) @@ -1852,8 +1855,8 @@ def write_SeaState(self): f.write('{:<22} {:<11} {:}'.format(self.fst_vt['SeaState']['CurrNSDir'], 'CurrNSDir', '- Near-surface current heading direction (degrees) [used only when CurrMod=1]\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['SeaState']['CurrDIV'], 'CurrDIV', '- Depth-independent current velocity (m/s) [used only when CurrMod=1]\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['SeaState']['CurrDIDir'], 'CurrDIDir', '- Depth-independent current heading direction (degrees) [used only when CurrMod=1]\n')) - f.write('---------------------- MacCamy-Fuchs Diffraction Model ------------------------- [unused with WaveMod=6]\n') - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['SeaState']['MCFD'],'MCFD', '- Diameter of members for which the MacCamy-Fuchs model is to be enable. [used only when MCFD > 0]\n')) + f.write('---------------------- MacCamy-Fuchs Diffraction Model -------------------------\n') + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['SeaState']['MCFD'],'MCFD', '- MacCamy-Fuchs member radius (ignored if radius <= 0) [must be 0 when WaveMod 0 or 6] \n')) f.write('---------------------- OUTPUT --------------------------------------------------\n') f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['SeaState']['SeaStSum'], 'SeaStSum', '- Output a summary file [flag]\n')) f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['SeaState']['OutSwtch'], 'OutSwtch','- Output requested channels to: [1=SeaState.out, 2=GlueCode.out, 3=both files]\n')) @@ -1862,7 +1865,7 @@ def write_SeaState(self): f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['SeaState']['NWaveElev'], 'NWaveElev','- Number of points where the incident wave elevations can be computed (-) [maximum of 9 output locations]\n')) f.write('{:<22} {:<11} {:}'.format(", ".join([f'{val:f}' for val in self.fst_vt['SeaState']['WaveElevxi']]), 'WaveElevxi', '- List of xi-coordinates for points where the incident wave elevations can be output (meters) [NWaveElev points, separated by commas or white space; usused if NWaveElev = 0]\n')) f.write('{:<22} {:<11} {:}'.format(", ".join([f'{val:f}' for val in self.fst_vt['SeaState']['WaveElevyi']]), 'WaveElevyi', '- List of yi-coordinates for points where the incident wave elevations can be output (meters) [NWaveElev points, separated by commas or white space; usused if NWaveElev = 0]\n')) - f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['SeaState']['NWaveKin'], 'NWaveKin','- Number of points where the incident wave elevations can be computed (-) [maximum of 9 output locations]\n')) + f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['SeaState']['NWaveKin'], 'NWaveKin','- Number of points where the wave kinematics can be output (-) [maximum of 9 output locations]\n')) if self.fst_vt['SeaState']['NWaveKin'] > 0 : f.write('{:<22} {:<11} {:}'.format(", ".join([f'{val:f}' for val in self.fst_vt['SeaState']['WaveKinxi']]), 'WaveKinxi', '- List of xi-coordinates for points where the wave kinematics can be output (meters) [NWaveKin points, separated by commas or white space; usused if NWaveKin = 0]\n')) @@ -1921,7 +1924,7 @@ def write_SubDyn(self): f.write('---- STRUCTURE JOINTS: joints connect structure members (~Hydrodyn Input File)---\n') f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['SubDyn']['NJoints'], 'NJoints', '- Number of joints (-)\n')) - f.write(" ".join(['{:^11s}'.format(i) for i in ['JointID','JointXss','JointYss','JointZss','JointType','JointDirX','JointDirY','JointDirZ','JointStiff']])+'\n') + f.write(" ".join(['{:^11s}'.format(i) for i in ['JointID','JointXss','JointYss','JointZss','JointType','JointDirX','JointDirY','JointDirZ','JointStiff']])+' ![Coordinates of Member joints in SS-Coordinate System][JointType={1:cantilever, 2:universal joint, 3:revolute joint, 4:spherical joint}]\n') f.write(" ".join(['{:^11s}'.format(i) for i in ['(-)','(m)','(m)','(m)','(-)','(-)','(-)','(-)','(Nm/rad)']])+'\n') for i in range(self.fst_vt['SubDyn']['NJoints']): ln = [] @@ -1952,7 +1955,7 @@ def write_SubDyn(self): f.write(" ".join(ln) + '\n') f.write('------- INTERFACE JOINTS: 1/0 for Locked (to the TP)/Free DOF @each Interface Joint (only Locked-to-TP implemented thus far (=rigid TP)) ---------\n') f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['SubDyn']['NInterf'], 'NInterf', '- Number of interface joints locked to the Transition Piece (TP): be sure to remove all rigid motion dofs\n')) - f.write(" ".join(['{:^11s}'.format(i) for i in ['IJointID', 'ItfTDXss', 'ItfTDYss', 'ItfTDZss', 'ItfRDXss', 'ItfRDYss', 'ItfRDZss']])+' ! [Global Coordinate System]\n') + f.write(" ".join(['{:^11s}'.format(i) for i in ['IJointID', 'ItfTDXss', 'ItfTDYss', 'ItfTDZss', 'ItfRDXss', 'ItfRDYss', 'ItfRDZss']])+'\n') f.write(" ".join(['{:^11s}'.format(i) for i in ['(-)', '(flag)', '(flag)', '(flag)', '(flag)', '(flag)', '(flag)']])+'\n') for i in range(self.fst_vt['SubDyn']['NInterf']): ln = [] @@ -1966,7 +1969,7 @@ def write_SubDyn(self): f.write(" ".join(ln) + '\n') f.write('----------------------------------- MEMBERS --------------------------------------\n') f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['SubDyn']['NMembers'], 'NMembers', '- Number of frame members\n')) - f.write(" ".join(['{:^11s}'.format(i) for i in ['MemberID', 'MJointID1', 'MJointID2', 'MPropSetID1', 'MPropSetID2', 'MType', 'COSMID']])+'\n') + f.write(" ".join(['{:^11s}'.format(i) for i in ['MemberID', 'MJointID1', 'MJointID2', 'MPropSetID1', 'MPropSetID2', 'MType', 'COSMID']])+' ![MType={1:beam circ., 2:cable, 3:rigid, 4:beam arb.}. COMSID={-1:none}]\n') f.write(" ".join(['{:^11s}'.format(i) for i in ['(-)','(-)','(-)','(-)','(-)','(-)','(-)']])+'\n') for i in range(self.fst_vt['SubDyn']['NMembers']): ln = [] @@ -1980,8 +1983,8 @@ def write_SubDyn(self): self.fst_vt['SubDyn']['M_COSMID'][i] = -1 if self.fst_vt['SubDyn']['M_COSMID'][i] is None else self.fst_vt['SubDyn']['M_COSMID'][i] ln.append('{:^11d}'.format(self.fst_vt['SubDyn']['M_COSMID'][i])) f.write(" ".join(ln) + '\n') - f.write('------------------ MEMBER X-SECTION PROPERTY data 1/2 [isotropic material for now: use this table for circular-tubular elements] ------------------------\n') - f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['SubDyn']['NPropSets'], 'NPropSets', '- Number of structurally unique x-sections (i.e. how many groups of X-sectional properties are utilized throughout all of the members)\n')) + f.write('------------------ CIRCULAR BEAM CROSS-SECTION PROPERTIES -----------------------------\n') + f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['SubDyn']['NPropSets'], 'NPropSets', '- Number of structurally unique cross-sections\n')) f.write(" ".join(['{:^11s}'.format(i) for i in ['PropSetID', 'YoungE', 'ShearG1', 'MatDens', 'XsecD', 'XsecT']])+'\n') f.write(" ".join(['{:^11s}'.format(i) for i in ['(-)','(N/m2)','(N/m2)','(kg/m3)','(m)','(m)']])+'\n') for i in range(self.fst_vt['SubDyn']['NPropSets']): @@ -1993,8 +1996,8 @@ def write_SubDyn(self): ln.append('{:^11}'.format(self.fst_vt['SubDyn']['XsecD'][i])) ln.append('{:^11}'.format(self.fst_vt['SubDyn']['XsecT'][i])) f.write(" ".join(ln) + '\n') - f.write('------------------ MEMBER X-SECTION PROPERTY data 2/2 [isotropic material for now: use this table if any section other than circular, however provide COSM(i,j) below] ------------------------\n') - f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['SubDyn']['NXPropSets'], 'NXPropSets', '- Number of structurally unique non-circular x-sections (if 0 the following table is ignored)\n')) + f.write('----------------- ARBITRARY BEAM CROSS-SECTION PROPERTIES -----------------------------\n') + f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['SubDyn']['NXPropSets'], 'NXPropSets', '- Number of structurally unique non-circular cross-sections (if 0 the following table is ignored)\n')) f.write(" ".join(['{:^11s}'.format(i) for i in ['PropSetID', 'YoungE', 'ShearG2', 'MatDens', 'XsecA', 'XsecAsx', 'XsecAsy', 'XsecJxx', 'XsecJyy', 'XsecJ0']])+'\n') f.write(" ".join(['{:^11s}'.format(i) for i in ['(-)','(N/m2)','(N/m2)','(kg/m3)','(m2)','(m2)','(m2)','(m4)','(m4)','(m4)']])+'\n') for i in range(self.fst_vt['SubDyn']['NXPropSets']): @@ -2095,7 +2098,7 @@ def write_SubDyn(self): f.write('{:<22} {:<11} {:}'.format(self.fst_vt['SubDyn']['OutFmt'], 'OutFmt', '- Output format for numerical results in the .SD.out file\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['SubDyn']['OutSFmt'], 'OutSFmt', '- Output format for header strings in the .SD.out file\n')) f.write('------------------------- MEMBER OUTPUT LIST ------------------------------------------\n') - f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['SubDyn']['NMOutputs'], 'NMOutputs', '- Number of members whose forces/displacements/velocities/accelerations will be output (-) [Must be <= 9].\n')) + f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['SubDyn']['NMOutputs'], 'NMOutputs', '- Number of members whose forces/displacements/velocities/accelerations will be output (-) [Must be <= 99].\n')) f.write(" ".join(['{:^11s}'.format(i) for i in ['MemberID', 'NOutCnt', 'NodeCnt']])+' ! [NOutCnt=how many nodes to get output for [< 10]; NodeCnt are local ordinal numbers from the start of the member, and must be >=1 and <= NDiv+1] If NMOutputs=0 leave blank as well.\n') f.write(" ".join(['{:^11s}'.format(i) for i in ['(-)','(-)','(-)']])+'\n') for i in range(self.fst_vt['SubDyn']['NMOutputs']): @@ -2157,7 +2160,7 @@ def write_ExtPtfm(self): for channel_list in outlist: for i in range(len(channel_list)): f.write('"' + channel_list[i] + '"\n') - f.write('END of input file (the word "END" must appear in the first 3 columns of this last OutList line)\n') + f.write('END of input file (the word "END" must appear in the first 3 columns of the last OutList line)\n') f.flush() os.fsync(f) f.close() @@ -2254,7 +2257,6 @@ def write_MAP(self): ln.append('{:^11d}'.format(self.fst_vt['MAP']['NodeAnch'][i])) ln.append('{:^11d}'.format(self.fst_vt['MAP']['NodeFair'][i])) # ln.append('{:^11}'.format(self.fst_vt['MAP']['Outputs'][i])) - # ln.append('{:^11}'.format(self.fst_vt['MAP']['CtrlChan'][i])) ln.append('{:<11}'.format(" ".join(self.fst_vt['MAP']['Flags'][i]))) f.write(" ".join(ln) + '\n') ln =[] @@ -2517,7 +2519,7 @@ def write_StC(self,StC_vt,StC_filename): row = [x, f_x, y, f_y, z, f_z] f.write(' '.join(['{: 2.8e}'.format(val) for val in row])+'\n') - f.write('---------------------- StructCtrl CONTROL -------------------------------------------- [used only when StC_DOF_MODE=1 or 2]\n') + f.write('---------------------- StructUserProp CONTROL -------------------------------------------- [used only when StC_DOF_MODE=1 or 2]\n') f.write('{:<22} {:<11} {:}'.format(StC_vt['StC_CMODE'], 'StC_CMODE', '- Control mode (switch) {0:none; 1: Semi-Active Control Mode; 2: Active Control Mode}\n')) f.write('{:<22} {:<11} {:}'.format(StC_vt['StC_CChan'], 'StC_CChan', '- Control channel group (1:10) for stiffness and damping (StC_[XYZ]_K, StC_[XYZ]_C, and StC_[XYZ]_Brake) (specify additional channels for blade instances of StC active control -- one channel per blade) [used only when StC_DOF_MODE=1 or 2, and StC_CMODE=4 or 5]\n')) f.write('{:<22} {:<11} {:}'.format(StC_vt['StC_SA_MODE'], 'StC_SA_MODE', '- Semi-Active control mode {1: velocity-based ground hook control; 2: Inverse velocity-based ground hook control; 3: displacement-based ground hook control 4: Phase difference Algorithm with Friction Force 5: Phase difference Algorithm with Damping Force} (-)\n')) diff --git a/openfast_io/openfast_io/FileTools.py b/openfast_io/openfast_io/FileTools.py index 2335314e4..082497b2a 100644 --- a/openfast_io/openfast_io/FileTools.py +++ b/openfast_io/openfast_io/FileTools.py @@ -306,7 +306,7 @@ def cleanup_fstvt(fst_vt, ignoreVars=None, removeFileRef=False, removeArrayProps 'EDFile', 'ServoFile', 'BldFile', - 'SeaStateFile', + 'SeaStFile', 'HydroFile', 'SubFile', 'MooringFile', From 9df86eb70ebb54ab86b9d2f484b2c59abf05871b Mon Sep 17 00:00:00 2001 From: andrew-platt Date: Mon, 23 Dec 2024 23:58:44 -0700 Subject: [PATCH 151/161] Add release notes --- docs/changelogs/v4.0.0.md | 557 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 557 insertions(+) create mode 100644 docs/changelogs/v4.0.0.md diff --git a/docs/changelogs/v4.0.0.md b/docs/changelogs/v4.0.0.md new file mode 100644 index 000000000..224e31dbf --- /dev/null +++ b/docs/changelogs/v4.0.0.md @@ -0,0 +1,557 @@ +**Feature or improvement description** +Pull request to merge `dev` into `main` for release version 4.0.0 + +See the milestone and project pages for additional information + + https://github.com/OpenFAST/openfast/milestone/15 + +Test results, if applicable +See GitHub Actions + +### Release checklist: +- [ ] Review GH projects and Milestones for outstanding items +- [ ] Update the documentation version in docs/conf.py +- [ ] Update the versions in docs/source/user/api_change.rst +- [ ] Verify readthedocs builds correctly +- [ ] Create a merge commit in r-test and add a corresponding annotated tag +- [ ] Update pointer to r-test +- [ ] Merge PR +- [ ] Create release + - [ ] Check "create a discussion" box + - [ ] Create a new tag +- [ ] Compile executables for Windows builds + - [ ] AeroDyn_Driver_x64.exe + - [ ] AeroDyn_Driver_x64_OpenMP.exe + - [ ] AeroDyn_Inflow_C_Binding_x64.dll + - [ ] AeroDyn_Inflow_C_Binding_x64_OpenMP.dll + - [ ] BeamDyn_Driver_x64.exe + - [ ] DISCON.dll (x64) + - [ ] DISCON_ITIBarge.dll (x64) + - [ ] DISCON_OC3Hywind.dll (x64) + - [ ] DISCON_SC.dll (x64) + - [ ] FAST.Farm_x64.exe + - [ ] FAST.Farm_x64_OMP.exe + - [ ] FAST_SFunc.mexw64 + - [ ] HydroDynDriver_x64.exe + - [ ] HydroDyn_C_Binding_x64.dll + - [ ] IfW_C_Binding_x64.dll + - [ ] InflowWind_Driver_x64.exe + - [ ] InflowWind_Driver_x64_OpenMP.exe + - [ ] MoorDyn_Driver_x64.exe + - [ ] MoorDyn_C_Binding_x64.dll + - [ ] OpenFAST-Simulink_x64.dll + - [ ] openfast_x64.exe + - [ ] Turbsim_x64.exe + + + +# Release Overview +------ +This release includes many architectural changes and physics improvements from the OpenFAST 3.5 series. Improvements and new features include large platform yaw dynamics, reduced order structural and aero modules, fluid-structure coupling with _AMR-Wind_, wake-added turbulence for _FAST.Farm_, linearization for MHK turbines, aeromap calculations, an updated Python library for _OpenFAST_ file handling, revised wind and wave data handling, removal of _AeroDyn14_, several new modules, and many bug fixes. The number of changes to input files is very large, so we recommend reviewing the changelog below and notes in https://openfast.readthedocs.io/en/main/source/user/api_change.html for specifics about which files have changes. + + +### Contribution Acknowledgements +Thanks to @bjonkman, @jjonkman, @deslaughter, @luwang00, @RBergua, and @MattEHall for numerous code reviews and suggestions and testing. + +Many thanks to @jjonkman and others for theory development and guidance to developers. + +### Statistics (since 3.5.5) +* Total PR's unique to 4.0.0: 169 +* Total individual code contributors: 27 +* OpenFAST code/docs: 601 files changed, 220202 insertions(+), 445810 deletions(-) +* regression tests: 1587 files changed, 1214606 insertions(+), 537760 deletions(-) + + + +# Changelog +------ + +## General + +### Build systems +There were several updates to the `CMake` and Visual Studio build systems to support code revisions and improve support for compilers such as Flang. + +#### CMake + +#1630 Make CMake module libs STATIC (@bjonkman) + +#1989 Bug: openfastcpp executable is installed to lib directory instead of bin (@deslaughter) + +#1998 switch from -fpic to -fPIC for all gfortran builds (@gbarter) + +#2094 Support cross-compiling with Mingw (MAP++)(@pablo-benito) + +#2133 Remove linking of implicit Fortran libraries (@jrood-nrel) + +#2210 New registry needs C++14 (@deslaughter) + +#2229 CMake: OpenMP turned on only if requested (@andrew-platt) + +#2136 ADI: adilib was getting included in aerodynlib (@andrew-platt) + +#2256 Remove ModVar from dev as ROCm Flang compiler can't build it (@deslaughter) + +#2392 Install also the Map++ API headers (@sanguinariojoe) + +#2442 Fix path to installed MAP include files (@deslaughter) + +#1682 Fix missing symbols for Simulink and LAPACK build (@deslaughter) + + +#### Visual Studio (Windows) + +#1968 VS: update VS build process to include ExtLoads (@andrew-platt) + +#2187 Fix syntax errors in Visual Studio project file for AD driver (@bjonkman) + +#2189 More fixes for Visual Studio (@bjonkman) + +#2327 Remove AD14 from FASTlib Visual Studio project (@bjonkman) + +#2548 Build OpenFAST in Visual Studio 2022 using IFX (@deslaughter) + + + +### Docker + +#2183 Update GHCR doc, remove old Dockerfile (@mayankchetan) + +### Documentation +There were multiple improvements to documentation, notably with _TurbSim_, _SubDyn_l and _HydroDyn_. + +#1664, #1665 TurbSim documentation (@bjonkman) + +#2212 Minor corrections to docs (@andrew-platt) + +#2315, #2336 Update SeaState and HydroDyn user documentation for OpenFAST 4.0 (@luwang00) + +#2366 Fixed typo in docs/source/install/index.rst (@Gjacquenot) + +#2372 SubDyn: Beam Element Formulation documentation (@RBergua) + +#2374 SubDyn documentation: Member Cosine Matrices (@RBergua) + +#2404 Update SubDyn User Documentation to reflect the removed input parameters (@luwang00) + +#2455 HydroDyn user documentation update for large platform rotation (@luwang00) + +#2587 Add release notes from v2.4 - v3.4.1 (@andrew-platt) + + + + +## Solvers + +### FAST.Farm +_FAST.Farm_ received a major upgrade with the addition of background wake-added turbulence effects across the entire farm domain. This improves the turbulence characteristices of propagating turbine wakes. +* Input file changes + +#1624 Use pointers to couple InflowWind and FAST.Farm (@deslaughter) + +#1729 FF: fix plane output for wakedynamics (@ebranlard) + +#2202 Wake-added turbulence in FAST.Farm (@ebranlard, @andrew-platt) + +#2584 Visualization of shared moorings (@andrew-platt) + + +### OpenFAST +Several improvements to the _OpenFAST_ glue code include a major restructuring of the core routines for better integration into CFD, a revised initialization ordering, the addition of logic for new or replaced modules, new data passing for wave and wind data, and bug fixes. Module related updates to logic and restructuring for CFD is included in pull-requests related to those modules. +* Input file changes + +#1610 Remove TurbineType parameter (@hkross) + +#1707 Linear trim solution: add error check (@bjonkman) + +#2076 Move flag for WriteThisStep to `FAST_PreWork` (@bjonkman, @andrew-platt) + +#2078 Minor code cleanup (replace some non-standard Fortran 2003 code) (@bjonkman) + +#2186 [Bug] Writing checkpoint files created empty `fort.#` files (@deslaughter) + +#2219 Turn off "#Restoring here" messages in .out files during linearization visualization sims (@andrew-platt) + +#2338 Vis: Fix bug with vtk writing of non-square wave surface (@andrew-platt) + +#2350 Vis: Fix another bug with vtk writing of non-square wave surface (@luwang00) + +#2431 Enable linearization with MHK turbines (@andrew-platt) + +#2445 ExtInfw: relocate initialization to after `AD_Init` (@andrew-platt) + +#2478 [BugFix] Incorrect value of AirDens passed to `ExtInfw_Init` from `FAST_Subs.f90` (@andrew-platt) + + +### OpenFAST interfaces + +#### OpenFASTcpp +* Interface library changes + +#2245 Fix restart file index and nc write (@ndevelder) + + +#### Simulink + +#1703 Add tests for `FAST_SFunc` using Matlab action to integrate with CI (@deslaughter) + + + +## Modules + +### Multiple +There are several pull requests that affected multiple modules. Important features include the intial development of aeromaps (for controls development), initial development of the reduced order modules of _AeroDisk_ and _Simplefied-ElastoDyn_ (overviews of each below). + + +#1295 Reduced order models: AeroDisk and Simplified-ElastoDyn (SED) (@andrew-platt) + +#1629 MHK: add parameters for readability (@bjonkman) + +#1631 Initial AeroMap changes for ElastoDyn and BeamDyn (@bjonkman) + +#2203 Support for large platform yaw offset in OpenFAST (ED, HD, SD) (@luwang00) + +#2254 Minor changes to FF input descriptions, re-enable test cases, update Simulink string compare (@andrew-platt) + +#2332 Minor bugfix: ED blade file parsing (no PichAxis column), AD warnings (@andrew-platt) + +#2415 Lidar bug fix + other minor changes (@bjonkman) + +#2416 SED+ADsk: update registry comments slightly (@andrew-platt) + + + +### AeroDyn 14 (deprecated, option replaced by AeroDisk) +_AeroDyn14_ has been removed from the code base as it has been superceded by _AeroDyn15_ (now called simply _AeroDyn_) for many years. + +#2267 AeroDyn14 removal (@andrew-platt) + + +### AeroDisk +_AeroDisk_ is a new module for a disk actuator aerodynamic module. This module assumes a rigid disk with only a few degrees of freedom for modeling turbine aerodynamics with a simple actuator disk. This is useful for modeling turbines that are not of interest in very large wind farms modeled by _FAST.Farm_, but whose wake dynamics are needed for turbines further into the wind farm that are of interest. We do not recommend ising this module with standalone _OpenFAST_ simulations. +* New input file + +#2575 ADsk: correction to disk average velocity equations (@andrew-platt) + + + +### AeroDyn (15) +_AeroDyn_ improvements include a new input file, nacelle drag, visualization improvements, unsteady aero for tailfins, multi-rotor support in the driver and interface library, a simple ground effect model for _OLAF_ wakes, using _InflowWind_ pointers for data acces, and many bug fixes. With the removal of _AeroDyn14_, _AeroDyn15_ is now simply referred to as _AeroDyn_ in the input files and code (documentation may not be fully updated). +* Input file changes +* Driver input file changes +* Interface library API changes + +#2428 Single value of TI in AD15 Aeroacoustics (@ptrbortolotti) + +#1596 Use pointers to couple InflowWind and AeroDyn (IfW pointer) (@andrew-platt) + +#1715 AD: Initial AeroMap changes for AeroDyn and misc UA/DBEMT changes (@bjonkman) + +#1882 Remove IfW data from AD15 inputs (@andrew-platt) + +#1909 New AeroDyn input file exposing new BEM options (polar BEM, skew momentum correction, sector averaging) (@ebranlard) + +#1973 Use AD tower diameter for VTK visualization + minor improvements (@bjonkman) + +#2014 Fix linearization with AD15 and IfW (@andrew-platt) + +#2181 AD15: use current wind instead of extrapolated wind (IfW pointer) (@andrew-platt) + +#2283 Aero modifications (many small updates) (@bjonkman) + +#2358 Adding nacelle drag to AeroDyn (@mayankchetan) + +#2425 AD: Bug Fix: Twist in blades 2 and 3 wrong when using Polar BEM (@ebranlard) + +#2427 `DBEMT_Mod = -1` for linearization (@andrew-platt) + +#2429 Fix seg-fault for `DBEMT_Mod=-1` (@andrew-platt) + +#2456 Add safety checks in AirfoilInfo for ill-defined airfoils (@bjonkman) + +#2559 Bug Fix: AD: projection method should now depend on `BEM_Mod` (@ebranlard) + + +#### Unsteady + +#1874 Add unsteady aerodynamic model for turbine tail fin (@abhineet-gupta) + +#1910 Unsteady Aero Driver: adding 3 degrees of freedom for the motion of a genralized airfoil section (@ebranlard) + +#2091 Fix bug in new UA driver (array size) (@bjonkman) + +#2357 Bug Fix: UA driver aero-elastic simulation had wrong sign (@bjonkman) + +#2375 Tail fin aerodynamics: address changes requested in pull request #1874 (@abhineet-gupta) + + +#### OLAF + +#1791 Apply the FakeGroundEffect to all FWspan points (@rcorniglion) + +#2349 [OLAF] Bug Fix: Twist Not Computed in OLAF cases when Polar Projection is used, resulting in wrong Fn, Ft outputs (@ebranlard) + +#2581 OLAF out of bounds (@andrew-platt) + + +#### AeroDyn Driver / AeroDyn\_Inflow\_C\_Bindings interface + +#1784 Multi-rotor support in ADI c-bindings interface (@andrew-platt) + +#2108 Refactored Aerodyn inflow C binding interface to get blade resolved mesh information (@faisal-bhuiyan) + +#2140 ADI: disable OMP in `AeroDyn_Inflow.f90` (@andrew-platt) + +#2287 Bug Fix: AeroDyn driver output files contained wrong channel names (@bjonkman) + +#2370 Correct frequency error in AeroDyn driver prescribed motions (@hkross) + +#2457 Bug: AeroDyn-Inflow WriteOutput Value Ordering (@deslaughter) + +#2470 Add blade distributed load output to AeroDyn-InflowWind C bindings (@deslaughter) + +#2571 Add new routine and variables to init in the `ADI_c_binding` interface (@andrew-platt) + + + +### ElastoDyn +_ElastoDyn_ includes a new yaw friction model, new output channels, several bugfixes, and code cleanup. +* Input file changes + +#2017 Yaw friction implementation (@abhineet-gupta, @kevo331, @rdamiani) + +#1760 Add output channels of linear acceleration relative to g in ElastoDyn + +#1426 Remove references to ADAMS coupling (@hkross) + +#2247 ED: Add inputs for the off-diagonal terms of the platform moment of inertia matrix (@luwang00) + +#2561 ED: Extended yaw-friction modeling (@luwang00) + + + +### ExtInflow (formerly OpenFOAM) +_ExtInflow_ (also called _ExternalInflow_) is the renamed _OpenFOAM_ module. The name change better reflects what this module does as it can couple to more than just the _OpenFOAM_ solver used in _SOWFA_. + +#1687 ExternalInflow: rename files, change names in files (@andrew-platt) + +#2443 Fixes in ExtInflw (heap-buffer-overlow, index flip, empty structure) (@marchdf) + + + +### ExtLoads +_ExtLoads_ is a new module for blade resolved fluid-structure interaction with CFD codes such as _AMR-Wind_. This module is accessed through the CPP interface to OpenFAST. + +#1932, #1946 Blade resolved loads from CFD (@gantech, @deslaughter, @psakievich, @jrood-nrel, @andrew-platt) + +#2001 ExtLoads: move integers from inputs to parameters (@andrew-platt) + +#2009 ExtLoads module: Use pointers for wind (@andrew-platt) + +#2226 Fix turbine indexing on ExtLoads Restart (@ndevelder) + +#2412 ExtLd: require use of InflowWind (@andrew-platt) + + +### HydroDyn +The _HydroDyn_ module was completely restructured with wave dynamics split out into a new module, _SeaState_ (documented below). _HydroDyn_ now accesses wave-field data through a pointer to the data held in the _SeaState_ module. Other improvements include large yaw angle dynamics, bug fixes, and feature enhancements. +* _Major_ input file changes + +#1578 More updates to the Morison module (@luwang00) + +#1609 Use pointers to couple SeaState and HydroDyn (@luwang00) + +#1612 Force the numerical hydrostatic load calculation to use double precision + +#1623 Ensure the estimated intersections between the free surface and the Morison members are treated as under water (@luwang00) + +#1804 Bug Fix with MSL2SWL (@luwang00) + +#1883 HD: Remove extra copy of WaveStMod from Morison (@bjonkman) + +#2031 HD Bug Fix for ExctnDisp and updates to CTestList.cmake with new r-tests (@luwang00) + +#2035 Backward compatibility for the AXIAL COEFFICIENTS section of the HydroDyn input file (@luwang00) + +#2069 HD bug fixes to the inertial loads from marine growth and ballast water on strip-theory members (@luwang00) + +#2073 HD bug fix to the inertial load from ballast water on strip-theory members (@luwang00) + +#2089 HD Bug Fix: Correct the indices of mean drift load components in WAMIT2 (@luwang00) + +#2098 More bug fixes in the WAMIT and WAMIT2 modules of HydroDyn with wave headings (@luwang00) + +#2341 HD: Initialization of the low-pass-filtered displacements of potential-flow bodies when `ExctnDisp = 2` (@luwang00) + +#2356 Fix a bug when reading WAMIT QTF files with multiple wave headings (@getChaos22) + +#2408 HD: Bug fix for potential-flow wave excitation with multiple bodies and large yaw offset (@luwang00) + +#2517 HD bug fix for depth-based axial hydrodynamic coefficients (@luwang00) + +#2444 HD: Reimplement the initialization of low-pass-filtered potential-flow body positions for `ExctnDisp=2` (@luwang00) + + +### InflowWind +The _InflowWind_ module data handling was updated so that _AeroDyn_, _ExtInflow_, and _Lidar_ can retrieve FlowField data through a pointer. The driver was updated to allow the export of VTK slices in XY planes at a chosen elevation from any wind format. This can be useful when visualizing wind flow in an _OpenFAST_ or _FAST.Farm_ simulation. +* Driver input file changes +* library API changes + +#1639 InflowWind pointers in AeroDyn, OpenFOAM (now ExtInflow), and Lidar (@deslaughter) + +#1684 [BugFix] change time handling to double precision for G4D timestep index (@deslaughter) + +#1869 IfW: check that uniform wind file time vector is always increasing (@andrew-platt) + +#2201 IfW: add VTK output of slice in XY to driver (@andrew-platt) + + + +### MAP++ +Several improvements were made to _MAP++_ to allow more modular coupling into other codes. + +#2394 Fixes to Map++ C API (@sanguinariojoe) + +#2405 [BugFix] remove extra summary file write from MAP++ (@sanguinariojoe, @andrew-platt) + +#2420 MAP: change `strncpy` to use macro `MAP_STRNCPY` (@andrew-platt) + + +### MoorDyn +_MoorDyn_ received several new features including coupled pinned bodies, ramping of inertial loads to better handle startup transients, updated body kinematics, linear damping for rod elements, and mooring line failures. Visualization of shared mooring lines for _FAST.Farm_ is also included. +* Input file changes + +#1967 MoorDyn: Coupled Pinned Bodies and bug fixes (@RyanDavies19) + +#1990 MD version update (@RyanDavies19) + +#2005 Removes MD driver standalone option, bug fix on initialization (@RyanDavies19) + +#2243 Initialize mass matrix to zeros in Moordyn (@faisal-bhuiyan) + +#2280 MD: ramp inertial loads during startup transients (@andrew-platt) + +#2294 Add MoorDyn module regression tests (@RyanDavies19) + +#2334 Updating MD Body Kinematics (@RyanDavies19) + +#2342 Linear damping for rod elements in MoorDyn (@RBerguai, with unnamed external contributions) + +#2400 MD: replace "save" variable with logical in MD\_Point (@andrew-platt) + +#2436 MD: Automatically detect the number of header lines in the WaveKin (wave elevation) file (@luwang00) + +#2459 MD: Adding Load dependent dynamic stiffness (@RyanDavies19) + +#2214 Mooring line failures added to MoorDyn (@RyanDavies19) + + +### NWTC-Library +There are a few minor bug fixes for the library. + +#2191 [BugFix] blank line not handled by InitFileInfo (@andrew-platt) + +#2223 SetErrStat referenced incorrectly in VTK.f90 (@andrew-platt) + + +### Registry +The _Registry_ was completely rewritten in C++ (included in #1609) significantly cleaning up the code. New features include pointer handling and new data structures to streamline packing and unpacking for saves/restarts. + +#1618 [BugFix] OpenFAST Registry on Windows (@deslaughter) + +#1625 Add support for pointers in OpenFAST Registry generated Pack and Unpack subroutines (@deslaughter) + +#1919 Use int64 to index arrays for Registry pack/unpack routines (@deslaughter) + +#1986 Save registry structures to file without using a buffer (@deslaughter) + +#2249 Bug in OpenFAST Registry Unpacking Structures with `C_obj` data (@deslaughter) + +#2365 Bugfix for OpenFAST Registry incorrectly restoring pointers in modules with `CObjs` (ExtLd) (@deslaughter, @gantech) + +#2519 Use B4Ki to store array bounds during pack/restore of TurbineType to file (@deslaughter) + + +### SeaState +The _SeaState_ module contains all the wave dynamics previously included within _HydroDyn_. As a standalone module, data is stored in the _WaveField_ data structure which is accessible from other modules through pointers. The first implementation of this code was developed by @HaymanConsulting (#970). +* New input file + +#970 Initial split of HydroDyn into HydroDyn+SeaState (@HaymanConsulting) + - #1008 supercedes this, but GitHub does not show the full history so this is listed here for completeness (#970 was merged through #1008) + +#1008 Additional features for the new SeaState module and HydroDyn (@HaymanConsulting, @bjonkman, @luwang00) + +#1864 Cleanup HydroDyn and SeaState code (@bjonkman) + +#1992 SeaState: fix grid size in wave surface visualization (@andrew-platt) + +#2026 SeaState: combine `SeaSt_Interp` into `SeaSt_WaveField`, and bug fix (@andrew-platt) + +#2071 SeaSt Vis: corrections to PR #1992 (@bjonkman, @andrew-platt) + +#2113 SeaState: replace pointer attribute with allocatable (@bjonkman) + + +### Simplified-ElastoDyn +The _Simplified-ElastoDyn_ moduel (_SED_) is a one degree of freedom rigid structural model useful for cases where a full structural model is not needed (for example, leading turbines in a _FAST.Farm_ simulation). This speeds up computations significantly, but at the expense of accuracy. So it is only recommended that this be used within _FAST.Farm_ for turbines where load calculations are not needed. This is often paired with the _AeroDisk_ module. +* New input file + +#2406 Correct issues with SED (logic lost in prior merge) (@andrew-platt) + + +### SubDyn +_SubDyn_ improvements include a new 6x6 spring element, removal of some stiffness terms for cable pretension, and a few bug fixes. +* Input file changes + +#1889 New spring element in SubDyn: 6 by 6 stiffness matrix (@RBergua) + +#1911 SubDyn summary file: fixes (@RBergua) + +#2363 SD: Comment out the geometric stiffness terms associated with cable pretension to prevent unphysical results (@luwang00) + +#2401 SD: Remove the misleading CBMod input (@luwang00) + +#2458 SD: Bug fix for concentrated mass with CoG offset (@luwang00) + + + +## Testing and input file processing +There were several updates and improvements to the testing system and GitHub actions. + +### openfast_io +This Python based library provides _OpenFAST_ users with library to read and write _OpenFAST_ input files. This library will be able usable for updating input files starting with this release of _OpenFAST_ going forward. This is designed for inclusion in other workflows, such as _WEIS_. + +#2361 Updates to `openfast_io` to match current dev branch API (@mayankchetan) + +#2577 Refactor `openfast/openfast_python/openfast_io/turbsim_file.py` (new entry point) (@Gjacquenot) + + +### GitHub actions + +#2072 GH actions: update matlab-actions version (@andrew-platt) + +#2074 GH actions: remove extraneous "products:" from recipe (added in #2072) (@andrew-platt) + +#2154 GH actions: build docker on release instead of merge (@andrew-platt) + + +### Regression and Unit testing + +#1598 Reduce memory requirements for regression tests after PR #1008 (@andrew-platt) + +#1950 Option to turn off `unit_tests` from cmake (@andrew-platt) + +#2024 Improvements to linearization regression testing (@andrew-platt) + +#2182 Move test `seastate_wavemod5` to after test `seastate_wr_kin1` (@andrew-platt) + +#2250 Add CalcSteady Regression Test (@deslaughter) + +#2276 Replace pFUnit with test-drive for running unit tests (@deslaughter) + +#2329 Remove pfunit as a submodule (@bjonkman) + + + +## Input file changes +This release brings a large number of input file changes and rearrangements with multiple new modules. A partial list of changes can be found here: https://openfast.readthedocs.io/en/main/source/user/api_change.html. However, we recommend that if you start by comparing to the complete set of input files found in the regression tests: https://github.com/OpenFAST/r-test/tree/v4.0.0 (example input files from the regression testing) + From aa6e5ebb3a848516b375e5aed1d8835fb0487453 Mon Sep 17 00:00:00 2001 From: andrew-platt Date: Tue, 24 Dec 2024 01:31:04 -0700 Subject: [PATCH 152/161] Release notes: fix typo --- docs/changelogs/v4.0.0.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/changelogs/v4.0.0.md b/docs/changelogs/v4.0.0.md index 224e31dbf..a1978386a 100644 --- a/docs/changelogs/v4.0.0.md +++ b/docs/changelogs/v4.0.0.md @@ -3,7 +3,7 @@ Pull request to merge `dev` into `main` for release version 4.0.0 See the milestone and project pages for additional information - https://github.com/OpenFAST/openfast/milestone/15 + https://github.com/OpenFAST/openfast/milestone/3 Test results, if applicable See GitHub Actions @@ -234,7 +234,7 @@ _AeroDisk_ is a new module for a disk actuator aerodynamic module. This module -### AeroDyn (15) +### AeroDyn _AeroDyn_ improvements include a new input file, nacelle drag, visualization improvements, unsteady aero for tailfins, multi-rotor support in the driver and interface library, a simple ground effect model for _OLAF_ wakes, using _InflowWind_ pointers for data acces, and many bug fixes. With the removal of _AeroDyn14_, _AeroDyn15_ is now simply referred to as _AeroDyn_ in the input files and code (documentation may not be fully updated). * Input file changes * Driver input file changes @@ -476,7 +476,7 @@ The _SeaState_ module contains all the wave dynamics previously included within * New input file #970 Initial split of HydroDyn into HydroDyn+SeaState (@HaymanConsulting) - - #1008 supercedes this, but GitHub does not show the full history so this is listed here for completeness (#970 was merged through #1008) + - PR 1008 supercedes this, but GitHub does not show the full history so this is listed here for completeness (PR 970 was merged through PR 1008) #1008 Additional features for the new SeaState module and HydroDyn (@HaymanConsulting, @bjonkman, @luwang00) From 45befd62ec2d4da52f6b0ec1a4d41489058a8c99 Mon Sep 17 00:00:00 2001 From: andrew-platt Date: Tue, 24 Dec 2024 01:41:53 -0700 Subject: [PATCH 153/161] Update version numbers for release --- docs/changelogs/v4.0.0.md | 6 ++++-- docs/conf.py | 4 ++-- docs/source/user/api_change.rst | 17 +++++++++-------- 3 files changed, 15 insertions(+), 12 deletions(-) diff --git a/docs/changelogs/v4.0.0.md b/docs/changelogs/v4.0.0.md index a1978386a..dd9412fbe 100644 --- a/docs/changelogs/v4.0.0.md +++ b/docs/changelogs/v4.0.0.md @@ -10,8 +10,10 @@ See GitHub Actions ### Release checklist: - [ ] Review GH projects and Milestones for outstanding items -- [ ] Update the documentation version in docs/conf.py -- [ ] Update the versions in docs/source/user/api_change.rst +- [ ] Update version info + - [ ] Update the documentation version in `docs/conf.py` + - [ ] Update the versions in `docs/source/user/api_change.rst` + - [ ] Update `openfast_io/pyproject.toml` - [ ] Verify readthedocs builds correctly - [ ] Create a merge commit in r-test and add a corresponding annotated tag - [ ] Update pointer to r-test diff --git a/docs/conf.py b/docs/conf.py index ab28d9e41..a298c58f2 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -136,9 +136,9 @@ def runDoxygen(sourcfile, doxyfileIn, doxyfileOut): # built documents. # # The short X.Y version. -version = u'3.5' +version = u'4.0' # The full version, including alpha/beta/rc tags. -release = u'v3.5.5' +release = u'v4.0.0' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/docs/source/user/api_change.rst b/docs/source/user/api_change.rst index 0bb053c49..508876e63 100644 --- a/docs/source/user/api_change.rst +++ b/docs/source/user/api_change.rst @@ -11,14 +11,15 @@ Thus, be sure to implement each in order so that subsequent line numbers are cor -OpenFAST v3.5.5 to OpenFAST dev ----------------------------------- +OpenFAST v3.5.5 to OpenFAST 4.0.0 +--------------------------------- The HydroDyn module was split into HydroDyn and SeaState. This results in a completely new input file for SeaState, and complete revision of the HydroDyn input file. See examples in the regression tests for the new formats. -New modules AeroDisk (see :numref:`ADsk`) and Simplified-ElastoDyn (see :numref:`SED`). +New modules AeroDisk (see :numref:`ADsk`) and Simplified-ElastoDyn (see :numref:`SED`) +were added. See documentation on those modules for exmple input files. ============================================= ======= ==================== ======================================================================================================================================================================================================== Modified in OpenFAST `dev` @@ -28,17 +29,21 @@ Module Line Flag Name Examp OpenFAST 15 CompAero\** 2 CompAero - Compute aerodynamic loads (switch) {0=None; 1=AeroDisk; 2=AeroDyn; 3=ExtLoads} OpenFAST 13 CompElast 3 CompElast - Compute structural dynamics (switch) {1=ElastoDyn; 2=ElastoDyn + BeamDyn for blades; 3=Simplified ElastoDyn} AeroDyn 40 IntegrationMethod 3 IntegrationMethod - Switch to indicate which integration method UA uses (1=RK4, 2=AB4, 3=ABM4, 4=BDF2) +AeroDyn 80\* NacArea 0, 0, 0 NacArea - Projected area of the nacelle in X, Y, Z in the nacelle coordinate system (m^2) +AeroDyn 81\* NacCd 0, 0, 0 NacCd - Drag coefficient for the nacelle areas defined above (-) +AeroDyn 82\* NacDragAC 0, 0, 0 NacDragAC - Position of aerodynamic center of nacelle drag in nacelle coordinates (m) AeroDyn 140\* BldNd_BlOutNd "All" BldNd_BlOutNd - Specify a portion of the nodes to output. {"ALL", "Tip", "Root", or a list of node numbers} (-) AeroDyn Aeroacoustics 11\* TI 0.1 TI - Rotor-incident wind turbulence intensity (-) [Only used if TiCalcMeth == 1] AeroDyn Aeroacoustics 12\* avgV 8 avgV - Average wind speed used to compute the section-incident turbulence intensity (m/s) [Only used if TiCalcMeth == 1] ElastoDyn blade file 15 Removal of the `PitchAxis` input column HydroDyn all Complete restructuring of input file SeaState all New module (split from HydroDyn, so contains some inputs previously found in HydroDyn) +Subdyn 11 --removed-- SubDyn 56\* ----------------------- SPRING ELEMENT PROPERTIES ------------------------------------- SubDyn 57\* NSpringPropSets 0 - Number of spring properties SubDyn 58\* PropSetID k11 k12 k13 k14 k15 k16 k22 k23 k24 k25 k26 k33 k34 k35 k36 k44 k45 k46 k55 k56 k66 SubDyn 59\* (-) (N/m) (N/m) (N/m) (N/rad) (N/rad) (N/rad) (N/m) (N/m) (N/rad) (N/rad) (N/rad) (N/m) (N/rad) (N/rad) (N/rad) (Nm/rad) (Nm/rad) (Nm/rad) (Nm/rad) (Nm/rad) (Nm/rad) -FAST.Farm 16 WrMooringVis true WrMooringVis - Write shared mooring visualization, at DT_Mooring timestep (-) [only used for Mod_SharedMooring=3] +FAST.Farm 16 WrMooringVis true WrMooringVis - Write shared mooring visualization, at DT_Mooring timestep (-) [only used for Mod_SharedMooring=3] FAST.Farm 48 RotorDiamRef 125 RotorDiamRef - Reference turbine rotor diameter for wake calculations (m) [>0.0] FAST.Farm 58 k_vAmb DEFAULT k_vAmb - Calibrated parameters for the influence of the ambient turbulence in the eddy viscosity (set of 5 parameters: k, FMin, DMin, DMax, Exp) (-) [>=0.0, >=0.0 and <=1.0, >=0.0, >DMin, >0.0] or DEFAULT [DEFAULT=0.05, 1.0, 0.0, 1.0, 0.01] FAST.Farm 59 kvShr DEFAULT k_vShr - Calibrated parameters for the influence of the shear layer in the eddy viscosity (set of 5 parameters: k, FMin, DMin, DMax, Exp) (-) [>=0.0, >=0.0 and <=1.0, >=0.0, >DMin, >0.0] or DEFAULT [DEFAULT=0.016, 0.2, 3.0, 25.0, 0.1] @@ -51,10 +56,6 @@ FAST.Farm 76 WAT_DxDyDz 5.0, FAST.Farm 77 WAT_ScaleBox default WAT_ScaleBox - Flag to scale the input turbulence box to zero mean and unit standard deviation at every node [DEFAULT=False] (flag) FAST.Farm 78 WAT_k_Def default WAT_k_Def - Calibrated parameters for the influence of the maximum wake deficit on wake-added turbulence (set of 5 parameters: k_Def, FMin, DMin, DMax, Exp) (-) [>=0.0, >=0.0 and <=1.0, >=0.0, >DMin, >0.0] or DEFAULT [DEFAULT=[0.6, 0.0, 0.0, 2.0, 1.0 ]] FAST.Farm 79 WAT_k_Grad default WAT_k_Grad - Calibrated parameters for the influence of the radial velocity gradient of the wake deficit on wake-added turbulence (set of 5 parameters: k_Grad, FMin, DMin, DMax, Exp) (-) [>=0.0, >=0.0 and <=1.0, >=0.0, >DMin, >0.0] or DEFAULT [DEFAULT=[3.0, 0.0, 0.0, 12.0, 0.65] -AeroDyn 80\* NacArea 0, 0, 0 NacArea - Projected area of the nacelle in X, Y, Z in the nacelle coordinate system (m^2) -AeroDyn 81\* NacCd 0, 0, 0 NacCd - Drag coefficient for the nacelle areas defined above (-) -AeroDyn 82\* NacDragAC 0, 0, 0 NacDragAC - Position of aerodynamic center of nacelle drag in nacelle coordinates (m) -Subdyn 11 --removed-- ============================================= ======= ==================== ======================================================================================================================================================================================================== \*Exact line number depends on number of entries in various preceeding tables. From 9ef28b1b4fd73d4dd914705442db6eda9d526baa Mon Sep 17 00:00:00 2001 From: andrew-platt Date: Tue, 24 Dec 2024 11:32:40 -0700 Subject: [PATCH 154/161] VSbuild: updates to put executables in correct place and remove OMP - ADsk -- remove OMP (not needed) - SED -- remove OMP (not needed) - HD -- correct binary output location - SeaState -- correct binary output location and naming - update PlatformToolSet and TargetPlatformVersion in MAPlib and Registry projects --- vs-build/AeroDisk/AeroDisk_Driver.vfproj | 24 +-- vs-build/HydroDyn/HydroDynDriver.vfproj | 200 +++++++++--------- vs-build/MAPlib/MAP_dll.vcxproj | 13 +- vs-build/Registry/FAST_Registry.vcxproj | 9 +- vs-build/SeaState/SeaStateDriver.vfproj | 14 +- .../SimpleElastoDyn_Driver.vfproj | 24 +-- 6 files changed, 143 insertions(+), 141 deletions(-) diff --git a/vs-build/AeroDisk/AeroDisk_Driver.vfproj b/vs-build/AeroDisk/AeroDisk_Driver.vfproj index db745ceac..ec2307e6c 100644 --- a/vs-build/AeroDisk/AeroDisk_Driver.vfproj +++ b/vs-build/AeroDisk/AeroDisk_Driver.vfproj @@ -5,7 +5,7 @@ - + @@ -15,7 +15,7 @@ - + @@ -25,7 +25,7 @@ - + @@ -35,7 +35,7 @@ - + @@ -45,7 +45,7 @@ - + @@ -55,7 +55,7 @@ - + @@ -65,7 +65,7 @@ - + @@ -75,7 +75,7 @@ - + @@ -93,19 +93,19 @@ - - + + - - + + diff --git a/vs-build/HydroDyn/HydroDynDriver.vfproj b/vs-build/HydroDyn/HydroDynDriver.vfproj index 84f9acfd3..3b057f9d1 100644 --- a/vs-build/HydroDyn/HydroDynDriver.vfproj +++ b/vs-build/HydroDyn/HydroDynDriver.vfproj @@ -24,7 +24,7 @@ - + @@ -44,7 +44,7 @@ - + @@ -54,7 +54,7 @@ - + @@ -93,19 +93,19 @@ - - + + - - + + @@ -117,19 +117,19 @@ - - + + - - + + @@ -141,19 +141,19 @@ - - + + - - + + @@ -165,19 +165,19 @@ - - + + - - + + @@ -187,19 +187,19 @@ - - + + - - + + @@ -211,36 +211,36 @@ - - + + - - + + - - + + - - + + @@ -272,19 +272,19 @@ - - + + - - + + @@ -293,19 +293,19 @@ - - + + - - + + @@ -320,192 +320,192 @@ - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - - + + - - + + + - - + + - - + + - - + + - - + + - - + + - - + + @@ -513,19 +513,19 @@ - - + + - - + + @@ -545,19 +545,19 @@ - - + + - - + + @@ -569,36 +569,36 @@ - - + + - - + + - - + + - - + + diff --git a/vs-build/MAPlib/MAP_dll.vcxproj b/vs-build/MAPlib/MAP_dll.vcxproj index db43418de..4ba5c06d0 100644 --- a/vs-build/MAPlib/MAP_dll.vcxproj +++ b/vs-build/MAPlib/MAP_dll.vcxproj @@ -22,33 +22,34 @@ {BF86702A-CB17-4050-8AE9-078CDC5910D3} Win32Proj MAP_DLL + 10.0 StaticLibrary true Unicode - v140 + v142 StaticLibrary true Unicode - v140 + v142 StaticLibrary false true Unicode - v140 + v142 StaticLibrary false true Unicode - v140 + v142 @@ -75,7 +76,7 @@ MAP_$(PlatformName) true ..\..\build\bin\ -$(PlatformName)\$(ConfigurationName) + $(PlatformName)\$(ConfigurationName) false @@ -86,7 +87,7 @@ MAP_$(PlatformName) false ..\..\build\bin\ -$(PlatformName)\$(ConfigurationName) + $(PlatformName)\$(ConfigurationName) diff --git a/vs-build/Registry/FAST_Registry.vcxproj b/vs-build/Registry/FAST_Registry.vcxproj index 209e8451f..c6b337e3c 100644 --- a/vs-build/Registry/FAST_Registry.vcxproj +++ b/vs-build/Registry/FAST_Registry.vcxproj @@ -22,33 +22,34 @@ {DA16A3A6-3297-4628-9E46-C6FA0E3C4D16} Win32Proj FAST_Registry_c + 10.0 Application true Unicode - v140 + v142 Application true Unicode - v140 + v142 Application false true Unicode - v140 + v142 Application false true Unicode - v140 + v142 diff --git a/vs-build/SeaState/SeaStateDriver.vfproj b/vs-build/SeaState/SeaStateDriver.vfproj index 0170ed9d1..0a2a9283b 100644 --- a/vs-build/SeaState/SeaStateDriver.vfproj +++ b/vs-build/SeaState/SeaStateDriver.vfproj @@ -4,7 +4,7 @@ - + @@ -14,7 +14,7 @@ - + @@ -24,7 +24,7 @@ - + @@ -34,7 +34,7 @@ - + @@ -44,7 +44,7 @@ - + @@ -54,7 +54,7 @@ - + @@ -199,7 +199,6 @@ - @@ -213,6 +212,7 @@ + diff --git a/vs-build/SimpleElastoDyn/SimpleElastoDyn_Driver.vfproj b/vs-build/SimpleElastoDyn/SimpleElastoDyn_Driver.vfproj index 80e3d4e56..4e3f17a83 100644 --- a/vs-build/SimpleElastoDyn/SimpleElastoDyn_Driver.vfproj +++ b/vs-build/SimpleElastoDyn/SimpleElastoDyn_Driver.vfproj @@ -5,7 +5,7 @@ - + @@ -15,7 +15,7 @@ - + @@ -25,7 +25,7 @@ - + @@ -35,7 +35,7 @@ - + @@ -45,7 +45,7 @@ - + @@ -55,7 +55,7 @@ - + @@ -65,7 +65,7 @@ - + @@ -75,7 +75,7 @@ - + @@ -125,19 +125,19 @@ - - + + - - + + From 5fd225a1939dd3780cb5b4a5c5c72dfca0b3b870 Mon Sep 17 00:00:00 2001 From: Andy Platt Date: Tue, 24 Dec 2024 12:39:01 -0700 Subject: [PATCH 155/161] Code review: _Types.f90 file paths in VS build projects Co-authored-by: Bonnie Jonkman --- .../AeroDyn_Inflow_c_binding.vfproj | 20 +++++++++---------- vs-build/SeaState/SeaStateDriver.vfproj | 6 +++--- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/vs-build/AeroDyn_Inflow_c_binding/AeroDyn_Inflow_c_binding.vfproj b/vs-build/AeroDyn_Inflow_c_binding/AeroDyn_Inflow_c_binding.vfproj index 27a5e7006..6a80b4e66 100644 --- a/vs-build/AeroDyn_Inflow_c_binding/AeroDyn_Inflow_c_binding.vfproj +++ b/vs-build/AeroDyn_Inflow_c_binding/AeroDyn_Inflow_c_binding.vfproj @@ -132,17 +132,17 @@ - + - + - + - + - + - + @@ -1000,13 +1000,13 @@ - + - + - + - + diff --git a/vs-build/SeaState/SeaStateDriver.vfproj b/vs-build/SeaState/SeaStateDriver.vfproj index 0a2a9283b..483c4ab25 100644 --- a/vs-build/SeaState/SeaStateDriver.vfproj +++ b/vs-build/SeaState/SeaStateDriver.vfproj @@ -276,11 +276,11 @@ - + - + - + From cb9646c387030047ccc1962bae96bbb0b3a525f1 Mon Sep 17 00:00:00 2001 From: Andy Platt Date: Tue, 24 Dec 2024 12:46:00 -0700 Subject: [PATCH 156/161] Code review: updates to release notes (typos and attribution) Co-authored-by: Lu Wang <83600445+luwang00@users.noreply.github.com> Co-authored-by: Derek Slaughter Co-authored-by: Bonnie Jonkman --- docs/changelogs/v4.0.0.md | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/docs/changelogs/v4.0.0.md b/docs/changelogs/v4.0.0.md index dd9412fbe..d6da7d045 100644 --- a/docs/changelogs/v4.0.0.md +++ b/docs/changelogs/v4.0.0.md @@ -22,6 +22,7 @@ See GitHub Actions - [ ] Check "create a discussion" box - [ ] Create a new tag - [ ] Compile executables for Windows builds + - [ ] AeroDisk_Driver_x64.exe - [ ] AeroDyn_Driver_x64.exe - [ ] AeroDyn_Driver_x64_OpenMP.exe - [ ] AeroDyn_Inflow_C_Binding_x64.dll @@ -43,6 +44,8 @@ See GitHub Actions - [ ] MoorDyn_C_Binding_x64.dll - [ ] OpenFAST-Simulink_x64.dll - [ ] openfast_x64.exe + - [ ] SeaState_driver_x64.exe + - [ ] SimpleElastodyn_driver_x64.exe - [ ] Turbsim_x64.exe @@ -75,7 +78,7 @@ There were several updates to the `CMake` and Visual Studio build systems to sup #### CMake -#1630 Make CMake module libs STATIC (@bjonkman) +#1630 Make CMake module libs STATIC (@deslaughter) #1989 Bug: openfastcpp executable is installed to lib directory instead of bin (@deslaughter) @@ -112,6 +115,7 @@ There were several updates to the `CMake` and Visual Studio build systems to sup #2548 Build OpenFAST in Visual Studio 2022 using IFX (@deslaughter) +#2589 VSbuild: updates for 4.0.0 release (binary output paths, OMP usage) (@andrew-platt) ### Docker @@ -119,7 +123,7 @@ There were several updates to the `CMake` and Visual Studio build systems to sup #2183 Update GHCR doc, remove old Dockerfile (@mayankchetan) ### Documentation -There were multiple improvements to documentation, notably with _TurbSim_, _SubDyn_l and _HydroDyn_. +There were multiple improvements to documentation, notably with _TurbSim_, _SubDyn_, and _HydroDyn_. #1664, #1665 TurbSim documentation (@bjonkman) @@ -145,7 +149,7 @@ There were multiple improvements to documentation, notably with _TurbSim_, _SubD ## Solvers ### FAST.Farm -_FAST.Farm_ received a major upgrade with the addition of background wake-added turbulence effects across the entire farm domain. This improves the turbulence characteristices of propagating turbine wakes. +_FAST.Farm_ received a major upgrade with the addition of background wake-added turbulence effects across the entire farm domain. This improves the turbulence characteristics of propagating turbine wakes. * Input file changes #1624 Use pointers to couple InflowWind and FAST.Farm (@deslaughter) @@ -201,7 +205,7 @@ Several improvements to the _OpenFAST_ glue code include a major restructuring o ## Modules ### Multiple -There are several pull requests that affected multiple modules. Important features include the intial development of aeromaps (for controls development), initial development of the reduced order modules of _AeroDisk_ and _Simplefied-ElastoDyn_ (overviews of each below). +There are several pull requests that affected multiple modules. Important features include the initial development of aeromaps (for controls development), initial development of the reduced order modules of _AeroDisk_ and _Simplified-ElastoDyn_ (overviews of each below). #1295 Reduced order models: AeroDisk and Simplified-ElastoDyn (SED) (@andrew-platt) @@ -223,13 +227,13 @@ There are several pull requests that affected multiple modules. Important featu ### AeroDyn 14 (deprecated, option replaced by AeroDisk) -_AeroDyn14_ has been removed from the code base as it has been superceded by _AeroDyn15_ (now called simply _AeroDyn_) for many years. +_AeroDyn14_ has been removed from the code base as it has been superseded by _AeroDyn15_ (now called simply _AeroDyn_) for many years. #2267 AeroDyn14 removal (@andrew-platt) ### AeroDisk -_AeroDisk_ is a new module for a disk actuator aerodynamic module. This module assumes a rigid disk with only a few degrees of freedom for modeling turbine aerodynamics with a simple actuator disk. This is useful for modeling turbines that are not of interest in very large wind farms modeled by _FAST.Farm_, but whose wake dynamics are needed for turbines further into the wind farm that are of interest. We do not recommend ising this module with standalone _OpenFAST_ simulations. +_AeroDisk_ is a new module for a disk actuator aerodynamic module. This module assumes a rigid disk with only a few degrees of freedom for modeling turbine aerodynamics with a simple actuator disk. This is useful for modeling turbines that are not of interest in very large wind farms modeled by _FAST.Farm_, but whose wake dynamics are needed for turbines further into the wind farm that are of interest. We do not recommend using this module with standalone _OpenFAST_ simulations. * New input file #2575 ADsk: correction to disk average velocity equations (@andrew-platt) @@ -237,7 +241,7 @@ _AeroDisk_ is a new module for a disk actuator aerodynamic module. This module ### AeroDyn -_AeroDyn_ improvements include a new input file, nacelle drag, visualization improvements, unsteady aero for tailfins, multi-rotor support in the driver and interface library, a simple ground effect model for _OLAF_ wakes, using _InflowWind_ pointers for data acces, and many bug fixes. With the removal of _AeroDyn14_, _AeroDyn15_ is now simply referred to as _AeroDyn_ in the input files and code (documentation may not be fully updated). +_AeroDyn_ improvements include a new input file, nacelle drag, visualization improvements, unsteady aero for tailfins, multi-rotor support in the driver and interface library, a simple ground effect model for _OLAF_ wakes, using _InflowWind_ pointers for data access, and many bug fixes. With the removal of _AeroDyn14_, _AeroDyn15_ is now simply referred to as _AeroDyn_ in the input files and code (documentation may not be fully updated). * Input file changes * Driver input file changes * Interface library API changes @@ -321,7 +325,7 @@ _ElastoDyn_ includes a new yaw friction model, new output channels, several bugf #2017 Yaw friction implementation (@abhineet-gupta, @kevo331, @rdamiani) -#1760 Add output channels of linear acceleration relative to g in ElastoDyn +#1760 Add output channels of linear acceleration relative to g in ElastoDyn (@luwang00) #1426 Remove references to ADAMS coupling (@hkross) @@ -336,7 +340,7 @@ _ExtInflow_ (also called _ExternalInflow_) is the renamed _OpenFOAM_ module. Th #1687 ExternalInflow: rename files, change names in files (@andrew-platt) -#2443 Fixes in ExtInflw (heap-buffer-overlow, index flip, empty structure) (@marchdf) +#2443 Fixes in ExtInflw (heap-buffer-overflow, index flip, empty structure) (@marchdf) @@ -362,7 +366,7 @@ The _HydroDyn_ module was completely restructured with wave dynamics split out i #1609 Use pointers to couple SeaState and HydroDyn (@luwang00) -#1612 Force the numerical hydrostatic load calculation to use double precision +#1612 Force the numerical hydrostatic load calculation to use double precision (@luwang00) #1623 Ensure the estimated intersections between the free surface and the Morison members are treated as under water (@luwang00) @@ -436,7 +440,7 @@ _MoorDyn_ received several new features including coupled pinned bodies, ramping #2334 Updating MD Body Kinematics (@RyanDavies19) -#2342 Linear damping for rod elements in MoorDyn (@RBerguai, with unnamed external contributions) +#2342 Linear damping for rod elements in MoorDyn (@RBergua, with contributions from Johyun Kyoung at Front Energies) #2400 MD: replace "save" variable with logical in MD\_Point (@andrew-platt) @@ -456,7 +460,7 @@ There are a few minor bug fixes for the library. ### Registry -The _Registry_ was completely rewritten in C++ (included in #1609) significantly cleaning up the code. New features include pointer handling and new data structures to streamline packing and unpacking for saves/restarts. +The _Registry_ was completely rewritten in C++ (included in #1609, @deslaughter) significantly cleaning up the code. New features include pointer handling and new data structures to streamline packing and unpacking for saves/restarts. #1618 [BugFix] OpenFAST Registry on Windows (@deslaughter) @@ -478,7 +482,7 @@ The _SeaState_ module contains all the wave dynamics previously included within * New input file #970 Initial split of HydroDyn into HydroDyn+SeaState (@HaymanConsulting) - - PR 1008 supercedes this, but GitHub does not show the full history so this is listed here for completeness (PR 970 was merged through PR 1008) + - PR 1008 supersedes this, but GitHub does not show the full history so this is listed here for completeness (PR 970 was merged through PR 1008) #1008 Additional features for the new SeaState module and HydroDyn (@HaymanConsulting, @bjonkman, @luwang00) @@ -494,7 +498,7 @@ The _SeaState_ module contains all the wave dynamics previously included within ### Simplified-ElastoDyn -The _Simplified-ElastoDyn_ moduel (_SED_) is a one degree of freedom rigid structural model useful for cases where a full structural model is not needed (for example, leading turbines in a _FAST.Farm_ simulation). This speeds up computations significantly, but at the expense of accuracy. So it is only recommended that this be used within _FAST.Farm_ for turbines where load calculations are not needed. This is often paired with the _AeroDisk_ module. +The _Simplified-ElastoDyn_ module (_SED_) is a one degree of freedom rigid structural model useful for cases where a full structural model is not needed (for example, leading turbines in a _FAST.Farm_ simulation). This speeds up computations significantly, but at the expense of accuracy. So it is only recommended that this be used within _FAST.Farm_ for turbines where load calculations are not needed. This is often paired with the _AeroDisk_ module. * New input file #2406 Correct issues with SED (logic lost in prior merge) (@andrew-platt) From e973b76cf68077910f974fb03a2c963c6f49cbad Mon Sep 17 00:00:00 2001 From: andrew-platt Date: Tue, 24 Dec 2024 13:27:57 -0700 Subject: [PATCH 157/161] Code review: updates to api_change.rst --- docs/changelogs/v4.0.0.md | 2 +- docs/source/user/api_change.rst | 96 +++++++++++++++++------------ docs/source/user/seastate/index.rst | 2 + 3 files changed, 60 insertions(+), 40 deletions(-) diff --git a/docs/changelogs/v4.0.0.md b/docs/changelogs/v4.0.0.md index d6da7d045..5b0f1f88d 100644 --- a/docs/changelogs/v4.0.0.md +++ b/docs/changelogs/v4.0.0.md @@ -242,7 +242,7 @@ _AeroDisk_ is a new module for a disk actuator aerodynamic module. This module ### AeroDyn _AeroDyn_ improvements include a new input file, nacelle drag, visualization improvements, unsteady aero for tailfins, multi-rotor support in the driver and interface library, a simple ground effect model for _OLAF_ wakes, using _InflowWind_ pointers for data access, and many bug fixes. With the removal of _AeroDyn14_, _AeroDyn15_ is now simply referred to as _AeroDyn_ in the input files and code (documentation may not be fully updated). -* Input file changes +* _Major_ input file changes * Driver input file changes * Interface library API changes diff --git a/docs/source/user/api_change.rst b/docs/source/user/api_change.rst index 508876e63..1b66f6d30 100644 --- a/docs/source/user/api_change.rst +++ b/docs/source/user/api_change.rst @@ -18,45 +18,63 @@ The HydroDyn module was split into HydroDyn and SeaState. This results in a completely new input file for SeaState, and complete revision of the HydroDyn input file. See examples in the regression tests for the new formats. -New modules AeroDisk (see :numref:`ADsk`) and Simplified-ElastoDyn (see :numref:`SED`) -were added. See documentation on those modules for exmple input files. - -============================================= ======= ==================== ======================================================================================================================================================================================================== -Modified in OpenFAST `dev` ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ -Module Line Flag Name Example Value -============================================= ======= ==================== ======================================================================================================================================================================================================== -OpenFAST 15 CompAero\** 2 CompAero - Compute aerodynamic loads (switch) {0=None; 1=AeroDisk; 2=AeroDyn; 3=ExtLoads} -OpenFAST 13 CompElast 3 CompElast - Compute structural dynamics (switch) {1=ElastoDyn; 2=ElastoDyn + BeamDyn for blades; 3=Simplified ElastoDyn} -AeroDyn 40 IntegrationMethod 3 IntegrationMethod - Switch to indicate which integration method UA uses (1=RK4, 2=AB4, 3=ABM4, 4=BDF2) -AeroDyn 80\* NacArea 0, 0, 0 NacArea - Projected area of the nacelle in X, Y, Z in the nacelle coordinate system (m^2) -AeroDyn 81\* NacCd 0, 0, 0 NacCd - Drag coefficient for the nacelle areas defined above (-) -AeroDyn 82\* NacDragAC 0, 0, 0 NacDragAC - Position of aerodynamic center of nacelle drag in nacelle coordinates (m) -AeroDyn 140\* BldNd_BlOutNd "All" BldNd_BlOutNd - Specify a portion of the nodes to output. {"ALL", "Tip", "Root", or a list of node numbers} (-) -AeroDyn Aeroacoustics 11\* TI 0.1 TI - Rotor-incident wind turbulence intensity (-) [Only used if TiCalcMeth == 1] -AeroDyn Aeroacoustics 12\* avgV 8 avgV - Average wind speed used to compute the section-incident turbulence intensity (m/s) [Only used if TiCalcMeth == 1] -ElastoDyn blade file 15 Removal of the `PitchAxis` input column -HydroDyn all Complete restructuring of input file -SeaState all New module (split from HydroDyn, so contains some inputs previously found in HydroDyn) -Subdyn 11 --removed-- -SubDyn 56\* ----------------------- SPRING ELEMENT PROPERTIES ------------------------------------- -SubDyn 57\* NSpringPropSets 0 - Number of spring properties -SubDyn 58\* PropSetID k11 k12 k13 k14 k15 k16 k22 k23 k24 k25 k26 k33 k34 k35 k36 k44 k45 k46 k55 k56 k66 -SubDyn 59\* (-) (N/m) (N/m) (N/m) (N/rad) (N/rad) (N/rad) (N/m) (N/m) (N/rad) (N/rad) (N/rad) (N/m) (N/rad) (N/rad) (N/rad) (Nm/rad) (Nm/rad) (Nm/rad) (Nm/rad) (Nm/rad) (Nm/rad) -FAST.Farm 16 WrMooringVis true WrMooringVis - Write shared mooring visualization, at DT_Mooring timestep (-) [only used for Mod_SharedMooring=3] -FAST.Farm 48 RotorDiamRef 125 RotorDiamRef - Reference turbine rotor diameter for wake calculations (m) [>0.0] -FAST.Farm 58 k_vAmb DEFAULT k_vAmb - Calibrated parameters for the influence of the ambient turbulence in the eddy viscosity (set of 5 parameters: k, FMin, DMin, DMax, Exp) (-) [>=0.0, >=0.0 and <=1.0, >=0.0, >DMin, >0.0] or DEFAULT [DEFAULT=0.05, 1.0, 0.0, 1.0, 0.01] -FAST.Farm 59 kvShr DEFAULT k_vShr - Calibrated parameters for the influence of the shear layer in the eddy viscosity (set of 5 parameters: k, FMin, DMin, DMax, Exp) (-) [>=0.0, >=0.0 and <=1.0, >=0.0, >DMin, >0.0] or DEFAULT [DEFAULT=0.016, 0.2, 3.0, 25.0, 0.1] -FAST.Farm 60-66 --removed-- -FAST.Farm 72 --- WAKE-ADDED TURBULENCE --- -FAST.Farm 73 WAT 2 WAT - Switch between wake-added turbulence box options {0: no wake added turbulence, 1: predefined turbulence box, 2: user defined turbulence box} (switch) -FAST.Farm 74 WAT_BoxFile "../WAT_MannBoxDB/FFDB_D100_512x512x64.u" WAT_BoxFile - Filepath to the file containing the u-component of the turbulence box (either predefined or user-defined) (quoted string) -FAST.Farm 75 WAT_NxNyNz 512, 512, 64 WAT_NxNyNz - Number of points in the x, y, and z directions of the WAT_BoxFile [used only if WAT=2, derived value if WAT=1] (-) -FAST.Farm 76 WAT_DxDyDz 5.0, 5.0, 5.0 WAT_DxDyDz - Distance (in meters) between points in the x, y, and z directions of the WAT_BoxFile [used only if WAT=2, derived value if WAT=1] (m) -FAST.Farm 77 WAT_ScaleBox default WAT_ScaleBox - Flag to scale the input turbulence box to zero mean and unit standard deviation at every node [DEFAULT=False] (flag) -FAST.Farm 78 WAT_k_Def default WAT_k_Def - Calibrated parameters for the influence of the maximum wake deficit on wake-added turbulence (set of 5 parameters: k_Def, FMin, DMin, DMax, Exp) (-) [>=0.0, >=0.0 and <=1.0, >=0.0, >DMin, >0.0] or DEFAULT [DEFAULT=[0.6, 0.0, 0.0, 2.0, 1.0 ]] -FAST.Farm 79 WAT_k_Grad default WAT_k_Grad - Calibrated parameters for the influence of the radial velocity gradient of the wake deficit on wake-added turbulence (set of 5 parameters: k_Grad, FMin, DMin, DMax, Exp) (-) [>=0.0, >=0.0 and <=1.0, >=0.0, >DMin, >0.0] or DEFAULT [DEFAULT=[3.0, 0.0, 0.0, 12.0, 0.65] -============================================= ======= ==================== ======================================================================================================================================================================================================== +New modules AeroDisk (see :numref:`ADsk`), Simplified-ElastoDyn (see +:numref:`SED`), and SeaState (see :numref:`SeaSt`) were added. See +documentation on those modules for exmple input files. + +============================================= ======== ==================== ======================================================================================================================================================================================================== +Modified in OpenFAST `dev` +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ +Module Line Flag Name Example Value +============================================= ======== ==================== ======================================================================================================================================================================================================== +OpenFAST 15 CompAero\** 2 CompAero - Compute aerodynamic loads (switch) {0=None; 1=AeroDisk; 2=AeroDyn; 3=ExtLoads} +OpenFAST 13 CompElast 3 CompElast - Compute structural dynamics (switch) {1=ElastoDyn; 2=ElastoDyn + BeamDyn for blades; 3=Simplified ElastoDyn} +AeroDyn all Complete restructuring of input file (see notes below) +AeroDyn Aeroacoustics 11\* TI 0.1 TI - Rotor-incident wind turbulence intensity (-) [Only used if TiCalcMeth == 1] +AeroDyn Aeroacoustics 12\* avgV 8 avgV - Average wind speed used to compute the section-incident turbulence intensity (m/s) [Only used if TiCalcMeth == 1] +HydroDyn all Complete restructuring of input file +SeaState all New module (split from HydroDyn, so contains some inputs previously found in HydroDyn) +AeroDisk all New module +Simplified-ElastoDyn all New module +ElastoDyn 84 PtfmXYIner 0 PtfmXYIner - Platform xy moment of inertia about the platform CM (=-int(xydm)) (kg m^2) +ElastoDyn 84 PtfmYZIner 0 PtfmYZIner - Platform yz moment of inertia about the platform CM (=-int(yzdm)) (kg m^2) +ElastoDyn 84 PtfmXZIner 0 PtfmXZIner - Platform xz moment of inertia about the platform CM (=-int(xzdm)) (kg m^2) +ElastoDyn 101 ---------------------- YAW-FRICTION -------------------------------------------- +ElastoDyn 102 YawFrctMod 0 YawFrctMod - Yaw-friction model {0: none, 1: friction independent of yaw-bearing force and bending moment, 2: friction with Coulomb terms depending on yaw-bearing force and bending moment... +ElastoDyn 103 M_CSmax 300 M_CSmax - Maximum static Coulomb friction torque (N-m) [M_CSmax when YawFrctMod=1; abs(Fz)*M_CSmax when YawFrctMod=2 and Fz<0] +ElastoDyn 104 M_FCSmax 0 M_FCSmax - Maximum static Coulomb friction torque proportional to yaw bearing shear force (N-m) [sqrt(Fx^2+Fy^2)*M_FCSmax; only used when YawFrctMod=2] +ElastoDyn 105 M_MCSmax 0 M_MCSmax - Maximum static Coulomb friction torque proportional to yaw bearing bending moment (N-m) [sqrt(Mx^2+My^2)*M_MCSmax; only used when YawFrctMod=2] +ElastoDyn 106 M_CD 40 M_CD - Dynamic Coulomb friction moment (N-m) [M_CD when YawFrctMod=1; abs(Fz)*M_CD when YawFrctMod=2 and Fz<0] +ElastoDyn 107 M_FCD 0 M_FCD - Dynamic Coulomb friction moment proportional to yaw bearing shear force (N-m) [sqrt(Fx^2+Fy^2)*M_FCD; only used when YawFrctMod=2] +ElastoDyn 108 M_MCD 0 M_MCD - Dynamic Coulomb friction moment proportional to yaw bearing bending moment (N-m) [sqrt(Mx^2+My^2)*M_MCD; only used when YawFrctMod=2] +ElastoDyn 109 sig_v 0 sig_v - Linear viscous friction coefficient (N-m/(rad/s)) +ElastoDyn 110 sig_v2 0 sig_v2 - Quadratic viscous friction coefficient (N-m/(rad/s)^2) +ElastoDyn 111 OmgCut 0 OmgCut - Yaw angular velocity cutoff below which viscous friction is linearized (rad/s) +ElastoDyn blade file 15 Removal of the `PitchAxis` input column +InflowWind driver 27 ---- Output VTK slices ------------------------------------------------------ +InflowWind driver 28 NOutWindXY 0 NOutWindXY -- Number of XY planes for output .XY.t.vtk (-) [0 to 9] +InflowWind driver 29 OutWindZ 90 OutWindZ -- Z coordinates of XY planes for output (m) [1 to NOutWindXY] [unused for NOutWindXY=0] +MoorDyn -- New optional sections (freeform file). See MoorDyn documentation for details +SubDyn 8 --removed-- removed: GuyanLoadCorrection +SubDyn 12 --removed-- removed: CBMod +SubDyn 56\* ----------------------- SPRING ELEMENT PROPERTIES ------------------------------------- +SubDyn 57\* NSpringPropSets 0 - Number of spring properties +SubDyn 58\* PropSetID k11 k12 k13 k14 k15 k16 k22 k23 k24 k25 k26 k33 k34 k35 k36 k44 k45 k46 k55 k56 k66 +SubDyn 59\* (-) (N/m) (N/m) (N/m) (N/rad) (N/rad) (N/rad) (N/m) (N/m) (N/rad) (N/rad) (N/rad) (N/m) (N/rad) (N/rad) (N/rad) (Nm/rad) (Nm/rad) (Nm/rad) (Nm/rad) (Nm/rad) (Nm/rad) +FAST.Farm 16 WrMooringVis true WrMooringVis - Write shared mooring visualization, at DT_Mooring timestep (-) [only used for Mod_SharedMooring=3] +FAST.Farm 48\* RotorDiamRef 125 RotorDiamRef - Reference turbine rotor diameter for wake calculations (m) [>0.0] +FAST.Farm 53\* k_vAmb DEFAULT k_vAmb - Calibrated parameters for the influence of the ambient turbulence in the eddy viscosity (set of 5 parameters: k, FMin, DMin, DMax, Exp) (-) [>=0.0, >=0.0 and <=1.0, >=0.0, >DMin, >0.0] or DEFAULT [DEFAULT=0.05, 1.0, 0.0, 1.0, 0.01] +FAST.Farm 54\* kvShr DEFAULT k_vShr - Calibrated parameters for the influence of the shear layer in the eddy viscosity (set of 5 parameters: k, FMin, DMin, DMax, Exp) (-) [>=0.0, >=0.0 and <=1.0, >=0.0, >DMin, >0.0] or DEFAULT [DEFAULT=0.016, 0.2, 3.0, 25.0, 0.1] +FAST.Farm 55-62\* --removed-- +FAST.Farm 69\* --- WAKE-ADDED TURBULENCE --- +FAST.Farm 70\* WAT 2 WAT - Switch between wake-added turbulence box options {0: no wake added turbulence, 1: predefined turbulence box, 2: user defined turbulence box} (switch) +FAST.Farm 71\* WAT_BoxFile "../WAT_MannBoxDB/FFDB_D100_512x512x64.u" WAT_BoxFile - Filepath to the file containing the u-component of the turbulence box (either predefined or user-defined) (quoted string) +FAST.Farm 72\* WAT_NxNyNz 512, 512, 64 WAT_NxNyNz - Number of points in the x, y, and z directions of the WAT_BoxFile [used only if WAT=2, derived value if WAT=1] (-) +FAST.Farm 73\* WAT_DxDyDz 5.0, 5.0, 5.0 WAT_DxDyDz - Distance (in meters) between points in the x, y, and z directions of the WAT_BoxFile [used only if WAT=2, derived value if WAT=1] (m) +FAST.Farm 74\* WAT_ScaleBox default WAT_ScaleBox - Flag to scale the input turbulence box to zero mean and unit standard deviation at every node [DEFAULT=False] (flag) +FAST.Farm 75\* WAT_k_Def default WAT_k_Def - Calibrated parameters for the influence of the maximum wake deficit on wake-added turbulence (set of 5 parameters: k_Def, FMin, DMin, DMax, Exp) (-) [>=0.0, >=0.0 and <=1.0, >=0.0, >DMin, >0.0] or DEFAULT [DEFAULT=[0.6, 0.0, 0.0, 2.0, 1.0 ]] +FAST.Farm 76\* WAT_k_Grad default WAT_k_Grad - Calibrated parameters for the influence of the radial velocity gradient of the wake deficit on wake-added turbulence (set of 5 parameters: k_Grad, FMin, DMin, DMax, Exp) (-) [>=0.0, >=0.0 and <=1.0, >=0.0, >DMin, >0.0] or DEFAULT [DEFAULT=[3.0, 0.0, 0.0, 12.0, 0.65] +============================================= ======== ==================== ======================================================================================================================================================================================================== \*Exact line number depends on number of entries in various preceeding tables. diff --git a/docs/source/user/seastate/index.rst b/docs/source/user/seastate/index.rst index b0dd44c04..1a24d5905 100644 --- a/docs/source/user/seastate/index.rst +++ b/docs/source/user/seastate/index.rst @@ -1,3 +1,5 @@ +.. _SeaSt: + SeaState User Guide and Theory Manual ===================================== From 3fb2212652f7768cda18b9de6968e23b67beb175 Mon Sep 17 00:00:00 2001 From: andrew-platt Date: Tue, 24 Dec 2024 13:33:06 -0700 Subject: [PATCH 158/161] Code review: more updates to api_change.rst --- docs/source/user/api_change.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/source/user/api_change.rst b/docs/source/user/api_change.rst index 1b66f6d30..91cd6f098 100644 --- a/docs/source/user/api_change.rst +++ b/docs/source/user/api_change.rst @@ -27,8 +27,10 @@ Modified in OpenFAST `dev` ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ Module Line Flag Name Example Value ============================================= ======== ==================== ======================================================================================================================================================================================================== -OpenFAST 15 CompAero\** 2 CompAero - Compute aerodynamic loads (switch) {0=None; 1=AeroDisk; 2=AeroDyn; 3=ExtLoads} OpenFAST 13 CompElast 3 CompElast - Compute structural dynamics (switch) {1=ElastoDyn; 2=ElastoDyn + BeamDyn for blades; 3=Simplified ElastoDyn} +OpenFAST 15 CompAero\** 2 CompAero - Compute aerodynamic loads (switch) {0=None; 1=AeroDisk; 2=AeroDyn; 3=ExtLoads} +OpenFAST 17 CompSeaSt 0 CompSeaSt - Compute sea state information (switch) {0=None; 1=SeaState} +OpenFAST 41 SeaStFile "unused" SeaStFile - Name of file containing sea state input parameters (quoted string) AeroDyn all Complete restructuring of input file (see notes below) AeroDyn Aeroacoustics 11\* TI 0.1 TI - Rotor-incident wind turbulence intensity (-) [Only used if TiCalcMeth == 1] AeroDyn Aeroacoustics 12\* avgV 8 avgV - Average wind speed used to compute the section-incident turbulence intensity (m/s) [Only used if TiCalcMeth == 1] From 0eecbc9d5228e949f4777f9e877f5925ab1df7c8 Mon Sep 17 00:00:00 2001 From: Andy Platt Date: Tue, 24 Dec 2024 13:51:58 -0700 Subject: [PATCH 159/161] Code review: updates to release notes, missing information --- docs/changelogs/v4.0.0.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/changelogs/v4.0.0.md b/docs/changelogs/v4.0.0.md index 5b0f1f88d..b7254dd88 100644 --- a/docs/changelogs/v4.0.0.md +++ b/docs/changelogs/v4.0.0.md @@ -52,7 +52,7 @@ See GitHub Actions # Release Overview ------ -This release includes many architectural changes and physics improvements from the OpenFAST 3.5 series. Improvements and new features include large platform yaw dynamics, reduced order structural and aero modules, fluid-structure coupling with _AMR-Wind_, wake-added turbulence for _FAST.Farm_, linearization for MHK turbines, aeromap calculations, an updated Python library for _OpenFAST_ file handling, revised wind and wave data handling, removal of _AeroDyn14_, several new modules, and many bug fixes. The number of changes to input files is very large, so we recommend reviewing the changelog below and notes in https://openfast.readthedocs.io/en/main/source/user/api_change.html for specifics about which files have changes. +This release includes many architectural changes and physics improvements from the OpenFAST 3.5 series. Improvements and new features include large platform yaw dynamics, reduced order structural and aero modules (_Simplified-ElastoDyn_ (SED) and _AeroDisk_ (ADsk)), fluid-structure coupling with _AMR-Wind_, wake-added turbulence for _FAST.Farm_, linearization for MHK turbines, aeromap calculations, an updated Python library for _OpenFAST_ file handling, revised wind and wave data handling, removal of _AeroDyn14_, many hydrodynamic improvements including the splitting of the wave field (new _SeaState_ (SS) module) from HydroDyn, and many bug fixes. The number of changes to input files is very large, so we recommend reviewing the changelog below and notes in https://openfast.readthedocs.io/en/main/source/user/api_change.html for specifics about which files have changes. ### Contribution Acknowledgements @@ -320,7 +320,7 @@ _AeroDyn_ improvements include a new input file, nacelle drag, visualization imp ### ElastoDyn -_ElastoDyn_ includes a new yaw friction model, new output channels, several bugfixes, and code cleanup. +_ElastoDyn_ includes a new yaw friction model, new output channels, new platform cross-inertia terms, several bugfixes, and code cleanup. * Input file changes #2017 Yaw friction implementation (@abhineet-gupta, @kevo331, @rdamiani) @@ -359,7 +359,7 @@ _ExtLoads_ is a new module for blade resolved fluid-structure interaction with C ### HydroDyn -The _HydroDyn_ module was completely restructured with wave dynamics split out into a new module, _SeaState_ (documented below). _HydroDyn_ now accesses wave-field data through a pointer to the data held in the _SeaState_ module. Other improvements include large yaw angle dynamics, bug fixes, and feature enhancements. +The _HydroDyn_ module was completely restructured with wave dynamics split out into a new module, _SeaState_ (documented below). _HydroDyn_ now accesses wave-field data through a pointer to the data held in the _SeaState_ module. Other improvements include large yaw angle dynamics, wave loads at the displaced position in surge/sway, MacCamy-Fuchs diffraction for strip-theory members, wave stretching (various models) with load smoothing, constrained New Wave theory, new strip-theory hydrostatic solution valid for near-horizontal members at the free surface, and bug fixes. * _Major_ input file changes #1578 More updates to the Morison module (@luwang00) @@ -505,7 +505,7 @@ The _Simplified-ElastoDyn_ module (_SED_) is a one degree of freedom rigid struc ### SubDyn -_SubDyn_ improvements include a new 6x6 spring element, removal of some stiffness terms for cable pretension, and a few bug fixes. +_SubDyn_ improvements include a new 6x6 spring element, removal of some stiffness terms for cable pretension, a few bug fixes, and code cleanup. * Input file changes #1889 New spring element in SubDyn: 6 by 6 stiffness matrix (@RBergua) From 1b88c3c52af03cafc5f30fcd9c8274b1cc0711e8 Mon Sep 17 00:00:00 2001 From: Andy Platt Date: Tue, 24 Dec 2024 14:11:22 -0700 Subject: [PATCH 160/161] Code review: updates to release notes, missing information Co-authored-by: jjonkman --- docs/changelogs/v4.0.0.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/changelogs/v4.0.0.md b/docs/changelogs/v4.0.0.md index b7254dd88..b84e6f493 100644 --- a/docs/changelogs/v4.0.0.md +++ b/docs/changelogs/v4.0.0.md @@ -123,7 +123,7 @@ There were several updates to the `CMake` and Visual Studio build systems to sup #2183 Update GHCR doc, remove old Dockerfile (@mayankchetan) ### Documentation -There were multiple improvements to documentation, notably with _TurbSim_, _SubDyn_, and _HydroDyn_. +There were multiple improvements to documentation, notably with _TurbSim_, _SubDyn_, _HydroDyn_, and _SeaState_. #1664, #1665 TurbSim documentation (@bjonkman) @@ -149,7 +149,7 @@ There were multiple improvements to documentation, notably with _TurbSim_, _SubD ## Solvers ### FAST.Farm -_FAST.Farm_ received a major upgrade with the addition of background wake-added turbulence effects across the entire farm domain. This improves the turbulence characteristics of propagating turbine wakes. +_FAST.Farm_ received a major upgrade with the addition of wake-added turbulence effects across the entire farm domain. This improves the turbulence characteristics of propagating turbine wakes. * Input file changes #1624 Use pointers to couple InflowWind and FAST.Farm (@deslaughter) @@ -233,7 +233,7 @@ _AeroDyn14_ has been removed from the code base as it has been superseded by _Ae ### AeroDisk -_AeroDisk_ is a new module for a disk actuator aerodynamic module. This module assumes a rigid disk with only a few degrees of freedom for modeling turbine aerodynamics with a simple actuator disk. This is useful for modeling turbines that are not of interest in very large wind farms modeled by _FAST.Farm_, but whose wake dynamics are needed for turbines further into the wind farm that are of interest. We do not recommend using this module with standalone _OpenFAST_ simulations. +_AeroDisk_ is a new module for a disk actuator aerodynamic module for modeling turbine aerodynamics as a simple actuator disk. This module assumes that the rotor is a rigid disk, and so, should be not be combined with _BeamDyn_ or _ElastoDyn_ with blade degrees of freedom enabled; it is meant to be used with the new _Simplified-ElastoDyn_ module. This is useful for modeling turbines that are not of interest in very large wind farms modeled by _FAST.Farm_, but whose wake dynamics are needed for turbines further into the wind farm that are of interest. We do not recommend using this module with standalone _OpenFAST_ simulations. * New input file #2575 ADsk: correction to disk average velocity equations (@andrew-platt) @@ -241,7 +241,7 @@ _AeroDisk_ is a new module for a disk actuator aerodynamic module. This module ### AeroDyn -_AeroDyn_ improvements include a new input file, nacelle drag, visualization improvements, unsteady aero for tailfins, multi-rotor support in the driver and interface library, a simple ground effect model for _OLAF_ wakes, using _InflowWind_ pointers for data access, and many bug fixes. With the removal of _AeroDyn14_, _AeroDyn15_ is now simply referred to as _AeroDyn_ in the input files and code (documentation may not be fully updated). +_AeroDyn_ improvements include a new input file, new options in BEM to improve aerodynamics for skewed and sheared inflow and coned rotors, nacelle drag, visualization improvements, unsteady aero for tailfins, an improved unsteady airfoil aerodynamics driver, multi-rotor support in the interface library, a simple ground effect model for _OLAF_ wakes, using _InflowWind_ pointers for data access, and many bug fixes. With the removal of _AeroDyn14_, _AeroDyn15_ is now simply referred to as _AeroDyn_ in the input files and code (documentation may not be fully updated). * _Major_ input file changes * Driver input file changes * Interface library API changes From daa0f436d3fd7ac336dd6e0ab2be003508a3618c Mon Sep 17 00:00:00 2001 From: andrew-platt Date: Tue, 24 Dec 2024 14:17:40 -0700 Subject: [PATCH 161/161] Update r-test pointer for 4.0.0 release --- reg_tests/r-test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reg_tests/r-test b/reg_tests/r-test index a35863f48..f78149f37 160000 --- a/reg_tests/r-test +++ b/reg_tests/r-test @@ -1 +1 @@ -Subproject commit a35863f48ab8d54bf518e51c8aaec66458b4124d +Subproject commit f78149f37477c23b5780d0cb52c198713a96330f