67 use mom_cpu_clock, only : cpu_clock_id, cpu_clock_begin, cpu_clock_end, clock_routine
79 implicit none ;
private 81 #include <MOM_memory.h> 97 real :: mixlenexponent
102 real :: mke_to_tke_effic
113 real :: wstar_ustar_coef
118 real :: vstar_scale_fac
121 real :: ekman_scale_coef
125 real :: translay_scale
134 real :: n2_dissipation_scale_neg
135 real :: n2_dissipation_scale_pos
154 real :: mstar_xint_up
155 real :: mstar_at_xint
157 real :: lt_enhance_coef
158 real :: lt_enhance_exp
159 real :: mstar_n = -2.
160 real :: mstar_a,mstar_a2
161 real :: mstar_b,mstar_b2
164 real :: mstar_coef = 0.3
166 real :: lac_mldoob_stab
167 real :: lac_ekoob_stab
168 real :: lac_mldoob_un
170 real :: ladepthratio=0.04
171 real :: max_enhance_m = 5.
173 type(time_type),
pointer :: time
174 integer :: lt_enhance_form = 0
175 integer :: mstar_mode = 0
177 integer :: const_mstar=0,mld_o_obukhov=1,ekman_o_obukhov=2
178 logical :: mstar_flatcap=.true.
179 logical :: tke_diagnostics = .false.
180 logical :: use_la_windsea = .false.
181 logical :: orig_pe_calc = .true.
182 logical :: use_mld_iteration=.false.
183 logical :: orig_mld_iteration=.false.
184 logical :: mld_iteration_guess=.false.
186 logical :: mixing_diagnostics = .false.
192 real,
allocatable,
dimension(:,:) :: &
198 diag_tke_mech_decay, &
199 diag_tke_conv_decay, &
213 real,
allocatable,
dimension(:,:,:) :: &
216 integer :: id_ml_depth = -1, id_tke_wind = -1, id_tke_mixing = -1
217 integer :: id_tke_mke = -1, id_tke_conv = -1, id_tke_forcing = -1
218 integer :: id_tke_mech_decay = -1, id_tke_conv_decay = -1
219 integer :: id_hsfc_used = -1
220 integer :: id_mixing_length = -1, id_velocity_scale = -1
221 integer :: id_osbl = -1, id_lt_enhancement = -1, id_mstar_mix = -1
222 integer :: id_mld_ekman, id_mld_obukhov, id_ekman_obukhov
223 integer :: id_la, id_la_mod
234 subroutine energetic_pbl(h_3d, u_3d, v_3d, tv, fluxes, dt, Kd_int, G, GV, CS, &
235 dSV_dT, dSV_dS, TKE_forced, Buoy_Flux, dt_diag, last_call, &
236 dT_expected, dS_expected )
239 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)), &
240 intent(inout) :: h_3d
243 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)), &
246 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)), &
249 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)), &
253 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)), &
256 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)), &
257 intent(in) :: TKE_forced
263 type(
forcing),
intent(inout) :: fluxes
266 real,
intent(in) :: dt
267 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)+1), &
268 intent(out) :: Kd_int
272 real,
dimension(SZI_(G),SZJ_(G)), &
273 intent(in) :: Buoy_Flux
274 real,
optional,
intent(in) :: dt_diag
277 logical,
optional,
intent(in) :: last_call
281 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)), &
282 optional,
intent(out) :: dT_expected, dS_expected
333 real,
dimension(SZI_(G),SZK_(GV)) :: &
339 real,
dimension(SZI_(G),SZK_(GV)+1) :: &
344 real,
dimension(SZI_(G)) :: &
361 real,
dimension(SZI_(G),SZK_(GV)) :: &
373 real,
dimension(SZK_(GV)) :: &
378 real,
dimension(SZK_(GV)) :: &
387 real,
dimension(SZI_(G)) :: &
391 real,
dimension(SZK_(GV)+1) :: &
451 real :: Kd_guess0, PE_chg_g0, dPEa_dKd_g0, Kddt_h_g0
461 real :: TKE_left_min, TKE_left_max, Kddt_h_max, Kddt_h_min
469 logical :: convectively_stable
470 logical,
dimension(SZI_(G)) :: &
473 logical :: sfc_disconnect
479 real,
dimension(SZI_(G),SZJ_(G)) :: &
481 logical :: write_diags
482 logical :: reset_diags
485 real :: dTKE_conv, dTKE_forcing, dTKE_mixing
486 real :: dTKE_MKE, dTKE_mech_decay, dTKE_conv_decay
490 real :: MLD_guess, MLD_found
491 real :: max_MLD, min_MLD
512 logical :: OBL_CONVERGED
515 integer :: MAX_OBL_IT=20
524 real,
dimension(SZK_(GV)+1) :: Vstar_Used, &
527 logical :: OBL_IT_STATS=.false.
528 REAL :: ITguess(20), ITresult(20),ITmax(20),ITmin(20)
530 integer,
save :: MAXIT=0
531 integer,
save :: MINIT=1e8
532 integer,
save :: SUMIT=0
533 integer,
save :: NUMIT=0
535 integer,
save :: CONVERGED
536 integer,
save :: NOTCONVERGED
538 real :: N2_dissipation
546 real :: MLD_o_Obukhov_stab
547 real :: Ekman_o_Obukhov_stab
548 real :: MLD_o_Obukhov_un
549 real :: Ekman_o_Obukhov_un
553 real :: MLD_over_STAB
558 real :: MSTAR_Conv_Adj
559 real :: MSTAR_STAB, MSTAR_ROT
560 logical :: debug=.false.
562 real :: dPE_debug, mixing_debug, taux2, tauy2
563 real,
dimension(20) :: TKE_left_itt, PE_chg_itt, Kddt_h_itt, dPEa_dKd_itt, MKE_src_itt
564 real,
dimension(SZI_(G),SZK_(GV)) :: &
565 mech_TKE_k, conv_PErel_k
566 real,
dimension(SZK_(GV)) :: nstar_k
567 integer,
dimension(SZK_(GV)) :: num_itts
569 integer :: i, j, k, is, ie, js, je, nz, itt, max_itt
571 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = gv%ke
573 if (.not.
associated(cs))
call mom_error(fatal,
"energetic_PBL: "//&
574 "Module must be initialized before it is used.")
576 if (.not.
ASSOCIATED(tv%eqn_of_state))
call mom_error(fatal, &
577 "energetic_PBL: Temperature, salinity and an equation of state "//&
579 if (.NOT.
ASSOCIATED(fluxes%ustar))
call mom_error(fatal, &
580 "energetic_PBL: No surface TKE fluxes (ustar) defined in mixedlayer!")
581 if (
present(dt_expected) .or.
present(ds_expected)) debug = .true.
583 h_neglect = gv%H_subroundoff
585 if(.not.cs%Use_MLD_Iteration) max_obl_it=1
587 dt__diag = dt ;
if (
present(dt_diag)) dt__diag = dt_diag
588 idtdr0 = 1.0 / (dt__diag * gv%Rho0)
589 write_diags = .true. ;
if (
present(last_call)) write_diags = last_call
595 i_dtrho = 0.0 ;
if (dt*gv%Rho0 > 0.0) i_dtrho = 1.0 / (dt*gv%Rho0)
599 if (
present(dt_diag) .and. write_diags .and. (dt__diag > dt)) &
600 reset_diags = .false.
602 if (reset_diags)
then 604 if (cs%TKE_diagnostics)
then 606 do j=js,je ;
do i=is,ie
607 cs%diag_TKE_wind(i,j) = 0.0 ; cs%diag_TKE_MKE(i,j) = 0.0
608 cs%diag_TKE_conv(i,j) = 0.0 ; cs%diag_TKE_forcing(i,j) = 0.0
609 cs%diag_TKE_mixing(i,j) = 0.0 ; cs%diag_TKE_mech_decay(i,j) = 0.0
610 cs%diag_TKE_conv_decay(i,j) = 0.0
613 if (cs%Mixing_Diagnostics)
then 614 cs%Mixing_Length(:,:,:) = 0.0
615 cs%Velocity_Scale(:,:,:) = 0.0
652 do k=1,nz ;
do i=is,ie
653 h(i,k) = h_3d(i,j,k) + h_neglect ; u(i,k) = u_3d(i,j,k) ; v(i,k) = v_3d(i,j,k)
654 t(i,k) = tv%T(i,j,k) ; s(i,k) = tv%S(i,j,k)
658 cs%ML_depth(i,j) = h(i,1)*gv%H_to_m
660 sfc_connected(i) = .true.
664 mech_tke_k(:,:) = 0.0 ; conv_perel_k(:,:) = 0.0
673 do i=is,ie ;
if (g%mask2dT(i,j) > 0.5)
then 676 u_star = fluxes%ustar(i,j)
678 if ((g%mask2dCu(i-1,j) + g%mask2dCu(i,j)) > 0) &
679 taux2 = (g%mask2dCu(i-1,j)*fluxes%taux(i-1,j)**2 + &
680 g%mask2dCu(i,j)*fluxes%taux(i,j)**2) / (g%mask2dCu(i-1,j) + g%mask2dCu(i,j))
682 if ((g%mask2dCv(i,j-1) + g%mask2dCv(i,j)) > 0) &
683 tauy2 = (g%mask2dCv(i,j-1)*fluxes%tauy(i,j-1)**2 + &
684 g%mask2dCv(i,j)*fluxes%tauy(i,j)**2) / (g%mask2dCv(i,j-1) + g%mask2dCv(i,j))
685 u_star_mean = sqrt(sqrt(taux2 + tauy2)/gv%rho0)
686 if (
associated(fluxes%ustar_shelf) .and.
associated(fluxes%frac_shelf_h))
then 687 if (fluxes%frac_shelf_h(i,j) > 0.0) &
688 u_star = (1.0 - fluxes%frac_shelf_h(i,j)) * u_star + &
689 fluxes%frac_shelf_h(i,j) * fluxes%ustar_shelf(i,j)
691 if (u_star < cs%ustar_min) u_star = cs%ustar_min
693 bf_stable = max(0.0,buoy_flux(i,j))
694 bf_unstable = min(0.0,buoy_flux(i,j))
695 if (cs%omega_frac >= 1.0)
then ; absf(i) = 2.0*cs%omega
697 absf(i) = 0.25*((abs(g%CoriolisBu(i,j)) + abs(g%CoriolisBu(i-1,j-1))) + &
698 (abs(g%CoriolisBu(i,j-1)) + abs(g%CoriolisBu(i-1,j))))
699 if (cs%omega_frac > 0.0) &
700 absf(i) = sqrt(cs%omega_frac*4.0*cs%omega**2 + (1.0-cs%omega_frac)*absf(i)**2)
704 stab_scale = u_star**2 / ( vonkar * ( c_mo * bf_stable/u_star - c_ek * u_star * absf(i)))
706 il_ekman = absf(i)/u_star
707 il_obukhov = buoy_flux(i,j)*vonkar/u_star**3
709 if (cs%Mstar_Mode.eq.cs%CONST_MSTAR)
then 710 mech_tke(i) = (dt*cs%mstar*gv%Rho0)*((u_star**3))
713 if (cs%TKE_diagnostics)
then 714 cs%diag_TKE_wind(i,j) = cs%diag_TKE_wind(i,j) + mech_tke(i) * idtdr0
715 if (tke_forced(i,j,1) <= 0.0)
then 716 cs%diag_TKE_forcing(i,j) = cs%diag_TKE_forcing(i,j) + &
717 max(-mech_tke(i), tke_forced(i,j,1)) * idtdr0
721 cs%diag_TKE_forcing(i,j) = cs%diag_TKE_forcing(i,j) + cs%nstar*tke_forced(i,j,1) * idtdr0
725 if (tke_forced(i,j,1) <= 0.0)
then 726 mech_tke(i) = mech_tke(i) + tke_forced(i,j,1)
727 if (mech_tke(i) < 0.0) mech_tke(i) = 0.0
729 conv_perel(i) = conv_perel(i) + tke_forced(i,j,1)
738 h_sum(i) = h_neglect ;
do k=1,nz ; h_sum(i) = h_sum(i) + h(i,k) ;
enddo 739 i_hs = 0.0 ;
if (h_sum(i) > 0.0) i_hs = 1.0 / h_sum(i)
741 h_bot = 0.0 ; hb_hs(i,nz+1) = 0.0
743 h_bot = h_bot + h(i,k)
744 hb_hs(i,k) = h_bot * i_hs
749 dmass = gv%H_to_kg_m2 * h(i,k)
750 dpres = gv%g_Earth * dmass
751 dt_to_dpe(i,k) = (dmass * (pres(i,k) + 0.5*dpres)) * dsv_dt(i,j,k)
752 ds_to_dpe(i,k) = (dmass * (pres(i,k) + 0.5*dpres)) * dsv_ds(i,j,k)
753 dt_to_dcolht(i,k) = dmass * dsv_dt(i,j,k)
754 ds_to_dcolht(i,k) = dmass * dsv_ds(i,j,k)
756 pres(i,k+1) = pres(i,k) + dpres
763 do k=1,nz ; t0(k) = t(i,k) ; s0(k) = s(i,k) ;
enddo 767 mech_tke_top(i) = mech_tke(i) ; conv_perel_top(i) = conv_perel(i)
772 max_mld = 0.0 ;
do k=1,nz ; max_mld = max_mld + h(i,k)*gv%H_to_m ;
enddo 779 if (cs%MLD_iteration_guess .and. cs%ML_Depth2(i,j) > 1.)
then 781 mld_guess=cs%ML_Depth2(i,j)
784 mld_guess = 0.5 * (min_mld+max_mld)
788 obl_converged = .false.
792 do obl_it=1,max_obl_it ;
if (.not. obl_converged)
then 795 cs%ML_depth(i,j) = h(i,1)*gv%H_to_m
798 sfc_connected(i) = .true.
800 if (cs%Mstar_Mode.gt.0)
then 803 if (cs%MSTAR_MODE.eq.cs%MLD_o_OBUKHOV)
then 804 mld_over_stab = mld_guess / stab_scale - cs%MSTAR_XINT
805 if ((mld_over_stab) .le. 0.0)
then 807 mstar_mix = (cs%MSTAR_B*(mld_over_stab)+cs%MSTAR_A)**(cs%MSTAR_N)
809 if (cs%MSTAR_CAP>=0.)
then 810 if (cs%MSTAR_FLATCAP .OR. (mld_over_stab .le.cs%MSTAR_XINT_UP))
then 813 mstar_mix = min(cs%MSTAR_CAP, &
814 cs%MSTAR_SLOPE*(mld_over_stab)+cs%MSTAR_AT_XINT)
817 mstar_mix = cs%MSTAR_CAP - &
818 (cs%MSTAR_B2*(mld_over_stab-cs%MSTAR_XINT_UP)&
819 +cs%MSTAR_A2)**(cs%MSTAR_N)
823 mstar_mix = cs%MSTAR_SLOPE*(mld_over_stab)+cs%MSTAR_AT_XINT
826 elseif (cs%MSTAR_MODE.eq.cs%EKMAN_o_OBUKHOV)
then 827 mstar_stab = cs%MSTAR_COEF*sqrt(bf_stable/u_star**2/(absf(i)+1.e-10))
828 mstar_rot = cs%C_EK*log(max(1.,u_star/(absf(i)+1.e-10)/mld_guess))
829 if ( cs%MSTAR_CAP.le.0.0)
then 830 mstar_mix = max(mstar_stab,&
851 mstar_conv_adj = 1. - cs%CNV_MST_FAC * (-bf_unstable+1.e-10) / &
852 ( (-bf_unstable+1.e-10)+ &
853 2. *mstar_mix *u_star**3 / mld_guess )
854 if (cs%Use_LA_windsea)
then 856 call get_la_windsea( u_star_mean, mld_guess*cs%LaDepthRatio, gv, la)
858 mld_o_ekman = abs(mld_guess*il_ekman)
859 mld_o_obukhov_stab = abs(max(0.,mld_guess*il_obukhov))
860 mld_o_obukhov_un = abs(min(0.,mld_guess*il_obukhov))
861 ekman_o_obukhov_stab = abs(max(0.,il_obukhov/(il_ekman+1.e-10)))
862 ekman_o_obukhov_un = abs(min(0.,il_obukhov/(il_ekman+1.e-10)))
866 lamod = la * (1.0 + max(-0.5,cs%LaC_MLDoEK * mld_o_ekman) + &
867 cs%LaC_EKoOB_stab * ekman_o_obukhov_stab + &
868 cs%LaC_EKoOB_un * ekman_o_obukhov_un + &
869 cs%LaC_MLDoOB_stab * mld_o_obukhov_stab + &
870 cs%LaC_MLDoOB_un * mld_o_obukhov_un )
871 if (cs%LT_Enhance_Form==1)
then 873 enhance_m = (1+(1.4*la)**(-2)+(5.4*la)**(-4))**(1.5)
874 elseif (cs%LT_Enhance_Form==2)
then 876 enhance_m = min(cs%Max_Enhance_M,(1.+cs%LT_ENHANCE_COEF*lamod**cs%LT_ENHANCE_EXP))
878 elseif (cs%LT_ENHANCE_Form == 3)
then 880 mstar_lt = cs%LT_ENHANCE_COEF * lamod**cs%LT_ENHANCE_EXP
885 mech_tke(i) = ( mstar_mix * mstar_conv_adj * enhance_m + mstar_lt) * (dt*gv%Rho0*u_star**3)
887 if (cs%TKE_diagnostics)
then 888 cs%diag_TKE_wind(i,j) = cs%diag_TKE_wind(i,j) + mech_tke(i) * idtdr0
889 if (tke_forced(i,j,1) <= 0.0)
then 890 cs%diag_TKE_forcing(i,j) = cs%diag_TKE_forcing(i,j) + &
891 max(-mech_tke(i), tke_forced(i,j,1)) * idtdr0
895 cs%diag_TKE_forcing(i,j) = cs%diag_TKE_forcing(i,j) + cs%nstar*tke_forced(i,j,1) * idtdr0
899 if (tke_forced(i,j,1) <= 0.0)
then 900 mech_tke(i) = mech_tke(i) + tke_forced(i,j,1)
901 if (mech_tke(i) < 0.0) mech_tke(i) = 0.0
903 conv_perel(i) = conv_perel(i) + tke_forced(i,j,1)
906 mech_tke(i) = mech_tke_top(i)*enhance_m ; conv_perel(i) = conv_perel_top(i)
909 if (cs%TKE_diagnostics)
then 910 dtke_conv = 0.0 ; dtke_forcing = 0.0 ; dtke_mixing = 0.0
911 dtke_mke = 0.0 ; dtke_mech_decay = 0.0 ; dtke_conv_decay = 0.0
917 vstar_used(k) = 0.0 ; mixing_length_used(k) = 0.0
919 if (.not.cs%Use_MLD_Iteration) obl_converged = .true.
921 if ((.not.cs%Use_MLD_Iteration) .or. &
922 (cs%transLay_scale >= 1.0) .or. (cs%transLay_scale < 0.0) )
then 923 do k=1,nz+1 ; mixlen_shape(k) = 1.0 ;
enddo 924 elseif (mld_guess <= 0.0)
then 925 if (cs%transLay_scale > 0.0)
then 926 do k=1,nz+1 ; mixlen_shape(k) = cs%transLay_scale ;
enddo 928 do k=1,nz+1 ; mixlen_shape(k) = 1.0 ;
enddo 933 i_mld = 1.0 / mld_guess ; h_rsum = 0.0
934 mixlen_shape(1) = 1.0
936 h_rsum = h_rsum + h(i,k-1)
937 if (cs%MixLenExponent==2.0)
then 938 mixlen_shape(k) = cs%transLay_scale + (1.0 - cs%transLay_scale) * &
939 (max(0.0, (mld_guess - h_rsum)*i_mld) )**2
941 mixlen_shape(k) = cs%transLay_scale + (1.0 - cs%transLay_scale) * &
942 (max(0.0, (mld_guess - h_rsum)*i_mld) )**cs%MixLenExponent
948 kd(i,1) = 0.0 ; kddt_h(1) = 0.0
950 dt_to_dpe_a(i,1) = dt_to_dpe(i,1) ; dt_to_dcolht_a(i,1) = dt_to_dcolht(i,1)
951 ds_to_dpe_a(i,1) = ds_to_dpe(i,1) ; ds_to_dcolht_a(i,1) = ds_to_dcolht(i,1)
953 htot(i) = h(i,1) ; uhtot(i) = u(i,1)*h(i,1) ; vhtot(i) = v(i,1)*h(i,1)
956 mech_tke_k(i,1) = mech_tke(i) ; conv_perel_k(i,1) = conv_perel(i)
957 nstar_k(:) = 0.0 ; nstar_k(1) = cs%nstar ; num_itts(:) = -1
968 idecay_len_tke(i) = (cs%TKE_decay * absf(i) / u_star) * gv%H_to_m
970 if (idecay_len_tke(i) > 0.0) exp_kh = exp(-h(i,k-1)*idecay_len_tke(i))
971 if (cs%TKE_diagnostics) &
972 dtke_mech_decay = dtke_mech_decay + (exp_kh-1.0) * mech_tke(i) * idtdr0
973 mech_tke(i) = mech_tke(i) * exp_kh
977 if (tke_forced(i,j,k) > 0.0)
then 978 conv_perel(i) = conv_perel(i) + tke_forced(i,j,k)
979 if (cs%TKE_diagnostics) &
980 dtke_forcing = dtke_forcing + cs%nstar*tke_forced(i,j,k) * idtdr0
984 mech_tke_k(i,k) = mech_tke(i) ; conv_perel_k(i,k) = conv_perel(i)
989 if (cs%nstar * conv_perel(i) > 0.0)
then 993 nstar_fc = cs%nstar * conv_perel(i) / (conv_perel(i) + 0.2 * &
994 sqrt(0.5 * dt * gv%Rho0 * (absf(i)*(htot(i)*gv%H_to_m))**3 * conv_perel(i)))
996 if (debug) nstar_k(k) = nstar_fc
998 tot_tke = mech_tke(i) + nstar_fc * conv_perel(i)
1002 if (tke_forced(i,j,k) < 0.0)
then 1003 if (tke_forced(i,j,k) + tot_tke < 0.0)
then 1005 if (cs%TKE_diagnostics)
then 1006 dtke_mixing = dtke_mixing + tot_tke * idtdr0
1007 dtke_forcing = dtke_forcing - tot_tke * idtdr0
1010 dtke_conv_decay = dtke_conv_decay + &
1011 (cs%nstar-nstar_fc) * conv_perel(i) * idtdr0
1013 tot_tke = 0.0 ; mech_tke(i) = 0.0 ; conv_perel(i) = 0.0
1016 tke_reduc = (tot_tke + tke_forced(i,j,k)) / tot_tke
1017 if (cs%TKE_diagnostics)
then 1018 dtke_mixing = dtke_mixing - tke_forced(i,j,k) * idtdr0
1019 dtke_forcing = dtke_forcing + tke_forced(i,j,k) * idtdr0
1020 dtke_conv_decay = dtke_conv_decay + &
1021 (1.0-tke_reduc)*(cs%nstar-nstar_fc) * conv_perel(i) * idtdr0
1023 tot_tke = tke_reduc*tot_tke
1024 mech_tke(i) = tke_reduc*mech_tke(i)
1025 conv_perel(i) = tke_reduc*conv_perel(i)
1030 if (cs%orig_PE_calc)
then 1032 dte_t2 = 0.0 ; dse_t2 = 0.0
1034 dte_t2 = kddt_h(k-1) * ((t0(k-2) - t0(k-1)) + dte(k-2))
1035 dse_t2 = kddt_h(k-1) * ((s0(k-2) - s0(k-1)) + dse(k-2))
1038 dt_h = (gv%m_to_H**2*dt) / max(0.5*(h(i,k-1)+h(i,k)), 1e-15*h_sum(i))
1046 convectively_stable = ( 0.0 <= &
1047 ( (dt_to_dcolht(i,k) + dt_to_dcolht(i,k-1) ) * (t0(k-1)-t0(k)) + &
1048 (ds_to_dcolht(i,k) + ds_to_dcolht(i,k-1) ) * (s0(k-1)-s0(k)) ) )
1050 if ((mech_tke(i) + conv_perel(i)) <= 0.0 .and. convectively_stable)
then 1052 tot_tke = 0.0 ; mech_tke(i) = 0.0 ; conv_perel(i) = 0.0
1053 kd(i,k) = 0.0 ; kddt_h(k) = 0.0
1054 sfc_disconnect = .true.
1064 if (cs%orig_PE_calc)
then 1065 dte(k-1) = b1 * ( dte_t2 )
1066 dse(k-1) = b1 * ( dse_t2 )
1070 dt_to_dpe_a(i,k) = dt_to_dpe(i,k)
1071 ds_to_dpe_a(i,k) = ds_to_dpe(i,k)
1072 dt_to_dcolht_a(i,k) = dt_to_dcolht(i,k)
1073 ds_to_dcolht_a(i,k) = ds_to_dcolht(i,k)
1076 sfc_disconnect = .false.
1080 if (cs%orig_PE_calc)
then 1082 dt_km1_t2 = (t0(k)-t0(k-1))
1083 ds_km1_t2 = (s0(k)-s0(k-1))
1085 dt_km1_t2 = (t0(k)-t0(k-1)) - &
1086 (kddt_h(k-1) / hp_a(i)) * ((t0(k-2) - t0(k-1)) + dte(k-2))
1087 ds_km1_t2 = (s0(k)-s0(k-1)) - &
1088 (kddt_h(k-1) / hp_a(i)) * ((s0(k-2) - s0(k-1)) + dse(k-2))
1090 dte_term = dte_t2 + hp_a(i) * (t0(k-1)-t0(k))
1091 dse_term = dse_t2 + hp_a(i) * (s0(k-1)-s0(k))
1094 th_a(k-1) = h(i,k-1) * t0(k-1) ; sh_a(k-1) = h(i,k-1) * s0(k-1)
1096 th_a(k-1) = h(i,k-1) * t0(k-1) + kddt_h(k-1) * te(k-2)
1097 sh_a(k-1) = h(i,k-1) * s0(k-1) + kddt_h(k-1) * se(k-2)
1099 th_b(k) = h(i,k) * t0(k) ; sh_b(k) = h(i,k) * s0(k)
1107 if ((cs%MKE_to_TKE_effic > 0.0) .and. (htot(i)*h(i,k) > 0.0))
then 1110 dmke_max = (gv%H_to_kg_m2 * cs%MKE_to_TKE_effic) * 0.5 * &
1111 (h(i,k) / ((htot(i) + h(i,k))*htot(i))) * &
1112 ((uhtot(i)-u(i,k)*htot(i))**2 + (vhtot(i)-v(i,k)*htot(i))**2)
1115 mke2_hharm = (htot(i) + h(i,k) + 2.0*h_neglect) / &
1116 ((htot(i)+h_neglect) * (h(i,k)+h_neglect))
1118 dmke_max = 0.0 ; mke2_hharm = 0.0
1124 h_tt = htot(i) + h_tt_min
1125 tke_here = mech_tke(i) + cs%wstar_ustar_coef*conv_perel(i)
1126 if (tke_here > 0.0)
then 1127 vstar = cs%vstar_scale_fac * (i_dtrho*tke_here)**c1_3
1128 hbs_here = gv%H_to_m * min(hb_hs(i,k), mixlen_shape(k))
1129 mixing_length_used(k) = max(cs%min_mix_len,((h_tt*hbs_here)*vstar) / &
1130 ((cs%Ekman_scale_coef * absf(i)) * (h_tt*hbs_here) + vstar))
1133 if (.not.cs%Use_MLD_Iteration)
then 1134 kd_guess0 = vstar * vonkar * ((h_tt*hbs_here)*vstar) / &
1135 ((cs%Ekman_scale_coef * absf(i)) * (h_tt*hbs_here) + vstar)
1137 kd_guess0 = vstar * vonkar * mixing_length_used(k)
1140 vstar = 0.0 ; kd_guess0 = 0.0
1142 vstar_used(k) = vstar
1143 kddt_h_g0 = kd_guess0*dt_h
1145 if (cs%orig_PE_calc)
then 1147 dt_km1_t2, ds_km1_t2, dt_to_dpe(i,k), ds_to_dpe(i,k), &
1148 dt_to_dpe_a(i,k-1), ds_to_dpe_a(i,k-1), &
1149 pres(i,k), dt_to_dcolht(i,k), ds_to_dcolht(i,k), &
1150 dt_to_dcolht_a(i,k-1), ds_to_dcolht_a(i,k-1), &
1151 pe_chg=pe_chg_g0, dpec_dkd=dpea_dkd_g0, dpe_max=pe_chg_max, &
1152 dpec_dkd_0=dpec_dkd_kd0 )
1154 call find_pe_chg(0.0, kddt_h_g0, hp_a(i), h(i,k), &
1155 th_a(k-1), sh_a(k-1), th_b(k), sh_b(k), &
1156 dt_to_dpe_a(i,k-1), ds_to_dpe_a(i,k-1), dt_to_dpe(i,k), ds_to_dpe(i,k), &
1157 pres(i,k), dt_to_dcolht_a(i,k-1), ds_to_dcolht_a(i,k-1), &
1158 dt_to_dcolht(i,k), ds_to_dcolht(i,k), &
1159 pe_chg=pe_chg_g0, dpec_dkd=dpea_dkd_g0, dpe_max=pe_chg_max, &
1160 dpec_dkd_0=dpec_dkd_kd0 )
1163 mke_src = dmke_max*(1.0 - exp(-kddt_h_g0 * mke2_hharm))
1165 if (pe_chg_g0 .gt. 0.0)
then 1167 n2_dissipation = 1.+cs%N2_DISSIPATION_SCALE_NEG
1170 n2_dissipation = 1.+cs%N2_DISSIPATION_SCALE_POS
1173 if ((pe_chg_g0 < 0.0) .or. ((vstar == 0.0) .and. (dpec_dkd_kd0 < 0.0)))
then 1175 if (pe_chg_max <= 0.0)
then 1177 tke_here = mech_tke(i) + cs%wstar_ustar_coef*(conv_perel(i)-pe_chg_max)
1178 if (tke_here > 0.0)
then 1179 vstar = cs%vstar_scale_fac * (i_dtrho*tke_here)**c1_3
1180 hbs_here = gv%H_to_m * min(hb_hs(i,k), mixlen_shape(k))
1181 mixing_length_used(k) = max(cs%min_mix_len,((h_tt*hbs_here)*vstar) / &
1182 ((cs%Ekman_scale_coef * absf(i)) * (h_tt*hbs_here) + vstar))
1183 if (.not.cs%Use_MLD_Iteration)
then 1186 kd(i,k) = vstar * vonkar * ((h_tt*hbs_here)*vstar) / &
1187 ((cs%Ekman_scale_coef * absf(i)) * (h_tt*hbs_here) + vstar)
1189 kd(i,k) = vstar * vonkar * mixing_length_used(k)
1192 vstar = 0.0 ; kd(i,k) = 0.0
1194 vstar_used(k) = vstar
1196 if (cs%orig_PE_calc)
then 1198 dt_km1_t2, ds_km1_t2, dt_to_dpe(i,k), ds_to_dpe(i,k), &
1199 dt_to_dpe_a(i,k-1), ds_to_dpe_a(i,k-1), &
1200 pres(i,k), dt_to_dcolht(i,k), ds_to_dcolht(i,k), &
1201 dt_to_dcolht_a(i,k-1), ds_to_dcolht_a(i,k-1), &
1204 call find_pe_chg(0.0, kd(i,k)*dt_h, hp_a(i), h(i,k), &
1205 th_a(k-1), sh_a(k-1), th_b(k), sh_b(k), &
1206 dt_to_dpe_a(i,k-1), ds_to_dpe_a(i,k-1), dt_to_dpe(i,k), ds_to_dpe(i,k), &
1207 pres(i,k), dt_to_dcolht_a(i,k-1), ds_to_dcolht_a(i,k-1), &
1208 dt_to_dcolht(i,k), ds_to_dcolht(i,k), &
1212 if (dpe_conv > 0.0)
then 1213 kd(i,k) = kd_guess0 ; dpe_conv = pe_chg_g0
1215 mke_src = dmke_max*(1.0 - exp(-(kd(i,k)*dt_h) * mke2_hharm))
1219 kd(i,k) = kd_guess0 ; dpe_conv = pe_chg_g0
1221 conv_perel(i) = conv_perel(i) - dpe_conv
1222 mech_tke(i) = mech_tke(i) + mke_src
1223 if (cs%TKE_diagnostics)
then 1224 dtke_conv = dtke_conv - cs%nstar*dpe_conv * idtdr0
1225 dtke_mke = dtke_mke + mke_src * idtdr0
1227 if (sfc_connected(i))
then 1228 cs%ML_depth(i,j) = cs%ML_depth(i,j) + gv%H_to_m * h(i,k)
1232 kddt_h(k) = kd(i,k)*dt_h
1233 elseif (tot_tke + (mke_src - n2_dissipation*pe_chg_g0) >= 0.0)
then 1236 kddt_h(k) = kddt_h_g0
1239 tot_tke = tot_tke + mke_src
1241 if (tot_tke > 0.0) tke_reduc = (tot_tke - n2_dissipation*pe_chg_g0) &
1243 if (cs%TKE_diagnostics)
then 1244 dtke_mixing = dtke_mixing - pe_chg_g0 * idtdr0
1245 dtke_mke = dtke_mke + mke_src * idtdr0
1246 dtke_conv_decay = dtke_conv_decay + &
1247 (1.0-tke_reduc)*(cs%nstar-nstar_fc) * conv_perel(i) * idtdr0
1249 tot_tke = tke_reduc*tot_tke
1250 mech_tke(i) = tke_reduc*(mech_tke(i) + mke_src)
1251 conv_perel(i) = tke_reduc*conv_perel(i)
1252 if (sfc_connected(i))
then 1253 cs%ML_depth(i,j) = cs%ML_depth(i,j) + gv%H_to_m * h(i,k)
1256 elseif (tot_tke == 0.0)
then 1258 kd(i,k) = 0.0 ; kddt_h(k) = 0.0
1259 tot_tke = 0.0 ; conv_perel(i) = 0.0 ; mech_tke(i) = 0.0
1260 sfc_disconnect = .true.
1264 kddt_h_max = kddt_h_g0 ; kddt_h_min = 0.0
1265 tke_left_max = tot_tke + (mke_src - n2_dissipation*pe_chg_g0) ;
1266 tke_left_min = tot_tke
1270 kddt_h_guess = tot_tke * kddt_h_max / max( n2_dissipation*pe_chg_g0 &
1271 - mke_src, kddt_h_max * (dpec_dkd_kd0 - dmke_max * &
1279 tke_left_itt(:) = 0.0 ; dpea_dkd_itt(:) = 0.0 ; pe_chg_itt(:) = 0.0
1280 mke_src_itt(:) = 0.0 ; kddt_h_itt(:) = 0.0
1283 if (cs%orig_PE_calc)
then 1285 dt_km1_t2, ds_km1_t2, dt_to_dpe(i,k), ds_to_dpe(i,k), &
1286 dt_to_dpe_a(i,k-1), ds_to_dpe_a(i,k-1), &
1287 pres(i,k), dt_to_dcolht(i,k), ds_to_dcolht(i,k), &
1288 dt_to_dcolht_a(i,k-1), ds_to_dcolht_a(i,k-1), &
1289 pe_chg=pe_chg, dpec_dkd=dpec_dkd )
1291 call find_pe_chg(0.0, kddt_h_guess, hp_a(i), h(i,k), &
1292 th_a(k-1), sh_a(k-1), th_b(k), sh_b(k), &
1293 dt_to_dpe_a(i,k-1), ds_to_dpe_a(i,k-1), dt_to_dpe(i,k), ds_to_dpe(i,k), &
1294 pres(i,k), dt_to_dcolht_a(i,k-1), ds_to_dcolht_a(i,k-1), &
1295 dt_to_dcolht(i,k), ds_to_dcolht(i,k), &
1298 mke_src = dmke_max * (1.0 - exp(-mke2_hharm * kddt_h_guess))
1299 dmke_src_dk = dmke_max * mke2_hharm * exp(-mke2_hharm * kddt_h_guess)
1301 tke_left = tot_tke + (mke_src - n2_dissipation*pe_chg)
1303 kddt_h_itt(itt) = kddt_h_guess ; mke_src_itt(itt) = mke_src
1304 pe_chg_itt(itt) = n2_dissipation*pe_chg
1305 tke_left_itt(itt) = tke_left
1306 dpea_dkd_itt(itt) = dpec_dkd
1310 if (tke_left >= 0.0)
then 1311 kddt_h_min = kddt_h_guess ; tke_left_min = tke_left
1313 kddt_h_max = kddt_h_guess ; tke_left_max = tke_left
1319 if (dpec_dkd*n2_dissipation - dmke_src_dk <= 0.0)
then 1322 dkddt_h_newt = tke_left / (dpec_dkd*n2_dissipation - dmke_src_dk)
1323 kddt_h_newt = kddt_h_guess + dkddt_h_newt
1324 if ((kddt_h_newt > kddt_h_max) .or. (kddt_h_newt < kddt_h_min)) &
1329 kddt_h_next = kddt_h_guess + dkddt_h_newt
1330 dkddt_h = dkddt_h_newt
1332 kddt_h_next = (tke_left_max * kddt_h_min - kddt_h_max * tke_left_min) / &
1333 (tke_left_max - tke_left_min)
1334 dkddt_h = kddt_h_next - kddt_h_guess
1337 if ((abs(dkddt_h) < 1e-9*kddt_h_guess) .or. (itt==max_itt))
then 1339 if (debug) num_itts(k) = itt
1342 kddt_h_guess = kddt_h_next
1345 kd(i,k) = kddt_h_guess / dt_h ; kddt_h(k) = kd(i,k)*dt_h
1348 if (cs%TKE_diagnostics)
then 1349 dtke_mixing = dtke_mixing - (tot_tke + mke_src) * idtdr0
1350 dtke_mke = dtke_mke + mke_src * idtdr0
1351 dtke_conv_decay = dtke_conv_decay + &
1352 (cs%nstar-nstar_fc) * conv_perel(i) * idtdr0
1355 if (sfc_connected(i)) cs%ML_depth(i,j) = cs%ML_depth(i,j) + &
1356 (pe_chg / pe_chg_g0) * gv%H_to_m * h(i,k)
1357 tot_tke = 0.0 ; mech_tke(i) = 0.0 ; conv_perel(i) = 0.0
1358 sfc_disconnect = .true.
1361 kddt_h(k) = kd(i,k)*dt_h
1364 b1 = 1.0 / (hp_a(i) + kddt_h(k))
1365 c1(k) = kddt_h(k) * b1
1366 if (cs%orig_PE_calc)
then 1367 dte(k-1) = b1 * ( kddt_h(k)*(t0(k)-t0(k-1)) + dte_t2 )
1368 dse(k-1) = b1 * ( kddt_h(k)*(s0(k)-s0(k-1)) + dse_t2 )
1371 hp_a(i) = h(i,k) + (hp_a(i) * b1) * kddt_h(k)
1372 dt_to_dpe_a(i,k) = dt_to_dpe(i,k) + c1(k)*dt_to_dpe_a(i,k-1)
1373 ds_to_dpe_a(i,k) = ds_to_dpe(i,k) + c1(k)*ds_to_dpe_a(i,k-1)
1374 dt_to_dcolht_a(i,k) = dt_to_dcolht(i,k) + c1(k)*dt_to_dcolht_a(i,k-1)
1375 ds_to_dcolht_a(i,k) = ds_to_dcolht(i,k) + c1(k)*ds_to_dcolht_a(i,k-1)
1380 if (sfc_disconnect)
then 1382 uhtot(i) = u(i,k)*h(i,k)
1383 vhtot(i) = v(i,k)*h(i,k)
1385 sfc_connected(i) = .false.
1387 uhtot(i) = uhtot(i) + u(i,k)*h(i,k)
1388 vhtot(i) = vhtot(i) + v(i,k)*h(i,k)
1389 htot(i) = htot(i) + h(i,k)
1394 te(1) = b1*(h(i,1)*t0(1))
1395 se(1) = b1*(h(i,1)*s0(1))
1397 te(k-1) = b1 * (h(i,k-1) * t0(k-1) + kddt_h(k-1) * te(k-2))
1398 se(k-1) = b1 * (h(i,k-1) * s0(k-1) + kddt_h(k-1) * se(k-2))
1407 te(nz) = b1 * (h(i,nz) * t0(nz) + kddt_h(nz) * te(nz-1))
1408 se(nz) = b1 * (h(i,nz) * s0(nz) + kddt_h(nz) * se(nz-1))
1410 te(k) = te(k) + c1(k+1)*te(k+1)
1411 se(k) = se(k) + c1(k+1)*se(k+1)
1414 if (
present(dt_expected))
then 1415 do k=1,nz ; dt_expected(i,j,k) = te(k) - t0(k) ;
enddo 1417 if (
present(ds_expected))
then 1418 do k=1,nz ; ds_expected(i,j,k) = se(k) - s0(k) ;
enddo 1423 dpe_debug = dpe_debug + (dt_to_dpe(i,k) * (te(k) - t0(k)) + &
1424 ds_to_dpe(i,k) * (se(k) - s0(k)))
1426 mixing_debug = dpe_debug * idtdr0
1436 itmax(obl_it) = max_mld
1437 itmin(obl_it) = min_mld
1438 itguess(obl_it) = mld_guess
1440 mld_found=0.0 ; first_obl=.true.
1441 if (cs%Orig_MLD_iteration)
then 1445 if (vstar_used(k) > 1.e-10 .and. k < nz)
then 1446 mld_found = mld_found+h(i,k-1)*gv%H_to_m
1449 if (mld_found-cs%MLD_tol > mld_guess)
then 1451 elseif ((mld_guess-mld_found) < max(cs%MLD_tol,h(i,k-1)*gv%H_to_m))
then 1452 obl_converged = .true.
1453 if (obl_it_stats)
then 1454 maxit = max(maxit,obl_it)
1455 minit = min(minit,obl_it)
1456 sumit = sumit+obl_it
1458 print*,maxit,minit,sumit/numit
1460 cs%ML_Depth2(i,j) = mld_guess
1469 mld_found=cs%ML_DEPTH(i,j)
1470 if (mld_found-cs%MLD_tol > mld_guess)
then 1472 elseif (abs(mld_guess-mld_found) < (cs%MLD_tol))
then 1473 obl_converged = .true.
1474 if (obl_it_stats)
then 1475 maxit = max(maxit,obl_it)
1476 minit = min(minit,obl_it)
1477 sumit = sumit+obl_it
1479 print*,maxit,minit,sumit/numit
1481 cs%ML_Depth2(i,j) = mld_guess
1487 mld_guess = min_mld*0.5 + max_mld*0.5
1488 itresult(obl_it) = mld_found
1490 if (.not.obl_converged)
then 1494 notconverged=notconverged+1
1508 converged=converged+1
1511 if (cs%TKE_diagnostics)
then 1512 cs%diag_TKE_MKE(i,j) = cs%diag_TKE_MKE(i,j) + dtke_mke
1513 cs%diag_TKE_conv(i,j) = cs%diag_TKE_conv(i,j) + dtke_conv
1514 cs%diag_TKE_forcing(i,j) = cs%diag_TKE_forcing(i,j) + dtke_forcing
1515 cs%diag_TKE_mixing(i,j) = cs%diag_TKE_mixing(i,j) + dtke_mixing
1516 cs%diag_TKE_mech_decay(i,j) = cs%diag_TKE_mech_decay(i,j) + dtke_mech_decay
1517 cs%diag_TKE_conv_decay(i,j) = cs%diag_TKE_conv_decay(i,j) + dtke_conv_decay
1520 if (cs%Mixing_Diagnostics)
then 1524 cs%Mixing_Length(i,j,k) = mixing_length_used(k)
1525 cs%Velocity_Scale(i,j,k) = vstar_used(k)
1528 if (
allocated(cs%Enhance_M)) cs%Enhance_M(i,j) = enhance_m
1529 if (
allocated(cs%mstar_mix)) cs%mstar_mix(i,j) = mstar_mix
1530 if (
allocated(cs%MLD_Obukhov)) cs%MLD_Obukhov(i,j) = (mld_guess*il_obukhov)
1531 if (
allocated(cs%MLD_Ekman)) cs%MLD_Ekman(i,j) = (mld_guess*il_ekman)
1532 if (
allocated(cs%Ekman_Obukhov)) cs%Ekman_Obukhov(i,j) = (il_obukhov/(il_ekman+1.e-10))
1533 if (
allocated(cs%La)) cs%La(i,j) = la
1534 if (
allocated(cs%La_mod)) cs%La_mod(i,j) = lamod
1540 if (
present(dt_expected))
then 1541 do k=1,nz ; dt_expected(i,j,k) = 0.0 ;
enddo 1543 if (
present(ds_expected))
then 1544 do k=1,nz ; ds_expected(i,j,k) = 0.0 ;
enddo 1548 if (cs%id_Hsfc_used > 0)
then 1549 do i=is,ie ; hsfc_used(i,j) = h(i,1)*gv%H_to_m ;
enddo 1550 do k=2,nz ;
do i=is,ie
1551 if (kd(i,k) > 0.0) hsfc_used(i,j) = hsfc_used(i,j) + h(i,k)*gv%H_to_m
1555 do k=1,nz+1 ;
do i=is,ie
1556 kd_int(i,j,k) = kd(i,k)
1561 if (write_diags)
then 1562 if (cs%id_ML_depth > 0) &
1563 call post_data(cs%id_ML_depth, cs%ML_depth, cs%diag)
1564 if (cs%id_TKE_wind > 0) &
1565 call post_data(cs%id_TKE_wind, cs%diag_TKE_wind, cs%diag)
1566 if (cs%id_TKE_MKE > 0) &
1567 call post_data(cs%id_TKE_MKE, cs%diag_TKE_MKE, cs%diag)
1568 if (cs%id_TKE_conv > 0) &
1569 call post_data(cs%id_TKE_conv, cs%diag_TKE_conv, cs%diag)
1570 if (cs%id_TKE_forcing > 0) &
1571 call post_data(cs%id_TKE_forcing, cs%diag_TKE_forcing, cs%diag)
1572 if (cs%id_TKE_mixing > 0) &
1573 call post_data(cs%id_TKE_mixing, cs%diag_TKE_mixing, cs%diag)
1574 if (cs%id_TKE_mech_decay > 0) &
1575 call post_data(cs%id_TKE_mech_decay, cs%diag_TKE_mech_decay, cs%diag)
1576 if (cs%id_TKE_conv_decay > 0) &
1577 call post_data(cs%id_TKE_conv_decay, cs%diag_TKE_conv_decay, cs%diag)
1578 if (cs%id_Hsfc_used > 0) &
1579 call post_data(cs%id_Hsfc_used, hsfc_used, cs%diag)
1580 if (cs%id_Mixing_Length > 0) &
1581 call post_data(cs%id_Mixing_Length, cs%Mixing_Length, cs%diag)
1582 if (cs%id_Velocity_Scale >0) &
1583 call post_data(cs%id_Velocity_Scale, cs%Velocity_Scale, cs%diag)
1584 if (cs%id_OSBL >0) &
1585 call post_data(cs%id_OSBL, cs%ML_Depth2, cs%diag)
1586 if (cs%id_LT_Enhancement >0) &
1587 call post_data(cs%id_LT_Enhancement, cs%Enhance_M, cs%diag)
1588 if (cs%id_MSTAR_MIX >0) &
1589 call post_data(cs%id_MSTAR_MIX, cs%MSTAR_MIX, cs%diag)
1590 if (cs%id_MLD_OBUKHOV >0) &
1591 call post_data(cs%id_MLD_Obukhov, cs%MLD_OBUKHOV, cs%diag)
1592 if (cs%id_MLD_EKMAN >0) &
1593 call post_data(cs%id_MLD_Ekman, cs%MLD_EKMAN, cs%diag)
1594 if (cs%id_Ekman_Obukhov >0) &
1595 call post_data(cs%id_Ekman_Obukhov, cs%Ekman_Obukhov, cs%diag)
1597 call post_data(cs%id_LA, cs%LA, cs%diag)
1598 if (cs%id_LA_MOD >0) &
1599 call post_data(cs%id_LA_MOD, cs%LA_MOD, cs%diag)
1607 subroutine find_pe_chg(Kddt_h0, dKddt_h, hp_a, hp_b, Th_a, Sh_a, Th_b, Sh_b, &
1608 dT_to_dPE_a, dS_to_dPE_a, dT_to_dPE_b, dS_to_dPE_b, &
1609 pres, dT_to_dColHt_a, dS_to_dColHt_a, dT_to_dColHt_b, dS_to_dColHt_b, &
1610 PE_chg, dPEc_dKd, dPE_max, dPEc_dKd_0, ColHt_cor)
1611 real,
intent(in) :: Kddt_h0
1614 real,
intent(in) :: dKddt_h
1617 real,
intent(in) :: hp_a
1621 real,
intent(in) :: hp_b
1625 real,
intent(in) :: Th_a
1628 real,
intent(in) :: Sh_a
1631 real,
intent(in) :: Th_b
1634 real,
intent(in) :: Sh_b
1637 real,
intent(in) :: dT_to_dPE_a
1641 real,
intent(in) :: dS_to_dPE_a
1645 real,
intent(in) :: dT_to_dPE_b
1649 real,
intent(in) :: dS_to_dPE_b
1653 real,
intent(in) :: pres
1656 real,
intent(in) :: dT_to_dColHt_a
1660 real,
intent(in) :: dS_to_dColHt_a
1664 real,
intent(in) :: dT_to_dColHt_b
1668 real,
intent(in) :: dS_to_dColHt_b
1673 real,
optional,
intent(out) :: PE_chg
1675 real,
optional,
intent(out) :: dPEc_dKd
1677 real,
optional,
intent(out) :: dPE_max
1680 real,
optional,
intent(out) :: dPEc_dKd_0
1682 real,
optional,
intent(out) :: ColHt_cor
1705 bdt1 = hp_a * hp_b + kddt_h0 * hps
1706 dt_c = hp_a * th_b - hp_b * th_a
1707 ds_c = hp_a * sh_b - hp_b * sh_a
1708 pec_core = hp_b * (dt_to_dpe_a * dt_c + ds_to_dpe_a * ds_c) - &
1709 hp_a * (dt_to_dpe_b * dt_c + ds_to_dpe_b * ds_c)
1710 colht_core = hp_b * (dt_to_dcolht_a * dt_c + ds_to_dcolht_a * ds_c) - &
1711 hp_a * (dt_to_dcolht_b * dt_c + ds_to_dcolht_b * ds_c)
1713 if (
present(pe_chg))
then 1716 y1 = dkddt_h / (bdt1 * (bdt1 + dkddt_h * hps))
1717 pe_chg = pec_core * y1
1718 colht_chg = colht_core * y1
1719 if (colht_chg < 0.0) pe_chg = pe_chg - pres * colht_chg
1720 if (
present(colht_cor)) colht_cor = -pres * min(colht_chg, 0.0)
1721 else if (
present(colht_cor))
then 1722 y1 = dkddt_h / (bdt1 * (bdt1 + dkddt_h * hps))
1723 colht_cor = -pres * min(colht_core * y1, 0.0)
1726 if (
present(dpec_dkd))
then 1728 y1 = 1.0 / (bdt1 + dkddt_h * hps)**2
1729 dpec_dkd = pec_core * y1
1730 colht_chg = colht_core * y1
1731 if (colht_chg < 0.0) dpec_dkd = dpec_dkd - pres * colht_chg
1734 if (
present(dpe_max))
then 1736 y1 = 1.0 / (bdt1 * hps)
1737 dpe_max = pec_core * y1
1738 colht_chg = colht_core * y1
1739 if (colht_chg < 0.0) dpe_max = dpe_max - pres * colht_chg
1742 if (
present(dpec_dkd_0))
then 1745 dpec_dkd_0 = pec_core * y1
1746 colht_chg = colht_core * y1
1747 if (colht_chg < 0.0) dpec_dkd_0 = dpec_dkd_0 - pres * colht_chg
1756 dT_km1_t2, dS_km1_t2, dT_to_dPE_k, dS_to_dPE_k, &
1757 dT_to_dPEa, dS_to_dPEa, pres, dT_to_dColHt_k, &
1758 dS_to_dColHt_k, dT_to_dColHta, dS_to_dColHta, &
1759 PE_chg, dPEc_dKd, dPE_max, dPEc_dKd_0)
1760 real,
intent(in) :: Kddt_h
1763 real,
intent(in) :: h_k
1764 real,
intent(in) :: b_den_1
1768 real,
intent(in) :: dTe_term
1770 real,
intent(in) :: dSe_term
1772 real,
intent(in) :: dT_km1_t2
1774 real,
intent(in) :: dS_km1_t2
1776 real,
intent(in) :: pres
1779 real,
intent(in) :: dT_to_dPE_k
1783 real,
intent(in) :: dS_to_dPE_k
1787 real,
intent(in) :: dT_to_dPEa
1791 real,
intent(in) :: dS_to_dPEa
1795 real,
intent(in) :: dT_to_dColHt_k
1799 real,
intent(in) :: dS_to_dColHt_k
1803 real,
intent(in) :: dT_to_dColHta
1807 real,
intent(in) :: dS_to_dColHta
1812 real,
optional,
intent(out) :: PE_chg
1814 real,
optional,
intent(out) :: dPEc_dKd
1816 real,
optional,
intent(out) :: dPE_max
1819 real,
optional,
intent(out) :: dPEc_dKd_0
1836 real :: dT_k, dT_km1
1837 real :: dS_k, dS_km1
1838 real :: I_Kr_denom, dKr_dKd
1839 real :: ddT_k_dKd, ddT_km1_dKd
1840 real :: ddS_k_dKd, ddS_km1_dKd
1842 b1 = 1.0 / (b_den_1 + kddt_h)
1850 i_kr_denom = 1.0 / (h_k*b_den_1 + (b_den_1 + h_k)*kddt_h)
1852 dt_k = (kddt_h*i_kr_denom) * dte_term
1853 ds_k = (kddt_h*i_kr_denom) * dse_term
1855 if (
present(pe_chg))
then 1858 dt_km1 = b1kd * ( dt_k + dt_km1_t2 )
1859 ds_km1 = b1kd * ( ds_k + ds_km1_t2 )
1860 pe_chg = (dt_to_dpe_k * dt_k + dt_to_dpea * dt_km1) + &
1861 (ds_to_dpe_k * ds_k + ds_to_dpea * ds_km1)
1862 colht_chg = (dt_to_dcolht_k * dt_k + dt_to_dcolhta * dt_km1) + &
1863 (ds_to_dcolht_k * ds_k + ds_to_dcolhta * ds_km1)
1864 if (colht_chg < 0.0) pe_chg = pe_chg - pres * colht_chg
1867 if (
present(dpec_dkd))
then 1869 dkr_dkd = (h_k*b_den_1) * i_kr_denom**2
1871 ddt_k_dkd = dkr_dkd * dte_term
1872 dds_k_dkd = dkr_dkd * dse_term
1873 ddt_km1_dkd = (b1**2 * b_den_1) * ( dt_k + dt_km1_t2 ) + b1kd * ddt_k_dkd
1874 dds_km1_dkd = (b1**2 * b_den_1) * ( ds_k + ds_km1_t2 ) + b1kd * dds_k_dkd
1877 dpec_dkd = (dt_to_dpe_k * ddt_k_dkd + dt_to_dpea * ddt_km1_dkd) + &
1878 (ds_to_dpe_k * dds_k_dkd + ds_to_dpea * dds_km1_dkd)
1879 dcolht_dkd = (dt_to_dcolht_k * ddt_k_dkd + dt_to_dcolhta * ddt_km1_dkd) + &
1880 (ds_to_dcolht_k * dds_k_dkd + ds_to_dcolhta * dds_km1_dkd)
1881 if (dcolht_dkd < 0.0) dpec_dkd = dpec_dkd - pres * dcolht_dkd
1884 if (
present(dpe_max))
then 1886 dpe_max = (dt_to_dpea * dt_km1_t2 + ds_to_dpea * ds_km1_t2) + &
1887 ((dt_to_dpe_k + dt_to_dpea) * dte_term + &
1888 (ds_to_dpe_k + ds_to_dpea) * dse_term) / (b_den_1 + h_k)
1889 dcolht_max = (dt_to_dcolhta * dt_km1_t2 + ds_to_dcolhta * ds_km1_t2) + &
1890 ((dt_to_dcolht_k + dt_to_dcolhta) * dte_term + &
1891 (ds_to_dcolht_k + ds_to_dcolhta) * dse_term) / (b_den_1 + h_k)
1892 if (dcolht_max < 0.0) dpe_max = dpe_max - pres*dcolht_max
1895 if (
present(dpec_dkd_0))
then 1897 dpec_dkd_0 = (dt_to_dpea * dt_km1_t2 + ds_to_dpea * ds_km1_t2) / (b_den_1) + &
1898 (dt_to_dpe_k * dte_term + ds_to_dpe_k * dse_term) / (h_k*b_den_1)
1899 dcolht_dkd = (dt_to_dcolhta * dt_km1_t2 + ds_to_dcolhta * ds_km1_t2) / (b_den_1) + &
1900 (dt_to_dcolht_k * dte_term + ds_to_dcolht_k * dse_term) / (h_k*b_den_1)
1901 if (dcolht_dkd < 0.0) dpec_dkd_0 = dpec_dkd_0 - pres*dcolht_dkd
1909 type(ocean_grid_type),
intent(in) :: G
1910 real,
dimension(SZI_(G),SZJ_(G)),
intent(out) :: MLD
1913 do j = g%jsc, g%jec ;
do i = g%isc, g%iec
1914 mld(i,j) = cs%ML_depth(i,j)
1920 real,
intent(in) :: USTair
1921 type(verticalgrid_type),
intent(in) :: GV
1922 real,
intent(out) :: U10
1923 real,
parameter :: vonkar = 0.4
1924 real,
parameter :: nu=1e-6
1925 real :: z0sm, z0, z0rough, u10a, alpha, CD
1934 z0sm = 0.11 * nu / ustair;
1935 u10 = ustair/sqrt(0.001);
1939 do while (abs(u10a/u10-1.)>0.001)
1942 alpha = min(0.028,0.0017 * u10 - 0.005)
1943 z0rough = alpha * ustair**2/gv%g_Earth
1945 cd = ( vonkar / log(10/z0) )**2
1946 u10 = ustair/sqrt(cd);
1953 u10 = ustair/sqrt(0.0015)
1976 real,
intent(in) :: &
1981 type(verticalgrid_type),
intent(in) :: GV
1982 real,
intent(out) :: LA
1985 real,
parameter :: &
1987 u19p5_to_u10 = 1.075, &
1992 us_to_u10 = 0.0162, &
1995 real :: us, hm0, fm, fp, vstokes, kphil, kstar
1996 real :: z0, z0i, r1, r2, r3, r4, tmp, us_sl, lasl_sqr_i
2001 if (u10 .gt. 0.0 .and. ustar .gt. 0.0)
then 2007 hm0 = 0.0246 *u10**2
2010 tmp = 2.0 * pi * u19p5_to_u10 * u10
2011 fp = 0.877 * gv%g_Earth / tmp
2020 vstokes = 0.125 * pi * r_loss * fm * hm0**2
2024 kphil = 0.176 * us / vstokes
2030 kstar = kphil * 2.56
2037 r1 = ( 0.151 / kphil * z0i -0.84 ) &
2038 * ( 1.0 - exp(-2.0 * kphil * z0) )
2039 r2 = -( 0.84 + 0.0591 / kphil * z0i ) &
2040 *sqrt( 2.0 * pi * kphil * z0 ) &
2041 *erfc( sqrt( 2.0 * kphil * z0 ) )
2042 r3 = ( 0.0632 / kstar * z0i + 0.125 ) &
2043 * (1.0 - exp(-2.0 * kstar * z0) )
2044 r4 = ( 0.125 + 0.0946 / kstar * z0i ) &
2045 *sqrt( 2.0 * pi *kstar * z0) &
2046 *erfc( sqrt( 2.0 * kstar * z0 ) )
2047 us_sl = us * (0.715 + r1 + r2 + r3 + r4)
2049 la = sqrt(ustar / us_sl)
2056 type(time_type),
target,
intent(in) :: Time
2057 type(ocean_grid_type),
intent(in) :: G
2058 type(verticalgrid_type),
intent(in) :: GV
2059 type(param_file_type),
intent(in) :: param_file
2060 type(diag_ctrl),
target,
intent(inout) :: diag
2071 #include "version_variable.h" 2072 character(len=40) :: mdl =
"MOM_energetic_PBL" 2073 real :: omega_frac_dflt
2074 integer :: isd, ied, jsd, jed
2075 logical :: use_temperature, use_omega
2076 isd = g%isd ; ied = g%ied ; jsd = g%jsd ; jed = g%jed
2078 if (
associated(cs))
then 2079 call mom_error(warning,
"mixedlayer_init called with an associated"// &
2080 "associated control structure.")
2082 else ;
allocate(cs) ;
endif 2088 call log_version(param_file, mdl, version,
"")
2090 call get_param(param_file, mdl,
"MSTAR_MODE", cs%mstar_mode, &
2091 "An integer switch for how to compute MSTAR. \n"//&
2092 " 0 for constant MSTAR\n"//&
2093 " 1 for MSTAR w/ MLD in stabilizing limit\n"//&
2094 " 2 for MSTAR w/ L_E/L_O in stabilizing limit.",&
2095 "units=nondim",default=0)
2096 call get_param(param_file, mdl,
"MSTAR", cs%mstar, &
2097 "The ratio of the friction velocity cubed to the TKE \n"//&
2098 "input to the mixed layer.",
"units=nondim", default=1.2)
2099 call get_param(param_file, mdl,
"MIX_LEN_EXPONENT", cs%MixLenExponent, &
2100 "The exponent applied to the ratio of the distance to the MLD \n"//&
2101 "and the MLD depth which determines the shape of the mixing length.",&
2102 "units=nondim", default=2.0)
2103 call get_param(param_file, mdl,
"MSTAR_CAP", cs%mstar_cap, &
2104 "Maximum value of mstar allowed in model if non-negative\n"//&
2105 "(used if MSTAR_MODE>0).",&
2106 "units=nondim", default=-1.0)
2107 call get_param(param_file, mdl,
"MSTAR_CONV_ADJ", cs%cnv_mst_fac, &
2108 "Factor used for reducing mstar during convection \n"//&
2109 " due to reduction of stable density gradient.",&
2110 "units=nondim", default=0.0)
2111 call get_param(param_file, mdl,
"MSTAR_SLOPE", cs%mstar_slope, &
2112 "The slope of the linear relationship between mstar \n"//&
2113 "and the length scale ratio (used if MSTAR_MODE=1).",&
2114 "units=nondim", default=0.85)
2115 call get_param(param_file, mdl,
"MSTAR_XINT", cs%mstar_xint, &
2116 "The value of the length scale ratio where the mstar \n"//&
2117 "is linear above (used if MSTAR_MODE=1).",&
2118 "units=nondim", default=-0.3)
2119 call get_param(param_file, mdl,
"MSTAR_AT_XINT", cs%mstar_at_xint, &
2120 "The value of mstar at MSTAR_XINT \n"//&
2121 "(used if MSTAR_MODE=1).",&
2122 "units=nondim", default=0.095)
2123 call get_param(param_file, mdl,
"MSTAR_FLATCAP", cs%MSTAR_FLATCAP, &
2124 "Set false to use asymptotic cap, defaults to true.\n"//&
2125 "(used only if MSTAR_MODE=1)"&
2126 ,
"units=nondim",default=.true.)
2127 call get_param(param_file, mdl,
"MSTAR2_COEF1", cs%MSTAR_COEF, &
2128 "Coefficient in computing mstar when rotation and \n"//&
2129 " stabilizing effects are both important (used if MSTAR_MODE=2)"&
2130 ,
"units=nondim",default=0.3)
2131 call get_param(param_file, mdl,
"MSTAR2_COEF2", cs%C_EK, &
2132 "Coefficient in computing mstar when only rotation limits \n"//&
2133 " the total mixing. (used only if MSTAR_MODE=2)"&
2134 ,
"units=nondim",default=0.085)
2135 call get_param(param_file, mdl,
"NSTAR", cs%nstar, &
2136 "The portion of the buoyant potential energy imparted by \n"//&
2137 "surface fluxes that is available to drive entrainment \n"//&
2138 "at the base of mixed layer when that energy is positive.", &
2139 units=
"nondim", default=0.2)
2140 call get_param(param_file, mdl,
"MKE_TO_TKE_EFFIC", cs%MKE_to_TKE_effic, &
2141 "The efficiency with which mean kinetic energy released \n"//&
2142 "by mechanically forced entrainment of the mixed layer \n"//&
2143 "is converted to turbulent kinetic energy.", units=
"nondim", &
2145 call get_param(param_file, mdl,
"TKE_DECAY", cs%TKE_decay, &
2146 "TKE_DECAY relates the vertical rate of decay of the \n"//&
2147 "TKE available for mechanical entrainment to the natural \n"//&
2148 "Ekman depth.", units=
"nondim", default=2.5)
2153 call get_param(param_file, mdl,
"OMEGA",cs%omega, &
2154 "The rotation rate of the earth.", units=
"s-1", &
2156 call get_param(param_file, mdl,
"ML_USE_OMEGA", use_omega, &
2157 "If true, use the absolute rotation rate instead of the \n"//&
2158 "vertical component of rotation when setting the decay \n"// &
2159 "scale for turbulence.", default=.false., do_not_log=.true.)
2160 omega_frac_dflt = 0.0
2162 call mom_error(warning,
"ML_USE_OMEGA is depricated; use ML_OMEGA_FRAC=1.0 instead.")
2163 omega_frac_dflt = 1.0
2165 call get_param(param_file, mdl,
"ML_OMEGA_FRAC", cs%omega_frac, &
2166 "When setting the decay scale for turbulence, use this \n"// &
2167 "fraction of the absolute rotation rate blended with the \n"//&
2168 "local value of f, as sqrt((1-of)*f^2 + of*4*omega^2).", &
2169 units=
"nondim", default=omega_frac_dflt)
2170 call get_param(param_file, mdl,
"WSTAR_USTAR_COEF", cs%wstar_ustar_coef, &
2171 "A ratio relating the efficiency with which convectively \n"//&
2172 "released energy is converted to a turbulent velocity, \n"// &
2173 "relative to mechanically forced TKE. Making this larger \n"//&
2174 "increases the BL diffusivity", units=
"nondim", default=1.0)
2175 call get_param(param_file, mdl,
"VSTAR_SCALE_FACTOR", cs%vstar_scale_fac, &
2176 "An overall nondimensional scaling factor for v*. \n"// &
2177 "Making this larger decreases the PBL diffusivity.", &
2178 units=
"nondim", default=1.0)
2179 call get_param(param_file, mdl,
"EKMAN_SCALE_COEF", cs%Ekman_scale_coef, &
2180 "A nondimensional scaling factor controlling the inhibition \n"// &
2181 "of the diffusive length scale by rotation. Making this larger \n"//&
2182 "decreases the PBL diffusivity.", units=
"nondim", default=1.0)
2183 call get_param(param_file, mdl,
"USE_MLD_ITERATION", cs%USE_MLD_ITERATION, &
2184 "A logical that specifies whether or not to use the \n"// &
2185 "distance to the bottom of the actively turblent boundary \n"//&
2186 "layer to help set the EPBL length scale.", default=.false.)
2187 call get_param(param_file, mdl,
"ORIG_MLD_ITERATION", cs%ORIG_MLD_ITERATION, &
2188 "A logical that specifies whether or not to use the \n"// &
2189 "old method for determining MLD depth in iteration, which \n"//&
2190 "is limited to resolution.", default=.true.)
2191 call get_param(param_file, mdl,
"MLD_ITERATION_GUESS", cs%MLD_ITERATION_GUESS, &
2192 "A logical that specifies whether or not to use the \n"// &
2193 "previous timestep MLD as a first guess in the MLD iteration.\n"// &
2194 "The default is false to facilitate reproducibility.", default=.false.)
2195 call get_param(param_file, mdl,
"EPBL_MLD_TOLERANCE", cs%MLD_tol, &
2196 "The tolerance for the iteratively determined mixed \n"// &
2197 "layer depth. This is only used with USE_MLD_ITERATION.", &
2198 units=
"meter", default=1.0)
2199 call get_param(param_file, mdl,
"EPBL_MIN_MIX_LEN", cs%min_mix_len, &
2200 "The minimum mixing length scale that will be used \n"//&
2201 "by ePBL. The default (0) does not set a minimum.", &
2202 units=
"meter", default=0.0)
2203 call get_param(param_file, mdl,
"EPBL_ORIGINAL_PE_CALC", cs%orig_PE_calc, &
2204 "If true, the ePBL code uses the original form of the \n"// &
2205 "potential energy change code. Otherwise, the newer \n"// &
2206 "version that can work with successive increments to the \n"// &
2207 "diffusivity in upward or downward passes is used.", default=.true.)
2208 call get_param(param_file, mdl,
"EPBL_TRANSITION_SCALE", cs%transLay_scale, &
2209 "A scale for the mixing length in the transition layer \n"// &
2210 "at the edge of the boundary layer as a fraction of the \n"//&
2211 "boundary layer thickness. The default is 0.1.", &
2212 units=
"nondim", default=0.1)
2213 if ( cs%USE_MLD_ITERATION .and. abs(cs%transLay_scale-0.5).ge.0.5)
then 2214 call mom_error(fatal,
"If flag USE_MLD_ITERATION is true, then "// &
2215 "EPBL_TRANSITION should be greater than 0 and less than 1.")
2217 call get_param(param_file, mdl,
"N2_DISSIPATION_POS", cs%N2_Dissipation_Scale_Pos, &
2218 "A scale for the dissipation of TKE due to stratification \n"// &
2219 "in the boundary layer, applied when local stratification \n"// &
2220 "is positive. The default is 0, but should probably be ~0.4.", &
2221 units=
"nondim", default=0.0)
2222 call get_param(param_file, mdl,
"N2_DISSIPATION_NEG", cs%N2_Dissipation_Scale_Neg,&
2223 "A scale for the dissipation of TKE due to stratification \n"// &
2224 "in the boundary layer, applied when local stratification \n"// &
2225 "is negative. The default is 0, but should probably be ~1.", &
2226 units=
"nondim", default=0.0)
2227 call get_param(param_file, mdl,
"USE_LA_LI2016", cs%USE_LA_Windsea, &
2228 "A logical to use the Li et al. 2016 (submitted) formula to \n"//&
2229 " determine the Langmuir number.", &
2230 units=
"nondim", default=.false.)
2231 call get_param(param_file, mdl,
"LA_DEPTH_RATIO", cs%LaDepthRatio, &
2232 "The depth (normalized by BLD) to average Stokes drift over in \n"//&
2233 " Lanmguir number calculation, where La = sqrt(ust/Stokes).", &
2234 units=
"nondim",default=0.04)
2235 call get_param(param_file, mdl,
"LT_ENHANCE", cs%LT_ENHANCE_FORM, &
2236 "Integer for Langmuir number mode. \n"// &
2237 " *Requires USE_LA_LI2016 to be set to True. \n"// &
2238 "Options: 0 - No Langmuir \n"// &
2239 " 1 - Van Roekel et al. 2014/Li et al., 2016 \n"//&
2240 " 2 - Multiplied w/ adjusted La. \n"// &
2241 " 3 - Added w/ adjusted La.", &
2242 units=
"nondim", default=0)
2243 call get_param(param_file, mdl,
"LT_ENHANCE_COEF", cs%LT_ENHANCE_COEF, &
2244 "Coefficient for Langmuir enhancement if LT_ENHANCE > 1",&
2245 units=
"nondim", default=0.447)
2246 call get_param(param_file, mdl,
"LT_ENHANCE_EXP", cs%LT_ENHANCE_EXP, &
2247 "Exponent for Langmuir enhancement if LT_ENHANCE > 1", &
2248 units=
"nondim", default=-1.33)
2249 call get_param(param_file, mdl,
"LT_MOD_LAC1", cs%LaC_MLDoEK, &
2250 "Coefficient for modification of Langmuir number due to\n"//&
2251 " MLD approaching Ekman depth if LT_ENHANCE=2.", &
2252 units=
"nondim", default=-0.87)
2253 call get_param(param_file, mdl,
"LT_MOD_LAC2", cs%LaC_MLDoOB_stab, &
2254 "Coefficient for modification of Langmuir number due to\n"//&
2255 " MLD approaching stable Obukhov depth if LT_ENHANCE=2.", &
2256 units=
"nondim", default=0.0)
2257 call get_param(param_file, mdl,
"LT_MOD_LAC3", cs%LaC_MLDoOB_un, &
2258 "Coefficient for modification of Langmuir number due to\n"//&
2259 " MLD approaching unstable Obukhov depth if LT_ENHANCE=2.", &
2260 units=
"nondim", default=0.0)
2261 call get_param(param_file, mdl,
"LT_MOD_LAC4", cs%Lac_EKoOB_stab, &
2262 "Coefficient for modification of Langmuir number due to\n"//&
2263 " ratio of Ekman to stable Obukhov depth if LT_ENHANCE=2.", &
2264 units=
"nondim", default=0.95)
2265 call get_param(param_file, mdl,
"LT_MOD_LAC5", cs%Lac_EKoOB_un, &
2266 "Coefficient for modification of Langmuir number due to\n"// &
2267 " ratio of Ekman to unstable Obukhov depth if LT_ENHANCE=2.",&
2268 units=
"nondim", default=0.95)
2269 if (cs%LT_ENHANCE_FORM.gt.0 .and. (.not.cs%USE_LA_Windsea))
then 2270 call mom_error(fatal,
"If flag USE_LA_LI2016 is false, then "//&
2271 " LT_ENHANCE must be 0.")
2274 cs%ustar_min = 2e-4*cs%omega*(gv%Angstrom_z + gv%H_to_m*gv%H_subroundoff)
2275 call log_param(param_file, mdl,
"EPBL_USTAR_MIN", cs%ustar_min, &
2276 "The (tiny) minimum friction velocity used within the \n"//&
2277 "ePBL code, derived from OMEGA and ANGSTROM.", units=
"meter second-1")
2279 cs%id_ML_depth = register_diag_field(
'ocean_model',
'ePBL_h_ML', diag%axesT1, &
2280 time,
'Surface mixed layer depth',
'meter')
2281 cs%id_TKE_wind = register_diag_field(
'ocean_model',
'ePBL_TKE_wind', diag%axesT1, &
2282 time,
'Wind-stirring source of mixed layer TKE',
'meter3 second-3')
2283 cs%id_TKE_MKE = register_diag_field(
'ocean_model',
'ePBL_TKE_MKE', diag%axesT1, &
2284 time,
'Mean kinetic energy source of mixed layer TKE',
'meter3 second-3')
2285 cs%id_TKE_conv = register_diag_field(
'ocean_model',
'ePBL_TKE_conv', diag%axesT1, &
2286 time,
'Convective source of mixed layer TKE',
'meter3 second-3')
2287 cs%id_TKE_forcing = register_diag_field(
'ocean_model',
'ePBL_TKE_forcing', diag%axesT1, &
2288 time,
'TKE consumed by mixing surface forcing or penetrative shortwave radation'//&
2289 ' through model layers',
'meter3 second-3')
2290 cs%id_TKE_mixing = register_diag_field(
'ocean_model',
'ePBL_TKE_mixing', diag%axesT1, &
2291 time,
'TKE consumed by mixing that deepens the mixed layer',
'meter3 second-3')
2292 cs%id_TKE_mech_decay = register_diag_field(
'ocean_model',
'ePBL_TKE_mech_decay', diag%axesT1, &
2293 time,
'Mechanical energy decay sink of mixed layer TKE',
'meter3 second-3')
2294 cs%id_TKE_conv_decay = register_diag_field(
'ocean_model',
'ePBL_TKE_conv_decay', diag%axesT1, &
2295 time,
'Convective energy decay sink of mixed layer TKE',
'meter3 second-3')
2296 cs%id_Hsfc_used = register_diag_field(
'ocean_model',
'ePBL_Hs_used', diag%axesT1, &
2297 time,
'Surface region thickness that is used',
'meter')
2298 cs%id_Mixing_Length = register_diag_field(
'ocean_model',
'Mixing_Length', diag%axesTi, &
2299 time,
'Mixing Length that is used',
'meter')
2300 cs%id_Velocity_Scale = register_diag_field(
'ocean_model',
'Velocity_Scale', diag%axesTi, &
2301 time,
'Velocity Scale that is used.',
'meter second-1')
2302 cs%id_LT_enhancement = register_diag_field(
'ocean_model',
'LT_Enhancement', diag%axesT1, &
2303 time,
'LT enhancement that is used.',
'non-dim')
2304 cs%id_MSTAR_mix = register_diag_field(
'ocean_model',
'MSTAR', diag%axesT1, &
2305 time,
'MSTAR that is used.',
'non-dim')
2306 cs%id_OSBL = register_diag_field(
'ocean_model',
'ePBL_OSBL', diag%axesT1, &
2307 time,
'Boundary layer depth from the iteration.',
'meter')
2308 cs%id_mld_ekman = register_diag_field(
'ocean_model',
'MLD_EKMAN', diag%axesT1, &
2309 time,
'Boundary layer depth over Ekman length.',
'meter')
2310 cs%id_mld_obukhov = register_diag_field(
'ocean_model',
'MLD_OBUKHOV', diag%axesT1, &
2311 time,
'Boundary layer depth over Obukhov length.',
'meter')
2312 cs%id_ekman_obukhov = register_diag_field(
'ocean_model',
'EKMAN_OBUKHOV', diag%axesT1, &
2313 time,
'Ekman length over Obukhov length.',
'meter')
2314 cs%id_LA = register_diag_field(
'ocean_model',
'LA', diag%axesT1, &
2315 time,
'Langmuir number.',
'non-dim')
2316 cs%id_LA_mod = register_diag_field(
'ocean_model',
'LA_MOD', diag%axesT1, &
2317 time,
'Modified Langmuir number.',
'non-dim')
2320 call get_param(param_file, mdl,
"ENABLE_THERMODYNAMICS", use_temperature, &
2321 "If true, temperature and salinity are used as state \n"//&
2322 "variables.", default=.true.)
2324 if (max(cs%id_TKE_wind, cs%id_TKE_MKE, cs%id_TKE_conv, &
2325 cs%id_TKE_mixing, cs%id_TKE_mech_decay, cs%id_TKE_forcing, &
2326 cs%id_TKE_conv_decay) > 0)
then 2327 call safe_alloc_alloc(cs%diag_TKE_wind, isd, ied, jsd, jed)
2328 call safe_alloc_alloc(cs%diag_TKE_MKE, isd, ied, jsd, jed)
2329 call safe_alloc_alloc(cs%diag_TKE_conv, isd, ied, jsd, jed)
2330 call safe_alloc_alloc(cs%diag_TKE_forcing, isd, ied, jsd, jed)
2331 call safe_alloc_alloc(cs%diag_TKE_mixing, isd, ied, jsd, jed)
2332 call safe_alloc_alloc(cs%diag_TKE_mech_decay, isd, ied, jsd, jed)
2333 call safe_alloc_alloc(cs%diag_TKE_conv_decay, isd, ied, jsd, jed)
2335 cs%TKE_diagnostics = .true.
2337 if ((cs%id_Mixing_Length>0) .or. (cs%id_Velocity_Scale>0))
then 2338 call safe_alloc_alloc(cs%Velocity_Scale,isd,ied,jsd,jed,gv%ke+1)
2339 call safe_alloc_alloc(cs%Mixing_Length,isd,ied,jsd,jed,gv%ke+1)
2340 cs%Velocity_Scale(:,:,:) = 0.0
2341 cs%Mixing_Length(:,:,:) = 0.0
2342 cs%mixing_diagnostics = .true.
2344 call safe_alloc_alloc(cs%ML_depth, isd, ied, jsd, jed)
2345 call safe_alloc_alloc(cs%ML_depth2, isd, ied, jsd, jed)
2346 if (max(cs%id_LT_Enhancement, cs%id_mstar_mix,cs%id_mld_ekman, &
2347 cs%id_ekman_obukhov, cs%id_mld_obukhov, cs%id_LA, cs%id_LA_mod)>0)
then 2348 call safe_alloc_alloc(cs%Mstar_mix, isd, ied, jsd, jed)
2349 call safe_alloc_alloc(cs%Enhance_M, isd, ied, jsd, jed)
2350 call safe_alloc_alloc(cs%MLD_EKMAN, isd, ied, jsd, jed)
2351 call safe_alloc_alloc(cs%MLD_OBUKHOV, isd, ied, jsd, jed)
2352 call safe_alloc_alloc(cs%EKMAN_OBUKHOV, isd, ied, jsd, jed)
2353 call safe_alloc_alloc(cs%LA, isd, ied, jsd, jed)
2354 call safe_alloc_alloc(cs%LA_MOD, isd, ied, jsd, jed)
2358 cs%MSTAR_A = cs%MSTAR_AT_XINT**(1./cs%MSTAR_N)
2359 cs%MSTAR_B = cs%MSTAR_SLOPE / (cs%MSTAR_N*cs%MSTAR_A**(cs%MSTAR_N-1.))
2362 cs%MSTAR_A2 = 0.5**(1./cs%MSTAR_N)
2363 cs%MSTAR_B2 = -cs%MSTAR_SLOPE / (cs%MSTAR_N*cs%MSTAR_A2**(cs%MSTAR_N-1))
2366 cs%MSTAR_XINT_UP = (cs%MSTAR_CAP-0.5-cs%MSTAR_AT_XINT)/cs%MSTAR_SLOPE
2373 if (.not.
associated(cs))
return 2375 if (
allocated(cs%ML_depth))
deallocate(cs%ML_depth)
2376 if (
allocated(cs%ML_depth2))
deallocate(cs%ML_depth2)
2377 if (
allocated(cs%Enhance_M))
deallocate(cs%Enhance_M)
2378 if (
allocated(cs%MLD_EKMAN))
deallocate(cs%MLD_EKMAN)
2379 if (
allocated(cs%MLD_OBUKHOV))
deallocate(cs%MLD_OBUKHOV)
2380 if (
allocated(cs%EKMAN_OBUKHOV))
deallocate(cs%EKMAN_OBUKHOV)
2381 if (
allocated(cs%LA))
deallocate(cs%LA)
2382 if (
allocated(cs%LA_mod))
deallocate(cs%LA_mod)
2383 if (
allocated(cs%MSTAR_MIX))
deallocate(cs%MSTAR_MIX)
2384 if (
allocated(cs%diag_TKE_wind))
deallocate(cs%diag_TKE_wind)
2385 if (
allocated(cs%diag_TKE_MKE))
deallocate(cs%diag_TKE_MKE)
2386 if (
allocated(cs%diag_TKE_conv))
deallocate(cs%diag_TKE_conv)
2387 if (
allocated(cs%diag_TKE_forcing))
deallocate(cs%diag_TKE_forcing)
2388 if (
allocated(cs%diag_TKE_mixing))
deallocate(cs%diag_TKE_mixing)
2389 if (
allocated(cs%diag_TKE_mech_decay))
deallocate(cs%diag_TKE_mech_decay)
2390 if (
allocated(cs%diag_TKE_conv_decay))
deallocate(cs%diag_TKE_conv_decay)
2391 if (
allocated(cs%Mixing_Length))
deallocate(cs%Mixing_Length)
2392 if (
allocated(cs%Velocity_Scale))
deallocate(cs%Velocity_Scale)
This module implements boundary forcing for MOM6.
Ocean grid type. See mom_grid for details.
subroutine, public energetic_pbl_end(CS)
Provides the ocean grid type.
subroutine, public do_group_pass(group, MOM_dom)
subroutine, public energetic_pbl(h_3d, u_3d, v_3d, tv, fluxes, dt, Kd_int, G, GV, CS, dSV_dT, dSV_dS, TKE_forced, Buoy_Flux, dt_diag, last_call, dT_expected, dS_expected)
This subroutine determines the diffusivities from the integrated energetics mixed layer model...
subroutine find_pe_chg(Kddt_h0, dKddt_h, hp_a, hp_b, Th_a, Sh_a, Th_b, Sh_b, dT_to_dPE_a, dS_to_dPE_a, dT_to_dPE_b, dS_to_dPE_b, pres, dT_to_dColHt_a, dS_to_dColHt_a, dT_to_dColHt_b, dS_to_dColHt_b, PE_chg, dPEc_dKd, dPE_max, dPEc_dKd_0, ColHt_cor)
This subroutine calculates the change in potential energy and or derivatives for several changes in a...
subroutine get_la_windsea(ustar, hbl, GV, LA)
subroutine ust_2_u10_coare3p5(USTair, U10, GV)
Computes wind speed from ustar_air based on COARE 3.5 Cd relationship.
Structure that contains pointers to the boundary forcing used to drive the liquid ocean simulated by ...
The thermo_var_ptrs structure contains pointers to an assortment of thermodynamic fields that may be ...
subroutine, public energetic_pbl_get_mld(CS, MLD, G)
Copies the ePBL active mixed layer depth into MLD.
subroutine find_pe_chg_orig(Kddt_h, h_k, b_den_1, dTe_term, dSe_term, dT_km1_t2, dS_km1_t2, dT_to_dPE_k, dS_to_dPE_k, dT_to_dPEa, dS_to_dPEa, pres, dT_to_dColHt_k, dS_to_dColHt_k, dT_to_dColHta, dS_to_dColHta, PE_chg, dPEc_dKd, dPE_max, dPEc_dKd_0)
This subroutine calculates the change in potential energy and or derivatives for several changes in a...
subroutine, public mom_error(level, message, all_print)
subroutine, public energetic_pbl_init(Time, G, GV, param_file, diag, CS)