diff --git a/.gitignore b/.gitignore index aaac7c06a..3da1c9327 100644 --- a/.gitignore +++ b/.gitignore @@ -29,8 +29,10 @@ _build *.outb *.dbg -# Fortran files +# ROSCO files *.85 +*.i90 +*local* # Binaries *.dylib @@ -52,3 +54,7 @@ Matlab_Toolbox/*.slxc # Exclude testing results ROSCO_testing/results/ + +# Simulink/Matlab temp files +*.slxc +*.autosave diff --git a/Examples/DISCON.IN b/Examples/DISCON.IN index 523448349..206ad5503 100644 --- a/Examples/DISCON.IN +++ b/Examples/DISCON.IN @@ -1,45 +1,45 @@ -! Controller parameter input file for the NREL-5MW wind turbine -! - File written using ROSCO Controller tuning logic on 12/17/20 +! Controller parameter input file for the IEA-15-240-RWT-UMaineSemi wind turbine +! - File written using ROSCO version 2.1.1 controller tuning logic on 02/04/21 !------- 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 ------------------------------------------------- -1 ! F_LPFType - {1: first-order low-pass filter, 2: second-order low-pass filter}, [rad/s] (currently filters generator speed and pitch control signals -0 ! 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} +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} 2 ! 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} -0 ! 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} -0 ! PS_Mode - Pitch saturation mode {0: no pitch saturation, 1: implement pitch saturation} +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} +1 ! 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.57080 ! F_LPFCornerFreq - Corner frequency (-3dB point) in the low-pass filters, [rad/s] -0.00000 ! F_LPFDamping - Damping coefficient [used only when F_FilterType = 2] -0.44990 ! F_NotchCornerFreq - Natural frequency of the notch filter, [rad/s] +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.23250 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, -]. -0.00000 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, -]. +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.000000 0.055534 0.083631 0.106008 0.125390 0.142939 0.159177 0.174442 0.188870 0.202686 0.215959 0.228773 0.241173 0.253254 0.264982 0.276438 0.287644 0.298587 0.309327 0.319883 0.330260 0.340461 0.350473 0.360332 0.370046 0.379623 0.389066 0.398385 ! PC_GS_angles - Gain-schedule table: pitch angles --0.019261 -0.016189 -0.013852 -0.012014 -0.010531 -0.009308 -0.008284 -0.007413 -0.006663 -0.006010 -0.005437 -0.004931 -0.004479 -0.004074 -0.003709 -0.003378 -0.003077 -0.002801 -0.002549 -0.002316 -0.002100 -0.001901 -0.001715 -0.001542 -0.001381 -0.001230 -0.001088 -0.000954 ! PC_GS_KP - Gain-schedule table: pitch controller kp gains --0.006968 -0.006022 -0.005302 -0.004736 -0.004279 -0.003903 -0.003587 -0.003319 -0.003088 -0.002887 -0.002710 -0.002554 -0.002415 -0.002290 -0.002178 -0.002076 -0.001983 -0.001898 -0.001820 -0.001749 -0.001682 -0.001621 -0.001564 -0.001510 -0.001461 -0.001414 -0.001370 -0.001329 ! 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) +30 ! PC_GS_n - Amount of gain-scheduling table entries +0.000000 0.061302 0.088725 0.110460 0.129231 0.146101 0.161618 0.176096 0.189763 0.202765 0.215213 0.227190 0.238754 0.249961 0.260854 0.271463 0.281817 0.291944 0.301857 0.311577 0.321120 0.330501 0.339728 0.348811 0.357760 0.366583 0.375288 0.383879 0.392362 0.400744 ! PC_GS_angles - Gain-schedule table: pitch angles +-1.918261 -1.686902 -1.496241 -1.336407 -1.200485 -1.083480 -0.981701 -0.892358 -0.813301 -0.742853 -0.679678 -0.622707 -0.571067 -0.524044 -0.481046 -0.441577 -0.405219 -0.371619 -0.340474 -0.311524 -0.284547 -0.259345 -0.235751 -0.213614 -0.192804 -0.173205 -0.154715 -0.137241 -0.120702 ! PC_GS_KP - Gain-schedule table: pitch controller kp gains +-0.295306 -0.266827 -0.243358 -0.223684 -0.206953 -0.192551 -0.180022 -0.169025 -0.159294 -0.150622 -0.142846 -0.135833 -0.129477 -0.123688 -0.118396 -0.113537 -0.109062 -0.104926 -0.101092 -0.097529 -0.094208 -0.091106 -0.088202 -0.085477 -0.082915 -0.080503 -0.078227 -0.076076 -0.074040 ! 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 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 0.0 ! PC_GS_TF - Gain-schedule table: pitch controller tf gains (derivative filter) 1.570800000000 ! PC_MaxPit - Maximum physical pitch limit, [rad]. --0.00873000000 ! PC_MinPit - Minimum physical pitch limit, [rad]. -0.174500000000 ! PC_MaxRat - Maximum pitch rate (in absolute value) in pitch controller, [rad/s]. --0.17450000000 ! PC_MinRat - Minimum pitch rate (in absolute value) in pitch controller, [rad/s]. -122.9096700000 ! PC_RefSpd - Desired (reference) HSS speed for pitch controller, [rad/s]. --0.00873000000 ! PC_FinePit - Record 5: Below-rated pitch angle set-point, [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 ----------------------------------------- @@ -49,38 +49,38 @@ 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 ------------------------------------------------ -94.40000000000 ! VS_GenEff - Generator efficiency mechanical power -> electrical power, [should match the efficiency defined in the generator properties!], [%] -43093.51876000 ! VS_ArSatTq - Above rated generator torque PI control saturation, [Nm] -1500000.000000 ! VS_MaxRat - Maximum torque rate (in absolute value) in torque controller, [Nm/s]. -47402.87063000 ! VS_MaxTq - Maximum generator torque in Region 3 (HSS side), [Nm]. +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]. -34.68909000000 ! VS_MinOMSpd - Optimal mode minimum speed, cut-in speed towards optimal mode gain path, [rad/s] -2.526550000000 ! VS_Rgn2K - Generator torque constant in Region 2 (HSS side), [N-m/(rad/s)^2] -5000000.000000 ! VS_RtPwr - Wind turbine rated power [W] -43093.51876000 ! VS_RtTq - Rated torque, [Nm]. -122.9096700000 ! VS_RefSpd - Rated generator speed [rad/s] +0.523600000000 ! VS_MinOMSpd - Optimal mode minimum speed, cut-in speed towards optimal mode gain path, [rad/s] +34937749.21735 ! 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 --998.986000000 ! 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) --185.790360000 ! VS_KI - Integral gain for generator PI torque controller [1/rad Nm]. (Only used in the transitional 2.5 region if VS_ControlMode =/ 2) -7.51 ! VS_TSRopt - Power-maximizing region 2 tip-speed-ratio [rad]. +-38005940.32297 ! 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 --------------------------------------------- -63.000 ! WE_BladeRadius - Blade length (distance from hub center to blade tip), [m] +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] -97.0 ! WE_GearboxRatio - Gearbox ratio [>=1], [-] -43702538.05700 ! WE_Jtot - Total drivetrain inertia, including blades, hub and casted generator inertia to LSS, [kg m^2] +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.NREL5MW.txt" ! PerfFileName - File containing rotor performance tables (Cp,Ct,Cq) -52 24 ! PerfTableSize - Size of rotor performance tables, first number refers to number of blade pitch angles, second number referse to number of tip-speed ratios -45 ! 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.00 11.40 11.90 12.40 12.90 13.40 13.90 14.40 14.90 15.40 15.90 16.40 16.90 17.40 17.90 18.40 18.90 19.40 19.90 20.40 20.90 21.40 21.90 22.40 22.90 23.40 23.90 24.40 24.90 ! WE_FOPoles_v - Wind speeds corresponding to first-order system poles [m/s] --0.01770597 -0.02065697 -0.02360796 -0.02655896 -0.02950995 -0.03246095 -0.03541194 -0.03836294 -0.04131393 -0.04426493 -0.04721592 -0.05016692 -0.05311791 -0.05606891 -0.05901990 -0.06197090 -0.06492189 -0.05552595 -0.05550495 -0.06612150 -0.07823391 -0.09181547 -0.10541082 -0.12063288 -0.13526687 -0.15098364 -0.16805193 -0.18381181 -0.20083198 -0.21911394 -0.23737327 -0.25461250 -0.27320900 -0.29297106 -0.31361831 -0.33167820 -0.35038172 -0.37015848 -0.39096899 -0.41270837 -0.43763254 -0.47283160 -0.50939485 -0.54727356 -0.58644343 ! WE_FOPoles - First order system poles +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.00 11.90 12.40 12.90 13.40 13.90 14.40 14.90 15.40 15.90 16.40 16.90 17.40 17.90 18.40 18.90 19.40 19.90 20.40 20.90 21.40 21.90 22.40 22.90 23.40 23.90 24.40 24.90 ! WE_FOPoles_v - Wind speeds corresponding to first-order system poles [m/s] +-0.01651600 -0.01926866 -0.02202133 -0.02477399 -0.02752666 -0.03027933 -0.03303199 -0.03578466 -0.03853732 -0.04128999 -0.04404266 -0.04679532 -0.04954799 -0.05230065 -0.05505332 -0.05780599 -0.06055865 -0.05136706 -0.06083297 -0.07318141 -0.08698814 -0.10174996 -0.11701540 -0.13277020 -0.14916461 -0.16625567 -0.18314382 -0.20108255 -0.21861726 -0.23708646 -0.25523482 -0.27455940 -0.29291942 -0.31337978 -0.33196662 -0.35213321 -0.37322194 -0.39245925 -0.41381198 -0.43612755 -0.45572506 -0.47749086 -0.50133095 -0.53269989 ! WE_FOPoles - First order system poles [1/s] !------- YAW CONTROL ------------------------------------------------------ 0.0 ! Y_ErrThresh - Yaw error threshold. Turbine begins to yaw when it passes this. [rad^2 s] @@ -101,16 +101,16 @@ 0.0 ! FA_IntSat - Integrator saturation (maximum signal amplitude contribution to pitch from FA damper), [rad] !------- MINIMUM PITCH SATURATION ------------------------------------------- -45 ! 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.00 11.40 11.90 12.40 12.90 13.40 13.90 14.40 14.90 15.40 15.90 16.40 16.90 17.40 17.90 18.40 18.90 19.40 19.90 20.40 20.90 21.40 21.90 22.40 22.90 23.40 23.90 24.40 24.90 ! PS_WindSpeeds - Wind speeds corresponding to minimum blade pitch angles [m/s] --0.00872665 -0.00872665 -0.00872665 -0.00872665 -0.00872665 -0.00872665 -0.00872665 -0.00872665 -0.00872665 -0.00872665 -0.00872665 -0.00872665 -0.00872665 -0.00872665 -0.00872665 -0.00872665 -0.00872665 -0.00872665 -0.00872665 -0.00872665 -0.00872665 -0.00872665 -0.00872665 -0.00872665 -0.00872665 -0.00872665 -0.00872665 -0.00872665 -0.00872665 -0.00872665 -0.00872665 -0.00872665 -0.00872665 -0.00872665 -0.00872665 -0.00872665 -0.00872665 -0.00872665 -0.00872665 -0.00872665 -0.00872665 -0.00872665 -0.00872665 -0.00872665 -0.00872665 ! PS_BldPitchMin - Minimum blade pitch angles [rad] +60 ! 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.27 3.53 3.80 4.07 4.33 4.60 4.87 5.14 5.40 5.67 5.94 6.20 6.47 6.74 7.00 7.27 7.54 7.80 8.07 8.34 8.60 8.87 9.14 9.41 9.67 9.94 10.21 10.47 10.74 10.74 11.23 11.72 12.22 12.71 13.20 13.69 14.18 14.67 15.17 15.66 16.15 16.64 17.13 17.62 18.12 18.61 19.10 19.59 20.08 20.57 21.07 21.56 22.05 22.54 23.03 23.52 24.02 24.51 25.00 ! PS_WindSpeeds - Wind speeds corresponding to minimum blade pitch angles [m/s] +0.06981317 0.06981317 0.06981317 0.06544985 0.06108652 0.06108652 0.05672320 0.05235988 0.04363323 0.03926991 0.03054326 0.02617994 0.01745329 0.01308997 0.00436332 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 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.436300000000 ! SD_MaxPit - Maximum blade pitch angle to initiate shutdown, [rad] +0.400740000000 ! 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 ----------------------------------------------------------- -0.000000000000 ! Fl_Kp - Nacelle velocity proportional feedback gain [s] +-9.32577000000 ! Fl_Kp - Nacelle velocity proportional feedback gain [s] !------- FLAP ACTUATION ----------------------------------------------------- 0.000000000000 ! Flp_Angle - Initial or steady state flap angle [rad] diff --git a/Examples/NREL5MW_saved.p b/Examples/NREL5MW_saved.p index b8852402d..fbdc484ae 100644 Binary files a/Examples/NREL5MW_saved.p and b/Examples/NREL5MW_saved.p differ diff --git a/Examples/ROSCO_walkthrough.ipynb b/Examples/ROSCO_walkthrough.ipynb index d6b13ab47..0cf1ad1a0 100644 --- a/Examples/ROSCO_walkthrough.ipynb +++ b/Examples/ROSCO_walkthrough.ipynb @@ -44,7 +44,7 @@ "from ROSCO_toolbox import utilities as ROSCO_utilities\n", "from ROSCO_toolbox import controller as ROSCO_controller\n", "from ROSCO_toolbox import control_interface as ROSCO_ci\n", - "from ofTools.fast_io.output_processing import output_processing\n" + "from ROSCO_toolbox.ofTools.fast_io.output_processing import output_processing\n" ] }, { @@ -648,4 +648,4 @@ }, "nbformat": 4, "nbformat_minor": 4 -} +} \ No newline at end of file diff --git a/Examples/example_01.py b/Examples/example_01.py index 2433be296..f5de2dd72 100644 --- a/Examples/example_01.py +++ b/Examples/example_01.py @@ -18,7 +18,8 @@ from ROSCO_toolbox import turbine as ROSCO_turbine # Load yaml file -parameter_filename = os.path.join(os.path.dirname(__file__),'NREL5MW_example.yaml') +this_dir = os.path.dirname(os.path.abspath(__file__)) +parameter_filename = os.path.join(this_dir,'NREL5MW_example.yaml') inps = yaml.safe_load(open(parameter_filename)) path_params = inps['path_params'] turbine_params = inps['turbine_params'] @@ -28,13 +29,13 @@ turbine.load_from_fast( path_params['FAST_InputFile'], - os.path.join(os.path.dirname(__file__),path_params['FAST_directory']), + os.path.join(this_dir,path_params['FAST_directory']), dev_branch=True, - rot_source='txt',txt_filename=os.path.join(os.path.dirname(__file__),path_params['rotor_performance_filename']) + rot_source='txt',txt_filename=os.path.join(this_dir,path_params['rotor_performance_filename']) ) # Print some basic turbine info print(turbine) # Save the turbine model -turbine.save(os.path.join(os.path.dirname(__file__),'NREL5MW_saved.p')) \ No newline at end of file +turbine.save(os.path.join(this_dir,'NREL5MW_saved.p')) \ No newline at end of file diff --git a/Examples/example_02.py b/Examples/example_02.py index 12c1db70a..51254f47a 100644 --- a/Examples/example_02.py +++ b/Examples/example_02.py @@ -19,7 +19,8 @@ turbine = ROSCO_turbine.Turbine # Load quick from python pickle -turbine = turbine.load(os.path.join(os.path.dirname(__file__),'NREL5MW_saved.p')) +this_dir = os.path.dirname(os.path.abspath(__file__)) +turbine = turbine.load(os.path.join(this_dir,'NREL5MW_saved.p')) # plot rotor performance print('Plotting Cp data') diff --git a/Examples/example_03.py b/Examples/example_03.py index 8a352da34..c262ede97 100644 --- a/Examples/example_03.py +++ b/Examples/example_03.py @@ -19,7 +19,8 @@ control_params = {} # Load yaml file -parameter_filename = os.path.join(os.path.dirname(__file__),'NREL5MW_example.yaml') +this_dir = os.path.dirname(os.path.abspath(__file__)) +parameter_filename = os.path.join(this_dir,'NREL5MW_example.yaml') inps = yaml.safe_load(open(parameter_filename)) path_params = inps['path_params'] turbine_params = inps['turbine_params'] @@ -29,11 +30,11 @@ turbine = ROSCO_turbine.Turbine(turbine_params) turbine.load_from_fast( path_params['FAST_InputFile'], - os.path.join(os.path.dirname(__file__),path_params['FAST_directory']), + 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(os.path.dirname(__file__),'Cp_Ct_Cq.Ex03.txt') +txt_filename = os.path.join(this_dir,'Cp_Ct_Cq.Ex03.txt') write_rotor_performance(turbine,txt_filename=txt_filename) diff --git a/Examples/example_04.py b/Examples/example_04.py index 431749eb1..9da8a7ca1 100644 --- a/Examples/example_04.py +++ b/Examples/example_04.py @@ -20,7 +20,8 @@ from ROSCO_toolbox.utilities import write_DISCON # Load yaml file -parameter_filename = os.path.join(os.path.dirname(__file__),'NREL5MW_example.yaml') +this_dir = os.path.dirname(os.path.abspath(__file__)) +parameter_filename = os.path.join(this_dir,'NREL5MW_example.yaml') inps = yaml.safe_load(open(parameter_filename)) path_params = inps['path_params'] turbine_params = inps['turbine_params'] @@ -33,9 +34,9 @@ # Load turbine data from OpenFAST and rotor performance text file turbine.load_from_fast( path_params['FAST_InputFile'], - os.path.join(os.path.dirname(__file__),path_params['FAST_directory']), + os.path.join(this_dir,path_params['FAST_directory']), dev_branch=True, - rot_source='txt',txt_filename=os.path.join(os.path.dirname(__file__),path_params['rotor_performance_filename']) + rot_source='txt',txt_filename=os.path.join(this_dir,path_params['rotor_performance_filename']) ) # Tune controller diff --git a/Examples/example_05.py b/Examples/example_05.py index c97dc472f..f88a779fb 100644 --- a/Examples/example_05.py +++ b/Examples/example_05.py @@ -25,7 +25,7 @@ from ROSCO_toolbox import control_interface as ROSCO_ci # Specify controller dynamic library path and name -this_dir = os.path.dirname(__file__) +this_dir = os.path.dirname(os.path.abspath(__file__)) lib_name = os.path.join(this_dir,'../ROSCO/build/libdiscon.dylib') param_filename = os.path.join(this_dir,'DISCON.IN') diff --git a/Examples/example_06.py b/Examples/example_06.py index 9731c2353..5e038527a 100644 --- a/Examples/example_06.py +++ b/Examples/example_06.py @@ -19,10 +19,10 @@ from ROSCO_toolbox.utilities import write_DISCON, run_openfast from ROSCO_toolbox import sim as ROSCO_sim -this_dir = os.path.dirname(__file__) +this_dir = os.path.dirname(os.path.abspath(__file__)) # Load yaml file -parameter_filename = os.path.join(this_dir,'NREL5MW_example.yaml') +parameter_filename = os.path.join(os.path.dirname(this_dir), 'Tune_Cases', 'IEA15MW.yaml') inps = yaml.safe_load(open(parameter_filename)) path_params = inps['path_params'] turbine_params = inps['turbine_params'] @@ -33,7 +33,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'],path_params['FAST_directory'],dev_branch=True,rot_source='txt',txt_filename=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=os.path.join(this_dir,path_params['FAST_directory'],path_params['rotor_performance_filename'])) # Tune controller controller.tune_controller(turbine) @@ -44,7 +47,8 @@ # Run OpenFAST # --- May need to change fastcall if you use a non-standard command to call openfast -run_openfast(path_params['FAST_directory'], fastcall='openfast_sdev', fastfile=path_params['FAST_InputFile'], chdir=True) +fastcall = 'openfast' +run_openfast(path_params['FAST_directory'], fastcall=fastcall, fastfile=path_params['FAST_InputFile'], chdir=True) diff --git a/Examples/example_08.py b/Examples/example_08.py index 22841a9e2..43786e823 100644 --- a/Examples/example_08.py +++ b/Examples/example_08.py @@ -19,7 +19,7 @@ from ROSCO_toolbox.ofTools.fast_io import output_processing import os -this_dir = os.path.dirname(__file__) +this_dir = os.path.dirname(os.path.abspath(__file__)) # Define openfast output filenames filenames = ["../Test_Cases/NREL-5MW/NREL-5MW.outb"] diff --git a/Examples/example_09.py b/Examples/example_09.py index 3065450f8..2e909ebcc 100644 --- a/Examples/example_09.py +++ b/Examples/example_09.py @@ -14,11 +14,11 @@ from ROSCO_toolbox.utilities import run_openfast import os -this_dir = os.path.dirname(__file__) +this_dir = os.path.dirname(os.path.abspath(__file__)) # Define openfast output filenames wind_directory = os.path.join(this_dir,'../Test_Cases/Wind/') turbsim_infile = '90m_12mps_twr.inp' -run_openfast(wind_directory, fastcall='turbsim_sdev', fastfile=turbsim_infile, chdir=False) +run_openfast(wind_directory, fastcall='turbsim', fastfile=turbsim_infile, chdir=False) diff --git a/Examples/example_10.py b/Examples/example_10.py index ed98aa481..b9b261868 100644 --- a/Examples/example_10.py +++ b/Examples/example_10.py @@ -21,10 +21,10 @@ from ROSCO_toolbox import turbine as ROSCO_turbine from ROSCO_toolbox import controller as ROSCO_controller -rt_dir = os.path.dirname(os.path.dirname(__file__)) +this_dir = os.path.dirname(os.path.abspath(__file__)) # Load yaml file -parameter_filename = os.path.join(rt_dir,'Tune_Cases/BAR.yaml') +parameter_filename = os.path.join(os.path.dirname(this_dir),'Tune_Cases/BAR.yaml') inps = yaml.safe_load(open(parameter_filename)) path_params = inps['path_params'] turbine_params = inps['turbine_params'] @@ -34,7 +34,7 @@ turbine = ROSCO_turbine.Turbine(turbine_params) # 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']) turbine.load_from_fast(path_params['FAST_InputFile'], \ - os.path.join(rt_dir,path_params['FAST_directory']),dev_branch=True) + os.path.join(this_dir,path_params['FAST_directory']),dev_branch=True) # Tune controller controller = ROSCO_controller.Controller(controller_params) diff --git a/Matlab_Toolbox/README.md b/Matlab_Toolbox/README.md index 6f4739c9f..eb672b93d 100644 --- a/Matlab_Toolbox/README.md +++ b/Matlab_Toolbox/README.md @@ -13,5 +13,5 @@ The modules not currently implemented include: - Shutdown control - Flap control -`runFAST.m` can be used to load the ROSCO parameters from a .IN file, using `load_ROSCO_params.m` and a more detailed version can be found in the `matlab-toolbox` [repository](https://github.com/dzalkind/matlab-toolbox/tree/master/Simulations). +`runFAST.m` can be used to load the ROSCO parameters from a .IN file, using `load_ROSCO_params.m`. Add the `matlab-toolbox` [repository](https://github.com/OpenFAST/matlab-toolbox) to your matlab path. diff --git a/Matlab_Toolbox/Utilities/Af_HPF.m b/Matlab_Toolbox/Utilities/Af_HPF.m new file mode 100644 index 000000000..e0dfb0953 --- /dev/null +++ b/Matlab_Toolbox/Utilities/Af_HPF.m @@ -0,0 +1,29 @@ +function [dHPF,HPF] = Af_HPF(omega,zeta,DT,varargin) +%% Example Code +% omega = 2*pi*6; %rad/s +% HPF = tf(om^2,[1,2*zeta*omega,omega^2]); +% dHFP = c2d(LPF,DT); +% +% varargin to specify order + +if isempty(varargin) + order = 2; +else + order = varargin{1}; +end + +if order == 2 + HPF = tf([1,0,0],[1,2*zeta*omega,omega^2]); +elseif order > 2 + [b,a] = butter(order,omega,'high','s'); + HPF = tf(b,a); +else + HPF = tf([1,0],[1,omega]); +end + +dHPF = c2d(HPF,DT,'tustin'); + +if 0 + figure(881); + bode(HPF); +end \ No newline at end of file diff --git a/Matlab_Toolbox/Utilities/Af_LPF.m b/Matlab_Toolbox/Utilities/Af_LPF.m new file mode 100644 index 000000000..0d29abde3 --- /dev/null +++ b/Matlab_Toolbox/Utilities/Af_LPF.m @@ -0,0 +1,29 @@ +function [dLPF,LPF] = Af_LPF(omega,zeta,DT,varargin) +%% Example Code +% omega = 2*pi*6; %rad/s +% LPF = tf(om^2,[1,2*zeta*omega,omega^2]); +% dLFP = c2d(LPF,DT); +% +% varargin to specify order + +if isempty(varargin) + order = 2; +else + order = varargin{1}; +end + +if order == 2 + LPF = tf(omega^2,[1,2*zeta*omega,omega^2]); +elseif order > 2 + [b,a] = butter(order,omega,'s'); + LPF = tf(b,a); +else + LPF = tf(omega,[1,omega]); +end + +dLPF = c2d(LPF,DT,'tustin'); + +if 0 + figure(881); + bode(LPF); +end \ No newline at end of file diff --git a/Matlab_Toolbox/Utilities/Af_MakeWind.m b/Matlab_Toolbox/Utilities/Af_MakeWind.m new file mode 100644 index 000000000..cced81f79 --- /dev/null +++ b/Matlab_Toolbox/Utilities/Af_MakeWind.m @@ -0,0 +1,376 @@ +function [windFileOut, W]=Af_MakeWind(fast,Disturbance,Simulation,varargin) +% Inputs: fast. struct +% Disturbance. struct +% .Type - type of wind input, options: const, steps, +% ramp, sine, step, EOG, ECD +% .U_ref - initial (or constant) wind before transient +% .LHshear - linear horizontal wind shear +% .Vshear - vertical (exponential) shear +% .LVshear - linear vertical shear +% .TStart - time to start transient event +% .TEnd - time to end transient event +% .Step - wind speed step size +% .Amp - amplitude (for sine) +% .Per - period (for sine and EOG) +% Simulation struct +% +% DZalkind 6/26/2020 - cleaned up old script, only const and step tested + +%% Input Handling +if ~isempty(varargin) > 0 + Mplot = varargin{1}; +end + + +% Simulation parameters +if isfield(Simulation,'TMax') + TMax = Simulation.TMax; +else + TMax = 9000; +end + +% Disturbance.Type +if isfield(Disturbance,'Type') + TYPE = Disturbance.Type; +else + disp('Af_MakeWind Warning: no disturbance type, setting constant wind input') + TYPE = 'const'; +end + +% Disturbance DT is usually 0.05 sec, but we can set it +if ~isfield(Disturbance,'DT') + DT = 0.05; +else + DT = Disturbance.DT; +end + + +%% Type Input Handling + +% U_ref is needed for all +if ~isfield(Disturbance,'U_ref') + Disturbance.U_ref = 15; + disp(['Af_MakeWind Warning: no U_ref set for ', TYPE, ' step wind input, setting U_ref = 15 m/s']); +end + +if strcmp(TYPE,'step') % Single Step in Wind + + if ~isfield(Disturbance,'Step') + Disturbance.Step = 2; + disp('Af_MakeWind Warning: no Step set for step wind input, setting Step = 2 m/s'); + end + + if ~isfield(Disturbance,'TStart') + Disturbance.TStart = 100; + disp('Af_MakeWind Warning: no TStart set for step wind input, setting TStart = 100 s'); + end + +elseif strcmp(TYPE,'ramp') % Ramp wind going from Vmin to Vmax to min, ramp starts at Stime + if ~isfield(Disturbance,'U_max') + Disturbance.Umin = 3; + disp('Af_MakeWind Warning: no U_max set for ramp wind input, setting Umin = 3 m/s'); + end + + + if ~isfield(Disturbance,'TStart') + Disturbance.TStart = 100; + disp('Af_MakeWind Warning: no TStart set for ramp input, setting TStart = 100 s'); + end + + if ~isfield(Disturbance,'TEnd') + Disturbance.TEnd = 1100; + disp('Af_MakeWind Warning: no TEnd set for ramp input, setting TEnd = 1100 s'); + end + + +elseif strcmp(TYPE,'sine') % Sinusoidal wind of DC+amp*sin(2*pi*freq*t) + + if ~isfield(Disturbance,'Amp') + Disturbance.Amp = 2; + disp('Af_MakeWind Warning: no Amp set for sine wind input, setting Amp = 2 m/s'); + end + + if ~isfield(Disturbance,'Per') + Disturbance.Per = 30; + disp('Af_MakeWind Warning: no Per set for sine wind input, setting Per = 30 sec'); + end + +elseif strcmp(TYPE,'steps') % Multiple steps in wind from Umin to Umax + if ~isfield(Disturbance,'Umin') + Disturbance.Umin = 3; + disp('Af_MakeWind Warning: no Vmin set for steps wind input, setting Umin = 3 m/s'); + end + + if ~isfield(Disturbance,'Umax') + Disturbance.Umax = 25; + disp('Af_MakeWind Warning: no Umax set for steps wind input, setting Umax = 25 m/s'); + end + + if ~isfield(Disturbance,'TStart') + Disturbance.TStart = 100; + disp('Af_MakeWind Warning: no TStart set for steps input, setting TStart = 100 s'); + end + + if ~isfield(Disturbance,'TEnd') + Disturbance.TEnd = 1100; + disp('Af_MakeWind Warning: no TEnd set for steps input, setting TEnd = 1100 s'); + end + + +elseif strcmp(TYPE,'EOG') + if ~isfield(Disturbance,'TStart') + Disturbance.TStart = 100; + disp('Af_MakeWind Warning: no TStart set for EOG input, setting TStart = 100 s'); + end + + if ~isfield(Disturbance,'Per') + Disturbance.Per = 30; + disp('Af_MakeWind Warning: no Per set for EOG wind input, setting Per = 30 sec'); + end + +elseif strcmp(TYPE,'ECD') + if ~isfield(Disturbance,'TStart') + Disturbance.TStart = 100; + disp('Af_MakeWind Warning: no TStart set for ECD input, setting TStart = 100 s'); + end + + if ~isfield(Disturbance,'TEnd') + Disturbance.TEnd = 100; + disp('Af_MakeWind Warning: no TEnd set for EOG input, setting TEnd = 110 s'); + end + +end + +%% Initialize W matrix for .wnd input +% The following parameters are fully described in the TurbSim/Aerodyn docs. + +% TMax= Max time, DT=Time step, WD= Wind Direction, VS= Vertical speed +% Hshear=Linear horizontal shear, Vshear= Power Law Vertical Shear, +% LVshear= Linear Vertical Shear, GS= Gust Speed +% Mplot==1 will produce a plot of the generated wind file (hub height) + +% Note: If any shear parameter input is a scalar, it will produce a wind +% file with a constant shear. If the input shear parameter is a vector, +% it must be the same length as the generated wind file and is used as the +% time varying shear. + +% EXAMPLE with Header +% ! Time Wind Wind Vert. Horiz. Vert. LinV Gust +% ! Speed Dir Speed Shear Shear Shear Speed +% 0.0 30 0 -1 0.1 0.14 0 0 + +% Generated wind file is stored in the PWD\WindData folder with +% the appropriate name for the type. + +% Initialize +samples = round(TMax/DT+1); +W = zeros(samples, 8); + +% Time +W(:,1) = 0:DT:TMax; + +% Direction, set to 0 unless ECD +W(:,3) = 0; + +% Vertical Speed, none for now +W(:,4) = 0; + +% Horizontal Shear (linear) +if isfield(Disturbance, 'LHshear') + W(:,5) = Disturbance.LHsear; +else + W(:,5) = 0; +end + +% Vertical Shear (exponential) +if isfield(Disturbance, 'Vshear') + W(:,6) = Disturbance.Vshear; +else + W(:,6) = 0; +end + +% Linear Vertical Shear +if isfield(Disturbance, 'LVshear') + W(:,7) = Disturbance.LVshear; +else + W(:,7) = 0; +end + +% Gust, set to 0 for now, let wind speed do the work +W(:,8) = 0; + + + +%% Make W(:,2), Wind Speed Vector + +switch TYPE + case 'const' % p1=DC VALUE + W(:,2) = ones(samples,1)*Disturbance.U_ref; + + case 'step' + tt = W(:,1); + uu = Disturbance.U_ref * ones(size(tt)); + uu(tt>Disturbance.TStart) = Disturbance.U_ref + Disturbance.Step; + W(:,2) = uu; + + + case 'steps' %p1=min, p2=max, p3=ds + +% p2=p2+p3; +% +% sgn=sign(p2-p1); +% +% W(:,2)=ones(samples,1)*p1; +% steptime=round(samples/2/(sgn*(p2-p1)/p3)); +% +% for n=1:2*sgn*(p2-p1)/p3 +% b=(n-1)*steptime+1; +% e=n*steptime+1; +% if e>samples; +% e=samples; +% end +% if n<=sgn*(p2-p1)/p3 +% W(b:e,2)=p1+sgn*(n-1)*p3; +% end +% if n>sgn*(p2-p1)/p3 +% W(b:e,2)=p2-sgn*(n-sgn*(p2-p1)/p3)*p3; +% end +% end + + + case 'sine' % p1=dcwind, p2=freq, p3=amp, + W(:,2)= Disturbance.U_ref + Disturbance.Amp*sin(2 * pi * W(:,1) / Disturbance.Period); + + case 'ramp' % p1=min, p2=max, p3=ST + + % ramp time breakpoints + t_ramp = [Disturbance.TStart, (Disturbance.TStart + Disturbance.TEnd)/2, Disturbance.TEnd]; + v_ramp = [Disturbance.U_ref, Disturbance.U_max, Disturbance.U_ref]; + + % append start end + t_ramp = [0, t_ramp, Simulation.TMax]; + v_ramp = [Disturbance.U_ref, v_ramp, Disturbance.U_ref]; + + % catch non-unique t_ramp(s) + [t_ramp, iu] = unique(t_ramp); + v_ramp = v_ramp(iu); + + W(:,2) = interp1(t_ramp',v_ramp',W(:,1)); + + + +% case 'yaw_step' % p1:5 [ Wind Speed Initial Yaw Start Time Final Yaw End Time ] +% +% tt = W(:,1); +% +% if p3 == p5 %just a step +% yy = p2*ones(samples,1); +% yy(tt>p3) = p4; +% +% else %ramp +% X = [0,p3,p5,TMax]; +% V = [p2,p2,p4,p4]; +% yy = interp1(X,V,tt); +% end +% W(:,2) = ones(samples,1)*p1./cosd(yy)+1.373157942907710e-08; +% W(:,2) = ones(samples,1)*p1; +% W(:,3) = yy; +% + + case 'EOG' + p3 = Disturbance.Per; + p2 = Distrubance.TStart; + p1 = Disturbance.U_ref; + + tt = W(:,1); + tt_gust = (0:DT:p3)'; + U = p1; + gust = [zeros(p2/DT,1); + -0.37*p4*sin(3*pi*tt_gust/p3).*(1-cos(2*pi*tt_gust/p3)); + zeros(samples-p2/DT-p3/DT-1,1)]; + W(:,2) = U+gust; + + case 'ECD' + p1 = Disturbance.U_ref; + p2 = Disturbance.TStart; + p3 = Distrubance.TEnd; + p4 = Disturbance.U_ref + 15; + + W(1:samples,2)=p1; + W((p2/DT)+1:((p2+p4)/DT)+1,2)= p1+0.5*15*(1-cos(pi*[((0)/DT)+1:((p4)/DT)+1]/(p4/DT))); + W(round((p2+p4)/DT)+1:end,2)= p3; + if p1<4 + theta_cg=180; + else + theta_cg=720/p1; + end + W(1:samples,3) = 0; + W((p2/DT)+1:((p2+p4)/DT)+1,3) = 0.5*theta_cg*(1-cos(pi*[((0)/DT)+1:((p4)/DT)+1]/(p4/DT))); + W(round((p2+p4)/DT)+1:end,3)= theta_cg; + + + case 'PeakTest' + startTime = 200; %start time of first gust + extraTime = 100; %time after test + periods = [60,45,30,20,10,5]; %sinusoid periods + + DT = 1/80; + T = periods(1); + tt = 0:DT:TMax; + gust = zeros(length(periods),length(tt)); + + startGust = [startTime,startTime + cumsum(periods(1:end-1))]; + + Amp = 6; %gust amplitude + startU = 9.3; %wind speed to start gust + + for iGust = 1:size(gust,1)-1 + T = periods(iGust); + gust(iGust,:) = (Amp/2 * (-cos(2*pi/T * (tt - startGust(iGust)))+1)).*(tt >= startGust(iGust) & tt <= startGust(iGust+1)); + end + + wind = sum(gust,1) + startU; + W(:,1) = tt; + W(:,2) = wind; + + if 1 + figure(100); + plot(tt,wind); + end + + case 'ConstRake' % p1=min, p2=t_start, p3=t_end, p4 = du + + tt = 0:DT:TMax; + b = p1 - p4/20 * p2; + m = p4 /20; + maxWS = 25; + tend = (maxWS-b)*(20/p4); + + W(:,2) = p1; + W(tt>p2,2) = m * tt(tt>p2) + b; + W(tt>tend,2) = maxWS; + + if 1 + figure(100); + plot(tt,W(:,2)); + end +end + + +%% Write Output +if ~isdir(fast.FAST_runDirectory) + mkdir(fast.FAST_runDirectory); +end + +windFileOut = fullfile(fast.FAST_runDirectory,[fast.FAST_namingOut,'.wnd']); +dlmwrite(windFileOut, W, 'delimiter','\t','precision','%.6f') +disp([TYPE,' Wind File Made: ',fast.FAST_namingOut,'.wnd']) + +if Mplot==1 + figure(800); + set(gcf,'Name','Wind Input') + plot(W(:,1),W(:,2)) + xlabel('Time [s]') + ylabel('HH Velocity [m/s]') + grid on +end \ No newline at end of file diff --git a/Matlab_Toolbox/Utilities/Af_MovingNotch.m b/Matlab_Toolbox/Utilities/Af_MovingNotch.m new file mode 100644 index 000000000..50ee65cc8 --- /dev/null +++ b/Matlab_Toolbox/Utilities/Af_MovingNotch.m @@ -0,0 +1,34 @@ +function [dNF_LPV,dNF_LPV_ss] = Af_MovingNotch(frequencyRange,zeta,beta,DT) +%% Example code +% Notch at 2P +% LPV filter with rotor speed as scheduling parameter + +% om_1P = 2*pi*RotorSpeedDomain/60; +% om_2P = 2*om_1P; +% +% zeta_2P = 0.8; +% beta_2P = zeta_2P/10; +% +% %populate range of 2P/4P filters +% dNF_2P_lpv = ss; +% for iom = 1:1:length(om_2P) +% NF_2P = tf([1,2*om_2P(iom)*beta_2P,(om_2P(iom))^2],[1,2*om_2P(iom)*zeta_2P,(om_2P(iom))^2]); +% dNF_2P_lpv(:,:,iom) = c2d(ss(NF_2P),Control.DT); +% end +% +% %sampling grid (scheduling parameter) +% dNF_2P_lpv.SamplingGrid = struct('Omega_2P',om_2P); + +%% +NF = tf; +dNF_LPV = tf; +dNF_LPV_ss = ss; + +for iFreq = 1:1:length(frequencyRange) + NF = tf([1,2*frequencyRange(iFreq)*beta,(frequencyRange(iFreq))^2],[1,2*frequencyRange(iFreq)*zeta,(frequencyRange(iFreq))^2]); + dNF_LPV(iFreq) = c2d((NF),DT); + dNF_LPV_ss(:,:,iFreq) = c2d(ss(NF),DT); +end + +%sampling grid (scheduling parameter) +dNF_LPV_ss.SamplingGrid = struct('Omega',frequencyRange); diff --git a/Matlab_Toolbox/Utilities/Af_sigma.m b/Matlab_Toolbox/Utilities/Af_sigma.m new file mode 100644 index 000000000..1016058fd --- /dev/null +++ b/Matlab_Toolbox/Utilities/Af_sigma.m @@ -0,0 +1,8 @@ +function a = Af_sigma(x0,x1); + +a3 = 2/(x0-x1)^3; +a2 = -3*(x0+x1)/(x0-x1)^3; +a1 = 6*x1*x0/(x0-x1)^3; +a0 = (x0-3*x1)*x0^2/(x0-x1)^3; + +a = [a3,a2,a1,a0]; \ No newline at end of file diff --git a/Matlab_Toolbox/Utilities/ParseROSCOInputLine.m b/Matlab_Toolbox/Utilities/ParseROSCOInputLine.m new file mode 100644 index 000000000..8f8db2746 --- /dev/null +++ b/Matlab_Toolbox/Utilities/ParseROSCOInputLine.m @@ -0,0 +1,128 @@ +function [value, label, isComment, descr, fieldType] = ParseROSCOInputLine( line ) +% This routine parses a line from a FAST type input file. +% Comment lines are assumed to start with any of the following individual characters: +% #!= +% or this combination of characters: +% -- +% If the line is not a comment, it is assumed to be of the form: +% value [,Array values] label descr +% If the value is an array, it must be separated by commas. +% If there are multiple values separated by white space, it is assumed to +% contain old values (instead of an array) +%-------------------------------------------------------------------------- +% Inputs: +% line - a line of text +% Outputs: +% value - the value of the parameter +% label - the name of the parameter/variable/field +% isComment - logical value that says if the line is a comment line +% descr - the description of the line +% fieldType - text saying the field is either a +% "Comment", "Logical", "Character", "Numeric" variable +%-------------------------------------------------------------------------- + + % first check that this isn't a blank line... + if isempty(line) || length(strtrim(line)) < 1 + value = ''; + label = ''; + isComment = true; + descr = ''; + fieldType = 'Comment'; + return + end + + trueFalseValues = {'true','false','t','f'}; + + % determine if this is a comment line: + first2Chars = sscanf(strtrim(line),'%c',2); %read the first two not-starting-with-whitespace characters + firstChar = first2Chars(1); + + if ~isempty( strfind( '#!=', firstChar ) ) || strcmp( first2Chars, '--' ) %comments start with any of these characters: # ! - = + value = strtrim(line); + label = ''; + isComment = true; + descr = value; + fieldType = 'Comment'; + else + isComment = false; + + % Get the Value, number or string + [value, cnt, ~, nextindex] = sscanf(line,'%f', 1); %First check if line begins with a number +% disp ([ '"' line(nextindex:end) '"']); + + if cnt == 0 || ... % we didn't find a number so... + ( nextindex < length(line) && ~isempty(strtrim(line(nextindex))) && ~strcmp(line(nextindex),',') ) % this would happen if a string started with a number and wasn't empty afterwards: e.g. "1P0.0" gets read as "1", but the next character is "P", not a space separating it from a label + [testVal, position] = textscan(line,'%q',1); %look for a string instead + if any( strcmpi(testVal{1}{1},trueFalseValues) ) + value = testVal{1}{1}; %this is a logical input + fieldType = 'Logical'; + else + if ~isempty(testVal{1}{1}) && strcmp(testVal{1}{1}(1),'@') + value = testVal{1}{1}; + else + value = ['"' testVal{1}{1} '"']; %add quotes back around the string + end + fieldType = 'Character'; + end + nextindex = position + 1; + else + fieldType = 'Numeric'; + end + + % Now get the label + + % Some looping is necessary because often times, + % old values for FAST parameters are kept next to new + % ones seperated by a space and need to be ignored + + + IsLabel = false; + label = ''; %initialize in case the line doesn't have a label + descr = ''; + + while ~IsLabel && length(line) >= nextindex + line = line(nextindex:end); + + [tmpVal, cnt, ~, nextindex] =sscanf(line,'%f',1); + if cnt == 0 || ~isfinite(tmpVal) %if we've reached something besides a number (or we read text as "Inf") - or we're at the end of the line + + [testVal, cnt, ~, nextindex] = sscanf(line,'%s',1); + if cnt == 1 + if any( strcmpi(testVal,trueFalseValues) ) + %this is a logical input + elseif strcmpi(testVal(1),',') + % commas are an indication that this parameter is a list + if strcmpi(fieldType, 'Numeric') + line = line(2:end); + [testVal, cnt, ~, nextindex] = sscanf(line,'%f',1); + if cnt == 1 + value = [value testVal]; + end + end + elseif strcmpi(testVal(1),'"') + [testVal, position] = textscan(line,'%q',1); %look for a string in quotes + nextindex = position + 1; + elseif strcmpi(testVal(1),'!') % is a comment in ROSCO, label is next + [tempStr,position] = textscan(line,'%s',2); + IsLabel = true; + label = tempStr{1}{2}; % hard code, sorry + descr = strtrim(line(position+1:end)); + else + IsLabel = true; + label = testVal; + descr = strtrim(line(nextindex:end)); + end + end + else + % this was a finite numeric value (not separated by commas), so we'll keep it + value = [value tmpVal]; + end + + end %while + + end %not a comment + + if strcmp(label,'-') + label = ''; + end +return \ No newline at end of file diff --git a/Matlab_Toolbox/Pl_FastPlots.m b/Matlab_Toolbox/Utilities/Pl_FastPlots.m similarity index 100% rename from Matlab_Toolbox/Pl_FastPlots.m rename to Matlab_Toolbox/Utilities/Pl_FastPlots.m diff --git a/Matlab_Toolbox/Utilities/Pre_LoadRotPerf.m b/Matlab_Toolbox/Utilities/Pre_LoadRotPerf.m new file mode 100644 index 000000000..bf9f017f6 --- /dev/null +++ b/Matlab_Toolbox/Utilities/Pre_LoadRotPerf.m @@ -0,0 +1,74 @@ +function RotPerf = Pre_LoadRotPerf(RotPerfFile) +% Load rotor performance information from a text file. +% Loads OpenFast model output into a MATLAB structure to be post processed +% +% Inputs: RotPerfFile - Cp_Ct_Cq.txt file from CCBlade/ROSCO +% Outputs: RotorPerformance - Structure containing rotor performance data +% +% Nikhar Abbas + + +fid = fopen(RotPerfFile, 'r'); +if fid == -1, error('Error loading file'), end + +% Read first line to start tline +tline = fgetl(fid); +while ~feof(fid) + tline = fgetl(fid); + l_str = strsplit(tline); + if tline + % Find pitch angle vector + if strcmpi(l_str{2},'Pitch') + tline = fgetl(fid); + BlPitch = str2num(tline); + % Find TSR vector + elseif strcmpi(l_str{2},'TSR') + tline = fgetl(fid); + TSR = str2num(tline); + % Find Wind speed vector + elseif strcmpi(l_str{2},'Wind') + tline = fgetl(fid); + Wind = str2num(tline); + + % Read Cp table + elseif strcmpi(l_str{2},'Power') + tline = fgetl(fid); + Cpmat = zeros(length(TSR),length(BlPitch)); + for pind = 1:length(TSR) + tline = fgetl(fid); + CpMat(pind,:) = str2num(tline); + end + + % Read Ct table + elseif strcmpi(l_str{2},'Thrust') + tline = fgetl(fid); + Ctmat = zeros(length(TSR),length(BlPitch)); + for pind = 1:length(TSR) + tline = fgetl(fid); + CtMat(pind,:) = str2num(tline); + end + + % Read Cq table + elseif strcmpi(l_str{2},'Torque') + tline = fgetl(fid); + Cqmat = zeros(length(TSR),length(BlPitch)); + for pind = 1:length(TSR) + tline = fgetl(fid); + CqMat(pind,:) = str2num(tline); + end + end + end +end + + + + +% Save Structure +RotPerf.BlPitch = BlPitch; +RotPerf.TSR = TSR; +RotPerf.Wind = Wind; +RotPerf.Cpmat = CpMat; +RotPerf.Ctmat = CtMat; +RotPerf.Cqmat = CqMat; + +end \ No newline at end of file diff --git a/Matlab_Toolbox/Utilities/ROSCO2Matlab.m b/Matlab_Toolbox/Utilities/ROSCO2Matlab.m new file mode 100644 index 000000000..906048d5f --- /dev/null +++ b/Matlab_Toolbox/Utilities/ROSCO2Matlab.m @@ -0,0 +1,414 @@ +function DataOut = ROSCO2Matlab(FST_file,hdrLines,DataOut) +%% Fast2Matlab +% DataOut = Fast2Matlab(FST_file,hdrLines,DataOut) +% Function for reading FAST input files in to a MATLAB struct. +% +% +%This function returns a structure DataOut, which contains the following +% cell arrays: +%.Val An array of values +%.Label An array of matching labels +%.HdrLines An array of the header lines (size specified at input) +% +% The following cell arrays may or may not be part of the DataOut structure +% (depending on the type of file being read): +%.OutList An array of variables to output +%.OutListComments An array of descriptions of the .OutList values +% +%.TowProp A matrix of tower properties with columns .TowPropHdr +%.TowPropHdr A cell array of headers corresponding to the TowProp table +% +%.BldProp A matrix of blade properties with columns .BldPropHdr +%.BldPropHdr A cell array of headers corresponding to the BldProp table +% +%.DLLProp A matrix of properties for the Bladed DLL Interface with columns .DLLPropHdr +%.DLLPropHdr A cell array of headers corresponding to the DLLProp table +% +%.FoilNm A Cell array of foil names +% +%.BldNodesHdr A cell array of headers corresponding to the BldNodes table +%.BldNodes A matrix of blade nodes with columns RNodes, AeroTwst DRNodes Chord and Nfoil +% +%.CasesHdr A cell array of headers corresponding to the Cases table +%.Cases A matrix of properties for individual cases in a driver file +% +%.AFCoeffHdr A cell array of headers corresponding to the AFCoeff table +%.AFCoeff A matrix of airfoil coefficients +% +%.TMDspProp A matrix of TMD spring forces +%.TMDspPropHdr A cell array of headers corresponding to the TMDspProp table +% +% .PointLoads A table of point loads in the BeamDyn driver input file +% .PointLoadsHdr A the headers for the point loads table +% +%.PrnElm An array determining whether or not to print a given element +% +%.kp A table of key points defined in BeamDyn +%.kpHdr A cell array of headers corresponding to the kp table +% +%.profile A table of profile values defined in TurbSim +%-------------------------------------------------------------------------- + +%These arrays are extracted from the FAST input file +% +% In: FST_file - Name of FAST input file +% hdrLines - Number of lines to skip at the top (optional) +% +% Knud A. Kragh, May 2011, NREL, Boulder +% +% Modified by Paul Fleming, JUNE 2011 +% Modified by Bonnie Jonkman, February 2013 (to allow us to read the +% platform file, too) +%% +if nargin < 2 + hdrLines = 0; +end + +%----------------------Read FST main file---------------------------------- +fid = fopen(FST_file,'r'); + +if fid == -1 + error(['FST file, ' FST_file ', could not be opened for reading. Check if the file exists or is locked.']) +end + +%skip hdr +for hi = 1:hdrLines + if nargin == 3 + fgetl(fid); + else + DataOut.HdrLines{hi,1} = fgetl(fid); %bjj: added field for storing header lines + end +end + +%PF: Commenting this out, not sure it's necessary +%DataOut.Sections=0; + +%Loop through the file line by line, looking for value-label pairs +%Stop once we've reached the OutList which this function is the last +%occuring thing before the EOF +if nargin == 3 + + count = max(length(DataOut.Label),length(DataOut.Val))+1; +else + count = 1; +end +NextIsMatrix = 0; +matrixVal = []; + +while true %loop until discovering Outlist or end of file, than break + + line = fgetl(fid); + if isnumeric(line) % we reached the end of the file\ + break + end + + % Check to see if the value is Outlist + + %if ~isempty(strfind(upper(line),upper('OutList'))) + if ~isempty(strfind( upper(line), upper('OutList') )) + % 6/23/2016: linearization inputs contain "OutList" in the + % comments, so we need to make sure this is either the first (value) or + % second (label) word of the line. + [value, ~, ~, nextindex] = sscanf(line,'%s', 1); + if strcmpi(value,'OutList') + [DataOut.OutList DataOut.OutListComments] = ParseFASTOutList(fid); + break; %bjj: we could continue now if we wanted to assume OutList wasn't the end of the file... + else + % try the second + [value] = sscanf(line(nextindex+1:end),'%s', 1); + if strcmpi(value,'OutList') + [DataOut.OutList DataOut.OutListComments] = ParseFASTOutList(fid); + break; %bjj: we could continue now if we wanted to assume OutList wasn't the end of the file... + end + end + end + + + [value, label, isComment, descr, fieldType] = ParseROSCOInputLine( line ); + + + if ~isComment + + if strcmpi(value,'"HtFract"') %we've reached the distributed tower properties table (and we think it's a string value so it's in quotes) + NTwInpSt = GetFASTPar(DataOut,'NTwInpSt'); + [DataOut.TowProp, DataOut.TowPropHdr] = ParseFASTNumTable(line, fid, NTwInpSt); + continue; %let's continue reading the file + elseif strcmpi(value,'"TwrElev"') %we've reached the distributed tower properties table (and we think it's a string value so it's in quotes) + NumTwrNds = GetFASTPar(DataOut,'NumTwrNds'); + [DataOut.TowProp, DataOut.TowPropHdr] = ParseFASTNumTable(line, fid, NumTwrNds); + continue; %let's continue reading the file + elseif strcmpi(value,'"BlFract"') %we've reached the distributed blade properties table (and we think it's a string value so it's in quotes) + NBlInpSt = GetFASTPar(DataOut,'NBlInpSt'); + [DataOut.BldProp, DataOut.BldPropHdr] = ParseFASTNumTable(line, fid, NBlInpSt); + continue; %let's continue reading the file + elseif strcmpi(label,'F_X') %we've reached the TMD spring forces table + NKInpSt = GetFASTPar(DataOut,'NKInpSt'); + [DataOut.TMDspProp, DataOut.TMDspPropHdr] = ParseFASTNumTable(line, fid, NKInpSt); + continue; %let's continue reading the file + elseif strcmpi(value,'"GenSpd_TLU"') %we've reached the DLL torque-speed lookup table (and we think it's a string value so it's in quotes) + DLL_NumTrq = GetFASTPar(DataOut,'DLL_NumTrq'); + [DataOut.DLLProp, DataOut.DLLPropHdr] = ParseFASTNumTable(line, fid, DLL_NumTrq); + continue; %let's continue reading the file + elseif strcmpi(label,'FoilNm') %note NO quotes because it's a label + NumFoil = GetFASTPar(DataOut,'NumFoil'); + [DataOut.FoilNm] = ParseFASTFileList( line, fid, NumFoil ); + continue; %let's continue reading the file + elseif strcmpi(label,'AFNames') %note NO quotes because it's a label + NumFoil = GetFASTPar(DataOut,'NumAFfiles'); + [DataOut.FoilNm] = ParseFASTFileList( line, fid, NumFoil ); + continue; %let's continue reading the file + elseif strcmpi(value,'"RNodes"') + BldNodes = GetFASTPar(DataOut,'BldNodes'); + [DataOut.BldNodes, DataOut.BldNodesHdr] = ParseFASTFmtTable( line, fid, BldNodes, false ); + continue; + elseif strcmpi(value,'"BlSpn"') + NumBlNds = GetFASTPar(DataOut,'NumBlNds'); + [DataOut.BldNodes, DataOut.BldNodesHdr] = ParseFASTNumTable( line, fid, NumBlNds ); + continue; + elseif strcmpi(value,'"WndSpeed"') %we've reached the cases table (and we think it's a string value so it's in quotes) + NumCases = GetFASTPar(DataOut,'NumCases'); + [DataOut.Cases, DataOut.CasesHdr] = ParseFASTNumTable(line, fid, NumCases); + continue; %let's continue reading the file + elseif strcmpi(label,'NumPointLoads') + DataOut.Label{count,1} = label; + DataOut.Val{count,1} = value; + count = count + 1; + + NumPointLoads = value; + line = fgetl(fid); % the next line is the header, and it may have comments + [DataOut.PointLoads, DataOut.PointLoadsHdr] = ParseFASTNumTable(line, fid, NumPointLoads); + continue; %let's continue reading the file + + elseif strcmpi(label,'NumAlf') + DataOut.Label{count,1} = label; + DataOut.Val{count,1} = value; + count = count + 1; + + NumAlf = value; + line = fgetl(fid); % the next line is the header, and it may have comments + line = line(2:end); + [DataOut.AFCoeff, DataOut.AFCoeffHdr] = ParseFASTNumTable(line, fid, NumAlf); + continue; %let's continue reading the file + elseif strcmpi(label,'kp_yr') %we've reached the BD key-points table + kp_total = GetFASTPar(DataOut,'kp_total'); + [DataOut.kp, DataOut.kpHdr] = ParseFASTNumTable(line, fid, kp_total); + continue; %let's continue reading the file + elseif strcmpi(label,'StdScale3') %we've reached the TurbSim profiles table + DataOut.Label{count,1} = label; + DataOut.Val{count,1} = value; + count = count + 1; + + NumUSRz = GetFASTPar(DataOut,'NumUSRz'); + line = fgetl(fid); % the next line is the header, and it may have comments + [DataOut.profile] = ParseFASTNumTable(line, fid, NumUSRz, 2 ); + continue; %let's continue reading the file + else + + if NextIsMatrix > 0 + matrixVal = vertcat( matrixVal, value ); + NextIsMatrix = NextIsMatrix - 1; + label = nextLabel; + value = matrixVal; + end + + if NextIsMatrix == 0 + DataOut.Label{count,1} = label; + DataOut.Val{count,1} = value; + count = count + 1; + matrixVal = []; + end + + if strcmpi(label,'GlbPos(3)') % the next one is a DCM from the BD driver file: + NextIsMatrix = 3; % three rows of a matrix (DCM) + nextLabel = 'DCM'; + elseif strcmpi(label,'kp_total') % the next one is a DCM from the BD driver file: + NextIsMatrix = GetFASTPar(DataOut,'member_total'); + nextLabel = 'MemberKeyPtTable'; + end + end + end + +end %end while + +fclose(fid); %close file + +return +end %end function +%% +function [OutList OutListComments] = ParseFASTOutList( fid ) + + %Now loop and read in the OutList + + outCount = 0; + while true + line = fgetl(fid); + if isempty(line) %Fortran allows blank lines in this list + continue; + end + [outVarC, position] = textscan(line,'%q',1); %we need to get the entire quoted line + outVar = outVarC{1}{1}; % this will not have quotes around it anymore... + + if isnumeric(line) %loop until we reach the word END or hit the end of the file + break; + else + indx = strfind(upper(outVar),'END'); + if (~isempty(indx) && indx == 1) %we found "END" so that's the end of the file + break; + else + outCount = outCount + 1; + OutList{outCount,1} = ['"' outVar '"']; + if position < length(line) + OutListComments{outCount,1} = line((position+1):end); + else + OutListComments{outCount,1} = ' '; + end + end + end + end %end while + + if outCount == 0 + disp( 'WARNING: no outputs found in OutList' ); + OutList = []; + OutListComments = ''; + end + +end %end function +%% +function [Table, Headers] = ParseFASTNumTable( line, fid, InpSt, NumUnitsLines ) + + % read a numeric table from the FAST file + + if strncmp(line,'--------------------------------------------', 20) + % this assumes we are using TurbSim profiles file + Headers = fgetl(fid); + nc = 5; + else + + % we've read the line of the table that includes the header + % let's parse it now, getting the number of columns as well: + if contains(line,',') + % these will be assumed to be comma delimited: + TmpHdr = textscan(line,'%s', 'Delimiter',','); + else + TmpHdr = textscan(line,'%s'); + end + + Headers = TmpHdr{1}; + if strcmp( Headers{1}, '!' ) + Headers = Headers(2:end); + end + nc = length(Headers); + end + + if nargin < 4 + NumUnitsLines = 1; + end + + for i=1:NumUnitsLines + % read the units line: + fgetl(fid); + end + + % now initialize Table and read its values from the file: + Table = zeros(InpSt, nc); %this is the size table we'll read + i = 0; % this the line of the table we're reading + while i < InpSt + + line = fgetl(fid); + if isnumeric(line) % we reached the end prematurely + break + elseif i == 0 + [~,cnt]=sscanf(line,'%f',nc); + if cnt==0 + break + % stop reading and return because the line was not numeric + elseif cnt 0: case_inputs_i[("ElastoDyn","NacYaw")] = {'vals':self.dlc_inputs['Yaw'][i], 'group':2} @@ -298,7 +311,7 @@ def execute(self, case_inputs={}): # make unique wave seeds if self.uniqueWaveSeeds: seed_base = int(float(dlc) * 10000) # set wave seed based on dlc so no repeats - num_in_dlc = len(case_inputs_i[("InflowWind","Filename")]['vals']) # sims in each DLC + num_in_dlc = len(case_inputs_i[("InflowWind","FileName_BTS")]['vals']) # sims in each DLC wave_seeds = (seed_base + np.arange(0,num_in_dlc)).tolist() case_inputs_i[("HydroDyn","WaveSeed1")] = {'vals':wave_seeds, 'group':1} diff --git a/ROSCO_toolbox/ofTools/case_gen/runFAST_pywrapper.py b/ROSCO_toolbox/ofTools/case_gen/runFAST_pywrapper.py index 068206a5a..e07157130 100644 --- a/ROSCO_toolbox/ofTools/case_gen/runFAST_pywrapper.py +++ b/ROSCO_toolbox/ofTools/case_gen/runFAST_pywrapper.py @@ -9,10 +9,10 @@ import multiprocessing as mp # sys.path.insert(0, os.path.abspath("..")) -from ofTools.fast_io.FAST_reader import InputReader_Common, InputReader_OpenFAST, InputReader_FAST7 -from ofTools.fast_io.FAST_writer import InputWriter_Common, InputWriter_OpenFAST, InputWriter_FAST7 -from ofTools.fast_io.FAST_wrapper import FastWrapper -from ofTools.fast_io.FAST_post import FAST_IO_timeseries +from ROSCO_toolbox.ofTools.fast_io.FAST_reader import InputReader_Common, InputReader_OpenFAST, InputReader_FAST7 +from ROSCO_toolbox.ofTools.fast_io.FAST_writer import InputWriter_Common, InputWriter_OpenFAST, InputWriter_FAST7 +from ROSCO_toolbox.ofTools.fast_io.FAST_wrapper import FastWrapper +from ROSCO_toolbox.ofTools.fast_io.FAST_post import FAST_IO_timeseries import numpy as np diff --git a/ROSCO_toolbox/ofTools/fast_io/FAST_post.py b/ROSCO_toolbox/ofTools/fast_io/FAST_post.py index 73e589f78..adee1d5da 100644 --- a/ROSCO_toolbox/ofTools/fast_io/FAST_post.py +++ b/ROSCO_toolbox/ofTools/fast_io/FAST_post.py @@ -1,5 +1,5 @@ from __future__ import print_function -from ofTools.fast_io.output_processing import output_processing +from ROSCO_toolbox.ofTools.fast_io.output_processing import output_processing import ROSCO_toolbox def FAST_IO_timeseries(fname): diff --git a/ROSCO_toolbox/ofTools/fast_io/FAST_reader.py b/ROSCO_toolbox/ofTools/fast_io/FAST_reader.py index a698573d6..310a8ca26 100644 --- a/ROSCO_toolbox/ofTools/fast_io/FAST_reader.py +++ b/ROSCO_toolbox/ofTools/fast_io/FAST_reader.py @@ -4,7 +4,7 @@ from functools import reduce import operator -from ofTools.fast_io.FAST_vars import FstModel +from ROSCO_toolbox.ofTools.fast_io.FAST_vars import FstModel from ROSCO_toolbox.utilities import read_DISCON, load_from_txt from ROSCO_toolbox import turbine as ROSCO_turbine ROSCO = True @@ -522,6 +522,7 @@ def read_MainInput(self): self.fst_vt['Fst']['SubFile_path'] = os.path.split(self.fst_vt['Fst']['SubFile'])[0] 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): # ElastoDyn v1.03 Input File # Currently no differences between FASTv8.16 and OpenFAST. @@ -781,7 +782,6 @@ def read_BeamDyn(self): self.read_BeamDynBlade() - def read_BeamDynBlade(self): # BeamDyn Blade @@ -836,6 +836,7 @@ def read_InflowWind(self): self.fst_vt['InflowWind']['Echo'] = bool_read(f.readline().split()[0]) self.fst_vt['InflowWind']['WindType'] = int(f.readline().split()[0]) self.fst_vt['InflowWind']['PropogationDir'] = float_read(f.readline().split()[0]) + self.fst_vt['InflowWind']['VFlowAng'] = float_read(f.readline().split()[0]) self.fst_vt['InflowWind']['NWindVel'] = int(f.readline().split()[0]) self.fst_vt['InflowWind']['WindVxiList'] = float_read(f.readline().split()[0]) self.fst_vt['InflowWind']['WindVyiList'] = float_read(f.readline().split()[0]) @@ -849,14 +850,13 @@ def read_InflowWind(self): # Parameters for Uniform wind file [used only for WindType = 2] (uniform_wind_params) f.readline() - self.fst_vt['InflowWind']['Filename'] = os.path.join(os.path.split(inflow_file)[0], f.readline().split()[0][1:-1]) - self.fst_vt['InflowWind']['RefHt'] = float_read(f.readline().split()[0]) + self.fst_vt['InflowWind']['Filename_Uni'] = os.path.join(os.path.split(inflow_file)[0], f.readline().split()[0][1:-1]) + self.fst_vt['InflowWind']['RefHt_Uni'] = float_read(f.readline().split()[0]) self.fst_vt['InflowWind']['RefLength'] = float_read(f.readline().split()[0]) # Parameters for Binary TurbSim Full-Field files [used only for WindType = 3] (turbsim_wind_params) f.readline() - self.fst_vt['InflowWind']['Filename'] = os.path.join(os.path.split(inflow_file)[0], f.readline().split()[0][1:-1]) - + self.fst_vt['InflowWind']['FileName_BTS'] = os.path.join(os.path.split(inflow_file)[0], f.readline().split()[0][1:-1]) # Parameters for Binary Bladed-style Full-Field files [used only for WindType = 4] (bladed_wind_params) f.readline() self.fst_vt['InflowWind']['FilenameRoot'] = f.readline().split()[0][1:-1] @@ -873,7 +873,7 @@ def read_InflowWind(self): self.fst_vt['InflowWind']['dx'] = float_read(f.readline().split()[0]) self.fst_vt['InflowWind']['dy'] = float_read(f.readline().split()[0]) self.fst_vt['InflowWind']['dz'] = float_read(f.readline().split()[0]) - self.fst_vt['InflowWind']['RefHt'] = float_read(f.readline().split()[0]) + self.fst_vt['InflowWind']['RefHt_Hawc'] = float_read(f.readline().split()[0]) # Scaling parameters for turbulence (still hawc_wind_params) f.readline() @@ -889,8 +889,9 @@ def read_InflowWind(self): f.readline() self.fst_vt['InflowWind']['URef'] = float_read(f.readline().split()[0]) self.fst_vt['InflowWind']['WindProfile'] = int(f.readline().split()[0]) - self.fst_vt['InflowWind']['PLExp'] = float_read(f.readline().split()[0]) + self.fst_vt['InflowWind']['PLExp_Hawc'] = float_read(f.readline().split()[0]) self.fst_vt['InflowWind']['Z0'] = float_read(f.readline().split()[0]) + self.fst_vt['InflowWind']['XOffset'] = float_read(f.readline().split()[0]) # Inflow Wind Output Parameters (inflow_out_params) f.readline() @@ -1002,7 +1003,6 @@ def read_AeroDyn14Tower(self): self.fst_vt['AeroDynTower']['TwrRe'][i] = data[0] self.fst_vt['AeroDynTower']['TwrCD'][i,:] = data[1:] - def read_AeroDyn15(self): # AeroDyn v15.03 @@ -1052,7 +1052,7 @@ def read_AeroDyn15(self): # Dynamic Blade-Element/Momentum Theory Options f.readline() self.fst_vt['AeroDyn15']['DBEMT_Mod'] = int(f.readline().split()[0]) - self.fst_vt['AeroDyn15']['tau1_const'] = int(f.readline().split()[0]) + self.fst_vt['AeroDyn15']['tau1_const'] = float_read(f.readline().split()[0]) # Olaf -- cOnvecting LAgrangian Filaments (Free Vortex Wake) Theory Options f.readline() @@ -1120,6 +1120,10 @@ 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() def read_AeroDyn15Blade(self): # AeroDyn v5.00 Blade Definition File @@ -1264,6 +1268,56 @@ def read_AeroDyn15Coord(self): f.close() + 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() + 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]) + 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]) + f.readline() + f.close() + + def read_ServoDyn(self): # ServoDyn v1.05 Input File # Currently no differences between FASTv8.16 and OpenFAST. @@ -1287,12 +1341,12 @@ def read_ServoDyn(self): self.fst_vt['ServoDyn']['TPitManS1'] = float_read(f.readline().split()[0]) self.fst_vt['ServoDyn']['TPitManS2'] = float_read(f.readline().split()[0]) self.fst_vt['ServoDyn']['TPitManS3'] = float_read(f.readline().split()[0]) - self.fst_vt['ServoDyn']['PitManRat1'] = float_read(f.readline().split()[0]) - self.fst_vt['ServoDyn']['PitManRat2'] = float_read(f.readline().split()[0]) - self.fst_vt['ServoDyn']['PitManRat3'] = float_read(f.readline().split()[0]) - self.fst_vt['ServoDyn']['BlPitchF1'] = float_read(f.readline().split()[0]) - self.fst_vt['ServoDyn']['BlPitchF2'] = float_read(f.readline().split()[0]) - self.fst_vt['ServoDyn']['BlPitchF3'] = float_read(f.readline().split()[0]) + self.fst_vt['ServoDyn']['PitManRat(1)'] = float_read(f.readline().split()[0]) + self.fst_vt['ServoDyn']['PitManRat(2)'] = float_read(f.readline().split()[0]) + self.fst_vt['ServoDyn']['PitManRat(3)'] = float_read(f.readline().split()[0]) + self.fst_vt['ServoDyn']['BlPitchF(1)'] = float_read(f.readline().split()[0]) + self.fst_vt['ServoDyn']['BlPitchF(2)'] = float_read(f.readline().split()[0]) + self.fst_vt['ServoDyn']['BlPitchF(3)'] = float_read(f.readline().split()[0]) # Geneartor and Torque Control (gen_torq_ctrl) f.readline() @@ -1447,7 +1501,7 @@ def read_DISCON_in(self): self.fst_vt['DISCON_in']['Ct_table'] = Ct_table self.fst_vt['DISCON_in']['Cq_table'] = Cq_table except: - pass + print('WARNING: Cp table not loaded!') # Add some DISCON entries that might be needed within WISDEM self.fst_vt['DISCON_in']['v_rated'] = 1. @@ -1455,7 +1509,6 @@ def read_DISCON_in(self): else: del self.fst_vt['DISCON_in'] - def read_HydroDyn(self): # AeroDyn v2.03 @@ -2150,7 +2203,8 @@ def read_MoorDyn(self): self.fst_vt['MoorDyn']['NumSegs'] = [] self.fst_vt['MoorDyn']['NodeAnch'] = [] self.fst_vt['MoorDyn']['NodeFair'] = [] - self.fst_vt['MoorDyn']['Flags_Outputs'] = [] + self.fst_vt['MoorDyn']['Outputs'] = [] + self.fst_vt['MoorDyn']['CtrlChan'] = [] for i in range(self.fst_vt['MoorDyn']['NLines']): data_line = f.readline().strip().split() self.fst_vt['MoorDyn']['Line'].append(int(data_line[0])) @@ -2159,7 +2213,11 @@ def read_MoorDyn(self): 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']['Flags_Outputs'].append(str(data_line[6])) + 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() self.fst_vt['MoorDyn']['dtM'] = float_read(f.readline().split()[0]) self.fst_vt['MoorDyn']['kbot'] = float_read(f.readline().split()[0]) diff --git a/ROSCO_toolbox/ofTools/fast_io/FAST_vars.py b/ROSCO_toolbox/ofTools/fast_io/FAST_vars.py index c6370d780..a1b605dfd 100644 --- a/ROSCO_toolbox/ofTools/fast_io/FAST_vars.py +++ b/ROSCO_toolbox/ofTools/fast_io/FAST_vars.py @@ -1,6 +1,6 @@ from numpy import zeros, array import numpy as np -from ofTools.fast_io.FAST_vars_out import FstOutput, Fst7Output +from ROSCO_toolbox.ofTools.fast_io.FAST_vars_out import FstOutput, Fst7Output # This variable tree contains all parameters required to create a FAST model # for FAST versions 7 and 8. @@ -288,12 +288,12 @@ InflowWind['PLexp'] = 0.0 # Parameters for Uniform wind file [used only for WindType = 2] -InflowWind['Filename'] = '' +InflowWind['UniformFilename'] = '' InflowWind['RefHt'] = 0.0 InflowWind['RefLength'] = 0.0 # Parameters for Binary TurbSim Full-Field files [used only for WindType = 3] -InflowWind['Filename'] = '' +InflowWind['TurbSimFilename'] = '' # Parameters for Binary Bladed-style Full-Field files [used only for WindType = 4] InflowWind['FilenameRoot'] = '' @@ -321,6 +321,7 @@ InflowWind['WindProfile'] = 0 InflowWind['PLExp'] = 0.0 InflowWind['Z0'] = 0.0 +InflowWind['InitPosition(x)'] = 0.0 # Inflow Wind Output Parameters (actual OutList included in master OutList) InflowWind['SumPrint'] = False @@ -510,12 +511,12 @@ ServoDyn['TPitManE1'] = 0.0 #FAST7 only ServoDyn['TPitManE2'] = 0.0 #FAST7 only ServoDyn['TPitManE3'] = 0.0 #FAST7 only -ServoDyn['PitManRat1'] = 0.0 -ServoDyn['PitManRat2'] = 0.0 -ServoDyn['PitManRat3'] = 0.0 -ServoDyn['BlPitchF1'] = 0.0 -ServoDyn['BlPitchF2'] = 0.0 -ServoDyn['BlPitchF3'] = 0.0 +ServoDyn['PitManRat(1)'] = 0.0 +ServoDyn['PitManRat(2)'] = 0.0 +ServoDyn['PitManRat(3)'] = 0.0 +ServoDyn['BlPitchF(1)'] = 0.0 +ServoDyn['BlPitchF(2)'] = 0.0 +ServoDyn['BlPitchF(3)'] = 0.0 ServoDyn['BlPitch1'] = 0.0 #FAST7 only ServoDyn['BlPitch2'] = 0.0 #FAST7 only ServoDyn['BlPitch3'] = 0.0 #FAST7 only diff --git a/ROSCO_toolbox/ofTools/fast_io/FAST_writer.py b/ROSCO_toolbox/ofTools/fast_io/FAST_writer.py index 274e70ae6..bbbe6b0f5 100644 --- a/ROSCO_toolbox/ofTools/fast_io/FAST_writer.py +++ b/ROSCO_toolbox/ofTools/fast_io/FAST_writer.py @@ -4,8 +4,8 @@ import numpy as np from functools import reduce -from ofTools.fast_io.FAST_reader import InputReader_Common, InputReader_OpenFAST, InputReader_FAST7 -from ofTools.fast_io.FAST_vars import FstModel +from ROSCO_toolbox.ofTools.fast_io.FAST_reader import InputReader_Common, InputReader_OpenFAST, InputReader_FAST7 +from ROSCO_toolbox.ofTools.fast_io.FAST_vars import FstModel from ROSCO_toolbox.utilities import write_rotor_performance, write_DISCON ROSCO = True @@ -549,8 +549,11 @@ def write_ElastoDyn(self): f.write('{:<22} {:<11} {:}'.format('"'+self.fst_vt['ElastoDyn']['OutFmt']+'"', 'OutFmt', '- Format used for text tabular output (except time). Resulting field should be 10 characters. (quoted string) (currently unused)\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ElastoDyn']['TStart'], 'TStart', '- Time to begin tabular output (s) (currently unused)\n')) 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')) - 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(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')) + 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(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')) @@ -685,24 +688,25 @@ def write_InflowWind(self): f.write('Generated with AeroElasticSE FAST driver\n') f.write('---------------------------------------------------------------------------------------------------------------\n') f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['InflowWind']['Echo'], 'Echo', '- Echo input data to .ech (flag)\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['InflowWind']['WindType'], 'WindType', '- switch for wind file type (1=steady; 2=uniform; 3=binary TurbSim FF; 4=binary Bladed-style FF; 5=HAWC format; 6=User defined)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['InflowWind']['WindType'], 'WindType', '- switch for wind file type (1=steady; 2=uniform; 3=binary TurbSim FF; 4=binary Bladed-style FF; 5=HAWC format; 6=User defined; 7=native Bladed FF)\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['InflowWind']['PropagationDir'], 'PropagationDir', '- Direction of wind propagation (meteoroligical rotation from aligned with X (positive rotates towards -Y) -- degrees)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['InflowWind']['VFlowAng'], 'VFlowAng', '- Upflow angle (degrees) (not used for native Bladed format WindType=7)\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['InflowWind']['NWindVel'], 'NWindVel', '- Number of points to output the wind velocity (0 to 9)\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['InflowWind']['WindVxiList'], 'WindVxiList', '- List of coordinates in the inertial X direction (m)\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['InflowWind']['WindVyiList'], 'WindVyiList', '- List of coordinates in the inertial Y direction (m)\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['InflowWind']['WindVziList'], 'WindVziList', '- List of coordinates in the inertial Z direction (m)\n')) f.write('================== Parameters for Steady Wind Conditions [used only for WindType = 1] =========================\n') f.write('{:<22} {:<11} {:}'.format(self.fst_vt['InflowWind']['HWindSpeed'], 'HWindSpeed', '- Horizontal windspeed (m/s)\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['InflowWind']['RefHt'], 'RefHtT1', '- Reference height for horizontal wind speed (m)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['InflowWind']['RefHt'], 'RefHt', '- Reference height for horizontal wind speed (m)\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['InflowWind']['PLexp'], 'PLexp', '- Power law exponent (-)\n')) f.write('================== Parameters for Uniform wind file [used only for WindType = 2] ============================\n') - f.write('{:<22} {:<11} {:}'.format('"'+self.fst_vt['InflowWind']['Filename']+'"', 'FilenameT2', '- Filename of time series data for uniform wind field. (-)\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['InflowWind']['RefHt'], 'RefHtT2', '- Reference height for horizontal wind speed (m)\n')) + f.write('{:<22} {:<11} {:}'.format('"'+self.fst_vt['InflowWind']['Filename_Uni']+'"', 'Filename_Uni', '- Filename of time series data for uniform wind field. (-)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['InflowWind']['RefHt_Uni'], 'RefHt_Uni', '- Reference height for horizontal wind speed (m)\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['InflowWind']['RefLength'], 'RefLength', '- Reference length for linear horizontal and vertical sheer (-)\n')) f.write('================== Parameters for Binary TurbSim Full-Field files [used only for WindType = 3] ==============\n') - f.write('{:<22} {:<11} {:}'.format('"'+self.fst_vt['InflowWind']['Filename']+'"', 'FilenameT3', '- Name of the Full field wind file to use (.bts)\n')) + f.write('{:<22} {:<11} {:}'.format('"'+self.fst_vt['InflowWind']['FileName_BTS']+'"', 'FileName_BTS', '- Name of the Full field wind file to use (.bts)\n')) f.write('================== Parameters for Binary Bladed-style Full-Field files [used only for WindType = 4] =========\n') - f.write('{:<22} {:<11} {:}'.format('"'+self.fst_vt['InflowWind']['FilenameRoot']+'"', 'FilenameT4', '- Rootname of the full-field wind file to use (.wnd, .sum)\n')) + f.write('{:<22} {:<11} {:}'.format('"'+self.fst_vt['InflowWind']['FilenameRoot']+'"', 'FilenameRoot', '- Rootname of the full-field wind file to use (.wnd, .sum)\n')) 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')) @@ -714,7 +718,7 @@ def write_InflowWind(self): 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'], 'RefHtT5', '- reference height; the height (in meters) of the vertical center of the grid (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')) @@ -726,8 +730,9 @@ def write_InflowWind(self): 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'], 'PLExp', '- Power law exponent (-) (used for PL wind profile type only)\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') @@ -864,6 +869,9 @@ def write_AeroDyn15(self): if self.fst_vt['AeroDyn15']['af_data'][1][0]['NumCoords'] != 0: self.write_AeroDyn15Coord() + if self.fst_vt['AeroDyn15']['WakeMod'] == 3: + self.write_OLAF() + # Generate AeroDyn v15.03 input file self.fst_vt['Fst']['AeroFile'] = self.FAST_namingOut + '_AeroDyn15.dat' ad_file = os.path.join(self.FAST_runDirectory, self.fst_vt['Fst']['AeroFile']) @@ -894,23 +902,24 @@ def write_AeroDyn15(self): f.write('{: 2.15e} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['Pvap'], 'Pvap', '- Vapour pressure of fluid (Pa) [used only when CavitCheck=True]\n')) f.write('{: 2.15e} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['FluidDepth'], 'FluidDepth', '- Water depth above mid-hub height (m) [used only when CavitCheck=True]\n')) f.write('====== Blade-Element/Momentum Theory Options ====================================================== [used only when WakeMod=1]\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} [used only when WakeMod=1]\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]\n')) - f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['TipLoss'], 'TipLoss', '- Use the Prandtl tip-loss model? (flag) [used only when WakeMod=1]\n')) - f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['HubLoss'], 'HubLoss', '- Use the Prandtl hub-loss model? (flag) [used only when WakeMod=1]\n')) - f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['TanInd'], 'TanInd', '- Include tangential induction in BEMT calculations? (flag) [used only when WakeMod=1]\n')) - f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['AIDrag'], 'AIDrag', '- Include the drag term in the axial-induction calculation? (flag) [used only when WakeMod=1]\n')) - f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['TIDrag'], 'TIDrag', '- Include the drag term in the tangential-induction calculation? (flag) [used only when WakeMod=1 and TanInd=TRUE]\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['IndToler'], 'IndToler', '- Convergence tolerance for BEMT nonlinear solve residual equation {or "default"} (-) [used only when WakeMod=1]\n')) - f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['MaxIter'], 'MaxIter', '- Maximum number of iteration steps (-) [used only when WakeMod=1]\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')) + f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['HubLoss'], 'HubLoss', '- Use the Prandtl hub-loss model? (flag) [unused when WakeMod=0 or 3]\n')) + f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['TanInd'], 'TanInd', '- Include tangential induction in BEMT calculations? (flag) [unused when WakeMod=0 or 3]\n')) + f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['AIDrag'], 'AIDrag', '- Include the drag term in the axial-induction calculation? (flag) [unused when WakeMod=0 or 3]\n')) + 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('{:<22d} {:<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('{:<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') - f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['OLAFInputFileName'], 'OLAFInputFileName', '- Input file for OLAF [used only when WakeMod=3]\n')) + olaf_file = self.FAST_namingOut + '_OLAF.dat' + f.write('{!s:<22} {:<11} {:}'.format(olaf_file, 'OLAFInputFileName', '- Input file for OLAF [used only when WakeMod=3]\n')) f.write('====== Beddoes-Leishman Unsteady Airfoil Aerodynamics Options ===================================== [used only when AFAeroMod=2]\n') - f.write('{:<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=Minemma/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('{:<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('====== 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')) @@ -1140,7 +1149,56 @@ def write_AeroDyn15Coord(self): for row in coord: f.write(' '.join(['{: 2.14e}'.format(val) for val in row])+'\n') 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('--------------------------- GENERAL OPTIONS ---------------------------------------------------\n') + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['OLAF']['IntMethod'], 'Integration method', '{5: Forward Euler 1st order, default: 5} (switch)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['OLAF']['DTfvw'], 'DTfvw method', 'Time interval for wake propagation. {default: dtaero} (s)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['AeroDyn15']['OLAF']['FreeWakeStart'], 'FreeWakeStart method', '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('===============================================================================================\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('------------------- 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('------------------- 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('------------------- 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('===============================================================================================\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('------------------------------------------------------------------------------------------------\n') + + f.close() def write_ServoDyn(self): # ServoDyn v1.05 Input File @@ -1160,12 +1218,12 @@ def write_ServoDyn(self): f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ServoDyn']['TPitManS1'], 'TPitManS(1)', '- Time to start override pitch maneuver for blade 1 and end standard pitch control (s)\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ServoDyn']['TPitManS2'], 'TPitManS(2)', '- Time to start override pitch maneuver for blade 2 and end standard pitch control (s)\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ServoDyn']['TPitManS3'], 'TPitManS(3)', '- Time to start override pitch maneuver for blade 3 and end standard pitch control (s) [unused for 2 blades]\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ServoDyn']['PitManRat1'], 'PitManRat(1)', '- Pitch rate at which override pitch maneuver heads toward final pitch angle for blade 1 (deg/s)\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ServoDyn']['PitManRat2'], 'PitManRat(2)', '- Pitch rate at which override pitch maneuver heads toward final pitch angle for blade 2 (deg/s)\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ServoDyn']['PitManRat3'], 'PitManRat(3)', '- Pitch rate at which override pitch maneuver heads toward final pitch angle for blade 3 (deg/s) [unused for 2 blades]\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ServoDyn']['BlPitchF1'], 'BlPitchF(1)', '- Blade 1 final pitch for pitch maneuvers (degrees)\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ServoDyn']['BlPitchF2'], 'BlPitchF(2)', '- Blade 2 final pitch for pitch maneuvers (degrees)\n')) - f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ServoDyn']['BlPitchF3'], 'BlPitchF(3)', '- Blade 3 final pitch for pitch maneuvers (degrees) [unused for 2 blades]\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ServoDyn']['PitManRat(1)'], 'PitManRat(1)', '- Pitch rate at which override pitch maneuver heads toward final pitch angle for blade 1 (deg/s)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ServoDyn']['PitManRat(2)'], 'PitManRat(2)', '- Pitch rate at which override pitch maneuver heads toward final pitch angle for blade 2 (deg/s)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ServoDyn']['PitManRat(3)'], 'PitManRat(3)', '- Pitch rate at which override pitch maneuver heads toward final pitch angle for blade 3 (deg/s) [unused for 2 blades]\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ServoDyn']['BlPitchF(1)'], 'BlPitchF(1)', '- Blade 1 final pitch for pitch maneuvers (degrees)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ServoDyn']['BlPitchF(2)'], 'BlPitchF(2)', '- Blade 2 final pitch for pitch maneuvers (degrees)\n')) + f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ServoDyn']['BlPitchF(3)'], 'BlPitchF(3)', '- Blade 3 final pitch for pitch maneuvers (degrees) [unused for 2 blades]\n')) f.write('---------------------- GENERATOR AND TORQUE CONTROL ----------------------------\n') f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ServoDyn']['VSContrl'], 'VSContrl', '- Variable-speed control mode {0: none, 1: simple VS, 3: user-defined from routine UserVSCont, 4: user-defined from Simulink/Labview, 5: user-defined from Bladed-style DLL} (switch)\n')) f.write('{:<22} {:<11} {:}'.format(self.fst_vt['ServoDyn']['GenModel'], 'GenModel', '- Generator model {1: simple, 2: Thevenin, 3: user-defined from routine UserGen} (switch) [used only when VSContrl=0]\n')) @@ -1285,7 +1343,10 @@ def write_DISCON_in(self): controller.pitch_op_pc = self.fst_vt['DISCON_in']['PC_GS_angles'] controller.pc_gain_schedule.Kp = self.fst_vt['DISCON_in']['PC_GS_KP'] controller.pc_gain_schedule.Ki = self.fst_vt['DISCON_in']['PC_GS_KI'] - controller.Ki_ipc1p = self.fst_vt['DISCON_in']['IPC_KI'] + if 'IPC_KI' in self.fst_vt['DISCON_in'].keys(): + controller.Ki_ipc1p = self.fst_vt['DISCON_in']['IPC_KI'][0] + else: + controller.Ki_ipc1p = 0. controller.max_pitch = self.fst_vt['DISCON_in']['PC_MaxPit'] controller.min_pitch = self.fst_vt['DISCON_in']['PC_MinPit'] controller.vs_minspd = self.fst_vt['DISCON_in']['VS_MinOMSpd'] @@ -1307,7 +1368,6 @@ def write_DISCON_in(self): controller.Ki_flap = self.fst_vt['DISCON_in']['Flp_Ki'] controller.flp_angle = self.fst_vt['DISCON_in']['Flp_Angle'] controller.flp_maxpit = self.fst_vt['DISCON_in']['Flp_MaxPit'] - controller.Ki_ipc1p = self.fst_vt['DISCON_in']['IPC_KI'][0] turbine = type('', (), {})() turbine.Cp = type('', (), {})() @@ -1641,7 +1701,13 @@ def write_SubDyn(self): f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['SubDyn']['NDiv'], 'NDiv', '- Number of sub-elements per member\n')) f.write('{!s:<22} {:<11} {:}'.format(self.fst_vt['SubDyn']['CBMod'], 'CBMod', '- [T/F] If True perform C-B reduction, else full FEM dofs will be retained. If True, select Nmodes to retain in C-B reduced system.\n')) 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')) - f.write('{:<22d} {:<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')) + + JDampings = self.fst_vt['SubDyn']['JDampings'] + if isinstance(JDampings, int): + 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')) + f.write('---- STRUCTURE JOINTS: joints connect structure members (~Hydrodyn Input File)---\n') f.write('{:<22d} {:<11} {:}'.format(self.fst_vt['SubDyn']['NJoints'], 'NJoints', '- Number of joints (-)\n')) f.write(" ".join(['{:^11s}'.format(i) for i in ['JointID', 'JointXss', 'JointYss', 'JointZss']])+' [Coordinates of Member joints in SS-Coordinate System]\n') @@ -1883,8 +1949,8 @@ def write_MoorDyn(self): 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', 'Flags/Outputs']])+'\n') - f.write(" ".join(['{:^11s}'.format(i) for i in ['(-)', '(-)', '(m)', '(-)', '(-)', '(-)', '(-)']])+'\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']): ln = [] ln.append('{:^11d}'.format(self.fst_vt['MoorDyn']['Line'][i])) @@ -1893,7 +1959,8 @@ def write_MoorDyn(self): 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']['Flags_Outputs'][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')) diff --git a/ROSCO_toolbox/ofTools/fast_io/pyIECWind.py b/ROSCO_toolbox/ofTools/fast_io/pyIECWind.py index 2305e4fc0..3cc899bb2 100644 --- a/ROSCO_toolbox/ofTools/fast_io/pyIECWind.py +++ b/ROSCO_toolbox/ofTools/fast_io/pyIECWind.py @@ -2,9 +2,9 @@ import os, sys # import matplotlib.pyplot as plt -from ofTools.fast_io.turbsim_io.turbsim_writer import TurbsimBuilder -from ofTools.fast_io.turbsim_io.turbsim_wrapper import Turbsim_wrapper -from ofTools.fast_io.turbsim_io.turbsim_vartrees import turbsiminputs +from ROSCO_toolbox.ofTools.fast_io.turbsim_io.turbsim_writer import TurbsimBuilder +from ROSCO_toolbox.ofTools.fast_io.turbsim_io.turbsim_wrapper import Turbsim_wrapper +from ROSCO_toolbox.ofTools.fast_io.turbsim_io.turbsim_vartrees import turbsiminputs # from AeroelasticSE.Turbsim_mdao.pyturbsim_wrapper import pyTurbsim_wrapper @@ -106,6 +106,7 @@ def EOG(self, V_hub_in): shear_vert = np.zeros_like(t)+alpha shear_vert_lin = np.zeros_like(t) V_gust = np.zeros_like(t) + upflow = np.zeros_like(t) V_gust = min([ 1.35*(V_e1 - V_hub), 3.3*(sigma_1/(1+0.1*(self.D/self.Sigma_1))) ]) @@ -120,7 +121,7 @@ def EOG(self, V_hub_in): self.fname_out = [] self.fname_type = [] fname = self.case_name + '_EOG_U%2.1f.wnd'%V_hub_in - data = np.column_stack((t, V, V_dir, V_vert, shear_horz, shear_vert, shear_vert_lin, V_gust_t)) + data = np.column_stack((t, V, V_dir, V_vert, shear_horz, shear_vert, shear_vert_lin, V_gust_t, upflow)) hd = [] hd.append('! Extreme operating guest\n') hd = self.heading_common(hd) @@ -155,8 +156,9 @@ def EDC(self, V_hub_in): shear_vert = np.zeros_like(t)+alpha shear_vert_lin = np.zeros_like(t) V_gust = np.zeros_like(t) + upflow = np.zeros_like(t) - # Transcient + # Transient Theta_e = 4.*np.arctan(sigma_1/(V_hub*(1.+0.01*(self.D/self.Sigma_1))))*180./np.pi if Theta_e > 180.: Theta_e = 180. @@ -177,7 +179,7 @@ def EDC(self, V_hub_in): if self.dir_change.lower() == 'both' or self.dir_change.lower() == '+': ## Vert fname = self.case_name + '_EDC_P_U%2.1f.wnd'%V_hub_in - data = np.column_stack((t, V, Theta_p, V_vert, shear_horz, shear_vert, shear_vert_lin, V_gust)) + data = np.column_stack((t, V, Theta_p, V_vert, shear_horz, shear_vert, shear_vert_lin, V_gust, upflow)) hd = [] hd.append('! Exteme Vertical Wind Shear, positive\n') hd = self.heading_common(hd) @@ -190,7 +192,7 @@ def EDC(self, V_hub_in): if self.dir_change.lower() == 'both' or self.dir_change.lower() == '-': ## Vert fname = self.case_name + '_EDC_N_U%2.1f.wnd'%V_hub_in - data = np.column_stack((t, V, Theta_n, V_vert, shear_horz, shear_vert, shear_vert_lin, V_gust)) + data = np.column_stack((t, V, Theta_n, V_vert, shear_horz, shear_vert, shear_vert_lin, V_gust, upflow)) hd = [] hd.append('! Exteme Vertical Wind Shear, negative\n') hd = self.heading_common(hd) @@ -224,8 +226,9 @@ def ECD(self, V_hub_in): shear_vert = np.zeros_like(t)+alpha shear_vert_lin = np.zeros_like(t) V_gust = np.zeros_like(t) + upflow = np.zeros_like(t) - # Transcient + # Transient if V_hub < 4: Theta_cg = 180 else: @@ -250,7 +253,7 @@ def ECD(self, V_hub_in): if self.dir_change.lower() == 'both' or self.dir_change.lower() == '+': ## Vert fname = self.case_name + '_ECD_P_U%2.1f.wnd'%V_hub_in - data = np.column_stack((t, V, Theta_p, V_vert, shear_horz, shear_vert, shear_vert_lin, V_gust)) + data = np.column_stack((t, V, Theta_p, V_vert, shear_horz, shear_vert, shear_vert_lin, V_gust, upflow)) hd = [] hd.append('! Exteme coherent gust with direction change, positive\n') hd = self.heading_common(hd) @@ -263,7 +266,7 @@ def ECD(self, V_hub_in): if self.dir_change.lower() == 'both' or self.dir_change.lower() == '-': ## Vert fname = self.case_name + '_ECD_N_U%2.1f.wnd'%V_hub_in - data = np.column_stack((t, V, Theta_n, V_vert, shear_horz, shear_vert, shear_vert_lin, V_gust)) + data = np.column_stack((t, V, Theta_n, V_vert, shear_horz, shear_vert, shear_vert_lin, V_gust, upflow)) hd = [] hd.append('! Exteme coherent gust with direction change, negative\n') hd = self.heading_common(hd) @@ -297,8 +300,9 @@ def EWS(self, V_hub_in): # shear_horz = np.zeros_like(t) shear_vert = np.zeros_like(t)+alpha V_gust = np.zeros_like(t) + upflow = np.zeros_like(t) - # Transcient + # Transient shear_lin_p = np.zeros_like(t) shear_lin_n = np.zeros_like(t) @@ -313,7 +317,7 @@ def EWS(self, V_hub_in): if self.shear_orient.lower() == 'both' or self.shear_orient.lower() == 'v': ## Vert fname = self.case_name + '_EWS_V_P_U%2.1f.wnd'%V_hub_in - data = np.column_stack((t, V, V_dir, V_vert, np.zeros_like(t), shear_vert, shear_lin_p, V_gust)) + data = np.column_stack((t, V, V_dir, V_vert, np.zeros_like(t), shear_vert, shear_lin_p, V_gust, upflow)) hd = [] hd.append('! Exteme Vertical Wind Shear, positive\n') hd = self.heading_common(hd) @@ -325,7 +329,7 @@ def EWS(self, V_hub_in): if self.shear_orient.lower() == 'both' or self.shear_orient.lower() == 'h': # Horz fname = self.case_name + '_EWS_H_P_U%2.1f.wnd'%V_hub_in - data = np.column_stack((t, V, V_dir, V_vert, shear_lin_p, shear_vert, np.zeros_like(t), V_gust)) + data = np.column_stack((t, V, V_dir, V_vert, shear_lin_p, shear_vert, np.zeros_like(t), V_gust, upflow)) hd = [] hd.append('! Exteme Horizontal Wind Shear, positive\n') hd = self.heading_common(hd) @@ -338,7 +342,7 @@ def EWS(self, V_hub_in): if self.shear_orient.lower() == 'both' or self.shear_orient.lower() == 'v': ## Vert fname = self.case_name + '_EWS_V_N_U%2.1f.wnd'%V_hub_in - data = np.column_stack((t, V, V_dir, V_vert, np.zeros_like(t), shear_vert, shear_lin_n, V_gust)) + data = np.column_stack((t, V, V_dir, V_vert, np.zeros_like(t), shear_vert, shear_lin_n, V_gust, upflow)) hd = [] hd.append('! Exteme Vertical Wind Shear, negative\n') hd = self.heading_common(hd) @@ -350,7 +354,7 @@ def EWS(self, V_hub_in): if self.shear_orient.lower() == 'both' or self.shear_orient.lower() == 'h': # Horz fname = self.case_name + '_EWS_H_N_U%2.1f.wnd'%V_hub_in - data = np.column_stack((t, V, V_dir, V_vert, shear_lin_n, shear_vert, np.zeros_like(t), V_gust)) + data = np.column_stack((t, V, V_dir, V_vert, shear_lin_n, shear_vert, np.zeros_like(t), V_gust, upflow)) hd = [] hd.append('! Exteme Horizontal Wind Shear, negative\n') hd = self.heading_common(hd) @@ -380,16 +384,16 @@ def write_wnd(self, fname, data, hd): if not os.path.isdir(self.outdir): os.makedirs(self.outdir) - # Move transcient event to user definted time + # Move transient event to user defined time data[:,0] += self.TStart data = np.vstack((data[0,:], data, data[-1,:])) data[0,0] = self.T0 data[-1,0] = self.TF # Headers - hd1 = ['Time', 'Wind', 'Wind', 'Vertical', 'Horiz.', 'Pwr. Law', 'Lin. Vert.', 'Gust'] - hd2 = ['', 'Speed', 'Dir', 'Speed', 'Shear', 'Vert. Shr', 'Shear', 'Speed'] - hd3 = ['(s)', '(m/s)', '(deg)', '(m/s)', '(-)', '(-)', '(-)', '(m/s)', ] + hd1 = ['Time', 'Wind', 'Wind', 'Vertical', 'Horiz.', 'Pwr. Law', 'Lin. Vert.', 'Gust', 'Upflow'] + hd2 = ['', 'Speed', 'Dir', 'Speed', 'Shear', 'Vert. Shr', 'Shear', 'Speed', 'Angle'] + hd3 = ['(s)', '(m/s)', '(deg)', '(m/s)', '(-)', '(-)', '(-)', '(m/s)', '(deg)'] self.fpath = os.path.join(self.outdir, fname) fid = open(self.fpath, 'w') @@ -439,9 +443,9 @@ def setup(self): turbsim_vt.runtime_options.RandSeed1 = self.seed turbsim_vt.runtime_options.WrADTWR = False turbsim_vt.tmspecs.AnalysisTime = self.AnalysisTime - turbsim_vt.tmspecs.HubHt = self.z_hub - turbsim_vt.tmspecs.GridHeight = np.ceil(self.z_hub*1.9) - turbsim_vt.tmspecs.GridWidth = np.ceil(self.z_hub*1.9) + turbsim_vt.tmspecs.HubHt = self.z_hub # wind grid centered at hub height + turbsim_vt.tmspecs.GridHeight = (self.z_hub - 1.) * 2.0 # wind grid stops 1 meter above the ground + turbsim_vt.tmspecs.GridWidth = (self.z_hub - 1.) * 2.0 # squared wind grid turbsim_vt.tmspecs.NumGrid_Z = 25 turbsim_vt.tmspecs.NumGrid_Y = 25 turbsim_vt.tmspecs.HFlowAng = 0.0 diff --git a/ROSCO_toolbox/ofTools/fast_io/turbsim_io/turbsim_writer.py b/ROSCO_toolbox/ofTools/fast_io/turbsim_io/turbsim_writer.py index 9d46c5cd0..167ebf5e8 100644 --- a/ROSCO_toolbox/ofTools/fast_io/turbsim_io/turbsim_writer.py +++ b/ROSCO_toolbox/ofTools/fast_io/turbsim_io/turbsim_writer.py @@ -1,6 +1,6 @@ -from ofTools.fast_io.turbsim_io.turbsim_vartrees import turbsiminputs -from ofTools.fast_io.turbsim_io.turbulence_spectrum import turb_specs -from ofTools.fast_io.turbsim_io.wind_profile_writer import write_wind +from ROSCO_toolbox.ofTools.fast_io.turbsim_io.turbsim_vartrees import turbsiminputs +from ROSCO_toolbox.ofTools.fast_io.turbsim_io.turbulence_spectrum import turb_specs +from ROSCO_toolbox.ofTools.fast_io.turbsim_io.wind_profile_writer import write_wind import os import numpy as np import random diff --git a/ROSCO_toolbox/utilities.py b/ROSCO_toolbox/utilities.py index 31451bc0b..8c210c0df 100644 --- a/ROSCO_toolbox/utilities.py +++ b/ROSCO_toolbox/utilities.py @@ -28,6 +28,7 @@ from matplotlib import transforms from itertools import takewhile, product import struct +import ROSCO_toolbox from ROSCO_toolbox.ofTools.util import spectral # Some useful constants @@ -57,7 +58,7 @@ def write_DISCON(turbine, controller, param_file='DISCON.IN', txt_filename='Cp_C # Should be obvious what's going on here... file = open(param_file,'w') file.write('! Controller parameter input file for the %s wind turbine\n' % turbine.TurbineName) - file.write('! - File written using ROSCO Controller tuning logic on %s\n' % now.strftime('%m/%d/%y')) + file.write('! - File written using ROSCO version {} controller tuning logic on {}\n'.format(ROSCO_toolbox.__version__, now.strftime('%m/%d/%y'))) file.write('\n') file.write('!------- DEBUG ------------------------------------------------------------\n') file.write('{0:<12d} ! LoggingLevel - {{0: write no debug files, 1: write standard output .dbg-file, 2: write standard output .dbg-file and complete avrSWAP-array .dbg2-file}}\n'.format(int(controller.LoggingLevel))) @@ -78,7 +79,7 @@ def write_DISCON(turbine, controller, param_file='DISCON.IN', txt_filename='Cp_C file.write('\n') file.write('!------- FILTERS ----------------------------------------------------------\n') file.write('{:<13.5f} ! F_LPFCornerFreq - Corner frequency (-3dB point) in the low-pass filters, [rad/s]\n'.format(turbine.bld_edgewise_freq * 1/4)) - file.write('{:<13.5f} ! F_LPFDamping - Damping coefficient [used only when F_FilterType = 2]\n'.format(controller.F_LPFDamping)) + file.write('{:<13.5f} ! F_LPFDamping - Damping coefficient {{used only when F_FilterType = 2}} [-]\n'.format(controller.F_LPFDamping)) file.write('{:<13.5f} ! F_NotchCornerFreq - Natural frequency of the notch filter, [rad/s]\n'.format(turbine.twr_freq)) file.write('{:<10.5f}{:<9.5f} ! F_NotchBetaNumDen - Two notch damping values (numerator and denominator, resp) - determines the width and depth of the notch, [-]\n'.format(0.0,0.25)) file.write('{:<014.5f} ! F_SSCornerFreq - Corner frequency (-3dB point) in the first order low pass filter for the setpoint smoother, [rad/s].\n'.format(controller.ss_cornerfreq)) @@ -88,9 +89,9 @@ def write_DISCON(turbine, controller, param_file='DISCON.IN', txt_filename='Cp_C file.write('\n') file.write('!------- BLADE PITCH CONTROL ----------------------------------------------\n') file.write('{:<11d} ! PC_GS_n - Amount of gain-scheduling table entries\n'.format(len(controller.pitch_op_pc))) - file.write('{} ! PC_GS_angles - Gain-schedule table: pitch angles\n'.format(''.join('{:<4.6f} '.format(controller.pitch_op_pc[i]) for i in range(len(controller.pitch_op_pc))))) - file.write('{} ! PC_GS_KP - Gain-schedule table: pitch controller kp gains\n'.format(''.join('{:<4.6f} '.format(controller.pc_gain_schedule.Kp[i]) for i in range(len(controller.pc_gain_schedule.Kp))))) - file.write('{} ! PC_GS_KI - Gain-schedule table: pitch controller ki gains\n'.format(''.join('{:<4.6f} '.format(controller.pc_gain_schedule.Ki[i]) for i in range(len(controller.pc_gain_schedule.Ki))))) + file.write('{} ! PC_GS_angles - Gain-schedule table: pitch angles [rad].\n'.format(''.join('{:<4.6f} '.format(controller.pitch_op_pc[i]) for i in range(len(controller.pitch_op_pc))))) + file.write('{} ! PC_GS_KP - Gain-schedule table: pitch controller kp gains [s].\n'.format(''.join('{:<4.6f} '.format(controller.pc_gain_schedule.Kp[i]) for i in range(len(controller.pc_gain_schedule.Kp))))) + file.write('{} ! PC_GS_KI - Gain-schedule table: pitch controller ki gains [-].\n'.format(''.join('{:<4.6f} '.format(controller.pc_gain_schedule.Ki[i]) for i in range(len(controller.pc_gain_schedule.Ki))))) file.write('{} ! PC_GS_KD - Gain-schedule table: pitch controller kd gains\n'.format(''.join('{:<1.1f} '.format(0.0) for i in range(len(controller.pc_gain_schedule.Ki))))) file.write('{} ! PC_GS_TF - Gain-schedule table: pitch controller tf gains (derivative filter)\n'.format(''.join('{:<1.1f} '.format(0.0) for i in range(len(controller.pc_gain_schedule.Ki))))) file.write('{:<014.5f} ! PC_MaxPit - Maximum physical pitch limit, [rad].\n'.format(controller.max_pitch)) @@ -114,13 +115,13 @@ def write_DISCON(turbine, controller, param_file='DISCON.IN', txt_filename='Cp_C file.write('{:<014.5f} ! VS_MaxTq - Maximum generator torque in Region 3 (HSS side), [Nm].\n'.format(turbine.max_torque)) file.write('{:<014.5f} ! VS_MinTq - Minimum generator (HSS side), [Nm].\n'.format(0.0)) file.write('{:<014.5f} ! VS_MinOMSpd - Optimal mode minimum speed, cut-in speed towards optimal mode gain path, [rad/s]\n'.format(controller.vs_minspd)) - file.write('{:<014.5f} ! VS_Rgn2K - Generator torque constant in Region 2 (HSS side), [N-m/(rad/s)^2]\n'.format(controller.vs_rgn2K)) + file.write('{:<014.5f} ! VS_Rgn2K - Generator torque constant in Region 2 (HSS side), [Nm/(rad/s)^2]\n'.format(controller.vs_rgn2K)) file.write('{:<014.5f} ! VS_RtPwr - Wind turbine rated power [W]\n'.format(turbine.rated_power)) file.write('{:<014.5f} ! VS_RtTq - Rated torque, [Nm].\n'.format(turbine.rated_torque)) file.write('{:<014.5f} ! VS_RefSpd - Rated generator speed [rad/s]\n'.format(controller.vs_refspd)) file.write('{:<11d} ! VS_n - Number of generator PI torque controller gains\n'.format(1)) - file.write('{:<014.5f} ! 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)\n'.format(controller.vs_gain_schedule.Kp[-1])) - file.write('{:<014.5f} ! VS_KI - Integral gain for generator PI torque controller [1/rad Nm]. (Only used in the transitional 2.5 region if VS_ControlMode =/ 2)\n'.format(controller.vs_gain_schedule.Ki[-1])) + file.write('{:<014.5f} ! VS_KP - Proportional gain for generator PI torque controller [-]. (Only used in the transitional 2.5 region if VS_ControlMode =/ 2)\n'.format(controller.vs_gain_schedule.Kp[-1])) + file.write('{:<014.5f} ! VS_KI - Integral gain for generator PI torque controller [s]. (Only used in the transitional 2.5 region if VS_ControlMode =/ 2)\n'.format(controller.vs_gain_schedule.Ki[-1])) file.write('{:<13.2f} ! VS_TSRopt - Power-maximizing region 2 tip-speed-ratio [rad].\n'.format(turbine.TSR_operational)) file.write('\n') file.write('!------- SETPOINT SMOOTHER ---------------------------------------------\n') @@ -139,7 +140,7 @@ def write_DISCON(turbine, controller, param_file='DISCON.IN', txt_filename='Cp_C file.write('{:<7d} {:<10d} ! PerfTableSize - Size of rotor performance tables, first number refers to number of blade pitch angles, second number referse to number of tip-speed ratios\n'.format(len(turbine.Cp.pitch_initial_rad),len(turbine.Cp.TSR_initial))) file.write('{:<11d} ! WE_FOPoles_N - Number of first-order system poles used in EKF\n'.format(len(controller.A))) file.write('{} ! WE_FOPoles_v - Wind speeds corresponding to first-order system poles [m/s]\n'.format(''.join('{:<4.2f} '.format(controller.v[i]) for i in range(len(controller.v))))) - file.write('{} ! WE_FOPoles - First order system poles\n'.format(''.join('{:<10.8f} '.format(controller.A[i]) for i in range(len(controller.A))))) + file.write('{} ! WE_FOPoles - First order system poles [1/s]\n'.format(''.join('{:<10.8f} '.format(controller.A[i]) for i in range(len(controller.A))))) file.write('\n') file.write('!------- YAW CONTROL ------------------------------------------------------\n') file.write('{:<13.1f} ! Y_ErrThresh - Yaw error threshold. Turbine begins to yaw when it passes this. [rad^2 s]\n'.format(0.0)) @@ -150,8 +151,8 @@ def write_DISCON(turbine, controller, param_file='DISCON.IN', txt_filename='Cp_C file.write('{:<13.1f} ! Y_IPC_omegaLP - Low-pass filter corner frequency for the Yaw-by-IPC controller to filtering the yaw alignment error, [rad/s].\n'.format(0.0)) file.write('{:<13.1f} ! Y_IPC_zetaLP - Low-pass filter damping factor for the Yaw-by-IPC controller to filtering the yaw alignment error, [-].\n'.format(0.0)) file.write('{:<13.1f} ! Y_MErrSet - Yaw alignment error, set point [rad]\n'.format(0.0)) - file.write('{:<13.1f} ! Y_omegaLPFast - Corner frequency fast low pass filter, 1.0 [Hz]\n'.format(0.0)) - file.write('{:<13.1f} ! Y_omegaLPSlow - Corner frequency slow low pass filter, 1/60 [Hz]\n'.format(0.0)) + file.write('{:<13.1f} ! Y_omegaLPFast - Corner frequency fast low pass filter, 1.0 [rad/s]\n'.format(0.0)) + file.write('{:<13.1f} ! Y_omegaLPSlow - Corner frequency slow low pass filter, 1/60 [rad/s]\n'.format(0.0)) file.write('{:<13.1f} ! Y_Rate - Yaw rate [rad/s]\n'.format(0.0)) file.write('\n') file.write('!------- TOWER FORE-AFT DAMPING -------------------------------------------\n') @@ -161,7 +162,7 @@ def write_DISCON(turbine, controller, param_file='DISCON.IN', txt_filename='Cp_C file.write('\n') file.write('!------- MINIMUM PITCH SATURATION -------------------------------------------\n') file.write('{:<11d} ! PS_BldPitchMin_N - Number of values in minimum blade pitch lookup table (should equal number of values in PS_WindSpeeds and PS_BldPitchMin)\n'.format(len(controller.ps_min_bld_pitch))) - file.write('{} ! PS_WindSpeeds - Wind speeds corresponding to minimum blade pitch angles [m/s]\n'.format(''.join('{:<4.2f} '.format(controller.v[i]) for i in range(len(controller.v))))) + file.write('{} ! PS_WindSpeeds - Wind speeds corresponding to minimum blade pitch angles [m/s]\n'.format(''.join('{:<4.4f} '.format(controller.v[i]) for i in range(len(controller.v))))) file.write('{} ! PS_BldPitchMin - Minimum blade pitch angles [rad]\n'.format(''.join('{:<10.8f} '.format(controller.ps_min_bld_pitch[i]) for i in range(len(controller.ps_min_bld_pitch))))) file.write('\n') file.write('!------- SHUTDOWN -----------------------------------------------------------\n') @@ -174,7 +175,7 @@ def write_DISCON(turbine, controller, param_file='DISCON.IN', txt_filename='Cp_C file.write('!------- FLAP ACTUATION -----------------------------------------------------\n') file.write('{:<014.5f} ! Flp_Angle - Initial or steady state flap angle [rad]\n'.format(controller.flp_angle)) file.write('{:<014.8e} ! Flp_Kp - Blade root bending moment proportional gain for flap control [s]\n'.format(controller.Kp_flap[-1])) - file.write('{:<014.8e} ! Flp_Ki - Flap displacement integral gain for flap control [s]\n'.format(controller.Ki_flap[-1])) + file.write('{:<014.8e} ! Flp_Ki - Flap displacement integral gain for flap control [-]\n'.format(controller.Ki_flap[-1])) file.write('{:<014.5f} ! Flp_MaxPit - Maximum (and minimum) flap pitch angle [rad]'.format(controller.flp_maxpit)) file.close() @@ -454,7 +455,7 @@ def DISCON_dict(turbine, controller, txt_filename=None): return DISCON_dict -def run_openfast(fast_dir,fastcall='OpenFAST',fastfile=None,chdir=False): +def run_openfast(fast_dir,fastcall='openfast',fastfile=None,chdir=False): ''' Runs a openfast openfast simulation. diff --git a/Test_Cases/5MW_Land_Simulink/5MW_Land_Simulink.fst b/Test_Cases/5MW_Land_Simulink/5MW_Land_Simulink.fst index f75c49589..6aa1c3c31 100644 --- a/Test_Cases/5MW_Land_Simulink/5MW_Land_Simulink.fst +++ b/Test_Cases/5MW_Land_Simulink/5MW_Land_Simulink.fst @@ -19,12 +19,12 @@ True Echo - Echo input data to .ech (flag) 0 CompMooring - Compute mooring system (switch) {0=None; 1=MAP++; 2=FEAMooring; 3=MoorDyn; 4=OrcaFlex} 0 CompIce - Compute ice loads (switch) {0=None; 1=IceFloe; 2=IceDyn} ---------------------- INPUT FILES --------------------------------------------- -"NRELOffshrBsline5MW_Onshore_ElastoDyn.dat" EDFile - Name of file containing ElastoDyn input parameters (quoted string) -"../5MW_Baseline/NRELOffshrBsline5MW_BeamDyn.dat" BDBldFile(1) - Name of file containing BeamDyn input parameters for blade 1 (quoted string) -"../5MW_Baseline/NRELOffshrBsline5MW_BeamDyn.dat" BDBldFile(2) - Name of file containing BeamDyn input parameters for blade 2 (quoted string) -"../5MW_Baseline/NRELOffshrBsline5MW_BeamDyn.dat" BDBldFile(3) - Name of file containing BeamDyn input parameters for blade 3 (quoted string) -"../5MW_Baseline/NRELOffshrBsline5MW_InflowWind_12mps.dat" InflowFile - Name of file containing inflow wind input parameters (quoted string) -"NRELOffshrBsline5MW_Onshore_AeroDyn15.dat" AeroFile - Name of file containing aerodynamic input parameters (quoted string) +"../NREL-5MW/NRELOffshrBsline5MW_Onshore_ElastoDyn.dat" EDFile - Name of file containing ElastoDyn input parameters (quoted string) +"unused" BDBldFile(1) - Name of file containing BeamDyn input parameters for blade 1 (quoted string) +"unused" BDBldFile(2) - Name of file containing BeamDyn input parameters for blade 2 (quoted string) +"unused" BDBldFile(3) - Name of file containing BeamDyn input parameters for blade 3 (quoted string) +"../NREL-5MW/NRELOffshrBsline5MW_InflowWind.dat" InflowFile - Name of file containing inflow wind input parameters (quoted string) +"../NREL-5MW/NRELOffshrBsline5MW_Onshore_AeroDyn15.dat" AeroFile - Name of file containing aerodynamic input parameters (quoted string) "NRELOffshrBsline5MW_Onshore_ServoDyn.dat" ServoFile - Name of file containing control and electrical-drive input parameters (quoted string) "unused" HydroFile - Name of file containing hydrodynamic input parameters (quoted string) "unused" SubFile - Name of file containing sub-structural input parameters (quoted string) @@ -41,6 +41,12 @@ True TabDelim - Use tab delimiters in text tabular output file? "ES10.3E2" OutFmt - Format used for text tabular output, excluding the time channel. Resulting field should be 10 characters. (quoted string) ---------------------- LINEARIZATION ------------------------------------------- False Linearize - Linearization analysis (flag) +False CalcSteady - Calculate a steady-state periodic operating point before linearization? [unused if Linearize=False] (flag) + 3 TrimCase - Controller parameter to be trimmed {1:yaw; 2:torque; 3:pitch} [used only if CalcSteady=True] (-) + 0.001 TrimTol - Tolerance for the rotational speed convergence [used only if CalcSteady=True] (-) + 0.01 TrimGain - Proportional gain for the rotational speed error (>0) [used only if CalcSteady=True] (rad/(rad/s) for yaw or pitch; Nm/(rad/s) for torque) + 0 Twr_Kdmp - Damping factor for the tower [used only if CalcSteady=True] (N/(m/s)) + 0 Bld_Kdmp - Damping factor for the blades [used only if CalcSteady=True] (N/(m/s)) 2 NLinTimes - Number of times to linearize (-) [>=1] [unused if Linearize=False] 30, 60 LinTimes - List of times at which to linearize (s) [1 to NLinTimes] [unused if Linearize=False] 1 LinInputs - Inputs included in linearization (switch) {0=none; 1=standard; 2=all module inputs (debug)} [unused if Linearize=False] diff --git a/Test_Cases/5MW_Land_Simulink/DISCON.IN b/Test_Cases/5MW_Land_Simulink/DISCON.IN index 1e5cf3de5..2571bbdb9 100644 --- a/Test_Cases/5MW_Land_Simulink/DISCON.IN +++ b/Test_Cases/5MW_Land_Simulink/DISCON.IN @@ -76,11 +76,11 @@ 97.0 ! WE_GearboxRatio - Gearbox ratio [>=1], [-] 43702538.05700 ! 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] -"../5MW_Baseline/Cp_Ct_Cq.NREL5MW.txt" ! PerfFileName - File containing rotor performance tables (Cp,Ct,Cq) +"../NREL-5MW/Cp_Ct_Cq.NREL5MW.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.00 11.90 12.40 12.90 13.40 13.90 14.40 14.90 15.40 15.90 16.40 16.90 17.40 17.90 18.40 18.90 19.40 19.90 20.40 20.90 21.40 21.90 22.40 22.90 23.40 23.90 24.40 24.90 ! WE_FOPoles_v - Wind speeds corresponding to first-order system poles [m/s] --0.01597097 -0.01863280 -0.02129463 -0.02395646 -0.02661829 -0.02928012 -0.03194195 -0.03460377 -0.03726560 -0.03992743 -0.04258926 -0.04525109 -0.04791292 -0.05057475 -0.05323658 -0.05589840 -0.05856023 -0.05136706 -0.06083297 -0.07318141 -0.08698814 -0.10174996 -0.11701540 -0.13277020 -0.14916461 -0.16625567 -0.18314382 -0.20108255 -0.21861726 -0.23708646 -0.25523482 -0.27455940 -0.29291942 -0.31337978 -0.33196662 -0.35213321 -0.37322194 -0.39245925 -0.41381198 -0.43612755 -0.45572506 -0.47749086 -0.50133095 -0.53269989 ! WE_FOPoles - First order system poles +-0.01651600 -0.01926866 -0.02202133 -0.02477399 -0.02752666 -0.03027933 -0.03303199 -0.03578466 -0.03853732 -0.04128999 -0.04404266 -0.04679532 -0.04954799 -0.05230065 -0.05505332 -0.05780599 -0.06055865 -0.05136706 -0.06083297 -0.07318141 -0.08698814 -0.10174996 -0.11701540 -0.13277020 -0.14916461 -0.16625567 -0.18314382 -0.20108255 -0.21861726 -0.23708646 -0.25523482 -0.27455940 -0.29291942 -0.31337978 -0.33196662 -0.35213321 -0.37322194 -0.39245925 -0.41381198 -0.43612755 -0.45572506 -0.47749086 -0.50133095 -0.53269989 ! WE_FOPoles - First order system poles [1/s] !------- YAW CONTROL ------------------------------------------------------ 0.0 ! Y_ErrThresh - Yaw error threshold. Turbine begins to yaw when it passes this. [rad^2 s] diff --git a/Test_Cases/5MW_Land_Simulink/NRELOffshrBsline5MW_Onshore_AeroDyn15.dat b/Test_Cases/5MW_Land_Simulink/NRELOffshrBsline5MW_Onshore_AeroDyn15.dat deleted file mode 100644 index 4b46b1f68..000000000 --- a/Test_Cases/5MW_Land_Simulink/NRELOffshrBsline5MW_Onshore_AeroDyn15.dat +++ /dev/null @@ -1,82 +0,0 @@ -------- AERODYN v15 for OpenFAST INPUT FILE ----------------------------------------------- -NREL 5.0 MW offshore baseline aerodynamic input properties. -====== 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} [WakeMod cannot be 2 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} -False TwrShadow - Calculate tower influence on wind based on downstream tower shadow? (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] -====== Environmental Conditions =================================================================== - 1.225 AirDens - Air density (kg/m^3) - 1.464E-05 KinVisc - Kinematic air viscosity (m^2/s) - 335 SpdSound - Speed of sound (m/s) - 103500 Patm - Atmospheric pressure (Pa) [used only when CavitCheck=True] - 1700 Pvap - Vapour pressure of fluid (Pa) [used only when CavitCheck=True] - 0.5 FluidDepth - Water depth above mid-hub height (m) [used only when CavitCheck=True] -====== Blade-Element/Momentum Theory Options ====================================================== [unused when WakeMod=0] - 2 SkewMod - Type of skewed-wake correction model (switch) {1=uncoupled, 2=Pitt/Peters, 3=coupled} [unused when WakeMod=0] -"default" SkewModFactor - Constant used in Pitt/Peters skewed wake model {or "default" is 15/32*pi} (-) [used only when SkewMod=2; unused when WakeMod=0] -True TipLoss - Use the Prandtl tip-loss model? (flag) [unused when WakeMod=0] -True HubLoss - Use the Prandtl hub-loss model? (flag) [unused when WakeMod=0] -true TanInd - Include tangential induction in BEMT calculations? (flag) [unused when WakeMod=0] -False AIDrag - Include the drag term in the axial-induction calculation? (flag) [unused when WakeMod=0] -False TIDrag - Include the drag term in the tangential-induction calculation? (flag) [unused when WakeMod=0 or TanInd=FALSE] -"Default" IndToler - Convergence tolerance for BEMT nonlinear solve residual equation {or "default"} (-) [unused when WakeMod=0] - 100 MaxIter - Maximum number of iteration steps (-) [unused when WakeMod=0] -====== Dynamic Blade-Element/Momentum Theory Options ============================================== [used only when WakeMod=2] - 2 DBEMT_Mod - Type of dynamic BEMT (DBEMT) model {1=constant tau1, 2=time-dependent tau1} (-) [used only when WakeMod=2] - 4 tau1_const - Time constant for DBEMT (s) [used only when WakeMod=2 and DBEMT_Mod=1] -====== 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] -====== 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 (-) - 2 InCol_Cl - The column in the airfoil tables that contains the lift coefficient (-) - 3 InCol_Cd - The column in the airfoil tables that contains the drag coefficient (-) - 4 InCol_Cm - The column in the airfoil tables that contains the pitching-moment coefficient; use zero if there is no Cm column (-) - 0 InCol_Cpmin - The column in the airfoil tables that contains the Cpmin coefficient; use zero if there is no Cpmin column (-) - 8 NumAFfiles - Number of airfoil files used (-) -"../5MW_Baseline/Airfoils/Cylinder1.dat" AFNames - Airfoil file names (NumAFfiles lines) (quoted strings) -"../5MW_Baseline/Airfoils/Cylinder2.dat" -"../5MW_Baseline/Airfoils/DU40_A17.dat" -"../5MW_Baseline/Airfoils/DU35_A17.dat" -"../5MW_Baseline/Airfoils/DU30_A17.dat" -"../5MW_Baseline/Airfoils/DU25_A17.dat" -"../5MW_Baseline/Airfoils/DU21_A17.dat" -"../5MW_Baseline/Airfoils/NACA64_A17.dat" -====== Rotor/Blade Properties ===================================================================== -True UseBlCm - Include aerodynamic pitching moment in calculations? (flag) -"../5MW_Baseline/NRELOffshrBsline5MW_AeroDyn_blade.dat" ADBlFile(1) - Name of file containing distributed aerodynamic properties for Blade #1 (-) -"../5MW_Baseline/NRELOffshrBsline5MW_AeroDyn_blade.dat" ADBlFile(2) - Name of file containing distributed aerodynamic properties for Blade #2 (-) [unused if NumBl < 2] -"../5MW_Baseline/NRELOffshrBsline5MW_AeroDyn_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=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 -(m) (m) (-) -0.0000000E+00 6.0000000E+00 1.0000000E+00 -8.5261000E+00 5.7870000E+00 1.0000000E+00 -1.7053000E+01 5.5740000E+00 1.0000000E+00 -2.5579000E+01 5.3610000E+00 1.0000000E+00 -3.4105000E+01 5.1480000E+00 1.0000000E+00 -4.2633000E+01 4.9350000E+00 1.0000000E+00 -5.1158000E+01 4.7220000E+00 1.0000000E+00 -5.9685000E+01 4.5090000E+00 1.0000000E+00 -6.8211000E+01 4.2960000E+00 1.0000000E+00 -7.6738000E+01 4.0830000E+00 1.0000000E+00 -8.5268000E+01 3.8700000E+00 1.0000000E+00 -8.7600000E+01 3.8700000E+00 1.0000000E+00 -====== 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] (-) - 1, 9, 19 BlOutNd - Blade nodes whose values will be output (-) - 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, (-) -"RtVAvgxh" -END of input file (the word "END" must appear in the first 3 columns of this last OutList line) ---------------------------------------------------------------------------------------- diff --git a/Test_Cases/5MW_Land_Simulink/NRELOffshrBsline5MW_Onshore_ElastoDyn.dat b/Test_Cases/5MW_Land_Simulink/NRELOffshrBsline5MW_Onshore_ElastoDyn.dat deleted file mode 100644 index f4f02b66e..000000000 --- a/Test_Cases/5MW_Land_Simulink/NRELOffshrBsline5MW_Onshore_ElastoDyn.dat +++ /dev/null @@ -1,159 +0,0 @@ -------- ELASTODYN v1.03.* INPUT FILE ------------------------------------------- -NREL 5.0 MW Baseline Wind Turbine for Use in Offshore Analysis. Properties from Dutch Offshore Wind Energy Converter (DOWEC) 6MW Pre-Design (10046_009.pdf) and REpower 5M 5MW (5m_uk.pdf) ----------------------- SIMULATION CONTROL -------------------------------------- -False Echo - Echo input data to ".ech" (flag) - 3 Method - Integration method: {1: RK4, 2: AB4, or 3: ABM4} (-) -"DEFAULT" DT - Integration time step (s) ----------------------- ENVIRONMENTAL CONDITION --------------------------------- - 9.80665 Gravity - Gravitational acceleration (m/s^2) ----------------------- DEGREES OF FREEDOM -------------------------------------- -True FlapDOF1 - First flapwise blade mode DOF (flag) -True FlapDOF2 - Second flapwise blade mode DOF (flag) -True EdgeDOF - First edgewise blade mode DOF (flag) -False TeetDOF - Rotor-teeter DOF (flag) [unused for 3 blades] -True DrTrDOF - Drivetrain rotational-flexibility DOF (flag) -True GenDOF - Generator DOF (flag) -True YawDOF - Yaw DOF (flag) -True TwFADOF1 - First fore-aft tower bending-mode DOF (flag) -True TwFADOF2 - Second fore-aft tower bending-mode DOF (flag) -True TwSSDOF1 - First side-to-side tower bending-mode DOF (flag) -True TwSSDOF2 - Second side-to-side tower bending-mode DOF (flag) -False PtfmSgDOF - Platform horizontal surge translation DOF (flag) -False PtfmSwDOF - Platform horizontal sway translation DOF (flag) -False PtfmHvDOF - Platform vertical heave translation DOF (flag) -False PtfmRDOF - Platform roll tilt rotation DOF (flag) -False PtfmPDOF - Platform pitch tilt rotation DOF (flag) -False PtfmYDOF - Platform yaw rotation DOF (flag) ----------------------- INITIAL CONDITIONS -------------------------------------- - 0 OoPDefl - Initial out-of-plane blade-tip displacement (meters) - 0 IPDefl - Initial in-plane blade-tip deflection (meters) - 10 BlPitch(1) - Blade 1 initial pitch (degrees) - 10 BlPitch(2) - Blade 2 initial pitch (degrees) - 10 BlPitch(3) - Blade 3 initial pitch (degrees) [unused for 2 blades] - 0 TeetDefl - Initial or fixed teeter angle (degrees) [unused for 3 blades] - 0 Azimuth - Initial azimuth angle for blade 1 (degrees) - 12.1 RotSpeed - Initial or fixed rotor speed (rpm) - 0 NacYaw - Initial or fixed nacelle-yaw angle (degrees) - 0 TTDspFA - Initial fore-aft tower-top displacement (meters) - 0 TTDspSS - Initial side-to-side tower-top displacement (meters) - 0 PtfmSurge - Initial or fixed horizontal surge translational displacement of platform (meters) - 0 PtfmSway - Initial or fixed horizontal sway translational displacement of platform (meters) - 0 PtfmHeave - Initial or fixed vertical heave translational displacement of platform (meters) - 0 PtfmRoll - Initial or fixed roll tilt rotational displacement of platform (degrees) - 0 PtfmPitch - Initial or fixed pitch tilt rotational displacement of platform (degrees) - 0 PtfmYaw - Initial or fixed yaw rotational displacement of platform (degrees) ----------------------- TURBINE CONFIGURATION ----------------------------------- - 3 NumBl - Number of blades (-) - 63 TipRad - The distance from the rotor apex to the blade tip (meters) - 1.5 HubRad - The distance from the rotor apex to the blade root (meters) - -2.5 PreCone(1) - Blade 1 cone angle (degrees) - -2.5 PreCone(2) - Blade 2 cone angle (degrees) - -2.5 PreCone(3) - Blade 3 cone angle (degrees) [unused for 2 blades] - 0 HubCM - Distance from rotor apex to hub mass [positive downwind] (meters) - 0 UndSling - Undersling length [distance from teeter pin to the rotor apex] (meters) [unused for 3 blades] - 0 Delta3 - Delta-3 angle for teetering rotors (degrees) [unused for 3 blades] - 0 AzimB1Up - Azimuth value to use for I/O when blade 1 points up (degrees) - -5.0191 OverHang - Distance from yaw axis to rotor apex [3 blades] or teeter pin [2 blades] (meters) - 1.912 ShftGagL - Distance from rotor apex [3 blades] or teeter pin [2 blades] to shaft strain gages [positive for upwind rotors] (meters) - -5 ShftTilt - Rotor shaft tilt angle (degrees) - 1.9 NacCMxn - Downwind distance from the tower-top to the nacelle CM (meters) - 0 NacCMyn - Lateral distance from the tower-top to the nacelle CM (meters) - 1.75 NacCMzn - Vertical distance from the tower-top to the nacelle CM (meters) - -3.09528 NcIMUxn - Downwind distance from the tower-top to the nacelle IMU (meters) - 0 NcIMUyn - Lateral distance from the tower-top to the nacelle IMU (meters) - 2.23336 NcIMUzn - Vertical distance from the tower-top to the nacelle IMU (meters) - 1.96256 Twr2Shft - Vertical distance from the tower-top to the rotor shaft (meters) - 87.6 TowerHt - Height of tower above ground level [onshore] or MSL [offshore] (meters) - 0 TowerBsHt - Height of tower base above ground level [onshore] or MSL [offshore] (meters) - 0 PtfmCMxt - Downwind distance from the ground level [onshore] or MSL [offshore] to the platform CM (meters) - 0 PtfmCMyt - Lateral distance from the ground level [onshore] or MSL [offshore] to the platform CM (meters) - 0 PtfmCMzt - Vertical distance from the ground level [onshore] or MSL [offshore] to the platform CM (meters) - 0 PtfmRefzt - Vertical distance from the ground level [onshore] or MSL [offshore] to the platform reference point (meters) ----------------------- MASS AND INERTIA ---------------------------------------- - 0 TipMass(1) - Tip-brake mass, blade 1 (kg) - 0 TipMass(2) - Tip-brake mass, blade 2 (kg) - 0 TipMass(3) - Tip-brake mass, blade 3 (kg) [unused for 2 blades] - 56780 HubMass - Hub mass (kg) - 115926 HubIner - Hub inertia about rotor axis [3 blades] or teeter axis [2 blades] (kg m^2) - 534.116 GenIner - Generator inertia about HSS (kg m^2) - 240000 NacMass - Nacelle mass (kg) -2.60789E+06 NacYIner - Nacelle inertia about yaw axis (kg m^2) - 0 YawBrMass - Yaw bearing mass (kg) - 0 PtfmMass - Platform mass (kg) - 0 PtfmRIner - Platform inertia for roll tilt rotation about the platform CM (kg m^2) - 0 PtfmPIner - Platform inertia for pitch tilt rotation about the platform CM (kg m^2) - 0 PtfmYIner - Platform inertia for yaw rotation about the platform CM (kg m^2) ----------------------- BLADE --------------------------------------------------- - 17 BldNodes - Number of blade nodes (per blade) used for analysis (-) -"../5MW_Baseline/NRELOffshrBsline5MW_Blade.dat" BldFile(1) - Name of file containing properties for blade 1 (quoted string) -"../5MW_Baseline/NRELOffshrBsline5MW_Blade.dat" BldFile(2) - Name of file containing properties for blade 2 (quoted string) -"../5MW_Baseline/NRELOffshrBsline5MW_Blade.dat" BldFile(3) - Name of file containing properties for blade 3 (quoted string) [unused for 2 blades] ----------------------- ROTOR-TEETER -------------------------------------------- - 0 TeetMod - Rotor-teeter spring/damper model {0: none, 1: standard, 2: user-defined from routine UserTeet} (switch) [unused for 3 blades] - 0 TeetDmpP - Rotor-teeter damper position (degrees) [used only for 2 blades and when TeetMod=1] - 0 TeetDmp - Rotor-teeter damping constant (N-m/(rad/s)) [used only for 2 blades and when TeetMod=1] - 0 TeetCDmp - Rotor-teeter rate-independent Coulomb-damping moment (N-m) [used only for 2 blades and when TeetMod=1] - 0 TeetSStP - Rotor-teeter soft-stop position (degrees) [used only for 2 blades and when TeetMod=1] - 0 TeetHStP - Rotor-teeter hard-stop position (degrees) [used only for 2 blades and when TeetMod=1] - 0 TeetSSSp - Rotor-teeter soft-stop linear-spring constant (N-m/rad) [used only for 2 blades and when TeetMod=1] - 0 TeetHSSp - Rotor-teeter hard-stop linear-spring constant (N-m/rad) [used only for 2 blades and when TeetMod=1] ----------------------- DRIVETRAIN ---------------------------------------------- - 100 GBoxEff - Gearbox efficiency (%) - 97 GBRatio - Gearbox ratio (-) -8.67637E+08 DTTorSpr - Drivetrain torsional spring (N-m/rad) - 6.215E+06 DTTorDmp - Drivetrain torsional damper (N-m/(rad/s)) ----------------------- FURLING ------------------------------------------------- -False Furling - Read in additional model properties for furling turbine (flag) [must currently be FALSE) -"unused" FurlFile - Name of file containing furling properties (quoted string) [unused when Furling=False] ----------------------- TOWER --------------------------------------------------- - 20 TwrNodes - Number of tower nodes used for analysis (-) -"NRELOffshrBsline5MW_Onshore_ElastoDyn_Tower.dat" TwrFile - Name of file containing tower properties (quoted string) ----------------------- OUTPUT -------------------------------------------------- -True SumPrint - Print summary data to ".sum" (flag) - 1 OutFile - Switch to determine where output will be placed: {1: in module output file only; 2: in glue code output file only; 3: both} (currently unused) -True TabDelim - Use tab delimiters in text tabular output file? (flag) (currently unused) -"ES10.3E2" OutFmt - Format used for text tabular output (except time). Resulting field should be 10 characters. (quoted string) (currently unused) - 0 TStart - Time to begin tabular output (s) (currently unused) - 1 DecFact - Decimation factor for tabular output {1: output every time step} (-) (currently unused) - 0 NTwGages - Number of tower nodes that have strain gages for output [0 to 9] (-) - 10, 19, 28 TwrGagNd - List of tower nodes that have strain gages [1 to TwrNodes] (-) [unused if NTwGages=0] - 3 NBlGages - Number of blade nodes that have strain gages for output [0 to 9] (-) - 5, 9, 13 BldGagNd - List of blade nodes that have strain gages [1 to BldNodes] (-) [unused if NBlGages=0] - OutList - The next line(s) contains a list of output parameters. See OutListParameters.xlsx for a listing of available output channels, (-) -"OoPDefl1" - Blade 1 out-of-plane and in-plane deflections and tip twist -"IPDefl1" - Blade 1 out-of-plane and in-plane deflections and tip twist -"TwstDefl1" - Blade 1 out-of-plane and in-plane deflections and tip twist -"BldPitch1" - Blade 1 pitch angle -"Azimuth" - Blade 1 azimuth angle -"RotSpeed" - Low-speed shaft and high-speed shaft speeds -"GenSpeed" - Low-speed shaft and high-speed shaft speeds -"TTDspFA" - Tower fore-aft and side-to-side displacements and top twist -"TTDspSS" - Tower fore-aft and side-to-side displacements and top twist -"TTDspTwst" - Tower fore-aft and side-to-side displacements and top twist -"Spn2MLxb1" - Blade 1 local edgewise and flapwise bending moments at span station 2 (approx. 50% span) -"Spn2MLyb1" - Blade 1 local edgewise and flapwise bending moments at span station 2 (approx. 50% span) -"RootFxb1" - Out-of-plane shear, in-plane shear, and axial forces at the root of blade 1 -"RootFyb1" - Out-of-plane shear, in-plane shear, and axial forces at the root of blade 1 -"RootFzb1" - Out-of-plane shear, in-plane shear, and axial forces at the root of blade 1 -"RootMxb1" - In-plane bending, out-of-plane bending, and pitching moments at the root of blade 1 -"RootMyb1" - In-plane bending, out-of-plane bending, and pitching moments at the root of blade 1 -"RootMzb1" - In-plane bending, out-of-plane bending, and pitching moments at the root of blade 1 -"RotTorq" - Rotor torque and low-speed shaft 0- and 90-bending moments at the main bearing -"LSSGagMya" - Rotor torque and low-speed shaft 0- and 90-bending moments at the main bearing -"LSSGagMza" - Rotor torque and low-speed shaft 0- and 90-bending moments at the main bearing -"YawBrFxp" - Fore-aft shear, side-to-side shear, and vertical forces at the top of the tower (not rotating with nacelle yaw) -"YawBrFyp" - Fore-aft shear, side-to-side shear, and vertical forces at the top of the tower (not rotating with nacelle yaw) -"YawBrFzp" - Fore-aft shear, side-to-side shear, and vertical forces at the top of the tower (not rotating with nacelle yaw) -"YawBrMxp" - Side-to-side bending, fore-aft bending, and yaw moments at the top of the tower (not rotating with nacelle yaw) -"YawBrMyp" - Side-to-side bending, fore-aft bending, and yaw moments at the top of the tower (not rotating with nacelle yaw) -"YawBrMzp" - Side-to-side bending, fore-aft bending, and yaw moments at the top of the tower (not rotating with nacelle yaw) -"TwrBsFxt" - Fore-aft shear, side-to-side shear, and vertical forces at the base of the tower (mudline) -"TwrBsFyt" - Fore-aft shear, side-to-side shear, and vertical forces at the base of the tower (mudline) -"TwrBsFzt" - Fore-aft shear, side-to-side shear, and vertical forces at the base of the tower (mudline) -"TwrBsMxt" - Side-to-side bending, fore-aft bending, and yaw moments at the base of the tower (mudline) -"TwrBsMyt" - Side-to-side bending, fore-aft bending, and yaw moments at the base of the tower (mudline) -"TwrBsMzt" - Side-to-side bending, fore-aft bending, and yaw moments at the base of the tower (mudline) -"NcIMURAys" - Nacell IMU Measurement of angular acceleration about the y-axis (Fore-aft) -"NcIMUTAys" -END of input file (the word "END" must appear in the first 3 columns of this last OutList line) ---------------------------------------------------------------------------------------- diff --git a/Test_Cases/5MW_Land_Simulink/NRELOffshrBsline5MW_Onshore_ElastoDyn_Tower.dat b/Test_Cases/5MW_Land_Simulink/NRELOffshrBsline5MW_Onshore_ElastoDyn_Tower.dat deleted file mode 100644 index cbb726978..000000000 --- a/Test_Cases/5MW_Land_Simulink/NRELOffshrBsline5MW_Onshore_ElastoDyn_Tower.dat +++ /dev/null @@ -1,54 +0,0 @@ -------- ELASTODYN V1.00.* TOWER INPUT FILE ------------------------------------- -NREL 5.0 MW offshore baseline tower input properties. ----------------------- TOWER PARAMETERS ---------------------------------------- - 11 NTwInpSt - Number of input stations to specify tower geometry - 1 TwrFADmp(1) - Tower 1st fore-aft mode structural damping ratio (%) - 1 TwrFADmp(2) - Tower 2nd fore-aft mode structural damping ratio (%) - 1 TwrSSDmp(1) - Tower 1st side-to-side mode structural damping ratio (%) - 1 TwrSSDmp(2) - Tower 2nd side-to-side mode structural damping ratio (%) ----------------------- TOWER ADJUSTMUNT FACTORS -------------------------------- - 1 FAStTunr(1) - Tower fore-aft modal stiffness tuner, 1st mode (-) - 1 FAStTunr(2) - Tower fore-aft modal stiffness tuner, 2nd mode (-) - 1 SSStTunr(1) - Tower side-to-side stiffness tuner, 1st mode (-) - 1 SSStTunr(2) - Tower side-to-side stiffness tuner, 2nd mode (-) - 1 AdjTwMa - Factor to adjust tower mass density (-) - 1 AdjFASt - Factor to adjust tower fore-aft stiffness (-) - 1 AdjSSSt - Factor to adjust tower side-to-side stiffness (-) ----------------------- DISTRIBUTED TOWER PROPERTIES ---------------------------- - HtFract TMassDen TwFAStif TwSSStif - (-) (kg/m) (Nm^2) (Nm^2) -0.0000000E+00 5.5908700E+03 6.1434300E+11 6.1434300E+11 -1.0000000E-01 5.2324300E+03 5.3482100E+11 5.3482100E+11 -2.0000000E-01 4.8857600E+03 4.6326700E+11 4.6326700E+11 -3.0000000E-01 4.5508700E+03 3.9913100E+11 3.9913100E+11 -4.0000000E-01 4.2277500E+03 3.4188300E+11 3.4188300E+11 -5.0000000E-01 3.9164100E+03 2.9101100E+11 2.9101100E+11 -6.0000000E-01 3.6168300E+03 2.4602700E+11 2.4602700E+11 -7.0000000E-01 3.3290300E+03 2.0645700E+11 2.0645700E+11 -8.0000000E-01 3.0530100E+03 1.7185100E+11 1.7185100E+11 -9.0000000E-01 2.7887500E+03 1.4177600E+11 1.4177600E+11 -1.0000000E+00 2.5362700E+03 1.1582000E+11 1.1582000E+11 ----------------------- TOWER FORE-AFT MODE SHAPES ------------------------------ - 0.7004 TwFAM1Sh(2) - Mode 1, coefficient of x^2 term - 2.1963 TwFAM1Sh(3) - , coefficient of x^3 term - -5.6202 TwFAM1Sh(4) - , coefficient of x^4 term - 6.2275 TwFAM1Sh(5) - , coefficient of x^5 term - -2.504 TwFAM1Sh(6) - , coefficient of x^6 term - -70.5319 TwFAM2Sh(2) - Mode 2, coefficient of x^2 term - -63.7623 TwFAM2Sh(3) - , coefficient of x^3 term - 289.737 TwFAM2Sh(4) - , coefficient of x^4 term - -176.513 TwFAM2Sh(5) - , coefficient of x^5 term - 22.0706 TwFAM2Sh(6) - , coefficient of x^6 term ----------------------- TOWER SIDE-TO-SIDE MODE SHAPES -------------------------- - 1.385 TwSSM1Sh(2) - Mode 1, coefficient of x^2 term - -1.7684 TwSSM1Sh(3) - , coefficient of x^3 term - 3.0871 TwSSM1Sh(4) - , coefficient of x^4 term - -2.2395 TwSSM1Sh(5) - , coefficient of x^5 term - 0.5357 TwSSM1Sh(6) - , coefficient of x^6 term - -121.21 TwSSM2Sh(2) - Mode 2, coefficient of x^2 term - 184.415 TwSSM2Sh(3) - , coefficient of x^3 term - -224.904 TwSSM2Sh(4) - , coefficient of x^4 term - 298.536 TwSSM2Sh(5) - , coefficient of x^5 term - -135.838 TwSSM2Sh(6) - , coefficient of x^6 term - - diff --git a/Test_Cases/BAR_10/BAR_10_InflowFile.dat b/Test_Cases/BAR_10/BAR_10_InflowFile.dat index c13500516..3cd7c48f4 100644 --- a/Test_Cases/BAR_10/BAR_10_InflowFile.dat +++ b/Test_Cases/BAR_10/BAR_10_InflowFile.dat @@ -2,7 +2,7 @@ Generated with AeroElasticSE FAST driver --------------------------------------------------------------------------------------------------------------- False Echo - Echo input data to .ech (flag) -3 WindType - switch for wind file type (1=steady; 2=uniform; 3=binary TurbSim FF; 4=binary Bladed-style FF; 5=HAWC format; 6=User defined) +1 WindType - switch for wind file type (1=steady; 2=uniform; 3=binary TurbSim FF; 4=binary Bladed-style FF; 5=HAWC format; 6=User defined) 0.0 PropagationDir - Direction of wind propagation (meteoroligical rotation from aligned with X (positive rotates towards -Y) -- degrees) 0 VFlowAng - Upflow angle (degrees) (not used for native Bladed format WindType=7) 1 NWindVel - Number of points to output the wind velocity (0 to 9) @@ -11,16 +11,16 @@ False Echo - Echo input data to .ech (flag) 90.0 WindVziList - List of coordinates in the inertial Z direction (m) ================== Parameters for Steady Wind Conditions [used only for WindType = 1] ========================= 10.0 HWindSpeed - Horizontal windspeed (m/s) -140.0 RefHtT1 - Reference height for horizontal wind speed (m) -0.2 PLexp - Power law exponent (-) +140.0 RefHt - Reference height for horizontal wind speed (m) +0.12 PLexp - Power law exponent (-) ================== Parameters for Uniform wind file [used only for WindType = 2] ============================ -"/Users/pbortolo/work/2_openfast/BAR/OpenFAST_Models/BAR_00/Wind/140m_12mps.bts" FilenameT2 - Filename of time series data for uniform wind field. (-) -140.0 RefHtT2 - Reference height for horizontal wind speed (m) +"Wind/NoShr_9-14_Inc1_50s.wnd" Filename_Uni - Filename of time series data for uniform wind field. (-) +140.0 RefHt_Uni - Reference height for horizontal wind speed (m) 125.88 RefLength - Reference length for linear horizontal and vertical sheer (-) ================== Parameters for Binary TurbSim Full-Field files [used only for WindType = 3] ============== -"/Users/nabbas/Documents/WindEnergyToolbox/WindFiles/TurbWind/140m/140m_12mps.bts" FilenameT3 - Name of the Full field wind file to use (.bts) +"Wind/145m_11mps_ClassA1ETM.bts" FileName_BTS - Name of the Full field wind file to use (.bts) ================== Parameters for Binary Bladed-style Full-Field files [used only for WindType = 4] ========= -"90m_12mps_twr" FilenameT4 - Rootname of the full-field wind file to use (.wnd, .sum) +"Wind/90m_12mps_twr" FilenameRoot - Rootname of the full-field wind file to use (.wnd, .sum) False TowerFile - Have tower file (.twr) (flag) ================== Parameters for HAWC-format binary files [Only used with WindType = 5] ===================== "/Users/pbortolo/work/2_openfast/BAR/OpenFAST_Models/BAR_00/basic_5u.bin" FileName_u - name of the file containing the u-component fluctuating wind (.bin) @@ -32,7 +32,7 @@ False TowerFile - Have tower file (.twr) (flag) 16.0 dx - distance (in meters) between points in the x direction (m) 3.0 dy - distance (in meters) between points in the y direction (m) 3.0 dz - distance (in meters) between points in the z direction (m) -140.0 RefHtT5 - reference height; the height (in meters) of the vertical center of the grid (m) +140.0 RefHt_Hawc - reference height; the height (in meters) of the vertical center of the grid (m) ------------- Scaling parameters for turbulence --------------------------------------------------------- 2 ScaleMethod - Turbulence scaling method [0 = none, 1 = direct scaling, 2 = calculate scaling factor based on a desired standard deviation] 1.0 SFx - Turbulence scaling factor for the x direction (-) [ScaleMethod=1] @@ -44,12 +44,12 @@ False TowerFile - Have tower file (.twr) (flag) ------------- Mean wind profile parameters (added to HAWC-format files) --------------------------------- 12.0 URef - Mean u-component wind speed at the reference height (m/s) 2 WindProfile - Wind profile type (0=constant;1=logarithmic,2=power law) -0.2 PLExp - Power law exponent (-) (used for PL wind profile type only) +0.2 PLExp_Hawc - Power law exponent (-) (used for PL wind profile type only) 0.03 Z0 - Surface roughness length (m) (used for LG wind profile type only) 0 XOffset - Initial offset in +x direction (shift of wind box) ====================== OUTPUT ================================================== False SumPrint - Print summary data to .IfW.sum (flag) OutList - The next line(s) contains a list of output parameters. See OutListParameters.xlsx for a listing of available output channels, (-) -"Wind1VelX" +Wind1VelX END of input file (the word "END" must appear in the first 3 columns of this last OutList line) --------------------------------------------------------------------------------------- diff --git a/Test_Cases/BAR_10/BAR_10_ServoDyn.dat b/Test_Cases/BAR_10/BAR_10_ServoDyn.dat index 7fdc11757..515796534 100644 --- a/Test_Cases/BAR_10/BAR_10_ServoDyn.dat +++ b/Test_Cases/BAR_10/BAR_10_ServoDyn.dat @@ -63,7 +63,7 @@ False CompNTMD - Compute nacelle tuned mass damper {true/fal False CompTTMD - Compute tower tuned mass damper {true/false} (flag) "b.dat" TTMDfile - Name of the file for tower tuned mass damper (quoted string) [unused when CompTTMD is false] ---------------------- BLADED INTERFACE ---------------------------------------- [used only with Bladed Interface] -"/Users/nabbas/Documents/WindEnergyToolbox/ROSCO/build/libdiscon.dylib" DLL_FileName - Name/location of the dynamic library {.dll [Windows] or .so [Linux]} in the Bladed-DLL format (-) [used only with Bladed Interface] +"../../ROSCO/build/libdiscon.dylib" DLL_FileName - Name/location of the dynamic library {.dll [Windows] or .so [Linux]} in the Bladed-DLL format (-) [used only with Bladed Interface] "BAR_10_DISCON.IN" DLL_InFile - Name of input file sent to the DLL (-) [used only with Bladed Interface] "DISCON" DLL_ProcName - Name of procedure in DLL to be called (-) [case sensitive; used only with DLL Interface] "default" DLL_DT - Communication interval for dynamic library (s) (or "default") [used only with Bladed Interface] diff --git a/Test_Cases/IEA-15-240-RWT-UMaineSemi/IEA-15-240-RWT-UMaineSemi_MoorDyn.dat b/Test_Cases/IEA-15-240-RWT-UMaineSemi/IEA-15-240-RWT-UMaineSemi_MoorDyn.dat index 18ca40f1a..9032a2d8f 100644 --- a/Test_Cases/IEA-15-240-RWT-UMaineSemi/IEA-15-240-RWT-UMaineSemi_MoorDyn.dat +++ b/Test_Cases/IEA-15-240-RWT-UMaineSemi/IEA-15-240-RWT-UMaineSemi_MoorDyn.dat @@ -18,11 +18,11 @@ Node Type X Y Z M V FX FY FZ CdA CA 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 -(-) (-) (m) (-) (-) (-) (-) -1 main 850.00 50 2 1 - -2 main 850.00 50 4 3 - -3 main 850.00 50 6 5 - +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 ---------------------- SOLVER OPTIONS --------------------------------------- 0.001 dtM - time step to use in mooring integration (s) 3.0e6 kbot - bottom stiffness (Pa/m) diff --git a/Test_Cases/IEA-15-240-RWT-UMaineSemi/IEA-15-240-RWT-UMaineSemi_ServoDyn.dat b/Test_Cases/IEA-15-240-RWT-UMaineSemi/IEA-15-240-RWT-UMaineSemi_ServoDyn.dat index 8985e90a7..92c9b2fed 100644 --- a/Test_Cases/IEA-15-240-RWT-UMaineSemi/IEA-15-240-RWT-UMaineSemi_ServoDyn.dat +++ b/Test_Cases/IEA-15-240-RWT-UMaineSemi/IEA-15-240-RWT-UMaineSemi_ServoDyn.dat @@ -63,7 +63,7 @@ False CompNTMD - Compute nacelle tuned mass damper {true/fal False CompTTMD - Compute tower tuned mass damper {true/false} (flag) "unused" TTMDfile - Name of the file for tower tuned mass damper (quoted string) [unused when CompTTMD is false] ---------------------- BLADED INTERFACE ---------------------------------------- [used only with Bladed Interface] -"../../ROSCO/libdiscon.dylib" DLL_FileName - Name/location of the dynamic library {.dll [Windows] or .so [Linux]} in the Bladed-DLL format (-) [used only with Bladed Interface] +"../../ROSCO/build/libdiscon.dylib" DLL_FileName - Name/location of the dynamic library {.dll [Windows] or .so [Linux]} in the Bladed-DLL format (-) [used only with Bladed Interface] "ServoData/DISCON-UMaineSemi.IN" DLL_InFile - Name of input file sent to the DLL (-) [used only with Bladed Interface] "DISCON" DLL_ProcName - Name of procedure in DLL to be called (-) [case sensitive; used only with DLL Interface] "default" DLL_DT - Communication interval for dynamic library (s) (or "default") [used only with Bladed Interface] diff --git a/Test_Cases/IEA-15-240-RWT-UMaineSemi/IEA-15-240-RWT_AeroDyn15.dat b/Test_Cases/IEA-15-240-RWT-UMaineSemi/IEA-15-240-RWT_AeroDyn15.dat index 215aa9586..182bc8353 100644 --- a/Test_Cases/IEA-15-240-RWT-UMaineSemi/IEA-15-240-RWT_AeroDyn15.dat +++ b/Test_Cases/IEA-15-240-RWT-UMaineSemi/IEA-15-240-RWT_AeroDyn15.dat @@ -3,15 +3,15 @@ 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 AFAeroMod - Type of blade airfoil aerodynamics model (switch) {1=steady model, 2=Beddoes-Leishman unsteady model} [must be 1 when linearizing] +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} -False TwrShadow - Calculate tower influence on wind based on downstream tower shadow? (flag) +False 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) TRUE will turn off unsteady aerodynamics -False CompAA - Flag to compute AeroAcoustics calculation [only used when WakeMod=1 or 2] -"AeroAcousticsInput.dat" AA_InputFile - Aeroacoustics input file +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] +"AeroAcousticsInput.dat" AA_InputFile - AeroAcoustics input file [used only when CompAA=true] ====== Environmental Conditions =================================================================== 1.225000000000000e+00 AirDens - Air density (kg/m^3) 1.479232653061225e-05 KinVisc - Kinematic air viscosity (m^2/s) @@ -20,23 +20,23 @@ False CompAA - Flag to compute AeroAcoustics calculation [ 1.700000000000000e+03 Pvap - Vapour pressure of fluid (Pa) [used only when CavitCheck=True] 5.000000000000000e-01 FluidDepth - Water depth above mid-hub height (m) [used only when CavitCheck=True] ====== Blade-Element/Momentum Theory Options ====================================================== [used only when WakeMod=1] -2 SkewMod - Type of skewed-wake correction model (switch) {1=uncoupled, 2=Pitt/Peters, 3=coupled} [used only when WakeMod=1] -"default" SkewModFactor - Constant used in Pitt/Peters skewed wake model {or "default" is 15/32*pi} (-) [used only when SkewMod=2; unused when WakeMod=0] -True TipLoss - Use the Prandtl tip-loss model? (flag) [used only when WakeMod=1] -True HubLoss - Use the Prandtl hub-loss model? (flag) [used only when WakeMod=1] -True TanInd - Include tangential induction in BEMT calculations? (flag) [used only when WakeMod=1] -True AIDrag - Include the drag term in the axial-induction calculation? (flag) [used only when WakeMod=1] -True TIDrag - Include the drag term in the tangential-induction calculation? (flag) [used only when WakeMod=1 and TanInd=TRUE] -"Default" IndToler - Convergence tolerance for BEMT nonlinear solve residual equation {or "default"} (-) [used only when WakeMod=1] -500 MaxIter - Maximum number of iteration steps (-) [used only when WakeMod=1] +2 SkewMod - Type of skewed-wake correction model (switch) {1=uncoupled, 2=Pitt/Peters, 3=coupled} [unused when WakeMod=0 or 3] +"default" 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] +True TipLoss - Use the Prandtl tip-loss model? (flag) [unused when WakeMod=0 or 3] +True HubLoss - Use the Prandtl hub-loss model? (flag) [unused when WakeMod=0 or 3] +True TanInd - Include tangential induction in BEMT calculations? (flag) [unused when WakeMod=0 or 3] +True AIDrag - Include the drag term in the axial-induction calculation? (flag) [unused when WakeMod=0 or 3] +True TIDrag - Include the drag term in the tangential-induction calculation? (flag) [unused when WakeMod=0,3 or TanInd=FALSE] +"Default" IndToler - Convergence tolerance for BEMT nonlinear solve residual equation {or "default"} (-) [unused when WakeMod=0 or 3] +500 MaxIter - Maximum number of iteration steps (-) [unused when WakeMod=0] ====== Dynamic Blade-Element/Momentum Theory Options ====================================================== [used only when WakeMod=1] 2 DBEMT_Mod - Type of dynamic BEMT (DBEMT) model {1=constant tau1, 2=time-dependent tau1} (-) [used only when WakeMod=2] 2 tau1_const - Time constant for DBEMT (s) [used only when WakeMod=2 and DBEMT_Mod=1] ====== 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] +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 (-) @@ -130,6 +130,9 @@ True SumPrint - Generate a summary file listing input optio "RtAeroMzh" "RtVAvgxh" "RtAeroCp" +"RtAeroCt" +"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/Test_Cases/IEA-15-240-RWT-UMaineSemi/IEA-15-240-RWT_InflowFile.dat b/Test_Cases/IEA-15-240-RWT-UMaineSemi/IEA-15-240-RWT_InflowFile.dat index 312f8e833..f7e3ccc8d 100644 --- a/Test_Cases/IEA-15-240-RWT-UMaineSemi/IEA-15-240-RWT_InflowFile.dat +++ b/Test_Cases/IEA-15-240-RWT-UMaineSemi/IEA-15-240-RWT_InflowFile.dat @@ -2,7 +2,7 @@ IEA 15 MW Offshore Reference Turbine --------------------------------------------------------------------------------------------------------------- False Echo - Echo input data to .ech (flag) -1 WindType - switch for wind file type (1=steady; 2=uniform; 3=binary TurbSim FF; 4=binary Bladed-style FF; 5=HAWC format; 6=User defined) +1 WindType - switch for wind file type (1=steady; 2=uniform; 3=binary TurbSim FF; 4=binary Bladed-style FF; 5=HAWC format; 6=User defined; 7=native Bladed FF) 0.0 PropagationDir - Direction of wind propagation (meteoroligical rotation from aligned with X (positive rotates towards -Y) -- degrees) 0 VFlowAng - Upflow angle (degrees) (not used for native Bladed format WindType=7) 1 NWindVel - Number of points to output the wind velocity (0 to 9) @@ -14,11 +14,11 @@ False Echo - Echo input data to .ech (flag) 150.0 RefHt - Reference height for horizontal wind speed (m) 0.12 PLexp - Power law exponent (-) ================== Parameters for Uniform wind file [used only for WindType = 2] ============================ -"Wind/NoShr_9-14_Inc1_50s.wnd" Filename - Filename of time series data for uniform wind field. (-) -150.0 RefHt - Reference height for horizontal wind speed (m) +"Wind/NoShr_9-14_Inc1_50s.wnd" Filename_Uni - Filename of time series data for uniform wind field. (-) +150.0 RefHt_Uni - Reference height for horizontal wind speed (m) 125.88 RefLength - Reference length for linear horizontal and vertical sheer (-) ================== Parameters for Binary TurbSim Full-Field files [used only for WindType = 3] ============== -"Wind/145m_11mps_ClassA1ETM.bts" Filename - Name of the Full field wind file to use (.bts) +"Wind/145m_11mps_ClassA1ETM.bts" FileName_BTS - Name of the Full field wind file to use (.bts) ================== Parameters for Binary Bladed-style Full-Field files [used only for WindType = 4] ========= "Wind/90m_12mps_twr" FilenameRoot - Rootname of the full-field wind file to use (.wnd, .sum) False TowerFile - Have tower file (.twr) (flag) @@ -32,7 +32,7 @@ False TowerFile - Have tower file (.twr) (flag) 16.0 dx - distance (in meters) between points in the x direction (m) 3.0 dy - distance (in meters) between points in the y direction (m) 3.0 dz - distance (in meters) between points in the z direction (m) -150.0 RefHt - reference height; the height (in meters) of the vertical center of the grid (m) +150.0 RefHt_Hawc - reference height; the height (in meters) of the vertical center of the grid (m) ------------- Scaling parameters for turbulence --------------------------------------------------------- 2 ScaleMethod - Turbulence scaling method [0 = none, 1 = direct scaling, 2 = calculate scaling factor based on a desired standard deviation] 1.0 SFx - Turbulence scaling factor for the x direction (-) [ScaleMethod=1] @@ -44,7 +44,7 @@ False TowerFile - Have tower file (.twr) (flag) ------------- Mean wind profile parameters (added to HAWC-format files) --------------------------------- 12.0 URef - Mean u-component wind speed at the reference height (m/s) 2 WindProfile - Wind profile type (0=constant;1=logarithmic,2=power law) -0.2 PLExp - Power law exponent (-) (used for PL wind profile type only) +0.2 PLExp_Hawc - Power law exponent (-) (used for PL wind profile type only) 0.03 Z0 - Surface roughness length (m) (used for LG wind profile type only) 0 XOffset - Initial offset in +x direction (shift of wind box) ====================== OUTPUT ================================================== diff --git a/Test_Cases/IEA-15-240-RWT-UMaineSemi/ServoData/DISCON-UMaineSemi.IN b/Test_Cases/IEA-15-240-RWT-UMaineSemi/ServoData/DISCON-UMaineSemi.IN index 8868e397b..0307be805 100644 --- a/Test_Cases/IEA-15-240-RWT-UMaineSemi/ServoData/DISCON-UMaineSemi.IN +++ b/Test_Cases/IEA-15-240-RWT-UMaineSemi/ServoData/DISCON-UMaineSemi.IN @@ -78,9 +78,9 @@ 1.225 ! WE_RhoAir - Air density, [kg m^-3] "Cp_Ct_Cq.IEA15MW.txt" ! PerfFileName - File containing rotor performance tables (Cp,Ct,Cq) 104 72 ! 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.09 11.59 12.09 12.59 13.09 13.59 14.09 14.59 15.09 15.59 16.09 16.59 17.09 17.59 18.09 18.59 19.09 19.59 20.09 20.59 21.09 21.59 22.09 22.59 23.09 23.59 24.09 24.59 ! WE_FOPoles_v - Wind speeds corresponding to first-order system poles [m/s] --0.02366483 -0.02760896 -0.03155310 -0.03549724 -0.03944138 -0.04338551 -0.04732965 -0.05127379 -0.05521793 -0.05916206 -0.06310620 -0.06705034 -0.07099448 -0.07493861 -0.07888275 -0.08282689 -0.05297576 -0.05605471 -0.06299641 -0.07197232 -0.08228907 -0.09357435 -0.10567394 -0.11844707 -0.13176547 -0.14562128 -0.16003276 -0.17507351 -0.19032493 -0.20602365 -0.22255106 -0.23876816 -0.25602518 -0.27307271 -0.29115170 -0.30880313 -0.32785309 -0.34593703 -0.36525166 -0.38468218 -0.40394579 -0.42458588 -0.44445660 -0.46456892 ! WE_FOPoles - First order system poles +60 ! WE_FOPoles_N - Number of first-order system poles used in EKF +3.00 3.27 3.53 3.80 4.07 4.33 4.60 4.87 5.14 5.40 5.67 5.94 6.20 6.47 6.74 7.00 7.27 7.54 7.80 8.07 8.34 8.60 8.87 9.14 9.41 9.67 9.94 10.21 10.47 10.74 10.74 11.23 11.72 12.22 12.71 13.20 13.69 14.18 14.67 15.17 15.66 16.15 16.64 17.13 17.62 18.12 18.61 19.10 19.59 20.08 20.57 21.07 21.56 22.05 22.54 23.03 23.52 24.02 24.51 25.00 ! WE_FOPoles_v - Wind speeds corresponding to first-order system poles [m/s] +-0.02366483 -0.02577018 -0.02787553 -0.02998089 -0.03208624 -0.03419159 -0.03629695 -0.03840230 -0.04050765 -0.04261301 -0.04471836 -0.04682371 -0.04892907 -0.05103442 -0.05313977 -0.05524513 -0.05735048 -0.05945583 -0.06156119 -0.06366654 -0.06577189 -0.06787725 -0.06998260 -0.07208795 -0.07419331 -0.07629866 -0.07840401 -0.08050937 -0.08261472 -0.08472008 -0.07921295 -0.05358619 -0.05636426 -0.06307564 -0.07173987 -0.08172495 -0.09271927 -0.10454428 -0.11705643 -0.13017613 -0.14379976 -0.15793978 -0.17258746 -0.18766434 -0.20315149 -0.21909644 -0.23538854 -0.25208919 -0.26915631 -0.28659300 -0.30437969 -0.32249538 -0.34096095 -0.35974552 -0.37881117 -0.39822177 -0.41789494 -0.43785131 -0.45808118 -0.47857910 ! WE_FOPoles - First order system poles [1/s] !------- YAW CONTROL ------------------------------------------------------ 0.0 ! Y_ErrThresh - Yaw error threshold. Turbine begins to yaw when it passes this. [rad^2 s] diff --git a/Test_Cases/NREL-5MW/DISCON.IN b/Test_Cases/NREL-5MW/DISCON.IN index 8cb34c903..92eb15fa3 100644 --- a/Test_Cases/NREL-5MW/DISCON.IN +++ b/Test_Cases/NREL-5MW/DISCON.IN @@ -80,7 +80,7 @@ 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.00 11.90 12.40 12.90 13.40 13.90 14.40 14.90 15.40 15.90 16.40 16.90 17.40 17.90 18.40 18.90 19.40 19.90 20.40 20.90 21.40 21.90 22.40 22.90 23.40 23.90 24.40 24.90 ! WE_FOPoles_v - Wind speeds corresponding to first-order system poles [m/s] --0.01651600 -0.01926866 -0.02202133 -0.02477399 -0.02752666 -0.03027933 -0.03303199 -0.03578466 -0.03853732 -0.04128999 -0.04404266 -0.04679532 -0.04954799 -0.05230065 -0.05505332 -0.05780599 -0.06055865 -0.05136706 -0.06083297 -0.07318141 -0.08698814 -0.10174996 -0.11701540 -0.13277020 -0.14916461 -0.16625567 -0.18314382 -0.20108255 -0.21861726 -0.23708646 -0.25523482 -0.27455940 -0.29291942 -0.31337978 -0.33196662 -0.35213321 -0.37322194 -0.39245925 -0.41381198 -0.43612755 -0.45572506 -0.47749086 -0.50133095 -0.53269989 ! WE_FOPoles - First order system poles +-0.01651600 -0.01926866 -0.02202133 -0.02477399 -0.02752666 -0.03027933 -0.03303199 -0.03578466 -0.03853732 -0.04128999 -0.04404266 -0.04679532 -0.04954799 -0.05230065 -0.05505332 -0.05780599 -0.06055865 -0.05136706 -0.06083297 -0.07318141 -0.08698814 -0.10174996 -0.11701540 -0.13277020 -0.14916461 -0.16625567 -0.18314382 -0.20108255 -0.21861726 -0.23708646 -0.25523482 -0.27455940 -0.29291942 -0.31337978 -0.33196662 -0.35213321 -0.37322194 -0.39245925 -0.41381198 -0.43612755 -0.45572506 -0.47749086 -0.50133095 -0.53269989 ! WE_FOPoles - First order system poles [1/s] !------- YAW CONTROL ------------------------------------------------------ 0.0 ! Y_ErrThresh - Yaw error threshold. Turbine begins to yaw when it passes this. [rad^2 s] diff --git a/Test_Cases/NREL-5MW/NRELOffshrBsline5MW_InflowWind.dat b/Test_Cases/NREL-5MW/NRELOffshrBsline5MW_InflowWind.dat index 916c6b29e..3fd8bc13f 100644 --- a/Test_Cases/NREL-5MW/NRELOffshrBsline5MW_InflowWind.dat +++ b/Test_Cases/NREL-5MW/NRELOffshrBsline5MW_InflowWind.dat @@ -4,7 +4,7 @@ Steady 8 m/s winds with no shear for FAST CertTests #20 and #25 False Echo - Echo input data to .ech (flag) 1 WindType - switch for wind file type (1=steady; 2=uniform; 3=binary TurbSim FF; 4=binary Bladed-style FF; 5=HAWC format; 6=User defined) 0 PropagationDir - Direction of wind propagation (meteoroligical rotation from aligned with X (positive rotates towards -Y) -- degrees) -0 VFlowAng - Upflow angle (degrees) (not used for native Bladed format WindType=7) + 0 VFlowAng - Upflow angle (degrees) (not used for native Bladed format WindType=7) 1 NWindVel - Number of points to output the wind velocity (0 to 9) 0 WindVxiList - List of coordinates in the inertial X direction (m) 0 WindVyiList - List of coordinates in the inertial Y direction (m) @@ -14,14 +14,14 @@ False Echo - Echo input data to .ech (flag) 90 RefHt - Reference height for horizontal wind speed (m) 0 PLexp - Power law exponent (-) ================== Parameters for Uniform wind file [used only for WindType = 2] ============================ -"unused" Filename - Filename of time series data for uniform wind field. (-) - 90 RefHt - Reference height for horizontal wind speed (m) +"unused" Filename_Uni - Filename of time series data for uniform wind field. (-) + 90 RefHt_Uni - Reference height for horizontal wind speed (m) 125.88 RefLength - Reference length for linear horizontal and vertical sheer (-) ================== Parameters for Binary TurbSim Full-Field files [used only for WindType = 3] ============== -"unused" Filename - Name of the Full field wind file to use (.bts) -================== Parameters for Binary Bladed-style Full-Field files [used only for WindType = 4] ========= -"unused" FilenameRoot - Rootname of the full-field wind file to use (.wnd, .sum) -False TowerFile - Have tower file (.twr) (flag) +"Wind/90m_12mps_twr.bts" FileName_BTS - Name of the Full field wind file to use (.bts) +================== Parameters for Binary Bladed-style Full-Field files [used only for WindType = 4 or WindType = 7] ========= +"unused" FileNameRoot - WindType=4: Rootname of the full-field wind file to use (.wnd, .sum); WindType=7: name of the intermediate file with wind scaling values +False TowerFile - Have tower file (.twr) (flag) ignored when WindType = 7 ================== Parameters for HAWC-format binary files [Only used with WindType = 5] ===================== "unused" FileName_u - name of the file containing the u-component fluctuating wind (.bin) "unused" FileName_v - name of the file containing the v-component fluctuating wind (.bin) @@ -32,7 +32,7 @@ False TowerFile - Have tower file (.twr) (flag) 16 dx - distance (in meters) between points in the x direction (m) 3 dy - distance (in meters) between points in the y direction (m) 3 dz - distance (in meters) between points in the z direction (m) - 90 RefHt - reference height; the height (in meters) of the vertical center of the grid (m) + 90 RefHt_Hawc - reference height; the height (in meters) of the vertical center of the grid (m) ------------- Scaling parameters for turbulence --------------------------------------------------------- 1 ScaleMethod - Turbulence scaling method [0 = none, 1 = direct scaling, 2 = calculate scaling factor based on a desired standard deviation] 1 SFx - Turbulence scaling factor for the x direction (-) [ScaleMethod=1] @@ -44,9 +44,9 @@ False TowerFile - Have tower file (.twr) (flag) ------------- Mean wind profile parameters (added to HAWC-format files) --------------------------------- 5 URef - Mean u-component wind speed at the reference height (m/s) 2 WindProfile - Wind profile type (0=constant;1=logarithmic,2=power law) - 0 PLExp - Power law exponent (-) (used for PL wind profile type only) + 0.2 PLExp_Hawc - Power law exponent (-) (used for PL wind profile type only) 0.03 Z0 - Surface roughness length (m) (used for LG wind profile type only) -0 XOffset - Initial offset in +x direction (shift of wind box) + 0 XOffset - Initial offset in +x direction (shift of wind box) ====================== OUTPUT ================================================== False SumPrint - Print summary data to .IfW.sum (flag) OutList - The next line(s) contains a list of output parameters. See OutListParameters.xlsx for a listing of available output channels, (-) diff --git a/Test_Cases/NREL-5MW/NRELOffshrBsline5MW_Onshore_ElastoDyn.dat b/Test_Cases/NREL-5MW/NRELOffshrBsline5MW_Onshore_ElastoDyn.dat index c9d2ff626..46c89f7d6 100644 --- a/Test_Cases/NREL-5MW/NRELOffshrBsline5MW_Onshore_ElastoDyn.dat +++ b/Test_Cases/NREL-5MW/NRELOffshrBsline5MW_Onshore_ElastoDyn.dat @@ -153,5 +153,7 @@ True TabDelim - Use tab delimiters in text tabular output file? (fla "TwrBsMxt" - Side-to-side bending, fore-aft bending, and yaw moments at the base of the tower (mudline) "TwrBsMyt" - Side-to-side bending, fore-aft bending, and yaw moments at the base of the tower (mudline) "TwrBsMzt" - Side-to-side bending, fore-aft bending, and yaw moments at the base of the tower (mudline) +"NcIMURAys" - Nacelle IMU rotational acceleration in the nodding direction +"NcIMUTAxs" - Nacelle IMU rotational acceleration in the streamwise direction END of input file (the word "END" must appear in the first 3 columns of this last OutList line) --------------------------------------------------------------------------------------- diff --git a/Tune_Cases/BAR.yaml b/Tune_Cases/BAR.yaml index c93d0a737..ebaacad7e 100644 --- a/Tune_Cases/BAR.yaml +++ b/Tune_Cases/BAR.yaml @@ -4,7 +4,7 @@ # ------------------------------ OpenFAST PATH DEFINITIONS ------------------------------ path_params: FAST_InputFile: 'BAR_10.fst' # Name of *.fst file - FAST_directory: 'Test_Cases/BAR_10' # Main OpenFAST model directory, where the *.fst lives + FAST_directory: '../Test_Cases/BAR_10' # Main OpenFAST model directory, where the *.fst lives # Optional (but suggested...) rotor_performance_filename: 'BAR_10_Cp_Ct_Cq.txt' # Filename for rotor performance text file (if it has been generated by ccblade already) diff --git a/Tune_Cases/DISCON.IN b/Tune_Cases/DISCON.IN index 0f451665e..314ede814 100644 --- a/Tune_Cases/DISCON.IN +++ b/Tune_Cases/DISCON.IN @@ -76,11 +76,11 @@ 50.0 ! WE_GearboxRatio - Gearbox ratio [>=1], [-] 160099282.20800 ! 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.DTU10MW.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 -42 ! WE_FOPoles_N - Number of first-order system poles used in EKF -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.00 11.90 12.40 12.90 13.40 13.90 14.40 14.90 15.40 15.90 16.40 16.90 17.40 17.90 18.40 18.90 19.40 19.90 20.40 20.90 21.40 21.90 22.40 22.90 23.40 23.90 24.40 24.90 ! WE_FOPoles_v - Wind speeds corresponding to first-order system poles [m/s] --0.02224894 -0.02503005 -0.02781117 -0.03059229 -0.03337341 -0.03615452 -0.03893564 -0.04171676 -0.04449787 -0.04727899 -0.05006011 -0.05284123 -0.05562234 -0.05840346 -0.06118458 -0.04912872 -0.05580722 -0.06518784 -0.07596687 -0.08768719 -0.10016561 -0.11321246 -0.12662324 -0.14054702 -0.15510757 -0.16979856 -0.18479723 -0.20065913 -0.21593099 -0.23258348 -0.24824509 -0.26557984 -0.28161699 -0.29910951 -0.31620223 -0.33341968 -0.35239722 -0.36909876 -0.38718142 -0.40701429 -0.42400719 -0.44234888 ! WE_FOPoles - First order system poles +"Cp_Ct_Cq.IEA15MW.txt" ! PerfFileName - File containing rotor performance tables (Cp,Ct,Cq) +104 72 ! PerfTableSize - Size of rotor performance tables, first number refers to number of blade pitch angles, second number referse to number of tip-speed ratios +60 ! WE_FOPoles_N - Number of first-order system poles used in EKF +3.00 3.27 3.53 3.80 4.07 4.33 4.60 4.87 5.14 5.40 5.67 5.94 6.20 6.47 6.74 7.00 7.27 7.54 7.80 8.07 8.34 8.60 8.87 9.14 9.41 9.67 9.94 10.21 10.47 10.74 10.74 11.23 11.72 12.22 12.71 13.20 13.69 14.18 14.67 15.17 15.66 16.15 16.64 17.13 17.62 18.12 18.61 19.10 19.59 20.08 20.57 21.07 21.56 22.05 22.54 23.03 23.52 24.02 24.51 25.00 ! WE_FOPoles_v - Wind speeds corresponding to first-order system poles [m/s] +-0.02366483 -0.02577018 -0.02787553 -0.02998089 -0.03208624 -0.03419159 -0.03629695 -0.03840230 -0.04050765 -0.04261301 -0.04471836 -0.04682371 -0.04892907 -0.05103442 -0.05313977 -0.05524513 -0.05735048 -0.05945583 -0.06156119 -0.06366654 -0.06577189 -0.06787725 -0.06998260 -0.07208795 -0.07419331 -0.07629866 -0.07840401 -0.08050937 -0.08261472 -0.08472008 -0.07921295 -0.05358619 -0.05636426 -0.06307564 -0.07173987 -0.08172495 -0.09271927 -0.10454428 -0.11705643 -0.13017613 -0.14379976 -0.15793978 -0.17258746 -0.18766434 -0.20315149 -0.21909644 -0.23538854 -0.25208919 -0.26915631 -0.28659300 -0.30437969 -0.32249538 -0.34096095 -0.35974552 -0.37881117 -0.39822177 -0.41789494 -0.43785131 -0.45808118 -0.47857910 ! WE_FOPoles - First order system poles [1/s] !------- YAW CONTROL ------------------------------------------------------ 0.0 ! Y_ErrThresh - Yaw error threshold. Turbine begins to yaw when it passes this. [rad^2 s] diff --git a/setup.py b/setup.py index e007dcf42..b2b669fae 100644 --- a/setup.py +++ b/setup.py @@ -52,6 +52,64 @@ } } + +# For the CMake Extensions +this_directory = os.path.abspath(os.path.dirname(__file__)) +ncpus = mp.cpu_count() +class CMakeExtension(Extension): + + def __init__(self, name, sourcedir='', **kwa): + Extension.__init__(self, name, sources=[], **kwa) + self.sourcedir = os.path.abspath(sourcedir) + +class CMakeBuildExt(build_ext): + + def copy_extensions_to_source(self): + newext = [] + for ext in self.extensions: + if isinstance(ext, CMakeExtension): continue + newext.append( ext ) + self.extensions = newext + super().copy_extensions_to_source() + + def build_extension(self, ext): + if isinstance(ext, CMakeExtension): + # Ensure that CMake is present and working + try: + self.spawn(['cmake', '--version']) + except OSError: + raise RuntimeError('Cannot find CMake executable') + + # Refresh build directory + localdir = os.path.join(this_directory, 'ROSCO','install') + os.makedirs(localdir, exist_ok=True) + + cmake_args = ['-DBUILD_SHARED_LIBS=OFF'] + cmake_args += ['-DCMAKE_Fortran_FLAGS=-ffree-line-length-0'] + + if platform.system() == 'Windows': + cmake_args += ['-DCMAKE_INSTALL_PREFIX={}'.format(localdir)] + if self.compiler.compiler_type == 'msvc': + cmake_args += ['-DCMAKE_GENERATOR_PLATFORM=x64'] + else: + cmake_args += ['-G', 'MinGW Makefiles'] + cmake_args += ['-D', 'CMAKE_Fortran_COMPILER=gfortran'] + + self.build_temp = os.path.join( os.path.dirname( os.path.realpath(__file__) ), 'ROSCO', 'build') + os.makedirs(localdir, exist_ok=True) + # Need fresh build directory for CMake + os.makedirs(self.build_temp, exist_ok=True) + + self.spawn(['cmake', '-S', ext.sourcedir, '-B', self.build_temp] + cmake_args) + self.spawn(['cmake', '--build', self.build_temp, '--target', 'install', '--config', 'Release']) + + else: + super().build_extension(ext) + + +# All of the extensions +roscoExt = CMakeExtension('rosco','ROSCO') + # The rest you shouldn't have to touch too much :) # ------------------------------------------------ # Except, perhaps the License and Trove Classifiers! @@ -113,24 +171,27 @@ def run(self): sys.exit() -# Where the magic happens: -setup( - name=NAME, - version=about['__version__'], - description=DESCRIPTION, - long_description=long_description, - long_description_content_type='text/markdown', - author=AUTHOR, - author_email=EMAIL, - python_requires=REQUIRES_PYTHON, - url=URL, - packages=find_packages(exclude=["tests", "*.tests", "*.tests.*", "tests.*"]), - install_requires=REQUIRED, - extras_require=EXTRAS, - include_package_data=True, - license='Apache License, Version 2.0', - - cmdclass={ - 'upload': UploadCommand, - }, + +metadata = dict( + name = NAME, + version = about['__version__'], + description = DESCRIPTION, + long_description = long_description, + long_description_content_type = 'text/markdown', + author = AUTHOR, + author_email = EMAIL, + url = URL, + install_requires = REQUIRED, + python_requires = REQUIRES_PYTHON, + extras_require = EXTRAS, + include_package_date = True, + packages = find_packages(exclude=["tests", "*.tests", "*.tests.*", "tests.*"]), + license = 'Apache License, Version 2.0', + cmdclass = {'build_ext': CMakeBuildExt, 'upload': UploadCommand}, + zip_safe = False, ) +if "--compile-rosco" in sys.argv: + metadata['ext_modules'] = [roscoExt] + sys.argv.remove("--compile-rosco") + +setup(**metadata)