From defd8b7b0b5a51162ed38b631fb9d766c6278d24 Mon Sep 17 00:00:00 2001 From: Bonnie Jonkman Date: Thu, 30 Nov 2023 07:36:22 -0700 Subject: [PATCH 1/4] Minor updates to UA driver (#22) * UA driver: vs build - vs project didn't like a `UA_OUTS` as both a preprocessor directive and value inside a type - vs project needed LinDyn added to it - moved override of UA_OUTS to UA driver and added initialization in BEMT & FVW so people could override the value before compiling if they wanted to debug UA inside of AeroDyn. * LinDyn: states should be reals, not logicals This would have caused issues when merging with the dev-unstable branch of OpenFAST * fix typo in RoutineName parameter * UA: minor updates - update extension of UA output files - explicitly initialize `d_34_to_ac` --- modules/aerodyn/src/BEMT.f90 | 5 +- modules/aerodyn/src/FVW.f90 | 5 +- modules/aerodyn/src/UA_Dvr_Subs.f90 | 68 ++++++++++++----------- modules/aerodyn/src/UnsteadyAero.f90 | 17 +++--- modules/lindyn/src/LinDyn_Registry.txt | 4 +- modules/lindyn/src/LinDyn_Types.f90 | 24 ++++---- modules/nwtc-library/src/NWTC_Num.f90 | 2 +- vs-build/RunRegistry.bat | 8 +++ vs-build/UnsteadyAero/UnsteadyAero.vfproj | 37 +++++++++--- 9 files changed, 103 insertions(+), 67 deletions(-) diff --git a/modules/aerodyn/src/BEMT.f90 b/modules/aerodyn/src/BEMT.f90 index 9c50d3fcdc..b99c3a6658 100644 --- a/modules/aerodyn/src/BEMT.f90 +++ b/modules/aerodyn/src/BEMT.f90 @@ -126,7 +126,7 @@ subroutine BEMT_Set_UA_InitData( InitInp, interval, Init_UA_Data, errStat, errMs call move_alloc(InitInp%UAOff_outerNode, Init_UA_Data%UAOff_outerNode) Init_UA_Data%dt = interval - Init_UA_Data%OutRootName = InitInp%RootName ! was 'Debug.UA' + Init_UA_Data%OutRootName = trim(InitInp%RootName)//'.UA' Init_UA_Data%numBlades = InitInp%numBlades Init_UA_Data%nNodesPerBlade = InitInp%numBladeNodes @@ -137,6 +137,9 @@ subroutine BEMT_Set_UA_InitData( InitInp, interval, Init_UA_Data, errStat, errMs Init_UA_Data%ShedEffect = .true. ! This should be true when coupled to BEM Init_UA_Data%WrSum = InitInp%SumPrint + Init_UA_Data%UA_OUTS = 0 + Init_UA_Data%d_34_to_ac = 0.5_ReKi + end subroutine BEMT_Set_UA_InitData diff --git a/modules/aerodyn/src/FVW.f90 b/modules/aerodyn/src/FVW.f90 index 616d96ffc7..9c454c0388 100644 --- a/modules/aerodyn/src/FVW.f90 +++ b/modules/aerodyn/src/FVW.f90 @@ -1591,7 +1591,7 @@ subroutine UA_Init_Wrapper(AFInfo, InitInp, interval, p, x, xd, OtherState, m, E Init_UA_Data%c(i,1) = p%W(iW)%chord_LL(i) ! NOTE: InitInp chord move-allocd to p end do Init_UA_Data%dt = interval - Init_UA_Data%OutRootName = trim(InitInp%RootName)//'W'//num2lstr(iW) + Init_UA_Data%OutRootName = trim(InitInp%RootName)//'W'//num2lstr(iW)//'.UA' Init_UA_Data%numBlades = 1 Init_UA_Data%nNodesPerBlade = InitInp%numBladeNodes ! At AeroDyn ndoes, not CP @@ -1600,6 +1600,9 @@ subroutine UA_Init_Wrapper(AFInfo, InitInp, interval, p, x, xd, OtherState, m, E Init_UA_Data%a_s = InitInp%a_s ! Speed of sound, m/s Init_UA_Data%ShedEffect = .False. ! Important, when coupling UA wih vortex code, shed vorticity is inherently accounted for Init_UA_Data%WrSum = InitInp%SumPrint + Init_UA_Data%UA_OUTS = 0 + Init_UA_Data%d_34_to_ac = 0.5_ReKi + allocate(Init_UA_Data%UAOff_innerNode(1), stat=errStat2) allocate(Init_UA_Data%UAOff_outerNode(1), stat=errStat2) Init_UA_Data%UAOff_innerNode(1) = InitInp%W(iW)%UAOff_innerNode diff --git a/modules/aerodyn/src/UA_Dvr_Subs.f90 b/modules/aerodyn/src/UA_Dvr_Subs.f90 index 323f62c52b..1d7e12f955 100644 --- a/modules/aerodyn/src/UA_Dvr_Subs.f90 +++ b/modules/aerodyn/src/UA_Dvr_Subs.f90 @@ -193,7 +193,7 @@ subroutine ReadDriverInputFile( FileName, InitInp, ErrStat, ErrMsg ) type(FileInfoType) :: FI !< The derived type for holding the file information. integer(IntKi) :: errStat2 ! Status of error message character(1024) :: errMsg2 ! Error message if ErrStat /= ErrID_None - character(*), parameter :: RoutineName = 'ReadDriverfilename' + character(*), parameter :: RoutineName = 'ReadDriverInputFile' ! Initialize the echo file unit to -1 which is the default to prevent echoing, we will alter this based on user input UnEcho = -1 ErrStat = ErrID_None @@ -401,6 +401,10 @@ subroutine driverInputsToUAInitData(p, InitInData, AFI_Params, AFIndx, errStat, errStat = ErrID_None errMsg = '' InitInData%UA_OUTS = 1 ! 0=None, 1=Write Outputs, 2=Separate File +#ifdef ADD_UA_OUTS + InitInData%UA_OUTS = 2 ! Compiler Flag Override, 2=Write a separate file +#endif + ! -- UA Init Input Data InitInData%nNodesPerBlade = 1 @@ -416,7 +420,7 @@ subroutine driverInputsToUAInitData(p, InitInData, AFI_Params, AFIndx, errStat, InitInData%c(1,1) = p%Chord InitInData%UAMod = p%UAMod InitInData%Flookup = p%Flookup - InitInData%OutRootName = p%OutRootName + InitInData%OutRootName = trim(p%OutRootName)//'.UA' InitInData%WrSum = p%SumPrint InitInData%d_34_to_ac = p%d_34_to_ac ! d_34_to_ac = d_QT ~0.5 [-], Approximated using y coordinate @@ -959,36 +963,36 @@ subroutine Dvr_WriteOutputs(nt, t, dvr, out, errStat, errMsg) ! Driver outputs j = 1 if (dvr%p%SimMod==3) then - ! TODO harmonization - out%outLine(j) = dvr%U0(1, 1) ; j=j+1 ! Ux - out%outLine(j) = dvr%U0(1, 2) ; j=j+1 ! Uy - out%outLine(j) = dvr%m%Vst_Q(1) ; j=j+1 ! VSTx_Q - out%outLine(j) = dvr%m%Vst_Q(2) ; j=j+1 ! VSTy_Q - out%outLine(j) = dvr%m%Vst_T(1) ; j=j+1 ! VSTx_T - out%outLine(j) = dvr%m%Vst_T(2) ; j=j+1 ! VSTy_T - out%outLine(j) = dvr%m%Vrel_Q(1) ; j=j+1 ! Vrelx_Q - out%outLine(j) = dvr%m%Vrel_Q(2) ; j=j+1 ! Vrely_Q - out%outLine(j) = dvr%m%Vrel_T(1) ; j=j+1 ! Vrelx_T - out%outLine(j) = dvr%m%Vrel_T(2) ; j=j+1 ! Vrely_T - out%outLine(j) = sqrt(dvr%m%Vrel_norm2_Q) ; j=j+1 ! Vrel_Q - out%outLine(j) = sqrt(dvr%m%Vrel_norm2_T) ; j=j+1 ! Vrel_T - out%outLine(j) = dvr%m%alpha_Q*R2D ; j=j+1 ! alpha_Q - out%outLine(j) = dvr%m%alpha_T*R2D ; j=j+1 ! alpha_T - out%outLine(j) = dvr%m%phi_Q *R2D ; j=j+1 ! phi_Q - out%outLine(j) = dvr%m%phi_T *R2D ; j=j+1 ! phi_T - out%outLine(j) = dvr%m%twist_full*R2D ; j=j+1 ! twist_full - out%outLine(j) = dvr%m%Re ; j=j+1 ! Re_T - out%outLine(j) = dvr%m%L ; j=j+1 ! L - out%outLine(j) = dvr%m%D ; j=j+1 ! D - out%outLine(j) = dvr%m%tau_Q ; j=j+1 ! M - out%outLine(j) = dvr%m%FxA ; j=j+1 ! Fx_A - out%outLine(j) = dvr%m%FyA ; j=j+1 ! Fy_A - out%outLine(j) = dvr%m%tau_A ; j=j+1 ! M_A - out%outLine(j) = dvr%m%GF(1) ; j=j+1 ! GFx - out%outLine(j) = dvr%m%GF(2) ; j=j+1 ! GFy - out%outLine(j) = dvr%m%GF(3) ; j=j+1 ! GFM - ! LD Outputs - out%outLine(nDV+1:nDV+nLD) = dvr%LD_y%WriteOutput(1:nLD) + ! TODO harmonization + out%outLine(j) = dvr%U0(1, 1) ; j=j+1 ! Ux + out%outLine(j) = dvr%U0(1, 2) ; j=j+1 ! Uy + out%outLine(j) = dvr%m%Vst_Q(1) ; j=j+1 ! VSTx_Q + out%outLine(j) = dvr%m%Vst_Q(2) ; j=j+1 ! VSTy_Q + out%outLine(j) = dvr%m%Vst_T(1) ; j=j+1 ! VSTx_T + out%outLine(j) = dvr%m%Vst_T(2) ; j=j+1 ! VSTy_T + out%outLine(j) = dvr%m%Vrel_Q(1) ; j=j+1 ! Vrelx_Q + out%outLine(j) = dvr%m%Vrel_Q(2) ; j=j+1 ! Vrely_Q + out%outLine(j) = dvr%m%Vrel_T(1) ; j=j+1 ! Vrelx_T + out%outLine(j) = dvr%m%Vrel_T(2) ; j=j+1 ! Vrely_T + out%outLine(j) = sqrt(dvr%m%Vrel_norm2_Q) ; j=j+1 ! Vrel_Q + out%outLine(j) = sqrt(dvr%m%Vrel_norm2_T) ; j=j+1 ! Vrel_T + out%outLine(j) = dvr%m%alpha_Q*R2D ; j=j+1 ! alpha_Q + out%outLine(j) = dvr%m%alpha_T*R2D ; j=j+1 ! alpha_T + out%outLine(j) = dvr%m%phi_Q *R2D ; j=j+1 ! phi_Q + out%outLine(j) = dvr%m%phi_T *R2D ; j=j+1 ! phi_T + out%outLine(j) = dvr%m%twist_full*R2D ; j=j+1 ! twist_full + out%outLine(j) = dvr%m%Re ; j=j+1 ! Re_T + out%outLine(j) = dvr%m%L ; j=j+1 ! L + out%outLine(j) = dvr%m%D ; j=j+1 ! D + out%outLine(j) = dvr%m%tau_Q ; j=j+1 ! M + out%outLine(j) = dvr%m%FxA ; j=j+1 ! Fx_A + out%outLine(j) = dvr%m%FyA ; j=j+1 ! Fy_A + out%outLine(j) = dvr%m%tau_A ; j=j+1 ! M_A + out%outLine(j) = dvr%m%GF(1) ; j=j+1 ! GFx + out%outLine(j) = dvr%m%GF(2) ; j=j+1 ! GFy + out%outLine(j) = dvr%m%GF(3) ; j=j+1 ! GFM + ! LD Outputs + out%outLine(nDV+1:nDV+nLD) = dvr%LD_y%WriteOutput(1:nLD) endif ! UA Outputs out%outLine(nDV+nLD+1:nDV+nLD+nUA) = dvr%UA_y%WriteOutput(1:nUA) diff --git a/modules/aerodyn/src/UnsteadyAero.f90 b/modules/aerodyn/src/UnsteadyAero.f90 index 63118ccab8..8cebfedb42 100644 --- a/modules/aerodyn/src/UnsteadyAero.f90 +++ b/modules/aerodyn/src/UnsteadyAero.f90 @@ -522,7 +522,7 @@ subroutine ComputeKelvinChain( i, j, u, p, xd, OtherState, misc, AFInfo, KC, BL_ KC%Cn_q_circ = KC%C_nalpha_circ*KC%q_f_cur/2.0 - KC%X3 - KC%X4 ! Eqn 1.16 - else ! these aren't used (they are possibly output to UA output file (when UA_OUTS defined) file, though) + else ! these aren't used (they are possibly output to UA output file when UA_OUTS is > 0 file, though) KC%X3 = 0.0_ReKi KC%X4 = 0.0_ReKi KC%Cn_q_circ = 0.0_ReKi @@ -748,9 +748,6 @@ subroutine UA_SetParameters( dt, InitInp, p, AFInfo, AFIndx, ErrStat, ErrMsg ) p%Flookup = InitInp%Flookup p%ShedEffect = InitInp%ShedEffect p%UA_OUTS = InitInp%UA_OUTS -#ifdef UA_OUTS - p%UA_OUTS = 2 ! Compiler Flag Override, 2=Write a separate file -#endif if (p%UAMod==UA_HGM .or. p%UAMod==UA_HGMV) then UA_NumLinStates = 4 @@ -1419,11 +1416,11 @@ subroutine UA_Init_Outputs(InitInp, p, y, InitOut, errStat, errMsg) ! --- Write to File if ((p%NumOuts > 0) .and. p%UA_OUTS==2) then - call WrScr(' UA: Writing separate output file: '//trim((InitInp%OutRootName)//'.UA.out')) + call WrScr(' UA: Writing separate output file: '//trim((InitInp%OutRootName)//'.out')) CALL GetNewUnit( p%unOutFile, ErrStat2, ErrMsg2 ) call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) if (ErrStat >= AbortErrLev) return - CALL OpenFOutFile ( p%unOutFile, trim(InitInp%OutRootName)//'.UA.out', ErrStat2, ErrMsg2 ) + CALL OpenFOutFile ( p%unOutFile, trim(InitInp%OutRootName)//'.out', ErrStat2, ErrMsg2 ) call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) if (ErrStat >= AbortErrLev) return @@ -1443,7 +1440,7 @@ subroutine UA_Init_Outputs(InitInp, p, y, InitOut, errStat, errMsg) WRITE (p%unOutFile,'(:,A,'//trim( p%OutSFmt )//')', ADVANCE='no' ) p%Delim, trim(InitOut%WriteOutputUnt(i)) end do WRITE (p%unOutFile,'()', IOSTAT=ErrStat2) ! write the line return - elseif ((p%NumOuts > 0) .and. p%UA_OUTS==2) then + else call WrScr(' UA: saving write outputs') @@ -3844,9 +3841,9 @@ subroutine BV_CalcOutput() ! --- Recompute variables, for temporary output to file only ! Calculate deltas to negative and positive stall angle (delN, and delP) if (p%UA_OUTS>0) then - call BV_delNP(adotnorm, alpha_34, alphaLag_D, BL_p, OtherState%activeD(i,j), delN, delP) - call BV_getGammas(tc=AFInfo%RelThickness, umach=0.0_ReKi, gammaL=gammaL, gammaD=gammaD) - TransA = BV_TransA(BL_p) + call BV_delNP(adotnorm, alpha_34, alphaLag_D, BL_p, OtherState%activeD(i,j), delN, delP) + call BV_getGammas(tc=AFInfo%RelThickness, umach=0.0_ReKi, gammaL=gammaL, gammaD=gammaD) + TransA = BV_TransA(BL_p) endif ! --- Cl, _, at effective angle of attack alphaE diff --git a/modules/lindyn/src/LinDyn_Registry.txt b/modules/lindyn/src/LinDyn_Registry.txt index a5dd46dee8..6140a54fab 100644 --- a/modules/lindyn/src/LinDyn_Registry.txt +++ b/modules/lindyn/src/LinDyn_Registry.txt @@ -39,10 +39,10 @@ typedef ^ ^ IntKi typedef ^ ContinuousStateType ReKi q {:} - - "Continuous states q =(x,xdot)" "-" # Discrete (non-differentiable) states: -typedef ^ DiscreteStateType Logical Dummy - - - "" - +typedef ^ DiscreteStateType SiKi Dummy - - - "" - # Constraint states: -typedef ^ ConstraintStateType Logical Dummy - - - "" - +typedef ^ ConstraintStateType SiKi Dummy - - - "" - # Other states: typedef ^ OtherStateType LD_ContinuousStateType xdot {:} - - "Previous state derivs for m-step time integrator" diff --git a/modules/lindyn/src/LinDyn_Types.f90 b/modules/lindyn/src/LinDyn_Types.f90 index ef28a6f104..778bb39cee 100644 --- a/modules/lindyn/src/LinDyn_Types.f90 +++ b/modules/lindyn/src/LinDyn_Types.f90 @@ -72,12 +72,12 @@ MODULE LinDyn_Types ! ======================= ! ========= LD_DiscreteStateType ======= TYPE, PUBLIC :: LD_DiscreteStateType - LOGICAL :: Dummy !< [-] + REAL(SiKi) :: Dummy !< [-] END TYPE LD_DiscreteStateType ! ======================= ! ========= LD_ConstraintStateType ======= TYPE, PUBLIC :: LD_ConstraintStateType - LOGICAL :: Dummy !< [-] + REAL(SiKi) :: Dummy !< [-] END TYPE LD_ConstraintStateType ! ======================= ! ========= LD_OtherStateType ======= @@ -1800,7 +1800,7 @@ SUBROUTINE LD_PackDiscState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg Re_BufSz = 0 Db_BufSz = 0 Int_BufSz = 0 - Int_BufSz = Int_BufSz + 1 ! Dummy + Re_BufSz = Re_BufSz + 1 ! Dummy IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -1828,8 +1828,8 @@ SUBROUTINE LD_PackDiscState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg Db_Xferred = 1 Int_Xferred = 1 - IntKiBuf(Int_Xferred) = TRANSFER(InData%Dummy, IntKiBuf(1)) - Int_Xferred = Int_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%Dummy + Re_Xferred = Re_Xferred + 1 END SUBROUTINE LD_PackDiscState SUBROUTINE LD_UnPackDiscState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) @@ -1858,8 +1858,8 @@ SUBROUTINE LD_UnPackDiscState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Err Re_Xferred = 1 Db_Xferred = 1 Int_Xferred = 1 - OutData%Dummy = TRANSFER(IntKiBuf(Int_Xferred), OutData%Dummy) - Int_Xferred = Int_Xferred + 1 + OutData%Dummy = REAL(ReKiBuf(Re_Xferred), SiKi) + Re_Xferred = Re_Xferred + 1 END SUBROUTINE LD_UnPackDiscState SUBROUTINE LD_CopyConstrState( SrcConstrStateData, DstConstrStateData, CtrlCode, ErrStat, ErrMsg ) @@ -1937,7 +1937,7 @@ SUBROUTINE LD_PackConstrState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrM Re_BufSz = 0 Db_BufSz = 0 Int_BufSz = 0 - Int_BufSz = Int_BufSz + 1 ! Dummy + Re_BufSz = Re_BufSz + 1 ! Dummy IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -1965,8 +1965,8 @@ SUBROUTINE LD_PackConstrState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrM Db_Xferred = 1 Int_Xferred = 1 - IntKiBuf(Int_Xferred) = TRANSFER(InData%Dummy, IntKiBuf(1)) - Int_Xferred = Int_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%Dummy + Re_Xferred = Re_Xferred + 1 END SUBROUTINE LD_PackConstrState SUBROUTINE LD_UnPackConstrState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) @@ -1995,8 +1995,8 @@ SUBROUTINE LD_UnPackConstrState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, E Re_Xferred = 1 Db_Xferred = 1 Int_Xferred = 1 - OutData%Dummy = TRANSFER(IntKiBuf(Int_Xferred), OutData%Dummy) - Int_Xferred = Int_Xferred + 1 + OutData%Dummy = REAL(ReKiBuf(Re_Xferred), SiKi) + Re_Xferred = Re_Xferred + 1 END SUBROUTINE LD_UnPackConstrState SUBROUTINE LD_CopyOtherState( SrcOtherStateData, DstOtherStateData, CtrlCode, ErrStat, ErrMsg ) diff --git a/modules/nwtc-library/src/NWTC_Num.f90 b/modules/nwtc-library/src/NWTC_Num.f90 index 3c2be77d25..66148d1e3d 100644 --- a/modules/nwtc-library/src/NWTC_Num.f90 +++ b/modules/nwtc-library/src/NWTC_Num.f90 @@ -4984,7 +4984,7 @@ FUNCTION RegCubicSplineInterpM ( X, XAry, YAry, DelX, Coef, ErrStat, ErrMsg ) RE RETURN END FUNCTION RegCubicSplineInterpM ! ( X, XAry, YAry, DelX, Coef, ErrStat, ErrMsg ) !======================================================================= -!> This routine is used to integrate funciton f over the interval [a, b]. This routine +!> This routine is used to integrate function f over the interval [a, b]. This routine !! is useful for sufficiently smooth (e.g., analytic) integrands, integrated over !! intervals which contain no singularities, and where the endpoints are also nonsingular. !! diff --git a/vs-build/RunRegistry.bat b/vs-build/RunRegistry.bat index 2649627f6b..af15365556 100644 --- a/vs-build/RunRegistry.bat +++ b/vs-build/RunRegistry.bat @@ -44,6 +44,8 @@ SET SrvD_Loc=%Modules_Loc%\servodyn\src SET BD_Loc=%Modules_Loc%\beamdyn\src SET SC_Loc=%Modules_Loc%\supercontroller\src +SET LD_Loc=%Modules_Loc%\lindyn\src + SET AWAE_Loc=%Modules_Loc%\awae\src SET WD_Loc=%Modules_Loc%\wakedynamics\src SET Farm_Loc=%Root_Loc%\glue-codes\fast-farm\src @@ -165,6 +167,12 @@ SET Output_Loc=%CURR_LOC% %REGISTRY% "%CURR_LOC%\UnsteadyAero_Registry.txt" -I "%NWTC_Lib_Loc%" -I "%CURR_LOC%" -O "%Output_Loc%" GOTO checkError +:LD +SET CURR_LOC=%LD_Loc% +SET Output_Loc=%CURR_LOC% +%REGISTRY% "%CURR_LOC%\LinDyn_Registry.txt" -I "%NWTC_Lib_Loc%" -I "%CURR_LOC%" -O "%Output_Loc%" +GOTO checkError + :FVW SET CURR_LOC=%AD_Loc% SET Output_Loc=%CURR_LOC% diff --git a/vs-build/UnsteadyAero/UnsteadyAero.vfproj b/vs-build/UnsteadyAero/UnsteadyAero.vfproj index 321fd8c587..066fc3feb7 100644 --- a/vs-build/UnsteadyAero/UnsteadyAero.vfproj +++ b/vs-build/UnsteadyAero/UnsteadyAero.vfproj @@ -5,7 +5,7 @@ - + @@ -15,7 +15,7 @@ - + @@ -25,7 +25,7 @@ - + @@ -35,7 +35,7 @@ - + @@ -45,7 +45,7 @@ - + @@ -55,7 +55,7 @@ - + @@ -65,7 +65,7 @@ - + @@ -75,7 +75,7 @@ - + @@ -120,6 +120,27 @@ + + + + + + + + + + + + + + + + + + + + + From 9562e5d7652b41bd1ba9fd2d693994790a6031f1 Mon Sep 17 00:00:00 2001 From: Emmanuel Branlard Date: Thu, 30 Nov 2023 19:30:57 -0700 Subject: [PATCH 2/4] UA: generalized scaling factors are now a 3x3 matrix --- modules/aerodyn/src/UA_Dvr_Subs.f90 | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/modules/aerodyn/src/UA_Dvr_Subs.f90 b/modules/aerodyn/src/UA_Dvr_Subs.f90 index 1d7e12f955..9120b2164c 100644 --- a/modules/aerodyn/src/UA_Dvr_Subs.f90 +++ b/modules/aerodyn/src/UA_Dvr_Subs.f90 @@ -58,7 +58,7 @@ module UA_Dvr_Subs real(ReKi) :: CC(3,3) real(ReKi) :: KK(3,3) logical :: activeDOFs(3) - real(ReKi) :: GFScaling(3) + real(ReKi) :: GFScaling(3,3) real(ReKi) :: initPos(3) real(ReKi) :: initVel(3) real(ReKi) :: Vec_AQ(2) ! Vector from A to quarter chord /aerodynamic center @@ -263,7 +263,9 @@ subroutine ReadDriverInputFile( FileName, InitInp, ErrStat, ErrMsg ) call ParseAry(FI, iLine, 'activeDOFs' , InitInp%activeDOFs, 3, errStat2, errMsg2, UnEcho); if(Failed()) return call ParseAry(FI, iLine, 'initPos' , InitInp%initPos , 3, errStat2, errMsg2, UnEcho); if(Failed()) return call ParseAry(FI, iLine, 'initVel' , InitInp%initVel , 3, errStat2, errMsg2, UnEcho); if(Failed()) return - call ParseAry(FI, iLine, 'GFScaling' , InitInp%GFScaling , 3, errStat2, errMsg2, UnEcho); if(Failed()) return + call ParseAry(FI, iLine, 'GFScaling1' , InitInp%GFScaling(1,:) , 3, errStat2, errMsg2, UnEcho); if(Failed()) return + call ParseAry(FI, iLine, 'GFScaling2' , InitInp%GFScaling(2,:) , 3, errStat2, errMsg2, UnEcho); if(Failed()) return + call ParseAry(FI, iLine, 'GFScaling3' , InitInp%GFScaling(3,:) , 3, errStat2, errMsg2, UnEcho); if(Failed()) return call ParseAry(FI, iLine, 'MassMatrix1' , InitInp%MM(1,:) , 3, errStat2, errMsg2, UnEcho); if(Failed()) return call ParseAry(FI, iLine, 'MassMatrix2' , InitInp%MM(2,:) , 3, errStat2, errMsg2, UnEcho); if(Failed()) return call ParseAry(FI, iLine, 'MassMatrix3' , InitInp%MM(3,:) , 3, errStat2, errMsg2, UnEcho); if(Failed()) return @@ -607,9 +609,9 @@ subroutine AeroKinetics(U0, q, qd, C_dyn, p, m) !tau_A2 = tau_A2 + q_dyn *C_dyn(2)* ( p%Vec_AQ(1) * CA - p%Vec_AQ(2) * SA) ! Generalized loads - m%GF(1) = m%FxA * p%GFScaling(1) - m%GF(2) = m%FyA * p%GFScaling(2) - m%GF(3) = -m%tau_A * p%GFScaling(3) ! theta_t is negative about z + m%GF(1) = m%FxA * p%GFScaling(1,1) + m%FyA * p%GFScaling(1,2) - m%tau_A * p%GFScaling(1,3) + m%GF(2) = m%FxA * p%GFScaling(2,1) + m%FyA * p%GFScaling(2,2) - m%tau_A * p%GFScaling(2,3) + m%GF(3) = m%FxA * p%GFScaling(3,1) + m%FyA * p%GFScaling(3,2) - m%tau_A * p%GFScaling(3,3) end subroutine AeroKinetics !---------------------------------------------------------------------------------------------------- From 39ea6c8f1a5014e2ac6e484ba1efce296d7f9cbf Mon Sep 17 00:00:00 2001 From: Emmanuel Branlard Date: Tue, 12 Dec 2023 14:44:24 -0700 Subject: [PATCH 3/4] UA: update of r-tests (new input file format) --- reg_tests/r-test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reg_tests/r-test b/reg_tests/r-test index c4c8c8fbb8..6f2c77d859 160000 --- a/reg_tests/r-test +++ b/reg_tests/r-test @@ -1 +1 @@ -Subproject commit c4c8c8fbb88b70ef26130d0d6314781f90b98396 +Subproject commit 6f2c77d8597f58aacb74a91768043f116bc315a9 From a8690947bf904380e818b5d00454ae2e4770c841 Mon Sep 17 00:00:00 2001 From: Emmanuel Branlard Date: Tue, 12 Dec 2023 16:31:06 -0700 Subject: [PATCH 4/4] UA: adding documentation for ua driver --- .../examples/UA-driver-timeseries.dat | 11 - .../examples/UA-driver.dvr | 28 --- docs/source/user/aerodyn/bibliography.bib | 8 + docs/source/user/aerodyn/theory_ua.rst | 202 +++++++++++++++++- 4 files changed, 206 insertions(+), 43 deletions(-) delete mode 100644 docs/source/user/aerodyn-dynamicStall/examples/UA-driver-timeseries.dat delete mode 100644 docs/source/user/aerodyn-dynamicStall/examples/UA-driver.dvr diff --git a/docs/source/user/aerodyn-dynamicStall/examples/UA-driver-timeseries.dat b/docs/source/user/aerodyn-dynamicStall/examples/UA-driver-timeseries.dat deleted file mode 100644 index 902354a4db..0000000000 --- a/docs/source/user/aerodyn-dynamicStall/examples/UA-driver-timeseries.dat +++ /dev/null @@ -1,11 +0,0 @@ -Example Time-Series Input File for UnsteadyAero Driver - - -This file has 8 header lines followed by three columns of data: - - -Time Angle of Attack VRel omega -(s) (deg) (m/s) (rad/s) -0.0 0 10 0 -0.01 0 10 0 -0.02 0 10 0 diff --git a/docs/source/user/aerodyn-dynamicStall/examples/UA-driver.dvr b/docs/source/user/aerodyn-dynamicStall/examples/UA-driver.dvr deleted file mode 100644 index 290e7e2245..0000000000 --- a/docs/source/user/aerodyn-dynamicStall/examples/UA-driver.dvr +++ /dev/null @@ -1,28 +0,0 @@ -UnsteadyAero Driver file for Unit NACA. k = 0.077 -------------------------------------------------------------------------------- -FALSE Echo - Echo the input file data (flag) ----------------------- ENVIRONMENTAL CONDITIONS ------------------------------- - 340.29 SpdSound - Speed of sound (m/s) ----------------------- UNSTEADYAERO ------------------------------------------- -"05014051_NACA" OutRootName - The name which prefixes all UnsteadyAero generated files (quoted string) - 40.36 InflowVel - Inflow velocity (m/s) - 1.48 Re - Reynolds number in millions (-) - 3 UAMod - Unsteady Aero Model Switch: 2 - Gonzalez’s variant (changes in Cn,Cc,Cm); 3 - Minnema/Pierce variant (changes in Cc and Cm) -TRUE Flookup – Flag to indicate whether a lookup for f’ will be calculated (TRUE) or whether best-fit exponential equations will be used (FALSE); if FALSE S1-S4 must be provided in airfoil input files -------------------- AIRFOIL PROPERTIES ---------------------------------------- -"05000051_AD15.dat" AirFoil - Airfoil table - 0.55 Chord - Chord length (m) -TRUE UseCm - Use Cm data in airfoil table -------------------- SIMULATION CONTROL ---------------------------------------- - 1 SimMod - Simulation model [ 1 - use reduced frequency model, 2 - use time series data stored in the TimeInputs file and ignore the remaining parameters ] - 3 NCycles - Number of angle-of-attack oscillations (cosine function) over the length of the simulation (-) - 720 StepsPerCycle - Number of timesteps per cycle (-) - 1.8 Frequency - Frequency for the airfoil oscillations (Hz) - 9.685 Amplitude - Amplitude of the oscillations (deg) - 15.195 Mean - Cycle mean (deg) - -180 Phase - Initial phase (num steps) -"UA-driver-timeseries.dat" InputsFile - Time series data in an ASCII input file (whitespace-separated data). 8 header lines, followed by column data. First column is time (sec), second column is angle-of-attack (deg), third column is InflowVel (m/s) -------------------- OUTPUT CONTROL -------------------------------------------- -True SumPrint - Write unsteady aerodynamics summary file (flag) -True WrAFITables - Write the tables of aerodynamic coefficients used internally, with extension ".Coeff.out" (flag) -END of driver input file diff --git a/docs/source/user/aerodyn/bibliography.bib b/docs/source/user/aerodyn/bibliography.bib index dc79859eb4..e6b5cdcad1 100644 --- a/docs/source/user/aerodyn/bibliography.bib +++ b/docs/source/user/aerodyn/bibliography.bib @@ -16,6 +16,14 @@ @TECHREPORT{ad-AeroDyn:manualUnsteady note = {NREL/TP-5000-66347} } +@article{ad-UAElast:torquepaper, + title = {Aeroelastic stability of a generalized wind turbine cross-section including unsteady airfoil aerodynamic and dynamic inflow}, + author = {E. Branlard and J.Jonkman and B. Jonkman and M. Singh and E. Mayda and K.Dixon and J H. Porter and G. Vijayakumar}, + year = 2024, + journal = {Jounal of Physics: Conference Series}, +} + + @book{ad-Branlard:book, author = {E. Branlard}, title = {Wind Turbine Aerodynamics and Vorticity-Based Methods: Fundamentals and Recent Applications}, diff --git a/docs/source/user/aerodyn/theory_ua.rst b/docs/source/user/aerodyn/theory_ua.rst index 005e478fdd..2a67b8fdd5 100644 --- a/docs/source/user/aerodyn/theory_ua.rst +++ b/docs/source/user/aerodyn/theory_ua.rst @@ -25,6 +25,12 @@ speed increases, but stall is delayed. + + + +.. _ua_theory: + + Theory ------ @@ -489,6 +495,12 @@ where :math:`\alpha_{50}` is computed the same way as :math:`\alpha_{34}` (using + + + + +.. _UA_inputs: + Inputs ------ @@ -503,6 +515,10 @@ An example of profile data (containing some of the unsteady aerodynamic paramete :download:`(here) `. +The unsteady aerodynamic driver inputs are documented in :numref:`ua_driver`. + + + .. _UA_AFI_defaults: Calculating Default Airfoil Coefficients @@ -579,17 +595,195 @@ to set preprocessor variable ``UA_OUTS`` and recompile the program (OpenFAST, Ae The outputs are written in output files with extension `*.UA.out`. To activate these outputs with `cmake`, compile using ``-DCMAKE_Fortran_FLAGS="-DUA_OUTS=ON"`` +When using the driver, there is no need to use this preprocessor variable. + +.. _ua_aeroelasttheory: + +Aeroelastic simulation of a 2D section +-------------------------------------- + +Aeroelastic simulations of an isolated 2D section are possible using the driver in order to use the unsteady aerodynamic model in a simplified context. +See :numref:`ua_driver`. +The theory and description for the aeroelastic simulation can be found in +:cite:`ad-UAElast:torquepaper`. + + + + +.. _ua_driver: + Driver ------ -A driver is available to run simulations for a single airfoil, using sinusoidal variation of the angle of attack, -or user defined time series of angle of attack, relative wind speed and pitch rate. + +A driver is available to run simulations for a single airfoil. + +Different kind of simulations are possible: + + - using sinusoidal variation of the angle of attack, + - user defined time series of angle of attack, relative wind speed and pitch rate. + - aero elastic simulations with 3 degrees of freedom for the elastic motion of the section in it's 2D plane (flap, edge and torsion), with possibility to prescribe time series of the wind speed, or prescribe the motion of the section. + +The theory and description for the aeroelastic simulation can be found in :cite:`ad-UAElast:torquepaper`. + + + + + +Compilation +~~~~~~~~~~~ Using `cmake`, the driver is compiled using `make unsteadyaero_driver`, resulting as an executable in the `aerodyn` folder. -An example of driver input file is available here: :download:`here <../aerodyn-dynamicStall/examples/UA-driver.dvr>`. -An example of time series input is available here: :download:`here <../aerodyn-dynamicStall/examples/UA-driver-timeseries.dat>` + +Driver Inputs +~~~~~~~~~~~~~ + +An example of input file for the unsteady aerodynamic driver can be found in the `r-test repository `__. + + +The differente inputs are described below. + + + +**Environmental conditions** + + +``FldDens``: Density of working fluid (kg/m^3) + +``KinVisc``: Kinematic viscosity of working fluid (m^2/s) + +``SpdSound``: Speed of sound of working fluid (m/s) + + +**Unsteady aerodynamics options** + +``UAMod`` : Unsteady Aero Model Switch (switch) {2=B-L Gonzalez, 3=B-L Minnema/Pierce, 4=B-L HGM 4-states, 5=B-L 5 states, 6=Oye, 7=Boeing-Vertol} [used only when AFAeroMod=2] + +``FLookup`` : Flag to indicate whether a lookup for f' will be calculated (TRUE) or whether best-fit exponential equations will be used (FALSE); if FALSE S1-S4 must be provided in airfoil input files (flag) [used only when AFAeroMod=2] + + +**Airfoil properties** + +``AirFoil``: Airfoil table (Column 1: Angle of Attack (AoA), column 2: Lift coeff, column 3: Drag coeff). + +``Chord`` : Chord length (m) + +``Vec_AQ`` : Vector from reference point "A" to aerodynamic center (~quarter chord) "Q" in airfoil coordinates and in chord length. If "A" is at mid chord values are likely (0, -0.25) (-) + +``Vec_AT`` : Vector from reference point "A" to three-quarter chord point "T" in airfoil coordinates and in chord length. If "A" is at mid chord values are likely (0, 0.25) (-) + +``UseCm`` : Use Cm (moment coefficient) data in airfoil table {true/false} + + +**Simulation control** + +``SimMod``: Simulation model {1=reduced frequency model, 2=prescribed-aero time series, 3=elastic cross section} + + +**Reduced-frequency simulation** (``SimMod=1``) + +``InflowVel`` : Inflow velocity (m/s) + +``NCycles`` : Number of angle-of-attack oscillations over the length of the simulation (-) + +``StepsPerCycle`` : Number of timesteps per cycle (-) + +``Frequency`` : Frequency for the airfoil oscillations (Hz) + +``Amplitude`` : Amplitude of the angle of attack oscillations (deg) + +``Mean`` : Cycle mean (deg) + +``Phase`` : Initial phase (num steps). + + +**Prescribed aerodynamic simulation inputs** (``SimMod=2``) + +``TMax_PA`` : Total run time (s) + +``DT_PA`` : Recommended module time step (s) + +``AeroTSFile``: Time series data in delimited input file (e.g. csv) with 1 header line, 4 columns: Time (s), angle-of-attack (deg), InflowVel (m/s), Pitch rate (rad/s) + + +**Aeroelastic simulation** (``SimMod=3``) + +The theory for the aeroelastic simulation can be found in :numref:`ua_aeroelasttheory`. + +``TMax`` : Total run time (s) + +``DT`` : Time step (s). + +``ActiveDOF`` : List of Degrees of freedom that are active (true or false) + +``InitPos`` : List of initial positions for the elastic degrees of freedom (m, m and rad) + +``InitVel`` : List of initial velocities for the elastic degrees of freedom (m/s, m/s, and rad/s) + +``GFScalingL1`` : Generalized force scaling factors to convert from section loads to generalized loads (3x3). Three values per line. + +``MassMatrixL1`` : Mass matrix (3x3). Three values per line. + +``DampMatrixL1`` : Damping matrix (3x3). Three values per line. + +``StifMatrixL1`` : Stiffness matrix (3x3). Three values per line. + +``Twist`` : Fixed twist of the section when torsion degree of freedom is zero (deg) + +``InflowMod`` : Model for the inflow velocity. {1: constant velocity, 2: time series} + +``Inflow`` : Inflow velocity in x and y direction [used only when InflowMod=1] + +``InflowTSFile`` : Input file for inflow velocity. Delimited file (e.g. csv) with one header line, three columns: Time (s), Ux (m/s), Uy (m/s). [used only when InflowMod=2] + +``MotionMod`` : Model for the motion of the degrees of freedom {1: dynamic, 2: prescribed} + +``MotionTSFile`` : Input file for prescribed motion. Delimited file (e.g. csv) with one header line, 10 columns: Time (s), x (m), y (m), th (rad), velocities, and accelerations. [used only when InflowMod=2] + + +**Output control** + +``SumPrint`` : Write unsteady aerodynamics summary file (flag) + +``WrAFITables`` : Write back the aerodynamic coefficients used internally (flag) + + +**Example CSV input files** + +The unsteady aerodyn driver now relies on CSV files for it's input time series. +The time column does not need to be at a constant time step, but needs to be monotonously increasing. + +Prescribed aero input (``SimMod=2``): + +.. code: + + Time_[s] , Alpha_[deg] , VRel_[m/s] , omega_[rad/s] + 0.0 , 0 , 10 , 0 + 0.01 , 0 , 10 , 0 + + +Inflow file input (``SimMod=3``, ``InflowMod=2``): + +.. code: + + Time_[s] , Ux_[m/s], Uy_[m/s] + 0.0 , 1 , 10 + 1.0 , 2 , 10 + 5.0 , 2 , 8 + 10.0 , 1 , 12 + + +Motion file input (``SimMod=3``, ``MotionMod=2``) (note in this dummy exmaple velocities and accelerations are not provided, but preferably they should be): + +.. code: + + Time_[s] , x_[m] , y_[m] , th_[rad] , xd_[m/s] , yd_[m/s] , thd_[rad/s] , xdd_[m/s^2] , ydd_[m/s^2] , thdd_[rad/s^2] + 0.0 , 1 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0 + 1.0 , 2 , 2 , 2 , 0 , 0 , 0 , 0 , 0 , 0 + 5.0 , 2 , 2 , 2 , 0 , 0 , 0 , 0 , 0 , 0 + 10.0 , 1 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0