SURFEX v8.1
General documentation of Surfex
get_mesh_index_lonlat_reg.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_lonlat_reg(KSSO,PGRID_PAR,PLAT,PLON,&
7  KINDEX,KISSOX,KISSOY,PVALUE,PNODATA)
8 ! ###############################################################
9 !
10 !!**** *GET_MESH_INDEX_LONLAT_REG* 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 modd_surfex_omp, ONLY : nblocktot
31 USE modd_surfex_mpi, ONLY : nrank
35 !
36 USE modd_point_overlay, ONLY : novmx
37 !
38 USE yomhook ,ONLY : lhook, dr_hook
39 USE parkind1 ,ONLY : jprb
40 !
41 IMPLICIT NONE
42 !
43 !* 0.1 Declaration of arguments
44 ! ------------------------
45 !
46 INTEGER, INTENT(IN) :: KSSO ! number of subgrid mesh in each direction
47 REAL, DIMENSION(:), INTENT(IN) :: PGRID_PAR ! grid parameters
48 REAL, DIMENSION(:), INTENT(IN) :: PLAT ! latitude of the point
49 REAL, DIMENSION(:), INTENT(IN) :: PLON ! longitude of the point
50 INTEGER, DIMENSION(:,:), INTENT(OUT) :: KINDEX ! index of the grid mesh where the point is
51 INTEGER, DIMENSION(:,:), INTENT(OUT) :: KISSOX ! X index of the subgrid mesh
52 INTEGER, DIMENSION(:,:), INTENT(OUT) :: KISSOY ! Y index of the subgrid mesh
53 !
54 REAL, DIMENSION(:), OPTIONAL, INTENT(IN) :: PVALUE ! value of the point to add
55 REAL, OPTIONAL, INTENT(IN) :: PNODATA
56 !
57 !* 0.2 Declaration of other local variables
58 ! ------------------------------------
59 !
60 INTEGER :: JI ! loop counter in x
61 INTEGER :: JJ ! loop counter in y
62 INTEGER :: JL ! loop counter on input points
63 !
64 REAL :: ZLONMIN ! minimum longitude (degrees)
65 REAL :: ZLONMAX ! maximum longitude (degrees)
66 REAL :: ZLATMIN ! minimum latitude (degrees)
67 REAL :: ZLATMAX ! maximum latitude (degrees)
68 REAL :: ZDLON ! longitude grid size
69 REAL :: ZDLAT ! latitude grid size
70 !
71 REAL :: ZNODATA
72 !
73 REAL, DIMENSION(SIZE(PLAT)) :: ZVALUE
74 !
75 REAL, DIMENSION(SIZE(PLON)) :: ZLON
76 !
77 INTEGER, DIMENSION(SIZE(PLAT)) :: ICI, ICJ
78 !
79 INTEGER :: IFACTLON, ISIZELON, IFACTLAT, ISIZELAT, ISIZE_OMP
80 !
81 REAL(KIND=JPRB) :: ZHOOK_HANDLE, ZHOOK_HANDLE_OMP
82 !
83 !----------------------------------------------------------------------------
84 !
85 IF (lhook) CALL dr_hook('GET_MESH_INDEX_LONLAT_REG_1',0,zhook_handle)
86 !
87 IF (PRESENT(pvalue) .AND. PRESENT(pnodata)) THEN
88  zvalue(:) = pvalue(:)
89  znodata = pnodata
90 ELSE
91  zvalue(:) = 1
92  znodata = 0
93 ENDIF
94 !
95 IF (.NOT. ALLOCATED(xlatlim)) THEN
96 !
97 !* 1. Uncode parameters of the grid
98 ! -----------------------------
99 !
100  CALL get_gridtype_lonlat_reg(pgrid_par,zlonmin,zlonmax, &
101  zlatmin,zlatmax,nlon,nlat )
102 !
103 !----------------------------------------------------------------------------
104 !
105 !* 2. Limits of grid meshes
106 ! ---------------------
107 !
108  zdlon = (zlonmax-zlonmin) / float(nlon)
109  zdlat = (zlatmax-zlatmin) / float(nlat)
110 !
111  ALLOCATE(xlonlim(nlon+1))
112  DO ji=1,nlon+1
113  xlonlim(ji) = zlonmin + float(ji-1)*zdlon
114  END DO
115 
116  ALLOCATE(xlatlim(nlat+1))
117  DO ji=1,nlat+1
118  xlatlim(ji) = zlatmin + float(ji-1)*zdlat
119  END DO
120  !
121  xlon0 = 0.5*(zlonmin+zlonmax)
122  !
123  ifactlon = floor(sqrt(float(nlon+1))) + 1
124  isizelon = floor(float(nlon+1) / ifactlon)
125  ALLOCATE(nfracdlon(ifactlon+1))
126  DO jj=1,ifactlon
127  nfracdlon(jj) = 1 + (jj-1) * isizelon
128  ENDDO
129  nfracdlon(ifactlon+1) = nlon+1
130  !
131  ifactlat = floor(sqrt(float(nlat+1))) + 1
132  isizelat = floor(float(nlat+1) / ifactlat)
133  ALLOCATE(nfracdlat(ifactlat+1))
134  DO jj=1,ifactlat
135  nfracdlat(jj) = 1 + (jj-1) * isizelat
136  ENDDO
137  nfracdlat(ifactlat+1) = nlat+1
138  !
139 END IF
140 IF (lhook) CALL dr_hook('GET_MESH_INDEX_LONLAT_REG_1',1,zhook_handle)
141 !----------------------------------------------------------------------------
142 !
143 !* 3. Reshifts the longitudes with respect to projection reference point
144 ! ------------------------------------------------------------------
145 !
146 !
147 !$OMP PARALLEL PRIVATE(ZHOOK_HANDLE_OMP)
148 IF (lhook) CALL dr_hook('GET_MESH_INDEX_LONLAT_REG_2',0,zhook_handle_omp)
149 !$OMP DO PRIVATE(JL)
150 DO jl = 1,SIZE(plon)
151  IF (plon(jl)>=xlon0+360.) THEN
152  zlon(jl) = plon(jl) - 360.
153  ELSEIF (plon(jl)<=xlon0-360.) THEN
154  zlon(jl) = plon(jl) + 360.
155  ELSE
156  zlon(jl) = plon(jl)
157  ENDIF
158 ENDDO
159 !$OMP END DO
160 IF (lhook) CALL dr_hook('GET_MESH_INDEX_LONLAT_REG_2',1,zhook_handle_omp)
161 !$OMP END PARALLEL
162 !
163 !ZLON(JL) = PLON(JL)+NINT((XLON0-PLON(JL))/360.)*360.
164 !
165 !----------------------------------------------------------------------------
166 !
167 !* 4. Localisation of the data points on (x,y) grid
168 ! ---------------------------------------------
169 !
170 IF (lhook) CALL dr_hook('GET_MESH_INDEX_LONLAT_REG_2b',0,zhook_handle)
171 !
172 !IF (SIZE(PLAT)/=NLON*NLAT) THEN
173 ! KINDEX = 0
174 ! KISSOX = 0
175 ! KISSOY = 0
176 !END IF
177 !
178 ifactlat = SIZE(nfracdlat)-1
179 ifactlon = SIZE(nfracdlon)-1
180 !
181 IF (lhook) CALL dr_hook('GET_MESH_INDEX_LONLAT_REG_2b',1,zhook_handle)
182 !
183 isize_omp = max(1,SIZE(plat)/nblocktot)
184 !
185 !$OMP PARALLEL PRIVATE(ZHOOK_HANDLE_OMP)
186 IF (lhook) CALL dr_hook('GET_MESH_INDEX_LONLAT_REG_3',0,zhook_handle_omp)
187 !$OMP DO SCHEDULE(STATIC,ISIZE_OMP) PRIVATE(JL,JJ,JI)
188 DO jl=1,SIZE(plat)
189  !
190  ici(jl) = 0
191  icj(jl) = 0
192  !
193  IF (zvalue(jl)==znodata) cycle
194  !
195  IF ( zlon(jl)<xlonlim(1) .OR. zlon(jl)>=xlonlim(nlon+1) &
196  .OR. plat(jl)<xlatlim(1) .OR. plat(jl)>=xlatlim(nlat+1) ) cycle
197  !
198  fraclat: &
199  DO jj = ifactlat,1,-1
200  IF (plat(jl)>xlatlim(nfracdlat(jj))) THEN
201  DO ji = nfracdlat(jj+1),nfracdlat(jj)+1,-1
202  IF (plat(jl)>=xlatlim(ji)) THEN
203  icj(jl) = ji
204  EXIT fraclat
205  ENDIF
206  ENDDO
207  icj(jl) = nfracdlat(jj)
208  EXIT fraclat
209  ENDIF
210  ENDDO fraclat
211  !
212  fraclon: &
213  DO jj = ifactlon,1,-1
214  IF (zlon(jl)>xlonlim(nfracdlon(jj))) THEN
215  DO ji = nfracdlon(jj+1),nfracdlon(jj)+1,-1
216  IF (zlon(jl)>=xlonlim(ji)) THEN
217  ici(jl) = ji
218  EXIT fraclon
219  ENDIF
220  ENDDO
221  ici(jl) = nfracdlon(jj)
222  EXIT fraclon
223  ENDIF
224  ENDDO fraclon
225  !
226 ENDDO
227 !$OMP END DO
228 IF (lhook) CALL dr_hook('GET_MESH_INDEX_LONLAT_REG_3',1,zhook_handle_omp)
229 !$OMP END PARALLEL
230 !
231 !$OMP PARALLEL PRIVATE(ZHOOK_HANDLE_OMP)
232 IF (lhook) CALL dr_hook('GET_MESH_INDEX_LONLAT_REG_4',0,zhook_handle_omp)
233 !$OMP DO PRIVATE(JL,JI,JJ)
234 DO jl=1,SIZE(plat)
235  !
236  IF (novmx>1) kindex(2:novmx,jl) = 0
237  !
238  IF (zvalue(jl)==znodata) THEN
239  !
240  kindex(1,jl) = 0
241  !
242  ELSEIF ( ici(jl)==0 .OR. icj(jl)==0 ) THEN
243  !
244  kindex(1,jl) = 0
245  !
246  IF (ksso/=0) THEN
247  kissox(1,jl) = 0
248  kissoy(1,jl) = 0
249  ENDIF
250  !
251  ELSE
252 
253  ji = ici(jl)
254  jj = icj(jl)
255  kindex(1,jl) = (jj-1) * nlon + ji
256 !
257 !
258 !* 6. Localisation of the data points on in the subgrid of this mesh
259 ! --------------------------------------------------------------
260 !
261  IF (ksso/=0) THEN
262  kissox(1,jl) = 1 + int( float(ksso) * (zlon(jl)-xlonlim(ji))/(xlonlim(ji+1)-xlonlim(ji)) )
263  kissoy(1,jl) = 1 + int( float(ksso) * (plat(jl)-xlatlim(jj))/(xlatlim(jj+1)-xlatlim(jj)) )
264  END IF
265 
266  ENDIF
267 
268 END DO
269 !$OMP END DO
270 IF (lhook) CALL dr_hook('GET_MESH_INDEX_LONLAT_REG_4',1,zhook_handle_omp)
271 !$OMP END PARALLEL
272 !
273 !-------------------------------------------------------------------------------
274 !
275 END SUBROUTINE get_mesh_index_lonlat_reg
subroutine get_mesh_index_lonlat_reg(KSSO, PGRID_PAR, PLAT, PLON, KINDEX, KISSOX, KISSOY, PVALUE, PNODATA)
real, dimension(:), allocatable xlatlim
integer, parameter jprb
Definition: parkind1.F90:32
subroutine get_gridtype_lonlat_reg(PGRID_PAR, PLONMIN, PLONMAX, PLATMIN, PLATMAX, KLON, KLAT, KL, PLON, PLAT)
integer, dimension(:), allocatable nfracdlon
logical lhook
Definition: yomhook.F90:15
integer, dimension(:), allocatable nfracdlat
real, dimension(:), allocatable xlonlim