SUBROUTINE PRE_SLADREP(KSLB2,PGFLT1,PSLBUF2,&
 & PGMVT1X,PGMVT1SX,PGFLT1X,PSLBUF2X)  
!    -------------------------------------------------------------------
USE PARKIND1  ,ONLY : JPIM     ,JPRB
USE YOMHOOK   ,ONLY : LHOOK,   DR_HOOK

USE YOMCT0   , ONLY : NPROC    ,LELAM
USE YOMDIM   , ONLY : NFLEVG   ,NPROMA   ,NGPBLKS
USE YOMSC2   , ONLY : NFLDSLB2
USE YOMMP    , ONLY : NASLB1   ,NSENDPTR,NRECVPTR,NSLRECVPOS,NSLCOMM,&
 & NSLSENDPOS,NSLPROCS,NSLCORE,NSLSPT,NSLRPT
USE YOMSLREP , ONLY : NGPTOTAD  ,NADCORE
USE YOMGEM   , ONLY : NGPTOT    ,NGPTOT_CAP
USE YOMMASK  , ONLY : MASK_SL1,MASK_SL2, NFIXSFLD, LSLONDEM
USE YOMGMV   , ONLY : GMVT1,GMVT1S,YT1
USE YOM_YGFL , ONLY : YGFL

!**** *PRE_SLADREP*

!     Purpose.
!     --------
!        Distributed memory communications for GFL and GMV variables.

!**   Interface.
!     ----------
!        *CALL* *PRE_SLADREP(..)

!        Explicit arguments :
!        --------------------

!        INPUT:
!          KSLB2       - Third dimension for PSLBUF2X,PGMVT1X,PGFLT1X
!          PGFLT1      - input "t+dt" GFL variables.
!          PSLBUF2     - input "SLB2" buffer.

!        OUTPUT:
!          PGMVT1X     - output "t+dt" upper air GMV variables.
!          PGMVT1SX    - output "t+dt" surface GMV variables.
!          PGFLT1X     - output "t+dt" GFL variables.
!          PSLBUF2X    - output "SLB2" buffer.

!        Implicit arguments :
!        --------------------

!     Method.
!     -------
!        See documentation

!     Externals.
!     ----------
!           see code below

!     Reference.
!     ----------
!             Arpege documentation.

!     Author.
!     -------
!        ???

!     Modifications.
!     --------------
!        Original : AUGUST 2003.
!        M.Hamrud      01-Oct-2003 CY28 Cleaning
!   04-Jun-2007 M. Jidane  : Fix NSLCORE bug
!   K. Yessad Dec 2008: merge SLCOMM+SLCOMM1 -> SLCOMM.
!     ------------------------------------------------------------------

IMPLICIT NONE

INTEGER(KIND=JPIM),INTENT(IN)    :: KSLB2 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PGFLT1(NPROMA,NFLEVG,YGFL%NDIM1,NGPBLKS) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PSLBUF2(NPROMA,NFLDSLB2,NGPBLKS) 
REAL(KIND=JPRB)   ,INTENT(OUT)   :: PGMVT1X(NPROMA,NFLEVG,YT1%NDIM,KSLB2) 
REAL(KIND=JPRB)   ,INTENT(OUT)   :: PGMVT1SX(NPROMA,YT1%NDIMS,KSLB2) 
REAL(KIND=JPRB)   ,INTENT(OUT)   :: PGFLT1X(NPROMA,NFLEVG,YGFL%NDIM1,KSLB2) 
REAL(KIND=JPRB)   ,INTENT(OUT)   :: PSLBUF2X(NPROMA,NFLDSLB2,KSLB2) 

!     ------------------------------------------------------------------

INTEGER(KIND=JPIM) :: IBL,JKGLO, JROF, JLEV,JFLD,IFP,IFLDSLBTEMP,IDUMARR(2)
REAL(KIND=JPRB), ALLOCATABLE :: ZSLBUFTEMP(:,:)
LOGICAL :: LLINC
REAL(KIND=JPRB) :: ZHOOK_HANDLE
INTEGER(KIND=JPIM) :: IGPCOMP

!     ------------------------------------------------------------------

#include "slcomm.intfb.h"
#include "slcomm2.intfb.h"

!    -------------------------------------------------------------------
IF (LHOOK) CALL DR_HOOK('PRE_SLADREP',0,ZHOOK_HANDLE)
!    -------------------------------------------------------------------

!       Build PSLBUF2X from PSLBUF2 contained on neighbouring processors
!       spanning standard nslwide halo

!    -------------------------------------------------------------------

IFLDSLBTEMP=NFLDSLB2+NFLEVG*YT1%NDIM+YT1%NDIMS+NFLEVG*YGFL%NDIM1
ALLOCATE (ZSLBUFTEMP(NASLB1,IFLDSLBTEMP))
CALL GSTATS(1014,0)
! Changed NGPTOT into IGPCOMP in order to pass properly
! the scan of NSLCORE values for the LAM models
IF(.NOT.LELAM) THEN
  IGPCOMP=NGPTOT
ELSE
  IGPCOMP=MIN(NGPTOT,NGPTOT_CAP)
