Skip to content

Commit cce3c37

Browse files
committed
Improvements from Luke Van Roekel
This branch adds an option to revert a part of the computation of the similarity similarity functions in the turbulent scales routine to the original Large et al. (1994) formulation. In particular this applies to the stable buoyancy forcing with wind stress case. In KPP, the similarity function in this regime is given as 1 + 5*zeta where zeta == sigma * OBL_depth / Monin_obukhov_length and sigma == depth/OBL_depth In Large et al. (1994), zeta is allowed to vary from 0 to 1. This is mostly an assumption that scalings in the surface layer continue through the boundary layer. However, Appendix B of Large et al. (1994) reference some observational support for this. In Danabasoglu et al. (2006), Appendix A, zeta is confined to run between zero and epsilon, where epsilon == surface layer extent / OBL_depth (usually taken as 0.1). This was done to increase the unresolved velocity shear in the bulk richardson number calculation (see Equations A1 and A2 of Danabasoglu et al (2006)). In tests conducted against LES (I am using the NCAR LES) forced by a constant wind stress and positive buoyancy forcing, the corresponding SCM result without the limitation on zeta is closer to LES. In this branch you can set l_LMD_ws in the cvmix_kpp_init routine. If this is set to true, the limitaton on zeta is removed in stable buoyancy forcing conditions, assuming the windstress is not zero. The default for this flag is false, so doing nothing will result in the current CVMIX implementation.
1 parent e7d5e80 commit cce3c37

File tree

1 file changed

+51
-22
lines changed

1 file changed

+51
-22
lines changed

src/shared/cvmix_kpp.F90

Lines changed: 51 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,14 @@ module cvmix_kpp
174174
logical :: lenhanced_entr ! True => enhance entrainment by adding
175175
! Stokes shear to the unresolved
176176
! vertial shear
177+
logical :: l_LMD_ws ! flag to use original Large et al. (1994)
178+
! equations for computing turbulent scales
179+
! rather than the updated methodology in
180+
! Danabasoglu et al. (2006). The latter
181+
! limits sigma to be < surf_layer_extent
182+
! when computing turbulent scales while
183+
! the former only imposes this restriction
184+
! in unstable regimes.
177185
end type cvmix_kpp_params_type
178186

179187
!EOP
@@ -192,7 +200,7 @@ subroutine cvmix_init_kpp(ri_crit, minOBLdepth, maxOBLdepth, minVtsqr, &
192200
Cv, interp_type, interp_type2, MatchTechnique, &
193201
old_vals, lEkman, lMonOb, lnoDGat1, &
194202
lenhanced_diff, lnonzero_surf_nonlocal, &
195-
llangmuirEF, lenhanced_entr, &
203+
llangmuirEF, lenhanced_entr, l_LMD_ws, &
196204
CVmix_kpp_params_user)
197205

