From 97f3fd36e7d028f7f43d0f5877a62b3abae55cac Mon Sep 17 00:00:00 2001 From: dzalkind Date: Thu, 1 Aug 2024 14:24:53 -0600 Subject: [PATCH] Add latest ED and AD changes in OF dev --- weis/aeroelasticse/FAST_reader.py | 22 ++++++++++++++++++---- weis/aeroelasticse/FAST_writer.py | 20 +++++++++++++++++--- 2 files changed, 35 insertions(+), 7 deletions(-) diff --git a/weis/aeroelasticse/FAST_reader.py b/weis/aeroelasticse/FAST_reader.py index fe32d8d57..c86126ed8 100644 --- a/weis/aeroelasticse/FAST_reader.py +++ b/weis/aeroelasticse/FAST_reader.py @@ -371,6 +371,9 @@ def read_ElastoDyn(self, ed_file): self.fst_vt['ElastoDyn']['PtfmRIner'] = float_read(f.readline().split()[0]) self.fst_vt['ElastoDyn']['PtfmPIner'] = float_read(f.readline().split()[0]) self.fst_vt['ElastoDyn']['PtfmYIner'] = float_read(f.readline().split()[0]) + self.fst_vt['ElastoDyn']['PtfmXYIner'] = float_read(f.readline().split()[0]) + self.fst_vt['ElastoDyn']['PtfmYZIner'] = float_read(f.readline().split()[0]) + self.fst_vt['ElastoDyn']['PtfmXZIner'] = float_read(f.readline().split()[0]) # ElastoDyn Blade (blade_struc) f.readline() @@ -852,11 +855,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]) @@ -871,10 +872,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]) @@ -882,6 +889,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 @@ -895,6 +908,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]) diff --git a/weis/aeroelasticse/FAST_writer.py b/weis/aeroelasticse/FAST_writer.py index 5f36502af..a509a1b7f 100644 --- a/weis/aeroelasticse/FAST_writer.py +++ b/weis/aeroelasticse/FAST_writer.py @@ -368,6 +368,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')) @@ -789,11 +792,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')) @@ -805,8 +806,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')) @@ -814,6 +820,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')) @@ -821,6 +834,7 @@ 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']: