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_grd_bruteforce.h90 in NEMO/branches/2021/dev_r14116_HPC-10_mcastril_Mixed_Precision_implementation/src/OCE/OBS – NEMO

source: NEMO/branches/2021/dev_r14116_HPC-10_mcastril_Mixed_Precision_implementation/src/OCE/OBS/obs_grd_bruteforce.h90 @ 15540

Last change on this file since 15540 was 15540, checked in by sparonuz, 3 years ago

Mixed precision version, tested up to 30 years on ORCA2.

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