MOM6
mom_cvmix_conv Module Reference

Detailed Description

Interface to CVMix convection scheme.

Data Types

type  cvmix_conv_cs
 Control structure including parameters for CVMix convection. More...
 

Functions/Subroutines

logical function, public cvmix_conv_init (Time, G, GV, US, param_file, diag, CS)
 Initialized the CVMix convection mixing routine. More...
 
subroutine, public calculate_cvmix_conv (h, tv, G, GV, US, CS, hbl, Kd, Kv, Kd_aux)
 Subroutine for calculating enhanced diffusivity/viscosity due to convection via CVMix. More...
 
logical function, public cvmix_conv_is_used (param_file)
 Reads the parameter "USE_CVMix_CONVECTION" and returns state. This function allows other modules to know whether this parameterization will be used without needing to duplicate the log entry. More...
 
subroutine, public cvmix_conv_end (CS)
 Clear pointers and dealocate memory. More...
 

Variables

character(len=40) mdl = "MOM_CVMix_conv"
 This module's name.
 

Function/Subroutine Documentation

◆ calculate_cvmix_conv()

subroutine, public mom_cvmix_conv::calculate_cvmix_conv ( real, dimension( g %isd: g %ied, g %jsd: g %jed, gv %ke), intent(in)  h,
type(thermo_var_ptrs), intent(in)  tv,
type(ocean_grid_type), intent(in)  G,
type(verticalgrid_type), intent(in)  GV,
type(unit_scale_type), intent(in)  US,
type(cvmix_conv_cs), pointer  CS,
real, dimension( g %isd: g %ied, g %jsd: g %jed), intent(in)  hbl,
real, dimension( g %isd: g %ied, g %jsd: g %jed, g %ke+1), intent(inout), optional  Kd,
real, dimension( g %isd: g %ied, g %jsd: g %jed, g %ke+1), intent(inout), optional  Kv,
real, dimension( g %isd: g %ied, g %jsd: g %jed, g %ke+1), intent(inout), optional  Kd_aux 
)

Subroutine for calculating enhanced diffusivity/viscosity due to convection via CVMix.

Parameters
[in]gGrid structure.
[in]gvVertical grid structure.
[in]usA dimensional unit scaling type
[in]hLayer thickness [H ~> m or kg m-2].
[in]tvThermodynamics structure.
csThe control structure returned by a previous call to CVMix_conv_init.
[in]hblDepth of ocean boundary layer [Z ~> m]
[in,out]kdDiapycnal diffusivity at each interface that
[in,out]kvViscosity at each interface that will be
[in,out]kd_auxA second diapycnal diffusivity at each

Definition at line 143 of file MOM_CVMix_conv.F90.

