@@ -3146,6 +3146,8 @@ subroutine g_tracer_vertdiff_G(g_tracer, h_old, ea, eb, dt, kg_m2_to_H, m_to_H,
3146
3146
integer :: i, j, k, nz
3147
3147
logical :: do_diagnostic
3148
3148
3149
+ character (len= fm_string_len), parameter :: sub_name = ' g_tracer_vertdiff_G'
3150
+
3149
3151
!
3150
3152
! Save the current state for calculation of the implicit vertical diffusion term
3151
3153
!
@@ -3180,37 +3182,34 @@ subroutine g_tracer_vertdiff_G(g_tracer, h_old, ea, eb, dt, kg_m2_to_H, m_to_H,
3180
3182
3181
3183
nz= g_tracer_com% grid_kmt(i,j)
3182
3184
3185
+ ! Note, sink_rate is ignored when using move_vertical
3183
3186
if (g_tracer% move_vertical) then
3184
3187
do k= 2 ,nz; sink_dist(k) = (dt* g_tracer% vmove(i,j,k)) * m_to_H; enddo
3185
3188
endif
3186
3189
sfc_src = 0.0 ; btm_src = 0.0
3187
3190
3188
- ! Find the sinking rates at all interfaces, limiting them if necesary
3189
- ! so that the characteristics do not cross within a timestep.
3190
- ! If a non-constant sinking rate were used, that would be incorprated
3191
- ! here.
3191
+ ! Sinking of tracer into a sediment reservoir?
3192
3192
if (_ALLOCATED(g_tracer% btm_reservoir)) then
3193
- do k= 2 ,nz
3194
- sink(k) = sink_dist(k) ; h_minus_dsink(k) = h_old(i,j,k)
3195
- enddo
3196
- sink(nz+1 ) = sink_dist(nz+1 )
3193
+ sink(nz+1 ) = sink_dist(nz) ! PJB [13th Nov 2024] to allow sinking into bottom reservoir
3197
3194
else
3198
3195
sink(nz+1 ) = 0.0
3199
- ! Find the limited sinking distance at the interfaces.
3200
- do k= nz,2 ,- 1
3201
- if (sink(k+1 ) >= sink_dist(k)) then
3202
- sink(k) = sink_dist(k)
3203
- h_minus_dsink(k) = h_old(i,j,k) + (sink(k+1 ) - sink(k))
3204
- elseif (sink(k+1 ) + h_old(i,j,k) < sink_dist(k)) then
3205
- sink(k) = sink(k+1 ) + h_old(i,j,k)
3206
- h_minus_dsink(k) = 0.0
3207
- else
3208
- sink(k) = sink_dist(k)
3209
- h_minus_dsink(k) = (h_old(i,j,k) + sink(k+1 )) - sink(k)
3210
- endif
3211
- enddo
3212
3196
endif
3213
3197
3198
+ ! Find the sinking rates at all interfaces, limiting them if necesary
3199
+ ! so that the characteristics do not cross within a timestep.
3200
+ do k= nz,2 ,- 1
3201
+ if (sink(k+1 ) >= sink_dist(k)) then
3202
+ sink(k) = sink_dist(k)
3203
+ h_minus_dsink(k) = h_old(i,j,k) + (sink(k+1 ) - sink(k))
3204
+ elseif (sink(k+1 ) + h_old(i,j,k) < sink_dist(k)) then
3205
+ sink(k) = sink(k+1 ) + h_old(i,j,k)
3206
+ h_minus_dsink(k) = 0.0
3207
+ else
3208
+ sink(k) = sink_dist(k)
3209
+ h_minus_dsink(k) = (h_old(i,j,k) + sink(k+1 )) - sink(k)
3210
+ endif
3211
+ enddo
3212
+
3214
3213
sink(1 ) = 0.0 ; h_minus_dsink(1 ) = (h_old(i,j,1 ) + sink(2 ))
3215
3214
3216
3215
! Avoid sinking tracers with negative concentrations
@@ -3231,6 +3230,9 @@ subroutine g_tracer_vertdiff_G(g_tracer, h_old, ea, eb, dt, kg_m2_to_H, m_to_H,
3231
3230
do k= 2 ,nz-1
3232
3231
c1(k) = eb(i,j,k-1 ) * b1
3233
3232
b_denom_1 = h_minus_dsink(k) + d1 * (ea(i,j,k) + sink(k))
3233
+ if (b_denom_1.le. 0.0 ) then
3234
+ call mpp_error(FATAL, trim (sub_name)// " : Diagonal value b_denom_1 must be > 0.0" )
3235
+ endif
3234
3236
b1 = 1.0 / (b_denom_1 + eb(i,j,k))
3235
3237
d1 = b_denom_1 * b1
3236
3238
@@ -3315,10 +3317,11 @@ subroutine g_tracer_vertdiff_M(g_tracer,dh, dhw, diff_cbt, dt, rho0,tau)
3315
3317
3316
3318
GOLDtridiag = .true.
3317
3319
IOWtridiag = .false.
3318
- if (g_tracer% move_vertical) then
3319
- GOLDtridiag = .false.
3320
- IOWtridiag = .true.
3321
- endif
3320
+ ! PJB [1st Dec 2024] Commenting out since GOLDtridiag now works with move_vertical==.true.
3321
+ ! if (g_tracer%move_vertical) then
3322
+ ! GOLDtridiag = .false.
3323
+ ! IOWtridiag = .true.
3324
+ ! endif
3322
3325
3323
3326
eps = 1.e-30
3324
3327
@@ -3424,6 +3427,11 @@ subroutine g_tracer_vertdiff_M(g_tracer,dh, dhw, diff_cbt, dt, rho0,tau)
3424
3427
wabsl = abs (g_tracer% vmove(i,j,k))
3425
3428
wposl(i,k) = fact2* (g_tracer% vmove(i,j,k ) + wabsl)* g_tracer_com% grid_tmask(i,j,kp1)
3426
3429
wnegl(i,k) = fact2* (g_tracer% vmove(i,j,k ) - wabsl)* g_tracer_com% grid_tmask(i,j,kp1)
3430
+ if (k.eq. g_tracer_com% grid_kmt(i,j) .and. _ALLOCATED(g_tracer% btm_reservoir)) then ! PJB [14th Nov 2024]
3431
+ wnegl(i,k) = fact2* (g_tracer% vmove(i,j,k ) - wabsl)* g_tracer_com% grid_tmask(i,j,k)
3432
+ g_tracer% btm_reservoir(i,j) = g_tracer% btm_reservoir(i,j) - &
3433
+ wnegl(i,k)* g_tracer% field(i,j,k,tau)* dh(i,j,k)
3434
+ endif
3427
3435
a1(i,k) = dcb(i,j,km1)* factu* g_tracer_com% grid_tmask(i,j,k)
3428
3436
c1(i,k) = dcb(i,j,k) * factl* g_tracer_com% grid_tmask(i,j,kp1)
3429
3437
a(i,k) = - (a1(i,k) - wnegu(i,k))
@@ -3433,12 +3441,14 @@ subroutine g_tracer_vertdiff_M(g_tracer,dh, dhw, diff_cbt, dt, rho0,tau)
3433
3441
enddo
3434
3442
enddo
3435
3443
3444
+ ! Set boundary conditions (zero flow out the top and bottom of the water column)
3436
3445
do i= g_tracer_com% isc,g_tracer_com% iec
3437
3446
a1(i,1 ) = 0.0
3438
3447
wnegu(i,1 ) = 0.0 ; wposu(i,1 ) = 0.0
3439
3448
a(i,1 ) = 0.0
3440
3449
c1(i,g_tracer_com% nk) = 0.0
3441
- wposl(i,g_tracer_com% nk) = 0.0 ; wnegl(i,g_tracer_com% nk) = 0.0
3450
+ wposl(i,g_tracer_com% nk) = 0.0
3451
+ if (.not. _ALLOCATED(g_tracer% btm_reservoir)) wnegl(i,g_tracer_com% nk) = 0.0 ! PJB [14th Nov 2024]
3442
3452
c(i,g_tracer_com% nk) = 0.0
3443
3453
b(i,1 ) = 1.0 + a1(i,1 ) + c1(i,1 ) - wnegl(i,1 ) + wposu(i,1 )
3444
3454
b(i,g_tracer_com% nk) = 1.0 + a1(i,g_tracer_com% nk) + c1(i,g_tracer_com% nk) &
0 commit comments