@@ -7,6 +7,9 @@ module satmedmfvdifq
7
7
use mfpbltq_mod
8
8
use tridi_mod
9
9
use mfscuq_mod
10
+ !PCC_CANOPY_utilities
11
+ use canopy_utils_mod
12
+
10
13
contains
11
14
12
15
!> \defgroup module_satmedmfvdifq GFS TKE- EDMF PBL Module
@@ -74,7 +77,7 @@ end subroutine satmedmfvdifq_init
74
77
!! (mfscuq.f).
75
78
!! \section detail_satmedmfvidfq GFS satmedmfvdifq Detailed Algorithm
76
79
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 , &
78
81
!The following three variables are for SA-3D-TKE
79
82
& def_1 ,def_2 ,def_3 ,sa3dtke ,dku3d_h ,dku3d_e , &
80
83
& dv ,du ,tdt ,rtg ,u1 ,v1 ,t1 ,q1 ,usfco ,vsfco ,icplocn2atm , &
@@ -85,9 +88,15 @@ subroutine satmedmfvdifq_run(im,km,ntrac,ntcw,ntrw, &
85
88
& dspheat ,dusfc ,dvsfc ,dtsfc ,dqsfc ,hpbl ,dkt ,dku ,tkeh , &
86
89
& kinver ,xkzm_m ,xkzm_h ,xkzm_s ,dspfac ,bl_upfr ,bl_dnfr , &
87
90
& 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
88
94
& ntqv ,dtend ,dtidx ,index_of_temperature ,index_of_x_wind , &
89
95
& 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
+
91
100
!
92
101
use machine , only : kind_phys
93
102
use funcphys , only : fpvs
@@ -104,11 +113,17 @@ subroutine satmedmfvdifq_run(im,km,ntrac,ntcw,ntrw, &
104
113
integer , intent (out ) :: kpbl(:)
105
114
logical , intent (in ) :: gen_tend,ldiag3d
106
115
!
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, &
108
117
& eps,epsm1
109
118
real (kind= kind_phys), intent (in ) :: delt, xkzm_m, xkzm_h, xkzm_s
110
119
real (kind= kind_phys), intent (in ) :: dspfac, bl_upfr, bl_dnfr
111
120
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
+ !----------------------------------------------
112
127
real (kind= kind_phys), intent (inout ) :: dv(:,:), du(:,:), &
113
128
& tdt(:,:), rtg(:,:,:), tkeh(:,:)
114
129
real (kind= kind_phys), intent (in ) :: &
@@ -289,8 +304,40 @@ subroutine satmedmfvdifq_run(im,km,ntrac,ntcw,ntrw, &
289
304
real (kind= kind_phys) h1
290
305
291
306
real (kind= kind_phys) bfac, mffac
292
-
307
+
293
308
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
+
294
341
!!
295
342
parameter (bfac= 100 .)
296
343
parameter (wfac= 7.0 ,cfac= 4.5 )
@@ -314,7 +361,7 @@ subroutine satmedmfvdifq_run(im,km,ntrac,ntcw,ntrw, &
314
361
parameter (ck1= 0.15 ,ch1= 0.15 )
315
362
parameter (cs0= 0.4 ,csmf= 0.5 )
316
363
parameter (rchck= 1.5 ,ndt= 20 )
317
- !The following variables are for SA-3D - TKE
364
+ !The following variables are for SA-3D - TKE
318
365
parameter (cpl1= 0.280 ,cpl2= 0.870 ,cpl3= 0.913 )
319
366
parameter (cpl4= 0.153 ,cpl5= 0.278 ,cpl6= 0.720 )
320
367
parameter (cpnl1= 0.243 ,cpnl2= 0.936 ,cpnl3= 1.11 )
@@ -325,6 +372,14 @@ subroutine satmedmfvdifq_run(im,km,ntrac,ntcw,ntrw, &
325
372
parameter (inv3= 0.33333333 )
326
373
! parameter (aa1= 0.92 ,aa2= 0.649 ,bb1= 17.7 ,bb2= 9.5 ,cc1= 0.08 )
327
374
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
+ !----------------------------------------------
328
383
if (tc_pbl == 0 ) then
329
384
ck0 = 0.4
330
385
ch0 = 0.4
@@ -1562,7 +1617,6 @@ subroutine satmedmfvdifq_run(im,km,ntrac,ntcw,ntrw, &
1562
1617
endif
1563
1618
enddo
1564
1619
enddo
1565
-
1566
1620
do k = kmscu, 1, -1
1567
1621
do i = 1, im
1568
1622
if(scuflg(i) .and.
@@ -1574,6 +1628,179 @@ subroutine satmedmfvdifq_run(im,km,ntrac,ntcw,ntrw, &
1574
1628
1575
1629
endif !sa3dtke
1576
1630
1631
+ !PCC_CANOPY------------------------------------
1632
+ kount=0 !IVAI
1633
+ if (do_canopy .and. cplaqm) then
1634
+
1635
+ !IVAI
1636
+ ! print*, ' SATMEDMFVDIFQ_RUN: CLAIE = ' , claie(:)
1637
+ ! print*, ' SATMEDMFVDIFQ_RUN: CFCH = ' , cfch (:)
1638
+ ! print*, ' SATMEDMFVDIFQ_RUN: CFRT = ' , cfrt (:)
1639
+ ! print*, ' SATMEDMFVDIFQ_RUN: CCLU = ' , cclu (:)
1640
+ ! print*, ' SATMEDMFVDIFQ_RUN: CPOPU= ' , cpopu(:)
1641
+ ! 2D aux arrays: canopy data in diffusion
1642
+ ! aux2d(:,1) = cfch (:)
1643
+ ! aux2d(:,2) = claie(:)
1644
+ ! aux2d(:,3) = cfrt(:)
1645
+
1646
+ ! 3D aux arrays: before canopy correction
1647
+ ! aux3d(:,:,1) = dkq(:,:)
1648
+ ! aux3d(:,:,2) = dkt(:,:)
1649
+ ! aux3d(:,:,3) = dku(:,:)
1650
+ !IVAI
1651
+ do k = 1, km1-1
1652
+ do i = 1, im
1653
+
1654
+ !IVAI: AQM canopy Inputs
1655
+ ! FCH = fch_table(vegtype(i)) !top of canopy from look-up table
1656
+ FCH = cfch(i) !top of canopy from AQM canopy inputs
1657
+ IF (k .EQ. 1) THEN !use model layer interfaces
1658
+ KCAN = 1
1659
+ ELSE
1660
+ IF ( cfch(i) .GT. zi(i,k)
1661
+ & .AND. cfch(i) .LE. zi(i,k+1) ) THEN
1662
+ KCAN = 1
1663
+ ELSE
1664
+ KCAN = 0
1665
+ END IF
1666
+ END IF
1667
+
1668
+ IF (KCAN .EQ. 1) THEN !canopy inside model layer
1669
+ ! Check for other Contiguous Canopy Grid Cell Conditions
1670
+
1671
+ ! Not a contigous canopy cell
1672
+ IF ( claie(i) .LT. 0.1
1673
+ & .OR. cfch (i) .LT. 0.5
1674
+ !IVAI: modified contiguous canopy condition
1675
+ ! & .OR. MAX(0.0, 1.0 - cfrt(i)) .GT. 0.5
1676
+ & .OR. MAX(0.0, 1.0 - cfrt(i)) .GT. 0.75
1677
+ !IVAI
1678
+ & .OR. cpopu(i) .GT. 10000.0
1679
+ & .OR. (EXP(-0.5*claie(i)*cclu(i)) .GT. 0.45
1680
+ & .AND. cfch(i) .LT. 18.) ) THEN
1681
+
1682
+
1683
+ !TODO: Canopy Inputs
1684
+ ! IF ( XCANOPYLAI .LT. 0.1 !from canopy inputs
1685
+ ! IF ( lai(i) .LT. 0.1 !from LSM
1686
+ ! & .OR. FCH .LT. 0.5 ) THEN
1687
+ ! & .OR. MAX(0.0, 1.0 - XCANOPYFRT) .GT. 0.5
1688
+ ! & .OR. POPU .GT. 10000.0
1689
+ ! & .OR. EXP(-0.5*XCANOPYLAI*XCANOPYCLU).GT. 0.45
1690
+ ! & .AND. FCH .LT. 18.0 ) THEN
1691
+
1692
+ dkt(i,k)= dkt(i,k)
1693
+ dkq(i,k)= dkq(i,k)
1694
+ dku(i,k)= dku(i,k)
1695
+
1696
+ ELSE ! There is a contiguous forest canopy, apply correction over canopy layers
1697
+
1698
+ ! Output contiguous canopy mask
1699
+ ! if (kount .EQ. 0 ) aux2d(i,5) = aux2d(i,5) + 1
1700
+
1701
+ !Raupauch M. R. A Practical Lagrangian method for relating scalar
1702
+ !concentrations to
1703
+ ! source distributions in vegetation canopies. Q. J. R. Meteor. Soc.
1704
+ ! (1989), 115, pp 609-632
1705
+ MOL = zol(i)/zl(i,k) !Monin-Obukhov Length in layer
1706
+ HOL = FCH/MOL !local canopy stability parameter (hc/MOL)
1707
+ ZCAN = zi(i,k+1) ! Initialize each model layer top that contains canopy (m)
1708
+ ! Integrate across total model interface
1709
+ ZFL = ZCAN ! Set ZFL = ZCAN
1710
+ COUNTCAN = 0 ! Initialize canopy layers
1711
+
1712
+ IF (k .EQ. 1) THEN !Find bottom in each model layer
1713
+ BOTCAN = 0.5
1714
+ ELSE
1715
+ BOTCAN = zi(i,k)
1716
+ END IF
1717
+
1718
+ DO WHILE (ZCAN.GE.BOTCAN)
1719
+ ! TLCAN = Lagrangian timescale
1720
+ TLCAN = (FCH/ustar(i)) * (
1721
+ & (0.256 * (ZCAN-(0.75*FCH))/FCH ) +
1722
+ & (0.492*EXP((-0.256*ZCAN/FCH)/0.492)) )
1723
+ IF ( HOL .LT. -0.1 ) THEN !STRONG UNSTABLE
1724
+ IF ( ZCAN/FCH .GT. 1.25 ) THEN !SIGMACAN = Eulerian vertical velocity variance
1725
+ SIGMACAN = 1.25*ustar(i)
1726
+ END IF
1727
+ IF ( ZCAN/FCH .GE. 0.175
1728
+ & .AND. ZCAN/FCH .LE. 1.25 ) THEN
1729
+ SIGMACAN = ustar(i) * ( 0.75 +
1730
+ & (0.5 * COS((PI/1.06818) *
1731
+ & (1.25 - (ZCAN/FCH)))) )
1732
+ END IF
1733
+ IF ( ZCAN/FCH .LT. 0.175 ) THEN
1734
+ SIGMACAN = 0.25*ustar(i)
1735
+ END IF
1736
+ END IF
1737
+ IF ( HOL .GE. -0.1 .AND. HOL .LT. 0.1 ) THEN !WEAKLY UNSTABLE to NEUTRAL
1738
+ IF ( ZCAN/FCH .GT. 1.25 ) THEN
1739
+ SIGMACAN = 1.0*ustar(i)
1740
+ END IF
1741
+ IF ( ZCAN/FCH .GE. 0.175
1742
+ & .AND. ZCAN/FCH .LE. 1.25 ) THEN
1743
+ SIGMACAN = ustar(i) * ( 0.625 +
1744
+ & (0.375* COS((PI/1.06818) *
1745
+ & (1.25 - (ZCAN/FCH)))) )
1746
+ END IF
1747
+ IF ( ZCAN/FCH .LT. 0.175 ) THEN
1748
+ SIGMACAN = 0.25*ustar(i)
1749
+ END IF
1750
+ END IF
1751
+ IF ( HOL .GE. 0.1 .AND. HOL .LT. 0.9 ) THEN !STABLE
1752
+ IF ( ZCAN/FCH .GT. 1.25 ) THEN
1753
+ SIGMACAN = 0.25*(4.375 - (3.75*HOL))*ustar(i)
1754
+ END IF
1755
+ IF ( ZCAN/FCH .GE. 0.175
1756
+ & .AND. ZCAN/FCH .LE. 1.25 ) THEN
1757
+ RRCAN=4.375-(3.75*HOL)
1758
+ AACAN=(0.125*RRCAN) + 0.125
1759
+ BBCAN=(0.125*RRCAN) - 0.125
1760
+ SIGMACAN = ustar(i) * ( AACAN +
1761
+ & (BBCAN * COS((PI/1.06818) *
1762
+ & (1.25 - (ZCAN/FCH)))) )
1763
+ END IF
1764
+ IF ( ZCAN/FCH .LT. 0.175 ) THEN
1765
+ SIGMACAN = 0.25*ustar(i)
1766
+ END IF
1767
+ END IF
1768
+ IF ( HOL .GE. 0.9 ) THEN !VERY STABLE
1769
+ SIGMACAN = 0.25*ustar(i)
1770
+ END IF
1771
+ IF ( ZCAN .EQ. ZFL ) THEN ! Each model layer that includes canopy
1772
+ EDDYVEST1 = (SIGMACAN*SIGMACAN)*TLCAN
1773
+ ELSE IF ( ZCAN .LE. FCH ) THEN !in-canopy layers and set arrays
1774
+ COUNTCAN = COUNTCAN + 1
1775
+ ZCANX (COUNTCAN) = ZCAN
1776
+ EDDYVESTX (COUNTCAN) = (SIGMACAN*SIGMACAN)*TLCAN
1777
+ END IF
1778
+ ZCAN = ZCAN-0.5 !step down in-canopy resolution of 0.5m
1779
+ END DO !end loop on canopy layers
1780
+ EDDYVEST_INT = IntegrateTrapezoid((ZCANX(COUNTCAN:1:-1)
1781
+ & ),EDDYVESTX(COUNTCAN:1:-1)) / ZFL
1782
+ dkt(i,k)= (dkt(i,k)/EDDYVEST1) * EDDYVEST_INT !Scale dkt to resolved eddy diffusivity
1783
+ dkq(i,k)= (dkq(i,k)/EDDYVEST1) * EDDYVEST_INT !Scale dkq to resolved eddy diffusivity
1784
+ dku(i,k)= (dku(i,k)/EDDYVEST1) * EDDYVEST_INT !Scale dku to resolved eddy diffusivity
1785
+
1786
+ !IVAI: Output contiguos canopy correction bottom layer and 3D
1787
+ ! if ( kount .EQ. 0)
1788
+ ! & aux2d(i,4) = 1./EDDYVEST1 * EDDYVEST_INT
1789
+ ! aux3d(i,k,4) = 1./EDDYVEST1 * EDDYVEST_INT
1790
+ !IVAI
1791
+
1792
+ END IF ! contigous canopy conditions
1793
+
1794
+ END IF ! (KCAN .EQ. 1) model layer(s) containing canopy
1795
+
1796
+ enddo !i
1797
+
1798
+ kount = kount + 1 !IVAI
1799
+
1800
+ enddo !k
1801
+
1802
+ endif !do_canopy .and. cplaqm
1803
+
1577
1804
!> ## Compute TKE.
1578
1805
!! - Compute a minimum TKE deduced from background diffusivity for momentum.
1579
1806
!
@@ -1995,6 +2222,7 @@ subroutine satmedmfvdifq_run(im,km,ntrac,ntcw,ntrw, &
1995
2222
tkei(i,k) = 0.5 * (tke(i,k)+tke(i,k+1))
1996
2223
enddo
1997
2224
enddo
2225
+
1998
2226
do k=1,kps
1999
2227
do i=1,im
2000
2228
e_diff(i,k) = tke(i,k) - tke(i,k+1)
0 commit comments