SURFEX  V8_0
Surfex V8_0 release
 All Classes Files Functions Variables
subscale_aos.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 subscale_aos (UG, USS, &
7  oz0effi,oz0effj,psea)
8 ! #############################################
9 !
10 !!*SUBSCALE_AOS computes the sum of the ratio: (h'-h)/L when h'/L >h/L
11 !! the ' is for subgrid scale orography
12 !!
13 !!
14 !! METHOD
15 !! ------
16 !! See M.Georgelin and al. July 1994, Monthly Weather Review.
17 !!
18 !! EXTERNAL
19 !! --------
20 !!
21 !! AUTHOR
22 !! ------
23 !!
24 !! M. Georgelin Laboratoire d'Aerologie
25 !!
26 !! MODIFICATION
27 !! ------------
28 !!
29 !! Original 18/12/95
30 !! (V. Masson) 10/03/97 rewrites the routine in doctor norm.
31 !! computations are made even if a only a few subsquares
32 !! contains data points.
33 !! returns to the calling routine the localization of
34 !! the points where the z0 coefficients are available.
35 !! (V. Masson) 03/2004 externalization
36 !!
37 !----------------------------------------------------------------------------
38 !
39 !* 0. DECLARATION
40 ! -----------
41 !
42 !
45 !
46 USE modd_pgdwork, ONLY : nsso, xssqo, lssqo
47 USE modd_pgd_grid, ONLY : nl, cgrid, xgrid_par, ngrid_par
48 !
49 USE modi_get_adjacent_meshes
50 !
51 !
52 USE yomhook ,ONLY : lhook, dr_hook
53 USE parkind1 ,ONLY : jprb
54 !
55 USE modi_get_mesh_dim
56 IMPLICIT NONE
57 !
58 !* 0.1 Declaration of dummy arguments
59 ! ------------------------------
60 !
61 !
62 TYPE(surf_atm_grid_t), INTENT(INOUT) :: ug
63 TYPE(surf_atm_sso_t), INTENT(INOUT) :: uss
64 !
65 LOGICAL, DIMENSION(:), INTENT(OUT) :: oz0effi! .T. : the z0eff coefficients
66 ! ! are computed at grid point
67 ! ! .F. : not enough sub-grid
68 ! ! information avalaible to
69 ! ! compute the coefficients
70 LOGICAL, DIMENSION(:), INTENT(OUT) :: oz0effj! .T. : the z0eff coefficients
71 ! ! are computed at grid point
72 ! ! .F. : not enough sub-grid
73 ! ! information avalaible to
74 ! ! compute the coefficients
75 REAL, DIMENSION(:), INTENT(IN) :: psea ! sea fraction
76 
77 !
78 !* 0.2 Declaration of indexes
79 ! ----------------------
80 !
81 !
82 INTEGER :: jl ! loop index on grid meshs
83 INTEGER :: il ! grid mesh index of second subgrid point used
84 INTEGER :: jiss, jjss ! loop indexes for subsquares arrays
85 INTEGER :: jnext ! loop index on subgrid meshes
86 INTEGER :: inext ! index to add to JISS or JJSS to obtain the following
87 ! ! point containing a data in a segment
88 INTEGER, DIMENSION(NL) :: ileft ! index of left grid mesh
89 INTEGER, DIMENSION(NL) :: iright ! index of right grid mesh
90 INTEGER, DIMENSION(NL) :: itop ! index of top grid mesh
91 INTEGER, DIMENSION(NL) :: ibottom ! index of bottom grid mesh
92 !
93 !* 0.3 Declaration of counters inside a grid (JL)
94 ! -----------------------
95 !
96 INTEGER :: iho2counterjp ! number of times where h/2 has been summed for JP coef
97 INTEGER :: iho2counterjm ! number of times where h/2 has been summed for JM coef
98 INTEGER :: iho2counterip ! number of times where h/2 has been summed for IP coef
99 INTEGER :: iho2counterim ! number of times where h/2 has been summed for IM coef
100 INTEGER :: iaoscounter ! number of segments where A/S has been summed
101 INTEGER :: iaosdist ! distance between first and last subsquares used in
102 ! ! computation of A/S in a subsegment of the grid
103 LOGICAL :: gfirst ! T indicates the first point has been found for this segment.
104 !
105 !* 0.4 Declaration of working arrays inside a grid (JL)
106 ! -----------------------------
107 !
108 REAL, DIMENSION(NSSO) :: zaosip ! A/S in each subsegment for IP coef.
109 REAL, DIMENSION(NSSO) :: zaosim ! A/S in each subsegment for IM coef.
110 REAL, DIMENSION(NSSO) :: zaosjp ! A/S in each subsegment for JP coef.
111 REAL, DIMENSION(NSSO) :: zaosjm ! A/S in each subsegment for JM coef.
112 REAL :: zaip ! Area in a subsegment for IP coef.
113 REAL :: zaim ! Area in a subsegment for IM coef.
114 REAL :: zajp ! Area in a subsegment for JP coef.
115 REAL :: zajm ! Area in a subsegment for JM coef.
116 REAL :: zsumho2ip ! sum of h/2 in the grid for IP coef.
117 REAL :: zsumho2im ! sum of h/2 in the grid for IM coef.
118 REAL :: zsumho2jp ! sum of h/2 in the grid for JP coef.
119 REAL :: zsumho2jm ! sum of h/2 in the grid for JM coef.
120 REAL :: zssaos ! A/S between 2 following points along a subsegment
121 REAL :: zslope ! slope between 2 following points along a subsegment
122 REAL :: zdxeff ! width of a subsquare along I axis
123 REAL :: zdyeff ! width of a subsquare along J axis
124 !
125 !* 0.5 Declaration of other local variables
126 ! ------------------------------------
127 !
128 REAL, DIMENSION(NL) :: zdx ! grid mesh size in x direction
129 REAL, DIMENSION(NL) :: zdy ! grid mesh size in y direction
130 REAL, DIMENSION(0:NL) :: zslopeip ! x mean slope
131 REAL, DIMENSION(0:NL) :: zslopejp ! y mean slope
132 REAL(KIND=JPRB) :: zhook_handle
133 !----------------------------------------------------------------------------
134 !
135 !* 1. Initializations
136 ! ---------------
137 !
138 !* 1.1 Occurence of computation of the coefficients
139 ! --------------------------------------------
140 !
141 IF (lhook) CALL dr_hook('SUBSCALE_AOS',0,zhook_handle)
142 oz0effi(:)=.false.
143 oz0effj(:)=.false.
144 !
145 !* 1.2 Grid dimension (meters)
146 ! -----------------------
147 !
148  CALL get_mesh_dim(cgrid,ngrid_par,nl,xgrid_par,zdx,zdy,ug%XMESH_SIZE)
149 !
150 !
151 !* 1.3 Left, top, right and bottom adjacent gris meshes
152 ! ------------------------------------------------
153 !
154  CALL get_adjacent_meshes(cgrid,ngrid_par,nl,xgrid_par,ileft,iright,itop,ibottom)
155 !
156 !
157 !* 1.4 Mean slopes between 2 grid meshes
158 ! -----------
159 !
160 zslopeip(0) = 0.
161 zslopejp(0) = 0.
162 !
163 DO jl=1,nl
164  IF (iright(jl)/=0 .AND. ileft(jl)/=0) THEN
165  zslopeip(jl) = 0.5 * ( uss%XAVG_ZS(iright(jl)) - uss%XAVG_ZS(jl) ) &
166  / ( 0.5 * (zdx(iright(jl)) + zdx(jl)) ) &
167  + 0.5 * ( uss%XAVG_ZS(jl) - uss%XAVG_ZS(ileft(jl)) ) &
168  / ( 0.5 * (zdx(jl) + zdx(ileft(jl))) )
169  ELSE
170  zslopeip(jl) = 0.
171  END IF
172  IF (itop(jl)/=0 .AND. ibottom(jl)/=0) THEN
173  zslopejp(jl) = 0.5 * ( uss%XAVG_ZS(itop(jl)) - uss%XAVG_ZS(jl) ) &
174  / ( 0.5 * (zdy(itop(jl)) + zdy(jl)) ) &
175  + 0.5 * ( uss%XAVG_ZS(jl) - uss%XAVG_ZS(ibottom(jl)) ) &
176  / ( 0.5 * (zdy(jl) + zdy(ibottom(jl))) )
177  ELSE
178  zslopejp(jl) = 0.
179  END IF
180 END DO
181 !
182 !----------------------------------------------------------------------------
183 !
184 !* 2. Loop on grid points
185 ! -------------------
186 !
187 DO jl=1,nl
188 !
189 !* 2.1 No land in grid mesh
190 ! --------------------
191 !
192  IF (psea(jl)==1.) cycle
193 !
194 !* 2.2 Index Initializations
195 ! ---------------------
196 !
197  zdxeff=zdx(jl)/float(nsso)
198  zdyeff=zdy(jl)/float(nsso)
199 !
200 !----------------------------------------------------------------------------
201 !
202 !* 3. Computations for IP and IM fields
203 ! ---------------------------------
204 !
205  zaosip(:)=0.
206  zaosim(:)=0.
207  zsumho2ip=0.
208  zsumho2im=0.
209  iho2counterip=0
210  iho2counterim=0
211  iaoscounter=0
212 !
213 !* 3.1 loop on jss index (there is no specific computation along j)
214 ! -----------------
215 !
216  DO jjss=1,nsso
217 !
218 !* 3.1.1 initializes counters for the A/S subscale segment computation
219 !
220  gfirst = .true.
221  iaosdist=0
222  zaip=0.
223  zaim=0.
224 !
225 !* 3.2 loop on iss index
226 ! -----------------
227 !
228  DO jiss=1,nsso
229 !
230 !* 3.3 search for two consecutive grid points
231 ! --------------------------------------
232 !
233 !* 3.3.1 first one
234 !
235  IF (.NOT. lssqo(jiss,jjss,jl) ) cycle
236 !
237 !* 3.3.2 second one (up to one grid mesh further)
238 !
239  DO jnext=1,nsso
240  IF (jiss+jnext>nsso) THEN
241  il = iright(jl)
242  inext = jiss+jnext-nsso
243  ELSE
244  il = jl
245  inext = jiss+jnext
246  END IF
247  ! no right point
248  IF (il==0) EXIT
249  ! subgrid data found
250  IF (lssqo(inext,jjss,il)) EXIT
251  END DO
252 !
253 !* 3.3.3 none found: end of loop along jss
254 ! ---------------------
255 !
256  IF (jnext>=nsso+1) EXIT
257 !
258 !* 3.3.4 second point outside of the domain: end of loop along iss
259 ! ---------------------
260 !
261  IF (il==0) EXIT
262 !
263 !* 3.4 add terms to sums of A/S and h/2
264 ! --------------------------------
265 !
266  IF (gfirst) iaoscounter=iaoscounter+1
267  gfirst = .false.
268  iaosdist =iaosdist+jnext
269 !
270 !* 3.4.1 mean slope
271 !
272  zslope=zslopeip(jl)
273 !
274 !* 3.4.2 A/S term
275 !
276  zssaos = xssqo(inext,jjss,il) - xssqo(jiss,jjss,jl) &
277  - zslope * zdxeff * jnext
278  IF (zssaos>0.) zaip=zaip+zssaos
279  IF (zssaos<0.) zaim=zaim-zssaos
280 !
281 !* 3.4.3 h/2 term
282 !
283  IF (zssaos>0.) THEN
284  zsumho2ip = zsumho2ip + 0.5 * zssaos
285  iho2counterip=iho2counterip+1
286  END IF
287  IF (zssaos<0.) THEN
288  zsumho2im = zsumho2im - 0.5 * zssaos
289  iho2counterim=iho2counterim+1
290  END IF
291 !
292 !* 3.5 end of loop on iss index
293 ! ------------------------
294 !
295  END DO
296  IF (iaosdist>0) THEN
297  zaosip(jjss)=zaip/(zdxeff*iaosdist)
298  zaosim(jjss)=zaim/(zdxeff*iaosdist)
299  END IF
300 !
301 !* 3.6 end of loop on jss index
302 ! ------------------------
303 !
304  END DO
305 !
306 !* 3.7 end of IP and IM coefficients
307 ! -----------------------------
308 !
309  IF (iaoscounter>0) THEN
310  uss%XAOSIP(jl)=sum(zaosip) / iaoscounter
311  uss%XAOSIM(jl)=sum(zaosim) / iaoscounter
312  IF (iho2counterip>0) THEN
313  uss%XHO2IP(jl)=zsumho2ip / iho2counterip
314  ELSE
315  uss%XHO2IP(jl)=0.
316  END IF
317  IF (iho2counterim>0) THEN
318  uss%XHO2IM(jl)=zsumho2im / iho2counterim
319  ELSE
320  uss%XHO2IM(jl)=0.
321  END IF
322  oz0effi(jl)=.true.
323  END IF
324 !
325 !----------------------------------------------------------------------------
326 !
327 !* 4. Computations for JP and JM fields
328 ! ---------------------------------
329 !
330  zaosjp(:)=0.
331  zaosjm(:)=0.
332  zsumho2jp=0.
333  zsumho2jm=0.
334  iho2counterjp=0
335  iho2counterjm=0
336  iaoscounter=0
337 !
338 !* 4.1 loop on iss index (there is no specific computation along i)
339 ! -----------------
340 !
341  DO jiss=1,nsso
342 !
343 !* 4.1.1 initializes counters for the A/S subscale segment computation
344 !
345  gfirst = .true.
346  iaosdist=0
347  zajp=0.
348  zajm=0.
349 !
350 !* 4.2 loop on jss index
351 ! -----------------
352 !
353  DO jjss=1,nsso
354 !
355 !* 4.3 search for two consecutive grid points
356 ! --------------------------------------
357 !
358 !* 4.3.1 first one
359 !
360  IF (.NOT. lssqo(jiss,jjss,jl) ) cycle
361 !
362 !* 4.3.2 second one (up to one grid mesh further)
363 !
364  DO jnext=1,nsso
365  IF (jjss+jnext>nsso) THEN
366  il = itop(jl)
367  inext = jjss+jnext-nsso
368  ELSE
369  il = jl
370  inext = jjss+jnext
371  END IF
372  ! no right point
373  IF (il==0) EXIT
374  ! subgrid data found
375  IF (lssqo(jiss,inext,il)) EXIT
376  END DO
377 !
378 !* 4.3.3 none found: end of loop along jss
379 ! ---------------------
380 !
381  IF (jnext>=nsso+1) EXIT
382 !
383 !* 4.3.4 second point outside of the domain: end of loop along iss
384 ! ---------------------
385 !
386  IF (il==0) EXIT
387 !
388 !
389 !* 4.4 add terms to sums of A/S and h/2
390 ! --------------------------------
391 !
392  IF (gfirst) iaoscounter=iaoscounter+1
393  gfirst = .false.
394  iaosdist =iaosdist+jnext
395 !
396 !* 4.4.1 mean slope
397 !
398  zslope=zslopejp(jl)
399 !
400 !* 4.4.2 A/S term
401 !
402  zssaos = xssqo(jiss,inext,il) - xssqo(jiss,jjss,jl) &
403  - zslope * zdyeff * jnext
404  IF (zssaos>0.) zajp=zajp+zssaos
405  IF (zssaos<0.) zajm=zajm-zssaos
406 !
407 !* 4.4.3 h/2 term
408 !
409  IF (zssaos>0.) THEN
410  zsumho2jp = zsumho2jp + 0.5 * zssaos
411  iho2counterjp=iho2counterjp+1
412  END IF
413  IF (zssaos<0.) THEN
414  zsumho2jm = zsumho2jm - 0.5 * zssaos
415  iho2counterjm=iho2counterjm+1
416  END IF
417 !
418 !* 4.5 end of loop on jss index
419 ! ------------------------
420 !
421  END DO
422  IF (iaosdist>0) THEN
423  zaosjp(jiss)=zajp/(zdyeff*iaosdist)
424  zaosjm(jiss)=zajm/(zdyeff*iaosdist)
425  END IF
426 !
427 !* 4.6 end of loop on iss index
428 ! ------------------------
429 !
430  END DO
431 !
432 !* 4.7 end of JP and JM coefficients
433 ! -----------------------------
434 !
435  IF (iaoscounter>0) THEN
436  uss%XAOSJP(jl)=sum(zaosjp) /iaoscounter
437  uss%XAOSJM(jl)=sum(zaosjm) /iaoscounter
438  IF (iho2counterjp>0) THEN
439  uss%XHO2JP(jl)=zsumho2jp /iho2counterjp
440  ELSE
441  uss%XHO2JP(jl)=0.
442  END IF
443  IF (iho2counterjm>0) THEN
444  uss%XHO2JM(jl)=zsumho2jm /iho2counterjm
445  ELSE
446  uss%XHO2JM(jl)=0.
447  END IF
448  oz0effj(jl)=.true.
449  END IF
450 !
451 !-------------------------------------------------------------------------------
452 !
453 !* 5. Next grid point
454 ! ---------------
455 !
456 END DO
457 IF (lhook) CALL dr_hook('SUBSCALE_AOS',1,zhook_handle)
458 !
459 !-------------------------------------------------------------------------------
460 !
461 END SUBROUTINE subscale_aos
subroutine get_adjacent_meshes(HGRID, KGRID_PAR, KL, PGRID_PAR, KLEFT, KRIGHT, KTOP, KBOTTOM)
subroutine get_mesh_dim(HGRID, KGRID_PAR, KL, PGRID_PAR, PDX, PDY, PMESHSIZE)
Definition: get_mesh_dim.F90:6
subroutine subscale_aos(UG, USS, OZ0EFFI, OZ0EFFJ, PSEA)
Definition: subscale_aos.F90:6