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.
Changeset 3680 for branches/2012/dev_MERGE_2012/NEMOGCM/NEMO/OPA_SRC/LBC – NEMO

Ignore:
Timestamp:
2012-11-27T15:42:24+01:00 (11 years ago)
Author:
rblod
Message:

First commit of the final branch for 2012 (future nemo_3_5), see ticket #1028

Location:
branches/2012/dev_MERGE_2012/NEMOGCM/NEMO/OPA_SRC/LBC
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • branches/2012/dev_MERGE_2012/NEMOGCM/NEMO/OPA_SRC/LBC/lbclnk.F90

    r3609 r3680  
    77   !!   NEMO     1.0  ! 2002-09  (G. Madec)     F90: Free form and module 
    88   !!            3.2  ! 2009-03  (R. Benshila)  External north fold treatment   
     9   !!            3.5  ! 2012     (S.Mocavero, I. Epicoco) Add 'lbc_bdy_lnk'  
     10   !!                            and lbc_obc_lnk' routine to optimize   
     11   !!                            the BDY/OBC communications 
    912   !!---------------------------------------------------------------------- 
    1013#if   defined key_mpp_mpi 
     
    1417   !!   lbc_lnk      : generic interface for mpp_lnk_3d and mpp_lnk_2d routines defined in lib_mpp 
    1518   !!   lbc_lnk_e    : generic interface for mpp_lnk_2d_e routine defined in lib_mpp 
     19   !!   lbc_bdy_lnk  : generic interface for mpp_lnk_bdy_2d and mpp_lnk_bdy_3d routines defined in lib_mpp 
     20   !!   lbc_obc_lnk  : generic interface for mpp_lnk_obc_2d and mpp_lnk_obc_3d routines defined in lib_mpp 
    1621   !!---------------------------------------------------------------------- 
    1722   USE lib_mpp          ! distributed memory computing library 
     
    2126   END INTERFACE 
    2227 
     28   INTERFACE lbc_bdy_lnk 
     29      MODULE PROCEDURE mpp_lnk_bdy_2d, mpp_lnk_bdy_3d 
     30   END INTERFACE 
     31   INTERFACE lbc_obc_lnk 
     32      MODULE PROCEDURE mpp_lnk_obc_2d, mpp_lnk_obc_3d 
     33   END INTERFACE 
     34 
    2335   INTERFACE lbc_lnk_e 
    2436      MODULE PROCEDURE mpp_lnk_2d_e 
     
    2739   PUBLIC lbc_lnk       ! ocean lateral boundary conditions 
    2840   PUBLIC lbc_lnk_e 
     41   PUBLIC lbc_bdy_lnk   ! ocean lateral BDY boundary conditions 
     42   PUBLIC lbc_obc_lnk   ! ocean lateral BDY boundary conditions 
    2943 
    3044   !!---------------------------------------------------------------------- 
     
    4155   !!   lbc_lnk_3d   : set the lateral boundary condition on a 3D variable on ocean mesh 
    4256   !!   lbc_lnk_2d   : set the lateral boundary condition on a 2D variable on ocean mesh 
     57   !!   lbc_bdy_lnk  : set the lateral BDY boundary condition 
     58   !!   lbc_obc_lnk  : set the lateral OBC boundary condition 
    4359   !!---------------------------------------------------------------------- 
    4460   USE oce             ! ocean dynamics and tracers    
     
    5874   END INTERFACE 
    5975 
     76   INTERFACE lbc_bdy_lnk 
     77      MODULE PROCEDURE lbc_bdy_lnk_2d, lbc_bdy_lnk_3d 
     78   END INTERFACE 
     79   INTERFACE lbc_obc_lnk 
     80      MODULE PROCEDURE lbc_lnk_2d, lbc_lnk_3d 
     81   END INTERFACE 
     82 
    6083   PUBLIC   lbc_lnk       ! ocean/ice  lateral boundary conditions 
    6184   PUBLIC   lbc_lnk_e  
     85   PUBLIC   lbc_bdy_lnk   ! ocean lateral BDY boundary conditions 
     86   PUBLIC   lbc_obc_lnk   ! ocean lateral OBC boundary conditions 
    6287    
    6388   !!---------------------------------------------------------------------- 
     
    180205   END SUBROUTINE lbc_lnk_3d 
    181206 
     207   SUBROUTINE lbc_bdy_lnk_3d( pt3d, cd_type, psgn, ib_bdy ) 
     208      !!--------------------------------------------------------------------- 
     209      !!                  ***  ROUTINE lbc_bdy_lnk  *** 
     210      !! 
     211      !! ** Purpose :   wrapper rountine to 'lbc_lnk_3d'. This wrapper is used 
     212      !!                to maintain the same interface with regards to the mpp case 
     213      !! 
     214      !!---------------------------------------------------------------------- 
     215      CHARACTER(len=1)                , INTENT(in   )           ::   cd_type   ! nature of pt3d grid-points 
     216      REAL(wp), DIMENSION(jpi,jpj,jpk), INTENT(inout)           ::   pt3d      ! 3D array on which the lbc is applied 
     217      REAL(wp)                        , INTENT(in   )           ::   psgn      ! control of the sign  
     218      INTEGER                                                   ::   ib_bdy    ! BDY boundary set 
     219      !! 
     220      CALL lbc_lnk_3d( pt3d, cd_type, psgn) 
     221 
     222   END SUBROUTINE lbc_bdy_lnk_3d 
     223 
     224   SUBROUTINE lbc_bdy_lnk_2d( pt2d, cd_type, psgn, ib_bdy ) 
     225      !!--------------------------------------------------------------------- 
     226      !!                  ***  ROUTINE lbc_bdy_lnk  *** 
     227      !! 
     228      !! ** Purpose :   wrapper rountine to 'lbc_lnk_3d'. This wrapper is used 
     229      !!                to maintain the same interface with regards to the mpp case 
     230      !! 
     231      !!---------------------------------------------------------------------- 
     232      CHARACTER(len=1)                , INTENT(in   )           ::   cd_type   ! nature of pt3d grid-points 
     233      REAL(wp), DIMENSION(jpi,jpj),     INTENT(inout)           ::   pt2d      ! 3D array on which the lbc is applied 
     234      REAL(wp)                        , INTENT(in   )           ::   psgn      ! control of the sign  
     235      INTEGER                                                   ::   ib_bdy    ! BDY boundary set 
     236      !! 
     237      CALL lbc_lnk_2d( pt2d, cd_type, psgn) 
     238 
     239   END SUBROUTINE lbc_bdy_lnk_2d 
    182240 
    183241   SUBROUTINE lbc_lnk_2d( pt2d, cd_type, psgn, cd_mpp, pval ) 
  • branches/2012/dev_MERGE_2012/NEMOGCM/NEMO/OPA_SRC/LBC/lib_mpp.F90

    r3632 r3680  
    1919   !!            3.2  !  2009  (O. Marti)    add mpp_ini_znl  
    2020   !!            4.0  !  2011  (G. Madec)  move ctl_ routines from in_out_manager 
     21   !!            3.5  !  2012  (S.Mocavero, I. Epicoco) Add 'mpp_lnk_bdy_3d', 'mpp_lnk_obc_3d',  
     22   !!                          'mpp_lnk_bdy_2d' and 'mpp_lnk_obc_2d' routines and update 
     23   !!                          the mppobc routine to optimize the BDY and OBC communications 
    2124   !!---------------------------------------------------------------------- 
    2225 
     
    6972   PUBLIC   mppsend, mpprecv                          ! needed by ICB routines 
    7073   PUBLIC   lib_mpp_alloc   ! Called in nemogcm.F90 
     74   PUBLIC   mpp_lnk_bdy_2d, mpp_lnk_bdy_3d 
     75   PUBLIC   mpp_lnk_obc_2d, mpp_lnk_obc_3d 
    7176 
    7277   !! * Interfaces 
     
    348353   END FUNCTION mynode 
    349354 
    350  
    351    SUBROUTINE mpp_lnk_3d( ptab, cd_type, psgn, cd_mpp, pval ) 
    352       !!---------------------------------------------------------------------- 
    353       !!                  ***  routine mpp_lnk_3d  *** 
     355   SUBROUTINE mpp_lnk_obc_3d( ptab, cd_type, psgn ) 
     356      !!---------------------------------------------------------------------- 
     357      !!                  ***  routine mpp_lnk_obc_3d  *** 
    354358      !! 
    355359      !! ** Purpose :   Message passing manadgement 
    356360      !! 
    357       !! ** Method  :   Use mppsend and mpprecv function for passing mask  
     361      !! ** Method  :   Use mppsend and mpprecv function for passing OBC boundaries  
    358362      !!      between processors following neighboring subdomains. 
    359363      !!            domain parameters 
     
    375379      REAL(wp)                        , INTENT(in   ) ::   psgn     ! =-1 the sign change across the north fold boundary 
    376380      !                                                             ! =  1. , the sign is kept 
    377       CHARACTER(len=3), OPTIONAL      , INTENT(in   ) ::   cd_mpp   ! fill the overlap area only  
    378       REAL(wp)        , OPTIONAL      , INTENT(in   ) ::   pval     ! background value (used at closed boundaries) 
    379381      !! 
    380382      INTEGER  ::   ji, jj, jk, jl             ! dummy loop indices 
     
    385387      !!---------------------------------------------------------------------- 
    386388 
    387       IF( PRESENT( pval ) ) THEN   ;   zland = pval      ! set land value 
    388       ELSE                         ;   zland = 0.e0      ! zero by default 
    389       ENDIF 
     389      zland = 0.e0      ! zero by default 
    390390 
    391391      ! 1. standard boundary treatment 
    392392      ! ------------------------------ 
    393       IF( PRESENT( cd_mpp ) ) THEN      ! only fill added line/raw with existing values 
    394          ! 
    395          ! WARNING ptab is defined only between nld and nle 
    396          DO jk = 1, jpk 
    397             DO jj = nlcj+1, jpj                 ! added line(s)   (inner only) 
    398                ptab(nldi  :nlei  , jj          ,jk) = ptab(nldi:nlei,     nlej,jk)    
    399                ptab(1     :nldi-1, jj          ,jk) = ptab(nldi     ,     nlej,jk) 
    400                ptab(nlei+1:nlci  , jj          ,jk) = ptab(     nlei,     nlej,jk) 
    401             END DO 
    402             DO ji = nlci+1, jpi                 ! added column(s) (full) 
    403                ptab(ji           ,nldj  :nlej  ,jk) = ptab(     nlei,nldj:nlej,jk) 
    404                ptab(ji           ,1     :nldj-1,jk) = ptab(     nlei,nldj     ,jk) 
    405                ptab(ji           ,nlej+1:jpj   ,jk) = ptab(     nlei,     nlej,jk) 
    406             END DO 
    407          END DO 
    408          ! 
    409       ELSE                              ! standard close or cyclic treatment  
    410          ! 
    411          !                                   ! East-West boundaries 
    412          !                                        !* Cyclic east-west 
    413          IF( nbondi == 2 .AND. (nperio == 1 .OR. nperio == 4 .OR. nperio == 6) ) THEN 
    414             ptab( 1 ,:,:) = ptab(jpim1,:,:) 
    415             ptab(jpi,:,:) = ptab(  2  ,:,:) 
    416          ELSE                                     !* closed 
    417             IF( .NOT. cd_type == 'F' )   ptab(     1       :jpreci,:,:) = zland    ! south except F-point 
    418                                          ptab(nlci-jpreci+1:jpi   ,:,:) = zland    ! north 
    419          ENDIF 
    420          !                                   ! North-South boundaries (always closed) 
    421          IF( .NOT. cd_type == 'F' )   ptab(:,     1       :jprecj,:) = zland       ! south except F-point 
    422                                       ptab(:,nlcj-jprecj+1:jpj   ,:) = zland       ! north 
    423          ! 
     393      IF( nbondi == 2) THEN 
     394        IF (nperio == 1 .OR. nperio == 4 .OR. nperio == 6) THEN 
     395          ptab( 1 ,:,:) = ptab(jpim1,:,:) 
     396          ptab(jpi,:,:) = ptab(  2  ,:,:) 
     397        ELSE 
     398          IF( .NOT. cd_type == 'F' )   ptab(     1       :jpreci,:,:) = zland    ! south except F-point 
     399          ptab(nlci-jpreci+1:jpi   ,:,:) = zland    ! north 
     400        ENDIF 
     401      ELSEIF(nbondi == -1) THEN 
     402        IF( .NOT. cd_type == 'F' )   ptab(     1       :jpreci,:,:) = zland    ! south except F-point 
     403      ELSEIF(nbondi == 1) THEN 
     404        ptab(nlci-jpreci+1:jpi   ,:,:) = zland    ! north 
     405      ENDIF                                     !* closed 
     406 
     407      IF (nbondj == 2 .OR. nbondj == -1) THEN 
     408        IF( .NOT. cd_type == 'F' )   ptab(:,     1       :jprecj,:) = zland       ! south except F-point 
     409      ELSEIF (nbondj == 2 .OR. nbondj == 1) THEN 
     410        ptab(:,nlcj-jprecj+1:jpj   ,:) = zland       ! north 
    424411      ENDIF 
    425412 
     
    428415      ! we play with the neigbours AND the row number because of the periodicity  
    429416      ! 
     417      IF(nbondj .ne. 0) THEN 
    430418      SELECT CASE ( nbondi )      ! Read Dirichlet lateral conditions 
    431419      CASE ( -1, 0, 1 )                ! all exept 2 (i.e. close case) 
     
    466454            ptab(iihom+jl,:,:) = t3ew(:,jl,:,2) 
    467455         END DO 
    468       CASE ( 0 )  
     456      CASE ( 0 ) 
    469457         DO jl = 1, jpreci 
    470458            ptab(jl      ,:,:) = t3we(:,jl,:,2) 
     
    476464         END DO 
    477465      END SELECT 
     466      ENDIF 
    478467 
    479468 
     
    482471      ! always closed : we play only with the neigbours 
    483472      ! 
     473      IF(nbondi .ne. 0) THEN 
    484474      IF( nbondj /= 2 ) THEN      ! Read Dirichlet lateral conditions 
    485475         ijhom = nlcj-nrecj 
     
    519509            ptab(:,ijhom+jl,:) = t3ns(:,jl,:,2) 
    520510         END DO 
    521       CASE ( 0 )  
     511      CASE ( 0 ) 
    522512         DO jl = 1, jprecj 
    523513            ptab(:,jl      ,:) = t3sn(:,jl,:,2) 
     
    529519         END DO 
    530520      END SELECT 
     521      ENDIF 
    531522 
    532523 
     
    534525      ! ----------------------- 
    535526      ! 
    536       IF( npolj /= 0 .AND. .NOT. PRESENT(cd_mpp) ) THEN 
     527      IF( npolj /= 0 ) THEN 
    537528         ! 
    538529         SELECT CASE ( jpni ) 
     
    543534      ENDIF 
    544535      ! 
    545    END SUBROUTINE mpp_lnk_3d 
    546  
    547  
    548    SUBROUTINE mpp_lnk_2d( pt2d, cd_type, psgn, cd_mpp, pval ) 
    549       !!---------------------------------------------------------------------- 
    550       !!                  ***  routine mpp_lnk_2d  *** 
     536   END SUBROUTINE mpp_lnk_obc_3d 
     537 
     538 
     539   SUBROUTINE mpp_lnk_obc_2d( pt2d, cd_type, psgn ) 
     540      !!---------------------------------------------------------------------- 
     541      !!                  ***  routine mpp_lnk_obc_2d  *** 
    551542      !!                   
    552543      !! ** Purpose :   Message passing manadgement for 2d array 
    553544      !! 
    554       !! ** Method  :   Use mppsend and mpprecv function for passing mask  
     545      !! ** Method  :   Use mppsend and mpprecv function for passing OBC boundaries  
    555546      !!      between processors following neighboring subdomains. 
    556547      !!            domain parameters 
     
    570561      REAL(wp)                    , INTENT(in   ) ::   psgn     ! =-1 the sign change across the north fold boundary 
    571562      !                                                         ! =  1. , the sign is kept 
    572       CHARACTER(len=3), OPTIONAL  , INTENT(in   ) ::   cd_mpp   ! fill the overlap area only  
    573       REAL(wp)        , OPTIONAL  , INTENT(in   ) ::   pval     ! background value (used at closed boundaries) 
    574563      !! 
    575564      INTEGER  ::   ji, jj, jl   ! dummy loop indices 
     
    580569      !!---------------------------------------------------------------------- 
    581570 
    582       IF( PRESENT( pval ) ) THEN   ;   zland = pval      ! set land value 
    583       ELSE                         ;   zland = 0.e0      ! zero by default 
    584       ENDIF 
     571      zland = 0.e0      ! zero by default 
    585572 
    586573      ! 1. standard boundary treatment 
    587574      ! ------------------------------ 
    588575      ! 
    589       IF( PRESENT( cd_mpp ) ) THEN      ! only fill added line/raw with existing values 
    590          ! 
    591          ! WARNING pt2d is defined only between nld and nle 
    592          DO jj = nlcj+1, jpj                 ! added line(s)   (inner only) 
    593             pt2d(nldi  :nlei  , jj          ) = pt2d(nldi:nlei,     nlej)    
    594             pt2d(1     :nldi-1, jj          ) = pt2d(nldi     ,     nlej) 
    595             pt2d(nlei+1:nlci  , jj          ) = pt2d(     nlei,     nlej) 
    596          END DO 
    597          DO ji = nlci+1, jpi                 ! added column(s) (full) 
    598             pt2d(ji           ,nldj  :nlej  ) = pt2d(     nlei,nldj:nlej) 
    599             pt2d(ji           ,1     :nldj-1) = pt2d(     nlei,nldj     ) 
    600             pt2d(ji           ,nlej+1:jpj   ) = pt2d(     nlei,     nlej) 
    601          END DO 
    602          ! 
    603       ELSE                              ! standard close or cyclic treatment  
    604          ! 
    605          !                                   ! East-West boundaries 
    606          IF( nbondi == 2 .AND.   &                ! Cyclic east-west 
    607             &    (nperio == 1 .OR. nperio == 4 .OR. nperio == 6) ) THEN 
    608             pt2d( 1 ,:) = pt2d(jpim1,:)                                    ! west 
    609             pt2d(jpi,:) = pt2d(  2  ,:)                                    ! east 
    610          ELSE                                     ! closed 
    611             IF( .NOT. cd_type == 'F' )   pt2d(     1       :jpreci,:) = zland    ! south except F-point 
    612                                          pt2d(nlci-jpreci+1:jpi   ,:) = zland    ! north 
    613          ENDIF 
    614          !                                   ! North-South boundaries (always closed) 
    615             IF( .NOT. cd_type == 'F' )   pt2d(:,     1       :jprecj) = zland    !south except F-point 
    616                                          pt2d(:,nlcj-jprecj+1:jpj   ) = zland    ! north 
    617          ! 
     576      IF( nbondi == 2) THEN 
     577        IF (nperio == 1 .OR. nperio == 4 .OR. nperio == 6) THEN 
     578          pt2d( 1 ,:) = pt2d(jpim1,:) 
     579          pt2d(jpi,:) = pt2d(  2  ,:) 
     580        ELSE 
     581          IF( .NOT. cd_type == 'F' )   pt2d(     1       :jpreci,:) = zland    ! south except F-point 
     582          pt2d(nlci-jpreci+1:jpi   ,:) = zland    ! north 
     583        ENDIF 
     584      ELSEIF(nbondi == -1) THEN 
     585        IF( .NOT. cd_type == 'F' )   pt2d(     1       :jpreci,:) = zland    ! south except F-point 
     586      ELSEIF(nbondi == 1) THEN 
     587        pt2d(nlci-jpreci+1:jpi   ,:) = zland    ! north 
     588      ENDIF                                     !* closed 
     589 
     590      IF (nbondj == 2 .OR. nbondj == -1) THEN 
     591        IF( .NOT. cd_type == 'F' )   pt2d(:,     1       :jprecj) = zland       ! south except F-point 
     592      ELSEIF (nbondj == 2 .OR. nbondj == 1) THEN 
     593        pt2d(:,nlcj-jprecj+1:jpj) = zland       ! north 
    618594      ENDIF 
    619595 
     
    728704      ! ----------------------- 
    729705      ! 
     706      IF( npolj /= 0 ) THEN 
     707         ! 
     708         SELECT CASE ( jpni ) 
     709         CASE ( 1 )     ;   CALL lbc_nfd      ( pt2d, cd_type, psgn )   ! only 1 northern proc, no mpp 
     710         CASE DEFAULT   ;   CALL mpp_lbc_north( pt2d, cd_type, psgn )   ! for all northern procs. 
     711         END SELECT 
     712         ! 
     713      ENDIF 
     714      ! 
     715   END SUBROUTINE mpp_lnk_obc_2d 
     716 
     717   SUBROUTINE mpp_lnk_3d( ptab, cd_type, psgn, cd_mpp, pval ) 
     718      !!---------------------------------------------------------------------- 
     719      !!                  ***  routine mpp_lnk_3d  *** 
     720      !! 
     721      !! ** Purpose :   Message passing manadgement 
     722      !! 
     723      !! ** Method  :   Use mppsend and mpprecv function for passing mask  
     724      !!      between processors following neighboring subdomains. 
     725      !!            domain parameters 
     726      !!                    nlci   : first dimension of the local subdomain 
     727      !!                    nlcj   : second dimension of the local subdomain 
     728      !!                    nbondi : mark for "east-west local boundary" 
     729      !!                    nbondj : mark for "north-south local boundary" 
     730      !!                    noea   : number for local neighboring processors  
     731      !!                    nowe   : number for local neighboring processors 
     732      !!                    noso   : number for local neighboring processors 
     733      !!                    nono   : number for local neighboring processors 
     734      !! 
     735      !! ** Action  :   ptab with update value at its periphery 
     736      !! 
     737      !!---------------------------------------------------------------------- 
     738      REAL(wp), DIMENSION(jpi,jpj,jpk), INTENT(inout) ::   ptab     ! 3D array on which the boundary condition is applied 
     739      CHARACTER(len=1)                , INTENT(in   ) ::   cd_type  ! define the nature of ptab array grid-points 
     740      !                                                             ! = T , U , V , F , W points 
     741      REAL(wp)                        , INTENT(in   ) ::   psgn     ! =-1 the sign change across the north fold boundary 
     742      !                                                             ! =  1. , the sign is kept 
     743      CHARACTER(len=3), OPTIONAL      , INTENT(in   ) ::   cd_mpp   ! fill the overlap area only  
     744      REAL(wp)        , OPTIONAL      , INTENT(in   ) ::   pval     ! background value (used at closed boundaries) 
     745      !! 
     746      INTEGER  ::   ji, jj, jk, jl             ! dummy loop indices 
     747      INTEGER  ::   imigr, iihom, ijhom        ! temporary integers 
     748      INTEGER  ::   ml_req1, ml_req2, ml_err   ! for key_mpi_isend 
     749      REAL(wp) ::   zland 
     750      INTEGER, DIMENSION(MPI_STATUS_SIZE) ::   ml_stat   ! for key_mpi_isend 
     751      !!---------------------------------------------------------------------- 
     752 
     753      IF( PRESENT( pval ) ) THEN   ;   zland = pval      ! set land value 
     754      ELSE                         ;   zland = 0.e0      ! zero by default 
     755      ENDIF 
     756 
     757      ! 1. standard boundary treatment 
     758      ! ------------------------------ 
     759      IF( PRESENT( cd_mpp ) ) THEN      ! only fill added line/raw with existing values 
     760         ! 
     761         ! WARNING ptab is defined only between nld and nle 
     762         DO jk = 1, jpk 
     763            DO jj = nlcj+1, jpj                 ! added line(s)   (inner only) 
     764               ptab(nldi  :nlei  , jj          ,jk) = ptab(nldi:nlei,     nlej,jk)    
     765               ptab(1     :nldi-1, jj          ,jk) = ptab(nldi     ,     nlej,jk) 
     766               ptab(nlei+1:nlci  , jj          ,jk) = ptab(     nlei,     nlej,jk) 
     767            END DO 
     768            DO ji = nlci+1, jpi                 ! added column(s) (full) 
     769               ptab(ji           ,nldj  :nlej  ,jk) = ptab(     nlei,nldj:nlej,jk) 
     770               ptab(ji           ,1     :nldj-1,jk) = ptab(     nlei,nldj     ,jk) 
     771               ptab(ji           ,nlej+1:jpj   ,jk) = ptab(     nlei,     nlej,jk) 
     772            END DO 
     773         END DO 
     774         ! 
     775      ELSE                              ! standard close or cyclic treatment  
     776         ! 
     777         !                                   ! East-West boundaries 
     778         !                                        !* Cyclic east-west 
     779         IF( nbondi == 2 .AND. (nperio == 1 .OR. nperio == 4 .OR. nperio == 6) ) THEN 
     780            ptab( 1 ,:,:) = ptab(jpim1,:,:) 
     781            ptab(jpi,:,:) = ptab(  2  ,:,:) 
     782         ELSE                                     !* closed 
     783            IF( .NOT. cd_type == 'F' )   ptab(     1       :jpreci,:,:) = zland    ! south except F-point 
     784                                         ptab(nlci-jpreci+1:jpi   ,:,:) = zland    ! north 
     785         ENDIF 
     786         !                                   ! North-South boundaries (always closed) 
     787         IF( .NOT. cd_type == 'F' )   ptab(:,     1       :jprecj,:) = zland       ! south except F-point 
     788                                      ptab(:,nlcj-jprecj+1:jpj   ,:) = zland       ! north 
     789         ! 
     790      ENDIF 
     791 
     792      ! 2. East and west directions exchange 
     793      ! ------------------------------------ 
     794      ! we play with the neigbours AND the row number because of the periodicity  
     795      ! 
     796      SELECT CASE ( nbondi )      ! Read Dirichlet lateral conditions 
     797      CASE ( -1, 0, 1 )                ! all exept 2 (i.e. close case) 
     798         iihom = nlci-nreci 
     799         DO jl = 1, jpreci 
     800            t3ew(:,jl,:,1) = ptab(jpreci+jl,:,:) 
     801            t3we(:,jl,:,1) = ptab(iihom +jl,:,:) 
     802         END DO 
     803      END SELECT   
     804      ! 
     805      !                           ! Migrations 
     806      imigr = jpreci * jpj * jpk 
     807      ! 
     808      SELECT CASE ( nbondi )  
     809      CASE ( -1 ) 
     810         CALL mppsend( 2, t3we(1,1,1,1), imigr, noea, ml_req1 ) 
     811         CALL mpprecv( 1, t3ew(1,1,1,2), imigr, noea ) 
     812         IF(l_isend) CALL mpi_wait(ml_req1, ml_stat, ml_err) 
     813      CASE ( 0 ) 
     814         CALL mppsend( 1, t3ew(1,1,1,1), imigr, nowe, ml_req1 ) 
     815         CALL mppsend( 2, t3we(1,1,1,1), imigr, noea, ml_req2 ) 
     816         CALL mpprecv( 1, t3ew(1,1,1,2), imigr, noea ) 
     817         CALL mpprecv( 2, t3we(1,1,1,2), imigr, nowe ) 
     818         IF(l_isend) CALL mpi_wait(ml_req1, ml_stat, ml_err) 
     819         IF(l_isend) CALL mpi_wait(ml_req2, ml_stat, ml_err) 
     820      CASE ( 1 ) 
     821         CALL mppsend( 1, t3ew(1,1,1,1), imigr, nowe, ml_req1 ) 
     822         CALL mpprecv( 2, t3we(1,1,1,2), imigr, nowe ) 
     823         IF(l_isend) CALL mpi_wait(ml_req1, ml_stat, ml_err) 
     824      END SELECT 
     825      ! 
     826      !                           ! Write Dirichlet lateral conditions 
     827      iihom = nlci-jpreci 
     828      ! 
     829      SELECT CASE ( nbondi ) 
     830      CASE ( -1 ) 
     831         DO jl = 1, jpreci 
     832            ptab(iihom+jl,:,:) = t3ew(:,jl,:,2) 
     833         END DO 
     834      CASE ( 0 )  
     835         DO jl = 1, jpreci 
     836            ptab(jl      ,:,:) = t3we(:,jl,:,2) 
     837            ptab(iihom+jl,:,:) = t3ew(:,jl,:,2) 
     838         END DO 
     839      CASE ( 1 ) 
     840         DO jl = 1, jpreci 
     841            ptab(jl      ,:,:) = t3we(:,jl,:,2) 
     842         END DO 
     843      END SELECT 
     844 
     845 
     846      ! 3. North and south directions 
     847      ! ----------------------------- 
     848      ! always closed : we play only with the neigbours 
     849      ! 
     850      IF( nbondj /= 2 ) THEN      ! Read Dirichlet lateral conditions 
     851         ijhom = nlcj-nrecj 
     852         DO jl = 1, jprecj 
     853            t3sn(:,jl,:,1) = ptab(:,ijhom +jl,:) 
     854            t3ns(:,jl,:,1) = ptab(:,jprecj+jl,:) 
     855         END DO 
     856      ENDIF 
     857      ! 
     858      !                           ! Migrations 
     859      imigr = jprecj * jpi * jpk 
     860      ! 
     861      SELECT CASE ( nbondj )      
     862      CASE ( -1 ) 
     863         CALL mppsend( 4, t3sn(1,1,1,1), imigr, nono, ml_req1 ) 
     864         CALL mpprecv( 3, t3ns(1,1,1,2), imigr, nono ) 
     865         IF(l_isend) CALL mpi_wait(ml_req1, ml_stat, ml_err) 
     866      CASE ( 0 ) 
     867         CALL mppsend( 3, t3ns(1,1,1,1), imigr, noso, ml_req1 ) 
     868         CALL mppsend( 4, t3sn(1,1,1,1), imigr, nono, ml_req2 ) 
     869         CALL mpprecv( 3, t3ns(1,1,1,2), imigr, nono ) 
     870         CALL mpprecv( 4, t3sn(1,1,1,2), imigr, noso ) 
     871         IF(l_isend) CALL mpi_wait(ml_req1, ml_stat, ml_err) 
     872         IF(l_isend) CALL mpi_wait(ml_req2, ml_stat, ml_err) 
     873      CASE ( 1 )  
     874         CALL mppsend( 3, t3ns(1,1,1,1), imigr, noso, ml_req1 ) 
     875         CALL mpprecv( 4, t3sn(1,1,1,2), imigr, noso ) 
     876         IF(l_isend) CALL mpi_wait(ml_req1, ml_stat, ml_err) 
     877      END SELECT 
     878      ! 
     879      !                           ! Write Dirichlet lateral conditions 
     880      ijhom = nlcj-jprecj 
     881      ! 
     882      SELECT CASE ( nbondj ) 
     883      CASE ( -1 ) 
     884         DO jl = 1, jprecj 
     885            ptab(:,ijhom+jl,:) = t3ns(:,jl,:,2) 
     886         END DO 
     887      CASE ( 0 )  
     888         DO jl = 1, jprecj 
     889            ptab(:,jl      ,:) = t3sn(:,jl,:,2) 
     890            ptab(:,ijhom+jl,:) = t3ns(:,jl,:,2) 
     891         END DO 
     892      CASE ( 1 ) 
     893         DO jl = 1, jprecj 
     894            ptab(:,jl,:) = t3sn(:,jl,:,2) 
     895         END DO 
     896      END SELECT 
     897 
     898 
     899      ! 4. north fold treatment 
     900      ! ----------------------- 
     901      ! 
     902      IF( npolj /= 0 .AND. .NOT. PRESENT(cd_mpp) ) THEN 
     903         ! 
     904         SELECT CASE ( jpni ) 
     905         CASE ( 1 )     ;   CALL lbc_nfd      ( ptab, cd_type, psgn )   ! only 1 northern proc, no mpp 
     906         CASE DEFAULT   ;   CALL mpp_lbc_north( ptab, cd_type, psgn )   ! for all northern procs. 
     907         END SELECT 
     908         ! 
     909      ENDIF 
     910      ! 
     911   END SUBROUTINE mpp_lnk_3d 
     912 
     913 
     914   SUBROUTINE mpp_lnk_2d( pt2d, cd_type, psgn, cd_mpp, pval ) 
     915      !!---------------------------------------------------------------------- 
     916      !!                  ***  routine mpp_lnk_2d  *** 
     917      !!                   
     918      !! ** Purpose :   Message passing manadgement for 2d array 
     919      !! 
     920      !! ** Method  :   Use mppsend and mpprecv function for passing mask  
     921      !!      between processors following neighboring subdomains. 
     922      !!            domain parameters 
     923      !!                    nlci   : first dimension of the local subdomain 
     924      !!                    nlcj   : second dimension of the local subdomain 
     925      !!                    nbondi : mark for "east-west local boundary" 
     926      !!                    nbondj : mark for "north-south local boundary" 
     927      !!                    noea   : number for local neighboring processors  
     928      !!                    nowe   : number for local neighboring processors 
     929      !!                    noso   : number for local neighboring processors 
     930      !!                    nono   : number for local neighboring processors 
     931      !! 
     932      !!---------------------------------------------------------------------- 
     933      REAL(wp), DIMENSION(jpi,jpj), INTENT(inout) ::   pt2d     ! 2D array on which the boundary condition is applied 
     934      CHARACTER(len=1)            , INTENT(in   ) ::   cd_type  ! define the nature of ptab array grid-points 
     935      !                                                         ! = T , U , V , F , W and I points 
     936      REAL(wp)                    , INTENT(in   ) ::   psgn     ! =-1 the sign change across the north fold boundary 
     937      !                                                         ! =  1. , the sign is kept 
     938      CHARACTER(len=3), OPTIONAL  , INTENT(in   ) ::   cd_mpp   ! fill the overlap area only  
     939      REAL(wp)        , OPTIONAL  , INTENT(in   ) ::   pval     ! background value (used at closed boundaries) 
     940      !! 
     941      INTEGER  ::   ji, jj, jl   ! dummy loop indices 
     942      INTEGER  ::   imigr, iihom, ijhom        ! temporary integers 
     943      INTEGER  ::   ml_req1, ml_req2, ml_err   ! for key_mpi_isend 
     944      REAL(wp) ::   zland 
     945      INTEGER, DIMENSION(MPI_STATUS_SIZE) ::   ml_stat   ! for key_mpi_isend 
     946      !!---------------------------------------------------------------------- 
     947 
     948      IF( PRESENT( pval ) ) THEN   ;   zland = pval      ! set land value 
     949      ELSE                         ;   zland = 0.e0      ! zero by default 
     950      ENDIF 
     951 
     952      ! 1. standard boundary treatment 
     953      ! ------------------------------ 
     954      ! 
     955      IF( PRESENT( cd_mpp ) ) THEN      ! only fill added line/raw with existing values 
     956         ! 
     957         ! WARNING pt2d is defined only between nld and nle 
     958         DO jj = nlcj+1, jpj                 ! added line(s)   (inner only) 
     959            pt2d(nldi  :nlei  , jj          ) = pt2d(nldi:nlei,     nlej)    
     960            pt2d(1     :nldi-1, jj          ) = pt2d(nldi     ,     nlej) 
     961            pt2d(nlei+1:nlci  , jj          ) = pt2d(     nlei,     nlej) 
     962         END DO 
     963         DO ji = nlci+1, jpi                 ! added column(s) (full) 
     964            pt2d(ji           ,nldj  :nlej  ) = pt2d(     nlei,nldj:nlej) 
     965            pt2d(ji           ,1     :nldj-1) = pt2d(     nlei,nldj     ) 
     966            pt2d(ji           ,nlej+1:jpj   ) = pt2d(     nlei,     nlej) 
     967         END DO 
     968         ! 
     969      ELSE                              ! standard close or cyclic treatment  
     970         ! 
     971         !                                   ! East-West boundaries 
     972         IF( nbondi == 2 .AND.   &                ! Cyclic east-west 
     973            &    (nperio == 1 .OR. nperio == 4 .OR. nperio == 6) ) THEN 
     974            pt2d( 1 ,:) = pt2d(jpim1,:)                                    ! west 
     975            pt2d(jpi,:) = pt2d(  2  ,:)                                    ! east 
     976         ELSE                                     ! closed 
     977            IF( .NOT. cd_type == 'F' )   pt2d(     1       :jpreci,:) = zland    ! south except F-point 
     978                                         pt2d(nlci-jpreci+1:jpi   ,:) = zland    ! north 
     979         ENDIF 
     980         !                                   ! North-South boundaries (always closed) 
     981            IF( .NOT. cd_type == 'F' )   pt2d(:,     1       :jprecj) = zland    !south except F-point 
     982                                         pt2d(:,nlcj-jprecj+1:jpj   ) = zland    ! north 
     983         ! 
     984      ENDIF 
     985 
     986      ! 2. East and west directions exchange 
     987      ! ------------------------------------ 
     988      ! we play with the neigbours AND the row number because of the periodicity  
     989      ! 
     990      SELECT CASE ( nbondi )      ! Read Dirichlet lateral conditions 
     991      CASE ( -1, 0, 1 )                ! all exept 2 (i.e. close case) 
     992         iihom = nlci-nreci 
     993         DO jl = 1, jpreci 
     994            t2ew(:,jl,1) = pt2d(jpreci+jl,:) 
     995            t2we(:,jl,1) = pt2d(iihom +jl,:) 
     996         END DO 
     997      END SELECT 
     998      ! 
     999      !                           ! Migrations 
     1000      imigr = jpreci * jpj 
     1001      ! 
     1002      SELECT CASE ( nbondi ) 
     1003      CASE ( -1 ) 
     1004         CALL mppsend( 2, t2we(1,1,1), imigr, noea, ml_req1 ) 
     1005         CALL mpprecv( 1, t2ew(1,1,2), imigr, noea ) 
     1006         IF(l_isend) CALL mpi_wait(ml_req1,ml_stat,ml_err) 
     1007      CASE ( 0 ) 
     1008         CALL mppsend( 1, t2ew(1,1,1), imigr, nowe, ml_req1 ) 
     1009         CALL mppsend( 2, t2we(1,1,1), imigr, noea, ml_req2 ) 
     1010         CALL mpprecv( 1, t2ew(1,1,2), imigr, noea ) 
     1011         CALL mpprecv( 2, t2we(1,1,2), imigr, nowe ) 
     1012         IF(l_isend) CALL mpi_wait(ml_req1,ml_stat,ml_err) 
     1013         IF(l_isend) CALL mpi_wait(ml_req2,ml_stat,ml_err) 
     1014      CASE ( 1 ) 
     1015         CALL mppsend( 1, t2ew(1,1,1), imigr, nowe, ml_req1 ) 
     1016         CALL mpprecv( 2, t2we(1,1,2), imigr, nowe ) 
     1017         IF(l_isend) CALL mpi_wait(ml_req1,ml_stat,ml_err) 
     1018      END SELECT 
     1019      ! 
     1020      !                           ! Write Dirichlet lateral conditions 
     1021      iihom = nlci - jpreci 
     1022      ! 
     1023      SELECT CASE ( nbondi ) 
     1024      CASE ( -1 ) 
     1025         DO jl = 1, jpreci 
     1026            pt2d(iihom+jl,:) = t2ew(:,jl,2) 
     1027         END DO 
     1028      CASE ( 0 ) 
     1029         DO jl = 1, jpreci 
     1030            pt2d(jl      ,:) = t2we(:,jl,2) 
     1031            pt2d(iihom+jl,:) = t2ew(:,jl,2) 
     1032         END DO 
     1033      CASE ( 1 ) 
     1034         DO jl = 1, jpreci 
     1035            pt2d(jl      ,:) = t2we(:,jl,2) 
     1036         END DO 
     1037      END SELECT 
     1038 
     1039 
     1040      ! 3. North and south directions 
     1041      ! ----------------------------- 
     1042      ! always closed : we play only with the neigbours 
     1043      ! 
     1044      IF( nbondj /= 2 ) THEN      ! Read Dirichlet lateral conditions 
     1045         ijhom = nlcj-nrecj 
     1046         DO jl = 1, jprecj 
     1047            t2sn(:,jl,1) = pt2d(:,ijhom +jl) 
     1048            t2ns(:,jl,1) = pt2d(:,jprecj+jl) 
     1049         END DO 
     1050      ENDIF 
     1051      ! 
     1052      !                           ! Migrations 
     1053      imigr = jprecj * jpi 
     1054      ! 
     1055      SELECT CASE ( nbondj ) 
     1056      CASE ( -1 ) 
     1057         CALL mppsend( 4, t2sn(1,1,1), imigr, nono, ml_req1 ) 
     1058         CALL mpprecv( 3, t2ns(1,1,2), imigr, nono ) 
     1059         IF(l_isend) CALL mpi_wait(ml_req1,ml_stat,ml_err) 
     1060      CASE ( 0 ) 
     1061         CALL mppsend( 3, t2ns(1,1,1), imigr, noso, ml_req1 ) 
     1062         CALL mppsend( 4, t2sn(1,1,1), imigr, nono, ml_req2 ) 
     1063         CALL mpprecv( 3, t2ns(1,1,2), imigr, nono ) 
     1064         CALL mpprecv( 4, t2sn(1,1,2), imigr, noso ) 
     1065         IF(l_isend) CALL mpi_wait(ml_req1,ml_stat,ml_err) 
     1066         IF(l_isend) CALL mpi_wait(ml_req2,ml_stat,ml_err) 
     1067      CASE ( 1 ) 
     1068         CALL mppsend( 3, t2ns(1,1,1), imigr, noso, ml_req1 ) 
     1069         CALL mpprecv( 4, t2sn(1,1,2), imigr, noso ) 
     1070         IF(l_isend) CALL mpi_wait(ml_req1,ml_stat,ml_err) 
     1071      END SELECT 
     1072      ! 
     1073      !                           ! Write Dirichlet lateral conditions 
     1074      ijhom = nlcj - jprecj 
     1075      ! 
     1076      SELECT CASE ( nbondj ) 
     1077      CASE ( -1 ) 
     1078         DO jl = 1, jprecj 
     1079            pt2d(:,ijhom+jl) = t2ns(:,jl,2) 
     1080         END DO 
     1081      CASE ( 0 ) 
     1082         DO jl = 1, jprecj 
     1083            pt2d(:,jl      ) = t2sn(:,jl,2) 
     1084            pt2d(:,ijhom+jl) = t2ns(:,jl,2) 
     1085         END DO 
     1086      CASE ( 1 )  
     1087         DO jl = 1, jprecj 
     1088            pt2d(:,jl      ) = t2sn(:,jl,2) 
     1089         END DO 
     1090      END SELECT 
     1091 
     1092 
     1093      ! 4. north fold treatment 
     1094      ! ----------------------- 
     1095      ! 
    7301096      IF( npolj /= 0 .AND. .NOT. PRESENT(cd_mpp) ) THEN 
    7311097         ! 
     
    17822148      INTEGER ::   ml_stat(MPI_STATUS_SIZE)    ! for key_mpi_isend 
    17832149      REAL(wp), POINTER, DIMENSION(:,:) ::   ztab   ! temporary workspace 
     2150      LOGICAL :: lmigr ! is true for those processors that have to migrate the OB 
    17842151      !!---------------------------------------------------------------------- 
    17852152 
     
    18072174         CALL mppstop 
    18082175      ENDIF 
    1809        
     2176 
    18102177      ! Communication level by level 
    18112178      ! ---------------------------- 
    18122179!!gm Remark : this is very time consumming!!! 
    18132180      !                                         ! ------------------------ ! 
     2181            IF( ijpt0 > ijpt1 .OR. iipt0 > iipt1 ) THEN 
     2182            ! there is nothing to be migrated 
     2183               lmigr = .FALSE. 
     2184            ELSE 
     2185              lmigr = .TRUE. 
     2186            ENDIF 
     2187 
     2188      IF( lmigr ) THEN 
     2189 
    18142190      DO jk = 1, kk                             !   Loop over the levels   ! 
    18152191         !                                      ! ------------------------ ! 
     
    18332209         ! --------------------------- 
    18342210         ! 
     2211       IF( ktype == 1 ) THEN 
     2212 
    18352213         IF( nbondi /= 2 ) THEN         ! Read Dirichlet lateral conditions 
    18362214            iihom = nlci-nreci 
    1837             DO jl = 1, jpreci 
    1838                t2ew(:,jl,1) = ztab(jpreci+jl,:) 
    1839                t2we(:,jl,1) = ztab(iihom +jl,:) 
    1840             END DO 
     2215            t2ew(1:jpreci,1,1) = ztab(jpreci+1:nreci, ijpt0) 
     2216            t2we(1:jpreci,1,1) = ztab(iihom+1:iihom+jpreci, ijpt0) 
    18412217         ENDIF 
    18422218         ! 
    18432219         !                              ! Migrations 
    1844          imigr=jpreci*jpj 
     2220         imigr = jpreci 
    18452221         ! 
    18462222         IF( nbondi == -1 ) THEN 
     
    18652241         ! 
    18662242         IF( nbondi == 0 .OR. nbondi == 1 ) THEN 
    1867             DO jl = 1, jpreci 
    1868                ztab(jl,:) = t2we(:,jl,2) 
    1869             END DO 
     2243            ztab(1:jpreci, ijpt0) = t2we(1:jpreci,1,2) 
    18702244         ENDIF 
    18712245         IF( nbondi == -1 .OR. nbondi == 0 ) THEN 
    1872             DO jl = 1, jpreci 
    1873                ztab(iihom+jl,:) = t2ew(:,jl,2) 
    1874             END DO 
     2246            ztab(iihom+1:iihom+jpreci, ijpt0) = t2ew(1:jpreci,1,2) 
    18752247         ENDIF 
    1876  
     2248       ENDIF  ! (ktype == 1) 
    18772249 
    18782250         ! 2. North and south directions 
    18792251         ! ----------------------------- 
    18802252         ! 
     2253       IF(ktype == 2 ) THEN 
    18812254         IF( nbondj /= 2 ) THEN         ! Read Dirichlet lateral conditions 
    18822255            ijhom = nlcj-nrecj 
    1883             DO jl = 1, jprecj 
    1884                t2sn(:,jl,1) = ztab(:,ijhom +jl) 
    1885                t2ns(:,jl,1) = ztab(:,jprecj+jl) 
    1886             END DO 
     2256            t2sn(1:jprecj,1,1) = ztab(iipt0, ijhom+1:ijhom+jprecj) 
     2257            t2ns(1:jprecj,1,1) = ztab(iipt0, jprecj+1:nrecj) 
    18872258         ENDIF 
    18882259         ! 
    18892260         !                              ! Migrations 
    1890          imigr = jprecj * jpi 
     2261         imigr = jprecj 
    18912262         ! 
    18922263         IF( nbondj == -1 ) THEN 
     
    19102281         ijhom = nlcj - jprecj 
    19112282         IF( nbondj == 0 .OR. nbondj == 1 ) THEN 
    1912             DO jl = 1, jprecj 
    1913                ztab(:,jl) = t2sn(:,jl,2) 
    1914             END DO 
     2283            ztab(iipt0,1:jprecj) = t2sn(1:jprecj,1,2) 
    19152284         ENDIF 
    19162285         IF( nbondj == 0 .OR. nbondj == -1 ) THEN 
    1917             DO jl = 1, jprecj 
    1918                ztab(:,ijhom+jl) = t2ns(:,jl,2) 
    1919             END DO 
     2286            ztab(iipt0, ijhom+1:ijhom+jprecj) = t2ns(1:jprecj,1,2) 
    19202287         ENDIF 
     2288         ENDIF    ! (ktype == 2) 
    19212289         IF( ktype==1 .AND. kd1 <= jpi+nimpp-1 .AND. nimpp <= kd2 ) THEN 
    19222290            DO jj = ijpt0, ijpt1            ! north/south boundaries 
    19232291               DO ji = iipt0,ilpt1 
    1924                   ptab(ji,jk) = ztab(ji,jj)   
     2292                  ptab(ji,jk) = ztab(ji,jj) 
    19252293               END DO 
    19262294            END DO 
     
    19282296            DO jj = ijpt0, ilpt1            ! east/west boundaries 
    19292297               DO ji = iipt0,iipt1 
    1930                   ptab(jj,jk) = ztab(ji,jj)  
     2298                  ptab(jj,jk) = ztab(ji,jj) 
    19312299               END DO 
    19322300            END DO 
     
    19352303      END DO 
    19362304      ! 
     2305      ENDIF ! ( lmigr ) 
    19372306      CALL wrk_dealloc( jpi,jpj, ztab ) 
    19382307      ! 
     
    25342903   END SUBROUTINE mpp_lbc_north_e 
    25352904 
     2905      SUBROUTINE mpp_lnk_bdy_3d( ptab, cd_type, psgn, ib_bdy ) 
     2906      !!---------------------------------------------------------------------- 
     2907      !!                  ***  routine mpp_lnk_bdy_3d  *** 
     2908      !! 
     2909      !! ** Purpose :   Message passing management 
     2910      !! 
     2911      !! ** Method  :   Use mppsend and mpprecv function for passing BDY boundaries  
     2912      !!      between processors following neighboring subdomains. 
     2913      !!            domain parameters 
     2914      !!                    nlci   : first dimension of the local subdomain 
     2915      !!                    nlcj   : second dimension of the local subdomain 
     2916      !!                    nbondi_bdy : mark for "east-west local boundary" 
     2917      !!                    nbondj_bdy : mark for "north-south local boundary" 
     2918      !!                    noea   : number for local neighboring processors  
     2919      !!                    nowe   : number for local neighboring processors 
     2920      !!                    noso   : number for local neighboring processors 
     2921      !!                    nono   : number for local neighboring processors 
     2922      !! 
     2923      !! ** Action  :   ptab with update value at its periphery 
     2924      !! 
     2925      !!---------------------------------------------------------------------- 
     2926 
     2927      USE lbcnfd          ! north fold 
     2928 
     2929      INCLUDE 'mpif.h' 
     2930 
     2931      REAL(wp), DIMENSION(jpi,jpj,jpk), INTENT(inout) ::   ptab     ! 3D array on which the boundary condition is applied 
     2932      CHARACTER(len=1)                , INTENT(in   ) ::   cd_type  ! define the nature of ptab array grid-points 
     2933      !                                                             ! = T , U , V , F , W points 
     2934      REAL(wp)                        , INTENT(in   ) ::   psgn     ! =-1 the sign change across the north fold boundary 
     2935      !                                                             ! =  1. , the sign is kept 
     2936      INTEGER                         , INTENT(in   ) ::   ib_bdy   ! BDY boundary set 
     2937      INTEGER  ::   ji, jj, jk, jl             ! dummy loop indices 
     2938      INTEGER  ::   imigr, iihom, ijhom        ! temporary integers 
     2939      INTEGER  ::   ml_req1, ml_req2, ml_err   ! for key_mpi_isend 
     2940      REAL(wp) ::   zland 
     2941      INTEGER, DIMENSION(MPI_STATUS_SIZE) ::   ml_stat   ! for key_mpi_isend 
     2942      !!---------------------------------------------------------------------- 
     2943 
     2944      zland = 0.e0 
     2945 
     2946      ! 1. standard boundary treatment 
     2947      ! ------------------------------ 
     2948       
     2949      !                                   ! East-West boundaries 
     2950      !                                        !* Cyclic east-west 
     2951 
     2952      IF( nbondi == 2) THEN 
     2953        IF (nperio == 1 .OR. nperio == 4 .OR. nperio == 6) THEN 
     2954          ptab( 1 ,:,:) = ptab(jpim1,:,:) 
     2955          ptab(jpi,:,:) = ptab(  2  ,:,:) 
     2956        ELSE 
     2957          IF( .NOT. cd_type == 'F' )   ptab(     1       :jpreci,:,:) = zland    ! south except F-point 
     2958          ptab(nlci-jpreci+1:jpi   ,:,:) = zland    ! north 
     2959        ENDIF 
     2960      ELSEIF(nbondi == -1) THEN 
     2961        IF( .NOT. cd_type == 'F' )   ptab(     1       :jpreci,:,:) = zland    ! south except F-point 
     2962      ELSEIF(nbondi == 1) THEN 
     2963        ptab(nlci-jpreci+1:jpi   ,:,:) = zland    ! north 
     2964      ENDIF                                     !* closed 
     2965 
     2966      IF (nbondj == 2 .OR. nbondj == -1) THEN 
     2967        IF( .NOT. cd_type == 'F' )   ptab(:,     1       :jprecj,:) = zland       ! south except F-point 
     2968      ELSEIF (nbondj == 2 .OR. nbondj == 1) THEN 
     2969        ptab(:,nlcj-jprecj+1:jpj   ,:) = zland       ! north 
     2970      ENDIF 
     2971       
     2972      ! 
     2973 
     2974      ! 2. East and west directions exchange 
     2975      ! ------------------------------------ 
     2976      ! we play with the neigbours AND the row number because of the periodicity  
     2977      ! 
     2978      SELECT CASE ( nbondi_bdy(ib_bdy) )      ! Read Dirichlet lateral conditions 
     2979      CASE ( -1, 0, 1 )                ! all exept 2 (i.e. close case) 
     2980         iihom = nlci-nreci 
     2981         DO jl = 1, jpreci 
     2982            t3ew(:,jl,:,1) = ptab(jpreci+jl,:,:) 
     2983            t3we(:,jl,:,1) = ptab(iihom +jl,:,:) 
     2984         END DO 
     2985      END SELECT 
     2986      ! 
     2987      !                           ! Migrations 
     2988      imigr = jpreci * jpj * jpk 
     2989      ! 
     2990      SELECT CASE ( nbondi_bdy(ib_bdy) ) 
     2991      CASE ( -1 ) 
     2992         CALL mppsend( 2, t3we(1,1,1,1), imigr, noea, ml_req1 ) 
     2993      CASE ( 0 ) 
     2994         CALL mppsend( 1, t3ew(1,1,1,1), imigr, nowe, ml_req1 ) 
     2995         CALL mppsend( 2, t3we(1,1,1,1), imigr, noea, ml_req2 ) 
     2996      CASE ( 1 ) 
     2997         CALL mppsend( 1, t3ew(1,1,1,1), imigr, nowe, ml_req1 ) 
     2998      END SELECT 
     2999      ! 
     3000      SELECT CASE ( nbondi_bdy_b(ib_bdy) ) 
     3001      CASE ( -1 ) 
     3002         CALL mpprecv( 1, t3ew(1,1,1,2), imigr, noea ) 
     3003      CASE ( 0 ) 
     3004         CALL mpprecv( 1, t3ew(1,1,1,2), imigr, noea ) 
     3005         CALL mpprecv( 2, t3we(1,1,1,2), imigr, nowe ) 
     3006      CASE ( 1 ) 
     3007         CALL mpprecv( 2, t3we(1,1,1,2), imigr, nowe ) 
     3008      END SELECT 
     3009      ! 
     3010      SELECT CASE ( nbondi_bdy(ib_bdy) ) 
     3011      CASE ( -1 ) 
     3012         IF(l_isend) CALL mpi_wait(ml_req1, ml_stat, ml_err) 
     3013      CASE ( 0 ) 
     3014         IF(l_isend) CALL mpi_wait(ml_req1, ml_stat, ml_err) 
     3015         IF(l_isend) CALL mpi_wait(ml_req2, ml_stat, ml_err) 
     3016      CASE ( 1 ) 
     3017         IF(l_isend) CALL mpi_wait(ml_req1, ml_stat, ml_err) 
     3018      END SELECT 
     3019      ! 
     3020      !                           ! Write Dirichlet lateral conditions 
     3021      iihom = nlci-jpreci 
     3022      ! 
     3023      SELECT CASE ( nbondi_bdy_b(ib_bdy) ) 
     3024      CASE ( -1 ) 
     3025         DO jl = 1, jpreci 
     3026            ptab(iihom+jl,:,:) = t3ew(:,jl,:,2) 
     3027         END DO 
     3028      CASE ( 0 ) 
     3029         DO jl = 1, jpreci 
     3030            ptab(jl      ,:,:) = t3we(:,jl,:,2) 
     3031            ptab(iihom+jl,:,:) = t3ew(:,jl,:,2) 
     3032         END DO 
     3033      CASE ( 1 ) 
     3034         DO jl = 1, jpreci 
     3035            ptab(jl      ,:,:) = t3we(:,jl,:,2) 
     3036         END DO 
     3037      END SELECT 
     3038 
     3039 
     3040      ! 3. North and south directions 
     3041      ! ----------------------------- 
     3042      ! always closed : we play only with the neigbours 
     3043      ! 
     3044      IF( nbondj_bdy(ib_bdy) /= 2 ) THEN      ! Read Dirichlet lateral conditions 
     3045         ijhom = nlcj-nrecj 
     3046         DO jl = 1, jprecj 
     3047            t3sn(:,jl,:,1) = ptab(:,ijhom +jl,:) 
     3048            t3ns(:,jl,:,1) = ptab(:,jprecj+jl,:) 
     3049         END DO 
     3050      ENDIF 
     3051      ! 
     3052      !                           ! Migrations 
     3053      imigr = jprecj * jpi * jpk 
     3054      ! 
     3055      SELECT CASE ( nbondj_bdy(ib_bdy) ) 
     3056      CASE ( -1 ) 
     3057         CALL mppsend( 4, t3sn(1,1,1,1), imigr, nono, ml_req1 ) 
     3058      CASE ( 0 ) 
     3059         CALL mppsend( 3, t3ns(1,1,1,1), imigr, noso, ml_req1 ) 
     3060         CALL mppsend( 4, t3sn(1,1,1,1), imigr, nono, ml_req2 ) 
     3061      CASE ( 1 ) 
     3062         CALL mppsend( 3, t3ns(1,1,1,1), imigr, noso, ml_req1 ) 
     3063      END SELECT 
     3064      ! 
     3065      SELECT CASE ( nbondj_bdy_b(ib_bdy) ) 
     3066      CASE ( -1 ) 
     3067         CALL mpprecv( 3, t3ns(1,1,1,2), imigr, nono ) 
     3068      CASE ( 0 ) 
     3069         CALL mpprecv( 3, t3ns(1,1,1,2), imigr, nono ) 
     3070         CALL mpprecv( 4, t3sn(1,1,1,2), imigr, noso ) 
     3071      CASE ( 1 ) 
     3072         CALL mpprecv( 4, t3sn(1,1,1,2), imigr, noso ) 
     3073      END SELECT 
     3074      ! 
     3075      SELECT CASE ( nbondj_bdy(ib_bdy) ) 
     3076      CASE ( -1 ) 
     3077         IF(l_isend) CALL mpi_wait(ml_req1, ml_stat, ml_err) 
     3078      CASE ( 0 ) 
     3079         IF(l_isend) CALL mpi_wait(ml_req1, ml_stat, ml_err) 
     3080         IF(l_isend) CALL mpi_wait(ml_req2, ml_stat, ml_err) 
     3081      CASE ( 1 ) 
     3082         IF(l_isend) CALL mpi_wait(ml_req1, ml_stat, ml_err) 
     3083      END SELECT 
     3084      ! 
     3085      !                           ! Write Dirichlet lateral conditions 
     3086      ijhom = nlcj-jprecj 
     3087      ! 
     3088      SELECT CASE ( nbondj_bdy_b(ib_bdy) ) 
     3089      CASE ( -1 ) 
     3090         DO jl = 1, jprecj 
     3091            ptab(:,ijhom+jl,:) = t3ns(:,jl,:,2) 
     3092         END DO 
     3093      CASE ( 0 ) 
     3094         DO jl = 1, jprecj 
     3095            ptab(:,jl      ,:) = t3sn(:,jl,:,2) 
     3096            ptab(:,ijhom+jl,:) = t3ns(:,jl,:,2) 
     3097         END DO 
     3098      CASE ( 1 ) 
     3099         DO jl = 1, jprecj 
     3100            ptab(:,jl,:) = t3sn(:,jl,:,2) 
     3101         END DO 
     3102      END SELECT 
     3103 
     3104 
     3105      ! 4. north fold treatment 
     3106      ! ----------------------- 
     3107      ! 
     3108      IF( npolj /= 0) THEN 
     3109         ! 
     3110         SELECT CASE ( jpni ) 
     3111         CASE ( 1 )     ;   CALL lbc_nfd      ( ptab, cd_type, psgn )   ! only 1 northern proc, no mpp 
     3112         CASE DEFAULT   ;   CALL mpp_lbc_north( ptab, cd_type, psgn )   ! for all northern procs. 
     3113         END SELECT 
     3114         ! 
     3115      ENDIF 
     3116      ! 
     3117   END SUBROUTINE mpp_lnk_bdy_3d 
     3118 
     3119      SUBROUTINE mpp_lnk_bdy_2d( ptab, cd_type, psgn, ib_bdy ) 
     3120      !!---------------------------------------------------------------------- 
     3121      !!                  ***  routine mpp_lnk_bdy_2d  *** 
     3122      !! 
     3123      !! ** Purpose :   Message passing management 
     3124      !! 
     3125      !! ** Method  :   Use mppsend and mpprecv function for passing BDY boundaries  
     3126      !!      between processors following neighboring subdomains. 
     3127      !!            domain parameters 
     3128      !!                    nlci   : first dimension of the local subdomain 
     3129      !!                    nlcj   : second dimension of the local subdomain 
     3130      !!                    nbondi_bdy : mark for "east-west local boundary" 
     3131      !!                    nbondj_bdy : mark for "north-south local boundary" 
     3132      !!                    noea   : number for local neighboring processors  
     3133      !!                    nowe   : number for local neighboring processors 
     3134      !!                    noso   : number for local neighboring processors 
     3135      !!                    nono   : number for local neighboring processors 
     3136      !! 
     3137      !! ** Action  :   ptab with update value at its periphery 
     3138      !! 
     3139      !!---------------------------------------------------------------------- 
     3140 
     3141      USE lbcnfd          ! north fold 
     3142 
     3143      INCLUDE 'mpif.h' 
     3144 
     3145      REAL(wp), DIMENSION(jpi,jpj)    , INTENT(inout) ::   ptab     ! 3D array on which the boundary condition is applied 
     3146      CHARACTER(len=1)                , INTENT(in   ) ::   cd_type  ! define the nature of ptab array grid-points 
     3147      !                                                             ! = T , U , V , F , W points 
     3148      REAL(wp)                        , INTENT(in   ) ::   psgn     ! =-1 the sign change across the north fold boundary 
     3149      !                                                             ! =  1. , the sign is kept 
     3150      INTEGER                         , INTENT(in   ) ::   ib_bdy   ! BDY boundary set 
     3151      INTEGER  ::   ji, jj, jl             ! dummy loop indices 
     3152      INTEGER  ::   imigr, iihom, ijhom        ! temporary integers 
     3153      INTEGER  ::   ml_req1, ml_req2, ml_err   ! for key_mpi_isend 
     3154      REAL(wp) ::   zland 
     3155      INTEGER, DIMENSION(MPI_STATUS_SIZE) ::   ml_stat   ! for key_mpi_isend 
     3156      !!---------------------------------------------------------------------- 
     3157 
     3158      zland = 0.e0 
     3159 
     3160      ! 1. standard boundary treatment 
     3161      ! ------------------------------ 
     3162       
     3163      !                                   ! East-West boundaries 
     3164      !                                        !* Cyclic east-west 
     3165 
     3166      IF( nbondi == 2) THEN 
     3167        IF (nperio == 1 .OR. nperio == 4 .OR. nperio == 6) THEN 
     3168          ptab( 1 ,:) = ptab(jpim1,:) 
     3169          ptab(jpi,:) = ptab(  2  ,:) 
     3170        ELSE 
     3171          IF( .NOT. cd_type == 'F' )   ptab(     1       :jpreci,:) = zland    ! south except F-point 
     3172          ptab(nlci-jpreci+1:jpi   ,:) = zland    ! north 
     3173        ENDIF 
     3174      ELSEIF(nbondi == -1) THEN 
     3175        IF( .NOT. cd_type == 'F' )   ptab(     1       :jpreci,:) = zland    ! south except F-point 
     3176      ELSEIF(nbondi == 1) THEN 
     3177        ptab(nlci-jpreci+1:jpi   ,:) = zland    ! north 
     3178      ENDIF                                     !* closed 
     3179 
     3180      IF (nbondj == 2 .OR. nbondj == -1) THEN 
     3181        IF( .NOT. cd_type == 'F' )   ptab(:,     1       :jprecj) = zland       ! south except F-point 
     3182      ELSEIF (nbondj == 2 .OR. nbondj == 1) THEN 
     3183        ptab(:,nlcj-jprecj+1:jpj) = zland       ! north 
     3184      ENDIF 
     3185       
     3186      ! 
     3187 
     3188      ! 2. East and west directions exchange 
     3189      ! ------------------------------------ 
     3190      ! we play with the neigbours AND the row number because of the periodicity  
     3191      ! 
     3192      SELECT CASE ( nbondi_bdy(ib_bdy) )      ! Read Dirichlet lateral conditions 
     3193      CASE ( -1, 0, 1 )                ! all exept 2 (i.e. close case) 
     3194         iihom = nlci-nreci 
     3195         DO jl = 1, jpreci 
     3196            t2ew(:,jl,1) = ptab(jpreci+jl,:) 
     3197            t2we(:,jl,1) = ptab(iihom +jl,:) 
     3198         END DO 
     3199      END SELECT 
     3200      ! 
     3201      !                           ! Migrations 
     3202      imigr = jpreci * jpj 
     3203      ! 
     3204      SELECT CASE ( nbondi_bdy(ib_bdy) ) 
     3205      CASE ( -1 ) 
     3206         CALL mppsend( 2, t2we(1,1,1), imigr, noea, ml_req1 ) 
     3207      CASE ( 0 ) 
     3208         CALL mppsend( 1, t2ew(1,1,1), imigr, nowe, ml_req1 ) 
     3209         CALL mppsend( 2, t2we(1,1,1), imigr, noea, ml_req2 ) 
     3210      CASE ( 1 ) 
     3211         CALL mppsend( 1, t2ew(1,1,1), imigr, nowe, ml_req1 ) 
     3212      END SELECT 
     3213      ! 
     3214      SELECT CASE ( nbondi_bdy_b(ib_bdy) ) 
     3215      CASE ( -1 ) 
     3216         CALL mpprecv( 1, t2ew(1,1,2), imigr, noea ) 
     3217      CASE ( 0 ) 
     3218         CALL mpprecv( 1, t2ew(1,1,2), imigr, noea ) 
     3219         CALL mpprecv( 2, t2we(1,1,2), imigr, nowe ) 
     3220      CASE ( 1 ) 
     3221         CALL mpprecv( 2, t2we(1,1,2), imigr, nowe ) 
     3222      END SELECT 
     3223      ! 
     3224      SELECT CASE ( nbondi_bdy(ib_bdy) ) 
     3225      CASE ( -1 ) 
     3226         IF(l_isend) CALL mpi_wait(ml_req1, ml_stat, ml_err) 
     3227      CASE ( 0 ) 
     3228         IF(l_isend) CALL mpi_wait(ml_req1, ml_stat, ml_err) 
     3229         IF(l_isend) CALL mpi_wait(ml_req2, ml_stat, ml_err) 
     3230      CASE ( 1 ) 
     3231         IF(l_isend) CALL mpi_wait(ml_req1, ml_stat, ml_err) 
     3232      END SELECT 
     3233      ! 
     3234      !                           ! Write Dirichlet lateral conditions 
     3235      iihom = nlci-jpreci 
     3236      ! 
     3237      SELECT CASE ( nbondi_bdy_b(ib_bdy) ) 
     3238      CASE ( -1 ) 
     3239         DO jl = 1, jpreci 
     3240            ptab(iihom+jl,:) = t2ew(:,jl,2) 
     3241         END DO 
     3242      CASE ( 0 ) 
     3243         DO jl = 1, jpreci 
     3244            ptab(jl      ,:) = t2we(:,jl,2) 
     3245            ptab(iihom+jl,:) = t2ew(:,jl,2) 
     3246         END DO 
     3247      CASE ( 1 ) 
     3248         DO jl = 1, jpreci 
     3249            ptab(jl      ,:) = t2we(:,jl,2) 
     3250         END DO 
     3251      END SELECT 
     3252 
     3253 
     3254      ! 3. North and south directions 
     3255      ! ----------------------------- 
     3256      ! always closed : we play only with the neigbours 
     3257      ! 
     3258      IF( nbondj_bdy(ib_bdy) /= 2 ) THEN      ! Read Dirichlet lateral conditions 
     3259         ijhom = nlcj-nrecj 
     3260         DO jl = 1, jprecj 
     3261            t2sn(:,jl,1) = ptab(:,ijhom +jl) 
     3262            t2ns(:,jl,1) = ptab(:,jprecj+jl) 
     3263         END DO 
     3264      ENDIF 
     3265      ! 
     3266      !                           ! Migrations 
     3267      imigr = jprecj * jpi 
     3268      ! 
     3269      SELECT CASE ( nbondj_bdy(ib_bdy) ) 
     3270      CASE ( -1 ) 
     3271         CALL mppsend( 4, t2sn(1,1,1), imigr, nono, ml_req1 ) 
     3272      CASE ( 0 ) 
     3273         CALL mppsend( 3, t2ns(1,1,1), imigr, noso, ml_req1 ) 
     3274         CALL mppsend( 4, t2sn(1,1,1), imigr, nono, ml_req2 ) 
     3275      CASE ( 1 ) 
     3276         CALL mppsend( 3, t2ns(1,1,1), imigr, noso, ml_req1 ) 
     3277      END SELECT 
     3278      ! 
     3279      SELECT CASE ( nbondj_bdy_b(ib_bdy) ) 
     3280      CASE ( -1 ) 
     3281         CALL mpprecv( 3, t2ns(1,1,2), imigr, nono ) 
     3282      CASE ( 0 ) 
     3283         CALL mpprecv( 3, t2ns(1,1,2), imigr, nono ) 
     3284         CALL mpprecv( 4, t2sn(1,1,2), imigr, noso ) 
     3285      CASE ( 1 ) 
     3286         CALL mpprecv( 4, t2sn(1,1,2), imigr, noso ) 
     3287      END SELECT 
     3288      ! 
     3289      SELECT CASE ( nbondj_bdy(ib_bdy) ) 
     3290      CASE ( -1 ) 
     3291         IF(l_isend) CALL mpi_wait(ml_req1, ml_stat, ml_err) 
     3292      CASE ( 0 ) 
     3293         IF(l_isend) CALL mpi_wait(ml_req1, ml_stat, ml_err) 
     3294         IF(l_isend) CALL mpi_wait(ml_req2, ml_stat, ml_err) 
     3295      CASE ( 1 ) 
     3296         IF(l_isend) CALL mpi_wait(ml_req1, ml_stat, ml_err) 
     3297      END SELECT 
     3298      ! 
     3299      !                           ! Write Dirichlet lateral conditions 
     3300      ijhom = nlcj-jprecj 
     3301      ! 
     3302      SELECT CASE ( nbondj_bdy_b(ib_bdy) ) 
     3303      CASE ( -1 ) 
     3304         DO jl = 1, jprecj 
     3305            ptab(:,ijhom+jl) = t2ns(:,jl,2) 
     3306         END DO 
     3307      CASE ( 0 ) 
     3308         DO jl = 1, jprecj 
     3309            ptab(:,jl      ) = t2sn(:,jl,2) 
     3310            ptab(:,ijhom+jl) = t2ns(:,jl,2) 
     3311         END DO 
     3312      CASE ( 1 ) 
     3313         DO jl = 1, jprecj 
     3314            ptab(:,jl) = t2sn(:,jl,2) 
     3315         END DO 
     3316      END SELECT 
     3317 
     3318 
     3319      ! 4. north fold treatment 
     3320      ! ----------------------- 
     3321      ! 
     3322      IF( npolj /= 0) THEN 
     3323         ! 
     3324         SELECT CASE ( jpni ) 
     3325         CASE ( 1 )     ;   CALL lbc_nfd      ( ptab, cd_type, psgn )   ! only 1 northern proc, no mpp 
     3326         CASE DEFAULT   ;   CALL mpp_lbc_north( ptab, cd_type, psgn )   ! for all northern procs. 
     3327         END SELECT 
     3328         ! 
     3329      ENDIF 
     3330      ! 
     3331   END SUBROUTINE mpp_lnk_bdy_2d 
    25363332 
    25373333   SUBROUTINE mpi_init_opa( ldtxt, ksft, code ) 
Note: See TracChangeset for help on using the changeset viewer.