19 use mpp_mod,
only : mpp_pe
21 use cvmix_kpp,
only : cvmix_init_kpp, cvmix_put_kpp, cvmix_get_kpp_real
22 use cvmix_kpp,
only : cvmix_coeffs_kpp
23 use cvmix_kpp,
only : cvmix_kpp_compute_obl_depth
24 use cvmix_kpp,
only : cvmix_kpp_compute_turbulent_scales
25 use cvmix_kpp,
only : cvmix_kpp_compute_bulk_richardson
26 use cvmix_kpp,
only : cvmix_kpp_compute_unresolved_shear
27 use cvmix_kpp,
only : cvmix_kpp_params_type
28 use cvmix_kpp,
only : cvmix_kpp_compute_kobl_depth
30 implicit none ;
private
32 #include "MOM_memory.h"
53 integer,
private,
parameter ::
lt_k_constant = 1, & !< Constant enhance K through column
79 logical :: enhance_diffusion
80 character(len=10) :: interptype
81 character(len=10) :: interptype2
82 logical :: computeekman
83 logical :: computemoninobukhov
84 logical :: passivemode
88 real :: surf_layer_ext
90 logical :: fixedobldepth
91 real :: fixedobldepth_value
93 character(len=30) :: matchtechnique
95 logical :: applynonlocaltrans
97 logical :: deepen_only
98 logical :: kppzerodiffusivity
100 logical :: kppisadditive
103 real :: min_thickness
106 logical :: correctsurflayeravg
107 real :: surflayerdepth
110 logical :: lt_k_enhancement
111 integer :: lt_k_shape
112 integer :: lt_k_method
113 real :: kpp_k_enh_fac
114 logical :: lt_vt2_enhancement
115 integer :: lt_vt2_method
116 real :: kpp_vt2_enh_fac
117 logical :: stokes_mixing
121 type(cvmix_kpp_params_type),
pointer :: kpp_params => null()
125 integer :: id_obldepth = -1, id_bulkri = -1
126 integer :: id_n = -1, id_n2 = -1
127 integer :: id_ws = -1, id_vt2 = -1
128 integer :: id_bulkuz2 = -1, id_bulkdrho = -1
129 integer :: id_ustar = -1, id_buoyflux = -1
130 integer :: id_qminussw = -1, id_nets = -1
131 integer :: id_sigma = -1, id_kv_kpp = -1
132 integer :: id_kt_kpp = -1, id_ks_kpp = -1
133 integer :: id_tsurf = -1, id_ssurf = -1
134 integer :: id_usurf = -1, id_vsurf = -1
135 integer :: id_kd_in = -1
136 integer :: id_nltt = -1
137 integer :: id_nlts = -1
138 integer :: id_nlt_dsdt = -1
139 integer :: id_nlt_dtdt = -1
140 integer :: id_nlt_temp_budget = -1
141 integer :: id_nlt_saln_budget = -1
142 integer :: id_enhk = -1, id_enhvt2 = -1
143 integer :: id_enhw = -1
144 integer :: id_la_sl = -1
145 integer :: id_obldepth_original = -1
149 real,
allocatable,
dimension(:,:) :: obldepth
150 real,
allocatable,
dimension(:,:) :: obldepth_original
151 real,
allocatable,
dimension(:,:) :: kobl
152 real,
allocatable,
dimension(:,:) :: obldepthprev
153 real,
allocatable,
dimension(:,:) :: la_sl
154 real,
allocatable,
dimension(:,:,:) :: drho
155 real,
allocatable,
dimension(:,:,:) :: uz2
156 real,
allocatable,
dimension(:,:,:) :: bulkri
157 real,
allocatable,
dimension(:,:,:) :: sigma
158 real,
allocatable,
dimension(:,:,:) :: ws
159 real,
allocatable,
dimension(:,:,:) :: n
160 real,
allocatable,
dimension(:,:,:) :: n2
161 real,
allocatable,
dimension(:,:,:) :: vt2
162 real,
allocatable,
dimension(:,:,:) :: kt_kpp
163 real,
allocatable,
dimension(:,:,:) :: ks_kpp
164 real,
allocatable,
dimension(:,:,:) :: kv_kpp
165 real,
allocatable,
dimension(:,:) :: tsurf
166 real,
allocatable,
dimension(:,:) :: ssurf
167 real,
allocatable,
dimension(:,:) :: usurf
168 real,
allocatable,
dimension(:,:) :: vsurf
169 real,
allocatable,
dimension(:,:,:) :: enhk
170 real,
allocatable,
dimension(:,:,:) :: enhvt2
174 #define __DO_SAFETY_CHECKS__
180 logical function kpp_init(paramFile, G, GV, US, diag, Time, CS, passive, Waves)
187 type(
diag_ctrl),
target,
intent(in) :: diag
188 type(time_type),
intent(in) :: time
189 type(
kpp_cs),
pointer :: cs
190 logical,
optional,
intent(out) :: passive
194 #include "version_variable.h"
195 character(len=40) :: mdl =
'MOM_CVMix_KPP'
196 character(len=20) :: string
197 logical :: cs_is_one=.false.
198 logical :: lnodgat1=.false.
200 if (
associated(cs))
call mom_error(fatal,
'MOM_CVMix_KPP, KPP_init: '// &
201 'Control structure has already been initialized')
204 call log_version(paramfile, mdl, version,
'This is the MOM wrapper to CVMix:KPP\n' // &
205 'See http://cvmix.github.io/')
207 "If true, turns on the [CVMix] KPP scheme of Large et al., 1994, "// &
208 "to calculate diffusivities and non-local transport in the OBL.", &
215 call get_param(paramfile, mdl,
'PASSIVE', cs%passiveMode, &
216 'If True, puts KPP into a passive-diagnostic mode.', &
220 if (
present(passive)) passive=cs%passiveMode
222 call get_param(paramfile, mdl,
'APPLY_NONLOCAL_TRANSPORT', cs%applyNonLocalTrans, &
223 'If True, applies the non-local transport to heat and scalars. '// &
224 'If False, calculates the non-local transport and tendencies but '//&
225 'purely for diagnostic purposes.', &
226 default=.not. cs%passiveMode)
227 call get_param(paramfile, mdl,
'N_SMOOTH', cs%n_smooth, &
228 'The number of times the 1-1-4-1-1 Laplacian filter is applied on '// &
231 if (cs%n_smooth > 0)
then
232 call get_param(paramfile, mdl,
'DEEPEN_ONLY_VIA_SMOOTHING', cs%deepen_only, &
233 'If true, apply OBLdepth smoothing at a cell only if the OBLdepth '// &
234 'gets deeper via smoothing.', &
237 call get_param(paramfile, mdl,
'RI_CRIT', cs%Ri_crit, &
238 'Critical bulk Richardson number used to define depth of the '// &
239 'surface Ocean Boundary Layer (OBL).', &
240 units=
'nondim', default=0.3)
241 call get_param(paramfile, mdl,
'VON_KARMAN', cs%vonKarman, &
242 'von Karman constant.', &
243 units=
'nondim', default=0.40)
244 call get_param(paramfile, mdl,
'ENHANCE_DIFFUSION', cs%enhance_diffusion, &
245 'If True, adds enhanced diffusion at the based of the boundary layer.', &
247 call get_param(paramfile, mdl,
'INTERP_TYPE', cs%interpType, &
248 'Type of interpolation to determine the OBL depth.\n'// &
249 'Allowed types are: linear, quadratic, cubic.', &
251 call get_param(paramfile, mdl,
'INTERP_TYPE2', cs%interpType2, &
252 'Type of interpolation to compute diff and visc at OBL_depth.\n'// &
253 'Allowed types are: linear, quadratic, cubic or LMD94.', &
255 call get_param(paramfile, mdl,
'COMPUTE_EKMAN', cs%computeEkman, &
256 'If True, limit OBL depth to be no deeper than Ekman depth.', &
258 call get_param(paramfile, mdl,
'COMPUTE_MONIN_OBUKHOV', cs%computeMoninObukhov, &
259 'If True, limit the OBL depth to be no deeper than '// &
260 'Monin-Obukhov depth.', &
262 call get_param(paramfile, mdl,
'CS', cs%cs, &
263 'Parameter for computing velocity scale function.', &
264 units=
'nondim', default=98.96)
265 call get_param(paramfile, mdl,
'CS2', cs%cs2, &
266 'Parameter for computing non-local term.', &
267 units=
'nondim', default=6.32739901508)
268 call get_param(paramfile, mdl,
'DEEP_OBL_OFFSET', cs%deepOBLoffset, &
269 'If non-zero, the distance above the bottom to which the OBL is clipped '// &
270 'if it would otherwise reach the bottom. The smaller of this and 0.1D is used.', &
271 units=
'm',default=0.)
272 call get_param(paramfile, mdl,
'FIXED_OBLDEPTH', cs%fixedOBLdepth, &
273 'If True, fix the OBL depth to FIXED_OBLDEPTH_VALUE '// &
274 'rather than using the OBL depth from CVMix. '// &
275 'This option is just for testing purposes.', &
277 call get_param(paramfile, mdl,
'FIXED_OBLDEPTH_VALUE', cs%fixedOBLdepth_value, &
278 'Value for the fixed OBL depth when fixedOBLdepth==True. '// &
279 'This parameter is for just for testing purposes. '// &
280 'It will over-ride the OBLdepth computed from CVMix.', &
281 units=
'm',default=30.0)
282 call get_param(paramfile, mdl,
'SURF_LAYER_EXTENT', cs%surf_layer_ext, &
283 'Fraction of OBL depth considered in the surface layer.', &
284 units=
'nondim',default=0.10)
285 call get_param(paramfile, mdl,
'MINIMUM_OBL_DEPTH', cs%minOBLdepth, &
286 'If non-zero, a minimum depth to use for KPP OBL depth. Independent of '// &
287 'this parameter, the OBL depth is always at least as deep as the first layer.', &
288 units=
'm',default=0.)
289 call get_param(paramfile, mdl,
'MINIMUM_VT2', cs%minVtsqr, &
290 'Min of the unresolved velocity Vt2 used in Rib CVMix calculation.\n'// &
291 'Scaling: MINIMUM_VT2 = const1*d*N*ws, with d=1m, N=1e-5/s, ws=1e-6 m/s.', &
292 units=
'm2/s2',default=1e-10)
295 call get_param(paramfile, mdl,
'CORRECT_SURFACE_LAYER_AVERAGE', cs%correctSurfLayerAvg, &
296 'If true, applies a correction step to the averaging of surface layer '// &
297 'properties. This option is obsolete.', default=.false.)
298 if (cs%correctSurfLayerAvg) &
299 call mom_error(fatal,
'Correct surface layer average disabled in code. To recover \n'// &
300 ' feature will require code intervention.')
301 call get_param(paramfile, mdl,
'FIRST_GUESS_SURFACE_LAYER_DEPTH', cs%surfLayerDepth, &
302 'The first guess at the depth of the surface layer used for averaging '// &
303 'the surface layer properties. If =0, the top model level properties '// &
304 'will be used for the surface layer. If CORRECT_SURFACE_LAYER_AVERAGE=True, a '// &
305 'subsequent correction is applied. This parameter is obsolete', units=
'm', default=0.)
308 call get_param(paramfile, mdl,
'NLT_SHAPE', string, &
309 'MOM6 method to set nonlocal transport profile. '// &
310 'Over-rides the result from CVMix. Allowed values are: \n'// &
311 '\t CVMix - Uses the profiles from CVMix specified by MATCH_TECHNIQUE\n'//&
312 '\t LINEAR - A linear profile, 1-sigma\n'// &
313 '\t PARABOLIC - A parablic profile, (1-sigma)^2\n'// &
314 '\t CUBIC - A cubic profile, (1-sigma)^2(1+2*sigma)\n'// &
315 '\t CUBIC_LMD - The original KPP profile', &
317 select case ( trim(string) )
323 case default ;
call mom_error(fatal,
"KPP_init: "// &
324 "Unrecognized NLT_SHAPE option"//trim(string))
326 call get_param(paramfile, mdl,
'MATCH_TECHNIQUE', cs%MatchTechnique, &
327 'CVMix method to set profile function for diffusivity and NLT, '// &
328 'as well as matching across OBL base. Allowed values are: \n'// &
329 '\t SimpleShapes = sigma*(1-sigma)^2 for both diffusivity and NLT\n'// &
330 '\t MatchGradient = sigma*(1-sigma)^2 for NLT; diffusivity profile from matching\n'//&
331 '\t MatchBoth = match gradient for both diffusivity and NLT\n'// &
332 '\t ParabolicNonLocal = sigma*(1-sigma)^2 for diffusivity; (1-sigma)^2 for NLT', &
333 default=
'SimpleShapes')
334 if (cs%MatchTechnique ==
'ParabolicNonLocal')
then
339 if (cs%MatchTechnique ==
'ParabolicNonLocal' .or. cs%MatchTechnique ==
'SimpleShapes')
then
345 if (cs%MatchTechnique ==
'MatchBoth' .and. (cs%interpType2 ==
'cubic' .or. &
346 cs%interpType2 ==
'quadratic'))
then
347 call mom_error(fatal,
"If MATCH_TECHNIQUE=MatchBoth, INTERP_TYPE2 must be set to \n"//&
348 "linear or LMD94 (recommended) to avoid negative viscosity and diffusivity.\n"//&
349 "Please select one of these valid options." )
352 call get_param(paramfile, mdl,
'KPP_ZERO_DIFFUSIVITY', cs%KPPzeroDiffusivity, &
353 'If True, zeroes the KPP diffusivity and viscosity; for testing purpose.',&
355 call get_param(paramfile, mdl,
'KPP_IS_ADDITIVE', cs%KPPisAdditive, &
356 'If true, adds KPP diffusivity to diffusivity from other schemes.\n'//&
357 'If false, KPP is the only diffusivity wherever KPP is non-zero.', &
359 call get_param(paramfile, mdl,
'KPP_SHORTWAVE_METHOD',string, &
360 'Determines contribution of shortwave radiation to KPP surface '// &
361 'buoyancy flux. Options include:\n'// &
362 ' ALL_SW: use total shortwave radiation\n'// &
363 ' MXL_SW: use shortwave radiation absorbed by mixing layer\n'// &
364 ' LV1_SW: use shortwave radiation absorbed by top model layer', &
366 select case ( trim(string) )
370 case default ;
call mom_error(fatal,
"KPP_init: "// &
371 "Unrecognized KPP_SHORTWAVE_METHOD option"//trim(string))
373 call get_param(paramfile, mdl,
'CVMix_ZERO_H_WORK_AROUND', cs%min_thickness, &
374 'A minimum thickness used to avoid division by small numbers in the vicinity '// &
375 'of vanished layers. This is independent of MIN_THICKNESS used in other parts of MOM.', &
376 units=
'm', default=0.)
380 call get_param(paramfile, mdl,
"USE_KPP_LT_K", cs%LT_K_Enhancement, &
381 'Flag for Langmuir turbulence enhancement of turbulent'//&
382 'mixing coefficient.', units=
"", default=.false.)
383 call get_param(paramfile, mdl,
"STOKES_MIXING", cs%STOKES_MIXING, &
384 'Flag for Langmuir turbulence enhancement of turbulent'//&
385 'mixing coefficient.', units=
"", default=.false.)
386 if (cs%LT_K_Enhancement)
then
387 call get_param(paramfile, mdl,
'KPP_LT_K_SHAPE', string, &
388 'Vertical dependence of LT enhancement of mixing. '// &
389 'Valid options are: \n'// &
390 '\t CONSTANT = Constant value for full OBL\n'// &
391 '\t SCALED = Varies based on normalized shape function.', &
393 select case ( trim(string))
396 case default ;
call mom_error(fatal,
"KPP_init: "//&
397 "Unrecognized KPP_LT_K_SHAPE option: "//trim(string))
399 call get_param(paramfile, mdl,
"KPP_LT_K_METHOD", string , &
400 'Method to enhance mixing coefficient in KPP. '// &
401 'Valid options are: \n'// &
402 '\t CONSTANT = Constant value (KPP_K_ENH_FAC) \n'// &
403 '\t VR12 = Function of Langmuir number based on VR12\n'// &
404 '\t RW16 = Function of Langmuir number based on RW16', &
406 select case ( trim(string))
410 case default ;
call mom_error(fatal,
"KPP_init: "//&
411 "Unrecognized KPP_LT_K_METHOD option: "//trim(string))
414 call get_param(paramfile, mdl,
"KPP_K_ENH_FAC",cs%KPP_K_ENH_FAC , &
415 'Constant value to enhance mixing coefficient in KPP.', &
420 call get_param(paramfile, mdl,
"USE_KPP_LT_VT2", cs%LT_Vt2_Enhancement, &
421 'Flag for Langmuir turbulence enhancement of Vt2'//&
422 'in Bulk Richardson Number.', units=
"", default=.false.)
423 if (cs%LT_Vt2_Enhancement)
then
424 call get_param(paramfile, mdl,
"KPP_LT_VT2_METHOD",string , &
425 'Method to enhance Vt2 in KPP. '// &
426 'Valid options are: \n'// &
427 '\t CONSTANT = Constant value (KPP_VT2_ENH_FAC) \n'// &
428 '\t VR12 = Function of Langmuir number based on VR12\n'// &
429 '\t RW16 = Function of Langmuir number based on RW16\n'// &
430 '\t LF17 = Function of Langmuir number based on LF17', &
432 select case ( trim(string))
437 case default ;
call mom_error(fatal,
"KPP_init: "//&
438 "Unrecognized KPP_LT_VT2_METHOD option: "//trim(string))
441 call get_param(paramfile, mdl,
"KPP_VT2_ENH_FAC",cs%KPP_VT2_ENH_FAC , &
442 'Constant value to enhance VT2 in KPP.', &
448 call get_param(paramfile, mdl,
'DEBUG', cs%debug, default=.false., do_not_log=.true.)
450 call cvmix_init_kpp( ri_crit=cs%Ri_crit, &
451 minobldepth=cs%minOBLdepth, &
452 minvtsqr=cs%minVtsqr, &
453 vonkarman=cs%vonKarman, &
454 surf_layer_ext=cs%surf_layer_ext, &
455 interp_type=cs%interpType, &
456 interp_type2=cs%interpType2, &
457 lekman=cs%computeEkman, &
458 lmonob=cs%computeMoninObukhov, &
459 matchtechnique=cs%MatchTechnique, &
460 lenhanced_diff=cs%enhance_diffusion,&
461 lnonzero_surf_nonlocal=cs_is_one ,&
463 cvmix_kpp_params_user=cs%KPP_params )
468 'Thickness of the surface Ocean Boundary Layer calculated by [CVMix] KPP',
'meter', &
469 cmor_field_name=
'oml', cmor_long_name=
'ocean_mixed_layer_thickness_defined_by_mixing_scheme', &
470 cmor_units=
'm', cmor_standard_name=
'Ocean Mixed Layer Thickness Defined by Mixing Scheme')
474 if (cs%n_smooth > 0)
then
475 cs%id_OBLdepth_original =
register_diag_field(
'ocean_model',
'KPP_OBLdepth_original', diag%axesT1, time, &
476 'Thickness of the surface Ocean Boundary Layer without smoothing calculated by [CVMix] KPP',
'meter', &
477 cmor_field_name=
'oml', cmor_long_name=
'ocean_mixed_layer_thickness_defined_by_mixing_scheme', &
478 cmor_units=
'm', cmor_standard_name=
'Ocean Mixed Layer Thickness Defined by Mixing Scheme')
481 'Bulk difference in density used in Bulk Richardson number, as used by [CVMix] KPP',
'kg/m3')
483 'Square of bulk difference in resolved velocity used in Bulk Richardson number via [CVMix] KPP',
'm2/s2')
485 'Bulk Richardson number used to find the OBL depth used by [CVMix] KPP',
'nondim')
487 'Sigma coordinate used by [CVMix] KPP',
'nondim')
489 'Turbulent vertical velocity scale for scalars used by [CVMix] KPP',
'm/s')
491 '(Adjusted) Brunt-Vaisala frequency used by [CVMix] KPP',
'1/s')
493 'Square of Brunt-Vaisala frequency used by [CVMix] KPP',
'1/s2')
495 'Unresolved shear turbulence used by [CVMix] KPP',
'm2/s2')
497 'Friction velocity, u*, as used by [CVMix] KPP',
'm/s', conversion=us%Z_to_m*us%s_to_T)
499 'Surface (and penetrating) buoyancy flux, as used by [CVMix] KPP',
'm2/s3', conversion=us%L_to_m**2*us%s_to_T**3)
501 'Net temperature flux ignoring short-wave, as used by [CVMix] KPP',
'K m/s')
503 'Effective net surface salt flux, as used by [CVMix] KPP',
'ppt m/s')
505 'Heat diffusivity due to KPP, as calculated by [CVMix] KPP',
'm2/s')
507 'Diffusivity passed to KPP',
'm2/s', conversion=us%Z2_T_to_m2_s)
509 'Salt diffusivity due to KPP, as calculated by [CVMix] KPP',
'm2/s')
511 'Vertical viscosity due to KPP, as calculated by [CVMix] KPP',
'm2/s')
512 cs%id_NLTt =
register_diag_field(
'ocean_model',
'KPP_NLtransport_heat', diag%axesTi, time, &
513 'Non-local transport (Cs*G(sigma)) for heat, as calculated by [CVMix] KPP',
'nondim')
514 cs%id_NLTs =
register_diag_field(
'ocean_model',
'KPP_NLtransport_salt', diag%axesTi, time, &
515 'Non-local tranpsort (Cs*G(sigma)) for scalars, as calculated by [CVMix] KPP',
'nondim')
517 'Temperature tendency due to non-local transport of heat, as calculated by [CVMix] KPP',
'K/s')
519 'Salinity tendency due to non-local transport of salt, as calculated by [CVMix] KPP',
'ppt/s')
520 cs%id_NLT_temp_budget =
register_diag_field(
'ocean_model',
'KPP_NLT_temp_budget', diag%axesTL, time, &
521 'Heat content change due to non-local transport, as calculated by [CVMix] KPP',
'W/m^2')
522 cs%id_NLT_saln_budget =
register_diag_field(
'ocean_model',
'KPP_NLT_saln_budget', diag%axesTL, time, &
523 'Salt content change due to non-local transport, as calculated by [CVMix] KPP',
'kg/(sec*m^2)')
525 'Temperature of surface layer (10% of OBL depth) as passed to [CVMix] KPP',
'C')
527 'Salinity of surface layer (10% of OBL depth) as passed to [CVMix] KPP',
'ppt')
529 'i-component flow of surface layer (10% of OBL depth) as passed to [CVMix] KPP',
'm/s')
531 'j-component flow of surface layer (10% of OBL depth) as passed to [CVMix] KPP',
'm/s')
533 'Langmuir number enhancement to K as used by [CVMix] KPP',
'nondim')
535 'Langmuir number enhancement to Vt2 as used by [CVMix] KPP',
'nondim')
537 'Surface-layer Langmuir number computed in [CVMix] KPP',
'nondim')
539 allocate( cs%N( szi_(g), szj_(g), szk_(g)+1 ) )
541 allocate( cs%OBLdepth( szi_(g), szj_(g) ) )
542 cs%OBLdepth(:,:) = 0.
543 allocate( cs%kOBL( szi_(g), szj_(g) ) )
545 allocate( cs%La_SL( szi_(g), szj_(g) ) )
547 allocate( cs%Vt2( szi_(g), szj_(g), szk_(g) ) )
549 if (cs%id_OBLdepth_original > 0)
allocate( cs%OBLdepth_original( szi_(g), szj_(g) ) )
551 allocate( cs%OBLdepthprev( szi_(g), szj_(g) ) ) ; cs%OBLdepthprev(:,:) = 0.0
552 if (cs%id_BulkDrho > 0)
allocate( cs%dRho( szi_(g), szj_(g), szk_(g) ) )
553 if (cs%id_BulkDrho > 0) cs%dRho(:,:,:) = 0.
554 if (cs%id_BulkUz2 > 0)
allocate( cs%Uz2( szi_(g), szj_(g), szk_(g) ) )
555 if (cs%id_BulkUz2 > 0) cs%Uz2(:,:,:) = 0.
556 if (cs%id_BulkRi > 0)
allocate( cs%BulkRi( szi_(g), szj_(g), szk_(g) ) )
557 if (cs%id_BulkRi > 0) cs%BulkRi(:,:,:) = 0.
558 if (cs%id_Sigma > 0)
allocate( cs%sigma( szi_(g), szj_(g), szk_(g)+1 ) )
559 if (cs%id_Sigma > 0) cs%sigma(:,:,:) = 0.
560 if (cs%id_Ws > 0)
allocate( cs%Ws( szi_(g), szj_(g), szk_(g) ) )
561 if (cs%id_Ws > 0) cs%Ws(:,:,:) = 0.
562 if (cs%id_N2 > 0)
allocate( cs%N2( szi_(g), szj_(g), szk_(g)+1 ) )
563 if (cs%id_N2 > 0) cs%N2(:,:,:) = 0.
564 if (cs%id_Kt_KPP > 0)
allocate( cs%Kt_KPP( szi_(g), szj_(g), szk_(g)+1 ) )
565 if (cs%id_Kt_KPP > 0) cs%Kt_KPP(:,:,:) = 0.
566 if (cs%id_Ks_KPP > 0)
allocate( cs%Ks_KPP( szi_(g), szj_(g), szk_(g)+1 ) )
567 if (cs%id_Ks_KPP > 0) cs%Ks_KPP(:,:,:) = 0.
568 if (cs%id_Kv_KPP > 0)
allocate( cs%Kv_KPP( szi_(g), szj_(g), szk_(g)+1 ) )
569 if (cs%id_Kv_KPP > 0) cs%Kv_KPP(:,:,:) = 0.
570 if (cs%id_Tsurf > 0)
allocate( cs%Tsurf( szi_(g), szj_(g)) )
571 if (cs%id_Tsurf > 0) cs%Tsurf(:,:) = 0.
572 if (cs%id_Ssurf > 0)
allocate( cs%Ssurf( szi_(g), szj_(g)) )
573 if (cs%id_Ssurf > 0) cs%Ssurf(:,:) = 0.
574 if (cs%id_Usurf > 0)
allocate( cs%Usurf( szib_(g), szj_(g)) )
575 if (cs%id_Usurf > 0) cs%Usurf(:,:) = 0.
576 if (cs%id_Vsurf > 0)
allocate( cs%Vsurf( szi_(g), szjb_(g)) )
577 if (cs%id_Vsurf > 0) cs%Vsurf(:,:) = 0.
578 if (cs%id_EnhVt2 > 0)
allocate( cs%EnhVt2( szi_(g), szj_(g), szk_(g)) )
579 if (cs%id_EnhVt2 > 0) cs%EnhVt2(:,:,:) = 0.
580 if (cs%id_EnhK > 0)
allocate( cs%EnhK( szi_(g), szj_(g), szk_(g)+1 ) )
581 if (cs%id_EnhK > 0) cs%EnhK(:,:,:) = 0.
588 buoyFlux, Kt, Ks, Kv, nonLocalTransHeat,&
589 nonLocalTransScalar, waves)
592 type(
kpp_cs),
pointer :: cs
597 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)),
intent(in) :: h
598 real,
dimension(SZI_(G),SZJ_(G)),
intent(in) :: ustar
599 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)+1),
intent(in) :: buoyflux
600 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)+1),
intent(inout) :: kt
603 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)+1),
intent(inout) :: ks
606 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)+1),
intent(inout) :: kv
609 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)+1),
intent(inout) :: nonlocaltransheat
610 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)+1),
intent(inout) :: nonlocaltransscalar
614 real,
dimension( G%ke ) :: cellheight
615 real,
dimension( G%ke+1 ) :: ifaceheight
616 real,
dimension( G%ke+1, 2) :: kdiffusivity
617 real,
dimension( G%ke+1 ) :: kviscosity
618 real,
dimension( G%ke+1, 2) :: nonlocaltrans
620 real :: surffricvel, surfbuoyflux
621 real :: sigma, sigmaratio
630 #ifdef __DO_SAFETY_CHECKS__
632 call hchksum(h,
"KPP in: h",g%HI,haloshift=0, scale=gv%H_to_m)
633 call hchksum(ustar,
"KPP in: uStar",g%HI,haloshift=0, scale=us%Z_to_m*us%s_to_T)
634 call hchksum(buoyflux,
"KPP in: buoyFlux",g%HI,haloshift=0)
635 call hchksum(kt,
"KPP in: Kt",g%HI,haloshift=0, scale=us%Z2_T_to_m2_s)
636 call hchksum(ks,
"KPP in: Ks",g%HI,haloshift=0, scale=us%Z2_T_to_m2_s)
640 nonlocaltrans(:,:) = 0.0
642 if (cs%id_Kd_in > 0)
call post_data(cs%id_Kd_in, kt, cs%diag)
644 buoy_scale = us%L_to_m**2*us%s_to_T**3
657 if (g%mask2dT(i,j)==0.) cycle
660 surffricvel = us%Z_to_m*us%s_to_T * ustar(i,j)
667 dh = h(i,j,k) * gv%H_to_m
669 hcorr = min( dh - cs%min_thickness, 0. )
670 dh = max( dh, cs%min_thickness )
671 cellheight(k) = ifaceheight(k) - 0.5 * dh
672 ifaceheight(k+1) = ifaceheight(k) - dh
676 surfbuoyflux = buoy_scale*buoyflux(i,j,1)
686 surfbuoyflux = buoy_scale * buoyflux(i,j,1)
689 surfbuoyflux = buoy_scale * (buoyflux(i,j,1) - buoyflux(i,j,int(cs%kOBL(i,j))+1))
691 surfbuoyflux = buoy_scale * (buoyflux(i,j,1) - buoyflux(i,j,2))
695 if (.not. (cs%MatchTechnique ==
'MatchBoth'))
then
696 kdiffusivity(:,:) = 0.
699 kdiffusivity(:,1) = us%Z2_T_to_m2_s * kt(i,j,:)
700 kdiffusivity(:,2) = us%Z2_T_to_m2_s * ks(i,j,:)
701 kviscosity(:) = us%Z2_T_to_m2_s * kv(i,j,:)
704 call cvmix_coeffs_kpp(kviscosity(:), &
720 cvmix_kpp_params_user=cs%KPP_params )
724 if (kviscosity(k) < 0. .or. kdiffusivity(k,1) < 0.)
then
725 call mom_error(fatal,
"KPP_calculate, after CVMix_coeffs_kpp: "// &
726 "Negative vertical viscosity or diffusivity has been detected. " // &
727 "This is likely related to the choice of MATCH_TECHNIQUE and INTERP_TYPE2." //&
728 "You might consider using the default options for these parameters." )
732 IF (cs%LT_K_ENHANCEMENT)
then
734 langenhk = cs%KPP_K_ENH_FAC
737 langenhk = sqrt(1.+(1.5*cs%La_SL(i,j))**(-2) + &
738 (5.4*cs%La_SL(i,j))**(-4))
741 langenhk = min(2.25, 1. + 1./cs%La_SL(i,j))
749 if (cs%id_EnhK > 0) cs%EnhK(i,j,:) = langenhk
750 kdiffusivity(k,1) = kdiffusivity(k,1) * langenhk
751 kdiffusivity(k,2) = kdiffusivity(k,2) * langenhk
752 kviscosity(k) = kviscosity(k) * langenhk
754 sigma = min(1.0,-ifaceheight(k)/cs%OBLdepth(i,j))
755 sigmaratio = sigma * (1. - sigma)**2 / 0.148148037
756 if (cs%id_EnhK > 0) cs%EnhK(i,j,k) = (1.0 + (langenhk - 1.)*sigmaratio)
757 kdiffusivity(k,1) = kdiffusivity(k,1) * ( 1. + &
758 ( langenhk - 1.)*sigmaratio)
759 kdiffusivity(k,2) = kdiffusivity(k,2) * ( 1. + &
760 ( langenhk - 1.)*sigmaratio)
761 kviscosity(k) = kviscosity(k) * ( 1. + &
762 ( langenhk - 1.)*sigmaratio)
776 if (surfbuoyflux < 0.0)
then
779 sigma = min(1.0,-ifaceheight(k)/cs%OBLdepth(i,j))
780 nonlocaltrans(k,1) = (1.0 - sigma)**2 * (1.0 + 2.0*sigma)
781 nonlocaltrans(k,2) = nonlocaltrans(k,1)
785 sigma = min(1.0,-ifaceheight(k)/cs%OBLdepth(i,j))
786 nonlocaltrans(k,1) = (1.0 - sigma)**2
787 nonlocaltrans(k,2) = nonlocaltrans(k,1)
791 sigma = min(1.0,-ifaceheight(k)/cs%OBLdepth(i,j))
792 nonlocaltrans(k,1) = (1.0 - sigma)
793 nonlocaltrans(k,2) = nonlocaltrans(k,1)
798 sigma = min(1.0,-ifaceheight(k)/cs%OBLdepth(i,j))
799 nonlocaltrans(k,1) = cs%CS2 * sigma*(1.0 -sigma)**2
800 nonlocaltrans(k,2) = nonlocaltrans(k,1)
807 nonlocaltransheat(i,j,:) = nonlocaltrans(:,1)
808 nonlocaltransscalar(i,j,:) = nonlocaltrans(:,2)
811 if (cs%KPPzeroDiffusivity)
then
812 kdiffusivity(:,1) = 0.0
813 kdiffusivity(:,2) = 0.0
819 if (cs%id_Vt2 > 0)
then
831 cs%OBLdepthprev(i,j)=cs%OBLdepth(i,j)
832 if (cs%id_sigma > 0)
then
834 if (cs%OBLdepth(i,j)>0.) cs%sigma(i,j,:) = -ifaceheight/cs%OBLdepth(i,j)
836 if (cs%id_Kt_KPP > 0) cs%Kt_KPP(i,j,:) = kdiffusivity(:,1)
837 if (cs%id_Ks_KPP > 0) cs%Ks_KPP(i,j,:) = kdiffusivity(:,2)
838 if (cs%id_Kv_KPP > 0) cs%Kv_KPP(i,j,:) = kviscosity(:)
841 if (.not. cs%passiveMode)
then
842 if (cs%KPPisAdditive)
then
844 kt(i,j,k) = kt(i,j,k) + us%m2_s_to_Z2_T * kdiffusivity(k,1)
845 ks(i,j,k) = ks(i,j,k) + us%m2_s_to_Z2_T * kdiffusivity(k,2)
846 kv(i,j,k) = kv(i,j,k) + us%m2_s_to_Z2_T * kviscosity(k)
847 if (cs%Stokes_Mixing) waves%KvS(i,j,k) = kv(i,j,k)
851 if (kdiffusivity(k,1) /= 0.) kt(i,j,k) = us%m2_s_to_Z2_T * kdiffusivity(k,1)
852 if (kdiffusivity(k,2) /= 0.) ks(i,j,k) = us%m2_s_to_Z2_T * kdiffusivity(k,2)
853 if (kviscosity(k) /= 0.) kv(i,j,k) = us%m2_s_to_Z2_T * kviscosity(k)
854 if (cs%Stokes_Mixing) waves%KvS(i,j,k) = kv(i,j,k)
865 #ifdef __DO_SAFETY_CHECKS__
867 call hchksum(kt,
"KPP out: Kt", g%HI, haloshift=0, scale=us%Z2_T_to_m2_s)
868 call hchksum(ks,
"KPP out: Ks", g%HI, haloshift=0, scale=us%Z2_T_to_m2_s)
873 if (cs%id_OBLdepth > 0)
call post_data(cs%id_OBLdepth, cs%OBLdepth, cs%diag)
874 if (cs%id_OBLdepth_original > 0)
call post_data(cs%id_OBLdepth_original,cs%OBLdepth_original,cs%diag)
875 if (cs%id_sigma > 0)
call post_data(cs%id_sigma, cs%sigma, cs%diag)
876 if (cs%id_Ws > 0)
call post_data(cs%id_Ws, cs%Ws, cs%diag)
877 if (cs%id_Vt2 > 0)
call post_data(cs%id_Vt2, cs%Vt2, cs%diag)
878 if (cs%id_uStar > 0)
call post_data(cs%id_uStar, ustar, cs%diag)
879 if (cs%id_buoyFlux > 0)
call post_data(cs%id_buoyFlux, buoyflux, cs%diag)
880 if (cs%id_Kt_KPP > 0)
call post_data(cs%id_Kt_KPP, cs%Kt_KPP, cs%diag)
881 if (cs%id_Ks_KPP > 0)
call post_data(cs%id_Ks_KPP, cs%Ks_KPP, cs%diag)
882 if (cs%id_Kv_KPP > 0)
call post_data(cs%id_Kv_KPP, cs%Kv_KPP, cs%diag)
883 if (cs%id_NLTt > 0)
call post_data(cs%id_NLTt, nonlocaltransheat, cs%diag)
884 if (cs%id_NLTs > 0)
call post_data(cs%id_NLTs, nonlocaltransscalar,cs%diag)
891 subroutine kpp_compute_bld(CS, G, GV, US, h, Temp, Salt, u, v, EOS, uStar, buoyFlux, Waves)
894 type(
kpp_cs),
pointer :: cs
898 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)),
intent(in) :: h
899 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)),
intent(in) :: temp
900 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)),
intent(in) :: salt
901 real,
dimension(SZIB_(G),SZJ_(G),SZK_(G)),
intent(in) :: u
902 real,
dimension(SZI_(G),SZJB_(G),SZK_(G)),
intent(in) :: v
904 real,
dimension(SZI_(G),SZJ_(G)),
intent(in) :: ustar
905 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)+1),
intent(in) :: buoyflux
909 integer :: i, j, k, km1
910 real,
dimension( G%ke ) :: cellheight
911 real,
dimension( G%ke+1 ) :: ifaceheight
912 real,
dimension( G%ke+1 ) :: n2_1d
913 real,
dimension( G%ke ) :: ws_1d
914 real,
dimension( G%ke ) :: deltarho
915 real,
dimension( G%ke ) :: deltau2
916 real,
dimension( G%ke ) :: surfbuoyflux2
917 real,
dimension( G%ke ) :: bulkri_1d
920 real,
dimension( 3*G%ke ) :: rho_1d
921 real,
dimension( 3*G%ke ) :: pres_1d
922 real,
dimension( 3*G%ke ) :: temp_1d
923 real,
dimension( 3*G%ke ) :: salt_1d
925 real :: surffricvel, surfbuoyflux, coriolis
927 real :: pref, rho1, rhok, uk, vk, sigma, sigmaratio
929 real :: zbottomminusoffset
934 real :: surfhtemp, surftemp
935 real :: surfhsalt, surfsalt
936 real :: surfhu, surfu
937 real :: surfhv, surfv
940 integer :: kk, ksfc, ktmp
944 real,
dimension(G%ke) :: langenhvt2
945 real,
dimension(G%ke) :: u_h, v_h
946 real :: mld_guess, la
947 real :: surfhus, surfhvs, surfus, surfvs, wavedir, currentdir
948 real :: varup, vardn, m, varlo, varavg
949 real :: h10pct, h20pct,cmnfact, usx20pct, usy20pct, enhvt2
954 #ifdef __DO_SAFETY_CHECKS__
956 call hchksum(salt,
"KPP in: S",g%HI,haloshift=0)
957 call hchksum(temp,
"KPP in: T",g%HI,haloshift=0)
958 call hchksum(u,
"KPP in: u",g%HI,haloshift=0)
959 call hchksum(v,
"KPP in: v",g%HI,haloshift=0)
964 gorho = gv%mks_g_Earth / (us%R_to_kg_m3*gv%Rho0)
965 buoy_scale = us%L_to_m**2*us%s_to_T**3
982 if (g%mask2dT(i,j)==0.) cycle
985 u_h(k) = 0.5 * us%L_T_to_m_s*(u(i,j,k)+u(i-1,j,k))
986 v_h(k) = 0.5 * us%L_T_to_m_s*(v(i,j,k)+v(i,j-1,k))
990 coriolis = 0.25*us%s_to_T*( (g%CoriolisBu(i,j) + g%CoriolisBu(i-1,j-1)) + &
991 (g%CoriolisBu(i-1,j) + g%CoriolisBu(i,j-1)) )
992 surffricvel = us%Z_to_m*us%s_to_T * ustar(i,j)
1000 ifaceheight(1) = 0.0
1006 dh = h(i,j,k) * gv%H_to_m
1008 hcorr = min( dh - cs%min_thickness, 0. )
1009 dh = max( dh, cs%min_thickness )
1010 cellheight(k) = ifaceheight(k) - 0.5 * dh
1011 ifaceheight(k+1) = ifaceheight(k) - dh
1014 sldepth_0d = cs%surf_layer_ext*max( max(-cellheight(k),-ifaceheight(2) ), cs%minOBLdepth )
1017 if (-1.0*ifaceheight(ktmp+1) >= sldepth_0d)
then
1035 delh = min( max(0.0, sldepth_0d - htot), h(i,j,ktmp)*gv%H_to_m )
1041 surfhtemp = surfhtemp + temp(i,j,ktmp) * delh
1042 surfhsalt = surfhsalt + salt(i,j,ktmp) * delh
1043 surfhu = surfhu + 0.5*us%L_T_to_m_s*(u(i,j,ktmp)+u(i-1,j,ktmp)) * delh
1044 surfhv = surfhv + 0.5*us%L_T_to_m_s*(v(i,j,ktmp)+v(i,j-1,ktmp)) * delh
1045 if (cs%Stokes_Mixing)
then
1046 surfhus = surfhus + 0.5*(waves%US_x(i,j,ktmp)+waves%US_x(i-1,j,ktmp)) * delh
1047 surfhvs = surfhvs + 0.5*(waves%US_y(i,j,ktmp)+waves%US_y(i,j-1,ktmp)) * delh
1051 surftemp = surfhtemp / htot
1052 surfsalt = surfhsalt / htot
1053 surfu = surfhu / htot
1054 surfv = surfhv / htot
1055 surfus = surfhus / htot
1056 surfvs = surfhvs / htot
1061 uk = 0.5*us%L_T_to_m_s*(u(i,j,k)+u(i-1,j,k)) - surfu
1062 vk = 0.5*us%L_T_to_m_s*(v(i,j,k)+v(i,j-1,k)) - surfv
1064 if (cs%Stokes_Mixing)
then
1068 uk = uk + (0.5*(waves%Us_x(i,j,k)+waves%US_x(i-1,j,k)) -surfus )
1069 vk = vk + (0.5*(waves%Us_y(i,j,k)+waves%Us_y(i,j-1,k)) -surfvs )
1072 deltau2(k) = uk**2 + vk**2
1080 pres_1d(kk+1) = pref
1081 pres_1d(kk+2) = pref
1082 pres_1d(kk+3) = pref
1083 temp_1d(kk+1) = surftemp
1084 temp_1d(kk+2) = temp(i,j,k)
1085 temp_1d(kk+3) = temp(i,j,km1)
1086 salt_1d(kk+1) = surfsalt
1087 salt_1d(kk+2) = salt(i,j,k)
1088 salt_1d(kk+3) = salt(i,j,km1)
1092 pref = pref + gv%H_to_Pa * h(i,j,k)
1095 surfbuoyflux2(k) = buoy_scale * (buoyflux(i,j,1) - buoyflux(i,j,k+1))
1099 if (cs%LT_K_ENHANCEMENT .or. cs%LT_VT2_ENHANCEMENT)
then
1100 mld_guess = max( 1.*us%m_to_Z, abs(us%m_to_Z*cs%OBLdepthprev(i,j) ) )
1102 h=h(i,j,:), u_h=u_h, v_h=v_h, waves=waves)
1116 deltarho(k) = rho_1d(kk+2) - rho_1d(kk+1)
1117 n2_1d(k) = (gorho * (rho_1d(kk+2) - rho_1d(kk+3)) ) / &
1118 ((0.5*(h(i,j,km1) + h(i,j,k))+gv%H_subroundoff)*gv%H_to_m)
1119 cs%N(i,j,k) = sqrt( max( n2_1d(k), 0.) )
1121 n2_1d(g%ke+1 ) = 0.0
1122 cs%N(i,j,g%ke+1 ) = 0.0
1128 call cvmix_kpp_compute_turbulent_scales( &
1129 cs%surf_layer_ext, &
1134 cvmix_kpp_params_user=cs%KPP_params )
1137 cs%Vt2(i,j,:) = cvmix_kpp_compute_unresolved_shear( &
1138 zt_cntr=cellheight(1:g%ke), &
1140 n_iface=cs%N(i,j,:), &
1141 cvmix_kpp_params_user=cs%KPP_params )
1144 IF (cs%LT_VT2_ENHANCEMENT)
then
1147 langenhvt2(k) = cs%KPP_VT2_ENH_FAC
1151 enhvt2 = sqrt(1.+(1.5*cs%La_SL(i,j))**(-2) + &
1152 (5.4*cs%La_SL(i,j))**(-4))
1154 langenhvt2(k) = enhvt2
1158 enhvt2 = 1. + 2.3*cs%La_SL(i,j)**(-0.5)
1160 langenhvt2(k) = enhvt2
1163 cs%CS=cvmix_get_kpp_real(
'c_s',cs%KPP_params)
1165 wst = (max(0.,-buoy_scale*buoyflux(i,j,1))*(-cellheight(k)))**(1./3.)
1166 langenhvt2(k) = sqrt((0.15*wst**3. + 0.17*surffricvel**3.* &
1167 (1.+0.49*cs%La_SL(i,j)**(-2.))) / &
1168 (0.2*ws_1d(k)**3/(cs%cs*cs%surf_layer_ext*cs%vonKarman**4.)))
1180 cs%Vt2(i,j,k)=cs%Vt2(i,j,k)*langenhvt2(k)
1181 if (cs%id_EnhVt2 > 0) cs%EnhVt2(i,j,k)=langenhvt2(k)
1185 bulkri_1d = cvmix_kpp_compute_bulk_richardson( &
1186 zt_cntr = cellheight(1:g%ke), &
1187 delta_buoy_cntr=gorho*deltarho, &
1188 delta_vsqr_cntr=deltau2, &
1189 vt_sqr_cntr=cs%Vt2(i,j,:), &
1191 n_iface=cs%N(i,j,:))
1194 surfbuoyflux = buoy_scale * buoyflux(i,j,1)
1197 call cvmix_kpp_compute_obl_depth( &
1202 zt_cntr=cellheight, &
1203 surf_fric=surffricvel, &
1204 surf_buoy=surfbuoyflux, &
1205 coriolis=coriolis, &
1206 cvmix_kpp_params_user=cs%KPP_params )
1210 if (cs%deepOBLoffset>0.)
then
1211 zbottomminusoffset = ifaceheight(g%ke+1) + min(cs%deepOBLoffset,-0.1*ifaceheight(g%ke+1))
1212 cs%OBLdepth(i,j) = min( cs%OBLdepth(i,j), -zbottomminusoffset )
1216 if(cs%fixedOBLdepth) cs%OBLdepth(i,j) = cs%fixedOBLdepth_value
1217 cs%OBLdepth(i,j) = max( cs%OBLdepth(i,j), -ifaceheight(2) )
1218 cs%OBLdepth(i,j) = min( cs%OBLdepth(i,j), -ifaceheight(g%ke+1) )
1219 cs%kOBL(i,j) = cvmix_kpp_compute_kobl_depth( ifaceheight, cellheight, cs%OBLdepth(i,j) )
1304 if (cs%id_Ws > 0)
then
1305 call cvmix_kpp_compute_turbulent_scales( &
1306 -cellheight/cs%OBLdepth(i,j), &
1311 cvmix_kpp_params_user=cs%KPP_params)
1312 cs%Ws(i,j,:) = ws_1d(:)
1316 if (cs%id_N2 > 0) cs%N2(i,j,:) = n2_1d(:)
1317 if (cs%id_BulkDrho > 0) cs%dRho(i,j,:) = deltarho(:)
1318 if (cs%id_BulkRi > 0) cs%BulkRi(i,j,:) = bulkri_1d(:)
1319 if (cs%id_BulkUz2 > 0) cs%Uz2(i,j,:) = deltau2(:)
1320 if (cs%id_Tsurf > 0) cs%Tsurf(i,j) = surftemp
1321 if (cs%id_Ssurf > 0) cs%Ssurf(i,j) = surfsalt
1322 if (cs%id_Usurf > 0) cs%Usurf(i,j) = surfu
1323 if (cs%id_Vsurf > 0) cs%Vsurf(i,j) = surfv
1329 if (cs%id_BulkRi > 0)
call post_data(cs%id_BulkRi, cs%BulkRi, cs%diag)
1330 if (cs%id_N > 0)
call post_data(cs%id_N, cs%N, cs%diag)
1331 if (cs%id_N2 > 0)
call post_data(cs%id_N2, cs%N2, cs%diag)
1332 if (cs%id_Tsurf > 0)
call post_data(cs%id_Tsurf, cs%Tsurf, cs%diag)
1333 if (cs%id_Ssurf > 0)
call post_data(cs%id_Ssurf, cs%Ssurf, cs%diag)
1334 if (cs%id_Usurf > 0)
call post_data(cs%id_Usurf, cs%Usurf, cs%diag)
1335 if (cs%id_Vsurf > 0)
call post_data(cs%id_Vsurf, cs%Vsurf, cs%diag)
1336 if (cs%id_BulkDrho > 0)
call post_data(cs%id_BulkDrho, cs%dRho, cs%diag)
1337 if (cs%id_BulkUz2 > 0)
call post_data(cs%id_BulkUz2, cs%Uz2, cs%diag)
1338 if (cs%id_EnhK > 0)
call post_data(cs%id_EnhK, cs%EnhK, cs%diag)
1339 if (cs%id_EnhVt2 > 0)
call post_data(cs%id_EnhVt2, cs%EnhVt2, cs%diag)
1340 if (cs%id_La_SL > 0)
call post_data(cs%id_La_SL, cs%La_SL, cs%diag)
1351 type(
kpp_cs),
pointer :: CS
1354 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)),
intent(in) :: h
1357 real,
dimension( G%ke ) :: cellHeight
1359 real,
dimension( G%ke+1 ) :: iFaceHeight
1361 real :: wc, ww, we, wn, ws
1365 integer :: i, j, k, s
1369 if (cs%id_OBLdepth_original > 0) cs%OBLdepth_original = cs%OBLdepth
1377 call pass_var(cs%OBLdepth, g%Domain, halo=4)
1380 cs%OBLdepthprev = cs%OBLdepth
1383 do j = g%jsc-2, g%jec+2
1384 do i = g%isc-2, g%iec+2
1387 if (g%mask2dT(i,j)==0.) cycle
1391 ww = 0.125 * g%mask2dT(i-1,j)
1392 we = 0.125 * g%mask2dT(i+1,j)
1393 ws = 0.125 * g%mask2dT(i,j-1)
1394 wn = 0.125 * g%mask2dT(i,j+1)
1420 wc = 1.0 - (ww+we+wn+ws)
1422 cs%OBLdepth(i,j) = wc * cs%OBLdepthprev(i,j) &
1423 + ww * cs%OBLdepthprev(i-1,j) &
1424 + we * cs%OBLdepthprev(i+1,j) &
1425 + ws * cs%OBLdepthprev(i,j-1) &
1426 + wn * cs%OBLdepthprev(i,j+1)
1438 if (g%mask2dT(i,j)==0.) cycle
1440 ifaceheight(1) = 0.0
1445 dh = h(i,j,k) * gv%H_to_m
1447 hcorr = min( dh - cs%min_thickness, 0. )
1448 dh = max( dh, cs%min_thickness )
1449 cellheight(k) = ifaceheight(k) - 0.5 * dh
1450 ifaceheight(k+1) = ifaceheight(k) - dh
1454 if (cs%deepen_only) cs%OBLdepth(i,j) = max(cs%OBLdepth(i,j),cs%OBLdepth_original(i,j))
1457 cs%OBLdepth(i,j) = min( cs%OBLdepth(i,j), -ifaceheight(g%ke+1) )
1459 cs%kOBL(i,j) = cvmix_kpp_compute_kobl_depth( ifaceheight, cellheight, cs%OBLdepth(i,j) )
1472 real,
dimension(SZI_(G),SZJ_(G)),
intent(inout) :: bld
1475 do j = g%jsc, g%jec ;
do i = g%isc, g%iec
1476 bld(i,j) = cs%OBLdepth(i,j)
1484 type(
kpp_cs),
intent(in) :: cs
1487 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)),
intent(in) :: h
1488 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)+1),
intent(in) :: nonlocaltrans
1489 real,
dimension(SZI_(G),SZJ_(G)),
intent(in) :: surfflux
1491 real,
intent(in) :: dt
1492 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)),
intent(inout) :: scalar
1493 real,
intent(in) :: c_p
1496 real,
dimension( SZI_(G), SZJ_(G), SZK_(G) ) :: dtracer
1499 dtracer(:,:,:) = 0.0
1504 dtracer(i,j,k) = ( nonlocaltrans(i,j,k) - nonlocaltrans(i,j,k+1) ) / &
1505 ( h(i,j,k) + gv%H_subroundoff ) * surfflux(i,j)
1511 if (cs%applyNonLocalTrans)
then
1515 scalar(i,j,k) = scalar(i,j,k) + dt * dtracer(i,j,k)
1522 if (cs%id_QminusSW > 0)
call post_data(cs%id_QminusSW, surfflux, cs%diag)
1523 if (cs%id_NLT_dTdt > 0)
call post_data(cs%id_NLT_dTdt, dtracer, cs%diag)
1524 if (cs%id_NLT_temp_budget > 0)
then
1525 dtracer(:,:,:) = 0.0
1529 dtracer(i,j,k) = (nonlocaltrans(i,j,k) - nonlocaltrans(i,j,k+1)) * &
1530 surfflux(i,j) * c_p * gv%H_to_kg_m2
1534 call post_data(cs%id_NLT_temp_budget, dtracer, cs%diag)
1544 type(
kpp_cs),
intent(in) :: cs
1547 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)),
intent(in) :: h
1548 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)+1),
intent(in) :: nonlocaltrans
1549 real,
dimension(SZI_(G),SZJ_(G)),
intent(in) :: surfflux
1551 real,
intent(in) :: dt
1552 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)),
intent(inout) :: scalar
1555 real,
dimension( SZI_(G), SZJ_(G), SZK_(G) ) :: dtracer
1558 dtracer(:,:,:) = 0.0
1563 dtracer(i,j,k) = ( nonlocaltrans(i,j,k) - nonlocaltrans(i,j,k+1) ) / &
1564 ( h(i,j,k) + gv%H_subroundoff ) * surfflux(i,j)
1570 if (cs%applyNonLocalTrans)
then
1574 scalar(i,j,k) = scalar(i,j,k) + dt * dtracer(i,j,k)
1581 if (cs%id_netS > 0)
call post_data(cs%id_netS, surfflux, cs%diag)
1582 if (cs%id_NLT_dSdt > 0)
call post_data(cs%id_NLT_dSdt, dtracer, cs%diag)
1583 if (cs%id_NLT_saln_budget > 0)
then
1584 dtracer(:,:,:) = 0.0
1588 dtracer(i,j,k) = (nonlocaltrans(i,j,k) - nonlocaltrans(i,j,k+1)) * &
1589 surfflux(i,j) * gv%H_to_kg_m2
1593 call post_data(cs%id_NLT_saln_budget, dtracer, cs%diag)
1605 if (.not.
associated(cs))
return