MOM6
mom_bkgnd_mixing Module Reference

Detailed Description

Interface to background mixing schemes, including the Bryan and Lewis (1979) which is applied via CVMix.

Data Types

type  bkgnd_mixing_cs
 Control structure including parameters for this module. More...
 

Functions/Subroutines

subroutine, public bkgnd_mixing_init (Time, G, GV, US, param_file, diag, CS)
 Initialize the background mixing routine. More...
 
subroutine, public calculate_bkgnd_mixing (h, tv, N2_lay, Kd_lay, Kd_int, Kv_bkgnd, j, G, GV, US, CS)
 Calculates the vertical background diffusivities/viscosities. More...
 
logical function cvmix_bkgnd_is_used (param_file)
 Reads the parameter "USE_CVMix_BACKGROUND" 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 check_bkgnd_scheme (CS, str)
 Sets CSbkgnd_scheme_str to check whether multiple background diffusivity schemes are activated. The string is also for error/log messages. More...
 
subroutine, public bkgnd_mixing_end (CS)
 Clear pointers and dealocate memory. More...
 

Variables

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

Function/Subroutine Documentation

◆ bkgnd_mixing_end()

subroutine, public mom_bkgnd_mixing::bkgnd_mixing_end ( type(bkgnd_mixing_cs), pointer  CS)

Clear pointers and dealocate memory.

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

Definition at line 551 of file MOM_bkgnd_mixing.F90.

551  type(bkgnd_mixing_cs), pointer :: cs !< Control structure for this module that
552  !! will be deallocated in this subroutine
553 
554  if (.not. associated(cs)) return
555  deallocate(cs)
556 

◆ bkgnd_mixing_init()

subroutine, public mom_bkgnd_mixing::bkgnd_mixing_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(bkgnd_mixing_cs), pointer  CS 
)

Initialize the background 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 114 of file MOM_bkgnd_mixing.F90.

