Skip to content

Commit 2f7a619

Browse files
authored
Merge pull request #3321 from andrew-platt/b/SlD-SD_react_loads_backport3319
Backport #3319 SoilDyn/SubDyn: reaction loads when REDWIN is used
2 parents b81d820 + a1bb1e8 commit 2f7a619

6 files changed

Lines changed: 58 additions & 34 deletions

File tree

‎modules/openfast-library/src/FAST_Subs.f90‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -907,6 +907,9 @@ SUBROUTINE FAST_InitializeAll( t_initial, m_Glue, p_FAST, y_FAST, m_FAST, ED, SE
907907
SlD%y, SlD%m, dt_module, Init%OutData_SlD, ErrStat2, ErrMsg2)
908908
if (Failed()) return
909909

910+
! Pass nonlinear flag to SubDyn: true only when REDWIN DLL is active (CalcOption=3)
911+
Init%InData_SD%SlDNonLinear = SlD%p%UseREDWINinterface ! REDWIN DLL returning nonlinear soil reaction forces
912+
910913
! Add module to list of modules, return on error
911914
CALL MV_AddModule(m_Glue%ModData, Module_SlD, 'SlD', 1, dt_module, p_FAST%DT, &
912915
Init%OutData_SlD%Vars, p_FAST%Linearize, ErrStat2, ErrMsg2)

