6 use mom_cpu_clock,
only : cpu_clock_id, cpu_clock_begin, cpu_clock_end, clock_routine
20 implicit none ;
private
22 #include <MOM_memory.h>
24 public bulkmixedlayer, bulkmixedlayer_init
42 logical :: absorb_all_sw
49 real :: bulk_ri_convective
52 real :: h_limit_fluxes
67 real :: hbuffer_rel_min
69 real :: bl_detrain_time
77 real :: bl_split_rho_tol
82 integer :: ml_presort_nz_conv_adj
88 logical :: correct_absorption
92 logical :: resolve_ekman
95 type(time_type),
pointer :: time => null()
96 logical :: tke_diagnostics = .false.
97 logical :: do_rivermix = .false.
99 real :: rivermix_depth = 0.0
102 real :: lim_det_dh_sfc
105 real :: lim_det_dh_bathy
109 logical :: use_river_heat_content
112 logical :: use_calving_heat_content
113 logical :: convect_mom_bug
118 real :: allowed_t_chg
120 real :: allowed_s_chg
124 real,
allocatable,
dimension(:,:) :: &
125 ml_depth, & !< The mixed layer depth [H ~> m or kg m-2].
126 diag_tke_wind, & !< The wind source of TKE.
127 diag_tke_ribulk, & !< The resolved KE source of TKE.
128 diag_tke_conv, & !< The convective source of TKE.
129 diag_tke_pen_sw, & !< The TKE sink required to mix penetrating shortwave heating.
130 diag_tke_mech_decay, & !< The decay of mechanical TKE.
131 diag_tke_conv_decay, & !< The decay of convective TKE.
132 diag_tke_mixing, & !< The work done by TKE to deepen the mixed layer.
133 diag_tke_conv_s2, & !< The convective source of TKE due to to mixing in sigma2.
134 diag_pe_detrain, & !< The spurious source of potential energy due to mixed layer
138 logical :: allow_clocks_in_omp_loops
140 type(group_pass_type) :: pass_h_sum_hmbl_prev
143 integer :: id_ml_depth = -1, id_tke_wind = -1, id_tke_mixing = -1
144 integer :: id_tke_ribulk = -1, id_tke_conv = -1, id_tke_pen_sw = -1
145 integer :: id_tke_mech_decay = -1, id_tke_conv_decay = -1, id_tke_conv_s2 = -1
146 integer :: id_pe_detrain = -1, id_pe_detrain2 = -1, id_h_mismatch = -1
147 integer :: id_hsfc_used = -1, id_hsfc_max = -1, id_hsfc_min = -1
152 integer :: id_clock_detrain=0, id_clock_mech=0, id_clock_conv=0, id_clock_adjustment=0
153 integer :: id_clock_eos=0, id_clock_resort=0, id_clock_pass=0
188 subroutine bulkmixedlayer(h_3d, u_3d, v_3d, tv, fluxes, dt, ea, eb, G, GV, US, CS, &
189 optics, Hml, aggregate_FW_forcing, dt_diag, last_call)
193 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)), &
194 intent(inout) :: h_3d
195 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)), &
198 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)), &
204 type(
forcing),
intent(inout) :: fluxes
207 real,
intent(in) :: dt
208 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)), &
212 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)), &
221 real,
dimension(:,:),
pointer :: hml
222 logical,
intent(in) :: aggregate_fw_forcing
226 real,
optional,
intent(in) :: dt_diag
229 logical,
optional,
intent(in) :: last_call
235 real,
dimension(SZI_(G),SZK_(GV)) :: &
244 real,
dimension(SZI_(G),SZK0_(GV)) :: &
250 real,
dimension(SZI_(G),SZK_(GV)) :: &
261 integer,
dimension(SZI_(G),SZK_(GV)) :: &
263 real,
dimension(SZI_(G),SZJ_(G)) :: &
265 real,
dimension(SZI_(G)) :: &
307 real,
dimension(max(CS%nsw,1),SZI_(G)) :: &
310 real,
dimension(max(CS%nsw,1),SZI_(G),SZK_(GV)) :: &
313 real :: cmke(2,szi_(g))
317 real :: inkml, inkmlm1
322 real,
dimension(SZI_(G)) :: &
326 real,
dimension(SZI_(G),SZK_(GV)) :: &
331 real,
dimension(SZI_(G),SZJ_(G)) :: &
341 real,
dimension(SZI_(G)) :: &
352 logical :: write_diags
353 logical :: reset_diags
354 integer,
dimension(2) :: eosdom
355 integer :: i, j, k, is, ie, js, je, nz, nkmb, n
358 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = gv%ke
360 if (.not.
associated(cs))
call mom_error(fatal,
"MOM_mixed_layer: "//&
361 "Module must be initialized before it is used.")
362 if (gv%nkml < 1)
return
364 if (.not.
associated(tv%eqn_of_state))
call mom_error(fatal, &
365 "MOM_mixed_layer: Temperature, salinity and an equation of state "//&
367 if (.NOT.
associated(fluxes%ustar))
call mom_error(fatal, &
368 "MOM_mixed_layer: No surface TKE fluxes (ustar) defined in mixedlayer!")
370 nkmb = cs%nkml+cs%nkbl
371 inkml = 1.0 / real(cs%nkml)
372 if (cs%nkml > 1) inkmlm1 = 1.0 / real(cs%nkml-1)
374 irho0 = 1.0 / (gv%Rho0)
375 dt__diag = dt ;
if (
present(dt_diag)) dt__diag = dt_diag
376 idt_diag = 1.0 / (dt__diag)
377 write_diags = .true. ;
if (
present(last_call)) write_diags = last_call
379 p_ref(:) = 0.0 ; p_ref_cv(:) = tv%P_Ref
383 if (cs%limit_det .or. (cs%id_Hsfc_min > 0))
then
385 do j=js-1,je+1 ;
do i=is-1,ie+1
386 h_sum(i,j) = 0.0 ; hmbl_prev(i,j) = 0.0
390 do k=1,nkmb ;
do i=is-1,ie+1
391 h_sum(i,j) = h_sum(i,j) + h_3d(i,j,k)
392 hmbl_prev(i,j) = hmbl_prev(i,j) + h_3d(i,j,k)
394 do k=nkmb+1,nz ;
do i=is-1,ie+1
395 h_sum(i,j) = h_sum(i,j) + h_3d(i,j,k)
399 call cpu_clock_begin(id_clock_pass)
402 call do_group_pass(cs%pass_h_sum_hmbl_prev, g%Domain)
403 call cpu_clock_end(id_clock_pass)
408 if (
present(dt_diag) .and. write_diags .and. (dt__diag > dt)) &
409 reset_diags = .false.
411 if (reset_diags)
then
412 if (cs%TKE_diagnostics)
then
414 do j=js,je ;
do i=is,ie
415 cs%diag_TKE_wind(i,j) = 0.0 ; cs%diag_TKE_RiBulk(i,j) = 0.0
416 cs%diag_TKE_conv(i,j) = 0.0 ; cs%diag_TKE_pen_SW(i,j) = 0.0
417 cs%diag_TKE_mixing(i,j) = 0.0 ; cs%diag_TKE_mech_decay(i,j) = 0.0
418 cs%diag_TKE_conv_decay(i,j) = 0.0 ; cs%diag_TKE_conv_s2(i,j) = 0.0
421 if (
allocated(cs%diag_PE_detrain))
then
423 do j=js,je ;
do i=is,ie
424 cs%diag_PE_detrain(i,j) = 0.0
427 if (
allocated(cs%diag_PE_detrain2))
then
429 do j=js,je ;
do i=is,ie
430 cs%diag_PE_detrain2(i,j) = 0.0
435 if (cs%ML_resort)
then
436 do i=is,ie ; h_ca(i) = 0.0 ;
enddo
437 do k=1,nz ;
do i=is,ie ; dke_ca(i,k) = 0.0 ; ctke(i,k) = 0.0 ;
enddo ;
enddo
440 eosdom(:) = eos_domain(g%HI)
452 do k=1,nz ;
do i=is,ie
453 h(i,k) = h_3d(i,j,k) ; u(i,k) = u_3d(i,j,k) ; v(i,k) = v_3d(i,j,k)
454 h_orig(i,k) = h_3d(i,j,k)
455 eps(i,k) = 0.0 ;
if (k > nkmb) eps(i,k) = gv%Angstrom_H
456 t(i,k) = tv%T(i,j,k) ; s(i,k) = tv%S(i,j,k)
458 if (nsw>0)
call extract_optics_slice(optics, j, g, gv, opacity=opacity_band, opacity_scale=gv%H_to_m)
460 do k=1,nz ;
do i=is,ie
461 d_ea(i,k) = 0.0 ; d_eb(i,k) = 0.0
464 if (id_clock_eos>0)
call cpu_clock_begin(id_clock_eos)
466 if (
associated(tv%p_surf))
then
467 do i=is,ie ; p_ref(i) = tv%p_surf(i,j) ;
enddo
469 do i=is,ie ; p_ref(i) = 0.0 ;
enddo
471 do k=1,cs%nkml ;
do i=is,ie
472 p_ref(i) = p_ref(i) + 0.5*(gv%H_to_RZ*gv%g_Earth)*h(i,k)
478 call calculate_density(t(:,k), s(:,k), p_ref_cv, rcv(:,k), tv%eqn_of_state, eosdom)
480 if (id_clock_eos>0)
call cpu_clock_end(id_clock_eos)
482 if (cs%ML_resort)
then
483 if (id_clock_resort>0)
call cpu_clock_begin(id_clock_resort)
484 if (cs%ML_presort_nz_conv_adj > 0) &
485 call convective_adjustment(h(:,1:), u, v, r0(:,1:), rcv(:,1:), t(:,1:), &
486 s(:,1:), eps, d_eb, dke_ca, ctke, j, g, gv, us, cs, &
487 cs%ML_presort_nz_conv_adj)
489 call sort_ml(h(:,1:), r0(:,1:), eps, g, gv, cs, ksort)
490 if (id_clock_resort>0)
call cpu_clock_end(id_clock_resort)
492 do k=1,nz ;
do i=is,ie ; ksort(i,k) = k ;
enddo ;
enddo
494 if (id_clock_adjustment>0)
call cpu_clock_begin(id_clock_adjustment)
498 call convective_adjustment(h(:,1:), u, v, r0(:,1:), rcv(:,1:), t(:,1:), &
499 s(:,1:), eps, d_eb, dke_ca, ctke, j, g, gv, us, cs)
500 do i=is,ie ; h_ca(i) = h(i,1) ;
enddo
502 if (id_clock_adjustment>0)
call cpu_clock_end(id_clock_adjustment)
505 if (
associated(fluxes%lrunoff) .and. cs%do_rivermix)
then
517 rmixconst = 0.5*cs%rivermix_depth * gv%g_Earth * irho0**2
519 tke_river(i) = max(0.0, rmixconst*dr0_ds(i)* &
520 (fluxes%lrunoff(i,j) + fluxes%frunoff(i,j)) * s(i,1))
523 do i=is,ie ; tke_river(i) = 0.0 ;
enddo
527 if (id_clock_conv>0)
call cpu_clock_begin(id_clock_conv)
536 call extractfluxes1d(g, gv, us, fluxes, optics, nsw, j, dt, &
537 cs%H_limit_fluxes, cs%use_river_heat_content, cs%use_calving_heat_content, &
538 h(:,1:), t(:,1:), netmassinout, netmassout, net_heat, net_salt, pen_sw_bnd,&
539 tv, aggregate_fw_forcing)
542 call mixedlayer_convection(h(:,1:), d_eb, htot, ttot, stot, uhtot, vhtot, &
543 r0_tot, rcv_tot, u, v, t(:,1:), s(:,1:), &
544 r0(:,1:), rcv(:,1:), eps, &
545 dr0_dt, drcv_dt, dr0_ds, drcv_ds, &
546 netmassinout, netmassout, net_heat, net_salt, &
547 nsw, pen_sw_bnd, opacity_band, conv_en, &
548 dke_fc, j, ksort, g, gv, us, cs, tv, fluxes, dt, &
549 aggregate_fw_forcing)
551 if (id_clock_conv>0)
call cpu_clock_end(id_clock_conv)
559 if (id_clock_mech>0)
call cpu_clock_begin(id_clock_mech)
561 call find_starting_tke(htot, h_ca, fluxes, conv_en, ctke, dke_fc, dke_ca, &
562 tke, tke_river, idecay_len_tke, cmke, dt, idt_diag, &
563 j, ksort, g, gv, us, cs)
566 call mechanical_entrainment(h(:,1:), d_eb, htot, ttot, stot, uhtot, vhtot, &
567 r0_tot, rcv_tot, u, v, t(:,1:), s(:,1:), r0(:,1:), rcv(:,1:), eps, dr0_dt, drcv_dt, &
568 cmke, idt_diag, nsw, pen_sw_bnd, opacity_band, tke, &
569 idecay_len_tke, j, ksort, g, gv, us, cs)
571 call absorbremainingsw(g, gv, us, h(:,1:), opacity_band, nsw, optics, j, dt, &
572 cs%H_limit_fluxes, cs%correct_absorption, cs%absorb_all_SW, &
573 t(:,1:), pen_sw_bnd, eps, ksort, htot, ttot)
575 if (cs%TKE_diagnostics)
then ;
do i=is,ie
576 cs%diag_TKE_mech_decay(i,j) = cs%diag_TKE_mech_decay(i,j) - idt_diag * tke(i)
578 if (id_clock_mech>0)
call cpu_clock_end(id_clock_mech)
581 do i=is,ie ;
if (htot(i) > 0.0)
then
583 r0(i,0) = r0_tot(i) * ih ; rcv(i,0) = rcv_tot(i) * ih
584 t(i,0) = ttot(i) * ih ; s(i,0) = stot(i) * ih
587 t(i,0) = t(i,1) ; s(i,0) = s(i,1) ; r0(i,0) = r0(i,1) ; rcv(i,0) = rcv(i,1)
590 if (write_diags .and.
allocated(cs%ML_depth))
then ;
do i=is,ie
591 cs%ML_depth(i,j) = h(i,0) * gv%H_to_m
593 if (
associated(hml))
then ;
do i=is,ie
594 hml(i,j) = g%mask2dT(i,j) * (h(i,0) * gv%H_to_Z)
607 if (cs%ML_resort)
then
608 if (id_clock_resort>0)
call cpu_clock_begin(id_clock_resort)
609 call resort_ml(h(:,0:), t(:,0:), s(:,0:), r0(:,0:), rcv(:,0:), gv%Rlay(:), eps, &
610 d_ea, d_eb, ksort, g, gv, cs, dr0_dt, dr0_ds, drcv_dt, drcv_ds)
611 if (id_clock_resort>0)
call cpu_clock_end(id_clock_resort)
614 if (cs%limit_det .or. (cs%id_Hsfc_max > 0) .or. (cs%id_Hsfc_min > 0))
then
615 do i=is,ie ; hsfc(i) = h(i,0) ;
enddo
616 do k=1,nkmb ;
do i=is,ie ; hsfc(i) = hsfc(i) + h(i,k) ;
enddo ;
enddo
618 if (cs%limit_det .or. (cs%id_Hsfc_min > 0))
then
619 dhsfc = cs%lim_det_dH_sfc ; dhd = cs%lim_det_dH_bathy
621 h_nbr = min(dhsfc*max(hmbl_prev(i-1,j), hmbl_prev(i+1,j), &
622 hmbl_prev(i,j-1), hmbl_prev(i,j+1)), &
623 max(hmbl_prev(i-1,j) - dhd*min(h_sum(i,j),h_sum(i-1,j)), &
624 hmbl_prev(i+1,j) - dhd*min(h_sum(i,j),h_sum(i+1,j)), &
625 hmbl_prev(i,j-1) - dhd*min(h_sum(i,j),h_sum(i,j-1)), &
626 hmbl_prev(i,j+1) - dhd*min(h_sum(i,j),h_sum(i,j+1))) )
628 hsfc_min(i,j) = gv%H_to_Z * max(h(i,0), min(hsfc(i), h_nbr))
630 if (cs%limit_det) max_bl_det(i) = max(0.0, hsfc(i)-h_nbr)
634 if (cs%id_Hsfc_max > 0)
then ;
do i=is,ie
635 hsfc_max(i,j) = gv%H_to_Z * hsfc(i)
642 if (id_clock_detrain>0)
call cpu_clock_begin(id_clock_detrain)
643 if (cs%nkbl == 1)
then
644 call mixedlayer_detrain_1(h(:,0:), t(:,0:), s(:,0:), r0(:,0:), rcv(:,0:), &
645 gv%Rlay(:), dt, dt__diag, d_ea, d_eb, j, g, gv, us, cs, &
646 drcv_dt, drcv_ds, max_bl_det)
647 elseif (cs%nkbl == 2)
then
648 call mixedlayer_detrain_2(h(:,0:), t(:,0:), s(:,0:), r0(:,0:), rcv(:,0:), &
649 gv%Rlay(:), dt, dt__diag, d_ea, j, g, gv, us, cs, &
650 dr0_dt, dr0_ds, drcv_dt, drcv_ds, max_bl_det)
653 call mom_error(fatal,
"MOM_mixed_layer: CS%nkbl must be 1 or 2 for now.")
655 if (id_clock_detrain>0)
call cpu_clock_end(id_clock_detrain)
658 if (cs%id_Hsfc_used > 0)
then
659 do i=is,ie ; hsfc_used(i,j) = gv%H_to_Z * h(i,0) ;
enddo
660 do k=cs%nkml+1,nkmb ;
do i=is,ie
661 hsfc_used(i,j) = hsfc_used(i,j) + gv%H_to_Z * h(i,k)
667 if (cs%Resolve_Ekman .and. (cs%nkml>1))
then
676 ku_star = 0.41*fluxes%ustar(i,j)
677 if (
associated(fluxes%ustar_shelf) .and. &
678 associated(fluxes%frac_shelf_h))
then
679 if (fluxes%frac_shelf_h(i,j) > 0.0) &
680 ku_star = (1.0 - fluxes%frac_shelf_h(i,j)) * ku_star + &
681 fluxes%frac_shelf_h(i,j) * (0.41*fluxes%ustar_shelf(i,j))
683 absf_x_h = 0.25 * gv%H_to_Z * h(i,0) * &
684 ((abs(g%CoriolisBu(i,j)) + abs(g%CoriolisBu(i-1,j-1))) + &
685 (abs(g%CoriolisBu(i,j-1)) + abs(g%CoriolisBu(i-1,j))))
688 h_3d(i,j,1) = h(i,0) / (3.0 + sqrt(absf_x_h*(absf_x_h + 2.0*ku_star) / ku_star**2))
691 h_3d(i,j,k) = (h(i,0)-h_3d(i,j,1)) * inkmlm1
692 d_ea(i,k) = d_ea(i,k) + h_3d(i,j,k)
693 d_ea(i,1) = d_ea(i,1) - h_3d(i,j,k)
698 h_3d(i,j,1) = h(i,0) * inkml
700 do k=2,cs%nkml ;
do i=is,ie
701 h_3d(i,j,k) = h(i,0) * inkml
702 d_ea(i,k) = d_ea(i,k) + h_3d(i,j,k)
703 d_ea(i,1) = d_ea(i,1) - h_3d(i,j,k)
706 do i=is,ie ; h(i,0) = 0.0 ;
enddo
707 do k=1,cs%nkml ;
do i=is,ie
708 tv%T(i,j,k) = t(i,0) ; tv%S(i,j,k) = s(i,0)
724 eaml(i,nz) = (h(i,nz) - h_orig(i,nz)) - d_eb(i,nz)
726 do k=nz-1,1,-1 ;
do i=is,ie
727 ebml(i,k) = ebml(i,k+1) - d_eb(i,k+1)
728 eaml(i,k) = eaml(i,k+1) + d_ea(i,k)
730 do i=is,ie ; eaml(i,1) = netmassinout(i) ;
enddo
733 do k=cs%nkml+1,nz ;
do i=is,ie
734 h_3d(i,j,k) = h(i,k); tv%T(i,j,k) = t(i,k) ; tv%S(i,j,k) = s(i,k)
737 do k=1,nz ;
do i=is,ie
738 ea(i,j,k) = ea(i,j,k) + eaml(i,k)
739 eb(i,j,k) = eb(i,j,k) + ebml(i,k)
742 if (cs%id_h_mismatch > 0)
then
744 h_miss(i,j) = gv%H_to_Z * abs(h_3d(i,j,1) - (h_orig(i,1) + &
745 (eaml(i,1) + (ebml(i,1) - eaml(i,1+1)))))
747 do k=2,nz-1 ;
do i=is,ie
748 h_miss(i,j) = h_miss(i,j) + gv%H_to_Z * abs(h_3d(i,j,k) - (h_orig(i,k) + &
749 ((eaml(i,k) - ebml(i,k-1)) + (ebml(i,k) - eaml(i,k+1)))))
752 h_miss(i,j) = h_miss(i,j) + gv%H_to_Z * abs(h_3d(i,j,nz) - (h_orig(i,nz) + &
753 ((eaml(i,nz) - ebml(i,nz-1)) + ebml(i,nz))))
763 call diag_update_remap_grids(cs%diag)
766 if (write_diags)
then
767 if (cs%id_ML_depth > 0) &
768 call post_data(cs%id_ML_depth, cs%ML_depth, cs%diag)
769 if (cs%id_TKE_wind > 0) &
770 call post_data(cs%id_TKE_wind, cs%diag_TKE_wind, cs%diag)
771 if (cs%id_TKE_RiBulk > 0) &
772 call post_data(cs%id_TKE_RiBulk, cs%diag_TKE_RiBulk, cs%diag)
773 if (cs%id_TKE_conv > 0) &
774 call post_data(cs%id_TKE_conv, cs%diag_TKE_conv, cs%diag)
775 if (cs%id_TKE_pen_SW > 0) &
776 call post_data(cs%id_TKE_pen_SW, cs%diag_TKE_pen_SW, cs%diag)
777 if (cs%id_TKE_mixing > 0) &
778 call post_data(cs%id_TKE_mixing, cs%diag_TKE_mixing, cs%diag)
779 if (cs%id_TKE_mech_decay > 0) &
780 call post_data(cs%id_TKE_mech_decay, cs%diag_TKE_mech_decay, cs%diag)
781 if (cs%id_TKE_conv_decay > 0) &
782 call post_data(cs%id_TKE_conv_decay, cs%diag_TKE_conv_decay, cs%diag)
783 if (cs%id_TKE_conv_s2 > 0) &
784 call post_data(cs%id_TKE_conv_s2, cs%diag_TKE_conv_s2, cs%diag)
785 if (cs%id_PE_detrain > 0) &
786 call post_data(cs%id_PE_detrain, cs%diag_PE_detrain, cs%diag)
787 if (cs%id_PE_detrain2 > 0) &
788 call post_data(cs%id_PE_detrain2, cs%diag_PE_detrain2, cs%diag)
789 if (cs%id_h_mismatch > 0) &
790 call post_data(cs%id_h_mismatch, h_miss, cs%diag)
791 if (cs%id_Hsfc_used > 0) &
792 call post_data(cs%id_Hsfc_used, hsfc_used, cs%diag)
793 if (cs%id_Hsfc_max > 0) &
794 call post_data(cs%id_Hsfc_max, hsfc_max, cs%diag)
795 if (cs%id_Hsfc_min > 0) &
796 call post_data(cs%id_Hsfc_min, hsfc_min, cs%diag)
799 end subroutine bulkmixedlayer
804 subroutine convective_adjustment(h, u, v, R0, Rcv, T, S, eps, d_eb, &
805 dKE_CA, cTKE, j, G, GV, US, CS, nz_conv)
808 real,
dimension(SZI_(G),SZK_(GV)),
intent(inout) :: h
810 real,
dimension(SZI_(G),SZK_(GV)),
intent(inout) :: u
812 real,
dimension(SZI_(G),SZK_(GV)),
intent(inout) :: v
814 real,
dimension(SZI_(G),SZK_(GV)),
intent(inout) :: T
815 real,
dimension(SZI_(G),SZK_(GV)),
intent(inout) :: S
816 real,
dimension(SZI_(G),SZK_(GV)),
intent(inout) :: R0
818 real,
dimension(SZI_(G),SZK_(GV)),
intent(inout) :: Rcv
820 real,
dimension(SZI_(G),SZK_(GV)),
intent(inout) :: d_eb
824 real,
dimension(SZI_(G),SZK_(GV)),
intent(in) :: eps
826 real,
dimension(SZI_(G),SZK_(GV)),
intent(out) :: dKE_CA
829 real,
dimension(SZI_(G),SZK_(GV)),
intent(out) :: cTKE
832 integer,
intent(in) :: j
835 integer,
optional,
intent(in) :: nz_conv
844 real,
dimension(SZI_(G)) :: &
865 integer :: is, ie, nz, i, k, k1, nzc, nkmb
867 is = g%isc ; ie = g%iec ; nz = gv%ke
868 g_h2_2rho0 = (gv%g_Earth * gv%H_to_Z**2) / (2.0 * gv%Rho0)
869 nzc = nz ;
if (
present(nz_conv)) nzc = nz_conv
870 nkmb = cs%nkml+cs%nkbl
875 do k1=min(nzc-1,nkmb),1,-1
877 h_orig_k1(i) = h(i,k1)
878 ke_orig(i) = 0.5*h(i,k1)*(u(i,k1)**2 + v(i,k1)**2)
879 uhtot(i) = h(i,k1)*u(i,k1) ; vhtot(i) = h(i,k1)*v(i,k1)
880 r0_tot(i) = r0(i,k1) * h(i,k1)
881 ctke(i,k1) = 0.0 ; dke_ca(i,k1) = 0.0
883 rcv_tot(i) = rcv(i,k1) * h(i,k1)
884 ttot(i) = t(i,k1) * h(i,k1) ; stot(i) = s(i,k1) * h(i,k1)
888 if ((h(i,k) > eps(i,k)) .and. (r0_tot(i) > h(i,k1)*r0(i,k)))
then
889 h_ent = h(i,k)-eps(i,k)
890 ctke(i,k1) = ctke(i,k1) + h_ent * g_h2_2rho0 * &
891 (r0_tot(i) - h(i,k1)*r0(i,k)) * cs%nstar2
893 ctke(i,k1) = ctke(i,k1) + ctke(i,k)
894 dke_ca(i,k1) = dke_ca(i,k1) + dke_ca(i,k)
896 r0_tot(i) = r0_tot(i) + h_ent * r0(i,k)
897 ke_orig(i) = ke_orig(i) + 0.5*h_ent* &
898 (u(i,k)*u(i,k) + v(i,k)*v(i,k))
899 uhtot(i) = uhtot(i) + h_ent*u(i,k)
900 vhtot(i) = vhtot(i) + h_ent*v(i,k)
902 rcv_tot(i) = rcv_tot(i) + h_ent * rcv(i,k)
903 ttot(i) = ttot(i) + h_ent * t(i,k)
904 stot(i) = stot(i) + h_ent * s(i,k)
905 h(i,k1) = h(i,k1) + h_ent ; h(i,k) = eps(i,k)
907 d_eb(i,k) = d_eb(i,k) - h_ent
908 d_eb(i,k1) = d_eb(i,k1) + h_ent
914 do i=is,ie ;
if (h(i,k1) > h_orig_k1(i))
then
916 r0(i,k1) = r0_tot(i) * ih
917 u(i,k1) = uhtot(i) * ih ; v(i,k1) = vhtot(i) * ih
918 dke_ca(i,k1) = dke_ca(i,k1) + gv%H_to_Z * (cs%bulk_Ri_convective * &
919 (ke_orig(i) - 0.5*h(i,k1)*(u(i,k1)**2 + v(i,k1)**2)))
920 rcv(i,k1) = rcv_tot(i) * ih
921 t(i,k1) = ttot(i) * ih ; s(i,k1) = stot(i) * ih
926 do k=2,min(nzc,nkmb) ;
do i=is,ie ;
if (h(i,k) == 0.0)
then
928 rcv(i,k) = rcv(i,k-1) ; t(i,k) = t(i,k-1) ; s(i,k) = s(i,k-1)
929 endif ;
enddo ;
enddo
931 end subroutine convective_adjustment
936 subroutine mixedlayer_convection(h, d_eb, htot, Ttot, Stot, uhtot, vhtot, &
937 R0_tot, Rcv_tot, u, v, T, S, R0, Rcv, eps, &
938 dR0_dT, dRcv_dT, dR0_dS, dRcv_dS, &
939 netMassInOut, netMassOut, Net_heat, Net_salt, &
940 nsw, Pen_SW_bnd, opacity_band, Conv_En, &
941 dKE_FC, j, ksort, G, GV, US, CS, tv, fluxes, dt, &
942 aggregate_FW_forcing)
945 real,
dimension(SZI_(G),SZK_(GV)), &
948 real,
dimension(SZI_(G),SZK_(GV)), &
949 intent(inout) :: d_eb
952 real,
dimension(SZI_(G)),
intent(out) :: htot
953 real,
dimension(SZI_(G)),
intent(out) :: Ttot
955 real,
dimension(SZI_(G)),
intent(out) :: Stot
957 real,
dimension(SZI_(G)),
intent(out) :: uhtot
959 real,
dimension(SZI_(G)),
intent(out) :: vhtot
961 real,
dimension(SZI_(G)),
intent(out) :: R0_tot
963 real,
dimension(SZI_(G)),
intent(out) :: Rcv_tot
965 real,
dimension(SZI_(G),SZK_(GV)), &
967 real,
dimension(SZI_(G),SZK_(GV)), &
969 real,
dimension(SZI_(G),SZK_(GV)), &
971 real,
dimension(SZI_(G),SZK_(GV)), &
973 real,
dimension(SZI_(G),SZK_(GV)), &
976 real,
dimension(SZI_(G),SZK_(GV)), &
979 real,
dimension(SZI_(G),SZK_(GV)), &
982 real,
dimension(SZI_(G)),
intent(in) :: dR0_dT
984 real,
dimension(SZI_(G)),
intent(in) :: dRcv_dT
986 real,
dimension(SZI_(G)),
intent(in) :: dR0_dS
988 real,
dimension(SZI_(G)),
intent(in) :: dRcv_dS
990 real,
dimension(SZI_(G)),
intent(in) :: netMassInOut
993 real,
dimension(SZI_(G)),
intent(in) :: netMassOut
995 real,
dimension(SZI_(G)),
intent(in) :: Net_heat
998 real,
dimension(SZI_(G)),
intent(in) :: Net_salt
1000 integer,
intent(in) :: nsw
1002 real,
dimension(max(nsw,1),SZI_(G)),
intent(inout) :: Pen_SW_bnd
1005 real,
dimension(max(nsw,1),SZI_(G),SZK_(GV)),
intent(in) :: opacity_band
1007 real,
dimension(SZI_(G)),
intent(out) :: Conv_En
1009 real,
dimension(SZI_(G)),
intent(out) :: dKE_FC
1011 integer,
intent(in) :: j
1012 integer,
dimension(SZI_(G),SZK_(GV)), &
1019 type(
forcing),
intent(inout) :: fluxes
1022 real,
intent(in) :: dt
1023 logical,
intent(in) :: aggregate_FW_forcing
1033 real,
dimension(SZI_(G)) :: &
1038 real :: Pen_absorbed
1045 real :: En_fn, Frac, x1
1047 real :: dr_ent, dr_comp
1049 real :: h_min, h_max
1064 integer :: is, ie, nz, i, k, ks, itt, n
1065 real,
dimension(max(nsw,1)) :: &
1069 angstrom = gv%Angstrom_H
1070 c1_3 = 1.0/3.0 ; c1_6 = 1.0/6.0
1071 g_h2_2rho0 = (gv%g_Earth * gv%H_to_Z**2) / (2.0 * gv%Rho0)
1073 is = g%isc ; ie = g%iec ; nz = gv%ke
1075 do i=is,ie ;
if (ksort(i,1) > 0)
then
1078 if (aggregate_fw_forcing)
then
1080 if (netmassinout(i) < 0.0) massoutrem(i) = -netmassinout(i)
1081 netmassin(i) = netmassinout(i) + massoutrem(i)
1083 massoutrem(i) = -netmassout(i)
1084 netmassin(i) = netmassinout(i) - netmassout(i)
1088 h_ent = max(min(angstrom,h(i,k)-eps(i,k)),0.0)
1089 htot(i) = h_ent + netmassin(i)
1090 h(i,k) = h(i,k) - h_ent
1091 d_eb(i,k) = d_eb(i,k) - h_ent
1094 do n=1,nsw ;
if (pen_sw_bnd(n,i) > 0.0)
then
1095 sw_trans = exp(-htot(i)*opacity_band(n,i,k))
1096 pen_absorbed = pen_absorbed + pen_sw_bnd(n,i) * (1.0-sw_trans)
1097 pen_sw_bnd(n,i) = pen_sw_bnd(n,i) * sw_trans
1104 ttot(i) = (net_heat(i) + (netmassin(i) * t_precip + h_ent * t(i,k))) + &
1112 stot(i) = h_ent*s(i,k) + net_salt(i)
1113 uhtot(i) = u(i,1)*netmassin(i) + u(i,k)*h_ent
1114 vhtot(i) = v(i,1)*netmassin(i) + v(i,k)*h_ent
1115 r0_tot(i) = (h_ent*r0(i,k) + netmassin(i)*r0(i,1)) + &
1117 (dr0_dt(i)*(net_heat(i) + pen_absorbed) - &
1118 dr0_ds(i) * (netmassin(i) * s(i,1) - net_salt(i)))
1119 rcv_tot(i) = (h_ent*rcv(i,k) + netmassin(i)*rcv(i,1)) + &
1121 (drcv_dt(i)*(net_heat(i) + pen_absorbed) - &
1122 drcv_ds(i) * (netmassin(i) * s(i,1) - net_salt(i)))
1123 conv_en(i) = 0.0 ; dke_fc(i) = 0.0
1124 if (
associated(fluxes%heat_content_massin)) &
1125 fluxes%heat_content_massin(i,j) = fluxes%heat_content_massin(i,j) + &
1126 t_precip * netmassin(i) * gv%H_to_RZ * fluxes%C_p * idt
1127 if (
associated(tv%TempxPmE)) tv%TempxPmE(i,j) = tv%TempxPmE(i,j) + &
1128 t_precip * netmassin(i) * gv%H_to_RZ
1130 htot(i) = 0.0 ; ttot(i) = 0.0 ; stot(i) = 0.0 ; r0_tot(i) = 0.0 ; rcv_tot = 0.0
1131 uhtot(i) = 0.0 ; vhtot(i) = 0.0 ; conv_en(i) = 0.0 ; dke_fc(i) = 0.0
1137 do i=is,ie ;
if (ksort(i,ks) > 0)
then
1140 if ((htot(i) < angstrom) .and. (h(i,k) > eps(i,k)))
then
1143 h_ent = min(angstrom-htot(i), h(i,k)-eps(i,k))
1144 htot(i) = htot(i) + h_ent
1145 h(i,k) = h(i,k) - h_ent
1146 d_eb(i,k) = d_eb(i,k) - h_ent
1148 r0_tot(i) = r0_tot(i) + h_ent*r0(i,k)
1149 uhtot(i) = uhtot(i) + h_ent*u(i,k)
1150 vhtot(i) = vhtot(i) + h_ent*v(i,k)
1152 rcv_tot(i) = rcv_tot(i) + h_ent*rcv(i,k)
1153 ttot(i) = ttot(i) + h_ent*t(i,k)
1154 stot(i) = stot(i) + h_ent*s(i,k)
1160 if ((massoutrem(i) > 0.0) .and. (h(i,k) > eps(i,k)))
then
1161 if (massoutrem(i) > (h(i,k) - eps(i,k)))
then
1162 h_evap = h(i,k) - eps(i,k)
1164 massoutrem(i) = massoutrem(i) - h_evap
1166 h_evap = massoutrem(i)
1167 h(i,k) = h(i,k) - h_evap
1171 stot(i) = stot(i) + h_evap*s(i,k)
1172 r0_tot(i) = r0_tot(i) + dr0_ds(i)*h_evap*s(i,k)
1173 rcv_tot(i) = rcv_tot(i) + drcv_ds(i)*h_evap*s(i,k)
1174 d_eb(i,k) = d_eb(i,k) - h_evap
1180 if (
associated(fluxes%heat_content_massout)) &
1181 fluxes%heat_content_massout(i,j) = fluxes%heat_content_massout(i,j) - &
1182 t(i,k)*h_evap*gv%H_to_RZ * fluxes%C_p * idt
1183 if (
associated(tv%TempxPmE)) tv%TempxPmE(i,j) = tv%TempxPmE(i,j) - &
1184 t(i,k)*h_evap*gv%H_to_RZ
1189 h_avail = h(i,k) - eps(i,k)
1190 if (h_avail > 0.0)
then
1191 dr = r0_tot(i) - htot(i)*r0(i,k)
1195 do n=1,nsw ;
if (pen_sw_bnd(n,i) > 0.0)
then
1196 dr0 = dr0 - (dr0_dt(i)*pen_sw_bnd(n,i)) * &
1197 opacity_band(n,i,k)*htot(i)
1203 do n=1,nsw ;
if (pen_sw_bnd(n,i) > 0.0)
then
1206 opacity = opacity_band(n,i,k)
1207 sw_trans = exp(-h_avail*opacity)
1208 dr_comp = dr_comp + (dr0_dt(i)*pen_sw_bnd(n,i)) * &
1209 ((1.0 - sw_trans) - opacity*(htot(i)+h_avail)*sw_trans)
1211 if (dr_comp >= 0.0)
then
1221 frac = dr0 / (dr0 - dr_comp)
1222 h_ent = h_avail * frac*frac
1223 h_min = 0.0 ; h_max = h_avail
1226 r_sw_top(n) = dr0_dt(i) * pen_sw_bnd(n,i)
1227 c2(n) = r_sw_top(n) * opacity_band(n,i,k)**2
1230 dr_ent = dr ; dr_dh = 0.0
1232 opacity = opacity_band(n,i,k)
1233 sw_trans = exp(-h_ent*opacity)
1234 dr_ent = dr_ent + r_sw_top(n) * ((1.0 - sw_trans) - &
1235 opacity*(htot(i)+h_ent)*sw_trans)
1236 dr_dh = dr_dh + c2(n) * (htot(i)+h_ent) * sw_trans
1239 if (dr_ent > 0.0)
then
1245 dh_newt = -dr_ent / dr_dh
1246 h_prev = h_ent ; h_ent = h_prev+dh_newt
1247 if (h_ent > h_max)
then
1248 h_ent = 0.5*(h_prev+h_max)
1249 elseif (h_ent < h_min)
then
1250 h_ent = 0.5*(h_prev+h_min)
1253 if (abs(dh_newt) < 0.2*angstrom)
exit
1260 sum_pen_en = 0.0 ; pen_absorbed = 0.0
1261 do n=1,nsw ;
if (pen_sw_bnd(n,i) > 0.0)
then
1262 opacity = opacity_band(n,i,k)
1263 sw_trans = exp(-h_ent*opacity)
1266 if (x1 < 2.0e-5)
then
1267 en_fn = (opacity*htot(i)*(1.0 - 0.5*(x1 - c1_3*x1)) + &
1270 en_fn = ((opacity*htot(i) + 2.0) * &
1271 ((1.0-sw_trans) / x1) - 1.0 + sw_trans)
1273 sum_pen_en = sum_pen_en - (dr0_dt(i)*pen_sw_bnd(n,i)) * en_fn
1275 pen_absorbed = pen_absorbed + pen_sw_bnd(n,i) * (1.0 - sw_trans)
1276 pen_sw_bnd(n,i) = pen_sw_bnd(n,i) * sw_trans
1279 conv_en(i) = conv_en(i) + g_h2_2rho0 * h_ent * &
1280 ( (r0_tot(i) - r0(i,k)*htot(i)) + sum_pen_en )
1282 r0_tot(i) = r0_tot(i) + (h_ent * r0(i,k) + pen_absorbed*dr0_dt(i))
1283 stot(i) = stot(i) + h_ent * s(i,k)
1284 ttot(i) = ttot(i) + (h_ent * t(i,k) + pen_absorbed)
1285 rcv_tot(i) = rcv_tot(i) + (h_ent * rcv(i,k) + pen_absorbed*drcv_dt(i))
1288 if (h_ent > 0.0)
then
1289 if (htot(i) > 0.0) &
1290 dke_fc(i) = dke_fc(i) + cs%bulk_Ri_convective * 0.5 * &
1291 ((gv%H_to_Z*h_ent) / (htot(i)*(h_ent+htot(i)))) * &
1292 ((uhtot(i)-u(i,k)*htot(i))**2 + (vhtot(i)-v(i,k)*htot(i))**2)
1294 htot(i) = htot(i) + h_ent
1295 h(i,k) = h(i,k) - h_ent
1296 d_eb(i,k) = d_eb(i,k) - h_ent
1297 if (cs%convect_mom_bug)
then
1298 uhtot(i) = u(i,k)*h_ent ; vhtot(i) = v(i,k)*h_ent
1300 uhtot(i) = uhtot(i) + h_ent*u(i,k) ; vhtot(i) = vhtot(i) + h_ent*v(i,k)
1309 end subroutine mixedlayer_convection
1313 subroutine find_starting_tke(htot, h_CA, fluxes, Conv_En, cTKE, dKE_FC, dKE_CA, &
1314 TKE, TKE_river, Idecay_len_TKE, cMKE, dt, Idt_diag, &
1315 j, ksort, G, GV, US, CS)
1319 real,
dimension(SZI_(G)),
intent(in) :: htot
1321 real,
dimension(SZI_(G)),
intent(in) :: h_CA
1323 type(
forcing),
intent(in) :: fluxes
1326 real,
dimension(SZI_(G)),
intent(inout) :: Conv_En
1328 real,
dimension(SZI_(G)),
intent(in) :: dKE_FC
1331 real,
dimension(SZI_(G),SZK_(GV)), &
1335 real,
dimension(SZI_(G),SZK_(GV)), &
1336 intent(in) :: dKE_CA
1339 real,
dimension(SZI_(G)),
intent(out) :: TKE
1341 real,
dimension(SZI_(G)),
intent(out) :: Idecay_len_TKE
1343 real,
dimension(SZI_(G)),
intent(in) :: TKE_river
1346 real,
dimension(2,SZI_(G)),
intent(out) :: cMKE
1349 real,
intent(in) :: dt
1350 real,
intent(in) :: Idt_diag
1352 integer,
intent(in) :: j
1353 integer,
dimension(SZI_(G),SZK_(GV)), &
1376 real :: wind_TKE_src
1379 integer :: is, ie, nz, i
1381 is = g%isc ; ie = g%iec ; nz = gv%ke
1382 diag_wt = dt * idt_diag
1384 if (cs%omega_frac >= 1.0) absf = 2.0*cs%omega
1386 u_star = fluxes%ustar(i,j)
1387 if (
associated(fluxes%ustar_shelf) .and.
associated(fluxes%frac_shelf_h))
then
1388 if (fluxes%frac_shelf_h(i,j) > 0.0) &
1389 u_star = (1.0 - fluxes%frac_shelf_h(i,j)) * u_star + &
1390 fluxes%frac_shelf_h(i,j) * fluxes%ustar_shelf(i,j)
1393 if (u_star < cs%ustar_min) u_star = cs%ustar_min
1394 if (cs%omega_frac < 1.0)
then
1395 absf = 0.25*((abs(g%CoriolisBu(i,j)) + abs(g%CoriolisBu(i-1,j-1))) + &
1396 (abs(g%CoriolisBu(i,j-1)) + abs(g%CoriolisBu(i-1,j))))
1397 if (cs%omega_frac > 0.0) &
1398 absf = sqrt(cs%omega_frac*4.0*cs%omega**2 + (1.0-cs%omega_frac)*absf**2)
1400 absf_ustar = absf / u_star
1401 idecay_len_tke(i) = (absf_ustar * cs%TKE_decay) * gv%H_to_Z
1413 ih = gv%H_to_Z/(3.0*0.41*u_star*dt)
1414 cmke(1,i) = 4.0 * ih ; cmke(2,i) = (absf_ustar*gv%H_to_Z) * ih
1416 if (idecay_len_tke(i) > 0.0)
then
1417 exp_kh = exp(-htot(i)*idecay_len_tke(i))
1425 if (conv_en(i) < 0.0) conv_en(i) = 0.0
1426 if (ctke(i,1) > 0.0)
then ; tke_ca = ctke(i,1) ;
else ; tke_ca = 0.0 ;
endif
1427 if ((htot(i) >= h_ca(i)) .or. (tke_ca == 0.0))
then
1428 toten_z = us%L_to_Z**2 * (conv_en(i) + tke_ca)
1430 if (toten_z > 0.0)
then
1431 nstar_fc = cs%nstar * toten_z / (toten_z + 0.2 * &
1432 sqrt(0.5 * dt * (absf*(htot(i)*gv%H_to_Z))**3 * toten_z))
1439 if (conv_en(i) > 0.0)
then
1440 toten_z = us%L_to_Z**2 * (conv_en(i) + tke_ca * (htot(i) / h_ca(i)) )
1441 nstar_fc = cs%nstar * toten_z / (toten_z + 0.2 * &
1442 sqrt(0.5 * dt * (absf*(htot(i)*gv%H_to_Z))**3 * toten_z))
1447 toten_z = us%L_to_Z**2 * (conv_en(i) + tke_ca)
1448 if (tke_ca > 0.0)
then
1449 nstar_ca = cs%nstar * toten_z / (toten_z + 0.2 * &
1450 sqrt(0.5 * dt * (absf*(h_ca(i)*gv%H_to_Z))**3 * toten_z))
1456 if (dke_fc(i) + dke_ca(i,1) > 0.0)
then
1457 if (htot(i) >= h_ca(i))
then
1458 mke_rate_fc = 1.0 / (1.0 + htot(i)*(cmke(1,i) + cmke(2,i)*htot(i)) )
1459 mke_rate_ca = mke_rate_fc
1461 mke_rate_fc = 1.0 / (1.0 + htot(i)*(cmke(1,i) + cmke(2,i)*htot(i)) )
1462 mke_rate_ca = 1.0 / (1.0 + h_ca(i)*(cmke(1,i) + cmke(2,i)*h_ca(i)) )
1466 mke_rate_fc = 1.0 ; mke_rate_ca = 1.0
1469 dke_conv = dke_ca(i,1) * mke_rate_ca + dke_fc(i) * mke_rate_fc
1472 tke(i) = (dt*cs%mstar)*((us%Z_to_L**2*(u_star*u_star*u_star))*exp_kh) + &
1473 (exp_kh * dke_conv + nstar_fc*conv_en(i) + nstar_ca * tke_ca)
1475 if (cs%do_rivermix)
then
1476 tke(i) = tke(i) + tke_river(i)*dt*exp_kh
1479 if (cs%TKE_diagnostics)
then
1480 wind_tke_src = cs%mstar*(us%Z_to_L**2*u_star*u_star*u_star) * diag_wt
1481 cs%diag_TKE_wind(i,j) = cs%diag_TKE_wind(i,j) + &
1482 ( wind_tke_src + tke_river(i) * diag_wt )
1483 cs%diag_TKE_RiBulk(i,j) = cs%diag_TKE_RiBulk(i,j) + dke_conv*idt_diag
1484 cs%diag_TKE_mech_decay(i,j) = cs%diag_TKE_mech_decay(i,j) + &
1485 (exp_kh-1.0)*(wind_tke_src + dke_conv*idt_diag)
1486 cs%diag_TKE_conv(i,j) = cs%diag_TKE_conv(i,j) + &
1487 idt_diag * (nstar_fc*conv_en(i) + nstar_ca*tke_ca)
1488 cs%diag_TKE_conv_decay(i,j) = cs%diag_TKE_conv_decay(i,j) + &
1489 idt_diag * ((cs%nstar-nstar_fc)*conv_en(i) + (cs%nstar-nstar_ca)*tke_ca)
1490 cs%diag_TKE_conv_s2(i,j) = cs%diag_TKE_conv_s2(i,j) + &
1491 idt_diag * (ctke(i,1)-tke_ca)
1495 end subroutine find_starting_tke
1498 subroutine mechanical_entrainment(h, d_eb, htot, Ttot, Stot, uhtot, vhtot, &
1499 R0_tot, Rcv_tot, u, v, T, S, R0, Rcv, eps, &
1500 dR0_dT, dRcv_dT, cMKE, Idt_diag, nsw, &
1501 Pen_SW_bnd, opacity_band, TKE, &
1502 Idecay_len_TKE, j, ksort, G, GV, US, CS)
1506 real,
dimension(SZI_(G),SZK_(GV)), &
1508 real,
dimension(SZI_(G),SZK_(GV)), &
1509 intent(inout) :: d_eb
1512 real,
dimension(SZI_(G)),
intent(inout) :: htot
1513 real,
dimension(SZI_(G)),
intent(inout) :: Ttot
1515 real,
dimension(SZI_(G)),
intent(inout) :: Stot
1517 real,
dimension(SZI_(G)),
intent(inout) :: uhtot
1519 real,
dimension(SZI_(G)),
intent(inout) :: vhtot
1521 real,
dimension(SZI_(G)),
intent(inout) :: R0_tot
1523 real,
dimension(SZI_(G)),
intent(inout) :: Rcv_tot
1525 real,
dimension(SZI_(G),SZK_(GV)), &
1527 real,
dimension(SZI_(G),SZK_(GV)), &
1529 real,
dimension(SZI_(G),SZK_(GV)), &
1531 real,
dimension(SZI_(G),SZK_(GV)), &
1533 real,
dimension(SZI_(G),SZK_(GV)), &
1536 real,
dimension(SZI_(G),SZK_(GV)), &
1539 real,
dimension(SZI_(G),SZK_(GV)), &
1542 real,
dimension(SZI_(G)),
intent(in) :: dR0_dT
1544 real,
dimension(SZI_(G)),
intent(in) :: dRcv_dT
1546 real,
dimension(2,SZI_(G)),
intent(in) :: cMKE
1549 real,
intent(in) :: Idt_diag
1551 integer,
intent(in) :: nsw
1553 real,
dimension(max(nsw,1),SZI_(G)),
intent(inout) :: Pen_SW_bnd
1556 real,
dimension(max(nsw,1),SZI_(G),SZK_(GV)),
intent(in) :: opacity_band
1558 real,
dimension(SZI_(G)),
intent(inout) :: TKE
1561 real,
dimension(SZI_(G)),
intent(inout) :: Idecay_len_TKE
1562 integer,
intent(in) :: j
1563 integer,
dimension(SZI_(G),SZK_(GV)), &
1572 real :: Pen_absorbed
1576 real :: h_min, h_max
1586 real :: TKE_full_ent
1590 real :: Pen_En_Contrib
1599 real :: Pen_dTKE_dh_Contrib
1609 real :: f1_x1, f2_x1
1615 real :: C1_3, C1_6, C1_24
1616 integer :: is, ie, nz, i, k, ks, itt, n
1618 c1_3 = 1.0/3.0 ; c1_6 = 1.0/6.0 ; c1_24 = 1.0/24.0
1619 g_h_2rho0 = (gv%g_Earth * gv%H_to_Z) / (2.0 * gv%Rho0)
1620 hmix_min = cs%Hmix_min
1621 h_neglect = gv%H_subroundoff
1622 is = g%isc ; ie = g%iec ; nz = gv%ke
1626 do i=is,ie ;
if (ksort(i,ks) > 0)
then
1629 h_avail = h(i,k) - eps(i,k)
1630 if ((h_avail > 0.) .and. ((tke(i) > 0.) .or. (htot(i) < hmix_min)))
then
1631 drl = g_h_2rho0 * (r0(i,k)*htot(i) - r0_tot(i) )
1632 dmke = (gv%H_to_Z * cs%bulk_Ri_ML) * 0.5 * &
1633 ((uhtot(i)-u(i,k)*htot(i))**2 + (vhtot(i)-v(i,k)*htot(i))**2)
1636 kh = idecay_len_tke(i)*h_avail ; exp_kh = exp(-kh)
1637 if (kh >= 2.0e-5)
then ; f1_kh = (1.0-exp_kh) / kh
1638 else ; f1_kh = (1.0 - kh*(0.5 - c1_6*kh)) ;
endif
1640 pen_en_contrib = 0.0
1641 do n=1,nsw ;
if (pen_sw_bnd(n,i) > 0.0)
then
1642 opacity = opacity_band(n,i,k)
1646 if (idecay_len_tke(i) > opacity)
then
1647 x1 = (idecay_len_tke(i) - opacity) * h_avail
1648 if (x1 >= 2.0e-5)
then
1649 e_x1 = exp(-x1) ; f1_x1 = ((1.0-e_x1)/(x1))
1650 f3_x1 = ((e_x1-(1.0-x1))/(x1*x1))
1652 f1_x1 = (1.0 - x1*(0.5 - c1_6*x1))
1653 f3_x1 = (0.5 - x1*(c1_6 - c1_24*x1))
1656 pen_en1 = exp(-opacity*h_avail) * &
1657 ((1.0+opacity*htot(i))*f1_x1 + opacity*h_avail*f3_x1)
1659 x1 = (opacity - idecay_len_tke(i)) * h_avail
1660 if (x1 >= 2.0e-5)
then
1661 e_x1 = exp(-x1) ; f1_x1 = ((1.0-e_x1)/(x1))
1662 f2_x1 = ((1.0-(1.0+x1)*e_x1)/(x1*x1))
1664 f1_x1 = (1.0 - x1*(0.5 - c1_6*x1))
1665 f2_x1 = (0.5 - x1*(c1_3 - 0.125*x1))
1668 pen_en1 = exp_kh * ((1.0+opacity*htot(i))*f1_x1 + &
1669 opacity*h_avail*f2_x1)
1671 pen_en_contrib = pen_en_contrib + &
1672 (g_h_2rho0*dr0_dt(i)*pen_sw_bnd(n,i)) * (pen_en1 - f1_kh)
1675 hpe = htot(i)+h_avail
1676 mke_rate = 1.0/(1.0 + (cmke(1,i)*hpe + cmke(2,i)*hpe**2))
1677 ef4_val = ef4(htot(i)+h_neglect,h_avail,idecay_len_tke(i))
1678 tke_full_ent = (exp_kh*tke(i) - (h_avail*gv%H_to_Z)*(drl*f1_kh + pen_en_contrib)) + &
1679 mke_rate*dmke*ef4_val
1680 if ((tke_full_ent >= 0.0) .or. (h_avail+htot(i) <= hmix_min))
then
1684 if (cs%TKE_diagnostics)
then
1685 e_hxhpe = h_ent / ((htot(i)+h_neglect)*(htot(i)+h_ent+h_neglect))
1686 cs%diag_TKE_mech_decay(i,j) = cs%diag_TKE_mech_decay(i,j) + &
1687 idt_diag * ((exp_kh-1.0)* tke(i) + (h_ent*gv%H_to_Z)*drl*(1.0-f1_kh) + &
1688 mke_rate*dmke*(ef4_val-e_hxhpe))
1689 cs%diag_TKE_mixing(i,j) = cs%diag_TKE_mixing(i,j) - &
1690 idt_diag*(gv%H_to_Z*h_ent)*drl
1691 cs%diag_TKE_pen_SW(i,j) = cs%diag_TKE_pen_SW(i,j) - &
1692 idt_diag*(gv%H_to_Z*h_ent)*pen_en_contrib
1693 cs%diag_TKE_RiBulk(i,j) = cs%diag_TKE_RiBulk(i,j) + &
1694 idt_diag*mke_rate*dmke*e_hxhpe
1697 tke(i) = tke_full_ent
1699 if (tke(i) <= 0.0) tke(i) = 1.0e-150*us%m_to_Z*us%m_s_to_L_T**2
1704 h_min = 0.0 ; h_max = h_avail
1705 if (tke(i) <= 0.0)
then
1708 h_ent = h_avail * tke(i) / (tke(i) - tke_full_ent)
1713 kh = idecay_len_tke(i)*h_ent ; exp_kh = exp(-kh)
1714 if (kh >= 2.0e-5)
then
1715 f1_kh = (1.0-exp_kh) / kh
1717 f1_kh = (1.0 - kh*(0.5 - c1_6*kh))
1721 pen_en_contrib = 0.0 ; pen_dtke_dh_contrib = 0.0
1722 do n=1,nsw ;
if (pen_sw_bnd(n,i) > 0.0)
then
1726 opacity = opacity_band(n,i,k)
1727 sw_trans = exp(-h_ent*opacity)
1728 if (idecay_len_tke(i) > opacity)
then
1729 x1 = (idecay_len_tke(i) - opacity) * h_ent
1730 if (x1 >= 2.0e-5)
then
1731 e_x1 = exp(-x1) ; f1_x1 = ((1.0-e_x1)/(x1))
1732 f3_x1 = ((e_x1-(1.0-x1))/(x1*x1))
1734 f1_x1 = (1.0 - x1*(0.5 - c1_6*x1))
1735 f3_x1 = (0.5 - x1*(c1_6 - c1_24*x1))
1737 pen_en1 = sw_trans * ((1.0+opacity*htot(i))*f1_x1 + &
1738 opacity*h_ent*f3_x1)
1740 x1 = (opacity - idecay_len_tke(i)) * h_ent
1741 if (x1 >= 2.0e-5)
then
1742 e_x1 = exp(-x1) ; f1_x1 = ((1.0-e_x1)/(x1))
1743 f2_x1 = ((1.0-(1.0+x1)*e_x1)/(x1*x1))
1745 f1_x1 = (1.0 - x1*(0.5 - c1_6*x1))
1746 f2_x1 = (0.5 - x1*(c1_3 - 0.125*x1))
1749 pen_en1 = exp_kh * ((1.0+opacity*htot(i))*f1_x1 + &
1750 opacity*h_ent*f2_x1)
1752 cpen1 = g_h_2rho0*dr0_dt(i)*pen_sw_bnd(n,i)
1753 pen_en_contrib = pen_en_contrib + cpen1*(pen_en1 - f1_kh)
1754 pen_dtke_dh_contrib = pen_dtke_dh_contrib + &
1755 cpen1*((1.0-sw_trans) - opacity*(htot(i) + h_ent)*sw_trans)
1758 tke_ent1 = exp_kh* tke(i) - (h_ent*gv%H_to_Z)*(drl*f1_kh + pen_en_contrib)
1759 ef4_val = ef4(htot(i)+h_neglect,h_ent,idecay_len_tke(i),def4_dh)
1761 mke_rate = 1.0/(1.0 + (cmke(1,i)*hpe + cmke(2,i)*hpe**2))
1762 tke_ent = tke_ent1 + dmke*ef4_val*mke_rate
1765 dtke_dh = ((-idecay_len_tke(i)*tke_ent1 - drl*gv%H_to_Z) + &
1766 pen_dtke_dh_contrib*gv%H_to_Z) + dmke * mke_rate* &
1767 (def4_dh - ef4_val*mke_rate*(cmke(1,i)+2.0*cmke(2,i)*hpe))
1770 if (tke_ent > 0.0)
then
1771 if ((h_max-h_ent)*(-dtke_dh) > tke_ent)
then
1772 dh_newt = -tke_ent / dtke_dh
1774 dh_newt = 0.5*(h_max-h_ent)
1778 if ((h_min-h_ent)*(-dtke_dh) < tke_ent)
then
1779 dh_newt = -tke_ent / dtke_dh
1781 dh_newt = 0.5*(h_min-h_ent)
1785 h_ent = h_ent + dh_newt
1787 if (abs(dh_newt) < 0.2*gv%Angstrom_H)
exit
1791 if (h_ent < hmix_min-htot(i)) h_ent = hmix_min - htot(i)
1793 if (cs%TKE_diagnostics)
then
1795 mke_rate = 1.0/(1.0 + cmke(1,i)*hpe + cmke(2,i)*hpe**2)
1796 ef4_val = ef4(htot(i)+h_neglect,h_ent,idecay_len_tke(i))
1798 e_hxhpe = h_ent / ((htot(i)+h_neglect)*(hpe+h_neglect))
1799 cs%diag_TKE_mech_decay(i,j) = cs%diag_TKE_mech_decay(i,j) + &
1800 idt_diag * ((exp_kh-1.0)* tke(i) + (h_ent*gv%H_to_Z)*drl*(1.0-f1_kh) + &
1801 dmke*mke_rate*(ef4_val-e_hxhpe))
1802 cs%diag_TKE_mixing(i,j) = cs%diag_TKE_mixing(i,j) - &
1803 idt_diag*(h_ent*gv%H_to_Z)*drl
1804 cs%diag_TKE_pen_SW(i,j) = cs%diag_TKE_pen_SW(i,j) - &
1805 idt_diag*(h_ent*gv%H_to_Z)*pen_en_contrib
1806 cs%diag_TKE_RiBulk(i,j) = cs%diag_TKE_RiBulk(i,j) + &
1807 idt_diag*dmke*mke_rate*e_hxhpe
1814 do n=1,nsw ;
if (pen_sw_bnd(n,i) > 0.0)
then
1815 sw_trans = exp(-h_ent*opacity_band(n,i,k))
1816 pen_absorbed = pen_absorbed + pen_sw_bnd(n,i) * (1.0 - sw_trans)
1817 pen_sw_bnd(n,i) = pen_sw_bnd(n,i) * sw_trans
1820 htot(i) = htot(i) + h_ent
1821 r0_tot(i) = r0_tot(i) + (h_ent * r0(i,k) + pen_absorbed*dr0_dt(i))
1822 h(i,k) = h(i,k) - h_ent
1823 d_eb(i,k) = d_eb(i,k) - h_ent
1825 stot(i) = stot(i) + h_ent * s(i,k)
1826 ttot(i) = ttot(i) + (h_ent * t(i,k) + pen_absorbed)
1827 rcv_tot(i) = rcv_tot(i) + (h_ent*rcv(i,k) + pen_absorbed*drcv_dt(i))
1829 uhtot(i) = uhtot(i) + u(i,k)*h_ent
1830 vhtot(i) = vhtot(i) + v(i,k)*h_ent
1836 end subroutine mechanical_entrainment
1840 subroutine sort_ml(h, R0, eps, G, GV, CS, ksort)
1843 real,
dimension(SZI_(G),SZK_(GV)),
intent(in) :: h
1844 real,
dimension(SZI_(G),SZK_(GV)),
intent(in) :: R0
1846 real,
dimension(SZI_(G),SZK_(GV)),
intent(in) :: eps
1850 integer,
dimension(SZI_(G),SZK_(GV)),
intent(out) :: ksort
1853 real :: R0sort(SZI_(G),SZK_(GV))
1854 integer :: nsort(SZI_(G))
1855 logical :: done_sorting(SZI_(G))
1856 integer :: i, k, ks, is, ie, nz, nkmb
1858 is = g%isc ; ie = g%iec ; nz = gv%ke
1859 nkmb = cs%nkml+cs%nkbl
1869 do k=1,nz ;
do i=is,ie ; ksort(i,k) = -1 ;
enddo ;
enddo
1871 do i=is,ie ; nsort(i) = 0 ; done_sorting(i) = .false. ;
enddo
1872 do k=1,nz ;
do i=is,ie ;
if (h(i,k) > eps(i,k))
then
1873 if (done_sorting(i))
then ; ks = nsort(i) ;
else
1875 if (r0(i,k) >= r0sort(i,ks))
exit
1876 r0sort(i,ks+1) = r0sort(i,ks) ; ksort(i,ks+1) = ksort(i,ks)
1878 if ((k > nkmb) .and. (ks == nsort(i))) done_sorting(i) = .true.
1882 r0sort(i,ks+1) = r0(i,k)
1883 nsort(i) = nsort(i) + 1
1884 endif ;
enddo ;
enddo
1886 end subroutine sort_ml
1891 subroutine resort_ml(h, T, S, R0, Rcv, RcvTgt, eps, d_ea, d_eb, ksort, G, GV, CS, &
1892 dR0_dT, dR0_dS, dRcv_dT, dRcv_dS)
1896 real,
dimension(SZI_(G),SZK0_(GV)),
intent(inout) :: h
1898 real,
dimension(SZI_(G),SZK0_(GV)),
intent(inout) :: T
1899 real,
dimension(SZI_(G),SZK0_(GV)),
intent(inout) :: S
1900 real,
dimension(SZI_(G),SZK0_(GV)),
intent(inout) :: R0
1902 real,
dimension(SZI_(G),SZK0_(GV)),
intent(inout) :: Rcv
1904 real,
dimension(SZK_(GV)),
intent(in) :: RcvTgt
1906 real,
dimension(SZI_(G),SZK_(GV)),
intent(inout) :: eps
1908 real,
dimension(SZI_(G),SZK_(GV)),
intent(inout) :: d_ea
1913 real,
dimension(SZI_(G),SZK_(GV)),
intent(inout) :: d_eb
1917 integer,
dimension(SZI_(G),SZK_(GV)),
intent(in) :: ksort
1920 real,
dimension(SZI_(G)),
intent(in) :: dR0_dT
1924 real,
dimension(SZI_(G)),
intent(in) :: dR0_dS
1928 real,
dimension(SZI_(G)),
intent(in) :: dRcv_dT
1932 real,
dimension(SZI_(G)),
intent(in) :: dRcv_dS
1951 real :: h_move, h_tgt_old, I_hnew
1952 real :: dT_dS_wt2, dT_dR, dS_dR, I_denom
1954 real :: T_up, S_up, R0_up, I_hup, h_to_up
1955 real :: T_dn, S_dn, R0_dn, I_hdn, h_to_dn
1958 real :: dPE, hmin, min_dPE, min_hmin
1959 real,
dimension(SZK_(GV)) :: &
1960 h_tmp, R0_tmp, T_tmp, S_tmp, Rcv_tmp
1962 logical :: sorted, leave_in_layer
1963 integer :: ks_deep(SZI_(G)), k_count(SZI_(G)), ks2_reverse(SZI_(G), SZK_(GV))
1964 integer :: ks2(SZK_(GV))
1965 integer :: i, k, ks, is, ie, nz, k1, k2, k_tgt, k_src, k_int_top
1966 integer :: nks, nkmb, num_interior, top_interior_ks
1968 is = g%isc ; ie = g%iec ; nz = gv%ke
1969 nkmb = cs%nkml+cs%nkbl
1971 dt_ds_wt2 = cs%dT_dS_wt**2
1974 do i=is,ie ; ks_deep(i) = -1 ; k_count(i) = 0 ;
enddo
1975 do ks=nz,1,-1 ;
do i=is,ie ;
if (ksort(i,ks) > 0)
then
1978 if (h(i,k) > eps(i,k))
then
1979 if (ks_deep(i) == -1)
then
1981 ks_deep(i) = ks ; k_count(i) = k_count(i) + 1
1982 ks2_reverse(i,k_count(i)) = k
1985 k_count(i) = k_count(i) + 1
1986 ks2_reverse(i,k_count(i)) = k
1989 endif ;
enddo ;
enddo
1991 do i=is,ie ;
if (k_count(i) > 1)
then
1997 ks2(nks) = ks2_reverse(i,1)
1999 ks2(ks) = ks2_reverse(i,1+nks-ks)
2000 if (ks2(ks) > ks2(ks+1)) sorted = .false.
2008 num_interior = 0 ; top_interior_ks = 0
2009 do ks=nks,1,-1 ;
if (ks2(ks) > nkmb)
then
2010 num_interior = num_interior+1 ; top_interior_ks = ks
2013 if (num_interior >= 1)
then
2016 do k=nkmb+1,nz ;
if (rcv(i,0) < rcvtgt(k))
exit ;
enddo
2017 k_int_top = k ; rcv_int = rcvtgt(k)
2019 i_denom = 1.0 / (drcv_ds(i)**2 + dt_ds_wt2*drcv_dt(i)**2)
2020 dt_dr = dt_ds_wt2*drcv_dt(i) * i_denom
2021 ds_dr = drcv_ds(i) * i_denom
2027 do ks = nks,top_interior_ks,-1
2029 leave_in_layer = .false.
2030 if ((k > nkmb) .and. (rcv(i,k) <= rcvtgt(k)))
then
2031 if (rcvtgt(k)-rcv(i,k) < cs%BL_split_rho_tol*(rcvtgt(k) - rcvtgt(k-1))) &
2032 leave_in_layer = .true.
2033 elseif (k > nkmb)
then
2034 if (rcv(i,k)-rcvtgt(k) < cs%BL_split_rho_tol*(rcvtgt(k+1) - rcvtgt(k))) &
2035 leave_in_layer = .true.
2038 if (leave_in_layer)
then
2041 elseif (rcv(i,k) < rcv_int)
then
2048 do k2=k_int_top+1,nz ;
if (rcv(i,k) < rcvtgt(k2))
exit ;
enddo
2053 dr1 = (rcvtgt(k2-1) - rcv(i,k)) ; dr2 = (rcvtgt(k2) - rcv(i,k))
2054 t_up = t(i,k) + dt_dr * dr1
2055 s_up = s(i,k) + ds_dr * dr1
2056 t_dn = t(i,k) + dt_dr * dr2
2057 s_dn = s(i,k) + ds_dr * dr2
2059 r0_up = r0(i,k) + (dt_dr*dr0_dt(i) + ds_dr*dr0_ds(i)) * dr1
2060 r0_dn = r0(i,k) + (dt_dr*dr0_dt(i) + ds_dr*dr0_ds(i)) * dr2
2063 if ((r0_up > r0(i,0)) .or. (r0_dn > r0(i,0))) &
2067 wt_dn = (rcv(i,k) - rcvtgt(k2-1)) / (rcvtgt(k2) - rcvtgt(k2-1))
2068 h_to_up = (h(i,k)-eps(i,k)) * (1.0 - wt_dn)
2069 h_to_dn = (h(i,k)-eps(i,k)) * wt_dn
2071 i_hup = 1.0 / (h(i,k2-1) + h_to_up)
2072 i_hdn = 1.0 / (h(i,k2) + h_to_dn)
2073 r0(i,k2-1) = (r0(i,k2)*h(i,k2-1) + r0_up*h_to_up) * i_hup
2074 r0(i,k2) = (r0(i,k2)*h(i,k2) + r0_dn*h_to_dn) * i_hdn
2076 t(i,k2-1) = (t(i,k2)*h(i,k2-1) + t_up*h_to_up) * i_hup
2077 t(i,k2) = (t(i,k2)*h(i,k2) + t_dn*h_to_dn) * i_hdn
2078 s(i,k2-1) = (s(i,k2)*h(i,k2-1) + s_up*h_to_up) * i_hup
2079 s(i,k2) = (s(i,k2)*h(i,k2) + s_dn*h_to_dn) * i_hdn
2080 rcv(i,k2-1) = (rcv(i,k2)*h(i,k2-1) + rcvtgt(k2-1)*h_to_up) * i_hup
2081 rcv(i,k2) = (rcv(i,k2)*h(i,k2) + rcvtgt(k2)*h_to_dn) * i_hdn
2084 h(i,k2) = h(i,k2) + h_to_dn
2085 h(i,k2-1) = h(i,k2-1) + h_to_up
2088 d_eb(i,k) = d_eb(i,k) - h_to_up
2089 d_eb(i,k2-1) = d_eb(i,k2-1) + h_to_up
2090 elseif (k < k2-1)
then
2091 d_ea(i,k) = d_ea(i,k) - h_to_up
2092 d_ea(i,k2-1) = d_ea(i,k2-1) + h_to_up
2095 d_eb(i,k) = d_eb(i,k) - h_to_dn
2096 d_eb(i,k2) = d_eb(i,k2) + h_to_dn
2097 elseif (k < k2)
then
2098 d_ea(i,k) = d_ea(i,k) - h_to_dn
2099 d_ea(i,k2) = d_ea(i,k2) + h_to_dn
2106 do while (nks > nkmb)
2115 ks_min = -1 ; min_dpe = 1.0 ; min_hmin = 0.0
2117 k1 = ks2(ks) ; k2 = ks2(ks+1)
2118 dpe = max(0.0, (r0(i,k2)-r0(i,k1)) * h(i,k1) * h(i,k2))
2119 hmin = min(h(i,k1)-eps(i,k1), h(i,k2)-eps(i,k2))
2120 if ((ks_min < 0) .or. (dpe < min_dpe) .or. &
2121 ((dpe <= 0.0) .and. (hmin < min_hmin)))
then
2122 ks_min = ks ; min_dpe = dpe ; min_hmin = hmin
2127 k1 = ks2(ks_min) ; k2 = ks2(ks_min+1)
2128 if (k1 < k2)
then ; k_tgt = k1 ; k_src = k2
2129 else ; k_tgt = k2 ; k_src = k1 ; ks2(ks_min) = k2 ;
endif
2131 h_tgt_old = h(i,k_tgt)
2132 h_move = h(i,k_src)-eps(i,k_src)
2133 h(i,k_src) = eps(i,k_src)
2134 h(i,k_tgt) = h(i,k_tgt) + h_move
2135 i_hnew = 1.0 / (h(i,k_tgt))
2136 r0(i,k_tgt) = (r0(i,k_tgt)*h_tgt_old + r0(i,k_src)*h_move) * i_hnew
2138 t(i,k_tgt) = (t(i,k_tgt)*h_tgt_old + t(i,k_src)*h_move) * i_hnew
2139 s(i,k_tgt) = (s(i,k_tgt)*h_tgt_old + s(i,k_src)*h_move) * i_hnew
2140 rcv(i,k_tgt) = (rcv(i,k_tgt)*h_tgt_old + rcv(i,k_src)*h_move) * i_hnew
2142 d_eb(i,k_src) = d_eb(i,k_src) - h_move
2143 d_eb(i,k_tgt) = d_eb(i,k_tgt) + h_move
2146 do ks=ks_min+1,nks ; ks2(ks) = ks2(ks+1) ;
enddo
2153 do ks=1,nks-1 ;
if (ks2(ks) > ks2(ks+1)) sorted = .false. ;
enddo
2162 h_tmp(k) = h(i,k) ; r0_tmp(k) = r0(i,k)
2163 t_tmp(k) = t(i,k) ; s_tmp(k) = s(i,k) ; rcv_tmp(k) = rcv(i,k)
2169 k_tgt = nkmb - nks + ks ; k_src = ks2(ks)
2170 if (k_tgt == k_src)
then
2171 h(i,k_tgt) = h_tmp(k_tgt)
2176 if (k_src > nkmb)
then
2177 h_move = h(i,k_src)-eps(i,k_src)
2178 h(i,k_src) = eps(i,k_src)
2180 r0(i,k_tgt) = r0(i,k_src)
2182 t(i,k_tgt) = t(i,k_src) ; s(i,k_tgt) = s(i,k_src)
2183 rcv(i,k_tgt) = rcv(i,k_src)
2185 d_eb(i,k_src) = d_eb(i,k_src) - h_move
2186 d_eb(i,k_tgt) = d_eb(i,k_tgt) + h_move
2188 h(i,k_tgt) = h_tmp(k_src)
2189 r0(i,k_tgt) = r0_tmp(k_src)
2191 t(i,k_tgt) = t_tmp(k_src) ; s(i,k_tgt) = s_tmp(k_src)
2192 rcv(i,k_tgt) = rcv_tmp(k_src)
2194 if (k_src > k_tgt)
then
2195 d_eb(i,k_src) = d_eb(i,k_src) - h_tmp(k_src)
2196 d_eb(i,k_tgt) = d_eb(i,k_tgt) + h_tmp(k_src)
2198 d_ea(i,k_src) = d_ea(i,k_src) - h_tmp(k_src)
2199 d_ea(i,k_tgt) = d_ea(i,k_tgt) + h_tmp(k_src)
2207 end subroutine resort_ml
2212 subroutine mixedlayer_detrain_2(h, T, S, R0, Rcv, RcvTgt, dt, dt_diag, d_ea, j, G, GV, US, CS, &
2213 dR0_dT, dR0_dS, dRcv_dT, dRcv_dS, max_BL_det)
2216 real,
dimension(SZI_(G),SZK0_(GV)),
intent(inout) :: h
2218 real,
dimension(SZI_(G),SZK0_(GV)),
intent(inout) :: T
2219 real,
dimension(SZI_(G),SZK0_(GV)),
intent(inout) :: S
2220 real,
dimension(SZI_(G),SZK0_(GV)),
intent(inout) :: R0
2222 real,
dimension(SZI_(G),SZK0_(GV)),
intent(inout) :: Rcv
2224 real,
dimension(SZK_(GV)),
intent(in) :: RcvTgt
2226 real,
intent(in) :: dt
2227 real,
intent(in) :: dt_diag
2228 real,
dimension(SZI_(G),SZK_(GV)),
intent(inout) :: d_ea
2232 integer,
intent(in) :: j
2236 real,
dimension(SZI_(G)),
intent(in) :: dR0_dT
2240 real,
dimension(SZI_(G)),
intent(in) :: dR0_dS
2244 real,
dimension(SZI_(G)),
intent(in) :: dRcv_dT
2248 real,
dimension(SZI_(G)),
intent(in) :: dRcv_dS
2251 real,
dimension(SZI_(G)),
intent(in) :: max_BL_det
2279 real :: stays_min, stays_max
2282 logical :: mergeable_bl
2288 real :: stays_min_merge
2290 real :: dR0_2dz, dRcv_2dz
2299 real :: dPE_det, dPE_merge
2308 real :: h_det_to_h2, h_ml_to_h2
2309 real :: h_det_to_h1, h_ml_to_h1
2310 real :: h1_to_h2, h1_to_k0
2311 real :: h2_to_k1, h2_to_k1_rem
2316 real :: R0_det, T_det, S_det
2317 real :: Rcv_stays, R0_stays
2318 real :: T_stays, S_stays
2319 real :: dSpice_det, dSpice_stays
2323 real :: dSpice_lim, dSpice_lim2
2334 real :: dPE_time_ratio
2335 real :: dT_dS_gauge, dS_dT_gauge
2345 logical :: stable_Rcv
2354 real :: Ih, Ihdet, Ih1f, Ih2f
2355 real :: Ihk0, Ihk1, Ih12
2356 real :: dR1, dR2, dR2b, dRk1
2357 real :: dR0, dR21, dRcv
2358 real :: dRcv_stays, dRcv_det, dRcv_lim
2361 real :: h2_to_k1_lim, T_new, S_new, T_max, T_min, S_max, S_min
2362 character(len=200) :: mesg
2364 integer :: i, k, k0, k1, is, ie, nz, kb1, kb2, nkmb
2365 is = g%isc ; ie = g%iec ; nz = gv%ke
2366 kb1 = cs%nkml+1; kb2 = cs%nkml+2
2367 nkmb = cs%nkml+cs%nkbl
2368 h_neglect = gv%H_subroundoff
2369 g_2 = 0.5 * gv%g_Earth
2370 rho0xg = gv%Rho0 * gv%g_Earth
2371 idt_h2 = gv%H_to_Z**2 / dt_diag
2372 i2rho0 = 0.5 / (gv%Rho0)
2373 angstrom = gv%Angstrom_H
2376 dt_ds_gauge = cs%dT_dS_wt ; ds_dt_gauge = 1.0 / dt_ds_gauge
2379 if (cs%nkbl /= 2)
call mom_error(fatal,
"MOM_mixed_layer"// &
2380 "CS%nkbl must be 2 in mixedlayer_detrain_2.")
2382 if (dt < cs%BL_detrain_time)
then ; dpe_time_ratio = cs%BL_detrain_time / (dt)
2383 else ; dpe_time_ratio = 1.0 ;
endif
2392 h_to_bl = 0.0 ; r0_to_bl = 0.0
2393 rcv_to_bl = 0.0 ; t_to_bl = 0.0 ; s_to_bl = 0.0
2395 do k=1,cs%nkml ;
if (h(i,k) > 0.0)
then
2396 h_to_bl = h_to_bl + h(i,k)
2397 r0_to_bl = r0_to_bl + r0(i,k)*h(i,k)
2399 rcv_to_bl = rcv_to_bl + rcv(i,k)*h(i,k)
2400 t_to_bl = t_to_bl + t(i,k)*h(i,k)
2401 s_to_bl = s_to_bl + s(i,k)*h(i,k)
2403 d_ea(i,k) = d_ea(i,k) - h(i,k)
2406 if (h_to_bl > 0.0)
then ; r0_det = r0_to_bl / h_to_bl
2407 else ; r0_det = r0(i,0) ;
endif
2429 h_min_bl = min(cs%Hbuffer_min, cs%Hbuffer_rel_min*h(i,0))
2432 if (((r0(i,kb2)-r0(i,kb1)) * (rcv(i,kb2)-rcv(i,kb1)) <= 0.0)) &
2433 stable_rcv = .false.
2435 h1 = h(i,kb1) ; h2 = h(i,kb2)
2437 h2_to_k1_rem = (h1 + h2) + h_to_bl
2438 if ((max_bl_det(i) >= 0.0) .and. (h2_to_k1_rem > max_bl_det(i))) &
2439 h2_to_k1_rem = max_bl_det(i)
2442 if ((h2 == 0.0) .and. (h1 > 0.0))
then
2451 do k1=kb2+1,nz ;
if (h(i,k1) > 2.0*angstrom)
exit ;
enddo
2453 r0(i,kb2) = r0(i,kb1)
2455 rcv(i,kb2)=rcv(i,kb1) ; t(i,kb2)=t(i,kb1) ; s(i,kb2)=s(i,kb1)
2458 if (k1 <= nz)
then ;
if (r0(i,k1) >= r0(i,kb1))
then
2459 r0(i,kb2) = 0.5*(r0(i,kb1)+r0(i,k1))
2461 rcv(i,kb2) = 0.5*(rcv(i,kb1)+rcv(i,k1))
2462 t(i,kb2) = 0.5*(t(i,kb1)+t(i,k1))
2463 s(i,kb2) = 0.5*(s(i,kb1)+s(i,k1))
2467 dpe_extrap = 0.0 ; dpe_merge = 0.0
2468 mergeable_bl = .false.
2469 if ((h1 > 0.0) .and. (h2 > 0.0) .and. (h_to_bl > 0.0) .and. &
2476 do k1=kb2+1,nz ;
if (rcvtgt(k1) >= rcv(i,kb2))
exit ;
enddo ; k0 = k1-1
2477 dr1 = rcvtgt(k0)-rcv(i,kb1) ; dr2 = rcv(i,kb2)-rcvtgt(k0)
2483 h1_avail = h1 - max(0.0,h_min_bl-h_to_bl)
2484 if ((k1<=nz) .and. (h2 > h_min_bl) .and. (h1_avail > 0.0) .and. &
2485 (r0(i,kb1) < r0(i,kb2)) .and. (h_to_bl*r0(i,kb1) > r0_to_bl))
then
2486 drk1 = (rcvtgt(k1) - rcv(i,kb2)) * (r0(i,kb2) - r0(i,kb1)) / &
2487 (rcv(i,kb2) - rcv(i,kb1))
2488 b1 = drk1 / (r0(i,kb2) - r0(i,kb1))
2494 h2_to_k1 = min(h2 - h_min_bl, h2_to_k1_rem)
2497 if (h2_to_k1*(h1_avail + b1*(h1_avail + h2)) > h2*h1_avail) &
2498 h2_to_k1 = (h2*h1_avail) / (h1_avail + b1*(h1_avail + h2))
2499 if (h2_to_k1*(drk1 * h2) > (h_to_bl*r0(i,kb1) - r0_to_bl) * h1) &
2500 h2_to_k1 = (h_to_bl*r0(i,kb1) - r0_to_bl) * h1 / (drk1 * h2)
2502 if ((k1==kb2+1) .and. (cs%BL_extrap_lim > 0.))
then
2505 drcv_lim = rcv(i,kb2)-rcv(i,0)
2506 do k=1,kb2 ; drcv_lim = max(drcv_lim, rcv(i,kb2)-rcv(i,k)) ;
enddo
2507 drcv_lim = cs%BL_extrap_lim*drcv_lim
2508 if ((rcvtgt(k1) - rcv(i,kb2)) >= drcv_lim)
then
2510 elseif ((rcvtgt(k1) - rcv(i,kb2)) > 0.5*drcv_lim)
then
2511 h2_to_k1 = h2_to_k1 * (2.0 - 2.0*((rcvtgt(k1) - rcv(i,kb2)) / drcv_lim))
2515 drcv = (rcvtgt(k1) - rcv(i,kb2))
2520 dspice_det = (ds_dt_gauge*drcv_ds(i)*(t(i,kb2)-t(i,kb1)) - &
2521 dt_ds_gauge*drcv_dt(i)*(s(i,kb2)-s(i,kb1))) * &
2522 (h2 - h2_to_k1) / (h1 + h2)
2524 if (h(i,k1) > 10.0*angstrom)
then
2525 dspice_lim = ds_dt_gauge*drcv_ds(i)*(t(i,k1)-t(i,kb2)) - &
2526 dt_ds_gauge*drcv_dt(i)*(s(i,k1)-s(i,kb2))
2527 if (dspice_det*dspice_lim <= 0.0) dspice_lim = 0.0
2529 if (k1<nz)
then ;
if (h(i,k1+1) > 10.0*angstrom)
then
2530 dspice_lim2 = ds_dt_gauge*drcv_ds(i)*(t(i,k1+1)-t(i,kb2)) - &
2531 dt_ds_gauge*drcv_dt(i)*(s(i,k1+1)-s(i,kb2))
2532 if ((dspice_det*dspice_lim2 > 0.0) .and. &
2533 (abs(dspice_lim2) > abs(dspice_lim))) dspice_lim = dspice_lim2
2535 if (abs(dspice_det) > abs(dspice_lim)) dspice_det = dspice_lim
2537 i_denom = 1.0 / (drcv_ds(i)**2 + (dt_ds_gauge*drcv_dt(i))**2)
2538 t_det = t(i,kb2) + dt_ds_gauge * i_denom * &
2539 (dt_ds_gauge * drcv_dt(i) * drcv + drcv_ds(i) * dspice_det)
2540 s_det = s(i,kb2) + i_denom * &
2541 (drcv_ds(i) * drcv - dt_ds_gauge * drcv_dt(i) * dspice_det)
2543 r0_det = r0(i,kb2) + (t_det-t(i,kb2)) * dr0_dt(i) + &
2544 (s_det-s(i,kb2)) * dr0_ds(i)
2546 if (cs%BL_extrap_lim >= 0.)
then
2549 if (h(i,k1) > 10.0*angstrom)
then
2550 t_min = min(t(i,kb1), t(i,kb2), t(i,k1)) - cs%Allowed_T_chg
2551 t_max = max(t(i,kb1), t(i,kb2), t(i,k1)) + cs%Allowed_T_chg
2552 s_min = min(s(i,kb1), s(i,kb2), s(i,k1)) - cs%Allowed_S_chg
2553 s_max = max(s(i,kb1), s(i,kb2), s(i,k1)) + cs%Allowed_S_chg
2555 t_min = min(t(i,kb1), t(i,kb2)) - cs%Allowed_T_chg
2556 t_max = max(t(i,kb1), t(i,kb2)) + cs%Allowed_T_chg
2557 s_min = min(s(i,kb1), s(i,kb2)) - cs%Allowed_S_chg
2558 s_max = max(s(i,kb1), s(i,kb2)) + cs%Allowed_S_chg
2560 ihk1 = 1.0 / (h(i,k1) + h2_to_k1)
2561 t_new = (h(i,k1)*t(i,k1) + h2_to_k1*t_det) * ihk1
2562 s_new = (h(i,k1)*s(i,k1) + h2_to_k1*s_det) * ihk1
2564 if ((t_new < t_min) .or. (t_new > t_max) .or. &
2565 (s_new < s_min) .or. (s_new > s_max)) &
2569 h1_to_h2 = b1*h2*h2_to_k1 / (h2 - (1.0+b1)*h2_to_k1)
2571 ihk1 = 1.0 / (h(i,k1) + h_neglect + h2_to_k1)
2572 ih2f = 1.0 / ((h(i,kb2) - h2_to_k1) + h1_to_h2)
2574 rcv(i,kb2) = ((h(i,kb2)*rcv(i,kb2) - h2_to_k1*rcvtgt(k1)) + &
2575 h1_to_h2*rcv(i,kb1))*ih2f
2576 rcv(i,k1) = ((h(i,k1)+h_neglect)*rcv(i,k1) + h2_to_k1*rcvtgt(k1)) * ihk1
2578 t(i,kb2) = ((h(i,kb2)*t(i,kb2) - h2_to_k1*t_det) + &
2579 h1_to_h2*t(i,kb1)) * ih2f
2580 t(i,k1) = ((h(i,k1)+h_neglect)*t(i,k1) + h2_to_k1*t_det) * ihk1
2582 s(i,kb2) = ((h(i,kb2)*s(i,kb2) - h2_to_k1*s_det) + &
2583 h1_to_h2*s(i,kb1)) * ih2f
2584 s(i,k1) = ((h(i,k1)+h_neglect)*s(i,k1) + h2_to_k1*s_det) * ihk1
2587 r0(i,kb2) = ((h(i,kb2)*r0(i,kb2) - h2_to_k1*r0_det) + &
2588 h1_to_h2*r0(i,kb1)) * ih2f
2589 r0(i,k1) = ((h(i,k1)+h_neglect)*r0(i,k1) + h2_to_k1*r0_det) * ihk1
2591 h(i,kb1) = h(i,kb1) - h1_to_h2 ; h1 = h(i,kb1)
2592 h(i,kb2) = (h(i,kb2) - h2_to_k1) + h1_to_h2 ; h2 = h(i,kb2)
2593 h(i,k1) = h(i,k1) + h2_to_k1
2595 d_ea(i,kb1) = d_ea(i,kb1) - h1_to_h2
2596 d_ea(i,kb2) = (d_ea(i,kb2) - h2_to_k1) + h1_to_h2
2597 d_ea(i,k1) = d_ea(i,k1) + h2_to_k1
2598 h2_to_k1_rem = max(h2_to_k1_rem - h2_to_k1, 0.0)
2602 if ((k1>kb2+1) .and. (rcvtgt(k1-1) >= rcv(i,kb2)))
then
2603 do k1=k1,kb2+1,-1 ;
if (rcvtgt(k1-1) < rcv(i,kb2))
exit ;
enddo
2608 dr1 = rcvtgt(k0)-rcv(i,kb1) ; dr2 = rcv(i,kb2)-rcvtgt(k0)
2610 if ((k0>kb2) .and. (dr1 > 0.0) .and. (h1 > h_min_bl) .and. &
2611 (h2*dr2 < h1*dr1) .and. (r0(i,kb2) > r0(i,kb1)))
then
2616 stays_merge = 2.0*(h1+h2)*(h1*dr1 - h2*dr2) / &
2617 ((dr1+dr2)*h1 + dr1*(h1+h2) + &
2618 sqrt((dr2*h1-dr1*h2)**2 + 4*(h1+h2)*h2*(dr1+dr2)*dr2))
2620 stays_min_merge = max(h_min_bl, 2.0*h_min_bl - h_to_bl, &
2621 h1 - (h1+h2)*(r0(i,kb1) - r0_det) / (r0(i,kb2) - r0(i,kb1)))
2622 if ((stays_merge > stays_min_merge) .and. &
2623 (stays_merge + h2_to_k1_rem >= h1 + h2))
then
2624 mergeable_bl = .true.
2625 dpe_merge = g_2*(r0(i,kb2)-r0(i,kb1))*(h1-stays_merge)*(h2-stays_merge)
2629 if ((k1<=nz).and.(.not.mergeable_bl))
then
2633 dr2b = rcvtgt(k1)-rcv(i,kb2) ; dr21 = rcv(i,kb2) - rcv(i,kb1)
2634 if (dr2b*(h1+h2) < h2*dr21)
then
2636 h2_to_k1 = min(h2 - (h1+h2) * dr2b / dr21, h2_to_k1_rem)
2638 if (h2 > h2_to_k1)
then
2639 drcv = (rcvtgt(k1) - rcv(i,kb2))
2644 dspice_det = (ds_dt_gauge*drcv_ds(i)*(t(i,kb2)-t(i,kb1)) - &
2645 dt_ds_gauge*drcv_dt(i)*(s(i,kb2)-s(i,kb1))) * &
2646 (h2 - h2_to_k1) / (h1 + h2)
2648 if (h(i,k1) > 10.0*angstrom)
then
2649 dspice_lim = ds_dt_gauge*drcv_ds(i)*(t(i,k1)-t(i,kb2)) - &
2650 dt_ds_gauge*drcv_dt(i)*(s(i,k1)-s(i,kb2))
2651 if (dspice_det*dspice_lim <= 0.0) dspice_lim = 0.0
2653 if (k1<nz) then;
if (h(i,k1+1) > 10.0*angstrom)
then
2654 dspice_lim2 = ds_dt_gauge*drcv_ds(i)*(t(i,k1+1)-t(i,kb2)) - &
2655 dt_ds_gauge*drcv_dt(i)*(s(i,k1+1)-s(i,kb2))
2656 if ((dspice_det*dspice_lim2 > 0.0) .and. &
2657 (abs(dspice_lim2) > abs(dspice_lim))) dspice_lim = dspice_lim2
2659 if (abs(dspice_det) > abs(dspice_lim)) dspice_det = dspice_lim
2661 i_denom = 1.0 / (drcv_ds(i)**2 + (dt_ds_gauge*drcv_dt(i))**2)
2662 t_det = t(i,kb2) + dt_ds_gauge * i_denom * &
2663 (dt_ds_gauge * drcv_dt(i) * drcv + drcv_ds(i) * dspice_det)
2664 s_det = s(i,kb2) + i_denom * &
2665 (drcv_ds(i) * drcv - dt_ds_gauge * drcv_dt(i) * dspice_det)
2667 r0_det = r0(i,kb2) + (t_det-t(i,kb2)) * dr0_dt(i) + &
2668 (s_det-s(i,kb2)) * dr0_ds(i)
2673 ih2f = 1.0 / (h2 - h2_to_k1)
2675 t_min = min(t(i,kb2), t(i,kb1)) - cs%Allowed_T_chg
2676 t_max = max(t(i,kb2), t(i,kb1)) + cs%Allowed_T_chg
2677 t_new = (h2*t(i,kb2) - h2_to_k1*t_det)*ih2f
2678 if (t_new < t_min)
then
2679 h2_to_k1_lim = h2 * (t(i,kb2) - t_min) / (t_det - t_min)
2686 h2_to_k1 = h2_to_k1_lim
2687 ih2f = 1.0 / (h2 - h2_to_k1)
2688 elseif (t_new > t_max)
then
2689 h2_to_k1_lim = h2 * (t(i,kb2) - t_max) / (t_det - t_max)
2696 h2_to_k1 = h2_to_k1_lim
2697 ih2f = 1.0 / (h2 - h2_to_k1)
2699 s_min = max(min(s(i,kb2), s(i,kb1)) - cs%Allowed_S_chg, 0.0)
2700 s_max = max(s(i,kb2), s(i,kb1)) + cs%Allowed_S_chg
2701 s_new = (h2*s(i,kb2) - h2_to_k1*s_det)*ih2f
2702 if (s_new < s_min)
then
2703 h2_to_k1_lim = h2 * (s(i,kb2) - s_min) / (s_det - s_min)
2710 h2_to_k1 = h2_to_k1_lim
2711 ih2f = 1.0 / (h2 - h2_to_k1)
2712 elseif (s_new > s_max)
then
2713 h2_to_k1_lim = h2 * (s(i,kb2) - s_max) / (s_det - s_max)
2720 h2_to_k1 = h2_to_k1_lim
2721 ih2f = 1.0 / (h2 - h2_to_k1)
2724 ihk1 = 1.0 / (h(i,k1) + h_neglect + h2_to_k1)
2725 rcv(i,k1) = ((h(i,k1)+h_neglect)*rcv(i,k1) + h2_to_k1*rcvtgt(k1)) * ihk1
2726 rcv(i,kb2) = rcv(i,kb2) - h2_to_k1*drcv*ih2f
2728 t(i,kb2) = (h2*t(i,kb2) - h2_to_k1*t_det)*ih2f
2729 t(i,k1) = ((h(i,k1)+h_neglect)*t(i,k1) + h2_to_k1*t_det) * ihk1
2731 s(i,kb2) = (h2*s(i,kb2) - h2_to_k1*s_det) * ih2f
2732 s(i,k1) = ((h(i,k1)+h_neglect)*s(i,k1) + h2_to_k1*s_det) * ihk1
2735 r0(i,kb2) = (h2*r0(i,kb2) - h2_to_k1*r0_det) * ih2f
2736 r0(i,k1) = ((h(i,k1)+h_neglect)*r0(i,k1) + h2_to_k1*r0_det) * ihk1
2741 ihk1 = 1.0 / (h(i,k1) + h2)
2743 rcv(i,k1) = (h(i,k1)*rcv(i,k1) + h2*rcv(i,kb2)) * ihk1
2744 t(i,k1) = (h(i,k1)*t(i,k1) + h2*t(i,kb2)) * ihk1
2745 s(i,k1) = (h(i,k1)*s(i,k1) + h2*s(i,kb2)) * ihk1
2746 r0(i,k1) = (h(i,k1)*r0(i,k1) + h2*r0(i,kb2)) * ihk1
2749 h(i,k1) = h(i,k1) + h2_to_k1
2750 h(i,kb2) = h(i,kb2) - h2_to_k1 ; h2 = h(i,kb2)
2752 dpe_extrap = i2rho0*(r0_det-r0(i,kb2))*h2_to_k1*h2
2754 d_ea(i,kb2) = d_ea(i,kb2) - h2_to_k1
2755 d_ea(i,k1) = d_ea(i,k1) + h2_to_k1
2756 h2_to_k1_rem = max(h2_to_k1_rem - h2_to_k1, 0.0)
2763 h_det_h2 = max(h_min_bl-(h1+h2), 0.0)
2764 if (h_det_h2 > 0.0)
then
2770 h_det_to_h2 = min(h_to_bl, h_det_h2)
2771 h_ml_to_h2 = h_det_h2 - h_det_to_h2
2772 h_det_to_h1 = h_to_bl - h_det_to_h2
2773 h_ml_to_h1 = max(h_min_bl-h_det_to_h1,0.0)
2776 ihdet = 0.0 ;
if (h_to_bl > 0.0) ihdet = 1.0 / h_to_bl
2777 ih1f = 1.0 / (h_det_to_h1 + h_ml_to_h1)
2779 r0(i,kb2) = ((h2*r0(i,kb2) + h1*r0(i,kb1)) + &
2780 (h_det_to_h2*r0_to_bl*ihdet + h_ml_to_h2*r0(i,0))) * ih
2781 r0(i,kb1) = (h_det_to_h1*r0_to_bl*ihdet + h_ml_to_h1*r0(i,0)) * ih1f
2783 rcv(i,kb2) = ((h2*rcv(i,kb2) + h1*rcv(i,kb1)) + &
2784 (h_det_to_h2*rcv_to_bl*ihdet + h_ml_to_h2*rcv(i,0))) * ih
2785 rcv(i,kb1) = (h_det_to_h1*rcv_to_bl*ihdet + h_ml_to_h1*rcv(i,0)) * ih1f
2787 t(i,kb2) = ((h2*t(i,kb2) + h1*t(i,kb1)) + &
2788 (h_det_to_h2*t_to_bl*ihdet + h_ml_to_h2*t(i,0))) * ih
2789 t(i,kb1) = (h_det_to_h1*t_to_bl*ihdet + h_ml_to_h1*t(i,0)) * ih1f
2791 s(i,kb2) = ((h2*s(i,kb2) + h1*s(i,kb1)) + &
2792 (h_det_to_h2*s_to_bl*ihdet + h_ml_to_h2*s(i,0))) * ih
2793 s(i,kb1) = (h_det_to_h1*s_to_bl*ihdet + h_ml_to_h1*s(i,0)) * ih1f
2796 d_ea(i,1) = d_ea(i,1) - (h_ml_to_h1 + h_ml_to_h2)
2797 d_ea(i,kb1) = d_ea(i,kb1) + ((h_det_to_h1 + h_ml_to_h1) - h1)
2798 d_ea(i,kb2) = d_ea(i,kb2) + (h_min_bl - h2)
2800 h(i,kb1) = h_det_to_h1 + h_ml_to_h1 ; h(i,kb2) = h_min_bl
2801 h(i,0) = h(i,0) - (h_ml_to_h1 + h_ml_to_h2)
2804 if (
allocated(cs%diag_PE_detrain) .or.
allocated(cs%diag_PE_detrain2))
then
2805 r0_det = r0_to_bl*ihdet
2806 s1en = g_2 * idt_h2 * ( ((r0(i,kb2)-r0(i,kb1))*h1*h2 + &
2807 h_det_to_h2*( (r0(i,kb1)-r0_det)*h1 + (r0(i,kb2)-r0_det)*h2 ) + &
2808 h_ml_to_h2*( (r0(i,kb2)-r0(i,0))*h2 + (r0(i,kb1)-r0(i,0))*h1 + &
2809 (r0_det-r0(i,0))*h_det_to_h2 ) + &
2810 h_det_to_h1*h_ml_to_h1*(r0_det-r0(i,0))) - 2.0*gv%Rho0*dpe_extrap )
2812 if (
allocated(cs%diag_PE_detrain)) &
2813 cs%diag_PE_detrain(i,j) = cs%diag_PE_detrain(i,j) + s1en
2815 if (
allocated(cs%diag_PE_detrain2)) cs%diag_PE_detrain2(i,j) = &
2816 cs%diag_PE_detrain2(i,j) + s1en + idt_h2*rho0xg*dpe_extrap
2819 elseif ((h_to_bl > 0.0) .or. (h1 < h_min_bl) .or. (h2 < h_min_bl))
then
2824 h_from_ml = h_min_bl + max(h_min_bl-h2,0.0) - h1 - h_to_bl
2825 if (h_from_ml > 0.0)
then
2828 dpe_extrap = dpe_extrap - i2rho0*h_from_ml*(r0_to_bl - r0(i,0)*h_to_bl)
2829 r0_to_bl = r0_to_bl + h_from_ml*r0(i,0)
2830 rcv_to_bl = rcv_to_bl + h_from_ml*rcv(i,0)
2831 t_to_bl = t_to_bl + h_from_ml*t(i,0)
2832 s_to_bl = s_to_bl + h_from_ml*s(i,0)
2834 h_to_bl = h_to_bl + h_from_ml
2835 h(i,0) = h(i,0) - h_from_ml
2836 d_ea(i,1) = d_ea(i,1) - h_from_ml
2841 if (r0(i,kb2) - r0(i,kb1) > 1.0e-9*abs(r0(i,kb1) - r0_det)) &
2842 b1 = abs(r0(i,kb1) - r0_det) / (r0(i,kb2) - r0(i,kb1))
2843 stays_min = max((1.0-b1)*h1 - b1*h2, 0.0, h_min_bl - h_to_bl)
2844 stays_max = h1 - max(h_min_bl-h2,0.0)
2847 if (stays_max <= stays_min)
then
2849 mergeable_bl = .false.
2850 if (stays_max < h1) scale_slope = (h1 - stays_min) / (h1 - stays_max)
2855 i_ya = (h1 + h2) / ((h1 + h2) + h_to_bl)
2857 s1 = 0.5*(h1 + (h2 - bh0) * i_ya) ; s2 = h1 - s1
2862 s3sq = i_ya*max(bh0*h1-dpe_extrap, 0.0)
2864 s3sq = i_ya*(bh0*h1-min(dpe_extrap,0.0))
2867 if (s3sq == 0.0)
then
2870 elseif (s2*s2 <= s3sq)
then
2878 if (bh0 <= 0.0)
then ; stays = h1
2879 elseif (s2 > 0.0)
then
2881 if (s1 >= stays_max)
then ; stays = stays_max
2882 elseif (s1 >= 0.0)
then ; stays = s1 + sqrt(s2*s2 - s3sq)
2883 else ; stays = (h1*(s2-s1) - s3sq) / (-s1 + sqrt(s2*s2 - s3sq))
2887 if (s1 <= stays_min)
then ; stays = stays_min
2888 else ; stays = (h1*(s1-s2) + s3sq) / (s1 + sqrt(s2*s2 - s3sq))
2897 if (stays >= stays_max)
then ; stays = stays_max
2898 elseif (stays < stays_min)
then ; stays = stays_min
2902 dpe_det = g_2*((r0(i,kb1)*h_to_bl - r0_to_bl)*stays + &
2903 (r0(i,kb2)-r0(i,kb1)) * (h1-stays) * &
2904 (h2 - scale_slope*stays*((h1+h2)+h_to_bl)/(h1+h2)) ) - &
2907 if (dpe_time_ratio*h_to_bl > h_to_bl+h(i,0))
then
2908 dpe_ratio = (h_to_bl+h(i,0)) / h_to_bl
2910 dpe_ratio = dpe_time_ratio
2913 if ((mergeable_bl) .and. (num_events*dpe_ratio*dpe_det > dpe_merge))
then
2918 h1_to_k0 = (h1-stays_merge)
2919 stays = max(h_min_bl-h_to_bl,0.0)
2920 h1_to_h2 = stays_merge - stays
2922 ihk0 = 1.0 / ((h1_to_k0 + h2) + h(i,k0))
2923 ih1f = 1.0 / (h_to_bl + stays); ih2f = 1.0 / h1_to_h2
2924 ih12 = 1.0 / (h1 + h2)
2926 drcv_2dz = (rcv(i,kb1) - rcv(i,kb2)) * ih12
2927 drcv_stays = drcv_2dz*(h1_to_k0 + h1_to_h2)
2928 drcv_det = - drcv_2dz*(stays + h1_to_h2)
2929 rcv(i,k0) = ((h1_to_k0*(rcv(i,kb1) + drcv_det) + &
2930 h2*rcv(i,kb2)) + h(i,k0)*rcv(i,k0)) * ihk0
2931 rcv(i,kb2) = rcv(i,kb1) + drcv_2dz*(h1_to_k0-stays)
2932 rcv(i,kb1) = (rcv_to_bl + stays*(rcv(i,kb1) + drcv_stays)) * ih1f
2937 i_denom = 1.0 / (drcv_ds(i)**2 + (dt_ds_gauge*drcv_dt(i))**2)
2938 dspice_2dz = (ds_dt_gauge*drcv_ds(i)*(t(i,kb1)-t(i,kb2)) - &
2939 dt_ds_gauge*drcv_dt(i)*(s(i,kb1)-s(i,kb2))) * ih12
2940 dspice_lim = (ds_dt_gauge*dr0_ds(i)*(t_to_bl-t(i,kb1)*h_to_bl) - &
2941 dt_ds_gauge*dr0_dt(i)*(s_to_bl-s(i,kb1)*h_to_bl)) / h_to_bl
2942 if (dspice_lim * dspice_2dz <= 0.0) dspice_2dz = 0.0
2944 if (stays > 0.0)
then
2946 if (abs(dspice_lim) < abs(dspice_2dz*(h1_to_k0 + h1_to_h2))) &
2947 dspice_2dz = dspice_lim/(h1_to_k0 + h1_to_h2)
2949 dspice_stays = dspice_2dz*(h1_to_k0 + h1_to_h2)
2950 t_stays = t(i,kb1) + dt_ds_gauge * i_denom * &
2951 (dt_ds_gauge * drcv_dt(i) * drcv_stays + drcv_ds(i) * dspice_stays)
2952 s_stays = s(i,kb1) + i_denom * &
2953 (drcv_ds(i) * drcv_stays - dt_ds_gauge * drcv_dt(i) * dspice_stays)
2955 r0_stays = r0(i,kb1) + (t_stays-t(i,kb1)) * dr0_dt(i) + &
2956 (s_stays-s(i,kb1)) * dr0_ds(i)
2959 if (abs(dspice_lim) < abs(dspice_2dz*h1_to_k0)) &
2960 dspice_2dz = dspice_lim/h1_to_k0
2962 t_stays = 0.0 ; s_stays = 0.0 ; r0_stays = 0.0
2965 dspice_det = - dspice_2dz*(stays + h1_to_h2)
2966 t_det = t(i,kb1) + dt_ds_gauge * i_denom * &
2967 (dt_ds_gauge * drcv_dt(i) * drcv_det + drcv_ds(i) * dspice_det)
2968 s_det = s(i,kb1) + i_denom * &
2969 (drcv_ds(i) * drcv_det - dt_ds_gauge * drcv_dt(i) * dspice_det)
2971 r0_det = r0(i,kb1) + (t_det-t(i,kb1)) * dr0_dt(i) + &
2972 (s_det-s(i,kb1)) * dr0_ds(i)
2974 t(i,k0) = ((h1_to_k0*t_det + h2*t(i,kb2)) + h(i,k0)*t(i,k0)) * ihk0
2975 t(i,kb2) = (h1*t(i,kb1) - stays*t_stays - h1_to_k0*t_det) * ih2f
2976 t(i,kb1) = (t_to_bl + stays*t_stays) * ih1f
2978 s(i,k0) = ((h1_to_k0*s_det + h2*s(i,kb2)) + h(i,k0)*s(i,k0)) * ihk0
2979 s(i,kb2) = (h1*s(i,kb1) - stays*s_stays - h1_to_k0*s_det) * ih2f
2980 s(i,kb1) = (s_to_bl + stays*s_stays) * ih1f
2982 r0(i,k0) = ((h1_to_k0*r0_det + h2*r0(i,kb2)) + h(i,k0)*r0(i,k0)) * ihk0
2983 r0(i,kb2) = (h1*r0(i,kb1) - stays*r0_stays - h1_to_k0*r0_det) * ih2f
2984 r0(i,kb1) = (r0_to_bl + stays*r0_stays) * ih1f
3006 d_ea(i,kb1) = (d_ea(i,kb1) + h_to_bl) + (stays - h1)
3007 d_ea(i,kb2) = d_ea(i,kb2) + (h1_to_h2 - h2)
3008 d_ea(i,k0) = d_ea(i,k0) + (h1_to_k0 + h2)
3010 h(i,kb1) = stays + h_to_bl
3012 h(i,k0) = h(i,k0) + (h1_to_k0 + h2)
3013 if (
allocated(cs%diag_PE_detrain)) &
3014 cs%diag_PE_detrain(i,j) = cs%diag_PE_detrain(i,j) + idt_h2*dpe_merge
3015 if (
allocated(cs%diag_PE_detrain2)) cs%diag_PE_detrain2(i,j) = &
3016 cs%diag_PE_detrain2(i,j) + idt_h2*(dpe_det + rho0xg*dpe_extrap)
3021 h1_to_h2 = h1 - stays
3022 ih1f = 1.0 / (h_to_bl + stays) ; ih2f = 1.0 / (h2 + h1_to_h2)
3023 ih = 1.0 / (h1 + h2)
3024 dr0_2dz = (r0(i,kb1) - r0(i,kb2)) * ih
3025 r0(i,kb2) = (h2*r0(i,kb2) + h1_to_h2*(r0(i,kb1) - &
3026 scale_slope*dr0_2dz*stays)) * ih2f
3027 r0(i,kb1) = (r0_to_bl + stays*(r0(i,kb1) + &
3028 scale_slope*dr0_2dz*h1_to_h2)) * ih1f
3033 dr0 = scale_slope*dr0_2dz*h1_to_h2
3034 dspice_stays = (ds_dt_gauge*dr0_ds(i)*(t(i,kb1)-t(i,kb2)) - &
3035 dt_ds_gauge*dr0_dt(i)*(s(i,kb1)-s(i,kb2))) * &
3036 scale_slope*h1_to_h2 * ih
3037 if (h_to_bl > 0.0)
then
3038 dspice_lim = (ds_dt_gauge*dr0_ds(i)*(t_to_bl-t(i,kb1)*h_to_bl) - &
3039 dt_ds_gauge*dr0_dt(i)*(s_to_bl-s(i,kb1)*h_to_bl)) /&
3042 dspice_lim = ds_dt_gauge*dr0_ds(i)*(t(i,0)-t(i,kb1)) - &
3043 dt_ds_gauge*dr0_dt(i)*(s(i,0)-s(i,kb1))
3045 if (dspice_stays*dspice_lim <= 0.0)
then
3047 elseif (abs(dspice_stays) > abs(dspice_lim))
then
3048 dspice_stays = dspice_lim
3050 i_denom = 1.0 / (dr0_ds(i)**2 + (dt_ds_gauge*dr0_dt(i))**2)
3051 t_stays = t(i,kb1) + dt_ds_gauge * i_denom * &
3052 (dt_ds_gauge * dr0_dt(i) * dr0 + dr0_ds(i) * dspice_stays)
3053 s_stays = s(i,kb1) + i_denom * &
3054 (dr0_ds(i) * dr0 - dt_ds_gauge * dr0_dt(i) * dspice_stays)
3056 rcv_stays = rcv(i,kb1) + (t_stays-t(i,kb1)) * drcv_dt(i) + &
3057 (s_stays-s(i,kb1)) * drcv_ds(i)
3059 t(i,kb2) = (h2*t(i,kb2) + h1*t(i,kb1) - t_stays*stays) * ih2f
3060 t(i,kb1) = (t_to_bl + stays*t_stays) * ih1f
3061 s(i,kb2) = (h2*s(i,kb2) + h1*s(i,kb1) - s_stays*stays) * ih2f
3062 s(i,kb1) = (s_to_bl + stays*s_stays) * ih1f
3063 rcv(i,kb2) = (h2*rcv(i,kb2) + h1*rcv(i,kb1) - rcv_stays*stays) * ih2f
3064 rcv(i,kb1) = (rcv_to_bl + stays*rcv_stays) * ih1f
3083 d_ea(i,kb1) = d_ea(i,kb1) + ((stays - h1) + h_to_bl)
3084 d_ea(i,kb2) = d_ea(i,kb2) + h1_to_h2
3086 h(i,kb1) = stays + h_to_bl
3087 h(i,kb2) = h(i,kb2) + h1_to_h2
3089 if (
allocated(cs%diag_PE_detrain)) &
3090 cs%diag_PE_detrain(i,j) = cs%diag_PE_detrain(i,j) + idt_h2*dpe_det
3091 if (
allocated(cs%diag_PE_detrain2)) cs%diag_PE_detrain2(i,j) = &
3092 cs%diag_PE_detrain2(i,j) + idt_h2*(dpe_det + rho0xg*dpe_extrap)
3098 end subroutine mixedlayer_detrain_2
3103 subroutine mixedlayer_detrain_1(h, T, S, R0, Rcv, RcvTgt, dt, dt_diag, d_ea, d_eb, &
3104 j, G, GV, US, CS, dRcv_dT, dRcv_dS, max_BL_det)
3107 real,
dimension(SZI_(G),SZK0_(GV)),
intent(inout) :: h
3109 real,
dimension(SZI_(G),SZK0_(GV)),
intent(inout) :: T
3110 real,
dimension(SZI_(G),SZK0_(GV)),
intent(inout) :: S
3111 real,
dimension(SZI_(G),SZK0_(GV)),
intent(inout) :: R0
3113 real,
dimension(SZI_(G),SZK0_(GV)),
intent(inout) :: Rcv
3115 real,
dimension(SZK_(GV)),
intent(in) :: RcvTgt
3117 real,
intent(in) :: dt
3118 real,
intent(in) :: dt_diag
3120 real,
dimension(SZI_(G),SZK_(GV)),
intent(inout) :: d_ea
3124 real,
dimension(SZI_(G),SZK_(GV)),
intent(inout) :: d_eb
3128 integer,
intent(in) :: j
3132 real,
dimension(SZI_(G)),
intent(in) :: dRcv_dT
3136 real,
dimension(SZI_(G)),
intent(in) :: dRcv_dS
3139 real,
dimension(SZI_(G)),
intent(in) :: max_BL_det
3147 real :: max_det_rem(SZI_(G))
3148 real :: detrain(SZI_(G))
3150 real :: dT_dR, dS_dR, dRml, dR0_dRcv, dT_dS_wt2
3152 real :: Sdown, Tdown
3154 real :: g_H2_2Rho0dt
3161 logical :: splittable_BL(SZI_(G)), orthogonal_extrap
3164 integer :: i, is, ie, k, k1, nkmb, nz
3165 is = g%isc ; ie = g%iec ; nz = gv%ke
3166 nkmb = cs%nkml+cs%nkbl
3167 if (cs%nkbl /= 1)
call mom_error(fatal,
"MOM_mixed_layer: "// &
3168 "CS%nkbl must be 1 in mixedlayer_detrain_1.")
3170 dt_time = dt / cs%BL_detrain_time
3171 g_h2_2rho0dt = (gv%g_Earth * gv%H_to_Z**2) / (2.0 * gv%Rho0 * dt_diag)
3172 g_h2_2dt = (gv%g_Earth * gv%H_to_Z**2) / (2.0 * dt_diag)
3176 do i=is,ie ;
if (h(i,k) > 0.0)
then
3177 ih = 1.0 / (h(i,nkmb) + h(i,k))
3178 if (cs%TKE_diagnostics) &
3179 cs%diag_TKE_conv_s2(i,j) = cs%diag_TKE_conv_s2(i,j) + &
3180 g_h2_2rho0dt * h(i,k) * h(i,nkmb) * (r0(i,nkmb) - r0(i,k))
3181 if (
allocated(cs%diag_PE_detrain)) &
3182 cs%diag_PE_detrain(i,j) = cs%diag_PE_detrain(i,j) + &
3183 g_h2_2dt * h(i,k) * h(i,nkmb) * (r0(i,nkmb) - r0(i,k))
3184 if (
allocated(cs%diag_PE_detrain2)) &
3185 cs%diag_PE_detrain2(i,j) = cs%diag_PE_detrain2(i,j) + &
3186 g_h2_2dt * h(i,k) * h(i,nkmb) * (r0(i,nkmb) - r0(i,k))
3188 r0(i,nkmb) = (r0(i,nkmb)*h(i,nkmb) + r0(i,k)*h(i,k)) * ih
3189 rcv(i,nkmb) = (rcv(i,nkmb)*h(i,nkmb) + rcv(i,k)*h(i,k)) * ih
3190 t(i,nkmb) = (t(i,nkmb)*h(i,nkmb) + t(i,k)*h(i,k)) * ih
3191 s(i,nkmb) = (s(i,nkmb)*h(i,nkmb) + s(i,k)*h(i,k)) * ih
3193 d_ea(i,k) = d_ea(i,k) - h(i,k)
3194 d_ea(i,nkmb) = d_ea(i,nkmb) + h(i,k)
3195 h(i,nkmb) = h(i,nkmb) + h(i,k)
3201 max_det_rem(i) = 10.0 * h(i,nkmb)
3202 if (max_bl_det(i) >= 0.0) max_det_rem(i) = max_bl_det(i)
3217 do i=is,ie ;
if (h(i,nkmb) > 0.0)
then
3218 if ((r0(i,0)<r0(i,nz)) .and. (r0(i,nz)<r0(i,nkmb)))
then
3219 if ((r0(i,nz)-r0(i,0))*h(i,0) > &
3220 (r0(i,nkmb)-r0(i,nz))*h(i,nkmb))
then
3221 detrain(i) = (r0(i,nkmb)-r0(i,nz))*h(i,nkmb) / (r0(i,nkmb)-r0(i,0))
3223 detrain(i) = (r0(i,nz)-r0(i,0))*h(i,0) / (r0(i,nkmb)-r0(i,0))
3226 d_eb(i,cs%nkml) = d_eb(i,cs%nkml) + detrain(i)
3227 d_ea(i,cs%nkml) = d_ea(i,cs%nkml) - detrain(i)
3228 d_eb(i,nkmb) = d_eb(i,nkmb) - detrain(i)
3229 d_ea(i,nkmb) = d_ea(i,nkmb) + detrain(i)
3231 if (
allocated(cs%diag_PE_detrain)) cs%diag_PE_detrain(i,j) = &
3232 cs%diag_PE_detrain(i,j) + g_h2_2dt * detrain(i)* &
3233 (h(i,0) + h(i,nkmb)) * (r0(i,nkmb) - r0(i,0))
3235 r0(i,0) = r0(i,0) - detrain(i)*(r0(i,0)-r0(i,nkmb)) / h(i,0)
3236 r0(i,nkmb) = r0(i,nkmb) - detrain(i)*(r0(i,nkmb)-x1) / h(i,nkmb)
3238 rcv(i,0) = rcv(i,0) - detrain(i)*(rcv(i,0)-rcv(i,nkmb)) / h(i,0)
3239 rcv(i,nkmb) = rcv(i,nkmb) - detrain(i)*(rcv(i,nkmb)-x1) / h(i,nkmb)
3241 t(i,0) = t(i,0) - detrain(i)*(t(i,0)-t(i,nkmb)) / h(i,0)
3242 t(i,nkmb) = t(i,nkmb) - detrain(i)*(t(i,nkmb)-x1) / h(i,nkmb)
3244 s(i,0) = s(i,0) - detrain(i)*(s(i,0)-s(i,nkmb)) / h(i,0)
3245 s(i,nkmb) = s(i,nkmb) - detrain(i)*(s(i,nkmb)-x1) / h(i,nkmb)
3255 if (h(i,nkmb) > 0.0)
then ; splittable_bl(i) = .true.
3256 else ; splittable_bl(i) = .false. ;
endif
3259 dt_ds_wt2 = cs%dT_dS_wt**2
3261 do k=nz-1,nkmb+1,-1 ;
do i=is,ie
3262 if (splittable_bl(i))
then
3263 if (rcvtgt(k)<=rcv(i,nkmb))
then
3268 splittable_bl(i) = .false.
3270 k1 = k+1 ; orthogonal_extrap = .false.
3275 if ((h(i,k+1) < 10.0*gv%Angstrom_H) .or. &
3276 ((rcvtgt(k+1)-rcv(i,nkmb)) >= 0.9*(rcv(i,k1) - rcv(i,0))))
then
3277 if (k>=nz-1)
then ; orthogonal_extrap = .true.
3278 elseif ((h(i,k+2) <= 10.0*gv%Angstrom_H) .and. &
3279 ((rcvtgt(k+1)-rcv(i,nkmb)) < 0.9*(rcv(i,k+2)-rcv(i,0))))
then
3281 else ; orthogonal_extrap = .true. ;
endif
3284 if ((r0(i,0) >= r0(i,k1)) .or. (rcv(i,0) >= rcv(i,nkmb))) cycle
3288 if (orthogonal_extrap)
then
3292 i_denom = 1.0 / (drcv_ds(i)**2 + dt_ds_wt2*drcv_dt(i)**2)
3293 dt_dr = dt_ds_wt2*drcv_dt(i) * i_denom
3294 ds_dr = drcv_ds(i) * i_denom
3296 dt_dr = (t(i,0) - t(i,k1)) / (rcv(i,0) - rcv(i,k1))
3297 ds_dr = (s(i,0) - s(i,k1)) / (rcv(i,0) - rcv(i,k1))
3299 drml = dt_time * (r0(i,nkmb) - r0(i,0)) * &
3300 (rcv(i,0) - rcv(i,k1)) / (r0(i,0) - r0(i,k1))
3302 if (drml < 0.0) cycle
3303 dr0_drcv = (r0(i,0) - r0(i,k1)) / (rcv(i,0) - rcv(i,k1))
3305 if ((rcv(i,nkmb) - drml < rcvtgt(k)) .and. (max_det_rem(i) > h(i,nkmb)))
then
3307 detrain(i) = h(i,nkmb)*(rcv(i,nkmb) - rcvtgt(k)) / &
3308 (rcvtgt(k+1) - rcvtgt(k))
3310 if (
allocated(cs%diag_PE_detrain)) cs%diag_PE_detrain(i,j) = &
3311 cs%diag_PE_detrain(i,j) - g_h2_2dt * detrain(i) * &
3312 (h(i,nkmb)-detrain(i)) * (rcvtgt(k+1) - rcvtgt(k)) * dr0_drcv
3314 tdown = detrain(i) * (t(i,nkmb) + dt_dr*(rcvtgt(k+1)-rcv(i,nkmb)))
3315 t(i,k) = (h(i,k) * t(i,k) + &
3316 (h(i,nkmb) * t(i,nkmb) - tdown)) / &
3317 (h(i,k) + (h(i,nkmb) - detrain(i)))
3318 t(i,k+1) = (h(i,k+1) * t(i,k+1) + tdown)/ &
3319 (h(i,k+1) + detrain(i))
3321 sdown = detrain(i) * (s(i,nkmb) + ds_dr*(rcvtgt(k+1)-rcv(i,nkmb)))
3322 s(i,k) = (h(i,k) * s(i,k) + &
3323 (h(i,nkmb) * s(i,nkmb) - sdown)) / &
3324 (h(i,k) + (h(i,nkmb) - detrain(i)))
3325 s(i,k+1) = (h(i,k+1) * s(i,k+1) + sdown)/ &
3326 (h(i,k+1) + detrain(i))
3328 rcv(i,nkmb) = rcv(i,0)
3330 d_ea(i,k+1) = d_ea(i,k+1) + detrain(i)
3331 d_ea(i,k) = d_ea(i,k) + (h(i,nkmb) - detrain(i))
3332 d_ea(i,nkmb) = d_ea(i,nkmb) - h(i,nkmb)
3334 h(i,k+1) = h(i,k+1) + detrain(i)
3335 h(i,k) = h(i,k) + h(i,nkmb) - detrain(i)
3339 detrain(i) = h(i,nkmb) * drml / (rcvtgt(k+1) - rcv(i,nkmb) + drml)
3340 if (detrain(i) > max_det_rem(i)) detrain(i) = max_det_rem(i)
3341 ih = 1.0 / (h(i,k+1) + detrain(i))
3343 tdown = (t(i,nkmb) + dt_dr*(rcvtgt(k+1)-rcv(i,nkmb)))
3344 t(i,nkmb) = t(i,nkmb) - dt_dr * drml
3345 t(i,k+1) = (h(i,k+1) * t(i,k+1) + detrain(i) * tdown) * ih
3346 sdown = (s(i,nkmb) + ds_dr*(rcvtgt(k+1)-rcv(i,nkmb)))
3350 s(i,nkmb) = s(i,nkmb) - ds_dr * drml
3351 s(i,k+1) = (h(i,k+1) * s(i,k+1) + detrain(i) * sdown) * ih
3353 d_ea(i,k+1) = d_ea(i,k+1) + detrain(i)
3354 d_ea(i,nkmb) = d_ea(i,nkmb) - detrain(i)
3356 h(i,k+1) = h(i,k+1) + detrain(i)
3357 h(i,nkmb) = h(i,nkmb) - detrain(i)
3359 if (
allocated(cs%diag_PE_detrain)) cs%diag_PE_detrain(i,j) = &
3360 cs%diag_PE_detrain(i,j) - g_h2_2dt * detrain(i) * dr0_drcv * &
3361 (h(i,nkmb)-detrain(i)) * (rcvtgt(k+1) - rcv(i,nkmb) + drml)
3372 if (h(i,nkmb) < 0.1*h(i,0))
then
3373 h_ent = 0.1*h(i,0) - h(i,nkmb)
3375 t(i,nkmb) = (h(i,nkmb)*t(i,nkmb) + h_ent*t(i,0)) * ih
3376 s(i,nkmb) = (h(i,nkmb)*s(i,nkmb) + h_ent*s(i,0)) * ih
3378 d_ea(i,1) = d_ea(i,1) - h_ent
3379 d_ea(i,nkmb) = d_ea(i,nkmb) + h_ent
3381 h(i,0) = h(i,0) - h_ent
3382 h(i,nkmb) = h(i,nkmb) + h_ent
3386 end subroutine mixedlayer_detrain_1
3389 subroutine bulkmixedlayer_init(Time, G, GV, US, param_file, diag, CS)
3390 type(time_type),
target,
intent(in) :: time
3396 type(
diag_ctrl),
target,
intent(inout) :: diag
3409 #include "version_variable.h"
3410 character(len=40) :: mdl =
"MOM_mixed_layer"
3411 real :: bl_detrain_time_dflt
3412 real :: omega_frac_dflt, ustar_min_dflt, hmix_min_m
3413 integer :: isd, ied, jsd, jed
3414 logical :: use_temperature, use_omega
3415 isd = g%isd ; ied = g%ied ; jsd = g%jsd ; jed = g%jed
3417 if (
associated(cs))
then
3418 call mom_error(warning,
"mixedlayer_init called with an associated"// &
3419 "associated control structure.")
3421 else ;
allocate(cs) ;
endif
3426 if (gv%nkml < 1)
return
3432 call log_param(param_file, mdl,
"NKML", cs%nkml, &
3433 "The number of sublayers within the mixed layer if "//&
3434 "BULKMIXEDLAYER is true.", units=
"nondim", default=2)
3435 cs%nkbl = gv%nk_rho_varies - gv%nkml
3436 call log_param(param_file, mdl,
"NKBL", cs%nkbl, &
3437 "The number of variable density buffer layers if "//&
3438 "BULKMIXEDLAYER is true.", units=
"nondim", default=2)
3439 call get_param(param_file, mdl,
"MSTAR", cs%mstar, &
3440 "The ratio of the friction velocity cubed to the TKE "//&
3441 "input to the mixed layer.", units=
"nondim", default=1.2)
3442 call get_param(param_file, mdl,
"NSTAR", cs%nstar, &
3443 "The portion of the buoyant potential energy imparted by "//&
3444 "surface fluxes that is available to drive entrainment "//&
3445 "at the base of mixed layer when that energy is positive.", &
3446 units=
"nondim", default=0.15)
3447 call get_param(param_file, mdl,
"BULK_RI_ML", cs%bulk_Ri_ML, &
3448 "The efficiency with which mean kinetic energy released "//&
3449 "by mechanically forced entrainment of the mixed layer "//&
3450 "is converted to turbulent kinetic energy.", units=
"nondim",&
3451 fail_if_missing=.true.)
3452 call get_param(param_file, mdl,
"ABSORB_ALL_SW", cs%absorb_all_sw, &
3453 "If true, all shortwave radiation is absorbed by the "//&
3454 "ocean, instead of passing through to the bottom mud.", &
3456 call get_param(param_file, mdl,
"TKE_DECAY", cs%TKE_decay, &
3457 "TKE_DECAY relates the vertical rate of decay of the "//&
3458 "TKE available for mechanical entrainment to the natural "//&
3459 "Ekman depth.", units=
"nondim", default=2.5)
3460 call get_param(param_file, mdl,
"NSTAR2", cs%nstar2, &
3461 "The portion of any potential energy released by "//&
3462 "convective adjustment that is available to drive "//&
3463 "entrainment at the base of mixed layer. By default "//&
3464 "NSTAR2=NSTAR.", units=
"nondim", default=cs%nstar)
3465 call get_param(param_file, mdl,
"BULK_RI_CONVECTIVE", cs%bulk_Ri_convective, &
3466 "The efficiency with which convectively released mean "//&
3467 "kinetic energy is converted to turbulent kinetic "//&
3468 "energy. By default BULK_RI_CONVECTIVE=BULK_RI_ML.", &
3469 units=
"nondim", default=cs%bulk_Ri_ML)
3470 call get_param(param_file, mdl,
"HMIX_MIN", cs%Hmix_min, &
3471 "The minimum mixed layer depth if the mixed layer depth "//&
3472 "is determined dynamically.", units=
"m", default=0.0, scale=gv%m_to_H, &
3473 unscaled=hmix_min_m)
3475 call get_param(param_file, mdl,
"LIMIT_BUFFER_DETRAIN", cs%limit_det, &
3476 "If true, limit the detrainment from the buffer layers "//&
3477 "to not be too different from the neighbors.", default=.false.)
3478 call get_param(param_file, mdl,
"ALLOWED_DETRAIN_TEMP_CHG", cs%Allowed_T_chg, &
3479 "The amount by which temperature is allowed to exceed "//&
3480 "previous values during detrainment.", units=
"K", default=0.5)
3481 call get_param(param_file, mdl,
"ALLOWED_DETRAIN_SALT_CHG", cs%Allowed_S_chg, &
3482 "The amount by which salinity is allowed to exceed "//&
3483 "previous values during detrainment.", units=
"PSU", default=0.1)
3484 call get_param(param_file, mdl,
"ML_DT_DS_WEIGHT", cs%dT_dS_wt, &
3485 "When forced to extrapolate T & S to match the layer "//&
3486 "densities, this factor (in deg C / PSU) is combined "//&
3487 "with the derivatives of density with T & S to determine "//&
3488 "what direction is orthogonal to density contours. It "//&
3489 "should be a typical value of (dR/dS) / (dR/dT) in "//&
3490 "oceanic profiles.", units=
"degC PSU-1", default=6.0)
3491 call get_param(param_file, mdl,
"BUFFER_LAYER_EXTRAP_LIMIT", cs%BL_extrap_lim, &
3492 "A limit on the density range over which extrapolation "//&
3493 "can occur when detraining from the buffer layers, "//&
3494 "relative to the density range within the mixed and "//&
3495 "buffer layers, when the detrainment is going into the "//&
3496 "lightest interior layer, nondimensional, or a negative "//&
3497 "value not to apply this limit.", units=
"nondim", default = -1.0)
3498 call get_param(param_file, mdl,
"BUFFER_LAYER_HMIN_THICK", cs%Hbuffer_min, &
3499 "The minimum buffer layer thickness when the mixed layer is very thick.", &
3500 units=
"m", default=5.0, scale=gv%m_to_H)
3501 call get_param(param_file, mdl,
"BUFFER_LAYER_HMIN_REL", cs%Hbuffer_rel_min, &
3502 "The minimum buffer layer thickness relative to the combined mixed "//&
3503 "land buffer ayer thicknesses when they are thin.", &
3504 units=
"nondim", default=0.1/cs%nkbl)
3505 bl_detrain_time_dflt = 4.0*3600.0 ;
if (cs%nkbl==1) bl_detrain_time_dflt = 86400.0*30.0
3506 call get_param(param_file, mdl,
"BUFFER_LAY_DETRAIN_TIME", cs%BL_detrain_time, &
3507 "A timescale that characterizes buffer layer detrainment events.", &
3508 units=
"s", default=bl_detrain_time_dflt, scale=us%s_to_T)
3509 call get_param(param_file, mdl,
"BUFFER_SPLIT_RHO_TOL", cs%BL_split_rho_tol, &
3510 "The fractional tolerance for matching layer target densities when splitting "//&
3511 "layers to deal with massive interior layers that are lighter than one of the "//&
3512 "mixed or buffer layers.", units=
"nondim", default=0.1)
3514 call get_param(param_file, mdl,
"DEPTH_LIMIT_FLUXES", cs%H_limit_fluxes, &
3515 "The surface fluxes are scaled away when the total ocean "//&
3516 "depth is less than DEPTH_LIMIT_FLUXES.", &
3517 units=
"m", default=0.1*hmix_min_m, scale=gv%m_to_H)
3518 call get_param(param_file, mdl,
"OMEGA", cs%omega, &
3519 "The rotation rate of the earth.", &
3520 default=7.2921e-5, units=
"s-1", scale=us%T_to_s)
3521 call get_param(param_file, mdl,
"ML_USE_OMEGA", use_omega, &
3522 "If true, use the absolute rotation rate instead of the "//&
3523 "vertical component of rotation when setting the decay "//&
3524 "scale for turbulence.", default=.false., do_not_log=.true.)
3525 omega_frac_dflt = 0.0
3527 call mom_error(warning,
"ML_USE_OMEGA is depricated; use ML_OMEGA_FRAC=1.0 instead.")
3528 omega_frac_dflt = 1.0
3530 call get_param(param_file, mdl,
"ML_OMEGA_FRAC", cs%omega_frac, &
3531 "When setting the decay scale for turbulence, use this "//&
3532 "fraction of the absolute rotation rate blended with the "//&
3533 "local value of f, as sqrt((1-of)*f^2 + of*4*omega^2).", &
3534 units=
"nondim", default=omega_frac_dflt)
3535 call get_param(param_file, mdl,
"ML_RESORT", cs%ML_resort, &
3536 "If true, resort the topmost layers by potential density "//&
3537 "before the mixed layer calculations.", default=.false.)
3539 call get_param(param_file, mdl,
"ML_PRESORT_NK_CONV_ADJ", cs%ML_presort_nz_conv_adj, &
3540 "Convectively mix the first ML_PRESORT_NK_CONV_ADJ "//&
3541 "layers before sorting when ML_RESORT is true.", &
3542 units=
"nondim", default=0, fail_if_missing=.true.)
3544 ustar_min_dflt = 2e-4*us%s_to_T*cs%omega*(gv%Angstrom_m + gv%H_to_m*gv%H_subroundoff)
3545 call get_param(param_file, mdl,
"BML_USTAR_MIN", cs%ustar_min, &
3546 "The minimum value of ustar that should be used by the "//&
3547 "bulk mixed layer model in setting vertical TKE decay "//&
3548 "scales. This must be greater than 0.", units=
"m s-1", &
3549 default=ustar_min_dflt, scale=us%m_to_Z*us%T_to_s)
3550 if (cs%ustar_min<=0.0)
call mom_error(fatal,
"BML_USTAR_MIN must be positive.")
3552 call get_param(param_file, mdl,
"RESOLVE_EKMAN", cs%Resolve_Ekman, &
3553 "If true, the NKML>1 layers in the mixed layer are "//&
3554 "chosen to optimally represent the impact of the Ekman "//&
3555 "transport on the mixed layer TKE budget. Otherwise, "//&
3556 "the sublayers are distributed uniformly through the "//&
3557 "mixed layer.", default=.false.)
3558 call get_param(param_file, mdl,
"CORRECT_ABSORPTION_DEPTH", cs%correct_absorption, &
3559 "If true, the average depth at which penetrating shortwave "//&
3560 "radiation is absorbed is adjusted to match the average "//&
3561 "heating depth of an exponential profile by moving some "//&
3562 "of the heating upward in the water column.", default=.false.)
3563 call get_param(param_file, mdl,
"DO_RIVERMIX", cs%do_rivermix, &
3564 "If true, apply additional mixing wherever there is "//&
3565 "runoff, so that it is mixed down to RIVERMIX_DEPTH, "//&
3566 "if the ocean is that deep.", default=.false.)
3567 if (cs%do_rivermix) &
3568 call get_param(param_file, mdl,
"RIVERMIX_DEPTH", cs%rivermix_depth, &
3569 "The depth to which rivers are mixed if DO_RIVERMIX is "//&
3570 "defined.", units=
"m", default=0.0, scale=us%m_to_Z)
3571 call get_param(param_file, mdl,
"USE_RIVER_HEAT_CONTENT", cs%use_river_heat_content, &
3572 "If true, use the fluxes%runoff_Hflx field to set the "//&
3573 "heat carried by runoff, instead of using SST*CP*liq_runoff.", &
3575 call get_param(param_file, mdl,
"USE_CALVING_HEAT_CONTENT", cs%use_calving_heat_content, &
3576 "If true, use the fluxes%calving_Hflx field to set the "//&
3577 "heat carried by runoff, instead of using SST*CP*froz_runoff.", &
3579 call get_param(param_file, mdl,
"BULKML_CONV_MOMENTUM_BUG", cs%convect_mom_bug, &
3580 "If true, use code with a bug that causes a loss of momentum conservation "//&
3581 "during mixedlayer convection.", default=.false.)
3583 call get_param(param_file, mdl,
"ALLOW_CLOCKS_IN_OMP_LOOPS", &
3584 cs%allow_clocks_in_omp_loops, &
3585 "If true, clocks can be called from inside loops that can "//&
3586 "be threaded. To run with multiple threads, set to False.", &
3589 cs%id_ML_depth = register_diag_field(
'ocean_model',
'h_ML', diag%axesT1, &
3590 time,
'Surface mixed layer depth',
'm')
3591 cs%id_TKE_wind = register_diag_field(
'ocean_model',
'TKE_wind', diag%axesT1, &
3592 time,
'Wind-stirring source of mixed layer TKE', &
3593 'm3 s-3', conversion=us%Z_to_m*(us%L_to_m**2)*(us%s_to_T**3))
3594 cs%id_TKE_RiBulk = register_diag_field(
'ocean_model',
'TKE_RiBulk', diag%axesT1, &
3595 time,
'Mean kinetic energy source of mixed layer TKE', &
3596 'm3 s-3', conversion=us%Z_to_m*(us%L_to_m**2)*(us%s_to_T**3))
3597 cs%id_TKE_conv = register_diag_field(
'ocean_model',
'TKE_conv', diag%axesT1, &
3598 time,
'Convective source of mixed layer TKE', &
3599 'm3 s-3', conversion=us%Z_to_m*(us%L_to_m**2)*(us%s_to_T**3))
3600 cs%id_TKE_pen_SW = register_diag_field(
'ocean_model',
'TKE_pen_SW', diag%axesT1, &
3601 time,
'TKE consumed by mixing penetrative shortwave radation through the mixed layer', &
3602 'm3 s-3', conversion=us%Z_to_m*(us%L_to_m**2)*(us%s_to_T**3))
3603 cs%id_TKE_mixing = register_diag_field(
'ocean_model',
'TKE_mixing', diag%axesT1, &
3604 time,
'TKE consumed by mixing that deepens the mixed layer', &
3605 'm3 s-3', conversion=us%Z_to_m*(us%L_to_m**2)*(us%s_to_T**3))
3606 cs%id_TKE_mech_decay = register_diag_field(
'ocean_model',
'TKE_mech_decay', diag%axesT1, &
3607 time,
'Mechanical energy decay sink of mixed layer TKE', &
3608 'm3 s-3', conversion=us%Z_to_m*(us%L_to_m**2)*(us%s_to_T**3))
3609 cs%id_TKE_conv_decay = register_diag_field(
'ocean_model',
'TKE_conv_decay', diag%axesT1, &
3610 time,
'Convective energy decay sink of mixed layer TKE', &
3611 'm3 s-3', conversion=us%Z_to_m*(us%L_to_m**2)*(us%s_to_T**3))
3612 cs%id_TKE_conv_s2 = register_diag_field(
'ocean_model',
'TKE_conv_s2', diag%axesT1, &
3613 time,
'Spurious source of mixed layer TKE from sigma2', &
3614 'm3 s-3', conversion=us%Z_to_m*(us%L_to_m**2)*(us%s_to_T**3))
3615 cs%id_PE_detrain = register_diag_field(
'ocean_model',
'PE_detrain', diag%axesT1, &
3616 time,
'Spurious source of potential energy from mixed layer detrainment', &
3617 'W m-2', conversion=us%RZ3_T3_to_W_m2*us%L_to_Z**2)
3618 cs%id_PE_detrain2 = register_diag_field(
'ocean_model',
'PE_detrain2', diag%axesT1, &
3619 time,
'Spurious source of potential energy from mixed layer only detrainment', &
3620 'W m-2', conversion=us%RZ3_T3_to_W_m2*us%L_to_Z**2)
3621 cs%id_h_mismatch = register_diag_field(
'ocean_model',
'h_miss_ML', diag%axesT1, &
3622 time,
'Summed absolute mismatch in entrainment terms',
'm', conversion=us%Z_to_m)
3623 cs%id_Hsfc_used = register_diag_field(
'ocean_model',
'Hs_used', diag%axesT1, &
3624 time,
'Surface region thickness that is used',
'm', conversion=us%Z_to_m)
3625 cs%id_Hsfc_max = register_diag_field(
'ocean_model',
'Hs_max', diag%axesT1, &
3626 time,
'Maximum surface region thickness',
'm', conversion=us%Z_to_m)
3627 cs%id_Hsfc_min = register_diag_field(
'ocean_model',
'Hs_min', diag%axesT1, &
3628 time,
'Minimum surface region thickness',
'm', conversion=us%Z_to_m)
3630 if (cs%limit_det .or. (cs%id_Hsfc_min > 0))
then
3631 call get_param(param_file, mdl,
"LIMIT_BUFFER_DET_DH_SFC", cs%lim_det_dH_sfc, &
3632 "The fractional limit in the change between grid points "//&
3633 "of the surface region (mixed & buffer layer) thickness.", &
3634 units=
"nondim", default=0.5)
3635 call get_param(param_file, mdl,
"LIMIT_BUFFER_DET_DH_BATHY", cs%lim_det_dH_bathy, &
3636 "The fraction of the total depth by which the thickness "//&
3637 "of the surface region (mixed & buffer layer) is allowed "//&
3638 "to change between grid points.", units=
"nondim", default=0.2)
3641 call get_param(param_file, mdl,
"ENABLE_THERMODYNAMICS", use_temperature, &
3642 "If true, temperature and salinity are used as state "//&
3643 "variables.", default=.true.)
3645 if (use_temperature)
then
3646 call get_param(param_file, mdl,
"PEN_SW_NBANDS", cs%nsw, default=1)
3650 if (max(cs%id_TKE_wind, cs%id_TKE_RiBulk, cs%id_TKE_conv, cs%id_TKE_mixing, &
3651 cs%id_TKE_pen_SW, cs%id_TKE_mech_decay, cs%id_TKE_conv_decay) > 0)
then
3652 call safe_alloc_alloc(cs%diag_TKE_wind, isd, ied, jsd, jed)
3653 call safe_alloc_alloc(cs%diag_TKE_RiBulk, isd, ied, jsd, jed)
3654 call safe_alloc_alloc(cs%diag_TKE_conv, isd, ied, jsd, jed)
3655 call safe_alloc_alloc(cs%diag_TKE_pen_SW, isd, ied, jsd, jed)
3656 call safe_alloc_alloc(cs%diag_TKE_mixing, isd, ied, jsd, jed)
3657 call safe_alloc_alloc(cs%diag_TKE_mech_decay, isd, ied, jsd, jed)
3658 call safe_alloc_alloc(cs%diag_TKE_conv_decay, isd, ied, jsd, jed)
3659 call safe_alloc_alloc(cs%diag_TKE_conv_s2, isd, ied, jsd, jed)
3661 cs%TKE_diagnostics = .true.
3663 if (cs%id_PE_detrain > 0)
call safe_alloc_alloc(cs%diag_PE_detrain, isd, ied, jsd, jed)
3664 if (cs%id_PE_detrain2 > 0)
call safe_alloc_alloc(cs%diag_PE_detrain2, isd, ied, jsd, jed)
3665 if (cs%id_ML_depth > 0)
call safe_alloc_alloc(cs%ML_depth, isd, ied, jsd, jed)
3667 if (cs%allow_clocks_in_omp_loops)
then
3668 id_clock_detrain = cpu_clock_id(
'(Ocean mixed layer detrain)', grain=clock_routine)
3669 id_clock_mech = cpu_clock_id(
'(Ocean mixed layer mechanical entrainment)', grain=clock_routine)
3670 id_clock_conv = cpu_clock_id(
'(Ocean mixed layer convection)', grain=clock_routine)
3671 if (cs%ML_resort)
then
3672 id_clock_resort = cpu_clock_id(
'(Ocean mixed layer resorting)', grain=clock_routine)
3674 id_clock_adjustment = cpu_clock_id(
'(Ocean mixed layer convective adjustment)', grain=clock_routine)
3676 id_clock_eos = cpu_clock_id(
'(Ocean mixed layer EOS)', grain=clock_routine)
3679 if (cs%limit_det .or. (cs%id_Hsfc_min > 0)) &
3680 id_clock_pass = cpu_clock_id(
'(Ocean mixed layer halo updates)', grain=clock_routine)
3686 end subroutine bulkmixedlayer_init
3693 function ef4(Ht, En, I_L, dR_de)
3694 real,
intent(in) :: ht
3695 real,
intent(in) :: en
3696 real,
intent(in) :: i_l
3697 real,
optional,
intent(inout) :: dr_de
3705 exp_lhpe = exp(-i_l*(en+ht))
3707 res = exp_lhpe * (en*i_hpe/ht - 0.5*i_l*log(ht*i_hpe) + 0.5*i_l*i_l*en)
3708 if (
PRESENT(dr_de)) &
3709 dr_de = -i_l*res + exp_lhpe*(i_hpe*i_hpe + 0.5*i_l*i_hpe + 0.5*i_l*i_l)