56 use mom_cpu_clock, only : cpu_clock_id, cpu_clock_begin, cpu_clock_end, clock_routine
69 implicit none ;
private 71 #include <MOM_memory.h> 85 logical :: absorb_all_sw
92 real :: bulk_ri_convective
95 real :: h_limit_fluxes
109 real :: bl_extrap_lim
117 integer :: ml_presort_nz_conv_adj
123 logical :: correct_absorption
127 logical :: resolve_ekman
130 type(time_type),
pointer :: time
131 logical :: tke_diagnostics = .false.
132 logical :: do_rivermix = .false.
134 real :: rivermix_depth = 0.0
137 real :: lim_det_dh_sfc
140 real :: lim_det_dh_bathy
144 logical :: use_river_heat_content
147 logical :: use_calving_heat_content
148 logical :: salt_reject_below_ml
152 real :: allowed_t_chg
154 real :: allowed_s_chg
158 real,
allocatable,
dimension(:,:) :: &
165 diag_tke_mech_decay, &
166 diag_tke_conv_decay, &
177 logical :: allow_clocks_in_omp_loops
180 type(group_pass_type) :: pass_h_sum_hmbl_prev
181 integer :: id_ml_depth = -1, id_tke_wind = -1, id_tke_mixing = -1
182 integer :: id_tke_ribulk = -1, id_tke_conv = -1, id_tke_pen_sw = -1
183 integer :: id_tke_mech_decay = -1, id_tke_conv_decay = -1, id_tke_conv_s2 = -1
184 integer :: id_pe_detrain = -1, id_pe_detrain2 = -1, id_h_mismatch = -1
185 integer :: id_hsfc_used = -1, id_hsfc_max = -1, id_hsfc_min = -1
225 subroutine bulkmixedlayer(h_3d, u_3d, v_3d, tv, fluxes, dt, ea, eb, G, GV, CS, &
226 optics, Hml, aggregate_FW_forcing, dt_diag, last_call)
229 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)), &
230 intent(inout) :: h_3d
233 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)), &
236 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)), &
242 type(
forcing),
intent(inout) :: fluxes
245 real,
intent(in) :: dt
246 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)), &
251 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)), &
261 real,
dimension(:,:),
pointer :: Hml
262 logical,
intent(in) :: aggregate_FW_forcing
263 real,
optional,
intent(in) :: dt_diag
266 logical,
optional,
intent(in) :: last_call
330 real,
dimension(SZI_(G),SZK_(GV)) :: &
339 real,
dimension(SZI_(G),SZK0_(GV)) :: &
345 real,
dimension(SZI_(G),SZK_(GV)) :: &
356 integer,
dimension(SZI_(G),SZK_(GV)) :: &
358 real,
dimension(SZI_(G),SZJ_(G)) :: &
360 real,
dimension(SZI_(G)) :: &
402 real,
dimension(max(CS%nsw,1),SZI_(G)) :: &
405 real,
dimension(max(CS%nsw,1),SZI_(G),SZK_(GV)) :: &
408 real :: cMKE(2,szi_(g))
411 real :: Inkml, Inkmlm1
417 real,
dimension(SZI_(G)) :: &
421 real,
dimension(SZI_(G),SZK_(GV)) :: &
426 real,
dimension(SZI_(G),SZJ_(G)) :: &
436 real,
dimension(SZI_(G)) :: &
448 logical :: write_diags
449 logical :: reset_diags
450 integer :: i, j, k, is, ie, js, je, nz, nkmb, n
453 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = gv%ke
455 if (.not.
associated(cs))
call mom_error(fatal,
"MOM_mixed_layer: "//&
456 "Module must be initialized before it is used.")
457 if (gv%nkml < 1)
return 459 if (.not.
ASSOCIATED(tv%eqn_of_state))
call mom_error(fatal, &
460 "MOM_mixed_layer: Temperature, salinity and an equation of state "//&
462 if (.NOT.
ASSOCIATED(fluxes%ustar))
call mom_error(fatal, &
463 "MOM_mixed_layer: No surface TKE fluxes (ustar) defined in mixedlayer!")
465 nkmb = cs%nkml+cs%nkbl
466 inkml = 1.0 /
REAL(cs%nkml)
467 if (cs%nkml > 1) inkmlm1 = 1.0 /
REAL(cs%nkml-1)
469 irho0 = 1.0 / gv%Rho0
470 dt__diag = dt ;
if (
present(dt_diag)) dt__diag = dt_diag
472 idt_diag = 1.0 / dt__diag
473 write_diags = .true. ;
if (
present(last_call)) write_diags = last_call
475 p_ref(:) = 0.0 ; p_ref_cv(:) = tv%P_Ref
480 if (cs%limit_det .or. (cs%id_Hsfc_min > 0))
then 483 do j=js-1,je+1 ;
do i=is-1,ie+1
484 h_sum(i,j) = 0.0 ; hmbl_prev(i,j) = 0.0
488 do k=1,nkmb ;
do i=is-1,ie+1
489 h_sum(i,j) = h_sum(i,j) + h_3d(i,j,k)
490 hmbl_prev(i,j) = hmbl_prev(i,j) + h_3d(i,j,k)
492 do k=nkmb+1,nz ;
do i=is-1,ie+1
493 h_sum(i,j) = h_sum(i,j) + h_3d(i,j,k)
507 if (
present(dt_diag) .and. write_diags .and. (dt__diag > dt)) &
508 reset_diags = .false.
510 if (reset_diags)
then 512 if (cs%TKE_diagnostics)
then 514 do j=js,je ;
do i=is,ie
515 cs%diag_TKE_wind(i,j) = 0.0 ; cs%diag_TKE_RiBulk(i,j) = 0.0
516 cs%diag_TKE_conv(i,j) = 0.0 ; cs%diag_TKE_pen_SW(i,j) = 0.0
517 cs%diag_TKE_mixing(i,j) = 0.0 ; cs%diag_TKE_mech_decay(i,j) = 0.0
518 cs%diag_TKE_conv_decay(i,j) = 0.0 ; cs%diag_TKE_conv_s2(i,j) = 0.0
521 if (
ALLOCATED(cs%diag_PE_detrain))
then 523 do j=js,je ;
do i=is,ie
524 cs%diag_PE_detrain(i,j) = 0.0
527 if (
ALLOCATED(cs%diag_PE_detrain2))
then 529 do j=js,je ;
do i=is,ie
530 cs%diag_PE_detrain2(i,j) = 0.0
536 if (cs%ML_resort)
then 537 do i=is,ie ; h_ca(i) = 0.0 ;
enddo 538 do k=1,nz ;
do i=is,ie ; dke_ca(i,k) = 0.0 ; ctke(i,k) = 0.0 ;
enddo ;
enddo 559 do k=1,nz ;
do i=is,ie
560 h(i,k) = h_3d(i,j,k) ; u(i,k) = u_3d(i,j,k) ; v(i,k) = v_3d(i,j,k)
561 h_orig(i,k) = h_3d(i,j,k)
562 eps(i,k) = 0.0 ;
if (k > nkmb) eps(i,k) = gv%Angstrom
563 t(i,k) = tv%T(i,j,k) ; s(i,k) = tv%S(i,j,k)
565 opacity_band(n,i,k) = gv%H_to_m*optics%opacity_band(n,i,j,k)
569 do k=1,nz ;
do i=is,ie
570 d_ea(i,k) = 0.0 ; d_eb(i,k) = 0.0
575 do i=is,ie ; p_ref(i) = 0.0 ;
enddo 576 do k=1,cs%nkml ;
do i=is,ie
577 p_ref(i) = p_ref(i) + 0.5*gv%H_to_Pa*h(i,k)
580 is, ie-is+1, tv%eqn_of_state)
582 is, ie-is+1, tv%eqn_of_state)
587 ie-is+1, tv%eqn_of_state)
591 if (cs%ML_resort)
then 593 if (cs%ML_presort_nz_conv_adj > 0) &
594 call convective_adjustment(h(:,1:), u, v, r0(:,1:), rcv(:,1:), t(:,1:), &
595 s(:,1:), eps, d_eb, dke_ca, ctke, j, g, gv, cs, &
596 cs%ML_presort_nz_conv_adj)
598 call sort_ml(h(:,1:), r0(:,1:), eps, g, gv, cs, ksort)
601 do k=1,nz ;
do i=is,ie ; ksort(i,k) = k ;
enddo ;
enddo 607 call convective_adjustment(h(:,1:), u, v, r0(:,1:), rcv(:,1:), t(:,1:), &
608 s(:,1:), eps, d_eb, dke_ca, ctke, j, g, gv, cs)
609 do i=is,ie ; h_ca(i) = h(i,1) ;
enddo 614 if (
associated(fluxes%lrunoff) .and. cs%do_rivermix)
then 626 rmixconst = 0.5*cs%rivermix_depth*gv%g_Earth*irho0**2
628 tke_river(i) = max(0.0, rmixconst*dr0_ds(i)* &
629 (fluxes%lrunoff(i,j) + fluxes%frunoff(i,j)) * s(i,1))
632 do i=is,ie ; tke_river(i) = 0.0 ;
enddo 646 cs%H_limit_fluxes, cs%use_river_heat_content, cs%use_calving_heat_content, &
647 h(:,1:), t(:,1:), netmassinout, netmassout, net_heat, net_salt, pen_sw_bnd,&
648 tv, aggregate_fw_forcing)
652 r0_tot, rcv_tot, u, v, t(:,1:), s(:,1:), &
653 r0(:,1:), rcv(:,1:), eps, &
654 dr0_dt, drcv_dt, dr0_ds, drcv_ds, &
655 netmassinout, netmassout, net_heat, net_salt, &
656 nsw, pen_sw_bnd, opacity_band, conv_en, &
657 dke_fc, j, ksort, g, gv, cs, tv, fluxes, dt, &
658 aggregate_fw_forcing)
671 tke, tke_river, idecay_len_tke, cmke, dt, idt_diag, &
676 r0_tot, rcv_tot, u, v, t(:,1:), s(:,1:), r0(:,1:), rcv(:,1:), eps, dr0_dt, drcv_dt, &
677 cmke, idt_diag, nsw, pen_sw_bnd, opacity_band, tke, &
678 idecay_len_tke, j, ksort, g, gv, cs)
680 call absorbremainingsw(g, gv, h(:,1:), opacity_band, nsw, j, dt, cs%H_limit_fluxes, &
681 cs%correct_absorption, cs%absorb_all_SW, &
682 t(:,1:), pen_sw_bnd, eps, ksort, htot, ttot)
684 if (cs%TKE_diagnostics)
then ;
do i=is,ie
685 cs%diag_TKE_mech_decay(i,j) = cs%diag_TKE_mech_decay(i,j) - idt_diag*tke(i)
690 do i=is,ie ;
if (htot(i) > 0.0)
then 692 r0(i,0) = r0_tot(i) * ih ; rcv(i,0) = rcv_tot(i) * ih
693 t(i,0) = ttot(i) * ih ; s(i,0) = stot(i) * ih
696 t(i,0) = t(i,1) ; s(i,0) = s(i,1) ; r0(i,0) = r0(i,1) ; rcv(i,0) = rcv(i,1)
699 if (write_diags .and.
ALLOCATED(cs%ML_depth))
then ;
do i=is,ie
700 cs%ML_depth(i,j) = h(i,0) * gv%H_to_m
702 if (
ASSOCIATED(hml))
then ;
do i=is,ie
703 hml(i,j) = g%mask2dT(i,j) * (h(i,0) * gv%H_to_m)
716 if (cs%ML_resort)
then 718 call resort_ml(h(:,0:), t(:,0:), s(:,0:), r0(:,0:), rcv(:,0:), gv%Rlay, eps, &
719 d_ea, d_eb, ksort, g, gv, cs, dr0_dt, dr0_ds, drcv_dt, drcv_ds)
723 if (cs%limit_det .or. (cs%id_Hsfc_max > 0) .or. (cs%id_Hsfc_min > 0))
then 724 do i=is,ie ; hsfc(i) = h(i,0) ;
enddo 725 do k=1,nkmb ;
do i=is,ie ; hsfc(i) = hsfc(i) + h(i,k) ;
enddo ;
enddo 727 if (cs%limit_det .or. (cs%id_Hsfc_min > 0))
then 728 dhsfc = cs%lim_det_dH_sfc ; dhd = cs%lim_det_dH_bathy
730 h_nbr = min(dhsfc*max(hmbl_prev(i-1,j), hmbl_prev(i+1,j), &
731 hmbl_prev(i,j-1), hmbl_prev(i,j+1)), &
732 max(hmbl_prev(i-1,j) - dhd*min(h_sum(i,j),h_sum(i-1,j)), &
733 hmbl_prev(i+1,j) - dhd*min(h_sum(i,j),h_sum(i+1,j)), &
734 hmbl_prev(i,j-1) - dhd*min(h_sum(i,j),h_sum(i,j-1)), &
735 hmbl_prev(i,j+1) - dhd*min(h_sum(i,j),h_sum(i,j+1))) )
737 hsfc_min(i,j) = gv%H_to_m*max(h(i,0), min(hsfc(i), h_nbr))
739 if (cs%limit_det) max_bl_det(i) = max(0.0, hsfc(i)-h_nbr)
743 if (cs%id_Hsfc_max > 0)
then ;
do i=is,ie
744 hsfc_max(i,j) = hsfc(i)*gv%H_to_m
752 if (cs%nkbl == 1)
then 753 call mixedlayer_detrain_1(h(:,0:), t(:,0:), s(:,0:), r0(:,0:), rcv(:,0:), &
754 gv%Rlay, dt, dt__diag, d_ea, d_eb, j, g, gv, cs, &
755 drcv_dt, drcv_ds, max_bl_det)
756 elseif (cs%nkbl == 2)
then 757 call mixedlayer_detrain_2(h(:,0:), t(:,0:), s(:,0:), r0(:,0:), rcv(:,0:), &
758 gv%Rlay, dt, dt__diag, d_ea, j, g, gv, cs, &
759 dr0_dt, dr0_ds, drcv_dt, drcv_ds, max_bl_det)
762 call mom_error(fatal,
"MOM_mixed_layer: CS%nkbl must be 1 or 2 for now.")
767 if (cs%id_Hsfc_used > 0)
then 768 do i=is,ie ; hsfc_used(i,j) = h(i,0)*gv%H_to_m ;
enddo 769 do k=cs%nkml+1,nkmb ;
do i=is,ie
770 hsfc_used(i,j) = hsfc_used(i,j) + h(i,k)*gv%H_to_m
776 if (cs%Resolve_Ekman .and. (cs%nkml>1))
then 785 ku_star = 0.41*fluxes%ustar(i,j)
786 if (
associated(fluxes%ustar_shelf) .and. &
787 associated(fluxes%frac_shelf_h))
then 788 if (fluxes%frac_shelf_h(i,j) > 0.0) &
789 ku_star = (1.0 - fluxes%frac_shelf_h(i,j)) * ku_star + &
790 fluxes%frac_shelf_h(i,j) * (0.41*fluxes%ustar_shelf(i,j))
792 absf_x_h = 0.25 * h(i,0) * &
793 ((abs(g%CoriolisBu(i,j)) + abs(g%CoriolisBu(i-1,j-1))) + &
794 (abs(g%CoriolisBu(i,j-1)) + abs(g%CoriolisBu(i-1,j))))
797 h_3d(i,j,1) = h(i,0) / (3.0 + sqrt(absf_x_h*(absf_x_h + 2.0*ku_star) / &
801 h_3d(i,j,k) = (h(i,0)-h_3d(i,j,1)) * inkmlm1
802 d_ea(i,k) = d_ea(i,k) + h_3d(i,j,k)
803 d_ea(i,1) = d_ea(i,1) - h_3d(i,j,k)
808 h_3d(i,j,1) = h(i,0) * inkml
810 do k=2,cs%nkml ;
do i=is,ie
811 h_3d(i,j,k) = h(i,0) * inkml
812 d_ea(i,k) = d_ea(i,k) + h_3d(i,j,k)
813 d_ea(i,1) = d_ea(i,1) - h_3d(i,j,k)
816 do i=is,ie ; h(i,0) = 0.0 ;
enddo 817 do k=1,cs%nkml ;
do i=is,ie
818 tv%T(i,j,k) = t(i,0) ; tv%S(i,j,k) = s(i,0)
834 eaml(i,nz) = (h(i,nz) - h_orig(i,nz)) - d_eb(i,nz)
836 do k=nz-1,1,-1 ;
do i=is,ie
837 ebml(i,k) = ebml(i,k+1) - d_eb(i,k+1)
838 eaml(i,k) = eaml(i,k+1) + d_ea(i,k)
840 do i=is,ie ; eaml(i,1) = netmassinout(i) ;
enddo 843 do k=cs%nkml+1,nz ;
do i=is,ie
844 h_3d(i,j,k) = h(i,k); tv%T(i,j,k) = t(i,k) ; tv%S(i,j,k) = s(i,k)
847 do k=1,nz ;
do i=is,ie
848 ea(i,j,k) = ea(i,j,k) + eaml(i,k)
849 eb(i,j,k) = eb(i,j,k) + ebml(i,k)
852 if (cs%id_h_mismatch > 0)
then 854 h_miss(i,j) = abs(h_3d(i,j,1) - (h_orig(i,1) + &
855 (eaml(i,1) + (ebml(i,1) - eaml(i,1+1)))))
857 do k=2,nz-1 ;
do i=is,ie
858 h_miss(i,j) = h_miss(i,j) + abs(h_3d(i,j,k) - (h_orig(i,k) + &
859 ((eaml(i,k) - ebml(i,k-1)) + (ebml(i,k) - eaml(i,k+1)))))
862 h_miss(i,j) = h_miss(i,j) + abs(h_3d(i,j,nz) - (h_orig(i,nz) + &
863 ((eaml(i,nz) - ebml(i,nz-1)) + ebml(i,nz))))
864 h_miss(i,j) = gv%H_to_m * h_miss(i,j)
877 if (write_diags)
then 878 if (cs%id_ML_depth > 0) &
879 call post_data(cs%id_ML_depth, cs%ML_depth, cs%diag)
880 if (cs%id_TKE_wind > 0) &
881 call post_data(cs%id_TKE_wind, cs%diag_TKE_wind, cs%diag)
882 if (cs%id_TKE_RiBulk > 0) &
883 call post_data(cs%id_TKE_RiBulk, cs%diag_TKE_RiBulk, cs%diag)
884 if (cs%id_TKE_conv > 0) &
885 call post_data(cs%id_TKE_conv, cs%diag_TKE_conv, cs%diag)
886 if (cs%id_TKE_pen_SW > 0) &
887 call post_data(cs%id_TKE_pen_SW, cs%diag_TKE_pen_SW, cs%diag)
888 if (cs%id_TKE_mixing > 0) &
889 call post_data(cs%id_TKE_mixing, cs%diag_TKE_mixing, cs%diag)
890 if (cs%id_TKE_mech_decay > 0) &
891 call post_data(cs%id_TKE_mech_decay, cs%diag_TKE_mech_decay, cs%diag)
892 if (cs%id_TKE_conv_decay > 0) &
893 call post_data(cs%id_TKE_conv_decay, cs%diag_TKE_conv_decay, cs%diag)
894 if (cs%id_TKE_conv_s2 > 0) &
895 call post_data(cs%id_TKE_conv_s2, cs%diag_TKE_conv_s2, cs%diag)
896 if (cs%id_PE_detrain > 0) &
897 call post_data(cs%id_PE_detrain, cs%diag_PE_detrain, cs%diag)
898 if (cs%id_PE_detrain2 > 0) &
899 call post_data(cs%id_PE_detrain2, cs%diag_PE_detrain2, cs%diag)
900 if (cs%id_h_mismatch > 0) &
901 call post_data(cs%id_h_mismatch, h_miss, cs%diag)
902 if (cs%id_Hsfc_used > 0) &
903 call post_data(cs%id_Hsfc_used, hsfc_used, cs%diag)
904 if (cs%id_Hsfc_max > 0) &
905 call post_data(cs%id_Hsfc_max, hsfc_max, cs%diag)
906 if (cs%id_Hsfc_min > 0) &
907 call post_data(cs%id_Hsfc_min, hsfc_min, cs%diag)
916 dKE_CA, cTKE, j, G, GV, CS, nz_conv)
919 real,
dimension(SZI_(G),SZK_(GV)),
intent(inout) :: h
922 real,
dimension(SZI_(G),SZK_(GV)),
intent(inout) :: u
924 real,
dimension(SZI_(G),SZK_(GV)),
intent(inout) :: v
926 real,
dimension(SZI_(G),SZK_(GV)),
intent(inout) :: T
927 real,
dimension(SZI_(G),SZK_(GV)),
intent(inout) :: S
928 real,
dimension(SZI_(G),SZK_(GV)),
intent(inout) :: R0
930 real,
dimension(SZI_(G),SZK_(GV)),
intent(inout) :: Rcv
932 real,
dimension(SZI_(G),SZK_(GV)),
intent(inout) :: d_eb
936 real,
dimension(SZI_(G),SZK_(GV)),
intent(in) :: eps
937 real,
dimension(SZI_(G),SZK_(GV)),
intent(out) :: dKE_CA
940 real,
dimension(SZI_(G),SZK_(GV)),
intent(out) :: cTKE
943 integer,
intent(in) :: j
945 integer,
optional,
intent(in) :: nz_conv
974 real,
dimension(SZI_(G)) :: &
995 integer :: is, ie, nz, i, k, k1, nzc, nkmb
997 is = g%isc ; ie = g%iec ; nz = gv%ke
998 g_h2_2rho0 = (gv%g_Earth * gv%H_to_m**2) / (2.0 * gv%Rho0)
999 nzc = nz ;
if (
present(nz_conv)) nzc = nz_conv
1000 nkmb = cs%nkml+cs%nkbl
1005 do k1=min(nzc-1,nkmb),1,-1
1007 h_orig_k1(i) = h(i,k1)
1008 ke_orig(i) = 0.5*h(i,k1)*(u(i,k1)**2 + v(i,k1)**2)
1009 uhtot(i) = h(i,k1)*u(i,k1) ; vhtot(i) = h(i,k1)*v(i,k1)
1010 r0_tot(i) = r0(i,k1) * h(i,k1)
1011 ctke(i,k1) = 0.0 ; dke_ca(i,k1) = 0.0
1013 rcv_tot(i) = rcv(i,k1) * h(i,k1)
1014 ttot(i) = t(i,k1) * h(i,k1) ; stot(i) = s(i,k1) * h(i,k1)
1018 if ((h(i,k) > eps(i,k)) .and. (r0_tot(i) > h(i,k1)*r0(i,k)))
then 1019 h_ent = h(i,k)-eps(i,k)
1020 ctke(i,k1) = ctke(i,k1) + (h_ent * g_h2_2rho0 * &
1021 (r0_tot(i) - h(i,k1)*r0(i,k)) * cs%nstar2)
1023 ctke(i,k1) = ctke(i,k1) + ctke(i,k)
1024 dke_ca(i,k1) = dke_ca(i,k1) + dke_ca(i,k)
1026 r0_tot(i) = r0_tot(i) + h_ent * r0(i,k)
1027 ke_orig(i) = ke_orig(i) + 0.5*h_ent* &
1028 (u(i,k)*u(i,k) + v(i,k)*v(i,k))
1029 uhtot(i) = uhtot(i) + h_ent*u(i,k)
1030 vhtot(i) = vhtot(i) + h_ent*v(i,k)
1032 rcv_tot(i) = rcv_tot(i) + h_ent * rcv(i,k)
1033 ttot(i) = ttot(i) + h_ent * t(i,k)
1034 stot(i) = stot(i) + h_ent * s(i,k)
1035 h(i,k1) = h(i,k1) + h_ent ; h(i,k) = eps(i,k)
1037 d_eb(i,k) = d_eb(i,k) - h_ent
1038 d_eb(i,k1) = d_eb(i,k1) + h_ent
1044 do i=is,ie ;
if (h(i,k1) > h_orig_k1(i))
then 1046 r0(i,k1) = r0_tot(i) * ih
1047 u(i,k1) = uhtot(i) * ih ; v(i,k1) = vhtot(i) * ih
1048 dke_ca(i,k1) = dke_ca(i,k1) + gv%H_to_m * (cs%bulk_Ri_convective * &
1049 (ke_orig(i) - 0.5*h(i,k1)*(u(i,k1)**2 + v(i,k1)**2)))
1050 rcv(i,k1) = rcv_tot(i) * ih
1051 t(i,k1) = ttot(i) * ih ; s(i,k1) = stot(i) * ih
1056 do k=2,min(nzc,nkmb) ;
do i=is,ie ;
if (h(i,k) == 0.0)
then 1058 rcv(i,k) = rcv(i,k-1) ; t(i,k) = t(i,k-1) ; s(i,k) = s(i,k-1)
1059 endif ;
enddo ;
enddo 1067 R0_tot, Rcv_tot, u, v, T, S, R0, Rcv, eps, &
1068 dR0_dT, dRcv_dT, dR0_dS, dRcv_dS, &
1069 netMassInOut, netMassOut, Net_heat, Net_salt, &
1070 nsw, Pen_SW_bnd, opacity_band, Conv_en, &
1071 dKE_FC, j, ksort, G, GV, CS, tv, fluxes, dt, &
1072 aggregate_FW_forcing)
1076 real,
dimension(SZI_(G),SZK_(GV)),
intent(inout) :: h
1079 real,
dimension(SZI_(G),SZK_(GV)),
intent(inout) :: d_eb
1083 real,
dimension(SZI_(G)),
intent(out) :: htot
1085 real,
dimension(SZI_(G)),
intent(out) :: Ttot
1087 real,
dimension(SZI_(G)),
intent(out) :: Stot
1089 real,
dimension(SZI_(G)),
intent(out) :: uhtot
1091 real,
dimension(SZI_(G)),
intent(out) :: vhtot
1093 real,
dimension(SZI_(G)),
intent(out) :: R0_tot
1096 real,
dimension(SZI_(G)),
intent(out) :: Rcv_tot
1099 real,
dimension(SZI_(G),SZK_(GV)),
intent(in) :: u, v, T, S, R0, Rcv, eps
1100 real,
dimension(SZI_(G)),
intent(in) :: dR0_dT, dRcv_dT, dR0_dS, dRcv_dS
1101 real,
dimension(SZI_(G)),
intent(in) :: netMassInOut, netMassOut
1102 real,
dimension(SZI_(G)),
intent(in) :: Net_heat, Net_salt
1103 integer,
intent(in) :: nsw
1105 real,
dimension(:,:),
intent(inout) :: Pen_SW_bnd
1109 real,
dimension(:,:,:),
intent(in) :: opacity_band
1110 real,
dimension(SZI_(G)),
intent(out) :: Conv_en
1113 real,
dimension(SZI_(G)),
intent(out) :: dKE_FC
1116 integer,
intent(in) :: j
1117 integer,
dimension(SZI_(G),SZK_(GV)), &
1122 type(
forcing),
intent(inout) :: fluxes
1123 real,
intent(in) :: dt
1124 logical,
intent(in) :: aggregate_FW_forcing
1155 real,
dimension(SZI_(G)) :: &
1160 real :: Pen_absorbed
1167 real :: En_fn, Frac, x1
1169 real :: dr_ent, dr_comp
1171 real :: h_min, h_max
1186 integer :: is, ie, nz, i, k, ks, itt, n
1187 real,
dimension(max(nsw,1)) :: &
1191 angstrom = gv%Angstrom
1192 c1_3 = 1.0/3.0 ; c1_6 = 1.0/6.0
1193 g_h2_2rho0 = (gv%g_Earth * gv%H_to_m**2) / (2.0 * gv%Rho0)
1195 is = g%isc ; ie = g%iec ; nz = gv%ke
1197 do i=is,ie ;
if (ksort(i,1) > 0)
then 1200 if (aggregate_fw_forcing)
then 1202 if (netmassinout(i) < 0.0) massoutrem(i) = -netmassinout(i)
1203 netmassin(i) = netmassinout(i) + massoutrem(i)
1205 massoutrem(i) = -netmassout(i)
1206 netmassin(i) = netmassinout(i) - netmassout(i)
1210 h_ent = max(min(angstrom,h(i,k)-eps(i,k)),0.0)
1211 htot(i) = h_ent + netmassin(i)
1212 h(i,k) = h(i,k) - h_ent
1213 d_eb(i,k) = d_eb(i,k) - h_ent
1216 do n=1,nsw ;
if (pen_sw_bnd(n,i) > 0.0)
then 1217 sw_trans = exp(-htot(i)*opacity_band(n,i,k))
1218 pen_absorbed = pen_absorbed + pen_sw_bnd(n,i) * (1.0-sw_trans)
1219 pen_sw_bnd(n,i) = pen_sw_bnd(n,i) * sw_trans
1226 ttot(i) = (net_heat(i) + (netmassin(i) * t_precip + h_ent * t(i,k))) + &
1234 stot(i) = h_ent*s(i,k) + net_salt(i)
1235 uhtot(i) = u(i,1)*netmassin(i) + u(i,k)*h_ent
1236 vhtot(i) = v(i,1)*netmassin(i) + v(i,k)*h_ent
1237 r0_tot(i) = (h_ent*r0(i,k) + netmassin(i)*r0(i,1)) + &
1239 (dr0_dt(i)*(net_heat(i) + pen_absorbed) - &
1240 dr0_ds(i) * (netmassin(i) * s(i,1) - net_salt(i)))
1241 rcv_tot(i) = (h_ent*rcv(i,k) + netmassin(i)*rcv(i,1)) + &
1243 (drcv_dt(i)*(net_heat(i) + pen_absorbed) - &
1244 drcv_ds(i) * (netmassin(i) * s(i,1) - net_salt(i)))
1245 conv_en(i) = 0.0 ; dke_fc(i) = 0.0
1246 if(
ASSOCIATED(fluxes%heat_content_massin)) &
1247 fluxes%heat_content_massin(i,j) = fluxes%heat_content_massin(i,j) &
1248 + t_precip * netmassin(i) * gv%H_to_kg_m2 * fluxes%C_p * idt
1249 if (
ASSOCIATED(tv%TempxPmE)) tv%TempxPmE(i,j) = tv%TempxPmE(i,j) + &
1250 t_precip * netmassin(i) * gv%H_to_kg_m2
1256 do i=is,ie ;
if (ksort(i,ks) > 0)
then 1259 if ((htot(i) < angstrom) .and. (h(i,k) > eps(i,k)))
then 1262 h_ent = min(angstrom-htot(i), h(i,k)-eps(i,k))
1263 htot(i) = htot(i) + h_ent
1264 h(i,k) = h(i,k) - h_ent
1265 d_eb(i,k) = d_eb(i,k) - h_ent
1267 r0_tot(i) = r0_tot(i) + h_ent*r0(i,k)
1268 uhtot(i) = uhtot(i) + h_ent*u(i,k)
1269 vhtot(i) = vhtot(i) + h_ent*v(i,k)
1271 rcv_tot(i) = rcv_tot(i) + h_ent*rcv(i,k)
1272 ttot(i) = ttot(i) + h_ent*t(i,k)
1273 stot(i) = stot(i) + h_ent*s(i,k)
1279 if ((massoutrem(i) > 0.0) .and. (h(i,k) > eps(i,k)))
then 1280 if (massoutrem(i) > (h(i,k) - eps(i,k)))
then 1281 h_evap = h(i,k) - eps(i,k)
1283 massoutrem(i) = massoutrem(i) - h_evap
1285 h_evap = massoutrem(i)
1286 h(i,k) = h(i,k) - h_evap
1290 stot(i) = stot(i) + h_evap*s(i,k)
1291 r0_tot(i) = r0_tot(i) + dr0_ds(i)*h_evap*s(i,k)
1292 rcv_tot(i) = rcv_tot(i) + drcv_ds(i)*h_evap*s(i,k)
1293 d_eb(i,k) = d_eb(i,k) - h_evap
1299 if(
ASSOCIATED(fluxes%heat_content_massout)) &
1300 fluxes%heat_content_massout(i,j) = fluxes%heat_content_massout(i,j) &
1301 - t(i,k)*h_evap*gv%H_to_kg_m2 * fluxes%C_p * idt
1302 if (
ASSOCIATED(tv%TempxPmE)) tv%TempxPmE(i,j) = tv%TempxPmE(i,j) - &
1303 t(i,k)*h_evap*gv%H_to_kg_m2
1308 h_avail = h(i,k) - eps(i,k)
1309 if (h_avail > 0.0)
then 1310 dr = r0_tot(i) - htot(i)*r0(i,k)
1314 do n=1,nsw ;
if (pen_sw_bnd(n,i) > 0.0)
then 1315 dr0 = dr0 - (dr0_dt(i)*pen_sw_bnd(n,i)) * &
1316 opacity_band(n,i,k)*htot(i)
1322 do n=1,nsw ;
if (pen_sw_bnd(n,i) > 0.0)
then 1325 opacity = opacity_band(n,i,k)
1326 sw_trans = exp(-h_avail*opacity)
1327 dr_comp = dr_comp + (dr0_dt(i)*pen_sw_bnd(n,i)) * &
1328 ((1.0 - sw_trans) - opacity*(htot(i)+h_avail)*sw_trans)
1330 if (dr_comp >= 0.0)
then 1340 frac = dr0 / (dr0 - dr_comp)
1341 h_ent = h_avail * frac*frac
1342 h_min = 0.0 ; h_max = h_avail
1345 r_sw_top(n) = dr0_dt(i) * pen_sw_bnd(n,i)
1346 c2(n) = r_sw_top(n) * opacity_band(n,i,k)**2
1349 dr_ent = dr ; dr_dh = 0.0
1351 opacity = opacity_band(n,i,k)
1352 sw_trans = exp(-h_ent*opacity)
1353 dr_ent = dr_ent + r_sw_top(n) * ((1.0 - sw_trans) - &
1354 opacity*(htot(i)+h_ent)*sw_trans)
1355 dr_dh = dr_dh + c2(n) * (htot(i)+h_ent) * sw_trans
1358 if (dr_ent > 0.0)
then 1364 dh_newt = -dr_ent / dr_dh
1365 h_prev = h_ent ; h_ent = h_prev+dh_newt
1366 if (h_ent > h_max)
then 1367 h_ent = 0.5*(h_prev+h_max)
1368 else if (h_ent < h_min)
then 1369 h_ent = 0.5*(h_prev+h_min)
1372 if (abs(dh_newt) < 0.2*angstrom)
exit 1379 sum_pen_en = 0.0 ; pen_absorbed = 0.0
1380 do n=1,nsw ;
if (pen_sw_bnd(n,i) > 0.0)
then 1381 opacity = opacity_band(n,i,k)
1382 sw_trans = exp(-h_ent*opacity)
1385 if (x1 < 2.0e-5)
then 1386 en_fn = (opacity*htot(i)*(1.0 - 0.5*(x1 - c1_3*x1)) + &
1389 en_fn = ((opacity*htot(i) + 2.0) * &
1390 ((1.0-sw_trans) / x1) - 1.0 + sw_trans)
1392 sum_pen_en = sum_pen_en - (dr0_dt(i)*pen_sw_bnd(n,i)) * en_fn
1394 pen_absorbed = pen_absorbed + pen_sw_bnd(n,i) * (1.0 - sw_trans)
1395 pen_sw_bnd(n,i) = pen_sw_bnd(n,i) * sw_trans
1398 conv_en(i) = conv_en(i) + g_h2_2rho0 * h_ent * &
1399 ( (r0_tot(i) - r0(i,k)*htot(i)) + sum_pen_en )
1401 r0_tot(i) = r0_tot(i) + (h_ent * r0(i,k) + pen_absorbed*dr0_dt(i))
1402 stot(i) = stot(i) + h_ent * s(i,k)
1403 ttot(i) = ttot(i) + (h_ent * t(i,k) + pen_absorbed)
1404 rcv_tot(i) = rcv_tot(i) + (h_ent * rcv(i,k) + pen_absorbed*drcv_dt(i))
1407 if (h_ent > 0.0)
then 1408 if (htot(i) > 0.0) &
1409 dke_fc(i) = dke_fc(i) + cs%bulk_Ri_convective * 0.5 * &
1410 ((gv%H_to_m*h_ent) / (htot(i)*(h_ent+htot(i)))) * &
1411 ((uhtot(i)-u(i,k)*htot(i))**2 + (vhtot(i)-v(i,k)*htot(i))**2)
1413 htot(i) = htot(i) + h_ent
1414 h(i,k) = h(i,k) - h_ent
1415 d_eb(i,k) = d_eb(i,k) - h_ent
1416 uhtot(i) = u(i,k)*h_ent ; vhtot(i) = v(i,k)*h_ent
1428 subroutine find_starting_tke(htot, h_CA, fluxes, Conv_En, cTKE, dKE_FC, dKE_CA, &
1429 TKE, TKE_river, Idecay_len_TKE, cMKE, dt, Idt_diag, &
1430 j, ksort, G, GV, CS)
1433 real,
dimension(SZI_(G)),
intent(in) :: htot
1435 real,
dimension(SZI_(G)),
intent(in) :: h_CA
1437 type(
forcing),
intent(in) :: fluxes
1440 real,
dimension(SZI_(G)),
intent(inout) :: Conv_En
1443 real,
dimension(SZI_(G)),
intent(in) :: dKE_FC
1446 real,
dimension(SZI_(G),SZK_(GV)), &
1450 real,
dimension(SZI_(G),SZK_(GV)), &
1451 intent(in) :: dKE_CA
1454 real,
dimension(SZI_(G)),
intent(out) :: TKE
1456 real,
dimension(SZI_(G)),
intent(out) :: Idecay_len_TKE
1458 real,
dimension(SZI_(G)),
intent(in) :: TKE_river
1459 real,
dimension(2,SZI_(G)),
intent(out) :: cMKE
1462 real,
intent(in) :: dt
1463 real,
intent(in) :: Idt_diag
1464 integer,
intent(in) :: j
1465 integer,
dimension(SZI_(G),SZK_(GV)), &
1513 real :: wind_TKE_src
1516 integer :: is, ie, nz, i
1518 is = g%isc ; ie = g%iec ; nz = gv%ke
1519 diag_wt = dt * idt_diag
1521 if (cs%omega_frac >= 1.0) absf = 2.0*cs%omega
1523 u_star = fluxes%ustar(i,j)
1524 if (
associated(fluxes%ustar_shelf) .and.
associated(fluxes%frac_shelf_h))
then 1525 if (fluxes%frac_shelf_h(i,j) > 0.0) &
1526 u_star = (1.0 - fluxes%frac_shelf_h(i,j)) * u_star + &
1527 fluxes%frac_shelf_h(i,j) * fluxes%ustar_shelf(i,j)
1530 if (u_star < cs%ustar_min) u_star = cs%ustar_min
1531 if (cs%omega_frac < 1.0)
then 1532 absf = 0.25*((abs(g%CoriolisBu(i,j)) + abs(g%CoriolisBu(i-1,j-1))) + &
1533 (abs(g%CoriolisBu(i,j-1)) + abs(g%CoriolisBu(i-1,j))))
1534 if (cs%omega_frac > 0.0) &
1535 absf = sqrt(cs%omega_frac*4.0*cs%omega**2 + (1.0-cs%omega_frac)*absf**2)
1537 absf_ustar = absf / u_star
1538 idecay_len_tke(i) = (absf_ustar * cs%TKE_decay) * gv%H_to_m
1550 ih = gv%H_to_m/(3.0*0.41*u_star*dt)
1551 cmke(1,i) = 4.0 * ih ; cmke(2,i) = (absf_ustar*gv%H_to_m) * ih
1553 if (idecay_len_tke(i) > 0.0)
then 1554 exp_kh = exp(-htot(i)*idecay_len_tke(i))
1562 if (conv_en(i) < 0.0) conv_en(i) = 0.0
1563 if (ctke(i,1) > 0.0)
then ; tke_ca = ctke(i,1) ;
else ; tke_ca = 0.0 ;
endif 1564 if ((htot(i) >= h_ca(i)) .or. (tke_ca == 0.0))
then 1565 toten = conv_en(i) + tke_ca
1567 if (toten > 0.0)
then 1568 nstar_fc = cs%nstar * toten / (toten + 0.2 * &
1569 sqrt(0.5 * dt * (absf*(htot(i)*gv%H_to_m))**3 * toten))
1576 if (conv_en(i) > 0.0)
then 1577 toten = conv_en(i) + tke_ca * (htot(i) / h_ca(i))
1578 nstar_fc = cs%nstar * toten / (toten + 0.2 * &
1579 sqrt(0.5 * dt * (absf*(htot(i)*gv%H_to_m))**3 * toten))
1584 toten = conv_en(i) + tke_ca
1585 if (tke_ca > 0.0)
then 1586 nstar_ca = cs%nstar * toten / (toten + 0.2 * &
1587 sqrt(0.5 * dt * (absf*(h_ca(i)*gv%H_to_m))**3 * toten))
1593 if (dke_fc(i) + dke_ca(i,1) > 0.0)
then 1594 if (htot(i) >= h_ca(i))
then 1595 mke_rate_fc = 1.0 / (1.0 + htot(i)*(cmke(1,i) + cmke(2,i)*htot(i)) )
1596 mke_rate_ca = mke_rate_fc
1598 mke_rate_fc = 1.0 / (1.0 + htot(i)*(cmke(1,i) + cmke(2,i)*htot(i)) )
1599 mke_rate_ca = 1.0 / (1.0 + h_ca(i)*(cmke(1,i) + cmke(2,i)*h_ca(i)) )
1603 mke_rate_fc = 1.0 ; mke_rate_ca = 1.0
1606 dke_conv = dke_ca(i,1) * mke_rate_ca + dke_fc(i) * mke_rate_fc
1609 tke(i) = (dt*cs%mstar)*((u_star*u_star*u_star)*exp_kh) + &
1610 (exp_kh * dke_conv + nstar_fc*conv_en(i) + nstar_ca*tke_ca)
1613 if (cs%do_rivermix)
then 1614 tke(i) = tke(i) + tke_river(i)*dt*exp_kh
1617 if (cs%TKE_diagnostics)
then 1618 wind_tke_src = cs%mstar*(u_star*u_star*u_star) * diag_wt
1619 cs%diag_TKE_wind(i,j) = cs%diag_TKE_wind(i,j) + &
1620 wind_tke_src + tke_river(i) * diag_wt
1621 cs%diag_TKE_RiBulk(i,j) = cs%diag_TKE_RiBulk(i,j) + dke_conv*idt_diag
1622 cs%diag_TKE_mech_decay(i,j) = cs%diag_TKE_mech_decay(i,j) + &
1623 (exp_kh-1.0)*(wind_tke_src + dke_conv*idt_diag)
1624 cs%diag_TKE_conv(i,j) = cs%diag_TKE_conv(i,j) + &
1625 idt_diag*(nstar_fc*conv_en(i) + nstar_ca*tke_ca)
1626 cs%diag_TKE_conv_decay(i,j) = cs%diag_TKE_conv_decay(i,j) + &
1627 idt_diag*((cs%nstar-nstar_fc)*conv_en(i) + (cs%nstar-nstar_ca)*tke_ca)
1628 cs%diag_TKE_conv_s2(i,j) = cs%diag_TKE_conv_s2(i,j) + &
1629 idt_diag*(ctke(i,1)-tke_ca)
1637 R0_tot, Rcv_tot, u, v, T, S, R0, Rcv, eps, &
1638 dR0_dT, dRcv_dT, cMKE, Idt_diag, nsw, &
1639 Pen_SW_bnd, opacity_band, TKE, &
1640 Idecay_len_TKE, j, ksort, G, GV, CS)
1644 real,
dimension(SZI_(G),SZK_(GV)),
intent(inout) :: h
1647 real,
dimension(SZI_(G),SZK_(GV)),
intent(inout) :: d_eb
1651 real,
dimension(SZI_(G)),
intent(inout) :: htot
1653 real,
dimension(SZI_(G)),
intent(inout) :: Ttot
1655 real,
dimension(SZI_(G)),
intent(inout) :: Stot
1657 real,
dimension(SZI_(G)),
intent(inout) :: uhtot
1659 real,
dimension(SZI_(G)),
intent(inout) :: vhtot
1661 real,
dimension(SZI_(G)),
intent(inout) :: R0_tot
1664 real,
dimension(SZI_(G)),
intent(inout) :: Rcv_tot
1667 real,
dimension(SZI_(G),SZK_(GV)),
intent(in) :: u, v, T, S, R0, Rcv, eps
1668 real,
dimension(SZI_(G)),
intent(in) :: dR0_dT, dRcv_dT
1669 real,
dimension(2,SZI_(G)),
intent(in) :: cMKE
1670 real,
intent(in) :: Idt_diag
1671 integer,
intent(in) :: nsw
1673 real,
dimension(:,:),
intent(inout) :: Pen_SW_bnd
1677 real,
dimension(:,:,:),
intent(in) :: opacity_band
1678 real,
dimension(SZI_(G)),
intent(inout) :: TKE
1681 real,
dimension(SZI_(G)),
intent(inout) :: Idecay_len_TKE
1682 integer,
intent(in) :: j
1683 integer,
dimension(SZI_(G),SZK_(GV)), &
1715 real :: Pen_absorbed
1719 real :: h_min, h_max
1729 real :: TKE_full_ent
1733 real :: Pen_En_Contrib
1742 real :: Pen_dTKE_dh_Contrib
1752 real :: f1_x1, f2_x1
1759 real :: C1_3, C1_6, C1_24
1760 integer :: is, ie, nz, i, k, ks, itt, n
1762 c1_3 = 1.0/3.0 ; c1_6 = 1.0/6.0 ; c1_24 = 1.0/24.0
1764 g_h_2rho0 = (gv%g_Earth * h_to_m) / (2.0 * gv%Rho0)
1765 hmix_min = cs%Hmix_min * gv%m_to_H
1766 h_neglect = gv%H_subroundoff
1767 is = g%isc ; ie = g%iec ; nz = gv%ke
1771 do i=is,ie ;
if (ksort(i,ks) > 0)
then 1774 h_avail = h(i,k) - eps(i,k)
1775 if ((h_avail > 0.) .and. ((tke(i) > 0.) .or. (htot(i) < hmix_min)))
then 1776 drl = g_h_2rho0 * (r0(i,k)*htot(i) - r0_tot(i) )
1777 dmke = (h_to_m * cs%bulk_Ri_ML) * 0.5 * &
1778 ((uhtot(i)-u(i,k)*htot(i))**2 + (vhtot(i)-v(i,k)*htot(i))**2)
1781 kh = idecay_len_tke(i)*h_avail ; exp_kh = exp(-kh)
1782 if (kh >= 2.0e-5)
then ; f1_kh = (1.0-exp_kh) / kh
1783 else ; f1_kh = (1.0 - kh*(0.5 - c1_6*kh)) ;
endif 1785 pen_en_contrib = 0.0
1786 do n=1,nsw ;
if (pen_sw_bnd(n,i) > 0.0)
then 1787 opacity = opacity_band(n,i,k)
1791 if (idecay_len_tke(i) > opacity)
then 1792 x1 = (idecay_len_tke(i) - opacity) * h_avail
1793 if (x1 >= 2.0e-5)
then 1794 e_x1 = exp(-x1) ; f1_x1 = ((1.0-e_x1)/(x1))
1795 f3_x1 = ((e_x1-(1.0-x1))/(x1*x1))
1797 f1_x1 = (1.0 - x1*(0.5 - c1_6*x1))
1798 f3_x1 = (0.5 - x1*(c1_6 - c1_24*x1))
1801 pen_en1 = exp(-opacity*h_avail) * &
1802 ((1.0+opacity*htot(i))*f1_x1 + opacity*h_avail*f3_x1)
1804 x1 = (opacity - idecay_len_tke(i)) * h_avail
1805 if (x1 >= 2.0e-5)
then 1806 e_x1 = exp(-x1) ; f1_x1 = ((1.0-e_x1)/(x1))
1807 f2_x1 = ((1.0-(1.0+x1)*e_x1)/(x1*x1))
1809 f1_x1 = (1.0 - x1*(0.5 - c1_6*x1))
1810 f2_x1 = (0.5 - x1*(c1_3 - 0.125*x1))
1813 pen_en1 = exp_kh * ((1.0+opacity*htot(i))*f1_x1 + &
1814 opacity*h_avail*f2_x1)
1816 pen_en_contrib = pen_en_contrib + &
1817 (g_h_2rho0*dr0_dt(i)*pen_sw_bnd(n,i)) * (pen_en1 - f1_kh)
1820 hpe = htot(i)+h_avail
1821 mke_rate = 1.0/(1.0 + (cmke(1,i)*hpe + cmke(2,i)*hpe**2))
1822 ef4_val =
ef4(htot(i)+h_neglect,h_avail,idecay_len_tke(i))
1823 tke_full_ent = (exp_kh*tke(i) - (h_avail*h_to_m)*(drl*f1_kh + pen_en_contrib)) + &
1824 mke_rate*dmke*ef4_val
1825 if ((tke_full_ent >= 0.0) .or. (h_avail+htot(i) <= hmix_min))
then 1829 if (cs%TKE_diagnostics)
then 1830 e_hxhpe = h_ent / ((htot(i)+h_neglect)*(htot(i)+h_ent+h_neglect))
1831 cs%diag_TKE_mech_decay(i,j) = cs%diag_TKE_mech_decay(i,j) + &
1832 idt_diag * ((exp_kh-1.0)*tke(i) + &
1833 (h_ent*h_to_m)*drl*(1.0-f1_kh) + &
1834 mke_rate*dmke*(ef4_val-e_hxhpe))
1835 cs%diag_TKE_mixing(i,j) = cs%diag_TKE_mixing(i,j) - &
1836 idt_diag*(h_to_m*h_ent)*drl
1837 cs%diag_TKE_pen_SW(i,j) = cs%diag_TKE_pen_SW(i,j) - &
1838 idt_diag*(h_to_m*h_ent)*pen_en_contrib
1839 cs%diag_TKE_RiBulk(i,j) = cs%diag_TKE_RiBulk(i,j) + &
1840 idt_diag*mke_rate*dmke*e_hxhpe
1843 tke(i) = tke_full_ent
1844 if (tke(i) <= 0.0) tke(i) = 1e-300
1849 h_min = 0.0 ; h_max = h_avail
1850 if (tke(i) <= 0.0)
then 1853 h_ent = h_avail * tke(i) / (tke(i) - tke_full_ent)
1858 kh = idecay_len_tke(i)*h_ent ; exp_kh = exp(-kh)
1859 if (kh >= 2.0e-5)
then 1860 f1_kh = (1.0-exp_kh) / kh
1862 f1_kh = (1.0 - kh*(0.5 - c1_6*kh))
1866 pen_en_contrib = 0.0 ; pen_dtke_dh_contrib = 0.0
1867 do n=1,nsw ;
if (pen_sw_bnd(n,i) > 0.0)
then 1871 opacity = opacity_band(n,i,k)
1872 sw_trans = exp(-h_ent*opacity)
1873 if (idecay_len_tke(i) > opacity)
then 1874 x1 = (idecay_len_tke(i) - opacity) * h_ent
1875 if (x1 >= 2.0e-5)
then 1876 e_x1 = exp(-x1) ; f1_x1 = ((1.0-e_x1)/(x1))
1877 f3_x1 = ((e_x1-(1.0-x1))/(x1*x1))
1879 f1_x1 = (1.0 - x1*(0.5 - c1_6*x1))
1880 f3_x1 = (0.5 - x1*(c1_6 - c1_24*x1))
1882 pen_en1 = sw_trans * ((1.0+opacity*htot(i))*f1_x1 + &
1883 opacity*h_ent*f3_x1)
1885 x1 = (opacity - idecay_len_tke(i)) * h_ent
1886 if (x1 >= 2.0e-5)
then 1887 e_x1 = exp(-x1) ; f1_x1 = ((1.0-e_x1)/(x1))
1888 f2_x1 = ((1.0-(1.0+x1)*e_x1)/(x1*x1))
1890 f1_x1 = (1.0 - x1*(0.5 - c1_6*x1))
1891 f2_x1 = (0.5 - x1*(c1_3 - 0.125*x1))
1894 pen_en1 = exp_kh * ((1.0+opacity*htot(i))*f1_x1 + &
1895 opacity*h_ent*f2_x1)
1897 c1 = g_h_2rho0*dr0_dt(i)*pen_sw_bnd(n,i)
1898 pen_en_contrib = pen_en_contrib + c1*(pen_en1 - f1_kh)
1899 pen_dtke_dh_contrib = pen_dtke_dh_contrib + &
1900 c1*((1.0-sw_trans) - opacity*(htot(i) + h_ent)*sw_trans)
1903 tke_ent1 = exp_kh*tke(i) - (h_ent*h_to_m)*(drl*f1_kh + pen_en_contrib)
1904 ef4_val =
ef4(htot(i)+h_neglect,h_ent,idecay_len_tke(i),def4_dh)
1906 mke_rate = 1.0/(1.0 + (cmke(1,i)*hpe + cmke(2,i)*hpe**2))
1907 tke_ent = tke_ent1 + dmke*ef4_val*mke_rate
1910 dtke_dh = ((-idecay_len_tke(i)*tke_ent1 - drl*h_to_m) + &
1911 pen_dtke_dh_contrib*h_to_m) + dmke * mke_rate* &
1912 (def4_dh - ef4_val*mke_rate*(cmke(1,i)+2.0*cmke(2,i)*hpe))
1915 if (tke_ent > 0.0)
then 1916 if ((h_max-h_ent)*(-dtke_dh) > tke_ent)
then 1917 dh_newt = -tke_ent / dtke_dh
1919 dh_newt = 0.5*(h_max-h_ent)
1923 if ((h_min-h_ent)*(-dtke_dh) < tke_ent)
then 1924 dh_newt = -tke_ent / dtke_dh
1926 dh_newt = 0.5*(h_min-h_ent)
1930 h_ent = h_ent + dh_newt
1932 if (abs(dh_newt) < 0.2*gv%Angstrom)
exit 1936 if (h_ent < hmix_min-htot(i)) h_ent = hmix_min - htot(i)
1938 if (cs%TKE_diagnostics)
then 1940 mke_rate = 1.0/(1.0 + cmke(1,i)*hpe + cmke(2,i)*hpe**2)
1941 ef4_val =
ef4(htot(i)+h_neglect,h_ent,idecay_len_tke(i))
1943 e_hxhpe = h_ent / ((htot(i)+h_neglect)*(hpe+h_neglect))
1944 cs%diag_TKE_mech_decay(i,j) = cs%diag_TKE_mech_decay(i,j) + &
1945 idt_diag * ((exp_kh-1.0)*tke(i) + &
1946 (h_ent*h_to_m)*drl*(1.0-f1_kh) + &
1947 dmke*mke_rate*(ef4_val-e_hxhpe))
1948 cs%diag_TKE_mixing(i,j) = cs%diag_TKE_mixing(i,j) - &
1949 idt_diag*(h_ent*h_to_m)*drl
1950 cs%diag_TKE_pen_SW(i,j) = cs%diag_TKE_pen_SW(i,j) - &
1951 idt_diag*(h_ent*h_to_m)*pen_en_contrib
1952 cs%diag_TKE_RiBulk(i,j) = cs%diag_TKE_RiBulk(i,j) + &
1953 idt_diag*dmke*mke_rate*e_hxhpe
1960 do n=1,nsw ;
if (pen_sw_bnd(n,i) > 0.0)
then 1961 sw_trans = exp(-h_ent*opacity_band(n,i,k))
1962 pen_absorbed = pen_absorbed + pen_sw_bnd(n,i) * (1.0 - sw_trans)
1963 pen_sw_bnd(n,i) = pen_sw_bnd(n,i) * sw_trans
1966 htot(i) = htot(i) + h_ent
1967 r0_tot(i) = r0_tot(i) + (h_ent * r0(i,k) + pen_absorbed*dr0_dt(i))
1968 h(i,k) = h(i,k) - h_ent
1969 d_eb(i,k) = d_eb(i,k) - h_ent
1971 stot(i) = stot(i) + h_ent * s(i,k)
1972 ttot(i) = ttot(i) + (h_ent * t(i,k) + pen_absorbed)
1973 rcv_tot(i) = rcv_tot(i) + (h_ent*rcv(i,k) + pen_absorbed*drcv_dt(i))
1975 uhtot(i) = uhtot(i) + u(i,k)*h_ent
1976 vhtot(i) = vhtot(i) + v(i,k)*h_ent
1986 subroutine sort_ml(h, R0, eps, G, GV, CS, ksort)
1989 real,
dimension(SZI_(G),SZK_(GV)),
intent(in) :: h
1992 real,
dimension(SZI_(G),SZK_(GV)),
intent(in) :: R0
1994 real,
dimension(SZI_(G),SZK_(GV)),
intent(in) :: eps
1998 integer,
dimension(SZI_(G),SZK_(GV)),
intent(out) :: ksort
2015 real :: R0sort(szi_(g),szk_(gv))
2016 integer :: nsort(szi_(g))
2017 logical :: done_sorting(szi_(g))
2018 integer :: i, k, ks, is, ie, nz, nkmb
2020 is = g%isc ; ie = g%iec ; nz = gv%ke
2021 nkmb = cs%nkml+cs%nkbl
2031 do k=1,nz ;
do i=is,ie ; ksort(i,k) = -1 ;
enddo ;
enddo 2033 do i=is,ie ; nsort(i) = 0 ; done_sorting(i) = .false. ;
enddo 2034 do k=1,nz ;
do i=is,ie ;
if (h(i,k) > eps(i,k))
then 2035 if (done_sorting(i))
then ; ks = nsort(i) ;
else 2037 if (r0(i,k) >= r0sort(i,ks))
exit 2038 r0sort(i,ks+1) = r0sort(i,ks) ; ksort(i,ks+1) = ksort(i,ks)
2040 if ((k > nkmb) .and. (ks == nsort(i))) done_sorting(i) = .true.
2044 r0sort(i,ks+1) = r0(i,k)
2045 nsort(i) = nsort(i) + 1
2046 endif ;
enddo ;
enddo 2053 subroutine resort_ml(h, T, S, R0, Rcv, RcvTgt, eps, d_ea, d_eb, ksort, G, GV, CS, &
2054 dR0_dT, dR0_dS, dRcv_dT, dRcv_dS)
2058 real,
dimension(SZI_(G),SZK0_(GV)),
intent(inout) :: h
2062 real,
dimension(SZI_(G),SZK0_(GV)),
intent(inout) :: T
2063 real,
dimension(SZI_(G),SZK0_(GV)),
intent(inout) :: S
2064 real,
dimension(SZI_(G),SZK0_(GV)),
intent(inout) :: R0
2066 real,
dimension(SZI_(G),SZK0_(GV)),
intent(inout) :: Rcv
2068 real,
dimension(SZK_(GV)),
intent(in) :: RcvTgt
2070 real,
dimension(SZI_(G),SZK_(GV)),
intent(inout) :: eps
2072 real,
dimension(SZI_(G),SZK_(GV)),
intent(inout) :: d_ea
2077 real,
dimension(SZI_(G),SZK_(GV)),
intent(inout) :: d_eb
2081 integer,
dimension(SZI_(G),SZK_(GV)),
intent(in) :: ksort
2084 real,
dimension(SZI_(G)),
intent(in) :: dR0_dT
2088 real,
dimension(SZI_(G)),
intent(in) :: dR0_dS
2092 real,
dimension(SZI_(G)),
intent(in) :: dRcv_dT
2096 real,
dimension(SZI_(G)),
intent(in) :: dRcv_dS
2143 real :: h_move, h_tgt_old, I_hnew
2144 real :: dT_dS_wt2, dT_dR, dS_dR, I_denom
2146 real :: target_match_tol
2147 real :: T_up, S_up, R0_up, I_hup, h_to_up
2148 real :: T_dn, S_dn, R0_dn, I_hdn, h_to_dn
2151 real :: dPE, hmin, min_dPE, min_hmin
2152 real,
dimension(SZK_(GV)) :: &
2153 h_tmp, R0_tmp, T_tmp, S_tmp, Rcv_tmp
2155 logical :: sorted, leave_in_layer
2156 integer :: ks_deep(szi_(g)), k_count(szi_(g)), ks2_reverse(szi_(g), szk_(gv))
2157 integer :: ks2(szk_(gv))
2158 integer :: i, k, ks, is, ie, nz, k1, k2, k_tgt, k_src, k_int_top
2159 integer :: nks, nkmb, num_interior, top_interior_ks
2161 is = g%isc ; ie = g%iec ; nz = gv%ke
2162 nkmb = cs%nkml+cs%nkbl
2163 target_match_tol = 0.1
2165 dt_ds_wt2 = cs%dT_dS_wt**2
2168 do i=is,ie ; ks_deep(i) = -1 ; k_count(i) = 0 ;
enddo 2169 do ks=nz,1,-1 ;
do i=is,ie ;
if (ksort(i,ks) > 0)
then 2172 if (h(i,k) > eps(i,k))
then 2173 if (ks_deep(i) == -1)
then 2175 ks_deep(i) = ks ; k_count(i) = k_count(i) + 1
2176 ks2_reverse(i,k_count(i)) = k
2179 k_count(i) = k_count(i) + 1
2180 ks2_reverse(i,k_count(i)) = k
2183 endif ;
enddo ;
enddo 2185 do i=is,ie ;
if (k_count(i) > 1)
then 2191 ks2(nks) = ks2_reverse(i,1)
2193 ks2(ks) = ks2_reverse(i,1+nks-ks)
2194 if (ks2(ks) > ks2(ks+1)) sorted = .false.
2202 num_interior = 0 ; top_interior_ks = 0
2203 do ks=nks,1,-1 ;
if (ks2(ks) > nkmb)
then 2204 num_interior = num_interior+1 ; top_interior_ks = ks
2207 if (num_interior >= 1)
then 2210 do k=nkmb+1,nz ;
if (rcv(i,0) < rcvtgt(k))
exit ;
enddo 2211 k_int_top = k ; rcv_int = rcvtgt(k)
2213 i_denom = 1.0 / (drcv_ds(i)**2 + dt_ds_wt2*drcv_dt(i)**2)
2214 dt_dr = dt_ds_wt2*drcv_dt(i) * i_denom
2215 ds_dr = drcv_ds(i) * i_denom
2221 do ks = nks,top_interior_ks,-1
2223 leave_in_layer = .false.
2224 if ((k > nkmb) .and. (rcv(i,k) <= rcvtgt(k)))
then 2225 if (rcvtgt(k)-rcv(i,k) < target_match_tol*(rcvtgt(k) - rcvtgt(k-1))) &
2226 leave_in_layer = .true.
2227 elseif (k > nkmb)
then 2228 if (rcv(i,k)-rcvtgt(k) < target_match_tol*(rcvtgt(k+1) - rcvtgt(k))) &
2229 leave_in_layer = .true.
2232 if (leave_in_layer)
then 2235 elseif (rcv(i,k) < rcv_int)
then 2242 do k2=k_int_top+1,nz ;
if (rcv(i,k) < rcvtgt(k2))
exit ;
enddo 2247 dr1 = (rcvtgt(k2-1) - rcv(i,k)) ; dr2 = (rcvtgt(k2) - rcv(i,k))
2248 t_up = t(i,k) + dt_dr * dr1
2249 s_up = s(i,k) + ds_dr * dr1
2250 t_dn = t(i,k) + dt_dr * dr2
2251 s_dn = s(i,k) + ds_dr * dr2
2253 r0_up = r0(i,k) + (dt_dr*dr0_dt(i) + ds_dr*dr0_ds(i)) * dr1
2254 r0_dn = r0(i,k) + (dt_dr*dr0_dt(i) + ds_dr*dr0_ds(i)) * dr2
2257 if ((r0_up > r0(i,0)) .or. (r0_dn > r0(i,0))) &
2261 wt_dn = (rcv(i,k) - rcvtgt(k2-1)) / (rcvtgt(k2) - rcvtgt(k2-1))
2262 h_to_up = (h(i,k)-eps(i,k)) * (1.0 - wt_dn)
2263 h_to_dn = (h(i,k)-eps(i,k)) * wt_dn
2265 i_hup = 1.0 / (h(i,k2-1) + h_to_up)
2266 i_hdn = 1.0 / (h(i,k2) + h_to_dn)
2267 r0(i,k2-1) = (r0(i,k2)*h(i,k2-1) + r0_up*h_to_up) * i_hup
2268 r0(i,k2) = (r0(i,k2)*h(i,k2) + r0_dn*h_to_dn) * i_hdn
2270 t(i,k2-1) = (t(i,k2)*h(i,k2-1) + t_up*h_to_up) * i_hup
2271 t(i,k2) = (t(i,k2)*h(i,k2) + t_dn*h_to_dn) * i_hdn
2272 s(i,k2-1) = (s(i,k2)*h(i,k2-1) + s_up*h_to_up) * i_hup
2273 s(i,k2) = (s(i,k2)*h(i,k2) + s_dn*h_to_dn) * i_hdn
2274 rcv(i,k2-1) = (rcv(i,k2)*h(i,k2-1) + rcvtgt(k2-1)*h_to_up) * i_hup
2275 rcv(i,k2) = (rcv(i,k2)*h(i,k2) + rcvtgt(k2)*h_to_dn) * i_hdn
2278 h(i,k2) = h(i,k2) + h_to_dn
2279 h(i,k2-1) = h(i,k2-1) + h_to_up
2282 d_eb(i,k) = d_eb(i,k) - h_to_up
2283 d_eb(i,k2-1) = d_eb(i,k2-1) + h_to_up
2284 elseif (k < k2-1)
then 2285 d_ea(i,k) = d_ea(i,k) - h_to_up
2286 d_ea(i,k2-1) = d_ea(i,k2-1) + h_to_up
2289 d_eb(i,k) = d_eb(i,k) - h_to_dn
2290 d_eb(i,k2) = d_eb(i,k2) + h_to_dn
2291 elseif (k < k2)
then 2292 d_ea(i,k) = d_ea(i,k) - h_to_dn
2293 d_ea(i,k2) = d_ea(i,k2) + h_to_dn
2300 do while (nks > nkmb)
2309 ks_min = -1 ; min_dpe = 1.0 ; min_hmin = 0.0
2311 k1 = ks2(ks) ; k2 = ks2(ks+1)
2312 dpe = max(0.0, (r0(i,k2)-r0(i,k1)) * h(i,k1) * h(i,k2))
2313 hmin = min(h(i,k1)-eps(i,k1), h(i,k2)-eps(i,k2))
2314 if ((ks_min < 0) .or. (dpe < min_dpe) .or. &
2315 ((dpe <= 0.0) .and. (hmin < min_hmin)))
then 2316 ks_min = ks ; min_dpe = dpe ; min_hmin = hmin
2321 k1 = ks2(ks_min) ; k2 = ks2(ks_min+1)
2322 if (k1 < k2)
then ; k_tgt = k1 ; k_src = k2
2323 else ; k_tgt = k2 ; k_src = k1 ; ks2(ks_min) = k2 ;
endif 2325 h_tgt_old = h(i,k_tgt)
2326 h_move = h(i,k_src)-eps(i,k_src)
2327 h(i,k_src) = eps(i,k_src)
2328 h(i,k_tgt) = h(i,k_tgt) + h_move
2329 i_hnew = 1.0 / (h(i,k_tgt))
2330 r0(i,k_tgt) = (r0(i,k_tgt)*h_tgt_old + r0(i,k_src)*h_move) * i_hnew
2332 t(i,k_tgt) = (t(i,k_tgt)*h_tgt_old + t(i,k_src)*h_move) * i_hnew
2333 s(i,k_tgt) = (s(i,k_tgt)*h_tgt_old + s(i,k_src)*h_move) * i_hnew
2334 rcv(i,k_tgt) = (rcv(i,k_tgt)*h_tgt_old + rcv(i,k_src)*h_move) * i_hnew
2336 d_eb(i,k_src) = d_eb(i,k_src) - h_move
2337 d_eb(i,k_tgt) = d_eb(i,k_tgt) + h_move
2340 do ks=ks_min+1,nks ; ks2(ks) = ks2(ks+1) ;
enddo 2347 do ks=1,nks-1 ;
if (ks2(ks) > ks2(ks+1)) sorted = .false. ;
enddo 2356 h_tmp(k) = h(i,k) ; r0_tmp(k) = r0(i,k)
2357 t_tmp(k) = t(i,k) ; s_tmp(k) = s(i,k) ; rcv_tmp(k) = rcv(i,k)
2363 k_tgt = nkmb - nks + ks ; k_src = ks2(ks)
2364 if (k_tgt == k_src)
then 2365 h(i,k_tgt) = h_tmp(k_tgt)
2370 if (k_src > nkmb)
then 2371 h_move = h(i,k_src)-eps(i,k_src)
2372 h(i,k_src) = eps(i,k_src)
2374 r0(i,k_tgt) = r0(i,k_src)
2376 t(i,k_tgt) = t(i,k_src) ; s(i,k_tgt) = s(i,k_src)
2377 rcv(i,k_tgt) = rcv(i,k_src)
2379 d_eb(i,k_src) = d_eb(i,k_src) - h_move
2380 d_eb(i,k_tgt) = d_eb(i,k_tgt) + h_move
2382 h(i,k_tgt) = h_tmp(k_src)
2383 r0(i,k_tgt) = r0_tmp(k_src)
2385 t(i,k_tgt) = t_tmp(k_src) ; s(i,k_tgt) = s_tmp(k_src)
2386 rcv(i,k_tgt) = rcv_tmp(k_src)
2388 if (k_src > k_tgt)
then 2389 d_eb(i,k_src) = d_eb(i,k_src) - h_tmp(k_src)
2390 d_eb(i,k_tgt) = d_eb(i,k_tgt) + h_tmp(k_src)
2392 d_ea(i,k_src) = d_ea(i,k_src) - h_tmp(k_src)
2393 d_ea(i,k_tgt) = d_ea(i,k_tgt) + h_tmp(k_src)
2406 subroutine mixedlayer_detrain_2(h, T, S, R0, Rcv, RcvTgt, dt, dt_diag, d_ea, j, G, GV, CS, &
2407 dR0_dT, dR0_dS, dRcv_dT, dRcv_dS, max_BL_det)
2410 real,
dimension(SZI_(G),SZK0_(GV)),
intent(inout) :: h
2414 real,
dimension(SZI_(G),SZK0_(GV)),
intent(inout) :: T
2415 real,
dimension(SZI_(G),SZK0_(GV)),
intent(inout) :: S
2416 real,
dimension(SZI_(G),SZK0_(GV)),
intent(inout) :: R0
2418 real,
dimension(SZI_(G),SZK0_(GV)),
intent(inout) :: Rcv
2420 real,
dimension(SZK_(GV)),
intent(in) :: RcvTgt
2422 real,
intent(in) :: dt
2423 real,
intent(in) :: dt_diag
2424 real,
dimension(SZI_(G),SZK_(GV)),
intent(inout) :: d_ea
2428 integer,
intent(in) :: j
2431 real,
dimension(SZI_(G)),
intent(in) :: dR0_dT
2435 real,
dimension(SZI_(G)),
intent(in) :: dR0_dS
2439 real,
dimension(SZI_(G)),
intent(in) :: dRcv_dT
2443 real,
dimension(SZI_(G)),
intent(in) :: dRcv_dS
2446 real,
dimension(SZI_(G)),
intent(in) :: max_BL_det
2483 real :: R0_to_bl, Rcv_to_bl
2484 real :: T_to_bl, S_to_bl
2488 real :: h_min_bl_thick
2490 real :: h_min_bl_frac_ml = 0.05
2501 real :: stays_min, stays_max
2504 logical :: mergeable_bl
2510 real :: stays_min_merge
2512 real :: dR0_2dz, dRcv_2dz
2521 real :: dPE_det, dPE_merge
2530 real :: h_det_to_h2, h_ml_to_h2
2531 real :: h_det_to_h1, h_ml_to_h1
2532 real :: h1_to_h2, h1_to_k0
2533 real :: h2_to_k1, h2_to_k1_rem
2538 real :: R0_det, T_det, S_det
2539 real :: Rcv_stays, R0_stays
2540 real :: T_stays, S_stays
2541 real :: dSpice_det, dSpice_stays
2545 real :: dSpice_lim, dSpice_lim2
2556 real :: detrainment_timescale
2558 real :: dPE_time_ratio
2560 real :: dT_dS_gauge, dS_dT_gauge
2570 logical :: stable_Rcv
2579 real :: Ih, Ihdet, Ih1f, Ih2f
2580 real :: Ihk0, Ihk1, Ih12
2581 real :: dR1, dR2, dR2b, dRk1
2582 real :: dR0, dR21, dRcv
2583 real :: dRcv_stays, dRcv_det, dRcv_lim
2586 real :: h2_to_k1_lim, T_new, S_new, T_max, T_min, S_max, S_min
2587 character(len=200) :: mesg
2589 integer :: i, k, k0, k1, is, ie, nz, kb1, kb2, nkmb
2590 is = g%isc ; ie = g%iec ; nz = gv%ke
2591 kb1 = cs%nkml+1; kb2 = cs%nkml+2
2592 nkmb = cs%nkml+cs%nkbl
2593 h_neglect = gv%H_subroundoff
2594 g_2 = 0.5*gv%g_Earth
2595 rho0xg = gv%Rho0 * gv%g_Earth
2596 idt_h2 = gv%H_to_m**2 / dt_diag
2597 i2rho0 = 0.5 / gv%Rho0
2598 angstrom = gv%Angstrom
2601 h_min_bl_thick = 5.0 * gv%m_to_H
2602 dt_ds_gauge = cs%dT_dS_wt ; ds_dt_gauge = 1.0 /dt_ds_gauge
2604 detrainment_timescale = 4.0*3600.0
2606 if (cs%nkbl /= 2)
call mom_error(fatal,
"MOM_mixed_layer"// &
2607 "CS%nkbl must be 2 in mixedlayer_detrain_2.")
2609 if (dt < detrainment_timescale)
then ; dpe_time_ratio = detrainment_timescale/dt
2610 else ; dpe_time_ratio = 1.0 ;
endif 2619 h_to_bl = 0.0 ; r0_to_bl = 0.0
2620 rcv_to_bl = 0.0 ; t_to_bl = 0.0 ; s_to_bl = 0.0
2622 do k=1,cs%nkml ;
if (h(i,k) > 0.0)
then 2623 h_to_bl = h_to_bl + h(i,k)
2624 r0_to_bl = r0_to_bl + r0(i,k)*h(i,k)
2626 rcv_to_bl = rcv_to_bl + rcv(i,k)*h(i,k)
2627 t_to_bl = t_to_bl + t(i,k)*h(i,k)
2628 s_to_bl = s_to_bl + s(i,k)*h(i,k)
2630 d_ea(i,k) = d_ea(i,k) - h(i,k)
2633 if (h_to_bl > 0.0)
then ; r0_det = r0_to_bl / h_to_bl
2634 else ; r0_det = r0(i,0) ;
endif 2656 h_min_bl = min(h_min_bl_thick,h_min_bl_frac_ml*h(i,0))
2659 if (((r0(i,kb2)-r0(i,kb1)) * (rcv(i,kb2)-rcv(i,kb1)) <= 0.0)) &
2660 stable_rcv = .false.
2662 h1 = h(i,kb1) ; h2 = h(i,kb2)
2664 h2_to_k1_rem = (h1 + h2) + h_to_bl
2665 if ((max_bl_det(i) >= 0.0) .and. (h2_to_k1_rem > max_bl_det(i))) &
2666 h2_to_k1_rem = max_bl_det(i)
2669 if ((h2 == 0.0) .and. (h1 > 0.0))
then 2678 do k1=kb2+1,nz ;
if (h(i,k1) > 2.0*angstrom)
exit ;
enddo 2680 r0(i,kb2) = r0(i,kb1)
2682 rcv(i,kb2)=rcv(i,kb1) ; t(i,kb2)=t(i,kb1) ; s(i,kb2)=s(i,kb1)
2685 if (k1 <= nz)
then ;
if (r0(i,k1) >= r0(i,kb1))
then 2686 r0(i,kb2) = 0.5*(r0(i,kb1)+r0(i,k1))
2688 rcv(i,kb2) = 0.5*(rcv(i,kb1)+rcv(i,k1))
2689 t(i,kb2) = 0.5*(t(i,kb1)+t(i,k1))
2690 s(i,kb2) = 0.5*(s(i,kb1)+s(i,k1))
2694 dpe_extrap = 0.0 ; dpe_merge = 0.0
2695 mergeable_bl = .false.
2696 if ((h1 > 0.0) .and. (h2 > 0.0) .and. (h_to_bl > 0.0) .and. &
2703 do k1=kb2+1,nz ;
if (rcvtgt(k1) >= rcv(i,kb2))
exit ;
enddo ; k0 = k1-1
2704 dr1 = rcvtgt(k0)-rcv(i,kb1) ; dr2 = rcv(i,kb2)-rcvtgt(k0)
2710 h1_avail = h1 - max(0.0,h_min_bl-h_to_bl)
2711 if ((k1<=nz) .and. (h2 > h_min_bl) .and. (h1_avail > 0.0) .and. &
2712 (r0(i,kb1) < r0(i,kb2)) .and. (h_to_bl*r0(i,kb1) > r0_to_bl))
then 2713 drk1 = (rcvtgt(k1) - rcv(i,kb2)) * (r0(i,kb2) - r0(i,kb1)) / &
2714 (rcv(i,kb2) - rcv(i,kb1))
2715 b1 = drk1 / (r0(i,kb2) - r0(i,kb1))
2721 h2_to_k1 = min(h2 - h_min_bl, h2_to_k1_rem)
2724 if (h2_to_k1*(h1_avail + b1*(h1_avail + h2)) > h2*h1_avail) &
2725 h2_to_k1 = (h2*h1_avail) / (h1_avail + b1*(h1_avail + h2))
2726 if (h2_to_k1*(drk1 * h2) > (h_to_bl*r0(i,kb1) - r0_to_bl) * h1) &
2727 h2_to_k1 = (h_to_bl*r0(i,kb1) - r0_to_bl) * h1 / (drk1 * h2)
2729 if ((k1==kb2+1) .and. (cs%BL_extrap_lim > 0.))
then 2732 drcv_lim = rcv(i,kb2)-rcv(i,0)
2733 do k=1,kb2 ; drcv_lim = max(drcv_lim, rcv(i,kb2)-rcv(i,k)) ;
enddo 2734 drcv_lim = cs%BL_extrap_lim*drcv_lim
2735 if ((rcvtgt(k1) - rcv(i,kb2)) >= drcv_lim)
then 2737 elseif ((rcvtgt(k1) - rcv(i,kb2)) > 0.5*drcv_lim)
then 2738 h2_to_k1 = h2_to_k1 * (2.0 - 2.0*((rcvtgt(k1) - rcv(i,kb2)) / drcv_lim))
2742 drcv = (rcvtgt(k1) - rcv(i,kb2))
2747 dspice_det = (ds_dt_gauge*drcv_ds(i)*(t(i,kb2)-t(i,kb1)) - &
2748 dt_ds_gauge*drcv_dt(i)*(s(i,kb2)-s(i,kb1))) * &
2749 (h2 - h2_to_k1) / (h1 + h2)
2751 if (h(i,k1) > 10.0*angstrom)
then 2752 dspice_lim = ds_dt_gauge*drcv_ds(i)*(t(i,k1)-t(i,kb2)) - &
2753 dt_ds_gauge*drcv_dt(i)*(s(i,k1)-s(i,kb2))
2754 if (dspice_det*dspice_lim <= 0.0) dspice_lim = 0.0
2756 if (k1<nz)
then ;
if (h(i,k1+1) > 10.0*angstrom)
then 2757 dspice_lim2 = ds_dt_gauge*drcv_ds(i)*(t(i,k1+1)-t(i,kb2)) - &
2758 dt_ds_gauge*drcv_dt(i)*(s(i,k1+1)-s(i,kb2))
2759 if ((dspice_det*dspice_lim2 > 0.0) .and. &
2760 (abs(dspice_lim2) > abs(dspice_lim))) dspice_lim = dspice_lim2
2762 if (abs(dspice_det) > abs(dspice_lim)) dspice_det = dspice_lim
2764 i_denom = 1.0 / (drcv_ds(i)**2 + (dt_ds_gauge*drcv_dt(i))**2)
2765 t_det = t(i,kb2) + dt_ds_gauge * i_denom * &
2766 (dt_ds_gauge * drcv_dt(i) * drcv + drcv_ds(i) * dspice_det)
2767 s_det = s(i,kb2) + i_denom * &
2768 (drcv_ds(i) * drcv - dt_ds_gauge * drcv_dt(i) * dspice_det)
2770 r0_det = r0(i,kb2) + (t_det-t(i,kb2)) * dr0_dt(i) + &
2771 (s_det-s(i,kb2)) * dr0_ds(i)
2773 if (cs%BL_extrap_lim >= 0.)
then 2776 if (h(i,k1) > 10.0*angstrom)
then 2777 t_min = min(t(i,kb1), t(i,kb2), t(i,k1)) - cs%Allowed_T_chg
2778 t_max = max(t(i,kb1), t(i,kb2), t(i,k1)) + cs%Allowed_T_chg
2779 s_min = min(s(i,kb1), s(i,kb2), s(i,k1)) - cs%Allowed_S_chg
2780 s_max = max(s(i,kb1), s(i,kb2), s(i,k1)) + cs%Allowed_S_chg
2782 t_min = min(t(i,kb1), t(i,kb2)) - cs%Allowed_T_chg
2783 t_max = max(t(i,kb1), t(i,kb2)) + cs%Allowed_T_chg
2784 s_min = min(s(i,kb1), s(i,kb2)) - cs%Allowed_S_chg
2785 s_max = max(s(i,kb1), s(i,kb2)) + cs%Allowed_S_chg
2787 ihk1 = 1.0 / (h(i,k1) + h2_to_k1)
2788 t_new = (h(i,k1)*t(i,k1) + h2_to_k1*t_det) * ihk1
2789 s_new = (h(i,k1)*s(i,k1) + h2_to_k1*s_det) * ihk1
2791 if ((t_new < t_min) .or. (t_new > t_max) .or. &
2792 (s_new < s_min) .or. (s_new > s_max)) &
2796 h1_to_h2 = b1*h2*h2_to_k1 / (h2 - (1.0+b1)*h2_to_k1)
2798 ihk1 = 1.0 / (h(i,k1) + h_neglect + h2_to_k1)
2799 ih2f = 1.0 / ((h(i,kb2) - h2_to_k1) + h1_to_h2)
2801 rcv(i,kb2) = ((h(i,kb2)*rcv(i,kb2) - h2_to_k1*rcvtgt(k1)) + &
2802 h1_to_h2*rcv(i,kb1))*ih2f
2803 rcv(i,k1) = ((h(i,k1)+h_neglect)*rcv(i,k1) + h2_to_k1*rcvtgt(k1)) * ihk1
2805 t(i,kb2) = ((h(i,kb2)*t(i,kb2) - h2_to_k1*t_det) + &
2806 h1_to_h2*t(i,kb1)) * ih2f
2807 t(i,k1) = ((h(i,k1)+h_neglect)*t(i,k1) + h2_to_k1*t_det) * ihk1
2809 s(i,kb2) = ((h(i,kb2)*s(i,kb2) - h2_to_k1*s_det) + &
2810 h1_to_h2*s(i,kb1)) * ih2f
2811 s(i,k1) = ((h(i,k1)+h_neglect)*s(i,k1) + h2_to_k1*s_det) * ihk1
2814 r0(i,kb2) = ((h(i,kb2)*r0(i,kb2) - h2_to_k1*r0_det) + &
2815 h1_to_h2*r0(i,kb1)) * ih2f
2816 r0(i,k1) = ((h(i,k1)+h_neglect)*r0(i,k1) + h2_to_k1*r0_det) * ihk1
2818 h(i,kb1) = h(i,kb1) - h1_to_h2 ; h1 = h(i,kb1)
2819 h(i,kb2) = (h(i,kb2) - h2_to_k1) + h1_to_h2 ; h2 = h(i,kb2)
2820 h(i,k1) = h(i,k1) + h2_to_k1
2822 d_ea(i,kb1) = d_ea(i,kb1) - h1_to_h2
2823 d_ea(i,kb2) = (d_ea(i,kb2) - h2_to_k1) + h1_to_h2
2824 d_ea(i,k1) = d_ea(i,k1) + h2_to_k1
2825 h2_to_k1_rem = max(h2_to_k1_rem - h2_to_k1, 0.0)
2829 if ((k1>kb2+1) .and. (rcvtgt(k1-1) >= rcv(i,kb2)))
then 2830 do k1=k1,kb2+1,-1 ;
if (rcvtgt(k1-1) < rcv(i,kb2))
exit ;
enddo 2835 dr1 = rcvtgt(k0)-rcv(i,kb1) ; dr2 = rcv(i,kb2)-rcvtgt(k0)
2837 if ((k0>kb2) .and. (dr1 > 0.0) .and. (h1 > h_min_bl) .and. &
2838 (h2*dr2 < h1*dr1) .and. (r0(i,kb2) > r0(i,kb1)))
then 2843 stays_merge = 2.0*(h1+h2)*(h1*dr1 - h2*dr2) / &
2844 ((dr1+dr2)*h1 + dr1*(h1+h2) + &
2845 sqrt((dr2*h1-dr1*h2)**2 + 4*(h1+h2)*h2*(dr1+dr2)*dr2))
2847 stays_min_merge = max(h_min_bl, 2.0*h_min_bl - h_to_bl, &
2848 h1 - (h1+h2)*(r0(i,kb1) - r0_det) / (r0(i,kb2) - r0(i,kb1)))
2849 if ((stays_merge > stays_min_merge) .and. &
2850 (stays_merge + h2_to_k1_rem >= h1 + h2))
then 2851 mergeable_bl = .true.
2852 dpe_merge = g_2*(r0(i,kb2)-r0(i,kb1))*(h1-stays_merge)*(h2-stays_merge)
2856 if ((k1<=nz).and.(.not.mergeable_bl))
then 2860 dr2b = rcvtgt(k1)-rcv(i,kb2) ; dr21 = rcv(i,kb2) - rcv(i,kb1)
2861 if (dr2b*(h1+h2) < h2*dr21)
then 2863 h2_to_k1 = min(h2 - (h1+h2) * dr2b / dr21, h2_to_k1_rem)
2865 if (h2 > h2_to_k1)
then 2866 drcv = (rcvtgt(k1) - rcv(i,kb2))
2871 dspice_det = (ds_dt_gauge*drcv_ds(i)*(t(i,kb2)-t(i,kb1)) - &
2872 dt_ds_gauge*drcv_dt(i)*(s(i,kb2)-s(i,kb1))) * &
2873 (h2 - h2_to_k1) / (h1 + h2)
2875 if (h(i,k1) > 10.0*angstrom)
then 2876 dspice_lim = ds_dt_gauge*drcv_ds(i)*(t(i,k1)-t(i,kb2)) - &
2877 dt_ds_gauge*drcv_dt(i)*(s(i,k1)-s(i,kb2))
2878 if (dspice_det*dspice_lim <= 0.0) dspice_lim = 0.0
2880 if (k1<nz) then;
if (h(i,k1+1) > 10.0*angstrom)
then 2881 dspice_lim2 = ds_dt_gauge*drcv_ds(i)*(t(i,k1+1)-t(i,kb2)) - &
2882 dt_ds_gauge*drcv_dt(i)*(s(i,k1+1)-s(i,kb2))
2883 if ((dspice_det*dspice_lim2 > 0.0) .and. &
2884 (abs(dspice_lim2) > abs(dspice_lim))) dspice_lim = dspice_lim2
2886 if (abs(dspice_det) > abs(dspice_lim)) dspice_det = dspice_lim
2888 i_denom = 1.0 / (drcv_ds(i)**2 + (dt_ds_gauge*drcv_dt(i))**2)
2889 t_det = t(i,kb2) + dt_ds_gauge * i_denom * &
2890 (dt_ds_gauge * drcv_dt(i) * drcv + drcv_ds(i) * dspice_det)
2891 s_det = s(i,kb2) + i_denom * &
2892 (drcv_ds(i) * drcv - dt_ds_gauge * drcv_dt(i) * dspice_det)
2894 r0_det = r0(i,kb2) + (t_det-t(i,kb2)) * dr0_dt(i) + &
2895 (s_det-s(i,kb2)) * dr0_ds(i)
2900 ih2f = 1.0 / (h2 - h2_to_k1)
2902 t_min = min(t(i,kb2), t(i,kb1)) - cs%Allowed_T_chg
2903 t_max = max(t(i,kb2), t(i,kb1)) + cs%Allowed_T_chg
2904 t_new = (h2*t(i,kb2) - h2_to_k1*t_det)*ih2f
2905 if (t_new < t_min)
then 2906 h2_to_k1_lim = h2 * (t(i,kb2) - t_min) / (t_det - t_min)
2913 h2_to_k1 = h2_to_k1_lim
2914 ih2f = 1.0 / (h2 - h2_to_k1)
2915 elseif (t_new > t_max)
then 2916 h2_to_k1_lim = h2 * (t(i,kb2) - t_max) / (t_det - t_max)
2923 h2_to_k1 = h2_to_k1_lim
2924 ih2f = 1.0 / (h2 - h2_to_k1)
2926 s_min = max(min(s(i,kb2), s(i,kb1)) - cs%Allowed_S_chg, 0.0)
2927 s_max = max(s(i,kb2), s(i,kb1)) + cs%Allowed_S_chg
2928 s_new = (h2*s(i,kb2) - h2_to_k1*s_det)*ih2f
2929 if (s_new < s_min)
then 2930 h2_to_k1_lim = h2 * (s(i,kb2) - s_min) / (s_det - s_min)
2937 h2_to_k1 = h2_to_k1_lim
2938 ih2f = 1.0 / (h2 - h2_to_k1)
2939 elseif (s_new > s_max)
then 2940 h2_to_k1_lim = h2 * (s(i,kb2) - s_max) / (s_det - s_max)
2947 h2_to_k1 = h2_to_k1_lim
2948 ih2f = 1.0 / (h2 - h2_to_k1)
2951 ihk1 = 1.0 / (h(i,k1) + h_neglect + h2_to_k1)
2952 rcv(i,k1) = ((h(i,k1)+h_neglect)*rcv(i,k1) + h2_to_k1*rcvtgt(k1)) * ihk1
2953 rcv(i,kb2) = rcv(i,kb2) - h2_to_k1*drcv*ih2f
2955 t(i,kb2) = (h2*t(i,kb2) - h2_to_k1*t_det)*ih2f
2956 t(i,k1) = ((h(i,k1)+h_neglect)*t(i,k1) + h2_to_k1*t_det) * ihk1
2958 s(i,kb2) = (h2*s(i,kb2) - h2_to_k1*s_det) * ih2f
2959 s(i,k1) = ((h(i,k1)+h_neglect)*s(i,k1) + h2_to_k1*s_det) * ihk1
2962 r0(i,kb2) = (h2*r0(i,kb2) - h2_to_k1*r0_det) * ih2f
2963 r0(i,k1) = ((h(i,k1)+h_neglect)*r0(i,k1) + h2_to_k1*r0_det) * ihk1
2968 ihk1 = 1.0 / (h(i,k1) + h2)
2970 rcv(i,k1) = (h(i,k1)*rcv(i,k1) + h2*rcv(i,kb2)) * ihk1
2971 t(i,k1) = (h(i,k1)*t(i,k1) + h2*t(i,kb2)) * ihk1
2972 s(i,k1) = (h(i,k1)*s(i,k1) + h2*s(i,kb2)) * ihk1
2973 r0(i,k1) = (h(i,k1)*r0(i,k1) + h2*r0(i,kb2)) * ihk1
2976 h(i,k1) = h(i,k1) + h2_to_k1
2977 h(i,kb2) = h(i,kb2) - h2_to_k1 ; h2 = h(i,kb2)
2979 dpe_extrap = i2rho0*(r0_det-r0(i,kb2))*h2_to_k1*h2
2981 d_ea(i,kb2) = d_ea(i,kb2) - h2_to_k1
2982 d_ea(i,k1) = d_ea(i,k1) + h2_to_k1
2983 h2_to_k1_rem = max(h2_to_k1_rem - h2_to_k1, 0.0)
2990 h_det_h2 = max(h_min_bl-(h1+h2), 0.0)
2991 if (h_det_h2 > 0.0)
then 2997 h_det_to_h2 = min(h_to_bl, h_det_h2)
2998 h_ml_to_h2 = h_det_h2 - h_det_to_h2
2999 h_det_to_h1 = h_to_bl - h_det_to_h2
3000 h_ml_to_h1 = max(h_min_bl-h_det_to_h1,0.0)
3003 ihdet = 0.0 ;
if (h_to_bl > 0.0) ihdet = 1.0 / h_to_bl
3004 ih1f = 1.0 / (h_det_to_h1 + h_ml_to_h1)
3006 r0(i,kb2) = ((h2*r0(i,kb2) + h1*r0(i,kb1)) + &
3007 (h_det_to_h2*r0_to_bl*ihdet + h_ml_to_h2*r0(i,0))) * ih
3008 r0(i,kb1) = (h_det_to_h1*r0_to_bl*ihdet + h_ml_to_h1*r0(i,0)) * ih1f
3010 rcv(i,kb2) = ((h2*rcv(i,kb2) + h1*rcv(i,kb1)) + &
3011 (h_det_to_h2*rcv_to_bl*ihdet + h_ml_to_h2*rcv(i,0))) * ih
3012 rcv(i,kb1) = (h_det_to_h1*rcv_to_bl*ihdet + h_ml_to_h1*rcv(i,0)) * ih1f
3014 t(i,kb2) = ((h2*t(i,kb2) + h1*t(i,kb1)) + &
3015 (h_det_to_h2*t_to_bl*ihdet + h_ml_to_h2*t(i,0))) * ih
3016 t(i,kb1) = (h_det_to_h1*t_to_bl*ihdet + h_ml_to_h1*t(i,0)) * ih1f
3018 s(i,kb2) = ((h2*s(i,kb2) + h1*s(i,kb1)) + &
3019 (h_det_to_h2*s_to_bl*ihdet + h_ml_to_h2*s(i,0))) * ih
3020 s(i,kb1) = (h_det_to_h1*s_to_bl*ihdet + h_ml_to_h1*s(i,0)) * ih1f
3023 d_ea(i,1) = d_ea(i,1) - (h_ml_to_h1 + h_ml_to_h2)
3024 d_ea(i,kb1) = d_ea(i,kb1) + ((h_det_to_h1 + h_ml_to_h1) - h1)
3025 d_ea(i,kb2) = d_ea(i,kb2) + (h_min_bl - h2)
3027 h(i,kb1) = h_det_to_h1 + h_ml_to_h1 ; h(i,kb2) = h_min_bl
3028 h(i,0) = h(i,0) - (h_ml_to_h1 + h_ml_to_h2)
3031 if (
ALLOCATED(cs%diag_PE_detrain) .or.
ALLOCATED(cs%diag_PE_detrain2))
then 3032 r0_det = r0_to_bl*ihdet
3033 s1en = g_2 * idt_h2 * ( ((r0(i,kb2)-r0(i,kb1))*h1*h2 + &
3034 h_det_to_h2*( (r0(i,kb1)-r0_det)*h1 + (r0(i,kb2)-r0_det)*h2 ) + &
3035 h_ml_to_h2*( (r0(i,kb2)-r0(i,0))*h2 + (r0(i,kb1)-r0(i,0))*h1 + &
3036 (r0_det-r0(i,0))*h_det_to_h2 ) + &
3037 h_det_to_h1*h_ml_to_h1*(r0_det-r0(i,0))) - 2.0*gv%Rho0*dpe_extrap )
3039 if (
ALLOCATED(cs%diag_PE_detrain)) &
3040 cs%diag_PE_detrain(i,j) = cs%diag_PE_detrain(i,j) + s1en
3042 if (
ALLOCATED(cs%diag_PE_detrain2)) cs%diag_PE_detrain2(i,j) = &
3043 cs%diag_PE_detrain2(i,j) + s1en + idt_h2*rho0xg*dpe_extrap
3046 elseif ((h_to_bl > 0.0) .or. (h1 < h_min_bl) .or. (h2 < h_min_bl))
then 3051 h_from_ml = h_min_bl + max(h_min_bl-h2,0.0) - h1 - h_to_bl
3052 if (h_from_ml > 0.0)
then 3055 dpe_extrap = dpe_extrap - i2rho0*h_from_ml*(r0_to_bl - r0(i,0)*h_to_bl)
3056 r0_to_bl = r0_to_bl + h_from_ml*r0(i,0)
3057 rcv_to_bl = rcv_to_bl + h_from_ml*rcv(i,0)
3058 t_to_bl = t_to_bl + h_from_ml*t(i,0)
3059 s_to_bl = s_to_bl + h_from_ml*s(i,0)
3061 h_to_bl = h_to_bl + h_from_ml
3062 h(i,0) = h(i,0) - h_from_ml
3063 d_ea(i,1) = d_ea(i,1) - h_from_ml
3068 if (r0(i,kb2) - r0(i,kb1) > 1.0e-9*abs(r0(i,kb1) - r0_det)) &
3069 b1 = abs(r0(i,kb1) - r0_det) / (r0(i,kb2) - r0(i,kb1))
3070 stays_min = max((1.0-b1)*h1 - b1*h2, 0.0, h_min_bl - h_to_bl)
3071 stays_max = h1 - max(h_min_bl-h2,0.0)
3074 if (stays_max <= stays_min)
then 3076 mergeable_bl = .false.
3077 if (stays_max < h1) scale_slope = (h1 - stays_min) / (h1 - stays_max)
3082 i_ya = (h1 + h2) / ((h1 + h2) + h_to_bl)
3084 s1 = 0.5*(h1 + (h2 - bh0) * i_ya) ; s2 = h1 - s1
3089 s3sq = i_ya*max(bh0*h1-dpe_extrap, 0.0)
3091 s3sq = i_ya*(bh0*h1-min(dpe_extrap,0.0))
3094 if (s3sq == 0.0)
then 3097 elseif (s2*s2 <= s3sq)
then 3105 if (bh0 <= 0.0)
then ; stays = h1
3106 elseif (s2 > 0.0)
then 3108 if (s1 >= stays_max)
then ; stays = stays_max
3109 elseif (s1 >= 0.0)
then ; stays = s1 + sqrt(s2*s2 - s3sq)
3110 else ; stays = (h1*(s2-s1) - s3sq) / (-s1 + sqrt(s2*s2 - s3sq))
3114 if (s1 <= stays_min)
then ; stays = stays_min
3115 else ; stays = (h1*(s1-s2) + s3sq) / (s1 + sqrt(s2*s2 - s3sq))
3124 if (stays >= stays_max)
then ; stays = stays_max
3125 elseif (stays < stays_min)
then ; stays = stays_min
3129 dpe_det = g_2*((r0(i,kb1)*h_to_bl - r0_to_bl)*stays + &
3130 (r0(i,kb2)-r0(i,kb1)) * (h1-stays) * &
3131 (h2 - scale_slope*stays*((h1+h2)+h_to_bl)/(h1+h2)) ) - &
3134 if (dpe_time_ratio*h_to_bl > h_to_bl+h(i,0))
then 3135 dpe_ratio = (h_to_bl+h(i,0)) / h_to_bl
3137 dpe_ratio = dpe_time_ratio
3140 if ((mergeable_bl) .and. (num_events*dpe_ratio*dpe_det > dpe_merge))
then 3145 h1_to_k0 = (h1-stays_merge)
3146 stays = max(h_min_bl-h_to_bl,0.0)
3147 h1_to_h2 = stays_merge - stays
3149 ihk0 = 1.0 / ((h1_to_k0 + h2) + h(i,k0))
3150 ih1f = 1.0 / (h_to_bl + stays); ih2f = 1.0 / h1_to_h2
3151 ih12 = 1.0 / (h1 + h2)
3153 drcv_2dz = (rcv(i,kb1) - rcv(i,kb2)) * ih12
3154 drcv_stays = drcv_2dz*(h1_to_k0 + h1_to_h2)
3155 drcv_det = - drcv_2dz*(stays + h1_to_h2)
3156 rcv(i,k0) = ((h1_to_k0*(rcv(i,kb1) + drcv_det) + &
3157 h2*rcv(i,kb2)) + h(i,k0)*rcv(i,k0)) * ihk0
3158 rcv(i,kb2) = rcv(i,kb1) + drcv_2dz*(h1_to_k0-stays)
3159 rcv(i,kb1) = (rcv_to_bl + stays*(rcv(i,kb1) + drcv_stays)) * ih1f
3164 i_denom = 1.0 / (drcv_ds(i)**2 + (dt_ds_gauge*drcv_dt(i))**2)
3165 dspice_2dz = (ds_dt_gauge*drcv_ds(i)*(t(i,kb1)-t(i,kb2)) - &
3166 dt_ds_gauge*drcv_dt(i)*(s(i,kb1)-s(i,kb2))) * ih12
3167 dspice_lim = (ds_dt_gauge*dr0_ds(i)*(t_to_bl-t(i,kb1)*h_to_bl) - &
3168 dt_ds_gauge*dr0_dt(i)*(s_to_bl-s(i,kb1)*h_to_bl)) / h_to_bl
3169 if (dspice_lim * dspice_2dz <= 0.0) dspice_2dz = 0.0
3171 if (stays > 0.0)
then 3173 if (abs(dspice_lim) < abs(dspice_2dz*(h1_to_k0 + h1_to_h2))) &
3174 dspice_2dz = dspice_lim/(h1_to_k0 + h1_to_h2)
3176 dspice_stays = dspice_2dz*(h1_to_k0 + h1_to_h2)
3177 t_stays = t(i,kb1) + dt_ds_gauge * i_denom * &
3178 (dt_ds_gauge * drcv_dt(i) * drcv_stays + drcv_ds(i) * dspice_stays)
3179 s_stays = s(i,kb1) + i_denom * &
3180 (drcv_ds(i) * drcv_stays - dt_ds_gauge * drcv_dt(i) * dspice_stays)
3182 r0_stays = r0(i,kb1) + (t_stays-t(i,kb1)) * dr0_dt(i) + &
3183 (s_stays-s(i,kb1)) * dr0_ds(i)
3186 if (abs(dspice_lim) < abs(dspice_2dz*h1_to_k0)) &
3187 dspice_2dz = dspice_lim/h1_to_k0
3189 t_stays = 0.0 ; s_stays = 0.0 ; r0_stays = 0.0
3192 dspice_det = - dspice_2dz*(stays + h1_to_h2)
3193 t_det = t(i,kb1) + dt_ds_gauge * i_denom * &
3194 (dt_ds_gauge * drcv_dt(i) * drcv_det + drcv_ds(i) * dspice_det)
3195 s_det = s(i,kb1) + i_denom * &
3196 (drcv_ds(i) * drcv_det - dt_ds_gauge * drcv_dt(i) * dspice_det)
3198 r0_det = r0(i,kb1) + (t_det-t(i,kb1)) * dr0_dt(i) + &
3199 (s_det-s(i,kb1)) * dr0_ds(i)
3201 t(i,k0) = ((h1_to_k0*t_det + h2*t(i,kb2)) + h(i,k0)*t(i,k0)) * ihk0
3202 t(i,kb2) = (h1*t(i,kb1) - stays*t_stays - h1_to_k0*t_det) * ih2f
3203 t(i,kb1) = (t_to_bl + stays*t_stays) * ih1f
3205 s(i,k0) = ((h1_to_k0*s_det + h2*s(i,kb2)) + h(i,k0)*s(i,k0)) * ihk0
3206 s(i,kb2) = (h1*s(i,kb1) - stays*s_stays - h1_to_k0*s_det) * ih2f
3207 s(i,kb1) = (s_to_bl + stays*s_stays) * ih1f
3209 r0(i,k0) = ((h1_to_k0*r0_det + h2*r0(i,kb2)) + h(i,k0)*r0(i,k0)) * ihk0
3210 r0(i,kb2) = (h1*r0(i,kb1) - stays*r0_stays - h1_to_k0*r0_det) * ih2f
3211 r0(i,kb1) = (r0_to_bl + stays*r0_stays) * ih1f
3233 d_ea(i,kb1) = (d_ea(i,kb1) + h_to_bl) + (stays - h1)
3234 d_ea(i,kb2) = d_ea(i,kb2) + (h1_to_h2 - h2)
3235 d_ea(i,k0) = d_ea(i,k0) + (h1_to_k0 + h2)
3237 h(i,kb1) = stays + h_to_bl
3239 h(i,k0) = h(i,k0) + (h1_to_k0 + h2)
3240 if (
ALLOCATED(cs%diag_PE_detrain)) &
3241 cs%diag_PE_detrain(i,j) = cs%diag_PE_detrain(i,j) + idt_h2*dpe_merge
3242 if (
ALLOCATED(cs%diag_PE_detrain2)) cs%diag_PE_detrain2(i,j) = &
3243 cs%diag_PE_detrain2(i,j) + idt_h2*(dpe_det+rho0xg*dpe_extrap)
3248 h1_to_h2 = h1 - stays
3249 ih1f = 1.0 / (h_to_bl + stays) ; ih2f = 1.0 / (h2 + h1_to_h2)
3250 ih = 1.0 / (h1 + h2)
3251 dr0_2dz = (r0(i,kb1) - r0(i,kb2)) * ih
3252 r0(i,kb2) = (h2*r0(i,kb2) + h1_to_h2*(r0(i,kb1) - &
3253 scale_slope*dr0_2dz*stays)) * ih2f
3254 r0(i,kb1) = (r0_to_bl + stays*(r0(i,kb1) + &
3255 scale_slope*dr0_2dz*h1_to_h2)) * ih1f
3260 dr0 = scale_slope*dr0_2dz*h1_to_h2
3261 dspice_stays = (ds_dt_gauge*dr0_ds(i)*(t(i,kb1)-t(i,kb2)) - &
3262 dt_ds_gauge*dr0_dt(i)*(s(i,kb1)-s(i,kb2))) * &
3263 scale_slope*h1_to_h2 * ih
3264 if (h_to_bl > 0.0)
then 3265 dspice_lim = (ds_dt_gauge*dr0_ds(i)*(t_to_bl-t(i,kb1)*h_to_bl) - &
3266 dt_ds_gauge*dr0_dt(i)*(s_to_bl-s(i,kb1)*h_to_bl)) /&
3269 dspice_lim = ds_dt_gauge*dr0_ds(i)*(t(i,0)-t(i,kb1)) - &
3270 dt_ds_gauge*dr0_dt(i)*(s(i,0)-s(i,kb1))
3272 if (dspice_stays*dspice_lim <= 0.0)
then 3274 elseif (abs(dspice_stays) > abs(dspice_lim))
then 3275 dspice_stays = dspice_lim
3277 i_denom = 1.0 / (dr0_ds(i)**2 + (dt_ds_gauge*dr0_dt(i))**2)
3278 t_stays = t(i,kb1) + dt_ds_gauge * i_denom * &
3279 (dt_ds_gauge * dr0_dt(i) * dr0 + dr0_ds(i) * dspice_stays)
3280 s_stays = s(i,kb1) + i_denom * &
3281 (dr0_ds(i) * dr0 - dt_ds_gauge * dr0_dt(i) * dspice_stays)
3283 rcv_stays = rcv(i,kb1) + (t_stays-t(i,kb1)) * drcv_dt(i) + &
3284 (s_stays-s(i,kb1)) * drcv_ds(i)
3286 t(i,kb2) = (h2*t(i,kb2) + h1*t(i,kb1) - t_stays*stays) * ih2f
3287 t(i,kb1) = (t_to_bl + stays*t_stays) * ih1f
3288 s(i,kb2) = (h2*s(i,kb2) + h1*s(i,kb1) - s_stays*stays) * ih2f
3289 s(i,kb1) = (s_to_bl + stays*s_stays) * ih1f
3290 rcv(i,kb2) = (h2*rcv(i,kb2) + h1*rcv(i,kb1) - rcv_stays*stays) * ih2f
3291 rcv(i,kb1) = (rcv_to_bl + stays*rcv_stays) * ih1f
3310 d_ea(i,kb1) = d_ea(i,kb1) + ((stays - h1) + h_to_bl)
3311 d_ea(i,kb2) = d_ea(i,kb2) + h1_to_h2
3313 h(i,kb1) = stays + h_to_bl
3314 h(i,kb2) = h(i,kb2) + h1_to_h2
3316 if (
ALLOCATED(cs%diag_PE_detrain)) &
3317 cs%diag_PE_detrain(i,j) = cs%diag_PE_detrain(i,j) + idt_h2*dpe_det
3318 if (
ALLOCATED(cs%diag_PE_detrain2)) cs%diag_PE_detrain2(i,j) = &
3319 cs%diag_PE_detrain2(i,j) + idt_h2*(dpe_det+rho0xg*dpe_extrap)
3330 subroutine mixedlayer_detrain_1(h, T, S, R0, Rcv, RcvTgt, dt, dt_diag, d_ea, d_eb, &
3331 j, G, GV, CS, dRcv_dT, dRcv_dS, max_BL_det)
3332 type(ocean_grid_type),
intent(in) :: G
3333 type(verticalgrid_type),
intent(in) :: GV
3334 real,
dimension(SZI_(G),SZK0_(GV)),
intent(inout) :: h
3338 real,
dimension(SZI_(G),SZK0_(GV)),
intent(inout) :: T
3339 real,
dimension(SZI_(G),SZK0_(GV)),
intent(inout) :: S
3340 real,
dimension(SZI_(G),SZK0_(GV)),
intent(inout) :: R0
3342 real,
dimension(SZI_(G),SZK0_(GV)),
intent(inout) :: Rcv
3344 real,
dimension(SZK_(GV)),
intent(in) :: RcvTgt
3346 real,
intent(in) :: dt
3347 real,
intent(in) :: dt_diag
3348 real,
dimension(SZI_(G),SZK_(GV)),
intent(inout) :: d_ea
3352 real,
dimension(SZI_(G),SZK_(GV)),
intent(inout) :: d_eb
3356 integer,
intent(in) :: j
3359 real,
dimension(SZI_(G)),
intent(in) :: dRcv_dT
3363 real,
dimension(SZI_(G)),
intent(in) :: dRcv_dS
3366 real,
dimension(SZI_(G)),
intent(in) :: max_BL_det
3401 real :: max_det_rem(szi_(g))
3402 real :: detrain(szi_(g))
3405 real :: dT_dR, dS_dR, dRml, dR0_dRcv, dT_dS_wt2
3407 real :: Sdown, Tdown
3408 real :: dt_Time, Timescale = 86400.0*30.0
3409 real :: g_H2_2Rho0dt
3416 logical :: splittable_BL(szi_(g)), orthogonal_extrap
3419 integer :: i, is, ie, k, k1, nkmb, nz
3420 is = g%isc ; ie = g%iec ; nz = gv%ke
3421 nkmb = cs%nkml+cs%nkbl
3422 if (cs%nkbl /= 1)
call mom_error(fatal,
"MOM_mixed_layer: "// &
3423 "CS%nkbl must be 1 in mixedlayer_detrain_1.")
3425 dt_time = dt/timescale
3426 g_h2_2rho0dt = (gv%g_Earth * gv%H_to_m**2) / (2.0 * gv%Rho0 * dt_diag)
3427 g_h2_2dt = (gv%g_Earth * gv%H_to_m**2) / (2.0 * dt_diag)
3431 do i=is,ie ;
if (h(i,k) > 0.0)
then 3432 ih = 1.0 / (h(i,nkmb) + h(i,k))
3433 if (cs%TKE_diagnostics) &
3434 cs%diag_TKE_conv_s2(i,j) = cs%diag_TKE_conv_s2(i,j) + &
3435 g_h2_2rho0dt * h(i,k) * h(i,nkmb) * &
3436 (r0(i,nkmb) - r0(i,k))
3437 if (
ALLOCATED(cs%diag_PE_detrain)) &
3438 cs%diag_PE_detrain(i,j) = cs%diag_PE_detrain(i,j) + &
3439 g_h2_2dt * h(i,k) * h(i,nkmb) * (r0(i,nkmb) - r0(i,k))
3440 if (
ALLOCATED(cs%diag_PE_detrain2)) &
3441 cs%diag_PE_detrain2(i,j) = cs%diag_PE_detrain2(i,j) + &
3442 g_h2_2dt * h(i,k) * h(i,nkmb) * (r0(i,nkmb) - r0(i,k))
3444 r0(i,nkmb) = (r0(i,nkmb)*h(i,nkmb) + r0(i,k)*h(i,k)) * ih
3445 rcv(i,nkmb) = (rcv(i,nkmb)*h(i,nkmb) + rcv(i,k)*h(i,k)) * ih
3446 t(i,nkmb) = (t(i,nkmb)*h(i,nkmb) + t(i,k)*h(i,k)) * ih
3447 s(i,nkmb) = (s(i,nkmb)*h(i,nkmb) + s(i,k)*h(i,k)) * ih
3449 d_ea(i,k) = d_ea(i,k) - h(i,k)
3450 d_ea(i,nkmb) = d_ea(i,nkmb) + h(i,k)
3451 h(i,nkmb) = h(i,nkmb) + h(i,k)
3457 max_det_rem(i) = 10.0 * h(i,nkmb)
3458 if (max_bl_det(i) >= 0.0) max_det_rem(i) = max_bl_det(i)
3473 do i=is,ie ;
if (h(i,nkmb) > 0.0)
then 3474 if ((r0(i,0)<r0(i,nz)) .and. (r0(i,nz)<r0(i,nkmb)))
then 3475 if ((r0(i,nz)-r0(i,0))*h(i,0) > &
3476 (r0(i,nkmb)-r0(i,nz))*h(i,nkmb))
then 3477 detrain(i) = (r0(i,nkmb)-r0(i,nz))*h(i,nkmb) / (r0(i,nkmb)-r0(i,0))
3479 detrain(i) = (r0(i,nz)-r0(i,0))*h(i,0) / (r0(i,nkmb)-r0(i,0))
3482 d_eb(i,cs%nkml) = d_eb(i,cs%nkml) + detrain(i)
3483 d_ea(i,cs%nkml) = d_ea(i,cs%nkml) - detrain(i)
3484 d_eb(i,nkmb) = d_eb(i,nkmb) - detrain(i)
3485 d_ea(i,nkmb) = d_ea(i,nkmb) + detrain(i)
3487 if (
ALLOCATED(cs%diag_PE_detrain)) cs%diag_PE_detrain(i,j) = &
3488 cs%diag_PE_detrain(i,j) + g_h2_2dt * detrain(i)* &
3489 (h(i,0) + h(i,nkmb)) * (r0(i,nkmb) - r0(i,0))
3491 r0(i,0) = r0(i,0) - detrain(i)*(r0(i,0)-r0(i,nkmb)) / h(i,0)
3492 r0(i,nkmb) = r0(i,nkmb) - detrain(i)*(r0(i,nkmb)-x1) / h(i,nkmb)
3494 rcv(i,0) = rcv(i,0) - detrain(i)*(rcv(i,0)-rcv(i,nkmb)) / h(i,0)
3495 rcv(i,nkmb) = rcv(i,nkmb) - detrain(i)*(rcv(i,nkmb)-x1) / h(i,nkmb)
3497 t(i,0) = t(i,0) - detrain(i)*(t(i,0)-t(i,nkmb)) / h(i,0)
3498 t(i,nkmb) = t(i,nkmb) - detrain(i)*(t(i,nkmb)-x1) / h(i,nkmb)
3500 s(i,0) = s(i,0) - detrain(i)*(s(i,0)-s(i,nkmb)) / h(i,0)
3501 s(i,nkmb) = s(i,nkmb) - detrain(i)*(s(i,nkmb)-x1) / h(i,nkmb)
3511 if (h(i,nkmb) > 0.0)
then ; splittable_bl(i) = .true.
3512 else ; splittable_bl(i) = .false. ;
endif 3515 dt_ds_wt2 = cs%dT_dS_wt**2
3518 do k=nz-1,nkmb+1,-1 ;
do i=is,ie
3519 if (splittable_bl(i))
then 3520 if (rcvtgt(k)<=rcv(i,nkmb))
then 3525 splittable_bl(i) = .false.
3527 k1 = k+1 ; orthogonal_extrap = .false.
3532 if ((h(i,k+1) < 10.0*gv%Angstrom) .or. &
3533 ((rcvtgt(k+1)-rcv(i,nkmb)) >= 0.9*(rcv(i,k1) - rcv(i,0))))
then 3534 if (k>=nz-1)
then ; orthogonal_extrap = .true.
3535 elseif ((h(i,k+2) <= 10.0*gv%Angstrom) .and. &
3536 ((rcvtgt(k+1)-rcv(i,nkmb)) < 0.9*(rcv(i,k+2)-rcv(i,0))))
then 3538 else ; orthogonal_extrap = .true. ;
endif 3541 if ((r0(i,0) >= r0(i,k1)) .or. (rcv(i,0) >= rcv(i,nkmb))) cycle
3545 if (orthogonal_extrap)
then 3549 i_denom = 1.0 / (drcv_ds(i)**2 + dt_ds_wt2*drcv_dt(i)**2)
3550 dt_dr = dt_ds_wt2*drcv_dt(i) * i_denom
3551 ds_dr = drcv_ds(i) * i_denom
3553 dt_dr = (t(i,0) - t(i,k1)) / (rcv(i,0) - rcv(i,k1))
3554 ds_dr = (s(i,0) - s(i,k1)) / (rcv(i,0) - rcv(i,k1))
3556 drml = dt_time * (r0(i,nkmb) - r0(i,0)) * &
3557 (rcv(i,0) - rcv(i,k1)) / (r0(i,0) - r0(i,k1))
3559 if (drml < 0.0) cycle
3560 dr0_drcv = (r0(i,0) - r0(i,k1)) / (rcv(i,0) - rcv(i,k1))
3562 if ((rcv(i,nkmb) - drml < rcvtgt(k)) .and. (max_det_rem(i) > h(i,nkmb)))
then 3564 detrain(i) = h(i,nkmb)*(rcv(i,nkmb) - rcvtgt(k)) / &
3565 (rcvtgt(k+1) - rcvtgt(k))
3567 if (
ALLOCATED(cs%diag_PE_detrain)) cs%diag_PE_detrain(i,j) = &
3568 cs%diag_PE_detrain(i,j) - g_h2_2dt * detrain(i) * &
3569 (h(i,nkmb)-detrain(i)) * (rcvtgt(k+1) - rcvtgt(k)) * dr0_drcv
3571 tdown = detrain(i) * (t(i,nkmb) + dt_dr*(rcvtgt(k+1)-rcv(i,nkmb)))
3572 t(i,k) = (h(i,k) * t(i,k) + &
3573 (h(i,nkmb) * t(i,nkmb) - tdown)) / &
3574 (h(i,k) + (h(i,nkmb) - detrain(i)))
3575 t(i,k+1) = (h(i,k+1) * t(i,k+1) + tdown)/ &
3576 (h(i,k+1) + detrain(i))
3578 sdown = detrain(i) * (s(i,nkmb) + ds_dr*(rcvtgt(k+1)-rcv(i,nkmb)))
3579 s(i,k) = (h(i,k) * s(i,k) + &
3580 (h(i,nkmb) * s(i,nkmb) - sdown)) / &
3581 (h(i,k) + (h(i,nkmb) - detrain(i)))
3582 s(i,k+1) = (h(i,k+1) * s(i,k+1) + sdown)/ &
3583 (h(i,k+1) + detrain(i))
3585 rcv(i,nkmb) = rcv(i,0)
3587 d_ea(i,k+1) = d_ea(i,k+1) + detrain(i)
3588 d_ea(i,k) = d_ea(i,k) + (h(i,nkmb) - detrain(i))
3589 d_ea(i,nkmb) = d_ea(i,nkmb) - h(i,nkmb)
3591 h(i,k+1) = h(i,k+1) + detrain(i)
3592 h(i,k) = h(i,k) + h(i,nkmb) - detrain(i)
3596 detrain(i) = h(i,nkmb) * drml / (rcvtgt(k+1) - rcv(i,nkmb) + drml)
3597 if (detrain(i) > max_det_rem(i)) detrain(i) = max_det_rem(i)
3598 ih = 1.0 / (h(i,k+1) + detrain(i))
3600 tdown = (t(i,nkmb) + dt_dr*(rcvtgt(k+1)-rcv(i,nkmb)))
3601 t(i,nkmb) = t(i,nkmb) - dt_dr * drml
3602 t(i,k+1) = (h(i,k+1) * t(i,k+1) + detrain(i) * tdown) * ih
3603 sdown = (s(i,nkmb) + ds_dr*(rcvtgt(k+1)-rcv(i,nkmb)))
3607 s(i,nkmb) = s(i,nkmb) - ds_dr * drml
3608 s(i,k+1) = (h(i,k+1) * s(i,k+1) + detrain(i) * sdown) * ih
3610 d_ea(i,k+1) = d_ea(i,k+1) + detrain(i)
3611 d_ea(i,nkmb) = d_ea(i,nkmb) - detrain(i)
3613 h(i,k+1) = h(i,k+1) + detrain(i)
3614 h(i,nkmb) = h(i,nkmb) - detrain(i)
3616 if (
ALLOCATED(cs%diag_PE_detrain)) cs%diag_PE_detrain(i,j) = &
3617 cs%diag_PE_detrain(i,j) - g_h2_2dt * detrain(i) * dr0_drcv * &
3618 (h(i,nkmb)-detrain(i)) * (rcvtgt(k+1) - rcv(i,nkmb) + drml)
3629 if (h(i,nkmb) < 0.1*h(i,0))
then 3630 h_ent = 0.1*h(i,0) - h(i,nkmb)
3632 t(i,nkmb) = (h(i,nkmb)*t(i,nkmb) + h_ent*t(i,0)) * ih
3633 s(i,nkmb) = (h(i,nkmb)*s(i,nkmb) + h_ent*s(i,0)) * ih
3635 d_ea(i,1) = d_ea(i,1) - h_ent
3636 d_ea(i,nkmb) = d_ea(i,nkmb) + h_ent
3638 h(i,0) = h(i,0) - h_ent
3639 h(i,nkmb) = h(i,nkmb) + h_ent
3647 type(time_type),
target,
intent(in) :: Time
3648 type(ocean_grid_type),
intent(in) :: G
3649 type(verticalgrid_type),
intent(in) :: GV
3650 type(param_file_type),
intent(in) :: param_file
3652 type(diag_ctrl),
target,
intent(inout) :: diag
3665 #include "version_variable.h" 3666 character(len=40) :: mdl =
"MOM_mixed_layer" 3667 real :: omega_frac_dflt, ustar_min_dflt
3668 integer :: isd, ied, jsd, jed
3669 logical :: use_temperature, use_omega
3670 isd = g%isd ; ied = g%ied ; jsd = g%jsd ; jed = g%jed
3672 if (
associated(cs))
then 3673 call mom_error(warning,
"mixedlayer_init called with an associated"// &
3674 "associated control structure.")
3676 else ;
allocate(cs) ;
endif 3681 if (gv%nkml < 1)
return 3684 call log_version(param_file, mdl, version,
"")
3687 call log_param(param_file, mdl,
"NKML", cs%nkml, &
3688 "The number of sublayers within the mixed layer if \n"//&
3689 "BULKMIXEDLAYER is true.", units=
"nondim", default=2)
3690 cs%nkbl = gv%nk_rho_varies - gv%nkml
3691 call log_param(param_file, mdl,
"NKBL", cs%nkbl, &
3692 "The number of variable density buffer layers if \n"//&
3693 "BULKMIXEDLAYER is true.", units=
"nondim", default=2)
3694 call get_param(param_file, mdl,
"MSTAR", cs%mstar, &
3695 "The ratio of the friction velocity cubed to the TKE \n"//&
3696 "input to the mixed layer.",
"units=nondim", default=1.2)
3697 call get_param(param_file, mdl,
"NSTAR", cs%nstar, &
3698 "The portion of the buoyant potential energy imparted by \n"//&
3699 "surface fluxes that is available to drive entrainment \n"//&
3700 "at the base of mixed layer when that energy is positive.", &
3701 units=
"nondim", default=0.15)
3702 call get_param(param_file, mdl,
"BULK_RI_ML", cs%bulk_Ri_ML, &
3703 "The efficiency with which mean kinetic energy released \n"//&
3704 "by mechanically forced entrainment of the mixed layer \n"//&
3705 "is converted to turbulent kinetic energy.", units=
"nondim",&
3706 fail_if_missing=.true.)
3707 call get_param(param_file, mdl,
"ABSORB_ALL_SW", cs%absorb_all_sw, &
3708 "If true, all shortwave radiation is absorbed by the \n"//&
3709 "ocean, instead of passing through to the bottom mud.", &
3711 call get_param(param_file, mdl,
"TKE_DECAY", cs%TKE_decay, &
3712 "TKE_DECAY relates the vertical rate of decay of the \n"//&
3713 "TKE available for mechanical entrainment to the natural \n"//&
3714 "Ekman depth.", units=
"nondim", default=2.5)
3715 call get_param(param_file, mdl,
"NSTAR2", cs%nstar2, &
3716 "The portion of any potential energy released by \n"//&
3717 "convective adjustment that is available to drive \n"//&
3718 "entrainment at the base of mixed layer. By default \n"//&
3719 "NSTAR2=NSTAR.", units=
"nondim", default=cs%nstar)
3720 call get_param(param_file, mdl,
"BULK_RI_CONVECTIVE", cs%bulk_Ri_convective, &
3721 "The efficiency with which convectively released mean \n"//&
3722 "kinetic energy is converted to turbulent kinetic \n"//&
3723 "energy. By default BULK_RI_CONVECTIVE=BULK_RI_ML.", &
3724 units=
"nondim", default=cs%bulk_Ri_ML)
3725 call get_param(param_file, mdl,
"HMIX_MIN", cs%Hmix_min, &
3726 "The minimum mixed layer depth if the mixed layer depth \n"//&
3727 "is determined dynamically.", units=
"m", default=0.0)
3729 call get_param(param_file, mdl,
"LIMIT_BUFFER_DETRAIN", cs%limit_det, &
3730 "If true, limit the detrainment from the buffer layers \n"//&
3731 "to not be too different from the neighbors.", default=.false.)
3732 call get_param(param_file, mdl,
"ALLOWED_DETRAIN_TEMP_CHG", cs%Allowed_T_chg, &
3733 "The amount by which temperature is allowed to exceed \n"//&
3734 "previous values during detrainment.", units=
"K", default=0.5)
3735 call get_param(param_file, mdl,
"ALLOWED_DETRAIN_SALT_CHG", cs%Allowed_S_chg, &
3736 "The amount by which salinity is allowed to exceed \n"//&
3737 "previous values during detrainment.", units=
"PSU", default=0.1)
3738 call get_param(param_file, mdl,
"ML_DT_DS_WEIGHT", cs%dT_dS_wt, &
3739 "When forced to extrapolate T & S to match the layer \n"//&
3740 "densities, this factor (in deg C / PSU) is combined \n"//&
3741 "with the derivatives of density with T & S to determine \n"//&
3742 "what direction is orthogonal to density contours. It \n"//&
3743 "should be a typical value of (dR/dS) / (dR/dT) in \n"//&
3744 "oceanic profiles.", units=
"degC PSU-1", default=6.0)
3745 call get_param(param_file, mdl,
"BUFFER_LAYER_EXTRAP_LIMIT", cs%BL_extrap_lim, &
3746 "A limit on the density range over which extrapolation \n"//&
3747 "can occur when detraining from the buffer layers, \n"//&
3748 "relative to the density range within the mixed and \n"//&
3749 "buffer layers, when the detrainment is going into the \n"//&
3750 "lightest interior layer, nondimensional, or a negative \n"//&
3751 "value not to apply this limit.", units=
"nondim", default = -1.0)
3752 call get_param(param_file, mdl,
"DEPTH_LIMIT_FLUXES", cs%H_limit_fluxes, &
3753 "The surface fluxes are scaled away when the total ocean \n"//&
3754 "depth is less than DEPTH_LIMIT_FLUXES.", &
3755 units=
"m", default=0.1*cs%Hmix_min)
3756 call get_param(param_file, mdl,
"OMEGA",cs%omega, &
3757 "The rotation rate of the earth.", units=
"s-1", &
3759 call get_param(param_file, mdl,
"ML_USE_OMEGA", use_omega, &
3760 "If true, use the absolute rotation rate instead of the \n"//&
3761 "vertical component of rotation when setting the decay \n"//&
3762 "scale for turbulence.", default=.false., do_not_log=.true.)
3763 omega_frac_dflt = 0.0
3765 call mom_error(warning,
"ML_USE_OMEGA is depricated; use ML_OMEGA_FRAC=1.0 instead.")
3766 omega_frac_dflt = 1.0
3768 call get_param(param_file, mdl,
"ML_OMEGA_FRAC", cs%omega_frac, &
3769 "When setting the decay scale for turbulence, use this \n"//&
3770 "fraction of the absolute rotation rate blended with the \n"//&
3771 "local value of f, as sqrt((1-of)*f^2 + of*4*omega^2).", &
3772 units=
"nondim", default=omega_frac_dflt)
3773 call get_param(param_file, mdl,
"ML_RESORT", cs%ML_resort, &
3774 "If true, resort the topmost layers by potential density \n"//&
3775 "before the mixed layer calculations.", default=.false.)
3777 call get_param(param_file, mdl,
"ML_PRESORT_NK_CONV_ADJ", cs%ML_presort_nz_conv_adj, &
3778 "Convectively mix the first ML_PRESORT_NK_CONV_ADJ \n"//&
3779 "layers before sorting when ML_RESORT is true.", &
3780 units=
"nondim", default=0, fail_if_missing=.true.)
3782 ustar_min_dflt = 2e-4*cs%omega*(gv%Angstrom_z + gv%H_to_m*gv%H_subroundoff)
3783 call get_param(param_file, mdl,
"BML_USTAR_MIN", cs%ustar_min, &
3784 "The minimum value of ustar that should be used by the \n"//&
3785 "bulk mixed layer model in setting vertical TKE decay \n"//&
3786 "scales. This must be greater than 0.", units=
"m s-1", &
3787 default=ustar_min_dflt)
3788 if (cs%ustar_min<=0.0)
call mom_error(fatal,
"BML_USTAR_MIN must be positive.")
3790 call get_param(param_file, mdl,
"RESOLVE_EKMAN", cs%Resolve_Ekman, &
3791 "If true, the NKML>1 layers in the mixed layer are \n"//&
3792 "chosen to optimally represent the impact of the Ekman \n"//&
3793 "transport on the mixed layer TKE budget. Otherwise, \n"//&
3794 "the sublayers are distributed uniformly through the \n"//&
3795 "mixed layer.", default=.false.)
3796 call get_param(param_file, mdl,
"CORRECT_ABSORPTION_DEPTH", cs%correct_absorption, &
3797 "If true, the average depth at which penetrating shortwave \n"//&
3798 "radiation is absorbed is adjusted to match the average \n"//&
3799 "heating depth of an exponential profile by moving some \n"//&
3800 "of the heating upward in the water column.", default=.false.)
3801 call get_param(param_file, mdl,
"DO_RIVERMIX", cs%do_rivermix, &
3802 "If true, apply additional mixing whereever there is \n"//&
3803 "runoff, so that it is mixed down to RIVERMIX_DEPTH, \n"//&
3804 "if the ocean is that deep.", default=.false.)
3805 if (cs%do_rivermix) &
3806 call get_param(param_file, mdl,
"RIVERMIX_DEPTH", cs%rivermix_depth, &
3807 "The depth to which rivers are mixed if DO_RIVERMIX is \n"//&
3808 "defined.", units=
"m", default=0.0)
3809 call get_param(param_file, mdl,
"USE_RIVER_HEAT_CONTENT", cs%use_river_heat_content, &
3810 "If true, use the fluxes%runoff_Hflx field to set the \n"//&
3811 "heat carried by runoff, instead of using SST*CP*liq_runoff.", &
3813 call get_param(param_file, mdl,
"USE_CALVING_HEAT_CONTENT", cs%use_calving_heat_content, &
3814 "If true, use the fluxes%calving_Hflx field to set the \n"//&
3815 "heat carried by runoff, instead of using SST*CP*froz_runoff.", &
3818 call get_param(param_file, mdl,
"ALLOW_CLOCKS_IN_OMP_LOOPS", &
3819 cs%allow_clocks_in_omp_loops, &
3820 "If true, clocks can be called from inside loops that can \n"//&
3821 "be threaded. To run with multiple threads, set to False.", &
3824 cs%id_ML_depth = register_diag_field(
'ocean_model',
'h_ML', diag%axesT1, &
3825 time,
'Surface mixed layer depth',
'meter')
3826 cs%id_TKE_wind = register_diag_field(
'ocean_model',
'TKE_wind', diag%axesT1, &
3827 time,
'Wind-stirring source of mixed layer TKE',
'meter3 second-3')
3828 cs%id_TKE_RiBulk = register_diag_field(
'ocean_model',
'TKE_RiBulk', diag%axesT1, &
3829 time,
'Mean kinetic energy source of mixed layer TKE',
'meter3 second-3')
3830 cs%id_TKE_conv = register_diag_field(
'ocean_model',
'TKE_conv', diag%axesT1, &
3831 time,
'Convective source of mixed layer TKE',
'meter3 second-3')
3832 cs%id_TKE_pen_SW = register_diag_field(
'ocean_model',
'TKE_pen_SW', diag%axesT1, &
3833 time,
'TKE consumed by mixing penetrative shortwave radation through the mixed layer',
'meter3 second-3')
3834 cs%id_TKE_mixing = register_diag_field(
'ocean_model',
'TKE_mixing', diag%axesT1, &
3835 time,
'TKE consumed by mixing that deepens the mixed layer',
'meter3 second-3')
3836 cs%id_TKE_mech_decay = register_diag_field(
'ocean_model',
'TKE_mech_decay', diag%axesT1, &
3837 time,
'Mechanical energy decay sink of mixed layer TKE',
'meter3 second-3')
3838 cs%id_TKE_conv_decay = register_diag_field(
'ocean_model',
'TKE_conv_decay', diag%axesT1, &
3839 time,
'Convective energy decay sink of mixed layer TKE',
'meter3 second-3')
3840 cs%id_TKE_conv_s2 = register_diag_field(
'ocean_model',
'TKE_conv_s2', diag%axesT1, &
3841 time,
'Spurious source of mixed layer TKE from sigma2',
'meter3 second-3')
3842 cs%id_PE_detrain = register_diag_field(
'ocean_model',
'PE_detrain', diag%axesT1, &
3843 time,
'Spurious source of potential energy from mixed layer detrainment',
'Watt meter-2')
3844 cs%id_PE_detrain2 = register_diag_field(
'ocean_model',
'PE_detrain2', diag%axesT1, &
3845 time,
'Spurious source of potential energy from mixed layer only detrainment',
'Watt meter-2')
3846 cs%id_h_mismatch = register_diag_field(
'ocean_model',
'h_miss_ML', diag%axesT1, &
3847 time,
'Summed absolute mismatch in entrainment terms',
'meter')
3848 cs%id_Hsfc_used = register_diag_field(
'ocean_model',
'Hs_used', diag%axesT1, &
3849 time,
'Surface region thickness that is used',
'meter')
3850 cs%id_Hsfc_max = register_diag_field(
'ocean_model',
'Hs_max', diag%axesT1, &
3851 time,
'Maximum surface region thickness',
'meter')
3852 cs%id_Hsfc_min = register_diag_field(
'ocean_model',
'Hs_min', diag%axesT1, &
3853 time,
'Minimum surface region thickness',
'meter')
3855 if (cs%limit_det .or. (cs%id_Hsfc_min > 0))
then 3856 call get_param(param_file, mdl,
"LIMIT_BUFFER_DET_DH_SFC", cs%lim_det_dH_sfc, &
3857 "The fractional limit in the change between grid points \n"//&
3858 "of the surface region (mixed & buffer layer) thickness.", &
3859 units=
"nondim", default=0.5)
3860 call get_param(param_file, mdl,
"LIMIT_BUFFER_DET_DH_BATHY", cs%lim_det_dH_bathy, &
3861 "The fraction of the total depth by which the thickness \n"//&
3862 "of the surface region (mixed & buffer layer) is allowed \n"//&
3863 "to change between grid points.", units=
"nondim", default=0.2)
3866 call get_param(param_file, mdl,
"ENABLE_THERMODYNAMICS", use_temperature, &
3867 "If true, temperature and salinity are used as state \n"//&
3868 "variables.", default=.true.)
3870 if (use_temperature)
then 3871 call get_param(param_file, mdl,
"PEN_SW_NBANDS", cs%nsw, default=1)
3875 if (max(cs%id_TKE_wind, cs%id_TKE_RiBulk, cs%id_TKE_conv, &
3876 cs%id_TKE_mixing, cs%id_TKE_pen_SW, cs%id_TKE_mech_decay, &
3877 cs%id_TKE_conv_decay) > 0)
then 3878 call safe_alloc_alloc(cs%diag_TKE_wind, isd, ied, jsd, jed)
3879 call safe_alloc_alloc(cs%diag_TKE_RiBulk, isd, ied, jsd, jed)
3880 call safe_alloc_alloc(cs%diag_TKE_conv, isd, ied, jsd, jed)
3881 call safe_alloc_alloc(cs%diag_TKE_pen_SW, isd, ied, jsd, jed)
3882 call safe_alloc_alloc(cs%diag_TKE_mixing, isd, ied, jsd, jed)
3883 call safe_alloc_alloc(cs%diag_TKE_mech_decay, isd, ied, jsd, jed)
3884 call safe_alloc_alloc(cs%diag_TKE_conv_decay, isd, ied, jsd, jed)
3885 call safe_alloc_alloc(cs%diag_TKE_conv_s2, isd, ied, jsd, jed)
3887 cs%TKE_diagnostics = .true.
3889 if (cs%id_PE_detrain > 0)
call safe_alloc_alloc(cs%diag_PE_detrain, isd, ied, jsd, jed)
3890 if (cs%id_PE_detrain2 > 0)
call safe_alloc_alloc(cs%diag_PE_detrain2, isd, ied, jsd, jed)
3891 if (cs%id_ML_depth > 0)
call safe_alloc_alloc(cs%ML_depth, isd, ied, jsd, jed)
3893 if(cs%allow_clocks_in_omp_loops)
then 3894 id_clock_detrain = cpu_clock_id(
'(Ocean mixed layer detrain)', grain=clock_routine)
3895 id_clock_mech = cpu_clock_id(
'(Ocean mixed layer mechanical entrainment)', grain=clock_routine)
3896 id_clock_conv = cpu_clock_id(
'(Ocean mixed layer convection)', grain=clock_routine)
3897 if (cs%ML_resort)
then 3898 id_clock_resort = cpu_clock_id(
'(Ocean mixed layer resorting)', grain=clock_routine)
3900 id_clock_adjustment = cpu_clock_id(
'(Ocean mixed layer convective adjustment)', grain=clock_routine)
3902 id_clock_eos = cpu_clock_id(
'(Ocean mixed layer EOS)', grain=clock_routine)
3905 if (cs%limit_det .or. (cs%id_Hsfc_min > 0)) &
3906 id_clock_pass = cpu_clock_id(
'(Ocean mixed layer halo updates)', grain=clock_routine)
3919 function ef4(H, E, L, dR_de)
3920 real,
intent(in) :: H
3922 real,
intent(in) :: E
3923 real,
intent(in) :: L
3924 real,
intent(inout),
optional :: dR_de
3942 exp_lhpe = exp(-l*(e+h))
3944 r = exp_lhpe * (e*i_hpe/h - 0.5*l*log(h*i_hpe) + 0.5*l*l*e)
3945 if (
PRESENT(dr_de)) &
3946 dr_de = -l*r + exp_lhpe*(i_hpe*i_hpe + 0.5*l*i_hpe + 0.5*l*l)
subroutine mechanical_entrainment(h, d_eb, htot, Ttot, Stot, uhtot, vhtot, R0_tot, Rcv_tot, u, v, T, S, R0, Rcv, eps, dR0_dT, dRcv_dT, cMKE, Idt_diag, nsw, Pen_SW_bnd, opacity_band, TKE, Idecay_len_TKE, j, ksort, G, GV, CS)
This subroutine calculates mechanically driven entrainment.
This module implements boundary forcing for MOM6.
Ocean grid type. See mom_grid for details.
Calculates density of sea water from T, S and P.
subroutine, public bulkmixedlayer_init(Time, G, GV, param_file, diag, CS)
subroutine mixedlayer_convection(h, d_eb, htot, Ttot, Stot, uhtot, vhtot, R0_tot, Rcv_tot, u, v, T, S, R0, Rcv, eps, dR0_dT, dRcv_dT, dR0_dS, dRcv_dS, netMassInOut, netMassOut, Net_heat, Net_salt, nsw, Pen_SW_bnd, opacity_band, Conv_en, dKE_FC, j, ksort, G, GV, CS, tv, fluxes, dt, aggregate_FW_forcing)
This subroutine causes the mixed layer to entrain to the depth of free convection. The depth of free convection is the shallowest depth at which the fluid is denser than the average of the fluid above.
Provides the ocean grid type.
subroutine, public do_group_pass(group, MOM_dom)
subroutine, public absorbremainingsw(G, GV, h, opacity_band, nsw, j, dt, H_limit_fluxes, adjustAbsorptionProfile, absorbAllSW, T, Pen_SW_bnd, eps, ksort, htot, Ttot, TKE, dSV_dT)
Apply shortwave heating below surface boundary layer.
subroutine mixedlayer_detrain_2(h, T, S, R0, Rcv, RcvTgt, dt, dt_diag, d_ea, j, G, GV, CS, dR0_dT, dR0_dS, dRcv_dT, dRcv_dS, max_BL_det)
This subroutine moves any water left in the former mixed layers into the two buffer layers and may al...
subroutine sort_ml(h, R0, eps, G, GV, CS, ksort)
This subroutine generates an array of indices that are sorted by layer density.
subroutine mixedlayer_detrain_1(h, T, S, R0, Rcv, RcvTgt, dt, dt_diag, d_ea, d_eb, j, G, GV, CS, dRcv_dT, dRcv_dS, max_BL_det)
This subroutine moves any water left in the former mixed layers into the single buffer layers and may...
subroutine, public calculate_density_derivs(T, S, pressure, drho_dT, drho_dS, start, npts, EOS)
Calls the appropriate subroutine to calculate density derivatives for 1-D array inputs.
subroutine find_starting_tke(htot, h_CA, fluxes, Conv_En, cTKE, dKE_FC, dKE_CA, TKE, TKE_river, Idecay_len_TKE, cMKE, dt, Idt_diag, j, ksort, G, GV, CS)
This subroutine determines the TKE available at the depth of free convection to drive mechanical entr...
Structure that contains pointers to the boundary forcing used to drive the liquid ocean simulated by ...
subroutine convective_adjustment(h, u, v, R0, Rcv, T, S, eps, d_eb, dKE_CA, cTKE, j, G, GV, CS, nz_conv)
This subroutine does instantaneous convective entrainment into the buffer layers and mixed layers to ...
Provides subroutines for quantities specific to the equation of state.
subroutine, public extractfluxes1d(G, GV, fluxes, optics, nsw, j, dt, DepthBeforeScalingFluxes, useRiverHeatContent, useCalvingHeatContent, h, T, netMassInOut, netMassOut, net_heat, net_salt, pen_SW_bnd, tv, aggregate_FW_forcing, nonpenSW, netmassInOut_rate, net_Heat_Rate, net_salt_rate, pen_sw_bnd_Rate, skip_diags)
This subroutine extracts fluxes from the surface fluxes type. It works on a j-row for optimization pu...
The thermo_var_ptrs structure contains pointers to an assortment of thermodynamic fields that may be ...
integer id_clock_adjustment
real function ef4(H, E, L, dR_de)
This subroutine returns an approximation to the integral R = exp(-L*(H+E)) integral(LH to L(H+E)) L/(...
subroutine, public bulkmixedlayer(h_3d, u_3d, v_3d, tv, fluxes, dt, ea, eb, G, GV, CS, optics, Hml, aggregate_FW_forcing, dt_diag, last_call)
This subroutine partially steps the bulk mixed layer model. The following processes are executed...
subroutine, public mom_error(level, message, all_print)
subroutine resort_ml(h, T, S, R0, Rcv, RcvTgt, eps, d_ea, d_eb, ksort, G, GV, CS, dR0_dT, dR0_dS, dRcv_dT, dRcv_dS)
This subroutine actually moves properties between layers to achieve a resorted state, with all of the resorted water either moved into the correct interior layers or in the top nkmb layers.