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 13766 for NEMO/branches/2020/dev_12905_xios_ancil/src/OCE/LBC – NEMO

Ignore:
Timestamp:
2020-11-10T12:57:08+01:00 (4 years ago)
Author:
andmirek
Message:

Ticket #2475: merge with trunk rev 13688

Location:
NEMO/branches/2020/dev_12905_xios_ancil
Files:
13 edited
3 copied

Legend:

Unmodified
Added
Removed
  • NEMO/branches/2020/dev_12905_xios_ancil

    • Property svn:externals
      •  

        old new  
        33^/utils/build/mk@HEAD         mk 
        44^/utils/tools@HEAD            tools 
        5 ^/vendors/AGRIF/dev@HEAD      ext/AGRIF 
         5^/vendors/AGRIF/dev_r12970_AGRIF_CMEMS      ext/AGRIF 
        66^/vendors/FCM@HEAD            ext/FCM 
        77^/vendors/IOIPSL@HEAD         ext/IOIPSL 
        88 
        99# SETTE 
        10 ^/utils/CI/sette@HEAD         sette 
         10^/utils/CI/sette@13559        sette 
  • NEMO/branches/2020/dev_12905_xios_ancil/src/OCE/LBC/lbc_lnk_multi_generic.h90

    r11536 r13766  
    1 #if defined DIM_2d 
    2 #   define ARRAY_TYPE(i,j,k,l)   REAL(wp), DIMENSION(i,j) 
    3 #   define PTR_TYPE              TYPE(PTR_2D) 
    4 #   define PTR_ptab              pt2d 
    5 #endif 
    6 #if defined DIM_3d 
    7 #   define ARRAY_TYPE(i,j,k,l)   REAL(wp), DIMENSION(i,j,k) 
    8 #   define PTR_TYPE              TYPE(PTR_3D) 
    9 #   define PTR_ptab              pt3d 
    10 #endif 
    11 #if defined DIM_4d 
    12 #   define ARRAY_TYPE(i,j,k,l)   REAL(wp), DIMENSION(i,j,k,l) 
    13 #   define PTR_TYPE              TYPE(PTR_4D) 
    14 #   define PTR_ptab              pt4d 
     1#if defined SINGLE_PRECISION 
     2#   if defined DIM_2d 
     3#      define ARRAY_TYPE(i,j,k,l)   REAL(sp), DIMENSION(i,j) 
     4#      define PTR_TYPE              TYPE(PTR_2D_sp) 
     5#      define PTR_ptab              pt2d 
     6#   endif 
     7#   if defined DIM_3d 
     8#      define ARRAY_TYPE(i,j,k,l)   REAL(sp), DIMENSION(i,j,k) 
     9#      define PTR_TYPE              TYPE(PTR_3D_sp) 
     10#      define PTR_ptab              pt3d 
     11#   endif 
     12#   if defined DIM_4d 
     13#      define ARRAY_TYPE(i,j,k,l)   REAL(sp), DIMENSION(i,j,k,l) 
     14#      define PTR_TYPE              TYPE(PTR_4D_sp) 
     15#      define PTR_ptab              pt4d 
     16#   endif 
     17#   define PRECISION sp 
     18#else 
     19#   if defined DIM_2d 
     20#      define ARRAY_TYPE(i,j,k,l)   REAL(dp), DIMENSION(i,j) 
     21#      define PTR_TYPE              TYPE(PTR_2D_dp) 
     22#      define PTR_ptab              pt2d 
     23#   endif 
     24#   if defined DIM_3d 
     25#      define ARRAY_TYPE(i,j,k,l)   REAL(dp), DIMENSION(i,j,k) 
     26#      define PTR_TYPE              TYPE(PTR_3D_dp) 
     27#      define PTR_ptab              pt3d 
     28#   endif 
     29#   if defined DIM_4d 
     30#      define ARRAY_TYPE(i,j,k,l)   REAL(dp), DIMENSION(i,j,k,l) 
     31#      define PTR_TYPE              TYPE(PTR_4D_dp) 
     32#      define PTR_ptab              pt4d 
     33#   endif 
     34#   define PRECISION dp 
    1535#endif 
    1636 
    17    SUBROUTINE ROUTINE_MULTI( cdname                                                                             & 
    18       &                    , pt1, cdna1, psgn1, pt2 , cdna2 , psgn2 , pt3 , cdna3 , psgn3 , pt4, cdna4, psgn4   & 
    19       &                    , pt5, cdna5, psgn5, pt6 , cdna6 , psgn6 , pt7 , cdna7 , psgn7 , pt8, cdna8, psgn8   & 
    20       &                    , pt9, cdna9, psgn9, pt10, cdna10, psgn10, pt11, cdna11, psgn11                      & 
    21       &                    , kfillmode, pfillval, lsend, lrecv, ihlcom ) 
     37   SUBROUTINE ROUTINE_MULTI( cdname                                                                               & 
     38      &                    , pt1 , cdna1 , psgn1 , pt2 , cdna2 , psgn2 , pt3 , cdna3 , psgn3 , pt4 , cdna4 , psgn4   & 
     39      &                    , pt5 , cdna5 , psgn5 , pt6 , cdna6 , psgn6 , pt7 , cdna7 , psgn7 , pt8 , cdna8 , psgn8   & 
     40      &                    , pt9 , cdna9 , psgn9 , pt10, cdna10, psgn10, pt11, cdna11, psgn11, pt12, cdna12, psgn12  & 
     41      &                    , pt13, cdna13, psgn13, pt14, cdna14, psgn14, pt15, cdna15, psgn15, pt16, cdna16, psgn16  & 
     42      &                    , kfillmode, pfillval, lsend, lrecv ) 
    2243      !!--------------------------------------------------------------------- 
    23       CHARACTER(len=*)   ,                   INTENT(in   ) :: cdname  ! name of the calling subroutine 
    24       ARRAY_TYPE(:,:,:,:)          , TARGET, INTENT(inout) :: pt1     ! arrays on which the lbc is applied 
    25       ARRAY_TYPE(:,:,:,:), OPTIONAL, TARGET, INTENT(inout) :: pt2  , pt3  , pt4  , pt5  , pt6  , pt7  , pt8  , pt9  , pt10  , pt11 
    26       CHARACTER(len=1)                     , INTENT(in   ) :: cdna1   ! nature of pt2D. array grid-points 
    27       CHARACTER(len=1)   , OPTIONAL        , INTENT(in   ) :: cdna2, cdna3, cdna4, cdna5, cdna6, cdna7, cdna8, cdna9, cdna10, cdna11 
    28       REAL(wp)                             , INTENT(in   ) :: psgn1   ! sign used across the north fold 
    29       REAL(wp)           , OPTIONAL        , INTENT(in   ) :: psgn2, psgn3, psgn4, psgn5, psgn6, psgn7, psgn8, psgn9, psgn10, psgn11 
    30       INTEGER            , OPTIONAL        , INTENT(in   ) :: kfillmode   ! filling method for halo over land (default = constant) 
    31       REAL(wp)           , OPTIONAL        , INTENT(in   ) :: pfillval    ! background value (used at closed boundaries) 
    32       LOGICAL, DIMENSION(4), OPTIONAL      , INTENT(in   ) :: lsend, lrecv   ! indicate how communications are to be carried out 
    33       INTEGER            , OPTIONAL        , INTENT(in   ) :: ihlcom         ! number of ranks and rows to be communicated 
     44      CHARACTER(len=*)     ,                   INTENT(in   ) ::   cdname  ! name of the calling subroutine 
     45      ARRAY_TYPE(:,:,:,:)            , TARGET, INTENT(inout) ::   pt1     ! arrays on which the lbc is applied 
     46      ARRAY_TYPE(:,:,:,:)  , OPTIONAL, TARGET, INTENT(inout) ::   pt2   , pt3   , pt4   , pt5   , pt6   , pt7   , pt8   , pt9  , & 
     47         &                                                        pt10  , pt11  , pt12  , pt13  , pt14  , pt15  , pt16 
     48      CHARACTER(len=1)                       , INTENT(in   ) ::   cdna1   ! nature of pt2D. array grid-points 
     49      CHARACTER(len=1)     , OPTIONAL        , INTENT(in   ) ::   cdna2 , cdna3 , cdna4 , cdna5 , cdna6 , cdna7 , cdna8 , cdna9, & 
     50         &                                                        cdna10, cdna11, cdna12, cdna13, cdna14, cdna15, cdna16 
     51      REAL(wp)                               , INTENT(in   ) ::   psgn1   ! sign used across the north fold 
     52      REAL(wp)             , OPTIONAL        , INTENT(in   ) ::   psgn2 , psgn3 , psgn4 , psgn5 , psgn6 , psgn7 , psgn8 , psgn9, & 
     53         &                                                        psgn10, psgn11, psgn12, psgn13, psgn14, psgn15, psgn16 
     54      INTEGER              , OPTIONAL        , INTENT(in   ) ::   kfillmode   ! filling method for halo over land (default = constant) 
     55      REAL(wp)             , OPTIONAL        , INTENT(in   ) ::   pfillval    ! background value (used at closed boundaries) 
     56      LOGICAL, DIMENSION(4), OPTIONAL        , INTENT(in   ) ::   lsend, lrecv   ! indicate how communications are to be carried out 
    3457      !! 
    3558      INTEGER                          ::   kfld        ! number of elements that will be attributed 
    36       PTR_TYPE         , DIMENSION(11) ::   ptab_ptr    ! pointer array 
    37       CHARACTER(len=1) , DIMENSION(11) ::   cdna_ptr    ! nature of ptab_ptr grid-points 
    38       REAL(wp)         , DIMENSION(11) ::   psgn_ptr    ! sign used across the north fold boundary 
     59      PTR_TYPE         , DIMENSION(16) ::   ptab_ptr    ! pointer array 
     60      CHARACTER(len=1) , DIMENSION(16) ::   cdna_ptr    ! nature of ptab_ptr grid-points 
     61      REAL(wp)         , DIMENSION(16) ::   psgn_ptr    ! sign used across the north fold boundary 
    3962      !!--------------------------------------------------------------------- 
    4063      ! 
     
    5578      IF( PRESENT(psgn10) )   CALL ROUTINE_LOAD( pt10, cdna10, psgn10, ptab_ptr, cdna_ptr, psgn_ptr, kfld ) 
    5679      IF( PRESENT(psgn11) )   CALL ROUTINE_LOAD( pt11, cdna11, psgn11, ptab_ptr, cdna_ptr, psgn_ptr, kfld ) 
     80      IF( PRESENT(psgn12) )   CALL ROUTINE_LOAD( pt12, cdna12, psgn12, ptab_ptr, cdna_ptr, psgn_ptr, kfld ) 
     81      IF( PRESENT(psgn13) )   CALL ROUTINE_LOAD( pt13, cdna13, psgn13, ptab_ptr, cdna_ptr, psgn_ptr, kfld ) 
     82      IF( PRESENT(psgn14) )   CALL ROUTINE_LOAD( pt14, cdna14, psgn14, ptab_ptr, cdna_ptr, psgn_ptr, kfld ) 
     83      IF( PRESENT(psgn15) )   CALL ROUTINE_LOAD( pt15, cdna15, psgn15, ptab_ptr, cdna_ptr, psgn_ptr, kfld ) 
     84      IF( PRESENT(psgn16) )   CALL ROUTINE_LOAD( pt16, cdna16, psgn16, ptab_ptr, cdna_ptr, psgn_ptr, kfld ) 
    5785      ! 
    58       CALL lbc_lnk_ptr    ( cdname,               ptab_ptr, cdna_ptr, psgn_ptr, kfld, kfillmode, pfillval, lsend, lrecv, ihlcom ) 
     86      CALL lbc_lnk_ptr( cdname, ptab_ptr, cdna_ptr, psgn_ptr, kfld, kfillmode, pfillval, lsend, lrecv ) 
    5987      ! 
    6088   END SUBROUTINE ROUTINE_MULTI 
     
    79107   END SUBROUTINE ROUTINE_LOAD 
    80108 
     109#undef PRECISION 
    81110#undef ARRAY_TYPE 
    82111#undef PTR_TYPE 
  • NEMO/branches/2020/dev_12905_xios_ancil/src/OCE/LBC/lbc_nfd_ext_generic.h90

    r10525 r13766  
    88#   define L_SIZE(ptab)          1 
    99#endif 
    10 #define ARRAY_TYPE(i,j,k,l,f)    REAL(wp),INTENT(inout)::ARRAY_IN(i,j,k,l,f) 
     10#if defined SINGLE_PRECISION 
     11#   define ARRAY_TYPE(i,j,k,l,f)    REAL(sp),INTENT(inout)::ARRAY_IN(i,j,k,l,f) 
     12#   define PRECISION sp 
     13#else 
     14#   define ARRAY_TYPE(i,j,k,l,f)    REAL(dp),INTENT(inout)::ARRAY_IN(i,j,k,l,f) 
     15#   define PRECISION dp 
     16#endif 
    1117 
    1218   SUBROUTINE ROUTINE_NFD( ptab, cd_nat, psgn, kextj ) 
     
    2834      ! 
    2935      SELECT CASE ( jpni ) 
    30       CASE ( 1 )     ;   ipj = nlcj       ! 1 proc only  along the i-direction 
     36      CASE ( 1 )     ;   ipj = jpj        ! 1 proc only  along the i-direction 
    3137      CASE DEFAULT   ;   ipj = 4          ! several proc along the i-direction 
    3238      END SELECT 
     
    149155   END SUBROUTINE ROUTINE_NFD 
    150156 
     157#undef PRECISION 
    151158#undef ARRAY_TYPE 
    152159#undef ARRAY_IN 
  • NEMO/branches/2020/dev_12905_xios_ancil/src/OCE/LBC/lbc_nfd_generic.h90

    r10425 r13766  
    44#   define F_SIZE(ptab)             kfld 
    55#   if defined DIM_2d 
    6 #      define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_2D),INTENT(inout)::ptab(f) 
     6#      if defined SINGLE_PRECISION 
     7#         define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_2D_sp),INTENT(inout)::ptab(f) 
     8#      else 
     9#         define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_2D_dp),INTENT(inout)::ptab(f) 
     10#      endif 
    711#      define ARRAY_IN(i,j,k,l,f)      ptab(f)%pt2d(i,j) 
     12#      define J_SIZE(ptab)             SIZE(ptab(1)%pt2d,2) 
    813#      define K_SIZE(ptab)             1 
    914#      define L_SIZE(ptab)             1 
    1015#   endif 
    1116#   if defined DIM_3d 
    12 #      define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_3D),INTENT(inout)::ptab(f) 
     17#      if defined SINGLE_PRECISION 
     18#         define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_3D_sp),INTENT(inout)::ptab(f) 
     19#      else 
     20#         define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_3D_dp),INTENT(inout)::ptab(f) 
     21#      endif 
    1322#      define ARRAY_IN(i,j,k,l,f)      ptab(f)%pt3d(i,j,k) 
     23#      define J_SIZE(ptab)             SIZE(ptab(1)%pt3d,2) 
    1424#      define K_SIZE(ptab)             SIZE(ptab(1)%pt3d,3) 
    1525#      define L_SIZE(ptab)             1 
    1626#   endif 
    1727#   if defined DIM_4d 
    18 #      define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_4D),INTENT(inout)::ptab(f) 
     28#      if defined SINGLE_PRECISION 
     29#         define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_4D_sp),INTENT(inout)::ptab(f) 
     30#      else 
     31#         define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_4D_dp),INTENT(inout)::ptab(f) 
     32#      endif 
    1933#      define ARRAY_IN(i,j,k,l,f)      ptab(f)%pt4d(i,j,k,l) 
     34#      define J_SIZE(ptab)             SIZE(ptab(1)%pt4d,2) 
    2035#      define K_SIZE(ptab)             SIZE(ptab(1)%pt4d,3) 
    2136#      define L_SIZE(ptab)             SIZE(ptab(1)%pt4d,4) 
     
    2843#   if defined DIM_2d 
    2944#      define ARRAY_IN(i,j,k,l,f)   ptab(i,j) 
     45#      define J_SIZE(ptab)          SIZE(ptab,2) 
    3046#      define K_SIZE(ptab)          1 
    3147#      define L_SIZE(ptab)          1 
     
    3349#   if defined DIM_3d 
    3450#      define ARRAY_IN(i,j,k,l,f)   ptab(i,j,k) 
     51#      define J_SIZE(ptab)          SIZE(ptab,2) 
    3552#      define K_SIZE(ptab)          SIZE(ptab,3) 
    3653#      define L_SIZE(ptab)          1 
     
    3855#   if defined DIM_4d 
    3956#      define ARRAY_IN(i,j,k,l,f)   ptab(i,j,k,l) 
     57#      define J_SIZE(ptab)          SIZE(ptab,2) 
    4058#      define K_SIZE(ptab)          SIZE(ptab,3) 
    4159#      define L_SIZE(ptab)          SIZE(ptab,4) 
    4260#   endif 
    43 #   define ARRAY_TYPE(i,j,k,l,f)    REAL(wp),INTENT(inout)::ARRAY_IN(i,j,k,l,f) 
     61#   if defined SINGLE_PRECISION 
     62#      define ARRAY_TYPE(i,j,k,l,f)    REAL(sp),INTENT(inout)::ARRAY_IN(i,j,k,l,f) 
     63#   else 
     64#      define ARRAY_TYPE(i,j,k,l,f)    REAL(dp),INTENT(inout)::ARRAY_IN(i,j,k,l,f) 
     65#   endif 
    4466#endif 
     67 
     68#   if defined SINGLE_PRECISION 
     69#      define PRECISION sp 
     70#   else 
     71#      define PRECISION dp 
     72#   endif 
    4573 
    4674#if defined MULTI 
     
    5482      REAL(wp)         , INTENT(in   ) ::   SGN_IN(:)   ! sign used across the north fold boundary 
    5583      ! 
    56       INTEGER  ::    ji,  jj,  jk,  jl, jh, jf   ! dummy loop indices 
    57       INTEGER  ::   ipi, ipj, ipk, ipl,    ipf   ! dimension of the input array 
    58       INTEGER  ::   ijt, iju, ipjm1 
     84      INTEGER  ::    ji,  jj,  jk,  jl, jf   ! dummy loop indices 
     85      INTEGER  ::        ipj, ipk, ipl, ipf   ! dimension of the input array 
     86      INTEGER  ::   ii1, ii2, ij1, ij2 
    5987      !!---------------------------------------------------------------------- 
    6088      ! 
    61       ipk = K_SIZE(ptab)   ! 3rd dimension 
     89      ipj = J_SIZE(ptab)   ! 2nd dimension 
     90      ipk = K_SIZE(ptab)   ! 3rd    - 
    6291      ipl = L_SIZE(ptab)   ! 4th    - 
    6392      ipf = F_SIZE(ptab)   ! 5th    -      use in "multi" case (array of pointers) 
    64       ! 
    65       ! 
    66       SELECT CASE ( jpni ) 
    67       CASE ( 1 )     ;   ipj = nlcj       ! 1 proc only  along the i-direction 
    68       CASE DEFAULT   ;   ipj = 4          ! several proc along the i-direction 
    69       END SELECT 
    70       ipjm1 = ipj-1 
    71  
    7293      ! 
    7394      DO jf = 1, ipf                      ! Loop on the number of arrays to be treated 
     
    79100            SELECT CASE ( NAT_IN(jf)  ) 
    80101            CASE ( 'T' , 'W' )                         ! T-, W-point 
    81                DO ji = 2, jpiglo 
    82                   ijt = jpiglo-ji+2 
    83                   ARRAY_IN(ji,ipj,:,:,jf) = SGN_IN(jf)  * ARRAY_IN(ijt,ipj-2,:,:,jf) 
    84                END DO 
    85                ARRAY_IN(1,ipj,:,:,jf) = SGN_IN(jf)  * ARRAY_IN(3,ipj-2,:,:,jf) 
    86                DO ji = jpiglo/2+1, jpiglo 
    87                   ijt = jpiglo-ji+2 
    88                   ARRAY_IN(ji,ipjm1,:,:,jf) = SGN_IN(jf)  * ARRAY_IN(ijt,ipjm1,:,:,jf) 
    89                END DO 
     102               DO jl = 1, ipl; DO jk = 1, ipk 
     103                  ! 
     104                  ! last nn_hls lines (from ipj to ipj-nn_hls+1) : full 
     105                    DO jj = 1, nn_hls 
     106                       ij1 = ipj            - jj + 1       ! ends at: ipj - nn_hls + 1 
     107                     ij2 = ipj - 2*nn_hls + jj - 1       ! ends at: ipj - 2*nn_hls + nn_hls - 1 = ipj - nn_hls - 1 
     108                     ! 
     109                     DO ji = 1, nn_hls            ! first nn_hls points 
     110                        ii1 =                ji          ! ends at: nn_hls 
     111                        ii2 = 2*nn_hls + 2 - ji          ! ends at: 2*nn_hls + 2 - nn_hls = nn_hls + 2 
     112                        ARRAY_IN(ii1,ij1,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(ii2,ij2,jk,jl,jf) 
     113                     END DO 
     114                     DO ji = 1, 1                 ! point nn_hls+1 
     115                        ii1 = nn_hls + ji 
     116                        ii2 = ii1 
     117                        ARRAY_IN(ii1,ij1,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(ii2,ij2,jk,jl,jf) 
     118                     END DO 
     119                     DO ji = 1, Ni0glo - 1        ! points from nn_hls+2 to jpiglo - nn_hls   (note: Ni0glo = jpiglo - 2*nn_hls) 
     120                        ii1 = 2 + nn_hls      + ji - 1   ! ends at: 2 + nn_hls + jpiglo - 2*nn_hls - 1 - 1 = jpiglo - nn_hls 
     121                        ii2 = jpiglo - nn_hls - ji + 1   ! ends at: jpiglo - nn_hls - ( jpiglo - 2*nn_hls - 1 ) + 1 = nn_hls + 2 
     122                        ARRAY_IN(ii1,ij1,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(ii2,ij2,jk,jl,jf) 
     123                     END DO 
     124                     DO ji = 1, 1                 ! point jpiglo - nn_hls + 1 
     125                        ii1 = jpiglo - nn_hls + ji 
     126                        ii2 =          nn_hls + ji 
     127                        ARRAY_IN(ii1,ij1,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(ii2,ij2,jk,jl,jf) 
     128                     END DO 
     129                     DO ji = 1, nn_hls-1          ! last nn_hls-1 points 
     130                        ii1 = jpiglo - nn_hls + 1 + ji   ! ends at: jpiglo - nn_hls + 1 + nn_hls - 1 = jpiglo 
     131                        ii2 = jpiglo - nn_hls + 1 - ji   ! ends at: jpiglo - nn_hls + 1 - nn_hls + 1 = jpiglo - 2*nn_hls + 2 
     132                        ARRAY_IN(ii1,ij1,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(ii2,ij2,jk,jl,jf) 
     133                     END DO 
     134                  END DO 
     135                  ! 
     136                  ! line number ipj-nn_hls : right half 
     137                    DO jj = 1, 1 
     138                     ij1 = ipj - nn_hls 
     139                     ij2 = ij1   ! same line 
     140                     ! 
     141                     DO ji = 1, Ni0glo/2-1        ! points from jpiglo/2+2 to jpiglo - nn_hls   (note: Ni0glo = jpiglo - 2*nn_hls) 
     142                        ii1 = jpiglo/2 + ji + 1          ! ends at: jpiglo/2 + (jpiglo/2 - nn_hls - 1) + 1 = jpiglo - nn_hls 
     143                        ii2 = jpiglo/2 - ji + 1          ! ends at: jpiglo/2 - (jpiglo/2 - nn_hls - 1) + 1 = nn_hls + 2 
     144                        ARRAY_IN(ii1,ij1,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(ii2,ij2,jk,jl,jf) 
     145                     END DO 
     146                     DO ji = 1, nn_hls            ! first nn_hls points: redo them just in case (if e-w periodocity already done) 
     147                        !                         ! as we just changed points jpiglo-2nn_hls+1 to jpiglo-nn_hls   
     148                        ii1 =                ji          ! ends at: nn_hls 
     149                        ii2 = 2*nn_hls + 2 - ji          ! ends at: 2*nn_hls + 2 - nn_hls = nn_hls + 2 
     150                        ARRAY_IN(ii1,ij1,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(ii2,ij2,jk,jl,jf) 
     151                     END DO 
     152                     !                            ! last nn_hls-1 points: have been / will done by e-w periodicity  
     153                  END DO 
     154                  ! 
     155               END DO; END DO 
    90156            CASE ( 'U' )                               ! U-point 
    91                DO ji = 1, jpiglo-1 
    92                   iju = jpiglo-ji+1 
    93                   ARRAY_IN(ji,ipj,:,:,jf) = SGN_IN(jf)  * ARRAY_IN(iju,ipj-2,:,:,jf) 
    94                END DO 
    95                ARRAY_IN(   1  ,ipj,:,:,jf) = SGN_IN(jf)  * ARRAY_IN(    2   ,ipj-2,:,:,jf) 
    96                ARRAY_IN(jpiglo,ipj,:,:,jf) = SGN_IN(jf)  * ARRAY_IN(jpiglo-1,ipj-2,:,:,jf)  
    97                DO ji = jpiglo/2, jpiglo-1 
    98                   iju = jpiglo-ji+1 
    99                   ARRAY_IN(ji,ipjm1,:,:,jf) = SGN_IN(jf)  * ARRAY_IN(iju,ipjm1,:,:,jf) 
    100                END DO 
     157               DO jl = 1, ipl; DO jk = 1, ipk 
     158                  ! 
     159                  ! last nn_hls lines (from ipj to ipj-nn_hls+1) : full 
     160                    DO jj = 1, nn_hls 
     161                       ij1 = ipj            - jj + 1       ! ends at: ipj - nn_hls + 1 
     162                     ij2 = ipj - 2*nn_hls + jj - 1       ! ends at: ipj - 2*nn_hls + nn_hls - 1 = ipj - nn_hls - 1 
     163                     ! 
     164                     DO ji = 1, nn_hls            ! first nn_hls points 
     165                        ii1 =                ji          ! ends at: nn_hls 
     166                        ii2 = 2*nn_hls + 1 - ji          ! ends at: 2*nn_hls + 1 - nn_hls = nn_hls + 1 
     167                        ARRAY_IN(ii1,ij1,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(ii2,ij2,jk,jl,jf) 
     168                     END DO 
     169                     DO ji = 1, Ni0glo            ! points from nn_hls to jpiglo - nn_hls   (note: Ni0glo = jpiglo - 2*nn_hls) 
     170                        ii1 = nn_hls          + ji       ! ends at: nn_hls + jpiglo - 2*nn_hls = jpiglo - nn_hls 
     171                        ii2 = jpiglo - nn_hls - ji + 1   ! ends at: jpiglo - nn_hls - ( jpiglo - 2*nn_hls ) + 1 = nn_hls + 1 
     172                        ARRAY_IN(ii1,ij1,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(ii2,ij2,jk,jl,jf) 
     173                     END DO 
     174                     DO ji = 1, nn_hls            ! last nn_hls points 
     175                        ii1 = jpiglo - nn_hls + ji       ! ends at: jpiglo - nn_hls + nn_hls = jpiglo 
     176                        ii2 = jpiglo - nn_hls + 1 - ji   ! ends at: jpiglo - nn_hls + 1 - nn_hls = jpiglo - 2*nn_hls + 1 
     177                        ARRAY_IN(ii1,ij1,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(ii2,ij2,jk,jl,jf) 
     178                     END DO 
     179                  END DO 
     180                  ! 
     181                  ! line number ipj-nn_hls : right half 
     182                    DO jj = 1, 1 
     183                     ij1 = ipj - nn_hls 
     184                     ij2 = ij1   ! same line 
     185                     ! 
     186                     DO ji = 1, Ni0glo/2          ! points from jpiglo/2+1 to jpiglo - nn_hls   (note: Ni0glo = jpiglo - 2*nn_hls) 
     187                        ii1 = jpiglo/2 + ji              ! ends at: jpiglo/2 + (jpiglo/2 - nn_hls) = jpiglo - nn_hls 
     188                        ii2 = jpiglo/2 - ji + 1          ! ends at: jpiglo/2 - (jpiglo/2 - nn_hls) + 1 = nn_hls + 1 
     189                        ARRAY_IN(ii1,ij1,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(ii2,ij2,jk,jl,jf) 
     190                     END DO 
     191                     DO ji = 1, nn_hls            ! first nn_hls points: redo them just in case (if e-w periodocity already done) 
     192                        !                         ! as we just changed points jpiglo-2nn_hls+1 to jpiglo-nn_hls   
     193                        ii1 =                ji          ! ends at: nn_hls 
     194                        ii2 = 2*nn_hls + 1 - ji          ! ends at: 2*nn_hls + 1 - nn_hls = nn_hls + 1 
     195                        ARRAY_IN(ii1,ij1,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(ii2,ij2,jk,jl,jf) 
     196                     END DO 
     197                     !                            ! last nn_hls-1 points: have been / will done by e-w periodicity  
     198                  END DO 
     199                  ! 
     200               END DO; END DO 
    101201            CASE ( 'V' )                               ! V-point 
    102                DO ji = 2, jpiglo 
    103                   ijt = jpiglo-ji+2 
    104                   ARRAY_IN(ji,ipj-1,:,:,jf) = SGN_IN(jf)  * ARRAY_IN(ijt,ipj-2,:,:,jf) 
    105                   ARRAY_IN(ji,ipj  ,:,:,jf) = SGN_IN(jf)  * ARRAY_IN(ijt,ipj-3,:,:,jf) 
    106                END DO 
    107                ARRAY_IN(1,ipj,:,:,jf) = SGN_IN(jf)  * ARRAY_IN(3,ipj-3,:,:,jf)  
     202               DO jl = 1, ipl; DO jk = 1, ipk 
     203                  ! 
     204                  ! last nn_hls+1 lines (from ipj to ipj-nn_hls) : full 
     205                    DO jj = 1, nn_hls+1 
     206                       ij1 = ipj            - jj + 1       ! ends at: ipj - ( nn_hls + 1 ) + 1 = ipj - nn_hls 
     207                     ij2 = ipj - 2*nn_hls + jj - 2       ! ends at: ipj - 2*nn_hls + nn_hls + 1 - 2 = ipj - nn_hls - 1 
     208                     ! 
     209                     DO ji = 1, nn_hls            ! first nn_hls points 
     210                        ii1 =                ji          ! ends at: nn_hls 
     211                        ii2 = 2*nn_hls + 2 - ji          ! ends at: 2*nn_hls + 2 - nn_hls = nn_hls + 2 
     212                        ARRAY_IN(ii1,ij1,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(ii2,ij2,jk,jl,jf) 
     213                     END DO 
     214                     DO ji = 1, 1                 ! point nn_hls+1 
     215                        ii1 = nn_hls + ji 
     216                        ii2 = ii1 
     217                        ARRAY_IN(ii1,ij1,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(ii2,ij2,jk,jl,jf) 
     218                     END DO 
     219                     DO ji = 1, Ni0glo - 1        ! points from nn_hls+2 to jpiglo - nn_hls   (note: Ni0glo = jpiglo - 2*nn_hls) 
     220                        ii1 = 2 + nn_hls      + ji - 1   ! ends at: 2 + nn_hls + jpiglo - 2*nn_hls - 1 - 1 = jpiglo - nn_hls 
     221                        ii2 = jpiglo - nn_hls - ji + 1   ! ends at: jpiglo - nn_hls - ( jpiglo - 2*nn_hls - 1 ) + 1 = nn_hls + 2 
     222                        ARRAY_IN(ii1,ij1,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(ii2,ij2,jk,jl,jf) 
     223                     END DO 
     224                     DO ji = 1, 1                 ! point jpiglo - nn_hls + 1 
     225                        ii1 = jpiglo - nn_hls + ji 
     226                        ii2 =          nn_hls + ji 
     227                        ARRAY_IN(ii1,ij1,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(ii2,ij2,jk,jl,jf) 
     228                     END DO 
     229                     DO ji = 1, nn_hls-1          ! last nn_hls-1 points 
     230                        ii1 = jpiglo - nn_hls + 1 + ji   ! ends at: jpiglo - nn_hls + 1 + nn_hls - 1 = jpiglo 
     231                        ii2 = jpiglo - nn_hls + 1 - ji   ! ends at: jpiglo - nn_hls + 1 - nn_hls + 1 = jpiglo - 2*nn_hls + 2 
     232                        ARRAY_IN(ii1,ij1,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(ii2,ij2,jk,jl,jf) 
     233                     END DO 
     234                  END DO 
     235                  ! 
     236               END DO; END DO 
    108237            CASE ( 'F' )                               ! F-point 
    109                DO ji = 1, jpiglo-1 
    110                   iju = jpiglo-ji+1 
    111                   ARRAY_IN(ji,ipj-1,:,:,jf) = SGN_IN(jf)  * ARRAY_IN(iju,ipj-2,:,:,jf) 
    112                   ARRAY_IN(ji,ipj  ,:,:,jf) = SGN_IN(jf)  * ARRAY_IN(iju,ipj-3,:,:,jf) 
    113                END DO 
    114                ARRAY_IN(   1  ,ipj,:,:,jf) = SGN_IN(jf)  * ARRAY_IN(    2   ,ipj-3,:,:,jf) 
    115                ARRAY_IN(jpiglo,ipj,:,:,jf) = SGN_IN(jf)  * ARRAY_IN(jpiglo-1,ipj-3,:,:,jf)  
    116             END SELECT 
     238               DO jl = 1, ipl; DO jk = 1, ipk 
     239                  ! 
     240                  ! last nn_hls+1 lines (from ipj to ipj-nn_hls) : full 
     241                    DO jj = 1, nn_hls+1 
     242                       ij1 = ipj            - jj + 1       ! ends at: ipj - ( nn_hls + 1 ) + 1 = ipj - nn_hls 
     243                     ij2 = ipj - 2*nn_hls + jj - 2       ! ends at: ipj - 2*nn_hls + nn_hls + 1 - 2 = ipj - nn_hls - 1 
     244                     ! 
     245                     DO ji = 1, nn_hls            ! first nn_hls points 
     246                        ii1 =                ji          ! ends at: nn_hls 
     247                        ii2 = 2*nn_hls + 1 - ji          ! ends at: 2*nn_hls + 1 - nn_hls = nn_hls + 1 
     248                        ARRAY_IN(ii1,ij1,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(ii2,ij2,jk,jl,jf) 
     249                     END DO 
     250                     DO ji = 1, Ni0glo            ! points from nn_hls to jpiglo - nn_hls   (note: Ni0glo = jpiglo - 2*nn_hls) 
     251                        ii1 = nn_hls          + ji       ! ends at: nn_hls + jpiglo - 2*nn_hls = jpiglo - nn_hls 
     252                        ii2 = jpiglo - nn_hls - ji + 1   ! ends at: jpiglo - nn_hls - ( jpiglo - 2*nn_hls ) + 1 = nn_hls + 1 
     253                        ARRAY_IN(ii1,ij1,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(ii2,ij2,jk,jl,jf) 
     254                     END DO 
     255                     DO ji = 1, nn_hls            ! last nn_hls points 
     256                        ii1 = jpiglo - nn_hls + ji       ! ends at: jpiglo - nn_hls + nn_hls = jpiglo 
     257                        ii2 = jpiglo - nn_hls + 1 - ji   ! ends at: jpiglo - nn_hls + 1 - nn_hls = jpiglo - 2*nn_hls + 1 
     258                        ARRAY_IN(ii1,ij1,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(ii2,ij2,jk,jl,jf) 
     259                     END DO 
     260                  END DO 
     261                  ! 
     262               END DO; END DO 
     263            END SELECT   ! NAT_IN(jf) 
    117264            ! 
    118265         CASE ( 5 , 6 )                        ! *  North fold  F-point pivot 
     
    120267            SELECT CASE ( NAT_IN(jf)  ) 
    121268            CASE ( 'T' , 'W' )                         ! T-, W-point 
    122                DO ji = 1, jpiglo 
    123                   ijt = jpiglo-ji+1 
    124                   ARRAY_IN(ji,ipj,:,:,jf) = SGN_IN(jf)  * ARRAY_IN(ijt,ipj-1,:,:,jf) 
    125                END DO 
     269               DO jl = 1, ipl; DO jk = 1, ipk 
     270                  ! 
     271                  ! first: line number ipj-nn_hls : 3 points 
     272                    DO jj = 1, 1 
     273                     ij1 = ipj - nn_hls 
     274                     ij2 = ij1   ! same line 
     275                     ! 
     276                     DO ji = 1, 1            ! points from jpiglo/2+1 
     277                        ii1 = jpiglo/2 + ji 
     278                        ii2 = jpiglo/2 - ji + 1 
     279                        ARRAY_IN(ii1,ij1,jk,jl,jf) =              ARRAY_IN(ii2,ij2,jk,jl,jf)   ! Warning: pb with sign... 
     280                     END DO 
     281                     DO ji = 1, 1            ! points jpiglo - nn_hls 
     282                        ii1 = jpiglo - nn_hls + ji - 1 
     283                        ii2 =          nn_hls + ji 
     284                        ARRAY_IN(ii1,ij1,jk,jl,jf) =              ARRAY_IN(ii2,ij2,jk,jl,jf)   ! Warning: pb with sign... 
     285                     END DO 
     286                     DO ji = 1, 1            ! point nn_hls: redo it just in case (if e-w periodocity already done) 
     287                        !                    ! as we just changed point jpiglo - nn_hls 
     288                        ii1 = nn_hls + ji - 1 
     289                        ii2 = nn_hls + ji 
     290                        ARRAY_IN(ii1,ij1,jk,jl,jf) =              ARRAY_IN(ii2,ij2,jk,jl,jf)   ! Warning: pb with sign... 
     291                     END DO 
     292                  END DO 
     293                  ! 
     294                  ! Second: last nn_hls lines (from ipj to ipj-nn_hls+1) : full 
     295                    DO jj = 1, nn_hls 
     296                       ij1 = ipj + 1        - jj           ! ends at: ipj + 1 - nn_hls 
     297                     ij2 = ipj - 2*nn_hls + jj           ! ends at: ipj - 2*nn_hls + nn_hls = ipj - nn_hls 
     298                     ! 
     299                     DO ji = 1, nn_hls            ! first nn_hls points 
     300                        ii1 =                ji          ! ends at: nn_hls 
     301                        ii2 = 2*nn_hls + 1 - ji          ! ends at: 2*nn_hls + 1 - nn_hls = nn_hls + 1 
     302                        ARRAY_IN(ii1,ij1,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(ii2,ij2,jk,jl,jf) 
     303                     END DO 
     304                     DO ji = 1, Ni0glo            ! points from nn_hls to jpiglo - nn_hls   (note: Ni0glo = jpiglo - 2*nn_hls) 
     305                        ii1 = nn_hls          + ji       ! ends at: nn_hls + jpiglo - 2*nn_hls = jpiglo - nn_hls 
     306                        ii2 = jpiglo - nn_hls - ji + 1   ! ends at: jpiglo - nn_hls - ( jpiglo - 2*nn_hls ) + 1 = nn_hls + 1 
     307                        ARRAY_IN(ii1,ij1,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(ii2,ij2,jk,jl,jf) 
     308                     END DO 
     309                     DO ji = 1, nn_hls            ! last nn_hls points 
     310                        ii1 = jpiglo - nn_hls + ji       ! ends at: jpiglo - nn_hls + nn_hls = jpiglo 
     311                        ii2 = jpiglo - nn_hls + 1 - ji   ! ends at: jpiglo - nn_hls + 1 - nn_hls = jpiglo - 2*nn_hls + 1 
     312                        ARRAY_IN(ii1,ij1,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(ii2,ij2,jk,jl,jf) 
     313                     END DO 
     314                  END DO 
     315                  ! 
     316               END DO; END DO 
    126317            CASE ( 'U' )                               ! U-point 
    127                DO ji = 1, jpiglo-1 
    128                   iju = jpiglo-ji 
    129                   ARRAY_IN(ji,ipj,:,:,jf) = SGN_IN(jf)  * ARRAY_IN(iju,ipj-1,:,:,jf) 
    130                END DO 
    131                ARRAY_IN(jpiglo,ipj,:,:,jf) = SGN_IN(jf) * ARRAY_IN(jpiglo-2,ipj-1,:,:,jf) 
     318               DO jl = 1, ipl; DO jk = 1, ipk 
     319                  ! 
     320                  ! last nn_hls lines (from ipj to ipj-nn_hls+1) : full 
     321                    DO jj = 1, nn_hls 
     322                       ij1 = ipj + 1        - jj           ! ends at: ipj + 1 - nn_hls 
     323                     ij2 = ipj - 2*nn_hls + jj           ! ends at: ipj - 2*nn_hls + nn_hls = ipj - nn_hls 
     324                     ! 
     325                     DO ji = 1, nn_hls-1          ! first nn_hls-1 points 
     326                        ii1 =            ji              ! ends at: nn_hls-1 
     327                        ii2 = 2*nn_hls - ji              ! ends at: 2*nn_hls - ( nn_hls - 1 ) = nn_hls + 1 
     328                        ARRAY_IN(ii1,ij1,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(ii2,ij2,jk,jl,jf) 
     329                     END DO 
     330                     DO ji = 1, 1                 ! point nn_hls 
     331                        ii1 = nn_hls + ji - 1 
     332                        ii2 = jpiglo - ii1 
     333                        ARRAY_IN(ii1,ij1,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(ii2,ij2,jk,jl,jf) 
     334                     END DO 
     335                     DO ji = 1, Ni0glo - 1        ! points from nn_hls+1 to jpiglo - nn_hls - 1  (note: Ni0glo = jpiglo - 2*nn_hls) 
     336                        ii1 =          nn_hls + ji       ! ends at: nn_hls + ( jpiglo - 2*nn_hls - 1 ) = jpiglo - nn_hls - 1 
     337                        ii2 = jpiglo - nn_hls - ji       ! ends at: jpiglo - nn_hls - ( jpiglo - 2*nn_hls - 1 ) = nn_hls + 1 
     338                        ARRAY_IN(ii1,ij1,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(ii2,ij2,jk,jl,jf) 
     339                     END DO 
     340                     DO ji = 1, 1                 ! point jpiglo - nn_hls 
     341                        ii1 = jpiglo - nn_hls + ji - 1 
     342                        ii2 = ii1 
     343                        ARRAY_IN(ii1,ij1,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(ii2,ij2,jk,jl,jf) 
     344                     END DO 
     345                     DO ji = 1, nn_hls            ! last nn_hls points 
     346                        ii1 = jpiglo - nn_hls + ji       ! ends at: jpiglo - nn_hls + nn_hls = jpiglo 
     347                        ii2 = jpiglo - nn_hls - ji       ! ends at: jpiglo - nn_hls - nn_hls = jpiglo - 2*nn_hls 
     348                        ARRAY_IN(ii1,ij1,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(ii2,ij2,jk,jl,jf) 
     349                     END DO 
     350                  END DO 
     351                  ! 
     352               END DO; END DO 
    132353            CASE ( 'V' )                               ! V-point 
    133                DO ji = 1, jpiglo 
    134                   ijt = jpiglo-ji+1 
    135                   ARRAY_IN(ji,ipj,:,:,jf) = SGN_IN(jf)  * ARRAY_IN(ijt,ipj-2,:,:,jf) 
    136                END DO 
    137                DO ji = jpiglo/2+1, jpiglo 
    138                   ijt = jpiglo-ji+1 
    139                   ARRAY_IN(ji,ipjm1,:,:,jf) = SGN_IN(jf)  * ARRAY_IN(ijt,ipjm1,:,:,jf) 
    140                END DO 
     354               DO jl = 1, ipl; DO jk = 1, ipk 
     355                  ! 
     356                  ! last nn_hls lines (from ipj to ipj-nn_hls+1) : full 
     357                    DO jj = 1, nn_hls 
     358                       ij1 = ipj            - jj + 1       ! ends at: ipj - nn_hls + 1 
     359                     ij2 = ipj - 2*nn_hls + jj - 1       ! ends at: ipj - 2*nn_hls + nn_hls - 1 = ipj - nn_hls - 1 
     360                     ! 
     361                     DO ji = 1, nn_hls            ! first nn_hls points 
     362                        ii1 =                ji          ! ends at: nn_hls 
     363                        ii2 = 2*nn_hls + 1 - ji          ! ends at: 2*nn_hls + 1 - nn_hls = nn_hls + 1 
     364                        ARRAY_IN(ii1,ij1,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(ii2,ij2,jk,jl,jf) 
     365                     END DO 
     366                     DO ji = 1, Ni0glo            ! points from nn_hls to jpiglo - nn_hls   (note: Ni0glo = jpiglo - 2*nn_hls) 
     367                        ii1 = nn_hls          + ji       ! ends at: nn_hls + jpiglo - 2*nn_hls = jpiglo - nn_hls 
     368                        ii2 = jpiglo - nn_hls - ji + 1   ! ends at: jpiglo - nn_hls - ( jpiglo - 2*nn_hls ) + 1 = nn_hls + 1 
     369                        ARRAY_IN(ii1,ij1,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(ii2,ij2,jk,jl,jf) 
     370                     END DO 
     371                     DO ji = 1, nn_hls            ! last nn_hls points 
     372                        ii1 = jpiglo - nn_hls + ji       ! ends at: jpiglo - nn_hls + nn_hls = jpiglo 
     373                        ii2 = jpiglo - nn_hls + 1 - ji   ! ends at: jpiglo - nn_hls + 1 - nn_hls = jpiglo - 2*nn_hls + 1 
     374                        ARRAY_IN(ii1,ij1,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(ii2,ij2,jk,jl,jf) 
     375                     END DO 
     376                  END DO    
     377                  ! 
     378                  ! line number ipj-nn_hls : right half 
     379                    DO jj = 1, 1 
     380                     ij1 = ipj - nn_hls 
     381                     ij2 = ij1   ! same line 
     382                     ! 
     383                     DO ji = 1, Ni0glo/2          ! points from jpiglo/2+1 to jpiglo - nn_hls   (note: Ni0glo = jpiglo - 2*nn_hls) 
     384                        ii1 = jpiglo/2 + ji              ! ends at: jpiglo/2 + (jpiglo/2 - nn_hls) = jpiglo - nn_hls 
     385                        ii2 = jpiglo/2 - ji + 1          ! ends at: jpiglo/2 - (jpiglo/2 - nn_hls) + 1 = nn_hls + 1 
     386                        ARRAY_IN(ii1,ij1,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(ii2,ij2,jk,jl,jf) 
     387                     END DO 
     388                     DO ji = 1, nn_hls            ! first nn_hls points: redo them just in case (if e-w periodocity already done) 
     389                        !                         ! as we just changed points jpiglo-2nn_hls+1 to jpiglo-nn_hls   
     390                        ii1 =                ji          ! ends at: nn_hls 
     391                        ii2 = 2*nn_hls + 1 - ji          ! ends at: 2*nn_hls + 1 - nn_hls = nn_hls + 1 
     392                        ARRAY_IN(ii1,ij1,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(ii2,ij2,jk,jl,jf) 
     393                     END DO 
     394                     !                            ! last nn_hls points: have been / will done by e-w periodicity  
     395                  END DO 
     396                  ! 
     397               END DO; END DO 
    141398            CASE ( 'F' )                               ! F-point 
    142                DO ji = 1, jpiglo-1 
    143                   iju = jpiglo-ji 
    144                   ARRAY_IN(ji,ipj  ,:,:,jf) = SGN_IN(jf)  * ARRAY_IN(iju,ipj-2,:,:,jf) 
    145                END DO 
    146                ARRAY_IN(jpiglo,ipj,:,:,jf) = SGN_IN(jf)   * ARRAY_IN(jpiglo-2,ipj-2,:,:,jf) 
    147                DO ji = jpiglo/2+1, jpiglo-1 
    148                   iju = jpiglo-ji 
    149                   ARRAY_IN(ji,ipjm1,:,:,jf) = SGN_IN(jf)  * ARRAY_IN(iju,ipjm1,:,:,jf) 
    150                END DO 
    151             END SELECT 
     399               DO jl = 1, ipl; DO jk = 1, ipk 
     400                  ! 
     401                  ! last nn_hls lines (from ipj to ipj-nn_hls+1) : full 
     402                    DO jj = 1, nn_hls 
     403                       ij1 = ipj            - jj + 1       ! ends at: ipj - nn_hls + 1 
     404                     ij2 = ipj - 2*nn_hls + jj - 1       ! ends at: ipj - 2*nn_hls + nn_hls - 1 = ipj - nn_hls - 1 
     405                     ! 
     406                     DO ji = 1, nn_hls-1          ! first nn_hls-1 points 
     407                        ii1 =            ji              ! ends at: nn_hls-1 
     408                        ii2 = 2*nn_hls - ji              ! ends at: 2*nn_hls - ( nn_hls - 1 ) = nn_hls + 1 
     409                        ARRAY_IN(ii1,ij1,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(ii2,ij2,jk,jl,jf) 
     410                     END DO 
     411                     DO ji = 1, 1                 ! point nn_hls 
     412                        ii1 = nn_hls + ji - 1 
     413                        ii2 = jpiglo - ii1 
     414                        ARRAY_IN(ii1,ij1,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(ii2,ij2,jk,jl,jf) 
     415                     END DO 
     416                     DO ji = 1, Ni0glo - 1        ! points from nn_hls+1 to jpiglo - nn_hls - 1  (note: Ni0glo = jpiglo - 2*nn_hls) 
     417                        ii1 =          nn_hls + ji       ! ends at: nn_hls + ( jpiglo - 2*nn_hls - 1 ) = jpiglo - nn_hls - 1 
     418                        ii2 = jpiglo - nn_hls - ji       ! ends at: jpiglo - nn_hls - ( jpiglo - 2*nn_hls - 1 ) = nn_hls + 1 
     419                        ARRAY_IN(ii1,ij1,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(ii2,ij2,jk,jl,jf) 
     420                     END DO 
     421                     DO ji = 1, 1                 ! point jpiglo - nn_hls 
     422                        ii1 = jpiglo - nn_hls + ji - 1 
     423                        ii2 = ii1 
     424                        ARRAY_IN(ii1,ij1,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(ii2,ij2,jk,jl,jf) 
     425                     END DO 
     426                     DO ji = 1, nn_hls            ! last nn_hls points 
     427                        ii1 = jpiglo - nn_hls + ji       ! ends at: jpiglo - nn_hls + nn_hls = jpiglo 
     428                        ii2 = jpiglo - nn_hls - ji       ! ends at: jpiglo - nn_hls - nn_hls = jpiglo - 2*nn_hls 
     429                        ARRAY_IN(ii1,ij1,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(ii2,ij2,jk,jl,jf) 
     430                     END DO 
     431                  END DO    
     432                  ! 
     433                  ! line number ipj-nn_hls : right half 
     434                    DO jj = 1, 1 
     435                     ij1 = ipj - nn_hls 
     436                     ij2 = ij1   ! same line 
     437                     ! 
     438                     DO ji = 1, Ni0glo/2-1        ! points from jpiglo/2+1 to jpiglo - nn_hls-1  (note: Ni0glo = jpiglo - 2*nn_hls) 
     439                        ii1 = jpiglo/2 + ji              ! ends at: jpiglo/2 + (jpiglo/2 - nn_hls) = jpiglo - nn_hls 
     440                        ii2 = jpiglo/2 - ji              ! ends at: jpiglo/2 - (jpiglo/2 - nn_hls - 1 ) = nn_hls + 1 
     441                        ARRAY_IN(ii1,ij1,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(ii2,ij2,jk,jl,jf) 
     442                     END DO 
     443                     DO ji = 1, nn_hls-1          ! first nn_hls-1 points: redo them just in case (if e-w periodocity already done) 
     444                        !                         ! as we just changed points jpiglo-2nn_hls+1 to jpiglo-nn_hl-1   
     445                        ii1 =            ji              ! ends at: nn_hls 
     446                        ii2 = 2*nn_hls - ji              ! ends at: 2*nn_hls - ( nn_hls - 1 ) = nn_hls + 1 
     447                        ARRAY_IN(ii1,ij1,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(ii2,ij2,jk,jl,jf) 
     448                     END DO 
     449                     !                            ! last nn_hls points: have been / will done by e-w periodicity  
     450                  END DO 
     451                  ! 
     452               END DO; END DO 
     453            END SELECT   ! NAT_IN(jf) 
    152454            ! 
    153          CASE DEFAULT                           ! *  closed : the code probably never go through 
    154             ! 
    155             SELECT CASE ( NAT_IN(jf) ) 
    156             CASE ( 'T' , 'U' , 'V' , 'W' )             ! T-, U-, V-, W-points 
    157                ARRAY_IN(:, 1 ,:,:,jf) = 0._wp 
    158                ARRAY_IN(:,ipj,:,:,jf) = 0._wp 
    159             CASE ( 'F' )                               ! F-point 
    160                ARRAY_IN(:,ipj,:,:,jf) = 0._wp 
    161             END SELECT 
    162             ! 
    163          END SELECT     !  npolj 
     455         END SELECT   ! npolj 
    164456         ! 
    165       END DO 
     457      END DO   ! ipf 
    166458      ! 
    167459   END SUBROUTINE ROUTINE_NFD 
    168460 
     461#undef PRECISION 
    169462#undef ARRAY_TYPE 
    170463#undef ARRAY_IN 
    171464#undef NAT_IN 
    172465#undef SGN_IN 
     466#undef J_SIZE 
    173467#undef K_SIZE 
    174468#undef L_SIZE 
  • NEMO/branches/2020/dev_12905_xios_ancil/src/OCE/LBC/lbc_nfd_nogather_generic.h90

    r11536 r13766  
    44#   define F_SIZE(ptab)             kfld 
    55#   if defined DIM_2d 
    6 #      define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_2D),INTENT(inout)::ptab(f) 
     6#      if defined SINGLE_PRECISION 
     7#         define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_2D_sp),INTENT(inout)::ptab(f) 
     8#      else 
     9#         define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_2D_dp),INTENT(inout)::ptab(f) 
     10#      endif  
    711#      define ARRAY_IN(i,j,k,l,f)      ptab(f)%pt2d(i,j) 
    812#      define K_SIZE(ptab)             1 
     
    1014#   endif 
    1115#   if defined DIM_3d 
    12 #      define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_3D),INTENT(inout)::ptab(f) 
     16#      if defined SINGLE_PRECISION 
     17#         define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_3D_sp),INTENT(inout)::ptab(f) 
     18#      else 
     19#         define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_3D_dp),INTENT(inout)::ptab(f) 
     20#      endif  
    1321#      define ARRAY_IN(i,j,k,l,f)      ptab(f)%pt3d(i,j,k) 
    1422#      define K_SIZE(ptab)             SIZE(ptab(1)%pt3d,3) 
     
    1624#   endif 
    1725#   if defined DIM_4d 
    18 #      define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_4D),INTENT(inout)::ptab(f) 
     26#      if defined SINGLE_PRECISION 
     27#         define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_4D_sp),INTENT(inout)::ptab(f) 
     28#      else 
     29#         define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_4D_dp),INTENT(inout)::ptab(f) 
     30#      endif  
    1931#      define ARRAY_IN(i,j,k,l,f)      ptab(f)%pt4d(i,j,k,l) 
    2032#      define K_SIZE(ptab)             SIZE(ptab(1)%pt4d,3) 
    2133#      define L_SIZE(ptab)             SIZE(ptab(1)%pt4d,4) 
    2234#   endif 
    23 #   define ARRAY2_TYPE(i,j,k,l,f)   TYPE(PTR_4D),INTENT(inout)::ptab2(f) 
     35#   if defined SINGLE_PRECISION 
     36#      define ARRAY2_TYPE(i,j,k,l,f)   TYPE(PTR_4D_sp),INTENT(inout)::ptab2(f) 
     37#   else 
     38#      define ARRAY2_TYPE(i,j,k,l,f)   TYPE(PTR_4D_dp),INTENT(inout)::ptab2(f) 
     39#   endif 
    2440#   define J_SIZE(ptab2)            SIZE(ptab2(1)%pt4d,2) 
    2541#   define ARRAY2_IN(i,j,k,l,f)     ptab2(f)%pt4d(i,j,k,l) 
     
    4460#      define L_SIZE(ptab)          SIZE(ptab,4) 
    4561#   endif 
    46 #   define ARRAY2_IN(i,j,k,l,f)  ptab2(i,j,k,l) 
    4762#   define J_SIZE(ptab2)             SIZE(ptab2,2) 
    48 #   define ARRAY_TYPE(i,j,k,l,f)     REAL(wp),INTENT(inout)::ARRAY_IN(i,j,k,l,f) 
    49 #   define ARRAY2_TYPE(i,j,k,l,f)    REAL(wp),INTENT(inout)::ARRAY2_IN(i,j,k,l,f) 
    50 #endif 
    51  
     63#   define ARRAY2_IN(i,j,k,l,f)   ptab2(i,j,k,l) 
     64#   if defined SINGLE_PRECISION 
     65#      define ARRAY_TYPE(i,j,k,l,f)     REAL(sp),INTENT(inout)::ARRAY_IN(i,j,k,l,f) 
     66#      define ARRAY2_TYPE(i,j,k,l,f)    REAL(sp),INTENT(inout)::ARRAY2_IN(i,j,k,l,f) 
     67#   else 
     68#      define ARRAY_TYPE(i,j,k,l,f)     REAL(dp),INTENT(inout)::ARRAY_IN(i,j,k,l,f) 
     69#      define ARRAY2_TYPE(i,j,k,l,f)    REAL(dp),INTENT(inout)::ARRAY2_IN(i,j,k,l,f) 
     70#   endif 
     71#   endif 
     72#   ifdef SINGLE_PRECISION 
     73#      define PRECISION sp 
     74#   else 
     75#      define PRECISION dp 
     76#   endif 
    5277   SUBROUTINE ROUTINE_NFD( ptab, ptab2, cd_nat, psgn, kfld ) 
    5378      !!---------------------------------------------------------------------- 
     
    5782      !! 
    5883      !!---------------------------------------------------------------------- 
    59       ARRAY_TYPE(:,:,:,:,:)                             ! array or pointer of arrays on which the boundary condition is applied 
    60       ARRAY2_TYPE(:,:,:,:,:)                            ! array or pointer of arrays on which the boundary condition is applied 
     84      ARRAY_TYPE(:,:,:,:,:) 
     85      ARRAY2_TYPE(:,:,:,:,:)  
    6186      CHARACTER(len=1) , INTENT(in   ) ::   NAT_IN(:)   ! nature of array grid-points 
    6287      REAL(wp)         , INTENT(in   ) ::   SGN_IN(:)   ! sign used across the north fold boundary 
    6388      INTEGER, OPTIONAL, INTENT(in   ) ::   kfld        ! number of pt3d arrays 
    6489      ! 
    65       INTEGER  ::    ji,  jj,   jk,     jl,   jh,  jf   ! dummy loop indices 
    66       INTEGER  ::   ipi, ipj,  ipk,    ipl,  ipf        ! dimension of the input array 
    67       INTEGER  ::   ijt, iju, ijpj, ijpjp1, ijta, ijua, jia, startloop, endloop 
     90      INTEGER  ::    ji,  jj,   jk, jn, ii,   jl,   jh,  jf   ! dummy loop indices 
     91      INTEGER  ::   ipi, ipj,  ipk,    ipl,  ipf, iij, ijj   ! dimension of the input array 
     92      INTEGER  ::   ijt, iju, ijta, ijua, jia, startloop, endloop 
    6893      LOGICAL  ::   l_fast_exchanges 
    6994      !!---------------------------------------------------------------------- 
     
    75100      ! Security check for further developments 
    76101      IF ( ipf > 1 ) CALL ctl_stop( 'STOP', 'lbc_nfd_nogather: multiple fields not allowed. Revise implementation...' ) 
    77       ! 
    78       ijpj   = 1    ! index of first modified line  
    79       ijpjp1 = 2    ! index + 1 
    80        
    81102      ! 2nd dimension determines exchange speed 
    82103      IF (ipj == 1 ) THEN 
     
    95116            ! 
    96117            CASE ( 'T' , 'W' )                         ! T-, W-point 
    97                IF ( nimpp /= 1 ) THEN   ;   startloop = 1 
    98                ELSE                     ;   startloop = 2 
    99                ENDIF 
    100                ! 
    101                DO jl = 1, ipl; DO jk = 1, ipk 
    102                   DO ji = startloop, nlci 
    103                      ijt = jpiglo - ji - nimpp - nfiimpp(isendto(1),jpnj) + 4 
    104                      ARRAY_IN(ji,nlcj,jk,jl,jf) = SGN_IN(jf) * ARRAY2_IN(ijt,ijpj,jk,jl,jf) 
     118               IF ( nimpp /= 1 ) THEN  ;  startloop = 1  
     119               ELSE                    ;  startloop = 1 + nn_hls 
     120               ENDIF 
     121               ! 
     122               DO jl = 1, ipl; DO jk = 1, ipk 
     123                    DO jj = 1, nn_hls 
     124                       ijj = jpj -jj +1 
     125                     DO ji = startloop, jpi 
     126                     ijt = jpiglo - ji - nimpp - nfimpp(isendto(1)) + 4 
     127                        ARRAY_IN(ji,ijj,jk,jl,jf) = SGN_IN(jf) * ARRAY2_IN(ijt,jj,jk,jl,jf) 
     128                     END DO 
    105129                  END DO 
    106130               END DO; END DO 
    107131               IF( nimpp == 1 ) THEN 
    108132                  DO jl = 1, ipl; DO jk = 1, ipk 
    109                      ARRAY_IN(1,nlcj,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(3,nlcj-2,jk,jl,jf) 
    110                   END DO; END DO 
    111                ENDIF 
    112                ! 
    113                IF ( .NOT. l_fast_exchanges ) THEN 
    114                   IF( nimpp >= jpiglo/2+1 ) THEN 
     133                     DO jj = 1, nn_hls 
     134                     ijj = jpj -jj +1 
     135                     DO ii = 0, nn_hls-1 
     136                        ARRAY_IN(ii+1,ijj,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(2*nn_hls-ii+1,jpj-2*nn_hls+jj-1,jk,jl,jf) 
     137                     END DO 
     138                     END DO 
     139                  END DO; END DO 
     140               ENDIF               
     141               ! 
     142               IF ( .NOT. l_fast_exchanges ) THEN 
     143                  IF( nimpp >= Ni0glo/2+2 ) THEN 
    115144                     startloop = 1 
    116                   ELSEIF( nimpp+nlci-1 >= jpiglo/2+1 .AND. nimpp < jpiglo/2+1 ) THEN 
    117                      startloop = jpiglo/2+1 - nimpp + 1 
    118                   ELSE 
    119                      startloop = nlci + 1 
    120                   ENDIF 
    121                   IF( startloop <= nlci ) THEN 
     145                  ELSEIF( nimpp+jpi-1 >= Ni0glo/2+2 .AND. nimpp < Ni0glo/2+2 ) THEN 
     146                     startloop = Ni0glo/2+2 - nimpp + nn_hls 
     147                  ELSE 
     148                     startloop = jpi + 1 
     149                  ENDIF 
     150                  IF( startloop <= jpi ) THEN 
    122151                     DO jl = 1, ipl; DO jk = 1, ipk 
    123                         DO ji = startloop, nlci 
    124                            ijt  = jpiglo - ji - nimpp - nfiimpp(isendto(1),jpnj) + 4 
     152                        DO ji = startloop, jpi 
     153                           ijt  = jpiglo - ji - nimpp - nfimpp(isendto(1)) + 4 
    125154                           jia  = ji + nimpp - 1 
    126155                           ijta = jpiglo - jia + 2 
    127156                           IF( ijta >= startloop+nimpp-1 .AND. ijta < jia ) THEN 
    128                               ARRAY_IN(ji,nlcj-1,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(ijta-nimpp+1,nlcj-1,jk,jl,jf) 
     157                              ARRAY_IN(ji,jpj-nn_hls,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(ijta-nimpp+nn_hls,jpj-nn_hls,jk,jl,jf) 
    129158                           ELSE 
    130                               ARRAY_IN(ji,nlcj-1,jk,jl,jf) = SGN_IN(jf) * ARRAY2_IN(ijt,ijpjp1,jk,jl,jf) 
     159                              ARRAY_IN(ji,jpj-nn_hls,jk,jl,jf) = SGN_IN(jf) * ARRAY2_IN(ijt,nn_hls+1,jk,jl,jf) 
    131160                           ENDIF 
    132161                        END DO 
     
    134163                  ENDIF 
    135164               ENDIF 
    136  
    137165            CASE ( 'U' )                                     ! U-point 
    138                IF( nimpp + nlci - 1 /= jpiglo ) THEN 
    139                   endloop = nlci 
     166               IF( nimpp + jpi - 1 /= jpiglo ) THEN 
     167                  endloop = jpi 
    140168               ELSE 
    141                   endloop = nlci - 1 
    142                ENDIF 
    143                DO jl = 1, ipl; DO jk = 1, ipk 
    144                   DO ji = 1, endloop 
    145                      iju = jpiglo - ji - nimpp - nfiimpp(isendto(1),jpnj) + 3 
    146                      ARRAY_IN(ji,nlcj,jk,jl,jf) = SGN_IN(jf) * ARRAY2_IN(iju,ijpj,jk,jl,jf) 
     169                  endloop = jpi - nn_hls 
     170               ENDIF 
     171               DO jl = 1, ipl; DO jk = 1, ipk 
     172        DO jj = 1, nn_hls 
     173              ijj = jpj -jj +1 
     174                     DO ji = 1, endloop 
     175                        iju = jpiglo - ji - nimpp - nfimpp(isendto(1)) + 3 
     176                        ARRAY_IN(ji,ijj,jk,jl,jf) = SGN_IN(jf) * ARRAY2_IN(iju,jj,jk,jl,jf) 
     177                     END DO 
    147178                  END DO 
    148179               END DO; END DO 
    149180               IF (nimpp .eq. 1) THEN 
    150                   ARRAY_IN(1,nlcj,:,:,jf) = SGN_IN(jf) * ARRAY_IN(2,nlcj-2,:,:,jf) 
    151                ENDIF 
    152                IF((nimpp + nlci - 1) .eq. jpiglo) THEN 
    153                   ARRAY_IN(nlci,nlcj,:,:,jf) = SGN_IN(jf) * ARRAY_IN(nlci-1,nlcj-2,:,:,jf) 
    154                ENDIF 
    155                ! 
    156                IF ( .NOT. l_fast_exchanges ) THEN 
    157                   IF( nimpp + nlci - 1 /= jpiglo ) THEN 
    158                      endloop = nlci 
    159                   ELSE 
    160                      endloop = nlci - 1 
    161                   ENDIF 
    162                   IF( nimpp >= jpiglo/2 ) THEN 
    163                      startloop = 1 
    164                      ELSEIF( ( nimpp+nlci-1 >= jpiglo/2 ) .AND. ( nimpp < jpiglo/2 ) ) THEN 
    165                      startloop = jpiglo/2 - nimpp + 1 
     181        DO jj = 1, nn_hls 
     182           ijj = jpj -jj +1 
     183           DO ii = 0, nn_hls-1 
     184         ARRAY_IN(ii+1,ijj,:,:,jf) = SGN_IN(jf) * ARRAY_IN(2*nn_hls-ii,jpj-2*nn_hls+jj-1,:,:,jf) 
     185           END DO 
     186                  END DO 
     187               ENDIF 
     188               IF((nimpp + jpi - 1) .eq. jpiglo) THEN 
     189                  DO jj = 1, nn_hls 
     190                       ijj = jpj -jj +1 
     191         DO ii = 1, nn_hls 
     192               ARRAY_IN(jpi-ii+1,ijj,:,:,jf) = SGN_IN(jf) * ARRAY_IN(jpi-2*nn_hls+ii,jpj-2*nn_hls+jj-1,:,:,jf) 
     193         END DO 
     194        END DO 
     195               ENDIF 
     196               ! 
     197               IF ( .NOT. l_fast_exchanges ) THEN 
     198                  IF( nimpp + jpi - 1 /= jpiglo ) THEN 
     199                     endloop = jpi 
     200                  ELSE 
     201                     endloop = jpi - nn_hls 
     202                  ENDIF 
     203                  IF( nimpp >= Ni0glo/2+1 ) THEN 
     204                     startloop = nn_hls 
     205                  ELSEIF( ( nimpp + jpi - 1 >= Ni0glo/2+1 ) .AND. ( nimpp < Ni0glo/2+1 ) ) THEN 
     206                     startloop = Ni0glo/2+1 - nimpp + nn_hls  
    166207                  ELSE 
    167208                     startloop = endloop + 1 
     
    170211                  DO jl = 1, ipl; DO jk = 1, ipk 
    171212                     DO ji = startloop, endloop 
    172                         iju = jpiglo - ji - nimpp - nfiimpp(isendto(1),jpnj) + 3 
    173                         jia = ji + nimpp - 1 
    174                         ijua = jpiglo - jia + 1 
     213                        iju = jpiglo - ji - nimpp - nfimpp(isendto(1)) + 3 
     214                        jia = ji + nimpp - 1  
     215                        ijua = jpiglo - jia + 1  
    175216                        IF( ijua >= startloop+nimpp-1 .AND. ijua < jia ) THEN 
    176                            ARRAY_IN(ji,nlcj-1,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(ijua-nimpp+1,nlcj-1,jk,jl,jf) 
     217                           ARRAY_IN(ji,jpj-nn_hls,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(ijua-nimpp+1,jpj-nn_hls,jk,jl,jf) 
    177218                        ELSE 
    178                            ARRAY_IN(ji,nlcj-1,jk,jl,jf) = SGN_IN(jf) * ARRAY2_IN(iju,ijpjp1,jk,jl,jf) 
     219                           ARRAY_IN(ji,jpj-nn_hls,jk,jl,jf) = SGN_IN(jf) * ARRAY2_IN(iju,nn_hls+1,jk,jl,jf) 
    179220                        ENDIF 
    180221                     END DO 
     
    185226            CASE ( 'V' )                                     ! V-point 
    186227               IF( nimpp /= 1 ) THEN 
    187                  startloop = 1 
     228                 startloop = 1  
    188229               ELSE 
    189                  startloop = 2 
    190                ENDIF 
    191                IF ( .NOT. l_fast_exchanges ) THEN 
    192                   DO jl = 1, ipl; DO jk = 1, ipk 
    193                      DO ji = startloop, nlci 
    194                         ijt=jpiglo - ji - nimpp - nfiimpp(isendto(1),jpnj) + 4 
    195                         ARRAY_IN(ji,nlcj-1,jk,jl,jf) = SGN_IN(jf) * ARRAY2_IN(ijt,ijpjp1,jk,jl,jf) 
    196                      END DO 
    197                   END DO; END DO 
    198                ENDIF 
    199                DO jl = 1, ipl; DO jk = 1, ipk 
    200                   DO ji = startloop, nlci 
    201                      ijt=jpiglo - ji - nimpp - nfiimpp(isendto(1),jpnj) + 4 
    202                      ARRAY_IN(ji,nlcj,jk,jl,jf) = SGN_IN(jf) * ARRAY2_IN(ijt,ijpj,jk,jl,jf) 
     230                 startloop = 1 + nn_hls 
     231               ENDIF 
     232               IF ( .NOT. l_fast_exchanges ) THEN 
     233                  DO jl = 1, ipl; DO jk = 1, ipk 
     234                       DO jj = 2, nn_hls+1 
     235                     ijj = jpj -jj +1 
     236                        DO ji = startloop, jpi 
     237                           ijt=jpiglo - ji - nimpp - nfimpp(isendto(1)) + 4 
     238                           ARRAY_IN(ji,ijj,jk,jl,jf) = SGN_IN(jf) * ARRAY2_IN(ijt,jj,jk,jl,jf) 
     239                        END DO 
     240                    END DO 
     241                  END DO; END DO 
     242               ENDIF 
     243               DO jl = 1, ipl; DO jk = 1, ipk 
     244                  DO ji = startloop, jpi 
     245                     ijt=jpiglo - ji - nimpp - nfimpp(isendto(1)) + 4 
     246                     ARRAY_IN(ji,jpj,jk,jl,jf) = SGN_IN(jf) * ARRAY2_IN(ijt,1,jk,jl,jf) 
    203247                  END DO 
    204248               END DO; END DO 
    205249               IF (nimpp .eq. 1) THEN 
    206                   ARRAY_IN(1,nlcj,:,:,jf) = SGN_IN(jf) * ARRAY_IN(3,nlcj-3,:,:,jf) 
     250        DO jj = 1, nn_hls 
     251                       ijj = jpj-jj+1 
     252                       DO ii = 0, nn_hls-1 
     253                        ARRAY_IN(ii+1,ijj,:,:,jf) = SGN_IN(jf) * ARRAY_IN(2*nn_hls-ii+1,jpj-2*nn_hls+jj-1,:,:,jf) 
     254           END DO 
     255        END DO 
    207256               ENDIF 
    208257            CASE ( 'F' )                                     ! F-point 
    209                IF( nimpp + nlci - 1 /= jpiglo ) THEN 
    210                   endloop = nlci 
     258               IF( nimpp + jpi - 1 /= jpiglo ) THEN 
     259                  endloop = jpi 
    211260               ELSE 
    212                   endloop = nlci - 1 
    213                ENDIF 
    214                IF ( .NOT. l_fast_exchanges ) THEN 
    215                   DO jl = 1, ipl; DO jk = 1, ipk 
    216                      DO ji = 1, endloop 
    217                         iju = jpiglo - ji - nimpp - nfiimpp(isendto(1),jpnj) + 3 
    218                         ARRAY_IN(ji,nlcj-1,jk,jl,jf) = SGN_IN(jf) * ARRAY2_IN(iju,ijpjp1,jk,jl,jf) 
    219                      END DO 
     261                  endloop = jpi - nn_hls 
     262               ENDIF 
     263               IF ( .NOT. l_fast_exchanges ) THEN 
     264                  DO jl = 1, ipl; DO jk = 1, ipk 
     265                       DO jj = 2, nn_hls+1 
     266                     ijj = jpj -jj +1 
     267                        DO ji = 1, endloop 
     268                           iju = jpiglo - ji - nimpp - nfimpp(isendto(1)) + 3 
     269                           ARRAY_IN(ji,ijj,jk,jl,jf) = SGN_IN(jf) * ARRAY2_IN(iju,jj,jk,jl,jf) 
     270                        END DO 
     271                    END DO 
    220272                  END DO; END DO 
    221273               ENDIF 
    222274               DO jl = 1, ipl; DO jk = 1, ipk 
    223275                  DO ji = 1, endloop 
    224                      iju = jpiglo - ji - nimpp - nfiimpp(isendto(1),jpnj) + 3 
    225                      ARRAY_IN(ji,nlcj,jk,jl,jf) = SGN_IN(jf) * ARRAY2_IN(iju,ijpj,jk,jl,jf) 
    226                   END DO 
    227                END DO; END DO 
    228                IF (nimpp .eq. 1) THEN 
    229                   ARRAY_IN(1,nlcj,:,:,jf) = SGN_IN(jf) * ARRAY_IN(2,nlcj-3,:,:,jf) 
    230                   IF ( .NOT. l_fast_exchanges ) & 
    231                      ARRAY_IN(1,nlcj-1,:,:,jf) = SGN_IN(jf) * ARRAY_IN(2,nlcj-2,:,:,jf) 
    232                ENDIF 
    233                IF((nimpp + nlci - 1) .eq. jpiglo) THEN 
    234                   ARRAY_IN(nlci,nlcj,:,:,jf) = SGN_IN(jf) * ARRAY_IN(nlci-1,nlcj-3,:,:,jf) 
    235                   IF ( .NOT. l_fast_exchanges ) & 
    236                      ARRAY_IN(nlci,nlcj-1,:,:,jf) = SGN_IN(jf) * ARRAY_IN(nlci-1,nlcj-2,:,:,jf) 
    237                ENDIF 
    238                ! 
    239             END SELECT 
     276                     iju = jpiglo - ji - nimpp - nfimpp(isendto(1)) + 3 
     277                     ARRAY_IN(ji,jpj,jk,jl,jf) = SGN_IN(jf) * ARRAY2_IN(iju,1,jk,jl,jf) 
     278                  END DO 
     279               END DO; END DO 
     280      IF (nimpp .eq. 1) THEN                
     281         DO ii = 1, nn_hls 
     282                 ARRAY_IN(ii,jpj,:,:,jf) = SGN_IN(jf) * ARRAY_IN(2*nn_hls-ii,jpj-2*nn_hls-1,:,:,jf) 
     283         END DO 
     284         IF ( .NOT. l_fast_exchanges ) THEN 
     285            DO jj = 1, nn_hls 
     286                      ijj = jpj -jj 
     287                      DO ii = 0, nn_hls-1 
     288                         ARRAY_IN(ii+1,ijj,:,:,jf) = SGN_IN(jf) * ARRAY_IN(2*nn_hls-ii,jpj-2*nn_hls+jj-1,:,:,jf) 
     289                   END DO 
     290                      END DO 
     291                     ENDIF 
     292      ENDIF 
     293      IF((nimpp + jpi - 1 ) .eq. jpiglo) THEN 
     294                   DO ii = 1, nn_hls 
     295                 ARRAY_IN(jpi-ii+1,jpj,:,:,jf) = SGN_IN(jf) * ARRAY_IN(jpi-2*nn_hls+ii,jpj-2*nn_hls-1,:,:,jf) 
     296         END DO 
     297         IF ( .NOT. l_fast_exchanges ) THEN 
     298            DO jj = 1, nn_hls 
     299                           ijj = jpj -jj 
     300                      DO ii = 1, nn_hls 
     301                         ARRAY_IN(jpi-ii+1,ijj,:,:,jf) = SGN_IN(jf) * ARRAY_IN(jpi-2*nn_hls+ii,jpj-2*nn_hls+jj-1,:,:,jf) 
     302                         END DO 
     303                      END DO 
     304                     ENDIF 
     305                  ENDIF 
     306                  ! 
     307       END SELECT 
    240308            ! 
    241309         CASE ( 5, 6 )                        ! *  North fold  F-point pivot 
     
    244312            CASE ( 'T' , 'W' )                               ! T-, W-point 
    245313               DO jl = 1, ipl; DO jk = 1, ipk 
    246                   DO ji = 1, nlci 
    247                      ijt = jpiglo - ji - nimpp - nfiimpp(isendto(1),jpnj) + 3 
    248                      ARRAY_IN(ji,nlcj,jk,jl,jf) = SGN_IN(jf) * ARRAY2_IN(ijt,ijpj,jk,jl,jf) 
    249                   END DO 
     314        DO jj = 1, nn_hls 
     315           ijj = jpj-jj+1 
     316           DO ji = 1, jpi 
     317                        ijt = jpiglo - ji - nimpp - nfimpp(isendto(1)) + 3 
     318                        ARRAY_IN(ji,ijj,jk,jl,jf) = SGN_IN(jf) * ARRAY2_IN(ijt,jj,jk,jl,jf) 
     319                     END DO 
     320        END DO 
    250321               END DO; END DO 
    251322               ! 
    252323            CASE ( 'U' )                                     ! U-point 
    253                IF( nimpp + nlci - 1 /= jpiglo ) THEN 
    254                   endloop = nlci 
     324               IF( nimpp + jpi - 1 /= jpiglo ) THEN 
     325                  endloop = jpi 
    255326               ELSE 
    256                   endloop = nlci - 1 
    257                ENDIF 
    258                DO jl = 1, ipl; DO jk = 1, ipk 
    259                   DO ji = 1, endloop 
    260                      iju = jpiglo - ji - nimpp - nfiimpp(isendto(1),jpnj) + 2 
    261                      ARRAY_IN(ji,nlcj,jk,jl,jf) = SGN_IN(jf) * ARRAY2_IN(iju,ijpj,jk,jl,jf) 
    262                   END DO 
    263                END DO; END DO 
    264                IF((nimpp + nlci - 1) .eq. jpiglo) THEN 
    265                   DO jl = 1, ipl; DO jk = 1, ipk 
    266                      ARRAY_IN(nlci,nlcj,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(nlci-2,nlcj-1,jk,jl,jf) 
     327                  endloop = jpi - nn_hls 
     328               ENDIF 
     329               DO jl = 1, ipl; DO jk = 1, ipk 
     330        DO jj = 1, nn_hls 
     331           ijj = jpj-jj+1 
     332                     DO ji = 1, endloop 
     333                        iju = jpiglo - ji - nimpp - nfimpp(isendto(1)) + 2 
     334                        ARRAY_IN(ji,ijj,jk,jl,jf) = SGN_IN(jf) * ARRAY2_IN(iju,jj,jk,jl,jf) 
     335                     END DO 
     336                  END DO 
     337               END DO; END DO 
     338               IF(nimpp + jpi - 1 .eq. jpiglo) THEN 
     339                  DO jl = 1, ipl; DO jk = 1, ipk 
     340                     DO jj = 1, nn_hls 
     341                          ijj = jpj-jj+1 
     342                        DO ii = 1, nn_hls 
     343            iij = jpi-ii+1 
     344                           ARRAY_IN(iij,ijj,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(jpi-2*nn_hls+ii-1,jpj-2*nn_hls+jj,jk,jl,jf) 
     345                        END DO 
     346                     END DO 
    267347                  END DO; END DO 
    268348               ENDIF 
     
    270350            CASE ( 'V' )                                     ! V-point 
    271351               DO jl = 1, ipl; DO jk = 1, ipk 
    272                   DO ji = 1, nlci 
    273                      ijt = jpiglo - ji - nimpp - nfiimpp(isendto(1),jpnj) + 3 
    274                      ARRAY_IN(ji,nlcj,jk,jl,jf) = SGN_IN(jf) * ARRAY2_IN(ijt,ijpj,jk,jl,jf) 
     352        DO jj = 1, nn_hls 
     353           ijj = jpj -jj +1 
     354                     DO ji = 1, jpi 
     355                        ijt = jpiglo - ji - nimpp - nfimpp(isendto(1)) + 3 
     356                        ARRAY_IN(ji,ijj,jk,jl,jf) = SGN_IN(jf) * ARRAY2_IN(ijt,jj,jk,jl,jf) 
     357                     END DO 
    275358                  END DO 
    276359               END DO; END DO 
    277360 
    278361               IF ( .NOT. l_fast_exchanges ) THEN 
    279                   IF( nimpp >= jpiglo/2+1 ) THEN 
     362                  IF( nimpp >= Ni0glo/2+2 ) THEN 
    280363                     startloop = 1 
    281                   ELSEIF( nimpp+nlci-1 >= jpiglo/2+1 .AND. nimpp < jpiglo/2+1 ) THEN 
    282                      startloop = jpiglo/2+1 - nimpp + 1 
    283                   ELSE 
    284                      startloop = nlci + 1 
    285                   ENDIF 
    286                   IF( startloop <= nlci ) THEN 
    287                   DO jl = 1, ipl; DO jk = 1, ipk 
    288                      DO ji = startloop, nlci 
    289                         ijt = jpiglo - ji - nimpp - nfiimpp(isendto(1),jpnj) + 3 
    290                         ARRAY_IN(ji,nlcj-1,jk,jl,jf) = SGN_IN(jf) * ARRAY2_IN(ijt,ijpjp1,jk,jl,jf) 
    291                      END DO 
     364                  ELSEIF( nimpp+jpi-1 >= Ni0glo/2+2 .AND. nimpp < Ni0glo/2+2 ) THEN 
     365                     startloop = Ni0glo/2+2 - nimpp + nn_hls 
     366                  ELSE 
     367                     startloop = jpi + 1 
     368                  ENDIF 
     369                  IF( startloop <= jpi ) THEN 
     370                  DO jl = 1, ipl; DO jk = 1, ipk 
     371                        DO ji = startloop, jpi 
     372                        ijt = jpiglo - ji - nimpp - nfimpp(isendto(1)) + 3 
     373                           ARRAY_IN(ji,jpj-nn_hls,jk,jl,jf) = SGN_IN(jf) * ARRAY2_IN(ijt,nn_hls+1,jk,jl,jf) 
     374                        END DO 
    292375                  END DO; END DO 
    293376                  ENDIF 
     
    295378               ! 
    296379            CASE ( 'F' )                               ! F-point 
    297                IF( nimpp + nlci - 1 /= jpiglo ) THEN 
    298                   endloop = nlci 
     380               IF( nimpp + jpi - 1 /= jpiglo ) THEN 
     381                  endloop = jpi 
    299382               ELSE 
    300                   endloop = nlci - 1 
    301                ENDIF 
    302                DO jl = 1, ipl; DO jk = 1, ipk 
    303                   DO ji = 1, endloop 
    304                      iju = jpiglo - ji - nimpp - nfiimpp(isendto(1),jpnj) + 2 
    305                      ARRAY_IN(ji,nlcj ,jk,jl,jf) = SGN_IN(jf) * ARRAY2_IN(iju,ijpj,jk,jl,jf) 
    306                   END DO 
    307                END DO; END DO 
    308                IF((nimpp + nlci - 1) .eq. jpiglo) THEN 
    309                   DO jl = 1, ipl; DO jk = 1, ipk 
    310                      ARRAY_IN(nlci,nlcj,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(nlci-2,nlcj-2,jk,jl,jf) 
    311                   END DO; END DO 
    312                ENDIF 
    313                ! 
    314                IF ( .NOT. l_fast_exchanges ) THEN 
    315                   IF( nimpp + nlci - 1 /= jpiglo ) THEN 
    316                      endloop = nlci 
    317                   ELSE 
    318                      endloop = nlci - 1 
    319                   ENDIF 
    320                   IF( nimpp >= jpiglo/2+1 ) THEN 
    321                      startloop = 1 
    322                   ELSEIF( nimpp+nlci-1 >= jpiglo/2+1 .AND. nimpp < jpiglo/2+1 ) THEN 
    323                      startloop = jpiglo/2+1 - nimpp + 1 
     383                  endloop = jpi - nn_hls 
     384               ENDIF 
     385               DO jl = 1, ipl; DO jk = 1, ipk 
     386        DO jj = 1, nn_hls 
     387          ijj = jpj -jj +1 
     388                    DO ji = 1, endloop 
     389                       iju = jpiglo - ji - nimpp - nfimpp(isendto(1)) + 2 
     390                       ARRAY_IN(ji,ijj ,jk,jl,jf) = SGN_IN(jf) * ARRAY2_IN(iju,jj,jk,jl,jf) 
     391                     END DO 
     392                  END DO 
     393               END DO; END DO 
     394               IF((nimpp + jpi - 1) .eq. jpiglo) THEN 
     395                  DO jl = 1, ipl; DO jk = 1, ipk 
     396                     DO jj = 1, nn_hls 
     397                        ijj = jpj -jj +1 
     398                        DO ii = 1, nn_hls 
     399            iij = jpi -ii+1 
     400                           ARRAY_IN(iij,ijj,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(jpi-2*nn_hls+ii-1,jpj-2*nn_hls+jj-1,jk,jl,jf) 
     401                        END DO 
     402                     END DO 
     403                  END DO; END DO 
     404               ENDIF 
     405               ! 
     406               IF ( .NOT. l_fast_exchanges ) THEN 
     407                  IF( nimpp + jpi - 1 /= jpiglo ) THEN 
     408                     endloop = jpi 
     409                  ELSE 
     410                     endloop = jpi - nn_hls 
     411                  ENDIF 
     412                  IF( nimpp >= Ni0glo/2+2 ) THEN 
     413                     startloop = 1  
     414                  ELSEIF( nimpp+jpi-1 >= Ni0glo/2+2 .AND. nimpp < Ni0glo/2+2 ) THEN 
     415                     startloop = Ni0glo/2+2 - nimpp + nn_hls 
    324416                  ELSE 
    325417                     startloop = endloop + 1 
     
    328420                     DO jl = 1, ipl; DO jk = 1, ipk 
    329421                        DO ji = startloop, endloop 
    330                            iju = jpiglo - ji - nimpp - nfiimpp(isendto(1),jpnj) + 2 
    331                            ARRAY_IN(ji,nlcj-1,jk,jl,jf) = SGN_IN(jf) * ARRAY2_IN(iju,ijpjp1,jk,jl,jf) 
     422                           iju = jpiglo - ji - nimpp - nfimpp(isendto(1)) + 2 
     423                           ARRAY_IN(ji,jpj-nn_hls,jk,jl,jf) = SGN_IN(jf) * ARRAY2_IN(iju,nn_hls+1,jk,jl,jf) 
    332424                        END DO 
    333425                     END DO; END DO 
     
    345437      END DO            ! End jf loop 
    346438   END SUBROUTINE ROUTINE_NFD 
     439#undef PRECISION 
    347440#undef ARRAY_TYPE 
    348441#undef ARRAY_IN 
  • NEMO/branches/2020/dev_12905_xios_ancil/src/OCE/LBC/lbclnk.F90

    r12377 r13766  
    2828 
    2929   INTERFACE lbc_lnk 
    30       MODULE PROCEDURE   mpp_lnk_2d      , mpp_lnk_3d      , mpp_lnk_4d 
     30      MODULE PROCEDURE   mpp_lnk_2d_sp   , mpp_lnk_3d_sp   , mpp_lnk_4d_sp 
     31      MODULE PROCEDURE   mpp_lnk_2d_dp   , mpp_lnk_3d_dp   , mpp_lnk_4d_dp 
    3132   END INTERFACE 
    3233   INTERFACE lbc_lnk_ptr 
    33       MODULE PROCEDURE   mpp_lnk_2d_ptr  , mpp_lnk_3d_ptr  , mpp_lnk_4d_ptr 
     34      MODULE PROCEDURE   mpp_lnk_2d_ptr_sp , mpp_lnk_3d_ptr_sp , mpp_lnk_4d_ptr_sp 
     35      MODULE PROCEDURE   mpp_lnk_2d_ptr_dp , mpp_lnk_3d_ptr_dp , mpp_lnk_4d_ptr_dp 
    3436   END INTERFACE 
    3537   INTERFACE lbc_lnk_multi 
    36       MODULE PROCEDURE   lbc_lnk_2d_multi, lbc_lnk_3d_multi, lbc_lnk_4d_multi 
     38      MODULE PROCEDURE   lbc_lnk_2d_multi_sp , lbc_lnk_3d_multi_sp, lbc_lnk_4d_multi_sp 
     39      MODULE PROCEDURE   lbc_lnk_2d_multi_dp , lbc_lnk_3d_multi_dp, lbc_lnk_4d_multi_dp 
    3740   END INTERFACE 
    3841   ! 
    3942   INTERFACE lbc_lnk_icb 
    40       MODULE PROCEDURE mpp_lnk_2d_icb 
     43      MODULE PROCEDURE mpp_lnk_2d_icb_dp, mpp_lnk_2d_icb_sp 
    4144   END INTERFACE 
    4245 
    4346   INTERFACE mpp_nfd 
    44       MODULE PROCEDURE   mpp_nfd_2d    , mpp_nfd_3d    , mpp_nfd_4d 
    45       MODULE PROCEDURE   mpp_nfd_2d_ptr, mpp_nfd_3d_ptr, mpp_nfd_4d_ptr 
     47      MODULE PROCEDURE   mpp_nfd_2d_sp    , mpp_nfd_3d_sp    , mpp_nfd_4d_sp 
     48      MODULE PROCEDURE   mpp_nfd_2d_dp    , mpp_nfd_3d_dp    , mpp_nfd_4d_dp 
     49      MODULE PROCEDURE   mpp_nfd_2d_ptr_sp, mpp_nfd_3d_ptr_sp, mpp_nfd_4d_ptr_sp 
     50      MODULE PROCEDURE   mpp_nfd_2d_ptr_dp, mpp_nfd_3d_ptr_dp, mpp_nfd_4d_ptr_dp 
     51       
    4652   END INTERFACE 
    4753 
     
    9298   !!---------------------------------------------------------------------- 
    9399 
    94 #  define DIM_2d 
    95 #     define ROUTINE_LOAD           load_ptr_2d 
    96 #     define ROUTINE_MULTI          lbc_lnk_2d_multi 
    97 #     include "lbc_lnk_multi_generic.h90" 
    98 #     undef ROUTINE_MULTI 
    99 #     undef ROUTINE_LOAD 
    100 #  undef DIM_2d 
    101  
    102 #  define DIM_3d 
    103 #     define ROUTINE_LOAD           load_ptr_3d 
    104 #     define ROUTINE_MULTI          lbc_lnk_3d_multi 
    105 #     include "lbc_lnk_multi_generic.h90" 
    106 #     undef ROUTINE_MULTI 
    107 #     undef ROUTINE_LOAD 
    108 #  undef DIM_3d 
    109  
    110 #  define DIM_4d 
    111 #     define ROUTINE_LOAD           load_ptr_4d 
    112 #     define ROUTINE_MULTI          lbc_lnk_4d_multi 
     100   !! 
     101   !!   ----   SINGLE PRECISION VERSIONS 
     102   !! 
     103#  define SINGLE_PRECISION 
     104#  define DIM_2d 
     105#     define ROUTINE_LOAD           load_ptr_2d_sp 
     106#     define ROUTINE_MULTI          lbc_lnk_2d_multi_sp 
     107#     include "lbc_lnk_multi_generic.h90" 
     108#     undef ROUTINE_MULTI 
     109#     undef ROUTINE_LOAD 
     110#  undef DIM_2d 
     111 
     112#  define DIM_3d 
     113#     define ROUTINE_LOAD           load_ptr_3d_sp 
     114#     define ROUTINE_MULTI          lbc_lnk_3d_multi_sp 
     115#     include "lbc_lnk_multi_generic.h90" 
     116#     undef ROUTINE_MULTI 
     117#     undef ROUTINE_LOAD 
     118#  undef DIM_3d 
     119 
     120#  define DIM_4d 
     121#     define ROUTINE_LOAD           load_ptr_4d_sp 
     122#     define ROUTINE_MULTI          lbc_lnk_4d_multi_sp 
     123#     include "lbc_lnk_multi_generic.h90" 
     124#     undef ROUTINE_MULTI 
     125#     undef ROUTINE_LOAD 
     126#  undef DIM_4d 
     127#  undef SINGLE_PRECISION 
     128   !! 
     129   !!   ----   DOUBLE PRECISION VERSIONS 
     130   !! 
     131 
     132#  define DIM_2d 
     133#     define ROUTINE_LOAD           load_ptr_2d_dp 
     134#     define ROUTINE_MULTI          lbc_lnk_2d_multi_dp 
     135#     include "lbc_lnk_multi_generic.h90" 
     136#     undef ROUTINE_MULTI 
     137#     undef ROUTINE_LOAD 
     138#  undef DIM_2d 
     139 
     140#  define DIM_3d 
     141#     define ROUTINE_LOAD           load_ptr_3d_dp 
     142#     define ROUTINE_MULTI          lbc_lnk_3d_multi_dp 
     143#     include "lbc_lnk_multi_generic.h90" 
     144#     undef ROUTINE_MULTI 
     145#     undef ROUTINE_LOAD 
     146#  undef DIM_3d 
     147 
     148#  define DIM_4d 
     149#     define ROUTINE_LOAD           load_ptr_4d_dp 
     150#     define ROUTINE_MULTI          lbc_lnk_4d_multi_dp 
    113151#     include "lbc_lnk_multi_generic.h90" 
    114152#     undef ROUTINE_MULTI 
     
    130168   !                       !==  2D array and array of 2D pointer  ==! 
    131169   ! 
    132 #  define DIM_2d 
    133 #     define ROUTINE_LNK           mpp_lnk_2d 
    134 #     include "mpp_lnk_generic.h90" 
    135 #     undef ROUTINE_LNK 
    136 #     define MULTI 
    137 #     define ROUTINE_LNK           mpp_lnk_2d_ptr 
     170   !! 
     171   !!   ----   SINGLE PRECISION VERSIONS 
     172   !! 
     173# define SINGLE_PRECISION 
     174#  define DIM_2d 
     175#     define ROUTINE_LNK           mpp_lnk_2d_sp 
     176#     include "mpp_lnk_generic.h90" 
     177#     undef ROUTINE_LNK 
     178#     define MULTI 
     179#     define ROUTINE_LNK           mpp_lnk_2d_ptr_sp 
    138180#     include "mpp_lnk_generic.h90" 
    139181#     undef ROUTINE_LNK 
     
    144186   ! 
    145187#  define DIM_3d 
    146 #     define ROUTINE_LNK           mpp_lnk_3d 
    147 #     include "mpp_lnk_generic.h90" 
    148 #     undef ROUTINE_LNK 
    149 #     define MULTI 
    150 #     define ROUTINE_LNK           mpp_lnk_3d_ptr 
     188#     define ROUTINE_LNK           mpp_lnk_3d_sp 
     189#     include "mpp_lnk_generic.h90" 
     190#     undef ROUTINE_LNK 
     191#     define MULTI 
     192#     define ROUTINE_LNK           mpp_lnk_3d_ptr_sp 
    151193#     include "mpp_lnk_generic.h90" 
    152194#     undef ROUTINE_LNK 
     
    157199   ! 
    158200#  define DIM_4d 
    159 #     define ROUTINE_LNK           mpp_lnk_4d 
    160 #     include "mpp_lnk_generic.h90" 
    161 #     undef ROUTINE_LNK 
    162 #     define MULTI 
    163 #     define ROUTINE_LNK           mpp_lnk_4d_ptr 
    164 #     include "mpp_lnk_generic.h90" 
    165 #     undef ROUTINE_LNK 
    166 #     undef MULTI 
    167 #  undef DIM_4d 
     201#     define ROUTINE_LNK           mpp_lnk_4d_sp 
     202#     include "mpp_lnk_generic.h90" 
     203#     undef ROUTINE_LNK 
     204#     define MULTI 
     205#     define ROUTINE_LNK           mpp_lnk_4d_ptr_sp 
     206#     include "mpp_lnk_generic.h90" 
     207#     undef ROUTINE_LNK 
     208#     undef MULTI 
     209#  undef DIM_4d 
     210# undef SINGLE_PRECISION 
     211 
     212   !! 
     213   !!   ----   DOUBLE PRECISION VERSIONS 
     214   !! 
     215#  define DIM_2d 
     216#     define ROUTINE_LNK           mpp_lnk_2d_dp 
     217#     include "mpp_lnk_generic.h90" 
     218#     undef ROUTINE_LNK 
     219#     define MULTI 
     220#     define ROUTINE_LNK           mpp_lnk_2d_ptr_dp 
     221#     include "mpp_lnk_generic.h90" 
     222#     undef ROUTINE_LNK 
     223#     undef MULTI 
     224#  undef DIM_2d 
     225   ! 
     226   !                       !==  3D array and array of 3D pointer  ==! 
     227   ! 
     228#  define DIM_3d 
     229#     define ROUTINE_LNK           mpp_lnk_3d_dp 
     230#     include "mpp_lnk_generic.h90" 
     231#     undef ROUTINE_LNK 
     232#     define MULTI 
     233#     define ROUTINE_LNK           mpp_lnk_3d_ptr_dp 
     234#     include "mpp_lnk_generic.h90" 
     235#     undef ROUTINE_LNK 
     236#     undef MULTI 
     237#  undef DIM_3d 
     238   ! 
     239   !                       !==  4D array and array of 4D pointer  ==! 
     240   ! 
     241#  define DIM_4d 
     242#     define ROUTINE_LNK           mpp_lnk_4d_dp 
     243#     include "mpp_lnk_generic.h90" 
     244#     undef ROUTINE_LNK 
     245#     define MULTI 
     246#     define ROUTINE_LNK           mpp_lnk_4d_ptr_dp 
     247#     include "mpp_lnk_generic.h90" 
     248#     undef ROUTINE_LNK 
     249#     undef MULTI 
     250#  undef DIM_4d 
     251 
    168252 
    169253   !!---------------------------------------------------------------------- 
     
    181265   !                       !==  2D array and array of 2D pointer  ==! 
    182266   ! 
    183 #  define DIM_2d 
    184 #     define ROUTINE_NFD           mpp_nfd_2d 
    185 #     include "mpp_nfd_generic.h90" 
    186 #     undef ROUTINE_NFD 
    187 #     define MULTI 
    188 #     define ROUTINE_NFD           mpp_nfd_2d_ptr 
     267   !! 
     268   !!   ----   SINGLE PRECISION VERSIONS 
     269   !! 
     270#  define SINGLE_PRECISION 
     271#  define DIM_2d 
     272#     define ROUTINE_NFD           mpp_nfd_2d_sp 
     273#     include "mpp_nfd_generic.h90" 
     274#     undef ROUTINE_NFD 
     275#     define MULTI 
     276#     define ROUTINE_NFD           mpp_nfd_2d_ptr_sp 
    189277#     include "mpp_nfd_generic.h90" 
    190278#     undef ROUTINE_NFD 
     
    195283   ! 
    196284#  define DIM_3d 
    197 #     define ROUTINE_NFD           mpp_nfd_3d 
    198 #     include "mpp_nfd_generic.h90" 
    199 #     undef ROUTINE_NFD 
    200 #     define MULTI 
    201 #     define ROUTINE_NFD           mpp_nfd_3d_ptr 
     285#     define ROUTINE_NFD           mpp_nfd_3d_sp 
     286#     include "mpp_nfd_generic.h90" 
     287#     undef ROUTINE_NFD 
     288#     define MULTI 
     289#     define ROUTINE_NFD           mpp_nfd_3d_ptr_sp 
    202290#     include "mpp_nfd_generic.h90" 
    203291#     undef ROUTINE_NFD 
     
    208296   ! 
    209297#  define DIM_4d 
    210 #     define ROUTINE_NFD           mpp_nfd_4d 
    211 #     include "mpp_nfd_generic.h90" 
    212 #     undef ROUTINE_NFD 
    213 #     define MULTI 
    214 #     define ROUTINE_NFD           mpp_nfd_4d_ptr 
    215 #     include "mpp_nfd_generic.h90" 
    216 #     undef ROUTINE_NFD 
    217 #     undef MULTI 
    218 #  undef DIM_4d 
    219  
     298#     define ROUTINE_NFD           mpp_nfd_4d_sp 
     299#     include "mpp_nfd_generic.h90" 
     300#     undef ROUTINE_NFD 
     301#     define MULTI 
     302#     define ROUTINE_NFD           mpp_nfd_4d_ptr_sp 
     303#     include "mpp_nfd_generic.h90" 
     304#     undef ROUTINE_NFD 
     305#     undef MULTI 
     306#  undef DIM_4d 
     307#  undef SINGLE_PRECISION 
     308 
     309   !! 
     310   !!   ----   DOUBLE PRECISION VERSIONS 
     311   !! 
     312#  define DIM_2d 
     313#     define ROUTINE_NFD           mpp_nfd_2d_dp 
     314#     include "mpp_nfd_generic.h90" 
     315#     undef ROUTINE_NFD 
     316#     define MULTI 
     317#     define ROUTINE_NFD           mpp_nfd_2d_ptr_dp 
     318#     include "mpp_nfd_generic.h90" 
     319#     undef ROUTINE_NFD 
     320#     undef MULTI 
     321#  undef DIM_2d 
     322   ! 
     323   !                       !==  3D array and array of 3D pointer  ==! 
     324   ! 
     325#  define DIM_3d 
     326#     define ROUTINE_NFD           mpp_nfd_3d_dp 
     327#     include "mpp_nfd_generic.h90" 
     328#     undef ROUTINE_NFD 
     329#     define MULTI 
     330#     define ROUTINE_NFD           mpp_nfd_3d_ptr_dp 
     331#     include "mpp_nfd_generic.h90" 
     332#     undef ROUTINE_NFD 
     333#     undef MULTI 
     334#  undef DIM_3d 
     335   ! 
     336   !                       !==  4D array and array of 4D pointer  ==! 
     337   ! 
     338#  define DIM_4d 
     339#     define ROUTINE_NFD           mpp_nfd_4d_dp 
     340#     include "mpp_nfd_generic.h90" 
     341#     undef ROUTINE_NFD 
     342#     define MULTI 
     343#     define ROUTINE_NFD           mpp_nfd_4d_ptr_dp 
     344#     include "mpp_nfd_generic.h90" 
     345#     undef ROUTINE_NFD 
     346#     undef MULTI 
     347#  undef DIM_4d 
    220348 
    221349   !!====================================================================== 
    222350 
    223351 
    224  
    225    SUBROUTINE mpp_lbc_north_icb( pt2d, cd_type, psgn, kextj) 
    226       !!--------------------------------------------------------------------- 
     352   !!====================================================================== 
     353     !!--------------------------------------------------------------------- 
    227354      !!                   ***  routine mpp_lbc_north_icb  *** 
    228355      !! 
     
    240367      !! 
    241368      !!---------------------------------------------------------------------- 
    242       REAL(wp), DIMENSION(:,:), INTENT(inout) ::   pt2d     ! 2D array with extra halo 
    243       CHARACTER(len=1)        , INTENT(in   ) ::   cd_type  ! nature of pt3d grid-points 
    244       !                                                     !   = T ,  U , V , F or W -points 
    245       REAL(wp)                , INTENT(in   ) ::   psgn     ! = -1. the sign change across the 
    246       !!                                                    ! north fold, =  1. otherwise 
    247       INTEGER                 , INTENT(in   ) ::   kextj    ! Extra halo width at north fold 
    248       ! 
    249       INTEGER ::   ji, jj, jr 
    250       INTEGER ::   ierr, itaille, ildi, ilei, iilb 
    251       INTEGER ::   ipj, ij, iproc 
    252       ! 
    253       REAL(wp), DIMENSION(:,:)  , ALLOCATABLE  ::  ztab_e, znorthloc_e 
    254       REAL(wp), DIMENSION(:,:,:), ALLOCATABLE  ::  znorthgloio_e 
    255       !!---------------------------------------------------------------------- 
    256 #if defined key_mpp_mpi 
    257       ! 
    258       ipj=4 
    259       ALLOCATE(        ztab_e(jpiglo, 1-kextj:ipj+kextj)       ,       & 
    260      &            znorthloc_e(jpimax, 1-kextj:ipj+kextj)       ,       & 
    261      &          znorthgloio_e(jpimax, 1-kextj:ipj+kextj,jpni)    ) 
    262       ! 
    263       ztab_e(:,:)      = 0._wp 
    264       znorthloc_e(:,:) = 0._wp 
    265       ! 
    266       ij = 1 - kextj 
    267       ! put the last ipj+2*kextj lines of pt2d into znorthloc_e  
    268       DO jj = jpj - ipj + 1 - kextj , jpj + kextj 
    269          znorthloc_e(1:jpi,ij)=pt2d(1:jpi,jj) 
    270          ij = ij + 1 
    271       END DO 
    272       ! 
    273       itaille = jpimax * ( ipj + 2*kextj ) 
    274       ! 
    275       IF( ln_timing ) CALL tic_tac(.TRUE.) 
    276       CALL MPI_ALLGATHER( znorthloc_e(1,1-kextj)    , itaille, MPI_DOUBLE_PRECISION,    & 
    277          &                znorthgloio_e(1,1-kextj,1), itaille, MPI_DOUBLE_PRECISION,    & 
    278          &                ncomm_north, ierr ) 
    279       ! 
    280       IF( ln_timing ) CALL tic_tac(.FALSE.) 
    281       ! 
    282       DO jr = 1, ndim_rank_north            ! recover the global north array 
    283          iproc = nrank_north(jr) + 1 
    284          ildi = nldit (iproc) 
    285          ilei = nleit (iproc) 
    286          iilb = nimppt(iproc) 
    287          DO jj = 1-kextj, ipj+kextj 
    288             DO ji = ildi, ilei 
    289                ztab_e(ji+iilb-1,jj) = znorthgloio_e(ji,jj,jr) 
    290             END DO 
    291          END DO 
    292       END DO 
    293  
    294       ! 2. North-Fold boundary conditions 
    295       ! ---------------------------------- 
    296       CALL lbc_nfd( ztab_e(:,1-kextj:ipj+kextj), cd_type, psgn, kextj ) 
    297  
    298       ij = 1 - kextj 
    299       !! Scatter back to pt2d 
    300       DO jj = jpj - ipj + 1 - kextj , jpj + kextj 
    301          DO ji= 1, jpi 
    302             pt2d(ji,jj) = ztab_e(ji+nimpp-1,ij) 
    303          END DO 
    304          ij  = ij +1 
    305       END DO 
    306       ! 
    307       DEALLOCATE( ztab_e, znorthloc_e, znorthgloio_e ) 
    308       ! 
    309 #endif 
    310    END SUBROUTINE mpp_lbc_north_icb 
    311  
    312  
    313    SUBROUTINE mpp_lnk_2d_icb( cdname, pt2d, cd_type, psgn, kexti, kextj ) 
     369#     define SINGLE_PRECISION 
     370#     define ROUTINE_LNK           mpp_lbc_north_icb_sp 
     371#     include "mpp_lbc_north_icb_generic.h90" 
     372#     undef ROUTINE_LNK 
     373#     undef SINGLE_PRECISION 
     374#     define ROUTINE_LNK           mpp_lbc_north_icb_dp 
     375#     include "mpp_lbc_north_icb_generic.h90" 
     376#     undef ROUTINE_LNK 
     377  
     378 
    314379      !!---------------------------------------------------------------------- 
    315380      !!                  ***  routine mpp_lnk_2d_icb  *** 
     
    333398      !!                    nono   : number for local neighboring processors 
    334399      !!---------------------------------------------------------------------- 
    335       CHARACTER(len=*)                                        , INTENT(in   ) ::   cdname      ! name of the calling subroutine 
    336       REAL(wp), DIMENSION(1-kexti:jpi+kexti,1-kextj:jpj+kextj), INTENT(inout) ::   pt2d     ! 2D array with extra halo 
    337       CHARACTER(len=1)                                        , INTENT(in   ) ::   cd_type  ! nature of ptab array grid-points 
    338       REAL(wp)                                                , INTENT(in   ) ::   psgn     ! sign used across the north fold 
    339       INTEGER                                                 , INTENT(in   ) ::   kexti    ! extra i-halo width 
    340       INTEGER                                                 , INTENT(in   ) ::   kextj    ! extra j-halo width 
    341       ! 
    342       INTEGER  ::   jl   ! dummy loop indices 
    343       INTEGER  ::   imigr, iihom, ijhom        ! local integers 
    344       INTEGER  ::   ipreci, iprecj             !   -       - 
    345       INTEGER  ::   ml_req1, ml_req2, ml_err   ! for key_mpi_isend 
    346       INTEGER, DIMENSION(MPI_STATUS_SIZE) ::   ml_stat   ! for key_mpi_isend 
    347       !! 
    348       REAL(wp), DIMENSION(1-kexti:jpi+kexti,nn_hls+kextj,2) ::   r2dns, r2dsn 
    349       REAL(wp), DIMENSION(1-kextj:jpj+kextj,nn_hls+kexti,2) ::   r2dwe, r2dew 
    350       !!---------------------------------------------------------------------- 
    351  
    352       ipreci = nn_hls + kexti      ! take into account outer extra 2D overlap area 
    353       iprecj = nn_hls + kextj 
    354  
    355       IF( narea == 1 .AND. numcom == -1 ) CALL mpp_report( cdname, 1, 1, 1, ld_lbc = .TRUE. ) 
    356  
    357       ! 1. standard boundary treatment 
    358       ! ------------------------------ 
    359       ! Order matters Here !!!! 
    360       ! 
    361       !                                      ! East-West boundaries 
    362       !                                           !* Cyclic east-west 
    363       IF( l_Iperio ) THEN 
    364          pt2d(1-kexti:     1   ,:) = pt2d(jpim1-kexti: jpim1 ,:)       ! east 
    365          pt2d(  jpi  :jpi+kexti,:) = pt2d(     2     :2+kexti,:)       ! west 
    366          ! 
    367       ELSE                                        !* closed 
    368          IF( .NOT. cd_type == 'F' )   pt2d(  1-kexti   :nn_hls   ,:) = 0._wp    ! east except at F-point 
    369                                       pt2d(jpi-nn_hls+1:jpi+kexti,:) = 0._wp    ! west 
    370       ENDIF 
    371       !                                      ! North-South boundaries 
    372       IF( l_Jperio ) THEN                         !* cyclic (only with no mpp j-split) 
    373          pt2d(:,1-kextj:     1   ) = pt2d(:,jpjm1-kextj:  jpjm1)       ! north 
    374          pt2d(:,  jpj  :jpj+kextj) = pt2d(:,     2     :2+kextj)       ! south 
    375       ELSE                                        !* closed 
    376          IF( .NOT. cd_type == 'F' )   pt2d(:,  1-kextj   :nn_hls   ) = 0._wp    ! north except at F-point 
    377                                       pt2d(:,jpj-nn_hls+1:jpj+kextj) = 0._wp    ! south 
    378       ENDIF 
    379       ! 
    380  
    381       ! north fold treatment 
    382       ! ----------------------- 
    383       IF( npolj /= 0 ) THEN 
    384          ! 
    385          SELECT CASE ( jpni ) 
    386                    CASE ( 1 )     ;   CALL lbc_nfd          ( pt2d(1:jpi,1:jpj+kextj), cd_type, psgn, kextj ) 
    387                    CASE DEFAULT   ;   CALL mpp_lbc_north_icb( pt2d(1:jpi,1:jpj+kextj), cd_type, psgn, kextj ) 
    388          END SELECT 
    389          ! 
    390       ENDIF 
    391  
    392       ! 2. East and west directions exchange 
    393       ! ------------------------------------ 
    394       ! we play with the neigbours AND the row number because of the periodicity 
    395       ! 
    396       SELECT CASE ( nbondi )      ! Read Dirichlet lateral conditions 
    397       CASE ( -1, 0, 1 )                ! all exept 2 (i.e. close case) 
    398          iihom = jpi-nreci-kexti 
    399          DO jl = 1, ipreci 
    400             r2dew(:,jl,1) = pt2d(nn_hls+jl,:) 
    401             r2dwe(:,jl,1) = pt2d(iihom +jl,:) 
    402          END DO 
    403       END SELECT 
    404       ! 
    405       !                           ! Migrations 
    406       imigr = ipreci * ( jpj + 2*kextj ) 
    407       ! 
    408       IF( ln_timing ) CALL tic_tac(.TRUE.) 
    409       ! 
    410       SELECT CASE ( nbondi ) 
    411       CASE ( -1 ) 
    412          CALL mppsend( 2, r2dwe(1-kextj,1,1), imigr, noea, ml_req1 ) 
    413          CALL mpprecv( 1, r2dew(1-kextj,1,2), imigr, noea ) 
    414          CALL mpi_wait(ml_req1,ml_stat,ml_err) 
    415       CASE ( 0 ) 
    416          CALL mppsend( 1, r2dew(1-kextj,1,1), imigr, nowe, ml_req1 ) 
    417          CALL mppsend( 2, r2dwe(1-kextj,1,1), imigr, noea, ml_req2 ) 
    418          CALL mpprecv( 1, r2dew(1-kextj,1,2), imigr, noea ) 
    419          CALL mpprecv( 2, r2dwe(1-kextj,1,2), imigr, nowe ) 
    420          CALL mpi_wait(ml_req1,ml_stat,ml_err) 
    421          CALL mpi_wait(ml_req2,ml_stat,ml_err) 
    422       CASE ( 1 ) 
    423          CALL mppsend( 1, r2dew(1-kextj,1,1), imigr, nowe, ml_req1 ) 
    424          CALL mpprecv( 2, r2dwe(1-kextj,1,2), imigr, nowe ) 
    425          CALL mpi_wait(ml_req1,ml_stat,ml_err) 
    426       END SELECT 
    427       ! 
    428       IF( ln_timing ) CALL tic_tac(.FALSE.) 
    429       ! 
    430       !                           ! Write Dirichlet lateral conditions 
    431       iihom = jpi - nn_hls 
    432       ! 
    433       SELECT CASE ( nbondi ) 
    434       CASE ( -1 ) 
    435          DO jl = 1, ipreci 
    436             pt2d(iihom+jl,:) = r2dew(:,jl,2) 
    437          END DO 
    438       CASE ( 0 ) 
    439          DO jl = 1, ipreci 
    440             pt2d(jl-kexti,:) = r2dwe(:,jl,2) 
    441             pt2d(iihom+jl,:) = r2dew(:,jl,2) 
    442          END DO 
    443       CASE ( 1 ) 
    444          DO jl = 1, ipreci 
    445             pt2d(jl-kexti,:) = r2dwe(:,jl,2) 
    446          END DO 
    447       END SELECT 
    448  
    449  
    450       ! 3. North and south directions 
    451       ! ----------------------------- 
    452       ! always closed : we play only with the neigbours 
    453       ! 
    454       IF( nbondj /= 2 ) THEN      ! Read Dirichlet lateral conditions 
    455          ijhom = jpj-nrecj-kextj 
    456          DO jl = 1, iprecj 
    457             r2dsn(:,jl,1) = pt2d(:,ijhom +jl) 
    458             r2dns(:,jl,1) = pt2d(:,nn_hls+jl) 
    459          END DO 
    460       ENDIF 
    461       ! 
    462       !                           ! Migrations 
    463       imigr = iprecj * ( jpi + 2*kexti ) 
    464       ! 
    465       IF( ln_timing ) CALL tic_tac(.TRUE.) 
    466       ! 
    467       SELECT CASE ( nbondj ) 
    468       CASE ( -1 ) 
    469          CALL mppsend( 4, r2dsn(1-kexti,1,1), imigr, nono, ml_req1 ) 
    470          CALL mpprecv( 3, r2dns(1-kexti,1,2), imigr, nono ) 
    471          CALL mpi_wait(ml_req1,ml_stat,ml_err) 
    472       CASE ( 0 ) 
    473          CALL mppsend( 3, r2dns(1-kexti,1,1), imigr, noso, ml_req1 ) 
    474          CALL mppsend( 4, r2dsn(1-kexti,1,1), imigr, nono, ml_req2 ) 
    475          CALL mpprecv( 3, r2dns(1-kexti,1,2), imigr, nono ) 
    476          CALL mpprecv( 4, r2dsn(1-kexti,1,2), imigr, noso ) 
    477          CALL mpi_wait(ml_req1,ml_stat,ml_err) 
    478          CALL mpi_wait(ml_req2,ml_stat,ml_err) 
    479       CASE ( 1 ) 
    480          CALL mppsend( 3, r2dns(1-kexti,1,1), imigr, noso, ml_req1 ) 
    481          CALL mpprecv( 4, r2dsn(1-kexti,1,2), imigr, noso ) 
    482          CALL mpi_wait(ml_req1,ml_stat,ml_err) 
    483       END SELECT 
    484       ! 
    485       IF( ln_timing ) CALL tic_tac(.FALSE.) 
    486       ! 
    487       !                           ! Write Dirichlet lateral conditions 
    488       ijhom = jpj - nn_hls 
    489       ! 
    490       SELECT CASE ( nbondj ) 
    491       CASE ( -1 ) 
    492          DO jl = 1, iprecj 
    493             pt2d(:,ijhom+jl) = r2dns(:,jl,2) 
    494          END DO 
    495       CASE ( 0 ) 
    496          DO jl = 1, iprecj 
    497             pt2d(:,jl-kextj) = r2dsn(:,jl,2) 
    498             pt2d(:,ijhom+jl) = r2dns(:,jl,2) 
    499          END DO 
    500       CASE ( 1 ) 
    501          DO jl = 1, iprecj 
    502             pt2d(:,jl-kextj) = r2dsn(:,jl,2) 
    503          END DO 
    504       END SELECT 
    505       ! 
    506    END SUBROUTINE mpp_lnk_2d_icb 
    507     
     400 
     401#     define SINGLE_PRECISION 
     402#     define ROUTINE_LNK           mpp_lnk_2d_icb_sp 
     403#     include "mpp_lnk_icb_generic.h90" 
     404#     undef ROUTINE_LNK 
     405#     undef SINGLE_PRECISION 
     406#     define ROUTINE_LNK           mpp_lnk_2d_icb_dp 
     407#     include "mpp_lnk_icb_generic.h90" 
     408#     undef ROUTINE_LNK 
     409   
    508410END MODULE lbclnk 
    509411 
  • NEMO/branches/2020/dev_12905_xios_ancil/src/OCE/LBC/lbcnfd.F90

    r11536 r13766  
    2626 
    2727   INTERFACE lbc_nfd 
    28       MODULE PROCEDURE   lbc_nfd_2d    , lbc_nfd_3d    , lbc_nfd_4d 
    29       MODULE PROCEDURE   lbc_nfd_2d_ptr, lbc_nfd_3d_ptr, lbc_nfd_4d_ptr 
    30       MODULE PROCEDURE   lbc_nfd_2d_ext 
     28      MODULE PROCEDURE   lbc_nfd_2d_sp    , lbc_nfd_3d_sp    , lbc_nfd_4d_sp 
     29      MODULE PROCEDURE   lbc_nfd_2d_ptr_sp, lbc_nfd_3d_ptr_sp, lbc_nfd_4d_ptr_sp 
     30      MODULE PROCEDURE   lbc_nfd_2d_ext_sp 
     31      MODULE PROCEDURE   lbc_nfd_2d_dp    , lbc_nfd_3d_dp    , lbc_nfd_4d_dp 
     32      MODULE PROCEDURE   lbc_nfd_2d_ptr_dp, lbc_nfd_3d_ptr_dp, lbc_nfd_4d_ptr_dp 
     33      MODULE PROCEDURE   lbc_nfd_2d_ext_dp 
    3134   END INTERFACE 
    3235   ! 
    3336   INTERFACE lbc_nfd_nogather 
    3437!                        ! Currently only 4d array version is needed 
    35      MODULE PROCEDURE   lbc_nfd_nogather_2d    , lbc_nfd_nogather_3d 
    36      MODULE PROCEDURE   lbc_nfd_nogather_4d 
    37      MODULE PROCEDURE   lbc_nfd_nogather_2d_ptr, lbc_nfd_nogather_3d_ptr 
     38     MODULE PROCEDURE   lbc_nfd_nogather_2d_sp    , lbc_nfd_nogather_3d_sp 
     39     MODULE PROCEDURE   lbc_nfd_nogather_4d_sp 
     40     MODULE PROCEDURE   lbc_nfd_nogather_2d_ptr_sp, lbc_nfd_nogather_3d_ptr_sp 
     41     MODULE PROCEDURE   lbc_nfd_nogather_2d_dp    , lbc_nfd_nogather_3d_dp 
     42     MODULE PROCEDURE   lbc_nfd_nogather_4d_dp 
     43     MODULE PROCEDURE   lbc_nfd_nogather_2d_ptr_dp, lbc_nfd_nogather_3d_ptr_dp 
    3844!     MODULE PROCEDURE   lbc_nfd_nogather_4d_ptr 
    3945   END INTERFACE 
    4046 
    41    TYPE, PUBLIC ::   PTR_2D   !: array of 2D pointers (also used in lib_mpp) 
    42       REAL(wp), DIMENSION (:,:)    , POINTER ::   pt2d 
    43    END TYPE PTR_2D 
    44    TYPE, PUBLIC ::   PTR_3D   !: array of 3D pointers (also used in lib_mpp) 
    45       REAL(wp), DIMENSION (:,:,:)  , POINTER ::   pt3d 
    46    END TYPE PTR_3D 
    47    TYPE, PUBLIC ::   PTR_4D   !: array of 4D pointers (also used in lib_mpp) 
    48       REAL(wp), DIMENSION (:,:,:,:), POINTER ::   pt4d 
    49    END TYPE PTR_4D 
     47   TYPE, PUBLIC ::   PTR_2D_dp   !: array of 2D pointers (also used in lib_mpp) 
     48      REAL(dp), DIMENSION (:,:)    , POINTER ::   pt2d 
     49   END TYPE PTR_2D_dp 
     50   TYPE, PUBLIC ::   PTR_3D_dp   !: array of 3D pointers (also used in lib_mpp) 
     51      REAL(dp), DIMENSION (:,:,:)  , POINTER ::   pt3d 
     52   END TYPE PTR_3D_dp 
     53   TYPE, PUBLIC ::   PTR_4D_dp   !: array of 4D pointers (also used in lib_mpp) 
     54      REAL(dp), DIMENSION (:,:,:,:), POINTER ::   pt4d 
     55   END TYPE PTR_4D_dp 
     56 
     57   TYPE, PUBLIC ::   PTR_2D_sp   !: array of 2D pointers (also used in lib_mpp) 
     58      REAL(sp), DIMENSION (:,:)    , POINTER ::   pt2d 
     59   END TYPE PTR_2D_sp 
     60   TYPE, PUBLIC ::   PTR_3D_sp   !: array of 3D pointers (also used in lib_mpp) 
     61      REAL(sp), DIMENSION (:,:,:)  , POINTER ::   pt3d 
     62   END TYPE PTR_3D_sp 
     63   TYPE, PUBLIC ::   PTR_4D_sp   !: array of 4D pointers (also used in lib_mpp) 
     64      REAL(sp), DIMENSION (:,:,:,:), POINTER ::   pt4d 
     65   END TYPE PTR_4D_sp 
     66 
    5067 
    5168   PUBLIC   lbc_nfd            ! north fold conditions 
     
    5370 
    5471   INTEGER, PUBLIC, PARAMETER            ::   jpmaxngh = 3               !: 
    55    INTEGER, PUBLIC                       ::   nsndto, nfsloop, nfeloop   !: 
     72   INTEGER, PUBLIC                       ::   nsndto                     !: 
    5673   INTEGER, PUBLIC, DIMENSION (jpmaxngh) ::   isendto                    !: processes to which communicate 
     74   INTEGER, PUBLIC                       ::   ijpj 
    5775 
    5876   !!---------------------------------------------------------------------- 
     
    7593   !!---------------------------------------------------------------------- 
    7694   ! 
    77    !                       !==  2D array and array of 2D pointer  ==! 
    78    ! 
    79 #  define DIM_2d 
    80 #     define ROUTINE_NFD           lbc_nfd_2d 
    81 #     include "lbc_nfd_generic.h90" 
    82 #     undef ROUTINE_NFD 
    83 #     define MULTI 
    84 #     define ROUTINE_NFD           lbc_nfd_2d_ptr 
     95   !                       !==  SINGLE PRECISION VERSIONS 
     96   ! 
     97   ! 
     98   !                       !==  2D array and array of 2D pointer  ==! 
     99   ! 
     100#  define SINGLE_PRECISION 
     101#  define DIM_2d 
     102#     define ROUTINE_NFD           lbc_nfd_2d_sp 
     103#     include "lbc_nfd_generic.h90" 
     104#     undef ROUTINE_NFD 
     105#     define MULTI 
     106#     define ROUTINE_NFD           lbc_nfd_2d_ptr_sp 
    85107#     include "lbc_nfd_generic.h90" 
    86108#     undef ROUTINE_NFD 
     
    91113   ! 
    92114#  define DIM_2d 
    93 #     define ROUTINE_NFD           lbc_nfd_2d_ext 
     115#     define ROUTINE_NFD           lbc_nfd_2d_ext_sp 
    94116#     include "lbc_nfd_ext_generic.h90" 
    95117#     undef ROUTINE_NFD 
     
    99121   ! 
    100122#  define DIM_3d 
    101 #     define ROUTINE_NFD           lbc_nfd_3d 
    102 #     include "lbc_nfd_generic.h90" 
    103 #     undef ROUTINE_NFD 
    104 #     define MULTI 
    105 #     define ROUTINE_NFD           lbc_nfd_3d_ptr 
    106 #     include "lbc_nfd_generic.h90" 
    107 #     undef ROUTINE_NFD 
    108 #     undef MULTI 
    109 #  undef DIM_3d 
    110    ! 
    111    !                       !==  4D array and array of 4D pointer  ==! 
    112    ! 
    113 #  define DIM_4d 
    114 #     define ROUTINE_NFD           lbc_nfd_4d 
    115 #     include "lbc_nfd_generic.h90" 
    116 #     undef ROUTINE_NFD 
    117 #     define MULTI 
    118 #     define ROUTINE_NFD           lbc_nfd_4d_ptr 
     123#     define ROUTINE_NFD           lbc_nfd_3d_sp 
     124#     include "lbc_nfd_generic.h90" 
     125#     undef ROUTINE_NFD 
     126#     define MULTI 
     127#     define ROUTINE_NFD           lbc_nfd_3d_ptr_sp 
     128#     include "lbc_nfd_generic.h90" 
     129#     undef ROUTINE_NFD 
     130#     undef MULTI 
     131#  undef DIM_3d 
     132   ! 
     133   !                       !==  4D array and array of 4D pointer  ==! 
     134   ! 
     135#  define DIM_4d 
     136#     define ROUTINE_NFD           lbc_nfd_4d_sp 
     137#     include "lbc_nfd_generic.h90" 
     138#     undef ROUTINE_NFD 
     139#     define MULTI 
     140#     define ROUTINE_NFD           lbc_nfd_4d_ptr_sp 
    119141#     include "lbc_nfd_generic.h90" 
    120142#     undef ROUTINE_NFD 
     
    127149   ! 
    128150#  define DIM_2d 
    129 #     define ROUTINE_NFD           lbc_nfd_nogather_2d 
    130 #     include "lbc_nfd_nogather_generic.h90" 
    131 #     undef ROUTINE_NFD 
    132 #     define MULTI 
    133 #     define ROUTINE_NFD           lbc_nfd_nogather_2d_ptr 
    134 #     include "lbc_nfd_nogather_generic.h90" 
    135 #     undef ROUTINE_NFD 
    136 #     undef MULTI 
    137 #  undef DIM_2d 
    138    ! 
    139    !                       !==  3D array and array of 3D pointer  ==! 
    140    ! 
    141 #  define DIM_3d 
    142 #     define ROUTINE_NFD           lbc_nfd_nogather_3d 
    143 #     include "lbc_nfd_nogather_generic.h90" 
    144 #     undef ROUTINE_NFD 
    145 #     define MULTI 
    146 #     define ROUTINE_NFD           lbc_nfd_nogather_3d_ptr 
    147 #     include "lbc_nfd_nogather_generic.h90" 
    148 #     undef ROUTINE_NFD 
    149 #     undef MULTI 
    150 #  undef DIM_3d 
    151    ! 
    152    !                       !==  4D array and array of 4D pointer  ==! 
    153    ! 
    154 #  define DIM_4d 
    155 #     define ROUTINE_NFD           lbc_nfd_nogather_4d 
     151#     define ROUTINE_NFD           lbc_nfd_nogather_2d_sp 
     152#     include "lbc_nfd_nogather_generic.h90" 
     153#     undef ROUTINE_NFD 
     154#     define MULTI 
     155#     define ROUTINE_NFD           lbc_nfd_nogather_2d_ptr_sp 
     156#     include "lbc_nfd_nogather_generic.h90" 
     157#     undef ROUTINE_NFD 
     158#     undef MULTI 
     159#  undef DIM_2d 
     160   ! 
     161   !                       !==  3D array and array of 3D pointer  ==! 
     162   ! 
     163#  define DIM_3d 
     164#     define ROUTINE_NFD           lbc_nfd_nogather_3d_sp 
     165#     include "lbc_nfd_nogather_generic.h90" 
     166#     undef ROUTINE_NFD 
     167#     define MULTI 
     168#     define ROUTINE_NFD           lbc_nfd_nogather_3d_ptr_sp 
     169#     include "lbc_nfd_nogather_generic.h90" 
     170#     undef ROUTINE_NFD 
     171#     undef MULTI 
     172#  undef DIM_3d 
     173   ! 
     174   !                       !==  4D array and array of 4D pointer  ==! 
     175   ! 
     176#  define DIM_4d 
     177#     define ROUTINE_NFD           lbc_nfd_nogather_4d_sp 
    156178#     include "lbc_nfd_nogather_generic.h90" 
    157179#     undef ROUTINE_NFD 
     
    162184!#     undef MULTI 
    163185#  undef DIM_4d 
    164  
    165    !!---------------------------------------------------------------------- 
     186#  undef SINGLE_PRECISION 
     187 
     188   !!---------------------------------------------------------------------- 
     189   ! 
     190   !                       !==  DOUBLE PRECISION VERSIONS 
     191   ! 
     192   ! 
     193   !                       !==  2D array and array of 2D pointer  ==! 
     194   ! 
     195#  define DIM_2d 
     196#     define ROUTINE_NFD           lbc_nfd_2d_dp 
     197#     include "lbc_nfd_generic.h90" 
     198#     undef ROUTINE_NFD 
     199#     define MULTI 
     200#     define ROUTINE_NFD           lbc_nfd_2d_ptr_dp 
     201#     include "lbc_nfd_generic.h90" 
     202#     undef ROUTINE_NFD 
     203#     undef MULTI 
     204#  undef DIM_2d 
     205   ! 
     206   !                       !==  2D array with extra haloes  ==! 
     207   ! 
     208#  define DIM_2d 
     209#     define ROUTINE_NFD           lbc_nfd_2d_ext_dp 
     210#     include "lbc_nfd_ext_generic.h90" 
     211#     undef ROUTINE_NFD 
     212#  undef DIM_2d 
     213   ! 
     214   !                       !==  3D array and array of 3D pointer  ==! 
     215   ! 
     216#  define DIM_3d 
     217#     define ROUTINE_NFD           lbc_nfd_3d_dp 
     218#     include "lbc_nfd_generic.h90" 
     219#     undef ROUTINE_NFD 
     220#     define MULTI 
     221#     define ROUTINE_NFD           lbc_nfd_3d_ptr_dp 
     222#     include "lbc_nfd_generic.h90" 
     223#     undef ROUTINE_NFD 
     224#     undef MULTI 
     225#  undef DIM_3d 
     226   ! 
     227   !                       !==  4D array and array of 4D pointer  ==! 
     228   ! 
     229#  define DIM_4d 
     230#     define ROUTINE_NFD           lbc_nfd_4d_dp 
     231#     include "lbc_nfd_generic.h90" 
     232#     undef ROUTINE_NFD 
     233#     define MULTI 
     234#     define ROUTINE_NFD           lbc_nfd_4d_ptr_dp 
     235#     include "lbc_nfd_generic.h90" 
     236#     undef ROUTINE_NFD 
     237#     undef MULTI 
     238#  undef DIM_4d 
     239   ! 
     240   !  lbc_nfd_nogather routines 
     241   ! 
     242   !                       !==  2D array and array of 2D pointer  ==! 
     243   ! 
     244#  define DIM_2d 
     245#     define ROUTINE_NFD           lbc_nfd_nogather_2d_dp 
     246#     include "lbc_nfd_nogather_generic.h90" 
     247#     undef ROUTINE_NFD 
     248#     define MULTI 
     249#     define ROUTINE_NFD           lbc_nfd_nogather_2d_ptr_dp 
     250#     include "lbc_nfd_nogather_generic.h90" 
     251#     undef ROUTINE_NFD 
     252#     undef MULTI 
     253#  undef DIM_2d 
     254   ! 
     255   !                       !==  3D array and array of 3D pointer  ==! 
     256   ! 
     257#  define DIM_3d 
     258#     define ROUTINE_NFD           lbc_nfd_nogather_3d_dp 
     259#     include "lbc_nfd_nogather_generic.h90" 
     260#     undef ROUTINE_NFD 
     261#     define MULTI 
     262#     define ROUTINE_NFD           lbc_nfd_nogather_3d_ptr_dp 
     263#     include "lbc_nfd_nogather_generic.h90" 
     264#     undef ROUTINE_NFD 
     265#     undef MULTI 
     266#  undef DIM_3d 
     267   ! 
     268   !                       !==  4D array and array of 4D pointer  ==! 
     269   ! 
     270#  define DIM_4d 
     271#     define ROUTINE_NFD           lbc_nfd_nogather_4d_dp 
     272#     include "lbc_nfd_nogather_generic.h90" 
     273#     undef ROUTINE_NFD 
     274!#     define MULTI 
     275!#     define ROUTINE_NFD           lbc_nfd_nogather_4d_ptr 
     276!#     include "lbc_nfd_nogather_generic.h90" 
     277!#     undef ROUTINE_NFD 
     278!#     undef MULTI 
     279#  undef DIM_4d 
     280 
     281   !!---------------------------------------------------------------------- 
     282 
    166283 
    167284 
  • NEMO/branches/2020/dev_12905_xios_ancil/src/OCE/LBC/lib_mpp.F90

    r12512 r13766  
    6767   PUBLIC   mpp_ini_znl 
    6868   PUBLIC   mppsend, mpprecv                          ! needed by TAM and ICB routines 
     69   PUBLIC   mppsend_sp, mpprecv_sp                          ! needed by TAM and ICB routines 
     70   PUBLIC   mppsend_dp, mpprecv_dp                          ! needed by TAM and ICB routines 
    6971   PUBLIC   mpp_report 
    7072   PUBLIC   mpp_bcast_nml 
    7173   PUBLIC   tic_tac 
    7274#if ! defined key_mpp_mpi 
     75   PUBLIC MPI_wait 
    7376   PUBLIC MPI_Wtime 
    7477#endif 
     
    7982   !! for the compilation on AIX system as well as NEC and SGI. Ok on COMPACQ 
    8083   INTERFACE mpp_min 
    81       MODULE PROCEDURE mppmin_a_int, mppmin_int, mppmin_a_real, mppmin_real 
     84      MODULE PROCEDURE mppmin_a_int, mppmin_int 
     85      MODULE PROCEDURE mppmin_a_real_sp, mppmin_real_sp 
     86      MODULE PROCEDURE mppmin_a_real_dp, mppmin_real_dp 
    8287   END INTERFACE 
    8388   INTERFACE mpp_max 
    84       MODULE PROCEDURE mppmax_a_int, mppmax_int, mppmax_a_real, mppmax_real 
     89      MODULE PROCEDURE mppmax_a_int, mppmax_int 
     90      MODULE PROCEDURE mppmax_a_real_sp, mppmax_real_sp 
     91      MODULE PROCEDURE mppmax_a_real_dp, mppmax_real_dp 
    8592   END INTERFACE 
    8693   INTERFACE mpp_sum 
    87       MODULE PROCEDURE mppsum_a_int, mppsum_int, mppsum_a_real, mppsum_real,   & 
    88          &             mppsum_realdd, mppsum_a_realdd 
     94      MODULE PROCEDURE mppsum_a_int, mppsum_int 
     95      MODULE PROCEDURE mppsum_realdd, mppsum_a_realdd 
     96      MODULE PROCEDURE mppsum_a_real_sp, mppsum_real_sp 
     97      MODULE PROCEDURE mppsum_a_real_dp, mppsum_real_dp 
    8998   END INTERFACE 
    9099   INTERFACE mpp_minloc 
    91       MODULE PROCEDURE mpp_minloc2d ,mpp_minloc3d 
     100      MODULE PROCEDURE mpp_minloc2d_sp ,mpp_minloc3d_sp 
     101      MODULE PROCEDURE mpp_minloc2d_dp ,mpp_minloc3d_dp 
    92102   END INTERFACE 
    93103   INTERFACE mpp_maxloc 
    94       MODULE PROCEDURE mpp_maxloc2d ,mpp_maxloc3d 
     104      MODULE PROCEDURE mpp_maxloc2d_sp ,mpp_maxloc3d_sp 
     105      MODULE PROCEDURE mpp_maxloc2d_dp ,mpp_maxloc3d_dp 
    95106   END INTERFACE 
    96107 
     
    105116#else    
    106117   INTEGER, PUBLIC, PARAMETER ::   MPI_STATUS_SIZE = 1 
     118   INTEGER, PUBLIC, PARAMETER ::   MPI_REAL = 4 
    107119   INTEGER, PUBLIC, PARAMETER ::   MPI_DOUBLE_PRECISION = 8 
    108120   LOGICAL, PUBLIC, PARAMETER ::   lk_mpp = .FALSE.    !: mpp flag 
     
    137149 
    138150   ! Communications summary report 
    139    CHARACTER(len=128), DIMENSION(:), ALLOCATABLE ::   crname_lbc                   !: names of lbc_lnk calling routines 
    140    CHARACTER(len=128), DIMENSION(:), ALLOCATABLE ::   crname_glb                   !: names of global comm calling routines 
    141    CHARACTER(len=128), DIMENSION(:), ALLOCATABLE ::   crname_dlg                   !: names of delayed global comm calling routines 
     151   CHARACTER(len=lca), DIMENSION(:), ALLOCATABLE ::   crname_lbc                   !: names of lbc_lnk calling routines 
     152   CHARACTER(len=lca), DIMENSION(:), ALLOCATABLE ::   crname_glb                   !: names of global comm calling routines 
     153   CHARACTER(len=lca), DIMENSION(:), ALLOCATABLE ::   crname_dlg                   !: names of delayed global comm calling routines 
    142154   INTEGER, PUBLIC                               ::   ncom_stp = 0                 !: copy of time step # istp 
    143155   INTEGER, PUBLIC                               ::   ncom_fsbc = 1                !: copy of sbc time step # nn_fsbc 
     
    158170   TYPE, PUBLIC ::   DELAYARR 
    159171      REAL(   wp), POINTER, DIMENSION(:) ::  z1d => NULL() 
    160       COMPLEX(wp), POINTER, DIMENSION(:) ::  y1d => NULL() 
     172      COMPLEX(dp), POINTER, DIMENSION(:) ::  y1d => NULL() 
    161173   END TYPE DELAYARR 
    162174   TYPE( DELAYARR ), DIMENSION(nbdelay), PUBLIC, SAVE  ::   todelay         !: must have SAVE for default initialization of DELAYARR 
     
    164176 
    165177   ! timing summary report 
    166    REAL(wp), DIMENSION(2), PUBLIC ::  waiting_time = 0._wp 
    167    REAL(wp)              , PUBLIC ::  compute_time = 0._wp, elapsed_time = 0._wp 
     178   REAL(dp), DIMENSION(2), PUBLIC ::  waiting_time = 0._dp 
     179   REAL(dp)              , PUBLIC ::  compute_time = 0._dp, elapsed_time = 0._dp 
    168180    
    169181   REAL(wp), DIMENSION(:), ALLOCATABLE, SAVE ::   tampon   ! buffer in case of bsend 
     
    251263      !! 
    252264      INTEGER ::   iflag 
     265      INTEGER :: mpi_working_type 
     266      !!---------------------------------------------------------------------- 
     267      ! 
     268#if defined key_mpp_mpi 
     269      IF (wp == dp) THEN 
     270         mpi_working_type = mpi_double_precision 
     271      ELSE 
     272         mpi_working_type = mpi_real 
     273      END IF 
     274      CALL mpi_isend( pmess, kbytes, mpi_working_type, kdest , ktyp, mpi_comm_oce, md_req, iflag ) 
     275#endif 
     276      ! 
     277   END SUBROUTINE mppsend 
     278 
     279 
     280   SUBROUTINE mppsend_dp( ktyp, pmess, kbytes, kdest, md_req ) 
     281      !!---------------------------------------------------------------------- 
     282      !!                  ***  routine mppsend  *** 
     283      !! 
     284      !! ** Purpose :   Send messag passing array 
     285      !! 
     286      !!---------------------------------------------------------------------- 
     287      REAL(dp), INTENT(inout) ::   pmess(*)   ! array of real 
     288      INTEGER , INTENT(in   ) ::   kbytes     ! size of the array pmess 
     289      INTEGER , INTENT(in   ) ::   kdest      ! receive process number 
     290      INTEGER , INTENT(in   ) ::   ktyp       ! tag of the message 
     291      INTEGER , INTENT(in   ) ::   md_req     ! argument for isend 
     292      !! 
     293      INTEGER ::   iflag 
    253294      !!---------------------------------------------------------------------- 
    254295      ! 
     
    257298#endif 
    258299      ! 
    259    END SUBROUTINE mppsend 
     300   END SUBROUTINE mppsend_dp 
     301 
     302 
     303   SUBROUTINE mppsend_sp( ktyp, pmess, kbytes, kdest, md_req ) 
     304      !!---------------------------------------------------------------------- 
     305      !!                  ***  routine mppsend  *** 
     306      !! 
     307      !! ** Purpose :   Send messag passing array 
     308      !! 
     309      !!---------------------------------------------------------------------- 
     310      REAL(sp), INTENT(inout) ::   pmess(*)   ! array of real 
     311      INTEGER , INTENT(in   ) ::   kbytes     ! size of the array pmess 
     312      INTEGER , INTENT(in   ) ::   kdest      ! receive process number 
     313      INTEGER , INTENT(in   ) ::   ktyp       ! tag of the message 
     314      INTEGER , INTENT(in   ) ::   md_req     ! argument for isend 
     315      !! 
     316      INTEGER ::   iflag 
     317      !!---------------------------------------------------------------------- 
     318      ! 
     319#if defined key_mpp_mpi 
     320      CALL mpi_isend( pmess, kbytes, mpi_real, kdest , ktyp, mpi_comm_oce, md_req, iflag ) 
     321#endif 
     322      ! 
     323   END SUBROUTINE mppsend_sp 
    260324 
    261325 
     
    275339      INTEGER :: iflag 
    276340      INTEGER :: use_source 
     341      INTEGER :: mpi_working_type 
    277342      !!---------------------------------------------------------------------- 
    278343      ! 
     
    283348      IF( PRESENT(ksource) )   use_source = ksource 
    284349      ! 
     350      IF (wp == dp) THEN 
     351         mpi_working_type = mpi_double_precision 
     352      ELSE 
     353         mpi_working_type = mpi_real 
     354      END IF 
     355      CALL mpi_recv( pmess, kbytes, mpi_working_type, use_source, ktyp, mpi_comm_oce, istatus, iflag ) 
     356#endif 
     357      ! 
     358   END SUBROUTINE mpprecv 
     359 
     360   SUBROUTINE mpprecv_dp( ktyp, pmess, kbytes, ksource ) 
     361      !!---------------------------------------------------------------------- 
     362      !!                  ***  routine mpprecv  *** 
     363      !! 
     364      !! ** Purpose :   Receive messag passing array 
     365      !! 
     366      !!---------------------------------------------------------------------- 
     367      REAL(dp), INTENT(inout) ::   pmess(*)   ! array of real 
     368      INTEGER , INTENT(in   ) ::   kbytes     ! suze of the array pmess 
     369      INTEGER , INTENT(in   ) ::   ktyp       ! Tag of the recevied message 
     370      INTEGER, OPTIONAL, INTENT(in) :: ksource    ! source process number 
     371      !! 
     372      INTEGER :: istatus(mpi_status_size) 
     373      INTEGER :: iflag 
     374      INTEGER :: use_source 
     375      !!---------------------------------------------------------------------- 
     376      ! 
     377#if defined key_mpp_mpi 
     378      ! If a specific process number has been passed to the receive call, 
     379      ! use that one. Default is to use mpi_any_source 
     380      use_source = mpi_any_source 
     381      IF( PRESENT(ksource) )   use_source = ksource 
     382      ! 
    285383      CALL mpi_recv( pmess, kbytes, mpi_double_precision, use_source, ktyp, mpi_comm_oce, istatus, iflag ) 
    286384#endif 
    287385      ! 
    288    END SUBROUTINE mpprecv 
     386   END SUBROUTINE mpprecv_dp 
     387 
     388 
     389   SUBROUTINE mpprecv_sp( ktyp, pmess, kbytes, ksource ) 
     390      !!---------------------------------------------------------------------- 
     391      !!                  ***  routine mpprecv  *** 
     392      !! 
     393      !! ** Purpose :   Receive messag passing array 
     394      !! 
     395      !!---------------------------------------------------------------------- 
     396      REAL(sp), INTENT(inout) ::   pmess(*)   ! array of real 
     397      INTEGER , INTENT(in   ) ::   kbytes     ! suze of the array pmess 
     398      INTEGER , INTENT(in   ) ::   ktyp       ! Tag of the recevied message 
     399      INTEGER, OPTIONAL, INTENT(in) :: ksource    ! source process number 
     400      !! 
     401      INTEGER :: istatus(mpi_status_size) 
     402      INTEGER :: iflag 
     403      INTEGER :: use_source 
     404      !!---------------------------------------------------------------------- 
     405      ! 
     406#if defined key_mpp_mpi 
     407      ! If a specific process number has been passed to the receive call, 
     408      ! use that one. Default is to use mpi_any_source 
     409      use_source = mpi_any_source 
     410      IF( PRESENT(ksource) )   use_source = ksource 
     411      ! 
     412      CALL mpi_recv( pmess, kbytes, mpi_real, use_source, ktyp, mpi_comm_oce, istatus, iflag ) 
     413#endif 
     414      ! 
     415   END SUBROUTINE mpprecv_sp 
    289416 
    290417 
     
    351478      CHARACTER(len=*), INTENT(in   )               ::   cdname  ! name of the calling subroutine 
    352479      CHARACTER(len=*), INTENT(in   )               ::   cdelay  ! name (used as id) of the delayed operation 
    353       COMPLEX(wp),      INTENT(in   ), DIMENSION(:) ::   y_in 
     480      COMPLEX(dp),      INTENT(in   ), DIMENSION(:) ::   y_in 
    354481      REAL(wp),         INTENT(  out), DIMENSION(:) ::   pout 
    355482      LOGICAL,          INTENT(in   )               ::   ldlast  ! true if this is the last time we call this routine 
     
    359486      INTEGER ::   idvar 
    360487      INTEGER ::   ierr, ilocalcomm 
    361       COMPLEX(wp), ALLOCATABLE, DIMENSION(:) ::   ytmp 
     488      COMPLEX(dp), ALLOCATABLE, DIMENSION(:) ::   ytmp 
    362489      !!---------------------------------------------------------------------- 
    363490#if defined key_mpp_mpi 
     
    384511            ALLOCATE(todelay(idvar)%y1d(isz)) 
    385512            todelay(idvar)%y1d(:) = CMPLX(todelay(idvar)%z1d(:), 0., wp)   ! create %y1d, complex variable needed by mpi_sumdd 
     513            ndelayid(idvar) = MPI_REQUEST_NULL                             ! initialised request to a valid value 
    386514         END IF 
    387515      ENDIF 
     
    391519         ALLOCATE(todelay(idvar)%z1d(isz), todelay(idvar)%y1d(isz))   ! allocate also %z1d as used for the restart 
    392520         CALL mpi_allreduce( y_in(:), todelay(idvar)%y1d(:), isz, MPI_DOUBLE_COMPLEX, mpi_sumdd, ilocalcomm, ierr )   ! get %y1d 
    393          todelay(idvar)%z1d(:) = REAL(todelay(idvar)%y1d(:), wp)      ! define %z1d from %y1d 
    394       ENDIF 
    395  
    396       IF( ndelayid(idvar) > 0 )   CALL mpp_delay_rcv( idvar )         ! make sure %z1d is received 
     521         ndelayid(idvar) = MPI_REQUEST_NULL 
     522      ENDIF 
     523 
     524      CALL mpp_delay_rcv( idvar )         ! make sure %z1d is received 
    397525 
    398526      ! send back pout from todelay(idvar)%z1d defined at previous call 
     
    403531      IF( ln_timing ) CALL tic_tac( .TRUE., ld_global = .TRUE.) 
    404532      CALL  mpi_allreduce( y_in(:), todelay(idvar)%y1d(:), isz, MPI_DOUBLE_COMPLEX, mpi_sumdd, ilocalcomm, ierr ) 
    405       ndelayid(idvar) = 1 
     533      ndelayid(idvar) = MPI_REQUEST_NULL 
    406534      IF( ln_timing ) CALL tic_tac(.FALSE., ld_global = .TRUE.) 
    407535# else 
     
    432560      INTEGER ::   idvar 
    433561      INTEGER ::   ierr, ilocalcomm 
    434       !!---------------------------------------------------------------------- 
    435 #if defined key_mpp_mpi 
     562      INTEGER ::   MPI_TYPE 
     563      !!---------------------------------------------------------------------- 
     564       
     565#if defined key_mpp_mpi 
     566      if( wp == dp ) then 
     567         MPI_TYPE = MPI_DOUBLE_PRECISION 
     568      else if ( wp == sp ) then 
     569         MPI_TYPE = MPI_REAL 
     570      else 
     571        CALL ctl_stop( "Error defining type, wp is neither dp nor sp" ) 
     572    
     573      end if 
     574 
    436575      ilocalcomm = mpi_comm_oce 
    437576      IF( PRESENT(kcom) )   ilocalcomm = kcom 
     
    453592            DEALLOCATE(todelay(idvar)%z1d) 
    454593            ndelayid(idvar) = -1                                      ! do as if we had no restart 
     594         ELSE 
     595            ndelayid(idvar) = MPI_REQUEST_NULL 
    455596         END IF 
    456597      ENDIF 
     
    460601         ALLOCATE(todelay(idvar)%z1d(isz)) 
    461602         CALL mpi_allreduce( p_in(:), todelay(idvar)%z1d(:), isz, MPI_DOUBLE_PRECISION, mpi_max, ilocalcomm, ierr )   ! get %z1d 
    462       ENDIF 
    463  
    464       IF( ndelayid(idvar) > 0 )   CALL mpp_delay_rcv( idvar )         ! make sure %z1d is received 
     603         ndelayid(idvar) = MPI_REQUEST_NULL 
     604      ENDIF 
     605 
     606      CALL mpp_delay_rcv( idvar )         ! make sure %z1d is received 
    465607 
    466608      ! send back pout from todelay(idvar)%z1d defined at previous call 
     
    468610 
    469611      ! send p_in into todelay(idvar)%z1d with a non-blocking communication 
     612      ! (PM) Should we get rid of MPI2 option ? MPI3 was release in 2013. Who is still using MPI2 ? 
    470613# if defined key_mpi2 
    471614      IF( ln_timing ) CALL tic_tac( .TRUE., ld_global = .TRUE.) 
    472       CALL  mpi_allreduce( p_in(:), todelay(idvar)%z1d(:), isz, MPI_DOUBLE_PRECISION, mpi_max, ilocalcomm, ierr ) 
    473       ndelayid(idvar) = 1 
     615      CALL  mpi_allreduce( p_in(:), todelay(idvar)%z1d(:), isz, MPI_TYPE, mpi_max, ilocalcomm, ierr ) 
    474616      IF( ln_timing ) CALL tic_tac(.FALSE., ld_global = .TRUE.) 
    475617# else 
    476       CALL mpi_iallreduce( p_in(:), todelay(idvar)%z1d(:), isz, MPI_DOUBLE_PRECISION, mpi_max, ilocalcomm, ndelayid(idvar), ierr ) 
     618      CALL mpi_iallreduce( p_in(:), todelay(idvar)%z1d(:), isz, MPI_TYPE, mpi_max, ilocalcomm, ndelayid(idvar), ierr ) 
    477619# endif 
    478620#else 
     
    494636      !!---------------------------------------------------------------------- 
    495637#if defined key_mpp_mpi 
    496       IF( ndelayid(kid) /= -2 ) THEN   
    497 #if ! defined key_mpi2 
    498          IF( ln_timing ) CALL tic_tac( .TRUE., ld_global = .TRUE.) 
    499          CALL mpi_wait( ndelayid(kid), MPI_STATUS_IGNORE, ierr )                        ! make sure todelay(kid) is received 
    500          IF( ln_timing ) CALL tic_tac(.FALSE., ld_global = .TRUE.) 
    501 #endif 
    502          IF( ASSOCIATED(todelay(kid)%y1d) )   todelay(kid)%z1d(:) = REAL(todelay(kid)%y1d(:), wp)  ! define %z1d from %y1d 
    503          ndelayid(kid) = -2   ! add flag to know that mpi_wait was already called on kid 
    504       ENDIF 
     638      IF( ln_timing ) CALL tic_tac( .TRUE., ld_global = .TRUE.) 
     639      ! test on ndelayid(kid) useless as mpi_wait return immediatly if the request handle is MPI_REQUEST_NULL 
     640      CALL mpi_wait( ndelayid(kid), MPI_STATUS_IGNORE, ierr ) ! after this ndelayid(kid) = MPI_REQUEST_NULL 
     641      IF( ln_timing ) CALL tic_tac( .FALSE., ld_global = .TRUE.) 
     642      IF( ASSOCIATED(todelay(kid)%y1d) )   todelay(kid)%z1d(:) = REAL(todelay(kid)%y1d(:), wp)  ! define %z1d from %y1d 
    505643#endif 
    506644   END SUBROUTINE mpp_delay_rcv 
     
    551689#  undef INTEGER_TYPE 
    552690! 
     691   !! 
     692   !!   ----   SINGLE PRECISION VERSIONS 
     693   !! 
     694#  define SINGLE_PRECISION 
    553695#  define REAL_TYPE 
    554696#  define DIM_0d 
    555 #     define ROUTINE_ALLREDUCE           mppmax_real 
     697#     define ROUTINE_ALLREDUCE           mppmax_real_sp 
    556698#     include "mpp_allreduce_generic.h90" 
    557699#     undef ROUTINE_ALLREDUCE 
    558700#  undef DIM_0d 
    559701#  define DIM_1d 
    560 #     define ROUTINE_ALLREDUCE           mppmax_a_real 
     702#     define ROUTINE_ALLREDUCE           mppmax_a_real_sp 
     703#     include "mpp_allreduce_generic.h90" 
     704#     undef ROUTINE_ALLREDUCE 
     705#  undef DIM_1d 
     706#  undef SINGLE_PRECISION 
     707   !! 
     708   !! 
     709   !!   ----   DOUBLE PRECISION VERSIONS 
     710   !! 
     711! 
     712#  define DIM_0d 
     713#     define ROUTINE_ALLREDUCE           mppmax_real_dp 
     714#     include "mpp_allreduce_generic.h90" 
     715#     undef ROUTINE_ALLREDUCE 
     716#  undef DIM_0d 
     717#  define DIM_1d 
     718#     define ROUTINE_ALLREDUCE           mppmax_a_real_dp 
    561719#     include "mpp_allreduce_generic.h90" 
    562720#     undef ROUTINE_ALLREDUCE 
     
    583741#  undef INTEGER_TYPE 
    584742! 
     743   !! 
     744   !!   ----   SINGLE PRECISION VERSIONS 
     745   !! 
     746#  define SINGLE_PRECISION 
    585747#  define REAL_TYPE 
    586748#  define DIM_0d 
    587 #     define ROUTINE_ALLREDUCE           mppmin_real 
     749#     define ROUTINE_ALLREDUCE           mppmin_real_sp 
    588750#     include "mpp_allreduce_generic.h90" 
    589751#     undef ROUTINE_ALLREDUCE 
    590752#  undef DIM_0d 
    591753#  define DIM_1d 
    592 #     define ROUTINE_ALLREDUCE           mppmin_a_real 
     754#     define ROUTINE_ALLREDUCE           mppmin_a_real_sp 
     755#     include "mpp_allreduce_generic.h90" 
     756#     undef ROUTINE_ALLREDUCE 
     757#  undef DIM_1d 
     758#  undef SINGLE_PRECISION 
     759   !! 
     760   !!   ----   DOUBLE PRECISION VERSIONS 
     761   !! 
     762 
     763#  define DIM_0d 
     764#     define ROUTINE_ALLREDUCE           mppmin_real_dp 
     765#     include "mpp_allreduce_generic.h90" 
     766#     undef ROUTINE_ALLREDUCE 
     767#  undef DIM_0d 
     768#  define DIM_1d 
     769#     define ROUTINE_ALLREDUCE           mppmin_a_real_dp 
    593770#     include "mpp_allreduce_generic.h90" 
    594771#     undef ROUTINE_ALLREDUCE 
     
    616793#  undef DIM_1d 
    617794#  undef INTEGER_TYPE 
    618 ! 
     795 
     796   !! 
     797   !!   ----   SINGLE PRECISION VERSIONS 
     798   !! 
     799#  define OPERATION_SUM 
     800#  define SINGLE_PRECISION 
    619801#  define REAL_TYPE 
    620802#  define DIM_0d 
    621 #     define ROUTINE_ALLREDUCE           mppsum_real 
     803#     define ROUTINE_ALLREDUCE           mppsum_real_sp 
    622804#     include "mpp_allreduce_generic.h90" 
    623805#     undef ROUTINE_ALLREDUCE 
    624806#  undef DIM_0d 
    625807#  define DIM_1d 
    626 #     define ROUTINE_ALLREDUCE           mppsum_a_real 
     808#     define ROUTINE_ALLREDUCE           mppsum_a_real_sp 
     809#     include "mpp_allreduce_generic.h90" 
     810#     undef ROUTINE_ALLREDUCE 
     811#  undef DIM_1d 
     812#  undef REAL_TYPE 
     813#  undef OPERATION_SUM 
     814 
     815#  undef SINGLE_PRECISION 
     816 
     817   !! 
     818   !!   ----   DOUBLE PRECISION VERSIONS 
     819   !! 
     820#  define OPERATION_SUM 
     821#  define REAL_TYPE 
     822#  define DIM_0d 
     823#     define ROUTINE_ALLREDUCE           mppsum_real_dp 
     824#     include "mpp_allreduce_generic.h90" 
     825#     undef ROUTINE_ALLREDUCE 
     826#  undef DIM_0d 
     827#  define DIM_1d 
     828#     define ROUTINE_ALLREDUCE           mppsum_a_real_dp 
    627829#     include "mpp_allreduce_generic.h90" 
    628830#     undef ROUTINE_ALLREDUCE 
     
    651853   !!---------------------------------------------------------------------- 
    652854   !! 
     855   !! 
     856   !!   ----   SINGLE PRECISION VERSIONS 
     857   !! 
     858#  define SINGLE_PRECISION 
    653859#  define OPERATION_MINLOC 
    654860#  define DIM_2d 
    655 #     define ROUTINE_LOC           mpp_minloc2d 
     861#     define ROUTINE_LOC           mpp_minloc2d_sp 
    656862#     include "mpp_loc_generic.h90" 
    657863#     undef ROUTINE_LOC 
    658864#  undef DIM_2d 
    659865#  define DIM_3d 
    660 #     define ROUTINE_LOC           mpp_minloc3d 
     866#     define ROUTINE_LOC           mpp_minloc3d_sp 
    661867#     include "mpp_loc_generic.h90" 
    662868#     undef ROUTINE_LOC 
     
    666872#  define OPERATION_MAXLOC 
    667873#  define DIM_2d 
    668 #     define ROUTINE_LOC           mpp_maxloc2d 
     874#     define ROUTINE_LOC           mpp_maxloc2d_sp 
    669875#     include "mpp_loc_generic.h90" 
    670876#     undef ROUTINE_LOC 
    671877#  undef DIM_2d 
    672878#  define DIM_3d 
    673 #     define ROUTINE_LOC           mpp_maxloc3d 
     879#     define ROUTINE_LOC           mpp_maxloc3d_sp 
    674880#     include "mpp_loc_generic.h90" 
    675881#     undef ROUTINE_LOC 
    676882#  undef DIM_3d 
    677883#  undef OPERATION_MAXLOC 
     884#  undef SINGLE_PRECISION 
     885   !! 
     886   !!   ----   DOUBLE PRECISION VERSIONS 
     887   !! 
     888#  define OPERATION_MINLOC 
     889#  define DIM_2d 
     890#     define ROUTINE_LOC           mpp_minloc2d_dp 
     891#     include "mpp_loc_generic.h90" 
     892#     undef ROUTINE_LOC 
     893#  undef DIM_2d 
     894#  define DIM_3d 
     895#     define ROUTINE_LOC           mpp_minloc3d_dp 
     896#     include "mpp_loc_generic.h90" 
     897#     undef ROUTINE_LOC 
     898#  undef DIM_3d 
     899#  undef OPERATION_MINLOC 
     900 
     901#  define OPERATION_MAXLOC 
     902#  define DIM_2d 
     903#     define ROUTINE_LOC           mpp_maxloc2d_dp 
     904#     include "mpp_loc_generic.h90" 
     905#     undef ROUTINE_LOC 
     906#  undef DIM_2d 
     907#  define DIM_3d 
     908#     define ROUTINE_LOC           mpp_maxloc3d_dp 
     909#     include "mpp_loc_generic.h90" 
     910#     undef ROUTINE_LOC 
     911#  undef DIM_3d 
     912#  undef OPERATION_MAXLOC 
     913 
    678914 
    679915   SUBROUTINE mppsync() 
     
    8651101      ! Look for how many procs on the northern boundary 
    8661102      ndim_rank_north = 0 
    867       DO jjproc = 1, jpnij 
    868          IF( njmppt(jjproc) == njmppmax )   ndim_rank_north = ndim_rank_north + 1 
     1103      DO jjproc = 1, jpni 
     1104         IF( nfproc(jjproc) /= -1 )   ndim_rank_north = ndim_rank_north + 1 
    8691105      END DO 
    8701106      ! 
     
    8761112      ! Note : the rank start at 0 in MPI 
    8771113      ii = 0 
    878       DO ji = 1, jpnij 
    879          IF ( njmppt(ji) == njmppmax   ) THEN 
     1114      DO ji = 1, jpni 
     1115         IF ( nfproc(ji) /= -1   ) THEN 
    8801116            ii=ii+1 
    881             nrank_north(ii)=ji-1 
     1117            nrank_north(ii)=nfproc(ji) 
    8821118         END IF 
    8831119      END DO 
     
    9041140      !!--------------------------------------------------------------------- 
    9051141      INTEGER                     , INTENT(in)    ::   ilen, itype 
    906       COMPLEX(wp), DIMENSION(ilen), INTENT(in)    ::   ydda 
    907       COMPLEX(wp), DIMENSION(ilen), INTENT(inout) ::   yddb 
    908       ! 
    909       REAL(wp) :: zerr, zt1, zt2    ! local work variables 
     1142      COMPLEX(dp), DIMENSION(ilen), INTENT(in)    ::   ydda 
     1143      COMPLEX(dp), DIMENSION(ilen), INTENT(inout) ::   yddb 
     1144      ! 
     1145      REAL(dp) :: zerr, zt1, zt2    ! local work variables 
    9101146      INTEGER  :: ji, ztmp           ! local scalar 
    9111147      !!--------------------------------------------------------------------- 
     
    10601296    LOGICAL,           INTENT(IN) :: ld_tic 
    10611297    LOGICAL, OPTIONAL, INTENT(IN) :: ld_global 
    1062     REAL(wp), DIMENSION(2), SAVE :: tic_wt 
    1063     REAL(wp),               SAVE :: tic_ct = 0._wp 
     1298    REAL(dp), DIMENSION(2), SAVE :: tic_wt 
     1299    REAL(dp),               SAVE :: tic_ct = 0._dp 
    10641300    INTEGER :: ii 
    10651301#if defined key_mpp_mpi 
     
    10741310    IF ( ld_tic ) THEN 
    10751311       tic_wt(ii) = MPI_Wtime()                                                    ! start count tic->tac (waiting time) 
    1076        IF ( tic_ct > 0.0_wp ) compute_time = compute_time + MPI_Wtime() - tic_ct   ! cumulate count tac->tic 
     1312       IF ( tic_ct > 0.0_dp ) compute_time = compute_time + MPI_Wtime() - tic_ct   ! cumulate count tac->tic 
    10771313    ELSE 
    10781314       waiting_time(ii) = waiting_time(ii) + MPI_Wtime() - tic_wt(ii)              ! cumulate count tic->tac 
     
    11121348      CHARACTER(len=*), INTENT(in   ), OPTIONAL ::        cd2, cd3, cd4, cd5 
    11131349      CHARACTER(len=*), INTENT(in   ), OPTIONAL ::   cd6, cd7, cd8, cd9, cd10 
     1350      ! 
     1351      CHARACTER(LEN=8) ::   clfmt            ! writing format 
     1352      INTEGER          ::   inum 
    11141353      !!---------------------------------------------------------------------- 
    11151354      ! 
    11161355      nstop = nstop + 1 
    11171356      ! 
    1118       ! force to open ocean.output file if not already opened 
    1119       IF( numout == 6 ) CALL ctl_opn( numout, 'ocean.output', 'APPEND', 'FORMATTED', 'SEQUENTIAL', -1, 6, .FALSE. ) 
     1357      IF( cd1 == 'STOP' .AND. narea /= 1 ) THEN    ! Immediate stop: add an arror message in 'ocean.output' file 
     1358         CALL ctl_opn( inum, 'ocean.output', 'APPEND', 'FORMATTED', 'SEQUENTIAL', -1, 6, .FALSE. ) 
     1359         WRITE(inum,*) 
     1360         WRITE(inum,*) ' ==>>>   Look for "E R R O R" messages in all existing *ocean.output* files' 
     1361         CLOSE(inum) 
     1362      ENDIF 
     1363      IF( numout == 6 ) THEN                       ! force to open ocean.output file if not already opened 
     1364         CALL ctl_opn( numout, 'ocean.output', 'REPLACE', 'FORMATTED', 'SEQUENTIAL', -1, -1, .FALSE., narea ) 
     1365      ENDIF 
    11201366      ! 
    11211367                            WRITE(numout,*) 
     
    11451391         WRITE(numout,*)  'huge E-R-R-O-R : immediate stop' 
    11461392         WRITE(numout,*)   
     1393         CALL FLUSH(numout) 
     1394         CALL SLEEP(60)   ! make sure that all output and abort files are written by all cores. 60s should be enough... 
    11471395         CALL mppstop( ld_abort = .true. ) 
    11481396      ENDIF 
     
    12071455      ! 
    12081456      CHARACTER(len=80) ::   clfile 
     1457      CHARACTER(LEN=10) ::   clfmt            ! writing format 
    12091458      INTEGER           ::   iost 
     1459      INTEGER           ::   idg              ! number of digits 
    12101460      !!---------------------------------------------------------------------- 
    12111461      ! 
     
    12141464      clfile = TRIM(cdfile) 
    12151465      IF( PRESENT( karea ) ) THEN 
    1216          IF( karea > 1 )   WRITE(clfile, "(a,'_',i4.4)") TRIM(clfile), karea-1 
     1466         IF( karea > 1 ) THEN 
     1467            ! Warning: jpnij is maybe not already defined when calling ctl_opn -> use mppsize instead of jpnij 
     1468            idg = MAX( INT(LOG10(REAL(MAX(1,mppsize-1),wp))) + 1, 4 )      ! how many digits to we need to write? min=4, max=9 
     1469            WRITE(clfmt, "('(a,a,i', i1, '.', i1, ')')") idg, idg          ! '(a,a,ix.x)' 
     1470            WRITE(clfile, clfmt) TRIM(clfile), '_', karea-1 
     1471         ENDIF 
    12171472      ENDIF 
    12181473#if defined key_agrif 
  • NEMO/branches/2020/dev_12905_xios_ancil/src/OCE/LBC/mpp_allreduce_generic.h90

    r10425 r13766  
    11!                          !==  IN: ptab is an array  ==! 
    22#   if defined REAL_TYPE 
    3 #      define ARRAY_TYPE(i)    REAL(wp)         , INTENT(inout) ::   ARRAY_IN(i) 
    4 #      define TMP_TYPE(i)      REAL(wp)         , ALLOCATABLE   ::   work(i) 
    5 #      define MPI_TYPE mpi_double_precision 
     3#      if defined SINGLE_PRECISION 
     4#         define ARRAY_TYPE(i)    REAL(sp)         , INTENT(inout) ::   ARRAY_IN(i) 
     5#         define TMP_TYPE(i)      REAL(sp)         , ALLOCATABLE   ::   work(i) 
     6#         define MPI_TYPE mpi_real 
     7#      else 
     8#         define ARRAY_TYPE(i)    REAL(dp)         , INTENT(inout) ::   ARRAY_IN(i) 
     9#         define TMP_TYPE(i)      REAL(dp)         , ALLOCATABLE   ::   work(i) 
     10#         define MPI_TYPE mpi_double_precision 
     11#      endif  
    612#   endif 
    713#   if defined INTEGER_TYPE 
     
    1117#   endif 
    1218#   if defined COMPLEX_TYPE 
    13 #      define ARRAY_TYPE(i)    COMPLEX          , INTENT(inout) ::   ARRAY_IN(i) 
    14 #      define TMP_TYPE(i)      COMPLEX          , ALLOCATABLE   ::   work(i) 
     19#      define ARRAY_TYPE(i)    COMPLEX(dp)       , INTENT(inout) ::   ARRAY_IN(i) 
     20#      define TMP_TYPE(i)      COMPLEX(dp)       , ALLOCATABLE   ::   work(i) 
    1521#      define MPI_TYPE mpi_double_complex 
    1622#   endif 
     
    7581   END SUBROUTINE ROUTINE_ALLREDUCE 
    7682 
     83#undef PRECISION 
    7784#undef ARRAY_TYPE 
    7885#undef ARRAY_IN 
  • NEMO/branches/2020/dev_12905_xios_ancil/src/OCE/LBC/mpp_lnk_generic.h90

    r11536 r13766  
    55#   define OPT_K(k)                 ,ipf 
    66#   if defined DIM_2d 
    7 #      define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_2D)                , INTENT(inout) ::   ptab(f) 
     7#      if defined SINGLE_PRECISION 
     8#         define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_2D_sp)                , INTENT(inout) ::   ptab(f) 
     9#      else 
     10#         define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_2D_dp)                , INTENT(inout) ::   ptab(f) 
     11#      endif 
    812#      define ARRAY_IN(i,j,k,l,f)      ptab(f)%pt2d(i,j) 
    913#      define K_SIZE(ptab)             1 
     
    1115#   endif 
    1216#   if defined DIM_3d 
    13 #      define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_3D)                , INTENT(inout) ::   ptab(f) 
     17#      if defined SINGLE_PRECISION 
     18#         define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_3D_sp)                , INTENT(inout) ::   ptab(f) 
     19#      else 
     20#         define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_3D_dp)                , INTENT(inout) ::   ptab(f) 
     21#      endif 
    1422#      define ARRAY_IN(i,j,k,l,f)      ptab(f)%pt3d(i,j,k) 
    1523#      define K_SIZE(ptab)             SIZE(ptab(1)%pt3d,3) 
     
    1725#   endif 
    1826#   if defined DIM_4d 
    19 #      define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_4D)                , INTENT(inout) ::   ptab(f) 
     27#      if defined SINGLE_PRECISION 
     28#         define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_4D_sp)                , INTENT(inout) ::   ptab(f) 
     29#      else 
     30#         define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_4D_dp)                , INTENT(inout) ::   ptab(f) 
     31#      endif 
    2032#      define ARRAY_IN(i,j,k,l,f)      ptab(f)%pt4d(i,j,k,l) 
    2133#      define K_SIZE(ptab)             SIZE(ptab(1)%pt4d,3) 
     
    2335#   endif 
    2436#else 
    25 #   define ARRAY_TYPE(i,j,k,l,f)    REAL(wp)                    , INTENT(inout) ::   ARRAY_IN(i,j,k,l,f) 
     37#   if defined SINGLE_PRECISION 
     38#      define ARRAY_TYPE(i,j,k,l,f)    REAL(sp)                    , INTENT(inout) ::   ARRAY_IN(i,j,k,l,f) 
     39#   else 
     40#      define ARRAY_TYPE(i,j,k,l,f)    REAL(dp)                    , INTENT(inout) ::   ARRAY_IN(i,j,k,l,f) 
     41#   endif 
    2642#   define NAT_IN(k)                cd_nat 
    2743#   define SGN_IN(k)                psgn 
     
    4561#endif 
    4662 
     63# if defined SINGLE_PRECISION 
     64#    define PRECISION sp 
     65#    define SENDROUTINE mppsend_sp 
     66#    define RECVROUTINE mpprecv_sp 
     67# else 
     68#    define PRECISION dp 
     69#    define SENDROUTINE mppsend_dp 
     70#    define RECVROUTINE mpprecv_dp 
     71# endif 
     72 
    4773#if defined MULTI 
    48    SUBROUTINE ROUTINE_LNK( cdname, ptab, cd_nat, psgn, kfld, kfillmode, pfillval, lsend, lrecv, ihlcom ) 
     74   SUBROUTINE ROUTINE_LNK( cdname, ptab, cd_nat, psgn, kfld, kfillmode, pfillval, lsend, lrecv ) 
    4975      INTEGER             , INTENT(in   ) ::   kfld        ! number of pt3d arrays 
    5076#else 
    51    SUBROUTINE ROUTINE_LNK( cdname, ptab, cd_nat, psgn      , kfillmode, pfillval, lsend, lrecv, ihlcom ) 
     77   SUBROUTINE ROUTINE_LNK( cdname, ptab, cd_nat, psgn      , kfillmode, pfillval, lsend, lrecv ) 
    5278#endif 
    5379      ARRAY_TYPE(:,:,:,:,:)                                        ! array or pointer of arrays on which the boundary condition is applied 
     
    5884      REAL(wp),             OPTIONAL, INTENT(in   ) ::   pfillval    ! background value (used at closed boundaries) 
    5985      LOGICAL, DIMENSION(4),OPTIONAL, INTENT(in   ) ::   lsend, lrecv  ! communication with other 4 proc 
    60       INTEGER              ,OPTIONAL, INTENT(in   ) ::   ihlcom        ! number of ranks and rows to be communicated 
    6186      ! 
    6287      INTEGER  ::    ji,  jj,  jk,  jl,  jf      ! dummy loop indices 
     
    6691      INTEGER  ::   ierr 
    6792      INTEGER  ::   ifill_we, ifill_ea, ifill_so, ifill_no 
    68       INTEGER  ::   ihl                          ! number of ranks and rows to be communicated  
    6993      REAL(wp) ::   zland 
    7094      INTEGER , DIMENSION(MPI_STATUS_SIZE)        ::   istat          ! for mpi_isend 
    71       REAL(wp), DIMENSION(:,:,:,:,:), ALLOCATABLE ::   zsnd_we, zrcv_we, zsnd_ea, zrcv_ea   ! east -west  & west - east  halos 
    72       REAL(wp), DIMENSION(:,:,:,:,:), ALLOCATABLE ::   zsnd_so, zrcv_so, zsnd_no, zrcv_no   ! north-south & south-north  halos 
     95      REAL(PRECISION), DIMENSION(:,:,:,:,:), ALLOCATABLE ::   zsnd_we, zrcv_we, zsnd_ea, zrcv_ea   ! east -west  & west - east  halos 
     96      REAL(PRECISION), DIMENSION(:,:,:,:,:), ALLOCATABLE ::   zsnd_so, zrcv_so, zsnd_no, zrcv_no   ! north-south & south-north  halos 
    7397      LOGICAL  ::   llsend_we, llsend_ea, llsend_no, llsend_so       ! communication send 
    7498      LOGICAL  ::   llrecv_we, llrecv_ea, llrecv_no, llrecv_so       ! communication receive  
     
    83107      ipl = L_SIZE(ptab)   ! 4th    - 
    84108      ipf = F_SIZE(ptab)   ! 5th    -      use in "multi" case (array of pointers) 
    85       ! 
    86       IF( PRESENT(ihlcom) ) THEN   ;   ihl = ihlcom 
    87       ELSE                         ;   ihl = 1 
    88       END IF 
    89109      ! 
    90110      IF( narea == 1 .AND. numcom == -1 ) CALL mpp_report( cdname, ipk, ipl, ipf, ld_lbc = .TRUE. ) 
     
    149169      ! 
    150170      ! Must exchange the whole column (from 1 to jpj) to get the corners if we have no south/north neighbourg 
    151       isize = ihl * jpj * ipk * ipl * ipf       
     171      isize = nn_hls * jpj * ipk * ipl * ipf       
    152172      ! 
    153173      ! Allocate local temporary arrays to be sent/received. Fill arrays to be sent 
    154       IF( llsend_we )   ALLOCATE( zsnd_we(ihl,jpj,ipk,ipl,ipf) ) 
    155       IF( llsend_ea )   ALLOCATE( zsnd_ea(ihl,jpj,ipk,ipl,ipf) ) 
    156       IF( llrecv_we )   ALLOCATE( zrcv_we(ihl,jpj,ipk,ipl,ipf) ) 
    157       IF( llrecv_ea )   ALLOCATE( zrcv_ea(ihl,jpj,ipk,ipl,ipf) ) 
     174      IF( llsend_we )   ALLOCATE( zsnd_we(nn_hls,jpj,ipk,ipl,ipf) ) 
     175      IF( llsend_ea )   ALLOCATE( zsnd_ea(nn_hls,jpj,ipk,ipl,ipf) ) 
     176      IF( llrecv_we )   ALLOCATE( zrcv_we(nn_hls,jpj,ipk,ipl,ipf) ) 
     177      IF( llrecv_ea )   ALLOCATE( zrcv_ea(nn_hls,jpj,ipk,ipl,ipf) ) 
    158178      ! 
    159179      IF( llsend_we ) THEN   ! copy western side of the inner mpi domain in local temporary array to be sent by MPI 
    160          ishift = ihl 
    161          DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, jpj   ;   DO ji = 1, ihl 
    162             zsnd_we(ji,jj,jk,jl,jf) = ARRAY_IN(ishift+ji,jj,jk,jl,jf)   ! ihl + 1 -> 2*ihl 
     180         ishift = nn_hls 
     181         DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, jpj   ;   DO ji = 1, nn_hls 
     182            zsnd_we(ji,jj,jk,jl,jf) = ARRAY_IN(ishift+ji,jj,jk,jl,jf)   ! nn_hls + 1 -> 2*nn_hls 
    163183         END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO 
    164184      ENDIF 
    165185      ! 
    166186      IF(llsend_ea  ) THEN   ! copy eastern side of the inner mpi domain in local temporary array to be sent by MPI 
    167          ishift = jpi - 2 * ihl 
    168          DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, jpj   ;   DO ji = 1, ihl 
    169             zsnd_ea(ji,jj,jk,jl,jf) = ARRAY_IN(ishift+ji,jj,jk,jl,jf)   ! jpi - 2*ihl + 1 -> jpi - ihl 
     187         ishift = jpi - 2 * nn_hls 
     188         DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, jpj   ;   DO ji = 1, nn_hls 
     189            zsnd_ea(ji,jj,jk,jl,jf) = ARRAY_IN(ishift+ji,jj,jk,jl,jf)   ! jpi - 2*nn_hls + 1 -> jpi - nn_hls 
    170190         END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO 
    171191      ENDIF 
     
    174194      ! 
    175195      ! non-blocking send of the western/eastern side using local temporary arrays 
    176       IF( llsend_we )   CALL mppsend( 1, zsnd_we(1,1,1,1,1), isize, nowe, ireq_we ) 
    177       IF( llsend_ea )   CALL mppsend( 2, zsnd_ea(1,1,1,1,1), isize, noea, ireq_ea ) 
     196      IF( llsend_we )   CALL SENDROUTINE( 1, zsnd_we(1,1,1,1,1), isize, nowe, ireq_we ) 
     197      IF( llsend_ea )   CALL SENDROUTINE( 2, zsnd_ea(1,1,1,1,1), isize, noea, ireq_ea ) 
    178198      ! blocking receive of the western/eastern halo in local temporary arrays 
    179       IF( llrecv_we )   CALL mpprecv( 2, zrcv_we(1,1,1,1,1), isize, nowe ) 
    180       IF( llrecv_ea )   CALL mpprecv( 1, zrcv_ea(1,1,1,1,1), isize, noea ) 
     199      IF( llrecv_we )   CALL RECVROUTINE( 2, zrcv_we(1,1,1,1,1), isize, nowe ) 
     200      IF( llrecv_ea )   CALL RECVROUTINE( 1, zrcv_ea(1,1,1,1,1), isize, noea ) 
    181201      ! 
    182202      IF( ln_timing ) CALL tic_tac(.FALSE.) 
     
    189209      ! 2.1 fill weastern halo 
    190210      ! ---------------------- 
    191       ! ishift = 0                         ! fill halo from ji = 1 to ihl 
     211      ! ishift = 0                         ! fill halo from ji = 1 to nn_hls 
    192212      SELECT CASE ( ifill_we ) 
    193213      CASE ( jpfillnothing )               ! no filling  
    194214      CASE ( jpfillmpi   )                 ! use data received by MPI  
    195          DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, jpj   ;   DO ji = 1, ihl 
    196             ARRAY_IN(ji,jj,jk,jl,jf) = zrcv_we(ji,jj,jk,jl,jf)   ! 1 -> ihl 
    197          END DO;   END DO   ;   END DO   ;   END DO   ;   END DO 
     215         DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, jpj   ;   DO ji = 1, nn_hls 
     216            ARRAY_IN(ji,jj,jk,jl,jf) = zrcv_we(ji,jj,jk,jl,jf)   ! 1 -> nn_hls 
     217         END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO 
    198218      CASE ( jpfillperio )                 ! use east-weast periodicity 
    199          ishift2 = jpi - 2 * ihl 
    200          DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, jpj   ;   DO ji = 1, ihl 
     219         ishift2 = jpi - 2 * nn_hls 
     220         DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, jpj   ;   DO ji = 1, nn_hls 
    201221            ARRAY_IN(ji,jj,jk,jl,jf) = ARRAY_IN(ishift2+ji,jj,jk,jl,jf) 
    202          END DO;   END DO   ;   END DO   ;   END DO   ;   END DO 
     222         END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO 
    203223      CASE ( jpfillcopy  )                 ! filling with inner domain values 
    204          DO jf = 1, ipf                               ! number of arrays to be treated 
    205             IF( .NOT. NAT_IN(jf) == 'F' ) THEN        ! do nothing for F point 
    206                DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, jpj   ;   DO ji = 1, ihl 
    207                   ARRAY_IN(ji,jj,jk,jl,jf) = ARRAY_IN(ihl+1,jj,jk,jl,jf) 
    208                END DO   ;   END DO   ;   END DO   ;   END DO 
    209             ENDIF 
    210          END DO 
     224         DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, jpj   ;   DO ji = 1, nn_hls 
     225            ARRAY_IN(ji,jj,jk,jl,jf) = ARRAY_IN(nn_hls+1,jj,jk,jl,jf) 
     226         END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO 
    211227      CASE ( jpfillcst   )                 ! filling with constant value 
    212          DO jf = 1, ipf                               ! number of arrays to be treated 
    213             IF( .NOT. NAT_IN(jf) == 'F' ) THEN        ! do nothing for F point 
    214                DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, jpj   ;   DO ji = 1, ihl 
    215                   ARRAY_IN(ji,jj,jk,jl,jf) = zland 
    216                END DO;   END DO   ;   END DO   ;   END DO 
    217             ENDIF 
    218          END DO 
     228         DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, jpj   ;   DO ji = 1, nn_hls 
     229            ARRAY_IN(ji,jj,jk,jl,jf) = zland 
     230         END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO 
    219231      END SELECT 
    220232      ! 
    221233      ! 2.2 fill eastern halo 
    222234      ! --------------------- 
    223       ishift = jpi - ihl                ! fill halo from ji = jpi-ihl+1 to jpi  
     235      ishift = jpi - nn_hls                ! fill halo from ji = jpi-nn_hls+1 to jpi  
    224236      SELECT CASE ( ifill_ea ) 
    225237      CASE ( jpfillnothing )               ! no filling  
    226238      CASE ( jpfillmpi   )                 ! use data received by MPI  
    227          DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, jpj   ;   DO ji = 1, ihl 
    228             ARRAY_IN(ishift+ji,jj,jk,jl,jf) = zrcv_ea(ji,jj,jk,jl,jf)   ! jpi - ihl + 1 -> jpi 
     239         DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, jpj   ;   DO ji = 1, nn_hls 
     240            ARRAY_IN(ishift+ji,jj,jk,jl,jf) = zrcv_ea(ji,jj,jk,jl,jf)   ! jpi - nn_hls + 1 -> jpi 
    229241         END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO 
    230242      CASE ( jpfillperio )                 ! use east-weast periodicity 
    231          ishift2 = ihl 
    232          DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, jpj   ;   DO ji = 1, ihl 
     243         ishift2 = nn_hls 
     244         DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, jpj   ;   DO ji = 1, nn_hls 
    233245            ARRAY_IN(ishift+ji,jj,jk,jl,jf) = ARRAY_IN(ishift2+ji,jj,jk,jl,jf) 
    234246         END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO 
    235247      CASE ( jpfillcopy  )                 ! filling with inner domain values 
    236          DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, jpj   ;   DO ji = 1, ihl 
     248         DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, jpj   ;   DO ji = 1, nn_hls 
    237249            ARRAY_IN(ishift+ji,jj,jk,jl,jf) = ARRAY_IN(ishift,jj,jk,jl,jf) 
    238250         END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO 
    239251      CASE ( jpfillcst   )                 ! filling with constant value 
    240          DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, jpj   ;   DO ji = 1, ihl 
     252         DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, jpj   ;   DO ji = 1, nn_hls 
    241253            ARRAY_IN(ishift+ji,jj,jk,jl,jf) = zland 
    242          END DO;   END DO   ;   END DO   ;   END DO   ;   END DO 
     254         END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO 
    243255      END SELECT 
    244256      ! 
     
    252264         ! 
    253265         SELECT CASE ( jpni ) 
    254          CASE ( 1 )     ;   CALL lbc_nfd( ptab, NAT_IN(:), SGN_IN(:) OPT_K(:) )   ! only 1 northern proc, no mpp 
    255          CASE DEFAULT   ;   CALL mpp_nfd( ptab, NAT_IN(:), SGN_IN(:) OPT_K(:) )   ! for all northern procs. 
     266         CASE ( 1 )     ;   CALL lbc_nfd( ptab, NAT_IN(:), SGN_IN(:)                  OPT_K(:) )   ! only 1 northern proc, no mpp 
     267         CASE DEFAULT   ;   CALL mpp_nfd( ptab, NAT_IN(:), SGN_IN(:), ifill_no, zland OPT_K(:) )   ! for all northern procs. 
    256268         END SELECT 
    257269         ! 
     
    264276      ! ---------------------------------------------------- ! 
    265277      ! 
    266       IF( llsend_so )   ALLOCATE( zsnd_so(jpi,ihl,ipk,ipl,ipf) ) 
    267       IF( llsend_no )   ALLOCATE( zsnd_no(jpi,ihl,ipk,ipl,ipf) ) 
    268       IF( llrecv_so )   ALLOCATE( zrcv_so(jpi,ihl,ipk,ipl,ipf) ) 
    269       IF( llrecv_no )   ALLOCATE( zrcv_no(jpi,ihl,ipk,ipl,ipf) ) 
    270       ! 
    271       isize = jpi * ihl * ipk * ipl * ipf       
     278      IF( llsend_so )   ALLOCATE( zsnd_so(jpi,nn_hls,ipk,ipl,ipf) ) 
     279      IF( llsend_no )   ALLOCATE( zsnd_no(jpi,nn_hls,ipk,ipl,ipf) ) 
     280      IF( llrecv_so )   ALLOCATE( zrcv_so(jpi,nn_hls,ipk,ipl,ipf) ) 
     281      IF( llrecv_no )   ALLOCATE( zrcv_no(jpi,nn_hls,ipk,ipl,ipf) ) 
     282      ! 
     283      isize = jpi * nn_hls * ipk * ipl * ipf       
    272284 
    273285      ! allocate local temporary arrays to be sent/received. Fill arrays to be sent 
    274286      IF( llsend_so ) THEN   ! copy sourhern side of the inner mpi domain in local temporary array to be sent by MPI 
    275          ishift = ihl 
    276          DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, ihl   ;   DO ji = 1, jpi 
    277             zsnd_so(ji,jj,jk,jl,jf) = ARRAY_IN(ji,ishift+jj,jk,jl,jf)   ! ihl+1 -> 2*ihl 
     287         ishift = nn_hls 
     288         DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, nn_hls   ;   DO ji = 1, jpi 
     289            zsnd_so(ji,jj,jk,jl,jf) = ARRAY_IN(ji,ishift+jj,jk,jl,jf)   ! nn_hls+1 -> 2*nn_hls 
    278290         END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO 
    279291      ENDIF 
    280292      ! 
    281293      IF( llsend_no ) THEN   ! copy eastern side of the inner mpi domain in local temporary array to be sent by MPI 
    282          ishift = jpj - 2 * ihl 
    283          DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, ihl   ;   DO ji = 1, jpi 
    284             zsnd_no(ji,jj,jk,jl,jf) = ARRAY_IN(ji,ishift+jj,jk,jl,jf)   ! jpj-2*ihl+1 -> jpj-ihl 
     294         ishift = jpj - 2 * nn_hls 
     295         DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, nn_hls   ;   DO ji = 1, jpi 
     296            zsnd_no(ji,jj,jk,jl,jf) = ARRAY_IN(ji,ishift+jj,jk,jl,jf)   ! jpj-2*nn_hls+1 -> jpj-nn_hls 
    285297         END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO 
    286298      ENDIF 
     
    289301      ! 
    290302      ! non-blocking send of the southern/northern side 
    291       IF( llsend_so )   CALL mppsend( 3, zsnd_so(1,1,1,1,1), isize, noso, ireq_so ) 
    292       IF( llsend_no )   CALL mppsend( 4, zsnd_no(1,1,1,1,1), isize, nono, ireq_no ) 
     303      IF( llsend_so )   CALL SENDROUTINE( 3, zsnd_so(1,1,1,1,1), isize, noso, ireq_so ) 
     304      IF( llsend_no )   CALL SENDROUTINE( 4, zsnd_no(1,1,1,1,1), isize, nono, ireq_no ) 
    293305      ! blocking receive of the southern/northern halo 
    294       IF( llrecv_so )   CALL mpprecv( 4, zrcv_so(1,1,1,1,1), isize, noso ) 
    295       IF( llrecv_no )   CALL mpprecv( 3, zrcv_no(1,1,1,1,1), isize, nono ) 
     306      IF( llrecv_so )   CALL RECVROUTINE( 4, zrcv_so(1,1,1,1,1), isize, noso ) 
     307      IF( llrecv_no )   CALL RECVROUTINE( 3, zrcv_no(1,1,1,1,1), isize, nono ) 
    296308      ! 
    297309      IF( ln_timing ) CALL tic_tac(.FALSE.) 
     
    303315      ! 5.1 fill southern halo 
    304316      ! ---------------------- 
    305       ! ishift = 0                         ! fill halo from jj = 1 to ihl 
     317      ! ishift = 0                         ! fill halo from jj = 1 to nn_hls 
    306318      SELECT CASE ( ifill_so ) 
    307319      CASE ( jpfillnothing )               ! no filling  
    308320      CASE ( jpfillmpi   )                 ! use data received by MPI  
    309          DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, ihl   ;   DO ji = 1, jpi 
    310             ARRAY_IN(ji,jj,jk,jl,jf) = zrcv_so(ji,jj,jk,jl,jf)   ! 1 -> ihl 
    311          END DO;   END DO   ;   END DO   ;   END DO   ;   END DO 
     321         DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, nn_hls   ;   DO ji = 1, jpi 
     322            ARRAY_IN(ji,jj,jk,jl,jf) = zrcv_so(ji,jj,jk,jl,jf)   ! 1 -> nn_hls 
     323         END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO 
    312324      CASE ( jpfillperio )                 ! use north-south periodicity 
    313          ishift2 = jpj - 2 * ihl 
    314          DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, ihl   ;   DO ji = 1, jpi 
     325         ishift2 = jpj - 2 * nn_hls 
     326         DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, nn_hls   ;   DO ji = 1, jpi 
    315327            ARRAY_IN(ji,jj,jk,jl,jf) = ARRAY_IN(ji,ishift2+jj,jk,jl,jf) 
    316          END DO;   END DO   ;   END DO   ;   END DO   ;   END DO 
     328         END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO 
    317329      CASE ( jpfillcopy  )                 ! filling with inner domain values 
    318          DO jf = 1, ipf                               ! number of arrays to be treated 
    319             IF( .NOT. NAT_IN(jf) == 'F' ) THEN        ! do nothing for F point 
    320                DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, ihl   ;   DO ji = 1, jpi 
    321                   ARRAY_IN(ji,jj,jk,jl,jf) = ARRAY_IN(ji,ihl+1,jk,jl,jf) 
    322                END DO   ;   END DO   ;   END DO   ;   END DO 
    323             ENDIF 
    324          END DO 
     330         DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, nn_hls   ;   DO ji = 1, jpi 
     331            ARRAY_IN(ji,jj,jk,jl,jf) = ARRAY_IN(ji,nn_hls+1,jk,jl,jf) 
     332         END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO 
    325333      CASE ( jpfillcst   )                 ! filling with constant value 
    326          DO jf = 1, ipf                               ! number of arrays to be treated 
    327             IF( .NOT. NAT_IN(jf) == 'F' ) THEN        ! do nothing for F point 
    328                DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, ihl   ;   DO ji = 1, jpi  
    329                   ARRAY_IN(ji,jj,jk,jl,jf) = zland 
    330                END DO;   END DO   ;   END DO   ;   END DO 
    331             ENDIF 
    332          END DO 
     334         DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, nn_hls   ;   DO ji = 1, jpi  
     335            ARRAY_IN(ji,jj,jk,jl,jf) = zland 
     336         END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO 
    333337      END SELECT 
    334338      ! 
    335339      ! 5.2 fill northern halo 
    336340      ! ---------------------- 
    337       ishift = jpj - ihl                ! fill halo from jj = jpj-ihl+1 to jpj  
     341      ishift = jpj - nn_hls                ! fill halo from jj = jpj-nn_hls+1 to jpj  
    338342      SELECT CASE ( ifill_no ) 
    339343      CASE ( jpfillnothing )               ! no filling  
    340344      CASE ( jpfillmpi   )                 ! use data received by MPI  
    341          DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, ihl   ;   DO ji = 1, jpi 
    342             ARRAY_IN(ji,ishift+jj,jk,jl,jf) = zrcv_no(ji,jj,jk,jl,jf)   ! jpj-ihl+1 -> jpj 
     345         DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, nn_hls   ;   DO ji = 1, jpi 
     346            ARRAY_IN(ji,ishift+jj,jk,jl,jf) = zrcv_no(ji,jj,jk,jl,jf)   ! jpj-nn_hls+1 -> jpj 
    343347         END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO 
    344348      CASE ( jpfillperio )                 ! use north-south periodicity 
    345          ishift2 = ihl 
    346          DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, ihl   ;   DO ji = 1, jpi 
     349         ishift2 = nn_hls 
     350         DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, nn_hls   ;   DO ji = 1, jpi 
    347351            ARRAY_IN(ji,ishift+jj,jk,jl,jf) = ARRAY_IN(ji,ishift2+jj,jk,jl,jf) 
    348          END DO;   END DO   ;   END DO   ;   END DO   ;   END DO 
     352         END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO 
    349353      CASE ( jpfillcopy  )                 ! filling with inner domain values 
    350          DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, ihl   ;   DO ji = 1, jpi 
     354         DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, nn_hls   ;   DO ji = 1, jpi 
    351355            ARRAY_IN(ji,ishift+jj,jk,jl,jf) = ARRAY_IN(ji,ishift,jk,jl,jf) 
    352          END DO;   END DO   ;   END DO   ;   END DO   ;   END DO 
     356         END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO 
    353357      CASE ( jpfillcst   )                 ! filling with constant value 
    354          DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, ihl   ;   DO ji = 1, jpi 
     358         DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, nn_hls   ;   DO ji = 1, jpi 
    355359            ARRAY_IN(ji,ishift+jj,jk,jl,jf) = zland 
    356          END DO;   END DO   ;   END DO   ;   END DO   ;   END DO 
     360         END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO 
    357361      END SELECT 
    358362      ! 
     
    384388      ! 
    385389   END SUBROUTINE ROUTINE_LNK 
    386  
     390#undef PRECISION 
     391#undef SENDROUTINE 
     392#undef RECVROUTINE 
    387393#undef ARRAY_TYPE 
    388394#undef NAT_IN 
  • NEMO/branches/2020/dev_12905_xios_ancil/src/OCE/LBC/mpp_loc_generic.h90

    r10716 r13766  
    11                          !==  IN: ptab is an array  ==! 
    2 #      define ARRAY_TYPE(i,j,k)    REAL(wp)        , INTENT(in   ) ::   ARRAY_IN(i,j,k) 
    3 #      define MASK_TYPE(i,j,k)     REAL(wp)        , INTENT(in   ) ::   MASK_IN(i,j,k) 
     2#   if defined SINGLE_PRECISION 
     3#      define ARRAY_TYPE(i,j,k)    REAL(sp)        , INTENT(in   ) ::   ARRAY_IN(i,j,k) 
     4#if defined key_mpp_mpi 
     5#      define MPI_TYPE MPI_2REAL 
     6#endif 
     7#      define PRECISION sp 
     8#   else 
     9#      define ARRAY_TYPE(i,j,k)    REAL(dp)        , INTENT(in   ) ::   ARRAY_IN(i,j,k) 
     10#if defined key_mpp_mpi 
     11#      define MPI_TYPE MPI_2DOUBLE_PRECISION 
     12#endif 
     13#      define PRECISION dp 
     14#   endif 
     15 
    416#   if defined DIM_2d 
    517#      define ARRAY_IN(i,j,k)   ptab(i,j) 
    6 #      define MASK_IN(i,j,k)    pmask(i,j) 
     18#      define MASK_IN(i,j,k)    ldmsk(i,j) 
    719#      define INDEX_TYPE(k)        INTEGER         , INTENT(  out) ::   kindex(2) 
    820#      define K_SIZE(ptab)      1 
     
    1022#   if defined DIM_3d 
    1123#      define ARRAY_IN(i,j,k)   ptab(i,j,k) 
    12 #      define MASK_IN(i,j,k)    pmask(i,j,k) 
     24#      define MASK_IN(i,j,k)    ldmsk(i,j,k) 
    1325#      define INDEX_TYPE(k)        INTEGER         , INTENT(  out) ::   kindex(3) 
    1426#      define K_SIZE(ptab)      SIZE(ptab,3) 
    1527#   endif 
    1628#   if defined OPERATION_MAXLOC 
    17 #      define MPI_OPERATION mpi_maxloc 
     29#      define MPI_OPERATION MPI_MAXLOC 
    1830#      define LOC_OPERATION MAXLOC 
    1931#      define ERRVAL -HUGE 
    2032#   endif 
    2133#   if defined OPERATION_MINLOC 
    22 #      define MPI_OPERATION mpi_minloc 
     34#      define MPI_OPERATION MPI_MINLOC 
    2335#      define LOC_OPERATION MINLOC 
    2436#      define ERRVAL HUGE 
    2537#   endif 
    2638 
    27    SUBROUTINE ROUTINE_LOC( cdname, ptab, pmask, pmin, kindex ) 
     39   SUBROUTINE ROUTINE_LOC( cdname, ptab, ldmsk, pmin, kindex, ldhalo ) 
    2840      !!---------------------------------------------------------------------- 
    29       CHARACTER(len=*), INTENT(in   ) ::   cdname  ! name of the calling subroutine 
     41      CHARACTER(len=*), INTENT(in    ) ::   cdname  ! name of the calling subroutine 
    3042      ARRAY_TYPE(:,:,:)                            ! array on which loctrans operation is applied 
    31       MASK_TYPE(:,:,:)                             ! local mask 
    32       REAL(wp)        , INTENT(  out) ::   pmin    ! Global minimum of ptab 
     43      LOGICAL          , INTENT(in   ) ::   MASK_IN(:,:,:)                     ! local mask 
     44      REAL(PRECISION)  , INTENT(  out) ::   pmin    ! Global minimum of ptab 
    3345      INDEX_TYPE(:)                                ! index of minimum in global frame 
    34 # if defined key_mpp_mpi 
     46      LOGICAL, OPTIONAL, INTENT(in   ) ::   ldhalo  ! If .false. (default) excludes halos in kindex  
    3547      ! 
    3648      INTEGER  ::   ierror, ii, idim 
    3749      INTEGER  ::   index0 
    38       REAL(wp) ::   zmin     ! local minimum 
    3950      INTEGER , DIMENSION(:), ALLOCATABLE  ::   ilocs 
    40       REAL(wp), DIMENSION(2,1) ::   zain, zaout 
     51      REAL(PRECISION) ::   zmin     ! local minimum 
     52      REAL(PRECISION), DIMENSION(2,1) ::   zain, zaout 
     53      LOGICAL  ::   llhalo 
    4154      !!----------------------------------------------------------------------- 
    4255      ! 
    4356      IF( narea == 1 .AND. numcom == -1 ) CALL mpp_report( cdname, ld_glb = .TRUE. ) 
    4457      ! 
     58      IF( PRESENT(ldhalo) ) THEN   ;   llhalo = ldhalo 
     59      ELSE                         ;   llhalo = .FALSE. 
     60      ENDIF 
     61      ! 
    4562      idim = SIZE(kindex) 
    4663      ! 
    47       IF ( ALL(MASK_IN(:,:,:) /= 1._wp) ) THEN 
    48          ! special case for land processors 
    49          zmin = ERRVAL(zmin) 
    50          index0 = 0 
    51       ELSE 
     64      IF ( ANY( MASK_IN(:,:,:) ) ) THEN   ! there is at least 1 valid point... 
     65         ! 
    5266         ALLOCATE ( ilocs(idim) ) 
    5367         ! 
    54          ilocs = LOC_OPERATION( ARRAY_IN(:,:,:) , mask= MASK_IN(:,:,:) == 1._wp ) 
     68         ilocs = LOC_OPERATION( ARRAY_IN(:,:,:) , mask= MASK_IN(:,:,:) ) 
    5569         zmin  = ARRAY_IN(ilocs(1),ilocs(2),ilocs(3)) 
    5670         ! 
    5771         kindex(1) = mig( ilocs(1) ) 
    58 #  if defined DIM_2d || defined DIM_3d    /* avoid warning when kindex has 1 element */ 
     72#if defined DIM_2d || defined DIM_3d    /* avoid warning when kindex has 1 element */ 
    5973         kindex(2) = mjg( ilocs(2) ) 
    60 #  endif 
    61 #  if defined DIM_3d                      /* avoid warning when kindex has 2 elements */ 
     74#endif 
     75#if defined DIM_3d                      /* avoid warning when kindex has 2 elements */ 
    6276         kindex(3) = ilocs(3) 
    63 #  endif 
     77#endif 
    6478         !  
    6579         DEALLOCATE (ilocs) 
    6680         ! 
    6781         index0 = kindex(1)-1   ! 1d index starting at 0 
    68 #  if defined DIM_2d || defined DIM_3d   /* avoid warning when kindex has 1 element */ 
     82#if defined DIM_2d || defined DIM_3d   /* avoid warning when kindex has 1 element */ 
    6983         index0 = index0 + jpiglo * (kindex(2)-1) 
    70 #  endif 
    71 #  if defined DIM_3d                     /* avoid warning when kindex has 2 elements */ 
     84#endif 
     85#if defined DIM_3d                     /* avoid warning when kindex has 2 elements */ 
    7286         index0 = index0 + jpiglo * jpjglo * (kindex(3)-1) 
    73 #  endif 
     87#endif 
     88      ELSE 
     89         ! special case for land processors 
     90         zmin = ERRVAL(zmin) 
     91         index0 = 0 
    7492      END IF 
     93      ! 
    7594      zain(1,:) = zmin 
    76       zain(2,:) = REAL(index0, wp) 
     95      zain(2,:) = REAL(index0, PRECISION) 
    7796      ! 
     97#if defined key_mpp_mpi 
    7898      IF( ln_timing ) CALL tic_tac(.TRUE., ld_global = .TRUE.) 
    79       CALL MPI_ALLREDUCE( zain, zaout, 1, MPI_2DOUBLE_PRECISION, MPI_OPERATION ,MPI_COMM_OCE, ierror) 
     99      CALL MPI_ALLREDUCE( zain, zaout, 1, MPI_TYPE, MPI_OPERATION ,MPI_COMM_OCE, ierror) 
    80100      IF( ln_timing ) CALL tic_tac(.FALSE., ld_global = .TRUE.) 
     101#else 
     102      zaout(:,:) = zain(:,:) 
     103#endif 
    81104      ! 
    82105      pmin      = zaout(1,1) 
    83106      index0    = NINT( zaout(2,1) ) 
    84 #  if defined DIM_3d                     /* avoid warning when kindex has 2 elements */ 
     107#if defined DIM_3d                     /* avoid warning when kindex has 2 elements */ 
    85108      kindex(3) = index0 / (jpiglo*jpjglo) 
    86109      index0    = index0 - kindex(3) * (jpiglo*jpjglo) 
    87 #  endif 
    88 #  if defined DIM_2d || defined DIM_3d   /* avoid warning when kindex has 1 element */ 
     110#endif 
     111#if defined DIM_2d || defined DIM_3d   /* avoid warning when kindex has 1 element */ 
    89112      kindex(2) = index0 / jpiglo 
    90113      index0 = index0 - kindex(2) * jpiglo 
    91 #  endif 
     114#endif 
    92115      kindex(1) = index0 
    93116      kindex(:) = kindex(:) + 1   ! start indices at 1 
    94 #else 
    95       kindex = 0 ; pmin = 0. 
    96       WRITE(*,*) 'ROUTINE_LOC: You should not have seen this print! error?' 
     117 
     118      IF( .NOT. llhalo ) THEN 
     119         kindex(1)  = kindex(1) - nn_hls 
     120#if defined DIM_2d || defined DIM_3d   /* avoid warning when kindex has 1 element */ 
     121         kindex(2)  = kindex(2) - nn_hls 
    97122#endif 
    98  
     123      ENDIF 
     124       
    99125   END SUBROUTINE ROUTINE_LOC 
    100126 
     127 
     128#undef PRECISION 
    101129#undef ARRAY_TYPE 
    102 #undef MAX_TYPE 
    103130#undef ARRAY_IN 
    104131#undef MASK_IN 
    105132#undef K_SIZE 
     133#if defined key_mpp_mpi 
     134#   undef MPI_TYPE 
     135#endif 
    106136#undef MPI_OPERATION 
    107137#undef LOC_OPERATION 
  • NEMO/branches/2020/dev_12905_xios_ancil/src/OCE/LBC/mpp_nfd_generic.h90

    r11536 r13766  
    55#   define LBC_ARG                  (jf) 
    66#   if defined DIM_2d 
    7 #      define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_2D)     , INTENT(inout) ::   ptab(f) 
     7#      if defined SINGLE_PRECISION 
     8#         define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_2D_sp)     , INTENT(inout) ::   ptab(f) 
     9#      else 
     10#         define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_2D_dp)     , INTENT(inout) ::   ptab(f) 
     11#      endif 
    812#      define ARRAY_IN(i,j,k,l,f)      ptab(f)%pt2d(i,j) 
    913#      define K_SIZE(ptab)             1 
     
    1115#   endif 
    1216#   if defined DIM_3d 
    13 #      define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_3D)     , INTENT(inout) ::   ptab(f) 
     17#      if defined SINGLE_PRECISION 
     18#         define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_3D_sp)     , INTENT(inout) ::   ptab(f) 
     19#      else 
     20#         define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_3D_dp)     , INTENT(inout) ::   ptab(f) 
     21#      endif 
    1422#      define ARRAY_IN(i,j,k,l,f)      ptab(f)%pt3d(i,j,k) 
    1523#      define K_SIZE(ptab)             SIZE(ptab(1)%pt3d,3) 
     
    1725#   endif 
    1826#   if defined DIM_4d 
    19 #      define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_4D)     , INTENT(inout) ::   ptab(f) 
     27#      if defined SINGLE_PRECISION 
     28#         define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_4D_sp)     , INTENT(inout) ::   ptab(f) 
     29#      else 
     30#         define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_4D_dp)     , INTENT(inout) ::   ptab(f) 
     31#      endif 
    2032#      define ARRAY_IN(i,j,k,l,f)      ptab(f)%pt4d(i,j,k,l) 
    2133#      define K_SIZE(ptab)             SIZE(ptab(1)%pt4d,3) 
     
    2436#else 
    2537!                          !==  IN: ptab is an array  ==! 
    26 #   define ARRAY_TYPE(i,j,k,l,f)    REAL(wp)         , INTENT(inout) ::   ARRAY_IN(i,j,k,l,f) 
     38#   if defined SINGLE_PRECISION 
     39#      define ARRAY_TYPE(i,j,k,l,f)    REAL(sp)         , INTENT(inout) ::   ARRAY_IN(i,j,k,l,f) 
     40#   else 
     41#      define ARRAY_TYPE(i,j,k,l,f)    REAL(dp)         , INTENT(inout) ::   ARRAY_IN(i,j,k,l,f) 
     42#   endif 
    2743#   define NAT_IN(k)                cd_nat 
    2844#   define SGN_IN(k)                psgn 
     
    4662#endif 
    4763 
    48    SUBROUTINE ROUTINE_NFD( ptab, cd_nat, psgn, kfld ) 
     64# if defined SINGLE_PRECISION 
     65#    define PRECISION sp 
     66#    define SENDROUTINE mppsend_sp 
     67#    define RECVROUTINE mpprecv_sp 
     68#    define MPI_TYPE MPI_REAL 
     69#    define HUGEVAL(x)   HUGE(x/**/_sp) 
     70# else 
     71#    define PRECISION dp 
     72#    define SENDROUTINE mppsend_dp 
     73#    define RECVROUTINE mpprecv_dp 
     74#    define MPI_TYPE MPI_DOUBLE_PRECISION 
     75#    define HUGEVAL(x)   HUGE(x/**/_dp) 
     76# endif 
     77 
     78   SUBROUTINE ROUTINE_NFD( ptab, cd_nat, psgn, kfillmode, pfillval, kfld ) 
    4979      !!---------------------------------------------------------------------- 
    5080      ARRAY_TYPE(:,:,:,:,:)   ! array or pointer of arrays on which the boundary condition is applied 
    5181      CHARACTER(len=1) , INTENT(in   ) ::   NAT_IN(:)   ! nature of array grid-points 
    5282      REAL(wp)         , INTENT(in   ) ::   SGN_IN(:)   ! sign used across the north fold boundary 
     83      INTEGER          , INTENT(in   ) ::   kfillmode   ! filling method for halo over land  
     84      REAL(wp)         , INTENT(in   ) ::   pfillval    ! background value (used at closed boundaries) 
    5385      INTEGER, OPTIONAL, INTENT(in   ) ::   kfld        ! number of pt3d arrays 
    5486      ! 
     87      LOGICAL  ::   ll_add_line 
    5588      INTEGER  ::   ji,  jj,  jk,  jl, jh, jf, jr   ! dummy loop indices 
    56       INTEGER  ::   ipi, ipj, ipk, ipl, ipf         ! dimension of the input array 
     89      INTEGER  ::   ipi, ipj, ipj2, ipk, ipl, ipf   ! dimension of the input array 
    5790      INTEGER  ::   imigr, iihom, ijhom             ! local integers 
    58       INTEGER  ::   ierr, ibuffsize, ilci, ildi, ilei, iilb 
    59       INTEGER  ::   ij, iproc 
     91      INTEGER  ::   ierr, ibuffsize, iis0, iie0, impp 
     92      INTEGER  ::   ii1, ii2, ij1, ij2 
     93      INTEGER  ::   ipimax, i0max 
     94      INTEGER  ::   ij, iproc, ipni, ijnr 
    6095      INTEGER, DIMENSION (jpmaxngh)       ::   ml_req_nf   ! for mpi_isend when avoiding mpi_allgather 
    6196      INTEGER                             ::   ml_err      ! for mpi_isend when avoiding mpi_allgather 
    6297      INTEGER, DIMENSION(MPI_STATUS_SIZE) ::   ml_stat     ! for mpi_isend when avoiding mpi_allgather 
    6398      !                                                    ! Workspace for message transfers avoiding mpi_allgather 
    64       INTEGER                             ::   ipf_j       ! sum of lines for all multi fields 
    65       INTEGER                             ::   js          ! counter 
    66       INTEGER, DIMENSION(:,:),          ALLOCATABLE ::   jj_s  ! position of sent lines 
    67       INTEGER, DIMENSION(:),            ALLOCATABLE ::   ipj_s ! number of sent lines 
    68       REAL(wp), DIMENSION(:,:,:)      , ALLOCATABLE ::   ztabl 
    69       REAL(wp), DIMENSION(:,:,:,:,:)  , ALLOCATABLE ::   ztab, ztabr 
    70       REAL(wp), DIMENSION(:,:,:,:,:)  , ALLOCATABLE ::   znorthloc, zfoldwk       
    71       REAL(wp), DIMENSION(:,:,:,:,:,:), ALLOCATABLE ::   znorthgloio 
     99      INTEGER                             ::   ipj_b       ! sum of lines for all multi fields 
     100      INTEGER                             ::   i012        ! 0, 1 or 2 
     101      INTEGER , DIMENSION(:,:)        , ALLOCATABLE ::   jj_s  ! position of sent lines 
     102      INTEGER , DIMENSION(:,:)        , ALLOCATABLE ::   jj_b  ! position of buffer lines 
     103      INTEGER , DIMENSION(:)          , ALLOCATABLE ::   ipj_s ! number of sent lines 
     104      REAL(PRECISION), DIMENSION(:,:,:,:)    , ALLOCATABLE ::   ztabb, ztabr, ztabw  ! buffer, receive and work arrays 
     105      REAL(PRECISION), DIMENSION(:,:,:,:,:)  , ALLOCATABLE ::   ztabglo, znorthloc 
     106      REAL(PRECISION), DIMENSION(:,:,:,:,:,:), ALLOCATABLE ::   znorthglo 
    72107      !!---------------------------------------------------------------------- 
    73108      ! 
     
    78113      IF( l_north_nogather ) THEN      !==  no allgather exchanges  ==! 
    79114 
    80          ALLOCATE(ipj_s(ipf)) 
    81  
    82          ipj      = 2            ! Max 2nd dimension of message transfers (last two j-line only) 
    83          ipj_s(:) = 1            ! Real 2nd dimension of message transfers (depending on perf requirement) 
    84                                  ! by default, only one line is exchanged 
    85  
    86          ALLOCATE( jj_s(ipf,2) ) 
    87  
    88          ! re-define number of exchanged lines : 
    89          !  must be two during the first two time steps 
    90          !  to correct possible incoherent values on North fold lines from restart  
    91  
     115         !   ---   define number of exchanged lines   --- 
     116         ! 
     117         ! In theory we should exchange only nn_hls lines. 
     118         ! 
     119         ! However, some other points are duplicated in the north pole folding: 
     120         !  - jperio=[34], grid=T : half of the last line (jpiglo/2+2:jpiglo-nn_hls) 
     121         !  - jperio=[34], grid=U : half of the last line (jpiglo/2+1:jpiglo-nn_hls) 
     122         !  - jperio=[34], grid=V : all the last line nn_hls+1 and (nn_hls+2:jpiglo-nn_hls) 
     123         !  - jperio=[34], grid=F : all the last line (nn_hls+1:jpiglo-nn_hls) 
     124         !  - jperio=[56], grid=T : 2 points of the last line (jpiglo/2+1 and jpglo-nn_hls) 
     125         !  - jperio=[56], grid=U : no points are duplicated 
     126         !  - jperio=[56], grid=V : half of the last line (jpiglo/2+1:jpiglo-nn_hls) 
     127         !  - jperio=[56], grid=F : half of the last line (jpiglo/2+1:jpiglo-nn_hls-1) 
     128         ! The order of the calculations may differ for these duplicated points (as, for example jj+1 becomes jj-1) 
     129         ! This explain why these duplicated points may have different values even if they are at the exact same location. 
     130         ! In consequence, we may want to force the folding on these points by setting l_full_nf_update = .TRUE. 
     131         ! This is slightly slower but necessary to avoid different values on identical grid points!! 
     132         ! 
    92133         !!!!!!!!!           temporary switch off this optimisation ==> force TRUE           !!!!!!!! 
    93134         !!!!!!!!!  needed to get the same results without agrif and with agrif and no zoom  !!!!!!!! 
    94135         !!!!!!!!!                    I don't know why we must do that...                    !!!!!!!! 
    95136         l_full_nf_update = .TRUE. 
    96  
    97          ! Two lines update (slower but necessary to avoid different values ion identical grid points 
    98          IF ( l_full_nf_update .OR.                          &    ! if coupling fields 
    99               ( ncom_stp == nit000 .AND. .NOT. ln_rstart ) ) &    ! at first time step, if not restart 
    100             ipj_s(:) = 2 
     137         ! also force it if not restart during the first 2 steps (leap frog?) 
     138         ll_add_line = l_full_nf_update .OR. ( ncom_stp <= nit000+1 .AND. .NOT. ln_rstart ) 
     139          
     140         ALLOCATE(ipj_s(ipf))                ! how many lines do we exchange? 
     141         IF( ll_add_line ) THEN 
     142            DO jf = 1, ipf                      ! Loop over the number of arrays to be processed 
     143               ipj_s(jf) = nn_hls + COUNT( (/ npolj == 3 .OR. npolj == 4 .OR. NAT_IN(jf) == 'V' .OR. NAT_IN(jf) == 'F' /) )  
     144            END DO 
     145         ELSE 
     146            ipj_s(:) = nn_hls 
     147         ENDIF 
     148          
     149         ipj   = MAXVAL(ipj_s(:))            ! Max 2nd dimension of message transfers 
     150         ipj_b = SUM(   ipj_s(:))            ! Total number of lines to be exchanged 
     151         ALLOCATE( jj_s(ipj, ipf), jj_b(ipj, ipf) ) 
    101152 
    102153         ! Index of modifying lines in input 
     154         ij1 = 0 
    103155         DO jf = 1, ipf                      ! Loop over the number of arrays to be processed 
    104156            ! 
    105157            SELECT CASE ( npolj ) 
    106             ! 
    107158            CASE ( 3, 4 )                       ! *  North fold  T-point pivot 
    108                ! 
    109159               SELECT CASE ( NAT_IN(jf) ) 
    110                ! 
    111                CASE ( 'T' , 'W' ,'U' )                            ! T-, U-, W-point 
    112                   jj_s(jf,1) = nlcj - 2 ;  jj_s(jf,2) = nlcj - 1 
    113                CASE ( 'V' , 'F' )                                 ! V-, F-point 
    114                   jj_s(jf,1) = nlcj - 3 ;  jj_s(jf,2) = nlcj - 2 
     160               CASE ( 'T', 'W', 'U' )   ;   i012 = 1   ! T-, U-, W-point 
     161               CASE ( 'V', 'F'      )   ;   i012 = 2   ! V-, F-point 
    115162               END SELECT 
    116             ! 
    117             CASE ( 5, 6 )                        ! *  North fold  F-point pivot 
     163            CASE ( 5, 6 )                       ! *  North fold  F-point pivot 
    118164               SELECT CASE ( NAT_IN(jf) ) 
    119                ! 
    120                CASE ( 'T' , 'W' ,'U' )                            ! T-, U-, W-point 
    121                   jj_s(jf,1) = nlcj - 1       
    122                   ipj_s(jf) = 1                  ! need only one line anyway 
    123                CASE ( 'V' , 'F' )                                 ! V-, F-point 
    124                   jj_s(jf,1) = nlcj - 2 ;  jj_s(jf,2) = nlcj - 1 
     165               CASE ( 'T', 'W', 'U' )   ;   i012 = 0   ! T-, U-, W-point 
     166               CASE ( 'V', 'F'      )   ;   i012 = 1   ! V-, F-point 
    125167               END SELECT 
    126             ! 
    127168            END SELECT 
    128             ! 
    129          ENDDO 
    130          !  
    131          ipf_j = sum (ipj_s(:))      ! Total number of lines to be exchanged 
    132          ! 
    133          ALLOCATE( znorthloc(jpimax,ipf_j,ipk,ipl,1) ) 
    134          ! 
    135          js = 0 
    136          DO jf = 1, ipf                      ! Loop over the number of arrays to be processed 
     169               ! 
    137170            DO jj = 1, ipj_s(jf) 
    138                js = js + 1 
    139                DO jl = 1, ipl 
    140                   DO jk = 1, ipk 
    141                      znorthloc(1:jpi,js,jk,jl,1) = ARRAY_IN(1:jpi,jj_s(jf,jj),jk,jl,jf) 
    142                   END DO 
    143                END DO 
     171               ij1 = ij1 + 1 
     172               jj_b(jj,jf) = ij1 
     173               jj_s(jj,jf) = jpj - 2*nn_hls + jj - i012 
    144174            END DO 
     175            ! 
    145176         END DO 
    146177         ! 
    147          ibuffsize = jpimax * ipf_j * ipk * ipl 
    148          ! 
    149          ALLOCATE( zfoldwk(jpimax,ipf_j,ipk,ipl,1) ) 
    150          ALLOCATE( ztabr(jpimax*jpmaxngh,ipj,ipk,ipl,ipf) )  
    151          ! when some processors of the north fold are suppressed,  
    152          ! values of ztab* arrays corresponding to these suppressed domain won't be defined  
    153          ! and we need a default definition to 0. 
    154          ! a better test should be: a testing if "suppressed land-processors" belongs to the north-pole folding 
    155          IF ( jpni*jpnj /= jpnij ) ztabr(:,:,:,:,:) = 0._wp 
     178         ALLOCATE( ztabb(jpimax,ipj_b,ipk,ipl) )   ! store all the data to be sent in a buffer array 
     179         ibuffsize = jpimax * ipj_b * ipk * ipl 
     180         ! 
     181         DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk 
     182            DO jj = 1, ipj_s(jf) 
     183               ij1 = jj_b(jj,jf) 
     184               ij2 = jj_s(jj,jf) 
     185               DO ji = 1, jpi 
     186                  ztabb(ji,ij1,jk,jl) = ARRAY_IN(ji,ij2,jk,jl,jf) 
     187               END DO 
     188               DO ji = jpi+1, jpimax 
     189                  ztabb(ji,ij1,jk,jl) = HUGEVAL(0.)   ! avoid sending uninitialized values (make sure we don't use it) 
     190               END DO 
     191            END DO 
     192         END DO   ;   END DO   ;   END DO 
    156193         ! 
    157194         ! start waiting time measurement 
    158195         IF( ln_timing ) CALL tic_tac(.TRUE.) 
    159196         ! 
     197         ! send the data as soon as possible 
    160198         DO jr = 1, nsndto 
    161             IF( nfipproc(isendto(jr),jpnj) /= narea-1 .AND. nfipproc(isendto(jr),jpnj) /= -1 ) THEN 
    162                CALL mppsend( 5, znorthloc, ibuffsize, nfipproc(isendto(jr),jpnj), ml_req_nf(jr) ) 
     199            iproc = nfproc(isendto(jr)) 
     200            IF( iproc /= narea-1 .AND. iproc /= -1 ) THEN 
     201               CALL SENDROUTINE( 5, ztabb, ibuffsize, iproc, ml_req_nf(jr) ) 
    163202            ENDIF 
    164203         END DO 
    165204         ! 
     205         ipimax = jpimax * jpmaxngh 
     206         ALLOCATE( ztabw(jpimax,ipj_b,ipk,ipl), ztabr(ipimax,ipj_b,ipk,ipl) )  
     207         ! 
     208         DO jr = 1, nsndto 
     209            ! 
     210            ipni  = isendto(jr) 
     211            iproc = nfproc(ipni) 
     212            ipi   = nfjpi (ipni) 
     213            ! 
     214            IF( ipni ==   1  ) THEN   ;   iis0 =   1            ! domain  left side: as e-w comm already done -> from 1st column 
     215            ELSE                      ;   iis0 =   1 + nn_hls   ! default: -> from inner domain  
     216            ENDIF 
     217            IF( ipni == jpni ) THEN   ;   iie0 = ipi            ! domain right side: as e-w comm already done -> until last column 
     218            ELSE                      ;   iie0 = ipi - nn_hls   ! default: -> until inner domain  
     219            ENDIF 
     220            impp = nfimpp(ipni) - nfimpp(isendto(1)) 
     221            ! 
     222            IF(           iproc == -1 ) THEN   ! No neighbour (land proc that was suppressed) 
     223               ! 
     224               SELECT CASE ( kfillmode ) 
     225               CASE ( jpfillnothing )               ! no filling  
     226               CASE ( jpfillcopy    )               ! filling with inner domain values 
     227                  DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk 
     228                     DO jj = 1, ipj_s(jf) 
     229                        ij1 = jj_b(jj,jf) 
     230                        ij2 = jj_s(jj,jf) 
     231                        DO ji = iis0, iie0 
     232                           ztabr(impp+ji,ij1,jk,jl) = ARRAY_IN(Nis0,ij2,jk,jl,jf)   ! chose to take the 1st iner domain point 
     233                        END DO 
     234                     END DO 
     235                  END DO   ;   END DO   ;   END DO 
     236               CASE ( jpfillcst     )               ! filling with constant value 
     237                  DO jl = 1, ipl   ;   DO jk = 1, ipk 
     238                     DO jj = 1, ipj_b 
     239                        DO ji = iis0, iie0 
     240                           ztabr(impp+ji,jj,jk,jl) = pfillval 
     241                        END DO 
     242                     END DO 
     243                  END DO   ;   END DO 
     244               END SELECT 
     245               ! 
     246            ELSE IF( iproc == narea-1 ) THEN   ! get data from myself! 
     247               ! 
     248               DO jf = 1, ipf   ;   DO jl = 1, ipl  ;   DO jk = 1, ipk 
     249                  DO jj = 1, ipj_s(jf) 
     250                     ij1 = jj_b(jj,jf) 
     251                     ij2 = jj_s(jj,jf) 
     252                     DO ji = iis0, iie0 
     253                        ztabr(impp+ji,ij1,jk,jl) = ARRAY_IN(ji,ij2,jk,jl,jf) 
     254                     END DO 
     255                  END DO 
     256               END DO   ;   END DO   ;   END DO 
     257               ! 
     258            ELSE                               ! get data from a neighbour trough communication 
     259               !   
     260               CALL RECVROUTINE(5, ztabw, ibuffsize, iproc) 
     261               DO jl = 1, ipl   ;   DO jk = 1, ipk 
     262                  DO jj = 1, ipj_b 
     263                     DO ji = iis0, iie0 
     264                        ztabr(impp+ji,jj,jk,jl) = ztabw(ji,jj,jk,jl) 
     265                     END DO 
     266                  END DO 
     267               END DO   ;   END DO 
     268                
     269            ENDIF 
     270            ! 
     271         END DO   ! nsndto 
     272         ! 
     273         IF( ln_timing ) CALL tic_tac(.FALSE.) 
     274         ! 
     275         ! North fold boundary condition 
     276         ! 
     277         DO jf = 1, ipf 
     278            ij1 = jj_b(       1 ,jf) 
     279            ij2 = jj_b(ipj_s(jf),jf) 
     280            CALL lbc_nfd_nogather( ARRAY_IN(:,:,:,:,jf), ztabr(:,ij1:ij2,:,:), cd_nat LBC_ARG, psgn LBC_ARG ) 
     281         END DO 
     282         ! 
     283         DEALLOCATE( ztabr, ztabw, jj_s, jj_b, ipj_s ) 
     284         ! 
    166285         DO jr = 1,nsndto 
    167             iproc = nfipproc(isendto(jr),jpnj) 
    168             IF(iproc /= -1) THEN 
    169                iilb = nimppt(iproc+1) 
    170                ilci = nlcit (iproc+1) 
    171                ildi = nldit (iproc+1) 
    172                ilei = nleit (iproc+1) 
    173                IF( iilb            ==      1 )   ildi = 1      ! e-w boundary already done -> force to take 1st column 
    174                IF( iilb + ilci - 1 == jpiglo )   ilei = ilci   ! e-w boundary already done -> force to take last column 
    175                iilb = nfiimpp(isendto(jr),jpnj) - nfiimpp(isendto(1),jpnj) 
    176             ENDIF 
     286            iproc = nfproc(isendto(jr)) 
    177287            IF( iproc /= narea-1 .AND. iproc /= -1 ) THEN 
    178                CALL mpprecv(5, zfoldwk, ibuffsize, iproc) 
    179                js = 0 
    180                DO jf = 1, ipf ; DO jj = 1, ipj_s(jf) 
    181                   js = js + 1 
    182                   DO jl = 1, ipl 
    183                      DO jk = 1, ipk 
    184                         DO ji = ildi, ilei 
    185                            ztabr(iilb+ji,jj,jk,jl,jf) = zfoldwk(ji,js,jk,jl,1) 
    186                         END DO 
    187                      END DO 
    188                   END DO 
    189                END DO; END DO 
    190             ELSE IF( iproc == narea-1 ) THEN 
    191                DO jf = 1, ipf ; DO jj = 1, ipj_s(jf) 
    192                   DO jl = 1, ipl 
    193                      DO jk = 1, ipk 
    194                         DO ji = ildi, ilei 
    195                            ztabr(iilb+ji,jj,jk,jl,jf) = ARRAY_IN(ji,jj_s(jf,jj),jk,jl,jf) 
    196                         END DO 
    197                      END DO 
    198                   END DO 
    199                END DO; END DO 
     288               CALL mpi_wait( ml_req_nf(jr), ml_stat, ml_err )   ! put the wait at the very end just before the deallocate 
    200289            ENDIF 
    201290         END DO 
    202          DO jr = 1,nsndto 
    203             IF( nfipproc(isendto(jr),jpnj) /= narea-1 .AND. nfipproc(isendto(jr),jpnj) /= -1 ) THEN 
    204                CALL mpi_wait( ml_req_nf(jr), ml_stat, ml_err ) 
    205             ENDIF 
    206          END DO 
    207          ! 
    208          IF( ln_timing ) CALL tic_tac(.FALSE.) 
    209          ! 
    210          ! North fold boundary condition 
    211          ! 
    212          DO jf = 1, ipf 
    213             CALL lbc_nfd_nogather( ARRAY_IN(:,:,:,:,jf), ztabr(:,1:ipj_s(jf),:,:,jf), cd_nat LBC_ARG, psgn LBC_ARG ) 
    214          END DO 
    215          ! 
    216          DEALLOCATE( zfoldwk, ztabr, jj_s, ipj_s ) 
     291         DEALLOCATE( ztabb ) 
    217292         ! 
    218293      ELSE                             !==  allgather exchanges  ==! 
    219294         ! 
    220          ipj   = 4            ! 2nd dimension of message transfers (last j-lines) 
    221          ! 
    222          ALLOCATE( znorthloc(jpimax,ipj,ipk,ipl,ipf) ) 
    223          ! 
    224          DO jf = 1, ipf                ! put in znorthloc the last ipj j-lines of ptab 
    225             DO jl = 1, ipl 
    226                DO jk = 1, ipk 
    227                   DO jj = nlcj - ipj +1, nlcj 
    228                      ij = jj - nlcj + ipj 
    229                      znorthloc(1:jpi,ij,jk,jl,jf) = ARRAY_IN(1:jpi,jj,jk,jl,jf) 
    230                   END DO 
     295         ! how many lines do we exchange at max? -> ipj    (no further optimizations in this case...) 
     296         ipj =      nn_hls + 2 
     297         ! how many lines do we     need at max? -> ipj2   (no further optimizations in this case...) 
     298         ipj2 = 2 * nn_hls + 2 
     299         ! 
     300         i0max = jpimax - 2 * nn_hls 
     301         ibuffsize = i0max * ipj * ipk * ipl * ipf 
     302         ALLOCATE( znorthloc(i0max,ipj,ipk,ipl,ipf), znorthglo(i0max,ipj,ipk,ipl,ipf,ndim_rank_north) ) 
     303         ! 
     304         DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk               ! put in znorthloc ipj j-lines of ptab 
     305            DO jj = 1, ipj 
     306               ij2 = jpj - ipj2 + jj                        ! the first ipj lines of the last ipj2 lines 
     307               DO ji = 1, Ni_0 
     308                  ii2 = Nis0 - 1 + ji                       ! inner domain: Nis0 to Nie0 
     309                  znorthloc(ji,jj,jk,jl,jf) = ARRAY_IN(ii2,ij2,jk,jl,jf) 
     310               END DO 
     311               DO ji = Ni_0+1, i0max 
     312                  znorthloc(ji,jj,jk,jl,jf) = HUGEVAL(0.)   ! avoid sending uninitialized values (make sure we don't use it) 
    231313               END DO 
    232314            END DO 
    233          END DO 
    234          ! 
    235          ibuffsize = jpimax * ipj * ipk * ipl * ipf 
    236          ! 
    237          ALLOCATE( ztab       (jpiglo,ipj,ipk,ipl,ipf     ) ) 
    238          ALLOCATE( znorthgloio(jpimax,ipj,ipk,ipl,ipf,jpni) ) 
    239          ! 
    240          ! when some processors of the north fold are suppressed, 
    241          ! values of ztab* arrays corresponding to these suppressed domain won't be defined 
    242          ! and we need a default definition to 0. 
    243          ! a better test should be: a testing if "suppressed land-processors" belongs to the north-pole folding 
    244          IF ( jpni*jpnj /= jpnij ) ztab(:,:,:,:,:) = 0._wp 
     315         END DO   ;   END DO   ;   END DO 
    245316         ! 
    246317         ! start waiting time measurement 
    247318         IF( ln_timing ) CALL tic_tac(.TRUE.) 
    248          CALL MPI_ALLGATHER( znorthloc  , ibuffsize, MPI_DOUBLE_PRECISION,                & 
    249             &                znorthgloio, ibuffsize, MPI_DOUBLE_PRECISION, ncomm_north, ierr ) 
    250          ! 
     319#if defined key_mpp_mpi 
     320         CALL MPI_ALLGATHER( znorthloc, ibuffsize, MPI_TYPE, znorthglo, ibuffsize, MPI_TYPE, ncomm_north, ierr ) 
     321#endif 
    251322         ! stop waiting time measurement 
    252323         IF( ln_timing ) CALL tic_tac(.FALSE.) 
    253          ! 
    254          DO jr = 1, ndim_rank_north         ! recover the global north array 
    255             iproc = nrank_north(jr) + 1 
    256             iilb  = nimppt(iproc) 
    257             ilci  = nlcit (iproc) 
    258             ildi  = nldit (iproc) 
    259             ilei  = nleit (iproc) 
    260             IF( iilb            ==      1 )   ildi = 1      ! e-w boundary already done -> force to take 1st column 
    261             IF( iilb + ilci - 1 == jpiglo )   ilei = ilci   ! e-w boundary already done -> force to take last column 
    262             DO jf = 1, ipf 
    263                DO jl = 1, ipl 
    264                   DO jk = 1, ipk 
     324         DEALLOCATE( znorthloc ) 
     325         ALLOCATE( ztabglo(jpiglo,ipj2,ipk,ipl,ipf) ) 
     326         ! 
     327         ! need to fill only the first ipj lines of ztabglo as lbc_nfd don't use the last nn_hls lines 
     328         ijnr = 0 
     329         DO jr = 1, jpni                                                        ! recover the global north array 
     330            iproc = nfproc(jr) 
     331            impp  = nfimpp(jr) 
     332            ipi   = nfjpi( jr) - 2 * nn_hls                       ! corresponds to Ni_0 but for subdomain iproc 
     333            IF( iproc == -1 ) THEN   ! No neighbour (land proc that was suppressed) 
     334              ! 
     335               SELECT CASE ( kfillmode ) 
     336               CASE ( jpfillnothing )               ! no filling  
     337               CASE ( jpfillcopy    )               ! filling with inner domain values 
     338                  DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk 
    265339                     DO jj = 1, ipj 
    266                         DO ji = ildi, ilei 
    267                            ztab(ji+iilb-1,jj,jk,jl,jf) = znorthgloio(ji,jj,jk,jl,jf,jr) 
     340                        ij2 = jpj - ipj2 + jj                    ! the first ipj lines of the last ipj2 lines 
     341                        DO ji = 1, ipi 
     342                           ii1 = impp + nn_hls + ji - 1          ! corresponds to mig(nn_hls + ji) but for subdomain iproc 
     343                           ztabglo(ii1,jj,jk,jl,jf) = ARRAY_IN(Nis0,ij2,jk,jl,jf)   ! chose to take the 1st iner domain point 
    268344                        END DO 
    269345                     END DO 
     346                  END DO   ;   END DO   ;   END DO 
     347               CASE ( jpfillcst     )               ! filling with constant value 
     348                  DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk 
     349                     DO jj = 1, ipj 
     350                        DO ji = 1, ipi 
     351                           ii1 = impp + nn_hls + ji - 1          ! corresponds to mig(nn_hls + ji) but for subdomain iproc 
     352                           ztabglo(ii1,jj,jk,jl,jf) = pfillval 
     353                        END DO 
     354                     END DO 
     355                 END DO   ;   END DO   ;   END DO 
     356               END SELECT 
     357               ! 
     358            ELSE 
     359               ijnr = ijnr + 1 
     360               DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk 
     361                  DO jj = 1, ipj 
     362                     DO ji = 1, ipi 
     363                        ii1 = impp + nn_hls + ji - 1             ! corresponds to mig(nn_hls + ji) but for subdomain iproc 
     364                        ztabglo(ii1,jj,jk,jl,jf) = znorthglo(ji,jj,jk,jl,jf,ijnr) 
     365                     END DO 
    270366                  END DO 
     367               END DO   ;   END DO   ;   END DO 
     368            ENDIF 
     369            ! 
     370         END DO   ! jpni 
     371         DEALLOCATE( znorthglo ) 
     372         ! 
     373         DO jf = 1, ipf 
     374            CALL lbc_nfd( ztabglo(:,:,:,:,jf), cd_nat LBC_ARG, psgn LBC_ARG )   ! North fold boundary condition 
     375            DO jl = 1, ipl   ;   DO jk = 1, ipk                  ! e-w periodicity 
     376               DO jj = 1, nn_hls + 1 
     377                  ij1 = ipj2 - (nn_hls + 1) + jj                 ! need only the last nn_hls + 1 lines until ipj2 
     378                  ztabglo(              1:nn_hls,ij1,jk,jl,jf) = ztabglo(jpiglo-2*nn_hls+1:jpiglo-nn_hls,ij1,jk,jl,jf) 
     379                  ztabglo(jpiglo-nn_hls+1:jpiglo,ij1,jk,jl,jf) = ztabglo(         nn_hls+1:     2*nn_hls,ij1,jk,jl,jf) 
     380               END DO 
     381            END DO   ;   END DO 
     382         END DO      
     383         ! 
     384         DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk               ! Scatter back to ARRAY_IN 
     385            DO jj = 1, nn_hls + 1 
     386               ij1 = jpj  - (nn_hls + 1) + jj   ! last nn_hls + 1 lines until jpj 
     387               ij2 = ipj2 - (nn_hls + 1) + jj   ! last nn_hls + 1 lines until ipj2 
     388               DO ji= 1, jpi 
     389                  ii2 = mig(ji) 
     390                  ARRAY_IN(ji,ij1,jk,jl,jf) = ztabglo(ii2,ij2,jk,jl,jf) 
    271391               END DO 
    272392            END DO 
    273          END DO 
    274          DO jf = 1, ipf 
    275             CALL lbc_nfd( ztab(:,:,:,:,jf), cd_nat LBC_ARG, psgn LBC_ARG )   ! North fold boundary condition 
    276          END DO 
    277          ! 
    278          DO jf = 1, ipf 
    279             DO jl = 1, ipl 
    280                DO jk = 1, ipk 
    281                   DO jj = nlcj-ipj+1, nlcj             ! Scatter back to ARRAY_IN 
    282                      ij = jj - nlcj + ipj 
    283                      DO ji= 1, nlci 
    284                         ARRAY_IN(ji,jj,jk,jl,jf) = ztab(ji+nimpp-1,ij,jk,jl,jf) 
    285                      END DO 
    286                   END DO 
    287                END DO 
    288             END DO 
    289          END DO 
    290          ! 
    291       ! 
    292          DEALLOCATE( ztab ) 
    293          DEALLOCATE( znorthgloio ) 
    294       ENDIF 
    295       ! 
    296       DEALLOCATE( znorthloc ) 
     393         END DO   ;   END DO   ;   END DO 
     394         ! 
     395         DEALLOCATE( ztabglo ) 
     396         ! 
     397      ENDIF   ! l_north_nogather 
    297398      ! 
    298399   END SUBROUTINE ROUTINE_NFD 
    299400 
     401#undef PRECISION 
     402#undef MPI_TYPE 
     403#undef SENDROUTINE 
     404#undef RECVROUTINE 
    300405#undef ARRAY_TYPE 
    301406#undef NAT_IN 
     
    306411#undef F_SIZE 
    307412#undef LBC_ARG 
     413#undef HUGEVAL 
  • NEMO/branches/2020/dev_12905_xios_ancil/src/OCE/LBC/mppini.F90

    r12377 r13766  
    88   !!            8.0  !  1998-05  (M. Imbard, J. Escobar, L. Colombet )  SHMEM and MPI versions 
    99   !!  NEMO      1.0  !  2004-01  (G. Madec, J.M Molines)  F90 : free form , north fold jpni > 1 
    10    !!            3.4  ! 2011-10  (A. C. Coward, NOCS & J. Donners, PRACE) add mpp_init_nfdcom 
    11    !!            3.   ! 2013-06  (I. Epicoco, S. Mocavero, CMCC) mpp_init_nfdcom: setup avoiding MPI communication  
     10   !!            3.4  !  2011-10  (A. C. Coward, NOCS & J. Donners, PRACE)  add init_nfdcom 
     11   !!            3.   !  2013-06  (I. Epicoco, S. Mocavero, CMCC)  init_nfdcom: setup avoiding MPI communication  
    1212   !!            4.0  !  2016-06  (G. Madec)  use domain configuration file instead of bathymetry file 
    1313   !!            4.0  !  2017-06  (J.M. Molines, T. Lovato) merge of mppini and mppini_2 
     
    1515 
    1616   !!---------------------------------------------------------------------- 
    17    !!  mpp_init          : Lay out the global domain over processors with/without land processor elimination 
    18    !!  mpp_init_mask     : Read global bathymetric information to facilitate land suppression 
    19    !!  mpp_init_ioipsl   : IOIPSL initialization in mpp  
    20    !!  mpp_init_partition: Calculate MPP domain decomposition 
    21    !!  factorise         : Calculate the factors of the no. of MPI processes 
    22    !!  mpp_init_nfdcom   : Setup for north fold exchanges with explicit point-to-point messaging 
     17   !!  mpp_init       : Lay out the global domain over processors with/without land processor elimination 
     18   !!      init_ioipsl: IOIPSL initialization in mpp  
     19   !!      init_nfdcom: Setup for north fold exchanges with explicit point-to-point messaging 
     20   !!      init_doloop: set the starting/ending indices of DO-loop used in do_loop_substitute  
    2321   !!---------------------------------------------------------------------- 
    2422   USE dom_oce        ! ocean space and time domain 
    2523   USE bdy_oce        ! open BounDarY   
    2624   ! 
    27    USE lbcnfd  , ONLY : isendto, nsndto, nfsloop, nfeloop  ! Setup of north fold exchanges  
     25   USE lbcnfd  , ONLY : isendto, nsndto ! Setup of north fold exchanges  
    2826   USE lib_mpp        ! distribued memory computing library 
    2927   USE iom            ! nemo I/O library  
     
    3432   PRIVATE 
    3533 
    36    PUBLIC mpp_init       ! called by opa.F90 
    37  
    38    INTEGER :: numbot = -1  ! 'bottom_level' local logical unit 
    39    INTEGER :: numbdy = -1  ! 'bdy_msk'      local logical unit 
     34   PUBLIC   mpp_init       ! called by nemogcm.F90 
     35   PUBLIC   mpp_getnum     ! called by prtctl 
     36   PUBLIC   mpp_basesplit  ! called by prtctl 
     37   PUBLIC   mpp_is_ocean   ! called by prtctl 
     38    
     39   INTEGER ::   numbot = -1   ! 'bottom_level' local logical unit 
     40   INTEGER ::   numbdy = -1   ! 'bdy_msk'      local logical unit 
    4041    
    4142   !!---------------------------------------------------------------------- 
     
    6162      !!---------------------------------------------------------------------- 
    6263      ! 
     64      nn_hls = 1 
     65      jpiglo = Ni0glo + 2 * nn_hls 
     66      jpjglo = Nj0glo + 2 * nn_hls 
    6367      jpimax = jpiglo 
    6468      jpjmax = jpjglo 
     
    6670      jpj    = jpjglo 
    6771      jpk    = jpkglo 
    68       jpim1  = jpi-1                                            ! inner domain indices 
    69       jpjm1  = jpj-1                                            !   "           " 
    70       jpkm1  = MAX( 1, jpk-1 )                                  !   "           " 
     72      jpim1  = jpi-1                         ! inner domain indices 
     73      jpjm1  = jpj-1                         !   "           " 
     74      jpkm1  = MAX( 1, jpk-1 )               !   "           " 
    7175      jpij   = jpi*jpj 
    7276      jpni   = 1 
    7377      jpnj   = 1 
    7478      jpnij  = jpni*jpnj 
    75       nimpp  = 1           !  
     79      nimpp  = 1 
    7680      njmpp  = 1 
    77       nlci   = jpi 
    78       nlcj   = jpj 
    79       nldi   = 1 
    80       nldj   = 1 
    81       nlei   = jpi 
    82       nlej   = jpj 
    8381      nbondi = 2 
    8482      nbondj = 2 
     
    9088      l_Jperio = jpnj == 1 .AND. (jperio == 2 .OR. jperio == 7) 
    9189      ! 
     90      CALL init_doloop                       ! set start/end indices or do-loop depending on the halo width value (nn_hls)  
     91      ! 
    9292      IF(lwp) THEN 
    9393         WRITE(numout,*) 
     
    9898      ENDIF 
    9999      ! 
    100       IF(  jpni /= 1 .OR. jpnj /= 1 .OR. jpnij /= 1 )                                     & 
    101          CALL ctl_stop( 'mpp_init: equality  jpni = jpnj = jpnij = 1 is not satisfied',   & 
    102             &           'the domain is lay out for distributed memory computing!' ) 
    103          ! 
     100#if defined key_agrif 
     101    IF (.NOT.agrif_root()) THEN 
     102      call agrif_nemo_init() 
     103    ENDIF 
     104#endif 
    104105   END SUBROUTINE mpp_init 
    105106 
     
    130131      !!                    njmpp     : latitudinal  index 
    131132      !!                    narea     : number for local area 
    132       !!                    nlci      : first dimension 
    133       !!                    nlcj      : second dimension 
    134133      !!                    nbondi    : mark for "east-west local boundary" 
    135134      !!                    nbondj    : mark for "north-south local boundary" 
     
    142141      INTEGER ::   ji, jj, jn, jproc, jarea   ! dummy loop indices 
    143142      INTEGER ::   inijmin 
    144       INTEGER ::   i2add 
    145143      INTEGER ::   inum                       ! local logical unit 
    146       INTEGER ::   idir, ifreq, icont         ! local integers 
     144      INTEGER ::   idir, ifreq                ! local integers 
    147145      INTEGER ::   ii, il1, ili, imil         !   -       - 
    148146      INTEGER ::   ij, il2, ilj, ijm1         !   -       - 
     
    157155      INTEGER, ALLOCATABLE, DIMENSION(:)     ::   iin, ii_nono, ii_noea          ! 1D workspace 
    158156      INTEGER, ALLOCATABLE, DIMENSION(:)     ::   ijn, ii_noso, ii_nowe          !  -     - 
    159       INTEGER, ALLOCATABLE, DIMENSION(:,:) ::   iimppt, ilci, ibondi, ipproc   ! 2D workspace 
    160       INTEGER, ALLOCATABLE, DIMENSION(:,:) ::   ijmppt, ilcj, ibondj, ipolj    !  -     - 
    161       INTEGER, ALLOCATABLE, DIMENSION(:,:) ::   ilei, ildi, iono, ioea         !  -     - 
    162       INTEGER, ALLOCATABLE, DIMENSION(:,:) ::   ilej, ildj, ioso, iowe         !  -     - 
     157      INTEGER, ALLOCATABLE, DIMENSION(:,:) ::   iimppt, ijpi, ibondi, ipproc   ! 2D workspace 
     158      INTEGER, ALLOCATABLE, DIMENSION(:,:) ::   ijmppt, ijpj, ibondj, ipolj    !  -     - 
     159      INTEGER, ALLOCATABLE, DIMENSION(:,:) ::   iie0, iis0, iono, ioea         !  -     - 
     160      INTEGER, ALLOCATABLE, DIMENSION(:,:) ::   ije0, ijs0, ioso, iowe         !  -     - 
    163161      LOGICAL, ALLOCATABLE, DIMENSION(:,:) ::   llisoce                        !  -     - 
    164162      NAMELIST/nambdy/ ln_bdy, nb_bdy, ln_coords_file, cn_coords_file,           & 
     
    168166           &             cn_ice, nn_ice_dta,                                     & 
    169167           &             ln_vol, nn_volctl, nn_rimwidth 
    170       NAMELIST/nammpp/ jpni, jpnj, ln_nnogather, ln_listonly 
     168      NAMELIST/nammpp/ jpni, jpnj, nn_hls, ln_nnogather, ln_listonly 
    171169      !!---------------------------------------------------------------------- 
    172170      ! 
     
    181179902   IF( ios >  0 )   CALL ctl_nam ( ios , 'nammpp in configuration namelist' )    
    182180      ! 
     181      nn_hls = MAX(1, nn_hls)   ! nn_hls must be > 0 
    183182      IF(lwp) THEN 
    184183            WRITE(numout,*) '   Namelist nammpp' 
     
    190189         ENDIF 
    191190            WRITE(numout,*) '      avoid use of mpi_allgather at the north fold  ln_nnogather = ', ln_nnogather 
     191            WRITE(numout,*) '      halo width (applies to both rows and columns)       nn_hls = ', nn_hls 
    192192      ENDIF 
    193193      ! 
    194194      IF(lwm)   WRITE( numond, nammpp ) 
    195  
     195      ! 
     196!!!------------------------------------ 
     197!!!  nn_hls shloud be read in nammpp 
     198!!!------------------------------------ 
     199      jpiglo = Ni0glo + 2 * nn_hls 
     200      jpjglo = Nj0glo + 2 * nn_hls 
     201      ! 
    196202      ! do we need to take into account bdy_msk? 
    197203      READ  ( numnam_ref, nambdy, IOSTAT = ios, ERR = 903) 
     
    203209      IF( ln_bdy .AND. ln_mask_file ) CALL iom_open( cn_mask_file, numbdy ) 
    204210      ! 
    205       IF( ln_listonly )   CALL mpp_init_bestpartition( MAX(mppsize,jpni*jpnj), ldlist = .TRUE. )   ! must be done by all core 
     211      IF( ln_listonly )   CALL bestpartition( MAX(mppsize,jpni*jpnj), ldlist = .TRUE. )   ! must be done by all core 
    206212      ! 
    207213      !  1. Dimension arrays for subdomains 
    208214      ! ----------------------------------- 
    209215      ! 
    210       ! If dimensions of processor grid weren't specified in the namelist file 
     216      ! If dimensions of processors grid weren't specified in the namelist file 
    211217      ! then we calculate them here now that we have our communicator size 
    212218      IF(lwp) THEN 
     
    216222      ENDIF 
    217223      IF( jpni < 1 .OR. jpnj < 1 ) THEN 
    218          CALL mpp_init_bestpartition( mppsize, jpni, jpnj )           ! best mpi decomposition for mppsize mpi processes 
     224         CALL bestpartition( mppsize, jpni, jpnj )           ! best mpi decomposition for mppsize mpi processes 
    219225         llauto = .TRUE. 
    220226         llbest = .TRUE. 
    221227      ELSE 
    222228         llauto = .FALSE. 
    223          CALL mpp_init_bestpartition( mppsize, inbi, inbj, icnt2 )    ! best mpi decomposition for mppsize mpi processes 
     229         CALL bestpartition( mppsize, inbi, inbj, icnt2 )    ! best mpi decomposition for mppsize mpi processes 
    224230         ! largest subdomain size for mpi decoposition jpni*jpnj given in the namelist 
    225          CALL mpp_basic_decomposition( jpni, jpnj, jpimax, jpjmax ) 
    226          ! largest subdomain size for mpi decoposition inbi*inbj given by mpp_init_bestpartition 
    227          CALL mpp_basic_decomposition( inbi, inbj,  iimax,  ijmax ) 
     231         CALL mpp_basesplit( jpiglo, jpjglo, nn_hls, jpni, jpnj, jpimax, jpjmax ) 
     232         ! largest subdomain size for mpi decoposition inbi*inbj given by bestpartition 
     233         CALL mpp_basesplit( jpiglo, jpjglo, nn_hls, inbi, inbj,  iimax,  ijmax ) 
    228234         icnt1 = jpni*jpnj - mppsize   ! number of land subdomains that should be removed to use mppsize mpi processes 
    229235         IF(lwp) THEN 
     
    256262      ! look for land mpi subdomains... 
    257263      ALLOCATE( llisoce(jpni,jpnj) ) 
    258       CALL mpp_init_isoce( jpni, jpnj, llisoce ) 
     264      CALL mpp_is_ocean( llisoce ) 
    259265      inijmin = COUNT( llisoce )   ! number of oce subdomains 
    260266 
     
    265271         WRITE(ctmp4,*) '   ==>>> There is the list of best domain decompositions you should use: ' 
    266272         CALL ctl_stop( ctmp1, ctmp2, ctmp3, ' ', ctmp4, ' ' ) 
    267          CALL mpp_init_bestpartition( mppsize, ldlist = .TRUE. )   ! must be done by all core 
     273         CALL bestpartition( mppsize, ldlist = .TRUE. )   ! must be done by all core 
    268274      ENDIF 
    269275 
     
    289295            WRITE(numout,*) 
    290296         ENDIF 
    291          CALL mpp_init_bestpartition( mppsize, ldlist = .TRUE. )   ! must be done by all core 
     297         CALL bestpartition( mppsize, ldlist = .TRUE. )   ! must be done by all core 
    292298      ENDIF 
    293299 
     
    3143209003  FORMAT (a, i5) 
    315321 
    316       IF( numbot /= -1 )   CALL iom_close( numbot ) 
    317       IF( numbdy /= -1 )   CALL iom_close( numbdy ) 
    318      
    319       ALLOCATE(  nfiimpp(jpni,jpnj), nfipproc(jpni,jpnj), nfilcit(jpni,jpnj) ,    & 
    320          &       nimppt(jpnij) , ibonit(jpnij) , nlcit(jpnij) , nlcjt(jpnij) ,    & 
    321          &       njmppt(jpnij) , ibonjt(jpnij) , nldit(jpnij) , nldjt(jpnij) ,    & 
    322          &                                       nleit(jpnij) , nlejt(jpnij) ,    & 
     322      ALLOCATE(  nfimpp(jpni ) , nfproc(jpni ) ,   nfjpi(jpni ) ,                     & 
     323         &       nimppt(jpnij) , ibonit(jpnij) ,  jpiall(jpnij) ,  jpjall(jpnij) ,    & 
     324         &       njmppt(jpnij) , ibonjt(jpnij) , nis0all(jpnij) , njs0all(jpnij) ,    & 
     325         &                                       nie0all(jpnij) , nje0all(jpnij) ,    & 
    323326         &       iin(jpnij), ii_nono(jpnij), ii_noea(jpnij),   & 
    324327         &       ijn(jpnij), ii_noso(jpnij), ii_nowe(jpnij),   & 
    325          &       iimppt(jpni,jpnj), ilci(jpni,jpnj), ibondi(jpni,jpnj), ipproc(jpni,jpnj),   & 
    326          &       ijmppt(jpni,jpnj), ilcj(jpni,jpnj), ibondj(jpni,jpnj), ipolj(jpni,jpnj),   & 
    327          &       ilei(jpni,jpnj), ildi(jpni,jpnj), iono(jpni,jpnj), ioea(jpni,jpnj),   & 
    328          &       ilej(jpni,jpnj), ildj(jpni,jpnj), ioso(jpni,jpnj), iowe(jpni,jpnj),   & 
     328         &       iimppt(jpni,jpnj), ijpi(jpni,jpnj), ibondi(jpni,jpnj), ipproc(jpni,jpnj),   & 
     329         &       ijmppt(jpni,jpnj), ijpj(jpni,jpnj), ibondj(jpni,jpnj), ipolj(jpni,jpnj),   & 
     330         &         iie0(jpni,jpnj), iis0(jpni,jpnj),   iono(jpni,jpnj),  ioea(jpni,jpnj),   & 
     331         &         ije0(jpni,jpnj), ijs0(jpni,jpnj),   ioso(jpni,jpnj),  iowe(jpni,jpnj),   & 
    329332         &       STAT=ierr ) 
    330333      CALL mpp_sum( 'mppini', ierr ) 
     
    333336#if defined key_agrif 
    334337      IF( .NOT. Agrif_Root() ) THEN       ! AGRIF children: specific setting (cf. agrif_user.F90) 
    335          IF( jpiglo /= nbcellsx + 2 + 2*nbghostcells )   & 
    336             CALL ctl_stop( 'STOP', 'mpp_init: Agrif children requires jpiglo == nbcellsx + 2 + 2*nbghostcells' ) 
    337          IF( jpjglo /= nbcellsy + 2 + 2*nbghostcells )   & 
    338             CALL ctl_stop( 'STOP', 'mpp_init: Agrif children requires jpjglo == nbcellsy + 2 + 2*nbghostcells' ) 
    339          IF( ln_use_jattr )   CALL ctl_stop( 'STOP', 'mpp_init:Agrif children requires ln_use_jattr = .false. ' ) 
     338         CALL agrif_nemo_init() 
    340339      ENDIF 
    341340#endif 
     
    344343      ! ----------------------------------- 
    345344      ! 
    346       nreci = 2 * nn_hls 
    347       nrecj = 2 * nn_hls 
    348       CALL mpp_basic_decomposition( jpni, jpnj, jpimax, jpjmax, iimppt, ijmppt, ilci, ilcj ) 
    349       nfiimpp(:,:) = iimppt(:,:) 
    350       nfilcit(:,:) = ilci(:,:) 
     345      CALL mpp_basesplit( jpiglo, jpjglo, nn_hls, jpni, jpnj, jpimax, jpjmax, iimppt, ijmppt, ijpi, ijpj ) 
     346      CALL mpp_getnum( llisoce, ipproc, iin, ijn ) 
     347      ! 
     348      !DO jn = 1, jpni 
     349      !   jproc = ipproc(jn,jpnj) 
     350      !   ii = iin(jproc+1) 
     351      !   ij = ijn(jproc+1) 
     352      !   nfproc(jn) = jproc 
     353      !   nfimpp(jn) = iimppt(ii,ij) 
     354      !   nfjpi (jn) =   ijpi(ii,ij) 
     355      !END DO 
     356      nfproc(:) = ipproc(:,jpnj)  
     357      nfimpp(:) = iimppt(:,jpnj)  
     358      nfjpi (:) =   ijpi(:,jpnj) 
    351359      ! 
    352360      IF(lwp) THEN 
     
    357365         WRITE(numout,*) '      jpni = ', jpni   
    358366         WRITE(numout,*) '      jpnj = ', jpnj 
     367         WRITE(numout,*) '     jpnij = ', jpnij 
    359368         WRITE(numout,*) 
    360          WRITE(numout,*) '      sum ilci(i,1) = ', sum(ilci(:,1)), ' jpiglo = ', jpiglo 
    361          WRITE(numout,*) '      sum ilcj(1,j) = ', sum(ilcj(1,:)), ' jpjglo = ', jpjglo 
     369         WRITE(numout,*) '      sum ijpi(i,1) = ', sum(ijpi(:,1)), ' jpiglo = ', jpiglo 
     370         WRITE(numout,*) '      sum ijpj(1,j) = ', sum(ijpj(1,:)), ' jpjglo = ', jpjglo 
    362371      ENDIF 
    363372      
     
    374383         ii = 1 + MOD(iarea0,jpni) 
    375384         ij = 1 +     iarea0/jpni 
    376          ili = ilci(ii,ij) 
    377          ilj = ilcj(ii,ij) 
     385         ili = ijpi(ii,ij) 
     386         ilj = ijpj(ii,ij) 
    378387         ibondi(ii,ij) = 0                         ! default: has e-w neighbours 
    379388         IF( ii   ==    1 )   ibondi(ii,ij) = -1   ! first column, has only e neighbour 
     
    390399         ioea(ii,ij) = iarea0 + 1 
    391400         iono(ii,ij) = iarea0 + jpni 
    392          ildi(ii,ij) =  1  + nn_hls 
    393          ilei(ii,ij) = ili - nn_hls 
    394          ildj(ii,ij) =  1  + nn_hls 
    395          ilej(ii,ij) = ilj - nn_hls 
     401         iis0(ii,ij) =  1  + nn_hls 
     402         iie0(ii,ij) = ili - nn_hls 
     403         ijs0(ii,ij) =  1  + nn_hls 
     404         ije0(ii,ij) = ilj - nn_hls 
    396405 
    397406         ! East-West periodicity: change ibondi, ioea, iowe 
     
    431440      ! ---------------------------- 
    432441      ! 
    433       ! specify which subdomains are oce subdomains; other are land subdomains 
    434       ipproc(:,:) = -1 
    435       icont = -1 
    436       DO jarea = 1, jpni*jpnj 
    437          iarea0 = jarea - 1 
    438          ii = 1 + MOD(iarea0,jpni) 
    439          ij = 1 +     iarea0/jpni 
    440          IF( llisoce(ii,ij) ) THEN 
    441             icont = icont + 1 
    442             ipproc(ii,ij) = icont 
    443             iin(icont+1) = ii 
    444             ijn(icont+1) = ij 
    445          ENDIF 
    446       END DO 
    447       ! if needed add some land subdomains to reach jpnij active subdomains 
    448       i2add = jpnij - inijmin 
    449       DO jarea = 1, jpni*jpnj 
    450          iarea0 = jarea - 1 
    451          ii = 1 + MOD(iarea0,jpni) 
    452          ij = 1 +     iarea0/jpni 
    453          IF( .NOT. llisoce(ii,ij) .AND. i2add > 0 ) THEN 
    454             icont = icont + 1 
    455             ipproc(ii,ij) = icont 
    456             iin(icont+1) = ii 
    457             ijn(icont+1) = ij 
    458             i2add = i2add - 1 
    459          ENDIF 
    460       END DO 
    461       nfipproc(:,:) = ipproc(:,:) 
    462  
    463442      ! neighbour treatment: change ibondi, ibondj if next to a land zone 
    464443      DO jarea = 1, jpni*jpnj 
     
    499478         ENDIF 
    500479      END DO 
    501  
    502       ! Update il[de][ij] according to modified ibond[ij] 
    503       ! ---------------------- 
    504       DO jproc = 1, jpnij 
    505          ii = iin(jproc) 
    506          ij = ijn(jproc) 
    507          IF( ibondi(ii,ij) == -1 .OR. ibondi(ii,ij) == 2 ) ildi(ii,ij) =  1 
    508          IF( ibondi(ii,ij) ==  1 .OR. ibondi(ii,ij) == 2 ) ilei(ii,ij) = ilci(ii,ij) 
    509          IF( ibondj(ii,ij) == -1 .OR. ibondj(ii,ij) == 2 ) ildj(ii,ij) =  1 
    510          IF( ibondj(ii,ij) ==  1 .OR. ibondj(ii,ij) == 2 ) ilej(ii,ij) = ilcj(ii,ij) 
    511       END DO 
    512480       
    513481      ! 5. Subdomain print 
     
    522490            DO jj = jpnj, 1, -1 
    523491               WRITE(numout,9403) ('   ',ji=il1,il2-1) 
    524                WRITE(numout,9402) jj, (ilci(ji,jj),ilcj(ji,jj),ji=il1,il2) 
     492               WRITE(numout,9402) jj, (ijpi(ji,jj),ijpj(ji,jj),ji=il1,il2) 
    525493               WRITE(numout,9404) (ipproc(ji,jj),ji=il1,il2) 
    526494               WRITE(numout,9403) ('   ',ji=il1,il2-1) 
     
    579547      noea = ii_noea(narea) 
    580548      nono = ii_nono(narea) 
    581       nlci = ilci(ii,ij)   
    582       nldi = ildi(ii,ij) 
    583       nlei = ilei(ii,ij) 
    584       nlcj = ilcj(ii,ij)   
    585       nldj = ildj(ii,ij) 
    586       nlej = ilej(ii,ij) 
     549      jpi    = ijpi(ii,ij)   
     550!!$      Nis0  = iis0(ii,ij) 
     551!!$      Nie0  = iie0(ii,ij) 
     552      jpj    = ijpj(ii,ij)   
     553!!$      Njs0  = ijs0(ii,ij) 
     554!!$      Nje0  = ije0(ii,ij) 
    587555      nbondi = ibondi(ii,ij) 
    588556      nbondj = ibondj(ii,ij) 
    589557      nimpp = iimppt(ii,ij)   
    590558      njmpp = ijmppt(ii,ij) 
    591       jpi = nlci 
    592       jpj = nlcj 
    593       jpk = jpkglo                                             ! third dim 
    594 #if defined key_agrif 
    595       ! simple trick to use same vertical grid as parent but different number of levels:  
    596       ! Save maximum number of levels in jpkglo, then define all vertical grids with this number. 
    597       ! Suppress once vertical online interpolation is ok 
    598 !!$      IF(.NOT.Agrif_Root())   jpkglo = Agrif_Parent( jpkglo ) 
    599 #endif 
    600       jpim1 = jpi-1                                            ! inner domain indices 
    601       jpjm1 = jpj-1                                            !   "           " 
    602       jpkm1 = MAX( 1, jpk-1 )                                  !   "           " 
    603       jpij  = jpi*jpj                                          !  jpi x j 
     559      jpk = jpkglo                              ! third dim 
     560      ! 
     561      CALL init_doloop                          ! set start/end indices of do-loop, depending on the halo width value (nn_hls)  
     562      ! 
     563      jpim1 = jpi-1                             ! inner domain indices 
     564      jpjm1 = jpj-1                             !   "           " 
     565      jpkm1 = MAX( 1, jpk-1 )                   !   "           " 
     566      jpij  = jpi*jpj                           !  jpi x j 
    604567      DO jproc = 1, jpnij 
    605568         ii = iin(jproc) 
    606569         ij = ijn(jproc) 
    607          nlcit(jproc) = ilci(ii,ij) 
    608          nldit(jproc) = ildi(ii,ij) 
    609          nleit(jproc) = ilei(ii,ij) 
    610          nlcjt(jproc) = ilcj(ii,ij) 
    611          nldjt(jproc) = ildj(ii,ij) 
    612          nlejt(jproc) = ilej(ii,ij) 
     570         jpiall (jproc) = ijpi(ii,ij) 
     571         nis0all(jproc) = iis0(ii,ij) 
     572         nie0all(jproc) = iie0(ii,ij) 
     573         jpjall (jproc) = ijpj(ii,ij) 
     574         njs0all(jproc) = ijs0(ii,ij) 
     575         nje0all(jproc) = ije0(ii,ij) 
    613576         ibonit(jproc) = ibondi(ii,ij) 
    614577         ibonjt(jproc) = ibondj(ii,ij) 
     
    624587         WRITE(inum,'(6i8,a,3i8,a)') jpnij,jpimax,jpjmax,jpk,jpiglo,jpjglo,& 
    625588   &           ' ( local: ',narea,jpi,jpj,' )' 
    626          WRITE(inum,'(a)') 'nproc nlci nlcj nldi nldj nlei nlej nimp njmp nono noso nowe noea nbondi nbondj ' 
     589         WRITE(inum,'(a)') 'nproc   jpi  jpj Nis0 Njs0 Nie0 Nje0 nimp njmp nono noso nowe noea nbondi nbondj ' 
    627590 
    628591         DO jproc = 1, jpnij 
    629             WRITE(inum,'(13i5,2i7)')   jproc-1, nlcit  (jproc), nlcjt  (jproc),   & 
    630                &                                nldit  (jproc), nldjt  (jproc),   & 
    631                &                                nleit  (jproc), nlejt  (jproc),   & 
     592            WRITE(inum,'(13i5,2i7)')   jproc-1,  jpiall(jproc),  jpjall(jproc),   & 
     593               &                                nis0all(jproc), njs0all(jproc),   & 
     594               &                                nie0all(jproc), nje0all(jproc),   & 
    632595               &                                nimppt (jproc), njmppt (jproc),   &  
    633596               &                                ii_nono(jproc), ii_noso(jproc),   & 
     
    663626         WRITE(numout,*) '    l_Iperio = ', l_Iperio 
    664627         WRITE(numout,*) '    l_Jperio = ', l_Jperio 
    665          WRITE(numout,*) '      nlci   = ', nlci 
    666          WRITE(numout,*) '      nlcj   = ', nlcj 
    667628         WRITE(numout,*) '      nimpp  = ', nimpp 
    668629         WRITE(numout,*) '      njmpp  = ', njmpp 
    669          WRITE(numout,*) '      nreci  = ', nreci   
    670          WRITE(numout,*) '      nrecj  = ', nrecj   
    671          WRITE(numout,*) '      nn_hls = ', nn_hls  
    672630      ENDIF 
    673631 
     
    691649      ENDIF 
    692650      ! 
    693       CALL mpp_init_ioipsl       ! Prepare NetCDF output file (if necessary) 
     651      CALL init_ioipsl       ! Prepare NetCDF output file (if necessary) 
    694652      !       
    695653      IF (( jperio >= 3 .AND. jperio <= 6 .AND. jpni > 1 ).AND.( ln_nnogather )) THEN 
    696          CALL mpp_init_nfdcom     ! northfold neighbour lists 
     654         CALL init_nfdcom     ! northfold neighbour lists 
    697655         IF (llwrtlay) THEN 
    698656            WRITE(inum,*) 
    699657            WRITE(inum,*) 
    700658            WRITE(inum,*) 'north fold exchanges with explicit point-to-point messaging :' 
    701             WRITE(inum,*) 'nfsloop : ', nfsloop 
    702             WRITE(inum,*) 'nfeloop : ', nfeloop 
    703659            WRITE(inum,*) 'nsndto : ', nsndto 
    704660            WRITE(inum,*) 'isendto : ', isendto 
     
    710666      DEALLOCATE(iin, ijn, ii_nono, ii_noea, ii_noso, ii_nowe,    & 
    711667         &       iimppt, ijmppt, ibondi, ibondj, ipproc, ipolj,   & 
    712          &       ilci, ilcj, ilei, ilej, ildi, ildj,              & 
     668         &       ijpi, ijpj, iie0, ije0, iis0, ijs0,              & 
    713669         &       iono, ioea, ioso, iowe, llisoce) 
    714670      ! 
    715671    END SUBROUTINE mpp_init 
    716672 
    717  
    718     SUBROUTINE mpp_basic_decomposition( knbi, knbj, kimax, kjmax, kimppt, kjmppt, klci, klcj) 
    719       !!---------------------------------------------------------------------- 
    720       !!                  ***  ROUTINE mpp_basic_decomposition  *** 
     673#endif 
     674 
     675    SUBROUTINE mpp_basesplit( kiglo, kjglo, khls, knbi, knbj, kimax, kjmax, kimppt, kjmppt, klci, klcj) 
     676      !!---------------------------------------------------------------------- 
     677      !!                  ***  ROUTINE mpp_basesplit  *** 
    721678      !!                     
    722679      !! ** Purpose :   Lay out the global domain over processors. 
     
    730687      !!                    klcj       : second dimension 
    731688      !!---------------------------------------------------------------------- 
     689      INTEGER,                                 INTENT(in   ) ::   kiglo, kjglo 
     690      INTEGER,                                 INTENT(in   ) ::   khls 
    732691      INTEGER,                                 INTENT(in   ) ::   knbi, knbj 
    733692      INTEGER,                                 INTENT(  out) ::   kimax, kjmax 
     
    736695      ! 
    737696      INTEGER ::   ji, jj 
     697      INTEGER ::   i2hls  
    738698      INTEGER ::   iresti, irestj, irm, ijpjmin 
    739       INTEGER ::   ireci, irecj 
    740       !!---------------------------------------------------------------------- 
     699      !!---------------------------------------------------------------------- 
     700      i2hls = 2*khls 
    741701      ! 
    742702#if defined key_nemocice_decomp 
    743       kimax = ( nx_global+2-2*nn_hls + (knbi-1) ) / knbi + 2*nn_hls    ! first  dim. 
    744       kjmax = ( ny_global+2-2*nn_hls + (knbj-1) ) / knbj + 2*nn_hls    ! second dim.  
     703      kimax = ( nx_global+2-i2hls + (knbi-1) ) / knbi + i2hls    ! first  dim. 
     704      kjmax = ( ny_global+2-i2hls + (knbj-1) ) / knbj + i2hls    ! second dim.  
    745705#else 
    746       kimax = ( jpiglo - 2*nn_hls + (knbi-1) ) / knbi + 2*nn_hls    ! first  dim. 
    747       kjmax = ( jpjglo - 2*nn_hls + (knbj-1) ) / knbj + 2*nn_hls    ! second dim. 
     706      kimax = ( kiglo - i2hls + (knbi-1) ) / knbi + i2hls    ! first  dim. 
     707      kjmax = ( kjglo - i2hls + (knbj-1) ) / knbj + i2hls    ! second dim. 
    748708#endif 
    749709      IF( .NOT. PRESENT(kimppt) ) RETURN 
     
    752712      ! ----------------------------------- 
    753713      !  Computation of local domain sizes klci() klcj() 
    754       !  These dimensions depend on global sizes knbi,knbj and jpiglo,jpjglo 
     714      !  These dimensions depend on global sizes knbi,knbj and kiglo,kjglo 
    755715      !  The subdomains are squares lesser than or equal to the global 
    756716      !  dimensions divided by the number of processors minus the overlap array. 
    757717      ! 
    758       ireci = 2 * nn_hls 
    759       irecj = 2 * nn_hls 
    760       iresti = 1 + MOD( jpiglo - ireci -1 , knbi ) 
    761       irestj = 1 + MOD( jpjglo - irecj -1 , knbj ) 
     718      iresti = 1 + MOD( kiglo - i2hls - 1 , knbi ) 
     719      irestj = 1 + MOD( kjglo - i2hls - 1 , knbj ) 
    762720      ! 
    763721      !  Need to use kimax and kjmax here since jpi and jpj not yet defined 
    764722#if defined key_nemocice_decomp 
    765723      ! Change padding to be consistent with CICE 
    766       klci(1:knbi-1      ,:) = kimax 
    767       klci(knbi          ,:) = jpiglo - (knbi - 1) * (kimax - nreci) 
    768       klcj(:,      1:knbj-1) = kjmax 
    769       klcj(:,          knbj) = jpjglo - (knbj - 1) * (kjmax - nrecj) 
     724      klci(1:knbi-1,:       ) = kimax 
     725      klci(  knbi  ,:       ) = kiglo - (knbi - 1) * (kimax - i2hls) 
     726      klcj(:       ,1:knbj-1) = kjmax 
     727      klcj(:       ,  knbj  ) = kjglo - (knbj - 1) * (kjmax - i2hls) 
    770728#else 
    771729      klci(1:iresti      ,:) = kimax 
    772730      klci(iresti+1:knbi ,:) = kimax-1 
    773       IF( MINVAL(klci) < 3 ) THEN 
    774          WRITE(ctmp1,*) '   mpp_basic_decomposition: minimum value of jpi must be >= 3' 
     731      IF( MINVAL(klci) < 2*i2hls ) THEN 
     732         WRITE(ctmp1,*) '   mpp_basesplit: minimum value of jpi must be >= ', 2*i2hls 
    775733         WRITE(ctmp2,*) '   We have ', MINVAL(klci) 
    776734        CALL ctl_stop( 'STOP', ctmp1, ctmp2 ) 
     
    778736      IF( jperio == 3 .OR. jperio == 4 .OR. jperio == 5 .OR. jperio == 6 ) THEN 
    779737         ! minimize the size of the last row to compensate for the north pole folding coast 
    780          IF( jperio == 3 .OR. jperio == 4 )   ijpjmin = 5   ! V and F folding involves line jpj-3 that must not be south boundary 
    781          IF( jperio == 5 .OR. jperio == 6 )   ijpjmin = 4   ! V and F folding involves line jpj-2 that must not be south boundary 
    782          irm = knbj - irestj                                    ! total number of lines to be removed 
    783          klcj(:,            knbj) = MAX( ijpjmin, kjmax-irm )   ! we must have jpj >= ijpjmin in the last row 
    784          irm = irm - ( kjmax - klcj(1,knbj) )                   ! remaining number of lines to remove  
    785          irestj = knbj - 1 - irm                         
    786          klcj(:,        1:irestj) = kjmax 
     738         IF( jperio == 3 .OR. jperio == 4 )   ijpjmin = 2+3*khls   ! V and F folding must be outside of southern halos 
     739         IF( jperio == 5 .OR. jperio == 6 )   ijpjmin = 1+3*khls   ! V and F folding must be outside of southern halos 
     740         irm = knbj - irestj                                       ! total number of lines to be removed 
     741         klcj(:,knbj) = MAX( ijpjmin, kjmax-irm )                  ! we must have jpj >= ijpjmin in the last row 
     742         irm = irm - ( kjmax - klcj(1,knbj) )                      ! remaining number of lines to remove  
     743         irestj = knbj - 1 - irm 
    787744         klcj(:, irestj+1:knbj-1) = kjmax-1 
    788745      ELSE 
    789          ijpjmin = 3 
    790          klcj(:,      1:irestj) = kjmax 
    791          klcj(:, irestj+1:knbj) = kjmax-1 
    792       ENDIF 
    793       IF( MINVAL(klcj) < ijpjmin ) THEN 
    794          WRITE(ctmp1,*) '   mpp_basic_decomposition: minimum value of jpj must be >= ', ijpjmin 
     746         klcj(:, irestj+1:knbj  ) = kjmax-1 
     747      ENDIF 
     748      klcj(:,1:irestj) = kjmax 
     749      IF( MINVAL(klcj) < 2*i2hls ) THEN 
     750         WRITE(ctmp1,*) '   mpp_basesplit: minimum value of jpj must be >= ', 2*i2hls 
    795751         WRITE(ctmp2,*) '   We have ', MINVAL(klcj) 
    796752         CALL ctl_stop( 'STOP', ctmp1, ctmp2 ) 
     
    806762         DO jj = 1, knbj 
    807763            DO ji = 2, knbi 
    808                kimppt(ji,jj) = kimppt(ji-1,jj) + klci(ji-1,jj) - ireci 
     764               kimppt(ji,jj) = kimppt(ji-1,jj) + klci(ji-1,jj) - i2hls 
    809765            END DO 
    810766         END DO 
     
    814770         DO jj = 2, knbj 
    815771            DO ji = 1, knbi 
    816                kjmppt(ji,jj) = kjmppt(ji,jj-1) + klcj(ji,jj-1) - irecj 
     772               kjmppt(ji,jj) = kjmppt(ji,jj-1) + klcj(ji,jj-1) - i2hls 
    817773            END DO 
    818774         END DO 
    819775      ENDIF 
    820776       
    821    END SUBROUTINE mpp_basic_decomposition 
    822  
    823  
    824    SUBROUTINE mpp_init_bestpartition( knbij, knbi, knbj, knbcnt, ldlist ) 
    825       !!---------------------------------------------------------------------- 
    826       !!                 ***  ROUTINE mpp_init_bestpartition  *** 
     777   END SUBROUTINE mpp_basesplit 
     778 
     779 
     780   SUBROUTINE bestpartition( knbij, knbi, knbj, knbcnt, ldlist ) 
     781      !!---------------------------------------------------------------------- 
     782      !!                 ***  ROUTINE bestpartition  *** 
    827783      !! 
    828784      !! ** Purpose : 
     
    830786      !! ** Method  : 
    831787      !!---------------------------------------------------------------------- 
    832       INTEGER,           INTENT(in   ) ::   knbij         ! total number if subdomains              (knbi*knbj) 
     788      INTEGER,           INTENT(in   ) ::   knbij         ! total number of subdomains (knbi*knbj) 
    833789      INTEGER, OPTIONAL, INTENT(  out) ::   knbi, knbj    ! number if subdomains along i and j (knbi and knbj) 
    834790      INTEGER, OPTIONAL, INTENT(  out) ::   knbcnt        ! number of land subdomains 
     
    838794      INTEGER :: iszitst, iszjtst 
    839795      INTEGER :: isziref, iszjref 
     796      INTEGER :: iszimin, iszjmin 
    840797      INTEGER :: inbij, iszij 
    841798      INTEGER :: inbimax, inbjmax, inbijmax, inbijold 
     
    866823      inbimax = 0 
    867824      inbjmax = 0 
    868       isziref = jpiglo*jpjglo+1 
     825      isziref = jpiglo*jpjglo+1   ! define a value that is larger than the largest possible 
    869826      iszjref = jpiglo*jpjglo+1 
     827      ! 
     828      iszimin = 4*nn_hls          ! minimum size of the MPI subdomain so halos are always adressing neighbor inner domain 
     829      iszjmin = 4*nn_hls 
     830      IF( jperio == 3 .OR. jperio == 4 )   iszjmin = MAX(iszjmin, 2+3*nn_hls)   ! V and F folding must be outside of southern halos 
     831      IF( jperio == 5 .OR. jperio == 6 )   iszjmin = MAX(iszjmin, 1+3*nn_hls)   ! V and F folding must be outside of southern halos 
    870832      ! 
    871833      ! get the list of knbi that gives a smaller jpimax than knbi-1 
     
    875837         iszitst = ( nx_global+2-2*nn_hls + (ji-1) ) / ji + 2*nn_hls    ! first  dim. 
    876838#else 
    877          iszitst = ( jpiglo - 2*nn_hls + (ji-1) ) / ji + 2*nn_hls 
     839         iszitst = ( Ni0glo + (ji-1) ) / ji + 2*nn_hls   ! max subdomain i-size 
    878840#endif 
    879          IF( iszitst < isziref ) THEN 
     841         IF( iszitst < isziref .AND. iszitst >= iszimin ) THEN 
    880842            isziref = iszitst 
    881843            inbimax = inbimax + 1 
     
    886848         iszjtst = ( ny_global+2-2*nn_hls + (ji-1) ) / ji + 2*nn_hls    ! first  dim. 
    887849#else 
    888          iszjtst = ( jpjglo - 2*nn_hls + (ji-1) ) / ji + 2*nn_hls 
     850         iszjtst = ( Nj0glo + (ji-1) ) / ji + 2*nn_hls   ! max subdomain j-size 
    889851#endif 
    890          IF( iszjtst < iszjref ) THEN 
     852         IF( iszjtst < iszjref .AND. iszjtst >= iszjmin ) THEN 
    891853            iszjref = iszjtst 
    892854            inbjmax = inbjmax + 1 
     
    926888      iszij1(:) = iszi1(:) * iszj1(:) 
    927889 
    928       ! if therr is no land and no print 
     890      ! if there is no land and no print 
    929891      IF( .NOT. llist .AND. numbot == -1 .AND. numbdy == -1 ) THEN 
    930892         ! get the smaller partition which gives the smallest subdomain size 
     
    945907         ii = MINLOC(iszij1, mask = inbij1 == inbij, dim = 1)   ! warning: send back the first occurence if multiple results 
    946908         IF ( iszij1(ii) < iszij ) THEN 
     909            ii = MINLOC( iszi1+iszj1, mask = iszij1 == iszij1(ii) .AND. inbij1 == inbij, dim = 1)  ! select the smaller perimeter if multiple min 
    947910            isz0 = isz0 + 1 
    948911            indexok(isz0) = ii 
     
    974937         ji = isz0   ! initialization with the largest value 
    975938         ALLOCATE( llisoce(inbi0(ji), inbj0(ji)) ) 
    976          CALL mpp_init_isoce( inbi0(ji), inbj0(ji), llisoce ) ! Warning: must be call by all cores (call mpp_sum) 
     939         CALL mpp_is_ocean( llisoce )  ! Warning: must be call by all cores (call mpp_sum) 
    977940         inbijold = COUNT(llisoce) 
    978941         DEALLOCATE( llisoce ) 
    979942         DO ji =isz0-1,1,-1 
    980943            ALLOCATE( llisoce(inbi0(ji), inbj0(ji)) ) 
    981             CALL mpp_init_isoce( inbi0(ji), inbj0(ji), llisoce ) ! Warning: must be call by all cores (call mpp_sum) 
     944            CALL mpp_is_ocean( llisoce )  ! Warning: must be call by all cores (call mpp_sum) 
    982945            inbij = COUNT(llisoce) 
    983946            DEALLOCATE( llisoce ) 
     
    1005968         ii = ii -1  
    1006969         ALLOCATE( llisoce(inbi0(ii), inbj0(ii)) ) 
    1007          CALL mpp_init_isoce( inbi0(ii), inbj0(ii), llisoce )            ! must be done by all core 
     970         CALL mpp_is_ocean( llisoce )            ! must be done by all core 
    1008971         inbij = COUNT(llisoce) 
    1009972         DEALLOCATE( llisoce ) 
     
    1014977      DEALLOCATE( inbi0, inbj0 ) 
    1015978      ! 
    1016    END SUBROUTINE mpp_init_bestpartition 
     979   END SUBROUTINE bestpartition 
    1017980    
    1018981    
     
    1023986      !! ** Purpose : the the proportion of land points in the surface land-sea mask 
    1024987      !! 
    1025       !! ** Method  : read iproc strips (of length jpiglo) of the land-sea mask 
     988      !! ** Method  : read iproc strips (of length Ni0glo) of the land-sea mask 
    1026989      !!---------------------------------------------------------------------- 
    1027990      REAL(wp), INTENT(  out) :: propland    ! proportion of land points in the global domain (between 0 and 1) 
     
    10401003 
    10411004      ! number of processes reading the bathymetry file  
    1042       iproc = MINVAL( (/mppsize, jpjglo/2, 100/) )  ! read a least 2 lines, no more that 100 processes reading at the same time 
     1005      iproc = MINVAL( (/mppsize, Nj0glo/2, 100/) )  ! read a least 2 lines, no more that 100 processes reading at the same time 
    10431006       
    10441007      ! we want to read iproc strips of the land-sea mask. -> pick up iproc processes every idiv processes starting at 1 
     
    10501013      IF( MOD( narea-1, idiv ) == 0 .AND. iarea < iproc ) THEN   ! beware idiv can be = to 1 
    10511014         ! 
    1052          ijsz = jpjglo / iproc                                               ! width of the stripe to read 
    1053          IF( iarea < MOD(jpjglo,iproc) ) ijsz = ijsz + 1 
    1054          ijstr = iarea*(jpjglo/iproc) + MIN(iarea, MOD(jpjglo,iproc)) + 1    ! starting j position of the reading 
     1015         ijsz = Nj0glo / iproc                                               ! width of the stripe to read 
     1016         IF( iarea < MOD(Nj0glo,iproc) ) ijsz = ijsz + 1 
     1017         ijstr = iarea*(Nj0glo/iproc) + MIN(iarea, MOD(Nj0glo,iproc)) + 1    ! starting j position of the reading 
    10551018         ! 
    1056          ALLOCATE( lloce(jpiglo, ijsz) )                                     ! allocate the strip 
    1057          CALL mpp_init_readbot_strip( ijstr, ijsz, lloce ) 
     1019         ALLOCATE( lloce(Ni0glo, ijsz) )                                     ! allocate the strip 
     1020         CALL readbot_strip( ijstr, ijsz, lloce ) 
    10581021         inboce = COUNT(lloce)                                               ! number of ocean point in the stripe 
    10591022         DEALLOCATE(lloce) 
     
    10641027      CALL mpp_sum( 'mppini', inboce )   ! total number of ocean points over the global domain 
    10651028      ! 
    1066       propland = REAL( jpiglo*jpjglo - inboce, wp ) / REAL( jpiglo*jpjglo, wp )  
     1029      propland = REAL( Ni0glo*Nj0glo - inboce, wp ) / REAL( Ni0glo*Nj0glo, wp )  
    10671030      ! 
    10681031   END SUBROUTINE mpp_init_landprop 
    10691032    
    10701033    
    1071    SUBROUTINE mpp_init_isoce( knbi, knbj, ldisoce ) 
    1072       !!---------------------------------------------------------------------- 
    1073       !!                  ***  ROUTINE mpp_init_nboce  *** 
    1074       !! 
    1075       !! ** Purpose : check for a mpi domain decomposition knbi x knbj which 
    1076       !!              subdomains contain at least 1 ocean point 
    1077       !! 
    1078       !! ** Method  : read knbj strips (of length jpiglo) of the land-sea mask 
    1079       !!---------------------------------------------------------------------- 
    1080       INTEGER,                       INTENT(in   ) ::   knbi, knbj     ! domain decomposition 
    1081       LOGICAL, DIMENSION(knbi,knbj), INTENT(  out) ::   ldisoce        ! .true. if a sub domain constains 1 ocean point  
    1082       ! 
    1083       INTEGER, DIMENSION(knbi,knbj) ::   inboce                        ! number oce oce pint in each mpi subdomain 
    1084       INTEGER, DIMENSION(knbi*knbj) ::   inboce_1d 
     1034   SUBROUTINE mpp_is_ocean( ldisoce ) 
     1035      !!---------------------------------------------------------------------- 
     1036      !!                  ***  ROUTINE mpp_is_ocean  *** 
     1037      !! 
     1038      !! ** Purpose : Check for a mpi domain decomposition inbi x inbj which 
     1039      !!              subdomains, including 1 halo (even if nn_hls>1), contain 
     1040      !!              at least 1 ocean point. 
     1041      !!              We must indeed ensure that each subdomain that is a neighbour 
     1042      !!              of a land subdomain as only land points on its boundary 
     1043      !!              (inside the inner subdomain) with the land subdomain. 
     1044      !!              This is needed to get the proper bondary conditions on 
     1045      !!              a subdomain with a closed boundary. 
     1046      !! 
     1047      !! ** Method  : read inbj strips (of length Ni0glo) of the land-sea mask 
     1048      !!---------------------------------------------------------------------- 
     1049      LOGICAL, DIMENSION(:,:), INTENT(  out) ::   ldisoce        ! .true. if a sub domain constains 1 ocean point  
     1050      ! 
    10851051      INTEGER :: idiv, iimax, ijmax, iarea 
     1052      INTEGER :: inbi, inbj, inx, iny, inry, isty 
    10861053      INTEGER :: ji, jn 
    1087       LOGICAL, ALLOCATABLE, DIMENSION(:,:) ::   lloce                  ! lloce(i,j) = .true. if the point (i,j) is ocean  
    1088       INTEGER, ALLOCATABLE, DIMENSION(:,:) ::   iimppt, ilci 
    1089       INTEGER, ALLOCATABLE, DIMENSION(:,:) ::   ijmppt, ilcj 
     1054      INTEGER, ALLOCATABLE, DIMENSION(:,:) ::   inboce           ! number oce oce pint in each mpi subdomain 
     1055      INTEGER, ALLOCATABLE, DIMENSION(:  ) ::   inboce_1d 
     1056      INTEGER, ALLOCATABLE, DIMENSION(:,:) ::   iimppt, ijpi 
     1057      INTEGER, ALLOCATABLE, DIMENSION(:,:) ::   ijmppt, ijpj 
     1058      LOGICAL, ALLOCATABLE, DIMENSION(:,:) ::   lloce            ! lloce(i,j) = .true. if the point (i,j) is ocean  
    10901059      !!---------------------------------------------------------------------- 
    10911060      ! do nothing if there is no land-sea mask 
     
    10941063         RETURN 
    10951064      ENDIF 
    1096  
    1097       ! we want to read knbj strips of the land-sea mask. -> pick up knbj processes every idiv processes starting at 1 
    1098       IF           ( knbj == 1 ) THEN   ;   idiv = mppsize 
    1099       ELSE IF ( mppsize < knbj ) THEN   ;   idiv = 1 
    1100       ELSE                              ;   idiv = ( mppsize - 1 ) / ( knbj - 1 ) 
    1101       ENDIF 
     1065      ! 
     1066      inbi = SIZE( ldisoce, dim = 1 ) 
     1067      inbj = SIZE( ldisoce, dim = 2 ) 
     1068      ! 
     1069      ! we want to read inbj strips of the land-sea mask. -> pick up inbj processes every idiv processes starting at 1 
     1070      IF           ( inbj == 1 ) THEN   ;   idiv = mppsize 
     1071      ELSE IF ( mppsize < inbj ) THEN   ;   idiv = 1 
     1072      ELSE                              ;   idiv = ( mppsize - 1 ) / ( inbj - 1 ) 
     1073      ENDIF 
     1074      ! 
     1075      ALLOCATE( inboce(inbi,inbj), inboce_1d(inbi*inbj) ) 
    11021076      inboce(:,:) = 0          ! default no ocean point found 
    1103  
    1104       DO jn = 0, (knbj-1)/mppsize   ! if mppsize < knbj : more strips than mpi processes (because of potential land domains) 
     1077      ! 
     1078      DO jn = 0, (inbj-1)/mppsize   ! if mppsize < inbj : more strips than mpi processes (because of potential land domains) 
    11051079         ! 
    1106          iarea = (narea-1)/idiv + jn * mppsize   ! involed process number (starting counting at 0) 
    1107          IF( MOD( narea-1, idiv ) == 0 .AND. iarea < knbj ) THEN   ! beware idiv can be = to 1 
     1080         iarea = (narea-1)/idiv + jn * mppsize + 1                     ! involed process number (starting counting at 1) 
     1081         IF( MOD( narea-1, idiv ) == 0 .AND. iarea <= inbj ) THEN      ! beware idiv can be = to 1 
    11081082            ! 
    1109             ALLOCATE( iimppt(knbi,knbj), ijmppt(knbi,knbj), ilci(knbi,knbj), ilcj(knbi,knbj) ) 
    1110             CALL mpp_basic_decomposition( knbi, knbj, iimax, ijmax, iimppt, ijmppt, ilci, ilcj ) 
     1083            ALLOCATE( iimppt(inbi,inbj), ijmppt(inbi,inbj), ijpi(inbi,inbj), ijpj(inbi,inbj) ) 
     1084            CALL mpp_basesplit( Ni0glo, Nj0glo, 0, inbi, inbj, iimax, ijmax, iimppt, ijmppt, ijpi, ijpj ) 
    11111085            ! 
    1112             ALLOCATE( lloce(jpiglo, ilcj(1,iarea+1)) )                                         ! allocate the strip 
    1113             CALL mpp_init_readbot_strip( ijmppt(1,iarea+1), ilcj(1,iarea+1), lloce )           ! read the strip 
    1114             DO  ji = 1, knbi 
    1115                inboce(ji,iarea+1) = COUNT( lloce(iimppt(ji,1):iimppt(ji,1)+ilci(ji,1)-1,:) )   ! number of ocean point in subdomain 
     1086            inx = Ni0glo + 2   ;   iny = ijpj(1,iarea) + 2             ! strip size + 1 halo on each direction (even if nn_hls>1) 
     1087            ALLOCATE( lloce(inx, iny) )                                ! allocate the strip 
     1088            inry = iny - COUNT( (/ iarea == 1, iarea == inbj /) )      ! number of point to read in y-direction 
     1089            isty = 1 + COUNT( (/ iarea == 1 /) )                       ! read from the first or the second line? 
     1090            CALL readbot_strip( ijmppt(1,iarea) - 2 + isty, inry, lloce(2:inx-1, isty:inry+isty-1) )   ! read the strip 
     1091            !  
     1092            IF( iarea == 1    ) THEN                                   ! the first line was not read 
     1093               IF( jperio == 2 .OR. jperio == 7 ) THEN                 !   north-south periodocity 
     1094                  CALL readbot_strip( Nj0glo, 1, lloce(2:inx-1, 1) )   !   read the last line -> first line of lloce 
     1095               ELSE 
     1096                  lloce(2:inx-1,  1) = .FALSE.                         !   closed boundary 
     1097               ENDIF 
     1098            ENDIF 
     1099            IF( iarea == inbj ) THEN                                   ! the last line was not read 
     1100               IF( jperio == 2 .OR. jperio == 7 ) THEN                 !   north-south periodocity 
     1101                  CALL readbot_strip( 1, 1, lloce(2:inx-1,iny) )       !      read the first line -> last line of lloce 
     1102               ELSEIF( jperio == 3 .OR. jperio == 4 ) THEN             !   north-pole folding T-pivot, T-point  
     1103                  lloce(2,iny) = lloce(2,iny-2)                        !      here we have 1 halo (even if nn_hls>1) 
     1104                  DO ji = 3,inx-1 
     1105                     lloce(ji,iny  ) = lloce(inx-ji+2,iny-2)           !      ok, we have at least 3 lines 
     1106                  END DO 
     1107                  DO ji = inx/2+2,inx-1 
     1108                     lloce(ji,iny-1) = lloce(inx-ji+2,iny-1) 
     1109                  END DO 
     1110               ELSEIF( jperio == 5 .OR. jperio == 6 ) THEN             !   north-pole folding F-pivot, T-point, 1 halo 
     1111                  lloce(inx/2+1,iny-1) = lloce(inx/2,iny-1)            !      here we have 1 halo (even if nn_hls>1) 
     1112                  lloce(inx  -1,iny-1) = lloce(2    ,iny-1) 
     1113                  DO ji = 2,inx-1 
     1114                     lloce(ji,iny) = lloce(inx-ji+1,iny-1) 
     1115                  END DO 
     1116               ELSE                                                    !   closed boundary 
     1117                  lloce(2:inx-1,iny) = .FALSE. 
     1118               ENDIF 
     1119            ENDIF 
     1120            !                                                          ! first and last column were not read 
     1121            IF( jperio == 1 .OR. jperio == 4 .OR. jperio == 6 .OR. jperio == 7 ) THEN 
     1122               lloce(1,:) = lloce(inx-1,:)   ;   lloce(inx,:) = lloce(2,:)   ! east-west periodocity 
     1123            ELSE 
     1124               lloce(1,:) = .FALSE.          ;   lloce(inx,:) = .FALSE.      ! closed boundary 
     1125            ENDIF 
     1126            ! 
     1127            DO  ji = 1, inbi 
     1128               inboce(ji,iarea) = COUNT( lloce(iimppt(ji,1):iimppt(ji,1)+ijpi(ji,1)+1,:) )   ! lloce as 2 points more than Ni0glo 
    11161129            END DO 
    11171130            ! 
    11181131            DEALLOCATE(lloce) 
    1119             DEALLOCATE(iimppt, ijmppt, ilci, ilcj) 
     1132            DEALLOCATE(iimppt, ijmppt, ijpi, ijpj) 
    11201133            ! 
    11211134         ENDIF 
    11221135      END DO 
    11231136    
    1124       inboce_1d = RESHAPE(inboce, (/ knbi*knbj /)) 
     1137      inboce_1d = RESHAPE(inboce, (/ inbi*inbj /)) 
    11251138      CALL mpp_sum( 'mppini', inboce_1d ) 
    1126       inboce = RESHAPE(inboce_1d, (/knbi, knbj/)) 
     1139      inboce = RESHAPE(inboce_1d, (/inbi, inbj/)) 
    11271140      ldisoce(:,:) = inboce(:,:) /= 0 
    1128       ! 
    1129    END SUBROUTINE mpp_init_isoce 
     1141      DEALLOCATE(inboce, inboce_1d) 
     1142      ! 
     1143   END SUBROUTINE mpp_is_ocean 
    11301144    
    11311145    
    1132    SUBROUTINE mpp_init_readbot_strip( kjstr, kjcnt, ldoce ) 
    1133       !!---------------------------------------------------------------------- 
    1134       !!                  ***  ROUTINE mpp_init_readbot_strip  *** 
     1146   SUBROUTINE readbot_strip( kjstr, kjcnt, ldoce ) 
     1147      !!---------------------------------------------------------------------- 
     1148      !!                  ***  ROUTINE readbot_strip  *** 
    11351149      !! 
    11361150      !! ** Purpose : Read relevant bathymetric information in order to 
     
    11381152      !!              of land domains, in an mpp computation. 
    11391153      !! 
    1140       !! ** Method  : read stipe of size (jpiglo,...) 
    1141       !!---------------------------------------------------------------------- 
    1142       INTEGER                         , INTENT(in   ) :: kjstr       ! starting j position of the reading 
    1143       INTEGER                         , INTENT(in   ) :: kjcnt       ! number of lines to read 
    1144       LOGICAL, DIMENSION(jpiglo,kjcnt), INTENT(  out) :: ldoce       ! ldoce(i,j) = .true. if the point (i,j) is ocean  
     1154      !! ** Method  : read stipe of size (Ni0glo,...) 
     1155      !!---------------------------------------------------------------------- 
     1156      INTEGER                         , INTENT(in   ) ::   kjstr       ! starting j position of the reading 
     1157      INTEGER                         , INTENT(in   ) ::   kjcnt       ! number of lines to read 
     1158      LOGICAL, DIMENSION(Ni0glo,kjcnt), INTENT(  out) ::  ldoce       ! ldoce(i,j) = .true. if the point (i,j) is ocean  
    11451159      ! 
    11461160      INTEGER                           ::   inumsave                ! local logical unit 
    1147       REAL(wp), DIMENSION(jpiglo,kjcnt) ::   zbot, zbdy  
     1161      REAL(wp), DIMENSION(Ni0glo,kjcnt) ::   zbot, zbdy  
    11481162      !!---------------------------------------------------------------------- 
    11491163      ! 
    11501164      inumsave = numout   ;   numout = numnul   !   redirect all print to /dev/null 
    11511165      ! 
    1152       IF( numbot /= -1 ) THEN 
    1153          CALL iom_get( numbot, jpdom_unknown, 'bottom_level', zbot, kstart = (/1,kjstr/), kcount = (/jpiglo, kjcnt/) ) 
     1166      IF( numbot /= -1 ) THEN    
     1167         CALL iom_get( numbot, jpdom_unknown, 'bottom_level', zbot, kstart = (/1,kjstr/), kcount = (/Ni0glo, kjcnt/) ) 
    11541168      ELSE 
    1155          zbot(:,:) = 1.                         ! put a non-null value 
    1156       ENDIF 
    1157  
    1158        IF( numbdy /= -1 ) THEN                  ! Adjust with bdy_msk if it exists     
    1159          CALL iom_get ( numbdy, jpdom_unknown, 'bdy_msk', zbdy, kstart = (/1,kjstr/), kcount = (/jpiglo, kjcnt/) ) 
     1169         zbot(:,:) = 1._wp                      ! put a non-null value 
     1170      ENDIF 
     1171      ! 
     1172      IF( numbdy /= -1 ) THEN                   ! Adjust with bdy_msk if it exists     
     1173         CALL iom_get ( numbdy, jpdom_unknown,     'bdy_msk', zbdy, kstart = (/1,kjstr/), kcount = (/Ni0glo, kjcnt/) ) 
    11601174         zbot(:,:) = zbot(:,:) * zbdy(:,:) 
    11611175      ENDIF 
    11621176      ! 
    1163       ldoce(:,:) = zbot(:,:) > 0. 
     1177      ldoce(:,:) = zbot(:,:) > 0._wp 
    11641178      numout = inumsave 
    11651179      ! 
    1166    END SUBROUTINE mpp_init_readbot_strip 
    1167  
    1168  
    1169    SUBROUTINE mpp_init_ioipsl 
    1170       !!---------------------------------------------------------------------- 
    1171       !!                  ***  ROUTINE mpp_init_ioipsl  *** 
     1180   END SUBROUTINE readbot_strip 
     1181 
     1182 
     1183   SUBROUTINE mpp_getnum( ldisoce, kproc, kipos, kjpos ) 
     1184      !!---------------------------------------------------------------------- 
     1185      !!                  ***  ROUTINE mpp_getnum  *** 
     1186      !! 
     1187      !! ** Purpose : give a number to each MPI subdomains (starting at 0) 
     1188      !! 
     1189      !! ** Method  : start from bottom left. First skip land subdomain, and finally use them if needed 
     1190      !!---------------------------------------------------------------------- 
     1191      LOGICAL, DIMENSION(:,:), INTENT(in   ) ::   ldisoce     ! F if land process 
     1192      INTEGER, DIMENSION(:,:), INTENT(  out) ::   kproc       ! subdomain number (-1 if supressed, starting at 0) 
     1193      INTEGER, DIMENSION(  :), INTENT(  out) ::   kipos       ! i-position of the subdomain (from 1 to jpni) 
     1194      INTEGER, DIMENSION(  :), INTENT(  out) ::   kjpos       ! j-position of the subdomain (from 1 to jpnj) 
     1195      ! 
     1196      INTEGER :: ii, ij, jarea, iarea0 
     1197      INTEGER :: icont, i2add , ini, inj, inij 
     1198      !!---------------------------------------------------------------------- 
     1199      ! 
     1200      ini = SIZE(ldisoce, dim = 1) 
     1201      inj = SIZE(ldisoce, dim = 2) 
     1202      inij = SIZE(kipos) 
     1203      ! 
     1204      ! specify which subdomains are oce subdomains; other are land subdomains 
     1205      kproc(:,:) = -1 
     1206      icont = -1 
     1207      DO jarea = 1, ini*inj 
     1208         iarea0 = jarea - 1 
     1209         ii = 1 + MOD(iarea0,ini) 
     1210         ij = 1 +     iarea0/ini 
     1211         IF( ldisoce(ii,ij) ) THEN 
     1212            icont = icont + 1 
     1213            kproc(ii,ij) = icont 
     1214            kipos(icont+1) = ii 
     1215            kjpos(icont+1) = ij 
     1216         ENDIF 
     1217      END DO 
     1218      ! if needed add some land subdomains to reach inij active subdomains 
     1219      i2add = inij - COUNT( ldisoce ) 
     1220      DO jarea = 1, ini*inj 
     1221         iarea0 = jarea - 1 
     1222         ii = 1 + MOD(iarea0,ini) 
     1223         ij = 1 +     iarea0/ini 
     1224         IF( .NOT. ldisoce(ii,ij) .AND. i2add > 0 ) THEN 
     1225            icont = icont + 1 
     1226            kproc(ii,ij) = icont 
     1227            kipos(icont+1) = ii 
     1228            kjpos(icont+1) = ij 
     1229            i2add = i2add - 1 
     1230         ENDIF 
     1231      END DO 
     1232      ! 
     1233   END SUBROUTINE mpp_getnum 
     1234 
     1235 
     1236   SUBROUTINE init_ioipsl 
     1237      !!---------------------------------------------------------------------- 
     1238      !!                  ***  ROUTINE init_ioipsl  *** 
    11721239      !! 
    11731240      !! ** Purpose :    
     
    11861253      ! Set idompar values equivalent to the jpdom_local_noextra definition 
    11871254      ! used in IOM. This works even if jpnij .ne. jpni*jpnj. 
    1188       iglo(1) = jpiglo 
    1189       iglo(2) = jpjglo 
    1190       iloc(1) = nlci 
    1191       iloc(2) = nlcj 
    1192       iabsf(1) = nimppt(narea) 
    1193       iabsf(2) = njmppt(narea) 
     1255      iglo( :) = (/ Ni0glo, Nj0glo /) 
     1256      iloc( :) = (/ Ni_0  , Nj_0   /) 
     1257      iabsf(:) = (/ Nis0  , Njs0   /) + (/ nimpp, njmpp /) - 1 - nn_hls   ! corresponds to mig0(Nis0) but mig0 is not yet defined! 
    11941258      iabsl(:) = iabsf(:) + iloc(:) - 1 
    1195       ihals(1) = nldi - 1 
    1196       ihals(2) = nldj - 1 
    1197       ihale(1) = nlci - nlei 
    1198       ihale(2) = nlcj - nlej 
    1199       idid(1) = 1 
    1200       idid(2) = 2 
     1259      ihals(:) = (/ 0     , 0      /) 
     1260      ihale(:) = (/ 0     , 0      /) 
     1261      idid( :) = (/ 1     , 2      /) 
    12011262 
    12021263      IF(lwp) THEN 
    12031264          WRITE(numout,*) 
    1204           WRITE(numout,*) 'mpp_init_ioipsl :   iloc  = ', iloc (1), iloc (2) 
    1205           WRITE(numout,*) '~~~~~~~~~~~~~~~     iabsf = ', iabsf(1), iabsf(2) 
    1206           WRITE(numout,*) '                    ihals = ', ihals(1), ihals(2) 
    1207           WRITE(numout,*) '                    ihale = ', ihale(1), ihale(2) 
     1265          WRITE(numout,*) 'mpp init_ioipsl :   iloc  = ', iloc 
     1266          WRITE(numout,*) '~~~~~~~~~~~~~~~     iabsf = ', iabsf 
     1267          WRITE(numout,*) '                    ihals = ', ihals 
     1268          WRITE(numout,*) '                    ihale = ', ihale 
    12081269      ENDIF 
    12091270      ! 
    12101271      CALL flio_dom_set ( jpnij, nproc, idid, iglo, iloc, iabsf, iabsl, ihals, ihale, 'BOX', nidom) 
    12111272      ! 
    1212    END SUBROUTINE mpp_init_ioipsl   
    1213  
    1214  
    1215    SUBROUTINE mpp_init_nfdcom 
    1216       !!---------------------------------------------------------------------- 
    1217       !!                     ***  ROUTINE  mpp_init_nfdcom  *** 
     1273   END SUBROUTINE init_ioipsl   
     1274 
     1275 
     1276   SUBROUTINE init_nfdcom 
     1277      !!---------------------------------------------------------------------- 
     1278      !!                     ***  ROUTINE  init_nfdcom  *** 
    12181279      !! ** Purpose :   Setup for north fold exchanges with explicit  
    12191280      !!                point-to-point messaging 
     
    12251286      !!---------------------------------------------------------------------- 
    12261287      INTEGER  ::   sxM, dxM, sxT, dxT, jn 
    1227       INTEGER  ::   njmppmax 
    1228       !!---------------------------------------------------------------------- 
    1229       ! 
    1230       njmppmax = MAXVAL( njmppt ) 
     1288      !!---------------------------------------------------------------------- 
    12311289      ! 
    12321290      !initializes the north-fold communication variables 
     
    12341292      nsndto     = 0 
    12351293      ! 
    1236       IF ( njmpp == njmppmax ) THEN      ! if I am a process in the north 
     1294      IF ( njmpp == MAXVAL( njmppt ) ) THEN      ! if I am a process in the north 
    12371295         ! 
    12381296         !sxM is the first point (in the global domain) needed to compute the north-fold for the current process 
    1239          sxM = jpiglo - nimppt(narea) - nlcit(narea) + 1 
     1297         sxM = jpiglo - nimppt(narea) - jpiall(narea) + 1 
    12401298         !dxM is the last point (in the global domain) needed to compute the north-fold for the current process 
    12411299         dxM = jpiglo - nimppt(narea) + 2 
     
    12461304         DO jn = 1, jpni 
    12471305            ! 
    1248             sxT = nfiimpp(jn, jpnj)                            ! sxT = 1st  point (in the global domain) of the jn process 
    1249             dxT = nfiimpp(jn, jpnj) + nfilcit(jn, jpnj) - 1    ! dxT = last point (in the global domain) of the jn process 
     1306            sxT = nfimpp(jn)                    ! sxT = 1st  point (in the global domain) of the jn process 
     1307            dxT = nfimpp(jn) + nfjpi(jn) - 1    ! dxT = last point (in the global domain) of the jn process 
    12501308            ! 
    12511309            IF    ( sxT < sxM  .AND.  sxM < dxT ) THEN 
     
    12611319            ! 
    12621320         END DO 
    1263          nfsloop = 1 
    1264          nfeloop = nlci 
    1265          DO jn = 2,jpni-1 
    1266             IF( nfipproc(jn,jpnj) == (narea - 1) ) THEN 
    1267                IF( nfipproc(jn-1,jpnj) == -1 )   nfsloop = nldi 
    1268                IF( nfipproc(jn+1,jpnj) == -1 )   nfeloop = nlei 
    1269             ENDIF 
    1270          END DO 
    12711321         ! 
    12721322      ENDIF 
    12731323      l_north_nogather = .TRUE. 
    12741324      ! 
    1275    END SUBROUTINE mpp_init_nfdcom 
    1276  
    1277  
    1278 #endif 
    1279  
     1325   END SUBROUTINE init_nfdcom 
     1326 
     1327 
     1328   SUBROUTINE init_doloop 
     1329      !!---------------------------------------------------------------------- 
     1330      !!                  ***  ROUTINE init_doloop  *** 
     1331      !! 
     1332      !! ** Purpose :   set the starting/ending indices of DO-loop 
     1333      !!              These indices are used in do_loop_substitute.h90 
     1334      !!---------------------------------------------------------------------- 
     1335      ! 
     1336      Nis0 =   1+nn_hls   ;   Nis1 = Nis0-1   ;   Nis2 = MAX(  1, Nis0-2) 
     1337      Njs0 =   1+nn_hls   ;   Njs1 = Njs0-1   ;   Njs2 = MAX(  1, Njs0-2)   
     1338      !                                                  
     1339      Nie0 = jpi-nn_hls   ;   Nie1 = Nie0+1   ;   Nie2 = MIN(jpi, Nie0+2) 
     1340      Nje0 = jpj-nn_hls   ;   Nje1 = Nje0+1   ;   Nje2 = MIN(jpj, Nje0+2) 
     1341      ! 
     1342      IF( nn_hls == 1 ) THEN          !* halo size of 1 
     1343         ! 
     1344         Nis1nxt2 = Nis0   ;   Njs1nxt2 = Njs0 
     1345         Nie1nxt2 = Nie0   ;   Nje1nxt2 = Nje0 
     1346         ! 
     1347      ELSE                            !* larger halo size...  
     1348         ! 
     1349         Nis1nxt2 = Nis1   ;   Njs1nxt2 = Njs1 
     1350         Nie1nxt2 = Nie1   ;   Nje1nxt2 = Nje1 
     1351         ! 
     1352      ENDIF 
     1353      ! 
     1354      Ni_0 = Nie0 - Nis0 + 1 
     1355      Nj_0 = Nje0 - Njs0 + 1 
     1356      Ni_1 = Nie1 - Nis1 + 1 
     1357      Nj_1 = Nje1 - Njs1 + 1 
     1358      Ni_2 = Nie2 - Nis2 + 1 
     1359      Nj_2 = Nje2 - Njs2 + 1 
     1360      ! 
     1361   END SUBROUTINE init_doloop 
     1362    
    12801363   !!====================================================================== 
    12811364END MODULE mppini 
Note: See TracChangeset for help on using the changeset viewer.