143 
144  type(ocean_grid_type), intent(in) :: g !< Grid structure.
145  type(verticalgrid_type), intent(in) :: gv !< Vertical grid structure.
146  type(unit_scale_type), intent(in) :: us !< A dimensional unit scaling type
147  real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(in) :: h !< Layer thickness [H ~> m or kg m-2].
148  type(thermo_var_ptrs), intent(in) :: tv !< Thermodynamics structure.
149  type(cvmix_conv_cs), pointer :: cs !< The control structure returned
150  !! by a previous call to CVMix_conv_init.
151  real, dimension(SZI_(G),SZJ_(G)), intent(in) :: hbl !< Depth of ocean boundary layer [Z ~> m]
152  real, dimension(SZI_(G),SZJ_(G),SZK_(G)+1), &
153  optional, intent(inout) :: kd !< Diapycnal diffusivity at each interface that
154  !! will be incremented here [Z2 T-1 ~> m2 s-1].
155  real, dimension(SZI_(G),SZJ_(G),SZK_(G)+1), &
156  optional, intent(inout) :: kv !< Viscosity at each interface that will be
157  !! incremented here [Z2 T-1 ~> m2 s-1].
158  real, dimension(SZI_(G),SZJ_(G),SZK_(G)+1), &
159  optional, intent(inout) :: kd_aux !< A second diapycnal diffusivity at each
160  !! interface that will also be incremented
161  !! here [Z2 T-1 ~> m2 s-1].
162 
163  ! local variables
164  real, dimension(SZK_(GV)) :: rho_lwr !< Adiabatic Water Density, this is a dummy
165  !! variable since here convection is always
166  !! computed based on Brunt Vaisala.
167  real, dimension(SZK_(GV)) :: rho_1d !< water density in a column, this is also
168  !! a dummy variable, same reason as above.
169  real, dimension(SZK_(GV)+1) :: n2 !< Squared buoyancy frequency [s-2]
170  real, dimension(SZK_(GV)+1) :: kv_col !< Viscosities at interfaces in the column [m2 s-1]
171  real, dimension(SZK_(GV)+1) :: kd_col !< Diffusivities at interfaces in the column [m2 s-1]
172  real, dimension(SZK_(GV)+1) :: ifaceheight !< Height of interfaces [m]
173  real, dimension(SZK_(GV)) :: cellheight !< Height of cell centers [m]
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]
177  n2_3d !< Squared buoyancy frequency for diagnostics [N-2 ~> s-2]
178  integer :: kobl !< level of OBL extent
179  real :: g_o_rho0 ! Gravitational acceleration divided by density times unit convserion factors
180  ! [Z s-2 R-1 ~> m4 s-2 kg-1]
181  real :: pref ! Interface pressures [R L2 T-2 ~> Pa]
182  real :: rhok, rhokm1 ! In situ densities of the layers above and below at the interface pressure [R ~> kg m-3]
183  real :: hbl_kpp ! The depth of the ocean boundary as used by KPP [m]
184  real :: dz ! A thickness [Z ~> m]
185  real :: dh, hcorr ! Two thicknesses [m]
186  integer :: i, j, k
187 
188  g_o_rho0 = us%L_to_Z**2*us%s_to_T**2 * gv%g_Earth / gv%Rho0
189 
190  ! initialize dummy variables
191  rho_lwr(:) = 0.0 ; rho_1d(:) = 0.0
192 
193  ! set N2 to zero at the top- and bottom-most interfaces
194  n2(1) = 0.0 ; n2(gv%ke+1) = 0.0
195 
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
199 
200  do j = g%jsc, g%jec
201  do i = g%isc, g%iec
202 
203  ! skip calling at land points
204  !if (G%mask2dT(i,j) == 0.) cycle
205 
206  pref = 0. ; if (associated(tv%p_surf)) pref = tv%p_surf(i,j)
207  ! Compute Brunt-Vaisala frequency (static stability) on interfaces
208  do k=2,gv%ke
209 
210  ! pRef is pressure at interface between k and km1 [R L2 T-2 ~> Pa].
211  pref = pref + (gv%H_to_RZ*gv%g_Earth) * h(i,j,k)
212  call calculate_density(tv%t(i,j,k), tv%s(i,j,k), pref, rhok, tv%eqn_of_state)
213  call calculate_density(tv%t(i,j,k-1), tv%s(i,j,k-1), pref, rhokm1, tv%eqn_of_state)
214 
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 ! Can be negative
217 
218  enddo
219 
220  ifaceheight(1) = 0.0 ! BBL is all relative to the surface
221  hcorr = 0.0
222  ! compute heights at cell center and interfaces
223  do k=1,gv%ke
224  dh = h(i,j,k) * gv%H_to_m ! Nominal thickness to use for increment, in the units used by CVMix.
225  dh = dh + hcorr ! Take away the accumulated error (could temporarily make dh<0)
226  hcorr = min( dh - cs%min_thickness, 0. ) ! If inflating then hcorr<0
227  dh = max( dh, cs%min_thickness ) ! Limit increment dh>=min_thickness
228  cellheight(k) = ifaceheight(k) - 0.5 * dh
229  ifaceheight(k+1) = ifaceheight(k) - dh
230  enddo
231 
232  ! gets index of the level and interface above hbl
233  hbl_kpp = us%Z_to_m*hbl(i,j) ! Convert to the units used by CVMix.
234  kobl = cvmix_kpp_compute_kobl_depth(ifaceheight, cellheight, hbl_kpp)
235 
236  kv_col(:) = 0.0 ; kd_col(:) = 0.0
237  call cvmix_coeffs_conv(mdiff_out=kv_col(:), &
238  tdiff_out=kd_col(:), &
239  nsqr=n2(:), &
240  dens=rho_1d(:), &
241  dens_lwr=rho_lwr(:), &
242  nlev=gv%ke, &
243  max_nlev=gv%ke, &
244  obl_ind=kobl)
245 
246  if (present(kd)) then
247  ! Increment the diffusivity outside of the boundary layer.
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)
250  enddo
251  endif
252  if (present(kd_aux)) then
253  ! Increment the other diffusivity outside of the boundary layer.
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)
256  enddo
257  endif
258 
259  if (present(kv)) then
260  ! Increment the viscosity outside of the boundary layer.
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)
263  enddo
264  endif
265 
266  ! Store 3-d arrays for diagnostics.
267  if (cs%id_kv_conv > 0) then
268  ! Do not apply mixing due to convection within the boundary layer
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)
271  enddo
272  endif
273  if (cs%id_kd_conv > 0) then
274  ! Do not apply mixing due to convection within the boundary layer
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)
277  enddo
278  endif
279 
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
281 
282  enddo
283  enddo
284 
285  if (cs%debug) then
286  ! if (CS%id_N2 > 0) call hchksum(N2_3d, "MOM_CVMix_conv: N2",G%HI,haloshift=0)
287  ! if (CS%id_kd_conv > 0) &
288  ! call hchksum(Kd_conv, "MOM_CVMix_conv: Kd_conv", G%HI, haloshift=0, scale=US%Z2_T_to_m2_s)
289  ! if (CS%id_kv_conv > 0) &
290  ! call hchksum(Kv_conv, "MOM_CVMix_conv: Kv_conv", G%HI, haloshift=0, scale=US%m2_s_to_Z2_T)
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)
293  endif
294 
295  ! send diagnostics to post_data
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)
299 

