17 use cvmix_convection,
only : cvmix_init_conv, cvmix_coeffs_conv
18 use cvmix_kpp,
only : cvmix_kpp_compute_kobl_depth
20 implicit none ;
private
22 #include <MOM_memory.h>
24 public cvmix_conv_init, calculate_cvmix_conv, cvmix_conv_end, cvmix_conv_is_used
40 integer :: id_n2 = -1, id_kd_conv = -1, id_kv_conv = -1
45 character(len=40) :: mdl =
"MOM_CVMix_conv"
50 logical function cvmix_conv_init(Time, G, GV, US, param_file, diag, CS)
52 type(time_type),
intent(in) :: time
57 type(
diag_ctrl),
target,
intent(inout) :: diag
64 #include "version_variable.h"
66 if (
associated(cs))
then
67 call mom_error(warning,
"CVMix_conv_init called with an associated "// &
74 call get_param(param_file, mdl,
"USE_CVMix_CONVECTION", cvmix_conv_init, default=.false., do_not_log=.true.)
76 "Parameterization of enhanced mixing due to convection via CVMix", &
77 all_default=.not.cvmix_conv_init)
78 call get_param(param_file, mdl,
"USE_CVMix_CONVECTION", cvmix_conv_init, &
79 "If true, turns on the enhanced mixing due to convection "//&
80 "via CVMix. This scheme increases diapycnal diffs./viscs. "//&
81 "at statically unstable interfaces. Relevant parameters are "//&
82 "contained in the CVMix_CONVECTION% parameter block.", &
85 if (.not. cvmix_conv_init)
return
87 call get_param(param_file, mdl,
"ENERGETICS_SFC_PBL", useepbl, default=.false., &
93 call mom_error(warning,
'MOM_CVMix_conv_init: '// &
94 'CVMix convection may not be properly applied when ENERGETICS_SFC_PBL = True'//&
95 'as convective mixing might occur in the boundary layer.')
98 call get_param(param_file, mdl,
'DEBUG', cs%debug, default=.false., do_not_log=.true.)
100 call get_param(param_file, mdl,
'MIN_THICKNESS', cs%min_thickness, default=0.001, do_not_log=.true.)
102 call openparameterblock(param_file,
'CVMix_CONVECTION')
104 call get_param(param_file, mdl,
"PRANDTL_CONV", prandtl_conv, &
105 "The turbulent Prandtl number applied to convective "//&
106 "instabilities (i.e., used to convert KD_CONV into KV_CONV)", &
107 units=
"nondim", default=1.0)
109 call get_param(param_file, mdl,
'KD_CONV', cs%kd_conv_const, &
110 "Diffusivity used in convective regime. Corresponding viscosity "//&
111 "(KV_CONV) will be set to KD_CONV * PRANDTL_TURB.", &
112 units=
'm2/s', default=1.00)
114 call get_param(param_file, mdl,
'BV_SQR_CONV', cs%bv_sqr_conv, &
115 "Threshold for squared buoyancy frequency needed to trigger "//&
116 "Brunt-Vaisala parameterization.", &
117 units=
'1/s^2', default=0.0)
119 call closeparameterblock(param_file)
122 cs%kv_conv_const = cs%kd_conv_const * prandtl_conv
126 cs%id_N2 = register_diag_field(
'ocean_model',
'N2_conv', diag%axesTi, time, &
127 'Square of Brunt-Vaisala frequency used by MOM_CVMix_conv module',
'1/s2', conversion=us%s_to_T**2)
128 cs%id_kd_conv = register_diag_field(
'ocean_model',
'kd_conv', diag%axesTi, time, &
129 'Additional diffusivity added by MOM_CVMix_conv module',
'm2/s', conversion=us%Z2_T_to_m2_s)
130 cs%id_kv_conv = register_diag_field(
'ocean_model',
'kv_conv', diag%axesTi, time, &
131 'Additional viscosity added by MOM_CVMix_conv module',
'm2/s', conversion=us%Z2_T_to_m2_s)
133 call cvmix_init_conv(convect_diff=cs%kd_conv_const, &
134 convect_visc=cs%kv_conv_const, &
135 lbruntvaisala=.true., &
136 bvsqr_convect=cs%bv_sqr_conv)
138 end function cvmix_conv_init
142 subroutine calculate_cvmix_conv(h, tv, G, GV, US, CS, hbl, Kd, Kv, Kd_aux)
147 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)),
intent(in) :: h
151 real,
dimension(SZI_(G),SZJ_(G)),
intent(in) :: hbl
152 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)+1), &
153 optional,
intent(inout) :: kd
155 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)+1), &
156 optional,
intent(inout) :: kv
158 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)+1), &
159 optional,
intent(inout) :: kd_aux
164 real,
dimension(SZK_(GV)) :: rho_lwr
167 real,
dimension(SZK_(GV)) :: rho_1d
169 real,
dimension(SZK_(GV)+1) :: n2
170 real,
dimension(SZK_(GV)+1) :: kv_col
171 real,
dimension(SZK_(GV)+1) :: kd_col
172 real,
dimension(SZK_(GV)+1) :: ifaceheight
173 real,
dimension(SZK_(GV)) :: cellheight
174 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)+1) :: &
175 kd_conv, & !< Diffusivity added by convection for diagnostics [Z2 T-1 ~> m2 s-1]
176 kv_conv, & !< Viscosity added by convection for diagnostics [Z2 T-1 ~> m2 s-1]
188 g_o_rho0 = us%L_to_Z**2*us%s_to_T**2 * gv%g_Earth / gv%Rho0
191 rho_lwr(:) = 0.0 ; rho_1d(:) = 0.0
194 n2(1) = 0.0 ; n2(gv%ke+1) = 0.0
196 if (cs%id_N2 > 0) n2_3d(:,:,:) = 0.0
197 if (cs%id_kv_conv > 0) kv_conv(:,:,:) = 0.0
198 if (cs%id_kd_conv > 0) kd_conv(:,:,:) = 0.0
206 pref = 0. ;
if (
associated(tv%p_surf)) pref = tv%p_surf(i,j)
211 pref = pref + (gv%H_to_RZ*gv%g_Earth) * h(i,j,k)
213 call calculate_density(tv%t(i,j,k-1), tv%s(i,j,k-1), pref, rhokm1, tv%eqn_of_state)
215 dz = ((0.5*(h(i,j,k-1) + h(i,j,k))+gv%H_subroundoff)*gv%H_to_Z)
216 n2(k) = g_o_rho0 * (rhok - rhokm1) / dz
224 dh = h(i,j,k) * gv%H_to_m
226 hcorr = min( dh - cs%min_thickness, 0. )
227 dh = max( dh, cs%min_thickness )
228 cellheight(k) = ifaceheight(k) - 0.5 * dh
229 ifaceheight(k+1) = ifaceheight(k) - dh
233 hbl_kpp = us%Z_to_m*hbl(i,j)
234 kobl = cvmix_kpp_compute_kobl_depth(ifaceheight, cellheight, hbl_kpp)
236 kv_col(:) = 0.0 ; kd_col(:) = 0.0
237 call cvmix_coeffs_conv(mdiff_out=kv_col(:), &
238 tdiff_out=kd_col(:), &
241 dens_lwr=rho_lwr(:), &
246 if (
present(kd))
then
248 do k=max(1,kobl+1),gv%ke+1
249 kd(i,j,k) = kd(i,j,k) + us%m2_s_to_Z2_T * kd_col(k)
252 if (
present(kd_aux))
then
254 do k=max(1,kobl+1),gv%ke+1
255 kd_aux(i,j,k) = kd_aux(i,j,k) + us%m2_s_to_Z2_T * kd_col(k)
259 if (
present(kv))
then
261 do k=max(1,kobl+1),gv%ke+1
262 kv(i,j,k) = kv(i,j,k) + us%m2_s_to_Z2_T * kv_col(k)
267 if (cs%id_kv_conv > 0)
then
269 do k=max(1,kobl+1),gv%ke+1
270 kv_conv(i,j,k) = us%m2_s_to_Z2_T * kv_col(k)
273 if (cs%id_kd_conv > 0)
then
275 do k=max(1,kobl+1),gv%ke+1
276 kd_conv(i,j,k) = us%m2_s_to_Z2_T * kd_col(k)
280 if (cs%id_N2 > 0)
then ;
do k=2,gv%ke ; n2_3d(i,j,k) = us%T_to_s**2*n2(k) ;
enddo ;
endif
291 if (
present(kd))
call hchksum(kv,
"MOM_CVMix_conv: Kd", g%HI, haloshift=0, scale=us%m2_s_to_Z2_T)
292 if (
present(kv))
call hchksum(kv,
"MOM_CVMix_conv: Kv", g%HI, haloshift=0, scale=us%m2_s_to_Z2_T)
296 if (cs%id_N2 > 0)
call post_data(cs%id_N2, n2_3d, cs%diag)
297 if (cs%id_kd_conv > 0)
call post_data(cs%id_kd_conv, kd_conv, cs%diag)
298 if (cs%id_kv_conv > 0)
call post_data(cs%id_kv_conv, kv_conv, cs%diag)
300 end subroutine calculate_cvmix_conv
305 logical function cvmix_conv_is_used(param_file)
307 call get_param(param_file, mdl,
"USE_CVMix_CONVECTION", cvmix_conv_is_used, &
308 default=.false., do_not_log = .true.)
310 end function cvmix_conv_is_used
313 subroutine cvmix_conv_end(CS)
317 if (.not.
associated(cs))
return
321 end subroutine cvmix_conv_end