From 115fddd8ed6173660b3b414e4b6ec767b97954ef Mon Sep 17 00:00:00 2001 From: RyanDavies19 Date: Sun, 22 Feb 2026 15:31:49 -0800 Subject: [PATCH 1/6] Change MoorDyn warning string for output files to remove too specific of suggested change. --- modules/moordyn/src/MoorDyn_IO.f90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/moordyn/src/MoorDyn_IO.f90 b/modules/moordyn/src/MoorDyn_IO.f90 index 3061b350f9..5d86177039 100644 --- a/modules/moordyn/src/MoorDyn_IO.f90 +++ b/modules/moordyn/src/MoorDyn_IO.f90 @@ -631,7 +631,7 @@ SUBROUTINE MDIO_ProcessOutList(OutList, p, m, y, InitOut, ErrStat, ErrMsg ) ! error ELSE CALL DenoteInvalidOutput(p%OutParam(I)) ! flag as invalid - CALL WrScr('Warning: invalid output specifier '//trim(OutListTmp)//'. Must start with L, R, or B') + CALL WrScr('Warning: invalid output specifier '//trim(OutListTmp)//'.') CYCLE END IF From d254da2b2375c2d55e966b9bb65b83562eea0590 Mon Sep 17 00:00:00 2001 From: RyanDavies19 Date: Mon, 17 Nov 2025 16:05:17 -0800 Subject: [PATCH 2/6] MD: Add ramp time for water kinematics --- modules/moordyn/src/MoorDyn.f90 | 2 ++ modules/moordyn/src/MoorDyn_IO.f90 | 4 ++-- modules/moordyn/src/MoorDyn_Misc.f90 | 8 ++++++++ modules/moordyn/src/MoorDyn_Registry.txt | 3 ++- modules/moordyn/src/MoorDyn_Types.f90 | 4 ++++ 5 files changed, 18 insertions(+), 3 deletions(-) diff --git a/modules/moordyn/src/MoorDyn.f90 b/modules/moordyn/src/MoorDyn.f90 index 67191d4609..7d72a0f5cc 100644 --- a/modules/moordyn/src/MoorDyn.f90 +++ b/modules/moordyn/src/MoorDyn.f90 @@ -487,6 +487,8 @@ SUBROUTINE MD_Init(InitInp, u, p, x, xd, z, other, y, m, DTcoupling, InitOut, Er read (OptValue,*) p%inertialF else if ( OptString == 'INERTIALF_RAMPT') then read (OptValue,*) p%inertialF_rampT + else if ( OptString == 'WAVEKIN_RAMPT') then + read (OptValue,*) p%waveKin_rampT else if ( OptString == 'OUTSWITCH') then read (OptValue,*) p%OutSwitch else if ( OptString == 'DISABLEOUTTIME') then diff --git a/modules/moordyn/src/MoorDyn_IO.f90 b/modules/moordyn/src/MoorDyn_IO.f90 index 5d86177039..2da76623ba 100644 --- a/modules/moordyn/src/MoorDyn_IO.f90 +++ b/modules/moordyn/src/MoorDyn_IO.f90 @@ -1668,8 +1668,8 @@ SUBROUTINE MDIO_WriteOutputs( Time, p, m, y, ErrStat, ErrMsg ) ! calculate number of output entries to write for this line !LineNumOuts = 3*(m%LineList(I)%N + 1)*SUM(m%LineList(I)%OutFlagList(2:5)) + m%LineList(I)%N*SUM(m%LineList(I)%OutFlagList(6:9)) - LineNumOuts = 3*(m%LineList(I)%N + 1)*SUM(m%LineList(I)%OutFlagList(2:6)) & - + (m%LineList(I)%N + 1)*SUM(m%LineList(I)%OutFlagList(7:9)) & + LineNumOuts = 3*(m%LineList(I)%N + 1)*SUM(m%LineList(I)%OutFlagList(2:7)) & + + (m%LineList(I)%N + 1)*SUM(m%LineList(I)%OutFlagList(8:9)) & + m%LineList(I)%N*SUM(m%LineList(I)%OutFlagList(10:18)) if (m%LineList(I)%OutFlagList(2) == 1) THEN ! if node positions are included, make them using a float format for higher precision diff --git a/modules/moordyn/src/MoorDyn_Misc.f90 b/modules/moordyn/src/MoorDyn_Misc.f90 index 3c661f1766..92ee7a610c 100644 --- a/modules/moordyn/src/MoorDyn_Misc.f90 +++ b/modules/moordyn/src/MoorDyn_Misc.f90 @@ -1033,6 +1033,14 @@ SUBROUTINE getWaterKin(p, m, x, y, z, t, U, Ud, zeta, PDyn, ErrStat, ErrMsg) call SetErrStat(ErrID_Fatal, "Invalid value of p%WaterKin", ErrStat, ErrMsg, RoutineName) end select + ! Apply ramp time + IF (t < p%waveKin_rampT) THEN + U = U * t / p%waveKin_rampT + Ud = Ud * t / p%waveKin_rampT + zeta = zeta * t / p%waveKin_rampT + PDyn = PDyn * t / p%waveKin_rampT + END IF + END SUBROUTINE getWaterKin ! ----- process WaterKin input value, potentially reading wave inputs and generating wave field ----- diff --git a/modules/moordyn/src/MoorDyn_Registry.txt b/modules/moordyn/src/MoorDyn_Registry.txt index 210b98cf0b..e4a44d1082 100644 --- a/modules/moordyn/src/MoorDyn_Registry.txt +++ b/modules/moordyn/src/MoorDyn_Registry.txt @@ -407,7 +407,8 @@ typedef ^ ^ DbKi mu_kA - typedef ^ ^ DbKi mc - - - "ratio of the static friction coefficient to the kinetic friction coefficient" "(-)" typedef ^ ^ DbKi cv - - - "saturated damping coefficient" "(-)" typedef ^ ^ IntKi inertialF - 0 - "Indicates MoorDyn returning inertial moments for coupled 6DOF objects. 0: no, 1: yes, 2: yes with ramp to inertialF_rampT" - -typedef ^ ^ R8Ki inertialF_rampT - 30 - "Ramp time for inertial forces" - +typedef ^ ^ R8Ki inertialF_rampT - 30 - "Ramp time for inertial forces" - +typedef ^ ^ R8Ki waveKin_rampT - 0 - "Ramp time for water kinematics" - typedef ^ ^ IntKi OutSwitch - 1 - "Switch to disable outputs when running with full OF. 0: no MD main outfile, 1: write MD main outfile" "(-)" typedef ^ ^ IntKi disableOutTime - 0 - "Disables the printing of the fairtens and timestep in init to the console, useful for the MATLAB wrapper" "(-)" # --- parameters for wave and current --- diff --git a/modules/moordyn/src/MoorDyn_Types.f90 b/modules/moordyn/src/MoorDyn_Types.f90 index 86703d7aa7..7026430e79 100644 --- a/modules/moordyn/src/MoorDyn_Types.f90 +++ b/modules/moordyn/src/MoorDyn_Types.f90 @@ -444,6 +444,7 @@ MODULE MoorDyn_Types REAL(DbKi) :: cv = 0.0_R8Ki !< saturated damping coefficient [(-)] INTEGER(IntKi) :: inertialF = 0 !< Indicates MoorDyn returning inertial moments for coupled 6DOF objects. 0: no, 1: yes, 2: yes with ramp to inertialF_rampT [-] REAL(R8Ki) :: inertialF_rampT = 30 !< Ramp time for inertial forces [-] + REAL(R8Ki) :: waveKin_rampT = 0 !< Ramp time for water kinematics [-] INTEGER(IntKi) :: OutSwitch = 1 !< Switch to disable outputs when running with full OF. 0: no MD main outfile, 1: write MD main outfile [(-)] INTEGER(IntKi) :: disableOutTime = 0 !< Disables the printing of the fairtens and timestep in init to the console, useful for the MATLAB wrapper [(-)] INTEGER(IntKi) :: nxWave = 0_IntKi !< number of x wave grid points [-] @@ -3117,6 +3118,7 @@ subroutine MD_CopyParam(SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMsg) DstParamData%cv = SrcParamData%cv DstParamData%inertialF = SrcParamData%inertialF DstParamData%inertialF_rampT = SrcParamData%inertialF_rampT + DstParamData%waveKin_rampT = SrcParamData%waveKin_rampT DstParamData%OutSwitch = SrcParamData%OutSwitch DstParamData%disableOutTime = SrcParamData%disableOutTime DstParamData%nxWave = SrcParamData%nxWave @@ -3468,6 +3470,7 @@ subroutine MD_PackParam(RF, Indata) call RegPack(RF, InData%cv) call RegPack(RF, InData%inertialF) call RegPack(RF, InData%inertialF_rampT) + call RegPack(RF, InData%waveKin_rampT) call RegPack(RF, InData%OutSwitch) call RegPack(RF, InData%disableOutTime) call RegPack(RF, InData%nxWave) @@ -3591,6 +3594,7 @@ subroutine MD_UnPackParam(RF, OutData) call RegUnpack(RF, OutData%cv); if (RegCheckErr(RF, RoutineName)) return call RegUnpack(RF, OutData%inertialF); if (RegCheckErr(RF, RoutineName)) return call RegUnpack(RF, OutData%inertialF_rampT); if (RegCheckErr(RF, RoutineName)) return + call RegUnpack(RF, OutData%waveKin_rampT); if (RegCheckErr(RF, RoutineName)) return call RegUnpack(RF, OutData%OutSwitch); if (RegCheckErr(RF, RoutineName)) return call RegUnpack(RF, OutData%disableOutTime); if (RegCheckErr(RF, RoutineName)) return call RegUnpack(RF, OutData%nxWave); if (RegCheckErr(RF, RoutineName)) return From d60da3eda7e459211a392a3b3fa57371be55e3a3 Mon Sep 17 00:00:00 2001 From: RyanDavies19 Date: Wed, 8 Apr 2026 11:02:08 -0700 Subject: [PATCH 3/6] MD: Add line node acceleration output --- modules/moordyn/src/MoorDyn.f90 | 30 +++-- modules/moordyn/src/MoorDyn_IO.f90 | 152 +++++++++++++---------- modules/moordyn/src/MoorDyn_Line.f90 | 25 ++-- modules/moordyn/src/MoorDyn_Registry.txt | 1 + modules/moordyn/src/MoorDyn_Types.f90 | 4 + 5 files changed, 124 insertions(+), 88 deletions(-) diff --git a/modules/moordyn/src/MoorDyn.f90 b/modules/moordyn/src/MoorDyn.f90 index 7d72a0f5cc..c449fff171 100644 --- a/modules/moordyn/src/MoorDyn.f90 +++ b/modules/moordyn/src/MoorDyn.f90 @@ -1637,25 +1637,29 @@ SUBROUTINE MD_Init(InitInp, u, p, x, xd, z, other, y, m, DTcoupling, InitOut, Er ! process output flag characters (LineOutString) and set line output flag array (OutFlagList) m%LineList(l)%OutFlagList = 0 ! first set array all to zero ! per node 3 component - IF ( scan( LineOutString, 'p') > 0 ) m%LineList(l)%OutFlagList(2) = 1 ! node position (p) - IF ( scan( LineOutString, 'v') > 0 ) m%LineList(l)%OutFlagList(3) = 1 ! node velocity (v) - IF ( scan( LineOutString, 'U') > 0 ) m%LineList(l)%OutFlagList(4) = 1 ! node displacement (U) - IF ( scan( LineOutString, 'D') > 0 ) m%LineList(l)%OutFlagList(5) = 1 ! node rotation (D) - IF ( scan( LineOutString, 'b') > 0 ) m%LineList(l)%OutFlagList(6) = 1 ! seabed contact forces (B) - IF ( scan( LineOutString, 'V') > 0 ) m%LineList(l)%OutFlagList(7) = 1 ! VIV forces + IF ( scan( LineOutString, 'p') > 0 ) m%LineList(l)%OutFlagList(2) = 1 ! node position (p) + IF ( scan( LineOutString, 'v') > 0 ) m%LineList(l)%OutFlagList(3) = 1 ! node velocity (v) + IF ( scan( LineOutString, 'a') > 0 ) m%LineList(l)%OutFlagList(4) = 1 ! node acceleration (a) + IF ( scan( LineOutString, 'U') > 0 ) m%LineList(l)%OutFlagList(5) = 1 ! wave velocity (U) + IF ( scan( LineOutString, 'D') > 0 ) m%LineList(l)%OutFlagList(6) = 1 ! hydrodynamic force (D) + IF ( scan( LineOutString, 'b') > 0 ) m%LineList(l)%OutFlagList(7) = 1 ! seabed contact forces (b) + IF ( scan( LineOutString, 'V') > 0 ) m%LineList(l)%OutFlagList(8) = 1 ! VIV forces ! per node 1 component - IF ( scan( LineOutString, 'W') > 0 ) m%LineList(l)%OutFlagList(8) = 1 ! node weight/buoyancy (positive up) - IF ( scan( LineOutString, 'K') > 0 ) m%LineList(l)%OutFlagList(9) = 1 ! curvature at node + IF ( scan( LineOutString, 'W') > 0 ) m%LineList(l)%OutFlagList(9) = 1 ! node weight/buoyancy (positive up) + IF ( scan( LineOutString, 'K') > 0 ) m%LineList(l)%OutFlagList(10) = 1 ! curvature at node ! per element 1 component - IF ( scan( LineOutString, 't') > 0 ) m%LineList(l)%OutFlagList(10) = 1 ! segment tension force (just EA) - IF ( scan( LineOutString, 'c') > 0 ) m%LineList(l)%OutFlagList(11) = 1 ! segment internal damping force - IF ( scan( LineOutString, 's') > 0 ) m%LineList(l)%OutFlagList(12) = 1 ! Segment strain - IF ( scan( LineOutString, 'd') > 0 ) m%LineList(l)%OutFlagList(13) = 1 ! Segment strain rate - IF ( scan( LineOutString, 'l') > 0 ) m%LineList(l)%OutFlagList(14) = 1 ! Segment stretched length + IF ( scan( LineOutString, 't') > 0 ) m%LineList(l)%OutFlagList(11) = 1 ! segment tension force (just EA) + IF ( scan( LineOutString, 'c') > 0 ) m%LineList(l)%OutFlagList(12) = 1 ! segment internal damping force + IF ( scan( LineOutString, 's') > 0 ) m%LineList(l)%OutFlagList(13) = 1 ! Segment strain + IF ( scan( LineOutString, 'd') > 0 ) m%LineList(l)%OutFlagList(14) = 1 ! Segment strain rate + IF ( scan( LineOutString, 'l') > 0 ) m%LineList(l)%OutFlagList(15) = 1 ! Segment stretched length IF (SUM(m%LineList(l)%OutFlagList) > 0) m%LineList(l)%OutFlagList(1) = 1 ! this first entry signals whether to create any output file at all ! the above letter-index combinations define which OutFlagList entry corresponds to which output type + ! set flag to store node accelerations if needed for VIV or acceleration output + m%LineList(l)%store_rdd = (m%LineTypeList(m%LineList(l)%PropsIdNum)%Cl > 0) .OR. (m%LineList(l)%OutFlagList(4) == 1) + if (p%writeLog > 1) then write(p%UnLog, '(A)' ) " - Line"//trim(num2lstr(m%LineList(l)%IdNum))//":" diff --git a/modules/moordyn/src/MoorDyn_IO.f90 b/modules/moordyn/src/MoorDyn_IO.f90 index 2da76623ba..f3f149bf17 100644 --- a/modules/moordyn/src/MoorDyn_IO.f90 +++ b/modules/moordyn/src/MoorDyn_IO.f90 @@ -810,9 +810,9 @@ SUBROUTINE MDIO_ProcessOutList(OutList, p, m, y, InitOut, ErrStat, ErrMsg ) ! calculate number of output entries (excluding time) to write for this line - LineNumOuts = 3*(m%LineList(I)%N + 1)*SUM(m%LineList(I)%OutFlagList(2:7)) & - + (m%LineList(I)%N + 1)*SUM(m%LineList(I)%OutFlagList(8:9)) & - + m%LineList(I)%N*SUM(m%LineList(I)%OutFlagList(10:18)) + LineNumOuts = 3*(m%LineList(I)%N + 1)*SUM(m%LineList(I)%OutFlagList(2:8)) & + + (m%LineList(I)%N + 1)*SUM(m%LineList(I)%OutFlagList(9:10)) & + + m%LineList(I)%N*SUM(m%LineList(I)%OutFlagList(11:19)) ALLOCATE(m%LineList(I)%LineWrOutput( 1 + LineNumOuts), STAT = ErrStat) IF ( ErrStat /= ErrID_None ) THEN @@ -959,9 +959,9 @@ SUBROUTINE MDIO_OpenOutput( MD_ProgDesc, p, m, InitOut, ErrStat, ErrMsg ) ! calculate number of output entries (excluding time) to write for this line - LineNumOuts = 3*(m%LineList(I)%N + 1)*SUM(m%LineList(I)%OutFlagList(2:7)) & - + (m%LineList(I)%N + 1)*SUM(m%LineList(I)%OutFlagList(8:9)) & - + m%LineList(I)%N*SUM(m%LineList(I)%OutFlagList(10:18)) + LineNumOuts = 3*(m%LineList(I)%N + 1)*SUM(m%LineList(I)%OutFlagList(2:8)) & + + (m%LineList(I)%N + 1)*SUM(m%LineList(I)%OutFlagList(9:10)) & + + m%LineList(I)%N*SUM(m%LineList(I)%OutFlagList(11:19)) if (wordy > 2) PRINT *, LineNumOuts, " output channels" @@ -981,48 +981,52 @@ SUBROUTINE MDIO_OpenOutput( MD_ProgDesc, p, m, InitOut, ErrStat, ErrMsg ) END IF IF (m%LineList(I)%OutFlagList(4) == 1) THEN WRITE(m%LineList(I)%LineUnOut,'('//TRIM(Int2LStr((3+3*m%LineList(I)%N)))//'(A1,A15))', advance='no', IOSTAT=ErrStat2) & - ( p%Delim, 'Node'//TRIM(Int2Lstr(J))//'Ux', p%Delim, 'Node'//TRIM(Int2Lstr(J))//'Uy', p%Delim, 'Node'//TRIM(Int2Lstr(J))//'Uz', J=0,(m%LineList(I)%N) ) + ( p%Delim, 'Node'//TRIM(Int2Lstr(J))//'ax', p%Delim, 'Node'//TRIM(Int2Lstr(J))//'ay', p%Delim, 'Node'//TRIM(Int2Lstr(J))//'az', J=0,(m%LineList(I)%N) ) END IF IF (m%LineList(I)%OutFlagList(5) == 1) THEN WRITE(m%LineList(I)%LineUnOut,'('//TRIM(Int2LStr((3+3*m%LineList(I)%N)))//'(A1,A15))', advance='no', IOSTAT=ErrStat2) & - ( p%Delim, 'Node'//TRIM(Int2Lstr(J))//'Dx', p%Delim, 'Node'//TRIM(Int2Lstr(J))//'Dy', p%Delim, 'Node'//TRIM(Int2Lstr(J))//'Dz', J=0,(m%LineList(I)%N) ) + ( p%Delim, 'Node'//TRIM(Int2Lstr(J))//'Ux', p%Delim, 'Node'//TRIM(Int2Lstr(J))//'Uy', p%Delim, 'Node'//TRIM(Int2Lstr(J))//'Uz', J=0,(m%LineList(I)%N) ) END IF IF (m%LineList(I)%OutFlagList(6) == 1) THEN + WRITE(m%LineList(I)%LineUnOut,'('//TRIM(Int2LStr((3+3*m%LineList(I)%N)))//'(A1,A15))', advance='no', IOSTAT=ErrStat2) & + ( p%Delim, 'Node'//TRIM(Int2Lstr(J))//'Dx', p%Delim, 'Node'//TRIM(Int2Lstr(J))//'Dy', p%Delim, 'Node'//TRIM(Int2Lstr(J))//'Dz', J=0,(m%LineList(I)%N) ) + END IF + IF (m%LineList(I)%OutFlagList(7) == 1) THEN WRITE(m%LineList(I)%LineUnOut,'('//TRIM(Int2LStr((3+3*m%LineList(I)%N)))//'(A1,A15))', advance='no', IOSTAT=ErrStat2) & ( p%Delim, 'Node'//TRIM(Int2Lstr(J))//'bx', p%Delim, 'Node'//TRIM(Int2Lstr(J))//'by', p%Delim, 'Node'//TRIM(Int2Lstr(J))//'bz', J=0,(m%LineList(I)%N) ) END IF - IF (m%LineList(I)%OutFlagList(7) == 1) THEN + IF (m%LineList(I)%OutFlagList(8) == 1) THEN WRITE(m%LineList(I)%LineUnOut,'('//TRIM(Int2LStr((3+3*m%LineList(I)%N)))//'(A1,A15))', advance='no', IOSTAT=ErrStat2) & ( p%Delim, 'Node'//TRIM(Int2Lstr(J))//'Vx', p%Delim, 'Node'//TRIM(Int2Lstr(J))//'Vy', p%Delim, 'Node'//TRIM(Int2Lstr(J))//'Vz', J=0,(m%LineList(I)%N) ) ! TODO adjust these when force to internal nodes END IF - - IF (m%LineList(I)%OutFlagList(8) == 1) THEN + + IF (m%LineList(I)%OutFlagList(9) == 1) THEN WRITE(m%LineList(I)%LineUnOut,'('//TRIM(Int2LStr((m%LineList(I)%N)))//'(A1,A15))', advance='no', IOSTAT=ErrStat2) & ( p%Delim, 'Node'//TRIM(Int2Lstr(J))//'Wz', J=0,(m%LineList(I)%N) ) END IF - IF (m%LineList(I)%OutFlagList(9) == 1) THEN + IF (m%LineList(I)%OutFlagList(10) == 1) THEN WRITE(m%LineList(I)%LineUnOut,'('//TRIM(Int2LStr((m%LineList(I)%N)))//'(A1,A15))', advance='no', IOSTAT=ErrStat2) & ( p%Delim, 'Node'//TRIM(Int2Lstr(J))//'Kurv', J=0,(m%LineList(I)%N) ) END IF - - IF (m%LineList(I)%OutFlagList(10) == 1) THEN + + IF (m%LineList(I)%OutFlagList(11) == 1) THEN WRITE(m%LineList(I)%LineUnOut,'('//TRIM(Int2LStr((m%LineList(I)%N)))//'(A1,A15))', advance='no', IOSTAT=ErrStat2) & ( p%Delim, 'Seg'//TRIM(Int2Lstr(J))//'Ten', J=1,(m%LineList(I)%N) ) END IF - IF (m%LineList(I)%OutFlagList(11) == 1) THEN + IF (m%LineList(I)%OutFlagList(12) == 1) THEN WRITE(m%LineList(I)%LineUnOut,'('//TRIM(Int2LStr((m%LineList(I)%N)))//'(A1,A15))', advance='no', IOSTAT=ErrStat2) & ( p%Delim, 'Seg'//TRIM(Int2Lstr(J))//'Dmp', J=1,(m%LineList(I)%N) ) END IF - IF (m%LineList(I)%OutFlagList(12) == 1) THEN + IF (m%LineList(I)%OutFlagList(13) == 1) THEN WRITE(m%LineList(I)%LineUnOut,'('//TRIM(Int2LStr((m%LineList(I)%N)))//'(A1,A15))', advance='no', IOSTAT=ErrStat2) & ( p%Delim, 'Seg'//TRIM(Int2Lstr(J))//'Str', J=1,(m%LineList(I)%N) ) END IF - IF (m%LineList(I)%OutFlagList(13) == 1) THEN + IF (m%LineList(I)%OutFlagList(14) == 1) THEN WRITE(m%LineList(I)%LineUnOut,'('//TRIM(Int2LStr((m%LineList(I)%N)))//'(A1,A15))', advance='no', IOSTAT=ErrStat2) & ( p%Delim, 'Seg'//TRIM(Int2Lstr(J))//'SRt', J=1,(m%LineList(I)%N) ) END IF - IF (m%LineList(I)%OutFlagList(14)== 1) THEN + IF (m%LineList(I)%OutFlagList(15)== 1) THEN WRITE(m%LineList(I)%LineUnOut,'('//TRIM(Int2LStr((m%LineList(I)%N)))//'(A1,A10))', advance='no', IOSTAT=ErrStat2) & ( p%Delim, 'Seg'//TRIM(Int2Lstr(J))//'Lst', J=1,(m%LineList(I)%N) ) END IF @@ -1043,11 +1047,11 @@ SUBROUTINE MDIO_OpenOutput( MD_ProgDesc, p, m, InitOut, ErrStat, ErrMsg ) END IF IF (m%LineList(I)%OutFlagList(4) == 1) THEN WRITE(m%LineList(I)%LineUnOut,'('//TRIM(Int2LStr((3+3*m%LineList(I)%N)))//'(A1,A15))', advance='no', IOSTAT=ErrStat2) & - ( p%Delim, '(m/s)', p%Delim, '(m/s)', p%Delim, '(m/s)', J=0,(m%LineList(I)%N) ) + ( p%Delim, '(m/s^2)', p%Delim, '(m/s^2)', p%Delim, '(m/s^2)', J=0,(m%LineList(I)%N) ) END IF IF (m%LineList(I)%OutFlagList(5) == 1) THEN WRITE(m%LineList(I)%LineUnOut,'('//TRIM(Int2LStr((3+3*m%LineList(I)%N)))//'(A1,A15))', advance='no', IOSTAT=ErrStat2) & - ( p%Delim, '(N)', p%Delim, '(N)', p%Delim, '(N)', J=0,(m%LineList(I)%N) ) + ( p%Delim, '(m/s)', p%Delim, '(m/s)', p%Delim, '(m/s)', J=0,(m%LineList(I)%N) ) END IF IF (m%LineList(I)%OutFlagList(6) == 1) THEN WRITE(m%LineList(I)%LineUnOut,'('//TRIM(Int2LStr((3+3*m%LineList(I)%N)))//'(A1,A15))', advance='no', IOSTAT=ErrStat2) & @@ -1057,33 +1061,37 @@ SUBROUTINE MDIO_OpenOutput( MD_ProgDesc, p, m, InitOut, ErrStat, ErrMsg ) WRITE(m%LineList(I)%LineUnOut,'('//TRIM(Int2LStr((3+3*m%LineList(I)%N)))//'(A1,A15))', advance='no', IOSTAT=ErrStat2) & ( p%Delim, '(N)', p%Delim, '(N)', p%Delim, '(N)', J=0,(m%LineList(I)%N) ) END IF - IF (m%LineList(I)%OutFlagList(8) == 1) THEN - WRITE(m%LineList(I)%LineUnOut,'('//TRIM(Int2LStr((m%LineList(I)%N)))//'(A1,A15))', advance='no', IOSTAT=ErrStat2) & - ( p%Delim, '(Nup)', J=0,(m%LineList(I)%N) ) + WRITE(m%LineList(I)%LineUnOut,'('//TRIM(Int2LStr((3+3*m%LineList(I)%N)))//'(A1,A15))', advance='no', IOSTAT=ErrStat2) & + ( p%Delim, '(N)', p%Delim, '(N)', p%Delim, '(N)', J=0,(m%LineList(I)%N) ) END IF + IF (m%LineList(I)%OutFlagList(9) == 1) THEN WRITE(m%LineList(I)%LineUnOut,'('//TRIM(Int2LStr((m%LineList(I)%N)))//'(A1,A15))', advance='no', IOSTAT=ErrStat2) & - ( p%Delim, '(1/m)', J=0,(m%LineList(I)%N) ) + ( p%Delim, '(Nup)', J=0,(m%LineList(I)%N) ) END IF - IF (m%LineList(I)%OutFlagList(10) == 1) THEN WRITE(m%LineList(I)%LineUnOut,'('//TRIM(Int2LStr((m%LineList(I)%N)))//'(A1,A15))', advance='no', IOSTAT=ErrStat2) & - ( p%Delim, '(N)', J=1,(m%LineList(I)%N) ) + ( p%Delim, '(1/m)', J=0,(m%LineList(I)%N) ) END IF + IF (m%LineList(I)%OutFlagList(11) == 1) THEN WRITE(m%LineList(I)%LineUnOut,'('//TRIM(Int2LStr((m%LineList(I)%N)))//'(A1,A15))', advance='no', IOSTAT=ErrStat2) & ( p%Delim, '(N)', J=1,(m%LineList(I)%N) ) END IF IF (m%LineList(I)%OutFlagList(12) == 1) THEN WRITE(m%LineList(I)%LineUnOut,'('//TRIM(Int2LStr((m%LineList(I)%N)))//'(A1,A15))', advance='no', IOSTAT=ErrStat2) & - ( p%Delim, '(-)', J=1,(m%LineList(I)%N) ) + ( p%Delim, '(N)', J=1,(m%LineList(I)%N) ) END IF IF (m%LineList(I)%OutFlagList(13) == 1) THEN + WRITE(m%LineList(I)%LineUnOut,'('//TRIM(Int2LStr((m%LineList(I)%N)))//'(A1,A15))', advance='no', IOSTAT=ErrStat2) & + ( p%Delim, '(-)', J=1,(m%LineList(I)%N) ) + END IF + IF (m%LineList(I)%OutFlagList(14) == 1) THEN WRITE(m%LineList(I)%LineUnOut,'('//TRIM(Int2LStr((m%LineList(I)%N)))//'(A1,A15))', advance='no', IOSTAT=ErrStat2) & ( p%Delim, '(1/s)', J=1,(m%LineList(I)%N) ) END IF - IF (m%LineList(I)%OutFlagList(14)== 1) THEN + IF (m%LineList(I)%OutFlagList(15)== 1) THEN WRITE(m%LineList(I)%LineUnOut,'('//TRIM(Int2LStr((m%LineList(I)%N)))//'(A1,A10))', advance='no', IOSTAT=ErrStat2) & ( p%Delim, '(m)', J=1,(m%LineList(I)%N) ) END IF @@ -1668,9 +1676,9 @@ SUBROUTINE MDIO_WriteOutputs( Time, p, m, y, ErrStat, ErrMsg ) ! calculate number of output entries to write for this line !LineNumOuts = 3*(m%LineList(I)%N + 1)*SUM(m%LineList(I)%OutFlagList(2:5)) + m%LineList(I)%N*SUM(m%LineList(I)%OutFlagList(6:9)) - LineNumOuts = 3*(m%LineList(I)%N + 1)*SUM(m%LineList(I)%OutFlagList(2:7)) & - + (m%LineList(I)%N + 1)*SUM(m%LineList(I)%OutFlagList(8:9)) & - + m%LineList(I)%N*SUM(m%LineList(I)%OutFlagList(10:18)) + LineNumOuts = 3*(m%LineList(I)%N + 1)*SUM(m%LineList(I)%OutFlagList(2:8)) & + + (m%LineList(I)%N + 1)*SUM(m%LineList(I)%OutFlagList(9:10)) & + + m%LineList(I)%N*SUM(m%LineList(I)%OutFlagList(11:19)) if (m%LineList(I)%OutFlagList(2) == 1) THEN ! if node positions are included, make them using a float format for higher precision Frmt = '(F10.4,'//TRIM(Int2LStr(3*(m%LineList(I)%N + 1)))//'(A1,ES15.7),'//TRIM(Int2LStr(LineNumOuts - 3*(m%LineList(I)%N - 1)))//'(A1,ES15.7))' @@ -1692,8 +1700,8 @@ SUBROUTINE MDIO_WriteOutputs( Time, p, m, y, ErrStat, ErrMsg ) L = L+1 END DO END DO - END IF - + END IF + ! Node velocities IF (m%LineList(I)%OutFlagList(3) == 1) THEN DO J = 0,m%LineList(I)%N ! note index starts at zero because these are nodes @@ -1703,10 +1711,20 @@ SUBROUTINE MDIO_WriteOutputs( Time, p, m, y, ErrStat, ErrMsg ) END DO END DO END IF - - - ! Node wave velocities (not implemented yet) + + ! Node accelerations IF (m%LineList(I)%OutFlagList(4) == 1) THEN + DO J = 0,m%LineList(I)%N ! note index starts at zero because these are nodes + DO K = 1,3 + m%LineList(I)%LineWrOutput(L) = m%LineList(I)%rdd_old(K,J) + L = L+1 + END DO + END DO + END IF + + + ! Node wave velocities + IF (m%LineList(I)%OutFlagList(5) == 1) THEN DO J = 0,m%LineList(I)%N ! note index starts at zero because these are nodes DO K = 1,3 m%LineList(I)%LineWrOutput(L) = m%LineList(I)%U(K,J) @@ -1714,10 +1732,10 @@ SUBROUTINE MDIO_WriteOutputs( Time, p, m, y, ErrStat, ErrMsg ) END DO END DO END IF - - + + ! Node total hydrodynamic forces (except added mass - just drag for now) - IF (m%LineList(I)%OutFlagList(5) == 1) THEN + IF (m%LineList(I)%OutFlagList(6) == 1) THEN DO J = 0,m%LineList(I)%N ! note index starts at zero because these are nodes DO K = 1,3 m%LineList(I)%LineWrOutput(L) = m%LineList(I)%Dp(K,J) + m%LineList(I)%Dq(K,J) @@ -1725,56 +1743,56 @@ SUBROUTINE MDIO_WriteOutputs( Time, p, m, y, ErrStat, ErrMsg ) END DO END DO END IF - - + + ! Node seabed contact force - IF (m%LineList(I)%OutFlagList(6) == 1) THEN - DO J = 0,m%LineList(I)%N + IF (m%LineList(I)%OutFlagList(7) == 1) THEN + DO J = 0,m%LineList(I)%N DO K = 1,3 m%LineList(I)%LineWrOutput(L) = m%LineList(I)%B(K,J) L = L+1 END DO END DO END IF - + ! Node VIV force - IF (m%LineList(I)%OutFlagList(7) == 1) THEN - DO J = 0,m%LineList(I)%N + IF (m%LineList(I)%OutFlagList(8) == 1) THEN + DO J = 0,m%LineList(I)%N DO K = 1,3 m%LineList(I)%LineWrOutput(L) = m%LineList(I)%Lf(K,J) L = L+1 END DO END DO END IF - + ! Node weights - IF (m%LineList(I)%OutFlagList(8) == 1) THEN + IF (m%LineList(I)%OutFlagList(9) == 1) THEN DO J = 0,m%LineList(I)%N m%LineList(I)%LineWrOutput(L) = m%LineList(I)%W(3,J) L = L+1 END DO END IF - + ! Node curvatures - IF (m%LineList(I)%OutFlagList(9) == 1) THEN + IF (m%LineList(I)%OutFlagList(10) == 1) THEN DO J = 0,m%LineList(I)%N m%LineList(I)%LineWrOutput(L) = m%LineList(I)%Kurv(J) L = L+1 END DO END IF - - + + ! Segment tension force (excludes damping term, just EA) - IF (m%LineList(I)%OutFlagList(10) == 1) THEN - DO J = 1,m%LineList(I)%N + IF (m%LineList(I)%OutFlagList(11) == 1) THEN + DO J = 1,m%LineList(I)%N m%LineList(I)%LineWrOutput(L) = TwoNorm(m%LineList(I)%T(:,J) ) L = L+1 END DO END IF - + ! Segment internal damping force - IF (m%LineList(I)%OutFlagList(11) == 1) THEN - DO J = 1,m%LineList(I)%N + IF (m%LineList(I)%OutFlagList(12) == 1) THEN + DO J = 1,m%LineList(I)%N IF (( m%LineList(I)%Td(3,J)*m%LineList(I)%T(3,J) ) > 0) THEN ! if statement for handling sign (positive = tension) m%LineList(I)%LineWrOutput(L) = TwoNorm(m%LineList(I)%Td(:,J) ) ELSE @@ -1783,26 +1801,26 @@ SUBROUTINE MDIO_WriteOutputs( Time, p, m, y, ErrStat, ErrMsg ) L = L+1 END DO END IF - + ! Segment strain - IF (m%LineList(I)%OutFlagList(12) == 1) THEN - DO J = 1,m%LineList(I)%N - m%LineList(I)%LineWrOutput(L) = m%LineList(I)%lstr(J)/m%LineList(I)%l(J) - 1.0 + IF (m%LineList(I)%OutFlagList(13) == 1) THEN + DO J = 1,m%LineList(I)%N + m%LineList(I)%LineWrOutput(L) = m%LineList(I)%lstr(J)/m%LineList(I)%l(J) - 1.0 L = L+1 END DO END IF - + ! Segment strain rate - IF (m%LineList(I)%OutFlagList(13) == 1) THEN - DO J = 1,m%LineList(I)%N + IF (m%LineList(I)%OutFlagList(14) == 1) THEN + DO J = 1,m%LineList(I)%N m%LineList(I)%LineWrOutput(L) = m%LineList(I)%lstrd(J)/m%LineList(I)%l(J) L = L+1 END DO END IF - + ! Segment length - IF (m%LineList(I)%OutFlagList(14) == 1) THEN - DO J = 1,m%LineList(I)%N + IF (m%LineList(I)%OutFlagList(15) == 1) THEN + DO J = 1,m%LineList(I)%N m%LineList(I)%LineWrOutput(L) = m%LineList(I)%lstr(J) L = L+1 END DO diff --git a/modules/moordyn/src/MoorDyn_Line.f90 b/modules/moordyn/src/MoorDyn_Line.f90 index 50e93350bf..327a6d16d9 100644 --- a/modules/moordyn/src/MoorDyn_Line.f90 +++ b/modules/moordyn/src/MoorDyn_Line.f90 @@ -184,11 +184,21 @@ SUBROUTINE SetupLine (Line, LineProp, p, ErrStat, ErrMsg) Line%dl_1 = 0.0_DbKi end if + ! allocate node accelerations if needed for VIV or output + if (Line%store_rdd) then + ALLOCATE ( Line%rdd_old(3,0:N), STAT = ErrStat ) + IF ( ErrStat /= ErrID_None ) THEN + ErrMsg = ' Error allocating rdd_old array.' + !CALL CleanUp() + RETURN + END IF + Line%rdd_old = 0.0_DbKi + end if + ! if using VIV model, allocate additional state quantities. if (Line%Cl > 0) then if (wordy > 1) print *, "Using the VIV model" - ! allocate old acclerations [for VIV] - ALLOCATE ( Line%phi(0:N), Line%rdd_old(3,0:N), Line%yd_rms_old(0:N), Line%ydd_rms_old(0:N), STAT = ErrStat ) + ALLOCATE ( Line%phi(0:N), Line%yd_rms_old(0:N), Line%ydd_rms_old(0:N), STAT = ErrStat ) IF ( ErrStat /= ErrID_None ) THEN ErrMsg = ' Error allocating VIV arrays.' !CALL CleanUp() @@ -196,7 +206,6 @@ SUBROUTINE SetupLine (Line, LineProp, p, ErrStat, ErrMsg) END IF ! initialize other things to 0 - Line%rdd_old = 0.0_DbKi Line%yd_rms_old = 0.0_DbKi Line%yd_rms_old = 0.0_DbKi end if @@ -1730,17 +1739,17 @@ SUBROUTINE Line_GetStateDeriv(Line, Xd, m, p, ErrStat, ErrMsg) !, FairFtot, Fai DO J=1,3 ! calculate RHS constant (premultiplying force vector by inverse of mass matrix ... i.e. rhs = S*Forces) - Sum1 = 0.0_DbKi ! reset temporary accumulator <<< could turn this into a Line%a array to save and output node accelerations + Sum1 = 0.0_DbKi ! reset temporary accumulator DO K = 1, 3 Sum1 = Sum1 + Line%S(K,J,I) * Line%Fnet(K,I) ! matrix-vector multiplication [S i]{Forces i} << double check indices END DO ! K - + ! update states Xd(3*N-3 + 3*I-3 + J) = Line%rd(J,I); ! dxdt = V (velocities) Xd( 3*I-3 + J) = Sum1 ! dVdt = RHS * A (accelerations) - - IF (Line%Cl > 0) THEN - Line%rdd_old(J,I) = Sum1 ! saving the acceleration for VIV RMS calculation. End nodes are left at zero, VIV disabled for end nodes + + IF (Line%store_rdd) THEN + Line%rdd_old(J,I) = Sum1 ! store node acceleration for VIV and/or output. End nodes are left at zero (VIV is disabled for end nodes). ENDIF END DO ! J diff --git a/modules/moordyn/src/MoorDyn_Registry.txt b/modules/moordyn/src/MoorDyn_Registry.txt index e4a44d1082..00fe8f63be 100644 --- a/modules/moordyn/src/MoorDyn_Registry.txt +++ b/modules/moordyn/src/MoorDyn_Registry.txt @@ -306,6 +306,7 @@ typedef ^ ^ DbKi t_old - typedef ^ ^ DbKi yd_rms_old {:} - - "node old cf vel rms" "m/s" typedef ^ ^ DbKi ydd_rms_old {:} - - "node old cf accel rms" "m/s^2" typedef ^ ^ DbKi rdd_old {:}{:} - - "node accelerations previous iteration" "m/s^2" +typedef ^ ^ Logical store_rdd - .FALSE. - "flag to store node accelerations (for VIV or output)" - # this is the ExtLd type, which holds data for each external load specification diff --git a/modules/moordyn/src/MoorDyn_Types.f90 b/modules/moordyn/src/MoorDyn_Types.f90 index 7026430e79..db4d73a8e0 100644 --- a/modules/moordyn/src/MoorDyn_Types.f90 +++ b/modules/moordyn/src/MoorDyn_Types.f90 @@ -326,6 +326,7 @@ MODULE MoorDyn_Types REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: yd_rms_old !< node old cf vel rms [m/s] REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: ydd_rms_old !< node old cf accel rms [m/s^2] REAL(DbKi) , DIMENSION(:,:), ALLOCATABLE :: rdd_old !< node accelerations previous iteration [m/s^2] + LOGICAL :: store_rdd = .FALSE. !< flag to store node accelerations (for VIV or output) [-] END TYPE MD_Line ! ======================= ! ========= MD_ExtLd ======= @@ -2212,6 +2213,7 @@ subroutine MD_CopyLine(SrcLineData, DstLineData, CtrlCode, ErrStat, ErrMsg) end if DstLineData%rdd_old = SrcLineData%rdd_old end if + DstLineData%store_rdd = SrcLineData%store_rdd end subroutine subroutine MD_DestroyLine(LineData, ErrStat, ErrMsg) @@ -2407,6 +2409,7 @@ subroutine MD_PackLine(RF, Indata) call RegPackAlloc(RF, InData%yd_rms_old) call RegPackAlloc(RF, InData%ydd_rms_old) call RegPackAlloc(RF, InData%rdd_old) + call RegPack(RF, InData%store_rdd) if (RegCheckErr(RF, RoutineName)) return end subroutine @@ -2495,6 +2498,7 @@ subroutine MD_UnPackLine(RF, OutData) call RegUnpackAlloc(RF, OutData%yd_rms_old); if (RegCheckErr(RF, RoutineName)) return call RegUnpackAlloc(RF, OutData%ydd_rms_old); if (RegCheckErr(RF, RoutineName)) return call RegUnpackAlloc(RF, OutData%rdd_old); if (RegCheckErr(RF, RoutineName)) return + call RegUnpack(RF, OutData%store_rdd); if (RegCheckErr(RF, RoutineName)) return end subroutine subroutine MD_CopyExtLd(SrcExtLdData, DstExtLdData, CtrlCode, ErrStat, ErrMsg) From d070a19f51750ade222c0e772e1c7c76d88ad515 Mon Sep 17 00:00:00 2001 From: RyanDavies19 Date: Mon, 13 Apr 2026 23:39:50 -0700 Subject: [PATCH 4/6] MD: runtime improvements for SeaState coupling --- modules/moordyn/src/MoorDyn.f90 | 13 ++++++++++--- modules/moordyn/src/MoorDyn_Line.f90 | 19 ++++++++++++++----- modules/moordyn/src/MoorDyn_Misc.f90 | 5 +---- modules/moordyn/src/MoorDyn_Rod.f90 | 24 ++++++++++++++++-------- 4 files changed, 41 insertions(+), 20 deletions(-) diff --git a/modules/moordyn/src/MoorDyn.f90 b/modules/moordyn/src/MoorDyn.f90 index c449fff171..ee4d859b95 100644 --- a/modules/moordyn/src/MoorDyn.f90 +++ b/modules/moordyn/src/MoorDyn.f90 @@ -503,6 +503,16 @@ SUBROUTINE MD_Init(InitInp, u, p, x, xd, z, other, y, m, DTcoupling, InitOut, Er Line = NextLine(i) END DO + + ! extract dtCoupling from input and warn if dtOut is invalid + p%dtCoupling = DTcoupling ! store coupling time step for use in updatestates + print*, "Coupling time step read in as: ", p%dtCoupling + print*, "Output time step read in as: ", p%dtOut + IF (p%dtOut > 0.0_DbKi .and. p%dtOut < DTcoupling) THEN + ErrStat2 = ErrID_Info + ErrMsg2 = 'MoorDyn dtOut is less than the coupling time step. Output will be written at the coupling time step.' + CALL CheckError( ErrStat2, ErrMsg2 ) + END IF if (p%writeLog > 1) then write(p%UnLog, '(A)' ) " - Options List:" @@ -2936,9 +2946,6 @@ SUBROUTINE MD_Init(InitInp, u, p, x, xd, z, other, y, m, DTcoupling, InitOut, Er END DO end if ! InputFileDat%TMaxIC > 0 - - - p%dtCoupling = DTcoupling ! store coupling time step for use in updatestates other%dummy = 0 xd%dummy = 0 diff --git a/modules/moordyn/src/MoorDyn_Line.f90 b/modules/moordyn/src/MoorDyn_Line.f90 index 327a6d16d9..affb532d31 100644 --- a/modules/moordyn/src/MoorDyn_Line.f90 +++ b/modules/moordyn/src/MoorDyn_Line.f90 @@ -1229,11 +1229,20 @@ SUBROUTINE Line_GetStateDeriv(Line, Xd, m, p, ErrStat, ErrMsg) !, FairFtot, Fai CALL UnitVector(Line%r(:,N-1), Line%r(:,N), Line%q(:,N), dummyLength) end if - ! apply wave kinematics (if there are any) - DO i=0,N - CALL getWaterKin(p, m, Line%r(1,i), Line%r(2,i), Line%r(3,i), Line%time, Line%U(:,i), Line%Ud(:,i), Line%zeta(i), Line%PDyn(i), ErrStat2, ErrMsg2) - CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - END DO + ! apply wave kinematics (if there are any) + ! For SeaState (WaterKin==3), skip during IC_gen (otherwise will never find steady state because of waves) + ! and skip if inside a coupling timestep (because external kinematics do not change between coupling steps) + if (p%WaterKin == 3 .and. (m%IC_gen .or. & + (abs(MOD(Line%time - 0.5*p%dtCoupling, p%dtCoupling) - 0.5*p%dtCoupling) >= 0.5*p%dtM0) .and. Line%time > 0.0_DbKi)) then + ! retain existing kinematics values + ! This does introduce some error, as the interpolation location does not track the motion exactly. But the change between + ! coupling steps should be small enough that the error is negligible. + else + DO i=0,N + CALL getWaterKin(p, m, Line%r(1,i), Line%r(2,i), Line%r(3,i), Line%time, Line%U(:,i), Line%Ud(:,i), Line%zeta(i), Line%PDyn(i), ErrStat2, ErrMsg2) + CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + END DO + end if ! --------- calculate line partial submergence (Line::calcSubSeg from MD-C) --------- DO i=1,N diff --git a/modules/moordyn/src/MoorDyn_Misc.f90 b/modules/moordyn/src/MoorDyn_Misc.f90 index 92ee7a610c..e0348bd0ec 100644 --- a/modules/moordyn/src/MoorDyn_Misc.f90 +++ b/modules/moordyn/src/MoorDyn_Misc.f90 @@ -944,7 +944,7 @@ SUBROUTINE getWaterKin(p, m, x, y, z, t, U, Ud, zeta, PDyn, ErrStat, ErrMsg) ! local CHARACTER(120) :: RoutineName = 'getWaterKin' - + ErrStat = ErrID_None ErrMsg = "" @@ -1010,9 +1010,6 @@ SUBROUTINE getWaterKin(p, m, x, y, z, t, U, Ud, zeta, PDyn, ErrStat, ErrMsg) ! SeaState wave kinematics case (3) - ! disable wavekin 3 during IC_gen, otherwise will never find steady state (because of waves) - if (m%IC_gen) return - ! SeaState throws warning when queried location is out of bounds from the SeaState grid, so no need to handle here ! Pack all MD inputs to WaveGrid input data types (double to single) diff --git a/modules/moordyn/src/MoorDyn_Rod.f90 b/modules/moordyn/src/MoorDyn_Rod.f90 index 34b2eb9339..c7ffbf10f1 100644 --- a/modules/moordyn/src/MoorDyn_Rod.f90 +++ b/modules/moordyn/src/MoorDyn_Rod.f90 @@ -622,14 +622,22 @@ SUBROUTINE Rod_DoRHS(Rod, m, p) ! apply wave kinematics (if there are any) - - DO i=0,N - CALL getWaterKin(p, m, Rod%r(1,i), Rod%r(2,i), Rod%r(3,i), Rod%time, Rod%U(:,i), Rod%Ud(:,i), Rod%zeta(i), Rod%PDyn(i), ErrStat2, ErrMsg2) - ! TODO: Handle error messages. Roads broadly needs error flags to be supported - - !F(i) = 1.0 ! set VOF value to one for now (everything submerged - eventually this should be element-based!!!) <<<< - ! <<<< currently F is not being used and instead a VOF variable is used within the node loop - END DO + ! For SeaState (WaterKin==3), skip during IC_gen (otherwise will never find steady state because of waves) + ! and skip if inside a coupling timestep (because external kinematics do not change between coupling steps) + if (p%WaterKin == 3 .and. (m%IC_gen .or. & + (abs(MOD(Rod%time - 0.5*p%dtCoupling, p%dtCoupling) - 0.5*p%dtCoupling) >= 0.5*p%dtM0) .and. Rod%time > 0.0_DbKi)) then + ! retain existing kinematics values + ! This does introduce some error, as the interpolation location does not track the motion exactly. But the change between + ! coupling steps should be small enough that the error is negligible. + else + DO i=0,N + CALL getWaterKin(p, m, Rod%r(1,i), Rod%r(2,i), Rod%r(3,i), Rod%time, Rod%U(:,i), Rod%Ud(:,i), Rod%zeta(i), Rod%PDyn(i), ErrStat2, ErrMsg2) + ! TODO: Handle error messages. Roads broadly needs error flags to be supported + + !F(i) = 1.0 ! set VOF value to one for now (everything submerged - eventually this should be element-based!!!) <<<< + ! <<<< currently F is not being used and instead a VOF variable is used within the node loop + END DO + end if ! Calculated h0 (note this should be deprecated/replced) zeta = Rod%zeta(N) ! temporary From 2f1252ab30a0b437eb3fc5648ac439c471ddf70b Mon Sep 17 00:00:00 2001 From: RyanDavies19 Date: Tue, 14 Apr 2026 10:40:03 -0700 Subject: [PATCH 5/6] MD: remove forgotten print statements --- modules/moordyn/src/MoorDyn.f90 | 2 -- 1 file changed, 2 deletions(-) diff --git a/modules/moordyn/src/MoorDyn.f90 b/modules/moordyn/src/MoorDyn.f90 index ee4d859b95..cd1e02a1e2 100644 --- a/modules/moordyn/src/MoorDyn.f90 +++ b/modules/moordyn/src/MoorDyn.f90 @@ -506,8 +506,6 @@ SUBROUTINE MD_Init(InitInp, u, p, x, xd, z, other, y, m, DTcoupling, InitOut, Er ! extract dtCoupling from input and warn if dtOut is invalid p%dtCoupling = DTcoupling ! store coupling time step for use in updatestates - print*, "Coupling time step read in as: ", p%dtCoupling - print*, "Output time step read in as: ", p%dtOut IF (p%dtOut > 0.0_DbKi .and. p%dtOut < DTcoupling) THEN ErrStat2 = ErrID_Info ErrMsg2 = 'MoorDyn dtOut is less than the coupling time step. Output will be written at the coupling time step.' From e4e6e52290ff5903eb1ca102ede14289998ab8a8 Mon Sep 17 00:00:00 2001 From: andrew-platt Date: Tue, 21 Apr 2026 14:27:28 -0600 Subject: [PATCH 6/6] Update r-test: RM1 floating tank case --- 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 878754d592..401b7fff63 160000 --- a/reg_tests/r-test +++ b/reg_tests/r-test @@ -1 +1 @@ -Subproject commit 878754d592042b97f0449701a57296afc1ecb23c +Subproject commit 401b7fff63108a5b50ca824149183fe3609203a2