diff --git a/ROSCO/.github/workflows/CI_rosco-compile.yml b/ROSCO/.github/workflows/CI_rosco-compile.yml index c04abb8f6..3e4e70c38 100644 --- a/ROSCO/.github/workflows/CI_rosco-compile.yml +++ b/ROSCO/.github/workflows/CI_rosco-compile.yml @@ -3,9 +3,9 @@ name: CI_rosco-compile # We run CI on push commits on all branches on: [push, pull_request] -# Specify FORTRAN compiler +# Specify FORTRAN compiler, used to be "gfortran-10" env: - FORTRAN_COMPILER: gfortran-10 + FORTRAN_COMPILER: gfortran # A workflow run is made up of one or more jobs that can run sequentially or in parallel jobs: @@ -16,11 +16,11 @@ jobs: fail-fast: true matrix: os: ["ubuntu-latest", "macOS-latest", "windows-latest"] - python-version: ["3.8"] + python-version: ["3.9"] steps: - name: Checkout repository - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Setup environment uses: conda-incubator/setup-miniconda@v2 @@ -28,7 +28,7 @@ jobs: miniconda-version: "latest" channels: conda-forge, general auto-update-conda: true - python-version: 3.8 + python-version: 3.9 environment-file: environment.yml # Install ROSCO toolbox @@ -42,19 +42,25 @@ jobs: shell: bash -l {0} run: python ROSCO/rosco_registry/write_registry.py - - name: Add dependencies windows if: true == contains( matrix.os, 'windows') - shell: bash -l {0} run: | conda install -y m2w64-toolchain + - name: Add dependencies windows + if: true == contains( matrix.os, 'mac') + shell: bash -l {0} + run: | + conda install -y gfortran + - name: Setup Workspace - run: cmake -E make_directory ${{runner.workspace}}/ROSCO/ROSCO/build + run: | + cmake -E make_directory ${{runner.workspace}}/ROSCO/ROSCO/build - name: Configure and Build - unix if: false == contains( matrix.os, 'windows') - working-directory: ${{runner.workspace}}/ROSCO/ROSCO/build + shell: bash -l {0} + working-directory: "${{runner.workspace}}/ROSCO/ROSCO/build" run: | cmake \ -DCMAKE_INSTALL_PREFIX:PATH=${{runner.workspace}}/ROSCO/ROSCO/install \ @@ -64,11 +70,8 @@ jobs: - name: Configure and Build - windows if: true == contains( matrix.os, 'windows') - working-directory: ${{runner.workspace}}/ROSCO/ROSCO/build - shell: bash -l {0} + #shell: bash #-l {0} + working-directory: "${{runner.workspace}}/ROSCO/ROSCO/build" run: | - cmake \ - -DCMAKE_INSTALL_PREFIX:PATH=${{runner.workspace}}/ROSCO/ROSCO/install \ - -G "MinGW Makefiles" \ - .. + cmake -G "MinGW Makefiles" -DCMAKE_INSTALL_PREFIX="${{runner.workspace}}/ROSCO/ROSCO/build" .. cmake --build . --target install diff --git a/ROSCO/.github/workflows/CI_rosco-pytools.yml b/ROSCO/.github/workflows/CI_rosco-pytools.yml index 141c16ee9..dbfe77ab4 100644 --- a/ROSCO/.github/workflows/CI_rosco-pytools.yml +++ b/ROSCO/.github/workflows/CI_rosco-pytools.yml @@ -3,9 +3,9 @@ name: CI_rosco-pytools # We run CI on push commits on all branches on: [push, pull_request] -# Specify FORTRAN compiler +# Specify FORTRAN compiler, used to be "gfortran-10" env: - FC: gfortran-10 + FC: gfortran # A workflow run is made up of one or more jobs that can run sequentially or in parallel jobs: @@ -16,14 +16,14 @@ jobs: fail-fast: true matrix: os: ["ubuntu-latest", "macOS-latest", "windows-latest"] - python-version: ["3.8"] + python-version: ["3.9"] defaults: run: shell: bash -l {0} steps: - name: Checkout repository and submodules - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: submodules: recursive @@ -33,7 +33,7 @@ jobs: miniconda-version: "latest" channels: conda-forge, general auto-update-conda: true - python-version: 3.8 + python-version: 3.9 environment-file: environment.yml @@ -46,10 +46,10 @@ jobs: FC: gfortran - # - name: Add dependencies macOS specific - # if: true == contains( matrix.os, 'macOS') - # run: | - # conda install compilers + - name: Add dependencies macOS specific + if: true == contains( matrix.os, 'macOS') + run: | + conda install compilers # Install ROSCO toolbox - name: Install ROSCO toolbox on Windows @@ -72,14 +72,14 @@ jobs: fail-fast: true matrix: os: ["ubuntu-latest"] #, "macOS-latest"] - python-version: ["3.8"] + python-version: ["3.9"] defaults: run: shell: bash -l {0} steps: - name: Checkout repository and submodules - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: submodules: recursive @@ -89,7 +89,7 @@ jobs: miniconda-version: "latest" channels: conda-forge, general auto-update-conda: true - python-version: 3.8 + python-version: 3.9 environment-file: environment.yml # setup cmake @@ -129,13 +129,13 @@ jobs: # Install OpenFAST - name: Install OpenFAST run: | - conda install openfast==3.2.0 + conda install openfast==3.4 # Run examples - name: Run examples run: | cd Examples - python run_examples.py + python test_examples.py # Test walkthrough notebook - name: Test walkthrough notebook @@ -159,14 +159,14 @@ jobs: fail-fast: true matrix: os: ["ubuntu-latest"] #, "macOS-latest"] - python-version: ["3.8"] + python-version: ["3.9"] defaults: run: shell: bash -l {0} steps: - name: Checkout repository and submodules - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: submodules: recursive @@ -176,7 +176,7 @@ jobs: miniconda-version: "latest" channels: conda-forge, general auto-update-conda: true - python-version: 3.8 + python-version: 3.9 environment-file: environment.yml @@ -194,7 +194,7 @@ jobs: # Install OpenFAST - name: Install OpenFAST run: | - conda install openfast==3.2.0 + conda install openfast==3.4 # Run ROSCO Testing - name: Run ROSCO testing diff --git a/ROSCO/Examples/example_01.py b/ROSCO/Examples/01_turbine_model.py similarity index 80% rename from ROSCO/Examples/example_01.py rename to ROSCO/Examples/01_turbine_model.py index 14cf3bbd4..14a30fc27 100644 --- a/ROSCO/Examples/example_01.py +++ b/ROSCO/Examples/01_turbine_model.py @@ -17,6 +17,7 @@ # ROSCO Modules from ROSCO_toolbox import turbine as ROSCO_turbine from ROSCO_toolbox.inputs.validation import load_rosco_yaml +import matplotlib.pyplot as plt # Load yaml file @@ -33,7 +34,6 @@ turbine.load_from_fast( path_params['FAST_InputFile'], os.path.join(tune_dir,path_params['FAST_directory']), - dev_branch=True, rot_source='txt',txt_filename=os.path.join(tune_dir,path_params['FAST_directory'],path_params['rotor_performance_filename']) ) @@ -45,4 +45,18 @@ if not os.path.isdir(example_out_dir): os.makedirs(example_out_dir) -turbine.save(os.path.join(example_out_dir,'01_NREL5MW_saved.p')) \ No newline at end of file +turbine.save(os.path.join(example_out_dir,'01_NREL5MW_saved.p')) + +# Now load the turbine and plot the Cp surface + +# Load quick from python pickle +turbine = turbine.load(os.path.join(example_out_dir,'01_NREL5MW_saved.p')) + +# plot rotor performance +print('Plotting Cp data') +turbine.Cp.plot_performance() + +if False: + plt.show() +else: + plt.savefig(os.path.join(example_out_dir,'01_NREL5MW_Cp.png')) \ No newline at end of file diff --git a/ROSCO/Examples/example_03.py b/ROSCO/Examples/02_ccblade.py similarity index 93% rename from ROSCO/Examples/example_03.py rename to ROSCO/Examples/02_ccblade.py index a5ea447ab..8d09aaff2 100644 --- a/ROSCO/Examples/example_03.py +++ b/ROSCO/Examples/02_ccblade.py @@ -10,7 +10,7 @@ - Write a text file with rotor performance properties ''' # Python modules -import yaml, os +import os # ROSCO toolbox modules from ROSCO_toolbox import turbine as ROSCO_turbine from ROSCO_toolbox.utilities import write_rotor_performance @@ -38,10 +38,9 @@ turbine.load_from_fast( path_params['FAST_InputFile'], os.path.join(this_dir,path_params['FAST_directory']), - dev_branch=True, rot_source='cc-blade', txt_filename=None) # Write rotor performance text file -txt_filename = os.path.join(example_out_dir,'03_Cp_Ct_Cq.Ex03.txt') +txt_filename = os.path.join(example_out_dir,'02_Cp_Ct_Cq.Ex03.txt') write_rotor_performance(turbine,txt_filename=txt_filename) diff --git a/ROSCO/Examples/example_04.py b/ROSCO/Examples/03_tune_controller.py similarity index 96% rename from ROSCO/Examples/example_04.py rename to ROSCO/Examples/03_tune_controller.py index 69da8392a..a4308390e 100644 --- a/ROSCO/Examples/example_04.py +++ b/ROSCO/Examples/03_tune_controller.py @@ -38,7 +38,6 @@ turbine.load_from_fast( path_params['FAST_InputFile'], os.path.join(tune_dir,path_params['FAST_directory']), - dev_branch=True, rot_source='txt',txt_filename= cp_filename ) @@ -78,4 +77,4 @@ if False: plt.show() else: - plt.savefig(os.path.join(example_out_dir,'04_GainSched.png')) \ No newline at end of file + plt.savefig(os.path.join(example_out_dir,'03_GainSched.png')) \ No newline at end of file diff --git a/ROSCO/Examples/example_05.py b/ROSCO/Examples/04_simple_sim.py similarity index 97% rename from ROSCO/Examples/example_05.py rename to ROSCO/Examples/04_simple_sim.py index 9555aeb30..29d0c7b2d 100644 --- a/ROSCO/Examples/example_05.py +++ b/ROSCO/Examples/04_simple_sim.py @@ -59,7 +59,6 @@ turbine.load_from_fast( path_params['FAST_InputFile'], os.path.join(tune_dir,path_params['FAST_directory']), - dev_branch=True, rot_source='txt',txt_filename=cp_filename ) @@ -108,5 +107,5 @@ if False: plt.show() else: - plt.savefig(os.path.join(example_out_dir,'05_NREL5MW_SimpSim.png')) + plt.savefig(os.path.join(example_out_dir,'04_NREL5MW_SimpSim.png')) diff --git a/ROSCO/Examples/example_06.py b/ROSCO/Examples/05_openfast_sim.py similarity index 89% rename from ROSCO/Examples/example_06.py rename to ROSCO/Examples/05_openfast_sim.py index 6eab38347..a11f1b309 100644 --- a/ROSCO/Examples/example_06.py +++ b/ROSCO/Examples/05_openfast_sim.py @@ -37,10 +37,12 @@ controller = ROSCO_controller.Controller(controller_params) # Load turbine data from OpenFAST and rotor performance text file -turbine.load_from_fast(path_params['FAST_InputFile'], \ - os.path.join(this_dir,path_params['FAST_directory']), \ - dev_branch=True,rot_source='txt',\ - txt_filename=os.path.join(this_dir,path_params['FAST_directory'],path_params['rotor_performance_filename'])) +turbine.load_from_fast( + path_params['FAST_InputFile'], + os.path.join(this_dir,path_params['FAST_directory']), + rot_source='txt', + txt_filename=os.path.join(this_dir,path_params['FAST_directory'],path_params['rotor_performance_filename']) + ) # Tune controller controller.tune_controller(turbine) @@ -79,7 +81,7 @@ if False: plt.show() else: - plt.savefig(os.path.join(example_out_dir,'06_GainSched.png')) + plt.savefig(os.path.join(example_out_dir,'05_GainSched.png')) # Run OpenFAST # --- May need to change fastcall if you use a non-standard command to call openfast diff --git a/ROSCO/Examples/example_07.py b/ROSCO/Examples/06_peak_shaving.py similarity index 96% rename from ROSCO/Examples/example_07.py rename to ROSCO/Examples/06_peak_shaving.py index 3fc16f859..fdad7db80 100644 --- a/ROSCO/Examples/example_07.py +++ b/ROSCO/Examples/06_peak_shaving.py @@ -44,7 +44,6 @@ turbine.load_from_fast( path_params['FAST_InputFile'], os.path.join(tune_dir,path_params['FAST_directory']), - dev_branch=True, rot_source='txt',txt_filename=os.path.join(tune_dir,path_params['FAST_directory'],path_params['rotor_performance_filename']) ) # Tune controller @@ -61,4 +60,4 @@ if False: plt.show() else: - plt.savefig(os.path.join(example_out_dir,'07_MinPitch.png')) + plt.savefig(os.path.join(example_out_dir,'06_MinPitch.png')) diff --git a/ROSCO/Examples/example_08.py b/ROSCO/Examples/07_openfast_outputs.py similarity index 93% rename from ROSCO/Examples/example_08.py rename to ROSCO/Examples/07_openfast_outputs.py index f4732a279..a794baf03 100644 --- a/ROSCO/Examples/example_08.py +++ b/ROSCO/Examples/07_openfast_outputs.py @@ -46,9 +46,9 @@ # fast_out.plot_fast_out() # Load and plot -fastout = fast_out.load_fast_out(filenames, tmin=10) +fastout = fast_out.load_fast_out(filenames) fast_out.plot_fast_out(cases=cases,showplot=False) -plt.savefig(os.path.join(example_out_dir,'08_IEA-15MW_Semi_Out.png')) +plt.savefig(os.path.join(example_out_dir,'07_IEA-15MW_Semi_Out.png')) diff --git a/ROSCO/Examples/example_09.py b/ROSCO/Examples/08_run_turbsim.py similarity index 100% rename from ROSCO/Examples/example_09.py rename to ROSCO/Examples/08_run_turbsim.py diff --git a/ROSCO/Examples/example_10.py b/ROSCO/Examples/09_distributed_aero.py similarity index 91% rename from ROSCO/Examples/example_10.py rename to ROSCO/Examples/09_distributed_aero.py index 7a7b06937..6d970194a 100644 --- a/ROSCO/Examples/example_10.py +++ b/ROSCO/Examples/09_distributed_aero.py @@ -34,8 +34,10 @@ # Load turbine data from openfast model turbine = ROSCO_turbine.Turbine(turbine_params) -turbine.load_from_fast(path_params['FAST_InputFile'], \ - os.path.join(this_dir,path_params['FAST_directory']),dev_branch=True) +turbine.load_from_fast( + path_params['FAST_InputFile'], + os.path.join(this_dir,path_params['FAST_directory']) + ) # Tune controller controller = ROSCO_controller.Controller(controller_params) diff --git a/ROSCO/Examples/example_11.py b/ROSCO/Examples/10_linear_params.py similarity index 97% rename from ROSCO/Examples/example_11.py rename to ROSCO/Examples/10_linear_params.py index 6b1e96801..b0c2470f0 100644 --- a/ROSCO/Examples/example_11.py +++ b/ROSCO/Examples/10_linear_params.py @@ -33,7 +33,7 @@ if not os.path.isdir(example_out_dir): os.makedirs(example_out_dir) -linmod_filename = os.path.join(example_out_dir,'11_IEA15MW_LinMod.dat') +linmod_filename = os.path.join(example_out_dir,'10_IEA15MW_LinMod.dat') # Instantiate turbine, controller, and file processing classes turbine = ROSCO_turbine.Turbine(turbine_params) @@ -44,7 +44,6 @@ turbine.load_from_fast( path_params['FAST_InputFile'], os.path.join(this_dir,path_params['FAST_directory']), - dev_branch=True, rot_source='txt', txt_filename=os.path.join(tune_dir,path_params['FAST_directory'],path_params['rotor_performance_filename']) ) diff --git a/ROSCO/Examples/example_12.py b/ROSCO/Examples/11_robust_tuning.py similarity index 97% rename from ROSCO/Examples/example_12.py rename to ROSCO/Examples/11_robust_tuning.py index 9d8c593d9..65f676d34 100644 --- a/ROSCO/Examples/example_12.py +++ b/ROSCO/Examples/11_robust_tuning.py @@ -43,7 +43,7 @@ def run_example(): # Path options example_out_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'examples_out') - output_name = '12_robust_scheduling' + output_name = '11_robust_scheduling' path_options = {'output_dir': example_out_dir, 'output_name': output_name } @@ -54,7 +54,6 @@ def run_example(): turbine.load_from_fast( path_params['FAST_InputFile'], os.path.join(this_dir, path_params['FAST_directory']), - dev_branch=True, rot_source='txt', txt_filename=os.path.join(this_dir,path_params['FAST_directory'],path_params['rotor_performance_filename']) ) @@ -124,7 +123,7 @@ def run_example(): if False: plt.show() else: - fig.savefig(os.path.join(example_out_dir, '12_RobustSched.png')) + fig.savefig(os.path.join(example_out_dir, '11_RobustSched.png')) # ---- Plot nyquist ---- # Re-load and trimlinturb for plotting diff --git a/ROSCO/Examples/example_13.py b/ROSCO/Examples/12_tune_ipc.py similarity index 91% rename from ROSCO/Examples/example_13.py rename to ROSCO/Examples/12_tune_ipc.py index b326491d3..d4040a68e 100644 --- a/ROSCO/Examples/example_13.py +++ b/ROSCO/Examples/12_tune_ipc.py @@ -1,5 +1,5 @@ ''' ------------ Example_13 -------------- +----------- 12_tune_ipc -------------- Load a turbine, tune a controller with IPC ------------------------------------- @@ -28,7 +28,8 @@ this_dir = os.path.dirname(os.path.abspath(__file__)) rosco_dir = os.path.dirname(this_dir) example_out_dir = os.path.join(this_dir,'examples_out') -run_dir = os.path.join(example_out_dir, '13_ipc_sim') +example_name = '12_ipc_sim' +run_dir = os.path.join(example_out_dir, example_name) # Load yaml file (Open Loop Case) parameter_filename = os.path.join(rosco_dir,'Tune_Cases/BAR.yaml') @@ -47,8 +48,10 @@ controller = ROSCO_controller.Controller(controller_params) # Load turbine data from OpenFAST and rotor performance text file -turbine.load_from_fast(path_params['FAST_InputFile'], - os.path.join(this_dir, path_params['FAST_directory']), dev_branch=True) +turbine.load_from_fast( + path_params['FAST_InputFile'], + os.path.join(this_dir, path_params['FAST_directory']) + ) # Tune controller controller.tune_controller(turbine) @@ -102,7 +105,7 @@ cases = {} cases['Baseline'] = ['Wind1VelX', ('BldPitch1', 'BldPitch2', 'BldPitch3'), 'RootMyc1', 'RotSpeed'] -out_file = os.path.join(example_out_dir,'13_ipc_sim/ipc_example_0.outb') +out_file = os.path.join(example_out_dir,example_name,'ipc_example_0.outb') op = output_processing.output_processing() fastout = op.load_fast_out(out_file, tmin=0) fig, ax = op.plot_fast_out(cases=cases,showplot=False) diff --git a/ROSCO/Examples/example_14.py b/ROSCO/Examples/14_open_loop_control.py similarity index 98% rename from ROSCO/Examples/example_14.py rename to ROSCO/Examples/14_open_loop_control.py index 2b14f2495..7ca794629 100644 --- a/ROSCO/Examples/example_14.py +++ b/ROSCO/Examples/14_open_loop_control.py @@ -1,5 +1,5 @@ ''' ------------ Example_14 -------------- +----------- 14_open_loop_control -------------- Load a turbine, tune a controller with open loop control commands ------------------------------------- @@ -76,7 +76,7 @@ # Load turbine data from OpenFAST and rotor performance text file turbine.load_from_fast(path_params['FAST_InputFile'], \ os.path.join(this_dir,path_params['FAST_directory']), \ - dev_branch=True,rot_source='txt',\ + rot_source='txt',\ txt_filename=os.path.join(this_dir,path_params['FAST_directory'],path_params['rotor_performance_filename'])) # Tune controller diff --git a/ROSCO/Examples/example_15.py b/ROSCO/Examples/15_pass_through.py similarity index 93% rename from ROSCO/Examples/example_15.py rename to ROSCO/Examples/15_pass_through.py index baa29c8af..f33fd3f75 100644 --- a/ROSCO/Examples/example_15.py +++ b/ROSCO/Examples/15_pass_through.py @@ -1,5 +1,5 @@ ''' ------------ Example_15 -------------- +----------- 15_pass_through -------------- Use the runFAST scripts to set up an example, use pass through in yaml ------------------------------------- @@ -37,6 +37,7 @@ def main(): 'wind_dir': run_dir } r.save_dir = run_dir + r.rosco_dir = rosco_dir r.run_FAST() diff --git a/ROSCO/Examples/example_16.py b/ROSCO/Examples/16_external_dll.py similarity index 95% rename from ROSCO/Examples/example_16.py rename to ROSCO/Examples/16_external_dll.py index 96268013a..afb629ecd 100644 --- a/ROSCO/Examples/example_16.py +++ b/ROSCO/Examples/16_external_dll.py @@ -1,5 +1,5 @@ ''' ------------ Example_16 -------------- +----------- 16_external_dll -------------- Run openfast with ROSCO and external control interface ------------------------------------- @@ -48,7 +48,7 @@ def main(): controller_params['DISCON']['DLL_InFile'] = os.path.join(rosco_dir,'Test_Cases/NREL-5MW/DISCON.IN') controller_params['DISCON']['DLL_ProcName'] = 'DISCON' - # RAAW FAD set up + # simulation set up r = run_FAST_ROSCO() r.tuning_yaml = parameter_filename r.wind_case_fcn = cl.simp_step @@ -58,6 +58,7 @@ def main(): 'wind_dir': run_dir } r.controller_params = controller_params + r.rosco_dir = rosco_dir r.save_dir = run_dir r.run_FAST() diff --git a/ROSCO/Examples/example_17.py b/ROSCO/Examples/17_zeromq_interface.py similarity index 98% rename from ROSCO/Examples/example_17.py rename to ROSCO/Examples/17_zeromq_interface.py index c77e8cc64..ae8a34aea 100644 --- a/ROSCO/Examples/example_17.py +++ b/ROSCO/Examples/17_zeromq_interface.py @@ -1,5 +1,5 @@ ''' ------------ Example_17 -------------- +----------- 17_zeromq_interface -------------- Run ROSCO using the ROSCO toolbox control interface and execute communication with ZeroMQ ------------------------------------- @@ -80,7 +80,6 @@ def sim_rosco(): turbine.load_from_fast( path_params['FAST_InputFile'], os.path.join(tune_dir, path_params['FAST_directory']), - dev_branch=True, rot_source='txt', txt_filename=cp_filename ) diff --git a/ROSCO/Examples/18_pitch_offsets.py b/ROSCO/Examples/18_pitch_offsets.py new file mode 100644 index 000000000..ace996c52 --- /dev/null +++ b/ROSCO/Examples/18_pitch_offsets.py @@ -0,0 +1,85 @@ +''' +----------- 18_pitch_offsets ------------------------ +Run openfast with ROSCO and pitch offset faults +----------------------------------------------- + +Set up and run simulation with pitch offsets, check outputs + +''' + +import os, platform +from ROSCO_toolbox.ofTools.case_gen.run_FAST import run_FAST_ROSCO +from ROSCO_toolbox.ofTools.case_gen import CaseLibrary as cl +from ROSCO_toolbox.ofTools.fast_io import output_processing +import numpy as np + + +#directories +this_dir = os.path.dirname(os.path.abspath(__file__)) +rosco_dir = os.path.dirname(this_dir) +example_out_dir = os.path.join(this_dir,'examples_out') +os.makedirs(example_out_dir,exist_ok=True) + +if platform.system() == 'Windows': + lib_name = os.path.realpath(os.path.join(this_dir, '../ROSCO/build/libdiscon.dll')) +elif platform.system() == 'Darwin': + lib_name = os.path.realpath(os.path.join(this_dir, '../ROSCO/build/libdiscon.dylib')) +else: + lib_name = os.path.realpath(os.path.join(this_dir, '../ROSCO/build/libdiscon.so')) + + +def main(): + + # Input yaml and output directory + parameter_filename = os.path.join(rosco_dir,'Tune_Cases/IEA15MW.yaml') + run_dir = os.path.join(example_out_dir,'18_PitchFaults') + os.makedirs(run_dir,exist_ok=True) + + # Set DISCON input dynamically through yaml/dict + controller_params = {} + controller_params['PF_Mode'] = 1 # Set pitch fault mode to pitch offsets + controller_params['DISCON'] = {} + + pitch2_offset = 1 # deg + pitch3_offset = -2 # deg + controller_params['DISCON']['PF_Offsets'] = [0.,float(np.radians(pitch2_offset)),float(np.radians(pitch3_offset))] + + # simulation set up + r = run_FAST_ROSCO() + r.tuning_yaml = parameter_filename + r.wind_case_fcn = cl.simp_step # single step wind input + r.wind_case_opts = { + 'U_start': [10], # from 10 to 15 m/s + 'U_end': [15], + 'wind_dir': run_dir, + 'T_step': 50, # step at 50 sec + 'T_Max': 100 # simulation is 100 sec + } + r.case_inputs = {} + r.case_inputs[("ServoDyn","Ptch_Cntrl")] = {'vals':[1], 'group':0} # Individual pitch control must be enabled in ServoDyn + r.controller_params = controller_params + r.save_dir = run_dir + r.rosco_dir = rosco_dir + + r.run_FAST() + + + # Check pitch offsets + filenames = [os.path.join(run_dir,'IEA15MW/simp_step/base/IEA15MW_0.outb')] + fast_out = output_processing.output_processing() + + # Load and plot + fastout = fast_out.load_fast_out(filenames) + offset_2 = fastout[0]['BldPitch2'] - fastout[0]['BldPitch1'] + offset_3 = fastout[0]['BldPitch3'] - fastout[0]['BldPitch1'] + + # check that offset (min,max) is very close to prescribed values + np.testing.assert_almost_equal(offset_2.max(),pitch2_offset,decimal=3) + np.testing.assert_almost_equal(offset_2.min(),pitch2_offset,decimal=3) + np.testing.assert_almost_equal(offset_3.max(),pitch3_offset,decimal=3) + np.testing.assert_almost_equal(offset_3.max(),pitch3_offset,decimal=3) + + + +if __name__=="__main__": + main() \ No newline at end of file diff --git a/ROSCO/Examples/19_update_discon_version.py b/ROSCO/Examples/19_update_discon_version.py new file mode 100644 index 000000000..342cd4d2a --- /dev/null +++ b/ROSCO/Examples/19_update_discon_version.py @@ -0,0 +1,29 @@ +''' +----------- 19_update_discon_version ----------------- +Test and demonstrate update_discon_version() function for converting an old ROSCO input +to the current version +''' + +import os +from ROSCO_toolbox.tune import update_discon_version + +this_dir = os.path.dirname(os.path.abspath(__file__)) +rosco_dir = os.path.dirname(this_dir) + + +def main(): + + old_discon_filename = os.path.join(this_dir,'example_inputs','DISCON_v2.2.0.IN') # An IEA-15MW input + + # Tuning yaml can be anything, does not have to correspond to old discon + tuning_yaml = os.path.join(rosco_dir,'Tune_Cases','NREL5MW.yaml') # dummy for now + update_discon_version( + old_discon_filename, + tuning_yaml, + os.path.join(this_dir,'examples_out','18_UPDATED_DISCON.IN') + ) + + + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/ROSCO/Examples/ROSCO_walkthrough.ipynb b/ROSCO/Examples/ROSCO_walkthrough.ipynb index 8f078be6d..d3f912b7c 100644 --- a/ROSCO/Examples/ROSCO_walkthrough.ipynb +++ b/ROSCO/Examples/ROSCO_walkthrough.ipynb @@ -33,23 +33,9 @@ "name": "stdout", "output_type": "stream", "text": [ + "WARNING: Be sure to pip install simpy and marmot-agents for offshore BOS runs\n", "Using ofTools in ROSCO_toolbox...\n" ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/Users/dzalkind/opt/anaconda3/envs/rosco-env/lib/python3.8/site-packages/openmdao/utils/general_utils.py:130: OMDeprecationWarning:simple_warning is deprecated. Use openmdao.utils.om_warnings.issue_warning instead.\n", - "/Users/dzalkind/opt/anaconda3/envs/rosco-env/lib/python3.8/site-packages/openmdao/utils/notebook_utils.py:171: UserWarning:Tabulate is not installed. Run `pip install openmdao[notebooks]` to install required dependencies. Using ASCII for outputs.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "WARNING: Be sure to pip install simpy and marmot-agents for offshore BOS runs\n" - ] } ], "source": [ @@ -193,15 +179,19 @@ "Loading wind turbine data for NREL's ROSCO tuning and simulation processeses\n", "-----------------------------------------------------------------------------\n", "Loading FAST model: NREL-5MW.fst \n", - "Loading rotor performace data from text file: /Users/dzalkind/Tools/ROSCO/Test_Cases/NREL-5MW/Cp_Ct_Cq.NREL5MW.txt\n", - "Loading rotor performace data from text file: Cp_Ct_Cq.NREL5MW.txt\n" + "Loading rotor performace data from text file: /Users/dzalkind/Tools/ROSCO3/Test_Cases/NREL-5MW/Cp_Ct_Cq.NREL5MW.txt\n", + "Loading rotor performace data from text file: ../Tune_Cases/../Test_Cases/NREL-5MW/Cp_Ct_Cq.NREL5MW.txt\n" ] } ], "source": [ "# Load turbine data from openfast model\n", "turbine = ROSCO_turbine.Turbine(turbine_params)\n", - "turbine.load_from_fast(path_params['FAST_InputFile'],path_params['FAST_directory'],dev_branch=True,rot_source='txt',txt_filename=path_params['rotor_performance_filename'])\n" + "turbine.load_from_fast(\n", + " path_params['FAST_InputFile'],\n", + " os.path.join('../Tune_Cases/',path_params['FAST_directory']),\n", + " rot_source='txt',txt_filename=os.path.join('../Tune_Cases/',path_params['FAST_directory'],path_params['rotor_performance_filename'])\n", + " )\n" ] }, { @@ -241,14 +231,12 @@ }, { "data": { - "image/png": "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\n", + "image/png": "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\n", "text/plain": [ - "
" + "
" ] }, - "metadata": { - "needs_background": "light" - }, + "metadata": {}, "output_type": "display_data" } ], @@ -320,14 +308,12 @@ "outputs": [ { "data": { - "image/png": "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\n", + "image/png": "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\n", "text/plain": [ - "
" + "
" ] }, - "metadata": { - "needs_background": "light" - }, + "metadata": {}, "output_type": "display_data" } ], @@ -366,7 +352,11 @@ "source": [ "# Write parameter input file\n", "param_file = 'DISCON.IN' # This must be named DISCON.IN to be seen by the compiled controller binary. \n", - "ROSCO_utilities.write_DISCON(turbine,controller,param_file=param_file, txt_filename=path_params['rotor_performance_filename'])" + "ROSCO_utilities.write_DISCON(\n", + " turbine,controller,\n", + " param_file=param_file, \n", + " txt_filename=os.path.join('../Tune_Cases/',path_params['FAST_directory'],path_params['rotor_performance_filename'])\n", + ")" ] }, { @@ -404,14 +394,12 @@ }, { "data": { - "image/png": "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\n", + "image/png": "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NzdSUlKue2zTpk1A2is9AL/88gtdunShXbt2bNu2jT///JPw8PA0+2bkdfPz88PPz48ffviBpKSkG25js9lo06YNa9eu5auvvmL37t288847uLr+N0poQkICEyZMYPbs2fz1118cPXqU559/3vH4tGnTGDVqFG+//TZ79uxh3LhxvPbaa8yaNQuA+Ph42rdvT/ny5dmyZQtjxoxJs/+dut15RSTr2WwGHy/bT/dp6zkdm0Tpwr788NS9dK9bwmlvQ10rd91jMENKAowras65XzkJHr4Z2qVHjx6MHDnScaVlzZo1zJs3L11D/7dt25YhQ4YA8NJLL/HBBx+wYsUKKlSocNN93nrrLe69914A+vXrx8iRIzl48CD33HMPAA8//DDLly/npZdeytDz6NOnD127dnXU0qBBA1577TVatWoFwDPPPEOfPn3SfbykpCT+7//+j9jYWO6///7rHi9cuDDw35WeK95++20effRRxo4d61hXvXr1NPtm5HVzc3Nj5syZDBgwgClTplCrVi2aNGnCo48+SrVq1QD4448/2LhxI3v27KFcuXIAjtfzipSUFKZMmULp0qUBe9B74403HI+/+eabTJw40XGVqVSpUuzevZvPPvuMXr168fXXX2O1Wpk+fTo+Pj5UrlyZ48eP8+STT6bzFb2x251XRLLWmbgkRnyz3TGTd5daxXjzwSr4euatr/u89WzzgEKFCtGuXTtmzZqFYRi0a9eOQoUKpWvfK1+uYL81FBISQlRUVLr3CQ4OxsfHJ80XcXBwMBs3bszgs7j+uABVq1ZNsy4xMZHY2FgCAgJuepzu3bvj6urKpUuXCAwMZMKECbRp0ybddWzfvp0BAwaku9b0vG4PPfQQ7dq1Y9WqVaxbt44lS5bw3nvv8fnnn9O7d2+2b99O8eLFHcHmRnx8fBzBBqBIkSKOc545c4Zjx47Rr1+/NLWnpqYSGBgIwJ49e6hevXqaNkcNGjS45fO8nfScV0SyztoDZ3lm/nbOxCXh7e7KGw9W5pHwULPLMoXCze24+9ivoJh17jvQt29fxy2bTz75JP2nc097H9ZisWCz2dK9j8Viue0xXFxcMK653Xaj20TXHvdm625X3wcffMADDzxAQEAAQUFBt9z2Rry9vW+7zZ28bl5eXrRo0YIWLVrw+uuv079/f0aPHk3v3r3v+JxXXtcr5542bRr16tVLs92VW1vXvgc3kt736or0nFdEMp/VZjDpz/1MWrYfw4BywX588lgtygbnrpm8M5PCze1YLBm+NWS21q1bk5ycDOC4jZNTFC5cOE3D19jYWCIiIrLsfCEhIZQpUyZd27q7u2O1WtOsq1atGn/++WeGboHdiUqVKjm6oVerVo3jx4+zb9++W169uZng4GCKFSvGoUOHePzxx296vtmzZ3Pp0iVHmFq/fn2abQoXLkxcXBzx8fH4+to/A7caAyc95xWRzHU6NpFn5m1j/SF7b8tH64QyukNlvD3y9h8UCjdOyNXVlT179jh+z0maN2/OzJkz6dChA/nz5+e1117LMTWWLFmSP//8k3vvvRdPT0/y58/P6NGjuf/++yldujSPPvooqamp/Prrr7z44ot3dI7o6GgeeeQR+vbtS7Vq1fD392fz5s289957PPjggwA0adKExo0b89BDD/H+++9TpkwZ9u7di8VioXXr1uk6z5gxYxg2bBgBAQG0adOGpKQkNm/ezPnz5xkxYgSPPfYYo0aNol+/frz66qscPnyYCRMmpDlGvXr18PHx4ZVXXuHpp59m48aNzJw5867OKyKZZ/X+szwzbxvR8cn4ergyrktVHqxRzOyycgT1lnJSAQEBt2yLYpaRI0fSuHFj2rdvT9u2benUqVOatiNmmjhxIkuXLk3Tdb5p06Z8++23LFq0iBo1atC8eXM2bNhwx+fw8/OjXr16fPDBBzRu3JgqVarw2muvMWDAAD7++GPHdt9//z116tShe/fuVKpUiRdffPG6q0q30r9/fz7//HNmzpxJ1apVadKkCTNnzqRUqVKOOn766Sd2795NzZo1GTVqFO+++26aYxQoUICvvvqKxYsXU7VqVebOnZumy/6dnFdE7p7VZvDhH/voMX0D0fHJVCwSwE9P36dgcxWLkZ6b704kNjaWwMBAYmJirvvyT0xMJCIiglKlSuHllbunexfJDfSZE8mY6ItJDJ//X2+o7nXtt6G83HPGFfCsdKvv72vptpSIiEgusPnwOYbO2cap2ES83V15u3MVutQqbnZZOZLCjYiISA5mGAZfrI7gnctTKJQu7MunT9SmXB7uDXU7CjciIiI5VMylFF74dge/7z4NQMfqRRnfpWqeG5Qvo/TqiIiI5EB/n4hhyNdbOXouAQ9XF17rUIkn6uWdKRTuhsLN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VKpUKc05rj3njXh4eFCpUiV279592+d3O/v37+fw4cPXjZdTrlw5nn32WX7//Xe6dOnCjBkzHI8lJiZy8OBBatasedfnF3E2CjcieUSzZs1YvXo127dvd1y5AXu4mTZtGomJiXcVbgCeeeYZ3nnnHRYuXMjevXsZMmTIbQcBHD58OL/99hsRERFs3bqVZcuWUbFixTTbvPHGG/z555/8/fff9O7dm0KFCjkGBnzppZdYt24dTz31FNu3b2f//v0sWrSIp59+GrAHhMcff5yePXuyYMECIiIi2LRpE++++66jV9awYcNYsmQJ7733Hvv27ePjjz++5S2pK1q1asXq1asz/kJd48cff+SBBx7Ax8cHsN/yGjp0KCtWrODIkSOsWbOGTZs2pXld1q9fj6enZ5pbdiJip3Ajkkc0a9aMS5cuUaZMGYKDgx3rmzRpQlxcHKVLlyY0NPSuzvHcc8/Rs2dPevfuTYMGDfD397+uLcu1rFYrTz31FBUrVqR169aUL1+eyZMnp9nmnXfe4ZlnnqF27dpERkayaNEiPDw8AKhWrRorV65k//79NGrUiJo1a/Laa69RpEgRx/4zZsygZ8+ePPfcc5QvX56OHTuyYcMGx/OtX78+n3/+OR999BE1atTg999/59VXX73t8x0wYACLFy8mJiYmoy9VGj/++GOaW1Kurq5ER0fTs2dPypUrR9euXWnTpg1jx451bDN37lwef/xxRyASkf9YjLu9YS4ikkWujLtz/vz5dE2FYIauXbtSs2ZNRo4ceUf7nz17liJFinDs2DHHbbLbOXPmDBUqVGDz5s2UKlXqjs4r4sx05UZE5C783//933Xj8mTEuXPneP/999MdbAAiIiKYPHmygo3ITejKjYjkWLnhyo2I5DwKNyIiIuJUdFtKREREnIrCjYiIiDgVhRsRERFxKgo3IiIi4lQUbkRERMSpKNyIiIiIU1G4EREREaeicCMiIiJO5f8Bz8SFbE872TMAAAAASUVORK5CYII=\n", "text/plain": [ - "
" + "
" ] }, - "metadata": { - "needs_background": "light" - }, + "metadata": {}, "output_type": "display_data" } ], @@ -459,13 +447,13 @@ "text": [ " \n", "------------------------------------------------------------------------------\n", - "Running ROSCO-v2.5.0\n", + "Running ROSCO-v2.6.0\n", "A wind turbine controller framework for public use in the scientific field \n", "Developed in collaboration: National Renewable Energy Laboratory \n", " Delft University of Technology, The Netherlands \n", "------------------------------------------------------------------------------\n", "Generator speed: 9.5 RPM, Pitch angle: 0.0 deg, Power: 0.0 kW, Est. wind Speed: 10.0 m/s\n", - "Generator speed: 673.4 RPM, Pitch angle: 0.1 deg, Power: 340.7 kW, Est. wind Speed: 4.6 m/s\n", + "Generator speed: 673.4 RPM, Pitch angle: 0.1 deg, Power: 340.8 kW, Est. wind Speed: 4.6 m/s\n", "Generator speed: 751.3 RPM, Pitch angle: 0.1 deg, Power: 853.4 kW, Est. wind Speed: 7.1 m/s\n", "Generator speed: 800.7 RPM, Pitch angle: 0.1 deg, Power: 1072.2 kW, Est. wind Speed: 6.8 m/s\n", "Generator speed: 781.4 RPM, Pitch angle: 0.1 deg, Power: 1190.5 kW, Est. wind Speed: 6.8 m/s\n", @@ -569,14 +557,12 @@ }, { "data": { - "image/png": "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\n", + "image/png": "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+YuKisLFixerHT83N/emc8yCRUUMBgN69OiBpKQkt/akpCT07dtXoajUSwiBqVOnYt26dfjpp58QFxfn9npcXByioqLc8mmxWLBt2zZXPnv06AG9Xu/WJysrC0eOHPHKnN977704fPgwDh065PrTs2dPPPLIIzh06BBat27NnN6Afv36VVtqf+LECbRs2RIAP6M3o6SkBBqN+68urVbrWtbMnN4aufLXp08fFBQUYN++fa4+e/fuRUFBwc3n+Kam6pLHOJc1r1y5UqSmpopp06YJf39/kZ6ernRoqvPXv/5VBAcHi61bt4qsrCzXn5KSElefV199VQQHB4t169aJw4cPi3HjxtW4PC8mJkZs2rRJHDhwQNxzzz1es7yxLqquEhKCOb0R+/btEzqdTixcuFCcPHlSfPbZZ8LPz098+umnrj7M542ZMGGCaN68uWtZ87p160R4eLh44YUXXH2Y02srLCwUBw8eFAcPHhQAxJIlS8TBgwdd22fIlb/7779fdOnSRezevVvs3r1bJCQkcFlzY/Pvf/9btGzZUhgMBnH77be7lumSOwA1/lm1apWrj91uFy+99JKIiooSRqNR3H333eLw4cNuxyktLRVTp04VoaGhwtfXVwwfPlycO3eunr8a9bq6YGFOb8x3330nOnfuLIxGo+jQoYNYvny52+vM540xmUzi2WefFS1atBA+Pj6idevWYs6cOcJsNrv6MKfXtmXLlhp/dk6YMEEIIV/+Ll++LB555BERGBgoAgMDxSOPPCLy8/NvOm5JCCFubmyGiIiIqH5wDgsRERGpHgsWIiIiUj0WLERERKR6LFiIiIhI9ViwEBERkeqxYCEiIiLVY8FCREREqseChYiIiFSPBQsRqdK8efPQrVs3xc7/4osv4sknn6xT3+eeew7PPPOMhyMi8m7c6ZaI6t31bi8/YcIELF26FGazGWFhYfUUVaWLFy8iPj4eKSkpaNWq1XX75+TkoE2bNkhJSal2E04ikgcLFiKqd1VvXf/5559j7ty5bnc19vX1RXBwsBKhAQAWLVqEbdu24ccff6zzex588EG0bdsW/+///T8PRkbkvXhJiIjqXVRUlOtPcHAwJEmq1nb1JaGJEydi9OjRWLRoESIjI9GkSRPMnz8f5eXleP755xEaGoqYmBh8+OGHbufKzMzE2LFjERISgrCwMIwaNQrp6enXjG/NmjUYOXKkW9uXX36JhIQE+Pr6IiwsDIMHD0ZxcbHr9ZEjR+K///3vLeeGiGrGgoWIGoyffvoJFy5cwPbt27FkyRLMmzcPw4cPR0hICPbu3YvJkydj8uTJyMjIAACUlJRg0KBBCAgIwPbt27Fz504EBATg/vvvh8ViqfEc+fn5OHLkCHr27Olqy8rKwrhx4zBp0iT89ttv2Lp1K8aMGYOqA9S9evVCRkYGzp4969kkEHkpFixE1GCEhobi7bffRvv27TFp0iS0b98eJSUlmD17NuLj4zFr1iwYDAb8/PPPABwjJRqNBh988AESEhLQsWNHrFq1CufOncPWrVtrPMfZs2chhEB0dLSrLSsrC+Xl5RgzZgxatWqFhIQETJkyBQEBAa4+zZs3B4Drjt4Q0c3RKR0AEVFdderUCRpN5b+zIiMj0blzZ9dzrVaLsLAw5OTkAACSk5Nx6tQpBAYGuh2nrKwMp0+frvEcpaWlAAAfHx9XW9euXXHvvfciISEB9913HxITE/H73/8eISEhrj6+vr4AHKM6RCQ/FixE1GDo9Xq355Ik1dhmt9sBAHa7HT169MBnn31W7VhNmzat8Rzh4eEAHJeGnH20Wi2SkpKwa9cubNy4Ee+88w7mzJmDvXv3ulYF5eXlXfO4RHRreEmIiBqt22+/HSdPnkRERATatm3r9qe2VUht2rRBUFAQUlNT3dolSUK/fv0wf/58HDx4EAaDAV9//bXr9SNHjkCv16NTp04e/ZqIvBULFiJqtB555BGEh4dj1KhR2LFjB9LS0rBt2zY8++yzOH/+fI3v0Wg0GDx4MHbu3Olq27t3LxYtWoRffvkF586dw7p165Cbm4uOHTu6+uzYsQP9+/d3XRoiInmxYCGiRsvPzw/bt29HixYtMGbMGHTs2BGTJk1CaWkpgoKCan3fk08+iTVr1rguLQUFBWH79u0YNmwY2rVrh3/84x944403MHToUNd7/vvf/+KJJ57w+NdE5K24cRwR0VWEEOjduzemTZuGcePGXbf///73Pzz//PNISUmBTsepgUSewBEWIqKrSJKE5cuXo7y8vE79i4uLsWrVKhYrRB7EERYiIiJSPY6wEBERkeqxYCEiIiLVY8FCREREqseChYiIiFSPBQsRERGpHgsWIiIiUj0WLERERKR6LFiIiIhI9ViwEBERker9fwzKRGBKDpp1AAAAAElFTkSuQmCC\n", "text/plain": [ - "
" + "
" ] }, - "metadata": { - "needs_background": "light" - }, + "metadata": {}, "output_type": "display_data" } ], @@ -593,7 +579,7 @@ "lib_name = (f'../ROSCO/build/libdiscon.{ext}')\n", "\n", "# Load the simulator and controller interface\n", - "controller_int = ROSCO_ci.ControllerInterface(lib_name)\n", + "controller_int = ROSCO_ci.ControllerInterface(lib_name,param_filename=param_file)\n", "sim = ROSCO_sim.Sim(turbine,controller_int)\n", "\n", "# Define a wind speed history\n", @@ -650,39 +636,35 @@ "outputs": [ { "data": { - "image/png": "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csklo6Kd//DDD+dPmzZtysSJE6dOmzZtyqOPPprXtczJJ588fsKECdPat5ubm+XMM88cO2rUqOmHHXbY5DVr1gSiXfvqq68eNnjw4MMmT548ddy4cdP+9Kc/FQNcfvnlI3/60592rBRw/PHHT7joootGt29fccUVI771rW8NbY+9oKDg8OHDh8+YPHny1OOOO25i13v8+Mc/Luu8b/jw4TO2b9/uAxCRWeeee+6Y9mNtbW0UFRXNnD9//vjuvqcAL7/8cvbnP//5kbHKxHLTTTeVTJw4cerEiROnTpgwYdq9995b2NNrdXbSSSeN37NnT0quh3aoszY4Y7oYOXJk6+rVq1dGO/bXv/615Mgjj2y47777is8///yoqy8cfvjhzQ899NC6K664ovxgrt1u8ODBbY8//vi68vLytnfeeSfzzDPPnLhr167324/ffffdhTk5OeHO5/zud78rLSgoCG3evHn5woULi66++uoRjz/++Ppo1//yl7+886c//enOZcuWZRx77LFTP//5z1fPnTu34cEHHywCdoXDYaqrq30NDQ0dv7Tfeeed3BtvvHHLDTfcsB3g/PPPLz/rrLNqL7vssupYnyWarKysyJo1a7IaGhokNzdXH3744fyysrK2A5134oknNp144olNByoXzYcffui/4YYbhi5ZsmRVSUlJuLa21tOecHvrpZdeWtcX1zF9z2pwxsQpEonw2GOPFd1zzz0bX3nllfympqZoy4Zw5JFHtsycObO1p/eZO3duc3l5eRvArFmzWoLBoKe5uVkAamtrPb///e/Lrr/++u2dz3nssccKv/CFL+wFuOyyy6pff/31vEgksv/FO5kxY0ZrZmZmZM+ePd6TTz65YfHixbkAixcvzpo0aVJzTk5OePfu3d7m5mb58MMPM4877rgeJZdoTjnllNp//vOfhQD3339/8fnnn9+x2OaLL76YfcQRR0yeMmXK1COOOGLy0qVLM9zPmNdey7v66quHXXjhheVz5syZNGLEiBk///nPO2qff/jDH4pnzJgxxa0ljw6FQmzfvt2fk5MTKSgoCAMUFBREJk+eHARYsWJFxgknnDBh2rRpU2bNmjXpvffeywQnif/Xf/3XqKOPPnriiBEjZjz++OO5F154YfnYsWOnnX/++eXt9+tcOzWpxf5RTEr5zoNLR36woz77wCXjN3FIXtP/u2DmlgOXdGzZsiVj8uTJU9u3b7rpps0LFixoePbZZ3NHjhzZOm3atNajjz66/p///GfBpZdeWnMwsVRWVgamTJkyNTc3N/yzn/1s64IFCxpilb/77ruLpk6d2pSVlaUAV1999fCrrrpqZ25u7j7Za+fOnYExY8YEAfx+P7m5ueGdO3f6hg4dGop2XYBXX301e/To0S3Dhw8PAfh8Pl27dm3gpZdeyjnmmGMat27d6n/hhRdyi4qKQpMmTWrOzMzss3bSz372s1XXXXfd0Isuuqhm1apV2Zdffvne119/PRdg5syZLW+//fZqv9/Pv//977zvfve7I55++ukPu15j3bp1ma+//vqampoa75QpU6Z/5zvf2b1ixYqMBx98sHjRokWrMzIy9DOf+cyo2267reTLX/7y3tLS0raRI0fOmDt3bv0nP/nJ6ksuuaQW4Itf/OLohQsXbpoxY0brCy+8kPOVr3xl1JtvvvkBQG1tre+NN9744L777iu86KKLJrzwwgurZ82a1XzYYYdNef3117OOO+645r76npi+ZwnOmC66e4x47733Fl9wwQVVABdffHHVvffeW3IwCW7UqFFtGzZseH/IkCHhV155JfvCCy8cv3LlyuXFxcVRq1qLFi3K/PGPfzz8qaeeWgvw+uuvZ23YsCHjjjvu2NK1jS3apOkiEjUh3XbbbWX33HPPoMrKysBDDz20tn3/rFmzGl588cWcN954I/c73/nOzs2bNwdee+21nIKCgvCcOXNiJuJ47tt5/9FHH91cWVmZ8ec//7n41FNPre1crqqqynvRRReN2bhxY6aIaFtbW9Sa8umnn16TlZWlWVlZoeLi4rbKykrfU089lbd8+fLsmTNnTgFoaWnxDB48OOTz+Xj55ZfXvvTSS9nPPPNM/rXXXjty0aJFOdddd92O9957L/fCCy8c137dYDDYcb8zzzyzxuPxcOSRRzaVlJS0zZkzpxlg4sSJzR9++GGGJbjUZgnOpJSDqWn1p1AoxJNPPln07LPPFt54441DVZWamhpfdXW154orrhi1fPny7LKysmCs9hj3l3EY4IQTTmgaNWpU6/LlyzM3btwY+N///d9hAAsXLtx44oknNn344Yf+Cy64YPwdd9yxYdq0aa0Ar7zySu7y5cuzhw8fPiMUCklVVZVvzpw5k95+++01Q4YMCW7YsCEwbty4tra2NhoaGryDBw8Of/3rXx/+7LPPFgC0J+32Nri777678Iorrhhz2mmnLcvOztZjjz224fXXX89dvXp11lFHHdU8duzY4E033VSWm5sbvuyyy/Z097l++ctfDrr77rsHATz11FNrS0pKQtu3b98nATc2NnpLS0v3aTdcsGBBzXXXXTfymWeeWbNr166O30XXXHPN8JNOOqn+2Wef/XDNmjWBk08+eRJRZGRkdCRMr9dLKBQSVZULL7xw76233rq1a3mPx8P8+fOb5s+f3/Txj3+87otf/GL5D3/4wx15eXmh7tpF22utXq+XQCCgna8VCoWiJl6TOqwNzpg4PPLII/mTJ09u2rFjx/tbt25dtm3btmULFiyovu+++woffPDBjatXr155oM4G27Zt84VCzhPDlStXBjZu3JgxadKk1s997nM1q1evXrl69eqVJ554YtOePXu8Z5xxxoTrr7++8vTTT29sP/+aa67ZvWvXrve3bt267OWXX15dXl7e+vbbb68Bp6Zx5513lgDcddddRccee2y9x+Ph5ptv3tp+7a7xXHrppTUzZsxovPXWW0sATjrppIbnnnuusLCwMOzz+SgrKwvX1dV533vvvdz58+c3dj2/3fe+973d7fcoLy9vO+WUUxqefvrpgurqag84nWImT57c5PPt+/f0V77ylT3f+ta3trXXitrV1dV5R4wYEQT405/+VBrre9rVggUL6h577LGirVu3+gB27tzp/eCDDwIbN270v/rqqx2PvhctWpQ9fPjwYHFxcWTEiBHBO++8swicdtY33ngj62DuaVKXJThjumhvg2t//fznPx983333FX/iE5+o6Vzu/PPPr/773/9e0vX8e+65p7CsrOywJUuW5Jx33nkTjj/++AkAzzzzTO7kyZOnTZo0aeoFF1ww7qabbtpUVlYW7nr+b37zm8GbN2/O+NWvfjWsPYb2X9jdueqqq/ZUV1f7Ro0aNf3mm28e8tvf/rYyns96/fXXb7/11luHhMNh5syZ01xTU+ObPXt2x+PIyZMnN+fm5oZjteV1dfTRRzdfccUVu4455pjJkydPnrpw4cJBd95558au5caNG9f2ox/9aL+prK655pod119//Ygjjzxycji837cnplmzZrX88Ic/3HrKKadMnDhx4tSTTz554pYtW/zBYFC+/e1vjxgzZsy0yZMnT33wwQeLbrnlli0A999///q77rqrdNKkSVMnTJgw7aGHHio8qJualGULnpqkW7p06caZM2d2+wjMmHS0dOnS0pkzZ5YnO45DmdXgjDHGDEiW4IwxxgxIluCMMcYMSJbgTCqIRCIR63JtBgz35zn2VDIm4SzBmVSwfPfu3QWW5MxA4K4HVwAsT3Yshzob6G2SLhQKfXHHjh2379ixw1b0NgNBx4reyQ7kUGfDBIwxxgxI9teyMcaYAckSnDHGmAHJEpwxxpgByRKcMcaYAckSnDHGmAHp/wMk2t7+Z9XjYwAAAABJRU5ErkJggg==\n", + "image/png": "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359NmzbVmocoKSmp1mznBQUFTJs2jYyMDDQaDT179mTHjh3069ev+T6YEEIIIUQja5PF4rBhw1AUpcH9KpWKF198kRdffLHBY7Zt21br9eLFi1m8eHEjRSiEEEIIYR6MHrN44sSJyx6zatWqqwpGCCGEEEKYF6OLxd69e/PWW2/V2yOXmZnJxIkTeeyxxxo1OCGEEEII0bKMLhZXrVrFwoULGTp0KPHx8bW2d+nShcLCQg4dOtQUMQohhBBCiBZidLE4efJkjh07hoeHB5GRkbz11ltMmjSJRx55hBdeeIFt27YRGhralLEKIYQQQohmZtINLl5eXqxbt467776bOXPm4ODgwJ49e4iIiGiq+IQQQgghRAsyaVLu/Px8pkyZwo8//sjTTz+Nl5cXd9xxB/v27Wuq+IQQQgghRAsyulj8+eef6dKlC/Hx8Rw4cIAFCxZw5MgRoqKiuO6663juueeoqqpqyliFEEIIIUQzM7pYvPXWW5kxYwa7d++mU6dOADg4OPDhhx/y888/8+WXX9KnT58mC1QIIYQQQjQ/o8cs/vnnn3Tv3r3efaNHj+bo0aM8+eSTjRaYEEIIIYRoeUb3LDZUKF7g7OzMZ599dtUBCSGEEEII82FUz+L69euNakylUjFhwoSrCkgIIYQQQpgPo4rFm266yajGVCoV1dXVVxOPEEIIIYQwI0YVi3q9vqnjEEIIIYQQZsikeRb/qby8vLHiEEIIIYQQZsjkYrG6upqXX34Zf39/HB0dSUhIAOD555+XG1yEEEIIIa4xJheLr776KsuXL2fhwoXY2NgYtkdERPDpp58a3U5ycjI7d+5k48aNHDx4kIqKClNDEUIIIYQQTczkYnHlypV8/PHH3H333VhaWhq2d+/enZMnT17y3MTERObOnUtISAghISFERUUxbtw4+vTpg0ajYfTo0Xz33XcyRlIIIYQQwkyYXCympqbSoUOHOtv1ej06na7B85544gkiIiI4ffo0L730EsePH6ewsJDKykoyMjLYsGED1113Hc8//zzdu3eX9aaFEEIIIcyA0Su4XNC1a1d27txJcHBwre3fffcdPXv2bPA8Gxsb4uPj8fT0rLPPy8uLESNGMGLECObNm8eGDRtITEykb9++poYnhBBCCCEakcnF4rx587jnnntITU1Fr9fzww8/EBcXx8qVK/n5558bPO/NN980+j3Gjx9valhCCCGEEKIJGH0ZOjs7G4AJEybwzTffsGHDBlQqFS+88AKxsbH89NNPjB492qi2ysrKKC0tNbxOTExkyZIlbNy40cTwhRBCCCFEUzK6Z9Hf35+JEyfy4IMPcv311zN27NgrftNJkyZxyy238Oijj1JQUED//v2xtrYmJyeHRYsW8dhjj11x20IIIYQQovEY3bO4YsUKtFotEyZMIDAwkOeff94wx6KpDh48yJAhQwD4/vvv8fb2JjExkZUrV/Luu+9eUZtCCCGEEKLxGV0s3nXXXWzatImzZ8/y8MMP89VXXxEWFsbw4cP56quvTFrNpbS0FCcnJwA2bdrELbfcgoWFBQMGDCAxMdH0TyGEEEIIIZqEyVPnBAYGMm/ePBISEti0aRP+/v5MmzYNX19fpk+fblQbHTp04McffyQ5OZmNGzcyZswYALKysnB2djY1JCGEEEII0USuam3okSNHsmrVKlauXImFhQUfffSRUee98MILzJ49m5CQEPr378/AgQOBml7GS02/I4QQQgghmpfJU+dccO7cOb744gtWrFhBSkoKw4cP58EHHzTq3FtvvZXrrruO9PR0IiMjDdtHjhzJzTfffKUhCSGEEEKIRmZSsVheXs53333HF198wY4dO/D39+e+++7j/vvvJyQk5LLn+/n5MWnSJCZOnMjIkSPx8fGptb9fv34mBS+EEEIIIZqW0Zehp02bho+PDw8//DCenp788ssvnDt3jvnz5xtVKAKsXr0ae3t7Hn/8cTw8PLjtttv48ssvycvLu9L4hRBCCCFEEzK6WNyzZw/z588nLS2Nb775hrFjx6JSqUx6s2HDhvH2229z+vRpdu/eTa9evVi6dCm+vr4MGzaMxYsXEx8fb/KHMNWOHTuYMGECfn5+qFQqfvzxx1r7FUXhxRdfxM/PDzs7O4YNG8bx48cv2+7atWvp0qULarWaLl26sG7duib6BEIIIYQQzcPoYvHIkSM88cQTuLm5Ncobd+3alblz57Jnzx4SExO5++672bJlCxEREXTr1o1ffvmlUd6nPiUlJURGRvL+++/Xu3/hwoUsWrSI999/n3379uHj48Po0aMpKipqsM3du3dzxx13cM8993D48GHuuecebr/9dvbu3dtUH0MIIYQQosld8Q0u/5ScnMy8efP4/PPPTT73wuXthx9+mNLSUjZu3IharW6s0OoYN24c48aNq3efoigsWbKEZ599lltuuQWomZDc29ub1atX88gjj9R73pIlSxg9ejRz584FYO7cuWzfvp0lS5awZs2apvkgJlAUhdLKKiqqobSyCmvFtF5h0bh0OsmFuZBcmAfJg/mQXJiHC3lQFKWlQ0GlNFIUhw8fplevXlRXVxt9TlZWFllZWej1+lrbu3fv3hghGUWlUrFu3TpuuukmABISEggNDeXgwYO1pvGZNGkSLi4urFixot52goKCePLJJ3nyyScN2xYvXsySJUsanGi8oqKCiooKw2utVktgYCA5OTmNPt9kaWUVkS9vadQ2hRBCCNG09j89FI2DbZO0rdVq8fDwoLCw8JJ1h9E9i+vXr7/kflOW/jtw4ABTp04lNja2TsWsUqlMKjgbW0ZGBgDe3t61tl9YkvBS59V3zoX26vPaa68xf/78Ots3bdqEvb29KWFfVkU1NGJHshBCCCGawZYtW1BbNk3bpaWlRh1ndPVw0003oVKpLtkdauwNL/fffz/h4eF89tlneHt7m3yjTHP4Z0yKolw2TlPPmTt3LrNmzTK8vtCzOGbMmEbvWVQUhREjKtiyZQsjRozA2loKx5ak01VJLsyE5MI8SB7Mh+TCPFzIww1jR2FjY9Mk76HVao06zuj/C3x9fVm6dKnhcu0/HTp0iN69exvV1tmzZ/nhhx/o0KGDsW/fbC7M/ZiRkYGvr69he1ZWVp2ew3+e989exMudo1ar6x2baW1tjbW1tamhX5ZGpUJtCRoH2yZpXxhPp9NJLsyE5MI8SB7Mh+TCPFzIg42NTZPlwdh2jb4bunfv3hw8eLDB/ZfrdbzYyJEjOXz4sLFv3azatWuHj48P0dHRhm2VlZVs376dQYMGNXjewIEDa50DNZeTL3WOEEIIIYS5M7pn8T//+Q8lJSUN7u/QoQNbt241qq1PP/2UqVOncuzYMbp161ansp04caKxYV2R4uJizpw5Y3h99uxZDh06hJubG0FBQcycOZMFCxYQFhZGWFgYCxYswN7enilTphjOuffee/H39+e1114D4IknnmDo0KG88cYbTJo0if/9739s3ryZXbt2NelnEUIIIYRoSkYXi0OGDLnkfgcHB6KiooxqKyYmhl27dvHrr7/W2dccN7js37+f4cOHG15fGDc4depUli9fzpw5cygrK2P6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gx49ehgoqoZJq9Xy6quvsnHjRnbu3Im7u7uhQ2qQnnjiCU6ePMmxY8d0ry5dujBixAiOHTsmiWItCgoKKjN91G+//UarVq0MFFHDlJubi4mJfkpgamoqU+cYmLu7OyqVSu/6XVhYSEJCQq1ev6VnsYGIiopi1KhRdOnShcDAQGJiYrh06RLjx483dGgNysSJE1m7di3ff/89NjY2ut7eJk2aYGlpaeDoGg4bG5syz4laW1vj4OAgz4/WssjISHr06MGcOXN47rnnOHDgADExMcTExBg6tAZl4MCBzJ49Gzc3N3x9fTl69CgLFy5kzJgxhg6t3rt37x6///677v358+c5duwY9vb2uLm5MXnyZObMmYOnpyeenp7MmTMHKysrXnjhhdoLUisajE8//VTbqlUrbaNGjbQBAQHahIQEQ4fU4ADlvlauXGno0Bq84OBg7aRJkwwdRoP0ww8/aP38/LRKpVLr5eWljYmJMXRIDU5WVpZ20qRJWjc3N62FhYXWw8NDO23aNG1BQYGhQ6v34uLiyr0uhIeHa7VarVaj0WhnzpypValUWqVSqe3du7f25MmTtRqjzLMohBBCCCEqJM8sCiGEEEKICkmyKIQQQgghKiTJohBCCCGEqJAki0IIIYQQokKSLAohhBBCiArJPItC1ENqtZqioiJDhyGEqCHm5uYyebyoNZIsClGPaLVa0tLSuHv3rqFDEULUMDs7O1QqVa2uESwaJkkWhahHShNFJycnrKys5CIiRD2k1WrJzc0lPT0dQG/NYCFqgiSLQtQTarValyg6ODgYOhwhRA0qXR40PT0dJycnuSUtapQMcBGinih9RtHKysrAkQghakPpz7o8nyxqmiSLQtQzcutZiIZBftZFbZFkUQghhBBCVEiSRSGEEPXC6NGjGTx4sKHDqDYhISFMnjzZ0GEIIcmiEMLw/nyRHz16NAqFosxrwIABZfabM2cOpqamzJs3r1Ln2bhxI/3798fR0RGFQsGxY8fK1AkJCSlz7mHDht33uMePH2f48OG0bNkSS0tLvL29+fe//11h/d9//x0bGxvs7OzKbEtISKBz585YWFjg4eHBsmXLHvi5/vydmZmZ4ebmxj//+U8yMjIAOH36NAqFgv379+vt161bN5RKJbm5ubqywsJCrKysiImJKbcd/vwaPXp0mViio6Px9/cvU3737l0U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\n", "text/plain": [ - "
" + "
" ] }, - "metadata": { - "needs_background": "light" - }, + "metadata": {}, "output_type": "display_data" }, { "data": { - "image/png": "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6/TnzjvvTJ82bdrMadOmzZw6deqsRx55JGWwdXV1+umnT6muro7Za6Cpw/QYnPrEGz9+fPv27du3RVv28MMPpy9YsMD36KOPpl100UVRr8Ywf/781ieffHL3tddeW3g0dXfIysoKPPfcc7sLCwsDH3zwQdx55503rbKyclPH8gcffDDF4/GEum7zm9/8JiM5OTl44MCBLffcc0/qDTfckP/cc8/tjVb/ddddV/HTn/60YvPmze5TTjll5lVXXVW3ZMkS3xNPPJEKVIZCIerq6hw+n69zp/3BBx9477jjjoO33357GcBFF11UeP755zd85StfqevvtUQTHx8f3rFjR7zP5xOv12ueeuqppOzs7MCRtlu6dGnL0qVLW460XjR79uxx3n777bkbNmz4OD09PdTQ0GDrSLhD9cYbb+w+FvWo4actOKX6EA6HWbVqVepDDz1U/NZbbyW1tLREu1QICxYsaJs3b177YJ9nyZIlrYWFhQGAhQsXtvn9fltra6sANDQ02H77299m33bbbWVdt1m1alXKV7/61RqAr3zlK3Vr165NDIfDvSvvYs6cOe1xcXHh6upq+4oVK3zr16/3Aqxfvz5++vTprR6PJ1RVVWVvbW2VPXv2xJ166qmDSi7RnHHGGQ3/+Mc/UgAee+yxtIsuuqjzApuvv/56wgknnFA0Y8aMmSeccELRxo0b3ZHXmNjRyrvhhhvGXXLJJYWLFy+enp+fP+dnP/tZZ+vz7rvvTpszZ86MSCt5QjAYpKyszOnxeMLJyckhgOTk5HBRUZEfYOvWre5PfepTU2fNmjVj4cKF0z/66KM4sJL4F77whYKTTjppWn5+/pznnnvOe8kllxROmjRp1kUXXVTY8XxdW6cqtuk/SY2qG5/YOH5neVPCkdccuGk5iS2/unjewSOvaTl48KC7qKhoZsfjO++888DKlSt9r7zyinf8+PHts2bNaj/ppJOa/vGPfyRfeeWV9UcTS0lJiWvGjBkzvV5v6L/+678OrVy50tff+g8++GDqzJkzW+Lj4w3ADTfckHf99ddXeL3ebtmroqLCNXHiRD+A0+nE6/WGKioqHLm5ucFo9QKsWbMmYcKECW15eXlBAIfDYXbt2uV64403PCeffHLzoUOHnK+99po3NTU1OH369Na4uLhjdpz0S1/6Uu2tt96ae9lll9V//PHHCVdffXXN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\n", + "image/png": "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69exdetWtZi7d+/+WMetUCiQmJiIlJQUeHp6YsmSJVi1apXW432UqKgorF+/HleuXFG17+TkhJKSErVZsHbt2sHR0RH3799/6iehjYyMcPjwYTg7O2P06NFwd3fHrFmzMGHCBLUHburbz8bGRu3WggdNmjQJ//jHPzBq1Cj07NkTN2/eVJtlfBISiQSJiYno168fwsPD0bFjR4SEhODy5cuqS/wDBw7EgQMHMHToUHTs2BFhYWFwdXXF4cOHVbEuWbIE8+fPR0xMDNzc3FT7PE0iS6QvJEJTr31BRI3q/v37yMvLg0KhgImJidjhEFET4+88iY0zi0RERESkFZNFIiIiItKKySIRERERacVkkYiIiIi0YrJIpKf4bBpRy8DfdRIbk0UiPVO3vIu2pWOI6NlSXl4OQPNNNUTNhYtyE+kZIyMjmJmZ4fr165BKpTAw4N98RM8iQRBQXl6OoqIiWFlZPXQdUKKmxHUWifRQZWUl8vLy+I5ZohbAysoKcrkcEolE7FCohWKySKSnlEolL0UTPeOkUilnFEl0TBaJiIiISCve7EREREREWjFZJCIiIiKtmCwSERERkVZMFomIiIhIKyaLRERERKQVk0UiIiIi0orJIhERERFp9f8Buc1bnbTL7OMAAAAASUVORK5CYII=\n", "text/plain": [ - "
" + "
" ] }, - "metadata": { - "needs_background": "light" - }, + "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ - "([
,
],\n", - " [array([,\n", - " ,\n", - " ,\n", - " ], dtype=object),\n", - " array([,\n", - " ,\n", - " ], dtype=object)])" + "([
,
],\n", + " [array([,\n", + " ,\n", + " ,\n", + " ], dtype=object),\n", + " array([,\n", + " ,\n", + " ], dtype=object)])" ] }, "execution_count": 11, @@ -702,7 +684,7 @@ "# Define Plot cases \n", "cases = {}\n", "cases['Baseline'] = ['Wind1VelX', 'BldPitch1', 'GenTq', 'RotSpeed']\n", - "cases['Rotor Performance'] = ['RtVAvgxh', 'RtTSR', 'RtAeroCp']\n", + "cases['Rotor Performance'] = ['RtVAvgxh', 'RtTSR', 'RtFldCp']\n", "\n", "# Plot, woohoo!\n", "op.plot_fast_out(fast_out, cases)" @@ -762,6 +744,13 @@ "I would finally like to note that there has been a lot of work from a lot of very smart (and really great) people that has gone into all of this, some of which are acknowledged on the [ROSCO toolbox](www.github.com/nrel/ROSCO_toolbox) and [ROSCO](www.github.com/nrel/ROSCO_toolbox) github pages. " ] }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, { "cell_type": "code", "execution_count": null, @@ -773,9 +762,9 @@ "metadata": { "celltoolbar": "Slideshow", "kernelspec": { - "display_name": "rosco-env", + "display_name": "rosco-env3", "language": "python", - "name": "rosco-env" + "name": "rosco-env3" }, "language_info": { "codemirror_mode": { @@ -787,7 +776,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.8.13" + "version": "3.10.8" } }, "nbformat": 4, diff --git a/ROSCO/Examples/example_02.py b/ROSCO/Examples/example_02.py deleted file mode 100644 index a513ddd95..000000000 --- a/ROSCO/Examples/example_02.py +++ /dev/null @@ -1,37 +0,0 @@ -''' ------------ Example_02 -------------- -Load a turbine model from saved pickle, make a quick cp plot -------------------------------------- - -In this example: - - Load a turbine from a saved pickle - - Plot Cp Surface -''' - -# Python modules -import os -import matplotlib.pyplot as plt -# ROSCO toolbox modules -from ROSCO_toolbox import turbine as ROSCO_turbine - -this_dir = os.path.dirname(os.path.abspath(__file__)) -example_out_dir = os.path.join(this_dir,'examples_out') -if not os.path.isdir(example_out_dir): - os.makedirs(example_out_dir) - -# Initialize a turbine class -- Don't need to instantiate! -turbine = ROSCO_turbine.Turbine - -# Load quick from python pickle -turbine = turbine.load(os.path.join(example_out_dir,'01_NREL5MW_saved.p')) - -# plot rotor performance -print('Plotting Cp data') -turbine.Cp.plot_performance() - - - -if False: - plt.show() -else: - plt.savefig(os.path.join(example_out_dir,'02_NREL5MW_Cp.png')) \ No newline at end of file diff --git a/ROSCO/Examples/example_19.py b/ROSCO/Examples/example_19.py new file mode 100644 index 000000000..fbbe67d1c --- /dev/null +++ b/ROSCO/Examples/example_19.py @@ -0,0 +1,29 @@ +''' +----------- XX_update_discon_version ----------------- +Test and demonstrate update_discon_version() function for converting an old ROSCO input +to the current version +''' + +import os +from ROSCO_toolbox.tune import update_discon_version + +this_dir = os.path.dirname(os.path.abspath(__file__)) +rosco_dir = os.path.dirname(this_dir) + + +def main(): + + old_discon_filename = os.path.join(this_dir,'example_inputs','DISCON_v2.2.0.IN') # An IEA-15MW input + + # Tuning yaml can be anything, does not have to correspond to old discon + tuning_yaml = os.path.join(rosco_dir,'Tune_Cases','NREL5MW.yaml') # dummy for now + update_discon_version( + old_discon_filename, + tuning_yaml, + os.path.join(this_dir,'examples_out','18_UPDATED_DISCON.IN') + ) + + + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/ROSCO/Examples/Cp_Ct_Cq.NREL5MW.txt b/ROSCO/Examples/example_inputs/Cp_Ct_Cq.NREL5MW.txt similarity index 100% rename from ROSCO/Examples/Cp_Ct_Cq.NREL5MW.txt rename to ROSCO/Examples/example_inputs/Cp_Ct_Cq.NREL5MW.txt diff --git a/ROSCO/Examples/example_inputs/DISCON_v2.2.0.IN b/ROSCO/Examples/example_inputs/DISCON_v2.2.0.IN new file mode 100644 index 000000000..81cbc1480 --- /dev/null +++ b/ROSCO/Examples/example_inputs/DISCON_v2.2.0.IN @@ -0,0 +1,119 @@ +! Controller parameter input file for the IEA-15-240-RWT wind turbine +! - File written using ROSCO Controller tuning logic on 02/25/20 + +!------- DEBUG ------------------------------------------------------------ +1 ! LoggingLevel - {0: write no debug files, 1: write standard output .dbg-file, 2: write standard output .dbg-file and complete avrSWAP-array .dbg2-file} + +!------- CONTROLLER FLAGS ------------------------------------------------- +2 ! F_LPFType - {1: first-order low-pass filter, 2: second-order low-pass filter}, [rad/s] (currently filters generator speed and pitch control signals +2 ! F_NotchType - Notch on the measured generator speed and/or tower fore-aft motion (for floating) {0: disable, 1: generator speed, 2: tower-top fore-aft motion, 3: generator speed and tower-top fore-aft motion} +0 ! IPC_ControlMode - Turn Individual Pitch Control (IPC) for fatigue load reductions (pitch contribution) {0: off, 1: 1P reductions, 2: 1P+2P reductions} +1 ! VS_ControlMode - Generator torque control mode in above rated conditions {0: constant torque, 1: constant power, 2: TSR tracking PI control} +1 ! PC_ControlMode - Blade pitch control mode {0: No pitch, fix to fine pitch, 1: active PI blade pitch control} +0 ! Y_ControlMode - Yaw control mode {0: no yaw control, 1: yaw rate control, 2: yaw-by-IPC} +1 ! SS_Mode - Setpoint Smoother mode {0: no setpoint smoothing, 1: introduce setpoint smoothing} +2 ! WE_Mode - Wind speed estimator mode {0: One-second low pass filtered hub height wind speed, 1: Immersion and Invariance Estimator, 2: Extended Kalman Filter} +1 ! PS_Mode - Pitch saturation mode {0: no pitch saturation, 1: implement pitch saturation} +0 ! SD_Mode - Shutdown mode {0: no shutdown procedure, 1: pitch to max pitch at shutdown} +0 ! Fl_Mode - Floating specific feedback mode {0: no nacelle velocity feedback, 1: nacelle velocity feedback} +0 ! Flp_Mode - Flap control mode {0: no flap control, 1: steady state flap angle, 2: Proportional flap control} + +!------- FILTERS ---------------------------------------------------------- +1.00810 ! F_LPFCornerFreq - Corner frequency (-3dB point) in the low-pass filters, [rad/s] +0.70000 ! F_LPFDamping - Damping coefficient [used only when F_FilterType = 2] +3.35500 ! F_NotchCornerFreq - Natural frequency of the notch filter, [rad/s] +0.00000 0.25000 ! F_NotchBetaNumDen - Two notch damping values (numerator and denominator, resp) - determines the width and depth of the notch, [-] +0.628320000000 ! F_SSCornerFreq - Corner frequency (-3dB point) in the first order low pass filter for the setpoint smoother, [rad/s]. +0.21300 1.00000 ! F_FlCornerFreq - Natural frequency and damping in the second order low pass filter of the tower-top fore-aft motion for floating feedback control [rad/s, -]. +1.16240 1.00000 ! F_FlpCornerFreq - Corner frequency and damping in the second order low pass filter of the blade root bending moment for flap control [rad/s, -]. + +!------- BLADE PITCH CONTROL ---------------------------------------------- +28 ! PC_GS_n - Amount of gain-scheduling table entries +0.063278 0.090539 0.112201 0.130892 0.147682 0.163130 0.177562 0.191194 0.204189 0.216578 0.228470 0.240017 0.251275 0.262033 0.272673 0.282965 0.293075 0.302964 0.312677 0.322161 0.331649 0.340690 0.349958 0.358737 0.367513 0.376528 0.384789 0.393240 ! PC_GS_angles - Gain-schedule table: pitch angles +-1.222765 -1.056462 -0.919886 -0.805720 -0.708866 -0.625663 -0.553417 -0.490096 -0.434142 -0.384341 -0.339730 -0.299539 -0.263141 -0.230024 -0.199764 -0.172005 -0.146450 -0.122847 -0.100980 -0.080665 -0.061742 -0.044072 -0.027535 -0.012026 0.002549 0.016271 0.029213 0.041440 ! PC_GS_KP - Gain-schedule table: pitch controller kp gains +-0.127742 -0.115205 -0.104909 -0.096302 -0.089000 -0.082728 -0.077281 -0.072508 -0.068289 -0.064535 -0.061172 -0.058142 -0.055398 -0.052901 -0.050620 -0.048527 -0.046601 -0.044821 -0.043173 -0.041641 -0.040215 -0.038883 -0.037636 -0.036467 -0.035368 -0.034333 -0.033358 -0.032436 ! PC_GS_KI - Gain-schedule table: pitch controller ki gains +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ! PC_GS_KD - Gain-schedule table: pitch controller kd gains +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ! PC_GS_TF - Gain-schedule table: pitch controller tf gains (derivative filter) +1.570800000000 ! PC_MaxPit - Maximum physical pitch limit, [rad]. +0.000000000000 ! PC_MinPit - Minimum physical pitch limit, [rad]. +0.034900000000 ! PC_MaxRat - Maximum pitch rate (in absolute value) in pitch controller, [rad/s]. +-0.03490000000 ! PC_MinRat - Minimum pitch rate (in absolute value) in pitch controller, [rad/s]. +0.791680000000 ! PC_RefSpd - Desired (reference) HSS speed for pitch controller, [rad/s]. +0.000000000000 ! PC_FinePit - Record 5: Below-rated pitch angle set-point, [rad] +0.017450000000 ! PC_Switch - Angle above lowest minimum pitch angle for switch, [rad] + +!------- INDIVIDUAL PITCH CONTROL ----------------------------------------- +0.0 ! IPC_IntSat - Integrator saturation (maximum signal amplitude contribution to pitch from IPC), [rad] +0.0 0.0 ! IPC_KI - Integral gain for the individual pitch controller: first parameter for 1P reductions, second for 2P reductions, [-] +0.0 0.0 ! IPC_aziOffset - Phase offset added to the azimuth angle for the individual pitch controller, [rad]. +0.0 ! IPC_CornerFreqAct - Corner frequency of the first-order actuators model, to induce a phase lag in the IPC signal {0: Disable}, [rad/s] + +!------- VS TORQUE CONTROL ------------------------------------------------ +96.55000000000 ! VS_GenEff - Generator efficiency mechanical power -> electrical power, [should match the efficiency defined in the generator properties!], [%] +19624046.66639 ! VS_ArSatTq - Above rated generator torque PI control saturation, [Nm] +4500000.000000 ! VS_MaxRat - Maximum torque rate (in absolute value) in torque controller, [Nm/s]. +21586451.33303 ! VS_MaxTq - Maximum generator torque in Region 3 (HSS side), [Nm]. +0.000000000000 ! VS_MinTq - Minimum generator (HSS side), [Nm]. +0.523600000000 ! VS_MinOMSpd - Optimal mode minimum speed, cut-in speed towards optimal mode gain path, [rad/s] +34505815.52476 ! VS_Rgn2K - Generator torque constant in Region 2 (HSS side), [N-m/(rad/s)^2] +15000000.00000 ! VS_RtPwr - Wind turbine rated power [W] +19624046.66639 ! VS_RtTq - Rated torque, [Nm]. +0.791680000000 ! VS_RefSpd - Rated generator speed [rad/s] +1 ! VS_n - Number of generator PI torque controller gains +-50437958.66505 ! VS_KP - Proportional gain for generator PI torque controller [1/(rad/s) Nm]. (Only used in the transitional 2.5 region if VS_ControlMode =/ 2) +-4588245.18720 ! VS_KI - Integral gain for generator PI torque controller [1/rad Nm]. (Only used in the transitional 2.5 region if VS_ControlMode =/ 2) +9.00 ! VS_TSRopt - Power-maximizing region 2 tip-speed-ratio [rad]. + +!------- SETPOINT SMOOTHER --------------------------------------------- +1.00000 ! SS_VSGain - Variable speed torque controller setpoint smoother gain, [-]. +0.00100 ! SS_PCGain - Collective pitch controller setpoint smoother gain, [-]. + +!------- WIND SPEED ESTIMATOR --------------------------------------------- +120.000 ! WE_BladeRadius - Blade length (distance from hub center to blade tip), [m] +1 ! WE_CP_n - Amount of parameters in the Cp array +0.0 0.0 0.0 0.0 ! WE_CP - Parameters that define the parameterized CP(lambda) function +0.0 ! WE_Gamma - Adaption gain of the wind speed estimator algorithm [m/rad] +1.0 ! WE_GearboxRatio - Gearbox ratio [>=1], [-] +318628138.00000 ! WE_Jtot - Total drivetrain inertia, including blades, hub and casted generator inertia to LSS, [kg m^2] +1.225 ! WE_RhoAir - Air density, [kg m^-3] +"Cp_Ct_Cq.IEA15MW.txt" ! PerfFileName - File containing rotor performance tables (Cp,Ct,Cq) +104 48 ! PerfTableSize - Size of rotor performance tables, first number refers to number of blade pitch angles, second number referse to number of tip-speed ratios +44 ! WE_FOPoles_N - Number of first-order system poles used in EKF +3.00 3.50 4.00 4.50 5.00 5.50 6.00 6.50 7.00 7.50 8.00 8.50 9.00 9.50 10.00 10.50 11.24 11.74 12.24 12.74 13.24 13.74 14.24 14.74 15.24 15.74 16.24 16.74 17.24 17.74 18.24 18.74 19.24 19.74 20.24 20.74 21.24 21.74 22.24 22.74 23.24 23.74 24.24 24.74 ! WE_FOPoles_v - Wind speeds corresponding to first-order system poles [m/s] +-0.02334364 -0.02723425 -0.03112486 -0.03501546 -0.03890607 -0.04279668 -0.04668728 -0.05057789 -0.05446850 -0.05835911 -0.06224971 -0.06614032 -0.07003093 -0.07392153 -0.07781214 -0.08170275 -0.05441825 -0.05758074 -0.06474714 -0.07383682 -0.08430904 -0.09581400 -0.10815415 -0.12121919 -0.13495759 -0.14915715 -0.16379718 -0.17904114 -0.19494603 -0.21082316 -0.22752972 -0.24440216 -0.26178793 -0.27954029 -0.29769427 -0.31606508 -0.33525667 -0.35396333 -0.37406865 -0.39341852 -0.41345400 -0.43495515 -0.45460302 -0.47551894 ! WE_FOPoles - First order system poles + +!------- YAW CONTROL ------------------------------------------------------ +0.0 ! Y_ErrThresh - Yaw error threshold. Turbine begins to yaw when it passes this. [rad^2 s] +0.0 ! Y_IPC_IntSat - Integrator saturation (maximum signal amplitude contribution to pitch from yaw-by-IPC), [rad] +1 ! Y_IPC_n - Number of controller gains (yaw-by-IPC) +0.0 ! Y_IPC_KP - Yaw-by-IPC proportional controller gain Kp +0.0 ! Y_IPC_KI - Yaw-by-IPC integral controller gain Ki +0.0 ! Y_IPC_omegaLP - Low-pass filter corner frequency for the Yaw-by-IPC controller to filtering the yaw alignment error, [rad/s]. +0.0 ! Y_IPC_zetaLP - Low-pass filter damping factor for the Yaw-by-IPC controller to filtering the yaw alignment error, [-]. +0.0 ! Y_MErrSet - Yaw alignment error, set point [rad] +0.0 ! Y_omegaLPFast - Corner frequency fast low pass filter, 1.0 [Hz] +0.0 ! Y_omegaLPSlow - Corner frequency slow low pass filter, 1/60 [Hz] +0.0 ! Y_Rate - Yaw rate [rad/s] + +!------- TOWER FORE-AFT DAMPING ------------------------------------------- +-1 ! FA_KI - Integral gain for the fore-aft tower damper controller, -1 = off / >0 = on [rad s/m] - !NJA - Make this a flag +0.0 ! FA_HPF_CornerFreq - Corner frequency (-3dB point) in the high-pass filter on the fore-aft acceleration signal [rad/s] +0.0 ! FA_IntSat - Integrator saturation (maximum signal amplitude contribution to pitch from FA damper), [rad] + +!------- MINIMUM PITCH SATURATION ------------------------------------------- +44 ! PS_BldPitchMin_N - Number of values in minimum blade pitch lookup table (should equal number of values in PS_WindSpeeds and PS_BldPitchMin) +3.00 3.50 4.00 4.50 5.00 5.50 6.00 6.50 7.00 7.50 8.00 8.50 9.00 9.50 10.00 10.50 11.24 11.74 12.24 12.74 13.24 13.74 14.24 14.74 15.24 15.74 16.24 16.74 17.24 17.74 18.24 18.74 19.24 19.74 20.24 20.74 21.24 21.74 22.24 22.74 23.24 23.74 24.24 24.74 ! PS_WindSpeeds - Wind speeds corresponding to minimum blade pitch angles [m/s] +0.06108652 0.06108652 0.06108652 0.05672320 0.04799655 0.03926991 0.02617994 0.01308997 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 ! PS_BldPitchMin - Minimum blade pitch angles [rad] + +!------- SHUTDOWN ----------------------------------------------------------- +0.393240000000 ! SD_MaxPit - Maximum blade pitch angle to initiate shutdown, [rad] +0.418880000000 ! SD_CornerFreq - Cutoff Frequency for first order low-pass filter for blade pitch angle, [rad/s] + +!------- Floating ----------------------------------------------------------- +-9.32196000000 ! Fl_Kp - Nacelle velocity proportional feedback gain [s] + +!------- FLAP ACTUATION ----------------------------------------------------- +0.000000000000 ! Flp_Angle - Initial or steady state flap angle [rad] +0.00000000e+00 ! Flp_Kp - Blade root bending moment proportional gain for flap control [s] +0.00000000e+00 ! Flp_Ki - Flap displacement integral gain for flap control [s] +0.000000000000 ! Flp_MaxPit - Maximum (and minimum) flap pitch angle [rad] \ No newline at end of file diff --git a/ROSCO/Examples/Example_OL_Input.dat b/ROSCO/Examples/example_inputs/Example_OL_Input.dat similarity index 100% rename from ROSCO/Examples/Example_OL_Input.dat rename to ROSCO/Examples/example_inputs/Example_OL_Input.dat diff --git a/ROSCO/Examples/run_examples.py b/ROSCO/Examples/test_examples.py similarity index 57% rename from ROSCO/Examples/run_examples.py rename to ROSCO/Examples/test_examples.py index 56b47208a..89d9e6c98 100644 --- a/ROSCO/Examples/run_examples.py +++ b/ROSCO/Examples/test_examples.py @@ -4,33 +4,42 @@ import runpy all_scripts = [ - 'example_01', - 'example_02', - 'example_03', - 'example_04', - 'example_05', - 'example_06', - 'example_07', - 'example_08', - 'example_09', - 'example_10', - 'example_11', - 'example_12', - 'example_13', - 'example_14', - 'example_15', - 'example_16', - 'example_17', # NJA: only runs on unix in CI + '01_turbine_model', + '02_ccblade', + '03_tune_controller', + '04_simple_sim', + '05_openfast_sim', + '06_peak_shaving', + '07_openfast_outputs', + '08_run_turbsim', + '09_distributed_aero', + '10_linear_params', + '11_robust_tuning', + '12_tune_ipc', + '14_open_loop_control', + '15_pass_through', + '16_external_dll', + '17_zeromq_interface', + '18_pitch_offsets', # NJA: only runs on unix in CI + '19_update_discon_version', + 'update_rosco_discons', ] def execute_script(fscript): examples_dir = os.path.dirname(os.path.realpath(__file__)) + test_case_dir = os.path.realpath(os.path.join(os.path.dirname(os.path.realpath(__file__)),'../Test_Cases')) # Go to location due to relative path use for airfoil files print("\n\n") print("NOW RUNNING:", fscript) print() - fullpath = os.path.join(examples_dir, fscript + ".py") + + if fscript in ['update_rosco_discons']: + run_dir = test_case_dir + else: + run_dir = examples_dir + + fullpath = os.path.join(run_dir, fscript + ".py") basepath = os.path.dirname(os.path.realpath(fullpath)) os.chdir(basepath) diff --git a/ROSCO/ROSCO/CMakeLists.txt b/ROSCO/ROSCO/CMakeLists.txt index 3a97a2160..b69aa02d0 100644 --- a/ROSCO/ROSCO/CMakeLists.txt +++ b/ROSCO/ROSCO/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.6) -project(ROSCO VERSION 2.6.0 LANGUAGES Fortran C) +project(ROSCO VERSION 2.7.0 LANGUAGES Fortran C) set(CMAKE_Fortran_MODULE_DIRECTORY "${CMAKE_BINARY_DIR}/ftnmods") @@ -109,6 +109,10 @@ install(TARGETS discon LIBRARY DESTINATION lib ARCHIVE DESTINATION lib ) -if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) + +set(linuxDefault ${CMAKE_INSTALL_PREFIX} STREQUAL "/usr/local") +set(windowsDefault ${CMAKE_INSTALL_PREFIX} STREQUAL "C:\\Program Files (x86)") +if(${linuxDefault} OR ${windowsDefault}) + message("TRUE") set(CMAKE_INSTALL_PREFIX "${CMAKE_SOURCE_DIR}/install") -endif() +endif() \ No newline at end of file diff --git a/ROSCO/ROSCO/rosco_registry/rosco_types.yaml b/ROSCO/ROSCO/rosco_registry/rosco_types.yaml index cd090bdc6..81ad0953a 100644 --- a/ROSCO/ROSCO/rosco_registry/rosco_types.yaml +++ b/ROSCO/ROSCO/rosco_registry/rosco_types.yaml @@ -12,6 +12,13 @@ default_types: size: 0 # Use this if the type IS an array (size:3 --> REAL(8), BldPitch(3)) allocatable: False equals: + float: &float + type: float + description: + dimension: # Use this if a higher-dimensional allocatable array (dimension:(:,:) --> REAL(8), DIMESION(:,:), ALLOCATABLE) + size: 0 # Use this if the type IS an array (size:3 --> REAL(8), BldPitch(3)) + allocatable: False + equals: character: &character type: character description: @@ -129,6 +136,9 @@ ControlParameters: IPC_IntSat: <<: *real description: Integrator saturation (maximum signal amplitude contrbution to pitch from IPC) + IPC_SatMode: + <<: *integer + description: IPC Saturation method IPC Saturation method (0 - no saturation (except by PC_MinPit), 1 - saturate by PS_BldPitchMin, 2 - saturate sotfly (full IPC cycle) by PC_MinPit, 3 - saturate softly by PS_BldPitchMin) IPC_KP: <<: *real description: Integral gain for the individual pitch controller, [-]. @@ -430,7 +440,16 @@ ControlParameters: PA_Damping: <<: *real description: Pitch actuator damping ratio [-, unused if PA_Mode = 1] - + + # Pitch actuator error + PF_Mode: + <<: *integer + description: Pitch actuator fault mode {0 - not used, 1 - offsets on one or more blades} + PF_Offsets: + <<: *real + description: Pitch actuator fault offsets for blade 1-3 [rad/s] + allocatable: True + # External Control Ext_Mode: <<: *integer @@ -643,6 +662,12 @@ FilterParameters: dimension: (99) description: Notch filter denominator coefficient 0 +rlParams: + LastSignal: + <<: *real + dimension: (99) + description: Last input signal + piParams: ITerm: <<: *real @@ -701,6 +726,9 @@ LocalVariables: <<: *real description: Blade pitch [rad] size: 3 + BlPitchCMeas: + <<: *real + description: Mean (collective) blade pitch [rad] Azimuth: <<: *real description: Rotor aziumuth angle [rad] @@ -802,6 +830,9 @@ LocalVariables: <<: *real description: Proportional gain for IPC, after ramp [-] size: 2 + IPC_IntSat: + <<: *real + description: Integrator saturation (maximum signal amplitude contrbution to pitch from IPC) PC_State: <<: *integer description: State of the pitch control system @@ -811,7 +842,7 @@ LocalVariables: size: 3 PitComAct: <<: *real - description: Actuated pitch of each blade the last time the controller was called [rad]. + description: Actuated pitch command of each blade [rad]. size: 3 SS_DelOmegaF: <<: *real @@ -902,6 +933,10 @@ LocalVariables: <<: *derived_type id: piParams description: PI parameters derived type + rlP: + <<: *derived_type + id: rlParams + description: Rate limiter parameters derived type ObjectInstances: instLPF: @@ -922,6 +957,9 @@ ObjectInstances: instPI: <<: *integer description: PI controller instance + instRL: + <<: *integer + description: Rate limiter instance PerformanceData: TSR_vec: @@ -1006,34 +1044,19 @@ DebugVariables: axisYaw_2P: <<: *real description: Yaw component of coleman transformation, 2P - YawRateCom: - <<: *real - description: Commanded yaw rate [rad/s]. - NacHeadingTarget: - <<: *real - description: Target nacelle heading [rad]. - NacVaneOffset: - <<: *real - description: Nacelle vane angle with offset [rad]. - Yaw_err: - <<: *real - description: Yaw error [rad]. - YawState: - <<: *real - description: State of yaw controller YawRateCom: <<: *real description: Commanded yaw rate [rad/s]. NacHeadingTarget: <<: *real - description: Target nacelle heading [rad]. + description: Target nacelle heading [deg]. NacVaneOffset: <<: *real - description: Nacelle vane angle with offset [rad]. - Yaw_err: + description: Nacelle vane angle with offset [deg]. + Yaw_Err: <<: *real - description: Yaw error [rad]. + description: Yaw error [deg]. YawState: <<: *real description: State of yaw controller @@ -1086,7 +1109,7 @@ ZMQ_Variables: ExtControlType: avrSWAP: - <<: *c_float + <<: *float description: The swap array- used to pass data to and from the DLL controller [see Bladed DLL documentation] allocatable: True dimension: (:) diff --git a/ROSCO/ROSCO/rosco_registry/write_registry.py b/ROSCO/ROSCO/rosco_registry/write_registry.py index 05baaa8dd..09c855b3b 100644 --- a/ROSCO/ROSCO/rosco_registry/write_registry.py +++ b/ROSCO/ROSCO/rosco_registry/write_registry.py @@ -125,7 +125,7 @@ def write_roscoio(yfile): file.write(" TYPE(PerformanceData), INTENT(INOUT) :: PerfData\n") file.write(" TYPE(ErrorVariables), INTENT(INOUT) :: ErrVar\n") file.write(" TYPE(ZMQ_Variables), INTENT(INOUT) :: zmqVar\n") - file.write(" REAL(C_FLOAT), INTENT(IN) :: avrSWAP(*)\n") + file.write(" REAL(ReKi), INTENT(IN) :: avrSWAP(*)\n") file.write(" INTEGER(IntKi), INTENT(IN) :: size_avcOUTNAME\n") file.write(" CHARACTER(size_avcOUTNAME-1), INTENT(IN) :: RootName \n") file.write(" \n") @@ -221,12 +221,15 @@ def write_roscoio(yfile): file.write(' DebugOutUnits = [CHARACTER(15) :: ') counter = 0 for unit in dbg_units: + # Give dummy unit if not defined + if not unit: + unit = '[N/A]' counter += 1 if counter == len(dbg_units): - file.write(" '{}'".format(unit)) + file.write(" '{}'".format(unit)) # last line else: file.write(" '{}',".format(unit)) - if (counter % 5 == 0): + if (counter % 5 == 0): # group in groups of 5 file.write(' & \n ') file.write(']\n') @@ -293,6 +296,20 @@ def write_roscoio(yfile): file.write(" 100 FORMAT('Generator speed: ', f6.1, ' RPM, Pitch angle: ', f5.1, ' deg, Power: ', f7.1, ' kW, Est. wind Speed: ', f5.1, ' m/s')\n") file.write(" END IF\n") file.write("\n") + file.write(" ! Process DebugOutData, LocalVarOutData\n") + file.write(" ! Remove very small numbers that cause ******** outputs\n") + file.write(" DO I = 1,SIZE(DebugOutData)\n") + file.write(" IF (ABS(DebugOutData(I)) < 1E-10) THEN\n") + file.write(" DebugOutData(I) = 0\n") + file.write(" END IF\n") + file.write(" END DO\n") + file.write(" \n") + file.write(" DO I = 1,SIZE(LocalVarOutData)\n") + file.write(" IF (ABS(LocalVarOutData(I)) < 1E-10) THEN\n") + file.write(" LocalVarOutData(I) = 0\n") + file.write(" END IF\n") + file.write(" END DO\n") + file.write(" \n") file.write(" ! Write debug files\n") file.write(" IF(CntrPar%LoggingLevel > 0) THEN\n") file.write(" WRITE (UnDb, FmtDat) LocalVar%Time, DebugOutData\n") @@ -336,6 +353,15 @@ def read_type(param): f90type += ', DIMENSION(:), ALLOCATABLE' elif param['dimension']: f90type += ', DIMENSION{}'.format(param['dimension']) + elif param['type'] == 'float': + f90type = 'REAL(ReKi)' + if param['allocatable']: + if param['dimension']: + f90type += ', DIMENSION{}, ALLOCATABLE'.format(param['dimension']) + else: + f90type += ', DIMENSION(:), ALLOCATABLE' + elif param['dimension']: + f90type += ', DIMENSION{}'.format(param['dimension']) elif param['type'] == 'character': f90type = 'CHARACTER' if param['length']: diff --git a/ROSCO/ROSCO/src/Constants.f90 b/ROSCO/ROSCO/src/Constants.f90 index d04745aed..0da3ac946 100644 --- a/ROSCO/ROSCO/src/Constants.f90 +++ b/ROSCO/ROSCO/src/Constants.f90 @@ -14,7 +14,7 @@ MODULE Constants USE, INTRINSIC :: ISO_C_Binding - Character(*), PARAMETER :: rosco_version = 'v2.6.0' ! ROSCO version + Character(*), PARAMETER :: rosco_version = 'v2.7.0' ! ROSCO version INTEGER, PARAMETER :: DbKi = C_DOUBLE !< Default kind for double floating-point numbers INTEGER, PARAMETER :: ReKi = C_FLOAT !< Default kind for single floating-point numbers INTEGER, PARAMETER :: IntKi = C_INT !< Default kind for integer numbers diff --git a/ROSCO/ROSCO/src/ControllerBlocks.f90 b/ROSCO/ROSCO/src/ControllerBlocks.f90 index a62c53661..3e4530523 100644 --- a/ROSCO/ROSCO/src/ControllerBlocks.f90 +++ b/ROSCO/ROSCO/src/ControllerBlocks.f90 @@ -206,10 +206,10 @@ SUBROUTINE WindSpeedEstimator(LocalVar, CntrPar, objInst, PerfData, DebugVar, Er WE_Inp_Speed = LocalVar%RotSpeedF END IF - IF (LocalVar%BlPitch(1) < CntrPar%PC_MinPit) THEN + IF (LocalVar%BlPitchCMeas < CntrPar%PC_MinPit) THEN WE_Inp_Pitch = CntrPar%PC_MinPit ELSE - WE_Inp_Pitch = LocalVar%BlPitch(1) + WE_Inp_Pitch = LocalVar%BlPitchCMeas END IF IF (LocalVar%VS_LastGenTrqF < 0.0001 * CntrPar%VS_RtTq) THEN @@ -228,7 +228,7 @@ SUBROUTINE WindSpeedEstimator(LocalVar, CntrPar, objInst, PerfData, DebugVar, Er ! Inversion and Invariance Filter implementation IF (CntrPar%WE_Mode == 1) THEN ! Compute AeroDynTorque - Tau_r = AeroDynTorque(LocalVar%RotSpeedF, LocalVar%BlPitch(1), LocalVar, CntrPar, PerfData, ErrVar) + Tau_r = AeroDynTorque(LocalVar%RotSpeedF, LocalVar%BlPitchCMeas, LocalVar, CntrPar, PerfData, ErrVar) LocalVar%WE_VwIdot = CntrPar%WE_Gamma/CntrPar%WE_Jtot*(LocalVar%VS_LastGenTrq*CntrPar%WE_GearboxRatio - Tau_r) LocalVar%WE_VwI = LocalVar%WE_VwI + LocalVar%WE_VwIdot*LocalVar%DT @@ -413,7 +413,7 @@ REAL(DbKi) FUNCTION Shutdown(LocalVar, CntrPar, objInst) ! Pitch Blades to 90 degrees at max pitch rate if in shutdown mode IF (LocalVar%SD) THEN - Shutdown = LocalVar%BlPitch(1) + CntrPar%PC_MaxRat*LocalVar%DT + Shutdown = LocalVar%BlPitchCMeas + CntrPar%PC_MaxRat*LocalVar%DT IF (MODULO(LocalVar%Time, 10.0_DbKi) == 0) THEN print *, ' ** SHUTDOWN MODE **' ENDIF diff --git a/ROSCO/ROSCO/src/Controllers.f90 b/ROSCO/ROSCO/src/Controllers.f90 index 7568d4df0..fd7a15f41 100644 --- a/ROSCO/ROSCO/src/Controllers.f90 +++ b/ROSCO/ROSCO/src/Controllers.f90 @@ -96,7 +96,7 @@ SUBROUTINE PitchControl(avrSWAP, CntrPar, LocalVar, objInst, DebugVar, ErrVar) ! Saturate collective pitch commands: LocalVar%PC_PitComT = saturate(LocalVar%PC_PitComT, LocalVar%PC_MinPit, CntrPar%PC_MaxPit) ! Saturate the overall command using the pitch angle limits - LocalVar%PC_PitComT = ratelimit(LocalVar%PC_PitComT, LocalVar%PC_PitComT_Last, CntrPar%PC_MinRat, CntrPar%PC_MaxRat, LocalVar%DT) ! Saturate the overall command of blade K using the pitch rate limit + LocalVar%PC_PitComT = ratelimit(LocalVar%PC_PitComT, CntrPar%PC_MinRat, CntrPar%PC_MaxRat, LocalVar%DT, LocalVar%restart, LocalVar%rlP,objInst%instRL,LocalVar%BlPitchCMeas) ! Saturate the overall command of blade K using the pitch rate limit LocalVar%PC_PitComT_Last = LocalVar%PC_PitComT ! Combine and saturate all individual pitch commands in software @@ -104,9 +104,15 @@ SUBROUTINE PitchControl(avrSWAP, CntrPar, LocalVar, objInst, DebugVar, ErrVar) LocalVar%PitCom(K) = LocalVar%PC_PitComT + LocalVar%FA_PitCom(K) LocalVar%PitCom(K) = saturate(LocalVar%PitCom(K), LocalVar%PC_MinPit, CntrPar%PC_MaxPit) ! Saturate the command using the pitch satauration limits LocalVar%PitCom(K) = LocalVar%PitCom(K) + LocalVar%IPC_PitComF(K) ! Add IPC - LocalVar%PitCom(K) = saturate(LocalVar%PitCom(K), LocalVar%PC_MinPit, CntrPar%PC_MaxPit) ! Saturate the command using the absolute pitch angle limits - LocalVar%PitCom(K) = ratelimit(LocalVar%PitCom(K), LocalVar%BlPitch(K), CntrPar%PC_MinRat, CntrPar%PC_MaxRat, LocalVar%DT) ! Saturate the overall command of blade K using the pitch rate limit - END DO + + ! Hard IPC saturation by peak shaving limit + IF (CntrPar%IPC_SatMode == 1) THEN + LocalVar%PitCom(K) = saturate(LocalVar%PitCom(K), LocalVar%PC_MinPit, CntrPar%PC_MaxPit) + END IF + + ! Rate limit + LocalVar%PitCom(K) = ratelimit(LocalVar%PitCom(K), CntrPar%PC_MinRat, CntrPar%PC_MaxRat, LocalVar%DT, LocalVar%restart, LocalVar%rlP,objInst%instRL,LocalVar%BlPitch(K)) ! Saturate the overall command of blade K using the pitch rate limit + END DO ! Open Loop control, use if ! Open loop mode active Using OL blade pitch control @@ -134,11 +140,19 @@ SUBROUTINE PitchControl(avrSWAP, CntrPar, LocalVar, objInst, DebugVar, ErrVar) ! Hardware saturation: using CntrPar%PC_MinPit DO K = 1,LocalVar%NumBl ! Loop through all blades, add IPC contribution and limit pitch rate ! Saturate the pitch command using the overall (hardware) limit - LocalVar%PitComAct(K) = saturate(LocalVar%PitComAct(K), LocalVar%PC_MinPit, CntrPar%PC_MaxPit) + LocalVar%PitComAct(K) = saturate(LocalVar%PitComAct(K), CntrPar%PC_MinPit, CntrPar%PC_MaxPit) ! Saturate the overall command of blade K using the pitch rate limit - LocalVar%PitComAct(K) = ratelimit(LocalVar%PitComAct(K), LocalVar%BlPitch(K), CntrPar%PC_MinRat, CntrPar%PC_MaxRat, LocalVar%DT) ! Saturate the overall command of blade K using the pitch rate limit + LocalVar%PitComAct(K) = ratelimit(LocalVar%PitComAct(K), CntrPar%PC_MinRat, CntrPar%PC_MaxRat, LocalVar%DT, LocalVar%restart, LocalVar%rlP,objInst%instRL,LocalVar%BlPitch(K)) ! Saturate the overall command of blade K using the pitch rate limit END DO + ! Add pitch actuator fault for blade K + IF (CntrPar%PF_Mode == 1) THEN + DO K = 1, LocalVar%NumBl + ! This assumes that the pitch actuator fault overides the Hardware saturation + LocalVar%PitComAct(K) = LocalVar%PitComAct(K) + CntrPar%PF_Offsets(K) + END DO + END IF + ! Command the pitch demanded from the last ! call to the controller (See Appendix A of Bladed User's Guide): avrSWAP(42) = LocalVar%PitComAct(1) ! Use the command angles of all blades if using individual pitch @@ -222,7 +236,7 @@ SUBROUTINE VariableSpeedControl(avrSWAP, CntrPar, LocalVar, objInst, ErrVar) LocalVar%GenTq = MIN(LocalVar%GenTq, CntrPar%VS_MaxTq) ! Saturate the command using the maximum torque limit ! Saturate the commanded torque using the torque rate limit: - LocalVar%GenTq = ratelimit(LocalVar%GenTq, LocalVar%VS_LastGenTrq, -CntrPar%VS_MaxRat, CntrPar%VS_MaxRat, LocalVar%DT) ! Saturate the command using the torque rate limit + LocalVar%GenTq = ratelimit(LocalVar%GenTq, -CntrPar%VS_MaxRat, CntrPar%VS_MaxRat, LocalVar%DT, LocalVar%restart, LocalVar%rlP,objInst%instRL) ! Saturate the command using the torque rate limit ! Open loop torque control IF ((CntrPar%OL_Mode == 1) .AND. (CntrPar%Ind_GenTq > 0)) THEN @@ -254,7 +268,7 @@ SUBROUTINE YawRateControl(avrSWAP, CntrPar, LocalVar, objInst, zmqVar, DebugVar, ! TODO: The constant offset implementation is sort of circular here as a setpoint is already being defined in SetVariablesSetpoints. This could also use cleanup USE ROSCO_Types, ONLY : ControlParameters, LocalVariables, ObjectInstances, DebugVariables, ErrorVariables, ZMQ_Variables - REAL(C_FLOAT), INTENT(INOUT) :: avrSWAP(*) ! The swap array, used to pass data to, and receive data from, the DLL controller. + REAL(ReKi), INTENT(INOUT) :: avrSWAP(*) ! The swap array, used to pass data to, and receive data from, the DLL controller. TYPE(ControlParameters), INTENT(INOUT) :: CntrPar TYPE(LocalVariables), INTENT(INOUT) :: LocalVar @@ -357,6 +371,7 @@ SUBROUTINE YawRateControl(avrSWAP, CntrPar, LocalVar, objInst, zmqVar, DebugVar, DebugVar%NacHeadingTarget = NacHeadingTarget DebugVar%NacVaneOffset = NacVaneOffset DebugVar%YawState = YawState + DebugVar%Yaw_Err = NacHeadingError END IF END SUBROUTINE YawRateControl !------------------------------------------------------------------------------------------------------------------------------- @@ -404,15 +419,26 @@ SUBROUTINE IPC(CntrPar, LocalVar, objInst, DebugVar, ErrVar) LocalVar%IPC_KP(i) = sigma(LocalVar%WE_Vw, CntrPar%IPC_Vramp(1), CntrPar%IPC_Vramp(2), 0.0_DbKi, CntrPar%IPC_KP(i), ErrVar) LocalVar%IPC_KI(i) = sigma(LocalVar%WE_Vw, CntrPar%IPC_Vramp(1), CntrPar%IPC_Vramp(2), 0.0_DbKi, CntrPar%IPC_KI(i), ErrVar) END DO + + ! Handle saturation limit, depends on IPC_SatMode + IF (CntrPar%IPC_SatMode == 2) THEN + ! Saturate to min allowed pitch angle, softly using IPC_IntSat + LocalVar%IPC_IntSat = min(CntrPar%IPC_IntSat,LocalVar%BlPitchCMeas - CntrPar%PC_MinPit) + ELSEIF (CntrPar%IPC_SatMode == 3) THEN + ! Saturate to peak shaving, softly using IPC_IntSat + LocalVar%IPC_IntSat = min(CntrPar%IPC_IntSat,LocalVar%BlPitchCMeas - LocalVar%PC_MinPit) + ELSE + LocalVar%IPC_IntSat = CntrPar%IPC_IntSat + ENDIF ! Integrate the signal and multiply with the IPC gain IF ((CntrPar%IPC_ControlMode >= 1) .AND. (CntrPar%Y_ControlMode /= 2)) THEN - LocalVar%IPC_axisTilt_1P = PIController(axisTilt_1P, LocalVar%IPC_KP(1), LocalVar%IPC_KI(1), -CntrPar%IPC_IntSat, CntrPar%IPC_IntSat, LocalVar%DT, 0.0_DbKi, LocalVar%piP, LocalVar%restart, objInst%instPI) - LocalVar%IPC_axisYaw_1P = PIController(axisYawF_1P, LocalVar%IPC_KP(1), LocalVar%IPC_KI(1), -CntrPar%IPC_IntSat, CntrPar%IPC_IntSat, LocalVar%DT, 0.0_DbKi, LocalVar%piP, LocalVar%restart, objInst%instPI) + LocalVar%IPC_axisTilt_1P = PIController(axisTilt_1P, LocalVar%IPC_KP(1), LocalVar%IPC_KI(1), -LocalVar%IPC_IntSat, LocalVar%IPC_IntSat, LocalVar%DT, 0.0_DbKi, LocalVar%piP, LocalVar%restart, objInst%instPI) + LocalVar%IPC_axisYaw_1P = PIController(axisYawF_1P, LocalVar%IPC_KP(1), LocalVar%IPC_KI(1), -LocalVar%IPC_IntSat, LocalVar%IPC_IntSat, LocalVar%DT, 0.0_DbKi, LocalVar%piP, LocalVar%restart, objInst%instPI) IF (CntrPar%IPC_ControlMode >= 2) THEN - LocalVar%IPC_axisTilt_2P = PIController(axisTilt_2P, LocalVar%IPC_KP(2), LocalVar%IPC_KI(2), -CntrPar%IPC_IntSat, CntrPar%IPC_IntSat, LocalVar%DT, 0.0_DbKi, LocalVar%piP, LocalVar%restart, objInst%instPI) - LocalVar%IPC_axisYaw_2P = PIController(axisYawF_2P, LocalVar%IPC_KP(2), LocalVar%IPC_KI(2), -CntrPar%IPC_IntSat, CntrPar%IPC_IntSat, LocalVar%DT, 0.0_DbKi, LocalVar%piP, LocalVar%restart, objInst%instPI) + LocalVar%IPC_axisTilt_2P = PIController(axisTilt_2P, LocalVar%IPC_KP(2), LocalVar%IPC_KI(2), -LocalVar%IPC_IntSat, LocalVar%IPC_IntSat, LocalVar%DT, 0.0_DbKi, LocalVar%piP, LocalVar%restart, objInst%instPI) + LocalVar%IPC_axisYaw_2P = PIController(axisYawF_2P, LocalVar%IPC_KP(2), LocalVar%IPC_KI(2), -LocalVar%IPC_IntSat, LocalVar%IPC_IntSat, LocalVar%DT, 0.0_DbKi, LocalVar%piP, LocalVar%restart, objInst%instPI) END IF ELSE LocalVar%IPC_axisTilt_1P = 0.0 diff --git a/ROSCO/ROSCO/src/DISCON.F90 b/ROSCO/ROSCO/src/DISCON.F90 index 2b2ec286f..e27b06b87 100644 --- a/ROSCO/ROSCO/src/DISCON.F90 +++ b/ROSCO/ROSCO/src/DISCON.F90 @@ -44,7 +44,7 @@ SUBROUTINE DISCON(avrSWAP, aviFAIL, accINFILE, avcOUTNAME, avcMSG) BIND (C, NAME !REAL(ReKi), INTENT(IN) :: from_SC(*) ! DATA from the super controller !REAL(ReKi), INTENT(INOUT) :: to_SC(*) ! DATA to the super controller -REAL(C_FLOAT), INTENT(INOUT) :: avrSWAP(*) ! The swap array, used to pass data to, and receive data from, the DLL controller. +REAL(ReKi), INTENT(INOUT) :: avrSWAP(*) ! The swap array, used to pass data to, and receive data from, the DLL controller. INTEGER(C_INT), INTENT(INOUT) :: aviFAIL ! A flag used to indicate the success of this DLL call set as follows: 0 if the DLL call was successful, >0 if the DLL call was successful but cMessage should be issued as a warning messsage, <0 if the DLL call was unsuccessful or for any other reason the simulation is to be stopped at this point with cMessage as the error message. CHARACTER(KIND=C_CHAR), INTENT(IN ) :: accINFILE(NINT(avrSWAP(50))) ! The name of the parameter input file CHARACTER(KIND=C_CHAR), INTENT(IN ) :: avcOUTNAME(NINT(avrSWAP(51))) ! OUTNAME (Simulation RootName) @@ -79,7 +79,7 @@ SUBROUTINE DISCON(avrSWAP, aviFAIL, accINFILE, avcOUTNAME, avcMSG) BIND (C, NAME END IF ! Read avrSWAP array into derived types/variables -CALL ReadAvrSWAP(avrSWAP, LocalVar) +CALL ReadAvrSWAP(avrSWAP, LocalVar, CntrPar) ! Set Control Parameters CALL SetParameters(avrSWAP, accINFILE, SIZE(avcMSG), CntrPar, LocalVar, objInst, PerfData, zmqVar, ErrVar) diff --git a/ROSCO/ROSCO/src/ExtControl.f90 b/ROSCO/ROSCO/src/ExtControl.f90 index 2a398cda2..17d821e49 100644 --- a/ROSCO/ROSCO/src/ExtControl.f90 +++ b/ROSCO/ROSCO/src/ExtControl.f90 @@ -26,6 +26,7 @@ MODULE ExtControl USE Functions USE ROSCO_Types USE SysSubs + USE Constants IMPLICIT NONE @@ -35,7 +36,9 @@ MODULE ExtControl SUBROUTINE BladedDLL_Legacy_Procedure ( avrSWAP, aviFAIL, accINFILE, avcOUTNAME, avcMSG ) BIND(C) USE, INTRINSIC :: ISO_C_Binding - REAL(C_FLOAT), INTENT(INOUT) :: avrSWAP (*) !< DATA + USE Constants + + REAL(ReKi), INTENT(INOUT) :: avrSWAP (*) !< DATA INTEGER(C_INT), INTENT(INOUT) :: aviFAIL !< FLAG (Status set in DLL and returned to simulation code) CHARACTER(KIND=C_CHAR), INTENT(IN) :: accINFILE (*) !< INFILE CHARACTER(KIND=C_CHAR), INTENT(INOUT) :: avcOUTNAME(*) !< OUTNAME (in:Simulation RootName; out:Name:Units; of logging channels) @@ -54,7 +57,7 @@ SUBROUTINE ExtController(avrSWAP, CntrPar, LocalVar, ExtDLL, ErrVar) TYPE(ExtControlType), INTENT(INOUT) :: ExtDLL - REAL(C_FLOAT), INTENT(INOUT) :: avrSWAP(*) ! The swap array, used to pass data to, and receive data from the DLL controller. + REAL(ReKi), INTENT(INOUT) :: avrSWAP(*) ! The swap array, used to pass data to, and receive data from the DLL controller. ! Temporary variables ! CHARACTER(1024), PARAMETER :: ExtDLL_InFile = '/Users/dzalkind/Tools/ROSCO/Test_Cases/IEA-15-240-RWT-UMaineSemi/ServoData/DISCON-UMaineSemi.IN' diff --git a/ROSCO/ROSCO/src/Filters.f90 b/ROSCO/ROSCO/src/Filters.f90 index 5123b74c0..a108dfda9 100644 --- a/ROSCO/ROSCO/src/Filters.f90 +++ b/ROSCO/ROSCO/src/Filters.f90 @@ -26,7 +26,7 @@ MODULE Filters CONTAINS !------------------------------------------------------------------------------------------------------------------------------- - REAL(DbKi) FUNCTION LPFilter(InputSignal, DT, CornerFreq, FP, iStatus, reset, inst) + REAL(DbKi) FUNCTION LPFilter(InputSignal, DT, CornerFreq, FP, iStatus, reset, inst, InitialValue) ! Discrete time Low-Pass Filter of the form: ! Continuous Time Form: H(s) = CornerFreq/(1 + CornerFreq) ! Discrete Time Form: H(z) = (b1z + b0) / (a1*z + a0) @@ -40,11 +40,18 @@ REAL(DbKi) FUNCTION LPFilter(InputSignal, DT, CornerFreq, FP, iStatus, reset, in INTEGER(IntKi), INTENT(IN) :: iStatus ! A status flag set by the simulation as follows: 0 if this is the first call, 1 for all subsequent time steps, -1 if this is the final call at the end of the simulation. INTEGER(IntKi), INTENT(INOUT) :: inst ! Instance number. Every instance of this function needs to have an unique instance number to ensure instances don't influence each other. LOGICAL(4), INTENT(IN) :: reset ! Reset the filter to the input signal + REAL(DbKi), OPTIONAL, INTENT(IN) :: InitialValue ! Value to set when reset + + REAL(DbKi) :: InitialValue_ ! Value to set when reset + + ! Defaults + InitialValue_ = InputSignal + IF (PRESENT(InitialValue)) InitialValue_ = InitialValue - ! Initialization + ! Initialization IF ((iStatus == 0) .OR. reset) THEN - FP%lpf1_OutputSignalLast(inst) = InputSignal - FP%lpf1_InputSignalLast(inst) = InputSignal + FP%lpf1_OutputSignalLast(inst) = InitialValue_ + FP%lpf1_InputSignalLast(inst) = InitialValue_ FP%lpf1_a1(inst) = 2 + CornerFreq*DT FP%lpf1_a0(inst) = CornerFreq*DT - 2 FP%lpf1_b1(inst) = CornerFreq*DT @@ -63,7 +70,7 @@ REAL(DbKi) FUNCTION LPFilter(InputSignal, DT, CornerFreq, FP, iStatus, reset, in END FUNCTION LPFilter !------------------------------------------------------------------------------------------------------------------------------- - REAL(DbKi) FUNCTION SecLPFilter(InputSignal, DT, CornerFreq, Damp, FP, iStatus, reset, inst) + REAL(DbKi) FUNCTION SecLPFilter(InputSignal, DT, CornerFreq, Damp, FP, iStatus, reset, inst, InitialValue) ! Discrete time Low-Pass Filter of the form: ! Continuous Time Form: H(s) = CornerFreq^2/(s^2 + 2*CornerFreq*Damp*s + CornerFreq^2) ! Discrete Time From: H(z) = (b2*z^2 + b1*z + b0) / (a2*z^2 + a1*z + a0) @@ -75,14 +82,21 @@ REAL(DbKi) FUNCTION SecLPFilter(InputSignal, DT, CornerFreq, Damp, FP, iStatus, REAL(DbKi), INTENT(IN) :: Damp ! Dampening constant INTEGER(IntKi), INTENT(IN) :: iStatus ! A status flag set by the simulation as follows: 0 if this is the first call, 1 for all subsequent time steps, -1 if this is the final call at the end of the simulation. INTEGER(IntKi), INTENT(INOUT) :: inst ! Instance number. Every instance of this function needs to have an unique instance number to ensure instances don't influence each other. - LOGICAL(4), INTENT(IN) :: reset ! Reset the filter to the input signal + LOGICAL(4), INTENT(IN) :: reset ! Reset the filter to the input signal + REAL(DbKi), OPTIONAL, INTENT(IN) :: InitialValue ! Value to set when reset + + REAL(DbKi) :: InitialValue_ ! Value to set when reset + + ! Defaults + InitialValue_ = InputSignal + IF (PRESENT(InitialValue)) InitialValue_ = InitialValue ! Initialization IF ((iStatus == 0) .OR. reset ) THEN - FP%lpf2_OutputSignalLast1(inst) = InputSignal - FP%lpf2_OutputSignalLast2(inst) = InputSignal - FP%lpf2_InputSignalLast1(inst) = InputSignal - FP%lpf2_InputSignalLast2(inst) = InputSignal + FP%lpf2_OutputSignalLast1(inst) = InitialValue_ + FP%lpf2_OutputSignalLast2(inst) = InitialValue_ + FP%lpf2_InputSignalLast1(inst) = InitialValue_ + FP%lpf2_InputSignalLast2(inst) = InitialValue_ ! Coefficients FP%lpf2_a2(inst) = DT**2.0*CornerFreq**2.0 + 4.0 + 4.0*Damp*CornerFreq*DT @@ -106,7 +120,7 @@ REAL(DbKi) FUNCTION SecLPFilter(InputSignal, DT, CornerFreq, Damp, FP, iStatus, END FUNCTION SecLPFilter !------------------------------------------------------------------------------------------------------------------------------- - REAL(DbKi) FUNCTION HPFilter( InputSignal, DT, CornerFreq, FP, iStatus, reset, inst) + REAL(DbKi) FUNCTION HPFilter( InputSignal, DT, CornerFreq, FP, iStatus, reset, inst, InitialValue) ! Discrete time High-Pass Filter USE ROSCO_Types, ONLY : FilterParameters TYPE(FilterParameters), INTENT(INOUT) :: FP @@ -119,11 +133,18 @@ REAL(DbKi) FUNCTION HPFilter( InputSignal, DT, CornerFreq, FP, iStatus, reset, i LOGICAL(4), INTENT(IN) :: reset ! Reset the filter to the input signal ! Local REAL(DbKi) :: K ! Constant gain + REAL(DbKi), OPTIONAL, INTENT(IN) :: InitialValue ! Value to set when reset + + REAL(DbKi) :: InitialValue_ ! Value to set when reset + + ! Defaults + InitialValue_ = InputSignal + IF (PRESENT(InitialValue)) InitialValue_ = InitialValue ! Initialization IF ((iStatus == 0) .OR. reset) THEN - FP%hpf_OutputSignalLast(inst) = InputSignal - FP%hpf_InputSignalLast(inst) = InputSignal + FP%hpf_OutputSignalLast(inst) = InitialValue_ + FP%hpf_InputSignalLast(inst) = InitialValue_ ENDIF K = 2.0 / DT @@ -137,7 +158,7 @@ REAL(DbKi) FUNCTION HPFilter( InputSignal, DT, CornerFreq, FP, iStatus, reset, i END FUNCTION HPFilter !------------------------------------------------------------------------------------------------------------------------------- - REAL(DbKi) FUNCTION NotchFilterSlopes(InputSignal, DT, CornerFreq, Damp, FP, iStatus, reset, inst, Moving) + REAL(DbKi) FUNCTION NotchFilterSlopes(InputSignal, DT, CornerFreq, Damp, FP, iStatus, reset, inst, Moving, InitialValue) ! Discrete time inverted Notch Filter with descending slopes, G = CornerFreq*s/(Damp*s^2+CornerFreq*s+Damp*CornerFreq^2) USE ROSCO_Types, ONLY : FilterParameters TYPE(FilterParameters), INTENT(INOUT) :: FP @@ -150,9 +171,15 @@ REAL(DbKi) FUNCTION NotchFilterSlopes(InputSignal, DT, CornerFreq, Damp, FP, iSt INTEGER(IntKi), INTENT(INOUT) :: inst ! Instance number. Every instance of this function needs to have an unique instance number to ensure instances don't influence each other. LOGICAL(4), INTENT(IN) :: reset ! Reset the filter to the input signal LOGICAL, OPTIONAL, INTENT(IN) :: Moving ! Moving CornerFreq flag + REAL(DbKi), OPTIONAL, INTENT(IN) :: InitialValue ! Value to set when reset LOGICAL :: Moving_ ! Local version REAL(DbKi) :: CornerFreq_ ! Local version + REAL(DbKi) :: InitialValue_ ! Value to set when reset + + ! Defaults + InitialValue_ = InputSignal + IF (PRESENT(InitialValue)) InitialValue_ = InitialValue Moving_ = .FALSE. IF (PRESENT(Moving)) Moving_ = Moving @@ -166,10 +193,10 @@ REAL(DbKi) FUNCTION NotchFilterSlopes(InputSignal, DT, CornerFreq, Damp, FP, iSt ! Initialization IF ((iStatus == 0) .OR. reset) THEN - FP%nfs_OutputSignalLast1(inst) = InputSignal - FP%nfs_OutputSignalLast2(inst) = InputSignal - FP%nfs_InputSignalLast1(inst) = InputSignal - FP%nfs_InputSignalLast2(inst) = InputSignal + FP%nfs_OutputSignalLast1(inst) = InitialValue_ + FP%nfs_OutputSignalLast2(inst) = InitialValue_ + FP%nfs_InputSignalLast1(inst) = InitialValue_ + FP%nfs_InputSignalLast2(inst) = InitialValue_ ENDIF IF ((iStatus == 0) .OR. reset .OR. Moving_) THEN @@ -192,7 +219,7 @@ REAL(DbKi) FUNCTION NotchFilterSlopes(InputSignal, DT, CornerFreq, Damp, FP, iSt END FUNCTION NotchFilterSlopes !------------------------------------------------------------------------------------------------------------------------------- - REAL(DbKi) FUNCTION NotchFilter(InputSignal, DT, omega, betaNum, betaDen, FP, iStatus, reset, inst) + REAL(DbKi) FUNCTION NotchFilter(InputSignal, DT, omega, betaNum, betaDen, FP, iStatus, reset, inst, InitialValue) ! Discrete time Notch Filter ! Continuous Time Form: G(s) = (s^2 + 2*omega*betaNum*s + omega^2)/(s^2 + 2*omega*betaDen*s + omega^2) ! Discrete Time Form: H(z) = (b2*z^2 +b1*z^2 + b0*z)/((z^2 +a1*z^2 + a0*z)) @@ -207,16 +234,22 @@ REAL(DbKi) FUNCTION NotchFilter(InputSignal, DT, omega, betaNum, betaDen, FP, iS INTEGER(IntKi), INTENT(IN) :: iStatus ! A status flag set by the simulation as follows: 0 if this is the first call, 1 for all subsequent time steps, -1 if this is the final call at the end of the simulation. INTEGER(IntKi), INTENT(INOUT) :: inst ! Instance number. Every instance of this function needs to have an unique instance number to ensure instances don't influence each other. LOGICAL(4), INTENT(IN) :: reset ! Reset the filter to the input signal + REAL(DbKi), OPTIONAL, INTENT(IN) :: InitialValue ! Value to set when reset ! Local REAL(DbKi) :: K ! Constant gain + REAL(DbKi) :: InitialValue_ ! Value to set when reset + + ! Defaults + InitialValue_ = InputSignal + IF (PRESENT(InitialValue)) InitialValue_ = InitialValue ! Initialization K = 2.0/DT IF ((iStatus == 0) .OR. reset) THEN - FP%nf_OutputSignalLast1(inst) = InputSignal - FP%nf_OutputSignalLast2(inst) = InputSignal - FP%nf_InputSignalLast1(inst) = InputSignal - FP%nf_InputSignalLast2(inst) = InputSignal + FP%nf_OutputSignalLast1(inst) = InitialValue_ + FP%nf_OutputSignalLast2(inst) = InitialValue_ + FP%nf_InputSignalLast1(inst) = InitialValue_ + FP%nf_InputSignalLast2(inst) = InitialValue_ FP%nf_b2(inst) = (K**2.0 + 2.0*omega*BetaNum*K + omega**2.0)/(K**2.0 + 2.0*omega*BetaDen*K + omega**2.0) FP%nf_b1(inst) = (2.0*omega**2.0 - 2.0*K**2.0) / (K**2.0 + 2.0*omega*BetaDen*K + omega**2.0); FP%nf_b0(inst) = (K**2.0 - 2.0*omega*BetaNum*K + omega**2.0) / (K**2.0 + 2.0*omega*BetaDen*K + omega**2.0) @@ -269,6 +302,10 @@ SUBROUTINE PreFilterMeasuredSignals(CntrPar, LocalVar, DebugVar, objInst, ErrVar ! Filtering the tower fore-aft acceleration signal IF (CntrPar%Fl_Mode > 0) THEN ! Force to start at 0 + IF (LocalVar%iStatus == 0 .AND. LocalVar%Time == 0) THEN + LocalVar%NacIMU_FA_Acc = 0 + LocalVar%FA_Acc = 0 + ENDIF LocalVar%NacIMU_FA_AccF = SecLPFilter(LocalVar%NacIMU_FA_Acc, LocalVar%DT, CntrPar%F_FlCornerFreq(1), CntrPar%F_FlCornerFreq(2), LocalVar%FP, LocalVar%iStatus, LocalVar%restart, objInst%instSecLPF) ! Fixed Damping LocalVar%FA_AccF = SecLPFilter(LocalVar%FA_Acc, LocalVar%DT, CntrPar%F_FlCornerFreq(1), CntrPar%F_FlCornerFreq(2), LocalVar%FP, LocalVar%iStatus, LocalVar%restart, objInst%instSecLPF) ! Fixed Damping LocalVar%NacIMU_FA_AccF = HPFilter(LocalVar%NacIMU_FA_AccF, LocalVar%DT, CntrPar%F_FlHighPassFreq, LocalVar%FP, LocalVar%iStatus, LocalVar%restart, objInst%instHPF) diff --git a/ROSCO/ROSCO/src/Functions.f90 b/ROSCO/ROSCO/src/Functions.f90 index af9a0c2cd..3e0e225e3 100644 --- a/ROSCO/ROSCO/src/Functions.f90 +++ b/ROSCO/ROSCO/src/Functions.f90 @@ -48,21 +48,45 @@ REAL(DbKi) FUNCTION saturate(inputValue, minValue, maxValue) END FUNCTION saturate !------------------------------------------------------------------------------------------------------------------------------- - REAL(DbKi) FUNCTION ratelimit(inputSignal, inputSignalPrev, minRate, maxRate, DT) + REAL(DbKi) FUNCTION ratelimit(inputSignal, minRate, maxRate, DT, reset, rlP, inst, ResetValue) ! Saturates inputValue. Makes sure it is not smaller than minValue and not larger than maxValue + USE ROSCO_Types, ONLY : rlParams + + IMPLICIT NONE - REAL(DbKi), INTENT(IN) :: inputSignal - REAL(DbKi), INTENT(IN) :: inputSignalPrev - REAL(DbKi), INTENT(IN) :: minRate - REAL(DbKi), INTENT(IN) :: maxRate - REAL(DbKi), INTENT(IN) :: DT + REAL(DbKi), INTENT(IN) :: inputSignal + REAL(DbKi), INTENT(IN) :: minRate + REAL(DbKi), INTENT(IN) :: maxRate + REAL(DbKi), INTENT(IN) :: DT + LOGICAL, INTENT(IN) :: reset + TYPE(rlParams), INTENT(INOUT) :: rlP + INTEGER(IntKi), INTENT(INOUT) :: inst + REAL(DbKi), OPTIONAL, INTENT(IN) :: ResetValue ! Value to base rate limit off if restarting + ! Local variables REAL(DbKi) :: rate + REAL(DbKi) :: ResetValue_ + + ResetValue_ = inputSignal + IF (PRESENT(ResetValue)) ResetValue_ = ResetValue + + IF (reset) THEN + rlP%LastSignal(inst) = ResetValue_ + ratelimit = ResetValue_ + + ELSE + rate = (inputSignal - rlP%LastSignal(inst))/DT ! Signal rate (unsaturated) + rate = saturate(rate, minRate, maxRate) ! Saturate the signal rate - rate = (inputSignal - inputSignalPrev)/DT ! Signal rate (unsaturated) - rate = saturate(rate, minRate, maxRate) ! Saturate the signal rate - ratelimit = inputSignalPrev + rate*DT ! Saturate the overall command using the rate limit + ratelimit = rlP%LastSignal(inst) + rate*DT + + rlP%LastSignal(inst) = ratelimit + + ENDIF + + ! Increment instance + inst = inst + 1 ! Saturate the overall command using the rate limit END FUNCTION ratelimit @@ -575,6 +599,7 @@ REAL(DbKi) FUNCTION sigma(x, x0, x1, y0, y1, ErrVar) END FUNCTION sigma + !------------------------------------------------------------------------------------------------------------------------------- ! Copied from NWTC_IO.f90 !> This function returns a character string encoded with today's date in the form dd-mmm-ccyy. diff --git a/ROSCO/ROSCO/src/ROSCO_IO.f90 b/ROSCO/ROSCO/src/ROSCO_IO.f90 index d495263b5..d465d512e 100644 --- a/ROSCO/ROSCO/src/ROSCO_IO.f90 +++ b/ROSCO/ROSCO/src/ROSCO_IO.f90 @@ -1,5 +1,5 @@ ! ROSCO IO -! This file is automatically generated by write_registry.py using ROSCO v2.6.0 +! This file is automatically generated by write_registry.py using ROSCO v2.7.0 ! For any modification to the registry, please edit the rosco_types.yaml accordingly MODULE ROSCO_IO @@ -53,6 +53,7 @@ SUBROUTINE WriteRestartFile(LocalVar, CntrPar, ErrVar, objInst, RootName, size_a WRITE( Un, IOSTAT=ErrStat) LocalVar%BlPitch(1) WRITE( Un, IOSTAT=ErrStat) LocalVar%BlPitch(2) WRITE( Un, IOSTAT=ErrStat) LocalVar%BlPitch(3) + WRITE( Un, IOSTAT=ErrStat) LocalVar%BlPitchCMeas WRITE( Un, IOSTAT=ErrStat) LocalVar%Azimuth WRITE( Un, IOSTAT=ErrStat) LocalVar%NumBl WRITE( Un, IOSTAT=ErrStat) LocalVar%FA_Acc @@ -93,6 +94,7 @@ SUBROUTINE WriteRestartFile(LocalVar, CntrPar, ErrVar, objInst, RootName, size_a WRITE( Un, IOSTAT=ErrStat) LocalVar%IPC_KI(2) WRITE( Un, IOSTAT=ErrStat) LocalVar%IPC_KP(1) WRITE( Un, IOSTAT=ErrStat) LocalVar%IPC_KP(2) + WRITE( Un, IOSTAT=ErrStat) LocalVar%IPC_IntSat WRITE( Un, IOSTAT=ErrStat) LocalVar%PC_State WRITE( Un, IOSTAT=ErrStat) LocalVar%PitCom(1) WRITE( Un, IOSTAT=ErrStat) LocalVar%PitCom(2) @@ -176,12 +178,14 @@ SUBROUTINE WriteRestartFile(LocalVar, CntrPar, ErrVar, objInst, RootName, size_a WRITE( Un, IOSTAT=ErrStat) LocalVar%piP%ITermLast WRITE( Un, IOSTAT=ErrStat) LocalVar%piP%ITerm2 WRITE( Un, IOSTAT=ErrStat) LocalVar%piP%ITermLast2 + WRITE( Un, IOSTAT=ErrStat) LocalVar%rlP%LastSignal WRITE( Un, IOSTAT=ErrStat) objInst%instLPF WRITE( Un, IOSTAT=ErrStat) objInst%instSecLPF WRITE( Un, IOSTAT=ErrStat) objInst%instHPF WRITE( Un, IOSTAT=ErrStat) objInst%instNotchSlopes WRITE( Un, IOSTAT=ErrStat) objInst%instNotch WRITE( Un, IOSTAT=ErrStat) objInst%instPI + WRITE( Un, IOSTAT=ErrStat) objInst%instRL Close ( Un ) ENDIF END SUBROUTINE WriteRestartFile @@ -194,7 +198,7 @@ SUBROUTINE ReadRestartFile(avrSWAP, LocalVar, CntrPar, objInst, PerfData, RootNa TYPE(PerformanceData), INTENT(INOUT) :: PerfData TYPE(ErrorVariables), INTENT(INOUT) :: ErrVar TYPE(ZMQ_Variables), INTENT(INOUT) :: zmqVar - REAL(C_FLOAT), INTENT(IN) :: avrSWAP(*) + REAL(ReKi), INTENT(IN) :: avrSWAP(*) INTEGER(IntKi), INTENT(IN) :: size_avcOUTNAME CHARACTER(size_avcOUTNAME-1), INTENT(IN) :: RootName @@ -232,6 +236,7 @@ SUBROUTINE ReadRestartFile(avrSWAP, LocalVar, CntrPar, objInst, PerfData, RootNa READ( Un, IOSTAT=ErrStat) LocalVar%BlPitch(1) READ( Un, IOSTAT=ErrStat) LocalVar%BlPitch(2) READ( Un, IOSTAT=ErrStat) LocalVar%BlPitch(3) + READ( Un, IOSTAT=ErrStat) LocalVar%BlPitchCMeas READ( Un, IOSTAT=ErrStat) LocalVar%Azimuth READ( Un, IOSTAT=ErrStat) LocalVar%NumBl READ( Un, IOSTAT=ErrStat) LocalVar%FA_Acc @@ -272,6 +277,7 @@ SUBROUTINE ReadRestartFile(avrSWAP, LocalVar, CntrPar, objInst, PerfData, RootNa READ( Un, IOSTAT=ErrStat) LocalVar%IPC_KI(2) READ( Un, IOSTAT=ErrStat) LocalVar%IPC_KP(1) READ( Un, IOSTAT=ErrStat) LocalVar%IPC_KP(2) + READ( Un, IOSTAT=ErrStat) LocalVar%IPC_IntSat READ( Un, IOSTAT=ErrStat) LocalVar%PC_State READ( Un, IOSTAT=ErrStat) LocalVar%PitCom(1) READ( Un, IOSTAT=ErrStat) LocalVar%PitCom(2) @@ -356,12 +362,14 @@ SUBROUTINE ReadRestartFile(avrSWAP, LocalVar, CntrPar, objInst, PerfData, RootNa READ( Un, IOSTAT=ErrStat) LocalVar%piP%ITermLast READ( Un, IOSTAT=ErrStat) LocalVar%piP%ITerm2 READ( Un, IOSTAT=ErrStat) LocalVar%piP%ITermLast2 + READ( Un, IOSTAT=ErrStat) LocalVar%rlP%LastSignal READ( Un, IOSTAT=ErrStat) objInst%instLPF READ( Un, IOSTAT=ErrStat) objInst%instSecLPF READ( Un, IOSTAT=ErrStat) objInst%instHPF READ( Un, IOSTAT=ErrStat) objInst%instNotchSlopes READ( Un, IOSTAT=ErrStat) objInst%instNotch READ( Un, IOSTAT=ErrStat) objInst%instPI + READ( Un, IOSTAT=ErrStat) objInst%instRL Close ( Un ) ENDIF ! Read Parameter files @@ -422,19 +430,19 @@ SUBROUTINE Debug(LocalVar, CntrPar, DebugVar, ErrVar, avrSWAP, RootName, size_av DebugOutData(20) = DebugVar%YawRateCom DebugOutData(21) = DebugVar%NacHeadingTarget DebugOutData(22) = DebugVar%NacVaneOffset - DebugOutData(23) = DebugVar%Yaw_err + DebugOutData(23) = DebugVar%Yaw_Err DebugOutData(24) = DebugVar%YawState DebugOutStrings = [CHARACTER(15) :: 'WE_Cp', 'WE_b', 'WE_w', 'WE_t', 'WE_Vm', & 'WE_Vt', 'WE_Vw', 'WE_lambda', 'PC_PICommand', 'GenSpeedF', & 'RotSpeedF', 'NacIMU_FA_AccF', 'FA_AccF', 'Fl_PitCom', 'PC_MinPit', & 'axisTilt_1P', 'axisYaw_1P', 'axisTilt_2P', 'axisYaw_2P', 'YawRateCom', & - 'NacHeadingTarget', 'NacVaneOffset', 'Yaw_err', 'YawState'] + 'NacHeadingTarget', 'NacVaneOffset', 'Yaw_Err', 'YawState'] DebugOutUnits = [CHARACTER(15) :: '[-]', '[-]', '[-]', '[-]', '[m/s]', & '[m/s]', '[m/s]', '[rad]', '[rad]', '[rad/s]', & '[rad/s]', '[rad/s]', '[m/s]', '[rad]', '[rad]', & - '', '', '', '', '[rad/s]', & - '[rad]', '[rad]', '[rad]', ''] - nLocalVars = 69 + '[N/A]', '[N/A]', '[N/A]', '[N/A]', '[rad/s]', & + '[deg]', '[deg]', '[deg]', '[N/A]'] + nLocalVars = 71 Allocate(LocalVarOutData(nLocalVars)) Allocate(LocalVarOutStrings(nLocalVars)) LocalVarOutData(1) = LocalVar%iStatus @@ -449,77 +457,80 @@ SUBROUTINE Debug(LocalVar, CntrPar, DebugVar, ErrVar, avrSWAP, RootName, size_av LocalVarOutData(10) = LocalVar%rootMOOP(1) LocalVarOutData(11) = LocalVar%rootMOOPF(1) LocalVarOutData(12) = LocalVar%BlPitch(1) - LocalVarOutData(13) = LocalVar%Azimuth - LocalVarOutData(14) = LocalVar%NumBl - LocalVarOutData(15) = LocalVar%FA_Acc - LocalVarOutData(16) = LocalVar%NacIMU_FA_Acc - LocalVarOutData(17) = LocalVar%FA_AccHPF - LocalVarOutData(18) = LocalVar%FA_AccHPFI - LocalVarOutData(19) = LocalVar%FA_PitCom(1) - LocalVarOutData(20) = LocalVar%RotSpeedF - LocalVarOutData(21) = LocalVar%GenSpeedF - LocalVarOutData(22) = LocalVar%GenTq - LocalVarOutData(23) = LocalVar%GenTqMeas - LocalVarOutData(24) = LocalVar%GenArTq - LocalVarOutData(25) = LocalVar%GenBrTq - LocalVarOutData(26) = LocalVar%IPC_PitComF(1) - LocalVarOutData(27) = LocalVar%PC_KP - LocalVarOutData(28) = LocalVar%PC_KI - LocalVarOutData(29) = LocalVar%PC_KD - LocalVarOutData(30) = LocalVar%PC_TF - LocalVarOutData(31) = LocalVar%PC_MaxPit - LocalVarOutData(32) = LocalVar%PC_MinPit - LocalVarOutData(33) = LocalVar%PC_PitComT - LocalVarOutData(34) = LocalVar%PC_PitComT_Last - LocalVarOutData(35) = LocalVar%PC_PitComTF - LocalVarOutData(36) = LocalVar%PC_PitComT_IPC(1) - LocalVarOutData(37) = LocalVar%PC_PwrErr - LocalVarOutData(38) = LocalVar%PC_SpdErr - LocalVarOutData(39) = LocalVar%IPC_AxisTilt_1P - LocalVarOutData(40) = LocalVar%IPC_AxisYaw_1P - LocalVarOutData(41) = LocalVar%IPC_AxisTilt_2P - LocalVarOutData(42) = LocalVar%IPC_AxisYaw_2P - LocalVarOutData(43) = LocalVar%IPC_KI(1) - LocalVarOutData(44) = LocalVar%IPC_KP(1) - LocalVarOutData(45) = LocalVar%PC_State - LocalVarOutData(46) = LocalVar%PitCom(1) - LocalVarOutData(47) = LocalVar%PitComAct(1) - LocalVarOutData(48) = LocalVar%SS_DelOmegaF - LocalVarOutData(49) = LocalVar%TestType - LocalVarOutData(50) = LocalVar%VS_MaxTq - LocalVarOutData(51) = LocalVar%VS_LastGenTrq - LocalVarOutData(52) = LocalVar%VS_LastGenPwr - LocalVarOutData(53) = LocalVar%VS_MechGenPwr - LocalVarOutData(54) = LocalVar%VS_SpdErrAr - LocalVarOutData(55) = LocalVar%VS_SpdErrBr - LocalVarOutData(56) = LocalVar%VS_SpdErr - LocalVarOutData(57) = LocalVar%VS_State - LocalVarOutData(58) = LocalVar%VS_Rgn3Pitch - LocalVarOutData(59) = LocalVar%WE_Vw - LocalVarOutData(60) = LocalVar%WE_Vw_F - LocalVarOutData(61) = LocalVar%WE_VwI - LocalVarOutData(62) = LocalVar%WE_VwIdot - LocalVarOutData(63) = LocalVar%VS_LastGenTrqF - LocalVarOutData(64) = LocalVar%Fl_PitCom - LocalVarOutData(65) = LocalVar%NACIMU_FA_AccF - LocalVarOutData(66) = LocalVar%FA_AccF - LocalVarOutData(67) = LocalVar%Flp_Angle(1) - LocalVarOutData(68) = LocalVar%RootMyb_Last(1) - LocalVarOutData(69) = LocalVar%ACC_INFILE_SIZE + LocalVarOutData(13) = LocalVar%BlPitchCMeas + LocalVarOutData(14) = LocalVar%Azimuth + LocalVarOutData(15) = LocalVar%NumBl + LocalVarOutData(16) = LocalVar%FA_Acc + LocalVarOutData(17) = LocalVar%NacIMU_FA_Acc + LocalVarOutData(18) = LocalVar%FA_AccHPF + LocalVarOutData(19) = LocalVar%FA_AccHPFI + LocalVarOutData(20) = LocalVar%FA_PitCom(1) + LocalVarOutData(21) = LocalVar%RotSpeedF + LocalVarOutData(22) = LocalVar%GenSpeedF + LocalVarOutData(23) = LocalVar%GenTq + LocalVarOutData(24) = LocalVar%GenTqMeas + LocalVarOutData(25) = LocalVar%GenArTq + LocalVarOutData(26) = LocalVar%GenBrTq + LocalVarOutData(27) = LocalVar%IPC_PitComF(1) + LocalVarOutData(28) = LocalVar%PC_KP + LocalVarOutData(29) = LocalVar%PC_KI + LocalVarOutData(30) = LocalVar%PC_KD + LocalVarOutData(31) = LocalVar%PC_TF + LocalVarOutData(32) = LocalVar%PC_MaxPit + LocalVarOutData(33) = LocalVar%PC_MinPit + LocalVarOutData(34) = LocalVar%PC_PitComT + LocalVarOutData(35) = LocalVar%PC_PitComT_Last + LocalVarOutData(36) = LocalVar%PC_PitComTF + LocalVarOutData(37) = LocalVar%PC_PitComT_IPC(1) + LocalVarOutData(38) = LocalVar%PC_PwrErr + LocalVarOutData(39) = LocalVar%PC_SpdErr + LocalVarOutData(40) = LocalVar%IPC_AxisTilt_1P + LocalVarOutData(41) = LocalVar%IPC_AxisYaw_1P + LocalVarOutData(42) = LocalVar%IPC_AxisTilt_2P + LocalVarOutData(43) = LocalVar%IPC_AxisYaw_2P + LocalVarOutData(44) = LocalVar%IPC_KI(1) + LocalVarOutData(45) = LocalVar%IPC_KP(1) + LocalVarOutData(46) = LocalVar%IPC_IntSat + LocalVarOutData(47) = LocalVar%PC_State + LocalVarOutData(48) = LocalVar%PitCom(1) + LocalVarOutData(49) = LocalVar%PitComAct(1) + LocalVarOutData(50) = LocalVar%SS_DelOmegaF + LocalVarOutData(51) = LocalVar%TestType + LocalVarOutData(52) = LocalVar%VS_MaxTq + LocalVarOutData(53) = LocalVar%VS_LastGenTrq + LocalVarOutData(54) = LocalVar%VS_LastGenPwr + LocalVarOutData(55) = LocalVar%VS_MechGenPwr + LocalVarOutData(56) = LocalVar%VS_SpdErrAr + LocalVarOutData(57) = LocalVar%VS_SpdErrBr + LocalVarOutData(58) = LocalVar%VS_SpdErr + LocalVarOutData(59) = LocalVar%VS_State + LocalVarOutData(60) = LocalVar%VS_Rgn3Pitch + LocalVarOutData(61) = LocalVar%WE_Vw + LocalVarOutData(62) = LocalVar%WE_Vw_F + LocalVarOutData(63) = LocalVar%WE_VwI + LocalVarOutData(64) = LocalVar%WE_VwIdot + LocalVarOutData(65) = LocalVar%VS_LastGenTrqF + LocalVarOutData(66) = LocalVar%Fl_PitCom + LocalVarOutData(67) = LocalVar%NACIMU_FA_AccF + LocalVarOutData(68) = LocalVar%FA_AccF + LocalVarOutData(69) = LocalVar%Flp_Angle(1) + LocalVarOutData(70) = LocalVar%RootMyb_Last(1) + LocalVarOutData(71) = LocalVar%ACC_INFILE_SIZE LocalVarOutStrings = [CHARACTER(15) :: 'iStatus', 'Time', 'DT', 'VS_GenPwr', 'GenSpeed', & 'RotSpeed', 'NacHeading', 'NacVane', 'HorWindV', 'rootMOOP', & - 'rootMOOPF', 'BlPitch', 'Azimuth', 'NumBl', 'FA_Acc', & - 'NacIMU_FA_Acc', 'FA_AccHPF', 'FA_AccHPFI', 'FA_PitCom', 'RotSpeedF', & - 'GenSpeedF', 'GenTq', 'GenTqMeas', 'GenArTq', 'GenBrTq', & - 'IPC_PitComF', 'PC_KP', 'PC_KI', 'PC_KD', 'PC_TF', & - 'PC_MaxPit', 'PC_MinPit', 'PC_PitComT', 'PC_PitComT_Last', 'PC_PitComTF', & - 'PC_PitComT_IPC', 'PC_PwrErr', 'PC_SpdErr', 'IPC_AxisTilt_1P', 'IPC_AxisYaw_1P', & - 'IPC_AxisTilt_2P', 'IPC_AxisYaw_2P', 'IPC_KI', 'IPC_KP', 'PC_State', & - 'PitCom', 'PitComAct', 'SS_DelOmegaF', 'TestType', 'VS_MaxTq', & - 'VS_LastGenTrq', 'VS_LastGenPwr', 'VS_MechGenPwr', 'VS_SpdErrAr', 'VS_SpdErrBr', & - 'VS_SpdErr', 'VS_State', 'VS_Rgn3Pitch', 'WE_Vw', 'WE_Vw_F', & - 'WE_VwI', 'WE_VwIdot', 'VS_LastGenTrqF', 'Fl_PitCom', 'NACIMU_FA_AccF', & - 'FA_AccF', 'Flp_Angle', 'RootMyb_Last', 'ACC_INFILE_SIZE'] + 'rootMOOPF', 'BlPitch', 'BlPitchCMeas', 'Azimuth', 'NumBl', & + 'FA_Acc', 'NacIMU_FA_Acc', 'FA_AccHPF', 'FA_AccHPFI', 'FA_PitCom', & + 'RotSpeedF', 'GenSpeedF', 'GenTq', 'GenTqMeas', 'GenArTq', & + 'GenBrTq', 'IPC_PitComF', 'PC_KP', 'PC_KI', 'PC_KD', & + 'PC_TF', 'PC_MaxPit', 'PC_MinPit', 'PC_PitComT', 'PC_PitComT_Last', & + 'PC_PitComTF', 'PC_PitComT_IPC', 'PC_PwrErr', 'PC_SpdErr', 'IPC_AxisTilt_1P', & + 'IPC_AxisYaw_1P', 'IPC_AxisTilt_2P', 'IPC_AxisYaw_2P', 'IPC_KI', 'IPC_KP', & + 'IPC_IntSat', 'PC_State', 'PitCom', 'PitComAct', 'SS_DelOmegaF', & + 'TestType', 'VS_MaxTq', 'VS_LastGenTrq', 'VS_LastGenPwr', 'VS_MechGenPwr', & + 'VS_SpdErrAr', 'VS_SpdErrBr', 'VS_SpdErr', 'VS_State', 'VS_Rgn3Pitch', & + 'WE_Vw', 'WE_Vw_F', 'WE_VwI', 'WE_VwIdot', 'VS_LastGenTrqF', & + 'Fl_PitCom', 'NACIMU_FA_AccF', 'FA_AccF', 'Flp_Angle', 'RootMyb_Last', & + 'ACC_INFILE_SIZE'] ! Initialize debug file IF ((LocalVar%iStatus == 0) .OR. (LocalVar%iStatus == -9)) THEN ! .TRUE. if we're on the first call to the DLL IF (CntrPar%LoggingLevel > 0) THEN @@ -552,6 +563,20 @@ SUBROUTINE Debug(LocalVar, CntrPar, DebugVar, ErrVar, avrSWAP, RootName, size_av 100 FORMAT('Generator speed: ', f6.1, ' RPM, Pitch angle: ', f5.1, ' deg, Power: ', f7.1, ' kW, Est. wind Speed: ', f5.1, ' m/s') END IF + ! Process DebugOutData, LocalVarOutData + ! Remove very small numbers that cause ******** outputs + DO I = 1,SIZE(DebugOutData) + IF (ABS(DebugOutData(I)) < 1E-10) THEN + DebugOutData(I) = 0 + END IF + END DO + + DO I = 1,SIZE(LocalVarOutData) + IF (ABS(LocalVarOutData(I)) < 1E-10) THEN + LocalVarOutData(I) = 0 + END IF + END DO + ! Write debug files IF(CntrPar%LoggingLevel > 0) THEN WRITE (UnDb, FmtDat) LocalVar%Time, DebugOutData diff --git a/ROSCO/ROSCO/src/ROSCO_Types.f90 b/ROSCO/ROSCO/src/ROSCO_Types.f90 index 46c26a098..2c4143bc5 100644 --- a/ROSCO/ROSCO/src/ROSCO_Types.f90 +++ b/ROSCO/ROSCO/src/ROSCO_Types.f90 @@ -1,5 +1,5 @@ ! ROSCO Registry -! This file is automatically generated by write_registry.py using ROSCO v2.6.0 +! This file is automatically generated by write_registry.py using ROSCO v2.7.0 ! For any modification to the registry, please edit the rosco_types.yaml accordingly MODULE ROSCO_Types @@ -28,6 +28,7 @@ MODULE ROSCO_Types INTEGER(IntKi) :: IPC_ControlMode ! Turn Individual Pitch Control (IPC) for fatigue load reductions (pitch contribution) {0 - off, 1 - 1P reductions, 2 - 1P+2P reductions} REAL(DbKi), DIMENSION(:), ALLOCATABLE :: IPC_Vramp ! Wind speeds for IPC cut-in sigma function [m/s] REAL(DbKi) :: IPC_IntSat ! Integrator saturation (maximum signal amplitude contrbution to pitch from IPC) + INTEGER(IntKi) :: IPC_SatMode ! IPC Saturation method IPC Saturation method (0 - no saturation (except by PC_MinPit), 1 - saturate by PS_BldPitchMin, 2 - saturate sotfly (full IPC cycle) by PC_MinPit, 3 - saturate softly by PS_BldPitchMin) REAL(DbKi), DIMENSION(:), ALLOCATABLE :: IPC_KP ! Integral gain for the individual pitch controller, [-]. REAL(DbKi), DIMENSION(:), ALLOCATABLE :: IPC_KI ! Integral gain for the individual pitch controller, [-]. REAL(DbKi), DIMENSION(:), ALLOCATABLE :: IPC_aziOffset ! Phase offset added to the azimuth angle for the individual pitch controller, [rad]. @@ -113,6 +114,8 @@ MODULE ROSCO_Types INTEGER(IntKi) :: PA_Mode ! Pitch actuator mode {0 - not used, 1 - first order filter, 2 - second order filter} REAL(DbKi) :: PA_CornerFreq ! Pitch actuator bandwidth/cut-off frequency [rad/s] REAL(DbKi) :: PA_Damping ! Pitch actuator damping ratio [-, unused if PA_Mode = 1] + INTEGER(IntKi) :: PF_Mode ! Pitch actuator fault mode {0 - not used, 1 - offsets on one or more blades} + REAL(DbKi), DIMENSION(:), ALLOCATABLE :: PF_Offsets ! Pitch actuator fault offsets for blade 1-3 [rad/s] INTEGER(IntKi) :: Ext_Mode ! External control mode (0 - not used, 1 - call external control library) CHARACTER(1024) :: DLL_FileName ! File name of external dynamic library CHARACTER(1024) :: DLL_InFile ! Name of input file called by dynamic library (DISCON.IN, e.g.) @@ -174,6 +177,10 @@ MODULE ROSCO_Types REAL(DbKi), DIMENSION(99) :: nf_a0 ! Notch filter denominator coefficient 0 END TYPE FilterParameters +TYPE, PUBLIC :: rlParams + REAL(DbKi), DIMENSION(99) :: LastSignal ! Last input signal +END TYPE rlParams + TYPE, PUBLIC :: piParams REAL(DbKi), DIMENSION(99) :: ITerm ! Integrator term REAL(DbKi), DIMENSION(99) :: ITermLast ! Previous integrator term @@ -194,6 +201,7 @@ MODULE ROSCO_Types REAL(DbKi) :: rootMOOP(3) ! Blade root bending moment [Nm] REAL(DbKi) :: rootMOOPF(3) ! Filtered Blade root bending moment [Nm] REAL(DbKi) :: BlPitch(3) ! Blade pitch [rad] + REAL(DbKi) :: BlPitchCMeas ! Mean (collective) blade pitch [rad] REAL(DbKi) :: Azimuth ! Rotor aziumuth angle [rad] INTEGER(IntKi) :: NumBl ! Number of blades [-] REAL(DbKi) :: FA_Acc ! Tower fore-aft acceleration [m/s^2] @@ -226,9 +234,10 @@ MODULE ROSCO_Types REAL(DbKi) :: IPC_AxisYaw_2P ! Integral of quadrature, 2P REAL(DbKi) :: IPC_KI(2) ! Integral gain for IPC, after ramp [-] REAL(DbKi) :: IPC_KP(2) ! Proportional gain for IPC, after ramp [-] + REAL(DbKi) :: IPC_IntSat ! Integrator saturation (maximum signal amplitude contrbution to pitch from IPC) INTEGER(IntKi) :: PC_State ! State of the pitch control system REAL(DbKi) :: PitCom(3) ! Commanded pitch of each blade the last time the controller was called [rad]. - REAL(DbKi) :: PitComAct(3) ! Actuated pitch of each blade the last time the controller was called [rad]. + REAL(DbKi) :: PitComAct(3) ! Actuated pitch command of each blade [rad]. REAL(DbKi) :: SS_DelOmegaF ! Filtered setpoint shifting term defined in setpoint smoother [rad/s]. REAL(DbKi) :: TestType ! Test variable, no use REAL(DbKi) :: VS_MaxTq ! Maximum allowable generator torque [Nm]. @@ -257,6 +266,7 @@ MODULE ROSCO_Types TYPE(WE) :: WE ! Wind speed estimator parameters derived type TYPE(FilterParameters) :: FP ! Filter parameters derived type TYPE(piParams) :: piP ! PI parameters derived type + TYPE(rlParams) :: rlP ! Rate limiter parameters derived type END TYPE LocalVariables TYPE, PUBLIC :: ObjectInstances @@ -266,6 +276,7 @@ MODULE ROSCO_Types INTEGER(IntKi) :: instNotchSlopes ! Notch filter slopes instance INTEGER(IntKi) :: instNotch ! Notch filter instance INTEGER(IntKi) :: instPI ! PI controller instance + INTEGER(IntKi) :: instRL ! Rate limiter instance END TYPE ObjectInstances TYPE, PUBLIC :: PerformanceData @@ -297,9 +308,9 @@ MODULE ROSCO_Types REAL(DbKi) :: axisTilt_2P ! Tilt component of coleman transformation, 2P REAL(DbKi) :: axisYaw_2P ! Yaw component of coleman transformation, 2P REAL(DbKi) :: YawRateCom ! Commanded yaw rate [rad/s]. - REAL(DbKi) :: NacHeadingTarget ! Target nacelle heading [rad]. - REAL(DbKi) :: NacVaneOffset ! Nacelle vane angle with offset [rad]. - REAL(DbKi) :: Yaw_err ! Yaw error [rad]. + REAL(DbKi) :: NacHeadingTarget ! Target nacelle heading [deg]. + REAL(DbKi) :: NacVaneOffset ! Nacelle vane angle with offset [deg]. + REAL(DbKi) :: Yaw_Err ! Yaw error [deg]. REAL(DbKi) :: YawState ! State of yaw controller END TYPE DebugVariables @@ -324,7 +335,7 @@ MODULE ROSCO_Types END TYPE ZMQ_Variables TYPE, PUBLIC :: ExtControlType - REAL(C_FLOAT), DIMENSION(:), ALLOCATABLE :: avrSWAP ! The swap array- used to pass data to and from the DLL controller [see Bladed DLL documentation] + REAL(ReKi), DIMENSION(:), ALLOCATABLE :: avrSWAP ! The swap array- used to pass data to and from the DLL controller [see Bladed DLL documentation] END TYPE ExtControlType END MODULE ROSCO_Types \ No newline at end of file diff --git a/ROSCO/ROSCO/src/ReadSetParameters.f90 b/ROSCO/ROSCO/src/ReadSetParameters.f90 index a0ac9e382..9ba9e80cb 100644 --- a/ROSCO/ROSCO/src/ReadSetParameters.f90 +++ b/ROSCO/ROSCO/src/ReadSetParameters.f90 @@ -26,11 +26,15 @@ MODULE ReadSetParameters CONTAINS ! ----------------------------------------------------------------------------------- ! Read avrSWAP array passed from ServoDyn - SUBROUTINE ReadAvrSWAP(avrSWAP, LocalVar) + SUBROUTINE ReadAvrSWAP(avrSWAP, LocalVar, CntrPar) USE ROSCO_Types, ONLY : LocalVariables, ZMQ_Variables REAL(ReKi), INTENT(INOUT) :: avrSWAP(*) ! The swap array, used to pass data to, and receive data from, the DLL controller. TYPE(LocalVariables), INTENT(INOUT) :: LocalVar + TYPE(ControlParameters), INTENT(IN) :: CntrPar + + ! Allocate Variables: + INTEGER(IntKi) :: K ! Index used for looping through blades. ! Load variables from calling program (See Appendix A of Bladed User's Guide): LocalVar%iStatus = NINT(avrSWAP(1)) @@ -46,6 +50,7 @@ SUBROUTINE ReadAvrSWAP(avrSWAP, LocalVar) LocalVar%rootMOOP(1) = avrSWAP(30) LocalVar%rootMOOP(2) = avrSWAP(31) LocalVar%rootMOOP(3) = avrSWAP(32) + LocalVar%NacHeading = avrSWAP(37) * R2D LocalVar%FA_Acc = avrSWAP(53) LocalVar%NacIMU_FA_Acc = avrSWAP(83) LocalVar%Azimuth = avrSWAP(60) @@ -57,12 +62,24 @@ SUBROUTINE ReadAvrSWAP(avrSWAP, LocalVar) LocalVar%BlPitch(2) = avrSWAP(33) LocalVar%BlPitch(3) = avrSWAP(34) ELSE - LocalVar%BlPitch(1) = LocalVar%PitCom(1) - LocalVar%BlPitch(2) = LocalVar%PitCom(2) - LocalVar%BlPitch(3) = LocalVar%PitCom(3) + + ! Subtract pitch actuator fault for blade K - This in a sense would make the controller blind to the pitch fault + IF (CntrPar%PF_Mode == 1) THEN + DO K = 1, LocalVar%NumBl + ! This assumes that the pitch actuator fault is hardware fault + LocalVar%BlPitch(K) = LocalVar%PitComAct(K) - CntrPar%PF_Offsets(K) ! why is PitCom used and not PitComAct?? + END DO + ELSE + LocalVar%BlPitch(1) = LocalVar%PitComAct(1) + LocalVar%BlPitch(2) = LocalVar%PitComAct(2) + LocalVar%BlPitch(3) = LocalVar%PitComAct(3) + END IF + ENDIF - IF (LocalVar%iStatus == 0) THEN + LocalVar%BlPitchCMeas = (1 / REAL(LocalVar%NumBl)) * (LocalVar%BlPitch(1) + LocalVar%BlPitch(2) + LocalVar%BlPitch(3)) + + IF (LocalVar%iStatus == 0) THEN ! TODO: Technically, LocalVar%Time > 0, too, but this restart is in many places as a reset LocalVar%restart = .True. ELSE LocalVar%restart = .False. @@ -106,6 +123,7 @@ SUBROUTINE SetParameters(avrSWAP, accINFILE, size_avcMSG, CntrPar, LocalVar, obj objInst%instNotchSlopes = 1 objInst%instNotch = 1 objInst%instPI = 1 + objInst%instRL = 1 ! Set unused outputs to zero (See Appendix A of Bladed User's Guide): avrSWAP(35) = 1.0 ! Generator contactor status: 1=main (high speed) variable-speed generator @@ -245,6 +263,7 @@ SUBROUTINE ReadControlParameterFileSub(CntrPar, zmqVar, accINFILE, accINFILE_siz CALL ParseInput(UnControllerParameters,CurLine,'Flp_Mode',accINFILE(1),CntrPar%Flp_Mode,ErrVar) CALL ParseInput(UnControllerParameters,CurLine,'OL_Mode',accINFILE(1),CntrPar%OL_Mode,ErrVar) CALL ParseInput(UnControllerParameters,CurLine,'PA_Mode',accINFILE(1),CntrPar%PA_Mode,ErrVar) + CALL ParseInput(UnControllerParameters,CurLine,'PF_Mode',accINFILE(1),CntrPar%PF_Mode,ErrVar) CALL ParseInput(UnControllerParameters,CurLine,'Ext_Mode',accINFILE(1),CntrPar%Ext_Mode,ErrVar) CALL ParseInput(UnControllerParameters,CurLine,'ZMQ_Mode',accINFILE(1), CntrPar%ZMQ_Mode,ErrVar) @@ -284,6 +303,7 @@ SUBROUTINE ReadControlParameterFileSub(CntrPar, zmqVar, accINFILE, accINFILE_siz !------------------- IPC CONSTANTS ----------------------- CALL ReadEmptyLine(UnControllerParameters,CurLine) CALL ParseAry(UnControllerParameters, CurLine, 'IPC_Vramp', CntrPar%IPC_Vramp, 2, accINFILE(1), ErrVar ) + CALL ParseInput(UnControllerParameters,CurLine,'IPC_SatMode',accINFILE(1),CntrPar%IPC_SatMode,ErrVar) CALL ParseInput(UnControllerParameters,CurLine,'IPC_IntSat',accINFILE(1),CntrPar%IPC_IntSat,ErrVar) CALL ParseAry(UnControllerParameters, CurLine, 'IPC_KP', CntrPar%IPC_KP, 2, accINFILE(1), ErrVar ) CALL ParseAry(UnControllerParameters, CurLine, 'IPC_KI', CntrPar%IPC_KI, 2, accINFILE(1), ErrVar ) @@ -389,6 +409,11 @@ SUBROUTINE ReadControlParameterFileSub(CntrPar, zmqVar, accINFILE, accINFILE_siz CALL ReadEmptyLine(UnControllerParameters,CurLine) CALL ParseInput(UnControllerParameters,CurLine,'PA_CornerFreq',accINFILE(1),CntrPar%PA_CornerFreq,ErrVar) CALL ParseInput(UnControllerParameters,CurLine,'PA_Damping',accINFILE(1),CntrPar%PA_Damping,ErrVar) + CALL ReadEmptyLine(UnControllerParameters,CurLine) + + !------------ Pitch Actuator Faults ------------ + CALL ReadEmptyLine(UnControllerParameters,CurLine) + CALL ParseAry(UnControllerParameters, CurLine,'PF_Offsets', CntrPar%PF_Offsets, 3, accINFILE(1), ErrVar) CALL ReadEmptyLine(UnControllerParameters,CurLine) !------------ External control interface ------------ @@ -783,6 +808,11 @@ SUBROUTINE CheckInputs(LocalVar, CntrPar, avrSWAP, ErrVar, size_avcMSG) ErrVar%ErrMsg = 'Corner frequency of IPC actuator model must be positive, or set to 0 to disable.' ENDIF + IF (CntrPar%IPC_SatMode < 0 .OR. CntrPar%IPC_SatMode > 3) THEN + ErrVar%aviFAIL = -1 + ErrVar%ErrMsg = 'IPC_SatMode must be 0, 1, 2, or 3.' + ENDIF + IF (CntrPar%IPC_KI(1) < 0.0) THEN ErrVar%aviFAIL = -1 ErrVar%ErrMsg = 'IPC_KI(1) must be zero or greater than zero.' @@ -971,7 +1001,7 @@ SUBROUTINE CheckInputs(LocalVar, CntrPar, avrSWAP, ErrVar, size_avcMSG) ! --- Pitch Actuator --- IF (CntrPar%PA_Mode > 0) THEN - IF ((CntrPar%PA_Mode < 0) .OR. (CntrPar%PA_Mode < 2)) THEN + IF ((CntrPar%PA_Mode < 0) .OR. (CntrPar%PA_Mode > 2)) THEN ErrVar%aviFAIL = -1 ErrVar%ErrMsg = 'PA_Mode must be 0, 1, or 2' END IF @@ -996,7 +1026,13 @@ SUBROUTINE CheckInputs(LocalVar, CntrPar, avrSWAP, ErrVar, size_avcMSG) IF (NINT(avrSWAP(28)) == 0 .AND. ((CntrPar%IPC_ControlMode > 0) .OR. (CntrPar%Y_ControlMode > 1))) THEN ErrVar%aviFAIL = -1 - ErrVar%ErrMsg = 'IPC enabled, but Ptch_Cntrl in ServoDyn has a value of 0. Set it to 1.' + ErrVar%ErrMsg = 'IPC enabled, but Ptch_Cntrl in ServoDyn has a value of 0. Set it to 1 for individual pitch control.' + ENDIF + + ! PF_Mode = 1 + IF (NINT(avrSWAP(28)) == 0 .AND. (CntrPar%PF_Mode == 1)) THEN + ErrVar%aviFAIL = -1 + ErrVar%ErrMsg = 'Pitch offset fault enabled (PF_Mode = 1), but Ptch_Cntrl in ServoDyn has a value of 0. Set it to 1 for individual pitch control.' ENDIF ! DT diff --git a/ROSCO/ROSCO_testing/ROSCO_testing.py b/ROSCO/ROSCO_testing/ROSCO_testing.py index d65eaa3a0..55c5d60f9 100644 --- a/ROSCO/ROSCO_testing/ROSCO_testing.py +++ b/ROSCO/ROSCO_testing/ROSCO_testing.py @@ -47,7 +47,6 @@ def __init__(self, **kwargs): self.rosco_path = glob.glob(os.path.join(os.path.dirname(os.path.realpath(__file__)),'../ROSCO/build/libdiscon.*'))[0] except: print('No compiled ROSCO version found, please provide ROSCO_testing.rosco_path.') - self.dev_branch = True # openfast dev branch? self.debug_level = 2 # debug level. 0 - no outputs, 1 - minimal outputs, 2 - all outputs self.overwrite = False # overwrite existing files? self.cores = 4 # number of cores to use @@ -114,8 +113,7 @@ def ROSCO_Test_lite(self, more_case_inputs={}, U=[]): else: WindSpeeds = [5, 8, 11, 14, 17] - fastRead = InputReader_OpenFAST( - FAST_ver=self.FAST_ver, dev_branch=self.dev_branch) + fastRead = InputReader_OpenFAST() fastRead.FAST_InputFile = self.FAST_InputFile # FAST input file (ext=.fst) # Path to fst directory files fastRead.FAST_directory = self.FAST_directory @@ -215,7 +213,6 @@ def ROSCO_Test_lite(self, more_case_inputs={}, U=[]): fastBatch.FAST_InputFile = self.FAST_InputFile # FAST input file (ext=.fst) fastBatch.FAST_directory = self.FAST_directory # Path to fst directory files fastBatch.debug_level = self.debug_level - fastBatch.dev_branch = self.dev_branch fastBatch.case_list = case_list fastBatch.case_name_list = case_name_list @@ -270,8 +267,7 @@ def ROSCO_Test_heavy(self, more_case_inputs={}, U=[]): else: WindSpeeds = [[4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24], [8.88, 12.88]] - fastRead = InputReader_OpenFAST( - FAST_ver=self.FAST_ver, dev_branch=self.dev_branch) + fastRead = InputReader_OpenFAST() fastRead.FAST_InputFile = self.FAST_InputFile # FAST input file (ext=.fst) # Path to fst directory files fastRead.FAST_directory = self.FAST_directory @@ -380,7 +376,6 @@ def ROSCO_Test_heavy(self, more_case_inputs={}, U=[]): fastBatch.FAST_InputFile = self.FAST_InputFile # FAST input file (ext=.fst) fastBatch.FAST_directory = self.FAST_directory # Path to fst directory files fastBatch.debug_level = self.debug_level - fastBatch.dev_branch = self.dev_branch fastBatch.case_list = case_list fastBatch.case_name_list = case_name_list @@ -555,7 +550,6 @@ def print_results(self,outfiles): rt.namebase = 'IEA-15MW' # Base name for FAST files rt.FAST_exe = 'openfast' # OpenFAST executable path rt.Turbsim_exe = 'turbsim' # Turbsim executable path - rt.FAST_ver = 'OpenFAST' # FAST version # path to compiled ROSCO controller if platform.system() == 'Windows': rt.rosco_path = os.path.join(os.getcwd(), '../ROSCO/build/libdiscon.dll') @@ -563,14 +557,12 @@ def print_results(self,outfiles): rt.rosco_path = os.path.join(os.getcwd(), '../ROSCO/build/libdiscon.dylib') else: rt.rosco_path = os.path.join(os.getcwd(), '../ROSCO/build/libdiscon.so') - rt.dev_branch = True # dev branch of Openfast? rt.debug_level = 2 # debug level. 0 - no outputs, 1 - minimal outputs, 2 - all outputs rt.overwrite = True # overwite fast sims? rt.cores = 4 # number of cores if multiprocessings rt.mpi_run = False # run using mpi rt.mpi_comm_map_down = [] # core mapping for MPI rt.outfile_fmt = 2 # 1 = .txt, 2 = binary, 3 = both - rt.dev_branch= 'True' # Setup turbine rt.Turbine_Class = 'I' diff --git a/ROSCO/ROSCO_testing/run_Testing.py b/ROSCO/ROSCO_testing/run_Testing.py index ef201d424..f10c0d011 100644 --- a/ROSCO/ROSCO_testing/run_Testing.py +++ b/ROSCO/ROSCO_testing/run_Testing.py @@ -91,7 +91,6 @@ def run_testing(turbine2test, testtype, rosco_binaries=[], discon_files=[], **kw rt_kwargs['wind_dir'] = os.path.join('/scratch/dzalkind/ROSCO_testing','wind','IEA-15_heavy') # OpenFAST executable path rt_kwargs['Turbsim_exe']= 'turbsim' # Turbsim executable path rt_kwargs['FAST_ver'] = 'OpenFAST' # FAST version - rt_kwargs['dev_branch'] = True # dev branch of Openfast? rt_kwargs['debug_level']= 2 # debug level. 0 - no outputs, 1 - minimal outputs, 2 - all outputs rt_kwargs['overwrite'] = False # overwite fast sims? rt_kwargs['cores'] = 36 # number of cores if multiprocessing diff --git a/ROSCO/ROSCO_testing/test_checkpoint.py b/ROSCO/ROSCO_testing/test_checkpoint.py index d42c7e747..e1d15f039 100644 --- a/ROSCO/ROSCO_testing/test_checkpoint.py +++ b/ROSCO/ROSCO_testing/test_checkpoint.py @@ -53,6 +53,7 @@ def test_restart(self): case_inputs[('Fst', 'OutFileFmt')] = {'vals': [2], 'group': 1} case_inputs[('Fst', 'DT')] = {'vals': [0.025], 'group': 0} case_inputs[('DISCON_in', 'LoggingLevel')] = {'vals': [2], 'group': 1} + case_inputs[('ElastoDyn', 'RotSpeed')] = {'vals': [7], 'group': 0} # Generate cases run_dir = os.path.join(test_out_dir, 'restart') @@ -110,7 +111,7 @@ def test_restart(self): if False: # Plotting for debug import matplotlib.pyplot as plt cases = {} - cases['Baseline'] = ['Wind1VelX', 'BldPitch1', 'GenTq', 'RotSpeed', 'NacYaw'] + cases['Baseline'] = ['Wind1VelX', 'BldPitch1', 'GenTq', 'RotSpeed', 'NacYaw','GenPwr'] fig, ax = op.plot_fast_out(cases=cases, showplot=False) plt.show() diff --git a/ROSCO/ROSCO_toolbox/__init__.py b/ROSCO/ROSCO_toolbox/__init__.py index afbd37e5f..092377edd 100644 --- a/ROSCO/ROSCO_toolbox/__init__.py +++ b/ROSCO/ROSCO_toolbox/__init__.py @@ -2,5 +2,5 @@ """Top-level package for ROSCO_toolbox Repo.""" __author__ = """Nikhar J. Abbas and Daniel S. Zalkind""" -__email__ = 'nikhar.abbas@nrel.gov' -__version__ = '2.6.0' +__email__ = 'daniel.zalkind@nrel.gov' +__version__ = '2.7.0' diff --git a/ROSCO/ROSCO_toolbox/control_interface.py b/ROSCO/ROSCO_toolbox/control_interface.py index 5514bf6a4..b3ad2777e 100644 --- a/ROSCO/ROSCO_toolbox/control_interface.py +++ b/ROSCO/ROSCO_toolbox/control_interface.py @@ -209,8 +209,13 @@ def null_free_dll(*spam): # pragma: no cover extra_libs = [] if OS == "Windows": # pragma: Windows - _dlclose = ctypes.windll.kernel32.FreeLibrary - dlclose = lambda handle: 0 if _dlclose(handle) else 1 + try: + _dlclose = ctypes.windll.kernel32.FreeLibrary + dlclose = lambda handle: 0 if _dlclose(handle) else 1 + except: + kernel32 = ctypes.WinDLL('kernel32',use_last_error=True) + kernel32.FreeLibrary.argtypes = [ctypes.wintypes.HMODULE] + dlclose = lambda handle: 0 if kernel32.FreeLibrary(handle) else 1 # There's some controversy as to whether this DLL is guaranteed to exist. # It always has so far but isn't documented. However, MinGW assumes that it # is so, should this DLL be removed, then we have much bigger problems than diff --git a/ROSCO/ROSCO_toolbox/controller.py b/ROSCO/ROSCO_toolbox/controller.py index b4e3c353a..f7cae56a2 100644 --- a/ROSCO/ROSCO_toolbox/controller.py +++ b/ROSCO/ROSCO_toolbox/controller.py @@ -64,6 +64,7 @@ def __init__(self, controller_params): self.TD_Mode = controller_params['TD_Mode'] self.Flp_Mode = controller_params['Flp_Mode'] self.PA_Mode = controller_params['PA_Mode'] + self.PF_Mode = controller_params['PF_Mode'] self.Ext_Mode = controller_params['Ext_Mode'] self.ZMQ_Mode = controller_params['ZMQ_Mode'] diff --git a/ROSCO/ROSCO_toolbox/inputs/schema2rst.py b/ROSCO/ROSCO_toolbox/inputs/schema2rst.py index a72343f3e..e88f63f5f 100644 --- a/ROSCO/ROSCO_toolbox/inputs/schema2rst.py +++ b/ROSCO/ROSCO_toolbox/inputs/schema2rst.py @@ -84,7 +84,7 @@ def __init__(self, fname): def write_rst(self): self.f = open(self.fout, "w") self.write_header() - self.write_loop(self.yaml["properties"], 0, self.fname.replace("yaml", "")) + self.write_loop(self.yaml["properties"], 0, 'toolbox_schema') self.f.close() def write_header(self): diff --git a/ROSCO/ROSCO_toolbox/inputs/toolbox_schema.yaml b/ROSCO/ROSCO_toolbox/inputs/toolbox_schema.yaml index c3e0c80b6..432785df5 100644 --- a/ROSCO/ROSCO_toolbox/inputs/toolbox_schema.yaml +++ b/ROSCO/ROSCO_toolbox/inputs/toolbox_schema.yaml @@ -197,6 +197,12 @@ properties: maximum: 2 default: 0 description: Pitch actuator mode {0 - not used, 1 - first order filter, 2 - second order filter} + PF_Mode: + type: number + minimum: 0 + maximum: 1 + default: 0 + description: Pitch fault mode {0 - not used, 1 - constant offset on one or more blades} Ext_Mode: type: number minimum: 0 @@ -600,6 +606,9 @@ properties: type: number description: Integrator saturation (maximum signal amplitude contribution to pitch from IPC) units: rad + IPC_SatMode: + type: integer + description: IPC Saturation method (0 - no saturation, 1 - saturate by PC_MinPit, 2 - saturate by PS_BldPitchMin) IPC_KP: type: array items: @@ -849,6 +858,12 @@ properties: type: string description: Name of procedure in DLL to be called default: DISCON + PF_Offsets: + type: array + items: + type: number + description: Pitch angle offsets for each blade (array with length of 3) + units: rad linmodel_tuning: type: object diff --git a/ROSCO/ROSCO_toolbox/linear/linear_models.py b/ROSCO/ROSCO_toolbox/linear/linear_models.py index 5a4d6969d..f096ce563 100644 --- a/ROSCO/ROSCO_toolbox/linear/linear_models.py +++ b/ROSCO/ROSCO_toolbox/linear/linear_models.py @@ -15,7 +15,7 @@ from scipy.io import loadmat try: - import pyFAST.linearization.mbc.mbc3 as mbc + import pyFAST.linearization.mbc as mbc except ImportError: import weis.control.mbc.mbc3 as mbc except ImportError: @@ -43,7 +43,6 @@ def __init__(self, lin_file_dir, lin_file_names, nlin=12, reduceStates=False, fr u_ops = np.array([], []) all_MBC = [] all_matData = [] - all_FAST_linData = [] if load_parallel: import time @@ -52,7 +51,7 @@ def __init__(self, lin_file_dir, lin_file_names, nlin=12, reduceStates=False, fr lin_file_dir, lin_file_names[iCase] + '.{}.lin'.format(i_lin+1))) for i_lin in range(0, nlin)] for iCase in range(0,n_lin_cases)] cores = mp.cpu_count() pool = mp.Pool(cores) - all_MBC, all_matData, all_FAST_linData = zip(*pool.map(run_mbc3, all_linfiles)) + all_MBC, all_matData = zip(*pool.map(run_mbc3, all_linfiles)) pool.close() pool.join() print('loaded in parallel in {} seconds'.format(time.time()-t1)) @@ -62,10 +61,9 @@ def __init__(self, lin_file_dir, lin_file_names, nlin=12, reduceStates=False, fr for iCase in range(0, n_lin_cases): lin_files_i = [os.path.realpath(os.path.join( lin_file_dir, lin_file_names[iCase] + '.{}.lin'.format(i_lin+1))) for i_lin in range(0, nlin)] - MBC, matData, FAST_linData = run_mbc3(lin_files_i) + MBC, matData = run_mbc3(lin_files_i) all_MBC.append(MBC) all_matData.append(matData) - all_FAST_linData.append(FAST_linData) print('loaded in serial in {} seconds'.format(time.time()-t1)) @@ -74,7 +72,6 @@ def __init__(self, lin_file_dir, lin_file_names, nlin=12, reduceStates=False, fr MBC = all_MBC[iCase] matData = all_matData[iCase] - FAST_linData = all_FAST_linData[iCase] if not iCase: # first time through # Initialize operating points, matrices @@ -713,9 +710,9 @@ def run_mbc3(fnames): Helper function to run mbc3 ''' print('Loading linearizations from:', ''.join(fnames[0].split('.')[:-2])) - MBC, matData, FAST_linData = mbc.fx_mbc3(fnames, verbose=False) + MBC, matData = mbc.fx_mbc3(fnames, verbose=False) - return MBC, matData, FAST_linData + return MBC, matData def connect_ml(mods, inputs, outputs): ''' diff --git a/ROSCO/ROSCO_toolbox/ofTools/case_gen/CaseGen_General.py b/ROSCO/ROSCO_toolbox/ofTools/case_gen/CaseGen_General.py index 87bb7bae2..8c46e5224 100644 --- a/ROSCO/ROSCO_toolbox/ofTools/case_gen/CaseGen_General.py +++ b/ROSCO/ROSCO_toolbox/ofTools/case_gen/CaseGen_General.py @@ -155,10 +155,8 @@ def CaseGen_General(case_inputs, dir_matrix='', namebase='', save_matrix=True): for g in matrix_group_idx[j]: row_out[g] = change_vals[g][val] matrix_out.append(row_out) - try: - matrix_out = np.asarray(matrix_out, dtype=str) - except: - matrix_out = np.asarray(matrix_out) + + matrix_out = np.asarray(matrix_out, dtype=object) n_cases = np.shape(matrix_out)[0] # case naming diff --git a/ROSCO/ROSCO_toolbox/ofTools/case_gen/CaseLibrary.py b/ROSCO/ROSCO_toolbox/ofTools/case_gen/CaseLibrary.py index 72fe07635..aa4d1ce4f 100644 --- a/ROSCO/ROSCO_toolbox/ofTools/case_gen/CaseLibrary.py +++ b/ROSCO/ROSCO_toolbox/ofTools/case_gen/CaseLibrary.py @@ -54,7 +54,7 @@ def load_tuning_yaml(tuning_yaml): cp_filename = os.path.join(tune_case_dir,path_params['FAST_directory'],path_params['rotor_performance_filename']) turbine.load_from_fast(path_params['FAST_InputFile'], \ os.path.join(tune_case_dir,path_params['FAST_directory']), \ - dev_branch=True,rot_source='txt',\ + rot_source='txt',\ txt_filename=cp_filename) return turbine, controller, cp_filename @@ -131,6 +131,10 @@ def power_curve(**wind_case_opts): if 'U' in wind_case_opts: U = wind_case_opts['U'] + if type(U) != list: + U = [U] + elif type(U) == np.ndarray: + U = U.tolist() else: # default # Run conditions U = np.arange(4,14.5,.5).tolist() @@ -171,6 +175,9 @@ def simp_step(**wind_case_opts): else: #default T_step = 150 + # Wind directory, default is run_dir + wind_case_opts['wind_dir'] = wind_case_opts.get('wind_dir',wind_case_opts['run_dir']) + # Step Wind Setup # Make Default step wind object @@ -388,7 +395,7 @@ def sweep_rated_torque(start_group, **control_sweep_opts): cp_filename = os.path.join(tune_case_dir,path_params['FAST_directory'],path_params['rotor_performance_filename']) turbine.load_from_fast(path_params['FAST_InputFile'], \ os.path.join(tune_case_dir,path_params['FAST_directory']), \ - dev_branch=True,rot_source='txt',\ + rot_source='txt',\ txt_filename=cp_filename) controller.tune_controller(turbine) @@ -425,9 +432,9 @@ def sweep_pitch_act(start_group, **control_sweep_opts): def sweep_ipc_gains(start_group, **control_sweep_opts): case_inputs_control = {} - kis = np.linspace(0,3,6).tolist() + kis = np.linspace(0,1,6).tolist() # kis = [0.,0.6,1.2,1.8,2.4,3.] - KIs = [[ki * 1e-8,0.] for ki in kis] + KIs = [[ki * 6e-9,0.] for ki in kis] case_inputs_control[('DISCON_in','IPC_ControlMode')] = {'vals': [1], 'group': 0} # case_inputs_control[('DISCON_in','IPC_KI')] = {'vals': [[0.,0.],[1e-8,0.]], 'group': start_group} case_inputs_control[('DISCON_in','IPC_KI')] = {'vals': KIs, 'group': start_group} @@ -472,7 +479,7 @@ def sweep_ps_percent(start_group, **control_sweep_opts): # make default controller, turbine objects for ROSCO_toolbox turbine = ROSCO_turbine.Turbine(turbine_params) - turbine.load_from_fast( path_params['FAST_InputFile'],path_params['FAST_directory'], dev_branch=True) + turbine.load_from_fast( path_params['FAST_InputFile'],path_params['FAST_directory']) controller = ROSCO_controller.Controller(controller_params) @@ -497,6 +504,15 @@ def sweep_ps_percent(start_group, **control_sweep_opts): return case_inputs_control +def test_pitch_offset(start_group, **control_sweep_opts): + case_inputs_control = {} + case_inputs_control[('DISCON_in','PF_Mode')] = {'vals': [1], 'group': start_group} + case_inputs_control[('DISCON_in','PF_Offsets')] = {'vals': [[0,float(np.radians(2)),0]], 'group': start_group} + return case_inputs_control + + + + # def sweep_pc_mode(cont_yaml,omega=np.linspace(.05,.35,8,endpoint=True).tolist(),zeta=[1.5],group=2): @@ -507,7 +523,7 @@ def sweep_ps_percent(start_group, **control_sweep_opts): # # make default controller, turbine objects for ROSCO_toolbox # turbine = ROSCO_turbine.Turbine(turbine_params) -# turbine.load_from_fast( path_params['FAST_InputFile'],path_params['FAST_directory'], dev_branch=True) +# turbine.load_from_fast( path_params['FAST_InputFile'],path_params['FAST_directory']) # controller = ROSCO_controller.Controller(controller_params) diff --git a/ROSCO/ROSCO_toolbox/ofTools/case_gen/run_FAST.py b/ROSCO/ROSCO_toolbox/ofTools/case_gen/run_FAST.py index a0c31925e..c5b335199 100644 --- a/ROSCO/ROSCO_toolbox/ofTools/case_gen/run_FAST.py +++ b/ROSCO/ROSCO_toolbox/ofTools/case_gen/run_FAST.py @@ -2,6 +2,9 @@ Example script to run the DLCs in OpenFAST +This script is designed to work as-is if ROSCO is installed in 'develop' mode, i.e., python setup.py develop +Otherwise, the directories can be defined as attributes of the run_FAST_ROSCO + """ from ROSCO_toolbox.ofTools.case_gen.runFAST_pywrapper import runFAST_pywrapper, runFAST_pywrapper_batch @@ -17,29 +20,42 @@ from ROSCO_toolbox import controller as ROSCO_controller from ROSCO_toolbox import turbine as ROSCO_turbine -# Globals -this_dir = os.path.dirname(os.path.abspath(__file__)) -tune_case_dir = os.path.realpath(os.path.join(this_dir,'../../../Tune_Cases')) -rosco_dir = os.path.realpath(os.path.join(this_dir,'../../..')) - +this_dir = os.path.dirname(os.path.abspath(__file__)) class run_FAST_ROSCO(): def __init__(self): # Set default parameters - self.tuning_yaml = os.path.join(tune_case_dir,'IEA15MW.yaml') + self.tuning_yaml = 'IEA15MW.yaml' self.wind_case_fcn = cl.power_curve self.wind_case_opts = {} self.control_sweep_opts = {} self.control_sweep_fcn = None self.case_inputs = {} self.rosco_dll = '' - self.save_dir = os.path.join(rosco_dir,'outputs') self.n_cores = 1 self.base_name = '' self.controller_params = {} + # Directories + self.tune_case_dir = '' + self.rosco_dir = '' + self.save_dir = '' + + def run_FAST(self): + + # handle directories, set defaults + if not self.rosco_dir: + self.rosco_dir = os.path.realpath(os.path.join(this_dir,'../../..')) + + if not self.tune_case_dir: + self.tune_case_dir = os.path.realpath(os.path.join(self.rosco_dir,'Tune_Cases')) + + if not self.save_dir: + self.save_dir = os.path.join(self.rosco_dir,'outputs') + + # set up run directory if self.control_sweep_fcn: sweep_name = self.control_sweep_fcn.__name__ @@ -55,7 +71,7 @@ def run_FAST(self): # Start with tuning yaml definition of controller if not os.path.isabs(self.tuning_yaml): - self.tuning_yaml = os.path.join(tune_case_dir,self.tuning_yaml) + self.tuning_yaml = os.path.join(self.tune_case_dir,self.tuning_yaml) # Load yaml file inps = load_rosco_yaml(self.tuning_yaml) @@ -77,10 +93,12 @@ def run_FAST(self): path_params['FAST_directory'], path_params['rotor_performance_filename'] ) - turbine.load_from_fast(path_params['FAST_InputFile'], \ - os.path.join(tune_yaml_dir,path_params['FAST_directory']), \ - dev_branch=True,rot_source='txt',\ - txt_filename=cp_filename) + turbine.load_from_fast( + path_params['FAST_InputFile'], + os.path.join(tune_yaml_dir,path_params['FAST_directory']), + rot_source='txt', + txt_filename=cp_filename + ) # tune base controller defined by the yaml controller.tune_controller(turbine) @@ -98,13 +116,12 @@ def run_FAST(self): # Set up rosco_dll if not self.rosco_dll: - rosco_dir = os.path.realpath(os.path.join(os.path.dirname(__file__),'../../..')) if platform.system() == 'Windows': - rosco_dll = os.path.join(rosco_dir, 'ROSCO/build/libdiscon.dll') + rosco_dll = os.path.join(self.rosco_dir, 'ROSCO/build/libdiscon.dll') elif platform.system() == 'Darwin': - rosco_dll = os.path.join(rosco_dir, 'ROSCO/build/libdiscon.dylib') + rosco_dll = os.path.join(self.rosco_dir, 'ROSCO/build/libdiscon.dylib') else: - rosco_dll = os.path.join(rosco_dir, 'ROSCO/build/libdiscon.so') + rosco_dll = os.path.join(self.rosco_dir, 'ROSCO/build/libdiscon.so') case_inputs[('ServoDyn','DLL_FileName')] = {'vals': [rosco_dll], 'group': 0} @@ -179,7 +196,7 @@ def run_FAST(self): if __name__ == "__main__": # Simulation config - sim_config = 11 + sim_config = 1 r = run_FAST_ROSCO() @@ -187,7 +204,7 @@ def run_FAST(self): if sim_config == 1: # FOCAL single wind speed testing - r.tuning_yaml = os.path.join(tune_case_dir,'IEA15MW.yaml') + r.tuning_yaml = 'IEA15MW.yaml' r.wind_case_fcn = cl.simp_step r.sweep_mode = None r.save_dir = '/Users/dzalkind/Tools/ROSCO/outputs' @@ -195,15 +212,15 @@ def run_FAST(self): elif sim_config == 6: # FOCAL rated wind speed tuning - r.tuning_yaml = os.path.join(tune_case_dir,'IEA15MW_FOCAL.yaml') - r.wind_case_fcn = power_curve + r.tuning_yaml = 'IEA15MW_FOCAL.yaml' + r.wind_case_fcn = cl.power_curve r.sweep_mode = cl.sweep_rated_torque r.save_dir = '/Users/dzalkind/Projects/FOCAL/drop_torque' elif sim_config == 7: # FOCAL rated wind speed tuning - r.tuning_yaml = os.path.join(tune_case_dir,'IEA15MW.yaml') + r.tuning_yaml = 'IEA15MW.yaml' r.wind_case_fcn = cl.steps r.wind_case_opts = { 'tt': [100,200], @@ -227,8 +244,8 @@ def run_FAST(self): r.wind_case_opts = { 'U': [16], } - r.save_dir = '/Users/dzalkind/Projects/RAAW/RAAW_OpenFAST/outputs/IPC_play' - r.control_sweep_fcn = cl.sweep_ipc_gains + r.save_dir = '/Users/dzalkind/Tools/ROSCO/outputs/offset_test' + r.control_sweep_fcn = cl.test_pitch_offset elif sim_config == 9: diff --git a/ROSCO/ROSCO_toolbox/ofTools/fast_io/FAST_reader.py b/ROSCO/ROSCO_toolbox/ofTools/fast_io/FAST_reader.py index f4fb2f597..2f809f3be 100644 --- a/ROSCO/ROSCO_toolbox/ofTools/fast_io/FAST_reader.py +++ b/ROSCO/ROSCO_toolbox/ofTools/fast_io/FAST_reader.py @@ -4,7 +4,7 @@ from functools import reduce import operator -from ROSCO_toolbox.ofTools.fast_io.FAST_vars import FstModel +from ROSCO_toolbox.ofTools.fast_io.FAST_vars_out import FstOutput from ROSCO_toolbox.utilities import read_DISCON, load_from_txt from ROSCO_toolbox import turbine as ROSCO_turbine ROSCO = True @@ -18,8 +18,6 @@ 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) @@ -48,7 +46,6 @@ def float_read(text): except: return str(text) - def int_read(text): # return int with error handing for "default" values if 'default' in text.lower(): @@ -59,30 +56,34 @@ def int_read(text): except: return str(text) +class InputReader_OpenFAST(object): + """ OpenFAST input file reader """ -class InputReader_Common(object): - """ Methods for reading input files that are (relatively) unchanged across FAST versions.""" + def __init__(self): - def __init__(self, **kwargs): - - self.FAST_ver = 'OPENFAST' self.FAST_InputFile = None # FAST input file (ext=.fst) self.FAST_directory = None # Path to fst directory files self.path2dll = None # Path to dll file - self.fst_vt = FstModel - - # Optional population class attributes from key word arguments - for (k, w) in kwargs.items(): - try: - setattr(self, k, w) - except: - pass - - super(InputReader_Common, self).__init__() - - def read_yaml(self): - f = open(self.FAST_yamlfile, 'r') - self.fst_vt = yaml.load(f) + self.fst_vt = {} + self.fst_vt['Fst'] = {} + self.fst_vt['outlist'] = FstOutput + self.fst_vt['ElastoDyn'] = {} + self.fst_vt['ElastoDynBlade'] = {} + self.fst_vt['ElastoDynTower'] = {} + self.fst_vt['InflowWind'] = {} + self.fst_vt['AeroDyn15'] = {} + self.fst_vt['AeroDyn14'] = {} + self.fst_vt['AeroDynBlade'] = {} + self.fst_vt['AeroDynTower'] = {} + self.fst_vt['AeroDynPolar'] = {} + self.fst_vt['ServoDyn'] = {} + self.fst_vt['DISCON_in'] = {} + self.fst_vt['HydroDyn'] = {} + self.fst_vt['MoorDyn'] = {} + self.fst_vt['SubDyn'] = {} + self.fst_vt['MAP'] = {} + self.fst_vt['BeamDyn'] = {} + self.fst_vt['BeamDynBlade'] = {} 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 """ @@ -109,325 +110,6 @@ def loop_dict(vartree, search_var, branch): var = var.replace(' ', '') loop_dict(vartree_head, var, []) - def read_ElastoDynBlade(self): - # ElastoDyn v1.00 Blade Input File - # Currently no differences between FASTv8.16 and OpenFAST. - if self.FAST_ver.lower() == 'fast7': - blade_file = os.path.join(self.FAST_directory, self.fst_vt['Fst7']['BldFile1']) - else: - blade_file = os.path.join(self.FAST_directory, self.fst_vt['ElastoDyn']['BldFile1']) - - f = open(blade_file) - # print blade_file - f.readline() - f.readline() - f.readline() - if self.FAST_ver.lower() == 'fast7': - f.readline() - - # Blade Parameters - self.fst_vt['ElastoDynBlade']['NBlInpSt'] = int(f.readline().split()[0]) - if self.FAST_ver.lower() == 'fast7': - self.fst_vt['ElastoDynBlade']['CalcBMode'] = bool_read(f.readline().split()[0]) - self.fst_vt['ElastoDynBlade']['BldFlDmp1'] = float_read(f.readline().split()[0]) - self.fst_vt['ElastoDynBlade']['BldFlDmp2'] = float_read(f.readline().split()[0]) - self.fst_vt['ElastoDynBlade']['BldEdDmp1'] = float_read(f.readline().split()[0]) - - # Blade Adjustment Factors - f.readline() - self.fst_vt['ElastoDynBlade']['FlStTunr1'] = float_read(f.readline().split()[0]) - self.fst_vt['ElastoDynBlade']['FlStTunr2'] = float_read(f.readline().split()[0]) - self.fst_vt['ElastoDynBlade']['AdjBlMs'] = float_read(f.readline().split()[0]) - self.fst_vt['ElastoDynBlade']['AdjFlSt'] = float_read(f.readline().split()[0]) - self.fst_vt['ElastoDynBlade']['AdjEdSt'] = float_read(f.readline().split()[0]) - - # Distrilbuted Blade Properties - f.readline() - f.readline() - f.readline() - self.fst_vt['ElastoDynBlade']['BlFract'] = [None] * self.fst_vt['ElastoDynBlade']['NBlInpSt'] - self.fst_vt['ElastoDynBlade']['PitchAxis'] = [None] * self.fst_vt['ElastoDynBlade']['NBlInpSt'] - self.fst_vt['ElastoDynBlade']['StrcTwst'] = [None] * self.fst_vt['ElastoDynBlade']['NBlInpSt'] - self.fst_vt['ElastoDynBlade']['BMassDen'] = [None] * self.fst_vt['ElastoDynBlade']['NBlInpSt'] - self.fst_vt['ElastoDynBlade']['FlpStff'] = [None] * self.fst_vt['ElastoDynBlade']['NBlInpSt'] - self.fst_vt['ElastoDynBlade']['EdgStff'] = [None] * self.fst_vt['ElastoDynBlade']['NBlInpSt'] - if self.FAST_ver.lower() == 'fast7': - self.fst_vt['ElastoDynBlade']['GJStff'] = [None] * self.fst_vt['ElastoDynBlade']['NBlInpSt'] - self.fst_vt['ElastoDynBlade']['EAStff'] = [None] * self.fst_vt['ElastoDynBlade']['NBlInpSt'] - self.fst_vt['ElastoDynBlade']['Alpha'] = [None] * self.fst_vt['ElastoDynBlade']['NBlInpSt'] - self.fst_vt['ElastoDynBlade']['FlpIner'] = [None] * self.fst_vt['ElastoDynBlade']['NBlInpSt'] - self.fst_vt['ElastoDynBlade']['EdgIner'] = [None] * self.fst_vt['ElastoDynBlade']['NBlInpSt'] - self.fst_vt['ElastoDynBlade']['PrecrvRef'] = [None] * self.fst_vt['ElastoDynBlade']['NBlInpSt'] - self.fst_vt['ElastoDynBlade']['PreswpRef'] = [None] * self.fst_vt['ElastoDynBlade']['NBlInpSt'] - self.fst_vt['ElastoDynBlade']['FlpcgOf'] = [None] * self.fst_vt['ElastoDynBlade']['NBlInpSt'] - self.fst_vt['ElastoDynBlade']['Edgcgof'] = [None] * self.fst_vt['ElastoDynBlade']['NBlInpSt'] - self.fst_vt['ElastoDynBlade']['FlpEAOf'] = [None] * self.fst_vt['ElastoDynBlade']['NBlInpSt'] - self.fst_vt['ElastoDynBlade']['EdgEAOf'] = [None] * self.fst_vt['ElastoDynBlade']['NBlInpSt'] - for i in range(self.fst_vt['ElastoDynBlade']['NBlInpSt']): - data = f.readline().split() - self.fst_vt['ElastoDynBlade']['BlFract'][i] = float_read(data[0]) - self.fst_vt['ElastoDynBlade']['PitchAxis'][i] = float_read(data[1]) - self.fst_vt['ElastoDynBlade']['StrcTwst'][i] = float_read(data[2]) - self.fst_vt['ElastoDynBlade']['BMassDen'][i] = float_read(data[3]) - self.fst_vt['ElastoDynBlade']['FlpStff'][i] = float_read(data[4]) - self.fst_vt['ElastoDynBlade']['EdgStff'][i] = float_read(data[5]) - if self.FAST_ver.lower() == 'fast7': - self.fst_vt['ElastoDynBlade']['GJStff'][i] = float_read(data[6]) - self.fst_vt['ElastoDynBlade']['EAStff'][i] = float_read(data[7]) - self.fst_vt['ElastoDynBlade']['Alpha'][i] = float_read(data[8]) - self.fst_vt['ElastoDynBlade']['FlpIner'][i] = float_read(data[9]) - self.fst_vt['ElastoDynBlade']['EdgIner'][i] = float_read(data[10]) - self.fst_vt['ElastoDynBlade']['PrecrvRef'][i] = float_read(data[11]) - self.fst_vt['ElastoDynBlade']['PreswpRef'][i] = float_read(data[12]) - self.fst_vt['ElastoDynBlade']['FlpcgOf'][i] = float_read(data[13]) - self.fst_vt['ElastoDynBlade']['Edgcgof'][i] = float_read(data[14]) - self.fst_vt['ElastoDynBlade']['FlpEAOf'][i] = float_read(data[15]) - self.fst_vt['ElastoDynBlade']['EdgEAOf'][i] = float_read(data[16]) - - f.readline() - self.fst_vt['ElastoDynBlade']['BldFl1Sh'] = [None] * 5 - self.fst_vt['ElastoDynBlade']['BldFl2Sh'] = [None] * 5 - self.fst_vt['ElastoDynBlade']['BldEdgSh'] = [None] * 5 - for i in range(5): - self.fst_vt['ElastoDynBlade']['BldFl1Sh'][i] = float_read(f.readline().split()[0]) - for i in range(5): - self.fst_vt['ElastoDynBlade']['BldFl2Sh'][i] = float_read(f.readline().split()[0]) - for i in range(5): - self.fst_vt['ElastoDynBlade']['BldEdgSh'][i] = float_read(f.readline().split()[0]) - - f.close() - - def read_ElastoDynTower(self): - # ElastoDyn v1.00 Tower Input Files - # Currently no differences between FASTv8.16 and OpenFAST. - - if self.FAST_ver.lower() == 'fast7': - tower_file = os.path.join(self.FAST_directory, self.fst_vt['Fst7']['TwrFile']) - else: - tower_file = os.path.join(self.FAST_directory, self.fst_vt['ElastoDyn']['TwrFile']) - - f = open(tower_file) - - f.readline() - f.readline() - if self.FAST_ver.lower() == 'fast7': - f.readline() - - # General Tower Paramters - f.readline() - self.fst_vt['ElastoDynTower']['NTwInpSt'] = int(f.readline().split()[0]) - if self.FAST_ver.lower() == 'fast7': - self.fst_vt['ElastoDynTower']['CalcTMode'] = bool_read(f.readline().split()[0]) - self.fst_vt['ElastoDynTower']['TwrFADmp1'] = float_read(f.readline().split()[0]) - self.fst_vt['ElastoDynTower']['TwrFADmp2'] = float_read(f.readline().split()[0]) - self.fst_vt['ElastoDynTower']['TwrSSDmp1'] = float_read(f.readline().split()[0]) - self.fst_vt['ElastoDynTower']['TwrSSDmp2'] = float_read(f.readline().split()[0]) - - # Tower Adjustment Factors - f.readline() - self.fst_vt['ElastoDynTower']['FAStTunr1'] = float_read(f.readline().split()[0]) - self.fst_vt['ElastoDynTower']['FAStTunr2'] = float_read(f.readline().split()[0]) - self.fst_vt['ElastoDynTower']['SSStTunr1'] = float_read(f.readline().split()[0]) - self.fst_vt['ElastoDynTower']['SSStTunr2'] = float_read(f.readline().split()[0]) - self.fst_vt['ElastoDynTower']['AdjTwMa'] = float_read(f.readline().split()[0]) - self.fst_vt['ElastoDynTower']['AdjFASt'] = float_read(f.readline().split()[0]) - self.fst_vt['ElastoDynTower']['AdjSSSt'] = float_read(f.readline().split()[0]) - - # Distributed Tower Properties - f.readline() - f.readline() - f.readline() - self.fst_vt['ElastoDynTower']['HtFract'] = [None] * self.fst_vt['ElastoDynTower']['NTwInpSt'] - self.fst_vt['ElastoDynTower']['TMassDen'] = [None] * self.fst_vt['ElastoDynTower']['NTwInpSt'] - self.fst_vt['ElastoDynTower']['TwFAStif'] = [None] * self.fst_vt['ElastoDynTower']['NTwInpSt'] - self.fst_vt['ElastoDynTower']['TwSSStif'] = [None] * self.fst_vt['ElastoDynTower']['NTwInpSt'] - if self.FAST_ver.lower() == 'fast7': - self.fst_vt['ElastoDynTower']['TwGJStif'] = [None] * self.fst_vt['ElastoDynTower']['NTwInpSt'] - self.fst_vt['ElastoDynTower']['TwEAStif'] = [None] * self.fst_vt['ElastoDynTower']['NTwInpSt'] - self.fst_vt['ElastoDynTower']['TwFAIner'] = [None] * self.fst_vt['ElastoDynTower']['NTwInpSt'] - self.fst_vt['ElastoDynTower']['TwSSIner'] = [None] * self.fst_vt['ElastoDynTower']['NTwInpSt'] - self.fst_vt['ElastoDynTower']['TwFAcgOf'] = [None] * self.fst_vt['ElastoDynTower']['NTwInpSt'] - self.fst_vt['ElastoDynTower']['TwSScgOf'] = [None] * self.fst_vt['ElastoDynTower']['NTwInpSt'] - - for i in range(self.fst_vt['ElastoDynTower']['NTwInpSt']): - data = f.readline().split() - self.fst_vt['ElastoDynTower']['HtFract'][i] = float_read(data[0]) - self.fst_vt['ElastoDynTower']['TMassDen'][i] = float_read(data[1]) - self.fst_vt['ElastoDynTower']['TwFAStif'][i] = float_read(data[2]) - self.fst_vt['ElastoDynTower']['TwSSStif'][i] = float_read(data[3]) - if self.FAST_ver.lower() == 'fast7': - self.fst_vt['ElastoDynTower']['TwGJStif'][i] = float_read(data[4]) - self.fst_vt['ElastoDynTower']['TwEAStif'][i] = float_read(data[5]) - self.fst_vt['ElastoDynTower']['TwFAIner'][i] = float_read(data[6]) - self.fst_vt['ElastoDynTower']['TwSSIner'][i] = float_read(data[7]) - self.fst_vt['ElastoDynTower']['TwFAcgOf'][i] = float_read(data[8]) - self.fst_vt['ElastoDynTower']['TwSScgOf'][i] = float_read(data[9]) - - # Tower Mode Shapes - f.readline() - self.fst_vt['ElastoDynTower']['TwFAM1Sh'] = [None] * 5 - self.fst_vt['ElastoDynTower']['TwFAM2Sh'] = [None] * 5 - for i in range(5): - self.fst_vt['ElastoDynTower']['TwFAM1Sh'][i] = float_read(f.readline().split()[0]) - for i in range(5): - self.fst_vt['ElastoDynTower']['TwFAM2Sh'][i] = float_read(f.readline().split()[0]) - f.readline() - self.fst_vt['ElastoDynTower']['TwSSM1Sh'] = [None] * 5 - self.fst_vt['ElastoDynTower']['TwSSM2Sh'] = [None] * 5 - for i in range(5): - self.fst_vt['ElastoDynTower']['TwSSM1Sh'][i] = float_read(f.readline().split()[0]) - for i in range(5): - self.fst_vt['ElastoDynTower']['TwSSM2Sh'][i] = float_read(f.readline().split()[0]) - - 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 WndWindReader(self, wndfile): - # # .Wnd Wind Input File for Inflow - # wind_file = os.path.join(self.FAST_directory, wndfile) - # f = open(wind_file) - - # data = [] - # while 1: - # line = f.readline() - # if not line: - # break - # if line.strip().split()[0] != '!' and line[0] != '!': - # data.append(line.split()) - - # self.fst_vt['wnd_wind']['TimeSteps'] = len(data) - # self.fst_vt['wnd_wind']['Time'] = [None] * len(data) - # self.fst_vt['wnd_wind']['HorSpd'] = [None] * len(data) - # self.fst_vt['wnd_wind']['WindDir'] = [None] * len(data) - # self.fst_vt['wnd_wind']['VerSpd'] = [None] * len(data) - # self.fst_vt['wnd_wind']['HorShr'] = [None] * len(data) - # self.fst_vt['wnd_wind']['VerShr'] = [None] * len(data) - # self.fst_vt['wnd_wind']['LnVShr'] = [None] * len(data) - # self.fst_vt['wnd_wind']['GstSpd'] = [None] * len(data) - # for i in range(len(data)): - # self.fst_vt['wnd_wind']['Time'][i] = float_read(data[i][0]) - # self.fst_vt['wnd_wind']['HorSpd'][i] = float_read(data[i][1]) - # self.fst_vt['wnd_wind']['WindDir'][i] = float_read(data[i][2]) - # self.fst_vt['wnd_wind']['VerSpd'][i] = float_read(data[i][3]) - # self.fst_vt['wnd_wind']['HorShr'][i] = float_read(data[i][4]) - # self.fst_vt['wnd_wind']['VerShr'][i] = float_read(data[i][5]) - # self.fst_vt['wnd_wind']['LnVShr'][i] = float_read(data[i][6]) - # self.fst_vt['wnd_wind']['GstSpd'][i] = float_read(data[i][7]) - - # f.close() - - -class InputReader_OpenFAST(InputReader_Common): - """ OpenFAST / FAST 8.16 input file reader """ - - def execute(self): - - self.read_MainInput() - self.read_ElastoDyn() - self.read_ElastoDynBlade() - self.read_ElastoDynTower() - self.read_InflowWind() - - # if file_wind.split('.')[1] == 'wnd': - # self.WndWindReader(file_wind) - # else: - # print 'Wind reader for file type .%s not implemented yet.' % file_wind.split('.')[1] - # AeroDyn version selection - if self.fst_vt['Fst']['CompAero'] == 1: - self.read_AeroDyn14() - elif self.fst_vt['Fst']['CompAero'] == 2: - self.read_AeroDyn15() - - self.read_ServoDyn() - if ROSCO: - self.read_DISCON_in() - - - if self.fst_vt['Fst']['CompHydro'] == 1: # SubDyn not yet implimented - self.read_HydroDyn() - if self.fst_vt['Fst']['CompSub'] == 1: # SubDyn not yet implimented - self.read_SubDyn() - if self.fst_vt['Fst']['CompMooring'] == 1: # only MAP++ implimented for mooring models - self.read_MAP() - if self.fst_vt['Fst']['CompMooring'] == 3: # MoorDyn implimented - self.read_MoorDyn() - - if self.fst_vt['Fst']['CompElast'] == 2: # BeamDyn read assumes all 3 blades are the same - self.read_BeamDyn() - def read_MainInput(self): # Main FAST v8.16-v8.17 Input File # Currently no differences between FASTv8.16 and OpenFAST. @@ -536,11 +218,10 @@ def read_MainInput(self): self.fst_vt['Fst']['MooringFile_path'] = os.path.split(self.fst_vt['Fst']['MooringFile'])[0] self.fst_vt['Fst']['IceFile_path'] = os.path.split(self.fst_vt['Fst']['IceFile'])[0] - def read_ElastoDyn(self): + def read_ElastoDyn(self, ed_file): # ElastoDyn v1.03 Input File # Currently no differences between FASTv8.16 and OpenFAST. - ed_file = os.path.join(self.FAST_directory, self.fst_vt['Fst']['EDFile']) f = open(ed_file) f.readline() @@ -682,14 +363,13 @@ def read_ElastoDyn(self): 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]) - twrg = f.readline().split(',') if self.fst_vt['ElastoDyn']['NTwGages'] != 0: #loop over elements if there are gauges to be added, otherwise assign directly - for i in range(self.fst_vt['ElastoDyn']['NTwGages']): - self.fst_vt['ElastoDyn']['TwrGagNd'].append(twrg[i]) - self.fst_vt['ElastoDyn']['TwrGagNd'][-1] = self.fst_vt['ElastoDyn']['TwrGagNd'][-1][:-1] #remove last (newline) character + 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(',')) else: - self.fst_vt['ElastoDyn']['TwrGagNd'] = twrg - self.fst_vt['ElastoDyn']['TwrGagNd'][-1] = self.fst_vt['ElastoDyn']['TwrGagNd'][-1][:-1] + 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']] @@ -701,23 +381,138 @@ def read_ElastoDyn(self): # Loop through output channel lines f.readline() - data = f.readline() - 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() + 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() + + f.close() + + def read_ElastoDynBlade(self, blade_file): + # ElastoDyn v1.00 Blade Input File + # Currently no differences between FASTv8.16 and OpenFAST. + + f = open(blade_file) + # print blade_file + f.readline() + f.readline() + f.readline() + + # Blade Parameters + self.fst_vt['ElastoDynBlade']['NBlInpSt'] = int(f.readline().split()[0]) + self.fst_vt['ElastoDynBlade']['BldFlDmp1'] = float_read(f.readline().split()[0]) + self.fst_vt['ElastoDynBlade']['BldFlDmp2'] = float_read(f.readline().split()[0]) + self.fst_vt['ElastoDynBlade']['BldEdDmp1'] = float_read(f.readline().split()[0]) + + # Blade Adjustment Factors + f.readline() + self.fst_vt['ElastoDynBlade']['FlStTunr1'] = float_read(f.readline().split()[0]) + self.fst_vt['ElastoDynBlade']['FlStTunr2'] = float_read(f.readline().split()[0]) + self.fst_vt['ElastoDynBlade']['AdjBlMs'] = float_read(f.readline().split()[0]) + self.fst_vt['ElastoDynBlade']['AdjFlSt'] = float_read(f.readline().split()[0]) + self.fst_vt['ElastoDynBlade']['AdjEdSt'] = float_read(f.readline().split()[0]) + + # Distrilbuted Blade Properties + f.readline() + f.readline() + f.readline() + self.fst_vt['ElastoDynBlade']['BlFract'] = [None] * self.fst_vt['ElastoDynBlade']['NBlInpSt'] + self.fst_vt['ElastoDynBlade']['PitchAxis'] = [None] * self.fst_vt['ElastoDynBlade']['NBlInpSt'] + self.fst_vt['ElastoDynBlade']['StrcTwst'] = [None] * self.fst_vt['ElastoDynBlade']['NBlInpSt'] + self.fst_vt['ElastoDynBlade']['BMassDen'] = [None] * self.fst_vt['ElastoDynBlade']['NBlInpSt'] + self.fst_vt['ElastoDynBlade']['FlpStff'] = [None] * self.fst_vt['ElastoDynBlade']['NBlInpSt'] + self.fst_vt['ElastoDynBlade']['EdgStff'] = [None] * self.fst_vt['ElastoDynBlade']['NBlInpSt'] + + for i in range(self.fst_vt['ElastoDynBlade']['NBlInpSt']): + data = f.readline().split() + self.fst_vt['ElastoDynBlade']['BlFract'][i] = float_read(data[0]) + self.fst_vt['ElastoDynBlade']['PitchAxis'][i] = float_read(data[1]) + self.fst_vt['ElastoDynBlade']['StrcTwst'][i] = float_read(data[2]) + self.fst_vt['ElastoDynBlade']['BMassDen'][i] = float_read(data[3]) + self.fst_vt['ElastoDynBlade']['FlpStff'][i] = float_read(data[4]) + self.fst_vt['ElastoDynBlade']['EdgStff'][i] = float_read(data[5]) + + f.readline() + self.fst_vt['ElastoDynBlade']['BldFl1Sh'] = [None] * 5 + self.fst_vt['ElastoDynBlade']['BldFl2Sh'] = [None] * 5 + self.fst_vt['ElastoDynBlade']['BldEdgSh'] = [None] * 5 + for i in range(5): + self.fst_vt['ElastoDynBlade']['BldFl1Sh'][i] = float_read(f.readline().split()[0]) + for i in range(5): + self.fst_vt['ElastoDynBlade']['BldFl2Sh'][i] = float_read(f.readline().split()[0]) + for i in range(5): + self.fst_vt['ElastoDynBlade']['BldEdgSh'][i] = float_read(f.readline().split()[0]) + + f.close() + + def read_ElastoDynTower(self, tower_file): + # ElastoDyn v1.00 Tower Input Files + # Currently no differences between FASTv8.16 and OpenFAST. + + f = open(tower_file) + + f.readline() + f.readline() + + # General Tower Paramters + f.readline() + self.fst_vt['ElastoDynTower']['NTwInpSt'] = int(f.readline().split()[0]) + self.fst_vt['ElastoDynTower']['TwrFADmp1'] = float_read(f.readline().split()[0]) + self.fst_vt['ElastoDynTower']['TwrFADmp2'] = float_read(f.readline().split()[0]) + self.fst_vt['ElastoDynTower']['TwrSSDmp1'] = float_read(f.readline().split()[0]) + self.fst_vt['ElastoDynTower']['TwrSSDmp2'] = float_read(f.readline().split()[0]) + + # Tower Adjustment Factors + f.readline() + self.fst_vt['ElastoDynTower']['FAStTunr1'] = float_read(f.readline().split()[0]) + self.fst_vt['ElastoDynTower']['FAStTunr2'] = float_read(f.readline().split()[0]) + self.fst_vt['ElastoDynTower']['SSStTunr1'] = float_read(f.readline().split()[0]) + self.fst_vt['ElastoDynTower']['SSStTunr2'] = float_read(f.readline().split()[0]) + self.fst_vt['ElastoDynTower']['AdjTwMa'] = float_read(f.readline().split()[0]) + self.fst_vt['ElastoDynTower']['AdjFASt'] = float_read(f.readline().split()[0]) + self.fst_vt['ElastoDynTower']['AdjSSSt'] = float_read(f.readline().split()[0]) + + # Distributed Tower Properties + f.readline() + f.readline() + f.readline() + self.fst_vt['ElastoDynTower']['HtFract'] = [None] * self.fst_vt['ElastoDynTower']['NTwInpSt'] + self.fst_vt['ElastoDynTower']['TMassDen'] = [None] * self.fst_vt['ElastoDynTower']['NTwInpSt'] + self.fst_vt['ElastoDynTower']['TwFAStif'] = [None] * self.fst_vt['ElastoDynTower']['NTwInpSt'] + self.fst_vt['ElastoDynTower']['TwSSStif'] = [None] * self.fst_vt['ElastoDynTower']['NTwInpSt'] - data = f.readline() + for i in range(self.fst_vt['ElastoDynTower']['NTwInpSt']): + data = f.readline().split() + self.fst_vt['ElastoDynTower']['HtFract'][i] = float_read(data[0]) + self.fst_vt['ElastoDynTower']['TMassDen'][i] = float_read(data[1]) + self.fst_vt['ElastoDynTower']['TwFAStif'][i] = float_read(data[2]) + self.fst_vt['ElastoDynTower']['TwSSStif'][i] = float_read(data[3]) + + # Tower Mode Shapes + f.readline() + self.fst_vt['ElastoDynTower']['TwFAM1Sh'] = [None] * 5 + self.fst_vt['ElastoDynTower']['TwFAM2Sh'] = [None] * 5 + for i in range(5): + self.fst_vt['ElastoDynTower']['TwFAM1Sh'][i] = float_read(f.readline().split()[0]) + for i in range(5): + self.fst_vt['ElastoDynTower']['TwFAM2Sh'][i] = float_read(f.readline().split()[0]) + f.readline() + self.fst_vt['ElastoDynTower']['TwSSM1Sh'] = [None] * 5 + self.fst_vt['ElastoDynTower']['TwSSM2Sh'] = [None] * 5 + for i in range(5): + self.fst_vt['ElastoDynTower']['TwSSM1Sh'][i] = float_read(f.readline().split()[0]) + for i in range(5): + self.fst_vt['ElastoDynTower']['TwSSM2Sh'][i] = float_read(f.readline().split()[0]) f.close() - def read_BeamDyn(self): + def read_BeamDyn(self, bd_file): # BeamDyn Input File - - bd_file = os.path.join(self.FAST_directory, self.fst_vt['Fst']['BDBldFile(1)']) f = open(bd_file) - f.readline() f.readline() f.readline() @@ -728,7 +523,7 @@ def read_BeamDyn(self): self.fst_vt['BeamDyn']['quadrature'] = int_read(f.readline().split()[0]) self.fst_vt['BeamDyn']['refine'] = int_read(f.readline().split()[0]) self.fst_vt['BeamDyn']['n_fact'] = int_read(f.readline().split()[0]) - self.fst_vt['BeamDyn']['DTBeam'] = float_read(f.readline().split()[0]) + self.fst_vt['BeamDyn']['DTBeam'] = float_read(f.readline().split()[0]) self.fst_vt['BeamDyn']['load_retries'] = int_read(f.readline().split()[0]) self.fst_vt['BeamDyn']['NRMax'] = int_read(f.readline().split()[0]) self.fst_vt['BeamDyn']['stop_tol'] = float_read(f.readline().split()[0]) @@ -906,112 +701,24 @@ def read_InflowWind(self): f.readline() self.fst_vt['InflowWind']['SumPrint'] = bool_read(f.readline().split()[0]) - # NO INFLOW WIND OUTPUT PARAMETERS YET DEFINED IN FAST - # f.readline() - # data = f.readline() - # while data.split()[0] != 'END': - # channels = data.split('"') - # channel_list = channels[1].split(',') - # for i in range(len(channel_list)): - # channel_list[i] = channel_list[i].replace(' ','') - # if channel_list[i] in self.fst_vt.outlist.inflow_wind_vt.__dict__.keys(): - # self.fst_vt.outlist.inflow_wind_vt.__dict__[channel_list[i]] = True - # data = 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'] = f.readline().split()[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]) - 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]) + # InflowWind Outlist 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] + 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']['InflowWind'], channel_list) + data = f.readline() f.close() - - # create airfoil objects - self.fst_vt['AeroDynBlade']['af_data'] = [] - for i in range(self.fst_vt['AeroDynBlade']['NumFoil']): - self.fst_vt['AeroDynBlade']['af_data'].append(self.read_AeroDyn14Polar(os.path.join(self.FAST_directory,self.fst_vt['AeroDyn14']['FoilNm'][i]))) - - # tower - self.read_AeroDyn14Tower() - - def read_AeroDyn14Tower(self): - # AeroDyn v14.04 Tower - - ad_tower_file = os.path.join(self.FAST_directory, self.fst_vt['aerodyn']['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:] - + def read_AeroDyn15(self): # AeroDyn v15.03 @@ -1027,10 +734,11 @@ def read_AeroDyn15(self): 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']['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]) self.fst_vt['AeroDyn15']['AA_InputFile'] = f.readline().split()[0] @@ -1045,8 +753,8 @@ def read_AeroDyn15(self): # Blade-Element/Momentum Theory Options f.readline() - self.fst_vt['AeroDyn15']['SkewMod'] = int(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']['SkewModFactor'] = float_read(f.readline().split()[0]) 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]) @@ -1069,8 +777,8 @@ def read_AeroDyn15(self): f.readline() self.fst_vt['AeroDyn15']['UAMod'] = int(f.readline().split()[0]) self.fst_vt['AeroDyn15']['FLookup'] = bool_read(f.readline().split()[0]) - self.fst_vt['AeroDyn15']['UAStartRad'] = float_read(f.readline().split()[0]) - self.fst_vt['AeroDyn15']['UAEndRad'] = float_read(f.readline().split()[0]) + # self.fst_vt['AeroDyn15']['UAStartRad'] = float_read(f.readline().split()[0]) + # self.fst_vt['AeroDyn15']['UAEndRad'] = float_read(f.readline().split()[0]) # Airfoil Information f.readline() @@ -1093,21 +801,36 @@ def read_AeroDyn15(self): self.fst_vt['AeroDyn15']['ADBlFile2'] = f.readline().split()[0][1:-1] self.fst_vt['AeroDyn15']['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]) + f.readline() + 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(',')] + f.readline() + self.fst_vt['AeroDyn15']['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)) + # Tower Influence and Aerodynamics f.readline() self.fst_vt['AeroDyn15']['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']['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']): 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] # Outputs f.readline() @@ -1121,8 +844,15 @@ def read_AeroDyn15(self): f.readline() data = f.readline() while data.split()[0] != 'END': - channels = data.split('"') - channel_list = channels[1].split(',') + 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() @@ -1131,10 +861,9 @@ def read_AeroDyn15(self): self.read_AeroDyn15Blade() self.read_AeroDyn15Polar() self.read_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') - self.read_AeroDyn15OLAF() + olaf_filename = os.path.join(self.FAST_directory, self.fst_vt['AeroDyn15']['OLAFInputFileName']) + if os.path.isfile(olaf_filename): + self.read_AeroDyn15OLAF(olaf_filename) def read_AeroDyn15Blade(self): # AeroDyn v5.00 Blade Definition File @@ -1197,6 +926,8 @@ def read_AeroDyn15Polar(self): polar['alpha0'] = float_read(readline_filterComments(f).split()[0]) polar['alpha1'] = float_read(readline_filterComments(f).split()[0]) polar['alpha2'] = float_read(readline_filterComments(f).split()[0]) + # polar['alphaUpper'] = float_read(readline_filterComments(f).split()[0]) + # polar['alphaLower'] = float_read(readline_filterComments(f).split()[0]) polar['eta_e'] = float_read(readline_filterComments(f).split()[0]) polar['C_nalpha'] = float_read(readline_filterComments(f).split()[0]) polar['T_f0'] = float_read(readline_filterComments(f).split()[0]) @@ -1251,84 +982,256 @@ def read_AeroDyn15Polar(self): f.close() - def read_AeroDyn15Coord(self): - - self.fst_vt['AeroDyn15']['af_coord'] = [] - self.fst_vt['AeroDyn15']['ac'] = np.zeros(len(self.fst_vt['AeroDyn15']['AFNames'])) + def read_AeroDyn15Coord(self): + + self.fst_vt['AeroDyn15']['af_coord'] = [] + self.fst_vt['AeroDyn15']['ac'] = np.zeros(len(self.fst_vt['AeroDyn15']['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] + 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() + + 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): + + self.fst_vt['AeroDyn15']['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]) + 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'] = f.readline().split()[0] + 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]) + 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]) + 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]) + 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(f.readline().split()[0]) + f.readline() + f.readline() + self.fst_vt['AeroDyn15']['OLAF']['WrVTk'] = int(f.readline().split()[0]) + self.fst_vt['AeroDyn15']['OLAF']['nVTKBlades'] = int(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]) + 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]))) - 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] - 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() + # tower + if self.fst_vt['AeroDyn14']['TwrShad'] > 0: + self.read_AeroDyn14Tower() - self.fst_vt['AeroDyn15']['af_coord'][afi]['x'] = x - self.fst_vt['AeroDyn15']['af_coord'][afi]['y'] = y + def read_AeroDyn14Tower(self): + # AeroDyn v14.04 Tower - f.close() + ad_tower_file = os.path.join(self.FAST_directory, self.fst_vt['AeroDyn14']['TwrFile']) + f = open(ad_tower_file) - def read_AeroDyn15OLAF(self): - - self.fst_vt['AeroDyn15']['OLAF'] = {} - olaf_filename = os.path.join(self.FAST_directory, self.fst_vt['AeroDyn15']['OLAFInputFileName']) - 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]) f.readline() - self.fst_vt['AeroDyn15']['OLAF']['CircSolvingMethod'] = 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'] = f.readline().split()[0] 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['AeroDyn15']['OLAF']['nNWPanel'] = int(f.readline().split()[0]) - self.fst_vt['AeroDyn15']['OLAF']['WakeLength'] = int(f.readline().split()[0]) - self.fst_vt['AeroDyn15']['OLAF']['FreeWakeLength'] = int_read(f.readline().split()[0]) - self.fst_vt['AeroDyn15']['OLAF']['FWShedVorticity'] = float_read(f.readline().split()[0]) + 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() - 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]) 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['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() - 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(f.readline().split()[0]) + 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() - self.fst_vt['AeroDyn15']['OLAF']['WrVTk'] = int(f.readline().split()[0]) - self.fst_vt['AeroDyn15']['OLAF']['nVTKBlades'] = int(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]) 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_ServoDyn(self): # ServoDyn v1.05 Input File @@ -1542,10 +1445,8 @@ def read_DISCON_in(self): else: del self.fst_vt['DISCON_in'] - def read_HydroDyn(self): - # AeroDyn v2.03 + def read_HydroDyn(self, hd_file): - hd_file = os.path.normpath(os.path.join(self.FAST_directory, self.fst_vt['Fst']['HydroFile'])) f = open(hd_file) f.readline() @@ -1906,10 +1807,8 @@ def read_HydroDyn(self): f.close() - def read_SubDyn(self): - # SubDyn v1.01 + def read_SubDyn(self, sd_file): - sd_file = os.path.normpath(os.path.join(self.FAST_directory, self.fst_vt['Fst']['SubFile'])) f = open(sd_file) f.readline() f.readline() @@ -1928,7 +1827,7 @@ def read_SubDyn(self): self.fst_vt['SubDyn']['Nmodes'] = int_read(f.readline().split()[0]) self.fst_vt['SubDyn']['JDampings'] = int_read(f.readline().split()[0]) self.fst_vt['SubDyn']['GuyanDampMod'] = int_read(f.readline().split()[0]) - self.fst_vt['SubDyn']['RayleighDamp'] = [float(m) for m in f.readline().strip().replace(',','').split()[:2]] + self.fst_vt['SubDyn']['RayleighDamp'] = [float(m.replace(',','')) for m in f.readline().split()[:2]] 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() @@ -2062,12 +1961,13 @@ def read_SubDyn(self): self.fst_vt['SubDyn']['YoungE2'][i] = float(ln[1]) self.fst_vt['SubDyn']['ShearG2'][i] = float(ln[2]) self.fst_vt['SubDyn']['MatDens2'][i] = float(ln[3]) - self.fst_vt['SubDyn']['XsecA'][i] = float(ln[4]) - self.fst_vt['SubDyn']['XsecAsx'][i] = float(ln[5]) - self.fst_vt['SubDyn']['XsecAsy'][i] = float(ln[6]) - self.fst_vt['SubDyn']['XsecJxx'][i] = float(ln[7]) - self.fst_vt['SubDyn']['XsecJyy'][i] = float(ln[8]) - self.fst_vt['SubDyn']['XsecJ0'][i] = float(ln[9]) + self.fst_vt['SubDyn']['XsecA'][i] = float(ln[4]) + self.fst_vt['SubDyn']['XsecAsx'][i] = float(ln[5]) + self.fst_vt['SubDyn']['XsecAsy'][i] = float(ln[6]) + self.fst_vt['SubDyn']['XsecJxx'][i] = float(ln[7]) + self.fst_vt['SubDyn']['XsecJyy'][i] = float(ln[8]) + self.fst_vt['SubDyn']['XsecJ0'][i] = float(ln[9]) + # CABLE PROPERTIES f.readline() self.fst_vt['SubDyn']['NCablePropSets'] = int_read(f.readline().split()[0]) self.fst_vt['SubDyn']['CablePropSetID'] = [None]*self.fst_vt['SubDyn']['NCablePropSets'] @@ -2185,14 +2085,12 @@ def read_SubDyn(self): f.close() - def read_MAP(self): + 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 - map_file = os.path.normpath(os.path.join(self.FAST_directory, self.fst_vt['Fst']['MooringFile'])) - f = open(map_file) f.readline() f.readline() @@ -2236,11 +2134,9 @@ def read_MAP(self): f.readline() f.readline() self.fst_vt['MAP']['Option'] = [str(val) for val in f.readline().strip().split()] + f.close() - - def read_MoorDyn(self): - - moordyn_file = os.path.normpath(os.path.join(self.FAST_directory, self.fst_vt['Fst']['MooringFile'])) + def read_MoorDyn(self, moordyn_file): f = open(moordyn_file) @@ -2249,7 +2145,6 @@ def read_MoorDyn(self): f.readline() self.fst_vt['MoorDyn']['Echo'] = bool_read(f.readline().split()[0]) f.readline() - self.fst_vt['MoorDyn']['NTypes'] = int_read(f.readline().split()[0]) f.readline() f.readline() self.fst_vt['MoorDyn']['Name'] = [] @@ -2257,77 +2152,67 @@ def read_MoorDyn(self): self.fst_vt['MoorDyn']['MassDen'] = [] self.fst_vt['MoorDyn']['EA'] = [] self.fst_vt['MoorDyn']['BA_zeta'] = [] - self.fst_vt['MoorDyn']['Can'] = [] - self.fst_vt['MoorDyn']['Cat'] = [] - self.fst_vt['MoorDyn']['Cdn'] = [] - self.fst_vt['MoorDyn']['Cdt'] = [] - for i in range(self.fst_vt['MoorDyn']['NTypes']): - data_line = f.readline().strip().split() + 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']['Can'].append(float(data_line[5])) - self.fst_vt['MoorDyn']['Cat'].append(float(data_line[6])) - self.fst_vt['MoorDyn']['Cdn'].append(float(data_line[7])) - self.fst_vt['MoorDyn']['Cdt'].append(float(data_line[8])) - f.readline() - self.fst_vt['MoorDyn']['NConnects'] = int_read(f.readline().split()[0]) + 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']['Node'] = [] - self.fst_vt['MoorDyn']['Type'] = [] + 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']['FX'] = [] - self.fst_vt['MoorDyn']['FY'] = [] - self.fst_vt['MoorDyn']['FZ'] = [] self.fst_vt['MoorDyn']['CdA'] = [] self.fst_vt['MoorDyn']['CA'] = [] - for i in range(self.fst_vt['MoorDyn']['NConnects']): - data_line = f.readline().strip().split() - self.fst_vt['MoorDyn']['Node'].append(int(data_line[0])) - self.fst_vt['MoorDyn']['Type'].append(str(data_line[1])) + 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']['FX'].append(float(data_line[7])) - self.fst_vt['MoorDyn']['FY'].append(float(data_line[8])) - self.fst_vt['MoorDyn']['FZ'].append(float(data_line[9])) - self.fst_vt['MoorDyn']['CdA'].append(float(data_line[10])) - self.fst_vt['MoorDyn']['CA'].append(float(data_line[11])) - f.readline() - self.fst_vt['MoorDyn']['NLines'] = int_read(f.readline().split()[0]) - f.readline() - f.readline() - self.fst_vt['MoorDyn']['Line'] = [] - self.fst_vt['MoorDyn']['LineType'] = [] - self.fst_vt['MoorDyn']['UnstrLen'] = [] - self.fst_vt['MoorDyn']['NumSegs'] = [] - self.fst_vt['MoorDyn']['NodeAnch'] = [] - self.fst_vt['MoorDyn']['NodeFair'] = [] - self.fst_vt['MoorDyn']['Outputs'] = [] - self.fst_vt['MoorDyn']['CtrlChan'] = [] - for i in range(self.fst_vt['MoorDyn']['NLines']): + 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() - self.fst_vt['MoorDyn']['Line'].append(int(data_line[0])) + 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']['UnstrLen'].append(float(data_line[2])) - self.fst_vt['MoorDyn']['NumSegs'].append(int(data_line[3])) - self.fst_vt['MoorDyn']['NodeAnch'].append(int(data_line[4])) - self.fst_vt['MoorDyn']['NodeFair'].append(int(data_line[5])) + 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])) - if len(data_line) > 7: - self.fst_vt['MoorDyn']['CtrlChan'].append(int(data_line[7])) - else: - self.fst_vt['MoorDyn']['CtrlChan'].append(0) - f.readline() + data_line = f.readline().strip().split() + 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]) @@ -2343,318 +2228,58 @@ def read_MoorDyn(self): channel_list = channels.split(',') self.set_outlist(self.fst_vt['outlist']['MoorDyn'], channel_list) data = f.readline() - f.close() + f.close() -class InputReader_FAST7(InputReader_Common): - """ FASTv7.02 input file reader """ - def execute(self): + self.read_MainInput() - self.read_AeroDyn_FAST7() - # if self.fst_vt['aerodyn']['wind_file_type'][1] == 'wnd': - # self.WndWindReader(self.fst_vt['aerodyn']['WindFile']) - # else: - # print 'Wind reader for file type .%s not implemented yet.' % self.fst_vt['aerodyn']['wind_file_type'][1] - self.read_ElastoDynBlade() - self.read_ElastoDynTower() - - def read_MainInput(self): - - fst_file = os.path.join(self.FAST_directory, self.FAST_InputFile) - f = open(fst_file) - - # FAST Inputs - f.readline() - f.readline() - self.fst_vt['description'] = f.readline().rstrip() - f.readline() - f.readline() - self.fst_vt['Fst7']['Echo'] = bool_read(f.readline().split()[0]) - self.fst_vt['Fst7']['ADAMSPrep'] = int(f.readline().split()[0]) - self.fst_vt['Fst7']['AnalMode'] = int(f.readline().split()[0]) - self.fst_vt['Fst7']['NumBl'] = int(f.readline().split()[0]) - self.fst_vt['Fst7']['TMax'] = float_read(f.readline().split()[0]) - self.fst_vt['Fst7']['DT'] = float_read(f.readline().split()[0]) - f.readline() - self.fst_vt['Fst7']['YCMode'] = int(f.readline().split()[0]) - self.fst_vt['Fst7']['TYCOn'] = float_read(f.readline().split()[0]) - self.fst_vt['Fst7']['PCMode'] = int(f.readline().split()[0]) - self.fst_vt['Fst7']['TPCOn'] = float_read(f.readline().split()[0]) - self.fst_vt['Fst7']['VSContrl'] = int(f.readline().split()[0]) - self.fst_vt['Fst7']['VS_RtGnSp'] = float_read(f.readline().split()[0]) - self.fst_vt['Fst7']['VS_RtTq'] = float_read(f.readline().split()[0]) - self.fst_vt['Fst7']['VS_Rgn2K'] = float_read(f.readline().split()[0]) - self.fst_vt['Fst7']['VS_SlPc'] = float_read(f.readline().split()[0]) - self.fst_vt['Fst7']['GenModel'] = int(f.readline().split()[0]) - self.fst_vt['Fst7']['GenTiStr'] = bool(f.readline().split()[0]) - self.fst_vt['Fst7']['GenTiStp'] = bool(f.readline().split()[0]) - self.fst_vt['Fst7']['SpdGenOn'] = float_read(f.readline().split()[0]) - self.fst_vt['Fst7']['TimGenOn'] = float_read(f.readline().split()[0]) - self.fst_vt['Fst7']['TimGenOf'] = float_read(f.readline().split()[0]) - self.fst_vt['Fst7']['HSSBrMode'] = int(f.readline().split()[0]) - self.fst_vt['Fst7']['THSSBrDp'] = float_read(f.readline().split()[0]) - self.fst_vt['Fst7']['TiDynBrk'] = float_read(f.readline().split()[0]) - self.fst_vt['Fst7']['TTpBrDp1'] = float_read(f.readline().split()[0]) - self.fst_vt['Fst7']['TTpBrDp2'] = float_read(f.readline().split()[0]) - self.fst_vt['Fst7']['TTpBrDp3'] = float_read(f.readline().split()[0]) - self.fst_vt['Fst7']['TBDepISp1'] = float_read(f.readline().split()[0]) - self.fst_vt['Fst7']['TBDepISp2'] = float_read(f.readline().split()[0]) - self.fst_vt['Fst7']['TBDepISp3'] = float_read(f.readline().split()[0]) - self.fst_vt['Fst7']['TYawManS'] = float_read(f.readline().split()[0]) - self.fst_vt['Fst7']['TYawManE'] = float_read(f.readline().split()[0]) - self.fst_vt['Fst7']['NacYawF'] = float_read(f.readline().split()[0]) - self.fst_vt['Fst7']['TPitManS1'] = float_read(f.readline().split()[0]) - self.fst_vt['Fst7']['TPitManS2'] = float_read(f.readline().split()[0]) - self.fst_vt['Fst7']['TPitManS3'] = float_read(f.readline().split()[0]) - self.fst_vt['Fst7']['TPitManE1'] = float_read(f.readline().split()[0]) - self.fst_vt['Fst7']['TPitManE2'] = float_read(f.readline().split()[0]) - self.fst_vt['Fst7']['TPitManE3'] = float_read(f.readline().split()[0]) - self.fst_vt['Fst7']['BlPitch1'] = float_read(f.readline().split()[0]) - self.fst_vt['Fst7']['BlPitch2'] = float_read(f.readline().split()[0]) - self.fst_vt['Fst7']['BlPitch3'] = float_read(f.readline().split()[0]) - self.fst_vt['Fst7']['B1PitchF1'] = float_read(f.readline().split()[0]) - self.fst_vt['Fst7']['B1PitchF2'] = float_read(f.readline().split()[0]) - self.fst_vt['Fst7']['B1PitchF3'] = float_read(f.readline().split()[0]) - f.readline() - self.fst_vt['Fst7']['Gravity'] = float_read(f.readline().split()[0]) - f.readline() - self.fst_vt['Fst7']['FlapDOF1'] = bool_read(f.readline().split()[0]) - self.fst_vt['Fst7']['FlapDOF2'] = bool_read(f.readline().split()[0]) - self.fst_vt['Fst7']['EdgeDOF'] = bool_read(f.readline().split()[0]) - self.fst_vt['Fst7']['TeetDOF'] = bool_read(f.readline().split()[0]) - self.fst_vt['Fst7']['DrTrDOF'] = bool_read(f.readline().split()[0]) - self.fst_vt['Fst7']['GenDOF'] = bool_read(f.readline().split()[0]) - self.fst_vt['Fst7']['YawDOF'] = bool_read(f.readline().split()[0]) - self.fst_vt['Fst7']['TwFADOF1'] = bool_read(f.readline().split()[0]) - self.fst_vt['Fst7']['TwFADOF2'] = bool_read(f.readline().split()[0]) - self.fst_vt['Fst7']['TwSSDOF1'] = bool_read(f.readline().split()[0]) - self.fst_vt['Fst7']['TwSSDOF2'] = bool_read(f.readline().split()[0]) - self.fst_vt['Fst7']['CompAero'] = bool_read(f.readline().split()[0]) - self.fst_vt['Fst7']['CompNoise'] = bool_read(f.readline().split()[0]) - f.readline() - self.fst_vt['Fst7']['OoPDefl'] = float_read(f.readline().split()[0]) - self.fst_vt['Fst7']['IPDefl'] = float_read(f.readline().split()[0]) - self.fst_vt['Fst7']['TeetDefl'] = float_read(f.readline().split()[0]) - self.fst_vt['Fst7']['Azimuth'] = float_read(f.readline().split()[0]) - self.fst_vt['Fst7']['RotSpeed'] = float_read(f.readline().split()[0]) - self.fst_vt['Fst7']['NacYaw'] = float_read(f.readline().split()[0]) - self.fst_vt['Fst7']['TTDspFA'] = float_read(f.readline().split()[0]) - self.fst_vt['Fst7']['TTDspSS'] = float_read(f.readline().split()[0]) - f.readline() - self.fst_vt['Fst7']['TipRad'] = float_read(f.readline().split()[0]) - self.fst_vt['Fst7']['HubRad'] = float_read(f.readline().split()[0]) - self.fst_vt['Fst7']['PSpnElN'] = int(f.readline().split()[0]) - self.fst_vt['Fst7']['UndSling'] = float_read(f.readline().split()[0]) - self.fst_vt['Fst7']['HubCM'] = float_read(f.readline().split()[0]) - self.fst_vt['Fst7']['OverHang'] = float_read(f.readline().split()[0]) - self.fst_vt['Fst7']['NacCMxn'] = float_read(f.readline().split()[0]) - self.fst_vt['Fst7']['NacCMyn'] = float_read(f.readline().split()[0]) - self.fst_vt['Fst7']['NacCMzn'] = float_read(f.readline().split()[0]) - self.fst_vt['Fst7']['TowerHt'] = float_read(f.readline().split()[0]) - self.fst_vt['Fst7']['Twr2Shft'] = float_read(f.readline().split()[0]) - self.fst_vt['Fst7']['TwrRBHt'] = float_read(f.readline().split()[0]) - self.fst_vt['Fst7']['ShftTilt'] = float_read(f.readline().split()[0]) - self.fst_vt['Fst7']['Delta3'] = float_read(f.readline().split()[0]) - self.fst_vt['Fst7']['PreCone(1)'] = float_read(f.readline().split()[0]) - self.fst_vt['Fst7']['PreCone(2)'] = float_read(f.readline().split()[0]) - self.fst_vt['Fst7']['PreCone(3)'] = float_read(f.readline().split()[0]) - self.fst_vt['Fst7']['AzimB1Up'] = float_read(f.readline().split()[0]) - f.readline() - self.fst_vt['Fst7']['YawBrMass'] = float_read(f.readline().split()[0]) - self.fst_vt['Fst7']['NacMass'] = float_read(f.readline().split()[0]) - self.fst_vt['Fst7']['HubMass'] = float_read(f.readline().split()[0]) - self.fst_vt['Fst7']['TipMass(1)'] = float_read(f.readline().split()[0]) - self.fst_vt['Fst7']['TipMass(2)'] = float_read(f.readline().split()[0]) - self.fst_vt['Fst7']['TipMass(3)'] = float_read(f.readline().split()[0]) - self.fst_vt['Fst7']['NacYIner'] = float_read(f.readline().split()[0]) - self.fst_vt['Fst7']['GenIner'] = float_read(f.readline().split()[0]) - self.fst_vt['Fst7']['HubIner'] = float_read(f.readline().split()[0]) - f.readline() - self.fst_vt['Fst7']['GBoxEff'] = float_read(f.readline().split()[0]) - self.fst_vt['Fst7']['GenEff'] = float_read(f.readline().split()[0]) - self.fst_vt['Fst7']['GBRatio'] = float_read(f.readline().split()[0]) - self.fst_vt['Fst7']['GBRevers'] = bool_read(f.readline().split()[0]) - self.fst_vt['Fst7']['HSSBrTqF'] = float_read(f.readline().split()[0]) - self.fst_vt['Fst7']['HSSBrDT'] = float_read(f.readline().split()[0]) - self.fst_vt['Fst7']['DynBrkFi'] = f.readline().split()[0] - self.fst_vt['Fst7']['DTTorSpr'] = float_read(f.readline().split()[0]) - self.fst_vt['Fst7']['DTTorDmp'] = float_read(f.readline().split()[0]) - f.readline() - self.fst_vt['Fst7']['SIG_SlPc'] = float_read(f.readline().split()[0]) - self.fst_vt['Fst7']['SIG_SySp'] = float_read(f.readline().split()[0]) - self.fst_vt['Fst7']['SIG_RtTq'] = float_read(f.readline().split()[0]) - self.fst_vt['Fst7']['SIG_PORt'] = float_read(f.readline().split()[0]) - f.readline() - self.fst_vt['Fst7']['TEC_Freq'] = float_read(f.readline().split()[0]) - self.fst_vt['Fst7']['TEC_NPol'] = int(f.readline().split()[0]) - self.fst_vt['Fst7']['TEC_SRes'] = float_read(f.readline().split()[0]) - self.fst_vt['Fst7']['TEC_RRes'] = float_read(f.readline().split()[0]) - self.fst_vt['Fst7']['TEC_VLL'] = float_read(f.readline().split()[0]) - self.fst_vt['Fst7']['TEC_SLR'] = float_read(f.readline().split()[0]) - self.fst_vt['Fst7']['TEC_RLR'] = float_read(f.readline().split()[0]) - self.fst_vt['Fst7']['TEC_MR'] = float_read(f.readline().split()[0]) - f.readline() - self.fst_vt['Fst7']['PtfmModel'] = int(f.readline().split()[0]) - self.fst_vt['Fst7']['PtfmFile'] = f.readline().split()[0][1:-1] - f.readline() - self.fst_vt['Fst7']['TwrNodes'] = int(f.readline().split()[0]) - self.fst_vt['Fst7']['TwrFile'] = f.readline().split()[0][1:-1] - f.readline() - self.fst_vt['Fst7']['YawSpr'] = float_read(f.readline().split()[0]) - self.fst_vt['Fst7']['YawDamp'] = float_read(f.readline().split()[0]) - self.fst_vt['Fst7']['YawNeut'] = float_read(f.readline().split()[0]) - f.readline() - self.fst_vt['Fst7']['Furling'] = bool_read(f.readline().split()[0]) - self.fst_vt['Fst7']['FurlFile'] = f.readline().split()[0] - f.readline() - self.fst_vt['Fst7']['TeetMod'] = int(f.readline().split()[0]) - self.fst_vt['Fst7']['TeetDmpP'] = float_read(f.readline().split()[0]) - self.fst_vt['Fst7']['TeetDmp'] = float_read(f.readline().split()[0]) - self.fst_vt['Fst7']['TeetCDmp'] = float_read(f.readline().split()[0]) - self.fst_vt['Fst7']['TeetSStP'] = float_read(f.readline().split()[0]) - self.fst_vt['Fst7']['TeetHStP'] = float_read(f.readline().split()[0]) - self.fst_vt['Fst7']['TeetSSSp'] = float_read(f.readline().split()[0]) - self.fst_vt['Fst7']['TeetHSSp'] = float_read(f.readline().split()[0]) - f.readline() - self.fst_vt['Fst7']['TBDrConN'] = float_read(f.readline().split()[0]) - self.fst_vt['Fst7']['TBDrConD'] = float_read(f.readline().split()[0]) - self.fst_vt['Fst7']['TpBrDT'] = float_read(f.readline().split()[0]) - f.readline() - self.fst_vt['Fst7']['BldFile1'] = f.readline().split()[0][1:-1] # TODO - different blade files - self.fst_vt['Fst7']['BldFile2'] = f.readline().split()[0][1:-1] - self.fst_vt['Fst7']['BldFile3'] = f.readline().split()[0][1:-1] - f.readline() - self.fst_vt['Fst7']['ADFile'] = f.readline().split()[0][1:-1] - f.readline() - self.fst_vt['Fst7']['NoiseFile'] = f.readline().split()[0] - f.readline() - self.fst_vt['Fst7']['ADAMSFile'] = f.readline().split()[0] - f.readline() - self.fst_vt['Fst7']['LinFile'] = f.readline().split()[0] - f.readline() - self.fst_vt['Fst7']['SumPrint'] = bool_read(f.readline().split()[0]) - self.fst_vt['Fst7']['OutFileFmt'] = int(f.readline().split()[0]) - self.fst_vt['Fst7']['TabDelim'] = bool_read(f.readline().split()[0]) - - self.fst_vt['Fst7']['OutFmt'] = f.readline().split()[0] - self.fst_vt['Fst7']['TStart'] = float_read(f.readline().split()[0]) - self.fst_vt['Fst7']['DecFact'] = int(f.readline().split()[0]) - self.fst_vt['Fst7']['SttsTime'] = float_read(f.readline().split()[0]) - self.fst_vt['Fst7']['NcIMUxn'] = float_read(f.readline().split()[0]) - self.fst_vt['Fst7']['NcIMUyn'] = float_read(f.readline().split()[0]) - self.fst_vt['Fst7']['NcIMUzn'] = float_read(f.readline().split()[0]) - self.fst_vt['Fst7']['ShftGagL'] = float_read(f.readline().split()[0]) - self.fst_vt['Fst7']['NTwGages'] = int(f.readline().split()[0]) - twrg = f.readline().split(',') - if self.fst_vt['Fst7']['NTwGages'] != 0: #loop over elements if there are gauges to be added, otherwise assign directly - for i in range(self.fst_vt['Fst7']['NTwGages']): - self.fst_vt['Fst7']['TwrGagNd'].append(twrg[i]) - self.fst_vt['Fst7']['TwrGagNd'][-1] = self.fst_vt['Fst7']['TwrGagNd'][-1][0:2] - else: - self.fst_vt['Fst7']['TwrGagNd'] = twrg - self.fst_vt['Fst7']['TwrGagNd'][-1] = self.fst_vt['Fst7']['TwrGagNd'][-1][0:4] - self.fst_vt['Fst7']['NBlGages'] = int(f.readline().split()[0]) - blg = f.readline().split(',') - if self.fst_vt['Fst7']['NBlGages'] != 0: - for i in range(self.fst_vt['Fst7']['NBlGages']): - self.fst_vt['Fst7']['BldGagNd'].append(blg[i]) - self.fst_vt['Fst7']['BldGagNd'][-1] = self.fst_vt['Fst7']['BldGagNd'][-1][0:2] - else: - self.fst_vt['Fst7']['BldGagNd'] = blg - self.fst_vt['Fst7']['BldGagNd'][-1] = self.fst_vt['Fst7']['BldGagNd'][-1][0:4] - - # Outlist (TODO - detailed categorization) - f.readline() - data = f.readline() - while data.split()[0] != 'END': - channels = data.split('"') - channel_list = channels[1].split(',') - self.set_outlist(self.fst_vt['outlist7'], channel_list) - data = f.readline() - - def read_AeroDyn_FAST7(self): - - ad_file = os.path.join(self.FAST_directory, self.fst_vt['Fst7']['ADFile']) - f = open(ad_file) - - # skip lines and check if nondimensional - f.readline() - self.fst_vt['AeroDyn14']['SysUnits'] = f.readline().split()[0] - 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']['WindFile'] = os.path.normpath(os.path.join(os.path.split(ad_file)[0], f.readline().split()[0][1:-1])) - self.fst_vt['AeroDyn14']['wind_file_type'] = self.fst_vt['AeroDyn14']['WindFile'].split('.') - self.fst_vt['AeroDyn14']['HH'] = float_read(f.readline().split()[0]) - self.fst_vt['AeroDyn14']['TwrShad'] = float_read(f.readline().split()[0]) - 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]) - - 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]))) - + 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']) + 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) + self.read_InflowWind() + # AeroDyn version selection + if self.fst_vt['Fst']['CompAero'] == 1: + self.read_AeroDyn14() + elif self.fst_vt['Fst']['CompAero'] == 2: + self.read_AeroDyn15() + + if self.fst_vt['Fst']['CompServo'] == 1: + self.read_ServoDyn() + # Would read StCs here + if ROSCO: + self.read_DISCON_in() + 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) + 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']['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): + self.read_MAP(map_file) + if self.fst_vt['Fst']['CompMooring'] == 3: # MoorDyn implimented + moordyn_file = os.path.normpath(os.path.join(self.FAST_directory, self.fst_vt['Fst']['MooringFile'])) + if os.path.isfile(moordyn_file): + self.read_MoorDyn(moordyn_file) + bd_file = os.path.normpath(os.path.join(self.FAST_directory, self.fst_vt['Fst']['BDBldFile(1)'])) + if os.path.isfile(bd_file): + self.read_BeamDyn(bd_file) if __name__=="__main__": - FAST_ver = 'OpenFAST' - read_yaml = False - - if read_yaml: - fast = InputReader_Common(FAST_ver=FAST_ver) - fast.FAST_yamlfile = 'temp/OpenFAST/test.yaml' - fast.read_yaml() - - else: - if FAST_ver.lower() == 'fast7': - fast = InputReader_FAST7(FAST_ver=FAST_ver) - fast.FAST_InputFile = 'Test16.fst' # FAST input file (ext=.fst) - fast.FAST_directory = 'C:/Users/egaertne/WT_Codes/models/FAST_v7.02.00d-bjj/CertTest/' # Path to fst directory files - - elif FAST_ver.lower() == 'fast8': - fast = InputReader_OpenFAST(FAST_ver=FAST_ver) - fast.FAST_InputFile = 'NREL5MW_onshore.fst' # FAST input file (ext=.fst) - fast.FAST_directory = 'C:/Users/egaertne/WT_Codes/models/FAST_v8.16.00a-bjj/ref/5mw_onshore/' # Path to fst directory files - - elif FAST_ver.lower() == 'openfast': - fast = InputReader_OpenFAST(FAST_ver=FAST_ver) - fast.FAST_InputFile = '5MW_OC3Spar_DLL_WTurb_WavesIrr.fst' # FAST input file (ext=.fst) - fast.FAST_directory = 'C:/Users/egaertne/WT_Codes/models/openfast-dev/r-test/glue-codes/openfast/5MW_OC3Spar_DLL_WTurb_WavesIrr' # Path to fst directory files - - fast.execute() + examples_dir = os.path.dirname( os.path.dirname( os.path.dirname( os.path.realpath(__file__) ) ) ) + os.sep + + 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() diff --git a/ROSCO/ROSCO_toolbox/ofTools/fast_io/FAST_vars_out.py b/ROSCO/ROSCO_toolbox/ofTools/fast_io/FAST_vars_out.py index 61ef8dcc1..358af810d 100644 --- a/ROSCO/ROSCO_toolbox/ofTools/fast_io/FAST_vars_out.py +++ b/ROSCO/ROSCO_toolbox/ofTools/fast_io/FAST_vars_out.py @@ -2543,17 +2543,17 @@ 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 load (force in x direction); the hub coordinate system -AeroDyn['RtAeroFyh'] = False # (N); Total rotor aerodynamic load (force in y direction); the hub coordinate system -AeroDyn['RtAeroFzh'] = False # (N); Total rotor aerodynamic load (force in z direction); the hub coordinate system -AeroDyn['RtAeroMxh'] = False # (N m); Total rotor aerodynamic load (moment in x direction); the hub coordinate system -AeroDyn['RtAeroMyh'] = False # (N m); Total rotor aerodynamic load (moment in y direction); the hub coordinate system -AeroDyn['RtAeroMzh'] = False # (N m); Total rotor aerodynamic load (moment in z direction); the hub coordinate system -AeroDyn['RtAeroPwr'] = False # (W); Rotor aerodynamic power; +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['RtAeroCp'] = False # (-); Rotor aerodynamic power coefficient; -AeroDyn['RtAeroCq'] = False # (-); Rotor aerodynamic torque coefficient; -AeroDyn['RtAeroCt'] = False # (-); Rotor aerodynamic thrust coefficient; +AeroDyn['RtFldCp'] = False # (-); Rotor aerodynamic power coefficient; +AeroDyn['RtFldCq'] = False # (-); Rotor aerodynamic torque coefficient; +AeroDyn['RtFldCt'] = False # (-); Rotor aerodynamic thrust coefficient; """ InflowWind """ diff --git a/ROSCO/ROSCO_toolbox/ofTools/fast_io/FAST_wrapper.py b/ROSCO/ROSCO_toolbox/ofTools/fast_io/FAST_wrapper.py index 66e73ff69..cc8780f58 100644 --- a/ROSCO/ROSCO_toolbox/ofTools/fast_io/FAST_wrapper.py +++ b/ROSCO/ROSCO_toolbox/ofTools/fast_io/FAST_wrapper.py @@ -54,7 +54,7 @@ def execute(self): print('OpenFAST Failed: {}'.format(e)) failed = True run_idx = 2 - except: + except Exception as e: print('OpenFAST Failed: {}'.format(e)) failed = True run_idx = 2 diff --git a/ROSCO/ROSCO_toolbox/ofTools/fast_io/FAST_writer.py b/ROSCO/ROSCO_toolbox/ofTools/fast_io/FAST_writer.py index c3f45edf1..852b3594d 100644 --- a/ROSCO/ROSCO_toolbox/ofTools/fast_io/FAST_writer.py +++ b/ROSCO/ROSCO_toolbox/ofTools/fast_io/FAST_writer.py @@ -4,7 +4,7 @@ import numpy as np from functools import reduce -from ROSCO_toolbox.ofTools.fast_io.FAST_reader import InputReader_Common, InputReader_OpenFAST, InputReader_FAST7 +from ROSCO_toolbox.ofTools.fast_io.FAST_reader import InputReader_OpenFAST from ROSCO_toolbox.ofTools.fast_io.FAST_vars import FstModel from ROSCO_toolbox.utilities import write_rotor_performance, write_DISCON @@ -38,32 +38,16 @@ def int_default_out(val): def get_dict(vartree, branch): return reduce(operator.getitem, branch, vartree) -class InputWriter_Common(object): - """ Methods for writing input files that are (relatively) unchanged across FAST versions.""" +class InputWriter_OpenFAST(object): + """ Methods to write OpenFAST input files.""" - def __init__(self, **kwargs): + def __init__(self): - self.FAST_ver = 'OPENFAST' self.FAST_namingOut = None #Master FAST file self.FAST_runDirectory = None #Output directory - self.fst_vt = FstModel + self.fst_vt = {} self.fst_update = {} - # Optional population class attributes from key word arguments - for (k, w) in kwargs.items(): - try: - setattr(self, k, w) - except: - pass - - super(InputWriter_Common, self).__init__() - - def write_yaml(self): - self.FAST_yamlfile = os.path.join(self.FAST_runDirectory, self.FAST_namingOut+'.yaml') - f = open(self.FAST_yamlfile, "w") - yaml.dump(self.fst_vt, f) - - def update(self, fst_update={}): """ Change fast variables based on the user supplied values """ if fst_update: @@ -102,160 +86,6 @@ def loop_dict(vartree, branch): # set fast variables to update values loop_dict(self.fst_update, []) - - 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']['BldFile3'] = self.fst_vt['ElastoDyn']['BldFile1'] - 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('Generated with AeroElasticSE FAST driver\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('---------------------- 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']['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')) - f.write('---------------------- DISTRIBUTED BLADE PROPERTIES ----------------------------\n') - f.write(' BlFract PitchAxis StrcTwst BMassDen FlpStff EdgStff\n') - f.write(' (-) (-) (deg) (kg/m) (Nm^2) (Nm^2)\n') - BlFract = self.fst_vt['ElastoDynBlade']['BlFract'] - PitchAxis = self.fst_vt['ElastoDynBlade']['PitchAxis'] - StrcTwst = self.fst_vt['ElastoDynBlade']['StrcTwst'] - BMassDen = self.fst_vt['ElastoDynBlade']['BMassDen'] - FlpStff = self.fst_vt['ElastoDynBlade']['FlpStff'] - EdgStff = self.fst_vt['ElastoDynBlade']['EdgStff'] - for BlFracti, PitchAxisi, StrcTwsti, BMassDeni, FlpStffi, EdgStffi in zip(BlFract, PitchAxis, StrcTwst, BMassDen, FlpStff, EdgStff): - f.write('{: 2.15e} {: 2.15e} {: 2.15e} {: 2.15e} {: 2.15e} {: 2.15e}\n'.format(BlFracti, PitchAxisi, StrcTwsti, BMassDeni, FlpStffi, EdgStffi)) - f.write('---------------------- BLADE MODE SHAPES ---------------------------------------\n') - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynBlade']['BldFl1Sh'][0], 'BldFl1Sh(2)', '- Flap mode 1, coeff of x^2\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynBlade']['BldFl1Sh'][1], 'BldFl1Sh(3)', '- , coeff of x^3\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynBlade']['BldFl1Sh'][2], 'BldFl1Sh(4)', '- , coeff of x^4\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynBlade']['BldFl1Sh'][3], 'BldFl1Sh(5)', '- , coeff of x^5\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynBlade']['BldFl1Sh'][4], 'BldFl1Sh(6)', '- , coeff of x^6\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynBlade']['BldFl2Sh'][0], 'BldFl2Sh(2)', '- Flap mode 2, coeff of x^2\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynBlade']['BldFl2Sh'][1], 'BldFl2Sh(3)', '- , coeff of x^3\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynBlade']['BldFl2Sh'][2], 'BldFl2Sh(4)', '- , coeff of x^4\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynBlade']['BldFl2Sh'][3], 'BldFl2Sh(5)', '- , coeff of x^5\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynBlade']['BldFl2Sh'][4], 'BldFl2Sh(6)', '- , coeff of x^6\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynBlade']['BldEdgSh'][0], 'BldEdgSh(2)', '- Edge mode 1, coeff of x^2\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynBlade']['BldEdgSh'][1], 'BldEdgSh(3)', '- , coeff of x^3\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynBlade']['BldEdgSh'][2], 'BldEdgSh(4)', '- , coeff of x^4\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynBlade']['BldEdgSh'][3], 'BldEdgSh(5)', '- , coeff of x^5\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynBlade']['BldEdgSh'][4], 'BldEdgSh(6)', '- , coeff of x^6\n')) - - f.close() - - - def write_ElastoDynTower(self): - - self.fst_vt['ElastoDyn']['TwrFile'] = self.FAST_namingOut + '_ElastoDyn_tower.dat' - 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('Generated with AeroElasticSE FAST driver\n') - f.write('---------------------- TOWER PARAMETERS ----------------------------------------\n') - if self.FAST_ver.lower() == 'fast7': - f.write('---\n') - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynTower']['NTwInpSt'], 'NTwInpSt', '- Number of input stations to specify tower geometry\n')) - if self.FAST_ver.lower() == 'fast7': - f.write('{:}\n'.format(self.fst_vt['ElastoDynTower']['CalcTMode'])) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynTower']['TwrFADmp1'], 'TwrFADmp(1)', '- Tower 1st fore-aft mode structural damping ratio (%)\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynTower']['TwrFADmp2'], 'TwrFADmp(2)', '- Tower 2nd fore-aft mode structural damping ratio (%)\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynTower']['TwrSSDmp1'], 'TwrSSDmp(1)', '- Tower 1st side-to-side mode structural damping ratio (%)\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynTower']['TwrSSDmp2'], 'TwrSSDmp(2)', '- Tower 2nd side-to-side mode structural damping ratio (%)\n')) - f.write('---------------------- TOWER ADJUSTMUNT FACTORS --------------------------------\n') - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynTower']['FAStTunr1'], 'FAStTunr(1)', '- Tower fore-aft modal stiffness tuner, 1st mode (-)\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynTower']['FAStTunr2'], 'FAStTunr(2)', '- Tower fore-aft modal stiffness tuner, 2nd mode (-)\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynTower']['SSStTunr1'], 'SSStTunr(1)', '- Tower side-to-side stiffness tuner, 1st mode (-)\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynTower']['SSStTunr2'], 'SSStTunr(2)', '- Tower side-to-side stiffness tuner, 2nd mode (-)\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynTower']['AdjTwMa'], 'AdjTwMa', '- Factor to adjust tower mass density (-)\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynTower']['AdjFASt'], 'AdjFASt', '- Factor to adjust tower fore-aft stiffness (-)\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynTower']['AdjSSSt'], 'AdjSSSt', '- Factor to adjust tower side-to-side stiffness (-)\n')) - f.write('---------------------- DISTRIBUTED TOWER PROPERTIES ----------------------------\n') - f.write(' HtFract TMassDen TwFAStif TwSSStif\n') - f.write(' (-) (kg/m) (Nm^2) (Nm^2)\n') - HtFract = self.fst_vt['ElastoDynTower']['HtFract'] - TMassDen = self.fst_vt['ElastoDynTower']['TMassDen'] - TwFAStif = self.fst_vt['ElastoDynTower']['TwFAStif'] - TwSSStif = self.fst_vt['ElastoDynTower']['TwSSStif'] - if self.FAST_ver.lower() == 'fast7': - gs = self.fst_vt['ElastoDynTower']['TwGJStif'] - es = self.fst_vt['ElastoDynTower']['TwEAStif'] - fi = self.fst_vt['ElastoDynTower']['TwFAIner'] - si = self.fst_vt['ElastoDynTower']['TwSSIner'] - fo = self.fst_vt['ElastoDynTower']['TwFAcgOf'] - so = self.fst_vt['ElastoDynTower']['TwSScgOf'] - for a1, a2, a3, a4, a5, a6, a7, a8, a9, a10 in zip(HtFract, TMassDen, TwFAStif, TwSSStif, gs, es, fi, si, fo, so): - f.write('{:.9e}\t{:.9e}\t{:.9e}\t{:.9e}\t{:.9e}\t{:.9e}\t{:.9e}\t{:.9e}\t{:.9e}\t{:.9e}\n'.\ - format(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10)) - else: - for HtFracti, TMassDeni, TwFAStifi, TwSSStifi in zip(HtFract, TMassDen, TwFAStif, TwSSStif): - f.write('{: 2.15e} {: 2.15e} {: 2.15e} {: 2.15e}\n'.format(HtFracti, TMassDeni, TwFAStifi, TwSSStifi)) - f.write('---------------------- TOWER FORE-AFT MODE SHAPES ------------------------------\n') - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynTower']['TwFAM1Sh'][0], 'TwFAM1Sh(2)', '- Mode 1, coefficient of x^2 term\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynTower']['TwFAM1Sh'][1], 'TwFAM1Sh(3)', '- , coefficient of x^3 term\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynTower']['TwFAM1Sh'][2], 'TwFAM1Sh(4)', '- , coefficient of x^4 term\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynTower']['TwFAM1Sh'][3], 'TwFAM1Sh(5)', '- , coefficient of x^5 term\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynTower']['TwFAM1Sh'][4], 'TwFAM1Sh(6)', '- , coefficient of x^6 term\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynTower']['TwFAM2Sh'][0], 'TwFAM2Sh(2)', '- Mode 2, coefficient of x^2 term\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynTower']['TwFAM2Sh'][1], 'TwFAM2Sh(3)', '- , coefficient of x^3 term\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynTower']['TwFAM2Sh'][2], 'TwFAM2Sh(4)', '- , coefficient of x^4 term\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynTower']['TwFAM2Sh'][3], 'TwFAM2Sh(5)', '- , coefficient of x^5 term\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynTower']['TwFAM2Sh'][4], 'TwFAM2Sh(6)', '- , coefficient of x^6 term\n')) - f.write('---------------------- TOWER SIDE-TO-SIDE MODE SHAPES --------------------------\n') - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynTower']['TwSSM1Sh'][0], 'TwSSM1Sh(2)', '- Mode 1, coefficient of x^2 term\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynTower']['TwSSM1Sh'][1], 'TwSSM1Sh(3)', '- , coefficient of x^3 term\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynTower']['TwSSM1Sh'][2], 'TwSSM1Sh(4)', '- , coefficient of x^4 term\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynTower']['TwSSM1Sh'][3], 'TwSSM1Sh(5)', '- , coefficient of x^5 term\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynTower']['TwSSM1Sh'][4], 'TwSSM1Sh(6)', '- , coefficient of x^6 term\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynTower']['TwSSM2Sh'][0], 'TwSSM2Sh(2)', '- Mode 2, coefficient of x^2 term\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynTower']['TwSSM2Sh'][1], 'TwSSM2Sh(3)', '- , coefficient of x^3 term\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynTower']['TwSSM2Sh'][2], 'TwSSM2Sh(4)', '- , coefficient of x^4 term\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynTower']['TwSSM2Sh'][3], 'TwSSM2Sh(5)', '- , coefficient of x^5 term\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynTower']['TwSSM2Sh'][4], 'TwSSM2Sh(6)', '- , coefficient of x^6 term\n')) - - 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 AeroElasticSE FAST driver\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.close() - def get_outlist(self, vartree_head, channel_list=[]): """ Loop through a list of output channel names, recursively find values set to True in the nested outlist dict """ @@ -312,9 +142,6 @@ def loop_dict(vartree, search_var, val, branch): var = var.replace(' ', '') loop_dict(self.fst_vt['outlist'], var, val, []) - -class InputWriter_OpenFAST(InputWriter_Common): - def execute(self): if not os.path.exists(self.FAST_runDirectory): @@ -330,9 +157,18 @@ def execute(self): elif self.fst_vt['Fst']['CompAero'] == 2: self.write_AeroDyn15() - if 'DISCON_in' in self.fst_vt and ROSCO: - self.write_DISCON_in() - self.write_ServoDyn() + if self.fst_vt['Fst']['CompServo'] == 1: + if 'DISCON_in' in self.fst_vt and ROSCO: + self.write_DISCON_in() + self.write_ServoDyn() + for i_NStC, NStC in enumerate(self.fst_vt['NStC']): + self.write_StC(NStC,self.fst_vt['ServoDyn']['NStCfiles'][i_NStC]) + for i_BStC, BStC in enumerate(self.fst_vt['BStC']): + self.write_StC(BStC,self.fst_vt['ServoDyn']['BStCfiles'][i_BStC]) + for i_TStC, TStC in enumerate(self.fst_vt['TStC']): + 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['Fst']['CompHydro'] == 1: self.write_HydroDyn() @@ -348,7 +184,6 @@ def execute(self): self.write_MainInput() - def write_MainInput(self): # Main FAST v8.16-v8.17 Input File # Currently no differences between FASTv8.16 and OpenFAST. @@ -434,7 +269,6 @@ def write_MainInput(self): f.close() - def write_ElastoDyn(self): self.fst_vt['Fst']['EDFile'] = self.FAST_namingOut + '_ElastoDyn.dat' @@ -560,9 +394,9 @@ 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(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'%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(0, 'TwrGagNd', '- List of tower nodes that have strain gages [1 to TwrNodes] (-) [unused if NTwGages=0]\n')) + 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')) @@ -580,6 +414,112 @@ def write_ElastoDyn(self): f.write('---------------------------------------------------------------------------------------\n') 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']['BldFile3'] = self.fst_vt['ElastoDyn']['BldFile1'] + 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('Generated with AeroElasticSE FAST driver\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('---------------------- 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']['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')) + f.write('---------------------- DISTRIBUTED BLADE PROPERTIES ----------------------------\n') + f.write(' BlFract PitchAxis StrcTwst BMassDen FlpStff EdgStff\n') + f.write(' (-) (-) (deg) (kg/m) (Nm^2) (Nm^2)\n') + BlFract = self.fst_vt['ElastoDynBlade']['BlFract'] + PitchAxis = self.fst_vt['ElastoDynBlade']['PitchAxis'] + StrcTwst = self.fst_vt['ElastoDynBlade']['StrcTwst'] + BMassDen = self.fst_vt['ElastoDynBlade']['BMassDen'] + FlpStff = self.fst_vt['ElastoDynBlade']['FlpStff'] + EdgStff = self.fst_vt['ElastoDynBlade']['EdgStff'] + for BlFracti, PitchAxisi, StrcTwsti, BMassDeni, FlpStffi, EdgStffi in zip(BlFract, PitchAxis, StrcTwst, BMassDen, FlpStff, EdgStff): + f.write('{: 2.15e} {: 2.15e} {: 2.15e} {: 2.15e} {: 2.15e} {: 2.15e}\n'.format(BlFracti, PitchAxisi, StrcTwsti, BMassDeni, FlpStffi, EdgStffi)) + f.write('---------------------- BLADE MODE SHAPES ---------------------------------------\n') + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynBlade']['BldFl1Sh'][0], 'BldFl1Sh(2)', '- Flap mode 1, coeff of x^2\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynBlade']['BldFl1Sh'][1], 'BldFl1Sh(3)', '- , coeff of x^3\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynBlade']['BldFl1Sh'][2], 'BldFl1Sh(4)', '- , coeff of x^4\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynBlade']['BldFl1Sh'][3], 'BldFl1Sh(5)', '- , coeff of x^5\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynBlade']['BldFl1Sh'][4], 'BldFl1Sh(6)', '- , coeff of x^6\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynBlade']['BldFl2Sh'][0], 'BldFl2Sh(2)', '- Flap mode 2, coeff of x^2\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynBlade']['BldFl2Sh'][1], 'BldFl2Sh(3)', '- , coeff of x^3\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynBlade']['BldFl2Sh'][2], 'BldFl2Sh(4)', '- , coeff of x^4\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynBlade']['BldFl2Sh'][3], 'BldFl2Sh(5)', '- , coeff of x^5\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynBlade']['BldFl2Sh'][4], 'BldFl2Sh(6)', '- , coeff of x^6\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynBlade']['BldEdgSh'][0], 'BldEdgSh(2)', '- Edge mode 1, coeff of x^2\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynBlade']['BldEdgSh'][1], 'BldEdgSh(3)', '- , coeff of x^3\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynBlade']['BldEdgSh'][2], 'BldEdgSh(4)', '- , coeff of x^4\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynBlade']['BldEdgSh'][3], 'BldEdgSh(5)', '- , coeff of x^5\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynBlade']['BldEdgSh'][4], 'BldEdgSh(6)', '- , coeff of x^6\n')) + + f.close() + + def write_ElastoDynTower(self): + + self.fst_vt['ElastoDyn']['TwrFile'] = self.FAST_namingOut + '_ElastoDyn_tower.dat' + 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('Generated with AeroElasticSE FAST driver\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')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynTower']['TwrFADmp1'], 'TwrFADmp(1)', '- Tower 1st fore-aft mode structural damping ratio (%)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynTower']['TwrFADmp2'], 'TwrFADmp(2)', '- Tower 2nd fore-aft mode structural damping ratio (%)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynTower']['TwrSSDmp1'], 'TwrSSDmp(1)', '- Tower 1st side-to-side mode structural damping ratio (%)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynTower']['TwrSSDmp2'], 'TwrSSDmp(2)', '- Tower 2nd side-to-side mode structural damping ratio (%)\n')) + f.write('---------------------- TOWER ADJUSTMUNT FACTORS --------------------------------\n') + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynTower']['FAStTunr1'], 'FAStTunr(1)', '- Tower fore-aft modal stiffness tuner, 1st mode (-)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynTower']['FAStTunr2'], 'FAStTunr(2)', '- Tower fore-aft modal stiffness tuner, 2nd mode (-)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynTower']['SSStTunr1'], 'SSStTunr(1)', '- Tower side-to-side stiffness tuner, 1st mode (-)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynTower']['SSStTunr2'], 'SSStTunr(2)', '- Tower side-to-side stiffness tuner, 2nd mode (-)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynTower']['AdjTwMa'], 'AdjTwMa', '- Factor to adjust tower mass density (-)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynTower']['AdjFASt'], 'AdjFASt', '- Factor to adjust tower fore-aft stiffness (-)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynTower']['AdjSSSt'], 'AdjSSSt', '- Factor to adjust tower side-to-side stiffness (-)\n')) + f.write('---------------------- DISTRIBUTED TOWER PROPERTIES ----------------------------\n') + f.write(' HtFract TMassDen TwFAStif TwSSStif\n') + f.write(' (-) (kg/m) (Nm^2) (Nm^2)\n') + HtFract = self.fst_vt['ElastoDynTower']['HtFract'] + TMassDen = self.fst_vt['ElastoDynTower']['TMassDen'] + TwFAStif = self.fst_vt['ElastoDynTower']['TwFAStif'] + TwSSStif = self.fst_vt['ElastoDynTower']['TwSSStif'] + for HtFracti, TMassDeni, TwFAStifi, TwSSStifi in zip(HtFract, TMassDen, TwFAStif, TwSSStif): + f.write('{: 2.15e} {: 2.15e} {: 2.15e} {: 2.15e}\n'.format(HtFracti, TMassDeni, TwFAStifi, TwSSStifi)) + f.write('---------------------- TOWER FORE-AFT MODE SHAPES ------------------------------\n') + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynTower']['TwFAM1Sh'][0], 'TwFAM1Sh(2)', '- Mode 1, coefficient of x^2 term\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynTower']['TwFAM1Sh'][1], 'TwFAM1Sh(3)', '- , coefficient of x^3 term\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynTower']['TwFAM1Sh'][2], 'TwFAM1Sh(4)', '- , coefficient of x^4 term\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynTower']['TwFAM1Sh'][3], 'TwFAM1Sh(5)', '- , coefficient of x^5 term\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynTower']['TwFAM1Sh'][4], 'TwFAM1Sh(6)', '- , coefficient of x^6 term\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynTower']['TwFAM2Sh'][0], 'TwFAM2Sh(2)', '- Mode 2, coefficient of x^2 term\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynTower']['TwFAM2Sh'][1], 'TwFAM2Sh(3)', '- , coefficient of x^3 term\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynTower']['TwFAM2Sh'][2], 'TwFAM2Sh(4)', '- , coefficient of x^4 term\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynTower']['TwFAM2Sh'][3], 'TwFAM2Sh(5)', '- , coefficient of x^5 term\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynTower']['TwFAM2Sh'][4], 'TwFAM2Sh(6)', '- , coefficient of x^6 term\n')) + f.write('---------------------- TOWER SIDE-TO-SIDE MODE SHAPES --------------------------\n') + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynTower']['TwSSM1Sh'][0], 'TwSSM1Sh(2)', '- Mode 1, coefficient of x^2 term\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynTower']['TwSSM1Sh'][1], 'TwSSM1Sh(3)', '- , coefficient of x^3 term\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynTower']['TwSSM1Sh'][2], 'TwSSM1Sh(4)', '- , coefficient of x^4 term\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynTower']['TwSSM1Sh'][3], 'TwSSM1Sh(5)', '- , coefficient of x^5 term\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynTower']['TwSSM1Sh'][4], 'TwSSM1Sh(6)', '- , coefficient of x^6 term\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynTower']['TwSSM2Sh'][0], 'TwSSM2Sh(2)', '- Mode 2, coefficient of x^2 term\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynTower']['TwSSM2Sh'][1], 'TwSSM2Sh(3)', '- , coefficient of x^3 term\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynTower']['TwSSM2Sh'][2], 'TwSSM2Sh(4)', '- , coefficient of x^4 term\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynTower']['TwSSM2Sh'][3], 'TwSSM2Sh(5)', '- , coefficient of x^5 term\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDynTower']['TwSSM2Sh'][4], 'TwSSM2Sh(6)', '- , coefficient of x^6 term\n')) + + f.close() def write_BeamDyn(self): self.fst_vt['Fst']['BDBldFile(1)'] = self.FAST_namingOut + '_BeamDyn.dat' @@ -660,8 +600,8 @@ def write_BeamDyn(self): def write_BeamDynBlade(self): # bd_blade_file = self.fst_vt['BeamDyn']['BldFile'] - bd_blade_file = os.path.abspath(os.path.join(self.FAST_runDirectory, self.FAST_namingOut + '_BeamDyn_Blade.dat')) - self.fst_vt['BeamDyn']['BldFile'] = bd_blade_file + self.fst_vt['BeamDyn']['BldFile'] = self.FAST_namingOut + '_BeamDyn_Blade.dat' + 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') @@ -687,7 +627,6 @@ def write_BeamDynBlade(self): f.write('\n') - def write_InflowWind(self): self.fst_vt['Fst']['InflowFile'] = self.FAST_namingOut + '_InflowFile.dat' inflow_file = os.path.join(self.FAST_runDirectory,self.fst_vt['Fst']['InflowFile']) @@ -719,152 +658,43 @@ def write_InflowWind(self): f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['InflowWind']['TowerFile'], 'TowerFile', '- Have tower file (.twr) (flag)\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')) - f.write('{:<22} {:<11} {:}'.format('"'+self.fst_vt['InflowWind']['FileName_w']+'"', 'FileName_w', '- name of the file containing the w-component fluctuating wind (.bin)\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['InflowWind']['nx'], 'nx', '- number of grids in the x direction (in the 3 files above) (-)\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['InflowWind']['ny'], 'ny', '- number of grids in the y direction (in the 3 files above) (-)\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['InflowWind']['nz'], 'nz', '- number of grids in the z direction (in the 3 files above) (-)\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['InflowWind']['dx'], 'dx', '- distance (in meters) between points in the x direction (m)\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['InflowWind']['dy'], 'dy', '- distance (in meters) between points in the y direction (m)\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['InflowWind']['dz'], 'dz', '- distance (in meters) between points in the z direction (m)\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['InflowWind']['RefHt_Hawc'], 'RefHt_Hawc', '- reference height; the height (in meters) of the vertical center of the grid (m)\n')) - f.write('------------- Scaling parameters for turbulence ---------------------------------------------------------\n') - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['InflowWind']['ScaleMethod'], 'ScaleMethod', '- Turbulence scaling method [0 = none, 1 = direct scaling, 2 = calculate scaling factor based on a desired standard deviation]\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['InflowWind']['SFx'], 'SFx', '- Turbulence scaling factor for the x direction (-) [ScaleMethod=1]\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['InflowWind']['SFy'], 'SFy', '- Turbulence scaling factor for the y direction (-) [ScaleMethod=1]\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['InflowWind']['SFz'], 'SFz', '- Turbulence scaling factor for the z direction (-) [ScaleMethod=1]\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['InflowWind']['SigmaFx'], 'SigmaFx', '- Turbulence standard deviation to calculate scaling from in x direction (m/s) [ScaleMethod=2]\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['InflowWind']['SigmaFy'], 'SigmaFy', '- Turbulence standard deviation to calculate scaling from in y direction (m/s) [ScaleMethod=2]\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['InflowWind']['SigmaFz'], 'SigmaFz', '- Turbulence standard deviation to calculate scaling from in z direction (m/s) [ScaleMethod=2]\n')) - f.write('------------- Mean wind profile parameters (added to HAWC-format files) ---------------------------------\n') - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['InflowWind']['URef'], 'URef', '- Mean u-component wind speed at the reference height (m/s)\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['InflowWind']['WindProfile'], 'WindProfile', '- Wind profile type (0=constant;1=logarithmic,2=power law)\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['InflowWind']['PLExp_Hawc'], 'PLExp_Hawc', '- Power law exponent (-) (used for PL wind profile type only)\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['InflowWind']['Z0'], 'Z0', '- Surface roughness length (m) (used for LG wind profile type only)\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['InflowWind']['XOffset'], 'XOffset', '- Initial offset in +x direction (shift of wind box) (-)\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') - - outlist = self.get_outlist(self.fst_vt['outlist'], ['InflowWind']) - 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.close() - - # def WndWindWriter(self, wndfile): - - # wind_file = os.path.join(self.FAST_runDirectory,wndfile) - # f = open(wind_file, 'w') - - # for i in range(self.fst_vt['wnd_wind']['TimeSteps']): - # f.write('{: 2.15e}\t{: 2.15e}\t{: 2.15e}\t{: 2.15e}\t{: 2.15e}\t{: 2.15e}\t{: 2.15e}\t{: 2.15e}\n'.format(\ - # self.fst_vt['wnd_wind']['Time'][i], self.fst_vt['wnd_wind']['HorSpd'][i], self.fst_vt['wnd_wind']['WindDir'][i],\ - # self.fst_vt['wnd_wind']['VerSpd'][i], self.fst_vt['wnd_wind']['HorShr'][i],\ - # self.fst_vt['wnd_wind']['VerShr'][i], self.fst_vt['wnd_wind']['LnVShr'][i], self.fst_vt['wnd_wind']['GstSpd'][i])) - - # 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 - 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'])) - - 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'])) - - 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('{:<22} {:<11} {:}'.format('"'+self.fst_vt['InflowWind']['FileName_v']+'"', 'FileName_v', '- name of the file containing the v-component fluctuating wind (.bin)\n')) + f.write('{:<22} {:<11} {:}'.format('"'+self.fst_vt['InflowWind']['FileName_w']+'"', 'FileName_w', '- name of the file containing the w-component fluctuating wind (.bin)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['InflowWind']['nx'], 'nx', '- number of grids in the x direction (in the 3 files above) (-)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['InflowWind']['ny'], 'ny', '- number of grids in the y direction (in the 3 files above) (-)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['InflowWind']['nz'], 'nz', '- number of grids in the z direction (in the 3 files above) (-)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['InflowWind']['dx'], 'dx', '- distance (in meters) between points in the x direction (m)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['InflowWind']['dy'], 'dy', '- distance (in meters) between points in the y direction (m)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['InflowWind']['dz'], 'dz', '- distance (in meters) between points in the z direction (m)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['InflowWind']['RefHt_Hawc'], 'RefHt_Hawc', '- reference height; the height (in meters) of the vertical center of the grid (m)\n')) + f.write('------------- Scaling parameters for turbulence ---------------------------------------------------------\n') + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['InflowWind']['ScaleMethod'], 'ScaleMethod', '- Turbulence scaling method [0 = none, 1 = direct scaling, 2 = calculate scaling factor based on a desired standard deviation]\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['InflowWind']['SFx'], 'SFx', '- Turbulence scaling factor for the x direction (-) [ScaleMethod=1]\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['InflowWind']['SFy'], 'SFy', '- Turbulence scaling factor for the y direction (-) [ScaleMethod=1]\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['InflowWind']['SFz'], 'SFz', '- Turbulence scaling factor for the z direction (-) [ScaleMethod=1]\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['InflowWind']['SigmaFx'], 'SigmaFx', '- Turbulence standard deviation to calculate scaling from in x direction (m/s) [ScaleMethod=2]\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['InflowWind']['SigmaFy'], 'SigmaFy', '- Turbulence standard deviation to calculate scaling from in y direction (m/s) [ScaleMethod=2]\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['InflowWind']['SigmaFz'], 'SigmaFz', '- Turbulence standard deviation to calculate scaling from in z direction (m/s) [ScaleMethod=2]\n')) + f.write('------------- Mean wind profile parameters (added to HAWC-format files) ---------------------------------\n') + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['InflowWind']['URef'], 'URef', '- Mean u-component wind speed at the reference height (m/s)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['InflowWind']['WindProfile'], 'WindProfile', '- Wind profile type (0=constant;1=logarithmic,2=power law)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['InflowWind']['PLExp_Hawc'], 'PLExp_Hawc', '- Power law exponent (-) (used for PL wind profile type only)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['InflowWind']['Z0'], 'Z0', '- Surface roughness length (m) (used for LG wind profile type only)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['InflowWind']['XOffset'], 'XOffset', '- Initial offset in +x direction (shift of wind box) (-)\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') + outlist = self.get_outlist(self.fst_vt['outlist'], ['InflowWind']) + for channel_list in outlist: + for i in range(len(channel_list)): + f.write('"' + channel_list[i] + '"\n') - f.write('{:2}\n'.format(self.fst_vt['AeroDynBlade']['NumFoil'])) - for i in range (self.fst_vt['AeroDynBlade']['NumFoil']): - f.write('"{:}"\n'.format(self.fst_vt['AeroDynBlade']['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.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('END of input file (the word "END" must appear in the first 3 columns of this last OutList line)\n') + f.write('---------------------------------------------------------------------------------------\n') - f.write('AeroDyn tower file, Aerodyn v14.04 formatting\n') - f.write('Generated with AeroElasticSE FAST driver\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.close() - + def write_AeroDyn15(self): # AeroDyn v15.03 @@ -879,6 +709,8 @@ def write_AeroDyn15(self): 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') self.write_OLAF() # Generate AeroDyn v15.03 input file @@ -898,6 +730,7 @@ def write_AeroDyn15(self): 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')) 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') @@ -906,7 +739,7 @@ def write_AeroDyn15(self): 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']['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 ====================================================== [used only when WakeMod=1]\n') + f.write('====== Blade-Element/Momentum Theory Options ====================================================== [unused when WakeMod=0 or 3]\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']['TipLoss'], 'TipLoss', '- Use the Prandtl tip-loss model? (flag) [unused when WakeMod=0 or 3]\n')) @@ -916,8 +749,8 @@ 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('====== Dynamic Blade-Element/Momentum Theory Options ====================================================== [used only when WakeMod=1]\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} (-) [used only when WakeMod=2]\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') olaf_file = self.FAST_namingOut + '_OLAF.dat' @@ -925,8 +758,6 @@ def write_AeroDyn15(self): f.write('====== Beddoes-Leishman Unsteady Airfoil Aerodynamics Options ===================================== [used only when AFAeroMod=2]\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('{!s:<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('{!s:<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')) @@ -945,12 +776,21 @@ def write_AeroDyn15(self): 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('====== Tower Influence and Aerodynamics ============================================================= [used only when TwrPotent/=0, TwrShadow/=0, or TwrAero=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, or TwrAero=True]\n')) - f.write('TwrElev TwrDiam TwrCd TwrTI (used only with TwrShadow=2)\n') - f.write('(m) (m) (-) (-)\n') - for TwrElev, TwrDiam, TwrCd, TwrTI in zip(self.fst_vt['AeroDyn15']['TwrElev'], self.fst_vt['AeroDyn15']['TwrDiam'], self.fst_vt['AeroDyn15']['TwrCd'], self.fst_vt['AeroDyn15']['TwrTI']): - f.write('{: 2.15e} {: 2.15e} {: 2.15e} {: 2.15e} \n'.format(TwrElev, TwrDiam, TwrCd, TwrTI)) + 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('{:<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('====== 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('====== 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('(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)) 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')) @@ -1027,7 +867,7 @@ def write_AeroDyn15Polar(self): 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'][1][0]['NumCoords'] != '0': + if self.fst_vt['AeroDyn15']['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')) @@ -1041,8 +881,8 @@ def write_AeroDyn15Polar(self): 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 and \ - self.fst_vt['AeroDyn15']['af_data'][afi][0]['Ctrl'] == self.fst_vt['AeroDyn15']['af_data'][afi][1]['Ctrl']: + 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']: 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'] @@ -1166,57 +1006,187 @@ def write_AeroDyn15Coord(self): f.write(' '.join(['{: 2.14e}'.format(val) for val in row])+'\n') 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.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 AeroElasticSE FAST driver\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.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 AeroElasticSE FAST driver\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.close() + def write_OLAF(self): olaf_file = os.path.join(self.FAST_runDirectory, self.FAST_namingOut + '_OLAF.dat') f = open(olaf_file, 'w') f.write('--------------------------- OLAF (cOnvecting LAgrangian Filaments) INPUT FILE -----------------\n') - f.write('Free wake input file for the Helix test case\n') + f.write('Generated by WEIS\n') f.write('--------------------------- GENERAL OPTIONS ---------------------------------------------------\n') - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['OLAF']['IntMethod'], 'IntMethod', 'Integration method {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['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('--------------------------- CIRCULATION SPECIFICATIONS ----------------------------------------\n') - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['OLAF']['CircSolvingMethod'], '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 CircSolvingMethod=1] (-)\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['OLAF']['CircSolvRelaxation'], 'CircSolvRelaxation', 'Relaxation factor {default: 0.1} [only if CircSolvingMethod=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 CircSolvingMethod=3] (quoted string)\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('===============================================================================================\n') f.write('--------------------------- WAKE OPTIONS ------------------------------------------------------\n') f.write('------------------- WAKE EXTENT AND DISCRETIZATION --------------------------------------------\n') - f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['OLAF']['nNWPanel'], 'nNWPanel','Number of near-wake panels [integer] (-)\n')) - f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['OLAF']['WakeLength'], 'WakeLength','Total wake distance [integer] (number of time steps)\n')) - f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['OLAF']['FreeWakeLength'], 'FreeWakeLength','Wake length that is free [integer] (number of time steps) {default: WakeLength}\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['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('{:<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('{!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('{:<22d} {:<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('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['OLAF']['RegDeterMethod'], 'RegDeterMethod','Method to determine the regularization parameters {0: Manual, 1: Optimized, default: 0 }\n')) - f.write('{:<22d} {:<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('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['OLAF']['WakeRegMethod'], 'WakeRegMethod','Wake regularization method {1: Constant, 2: Stretching, 3: Age, default: 1} (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('{:<22d} {:<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('{:<22d} {:<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('{:<22d} {:<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('{:<22d} {:<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('------------------- 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('{:<22d} {:<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['AeroDyn15']['OLAF']['TwrShadowOnWake'], 'TwrShadowOnWake','- Include tower flow disturbance effects on wake convection {default:false} [only if TwrPotent or TwrShadow]\n')) + f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['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:Biot-Savart Segment, 2:Particle tree, default: 1}\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['OLAF']['TreeBranchFactor'], 'TreeBranchFactor','Branch radius fraction above which a multipole calculation is used {default: 2.0} [only if VelocityMethod=2]\n')) - f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['OLAF']['PartPerSegment'], 'PartPerSegment','Number of particles per segment [only if VelocityMethod=2]\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('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['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('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['OLAF']['WrVTk'], 'WrVTk','Outputs Visualization Toolkit (VTK) (independent of .fst option) {0: NoVTK, 1: Write VTK at each time step} (flag)\n')) - f.write('{:<22d} {:<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} (-)\n')) - f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['OLAF']['VTKCoord'], 'VTKCoord','Coordinate system used for VTK export. {1: Global, 2: Hub, "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} [used only if WrVTK=1]\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['OLAF']['nGridOut'], 'nGridOut','GB DEBUG 7/8: Number of grid points for VTK output\n')) - f.write('--GridOutHeaders--\n') - f.write('--GridOutUnits--\n') - f.write('1.0 1.0 1.0\n') - f.write('------------------------------------------------------------------------------------------------\n') + f.write('{:<22d} {:<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('{:<22d} {:<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('{:<22d} {:<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('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') + f.write('--------------------------- ADVANCED OPTIONS --------------------------------------------------\n') + f.write('===============================================================================================\n') f.close() @@ -1293,13 +1263,13 @@ def write_ServoDyn(self): 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 file for blade tuned mass damper (quoted string) [unused when CompNTMD is false]\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 file for nacelle tuned mass damper (quoted string) [unused when CompNTMD is false]\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('{!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']['SStCfiles']) + '"', 'SStCfiles', '- Name of the file for sbustructure tuned mass damper (quoted string) [unused when CompNTMD is false]\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') @@ -1368,8 +1338,8 @@ def write_DISCON_in(self): turbine.Cq_table = self.fst_vt['DISCON_in']['Cq_table'] turbine.pitch_initial_rad = self.fst_vt['DISCON_in']['Cp_pitch_initial_rad'] turbine.TSR_initial = self.fst_vt['DISCON_in']['Cp_TSR_initial'] - turbine.TurbineName = self.fst_vt['description'] - + turbine.TurbineName = 'WEIS Turbine' + # Define DISCON infile paths self.fst_vt['ServoDyn']['DLL_InFile'] = self.FAST_namingOut + '_DISCON.IN' discon_in_file = os.path.join(self.FAST_runDirectory, self.fst_vt['ServoDyn']['DLL_InFile']) @@ -1410,7 +1380,14 @@ def write_HydroDyn(self): 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')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['HydroDyn']['WavePkShp'], 'WavePkShp', '- Peak-shape parameter of incident wave spectrum (-) or DEFAULT (string) [used only when WaveMod=2; use 1.0 for Pierson-Moskowitz]\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')) @@ -1419,7 +1396,13 @@ def write_HydroDyn(self): 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')) - 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')) + + 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')) @@ -1517,7 +1500,7 @@ def write_HydroDyn(self): 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')) - f.write(" ".join(['{:^11s}'.format(i) for i in ['JointID', 'Jointxi', 'Jointyi', 'Jointzi', 'JointAxID', 'JointOvrlp']])+' [JointOvrlp= 0: do nothing at joint, 1: eliminate overlaps by calculating super member]\n') + f.write(" ".join(['{:^11s}'.format(i) for i in ['JointID', 'Jointxi', 'Jointyi', 'Jointzi', 'JointAxID', 'JointOvrlp']])+' ! [JointOvrlp= 0: do nothing at joint, 1: eliminate overlaps by calculating super member]\n') f.write(" ".join(['{:^11s}'.format(i) for i in ['(-)', '(m)', '(m)', '(m)', '(-)', '(switch)']])+'\n') for i in range(self.fst_vt['HydroDyn']['NJoints']): ln = [] @@ -1609,7 +1592,7 @@ def write_HydroDyn(self): 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', '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 = [] @@ -1693,10 +1676,10 @@ def write_SubDyn(self): 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')) JDampings = self.fst_vt['SubDyn']['JDampings'] - if isinstance(JDampings, int): + if isinstance(JDampings, float): f.write('{:<22} {:<11} {:}'.format(self.fst_vt['SubDyn']['JDampings'], 'JDampings', '- Damping Ratios for each retained mode (% of critical) If Nmodes>0, list Nmodes structural damping ratios for each retained mode (% of critical), or a single damping ratio to be applied to all retained modes. (last entered value will be used for all remaining modes).\n')) - else: - f.write('{:<22} {:<11} {:}'.format(", ".join(self.fst_vt['SubDyn']['JDampings']), 'JDampings', '- Damping Ratios for each retained mode (% of critical) If Nmodes>0, list Nmodes structural damping ratios for each retained mode (% of critical), or a single damping ratio to be applied to all retained modes. (last entered value will be used for all remaining modes).\n')) + else: # list of floats + f.write('{:<22} {:<11} {:}'.format(", ".join([f'{d:f}' for d in self.fst_vt['SubDyn']['JDampings']]), 'JDampings', '- Damping Ratios for each retained mode (% of critical) If Nmodes>0, list Nmodes structural damping ratios for each retained mode (% of critical), or a single damping ratio to be applied to all retained modes. (last entered value will be used for all remaining modes).\n')) f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['SubDyn']['GuyanDampMod'], 'GuyanDampMod', '- Guyan damping {0=none, 1=Rayleigh Damping, 2=user specified 6x6 matrix}.\n')) f.write('{:<10}, {:<10} {:<11} {:}'.format(self.fst_vt['SubDyn']['RayleighDamp'][0], self.fst_vt['SubDyn']['RayleighDamp'][1], 'RayleighDamp', '- Mass and stiffness proportional damping coefficients (Rayleigh Damping) [only if GuyanDampMod=1].\n')) f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['SubDyn']['GuyanDampSize'], 'GuyanDampSize', '- Guyan damping matrix (6x6) [only if GuyanDampMod=2].\n')) @@ -1726,7 +1709,7 @@ def write_SubDyn(self): f.write(" ".join(ln) + '\n') f.write('------------------- BASE REACTION JOINTS: 1/0 for Locked/Free DOF @ each Reaction Node ---------------------\n') f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['SubDyn']['NReact'], 'NReact', '- Number of Joints with reaction forces; be sure to remove all rigid motion DOFs of the structure (else det([K])=[0])\n')) - f.write(" ".join(['{:^11s}'.format(i) for i in ['RJointID', 'RctTDXss', 'RctTDYss', 'RctTDZss', 'RctRDXss', 'RctRDYss', 'RctRDZss','SSIfile']])+' [Global Coordinate System]\n') + f.write(" ".join(['{:^11s}'.format(i) for i in ['RJointID', 'RctTDXss', 'RctTDYss', 'RctTDZss', 'RctRDXss', 'RctRDYss', 'RctRDZss','SSIfile']])+' ! [Global Coordinate System]\n') f.write(" ".join(['{:^11s}'.format(i) for i in ['(-)', '(flag)', '(flag)', '(flag)', '(flag)', '(flag)', '(flag)', '(string)']])+'\n') for i in range(self.fst_vt['SubDyn']['NReact']): ln = [] @@ -1741,7 +1724,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']])+' ! [Global Coordinate System]\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 = [] @@ -1864,7 +1847,7 @@ def write_SubDyn(self): 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(" ".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 ['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']): ln = [] @@ -1951,54 +1934,48 @@ def write_MoorDyn(self): f.write('Generated with AeroElasticSE FAST driver\n') f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['MoorDyn']['Echo'], 'Echo', '- echo the input file data (flag)\n')) f.write('----------------------- LINE TYPES ------------------------------------------\n') - f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['MoorDyn']['NTypes'], 'NTypes', '- number of LineTypes\n')) - f.write(" ".join(['{:^11s}'.format(i) for i in ['Name', 'Diam', 'MassDen', 'EA', 'BA/-zeta', 'Can', 'Cat', 'Cdn', 'Cdt']])+'\n') - f.write(" ".join(['{:^11s}'.format(i) for i in ['(-)', '(m)', '(kg/m)', '(N)', '(N-s/-)', '(-)', '(-)', '(-)', '(-)']])+'\n') - for i in range(self.fst_vt['MoorDyn']['NTypes']): + f.write(" ".join(['{:^11s}'.format(i) for i in ['Name', 'Diam', 'MassDen', 'EA', 'BA/-zeta', 'EI', 'Cd', 'Ca', 'CdAx', 'CaAx']])+'\n') + f.write(" ".join(['{:^11s}'.format(i) for i in ['(-)', '(m)', '(kg/m)', '(N)', '(N-s/-)', '(-)', '(-)', '(-)', '(-)', '(-)']])+'\n') + for i in range(len(self.fst_vt['MoorDyn']['Name'])): ln = [] ln.append('{:^11}'.format(self.fst_vt['MoorDyn']['Name'][i])) ln.append('{:^11}'.format(self.fst_vt['MoorDyn']['Diam'][i])) ln.append('{:^11}'.format(self.fst_vt['MoorDyn']['MassDen'][i])) ln.append('{:^11}'.format(self.fst_vt['MoorDyn']['EA'][i])) ln.append('{:^11}'.format(self.fst_vt['MoorDyn']['BA_zeta'][i])) - ln.append('{:^11}'.format(self.fst_vt['MoorDyn']['Can'][i])) - ln.append('{:^11}'.format(self.fst_vt['MoorDyn']['Cat'][i])) - ln.append('{:^11}'.format(self.fst_vt['MoorDyn']['Cdn'][i])) - ln.append('{:^11}'.format(self.fst_vt['MoorDyn']['Cdt'][i])) + ln.append('{:^11}'.format(self.fst_vt['MoorDyn']['EI'][i])) + ln.append('{:^11}'.format(self.fst_vt['MoorDyn']['Cd'][i])) + ln.append('{:^11}'.format(self.fst_vt['MoorDyn']['Ca'][i])) + ln.append('{:^11}'.format(self.fst_vt['MoorDyn']['CdAx'][i])) + ln.append('{:^11}'.format(self.fst_vt['MoorDyn']['CaAx'][i])) f.write(" ".join(ln) + '\n') - f.write('---------------------- CONNECTION PROPERTIES --------------------------------\n') - f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['MoorDyn']['NConnects'], 'NConnects', '- number of connections including anchors and fairleads\n')) - f.write(" ".join(['{:^11s}'.format(i) for i in ['Node', 'Type', 'X', 'Y', 'Z', 'M', 'V', 'FX', 'FY', 'FZ', 'CdA', 'CA']])+'\n') - f.write(" ".join(['{:^11s}'.format(i) for i in ['(-)', '(-)', '(m)', '(m)', '(m)', '(kg)', '(m^3)', '(kN)', '(kN)', '(kN)', '(m^2)', '(-)']])+'\n') - for i in range(self.fst_vt['MoorDyn']['NConnects']): + 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') + for i in range(len(self.fst_vt['MoorDyn']['Point_ID'])): ln = [] - ln.append('{:^11d}'.format(self.fst_vt['MoorDyn']['Node'][i])) - ln.append('{:^11}'.format(self.fst_vt['MoorDyn']['Type'][i])) + ln.append('{:^11d}'.format(self.fst_vt['MoorDyn']['Point_ID'][i])) + ln.append('{:^11}'.format(self.fst_vt['MoorDyn']['Attachment'][i])) ln.append('{:^11}'.format(self.fst_vt['MoorDyn']['X'][i])) ln.append('{:^11}'.format(self.fst_vt['MoorDyn']['Y'][i])) ln.append('{:^11}'.format(self.fst_vt['MoorDyn']['Z'][i])) ln.append('{:^11}'.format(self.fst_vt['MoorDyn']['M'][i])) ln.append('{:^11}'.format(self.fst_vt['MoorDyn']['V'][i])) - ln.append('{:^11}'.format(self.fst_vt['MoorDyn']['FX'][i])) - ln.append('{:^11}'.format(self.fst_vt['MoorDyn']['FY'][i])) - ln.append('{:^11}'.format(self.fst_vt['MoorDyn']['FZ'][i])) ln.append('{:^11}'.format(self.fst_vt['MoorDyn']['CdA'][i])) ln.append('{:^11}'.format(self.fst_vt['MoorDyn']['CA'][i])) f.write(" ".join(ln) + '\n') - f.write('---------------------- LINE PROPERTIES --------------------------------------\n') - f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['MoorDyn']['NLines'], 'NLines', '- number of line objects\n')) - f.write(" ".join(['{:^11s}'.format(i) for i in ['Line', 'LineType', 'UnstrLen', 'NumSegs', 'NodeAnch', 'NodeFair', 'Outputs', 'CtrlChan']])+'\n') - f.write(" ".join(['{:^11s}'.format(i) for i in ['(-)', '(-)', '(m)', '(-)', '(-)', '(-)', '(-)', '(-)']])+'\n') - for i in range(self.fst_vt['MoorDyn']['NLines']): + f.write('---------------------- LINES --------------------------------------\n') + f.write(" ".join(['{:^11s}'.format(i) for i in ['Line', 'LineType', 'AttachA', 'AttachB', 'UnstrLen', 'NumSegs', 'Outputs']])+'\n') + f.write(" ".join(['{:^11s}'.format(i) for i in ['(-)', '(-)', '(-)', '(-)', '(m)', '(-)', '(-)']])+'\n') + for i in range(len(self.fst_vt['MoorDyn']['Line_ID'])): ln = [] - ln.append('{:^11d}'.format(self.fst_vt['MoorDyn']['Line'][i])) + 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']['UnstrLen'][i])) ln.append('{:^11d}'.format(self.fst_vt['MoorDyn']['NumSegs'][i])) - ln.append('{:^11d}'.format(self.fst_vt['MoorDyn']['NodeAnch'][i])) - ln.append('{:^11d}'.format(self.fst_vt['MoorDyn']['NodeFair'][i])) ln.append('{:^11}'.format(self.fst_vt['MoorDyn']['Outputs'][i])) - ln.append('{:^11}'.format(self.fst_vt['MoorDyn']['CtrlChan'][i])) f.write(" ".join(ln) + '\n') f.write('---------------------- SOLVER OPTIONS ---------------------------------------\n') f.write('{:<22} {:<11} {:}'.format(self.fst_vt['MoorDyn']['dtM'], 'dtM', '- time step to use in mooring integration (s)\n')) @@ -2016,350 +1993,146 @@ def write_MoorDyn(self): f.write('END\n') f.write('------------------------- need this line --------------------------------------\n') - f.close() - -class InputWriter_FAST7(InputWriter_Common): - - def execute(self): + f.close() - if not os.path.exists(self.FAST_runDirectory): - os.makedirs(self.FAST_runDirectory) - - # self.write_WindWnd() - self.write_ElastoDynBlade() - self.write_ElastoDynTower() - self.write_AeroDyn_FAST7() - - self.write_MainInput() - - def write_MainInput(self): - - self.FAST_InputFileOut = os.path.join(self.FAST_runDirectory, self.FAST_namingOut+'.fst') - ofh = open(self.FAST_InputFileOut, 'w') - - # FAST Inputs - ofh.write('---\n') - ofh.write('---\n') - ofh.write('{:}\n'.format(self.fst_vt['description'])) - ofh.write('---\n') - ofh.write('---\n') - ofh.write('{:}\n'.format(self.fst_vt['Fst7']['Echo'])) - ofh.write('{:3}\n'.format(self.fst_vt['Fst7']['ADAMSPrep'])) - ofh.write('{:3}\n'.format(self.fst_vt['Fst7']['AnalMode'])) - ofh.write('{:3}\n'.format(self.fst_vt['Fst7']['NumBl'])) - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['TMax'])) - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['DT'])) - ofh.write('---\n') - ofh.write('{:3}\n'.format(self.fst_vt['Fst7']['YCMode'])) - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['TYCOn'])) - ofh.write('{:3}\n'.format(self.fst_vt['Fst7']['PCMode'])) - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['TPCOn'])) - ofh.write('{:3}\n'.format(self.fst_vt['Fst7']['VSContrl'])) - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['VS_RtGnSp'])) - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['VS_RtTq'])) - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['VS_Rgn2K'])) - ofh.write('{:.5e}\n'.format(self.fst_vt['Fst7']['VS_SlPc'])) - ofh.write('{:3}\n'.format(self.fst_vt['Fst7']['GenModel'])) - ofh.write('{:}\n'.format(self.fst_vt['Fst7']['GenTiStr'])) - ofh.write('{:}\n'.format(self.fst_vt['Fst7']['GenTiStp'])) - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['SpdGenOn'])) - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['TimGenOn'])) - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['TimGenOf'])) - ofh.write('{:3}\n'.format(self.fst_vt['Fst7']['HSSBrMode'])) - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['THSSBrDp'])) - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['TiDynBrk'])) - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['TTpBrDp1'])) - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['TTpBrDp2'])) - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['TTpBrDp3'])) - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['TBDepISp1'])) - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['TBDepISp2'])) - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['TBDepISp3'])) - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['TYawManS'])) - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['TYawManE'])) - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['NacYawF'])) - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['TPitManS1'])) - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['TPitManS2'])) - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['TPitManS3'])) - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['TPitManE1'])) - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['TPitManE2'])) - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['TPitManE3'])) - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['BlPitch1'])) - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['BlPitch2'])) - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['BlPitch3'])) - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['B1PitchF1'])) - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['B1PitchF2'])) - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['B1PitchF3'])) - ofh.write('---\n') - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['Gravity'])) - ofh.write('---\n') - ofh.write('{:}\n'.format(self.fst_vt['Fst7']['FlapDOF1'])) - ofh.write('{:}\n'.format(self.fst_vt['Fst7']['FlapDOF2'])) - ofh.write('{:}\n'.format(self.fst_vt['Fst7']['EdgeDOF'])) - ofh.write('{:}\n'.format(self.fst_vt['Fst7']['TeetDOF'])) - ofh.write('{:}\n'.format(self.fst_vt['Fst7']['DrTrDOF'])) - ofh.write('{:}\n'.format(self.fst_vt['Fst7']['GenDOF'])) - ofh.write('{:}\n'.format(self.fst_vt['Fst7']['YawDOF'])) - ofh.write('{:}\n'.format(self.fst_vt['Fst7']['TwFADOF1'])) - ofh.write('{:}\n'.format(self.fst_vt['Fst7']['TwFADOF2'])) - ofh.write('{:}\n'.format(self.fst_vt['Fst7']['TwSSDOF1'])) - ofh.write('{:}\n'.format(self.fst_vt['Fst7']['TwSSDOF2'])) - ofh.write('{:}\n'.format(self.fst_vt['Fst7']['CompAero'])) - ofh.write('{:}\n'.format(self.fst_vt['Fst7']['CompNoise'])) - ofh.write('---\n') - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['OoPDefl'])) - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['IPDefl'])) - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['TeetDefl'])) - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['Azimuth'])) - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['RotSpeed'])) - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['NacYaw'])) - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['TTDspFA'])) - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['TTDspSS'])) - ofh.write('---\n') - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['TipRad'])) - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['HubRad'])) - ofh.write('{:3}\n'.format(self.fst_vt['Fst7']['PSpnElN'])) - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['UndSling'])) - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['HubCM'])) - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['OverHang'])) - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['NacCMxn'])) - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['NacCMyn'])) - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['NacCMzn'])) - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['TowerHt'])) - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['Twr2Shft'])) - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['TwrRBHt'])) - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['ShftTilt'])) - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['Delta3'])) - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['PreCone(1)'])) - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['PreCone(2)'])) - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['PreCone(3)'])) - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['AzimB1Up'])) - ofh.write('---\n') - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['YawBrMass'])) - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['NacMass'])) - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['HubMass'])) - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['TipMass(1)'])) - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['TipMass(2)'])) - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['TipMass(3)'])) - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['NacYIner'])) - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['GenIner'])) - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['HubIner'])) - ofh.write('---\n') - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['GBoxEff'])) - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['GenEff'])) - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['GBRatio'])) - ofh.write('{:}\n'.format(self.fst_vt['Fst7']['GBRevers'])) - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['HSSBrTqF'])) - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['HSSBrDT'])) - ofh.write('{:}\n'.format(self.fst_vt['Fst7']['DynBrkFi'])) - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['DTTorSpr'])) - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['DTTorDmp'])) - ofh.write('---\n') - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['SIG_SlPc'])) - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['SIG_SySp'])) - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['SIG_RtTq'])) - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['SIG_PORt'])) - ofh.write('---\n') - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['TEC_Freq'])) - ofh.write('{:5}\n'.format(self.fst_vt['Fst7']['TEC_NPol'])) - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['TEC_SRes'])) - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['TEC_RRes'])) - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['TEC_VLL'])) - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['TEC_SLR'])) - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['TEC_RLR'])) - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['TEC_MR'])) - ofh.write('---\n') - ofh.write('{:3}\n'.format(self.fst_vt['Fst7']['PtfmModel'])) - ofh.write('"{:}"\n'.format(self.fst_vt['Fst7']['PtfmFile'])) - ofh.write('---\n') - ofh.write('{:3}\n'.format(self.fst_vt['Fst7']['TwrNodes'])) - ofh.write('"{:}"\n'.format(self.fst_vt['Fst7']['TwrFile'])) - ofh.write('---\n') - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['YawSpr'])) - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['YawDamp'])) - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['YawNeut'])) - ofh.write('---\n') - ofh.write('{:}\n'.format(self.fst_vt['Fst7']['Furling'])) - ofh.write('{:}\n'.format(self.fst_vt['Fst7']['FurlFile'])) - ofh.write('---\n') - ofh.write('{:}\n'.format(self.fst_vt['Fst7']['TeetMod'])) - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['TeetDmpP'])) - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['TeetDmp'])) - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['TeetCDmp'])) - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['TeetSStP'])) - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['TeetHStP'])) - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['TeetSSSp'])) - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['TeetHSSp'])) - ofh.write('---\n') - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['TBDrConN'])) - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['TBDrConD'])) - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['TpBrDT'])) - ofh.write('---\n') - ofh.write('"{:}"\n'.format(self.fst_vt['Fst7']['BldFile1'])) - ofh.write('"{:}"\n'.format(self.fst_vt['Fst7']['BldFile2'])) - ofh.write('"{:}"\n'.format(self.fst_vt['Fst7']['BldFile3'])) - ofh.write('---\n') - ofh.write('"{:}"\n'.format(self.fst_vt['Fst7']['ADFile'])) - ofh.write('---\n') - ofh.write('{:}\n'.format(self.fst_vt['Fst7']['NoiseFile'])) - ofh.write('---\n') - ofh.write('{:}\n'.format(self.fst_vt['Fst7']['ADAMSFile'])) - ofh.write('---\n') - ofh.write('{:}\n'.format(self.fst_vt['Fst7']['LinFile'])) - ofh.write('---\n') - ofh.write('{:}\n'.format(self.fst_vt['Fst7']['SumPrint'])) - ofh.write('{:}\n'.format(self.fst_vt['Fst7']['OutFileFmt'])) - ofh.write('{:}\n'.format(self.fst_vt['Fst7']['TabDelim'])) - ofh.write('{:}\n'.format(self.fst_vt['Fst7']['OutFmt'])) - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['TStart'])) - ofh.write('{:3}\n'.format(self.fst_vt['Fst7']['DecFact'])) - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['SttsTime'])) - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['NcIMUxn'])) - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['NcIMUyn'])) - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['NcIMUzn'])) - ofh.write('{:.9f}\n'.format(self.fst_vt['Fst7']['ShftGagL'])) - ofh.write('{:3}\n'.format(self.fst_vt['Fst7']['NTwGages'])) - for i in range(self.fst_vt['Fst7']['NTwGages']-1): - ofh.write('{:3}, '.format(self.fst_vt['Fst7']['TwrGagNd'][i])) - ofh.write('{:3}\n'.format(self.fst_vt['Fst7']['TwrGagNd'][-1])) - ofh.write('{:3}\n'.format(self.fst_vt['Fst7']['NBlGages'])) - for i in range(self.fst_vt['Fst7']['NBlGages']-1): - ofh.write('{:3}, '.format(self.fst_vt['Fst7']['BldGagNd'][i])) - ofh.write('{:3}\n'.format(self.fst_vt['Fst7']['BldGagNd'][-1])) - - # Outlist - ofh.write('Outlist\n') - outlist = self.get_outlist(self.fst_vt['outlist7'], ['OutList']) - for channel_list in outlist: - for i in range(len(channel_list)): - f.write('"' + channel_list[i] + '"\n') - ofh.write('END\n') - ofh.close() - ofh.close() - - def write_AeroDyn_FAST7(self): - if not os.path.isdir(os.path.join(self.FAST_runDirectory,'AeroData')): - os.mkdir(os.path.join(self.FAST_runDirectory,'AeroData')) + def write_StC(self,StC_vt,StC_filename): - # create airfoil objects - 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['Fst7']['ADFile'] = self.FAST_namingOut + '_AeroDyn.dat' - ad_file = os.path.join(self.FAST_runDirectory,self.fst_vt['Fst7']['ADFile']) - ofh = open(ad_file,'w') + stc_file = os.path.join(self.FAST_runDirectory, StC_filename) + f = open(stc_file, 'w') - ofh.write('Aerodyn input file for FAST\n') + f.write('------- STRUCTURAL CONTROL (StC) INPUT FILE ----------------------------\n') + f.write('Generated with AeroElasticSE FAST driver within WEIS\n') - ofh.write('{:}\n'.format(self.fst_vt['AeroDyn14']['SysUnits'])) - ofh.write('{:}\n'.format(self.fst_vt['AeroDyn14']['StallMod'])) + f.write('---------------------- SIMULATION CONTROL --------------------------------------\n') + f.write('{!s:<22} {:<11} {:}'.format(StC_vt['Echo'], 'Echo', '- Echo input data to ".SD.ech" (flag)\n')) - ofh.write('{:}\n'.format(self.fst_vt['AeroDyn14']['UseCm'])) - ofh.write('{:}\n'.format(self.fst_vt['AeroDyn14']['InfModel'])) - ofh.write('{:}\n'.format(self.fst_vt['AeroDyn14']['IndModel'])) - ofh.write('{:.3f}\n'.format(self.fst_vt['AeroDyn14']['AToler'])) - ofh.write('{:}\n'.format(self.fst_vt['AeroDyn14']['TLModel'])) - ofh.write('{:}\n'.format(self.fst_vt['AeroDyn14']['HLModel'])) - ofh.write('"{:}"\n'.format(self.fst_vt['AeroDyn14']['WindFile'])) - ofh.write('{:f}\n'.format(self.fst_vt['AeroDyn14']['HH'])) - - ofh.write('{:.1f}\n'.format(self.fst_vt['AeroDyn14']['TwrShad'])) - - ofh.write('{:.1f}\n'.format(self.fst_vt['AeroDyn14']['ShadHWid'])) - - ofh.write('{:.1f}\n'.format(self.fst_vt['AeroDyn14']['T_Shad_Refpt'])) - - ofh.write('{:.3f}\n'.format(self.fst_vt['AeroDyn14']['AirDens'])) - - ofh.write('{:.9f}\n'.format(self.fst_vt['AeroDyn14']['KinVisc'])) - - ofh.write('{:2}\n'.format(self.fst_vt['AeroDyn14']['DTAero'])) + f.write('---------------------- StC DEGREES OF FREEDOM ----------------------------------\n') + f.write('{:<22} {:<11} {:}'.format(StC_vt['StC_DOF_MODE'], 'StC_DOF_MODE', '- DOF mode (switch) {0: No StC or TLCD DOF; 1: StC_X_DOF, StC_Y_DOF, and/or StC_Z_DOF (three independent StC DOFs); 2: StC_XY_DOF (Omni-Directional StC); 3: TLCD; 4: Prescribed force/moment time series}\n')) + f.write('{!s:<22} {:<11} {:}'.format(StC_vt['StC_X_DOF'], 'StC_X_DOF', '- DOF on or off for StC X (flag) [Used only when StC_DOF_MODE=1]\n')) + f.write('{!s:<22} {:<11} {:}'.format(StC_vt['StC_Y_DOF'], 'StC_Y_DOF', '- DOF on or off for StC Y (flag) [Used only when StC_DOF_MODE=1]\n')) + f.write('{!s:<22} {:<11} {:}'.format(StC_vt['StC_Z_DOF'], 'StC_Z_DOF', '- DOF on or off for StC Z (flag) [Used only when StC_DOF_MODE=1]\n')) + f.write('---------------------- StC LOCATION ------------------------------------------- [relative to the reference origin of component attached to]\n') + f.write('{:<22} {:<11} {:}'.format(StC_vt['StC_P_X'], 'StC_P_X', '- At rest X position of StC (m)\n')) + f.write('{:<22} {:<11} {:}'.format(StC_vt['StC_P_Y'], 'StC_P_Y', '- At rest Y position of StC (m)\n')) + f.write('{:<22} {:<11} {:}'.format(StC_vt['StC_P_Z'], 'StC_P_Z', '- At rest Z position of StC (m)\n')) + + f.write('---------------------- StC INITIAL CONDITIONS --------------------------------- [used only when StC_DOF_MODE=1 or 2]\n') + f.write('{:<22} {:<11} {:}'.format(StC_vt['StC_X_DSP'], 'StC_X_DSP', '- StC X initial displacement (m) [relative to at rest position]\n')) + f.write('{:<22} {:<11} {:}'.format(StC_vt['StC_Y_DSP'], 'StC_Y_DSP', '- StC Y initial displacement (m) [relative to at rest position]\n')) + f.write('{:<22} {:<11} {:}'.format(StC_vt['StC_Z_DSP'], '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]\n')) + f.write('{!s:<22} {:<11} {:}'.format(StC_vt['StC_Z_PreLd'], 'StC_Z_PreLd', '- StC Z pre-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]\n')) + + f.write('---------------------- StC CONFIGURATION -------------------------------------- [used only when StC_DOF_MODE=1 or 2]\n') + f.write('{:<22} {:<11} {:}'.format(StC_vt['StC_X_PSP'], 'StC_X_PSP', '- Positive stop position (maximum X mass displacement) (m)\n')) + f.write('{:<22} {:<11} {:}'.format(StC_vt['StC_X_NSP'], 'StC_X_NSP', '- Negative stop position (minimum X mass displacement) (m)\n')) + f.write('{:<22} {:<11} {:}'.format(StC_vt['StC_Y_PSP'], 'StC_Y_PSP', '- Positive stop position (maximum Y mass displacement) (m)\n')) + f.write('{:<22} {:<11} {:}'.format(StC_vt['StC_Y_NSP'], 'StC_Y_NSP', '- Negative stop position (minimum Y mass displacement) (m)\n')) + f.write('{:<22} {:<11} {:}'.format(StC_vt['StC_Z_PSP'], 'StC_Z_PSP', '- Positive stop position (maximum Z mass displacement) (m) [used only when StC_DOF_MODE=1 and StC_Z_DOF=TRUE]\n')) + f.write('{:<22} {:<11} {:}'.format(StC_vt['StC_Z_NSP'], 'StC_Z_NSP', '- Negative stop position (minimum Z mass displacement) (m) [used only when StC_DOF_MODE=1 and StC_Z_DOF=TRUE]\n')) + + f.write('---------------------- StC MASS, STIFFNESS, & DAMPING ------------------------- [used only when StC_DOF_MODE=1 or 2]\n') + f.write('{:<22} {:<11} {:}'.format(StC_vt['StC_X_M'], 'StC_X_M', '- StC X mass (kg) [must equal StC_Y_M for StC_DOF_MODE = 2]\n')) + f.write('{:<22} {:<11} {:}'.format(StC_vt['StC_Y_M'], 'StC_Y_M', '- StC Y mass (kg) [must equal StC_X_M for StC_DOF_MODE = 2]\n')) + f.write('{:<22} {:<11} {:}'.format(StC_vt['StC_Z_M'], 'StC_Z_M', '- StC Z mass (kg) [used only when StC_DOF_MODE=1 and StC_Z_DOF=TRUE]\n')) + f.write('{:<22} {:<11} {:}'.format(StC_vt['StC_XY_M'], 'StC_XY_M', '- StC Z mass (kg) [used only when StC_DOF_MODE=2]\n')) + f.write('{:<22} {:<11} {:}'.format(StC_vt['StC_X_K'], 'StC_X_K', '- StC X stiffness (N/m)\n')) + f.write('{:<22} {:<11} {:}'.format(StC_vt['StC_Y_K'], 'StC_Y_K', '- StC Y stiffness (N/m)\n')) + f.write('{:<22} {:<11} {:}'.format(StC_vt['StC_Z_K'], 'StC_Z_K', '- StC Z stiffness (N/m) [used only when StC_DOF_MODE=1 and StC_Z_DOF=TRUE]\n')) + f.write('{:<22} {:<11} {:}'.format(StC_vt['StC_X_C'], 'StC_X_C', '- StC X damping (N/(m/s))\n')) + f.write('{:<22} {:<11} {:}'.format(StC_vt['StC_Y_C'], 'StC_Y_C', '- StC Y damping (N/(m/s))\n')) + f.write('{:<22} {:<11} {:}'.format(StC_vt['StC_Z_C'], 'StC_Z_C', '- StC Z damping (N/(m/s)) [used only when StC_DOF_MODE=1 and StC_Z_DOF=TRUE]\n')) + f.write('{:<22} {:<11} {:}'.format(StC_vt['StC_X_KS'], 'StC_X_KS', '- Stop spring X stiffness (N/m)\n')) + f.write('{:<22} {:<11} {:}'.format(StC_vt['StC_Y_KS'], 'StC_Y_KS', '- Stop spring Y stiffness (N/m)\n')) + f.write('{:<22} {:<11} {:}'.format(StC_vt['StC_Z_KS'], 'StC_Z_KS', '- Stop spring Z stiffness (N/m) [used only when StC_DOF_MODE=1 and StC_Z_DOF=TRUE]\n')) + f.write('{:<22} {:<11} {:}'.format(StC_vt['StC_X_CS'], 'StC_X_CS', '- Stop spring X damping (N/(m/s))\n')) + f.write('{:<22} {:<11} {:}'.format(StC_vt['StC_Y_CS'], 'StC_Y_CS', '- Stop spring Y damping (N/(m/s))\n')) + f.write('{:<22} {:<11} {:}'.format(StC_vt['StC_Z_CS'], 'StC_Z_CS', '- Stop spring Z damping (N/(m/s)) [used only when StC_DOF_MODE=1 and StC_Z_DOF=TRUE]\n')) + + f.write('---------------------- StC USER-DEFINED SPRING FORCES ------------------------- [used only when StC_DOF_MODE=1 or 2]\n') + f.write('{!s:<22} {:<11} {:}'.format(StC_vt['Use_F_TBL'], 'Use_F_TBL', '- Use spring force from user-defined table (flag)\n')) + f.write('{:<22} {:<11} {:}'.format(StC_vt['NKInpSt'], 'NKInpSt', '- Number of spring force input stations\n')) + + f.write('---------------------- StC SPRING FORCES TABLE -------------------------------- [used only when StC_DOF_MODE=1 or 2]\n') + f.write('X F_X Y F_Y Z F_Z\n') + f.write('(m) (N) (m) (N) (m) (N)\n') + table = StC_vt['SpringForceTable'] + for x, f_x, y, f_y, z, f_z in zip(table['X'],table['F_X'],table['Y'],table['F_Y'],table['Z'],table['F_Z']): + 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('{:<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')) + f.write('{:<22} {:<11} {:}'.format(StC_vt['StC_X_C_HIGH'], 'StC_X_C_HIGH', '- StC X high damping for ground hook control\n')) + f.write('{:<22} {:<11} {:}'.format(StC_vt['StC_X_C_LOW'], 'StC_X_C_LOW', '- StC X low damping for ground hook control\n')) + f.write('{:<22} {:<11} {:}'.format(StC_vt['StC_Y_C_HIGH'], 'StC_Y_C_HIGH', '- StC Y high damping for ground hook control\n')) + f.write('{:<22} {:<11} {:}'.format(StC_vt['StC_Y_C_LOW'], 'StC_Y_C_LOW', '- StC Y low damping for ground hook control\n')) + f.write('{:<22} {:<11} {:}'.format(StC_vt['StC_Z_C_HIGH'], 'StC_Z_C_HIGH', '- StC Z high damping for ground hook control [used only when StC_DOF_MODE=1 and StC_Z_DOF=TRUE]\n')) + f.write('{:<22} {:<11} {:}'.format(StC_vt['StC_Z_C_LOW'], 'StC_Z_C_LOW', '- StC Z low damping for ground hook control [used only when StC_DOF_MODE=1 and StC_Z_DOF=TRUE]\n')) + f.write('{:<22} {:<11} {:}'.format(StC_vt['StC_X_C_BRAKE'], 'StC_X_C_BRAKE', '- StC X high damping for braking the StC (Don''t use it now. should be zero)\n')) + f.write('{:<22} {:<11} {:}'.format(StC_vt['StC_Y_C_BRAKE'], 'StC_Y_C_BRAKE', '- StC Y high damping for braking the StC (Don''t use it now. should be zero)\n')) + f.write('{:<22} {:<11} {:}'.format(StC_vt['StC_Z_C_BRAKE'], 'StC_Z_C_BRAKE', '- StC Z high damping for braking the StC (Don''t use it now. should be zero) [used only when StC_DOF_MODE=1 and StC_Z_DOF=TRUE]\n')) + + f.write('---------------------- TLCD --------------------------------------------------- [used only when StC_DOF_MODE=3]\n') + f.write('{:<22} {:<11} {:}'.format(StC_vt['L_X'], 'L_X', '- X TLCD total length (m)\n')) + f.write('{:<22} {:<11} {:}'.format(StC_vt['B_X'], 'B_X', '- X TLCD horizontal length (m)\n')) + f.write('{:<22} {:<11} {:}'.format(StC_vt['area_X'], 'area_X', '- X TLCD cross-sectional area of vertical column (m^2)\n')) + f.write('{:<22} {:<11} {:}'.format(StC_vt['area_ratio_X'], 'area_ratio_X', '- X TLCD cross-sectional area ratio (vertical column area divided by horizontal column area) (-)\n')) + f.write('{:<22} {:<11} {:}'.format(StC_vt['headLossCoeff_X'], 'headLossCoeff_X', '- X TLCD head loss coeff (-)\n')) + f.write('{:<22} {:<11} {:}'.format(StC_vt['rho_X'], 'rho_X', '- X TLCD liquid density (kg/m^3)\n')) + f.write('{:<22} {:<11} {:}'.format(StC_vt['L_Y'], 'L_Y', '- Y TLCD total length (m)\n')) + f.write('{:<22} {:<11} {:}'.format(StC_vt['B_Y'], 'B_Y', '- Y TLCD horizontal length (m)\n')) + f.write('{:<22} {:<11} {:}'.format(StC_vt['area_Y'], 'area_Y', '- Y TLCD cross-sectional area of vertical column (m^2)\n')) + f.write('{:<22} {:<11} {:}'.format(StC_vt['area_ratio_Y'], 'area_ratio_Y', '- Y TLCD cross-sectional area ratio (vertical column area divided by horizontal column area) (-)\n')) + f.write('{:<22} {:<11} {:}'.format(StC_vt['headLossCoeff_Y'], 'headLossCoeff_Y', '- Y TLCD head loss coeff (-)\n')) + f.write('{:<22} {:<11} {:}'.format(StC_vt['rho_Y'], 'rho_Y', '- Y TLCD liquid density (kg/m^3)\n')) + + f.write('---------------------- PRESCRIBED TIME SERIES --------------------------------- [used only when StC_DOF_MODE=4]\n') + f.write('{:<22} {:<11} {:}'.format(StC_vt['PrescribedForcesCoord'], 'PrescribedForcesCoord', '- Prescribed forces are in global or local coordinates (switch) {1: global; 2: local}\n')) + f.write('{!s:<22} {:<11} {:}'.format(StC_vt['PrescribedForcesFile'], 'PrescribedForcesFile', '- Time series force and moment (7 columns of time, FX, FY, FZ, MX, MY, MZ)\n')) + f.write('-------------------------------------------------------------------------------\n') - ofh.write('{:2}\n'.format(self.fst_vt['AeroDyn14']['NumFoil'])) - for i in range (self.fst_vt['AeroDyn14']['NumFoil']): - ofh.write('"{:}"\n'.format(self.fst_vt['AeroDyn14']['FoilNm'][i])) - - ofh.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'] - ofh.write('Nodal properties\n') - for r, t, dr, c, a, p in zip(rnodes, twist, drnodes, chord, nfoil, prnelm): - ofh.write('{: 2.15e}\t{:.3f}\t{:.4f}\t{:.3f}\t{:5}\t{:}\n'.format(r, t, dr, c, a, p)) - - ofh.close() - - + f.close() if __name__=="__main__": - FAST_ver = 'openfast' - read_yaml = False - 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 - if read_yaml: - fast = InputReader_Common(FAST_ver=FAST_ver) - fast.FAST_yamlfile = 'temp/OpenFAST/test.yaml' - fast.read_yaml() - - if FAST_ver.lower() == 'fast7': - if not read_yaml: - fast = InputReader_FAST7(FAST_ver=FAST_ver) - fast.FAST_InputFile = 'Test16.fst' # FAST input file (ext=.fst) - fast.FAST_directory = 'C:/Users/egaertne/WT_Codes/models/FAST_v7.02.00d-bjj/CertTest/' # Path to fst directory files - fast.execute() - - fastout = InputWriter_FAST7(FAST_ver=FAST_ver) - fastout.fst_vt = fast.fst_vt - fastout.FAST_runDirectory = 'temp/FAST7' - fastout.FAST_namingOut = 'test' - fastout.execute() - - elif FAST_ver.lower() == 'fast8': - if not read_yaml: - fast = InputReader_OpenFAST(FAST_ver=FAST_ver) - fast.FAST_InputFile = 'NREL5MW_onshore.fst' # FAST input file (ext=.fst) - fast.FAST_directory = 'C:/Users/egaertne/WT_Codes/models/FAST_v8.16.00a-bjj/ref/5mw_onshore/' # Path to fst directory files - fast.execute() - - fastout = InputWriter_OpenFAST(FAST_ver=FAST_ver) - fastout.fst_vt = fast.fst_vt - fastout.FAST_runDirectory = 'temp/FAST8' - fastout.FAST_namingOut = 'test' - fastout.execute() - - elif FAST_ver.lower() == 'openfast': - if not read_yaml: - fast = InputReader_OpenFAST(FAST_ver=FAST_ver) - # fast.FAST_InputFile = '5MW_Land_DLL_WTurb.fst' # FAST input file (ext=.fst) - # fast.FAST_directory = 'C:/Users/egaertne/WT_Codes/models/openfast/glue-codes/fast/5MW_Land_DLL_WTurb' # Path to fst directory files - - # fast.FAST_InputFile = "5MW_OC4Jckt_DLL_WTurb_WavesIrr_MGrowth.fst" - # fast.FAST_directory = 'C:/Users/egaertne/WT_Codes/models/openfast-dev/r-test/glue-codes/openfast/5MW_OC4Jckt_DLL_WTurb_WavesIrr_MGrowth' - - fast.FAST_InputFile = '5MW_OC3Spar_DLL_WTurb_WavesIrr.fst' # FAST input file (ext=.fst) - fast.FAST_directory = 'C:/Users/egaertne/WT_Codes/models/openfast-dev/r-test/glue-codes/openfast/5MW_OC3Spar_DLL_WTurb_WavesIrr' # Path to fst directory files - - fast.execute() - - fastout = InputWriter_OpenFAST(FAST_ver=FAST_ver) - fastout.fst_vt = fast.fst_vt - fastout.FAST_runDirectory = 'temp/OpenFAST' - fastout.FAST_namingOut = 'test' - fastout.update(fst_update=fst_update) - fastout.execute() + # 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() - fastout.write_yaml() + # Write out the model + fastout = InputWriter_OpenFAST() + fastout.fst_vt = fast.fst_vt + fastout.FAST_runDirectory = 'temp/OpenFAST' + fastout.FAST_namingOut = 'iea15' + 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/ROSCO/ROSCO_toolbox/ofTools/fast_io/update_discons.py b/ROSCO/ROSCO_toolbox/ofTools/fast_io/update_discons.py index 901a953ae..6c8b62717 100644 --- a/ROSCO/ROSCO_toolbox/ofTools/fast_io/update_discons.py +++ b/ROSCO/ROSCO_toolbox/ofTools/fast_io/update_discons.py @@ -1,37 +1,15 @@ import os # ROSCO toolbox modules -from ROSCO_toolbox import controller as ROSCO_controller -from ROSCO_toolbox import turbine as ROSCO_turbine + from ROSCO_toolbox.utilities import write_DISCON -from ROSCO_toolbox.inputs.validation import load_rosco_yaml +from ROSCO_toolbox.tune import yaml_to_objs def update_discons(tune_to_test_map): # Update a set of discon files # Input is a dict: each key is the tuning yaml and each value is the discon or list of discons for tuning_yaml in tune_to_test_map: - # Load yaml file - inps = load_rosco_yaml(tuning_yaml) - path_params = inps['path_params'] - turbine_params = inps['turbine_params'] - controller_params = inps['controller_params'] - - # Instantiate turbine, controller, and file processing classes - turbine = ROSCO_turbine.Turbine(turbine_params) - controller = ROSCO_controller.Controller(controller_params) - - # Load turbine data from OpenFAST and rotor performance text file - yaml_dir = os.path.dirname(tuning_yaml) # files relative to tuning yaml - turbine.load_from_fast( - path_params['FAST_InputFile'], - os.path.join(yaml_dir,path_params['FAST_directory']), - dev_branch=True, - rot_source='txt', - txt_filename=os.path.join(yaml_dir,path_params['FAST_directory'],path_params['rotor_performance_filename']) - ) - - # Tune controller - controller.tune_controller(turbine) + controller, turbine, path_params = yaml_to_objs(tuning_yaml) # Write parameter input file if not isinstance(tune_to_test_map[tuning_yaml],list): diff --git a/ROSCO/ROSCO_toolbox/sim.py b/ROSCO/ROSCO_toolbox/sim.py index 54e3df62d..39ab71f66 100644 --- a/ROSCO/ROSCO_toolbox/sim.py +++ b/ROSCO/ROSCO_toolbox/sim.py @@ -140,7 +140,7 @@ def sim_ws_series(self, t_array, ws_array, rotor_rpm_init=10, init_pitch=0.0, gen_torque[i], bld_pitch[i], nac_yawrate[i] = self.controller_int.call_controller(turbine_state) # Calculate the power - gen_power[i] = gen_speed[i] * gen_torque[i] + gen_power[i] = gen_speed[i] * gen_torque[i] * self.turbine.GenEff / 100 # Calculate the nacelle position nac_yaw[i] = nac_yaw[i-1] + nac_yawrate[i] * dt @@ -181,7 +181,7 @@ def sim_ws_series(self, t_array, ws_array, rotor_rpm_init=10, init_pitch=0.0, ax.grid() ax = axarr[3] ax.plot(self.t_array, self.gen_power/1000) - ax.set_ylabel('Gen Power (W)') + ax.set_ylabel('Gen Power (kW)') ax.grid() ax = axarr[4] ax.plot(self.t_array, self.bld_pitch*rad2deg) @@ -304,6 +304,7 @@ def sim_ws_wd_series(self, t_array, ws_array, wd_array, # Calculate the power gen_power[i] = gen_speed[i] * gen_torque[i] + gen_power[i] = gen_speed[i] * gen_torque[i] * self.turbine.GenEff / 100 # Update the nacelle position nac_yaw[i] = nac_yaw[i-1] + nac_yawrate[i]*rad2deg*dt diff --git a/ROSCO/ROSCO_toolbox/tune.py b/ROSCO/ROSCO_toolbox/tune.py new file mode 100644 index 000000000..e4d5392cf --- /dev/null +++ b/ROSCO/ROSCO_toolbox/tune.py @@ -0,0 +1,87 @@ +# Copyright 2019 NREL + +# 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 http://www.apache.org/licenses/LICENSE-2.0 + +# 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. + +import os +from ROSCO_toolbox import controller as ROSCO_controller +from ROSCO_toolbox import turbine as ROSCO_turbine +from ROSCO_toolbox.inputs.validation import load_rosco_yaml +from ROSCO_toolbox.utilities import read_DISCON, write_DISCON, DISCON_dict + + +def yaml_to_objs(tuning_yaml): + # Load yaml and return controller, turbine objects + # Basically, tune a whole controller! + + # Load yaml file + inps = load_rosco_yaml(tuning_yaml) + path_params = inps['path_params'] + turbine_params = inps['turbine_params'] + controller_params = inps['controller_params'] + + # Instantiate turbine, controller, and file processing classes + turbine = ROSCO_turbine.Turbine(turbine_params) + controller = ROSCO_controller.Controller(controller_params) + + # Load turbine data from OpenFAST and rotor performance text file + yaml_dir = os.path.dirname(tuning_yaml) # files relative to tuning yaml + turbine.load_from_fast( + path_params['FAST_InputFile'], + os.path.join(yaml_dir,path_params['FAST_directory']), + rot_source='txt', + txt_filename=os.path.join(yaml_dir,path_params['FAST_directory'],path_params['rotor_performance_filename']) + ) + + # Tune controller + controller.tune_controller(turbine) + + return controller, turbine, path_params + +def update_discon_version(file,tuning_yaml,new_discon_filename): + ''''''''' + This function will take a DISCON input from a previous version of ROSCO and conver it to this version + It will not be 100%, requires a check, but still saves time + + ''' + + # Use new defaults for these inputs for various reasons + exclude_list = [ + 'Y_ErrThresh', # translated from float to list of floats in v2.6 + 'WE_CP', + ] + + # Read original DISCON + discon_vt = read_DISCON(file) + + # Tune dummy controller to get objects + controller, turbine, _ = yaml_to_objs(tuning_yaml) + + # Load default inputs + discon_defaults = DISCON_dict(turbine,controller) + + # A simple update doesn't handle type changes + new_discon = {} + for param in discon_defaults: + # If the value is in the original DISCON and not excluded, use the original + if (param in discon_vt) and (param not in exclude_list): + new_discon[param] = discon_vt[param] + + # Otherwise, use the new default + else: + new_discon[param] = discon_defaults[param] + + # Make the DISCON + write_DISCON( + turbine, + controller, + new_discon_filename, + rosco_vt = new_discon, + ) + diff --git a/ROSCO/ROSCO_toolbox/turbine.py b/ROSCO/ROSCO_toolbox/turbine.py index e97d72036..9aa619326 100644 --- a/ROSCO/ROSCO_toolbox/turbine.py +++ b/ROSCO/ROSCO_toolbox/turbine.py @@ -130,7 +130,13 @@ def load(filename): return turbine # Load data from fast input deck - def load_from_fast(self, FAST_InputFile,FAST_directory, FAST_ver='OpenFAST',dev_branch=True,rot_source=None, txt_filename=None): + def load_from_fast( + self, + FAST_InputFile, + FAST_directory, + rot_source=None, + txt_filename=None + ): """ Load the parameter files directly from a FAST input deck @@ -140,10 +146,6 @@ def load_from_fast(self, FAST_InputFile,FAST_directory, FAST_ver='OpenFAST',dev_ Primary fast model input file (*.fst) FAST_directory: str Directory for primary fast model input file - FAST_ver: string, optional - fast version, usually OpenFAST - dev_branch: bool, optional - dev_branch input to InputReader_OpenFAST, probably True rot_source: str, optional desired source for rotor to get Cp, Ct, Cq tables. Default is to run cc-blade. options: cc-blade - run cc-blade @@ -163,7 +165,28 @@ def load_from_fast(self, FAST_InputFile,FAST_directory, FAST_ver='OpenFAST',dev_ fast = self.fast = InputReader_OpenFAST() fast.FAST_InputFile = FAST_InputFile fast.FAST_directory = FAST_directory - fast.execute() + + fast.read_MainInput() + + # file + ed_file = os.path.join(fast.FAST_directory, fast.fst_vt['Fst']['EDFile']) + + fast.read_ElastoDyn(ed_file) + ed_blade_file = os.path.join(os.path.dirname(ed_file), fast.fst_vt['ElastoDyn']['BldFile1']) + fast.read_ElastoDynBlade(ed_blade_file) + + fast.read_AeroDyn15() + + fast.read_ServoDyn() + fast.read_DISCON_in() + + + if fast.fst_vt['Fst']['CompHydro'] == 1: # SubDyn not yet implimented + hd_file = os.path.normpath(os.path.join(fast.FAST_directory, fast.fst_vt['Fst']['HydroFile'])) + fast.read_HydroDyn(hd_file) + + # fast.read_AeroDyn15() + # fast.execute() # Use Performance tables if defined, otherwise use defaults if txt_filename: @@ -419,7 +442,7 @@ def generate_rotperf_fast(self, openfast_path, FAST_runDirectory=None, run_BeamD "GenPwr", "GenTq", # AeroDyn15 "RtArea", "RtVAvgxh", "B1N3Clrnc", "B2N3Clrnc", "B3N3Clrnc", - "RtAeroCp", 'RtAeroCq', 'RtAeroCt', 'RtTSR', # NECESSARY + "RtFldCp", 'RtFldCq', 'RtFldCt', 'RtTSR', # NECESSARY # InflowWind "Wind1VelX", ] diff --git a/ROSCO/ROSCO_toolbox/utilities.py b/ROSCO/ROSCO_toolbox/utilities.py index b68dd3a90..04cf98f32 100644 --- a/ROSCO/ROSCO_toolbox/utilities.py +++ b/ROSCO/ROSCO_toolbox/utilities.py @@ -28,6 +28,8 @@ import subprocess import ROSCO_toolbox +from wisdem.inputs import load_yaml + # Some useful constants now = datetime.datetime.now() pi = np.pi @@ -81,8 +83,9 @@ def write_DISCON(turbine, controller, param_file='DISCON.IN', txt_filename='Cp_C file.write('{0:<12d} ! Flp_Mode - Flap control mode {{0: no flap control, 1: steady state flap angle, 2: Proportional flap control, 2: Cyclic (1P) flap control}}\n'.format(int(rosco_vt['Flp_Mode']))) file.write('{0:<12d} ! OL_Mode - Open loop control mode {{0: no open loop control, 1: open loop control vs. time}}\n'.format(int(rosco_vt['OL_Mode']))) file.write('{0:<12d} ! PA_Mode - Pitch actuator mode {{0 - not used, 1 - first order filter, 2 - second order filter}}\n'.format(int(rosco_vt['PA_Mode']))) + file.write('{0:<12d} ! PF_Mode - Pitch fault mode {{0 - not used, 1 - constant offset on one or more blades}}\n'.format(int(rosco_vt['PF_Mode']))) file.write('{0:<12d} ! Ext_Mode - External control mode {{0 - not used, 1 - call external dynamic library}}\n'.format(int(rosco_vt['Ext_Mode']))) - file.write('{0:<12d} ! ZMQ_Mode - Fuse ZeroMQ interaface {{0: unused, 1: Yaw Control}}\n'.format(int(rosco_vt['ZMQ_Mode']))) + file.write('{0:<12d} ! ZMQ_Mode - Fuse ZeroMQ interface {{0: unused, 1: Yaw Control}}\n'.format(int(rosco_vt['ZMQ_Mode']))) file.write('\n') file.write('!------- FILTERS ----------------------------------------------------------\n') @@ -115,7 +118,8 @@ def write_DISCON(turbine, controller, param_file='DISCON.IN', txt_filename='Cp_C file.write('\n') file.write('!------- INDIVIDUAL PITCH CONTROL -----------------------------------------\n') file.write('{}! IPC_Vramp - Start and end wind speeds for cut-in ramp function. First entry: IPC inactive, second entry: IPC fully active. [m/s]\n'.format(''.join('{:<4.6f} '.format(rosco_vt['IPC_Vramp'][i]) for i in range(len(rosco_vt['IPC_Vramp']))))) - file.write('{:<13.1f} ! IPC_IntSat - Integrator saturation (maximum signal amplitude contribution to pitch from IPC), [rad]\n'.format(rosco_vt['IPC_IntSat'])) # Hardcode to 5 degrees + file.write('{:<11d} ! IPC_SatMode - IPC Saturation method (0 - no saturation (except by PC_MinPit), 1 - saturate by PS_BldPitchMin, 2 - saturate sotfly (full IPC cycle) by PC_MinPit, 3 - saturate softly by PS_BldPitchMin)\n'.format(int(rosco_vt['IPC_SatMode']))) # Hardcode to 5 degrees + file.write('{:<13.1f} ! IPC_IntSat - Integrator saturation (maximum signal amplitude contribution to pitch from IPC), [rad]\n'.format(rosco_vt['IPC_IntSat'])) file.write('{}! IPC_KP - Proportional gain for the individual pitch controller: first parameter for 1P reductions, second for 2P reductions, [-]\n'.format(''.join('{:<4.3e} '.format(rosco_vt['IPC_KP'][i]) for i in range(len(rosco_vt['IPC_KP']))))) file.write('{}! IPC_KI - Integral gain for the individual pitch controller: first parameter for 1P reductions, second for 2P reductions, [-]\n'.format(''.join('{:<4.3e} '.format(rosco_vt['IPC_KI'][i]) for i in range(len(rosco_vt['IPC_KI']))))) file.write('{}! IPC_aziOffset - Phase offset added to the azimuth angle for the individual pitch controller, [rad]. \n'.format(''.join('{:<4.6f} '.format(rosco_vt['IPC_aziOffset'][i]) for i in range(len(rosco_vt['IPC_aziOffset']))))) @@ -156,8 +160,8 @@ def write_DISCON(turbine, controller, param_file='DISCON.IN', txt_filename='Cp_C file.write('{} ! WE_FOPoles - First order system poles [1/s]\n'.format(''.join('{:<10.8f} '.format(rosco_vt['WE_FOPoles'][i]) for i in range(len(rosco_vt['WE_FOPoles']))))) file.write('\n') file.write('!------- YAW CONTROL ------------------------------------------------------\n') - file.write('{:<13.5f} ! Y_uSwitch - Wind speed to switch between Y_ErrThresh. If zero, only the first value of Y_ErrThresh is used [m/s]\n'.format(rosco_vt['Y_uSwitch'])) - file.write('{}! Y_ErrThresh - Yaw error threshold/deadband. Turbine begins to yaw when it passes this. If Y_uSwitch is zero, only the first value is used. [deg].\n'.format(''.join('{:<4.6f} '.format(rosco_vt['Y_ErrThresh'][i]) for i in range(len(rosco_vt['F_FlCornerFreq']))))) + file.write('{:<13.5f} ! Y_uSwitch - Wind speed to switch between Y_ErrThresh. If zero, only the second value of Y_ErrThresh is used [m/s]\n'.format(rosco_vt['Y_uSwitch'])) + file.write('{}! Y_ErrThresh - Yaw error threshold/deadbands. Turbine begins to yaw when it passes this. If Y_uSwitch is zero, only the second value is used. [deg].\n'.format(''.join('{:<4.6f} '.format(rosco_vt['Y_ErrThresh'][i]) for i in range(len(rosco_vt['F_FlCornerFreq']))))) file.write('{:<13.5f} ! Y_Rate - Yaw rate [rad/s]\n'.format(rosco_vt['Y_Rate'])) file.write('{:<13.5f} ! Y_MErrSet - Integrator saturation (maximum signal amplitude contribution to pitch from yaw-by-IPC), [rad]\n'.format(rosco_vt['Y_MErrSet'])) file.write('{:<13.5f} ! Y_IPC_IntSat - Integrator saturation (maximum signal amplitude contribution to pitch from yaw-by-IPC), [rad]\n'.format(rosco_vt['Y_IPC_IntSat'])) @@ -202,6 +206,9 @@ def write_DISCON(turbine, controller, param_file='DISCON.IN', txt_filename='Cp_C file.write('{:<014.5f} ! PA_CornerFreq - Pitch actuator bandwidth/cut-off frequency [rad/s]\n'.format(rosco_vt['PA_CornerFreq'])) file.write('{:<014.5f} ! PA_Damping - Pitch actuator damping ratio [-, unused if PA_Mode = 1]\n'.format(rosco_vt['PA_Damping'])) file.write('\n') + file.write('!------- Pitch Actuator Faults -----------------------------------------------------\n') + file.write('{} ! PF_Offsets - Constant blade pitch offsets for blades 1-3 [rad]\n'.format(''.join('{:<10.8f} '.format(rosco_vt['PF_Offsets'][i]) for i in range(3)))) + file.write('\n') file.write('!------- External Controller Interface -----------------------------------------------------\n') file.write('"{}" ! DLL_FileName - Name/location of the dynamic library in the Bladed-DLL format\n'.format(rosco_vt['DLL_FileName'])) file.write('"{}" ! DLL_InFile - Name of input file sent to the DLL (-)\n'.format(rosco_vt['DLL_InFile'])) @@ -376,6 +383,14 @@ def DISCON_dict(turbine, controller, txt_filename=None): Name of rotor performance filename ''' DISCON_dict = {} + + # Populate with available defaults + input_schema = load_yaml(os.path.join(os.path.dirname(__file__),'inputs/toolbox_schema.yaml')) + discon_props = input_schema['properties']['controller_params']['properties']['DISCON']['properties'] + for prop in discon_props: + if 'default' in discon_props[prop]: + DISCON_dict[prop] = discon_props[prop]['default'] + # ------- DEBUG ------- DISCON_dict['LoggingLevel'] = int(controller.LoggingLevel) # ------- CONTROLLER FLAGS ------- @@ -393,6 +408,7 @@ def DISCON_dict(turbine, controller, txt_filename=None): DISCON_dict['TD_Mode'] = int(controller.TD_Mode) DISCON_dict['Flp_Mode'] = int(controller.Flp_Mode) DISCON_dict['OL_Mode'] = int(controller.OL_Mode) + DISCON_dict['PF_Mode'] = int(controller.PF_Mode) DISCON_dict['PA_Mode'] = int(controller.PA_Mode) DISCON_dict['Ext_Mode'] = int(controller.Ext_Mode) DISCON_dict['ZMQ_Mode'] = int(controller.ZMQ_Mode) @@ -432,6 +448,7 @@ def DISCON_dict(turbine, controller, txt_filename=None): # ------- INDIVIDUAL PITCH CONTROL ------- DISCON_dict['IPC_Vramp'] = controller.IPC_Vramp DISCON_dict['IPC_IntSat'] = 0.2618 + DISCON_dict['IPC_SatMode'] = 2 DISCON_dict['IPC_KP'] = [controller.Kp_ipc1p, controller.Kp_ipc2p] DISCON_dict['IPC_KI'] = [controller.Ki_ipc1p, controller.Ki_ipc2p] DISCON_dict['IPC_aziOffset'] = [0.0, 0.0] @@ -503,9 +520,12 @@ def DISCON_dict(turbine, controller, txt_filename=None): DISCON_dict['PA_Mode'] = controller.PA_Mode DISCON_dict['PA_CornerFreq'] = controller.PA_CornerFreq DISCON_dict['PA_Damping'] = controller.PA_Damping + # ------- Pitch Actuator Fault ------- + DISCON_dict['PF_Offsets'] = [0.,0.,0.] # ------- Zero-MQ ------- DISCON_dict['ZMQ_CommAddress'] = "tcp://localhost:5555" DISCON_dict['ZMQ_UpdatePeriod'] = 2 + # Add pass through here for param, value in controller.controller_params['DISCON'].items(): DISCON_dict[param] = value diff --git a/ROSCO/Test_Cases/BAR_10/BAR_10_AeroDyn15.dat b/ROSCO/Test_Cases/BAR_10/BAR_10_AeroDyn15.dat index 201d9e6d8..9f32b6050 100644 --- a/ROSCO/Test_Cases/BAR_10/BAR_10_AeroDyn15.dat +++ b/ROSCO/Test_Cases/BAR_10/BAR_10_AeroDyn15.dat @@ -10,6 +10,7 @@ False Echo - Echo the input to ".AD.ech"? (fl True TwrAero - Calculate tower aerodynamic loads? (flag) False FrozenWake - Assume frozen wake during linearization? (flag) [used only when WakeMod=1 and when linearizing] False CavitCheck - Perform cavitation check? (flag) TRUE will turn off unsteady aerodynamics +False Buoyancy - Include buoyancy effects? (flag) False CompAA Flag to compute AeroAcoustics calculation [only used when WakeMod=1 or 2] "AeroAcousticsInput.dat" AA_InputFile - Aeroacoustics input file ====== Environmental Conditions =================================================================== @@ -34,10 +35,8 @@ True TIDrag - Include the drag term in the tangential-ind ====== OLAF -- cOnvecting LAgrangian Filaments (Free Vortex Wake) Theory Options ================== [used only when WakeMod=3] "unused" OLAFInputFileName - Input file for OLAF [used only when WakeMod=3] ====== Beddoes-Leishman Unsteady Airfoil Aerodynamics Options ===================================== [used only when AFAeroMod=2] -3 UAMod Unsteady Aero Model Switch (switch) {1=Baseline model (Original), 2=Gonzalez's variant (changes in Cn,Cc,Cm), 3=Minemma/Pierce variant (changes in Cc and Cm)} [used only when AFAeroMod=2] -True 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] -0.0 UAStartRad - Starting radius for dynamic stall (fraction of rotor radius) [used only when AFAeroMod=2] -1.0 UAEndRad - Ending radius for dynamic stall (fraction of rotor radius) [used only when AFAeroMod=2] +3 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] +True 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] ====== Airfoil Information ========================================================================= 3 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} (-) 1 InCol_Alfa - The column in the airfoil tables that contains the angle of attack (-) @@ -81,19 +80,28 @@ True UseBlCm - Include aerodynamic pitching moment in calc "BAR_10_AeroDyn15_blade.dat" ADBlFile(1) - Name of file containing distributed aerodynamic properties for Blade #1 (-) "BAR_10_AeroDyn15_blade.dat" ADBlFile(2) - Name of file containing distributed aerodynamic properties for Blade #2 (-) [unused if NumBl < 2] "BAR_10_AeroDyn15_blade.dat" ADBlFile(3) - Name of file containing distributed aerodynamic properties for Blade #3 (-) [unused if NumBl < 3] +====== Hub Properties ============================================================================== [used only when Buoyancy=True] +0.0 VolHub - Hub volume (m^3) +0.0 HubCenBx - Hub center of buoyancy x direction offset (m) +====== Nacelle Properties ========================================================================== [used only when Buoyancy=True] +0.0 VolNac - Nacelle volume (m^3) +0,0,0 NacCenB - Position of nacelle center of buoyancy from yaw bearing in nacelle coordinates (m) +====== Tail fin Aerodynamics ======================================================================== +False TFinAero - Calculate tail fin aerodynamics model (flag) +"unused" TFinFile - Input file for tail fin aerodynamics [used only when TFinAero=True] ====== Tower Influence and Aerodynamics ============================================================= [used only when TwrPotent/=0, TwrShadow=True, or TwrAero=True] 9 NumTwrNds - Number of tower nodes used in the analysis (-) [used only when TwrPotent/=0, TwrShadow=True, or TwrAero=True] -TwrElev TwrDiam TwrCd TwrTI (used only with TwrShadow=2) -(m) (m) (-) (-) - 2.740000000000000e+01 6.000000000000000e+00 1.000000000000000e+00 1.0e-1 - 4.110000000000000e+01 6.000000000000000e+00 1.000000000000000e+00 1.0e-1 - 5.480000000000000e+01 6.000000000000000e+00 1.000000000000000e+00 1.0e-1 - 6.850000000000000e+01 6.000000000000000e+00 1.000000000000000e+00 1.0e-1 - 8.220000000000000e+01 6.000000000000000e+00 1.000000000000000e+00 1.0e-1 - 9.590000000000001e+01 6.000000000000000e+00 1.000000000000000e+00 1.0e-1 - 1.096000000000000e+02 6.000000000000000e+00 1.000000000000000e+00 1.0e-1 - 1.233000000000000e+02 5.890792130000000e+00 1.000000000000000e+00 1.0e-1 - 1.370000000000000e+02 5.530325920000000e+00 1.000000000000000e+00 1.0e-1 +TwrElev TwrDiam TwrCd TwrTI TwrCb !TwrTI used only with TwrShadow=2, TwrCb used only with Buoyancy=True +(m) (m) (-) (-) (-) + 2.740e+01 6.00000e+00 1.0e+00 1.0e-1 0.0 + 4.110e+01 6.00000e+00 1.0e+00 1.0e-1 0.0 + 5.480e+01 6.00000e+00 1.0e+00 1.0e-1 0.0 + 6.850e+01 6.00000e+00 1.0e+00 1.0e-1 0.0 + 8.220e+01 6.00000e+00 1.0e+00 1.0e-1 0.0 + 9.590e+01 6.00000e+00 1.0e+00 1.0e-1 0.0 + 1.096e+02 6.00000e+00 1.0e+00 1.0e-1 0.0 + 1.233e+02 5.89079e+00 1.0e+00 1.0e-1 0.0 + 1.370e+02 5.53032e+00 1.0e+00 1.0e-1 0.0 ====== Tower Influence and Aerodynamics ============================================================= [used only when TwrPotent/=0, TwrShadow=True, or TwrAero=True] True SumPrint - Generate a summary file listing input options and interpolated properties to ".AD.sum"? (flag) 9 NBlOuts - Number of blade node outputs [0 - 9] (-) @@ -101,18 +109,16 @@ True SumPrint - Generate a summary file listing input optio 0 NTwOuts - Number of tower node outputs [0 - 9] (-) 1, 2, 6 TwOutNd - Tower nodes whose values will be output (-) OutList - The next line(s) contains a list of output parameters. See OutListParameters.xlsx for a listing of available output channels, (-) -"RtAeroCp" -"RtAeroCq" -"RtAeroCt" -"RtAeroFxh" -"RtAeroFyh" -"RtAeroFzh" -"RtAeroMxh" -"RtAeroMyh" -"RtAeroMzh" -"RtAeroPwr" +"RtFldFxh" +"RtFldFyh" +"RtFldFzh" +"RtFldMxh" +"RtFldMyh" +"RtFldMzh" +"RtVAvgxh" +"RtFldCp" +"RtFldCt" "RtArea" -"RtSkew" "RtSpeed" "RtTSR" "RtVAvgxh" diff --git a/ROSCO/Test_Cases/BAR_10/BAR_10_DISCON.IN b/ROSCO/Test_Cases/BAR_10/BAR_10_DISCON.IN index a2d09fa10..17875c9c6 100644 --- a/ROSCO/Test_Cases/BAR_10/BAR_10_DISCON.IN +++ b/ROSCO/Test_Cases/BAR_10/BAR_10_DISCON.IN @@ -1,5 +1,5 @@ ! Controller parameter input file for the BAR_10 wind turbine -! - File written using ROSCO version 2.5.0 controller tuning logic on 07/22/22 +! - File written using ROSCO version 2.7.0 controller tuning logic on 02/06/23 !------- DEBUG ------------------------------------------------------------ 1 ! LoggingLevel - {0: write no debug files, 1: write standard output .dbg-file, 2: LoggingLevel 1 + ROSCO LocalVars (.dbg2) 3: LoggingLevel 2 + complete avrSWAP-array (.dbg3)} @@ -20,8 +20,9 @@ 2 ! Flp_Mode - Flap control mode {0: no flap control, 1: steady state flap angle, 2: Proportional flap control, 2: Cyclic (1P) flap control} 0 ! OL_Mode - Open loop control mode {0: no open loop control, 1: open loop control vs. time} 0 ! PA_Mode - Pitch actuator mode {0 - not used, 1 - first order filter, 2 - second order filter} +0 ! PF_Mode - Pitch fault mode {0 - not used, 1 - constant offset on one or more blades} 0 ! Ext_Mode - External control mode {0 - not used, 1 - call external dynamic library} -0 ! ZMQ_Mode - Fuse ZeroMQ interaface {0: unused, 1: Yaw Control} +0 ! ZMQ_Mode - Fuse ZeroMQ interface {0: unused, 1: Yaw Control} !------- FILTERS ---------------------------------------------------------- 0.81771 ! F_LPFCornerFreq - Corner frequency (-3dB point) in the low-pass filters, [rad/s] @@ -52,6 +53,7 @@ !------- INDIVIDUAL PITCH CONTROL ----------------------------------------- 6.618848 8.273560 ! IPC_Vramp - Start and end wind speeds for cut-in ramp function. First entry: IPC inactive, second entry: IPC fully active. [m/s] +2 ! IPC_SatMode - IPC Saturation method (0 - no saturation (except by PC_MinPit), 1 - saturate by PS_BldPitchMin, 2 - saturate sotfly (full IPC cycle) by PC_MinPit, 3 - saturate softly by PS_BldPitchMin) 0.3 ! IPC_IntSat - Integrator saturation (maximum signal amplitude contribution to pitch from IPC), [rad] 2.050e-08 0.000e+00 ! IPC_KP - Proportional gain for the individual pitch controller: first parameter for 1P reductions, second for 2P reductions, [-] 1.450e-09 0.000e+00 ! IPC_KI - Integral gain for the individual pitch controller: first parameter for 1P reductions, second for 2P reductions, [-] @@ -93,8 +95,8 @@ -0.00972164 -0.01031092 -0.01090020 -0.01148948 -0.01207877 -0.01266805 -0.01325733 -0.01384662 -0.01443590 -0.01502518 -0.01561447 -0.01620375 -0.01679303 -0.01738232 -0.01797160 -0.01856088 -0.01915016 -0.01973945 -0.02032873 -0.02091801 -0.02150730 -0.02209658 -0.02268586 -0.02327515 -0.02386443 -0.02445371 -0.02504300 -0.02563228 -0.02622156 -0.02378670 -0.02062296 -0.02541485 -0.03159105 -0.03849962 -0.04595997 -0.05389417 -0.06225884 -0.07101431 -0.08016995 -0.08970426 -0.09955610 -0.10976762 -0.12028100 -0.13120419 -0.14238799 -0.15383228 -0.16572504 -0.17783697 -0.19011487 -0.20289651 -0.21593424 -0.22919262 -0.24255457 -0.25635133 -0.27049546 -0.28482651 -0.29923376 -0.31380076 -0.32862514 -0.34372726 ! WE_FOPoles - First order system poles [1/s] !------- YAW CONTROL ------------------------------------------------------ -0.00000 ! Y_uSwitch - Wind speed to switch between Y_ErrThresh. If zero, only the first value of Y_ErrThresh is used [m/s] -4.000000 8.000000 ! Y_ErrThresh - Yaw error threshold. Turbine begins to yaw when it passes this. If Y_uSwitch is zero, only the first value is used. [deg]. +0.00000 ! Y_uSwitch - Wind speed to switch between Y_ErrThresh. If zero, only the second value of Y_ErrThresh is used [m/s] +4.000000 8.000000 ! Y_ErrThresh - Yaw error threshold/deadbands. Turbine begins to yaw when it passes this. If Y_uSwitch is zero, only the second value is used. [deg]. 0.00870 ! Y_Rate - Yaw rate [rad/s] 0.00000 ! Y_MErrSet - Integrator saturation (maximum signal amplitude contribution to pitch from yaw-by-IPC), [rad] 0.00000 ! Y_IPC_IntSat - Integrator saturation (maximum signal amplitude contribution to pitch from yaw-by-IPC), [rad] @@ -135,6 +137,9 @@ 3.140000000000 ! PA_CornerFreq - Pitch actuator bandwidth/cut-off frequency [rad/s] 0.707000000000 ! PA_Damping - Pitch actuator damping ratio [-, unused if PA_Mode = 1] +!------- Pitch Actuator Faults ----------------------------------------------------- +0.00000000 0.00000000 0.00000000 ! PF_Offsets - Constant blade pitch offsets for blades 1-3 [rad] + !------- External Controller Interface ----------------------------------------------------- "unused" ! DLL_FileName - Name/location of the dynamic library in the Bladed-DLL format "unused" ! DLL_InFile - Name of input file sent to the DLL (-) diff --git a/ROSCO/Test_Cases/IEA-15-240-RWT-UMaineSemi/DISCON-UMaineSemi.IN b/ROSCO/Test_Cases/IEA-15-240-RWT-UMaineSemi/DISCON-UMaineSemi.IN index 3745fee9e..5f55c5ab9 100644 --- a/ROSCO/Test_Cases/IEA-15-240-RWT-UMaineSemi/DISCON-UMaineSemi.IN +++ b/ROSCO/Test_Cases/IEA-15-240-RWT-UMaineSemi/DISCON-UMaineSemi.IN @@ -1,5 +1,5 @@ ! Controller parameter input file for the IEA-15-240-RWT-UMaineSemi wind turbine -! - File written using ROSCO version 2.5.0 controller tuning logic on 07/22/22 +! - File written using ROSCO version 2.7.0 controller tuning logic on 02/06/23 !------- DEBUG ------------------------------------------------------------ 2 ! LoggingLevel - {0: write no debug files, 1: write standard output .dbg-file, 2: LoggingLevel 1 + ROSCO LocalVars (.dbg2) 3: LoggingLevel 2 + complete avrSWAP-array (.dbg3)} @@ -20,8 +20,9 @@ 0 ! Flp_Mode - Flap control mode {0: no flap control, 1: steady state flap angle, 2: Proportional flap control, 2: Cyclic (1P) flap control} 0 ! OL_Mode - Open loop control mode {0: no open loop control, 1: open loop control vs. time} 2 ! PA_Mode - Pitch actuator mode {0 - not used, 1 - first order filter, 2 - second order filter} +0 ! PF_Mode - Pitch fault mode {0 - not used, 1 - constant offset on one or more blades} 0 ! Ext_Mode - External control mode {0 - not used, 1 - call external dynamic library} -0 ! ZMQ_Mode - Fuse ZeroMQ interaface {0: unused, 1: Yaw Control} +0 ! ZMQ_Mode - Fuse ZeroMQ interface {0: unused, 1: Yaw Control} !------- FILTERS ---------------------------------------------------------- 1.00810 ! F_LPFCornerFreq - Corner frequency (-3dB point) in the low-pass filters, [rad/s] @@ -52,6 +53,7 @@ !------- INDIVIDUAL PITCH CONTROL ----------------------------------------- 8.592000 10.740000 ! IPC_Vramp - Start and end wind speeds for cut-in ramp function. First entry: IPC inactive, second entry: IPC fully active. [m/s] +2 ! IPC_SatMode - IPC Saturation method (0 - no saturation (except by PC_MinPit), 1 - saturate by PS_BldPitchMin, 2 - saturate sotfly (full IPC cycle) by PC_MinPit, 3 - saturate softly by PS_BldPitchMin) 0.3 ! IPC_IntSat - Integrator saturation (maximum signal amplitude contribution to pitch from IPC), [rad] 0.000e+00 0.000e+00 ! IPC_KP - Proportional gain for the individual pitch controller: first parameter for 1P reductions, second for 2P reductions, [-] 0.000e+00 0.000e+00 ! IPC_KI - Integral gain for the individual pitch controller: first parameter for 1P reductions, second for 2P reductions, [-] @@ -93,8 +95,8 @@ -0.02438353 -0.02655283 -0.02872212 -0.03089141 -0.03306071 -0.03523000 -0.03739930 -0.03956859 -0.04173788 -0.04390718 -0.04607647 -0.04824576 -0.05041506 -0.05258435 -0.05475365 -0.05692294 -0.05909223 -0.06126153 -0.06343082 -0.06560011 -0.06776941 -0.06993870 -0.07210800 -0.07427729 -0.07644658 -0.07861588 -0.08078517 -0.08295446 -0.08512376 -0.08490640 -0.05739531 -0.05967534 -0.06643664 -0.07537721 -0.08537869 -0.09664144 -0.10851650 -0.12137925 -0.13453168 -0.14834459 -0.16280188 -0.17753158 -0.19283401 -0.20862160 -0.22461456 -0.24120058 -0.25817445 -0.27538476 -0.29299882 -0.31103587 -0.32941546 -0.34807902 -0.36693717 -0.38625237 -0.40583167 -0.42579305 -0.44596365 -0.46626113 -0.48675074 -0.50756940 ! WE_FOPoles - First order system poles [1/s] !------- YAW CONTROL ------------------------------------------------------ -0.00000 ! Y_uSwitch - Wind speed to switch between Y_ErrThresh. If zero, only the first value of Y_ErrThresh is used [m/s] -4.000000 8.000000 ! Y_ErrThresh - Yaw error threshold. Turbine begins to yaw when it passes this. If Y_uSwitch is zero, only the first value is used. [deg]. +0.00000 ! Y_uSwitch - Wind speed to switch between Y_ErrThresh. If zero, only the second value of Y_ErrThresh is used [m/s] +4.000000 8.000000 ! Y_ErrThresh - Yaw error threshold/deadbands. Turbine begins to yaw when it passes this. If Y_uSwitch is zero, only the second value is used. [deg]. 0.00870 ! Y_Rate - Yaw rate [rad/s] 0.00000 ! Y_MErrSet - Integrator saturation (maximum signal amplitude contribution to pitch from yaw-by-IPC), [rad] 0.00000 ! Y_IPC_IntSat - Integrator saturation (maximum signal amplitude contribution to pitch from yaw-by-IPC), [rad] @@ -135,6 +137,9 @@ 1.570800000000 ! PA_CornerFreq - Pitch actuator bandwidth/cut-off frequency [rad/s] 0.707000000000 ! PA_Damping - Pitch actuator damping ratio [-, unused if PA_Mode = 1] +!------- Pitch Actuator Faults ----------------------------------------------------- +0.00000000 0.00000000 0.00000000 ! PF_Offsets - Constant blade pitch offsets for blades 1-3 [rad] + !------- External Controller Interface ----------------------------------------------------- "unused" ! DLL_FileName - Name/location of the dynamic library in the Bladed-DLL format "unused" ! DLL_InFile - Name of input file sent to the DLL (-) diff --git a/ROSCO/Test_Cases/IEA-15-240-RWT-UMaineSemi/IEA-15-240-RWT-UMaineSemi_ElastoDyn.dat b/ROSCO/Test_Cases/IEA-15-240-RWT-UMaineSemi/IEA-15-240-RWT-UMaineSemi_ElastoDyn.dat index 07ca94c06..c0f6fbe79 100644 --- a/ROSCO/Test_Cases/IEA-15-240-RWT-UMaineSemi/IEA-15-240-RWT-UMaineSemi_ElastoDyn.dat +++ b/ROSCO/Test_Cases/IEA-15-240-RWT-UMaineSemi/IEA-15-240-RWT-UMaineSemi_ElastoDyn.dat @@ -120,6 +120,8 @@ True TabDelim - Use tab delimiters in text tabular output file? (fla OutList - The next line(s) contains a list of output parameters. See OutListParameters.xlsx for a listing of available output channels, (-) "Azimuth" "BldPitch1" +"BldPitch2" +"BldPitch3" "GenSpeed" "IPDefl1" "LSSGagMya" diff --git a/ROSCO/Test_Cases/IEA-15-240-RWT-UMaineSemi/IEA-15-240-RWT-UMaineSemi_MoorDyn.dat b/ROSCO/Test_Cases/IEA-15-240-RWT-UMaineSemi/IEA-15-240-RWT-UMaineSemi_MoorDyn.dat index 9032a2d8f..ecb74bd91 100644 --- a/ROSCO/Test_Cases/IEA-15-240-RWT-UMaineSemi/IEA-15-240-RWT-UMaineSemi_MoorDyn.dat +++ b/ROSCO/Test_Cases/IEA-15-240-RWT-UMaineSemi/IEA-15-240-RWT-UMaineSemi_MoorDyn.dat @@ -1,28 +1,25 @@ ---------------------- MoorDyn Input File ------------------------------------ +--------------------- MoorDyn Input File ------------------------------------ IEA 15 MW offshore reference model on UMaine VolturnUS-S semi-submersible floating platform mooring model- C. Allen UMaine FALSE Echo - echo the input file data (flag) ----------------------- LINE TYPES ------------------------------------------ -1 NTypes - number of LineTypes -Name Diam MassDen EA BA/-zeta Can Cat Cdn Cdt -(-) (m) (kg/m) (N) (N-s/-) (-) (-) (-) (-) -main 0.333 685.00 3.27E+09 -1 0.82 0.27 1.11 0.20 ----------------------- CONNECTION PROPERTIES -------------------------------- -6 NConnects - number of connections including anchors and fairleads -Node Type X Y Z M V FX FY FZ CdA CA -(-) (-) (m) (m) (m) (kg) (m^3) (kN) (kN) (kN) (m^2) (-) -1 Vessel -58.000 0.000 -14.000 0 0 0 0 0 0 0 -2 Fixed -837.600 0.000 -200.000 0 0 0 0 0 0 0 -3 Vessel 29.000 50.229 -14.000 0 0 0 0 0 0 0 -4 Fixed 418.800 725.383 -200.000 0 0 0 0 0 0 0 -5 Vessel 29.000 -50.229 -14.000 0 0 0 0 0 0 0 -6 Fixed 418.800 -725.383 -200.000 0 0 0 0 0 0 0 ----------------------- LINE PROPERTIES -------------------------------------- -3 NLines - number of line objects -Line LineType UnstrLen NumSegs NodeAnch NodeFair Flags/Outputs Control -(-) (-) (m) (-) (-) (-) (-) (-) -1 main 850.00 50 2 1 - 0 -2 main 850.00 50 4 3 - 0 -3 main 850.00 50 6 5 - 0 +Name Diam MassDen EA BA/-zeta EI Cd Ca CdAx CaAx +(-) (m) (kg/m) (N) (N-s/-) (-) (-) (-) (-) (-) +main 0.333 685.00 3.27E+09 -1 0 1.11 0.82 0.2 0.27 +---------------------- POINTS -------------------------------- +ID Type X Y Z M V CdA CA +(-) (-) (m) (m) (m) (kg) (m^3) (m^2) (-) +1 Vessel -58.000 0.000 -14.000 0 0 0 0 +2 Fixed -837.600 0.000 -200.000 0 0 0 0 +3 Vessel 29.000 50.229 -14.000 0 0 0 0 +4 Fixed 418.800 725.383 -200.000 0 0 0 0 +5 Vessel 29.000 -50.229 -14.000 0 0 0 0 +6 Fixed 418.800 -725.383 -200.000 0 0 0 0 +---------------------- LINES -------------------------------------- +ID LineType AttachA AttachB UnstrLen NumSegs Outputs +(-) (-) (-) (-) (m) (-) (-) +1 main 2 1 850.00 50 - +2 main 4 3 850.00 50 - +3 main 6 5 850.00 50 - ---------------------- SOLVER OPTIONS --------------------------------------- 0.001 dtM - time step to use in mooring integration (s) 3.0e6 kbot - bottom stiffness (Pa/m) @@ -31,7 +28,7 @@ Line LineType UnstrLen NumSegs NodeAnch NodeFair Flags/Outputs Control 60.0 TmaxIC - max time for ic gen (s) 4.0 CdScaleIC - factor by which to scale drag coefficients during dynamic relaxation (-) 0.001 threshIC - threshold for IC convergence (-) ------------------------- OUTPUTS -------------------------------------------- +------------------------ OUTPUTS -------------------------------------------- FairTen1 FairTen2 FairTen3 @@ -60,5 +57,4 @@ fx fy fz END -------------------------- need this line -------------------------------------- - +------------------------- need this line -------------------------------------- \ No newline at end of file diff --git a/ROSCO/Test_Cases/IEA-15-240-RWT-UMaineSemi/IEA-15-240-RWT-UMaineSemi_ServoDyn.dat b/ROSCO/Test_Cases/IEA-15-240-RWT-UMaineSemi/IEA-15-240-RWT-UMaineSemi_ServoDyn.dat index f402ab4be..51a09d4e8 100644 --- a/ROSCO/Test_Cases/IEA-15-240-RWT-UMaineSemi/IEA-15-240-RWT-UMaineSemi_ServoDyn.dat +++ b/ROSCO/Test_Cases/IEA-15-240-RWT-UMaineSemi/IEA-15-240-RWT-UMaineSemi_ServoDyn.dat @@ -81,7 +81,7 @@ True GenTiStp - Method to stop the generator {T: timed usin False 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] 9999.9 BPCutoff - Cuttoff frequency for low-pass filter on blade pitch from DLL (Hz) [used only with Bladed Interface] 0.0 NacYaw_North - Reference yaw angle of the nacelle when the upwind end points due North (deg) [used only with Bladed Interface] -0 Ptch_Cntrl - Record 28: Use individual pitch control {0: collective pitch; 1: individual pitch control} (switch) [used only with Bladed Interface] +1 Ptch_Cntrl - Record 28: Use individual pitch control {0: collective pitch; 1: individual pitch control} (switch) [used only with Bladed Interface] 0.0 Ptch_SetPnt - Record 5: Below-rated pitch angle set-point (deg) [used only with Bladed Interface] 0.0 Ptch_Min - Record 6: Minimum pitch angle (deg) [used only with Bladed Interface] 0.0 Ptch_Max - Record 7: Maximum pitch angle (deg) [used only with Bladed Interface] diff --git a/ROSCO/Test_Cases/IEA-15-240-RWT-UMaineSemi/IEA-15-240-RWT_AeroDyn15.dat b/ROSCO/Test_Cases/IEA-15-240-RWT-UMaineSemi/IEA-15-240-RWT_AeroDyn15.dat index 585bd715c..c2602a6f9 100644 --- a/ROSCO/Test_Cases/IEA-15-240-RWT-UMaineSemi/IEA-15-240-RWT_AeroDyn15.dat +++ b/ROSCO/Test_Cases/IEA-15-240-RWT-UMaineSemi/IEA-15-240-RWT_AeroDyn15.dat @@ -1,16 +1,17 @@ ------- AERODYN v15.03.* INPUT FILE ------------------------------------------------ IEA 15 MW Offshore Reference Turbine ====== General Options ============================================================================ -False Echo - Echo the input to ".AD.ech"? (flag) -"default" DTAero - Time interval for aerodynamic calculations {or "default"} (s) -1 WakeMod - Type of wake/induction model (switch) {0=none, 1=BEMT, 2=DBEMT, 3=OLAF} [WakeMod cannot be 2 or 3 when linearizing] -2 AFAeroMod - Type of blade airfoil aerodynamics model (switch) {1=steady model, 2=Beddoes-Leishman unsteady model} [AFAeroMod must be 1 when linearizing] -1 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} -0 TwrShadow - Calculate tower influence on wind based on downstream tower shadow (switch) {0=none, 1=Powles model, 2=Eames model} -True TwrAero - Calculate tower aerodynamic loads? (flag) -False FrozenWake - Assume frozen wake during linearization? (flag) [used only when WakeMod=1 and when linearizing] -False CavitCheck - Perform cavitation check? (flag) [AFAeroMod must be 1 when CavitCheck=true] -False CompAA - Flag to compute AeroAcoustics calculation [used only when WakeMod = 1 or 2] +False Echo - Echo the input to ".AD.ech"? (flag) +"default" DTAero - Time interval for aerodynamic calculations {or "default"} (s) +1 WakeMod - Type of wake/induction model (switch) {0=none, 1=BEMT, 2=DBEMT, 3=OLAF} [WakeMod cannot be 2 or 3 when linearizing] +2 AFAeroMod - Type of blade airfoil aerodynamics model (switch) {1=steady model, 2=Beddoes-Leishman unsteady model} [AFAeroMod must be 1 when linearizing] +1 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} +1 TwrShadow - Calculate tower influence on wind based on downstream tower shadow (switch) {0=none, 1=Powles model, 2=Eames model} +True TwrAero - Calculate tower aerodynamic loads? (flag) +False FrozenWake - Assume frozen wake during linearization? (flag) [used only when WakeMod=1 and when linearizing] +False CavitCheck - Perform cavitation check? (flag) [AFAeroMod must be 1 when CavitCheck=true] +False Buoyancy - Include buoyancy effects? (flag) +False CompAA - Flag to compute AeroAcoustics calculation [used only when WakeMod = 1 or 2] "AeroAcousticsInput.dat" AA_InputFile - AeroAcoustics input file [used only when CompAA=true] ====== Environmental Conditions =================================================================== "default" AirDens - Air density (kg/m^3) @@ -36,8 +37,6 @@ True TIDrag - Include the drag term in the tangential-ind ====== Beddoes-Leishman Unsteady Airfoil Aerodynamics Options ===================================== [used only when AFAeroMod=2] 3 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] True 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] -0.0 UAStartRad - Starting radius for dynamic stall (fraction of rotor radius) [used only when AFAeroMod=2] -1.0 UAEndRad - Ending radius for dynamic stall (fraction of rotor radius) [used only when AFAeroMod=2] ====== Airfoil Information ========================================================================= 1 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} (-) 1 InCol_Alfa - The column in the airfoil tables that contains the angle of attack (-) @@ -101,21 +100,30 @@ True UseBlCm - Include aerodynamic pitching moment in calc "IEA-15-240-RWT_AeroDyn15_blade.dat" ADBlFile(1) - Name of file containing distributed aerodynamic properties for Blade #1 (-) "IEA-15-240-RWT_AeroDyn15_blade.dat" ADBlFile(2) - Name of file containing distributed aerodynamic properties for Blade #2 (-) [unused if NumBl < 2] "IEA-15-240-RWT_AeroDyn15_blade.dat" ADBlFile(3) - Name of file containing distributed aerodynamic properties for Blade #3 (-) [unused if NumBl < 3] -====== Tower Influence and Aerodynamics ============================================================= [used only when TwrPotent/=0, TwrShadow/=0, or TwrAero=True] -11 NumTwrNds - Number of tower nodes used in the analysis (-) [used only when TwrPotent/=0, TwrShadow/=0, or TwrAero=True] -TwrElev TwrDiam TwrCd TwrTI (used only with TwrShadow=2) -(m) (m) (-) (-) - 15. 10. 0.5 0.1 - 28. 10. 0.5 0.1 - 41. 9.926 0.5 0.1 - 54. 9.443 0.5 0.1 - 67. 8.833 0.5 0.1 - 80. 8.151 0.5 0.1 - 93. 7.39 0.5 0.1 - 106. 6.909 0.5 0.1 - 119. 6.748 0.5 0.1 - 132. 6.572 0.5 0.1 - 144.386 6.5 0.5 0.1 +====== Hub Properties ============================================================================== [used only when Buoyancy=True] +0.0 VolHub - Hub volume (m^3) +0.0 HubCenBx - Hub center of buoyancy x direction offset (m) +====== Nacelle Properties ========================================================================== [used only when Buoyancy=True] +0.0 VolNac - Nacelle volume (m^3) +0,0,0 NacCenB - Position of nacelle center of buoyancy from yaw bearing in nacelle coordinates (m) +====== Tail fin Aerodynamics ======================================================================== +False TFinAero - Calculate tail fin aerodynamics model (flag) +"unused" TFinFile - Input file for tail fin aerodynamics [used only when TFinAero=True] +====== Tower Influence and Aerodynamics ============================================================ [used only when TwrPotent/=0, TwrShadow/=0, TwrAero=True, or Buoyancy=True] + 11 NumTwrNds - Number of tower nodes used in the analysis (-) [used only when TwrPotent/=0, TwrShadow/=0, TwrAero=True, or Buoyancy=True] +TwrElev TwrDiam TwrCd TwrTI TwrCb !TwrTI used only with TwrShadow=2, TwrCb used only with Buoyancy=True +(m) (m) (-) (-) (-) + 15. 10. 0.5 0.1 0.0 + 28. 10. 0.5 0.1 0.0 + 41. 9.926 0.5 0.1 0.0 + 54. 9.443 0.5 0.1 0.0 + 67. 8.833 0.5 0.1 0.0 + 80. 8.151 0.5 0.1 0.0 + 93. 7.39 0.5 0.1 0.0 + 106. 6.909 0.5 0.1 0.0 + 119. 6.748 0.5 0.1 0.0 + 132. 6.572 0.5 0.1 0.0 + 144.386 6.5 0.5 0.1 0.0 ====== Outputs ==================================================================================== True SumPrint - Generate a summary file listing input options and interpolated properties to ".AD.sum"? (flag) 9 NBlOuts - Number of blade node outputs [0 - 9] (-) @@ -123,15 +131,15 @@ True SumPrint - Generate a summary file listing input optio 0 NTwOuts - Number of tower node outputs [0 - 9] (-) 1, 2, 3, 4, 5 TwOutNd - Tower nodes whose values will be output (-) OutList - The next line(s) contains a list of output parameters. See OutListParameters.xlsx for a listing of available output channels, (-) -"RtAeroFxh" -"RtAeroFyh" -"RtAeroFzh" -"RtAeroMxh" -"RtAeroMyh" -"RtAeroMzh" +"RtFldFxh" +"RtFldFyh" +"RtFldFzh" +"RtFldMxh" +"RtFldMyh" +"RtFldMzh" "RtVAvgxh" -"RtAeroCp" -"RtAeroCt" +"RtFldCp" +"RtFldCt" "RtArea" "RtSpeed" "RtTSR" diff --git a/ROSCO/Test_Cases/NREL-5MW/DISCON.IN b/ROSCO/Test_Cases/NREL-5MW/DISCON.IN index b5a353aea..e3c2ae45a 100644 --- a/ROSCO/Test_Cases/NREL-5MW/DISCON.IN +++ b/ROSCO/Test_Cases/NREL-5MW/DISCON.IN @@ -1,5 +1,5 @@ ! Controller parameter input file for the NREL-5MW wind turbine -! - File written using ROSCO version 2.5.0 controller tuning logic on 07/22/22 +! - File written using ROSCO version 2.7.0 controller tuning logic on 02/06/23 !------- DEBUG ------------------------------------------------------------ 1 ! LoggingLevel - {0: write no debug files, 1: write standard output .dbg-file, 2: LoggingLevel 1 + ROSCO LocalVars (.dbg2) 3: LoggingLevel 2 + complete avrSWAP-array (.dbg3)} @@ -20,8 +20,9 @@ 0 ! Flp_Mode - Flap control mode {0: no flap control, 1: steady state flap angle, 2: Proportional flap control, 2: Cyclic (1P) flap control} 0 ! OL_Mode - Open loop control mode {0: no open loop control, 1: open loop control vs. time} 0 ! PA_Mode - Pitch actuator mode {0 - not used, 1 - first order filter, 2 - second order filter} +0 ! PF_Mode - Pitch fault mode {0 - not used, 1 - constant offset on one or more blades} 0 ! Ext_Mode - External control mode {0 - not used, 1 - call external dynamic library} -0 ! ZMQ_Mode - Fuse ZeroMQ interaface {0: unused, 1: Yaw Control} +0 ! ZMQ_Mode - Fuse ZeroMQ interface {0: unused, 1: Yaw Control} !------- FILTERS ---------------------------------------------------------- 1.57080 ! F_LPFCornerFreq - Corner frequency (-3dB point) in the low-pass filters, [rad/s] @@ -52,6 +53,7 @@ !------- INDIVIDUAL PITCH CONTROL ----------------------------------------- 9.120000 11.400000 ! IPC_Vramp - Start and end wind speeds for cut-in ramp function. First entry: IPC inactive, second entry: IPC fully active. [m/s] +2 ! IPC_SatMode - IPC Saturation method (0 - no saturation (except by PC_MinPit), 1 - saturate by PS_BldPitchMin, 2 - saturate sotfly (full IPC cycle) by PC_MinPit, 3 - saturate softly by PS_BldPitchMin) 0.3 ! IPC_IntSat - Integrator saturation (maximum signal amplitude contribution to pitch from IPC), [rad] 0.000e+00 0.000e+00 ! IPC_KP - Proportional gain for the individual pitch controller: first parameter for 1P reductions, second for 2P reductions, [-] 0.000e+00 0.000e+00 ! IPC_KI - Integral gain for the individual pitch controller: first parameter for 1P reductions, second for 2P reductions, [-] @@ -93,8 +95,8 @@ -0.01638154 -0.01796321 -0.01954487 -0.02112654 -0.02270820 -0.02428987 -0.02587154 -0.02745320 -0.02903487 -0.03061653 -0.03219820 -0.03377987 -0.03536153 -0.03694320 -0.03852486 -0.04010653 -0.04168820 -0.04326986 -0.04485153 -0.04643319 -0.04801486 -0.04959652 -0.05117819 -0.05275986 -0.05434152 -0.05592319 -0.05758373 -0.05882656 -0.06845507 -0.05992890 0.02094683 0.01327182 0.00285485 -0.00935731 -0.02210773 -0.03573037 -0.04990222 -0.06404904 -0.07899629 -0.09463190 -0.10954192 -0.12525205 -0.14168652 -0.15843395 -0.17415061 -0.19052486 -0.20780146 -0.22581018 -0.24373777 -0.26010871 -0.27706767 -0.29551708 -0.31430599 -0.33428552 -0.35420853 -0.37183729 -0.38936451 -0.40828911 -0.42758878 -0.44818175 ! WE_FOPoles - First order system poles [1/s] !------- YAW CONTROL ------------------------------------------------------ -0.00000 ! Y_uSwitch - Wind speed to switch between Y_ErrThresh. If zero, only the first value of Y_ErrThresh is used [m/s] -4.000000 8.000000 ! Y_ErrThresh - Yaw error threshold. Turbine begins to yaw when it passes this. If Y_uSwitch is zero, only the first value is used. [deg]. +0.00000 ! Y_uSwitch - Wind speed to switch between Y_ErrThresh. If zero, only the second value of Y_ErrThresh is used [m/s] +4.000000 8.000000 ! Y_ErrThresh - Yaw error threshold/deadbands. Turbine begins to yaw when it passes this. If Y_uSwitch is zero, only the second value is used. [deg]. 0.00870 ! Y_Rate - Yaw rate [rad/s] 0.00000 ! Y_MErrSet - Integrator saturation (maximum signal amplitude contribution to pitch from yaw-by-IPC), [rad] 0.00000 ! Y_IPC_IntSat - Integrator saturation (maximum signal amplitude contribution to pitch from yaw-by-IPC), [rad] @@ -135,6 +137,9 @@ 3.140000000000 ! PA_CornerFreq - Pitch actuator bandwidth/cut-off frequency [rad/s] 0.707000000000 ! PA_Damping - Pitch actuator damping ratio [-, unused if PA_Mode = 1] +!------- Pitch Actuator Faults ----------------------------------------------------- +0.00000000 0.00000000 0.00000000 ! PF_Offsets - Constant blade pitch offsets for blades 1-3 [rad] + !------- External Controller Interface ----------------------------------------------------- "unused" ! DLL_FileName - Name/location of the dynamic library in the Bladed-DLL format "unused" ! DLL_InFile - Name of input file sent to the DLL (-) diff --git a/ROSCO/Test_Cases/NREL-5MW/NRELOffshrBsline5MW_Onshore_AeroDyn15.dat b/ROSCO/Test_Cases/NREL-5MW/NRELOffshrBsline5MW_Onshore_AeroDyn15.dat index 0983cb2d3..b3660b01a 100644 --- a/ROSCO/Test_Cases/NREL-5MW/NRELOffshrBsline5MW_Onshore_AeroDyn15.dat +++ b/ROSCO/Test_Cases/NREL-5MW/NRELOffshrBsline5MW_Onshore_AeroDyn15.dat @@ -10,6 +10,7 @@ False Echo - Echo the input to ".AD.ech"? (flag True TwrAero - Calculate tower aerodynamic loads? (flag) False FrozenWake - Assume frozen wake during linearization? (flag) [used only when WakeMod=1 and when linearizing] False CavitCheck - Perform cavitation check? (flag) [AFAeroMod must be 1 when CavitCheck=true] +False Buoyancy - Include buoyancy effects? (flag) False CompAA - Flag to compute AeroAcoustics calculation [only used when WakeMod=1 or 2] "unused" AA_InputFile - Aeroacoustics input file ====== Environmental Conditions =================================================================== @@ -34,10 +35,8 @@ False TIDrag - Include the drag term in the tangential-induc ====== OLAF -- cOnvecting LAgrangian Filaments (Free Vortex Wake) Theory Options ================== [used only when WakeMod=3] "unused" OLAFInputFileName - Input file for OLAF [used only when WakeMod=3] ====== Beddoes-Leishman Unsteady Airfoil Aerodynamics Options ===================================== [used only when AFAeroMod=2] - 3 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] -True 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] -0.0 UAStartRad - Starting radius for dynamic stall (fraction of rotor radius) [used only when AFAeroMod=2] -1.0 UAEndRad - Ending radius for dynamic stall (fraction of rotor radius) [used only when AFAeroMod=2] +3 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] +True 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] ====== Airfoil Information ========================================================================= 1 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} (-) 1 InCol_Alfa - The column in the airfoil tables that contains the angle of attack (-) @@ -59,22 +58,31 @@ True UseBlCm - Include aerodynamic pitching moment in calcul "NRELOffshrBsline5MW_AeroDyn_blade.dat" ADBlFile(1) - Name of file containing distributed aerodynamic properties for Blade #1 (-) "NRELOffshrBsline5MW_AeroDyn_blade.dat" ADBlFile(2) - Name of file containing distributed aerodynamic properties for Blade #2 (-) [unused if NumBl < 2] "NRELOffshrBsline5MW_AeroDyn_blade.dat" ADBlFile(3) - Name of file containing distributed aerodynamic properties for Blade #3 (-) [unused if NumBl < 3] +====== Hub Properties ============================================================================== [used only when Buoyancy=True] +0.0 VolHub - Hub volume (m^3) +0.0 HubCenBx - Hub center of buoyancy x direction offset (m) +====== Nacelle Properties ========================================================================== [used only when Buoyancy=True] +0.0 VolNac - Nacelle volume (m^3) +0,0,0 NacCenB - Position of nacelle center of buoyancy from yaw bearing in nacelle coordinates (m) +====== Tail fin Aerodynamics ======================================================================== +False TFinAero - Calculate tail fin aerodynamics model (flag) +"unused" TFinFile - Input file for tail fin aerodynamics [used only when TFinAero=True] ====== Tower Influence and Aerodynamics ============================================================= [used only when TwrPotent/=0, TwrShadow=True, or TwrAero=True] 12 NumTwrNds - Number of tower nodes used in the analysis (-) [used only when TwrPotent/=0, TwrShadow=True, or TwrAero=True] -TwrElev TwrDiam TwrCd TwrTI (used only with TwrShadow=2) -(m) (m) (-) (-) -0.0000000E+00 6.0000000E+00 1.0000000E+00 1.000000E-01 -8.5261000E+00 5.7870000E+00 1.0000000E+00 1.000000E-01 -1.7053000E+01 5.5740000E+00 1.0000000E+00 1.000000E-01 -2.5579000E+01 5.3610000E+00 1.0000000E+00 1.000000E-01 -3.4105000E+01 5.1480000E+00 1.0000000E+00 1.000000E-01 -4.2633000E+01 4.9350000E+00 1.0000000E+00 1.000000E-01 -5.1158000E+01 4.7220000E+00 1.0000000E+00 1.000000E-01 -5.9685000E+01 4.5090000E+00 1.0000000E+00 1.000000E-01 -6.8211000E+01 4.2960000E+00 1.0000000E+00 1.000000E-01 -7.6738000E+01 4.0830000E+00 1.0000000E+00 1.000000E-01 -8.5268000E+01 3.8700000E+00 1.0000000E+00 1.000000E-01 -8.7600000E+01 3.8700000E+00 1.0000000E+00 1.000000E-01 +TwrElev TwrDiam TwrCd TwrTI TwrCb !TwrTI used only with TwrShadow=2, TwrCb used only with Buoyancy=True +(m) (m) (-) (-) (-) +0.0000000E+00 6.0000000E+00 1.0000000E+00 1.000000E-01 0.0 +8.5261000E+00 5.7870000E+00 1.0000000E+00 1.000000E-01 0.0 +1.7053000E+01 5.5740000E+00 1.0000000E+00 1.000000E-01 0.0 +2.5579000E+01 5.3610000E+00 1.0000000E+00 1.000000E-01 0.0 +3.4105000E+01 5.1480000E+00 1.0000000E+00 1.000000E-01 0.0 +4.2633000E+01 4.9350000E+00 1.0000000E+00 1.000000E-01 0.0 +5.1158000E+01 4.7220000E+00 1.0000000E+00 1.000000E-01 0.0 +5.9685000E+01 4.5090000E+00 1.0000000E+00 1.000000E-01 0.0 +6.8211000E+01 4.2960000E+00 1.0000000E+00 1.000000E-01 0.0 +7.6738000E+01 4.0830000E+00 1.0000000E+00 1.000000E-01 0.0 +8.5268000E+01 3.8700000E+00 1.0000000E+00 1.000000E-01 0.0 +8.7600000E+01 3.8700000E+00 1.0000000E+00 1.000000E-01 0.0 ====== Outputs ==================================================================================== True SumPrint - Generate a summary file listing input options and interpolated properties to ".AD.sum"? (flag) 0 NBlOuts - Number of blade node outputs [0 - 9] (-) @@ -82,5 +90,17 @@ True SumPrint - Generate a summary file listing input option 0 NTwOuts - Number of tower node outputs [0 - 9] (-) 1, 2, 6 TwOutNd - Tower nodes whose values will be output (-) OutList - The next line(s) contains a list of output parameters. See OutListParameters.xlsx for a listing of available output channels, (-) +"RtFldFxh" +"RtFldFyh" +"RtFldFzh" +"RtFldMxh" +"RtFldMyh" +"RtFldMzh" +"RtVAvgxh" +"RtFldCp" +"RtFldCt" +"RtArea" +"RtSpeed" +"RtTSR" END of input file (the word "END" must appear in the first 3 columns of this last OutList line) --------------------------------------------------------------------------------------- diff --git a/ROSCO/Tune_Cases/tune_ROSCO.py b/ROSCO/Tune_Cases/tune_ROSCO.py deleted file mode 100644 index f06319365..000000000 --- a/ROSCO/Tune_Cases/tune_ROSCO.py +++ /dev/null @@ -1,68 +0,0 @@ -# Controller Tuning Script for NREL-5MW Wind Turbine -# -- Made to run the tools distributed as a part of the ROSCO_Toolbox -import os - -#-------------------------------- LOAD INPUT PARAMETERS ---------------------------------# -# Change this for your turbine -this_dir = os.path.dirname(__file__) -parameter_filename = os.path.join(this_dir,'IEA15MW.yaml') # Name of .yaml input file for the specific turbine - - - - -#--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------# -#--------------------- NOTHING SHOULD NEED TO CHANGE AFTER THIS -----------------------------------------------------------------------------------------------------------------# -#--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------# - - -#------------------------------------- INITIALIZATION ----------------------------------# -# Import python modules -import matplotlib.pyplot as plt -import yaml -# Import ROSCO_toolbox modules -from ROSCO_toolbox import controller as ROSCO_controller -from ROSCO_toolbox import turbine as ROSCO_turbine -from ROSCO_toolbox.utilities import write_rotor_performance, write_DISCON -from ROSCO_toolbox.inputs.validation import load_rosco_yaml - -# Initialize parameter dictionaries -turbine_params = {} -control_params = {} - -# Load input file contents, put them in some dictionaries to keep things cleaner -inps = load_rosco_yaml(parameter_filename) -path_params = inps['path_params'] -turbine_params = inps['turbine_params'] -controller_params = inps['controller_params'] - -#---------------------------------- DO THE FUN STUFF ------------------------------------# -# Initialiize turbine and controller -turbine = ROSCO_turbine.Turbine(turbine_params) - -# Load Turbine, write rotor performance file if it doesn't exist -if os.path.exists(os.path.join(this_dir,path_params['rotor_performance_filename'])): - turbine.load_from_fast(path_params['FAST_InputFile'], \ - os.path.join(this_dir,path_params['FAST_directory']), \ - dev_branch=True,rot_source='txt',txt_filename=path_params['rotor_performance_filename']) -else: - turbine.load_from_fast(path_params['FAST_InputFile'], \ - os.path.join(this_dir,path_params['FAST_directory']), \ - dev_branch=True,rot_source=None, txt_filename=path_params['rotor_performance_filename']) - - write_rotor_performance(turbine,txt_filename=os.path.join(this_dir,path_params['rotor_performance_filename'])) - -# Flap tuning if necessary -if controller_params['Flp_Mode']: - turbine.load_blade_info() - -# Instantiate controller tuning and tune controller -controller = ROSCO_controller.Controller(controller_params) -controller.tune_controller(turbine) - -# Write parameter input file -param_file = 'DISCON.IN' -write_DISCON(turbine,controller,param_file=param_file, txt_filename=os.path.join(this_dir,path_params['rotor_performance_filename'])) - -# Plot rotor performance -turbine.Cp.plot_performance() -plt.show() diff --git a/ROSCO/docs/source/api_change.rst b/ROSCO/docs/source/api_change.rst index 9efdd8db4..f6ad8a574 100644 --- a/ROSCO/docs/source/api_change.rst +++ b/ROSCO/docs/source/api_change.rst @@ -9,6 +9,26 @@ The changes are tabulated according to the line number, and flag name. 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. +2.6.0 to 2.7.0 +------------------------------- +Pitch Faults +- Constant pitch actuator offsets (PF_Mode = 1) +IPC Saturation Modes +- Added options for saturating the IPC command with the peak shaving limit + +====== ================= ====================================================================================================================================================================================================== +New in ROSCO 2.7.0 +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +Line Input Name Example Value +====== ================= ====================================================================================================================================================================================================== +23 PF_Mode 0 ! PF_Mode - Pitch fault mode {0 - not used, 1 - constant offset on one or more blades} +56 IPC_SatMode 2 ! IPC_SatMode - IPC Saturation method (0 - no saturation (except by PC_MinPit), 1 - saturate by PS_BldPitchMin, 2 - saturate sotfly (full IPC cycle) by PC_MinPit, 3 - saturate softly by PS_BldPitchMin) +139 PF_Section !------- Pitch Actuator Faults --------------------------------------------------------- +140 PF_Offsets 0.00000000 0.00000000 0.00000000 ! PF_Offsets - Constant blade pitch offsets for blades 1-3 [rad] +141 Empty Line +====== ================= ====================================================================================================================================================================================================== + + 2.5.0 to 2.6.0 ------------------------------- IPC @@ -27,7 +47,7 @@ Updated yaw control - Filter wind direction with deadband, and yaw until direction error changes signs (https://iopscience.iop.org/article/10.1088/1742-6596/1037/3/032011) ====== ================= ====================================================================================================================================================================================================== -New in ROSCO develop +New in ROSCO 2.6.0 ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Line Input Name Example Value ====== ================= ====================================================================================================================================================================================================== @@ -54,17 +74,17 @@ Line Input Name Example Value ====== ================= ====================================================================================================================================================================================================== ====== ================= ====================================================================================================================================================================================================== -Modified in ROSCO develop +Modified in ROSCO 2.6.0 ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Line Input Name Example Value ====== ================= ====================================================================================================================================================================================================== -97 Y_ErrThresh 4.000000 8.000000 ! Y_ErrThresh - Yaw error threshold/deadband. Turbine begins to yaw when it passes this. If Y_uSwitch is zero, only the first value is used. [deg]. +97 Y_ErrThresh 4.000000 8.000000 ! Y_ErrThresh - Yaw error threshold/deadbands. Turbine begins to yaw when it passes this. If Y_uSwitch is zero, only the second value is used. [deg]. 98 Y_Rate 0.00870 ! Y_Rate - Yaw rate [rad/s] 99 Y_MErrSet 0.00000 ! Y_MErrSet - Integrator saturation (maximum signal amplitude contribution to pitch from yaw-by-IPC), [rad] ====== ================= ====================================================================================================================================================================================================== ====== ================= ====================================================================================================================================================================================================== -Removed in ROSCO develop +Removed in ROSCO 2.6.0 ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Line Input Name Example Value ====== ================= ====================================================================================================================================================================================================== diff --git a/ROSCO/docs/source/install.rst b/ROSCO/docs/source/install.rst index 29a71620a..ecd12be2d 100644 --- a/ROSCO/docs/source/install.rst +++ b/ROSCO/docs/source/install.rst @@ -104,6 +104,7 @@ On Mac/Linux, standard compilers are generally available without any additional .. code-block:: bash conda install m2w64-toolchain libpython + conda install cmake make # if Windows users would like to install these in anaconda environment Once the CMake and the required compilers are downloaded, the following code can be used to compile ROSCO. @@ -181,17 +182,17 @@ Full ROSCO Installation We recommend using the full ROSCO tool-chain. This allows for full use of the provided functions along with the developed python packages and controller code, -Please follow the following steps to install the ROSCO tool-chain. You should do step 3 *or* 4. If you simply want to install the ROSCO toolbox without the controller, do step 3. If you would like to install the ROSCO toolbox and compile the controller simultaneously, do step 4. +Please follow the following steps to install the ROSCO tool-chain. You should do step 2 *or* 3. If you simply want to install the ROSCO toolbox without the controller, do step 3. If you would like to install the ROSCO toolbox and compile the controller simultaneously, do step 2. 1. Create a conda environment for ROSCO .. code-block:: bash - conda config --add channels conda-forge - conda create -y --name rosco-env python=3.8 - conda activate rosco-env + conda config --add channels conda-forge # (Enable Conda-forge Channel For Conda Package Manager) + conda create -y --name rosco-env python=3.8 # (Create a new environment named "rosco-env" that contains Python 3.8) + conda activate rosco-env # (Activate your "rosco-env" environment) -2. Clone and Install the ROSCO toolbox with ROSCO +2. Clone and Install the ROSCO toolbox with ROSCO controller .. code-block:: bash @@ -199,10 +200,11 @@ Please follow the following steps to install the ROSCO tool-chain. You should do cd ROSCO conda install compilers # (Mac/Linux only) conda install m2w64-toolchain libpython # (Windows only) - conda install -y wisdem + conda env config vars set FC=gfortran # Sometimes needed for Windows + conda install -y wisdem=3.5.0 python setup.py install --compile-rosco -3. Clone and Install the ROSCO toolbox without ROSCO +3. Clone and Install the ROSCO toolbox without ROSCO controller .. code-block:: bash diff --git a/ROSCO/docs/source/toolbox_input.rst b/ROSCO/docs/source/toolbox_input.rst index a3b477292..2c11d648a 100644 --- a/ROSCO/docs/source/toolbox_input.rst +++ b/ROSCO/docs/source/toolbox_input.rst @@ -9,7 +9,7 @@ ROSCO_Toolbox tuning .yaml Definition of inputs for ROSCO tuning procedure -toolbox_schema. +toolbox_schema @@ -256,6 +256,15 @@ controller_params *Minimum* = 0 *Maximum* = 2 +:code:`PF_Mode` : Float + Pitch fault mode {0 - not used, 1 - constant offset on one or more + blades} + + *Default* = 0 + + *Minimum* = 0 *Maximum* = 1 + + :code:`Ext_Mode` : Float External control mode {{0 - not used, 1 - call external dynamic library}} @@ -688,6 +697,10 @@ These are pass-through parameters for the DISCON.IN file. Use with caution. Integrator saturation (maximum signal amplitude contribution to pitch from IPC) +:code:`IPC_SatMode` : Integer + IPC Saturation method (0 - no saturation, 1 - saturate by + PC_MinPit, 2 - saturate by PS_BldPitchMin) + :code:`IPC_KP` : Array of Floats Proportional gain for the individual pitch controller- first parameter for 1P reductions, second for 2P reductions, [-] @@ -909,6 +922,9 @@ These are pass-through parameters for the DISCON.IN file. Use with caution. *Default* = DISCON +:code:`PF_Offsets` : Array of Floats + Pitch angle offsets for each blade (array with length of 3) + linmodel_tuning diff --git a/ROSCO/setup.py b/ROSCO/setup.py index ee6816479..70fa943fe 100644 --- a/ROSCO/setup.py +++ b/ROSCO/setup.py @@ -33,10 +33,10 @@ NAME = 'rosco' DESCRIPTION = 'A reference open source controller toolset for wind turbine applications.' URL = 'https://github.com/NREL/ROSCO' -EMAIL = 'nikhar.abbas@nrel.gov' +EMAIL = 'daniel.zalkind@nrel.gov' AUTHOR = 'NREL, National Wind Technology Center' REQUIRES_PYTHON = '>=3.4' -VERSION = '2.6.0' +VERSION = '2.7.0' # These packages are required for all of the code to be executed. # - Maybe you can get away with older versions... diff --git a/examples/01_aeroelasticse/OpenFAST_models/IEA-15-240-RWT/IEA-15-240-RWT-Monopile/DISCON-Monopile.IN b/examples/01_aeroelasticse/OpenFAST_models/IEA-15-240-RWT/IEA-15-240-RWT-Monopile/DISCON-Monopile.IN index 178c26003..76c74eec0 100644 --- a/examples/01_aeroelasticse/OpenFAST_models/IEA-15-240-RWT/IEA-15-240-RWT-Monopile/DISCON-Monopile.IN +++ b/examples/01_aeroelasticse/OpenFAST_models/IEA-15-240-RWT/IEA-15-240-RWT-Monopile/DISCON-Monopile.IN @@ -1,5 +1,5 @@ ! Controller parameter input file for the IEA-15-240-RWT-Monopile wind turbine -! - File written using ROSCO version 2.6.0 controller tuning logic on 08/10/22 +! - File written using ROSCO version 2.7.0 controller tuning logic on 02/10/23 !------- DEBUG ------------------------------------------------------------ 1 ! LoggingLevel - {0: write no debug files, 1: write standard output .dbg-file, 2: LoggingLevel 1 + ROSCO LocalVars (.dbg2) 3: LoggingLevel 2 + complete avrSWAP-array (.dbg3)} @@ -20,8 +20,9 @@ 0 ! Flp_Mode - Flap control mode {0: no flap control, 1: steady state flap angle, 2: Proportional flap control, 2: Cyclic (1P) flap control} 0 ! OL_Mode - Open loop control mode {0: no open loop control, 1: open loop control vs. time} 0 ! PA_Mode - Pitch actuator mode {0 - not used, 1 - first order filter, 2 - second order filter} +0 ! PF_Mode - Pitch fault mode {0 - not used, 1 - constant offset on one or more blades} 0 ! Ext_Mode - External control mode {0 - not used, 1 - call external dynamic library} -0 ! ZMQ_Mode - Fuse ZeroMQ interaface {0: unused, 1: Yaw Control} +0 ! ZMQ_Mode - Fuse ZeroMQ interface {0: unused, 1: Yaw Control} !------- FILTERS ---------------------------------------------------------- 1.00810 ! F_LPFCornerFreq - Corner frequency (-3dB point) in the low-pass filters, [rad/s] @@ -52,6 +53,7 @@ !------- INDIVIDUAL PITCH CONTROL ----------------------------------------- 8.472000 10.590000 ! IPC_Vramp - Start and end wind speeds for cut-in ramp function. First entry: IPC inactive, second entry: IPC fully active. [m/s] +2 ! IPC_SatMode - IPC Saturation method (0 - no saturation (except by PC_MinPit), 1 - saturate by PS_BldPitchMin, 2 - saturate sotfly (full IPC cycle) by PC_MinPit, 3 - saturate softly by PS_BldPitchMin) 0.3 ! IPC_IntSat - Integrator saturation (maximum signal amplitude contribution to pitch from IPC), [rad] 0.000e+00 0.000e+00 ! IPC_KP - Proportional gain for the individual pitch controller: first parameter for 1P reductions, second for 2P reductions, [-] 0.000e+00 0.000e+00 ! IPC_KI - Integral gain for the individual pitch controller: first parameter for 1P reductions, second for 2P reductions, [-] @@ -93,8 +95,8 @@ -0.02465686 -0.02680796 -0.02895906 -0.03111016 -0.03326126 -0.03541236 -0.03756345 -0.03971455 -0.04186565 -0.04401675 -0.04616785 -0.04831895 -0.05047005 -0.05262115 -0.05477224 -0.05692334 -0.05907444 -0.06122554 -0.06337664 -0.06552774 -0.06767884 -0.06982993 -0.07198103 -0.07413213 -0.07628323 -0.07843433 -0.08058543 -0.08273653 -0.08488763 -0.08437319 -0.05533848 -0.05796693 -0.06461721 -0.07329774 -0.08334692 -0.09440458 -0.10626594 -0.11880543 -0.13196165 -0.14566704 -0.15985206 -0.17448133 -0.18958161 -0.20511150 -0.22101041 -0.23735050 -0.25401237 -0.27107323 -0.28848244 -0.30624857 -0.32435142 -0.34277122 -0.36152503 -0.38058409 -0.39991468 -0.41959174 -0.43951785 -0.45972013 -0.48018912 -0.50091553 ! WE_FOPoles - First order system poles [1/s] !------- YAW CONTROL ------------------------------------------------------ -0.00000 ! Y_uSwitch - Wind speed to switch between Y_ErrThresh. If zero, only the first value of Y_ErrThresh is used [m/s] -4.000000 8.000000 ! Y_ErrThresh - Yaw error threshold/deadband. Turbine begins to yaw when it passes this. If Y_uSwitch is zero, only the first value is used. [deg]. +0.00000 ! Y_uSwitch - Wind speed to switch between Y_ErrThresh. If zero, only the second value of Y_ErrThresh is used [m/s] +4.000000 8.000000 ! Y_ErrThresh - Yaw error threshold/deadbands. Turbine begins to yaw when it passes this. If Y_uSwitch is zero, only the second value is used. [deg]. 0.00870 ! Y_Rate - Yaw rate [rad/s] 0.00000 ! Y_MErrSet - Integrator saturation (maximum signal amplitude contribution to pitch from yaw-by-IPC), [rad] 0.00000 ! Y_IPC_IntSat - Integrator saturation (maximum signal amplitude contribution to pitch from yaw-by-IPC), [rad] @@ -135,6 +137,9 @@ 3.140000000000 ! PA_CornerFreq - Pitch actuator bandwidth/cut-off frequency [rad/s] 0.707000000000 ! PA_Damping - Pitch actuator damping ratio [-, unused if PA_Mode = 1] +!------- Pitch Actuator Faults ----------------------------------------------------- +0.00000000 0.00000000 0.00000000 ! PF_Offsets - Constant blade pitch offsets for blades 1-3 [rad] + !------- External Controller Interface ----------------------------------------------------- "unused" ! DLL_FileName - Name/location of the dynamic library in the Bladed-DLL format "unused" ! DLL_InFile - Name of input file sent to the DLL (-) diff --git a/examples/01_aeroelasticse/OpenFAST_models/IEA-15-240-RWT/IEA-15-240-RWT-UMaineSemi/DISCON-UMaineSemi.IN b/examples/01_aeroelasticse/OpenFAST_models/IEA-15-240-RWT/IEA-15-240-RWT-UMaineSemi/DISCON-UMaineSemi.IN index 4ca32b732..117989167 100644 --- a/examples/01_aeroelasticse/OpenFAST_models/IEA-15-240-RWT/IEA-15-240-RWT-UMaineSemi/DISCON-UMaineSemi.IN +++ b/examples/01_aeroelasticse/OpenFAST_models/IEA-15-240-RWT/IEA-15-240-RWT-UMaineSemi/DISCON-UMaineSemi.IN @@ -1,5 +1,5 @@ ! Controller parameter input file for the IEA-15-240-RWT-UMaineSemi wind turbine -! - File written using ROSCO version 2.6.0 controller tuning logic on 08/10/22 +! - File written using ROSCO version 2.7.0 controller tuning logic on 02/10/23 !------- DEBUG ------------------------------------------------------------ 1 ! LoggingLevel - {0: write no debug files, 1: write standard output .dbg-file, 2: LoggingLevel 1 + ROSCO LocalVars (.dbg2) 3: LoggingLevel 2 + complete avrSWAP-array (.dbg3)} @@ -20,8 +20,9 @@ 0 ! Flp_Mode - Flap control mode {0: no flap control, 1: steady state flap angle, 2: Proportional flap control, 2: Cyclic (1P) flap control} 0 ! OL_Mode - Open loop control mode {0: no open loop control, 1: open loop control vs. time} 0 ! PA_Mode - Pitch actuator mode {0 - not used, 1 - first order filter, 2 - second order filter} +0 ! PF_Mode - Pitch fault mode {0 - not used, 1 - constant offset on one or more blades} 0 ! Ext_Mode - External control mode {0 - not used, 1 - call external dynamic library} -0 ! ZMQ_Mode - Fuse ZeroMQ interaface {0: unused, 1: Yaw Control} +0 ! ZMQ_Mode - Fuse ZeroMQ interface {0: unused, 1: Yaw Control} !------- FILTERS ---------------------------------------------------------- 1.00810 ! F_LPFCornerFreq - Corner frequency (-3dB point) in the low-pass filters, [rad/s] @@ -52,6 +53,7 @@ !------- INDIVIDUAL PITCH CONTROL ----------------------------------------- 8.592000 10.740000 ! IPC_Vramp - Start and end wind speeds for cut-in ramp function. First entry: IPC inactive, second entry: IPC fully active. [m/s] +2 ! IPC_SatMode - IPC Saturation method (0 - no saturation (except by PC_MinPit), 1 - saturate by PS_BldPitchMin, 2 - saturate sotfly (full IPC cycle) by PC_MinPit, 3 - saturate softly by PS_BldPitchMin) 0.3 ! IPC_IntSat - Integrator saturation (maximum signal amplitude contribution to pitch from IPC), [rad] 0.000e+00 0.000e+00 ! IPC_KP - Proportional gain for the individual pitch controller: first parameter for 1P reductions, second for 2P reductions, [-] 0.000e+00 0.000e+00 ! IPC_KI - Integral gain for the individual pitch controller: first parameter for 1P reductions, second for 2P reductions, [-] @@ -93,8 +95,8 @@ -0.02465686 -0.02685047 -0.02904408 -0.03123769 -0.03343130 -0.03562491 -0.03781853 -0.04001214 -0.04220575 -0.04439936 -0.04659297 -0.04878658 -0.05098019 -0.05317380 -0.05536741 -0.05756102 -0.05975463 -0.06194824 -0.06414185 -0.06633546 -0.06852907 -0.07072268 -0.07291629 -0.07510990 -0.07730351 -0.07949712 -0.08169074 -0.08388435 -0.08607796 -0.08367786 -0.05601496 -0.05845251 -0.06491969 -0.07343523 -0.08331020 -0.09419764 -0.10588646 -0.11825801 -0.13123772 -0.14476398 -0.15881875 -0.17327736 -0.18819599 -0.20358260 -0.21929818 -0.23545859 -0.25196259 -0.26884815 -0.28608407 -0.30367233 -0.32159721 -0.33983661 -0.35840660 -0.37728873 -0.39643034 -0.41591476 -0.43565664 -0.45565512 -0.47592625 -0.49646875 ! WE_FOPoles - First order system poles [1/s] !------- YAW CONTROL ------------------------------------------------------ -0.00000 ! Y_uSwitch - Wind speed to switch between Y_ErrThresh. If zero, only the first value of Y_ErrThresh is used [m/s] -4.000000 8.000000 ! Y_ErrThresh - Yaw error threshold/deadband. Turbine begins to yaw when it passes this. If Y_uSwitch is zero, only the first value is used. [deg]. +0.00000 ! Y_uSwitch - Wind speed to switch between Y_ErrThresh. If zero, only the second value of Y_ErrThresh is used [m/s] +4.000000 8.000000 ! Y_ErrThresh - Yaw error threshold/deadbands. Turbine begins to yaw when it passes this. If Y_uSwitch is zero, only the second value is used. [deg]. 0.00870 ! Y_Rate - Yaw rate [rad/s] 0.00000 ! Y_MErrSet - Integrator saturation (maximum signal amplitude contribution to pitch from yaw-by-IPC), [rad] 0.00000 ! Y_IPC_IntSat - Integrator saturation (maximum signal amplitude contribution to pitch from yaw-by-IPC), [rad] @@ -135,6 +137,9 @@ 3.140000000000 ! PA_CornerFreq - Pitch actuator bandwidth/cut-off frequency [rad/s] 0.707000000000 ! PA_Damping - Pitch actuator damping ratio [-, unused if PA_Mode = 1] +!------- Pitch Actuator Faults ----------------------------------------------------- +0.00000000 0.00000000 0.00000000 ! PF_Offsets - Constant blade pitch offsets for blades 1-3 [rad] + !------- External Controller Interface ----------------------------------------------------- "unused" ! DLL_FileName - Name/location of the dynamic library in the Bladed-DLL format "unused" ! DLL_InFile - Name of input file sent to the DLL (-) diff --git a/weis/aeroelasticse/LinearFAST.py b/weis/aeroelasticse/LinearFAST.py index 0e3170cae..cda6baecb 100644 --- a/weis/aeroelasticse/LinearFAST.py +++ b/weis/aeroelasticse/LinearFAST.py @@ -35,7 +35,6 @@ def __init__(self, **kwargs): self.FAST_InputFile = None self.FAST_directory = None self.FAST_runDirectory = None - self.dev_branch = True self.read_yaml = False self.FAST_yamlfile_in = '' diff --git a/weis/control/tune_rosco.py b/weis/control/tune_rosco.py index 84f1f2fbe..6bb014219 100644 --- a/weis/control/tune_rosco.py +++ b/weis/control/tune_rosco.py @@ -538,7 +538,7 @@ def setup(self): self.turbine = ROSCO_turbine.Turbine(self.turbine_params) # Load turbine data from OpenFAST and compute Cp surface here - self.turbine.load_from_fast(FAST_InputFile, FAST_directory, dev_branch=True) + self.turbine.load_from_fast(FAST_InputFile, FAST_directory) self.add_output('rotor_inertia', val=0.0, units='kg*m**2', desc='Rotor inertia') self.add_output('rho', val=0.0, units='kg/m**3', desc='Air Density')