Skip to content

Commit 99edf23

Browse files
Hallberg-NOAAalperaltuntas
authored andcommitted
*+Make Leith viscosity runs layout-invariant
Added the new function hor_visc_vel_stencil to return the velocity stencil of the velocity fields used by horizontal_viscosity depending on the options that are in use, and then use this information in the group_pass calls for the velocities that are passed to horizontal_viscosity. Also adjusted the size of the loops used to set up DX_dyBu and DY_dxBu in the hor_visc control structure depending on the horizontal viscosity options and added a test in hor_visc_init for a large enough halo size for the options that are in use. Both of these answer-changing modifications are necessary for MOM6 to reproduce across PE count and layout) when Leith viscosity parameterizations are in use. The MOM_hor_visc code was also revised slightly in several places to more closely adhere to MOM6 style with respect to using a 2-point indent and similar purely cosmetic considerations. This commit does change answers when a Leith viscosity is in use, and adds a new publicly visible function. Answers are bitwise identical when a Leith viscosity is not being used.
1 parent 8a03b63 commit 99edf23

File tree

2 files changed

+59
-31
lines changed

2 files changed

+59
-31
lines changed

src/core/MOM_dynamics_split_RK2.F90

+8-7
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ module MOM_dynamics_split_RK2
4848
use MOM_debugging, only : check_redundant
4949
use MOM_grid, only : ocean_grid_type
5050
use MOM_hor_index, only : hor_index_type
51-
use MOM_hor_visc, only : horizontal_viscosity, hor_visc_CS
51+
use MOM_hor_visc, only : horizontal_viscosity, hor_visc_CS, hor_visc_vel_stencil
5252
use MOM_hor_visc, only : hor_visc_init, hor_visc_end
5353
use MOM_interface_heights, only : thickness_to_dz, find_col_avg_SpV
5454
use MOM_lateral_mixing_coeffs, only : VarMix_CS
@@ -401,7 +401,7 @@ subroutine step_MOM_dyn_split_RK2(u, v, h, tv, visc, Time_local, dt, forces, p_s
401401
logical :: showCallTree, sym
402402

403403
integer :: i, j, k, is, ie, js, je, Isq, Ieq, Jsq, Jeq, nz
404-
integer :: cont_stencil, obc_stencil
404+
integer :: cont_stencil, obc_stencil, vel_stencil
405405

406406
is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke
407407
Isq = G%IscB ; Ieq = G%IecB ; Jsq = G%JscB ; Jeq = G%JecB
@@ -468,19 +468,20 @@ subroutine step_MOM_dyn_split_RK2(u, v, h, tv, visc, Time_local, dt, forces, p_s
468468
if (associated(CS%OBC)) then
469469
if (CS%OBC%oblique_BCs_exist_globally) obc_stencil = 3
470470
endif
471+
vel_stencil = max(2, obc_stencil, hor_visc_vel_stencil(CS%hor_visc))
471472
call cpu_clock_begin(id_clock_pass)
472473
call create_group_pass(CS%pass_eta, eta, G%Domain, halo=1)
473474
call create_group_pass(CS%pass_visc_rem, CS%visc_rem_u, CS%visc_rem_v, G%Domain, &
474475
To_All+SCALAR_PAIR, CGRID_NE, halo=max(1,cont_stencil))
475476
call create_group_pass(CS%pass_uvp, up, vp, G%Domain, halo=max(1,cont_stencil))
476477
call create_group_pass(CS%pass_hp_uv, hp, G%Domain, halo=2)
477-
call create_group_pass(CS%pass_hp_uv, u_av, v_av, G%Domain, halo=max(2,obc_stencil))
478-
call create_group_pass(CS%pass_hp_uv, uh(:,:,:), vh(:,:,:), G%Domain, halo=max(2,obc_stencil))
478+
call create_group_pass(CS%pass_hp_uv, u_av, v_av, G%Domain, halo=vel_stencil)
479+
call create_group_pass(CS%pass_hp_uv, uh(:,:,:), vh(:,:,:), G%Domain, halo=vel_stencil)
479480

480481
call create_group_pass(CS%pass_uv, u, v, G%Domain, halo=max(2,cont_stencil))
481482
call create_group_pass(CS%pass_h, h, G%Domain, halo=max(2,cont_stencil))
482-
call create_group_pass(CS%pass_av_uvh, u_av, v_av, G%Domain, halo=max(2,obc_stencil))
483-
call create_group_pass(CS%pass_av_uvh, uh(:,:,:), vh(:,:,:), G%Domain, halo=max(2,obc_stencil))
483+
call create_group_pass(CS%pass_av_uvh, u_av, v_av, G%Domain, halo=vel_stencil)
484+
call create_group_pass(CS%pass_av_uvh, uh(:,:,:), vh(:,:,:), G%Domain, halo=vel_stencil)
484485
call cpu_clock_end(id_clock_pass)
485486
!--- end set up for group halo pass
486487

@@ -841,7 +842,7 @@ subroutine step_MOM_dyn_split_RK2(u, v, h, tv, visc, Time_local, dt, forces, p_s
841842

842843
if (CS%debug) then
843844
call MOM_state_chksum("Predictor ", up, vp, hp, uh, vh, G, GV, US, symmetric=sym)
844-
call uvchksum("Predictor avg [uv]", u_av, v_av, G%HI, haloshift=1, symmetric=sym, scale=US%L_T_to_m_s)
845+
call uvchksum("Predictor avg [uv]", u_av, v_av, G%HI, haloshift=vel_stencil, symmetric=sym, scale=US%L_T_to_m_s)
845846
call hchksum(h_av, "Predictor avg h", G%HI, haloshift=0, scale=GV%H_to_MKS)
846847
! call MOM_state_chksum("Predictor avg ", u_av, v_av, h_av, uh, vh, G, GV, US)
847848
call check_redundant("Predictor up ", up, vp, G, unscale=US%L_T_to_m_s)

src/parameterizations/lateral/MOM_hor_visc.F90

+51-24
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ module MOM_hor_visc
3131

3232
#include <MOM_memory.h>
3333

34-
public horizontal_viscosity, hor_visc_init, hor_visc_end
34+
public horizontal_viscosity, hor_visc_init, hor_visc_end, hor_visc_vel_stencil
3535

3636
!> Control structure for horizontal viscosity
3737
type, public :: hor_visc_CS ; private
@@ -1198,10 +1198,9 @@ subroutine horizontal_viscosity(u, v, h, diffu, diffv, MEKE, VarMix, G, GV, US,
11981198
if ((CS%Smagorinsky_Ah) .or. (CS%Leith_Ah) .or. (CS%use_Leithy)) then
11991199
if (CS%Smagorinsky_Ah) then
12001200
if (CS%bound_Coriolis) then
1201-
do j=js_Kh,je_Kh ; do i=is_Kh,ie_Kh
1201+
do j=js_Kh,je_Kh ; do i=is_Kh,ie_Kh
12021202
AhSm = Shear_mag(i,j) * (CS%Biharm_const_xx(i,j) &
1203-
+ CS%Biharm_const2_xx(i,j) * Shear_mag(i,j) &
1204-
)
1203+
+ CS%Biharm_const2_xx(i,j) * Shear_mag(i,j))
12051204
Ah(i,j) = max(Ah(i,j), AhSm)
12061205
enddo ; enddo
12071206
else
@@ -1432,10 +1431,7 @@ subroutine horizontal_viscosity(u, v, h, diffu, diffv, MEKE, VarMix, G, GV, US,
14321431

14331432
! Pass the velocity gradients and thickness to ZB2020
14341433
if (CS%use_ZB2020) then
1435-
call ZB2020_copy_gradient_and_thickness( &
1436-
sh_xx, sh_xy, vort_xy, &
1437-
hq, &
1438-
G, GV, CS%ZB2020, k)
1434+
call ZB2020_copy_gradient_and_thickness(sh_xx, sh_xy, vort_xy, hq, G, GV, CS%ZB2020, k)
14391435
endif
14401436

14411437
if (CS%Laplacian) then
@@ -1575,8 +1571,7 @@ subroutine horizontal_viscosity(u, v, h, diffu, diffv, MEKE, VarMix, G, GV, US,
15751571
if (CS%bound_Coriolis) then
15761572
do J=js-1,Jeq ; do I=is-1,Ieq
15771573
AhSm = Shear_mag(I,J) * (CS%Biharm_const_xy(I,J) &
1578-
+ CS%Biharm_const2_xy(I,J) * Shear_mag(I,J) &
1579-
)
1574+
+ CS%Biharm_const2_xy(I,J) * Shear_mag(I,J))
15801575
Ah(I,J) = max(Ah(I,J), AhSm)
15811576
enddo ; enddo
15821577
else
@@ -1605,8 +1600,7 @@ subroutine horizontal_viscosity(u, v, h, diffu, diffv, MEKE, VarMix, G, GV, US,
16051600
! *Add* the MEKE contribution
16061601
do J=js-1,Jeq ; do I=is-1,Ieq
16071602
Ah(I,J) = Ah(I,J) + 0.25 * ( &
1608-
(MEKE%Au(i,j) + MEKE%Au(i+1,j+1)) + (MEKE%Au(i+1,j) + MEKE%Au(i,j+1)) &
1609-
)
1603+
(MEKE%Au(i,j) + MEKE%Au(i+1,j+1)) + (MEKE%Au(i+1,j) + MEKE%Au(i,j+1)) )
16101604
enddo ; enddo
16111605
endif
16121606

@@ -1897,11 +1891,15 @@ subroutine horizontal_viscosity(u, v, h, diffu, diffv, MEKE, VarMix, G, GV, US,
18971891

18981892
if (CS%debug) then
18991893
if (CS%Laplacian) then
1894+
! In symmetric memory mode, Kh_h should also be valid with a haloshift of 1.
19001895
call hchksum(Kh_h, "Kh_h", G%HI, haloshift=0, scale=US%L_to_m**2*US%s_to_T)
1901-
call Bchksum(Kh_q, "Kh_q", G%HI, haloshift=0, scale=US%L_to_m**2*US%s_to_T)
1896+
call Bchksum(Kh_q, "Kh_q", G%HI, haloshift=0, symmetric=.true., scale=US%L_to_m**2*US%s_to_T)
1897+
endif
1898+
if (CS%biharmonic) then
1899+
! In symmetric memory mode, Ah_h should also be valid with a haloshift of 1.
1900+
call hchksum(Ah_h, "Ah_h", G%HI, haloshift=0, scale=US%L_to_m**4*US%s_to_T)
1901+
call Bchksum(Ah_q, "Ah_q", G%HI, haloshift=0, symmetric=.true., scale=US%L_to_m**4*US%s_to_T)
19021902
endif
1903-
if (CS%biharmonic) call hchksum(Ah_h, "Ah_h", G%HI, haloshift=0, scale=US%L_to_m**4*US%s_to_T)
1904-
if (CS%biharmonic) call Bchksum(Ah_q, "Ah_q", G%HI, haloshift=0, scale=US%L_to_m**4*US%s_to_T)
19051903
endif
19061904

19071905
if (CS%id_FrictWorkIntz > 0) then
@@ -2403,14 +2401,31 @@ subroutine hor_visc_init(Time, G, GV, US, param_file, diag, CS, ADp)
24032401
ALLOC_(CS%m_leithy_max(isd:ied,jsd:jed)) ; CS%m_leithy_max(:,:) = 0.0
24042402
endif
24052403
if (CS%Re_Ah > 0.0) then
2406-
ALLOC_(CS%Re_Ah_const_xx(isd:ied,jsd:jed)); CS%Re_Ah_const_xx(:,:) = 0.0
2407-
ALLOC_(CS%Re_Ah_const_xy(IsdB:IedB,JsdB:JedB)); CS%Re_Ah_const_xy(:,:) = 0.0
2404+
ALLOC_(CS%Re_Ah_const_xx(isd:ied,jsd:jed)) ; CS%Re_Ah_const_xx(:,:) = 0.0
2405+
ALLOC_(CS%Re_Ah_const_xy(IsdB:IedB,JsdB:JedB)) ; CS%Re_Ah_const_xy(:,:) = 0.0
24082406
endif
24092407
endif
24102408
do J=js-2,Jeq+1 ; do I=is-2,Ieq+1
24112409
CS%dx2q(I,J) = G%dxBu(I,J)*G%dxBu(I,J) ; CS%dy2q(I,J) = G%dyBu(I,J)*G%dyBu(I,J)
2412-
CS%DX_dyBu(I,J) = G%dxBu(I,J)*G%IdyBu(I,J) ; CS%DY_dxBu(I,J) = G%dyBu(I,J)*G%IdxBu(I,J)
24132410
enddo ; enddo
2411+
2412+
if (((CS%Leith_Kh) .or. (CS%Leith_Ah) .or. (CS%use_Leithy)) .and. &
2413+
((G%isc-G%isd < 3) .or. (G%isc-G%isd < 3))) call MOM_error(FATAL, &
2414+
"The minimum halo size is 3 when a Leith viscosity is being used.")
2415+
if (CS%use_Leithy) then
2416+
do J=js-3,Jeq+2 ; do I=is-3,Ieq+2
2417+
CS%DX_dyBu(I,J) = G%dxBu(I,J)*G%IdyBu(I,J) ; CS%DY_dxBu(I,J) = G%dyBu(I,J)*G%IdxBu(I,J)
2418+
enddo ; enddo
2419+
elseif ((CS%Leith_Kh) .or. (CS%Leith_Ah)) then
2420+
do J=Jsq-2,Jeq+2 ; do I=Isq-2,Ieq+2
2421+
CS%DX_dyBu(I,J) = G%dxBu(I,J)*G%IdyBu(I,J) ; CS%DY_dxBu(I,J) = G%dyBu(I,J)*G%IdxBu(I,J)
2422+
enddo ; enddo
2423+
else
2424+
do J=js-2,Jeq+1 ; do I=is-2,Ieq+1
2425+
CS%DX_dyBu(I,J) = G%dxBu(I,J)*G%IdyBu(I,J) ; CS%DY_dxBu(I,J) = G%dyBu(I,J)*G%IdxBu(I,J)
2426+
enddo ; enddo
2427+
endif
2428+
24142429
do j=js-2,Jeq+2 ; do i=is-2,Ieq+2
24152430
CS%dx2h(i,j) = G%dxT(i,j)*G%dxT(i,j) ; CS%dy2h(i,j) = G%dyT(i,j)*G%dyT(i,j)
24162431
CS%DX_dyT(i,j) = G%dxT(i,j)*G%IdyT(i,j) ; CS%DY_dxT(i,j) = G%dyT(i,j)*G%IdxT(i,j)
@@ -2541,12 +2556,12 @@ subroutine hor_visc_init(Time, G, GV, US, param_file, diag, CS, ADp)
25412556
endif
25422557
endif
25432558
if (CS%Leith_Ah) then
2544-
CS%biharm6_const_xx(i,j) = Leith_bi_const * (grid_sp_h3 * grid_sp_h3)
2559+
CS%biharm6_const_xx(i,j) = Leith_bi_const * (grid_sp_h3 * grid_sp_h3)
25452560
endif
25462561
if (CS%use_Leithy) then
2547-
CS%biharm6_const_xx(i,j) = Leith_bi_const * max(G%dxT(i,j),G%dyT(i,j))**6
2548-
CS%m_const_leithy(i,j) = 0.5 * sqrt(CS%c_K) * max(G%dxT(i,j),G%dyT(i,j))
2549-
CS%m_leithy_max(i,j) = 4. / max(G%dxT(i,j),G%dyT(i,j))**2
2562+
CS%biharm6_const_xx(i,j) = Leith_bi_const * max(G%dxT(i,j),G%dyT(i,j))**6
2563+
CS%m_const_leithy(i,j) = 0.5 * sqrt(CS%c_K) * max(G%dxT(i,j),G%dyT(i,j))
2564+
CS%m_leithy_max(i,j) = 4. / max(G%dxT(i,j),G%dyT(i,j))**2
25502565
endif
25512566
CS%Ah_bg_xx(i,j) = MAX(Ah, Ah_vel_scale * grid_sp_h2 * sqrt(grid_sp_h2))
25522567
if (CS%Re_Ah > 0.0) CS%Re_Ah_const_xx(i,j) = grid_sp_h3 / CS%Re_Ah
@@ -2571,12 +2586,12 @@ subroutine hor_visc_init(Time, G, GV, US, param_file, diag, CS, ADp)
25712586
endif
25722587
endif
25732588
if ((CS%Leith_Ah) .or. (CS%use_Leithy))then
2574-
CS%biharm6_const_xy(I,J) = Leith_bi_const * (grid_sp_q3 * grid_sp_q3)
2589+
CS%biharm6_const_xy(I,J) = Leith_bi_const * (grid_sp_q3 * grid_sp_q3)
25752590
endif
25762591
CS%Ah_bg_xy(I,J) = MAX(Ah, Ah_vel_scale * grid_sp_q2 * sqrt(grid_sp_q2))
25772592
if (CS%Re_Ah > 0.0) CS%Re_Ah_const_xy(i,j) = grid_sp_q3 / CS%Re_Ah
25782593
if (Ah_time_scale > 0.) CS%Ah_bg_xy(i,j) = &
2579-
MAX(CS%Ah_bg_xy(i,j), (grid_sp_q2 * grid_sp_q2) / Ah_time_scale)
2594+
MAX(CS%Ah_bg_xy(i,j), (grid_sp_q2 * grid_sp_q2) / Ah_time_scale)
25802595
if (CS%bound_Ah .and. .not.CS%better_bound_Ah) then
25812596
CS%Ah_Max_xy(I,J) = Ah_Limit * (grid_sp_q2 * grid_sp_q2)
25822597
CS%Ah_bg_xy(I,J) = MIN(CS%Ah_bg_xy(I,J), CS%Ah_Max_xy(I,J))
@@ -2822,6 +2837,18 @@ subroutine hor_visc_init(Time, G, GV, US, param_file, diag, CS, ADp)
28222837

28232838
end subroutine hor_visc_init
28242839

2840+
!> hor_visc_vel_stencil returns the horizontal viscosity input velocity stencil size
2841+
function hor_visc_vel_stencil(CS) result(stencil)
2842+
type(hor_visc_CS), intent(in) :: CS !< Control structure for horizontal viscosity
2843+
integer :: stencil !< The horizontal viscosity velocity stencil size with the current settings.
2844+
2845+
stencil = 2
2846+
2847+
if ((CS%Leith_Kh) .or. (CS%Leith_Ah) .or. (CS%use_Leithy)) then
2848+
stencil = 3
2849+
endif
2850+
end function hor_visc_vel_stencil
2851+
28252852
!> Calculates factors in the anisotropic orientation tensor to be align with the grid.
28262853
!! With n1=1 and n2=0, this recovers the approach of Large et al, 2001.
28272854
subroutine align_aniso_tensor_to_grid(CS, n1, n2)

0 commit comments

Comments
 (0)