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 11192 for NEMO/branches/2019/dev_r10984_HPC-13_IRRMANN_BDY_optimization/src/OCE/LBC/mpp_lnk_generic.h90 – NEMO

Ignore:
Timestamp:
2019-06-27T12:40:32+02:00 (5 years ago)
Author:
smasson
Message:

dev_r10984_HPC-13 : reorganization of lbclnk, part 1: simpler mpp_lnk_generic.h90 supress lbc_lnk_generic.h90, see #2285

File:
1 edited

Legend:

Unmodified
Added
Removed
  • NEMO/branches/2019/dev_r10984_HPC-13_IRRMANN_BDY_optimization/src/OCE/LBC/mpp_lnk_generic.h90

    r10542 r11192  
    4646 
    4747#if defined MULTI 
    48    SUBROUTINE ROUTINE_LNK( cdname, ptab, cd_nat, psgn, kfld, cd_mpp, pval ) 
    49       INTEGER                     , INTENT(in   ) ::   kfld        ! number of pt3d arrays 
     48   SUBROUTINE ROUTINE_LNK( cdname, ptab, cd_nat, psgn, kfld, kfillmode, pfillval ) 
     49      INTEGER             , INTENT(in   ) ::   kfld        ! number of pt3d arrays 
    5050#else 
    51    SUBROUTINE ROUTINE_LNK( cdname, ptab, cd_nat, psgn      , cd_mpp, pval ) 
     51   SUBROUTINE ROUTINE_LNK( cdname, ptab, cd_nat, psgn      , kfillmode, pfillval ) 
    5252#endif 
    5353      ARRAY_TYPE(:,:,:,:,:)                                        ! array or pointer of arrays on which the boundary condition is applied 
    54       CHARACTER(len=*)            , INTENT(in   ) ::   cdname      ! name of the calling subroutine 
    55       CHARACTER(len=1)            , INTENT(in   ) ::   NAT_IN(:)   ! nature of array grid-points 
    56       REAL(wp)                    , INTENT(in   ) ::   SGN_IN(:)   ! sign used across the north fold boundary 
    57       CHARACTER(len=3), OPTIONAL  , INTENT(in   ) ::   cd_mpp      ! fill the overlap area only 
    58       REAL(wp)        , OPTIONAL  , INTENT(in   ) ::   pval        ! background value (used at closed boundaries) 
    59       ! 
    60       INTEGER  ::    ji,  jj,  jk,  jl, jh, jf   ! dummy loop indices 
     54      CHARACTER(len=*)    , INTENT(in   ) ::   cdname      ! name of the calling subroutine 
     55      CHARACTER(len=1)    , INTENT(in   ) ::   NAT_IN(:)   ! nature of array grid-points 
     56      REAL(wp)            , INTENT(in   ) ::   SGN_IN(:)   ! sign used across the north fold boundary 
     57      INTEGER , OPTIONAL  , INTENT(in   ) ::   kfillmode   ! filling method for halo over land (default = constant) 
     58      REAL(wp), OPTIONAL  , INTENT(in   ) ::   pfillval    ! background value (used at closed boundaries) 
     59      ! 
     60      INTEGER  ::    ji,  jj,  jk,  jl,  jf      ! dummy loop indices 
    6161      INTEGER  ::   ipi, ipj, ipk, ipl, ipf      ! dimension of the input array 
    62       INTEGER  ::   imigr, iihom, ijhom          ! local integers 
    63       INTEGER  ::   ml_req1, ml_req2, ml_err     ! for key_mpi_isend 
     62      INTEGER  ::   isize, ishift, ishift2       ! local integers 
     63      INTEGER  ::   ireq_we, ireq_ea, ireq_so, ireq_no     ! mpi_request id 
    6464      INTEGER  ::   ierr 
     65      INTEGER  ::   ifill_we, ifill_ea, ifill_so, ifill_no    
    6566      REAL(wp) ::   zland 
    66       INTEGER , DIMENSION(MPI_STATUS_SIZE)      ::   ml_stat        ! for key_mpi_isend 
    67       REAL(wp), DIMENSION(:,:,:,:,:,:), ALLOCATABLE ::   zt3ns, zt3sn   ! north-south & south-north  halos 
    68       REAL(wp), DIMENSION(:,:,:,:,:,:), ALLOCATABLE ::   zt3ew, zt3we   ! east -west  & west - east  halos 
     67      INTEGER , DIMENSION(MPI_STATUS_SIZE)        ::   istat          ! for mpi_isend 
     68      REAL(wp), DIMENSION(:,:,:,:,:), ALLOCATABLE ::   zsnd_we, zrcv_we, zsnd_ea, zrcv_ea   ! east -west  & west - east  halos 
     69      REAL(wp), DIMENSION(:,:,:,:,:), ALLOCATABLE ::   zsnd_so, zrcv_so, zsnd_no, zrcv_no   ! north-south & south-north  halos 
     70      LOGICAL  ::   llcom_we, llcom_ea, llcom_no, llcom_so       ! communication done or not 
     71      LOGICAL  ::   lldo_nfd                                     ! do north pole folding 
    6972      !!---------------------------------------------------------------------- 
     73      ! 
     74      ! ----------------------------------------- ! 
     75      !     0. local variables initialization     ! 
     76      ! ----------------------------------------- ! 
    7077      ! 
    7178      ipk = K_SIZE(ptab)   ! 3rd dimension 
     
    7582      IF( narea == 1 .AND. numcom == -1 ) CALL mpp_report( cdname, ipk, ipl, ipf, ld_lbc = .TRUE. ) 
    7683      ! 
    77       IF( PRESENT( pval ) ) THEN   ;   zland = pval      ! set land value 
    78       ELSE                         ;   zland = 0._wp     ! zero by default 
    79       ENDIF 
    80  
    81       ! ------------------------------- ! 
    82       !   standard boundary treatment   !    ! CAUTION: semi-column notation is often impossible 
    83       ! ------------------------------- ! 
    84       ! 
    85       IF( .NOT. PRESENT( cd_mpp ) ) THEN     !==  standard close or cyclic treatment  ==! 
    86          ! 
    87          DO jf = 1, ipf                      ! number of arrays to be treated 
    88             ! 
    89             !                                ! East-West boundaries 
    90             IF( l_Iperio ) THEN                    !* cyclic 
    91                ARRAY_IN( 1 ,:,:,:,jf) = ARRAY_IN(jpim1,:,:,:,jf) 
    92                ARRAY_IN(jpi,:,:,:,jf) = ARRAY_IN(  2  ,:,:,:,jf) 
    93             ELSE                                   !* closed 
    94                IF( .NOT. NAT_IN(jf) == 'F' )   ARRAY_IN(     1       :nn_hls,:,:,:,jf) = zland    ! east except F-point 
    95                                                ARRAY_IN(nlci-nn_hls+1:jpi   ,:,:,:,jf) = zland    ! west 
    96             ENDIF 
    97             !                                ! North-South boundaries 
    98             IF( l_Jperio ) THEN                    !* cyclic (only with no mpp j-split) 
    99                ARRAY_IN(:, 1 ,:,:,jf) = ARRAY_IN(:, jpjm1,:,:,jf) 
    100                ARRAY_IN(:,jpj,:,:,jf) = ARRAY_IN(:,   2  ,:,:,jf) 
    101             ELSE                                   !* closed 
    102                IF( .NOT. NAT_IN(jf) == 'F' )   ARRAY_IN(:,     1       :nn_hls,:,:,jf) = zland    ! south except F-point 
    103                                                ARRAY_IN(:,nlcj-nn_hls+1:jpj   ,:,:,jf) = zland    ! north 
     84      llcom_we = nbondi ==  1 .OR. nbondi == 0   ! keep for compatibility, should be defined in mppini 
     85      llcom_ea = nbondi == -1 .OR. nbondi == 0   ! keep for compatibility, should be defined in mppini 
     86      llcom_so = nbondj ==  1 .OR. nbondj == 0   ! keep for compatibility, should be defined in mppini 
     87      llcom_no = nbondj == -1 .OR. nbondj == 0   ! keep for compatibility, should be defined in mppini 
     88       
     89      lldo_nfd = npolj /= 0                      ! keep for compatibility, should be defined in mppini 
     90 
     91      zland = 0._wp                                     ! land filling value: zero by default 
     92      IF( PRESENT( pfillval ) )   zland = pfillval      ! set land value 
     93 
     94      ! define the method we will use to fill the halos in each direction 
     95      IF(               llcom_we ) THEN   ;   ifill_we = jpfillmpi 
     96      ELSEIF(           l_Iperio ) THEN   ;   ifill_we = jpfillperio 
     97      ELSEIF( PRESENT(kfillmode) ) THEN   ;   ifill_we = kfillmode 
     98      ELSE                                ;   ifill_we = jpfillcst 
     99      END IF 
     100      ! 
     101      IF(               llcom_ea ) THEN   ;   ifill_ea = jpfillmpi 
     102      ELSE                                ;   ifill_ea = ifill_we 
     103      END IF 
     104      ! 
     105      IF(               llcom_so ) THEN   ;   ifill_so = jpfillmpi 
     106      ELSEIF(           l_Jperio ) THEN   ;   ifill_so = jpfillperio 
     107      ELSEIF( PRESENT(kfillmode) ) THEN   ;   ifill_so = kfillmode 
     108      ELSE                                ;   ifill_so = jpfillcst 
     109      END IF 
     110      ! 
     111      IF(               llcom_no ) THEN   ;   ifill_no = jpfillmpi 
     112      ELSE                                ;   ifill_no = ifill_so   ! warning will be potentially changed if lldo_nfd = T 
     113      END IF 
     114      ! 
     115#if defined PRINT_CAUTION 
     116      ! 
     117      ! ================================================================================== ! 
     118      ! CAUTION: semi-column notation is often impossible because of the cpp preprocessing ! 
     119      ! ================================================================================== ! 
     120      ! 
     121#endif 
     122      ! 
     123      ! -------------------------------------------------- ! 
     124      !     1. Do east and west MPI exchange if needed     ! 
     125      ! -------------------------------------------------- ! 
     126      ! 
     127      ! these echanges are made for jj = nn_hls+1 to jpj-nn_hls 
     128      isize = nn_hls * ( jpj - 2*nn_hls ) * ipk * ipl * ipf       
     129 
     130      ! Allocate local temporary arrays to be sent/received. Fill arrays to be sent 
     131      IF( ifill_we == jpfillmpi ) THEN   ! copy western side of the inner mpi domain in local temporary array to be sent by MPI 
     132         ! 
     133         ALLOCATE( zsnd_we(nn_hls,jpj-2*nn_hls,ipk,ipl,ipf), zrcv_we(nn_hls,jpj-2*nn_hls,ipk,ipl,ipf) ) 
     134         ishift = nn_hls 
     135         DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = nn_hls+1, jpj-nn_hls   ;   DO ji = 1, nn_hls 
     136            zsnd_we(ji,jj-nn_hls,jk,jl,jf) = ARRAY_IN(ishift+ji,jj,jk,jl,jf)   ! nn_hls + 1 -> 2*nn_hls 
     137         END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO 
     138      ENDIF 
     139      ! 
     140      IF( ifill_ea == jpfillmpi ) THEN   ! copy eastern side of the inner mpi domain in local temporary array to be sent by MPI 
     141         ! 
     142         ALLOCATE( zsnd_ea(nn_hls,jpj-2*nn_hls,ipk,ipl,ipf), zrcv_ea(nn_hls,jpj-2*nn_hls,ipk,ipl,ipf) ) 
     143         ishift = jpi - 2 * nn_hls 
     144         DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = nn_hls+1, jpj-nn_hls   ;   DO ji = 1, nn_hls 
     145            zsnd_ea(ji,jj-nn_hls,jk,jl,jf) = ARRAY_IN(ishift+ji,jj,jk,jl,jf)   ! jpi - 2*nn_hls + 1 -> jpi - nn_hls 
     146         END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO 
     147      ENDIF 
     148      ! 
     149      IF( ln_timing ) CALL tic_tac(.TRUE.) 
     150      ! 
     151      ! non-blocking send of the western/eastern side using local temporary arrays 
     152      IF( ifill_we == jpfillmpi )   CALL mppsend( 1, zsnd_we(1,1,1,1,1), isize, nowe, ireq_we ) 
     153      IF( ifill_ea == jpfillmpi )   CALL mppsend( 2, zsnd_ea(1,1,1,1,1), isize, noea, ireq_ea ) 
     154      ! blocking receive of the western/eastern halo in local temporary arrays 
     155      IF( ifill_we == jpfillmpi )   CALL mpprecv( 2, zrcv_we(1,1,1,1,1), isize, nowe ) 
     156      IF( ifill_ea == jpfillmpi )   CALL mpprecv( 1, zrcv_ea(1,1,1,1,1), isize, noea ) 
     157      ! 
     158      IF( ln_timing ) CALL tic_tac(.FALSE.) 
     159      ! 
     160      ! 
     161      ! ----------------------------------- ! 
     162      !     2. Fill east and west halos     ! 
     163      ! ----------------------------------- ! 
     164      ! 
     165      ! 2.1 fill weastern halo 
     166      ! ---------------------- 
     167      ! ishift = 0                         ! fill halo from ji = 1 to nn_hls 
     168      SELECT CASE ( ifill_we ) 
     169      CASE ( jpfillnothing )               ! no filling  
     170      CASE ( jpfillmpi   )                 ! use data received by MPI  
     171         DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = nn_hls+1, jpj-nn_hls   ;   DO ji = 1, nn_hls 
     172            ARRAY_IN(ji,jj,jk,jl,jf) = zrcv_we(ji,jj-nn_hls,jk,jl,jf)   ! 1 -> nn_hls 
     173         END DO;   END DO   ;   END DO   ;   END DO   ;   END DO 
     174      CASE ( jpfillperio )                 ! use east-weast periodicity 
     175         ishift2 = jpi - 2 * nn_hls 
     176         DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = nn_hls+1, jpj-nn_hls   ;   DO ji = 1, nn_hls 
     177            ARRAY_IN(ji,jj,jk,jl,jf) = ARRAY_IN(ishift2+ji,jj,jk,jl,jf) 
     178         END DO;   END DO   ;   END DO   ;   END DO   ;   END DO 
     179      CASE ( jpfillcopy  )                 ! filling with inner domain values 
     180         DO jf = 1, ipf                               ! number of arrays to be treated 
     181            IF( .NOT. NAT_IN(jf) == 'F' ) THEN        ! do nothing for F point 
     182               DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = nn_hls+1, jpj-nn_hls   ;   DO ji = 1, nn_hls 
     183                  ARRAY_IN(ji,jj,jk,jl,jf) = ARRAY_IN(nn_hls+1,jj,jk,jl,jf) 
     184               END DO   ;   END DO   ;   END DO   ;   END DO 
    104185            ENDIF 
    105186         END DO 
    106          ! 
    107       ENDIF 
    108  
    109       ! ------------------------------- ! 
    110       !      East and west exchange     ! 
    111       ! ------------------------------- ! 
    112       ! we play with the neigbours AND the row number because of the periodicity 
    113       ! 
    114       IF( ABS(nbondi) == 1 ) ALLOCATE( zt3ew(jpj,nn_hls,ipk,ipl,ipf,1), zt3we(jpj,nn_hls,ipk,ipl,ipf,1) ) 
    115       IF(     nbondi  == 0 ) ALLOCATE( zt3ew(jpj,nn_hls,ipk,ipl,ipf,2), zt3we(jpj,nn_hls,ipk,ipl,ipf,2) ) 
    116       ! 
    117       SELECT CASE ( nbondi )      ! Read Dirichlet lateral conditions 
    118       CASE ( -1 ) 
    119          iihom = nlci-nreci 
    120          DO jf = 1, ipf 
    121             DO jl = 1, ipl 
    122                DO jk = 1, ipk 
    123                   DO jh = 1, nn_hls 
    124                      zt3we(:,jh,jk,jl,jf,1) = ARRAY_IN(iihom +jh,:,jk,jl,jf) 
    125                   END DO 
    126                END DO 
    127             END DO 
    128          END DO 
    129       CASE ( 0 ) 
    130          iihom = nlci-nreci 
    131          DO jf = 1, ipf 
    132             DO jl = 1, ipl 
    133                DO jk = 1, ipk 
    134                   DO jh = 1, nn_hls 
    135                      zt3ew(:,jh,jk,jl,jf,1) = ARRAY_IN(nn_hls+jh,:,jk,jl,jf) 
    136                      zt3we(:,jh,jk,jl,jf,1) = ARRAY_IN(iihom +jh,:,jk,jl,jf) 
    137                   END DO 
    138                END DO 
    139             END DO 
    140          END DO 
    141       CASE ( 1 ) 
    142          iihom = nlci-nreci 
    143          DO jf = 1, ipf 
    144             DO jl = 1, ipl 
    145                DO jk = 1, ipk 
    146                   DO jh = 1, nn_hls 
    147                      zt3ew(:,jh,jk,jl,jf,1) = ARRAY_IN(nn_hls+jh,:,jk,jl,jf) 
    148                   END DO 
    149                END DO 
    150             END DO 
     187      CASE ( jpfillcst   )                 ! filling with constant value 
     188         DO jf = 1, ipf                               ! number of arrays to be treated 
     189            IF( .NOT. NAT_IN(jf) == 'F' ) THEN        ! do nothing for F point 
     190               DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = nn_hls+1, jpj-nn_hls   ;   DO ji = 1, nn_hls 
     191                  ARRAY_IN(ji,jj,jk,jl,jf) = zland 
     192               END DO;   END DO   ;   END DO   ;   END DO 
     193            ENDIF 
    151194         END DO 
    152195      END SELECT 
    153       !                           ! Migrations 
    154       imigr = nn_hls * jpj * ipk * ipl * ipf       
    155       ! 
    156       IF( ln_timing ) CALL tic_tac(.TRUE.) 
    157       ! 
    158       SELECT CASE ( nbondi ) 
    159       CASE ( -1 ) 
    160          CALL mppsend( 2, zt3we(1,1,1,1,1,1), imigr, noea, ml_req1 ) 
    161          CALL mpprecv( 1, zt3ew(1,1,1,1,1,1), imigr, noea ) 
    162          IF(l_isend)   CALL mpi_wait(ml_req1, ml_stat, ml_err) 
    163       CASE ( 0 ) 
    164          CALL mppsend( 1, zt3ew(1,1,1,1,1,1), imigr, nowe, ml_req1 ) 
    165          CALL mppsend( 2, zt3we(1,1,1,1,1,1), imigr, noea, ml_req2 ) 
    166          CALL mpprecv( 1, zt3ew(1,1,1,1,1,2), imigr, noea ) 
    167          CALL mpprecv( 2, zt3we(1,1,1,1,1,2), imigr, nowe ) 
    168          IF(l_isend)   CALL mpi_wait(ml_req1, ml_stat, ml_err) 
    169          IF(l_isend)   CALL mpi_wait(ml_req2, ml_stat, ml_err) 
    170       CASE ( 1 ) 
    171          CALL mppsend( 1, zt3ew(1,1,1,1,1,1), imigr, nowe, ml_req1 ) 
    172          CALL mpprecv( 2, zt3we(1,1,1,1,1,1), imigr, nowe ) 
    173          IF(l_isend)   CALL mpi_wait(ml_req1, ml_stat, ml_err ) 
     196      ! 
     197      ! 2.2 fill eastern halo 
     198      ! --------------------- 
     199      ishift = jpi - nn_hls                ! fill halo from ji = jpi-nn_hls+1 to jpi  
     200      SELECT CASE ( ifill_ea ) 
     201      CASE ( jpfillnothing )               ! no filling  
     202      CASE ( jpfillmpi   )                 ! use data received by MPI  
     203         DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = nn_hls+1, jpj-nn_hls   ;   DO ji = 1, nn_hls 
     204            ARRAY_IN(ishift+ji,jj,jk,jl,jf) = zrcv_ea(ji,jj-nn_hls,jk,jl,jf)   ! jpi - nn_hls + 1 -> jpi 
     205         END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO 
     206      CASE ( jpfillperio )                 ! use east-weast periodicity 
     207         ishift2 = nn_hls 
     208         DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = nn_hls+1, jpj-nn_hls   ;   DO ji = 1, nn_hls 
     209            ARRAY_IN(ishift+ji,jj,jk,jl,jf) = ARRAY_IN(ishift2+ji,jj,jk,jl,jf) 
     210         END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO 
     211      CASE ( jpfillcopy  )                 ! filling with inner domain values 
     212         DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = nn_hls+1, jpj-nn_hls   ;   DO ji = 1, nn_hls 
     213            ARRAY_IN(ishift+ji,jj,jk,jl,jf) = ARRAY_IN(ishift,jj,jk,jl,jf) 
     214         END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO 
     215      CASE ( jpfillcst   )                 ! filling with constant value 
     216         DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = nn_hls+1, jpj-nn_hls   ;   DO ji = 1, nn_hls 
     217            ARRAY_IN(ishift+ji,jj,jk,jl,jf) = zland 
     218         END DO;   END DO   ;   END DO   ;   END DO   ;   END DO 
    174219      END SELECT 
    175       ! 
    176       IF( ln_timing ) CALL tic_tac(.FALSE.) 
    177       ! 
    178       !                           ! Write Dirichlet lateral conditions 
    179       iihom = nlci-nn_hls 
    180       ! 
    181       SELECT CASE ( nbondi ) 
    182       CASE ( -1 ) 
    183          DO jf = 1, ipf 
    184             DO jl = 1, ipl 
    185                DO jk = 1, ipk 
    186                   DO jh = 1, nn_hls 
    187                      ARRAY_IN(iihom+jh,:,jk,jl,jf) = zt3ew(:,jh,jk,jl,jf,1) 
    188                   END DO 
    189                END DO 
    190             END DO 
    191          END DO 
    192       CASE ( 0 ) 
    193          DO jf = 1, ipf 
    194             DO jl = 1, ipl 
    195                DO jk = 1, ipk 
    196                   DO jh = 1, nn_hls 
    197                      ARRAY_IN(jh      ,:,jk,jl,jf) = zt3we(:,jh,jk,jl,jf,2) 
    198                      ARRAY_IN(iihom+jh,:,jk,jl,jf) = zt3ew(:,jh,jk,jl,jf,2) 
    199                   END DO 
    200                END DO 
    201             END DO 
    202          END DO 
    203       CASE ( 1 ) 
    204          DO jf = 1, ipf 
    205             DO jl = 1, ipl 
    206                DO jk = 1, ipk 
    207                   DO jh = 1, nn_hls 
    208                      ARRAY_IN(jh      ,:,jk,jl,jf) = zt3we(:,jh,jk,jl,jf,1) 
    209                   END DO 
    210                END DO 
    211             END DO 
    212          END DO 
    213       END SELECT 
    214       ! 
    215       IF( nbondi /= 2 ) DEALLOCATE( zt3ew, zt3we ) 
    216220      ! 
    217221      ! ------------------------------- ! 
    218222      !     3. north fold treatment     ! 
    219223      ! ------------------------------- ! 
     224      ! 
    220225      ! do it before south directions so concerned processes can do it without waiting for the comm with the sourthern neighbor 
    221       IF( npolj /= 0 .AND. .NOT. PRESENT(cd_mpp) ) THEN 
     226      ! 
     227      IF( lldo_nfd .AND. ifill_no /= jpfillnothing ) THEN 
    222228         ! 
    223229         SELECT CASE ( jpni ) 
     
    226232         END SELECT 
    227233         ! 
    228       ENDIF 
    229       ! 
    230       ! ------------------------------- ! 
    231       !  4. North and south directions  ! 
    232       ! ------------------------------- ! 
    233       ! always closed : we play only with the neigbours 
    234       ! 
    235       IF( ABS(nbondj) == 1 ) ALLOCATE( zt3ns(jpi,nn_hls,ipk,ipl,ipf,1), zt3sn(jpi,nn_hls,ipk,ipl,ipf,1) ) 
    236       IF(     nbondj  == 0 ) ALLOCATE( zt3ns(jpi,nn_hls,ipk,ipl,ipf,2), zt3sn(jpi,nn_hls,ipk,ipl,ipf,2) ) 
    237       ! 
    238       SELECT CASE ( nbondj ) 
    239       CASE ( -1 ) 
    240          ijhom = nlcj-nrecj 
    241          DO jf = 1, ipf 
    242             DO jl = 1, ipl 
    243                DO jk = 1, ipk 
    244                   DO jh = 1, nn_hls 
    245                      zt3sn(:,jh,jk,jl,jf,1) = ARRAY_IN(:,ijhom +jh,jk,jl,jf) 
    246                   END DO 
    247                END DO 
    248             END DO 
     234         ifill_no = jpfillnothing  ! force to do nothing for the northern halo as we just done the north pole folding 
     235         ! 
     236      ENDIF 
     237      ! 
     238      ! ---------------------------------------------------- ! 
     239      !     4. Do north and south MPI exchange if needed     ! 
     240      ! ---------------------------------------------------- ! 
     241      ! 
     242      isize = jpi * nn_hls * ipk * ipl * ipf       
     243 
     244      ! allocate local temporary arrays to be sent/received. Fill arrays to be sent 
     245      IF( ifill_so == jpfillmpi ) THEN   ! copy sourhern side of the inner mpi domain in local temporary array to be sent by MPI 
     246         ! 
     247         ALLOCATE( zsnd_so(jpi,nn_hls,ipk,ipl,ipf), zrcv_so(jpi,nn_hls,ipk,ipl,ipf) ) 
     248         ishift = nn_hls 
     249         DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, nn_hls   ;   DO ji = 1, jpi 
     250            zsnd_so(ji,jj,jk,jl,jf) = ARRAY_IN(ji,ishift+jj,jk,jl,jf)   ! nn_hls+1 -> 2*nn_hls 
     251         END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO 
     252      ENDIF 
     253      ! 
     254      IF( ifill_no == jpfillmpi ) THEN   ! copy eastern side of the inner mpi domain in local temporary array to be sent by MPI 
     255         ! 
     256         ALLOCATE( zsnd_no(jpi,nn_hls,ipk,ipl,ipf), zrcv_no(jpi,nn_hls,ipk,ipl,ipf) ) 
     257         ishift = jpj - 2 * nn_hls 
     258         DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, nn_hls   ;   DO ji = 1, jpi 
     259            zsnd_no(ji,jj,jk,jl,jf) = ARRAY_IN(ji,ishift+jj,jk,jl,jf)   ! jpj-2*nn_hls+1 -> jpj-nn_hls 
     260         END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO 
     261      ENDIF 
     262      ! 
     263      IF( ln_timing ) CALL tic_tac(.TRUE.) 
     264      ! 
     265      ! non-blocking send of the southern/northern side 
     266      IF( ifill_so == jpfillmpi )   CALL mppsend( 3, zsnd_so(1,1,1,1,1), isize, noso, ireq_so ) 
     267      IF( ifill_no == jpfillmpi )   CALL mppsend( 4, zsnd_no(1,1,1,1,1), isize, nono, ireq_no ) 
     268      ! blocking receive of the southern/northern halo 
     269      IF( ifill_so == jpfillmpi )   CALL mpprecv( 4, zrcv_so(1,1,1,1,1), isize, noso ) 
     270      IF( ifill_no == jpfillmpi )   CALL mpprecv( 3, zrcv_no(1,1,1,1,1), isize, nono ) 
     271      ! 
     272      IF( ln_timing ) CALL tic_tac(.FALSE.) 
     273      ! 
     274      ! ------------------------------------- ! 
     275      !     5. Fill south and north halos     ! 
     276      ! ------------------------------------- ! 
     277      ! 
     278      ! 5.1 fill southern halo 
     279      ! ---------------------- 
     280      ! ishift = 0                         ! fill halo from jj = 1 to nn_hls 
     281      SELECT CASE ( ifill_so ) 
     282      CASE ( jpfillnothing )               ! no filling  
     283      CASE ( jpfillmpi   )                 ! use data received by MPI  
     284         DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, nn_hls   ;   DO ji = 1, jpi 
     285            ARRAY_IN(ji,jj,jk,jl,jf) = zrcv_so(ji,jj,jk,jl,jf)   ! 1 -> nn_hls 
     286         END DO;   END DO   ;   END DO   ;   END DO   ;   END DO 
     287      CASE ( jpfillperio )                 ! use north-south periodicity 
     288         ishift2 = jpj - 2 * nn_hls 
     289         DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, nn_hls   ;   DO ji = 1, jpi 
     290            ARRAY_IN(ji,jj,jk,jl,jf) = ARRAY_IN(ji,ishift2+jj,jk,jl,jf) 
     291         END DO;   END DO   ;   END DO   ;   END DO   ;   END DO 
     292      CASE ( jpfillcopy  )                 ! filling with inner domain values 
     293         DO jf = 1, ipf                               ! number of arrays to be treated 
     294            IF( .NOT. NAT_IN(jf) == 'F' ) THEN        ! do nothing for F point 
     295               DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, nn_hls   ;   DO ji = 1, jpi 
     296                  ARRAY_IN(ji,jj,jk,jl,jf) = ARRAY_IN(ji,nn_hls+1,jk,jl,jf) 
     297               END DO   ;   END DO   ;   END DO   ;   END DO 
     298            ENDIF 
    249299         END DO 
    250       CASE ( 0 ) 
    251          ijhom = nlcj-nrecj 
    252          DO jf = 1, ipf 
    253             DO jl = 1, ipl 
    254                DO jk = 1, ipk 
    255                   DO jh = 1, nn_hls 
    256                      zt3sn(:,jh,jk,jl,jf,1) = ARRAY_IN(:,ijhom +jh,jk,jl,jf) 
    257                      zt3ns(:,jh,jk,jl,jf,1) = ARRAY_IN(:,nn_hls+jh,jk,jl,jf) 
    258                   END DO 
    259                END DO 
    260             END DO 
    261          END DO 
    262       CASE ( 1 ) 
    263          ijhom = nlcj-nrecj 
    264          DO jf = 1, ipf 
    265             DO jl = 1, ipl 
    266                DO jk = 1, ipk 
    267                   DO jh = 1, nn_hls 
    268                      zt3ns(:,jh,jk,jl,jf,1) = ARRAY_IN(:,nn_hls+jh,jk,jl,jf) 
    269                   END DO 
    270                END DO 
    271             END DO 
     300      CASE ( jpfillcst   )                 ! filling with constant value 
     301         DO jf = 1, ipf                               ! number of arrays to be treated 
     302            IF( .NOT. NAT_IN(jf) == 'F' ) THEN        ! do nothing for F point 
     303               DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, nn_hls   ;   DO ji = 1, jpi  
     304                  ARRAY_IN(ji,jj,jk,jl,jf) = zland 
     305               END DO;   END DO   ;   END DO   ;   END DO 
     306            ENDIF 
    272307         END DO 
    273308      END SELECT 
    274309      ! 
    275       !                           ! Migrations 
    276       imigr = nn_hls * jpi * ipk * ipl * ipf 
    277       ! 
    278       IF( ln_timing ) CALL tic_tac(.TRUE.) 
    279       !  
    280       SELECT CASE ( nbondj ) 
    281       CASE ( -1 ) 
    282          CALL mppsend( 4, zt3sn(1,1,1,1,1,1), imigr, nono, ml_req1 ) 
    283          CALL mpprecv( 3, zt3ns(1,1,1,1,1,1), imigr, nono ) 
    284          IF(l_isend) CALL mpi_wait(ml_req1, ml_stat, ml_err ) 
    285       CASE ( 0 ) 
    286          CALL mppsend( 3, zt3ns(1,1,1,1,1,1), imigr, noso, ml_req1 ) 
    287          CALL mppsend( 4, zt3sn(1,1,1,1,1,1), imigr, nono, ml_req2 ) 
    288          CALL mpprecv( 3, zt3ns(1,1,1,1,1,2), imigr, nono ) 
    289          CALL mpprecv( 4, zt3sn(1,1,1,1,1,2), imigr, noso ) 
    290          IF(l_isend)   CALL mpi_wait(ml_req1, ml_stat, ml_err ) 
    291          IF(l_isend)   CALL mpi_wait(ml_req2, ml_stat, ml_err ) 
    292       CASE ( 1 ) 
    293          CALL mppsend( 3, zt3ns(1,1,1,1,1,1), imigr, noso, ml_req1 ) 
    294          CALL mpprecv( 4, zt3sn(1,1,1,1,1,1), imigr, noso ) 
    295          IF(l_isend)   CALL mpi_wait(ml_req1, ml_stat, ml_err ) 
     310      ! 5.2 fill northern halo 
     311      ! ---------------------- 
     312      ishift = jpj - nn_hls                ! fill halo from jj = jpj-nn_hls+1 to jpj  
     313      SELECT CASE ( ifill_no ) 
     314      CASE ( jpfillnothing )               ! no filling  
     315      CASE ( jpfillmpi   )                 ! use data received by MPI  
     316         DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, nn_hls   ;   DO ji = 1, jpi 
     317            ARRAY_IN(ji,ishift+jj,jk,jl,jf) = zrcv_no(ji,jj,jk,jl,jf)   ! jpj-nn_hls+1 -> jpj 
     318         END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO 
     319      CASE ( jpfillperio )                 ! use north-south periodicity 
     320         ishift2 = nn_hls 
     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,ishift+jj,jk,jl,jf) = ARRAY_IN(ji,ishift2+jj,jk,jl,jf) 
     323         END DO;   END DO   ;   END DO   ;   END DO   ;   END DO 
     324      CASE ( jpfillcopy  )                 ! filling with inner domain values 
     325         DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, nn_hls   ;   DO ji = 1, jpi 
     326            ARRAY_IN(ji,ishift+jj,jk,jl,jf) = ARRAY_IN(ji,ishift,jk,jl,jf) 
     327         END DO;   END DO   ;   END DO   ;   END DO   ;   END DO 
     328      CASE ( jpfillcst   )                 ! filling with constant value 
     329         DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, nn_hls   ;   DO ji = 1, jpi 
     330            ARRAY_IN(ji,ishift+jj,jk,jl,jf) = zland 
     331         END DO;   END DO   ;   END DO   ;   END DO   ;   END DO 
    296332      END SELECT 
    297333      ! 
    298       IF( ln_timing ) CALL tic_tac(.FALSE.) 
    299       !                           ! Write Dirichlet lateral conditions 
    300       ijhom = nlcj-nn_hls 
    301       ! 
    302       SELECT CASE ( nbondj ) 
    303       CASE ( -1 ) 
    304          DO jf = 1, ipf 
    305             DO jl = 1, ipl 
    306                DO jk = 1, ipk 
    307                   DO jh = 1, nn_hls 
    308                      ARRAY_IN(:,ijhom+jh,jk,jl,jf) = zt3ns(:,jh,jk,jl,jf,1) 
    309                   END DO 
    310                END DO 
    311             END DO 
    312          END DO 
    313       CASE ( 0 ) 
    314          DO jf = 1, ipf 
    315             DO jl = 1, ipl 
    316                DO jk = 1, ipk 
    317                   DO jh = 1, nn_hls 
    318                      ARRAY_IN(:,      jh,jk,jl,jf) = zt3sn(:,jh,jk,jl,jf,2) 
    319                      ARRAY_IN(:,ijhom+jh,jk,jl,jf) = zt3ns(:,jh,jk,jl,jf,2) 
    320                   END DO 
    321                END DO 
    322             END DO 
    323          END DO 
    324       CASE ( 1 ) 
    325          DO jf = 1, ipf 
    326             DO jl = 1, ipl 
    327                DO jk = 1, ipk 
    328                   DO jh = 1, nn_hls 
    329                      ARRAY_IN(:,jh,jk,jl,jf) = zt3sn(:,jh,jk,jl,jf,1) 
    330                   END DO 
    331                END DO 
    332             END DO 
    333          END DO 
    334       END SELECT 
    335       ! 
    336       IF( nbondj /= 2 ) DEALLOCATE( zt3ns, zt3sn ) 
     334      ! -------------------------------------------- ! 
     335      !     6. deallocate local temporary arrays     ! 
     336      ! -------------------------------------------- ! 
     337      ! 
     338      IF( ifill_we == jpfillmpi ) THEN 
     339         CALL mpi_wait(ireq_we, istat, ierr ) 
     340         DEALLOCATE( zsnd_we, zrcv_we ) 
     341      ENDIF 
     342      IF( ifill_ea == jpfillmpi )  THEN 
     343         CALL mpi_wait(ireq_ea, istat, ierr ) 
     344         DEALLOCATE( zsnd_ea, zrcv_ea ) 
     345      ENDIF 
     346      IF( ifill_so == jpfillmpi ) THEN 
     347         CALL mpi_wait(ireq_so, istat, ierr ) 
     348         DEALLOCATE( zsnd_so, zrcv_so ) 
     349      ENDIF 
     350      IF( ifill_no == jpfillmpi ) THEN 
     351         CALL mpi_wait(ireq_no, istat, ierr ) 
     352         DEALLOCATE( zsnd_no, zrcv_no ) 
     353      ENDIF 
    337354      ! 
    338355   END SUBROUTINE ROUTINE_LNK 
Note: See TracChangeset for help on using the changeset viewer.