‎modules/soildyn/src/SoilDyn.f90‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,9 +109,11 @@ subroutine SlD_Init(InitInp, u, p, x, xd, z, OtherState, y, m, Interval, InitOut
109109
z%DummyConstrState = 0.0_ReKi
110110
OtherState%DummyOtherState = 0.0_ReKi
111111

112-
! are the returned reaction forces only the non-linear portion (used when SubDyn is calculating the linear portion)
112+
! The linear soil stiffness is passed directly to SubDyn as a stiffness matrix (not as a load)
113+
! The nonlinear portion of reaction forces is only computed when REDWIN DLL is active and passed as loads.
113114
p%SlDNonLinearForcePortionOnly = InitInp%SlDNonLinearForcePortionOnly
114-
if (p%SlDNonLinearForcePortionOnly) call WrScr(' SoilDyn returning only non-linear portion of reaction forces')
115+
call WrScr(' SoilDyn: linear stiffness passed directly to SubDyn as a stiffness matrix')
116+
if (p%CalcOption == Calc_REDWIN) call WrScr(' SoilDyn: nonlinear soil reaction loads computed by REDWIN')
115117

116118
! If the module does not implement the four Jacobian routines at the end of this template, or the module cannot
117119
! linearize with the features that are enabled, stop the simulation if InitInp%Linearize is true.

‎modules/subdyn/src/SubDyn.f90‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -479,6 +479,9 @@ SUBROUTINE SD_Init( InitInput, u, p, x, xd, z, OtherState, y, m, Interval, InitO
479479
! Initialize the outputs & Store mapping between nodes and elements
480480
CALL SDOUT_Init( Init, y, p, m, InitOut, InitInput%WtrDpth, ErrStat2, ErrMsg2 ); if(Failed()) return
481481

482+
! Flag from glue code: if SoilDyn is returning nonlinear loads
483+
p%SlDNonLinear = InitInput%SlDNonLinear
484+
482485
! Determine if we need to perform output file handling
483486
IF ( p%OutSwtch == 1 .OR. p%OutSwtch == 3 ) THEN
484487
CALL SDOUT_OpenOutput( SD_ProgDesc, Init%RootName, p, InitOut, ErrStat2, ErrMsg2 ); if(Failed()) return

‎modules/subdyn/src/SubDyn_Output.f90‎

Lines changed: 38 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -443,39 +443,45 @@ SUBROUTINE SDOut_MapOutputs(u,p,x, y, m, AllOuts, ErrStat, ErrMsg )
443443
! --------------------------------------------------------------------------------{
444444
! Total base reaction forces and moments at the (0.,0.,-WtrDpth) location in SS coordinate system
445445
! "ReactFXss, ReactFYss, ReactFZss, ReactMXss, ReactMYss, ReactMZss"
446-
IF (p%OutReact) THEN
447-
ALLOCATE ( ReactNs(6*p%nNodes_C), STAT = ErrStat )
448-
IF ( ErrStat /= ErrID_None ) THEN
449-
ErrMsg = ' Error allocating space for ReactNs array.'
450-
ErrStat = ErrID_Fatal
451-
RETURN
452-
END IF
453-
ReactNs = 0.0_ReKi !Initialize
454-
DO I=1,p%nNodes_C !Do for each constrained node, they are ordered as given in the input file and so as in the order of y2mesh
455-
FK_elm2=0._ReKi !Initialize for cumulative force
456-
FM_elm2=0._ReKi !Initialize
457-
pLst => p%MOutLst3(I)
458-
!Find the joint forces
459-
DO J=1,SIZE(pLst%ElmIDs(1,:)) !for all the elements connected (normally 1)
460-
iiNode = 1
461-
call ElementForce(pLst, iiNode, J, FM_elm, FK_elm, sgn, DIRCOS, .false.)
462-
!transform back to global, need to do 3 at a time since cosine matrix is 3x3
463-
DO L=1,2
464-
FM_elm2((L-1)*3+1:L*3) = FM_elm2((L-1)*3+1:L*3) + matmul(transpose(DIRCOS),FM_elm((L-1)*3+1:L*3)) !sum forces at joint in GLOBAL REF
465-
FK_elm2((L-1)*3+1:L*3) = FK_elm2((L-1)*3+1:L*3) + matmul(transpose(DIRCOS),FK_elm((L-1)*3+1:L*3)) !signs may be wrong, we will fix that later;
466-
! I believe this is all fixed in terms of signs now ,RRD 5/20/13
467-
ENDDO
446+
IF (p%OutReact) THEN
447+
IF (p%SlDNonLinear) THEN
448+
! When SoilDyn nonlinear loads are active (e.g., SoilDyn CalcOption = 3), SubDyn reaction loads are incomplete (only the linear part is included)
449+
! The total reaction at each base reaction joint is available in the SoilDyn output sensors (e.g., "Sld1Fxg Sld1Fyg Sld1Fzg Sld1Mxg Sld1Myg Sld1Mzg")
450+
AllOuts( ReactSS(1:nDOFL_TP) ) = NaN
451+
ELSE
452+
ALLOCATE ( ReactNs(6*p%nNodes_C), STAT = ErrStat )
453+
IF ( ErrStat /= ErrID_None ) THEN
454+
ErrMsg = ' Error allocating space for ReactNs array.'
455+
ErrStat = ErrID_Fatal
456+
RETURN
457+
END IF
458+
ReactNs = 0.0_ReKi !Initialize
459+
DO I=1,p%nNodes_C !Do for each constrained node, they are ordered as given in the input file and so as in the order of y2mesh
460+
FK_elm2=0._ReKi !Initialize for cumulative force
461+
FM_elm2=0._ReKi !Initialize
462+
pLst => p%MOutLst3(I)
463+
!Find the joint forces
464+
DO J=1,SIZE(pLst%ElmIDs(1,:)) !for all the elements connected (normally 1)
465+
iiNode = 1
466+
call ElementForce(pLst, iiNode, J, FM_elm, FK_elm, sgn, DIRCOS, .false.)
467+
!transform back to global, need to do 3 at a time since cosine matrix is 3x3
468+
DO L=1,2
469+
FM_elm2((L-1)*3+1:L*3) = FM_elm2((L-1)*3+1:L*3) + matmul(transpose(DIRCOS),FM_elm((L-1)*3+1:L*3)) !sum forces at joint in GLOBAL REF
470+
FK_elm2((L-1)*3+1:L*3) = FK_elm2((L-1)*3+1:L*3) + matmul(transpose(DIRCOS),FK_elm((L-1)*3+1:L*3)) !signs may be wrong, we will fix that later;
471+
! I believe this is all fixed in terms of signs now ,RRD 5/20/13
472+
ENDDO
473+
ENDDO
474+
! FK_elm2 ! + FM_elm2 !removed the inertial component 12/13 !Not sure why I need an intermediate step here, but the sum would not work otherwise
475+
! NEED TO ADD HYDRODYNAMIC FORCES AT THE RESTRAINT NODES
476+
iSDNode = p%Nodes_C(I,1)
477+
iMeshNode = iSDNode ! input and Y2 mesh nodes are the same as subdyn
478+
Fext = (/ u%LMesh%Force(:,iMeshNode), u%LMesh%Moment(:,iMeshNode) /) + p%FG(p%NodesDOF(iMeshNode)%List(1:6))
479+
Fext(1:3) = Fext(1:3) + p%FC(p%NodesDOF(iMeshNode)%List(1:3))
480+
ReactNs((I-1)*6+1:6*I) = FK_elm2 - Fext !Accumulate reactions from all nodes in GLOBAL COORDINATES
468481
ENDDO
469-
! FK_elm2 ! + FM_elm2 !removed the inertial component 12/13 !Not sure why I need an intermediate step here, but the sum would not work otherwise
470-
! NEED TO ADD HYDRODYNAMIC FORCES AT THE RESTRAINT NODES
471-
iSDNode = p%Nodes_C(I,1)
472-
iMeshNode = iSDNode ! input and Y2 mesh nodes are the same as subdyn
473-
Fext = (/ u%LMesh%Force(:,iMeshNode), u%LMesh%Moment(:,iMeshNode) /) + p%FG(p%NodesDOF(iMeshNode)%List(1:6))
474-
Fext(1:3) = Fext(1:3) + p%FC(p%NodesDOF(iMeshNode)%List(1:3))
475-
ReactNs((I-1)*6+1:6*I) = FK_elm2 - Fext !Accumulate reactions from all nodes in GLOBAL COORDINATES
476-
ENDDO
477-
! Store into AllOuts
478-
AllOuts( ReactSS(1:nDOFL_TP) ) = matmul(p%TIreact,ReactNs)
482+
! Store into AllOuts
483+
AllOuts( ReactSS(1:nDOFL_TP) ) = matmul(p%TIreact,ReactNs)
484+
ENDIF
479485
ENDIF
480486
if (allocated(ReactNs)) deallocate(ReactNs)
481487
contains

‎modules/subdyn/src/SubDyn_Registry.txt‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ typedef ^ InitInputType ReKi TP_RefPoint {3}{:} - - "global pos
7878
typedef ^ InitInputType ReKi SubRotateZ - - - "Rotation angle in degrees about global Z"
7979
typedef ^ InitInputType ReKi SoilStiffness ::: - - "Soil stiffness matrices from SoilDyn" '(N/m, N-m/rad)'
8080
typedef ^ InitInputType MeshType SoilMesh - - - "Mesh for soil stiffness locations" -
81+
typedef ^ InitInputType Logical SlDNonLinear - - - "Flag indicating that SoilDyn is returning nonlinear loads"
8182
typedef ^ InitInputType Logical Linearize - .FALSE. - "Flag that tells this module if the glue code wants to linearize." -
8283

8384
# ============================== Initialization outputs ============================================================================================================================================
@@ -208,6 +209,7 @@ typedef ^ ParameterType IntKi nDOFM - - - "retained degrees of fr
208209
typedef ^ ParameterType IntKi nDOFRB - - - "number of rigid-body modes"
209210
typedef ^ ParameterType IntKi SttcSolve - - - "Solve dynamics about static equilibrium point (flag)"
210211
typedef ^ ParameterType Logical Floating - - - "True if floating bottom (the 6 DOF are free at all reaction nodes)"
212+
typedef ^ ParameterType Logical SlDNonLinear - - - "Flag indicating that SoilDyn is returning nonlinear loads"
211213
typedef ^ ParameterType ReKi KMMDiag {:} - - "Diagonal coefficients of Kmm (OmegaM squared)"
212214
typedef ^ ParameterType ReKi CMMDiag {:} - - "Diagonal coefficients of Cmm (~2 Zeta OmegaM))"
213215
typedef ^ ParameterType ReKi MMB {:}{:} - - "Matrix after C-B reduction (transpose of MBM"

‎modules/subdyn/src/SubDyn_Types.f90‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ MODULE SubDyn_Types
115115
REAL(ReKi) :: SubRotateZ = 0.0_ReKi !< Rotation angle in degrees about global Z [-]
116116
REAL(ReKi) , DIMENSION(:,:,:), ALLOCATABLE :: SoilStiffness !< Soil stiffness matrices from SoilDyn ['(N/m,]
117117
TYPE(MeshType) :: SoilMesh !< Mesh for soil stiffness locations [-]
118+
LOGICAL :: SlDNonLinear = .false. !< Flag indicating that SoilDyn is returning nonlinear loads [-]
118119
LOGICAL :: Linearize = .FALSE. !< Flag that tells this module if the glue code wants to linearize. [-]
119120
END TYPE SD_InitInputType
120121
! =======================
@@ -258,6 +259,7 @@ MODULE SubDyn_Types
258259
INTEGER(IntKi) :: nDOFRB = 0_IntKi !< number of rigid-body modes [-]
259260
INTEGER(IntKi) :: SttcSolve = 0_IntKi !< Solve dynamics about static equilibrium point (flag) [-]
260261
LOGICAL :: Floating = .false. !< True if floating bottom (the 6 DOF are free at all reaction nodes) [-]
262+
LOGICAL :: SlDNonLinear = .false. !< Flag indicating that SoilDyn is returning nonlinear loads [-]
261263
REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: KMMDiag !< Diagonal coefficients of Kmm (OmegaM squared) [-]
262264
REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: CMMDiag !< Diagonal coefficients of Cmm (~2 Zeta OmegaM)) [-]
263265
REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: MMB !< Matrix after C-B reduction (transpose of MBM [-]
@@ -987,6 +989,7 @@ subroutine SD_CopyInitInput(SrcInitInputData, DstInitInputData, CtrlCode, ErrSta
987989
call MeshCopy(SrcInitInputData%SoilMesh, DstInitInputData%SoilMesh, CtrlCode, ErrStat2, ErrMsg2 )
988990
call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName)
989991
if (ErrStat >= AbortErrLev) return
992+
DstInitInputData%SlDNonLinear = SrcInitInputData%SlDNonLinear
990993
DstInitInputData%Linearize = SrcInitInputData%Linearize
991994
end subroutine
992995

@@ -1023,6 +1026,7 @@ subroutine SD_PackInitInput(RF, Indata)
10231026
call RegPack(RF, InData%SubRotateZ)
10241027
call RegPackAlloc(RF, InData%SoilStiffness)
10251028
call MeshPack(RF, InData%SoilMesh)
1029+
call RegPack(RF, InData%SlDNonLinear)
10261030
call RegPack(RF, InData%Linearize)
10271031
if (RegCheckErr(RF, RoutineName)) return
10281032
end subroutine
@@ -1044,6 +1048,7 @@ subroutine SD_UnPackInitInput(RF, OutData)
10441048
call RegUnpack(RF, OutData%SubRotateZ); if (RegCheckErr(RF, RoutineName)) return
10451049
call RegUnpackAlloc(RF, OutData%SoilStiffness); if (RegCheckErr(RF, RoutineName)) return
10461050
call MeshUnpack(RF, OutData%SoilMesh) ! SoilMesh
1051+
call RegUnpack(RF, OutData%SlDNonLinear); if (RegCheckErr(RF, RoutineName)) return
10471052
call RegUnpack(RF, OutData%Linearize); if (RegCheckErr(RF, RoutineName)) return
10481053
end subroutine
10491054

@@ -2413,6 +2418,7 @@ subroutine SD_CopyParam(SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMsg)
24132418
DstParamData%nDOFRB = SrcParamData%nDOFRB
24142419
DstParamData%SttcSolve = SrcParamData%SttcSolve
24152420
DstParamData%Floating = SrcParamData%Floating
2421+
DstParamData%SlDNonLinear = SrcParamData%SlDNonLinear
24162422
if (allocated(SrcParamData%KMMDiag)) then
24172423
LB(1:1) = lbound(SrcParamData%KMMDiag)
24182424
UB(1:1) = ubound(SrcParamData%KMMDiag)
@@ -3466,6 +3472,7 @@ subroutine SD_PackParam(RF, Indata)
34663472
call RegPack(RF, InData%nDOFRB)
34673473
call RegPack(RF, InData%SttcSolve)
34683474
call RegPack(RF, InData%Floating)
3475+
call RegPack(RF, InData%SlDNonLinear)
34693476
call RegPackAlloc(RF, InData%KMMDiag)
34703477
call RegPackAlloc(RF, InData%CMMDiag)
34713478
call RegPackAlloc(RF, InData%MMB)
@@ -3666,6 +3673,7 @@ subroutine SD_UnPackParam(RF, OutData)
36663673
call RegUnpack(RF, OutData%nDOFRB); if (RegCheckErr(RF, RoutineName)) return
36673674
call RegUnpack(RF, OutData%SttcSolve); if (RegCheckErr(RF, RoutineName)) return
36683675
call RegUnpack(RF, OutData%Floating); if (RegCheckErr(RF, RoutineName)) return
3676+
call RegUnpack(RF, OutData%SlDNonLinear); if (RegCheckErr(RF, RoutineName)) return
36693677
call RegUnpackAlloc(RF, OutData%KMMDiag); if (RegCheckErr(RF, RoutineName)) return
36703678
call RegUnpackAlloc(RF, OutData%CMMDiag); if (RegCheckErr(RF, RoutineName)) return
36713679
call RegUnpackAlloc(RF, OutData%MMB); if (RegCheckErr(RF, RoutineName)) return

0 commit comments

Comments
 (0)