def main():
    parser = argparse.ArgumentParser(
        description='Creates MAT files of proper format for reliability code '
        'from OpenFAST .outb and .out files')
    parser.add_argument(
        '-dir',
        '--openfastfiledir',
        type=str,
        required=True,
        help=
        'String of relative path to file directory consisting of .out and .outb OpenFAST files'
    )
    args = parser.parse_args()

    openfast_file_dir = args.openfastfiledir
    mat_file_dir = 'force_gen'

    if not os.path.exists('force_gen'):
        os.makedirs('force_gen')

    outb_files = parse.get_filenames('.outb', file_directory=openfast_file_dir)

    md_out_files = parse.get_filenames('.out',
                                       file_directory=openfast_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(openfast_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)
示例#2
0
def fst_bulk_filegen(template_file, new_filename_root, moordyn_file,
                     ifw_file_dir, hd_file_dir):
    """
    Generates a set of FST files for use in OpenFAST based on the DAT files existing in each of the specified
    directories. The number of generated files is equal to the number of DAT files in ifw_file_dir times the
    number of DAT files in hd_file_dir.
    Parameters:
        template_file: string containing the path of the existing file to use to modify parameters.
        new_filename_root: string containing the base for the new filenames to be generated.
        moordyn_file: path to the MoorDyn file to be used for all the tests
        ifw_file_dir: path to the directory containing all InflowWind DAT files to be referenced in the generated files.
            All InflowWind DAT files should have the string 'InflowWind' somewhere in its filename to be recognized.
            Each DAT file will generate a different FST file.
        hd_file_dir: same as 'ifw_file_dir', but for HydroDyn DAT files. Files should have 'HydroDyn' somewhere in its
            filename to be recognized.
    """

    ifw_files = parse.get_filenames('.dat', file_directory=ifw_file_dir)
    ifw_files = [
        filenames for filenames in ifw_files
        if 'inflowwind' in filenames.lower()
    ]
    hd_files = parse.get_filenames('.dat', file_directory=hd_file_dir)
    hd_files = [
        filenames for filenames in hd_files if 'hydrodyn' in filenames.lower()
    ]

    for ifw_file in ifw_files:
        for hd_file in hd_files:
            split_ifw_file = ifw_file.split('_')
            split_hd_file = hd_file.split('_')

            wind_speed_info = split_ifw_file[-2]
            wind_dir_info = split_ifw_file[-1].split('.')[0]
            climate_num_info = split_hd_file[-1].split('.')[0]

            new_fst_filename = new_filename_root + '_' + wind_speed_info + '_' + wind_dir_info + '_' + \
                climate_num_info + '.fst'
            # TODO: add error catching if ifw_file_dir or hd_file_dir is working directory
            filegen(template_file,
                    new_fst_filename,
                    InflowFile='"' + ifw_file_dir + '/' + ifw_file + '"',
                    HydroFile='"' + hd_file_dir + '/' + hd_file + '"',
                    MooringFile='"' + moordyn_file + '"')
示例#3
0
def inflowwind_bulk_filegen(template_file,
                            new_filename_root,
                            bts_file_directory,
                            directions,
                            no_turbsim=False):
    """
    Generates a set of InflowWind DAT files for use in OpenFAST based on the BTS files in a specified directory and
    a list of wind directions. The number of generated files is equal to the number of BTS files in bts_file_directory
    time the length of the 'directions' list.
    Parameters:
        template_file: string containing the path of the existing file to use to modify parameters.
        new_filename_root: string containing the base for the new filenames to be generated.
        bts_file_directory: directory containing the BTS files to be referenced in the generated files. Each BTS file
            will generate a different file.
        directions: list containing the desired directions to be covered in the generated DAT files.
        no_turbsim: used for demonstration purposes when TurbSim is not installed on the local machine. Creates
            InflowWind files linking to "dummy" BTS files based on INP files in bts_file_directory
    """
    if no_turbsim:
        bts_files = parse.get_filenames('.inp',
                                        file_directory=bts_file_directory)
    else:
        bts_files = parse.get_filenames('.bts',
                                        file_directory=bts_file_directory)

    for dir in directions:
        for bts_file in bts_files:
            URef = bts_file.split('_')[-2]
            new_ifw_filename = new_filename_root + '_' + URef + '_' + str(
                dir) + 'deg.dat'
            # TODO: add error catching if btw_file_directory is also working directory
            if no_turbsim:
                filegen(template_file,
                        new_ifw_filename,
                        PropogationDir=str(dir),
                        Filename='"' + bts_file_directory + '/' +
                        bts_file[0:-4] + '.bts"')
            else:
                filegen(template_file,
                        new_ifw_filename,
                        PropogationDir=str(dir),
                        Filename='"' + bts_file_directory + '/' + bts_file +
                        '"')
示例#4
0
 def test_file_catching_2(self):
     # Test get_filenames functionality
     test_dir = 'tests/test_data'
     txt_files = parse.get_filenames('.txt', file_directory=test_dir)
     compare_txt_files = [
         'test_currentdata_normal.txt', 'test_currentdata_overflow.txt',
         'test_currentdata_string.txt', 'test_datetime_normal.txt',
         'test_datetime_oldstyle.txt', 'test_datetime_skip.txt',
         'test_metdata_normal.txt', 'test_metdata_overflow.txt',
         'test_winddata_normal.txt', 'test_winddata_overflow.txt',
         'test_winddata_realdata.txt'
     ]
     assert txt_files == compare_txt_files
示例#5
0
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)
示例#6
0
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')