Skip to content

Commit 90b1ba8

Browse files
authored
Merge pull request #3307 from OpenFAST/rc-5.0.1
Cross merge rc-5.0.1 progress to dev
2 parents 70694f1 + 005b790 commit 90b1ba8

22 files changed

Lines changed: 166 additions & 62 deletions

File tree

Binary file not shown.
718 Bytes
Binary file not shown.

docs/source/user/aerodyn/examples/NodalOutputs.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ END of input file (the word "END" must appear in the first 3 columns of this las
4141
"Clrnc" - Tower clearance at each node (based on the absolute distance to the nearest point in the tower from blade node B#N# minus the local tower radius, in the deflected configuration); please note that this clearance is only approximate because the calculation assumes that the blade is a line with no volume (however, the calculation does use the local tower radius); when blade node B#N# is above the tower top (or below the tower base), the absolute distance to the tower top (or base) minus the local tower radius, in the deflected configuration, is output
4242
"Vx" - Local axial velocity
4343
"Vy" - Local tangential velocity
44-
"GeomPhi" - Geometric phi? If phi was solved using normal BEMT equations, GeomPhi = 1; otherwise, if it was solved geometrically, GeomPhi = 0.
44+
"GeomPhi" - Geometric phi? If phi was solved using normal BEMT equations, GeomPhi = 0; otherwise, if it was solved geometrically, GeomPhi = 1.
4545
"Chi" - Skew angle (used in skewed wake correction) -- not available for OLAF
4646
"UA_Flag" - Flag indicating if UA is turned on for this node. -- not available for OLAF
4747
"CpMin" - Pressure coefficient

docs/source/user/api_change.rst

Lines changed: 43 additions & 8 deletions
Large diffs are not rendered by default.

docs/source/user/hydrodyn/index.rst

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ of HydroDyn.
3737
- :download:`Implementation Plan - 2nd-order Forces Within HydroDyn <../../../OtherSupporting/HydroDyn/HydroDyn_2ndOrderForces_Plan.pdf>`
3838
- :download:`Implementation Plan - 2nd-order Wave Kinematics Within HydroDyn <../../../OtherSupporting/HydroDyn/WAVE2_document.pdf>`
3939
- :download:`Plan for Adding Wave Stretching to HydroDyn <../../../OtherSupporting/HydroDyn/HydroDyn_WaveStretching_Plan.docx>`
40-
- :download:`Breaking Wave Modeling Approach for FAST <../../../OtherSupporting/HydroDyn/Breaking_Wave_Modeling_Approach_for_FAST.docx>`
4140

4241

4342
HydroDyn allows for multiple approaches for calculating the hydrodynamic

docs/source/user/hydrodyn/input_files.rst

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -429,11 +429,12 @@ must match the modes in the 1st-order WAMIT-style input files, i.e., the .1,
429429
.3, and .hst files. The convention for the WAMIT-style input files requires
430430
the first 6 modes to be rigid-body modes always, and the additional generalized
431431
modes are numbered from 7 onward. The total number of modes in the 1st-order
432-
WAMIT-style input files should be **6+NAddDOF** for each body. Currently, only
433-
one potential-flow body is allowed when additional degrees of freedom are used,
434-
requiring **NBody = 1**. In this case, the choice of **NBodyMod** does not
435-
matter. If more than one potential-flow bodies are present, **NAddDOF** should
436-
be populated with **NBody** zeros. This because, internally, HydroDyn supports
432+
WAMIT-style input files should be **6+NAddDOF** for each body.
433+
434+
Currently, only one potential-flow body is allowed when additional degrees of
435+
freedom are used, requiring **NBody = 1**. In this case, the choice of **NBodyMod**
436+
does not matter. If more than one potential-flow bodies are present, **NAddDOF**
437+
should be populated with **NBody** zeros. This because, internally, HydroDyn supports
437438
additional degrees of freedom for an arbitrary number of bodies with any of the
438439
**NBodyMod** options. The limitation of one potential-flow body only is due
439440
to constraints with coupling to ExtPtfm, the only module that can make use of the
@@ -442,6 +443,11 @@ been implemented for 2nd-order loads; therefore, the 2nd-order WAMIT-style input
442443
files, if included, should always contain **6NBody** modes irrespective of
443444
**NAddDOF**. Finally, when **NAddDOF > 0**, **WAMITULEN** must be 1.
444445

446+
In addition to being limited to one potential-flow body, **NAddDOF > 0** is only
447+
supported when **ExctnMod** = 0 or 1 and **RdtnMod** = 0 or 1. State-space
448+
wave-excitation and wave-radiation models are not supported. **NAddDOF** is not
449+
used when **PotMod** = 0 or 2.
450+
445451
Currently, the HydroDyn loads for the additional degrees of freedom can only be
446452
used by the ExtPtfm module of OpenFAST with externally generated structural
447453
mass (M), stiffness (K), and damping (C) matrices. This workflow is intended for

modules/aerodyn/src/AeroDyn.f90

Lines changed: 36 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1976,18 +1976,27 @@ subroutine AD_CalcWind(t, u, FLowField, p, m, o, Inflow, ErrStat, ErrMsg)
19761976
! OLAF points
19771977
if (allocated(o%WakeLocationPoints) .and. allocated(Inflow%InflowWakeVel)) then
19781978
! If rotor is MHK, add water depth to z coordinate
1979-
if (p%FVW%MHK > 0) then
1979+
if (p%FVW%MHK /= MHK_None) then
19801980
PosOffset = [0.0_ReKi, 0.0_ReKi, p%FVW%WtrDpth]
19811981
else
19821982
PosOffset = 0.0_ReKi
19831983
end if
19841984

1985-
call IfW_FlowField_GetVelAcc(FlowField, StartNode, t, &
1986-
o%WakeLocationPoints, &
1987-
Inflow%InflowWakeVel, &
1988-
NoAcc, ErrStat2, ErrMsg2, &
1989-
BoxExceedAllow=.true., PosOffset=PosOffset)
1990-
if(Failed()) return
1985+
if (p%FVW%MHK /= MHK_None .and. p%CompSeaSt) then ! MHK turbines with waves
1986+
call WaveField_GetWaveVelAcc_AD(p%WaveField, m%WaveField_m, &
1987+
StartNode, t, &
1988+
o%WakeLocationPoints, &
1989+
Inflow%InflowWakeVel, &
1990+
NoAcc, ErrStat2, ErrMsg2)
1991+
if(Failed()) return
1992+
else
1993+
call IfW_FlowField_GetVelAcc(FlowField, StartNode, t, &
1994+
o%WakeLocationPoints, &
1995+
Inflow%InflowWakeVel, &
1996+
NoAcc, ErrStat2, ErrMsg2, &
1997+
BoxExceedAllow=.true., PosOffset=PosOffset)
1998+
if(Failed()) return
1999+
end if
19912000
StartNode = StartNode + size(o%WakeLocationPoints)
19922001
end if
19932002

@@ -2034,7 +2043,7 @@ subroutine AD_CalcWind_Rotor(t, u, FlowField, p, p_AD, m, RotInflow, StartNode,
20342043
call WaveField_GetWaveVelAcc_AD(p_AD%WaveField, m%WaveField_m, StartNode, t, &
20352044
real(u%HubMotion%TranslationDisp + u%HubMotion%Position, ReKi), &
20362045
RotInflow%InflowOnHub, NoAcc, ErrStat2, ErrMsg2)
2037-
if(Failed()) return
2046+
if(Failed()) return
20382047
else
20392048
RotInflow%InflowOnHub = 0.0_ReKi
20402049
end if
@@ -2085,7 +2094,7 @@ subroutine AD_CalcWind_Rotor(t, u, FlowField, p, p_AD, m, RotInflow, StartNode,
20852094
call IfW_FlowField_GetVelAcc(FlowField, StartNode, t, &
20862095
real(u%HubMotion%TranslationDisp + u%HubMotion%Position, ReKi), &
20872096
RotInflow%InflowOnHub, NoAcc, ErrStat2, ErrMsg2, PosOffset=PosOffset)
2088-
if(Failed()) return
2097+
if(Failed()) return
20892098
else
20902099
RotInflow%InflowOnHub = 0.0_ReKi
20912100
end if
@@ -2469,7 +2478,7 @@ subroutine RotCavtCrit(u, p, m, errStat, errMsg)
24692478
SigmaCavitCrit = ( p%rotors(iR)%Patm + ( p%rotors(iR)%Gravity * ( abs( u%rotors(iR)%BladeMotion(j)%Position(3,i) + u%rotors(iR)%BladeMotion(j)%TranslationDisp(3,i) ) + p%rotors(iR)%MSL2SWL ) * p%rotors(iR)%airDens ) - p%rotors(iR)%Pvap ) / ( 0.5_ReKi * p%rotors(iR)%airDens * Vreltemp**2 ) ! Critical value of Sigma, cavitation occurs if local cavitation number is greater than this
24702479

24712480
if ( ( SigmaCavitCrit < SigmaCavit ) .and. ( .not. ( m%rotors(iR)%CavitWarnSet(i,j) ) ) ) then
2472-
call WrScr( NewLine//'Cavitation occurred at blade '//trim(num2lstr(j))//' and node '//trim(num2lstr(i))//'.' )
2481+
call WrScr( NewLine//'Cavitation occurred at rotor '//trim(num2lstr(iR))//', blade '//trim(num2lstr(j))//', and node '//trim(num2lstr(i))//'.' )
24732482
m%rotors(iR)%CavitWarnSet(i,j) = .true.
24742483
end if
24752484

@@ -3208,7 +3217,7 @@ end subroutine SetDisturbedInflow
32083217
!! Loop on blade nodes and computed a weighted sector average inflow at each node
32093218
subroutine SetSectAvgInflow(t, p, p_AD, u, RotInflow, m, errStat, errMsg)
32103219
real(DbKi), intent(in ) :: t !< Current simulation time in seconds
3211-
type(RotParameterType), intent(in ) :: p !< AD parameters
3220+
type(RotParameterType), intent(in ) :: p !< Rotor parameters
32123221
type(AD_ParameterType), intent(in ) :: p_AD !< AD parameters
32133222
type(RotInputType), intent(in ) :: u !< AD Inputs at Time
32143223
type(RotInflowType), intent(in ) :: RotInflow !< Rotor inflow at Time
@@ -3227,6 +3236,7 @@ subroutine SetSectAvgInflow(t, p, p_AD, u, RotInflow, m, errStat, errMsg)
32273236
real(ReKi) :: e_t(3) !< Polar unit vector perpendicular to rHA_perp ("e_theta")
32283237
real(ReKi) :: psi !< Azimuthal offset in the current sector, runs from -psi_bwd to psi_fwd
32293238
real(ReKi) :: dpsi !< Azimuthal increment
3239+
real(ReKi) :: PosOffset(3)!< IfW position offset for MHK turbines
32303240
real(ReKi), allocatable :: SectPos(:,:)!< Points used to define a given sector (for a given blade node A)
32313241
real(ReKi), allocatable :: SectVel(:,:)!< Inflow velocity at a given sector (Undisturbed and then disturbed)
32323242
real(ReKi), allocatable :: SectAcc(:,:)!< Inflow velocity at a given sector (Undisturbed and then disturbed)
@@ -3293,7 +3303,21 @@ subroutine SetSectAvgInflow(t, p, p_AD, u, RotInflow, m, errStat, errMsg)
32933303

32943304
! --- Inflow on sector points
32953305
! Undisturbed
3296-
call IfW_FlowField_GetVelAcc(p_AD%FlowField, 1, t, SectPos, SectVel, SectAcc, errStat=errStat2, errMsg=errMsg2); if(Failed()) return
3306+
if (p%MHK /= MHK_None .and. p_AD%CompSeaSt) then ! MHK turbines with waves
3307+
call WaveField_GetWaveVelAcc_AD(p_AD%WaveField, m%WaveField_m, 1_IntKi, t, &
3308+
SectPos, SectVel, SectAcc, ErrStat2, ErrMsg2)
3309+
if(Failed()) return
3310+
else
3311+
if (p%MHK /= MHK_None) then
3312+
PosOffset = [0.0_ReKi, 0.0_ReKi, p%WtrDpth]
3313+
else
3314+
PosOffset = 0.0_ReKi
3315+
end if
3316+
call IfW_FlowField_GetVelAcc(p_AD%FlowField, 1_IntKi, t, &
3317+
SectPos, SectVel, SectAcc, errStat=errStat2, errMsg=errMsg2, &
3318+
PosOffset=PosOffset); if(Failed()) return
3319+
end if
3320+
32973321
! --- Option 1 Disturbed inflow Before averaging - SectVel is modified in place
32983322
!if (p%TwrPotent /= TwrPotent_none .or. p%TwrShadow /= TwrShadow_none) then
32993323
! call TwrInflArray(p, u, RotInflow, m, SectPos, SectVel, errStat2, errMsg2); if(Failed()) return

modules/aerodyn/src/AeroDyn_Registry.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -517,6 +517,7 @@ typedef ^ RotMiscVarType ReKi TFinVrel_i 3 - - "Relative velocity at the refere
517517
typedef ^ RotMiscVarType ReKi TFinSTV_i 3 - - "Structural velocity at the reference point of the fin in the inertial system"
518518
typedef ^ RotMiscVarType ReKi TFinF_i 3 - - "Forces at the reference point of the fin in the inertial system"
519519
typedef ^ RotMiscVarType ReKi TFinM_i 3 - - "Moments at the reference point of the fin in the inertial system"
520+
typedef ^ RotMiscVarType GridInterp_MiscVarType WaveField_m - - - "misc var information from the GridInterp module"
520521

521522
typedef ^ MiscVarType RotMiscVarType rotors {:} - - "MiscVars for each rotor" -
522523
typedef ^ MiscVarType FVW_InputType FVW_u : - - "Inputs to the FVW module" -
@@ -525,7 +526,7 @@ typedef ^ MiscVarType FVW_MiscVarType FVW - - - "MiscVars from the FVW module" -
525526
typedef ^ MiscVarType ReKi WindPos {:}{:} - - "XYZ coordinates to query for wind velocity/acceleration" -
526527
typedef ^ MiscVarType ReKi WindVel {:}{:} - - "XYZ components of wind velocity" -
527528
typedef ^ MiscVarType ReKi WindAcc {:}{:} - - "XYZ components of wind acceleration" -
528-
typedef ^ MiscVarType GridInterp_MiscVarType WaveField_m - - - "misc var information from the SeaState WaveField module" -
529+
typedef ^ MiscVarType GridInterp_MiscVarType WaveField_m - - - "misc var information from the GridInterp module" -
529530
typedef ^ MiscVarType AD_InflowType Inflow {:} - - "Inflow storage (size of u for history of inputs)" -
530531
typedef ^ MiscVarType AD_InputType u_perturb - - - "input perturbation for linearization" -
531532
typedef ^ MiscVarType AD_OutputType y_lin - - - "output perturbation for linearization" -

modules/aerodyn/src/AeroDyn_Types.f90

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -557,6 +557,7 @@ MODULE AeroDyn_Types
557557
REAL(ReKi) , DIMENSION(1:3) :: TFinSTV_i = 0.0_ReKi !< Structural velocity at the reference point of the fin in the inertial system [-]
558558
REAL(ReKi) , DIMENSION(1:3) :: TFinF_i = 0.0_ReKi !< Forces at the reference point of the fin in the inertial system [-]
559559
REAL(ReKi) , DIMENSION(1:3) :: TFinM_i = 0.0_ReKi !< Moments at the reference point of the fin in the inertial system [-]
560+
TYPE(GridInterp_MiscVarType) :: WaveField_m !< misc var information from the GridInterp module [-]
560561
END TYPE RotMiscVarType
561562
! =======================
562563
! ========= AD_MiscVarType =======
@@ -568,7 +569,7 @@ MODULE AeroDyn_Types
568569
REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: WindPos !< XYZ coordinates to query for wind velocity/acceleration [-]
569570
REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: WindVel !< XYZ components of wind velocity [-]
570571
REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: WindAcc !< XYZ components of wind acceleration [-]
571-
TYPE(GridInterp_MiscVarType) :: WaveField_m !< misc var information from the SeaState WaveField module [-]
572+
TYPE(GridInterp_MiscVarType) :: WaveField_m !< misc var information from the GridInterp module [-]
572573
TYPE(AD_InflowType) , DIMENSION(:), ALLOCATABLE :: Inflow !< Inflow storage (size of u for history of inputs) [-]
573574
TYPE(AD_InputType) :: u_perturb !< input perturbation for linearization [-]
574575
TYPE(AD_OutputType) :: y_lin !< output perturbation for linearization [-]
@@ -5553,6 +5554,9 @@ subroutine AD_CopyRotMiscVarType(SrcRotMiscVarTypeData, DstRotMiscVarTypeData, C
55535554
DstRotMiscVarTypeData%TFinSTV_i = SrcRotMiscVarTypeData%TFinSTV_i
55545555
DstRotMiscVarTypeData%TFinF_i = SrcRotMiscVarTypeData%TFinF_i
55555556
DstRotMiscVarTypeData%TFinM_i = SrcRotMiscVarTypeData%TFinM_i
5557+
call GridInterp_CopyMisc(SrcRotMiscVarTypeData%WaveField_m, DstRotMiscVarTypeData%WaveField_m, CtrlCode, ErrStat2, ErrMsg2)
5558+
call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName)
5559+
if (ErrStat >= AbortErrLev) return
55565560
end subroutine
55575561

55585562
subroutine AD_DestroyRotMiscVarType(RotMiscVarTypeData, ErrStat, ErrMsg)
@@ -5776,6 +5780,8 @@ subroutine AD_DestroyRotMiscVarType(RotMiscVarTypeData, ErrStat, ErrMsg)
57765780
call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName)
57775781
call NWTC_Library_DestroyMeshMapType(RotMiscVarTypeData%T_P_2_T_L, ErrStat2, ErrMsg2)
57785782
call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName)
5783+
call GridInterp_DestroyMisc(RotMiscVarTypeData%WaveField_m, ErrStat2, ErrMsg2)
5784+
call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName)
57795785
end subroutine
57805786

57815787
subroutine AD_PackRotMiscVarType(RF, Indata)
@@ -5916,6 +5922,7 @@ subroutine AD_PackRotMiscVarType(RF, Indata)
59165922
call RegPack(RF, InData%TFinSTV_i)
59175923
call RegPack(RF, InData%TFinF_i)
59185924
call RegPack(RF, InData%TFinM_i)
5925+
call GridInterp_PackMisc(RF, InData%WaveField_m)
59195926
if (RegCheckErr(RF, RoutineName)) return
59205927
end subroutine
59215928

@@ -6083,6 +6090,7 @@ subroutine AD_UnPackRotMiscVarType(RF, OutData)
60836090
call RegUnpack(RF, OutData%TFinSTV_i); if (RegCheckErr(RF, RoutineName)) return
60846091
call RegUnpack(RF, OutData%TFinF_i); if (RegCheckErr(RF, RoutineName)) return
60856092
call RegUnpack(RF, OutData%TFinM_i); if (RegCheckErr(RF, RoutineName)) return
6093+
call GridInterp_UnpackMisc(RF, OutData%WaveField_m) ! WaveField_m
60866094
end subroutine
60876095

60886096
subroutine AD_CopyMisc(SrcMiscData, DstMiscData, CtrlCode, ErrStat, ErrMsg)

modules/aerodyn/src/FVW.f90

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1489,6 +1489,10 @@ subroutine FVW_CalcOutput(t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMsg)
14891489
character(*), intent( out) :: ErrMsg !< Error message if ErrStat /= ErrID_None
14901490
! Local variables
14911491
integer(IntKi) :: nP
1492+
integer(IntKi) :: iStepFVW
1493+
logical, save :: FirstNotice_FreeNearWake = .true.
1494+
logical, save :: FirstNotice_NearWake = .true.
1495+
logical, save :: FirstNotice_FullWake = .true.
14921496
integer(IntKi) :: ErrStat2
14931497
character(ErrMsgLen) :: ErrMsg2
14941498
character(*), parameter :: RoutineName = 'FVW_CalcOutput'
@@ -1514,23 +1518,24 @@ subroutine FVW_CalcOutput(t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMsg)
15141518
endif
15151519

15161520
! Write some info to screen when major milestone achieved
1517-
if (m%iStep == p%nNWFree .and. p%nNWFree<p%nNWMax) then
1518-
nP = CountCPs(p, p%nNWFree, 0)
1519-
call WrScr(NewLine//'[INFO] OLAF free near wake is at full extent - '//trim(num2lstr(t))//'s, '//trim(num2lstr(nP))//' points.')
1520-
endif
1521-
if (m%iStep == p%nNWMax) then
1522-
nP = CountCPs(p, p%nNWMax, 0)
1523-
if (p%nFWMax==0) then
1524-
call WrScr(NewLine//'[INFO] OLAF wake is at full extent - '//trim(num2lstr(t))//'s, '//trim(num2lstr(nP))//' points.')
1525-
else
1526-
call WrScr(NewLine//'[INFO] OLAF near wake is at full extent - '//trim(num2lstr(t))//'s, '//trim(num2lstr(nP))//' points.')
1527-
endif
1528-
endif
1529-
if (p%nFWMax>0 .and. m%iStep== p%nNWMax+p%nFWMax) then
1521+
iStepFVW = floor(t/p%DTfvw+1.0E-6_DbKi)
1522+
if (FirstNotice_FullWake .and. iStepFVW == p%nNWMax+p%nFWMax) then
15301523
nP = CountCPs(p, p%nNWMax, p%nFWMax)
15311524
call WrScr(NewLine//'[INFO] OLAF wake is at full extent - '//trim(num2lstr(t))//'s, '//trim(num2lstr(nP))//' points.')
1532-
endif
1533-
1525+
FirstNotice_FullWake = .false.
1526+
FirstNotice_NearWake = .false.
1527+
FirstNotice_FreeNearWake = .false.
1528+
elseif (FirstNotice_NearWake .and. iStepFVW == p%nNWMax) then ! implies p%nFWMax > 0
1529+
nP = CountCPs(p, p%nNWMax, 0_IntKi)
1530+
call WrScr(NewLine//'[INFO] OLAF near wake is at full extent - '//trim(num2lstr(t))//'s, '//trim(num2lstr(nP))//' points.')
1531+
FirstNotice_NearWake = .false.
1532+
FirstNotice_FreeNearWake = .false.
1533+
elseif (FirstNotice_FreeNearWake .and. iStepFVW == p%nNWFree) then ! implies p%nNWFree<p%nNWMax
1534+
nP = CountCPs(p, p%nNWFree, 0_IntKi)
1535+
call WrScr(NewLine//'[INFO] OLAF free near wake is at full extent - '//trim(num2lstr(t))//'s, '//trim(num2lstr(nP))//' points.')
1536+
FirstNotice_FreeNearWake = .false.
1537+
end if
1538+
15341539
! --- Export to VTK
15351540
if (m%VTKstep==-1) then
15361541
! Has never been called, special handling for init

0 commit comments

Comments
 (0)