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.
lbc_nfd_nogather_generic.h90 in NEMO/branches/2021/dev_r14312_MPI_Interface/src/OCE/LBC – NEMO

source: NEMO/branches/2021/dev_r14312_MPI_Interface/src/OCE/LBC/lbc_nfd_nogather_generic.h90 @ 14314

Last change on this file since 14314 was 14314, checked in by smasson, 3 years ago

dev_r14312_MPI_Interface: first implementation, #2598

  • Property svn:keywords set to Id
  • Property svn:mime-type set to text/x-fortran
File size: 18.2 KB
Line 
1#if defined MULTI
2#   define NAT_IN(k)                cd_nat(k)   
3#   define SGN_IN(k)                psgn(k)
4#   define F_SIZE(ptab)             kfld
5#   if defined DIM_2d
6#      if defined SINGLE_PRECISION
7#         define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_2D_sp),INTENT(inout)::ptab(f)
8#      else
9#         define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_2D_dp),INTENT(inout)::ptab(f)
10#      endif 
11#      define ARRAY_IN(i,j,k,l,f)      ptab(f)%pt2d(i,j)
12#      define K_SIZE(ptab)             1
13#      define L_SIZE(ptab)             1
14#   endif
15#   if defined DIM_3d
16#      if defined SINGLE_PRECISION
17#         define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_3D_sp),INTENT(inout)::ptab(f)
18#      else
19#         define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_3D_dp),INTENT(inout)::ptab(f)
20#      endif 
21#      define ARRAY_IN(i,j,k,l,f)      ptab(f)%pt3d(i,j,k)
22#      define K_SIZE(ptab)             SIZE(ptab(1)%pt3d,3)
23#      define L_SIZE(ptab)             1
24#   endif
25#   if defined DIM_4d
26#      if defined SINGLE_PRECISION
27#         define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_4D_sp),INTENT(inout)::ptab(f)
28#      else
29#         define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_4D_dp),INTENT(inout)::ptab(f)
30#      endif 
31#      define ARRAY_IN(i,j,k,l,f)      ptab(f)%pt4d(i,j,k,l)
32#      define K_SIZE(ptab)             SIZE(ptab(1)%pt4d,3)
33#      define L_SIZE(ptab)             SIZE(ptab(1)%pt4d,4)
34#   endif
35#   if defined SINGLE_PRECISION
36#      define ARRAY2_TYPE(i,j,k,l,f)   TYPE(PTR_4D_sp),INTENT(inout)::ptab2(f)
37#   else
38#      define ARRAY2_TYPE(i,j,k,l,f)   TYPE(PTR_4D_dp),INTENT(inout)::ptab2(f)
39#   endif
40#   define J_SIZE(ptab2)            SIZE(ptab2(1)%pt4d,2)
41#   define ARRAY2_IN(i,j,k,l,f)     ptab2(f)%pt4d(i,j,k,l)
42#else
43!                          !==  IN: ptab is an array  ==!
44#   define NAT_IN(k)                cd_nat
45#   define SGN_IN(k)                psgn
46#   define F_SIZE(ptab)             1
47#   if defined DIM_2d
48#      define ARRAY_IN(i,j,k,l,f)   ptab(i,j)
49#      define K_SIZE(ptab)          1
50#      define L_SIZE(ptab)          1
51#   endif
52#   if defined DIM_3d
53#      define ARRAY_IN(i,j,k,l,f)   ptab(i,j,k)
54#      define K_SIZE(ptab)          SIZE(ptab,3)
55#      define L_SIZE(ptab)          1
56#   endif
57#   if defined DIM_4d
58#      define ARRAY_IN(i,j,k,l,f)   ptab(i,j,k,l)
59#      define K_SIZE(ptab)          SIZE(ptab,3)
60#      define L_SIZE(ptab)          SIZE(ptab,4)
61#   endif
62#   define J_SIZE(ptab2)             SIZE(ptab2,2)
63#   define ARRAY2_IN(i,j,k,l,f)   ptab2(i,j,k,l)
64#   if defined SINGLE_PRECISION
65#      define ARRAY_TYPE(i,j,k,l,f)     REAL(sp),INTENT(inout)::ARRAY_IN(i,j,k,l,f)
66#      define ARRAY2_TYPE(i,j,k,l,f)    REAL(sp),INTENT(inout)::ARRAY2_IN(i,j,k,l,f)
67#   else
68#      define ARRAY_TYPE(i,j,k,l,f)     REAL(dp),INTENT(inout)::ARRAY_IN(i,j,k,l,f)
69#      define ARRAY2_TYPE(i,j,k,l,f)    REAL(dp),INTENT(inout)::ARRAY2_IN(i,j,k,l,f)
70#   endif
71#   endif
72#   ifdef SINGLE_PRECISION
73#      define PRECISION sp
74#   else
75#      define PRECISION dp
76#   endif
77   SUBROUTINE ROUTINE_NFD( ptab, ptab2, cd_nat, psgn, kfld )
78      !!----------------------------------------------------------------------
79      !!
80      !! ** Purpose :   lateral boundary condition : North fold treatment
81      !!                without allgather exchanges.
82      !!
83      !!----------------------------------------------------------------------
84      ARRAY_TYPE(:,:,:,:,:)
85      ARRAY2_TYPE(:,:,:,:,:) 
86      CHARACTER(len=1) , INTENT(in   ) ::   NAT_IN(:)   ! nature of array grid-points
87      REAL(PRECISION)  , INTENT(in   ) ::   SGN_IN(:)   ! sign used across the north fold boundary
88      INTEGER, OPTIONAL, INTENT(in   ) ::   kfld        ! number of pt3d arrays
89      !
90      INTEGER  ::    ji,  jj,   jk, jn, ii,   jl,   jh,  jf   ! dummy loop indices
91      INTEGER  ::   ipi, ipj,  ipk,    ipl,  ipf, iij, ijj   ! dimension of the input array
92      INTEGER  ::   ijt, iju, ijta, ijua, jia, startloop, endloop
93      LOGICAL  ::   l_fast_exchanges
94      !!----------------------------------------------------------------------
95      ipj = J_SIZE(ptab2)  ! 2nd dimension of input array
96      ipk = K_SIZE(ptab)   ! 3rd dimension of output array
97      ipl = L_SIZE(ptab)   ! 4th    -
98      ipf = F_SIZE(ptab)   ! 5th    -      use in "multi" case (array of pointers)
99      !
100      ! Security check for further developments
101      IF ( ipf > 1 ) CALL ctl_stop( 'STOP', 'lbc_nfd_nogather: multiple fields not allowed. Revise implementation...' )
102      ! 2nd dimension determines exchange speed
103      IF (ipj == 1 ) THEN
104        l_fast_exchanges = .TRUE.
105      ELSE
106        l_fast_exchanges = .FALSE.
107      ENDIF
108      !
109      DO jf = 1, ipf                      ! Loop over the number of arrays to be processed
110         !
111         IF( l_NFoldT ) THEN                 ! *  North fold  T-point pivot
112            !
113            SELECT CASE ( NAT_IN(jf) )
114            !
115            CASE ( 'T' , 'W' )                         ! T-, W-point
116               IF ( nimpp /= 1 ) THEN  ;  startloop = 1 
117               ELSE                    ;  startloop = 1 + nn_hls
118               ENDIF
119               !
120               DO jl = 1, ipl; DO jk = 1, ipk
121                    DO jj = 1, nn_hls
122                       ijj = jpj -jj +1
123                     DO ji = startloop, jpi
124                     ijt = jpiglo - ji - nimpp - nfimpp(isendto(1)) + 4
125                        ARRAY_IN(ji,ijj,jk,jl,jf) = SGN_IN(jf) * ARRAY2_IN(ijt,jj,jk,jl,jf)
126                     END DO
127                  END DO
128               END DO; END DO
129               IF( nimpp == 1 ) THEN
130                  DO jl = 1, ipl; DO jk = 1, ipk
131                     DO jj = 1, nn_hls
132                     ijj = jpj -jj +1
133                     DO ii = 0, nn_hls-1
134                        ARRAY_IN(ii+1,ijj,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(2*nn_hls-ii+1,jpj-2*nn_hls+jj-1,jk,jl,jf)
135                     END DO
136                     END DO
137                  END DO; END DO
138               ENDIF             
139               !
140               IF ( .NOT. l_fast_exchanges ) THEN
141                  IF( nimpp >= Ni0glo/2+2 ) THEN
142                     startloop = 1
143                  ELSEIF( nimpp+jpi-1 >= Ni0glo/2+2 .AND. nimpp < Ni0glo/2+2 ) THEN
144                     startloop = Ni0glo/2+2 - nimpp + nn_hls
145                  ELSE
146                     startloop = jpi + 1
147                  ENDIF
148                  IF( startloop <= jpi ) THEN
149                     DO jl = 1, ipl; DO jk = 1, ipk
150                        DO ji = startloop, jpi
151                           ijt  = jpiglo - ji - nimpp - nfimpp(isendto(1)) + 4
152                           jia  = ji + nimpp - 1
153                           ijta = jpiglo - jia + 2
154                           IF( ijta >= startloop+nimpp-1 .AND. ijta < jia ) THEN
155                              ARRAY_IN(ji,jpj-nn_hls,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(ijta-nimpp+nn_hls,jpj-nn_hls,jk,jl,jf)
156                           ELSE
157                              ARRAY_IN(ji,jpj-nn_hls,jk,jl,jf) = SGN_IN(jf) * ARRAY2_IN(ijt,nn_hls+1,jk,jl,jf)
158                           ENDIF
159                        END DO
160                     END DO; END DO
161                  ENDIF
162               ENDIF
163            CASE ( 'U' )                                     ! U-point
164               IF( nimpp + jpi - 1 /= jpiglo ) THEN
165                  endloop = jpi
166               ELSE
167                  endloop = jpi - nn_hls
168               ENDIF
169               DO jl = 1, ipl; DO jk = 1, ipk
170        DO jj = 1, nn_hls
171              ijj = jpj -jj +1
172                     DO ji = 1, endloop
173                        iju = jpiglo - ji - nimpp - nfimpp(isendto(1)) + 3
174                        ARRAY_IN(ji,ijj,jk,jl,jf) = SGN_IN(jf) * ARRAY2_IN(iju,jj,jk,jl,jf)
175                     END DO
176                  END DO
177               END DO; END DO
178               IF (nimpp .eq. 1) THEN
179        DO jj = 1, nn_hls
180           ijj = jpj -jj +1
181           DO ii = 0, nn_hls-1
182         ARRAY_IN(ii+1,ijj,:,:,jf) = SGN_IN(jf) * ARRAY_IN(2*nn_hls-ii,jpj-2*nn_hls+jj-1,:,:,jf)
183           END DO
184                  END DO
185               ENDIF
186               IF((nimpp + jpi - 1) .eq. jpiglo) THEN
187                  DO jj = 1, nn_hls
188                       ijj = jpj -jj +1
189         DO ii = 1, nn_hls
190               ARRAY_IN(jpi-ii+1,ijj,:,:,jf) = SGN_IN(jf) * ARRAY_IN(jpi-2*nn_hls+ii,jpj-2*nn_hls+jj-1,:,:,jf)
191         END DO
192        END DO
193               ENDIF
194               !
195               IF ( .NOT. l_fast_exchanges ) THEN
196                  IF( nimpp + jpi - 1 /= jpiglo ) THEN
197                     endloop = jpi
198                  ELSE
199                     endloop = jpi - nn_hls
200                  ENDIF
201                  IF( nimpp >= Ni0glo/2+1 ) THEN
202                     startloop = nn_hls
203                  ELSEIF( ( nimpp + jpi - 1 >= Ni0glo/2+1 ) .AND. ( nimpp < Ni0glo/2+1 ) ) THEN
204                     startloop = Ni0glo/2+1 - nimpp + nn_hls 
205                  ELSE
206                     startloop = endloop + 1
207                  ENDIF
208                  IF( startloop <= endloop ) THEN
209                  DO jl = 1, ipl; DO jk = 1, ipk
210                     DO ji = startloop, endloop
211                        iju = jpiglo - ji - nimpp - nfimpp(isendto(1)) + 3
212                        jia = ji + nimpp - 1 
213                        ijua = jpiglo - jia + 1 
214                        IF( ijua >= startloop+nimpp-1 .AND. ijua < jia ) THEN
215                           ARRAY_IN(ji,jpj-nn_hls,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(ijua-nimpp+1,jpj-nn_hls,jk,jl,jf)
216                        ELSE
217                           ARRAY_IN(ji,jpj-nn_hls,jk,jl,jf) = SGN_IN(jf) * ARRAY2_IN(iju,nn_hls+1,jk,jl,jf)
218                        ENDIF
219                     END DO
220                  END DO; END DO
221                  ENDIF
222               ENDIF
223               !
224            CASE ( 'V' )                                     ! V-point
225               IF( nimpp /= 1 ) THEN
226                 startloop = 1 
227               ELSE
228                 startloop = 1 + nn_hls
229               ENDIF
230               IF ( .NOT. l_fast_exchanges ) THEN
231                  DO jl = 1, ipl; DO jk = 1, ipk
232                       DO jj = 2, nn_hls+1
233                     ijj = jpj -jj +1
234                        DO ji = startloop, jpi
235                           ijt=jpiglo - ji - nimpp - nfimpp(isendto(1)) + 4
236                           ARRAY_IN(ji,ijj,jk,jl,jf) = SGN_IN(jf) * ARRAY2_IN(ijt,jj,jk,jl,jf)
237                        END DO
238                    END DO
239                  END DO; END DO
240               ENDIF
241               DO jl = 1, ipl; DO jk = 1, ipk
242                  DO ji = startloop, jpi
243                     ijt=jpiglo - ji - nimpp - nfimpp(isendto(1)) + 4
244                     ARRAY_IN(ji,jpj,jk,jl,jf) = SGN_IN(jf) * ARRAY2_IN(ijt,1,jk,jl,jf)
245                  END DO
246               END DO; END DO
247               IF (nimpp .eq. 1) THEN
248        DO jj = 1, nn_hls
249                       ijj = jpj-jj+1
250                       DO ii = 0, nn_hls-1
251                        ARRAY_IN(ii+1,ijj,:,:,jf) = SGN_IN(jf) * ARRAY_IN(2*nn_hls-ii+1,jpj-2*nn_hls+jj-1,:,:,jf)
252           END DO
253        END DO
254               ENDIF
255            CASE ( 'F' )                                     ! F-point
256               IF( nimpp + jpi - 1 /= jpiglo ) THEN
257                  endloop = jpi
258               ELSE
259                  endloop = jpi - nn_hls
260               ENDIF
261               IF ( .NOT. l_fast_exchanges ) THEN
262                  DO jl = 1, ipl; DO jk = 1, ipk
263                       DO jj = 2, nn_hls+1
264                     ijj = jpj -jj +1
265                        DO ji = 1, endloop
266                           iju = jpiglo - ji - nimpp - nfimpp(isendto(1)) + 3
267                           ARRAY_IN(ji,ijj,jk,jl,jf) = SGN_IN(jf) * ARRAY2_IN(iju,jj,jk,jl,jf)
268                        END DO
269                    END DO
270                  END DO; END DO
271               ENDIF
272               DO jl = 1, ipl; DO jk = 1, ipk
273                  DO ji = 1, endloop
274                     iju = jpiglo - ji - nimpp - nfimpp(isendto(1)) + 3
275                     ARRAY_IN(ji,jpj,jk,jl,jf) = SGN_IN(jf) * ARRAY2_IN(iju,1,jk,jl,jf)
276                  END DO
277               END DO; END DO
278      IF (nimpp .eq. 1) THEN               
279         DO ii = 1, nn_hls
280                 ARRAY_IN(ii,jpj,:,:,jf) = SGN_IN(jf) * ARRAY_IN(2*nn_hls-ii,jpj-2*nn_hls-1,:,:,jf)
281         END DO
282         IF ( .NOT. l_fast_exchanges ) THEN
283            DO jj = 1, nn_hls
284                      ijj = jpj -jj
285                      DO ii = 0, nn_hls-1
286                         ARRAY_IN(ii+1,ijj,:,:,jf) = SGN_IN(jf) * ARRAY_IN(2*nn_hls-ii,jpj-2*nn_hls+jj-1,:,:,jf)
287                   END DO
288                      END DO
289                     ENDIF
290      ENDIF
291      IF((nimpp + jpi - 1 ) .eq. jpiglo) THEN
292                   DO ii = 1, nn_hls
293                 ARRAY_IN(jpi-ii+1,jpj,:,:,jf) = SGN_IN(jf) * ARRAY_IN(jpi-2*nn_hls+ii,jpj-2*nn_hls-1,:,:,jf)
294         END DO
295         IF ( .NOT. l_fast_exchanges ) THEN
296            DO jj = 1, nn_hls
297                           ijj = jpj -jj
298                      DO ii = 1, nn_hls
299                         ARRAY_IN(jpi-ii+1,ijj,:,:,jf) = SGN_IN(jf) * ARRAY_IN(jpi-2*nn_hls+ii,jpj-2*nn_hls+jj-1,:,:,jf)
300                         END DO
301                      END DO
302                     ENDIF
303                  ENDIF
304                  !
305            END SELECT
306            !
307         ENDIF   ! l_NFoldT
308         !
309         IF( l_NFoldF ) THEN                  ! *  North fold  F-point pivot
310            !
311            SELECT CASE ( NAT_IN(jf) )
312            CASE ( 'T' , 'W' )                               ! T-, W-point
313               DO jl = 1, ipl; DO jk = 1, ipk
314        DO jj = 1, nn_hls
315           ijj = jpj-jj+1
316           DO ji = 1, jpi
317                        ijt = jpiglo - ji - nimpp - nfimpp(isendto(1)) + 3
318                        ARRAY_IN(ji,ijj,jk,jl,jf) = SGN_IN(jf) * ARRAY2_IN(ijt,jj,jk,jl,jf)
319                     END DO
320        END DO
321               END DO; END DO
322               !
323            CASE ( 'U' )                                     ! U-point
324               IF( nimpp + jpi - 1 /= jpiglo ) THEN
325                  endloop = jpi
326               ELSE
327                  endloop = jpi - nn_hls
328               ENDIF
329               DO jl = 1, ipl; DO jk = 1, ipk
330        DO jj = 1, nn_hls
331           ijj = jpj-jj+1
332                     DO ji = 1, endloop
333                        iju = jpiglo - ji - nimpp - nfimpp(isendto(1)) + 2
334                        ARRAY_IN(ji,ijj,jk,jl,jf) = SGN_IN(jf) * ARRAY2_IN(iju,jj,jk,jl,jf)
335                     END DO
336                  END DO
337               END DO; END DO
338               IF(nimpp + jpi - 1 .eq. jpiglo) THEN
339                  DO jl = 1, ipl; DO jk = 1, ipk
340                     DO jj = 1, nn_hls
341                          ijj = jpj-jj+1
342                        DO ii = 1, nn_hls
343            iij = jpi-ii+1
344                           ARRAY_IN(iij,ijj,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(jpi-2*nn_hls+ii-1,jpj-2*nn_hls+jj,jk,jl,jf)
345                        END DO
346                     END DO
347                  END DO; END DO
348               ENDIF
349               !
350            CASE ( 'V' )                                     ! V-point
351               DO jl = 1, ipl; DO jk = 1, ipk
352        DO jj = 1, nn_hls
353           ijj = jpj -jj +1
354                     DO ji = 1, jpi
355                        ijt = jpiglo - ji - nimpp - nfimpp(isendto(1)) + 3
356                        ARRAY_IN(ji,ijj,jk,jl,jf) = SGN_IN(jf) * ARRAY2_IN(ijt,jj,jk,jl,jf)
357                     END DO
358                  END DO
359               END DO; END DO
360
361               IF ( .NOT. l_fast_exchanges ) THEN
362                  IF( nimpp >= Ni0glo/2+2 ) THEN
363                     startloop = 1
364                  ELSEIF( nimpp+jpi-1 >= Ni0glo/2+2 .AND. nimpp < Ni0glo/2+2 ) THEN
365                     startloop = Ni0glo/2+2 - nimpp + nn_hls
366                  ELSE
367                     startloop = jpi + 1
368                  ENDIF
369                  IF( startloop <= jpi ) THEN
370                  DO jl = 1, ipl; DO jk = 1, ipk
371                        DO ji = startloop, jpi
372                        ijt = jpiglo - ji - nimpp - nfimpp(isendto(1)) + 3
373                           ARRAY_IN(ji,jpj-nn_hls,jk,jl,jf) = SGN_IN(jf) * ARRAY2_IN(ijt,nn_hls+1,jk,jl,jf)
374                        END DO
375                  END DO; END DO
376                  ENDIF
377               ENDIF
378               !
379            CASE ( 'F' )                               ! F-point
380               IF( nimpp + jpi - 1 /= jpiglo ) THEN
381                  endloop = jpi
382               ELSE
383                  endloop = jpi - nn_hls
384               ENDIF
385               DO jl = 1, ipl; DO jk = 1, ipk
386        DO jj = 1, nn_hls
387          ijj = jpj -jj +1
388                    DO ji = 1, endloop
389                       iju = jpiglo - ji - nimpp - nfimpp(isendto(1)) + 2
390                       ARRAY_IN(ji,ijj ,jk,jl,jf) = SGN_IN(jf) * ARRAY2_IN(iju,jj,jk,jl,jf)
391                     END DO
392                  END DO
393               END DO; END DO
394               IF((nimpp + jpi - 1) .eq. jpiglo) THEN
395                  DO jl = 1, ipl; DO jk = 1, ipk
396                     DO jj = 1, nn_hls
397                        ijj = jpj -jj +1
398                        DO ii = 1, nn_hls
399            iij = jpi -ii+1
400                           ARRAY_IN(iij,ijj,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(jpi-2*nn_hls+ii-1,jpj-2*nn_hls+jj-1,jk,jl,jf)
401                        END DO
402                     END DO
403                  END DO; END DO
404               ENDIF
405               !
406               IF ( .NOT. l_fast_exchanges ) THEN
407                  IF( nimpp + jpi - 1 /= jpiglo ) THEN
408                     endloop = jpi
409                  ELSE
410                     endloop = jpi - nn_hls
411                  ENDIF
412                  IF( nimpp >= Ni0glo/2+2 ) THEN
413                     startloop = 1 
414                  ELSEIF( nimpp+jpi-1 >= Ni0glo/2+2 .AND. nimpp < Ni0glo/2+2 ) THEN
415                     startloop = Ni0glo/2+2 - nimpp + nn_hls
416                  ELSE
417                     startloop = endloop + 1
418                  ENDIF
419                  IF( startloop <= endloop ) THEN
420                     DO jl = 1, ipl; DO jk = 1, ipk
421                        DO ji = startloop, endloop
422                           iju = jpiglo - ji - nimpp - nfimpp(isendto(1)) + 2
423                           ARRAY_IN(ji,jpj-nn_hls,jk,jl,jf) = SGN_IN(jf) * ARRAY2_IN(iju,nn_hls+1,jk,jl,jf)
424                        END DO
425                     END DO; END DO
426                  ENDIF
427               ENDIF
428               !
429            END SELECT
430            !
431         ENDIF   ! l_NFoldF
432         !
433      END DO            ! End jf loop
434   END SUBROUTINE ROUTINE_NFD
435#undef PRECISION
436#undef ARRAY_TYPE
437#undef ARRAY_IN
438#undef NAT_IN
439#undef SGN_IN
440#undef J_SIZE
441#undef K_SIZE
442#undef L_SIZE
443#undef F_SIZE
444#undef ARRAY2_TYPE
445#undef ARRAY2_IN
Note: See TracBrowser for help on using the repository browser.