10 use mom_cpu_clock,
only : cpu_clock_id, cpu_clock_begin, cpu_clock_end
11 use mom_cpu_clock,
only : clock_module_driver, clock_module, clock_routine
74 implicit none ;
private
76 #include <MOM_memory.h>
94 logical :: use_legacy_diabatic
99 logical :: use_energetic_pbl
104 logical :: use_kappa_shear
106 logical :: use_cvmix_shear
108 logical :: use_cvmix_ddiff
109 logical :: use_tidal_mixing
110 logical :: use_cvmix_conv
112 logical :: use_sponge
116 logical :: use_geothermal
117 logical :: use_int_tides
119 logical :: epbl_is_additive
123 real :: uniform_test_cg
125 logical :: usealealgorithm
128 logical :: aggregate_fw_forcing
138 logical :: massless_match_targets
140 logical :: mix_boundary_tracers
151 real :: minimum_forcing_depth
153 real :: evap_cfl_limit = 0.8
155 integer :: halo_ts_diff = 0
157 logical :: usekpp = .false.
158 logical :: salt_reject_below_ml
159 logical :: kppispassive
161 logical :: debugconservation
162 logical :: tracer_tridiag
164 logical :: debug_energy_req
166 real :: mlddensitydifference
171 integer :: id_cg1 = -1
172 integer,
allocatable,
dimension(:) :: id_cn
173 integer :: id_wd = -1, id_ea = -1, id_eb = -1
174 integer :: id_dudt_dia = -1, id_dvdt_dia = -1, id_ea_s = -1, id_eb_s = -1
175 integer :: id_ea_t = -1, id_eb_t = -1
176 integer :: id_kd_heat = -1, id_kd_salt = -1, id_kd_interface = -1, id_kd_epbl = -1
177 integer :: id_tdif = -1, id_tadv = -1, id_sdif = -1, id_sadv = -1
178 integer :: id_mld_003 = -1, id_mld_0125 = -1, id_mld_user = -1, id_mlotstsq = -1
179 integer :: id_submln2 = -1, id_brine_lay = -1
182 integer :: id_u_predia = -1, id_v_predia = -1, id_h_predia = -1
183 integer :: id_t_predia = -1, id_s_predia = -1, id_e_predia = -1
185 integer :: id_diabatic_diff_temp_tend = -1
186 integer :: id_diabatic_diff_saln_tend = -1
187 integer :: id_diabatic_diff_heat_tend = -1
188 integer :: id_diabatic_diff_salt_tend = -1
189 integer :: id_diabatic_diff_heat_tend_2d = -1
190 integer :: id_diabatic_diff_salt_tend_2d = -1
191 integer :: id_diabatic_diff_h= -1
193 integer :: id_boundary_forcing_h = -1
194 integer :: id_boundary_forcing_h_tendency = -1
195 integer :: id_boundary_forcing_temp_tend = -1
196 integer :: id_boundary_forcing_saln_tend = -1
197 integer :: id_boundary_forcing_heat_tend = -1
198 integer :: id_boundary_forcing_salt_tend = -1
199 integer :: id_boundary_forcing_heat_tend_2d = -1
200 integer :: id_boundary_forcing_salt_tend_2d = -1
202 integer :: id_frazil_h = -1
203 integer :: id_frazil_temp_tend = -1
204 integer :: id_frazil_heat_tend = -1
205 integer :: id_frazil_heat_tend_2d = -1
208 logical :: diabatic_diff_tendency_diag = .false.
209 logical :: boundary_forcing_tendency_diag = .false.
210 logical :: frazil_tendency_diag = .false.
211 real,
allocatable,
dimension(:,:,:) :: frazil_heat_diag
212 real,
allocatable,
dimension(:,:,:) :: frazil_temp_diag
229 type(
kpp_cs),
pointer :: kpp_csp => null()
234 type(group_pass_type) :: pass_hold_eb_ea
235 type(group_pass_type) :: pass_kv
238 real,
allocatable,
dimension(:,:,:) :: kpp_nltheat
239 real,
allocatable,
dimension(:,:,:) :: kpp_nltscalar
240 real,
allocatable,
dimension(:,:,:) :: kpp_buoy_flux
241 real,
allocatable,
dimension(:,:) :: kpp_temp_flux
242 real,
allocatable,
dimension(:,:) :: kpp_salt_flux
244 type(time_type),
pointer :: time
257 subroutine diabatic(u, v, h, tv, Hml, fluxes, visc, ADp, CDp, dt, Time_end, &
258 G, GV, US, CS, WAVES)
261 real,
dimension(SZIB_(G),SZJ_(G),SZK_(G)),
intent(inout) :: u
262 real,
dimension(SZI_(G),SZJB_(G),SZK_(G)),
intent(inout) :: v
263 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)),
intent(inout) :: h
266 real,
dimension(:,:),
pointer :: hml
267 type(
forcing),
intent(inout) :: fluxes
274 real,
intent(in) :: dt
275 type(time_type),
intent(in) :: time_end
281 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)+1) :: &
283 real,
dimension(SZI_(G),SZJ_(G),CS%nMode) :: &
285 real,
dimension(SZI_(G),SZJ_(G),G%ke) :: temp_diag
286 integer :: i, j, k, m, is, ie, js, je, nz
287 logical :: showcalltree
289 if (g%ke == 1)
return
291 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
293 if (.not.
associated(cs))
call mom_error(fatal,
"MOM_diabatic_driver: "// &
294 "Module must be initialized before it is used.")
295 if (dt == 0.0)
call mom_error(fatal,
"MOM_diabatic_driver: "// &
296 "diabatic was called with a zero length timestep.")
297 if (dt < 0.0)
call mom_error(fatal,
"MOM_diabatic_driver: "// &
298 "diabatic was called with a negative timestep.")
300 showcalltree = calltree_showquery()
304 if (cs%id_u_predia > 0)
call post_data(cs%id_u_predia, u, cs%diag)
305 if (cs%id_v_predia > 0)
call post_data(cs%id_v_predia, v, cs%diag)
306 if (cs%id_h_predia > 0)
call post_data(cs%id_h_predia, h, cs%diag)
307 if (cs%id_T_predia > 0)
call post_data(cs%id_T_predia, tv%T, cs%diag)
308 if (cs%id_S_predia > 0)
call post_data(cs%id_S_predia, tv%S, cs%diag)
309 if (cs%id_e_predia > 0)
then
310 call find_eta(h, tv, g, gv, us, eta, eta_to_m=1.0)
311 call post_data(cs%id_e_predia, eta, cs%diag)
315 call mom_state_chksum(
"Start of diabatic ", u, v, h, g, gv, us, haloshift=0)
316 call mom_forcing_chksum(
"Start of diabatic", fluxes, g, us, haloshift=0)
318 if (cs%debugConservation)
call mom_state_stats(
'Start of diabatic', u, v, h, tv%T, tv%S, g, gv, us)
320 if (cs%debug_energy_req) &
324 call set_bbl_tke(u, v, h, fluxes, visc, g, gv, us, cs%set_diff_CSp)
330 if (
associated(tv%T) .AND.
associated(tv%frazil))
then
332 call enable_averages(0.5*dt, time_end -
real_to_time(0.5*us%T_to_s*dt), cs%diag)
333 if (cs%frazil_tendency_diag)
then
334 do k=1,nz ;
do j=js,je ;
do i=is,ie
335 temp_diag(i,j,k) = tv%T(i,j,k)
336 enddo ;
enddo ;
enddo
339 if (
associated(fluxes%p_surf_full))
then
340 call make_frazil(h, tv, g, gv, cs%diabatic_aux_CSp, fluxes%p_surf_full, halo=cs%halo_TS_diff)
342 call make_frazil(h, tv, g, gv, cs%diabatic_aux_CSp, halo=cs%halo_TS_diff)
346 if (cs%frazil_tendency_diag)
then
348 if (cs%id_frazil_h > 0)
call post_data(cs%id_frazil_h, h, cs%diag)
350 call disable_averaging(cs%diag)
352 if (cs%debugConservation)
call mom_state_stats(
'1st make_frazil', u, v, h, tv%T, tv%S, g, gv, us)
355 if (cs%use_int_tides)
then
357 call set_int_tide_input(u, v, h, tv, fluxes, cs%int_tide_input, dt, g, gv, us, &
358 cs%int_tide_input_CSp)
360 if (cs%uniform_test_cg > 0.0)
then
361 do m=1,cs%nMode ; cn_igw(:,:,m) = cs%uniform_test_cg ;
enddo
363 call wave_speeds(h, tv, g, gv, us, cs%nMode, cn_igw, full_halos=.true.)
366 call propagate_int_tide(h, tv, cn_igw, cs%int_tide_input%TKE_itidal_input, cs%int_tide_input%tideamp, &
367 cs%int_tide_input%Nb, dt, g, gv, us, cs%int_tide_CSp)
368 if (showcalltree)
call calltree_waypoint(
"done with propagate_int_tide (diabatic)")
371 if (cs%useALEalgorithm .and. cs%use_legacy_diabatic)
then
372 call diabatic_ale_legacy(u, v, h, tv, hml, fluxes, visc, adp, cdp, dt, time_end, &
373 g, gv, us, cs, waves)
374 elseif (cs%useALEalgorithm)
then
375 call diabatic_ale(u, v, h, tv, hml, fluxes, visc, adp, cdp, dt, time_end, &
376 g, gv, us, cs, waves)
378 call layered_diabatic(u, v, h, tv, hml, fluxes, visc, adp, cdp, dt, time_end, &
379 g, gv, us, cs, waves)
384 if (
associated(visc%Kv_shear)) &
385 call pass_var(visc%Kv_shear, g%Domain, to_all+omit_corners, halo=1)
388 call disable_averaging(cs%diag)
392 if (
associated(tv%T) .AND.
associated(tv%frazil))
then
393 call enable_averages(0.5*dt, time_end, cs%diag)
394 if (cs%frazil_tendency_diag)
then
395 do k=1,nz ;
do j=js,je ;
do i=is,ie
396 temp_diag(i,j,k) = tv%T(i,j,k)
397 enddo ;
enddo ;
enddo
400 if (
associated(fluxes%p_surf_full))
then
401 call make_frazil(h, tv, g, gv, cs%diabatic_aux_CSp, fluxes%p_surf_full)
403 call make_frazil(h, tv, g, gv, cs%diabatic_aux_CSp)
406 if (cs%frazil_tendency_diag)
then
408 if (cs%id_frazil_h > 0 )
call post_data(cs%id_frazil_h, h, cs%diag)
412 if (cs%debugConservation)
call mom_state_stats(
'2nd make_frazil', u, v, h, tv%T, tv%S, g, gv, us)
413 call disable_averaging(cs%diag)
419 call enable_averages(dt, time_end, cs%diag)
420 if (cs%id_MLD_003 > 0 .or. cs%id_subMLN2 > 0 .or. cs%id_mlotstsq > 0)
then
421 call diagnosemldbydensitydifference(cs%id_MLD_003, h, tv, 0.03*us%kg_m3_to_R, g, gv, us, cs%diag, &
422 id_n2subml=cs%id_subMLN2, id_mldsq=cs%id_mlotstsq, dz_subml=cs%dz_subML_N2)
424 if (cs%id_MLD_0125 > 0)
then
425 call diagnosemldbydensitydifference(cs%id_MLD_0125, h, tv, 0.125*us%kg_m3_to_R, g, gv, us, cs%diag)
427 if (cs%id_MLD_user > 0)
then
428 call diagnosemldbydensitydifference(cs%id_MLD_user, h, tv, cs%MLDdensityDifference, g, gv, us, cs%diag)
430 if (cs%use_int_tides)
then
431 if (cs%id_cg1 > 0)
call post_data(cs%id_cg1, cn_igw(:,:,1),cs%diag)
432 do m=1,cs%nMode ;
if (cs%id_cn(m) > 0)
call post_data(cs%id_cn(m), cn_igw(:,:,m), cs%diag) ;
enddo
434 call disable_averaging(cs%diag)
436 if (cs%debugConservation)
call mom_state_stats(
'leaving diabatic', u, v, h, tv%T, tv%S, g, gv, us)
444 subroutine diabatic_ale_legacy(u, v, h, tv, Hml, fluxes, visc, ADp, CDp, dt, Time_end, &
445 G, GV, US, CS, WAVES)
449 real,
dimension(SZIB_(G),SZJ_(G),SZK_(G)),
intent(inout) :: u
450 real,
dimension(SZI_(G),SZJB_(G),SZK_(G)),
intent(inout) :: v
451 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)),
intent(inout) :: h
454 real,
dimension(:,:),
pointer :: Hml
455 type(
forcing),
intent(inout) :: fluxes
462 real,
intent(in) :: dt
463 type(time_type),
intent(in) :: Time_end
468 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)) :: &
488 real,
dimension(SZI_(G),SZJ_(G)) :: &
491 real,
dimension(SZI_(G),SZJ_(G),G%ke) :: h_diag
492 real,
dimension(SZI_(G),SZJ_(G),G%ke) :: temp_diag
493 real,
dimension(SZI_(G),SZJ_(G),G%ke) :: saln_diag
494 real,
dimension(SZI_(G),SZJ_(G)) :: tendency_2d
498 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)) :: &
503 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)+1),
target :: &
513 logical :: in_boundary(SZI_(G))
533 real :: htot(SZIB_(G))
534 real :: b1(SZIB_(G)), d1(SZIB_(G))
535 real :: c1(SZIB_(G),SZK_(G))
541 logical :: showCallTree
542 integer :: i, j, k, is, ie, js, je, Isq, Ieq, Jsq, Jeq, nz, nkmb, m, halo
547 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
548 isq = g%IscB ; ieq = g%IecB ; jsq = g%JscB ; jeq = g%JecB
549 nkmb = gv%nk_rho_varies
550 h_neglect = gv%H_subroundoff ; h_neglect2 = h_neglect*h_neglect
551 kd_heat(:,:,:) = 0.0 ; kd_salt(:,:,:) = 0.0
553 showcalltree = calltree_showquery()
554 if (showcalltree)
call calltree_enter(
"diabatic_ALE_legacy(), MOM_diabatic_driver.F90")
558 call enable_averages(dt, time_end, cs%diag)
560 if (cs%use_geothermal)
then
561 halo = cs%halo_TS_diff
563 do k=1,nz ;
do j=js-halo,je+halo ;
do i=is-halo,ie+halo
564 h_orig(i,j,k) = h(i,j,k) ; eatr(i,j,k) = 0.0 ; ebtr(i,j,k) = 0.0
565 enddo ;
enddo ;
enddo
568 if (cs%use_geothermal)
then
570 call geothermal(h, tv, dt, eatr, ebtr, g, gv, us, cs%geothermal_CSp, halo=cs%halo_TS_diff)
573 if (cs%debugConservation)
call mom_state_stats(
'geothermal', u, v, h, tv%T, tv%S, g, gv, us)
578 call diag_update_remap_grids(cs%diag)
583 if (
associated(cs%optics)) &
584 call set_pen_shortwave(cs%optics, fluxes, g, gv, cs%diabatic_aux_CSp, cs%opacity_CSp, cs%tracer_flow_CSp)
586 if (cs%debug)
call mom_state_chksum(
"before find_uv_at_h", u, v, h, g, gv, us, haloshift=0)
588 if (cs%use_kappa_shear .or. cs%use_CVMix_shear)
then
589 if (cs%use_geothermal)
then
590 call find_uv_at_h(u, v, h_orig, u_h, v_h, g, gv, us, eatr, ebtr)
592 call hchksum(eatr,
"after find_uv_at_h eatr",g%HI, scale=gv%H_to_m)
593 call hchksum(ebtr,
"after find_uv_at_h ebtr",g%HI, scale=gv%H_to_m)
596 call find_uv_at_h(u, v, h, u_h, v_h, g, gv, us)
604 call set_diffusivity(u, v, h, u_h, v_h, tv, fluxes, cs%optics, &
605 visc, dt, g, gv, us, cs%set_diff_CSp, kd_lay, kd_int)
611 if (.not.cs%use_legacy_diabatic .or. cs%useKPP)
then
613 do k=1,nz+1 ;
do j=js,je ;
do i=is,ie
614 kd_salt(i,j,k) = kd_int(i,j,k)
615 kd_heat(i,j,k) = kd_int(i,j,k)
616 enddo ;
enddo ;
enddo
618 if (
associated(visc%Kd_extra_S))
then
620 do k=1,nz+1 ;
do j=js,je ;
do i=is,ie
621 kd_salt(i,j,k) = kd_salt(i,j,k) + visc%Kd_extra_S(i,j,k)
622 enddo ;
enddo ;
enddo
624 if (
associated(visc%Kd_extra_T))
then
626 do k=1,nz+1 ;
do j=js,je ;
do i=is,ie
627 kd_heat(i,j,k) = kd_heat(i,j,k) + visc%Kd_extra_T(i,j,k)
628 enddo ;
enddo ;
enddo
633 call mom_state_chksum(
"after set_diffusivity ", u, v, h, g, gv, us, haloshift=0)
634 call mom_forcing_chksum(
"after set_diffusivity ", fluxes, g, us, haloshift=0)
636 call hchksum(kd_int,
"after set_diffusivity Kd_Int", g%HI, haloshift=0, scale=us%Z2_T_to_m2_s)
637 call hchksum(kd_heat,
"after set_diffusivity Kd_heat", g%HI, haloshift=0, scale=us%Z2_T_to_m2_s)
638 call hchksum(kd_salt,
"after set_diffusivity Kd_salt", g%HI, haloshift=0, scale=us%Z2_T_to_m2_s)
644 if (.not.cs%use_legacy_diabatic)
then
645 do k=1,nz+1 ;
do j=js,je ;
do i=is,ie
646 visc%Kv_shear(i,j,k) = visc%Kv_shear(i,j,k) + visc%Kv_slow(i,j,k)
647 enddo ;
enddo ;
enddo
656 cs%KPP_buoy_flux, cs%KPP_temp_flux, cs%KPP_salt_flux)
659 call kpp_compute_bld(cs%KPP_CSp, g, gv, us, h, tv%T, tv%S, u, v, tv%eqn_of_state, &
660 fluxes%ustar, cs%KPP_buoy_flux, waves=waves)
662 call kpp_calculate(cs%KPP_CSp, g, gv, us, h, fluxes%ustar, cs%KPP_buoy_flux, kd_heat, &
663 kd_salt, visc%Kv_shear, cs%KPP_NLTheat, cs%KPP_NLTscalar, waves=waves)
665 if (
associated(hml))
then
667 call kpp_get_bld(cs%KPP_CSp, hml(:,:), g)
669 call pass_var(hml, g%domain, halo=1)
671 if (
associated(visc%MLD)) visc%MLD(:,:) = hml(:,:)
674 if (cs%use_legacy_diabatic .and. .not.cs%KPPisPassive)
then
676 do k=1,nz+1 ;
do j=js,je ;
do i=is,ie
677 kd_int(i,j,k) = min( kd_salt(i,j,k), kd_heat(i,j,k) )
678 enddo ;
enddo ;
enddo
679 if (
associated(visc%Kd_extra_S))
then
681 do k=1,nz+1 ;
do j=js,je ;
do i=is,ie
682 visc%Kd_extra_S(i,j,k) = (kd_salt(i,j,k) - kd_int(i,j,k))
683 enddo ;
enddo ;
enddo
685 if (
associated(visc%Kd_extra_T))
then
687 do k=1,nz+1 ;
do j=js,je ;
do i=is,ie
688 visc%Kd_extra_T(i,j,k) = (kd_heat(i,j,k) - kd_int(i,j,k))
689 enddo ;
enddo ;
enddo
697 call mom_forcing_chksum(
"after KPP", fluxes, g, us, haloshift=0)
699 call hchksum(kd_heat,
"after KPP Kd_heat", g%HI, haloshift=0, scale=us%Z2_T_to_m2_s)
700 call hchksum(kd_salt,
"after KPP Kd_salt", g%HI, haloshift=0, scale=us%Z2_T_to_m2_s)
709 call hchksum(cs%KPP_temp_flux,
"before KPP_applyNLT netHeat", g%HI, haloshift=0, scale=gv%H_to_m)
710 call hchksum(cs%KPP_salt_flux,
"before KPP_applyNLT netSalt", g%HI, haloshift=0, scale=gv%H_to_m)
711 call hchksum(cs%KPP_NLTheat,
"before KPP_applyNLT NLTheat", g%HI, haloshift=0)
712 call hchksum(cs%KPP_NLTscalar,
"before KPP_applyNLT NLTscalar", g%HI, haloshift=0)
717 us%T_to_s*dt, tv%T, tv%C_p)
721 if (showcalltree)
call calltree_waypoint(
"done with KPP_applyNonLocalTransport (diabatic)")
722 if (cs%debugConservation)
call mom_state_stats(
'KPP_applyNonLocalTransport', u, v, h, tv%T, tv%S, g, gv, us)
725 call mom_state_chksum(
"after KPP_applyNLT ", u, v, h, g, gv, us, haloshift=0)
726 call mom_forcing_chksum(
"after KPP_applyNLT ", fluxes, g, us, haloshift=0)
733 if (
associated(visc%Kd_extra_T) .and.
associated(visc%Kd_extra_S) .and.
associated(tv%T) .and. &
734 (cs%use_legacy_diabatic .or. .not.cs%use_CVMix_ddiff))
then
737 call differential_diffuse_t_s(h, tv, visc, dt, g, gv)
740 if (showcalltree)
call calltree_waypoint(
"done with differential_diffuse_T_S (diabatic)")
741 if (cs%debugConservation)
call mom_state_stats(
'differential_diffuse_T_S', u, v, h, tv%T, tv%S, g, gv, us)
745 if (.not. cs%useKPP)
then
747 do k=2,nz ;
do j=js,je ;
do i=is,ie
748 kd_heat(i,j,k) = kd_heat(i,j,k) + visc%Kd_extra_T(i,j,k)
749 kd_salt(i,j,k) = kd_salt(i,j,k) + visc%Kd_extra_S(i,j,k)
750 enddo ;
enddo ;
enddo
756 if (cs%use_CVMix_conv)
then
759 if (cs%use_legacy_diabatic)
then
761 do k=1,nz+1 ;
do j=js,je ;
do i=is,ie
762 kd_int(i,j,k) = kd_int(i,j,k) + cs%CVMix_conv_csp%kd_conv(i,j,k)
763 visc%Kv_slow(i,j,k) = visc%Kv_slow(i,j,k) + cs%CVMix_conv_csp%kv_conv(i,j,k)
764 enddo ;
enddo ;
enddo
767 do k=1,nz+1 ;
do j=js,je ;
do i=is,ie
768 kd_heat(i,j,k) = kd_heat(i,j,k) + cs%CVMix_conv_csp%kd_conv(i,j,k)
769 kd_salt(i,j,k) = kd_salt(i,j,k) + cs%CVMix_conv_csp%kd_conv(i,j,k)
771 visc%Kv_shear(i,j,k) = visc%Kv_shear(i,j,k) + cs%CVMix_conv_csp%kv_conv(i,j,k)
773 visc%Kv_slow(i,j,k) = visc%Kv_slow(i,j,k) + cs%CVMix_conv_csp%kv_conv(i,j,k)
775 enddo ;
enddo ;
enddo
780 if (cs%use_legacy_diabatic)
then
781 do j=js,je ;
do i=is,ie
785 do k=2,nz ;
do j=js,je ;
do i=is,ie
786 hval=1.0/(h_neglect + 0.5*(h(i,j,k-1) + h(i,j,k)))
787 ea_s(i,j,k) = (gv%Z_to_H**2) * dt * hval * kd_int(i,j,k)
788 eb_s(i,j,k-1) = ea_s(i,j,k)
789 ea_t(i,j,k-1) = ea_s(i,j,k-1) ; eb_t(i,j,k-1) = eb_s(i,j,k-1)
790 enddo ;
enddo ;
enddo
791 do j=js,je ;
do i=is,ie
793 ea_t(i,j,nz) = ea_s(i,j,nz) ; eb_t(i,j,nz) = eb_s(i,j,nz)
795 if (showcalltree)
call calltree_waypoint(
"done setting ea,eb from Kd_int (diabatic)")
799 call mom_forcing_chksum(
"after calc_entrain ", fluxes, g, us, haloshift=0)
801 call mom_state_chksum(
"after calc_entrain ", u, v, h, g, gv, us, haloshift=0)
802 call hchksum(ea_s,
"after calc_entrain ea_s", g%HI, haloshift=0, scale=gv%H_to_m)
803 call hchksum(eb_s,
"after calc_entrain eb_s", g%HI, haloshift=0, scale=gv%H_to_m)
807 if (cs%boundary_forcing_tendency_diag)
then
808 do k=1,nz ;
do j=js,je ;
do i=is,ie
809 h_diag(i,j,k) = h(i,j,k)
810 temp_diag(i,j,k) = tv%T(i,j,k)
811 saln_diag(i,j,k) = tv%S(i,j,k)
812 enddo ;
enddo ;
enddo
819 do k=1,nz ;
do j=js,je ;
do i=is,ie
820 h_prebound(i,j,k) = h(i,j,k)
821 enddo ;
enddo ;
enddo
822 if (cs%use_energetic_PBL)
then
824 skinbuoyflux(:,:) = 0.0
825 call applyboundaryfluxesinout(cs%diabatic_aux_CSp, g, gv, us, dt, fluxes, cs%optics, &
826 optics_nbands(cs%optics), h, tv, cs%aggregate_FW_forcing, cs%evap_CFL_limit, &
827 cs%minimum_forcing_depth, ctke, dsv_dt, dsv_ds, skinbuoyflux=skinbuoyflux)
830 call hchksum(ea_t,
"after applyBoundaryFluxes ea_t",g%HI,haloshift=0, scale=gv%H_to_m)
831 call hchksum(eb_t,
"after applyBoundaryFluxes eb_t",g%HI,haloshift=0, scale=gv%H_to_m)
832 call hchksum(ea_s,
"after applyBoundaryFluxes ea_s",g%HI,haloshift=0, scale=gv%H_to_m)
833 call hchksum(eb_s,
"after applyBoundaryFluxes eb_s",g%HI,haloshift=0, scale=gv%H_to_m)
834 call hchksum(ctke,
"after applyBoundaryFluxes cTKE", g%HI, haloshift=0, &
835 scale=us%R_to_kg_m3*us%Z_to_m**3*us%s_to_T**2)
836 call hchksum(dsv_dt,
"after applyBoundaryFluxes dSV_dT", g%HI, haloshift=0, scale=us%kg_m3_to_R)
837 call hchksum(dsv_ds,
"after applyBoundaryFluxes dSV_dS", g%HI, haloshift=0, scale=us%kg_m3_to_R)
840 call find_uv_at_h(u, v, h, u_h, v_h, g, gv, us)
841 call energetic_pbl(h, u_h, v_h, tv, fluxes, dt, kd_epbl, g, gv, us, &
842 cs%energetic_PBL_CSp, dsv_dt, dsv_ds, ctke, skinbuoyflux, waves=waves)
844 if (
associated(hml))
then
846 call pass_var(hml, g%domain, halo=1)
848 if (
associated(visc%MLD)) visc%MLD(:,:) = hml(:,:)
849 elseif (
associated(visc%MLD))
then
851 call pass_var(visc%MLD, g%domain, halo=1)
855 do k=2,nz ;
do j=js,je ;
do i=is,ie
857 if (cs%ePBL_is_additive)
then
858 kd_add_here = kd_epbl(i,j,k)
859 visc%Kv_shear(i,j,k) = visc%Kv_shear(i,j,k) + kd_epbl(i,j,k)
861 kd_add_here = max(kd_epbl(i,j,k) - visc%Kd_shear(i,j,k), 0.0)
862 visc%Kv_shear(i,j,k) = max(visc%Kv_shear(i,j,k), kd_epbl(i,j,k))
865 if (cs%use_legacy_diabatic)
then
866 ent_int = kd_add_here * (gv%Z_to_H**2 * dt) / &
867 (0.5*(h(i,j,k-1) + h(i,j,k)) + h_neglect)
868 eb_s(i,j,k-1) = eb_s(i,j,k-1) + ent_int
869 ea_s(i,j,k) = ea_s(i,j,k) + ent_int
870 kd_int(i,j,k) = kd_int(i,j,k) + kd_add_here
873 kd_heat(i,j,k) = kd_heat(i,j,k) + kd_int(i,j,k)
874 kd_salt(i,j,k) = kd_salt(i,j,k) + kd_int(i,j,k)
876 kd_heat(i,j,k) = kd_heat(i,j,k) + kd_add_here
877 kd_salt(i,j,k) = kd_salt(i,j,k) + kd_add_here
880 enddo ;
enddo ;
enddo
883 call hchksum(ea_t,
"after ePBL ea_t",g%HI,haloshift=0, scale=gv%H_to_m)
884 call hchksum(eb_t,
"after ePBL eb_t",g%HI,haloshift=0, scale=gv%H_to_m)
885 call hchksum(ea_s,
"after ePBL ea_s",g%HI,haloshift=0, scale=gv%H_to_m)
886 call hchksum(eb_s,
"after ePBL eb_s",g%HI,haloshift=0, scale=gv%H_to_m)
887 call hchksum(kd_epbl,
"after ePBL Kd_ePBL", g%HI, haloshift=0, scale=us%Z2_T_to_m2_s)
891 call applyboundaryfluxesinout(cs%diabatic_aux_CSp, g, gv, us, dt, fluxes, cs%optics, &
893 cs%evap_CFL_limit, cs%minimum_forcing_depth)
900 if (cs%boundary_forcing_tendency_diag)
then
902 if (cs%id_boundary_forcing_h > 0)
call post_data(cs%id_boundary_forcing_h, h, cs%diag, alt_h = h_diag)
905 call diag_update_remap_grids(cs%diag)
908 call mom_forcing_chksum(
"after applyBoundaryFluxes ", fluxes, g, us, haloshift=0)
910 call mom_state_chksum(
"after applyBoundaryFluxes ", u, v, h, g, gv, us, haloshift=0)
912 if (showcalltree)
call calltree_waypoint(
"done with applyBoundaryFluxes (diabatic)")
913 if (cs%debugConservation)
call mom_state_stats(
'applyBoundaryFluxes', u, v, h, tv%T, tv%S, g, gv, us)
921 if (cs%use_legacy_diabatic)
then
925 hold(i,j,1) = h(i,j,1)
927 hold(i,j,nz) = h(i,j,nz)
929 if (h(i,j,1) <= 0.0) h(i,j,1) = gv%Angstrom_H
930 if (h(i,j,nz) <= 0.0) h(i,j,nz) = gv%Angstrom_H
932 do k=2,nz-1 ;
do i=is,ie
933 hold(i,j,k) = h(i,j,k)
936 if (h(i,j,k) <= 0.0) h(i,j,k) = gv%Angstrom_H
940 call diag_update_remap_grids(cs%diag)
944 call mom_state_chksum(
"after negative check ", u, v, h, g, gv, us, haloshift=0)
945 call mom_forcing_chksum(
"after negative check ", fluxes, g, us, haloshift=0)
949 if (cs%debugConservation)
call mom_state_stats(
'h=ea-eb', u, v, h, tv%T, tv%S, g, gv, us)
952 if (
associated(tv%T))
then
955 call hchksum(ea_t,
"before triDiagTS ea_t ",g%HI,haloshift=0, scale=gv%H_to_m)
956 call hchksum(eb_t,
"before triDiagTS eb_t ",g%HI,haloshift=0, scale=gv%H_to_m)
957 call hchksum(ea_s,
"before triDiagTS ea_s ",g%HI,haloshift=0, scale=gv%H_to_m)
958 call hchksum(eb_s,
"before triDiagTS eb_s ",g%HI,haloshift=0, scale=gv%H_to_m)
968 if (
associated(tv%S) .and.
associated(tv%salt_deficit)) &
969 call adjust_salt(h, tv, g, gv, cs%diabatic_aux_CSp)
971 if (cs%diabatic_diff_tendency_diag)
then
972 do k=1,nz ;
do j=js,je ;
do i=is,ie
973 temp_diag(i,j,k) = tv%T(i,j,k)
974 saln_diag(i,j,k) = tv%S(i,j,k)
975 enddo ;
enddo ;
enddo
978 if (cs%use_legacy_diabatic)
then
980 do k=1,nz ;
do j=js,je ;
do i=is,ie
981 ea_t(i,j,k) = ea_s(i,j,k) ; eb_t(i,j,k) = eb_s(i,j,k)
982 enddo ;
enddo ;
enddo
983 if (cs%tracer_tridiag)
then
987 call tridiagts(g, gv, is, ie, js, je, hold, ea_s, eb_s, tv%T, tv%S)
994 if (cs%diabatic_diff_tendency_diag)
then
996 if (cs%id_diabatic_diff_h > 0)
call post_data(cs%id_diabatic_diff_h, hold, cs%diag, alt_h = hold)
1001 do j=js,je ;
do i=is,ie
1002 ea_t(i,j,1) = 0.; ea_s(i,j,1) = 0.
1006 do k=2,nz ;
do j=js,je ;
do i=is,ie
1007 hval = 1.0 / (h_neglect + 0.5*(h(i,j,k-1) + h(i,j,k)))
1008 ea_t(i,j,k) = (gv%Z_to_H**2) * dt * hval * kd_heat(i,j,k)
1009 eb_t(i,j,k-1) = ea_t(i,j,k)
1010 ea_s(i,j,k) = (gv%Z_to_H**2) * dt * hval * kd_salt(i,j,k)
1011 eb_s(i,j,k-1) = ea_s(i,j,k)
1012 enddo ;
enddo ;
enddo
1013 do j=js,je ;
do i=is,ie
1014 eb_t(i,j,nz) = 0. ; eb_s(i,j,nz) = 0.
1016 if (showcalltree)
call calltree_waypoint(
"done setting ea_t,ea_s,eb_t,eb_s from Kd_heat" //&
1017 "and Kd_salt (diabatic)")
1024 if (cs%diabatic_diff_tendency_diag) &
1034 if (cs%debugConservation)
call mom_state_stats(
'triDiagTS', u, v, h, tv%T, tv%S, g, gv, us)
1037 call mom_state_chksum(
"after mixed layer ", u, v, h, g, gv, us, haloshift=0)
1043 if (cs%id_dudt_dia > 0 .or. cs%id_dvdt_dia > 0) &
1045 call pass_var(h, g%domain, to_west+to_south+omit_corners, halo=1)
1046 call diag_update_remap_grids(cs%diag)
1050 if ((cs%id_Tdif > 0) .or. (cs%id_Tadv > 0))
then
1051 do j=js,je ;
do i=is,ie
1052 tdif_flx(i,j,1) = 0.0 ; tdif_flx(i,j,nz+1) = 0.0
1053 tadv_flx(i,j,1) = 0.0 ; tadv_flx(i,j,nz+1) = 0.0
1056 do k=2,nz ;
do j=js,je ;
do i=is,ie
1057 tdif_flx(i,j,k) = (idt * 0.5*(ea_t(i,j,k) + eb_t(i,j,k-1))) * &
1058 (tv%T(i,j,k-1) - tv%T(i,j,k))
1059 tadv_flx(i,j,k) = (idt * (ea_t(i,j,k) - eb_t(i,j,k-1))) * &
1060 0.5*(tv%T(i,j,k-1) + tv%T(i,j,k))
1061 enddo ;
enddo ;
enddo
1063 if ((cs%id_Sdif > 0) .or. (cs%id_Sadv > 0))
then
1064 do j=js,je ;
do i=is,ie
1065 sdif_flx(i,j,1) = 0.0 ; sdif_flx(i,j,nz+1) = 0.0
1066 sadv_flx(i,j,1) = 0.0 ; sadv_flx(i,j,nz+1) = 0.0
1069 do k=2,nz ;
do j=js,je ;
do i=is,ie
1070 sdif_flx(i,j,k) = (idt * 0.5*(ea_s(i,j,k) + eb_s(i,j,k-1))) * &
1071 (tv%S(i,j,k-1) - tv%S(i,j,k))
1072 sadv_flx(i,j,k) = (idt * (ea_s(i,j,k) - eb_s(i,j,k-1))) * &
1073 0.5*(tv%S(i,j,k-1) + tv%S(i,j,k))
1074 enddo ;
enddo ;
enddo
1080 if (cs%mix_boundary_tracers)
then
1081 tr_ea_bbl = gv%Z_to_H * sqrt(dt*cs%Kd_BBL_tr)
1085 ebtr(i,j,nz) = eb_s(i,j,nz)
1087 in_boundary(i) = (g%mask2dT(i,j) > 0.0)
1089 do k=nz,2,-1 ;
do i=is,ie
1090 if (in_boundary(i))
then
1091 htot(i) = htot(i) + h(i,j,k)
1100 add_ent = ((dt * cs%Kd_min_tr) * gv%Z_to_H**2) * &
1101 ((h(i,j,k-1)+h(i,j,k)+h_neglect) / &
1102 (h(i,j,k-1)*h(i,j,k)+h_neglect2)) - &
1103 0.5*(ea_s(i,j,k) + eb_s(i,j,k-1))
1104 if (htot(i) < tr_ea_bbl)
then
1105 add_ent = max(0.0, add_ent, &
1106 (tr_ea_bbl - htot(i)) - min(ea_s(i,j,k),eb_s(i,j,k-1)))
1107 elseif (add_ent < 0.0)
then
1108 add_ent = 0.0 ; in_boundary(i) = .false.
1111 ebtr(i,j,k-1) = eb_s(i,j,k-1) + add_ent
1112 eatr(i,j,k) = ea_s(i,j,k) + add_ent
1114 ebtr(i,j,k-1) = eb_s(i,j,k-1) ; eatr(i,j,k) = ea_s(i,j,k)
1117 if (
associated(visc%Kd_extra_S))
then ;
if (visc%Kd_extra_S(i,j,k) > 0.0)
then
1118 if (cs%use_legacy_diabatic)
then
1119 add_ent = ((dt * visc%Kd_extra_S(i,j,k)) * gv%Z_to_H**2) / &
1120 (0.25 * ((h(i,j,k-1) + h(i,j,k)) + (hold(i,j,k-1) + hold(i,j,k))) + h_neglect)
1122 add_ent = ((dt * visc%Kd_extra_S(i,j,k)) * gv%Z_to_H**2) / &
1123 (0.5 * (h(i,j,k-1) + h(i,j,k)) + &
1126 ebtr(i,j,k-1) = ebtr(i,j,k-1) + add_ent
1127 eatr(i,j,k) = eatr(i,j,k) + add_ent
1130 do i=is,ie ; eatr(i,j,1) = ea_s(i,j,1) ;
enddo
1136 call call_tracer_column_fns(h_prebound, h, ea_s, eb_s, fluxes, hml, dt, g, gv, us, tv, &
1137 cs%optics, cs%tracer_flow_CSp, cs%debug, &
1138 evap_cfl_limit = cs%evap_CFL_limit, &
1139 minimum_forcing_depth=cs%minimum_forcing_depth)
1141 elseif (
associated(visc%Kd_extra_S))
then
1143 do j=js,je ;
do i=is,ie
1144 ebtr(i,j,nz) = eb_s(i,j,nz) ; eatr(i,j,1) = ea_s(i,j,1)
1147 do k=nz,2,-1 ;
do j=js,je ;
do i=is,ie
1148 if (visc%Kd_extra_S(i,j,k) > 0.0)
then
1149 if (cs%use_legacy_diabatic)
then
1150 add_ent = ((dt * visc%Kd_extra_S(i,j,k)) * gv%Z_to_H**2) / &
1151 (0.25 * ((h(i,j,k-1) + h(i,j,k)) + (hold(i,j,k-1) + hold(i,j,k))) + h_neglect)
1153 add_ent = ((dt * visc%Kd_extra_S(i,j,k)) * gv%Z_to_H**2) / &
1154 (0.5 * (h(i,j,k-1) + h(i,j,k)) + &
1160 ebtr(i,j,k-1) = eb_s(i,j,k-1) + add_ent
1161 eatr(i,j,k) = ea_s(i,j,k) + add_ent
1162 enddo ;
enddo ;
enddo
1165 call call_tracer_column_fns(h_prebound, h, eatr, ebtr, fluxes, hml, dt, g, gv, us, tv, &
1166 cs%optics, cs%tracer_flow_CSp, cs%debug,&
1167 evap_cfl_limit = cs%evap_CFL_limit, &
1168 minimum_forcing_depth=cs%minimum_forcing_depth)
1171 call call_tracer_column_fns(h_prebound, h, eatr, ebtr, fluxes, hml, dt, g, gv, us, tv, &
1172 cs%optics, cs%tracer_flow_CSp, cs%debug, &
1173 evap_cfl_limit = cs%evap_CFL_limit, &
1174 minimum_forcing_depth=cs%minimum_forcing_depth)
1180 if (cs%use_sponge)
then
1182 if (
associated(cs%ALE_sponge_CSp))
then
1193 call disable_averaging(cs%diag)
1195 call enable_averages(dt, time_end, cs%diag)
1197 if (cs%id_Kd_interface > 0)
call post_data(cs%id_Kd_interface, kd_int, cs%diag)
1198 if (cs%id_Kd_heat > 0)
call post_data(cs%id_Kd_heat, kd_heat, cs%diag)
1199 if (cs%id_Kd_salt > 0)
call post_data(cs%id_Kd_salt, kd_salt, cs%diag)
1200 if (cs%id_Kd_ePBL > 0)
call post_data(cs%id_Kd_ePBL, kd_epbl, cs%diag)
1202 if (cs%id_ea > 0)
call post_data(cs%id_ea, ea_s, cs%diag)
1203 if (cs%id_eb > 0)
call post_data(cs%id_eb, eb_s, cs%diag)
1204 if (cs%id_ea_t > 0)
call post_data(cs%id_ea_t, ea_t, cs%diag)
1205 if (cs%id_eb_t > 0)
call post_data(cs%id_eb_t, eb_t, cs%diag)
1206 if (cs%id_ea_s > 0)
call post_data(cs%id_ea_s, ea_s, cs%diag)
1207 if (cs%id_eb_s > 0)
call post_data(cs%id_eb_s, eb_s, cs%diag)
1209 if (cs%id_dudt_dia > 0)
call post_data(cs%id_dudt_dia, adp%du_dt_dia, cs%diag)
1210 if (cs%id_dvdt_dia > 0)
call post_data(cs%id_dvdt_dia, adp%dv_dt_dia, cs%diag)
1211 if (cs%id_wd > 0)
call post_data(cs%id_wd, cdp%diapyc_vel, cs%diag)
1213 if (cs%id_Tdif > 0)
call post_data(cs%id_Tdif, tdif_flx, cs%diag)
1214 if (cs%id_Tadv > 0)
call post_data(cs%id_Tadv, tadv_flx, cs%diag)
1215 if (cs%id_Sdif > 0)
call post_data(cs%id_Sdif, sdif_flx, cs%diag)
1216 if (cs%id_Sadv > 0)
call post_data(cs%id_Sadv, sadv_flx, cs%diag)
1218 call disable_averaging(cs%diag)
1227 subroutine diabatic_ale(u, v, h, tv, Hml, fluxes, visc, ADp, CDp, dt, Time_end, &
1228 G, GV, US, CS, Waves)
1232 real,
dimension(SZIB_(G),SZJ_(G),SZK_(G)),
intent(inout) :: u
1233 real,
dimension(SZI_(G),SZJB_(G),SZK_(G)),
intent(inout) :: v
1234 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)),
intent(inout) :: h
1237 real,
dimension(:,:),
pointer :: Hml
1238 type(
forcing),
intent(inout) :: fluxes
1245 real,
intent(in) :: dt
1246 type(time_type),
intent(in) :: Time_end
1251 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)) :: &
1271 real,
dimension(SZI_(G),SZJ_(G)) :: &
1274 real,
dimension(SZI_(G),SZJ_(G),G%ke) :: h_diag
1275 real,
dimension(SZI_(G),SZJ_(G),G%ke) :: temp_diag
1276 real,
dimension(SZI_(G),SZJ_(G),G%ke) :: saln_diag
1277 real,
dimension(SZI_(G),SZJ_(G)) :: tendency_2d
1281 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)) :: &
1286 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)+1),
target :: &
1296 logical :: in_boundary(SZI_(G))
1316 real :: htot(SZIB_(G))
1317 real :: b1(SZIB_(G)), d1(SZIB_(G))
1318 real :: c1(SZIB_(G),SZK_(G))
1324 logical :: showCallTree
1325 integer :: i, j, k, is, ie, js, je, Isq, Ieq, Jsq, Jeq, nz, nkmb, m, halo
1330 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
1331 isq = g%IscB ; ieq = g%IecB ; jsq = g%JscB ; jeq = g%JecB
1332 nkmb = gv%nk_rho_varies
1333 h_neglect = gv%H_subroundoff ; h_neglect2 = h_neglect*h_neglect
1334 kd_heat(:,:,:) = 0.0 ; kd_salt(:,:,:) = 0.0
1336 showcalltree = calltree_showquery()
1337 if (showcalltree)
call calltree_enter(
"diabatic_ALE(), MOM_diabatic_driver.F90")
1339 if (.not. (cs%useALEalgorithm))
call mom_error(fatal,
"MOM_diabatic_driver: "// &
1340 "The ALE algorithm must be enabled when using MOM_diabatic_driver.")
1343 call enable_averages(dt, time_end, cs%diag)
1345 if (cs%use_geothermal)
then
1346 halo = cs%halo_TS_diff
1348 do k=1,nz ;
do j=js-halo,je+halo ;
do i=is-halo,ie+halo
1349 h_orig(i,j,k) = h(i,j,k) ; eatr(i,j,k) = 0.0 ; ebtr(i,j,k) = 0.0
1350 enddo ;
enddo ;
enddo
1353 if (cs%use_geothermal)
then
1355 call geothermal(h, tv, dt, eatr, ebtr, g, gv, us, cs%geothermal_CSp, halo=cs%halo_TS_diff)
1358 if (cs%debugConservation)
call mom_state_stats(
'geothermal', u, v, h, tv%T, tv%S, g, gv, us)
1363 call diag_update_remap_grids(cs%diag)
1368 if (
associated(cs%optics)) &
1369 call set_pen_shortwave(cs%optics, fluxes, g, gv, cs%diabatic_aux_CSp, cs%opacity_CSp, cs%tracer_flow_CSp)
1371 if (cs%debug)
call mom_state_chksum(
"before find_uv_at_h", u, v, h, g, gv, us, haloshift=0)
1373 if (cs%use_kappa_shear .or. cs%use_CVMix_shear)
then
1374 if (cs%use_geothermal)
then
1375 call find_uv_at_h(u, v, h_orig, u_h, v_h, g, gv, us, eatr, ebtr)
1377 call hchksum(eatr,
"after find_uv_at_h eatr",g%HI, scale=gv%H_to_m)
1378 call hchksum(ebtr,
"after find_uv_at_h ebtr",g%HI, scale=gv%H_to_m)
1381 call find_uv_at_h(u, v, h, u_h, v_h, g, gv, us)
1389 call set_diffusivity(u, v, h, u_h, v_h, tv, fluxes, cs%optics, &
1390 visc, dt, g, gv, us,cs%set_diff_CSp, kd_lay, kd_int)
1392 if (showcalltree)
call calltree_waypoint(
"done with set_diffusivity (diabatic)")
1395 call mom_state_chksum(
"after set_diffusivity ", u, v, h, g, gv, us, haloshift=0)
1396 call mom_forcing_chksum(
"after set_diffusivity ", fluxes, g, us, haloshift=0)
1398 call hchksum(kd_int,
"after set_diffusivity Kd_Int", g%HI, haloshift=0, scale=us%Z2_T_to_m2_s)
1404 do k=1,nz+1 ;
do j=js,je ;
do i=is,ie
1405 kd_salt(i,j,k) = kd_int(i,j,k)
1406 kd_heat(i,j,k) = kd_int(i,j,k)
1407 enddo ;
enddo ;
enddo
1409 if (
associated(visc%Kd_extra_S))
then
1411 do k=1,nz+1 ;
do j=js,je ;
do i=is,ie
1412 kd_salt(i,j,k) = kd_salt(i,j,k) + visc%Kd_extra_S(i,j,k)
1413 enddo ;
enddo ;
enddo
1415 if (
associated(visc%Kd_extra_T))
then
1417 do k=1,nz+1 ;
do j=js,je ;
do i=is,ie
1418 kd_heat(i,j,k) = kd_heat(i,j,k) + visc%Kd_extra_T(i,j,k)
1419 enddo ;
enddo ;
enddo
1423 call hchksum(kd_heat,
"after set_diffusivity Kd_heat", g%HI, haloshift=0, scale=us%Z2_T_to_m2_s)
1424 call hchksum(kd_salt,
"after set_diffusivity Kd_salt", g%HI, haloshift=0, scale=us%Z2_T_to_m2_s)
1430 do k=1,nz+1 ;
do j=js,je ;
do i=is,ie
1431 visc%Kv_shear(i,j,k) = visc%Kv_shear(i,j,k) + visc%Kv_slow(i,j,k)
1432 enddo ;
enddo ;
enddo
1440 cs%KPP_buoy_flux, cs%KPP_temp_flux, cs%KPP_salt_flux)
1443 call kpp_compute_bld(cs%KPP_CSp, g, gv, us, h, tv%T, tv%S, u, v, tv%eqn_of_state, &
1444 fluxes%ustar, cs%KPP_buoy_flux, waves=waves)
1446 call kpp_calculate(cs%KPP_CSp, g, gv, us, h, fluxes%ustar, cs%KPP_buoy_flux, kd_heat, &
1447 kd_salt, visc%Kv_shear, cs%KPP_NLTheat, cs%KPP_NLTscalar, waves=waves)
1449 if (
associated(hml))
then
1451 call kpp_get_bld(cs%KPP_CSp, hml(:,:), g)
1453 call pass_var(hml, g%domain, halo=1)
1455 if (
associated(visc%MLD)) visc%MLD(:,:) = hml(:,:)
1462 call mom_forcing_chksum(
"after KPP", fluxes, g, us, haloshift=0)
1464 call hchksum(kd_heat,
"after KPP Kd_heat", g%HI, haloshift=0, scale=us%Z2_T_to_m2_s)
1465 call hchksum(kd_salt,
"after KPP Kd_salt", g%HI, haloshift=0, scale=us%Z2_T_to_m2_s)
1474 call hchksum(cs%KPP_temp_flux,
"before KPP_applyNLT netHeat", g%HI, haloshift=0, scale=gv%H_to_m)
1475 call hchksum(cs%KPP_salt_flux,
"before KPP_applyNLT netSalt", g%HI, haloshift=0, scale=gv%H_to_m)
1476 call hchksum(cs%KPP_NLTheat,
"before KPP_applyNLT NLTheat", g%HI, haloshift=0)
1477 call hchksum(cs%KPP_NLTscalar,
"before KPP_applyNLT NLTscalar", g%HI, haloshift=0)
1482 us%T_to_s*dt, tv%T, tv%C_p)
1486 if (showcalltree)
call calltree_waypoint(
"done with KPP_applyNonLocalTransport (diabatic)")
1487 if (cs%debugConservation)
call mom_state_stats(
'KPP_applyNonLocalTransport', u, v, h, tv%T, tv%S, g, gv, us)
1490 call mom_state_chksum(
"after KPP_applyNLT ", u, v, h, g, gv, us, haloshift=0)
1491 call mom_forcing_chksum(
"after KPP_applyNLT ", fluxes, g, us, haloshift=0)
1498 if (
associated(visc%Kd_extra_T) .and.
associated(visc%Kd_extra_S) .and.
associated(tv%T) .and. &
1499 (.not.cs%use_CVMix_ddiff))
then
1502 call differential_diffuse_t_s(h, tv, visc, dt, g, gv)
1505 if (showcalltree)
call calltree_waypoint(
"done with differential_diffuse_T_S (diabatic)")
1506 if (cs%debugConservation)
call mom_state_stats(
'differential_diffuse_T_S', u, v, h, tv%T, tv%S, g, gv, us)
1510 if (.not. cs%useKPP)
then
1512 do k=2,nz ;
do j=js,je ;
do i=is,ie
1513 kd_heat(i,j,k) = kd_heat(i,j,k) + visc%Kd_extra_T(i,j,k)
1514 kd_salt(i,j,k) = kd_salt(i,j,k) + visc%Kd_extra_S(i,j,k)
1515 enddo ;
enddo ;
enddo
1521 if (cs%use_CVMix_conv)
then
1525 do k=1,nz+1 ;
do j=js,je ;
do i=is,ie
1526 kd_heat(i,j,k) = kd_heat(i,j,k) + cs%CVMix_conv_csp%kd_conv(i,j,k)
1527 kd_salt(i,j,k) = kd_salt(i,j,k) + cs%CVMix_conv_csp%kd_conv(i,j,k)
1529 visc%Kv_shear(i,j,k) = visc%Kv_shear(i,j,k) + cs%CVMix_conv_csp%kv_conv(i,j,k)
1531 visc%Kv_slow(i,j,k) = visc%Kv_slow(i,j,k) + cs%CVMix_conv_csp%kv_conv(i,j,k)
1533 enddo ;
enddo ;
enddo
1537 if (cs%boundary_forcing_tendency_diag)
then
1538 do k=1,nz ;
do j=js,je ;
do i=is,ie
1539 h_diag(i,j,k) = h(i,j,k)
1540 temp_diag(i,j,k) = tv%T(i,j,k)
1541 saln_diag(i,j,k) = tv%S(i,j,k)
1542 enddo ;
enddo ;
enddo
1549 do k=1,nz ;
do j=js,je ;
do i=is,ie
1550 h_prebound(i,j,k) = h(i,j,k)
1551 enddo ;
enddo ;
enddo
1552 if (cs%use_energetic_PBL)
then
1554 skinbuoyflux(:,:) = 0.0
1555 call applyboundaryfluxesinout(cs%diabatic_aux_CSp, g, gv, us, dt, fluxes, cs%optics, &
1556 optics_nbands(cs%optics), h, tv, cs%aggregate_FW_forcing, cs%evap_CFL_limit, &
1557 cs%minimum_forcing_depth, ctke, dsv_dt, dsv_ds, skinbuoyflux=skinbuoyflux)
1560 call hchksum(ea_t,
"after applyBoundaryFluxes ea_t",g%HI,haloshift=0, scale=gv%H_to_m)
1561 call hchksum(eb_t,
"after applyBoundaryFluxes eb_t",g%HI,haloshift=0, scale=gv%H_to_m)
1562 call hchksum(ea_s,
"after applyBoundaryFluxes ea_s",g%HI,haloshift=0, scale=gv%H_to_m)
1563 call hchksum(eb_s,
"after applyBoundaryFluxes eb_s",g%HI,haloshift=0, scale=gv%H_to_m)
1564 call hchksum(ctke,
"after applyBoundaryFluxes cTKE",g%HI,haloshift=0, &
1565 scale=us%R_to_kg_m3*us%Z_to_m**3*us%s_to_T**2)
1566 call hchksum(dsv_dt,
"after applyBoundaryFluxes dSV_dT",g%HI,haloshift=0, scale=us%kg_m3_to_R)
1567 call hchksum(dsv_ds,
"after applyBoundaryFluxes dSV_dS",g%HI,haloshift=0, scale=us%kg_m3_to_R)
1570 call find_uv_at_h(u, v, h, u_h, v_h, g, gv, us)
1571 call energetic_pbl(h, u_h, v_h, tv, fluxes, dt, kd_epbl, g, gv, us, &
1572 cs%energetic_PBL_CSp, dsv_dt, dsv_ds, ctke, skinbuoyflux, waves=waves)
1574 if (
associated(hml))
then
1576 call pass_var(hml, g%domain, halo=1)
1578 if (
associated(visc%MLD)) visc%MLD(:,:) = hml(:,:)
1579 elseif (
associated(visc%MLD))
then
1581 call pass_var(visc%MLD, g%domain, halo=1)
1585 do k=2,nz ;
do j=js,je ;
do i=is,ie
1587 if (cs%ePBL_is_additive)
then
1588 kd_add_here = kd_epbl(i,j,k)
1589 visc%Kv_shear(i,j,k) = visc%Kv_shear(i,j,k) + kd_epbl(i,j,k)
1591 kd_add_here = max(kd_epbl(i,j,k) - visc%Kd_shear(i,j,k), 0.0)
1592 visc%Kv_shear(i,j,k) = max(visc%Kv_shear(i,j,k), kd_epbl(i,j,k))
1595 kd_heat(i,j,k) = kd_heat(i,j,k) + kd_add_here
1596 kd_salt(i,j,k) = kd_salt(i,j,k) + kd_add_here
1598 enddo ;
enddo ;
enddo
1601 call hchksum(ea_t,
"after ePBL ea_t",g%HI,haloshift=0, scale=gv%H_to_m)
1602 call hchksum(eb_t,
"after ePBL eb_t",g%HI,haloshift=0, scale=gv%H_to_m)
1603 call hchksum(ea_s,
"after ePBL ea_s",g%HI,haloshift=0, scale=gv%H_to_m)
1604 call hchksum(eb_s,
"after ePBL eb_s",g%HI,haloshift=0, scale=gv%H_to_m)
1605 call hchksum(kd_epbl,
"after ePBL Kd_ePBL", g%HI, haloshift=0, scale=us%Z2_T_to_m2_s)
1609 call applyboundaryfluxesinout(cs%diabatic_aux_CSp, g, gv, us, dt, fluxes, cs%optics, &
1611 cs%evap_CFL_limit, cs%minimum_forcing_depth)
1618 if (cs%boundary_forcing_tendency_diag)
then
1620 if (cs%id_boundary_forcing_h > 0)
call post_data(cs%id_boundary_forcing_h, h, cs%diag, alt_h = h_diag)
1623 call diag_update_remap_grids(cs%diag)
1626 call mom_forcing_chksum(
"after applyBoundaryFluxes ", fluxes, g, us, haloshift=0)
1628 call mom_state_chksum(
"after applyBoundaryFluxes ", u, v, h, g, gv, us, haloshift=0)
1630 if (showcalltree)
call calltree_waypoint(
"done with applyBoundaryFluxes (diabatic)")
1631 if (cs%debugConservation)
call mom_state_stats(
'applyBoundaryFluxes', u, v, h, tv%T, tv%S, g, gv, us)
1634 if (cs%debugConservation)
call mom_state_stats(
'h=ea-eb', u, v, h, tv%T, tv%S, g, gv, us)
1637 if (
associated(tv%T))
then
1640 call hchksum(ea_t,
"before triDiagTS ea_t ",g%HI,haloshift=0, scale=gv%H_to_m)
1641 call hchksum(eb_t,
"before triDiagTS eb_t ",g%HI,haloshift=0, scale=gv%H_to_m)
1642 call hchksum(ea_s,
"before triDiagTS ea_s ",g%HI,haloshift=0, scale=gv%H_to_m)
1643 call hchksum(eb_s,
"before triDiagTS eb_s ",g%HI,haloshift=0, scale=gv%H_to_m)
1653 if (
associated(tv%S) .and.
associated(tv%salt_deficit)) &
1654 call adjust_salt(h, tv, g, gv, cs%diabatic_aux_CSp)
1656 if (cs%diabatic_diff_tendency_diag)
then
1657 do k=1,nz ;
do j=js,je ;
do i=is,ie
1658 temp_diag(i,j,k) = tv%T(i,j,k)
1659 saln_diag(i,j,k) = tv%S(i,j,k)
1660 enddo ;
enddo ;
enddo
1666 do j=js,je ;
do i=is,ie
1667 ea_t(i,j,1) = 0.; ea_s(i,j,1) = 0.
1671 do k=2,nz ;
do j=js,je ;
do i=is,ie
1672 hval = 1.0 / (h_neglect + 0.5*(h(i,j,k-1) + h(i,j,k)))
1673 ea_t(i,j,k) = (gv%Z_to_H**2) * dt * hval * kd_heat(i,j,k)
1674 eb_t(i,j,k-1) = ea_t(i,j,k)
1675 ea_s(i,j,k) = (gv%Z_to_H**2) * dt * hval * kd_salt(i,j,k)
1676 eb_s(i,j,k-1) = ea_s(i,j,k)
1677 enddo ;
enddo ;
enddo
1678 do j=js,je ;
do i=is,ie
1679 eb_t(i,j,nz) = 0. ; eb_s(i,j,nz) = 0.
1681 if (showcalltree)
call calltree_waypoint(
"done setting ea_t,ea_s,eb_t,eb_s from Kd_heat" //&
1682 "and Kd_salt (diabatic)")
1688 ea_t(i,js-1,k) = 0.0 ; eb_t(i,js-1,k) = 0.0
1689 ea_s(i,js-1,k) = 0.0 ; eb_s(i,js-1,k) = 0.0
1690 ea_t(i,je+1,k) = 0.0 ; eb_t(i,je+1,k) = 0.0
1691 ea_s(i,je+1,k) = 0.0 ; eb_s(i,je+1,k) = 0.0
1694 ea_t(is-1,j,k) = 0.0 ; eb_t(is-1,j,k) = 0.0
1695 ea_s(is-1,j,k) = 0.0 ; eb_s(is-1,j,k) = 0.0
1696 ea_t(ie+1,j,k) = 0.0 ; eb_t(ie+1,j,k) = 0.0
1697 ea_s(ie+1,j,k) = 0.0 ; eb_s(ie+1,j,k) = 0.0
1707 if (cs%diabatic_diff_tendency_diag)
then
1716 if (cs%debugConservation)
call mom_state_stats(
'triDiagTS', u, v, h, tv%T, tv%S, g, gv, us)
1719 call mom_state_chksum(
"after mixed layer ", u, v, h, g, gv, us, haloshift=0)
1725 call diag_update_remap_grids(cs%diag)
1729 if ((cs%id_Tdif > 0) .or. (cs%id_Tadv > 0))
then
1730 do j=js,je ;
do i=is,ie
1731 tdif_flx(i,j,1) = 0.0 ; tdif_flx(i,j,nz+1) = 0.0
1732 tadv_flx(i,j,1) = 0.0 ; tadv_flx(i,j,nz+1) = 0.0
1735 do k=2,nz ;
do j=js,je ;
do i=is,ie
1736 tdif_flx(i,j,k) = (idt * 0.5*(ea_t(i,j,k) + eb_t(i,j,k-1))) * &
1737 (tv%T(i,j,k-1) - tv%T(i,j,k))
1738 tadv_flx(i,j,k) = (idt * (ea_t(i,j,k) - eb_t(i,j,k-1))) * &
1739 0.5*(tv%T(i,j,k-1) + tv%T(i,j,k))
1740 enddo ;
enddo ;
enddo
1742 if ((cs%id_Sdif > 0) .or. (cs%id_Sadv > 0))
then
1743 do j=js,je ;
do i=is,ie
1744 sdif_flx(i,j,1) = 0.0 ; sdif_flx(i,j,nz+1) = 0.0
1745 sadv_flx(i,j,1) = 0.0 ; sadv_flx(i,j,nz+1) = 0.0
1748 do k=2,nz ;
do j=js,je ;
do i=is,ie
1749 sdif_flx(i,j,k) = (idt * 0.5*(ea_s(i,j,k) + eb_s(i,j,k-1))) * &
1750 (tv%S(i,j,k-1) - tv%S(i,j,k))
1751 sadv_flx(i,j,k) = (idt * (ea_s(i,j,k) - eb_s(i,j,k-1))) * &
1752 0.5*(tv%S(i,j,k-1) + tv%S(i,j,k))
1753 enddo ;
enddo ;
enddo
1759 if (cs%mix_boundary_tracers)
then
1760 tr_ea_bbl = gv%Z_to_H * sqrt(dt*cs%Kd_BBL_tr)
1764 ebtr(i,j,nz) = eb_s(i,j,nz)
1766 in_boundary(i) = (g%mask2dT(i,j) > 0.0)
1768 do k=nz,2,-1 ;
do i=is,ie
1769 if (in_boundary(i))
then
1770 htot(i) = htot(i) + h(i,j,k)
1779 add_ent = ((dt * cs%Kd_min_tr) * gv%Z_to_H**2) * &
1780 ((h(i,j,k-1)+h(i,j,k)+h_neglect) / &
1781 (h(i,j,k-1)*h(i,j,k)+h_neglect2)) - &
1782 0.5*(ea_s(i,j,k) + eb_s(i,j,k-1))
1783 if (htot(i) < tr_ea_bbl)
then
1784 add_ent = max(0.0, add_ent, &
1785 (tr_ea_bbl - htot(i)) - min(ea_s(i,j,k),eb_s(i,j,k-1)))
1786 elseif (add_ent < 0.0)
then
1787 add_ent = 0.0 ; in_boundary(i) = .false.
1790 ebtr(i,j,k-1) = eb_s(i,j,k-1) + add_ent
1791 eatr(i,j,k) = ea_s(i,j,k) + add_ent
1793 ebtr(i,j,k-1) = eb_s(i,j,k-1) ; eatr(i,j,k) = ea_s(i,j,k)
1796 if (
associated(visc%Kd_extra_S))
then ;
if (visc%Kd_extra_S(i,j,k) > 0.0)
then
1797 add_ent = ((dt * visc%Kd_extra_S(i,j,k)) * gv%Z_to_H**2) / &
1798 (0.5 * (h(i,j,k-1) + h(i,j,k)) + &
1800 ebtr(i,j,k-1) = ebtr(i,j,k-1) + add_ent
1801 eatr(i,j,k) = eatr(i,j,k) + add_ent
1804 do i=is,ie ; eatr(i,j,1) = ea_s(i,j,1) ;
enddo
1810 call call_tracer_column_fns(h_prebound, h, ea_s, eb_s, fluxes, hml, dt, g, gv, us, tv, &
1811 cs%optics, cs%tracer_flow_CSp, cs%debug, &
1812 evap_cfl_limit = cs%evap_CFL_limit, &
1813 minimum_forcing_depth=cs%minimum_forcing_depth)
1815 elseif (
associated(visc%Kd_extra_S))
then
1817 do j=js,je ;
do i=is,ie
1818 ebtr(i,j,nz) = eb_s(i,j,nz) ; eatr(i,j,1) = ea_s(i,j,1)
1821 do k=nz,2,-1 ;
do j=js,je ;
do i=is,ie
1822 if (visc%Kd_extra_S(i,j,k) > 0.0)
then
1823 add_ent = ((dt * visc%Kd_extra_S(i,j,k)) * gv%Z_to_H**2) / &
1824 (0.5 * (h(i,j,k-1) + h(i,j,k)) + &
1829 ebtr(i,j,k-1) = eb_s(i,j,k-1) + add_ent
1830 eatr(i,j,k) = ea_s(i,j,k) + add_ent
1831 enddo ;
enddo ;
enddo
1834 call call_tracer_column_fns(h_prebound, h, eatr, ebtr, fluxes, hml, dt, g, gv, us, tv, &
1835 cs%optics, cs%tracer_flow_CSp, cs%debug,&
1836 evap_cfl_limit = cs%evap_CFL_limit, &
1837 minimum_forcing_depth=cs%minimum_forcing_depth)
1840 call call_tracer_column_fns(h_prebound, h, eatr, ebtr, fluxes, hml, dt, g, gv, us, tv, &
1841 cs%optics, cs%tracer_flow_CSp, cs%debug, &
1842 evap_cfl_limit = cs%evap_CFL_limit, &
1843 minimum_forcing_depth=cs%minimum_forcing_depth)
1849 if (cs%use_sponge)
then
1851 if (
associated(cs%ALE_sponge_CSp))
then
1863 if (g%symmetric)
then ; dir_flag = to_all+omit_corners
1864 else ; dir_flag = to_west+to_south+omit_corners ;
endif
1871 if (
associated(visc%Kv_slow)) &
1872 call pass_var(visc%Kv_slow, g%Domain, to_all+omit_corners, halo=1)
1875 call disable_averaging(cs%diag)
1878 call enable_averages(dt, time_end, cs%diag)
1880 if (cs%id_Kd_interface > 0)
call post_data(cs%id_Kd_interface, kd_int, cs%diag)
1881 if (cs%id_Kd_heat > 0)
call post_data(cs%id_Kd_heat, kd_heat, cs%diag)
1882 if (cs%id_Kd_salt > 0)
call post_data(cs%id_Kd_salt, kd_salt, cs%diag)
1883 if (cs%id_Kd_ePBL > 0)
call post_data(cs%id_Kd_ePBL, kd_epbl, cs%diag)
1885 if (cs%id_ea_t > 0)
call post_data(cs%id_ea_t, ea_t, cs%diag)
1886 if (cs%id_eb_t > 0)
call post_data(cs%id_eb_t, eb_t, cs%diag)
1887 if (cs%id_ea_s > 0)
call post_data(cs%id_ea_s, ea_s, cs%diag)
1888 if (cs%id_eb_s > 0)
call post_data(cs%id_eb_s, eb_s, cs%diag)
1890 if (cs%id_dudt_dia > 0)
call post_data(cs%id_dudt_dia, adp%du_dt_dia, cs%diag)
1891 if (cs%id_dvdt_dia > 0)
call post_data(cs%id_dvdt_dia, adp%dv_dt_dia, cs%diag)
1893 if (cs%id_Tdif > 0)
call post_data(cs%id_Tdif, tdif_flx, cs%diag)
1894 if (cs%id_Tadv > 0)
call post_data(cs%id_Tadv, tadv_flx, cs%diag)
1895 if (cs%id_Sdif > 0)
call post_data(cs%id_Sdif, sdif_flx, cs%diag)
1896 if (cs%id_Sadv > 0)
call post_data(cs%id_Sadv, sadv_flx, cs%diag)
1898 call disable_averaging(cs%diag)
1906 subroutine layered_diabatic(u, v, h, tv, Hml, fluxes, visc, ADp, CDp, dt, Time_end, &
1907 G, GV, US, CS, WAVES)
1911 real,
dimension(SZIB_(G),SZJ_(G),SZK_(G)),
intent(inout) :: u
1912 real,
dimension(SZI_(G),SZJB_(G),SZK_(G)),
intent(inout) :: v
1913 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)),
intent(inout) :: h
1916 real,
dimension(:,:),
pointer :: Hml
1917 type(
forcing),
intent(inout) :: fluxes
1924 real,
intent(in) :: dt
1925 type(time_type),
intent(in) :: Time_end
1929 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)) :: &
1944 real,
dimension(SZI_(G),SZJ_(G)) :: &
1947 real,
dimension(SZI_(G),SZJ_(G),G%ke) :: h_diag
1948 real,
dimension(SZI_(G),SZJ_(G),G%ke) :: temp_diag
1949 real,
dimension(SZI_(G),SZJ_(G),G%ke) :: saln_diag
1950 real,
dimension(SZI_(G),SZJ_(G)) :: tendency_2d
1954 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)),
target :: &
1960 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)+1),
target :: &
1971 real,
pointer,
dimension(:,:,:) :: &
1977 integer :: kb(SZI_(G),SZJ_(G))
1980 real :: p_ref_cv(SZI_(G))
1984 logical :: in_boundary(SZI_(G))
2004 real :: htot(SZIB_(G))
2005 real :: b1(SZIB_(G)), d1(SZIB_(G))
2006 real :: c1(SZIB_(G),SZK_(G))
2014 logical :: showCallTree
2015 integer :: i, j, k, is, ie, js, je, Isq, Ieq, Jsq, Jeq, nz, nkmb, m, halo
2020 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
2021 isq = g%IscB ; ieq = g%IecB ; jsq = g%JscB ; jeq = g%JecB
2022 nkmb = gv%nk_rho_varies
2023 h_neglect = gv%H_subroundoff ; h_neglect2 = h_neglect*h_neglect
2024 kd_heat(:,:,:) = 0.0 ; kd_salt(:,:,:) = 0.0
2027 showcalltree = calltree_showquery()
2028 if (showcalltree)
call calltree_enter(
"layered_diabatic(), MOM_diabatic_driver.F90")
2031 eaml => eatr ; ebml => ebtr
2034 call enable_averages(dt, time_end, cs%diag)
2036 if ((cs%ML_mix_first > 0.0) .or. cs%use_geothermal)
then
2037 halo = cs%halo_TS_diff
2039 do k=1,nz ;
do j=js-halo,je+halo ;
do i=is-halo,ie+halo
2040 h_orig(i,j,k) = h(i,j,k) ; eaml(i,j,k) = 0.0 ; ebml(i,j,k) = 0.0
2041 enddo ;
enddo ;
enddo
2044 if (cs%use_geothermal)
then
2046 call geothermal(h, tv, dt, eaml, ebml, g, gv, us, cs%geothermal_CSp, halo=cs%halo_TS_diff)
2049 if (cs%debugConservation)
call mom_state_stats(
'geothermal', u, v, h, tv%T, tv%S, g, gv, us)
2054 call diag_update_remap_grids(cs%diag)
2059 if (
associated(cs%optics)) &
2060 call set_pen_shortwave(cs%optics, fluxes, g, gv, cs%diabatic_aux_CSp, cs%opacity_CSp, cs%tracer_flow_CSp)
2062 if (cs%bulkmixedlayer)
then
2063 if (cs%debug)
call mom_forcing_chksum(
"Before mixedlayer", fluxes, g, us, haloshift=0)
2065 if (cs%ML_mix_first > 0.0)
then
2073 call find_uv_at_h(u, v, h, u_h, v_h, g, gv, us)
2076 if (cs%ML_mix_first < 1.0)
then
2078 call bulkmixedlayer(h, u_h, v_h, tv, fluxes, dt*cs%ML_mix_first, &
2079 eaml,ebml, g, gv, us, cs%bulkmixedlayer_CSp, cs%optics, &
2080 hml, cs%aggregate_FW_forcing, dt, last_call=.false.)
2081 if (cs%salt_reject_below_ML) &
2082 call insert_brine(h, tv, g, gv, us, fluxes, nkmb, cs%diabatic_aux_CSp, &
2083 dt*cs%ML_mix_first, cs%id_brine_lay)
2087 g, gv, us, cs%bulkmixedlayer_CSp, cs%optics, &
2088 hml, cs%aggregate_FW_forcing, dt, last_call=.true.)
2097 if (
associated(tv%S) .and.
associated(tv%salt_deficit)) &
2098 call adjust_salt(h, tv, g, gv, cs%diabatic_aux_CSp)
2101 call mom_state_chksum(
"After mixedlayer ", u, v, h, g, gv, us, haloshift=0)
2102 call mom_forcing_chksum(
"After mixedlayer", fluxes, g, us, haloshift=0)
2104 if (showcalltree)
call calltree_waypoint(
"done with 1st bulkmixedlayer (diabatic)")
2105 if (cs%debugConservation)
call mom_state_stats(
'1st bulkmixedlayer', u, v, h, tv%T, tv%S, g, gv, us)
2110 call mom_state_chksum(
"before find_uv_at_h", u, v, h, g, gv, us, haloshift=0)
2111 if (cs%use_kappa_shear .or. cs%use_CVMix_shear)
then
2112 if ((cs%ML_mix_first > 0.0) .or. cs%use_geothermal)
then
2113 call find_uv_at_h(u, v, h_orig, u_h, v_h, g, gv, us, eaml, ebml)
2115 call hchksum(eaml,
"after find_uv_at_h eaml",g%HI, scale=gv%H_to_m)
2116 call hchksum(ebml,
"after find_uv_at_h ebml",g%HI, scale=gv%H_to_m)
2119 call find_uv_at_h(u, v, h, u_h, v_h, g, gv, us)
2127 if ((cs%halo_TS_diff > 0) .and. (cs%ML_mix_first > 0.0))
then
2128 if (
associated(tv%T))
call pass_var(tv%T, g%Domain, halo=cs%halo_TS_diff, complete=.false.)
2129 if (
associated(tv%T))
call pass_var(tv%S, g%Domain, halo=cs%halo_TS_diff, complete=.false.)
2130 call pass_var(h, g%domain, halo=cs%halo_TS_diff, complete=.true.)
2132 call set_diffusivity(u, v, h, u_h, v_h, tv, fluxes, cs%optics, &
2133 visc, dt, g, gv, us, cs%set_diff_CSp, kd_lay, kd_int)
2135 if (showcalltree)
call calltree_waypoint(
"done with set_diffusivity (diabatic)")
2138 call mom_state_chksum(
"after set_diffusivity ", u, v, h, g, gv, us, haloshift=0)
2139 call mom_forcing_chksum(
"after set_diffusivity ", fluxes, g, us, haloshift=0)
2141 call hchksum(kd_lay,
"after set_diffusivity Kd_lay", g%HI, haloshift=0, scale=us%Z2_T_to_m2_s)
2142 call hchksum(kd_int,
"after set_diffusivity Kd_Int", g%HI, haloshift=0, scale=us%Z2_T_to_m2_s)
2154 cs%KPP_buoy_flux, cs%KPP_temp_flux, cs%KPP_salt_flux)
2160 do k=1,nz+1 ;
do j=js,je ;
do i=is,ie
2161 kd_salt(i,j,k) = kd_int(i,j,k)
2162 kd_heat(i,j,k) = kd_int(i,j,k)
2163 enddo ;
enddo ;
enddo
2165 if (
associated(visc%Kd_extra_S))
then
2167 do k=1,nz+1 ;
do j=js,je ;
do i=is,ie
2168 kd_salt(i,j,k) = kd_salt(i,j,k) + visc%Kd_extra_S(i,j,k)
2169 enddo ;
enddo ;
enddo
2171 if (
associated(visc%Kd_extra_T))
then
2173 do k=1,nz+1 ;
do j=js,je ;
do i=is,ie
2174 kd_heat(i,j,k) = kd_heat(i,j,k) + visc%Kd_extra_T(i,j,k)
2175 enddo ;
enddo ;
enddo
2178 call kpp_compute_bld(cs%KPP_CSp, g, gv, us, h, tv%T, tv%S, u, v, tv%eqn_of_state, &
2179 fluxes%ustar, cs%KPP_buoy_flux, waves=waves)
2181 call kpp_calculate(cs%KPP_CSp, g, gv, us, h, fluxes%ustar, cs%KPP_buoy_flux, kd_heat, &
2182 kd_salt, visc%Kv_shear, cs%KPP_NLTheat, cs%KPP_NLTscalar, waves=waves)
2184 if (
associated(hml))
then
2185 call kpp_get_bld(cs%KPP_CSp, hml(:,:), g)
2186 call pass_var(hml, g%domain, halo=1)
2188 if (
associated(visc%MLD)) visc%MLD(:,:) = hml(:,:)
2191 if (.not. cs%KPPisPassive)
then
2193 do k=1,nz+1 ;
do j=js,je ;
do i=is,ie
2194 kd_int(i,j,k) = min( kd_salt(i,j,k), kd_heat(i,j,k) )
2195 enddo ;
enddo ;
enddo
2196 if (
associated(visc%Kd_extra_S))
then
2198 do k=1,nz+1 ;
do j=js,je ;
do i=is,ie
2199 visc%Kd_extra_S(i,j,k) = (kd_salt(i,j,k) - kd_int(i,j,k))
2200 enddo ;
enddo ;
enddo
2202 if (
associated(visc%Kd_extra_T))
then
2204 do k=1,nz+1 ;
do j=js,je ;
do i=is,ie
2205 visc%Kd_extra_T(i,j,k) = (kd_heat(i,j,k) - kd_int(i,j,k))
2206 enddo ;
enddo ;
enddo
2214 call mom_forcing_chksum(
"after KPP", fluxes, g, us, haloshift=0)
2216 call hchksum(kd_lay,
"after KPP Kd_lay", g%HI, haloshift=0, scale=us%Z2_T_to_m2_s)
2217 call hchksum(kd_int,
"after KPP Kd_Int", g%HI, haloshift=0, scale=us%Z2_T_to_m2_s)
2223 if (cs%use_CVMix_conv)
then
2226 do k=1,nz+1 ;
do j=js,je ;
do i=is,ie
2227 kd_int(i,j,k) = kd_int(i,j,k) + cs%CVMix_conv_csp%kd_conv(i,j,k)
2228 visc%Kv_slow(i,j,k) = visc%Kv_slow(i,j,k) + cs%CVMix_conv_csp%kv_conv(i,j,k)
2229 enddo ;
enddo ;
enddo
2235 call hchksum(cs%KPP_temp_flux,
"before KPP_applyNLT netHeat", g%HI, haloshift=0, scale=gv%H_to_m)
2236 call hchksum(cs%KPP_salt_flux,
"before KPP_applyNLT netSalt", g%HI, haloshift=0, scale=gv%H_to_m)
2237 call hchksum(cs%KPP_NLTheat,
"before KPP_applyNLT NLTheat", g%HI, haloshift=0)
2238 call hchksum(cs%KPP_NLTscalar,
"before KPP_applyNLT NLTscalar", g%HI, haloshift=0)
2243 us%T_to_s*dt, tv%T, tv%C_p)
2247 if (showcalltree)
call calltree_waypoint(
"done with KPP_applyNonLocalTransport (diabatic)")
2248 if (cs%debugConservation)
call mom_state_stats(
'KPP_applyNonLocalTransport', u, v, h, tv%T, tv%S, g, gv, us)
2251 call mom_state_chksum(
"after KPP_applyNLT ", u, v, h, g, gv, us, haloshift=0)
2252 call mom_forcing_chksum(
"after KPP_applyNLT ", fluxes, g, us, haloshift=0)
2259 if (
associated(visc%Kd_extra_T) .and.
associated(visc%Kd_extra_S) .and.
associated(tv%T))
then
2262 call differential_diffuse_t_s(h, tv, visc, dt, g, gv)
2264 if (showcalltree)
call calltree_waypoint(
"done with differential_diffuse_T_S (diabatic)")
2265 if (cs%debugConservation)
call mom_state_stats(
'differential_diffuse_T_S', u, v, h, tv%T, tv%S, g, gv, us)
2269 if (.not. cs%useKPP)
then
2271 do k=2,nz ;
do j=js,je ;
do i=is,ie
2272 kd_heat(i,j,k) = kd_heat(i,j,k) + visc%Kd_extra_T(i,j,k)
2273 kd_salt(i,j,k) = kd_salt(i,j,k) + visc%Kd_extra_S(i,j,k)
2274 enddo ;
enddo ;
enddo
2287 call entrainment_diffusive(h, tv, fluxes, dt, g, gv, us, cs%entrain_diffusive_CSp, &
2288 ea, eb, kb, kd_lay=kd_lay, kd_int=kd_int)
2290 if (showcalltree)
call calltree_waypoint(
"done with Entrainment_diffusive (diabatic)")
2293 call mom_forcing_chksum(
"after calc_entrain ", fluxes, g, us, haloshift=0)
2295 call mom_state_chksum(
"after calc_entrain ", u, v, h, g, gv, us, haloshift=0)
2296 call hchksum(ea,
"after calc_entrain ea", g%HI, haloshift=0, scale=gv%H_to_m)
2297 call hchksum(eb,
"after calc_entrain eb", g%HI, haloshift=0, scale=gv%H_to_m)
2301 if (cs%boundary_forcing_tendency_diag)
then
2302 do k=1,nz ;
do j=js,je ;
do i=is,ie
2303 h_diag(i,j,k) = h(i,j,k)
2304 temp_diag(i,j,k) = tv%T(i,j,k)
2305 saln_diag(i,j,k) = tv%S(i,j,k)
2306 enddo ;
enddo ;
enddo
2320 hold(i,j,1) = h(i,j,1)
2321 h(i,j,1) = h(i,j,1) + (eb(i,j,1) - ea(i,j,2))
2322 hold(i,j,nz) = h(i,j,nz)
2323 h(i,j,nz) = h(i,j,nz) + (ea(i,j,nz) - eb(i,j,nz-1))
2324 if (h(i,j,1) <= 0.0)
then
2325 h(i,j,1) = gv%Angstrom_H
2327 if (h(i,j,nz) <= 0.0)
then
2328 h(i,j,nz) = gv%Angstrom_H
2331 do k=2,nz-1 ;
do i=is,ie
2332 hold(i,j,k) = h(i,j,k)
2333 h(i,j,k) = h(i,j,k) + ((ea(i,j,k) - eb(i,j,k-1)) + &
2334 (eb(i,j,k) - ea(i,j,k+1)))
2335 if (h(i,j,k) <= 0.0)
then
2336 h(i,j,k) = gv%Angstrom_H
2341 call diag_update_remap_grids(cs%diag)
2344 call mom_state_chksum(
"after negative check ", u, v, h, g, gv, us, haloshift=0)
2345 call mom_forcing_chksum(
"after negative check ", fluxes, g, us, haloshift=0)
2349 if (cs%debugConservation)
call mom_state_stats(
'h=ea-eb', u, v, h, tv%T, tv%S, g, gv, us)
2355 if (cs%bulkmixedlayer)
then
2357 if (
associated(tv%T))
then
2363 if (cs%massless_match_targets)
then
2367 h_tr = hold(i,j,1) + h_neglect
2368 b1(i) = 1.0 / (h_tr + eb(i,j,1))
2369 d1(i) = h_tr * b1(i)
2370 tv%T(i,j,1) = b1(i) * (h_tr*tv%T(i,j,1))
2371 tv%S(i,j,1) = b1(i) * (h_tr*tv%S(i,j,1))
2373 do k=2,nkmb ;
do i=is,ie
2374 c1(i,k) = eb(i,j,k-1) * b1(i)
2375 h_tr = hold(i,j,k) + h_neglect
2376 b_denom_1 = h_tr + d1(i)*ea(i,j,k)
2377 b1(i) = 1.0 / (b_denom_1 + eb(i,j,k))
2378 if (k<nkmb) d1(i) = b_denom_1 * b1(i)
2379 tv%T(i,j,k) = b1(i) * (h_tr*tv%T(i,j,k) + ea(i,j,k)*tv%T(i,j,k-1))
2380 tv%S(i,j,k) = b1(i) * (h_tr*tv%S(i,j,k) + ea(i,j,k)*tv%S(i,j,k-1))
2383 do k=nkmb+1,nz ;
do i=is,ie
2384 if (k == kb(i,j))
then
2385 c1(i,k) = eb(i,j,k-1) * b1(i)
2386 d1(i) = (((eb(i,j,nkmb)-eb(i,j,k-1)) + hold(i,j,nkmb) + h_neglect) + &
2387 d1(i)*ea(i,j,nkmb)) * b1(i)
2388 h_tr = hold(i,j,k) + h_neglect
2389 b_denom_1 = h_tr + d1(i)*ea(i,j,k)
2390 b1(i) = 1.0 / (b_denom_1 + eb(i,j,k))
2391 d1(i) = b_denom_1 * b1(i)
2392 tv%T(i,j,k) = b1(i) * (h_tr*tv%T(i,j,k) + ea(i,j,k)*tv%T(i,j,nkmb))
2393 tv%S(i,j,k) = b1(i) * (h_tr*tv%S(i,j,k) + ea(i,j,k)*tv%S(i,j,nkmb))
2394 elseif (k > kb(i,j))
then
2395 c1(i,k) = eb(i,j,k-1) * b1(i)
2396 h_tr = hold(i,j,k) + h_neglect
2397 b_denom_1 = h_tr + d1(i)*ea(i,j,k)
2398 b1(i) = 1.0 / (b_denom_1 + eb(i,j,k))
2399 d1(i) = b_denom_1 * b1(i)
2400 tv%T(i,j,k) = b1(i) * (h_tr*tv%T(i,j,k) + ea(i,j,k)*tv%T(i,j,k-1))
2401 tv%S(i,j,k) = b1(i) * (h_tr*tv%S(i,j,k) + ea(i,j,k)*tv%S(i,j,k-1))
2402 elseif (eb(i,j,k) < eb(i,j,k-1))
then
2407 tv%T(i,j,nkmb) = tv%T(i,j,nkmb) + b1(i) * (eb(i,j,k-1) - eb(i,j,k)) * tv%T(i,j,k)
2408 tv%S(i,j,nkmb) = tv%S(i,j,nkmb) + b1(i) * (eb(i,j,k-1) - eb(i,j,k)) * tv%S(i,j,k)
2412 do k=nz-1,nkmb,-1 ;
do i=is,ie
2413 if (k >= kb(i,j))
then
2414 tv%T(i,j,k) = tv%T(i,j,k) + c1(i,k+1)*tv%T(i,j,k+1)
2415 tv%S(i,j,k) = tv%S(i,j,k) + c1(i,k+1)*tv%S(i,j,k+1)
2418 do i=is,ie ;
if (kb(i,j) <= nz)
then
2419 tv%T(i,j,nkmb) = tv%T(i,j,nkmb) + c1(i,kb(i,j))*tv%T(i,j,kb(i,j))
2420 tv%S(i,j,nkmb) = tv%S(i,j,nkmb) + c1(i,kb(i,j))*tv%S(i,j,kb(i,j))
2422 do k=nkmb-1,1,-1 ;
do i=is,ie
2423 tv%T(i,j,k) = tv%T(i,j,k) + c1(i,k+1)*tv%T(i,j,k+1)
2424 tv%S(i,j,k) = tv%S(i,j,k) + c1(i,k+1)*tv%S(i,j,k+1)
2431 if (cs%tracer_tridiag)
then
2435 call tridiagts(g, gv, is, ie, js, je, hold, ea, eb, tv%T, tv%S)
2441 if (cs%debugConservation)
call mom_state_stats(
'BML tridiag', u, v, h, tv%T, tv%S, g, gv, us)
2443 if ((cs%ML_mix_first > 0.0) .or. cs%use_geothermal)
then
2447 do k=1,nz ;
do j=js,je ;
do i=is,ie
2448 hold(i,j,k) = h_orig(i,j,k)
2449 ea(i,j,k) = ea(i,j,k) + eaml(i,j,k)
2450 eb(i,j,k) = eb(i,j,k) + ebml(i,j,k)
2451 enddo ;
enddo ;
enddo
2453 call hchksum(ea,
"after ea = ea + eaml",g%HI,haloshift=0, scale=gv%H_to_m)
2454 call hchksum(eb,
"after eb = eb + ebml",g%HI,haloshift=0, scale=gv%H_to_m)
2458 if (cs%ML_mix_first < 1.0)
then
2467 call find_uv_at_h(u, v, hold, u_h, v_h, g, gv, us, ea, eb)
2468 if (cs%debug)
call mom_state_chksum(
"find_uv_at_h1 ", u, v, h, g, gv, us, haloshift=0)
2470 dt_mix = min(dt, dt*(1.0 - cs%ML_mix_first))
2474 g, gv, us, cs%bulkmixedlayer_CSp, cs%optics, &
2475 hml, cs%aggregate_FW_forcing, dt, last_call=.true.)
2477 if (cs%salt_reject_below_ML) &
2478 call insert_brine(h, tv, g, gv, us, fluxes, nkmb, cs%diabatic_aux_CSp, dt_mix, &
2487 if (
associated(tv%S) .and.
associated(tv%salt_deficit)) &
2488 call adjust_salt(h, tv, g, gv, cs%diabatic_aux_CSp)
2491 if (showcalltree)
call calltree_waypoint(
"done with 2nd bulkmixedlayer (diabatic)")
2492 if (cs%debugConservation)
call mom_state_stats(
'2nd bulkmixedlayer', u, v, h, tv%T, tv%S, g, gv, us)
2498 if (
associated(tv%T))
then
2501 call hchksum(ea,
"before triDiagTS ea ",g%HI,haloshift=0, scale=gv%H_to_m)
2502 call hchksum(eb,
"before triDiagTS eb ",g%HI,haloshift=0, scale=gv%H_to_m)
2512 if (
associated(tv%S) .and.
associated(tv%salt_deficit)) &
2513 call adjust_salt(h, tv, g, gv, cs%diabatic_aux_CSp)
2515 if (cs%diabatic_diff_tendency_diag)
then
2516 do k=1,nz ;
do j=js,je ;
do i=is,ie
2517 temp_diag(i,j,k) = tv%T(i,j,k)
2518 saln_diag(i,j,k) = tv%S(i,j,k)
2519 enddo ;
enddo ;
enddo
2523 if (cs%tracer_tridiag)
then
2527 call tridiagts(g, gv, is, ie, js, je, hold, ea, eb, tv%T, tv%S)
2533 if (cs%diabatic_diff_tendency_diag)
then
2535 if (cs%id_diabatic_diff_h > 0)
call post_data(cs%id_diabatic_diff_h, hold, cs%diag, alt_h=hold)
2542 if (cs%debugConservation)
call mom_state_stats(
'triDiagTS', u, v, h, tv%T, tv%S, g, gv, us)
2547 call mom_state_chksum(
"after mixed layer ", u, v, h, g, gv, us, haloshift=0)
2549 call hchksum(ea,
"after mixed layer ea", g%HI, scale=gv%H_to_m)
2550 call hchksum(eb,
"after mixed layer eb", g%HI, scale=gv%H_to_m)
2556 if (showcalltree)
call calltree_waypoint(
"done with regularize_layers (diabatic)")
2557 if (cs%debugConservation)
call mom_state_stats(
'regularize_layers', u, v, h, tv%T, tv%S, g, gv, us)
2561 if (cs%id_dudt_dia > 0 .or. cs%id_dvdt_dia > 0) &
2563 call pass_var(h, g%domain, to_west+to_south+omit_corners, halo=1)
2564 call diag_update_remap_grids(cs%diag)
2568 if ((cs%id_Tdif > 0) .or. (cs%id_Tadv > 0))
then
2569 do j=js,je ;
do i=is,ie
2570 tdif_flx(i,j,1) = 0.0 ; tdif_flx(i,j,nz+1) = 0.0
2571 tadv_flx(i,j,1) = 0.0 ; tadv_flx(i,j,nz+1) = 0.0
2574 do k=2,nz ;
do j=js,je ;
do i=is,ie
2575 tdif_flx(i,j,k) = (idt * 0.5*(ea(i,j,k) + eb(i,j,k-1))) * &
2576 (tv%T(i,j,k-1) - tv%T(i,j,k))
2577 tadv_flx(i,j,k) = (idt * (ea(i,j,k) - eb(i,j,k-1))) * &
2578 0.5*(tv%T(i,j,k-1) + tv%T(i,j,k))
2579 enddo ;
enddo ;
enddo
2581 if ((cs%id_Sdif > 0) .or. (cs%id_Sadv > 0))
then
2582 do j=js,je ;
do i=is,ie
2583 sdif_flx(i,j,1) = 0.0 ; sdif_flx(i,j,nz+1) = 0.0
2584 sadv_flx(i,j,1) = 0.0 ; sadv_flx(i,j,nz+1) = 0.0
2587 do k=2,nz ;
do j=js,je ;
do i=is,ie
2588 sdif_flx(i,j,k) = (idt * 0.5*(ea(i,j,k) + eb(i,j,k-1))) * &
2589 (tv%S(i,j,k-1) - tv%S(i,j,k))
2590 sadv_flx(i,j,k) = (idt * (ea(i,j,k) - eb(i,j,k-1))) * &
2591 0.5*(tv%S(i,j,k-1) + tv%S(i,j,k))
2592 enddo ;
enddo ;
enddo
2597 if (cs%mix_boundary_tracers)
then
2598 tr_ea_bbl = gv%Z_to_H * sqrt(dt*cs%Kd_BBL_tr)
2602 ebtr(i,j,nz) = eb(i,j,nz)
2604 in_boundary(i) = (g%mask2dT(i,j) > 0.0)
2606 do k=nz,2,-1 ;
do i=is,ie
2607 if (in_boundary(i))
then
2608 htot(i) = htot(i) + h(i,j,k)
2617 add_ent = ((dt * cs%Kd_min_tr) * gv%Z_to_H**2) * &
2618 ((h(i,j,k-1)+h(i,j,k)+h_neglect) / &
2619 (h(i,j,k-1)*h(i,j,k)+h_neglect2)) - &
2620 0.5*(ea(i,j,k) + eb(i,j,k-1))
2621 if (htot(i) < tr_ea_bbl)
then
2622 add_ent = max(0.0, add_ent, &
2623 (tr_ea_bbl - htot(i)) - min(ea(i,j,k),eb(i,j,k-1)))
2624 elseif (add_ent < 0.0)
then
2625 add_ent = 0.0 ; in_boundary(i) = .false.
2628 ebtr(i,j,k-1) = eb(i,j,k-1) + add_ent
2629 eatr(i,j,k) = ea(i,j,k) + add_ent
2631 ebtr(i,j,k-1) = eb(i,j,k-1) ; eatr(i,j,k) = ea(i,j,k)
2633 if (
associated(visc%Kd_extra_S))
then ;
if (visc%Kd_extra_S(i,j,k) > 0.0)
then
2634 add_ent = ((dt * visc%Kd_extra_S(i,j,k)) * gv%Z_to_H**2) / &
2635 (0.25 * ((h(i,j,k-1) + h(i,j,k)) + (hold(i,j,k-1) + hold(i,j,k))) + &
2637 ebtr(i,j,k-1) = ebtr(i,j,k-1) + add_ent
2638 eatr(i,j,k) = eatr(i,j,k) + add_ent
2641 do i=is,ie ; eatr(i,j,1) = ea(i,j,1) ;
enddo
2645 call call_tracer_column_fns(hold, h, eatr, ebtr, fluxes, hml, dt, g, gv, us, tv, &
2646 cs%optics, cs%tracer_flow_CSp, cs%debug)
2648 elseif (
associated(visc%Kd_extra_S))
then
2650 do j=js,je ;
do i=is,ie
2651 ebtr(i,j,nz) = eb(i,j,nz) ; eatr(i,j,1) = ea(i,j,1)
2654 do k=nz,2,-1 ;
do j=js,je ;
do i=is,ie
2655 if (visc%Kd_extra_S(i,j,k) > 0.0)
then
2656 add_ent = ((dt * visc%Kd_extra_S(i,j,k)) * gv%Z_to_H**2) / &
2657 (0.25 * ((h(i,j,k-1) + h(i,j,k)) + (hold(i,j,k-1) + hold(i,j,k))) + &
2662 ebtr(i,j,k-1) = eb(i,j,k-1) + add_ent
2663 eatr(i,j,k) = ea(i,j,k) + add_ent
2664 enddo ;
enddo ;
enddo
2666 call call_tracer_column_fns(hold, h, eatr, ebtr, fluxes, hml, dt, g, gv, us, tv, &
2667 cs%optics, cs%tracer_flow_CSp, cs%debug)
2670 call call_tracer_column_fns(hold, h, ea, eb, fluxes, hml, dt, g, gv, us, tv, &
2671 cs%optics, cs%tracer_flow_CSp, cs%debug)
2678 if (cs%use_sponge)
then
2681 if (cs%bulkmixedlayer .and.
associated(tv%eqn_of_state))
then
2682 do i=is,ie ; p_ref_cv(i) = tv%P_Ref ;
enddo
2686 is, ie-is+1, tv%eqn_of_state, scale=us%kg_m3_to_R)
2688 call apply_sponge(h, dt, g, gv, us, ea, eb, cs%sponge_CSp, rcv_ml)
2690 call apply_sponge(h, dt, g, gv, us, ea, eb, cs%sponge_CSp)
2700 if (
associated(cdp%diapyc_vel))
then
2703 do k=2,nz ;
do i=is,ie
2704 cdp%diapyc_vel(i,j,k) = us%s_to_T*idt * (ea(i,j,k) - eb(i,j,k-1))
2707 cdp%diapyc_vel(i,j,1) = 0.0
2708 cdp%diapyc_vel(i,j,nz+1) = 0.0
2716 if (cs%bulkmixedlayer)
then
2718 call hchksum(ea,
"before net flux rearrangement ea",g%HI, scale=gv%H_to_m)
2719 call hchksum(eb,
"before net flux rearrangement eb",g%HI, scale=gv%H_to_m)
2723 do k=2,gv%nkml ;
do i=is,ie
2724 net_ent = ea(i,j,k) - eb(i,j,k-1)
2725 ea(i,j,k) = max(net_ent, 0.0)
2726 eb(i,j,k-1) = max(-net_ent, 0.0)
2730 call hchksum(ea,
"after net flux rearrangement ea",g%HI, scale=gv%H_to_m)
2731 call hchksum(eb,
"after net flux rearrangement eb",g%HI, scale=gv%H_to_m)
2739 hold(i,js-1,k) = gv%Angstrom_H ; ea(i,js-1,k) = 0.0 ; eb(i,js-1,k) = 0.0
2740 hold(i,je+1,k) = gv%Angstrom_H ; ea(i,je+1,k) = 0.0 ; eb(i,je+1,k) = 0.0
2743 hold(is-1,j,k) = gv%Angstrom_H ; ea(is-1,j,k) = 0.0 ; eb(is-1,j,k) = 0.0
2744 hold(ie+1,j,k) = gv%Angstrom_H ; ea(ie+1,j,k) = 0.0 ; eb(ie+1,j,k) = 0.0
2749 if (g%symmetric)
then ; dir_flag = to_all+omit_corners
2750 else ; dir_flag = to_west+to_south+omit_corners ;
endif
2761 call mom_state_chksum(
"before u/v tridiag ", u, v, h, g, gv, us, haloshift=0)
2762 call hchksum(ea,
"before u/v tridiag ea",g%HI, scale=gv%H_to_m)
2763 call hchksum(eb,
"before u/v tridiag eb",g%HI, scale=gv%H_to_m)
2764 call hchksum(hold,
"before u/v tridiag hold",g%HI, scale=gv%H_to_m)
2767 idt_accel = 1.0 / dt
2771 if (
associated(adp%du_dt_dia)) adp%du_dt_dia(i,j,1) = u(i,j,1)
2772 hval = (hold(i,j,1) + hold(i+1,j,1)) + (ea(i,j,1) + ea(i+1,j,1)) + h_neglect
2773 b1(i) = 1.0 / (hval + (eb(i,j,1) + eb(i+1,j,1)))
2774 d1(i) = hval * b1(i)
2775 u(i,j,1) = b1(i) * (hval * u(i,j,1))
2777 do k=2,nz ;
do i=isq,ieq
2778 if (
associated(adp%du_dt_dia)) adp%du_dt_dia(i,j,k) = u(i,j,k)
2779 c1(i,k) = (eb(i,j,k-1)+eb(i+1,j,k-1)) * b1(i)
2780 eaval = ea(i,j,k) + ea(i+1,j,k)
2781 hval = hold(i,j,k) + hold(i+1,j,k) + h_neglect
2782 b1(i) = 1.0 / ((eb(i,j,k) + eb(i+1,j,k)) + (hval + d1(i)*eaval))
2783 d1(i) = (hval + d1(i)*eaval) * b1(i)
2784 u(i,j,k) = (hval*u(i,j,k) + eaval*u(i,j,k-1))*b1(i)
2786 do k=nz-1,1,-1 ;
do i=isq,ieq
2787 u(i,j,k) = u(i,j,k) + c1(i,k+1)*u(i,j,k+1)
2788 if (
associated(adp%du_dt_dia)) &
2789 adp%du_dt_dia(i,j,k) = (u(i,j,k) - adp%du_dt_dia(i,j,k)) * idt_accel
2791 if (
associated(adp%du_dt_dia))
then
2793 adp%du_dt_dia(i,j,nz) = (u(i,j,nz)-adp%du_dt_dia(i,j,nz)) * idt_accel
2798 call mom_state_chksum(
"aft 1st loop tridiag ", u, v, h, g, gv, us, haloshift=0)
2803 if (
associated(adp%dv_dt_dia)) adp%dv_dt_dia(i,j,1) = v(i,j,1)
2804 hval = (hold(i,j,1) + hold(i,j+1,1)) + (ea(i,j,1) + ea(i,j+1,1)) + h_neglect
2805 b1(i) = 1.0 / (hval + (eb(i,j,1) + eb(i,j+1,1)))
2806 d1(i) = hval * b1(i)
2807 v(i,j,1) = b1(i) * (hval * v(i,j,1))
2809 do k=2,nz ;
do i=is,ie
2810 if (
associated(adp%dv_dt_dia)) adp%dv_dt_dia(i,j,k) = v(i,j,k)
2811 c1(i,k) = (eb(i,j,k-1)+eb(i,j+1,k-1)) * b1(i)
2812 eaval = ea(i,j,k) + ea(i,j+1,k)
2813 hval = hold(i,j,k) + hold(i,j+1,k) + h_neglect
2814 b1(i) = 1.0 / ((eb(i,j,k) + eb(i,j+1,k)) + (hval + d1(i)*eaval))
2815 d1(i) = (hval + d1(i)*eaval) * b1(i)
2816 v(i,j,k) = (hval*v(i,j,k) + eaval*v(i,j,k-1))*b1(i)
2818 do k=nz-1,1,-1 ;
do i=is,ie
2819 v(i,j,k) = v(i,j,k) + c1(i,k+1)*v(i,j,k+1)
2820 if (
associated(adp%dv_dt_dia)) &
2821 adp%dv_dt_dia(i,j,k) = (v(i,j,k) - adp%dv_dt_dia(i,j,k)) * idt_accel
2823 if (
associated(adp%dv_dt_dia))
then
2825 adp%dv_dt_dia(i,j,nz) = (v(i,j,nz)-adp%dv_dt_dia(i,j,nz)) * idt_accel
2831 call mom_state_chksum(
"after u/v tridiag ", u, v, h, g, gv, us, haloshift=0)
2834 call disable_averaging(cs%diag)
2836 call enable_averages(dt, time_end, cs%diag)
2838 if (cs%id_Kd_interface > 0)
call post_data(cs%id_Kd_interface, kd_int, cs%diag)
2839 if (cs%id_Kd_heat > 0)
call post_data(cs%id_Kd_heat, kd_heat, cs%diag)
2840 if (cs%id_Kd_salt > 0)
call post_data(cs%id_Kd_salt, kd_salt, cs%diag)
2841 if (cs%id_Kd_ePBL > 0)
call post_data(cs%id_Kd_ePBL, kd_epbl, cs%diag)
2843 if (cs%id_ea > 0)
call post_data(cs%id_ea, ea, cs%diag)
2844 if (cs%id_eb > 0)
call post_data(cs%id_eb, eb, cs%diag)
2846 if (cs%id_dudt_dia > 0)
call post_data(cs%id_dudt_dia, adp%du_dt_dia, cs%diag)
2847 if (cs%id_dvdt_dia > 0)
call post_data(cs%id_dvdt_dia, adp%dv_dt_dia, cs%diag)
2848 if (cs%id_wd > 0)
call post_data(cs%id_wd, cdp%diapyc_vel, cs%diag)
2850 if (cs%id_Tdif > 0)
call post_data(cs%id_Tdif, tdif_flx, cs%diag)
2851 if (cs%id_Tadv > 0)
call post_data(cs%id_Tadv, tadv_flx, cs%diag)
2852 if (cs%id_Sdif > 0)
call post_data(cs%id_Sdif, sdif_flx, cs%diag)
2853 if (cs%id_Sadv > 0)
call post_data(cs%id_Sadv, sadv_flx, cs%diag)
2855 call disable_averaging(cs%diag)
2864 minimum_forcing_depth, KPP_CSp, energetic_PBL_CSp, diabatic_aux_CSp)
2867 type(
opacity_cs),
optional,
pointer :: opacity_csp
2868 type(
optics_type),
optional,
pointer :: optics_csp
2869 type(
kpp_cs),
optional,
pointer :: kpp_csp
2871 real,
optional,
intent( out) :: evap_cfl_limit
2873 real,
optional,
intent( out) :: minimum_forcing_depth
2879 if (
present(opacity_csp)) opacity_csp => cs%opacity_CSp
2880 if (
present(optics_csp)) optics_csp => cs%optics
2881 if (
present(kpp_csp)) kpp_csp => cs%KPP_CSp
2882 if (
present(energetic_pbl_csp)) energetic_pbl_csp => cs%energetic_PBL_CSp
2885 if (
present(evap_cfl_limit)) evap_cfl_limit = cs%evap_CFL_limit
2886 if (
present(minimum_forcing_depth)) minimum_forcing_depth = cs%minimum_forcing_depth
2891 subroutine adiabatic(h, tv, fluxes, dt, G, GV, US, CS)
2893 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)), &
2896 type(
forcing),
intent(inout) :: fluxes
2897 real,
intent(in) :: dt
2902 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)) :: zeros
2906 call call_tracer_column_fns(h, h, zeros, zeros, fluxes, zeros(:,:,1), dt, g, gv, us, tv, &
2907 cs%optics, cs%tracer_flow_CSp, cs%debug)
2919 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)),
intent(in) :: h
2920 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)),
intent(in) :: temp_old
2921 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)),
intent(in) :: saln_old
2922 real,
intent(in) :: dt
2926 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)) :: work_3d
2927 real,
dimension(SZI_(G),SZJ_(G)) :: work_2d
2929 real :: ppt2mks = 0.001
2930 integer :: i, j, k, is, ie, js, je, nz
2931 logical :: do_saln_tend
2933 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
2934 idt = 0.0 ;
if (dt > 0.0) idt = 1. / dt
2935 work_3d(:,:,:) = 0.0
2940 do k=1,nz ;
do j=js,je ;
do i=is,ie
2941 work_3d(i,j,k) = (tv%T(i,j,k)-temp_old(i,j,k))*idt
2942 enddo ;
enddo ;
enddo
2943 if (cs%id_diabatic_diff_temp_tend > 0)
then
2944 call post_data(cs%id_diabatic_diff_temp_tend, work_3d, cs%diag, alt_h=h)
2948 if (cs%id_diabatic_diff_heat_tend > 0 .or. cs%id_diabatic_diff_heat_tend_2d > 0)
then
2949 do k=1,nz ;
do j=js,je ;
do i=is,ie
2950 work_3d(i,j,k) = h(i,j,k) * gv%H_to_kg_m2 * tv%C_p * work_3d(i,j,k)
2951 enddo ;
enddo ;
enddo
2952 if (cs%id_diabatic_diff_heat_tend > 0)
then
2953 call post_data(cs%id_diabatic_diff_heat_tend, work_3d, cs%diag, alt_h=h)
2955 if (cs%id_diabatic_diff_heat_tend_2d > 0)
then
2956 do j=js,je ;
do i=is,ie
2959 work_2d(i,j) = work_2d(i,j) + work_3d(i,j,k)
2962 call post_data(cs%id_diabatic_diff_heat_tend_2d, work_2d, cs%diag)
2967 do_saln_tend = cs%id_diabatic_diff_saln_tend > 0 &
2968 .or. cs%id_diabatic_diff_salt_tend > 0 &
2969 .or. cs%id_diabatic_diff_salt_tend_2d > 0
2971 if (do_saln_tend)
then
2972 do k=1,nz ;
do j=js,je ;
do i=is,ie
2973 work_3d(i,j,k) = (tv%S(i,j,k) - saln_old(i,j,k)) * idt
2974 enddo ;
enddo ;
enddo
2976 if (cs%id_diabatic_diff_saln_tend > 0) &
2977 call post_data(cs%id_diabatic_diff_saln_tend, work_3d, cs%diag, alt_h=h)
2980 if (cs%id_diabatic_diff_salt_tend > 0 .or. cs%id_diabatic_diff_salt_tend_2d > 0)
then
2981 do k=1,nz ;
do j=js,je ;
do i=is,ie
2982 work_3d(i,j,k) = h(i,j,k) * gv%H_to_kg_m2 * ppt2mks * work_3d(i,j,k)
2983 enddo ;
enddo ;
enddo
2984 if (cs%id_diabatic_diff_salt_tend > 0)
then
2985 call post_data(cs%id_diabatic_diff_salt_tend, work_3d, cs%diag, alt_h=h)
2987 if (cs%id_diabatic_diff_salt_tend_2d > 0)
then
2988 do j=js,je ;
do i=is,ie
2991 work_2d(i,j) = work_2d(i,j) + work_3d(i,j,k)
2994 call post_data(cs%id_diabatic_diff_salt_tend_2d, work_2d, cs%diag)
3011 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)), &
3013 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)), &
3014 intent(in) :: temp_old
3015 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)), &
3016 intent(in) :: saln_old
3017 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)), &
3019 real,
intent(in) :: dt
3023 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)) :: work_3d
3024 real,
dimension(SZI_(G),SZJ_(G)) :: work_2d
3026 real :: ppt2mks = 0.001
3027 integer :: i, j, k, is, ie, js, je, nz
3029 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
3030 idt = 0.0 ;
if (dt > 0.0) idt = 1. / dt
3031 work_3d(:,:,:) = 0.0
3035 if (cs%id_boundary_forcing_h_tendency > 0)
then
3036 do k=1,nz ;
do j=js,je ;
do i=is,ie
3037 work_3d(i,j,k) = (h(i,j,k) - h_old(i,j,k))*idt
3038 enddo ;
enddo ;
enddo
3039 call post_data(cs%id_boundary_forcing_h_tendency, work_3d, cs%diag, alt_h=h_old)
3043 if (cs%id_boundary_forcing_temp_tend > 0)
then
3044 do k=1,nz ;
do j=js,je ;
do i=is,ie
3045 work_3d(i,j,k) = (tv%T(i,j,k)-temp_old(i,j,k))*idt
3046 enddo ;
enddo ;
enddo
3047 call post_data(cs%id_boundary_forcing_temp_tend, work_3d, cs%diag, alt_h=h_old)
3051 if (cs%id_boundary_forcing_heat_tend > 0 .or. cs%id_boundary_forcing_heat_tend_2d > 0)
then
3052 do k=1,nz ;
do j=js,je ;
do i=is,ie
3053 work_3d(i,j,k) = gv%H_to_kg_m2 * tv%C_p * idt * (h(i,j,k) * tv%T(i,j,k) - h_old(i,j,k) * temp_old(i,j,k))
3054 enddo ;
enddo ;
enddo
3055 if (cs%id_boundary_forcing_heat_tend > 0)
then
3056 call post_data(cs%id_boundary_forcing_heat_tend, work_3d, cs%diag, alt_h = h_old)
3058 if (cs%id_boundary_forcing_heat_tend_2d > 0)
then
3059 do j=js,je ;
do i=is,ie
3062 work_2d(i,j) = work_2d(i,j) + work_3d(i,j,k)
3065 call post_data(cs%id_boundary_forcing_heat_tend_2d, work_2d, cs%diag)
3070 if (cs%id_boundary_forcing_saln_tend > 0)
then
3071 do k=1,nz ;
do j=js,je ;
do i=is,ie
3072 work_3d(i,j,k) = (tv%S(i,j,k)-saln_old(i,j,k))*idt
3073 enddo ;
enddo ;
enddo
3074 call post_data(cs%id_boundary_forcing_saln_tend, work_3d, cs%diag, alt_h = h_old)
3078 if (cs%id_boundary_forcing_salt_tend > 0 .or. cs%id_boundary_forcing_salt_tend_2d > 0)
then
3079 do k=1,nz ;
do j=js,je ;
do i=is,ie
3080 work_3d(i,j,k) = gv%H_to_kg_m2 * ppt2mks * idt * (h(i,j,k) * tv%S(i,j,k) - h_old(i,j,k) * saln_old(i,j,k))
3081 enddo ;
enddo ;
enddo
3082 if (cs%id_boundary_forcing_salt_tend > 0)
then
3083 call post_data(cs%id_boundary_forcing_salt_tend, work_3d, cs%diag, alt_h = h_old)
3085 if (cs%id_boundary_forcing_salt_tend_2d > 0)
then
3086 do j=js,je ;
do i=is,ie
3089 work_2d(i,j) = work_2d(i,j) + work_3d(i,j,k)
3092 call post_data(cs%id_boundary_forcing_salt_tend_2d, work_2d, cs%diag)
3108 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)),
intent(in) :: h
3109 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)),
intent(in) :: temp_old
3110 real,
intent(in) :: dt
3112 real,
dimension(SZI_(G),SZJ_(G)) :: work_2d
3114 integer :: i, j, k, is, ie, js, je, nz
3116 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
3117 idt = 0.0 ;
if (dt > 0.0) idt = 1. / dt
3120 if (cs%id_frazil_temp_tend > 0)
then
3121 do k=1,nz ;
do j=js,je ;
do i=is,ie
3122 cs%frazil_temp_diag(i,j,k) = idt * (tv%T(i,j,k)-temp_old(i,j,k))
3123 enddo ;
enddo ;
enddo
3124 call post_data(cs%id_frazil_temp_tend, cs%frazil_temp_diag(:,:,:), cs%diag)
3128 if (cs%id_frazil_heat_tend > 0 .or. cs%id_frazil_heat_tend_2d > 0)
then
3129 do k=1,nz ;
do j=js,je ;
do i=is,ie
3130 cs%frazil_heat_diag(i,j,k) = gv%H_to_kg_m2 * tv%C_p * h(i,j,k) * idt * (tv%T(i,j,k)-temp_old(i,j,k))
3131 enddo ;
enddo ;
enddo
3132 if (cs%id_frazil_heat_tend > 0)
call post_data(cs%id_frazil_heat_tend, cs%frazil_heat_diag(:,:,:), cs%diag)
3136 if (cs%id_frazil_heat_tend_2d > 0)
then
3137 do j=js,je ;
do i=is,ie
3140 work_2d(i,j) = work_2d(i,j) + cs%frazil_heat_diag(i,j,k)
3143 call post_data(cs%id_frazil_heat_tend_2d, work_2d, cs%diag)
3155 type(time_type),
intent(in) :: time
3158 type(
diag_ctrl),
target,
intent(inout) :: diag
3164 #include "version_variable.h"
3165 character(len=40) :: mdl =
"MOM_diabatic_driver"
3167 if (
associated(cs))
then
3168 call mom_error(warning,
"adiabatic_driver_init called with an "// &
3169 "associated control structure.")
3171 else ;
allocate(cs) ;
endif
3174 if (
associated(tracer_flow_csp)) cs%tracer_flow_CSp => tracer_flow_csp
3178 "The following parameters are used for diabatic processes.")
3185 ADp, CDp, CS, tracer_flow_CSp, sponge_CSp, &
3187 type(time_type),
target :: time
3192 logical,
intent(in) :: usealealgorithm
3193 type(
diag_ctrl),
target,
intent(inout) :: diag
3205 logical :: use_temperature, differentialdiffusion
3208 #include "version_variable.h"
3209 character(len=40) :: mdl =
"MOM_diabatic_driver"
3210 character(len=48) :: thickness_units
3211 character(len=40) :: var_name
3212 character(len=160) :: var_descript
3213 integer :: isd, ied, jsd, jed, isdb, iedb, jsdb, jedb, nz, nbands, m
3214 isd = g%isd ; ied = g%ied ; jsd = g%jsd ; jed = g%jed ; nz = g%ke
3215 isdb = g%IsdB ; iedb = g%IedB ; jsdb = g%JsdB ; jedb = g%JedB
3217 if (
associated(cs))
then
3218 call mom_error(warning,
"diabatic_driver_init called with an "// &
3219 "associated control structure.")
3228 if (
associated(tracer_flow_csp)) cs%tracer_flow_CSp => tracer_flow_csp
3229 if (
associated(sponge_csp)) cs%sponge_CSp => sponge_csp
3230 if (
associated(ale_sponge_csp)) cs%ALE_sponge_CSp => ale_sponge_csp
3232 cs%useALEalgorithm = usealealgorithm
3233 cs%bulkmixedlayer = (gv%nkml > 0)
3237 "The following parameters are used for diabatic processes.")
3238 call get_param(param_file, mdl,
"USE_LEGACY_DIABATIC_DRIVER", cs%use_legacy_diabatic, &
3239 "If true, use a legacy version of the diabatic subroutine. "//&
3240 "This is temporary and is needed to avoid change in answers.", &
3242 call get_param(param_file, mdl,
"SPONGE", cs%use_sponge, &
3243 "If true, sponges may be applied anywhere in the domain. "//&
3244 "The exact location and properties of those sponges are "//&
3245 "specified via calls to initialize_sponge and possibly "//&
3246 "set_up_sponge_field.", default=.false.)
3247 call get_param(param_file, mdl,
"ENABLE_THERMODYNAMICS", use_temperature, &
3248 "If true, temperature and salinity are used as state "//&
3249 "variables.", default=.true.)
3250 call get_param(param_file, mdl,
"ENERGETICS_SFC_PBL", cs%use_energetic_PBL, &
3251 "If true, use an implied energetics planetary boundary "//&
3252 "layer scheme to determine the diffusivity and viscosity "//&
3253 "in the surface boundary layer.", default=.false.)
3254 call get_param(param_file, mdl,
"EPBL_IS_ADDITIVE", cs%ePBL_is_additive, &
3255 "If true, the diffusivity from ePBL is added to all "//&
3256 "other diffusivities. Otherwise, the larger of kappa-shear "//&
3257 "and ePBL diffusivities are used.", default=.true.)
3258 call get_param(param_file, mdl,
"DOUBLE_DIFFUSION", differentialdiffusion, &
3259 "If true, apply parameterization of double-diffusion.", &
3261 call get_param(param_file, mdl,
"USE_KPP", cs%use_KPP, &
3262 "If true, turns on the [CVMix] KPP scheme of Large et al., 1994, "//&
3263 "to calculate diffusivities and non-local transport in the OBL.", &
3264 default=.false., do_not_log=.true.)
3267 if (cs%use_CVMix_ddiff .and. differentialdiffusion)
then
3268 call mom_error(fatal,
'diabatic_driver_init: '// &
3269 'Multiple double-diffusion options selected (DOUBLE_DIFFUSION and'//&
3270 'USE_CVMIX_DDIFF), please disable all but one option to proceed.')
3276 if (cs%bulkmixedlayer)
then
3277 call get_param(param_file, mdl,
"ML_MIX_FIRST", cs%ML_mix_first, &
3278 "The fraction of the mixed layer mixing that is applied "//&
3279 "before interior diapycnal mixing. 0 by default.", &
3280 units=
"nondim", default=0.0)
3281 call get_param(param_file, mdl,
"NKBL", cs%nkbl, default=2, do_not_log=.true.)
3283 cs%ML_mix_first = 0.0
3285 if (use_temperature)
then
3286 call get_param(param_file, mdl,
"DO_GEOTHERMAL", cs%use_geothermal, &
3287 "If true, apply geothermal heating.", default=.false.)
3289 cs%use_geothermal = .false.
3291 call get_param(param_file, mdl,
"INTERNAL_TIDES", cs%use_int_tides, &
3292 "If true, use the code that advances a separate set of "//&
3293 "equations for the internal tide energy density.", default=.false.)
3295 if (cs%use_int_tides)
then
3296 call get_param(param_file, mdl,
"INTERNAL_TIDE_MODES", cs%nMode, &
3297 "The number of distinct internal tide modes "//&
3298 "that will be calculated.", default=1, do_not_log=.true.)
3299 call get_param(param_file, mdl,
"UNIFORM_TEST_CG", cs%uniform_test_cg, &
3300 "If positive, a uniform group velocity of internal tide for test case", &
3301 default=-1., units=
"m s-1", scale=us%m_s_to_L_T)
3304 call get_param(param_file, mdl,
"MASSLESS_MATCH_TARGETS", &
3305 cs%massless_match_targets, &
3306 "If true, the temperature and salinity of massless layers "//&
3307 "are kept consistent with their target densities. "//&
3308 "Otherwise the properties of massless layers evolve "//&
3309 "diffusively to match massive neighboring layers.", &
3312 call get_param(param_file, mdl,
"AGGREGATE_FW_FORCING", cs%aggregate_FW_forcing, &
3313 "If true, the net incoming and outgoing fresh water fluxes are combined "//&
3314 "and applied as either incoming or outgoing depending on the sign of the net. "//&
3315 "If false, the net incoming fresh water flux is added to the model and "//&
3316 "thereafter the net outgoing is removed from the topmost non-vanished "//&
3317 "layers of the updated state.", default=.true.)
3319 call get_param(param_file, mdl,
"DEBUG", cs%debug, &
3320 "If true, write out verbose debugging data.", &
3321 default=.false., debuggingparam=.true.)
3322 call get_param(param_file, mdl,
"DEBUG_CONSERVATION", cs%debugConservation, &
3323 "If true, monitor conservation and extrema.", &
3324 default=.false., debuggingparam=.true.)
3326 call get_param(param_file, mdl,
"DEBUG_ENERGY_REQ", cs%debug_energy_req, &
3327 "If true, debug the energy requirements.", default=.false., do_not_log=.true.)
3328 call get_param(param_file, mdl,
"MIX_BOUNDARY_TRACERS", cs%mix_boundary_tracers, &
3329 "If true, mix the passive tracers in massless layers at "//&
3330 "the bottom into the interior as though a diffusivity of "//&
3331 "KD_MIN_TR were operating.", default=.true.)
3333 if (cs%mix_boundary_tracers)
then
3334 call get_param(param_file, mdl,
"KD", kd, fail_if_missing=.true.)
3335 call get_param(param_file, mdl,
"KD_MIN_TR", cs%Kd_min_tr, &
3336 "A minimal diffusivity that should always be applied to "//&
3337 "tracers, especially in massless layers near the bottom. "//&
3338 "The default is 0.1*KD.", units=
"m2 s-1", default=0.1*kd, scale=us%m2_s_to_Z2_T)
3339 call get_param(param_file, mdl,
"KD_BBL_TR", cs%Kd_BBL_tr, &
3340 "A bottom boundary layer tracer diffusivity that will "//&
3341 "allow for explicitly specified bottom fluxes. The "//&
3342 "entrainment at the bottom is at least sqrt(Kd_BBL_tr*dt) "//&
3343 "over the same distance.", units=
"m2 s-1", default=0., scale=us%m2_s_to_Z2_T)
3346 call get_param(param_file, mdl,
"TRACER_TRIDIAG", cs%tracer_tridiag, &
3347 "If true, use the passive tracer tridiagonal solver for T and S", &
3350 call get_param(param_file, mdl,
"MINIMUM_FORCING_DEPTH", cs%minimum_forcing_depth, &
3351 "The smallest depth over which forcing can be applied. This "//&
3352 "only takes effect when near-surface layers become thin "//&
3353 "relative to this scale, in which case the forcing tendencies "//&
3354 "scaled down by distributing the forcing over this depth scale.", &
3355 units=
"m", default=0.001, scale=gv%m_to_H)
3356 call get_param(param_file, mdl,
"EVAP_CFL_LIMIT", cs%evap_CFL_limit, &
3357 "The largest fraction of a layer than can be lost to forcing "//&
3358 "(e.g. evaporation, sea-ice formation) in one time-step. The unused "//&
3359 "mass loss is passed down through the column.", &
3360 units=
"nondim", default=0.8)
3366 cs%id_ea_t = register_diag_field(
'ocean_model',
'ea_t',diag%axesTL,time, &
3367 'Layer (heat) entrainment from above per timestep',
'm', &
3368 conversion=gv%H_to_m)
3369 cs%id_eb_t = register_diag_field(
'ocean_model',
'eb_t',diag%axesTL,time, &
3370 'Layer (heat) entrainment from below per timestep',
'm', &
3371 conversion=gv%H_to_m)
3372 cs%id_ea_s = register_diag_field(
'ocean_model',
'ea_s',diag%axesTL,time, &
3373 'Layer (salt) entrainment from above per timestep',
'm', &
3374 conversion=gv%H_to_m)
3375 cs%id_eb_s = register_diag_field(
'ocean_model',
'eb_s',diag%axesTL,time, &
3376 'Layer (salt) entrainment from below per timestep',
'm', &
3377 conversion=gv%H_to_m)
3379 cs%id_ea = register_diag_field(
'ocean_model',
'ea',diag%axesTL,time, &
3380 'Layer entrainment from above per timestep',
'm', &
3381 conversion=gv%H_to_m)
3382 cs%id_eb = register_diag_field(
'ocean_model',
'eb',diag%axesTL,time, &
3383 'Layer entrainment from below per timestep',
'm', &
3384 conversion=gv%H_to_m)
3385 cs%id_wd = register_diag_field(
'ocean_model',
'wd',diag%axesTi,time, &
3386 'Diapycnal velocity',
'm s-1', conversion=gv%H_to_m)
3387 if (cs%id_wd > 0)
call safe_alloc_ptr(cdp%diapyc_vel,isd,ied,jsd,jed,nz+1)
3389 cs%id_dudt_dia = register_diag_field(
'ocean_model',
'dudt_dia',diag%axesCuL,time, &
3390 'Zonal Acceleration from Diapycnal Mixing',
'm s-2', conversion=us%L_T2_to_m_s2)
3391 cs%id_dvdt_dia = register_diag_field(
'ocean_model',
'dvdt_dia',diag%axesCvL,time, &
3392 'Meridional Acceleration from Diapycnal Mixing',
'm s-2', conversion=us%L_T2_to_m_s2)
3394 if (cs%use_int_tides)
then
3395 cs%id_cg1 = register_diag_field(
'ocean_model',
'cn1', diag%axesT1, &
3396 time,
'First baroclinic mode (eigen) speed',
'm s-1')
3397 allocate(cs%id_cn(cs%nMode)) ; cs%id_cn(:) = -1
3399 write(var_name,
'("cn_mode",i1)') m
3400 write(var_descript,
'("Baroclinic (eigen) speed of mode ",i1)') m
3401 cs%id_cn(m) = register_diag_field(
'ocean_model',var_name, diag%axesT1, &
3402 time, var_descript,
'm s-1')
3403 call mom_mesg(
"Registering "//trim(var_name)//
", Described as: "//var_descript, 5)
3407 if (use_temperature)
then
3408 cs%id_Tdif = register_diag_field(
'ocean_model',
"Tflx_dia_diff",diag%axesTi, &
3409 time,
"Diffusive diapycnal temperature flux across interfaces", &
3410 "degC m s-1", conversion=gv%H_to_m*us%s_to_T)
3411 cs%id_Tadv = register_diag_field(
'ocean_model',
"Tflx_dia_adv",diag%axesTi, &
3412 time,
"Advective diapycnal temperature flux across interfaces", &
3413 "degC m s-1", conversion=gv%H_to_m*us%s_to_T)
3414 cs%id_Sdif = register_diag_field(
'ocean_model',
"Sflx_dia_diff",diag%axesTi, &
3415 time,
"Diffusive diapycnal salnity flux across interfaces", &
3416 "psu m s-1", conversion=gv%H_to_m*us%s_to_T)
3417 cs%id_Sadv = register_diag_field(
'ocean_model',
"Sflx_dia_adv",diag%axesTi, &
3418 time,
"Advective diapycnal salnity flux across interfaces", &
3419 "psu m s-1", conversion=gv%H_to_m*us%s_to_T)
3420 cs%id_MLD_003 = register_diag_field(
'ocean_model',
'MLD_003', diag%axesT1, time, &
3421 'Mixed layer depth (delta rho = 0.03)',
'm', conversion=us%Z_to_m, &
3422 cmor_field_name=
'mlotst', cmor_long_name=
'Ocean Mixed Layer Thickness Defined by Sigma T', &
3423 cmor_standard_name=
'ocean_mixed_layer_thickness_defined_by_sigma_t')
3424 cs%id_mlotstsq = register_diag_field(
'ocean_model',
'mlotstsq',diag%axesT1, time, &
3425 long_name=
'Square of Ocean Mixed Layer Thickness Defined by Sigma T', &
3426 standard_name=
'square_of_ocean_mixed_layer_thickness_defined_by_sigma_t', &
3427 units=
'm2', conversion=us%Z_to_m**2)
3428 cs%id_MLD_0125 = register_diag_field(
'ocean_model',
'MLD_0125',diag%axesT1,time, &
3429 'Mixed layer depth (delta rho = 0.125)',
'm', conversion=us%Z_to_m)
3430 cs%id_subMLN2 = register_diag_field(
'ocean_model',
'subML_N2',diag%axesT1,time, &
3431 'Squared buoyancy frequency below mixed layer',
's-2', conversion=us%s_to_T**2)
3432 cs%id_MLD_user = register_diag_field(
'ocean_model',
'MLD_user',diag%axesT1,time, &
3433 'Mixed layer depth (used defined)',
'm', conversion=us%Z_to_m)
3435 call get_param(param_file, mdl,
"DIAG_MLD_DENSITY_DIFF", cs%MLDdensityDifference, &
3436 "The density difference used to determine a diagnostic mixed "//&
3437 "layer depth, MLD_user, following the definition of Levitus 1982. "//&
3438 "The MLD is the depth at which the density is larger than the "//&
3439 "surface density by the specified amount.", &
3440 units=
'kg/m3', default=0.1, scale=us%kg_m3_to_R)
3441 call get_param(param_file, mdl,
"DIAG_DEPTH_SUBML_N2", cs%dz_subML_N2, &
3442 "The distance over which to calculate a diagnostic of the "//&
3443 "stratification at the base of the mixed layer.", &
3444 units=
'm', default=50.0, scale=us%m_to_Z)
3446 if (cs%id_dudt_dia > 0)
call safe_alloc_ptr(adp%du_dt_dia,isdb,iedb,jsd,jed,nz)
3447 if (cs%id_dvdt_dia > 0)
call safe_alloc_ptr(adp%dv_dt_dia,isd,ied,jsdb,jedb,nz)
3450 cs%id_u_predia = register_diag_field(
'ocean_model',
'u_predia', diag%axesCuL, time, &
3451 'Zonal velocity before diabatic forcing',
'm s-1', conversion=us%L_T_to_m_s)
3452 cs%id_v_predia = register_diag_field(
'ocean_model',
'v_predia', diag%axesCvL, time, &
3453 'Meridional velocity before diabatic forcing',
'm s-1', conversion=us%L_T_to_m_s)
3454 cs%id_h_predia = register_diag_field(
'ocean_model',
'h_predia', diag%axesTL, time, &
3455 'Layer Thickness before diabatic forcing', trim(thickness_units), &
3456 conversion=gv%H_to_MKS, v_extensive=.true.)
3457 cs%id_e_predia = register_diag_field(
'ocean_model',
'e_predia', diag%axesTi, time, &
3458 'Interface Heights before diabatic forcing',
'm')
3459 if (use_temperature)
then
3460 cs%id_T_predia = register_diag_field(
'ocean_model',
'temp_predia', diag%axesTL, time, &
3461 'Potential Temperature',
'degC')
3462 cs%id_S_predia = register_diag_field(
'ocean_model',
'salt_predia', diag%axesTL, time, &
3468 cs%id_Kd_interface = register_diag_field(
'ocean_model',
'Kd_interface', diag%axesTi, time, &
3469 'Total diapycnal diffusivity at interfaces',
'm2 s-1', conversion=us%Z2_T_to_m2_s)
3470 if (cs%use_energetic_PBL)
then
3471 cs%id_Kd_ePBL = register_diag_field(
'ocean_model',
'Kd_ePBL', diag%axesTi, time, &
3472 'ePBL diapycnal diffusivity at interfaces',
'm2 s-1', conversion=us%Z2_T_to_m2_s)
3475 cs%id_Kd_heat = register_diag_field(
'ocean_model',
'Kd_heat', diag%axesTi, time, &
3476 'Total diapycnal diffusivity for heat at interfaces',
'm2 s-1', conversion=us%Z2_T_to_m2_s, &
3477 cmor_field_name=
'difvho', &
3478 cmor_standard_name=
'ocean_vertical_heat_diffusivity', &
3479 cmor_long_name=
'Ocean vertical heat diffusivity')
3480 cs%id_Kd_salt = register_diag_field(
'ocean_model',
'Kd_salt', diag%axesTi, time, &
3481 'Total diapycnal diffusivity for salt at interfaces',
'm2 s-1', conversion=us%Z2_T_to_m2_s, &
3482 cmor_field_name=
'difvso', &
3483 cmor_standard_name=
'ocean_vertical_salt_diffusivity', &
3484 cmor_long_name=
'Ocean vertical salt diffusivity')
3488 cs%useKPP = kpp_init(param_file, g, gv, us, diag, time, cs%KPP_CSp, passive=cs%KPPisPassive)
3490 allocate( cs%KPP_NLTheat(isd:ied,jsd:jed,nz+1) ) ; cs%KPP_NLTheat(:,:,:) = 0.
3491 allocate( cs%KPP_NLTscalar(isd:ied,jsd:jed,nz+1) ) ; cs%KPP_NLTscalar(:,:,:) = 0.
3494 allocate( cs%KPP_buoy_flux(isd:ied,jsd:jed,nz+1) ) ; cs%KPP_buoy_flux(:,:,:) = 0.
3495 allocate( cs%KPP_temp_flux(isd:ied,jsd:jed) ) ; cs%KPP_temp_flux(:,:) = 0.
3496 allocate( cs%KPP_salt_flux(isd:ied,jsd:jed) ) ; cs%KPP_salt_flux(:,:) = 0.
3499 if (cs%useKPP .and. differentialdiffusion)
then
3500 call mom_error(fatal,
'diabatic_driver_init: '// &
3501 'DOUBLE_DIFFUSION (old method) does not work with KPP. Please'//&
3502 'set DOUBLE_DIFFUSION=False and USE_CVMIX_DDIFF=True.')
3505 call get_param(param_file, mdl,
"SALT_REJECT_BELOW_ML", cs%salt_reject_below_ML, &
3506 "If true, place salt from brine rejection below the mixed layer, "// &
3507 "into the first non-vanished layer for which the column remains stable", &
3510 if (cs%salt_reject_below_ML)
then
3511 cs%id_brine_lay = register_diag_field(
'ocean_model',
'brine_layer',diag%axesT1,time, &
3512 'Brine insertion layer',
'none')
3519 cs%id_diabatic_diff_h = register_diag_field(
'ocean_model',
'diabatic_diff_h', diag%axesTL, time, &
3520 long_name=
'Cell thickness used during diabatic diffusion', units=
'm', &
3521 conversion=gv%H_to_m, v_extensive=.true.)
3522 if (cs%useALEalgorithm)
then
3523 cs%id_diabatic_diff_temp_tend = register_diag_field(
'ocean_model', &
3524 'diabatic_diff_temp_tendency', diag%axesTL, time, &
3525 'Diabatic diffusion temperature tendency',
'degC s-1', conversion=us%s_to_T)
3526 if (cs%id_diabatic_diff_temp_tend > 0)
then
3527 cs%diabatic_diff_tendency_diag = .true.
3530 cs%id_diabatic_diff_saln_tend = register_diag_field(
'ocean_model',&
3531 'diabatic_diff_saln_tendency', diag%axesTL, time, &
3532 'Diabatic diffusion salinity tendency',
'psu s-1', conversion=us%s_to_T)
3533 if (cs%id_diabatic_diff_saln_tend > 0)
then
3534 cs%diabatic_diff_tendency_diag = .true.
3537 cs%id_diabatic_diff_heat_tend = register_diag_field(
'ocean_model', &
3538 'diabatic_heat_tendency', diag%axesTL, time, &
3539 'Diabatic diffusion heat tendency', &
3540 'W m-2', conversion=us%s_to_T, cmor_field_name=
'opottempdiff', &
3541 cmor_standard_name=
'tendency_of_sea_water_potential_temperature_expressed_as_heat_content_'// &
3542 'due_to_parameterized_dianeutral_mixing', &
3543 cmor_long_name=
'Tendency of sea water potential temperature expressed as heat content '// &
3544 'due to parameterized dianeutral mixing', &
3546 if (cs%id_diabatic_diff_heat_tend > 0)
then
3547 cs%diabatic_diff_tendency_diag = .true.
3550 cs%id_diabatic_diff_salt_tend = register_diag_field(
'ocean_model', &
3551 'diabatic_salt_tendency', diag%axesTL, time, &
3552 'Diabatic diffusion of salt tendency', &
3553 'kg m-2 s-1', conversion=us%s_to_T, cmor_field_name=
'osaltdiff', &
3554 cmor_standard_name=
'tendency_of_sea_water_salinity_expressed_as_salt_content_'// &
3555 'due_to_parameterized_dianeutral_mixing', &
3556 cmor_long_name=
'Tendency of sea water salinity expressed as salt content '// &
3557 'due to parameterized dianeutral mixing', &
3559 if (cs%id_diabatic_diff_salt_tend > 0)
then
3560 cs%diabatic_diff_tendency_diag = .true.
3564 cs%id_diabatic_diff_heat_tend_2d = register_diag_field(
'ocean_model', &
3565 'diabatic_heat_tendency_2d', diag%axesT1, time, &
3566 'Depth integrated diabatic diffusion heat tendency', &
3567 'W m-2', conversion=us%s_to_T, cmor_field_name=
'opottempdiff_2d', &
3568 cmor_standard_name=
'tendency_of_sea_water_potential_temperature_expressed_as_heat_content_'//&
3569 'due_to_parameterized_dianeutral_mixing_depth_integrated', &
3570 cmor_long_name=
'Tendency of sea water potential temperature expressed as heat content '//&
3571 'due to parameterized dianeutral mixing depth integrated')
3572 if (cs%id_diabatic_diff_heat_tend_2d > 0)
then
3573 cs%diabatic_diff_tendency_diag = .true.
3577 cs%id_diabatic_diff_salt_tend_2d = register_diag_field(
'ocean_model', &
3578 'diabatic_salt_tendency_2d', diag%axesT1, time, &
3579 'Depth integrated diabatic diffusion salt tendency', &
3580 'kg m-2 s-1', conversion=us%s_to_T, cmor_field_name=
'osaltdiff_2d', &
3581 cmor_standard_name=
'tendency_of_sea_water_salinity_expressed_as_salt_content_'// &
3582 'due_to_parameterized_dianeutral_mixing_depth_integrated', &
3583 cmor_long_name=
'Tendency of sea water salinity expressed as salt content '// &
3584 'due to parameterized dianeutral mixing depth integrated')
3585 if (cs%id_diabatic_diff_salt_tend_2d > 0)
then
3586 cs%diabatic_diff_tendency_diag = .true.
3592 cs%id_boundary_forcing_h = register_diag_field(
'ocean_model',
'boundary_forcing_h', diag%axesTL, time, &
3593 long_name=
'Cell thickness after applying boundary forcing', units=
'm', &
3594 conversion=gv%H_to_m, v_extensive=.true.)
3595 cs%id_boundary_forcing_h_tendency = register_diag_field(
'ocean_model', &
3596 'boundary_forcing_h_tendency', diag%axesTL, time, &
3597 'Cell thickness tendency due to boundary forcing',
'm s-1', conversion=us%s_to_T, &
3598 v_extensive = .true.)
3599 if (cs%id_boundary_forcing_h_tendency > 0)
then
3600 cs%boundary_forcing_tendency_diag = .true.
3603 cs%id_boundary_forcing_temp_tend = register_diag_field(
'ocean_model',&
3604 'boundary_forcing_temp_tendency', diag%axesTL, time, &
3605 'Boundary forcing temperature tendency',
'degC s-1', conversion=us%s_to_T)
3606 if (cs%id_boundary_forcing_temp_tend > 0)
then
3607 cs%boundary_forcing_tendency_diag = .true.
3610 cs%id_boundary_forcing_saln_tend = register_diag_field(
'ocean_model',&
3611 'boundary_forcing_saln_tendency', diag%axesTL, time, &
3612 'Boundary forcing saln tendency',
'psu s-1', conversion=us%s_to_T)
3613 if (cs%id_boundary_forcing_saln_tend > 0)
then
3614 cs%boundary_forcing_tendency_diag = .true.
3617 cs%id_boundary_forcing_heat_tend = register_diag_field(
'ocean_model',&
3618 'boundary_forcing_heat_tendency', diag%axesTL, time, &
3619 'Boundary forcing heat tendency',
'W m-2', conversion=us%s_to_T, &
3620 v_extensive = .true.)
3621 if (cs%id_boundary_forcing_heat_tend > 0)
then
3622 cs%boundary_forcing_tendency_diag = .true.
3625 cs%id_boundary_forcing_salt_tend = register_diag_field(
'ocean_model',&
3626 'boundary_forcing_salt_tendency', diag%axesTL, time, &
3627 'Boundary forcing salt tendency',
'kg m-2 s-1', conversion=us%s_to_T, &
3628 v_extensive = .true.)
3629 if (cs%id_boundary_forcing_salt_tend > 0)
then
3630 cs%boundary_forcing_tendency_diag = .true.
3634 cs%id_boundary_forcing_heat_tend_2d = register_diag_field(
'ocean_model',&
3635 'boundary_forcing_heat_tendency_2d', diag%axesT1, time, &
3636 'Depth integrated boundary forcing of ocean heat',
'W m-2', conversion=us%s_to_T)
3637 if (cs%id_boundary_forcing_heat_tend_2d > 0)
then
3638 cs%boundary_forcing_tendency_diag = .true.
3642 cs%id_boundary_forcing_salt_tend_2d = register_diag_field(
'ocean_model',&
3643 'boundary_forcing_salt_tendency_2d', diag%axesT1, time, &
3644 'Depth integrated boundary forcing of ocean salt',
'kg m-2 s-1', conversion=us%s_to_T)
3645 if (cs%id_boundary_forcing_salt_tend_2d > 0)
then
3646 cs%boundary_forcing_tendency_diag = .true.
3651 cs%id_frazil_h = register_diag_field(
'ocean_model',
'frazil_h', diag%axesTL, time, &
3652 long_name=
'Cell Thickness', standard_name=
'cell_thickness', units=
'm', &
3653 conversion=gv%H_to_m, v_extensive=.true.)
3656 cs%id_frazil_temp_tend = register_diag_field(
'ocean_model',&
3657 'frazil_temp_tendency', diag%axesTL, time, &
3658 'Temperature tendency due to frazil formation',
'degC s-1', conversion=us%s_to_T)
3659 if (cs%id_frazil_temp_tend > 0)
then
3660 cs%frazil_tendency_diag = .true.
3664 cs%id_frazil_heat_tend = register_diag_field(
'ocean_model',&
3665 'frazil_heat_tendency', diag%axesTL, time, &
3666 'Heat tendency due to frazil formation',
'W m-2', conversion=us%s_to_T, v_extensive=.true.)
3667 if (cs%id_frazil_heat_tend > 0)
then
3668 cs%frazil_tendency_diag = .true.
3672 cs%id_frazil_heat_tend_2d = register_diag_field(
'ocean_model',&
3673 'frazil_heat_tendency_2d', diag%axesT1, time, &
3674 'Depth integrated heat tendency due to frazil formation',
'W m-2', conversion=us%s_to_T)
3675 if (cs%id_frazil_heat_tend_2d > 0)
then
3676 cs%frazil_tendency_diag = .true.
3679 if (cs%frazil_tendency_diag)
then
3680 allocate(cs%frazil_temp_diag(isd:ied,jsd:jed,nz) ) ; cs%frazil_temp_diag(:,:,:) = 0.
3681 allocate(cs%frazil_heat_diag(isd:ied,jsd:jed,nz) ) ; cs%frazil_heat_diag(:,:,:) = 0.
3685 cs%use_tidal_mixing = tidal_mixing_init(time, g, gv, us, param_file, diag, &
3686 cs%tidal_mixing_CSp)
3690 cs%use_CVMix_conv = cvmix_conv_init(time, g, gv, us, param_file, diag, cs%CVMix_conv_csp)
3692 call entrain_diffusive_init(time, g, gv, us, param_file, diag, cs%entrain_diffusive_CSp)
3695 if (cs%use_geothermal) &
3696 call geothermal_init(time, g, gv, us, param_file, diag, cs%geothermal_CSp)
3699 if (cs%use_int_tides)
then
3700 call int_tide_input_init(time, g, gv, us, param_file, diag, cs%int_tide_input_CSp, &
3706 call set_diffusivity_init(time, g, gv, us, param_file, diag, cs%set_diff_CSp, &
3707 cs%int_tide_CSp, cs%tidal_mixing_CSp, cs%halo_TS_diff)
3710 id_clock_entrain = cpu_clock_id(
'(Ocean diabatic entrain)', grain=clock_module)
3711 if (cs%bulkmixedlayer) &
3713 id_clock_remap = cpu_clock_id(
'(Ocean vert remap)', grain=clock_module)
3714 if (cs%use_geothermal) &
3717 id_clock_kpp = cpu_clock_id(
'(Ocean KPP)', grain=clock_module)
3718 id_clock_tracers = cpu_clock_id(
'(Ocean tracer_columns)', grain=clock_module_driver+5)
3719 if (cs%use_sponge) &
3721 id_clock_tridiag = cpu_clock_id(
'(Ocean diabatic tridiag)', grain=clock_routine)
3722 id_clock_pass = cpu_clock_id(
'(Ocean diabatic message passing)', grain=clock_routine)
3727 call diabatic_aux_init(time, g, gv, us, param_file, diag, cs%diabatic_aux_CSp, &
3728 cs%useALEalgorithm, cs%use_energetic_PBL)
3731 if (cs%bulkmixedlayer) &
3733 if (cs%use_energetic_PBL) &
3734 call energetic_pbl_init(time, g, gv, us, param_file, diag, cs%energetic_PBL_CSp)
3738 if (cs%debug_energy_req) &
3739 call diapyc_energy_req_init(time, g, gv, us, param_file, diag, cs%diapyc_en_rec_CSp)
3742 if (use_temperature)
then
3743 call get_param(param_file, mdl,
"PEN_SW_NBANDS", nbands, default=1)
3744 if (nbands > 0)
then
3746 call opacity_init(time, g, gv, us, param_file, diag, cs%opacity_CSp, cs%optics)
3751 call diag_grid_storage_init(cs%diag_grids_prev, g, diag)
3760 if (.not.
associated(cs))
return
3762 call diabatic_aux_end(cs%diabatic_aux_CSp)
3765 call set_diffusivity_end(cs%set_diff_CSp)
3768 deallocate( cs%KPP_buoy_flux )
3769 deallocate( cs%KPP_temp_flux )
3770 deallocate( cs%KPP_salt_flux )
3773 deallocate( cs%KPP_NLTheat )
3774 deallocate( cs%KPP_NLTscalar )
3775 call kpp_end(cs%KPP_CSp)
3782 if (cs%use_energetic_PBL) &
3783 call energetic_pbl_end(cs%energetic_PBL_CSp)
3784 if (cs%debug_energy_req) &
3785 call diapyc_energy_req_end(cs%diapyc_en_rec_CSp)
3787 if (
associated(cs%optics))
then
3788 call opacity_end(cs%opacity_CSp, cs%optics)
3789 deallocate(cs%optics)