SURFEX  V8_0
Surfex V8_0 release
 All Classes Files Functions Variables
canopy_evol.F90
Go to the documentation of this file.
1 !SFX_LIC Copyright 1994-2014 CNRS, Meteo-France and Universite Paul Sabatier
2 !SFX_LIC This is part of the SURFEX software governed by the CeCILL-C licence
3 !SFX_LIC version 1. See LICENSE, CeCILL-C_V1-en.txt and CeCILL-C_V1-fr.txt
4 !SFX_LIC for details. version 1.
5 ! #########################################
6  SUBROUTINE canopy_evol(KI,KLVL,PTSTEP, KIMPL, &
7  pzz,pwind,pta,pqa,ppa,prhoa, &
8  psflux_u,psflux_t,psflux_q, &
9  pforc_u,pdforc_udu,pforc_e,pdforc_ede,pforc_t,pdforc_tdt, &
10  pforc_q,pdforc_qdq, &
11  pz,pzf,pdz,pdzf,pu,ptke,pt,pq,plmo,plm,pleps,pp,pustar, &
12  palfau,pbetau,palfath,pbetath,palfaq,pbetaq, oneutral )
13 ! #########################################
14 !
15 !!**** *CANOPY_EVOL* - evolution of canopy
16 !!
17 !!
18 !! PURPOSE
19 !! -------
20 !!
21 !!** METHOD
22 !! ------
23 !!
24 !! EXTERNAL
25 !! --------
26 !!
27 !!
28 !! IMPLICIT ARGUMENTS
29 !! ------------------
30 !!
31 !! REFERENCE
32 !! ---------
33 !!
34 !!
35 !! AUTHOR
36 !! ------
37 !! V. Masson *Meteo France*
38 !!
39 !! MODIFICATIONS
40 !! -------------
41 !! Original 07/2006
42 !-------------------------------------------------------------------------------
43 !
44 !* 0. DECLARATIONS
45 ! ------------
46 !
47 USE modd_csts, ONLY : xg, xrd, xcpd, xp00
48 USE modd_surf_par, ONLY : xundef
49 USE modd_canopy_turb, ONLY : xcmfs, xcshf
50 !
51 USE modi_rmc01_surf
52 USE modi_canopy_evol_wind
53 USE modi_canopy_evol_tke
54 USE modi_canopy_evol_temp
55 !
56 USE mode_sbls
57 !
58 USE yomhook ,ONLY : lhook, dr_hook
59 USE parkind1 ,ONLY : jprb
60 !
61 IMPLICIT NONE
62 !
63 !* 0.1 Declarations of arguments
64 ! -------------------------
65 !
66 INTEGER, INTENT(IN) :: ki ! number of horizontal points
67 INTEGER, INTENT(IN) :: klvl ! number of levels in canopy
68 REAL, INTENT(IN) :: ptstep ! atmospheric time-step (s)
69 INTEGER, INTENT(IN) :: kimpl ! implicitation code:
70 ! ! 1 : computes only alfa and beta coupling
71 ! ! coefficients for all variables
72 ! ! 2 : computes temporal evolution of the
73 ! ! variables
74 REAL, DIMENSION(KI,KLVL), INTENT(IN) :: pzz ! Mixing length generic profile at mid levels (-)
75 REAL, DIMENSION(KI), INTENT(IN) :: pwind ! wind speed (m/s)
76 REAL, DIMENSION(KI), INTENT(IN) :: pta ! Air temperature (K)
77 REAL, DIMENSION(KI), INTENT(IN) :: pqa ! Air humidity (kg/m3)
78 REAL, DIMENSION(KI), INTENT(IN) :: ppa ! Pressure at forcing level (Pa)
79 REAL, DIMENSION(KI), INTENT(IN) :: prhoa ! Air density at forcing level (kg/m3)
80 REAL, DIMENSION(KI), INTENT(IN) :: psflux_u ! surface flux u'w' (m2/s2)
81 REAL, DIMENSION(KI), INTENT(IN) :: psflux_t ! surface flux w'T' (Km/s)
82 REAL, DIMENSION(KI), INTENT(IN) :: psflux_q ! surface flux w'q' (kg/m2/s)
83 REAL, DIMENSION(KI,KLVL), INTENT(IN) :: pforc_u ! tendency of wind due to canopy drag (m/s2)
84 REAL, DIMENSION(KI,KLVL), INTENT(IN) :: pdforc_udu! formal derivative of the tendency of
85 ! ! wind due to canopy drag (1/s)
86 REAL, DIMENSION(KI,KLVL), INTENT(IN) :: pforc_e ! tendency of TKE due to canopy drag (m2/s3)
87 REAL, DIMENSION(KI,KLVL), INTENT(IN) :: pdforc_ede! formal derivative of the tendency of
88 ! ! TKE due to canopy drag (1/s)
89 REAL, DIMENSION(KI,KLVL), INTENT(IN) :: pforc_t ! tendency of Temp due to canopy drag (T/s)
90 REAL, DIMENSION(KI,KLVL), INTENT(IN) :: pdforc_tdt! formal derivative of the tendency of
91 ! ! Temp due to canopy drag (1/s)
92 REAL, DIMENSION(KI,KLVL), INTENT(IN) :: pforc_q ! tendency of Hum. due to canopy drag (kg/m3/s)
93 REAL, DIMENSION(KI,KLVL), INTENT(IN) :: pdforc_qdq! formal derivative of the tendency of
94 ! ! Hum. due to canopy drag (1/s)
95 !
96 REAL, DIMENSION(KI,KLVL), INTENT(IN) :: pz ! heights of canopy levels (m)
97 REAL, DIMENSION(KI,KLVL), INTENT(IN) :: pzf ! heights of bottom of canopy levels (m)
98 REAL, DIMENSION(KI,KLVL), INTENT(IN) :: pdz ! depth of canopy levels (m)
99 REAL, DIMENSION(KI,KLVL), INTENT(IN) :: pdzf ! depth between canopy levels (m)
100 REAL, DIMENSION(KI,KLVL), INTENT(INOUT) :: pu ! wind speed at canopy levels (m/s)
101 REAL, DIMENSION(KI,KLVL), INTENT(INOUT) :: ptke ! TKE at canopy levels (m2/s2)
102 REAL, DIMENSION(KI,KLVL), INTENT(INOUT) :: pt ! Temperature at canopy levels (K)
103 REAL, DIMENSION(KI,KLVL), INTENT(INOUT) :: pq ! Humidity at canopy levels (kg/m3)
104 REAL, DIMENSION(KI,KLVL), INTENT(INOUT) :: plmo ! Monin-Obhukov length (m)
105 REAL, DIMENSION(KI,KLVL), INTENT(OUT) :: plm ! mixing length (m)
106 REAL, DIMENSION(KI,KLVL), INTENT(OUT) :: pleps ! dissipative length (m)
107 REAL, DIMENSION(KI,KLVL), INTENT(INOUT) :: pp ! Pressure at canopy levels (Pa)
108 REAL, DIMENSION(KI), INTENT(OUT) :: pustar ! friction velocity at forcing level (m/s)
109 !
110 REAL, DIMENSION(KI), INTENT(OUT) :: palfau ! V+(1) = alfa u'w'(1) + beta
111 REAL, DIMENSION(KI), INTENT(OUT) :: pbetau ! V+(1) = alfa u'w'(1) + beta
112 REAL, DIMENSION(KI), INTENT(OUT) :: palfath ! Th+(1) = alfa w'th'(1) + beta
113 REAL, DIMENSION(KI), INTENT(OUT) :: pbetath ! Th+(1) = alfa w'th'(1) + beta
114 REAL, DIMENSION(KI), INTENT(OUT) :: palfaq ! Q+(1) = alfa w'q'(1) + beta
115 REAL, DIMENSION(KI), INTENT(OUT) :: pbetaq ! Q+(1) = alfa w'q'(1) + beta
116 !
117 LOGICAL, OPTIONAL, INTENT(IN) :: oneutral
118 !
119 !* 0.2 Declarations of local variables
120 ! -------------------------------
121 !
122 LOGICAL :: gneutral
123 !
124 INTEGER :: jlayer ! loop counter on layers
125 INTEGER :: ji ! loop counter
126 !
127 REAL, DIMENSION(KI,KLVL) :: zk ! mixing coefficient
128 REAL, DIMENSION(KI,KLVL) :: zdkddvdz ! formal derivative of mixing coefficient according to variable vertical gradient
129 REAL, DIMENSION(KI,KLVL) :: zth ! potential temperature at full levels
130 REAL, DIMENSION(KI) :: ztha ! potential temperature at forcing level
131 REAL, DIMENSION(KI,KLVL) :: zexn ! Exner function at full levels
132 REAL, DIMENSION(KI,KLVL) :: zuw ! friction at mid levels
133 REAL, DIMENSION(KI) :: zsflux_th ! Surface flux w'Th' (mK/s)
134 REAL, DIMENSION(KI,KLVL) :: zforc_th ! tendency of Temp due to canopy drag (T/s)
135 REAL, DIMENSION(KI,KLVL) :: zdforc_thdth ! formal derivative of the tendency of
136 ! ! Temp due to canopy drag (1/s)
137 REAL, DIMENSION(KI,KLVL) :: zwth ! w'Th' at mid levels
138 REAL, DIMENSION(KI,KLVL) :: zwq ! w'q' at mid levels
139 REAL, DIMENSION(KI,KLVL) :: zsfth ! heat flux at atmospheric forcing level
140 REAL, DIMENSION(KI,KLVL) :: zsfrv ! vapor flux at atmospheric forcing level
141 REAL :: zz0 ! a value of z0 just for first time-step init.
142 REAL, DIMENSION(KI,KLVL) :: zrhoa ! air density profile
143 REAL(KIND=JPRB) :: zhook_handle
144 !-------------------------------------------------------------------------------
145 IF (lhook) CALL dr_hook('CANOPY_EVOL',0,zhook_handle)
146 !
147 gneutral = .false.
148 !
149 IF (present(oneutral)) gneutral = oneutral
150 !
151 !* 1. First time step initialization
152 ! ------------------------------
153 !
154 !* first time step (i.e. wind profile is initially zero) :
155 ! set a neutral wind profile in relation with forcing wind
156 DO ji=1,ki
157  IF(pwind(ji)>0. .AND. pu(ji,klvl-1)==0.) THEN
158  zz0 = pz(ji,1)/2.
159  pu(ji,:) = pwind(ji) * log(pz(ji,:)/zz0) / log(pz(ji,klvl)/zz0)
160  END IF
161 END DO
162 !-------------------------------------------------------------------------------
163 !
164 !* 5. mixing and dissipative lengths (at full levels)
165 ! ------------------------------
166 !
167  CALL rmc01_surf(pzz,plmo,plm,pleps,gneutral)
168 !
169 !-------------------------------------------------------------------------------
170 !
171 !* 6. time evolution of wind in canopy
172 ! --------------------------------
173 !
174 !* 6.1 mixing coefficient for wind at mid layers (at half levels)
175 ! ---------------------------
176 !
177 zk = -999.
178 DO jlayer=2,klvl
179  zk(:,jlayer) = 0.5 * xcmfs * plm(:,jlayer) * sqrt(ptke(:,jlayer) ) &
180  + 0.5 * xcmfs * plm(:,jlayer-1) * sqrt(ptke(:,jlayer-1))
181 END DO
182 !
183 !
184 !* 6.2 mixing coefficient vertical derivative at mid layers (at half levels)
185 ! --------------------------------------
186 !
187 !* there is no formal dependency on wind
188 zdkddvdz = 0.
189 !
190 !
191 !* 6.3 time evolution of wind in canopy
192 ! --------------------------------
193 !
194  CALL canopy_evol_wind(ki,klvl,ptstep,kimpl,pwind,zk,zdkddvdz,psflux_u,pforc_u,pdforc_udu,pdz,pdzf,pu,zuw,palfau,pbetau)
195 !
196 !* 6.4 Friction velocity at top of SBL layers
197 ! --------------------------------------
198 !
199 pustar = sqrt(abs(zuw(:,klvl)))
200 !
201 !-------------------------------------------------------------------------------
202 !
203 IF (gneutral) THEN
204  !
205  zth = 300.
206  zwth = 0.
207  zwq = 0.
208  !
209 ELSE
210  !
211  !* 7. time evolution of temperature in canopy
212  ! ---------------------------------------
213  !
214  !* 7.3 convertion into potential temperature (at half levels)
215  ! -------------------------------------
216  !
217  DO jlayer=1,klvl
218  pp(:,jlayer) = ppa(:) + xg * prhoa(:) * (pz(:,klvl) - pz(:,jlayer))
219  END DO
220  zexn = (pp/xp00)**(xrd/xcpd)
221  !
222  zth = xundef
223  WHERE(pt/=xundef) zth(:,:) = pt(:,:) / zexn(:,:)
224  !
225  ztha(:) = pta(:) / zexn(:,klvl)
226  !
227  !* 7.1 mixing coefficient for wind at mid layers (at half levels)
228  ! ---------------------------
229  !
230  zk = -999.
231  DO jlayer=2,klvl
232  zk(:,jlayer) = 0.5 * xcshf * plm(:,jlayer) * sqrt(ptke(:,jlayer) ) &
233  + 0.5 * xcshf * plm(:,jlayer-1) * sqrt(ptke(:,jlayer-1))
234  END DO
235  !
236  !* 7.2 mixing coefficient vertical derivative at mid layers (at half levels)
237  ! --------------------------------------
238  !
239  !* there is no formal dependency on temperature
240  zdkddvdz = 0.
241  !
242  !* 7.4 conversion of canopy tendency into potential temperature tendency
243  ! -----------------------------------------------------------------
244  !
245  zsflux_th = psflux_t / zexn(:,1)
246  zforc_th = pforc_t / zexn
247  zdforc_thdth = pdforc_tdt
248  !
249  !
250  !* 7.5 time evolution of temperature in canopy
251  ! ---------------------------------------
252  !
253  CALL canopy_evol_temp(ki,klvl,ptstep,kimpl,ztha,zk,zdkddvdz,zsflux_th,zforc_th,zdforc_thdth,pdz,pdzf,zth,zwth,palfath,pbetath)
254  !
255  !* 7.6 convertion into absolute temperature
256  ! ------------------------------------
257  !
258  WHERE(pt/=xundef) pt(:,:) = zth(:,:) * zexn(:,:)
259  !
260  !-------------------------------------------------------------------------------
261  !
262  !* 8. time evolution of Humidity in canopy
263  ! ------------------------------------
264  !
265  CALL canopy_evol_temp(ki,klvl,ptstep,kimpl,pqa,zk,zdkddvdz,psflux_q,pforc_q,pdforc_qdq,pdz,pdzf,pq,zwq,palfaq,pbetaq)
266  !
267  !-------------------------------------------------------------------------------
268  IF (kimpl==1 .AND. lhook) CALL dr_hook('CANOPY_EVOL',1,zhook_handle)
269  IF (kimpl==1) RETURN
270  !-------------------------------------------------------------------------------
271  !
272 ENDIF
273 !
274 !* 9. time evolution of TKE in canopy
275 ! -------------------------------
276 !
277  CALL canopy_evol_tke(ki,klvl,ptstep,prhoa,pz,pzf,pdz,pdzf,pforc_e,pdforc_ede, &
278  pu,zth,zuw,zwth,zwq,pleps,ptke )
279 !
280 !-------------------------------------------------------------------------------
281 !
282 IF (.NOT.gneutral) THEN
283  !
284  !* 10. Monin-Obuhkov length
285  ! --------------------
286  !
287  !* MO length is estimated using the heat and vapor turbulent fluxes at atmospheric level
288  ! (it avoids the problems of vertical variation of the fluxes in the canopy)
289  ! However, friction flux MUST be taken as the maximum flux on the
290  ! profile, in order to avoid unrealistically small MO length when using
291  ! small time-steps
292  !
293  zrhoa(:,:) = spread(prhoa(:),2,klvl)
294  !
295  zsfth(:,:) = zwth(:,:)
296  zsfrv(:,:) = zwq(:,:) / zrhoa(:,:)
297  !
298  plmo(:,:) = lmo(sqrt(abs(zuw)),pt,pq,zsfth,zsfrv)
299  !
300  DO jlayer=1,klvl
301  WHERE (plmo(:,jlayer)>0.) plmo(:,jlayer) = max(plmo(:,jlayer),pz(:,klvl))
302  WHERE (plmo(:,jlayer)<0.) plmo(:,jlayer) = min(plmo(:,jlayer),-pz(:,klvl))
303  ENDDO
304  !
305  !-------------------------------------------------------------------------------
306  !
307  !* 11. Security at atmospheric forcing level
308  ! -------------------------------------
309  !
310  pt(:,klvl) = pta(:)
311  !
312  pq(:,klvl) = pqa(:)
313  !
314 ENDIF
315 !
316 pu(:,klvl) = pwind(:)
317 !
318 IF (lhook) CALL dr_hook('CANOPY_EVOL',1,zhook_handle)
319 !
320 !-------------------------------------------------------------------------------
321 END SUBROUTINE canopy_evol
322 
subroutine canopy_evol_tke(KI, KLVL, PTSTEP, PRHOA, PZ, PZF, PDZ, PDZF, PFORC_E, PDFORC_EDE, PU, PTH, PUW, PWTH, PWQ, PLEPS, PTKE)
subroutine canopy_evol_wind(KI, KLVL, PTSTEP, KIMPL, PWIND, PK, PDKDDVDZ, PSFLUX_U, PFORC_U, PDFORC_UDU, PDZ, PDZF, PU, PUW, PALFA, PBETA)
subroutine rmc01_surf(PZ, PLMO, PLK, PLEPS, ONEUTRAL)
Definition: rmc01_surf.F90:6
subroutine canopy_evol_temp(KI, KLVL, PTSTEP, KIMPL, PTHA, PK, PDKDDVDZ, PSFLUX_T, PFORC_T, PDFORC_TDT, PDZ, PDZF, PTH, PWTH, PALFA, PBETA)
subroutine canopy_evol(KI, KLVL, PTSTEP, KIMPL, PZZ, PWIND, PTA, PQA, PPA, PRHOA, PSFLUX_U, PSFLUX_T, PSFLUX_Q, PFORC_U, PDFORC_UDU, PFORC_E, PDFORC_EDE, PFORC_T, PDFORC_TDT, PFORC_Q, PDFORC_QDQ, PZ, PZF, PDZ, PDZF, PU, PTKE, PT, PQ, PLMO, PLM, PLEPS, PP, PUSTAR, PALFAU, PBETAU, PALFATH, PBETATH, PALFAQ, PBETAQ, ONEUTRAL)
Definition: canopy_evol.F90:6