Skip to content

Commit 6c90cb5

Browse files
authored
Added vmove functionality to the implicit diffusion schemes: (#25)
* In vertdiff_G - ensured that vertical changes in sinking rate were accounted for * In vertdiff_M - enabled detritus within the water column to enter a btm_reservoir when sinking through the bottom
1 parent b6f728a commit 6c90cb5

File tree

1 file changed

+36
-26
lines changed

1 file changed

+36
-26
lines changed

generic_tracers/generic_tracer_utils.F90

Lines changed: 36 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -3146,6 +3146,8 @@ subroutine g_tracer_vertdiff_G(g_tracer, h_old, ea, eb, dt, kg_m2_to_H, m_to_H,
31463146
integer :: i, j, k, nz
31473147
logical :: do_diagnostic
31483148

3149+
character(len=fm_string_len), parameter :: sub_name = 'g_tracer_vertdiff_G'
3150+
31493151
!
31503152
! Save the current state for calculation of the implicit vertical diffusion term
31513153
!
@@ -3180,37 +3182,34 @@ subroutine g_tracer_vertdiff_G(g_tracer, h_old, ea, eb, dt, kg_m2_to_H, m_to_H,
31803182

31813183
nz=g_tracer_com%grid_kmt(i,j)
31823184

3185+
! Note, sink_rate is ignored when using move_vertical
31833186
if (g_tracer%move_vertical) then
31843187
do k=2,nz; sink_dist(k) = (dt*g_tracer%vmove(i,j,k)) * m_to_H; enddo
31853188
endif
31863189
sfc_src = 0.0 ; btm_src = 0.0
31873190

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?
31923192
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
31973194
else
31983195
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
32123196
endif
32133197

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+
32143213
sink(1) = 0.0 ; h_minus_dsink(1) = (h_old(i,j,1) + sink(2))
32153214

32163215
!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,
32313230
do k=2,nz-1
32323231
c1(k) = eb(i,j,k-1) * b1
32333232
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
32343236
b1 = 1.0 / (b_denom_1 + eb(i,j,k))
32353237
d1 = b_denom_1 * b1
32363238

@@ -3315,10 +3317,11 @@ subroutine g_tracer_vertdiff_M(g_tracer,dh, dhw, diff_cbt, dt, rho0,tau)
33153317

33163318
GOLDtridiag = .true.
33173319
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
33223325

33233326
eps = 1.e-30
33243327

@@ -3424,6 +3427,11 @@ subroutine g_tracer_vertdiff_M(g_tracer,dh, dhw, diff_cbt, dt, rho0,tau)
34243427
wabsl = abs(g_tracer%vmove(i,j,k))
34253428
wposl(i,k) = fact2*(g_tracer%vmove(i,j,k ) + wabsl)*g_tracer_com%grid_tmask(i,j,kp1)
34263429
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
34273435
a1(i,k) = dcb(i,j,km1)*factu*g_tracer_com%grid_tmask(i,j,k)
34283436
c1(i,k) = dcb(i,j,k) *factl*g_tracer_com%grid_tmask(i,j,kp1)
34293437
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)
34333441
enddo
34343442
enddo
34353443

3444+
! Set boundary conditions (zero flow out the top and bottom of the water column)
34363445
do i=g_tracer_com%isc,g_tracer_com%iec
34373446
a1(i,1) = 0.0
34383447
wnegu(i,1) = 0.0; wposu(i,1) = 0.0
34393448
a(i,1) = 0.0
34403449
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]
34423452
c(i,g_tracer_com%nk) = 0.0
34433453
b(i,1) = 1.0 + a1(i,1) + c1(i,1) - wnegl(i,1) + wposu(i,1)
34443454
b(i,g_tracer_com%nk) = 1.0 + a1(i,g_tracer_com%nk) + c1(i,g_tracer_com%nk) &

0 commit comments

Comments
 (0)