@@ -201,7 +201,7 @@ subroutine step_forward_MEKE(MEKE, h, SN_u, SN_v, visc, dt, G, GV, US, CS, hu, h
201201 src_GM, & ! The MEKE source/tendency from the thickness mixing (GM) [L2 T-3 ~> W kg-1] (= m2 s-3).
202202 src_mom_lp, & ! The MEKE source/tendency from the Laplacian of the resolved flow [L2 T-3 ~> W kg-1] (= m2 s-3).
203203 src_mom_bh, & ! The MEKE source/tendency from the biharmonic of the resolved flow [L2 T-3 ~> W kg-1] (= m2 s-3).
204- ldamping_Strang1 , & ! The MEKE damping rate computed at the 1st Strang splitting stage [T-1 ~> s-1].
204+ damp_rate_s1 , & ! The MEKE damping rate computed at the 1st Strang splitting stage [T-1 ~> s-1].
205205 MEKE_current, & ! A copy of MEKE for use in computing the MEKE damping [L2 T-2 ~> m2 s-2].
206206 drag_rate_visc, & ! Near-bottom velocity contribution to bottom drag [H T-1 ~> m s-1 or kg m-2 s-1]
207207 drag_rate, & ! The MEKE spindown timescale due to bottom drag [T-1 ~> s-1].
@@ -233,11 +233,11 @@ subroutine step_forward_MEKE(MEKE, h, SN_u, SN_v, visc, dt, G, GV, US, CS, hu, h
233233 real :: cdrag2 ! The square of the drag coefficient times unit conversion factors [H2 L-2 ~> nondim or kg2 m-6]
234234 real :: advFac ! The product of the advection scaling factor and 1/dt [T-1 ~> s-1]
235235 real :: mass_neglect ! A negligible mass [R Z ~> kg m-2].
236- real :: ldamping ! The MEKE damping rate [T-1 ~> s-1].
237236 real :: sdt ! dt to use locally [T ~> s] (could be scaled to accelerate)
238237 real :: sdt_damp ! dt for damping [T ~> s] (sdt could be split).
239- real :: sfac ! A factor needed to compute damping due to Strang splitting [nondim]
240- real :: Isfac ! Inverse of sfac [nondim]
238+ real :: damp_step ! Size of damping timestep relative to sdt [nondim]
239+ real :: damp_rate ! The MEKE damping rate [T-1 ~> s-1].
240+ real :: damping ! The net damping of a field after sdt_damp [nondim]
241241 logical :: use_drag_rate ! Flag to indicate drag_rate is finite
242242 integer :: i, j, k, is, ie, js, je, Isq, Ieq, Jsq, Jeq, nz
243243 real (kind= real32), dimension (size (MEKE% MEKE),NUM_FEATURES) :: features_array ! The array of features
@@ -287,7 +287,9 @@ subroutine step_forward_MEKE(MEKE, h, SN_u, SN_v, visc, dt, G, GV, US, CS, hu, h
287287
288288 ! With a depth-dependent (and possibly strong) damping, it seems
289289 ! advisable to use Strang splitting between the damping and diffusion.
290- sdt_damp = sdt ; if (CS% MEKE_KH >= 0.0 .or. CS% MEKE_K4 >= 0 .) sdt_damp = 0.5 * sdt
290+ damp_step = 1 .
291+ if (CS% MEKE_KH >= 0 . .or. CS% MEKE_K4 >= 0 .) damp_step = 0.5
292+ sdt_damp = sdt * damp_step
291293
292294 ! Calculate depth integrated mass exchange if doing advection [R Z L2 ~> kg]
293295 if (CS% MEKE_advection_factor> 0 .) then
@@ -479,19 +481,29 @@ subroutine step_forward_MEKE(MEKE, h, SN_u, SN_v, visc, dt, G, GV, US, CS, hu, h
479481 ! First stage of Strang splitting
480482 ! $OMP parallel do default(shared)
481483 do j= js,je ; do i= is,ie
482- ldamping = CS% MEKE_damping + drag_rate(i,j) * bottomFac2(i,j)
483- if (MEKE% MEKE(i,j) < 0 .) ldamping = 0 .
484+ damp_rate = CS% MEKE_damping + drag_rate(i,j) * bottomFac2(i,j)
485+ if (MEKE% MEKE(i,j) < 0 .) damp_rate = 0 .
484486 ! notice that the above line ensures a damping only if MEKE is positive,
485487 ! while leaving MEKE unchanged if it is negative
486- Isfac = 1 . / (1 . + sdt_damp * ldamping)
487- MEKE% MEKE(i,j) = MEKE% MEKE(i,j) / (1.0 + sdt_damp* ldamping)
488- MEKE_decay(i,j) = ldamping* G% mask2dT(i,j)
489- ldamping_Strang1(i,j) = ldamping
490- src_GM(i,j) = src_GM(i,j) * Isfac
491- src_mom_lp(i,j) = src_mom_lp(i,j) * Isfac
492- src_mom_bh(i,j) = src_mom_bh(i,j) * Isfac
493- sfac = ( 1.0 + sdt_damp* ldamping )
494- src_btm_drag(i,j) = MEKE_current(i,j) * ( (1.0 - sfac) / ( sdt * sfac ) )
488+
489+ damping = 1 . / (1 . + sdt_damp * damp_rate)
490+
491+ ! NOTE: MEKE%MEKE should use `damping` but we must preserve the existing
492+ ! expression for bit reproducibility
493+ MEKE% MEKE(i,j) = MEKE% MEKE(i,j) / (1 . + sdt_damp * damp_rate)
494+ MEKE_decay(i,j) = damp_rate * G% mask2dT(i,j)
495+
496+ src_GM(i,j) = src_GM(i,j) * damping
497+ src_mom_lp(i,j) = src_mom_lp(i,j) * damping
498+ src_mom_bh(i,j) = src_mom_bh(i,j) * damping
499+
500+ src_btm_drag(i,j) = - MEKE_current(i,j) * ( &
501+ damp_step * (damp_rate * damping) &
502+ )
503+
504+ ! Store the effective damping rate if sdt is split
505+ if (CS% MEKE_KH >= 0 . .or. CS% MEKE_K4 >= 0 .) &
506+ damp_rate_s1(i,j) = damp_rate * damping
495507 enddo ; enddo
496508
497509 if (CS% kh_flux_enabled .or. CS% MEKE_K4 >= 0.0 ) then
@@ -647,33 +659,38 @@ subroutine step_forward_MEKE(MEKE, h, SN_u, SN_v, visc, dt, G, GV, US, CS, hu, h
647659
648660 ! Second stage of Strang splitting
649661 if (CS% MEKE_KH >= 0.0 .or. CS% MEKE_K4 >= 0.0 ) then
650- if (sdt> sdt_damp) then
651- ! Recalculate the drag rate, since MEKE has changed.
652- if (use_drag_rate) then
653- ! $OMP parallel do default(shared)
654- do j= js,je ; do i= is,ie
655- drag_rate(i,j) = (GV% H_to_RZ * I_mass(i,j)) * sqrt ( drag_rate_visc(i,j)** 2 + &
656- cdrag2 * ( max (0.0 , 2.0 * bottomFac2(i,j)* MEKE% MEKE(i,j)) + CS% MEKE_Uscale** 2 ) )
657- enddo ; enddo
658- endif
662+ ! Recalculate the drag rate, since MEKE has changed.
663+ if (use_drag_rate) then
659664 ! $OMP parallel do default(shared)
660665 do j= js,je ; do i= is,ie
661- ldamping = CS% MEKE_damping + drag_rate(i,j) * bottomFac2(i,j)
662- if (MEKE% MEKE(i,j) < 0 .) ldamping = 0 .
663- ! notice that the above line ensures a damping only if MEKE is positive,
664- ! while leaving MEKE unchanged if it is negative
665- Isfac = 1 . / (1 . + sdt_damp* ldamping)
666- MEKE% MEKE(i,j) = MEKE% MEKE(i,j) / (1.0 + sdt_damp* ldamping)
667- MEKE_decay(i,j) = ldamping* G% mask2dT(i,j)
668- src_GM(i,j) = src_GM(i,j) * Isfac
669- src_mom_lp(i,j) = src_mom_lp(i,j) * Isfac
670- src_mom_bh(i,j) = src_mom_bh(i,j) * Isfac
671- src_adv(i,j) = src_adv(i,j) * Isfac
672- src_mom_K4(i,j) = src_mom_K4(i,j) * Isfac
673- sfac = ( 1.0 + sdt_damp* ldamping_Strang1(i,j) ) * ( 1.0 + sdt_damp* ldamping )
674- src_btm_drag(i,j) = MEKE_current(i,j) * ( (1.0 - sfac) / ( sdt * sfac ) )
666+ drag_rate(i,j) = (GV% H_to_RZ * I_mass(i,j)) * sqrt ( drag_rate_visc(i,j)** 2 + &
667+ cdrag2 * ( max (0.0 , 2.0 * bottomFac2(i,j)* MEKE% MEKE(i,j)) + CS% MEKE_Uscale** 2 ) )
675668 enddo ; enddo
676669 endif
670+ ! $OMP parallel do default(shared)
671+ do j= js,je ; do i= is,ie
672+ damp_rate = CS% MEKE_damping + drag_rate(i,j) * bottomFac2(i,j)
673+ if (MEKE% MEKE(i,j) < 0 .) damp_rate = 0 .
674+ ! notice that the above line ensures a damping only if MEKE is positive,
675+ ! while leaving MEKE unchanged if it is negative
676+
677+ damping = 1 . / (1 . + sdt_damp * damp_rate)
678+
679+ ! NOTE: As above, MEKE%MEKE should use `damping` but we must preserve
680+ ! the existing expression for bit reproducibility.
681+ MEKE% MEKE(i,j) = MEKE% MEKE(i,j) / (1.0 + sdt_damp* damp_rate)
682+ MEKE_decay(i,j) = damp_rate* G% mask2dT(i,j)
683+
684+ src_GM(i,j) = src_GM(i,j) * damping
685+ src_mom_lp(i,j) = src_mom_lp(i,j) * damping
686+ src_mom_bh(i,j) = src_mom_bh(i,j) * damping
687+ src_adv(i,j) = src_adv(i,j) * damping
688+ src_mom_K4(i,j) = src_mom_K4(i,j) * damping
689+
690+ src_btm_drag(i,j) = - MEKE_current(i,j) * ( &
691+ damp_step * damping * (damp_rate + damp_rate_s1(i,j)) &
692+ )
693+ enddo ; enddo
677694 endif ! MEKE_KH>=0
678695
679696 if (CS% debug) then
0 commit comments