◆ cvmix_conv_end()

subroutine, public mom_cvmix_conv::cvmix_conv_end ( type(cvmix_conv_cs), pointer  CS)

Clear pointers and dealocate memory.

Parameters
csControl structure for this module that will be deallocated in this subroutine

Definition at line 314 of file MOM_CVMix_conv.F90.

314  type(cvmix_conv_cs), pointer :: cs !< Control structure for this module that
315  !! will be deallocated in this subroutine
316 
317  if (.not. associated(cs)) return
318 
319  deallocate(cs)
320 

◆ cvmix_conv_init()

logical function, public mom_cvmix_conv::cvmix_conv_init ( type(time_type), intent(in)  Time,
type(ocean_grid_type), intent(in)  G,
type(verticalgrid_type), intent(in)  GV,
type(unit_scale_type), intent(in)  US,
type(param_file_type), intent(in)  param_file,
type(diag_ctrl), intent(inout), target  diag,
type(cvmix_conv_cs), pointer  CS 
)

Initialized the CVMix convection mixing routine.

Parameters
[in]timeThe current time.
[in]gGrid structure.
[in]gvVertical grid structure.
[in]usA dimensional unit scaling type
[in]param_fileRun-time parameter file handle
[in,out]diagDiagnostics control structure.
csThis module's control structure.

Definition at line 51 of file MOM_CVMix_conv.F90.

51 
52  type(time_type), intent(in) :: time !< The current time.
53  type(ocean_grid_type), intent(in) :: g !< Grid structure.
54  type(verticalgrid_type), intent(in) :: gv !< Vertical grid structure.
55  type(unit_scale_type), intent(in) :: us !< A dimensional unit scaling type
56  type(param_file_type), intent(in) :: param_file !< Run-time parameter file handle
57  type(diag_ctrl), target, intent(inout) :: diag !< Diagnostics control structure.
58  type(cvmix_conv_cs), pointer :: cs !< This module's control structure.
59  ! Local variables
60  real :: prandtl_conv !< Turbulent Prandtl number used in convective instabilities.
61  logical :: useepbl !< If True, use the ePBL boundary layer scheme.
62 
63 ! This include declares and sets the variable "version".
64 #include "version_variable.h"
65 
66  if (associated(cs)) then
67  call mom_error(warning, "CVMix_conv_init called with an associated "// &
68  "control structure.")
69  return
70  endif
71  allocate(cs)
72 
73  ! Read parameters
74  call get_param(param_file, mdl, "USE_CVMix_CONVECTION", cvmix_conv_init, default=.false., do_not_log=.true.)
75  call log_version(param_file, mdl, version, &
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.", &
83  default=.false.)
84 
85  if (.not. cvmix_conv_init) return
86 
87  call get_param(param_file, mdl, "ENERGETICS_SFC_PBL", useepbl, default=.false., &
88  do_not_log=.true.)
89 
90  ! Warn user if EPBL is being used, since in this case mixing due to convection will
91  ! be aplied in the boundary layer
92  if (useepbl) then
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.')
96  endif
97 
98  call get_param(param_file, mdl, 'DEBUG', cs%debug, default=.false., do_not_log=.true.)
99 
100  call get_param(param_file, mdl, 'MIN_THICKNESS', cs%min_thickness, default=0.001, do_not_log=.true.)
101 
102  call openparameterblock(param_file,'CVMix_CONVECTION')
103 
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)
108 
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)
113 
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)
118 
119  call closeparameterblock(param_file)
120 
121  ! set kv_conv_const based on kd_conv_const and prandtl_conv
122  cs%kv_conv_const = cs%kd_conv_const * prandtl_conv
123 
124  ! Register diagnostics
125  cs%diag => diag
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)
132 
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)
137 

◆ cvmix_conv_is_used()

logical function, public mom_cvmix_conv::cvmix_conv_is_used ( type(param_file_type), intent(in)  param_file)

Reads the parameter "USE_CVMix_CONVECTION" and returns state. This function allows other modules to know whether this parameterization will be used without needing to duplicate the log entry.

Parameters
[in]param_fileA structure to parse for run-time parameters

Definition at line 306 of file MOM_CVMix_conv.F90.

306  type(param_file_type), intent(in) :: param_file !< A structure to parse for run-time parameters
307  call get_param(param_file, mdl, "USE_CVMix_CONVECTION", cvmix_conv_is_used, &
308  default=.false., do_not_log = .true.)
309