def test_wind_class_4(self): # Edge case test (i.e. data with many nans) for Wind.get_bin_probabilities file = 'tests/test_data//test_winddata_overflow.txt' wind_data = windbins.get_wind_data(file) wind = windbins.Wind(wind_data) bin_probabilities = wind.get_bin_probabilities() compare_bin_probabilities = { 0: [0.0, 0.0, 0.0, 0.0, 0.0], 22.5: [0.0, 0.0, 0.0, 0.0, 0.0], 45: [0.0, 0.0, 0.0, 0.0, 0.0], 67.5: [0.5, 0.0, 0.5, 0.0, 0.0], 90: [0.0, 0.0, 0.0, 0.0, 0.0], 112.5: [0.0, 0.0, 0.0, 0.0, 0.0], 135: [0.0, 0.0, 0.0, 0.0, 0.0], 157.5: [0.0, 0.0, 0.0, 0.0, 0.0], 180: [0.0, 0.0, 0.0, 0.0, 0.0], 202.5: [0.0, 0.0, 0.0, 0.0, 0.0], 225: [0.0, 0.0, 0.0, 0.0, 0.0], 247.5: [0.0, 0.0, 0.0, 0.0, 0.0], 270: [0.0, 0.0, 0.0, 0.0, 0.0], 292.5: [0.0, 0.0, 0.0, 0.0, 0.0], 315: [0.0, 0.0, 0.0, 0.0, 0.0], 337.5: [0.0, 0.0, 0.0, 0.0, 0.0] } compare_bin_probabilities = pd.DataFrame( data=compare_bin_probabilities, index=[3.47, 3.61, 3.75, 3.89, 4.03]) assert compare_bin_probabilities.equals(bin_probabilities)
def test_wind_class_3(self): # Interior test for Wind.get_bin_probabilities file = 'tests/test_data//test_winddata_realdata.txt' wind_data = windbins.get_wind_data(file) wind = windbins.Wind(wind_data) bin_probabilities = wind.get_bin_probabilities() compare_bin_probabilities = { 0: [0.03067, 0.10781, 0.10277, 0.00333, 0.0], 22.5: [0.02326, 0.04484, 0.01642, 0.0002, 0.0], 45: [0.01626, 0.01206, 0.00337, 0.0, 0.0], 67.5: [0.0116, 0.0067, 0.00153, 0.0, 0.0], 90: [0.00992, 0.00951, 0.00313, 6e-05, 0.0], 112.5: [0.01132, 0.01505, 0.00574, 0.0008, 0.0], 135: [0.01632, 0.02045, 0.01036, 0.00118, 2e-05], 157.5: [0.02256, 0.03155, 0.01736, 0.00418, 0.00022], 180: [0.03069, 0.05586, 0.06887, 0.02634, 0.00281], 202.5: [0.02754, 0.02868, 0.02943, 0.01277, 0.00094], 225: [0.01664, 0.01098, 0.00072, 4e-05, 0.0], 247.5: [0.00799, 0.00193, 0.00012, 0.0, 0.0], 270: [0.00713, 0.00195, 0.0, 0.0, 0.0], 292.5: [0.00624, 0.00215, 0.0, 0.0, 0.0], 315: [0.01006, 0.00652, 0.00052, 0.0, 0.0], 337.5: [0.01789, 0.04011, 0.02296, 0.00153, 0.0] } compare_bin_probabilities = pd.DataFrame( data=compare_bin_probabilities, index=[2.25, 6.75, 11.25, 15.75, 20.25]) assert compare_bin_probabilities.equals(bin_probabilities)
def test_wind_generation_2(self): # Test with integer overflows in input file file = 'tests/test_data//test_winddata_overflow.txt' wind_data = windbins.get_wind_data(file) compare_data = { 'Wind Speed': [np.nan, np.nan, np.nan, 4.1, np.nan, 3.4, 3.7], 'Wind Direction': [np.nan, np.nan, np.nan, np.nan, 74.0, 77.0, 75.0] } compare_data = pd.DataFrame(data=compare_data) assert compare_data.equals(wind_data)
def test_wind_generation_1(self): # Interior test file = 'tests/test_data//test_winddata_normal.txt' wind_data = windbins.get_wind_data(file) compare_data = { 'Wind Speed': [2.2, 2.1, 2.3, 2.1, 2.9, 2.6, 2.2, 2.0, 1.7, 2.0], 'Wind Direction': [ 345.0, 338.0, 335.0, 344.0, 332.0, 329.0, 324.0, 329.0, 340.0, 333.0 ] } compare_data = pd.DataFrame(data=compare_data) assert compare_data.equals(wind_data)
def main(): # Step 1: The user enters in geographic location of buoy location off the coast of North America parser = argparse.ArgumentParser( description= 'Identifies nearest NOAA stationary buoy to input coordinates') parser.add_argument( '-lat', '--latitude', type=str, required=True, help= 'String input of latitude. Use decimals degrees and either N/S or +/- to notate direction.' ) parser.add_argument( '-lon', '--longitude', type=str, required=True, help= 'String input of longitude. Use decimal degrees and either E/W or +/- to notate direction.' ) parser.add_argument( '-pf', '--platform', type=str, required=True, help='Platform type. Either OC3 or OC4 (i.e. Hywind or DeepCwind)') parser.add_argument( '-fr', '--fileroot', type=str, required=True, help='Root of filenames that all output files will start with.') args = parser.parse_args() # Step 1.5: Define template OpenFAST files to be used later in custom file creation (Step 5) # note: this ignores MoorDyn, which is created independently in Step 4 template_file_dir = 'template_files' turbsim_file_dir = 'turbsim_files' dat_file_dir = 'fast_input_files' output_file_dir = 'output_files' mat_file_dir = 'force_gen' if not os.path.exists('force_gen'): os.makedirs('force_gen') if not os.path.exists('turbsim_files'): os.makedirs('turbsim_files') if not os.path.exists('output_files'): os.makedirs('output_files') if args.platform.lower() == 'oc3': template_hd_file = template_file_dir + '/OC3Hywind_HydroDyn_template.dat' template_fst_file = template_file_dir + '/OC3Hywind_OpenFAST_template.fst' elif args.platform.lower() == 'oc4': template_hd_file = template_file_dir + '/OC4Semi_HydroDyn_template.dat' template_fst_file = template_file_dir + '/OC4Semi_OpenFAST_template.fst' else: raise ValueError( "Platform type not recognized. Please specify either 'OC3' or 'OC4'" ) template_inp_file = template_file_dir + '/IECKAI_template.inp' template_ifw_file = template_file_dir + '/InflowWind_template.dat' # Step 2: The nearest NOAA buoy is identified, and meteorological from the buoy is scraped and saved in text files buoy_num = buoy.geo_match(args.latitude, args.longitude) water_depth = buoy.get_water_depth(buoy_num) buoy.data_scraper(buoy_num) # Step 3: Read the text files and partition critical parameters into bins. If wind or current data does # not exist, specify as such so it isn't accounted for in OpenFAST file creation. Prompt user for input # to determine how to split wave climates, as separate HydroDyn files are created for each climate later. met_file = parse.get_most_recent_file_containing( 'met_data_' + str(buoy_num), '.txt') met_data = windbins.get_met_data(met_file) os.remove(met_file) try: wind_file = parse.get_most_recent_file_containing( 'wind_data_' + str(buoy_num), '.txt') wind_data = windbins.get_wind_data(wind_file) wind = windbins.Wind(wind_data) os.remove(wind_file) except: wind = windbins.Wind(met_data) pass try: curr_file = parse.get_most_recent_file_containing( 'curr_data_' + str(buoy_num), '.txt') curr_data, curr_depth = windbins.get_current_data(curr_file) curr_speed = curr_data['Current Speed'] curr_dir = curr_data['Current Direction'] no_curr_file = False os.remove(curr_file) except: no_curr_file = True pass bin_probabilities = wind.get_bin_probabilities() waves = windbins.Wave(met_data) wave_climates = waves.partition(custom_partitioning=True) # Step 4: Tune the floating wind platform mooring system for the depth and platform used at the site, and generate # the resulting MoorDyn input file moortune.tune(water_depth, args.platform, dat_file_dir + '/' + args.fileroot + '_MoorDyn.dat') # Step 5: Generate the other needed OpenFAST input files for each permutation, and run OpenFAST # Create INP files and run TurbSim filegen.inp_bulk_filegen(template_inp_file, turbsim_file_dir + '/' + args.fileroot, bin_probabilities.index.values) inp_files = parse.get_filenames('.inp', file_directory=turbsim_file_dir) run_fast.run_turbsim(inp_files) # Create InflowWind files from TurbSim BTS files and wind direction data filegen.inflowwind_bulk_filegen( template_ifw_file, dat_file_dir + '/' + args.fileroot + '_InflowWind', turbsim_file_dir, bin_probabilities.columns) # Create HydroDyn DAT files from custom wave climates if no_curr_file: filegen.hydrodyn_bulk_filegen( template_hd_file, dat_file_dir + '/' + args.fileroot + '_HydroDyn', water_depth, wave_climates) else: filegen.hydrodyn_bulk_filegen( template_hd_file, dat_file_dir + '/' + args.fileroot + '_HydroDyn', water_depth, wave_climates, current_climate=[curr_depth, curr_speed, curr_dir]) # Create OpenFAST FST files from previous custom files filegen.fst_bulk_filegen( template_fst_file, args.fileroot, dat_file_dir + '/' + args.fileroot + '_MoorDyn.dat', dat_file_dir, dat_file_dir) # Run OpenFAST for all created FST files and move output files to specified directories fst_files = parse.get_filenames('.fst') run_fast.run_fast(fst_files) os.remove(fst_files) outb_files = parse.get_filenames('.outb') parse.move_files(outb_files, output_file_dir) md_out_files = parse.get_filenames('.out') parse.move_files(md_out_files, output_file_dir) # Do post-processing for all tests all_output_roots = [ filenames.replace('.outb', '') for filenames in outb_files ] for test in all_output_roots: # Step 6: Parse the OpenFAST outputs into mooring/anchor tension and platform surge/sway into numpy arrays # containing the relevant statistical occurrences ptfm_surge, ptfm_sway, anchor_tension, line1_tension, line2_tension, line3_tension = \ parse.output_parse(output_file_dir+'/'+test) surge_stats = parse.make_distributions(ptfm_surge, calculate_stdev=False) sway_stats = parse.make_distributions(ptfm_sway, calculate_stdev=False) anchor_stats = parse.make_distributions(anchor_tension) line1_stats = parse.make_distributions(line1_tension) line2_stats = parse.make_distributions(line2_tension) line3_stats = parse.make_distributions(line3_tension) # Step 7: Create MAT files matching the format of the external reliability code reliability_results_filename = mat_file_dir + '/' + 'ReliabilityResults_' + test + '.mat' surge_results_filename = mat_file_dir + '/' + 'Surge_' + test + '.mat' filegen.create_mat_files(reliability_results_filename, surge_results_filename, line1_stats, line2_stats, line3_stats, anchor_stats[0, :], anchor_stats[1, :], anchor_stats[2, :], surge_stats, sway_stats)
def main(): # Step 1: The user enters in geographic location of buoy location off the coast of North America parser = argparse.ArgumentParser( description= 'Identifies nearest NOAA stationary buoy to input coordinates') parser.add_argument( '-lat', '--latitude', type=str, required=True, help= 'String input of latitude. Use decimals degrees and either N/S or +/- to notate direction.' ) parser.add_argument( '-lon', '--longitude', type=str, required=True, help= 'String input of longitude. Use decimal degrees and either E/W or +/- to notate direction.' ) parser.add_argument( '-pf', '--platform', type=str, required=True, help='Platform type. Either OC3 or OC4 (i.e. Hywind or DeepCwind)') parser.add_argument( '-fr', '--fileroot', type=str, required=True, help='Root of filenames that all output files will start with.') parser.add_argument( '-ex', '--example', type=int, help= 'Example MoorDyn files to use (optional). Overwrites fileroot if used.' ) args = parser.parse_args() # Step 1.5: Define template OpenFAST files to be used later in custom file creation (Step 5) # note: this ignores MoorDyn, which is created independently in Step 4 if args.example: fileroot = 'example' + str(args.example) ex_file_dir = 'example_files' else: fileroot = args.fileroot template_file_dir = 'template_files' turbsim_file_dir = 'turbsim_files' dat_file_dir = 'fast_input_files' if not os.path.exists('force_gen'): os.makedirs('force_gen') if not os.path.exists('turbsim_files'): os.makedirs('turbsim_files') if args.platform.lower() == 'oc3': template_hd_file = template_file_dir + '/OC3Hywind_HydroDyn_template.dat' template_fst_file = template_file_dir + '/OC3Hywind_OpenFAST_template.fst' elif args.platform.lower() == 'oc4': template_hd_file = template_file_dir + '/OC4Semi_HydroDyn_template.dat' template_fst_file = template_file_dir + '/OC4Semi_OpenFAST_template.fst' else: raise ValueError( "Platform type not recognized. Please specify either 'OC3' or 'OC4'" ) template_inp_file = template_file_dir + '/IECKAI_template.inp' template_ifw_file = template_file_dir + '/InflowWind_template.dat' # Step 2: The nearest NOAA buoy is identified, and meteorological from the buoy is scraped and saved in text files buoy_num = buoy.geo_match(args.latitude, args.longitude) water_depth = buoy.get_water_depth(buoy_num) buoy.data_scraper(buoy_num) # Step 3: Read the text files and partition critical parameters into bins. If wind or current data does # not exist, specify as such so it isn't accounted for in OpenFAST file creation. Prompt user for input # to determine how to split wave climates, as separate HydroDyn files are created for each climate later. met_file = parse.get_most_recent_file_containing( 'met_data_' + str(buoy_num), '.txt') met_data = windbins.get_met_data(met_file) os.remove(met_file) try: wind_file = parse.get_most_recent_file_containing( 'wind_data_' + str(buoy_num), '.txt') wind_data = windbins.get_wind_data(wind_file) wind = windbins.Wind(wind_data) os.remove(wind_file) except: wind = windbins.Wind(met_data) pass try: curr_file = parse.get_most_recent_file_containing( 'curr_data_' + str(buoy_num), '.txt') curr_data, curr_depth = windbins.get_current_data(curr_file) curr_speed = curr_data['Current Speed'] curr_dir = curr_data['Current Direction'] no_curr_file = False os.remove(curr_file) except: no_curr_file = True pass bin_probabilities = wind.get_bin_probabilities() waves = windbins.Wave(met_data) wave_climates = waves.partition(custom_partitioning=True) # Step 4: Tune the floating wind platform mooring system for the depth and platform used at the site, and generate # the resulting MoorDyn input file if not args.example: moortune.tune(water_depth, args.platform, dat_file_dir + '/' + fileroot + '_MoorDyn.dat') # Step 5: Generate the other needed OpenFAST input files for each permutation, and run OpenFAST # Create INP files filegen.inp_bulk_filegen(template_inp_file, turbsim_file_dir + '/' + fileroot, bin_probabilities.index.values) inp_files = parse.get_filenames('.inp', file_directory=turbsim_file_dir) # Run TurbSim and create InflowWind files from BTS files and wind direction data if args.example: filegen.inflowwind_bulk_filegen(template_ifw_file, dat_file_dir + '/' + fileroot + '_InflowWind', turbsim_file_dir, bin_probabilities.columns, no_turbsim=True) else: run_fast.run_turbsim(inp_files) filegen.inflowwind_bulk_filegen( template_ifw_file, dat_file_dir + '/' + fileroot + '_InflowWind', turbsim_file_dir, bin_probabilities.columns) # Create HydroDyn DAT files from custom wave climates if no_curr_file: filegen.hydrodyn_bulk_filegen( template_hd_file, dat_file_dir + '/' + fileroot + '_HydroDyn', water_depth, wave_climates) else: filegen.hydrodyn_bulk_filegen( template_hd_file, dat_file_dir + '/' + fileroot + '_HydroDyn', water_depth, wave_climates, current_climate=[curr_depth, curr_speed, curr_dir]) # Create OpenFAST FST files from previous custom files if args.example: filegen.fst_bulk_filegen(template_fst_file, 'force_gen/' + fileroot, ex_file_dir + '/' + fileroot + '_MoorDyn.dat', dat_file_dir, dat_file_dir) else: filegen.fst_bulk_filegen( template_fst_file, 'force_gen/' + fileroot, dat_file_dir + '/' + fileroot + '_MoorDyn.dat', dat_file_dir, dat_file_dir) bin_probabilities.to_csv(fileroot + '_bin_probabilities.csv')