198206
! !DESCRIPTION:
@@ -225,7 +233,8 @@ subroutine cvmix_init_kpp(ri_crit, minOBLdepth, maxOBLdepth, minVtsqr, &
225233
lenhanced_diff, &
226234
llangmuirEF, &
227235
lenhanced_entr, &
228-
lnonzero_surf_nonlocal
236+
lnonzero_surf_nonlocal, &
237+
l_LMD_ws
229238

230239
! !OUTPUT PARAMETERS:
231240
type(cvmix_kpp_params_type), intent(inout), target, optional :: &
@@ -501,6 +510,15 @@ subroutine cvmix_init_kpp(ri_crit, minOBLdepth, maxOBLdepth, minVtsqr, &
501510
end if
502511
call cvmix_put_kpp('nonlocal_coeff',nonlocal_coeff,CVmix_kpp_params_user)
503512

513+
! By default, use sigma construction from Danabasoglu et al. when computing
514+
! turbulent scales. Set l_LMD_ws = .true. to use Large et al. construction.
515+
if (present(l_LMD_ws)) then
516+
call cvmix_put_kpp('l_LMD_ws', l_LMD_ws, &
517+
CVmix_kpp_params_user)
518+
else
519+
call cvmix_put_kpp('l_LMD_ws', .false., CVmix_kpp_params_user)
520+
end if
521+
504522
!EOC
505523

506524
end subroutine cvmix_init_kpp
@@ -1168,6 +1186,8 @@ subroutine cvmix_put_kpp_logical(varname, val, CVmix_kpp_params_user)
11681186
CVmix_kpp_params_out%llangmuirEF = val
11691187
case ('lenhanced_entr')
11701188
CVmix_kpp_params_out%lenhanced_entr = val
1189+
case ('l_LMD_ws')
1190+
CVmix_kpp_params_out%l_LMD_ws = val
11711191
case DEFAULT
11721192
print*, "ERROR: ", trim(varname), " is not a boolean variable!"
11731193
stop 1
@@ -1864,8 +1884,8 @@ subroutine cvmix_kpp_compute_turbulent_scales_1d_sigma(sigma_coord, &
18641884

18651885
! Local variables
18661886
integer :: n_sigma, kw
1867-
logical :: compute_wm, compute_ws
1868-
real(cvmix_r8), dimension(size(sigma_coord)) :: zeta
1887+
logical :: compute_wm, compute_ws, l_LMD_ws
1888+
real(cvmix_r8), dimension(size(sigma_coord)) :: zeta, sigma_loc
18691889
real(cvmix_r8) :: vonkar, surf_layer_ext
18701890
type(cvmix_kpp_params_type), pointer :: CVmix_kpp_params_in
18711891

@@ -1878,16 +1898,21 @@ subroutine cvmix_kpp_compute_turbulent_scales_1d_sigma(sigma_coord, &
18781898

18791899
compute_wm = present(w_m)
18801900
compute_ws = present(w_s)
1881-
vonkar = cvmix_get_kpp_real('vonkarman', CVmix_kpp_params_in)
1882-
surf_layer_ext = cvmix_get_kpp_real('surf_layer_ext', CVmix_kpp_params_in)
1901+
1902+
l_LMD_ws = CVmix_kpp_params_in%l_LMD_ws
1903+
vonkar = CVmix_kpp_params_in%vonkarman
1904+
surf_layer_ext = CVmix_kpp_params_in%surf_layer_ext
18831905

18841906
if (surf_fric_vel.ne.cvmix_zero) then
1885-
do kw=1,n_sigma
1886-
! compute scales at sigma if sigma < surf_layer_ext, otherwise compute
1887-
! at surf_layer_ext
1888-
zeta(kw) = min(surf_layer_ext, sigma_coord(kw)) * OBL_depth * &
1889-
surf_buoy_force*vonkar/(surf_fric_vel**3)
1890-
end do
1907+
if ((surf_buoy_force.ge.cvmix_zero) .and. l_LMD_ws) then
1908+
sigma_loc(:) = sigma_coord(:)
1909+
else
1910+
sigma_loc(:) = min(surf_layer_ext, sigma_coord(:))
1911+
end if
1912+
! compute scales at sigma if sigma < surf_layer_ext, otherwise compute
1913+
! at surf_layer_ext
1914+
zeta(:) = sigma_loc(:) * OBL_depth * surf_buoy_force * vonkar / &
1915+
(surf_fric_vel**3)
18911916

18921917
if (compute_wm) then
18931918
w_m(1) = compute_phi_inv(zeta(1), CVmix_kpp_params_in, lphi_m=.true.)*&
@@ -2029,8 +2054,8 @@ subroutine cvmix_kpp_compute_turbulent_scales_1d_OBL(sigma_coord, &
20292054

20302055
! Local variables
20312056
integer :: n_sigma, kw
2032-
logical :: compute_wm, compute_ws
2033-
real(cvmix_r8), dimension(size(surf_buoy_force)) :: zeta
2057+
logical :: compute_wm, compute_ws, l_LMD_ws
2058+
real(cvmix_r8), dimension(size(surf_buoy_force)) :: zeta, sigma_loc
20342059
real(cvmix_r8) :: vonkar, surf_layer_ext
20352060
type(cvmix_kpp_params_type), pointer :: CVmix_kpp_params_in
20362061

@@ -2043,16 +2068,20 @@ subroutine cvmix_kpp_compute_turbulent_scales_1d_OBL(sigma_coord, &
20432068

20442069
compute_wm = present(w_m)
20452070
compute_ws = present(w_s)
2046-
vonkar = cvmix_get_kpp_real('vonkarman', CVmix_kpp_params_in)
2047-
surf_layer_ext = cvmix_get_kpp_real('surf_layer_ext', CVmix_kpp_params_in)
2071+
2072+
l_LMD_ws = CVmix_kpp_params_in%l_LMD_ws
2073+
vonkar = CVmix_kpp_params_in%vonkarman
2074+
surf_layer_ext = CVmix_kpp_params_in%surf_layer_ext
20482075

20492076
if (surf_fric_vel.ne.cvmix_zero) then
2050-
do kw=1,n_sigma
2051-
! compute scales at sigma if sigma < surf_layer_ext, otherwise compute
2052-
! at surf_layer_ext
2053-
zeta(kw) = min(surf_layer_ext, sigma_coord) * OBL_depth(kw) * &
2054-
surf_buoy_force(kw)*vonkar/(surf_fric_vel**3)
2055-
end do
2077+
sigma_loc = min(surf_layer_ext, sigma_coord)
2078+
if (l_LMD_ws) then
2079+
where (surf_buoy_force.ge.cvmix_zero)
2080+
sigma_loc = sigma_coord
2081+
end where
2082+
end if
2083+
zeta(:) = sigma_loc(:) * OBL_depth(:) * surf_buoy_force(:) * vonkar / &
2084+
(surf_fric_vel**3)
20562085

20572086
if (compute_wm) then
20582087
w_m(1) = compute_phi_inv(zeta(1), CVmix_kpp_params_in, lphi_m=.true.)*&

0 commit comments

Comments
 (0)