From 0de06aa9920dad90a3b933b93adc0411a060e9a7 Mon Sep 17 00:00:00 2001 From: Jake Nunemaker Date: Thu, 24 Sep 2020 17:39:07 -0600 Subject: [PATCH] Initialize InflowWind with strings or input file --- .../tests-module-inflowwind/action.yml | 9 + .github/workflows/automated-dev-tests.yml | 2 + modules/inflowwind/src/IfW_UniformWind.f90 | 350 ++++---- modules/inflowwind/src/IfW_UniformWind.txt | 12 +- .../inflowwind/src/IfW_UniformWind_Types.f90 | 100 ++- modules/inflowwind/src/InflowWind.f90 | 44 +- modules/inflowwind/src/InflowWind.txt | 6 +- modules/inflowwind/src/InflowWind_Subs.f90 | 752 ++++-------------- modules/inflowwind/src/InflowWind_Types.f90 | 111 ++- modules/inflowwind/tests/ifw_test_tools.F90 | 143 ++++ modules/inflowwind/tests/test_bladed_wind.F90 | 35 + modules/inflowwind/tests/test_hawc_wind.F90 | 64 ++ modules/inflowwind/tests/test_outputs.F90 | 62 ++ modules/inflowwind/tests/test_steady_wind.F90 | 63 ++ .../inflowwind/tests/test_turbsim_wind.F90 | 34 + .../inflowwind/tests/test_uniform_wind.F90 | 99 +++ reg_tests/r-test | 2 +- unit_tests/CMakeLists.txt | 5 +- unit_tests/inflowwind/CMakeLists.txt | 67 ++ 19 files changed, 1184 insertions(+), 776 deletions(-) create mode 100644 .github/actions/tests-module-inflowwind/action.yml create mode 100644 modules/inflowwind/tests/ifw_test_tools.F90 create mode 100644 modules/inflowwind/tests/test_bladed_wind.F90 create mode 100644 modules/inflowwind/tests/test_hawc_wind.F90 create mode 100644 modules/inflowwind/tests/test_outputs.F90 create mode 100644 modules/inflowwind/tests/test_steady_wind.F90 create mode 100644 modules/inflowwind/tests/test_turbsim_wind.F90 create mode 100644 modules/inflowwind/tests/test_uniform_wind.F90 create mode 100644 unit_tests/inflowwind/CMakeLists.txt diff --git a/.github/actions/tests-module-inflowwind/action.yml b/.github/actions/tests-module-inflowwind/action.yml new file mode 100644 index 0000000000..93a7e14b5f --- /dev/null +++ b/.github/actions/tests-module-inflowwind/action.yml @@ -0,0 +1,9 @@ +name: 'InflowWind module tests' +description: 'Run tests specific to the InflowWind module' +author: 'Rafael Mudafort https://github.com/rafmudaf' +runs: + using: "composite" + steps: + - run: ctest -VV -R inflowwind_utest + working-directory: "/openfast/build" + shell: bash diff --git a/.github/workflows/automated-dev-tests.yml b/.github/workflows/automated-dev-tests.yml index 5091fa6dad..163fbf9f46 100644 --- a/.github/workflows/automated-dev-tests.yml +++ b/.github/workflows/automated-dev-tests.yml @@ -59,6 +59,8 @@ jobs: uses: ./.github/actions/tests-module-aerodyn - name: 'Run BeamDyn tests' uses: ./.github/actions/tests-module-beamdyn + - name: 'Run InflowWind tests' + uses: ./.github/actions/tests-module-inflowwind - name: 'Run OpenFAST tests' # if: contains(github.event.head_commit.message, 'Action - Test All') || contains(github.event.pull_request.labels.*.name, 'Action - Test All') uses: ./.github/actions/tests-gluecode-openfast diff --git a/modules/inflowwind/src/IfW_UniformWind.f90 b/modules/inflowwind/src/IfW_UniformWind.f90 index 8d4b7882ff..9e1e275b27 100644 --- a/modules/inflowwind/src/IfW_UniformWind.f90 +++ b/modules/inflowwind/src/IfW_UniformWind.f90 @@ -93,7 +93,7 @@ SUBROUTINE IfW_UniformWind_Init(InitData, ParamData, MiscVars, Interval, InitOut ! Passed Variables TYPE(IfW_UniformWind_InitInputType), INTENT(IN ) :: InitData !< Input data for initialization TYPE(IfW_UniformWind_ParameterType), INTENT( OUT) :: ParamData !< Parameters - TYPE(IfW_UniformWind_MiscVarType), INTENT( OUT) :: MiscVars !< Misc variables for optimization (not copied in glue code) + TYPE(IfW_UniformWind_MiscVarType), INTENT(INOUT) :: MiscVars !< Misc variables for optimization (not copied in glue code) TYPE(IfW_UniformWind_InitOutputType), INTENT( OUT) :: InitOutData !< Initial output REAL(DbKi), INTENT(IN ) :: Interval !< We don't change this. @@ -108,6 +108,7 @@ SUBROUTINE IfW_UniformWind_Init(InitData, ParamData, MiscVars, Interval, InitOut INTEGER(IntKi), PARAMETER :: NumCols = 8 ! Number of columns in the Uniform file REAL(ReKi) :: TmpData(NumCols) ! Temp variable for reading all columns from a line + INTEGER(IntKi) :: LineNo REAL(ReKi) :: DelDiff ! Temp variable for storing the direction difference INTEGER(IntKi) :: UnitWind ! Unit number for the InflowWind input file @@ -116,6 +117,7 @@ SUBROUTINE IfW_UniformWind_Init(InitData, ParamData, MiscVars, Interval, InitOut INTEGER(IntKi) :: ILine ! Counts the line number in the file INTEGER(IntKi), PARAMETER :: MaxTries = 100 CHARACTER(1024) :: Line ! Temp variable for reading whole line from file + TYPE(FileInfoType) :: InFileInfo !< The derived type for holding the full input file for parsing -- we may pass this in the future ! Temporary variables for error handling INTEGER(IntKi) :: TmpErrStat ! Temp variable for the error status @@ -129,7 +131,6 @@ SUBROUTINE IfW_UniformWind_Init(InitData, ParamData, MiscVars, Interval, InitOut ErrStat = ErrID_None ErrMsg = "" - !------------------------------------------------------------------------------------------------- ! Check that it's not already initialized !------------------------------------------------------------------------------------------------- @@ -139,14 +140,6 @@ SUBROUTINE IfW_UniformWind_Init(InitData, ParamData, MiscVars, Interval, InitOut RETURN END IF - - ! Get a unit number to use - - CALL GetNewUnit(UnitWind, TmpErrStat, TmpErrMsg) - CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - !------------------------------------------------------------------------------------------------- ! Copy things from the InitData to the ParamData !------------------------------------------------------------------------------------------------- @@ -154,185 +147,161 @@ SUBROUTINE IfW_UniformWind_Init(InitData, ParamData, MiscVars, Interval, InitOut ParamData%RefHt = InitData%ReferenceHeight ParamData%RefLength = InitData%RefLength + IF ( InitData%UseInputFile ) THEN + + ! Get a unit number to use + + CALL GetNewUnit(UnitWind, TmpErrStat, TmpErrMsg) + CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) + IF (ErrStat >= AbortErrLev) RETURN !------------------------------------------------------------------------------------------------- ! Open the file for reading !------------------------------------------------------------------------------------------------- - CALL OpenFInpFile (UnitWind, TRIM(InitData%WindFileName), TmpErrStat, TmpErrMsg) - CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - IF ( ErrStat >= AbortErrLev ) RETURN - + CALL OpenFInpFile (UnitWind, TRIM(InitData%WindFileName), TmpErrStat, TmpErrMsg) + CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) + IF ( ErrStat >= AbortErrLev ) RETURN !------------------------------------------------------------------------------------------------- ! Find the number of comment lines !------------------------------------------------------------------------------------------------- - LINE = '!' ! Initialize the line for the DO WHILE LOOP - NumComments = -1 ! the last line we read is not a comment, so we'll initialize this to -1 instead of 0 + LINE = '!' ! Initialize the line for the DO WHILE LOOP + NumComments = -1 ! the last line we read is not a comment, so we'll initialize this to -1 instead of 0 - DO WHILE ( (INDEX( LINE, '!' ) > 0) .OR. (INDEX( LINE, '#' ) > 0) .OR. (INDEX( LINE, '%' ) > 0) ) ! Lines containing "!" are treated as comment lines - NumComments = NumComments + 1 + DO WHILE ( (INDEX( LINE, '!' ) > 0) .OR. (INDEX( LINE, '#' ) > 0) .OR. (INDEX( LINE, '%' ) > 0) ) ! Lines containing "!" are treated as comment lines + NumComments = NumComments + 1 - READ(UnitWind,'( A )',IOSTAT=TmpErrStat) LINE + READ(UnitWind,'( A )',IOSTAT=TmpErrStat) LINE - IF ( TmpErrStat /=0 ) THEN - CALL SetErrStat(ErrID_Fatal,' Error reading from uniform wind file on line '//TRIM(Num2LStr(NumComments+1))//'.', & - ErrStat, ErrMsg, RoutineName) - CLOSE(UnitWind) - RETURN - END IF - - END DO !WHILE + IF ( TmpErrStat /=0 ) THEN + CALL SetErrStat(ErrID_Fatal,' Error reading from uniform wind file on line '//TRIM(Num2LStr(NumComments+1))//'.', & + ErrStat, ErrMsg, RoutineName) + CLOSE(UnitWind) + RETURN + END IF + END DO !WHILE !------------------------------------------------------------------------------------------------- ! Find the number of data lines !------------------------------------------------------------------------------------------------- - ParamData%NumDataLines = 0 + ParamData%NumDataLines = 0 - READ(LINE,*,IOSTAT=TmpErrStat) ( TmpData(I), I=1,NumCols ) ! this line was read when we were figuring out the comment lines; let's make sure it contains + READ(LINE,*,IOSTAT=TmpErrStat) ( TmpData(I), I=1,NumCols ) ! this line was read when we were figuring out the comment lines; let's make sure it contains - DO WHILE (TmpErrStat == 0) ! read the rest of the file (until an error occurs) - ParamData%NumDataLines = ParamData%NumDataLines + 1 + DO WHILE (TmpErrStat == 0) ! read the rest of the file (until an error occurs) + ParamData%NumDataLines = ParamData%NumDataLines + 1 - READ(UnitWind,*,IOSTAT=TmpErrStat) ( TmpData(I), I=1,NumCols ) + READ(UnitWind,*,IOSTAT=TmpErrStat) ( TmpData(I), I=1,NumCols ) - END DO !WHILE - - - IF (ParamData%NumDataLines < 1) THEN - TmpErrMsg= 'Error: '//TRIM(Num2LStr(NumComments))//' comment lines were found in the uniform wind file, '// & - 'but the first data line does not contain the proper format.' - CALL SetErrStat(ErrID_Fatal,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - CLOSE(UnitWind) - RETURN - END IF - - - !------------------------------------------------------------------------------------------------- - ! Allocate arrays for the uniform wind data - !------------------------------------------------------------------------------------------------- - ! BJJ note: If the subroutine AllocAry() is called, the CVF compiler with A2AD does not work - ! properly. The arrays are not properly read even though they've been allocated. - ! ADP note: the above note may or may not apply after conversion to the modular framework in 2013 - !------------------------------------------------------------------------------------------------- + END DO !WHILE - IF (.NOT. ALLOCATED(ParamData%Tdata) ) THEN - CALL AllocAry( ParamData%Tdata, ParamData%NumDataLines, 'Uniform wind time', TmpErrStat, TmpErrMsg ) - CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - IF ( ErrStat >= AbortErrLev ) THEN - CLOSE(UnitWind) - RETURN - ENDIF - END IF - - IF (.NOT. ALLOCATED(ParamData%V) ) THEN - CALL AllocAry( ParamData%V, ParamData%NumDataLines, 'Uniform wind horizontal wind speed', TmpErrStat, TmpErrMsg ) - CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - IF ( ErrStat >= AbortErrLev ) THEN - CLOSE(UnitWind) - RETURN - ENDIF - END IF - - IF (.NOT. ALLOCATED(ParamData%Delta) ) THEN - CALL AllocAry( ParamData%Delta, ParamData%NumDataLines, 'Uniform wind direction', TmpErrStat, TmpErrMsg ) - CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - IF ( ErrStat >= AbortErrLev ) THEN - CLOSE(UnitWind) - RETURN - ENDIF - END IF - IF (.NOT. ALLOCATED(ParamData%VZ) ) THEN - CALL AllocAry( ParamData%VZ, ParamData%NumDataLines, 'Uniform vertical wind speed', TmpErrStat, TmpErrMsg ) - CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - IF ( ErrStat >= AbortErrLev ) THEN + IF (ParamData%NumDataLines < 1) THEN + TmpErrMsg= 'Error: '//TRIM(Num2LStr(NumComments))//' comment lines were found in the uniform wind file, '// & + 'but the first data line does not contain the proper format.' + CALL SetErrStat(ErrID_Fatal,TmpErrMsg,ErrStat,ErrMsg,RoutineName) CLOSE(UnitWind) RETURN - ENDIF - END IF + END IF - IF (.NOT. ALLOCATED(ParamData%HShr) ) THEN - CALL AllocAry( ParamData%HShr, ParamData%NumDataLines, 'Uniform horizontal linear shear', TmpErrStat, TmpErrMsg ) - CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - IF ( ErrStat >= AbortErrLev ) THEN - CLOSE(UnitWind) - RETURN - ENDIF - END IF + !------------------------------------------------------------------------------------------------- + ! Allocate the data arrays + !------------------------------------------------------------------------------------------------- - IF (.NOT. ALLOCATED(ParamData%VShr) ) THEN - CALL AllocAry( ParamData%VShr, ParamData%NumDataLines, 'Uniform vertical power-law shear exponent', TmpErrStat, TmpErrMsg ) - CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) + CALL Alloc_ParamDataArrays( ParamData, TmpErrStat, TmpErrMsg) IF ( ErrStat >= AbortErrLev ) THEN CLOSE(UnitWind) RETURN - ENDIF - END IF + END IF - IF (.NOT. ALLOCATED(ParamData%VLinShr) ) THEN - CALL AllocAry( ParamData%VLinShr, ParamData%NumDataLines, 'Uniform vertical linear shear', TmpErrStat, TmpErrMsg ) - CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - IF ( ErrStat >= AbortErrLev ) THEN - CLOSE(UnitWind) - RETURN - ENDIF - END IF + !------------------------------------------------------------------------------------------------- + ! Rewind the file (to the beginning) and skip the comment lines + !------------------------------------------------------------------------------------------------- - IF (.NOT. ALLOCATED(ParamData%VGust) ) THEN - CALL AllocAry( ParamData%VGust, ParamData%NumDataLines, 'Uniform gust velocity', TmpErrStat, TmpErrMsg ) - CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - IF ( ErrStat >= AbortErrLev ) THEN - CLOSE(UnitWind) - RETURN - ENDIF - END IF + REWIND( UnitWind ) + DO I=1,NumComments + CALL ReadCom( UnitWind, TRIM(InitData%WindFileName), 'Header line #'//TRIM(Num2LStr(I)), TmpErrStat, TmpErrMsg ) + CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) + IF ( ErrStat >= AbortErrLev ) THEN + CLOSE(UnitWind) + RETURN + ENDIF + END DO !------------------------------------------------------------------------------------------------- - ! Rewind the file (to the beginning) and skip the comment lines + ! Read the data arrays !------------------------------------------------------------------------------------------------- - REWIND( UnitWind ) - - DO I=1,NumComments - CALL ReadCom( UnitWind, TRIM(InitData%WindFileName), 'Header line #'//TRIM(Num2LStr(I)), TmpErrStat, TmpErrMsg ) - CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - IF ( ErrStat >= AbortErrLev ) THEN - CLOSE(UnitWind) - RETURN - ENDIF - END DO !I + DO I=1,ParamData%NumDataLines + + CALL ReadAry( UnitWind, TRIM(InitData%WindFileName), TmpData(1:NumCols), NumCols, 'TmpData', & + 'Data from uniform wind file line '//TRIM(Num2LStr(NumComments+I)), TmpErrStat, TmpErrMsg) + CALL SetErrStat(TmpErrStat,'Error retrieving data from the uniform wind file line'//TRIM(Num2LStr(NumComments+I)), & + ErrStat,ErrMsg,RoutineName) + IF ( ErrStat >= AbortErrLev ) THEN + CLOSE(UnitWind) + RETURN + ENDIF + + ParamData%Tdata( I) = TmpData(1) + ParamData%V( I) = TmpData(2) + ParamData%Delta( I) = TmpData(3)*D2R + ParamData%VZ( I) = TmpData(4) + ParamData%HShr( I) = TmpData(5) + ParamData%VShr( I) = TmpData(6) + ParamData%VLinShr(I) = TmpData(7) + ParamData%VGust( I) = TmpData(8) + END DO !I !------------------------------------------------------------------------------------------------- - ! Read the data arrays + ! Close the file !------------------------------------------------------------------------------------------------- - DO I=1,ParamData%NumDataLines + CLOSE( UnitWind ) + + ELSE + + NumComments = 0 + DO I=1, SIZE(InitData%PassedFileData%Lines) + Line = InitData%PassedFileData%Lines(I) + IF ( (INDEX( Line, '!' ) > 0) .OR. (INDEX( Line, '#' ) > 0) .OR. (INDEX( Line, '%' ) > 0) ) THEN + NumComments = NumComments + 1 + END if + END DO - CALL ReadAry( UnitWind, TRIM(InitData%WindFileName), TmpData(1:NumCols), NumCols, 'TmpData', & - 'Data from uniform wind file line '//TRIM(Num2LStr(NumComments+I)), TmpErrStat, TmpErrMsg) - CALL SetErrStat(TmpErrStat,'Error retrieving data from the uniform wind file line'//TRIM(Num2LStr(NumComments+I)), & - ErrStat,ErrMsg,RoutineName) + ParamData%NumDataLines = SIZE(InitData%PassedFileData%Lines) - NumComments + CALL Alloc_ParamDataArrays( ParamData, TmpErrStat, TmpErrMsg) IF ( ErrStat >= AbortErrLev ) THEN - CLOSE(UnitWind) RETURN ENDIF + DO I=1,ParamData%NumDataLines + + LineNo = NumComments + I + CALL ParseAry( InitData%PassedFileData, LineNo, "Wind type 2 line"//TRIM(Num2LStr(NumComments+I)), TmpData(1:NumCols), NumCols, TmpErrStat, TmpErrMsg ) + CALL SetErrStat(TmpErrStat,'Error retrieving data from the uniform wind file line'//TRIM(Num2LStr(NumComments+I)), & + ErrStat,ErrMsg,RoutineName) + IF ( ErrStat >= AbortErrLev ) THEN + RETURN + ENDIF + + ParamData%Tdata( I) = TmpData(1) + ParamData%V( I) = TmpData(2) + ParamData%Delta( I) = TmpData(3)*D2R + ParamData%VZ( I) = TmpData(4) + ParamData%HShr( I) = TmpData(5) + ParamData%VShr( I) = TmpData(6) + ParamData%VLinShr(I) = TmpData(7) + ParamData%VGust( I) = TmpData(8) - ParamData%Tdata( I) = TmpData(1) - ParamData%V( I) = TmpData(2) - ParamData%Delta( I) = TmpData(3)*D2R - ParamData%VZ( I) = TmpData(4) - ParamData%HShr( I) = TmpData(5) - ParamData%VShr( I) = TmpData(6) - ParamData%VLinShr(I) = TmpData(7) - ParamData%VGust( I) = TmpData(8) + END DO !I - END DO !I + END IF !------------------------------------------------------------------------------------------------- @@ -366,8 +335,6 @@ SUBROUTINE IfW_UniformWind_Init(InitData, ParamData, MiscVars, Interval, InitOut END DO !I - - !------------------------------------------------------------------------------------------------- ! Find out information on the timesteps and range !------------------------------------------------------------------------------------------------- @@ -403,15 +370,6 @@ SUBROUTINE IfW_UniformWind_Init(InitData, ParamData, MiscVars, Interval, InitOut ! Number of timesteps InitOutData%WindFileNumTSteps = ParamData%NumDataLines - - - !------------------------------------------------------------------------------------------------- - ! Close the file - !------------------------------------------------------------------------------------------------- - - CLOSE( UnitWind ) - - !------------------------------------------------------------------------------------------------- ! Print warnings and messages !------------------------------------------------------------------------------------------------- @@ -476,6 +434,98 @@ SUBROUTINE IfW_UniformWind_Init(InitData, ParamData, MiscVars, Interval, InitOut END SUBROUTINE IfW_UniformWind_Init +SUBROUTINE Alloc_ParamDataArrays( ParamData, ErrStat, ErrMsg ) + + IMPLICIT NONE + CHARACTER(*), PARAMETER :: RoutineName="Alloc_ParamDataArrays" + + TYPE(IfW_UniformWind_ParameterType), INTENT(INOUT) :: ParamData !< Parameters + + ! Error handling + INTEGER(IntKi), INTENT( OUT) :: ErrStat !< determines if an error has been encountered + CHARACTER(*), INTENT( OUT) :: ErrMsg !< A message about the error + + ! Temporary variables for error handling + INTEGER(IntKi) :: TmpErrStat ! Temp variable for the error status + CHARACTER(ErrMsgLen) :: TmpErrMsg ! Temporary error message + + ErrStat = ErrID_None + ErrMsg = "" + + !------------------------------------------------------------------------------------------------- + ! Allocate arrays for the uniform wind data + !------------------------------------------------------------------------------------------------- + ! BJJ note: If the subroutine AllocAry() is called, the CVF compiler with A2AD does not work + ! properly. The arrays are not properly read even though they've been allocated. + ! ADP note: the above note may or may not apply after conversion to the modular framework in 2013 + !------------------------------------------------------------------------------------------------- + + IF (.NOT. ALLOCATED(ParamData%Tdata) ) THEN + CALL AllocAry( ParamData%Tdata, ParamData%NumDataLines, 'Uniform wind time', TmpErrStat, TmpErrMsg ) + CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) + IF ( ErrStat >= AbortErrLev ) THEN + RETURN + ENDIF + END IF + + IF (.NOT. ALLOCATED(ParamData%V) ) THEN + CALL AllocAry( ParamData%V, ParamData%NumDataLines, 'Uniform wind horizontal wind speed', TmpErrStat, TmpErrMsg ) + CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) + IF ( ErrStat >= AbortErrLev ) THEN + RETURN + ENDIF + END IF + + IF (.NOT. ALLOCATED(ParamData%Delta) ) THEN + CALL AllocAry( ParamData%Delta, ParamData%NumDataLines, 'Uniform wind direction', TmpErrStat, TmpErrMsg ) + CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) + IF ( ErrStat >= AbortErrLev ) THEN + RETURN + ENDIF + END IF + + IF (.NOT. ALLOCATED(ParamData%VZ) ) THEN + CALL AllocAry( ParamData%VZ, ParamData%NumDataLines, 'Uniform vertical wind speed', TmpErrStat, TmpErrMsg ) + CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) + IF ( ErrStat >= AbortErrLev ) THEN + RETURN + ENDIF + END IF + + IF (.NOT. ALLOCATED(ParamData%HShr) ) THEN + CALL AllocAry( ParamData%HShr, ParamData%NumDataLines, 'Uniform horizontal linear shear', TmpErrStat, TmpErrMsg ) + CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) + IF ( ErrStat >= AbortErrLev ) THEN + RETURN + ENDIF + END IF + + IF (.NOT. ALLOCATED(ParamData%VShr) ) THEN + CALL AllocAry( ParamData%VShr, ParamData%NumDataLines, 'Uniform vertical power-law shear exponent', TmpErrStat, TmpErrMsg ) + CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) + IF ( ErrStat >= AbortErrLev ) THEN + RETURN + ENDIF + END IF + + IF (.NOT. ALLOCATED(ParamData%VLinShr) ) THEN + CALL AllocAry( ParamData%VLinShr, ParamData%NumDataLines, 'Uniform vertical linear shear', TmpErrStat, TmpErrMsg ) + CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) + IF ( ErrStat >= AbortErrLev ) THEN + RETURN + ENDIF + END IF + + IF (.NOT. ALLOCATED(ParamData%VGust) ) THEN + CALL AllocAry( ParamData%VGust, ParamData%NumDataLines, 'Uniform gust velocity', TmpErrStat, TmpErrMsg ) + CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) + IF ( ErrStat >= AbortErrLev ) THEN + RETURN + ENDIF + END IF + +END SUBROUTINE + !==================================================================================================== !------------------------------------------------------------------------------------------------- diff --git a/modules/inflowwind/src/IfW_UniformWind.txt b/modules/inflowwind/src/IfW_UniformWind.txt index 37e2853b36..c070ef305b 100644 --- a/modules/inflowwind/src/IfW_UniformWind.txt +++ b/modules/inflowwind/src/IfW_UniformWind.txt @@ -12,10 +12,12 @@ include Registry_NWTC_Library.txt ######################### -typedef IfW_UniformWind/IfW_UniformWind InitInputType CHARACTER(1024) WindFileName - - - "Name of the wind file to use" - -typedef ^ ^ ReKi ReferenceHeight - - - "Hub height of the turbine" meters -typedef ^ ^ ReKi RefLength - - - "RefLength of the wind field to use" meters -typedef ^ ^ IntKi SumFileUnit - - - "Unit number for the summary file (-1 for none). Provided by IfW." - +typedef IfW_UniformWind/IfW_UniformWind InitInputType CHARACTER(1024) WindFileName - - - "Name of the wind file to use" - +typedef ^ ^ ReKi ReferenceHeight - - - "Hub height of the turbine" meters +typedef ^ ^ ReKi RefLength - - - "RefLength of the wind field to use" meters +typedef ^ ^ IntKi SumFileUnit - - - "Unit number for the summary file (-1 for none). Provided by IfW." - +typedef ^ ^ LOGICAL UseInputFile - .TRUE. - "Flag for toggling file based IO in wind type 2." - +typedef ^ ^ FileInfoType PassedFileData - - - "Optional slot for wind type 2 data if file IO is not used." - @@ -30,7 +32,7 @@ typedef ^ ^ LOGICAL WindFileConsta # ..... Misc/Optimization variables................................................................................................. # Define any data that are used only for efficiency purposes (these variables are not associated with time): # e.g. indices for searching in an array, large arrays that are local variables in any routine called multiple times, etc. -typedef ^ MiscVarType IntKi TimeIndex - - - "An Index into the TData array" - +typedef ^ MiscVarType IntKi TimeIndex - 0 - "An Index into the TData array" - # ..... Parameters ................................................................................................................ diff --git a/modules/inflowwind/src/IfW_UniformWind_Types.f90 b/modules/inflowwind/src/IfW_UniformWind_Types.f90 index 882554e796..ddb3049b96 100644 --- a/modules/inflowwind/src/IfW_UniformWind_Types.f90 +++ b/modules/inflowwind/src/IfW_UniformWind_Types.f90 @@ -39,6 +39,8 @@ MODULE IfW_UniformWind_Types REAL(ReKi) :: ReferenceHeight !< Hub height of the turbine [meters] REAL(ReKi) :: RefLength !< RefLength of the wind field to use [meters] INTEGER(IntKi) :: SumFileUnit !< Unit number for the summary file (-1 for none). Provided by IfW. [-] + LOGICAL :: UseInputFile = .TRUE. !< Flag for toggling file based IO in wind type 2. [-] + TYPE(FileInfoType) :: PassedFileData !< Optional slot for wind type 2 data if file IO is not used. [-] END TYPE IfW_UniformWind_InitInputType ! ======================= ! ========= IfW_UniformWind_InitOutputType ======= @@ -52,7 +54,7 @@ MODULE IfW_UniformWind_Types ! ======================= ! ========= IfW_UniformWind_MiscVarType ======= TYPE, PUBLIC :: IfW_UniformWind_MiscVarType - INTEGER(IntKi) :: TimeIndex !< An Index into the TData array [-] + INTEGER(IntKi) :: TimeIndex = 0 !< An Index into the TData array [-] END TYPE IfW_UniformWind_MiscVarType ! ======================= ! ========= IfW_UniformWind_ParameterType ======= @@ -101,6 +103,10 @@ SUBROUTINE IfW_UniformWind_CopyInitInput( SrcInitInputData, DstInitInputData, Ct DstInitInputData%ReferenceHeight = SrcInitInputData%ReferenceHeight DstInitInputData%RefLength = SrcInitInputData%RefLength DstInitInputData%SumFileUnit = SrcInitInputData%SumFileUnit + DstInitInputData%UseInputFile = SrcInitInputData%UseInputFile + CALL NWTC_Library_Copyfileinfotype( SrcInitInputData%PassedFileData, DstInitInputData%PassedFileData, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN END SUBROUTINE IfW_UniformWind_CopyInitInput SUBROUTINE IfW_UniformWind_DestroyInitInput( InitInputData, ErrStat, ErrMsg ) @@ -112,6 +118,7 @@ SUBROUTINE IfW_UniformWind_DestroyInitInput( InitInputData, ErrStat, ErrMsg ) ! ErrStat = ErrID_None ErrMsg = "" + CALL NWTC_Library_Destroyfileinfotype( InitInputData%PassedFileData, ErrStat, ErrMsg ) END SUBROUTINE IfW_UniformWind_DestroyInitInput SUBROUTINE IfW_UniformWind_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -153,6 +160,25 @@ SUBROUTINE IfW_UniformWind_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, Er Re_BufSz = Re_BufSz + 1 ! ReferenceHeight Re_BufSz = Re_BufSz + 1 ! RefLength Int_BufSz = Int_BufSz + 1 ! SumFileUnit + Int_BufSz = Int_BufSz + 1 ! UseInputFile + ! Allocate buffers for subtypes, if any (we'll get sizes from these) + Int_BufSz = Int_BufSz + 3 ! PassedFileData: size of buffers for each call to pack subtype + CALL NWTC_Library_Packfileinfotype( Re_Buf, Db_Buf, Int_Buf, InData%PassedFileData, ErrStat2, ErrMsg2, .TRUE. ) ! PassedFileData + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! PassedFileData + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! PassedFileData + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! PassedFileData + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -190,6 +216,36 @@ SUBROUTINE IfW_UniformWind_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, Er Re_Xferred = Re_Xferred + 1 IntKiBuf(Int_Xferred) = InData%SumFileUnit Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = TRANSFER(InData%UseInputFile, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 + CALL NWTC_Library_Packfileinfotype( Re_Buf, Db_Buf, Int_Buf, InData%PassedFileData, ErrStat2, ErrMsg2, OnlySize ) ! PassedFileData + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf + Re_Xferred = Re_Xferred + SIZE(Re_Buf) + DEALLOCATE(Re_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Db_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf + Db_Xferred = Db_Xferred + SIZE(Db_Buf) + DEALLOCATE(Db_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Int_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf + Int_Xferred = Int_Xferred + SIZE(Int_Buf) + DEALLOCATE(Int_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF END SUBROUTINE IfW_UniformWind_PackInitInput SUBROUTINE IfW_UniformWind_UnPackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) @@ -229,6 +285,48 @@ SUBROUTINE IfW_UniformWind_UnPackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, Re_Xferred = Re_Xferred + 1 OutData%SumFileUnit = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 + OutData%UseInputFile = TRANSFER(IntKiBuf(Int_Xferred), OutData%UseInputFile) + Int_Xferred = Int_Xferred + 1 + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) + Re_Xferred = Re_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) + Db_Xferred = Db_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) + Int_Xferred = Int_Xferred + Buf_size + END IF + CALL NWTC_Library_Unpackfileinfotype( Re_Buf, Db_Buf, Int_Buf, OutData%PassedFileData, ErrStat2, ErrMsg2 ) ! PassedFileData + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) + IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) + IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) END SUBROUTINE IfW_UniformWind_UnPackInitInput SUBROUTINE IfW_UniformWind_CopyInitOutput( SrcInitOutputData, DstInitOutputData, CtrlCode, ErrStat, ErrMsg ) diff --git a/modules/inflowwind/src/InflowWind.f90 b/modules/inflowwind/src/InflowWind.f90 index 6c12d390f9..6558bc6605 100644 --- a/modules/inflowwind/src/InflowWind.f90 +++ b/modules/inflowwind/src/InflowWind.f90 @@ -139,13 +139,14 @@ SUBROUTINE InflowWind_Init( InitInp, InputGuess, p, ContStates, DiscStates, TYPE(IfW_4Dext_InitOutputType) :: FDext_InitOutData !< initialization info + TYPE(FileInfoType) :: InFileInfo !< The derived type for holding the full input file for parsing -- we may pass this in the future !!! TYPE(CTBladed_Backgr) :: BackGrndValues ! Temporary variables for error handling INTEGER(IntKi) :: TmpErrStat CHARACTER(ErrMsgLen) :: TmpErrMsg !< temporary error message - + CHARACTER(1024) :: PriPath ! Local Variables INTEGER(IntKi) :: I, j !< Generic counter @@ -182,37 +183,51 @@ SUBROUTINE InflowWind_Init( InitInp, InputGuess, p, ContStates, DiscStates, EchoFileName = TRIM(p%RootFileName)//".ech" SumFileName = TRIM(p%RootFileName)//".sum" + ! these values (and others hard-coded in lidar_init) should be set in the input file, too + InputFileData%SensorType = InitInp%lidar%SensorType + InputFileData%NumPulseGate = InitInp%lidar%NumPulseGate + InputFileData%RotorApexOffsetPos = InitInp%lidar%RotorApexOffsetPos + InputFileData%LidRadialVel = InitInp%lidar%LidRadialVel ! Parse all the InflowWind related input files and populate the *_InitDataType derived types + CALL GetPath( InitInp%InputFileName, PriPath ) IF ( InitInp%UseInputFile ) THEN - CALL InflowWind_ReadInput( InitInp%InputFileName, EchoFileName, InputFileData, TmpErrStat, TmpErrMsg ) + CALL ProcessComFile( InitInp%InputFileName, InFileInfo, TmpErrStat, TmpErrMsg ) + ! For diagnostic purposes, the following can be used to display the contents + ! of the InFileInfo data structure. + ! call Print_FileInfo_Struct( CU, InFileInfo ) ! CU is the screen -- different number on different systems. + CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) IF ( ErrStat >= AbortErrLev ) THEN CALL Cleanup() RETURN ENDIF - - ! these values (and others hard-coded in lidar_init) should be set in the input file, too - InputFileData%SensorType = InitInp%lidar%SensorType - InputFileData%NumPulseGate = InitInp%lidar%NumPulseGate - InputFileData%RotorApexOffsetPos = InitInp%lidar%RotorApexOffsetPos - InputFileData%LidRadialVel = InitInp%lidar%LidRadialVel ELSE - - CALL InflowWind_CopyInputFile( InitInp%PassedFileData, InputFileData, MESH_NEWCOPY, TmpErrStat, TmpErrMsg ) - CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) + CALL NWTC_Library_CopyFileInfoType( InitInp%PassedFileData, InFileInfo, MESH_NEWCOPY, TmpErrStat, TmpErrMsg ) + CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) + IF ( ErrStat >= AbortErrLev ) THEN + CALL Cleanup() + RETURN + ENDIF ENDIF + CALL InflowWind_ParseInputFileInfo( InputFileData, InFileInfo, PriPath, TmpErrStat, TmpErrMsg ) + CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) + IF ( ErrStat >= AbortErrLev ) THEN + CALL Cleanup() + CALL InflowWind_DestroyInputFile( InputFileData, TmpErrStat, TmpErrMsg ) + RETURN + ENDIF ! let's tell InflowWind if an external module (e.g., FAST.Farm) is going to set the velocity grids. + IF ( InitInp%Use4Dext) then InputFileData%WindType = FDext_WindNumber InputFileData%PropagationDir = 0.0_ReKi ! wind is in XYZ coordinates (already rotated if necessary), so don't rotate it again END IF - - + ! initialize sensor data: CALL Lidar_Init( InitInp, InputGuess, p, ContStates, DiscStates, ConstrStateGuess, OtherStates, & y, m, TimeInterval, InitOutData, TmpErrStat, TmpErrMsg ) @@ -387,6 +402,9 @@ SUBROUTINE InflowWind_Init( InitInp, InputGuess, p, ContStates, DiscStates, Uniform_InitData%WindFileName = InputFileData%Uniform_FileName Uniform_InitData%SumFileUnit = SumFileUnit + Uniform_InitData%UseInputFile = InitInp%WindType2UseInputFile + Uniform_InitData%PassedFileData = InitInp%WindType2Data + ! Initialize the UniformWind module CALL IfW_UniformWind_Init(Uniform_InitData, p%UniformWind, & m%UniformWind, TimeInterval, Uniform_InitOutData, TmpErrStat, TmpErrMsg) diff --git a/modules/inflowwind/src/InflowWind.txt b/modules/inflowwind/src/InflowWind.txt index d634f2db00..9a01d41ad4 100644 --- a/modules/inflowwind/src/InflowWind.txt +++ b/modules/inflowwind/src/InflowWind.txt @@ -73,7 +73,7 @@ typedef ^ ^ ReKi Uniform_Ref typedef ^ ^ CHARACTER(1024) TSFF_FileName - - - "TurbSim Full-Field -- filename" - typedef ^ ^ CHARACTER(1024) BladedFF_FileName - - - "Bladed-style Full-Field -- filename" - typedef ^ ^ LOGICAL BladedFF_TowerFile - - - "Bladed-style Full-Field -- tower file exists" - -typedef ^ ^ LOGICAL CTTS_CoherentTurb - - - "Coherent turbulence data exists" - +typedef ^ ^ LOGICAL CTTS_CoherentTurb - .FALSE. - "Coherent turbulence data exists" - typedef ^ ^ CHARACTER(1024) CTTS_FileName - - - "Name of coherent turbulence file" - typedef ^ ^ CHARACTER(1024) CTTS_Path - - - "Path to coherent turbulence binary data files" - typedef ^ ^ CHARACTER(1024) HAWC_FileName_u - - - "HAWC -- u component binary data file name" - @@ -116,7 +116,9 @@ typedef ^ ^ LOGICAL Use4Dext typedef ^ ^ IntKi NumWindPoints - - - "Number of wind velocity points expected" - typedef ^ ^ LOGICAL UseInputFile - .TRUE. - "Should we read everthing from an input file, or do we get it some other way" - typedef ^ ^ CHARACTER(1024) RootName - - - "RootName for writing output files" -typedef ^ ^ InflowWind_InputFile PassedFileData - - - "If we don't use the input file, pass everything through this" - +typedef ^ ^ FileInfoType PassedFileData - - - "If we don't use the input file, pass everything through this" - +typedef ^ ^ LOGICAL WindType2UseInputFile - .TRUE. - "Flag for toggling file based IO in wind type 2." - +typedef ^ ^ FileInfoType WindType2Data - - - "Optional slot for wind type 2 data if file IO is not used." - typedef ^ ^ Lidar_InitInputType lidar - - - "InitInput for lidar data" - typedef ^ ^ IfW_4Dext_InitInputType FDext - - - "InitInput for lidar data" - diff --git a/modules/inflowwind/src/InflowWind_Subs.f90 b/modules/inflowwind/src/InflowWind_Subs.f90 index 8a6f457e7a..a7384fbf24 100644 --- a/modules/inflowwind/src/InflowWind_Subs.f90 +++ b/modules/inflowwind/src/InflowWind_Subs.f90 @@ -120,192 +120,64 @@ MODULE InflowWind_Subs CONTAINS - !==================================================================================================== -!> This public subroutine reads the input required for InflowWind from the file whose name is an -!! input parameter. -SUBROUTINE InflowWind_ReadInput( InputFileName, EchoFileName, InputFileData, ErrStat, ErrMsg ) +!> This public subroutine parses the array of strings in InputFileData for the input parameters. +SUBROUTINE InflowWind_ParseInputFileInfo( InputFileData, InFileInfo, PriPath, ErrStat, ErrMsg ) !---------------------------------------------------------------------------------------------------- - IMPLICIT NONE - - CHARACTER(*), PARAMETER :: RoutineName="InflowWind_ReadInput" - + IMPLICIT NONE + CHARACTER(*), PARAMETER :: RoutineName="InflowWind_ParseInputFileInfo" ! Passed variables - CHARACTER(*), INTENT(IN ) :: InputFileName !< name of the input file - CHARACTER(*), INTENT(IN ) :: EchoFileName !< name of the echo file - TYPE(InflowWind_InputFile), INTENT(INOUT) :: InputFileData !< The data for initialization - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Returned error status from this subroutine - CHARACTER(*), INTENT( OUT) :: ErrMsg !< Returned error message from this subroutine + TYPE(InflowWind_InputFile), INTENT(INOUT) :: InputFileData !< Data of the InflowWind Input File + TYPE(FileInfoType), INTENT(IN ) :: InFileInfo !< The derived type for holding the file information + CHARACTER(*), INTENT(IN ) :: PriPath !< Path to InflowWind input files + INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Returned error status from this subroutine + CHARACTER(*), INTENT( OUT) :: ErrMsg !< Returned error message from this subroutine ! Local variables - INTEGER(IntKi) :: UnitInput !< Unit number for the input file - INTEGER(IntKi) :: UnitEcho !< The local unit number for this module's echo file - CHARACTER(1024) :: TmpPath !< Temporary storage for relative path name - CHARACTER(1024) :: TmpFmt !< Temporary storage for format statement - CHARACTER(35) :: Frmt !< Output format for logical parameters. (matches NWTC Subroutine Library format) - + INTEGER(IntKi) :: CurLine !< Current entry in InFileInfo%Lines array ! Temoporary messages INTEGER(IntKi) :: TmpErrStat CHARACTER(ErrMsgLen) :: TmpErrMsg - CHARACTER(1024) :: PriPath ! Path name of the primary file - - ! Initialize local data - - UnitEcho = -1 - Frmt = "( 2X, L11, 2X, A, T30, ' - ', A )" + ! Initialization ErrStat = ErrID_None ErrMsg = "" - InputFileData%EchoFlag = .FALSE. ! initialize for error handling (cleanup() routine) - CALL GetPath( InputFileName, PriPath ) ! Input files will be relative to the path where the primary input file is located. - + InputFileData%EchoFlag = .FALSE. ! initialize for error handling (cleanup() routine) - ! allocate the array for the OutList + ! Allocate the array for the OutList CALL AllocAry( InputFileData%OutList, MaxOutPts, "InflowWind Input File's OutList", TmpErrStat, TmpErrMsg ) CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) THEN - CALL Cleanup() - RETURN - END IF - - - !------------------------------------------------------------------------------------------------- - ! Open the file - !------------------------------------------------------------------------------------------------- - - CALL GetNewUnit( UnitInput, TmpErrStat, TmpErrMsg ) - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - - CALL OpenFInpFile( UnitInput, TRIM(InputFileName), TmpErrStat, TmpErrMsg ) - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) THEN - CALL Cleanup() - RETURN - END IF - - - ! Tell the users what we are doing... though this part should be rather quick. - ! CALL WrScr( ' Opening InflowWind input file: '//InputFileName ) - + IF (ErrStat >= AbortErrLev) RETURN - !------------------------------------------------------------------------------------------------- - ! File header - !------------------------------------------------------------------------------------------------- + !--------------------------------------------------------------------------------------------- + ! General settings with wind type, direction and output point list (applies to all wind types) + !--------------------------------------------------------------------------------------------- - CALL ReadCom( UnitInput, InputFileName, 'InflowWind input file header line 1', TmpErrStat, TmpErrMsg ) + CurLine = 4 + CALL ParseVar( InFileInfo, CurLine, "Echo", InputFileData%EchoFlag, TmpErrStat, TmpErrMsg ) CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) THEN - CALL Cleanup() - RETURN - END IF + IF (ErrStat >= AbortErrLev) RETURN - CALL ReadCom( UnitInput, InputFileName, 'InflowWind input file header line 2', TmpErrStat, TmpErrMsg ) + CALL ParseVar( InFileInfo, CurLine, "WindType", InputFileData%WindType, TmpErrStat, TmpErrMsg ) CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) THEN - CALL Cleanup() - RETURN - END IF + IF (ErrStat >= AbortErrLev) RETURN - CALL ReadCom( UnitInput, InputFileName, 'InflowWind input file separator line', TmpErrStat, TmpErrMsg ) + CALL ParseVar( InFileInfo, CurLine, "PropagationDir", InputFileData%PropagationDir, TmpErrStat, TmpErrMsg ) CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) THEN - CALL Cleanup() - RETURN - END IF - - - ! Echo Input Files. + IF (ErrStat >= AbortErrLev) RETURN - CALL ReadVar ( UnitInput, InputFileName, InputFileData%EchoFlag, 'Echo', 'Echo Input', TmpErrStat, TmpErrMsg ) + CALL ParseVar( InFileInfo, CurLine, "NWindVel", InputFileData%NWindVel, TmpErrStat, TmpErrMsg ) CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) THEN - CALL Cleanup() - RETURN - END IF - - ! If we are Echoing the input then we should re-read the first three lines so that we can echo them - ! using the NWTC_Library routines. The echoing is done inside those routines via a global variable - ! which we must store, set, and then replace on error or completion. - - IF ( InputFileData%EchoFlag ) THEN - - CALL OpenEcho ( UnitEcho, TRIM(EchoFileName), TmpErrStat, TmpErrMsg ) - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) THEN - CALL CleanUp() - RETURN - END IF - - REWIND(UnitInput) - - - ! The input file was already successfully read through up to this point, so we shouldn't have any read - ! errors in the first four lines. So, we won't worry about checking the error status here. - - CALL ReadCom( UnitInput, InputFileName, 'InflowWind input file header line 1', TmpErrStat, TmpErrMsg, UnitEcho ) - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - - CALL ReadCom( UnitInput, InputFileName, 'InflowWind input file header line 2', TmpErrStat, TmpErrMsg, UnitEcho ) - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - - CALL ReadCom( UnitInput, InputFileName, 'InflowWind input file separator line', TmpErrStat, TmpErrMsg, UnitEcho ) - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - - ! Echo Input Files. - - CALL ReadVar ( UnitInput, InputFileName, InputFileData%EchoFlag, 'Echo', 'Echo the input file data', TmpErrStat, TmpErrMsg, UnitEcho ) - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - - END IF - - - - !------------------------------------------------------------------------------------------------- - !> Read general section with wind type, direction, and output point list (applies to all wind types) - !------------------------------------------------------------------------------------------------- - - - ! Read WindType - CALL ReadVar( UnitInput, InputFileName, InputFileData%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)', & - TmpErrStat, TmpErrMsg, UnitEcho ) - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) THEN - CALL CleanUp() - RETURN - ENDIF - - - ! Read PropagationDir - CALL ReadVar( UnitInput, InputFileName, InputFileData%PropagationDir, 'PropagationDir', & - 'Direction of wind propagation (meteoroligical direction)', TmpErrStat, TmpErrMsg, UnitEcho ) - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) THEN - CALL CleanUp() - RETURN - ENDIF - - - ! Read the number of points for the wind velocity output - CALL ReadVar( UnitInput, InputFileName, InputFileData%NWindVel, 'NWindVel', & - 'Number of points to output the wind velocity (0 to 9)', & - TmpErrStat, TmpErrMsg, UnitEcho ) - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) THEN - CALL CleanUp() - RETURN - ENDIF + IF (ErrStat >= AbortErrLev) RETURN ! Before proceeding, make sure that NWindVel makes sense IF ( InputFileData%NWindVel < 0 .OR. InputFileData%NwindVel > 9 ) THEN CALL SetErrStat( ErrID_Fatal, 'NWindVel must be greater than or equal to zero and less than 10.', & ErrStat, ErrMsg, RoutineName ) - CALL CleanUp() RETURN ELSE @@ -316,553 +188,242 @@ SUBROUTINE InflowWind_ReadInput( InputFileName, EchoFileName, InputFileData, Err CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) CALL AllocAry( InputFileData%WindVziList, InputFileData%NWindVel, 'WindVziList', TmpErrStat, TmpErrMsg ) CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) THEN - CALL CleanUp() - RETURN - ENDIF + IF (ErrStat >= AbortErrLev) RETURN ENDIF - ! Read in the values of WindVxiList - CALL ReadAry( UnitInput, InputFileName, InputFileData%WindVxiList, InputFileData%NWindVel, 'WindVxiList', & - 'List of coordinates in the inertial X direction (m)', TmpErrStat, TmpErrMsg, UnitEcho ) - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) THEN - CALL CleanUp() - RETURN - ENDIF - - ! Read in the values of WindVxiList - CALL ReadAry( UnitInput, InputFileName, InputFileData%WindVyiList, InputFileData%NWindVel, 'WindVyiList', & - 'List of coordinates in the inertial Y direction (m)', TmpErrStat, TmpErrMsg, UnitEcho ) - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) THEN - CALL CleanUp() - RETURN - ENDIF + CALL ParseAry( InFileInfo, CurLine, 'WindVxiList', InputFileData%WindVxiList, InputFileData%NWindVel, TmpErrStat, TmpErrMsg ) + CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) + IF (ErrStat >= AbortErrLev) RETURN - ! Read in the values of WindVziList - CALL ReadAry( UnitInput, InputFileName, InputFileData%WindVziList, InputFileData%NWindVel, 'WindVziList', & - 'List of coordinates in the inertial Z direction (m)', TmpErrStat, TmpErrMsg, UnitEcho ) - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) THEN - CALL CleanUp() - RETURN - ENDIF + CALL ParseAry( InFileInfo, CurLine, 'WindVyiList', InputFileData%WindVyiList, InputFileData%NWindVel, TmpErrStat, TmpErrMsg ) + CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) + IF (ErrStat >= AbortErrLev) RETURN + CALL ParseAry( InFileInfo, CurLine, 'WindVziList', InputFileData%WindVziList, InputFileData%NWindVel, TmpErrStat, TmpErrMsg ) + CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) + IF (ErrStat >= AbortErrLev) RETURN !------------------------------------------------------------------------------------------------- !> Read the _Parameters for Steady Wind Conditions [used only for WindType = 1]_ section !------------------------------------------------------------------------------------------------- - ! Section separator line - CALL ReadCom( UnitInput, InputFileName, 'InflowWind input file separator line', TmpErrStat, TmpErrMsg, UnitEcho ) + CurLine = CurLine + 1 ! Skip section break + CALL ParseVar( InFileInfo, CurLine, "HWindSpeed", InputFileData%Steady_HWindSpeed, TmpErrStat, TmpErrMsg ) CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) THEN - CALL Cleanup() - RETURN - END IF - - - ! Read HWindSpeed - CALL ReadVar( UnitInput, InputFileName, InputFileData%Steady_HWindSpeed, 'HWindSpeed', & - 'Horizontal windspeed for steady wind', TmpErrStat, TmpErrMsg, UnitEcho ) - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) THEN - CALL CleanUp() - RETURN - ENDIF - - ! Read RefHt - CALL ReadVar( UnitInput, InputFileName, InputFileData%Steady_RefHt, 'RefHt', & - 'Reference height for horizontal wind speed for steady wind', TmpErrStat, TmpErrMsg, UnitEcho ) - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) THEN - CALL CleanUp() - RETURN - ENDIF + IF (ErrStat >= AbortErrLev) RETURN - ! Read PLexp - CALL ReadVar( UnitInput, InputFileName, InputFileData%Steady_PLexp, 'PLexp', & - 'Power law exponent for steady wind', TmpErrStat, TmpErrMsg, UnitEcho ) - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) THEN - CALL CleanUp() - RETURN - ENDIF + CALL ParseVar( InFileInfo, CurLine, "RefHt", InputFileData%Steady_RefHt, TmpErrStat, TmpErrMsg ) + CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) + IF (ErrStat >= AbortErrLev) RETURN + CALL ParseVar( InFileInfo, CurLine, "PLexp", InputFileData%Steady_PLexp, TmpErrStat, TmpErrMsg ) + CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) + IF (ErrStat >= AbortErrLev) RETURN !------------------------------------------------------------------------------------------------- !> Read the _Parameters for Uniform wind file [used only for WindType = 2]_ section !------------------------------------------------------------------------------------------------- - ! Section separator line - CALL ReadCom( UnitInput, InputFileName, 'InflowWind input file separator line', TmpErrStat, TmpErrMsg, UnitEcho ) + CurLine = CurLine + 1 ! Skip section break + CALL ParseVar( InFileInfo, CurLine, "UniformFileName", InputFileData%Uniform_FileName, TmpErrStat, TmpErrMsg ) CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) THEN - CALL Cleanup() - RETURN - END IF - - ! Read UniformWindFile - CALL ReadVar( UnitInput, InputFileName, InputFileData%Uniform_FileName, 'WindFileName', & - 'Filename of time series data for uniform wind field', TmpErrStat, TmpErrMsg, UnitEcho ) - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) THEN - CALL CleanUp() - RETURN - ENDIF + IF (ErrStat >= AbortErrLev) RETURN IF ( PathIsRelative( InputFileData%Uniform_FileName ) ) InputFileData%Uniform_FileName = TRIM(PriPath)//TRIM(InputFileData%Uniform_FileName) - ! Read RefHt - CALL ReadVar( UnitInput, InputFileName, InputFileData%Uniform_RefHt, 'RefHt', & - 'Reference height for uniform wind file', TmpErrStat, TmpErrMsg, UnitEcho ) - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) THEN - CALL CleanUp() - RETURN - ENDIF - - ! Read RefLength - CALL ReadVar( UnitInput, InputFileName, InputFileData%Uniform_RefLength, 'RefLength', & - 'Reference length for uniform wind file', TmpErrStat, TmpErrMsg, UnitEcho ) - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) THEN - CALL CleanUp() - RETURN - ENDIF + CALL ParseVar( InFileInfo, CurLine, "RefHt", InputFileData%Uniform_RefHt, TmpErrStat, TmpErrMsg ) + CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) + IF (ErrStat >= AbortErrLev) RETURN + CALL ParseVar( InFileInfo, CurLine, "RefLength", InputFileData%Uniform_RefLength, TmpErrStat, TmpErrMsg ) + CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) + IF (ErrStat >= AbortErrLev) RETURN !------------------------------------------------------------------------------------------------- !> Read the _Parameters for Binary TurbSim Full-Field files [used only for WindType = 3]_ section !------------------------------------------------------------------------------------------------- - ! Section separator line - CALL ReadCom( UnitInput, InputFileName, 'InflowWind input file separator line', TmpErrStat, TmpErrMsg, UnitEcho ) + CurLine = CurLine + 1 ! Skip section break + CALL ParseVar( InFileInfo, CurLine, "TurbSimFileName", InputFileData%TSFF_FileName, TmpErrStat, TmpErrMsg ) CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) THEN - CALL Cleanup() - RETURN - END IF - - ! Read TSFFWind info - CALL ReadVar( UnitInput, InputFileName, InputFileData%TSFF_FileName, 'FileName', & - 'Name of the TurbSim full field wind file to use (.bts)', TmpErrStat, TmpErrMsg, UnitEcho ) - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) THEN - CALL CleanUp() - RETURN - ENDIF + IF (ErrStat >= AbortErrLev) RETURN IF ( PathIsRelative( InputFileData%TSFF_FileName ) ) InputFileData%TSFF_FileName = TRIM(PriPath)//TRIM(InputFileData%TSFF_FileName) - !------------------------------------------------------------------------------------------------- !> Read the _Parameters for Binary Bladed-style Full-Field files [used only for WindType = 4]_ section !------------------------------------------------------------------------------------------------- - ! Section separator line - CALL ReadCom( UnitInput, InputFileName, 'InflowWind input file separator line', TmpErrStat, TmpErrMsg, UnitEcho ) + CurLine = CurLine + 1 ! Skip section break + CALL ParseVar( InFileInfo, CurLine, "FilenameRoot", InputFileData%BladedFF_FileName, TmpErrStat, TmpErrMsg ) CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) THEN - CALL Cleanup() - RETURN - END IF - - ! Read BladedStyle%WindFileName - CALL ReadVar( UnitInput, InputFileName, InputFileData%BladedFF_FileName, 'FileName', & - 'Rootname of the full-field wind file to use (.wnd, .sum)', TmpErrStat, TmpErrMsg, UnitEcho ) - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) THEN - CALL CleanUp() - RETURN - ENDIF + IF (ErrStat >= AbortErrLev) RETURN IF ( PathIsRelative( InputFileData%BladedFF_FileName ) ) InputFileData%BladedFF_FileName = TRIM(PriPath)//TRIM(InputFileData%BladedFF_FileName) InputFileData%BladedFF_FileName = TRIM(InputFileData%BladedFF_FileName)//'.wnd' - - ! Read TowerFileFlag - CALL ReadVar( UnitInput, InputFileName, InputFileData%BladedFF_TowerFile, 'TowerFileFlag', & - 'Have tower file (.twr) [flag]', TmpErrStat, TmpErrMsg, UnitEcho ) - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) THEN - CALL CleanUp() - RETURN - ENDIF -#ifdef UNUSED_INPUTFILE_LINES + CALL ParseVar( InFileInfo, CurLine, "TowerFile", InputFileData%BladedFF_TowerFile, TmpErrStat, TmpErrMsg ) + CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) + IF (ErrStat >= AbortErrLev) RETURN !------------------------------------------------------------------------------------------------- !> Read the _Parameters for coherent turbulence [used only for WindType = 3 or 4]_ section !------------------------------------------------------------------------------------------------- - ! Section separator line - CALL ReadCom( UnitInput, InputFileName, 'InflowWind input file separator line', TmpErrStat, TmpErrMsg, UnitEcho ) - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) THEN - CALL Cleanup() - RETURN - END IF + ! CurLine = CurLine + 1 ! Skip section break + ! CALL ParseVar( InFileInfo, CurLine, "CTTS_CoherentTurbFlag", InputFileData%CTTS_CoherentTurb, TmpErrStat, TmpErrMsg ) + ! CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) + ! IF (ErrStat >= AbortErrLev) RETURN - ! Read CTTS_Flag - CALL ReadVar( UnitInput, InputFileName, InputFileData%CTTS_CoherentTurb, 'CTTS_CoherentTurbFlag', & - 'Flag to coherent turbulence', TmpErrStat, TmpErrMsg, UnitEcho ) - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) THEN - CALL CleanUp() - RETURN - ENDIF + ! CALL ParseVar( InFileInfo, CurLine, "CTTS_FileName", InputFileData%CTTS_FileName, TmpErrStat, TmpErrMsg ) + ! CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) + ! IF (ErrStat >= AbortErrLev) RETURN + ! IF ( PathIsRelative( InputFileData%CTTS_FileName ) ) InputFileData%CTTS_FileName = TRIM(PriPath)//TRIM(InputFileData%CTTS_FileName) - ! Read CTWind%WindFileName - CALL ReadVar( UnitInput, InputFileName, InputFileData%CTTS_FileName, 'CTTS_FileName', & - 'Name of coherent turbulence file', TmpErrStat, TmpErrMsg, UnitEcho ) - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) THEN - CALL CleanUp() - RETURN - ENDIF - IF ( PathIsRelative( InputFileData%CTTS_FileName ) ) InputFileData%CTTS_FileName = TRIM(PriPath)//TRIM(InputFileData%CTTS_FileName) - - ! Read CTWind%PathName - CALL ReadVar( UnitInput, InputFileName, InputFileData%CTTS_Path, 'CTTS_Path', & - 'Path to coherent turbulence binary files', TmpErrStat, TmpErrMsg, UnitEcho ) - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) THEN - CALL CleanUp() - RETURN - ENDIF - IF ( PathIsRelative( InputFileData%CTTS_Path ) ) InputFileData%CTTS_Path = TRIM(PriPath)//TRIM(InputFileData%CTTS_Path) - -#else - InputFileData%CTTS_CoherentTurb = .FALSE. -#endif + ! CALL ParseVar( InFileInfo, CurLine, "CTTS_Path", InputFileData%CTTS_Path, TmpErrStat, TmpErrMsg ) + ! CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) + ! IF (ErrStat >= AbortErrLev) RETURN + ! IF ( PathIsRelative( InputFileData%CTTS_Path ) ) InputFileData%CTTS_Path = TRIM(PriPath)//TRIM(InputFileData%CTTS_Path) !------------------------------------------------------------------------------------------------- !> Read the _Parameters for HAWC-formatted binary files [used only for WindType = 5]_ section !------------------------------------------------------------------------------------------------- - ! Section separator line - CALL ReadCom( UnitInput, InputFileName, 'InflowWind input file separator line', TmpErrStat, TmpErrMsg, UnitEcho ) - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) THEN - CALL Cleanup() - RETURN - END IF - - ! Read HAWC_FileName_u - CALL ReadVar( UnitInput, InputFileName, InputFileData%HAWC_FileName_u, 'HAWC_FileName_u', & - 'Name of the file containing the u-component fluctuating wind', TmpErrStat, TmpErrMsg, UnitEcho ) + CurLine = CurLine + 1 ! Skip section break + CALL ParseVar( InFileInfo, CurLine, "FileName_u", InputFileData%HAWC_FileName_u, TmpErrStat, TmpErrMsg ) CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) THEN - CALL Cleanup() - RETURN - END IF + IF (ErrStat >= AbortErrLev) RETURN IF ( PathIsRelative( InputFileData%HAWC_FileName_u ) ) InputFileData%HAWC_FileName_u = TRIM(PriPath)//TRIM(InputFileData%HAWC_FileName_u) - ! Read HAWC_FileName_v - CALL ReadVar( UnitInput, InputFileName, InputFileData%HAWC_FileName_v, 'HAWC_FileName_v', & - 'Name of the file containing the v-component fluctuating wind', TmpErrStat, TmpErrMsg, UnitEcho ) + CALL ParseVar( InFileInfo, CurLine, "FileName_v", InputFileData%HAWC_FileName_v, TmpErrStat, TmpErrMsg ) CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) THEN - CALL Cleanup() - RETURN - END IF + IF (ErrStat >= AbortErrLev) RETURN IF ( PathIsRelative( InputFileData%HAWC_FileName_v ) ) InputFileData%HAWC_FileName_v = TRIM(PriPath)//TRIM(InputFileData%HAWC_FileName_v) - ! Read HAWC_FileName_w - CALL ReadVar( UnitInput, InputFileName, InputFileData%HAWC_FileName_w, 'HAWC_FileName_w', & - 'Name of the file containing the w-component fluctuating wind', TmpErrStat, TmpErrMsg, UnitEcho ) + CALL ParseVar( InFileInfo, CurLine, "FileName_w", InputFileData%HAWC_FileName_w, TmpErrStat, TmpErrMsg ) CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) THEN - CALL Cleanup() - RETURN - END IF + IF (ErrStat >= AbortErrLev) RETURN IF ( PathIsRelative( InputFileData%HAWC_FileName_w ) ) InputFileData%HAWC_FileName_w = TRIM(PriPath)//TRIM(InputFileData%HAWC_FileName_w) - ! Read HAWC_nx - CALL ReadVar( UnitInput, InputFileName, InputFileData%HAWC_nx, 'HAWC_nx', & - 'Number of grids in the x direction (in the 3 files above)', TmpErrStat, TmpErrMsg, UnitEcho ) - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) THEN - CALL Cleanup() - RETURN - END IF - - ! Read HAWC_ny - CALL ReadVar( UnitInput, InputFileName, InputFileData%HAWC_ny, 'HAWC_ny', & - 'Number of grids in the y direction (in the 3 files above)', TmpErrStat, TmpErrMsg, UnitEcho ) + CALL ParseVar( InFileInfo, CurLine, "nx", InputFileData%HAWC_nx, TmpErrStat, TmpErrMsg ) CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) THEN - CALL Cleanup() - RETURN - END IF - - ! Read HAWC_nz - CALL ReadVar( UnitInput, InputFileName, InputFileData%HAWC_nz, 'HAWC_nz', & - 'Number of grids in the z direction (in the 3 files above)', TmpErrStat, TmpErrMsg, UnitEcho ) - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) THEN - CALL Cleanup() - RETURN - END IF - - ! Read HAWC_dx - CALL ReadVar( UnitInput, InputFileName, InputFileData%HAWC_dx, 'HAWC_dx', & - 'Number of grids in the x direction (in the 3 files above)', TmpErrStat, TmpErrMsg, UnitEcho ) - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) THEN - CALL Cleanup() - RETURN - END IF + IF (ErrStat >= AbortErrLev) RETURN - ! Read HAWC_dy - CALL ReadVar( UnitInput, InputFileName, InputFileData%HAWC_dy, 'HAWC_dy', & - 'Number of grids in the y direction (in the 3 files above)', TmpErrStat, TmpErrMsg, UnitEcho ) + CALL ParseVar( InFileInfo, CurLine, "ny", InputFileData%HAWC_ny, TmpErrStat, TmpErrMsg ) CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) THEN - CALL Cleanup() - RETURN - END IF + IF (ErrStat >= AbortErrLev) RETURN - ! Read HAWC_dz - CALL ReadVar( UnitInput, InputFileName, InputFileData%HAWC_dz, 'HAWC_dz', & - 'Number of grids in the z direction (in the 3 files above)', TmpErrStat, TmpErrMsg, UnitEcho ) + CALL ParseVar( InFileInfo, CurLine, "nz", InputFileData%HAWC_nz, TmpErrStat, TmpErrMsg ) CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) THEN - CALL Cleanup() - RETURN - END IF + IF (ErrStat >= AbortErrLev) RETURN - ! Read HAWC_RefHt - CALL ReadVar( UnitInput, InputFileName, InputFileData%HAWC_RefHt, 'HAWC_RefHt', & - 'Reference (hub) height of the grid', TmpErrStat, TmpErrMsg, UnitEcho ) + CALL ParseVar( InFileInfo, CurLine, "dx", InputFileData%HAWC_dx, TmpErrStat, TmpErrMsg ) CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) THEN - CALL Cleanup() - RETURN - END IF - - - - !---------------------------------------------------------------------------------------------- - !> Read the _Scaling parameters for turbulence (HAWC-format files) [used only for WindType = 5]_ subsection - !---------------------------------------------------------------------------------------------- + IF (ErrStat >= AbortErrLev) RETURN - ! Section separator line - CALL ReadCom( UnitInput, InputFileName, 'InflowWind input file separator line', TmpErrStat, TmpErrMsg, UnitEcho ) - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) THEN - CALL Cleanup() - RETURN - END IF + CALL ParseVar( InFileInfo, CurLine, "dy", InputFileData%HAWC_dy, TmpErrStat, TmpErrMsg ) + IF (ErrStat >= AbortErrLev) RETURN - ! Read HAWC_ScaleMethod - CALL ReadVar( UnitInput, InputFileName, InputFileData%HAWC_ScaleMethod, 'HAWC_ScaleMethod', & - 'Turbulence scaling method [0=none, 1=direct scaling, 2= calculate scaling '// & - 'factor based on a desired standard deviation]', TmpErrStat, TmpErrMsg, UnitEcho ) + CALL ParseVar( InFileInfo, CurLine, "dz", InputFileData%HAWC_dz, TmpErrStat, TmpErrMsg ) CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) THEN - CALL Cleanup() - RETURN - END IF + IF (ErrStat >= AbortErrLev) RETURN - ! Read HAWC_SFx - CALL ReadVar( UnitInput, InputFileName, InputFileData%HAWC_SFx, 'HAWC_SFx', & - 'Turbulence scaling factor for the x direction [ScaleMethod=1]', TmpErrStat, TmpErrMsg, UnitEcho ) + CALL ParseVar( InFileInfo, CurLine, "RefHt", InputFileData%HAWC_RefHt, TmpErrStat, TmpErrMsg ) CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) THEN - CALL Cleanup() - RETURN - END IF + IF (ErrStat >= AbortErrLev) RETURN - ! Read HAWC_SFy - CALL ReadVar( UnitInput, InputFileName, InputFileData%HAWC_SFy, 'HAWC_SFy', & - 'Turbulence scaling factor for the y direction [ScaleMethod=1]', TmpErrStat, TmpErrMsg, UnitEcho ) - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) THEN - CALL Cleanup() - RETURN - END IF + !---------------------------------------------------------------------------------------------- + !> Read the _Scaling parameters for turbulence (HAWC-format files) [used only for WindType = 5]_ subsection + !---------------------------------------------------------------------------------------------- - ! Read HAWC_SFz - CALL ReadVar( UnitInput, InputFileName, InputFileData%HAWC_SFz, 'HAWC_SFz', & - 'Turbulence scaling factor for the z direction [ScaleMethod=1]', TmpErrStat, TmpErrMsg, UnitEcho ) + CurLine = CurLine + 1 ! Skip section break + CALL ParseVar( InFileInfo, CurLine, "ScaleMethod", InputFileData%HAWC_ScaleMethod, TmpErrStat, TmpErrMsg ) CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) THEN - CALL Cleanup() - RETURN - END IF + IF (ErrStat >= AbortErrLev) RETURN - ! Read HAWC_SigmaFx - CALL ReadVar( UnitInput, InputFileName, InputFileData%HAWC_SigmaFx, 'HAWC_SigmaFx', & - 'Turbulence standard deviation to calculate scaling from in x direction [ScaleMethod=2]', TmpErrStat, TmpErrMsg, UnitEcho ) + CALL ParseVar( InFileInfo, CurLine, "SFx", InputFileData%HAWC_SFx, TmpErrStat, TmpErrMsg ) CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) THEN - CALL Cleanup() - RETURN - END IF + IF (ErrStat >= AbortErrLev) RETURN - ! Read HAWC_SigmaFy - CALL ReadVar( UnitInput, InputFileName, InputFileData%HAWC_SigmaFy, 'HAWC_SigmaFy', & - 'Turbulence standard deviation to calculate scaling from in y direction [ScaleMethod=2]', TmpErrStat, TmpErrMsg, UnitEcho ) + CALL ParseVar( InFileInfo, CurLine, "SFy", InputFileData%HAWC_SFy, TmpErrStat, TmpErrMsg ) CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) THEN - CALL Cleanup() - RETURN - END IF + IF (ErrStat >= AbortErrLev) RETURN - ! Read HAWC_SigmaFz - CALL ReadVar( UnitInput, InputFileName, InputFileData%HAWC_SigmaFz, 'HAWC_SigmaFz', & - 'Turbulence standard deviation to calculate scaling from in z direction [ScaleMethod=2]', TmpErrStat, TmpErrMsg, UnitEcho ) + CALL ParseVar( InFileInfo, CurLine, "SFz", InputFileData%HAWC_SFz, TmpErrStat, TmpErrMsg ) CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) THEN - CALL Cleanup() - RETURN - END IF - -#ifdef UNUSED_INPUTFILE_LINES + IF (ErrStat >= AbortErrLev) RETURN -!FIXME: TStart has no comment - ! Read HAWC_TStart - CALL ReadVar( UnitInput, InputFileName, InputFileData%HAWC_TStart, 'HAWC_TStart', & - '', TmpErrStat, TmpErrMsg, UnitEcho ) + CALL ParseVar( InFileInfo, CurLine, "SigmaFx", InputFileData%HAWC_SigmaFx, TmpErrStat, TmpErrMsg ) CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) THEN - CALL Cleanup() - RETURN - END IF + IF (ErrStat >= AbortErrLev) RETURN -!FIXME: TEnd has no comment - ! Read HAWC_TEnd - CALL ReadVar( UnitInput, InputFileName, InputFileData%HAWC_TEnd, 'HAWC_TEnd', & - '', TmpErrStat, TmpErrMsg, UnitEcho ) + CALL ParseVar( InFileInfo, CurLine, "SigmaFy", InputFileData%HAWC_SigmaFy, TmpErrStat, TmpErrMsg ) CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) THEN - CALL Cleanup() - RETURN - END IF - -#endif - - !---------------------------------------------------------------------------------------------- - !> Read the _Mean wind profile paramters (added to HAWC-format files) [used only for WindType = 5]_ subsection - !---------------------------------------------------------------------------------------------- + IF (ErrStat >= AbortErrLev) RETURN - ! Section separator line - CALL ReadCom( UnitInput, InputFileName, 'InflowWind input file separator line', TmpErrStat, TmpErrMsg, UnitEcho ) + CALL ParseVar( InFileInfo, CurLine, "SigmaFz", InputFileData%HAWC_SigmaFz, TmpErrStat, TmpErrMsg ) CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) THEN - CALL Cleanup() - RETURN - END IF + IF (ErrStat >= AbortErrLev) RETURN - ! Read HAWC_URef - CALL ReadVar( UnitInput, InputFileName, InputFileData%HAWC_URef, 'HAWC_URef', & - 'Mean u-component wind speed at the reference height', TmpErrStat, TmpErrMsg, UnitEcho ) + ! FIXME: TStart has no comment + ! CALL ParseVar( InFileInfo, CurLine, "HAWC_TStart", InputFileData%HAWC_TStart, TmpErrStat, TmpErrMsg ) + ! CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) + ! IF (ErrStat >= AbortErrLev) THEN + ! RETURN + ! ENDIF + + ! FIXME: TEnd has no comment + ! CALL ParseVar( InFileInfo, CurLine, "HAWC_TEnd", InputFileData%HAWC_TEnd, TmpErrStat, TmpErrMsg ) + ! CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) + ! IF (ErrStat >= AbortErrLev) THEN + ! RETURN + ! ENDIF + + !---------------------------------------------------------------------------------------------- + !> Read the _Mean wind profile paramters (added to HAWC-format files) [used only for WindType = 5]_ subsection + !---------------------------------------------------------------------------------------------- + + CurLine = CurLine + 1 ! Skip section break + CALL ParseVar( InFileInfo, CurLine, "URef", InputFileData%HAWC_URef, TmpErrStat, TmpErrMsg ) CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) THEN - CALL Cleanup() - RETURN - END IF + IF (ErrStat >= AbortErrLev) RETURN - ! Read HAWC_ProfileType - CALL ReadVar( UnitInput, InputFileName, InputFileData%HAWC_ProfileType, 'HAWC_ProfileType', & - 'Wind profile type (0=constant;1=logarithmic;2=power law)', TmpErrStat, TmpErrMsg, UnitEcho ) + CALL ParseVar( InFileInfo, CurLine, "WindProfile", InputFileData%HAWC_ProfileType, TmpErrStat, TmpErrMsg ) CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) THEN - CALL Cleanup() - RETURN - END IF + IF (ErrStat >= AbortErrLev) RETURN - ! Read HAWC_PLExp - CALL ReadVar( UnitInput, InputFileName, InputFileData%HAWC_PLExp, 'HAWC_PLExp', & - 'Power law exponent (used for PL wind profile type only)', TmpErrStat, TmpErrMsg, UnitEcho ) + CALL ParseVar( InFileInfo, CurLine, "PLExp", InputFileData%HAWC_PLExp, TmpErrStat, TmpErrMsg ) CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) THEN - CALL Cleanup() - RETURN - END IF + IF (ErrStat >= AbortErrLev) RETURN - ! Read HAWC_Z0 - CALL ReadVar( UnitInput, InputFileName, InputFileData%HAWC_Z0, 'HAWC_Z0', & - 'Surface roughness length (used for LOG wind profile type only)', TmpErrStat, TmpErrMsg, UnitEcho ) + CALL ParseVar( InFileInfo, CurLine, "Z0", InputFileData%HAWC_Z0, TmpErrStat, TmpErrMsg ) CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) THEN - CALL Cleanup() - RETURN - END IF + IF (ErrStat >= AbortErrLev) RETURN - ! Read HAWC_InitPosition (Shift of wind box) NOTE: This an optional input!!!! InputFileData%HAWC_InitPosition(2:3) = 0.0_ReKi ! We are only using X, so only read in one. The data can handle 3 coords - CALL ReadVar( UnitInput, InputFileName, InputFileData%HAWC_InitPosition(1), 'HAWC_Position', & - 'Initial position of the HAWC wind file (shift along X usually)', TmpErrStat, TmpErrMsg, UnitEcho ) - if (TmpErrStat == ErrID_None) then - !---------------------- OUTPUT -------------------------------------------------- - CALL ReadCom( UnitInput, InputFileName, 'Section Header: Output', TmpErrStat, TmpErrMsg, UnitEcho ) - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) THEN - CALL Cleanup() - RETURN - END IF - else - InputFileData%HAWC_InitPosition = 0.0_ReKi - TmpErrStat = ErrID_None ! reset - TmpErrMsg = "" - ! NOTE: since we read in a line that wasn't a number, what we actually read was the header. - endif - - ! SumPrint - Print summary data to .IfW.sum (flag): - CALL ReadVar( UnitInput, InputFileName, InputFileData%SumPrint, "SumPrint", "Print summary data to .IfW.sum (flag)", TmpErrStat, TmpErrMsg, UnitEcho) + CALL ParseVar( InFileInfo, CurLine, "InitPosition(x)", InputFileData%HAWC_InitPosition(1), TmpErrStat, TmpErrMsg ) CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) THEN - CALL Cleanup() - RETURN - END IF - + IF (ErrStat >= AbortErrLev) RETURN - !---------------------- OUTLIST -------------------------------------------- - CALL ReadCom( UnitInput, InputFileName, 'Section Header: OutList', TmpErrStat, TmpErrMsg, UnitEcho ) + !---------------------------------------------------------------------------------------------- + !> Read the _OUTPUT_ subsection + !---------------------------------------------------------------------------------------------- + CurLine = CurLine + 1 ! Skip section break + CALL ParseVar( InFileInfo, CurLine, "SumPrint", InputFileData%SumPrint, TmpErrStat, TmpErrMsg ) CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) THEN - CALL Cleanup() - RETURN - END IF + IF (ErrStat >= AbortErrLev) RETURN - ! OutList - List of user-requested output channels (-): -- uses routine from the NWTC_Library - CALL ReadOutputList ( UnitInput, InputFileName, InputFileData%OutList, InputFileData%NumOuts, 'OutList', & - "List of user-requested output channels", TmpErrStat, TmpErrMsg, UnitEcho ) + !---------------------- OUTLIST -------------------------------------------- + CurLine = CurLine + 1 ! Skip comment line + CALL ReadOutputListFromFileInfo( InFileInfo, CurLine, InputFileData%OutList, & + InputFileData%NumOuts, "OutList", "List of user-requested output channels", TmpErrStat, TmpErrMsg ) CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) THEN - CALL Cleanup() - RETURN - END IF - - - + IF (ErrStat >= AbortErrLev) RETURN !------------------------------------------------------------------------------------------------- ! This is the end of the input file !------------------------------------------------------------------------------------------------- - CALL Cleanup() - RETURN - CONTAINS - !.............................. - SUBROUTINE Cleanup() - - - ! Close input file - CLOSE ( UnitInput ) - - ! Cleanup the Echo file and global variables - IF ( InputFileData%EchoFlag ) THEN - CLOSE(UnitEcho) - END IF - - - END SUBROUTINE Cleanup - -END SUBROUTINE InflowWind_ReadInput - + END SUBROUTINE InflowWind_ParseInputFileInfo !==================================================================================================== !> This private subroutine verifies the input required for InflowWind is correctly specified. This @@ -962,7 +523,8 @@ SUBROUTINE InflowWind_ValidateInput( InitInp, InputFileData, ErrStat, ErrMsg ) CALL Steady_ValidateInput() CASE ( Uniform_WindNumber ) - CALL Uniform_ValidateInput() + + IF ( InitInp%WindType2UseInputFile ) CALL Uniform_ValidateInput() CASE ( TSFF_WindNumber ) CALL TSFF_ValidateInput() diff --git a/modules/inflowwind/src/InflowWind_Types.f90 b/modules/inflowwind/src/InflowWind_Types.f90 index d8f2890b35..07246808a6 100644 --- a/modules/inflowwind/src/InflowWind_Types.f90 +++ b/modules/inflowwind/src/InflowWind_Types.f90 @@ -89,7 +89,7 @@ MODULE InflowWind_Types CHARACTER(1024) :: TSFF_FileName !< TurbSim Full-Field -- filename [-] CHARACTER(1024) :: BladedFF_FileName !< Bladed-style Full-Field -- filename [-] LOGICAL :: BladedFF_TowerFile !< Bladed-style Full-Field -- tower file exists [-] - LOGICAL :: CTTS_CoherentTurb !< Coherent turbulence data exists [-] + LOGICAL :: CTTS_CoherentTurb = .FALSE. !< Coherent turbulence data exists [-] CHARACTER(1024) :: CTTS_FileName !< Name of coherent turbulence file [-] CHARACTER(1024) :: CTTS_Path !< Path to coherent turbulence binary data files [-] CHARACTER(1024) :: HAWC_FileName_u !< HAWC -- u component binary data file name [-] @@ -133,7 +133,9 @@ MODULE InflowWind_Types INTEGER(IntKi) :: NumWindPoints !< Number of wind velocity points expected [-] LOGICAL :: UseInputFile = .TRUE. !< Should we read everthing from an input file, or do we get it some other way [-] CHARACTER(1024) :: RootName !< RootName for writing output files [-] - TYPE(InflowWind_InputFile) :: PassedFileData !< If we don't use the input file, pass everything through this [-] + TYPE(FileInfoType) :: PassedFileData !< If we don't use the input file, pass everything through this [-] + LOGICAL :: WindType2UseInputFile = .TRUE. !< Flag for toggling file based IO in wind type 2. [-] + TYPE(FileInfoType) :: WindType2Data !< Optional slot for wind type 2 data if file IO is not used. [-] TYPE(Lidar_InitInputType) :: lidar !< InitInput for lidar data [-] TYPE(IfW_4Dext_InitInputType) :: FDext !< InitInput for lidar data [-] END TYPE InflowWind_InitInputType @@ -1160,7 +1162,11 @@ SUBROUTINE InflowWind_CopyInitInput( SrcInitInputData, DstInitInputData, CtrlCod DstInitInputData%NumWindPoints = SrcInitInputData%NumWindPoints DstInitInputData%UseInputFile = SrcInitInputData%UseInputFile DstInitInputData%RootName = SrcInitInputData%RootName - CALL InflowWind_Copyinputfile( SrcInitInputData%PassedFileData, DstInitInputData%PassedFileData, CtrlCode, ErrStat2, ErrMsg2 ) + CALL NWTC_Library_Copyfileinfotype( SrcInitInputData%PassedFileData, DstInitInputData%PassedFileData, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + DstInitInputData%WindType2UseInputFile = SrcInitInputData%WindType2UseInputFile + CALL NWTC_Library_Copyfileinfotype( SrcInitInputData%WindType2Data, DstInitInputData%WindType2Data, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN CALL Lidar_CopyInitInput( SrcInitInputData%lidar, DstInitInputData%lidar, CtrlCode, ErrStat2, ErrMsg2 ) @@ -1180,7 +1186,8 @@ SUBROUTINE InflowWind_DestroyInitInput( InitInputData, ErrStat, ErrMsg ) ! ErrStat = ErrID_None ErrMsg = "" - CALL InflowWind_Destroyinputfile( InitInputData%PassedFileData, ErrStat, ErrMsg ) + CALL NWTC_Library_Destroyfileinfotype( InitInputData%PassedFileData, ErrStat, ErrMsg ) + CALL NWTC_Library_Destroyfileinfotype( InitInputData%WindType2Data, ErrStat, ErrMsg ) CALL Lidar_DestroyInitInput( InitInputData%lidar, ErrStat, ErrMsg ) CALL IfW_4Dext_DestroyInitInput( InitInputData%FDext, ErrStat, ErrMsg ) END SUBROUTINE InflowWind_DestroyInitInput @@ -1228,7 +1235,7 @@ SUBROUTINE InflowWind_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat Int_BufSz = Int_BufSz + 1*LEN(InData%RootName) ! RootName ! Allocate buffers for subtypes, if any (we'll get sizes from these) Int_BufSz = Int_BufSz + 3 ! PassedFileData: size of buffers for each call to pack subtype - CALL InflowWind_Packinputfile( Re_Buf, Db_Buf, Int_Buf, InData%PassedFileData, ErrStat2, ErrMsg2, .TRUE. ) ! PassedFileData + CALL NWTC_Library_Packfileinfotype( Re_Buf, Db_Buf, Int_Buf, InData%PassedFileData, ErrStat2, ErrMsg2, .TRUE. ) ! PassedFileData CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -1244,6 +1251,24 @@ SUBROUTINE InflowWind_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF + Int_BufSz = Int_BufSz + 1 ! WindType2UseInputFile + Int_BufSz = Int_BufSz + 3 ! WindType2Data: size of buffers for each call to pack subtype + CALL NWTC_Library_Packfileinfotype( Re_Buf, Db_Buf, Int_Buf, InData%WindType2Data, ErrStat2, ErrMsg2, .TRUE. ) ! WindType2Data + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! WindType2Data + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! WindType2Data + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! WindType2Data + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF Int_BufSz = Int_BufSz + 3 ! lidar: size of buffers for each call to pack subtype CALL Lidar_PackInitInput( Re_Buf, Db_Buf, Int_Buf, InData%lidar, ErrStat2, ErrMsg2, .TRUE. ) ! lidar CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) @@ -1321,7 +1346,37 @@ SUBROUTINE InflowWind_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat IntKiBuf(Int_Xferred) = ICHAR(InData%RootName(I:I), IntKi) Int_Xferred = Int_Xferred + 1 END DO ! I - CALL InflowWind_Packinputfile( Re_Buf, Db_Buf, Int_Buf, InData%PassedFileData, ErrStat2, ErrMsg2, OnlySize ) ! PassedFileData + CALL NWTC_Library_Packfileinfotype( Re_Buf, Db_Buf, Int_Buf, InData%PassedFileData, ErrStat2, ErrMsg2, OnlySize ) ! PassedFileData + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf + Re_Xferred = Re_Xferred + SIZE(Re_Buf) + DEALLOCATE(Re_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Db_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf + Db_Xferred = Db_Xferred + SIZE(Db_Buf) + DEALLOCATE(Db_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Int_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf + Int_Xferred = Int_Xferred + SIZE(Int_Buf) + DEALLOCATE(Int_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IntKiBuf(Int_Xferred) = TRANSFER(InData%WindType2UseInputFile, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 + CALL NWTC_Library_Packfileinfotype( Re_Buf, Db_Buf, Int_Buf, InData%WindType2Data, ErrStat2, ErrMsg2, OnlySize ) ! WindType2Data CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -1482,7 +1537,49 @@ SUBROUTINE InflowWind_UnPackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrS Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL InflowWind_Unpackinputfile( Re_Buf, Db_Buf, Int_Buf, OutData%PassedFileData, ErrStat2, ErrMsg2 ) ! PassedFileData + CALL NWTC_Library_Unpackfileinfotype( Re_Buf, Db_Buf, Int_Buf, OutData%PassedFileData, ErrStat2, ErrMsg2 ) ! PassedFileData + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) + IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) + IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + OutData%WindType2UseInputFile = TRANSFER(IntKiBuf(Int_Xferred), OutData%WindType2UseInputFile) + Int_Xferred = Int_Xferred + 1 + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) + Re_Xferred = Re_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) + Db_Xferred = Db_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) + Int_Xferred = Int_Xferred + Buf_size + END IF + CALL NWTC_Library_Unpackfileinfotype( Re_Buf, Db_Buf, Int_Buf, OutData%WindType2Data, ErrStat2, ErrMsg2 ) ! WindType2Data CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN diff --git a/modules/inflowwind/tests/ifw_test_tools.F90 b/modules/inflowwind/tests/ifw_test_tools.F90 new file mode 100644 index 0000000000..c4e1fd6abd --- /dev/null +++ b/modules/inflowwind/tests/ifw_test_tools.F90 @@ -0,0 +1,143 @@ +module ifw_test_tools + + use NWTC_IO + use NWTC_Library + use NWTC_Library_Types + + implicit none + +contains + + function getInputFileData() + + INTEGER :: ErrStat + CHARACTER(ErrMsgLen) :: ErrMsg + TYPE(FileInfoType) :: getInputFileData + CHARACTER(1024), DIMENSION(54) :: data = (/ & + '------- InflowWind v3.01.* INPUT FILE ------------------------------------------------------------------------- ', & + 'Steady 8 m/s winds with no shear for FAST CertTests #20 and #25 ', & + '--------------------------------------------------------------------------------------------------------------- ', & + ' true 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) ', & + ' 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) ', & + ' 90 WindVziList - List of coordinates in the inertial Z direction (m) ', & + '================== Parameters for Steady Wind Conditions [used only for WindType = 1] ========================= ', & + ' 8.0 HWindSpeed - Horizontal windspeed (m/s) ', & + ' 90 RefHt - Reference height for horizontal wind speed (m) ', & + ' 0.1 PLexp - Power law exponent (-) ', & + '================== Parameters for Uniform wind file [used only for WindType = 2] ============================ ', & + '"Wind/08ms.wnd" UniformFileName - Filename of time series data for uniform wind field. (-) ', & + ' 90 RefHt - 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/08ms.wnd" TurbSimFileName - 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) ', & + '================== Parameters for HAWC-format binary files [Only used with WindType = 5] ===================== ', & + '"wasp\Output\basic_5u.bin" FileName_u - name of the file containing the u-component fluctuating wind (.bin) ', & + '"wasp\Output\basic_5v.bin" FileName_v - name of the file containing the v-component fluctuating wind (.bin) ', & + '"wasp\Output\basic_5w.bin" FileName_w - name of the file containing the w-component fluctuating wind (.bin) ', & + ' 64 nx - number of grids in the x direction (in the 3 files above) (-) ', & + ' 32 ny - number of grids in the y direction (in the 3 files above) (-) ', & + ' 32 nz - number of grids in the z direction (in the 3 files above) (-) ', & + ' 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) ', & + ' ------------- 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] ', & + ' 1 SFy - Turbulence scaling factor for the y direction (-) [ScaleMethod=1] ', & + ' 1 SFz - Turbulence scaling factor for the z direction (-) [ScaleMethod=1] ', & + ' 12 SigmaFx - Turbulence standard deviation to calculate scaling from in x direction (m/s) [ScaleMethod=2] ', & + ' 8 SigmaFy - Turbulence standard deviation to calculate scaling from in y direction (m/s) [ScaleMethod=2] ', & + ' 2 SigmaFz - Turbulence standard deviation to calculate scaling from in z direction (m/s) [ScaleMethod=2] ', & + ' ------------- 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.03 Z0 - Surface roughness length (m) (used for LG wind profile type only) ', & + ' 0 InitPosition(x) - 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,Wind1VelY,Wind1VelZ" - Wind velocity at point WindVxiList(1),WindVyiList(1),WindVziList(1). X, Y, and Z direction components. ', & + 'END of input file (the word "END" must appear in the first 3 columns of this last OutList line) ', & + '--------------------------------------------------------------------------------------- ' & + /) + + CALL InitFileInfo(data, getInputFileData, ErrStat, ErrMsg) + + end function + + function getInputFileDataWindType2() + + INTEGER :: ErrStat + CHARACTER(ErrMsgLen) :: ErrMsg + TYPE(FileInfoType) :: getInputFileDataWindType2 + CHARACTER(1024), DIMENSION(54) :: data = (/ & + '------- InflowWind v3.01.* INPUT FILE ------------------------------------------------------------------------- ', & + 'Steady 8 m/s winds with no shear for FAST CertTests #20 and #25 ', & + '--------------------------------------------------------------------------------------------------------------- ', & + ' true Echo - Echo input data to .ech (flag) ', & + ' 2 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) ', & + ' 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) ', & + ' 90 WindVziList - List of coordinates in the inertial Z direction (m) ', & + '================== Parameters for Steady Wind Conditions [used only for WindType = 1] ========================= ', & + ' 8.0 HWindSpeed - Horizontal windspeed (m/s) ', & + ' 90 RefHt - Reference height for horizontal wind speed (m) ', & + ' 0.1 PLexp - Power law exponent (-) ', & + '================== Parameters for Uniform wind file [used only for WindType = 2] ============================ ', & + '"Wind/08ms.wnd" UniformFileName - Filename of time series data for uniform wind field. (-) ', & + ' 90 RefHt - 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/08ms.wnd" TurbSimFileName - 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) ', & + '================== Parameters for HAWC-format binary files [Only used with WindType = 5] ===================== ', & + '"wasp\Output\basic_5u.bin" FileName_u - name of the file containing the u-component fluctuating wind (.bin) ', & + '"wasp\Output\basic_5v.bin" FileName_v - name of the file containing the v-component fluctuating wind (.bin) ', & + '"wasp\Output\basic_5w.bin" FileName_w - name of the file containing the w-component fluctuating wind (.bin) ', & + ' 64 nx - number of grids in the x direction (in the 3 files above) (-) ', & + ' 32 ny - number of grids in the y direction (in the 3 files above) (-) ', & + ' 32 nz - number of grids in the z direction (in the 3 files above) (-) ', & + ' 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) ', & + ' ------------- 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] ', & + ' 1 SFy - Turbulence scaling factor for the y direction (-) [ScaleMethod=1] ', & + ' 1 SFz - Turbulence scaling factor for the z direction (-) [ScaleMethod=1] ', & + ' 12 SigmaFx - Turbulence standard deviation to calculate scaling from in x direction (m/s) [ScaleMethod=2] ', & + ' 8 SigmaFy - Turbulence standard deviation to calculate scaling from in y direction (m/s) [ScaleMethod=2] ', & + ' 2 SigmaFz - Turbulence standard deviation to calculate scaling from in z direction (m/s) [ScaleMethod=2] ', & + ' ------------- 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.03 Z0 - Surface roughness length (m) (used for LG wind profile type only) ', & + ' 0 InitPosition(x) - 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,Wind1VelY,Wind1VelZ" - Wind velocity at point WindVxiList(1),WindVyiList(1),WindVziList(1). X, Y, and Z direction components. ', & + 'END of input file (the word "END" must appear in the first 3 columns of this last OutList line) ', & + '--------------------------------------------------------------------------------------- ' & + /) + + CALL InitFileInfo(data, getInputFileDataWindType2, ErrStat, ErrMsg) + + end function + +end module \ No newline at end of file diff --git a/modules/inflowwind/tests/test_bladed_wind.F90 b/modules/inflowwind/tests/test_bladed_wind.F90 new file mode 100644 index 0000000000..819c7bb16b --- /dev/null +++ b/modules/inflowwind/tests/test_bladed_wind.F90 @@ -0,0 +1,35 @@ +module test_bladed_wind + + use pFUnit_mod + use ifw_test_tools + use InflowWind_Subs + use InflowWind_Types + + implicit none + +contains + + @test + subroutine test_bladed_wind_input() + + TYPE(FileInfoType) :: InFileInfo + TYPE(InflowWind_InputFile) :: InputFileData + CHARACTER(1024) :: PriPath + INTEGER(IntKi) :: TmpErrStat + CHARACTER(ErrMsgLen) :: TmpErrMsg + + CHARACTER(16) :: expected + + expected = "unused.wnd" + PriPath = "" + + InFileInfo = getInputFileData() + CALL InflowWind_ParseInputFileInfo(InputFileData , InFileInfo, PriPath, TmpErrStat, TmpErrMsg) + + @assertEqual(TmpErrStat, 0) + @assertEqual(InputFileData%BladedFF_FileName, trim(expected)) + @assertEqual(InputFileData%BladedFF_TowerFile, .FALSE.) + + end subroutine + +end module diff --git a/modules/inflowwind/tests/test_hawc_wind.F90 b/modules/inflowwind/tests/test_hawc_wind.F90 new file mode 100644 index 0000000000..bcfb4ab5a5 --- /dev/null +++ b/modules/inflowwind/tests/test_hawc_wind.F90 @@ -0,0 +1,64 @@ +module test_hawc_wind + + use pFUnit_mod + use ifw_test_tools + use InflowWind_Subs + use InflowWind_Types + + implicit none + +contains + + @test + subroutine test_hawc_wind_input() + + TYPE(FileInfoType) :: InFileInfo + TYPE(InflowWind_InputFile) :: InputFileData + CHARACTER(1024) :: PriPath + INTEGER(IntKi) :: TmpErrStat + CHARACTER(ErrMsgLen) :: TmpErrMsg + + CHARACTER(32) :: expected_fnu + CHARACTER(32) :: expected_fnv + CHARACTER(32) :: expected_fnw + + PriPath = "" + expected_fnu = "wasp\Output\basic_5u.bin" + expected_fnv = "wasp\Output\basic_5v.bin" + expected_fnw = "wasp\Output\basic_5w.bin" + + InFileInfo = getInputFileData() + CALL InflowWind_ParseInputFileInfo(InputFileData , InFileInfo, PriPath, TmpErrStat, TmpErrMsg) + + @assertEqual(TmpErrStat, 0) + + @assertEqual(InputFileData%HAWC_FileName_u, trim(expected_fnu)) + @assertEqual(InputFileData%HAWC_FileName_v, trim(expected_fnv)) + @assertEqual(InputFileData%HAWC_FileName_w, trim(expected_fnw)) + @assertEqual(InputFileData%HAWC_nx, 64) + @assertEqual(InputFileData%HAWC_ny, 32) + @assertEqual(InputFileData%HAWC_nz, 32) + @assertEqual(InputFileData%HAWC_dx, 16) + @assertEqual(InputFileData%HAWC_dy, 3) + @assertEqual(InputFileData%HAWC_dz, 3) + @assertEqual(InputFileData%HAWC_RefHt, 90) + + @assertEqual(InputFileData%HAWC_ScaleMethod, 1) + @assertEqual(InputFileData%HAWC_SFx, 1) + @assertEqual(InputFileData%HAWC_SFy, 1) + @assertEqual(InputFileData%HAWC_SFz, 1) + @assertEqual(InputFileData%HAWC_SigmaFx, 12) + @assertEqual(InputFileData%HAWC_SigmaFy, 8) + @assertEqual(InputFileData%HAWC_SigmaFz, 2) + + @assertEqual(InputFileData%HAWC_URef, 5) + @assertEqual(InputFileData%HAWC_ProfileType, 2) + @assertEqual(InputFileData%HAWC_PLExp, 0) + @assertEqual(InputFileData%HAWC_Z0, 0.03) + @assertEqual(InputFileData%HAWC_InitPosition(1), 0) + @assertEqual(InputFileData%HAWC_InitPosition(2), 0) + @assertEqual(InputFileData%HAWC_InitPosition(3), 0) + + end subroutine + +end module diff --git a/modules/inflowwind/tests/test_outputs.F90 b/modules/inflowwind/tests/test_outputs.F90 new file mode 100644 index 0000000000..83f0962986 --- /dev/null +++ b/modules/inflowwind/tests/test_outputs.F90 @@ -0,0 +1,62 @@ +module test_outputs + + use pFUnit_mod + use ifw_test_tools + use InflowWind_Subs + use InflowWind_Types + + implicit none + +contains + + @test + subroutine test_outputs_parsing() + + TYPE(FileInfoType) :: InFileInfo + TYPE(InflowWind_InputFile) :: InputFileData + CHARACTER(1024) :: PriPath + INTEGER(IntKi) :: TmpErrStat + CHARACTER(ErrMsgLen) :: TmpErrMsg + + PriPath = "" + + InFileInfo = getInputFileData() + CALL InflowWind_ParseInputFileInfo(InputFileData , InFileInfo, PriPath, TmpErrStat, TmpErrMsg) + + @assertEqual(TmpErrStat, 0) + @assertEqual(InputFileData%SumPrint, .FALSE.) + @assertEqual(InputFileData%OutList(1), "Wind1VelX") + @assertEqual(InputFileData%OutList(2), "Wind1VelY") + @assertEqual(InputFileData%OutList(3), "Wind1VelZ") + + end subroutine + + + @test + subroutine test_outputs_parsing_alternate() + + TYPE(FileInfoType) :: InFileInfo + TYPE(InflowWind_InputFile) :: InputFileData + CHARACTER(1024) :: PriPath + INTEGER(IntKi) :: TmpErrStat + CHARACTER(ErrMsgLen) :: TmpErrMsg + + PriPath = "" + + InFileInfo = getInputFileData() + InFileInfo%Lines(50:52) = (/ & + 'True 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,Wind1VelY" - Wind velocity at point WindVxiList(1),WindVyiList(1),WindVziList(1). X, Y, and Z direction components. ' & + /) + + CALL InflowWind_ParseInputFileInfo(InputFileData , InFileInfo, PriPath, TmpErrStat, TmpErrMsg) + + @assertEqual(TmpErrStat, 0) + @assertEqual(InputFileData%SumPrint, .TRUE.) + @assertEqual(InputFileData%OutList(1), "Wind1VelX") + @assertEqual(InputFileData%OutList(2), "Wind1VelY") + + end subroutine + +end module diff --git a/modules/inflowwind/tests/test_steady_wind.F90 b/modules/inflowwind/tests/test_steady_wind.F90 new file mode 100644 index 0000000000..3699566192 --- /dev/null +++ b/modules/inflowwind/tests/test_steady_wind.F90 @@ -0,0 +1,63 @@ +module test_steady_wind + + use pFUnit_mod + use ifw_test_tools + use InflowWind_Subs + use InflowWind_Types + + implicit none + +contains + + @test + subroutine test_steady_wind_input_single_height() + + TYPE(FileInfoType) :: InFileInfo + TYPE(InflowWind_InputFile) :: InputFileData + CHARACTER(1024) :: PriPath + INTEGER(IntKi) :: TmpErrStat + CHARACTER(ErrMsgLen) :: TmpErrMsg + + PriPath = "" + + InFileInfo = getInputFileData() + CALL InflowWind_ParseInputFileInfo(InputFileData , InFileInfo, PriPath, TmpErrStat, TmpErrMsg) + + @assertEqual(TmpErrStat, 0) + @assertEqual(InputFileData%WindType, 1) + @assertEqual(InputFileData%NWindVel, 1) + @assertEqual(InputFileData%WindVziList(1), 90) + + end subroutine + + + @test + subroutine test_steady_wind_input_mult_heights() + + TYPE(FileInfoType) :: InFileInfo + TYPE(InflowWind_InputFile) :: InputFileData + CHARACTER(1024) :: PriPath + INTEGER(IntKi) :: TmpErrStat + CHARACTER(ErrMsgLen) :: TmpErrMsg + + PriPath = "" + + InFileInfo = getInputFileData() + InFileInfo%Lines(7:10) = (/ & + ' 2 NWindVel - Number of points to output the wind velocity (0 to 9) ', & + ' 0,0 WindVxiList - List of coordinates in the inertial X direction (m) ', & + ' 0,0 WindVyiList - List of coordinates in the inertial Y direction (m) ', & + ' 80,100 WindVziList - List of coordinates in the inertial Z direction (m) ' & + /) + + CALL InflowWind_ParseInputFileInfo(InputFileData , InFileInfo, PriPath, TmpErrStat, TmpErrMsg) + + @assertEqual(TmpErrStat, 0) + @assertEqual(InputFileData%WindType, 1) + @assertEqual(InputFileData%NWindVel, 2) + @assertEqual(InputFileData%WindVziList(1), 80) + @assertEqual(InputFileData%WindVziList(2), 100) + + end subroutine + +end module diff --git a/modules/inflowwind/tests/test_turbsim_wind.F90 b/modules/inflowwind/tests/test_turbsim_wind.F90 new file mode 100644 index 0000000000..8b301ca8bb --- /dev/null +++ b/modules/inflowwind/tests/test_turbsim_wind.F90 @@ -0,0 +1,34 @@ +module test_turbsim_wind + + use pFUnit_mod + use ifw_test_tools + use InflowWind_Subs + use InflowWind_Types + + implicit none + +contains + + @test + subroutine test_steady_wind_input_single_height() + + TYPE(FileInfoType) :: InFileInfo + TYPE(InflowWind_InputFile) :: InputFileData + CHARACTER(1024) :: PriPath + INTEGER(IntKi) :: TmpErrStat + CHARACTER(ErrMsgLen) :: TmpErrMsg + + CHARACTER(16) :: expected + + expected = "Wind/08ms.wnd" + PriPath = "" + + InFileInfo = getInputFileData() + CALL InflowWind_ParseInputFileInfo(InputFileData , InFileInfo, PriPath, TmpErrStat, TmpErrMsg) + + @assertEqual(TmpErrStat, 0) + @assertEqual(InputFileData%TSFF_FileName, trim(expected)) + + end subroutine + +end module diff --git a/modules/inflowwind/tests/test_uniform_wind.F90 b/modules/inflowwind/tests/test_uniform_wind.F90 new file mode 100644 index 0000000000..c17d069f31 --- /dev/null +++ b/modules/inflowwind/tests/test_uniform_wind.F90 @@ -0,0 +1,99 @@ +module test_uniform_wind + + use pFUnit_mod + use ifw_test_tools + use InflowWind + use InflowWind_Subs + use InflowWind_Types + + implicit none + +contains + + @test + subroutine test_uniform_wind_input() + + TYPE(FileInfoType) :: InFileInfo + TYPE(InflowWind_InputFile) :: InputFileData + CHARACTER(1024) :: PriPath + INTEGER(IntKi) :: TmpErrStat + CHARACTER(ErrMsgLen) :: TmpErrMsg + + CHARACTER(16) :: expected + + expected = "Wind/08ms.wnd" + PriPath = "" + + InFileInfo = getInputFileData() + CALL InflowWind_ParseInputFileInfo(InputFileData , InFileInfo, PriPath, TmpErrStat, TmpErrMsg) + + @assertEqual(TmpErrStat, 0) + @assertEqual(InputFileData%Uniform_FileName, trim(expected)) + @assertEqual(InputFileData%Uniform_RefHt, 90) + @assertEqual(InputFileData%Uniform_RefLength, 125.88) + + end subroutine + + @test + subroutine test_uniform_wind_direct_data() + + ! Types for setting up module + TYPE(InflowWind_InitInputType) :: InitInp !< Input data for initialization + TYPE(InflowWind_InputType) :: InputGuess !< An initial guess for the input; the input mesh must be defined + TYPE(InflowWind_ParameterType) :: p !< Parameters + TYPE(InflowWind_ContinuousStateType) :: ContStates !< Initial continuous states + TYPE(InflowWind_DiscreteStateType) :: DiscStates !< Initial discrete states + TYPE(InflowWind_ConstraintStateType) :: ConstrStateGuess !< Initial guess of the constraint states + TYPE(InflowWind_OtherStateType) :: OtherStates !< Initial other/optimization states + TYPE(InflowWind_OutputType) :: y !< Initial output (outputs are not calculated; only the output mesh is initialized) + TYPE(InflowWind_MiscVarType) :: m !< Misc variables for optimization (not copied in glue code) + REAL(DbKi) :: TimeInterval !< Coupling time interval in seconds: InflowWind does not change this. + TYPE(InflowWind_InitOutputType) :: InitOutData + + ! Variables for testing + INTEGER :: ErrStat + CHARACTER(ErrMsgLen) :: ErrMsg + TYPE(FileInfoType) :: InFileInfo + TYPE(FileInfoType) :: WindType2Data + CHARACTER(1024), DIMENSION(6) :: data = (/ & + '! Wind file for sheared 18 m/s wind with 30 degree direction. ', & + '! Time Wind Wind Vert. Horiz. Vert. LinV Gust ', & + '! Speed Dir Speed Shear Shear Shear Speed ', & + ' 0.0 12.0 0.0 0.0 0.0 0.0 0.0 0.0 ', & + ' 0.1 12.0 0.0 0.0 0.0 0.0 0.0 0.0 ', & + ' 999.9 12.0 0.0 0.0 0.0 0.0 0.0 0.0 ' & + /) + + ! Error handling + INTEGER(IntKi) :: TmpErrStat + CHARACTER(ErrMsgLen) :: TmpErrMsg !< temporary error message + + InFileInfo = getInputFileDataWindType2() + CALL InitFileInfo(data, WindType2Data, ErrStat, ErrMsg) + + ! Variable definitions + InitInp%InputFileName = "" + InitInp%NumWindPoints = 5 + InitInp%UseInputFile = .FALSE. + InitInp%RootName = "" + InitInp%PassedFileData = InFileInfo + InitInp%WindType2UseInputFile = .FALSE. + InitInp%WindType2Data = WindType2Data + + CALL InflowWind_Init( InitInp, InputGuess, p, ContStates, DiscStates, & + ConstrStateGuess, OtherStates, y, m, TimeInterval, & + InitOutData, TmpErrStat, TmpErrMsg) + + ! Results + + @assertEqual(0.0, p%UniformWind%TData(1)) + @assertEqual(0.1, p%UniformWind%TData(2)) + @assertEqual(999.9, p%UniformWind%TData(3)) + + @assertEqual(12.0, p%UniformWind%V(1)) + @assertEqual(12.0, p%UniformWind%V(2)) + @assertEqual(12.0, p%UniformWind%V(3)) + + end subroutine + +end module diff --git a/reg_tests/r-test b/reg_tests/r-test index 7ab61a078f..ae2ed207c9 160000 --- a/reg_tests/r-test +++ b/reg_tests/r-test @@ -1 +1 @@ -Subproject commit 7ab61a078f6dc48b26234988fbef84fbf7676ad2 +Subproject commit ae2ed207c937421f1d0fa2fd578e5b627d7979f4 diff --git a/unit_tests/CMakeLists.txt b/unit_tests/CMakeLists.txt index 6303fc19c4..4339b0c437 100644 --- a/unit_tests/CMakeLists.txt +++ b/unit_tests/CMakeLists.txt @@ -72,8 +72,9 @@ endif() add_subdirectory("beamdyn") add_subdirectory("nwtc-library") add_subdirectory("aerodyn") +add_subdirectory("inflowwind") add_custom_target( unit_tests - DEPENDS beamdyn_utest nwtc_library_utest fvw_utest -) \ No newline at end of file + DEPENDS beamdyn_utest nwtc_library_utest fvw_utest inflowwind_utest +) diff --git a/unit_tests/inflowwind/CMakeLists.txt b/unit_tests/inflowwind/CMakeLists.txt new file mode 100644 index 0000000000..809256d44d --- /dev/null +++ b/unit_tests/inflowwind/CMakeLists.txt @@ -0,0 +1,67 @@ +# +# Copyright 2017 National Renewable Energy Laboratory +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +set_source_files_properties(${pfunit_directory}/include/driver.F90 PROPERTIES GENERATED 1) + +set(module_name "inflowwind") +set(module_directory "inflowwind") +set(module_library "ifwlib") + +file(MAKE_DIRECTORY ${build_testdirectory}/${module_directory}) +file(WRITE ${build_testdirectory}/${module_directory}/testSuites.inc "") + +include_directories( + ${PROJECT_SOURCE_DIR} + ${pfunit_directory}/mod + ${build_testdirectory}/${module_directory} +) + +set(testlist + ifw_test_tools + test_steady_wind + test_uniform_wind + test_turbsim_wind + test_bladed_wind + test_hawc_wind + test_outputs +) +foreach(test ${testlist}) + set(test_dependency pfunit ${source_modulesdirectory}/${module_directory}/tests/${test}.F90) + add_custom_command( + OUTPUT ${build_testdirectory}/${module_directory}/${test}.F90 + COMMAND ${PYTHON_EXECUTABLE} ${pfunit_directory}/bin/pFUnitParser.py ${source_modulesdirectory}/${module_directory}/tests/${test}.F90 ${build_testdirectory}/${module_directory}/${test}.F90 + DEPENDS ${test_dependency} + ) + set(test_sources ${test_sources} ${build_testdirectory}/${module_directory}/${test}.F90) + file(APPEND ${build_testdirectory}/${module_directory}/testSuites.inc "ADD_TEST_SUITE(${test}_suite)\n") +endforeach() + +add_executable( + ${module_name}_utest + ${pfunit_directory}/include/driver.F90 + ${test_sources} +) + +target_link_libraries( + ${module_name}_utest + ${pfunit_directory}${pfunit_lib} + ${module_library} +) + +add_test( + ${module_name}_utest + ${PROJECT_BINARY_DIR}/${module_directory}/${module_name}_utest +)