SURFEX  V8_0
Surfex V8_0 release
 All Classes Files Functions Variables
drag.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 drag(HISBA, HSNOW_ISBA, HCPSURF, PTSTEP, &
7  ptg, pwg, pwgi, &
8  pexns, pexna, pta, pvmod, pqa, prr, psr, &
9  pps, prs, pveg, pz0, pz0eff, pz0h, &
10  pwfc, pwsat, ppsng, ppsnv, pzref, puref, &
11  pdircoszw, pdelta, pf5, pra, &
12  pch, pcd, pcdn, pri, phug, phugi, &
13  phv, phu, pcps, pqs, pffg, pffv, pff, &
14  pffg_nosnow, pffv_nosnow, &
15  pleg_delta, plegi_delta, pwr, prhoa, plvtt, pqsat )
16 ! ############################################################################
17 !
18 !!**** *DRAG*
19 !!
20 !! PURPOSE
21 !! -------
22 !
23 ! Calculates the drag coefficients for heat and momentum transfers
24 ! over ground (i.e., Ch and Cd).
25 !
26 !
27 !!** METHOD
28 !! ------
29 !
30 ! 1) computes hu, hv, and delta
31 !
32 ! 2) use this to find qsoil, the grid-averaged relative humidity
33 ! of the soil
34 !
35 ! 3) calculates the Richardson's number
36 !
37 ! 4) find the transfer and resistance coefficients Ch, Cd, and Ra
38 !
39 !! EXTERNAL
40 !! --------
41 !!
42 !! IMPLICIT ARGUMENTS
43 !! ------------------
44 !!
45 !! USE MODD_CST
46 !!
47 !!
48 !! REFERENCE
49 !! ---------
50 !!
51 !! Mascart et al. (1995)
52 !! Belair (1995)
53 !!
54 !! AUTHOR
55 !! ------
56 !!
57 !! S. Belair * Meteo-France *
58 !!
59 !! MODIFICATIONS
60 !! -------------
61 !! Original 13/03/95
62 !! (J.Stein) 15/11/95 use the potential temperature to compute Ri
63 !! and PVMOD instead of ZVMOD
64 !! (P.Lacarrere)15/03/96 replace * PEXNS by / PEXNS
65 !! (V.Masson) 22/12/97 computation of z0eff after snow treatment
66 !! (V.Masson) 05/10/98 clear routine
67 !! (A.Boone) 11/26/98 Option for PDELTA: forested vs default surface
68 !! (V.Masson) 01/03/03 Puts PDELTA in another routine
69 !! (P.LeMoigne) 28/07/05 dependance on qs for cp
70 !! (P.LeMoigne) 09/02/06 z0h and snow
71 !! (P.LeMoigne) 09/01/08 limitation of Ri
72 !! (B.Decharme) 01/05/08 optional limitation of Ri
73 !! (B.Decharme) 03/06/08 flooding scheme
74 !! (A.Boone) 03/15/10 Add delta fnctions to force LEG ans LEGI=0
75 !! when hug(i)Qsat < Qa and Qsat > Qa
76 !! (A.Boone) 21/11/11 Add Rs_max limit for dry conditions with Etv
77 !! (B. Decharme) 09/12 limitation of Ri in surface_ri.F90
78 !! (C. Ardilouze) 09/13 Halstead coef set to 0 for very low values
79 !! (B. Decharme) 03/16 Bug in limitation of Er for Interception reservoir
80 !-------------------------------------------------------------------------------
81 !
82 !* 0. DECLARATIONS
83 ! ------------
84 !
85 USE modd_csts, ONLY : xpi, xcpd, xcpv
86 USE modd_isba_par, ONLY : xwgmin, xrs_max
87 USE modd_surf_atm, ONLY : ldrag_coef_arp, lrrgust_arp, xrrscale, &
88  xrrgamma, xutilgust, lcpl_arp
89 !
90 USE modi_surface_ri
91 USE modi_surface_aero_cond
92 USE modi_surface_cd
93 USE modi_surface_cdch_1darp
94 USE modi_wind_threshold
95 !
96 USE mode_thermos
97 !
98 !
99 USE yomhook ,ONLY : lhook, dr_hook
100 USE parkind1 ,ONLY : jprb
101 !
102 IMPLICIT NONE
103 !
104 !* 0.1 declarations of arguments
105 !
106 !
107  CHARACTER(LEN=*), INTENT(IN) :: hisba ! type of ISBA version:
108 ! ! '2-L' (default)
109 ! ! '3-L'
110 ! ! 'DIF'
111  CHARACTER(LEN=*), INTENT(IN) :: hsnow_isba ! 'DEF' = Default F-R snow scheme
112 ! ! (Douville et al. 1995)
113 ! ! '3-L' = 3-L snow scheme (option)
114 ! ! (Boone and Etchevers 2000)
115  CHARACTER(LEN=*), INTENT(IN) :: hcpsurf ! option for specific heat Cp:
116 ! ! 'DRY' = dry Cp
117 ! ! 'HUM' = Cp as a function of qs
118 !
119 REAL, INTENT(IN) :: ptstep ! timestep of ISBA (not split time step)
120 !
121 REAL, DIMENSION(:), INTENT(IN) :: ptg, pwg, pwgi, pexns
122 ! PTG = surface temperature
123 ! PWG = near-surface volumetric water content
124 ! PWGI = near-surface frozen volumetric water content
125 ! PEXNS = Exner function at the surface
126 !
127 REAL, DIMENSION(:), INTENT(IN) :: pexna, pta, pvmod, pqa, prr, psr, pps
128 ! PEXNA= Exner function
129 ! near surface atmospheric variables
130 ! PTA = 2m temperature
131 ! PVMOD = module of the horizontal wind
132 ! NOTE it should be input as >= 1. (m)
133 ! PQA = specific humidity
134 ! PPS = surface pressure
135 ! PRR = rain rate
136 ! PSR = snow rate
137 !
138 REAL, DIMENSION(:), INTENT(IN) :: prs, pveg, pz0, pz0h, pz0eff
139 REAL, DIMENSION(:), INTENT(IN) :: pwfc, pwsat, ppsng, ppsnv, pzref, puref
140 ! PRS = stomatal resistance
141 ! PVEG = vegetation fraction
142 ! PZ0 = roughness length for momentum
143 ! PZ0H = roughness length for heat
144 ! PZ0EFF= effective roughness length
145 ! PWFC = field capacity volumetric water content
146 ! PWSAT = volumetric water content at saturation
147 ! PPSNG = fraction of the bare ground covered
148 ! by snow
149 ! PPSNV = fraction of the vegetation covered
150 ! by snow
151 ! PZREF = reference height of the first
152 ! atmospheric level
153 ! PUREF = reference height of the wind
154 ! NOTE this is different from ZZREF
155 ! ONLY in stand-alone/forced mode,
156 ! NOT when coupled to a model (MesoNH)
157 !
158 REAL, DIMENSION(:), INTENT(INOUT) :: pdelta
159 ! PDELTA = fraction of the foliage covered
160 ! by intercepted water
161 REAL, DIMENSION(:), INTENT(IN) :: pf5
162 ! PF5 = water stress function for Hv
163 REAL, DIMENSION(:), INTENT(IN) :: pdircoszw
164 ! Cosinus of the angle between the normal to the surface and the vertical
165 REAL, DIMENSION(:), INTENT(INOUT) :: pra
166 ! aerodynamic surface resistance
167 REAL, DIMENSION(:), INTENT(INOUT) :: pcps
168 ! specific heat at surface
169 !
170 REAL, DIMENSION(:), INTENT(OUT) :: pch, pcd, pcdn, pri
171 ! PCH = drag coefficient for heat
172 ! PCD = drag coefficient for momentum
173 ! PCDN= neutral drag coefficient for momentum
174 ! PRI = Richardson number
175 !
176 REAL, DIMENSION(:), INTENT(OUT) :: phug, phugi, phv, phu, pqs, pleg_delta, plegi_delta
177 ! PHUG = ground relative humidity
178 ! PHUGI = ground (ice) relative humidity
179 ! PHV = Halstead coefficient
180 ! PHU = relative humidity at the surface
181 ! PQS = humidity at surface
182 ! PLEG_DELTA = soil evaporation delta fn
183 ! PLEGI_DELTA = soil sublimation delta fn
184 !
185 REAL, DIMENSION(:), INTENT(IN) :: pffv, pff, pffg, pffg_nosnow, pffv_nosnow
186 ! PFFG = Floodplain fraction over ground
187 ! PFFV = Floodplain fraction over vegetation
188 ! PFF = Floodplain fraction at the surface
189 !
190 REAL, DIMENSION(:), INTENT(IN) :: pwr, prhoa, plvtt
191 ! PWR = liquid water retained on the foliage
192 ! PRHOA = near-ground air density
193 ! PLVTT = Vaporization heat
194 !
195 REAL, DIMENSION(:), INTENT(OUT), OPTIONAL :: pqsat
196 ! PQSAT = specific humidity at saturation
197 !
198 !* 0.2 declarations of local variables
199 !
200 REAL, PARAMETER :: zhvlim = 1.e-12 ! set halstead coef to 0 at this limit
201 !
202 REAL, DIMENSION(SIZE(PTG)) :: zqsat, &
203 ! ZQSAT = specific humidity at saturation
204  zac, &
205 ! ZAC = aerodynamical conductance
206  zwfc, &
207 ! ZWFC = field capacity in presence of ice
208  zvmod, &
209 ! ZVMOD = wind modulus with minimum threshold
210  zfp, &
211 ! ZFP = working variable
212  zzhv, &
213 ! ZZHV = condensation delta fn for Hv
214  zrrcor
215 ! ZRRCOR = correction of CD, CH, CDN due to moist-gustiness
216 !
217 REAL(KIND=JPRB) :: zhook_handle
218 !-------------------------------------------------------------------------------
219 !
220 !* 0. Initialization:
221 ! ---------------
222 !
223 IF (lhook) CALL dr_hook('DRAG',0,zhook_handle)
224 pch(:) =0.
225 pcd(:) =0.
226 phug(:) =0.
227 phugi(:) =0.
228 phv(:) =0.
229 phu(:) =0.
230 !
231 zqsat(:) =0.
232 zwfc(:) =0.
233 pri(:) =0.
234 !
235 zvmod = wind_threshold(pvmod,puref)
236 !
237 zqsat(:) = qsat(ptg(:),pps(:))
238 !
239 IF(present(pqsat))pqsat(:)=zqsat(:)
240 !
241 !-------------------------------------------------------------------------------
242 !
243 !* 1. RELATIVE HUMIDITY OF THE GROUND HU
244 ! ----------------------------------
245 !
246 ! this relative humidity is related to
247 ! the superficial soil moisture and the
248 ! field capacity of the ground
249 !
250 !
251 zwfc(:) = pwfc(:)*(pwsat(:)-pwgi(:))/pwsat(:)
252 !
253 phug(:) = 0.5 * ( 1.-cos(xpi*min((pwg(:)-xwgmin) /zwfc(:),1.)) )
254 
255 zwfc(:) = pwfc(:)*max(xwgmin, pwsat(:)-pwg(:))/pwsat(:)
256 !
257 phugi(:) = 0.5 * ( 1.-cos(xpi*min(pwgi(:)/zwfc(:),1.)) )
258 !
259 !
260 ! there is a specific treatment for dew
261 ! (see Mahfouf and Noilhan, jam, 1991)
262 ! when hu*qsat < qa, there are two
263 ! possibilities
264 !
265 ! a) low-level air is dry, i.e.,
266 ! qa < qsat
267 !
268 ! NOTE the additional delta fn's
269 ! here are needed owing to linearization
270 ! of Qsat in the surface energy budget.
271 !
272 pleg_delta(:) = 1.0
273 plegi_delta(:) = 1.0
274 WHERE ( phug*zqsat < pqa .AND. zqsat > pqa )
275  phug(:) = pqa(:) / zqsat(:)
276  pleg_delta(:) = 0.0
277 END WHERE
278 WHERE ( phugi*zqsat < pqa .AND. zqsat > pqa )
279  phugi(:) = pqa(:) / zqsat(:)
280  plegi_delta(:) = 0.0
281 END WHERE
282 !
283 ! b) low-level air is humid, i.e.,
284 ! qa >= qsat
285 !
286 WHERE ( phug*zqsat < pqa .AND. zqsat <= pqa )
287  phug(:) = 1.0
288 END WHERE
289 WHERE ( phugi*zqsat < pqa .AND. zqsat <= pqa )
290  phugi(:) = 1.0
291 END WHERE
292 !
293 !-------------------------------------------------------------------------------
294 !
295 !* 3. HALSTEAD COEFFICIENT (RELATIVE HUMIDITY OF THE VEGETATION)
296 ! ----------------------------------------------------------
297 !
298 zzhv(:) = max(0.,sign(1.,zqsat(:)-pqa(:))) ! condensation on foilage if = 1
299 !
300 phv(:) = pdelta(:) + (1.- pdelta(:))* &
301  ( pra(:) + prs(:)*(1.0 - zzhv(:)) )* &
302  ( (1/(pra(:)+prs(:))) - (zzhv(:)*(1.-pf5(:))/(pra(:)+xrs_max)) )
303 !
304 WHERE(phv(:)<zhvlim)
305  phv(:)=0.0
306 ENDWHERE
307 !
308 !-------------------------------------------------------------------------------
309 !
310 !* 4. GRID-AVERAGED HUMIDITY OF THE SURFACE
311 ! -------------------------------------
312 !
313 IF(hsnow_isba == '3-L' .OR. hsnow_isba == 'CRO' .OR. hisba == 'DIF')THEN
314 !
315 ! For explicit snow, humidity HERE only over snow-free region:
316 !
317  pqs(:) =( (1.-pveg(:))*(1.-pffg_nosnow(:))*(pwg(:) /(pwg(:)+pwgi(:)))*phug(:) &
318  + (1.-pveg(:))*(1.-pffg_nosnow(:))*(pwgi(:)/(pwg(:)+pwgi(:)))*phugi(:) &
319  + pveg(:) *(1.-pffv_nosnow(:))* phv(:) &
320  + ((1.-pveg(:))*pffg_nosnow(:)+pveg(:)*pffv_nosnow(:)))*zqsat(:) &
321  + pveg(:) *(1.-pffv_nosnow(:))*(1.-phv(:))*pqa(:)
322 !
323 ELSE
324 !
325  pqs(:) =( (1.-pveg(:))*(1.-ppsng(:)-pffg(:))*(pwg(:) /(pwg(:)+pwgi(:)))*phug(:) &
326  + (1.-pveg(:))*(1.-ppsng(:)-pffg(:))*(pwgi(:)/(pwg(:)+pwgi(:)))*phugi(:) &
327  + (1.-pveg(:))* ppsng(:) &
328  + pveg(:) *(1.-ppsnv(:)-pffv(:))*phv(:) &
329  + pveg(:) * ppsnv(:) &
330  + pff(:) )*zqsat(:) &
331  + pveg(:) *(1.-ppsnv(:)-pffv(:))*(1.-phv(:))*pqa(:)
332 !
333 ENDIF
334 !
335 phu(:) = pqs(:)/zqsat(:)
336 !
337 !-------------------------------------------------------------------------------
338 !
339 !* 5. SPECIFIC HEAT OF THE SURFACE
340 ! ----------------------------
341 !
342 IF (hcpsurf=='DRY') THEN
343  pcps(:) = xcpd
344 ELSEIF(.NOT.lcpl_arp)THEN
345  pcps(:) = xcpd + ( xcpv - xcpd ) * pqa(:)
346 ENDIF
347 !
348 !-------------------------------------------------------------------------------
349 !
350 !* 6. COMPUTATION OF RESISTANCE AND DRAG COEFFICIENT
351 ! ----------------------------------------------
352 !
353  CALL surface_ri(ptg, pqs, pexns, pexna, pta, pqa, &
354  pzref, puref, pdircoszw, pvmod, pri )
355 !
356 !-------------------------------------------------------------------------------
357 !
358 !* 6.5 LIMITATION OF RICHARDSON NUMBER
359 ! -------------------------------
360 !
361 !Now done directly in SURFACE_RI subroutine
362 !
363 !-------------------------------------------------------------------------------
364 !* 7.0 DRAG COEFFICIENT FOR HEAT AND MOMENTUM TRANSFERS
365 ! -------------------------------------------------
366 !
367 IF (ldrag_coef_arp) THEN
368 
369  CALL surface_cdch_1darp(pzref, pz0eff, pz0h, zvmod, pta, ptg, &
370  pqa, pqs, pcd, pcdn, pch )
371  pra(:) = 1. / ( pch(:) * zvmod(:) )
372 
373 ELSE
374 
375 !
376 !* 7.1 SURFACE AERODYNAMIC RESISTANCE FOR HEAT TRANSFERS
377 ! -------------------------------------------------
378 !
379  CALL surface_aero_cond(pri, pzref, puref, zvmod, pz0, pz0h, zac, pra, pch)
380 !
381 !-------------------------------------------------------------------------------
382 !
383 !* 7.2 DRAG COEFFICIENT FOR MOMENTUM TRANSFERS
384 ! ---------------------------------------
385 !
386 !
387  CALL surface_cd(pri, pzref, puref, pz0eff, pz0h, pcd, pcdn)
388 !
389 ENDIF
390 !
391 !-------------------------------------------------------------------------------
392 !
393 !* 8. CORRECTION DUE TO MOIST GUSTINESS
394 ! ---------------------------------
395 !
396 IF (lrrgust_arp) THEN
397 
398  zfp(:)=max(0.0,prr(:)+psr(:))
399  zrrcor(:)=sqrt(1.0+((((zfp(:)/(zfp(:)+xrrscale))**xrrgamma)*xutilgust)**2) &
400  /(pcd(:)*zvmod(:)**2))
401 
402  pcd = pcd * zrrcor
403  pch = pch * zrrcor
404  pcdn = pcdn * zrrcor
405 
406 ENDIF
407 !
408 !-------------------------------------------------------------------------------
409 !
410 !
411 !* 9. HALSTEAD COEFFICIENT (WITH THE NEW VALUES OF PRA)
412 ! ----------------------------------------------------------
413 !
414 !
415 phv(:) = pdelta(:) + (1.- pdelta(:))* &
416  ( pra(:) + prs(:)*(1.0 - zzhv(:)) )* &
417  ( (1/(pra(:)+prs(:))) - (zzhv(:)*(1.-pf5(:))/(pra(:)+xrs_max)) )
418 !
419  CALL limit_ler(pdelta)
420 !
421 WHERE(phv(:)<zhvlim)
422  phv(:)=0.0
423 ENDWHERE
424 !
425 IF (lhook) CALL dr_hook('DRAG',1,zhook_handle)
426 !
427 !-------------------------------------------------------------------------------
428 !
429  CONTAINS
430 !
431 !-------------------------------------------------------------------------------
432 !
433 SUBROUTINE limit_ler(PDELTA)
434 !
435 IMPLICIT NONE
436 !
437 !* 0.1 declarations of arguments
438 !
439 REAL, DIMENSION(:), INTENT(INOUT) :: pdelta
440 !
441 !
442 !* 0.2 declarations of local variables
443 !
444 REAL, DIMENSION(SIZE(PDELTA)) :: zpsnv
445 REAL, DIMENSION(SIZE(PDELTA)) :: zlev
446 REAL, DIMENSION(SIZE(PDELTA)) :: zletr
447 REAL, DIMENSION(SIZE(PDELTA)) :: zlecoef
448 REAL, DIMENSION(SIZE(PDELTA)) :: zer
449 REAL, DIMENSION(SIZE(PDELTA)) :: zrrveg
450 REAL, DIMENSION(SIZE(PDELTA)) :: zwr_delta
451 !
452 REAL(KIND=JPRB) :: zhook_handle
453 !
454 IF (lhook) CALL dr_hook('DRAG:LIMIT_LER',0,zhook_handle)
455 !
456 !-------------------------------------------------------------------------------
457 !
458 !* 1. Initialization:
459 ! ---------------
460 !
461 IF(hsnow_isba == '3-L' .OR. hsnow_isba == 'CRO' .OR. hisba == 'DIF')THEN
462  zlecoef(:) = (1.0-ppsnv(:)-pffv(:))
463  zpsnv(:) = 0.0
464 ELSE
465  zlecoef(:) = 1.0
466  zpsnv(:) = ppsnv(:)+pffv(:)
467 ENDIF
468 !
469 !
470 !* 2. Interception reservoir consistency:
471 ! -----------------------------------
472 !
473 ! In DRAG, we use the timestep of ISBA (PTSTEP) and not the split time step (ZTSTEP)
474 ! because diagnostic canopy evaporation (Er) must be consistent with PWR to
475 ! limit negative dripping in hydro_veg
476 
477 !
478 zlev(:) = prhoa(:) * plvtt(:) * pveg(:) * (1-zpsnv(:)) * phv(:) * (zqsat(:) - pqa(:)) / pra(:)
479 !
480 zletr(:) = zzhv(:) * prhoa(:) * (1. - pdelta(:)) * plvtt(:) * pveg(:) *(1-zpsnv(:)) &
481  * (zqsat(:) - pqa(:)) * ( (1/(pra(:) + prs(:))) - ((1.-pf5(:))/(pra(:) + xrs_max)) )
482 !
483 zer(:)=ptstep*(zlev(:)-zletr(:))*zlecoef(:)/plvtt(:)
484 !
485 zrrveg(:) = ptstep*pveg(:)*(1.-ppsnv(:))*prr(:)
486 !
487 zwr_delta(:)=1.0
488 !
489 WHERE( zzhv(:)>0.0 .AND. zer(:)/=0.0 .AND. (pwr(:)+zrrveg(:))<zer(:) )
490 !
491  zwr_delta(:) = max(0.01,min(1.0,(pwr(:)+zrrveg(:))/zer(:)))
492 !
493  pdelta(:) = pdelta(:) * zwr_delta(:)
494 !
495  phv(:) = pdelta(:) + (1.- pdelta(:))*( pra(:) + prs(:)*(1.0 - zzhv(:)) )* &
496  ( (1/(pra(:)+prs(:))) - (zzhv(:)*(1.-pf5(:))/(pra(:)+xrs_max)) )
497 !
498 ENDWHERE
499 !
500 IF (lhook) CALL dr_hook('DRAG:LIMIT_LER',1,zhook_handle)
501 !
502 END SUBROUTINE limit_ler
503 !
504 !-------------------------------------------------------------------------------
505 !
506 END SUBROUTINE drag
real function, dimension(size(pwind)) wind_threshold(PWIND, PUREF)
subroutine surface_ri(PTG, PQS, PEXNS, PEXNA, PTA, PQA, PZREF, PUREF, PDIRCOSZW, PVMOD, PRI)
Definition: surface_ri.F90:6
subroutine surface_aero_cond(PRI, PZREF, PUREF, PVMOD, PZ0, PZ0H, PAC, PRA, PCH)
subroutine limit_ler(PDELTA)
Definition: drag.F90:433
subroutine surface_cd(PRI, PZREF, PUREF, PZ0EFF, PZ0H, PCD, PCDN)
Definition: surface_cd.F90:6
subroutine surface_cdch_1darp(PZREF, PZ0EFF, PZ0H, PVMOD, PTA, PTG, PQA, PQS, PCD, PCDN, PCH)
subroutine drag(HISBA, HSNOW_ISBA, HCPSURF, PTSTEP, PTG, PWG, PWGI, PEXNS, PEXNA, PTA, PVMOD, PQA, PRR, PSR, PPS, PRS, PVEG, PZ0, PZ0EFF, PZ0H, PWFC, PWSAT, PPSNG, PPSNV, PZREF, PUREF, PDIRCOSZW, PDELTA, PF5, PRA, PCH, PCD, PCDN, PRI, PHUG, PHUGI, PHV, PHU, PCPS, PQS, PFFG, PFFV, PFF, PFFG_NOSNOW, PFFV_NOSNOW, PLEG_DELTA, PLEGI_DELTA, PWR, PRHOA, PLVTT, PQSAT)
Definition: drag.F90:6