SURFEX  V8_0
Surfex V8_0 release
 All Classes Files Functions Variables
mr98.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 mr98 (PZ0SEA, &
7  pta, pexna, prhoa, psst, pexns, pqa, &
8  ptt, &
9  pvmod, pzref, puref, &
10  pps, pqsat, &
11  psfth, psftq, pustar, &
12  pcd, pcdn, pch, pri, presa, pz0hsea )
13 ! #######################################################################
14 !
15 !
16 !!**** *MR98*
17 !!
18 !! PURPOSE
19 !! -------
20 ! Calculate the surface fluxes of heat, moisture, and momentum over
21 ! water surfaces.
22 !
23 !!** METHOD
24 !! ------
25 !
26 !! EXTERNAL
27 !! --------
28 !!
29 !! IMPLICIT ARGUMENTS
30 !! ------------------
31 !!
32 !!
33 !! REFERENCE
34 !! ---------
35 !!
36 !! AUTHOR
37 !! ------
38 !! V. Masson * Meteo-France *
39 !! from part of water_flux.f90 written by M. tomasini
40 !!
41 !! MODIFICATIONS
42 !! -------------
43 !! Original 11/2004
44 !! (M.Tomasini) 25/07/00 Add an iterative method for the fluxes calculation
45 !!-------------------------------------------------------------------------------
46 !
47 !* 0. DECLARATIONS
48 ! ------------
49 !
50 USE modd_csts, ONLY : xpi, xcpd, xg, xkarman
51 USE modd_surf_par, ONLY : xundef
52 !
53 USE mode_thermos
54 !
55 !
56 !
57 USE yomhook ,ONLY : lhook, dr_hook
58 USE parkind1 ,ONLY : jprb
59 !
60 IMPLICIT NONE
61 !
62 !* 0.1 declarations of arguments
63 !
64 !
65 REAL, DIMENSION(:), INTENT(IN) :: pta ! air temperature at atm. level
66 REAL, DIMENSION(:), INTENT(IN) :: pqa ! air humidity at atm. level (kg/kg)
67 REAL, DIMENSION(:), INTENT(IN) :: pexna ! Exner function at atm. level
68 REAL, DIMENSION(:), INTENT(IN) :: prhoa ! air density at atm. level
69 REAL, DIMENSION(:), INTENT(IN) :: pvmod ! module of wind at atm. wind level
70 REAL, DIMENSION(:), INTENT(IN) :: pzref ! atm. level for temp. and humidity
71 REAL, DIMENSION(:), INTENT(IN) :: puref ! atm. level for wind
72 REAL, DIMENSION(:), INTENT(IN) :: psst ! Sea Surface Temperature
73 REAL, DIMENSION(:), INTENT(IN) :: pexns ! Exner function at sea surface
74 REAL, DIMENSION(:), INTENT(IN) :: pps ! air pressure at sea surface
75 REAL, INTENT(IN) :: ptt ! temperature of freezing point
76 !
77 REAL, DIMENSION(:), INTENT(INOUT) :: pz0sea! roughness length over the ocean
78 !
79 !
80 ! surface fluxes : latent heat, sensible heat, friction fluxes
81 REAL, DIMENSION(:), INTENT(OUT) :: psfth ! heat flux (W/m2)
82 REAL, DIMENSION(:), INTENT(OUT) :: psftq ! water flux (kg/m2/s)
83 REAL, DIMENSION(:), INTENT(OUT) :: pustar! friction velocity (m/s)
84 !
85 ! diagnostics
86 REAL, DIMENSION(:), INTENT(OUT) :: pqsat ! humidity at saturation
87 REAL, DIMENSION(:), INTENT(OUT) :: pcd ! heat drag coefficient
88 REAL, DIMENSION(:), INTENT(OUT) :: pcdn ! momentum drag coefficient
89 REAL, DIMENSION(:), INTENT(OUT) :: pch ! neutral momentum drag coefficient
90 REAL, DIMENSION(:), INTENT(OUT) :: pri ! Richardson number
91 REAL, DIMENSION(:), INTENT(OUT) :: presa ! aerodynamical resistance
92 REAL, DIMENSION(:), INTENT(OUT) :: pz0hsea ! roughness length for heat
93 !
94 !
95 !
96 !* 0.2 declarations of local variables
97 !
98 !
99 REAL, DIMENSION(SIZE(PTA)) :: zz0seah, &!roughness length heat
100  zz0seaq, &!roughness length moisture
101  zthvi
102 !
103 REAL, DIMENSION(SIZE(PTA)) :: zqsa, ztha, zdu, zdt, zdq, znu, zwg
104 ! ZQSA = specific humidity at the
105 ! sea surface
106 ! ZTHA = potential temperature at the
107 ! the first level
108 ! ZDU, ZDT, ZDQ = wind, potential
109 ! temperature and specific
110 ! humidity difference between
111 ! the first level and the sea
112 ! ZNU = air kinematic visosity
113 ! ZWG = wind subgrid "gustiness" effects
114 REAL, DIMENSION(SIZE(PTA)) :: ztstar, zqstar, ztvstar, &
115 ! T*, Q*, Tv* usefull in fluxes computation
116  zbuflx
117 ! ZBUFLX = surface buoyancy flux
118 !
119 REAL, DIMENSION(SIZE(PTA)) :: zlmon, zzeta, zpsim, zpsih, zpsiq, &
120  zkhi, zkhic, zpsic, zf, &
121  zpsihstand,zpsimstand,zzetast
122 ! ZLMON = Monin Obukhov length
123 ! ZZETA = Monin Obukhov Stability
124 ! parameter : Zeta=Zref/Lmon
125 ! ZPSIM, ZPSIH, ZPSIQ = Stability
126 ! functions for Momentum,
127 ! Heat and Moisture
128 ! ZKHI = variable for Stability functions
129 ! ZPSIC = Stability function correction for
130 ! very unstable conditions
131 ! ZKHIC = variable for ZPSIC
132 ! ZF = weight parameter in psi function
133 ! computation
134 !
135 ! constants for wind gustiness effect (ZWG) calculation
136 !
137 REAL :: zbeta
138 ! ZBETA = coef. for the gustiness
139 ! effect on the wind
140 
141 ! Wg=(ZBETA).W*
142 REAL :: zzbl
143 ! ZZBL = atmospheric boundary
144 ! layer depth (m)
145 !
146 REAL :: zstand
147 !
148 ! loop parameters for iterative case
149 !
150 INTEGER :: jiter
151 ! JITER = loop parameter for
152 ! iterations
153 !
154 INTEGER, PARAMETER :: iitermax = 10
155 REAL(KIND=JPRB) :: zhook_handle
156 ! IITERMAX = number of iterations
157 !
158 !-------------------------------------------------------------------------------
159 !
160 IF (lhook) CALL dr_hook('MR98',0,zhook_handle)
161 pri(:) = xundef
162 pch(:) = xundef
163 pcd(:) = xundef
164 pcdn(:) = xundef
165 presa(:) = xundef
166 !
167 psfth(:) =xundef
168 psftq(:)=xundef
169 pustar(:)=xundef
170 !
171 ! Although it is not necessary, fluxes over
172 ! water surfaces are calculated at every
173 ! grid-points, even for those over the
174 ! continent. When the "WHERE" function of
175 ! the CRAY F90 will be vectorized, it can
176 ! be used to discriminate points over the
177 ! ocean and the continent. But for now,
178 ! the current approach is believed the
179 ! simplest, without being too penalizing.
180 ! It mainly consists in averaging the
181 ! surface fluxes over water and land using
182 ! the cover type variables.
183 !
184 !
185 ! 1. Saturated specific humidity near the water surface
186 ! ---------------------------------------------------------
187 !
188 pqsat(:) = qsat(psst(:),pps(:))
189 !
190 !-------------------------------------------------------------------------------
191 !
192 ! Begining of the fluxes calculation
193 ! by an iterative method coming from the one
194 ! proposed by Fairall et al (1996) for
195 ! the TOGA-COARE Bulk Flux Algorithm
196 !
197 !
198 !
199 ! 3.1 initialisations
200 ! ----------------------------------------------------
201 !
202 zzbl=650.
203 zstand=15.
204 zbeta = 0.6
205 !
206  zqsa(:) = 0.98 * pqsat(:)
207  ztha(:) = pta(:) / pexna(:)
208  zthvi(:) = ( 1 + 0.61 * pqa(:) ) * ztha(:)
209 !
210  zdu(:) = pvmod(:)
211  zdt(:) = ztha(:) - psst(:) /pexns(:)
212  zdq(:) = pqa(:) - zqsa(:)
213 !
214  pustar(:) = max( 0.04 * zdu(:) , 5e-3)
215  ztstar(:) = 0.04 * zdt(:)
216  zqstar(:) = 0.04 * zdq(:)
217  ztvstar(:) = ztstar(:)*(1+0.61*pqa(:)) + 0.61*zqstar(:)*ztha(:)
218 !
219  znu(:) = 1.318e-5 + 9.282e-8 * (pta(:) - ptt)
220 !
221 !
222 !
223 ! 3.2 begining of iterations
224 ! -------------------------------------------------
225 !
226  DO jiter = 1 , iitermax
227 !
228 ! 3.2.1 compute stability functions
229 ! -------------------------------------------------
230 !
231  WHERE (abs(ztvstar(:)) < 1e-6)
232  zzeta(:) = 0.0
233  zzetast(:) = 0.0
234  ELSEWHERE
235  zlmon(:) = zthvi(:)*pustar(:)*pustar(:)/(ztvstar(:)*xg*xkarman)
236  zzeta(:) = max( pzref(:) / zlmon(:) , -20000.)
237  zzetast(:) = max( zstand / zlmon(:) , -20000.)
238  END WHERE
239 !
240 !
241  WHERE(zzeta(:) >= 0.0)
242  zpsim(:) = -4.7*zzeta(:)
243  zpsih(:) = zpsim(:)
244  zpsiq(:) = zpsih(:)
245  zpsihstand(:) = -4.7*zzetast(:)
246  zpsimstand(:) = zpsihstand(:)
247  ELSEWHERE
248  zkhi(:) = (1 - 16 * zzeta(:))**0.25
249  zpsim(:) = 2*log((1+zkhi(:))/2) &
250  + log((1+zkhi(:)*zkhi(:))/2) &
251  - 2*atan(zkhi(:)) &
252  + xpi/2
253  zpsih(:) = 2 * log((1+zkhi(:)*zkhi(:))/2)
254 !
255  zkhi(:) = (1 - 16 * zzetast(:))**0.25
256  zpsihstand(:) = 2 * log((1+zkhi(:)*zkhi(:))/2)
257  zpsimstand(:) = 2*log((1+zkhi(:))/2) &
258  + log((1+zkhi(:)*zkhi(:))/2) &
259  - 2*atan(zkhi(:)) &
260  + xpi/2
261 !
262 ! to match very unstable conditions
263 !
264  zkhic(:) = (1 - 12.87 * zzeta(:))**0.33
265  zpsic(:) = 1.5 * log((1+zkhic(:)+zkhic(:)*zkhic(:))/3) &
266  - (3**0.5)*atan((2*zkhic(:)+1)/(3**0.5)) &
267  + xpi/(3**0.5)
268 !
269  zf(:) = 1 / (1+ zzeta(:)*zzeta(:))
270  zpsim(:) = zpsim(:)*zf(:) + zpsic(:)*(1-zf(:))
271  zpsih(:) = zpsih(:)*zf(:) + zpsic(:)*(1-zf(:))
272  zpsiq(:) = zpsih(:)
273 !
274  zkhic(:) = (1 - 12.87 * zzetast(:))**0.33
275  zpsic(:) = 1.5 * log((1+zkhic(:)+zkhic(:)*zkhic(:))/3) &
276  - (3**0.5)*atan((2*zkhic(:)+1)/(3**0.5)) &
277  + xpi/(3**0.5)
278 !
279  zf(:) = 1 / (1+ zzetast(:)*zzetast(:))
280  zpsimstand(:) = zpsimstand(:)*zf(:) + zpsic(:)*(1-zf(:))
281  zpsihstand(:) = zpsihstand(:)*zf(:) + zpsic(:)*(1-zf(:))
282 !
283  END WHERE
284 !
285 ! 3.2.2 compute roughness length Zo, Zoh and Zoq
286 ! ----------------------------------------------
287 !
288  pz0sea(:) = 0.011*pustar(:)*pustar(:)/xg &
289  +0.11*znu(:)/(pustar(:))
290 !
291 !
292  WHERE(pustar(:) > 0.23)
293  zz0seah(:) = 0.14*znu(:)/(pustar(:)-0.2) + 7e-6
294  zz0seaq(:) = 0.20*znu(:)/(pustar(:)-0.2) + 9e-6
295  ELSEWHERE
296  zz0seah(:) = 0.015*pustar(:)*pustar(:)/xg &
297  + 0.18*znu(:)/(pustar(:))
298  zz0seaq(:) = 0.0205*pustar(:)*pustar(:)/xg &
299  + 0.294*znu(:)/(pustar(:))
300  END WHERE
301 !
302 !
303 ! 3.2.3 compute friction velocity u*, T*, Q* and Tv*
304 ! ---------------------------------------------------
305 !
306  pustar(:) = max( &
307  zdu(:)*xkarman / (log(pzref(:)/pz0sea(:)) - zpsim(:)) &
308  , 5e-3 )
309 !
310  ztstar(:) = zdt(:)*xkarman / (log(pzref(:)/zz0seah(:)) - zpsih(:))
311 !
312  zqstar(:) = zdq(:)*xkarman / (log(pzref(:)/zz0seaq(:)) - zpsiq(:))
313 !
314  ztvstar(:) = ztstar(:)*(1+0.61*pqa(:))+0.61*zqstar(:)*ztha(:)
315 !
316 !
317 ! 3.2.4 compute subgrid correction for wind due to convective motions
318 ! --------------------------------------------------------------------
319 !
320  zbuflx(:) = -xg*ztvstar(:)*pustar(:)/zthvi(:)
321 !
322  WHERE(zbuflx(:) > 0.)
323  zwg(:) = zbeta*(zbuflx(:)*zzbl)**0.333
324  ELSEWHERE
325  zwg(:) = 0.
326  END WHERE
327 !
328  zdu(:) = (pvmod(:)*pvmod(:)+zwg(:)*zwg(:))**0.5
329 !
330  END DO
331 !
332 pz0hsea = zz0seah
333 !-------------------------------------------------------------------------------
334 !
335 ! 3.3 here are the fluxes of iterative case
336 ! ------------------------------------------
337 !
338  psfth(:) = - prhoa(:) * xcpd * pustar(:) * ztstar(:)
339  psftq(:) = - prhoa(:) * pustar(:) * zqstar(:)
340 IF (lhook) CALL dr_hook('MR98',1,zhook_handle)
341 !
342 !-------------------------------------------------------------------------------
343 !
344 END SUBROUTINE mr98
subroutine mr98(PZ0SEA, PTA, PEXNA, PRHOA, PSST, PEXNS, PQA, PTT, PVMOD, PZREF, PUREF, PPS, PQSAT, PSFTH, PSFTQ, PUSTAR, PCD, PCDN, PCH, PRI, PRESA, PZ0HSEA)
Definition: mr98.F90:6