@@ -7,6 +7,9 @@ module satmedmfvdifq
77 use mfpbltq_mod
88 use tridi_mod
99 use mfscuq_mod
10+ !PCC_CANOPY_utilities
11+ use canopy_utils_mod
12+
1013 contains
1114
1215!> \defgroup module_satmedmfvdifq GFS TKE- EDMF PBL Module
@@ -74,7 +77,7 @@ end subroutine satmedmfvdifq_init
7477!! (mfscuq.f).
7578!! \section detail_satmedmfvidfq GFS satmedmfvdifq Detailed Algorithm
7679 subroutine satmedmfvdifq_run (im ,km ,ntrac ,ntcw ,ntrw , &
77- & ntiw ,ntke ,grav ,rd ,cp ,rv ,hvap ,hfus ,fv ,eps ,epsm1 , &
80+ & ntiw ,ntke ,grav ,pi , rd ,cp ,rv ,hvap ,hfus ,fv ,eps ,epsm1 , &
7881!The following three variables are for SA-3D-TKE
7982 & def_1 ,def_2 ,def_3 ,sa3dtke ,dku3d_h ,dku3d_e , &
8083 & dv ,du ,tdt ,rtg ,u1 ,v1 ,t1 ,q1 ,usfco ,vsfco ,icplocn2atm , &
@@ -85,9 +88,15 @@ subroutine satmedmfvdifq_run(im,km,ntrac,ntcw,ntrw, &
8588 & dspheat ,dusfc ,dvsfc ,dtsfc ,dqsfc ,hpbl ,dkt ,dku ,tkeh , &
8689 & kinver ,xkzm_m ,xkzm_h ,xkzm_s ,dspfac ,bl_upfr ,bl_dnfr , &
8790 & rlmx ,elmx ,sfc_rlm ,tc_pbl ,use_lpt , &
91+ !IVAI: canopy inputs from AQM
92+ & do_canopy , cplaqm , claie , cfch , cfrt , cclu , cpopu , &
93+ !IVAI
8894 & ntqv ,dtend ,dtidx ,index_of_temperature ,index_of_x_wind , &
8995 & index_of_y_wind ,index_of_process_pbl ,gen_tend ,ldiag3d , &
90- & errmsg ,errflg )
96+ & errmsg ,errflg )
97+ !IVAI: aux arrays
98+ ! & naux2d,naux3d,aux2d,aux3d)
99+
91100!
92101 use machine , only : kind_phys
93102 use funcphys , only : fpvs
@@ -104,11 +113,17 @@ subroutine satmedmfvdifq_run(im,km,ntrac,ntcw,ntrw, &
104113 integer , intent (out ) :: kpbl(:)
105114 logical , intent (in ) :: gen_tend,ldiag3d
106115!
107- real (kind= kind_phys), intent (in ) :: grav,rd,cp,rv,hvap,hfus,fv, &
116+ real (kind= kind_phys), intent (in ) :: grav,pi, rd,cp,rv,hvap,hfus,fv, &
108117 & eps,epsm1
109118 real (kind= kind_phys), intent (in ) :: delt, xkzm_m, xkzm_h, xkzm_s
110119 real (kind= kind_phys), intent (in ) :: dspfac, bl_upfr, bl_dnfr
111120 real (kind= kind_phys), intent (in ) :: rlmx, elmx
121+ !PCC CANOPY------------------------------------
122+ logical , intent (in ) :: do_canopy, cplaqm
123+ !IVAI: canopy inputs
124+ real (kind= kind_phys), optional, intent (in ) :: claie(:), cfch(:), &
125+ & cfrt(:), cclu(:), cpopu(:)
126+ !----------------------------------------------
112127 real (kind= kind_phys), intent (inout ) :: dv(:,:), du(:,:), &
113128 & tdt(:,:), rtg(:,:,:), tkeh(:,:)
114129 real (kind= kind_phys), intent (in ) :: &
@@ -289,8 +304,40 @@ subroutine satmedmfvdifq_run(im,km,ntrac,ntcw,ntrw, &
289304 real (kind= kind_phys) h1
290305
291306 real (kind= kind_phys) bfac, mffac
292-
307+
293308 real (kind= kind_phys) qice(im,km),qliq(im,km)
309+
310+ !PCC_CANOPY------------------------------------
311+ integer COUNTCAN,KCAN
312+ integer kount !IVAI
313+ real (kind= kind_phys) FCH, MOL, HOL, TLCAN,
314+ & SIGMACAN, RRCAN, BBCAN,
315+ & AACAN, ZCAN, ZFL, BOTCAN,
316+ & EDDYVEST1, EDDYVEST_INT
317+
318+ ! in canopy eddy diffusivity [ m** 2 / s ]
319+ real (kind= kind_phys), allocatable :: EDDYVESTX ( : )
320+ ! in canopy layer [m]
321+ real (kind= kind_phys), allocatable :: ZCANX ( : )
322+ ! Declare local maximum canopy layers
323+ integer , parameter :: MAXCAN = 1000
324+ integer , parameter :: mvt = 30 ! use 30 instead of 27
325+ !Based on MODIS IGBP 20 Category Dataset
326+ real :: fch_table(mvt) !< top of canopy (m)
327+ data ( fch_table(i),i= 1 ,mvt) /
328+ & 20.0 , 20.0 , 18.0 , 16.0 , 16.0 , 1.10 ,
329+ & 1.10 , 13.0 , 10.0 , 1.00 , 5.00 , 2.00 ,
330+ & 15.0 , 1.50 , 0.00 , 0.00 , 0.00 , 4.00 ,
331+ & 2.00 , 0.50 , 0.00 , 0.00 , 0.00 , 0.00 ,
332+ & 0.00 , 0.00 , 0.00 , 0.00 , 0.00 , 0.00 /
333+ !----------------------------------------------
334+
335+ !IVAI
336+ ! integer , intent (in ) :: naux2d,naux3d
337+ ! real (kind_phys), intent (inout ) :: aux2d(:,:)
338+ ! real (kind_phys), intent (inout ) :: aux3d(:,:,:)
339+ !IVAI
340+
294341!!
295342 parameter (bfac= 100 .)
296343 parameter (wfac= 7.0 ,cfac= 4.5 )
@@ -314,7 +361,7 @@ subroutine satmedmfvdifq_run(im,km,ntrac,ntcw,ntrw, &
314361 parameter (ck1= 0.15 ,ch1= 0.15 )
315362 parameter (cs0= 0.4 ,csmf= 0.5 )
316363 parameter (rchck= 1.5 ,ndt= 20 )
317- !The following variables are for SA-3D - TKE
364+ !The following variables are for SA-3D - TKE
318365 parameter (cpl1= 0.280 ,cpl2= 0.870 ,cpl3= 0.913 )
319366 parameter (cpl4= 0.153 ,cpl5= 0.278 ,cpl6= 0.720 )
320367 parameter (cpnl1= 0.243 ,cpnl2= 0.936 ,cpnl3= 1.11 )
@@ -325,6 +372,14 @@ subroutine satmedmfvdifq_run(im,km,ntrac,ntcw,ntrw, &
325372 parameter (inv3= 0.33333333 )
326373! parameter (aa1= 0.92 ,aa2= 0.649 ,bb1= 17.7 ,bb2= 9.5 ,cc1= 0.08 )
327374
375+ !PCC_CANOPY------------------------------------
376+ if (do_canopy) then
377+ if (.not. allocated(EDDYVESTX))
378+ & allocate( EDDYVESTX ( MAXCAN ) )
379+ if (.not. allocated(ZCANX))
380+ & allocate( ZCANX ( MAXCAN ) )
381+ endif
382+ !----------------------------------------------
328383 if (tc_pbl == 0 ) then
329384 ck0 = 0.4
330385 ch0 = 0.4
@@ -1562,8 +1617,8 @@ subroutine satmedmfvdifq_run(im,km,ntrac,ntcw,ntrw, &
15621617 endif
15631618 enddo
15641619 enddo
1565-
1566- do k = kmscu, 1, -1
1620+
1621+ do k = kmscu, 1, -1
15671622 do i = 1, im
15681623 if(scuflg(i) .and.
15691624 & (k >= mrad(i) .and. k < krad(i))) then
@@ -1574,6 +1629,179 @@ subroutine satmedmfvdifq_run(im,km,ntrac,ntcw,ntrw, &
15741629
15751630 endif !sa3dtke
15761631
1632+ !PCC_CANOPY------------------------------------
1633+ kount=0 !IVAI
1634+ if (do_canopy .and. cplaqm) then
1635+
1636+ !IVAI
1637+ ! print*, ' SATMEDMFVDIFQ_RUN: CLAIE = ' , claie(:)
1638+ ! print*, ' SATMEDMFVDIFQ_RUN: CFCH = ' , cfch (:)
1639+ ! print*, ' SATMEDMFVDIFQ_RUN: CFRT = ' , cfrt (:)
1640+ ! print*, ' SATMEDMFVDIFQ_RUN: CCLU = ' , cclu (:)
1641+ ! print*, ' SATMEDMFVDIFQ_RUN: CPOPU= ' , cpopu(:)
1642+ ! 2D aux arrays: canopy data in diffusion
1643+ ! aux2d(:,1) = cfch (:)
1644+ ! aux2d(:,2) = claie(:)
1645+ ! aux2d(:,3) = cfrt(:)
1646+
1647+ ! 3D aux arrays: before canopy correction
1648+ ! aux3d(:,:,1) = dkq(:,:)
1649+ ! aux3d(:,:,2) = dkt(:,:)
1650+ ! aux3d(:,:,3) = dku(:,:)
1651+ !IVAI
1652+ do k = 1, km1-1
1653+ do i = 1, im
1654+
1655+ !IVAI: AQM canopy Inputs
1656+ ! FCH = fch_table(vegtype(i)) !top of canopy from look-up table
1657+ FCH = cfch(i) !top of canopy from AQM canopy inputs
1658+ IF (k .EQ. 1) THEN !use model layer interfaces
1659+ KCAN = 1
1660+ ELSE
1661+ IF ( cfch(i) .GT. zi(i,k)
1662+ & .AND. cfch(i) .LE. zi(i,k+1) ) THEN
1663+ KCAN = 1
1664+ ELSE
1665+ KCAN = 0
1666+ END IF
1667+ END IF
1668+
1669+ IF (KCAN .EQ. 1) THEN !canopy inside model layer
1670+ ! Check for other Contiguous Canopy Grid Cell Conditions
1671+
1672+ ! Not a contigous canopy cell
1673+ IF ( claie(i) .LT. 0.1
1674+ & .OR. cfch (i) .LT. 0.5
1675+ !IVAI: modified contiguous canopy condition
1676+ ! & .OR. MAX(0.0, 1.0 - cfrt(i)) .GT. 0.5
1677+ & .OR. MAX(0.0, 1.0 - cfrt(i)) .GT. 0.75
1678+ !IVAI
1679+ & .OR. cpopu(i) .GT. 10000.0
1680+ & .OR. (EXP(-0.5*claie(i)*cclu(i)) .GT. 0.45
1681+ & .AND. cfch(i) .LT. 18.) ) THEN
1682+
1683+
1684+ !TODO: Canopy Inputs
1685+ ! IF ( XCANOPYLAI .LT. 0.1 !from canopy inputs
1686+ ! IF ( lai(i) .LT. 0.1 !from LSM
1687+ ! & .OR. FCH .LT. 0.5 ) THEN
1688+ ! & .OR. MAX(0.0, 1.0 - XCANOPYFRT) .GT. 0.5
1689+ ! & .OR. POPU .GT. 10000.0
1690+ ! & .OR. EXP(-0.5*XCANOPYLAI*XCANOPYCLU).GT. 0.45
1691+ ! & .AND. FCH .LT. 18.0 ) THEN
1692+
1693+ dkt(i,k)= dkt(i,k)
1694+ dkq(i,k)= dkq(i,k)
1695+ dku(i,k)= dku(i,k)
1696+
1697+ ELSE ! There is a contiguous forest canopy, apply correction over canopy layers
1698+
1699+ ! Output contiguous canopy mask
1700+ ! if (kount .EQ. 0 ) aux2d(i,5) = aux2d(i,5) + 1
1701+
1702+ !Raupauch M. R. A Practical Lagrangian method for relating scalar
1703+ !concentrations to
1704+ ! source distributions in vegetation canopies. Q. J. R. Meteor. Soc.
1705+ ! (1989), 115, pp 609-632
1706+ MOL = zol(i)/zl(i,k) !Monin-Obukhov Length in layer
1707+ HOL = FCH/MOL !local canopy stability parameter (hc/MOL)
1708+ ZCAN = zi(i,k+1) ! Initialize each model layer top that contains canopy (m)
1709+ ! Integrate across total model interface
1710+ ZFL = ZCAN ! Set ZFL = ZCAN
1711+ COUNTCAN = 0 ! Initialize canopy layers
1712+
1713+ IF (k .EQ. 1) THEN !Find bottom in each model layer
1714+ BOTCAN = 0.5
1715+ ELSE
1716+ BOTCAN = zi(i,k)
1717+ END IF
1718+
1719+ DO WHILE (ZCAN.GE.BOTCAN)
1720+ ! TLCAN = Lagrangian timescale
1721+ TLCAN = (FCH/ustar(i)) * (
1722+ & (0.256 * (ZCAN-(0.75*FCH))/FCH ) +
1723+ & (0.492*EXP((-0.256*ZCAN/FCH)/0.492)) )
1724+ IF ( HOL .LT. -0.1 ) THEN !STRONG UNSTABLE
1725+ IF ( ZCAN/FCH .GT. 1.25 ) THEN !SIGMACAN = Eulerian vertical velocity variance
1726+ SIGMACAN = 1.25*ustar(i)
1727+ END IF
1728+ IF ( ZCAN/FCH .GE. 0.175
1729+ & .AND. ZCAN/FCH .LE. 1.25 ) THEN
1730+ SIGMACAN = ustar(i) * ( 0.75 +
1731+ & (0.5 * COS((PI/1.06818) *
1732+ & (1.25 - (ZCAN/FCH)))) )
1733+ END IF
1734+ IF ( ZCAN/FCH .LT. 0.175 ) THEN
1735+ SIGMACAN = 0.25*ustar(i)
1736+ END IF
1737+ END IF
1738+ IF ( HOL .GE. -0.1 .AND. HOL .LT. 0.1 ) THEN !WEAKLY UNSTABLE to NEUTRAL
1739+ IF ( ZCAN/FCH .GT. 1.25 ) THEN
1740+ SIGMACAN = 1.0*ustar(i)
1741+ END IF
1742+ IF ( ZCAN/FCH .GE. 0.175
1743+ & .AND. ZCAN/FCH .LE. 1.25 ) THEN
1744+ SIGMACAN = ustar(i) * ( 0.625 +
1745+ & (0.375* COS((PI/1.06818) *
1746+ & (1.25 - (ZCAN/FCH)))) )
1747+ END IF
1748+ IF ( ZCAN/FCH .LT. 0.175 ) THEN
1749+ SIGMACAN = 0.25*ustar(i)
1750+ END IF
1751+ END IF
1752+ IF ( HOL .GE. 0.1 .AND. HOL .LT. 0.9 ) THEN !STABLE
1753+ IF ( ZCAN/FCH .GT. 1.25 ) THEN
1754+ SIGMACAN = 0.25*(4.375 - (3.75*HOL))*ustar(i)
1755+ END IF
1756+ IF ( ZCAN/FCH .GE. 0.175
1757+ & .AND. ZCAN/FCH .LE. 1.25 ) THEN
1758+ RRCAN=4.375-(3.75*HOL)
1759+ AACAN=(0.125*RRCAN) + 0.125
1760+ BBCAN=(0.125*RRCAN) - 0.125
1761+ SIGMACAN = ustar(i) * ( AACAN +
1762+ & (BBCAN * COS((PI/1.06818) *
1763+ & (1.25 - (ZCAN/FCH)))) )
1764+ END IF
1765+ IF ( ZCAN/FCH .LT. 0.175 ) THEN
1766+ SIGMACAN = 0.25*ustar(i)
1767+ END IF
1768+ END IF
1769+ IF ( HOL .GE. 0.9 ) THEN !VERY STABLE
1770+ SIGMACAN = 0.25*ustar(i)
1771+ END IF
1772+ IF ( ZCAN .EQ. ZFL ) THEN ! Each model layer that includes canopy
1773+ EDDYVEST1 = (SIGMACAN*SIGMACAN)*TLCAN
1774+ ELSE IF ( ZCAN .LE. FCH ) THEN !in-canopy layers and set arrays
1775+ COUNTCAN = COUNTCAN + 1
1776+ ZCANX (COUNTCAN) = ZCAN
1777+ EDDYVESTX (COUNTCAN) = (SIGMACAN*SIGMACAN)*TLCAN
1778+ END IF
1779+ ZCAN = ZCAN-0.5 !step down in-canopy resolution of 0.5m
1780+ END DO !end loop on canopy layers
1781+ EDDYVEST_INT = IntegrateTrapezoid((ZCANX(COUNTCAN:1:-1)
1782+ & ),EDDYVESTX(COUNTCAN:1:-1)) / ZFL
1783+ dkt(i,k)= (dkt(i,k)/EDDYVEST1) * EDDYVEST_INT !Scale dkt to resolved eddy diffusivity
1784+ dkq(i,k)= (dkq(i,k)/EDDYVEST1) * EDDYVEST_INT !Scale dkq to resolved eddy diffusivity
1785+ dku(i,k)= (dku(i,k)/EDDYVEST1) * EDDYVEST_INT !Scale dku to resolved eddy diffusivity
1786+
1787+ !IVAI: Output contiguos canopy correction bottom layer and 3D
1788+ ! if ( kount .EQ. 0)
1789+ ! & aux2d(i,4) = 1./EDDYVEST1 * EDDYVEST_INT
1790+ ! aux3d(i,k,4) = 1./EDDYVEST1 * EDDYVEST_INT
1791+ !IVAI
1792+
1793+ END IF ! contigous canopy conditions
1794+
1795+ END IF ! (KCAN .EQ. 1) model layer(s) containing canopy
1796+
1797+ enddo !i
1798+
1799+ kount = kount + 1 !IVAI
1800+
1801+ enddo !k
1802+
1803+ endif !do_canopy .and. cplaqm
1804+
15771805!> ## Compute TKE.
15781806!! - Compute a minimum TKE deduced from background diffusivity for momentum.
15791807!
@@ -1995,6 +2223,7 @@ subroutine satmedmfvdifq_run(im,km,ntrac,ntcw,ntrw, &
19952223 tkei(i,k) = 0.5 * (tke(i,k)+tke(i,k+1))
19962224 enddo
19972225 enddo
2226+
19982227 do k=1,kps
19992228 do i=1,im
20002229 e_diff(i,k) = tke(i,k) - tke(i,k+1)
0 commit comments