From 13b5a64beae4a880e1b113ee8c08ae04e724da2a Mon Sep 17 00:00:00 2001 From: Emmanuel Branlard Date: Tue, 4 Jan 2022 16:51:12 -0700 Subject: [PATCH 1/5] Lin: CalcSteady, forcing linearization at end of simulation --- modules/openfast-library/src/FAST_Lin.f90 | 11 +++++++++++ modules/openfast-library/src/FAST_Registry.txt | 1 + modules/openfast-library/src/FAST_Types.f90 | 7 +++++++ 3 files changed, 19 insertions(+) diff --git a/modules/openfast-library/src/FAST_Lin.f90 b/modules/openfast-library/src/FAST_Lin.f90 index 2a03635b84..00b030d554 100644 --- a/modules/openfast-library/src/FAST_Lin.f90 +++ b/modules/openfast-library/src/FAST_Lin.f90 @@ -293,6 +293,7 @@ SUBROUTINE Init_Lin(p_FAST, y_FAST, m_FAST, AD, ED, NumBl, NumBlNodes, ErrStat, m_FAST%Lin%n_rot = 0 m_FAST%Lin%IsConverged = .false. m_FAST%Lin%FoundSteady = .false. + m_FAST%Lin%ForceLin = .false. m_FAST%Lin%AzimIndx = 1 p_FAST%AzimDelta = TwoPi / p_FAST%NLinTimes @@ -5323,6 +5324,10 @@ SUBROUTINE FAST_CalcSteady( n_t_global, t_global, p_FAST, y_FAST, m_FAST, ED, BD ! interpolate to find y at the target azimuth call FAST_DiffInterpOutputs( m_FAST%Lin%AzimTarget(m_FAST%Lin%AzimIndx), p_FAST, y_FAST, m_FAST, ED, BD, SrvD, AD, IfW, HD, SD, ExtPtfm, MAPp, FEAM, MD, Orca, & IceF, IceD, ErrStat, ErrMsg ) + ! If linearization is forced + if (m_FAST%Lin%ForceLin) then + m_FAST%Lin%IsConverged = .True. + endif if (m_FAST%Lin%IsConverged .or. m_FAST%Lin%n_rot == 0) then ! save this operating point for linearization later m_FAST%Lin%LinTimes(m_FAST%Lin%AzimIndx) = t_global @@ -5346,6 +5351,12 @@ SUBROUTINE FAST_CalcSteady( n_t_global, t_global, p_FAST, y_FAST, m_FAST, ED, BD m_FAST%Lin%AzimIndx = 1 m_FAST%Lin%CopyOP_CtrlCode = MESH_UPDATECOPY end if + ! Forcing linearization if time is close to tmax + if ((t_global> p_FAST%TMax - 1.5*TwoPi_D/ED%y%RotSpeed) .and. .not.m_FAST%Lin%FoundSteady) then + call WrScr('') + call WrScr('[WARNING] Steady state not found before end of simulation. Forcing linearization') + m_FAST%Lin%ForceLin = .True. + endif end if end if diff --git a/modules/openfast-library/src/FAST_Registry.txt b/modules/openfast-library/src/FAST_Registry.txt index bfaf87a116..f6f9fadf4d 100644 --- a/modules/openfast-library/src/FAST_Registry.txt +++ b/modules/openfast-library/src/FAST_Registry.txt @@ -325,6 +325,7 @@ typedef ^ FAST_MiscLinType IntKi CopyOP_CtrlCode - - - "mesh control co typedef ^ FAST_MiscLinType DbKi AzimTarget {:} - - "target azimuth positions in CalcSteady algorithm" rad typedef ^ FAST_MiscLinType logical IsConverged - - - "whether the error calculation in the CalcSteady algorithm is converged" - typedef ^ FAST_MiscLinType logical FoundSteady - - - "whether the CalcSteady algorithm found a steady-state solution" - +typedef ^ FAST_MiscLinType logical ForceLin - - - "whether the CalcSteady algorithm found a steady-state solution" - typedef ^ FAST_MiscLinType IntKi n_rot - - - "number of rotations completed in CalcSteady algorithm" - typedef ^ FAST_MiscLinType IntKi AzimIndx - - - "index into target azimuth array in CalcSteady algorithm" - typedef ^ FAST_MiscLinType IntKi NextLinTimeIndx - - - "index for next time in LinTimes where linearization should occur" - diff --git a/modules/openfast-library/src/FAST_Types.f90 b/modules/openfast-library/src/FAST_Types.f90 index 801d11adf5..c7f0c39fa5 100644 --- a/modules/openfast-library/src/FAST_Types.f90 +++ b/modules/openfast-library/src/FAST_Types.f90 @@ -325,6 +325,7 @@ MODULE FAST_Types REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: AzimTarget !< target azimuth positions in CalcSteady algorithm [rad] LOGICAL :: IsConverged !< whether the error calculation in the CalcSteady algorithm is converged [-] LOGICAL :: FoundSteady !< whether the CalcSteady algorithm found a steady-state solution [-] + LOGICAL :: ForceLin !< whether the CalcSteady algorithm found a steady-state solution [-] INTEGER(IntKi) :: n_rot !< number of rotations completed in CalcSteady algorithm [-] INTEGER(IntKi) :: AzimIndx !< index into target azimuth array in CalcSteady algorithm [-] INTEGER(IntKi) :: NextLinTimeIndx !< index for next time in LinTimes where linearization should occur [-] @@ -14769,6 +14770,7 @@ SUBROUTINE FAST_CopyMiscLinType( SrcMiscLinTypeData, DstMiscLinTypeData, CtrlCod ENDIF DstMiscLinTypeData%IsConverged = SrcMiscLinTypeData%IsConverged DstMiscLinTypeData%FoundSteady = SrcMiscLinTypeData%FoundSteady + DstMiscLinTypeData%ForceLin = SrcMiscLinTypeData%ForceLin DstMiscLinTypeData%n_rot = SrcMiscLinTypeData%n_rot DstMiscLinTypeData%AzimIndx = SrcMiscLinTypeData%AzimIndx DstMiscLinTypeData%NextLinTimeIndx = SrcMiscLinTypeData%NextLinTimeIndx @@ -14901,6 +14903,7 @@ SUBROUTINE FAST_PackMiscLinType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Er END IF Int_BufSz = Int_BufSz + 1 ! IsConverged Int_BufSz = Int_BufSz + 1 ! FoundSteady + Int_BufSz = Int_BufSz + 1 ! ForceLin Int_BufSz = Int_BufSz + 1 ! n_rot Int_BufSz = Int_BufSz + 1 ! AzimIndx Int_BufSz = Int_BufSz + 1 ! NextLinTimeIndx @@ -14987,6 +14990,8 @@ SUBROUTINE FAST_PackMiscLinType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Er Int_Xferred = Int_Xferred + 1 IntKiBuf(Int_Xferred) = TRANSFER(InData%FoundSteady, IntKiBuf(1)) Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = TRANSFER(InData%ForceLin, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 IntKiBuf(Int_Xferred) = InData%n_rot Int_Xferred = Int_Xferred + 1 IntKiBuf(Int_Xferred) = InData%AzimIndx @@ -15130,6 +15135,8 @@ SUBROUTINE FAST_UnPackMiscLinType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Int_Xferred = Int_Xferred + 1 OutData%FoundSteady = TRANSFER(IntKiBuf(Int_Xferred), OutData%FoundSteady) Int_Xferred = Int_Xferred + 1 + OutData%ForceLin = TRANSFER(IntKiBuf(Int_Xferred), OutData%ForceLin) + Int_Xferred = Int_Xferred + 1 OutData%n_rot = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 OutData%AzimIndx = IntKiBuf(Int_Xferred) From 013ae029a9a633eb2c38df571fbfb614c8d513cf Mon Sep 17 00:00:00 2001 From: Emmanuel Branlard Date: Tue, 4 Jan 2022 19:11:04 -0700 Subject: [PATCH 2/5] Lin: Calcsteady with increased margin and using init rot speed --- modules/openfast-library/src/FAST_Lin.f90 | 20 +++++++++++++++----- modules/openfast-library/src/FAST_Subs.f90 | 6 ++++++ 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/modules/openfast-library/src/FAST_Lin.f90 b/modules/openfast-library/src/FAST_Lin.f90 index 00b030d554..9b8ea435a4 100644 --- a/modules/openfast-library/src/FAST_Lin.f90 +++ b/modules/openfast-library/src/FAST_Lin.f90 @@ -5351,11 +5351,21 @@ SUBROUTINE FAST_CalcSteady( n_t_global, t_global, p_FAST, y_FAST, m_FAST, ED, BD m_FAST%Lin%AzimIndx = 1 m_FAST%Lin%CopyOP_CtrlCode = MESH_UPDATECOPY end if - ! Forcing linearization if time is close to tmax - if ((t_global> p_FAST%TMax - 1.5*TwoPi_D/ED%y%RotSpeed) .and. .not.m_FAST%Lin%FoundSteady) then - call WrScr('') - call WrScr('[WARNING] Steady state not found before end of simulation. Forcing linearization') - m_FAST%Lin%ForceLin = .True. + ! Forcing linearization if time is close to tmax (with small margin) + if (.not.m_FAST%Lin%FoundSteady) then + if (ED%p%RotSpeed>0) then + if (t_global >= p_FAST%TMax - 2._DbKi*(TwoPi_D)/ED%p%RotSpeed) then + call WrScr('') + call WrScr('[WARNING] Steady state not found before end of simulation. Forcing linearization.') + m_FAST%Lin%ForceLin = .True. + endif + else + if (t_global >= p_FAST%TMax - 1.5_DbKi*p_FAST%DT) then + call WrScr('') + call WrScr('[WARNING] Steady state not found before end of simulation. Forcing linearization.') + m_FAST%Lin%ForceLin = .True. + endif + endif endif end if diff --git a/modules/openfast-library/src/FAST_Subs.f90 b/modules/openfast-library/src/FAST_Subs.f90 index 7a28e2cfc2..eed462a81e 100644 --- a/modules/openfast-library/src/FAST_Subs.f90 +++ b/modules/openfast-library/src/FAST_Subs.f90 @@ -6162,6 +6162,12 @@ SUBROUTINE FAST_Linearize_T(t_initial, n_t_global, Turbine, ErrStat, ErrMsg) if (Turbine%p_FAST%WrVTK == VTK_ModeShapes) CALL WrVTKCheckpoint() + if (Turbine%m_FAST%Lin%ForceLin) then + ErrStat2 = ErrID_Warn + ErrMsg2 = 'Linearization was forced at simulation end. The linearized model may not be sufficiently representative of the solution in steady state.' + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + endif + end if end if From 5ae23df45642759e769e72cd6ad44292aaf706cf Mon Sep 17 00:00:00 2001 From: Emmanuel Branlard Date: Tue, 4 Jan 2022 19:43:08 -0700 Subject: [PATCH 3/5] Lin: forced lin only if rotor speed closed to 0.1% of desired value --- modules/openfast-library/src/FAST_Lin.f90 | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/modules/openfast-library/src/FAST_Lin.f90 b/modules/openfast-library/src/FAST_Lin.f90 index 9b8ea435a4..644ad67e22 100644 --- a/modules/openfast-library/src/FAST_Lin.f90 +++ b/modules/openfast-library/src/FAST_Lin.f90 @@ -5351,13 +5351,15 @@ SUBROUTINE FAST_CalcSteady( n_t_global, t_global, p_FAST, y_FAST, m_FAST, ED, BD m_FAST%Lin%AzimIndx = 1 m_FAST%Lin%CopyOP_CtrlCode = MESH_UPDATECOPY end if - ! Forcing linearization if time is close to tmax (with small margin) + ! Forcing linearization if time is close to tmax (with sufficient margin) and error in rotor speed less than 0.1% if (.not.m_FAST%Lin%FoundSteady) then if (ED%p%RotSpeed>0) then if (t_global >= p_FAST%TMax - 2._DbKi*(TwoPi_D)/ED%p%RotSpeed) then - call WrScr('') - call WrScr('[WARNING] Steady state not found before end of simulation. Forcing linearization.') - m_FAST%Lin%ForceLin = .True. + if (abs(ED%y%RotSpeed-ED%p%RotSpeed)/ED%p%RotSpeed<0.001) then + call WrScr('') + call WrScr('[WARNING] Steady state not found before end of simulation. Forcing linearization.') + m_FAST%Lin%ForceLin = .True. + endif endif else if (t_global >= p_FAST%TMax - 1.5_DbKi*p_FAST%DT) then From 4abdd9936dc8ec673ecfcdcc8ee8a221330a6c43 Mon Sep 17 00:00:00 2001 From: Emmanuel Branlard Date: Tue, 4 Jan 2022 19:50:42 -0700 Subject: [PATCH 4/5] Lin: forced lin only if simulation more than 10 rev --- modules/openfast-library/src/FAST_Lin.f90 | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/modules/openfast-library/src/FAST_Lin.f90 b/modules/openfast-library/src/FAST_Lin.f90 index 644ad67e22..68ac872fef 100644 --- a/modules/openfast-library/src/FAST_Lin.f90 +++ b/modules/openfast-library/src/FAST_Lin.f90 @@ -5351,10 +5351,11 @@ SUBROUTINE FAST_CalcSteady( n_t_global, t_global, p_FAST, y_FAST, m_FAST, ED, BD m_FAST%Lin%AzimIndx = 1 m_FAST%Lin%CopyOP_CtrlCode = MESH_UPDATECOPY end if - ! Forcing linearization if time is close to tmax (with sufficient margin) and error in rotor speed less than 0.1% + ! Forcing linearization if time is close to tmax (with sufficient margin) if (.not.m_FAST%Lin%FoundSteady) then if (ED%p%RotSpeed>0) then - if (t_global >= p_FAST%TMax - 2._DbKi*(TwoPi_D)/ED%p%RotSpeed) then + ! If simulation is at least 10 revolutions, and error in rotor speed less than 0.1% + if ((p_FAST%TMax>10*(TwoPi_D)/ED%p%RotSpeed) .and. ( t_global >= p_FAST%TMax - 2._DbKi*(TwoPi_D)/ED%p%RotSpeed)) then if (abs(ED%y%RotSpeed-ED%p%RotSpeed)/ED%p%RotSpeed<0.001) then call WrScr('') call WrScr('[WARNING] Steady state not found before end of simulation. Forcing linearization.') From 975115f62bb12051f19d5fcdca385433de9d16e7 Mon Sep 17 00:00:00 2001 From: Emmanuel Branlard Date: Fri, 7 Jan 2022 13:34:05 -0700 Subject: [PATCH 5/5] Lin: force lin, performing only one lin at final time --- modules/openfast-library/src/FAST_Lin.f90 | 32 +++++++++------------- modules/openfast-library/src/FAST_Subs.f90 | 3 ++ 2 files changed, 16 insertions(+), 19 deletions(-) diff --git a/modules/openfast-library/src/FAST_Lin.f90 b/modules/openfast-library/src/FAST_Lin.f90 index 68ac872fef..3b603da049 100644 --- a/modules/openfast-library/src/FAST_Lin.f90 +++ b/modules/openfast-library/src/FAST_Lin.f90 @@ -5318,6 +5318,15 @@ SUBROUTINE FAST_CalcSteady( n_t_global, t_global, p_FAST, y_FAST, m_FAST, ED, BD ! this is the 2pi boundary, so we are either larger than the last target azimuth or less than the next one NextAzimuth = psi >= m_FAST%Lin%AzimTarget(m_FAST%Lin%AzimIndx) .and. psi < m_FAST%Lin%AzimTarget(m_FAST%Lin%AzimIndx-1) end if + + ! Forcing linearization if it's the last step + if (t_global >= p_FAST%TMax - 0.5_DbKi*p_FAST%DT) then + call WrScr('') + call WrScr('[WARNING] Steady state not found before end of simulation. Forcing linearization.') + m_FAST%Lin%ForceLin = .True. + m_FAST%Lin%AzimIndx = 1 + NextAzimuth = .True. + endif if (NextAzimuth) then @@ -5351,28 +5360,13 @@ SUBROUTINE FAST_CalcSteady( n_t_global, t_global, p_FAST, y_FAST, m_FAST, ED, BD m_FAST%Lin%AzimIndx = 1 m_FAST%Lin%CopyOP_CtrlCode = MESH_UPDATECOPY end if - ! Forcing linearization if time is close to tmax (with sufficient margin) - if (.not.m_FAST%Lin%FoundSteady) then - if (ED%p%RotSpeed>0) then - ! If simulation is at least 10 revolutions, and error in rotor speed less than 0.1% - if ((p_FAST%TMax>10*(TwoPi_D)/ED%p%RotSpeed) .and. ( t_global >= p_FAST%TMax - 2._DbKi*(TwoPi_D)/ED%p%RotSpeed)) then - if (abs(ED%y%RotSpeed-ED%p%RotSpeed)/ED%p%RotSpeed<0.001) then - call WrScr('') - call WrScr('[WARNING] Steady state not found before end of simulation. Forcing linearization.') - m_FAST%Lin%ForceLin = .True. - endif - endif - else - if (t_global >= p_FAST%TMax - 1.5_DbKi*p_FAST%DT) then - call WrScr('') - call WrScr('[WARNING] Steady state not found before end of simulation. Forcing linearization.') - m_FAST%Lin%ForceLin = .True. - endif - endif - endif end if end if + if (m_FAST%Lin%ForceLin) then + m_FAST%Lin%IsConverged=.true. + m_FAST%Lin%FoundSteady=.true. + endif END SUBROUTINE FAST_CalcSteady diff --git a/modules/openfast-library/src/FAST_Subs.f90 b/modules/openfast-library/src/FAST_Subs.f90 index eed462a81e..9b53f2b5b4 100644 --- a/modules/openfast-library/src/FAST_Subs.f90 +++ b/modules/openfast-library/src/FAST_Subs.f90 @@ -6131,6 +6131,9 @@ SUBROUTINE FAST_Linearize_T(t_initial, n_t_global, Turbine, ErrStat, ErrMsg) call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) if (Turbine%m_FAST%Lin%FoundSteady) then + if (Turbine%m_FAST%Lin%ForceLin) then + Turbine%p_FAST%NLinTimes=1 + endif do iLinTime=1,Turbine%p_FAST%NLinTimes t_global = Turbine%m_FAST%Lin%LinTimes(iLinTime)