114 
115  type(time_type), intent(in) :: time !< The current time.
116  type(ocean_grid_type), intent(in) :: g !< Grid structure.
117  type(verticalgrid_type), intent(in) :: gv !< Vertical grid structure.
118  type(unit_scale_type), intent(in) :: us !< A dimensional unit scaling type
119  type(param_file_type), intent(in) :: param_file !< Run-time parameter file handle
120  type(diag_ctrl), target, intent(inout) :: diag !< Diagnostics control structure.
121  type(bkgnd_mixing_cs), pointer :: cs !< This module's control structure.
122 
123  ! Local variables
124  real :: kv ! The interior vertical viscosity [Z2 T-1 ~> m2 s-1] - read to set Prandtl
125  ! number unless it is provided as a parameter
126  real :: prandtl_bkgnd_comp ! Kv/CS%Kd. Gets compared with user-specified prandtl_bkgnd.
127 
128 ! This include declares and sets the variable "version".
129 #include "version_variable.h"
130 
131  if (associated(cs)) then
132  call mom_error(warning, "bkgnd_mixing_init called with an associated "// &
133  "control structure.")
134  return
135  endif
136  allocate(cs)
137 
138  ! Read parameters
139  call log_version(param_file, mdl, version, &
140  "Adding static vertical background mixing coefficients")
141 
142  call get_param(param_file, mdl, "KD", cs%Kd, &
143  "The background diapycnal diffusivity of density in the "//&
144  "interior. Zero or the molecular value, ~1e-7 m2 s-1, "//&
145  "may be used.", default=0.0, units="m2 s-1", scale=us%m2_s_to_Z2_T)
146 
147  call get_param(param_file, mdl, "KV", kv, &
148  "The background kinematic viscosity in the interior. "//&
149  "The molecular value, ~1e-6 m2 s-1, may be used.", &
150  units="m2 s-1", scale=us%m2_s_to_Z2_T, fail_if_missing=.true.)
151 
152  call get_param(param_file, mdl, "KD_MIN", cs%Kd_min, &
153  "The minimum diapycnal diffusivity.", &
154  units="m2 s-1", default=0.01*cs%Kd*us%Z2_T_to_m2_s, scale=us%m2_s_to_Z2_T)
155 
156  ! The following is needed to set one of the choices of vertical background mixing
157 
158  ! BULKMIXEDLAYER is not always defined (e.g., CM2G63L), so the following line by passes
159  ! the need to include BULKMIXEDLAYER in MOM_input
160  cs%bulkmixedlayer = (gv%nkml > 0)
161  if (cs%bulkmixedlayer) then
162  ! Check that Kdml is not set when using bulk mixed layer
163  call get_param(param_file, mdl, "KDML", cs%Kdml, default=-1.)
164  if (cs%Kdml>0.) call mom_error(fatal, &
165  "bkgnd_mixing_init: KDML cannot be set when using bulk mixed layer.")
166  cs%Kdml = cs%Kd ! This is not used with a bulk mixed layer, but also cannot be a NaN.
167  else
168  call get_param(param_file, mdl, "KDML", cs%Kdml, &
169  "If BULKMIXEDLAYER is false, KDML is the elevated "//&
170  "diapycnal diffusivity in the topmost HMIX of fluid. "//&
171  "KDML is only used if BULKMIXEDLAYER is false.", &
172  units="m2 s-1", default=cs%Kd*us%Z2_T_to_m2_s, scale=us%m2_s_to_Z2_T)
173  call get_param(param_file, mdl, "HMIX_FIXED", cs%Hmix, &
174  "The prescribed depth over which the near-surface "//&
175  "viscosity and diffusivity are elevated when the bulk "//&
176  "mixed layer is not used.", units="m", scale=us%m_to_Z, fail_if_missing=.true.)
177  endif
178 
179  call get_param(param_file, mdl, 'DEBUG', cs%debug, default=.false., do_not_log=.true.)
180 
181 ! call openParameterBlock(param_file,'MOM_BACKGROUND_MIXING')
182 
183  call get_param(param_file, mdl, "BRYAN_LEWIS_DIFFUSIVITY", cs%Bryan_Lewis_diffusivity, &
184  "If true, use a Bryan & Lewis (JGR 1979) like tanh "//&
185  "profile of background diapycnal diffusivity with depth. "//&
186  "This is done via CVMix.", default=.false.)
187 
188  if (cs%Bryan_Lewis_diffusivity) then
189  call check_bkgnd_scheme(cs, "BRYAN_LEWIS_DIFFUSIVITY")
190 
191  call get_param(param_file, mdl, "BRYAN_LEWIS_C1", cs%Bryan_Lewis_c1, &
192  "The vertical diffusivity values for Bryan-Lewis profile at |z|=D.", &
193  units="m2 s-1", fail_if_missing=.true.)
194 
195  call get_param(param_file, mdl, "BRYAN_LEWIS_C2", cs%Bryan_Lewis_c2, &
196  "The amplitude of variation in diffusivity for the Bryan-Lewis profile", &
197  units="m2 s-1", fail_if_missing=.true.)
198 
199  call get_param(param_file, mdl, "BRYAN_LEWIS_C3", cs%Bryan_Lewis_c3, &
200  "The inverse length scale for transition region in the Bryan-Lewis profile", &
201  units="m-1", fail_if_missing=.true.)
202 
203  call get_param(param_file, mdl, "BRYAN_LEWIS_C4", cs%Bryan_Lewis_c4, &
204  "The depth where diffusivity is BRYAN_LEWIS_C1 in the Bryan-Lewis profile",&
205  units="m", fail_if_missing=.true.)
206 
207  endif ! CS%Bryan_Lewis_diffusivity
208 
209  call get_param(param_file, mdl, "HORIZ_VARYING_BACKGROUND", cs%horiz_varying_background, &
210  "If true, apply vertically uniform, latitude-dependent background "//&
211  "diffusivity, as described in Danabasoglu et al., 2012", &
212  default=.false.)
213 
214  if (cs%horiz_varying_background) then
215  call check_bkgnd_scheme(cs, "HORIZ_VARYING_BACKGROUND")
216 
217  call get_param(param_file, mdl, "BCKGRND_VDC1", cs%bckgrnd_vdc1, &
218  "Background diffusivity (Ledwell) when HORIZ_VARYING_BACKGROUND=True", &
219  units="m2 s-1",default = 0.16e-04, scale=us%m2_s_to_Z2_T)
220 
221  call get_param(param_file, mdl, "BCKGRND_VDC_EQ", cs%bckgrnd_vdc_eq, &
222  "Equatorial diffusivity (Gregg) when HORIZ_VARYING_BACKGROUND=True", &
223  units="m2 s-1",default = 0.01e-04, scale=us%m2_s_to_Z2_T)
224 
225  call get_param(param_file, mdl, "BCKGRND_VDC_PSIM", cs%bckgrnd_vdc_psim, &
226  "Max. PSI induced diffusivity (MacKinnon) when HORIZ_VARYING_BACKGROUND=True", &
227  units="m2 s-1",default = 0.13e-4, scale=us%m2_s_to_Z2_T)
228 
229  call get_param(param_file, mdl, "BCKGRND_VDC_BAN", cs%bckgrnd_vdc_Banda, &
230  "Banda Sea diffusivity (Gordon) when HORIZ_VARYING_BACKGROUND=True", &
231  units="m2 s-1",default = 1.0e-4, scale=us%m2_s_to_Z2_T)
232  endif
233 
234  call get_param(param_file, mdl, "PRANDTL_BKGND", cs%prandtl_bkgnd, &
235  "Turbulent Prandtl number used to convert vertical "//&
236  "background diffusivities into viscosities.", &
237  units="nondim", default=1.0)
238 
239  if (cs%Bryan_Lewis_diffusivity .or. cs%horiz_varying_background) then
240 
241  prandtl_bkgnd_comp = cs%prandtl_bkgnd
242  if (cs%Kd /= 0.0) prandtl_bkgnd_comp = kv/cs%Kd
243 
244  if ( abs(cs%prandtl_bkgnd - prandtl_bkgnd_comp)>1.e-14) then
245  call mom_error(fatal,"set_diffusivity_init: The provided KD, KV,"//&
246  "and PRANDTL_BKGND values are incompatible. The following "//&
247  "must hold: KD*PRANDTL_BKGND==KV")
248  endif
249 
250  endif
251 
252  call get_param(param_file, mdl, "HENYEY_IGW_BACKGROUND", cs%Henyey_IGW_background, &
253  "If true, use a latitude-dependent scaling for the near "//&
254  "surface background diffusivity, as described in "//&
255  "Harrison & Hallberg, JPO 2008.", default=.false.)
256  if (cs%Henyey_IGW_background) call check_bkgnd_scheme(cs, "HENYEY_IGW_BACKGROUND")
257 
258 
259  call get_param(param_file, mdl, "HENYEY_IGW_BACKGROUND_NEW", cs%Henyey_IGW_background_new, &
260  "If true, use a better latitude-dependent scaling for the "//&
261  "background diffusivity, as described in "//&
262  "Harrison & Hallberg, JPO 2008.", default=.false.)
263  if (cs%Henyey_IGW_background_new) call check_bkgnd_scheme(cs, "HENYEY_IGW_BACKGROUND_NEW")
264 
265  if (cs%Kd>0.0 .and. (trim(cs%bkgnd_scheme_str)=="BRYAN_LEWIS_DIFFUSIVITY" .or.&
266  trim(cs%bkgnd_scheme_str)=="HORIZ_VARYING_BACKGROUND" )) then
267  call mom_error(warning, "set_diffusivity_init: a nonzero constant background "//&
268  "diffusivity (KD) is specified along with "//trim(cs%bkgnd_scheme_str))
269  endif
270 
271  if (cs%Henyey_IGW_background) then
272  call get_param(param_file, mdl, "HENYEY_N0_2OMEGA", cs%N0_2Omega, &
273  "The ratio of the typical Buoyancy frequency to twice "//&
274  "the Earth's rotation period, used with the Henyey "//&
275  "scaling from the mixing.", units="nondim", default=20.0)
276  call get_param(param_file, mdl, "OMEGA", cs%omega, &
277  "The rotation rate of the earth.", units="s-1", &
278  default=7.2921e-5, scale=us%T_to_s)
279  endif
280 
281  call get_param(param_file, mdl, "KD_TANH_LAT_FN", cs%Kd_tanh_lat_fn, &
282  "If true, use a tanh dependence of Kd_sfc on latitude, "//&
283  "like CM2.1/CM2M. There is no physical justification "//&
284  "for this form, and it can not be used with "//&
285  "HENYEY_IGW_BACKGROUND.", default=.false.)
286 
287  if (cs%Kd_tanh_lat_fn) &
288  call get_param(param_file, mdl, "KD_TANH_LAT_SCALE", cs%Kd_tanh_lat_scale, &
289  "A nondimensional scaling for the range ofdiffusivities "//&
290  "with KD_TANH_LAT_FN. Valid values are in the range of "//&
291  "-2 to 2; 0.4 reproduces CM2M.", units="nondim", default=0.0)
292 
293  if (cs%Henyey_IGW_background .and. cs%Kd_tanh_lat_fn) call mom_error(fatal, &
294  "MOM_bkgnd_mixing: KD_TANH_LAT_FN can not be used with HENYEY_IGW_BACKGROUND.")
295 
296  cs%Kd_via_Kdml_bug = .false.
297  if ((cs%Kd /= cs%Kdml) .and. .not.(cs%Kd_tanh_lat_fn .or. cs%bulkmixedlayer .or. &
298  cs%Henyey_IGW_background .or. cs%Henyey_IGW_background_new .or. &
299  cs%horiz_varying_background .or. cs%Bryan_Lewis_diffusivity)) then
300  call get_param(param_file, mdl, "KD_BACKGROUND_VIA_KDML_BUG", cs%Kd_via_Kdml_bug, &
301  "If true and KDML /= KD and several other conditions apply, the background "//&
302  "diffusivity is set incorrectly using a bug that was introduced in March, 2018.", &
303  default=.true.) ! The default should be changed to false and this parameter obsoleted.
304  endif
305 
306 ! call closeParameterBlock(param_file)
307 

◆ calculate_bkgnd_mixing()

subroutine, public mom_bkgnd_mixing::calculate_bkgnd_mixing ( real, dimension( g %isd: g %ied, g %jsd: g %jed, gv %ke), intent(in)  h,
type(thermo_var_ptrs), intent(in)  tv,
real, dimension( g %isd: g %ied, gv %ke), intent(in)  N2_lay,
real, dimension( g %isd: g %ied, gv %ke), intent(out)  Kd_lay,
real, dimension( g %isd: g %ied, gv %ke+1), intent(out)  Kd_int,
real, dimension( g %isd: g %ied, gv %ke+1), intent(out)  Kv_bkgnd,
integer, intent(in)  j,
type(ocean_grid_type), intent(in)  G,
type(verticalgrid_type), intent(in)  GV,
type(unit_scale_type), intent(in)  US,
type(bkgnd_mixing_cs), pointer  CS 
)

Calculates the vertical background diffusivities/viscosities.

Parameters
[in]gGrid structure.
[in]gvVertical grid structure.
[in]hLayer thickness [H ~> m or kg m-2].
[in]tvThermodynamics structure.
[in]n2_laysquared buoyancy frequency associated with layers [T-2 ~> s-2]
[out]kd_layThe background diapycnal diffusivity of each layer [Z2 T-1 ~> m2 s-1].
[out]kd_intThe background diapycnal diffusivity of each interface [Z2 T-1 ~> m2 s-1].
[out]kv_bkgndThe background vertical viscosity at each interface [Z2 T-1 ~> m2 s-1]
[in]jMeridional grid index
[in]usA dimensional unit scaling type
csThe control structure returned by a previous call to bkgnd_mixing_init.

Definition at line 312 of file MOM_bkgnd_mixing.F90.

312 
313  type(ocean_grid_type), intent(in) :: g !< Grid structure.
314  type(verticalgrid_type), intent(in) :: gv !< Vertical grid structure.
315  real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(in) :: h !< Layer thickness [H ~> m or kg m-2].
316  type(thermo_var_ptrs), intent(in) :: tv !< Thermodynamics structure.
317  real, dimension(SZI_(G),SZK_(GV)), intent(in) :: n2_lay !< squared buoyancy frequency associated
318  !! with layers [T-2 ~> s-2]
319  real, dimension(SZI_(G),SZK_(GV)), intent(out) :: kd_lay !< The background diapycnal diffusivity
320  !! of each layer [Z2 T-1 ~> m2 s-1].
321  real, dimension(SZI_(G),SZK_(GV)+1), intent(out) :: kd_int !< The background diapycnal diffusivity
322  !! of each interface [Z2 T-1 ~> m2 s-1].
323  real, dimension(SZI_(G),SZK_(GV)+1), intent(out) :: kv_bkgnd !< The background vertical viscosity at
324  !! each interface [Z2 T-1 ~> m2 s-1]
325  integer, intent(in) :: j !< Meridional grid index
326  type(unit_scale_type), intent(in) :: us !< A dimensional unit scaling type
327  type(bkgnd_mixing_cs), pointer :: cs !< The control structure returned by
328  !! a previous call to bkgnd_mixing_init.
329 
330  ! local variables
331  real, dimension(SZK_(GV)+1) :: depth_int !< Distance from surface of the interfaces [m]
332  real, dimension(SZK_(GV)+1) :: kd_col !< Diffusivities at the interfaces [m2 s-1]
333  real, dimension(SZK_(GV)+1) :: kv_col !< Viscosities at the interfaces [m2 s-1]
334  real, dimension(SZI_(G)) :: kd_sfc !< Surface value of the diffusivity [Z2 T-1 ~> m2 s-1]
335  real, dimension(SZI_(G)) :: depth !< Distance from surface of an interface [Z ~> m]
336  real :: depth_c !< depth of the center of a layer [Z ~> m]
337  real :: i_hmix !< inverse of fixed mixed layer thickness [Z-1 ~> m-1]
338  real :: i_2omega !< 1/(2 Omega) [T ~> s]
339  real :: n_2omega ! The ratio of the stratification to the Earth's rotation rate [nondim]
340  real :: n02_n2 ! The ratio a reference stratification to the actual stratification [nondim]
341  real :: i_x30 !< 2/acos(2) = 1/(sin(30 deg) * acosh(1/sin(30 deg)))
342  real :: deg_to_rad !< factor converting degrees to radians, pi/180.
343  real :: abs_sinlat !< absolute value of sine of latitude [nondim]
344  real :: min_sinlat ! The minimum value of the sine of latitude [nondim]
345  real :: bckgrnd_vdc_psin !< PSI diffusivity in northern hemisphere [Z2 T-1 ~> m2 s-1]
346  real :: bckgrnd_vdc_psis !< PSI diffusivity in southern hemisphere [Z2 T-1 ~> m2 s-1]
347  integer :: i, k, is, ie, js, je, nz
348 
349  is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
350 
351  ! set some parameters
352  deg_to_rad = atan(1.0)/45.0 ! = PI/180
353  min_sinlat = 1.e-10
354 
355  ! Start with a constant value that may be replaced below.
356  kd_lay(:,:) = cs%Kd
357  kv_bkgnd(:,:) = 0.0
358 
359  ! Set up the background diffusivity.
360  if (cs%Bryan_Lewis_diffusivity) then
361 
362  do i=is,ie
363  depth_int(1) = 0.0
364  do k=2,nz+1
365  depth_int(k) = depth_int(k-1) + gv%H_to_m*h(i,j,k-1)
366  enddo
367 
368  call cvmix_init_bkgnd(max_nlev=nz, &
369  zw = depth_int(:), & !< interface depths relative to the surface in m, must be positive.
370  bl1 = cs%Bryan_Lewis_c1, &
371  bl2 = cs%Bryan_Lewis_c2, &
372  bl3 = cs%Bryan_Lewis_c3, &
373  bl4 = cs%Bryan_Lewis_c4, &
374  prandtl = cs%prandtl_bkgnd)
375 
376  kd_col(:) = 0.0 ; kv_col(:) = 0.0 ! Is this line necessary?
377  call cvmix_coeffs_bkgnd(mdiff_out=kv_col, tdiff_out=kd_col, nlev=nz, max_nlev=nz)
378 
379  ! Update Kd and Kv.
380  do k=1,nz+1
381  kv_bkgnd(i,k) = us%m2_s_to_Z2_T*kv_col(k)
382  kd_int(i,k) = us%m2_s_to_Z2_T*kd_col(k)
383  enddo
384  do k=1,nz
385  kd_lay(i,k) = kd_lay(i,k) + 0.5 * us%m2_s_to_Z2_T * (kd_col(k) + kd_col(k+1))
386  enddo
387  enddo ! i loop
388 
389  elseif (cs%horiz_varying_background) then
390  !### Note that there are lots of hard-coded parameters (mostly latitudes and longitudes) here.
391  do i=is,ie
392  bckgrnd_vdc_psis = cs%bckgrnd_vdc_psim * exp(-(0.4*(g%geoLatT(i,j)+28.9))**2)
393  bckgrnd_vdc_psin = cs%bckgrnd_vdc_psim * exp(-(0.4*(g%geoLatT(i,j)-28.9))**2)
394  kd_int(i,1) = (cs%bckgrnd_vdc_eq + bckgrnd_vdc_psin) + bckgrnd_vdc_psis
395 
396  if (g%geoLatT(i,j) < -10.0) then
397  kd_int(i,1) = kd_int(i,1) + cs%bckgrnd_vdc1
398  elseif (g%geoLatT(i,j) <= 10.0) then
399  kd_int(i,1) = kd_int(i,1) + cs%bckgrnd_vdc1 * (g%geoLatT(i,j)/10.0)**2
400  else
401  kd_int(i,1) = kd_int(i,1) + cs%bckgrnd_vdc1
402  endif
403 
404  ! North Banda Sea
405  if ( (g%geoLatT(i,j) < -1.0) .and. (g%geoLatT(i,j) > -4.0) .and. &
406  ( mod(g%geoLonT(i,j)+360.0,360.0) > 103.0) .and. &
407  ( mod(g%geoLonT(i,j)+360.0,360.0) < 134.0) ) then
408  kd_int(i,1) = cs%bckgrnd_vdc_Banda
409  endif
410 
411  ! Middle Banda Sea
412  if ( (g%geoLatT(i,j) <= -4.0) .and. (g%geoLatT(i,j) > -7.0) .and. &
413  ( mod(g%geoLonT(i,j)+360.0,360.0) > 106.0) .and. &
414  ( mod(g%geoLonT(i,j)+360.0,360.0) < 140.0) ) then
415  kd_int(i,1) = cs%bckgrnd_vdc_Banda
416  endif
417 
418  ! South Banda Sea
419  if ( (g%geoLatT(i,j) <= -7.0) .and. (g%geoLatT(i,j) > -8.3) .and. &
420  ( mod(g%geoLonT(i,j)+360.0,360.0) > 111.0) .and. &
421  ( mod(g%geoLonT(i,j)+360.0,360.0) < 142.0) ) then
422  kd_int(i,1) = cs%bckgrnd_vdc_Banda
423  endif
424 
425  enddo
426  ! Update interior values of Kd and Kv (uniform profile; no interpolation needed)
427  do k=1,nz+1 ; do i=is,ie
428  kd_int(i,k) = kd_int(i,1)
429  kv_bkgnd(i,k) = kd_int(i,1) * cs%prandtl_bkgnd
430  enddo ; enddo
431  do k=1,nz ; do i=is,ie
432  kd_lay(i,k) = kd_int(i,1)
433  enddo ; enddo
434 
435  elseif (cs%Henyey_IGW_background_new) then
436  i_x30 = 2.0 / invcosh(cs%N0_2Omega*2.0) ! This is evaluated at 30 deg.
437  i_2omega = 0.5 / cs%omega
438  do k=1,nz ; do i=is,ie
439  abs_sinlat = max(min_sinlat, abs(sin(g%geoLatT(i,j)*deg_to_rad)))
440  n_2omega = max(abs_sinlat, sqrt(n2_lay(i,k))*i_2omega)
441  n02_n2 = (cs%N0_2Omega/n_2omega)**2
442  kd_lay(i,k) = max(cs%Kd_min, cs%Kd * &
443  ((abs_sinlat * invcosh(n_2omega/abs_sinlat)) * i_x30)*n02_n2)
444  enddo ; enddo
445  ! Update Kd_int and Kv_bkgnd, based on Kd_lay. These might be just used for diagnostic purposes.
446  do i=is,ie
447  kd_int(i,1) = 0.0; kv_bkgnd(i,1) = 0.0
448  kd_int(i,nz+1) = 0.0; kv_bkgnd(i,nz+1) = 0.0
449  enddo
450  do k=2,nz ; do i=is,ie
451  kd_int(i,k) = 0.5*(kd_lay(i,k-1) + kd_lay(i,k))
452  kv_bkgnd(i,k) = kd_int(i,k) * cs%prandtl_bkgnd
453  enddo ; enddo
454  else
455  ! Set a potentially spatially varying surface value of diffusivity.
456  if (cs%Henyey_IGW_background) then
457  i_x30 = 2.0 / invcosh(cs%N0_2Omega*2.0) ! This is evaluated at 30 deg.
458  do i=is,ie
459  abs_sinlat = abs(sin(g%geoLatT(i,j)*deg_to_rad))
460  kd_sfc(i) = max(cs%Kd_min, cs%Kd * &
461  ((abs_sinlat * invcosh(cs%N0_2Omega / max(min_sinlat, abs_sinlat))) * i_x30) )
462  enddo
463  elseif (cs%Kd_tanh_lat_fn) then
464  do i=is,ie
465  ! The transition latitude and latitude range are hard-scaled here, since
466  ! this is not really intended for wide-spread use, but rather for
467  ! comparison with CM2M / CM2.1 settings.
468  kd_sfc(i) = max(cs%Kd_min, cs%Kd * (1.0 + &
469  cs%Kd_tanh_lat_scale * 0.5*tanh((abs(g%geoLatT(i,j)) - 35.0)/5.0) ))
470  enddo
471  else ! Use a spatially constant surface value.
472  do i=is,ie
473  kd_sfc(i) = cs%Kd
474  enddo
475  endif
476 
477  ! Now set background diffusivies based on these surface values, possibly with vertical structure.
478  if ((.not.cs%bulkmixedlayer) .and. (cs%Kd /= cs%Kdml)) then
479  ! This is a crude way to put in a diffusive boundary layer without an explicit boundary
480  ! layer turbulence scheme. It should not be used for any realistic ocean models.
481  i_hmix = 1.0 / (cs%Hmix + gv%H_subroundoff*gv%H_to_Z)
482  do i=is,ie ; depth(i) = 0.0 ; enddo
483  do k=1,nz ; do i=is,ie
484  depth_c = depth(i) + 0.5*gv%H_to_Z*h(i,j,k)
485  if (cs%Kd_via_Kdml_bug) then
486  ! These two lines should update Kd_lay, not Kd_int. They were correctly working on the
487  ! same variables until MOM6 commit 7a818716 (PR#750), which was added on March 26, 2018.
488  if (depth_c <= cs%Hmix) then ; kd_int(i,k) = cs%Kdml
489  elseif (depth_c >= 2.0*cs%Hmix) then ; kd_int(i,k) = kd_sfc(i)
490  else
491  kd_lay(i,k) = ((kd_sfc(i) - cs%Kdml) * i_hmix) * depth_c + (2.0*cs%Kdml - kd_sfc(i))
492  endif
493  else
494  if (depth_c <= cs%Hmix) then ; kd_lay(i,k) = cs%Kdml
495  elseif (depth_c >= 2.0*cs%Hmix) then ; kd_lay(i,k) = kd_sfc(i)
496  else
497  kd_lay(i,k) = ((kd_sfc(i) - cs%Kdml) * i_hmix) * depth_c + (2.0*cs%Kdml - kd_sfc(i))
498  endif
499  endif
500 
501  depth(i) = depth(i) + gv%H_to_Z*h(i,j,k)
502  enddo ; enddo
503 
504  else ! There is no vertical structure to the background diffusivity.
505  do k=1,nz ; do i=is,ie
506  kd_lay(i,k) = kd_sfc(i)
507  enddo ; enddo
508  endif
509 
510  ! Update Kd_int and Kv_bkgnd, based on Kd_lay. These might be just used for diagnostic purposes.
511  do i=is,ie
512  kd_int(i,1) = 0.0; kv_bkgnd(i,1) = 0.0
513  kd_int(i,nz+1) = 0.0; kv_bkgnd(i,nz+1) = 0.0
514  enddo
515  do k=2,nz ; do i=is,ie
516  kd_int(i,k) = 0.5*(kd_lay(i,k-1) + kd_lay(i,k))
517  kv_bkgnd(i,k) = kd_int(i,k) * cs%prandtl_bkgnd
518  enddo ; enddo
519  endif
520 

◆ check_bkgnd_scheme()

subroutine mom_bkgnd_mixing::check_bkgnd_scheme ( type(bkgnd_mixing_cs), pointer  CS,
character(len=*), intent(in)  str 
)
private

Sets CSbkgnd_scheme_str to check whether multiple background diffusivity schemes are activated. The string is also for error/log messages.

Parameters
csControl structure
[in]strBackground scheme identifier deducted from MOM_input parameters

Definition at line 536 of file MOM_bkgnd_mixing.F90.

536  type(bkgnd_mixing_cs), pointer :: cs !< Control structure
537  character(len=*), intent(in) :: str !< Background scheme identifier deducted from MOM_input
538  !! parameters
539 
540  if (trim(cs%bkgnd_scheme_str)=="none") then
541  cs%bkgnd_scheme_str = str
542  else
543  call mom_error(fatal, "set_diffusivity_init: Cannot activate both "//trim(str)//" and "//&
544  trim(cs%bkgnd_scheme_str)//".")
545  endif
546 

◆ cvmix_bkgnd_is_used()

logical function mom_bkgnd_mixing::cvmix_bkgnd_is_used ( type(param_file_type), intent(in)  param_file)
private

Reads the parameter "USE_CVMix_BACKGROUND" 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 527 of file MOM_bkgnd_mixing.F90.

527  type(param_file_type), intent(in) :: param_file !< A structure to parse for run-time parameters
528  call get_param(param_file, mdl, "USE_CVMix_BACKGROUND", cvmix_bkgnd_is_used, &
529  default=.false., do_not_log = .true.)
530