Skip to content

Commit

Permalink
Fix connections to drivese_post with WISDEM 3.17 (#317)
Browse files Browse the repository at this point in the history
* Fix connections to drivese_post

* Set run directories relative to input files

* Get member ids from modopts

* Tidy OC3 example

* Re-enable testing of OC3 spar

* Send aero-only hub loads to WISDEM

* Disable potential flow modeling for fixed substructures

* Disable second tower mode in OC3 example for now
  • Loading branch information
dzalkind authored Nov 8, 2024
1 parent f779fa5 commit f24a213
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 21 deletions.
6 changes: 2 additions & 4 deletions examples/03_NREL5MW_OC3_spar/modeling_options.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ General:
verbosity: False # When set to True, the code prints to screen many infos
openfast_configuration:
OF_run_fst: NREL5MW_OC3_spar
OF_run_dir: outputs/03_NREL5MW_OC3_spar
use_exe: True

WISDEM:
Expand All @@ -18,7 +17,6 @@ WISDEM:
flag: True
FloatingSE:
flag: True
rank_and_file: True
BOS:
flag: True

Expand Down Expand Up @@ -55,9 +53,9 @@ Level3: # Options for WEIS fidelity level 3 = nonlinear time domain
GenDOF: True
YawDOF: False
TwFADOF1 : True
TwFADOF2 : True
TwFADOF2 : False
TwSSDOF1 : True
TwSSDOF2 : True
TwSSDOF2 : False
PtfmSgDOF: True
PtfmSwDOF: True
PtfmHvDOF: True
Expand Down
26 changes: 21 additions & 5 deletions weis/aeroelasticse/openmdao_openfast.py
Original file line number Diff line number Diff line change
Expand Up @@ -365,9 +365,9 @@ def setup(self):
OFmgmt = modopt['General']['openfast_configuration']
self.model_only = OFmgmt['model_only']
FAST_directory_base = OFmgmt['OF_run_dir']
# If the path is relative, make it an absolute path to current working directory
# If the path is relative, make it an absolute path to modeling options file
if not os.path.isabs(FAST_directory_base):
FAST_directory_base = os.path.join(os.getcwd(), FAST_directory_base)
FAST_directory_base = os.path.join(os.path.dirname(modopt['fname_input_modeling']), FAST_directory_base)
# Flag to clear OpenFAST run folder. Use it only if disk space is an issue
self.clean_FAST_directory = False
self.FAST_InputFile = OFmgmt['OF_run_fst']
Expand Down Expand Up @@ -472,6 +472,8 @@ def setup(self):
# Hub outputs
self.add_output('hub_Fxyz', val=np.zeros(3), units='kN', desc = 'Maximum hub forces in the non rotating frame')
self.add_output('hub_Mxyz', val=np.zeros(3), units='kN*m', desc = 'Maximum hub moments in the non rotating frame')
self.add_output('hub_Fxyz_aero', val=np.zeros(3), units='N', desc = 'Aero-only maximum hub forces in the non rotating frame')
self.add_output('hub_Mxyz_aero', val=np.zeros(3), units='N*m', desc = 'Aero-only maximum hub moments in the non rotating frame')

self.add_output('max_TwrBsMyt',val=0.0, units='kN*m', desc='maximum of tower base bending moment in fore-aft direction')
self.add_output('max_TwrBsMyt_ratio',val=0.0, desc='ratio of maximum of tower base bending moment in fore-aft direction to maximum allowable bending moment')
Expand Down Expand Up @@ -1428,8 +1430,10 @@ def update_FAST_model(self, fst_vt, inputs, discrete_inputs):
else:
PropPotBool = [False] * fst_vt['HydroDyn']['NMembers']
for k in range(fst_vt['HydroDyn']['NMembers']):
idx = discrete_inputs['platform_elem_memid'][k]
PropPotBool[k] = modopt["Level1"]["model_potential"][idx]
# Potential modeling of fixed substructres not supported
if modopt['flags']['floating']:
idx = modopt['floating']['members']['platform_elem_memid'][k]
PropPotBool[k] = modopt["Level1"]["model_potential"][idx]
fst_vt['HydroDyn']['PropPot'] = PropPotBool

if fst_vt['HydroDyn']['NBody'] > 1:
Expand Down Expand Up @@ -1651,6 +1655,7 @@ def output_channels(self,fst_vt):
channels_out += ["Spn1MLxb3", "Spn2MLxb3", "Spn3MLxb3", "Spn4MLxb3", "Spn5MLxb3", "Spn6MLxb3", "Spn7MLxb3", "Spn8MLxb3", "Spn9MLxb3"]
channels_out += ["Spn1MLyb3", "Spn2MLyb3", "Spn3MLyb3", "Spn4MLyb3", "Spn5MLyb3", "Spn6MLyb3", "Spn7MLyb3", "Spn8MLyb3", "Spn9MLyb3"]
channels_out += ["RtFldCp", "RtFldCt"]
channels_out += ["RtFldFxh", "RtFldFyh", "RtFldFzh", "RtFldMxh", "RtFldMyh", "RtFldMzh"]
channels_out += ["RotSpeed", "GenSpeed", "NacYaw", "Azimuth"]
channels_out += ["GenPwr", "GenTq", "BldPitch1", "BldPitch2", "BldPitch3"]
channels_out += ["Wind1VelX", "Wind1VelY", "Wind1VelZ"]
Expand All @@ -1663,7 +1668,6 @@ def output_channels(self,fst_vt):
channels_out += ["TwHt1MLxt", "TwHt2MLxt", "TwHt3MLxt", "TwHt4MLxt", "TwHt5MLxt", "TwHt6MLxt", "TwHt7MLxt", "TwHt8MLxt", "TwHt9MLxt"]
channels_out += ["TwHt1MLyt", "TwHt2MLyt", "TwHt3MLyt", "TwHt4MLyt", "TwHt5MLyt", "TwHt6MLyt", "TwHt7MLyt", "TwHt8MLyt", "TwHt9MLyt"]
channels_out += ["TwHt1MLzt", "TwHt2MLzt", "TwHt3MLzt", "TwHt4MLzt", "TwHt5MLzt", "TwHt6MLzt", "TwHt7MLzt", "TwHt8MLzt", "TwHt9MLzt"]
channels_out += ["RtFldFxh", "RtFldFyh", "RtFldFzh"]
channels_out += ["RotThrust", "LSShftFxs", "LSShftFys", "LSShftFzs", "LSShftFxa", "LSShftFya", "LSShftFza"]
channels_out += ["RotTorq", "LSSTipMxs", "LSSTipMys", "LSSTipMzs", "LSSTipMxa", "LSSTipMya", "LSSTipMza"]
channels_out += ["B1N1Alpha", "B1N2Alpha", "B1N3Alpha", "B1N4Alpha", "B1N5Alpha", "B1N6Alpha", "B1N7Alpha", "B1N8Alpha", "B1N9Alpha", "B2N1Alpha", "B2N2Alpha", "B2N3Alpha", "B2N4Alpha", "B2N5Alpha", "B2N6Alpha", "B2N7Alpha", "B2N8Alpha","B2N9Alpha"]
Expand Down Expand Up @@ -2097,6 +2101,10 @@ def run_FAST(self, inputs, discrete_inputs, fst_vt):
else:
magnitude_channels[f'LSShft{s}{k}{x}a'] = ['LSShftFya', 'LSShftFza'] if ik==0 else ['LSSTipMya', 'LSSTipMza']

# Aero-only hub loads
magnitude_channels["RtFldF"] = ["RtFldFxh", "RtFldFyh", "RtFldFzh"]
magnitude_channels["RtFldM"] = ["RtFldMxh", "RtFldMyh", "RtFldMzh"]

# Fatigue at the tower base
# Convert ultstress and S_intercept values to kPa with 1e-3 factor
tower_fatigue_base = FatigueParams(load2stress=1.0,
Expand Down Expand Up @@ -2279,6 +2287,14 @@ def get_blade_loading(self, sum_stats, extreme_table, inputs, discrete_inputs, o
outputs['hub_Mxyz'] = np.array([extreme_table['LSShftM'][np.argmax(sum_stats['LSShftM']['max'])]['RotTorq'],
extreme_table['LSShftM'][np.argmax(sum_stats['LSShftM']['max'])]['LSSTipMys'],
extreme_table['LSShftM'][np.argmax(sum_stats['LSShftM']['max'])]['LSSTipMzs']])*1.e3

# Aero-only for WISDEM (outputs are in N and N-m)
outputs['hub_Fxyz_aero'] = np.array([extreme_table['RtFldF'][np.argmax(sum_stats['RtFldF']['max'])]['RtFldFxh'],
extreme_table['RtFldF'][np.argmax(sum_stats['RtFldF']['max'])]['RtFldFyh'],
extreme_table['RtFldF'][np.argmax(sum_stats['RtFldF']['max'])]['RtFldFzh']])
outputs['hub_Mxyz_aero'] = np.array([extreme_table['RtFldM'][np.argmax(sum_stats['RtFldM']['max'])]['RtFldMxh'],
extreme_table['RtFldM'][np.argmax(sum_stats['RtFldM']['max'])]['RtFldMyh'],
extreme_table['RtFldM'][np.argmax(sum_stats['RtFldM']['max'])]['RtFldMzh']])

## Post process aerodynamic data
# Angles of attack - max, std, mean
Expand Down
21 changes: 12 additions & 9 deletions weis/glue_code/gc_LoadInputs.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,17 @@ def set_weis_data(self):
# Directory of modeling option input, if we want to use it for relative paths
mod_opt_dir = osp.split(self.modeling_options['fname_input_modeling'])[0]

# OpenFAST prefixes
if self.modeling_options['General']['openfast_configuration']['OF_run_fst'] in ['','None','NONE','none']:
self.modeling_options['General']['openfast_configuration']['OF_run_fst'] = 'weis_job'

if self.modeling_options['General']['openfast_configuration']['OF_run_dir'] in ['','None','NONE','none']:
self.modeling_options['General']['openfast_configuration']['OF_run_dir'] = osp.join(
mod_opt_dir, # If it's a relative path, will be relative to mod_opt directory
self.analysis_options['general']['folder_output'],
'openfast_runs'
)

# BEM dir, all levels
base_run_dir = os.path.join(mod_opt_dir,self.modeling_options['General']['openfast_configuration']['OF_run_dir'])
if MPI:
Expand All @@ -78,15 +89,7 @@ def set_weis_data(self):
self.modeling_options['General']['openfast_configuration']['fst_vt'] = {}
self.modeling_options['General']['openfast_configuration']['fst_vt']['outlist'] = fast.fst_vt['outlist']

# OpenFAST prefixes
if self.modeling_options['General']['openfast_configuration']['OF_run_fst'] in ['','None','NONE','none']:
self.modeling_options['General']['openfast_configuration']['OF_run_fst'] = 'weis_job'

if self.modeling_options['General']['openfast_configuration']['OF_run_dir'] in ['','None','NONE','none']:
self.modeling_options['General']['openfast_configuration']['OF_run_dir'] = osp.join(
self.analysis_options['general']['folder_output'],
'openfast_runs'
)


# User-defined control dylib (path2dll)
path2dll = self.modeling_options['General']['openfast_configuration']['path2dll']
Expand Down
4 changes: 2 additions & 2 deletions weis/glue_code/glue_code.py
Original file line number Diff line number Diff line change
Expand Up @@ -676,8 +676,8 @@ def setup(self):
self.connect('rotorse.rp.powercurve.rated_Q', 'drivese_post.rated_torque')
self.connect('configuration.rated_power', 'drivese_post.machine_rating')
self.connect('tower.diameter', 'drivese_post.D_top', src_indices=[-1])
self.connect('aeroelastic.hub_Fxyz', 'drivese_post.F_hub')
self.connect('aeroelastic.hub_Mxyz', 'drivese_post.M_hub')
self.connect('aeroelastic.hub_Fxyz_aero', 'drivese_post.F_aero_hub')
self.connect('aeroelastic.hub_Mxyz_aero', 'drivese_post.M_aero_hub')
self.connect('aeroelastic.max_RootMyb', 'drivese_post.pitch_system.BRFM')
self.connect('blade.pa.chord_param', 'drivese_post.blade_root_diameter', src_indices=[0])
self.connect('rotorse.blade_mass', 'drivese_post.blade_mass')
Expand Down
2 changes: 1 addition & 1 deletion weis/test/run_examples.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"01_aeroelasticse/run_OLAF",
"01_aeroelasticse/run_nodalOutputs",
"02_run_openfast_cases/weis_driver_loads",
#"03_NREL5MW_OC3_spar/weis_driver", # executed in the test_OC3.py
"03_NREL5MW_OC3_spar/weis_driver",
# "03_NREL5MW_OC3_spar/weis_freq_driver", # executed in examples_skinny
# "04_NREL5MW_OC4_semi/weis_driver", # skipping until we resolve multiple variable ballasts
"04_NREL5MW_OC4_semi/weis_freq_driver",
Expand Down

0 comments on commit f24a213

Please sign in to comment.