SURFEX  V8_0
Surfex V8_0 release
 All Classes Files Functions Variables
preps_for_meb_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 preps_for_meb_drag(LCVEL, LFORC_MEASURE, &
7  pz0, pz0h, pz0eff, ph_veg, pzref, &
8  ptc, pta, pqc, pqa, puref, pvmod, &
9  pexna, pexns, pdircoszw, pdisph, &
10  pvelc, pzvmod, pri, pra, &
11  pch,pcdn,pcd )
12 !
13 ! typical values for nordic forest:
14 ! PZ0 = 0.8 m
15 ! PH_VEG = 15 m
16 !
17 !
18 !!**** *PREPS_FOR_MEB*
19 !!
20 !! PURPOSE
21 !! -------
22 !
23 ! Calculates the winds near top of vegetation (PVELC)
24 ! vegetation (PVELC). Used for input to surface_air_meb.
25 ! Only used for double energy balance
26 ! Also calculates PRA,PCH,PCDN and PCD
27 !
28 !
29 !!** METHOD
30 !! ------
31 !!
32 !! REFERENCE
33 !! ---------
34 !!
35 !!
36 !! AUTHOR
37 !! ------
38 !!
39 !! P. Samuelsson/S.Gollvik * SMHI *
40 !!
41 !! MODIFICATIONS
42 !! -------------
43 !! Original 11/2010
44 !!
45 !-------------------------------------------------------------------------------
46 !
47 !* 0. DECLARATIONS
48 ! ------------
49 !
50 ! LFORC_MEASURE= .TRUE. => heigh is given over ground
51 ! .FALSE. => heigh is given over displacement height
52 ! example from a numerical model PZREF=10 means that
53 ! the level is 10 m above the displacement height
54 !
55 !
56 USE modd_csts, ONLY : xpi, xkarman, xg, xcpd, xrd
57 USE modd_surf_atm, ONLY : ldrag_coef_arp, xrimax
58 USE modd_isba_par, ONLY : xlimh
59 !
60 USE modi_surface_aero_cond
61 USE modi_surface_cd
62 USE modi_surface_ri
63 USE modi_wind_threshold
64 !RJ: missing modi
65 USE modi_surface_cdch_1darp
66 !
67 USE yomhook ,ONLY : lhook, dr_hook
68 USE parkind1 ,ONLY : jprb
69 !
70 IMPLICIT NONE
71 !
72 !* 0.1 declarations of arguments
73 !
74 REAL, DIMENSION(:), INTENT(IN) :: pz0, pz0h, pz0eff,ph_veg, pzref, puref, pvmod
75 ! PZ0 = roughness length for momentum
76 ! PZ0H = roughness length for heat
77 ! PZ0EFF = roughness length for momentum (orographic)
78 ! PH_VEG = height of the vegetation
79 ! PZREF = height of the lowest model layer
80 ! PUREF = reference height of the wind
81 ! NOTE this is different from PZREF
82 ! ONLY in stand-alone/forced mode,
83 ! NOT when coupled to a model (MesoNH)
84 ! PVMOD = module of the horizontal wind
85 !
86 REAL, DIMENSION(:), INTENT(IN) :: ptc, pta, pqc, pqa
87 ! PTC = temperature of the canopy air
88 ! PTA = temperature of the lowest model layer
89 ! PQC = specific humidity of the canopy air
90 ! PQA = specific humidity of the lowest model level
91 !
92 REAL, DIMENSION(:), INTENT(IN) :: pexna, pexns, pdircoszw, pdisph
93 ! PEXNA = exner function at the lowest model level
94 ! PEXNS = exner function at the surface
95 ! PDIRCOSZW = Cosine of the angle between the normal
96 ! to the surface and the vertical
97 ! PDISPH = displacement height
98 !
99 REAL, DIMENSION(:), INTENT(OUT) :: pvelc, pzvmod, pri, pra, pch, pcdn, pcd
100 ! PVELC = wind speed atr top of vegetation
101 ! PZVMOD = PMOD after wind threshold
102 ! PRI = Richardson number between canopy air and atm
103 ! PRA = aerodynamic resistance between canopy air
104 ! and lowest model layer
105 ! PCH = exchange coefficient for heat
106 ! PCDN = neutral exchange coefficient for momentum
107 ! PCD = exchange coefficient for momentum
108 !
109 LOGICAL, INTENT(IN) :: lcvel, lforc_measure
110 ! LCVEL = switch for calculating PVELC
111 ! LFORC_MEASURE = switch for using measured data
112 !
113 !* 0.2 declarations of local variables
114 !
115 REAL, DIMENSION(SIZE(PZ0)) :: zreveg, zcd, zcur, zucur, zratvv, zac
116 REAL, DIMENSION(SIZE(PZ0)) :: zbn, zbd, zcbnvv, zcbsvv, zcbuvv, zredvv
117 !
118 REAL(KIND=JPRB) :: zhook_handle
119 !
120 !* 0.3 declarations of local parameters
121 !
122 REAL, PARAMETER :: zul = 1. ! typical windspeed within the foliage
123 REAL, PARAMETER :: zny = 0.15e-04 ! kinematic viscosity for air
124 REAL, PARAMETER :: zvelclim = 0.1 ! safe minimum value ov PVELC
125 !-------------------------------------------------------------------------------
126 !
127 !* 0. Initialization:
128 !
129 IF (lhook) CALL dr_hook('PREPS_FOR_MEB_DRAG',0,zhook_handle)
130 !
131 pvelc(:) = zvelclim
132 pra(:) = 0.
133 zcur(:) = max(pzref(:),xlimh)
134 zucur(:) = max(puref(:),xlimh)
135 !
136 !Calculate height compared to dispacement height
137 !
138 IF(lforc_measure) THEN
139 !
140  zcur(:) = pzref(:)-pdisph(:)
141  zucur(:) = puref(:)-pdisph(:)
142 !
143  IF (any(zcur<0.0 .OR. zucur<0.0))THEN
144  print *,'MAXVAL(PH_VEG)=',maxval(ph_veg)
145  print *,'MAXVAL(PDISPH)=',maxval(pdisph)
146  print *,'MINVAL(PZREF)=',minval(pzref)
147  print *,'MINVAL(PUREF)=',minval(puref)
148  stop "Forcing height for wind or temperature too low!!"
149  ENDIF
150 !
151 ELSE
152 !
153 ! When running a numerical model it is assumed that PZREF is the distance between the
154 ! lowest model layer and displacement height, thus the "trees are below surface"
155 !
156  zcur(:) = max(pzref(:),ph_veg(:)-pdisph(:)+xlimh)
157  zucur(:) = max(puref(:),ph_veg(:)-pdisph(:)+xlimh)
158 !
159 ENDIF
160 !
161 ! Exner function at displacement height
162 ! For consistancy displacement height has the same pressure as the surface
163 !
164  CALL surface_ri(ptc, pqc, pexns, pexna, pta, pqa, &
165  zcur, zucur, pdircoszw, pvmod, pri )
166 !
167 pri(:) = min(pri(:),xrimax)
168 !
169 pzvmod = wind_threshold(pvmod,zucur)
170 !
171 IF (ldrag_coef_arp) THEN
172 
173  CALL surface_cdch_1darp(zcur, pz0eff, pz0h, pzvmod, pta, ptc, &
174  pqa, pqc, pcd, pcdn, pch )
175  pra(:) = 1. / ( pch(:) * pzvmod(:) )
176 
177 ELSE
178 !
179 ! -------------------------------------------------
180 !
181  CALL surface_aero_cond(pri, zcur, zucur, pzvmod, pz0, pz0h, zac, pra, pch)
182 !
183 !-------------------------------------------------------------------------------
184 !
185 !* 7.2 DRAG COEFFICIENT FOR MOMENTUM TRANSFERS
186 ! ---------------------------------------
187 !
188 !
189  CALL surface_cd(pri, zcur, zucur, pz0eff, pz0h, pcd, pcdn)
190 !
191 ENDIF
192 !
193 IF(lcvel) THEN
194 !
195 ! In cases with very low model layer, we estimate the wind at treetop as that of
196 ! the lowest layer
197 !
198  zratvv(:) = min((ph_veg(:)-pdisph(:))/zcur(:),1.)
199 !
200  zbn(:) = xkarman/sqrt(pcdn(:))
201  zbd(:) = xkarman/sqrt(pcd(:))
202  zcbnvv(:) = alog(1.+(exp(zbn(:))-1.)*zratvv(:))
203  zcbsvv(:) = -(zbn(:)-zbd(:))*zratvv(:)
204  zcbuvv(:) = -alog(1.+(exp(zbn(:)-zbd(:))-1.)*zratvv(:))
205 !
206  WHERE(pri>=0)
207  zredvv(:) = (zcbnvv(:) + zcbsvv(:))/zbd(:)
208  ELSEWHERE
209  zredvv(:) = (zcbnvv(:) + zcbuvv(:))/zbd(:)
210  END WHERE
211 !
212  pvelc(:) = max(zredvv(:)*pzvmod(:),zvelclim)
213 !
214 ENDIF
215 !
216 IF (lhook) CALL dr_hook('PREPS_FOR_MEB_DRAG',1,zhook_handle)
217 !
218 END SUBROUTINE preps_for_meb_drag
219 
220 
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 preps_for_meb_drag(LCVEL, LFORC_MEASURE, PZ0, PZ0H, PZ0EFF, PH_VEG, PZREF, PTC, PTA, PQC, PQA, PUREF, PVMOD, PEXNA, PEXNS, PDIRCOSZW, PDISPH, PVELC, PZVMOD, PRI, PRA, PCH, PCDN, PCD)
subroutine surface_aero_cond(PRI, PZREF, PUREF, PVMOD, PZ0, PZ0H, PAC, PRA, PCH)
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)