SURFEX v8.1
General documentation of Surfex
average_diag.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 average_diag(PFRAC_TILE, DGO, D, ND, DC, NDC )
7 ! ######################################################################
8 !
9 !
10 !!**** *AVERAGE_DIAG*
11 !!
12 !! PURPOSE
13 !! -------
14 ! Average the fluxes from the land and water surfaces depending on the
15 ! fraction of each surface cover type in the mesh area.
16 !
17 !!** METHOD
18 !! ------
19 !
20 !! EXTERNAL
21 !! --------
22 !!
23 !! IMPLICIT ARGUMENTS
24 !! ------------------
25 !!
26 !!
27 !! REFERENCE
28 !! ---------
29 !!
30 !! AUTHOR
31 !! ------
32 !! V. Masson * Meteo-France-
33 !!
34 !! MODIFICATIONS
35 !! -------------
36 !! Original 06/2003
37 !! Modified 08/2009 (B. Decharme) : new diag
38 ! 02/2010 - S. Riette - Security for wind average in case of XUNDEF values
39 ! B. decharme 04/2013 : Add EVAP and SUBL diag
40 !-------------------------------------------------------------------------------
41 !
42 !* 0. DECLARATIONS
43 ! ------------
44 !
45 USE modd_data_cover_par, ONLY : ntilesfc
46 !
48 !
49 USE yomhook ,ONLY : lhook, dr_hook
50 USE parkind1 ,ONLY : jprb
51 !
52 IMPLICIT NONE
53 !
54 !* 0.1 declarations of arguments
55 !
56 REAL, DIMENSION(:,:), INTENT(IN) :: PFRAC_TILE ! Fraction in a mesh-area of
57 !
58 TYPE(diag_options_t), INTENt(INOUT) :: DGO
59 TYPE(diag_t), INTENT(INOUT) :: D
60 TYPE(diag_np_t), INTENT(INOUT) :: ND
61 TYPE(diag_t), INTENT(INOUT) :: DC
62 TYPE(diag_np_t), INTENT(INOUT) :: NDC
63 !
64 !* 0.2 declarations of local variables
65 !
66 REAL, DIMENSION(SIZE(PFRAC_TILE,1)) :: ZLAND, ZSEA, ZFRL
67 INTEGER :: JT
68 REAL(KIND=JPRB) :: ZHOOK_HANDLE
69 !-------------------------------------------------------------------------------
70 !
71 ! 1. Grid-Box average fluxes
72 ! -----------------------
73 !
74 IF (lhook) CALL dr_hook('AVERAGE_DIAG',0,zhook_handle)
75 !
76 IF (dgo%LSURF_BUDGET) THEN
77 !
78  DO jt = 1,ntilesfc
79  !
80  ! Net radiation
81  !
82  CALL make_average(pfrac_tile(:,jt),nd%AL(jt)%XRN,d%XRN,jt)
83 !
84 ! Sensible heat flux
85 !
86  CALL make_average(pfrac_tile(:,jt),nd%AL(jt)%XH,d%XH,jt)
87 !
88 ! Total latent heat flux
89 !
90  CALL make_average(pfrac_tile(:,jt),nd%AL(jt)%XLE,d%XLE,jt)
91 !
92 ! Sublimation latent heat flux
93 !
94  CALL make_average(pfrac_tile(:,jt),nd%AL(jt)%XLEI,d%XLEI,jt)
95 !
96 ! Total evapotranspiration
97 !
98  CALL make_average(pfrac_tile(:,jt),nd%AL(jt)%XEVAP,d%XEVAP,jt)
99 !
100 ! Sublimation
101 !
102  CALL make_average(pfrac_tile(:,jt),nd%AL(jt)%XSUBL,d%XSUBL,jt)
103 !
104 ! Storage flux
105 !
106  CALL make_average(pfrac_tile(:,jt),nd%AL(jt)%XGFLUX,d%XGFLUX,jt)
107 !
108 ! Downwards short wave radiation
109 !
110  CALL make_average(pfrac_tile(:,jt),nd%AL(jt)%XSWD,d%XSWD,jt)
111 !
112 ! Upwards short wave radiation
113 !
114  CALL make_average(pfrac_tile(:,jt),nd%AL(jt)%XSWU,d%XSWU,jt)
115 !
116 ! Downwards long wave radiation
117 !
118  CALL make_average(pfrac_tile(:,jt),nd%AL(jt)%XLWD,d%XLWD,jt)
119 !
120 ! Upwards long wave radiation
121 !
122  CALL make_average(pfrac_tile(:,jt),nd%AL(jt)%XLWU,d%XLWU,jt)
123 !
124 ! Zonal wind stress
125 !
126  CALL make_average(pfrac_tile(:,jt),nd%AL(jt)%XFMU,d%XFMU,jt)
127 !
128 ! Meridian wind stress
129 !
130  CALL make_average(pfrac_tile(:,jt),nd%AL(jt)%XFMV,d%XFMV,jt)
131 !
132 ! Downwards short wave radiation for each spectral band
133 !
134  CALL make_average_2d(pfrac_tile(:,jt),nd%AL(jt)%XSWBD,d%XSWBD,jt)
135 !
136 ! Upwards short wave radiation for each spectral band
137 !
138  CALL make_average_2d(pfrac_tile(:,jt),nd%AL(jt)%XSWBU,d%XSWBU,jt)
139 !
140  ENDDO
141  !
142 END IF
143 !
144 IF (dgo%LSURF_BUDGETC) THEN
145 !
146  DO jt = 1,ntilesfc
147  !
148 ! Net radiation
149 !
150  CALL make_average(pfrac_tile(:,jt),ndc%AL(jt)%XRN,dc%XRN,jt)
151 !
152 ! Sensible heat flux
153 !
154  CALL make_average(pfrac_tile(:,jt),ndc%AL(jt)%XH,dc%XH,jt)
155 !
156 ! Total latent heat flux
157 !
158  CALL make_average(pfrac_tile(:,jt),ndc%AL(jt)%XLE,dc%XLE,jt)
159 !
160 ! Sublimation latent heat flux
161 !
162  CALL make_average(pfrac_tile(:,jt),ndc%AL(jt)%XLEI,dc%XLEI,jt)
163 !
164 ! Storage flux
165 !
166  CALL make_average(pfrac_tile(:,jt),ndc%AL(jt)%XGFLUX,dc%XGFLUX,jt)
167 !
168 ! Total evapotranspiration
169 !
170  CALL make_average(pfrac_tile(:,jt),ndc%AL(jt)%XEVAP,dc%XEVAP,jt)
171 !
172 ! Sublimation
173 !
174  CALL make_average(pfrac_tile(:,jt),ndc%AL(jt)%XSUBL,dc%XSUBL,jt)
175 !
176 ! Downwards short wave radiation
177 !
178  CALL make_average(pfrac_tile(:,jt),ndc%AL(jt)%XSWD,dc%XSWD,jt)
179 !
180 ! Upwards short wave radiation
181 !
182  CALL make_average(pfrac_tile(:,jt),ndc%AL(jt)%XSWU,dc%XSWU,jt)
183 !
184 ! Downwards long wave radiation
185 !
186  CALL make_average(pfrac_tile(:,jt),ndc%AL(jt)%XLWD,dc%XLWD,jt)
187 !
188 ! Upwards long wave radiation
189 !
190  CALL make_average(pfrac_tile(:,jt),ndc%AL(jt)%XLWU,dc%XLWU,jt)
191 !
192 ! Zonal wind stress
193 !
194  CALL make_average(pfrac_tile(:,jt),ndc%AL(jt)%XFMU,dc%XFMU,jt)
195 !
196 ! Meridian wind stress
197 !
198  CALL make_average(pfrac_tile(:,jt),ndc%AL(jt)%XFMV,dc%XFMV,jt)
199 !
200  ENDDO
201  !
202 END IF
203 !
204 !-------------------------------------------------------------------------------
205 !
206 ! 2. Richardson number
207 ! -----------------
208 !
209 IF (dgo%N2M>=1) THEN
210 !
211  DO jt = 1,ntilesfc
212  !
213  CALL make_average(pfrac_tile(:,jt),nd%AL(jt)%XRI,d%XRI,jt)
214  !
215  ENDDO
216 !
217 ENDIF
218 !
219 !-------------------------------------------------------------------------------
220 !
221 ! 3. Operational parameters at surface, 2 and 10 meters
222 ! --------------------------------------------------
223 !
224 !
225 IF (dgo%N2M>=1.OR.dgo%LSURF_BUDGET.OR.dgo%LSURF_BUDGETC) THEN
226 !
227  DO jt = 1,ntilesfc
228  !
229 ! Surface temperature
230 !
231  CALL make_average(pfrac_tile(:,jt),nd%AL(jt)%XTS,d%XTS,jt)
232 !
233  ENDDO
234  !
235 ENDIF
236 !
237 IF (dgo%N2M>=1) THEN
238 !
239 ! Temperature at 2 meters
240 !
241  IF (dgo%LT2MMW) THEN
242  DO jt=1,ntilesfc
243 ! Modified weighting giving increased weight to LAND temperature
244  CALL make_average_mw(pfrac_tile(:,jt),nd%AL(jt)%XT2M,d%XT2M,jt,zland,zsea,zfrl)
245  ENDDO
246  DO jt=1,ntilesfc
247  CALL make_average_mw(pfrac_tile(:,jt),nd%AL(jt)%XT2M_MIN,d%XT2M_MIN,jt,zland,zsea,zfrl)
248  ENDDO
249  DO jt=1,ntilesfc
250  CALL make_average_mw(pfrac_tile(:,jt),nd%AL(jt)%XT2M_MAX,d%XT2M_MAX,jt,zland,zsea,zfrl)
251  ENDDO
252  ELSE
253  DO jt=1,ntilesfc
254  CALL make_average(pfrac_tile(:,jt),nd%AL(jt)%XT2M,d%XT2M,jt)
255  CALL make_average(pfrac_tile(:,jt),nd%AL(jt)%XT2M_MIN,d%XT2M_MIN,jt)
256  CALL make_average(pfrac_tile(:,jt),nd%AL(jt)%XT2M_MAX,d%XT2M_MAX,jt)
257  ENDDO
258  ENDIF
259 !
260  DO jt=1,ntilesfc
261 ! Relative humidity at 2 meters
262 !
263  CALL make_average(pfrac_tile(:,jt),nd%AL(jt)%XHU2M,d%XHU2M,jt)
264  CALL make_average(pfrac_tile(:,jt),nd%AL(jt)%XHU2M_MIN,d%XHU2M_MIN,jt)
265  CALL make_average(pfrac_tile(:,jt),nd%AL(jt)%XHU2M_MAX,d%XHU2M_MAX,jt)
266 !
267 ! Specific humidity at 2 meters
268 !
269  CALL make_average(pfrac_tile(:,jt),nd%AL(jt)%XQ2M,d%XQ2M,jt)
270 !
271 ! Wind at 10 meters
272 !
273  CALL make_average(pfrac_tile(:,jt),nd%AL(jt)%XZON10M,d%XZON10M,jt)
274 !
275  CALL make_average(pfrac_tile(:,jt),nd%AL(jt)%XMER10M,d%XMER10M,jt)
276 !
277  CALL make_average(pfrac_tile(:,jt),nd%AL(jt)%XWIND10M,d%XWIND10M,jt)
278  CALL make_average(pfrac_tile(:,jt),nd%AL(jt)%XWIND10M_MAX,d%XWIND10M_MAX,jt)
279 !
280  ENDDO
281  !
282 END IF
283 !-------------------------------------------------------------------------------
284 !
285 ! 4. Transfer coeffients and roughness lengths
286 ! -----------------------------------------
287 !
288 IF (dgo%LCOEF) THEN
289 !
290  DO jt=1,ntilesfc
291  !
292  CALL make_average(pfrac_tile(:,jt),nd%AL(jt)%XCD,d%XCD,jt)
293 !
294  CALL make_average(pfrac_tile(:,jt),nd%AL(jt)%XCH,d%XCH,jt)
295 !
296  CALL make_average(pfrac_tile(:,jt),nd%AL(jt)%XCE,d%XCE,jt)
297 !
298  CALL make_average_z0(pfrac_tile(:,jt),d%XUREF,nd%AL(jt)%XZ0,d%XZ0,jt)
299 !
300  CALL make_average_z0(pfrac_tile(:,jt),d%XZREF,nd%AL(jt)%XZ0H,d%XZ0H,jt)
301 !
302  ENDDO
303  !
304 ENDIF
305 !
306 IF (dgo%LSURF_VARS) THEN
307 !
308  DO jt=1,ntilesfc
309  CALL make_average(pfrac_tile(:,jt),nd%AL(jt)%XQS,d%XQS,jt)
310  ENDDO
311 !
312 ENDIF
313 !
314 IF (lhook) CALL dr_hook('AVERAGE_DIAG',1,zhook_handle)
315 !
316 CONTAINS
317 !
318 SUBROUTINE make_average(PFRAC,PFIELD_IN,PFIELD_OUT,KTILE)
319 !
320 USE modd_surf_par, ONLY : xundef
321 !
322 IMPLICIT NONE
323 !
324 REAL, DIMENSION(:),INTENT(IN) :: PFRAC
325 REAL, DIMENSION(:),INTENT(IN) :: PFIELD_IN
326 REAL, DIMENSION(:), INTENT(OUT) :: PFIELD_OUT
327 INTEGER, INTENT(IN) :: KTILE
328 REAL(KIND=JPRB) :: ZHOOK_HANDLE
329 INTEGER :: JT
330 !
331 IF (lhook) CALL dr_hook('AVERAGE_DIAG:MAKE_AVERAGE',0,zhook_handle)
332 !
333 IF (ktile==1) pfield_out(:) = 0.
334 !
335 WHERE (pfield_in(:)==xundef .AND. pfrac(:)/=0.) pfield_out(:) = xundef
336 !
337 WHERE (pfield_out(:)/=xundef)
338  pfield_out(:) = pfield_out(:) + pfrac(:) * pfield_in(:)
339 END WHERE
340 !
341 IF (lhook) CALL dr_hook('AVERAGE_DIAG:MAKE_AVERAGE',1,zhook_handle)
342 !
343 END SUBROUTINE make_average
344 !
345 SUBROUTINE make_average_2d(PFRAC,PFIELD_IN,PFIELD_OUT,KTILE)
346 !
347 USE modd_surf_par, ONLY : xundef
348 !
349 IMPLICIT NONE
350 !
351 REAL, DIMENSION(:),INTENT(IN) :: PFRAC
352 REAL, DIMENSION(:,:),INTENT(IN) :: PFIELD_IN
353 REAL, DIMENSION(:,:), INTENT(OUT) :: PFIELD_OUT
354 INTEGER, INTENT(IN) :: KTILE
355 REAL(KIND=JPRB) :: ZHOOK_HANDLE
356 INTEGER :: JT, JL
357 !
358 IF (lhook) CALL dr_hook('AVERAGE_DIAG:MAKE_AVERAGE_2D',0,zhook_handle)
359 !
360 IF (ktile==1) pfield_out(:,:) = 0.
361 !
362 DO jl=1,SIZE(pfield_in,2)
363  WHERE (pfield_in(:,jl)==xundef .AND. pfrac(:)/=0.) pfield_out(:,jl) = xundef
364  WHERE(pfield_out(:,jl)/=xundef)
365  pfield_out(:,jl) = pfield_out(:,jl) + pfrac(:) * pfield_in(:,jl)
366  END WHERE
367 END DO
368 !
369 IF (lhook) CALL dr_hook('AVERAGE_DIAG:MAKE_AVERAGE_2D',1,zhook_handle)
370 !
371 END SUBROUTINE make_average_2d
372 !
373 SUBROUTINE make_average_z0(PFRAC,PREF,PFIELD_IN,PFIELD_OUT,KTILE)
374 !
375 USE modd_surf_par, ONLY : xundef
376 !
377 IMPLICIT NONE
378 !
379 REAL, DIMENSION(:),INTENT(IN) :: PFRAC
380 REAL, DIMENSION(:),INTENT(IN) :: PFIELD_IN
381 REAL, DIMENSION(:),INTENT(IN) :: PREF
382 REAL, DIMENSION(:), INTENT(OUT) :: PFIELD_OUT
383 INTEGER, INTENT(IN) :: KTILE
384 REAL(KIND=JPRB) :: ZHOOK_HANDLE
385 !
386 IF (lhook) CALL dr_hook('AVERAGE_DIAG:MAKE_AVERAGE_Z0',0,zhook_handle)
387 !
388 IF (ktile==1) pfield_out(:) = 0.
389 !
390 WHERE (pfield_in(:)==xundef .AND. pfrac(:)/=0.) pfield_out(:) = xundef
391 !
392 WHERE (pfield_out(:)/=xundef)
393  pfield_out(:) = pfield_out(:) + pfrac(:) * 1./(log(pref(:)/pfield_in(:)))**2
394 END WHERE
395 !
396 IF (ktile==ntilesfc) THEN
397  WHERE (pfield_out(:) == 0.)
398  pfield_out(:) = xundef
399  ELSEWHERE (pfield_out(:)/=xundef)
400  pfield_out(:) = pref(:) * exp( - sqrt(1./pfield_out(:)) )
401  ENDWHERE
402 ENDIF
403 !
404 IF (lhook) CALL dr_hook('AVERAGE_DIAG:MAKE_AVERAGE_Z0',1,zhook_handle)
405 !
406 END SUBROUTINE make_average_z0
407 !
408 SUBROUTINE make_average_mw(PFRAC,PFIELD_IN,PFIELD_OUT,KTILE,PLAND,PSEA,PFRL)
409 !
410 USE modd_surf_par, ONLY : xundef
411 !
412 IMPLICIT NONE
413 !
414 REAL, DIMENSION(:),INTENT(IN) :: PFRAC
415 REAL, DIMENSION(:),INTENT(IN) :: PFIELD_IN
416 REAL, DIMENSION(:), INTENT(OUT) :: PFIELD_OUT
417 INTEGER, INTENT(IN) :: KTILE
418 REAL, DIMENSION(:), INTENT(INOUT) :: PLAND
419 REAL, DIMENSION(:), INTENT(INOUT) :: PSEA
420 REAL, DIMENSION(:), INTENT(INOUT) :: PFRL
421 REAL(KIND=JPRB) :: ZHOOK_HANDLE
422 INTEGER :: JT
423 REAL, DIMENSION(SIZE(PFIELD_IN)) :: ZALFA
424 !
425 IF (lhook) CALL dr_hook('AVERAGE_DIAG:MAKE_AVERAGE_MW',0,zhook_handle)
426 !
427 IF (ktile==1) THEN
428  pfield_out(:) = 0.
429  psea(:)= 0.
430  pland(:)= 0.
431  pfrl(:)= 0.
432 ENDIF
433 !
434 WHERE (pfield_in(:)==xundef .AND. pfrac(:)/=0.) pfield_out(:) = xundef
435 !
436 IF (ktile==1.OR.ktile==2) THEN
437  psea(:) = psea(:) + pfrac(:) * pfield_in(:)
438 ENDIF
439 !
440 IF (ktile==3.OR.ktile==4) THEN
441  pland(:) = pland(:) + pfrac(:) * pfield_in(:)
442  pfrl(:) = pfrl(:) + pfrac(:)
443 ENDIF
444 !
445 IF (ktile==4) THEN
446  WHERE(zfrl(:)>0.)
447  zland(:) = zland(:)/zfrl(:)
448  ENDWHERE
449  WHERE(zfrl(:)<1.)
450  zsea(:) = zsea(:)/(1.-zfrl(:))
451  ENDWHERE
452  !
453  zalfa(:) = 1. - exp(-10.*zfrl(:))
454  !
455  WHERE (pfield_out(:)/=xundef)
456  pfield_out(:) = zalfa(:) * zland(:) + (1. - zalfa(:)) * zsea(:)
457  END WHERE
458  !
459 ENDIF
460 !
461 IF (lhook) CALL dr_hook('AVERAGE_DIAG:MAKE_AVERAGE_MW',1,zhook_handle)
462 !
463 END SUBROUTINE make_average_mw
464 !
465 !-------------------------------------------------------------------------------
466 !
467 END SUBROUTINE average_diag
subroutine average_diag(PFRAC_TILE, DGO, D, ND, DC, NDC)
Definition: average_diag.F90:7
real, parameter xundef
subroutine make_average(PFRAC, PFIELD_IN, PFIELD_OUT, KTILE)
integer, parameter jprb
Definition: parkind1.F90:32
subroutine make_average_2d(PFRAC, PFIELD_IN, PFIELD_OUT, KTILE)
subroutine make_average_mw(PFRAC, PFIELD_IN, PFIELD_OUT, KTILE, PLAND, PSEA, P
subroutine make_average_z0(PFRAC, PREF, PFIELD_IN, PFIELD_OUT, KTILE)
logical lhook
Definition: yomhook.F90:15