Skip to content

Commit 6d1edf6

Browse files
Merge branch 'whannah/eam/zm-cleanup-03' (PR #6964)
ZM cleanup - Remove buoyan() subroutine This is a continuation of the ZM overhaul and refactoring, which is limited to cosmetic cleanup of the main ZM routines. In this iteration we remove the unused subroutine buoyan(), which is the original undilute parcel and CAPE calculations that were abandoned in the CAM4 era. [BFB] * whannah/eam/zm-cleanup-03: remove buoyan() subroutine from ZM
2 parents b36604b + 7e89d9b commit 6d1edf6

File tree

1 file changed

+23
-344
lines changed

1 file changed

+23
-344
lines changed

components/eam/src/physics/cam/zm_conv.F90

Lines changed: 23 additions & 344 deletions
Original file line numberDiff line numberDiff line change
@@ -350,7 +350,6 @@ subroutine zm_convr(lchnk ,ncol , &
350350
! and will make use of the standard CAM nomenclature
351351
!
352352
!-----------------------------------------------------------------------
353-
use phys_control, only: cam_physpkg_is
354353
use time_manager, only: is_first_step
355354
!
356355
! ************************ index of variables **********************
@@ -800,53 +799,36 @@ subroutine zm_convr(lchnk ,ncol , &
800799
dsubcld(i) = 0._r8
801800
end do
802801

803-
if( cam_physpkg_is('cam3')) then
802+
! Evaluate Tparcel, qs(Tparcel), buoyancy, CAPE, lcl, lel, parcel launch level at index maxi()=hmax
803+
! - call #1, iclosure=.true. standard calculation using state of current step
804+
! - call #2, iclosure=.false. use state from previous step and launch level from call #1
805+
! DCAPE is the difference in CAPE between the two calls using the same launch level
804806

805-
! For cam3 physics package, call non-dilute
807+
iclosure = .true.
808+
call buoyan_dilute(lchnk ,ncol , &
809+
q ,t ,p ,z ,pf , &
810+
tp ,qstp ,tl ,rl ,cape , &
811+
pblt ,lcl ,lel ,lon ,maxi , &
812+
rgas ,grav ,cpres ,msg , &
813+
tpert ,iclosure )
806814

807-
call buoyan(lchnk ,ncol , &
808-
q ,t ,p ,z ,pf , &
809-
tp ,qstp ,tl ,rl ,cape , &
810-
pblt ,lcl ,lel ,lon ,maxi , &
811-
rgas ,grav ,cpres ,msg , &
812-
tpert )
813-
else
814-
815-
! Evaluate Tparcel, qs(Tparcel), buoyancy and CAPE,
816-
! lcl, lel, parcel launch level at index maxi()=hmax
817-
!
815+
if (trigdcape_ull .or. trig_dcape_only) dcapemx(:ncol) = maxi(:ncol)
818816

819-
! 1. First call, iclosure = .true., standard calculation, scanning for launching level up to 600 hPa
820-
! 2. Second call, iclosure = .faklse. pass the launch level from 1st call to determine CAPE at previous step
821-
! The differewnce of CAPE values from the two calls is DCAPE, based on the same launch level
817+
!DCAPE-ULL
818+
if ( .not.is_first_step() .and. (trigdcape_ull.or.trig_dcape_only) ) then
822819

823-
iclosure = .true.
820+
iclosure = .false.
821+
call buoyan_dilute( lchnk ,ncol , &
822+
q_star ,t_star ,p ,z ,pf , &
823+
tpm1 ,qstpm1 ,tlm1 ,rl ,capem1 , &
824+
pblt ,lclm1 ,lelm1 ,lonm1 ,maxim1 , &
825+
rgas ,grav ,cpres ,msg , &
826+
tpert ,iclosure, dcapemx )
824827

825-
call buoyan_dilute(lchnk ,ncol , &! in
826-
q ,t ,p ,z ,pf , &! in
827-
tp ,qstp ,tl ,rl ,cape , &! rl = in, others = out
828-
pblt ,lcl ,lel ,lon ,maxi , &! pblt = in, others = out
829-
rgas ,grav ,cpres ,msg , &! in
830-
tpert ,iclosure ) ! in
831-
832-
if (trigdcape_ull .or. trig_dcape_only) then
833-
dcapemx(:ncol) = maxi(:ncol)
834-
endif
828+
dcape(:ncol) = (cape(:ncol)-capem1(:ncol))/(delt*2._r8)
835829

836-
!DCAPE-ULL
837-
if (.not. is_first_step() .and. (trigdcape_ull .or. trig_dcape_only)) then
838-
iclosure = .false.
839-
840-
call buoyan_dilute(lchnk ,ncol , &! in
841-
q_star ,t_star ,p ,z ,pf , &! in
842-
tpm1 ,qstpm1 ,tlm1 ,rl ,capem1 , &! rl = in, others = out
843-
pblt ,lclm1 ,lelm1 ,lonm1 ,maxim1 , &! pblt = in; others = out
844-
rgas ,grav ,cpres ,msg , &! in
845-
tpert ,iclosure, dcapemx ) ! in
830+
endif
846831

847-
dcape(:ncol) = (cape(:ncol)-capem1(:ncol))/(delt*2._r8)
848-
endif
849-
end if
850832

851833
!
852834
! determine whether grid points will undergo some deep convection
@@ -2434,309 +2416,6 @@ end subroutine momtran
24342416

24352417
!=========================================================================================
24362418

2437-
subroutine buoyan(lchnk ,ncol , &
2438-
q ,t ,p ,z ,pf , &
2439-
tp ,qstp ,tl ,rl ,cape , &
2440-
pblt ,lcl ,lel ,lon ,mx , &
2441-
rd ,grav ,cp ,msg , &
2442-
tpert )
2443-
!-----------------------------------------------------------------------
2444-
!
2445-
! Purpose:
2446-
! <Say what the routine does>
2447-
!
2448-
! Method:
2449-
! <Describe the algorithm(s) used in the routine.>
2450-
! <Also include any applicable external references.>
2451-
!
2452-
! Author:
2453-
! This is contributed code not fully standardized by the CCM core group.
2454-
! The documentation has been enhanced to the degree that we are able.
2455-
! Reviewed: P. Rasch, April 1996
2456-
!
2457-
!-----------------------------------------------------------------------
2458-
implicit none
2459-
!-----------------------------------------------------------------------
2460-
!
2461-
! input arguments
2462-
!
2463-
integer, intent(in) :: lchnk ! chunk identifier
2464-
integer, intent(in) :: ncol ! number of atmospheric columns
2465-
2466-
real(r8), intent(in) :: q(pcols,pver) ! spec. humidity
2467-
real(r8), intent(in) :: t(pcols,pver) ! temperature
2468-
real(r8), intent(in) :: p(pcols,pver) ! pressure
2469-
real(r8), intent(in) :: z(pcols,pver) ! height
2470-
real(r8), intent(in) :: pf(pcols,pver+1) ! pressure at interfaces
2471-
integer, intent(in) :: pblt(pcols) ! index of pbl depth
2472-
real(r8), intent(in) :: tpert(pcols) ! perturbation temperature by pbl processes
2473-
2474-
!
2475-
! output arguments
2476-
!
2477-
real(r8), intent(out) :: tp(pcols,pver) ! parcel temperature
2478-
real(r8), intent(out) :: qstp(pcols,pver) ! saturation mixing ratio of parcel
2479-
real(r8), intent(out) :: tl(pcols) ! parcel temperature at lcl
2480-
real(r8), intent(out) :: cape(pcols) ! convective aval. pot. energy.
2481-
integer lcl(pcols) !
2482-
integer lel(pcols) !
2483-
integer lon(pcols) ! level of onset of deep convection
2484-
integer mx(pcols) ! level of max moist static energy
2485-
!
2486-
!--------------------------Local Variables------------------------------
2487-
!
2488-
real(r8) capeten(pcols,5) ! provisional value of cape
2489-
real(r8) tv(pcols,pver) !
2490-
real(r8) tpv(pcols,pver) !
2491-
real(r8) buoy(pcols,pver)
2492-
2493-
real(r8) a1(pcols)
2494-
real(r8) a2(pcols)
2495-
real(r8) estp(pcols)
2496-
real(r8) pl(pcols)
2497-
real(r8) plexp(pcols)
2498-
real(r8) hmax(pcols)
2499-
real(r8) hmn(pcols)
2500-
real(r8) y(pcols)
2501-
2502-
logical plge600(pcols)
2503-
integer knt(pcols)
2504-
integer lelten(pcols,5)
2505-
2506-
real(r8) cp
2507-
real(r8) e
2508-
real(r8) grav
2509-
2510-
integer i
2511-
integer k
2512-
integer msg
2513-
integer n
2514-
2515-
real(r8) rd
2516-
real(r8) rl
2517-
#ifdef PERGRO
2518-
real(r8) rhd
2519-
#endif
2520-
!
2521-
!-----------------------------------------------------------------------
2522-
!
2523-
do n = 1,5
2524-
do i = 1,ncol
2525-
lelten(i,n) = pver
2526-
capeten(i,n) = 0._r8
2527-
end do
2528-
end do
2529-
!
2530-
do i = 1,ncol
2531-
lon(i) = pver
2532-
knt(i) = 0
2533-
lel(i) = pver
2534-
mx(i) = lon(i)
2535-
cape(i) = 0._r8
2536-
hmax(i) = 0._r8
2537-
end do
2538-
2539-
tp(:ncol,:) = t(:ncol,:)
2540-
qstp(:ncol,:) = q(:ncol,:)
2541-
2542-
!!! RBN - Initialize tv and buoy for output.
2543-
!!! tv=tv : tpv=tpv : qstp=q : buoy=0.
2544-
tv(:ncol,:) = t(:ncol,:) *(1._r8+1.608_r8*q(:ncol,:))/ (1._r8+q(:ncol,:))
2545-
tpv(:ncol,:) = tv(:ncol,:)
2546-
buoy(:ncol,:) = 0._r8
2547-
2548-
!
2549-
! set "launching" level(mx) to be at maximum moist static energy.
2550-
! search for this level stops at planetary boundary layer top.
2551-
!
2552-
#ifdef PERGRO
2553-
do k = pver,msg + 1,-1
2554-
do i = 1,ncol
2555-
hmn(i) = cp*t(i,k) + grav*z(i,k) + rl*q(i,k)
2556-
!
2557-
! Reset max moist static energy level when relative difference exceeds 1.e-4
2558-
!
2559-
rhd = (hmn(i) - hmax(i))/(hmn(i) + hmax(i))
2560-
if (k >= pblt(i) .and. k <= lon(i) .and. rhd > -1.e-4_r8) then
2561-
hmax(i) = hmn(i)
2562-
mx(i) = k
2563-
end if
2564-
end do
2565-
end do
2566-
#else
2567-
do k = pver,msg + 1,-1
2568-
do i = 1,ncol
2569-
hmn(i) = cp*t(i,k) + grav*z(i,k) + rl*q(i,k)
2570-
if (k >= pblt(i) .and. k <= lon(i) .and. hmn(i) > hmax(i)) then
2571-
hmax(i) = hmn(i)
2572-
mx(i) = k
2573-
end if
2574-
end do
2575-
end do
2576-
#endif
2577-
!
2578-
do i = 1,ncol
2579-
lcl(i) = mx(i)
2580-
e = p(i,mx(i))*q(i,mx(i))/ (eps1+q(i,mx(i)))
2581-
tl(i) = 2840._r8/ (3.5_r8*log(t(i,mx(i)))-log(e)-4.805_r8) + 55._r8
2582-
if (tl(i) < t(i,mx(i))) then
2583-
plexp(i) = (1._r8/ (0.2854_r8* (1._r8-0.28_r8*q(i,mx(i)))))
2584-
pl(i) = p(i,mx(i))* (tl(i)/t(i,mx(i)))**plexp(i)
2585-
else
2586-
tl(i) = t(i,mx(i))
2587-
pl(i) = p(i,mx(i))
2588-
end if
2589-
end do
2590-
2591-
!
2592-
! calculate lifting condensation level (lcl).
2593-
!
2594-
do k = pver,msg + 2,-1
2595-
do i = 1,ncol
2596-
if (k <= mx(i) .and. (p(i,k) > pl(i) .and. p(i,k-1) <= pl(i))) then
2597-
lcl(i) = k - 1
2598-
end if
2599-
end do
2600-
end do
2601-
!
2602-
! if lcl is above the nominal level of non-divergence (600 mbs),
2603-
! no deep convection is permitted (ensuing calculations
2604-
! skipped and cape retains initialized value of zero).
2605-
!
2606-
do i = 1,ncol
2607-
plge600(i) = pl(i).ge.600._r8
2608-
end do
2609-
!
2610-
! initialize parcel properties in sub-cloud layer below lcl.
2611-
!
2612-
do k = pver,msg + 1,-1
2613-
do i=1,ncol
2614-
if (k > lcl(i) .and. k <= mx(i) .and. plge600(i)) then
2615-
tv(i,k) = t(i,k)* (1._r8+1.608_r8*q(i,k))/ (1._r8+q(i,k))
2616-
qstp(i,k) = q(i,mx(i))
2617-
tp(i,k) = t(i,mx(i))* (p(i,k)/p(i,mx(i)))**(0.2854_r8* (1._r8-0.28_r8*q(i,mx(i))))
2618-
!
2619-
! buoyancy is increased by 0.5 k as in tiedtke
2620-
!
2621-
!-jjh tpv (i,k)=tp(i,k)*(1.+1.608*q(i,mx(i)))/
2622-
!-jjh 1 (1.+q(i,mx(i)))
2623-
tpv(i,k) = (tp(i,k)+tpert(i))*(1._r8+1.608_r8*q(i,mx(i)))/ (1._r8+q(i,mx(i)))
2624-
buoy(i,k) = tpv(i,k) - tv(i,k) + tiedke_add
2625-
end if
2626-
end do
2627-
end do
2628-
2629-
!
2630-
! define parcel properties at lcl (i.e. level immediately above pl).
2631-
!
2632-
do k = pver,msg + 1,-1
2633-
do i=1,ncol
2634-
if (k == lcl(i) .and. plge600(i)) then
2635-
tv(i,k) = t(i,k)* (1._r8+1.608_r8*q(i,k))/ (1._r8+q(i,k))
2636-
qstp(i,k) = q(i,mx(i))
2637-
tp(i,k) = tl(i)* (p(i,k)/pl(i))**(0.2854_r8* (1._r8-0.28_r8*qstp(i,k)))
2638-
! estp(i) =exp(21.656_r8 - 5418._r8/tp(i,k))
2639-
! use of different formulas for es has about 1 g/kg difference
2640-
! in qs at t= 300k, and 0.02 g/kg at t=263k, with the formula
2641-
! above giving larger qs.
2642-
call qsat_hPa(tp(i,k), p(i,k), estp(i), qstp(i,k))
2643-
a1(i) = cp / rl + qstp(i,k) * (1._r8+ qstp(i,k) / eps1) * rl * eps1 / &
2644-
(rd * tp(i,k) ** 2)
2645-
a2(i) = .5_r8* (qstp(i,k)* (1._r8+2._r8/eps1*qstp(i,k))* &
2646-
(1._r8+qstp(i,k)/eps1)*eps1**2*rl*rl/ &
2647-
(rd**2*tp(i,k)**4)-qstp(i,k)* &
2648-
(1._r8+qstp(i,k)/eps1)*2._r8*eps1*rl/ &
2649-
(rd*tp(i,k)**3))
2650-
a1(i) = 1._r8/a1(i)
2651-
a2(i) = -a2(i)*a1(i)**3
2652-
y(i) = q(i,mx(i)) - qstp(i,k)
2653-
tp(i,k) = tp(i,k) + a1(i)*y(i) + a2(i)*y(i)**2
2654-
call qsat_hPa(tp(i,k), p(i,k), estp(i), qstp(i,k))
2655-
!
2656-
! buoyancy is increased by 0.5 k in cape calculation.
2657-
! dec. 9, 1994
2658-
!-jjh tpv(i,k) =tp(i,k)*(1.+1.608*qstp(i,k))/(1.+q(i,mx(i)))
2659-
!
2660-
tpv(i,k) = (tp(i,k)+tpert(i))* (1._r8+1.608_r8*qstp(i,k)) / (1._r8+q(i,mx(i)))
2661-
buoy(i,k) = tpv(i,k) - tv(i,k) + tiedke_add
2662-
end if
2663-
end do
2664-
end do
2665-
!
2666-
! main buoyancy calculation.
2667-
!
2668-
do k = pver - 1,msg + 1,-1
2669-
do i=1,ncol
2670-
if (k < lcl(i) .and. plge600(i)) then
2671-
tv(i,k) = t(i,k)* (1._r8+1.608_r8*q(i,k))/ (1._r8+q(i,k))
2672-
qstp(i,k) = qstp(i,k+1)
2673-
tp(i,k) = tp(i,k+1)* (p(i,k)/p(i,k+1))**(0.2854_r8* (1._r8-0.28_r8*qstp(i,k)))
2674-
call qsat_hPa(tp(i,k), p(i,k), estp(i), qstp(i,k))
2675-
a1(i) = cp/rl + qstp(i,k)* (1._r8+qstp(i,k)/eps1)*rl*eps1/ (rd*tp(i,k)**2)
2676-
a2(i) = .5_r8* (qstp(i,k)* (1._r8+2._r8/eps1*qstp(i,k))* &
2677-
(1._r8+qstp(i,k)/eps1)*eps1**2*rl*rl/ &
2678-
(rd**2*tp(i,k)**4)-qstp(i,k)* &
2679-
(1._r8+qstp(i,k)/eps1)*2._r8*eps1*rl/ &
2680-
(rd*tp(i,k)**3))
2681-
a1(i) = 1._r8/a1(i)
2682-
a2(i) = -a2(i)*a1(i)**3
2683-
y(i) = qstp(i,k+1) - qstp(i,k)
2684-
tp(i,k) = tp(i,k) + a1(i)*y(i) + a2(i)*y(i)**2
2685-
call qsat_hPa(tp(i,k), p(i,k), estp(i), qstp(i,k))
2686-
!-jjh tpv(i,k) =tp(i,k)*(1.+1.608*qstp(i,k))/
2687-
!jt (1.+q(i,mx(i)))
2688-
tpv(i,k) = (tp(i,k)+tpert(i))* (1._r8+1.608_r8*qstp(i,k))/(1._r8+q(i,mx(i)))
2689-
buoy(i,k) = tpv(i,k) - tv(i,k) + tiedke_add
2690-
end if
2691-
end do
2692-
end do
2693-
2694-
!
2695-
do k = msg + 2,pver
2696-
do i = 1,ncol
2697-
if (k < lcl(i) .and. plge600(i)) then
2698-
if (buoy(i,k+1) > 0._r8 .and. buoy(i,k) <= 0._r8) then
2699-
knt(i) = min(5,knt(i) + 1)
2700-
lelten(i,knt(i)) = k
2701-
end if
2702-
end if
2703-
end do
2704-
end do
2705-
!
2706-
! calculate convective available potential energy (cape).
2707-
!
2708-
do n = 1,5
2709-
do k = msg + 1,pver
2710-
do i = 1,ncol
2711-
if (plge600(i) .and. k <= mx(i) .and. k > lelten(i,n)) then
2712-
capeten(i,n) = capeten(i,n) + rd*buoy(i,k)*log(pf(i,k+1)/pf(i,k))
2713-
end if
2714-
end do
2715-
end do
2716-
end do
2717-
!
2718-
! find maximum cape from all possible tentative capes from
2719-
! one sounding,
2720-
! and use it as the final cape, april 26, 1995
2721-
!
2722-
do n = 1,5
2723-
do i = 1,ncol
2724-
if (capeten(i,n) > cape(i)) then
2725-
cape(i) = capeten(i,n)
2726-
lel(i) = lelten(i,n)
2727-
end if
2728-
end do
2729-
end do
2730-
!
2731-
! put lower bound on cape for diagnostic purposes.
2732-
!
2733-
do i = 1,ncol
2734-
cape(i) = max(cape(i), 0._r8)
2735-
end do
2736-
!
2737-
return
2738-
end subroutine buoyan
2739-
27402419
subroutine cldprp(lchnk , &
27412420
q ,t ,u ,v ,p , &
27422421
z ,s ,mu ,eu ,du , &

0 commit comments

Comments
 (0)