ENDIF
!$OMP PARALLEL DO SCHEDULE(DYNAMIC,1) PRIVATE(JKGLO,IBL,JROF,JFLD,IFP,JLEV)
DO JKGLO=1,IGPCOMP,NPROMA
  IBL=(JKGLO-1)/NPROMA+1
  DO JFLD=1,NFLDSLB2
    DO JROF=JKGLO,MIN(JKGLO-1+NPROMA,IGPCOMP)
      ZSLBUFTEMP(NSLCORE(JROF),JFLD)=PSLBUF2(JROF-JKGLO+1,JFLD,IBL)
    ENDDO
  ENDDO
  IFP=NFLDSLB2
  DO JFLD=1,YT1%NDIM
    DO JLEV=1,NFLEVG
      IFP=IFP+1
      DO JROF=JKGLO,MIN(JKGLO-1+NPROMA,IGPCOMP)
        ZSLBUFTEMP(NSLCORE(JROF),IFP)=GMVT1(JROF-JKGLO+1,JLEV,JFLD,IBL)
      ENDDO
    ENDDO
  ENDDO
  DO JFLD=1,YT1%NDIMS
    IFP=IFP+1
    DO JROF=JKGLO,MIN(JKGLO-1+NPROMA,IGPCOMP)
      ZSLBUFTEMP(NSLCORE(JROF),IFP)=GMVT1S(JROF-JKGLO+1,JFLD,IBL)
    ENDDO
  ENDDO
  DO JFLD=1,YGFL%NDIM1
    DO JLEV=1,NFLEVG
      IFP=IFP+1
      DO JROF=JKGLO,MIN(JKGLO-1+NPROMA,IGPCOMP)
        ZSLBUFTEMP(NSLCORE(JROF),IFP)=PGFLT1(JROF-JKGLO+1,JLEV,JFLD,IBL)
      ENDDO
    ENDDO
  ENDDO
ENDDO
!$OMP END PARALLEL DO
CALL GSTATS(1014,1)
  
IF(LSLONDEM)THEN

  IF(.NOT.ALLOCATED(MASK_SL2)) ALLOCATE(MASK_SL2(NASLB1+4))
  
  MASK_SL2(:)=0

  DO JROF=1,NGPTOTAD
    MASK_SL2(NADCORE(JROF))=1
  ENDDO
  
  NFIXSFLD(1)=1
  NFIXSFLD(2)=0

  IF (NPROC > 1) THEN
    LLINC=.FALSE.
    CALL GSTATS(35,2)
    CALL GSTATS(85,0)
    CALL SLCOMM2(NASLB1,NSLPROCS,NSLRPT,&
     & NSLSPT,NSLSENDPOS,NSLRECVPOS,NSENDPTR,NRECVPTR,NSLCOMM,&
     & NFIXSFLD,MASK_SL1,MASK_SL2,&
     & IFLDSLBTEMP,LLINC,ZSLBUFTEMP)  
    CALL GSTATS(85,1)
    CALL GSTATS(35,3)
  ENDIF
  
ELSE

  IF (NPROC > 1) THEN
    LLINC=.FALSE.
    CALL GSTATS(35,2)
    CALL GSTATS(85,0)
    CALL SLCOMM(NASLB1,NSLPROCS,NSLRPT,&
     & NSLSPT,NSLSENDPOS,NSLRECVPOS,NSENDPTR,NRECVPTR,NSLCOMM,&
     & IDUMARR,IFLDSLBTEMP,LLINC,0,ZSLBUFTEMP)  
    CALL GSTATS(85,1)
    CALL GSTATS(35,3)
  ENDIF
  
ENDIF
  
CALL GSTATS(1015,0)
!$OMP PARALLEL DO SCHEDULE(DYNAMIC,1) PRIVATE(JKGLO,IBL,JROF,JFLD,JLEV,IFP)
DO JKGLO=1,NGPTOTAD,NPROMA
  IBL=(JKGLO-1)/NPROMA+1
  DO JFLD=1,NFLDSLB2
    DO JROF=JKGLO,MIN(JKGLO-1+NPROMA,NGPTOTAD)
      PSLBUF2X(JROF-JKGLO+1,JFLD,IBL)=ZSLBUFTEMP(NADCORE(JROF),JFLD)
    ENDDO
  ENDDO
  IFP=NFLDSLB2
  DO JFLD=1,YT1%NDIM
    DO JLEV=1,NFLEVG
      IFP=IFP+1
      DO JROF=JKGLO,MIN(JKGLO-1+NPROMA,NGPTOTAD)
        PGMVT1X(JROF-JKGLO+1,JLEV,JFLD,IBL)=ZSLBUFTEMP(NADCORE(JROF),IFP)
      ENDDO
    ENDDO
  ENDDO
  DO JFLD=1,YT1%NDIMS
    IFP=IFP+1
    DO JROF=JKGLO,MIN(JKGLO-1+NPROMA,NGPTOTAD)
      PGMVT1SX(JROF-JKGLO+1,JFLD,IBL)=ZSLBUFTEMP(NADCORE(JROF),IFP)
    ENDDO
  ENDDO
  DO JFLD=1,YGFL%NDIM1
    DO JLEV=1,NFLEVG
      IFP=IFP+1
      DO JROF=JKGLO,MIN(JKGLO-1+NPROMA,NGPTOTAD)
        PGFLT1X(JROF-JKGLO+1,JLEV,JFLD,IBL)=ZSLBUFTEMP(NADCORE(JROF),IFP)
      ENDDO
    ENDDO
  ENDDO
ENDDO
!$OMP END PARALLEL DO
CALL GSTATS(1015,1)
DEALLOCATE(ZSLBUFTEMP)

!     ------------------------------------------------------------------
IF (LHOOK) CALL DR_HOOK('PRE_SLADREP',1,ZHOOK_HANDLE)
END SUBROUTINE PRE_SLADREP
