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.
mpp_nfd_generic.h90 in NEMO/branches/2018/dev_r9759_HPC09_ESIWACE/src/OCE/LBC – NEMO

source: NEMO/branches/2018/dev_r9759_HPC09_ESIWACE/src/OCE/LBC/mpp_nfd_generic.h90 @ 13065

Last change on this file since 13065 was 9926, checked in by smasson, 6 years ago

dev_r9759_HPC09_ESIWACE: report bugixes from NEMO trunk

  • Property svn:mime-type set to text/x-fortran
File size: 10.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#   define LBC_ARG                  (jf)
6#   if defined DIM_2d
7#      define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_2D)     , INTENT(inout) ::   ptab(f)
8#      define ARRAY_IN(i,j,k,l,f)      ptab(f)%pt2d(i,j)
9#      define K_SIZE(ptab)             1
10#      define L_SIZE(ptab)             1
11#   endif
12#   if defined DIM_3d
13#      define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_3D)     , INTENT(inout) ::   ptab(f)
14#      define ARRAY_IN(i,j,k,l,f)      ptab(f)%pt3d(i,j,k)
15#      define K_SIZE(ptab)             SIZE(ptab(1)%pt3d,3)
16#      define L_SIZE(ptab)             1
17#   endif
18#   if defined DIM_4d
19#      define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_4D)     , INTENT(inout) ::   ptab(f)
20#      define ARRAY_IN(i,j,k,l,f)      ptab(f)%pt4d(i,j,k,l)
21#      define K_SIZE(ptab)             SIZE(ptab(1)%pt4d,3)
22#      define L_SIZE(ptab)             SIZE(ptab(1)%pt4d,4)
23#   endif
24#else
25!                          !==  IN: ptab is an array  ==!
26#   define ARRAY_TYPE(i,j,k,l,f)    REAL(wp)         , INTENT(inout) ::   ARRAY_IN(i,j,k,l,f)
27#   define NAT_IN(k)                cd_nat
28#   define SGN_IN(k)                psgn
29#   define F_SIZE(ptab)             1
30#   define LBC_ARG
31#   if defined DIM_2d
32#      define ARRAY_IN(i,j,k,l,f)   ptab(i,j)
33#      define K_SIZE(ptab)          1
34#      define L_SIZE(ptab)          1
35#   endif
36#   if defined DIM_3d
37#      define ARRAY_IN(i,j,k,l,f)   ptab(i,j,k)
38#      define K_SIZE(ptab)          SIZE(ptab,3)
39#      define L_SIZE(ptab)          1
40#   endif
41#   if defined DIM_4d
42#      define ARRAY_IN(i,j,k,l,f)   ptab(i,j,k,l)
43#      define K_SIZE(ptab)          SIZE(ptab,3)
44#      define L_SIZE(ptab)          SIZE(ptab,4)
45#   endif
46#endif
47
48   SUBROUTINE ROUTINE_NFD( ptab, cd_nat, psgn, kfld )
49      !!----------------------------------------------------------------------
50      ARRAY_TYPE(:,:,:,:,:)   ! array or pointer of arrays on which the boundary condition is applied
51      CHARACTER(len=1) , INTENT(in   ) ::   NAT_IN(:)   ! nature of array grid-points
52      REAL(wp)         , INTENT(in   ) ::   SGN_IN(:)   ! sign used across the north fold boundary
53      INTEGER, OPTIONAL, INTENT(in   ) ::   kfld        ! number of pt3d arrays
54      !
55      INTEGER  ::   ji,  jj,  jk,  jl, jh, jf, jr   ! dummy loop indices
56      INTEGER  ::   ipi, ipj, ipk, ipl, ipf         ! dimension of the input array
57      INTEGER  ::   imigr, iihom, ijhom             ! local integers
58      INTEGER  ::   ierr, itaille, ilci, ildi, ilei, iilb
59      INTEGER  ::   ij, iproc
60      INTEGER, DIMENSION (jpmaxngh)       ::   ml_req_nf   ! for mpi_isend when avoiding mpi_allgather
61      INTEGER                             ::   ml_err      ! for mpi_isend when avoiding mpi_allgather
62      INTEGER, DIMENSION(MPI_STATUS_SIZE) ::   ml_stat     ! for mpi_isend when avoiding mpi_allgather
63      !                                                    ! Workspace for message transfers avoiding mpi_allgather
64      REAL(wp), DIMENSION(:,:,:,:,:)  , ALLOCATABLE ::   ztab, ztabl, ztabr
65      REAL(wp), DIMENSION(:,:,:,:,:)  , ALLOCATABLE ::   znorthloc, zfoldwk     
66      REAL(wp), DIMENSION(:,:,:,:,:,:), ALLOCATABLE ::   znorthgloio
67      !!----------------------------------------------------------------------
68      !
69      ipk = K_SIZE(ptab)   ! 3rd dimension
70      ipl = L_SIZE(ptab)   ! 4th    -
71      ipf = F_SIZE(ptab)   ! 5th    -      use in "multi" case (array of pointers)
72      !
73      ipj   = 4            ! 2nd dimension of message transfers (last j-lines)
74      !
75      ALLOCATE( znorthloc(jpimax,4,ipk,ipl,ipf) )
76      !
77      znorthloc(:,:,:,:,:) = 0._wp
78      !
79      DO jf = 1, ipf                ! put in znorthloc the last ipj j-lines of ptab
80         DO jl = 1, ipl
81            DO jk = 1, ipk
82               DO jj = nlcj - ipj +1, nlcj
83                  ij = jj - nlcj + ipj
84                  znorthloc(1:jpi,ij,jk,jl,jf) = ARRAY_IN(1:jpi,jj,jk,jl,jf)
85               END DO
86            END DO
87         END DO
88      END DO
89      !
90      !
91      itaille = jpimax * ipj * ipk * ipl * ipf
92      !
93      IF( l_north_nogather ) THEN      !==  ????  ==!
94         ALLOCATE( zfoldwk(jpimax,4,ipk,ipl,ipf) )
95         ALLOCATE( ztabl(jpimax   ,4,ipk,ipl,ipf) , ztabr(jpimax*jpmaxngh,4,ipk,ipl,ipf) ) 
96         !
97         DO jf = 1, ipf
98            DO jl = 1, ipl
99               DO jk = 1, ipk
100                  DO jj = nlcj-ipj+1, nlcj          ! First put local values into the global array
101                     ij = jj - nlcj + ipj
102                     DO ji = nfsloop, nfeloop
103                        ztabl(ji,ij,jk,jl,jf) = ARRAY_IN(ji,jj,jk,jl,jf)
104                     END DO
105                  END DO
106               END DO
107            END DO
108         END DO
109         !
110         IF (ncom_stp <= ( nit000 + 1 ) .or. mod(ncom_stp,nn_comm_mod) == 0 ) THEN
111         ! start waiting time measurement
112         CALL tic_tac(.TRUE.)
113         !
114         DO jr = 1, nsndto
115            IF( nfipproc(isendto(jr),jpnj) /= narea-1 .AND. nfipproc(isendto(jr),jpnj) /= -1 ) THEN
116              CALL mppsend( 5, znorthloc, itaille, nfipproc(isendto(jr),jpnj), ml_req_nf(jr) )
117            ENDIF
118         END DO
119         DO jr = 1,nsndto
120            iproc = nfipproc(isendto(jr),jpnj)
121            IF(iproc /= -1) THEN
122               iilb = nimppt(iproc+1)
123               ilci = nlcit (iproc+1)
124               ildi = nldit (iproc+1)
125               ilei = nleit (iproc+1)
126               IF( iilb            ==      1 )   ildi = 1      ! e-w boundary already done -> force to take 1st column
127               IF( iilb + ilci - 1 == jpiglo )   ilei = ilci   ! e-w boundary already done -> force to take last column
128               iilb = nfiimpp(isendto(jr),jpnj) - nfiimpp(isendto(1),jpnj)
129            ENDIF
130            IF( iproc /= narea-1 .AND. iproc /= -1 ) THEN
131              CALL mpprecv(5, zfoldwk, itaille, iproc)
132               DO jf = 1, ipf
133                  DO jl = 1, ipl
134                     DO jk = 1, ipk
135                        DO jj = 1, ipj
136                           DO ji = ildi, ilei
137                              ztabr(iilb+ji,jj,jk,jl,jf) = zfoldwk(ji,jj,jk,jl,jf)
138                           END DO
139                        END DO
140                     END DO
141                  END DO
142               END DO
143            ELSE IF( iproc == narea-1 ) THEN
144               DO jf = 1, ipf
145                  DO jl = 1, ipl
146                     DO jk = 1, ipk
147                        DO jj = 1, ipj
148                           DO ji = ildi, ilei
149                              ztabr(iilb+ji,jj,jk,jl,jf) = ARRAY_IN(ji,nlcj-ipj+jj,jk,jl,jf)
150                           END DO
151                        END DO
152                     END DO
153                  END DO
154               END DO
155            ENDIF
156         END DO
157         IF( l_isend ) THEN
158            DO jr = 1,nsndto
159               IF( nfipproc(isendto(jr),jpnj) /= narea-1 .AND. nfipproc(isendto(jr),jpnj) /= -1 ) THEN
160                  CALL mpi_wait( ml_req_nf(jr), ml_stat, ml_err )
161               ENDIF   
162            END DO
163         ENDIF
164         ! stop waiting time measurement
165         CALL tic_tac(.FALSE.)
166         ENDIF
167         !
168         DO jf = 1, ipf
169            CALL lbc_nfd_nogather( ztabl(:,:,:,:,jf), ztabr(:,:,:,:,jf), cd_nat LBC_ARG, psgn LBC_ARG )   ! North fold boundary condition
170         END DO
171         DO jf = 1, ipf
172            DO jl = 1, ipl
173               DO jk = 1, ipk
174                  DO jj = nlcj-ipj+1, nlcj             ! Scatter back to ARRAY_IN
175                     ij = jj - nlcj + ipj
176                     DO ji= 1, nlci
177                        ARRAY_IN(ji,jj,jk,jl,jf) = ztabl(ji,ij,jk,jl,jf)
178                     END DO
179                  END DO
180               END DO
181            END DO
182         END DO
183         !
184         DEALLOCATE( zfoldwk )
185         DEALLOCATE( ztabl, ztabr ) 
186      ELSE                             !==  ????  ==!
187         ALLOCATE( ztab       (jpiglo,4,ipk,ipl,ipf     ) )
188         ALLOCATE( znorthgloio(jpimax,4,ipk,ipl,ipf,jpni) )
189         !
190         IF (ncom_stp <= ( nit000 + 1 ) .or. mod(ncom_stp,nn_comm_mod) == 0 ) THEN
191         ! start waiting time measurement
192         CALL tic_tac(.TRUE.)
193         IF (ncom_stp <= ( nit000 + 1 ) .or. mod(ncom_stp,nn_comm_mod) == 0 ) THEN
194            CALL MPI_ALLGATHER( znorthloc  , itaille, MPI_DOUBLE_PRECISION,                &
195               &                znorthgloio, itaille, MPI_DOUBLE_PRECISION, ncomm_north, ierr )
196         ENDIF
197         !
198         ! stop waiting time measurement
199         CALL tic_tac(.FALSE.)
200         ENDIF
201         !
202         DO jr = 1, ndim_rank_north         ! recover the global north array
203            iproc = nrank_north(jr) + 1
204            iilb  = nimppt(iproc)
205            ilci  = nlcit (iproc)
206            ildi  = nldit (iproc)
207            ilei  = nleit (iproc)
208            IF( iilb            ==      1 )   ildi = 1      ! e-w boundary already done -> force to take 1st column
209            IF( iilb + ilci - 1 == jpiglo )   ilei = ilci   ! e-w boundary already done -> force to take last column
210            DO jf = 1, ipf
211               DO jl = 1, ipl
212                  DO jk = 1, ipk
213                     DO jj = 1, ipj
214                        DO ji = ildi, ilei
215                           ztab(ji+iilb-1,jj,jk,jl,jf) = znorthgloio(ji,jj,jk,jl,jf,jr)
216                        END DO
217                     END DO
218                  END DO
219               END DO
220            END DO
221         END DO
222         DO jf = 1, ipf
223            CALL lbc_nfd( ztab(:,:,:,:,jf), cd_nat LBC_ARG, psgn LBC_ARG )   ! North fold boundary condition
224         END DO
225         !
226         DO jf = 1, ipf
227            DO jl = 1, ipl
228               DO jk = 1, ipk
229                  DO jj = nlcj-ipj+1, nlcj             ! Scatter back to ARRAY_IN
230                     ij = jj - nlcj + ipj
231                     DO ji= 1, nlci
232                        ARRAY_IN(ji,jj,jk,jl,jf) = ztab(ji+nimpp-1,ij,jk,jl,jf)
233                     END DO
234                  END DO
235               END DO
236            END DO
237         END DO
238         !
239      !
240         DEALLOCATE( ztab )
241         DEALLOCATE( znorthgloio )
242      ENDIF
243      !
244      DEALLOCATE( znorthloc )
245      !
246   END SUBROUTINE ROUTINE_NFD
247
248#undef ARRAY_TYPE
249#undef NAT_IN
250#undef SGN_IN
251#undef ARRAY_IN
252#undef K_SIZE
253#undef L_SIZE
254#undef F_SIZE
255#undef LBC_ARG
Note: See TracBrowser for help on using the repository browser.