New URL for NEMO forge!   http://forge.nemo-ocean.eu

Since March 2022 along with NEMO 4.2 release, the code development moved to a self-hosted GitLab.
This present forge is now archived and remained online for history.
obs_grid_search_bruteforce.h90 in branches/nemo_v3_3_beta/NEMOGCM/NEMO/OPA_SRC/OBS – NEMO

source: branches/nemo_v3_3_beta/NEMOGCM/NEMO/OPA_SRC/OBS/obs_grid_search_bruteforce.h90 @ 2287

Last change on this file since 2287 was 2287, checked in by smasson, 14 years ago

update licence of all NEMO files...

  • Property svn:keywords set to Id
File size: 14.2 KB
Line 
1   !!----------------------------------------------------------------------
2   !! NEMO/OPA 3.3 , NEMO Consortium (2010)
3   !! $Id$
4   !! Software governed by the CeCILL licence (NEMOGCM/NEMO_CeCILL.txt)
5   !!----------------------------------------------------------------------
6
7   SUBROUTINE obs_grid_search_bruteforce( kpi, kpj, kpiglo, kpjglo,       &
8      &                                   kldi, klei, kldj, klej,         &
9      &                                   kmyproc, ktotproc,              &
10      &                                   pglam, pgphi, pmask,            &
11      &                                   kobs, plam, pphi, kobsi, kobsj, &
12      &                                   kproc)
13      !!----------------------------------------------------------------------
14      !!                ***  ROUTINE obs_grid_search_bruteforce ***
15      !!
16      !! ** Purpose : Search gridpoints to find the grid box containing
17      !!              the observations
18      !!
19      !! ** Method  : Call to linquad
20      !!
21      !! ** Action  : Return kproc holding the observation and kiobsi,kobsj
22      !!              valid on kproc=kmyproc processor only.
23      !!   
24      !! History :
25      !!        !  2001-11  (N. Daget, A. Weaver)
26      !!        !  2006-03  (A. Weaver) NEMOVAR migration.
27      !!        !  2006-05  (K. Mogensen) Moved to to separate routine.
28      !!        !  2007-10  (A. Vidard) Bug fix in wrap around checks; cleanup
29      !!----------------------------------------------------------------------
30
31      !! * Arguments
32      INTEGER, INTENT(IN) :: kpi                ! Number of local longitudes
33      INTEGER, INTENT(IN) :: kpj                ! Number of local latitudes
34      INTEGER, INTENT(IN) :: kpiglo             ! Number of global longitudes
35      INTEGER, INTENT(IN) :: kpjglo             ! Number of global latitudes
36      INTEGER, INTENT(IN) :: kldi               ! Start of inner domain in i
37      INTEGER, INTENT(IN) :: klei               ! End of inner domain in i
38      INTEGER, INTENT(IN) :: kldj               ! Start of inner domain in j
39      INTEGER, INTENT(IN) :: klej               ! End of inner domain in j
40      INTEGER, INTENT(IN) :: kmyproc            ! Processor number for MPP
41      INTEGER, INTENT(IN) :: ktotproc           ! Total number of processors
42      REAL(KIND=wp), DIMENSION(kpi,kpj), INTENT(IN) :: &
43         & pglam,   &               ! Grid point longitude
44         & pgphi,   &               ! Grid point latitude
45         & pmask                    ! Grid point mask
46      INTEGER,INTENT(IN) :: kobs                ! Size of the observation arrays
47      REAL(KIND=wp), DIMENSION(kobs), INTENT(IN) :: &
48         & plam, &                  ! Longitude of obsrvations
49         & pphi                     ! Latitude of observations
50      INTEGER, DIMENSION(kobs), INTENT(OUT) :: &
51         & kobsi, &                 ! I-index of observations
52         & kobsj, &                 ! J-index of observations
53         & kproc                    ! Processor number of observations
54 
55      !! * Local declarations
56      REAL(wp), DIMENSION(:), ALLOCATABLE :: &
57         & zplam, zpphi
58      REAL(wp) :: zlammax
59      REAL(wp) :: zlam
60      INTEGER :: ji
61      INTEGER :: jj
62      INTEGER :: jk
63      INTEGER :: jo
64      INTEGER :: jlon
65      INTEGER :: jlat
66      INTEGER :: joffset
67      INTEGER :: jostride
68      REAL(KIND=wp), DIMENSION(:,:), ALLOCATABLE :: &
69         & zlamg, &
70         & zphig, &
71         & zmskg, &
72         & zphitmax,&
73         & zphitmin,&
74         & zlamtmax,&
75         & zlamtmin
76      LOGICAL, DIMENSION(:,:), ALLOCATABLE :: &
77         & llinvalidcell
78      REAL(wp), DIMENSION(:,:,:), ALLOCATABLE :: &
79         & zlamtm,  &
80         & zphitm
81
82      !-----------------------------------------------------------------------
83      ! Define grid setup for grid search
84      !-----------------------------------------------------------------------
85      IF (ln_grid_global) THEN
86         jlon     = kpiglo
87         jlat     = kpjglo
88         joffset  = kmyproc
89         jostride = ktotproc
90      ELSE
91         jlon     = kpi
92         jlat     = kpj
93         joffset  = 0
94         jostride = 1
95      ENDIF
96      !-----------------------------------------------------------------------
97      ! Set up data for grid search
98      !-----------------------------------------------------------------------
99      ALLOCATE( &
100         & zlamg(jlon,jlat),             &
101         & zphig(jlon,jlat),             &
102         & zmskg(jlon,jlat),             &
103         & zphitmax(jlon-1,jlat-1),      &
104         & zphitmin(jlon-1,jlat-1),      &
105         & zlamtmax(jlon-1,jlat-1),      &
106         & zlamtmin(jlon-1,jlat-1),      &
107         & llinvalidcell(jlon-1,jlat-1), &
108         & zlamtm(4,jlon-1,jlat-1),      &
109         & zphitm(4,jlon-1,jlat-1)       &
110         & )
111      !-----------------------------------------------------------------------
112      ! Copy data to local arrays
113      !-----------------------------------------------------------------------
114      IF (ln_grid_global) THEN
115         zlamg(:,:) = -1.e+10
116         zphig(:,:) = -1.e+10
117         zmskg(:,:) = -1.e+10
118         DO jj = kldj, klej
119            DO ji = kldi, klei
120               zlamg(mig(ji),mjg(jj)) = pglam(ji,jj)
121               zphig(mig(ji),mjg(jj)) = pgphi(ji,jj)
122               zmskg(mig(ji),mjg(jj)) = pmask(ji,jj)
123            END DO
124         END DO
125         CALL mpp_global_max( zlamg )
126         CALL mpp_global_max( zphig )
127         CALL mpp_global_max( zmskg )
128      ELSE
129         DO jj = 1, jlat
130            DO ji = 1, jlon
131               zlamg(ji,jj) = pglam(ji,jj)
132               zphig(ji,jj) = pgphi(ji,jj)
133               zmskg(ji,jj) = pmask(ji,jj)
134            END DO
135         END DO
136      ENDIF
137      !-----------------------------------------------------------------------
138      ! Copy longitudes and latitudes
139      !-----------------------------------------------------------------------
140      ALLOCATE( &
141         & zplam(kobs), &
142         & zpphi(kobs)  &
143         & )
144      DO jo = 1, kobs
145         zplam(jo) = plam(jo)
146         zpphi(jo) = pphi(jo)
147      END DO
148      !-----------------------------------------------------------------------
149      ! Set default values for output
150      !-----------------------------------------------------------------------
151      kproc(:) = -1
152      kobsi(:) = -1
153      kobsj(:) = -1
154      !-----------------------------------------------------------------------
155      ! Copy grid positions to temporary arrays and renormalize to 0 to 360.
156      !-----------------------------------------------------------------------
157      DO jj = 1, jlat-1
158         DO ji = 1, jlon-1
159            zlamtm(1,ji,jj) = zlamg(ji  ,jj  )
160            zphitm(1,ji,jj) = zphig(ji  ,jj  )
161            zlamtm(2,ji,jj) = zlamg(ji+1,jj  )
162            zphitm(2,ji,jj) = zphig(ji+1,jj  )
163            zlamtm(3,ji,jj) = zlamg(ji+1,jj+1)
164            zphitm(3,ji,jj) = zphig(ji+1,jj+1)
165            zlamtm(4,ji,jj) = zlamg(ji  ,jj+1)
166            zphitm(4,ji,jj) = zphig(ji  ,jj+1)
167         END DO
168      END DO
169      WHERE ( zlamtm(:,:,:) < 0.0_wp )
170         zlamtm(:,:,:) = zlamtm(:,:,:) + 360.0_wp
171      END WHERE
172      WHERE ( zlamtm(:,:,:) > 360.0_wp )
173         zlamtm(:,:,:) = zlamtm(:,:,:) - 360.0_wp
174      END WHERE
175      !-----------------------------------------------------------------------
176      ! Handle case of the wraparound; beware, not working with orca180
177      !-----------------------------------------------------------------------
178      DO jj = 1, jlat-1
179         DO ji = 1, jlon-1
180            zlammax = MAXVAL( zlamtm(:,ji,jj) )
181            WHERE (zlammax - zlamtm(:, ji, jj) > 180 ) &
182               & zlamtm(:,ji,jj) = zlamtm(:,ji,jj) + 360._wp
183            zphitmax(ji,jj) = MAXVAL(zphitm(:,ji,jj))
184            zphitmin(ji,jj) = MINVAL(zphitm(:,ji,jj))
185            zlamtmax(ji,jj) = MAXVAL(zlamtm(:,ji,jj))
186            zlamtmin(ji,jj) = MINVAL(zlamtm(:,ji,jj))
187         END DO
188      END DO
189      !-----------------------------------------------------------------------
190      ! Search for boxes with only land points mark them invalid
191      !-----------------------------------------------------------------------
192      llinvalidcell(:,:) = .FALSE.
193      DO jj = 1, jlat-1
194         DO ji = 1, jlon-1
195            llinvalidcell(ji,jj) =               &
196               & zmskg(ji  ,jj  ) == 0.0_wp .AND. &
197               & zmskg(ji+1,jj  ) == 0.0_wp .AND. &
198               & zmskg(ji+1,jj+1) == 0.0_wp .AND. &
199               & zmskg(ji  ,jj+1) == 0.0_wp
200         END DO
201      END DO
202
203      !------------------------------------------------------------------------
204      ! Master loop for grid search
205      !------------------------------------------------------------------------
206
207      DO jo = 1+joffset, kobs, jostride
208
209         !---------------------------------------------------------------------
210         ! Ensure that all observation longtiudes are between 0 and 360
211         !---------------------------------------------------------------------
212
213         IF ( zplam(jo) <   0.0_wp ) zplam(jo) = zplam(jo) + 360.0_wp
214         IF ( zplam(jo) > 360.0_wp ) zplam(jo) = zplam(jo) - 360.0_wp
215
216         !---------------------------------------------------------------------
217         ! Find observations which are on within 1e-6 of a grid point
218         !---------------------------------------------------------------------
219
220         gridloop: DO jj = 1, jlat-1
221            DO ji = 1, jlon-1
222               IF ( ABS( zphig(ji,jj) - zpphi(jo) ) < 1e-6 )  THEN
223                  zlam = zlamg(ji,jj)
224                  IF ( zlam <   0.0_wp ) zlam = zlam + 360.0_wp
225                  IF ( zlam > 360.0_wp ) zlam = zlam - 360.0_wp
226                  IF ( ABS( zlam - zplam(jo) ) < 1e-6 ) THEN
227                     IF ( llinvalidcell(ji,jj) ) THEN
228                        kproc(jo) = kmyproc + 1000000
229                        kobsi(jo) = ji + 1
230                        kobsj(jo) = jj + 1
231                        CYCLE
232                     ELSE
233                        kproc(jo) = kmyproc
234                        kobsi(jo) = ji + 1
235                        kobsj(jo) = jj + 1
236                        EXIT gridloop
237                     ENDIF
238                  ENDIF
239               ENDIF
240            END DO
241         END DO gridloop
242         
243         !---------------------------------------------------------------------
244         ! Ensure that all observation longtiudes are between -180 and 180
245         !---------------------------------------------------------------------
246
247         IF ( zplam(jo) > 180 ) zplam(jo) = zplam(jo) - 360.0_wp
248
249         !---------------------------------------------------------------------
250         ! Do coordinate search using brute force.
251         ! - For land points kproc is set to number of the processor + 1000000
252         !   and we continue the search.
253         ! - For ocean points kproc is set to the number of the processor
254         !   and we stop the search.
255         !---------------------------------------------------------------------
256
257         IF ( kproc(jo) == -1 ) THEN
258
259            ! Normal case
260            gridpoints : DO jj = 1, jlat-1
261               DO ji = 1, jlon-1
262                 
263                  IF ( ( zplam(jo) > zlamtmax(ji,jj) ) .OR. &
264                     & ( zplam(jo) < zlamtmin(ji,jj) ) ) CYCLE
265                 
266                  IF ( ABS( zpphi(jo) ) < 85 ) THEN
267                     IF ( ( zpphi(jo) > zphitmax(ji,jj) ) .OR. &
268                        & ( zpphi(jo) < zphitmin(ji,jj) ) ) CYCLE
269                  ENDIF
270                 
271                  IF ( linquad( zplam(jo), zpphi(jo), &
272                     &          zlamtm(:,ji,jj), zphitm(:,ji,jj) ) ) THEN
273                     IF ( llinvalidcell(ji,jj) ) THEN
274                        kproc(jo) = kmyproc + 1000000
275                        kobsi(jo) = ji + 1
276                        kobsj(jo) = jj + 1
277                        CYCLE
278                     ELSE
279                        kproc(jo) = kmyproc
280                        kobsi(jo) = ji + 1
281                        kobsj(jo) = jj + 1
282                        EXIT gridpoints
283                     ENDIF
284                  ENDIF
285                 
286               END DO
287            END DO gridpoints
288
289         ENDIF
290
291         ! In case of failure retry for obs. longtiude + 360.
292         IF ( kproc(jo) == -1 ) THEN
293            gridpoints_greenwich : DO jj = 1, jlat-1
294               DO ji = 1, jlon-1
295
296                  IF ( ( zplam(jo)+360.0_wp > zlamtmax(ji,jj) ) .OR. &
297                     & ( zplam(jo)+360.0_wp < zlamtmin(ji,jj) ) ) CYCLE
298
299                  IF ( ABS( zpphi(jo) ) < 85 ) THEN
300                     IF ( ( zpphi(jo) > zphitmax(ji,jj) ) .OR. &
301                        & ( zpphi(jo) < zphitmin(ji,jj) ) ) CYCLE
302                  ENDIF
303
304                  IF ( linquad( zplam(jo)+360.0_wp, zpphi(jo), &
305                     &          zlamtm(:,ji,jj), zphitm(:,ji,jj) ) ) THEN
306                     IF ( llinvalidcell(ji,jj) ) THEN
307                        kproc(jo) = kmyproc + 1000000
308                        kobsi(jo) = ji + 1
309                        kobsj(jo) = jj + 1
310                        CYCLE
311                     ELSE
312                        kproc(jo) = kmyproc
313                        kobsi(jo) = ji + 1
314                        kobsj(jo) = jj + 1
315                        EXIT gridpoints_greenwich
316                     ENDIF
317                  ENDIF
318
319               END DO
320            END DO gridpoints_greenwich
321
322         ENDIF
323      END DO
324
325      !----------------------------------------------------------------------
326      ! Synchronize kproc on all processors
327      !----------------------------------------------------------------------
328      IF ( ln_grid_global ) THEN
329         CALL obs_mpp_max_integer( kproc, kobs )
330         CALL obs_mpp_max_integer( kobsi, kobs )
331         CALL obs_mpp_max_integer( kobsj, kobs )
332      ELSE
333         CALL obs_mpp_find_obs_proc( kproc, kobsi, kobsj, kobs )
334      ENDIF
335
336      WHERE( kproc(:) >= 1000000 )
337         kproc(:) = kproc(:) - 1000000
338      END WHERE
339
340      DEALLOCATE( &
341         & zlamg,         &
342         & zphig,         &
343         & zmskg,         &
344         & zphitmax,      &
345         & zphitmin,      &
346         & zlamtmax,      &
347         & zlamtmin,      &
348         & llinvalidcell, &
349         & zlamtm,        &
350         & zphitm,        &
351         & zplam,         &
352         & zpphi          &
353         & )
354
355   END SUBROUTINE obs_grid_search_bruteforce
Note: See TracBrowser for help on using the repository browser.