      SUBROUTINE gm_cart_shift ( ldim,  nbdims,  jdims,  coords,  periods,  iav,  iap  )
!
! Calcul du rang des deux voisins immediats
!
      IMPLICIT NONE
!
! Declaration des arguments
!
! Nombre de processus total
      INTEGER,                        INTENT(IN)   ::  ldim
!
! Nombre de directions spatiales
      INTEGER,                        INTENT(IN)   ::  nbdims
!
! Nombre de processus par direction spatiale
      INTEGER,  DIMENSION(1:nbdims),  INTENT(IN)   ::  jdims
!
! Coordonnees du processus courant dans la topologie cartesienne
      INTEGER,  DIMENSION(1:nbdims),  INTENT(IN)   ::  coords
!
! Periodicite des directions spatiales
      LOGICAL,  DIMENSION(1:nbdims),  INTENT(IN)   ::  periods
!
! Rang du processus voisin "gauche"
      INTEGER,                        INTENT(OUT)  ::  iav
!
! Rang du processus voisin "droit"
      INTEGER,                        INTENT(OUT)  ::  iap
!
! Declaration des variables locales
!
      INTEGER,  DIMENSION(1:nbdims)  ::  ic2
!
      INTEGER  ::  bloc
      INTEGER  ::  k
!
! Debut de la subroutine
!
      ic2(1:nbdims) = coords(1:nbdims)
!
! Calcul du rang du processus "gauche"
      IF( ic2(ldim) == 0 ) THEN
!
! Si periodicite dans la direction ...
        IF( periods(ldim) ) THEN
!
          ic2(ldim) = jdims(ldim) - 1
          iav = 0
          bloc = 1
          DO k = 1, nbdims
             iav = iav + bloc * ic2(k)
             bloc = bloc * jdims(k)
          END DO
!
        ELSE
!
          iav = -1
!
        END IF
!
      ELSE
!
        ic2(ldim) = ic2(ldim) - 1
        iav = 0
        bloc = 1
        DO k = 1, nbdims
           iav = iav + bloc * ic2(k)
           bloc = bloc * jdims(k)
        END DO
!
      END IF
!
      ic2(1:nbdims) = coords(1:nbdims)
!
! Calcul du rang du processus "droit"
      IF( ic2(ldim) == jdims(ldim) - 1 ) THEN
!
! Si periodicite dans la direction ...
        IF( periods(ldim) ) THEN
!
          ic2(ldim) = 0
          iap = 0
          bloc = 1
          DO k = 1, nbdims
             iap = iap + bloc * ic2(k)
             bloc = bloc * jdims(k)
          END DO
!
        ELSE
!
          iap = -1
!
        END IF
!
      ELSE
!
        ic2(ldim) = ic2(ldim) + 1
        iap = 0
        bloc = 1
        DO k = 1, nbdims
           iap = iap + bloc * ic2(k)
           bloc = bloc * jdims(k)
        END DO
!
      END IF
!
! Fin   de la subroutine
!
      RETURN
      END SUBROUTINE gm_cart_shift

