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)
806 type(ocean_grid_type),
intent(in) :: G
807 type(verticalGrid_type),
intent(in) :: GV
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
833 type(unit_scale_type),
intent(in) :: US
834 type(bulkmixedlayer_CS),
pointer :: CS
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)
943 type(ocean_grid_type),
intent(in) :: G
944 type(verticalGrid_type),
intent(in) :: GV
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)), &
1014 type(unit_scale_type),
intent(in) :: US
1015 type(bulkmixedlayer_CS),
pointer :: CS
1016 type(thermo_var_ptrs),
intent(inout) :: tv
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)
1316 type(ocean_grid_type),
intent(in) :: G
1317 type(verticalGrid_type),
intent(in) :: GV
1318 type(unit_scale_type),
intent(in) :: US
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)), &
1355 type(bulkmixedlayer_CS),
pointer :: CS
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)
1503 type(ocean_grid_type),
intent(in) :: G
1504 type(verticalGrid_type),
intent(in) :: GV
1505 type(unit_scale_type),
intent(in) :: US
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)), &
1565 type(bulkmixedlayer_CS),
pointer :: CS
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)
1841 type(ocean_grid_type),
intent(in) :: G
1842 type(verticalGrid_type),
intent(in) :: GV
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
1848 type(bulkmixedlayer_CS),
pointer :: CS
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)
1893 type(ocean_grid_type),
intent(in) :: G
1894 type(verticalGrid_type),
intent(in) :: GV
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
1918 type(bulkmixedlayer_CS),
pointer :: CS
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)
2214 type(ocean_grid_type),
intent(in) :: G
2215 type(verticalGrid_type),
intent(in) :: GV
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
2233 type(unit_scale_type),
intent(in) :: US
2234 type(bulkmixedlayer_CS),
pointer :: CS
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)
3105 type(ocean_grid_type),
intent(in) :: G
3106 type(verticalGrid_type),
intent(in) :: GV
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
3129 type(unit_scale_type),
intent(in) :: US
3130 type(bulkmixedlayer_CS),
pointer :: CS
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
3391 type(ocean_grid_type),
intent(in) :: g
3392 type(verticalgrid_type),
intent(in) :: gv
3393 type(unit_scale_type),
intent(in) :: us
3394 type(param_file_type),
intent(in) :: param_file
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 3429 call log_version(param_file, mdl, version,
"")
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)
This module implements boundary forcing for MOM6.
Ocean grid type. See mom_grid for details.
The control structure with parameters for the MOM_bulk_mixed_layer module.
Calculates density of sea water from T, S and P.
A structure that can be parsed to read and document run-time parameters.
Provides the ocean grid type.
Wraps the MPP cpu clock functions.
The MOM6 facility to parse input files for runtime parameters.
An overloaded interface to log the values of various types of parameters.
Make a diagnostic available for averaging or output.
Describes various unit conversion factors.
Routines used to calculate the opacity of the ocean.
Provides a transparent unit rescaling type to facilitate dimensional consistency testing.
Describes the decomposed MOM domain and has routines for communications across PEs.
Build mixed layer parameterization.
Routines for error handling and I/O management.
Structure that contains pointers to the boundary forcing used to drive the liquid ocean simulated by ...
Calculate the derivatives of density with temperature and salinity from T, S, and P...
Provides subroutines for quantities specific to the equation of state.
An overloaded interface to log version information about modules.
Describes the vertical ocean grid, including unit conversion factors.
Set up a group of halo updates.
Pointers to an assortment of thermodynamic fields that may be available, including potential temperat...
This type is used to store information about ocean optical properties.
Provides a transparent vertical ocean grid type and supporting routines.
Provides transparent structures with groups of MOM6 variables and supporting routines.
An overloaded interface to read and log the values of various types of parameters.