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.
lbcnfd.F90 in branches/2017/dev_rev8689_LIM3_RST/NEMOGCM/NEMO/OPA_SRC/LBC – NEMO

source: branches/2017/dev_rev8689_LIM3_RST/NEMOGCM/NEMO/OPA_SRC/LBC/lbcnfd.F90 @ 8708

Last change on this file since 8708 was 8708, checked in by andmirek, 6 years ago

#1976 improvements in LIM3 restart. Working version

  • Property svn:keywords set to Id
File size: 39.7 KB
Line 
1MODULE lbcnfd
2   !!======================================================================
3   !!                       ***  MODULE  lbcnfd  ***
4   !! Ocean        : north fold  boundary conditions
5   !!======================================================================
6   !! History :  3.2  ! 2009-03  (R. Benshila)  Original code
7   !!            3.5  ! 2013-07 (I. Epicoco, S. Mocavero - CMCC) MPP optimization
8   !!----------------------------------------------------------------------
9
10   !!----------------------------------------------------------------------
11   !!   lbc_nfd       : generic interface for lbc_nfd_3d and lbc_nfd_2d routines
12   !!   lbc_nfd_3d    : lateral boundary condition: North fold treatment for a 3D arrays   (lbc_nfd)
13   !!   lbc_nfd_2d    : lateral boundary condition: North fold treatment for a 2D arrays   (lbc_nfd)
14   !!   mpp_lbc_nfd_3d    : North fold treatment for a 3D arrays optimized for MPP
15   !!   mpp_lbc_nfd_2d    : North fold treatment for a 2D arrays optimized for MPP
16   !!----------------------------------------------------------------------
17   USE dom_oce        ! ocean space and time domain
18   USE in_out_manager ! I/O manager
19
20   IMPLICIT NONE
21   PRIVATE
22
23   INTERFACE lbc_nfd
24      MODULE PROCEDURE   lbc_nfd_3d, lbc_nfd_2d
25   END INTERFACE
26   !
27   INTERFACE mpp_lbc_nfd
28      MODULE PROCEDURE   mpp_lbc_nfd_3d, mpp_lbc_nfd_2d
29   END INTERFACE
30
31   PUBLIC   lbc_nfd       ! north fold conditions
32   PUBLIC   mpp_lbc_nfd   ! north fold conditions (parallel case)
33
34   INTEGER, PUBLIC, PARAMETER            ::   jpmaxngh = 3               !:
35   INTEGER, PUBLIC                       ::   nsndto, nfsloop, nfeloop   !:
36   INTEGER, PUBLIC, DIMENSION (jpmaxngh) ::   isendto                    !: processes to which communicate
37
38   !!----------------------------------------------------------------------
39   !! NEMO/OPA 3.3 , NEMO Consortium (2010)
40   !! $Id$
41   !! Software governed by the CeCILL licence     (NEMOGCM/NEMO_CeCILL.txt)
42   !!----------------------------------------------------------------------
43CONTAINS
44
45   SUBROUTINE lbc_nfd_3d( pt3d, cd_type, psgn )
46      !!----------------------------------------------------------------------
47      !!                  ***  routine lbc_nfd_3d  ***
48      !!
49      !! ** Purpose :   3D lateral boundary condition : North fold treatment
50      !!              without processor exchanges.
51      !!
52      !! ** Method  :   
53      !!
54      !! ** Action  :   pt3d with updated values along the north fold
55      !!----------------------------------------------------------------------
56      CHARACTER(len=1)          , INTENT(in   ) ::   cd_type   ! define the nature of ptab array grid-points
57      !                                                        !   = T , U , V , F , W points
58      REAL(wp)                  , INTENT(in   ) ::   psgn      ! control of the sign change
59      !                                                        !   = -1. , the sign is changed if north fold boundary
60      !                                                        !   =  1. , the sign is kept  if north fold boundary
61      REAL(wp), DIMENSION(:,:,:), INTENT(inout) ::   pt3d      ! 3D array on which the boundary condition is applied
62      !
63      INTEGER  ::   ji, jk
64      INTEGER  ::   ijt, iju, ijpj, ijpjm1, ilev
65      !!----------------------------------------------------------------------
66
67      SELECT CASE ( jpni )
68      CASE ( 1 )     ;   ijpj = nlcj      ! 1 proc only  along the i-direction
69      CASE DEFAULT   ;   ijpj = 4         ! several proc along the i-direction
70      END SELECT
71      ijpjm1 = ijpj-1
72
73      ilev = SIZE(pt3d, 3)
74      DO jk = 1, ilev
75         !
76         SELECT CASE ( npolj )
77         !
78         CASE ( 3 , 4 )                        ! *  North fold  T-point pivot
79            !
80            SELECT CASE ( cd_type )
81            CASE ( 'T' , 'W' )                         ! T-, W-point
82               DO ji = 2, jpiglo
83                  ijt = jpiglo-ji+2
84                  pt3d(ji,ijpj,jk) = psgn * pt3d(ijt,ijpj-2,jk)
85               END DO
86               pt3d(1,ijpj,jk) = psgn * pt3d(3,ijpj-2,jk)
87               DO ji = jpiglo/2+1, jpiglo
88                  ijt = jpiglo-ji+2
89                  pt3d(ji,ijpjm1,jk) = psgn * pt3d(ijt,ijpjm1,jk)
90               END DO
91            CASE ( 'U' )                               ! U-point
92               DO ji = 1, jpiglo-1
93                  iju = jpiglo-ji+1
94                  pt3d(ji,ijpj,jk) = psgn * pt3d(iju,ijpj-2,jk)
95               END DO
96               pt3d(   1  ,ijpj,jk) = psgn * pt3d(    2   ,ijpj-2,jk)
97               pt3d(jpiglo,ijpj,jk) = psgn * pt3d(jpiglo-1,ijpj-2,jk) 
98               DO ji = jpiglo/2, jpiglo-1
99                  iju = jpiglo-ji+1
100                  pt3d(ji,ijpjm1,jk) = psgn * pt3d(iju,ijpjm1,jk)
101               END DO
102            CASE ( 'V' )                               ! V-point
103               DO ji = 2, jpiglo
104                  ijt = jpiglo-ji+2
105                  pt3d(ji,ijpj-1,jk) = psgn * pt3d(ijt,ijpj-2,jk)
106                  pt3d(ji,ijpj  ,jk) = psgn * pt3d(ijt,ijpj-3,jk)
107               END DO
108               pt3d(1,ijpj,jk) = psgn * pt3d(3,ijpj-3,jk) 
109            CASE ( 'F' )                               ! F-point
110               DO ji = 1, jpiglo-1
111                  iju = jpiglo-ji+1
112                  pt3d(ji,ijpj-1,jk) = psgn * pt3d(iju,ijpj-2,jk)
113                  pt3d(ji,ijpj  ,jk) = psgn * pt3d(iju,ijpj-3,jk)
114               END DO
115               pt3d(   1  ,ijpj,jk) = psgn * pt3d(    2   ,ijpj-3,jk)
116               pt3d(jpiglo,ijpj,jk) = psgn * pt3d(jpiglo-1,ijpj-3,jk) 
117            END SELECT
118            !
119         CASE ( 5 , 6 )                        ! *  North fold  F-point pivot
120            !
121            SELECT CASE ( cd_type )
122            CASE ( 'T' , 'W' )                         ! T-, W-point
123               DO ji = 1, jpiglo
124                  ijt = jpiglo-ji+1
125                  pt3d(ji,ijpj,jk) = psgn * pt3d(ijt,ijpj-1,jk)
126               END DO
127            CASE ( 'U' )                               ! U-point
128               DO ji = 1, jpiglo-1
129                  iju = jpiglo-ji
130                  pt3d(ji,ijpj,jk) = psgn * pt3d(iju,ijpj-1,jk)
131               END DO
132               pt3d(jpiglo,ijpj,jk) = psgn * pt3d(1,ijpj-1,jk)
133            CASE ( 'V' )                               ! V-point
134               DO ji = 1, jpiglo
135                  ijt = jpiglo-ji+1
136                  pt3d(ji,ijpj,jk) = psgn * pt3d(ijt,ijpj-2,jk)
137               END DO
138               DO ji = jpiglo/2+1, jpiglo
139                  ijt = jpiglo-ji+1
140                  pt3d(ji,ijpjm1,jk) = psgn * pt3d(ijt,ijpjm1,jk)
141               END DO
142            CASE ( 'F' )                               ! F-point
143               DO ji = 1, jpiglo-1
144                  iju = jpiglo-ji
145                  pt3d(ji,ijpj  ,jk) = psgn * pt3d(iju,ijpj-2,jk)
146               END DO
147               pt3d(jpiglo,ijpj,jk) = psgn * pt3d(1,ijpj-2,jk)
148               DO ji = jpiglo/2+1, jpiglo-1
149                  iju = jpiglo-ji
150                  pt3d(ji,ijpjm1,jk) = psgn * pt3d(iju,ijpjm1,jk)
151               END DO
152            END SELECT
153            !
154         CASE DEFAULT                           ! *  closed : the code probably never go through
155            !
156            SELECT CASE ( cd_type)
157            CASE ( 'T' , 'U' , 'V' , 'W' )             ! T-, U-, V-, W-points
158               pt3d(:, 1  ,jk) = 0.e0
159               pt3d(:,ijpj,jk) = 0.e0
160            CASE ( 'F' )                               ! F-point
161               pt3d(:,ijpj,jk) = 0.e0
162            END SELECT
163            !
164         END SELECT     !  npolj
165         !
166      END DO
167      !
168   END SUBROUTINE lbc_nfd_3d
169
170
171   SUBROUTINE lbc_nfd_2d( pt2d, cd_type, psgn, pr2dj )
172      !!----------------------------------------------------------------------
173      !!                  ***  routine lbc_nfd_2d  ***
174      !!
175      !! ** Purpose :   2D lateral boundary condition : North fold treatment
176      !!       without processor exchanges.
177      !!
178      !! ** Method  :   
179      !!
180      !! ** Action  :   pt2d with updated values along the north fold
181      !!----------------------------------------------------------------------
182      CHARACTER(len=1)        , INTENT(in   ) ::   cd_type   ! define the nature of ptab array grid-points
183      !                                                      ! = T , U , V , F , W points
184      REAL(wp)                , INTENT(in   ) ::   psgn      ! control of the sign change
185      !                                                      !   = -1. , the sign is changed if north fold boundary
186      !                                                      !   =  1. , the sign is kept  if north fold boundary
187      REAL(wp), DIMENSION(:,:), INTENT(inout) ::   pt2d      ! 2D array on which the boundary condition is applied
188      INTEGER , OPTIONAL      , INTENT(in   ) ::   pr2dj     ! number of additional halos
189      !
190      INTEGER  ::   ji, jl, ipr2dj
191      INTEGER  ::   ijt, iju, ijpj, ijpjm1
192      !!----------------------------------------------------------------------
193
194      SELECT CASE ( jpni )
195      CASE ( 1 )     ;   ijpj = nlcj      ! 1 proc only  along the i-direction
196      CASE DEFAULT   ;   ijpj = 4         ! several proc along the i-direction
197      END SELECT
198      !
199      IF( PRESENT(pr2dj) ) THEN           ! use of additional halos
200         ipr2dj = pr2dj
201         IF( jpni > 1 )   ijpj = ijpj + ipr2dj
202      ELSE
203         ipr2dj = 0 
204      ENDIF
205      !
206      ijpjm1 = ijpj-1
207
208
209      SELECT CASE ( npolj )
210      !
211      CASE ( 3, 4 )                       ! *  North fold  T-point pivot
212         !
213         SELECT CASE ( cd_type )
214         !
215         CASE ( 'T' , 'W' )                               ! T- , W-points
216            DO jl = 0, ipr2dj
217               DO ji = 2, jpiglo
218                  ijt=jpiglo-ji+2
219                  pt2d(ji,ijpj+jl) = psgn * pt2d(ijt,ijpj-2-jl)
220               END DO
221            END DO
222            pt2d(1,ijpj)   = psgn * pt2d(3,ijpj-2)
223            DO ji = jpiglo/2+1, jpiglo
224               ijt=jpiglo-ji+2
225               pt2d(ji,ijpj-1) = psgn * pt2d(ijt,ijpj-1)
226            END DO
227         CASE ( 'U' )                                     ! U-point
228            DO jl = 0, ipr2dj
229               DO ji = 1, jpiglo-1
230                  iju = jpiglo-ji+1
231                  pt2d(ji,ijpj+jl) = psgn * pt2d(iju,ijpj-2-jl)
232               END DO
233            END DO
234            pt2d(   1  ,ijpj  ) = psgn * pt2d(    2   ,ijpj-2)
235            pt2d(jpiglo,ijpj  ) = psgn * pt2d(jpiglo-1,ijpj-2)
236            pt2d(1     ,ijpj-1) = psgn * pt2d(jpiglo  ,ijpj-1)   
237            DO ji = jpiglo/2, jpiglo-1
238               iju = jpiglo-ji+1
239               pt2d(ji,ijpjm1) = psgn * pt2d(iju,ijpjm1)
240            END DO
241         CASE ( 'V' )                                     ! V-point
242            DO jl = -1, ipr2dj
243               DO ji = 2, jpiglo
244                  ijt = jpiglo-ji+2
245                  pt2d(ji,ijpj+jl) = psgn * pt2d(ijt,ijpj-3-jl)
246               END DO
247            END DO
248            pt2d( 1 ,ijpj)   = psgn * pt2d( 3 ,ijpj-3) 
249         CASE ( 'F' )                                     ! F-point
250            DO jl = -1, ipr2dj
251               DO ji = 1, jpiglo-1
252                  iju = jpiglo-ji+1
253                  pt2d(ji,ijpj+jl) = psgn * pt2d(iju,ijpj-3-jl)
254               END DO
255            END DO
256            pt2d(   1  ,ijpj)   = psgn * pt2d(    2   ,ijpj-3)
257            pt2d(jpiglo,ijpj)   = psgn * pt2d(jpiglo-1,ijpj-3)
258            pt2d(jpiglo,ijpj-1) = psgn * pt2d(jpiglo-1,ijpj-2)     
259            pt2d(   1  ,ijpj-1) = psgn * pt2d(    2   ,ijpj-2)     
260         CASE ( 'I' )                                     ! ice U-V point (I-point)
261            DO jl = 0, ipr2dj
262               pt2d(2,ijpj+jl) = psgn * pt2d(3,ijpj-1+jl)
263               DO ji = 3, jpiglo
264                  iju = jpiglo - ji + 3
265                  pt2d(ji,ijpj+jl) = psgn * pt2d(iju,ijpj-1-jl)
266               END DO
267            END DO
268         CASE ( 'J' )                                     ! first ice U-V point
269            DO jl =0, ipr2dj
270               pt2d(2,ijpj+jl) = psgn * pt2d(3,ijpj-1+jl)
271               DO ji = 3, jpiglo
272                  iju = jpiglo - ji + 3
273                  pt2d(ji,ijpj+jl) = psgn * pt2d(iju,ijpj-1-jl)
274               END DO
275            END DO
276         CASE ( 'K' )                                     ! second ice U-V point
277            DO jl =0, ipr2dj
278               pt2d(2,ijpj+jl) = psgn * pt2d(3,ijpj-1+jl)
279               DO ji = 3, jpiglo
280                  iju = jpiglo - ji + 3
281                  pt2d(ji,ijpj+jl) = psgn * pt2d(iju,ijpj-1-jl)
282               END DO
283            END DO
284         END SELECT
285         !
286      CASE ( 5, 6 )                        ! *  North fold  F-point pivot
287         !
288         SELECT CASE ( cd_type )
289         CASE ( 'T' , 'W' )                               ! T-, W-point
290            DO jl = 0, ipr2dj
291               DO ji = 1, jpiglo
292                  ijt = jpiglo-ji+1
293                  pt2d(ji,ijpj+jl) = psgn * pt2d(ijt,ijpj-1-jl)
294               END DO
295            END DO
296         CASE ( 'U' )                                     ! U-point
297            DO jl = 0, ipr2dj
298               DO ji = 1, jpiglo-1
299                  iju = jpiglo-ji
300                  pt2d(ji,ijpj+jl) = psgn * pt2d(iju,ijpj-1-jl)
301               END DO
302            END DO
303            pt2d(jpiglo,ijpj) = psgn * pt2d(1,ijpj-1)
304         CASE ( 'V' )                                     ! V-point
305            DO jl = 0, ipr2dj
306               DO ji = 1, jpiglo
307                  ijt = jpiglo-ji+1
308                  pt2d(ji,ijpj+jl) = psgn * pt2d(ijt,ijpj-2-jl)
309               END DO
310            END DO
311            DO ji = jpiglo/2+1, jpiglo
312               ijt = jpiglo-ji+1
313               pt2d(ji,ijpjm1) = psgn * pt2d(ijt,ijpjm1)
314            END DO
315         CASE ( 'F' )                               ! F-point
316            DO jl = 0, ipr2dj
317               DO ji = 1, jpiglo-1
318                  iju = jpiglo-ji
319                  pt2d(ji,ijpj+jl) = psgn * pt2d(iju,ijpj-2-jl)
320               END DO
321            END DO
322            pt2d(jpiglo,ijpj) = psgn * pt2d(1,ijpj-2)
323            DO ji = jpiglo/2+1, jpiglo-1
324               iju = jpiglo-ji
325               pt2d(ji,ijpjm1) = psgn * pt2d(iju,ijpjm1)
326            END DO
327         CASE ( 'I' )                                  ! ice U-V point (I-point)
328            pt2d( 2 ,ijpj:ijpj+ipr2dj) = 0.e0
329            DO jl = 0, ipr2dj
330               DO ji = 2 , jpiglo-1
331                  ijt = jpiglo - ji + 2
332                  pt2d(ji,ijpj+jl)= 0.5 * ( pt2d(ji,ijpj-1-jl) + psgn * pt2d(ijt,ijpj-1-jl) )
333               END DO
334            END DO
335         CASE ( 'J' )                                  ! first ice U-V point
336            pt2d( 2 ,ijpj:ijpj+ipr2dj) = 0.e0
337            DO jl = 0, ipr2dj
338               DO ji = 2 , jpiglo-1
339                  ijt = jpiglo - ji + 2
340                  pt2d(ji,ijpj+jl)= pt2d(ji,ijpj-1-jl)
341               END DO
342            END DO
343         CASE ( 'K' )                                  ! second ice U-V point
344            pt2d( 2 ,ijpj:ijpj+ipr2dj) = 0.e0
345            DO jl = 0, ipr2dj
346               DO ji = 2 , jpiglo-1
347                  ijt = jpiglo - ji + 2
348                  pt2d(ji,ijpj+jl)= pt2d(ijt,ijpj-1-jl)
349               END DO
350            END DO
351         END SELECT
352         !
353      CASE DEFAULT                           ! *  closed : the code probably never go through
354         !
355         SELECT CASE ( cd_type)
356         CASE ( 'T' , 'U' , 'V' , 'W' )                 ! T-, U-, V-, W-points
357            pt2d(:, 1:1-ipr2dj     ) = 0.e0
358            pt2d(:,ijpj:ijpj+ipr2dj) = 0.e0
359         CASE ( 'F' )                                   ! F-point
360            pt2d(:,ijpj:ijpj+ipr2dj) = 0.e0
361         CASE ( 'I' )                                   ! ice U-V point
362            pt2d(:, 1:1-ipr2dj     ) = 0.e0
363            pt2d(:,ijpj:ijpj+ipr2dj) = 0.e0
364         CASE ( 'J' )                                   ! first ice U-V point
365            pt2d(:, 1:1-ipr2dj     ) = 0.e0
366            pt2d(:,ijpj:ijpj+ipr2dj) = 0.e0
367         CASE ( 'K' )                                   ! second ice U-V point
368            pt2d(:, 1:1-ipr2dj     ) = 0.e0
369            pt2d(:,ijpj:ijpj+ipr2dj) = 0.e0
370         END SELECT
371         !
372      END SELECT
373      !
374   END SUBROUTINE lbc_nfd_2d
375
376
377   SUBROUTINE mpp_lbc_nfd_3d( pt3dl, pt3dr, cd_type, psgn )
378      !!----------------------------------------------------------------------
379      !!                  ***  routine mpp_lbc_nfd_3d  ***
380      !!
381      !! ** Purpose :   3D lateral boundary condition : North fold treatment
382      !!              without processor exchanges.
383      !!
384      !! ** Method  :   
385      !!
386      !! ** Action  :   pt3d with updated values along the north fold
387      !!----------------------------------------------------------------------
388      CHARACTER(len=1)          , INTENT(in   ) ::   cd_type   ! define the nature of ptab array grid-points
389      !                                                        !   = T , U , V , F , W points
390      REAL(wp)                  , INTENT(in   ) ::   psgn      ! control of the sign change
391      !                                                        !   = -1. , the sign is changed if north fold boundary
392      !                                                        !   =  1. , the sign is kept    if north fold boundary
393      REAL(wp), DIMENSION(:,:,:), INTENT(inout) ::   pt3dl     ! 3D array on which the boundary condition is applied
394      REAL(wp), DIMENSION(:,:,:), INTENT(in   ) ::   pt3dr     ! 3D array on which the boundary condition is applied
395      !
396      INTEGER  ::   ji, jk, ilev
397      INTEGER  ::   ijt, iju, ijpj, ijpjm1, ijta, ijua, jia, startloop, endloop
398      !!----------------------------------------------------------------------
399      !
400      SELECT CASE ( jpni )
401      CASE ( 1 )     ;   ijpj = nlcj      ! 1 proc only  along the i-direction
402      CASE DEFAULT   ;   ijpj = 4         ! several proc along the i-direction
403      END SELECT
404      ijpjm1 = ijpj-1
405      ilev = SIZE(pt3dl,3)
406         !
407         SELECT CASE ( npolj )
408         !
409         CASE ( 3 , 4 )                        ! *  North fold  T-point pivot
410            !
411            SELECT CASE ( cd_type )
412            CASE ( 'T' , 'W' )                         ! T-, W-point
413               IF (nimpp .ne. 1) THEN
414                 startloop = 1
415               ELSE
416                 startloop = 2
417               ENDIF
418
419               DO jk = 1, ilev
420                  DO ji = startloop, nlci
421                     ijt = jpiglo - ji - nimpp - nfiimpp(isendto(1),jpnj) + 4
422                     pt3dl(ji,ijpj,jk) = psgn * pt3dr(ijt,ijpj-2,jk)
423                  END DO
424                  IF(nimpp .eq. 1) THEN
425                     pt3dl(1,ijpj,jk) = psgn * pt3dl(3,ijpj-2,jk)
426                  ENDIF
427               END DO
428
429               IF(nimpp .ge. (jpiglo/2+1)) THEN
430                 startloop = 1
431               ELSEIF(((nimpp+nlci-1) .ge. (jpiglo/2+1)) .AND. (nimpp .lt. (jpiglo/2+1))) THEN
432                 startloop = jpiglo/2+1 - nimpp + 1
433               ELSE
434                 startloop = nlci + 1
435               ENDIF
436               IF(startloop .le. nlci) THEN
437                 DO jk = 1, ilev
438                    DO ji = startloop, nlci
439                       ijt = jpiglo - ji - nimpp - nfiimpp(isendto(1),jpnj) + 4
440                       jia = ji + nimpp - 1
441                       ijta = jpiglo - jia + 2
442                       IF((ijta .ge. (startloop + nimpp - 1)) .and. (ijta .lt. jia)) THEN
443                          pt3dl(ji,ijpjm1,jk) = psgn * pt3dl(ijta-nimpp+1,ijpjm1,jk)
444                       ELSE
445                          pt3dl(ji,ijpjm1,jk) = psgn * pt3dr(ijt,ijpjm1,jk)
446                       ENDIF
447                    END DO
448                 END DO
449               ENDIF
450
451
452            CASE ( 'U' )                               ! U-point
453               IF ((nimpp + nlci - 1) .ne. jpiglo) THEN
454                  endloop = nlci
455               ELSE
456                  endloop = nlci - 1
457               ENDIF
458               DO jk = 1, ilev
459                  DO ji = 1, endloop
460                     iju = jpiglo - ji - nimpp - nfiimpp(isendto(1),jpnj) + 3
461                     pt3dl(ji,ijpj,jk) = psgn * pt3dr(iju,ijpj-2,jk)
462                  END DO
463                  IF(nimpp .eq. 1) THEN
464                     pt3dl(   1  ,ijpj,jk) = psgn * pt3dl(    2   ,ijpj-2,jk)
465                  ENDIF
466                  IF((nimpp + nlci - 1) .eq. jpiglo) THEN
467                     pt3dl(nlci,ijpj,jk) = psgn * pt3dl(nlci-1,ijpj-2,jk)
468                  ENDIF
469               END DO
470
471               IF ((nimpp + nlci - 1) .ne. jpiglo) THEN
472                  endloop = nlci
473               ELSE
474                  endloop = nlci - 1
475               ENDIF
476               IF(nimpp .ge. (jpiglo/2)) THEN
477                  startloop = 1
478               ELSEIF(((nimpp+nlci-1) .ge. (jpiglo/2)) .AND. (nimpp .lt. (jpiglo/2))) THEN
479                  startloop = jpiglo/2 - nimpp + 1
480               ELSE
481                  startloop = endloop + 1
482               ENDIF
483               IF (startloop .le. endloop) THEN
484                 DO jk = 1, ilev
485                    DO ji = startloop, endloop
486                      iju = jpiglo - ji - nimpp - nfiimpp(isendto(1),jpnj) + 3
487                      jia = ji + nimpp - 1
488                      ijua = jpiglo - jia + 1
489                      IF((ijua .ge. (startloop + nimpp - 1)) .and. (ijua .lt. jia)) THEN
490                        pt3dl(ji,ijpjm1,jk) = psgn * pt3dl(ijua-nimpp+1,ijpjm1,jk)
491                      ELSE
492                        pt3dl(ji,ijpjm1,jk) = psgn * pt3dr(iju,ijpjm1,jk)
493                      ENDIF
494                    END DO
495                 END DO
496               ENDIF
497
498            CASE ( 'V' )                               ! V-point
499               IF (nimpp .ne. 1) THEN
500                  startloop = 1
501               ELSE
502                  startloop = 2
503               ENDIF
504               DO jk = 1, ilev
505                  DO ji = startloop, nlci
506                     ijt = jpiglo - ji - nimpp - nfiimpp(isendto(1),jpnj) + 4
507                     pt3dl(ji,ijpj-1,jk) = psgn * pt3dr(ijt,ijpj-2,jk)
508                     pt3dl(ji,ijpj  ,jk) = psgn * pt3dr(ijt,ijpj-3,jk)
509                  END DO
510                  IF(nimpp .eq. 1) THEN
511                     pt3dl(1,ijpj,jk) = psgn * pt3dl(3,ijpj-3,jk)
512                  ENDIF
513               END DO
514            CASE ( 'F' )                               ! F-point
515               IF ((nimpp + nlci - 1) .ne. jpiglo) THEN
516                  endloop = nlci
517               ELSE
518                  endloop = nlci - 1
519               ENDIF
520               DO jk = 1, ilev
521                  DO ji = 1, endloop
522                     iju = jpiglo - ji - nimpp - nfiimpp(isendto(1),jpnj) + 3
523                     pt3dl(ji,ijpj-1,jk) = psgn * pt3dr(iju,ijpj-2,jk)
524                     pt3dl(ji,ijpj  ,jk) = psgn * pt3dr(iju,ijpj-3,jk)
525                  END DO
526                  IF(nimpp .eq. 1) THEN
527                     pt3dl(   1  ,ijpj,jk) = psgn * pt3dl(    2   ,ijpj-3,jk)
528                  ENDIF
529                  IF((nimpp + nlci - 1) .eq. jpiglo) THEN
530                     pt3dl(nlci,ijpj,jk) = psgn * pt3dl(nlci-1,ijpj-3,jk)
531                  ENDIF
532               END DO
533            END SELECT
534            !
535
536         CASE ( 5 , 6 )                        ! *  North fold  F-point pivot
537            !
538            SELECT CASE ( cd_type )
539            CASE ( 'T' , 'W' )                         ! T-, W-point
540               DO jk = 1, ilev
541                  DO ji = 1, nlci
542                     ijt = jpiglo - ji - nimpp - nfiimpp(isendto(1),jpnj) + 3
543                     pt3dl(ji,ijpj,jk) = psgn * pt3dr(ijt,ijpj-1,jk)
544                  END DO
545               END DO
546
547            CASE ( 'U' )                               ! U-point
548               IF ((nimpp + nlci - 1) .ne. jpiglo) THEN
549                  endloop = nlci
550               ELSE
551                  endloop = nlci - 1
552               ENDIF
553               DO jk = 1, ilev
554                  DO ji = 1, endloop
555                     iju = jpiglo - ji - nimpp - nfiimpp(isendto(1),jpnj) + 2
556                     pt3dl(ji,ijpj,jk) = psgn * pt3dr(iju,ijpj-1,jk)
557                  END DO
558                  IF((nimpp + nlci - 1) .eq. jpiglo) THEN
559                     pt3dl(nlci,ijpj,jk) = psgn * pt3dr(1,ijpj-1,jk)
560                  ENDIF
561               END DO
562
563            CASE ( 'V' )                               ! V-point
564               DO jk = 1, ilev
565                  DO ji = 1, nlci
566                     ijt = jpiglo - ji- nimpp - nfiimpp(isendto(1),jpnj) + 3
567                     pt3dl(ji,ijpj,jk) = psgn * pt3dr(ijt,ijpj-2,jk)
568                  END DO
569               END DO
570
571               IF(nimpp .ge. (jpiglo/2+1)) THEN
572                  startloop = 1
573               ELSEIF(((nimpp+nlci-1) .ge. (jpiglo/2+1)) .AND. (nimpp .lt. (jpiglo/2+1))) THEN
574                  startloop = jpiglo/2+1 - nimpp + 1
575               ELSE
576                  startloop = nlci + 1
577               ENDIF
578               IF(startloop .le. nlci) THEN
579                 DO jk = 1, ilev
580                    DO ji = startloop, nlci
581                       ijt = jpiglo - ji - nimpp - nfiimpp(isendto(1),jpnj) + 3
582                       pt3dl(ji,ijpjm1,jk) = psgn * pt3dr(ijt,ijpjm1,jk)
583                    END DO
584                 END DO
585               ENDIF
586
587            CASE ( 'F' )                               ! F-point
588               IF ((nimpp + nlci - 1) .ne. jpiglo) THEN
589                  endloop = nlci
590               ELSE
591                  endloop = nlci - 1
592               ENDIF
593               DO jk = 1, ilev
594                  DO ji = 1, endloop
595                     iju = jpiglo - ji - nimpp - nfiimpp(isendto(1),jpnj) + 2
596                     pt3dl(ji,ijpj ,jk) = psgn * pt3dr(iju,ijpj-2,jk)
597                  END DO
598                  IF((nimpp + nlci - 1) .eq. jpiglo) THEN
599                     pt3dl(nlci,ijpj,jk) = psgn * pt3dr(1,ijpj-2,jk)
600                  ENDIF
601               END DO
602
603               IF ((nimpp + nlci - 1) .ne. jpiglo) THEN
604                  endloop = nlci
605               ELSE
606                  endloop = nlci - 1
607               ENDIF
608               IF(nimpp .ge. (jpiglo/2+1)) THEN
609                  startloop = 1
610               ELSEIF(((nimpp+nlci-1) .ge. (jpiglo/2+1)) .AND. (nimpp .lt. (jpiglo/2+1))) THEN
611                  startloop = jpiglo/2+1 - nimpp + 1
612               ELSE
613                  startloop = endloop + 1
614               ENDIF
615               IF (startloop .le. endloop) THEN
616                  DO jk = 1, ilev
617                     DO ji = startloop, endloop
618                        iju = jpiglo - ji - nimpp - nfiimpp(isendto(1),jpnj) + 2
619                        pt3dl(ji,ijpjm1,jk) = psgn * pt3dr(iju,ijpjm1,jk)
620                     END DO
621                  END DO
622               ENDIF
623
624            END SELECT
625
626         CASE DEFAULT                           ! *  closed : the code probably never go through
627            !
628            SELECT CASE ( cd_type)
629            CASE ( 'T' , 'U' , 'V' , 'W' )             ! T-, U-, V-, W-points
630               pt3dl(:, 1  ,:) = 0.e0
631               pt3dl(:,ijpj,:) = 0.e0
632            CASE ( 'F' )                               ! F-point
633               pt3dl(:,ijpj,:) = 0.e0
634            END SELECT
635            !
636         END SELECT     !  npolj
637         !
638      !
639   END SUBROUTINE mpp_lbc_nfd_3d
640
641
642   SUBROUTINE mpp_lbc_nfd_2d( pt2dl, pt2dr, cd_type, psgn )
643      !!----------------------------------------------------------------------
644      !!                  ***  routine mpp_lbc_nfd_2d  ***
645      !!
646      !! ** Purpose :   2D lateral boundary condition : North fold treatment
647      !!       without processor exchanges.
648      !!
649      !! ** Method  :   
650      !!
651      !! ** Action  :   pt2d with updated values along the north fold
652      !!----------------------------------------------------------------------
653      CHARACTER(len=1)        , INTENT(in   ) ::   cd_type   ! define the nature of ptab array grid-points
654      !                                                      ! = T , U , V , F , W points
655      REAL(wp)                , INTENT(in   ) ::   psgn      ! control of the sign change
656      !                                                      !   = -1. , the sign is changed if north fold boundary
657      !                                                      !   =  1. , the sign is kept  if north fold boundary
658      REAL(wp), DIMENSION(:,:), INTENT(inout) ::   pt2dl     ! 2D array on which the boundary condition is applied
659      REAL(wp), DIMENSION(:,:), INTENT(in   ) ::   pt2dr     ! 2D array on which the boundary condition is applied
660      !
661      INTEGER  ::   ji
662      INTEGER  ::   ijt, iju, ijpj, ijpjm1, ijta, ijua, jia, startloop, endloop
663      !!----------------------------------------------------------------------
664
665      SELECT CASE ( jpni )
666      CASE ( 1 )     ;   ijpj = nlcj      ! 1 proc only  along the i-direction
667      CASE DEFAULT   ;   ijpj = 4         ! several proc along the i-direction
668      END SELECT
669      !
670      ijpjm1 = ijpj-1
671
672
673      SELECT CASE ( npolj )
674      !
675      CASE ( 3, 4 )                       ! *  North fold  T-point pivot
676         !
677         SELECT CASE ( cd_type )
678         !
679         CASE ( 'T' , 'W' )                               ! T- , W-points
680            IF (nimpp .ne. 1) THEN
681              startloop = 1
682            ELSE
683              startloop = 2
684            ENDIF
685            DO ji = startloop, nlci
686              ijt=jpiglo - ji - nimpp - nfiimpp(isendto(1),jpnj) + 4
687              pt2dl(ji,ijpj) = psgn * pt2dr(ijt,ijpjm1-1)
688            END DO
689            IF (nimpp .eq. 1) THEN
690              pt2dl(1,ijpj)   = psgn * pt2dl(3,ijpj-2)
691            ENDIF
692
693            IF(nimpp .ge. (jpiglo/2+1)) THEN
694               startloop = 1
695            ELSEIF(((nimpp+nlci-1) .ge. (jpiglo/2+1)) .AND. (nimpp .lt. (jpiglo/2+1))) THEN
696               startloop = jpiglo/2+1 - nimpp + 1
697            ELSE
698               startloop = nlci + 1
699            ENDIF
700            DO ji = startloop, nlci
701               ijt=jpiglo - ji - nimpp - nfiimpp(isendto(1),jpnj) + 4
702               jia = ji + nimpp - 1
703               ijta = jpiglo - jia + 2
704               IF((ijta .ge. (startloop + nimpp - 1)) .and. (ijta .lt. jia)) THEN
705                  pt2dl(ji,ijpjm1) = psgn * pt2dl(ijta-nimpp+1,ijpjm1)
706               ELSE
707                  pt2dl(ji,ijpjm1) = psgn * pt2dr(ijt,ijpjm1)
708               ENDIF
709            END DO
710
711         CASE ( 'U' )                                     ! U-point
712            IF ((nimpp + nlci - 1) .ne. jpiglo) THEN
713               endloop = nlci
714            ELSE
715               endloop = nlci - 1
716            ENDIF
717            DO ji = 1, endloop
718               iju = jpiglo - ji - nimpp - nfiimpp(isendto(1),jpnj) + 3
719               pt2dl(ji,ijpj) = psgn * pt2dr(iju,ijpjm1-1)
720            END DO
721
722            IF (nimpp .eq. 1) THEN
723              pt2dl(   1  ,ijpj  ) = psgn * pt2dl(    2   ,ijpj-2)
724              pt2dl(1     ,ijpj-1) = psgn * pt2dr(jpiglo - nfiimpp(isendto(1), jpnj) + 1, ijpj-1)
725            ENDIF
726            IF((nimpp + nlci - 1) .eq. jpiglo) THEN
727              pt2dl(nlci,ijpj  ) = psgn * pt2dl(nlci-1,ijpj-2)
728            ENDIF
729
730            IF ((nimpp + nlci - 1) .ne. jpiglo) THEN
731               endloop = nlci
732            ELSE
733               endloop = nlci - 1
734            ENDIF
735            IF(nimpp .ge. (jpiglo/2)) THEN
736               startloop = 1
737            ELSEIF(((nimpp+nlci-1) .ge. (jpiglo/2)) .AND. (nimpp .lt. (jpiglo/2))) THEN
738               startloop = jpiglo/2 - nimpp + 1
739            ELSE
740               startloop = endloop + 1
741            ENDIF
742            DO ji = startloop, endloop
743               iju = jpiglo - ji - nimpp - nfiimpp(isendto(1),jpnj) + 3
744               jia = ji + nimpp - 1
745               ijua = jpiglo - jia + 1
746               IF((ijua .ge. (startloop + nimpp - 1)) .and. (ijua .lt. jia)) THEN
747                  pt2dl(ji,ijpjm1) = psgn * pt2dl(ijua-nimpp+1,ijpjm1)
748               ELSE
749                  pt2dl(ji,ijpjm1) = psgn * pt2dr(iju,ijpjm1)
750               ENDIF
751            END DO
752
753         CASE ( 'V' )                                     ! V-point
754            IF (nimpp .ne. 1) THEN
755              startloop = 1
756            ELSE
757              startloop = 2
758            ENDIF
759            DO ji = startloop, nlci
760              ijt=jpiglo - ji - nimpp - nfiimpp(isendto(1),jpnj) + 4
761              pt2dl(ji,ijpjm1) = psgn * pt2dr(ijt,ijpjm1-1)
762              pt2dl(ji,ijpj) = psgn * pt2dr(ijt,ijpjm1-2)
763            END DO
764            IF (nimpp .eq. 1) THEN
765              pt2dl( 1 ,ijpj)   = psgn * pt2dl( 3 ,ijpj-3) 
766            ENDIF
767
768         CASE ( 'F' )                                     ! F-point
769            IF ((nimpp + nlci - 1) .ne. jpiglo) THEN
770               endloop = nlci
771            ELSE
772               endloop = nlci - 1
773            ENDIF
774            DO ji = 1, endloop
775               iju = jpiglo - ji - nimpp - nfiimpp(isendto(1),jpnj) + 3
776               pt2dl(ji,ijpjm1) = psgn * pt2dr(iju,ijpjm1-1)
777               pt2dl(ji,ijpj) = psgn * pt2dr(iju,ijpjm1-2)
778            END DO
779            IF (nimpp .eq. 1) THEN
780              pt2dl(   1  ,ijpj)   = psgn * pt2dl(    2   ,ijpj-3)
781              pt2dl(   1  ,ijpj-1) = psgn * pt2dl(    2   ,ijpj-2)
782            ENDIF
783            IF((nimpp + nlci - 1) .eq. jpiglo) THEN
784              pt2dl(nlci,ijpj)   = psgn * pt2dl(nlci-1,ijpj-3)
785              pt2dl(nlci,ijpj-1) = psgn * pt2dl(nlci-1,ijpj-2) 
786            ENDIF
787
788         CASE ( 'I' )                                     ! ice U-V point (I-point)
789            IF (nimpp .ne. 1) THEN
790               startloop = 1
791            ELSE
792               startloop = 3
793               pt2dl(2,ijpj) = psgn * pt2dr(3,ijpjm1)
794            ENDIF
795            DO ji = startloop, nlci
796               iju = jpiglo - ji - nimpp - nfiimpp(isendto(1),jpnj) + 5
797               pt2dl(ji,ijpj) = psgn * pt2dr(iju,ijpjm1)
798            END DO
799
800         CASE ( 'J' )                                     ! first ice U-V point
801            IF (nimpp .ne. 1) THEN
802               startloop = 1
803            ELSE
804               startloop = 3
805               pt2dl(2,ijpj) = psgn * pt2dl(3,ijpjm1)
806            ENDIF
807            DO ji = startloop, nlci
808               iju = jpiglo - ji - nimpp - nfiimpp(isendto(1),jpnj) + 5
809               pt2dl(ji,ijpj) = psgn * pt2dr(iju,ijpjm1)
810            END DO
811
812         CASE ( 'K' )                                     ! second ice U-V point
813            IF (nimpp .ne. 1) THEN
814               startloop = 1
815            ELSE
816               startloop = 3
817               pt2dl(2,ijpj) = psgn * pt2dl(3,ijpjm1)
818            ENDIF
819            DO ji = startloop, nlci
820               iju = jpiglo - ji - nimpp - nfiimpp(isendto(1),jpnj) + 5
821               pt2dl(ji,ijpj) = psgn * pt2dr(iju,ijpjm1)
822            END DO
823
824         END SELECT
825         !
826      CASE ( 5, 6 )                        ! *  North fold  F-point pivot
827         !
828         SELECT CASE ( cd_type )
829         CASE ( 'T' , 'W' )                               ! T-, W-point
830            DO ji = 1, nlci
831               ijt = jpiglo - ji - nimpp - nfiimpp(isendto(1),jpnj) + 3
832               pt2dl(ji,ijpj) = psgn * pt2dr(ijt,ijpjm1)
833            END DO
834
835         CASE ( 'U' )                                     ! U-point
836            IF ((nimpp + nlci - 1) .ne. jpiglo) THEN
837               endloop = nlci
838            ELSE
839               endloop = nlci - 1
840            ENDIF
841            DO ji = 1, endloop
842               iju = jpiglo - ji - nimpp - nfiimpp(isendto(1),jpnj) + 2
843               pt2dl(ji,ijpj) = psgn * pt2dr(iju,ijpjm1)
844            END DO
845            IF((nimpp + nlci - 1) .eq. jpiglo) THEN
846               pt2dl(nlci,ijpj) = psgn * pt2dr(1,ijpj-1)
847            ENDIF
848
849         CASE ( 'V' )                                     ! V-point
850            DO ji = 1, nlci
851               ijt = jpiglo - ji - nimpp - nfiimpp(isendto(1),jpnj) + 3
852               pt2dl(ji,ijpj) = psgn * pt2dr(ijt,ijpjm1-1)
853            END DO
854            IF(nimpp .ge. (jpiglo/2+1)) THEN
855               startloop = 1
856            ELSEIF(((nimpp+nlci-1) .ge. (jpiglo/2+1)) .AND. (nimpp .lt. (jpiglo/2+1))) THEN
857               startloop = jpiglo/2+1 - nimpp + 1
858            ELSE
859               startloop = nlci + 1
860            ENDIF
861            DO ji = startloop, nlci
862               ijt = jpiglo - ji - nimpp - nfiimpp(isendto(1),jpnj) + 3
863               pt2dl(ji,ijpjm1) = psgn * pt2dr(ijt,ijpjm1)
864            END DO
865
866         CASE ( 'F' )                               ! F-point
867            IF ((nimpp + nlci - 1) .ne. jpiglo) THEN
868               endloop = nlci
869            ELSE
870               endloop = nlci - 1
871            ENDIF
872            DO ji = 1, endloop
873               iju = jpiglo - ji - nimpp - nfiimpp(isendto(1),jpnj) + 2
874               pt2dl(ji,ijpj) = psgn * pt2dr(iju,ijpjm1-1)
875            END DO
876            IF((nimpp + nlci - 1) .eq. jpiglo) THEN
877                pt2dl(nlci,ijpj) = psgn * pt2dr(1,ijpj-2)
878            ENDIF
879
880            IF ((nimpp + nlci - 1) .ne. jpiglo) THEN
881               endloop = nlci
882            ELSE
883               endloop = nlci - 1
884            ENDIF
885            IF(nimpp .ge. (jpiglo/2+1)) THEN
886               startloop = 1
887            ELSEIF(((nimpp+nlci-1) .ge. (jpiglo/2+1)) .AND. (nimpp .lt. (jpiglo/2+1))) THEN
888               startloop = jpiglo/2+1 - nimpp + 1
889            ELSE
890               startloop = endloop + 1
891            ENDIF
892
893            DO ji = startloop, endloop
894               iju = jpiglo - ji - nimpp - nfiimpp(isendto(1),jpnj) + 2
895               pt2dl(ji,ijpjm1) = psgn * pt2dr(iju,ijpjm1)
896            END DO
897
898         CASE ( 'I' )                                  ! ice U-V point (I-point)
899               IF (nimpp .ne. 1) THEN
900                  startloop = 1
901               ELSE
902                  startloop = 2
903               ENDIF
904               IF ((nimpp + nlci - 1) .ne. jpiglo) THEN
905                  endloop = nlci
906               ELSE
907                  endloop = nlci - 1
908               ENDIF
909               DO ji = startloop , endloop
910                  ijt = jpiglo - ji - nimpp - nfiimpp(isendto(1),jpnj) + 4
911                  pt2dl(ji,ijpj)= 0.5 * (pt2dl(ji,ijpjm1) + psgn * pt2dr(ijt,ijpjm1))
912               END DO
913
914         CASE ( 'J' )                                  ! first ice U-V point
915               IF (nimpp .ne. 1) THEN
916                  startloop = 1
917               ELSE
918                  startloop = 2
919               ENDIF
920               IF ((nimpp + nlci - 1) .ne. jpiglo) THEN
921                  endloop = nlci
922               ELSE
923                  endloop = nlci - 1
924               ENDIF
925               DO ji = startloop , endloop
926                  ijt = jpiglo - ji - nimpp - nfiimpp(isendto(1),jpnj) + 4
927                  pt2dl(ji,ijpj) = pt2dl(ji,ijpjm1)
928               END DO
929
930         CASE ( 'K' )                                  ! second ice U-V point
931               IF (nimpp .ne. 1) THEN
932                  startloop = 1
933               ELSE
934                  startloop = 2
935               ENDIF
936               IF ((nimpp + nlci - 1) .ne. jpiglo) THEN
937                  endloop = nlci
938               ELSE
939                  endloop = nlci - 1
940               ENDIF
941               DO ji = startloop, endloop
942                  ijt = jpiglo - ji - nimpp - nfiimpp(isendto(1),jpnj) + 4
943                  pt2dl(ji,ijpj) = pt2dr(ijt,ijpjm1)
944               END DO
945
946         END SELECT
947         !
948      CASE DEFAULT                           ! *  closed : the code probably never go through
949         !
950         SELECT CASE ( cd_type)
951         CASE ( 'T' , 'U' , 'V' , 'W' )                 ! T-, U-, V-, W-points
952            pt2dl(:, 1     ) = 0.e0
953            pt2dl(:,ijpj) = 0.e0
954         CASE ( 'F' )                                   ! F-point
955            pt2dl(:,ijpj) = 0.e0
956         CASE ( 'I' )                                   ! ice U-V point
957            pt2dl(:, 1     ) = 0.e0
958            pt2dl(:,ijpj) = 0.e0
959         CASE ( 'J' )                                   ! first ice U-V point
960            pt2dl(:, 1     ) = 0.e0
961            pt2dl(:,ijpj) = 0.e0
962         CASE ( 'K' )                                   ! second ice U-V point
963            pt2dl(:, 1     ) = 0.e0
964            pt2dl(:,ijpj) = 0.e0
965         END SELECT
966         !
967      END SELECT
968      !
969   END SUBROUTINE mpp_lbc_nfd_2d
970
971   !!======================================================================
972END MODULE lbcnfd
Note: See TracBrowser for help on using the repository browser.