SURFEX  V8_0
Surfex V8_0 release
 All Classes Files Functions Variables
get_mesh_index_gauss.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 get_mesh_index_gauss(KNBLINES,KGRID_PAR,KSSO,PGRID_PAR,PLAT,PLON,&
7  kindex,kissox,kissoy,pvalue,pnodata)
8 ! ###############################################################
9 !
10 !!**** *GET_MESH_INDEX_GAUSS* get the grid mesh where point (lat,lon) is located
11 !!
12 !! PURPOSE
13 !! -------
14 !!
15 !! AUTHOR
16 !! ------
17 !!
18 !! V. Masson Meteo-France
19 !!
20 !! MODIFICATION
21 !! ------------
22 !!
23 !! Original 12/09/95
24 !!
25 !----------------------------------------------------------------------------
26 !
27 !* 0. DECLARATION
28 ! -----------
29 !
30 USE eggangles,ONLY : lola, angle_domain
31 !
32 USE modd_get_mesh_index_gauss, ONLY : xxcen, xycen, xyinf, xysup, xxinf, xxsup, &
33  nnlati, nnlopa, xlapo, xlopo, xcodil, xsints, &
34  xlon, xlat, xcost, xsintc, xcosn, xsinn, xlonp, &
35  xlatp, xcosp, xsinp, xpi, x1, x2, xdr, &
36  nfracdx, nfracgx, nfracdy, nfacty, xxdif, xydif,&
37  lrotstretch
38 !
40 !
41 USE yomhook ,ONLY : lhook, dr_hook
42 USE parkind1 ,ONLY : jprb
43 !
44 IMPLICIT NONE
45 !
46 !* 0.1 Declaration of arguments
47 ! ------------------------
48 !
49 INTEGER, INTENT(IN) :: knblines
50 INTEGER, INTENT(IN) :: kgrid_par ! size of PGRID_PAR
51 INTEGER, INTENT(IN) :: ksso ! number of subgrid mesh in each direction
52 REAL, DIMENSION(:), INTENT(IN) :: pgrid_par ! grid parameters
53 REAL, DIMENSION(:), INTENT(IN) :: plat ! latitude of the point (degrees)
54 REAL, DIMENSION(:), INTENT(IN) :: plon ! longitude of the point (degrees)
55 INTEGER, DIMENSION(:,:), INTENT(OUT) :: kindex ! index of the grid mesh where the point is
56 INTEGER, DIMENSION(:,:), INTENT(OUT) :: kissox ! X index of the subgrid mesh
57 INTEGER, DIMENSION(:,:), INTENT(OUT) :: kissoy ! Y index of the subgrid mesh
58 !
59 REAL, DIMENSION(:), OPTIONAL, INTENT(IN) :: pvalue ! value of the point to add
60 REAL, OPTIONAL, INTENT(IN) :: pnodata
61 
62 !
63 !* 0.2 Declaration of other local variables
64 ! ------------------------------------
65 !
66 REAL, DIMENSION(SIZE(PLAT)) :: zx, zy ! pseudo longitude of input point
67 REAL, DIMENSION(SIZE(PLAT)) :: zvalue
68 REAL :: zpc2
69 REAL :: znodata
70 !
71 INTEGER, DIMENSION(SIZE(PLAT)) :: icj
72 INTEGER :: ilgrid, isize ! number of grid points
73 INTEGER :: ifactx, isizex, isizey
74 INTEGER :: ji, jj, jl ! loop counter in x
75 INTEGER :: jgrid, igrid0 ! loop counter on grid points
76 !
77 REAL(KIND=JPRB) :: zhook_handle
78 !----------------------------------------------------------------------------
79 !
80 IF (lhook) CALL dr_hook('GET_MESH_INDEX_GAUSS_1',0,zhook_handle)
81 !
82 IF (present(pvalue) .AND. present(pnodata)) THEN
83  zvalue(:) = pvalue(:)
84  znodata = pnodata
85 ELSE
86  zvalue(:) = 1
87  znodata = 0
88 ENDIF
89 !
90 kindex(:,:) = 0
91 kissox(:,:) = 0
92 kissoy(:,:) = 0
93 !
94 IF (.NOT. ALLOCATED(nnlopa)) THEN
95  !
96  !* 1. Gets parameters of the projection
97  ! ---------------------------------
98  !
99  xpi = 4.*atan(1.)
100  xdr = xpi / 180.
101  !
102  CALL get_gridtype_gauss(pgrid_par,nnlati,kl=ilgrid)
103  !
104  ALLOCATE(nnlopa(0:nnlati))
105  ALLOCATE(xxcen(ilgrid))
106  ALLOCATE(xycen(ilgrid))
107  CALL get_gridtype_gauss(pgrid_par,nnlati,xlapo,xlopo,xcodil,nnlopa(1:nnlati), &
108  ilgrid,plat_xy=xycen,plon_xy=xxcen )
109  nnlopa(0) = 0
110  !
111  zpc2 = xcodil*xcodil
112  x1 = 1.0-zpc2
113  x2 = 1.0+zpc2
114  !
115  xlonp = angle_domain(xlopo,dom='0+',unit='D') * xdr
116  xlatp = xlapo * xdr
117  !
118  xcosp = cos(xlatp)
119  xsinp = sin(xlatp)
120  !
121  !* 2. Limits of grid meshes in x and y
122  ! --------------------------------
123  !
124  ALLOCATE(xxinf(ilgrid))
125  ALLOCATE(xyinf(ilgrid))
126  ALLOCATE(xxsup(ilgrid))
127  ALLOCATE(xysup(ilgrid))
128  ALLOCATE(xxdif(ilgrid))
129  ALLOCATE(xydif(ilgrid))
130  !
131  CALL gauss_grid_limits(nnlati,nnlopa(1:nnlati),xxinf,xxsup,xyinf,xysup)
132  DO jj=1,ilgrid
133  xxdif(jj) = 1. / (xxsup(jj) - xxinf(jj))
134  xydif(jj) = 1. / (xysup(jj) - xyinf(jj))
135  ENDDO
136  !
137  ifactx = floor(sqrt(float(nnlati))) + 1
138  isizex = floor(float(nnlati) / ifactx)
139  !
140  ALLOCATE(nfracdx(0:ifactx))
141  ALLOCATE(nfracgx(0:ifactx))
142  !
143  nfracdx(0) = 0
144  nfracgx(0) = 1
145  nfracdx(1) = 1
146  nfracgx(1) = 1
147  nfracdx(ifactx) = nnlati
148  nfracgx(ifactx) = sum(nnlopa(:))
149  DO jj=2,ifactx-1
150  nfracdx(jj) = 1 + (jj-1) * isizex
151  nfracgx(jj) = nfracgx(jj-1) + sum(nnlopa(nfracdx(jj-1):(jj-1)*isizex))
152  ENDDO
153  !
154  !
155  ALLOCATE(nfacty(nnlati))
156  nfacty(:) = floor(sqrt(float(nnlopa(1:nnlati))))+1
157  !
158  ALLOCATE(nfracdy(nnlati,0:maxval(nfacty)))
159  !
160  DO jj=1,nnlati
161  isizey = floor(float(nnlopa(jj)) / nfacty(jj))
162  nfracdy(jj,0) = 0
163  nfracdy(jj,1) = 1
164  nfracdy(jj,nfacty(jj)) = nnlopa(jj)
165  DO ji=2,nfacty(jj)-1
166  nfracdy(jj,ji) = 1 + (ji-1) * isizey
167  ENDDO
168  ENDDO
169  !
170  !* 3. Find if rotated pole and/or stretching to improve CPU time
171  ! ----------------------------------------------------------
172  !
173  lrotstretch = .true.
174  IF (xcodil==1.0.AND.xlapo==90.0.AND.xlopo==0.0) lrotstretch = .false.
175  !
176 ENDIF
177 !
178 isize = SIZE(plat)/knblines
179 !
180 IF (ALLOCATED(xlon)) THEN
181  IF ( isize/=SIZE(xlon) .OR. knblines/=SIZE(xlat) ) THEN
182  DEALLOCATE(xlon)
183  DEALLOCATE(xlat)
184  DEALLOCATE(xcost)
185  DEALLOCATE(xsintc)
186  DEALLOCATE(xsints)
187  DEALLOCATE(xcosn)
188  DEALLOCATE(xsinn)
189  ENDIF
190 ENDIF
191 !
192 IF (.NOT.ALLOCATED(xlon)) THEN
193  !
194  ALLOCATE(xlon(isize))
195  ALLOCATE(xlat(knblines))
196  !
197  ALLOCATE(xcost(SIZE(xlat)))
198  ALLOCATE(xsintc(SIZE(xlat)))
199  ALLOCATE(xsints(SIZE(xlat)))
200  ALLOCATE(xcosn(SIZE(xlon)))
201  ALLOCATE(xsinn(SIZE(xlon)))
202  !
203  xlon(:) = angle_domain(plon(1:isize),dom='0+',unit='D') * xdr
204  xcosn(:) = cos(xlon(:)-xlonp)
205  xsinn(:) = sin(xlon(:)-xlonp)
206  !
207 ENDIF
208 !
209 IF (lhook) CALL dr_hook('GET_MESH_INDEX_GAUSS_1',1,zhook_handle)
210 IF (lhook) CALL dr_hook('GET_MESH_INDEX_GAUSS_2',0,zhook_handle)
211 
212 !
213 !* 3. Projection of input points into pseudo coordinates
214 ! --------------------------------------------------
215 !
216 DO jj=1,knblines
217  xlat(jj) = plat(jj*isize) * xdr
218  xsintc(jj) = sin(xlat(jj)) * xcosp
219  xsints(jj) = sin(xlat(jj)) * xsinp
220  xcost(jj) = cos(xlat(jj))
221 ENDDO
222 !
223 IF (lrotstretch) THEN
224  CALL xy_gauss(xcodil,isize,znodata,zvalue,zy,zx)
225 ELSE
226  zx(:) = plon(:)
227  zy(:) = plat(:)
228 ENDIF
229 !
230 IF (lhook) CALL dr_hook('GET_MESH_INDEX_GAUSS_2',1,zhook_handle)
231 IF (lhook) CALL dr_hook('GET_MESH_INDEX_GAUSS_3',0,zhook_handle)
232 !
233 !-------------------------------------------------------------------------------
234 !
235 !* 5. Localisation of the data points on (x,y) grid
236 ! ---------------------------------------------
237 !
238 icj(:) = 0
239 !
240 ifactx = SIZE(nfracdx)
241 !$OMP PARALLEL DO PRIVATE(JJ,JI,JGRID)
242 DO jl=1,SIZE(plat)
243  !
244  IF (zvalue(jl)==znodata) cycle
245  !
246  fracx: &
247  DO jj=1,ifactx
248  !
249  IF (zy(jl)>=xyinf(nfracgx(jj))) THEN
250  !
251  jgrid = nfracgx(jj-1)
252  !
253  DO ji=nfracdx(jj-1)+1,nfracdx(jj)-1
254  !
255  jgrid = jgrid + nnlopa(ji-1)
256  !
257  IF (zy(jl)>=xyinf(jgrid)) THEN
258  !
259  icj(jl) = ji
260  EXIT fracx
261  !
262  ENDIF
263  !
264  ENDDO
265  !
266  icj(jl) = nfracdx(jj)
267  !
268  exit fracx
269  !
270  ENDIF
271  !
272  ENDDO fracx
273  !
274 ENDDO
275 !$OMP END PARALLEL DO
276 !
277 IF (lhook) CALL dr_hook('GET_MESH_INDEX_GAUSS_3',1,zhook_handle)
278 IF (lhook) CALL dr_hook('GET_MESH_INDEX_GAUSS_4',0,zhook_handle)
279 !
280 !$OMP PARALLEL DO PRIVATE(IGRID0,JGRID,JI,JJ)
281 DO jl=1,SIZE(plat)
282  !
283  IF (zvalue(jl)==znodata) cycle
284  !
285  igrid0 = 0
286  IF (icj(jl)/=1) igrid0 = sum(nnlopa(1:icj(jl)-1))
287  !
288  !* loop on grid points: longitude
289  fracy: &
290  DO jj = 1,nfacty(icj(jl))
291  !
292  IF (zx(jl)<xxsup(igrid0+nfracdy(icj(jl),jj))) THEN
293  !
294  jgrid = igrid0 + nfracdy(icj(jl),jj-1)
295  !
296  DO ji=nfracdy(icj(jl),jj-1)+1,nfracdy(icj(jl),jj)
297  !
298  jgrid = jgrid + 1
299  IF (zx(jl)<=xxcen(jgrid)-180. .AND. zx(jl)<xxsup(jgrid)-360.) zx(jl) = zx(jl) + 360.
300  !* imput point is in this grid mesh
301  IF (zx(jl)>=xxinf(jgrid) .AND. zx(jl)<xxsup(jgrid)) THEN
302  !
303  kindex(1,jl) = jgrid
304  !
305  EXIT fracy
306  !
307  ENDIF
308  !
309  ENDDO
310  !
311  END IF
312  !
313  END DO fracy
314  !
315 END DO
316 !$OMP END PARALLEL DO
317 !
318 IF (lhook) CALL dr_hook('GET_MESH_INDEX_GAUSS_4',1,zhook_handle)
319 IF (lhook) CALL dr_hook('GET_MESH_INDEX_GAUSS_5',0,zhook_handle)
320 !
321 !* 6. Localisation of the data points on in the subgrid of this mesh
322 ! --------------------------------------------------------------
323 !
324 IF (ksso/=0) THEN
325 !$OMP PARALLEL DO
326  DO jl=1,SIZE(plat)
327  IF (kindex(1,jl)/=0) THEN
328  kissox(1,jl) = 1 + int( float(ksso) * (zx(jl)-xxinf(kindex(1,jl)))/(xxsup(kindex(1,jl))-xxinf(kindex(1,jl))) )
329  kissoy(1,jl) = 1 + int( float(ksso) * (zy(jl)-xyinf(kindex(1,jl)))/(xysup(kindex(1,jl))-xyinf(kindex(1,jl))) )
330  ENDIF
331  ENDDO
332 !$OMP END PARALLEL DO
333 ENDIF
334 !
335 IF (lhook) CALL dr_hook('GET_MESH_INDEX_GAUSS_5',1,zhook_handle)
336 !-------------------------------------------------------------------------------
337 !
338 END SUBROUTINE get_mesh_index_gauss
subroutine get_gridtype_gauss(PGRID_PAR, KNLATI, PLAPO, PLOPO, PCODIL, KNLOPA, KL, PLAT, PLON, PLAT_XY, PLON_XY, PMESH_SIZE, PLONINF, PLATINF, PLONSUP, PLATSUP)
subroutine gauss_grid_limits(KNLATI, KNLOPA, PXINF, PXSUP, PYINF, PYSUP)
subroutine get_mesh_index_gauss(KNBLINES, KGRID_PAR, KSSO, PGRID_PAR, PLAT, PLON, KINDEX, KISSOX, KISSOY, PVALUE, PNODATA)
subroutine xy_gauss(PCODIL, KSIZE, PNODATA, PVALUE, PLAT_XY, PLON_XY)