SUBROUTINE GATHERGOM(KSUR,KCON,KTOV,KSCA,&
 & PSURU,PSURV,PSURT,PSURQ,PSURO3,PSURCLW,PSURGHG,PSURGRG,PSURAERO,PSURPS,&
 & PCONU,PCONV,PCONT,PCONQ,PCONO3,PCONCLW,PCONGHG,PCONGRG,PCONAERO,&
 & PCONSW,PCONRW,PCONGW,PCONPS,&
 & PTOVU,PTOVV,PTOVT,PTOVQ,PTOVO3,PTOVCLW,PTOVGHG,PTOVGRG,PTOVAERO,PTOVPS,&
 & PSCAU,PSCAV,PSCAUN,PSCAVN,PSCAT,PSCAQ,PSCAPS)  

!****  GATHERGOM - gather rms of gom-arrays for PRTGOM

!     M.Hamrud          19/07/96       ECMWF

!     PURPOSE
!     -------
!       Receive and accumulate rms values of gom-arrays from all PE's
!       This diagnostic is not totally identical on the different PE's
!       or if NPROC is changed due to ordering of summations.

!**   INTERFACE
!     ---------

!      CALL GATHERGOM(....)

!     Explicit arguments :
!     --------------------
!        All arguments are data variables or arrays received from 
!        other PE's and added to this PE's data values.

!**   METHOD
!     ------

!**   EXTERNALS   MPL_SEND
!     ---------   MPL_RECV

!**   MODIFICATIONS
!     -------------
!     E.Andersson 980818 : Introduce CLW
!     D.Dent      00-09-01:  MPE to MPL conversion
!     A.Dethof    18-May-05  Add GRG
!     R.Engelen   07-Jul-05  Add GHG
!     A.Benedetti 30-Aug-05  Add AERO
!     H.Hersbach  12-Feb-10  Add Neutral wind for SCAT

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

USE PARKIND1  ,ONLY : JPIM     ,JPRB

USE YOMHOOK   ,ONLY : LHOOK,   DR_HOOK

USE YOMDIM   , ONLY : NFLEVG
USE YOMCT0   , ONLY : NPROC
USE YOMMP    , ONLY : NPRCIDS  ,MYPROC
USE YOMTAG   , ONLY : MTAGGOM
USE MPL_MODULE
USE YOM_YGFL , ONLY : NGHG, NGRG, NAERO

IMPLICIT NONE

INTEGER(KIND=JPIM),INTENT(INOUT) :: KSUR 
INTEGER(KIND=JPIM),INTENT(INOUT) :: KCON 
INTEGER(KIND=JPIM),INTENT(INOUT) :: KTOV 
INTEGER(KIND=JPIM),INTENT(INOUT) :: KSCA 
REAL(KIND=JPRB)   ,INTENT(INOUT) :: PSURU(NFLEVG) 
REAL(KIND=JPRB)   ,INTENT(INOUT) :: PSURV(NFLEVG) 
REAL(KIND=JPRB)   ,INTENT(INOUT) :: PSURT(NFLEVG) 
REAL(KIND=JPRB)   ,INTENT(INOUT) :: PSURQ(NFLEVG) 
REAL(KIND=JPRB)   ,INTENT(INOUT) :: PSURO3(NFLEVG) 
REAL(KIND=JPRB)   ,INTENT(INOUT) :: PSURCLW(NFLEVG) 
REAL(KIND=JPRB)   ,INTENT(INOUT) :: PSURGHG(NFLEVG,NGHG) 
REAL(KIND=JPRB)   ,INTENT(INOUT) :: PSURAERO(NFLEVG,NAERO) 
REAL(KIND=JPRB)   ,INTENT(INOUT) :: PSURGRG(NFLEVG,NGRG) 
REAL(KIND=JPRB)   ,INTENT(INOUT) :: PSURPS(NFLEVG) 
REAL(KIND=JPRB)   ,INTENT(INOUT) :: PCONU(NFLEVG) 
REAL(KIND=JPRB)   ,INTENT(INOUT) :: PCONV(NFLEVG) 
REAL(KIND=JPRB)   ,INTENT(INOUT) :: PCONT(NFLEVG) 
REAL(KIND=JPRB)   ,INTENT(INOUT) :: PCONQ(NFLEVG) 
REAL(KIND=JPRB)   ,INTENT(INOUT) :: PCONO3(NFLEVG) 
REAL(KIND=JPRB)   ,INTENT(INOUT) :: PCONCLW(NFLEVG) 
REAL(KIND=JPRB)   ,INTENT(INOUT) :: PCONGHG(NFLEVG,NGHG) 
REAL(KIND=JPRB)   ,INTENT(INOUT) :: PCONAERO(NFLEVG,NAERO) 
 REAL(KIND=JPRB)   ,INTENT(INOUT) :: PCONGRG(NFLEVG,NGRG) 
REAL(KIND=JPRB)   ,INTENT(INOUT) :: PCONSW(NFLEVG)
REAL(KIND=JPRB)   ,INTENT(INOUT) :: PCONRW(NFLEVG)
REAL(KIND=JPRB)   ,INTENT(INOUT) :: PCONGW(NFLEVG)
REAL(KIND=JPRB)   ,INTENT(INOUT) :: PCONPS(NFLEVG) 
REAL(KIND=JPRB)   ,INTENT(INOUT) :: PTOVU(NFLEVG) 
REAL(KIND=JPRB)   ,INTENT(INOUT) :: PTOVV(NFLEVG) 
REAL(KIND=JPRB)   ,INTENT(INOUT) :: PTOVT(NFLEVG) 
REAL(KIND=JPRB)   ,INTENT(INOUT) :: PTOVQ(NFLEVG) 
REAL(KIND=JPRB)   ,INTENT(INOUT) :: PTOVO3(NFLEVG) 
REAL(KIND=JPRB)   ,INTENT(INOUT) :: PTOVCLW(NFLEVG) 
REAL(KIND=JPRB)   ,INTENT(INOUT) :: PTOVGHG(NFLEVG,NGHG) 
REAL(KIND=JPRB)   ,INTENT(INOUT) :: PTOVAERO(NFLEVG,NAERO) 
REAL(KIND=JPRB)   ,INTENT(INOUT) :: PTOVGRG(NFLEVG,NGRG) 
REAL(KIND=JPRB)   ,INTENT(INOUT) :: PTOVPS(NFLEVG) 
REAL(KIND=JPRB)   ,INTENT(INOUT) :: PSCAU 
REAL(KIND=JPRB)   ,INTENT(INOUT) :: PSCAV 
REAL(KIND=JPRB)   ,INTENT(INOUT) :: PSCAUN 
REAL(KIND=JPRB)   ,INTENT(INOUT) :: PSCAVN 
REAL(KIND=JPRB)   ,INTENT(INOUT) :: PSCAT 
REAL(KIND=JPRB)   ,INTENT(INOUT) :: PSCAQ 
REAL(KIND=JPRB)   ,INTENT(INOUT) :: PSCAPS 
REAL(KIND=JPRB) :: ZSENDBUF(24*NFLEVG+3*NGHG*NFLEVG+3*NGRG*NFLEVG+3*NAERO*NFLEVG+11)
REAL(KIND=JPRB) :: ZRECVBUF(24*NFLEVG+3*NGHG*NFLEVG+3*NGRG*NFLEVG+3*NAERO*NFLEVG+11)

INTEGER(KIND=JPIM) :: ISENDBUF,IRECVBUF,IOFF,ITAG,ISEND,IRECV
INTEGER(KIND=JPIM) :: JROC,JGHG,JGRG,JAERO
REAL(KIND=JPRB) :: ZHOOK_HANDLE

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


ISENDBUF = SIZE(ZSENDBUF)
IRECVBUF = SIZE(ZRECVBUF)

!*       1.1      FILL SEND BUFFER

IOFF = 1
ZSENDBUF(IOFF) = KSUR
IOFF = IOFF+1
ZSENDBUF(IOFF) = KCON
IOFF = IOFF+1
ZSENDBUF(IOFF) = KTOV
IOFF = IOFF+1
ZSENDBUF(IOFF) = KSCA
IOFF = IOFF+1

ZSENDBUF(IOFF:IOFF+NFLEVG-1) = PSURU(:)
IOFF = IOFF+NFLEVG
ZSENDBUF(IOFF:IOFF+NFLEVG-1) = PSURV(:)
IOFF = IOFF+NFLEVG
ZSENDBUF(IOFF:IOFF+NFLEVG-1) = PSURT(:)
IOFF = IOFF+NFLEVG
ZSENDBUF(IOFF:IOFF+NFLEVG-1) = PSURQ(:)
IOFF = IOFF+NFLEVG
ZSENDBUF(IOFF:IOFF+NFLEVG-1) = PSURO3(:)
IOFF = IOFF+NFLEVG
ZSENDBUF(IOFF:IOFF+NFLEVG-1) = PSURCLW(:)
IOFF = IOFF+NFLEVG
DO JGHG=1,NGHG
  ZSENDBUF(IOFF:IOFF+NFLEVG-1) = PSURGHG(:,JGHG)
  IOFF = IOFF+NFLEVG
ENDDO
DO JGRG=1,NGRG
  ZSENDBUF(IOFF:IOFF+NFLEVG-1) = PSURGRG(:,JGRG)
  IOFF = IOFF+NFLEVG
ENDDO
DO JAERO=1,NAERO
  ZSENDBUF(IOFF:IOFF+NFLEVG-1) = PSURAERO(:,JAERO)
  IOFF = IOFF+NFLEVG
ENDDO
ZSENDBUF(IOFF:IOFF+NFLEVG-1) = PSURPS(:)
IOFF = IOFF+NFLEVG

ZSENDBUF(IOFF:IOFF+NFLEVG-1) = PCONU(:)
IOFF = IOFF+NFLEVG
ZSENDBUF(IOFF:IOFF+NFLEVG-1) = PCONV(:)
IOFF = IOFF+NFLEVG
ZSENDBUF(IOFF:IOFF+NFLEVG-1) = PCONT(:)
IOFF = IOFF+NFLEVG
ZSENDBUF(IOFF:IOFF+NFLEVG-1) = PCONQ(:)
IOFF = IOFF+NFLEVG
ZSENDBUF(IOFF:IOFF+NFLEVG-1) = PCONO3(:)
IOFF = IOFF+NFLEVG
ZSENDBUF(IOFF:IOFF+NFLEVG-1) = PCONCLW(:)
IOFF = IOFF+NFLEVG
DO JGHG=1,NGHG
  ZSENDBUF(IOFF:IOFF+NFLEVG-1) = PCONGHG(:,JGHG)
  IOFF = IOFF+NFLEVG
ENDDO
DO JGRG=1,NGRG
  ZSENDBUF(IOFF:IOFF+NFLEVG-1) = PCONGRG(:,JGRG)
  IOFF = IOFF+NFLEVG
ENDDO
DO JAERO=1,NAERO
  ZSENDBUF(IOFF:IOFF+NFLEVG-1) = PCONAERO(:,JAERO)
  IOFF = IOFF+NFLEVG
ENDDO
ZSENDBUF(IOFF:IOFF+NFLEVG-1) = PCONSW(:)
IOFF = IOFF+NFLEVG
ZSENDBUF(IOFF:IOFF+NFLEVG-1) = PCONRW(:)
IOFF = IOFF+NFLEVG
ZSENDBUF(IOFF:IOFF+NFLEVG-1) = PCONGW(:)
IOFF = IOFF+NFLEVG
ZSENDBUF(IOFF:IOFF+NFLEVG-1) = PCONPS(:)
IOFF = IOFF+NFLEVG

ZSENDBUF(IOFF:IOFF+NFLEVG-1) = PTOVU(:)
IOFF = IOFF+NFLEVG
ZSENDBUF(IOFF:IOFF+NFLEVG-1) = PTOVV(:)
IOFF = IOFF+NFLEVG
ZSENDBUF(IOFF:IOFF+NFLEVG-1) = PTOVT(:)
IOFF = IOFF+NFLEVG
ZSENDBUF(IOFF:IOFF+NFLEVG-1) = PTOVQ(:)
IOFF = IOFF+NFLEVG
ZSENDBUF(IOFF:IOFF+NFLEVG-1) = PTOVO3(:)
IOFF = IOFF+NFLEVG
ZSENDBUF(IOFF:IOFF+NFLEVG-1) = PTOVCLW(:)
IOFF = IOFF+NFLEVG
DO JGHG=1,NGHG
  ZSENDBUF(IOFF:IOFF+NFLEVG-1) = PTOVGHG(:,JGHG)
  IOFF = IOFF+NFLEVG
ENDDO
DO JGRG=1,NGRG
  ZSENDBUF(IOFF:IOFF+NFLEVG-1) = PTOVGRG(:,JGRG)
  IOFF = IOFF+NFLEVG
ENDDO  
DO JAERO=1,NAERO
  ZSENDBUF(IOFF:IOFF+NFLEVG-1) = PTOVAERO(:,JAERO)
  IOFF = IOFF+NFLEVG
ENDDO
ZSENDBUF(IOFF:IOFF+NFLEVG-1) = PTOVPS(:)
IOFF = IOFF+NFLEVG

ZSENDBUF(IOFF) = PSCAU
IOFF = IOFF+1
ZSENDBUF(IOFF) = PSCAV
IOFF = IOFF+1
ZSENDBUF(IOFF) = PSCAUN
IOFF = IOFF+1
ZSENDBUF(IOFF) = PSCAVN
IOFF = IOFF+1
ZSENDBUF(IOFF) = PSCAT
IOFF = IOFF+1
ZSENDBUF(IOFF) = PSCAQ
IOFF = IOFF+1
ZSENDBUF(IOFF) = PSCAPS

!*       1.2  EXCHANGE MESSAGES

ITAG = MTAGGOM
CALL GSTATS_BARRIER(772)
DO JROC=1,NPROC-1

!*       1.2.1  SEND MESSAGE

  CALL GSTATS(666,0)
  ISEND = MOD(MYPROC+JROC-1,NPROC)+1
  CALL MPL_SEND(ZSENDBUF(1:ISENDBUF),KDEST=NPRCIDS(ISEND),KTAG=ITAG, &
   & CDSTRING='GATHERGOM:')  

!*       1.2.2  RECEIVE MESSAGE

  IRECV = MOD(-JROC-1+MYPROC+NPROC,NPROC)+1
  CALL MPL_RECV(ZRECVBUF(1:IRECVBUF),KSOURCE=NPRCIDS(IRECV),KTAG=ITAG, &
   & CDSTRING='GATHERGOM:')  
  CALL GSTATS(666,1)

!*       1.2.2  UNPACK RECEIVE BUFFER

  IOFF = 1
  KSUR = KSUR+NINT(ZRECVBUF(IOFF))
  IOFF = IOFF+1
  KCON = KCON+NINT(ZRECVBUF(IOFF))
  IOFF = IOFF+1
  KTOV = KTOV+NINT(ZRECVBUF(IOFF))
  IOFF = IOFF+1
  KSCA = KSCA+NINT(ZRECVBUF(IOFF))
  IOFF = IOFF+1

  PSURU(:) = PSURU(:)+ZRECVBUF(IOFF:IOFF+NFLEVG-1)
  IOFF = IOFF+NFLEVG
  PSURV(:) = PSURV(:)+ZRECVBUF(IOFF:IOFF+NFLEVG-1)
  IOFF = IOFF+NFLEVG
  PSURT(:) = PSURT(:)+ZRECVBUF(IOFF:IOFF+NFLEVG-1)
  IOFF = IOFF+NFLEVG
  PSURQ(:) = PSURQ(:)+ZRECVBUF(IOFF:IOFF+NFLEVG-1)
  IOFF = IOFF+NFLEVG
  PSURO3(:) = PSURO3(:)+ZRECVBUF(IOFF:IOFF+NFLEVG-1)
  IOFF = IOFF+NFLEVG
  PSURCLW(:) = PSURCLW(:)+ZRECVBUF(IOFF:IOFF+NFLEVG-1)
  IOFF = IOFF+NFLEVG
  DO JGHG=1,NGHG
    PSURGHG(:,JGHG) = PSURGHG(:,JGHG)+ZRECVBUF(IOFF:IOFF+NFLEVG-1)
    IOFF = IOFF+NFLEVG
  ENDDO
  DO JGRG=1,NGRG
    PSURGRG(:,JGRG) = PSURGRG(:,JGRG)+ZRECVBUF(IOFF:IOFF+NFLEVG-1)
    IOFF = IOFF+NFLEVG
  ENDDO
  DO JAERO=1,NAERO
    PSURAERO(:,JAERO) = PSURAERO(:,JAERO)+ZRECVBUF(IOFF:IOFF+NFLEVG-1)
    IOFF = IOFF+NFLEVG
  ENDDO
  PSURPS(:) = PSURPS(:)+ZRECVBUF(IOFF:IOFF+NFLEVG-1)
  IOFF = IOFF+NFLEVG

  PCONU(:) = PCONU(:)+ZRECVBUF(IOFF:IOFF+NFLEVG-1)
  IOFF = IOFF+NFLEVG
  PCONV(:) = PCONV(:)+ZRECVBUF(IOFF:IOFF+NFLEVG-1)
  IOFF = IOFF+NFLEVG
  PCONT(:) = PCONT(:)+ZRECVBUF(IOFF:IOFF+NFLEVG-1)
  IOFF = IOFF+NFLEVG
  PCONQ(:) = PCONQ(:)+ZRECVBUF(IOFF:IOFF+NFLEVG-1)
  IOFF = IOFF+NFLEVG
  PCONO3(:) = PCONO3(:)+ZRECVBUF(IOFF:IOFF+NFLEVG-1)
  IOFF = IOFF+NFLEVG
  PCONCLW(:) = PCONCLW(:)+ZRECVBUF(IOFF:IOFF+NFLEVG-1)
  IOFF = IOFF+NFLEVG
  DO JGHG=1,NGHG
    PCONGHG(:,JGHG) = PCONGHG(:,JGHG)+ZRECVBUF(IOFF:IOFF+NFLEVG-1)
    IOFF = IOFF+NFLEVG
  ENDDO
  DO JGRG=1,NGRG
    PCONGRG(:,JGRG) = PCONGRG(:,JGRG)+ZRECVBUF(IOFF:IOFF+NFLEVG-1)
    IOFF = IOFF+NFLEVG
  ENDDO    
  DO JAERO=1,NAERO
    PCONAERO(:,JAERO) = PCONAERO(:,JAERO)+ZRECVBUF(IOFF:IOFF+NFLEVG-1)
    IOFF = IOFF+NFLEVG
  ENDDO
  PCONSW(:) = PCONSW(:)+ZRECVBUF(IOFF:IOFF+NFLEVG-1)  
  IOFF = IOFF+NFLEVG
  PCONRW(:) = PCONRW(:)+ZRECVBUF(IOFF:IOFF+NFLEVG-1)
  IOFF = IOFF+NFLEVG
  PCONGW(:) = PCONGW(:)+ZRECVBUF(IOFF:IOFF+NFLEVG-1)
  IOFF = IOFF+NFLEVG
  PCONPS(:) = PCONPS(:)+ZRECVBUF(IOFF:IOFF+NFLEVG-1)
  IOFF = IOFF+NFLEVG

  PTOVU(:) = PTOVU(:)+ZRECVBUF(IOFF:IOFF+NFLEVG-1)
  IOFF = IOFF+NFLEVG
  PTOVV(:) = PTOVV(:)+ZRECVBUF(IOFF:IOFF+NFLEVG-1)
  IOFF = IOFF+NFLEVG
  PTOVT(:) = PTOVT(:)+ZRECVBUF(IOFF:IOFF+NFLEVG-1)
  IOFF = IOFF+NFLEVG
  PTOVQ(:) = PTOVQ(:)+ZRECVBUF(IOFF:IOFF+NFLEVG-1)
  IOFF = IOFF+NFLEVG
  PTOVO3(:) = PTOVO3(:)+ZRECVBUF(IOFF:IOFF+NFLEVG-1)
  IOFF = IOFF+NFLEVG
  PTOVCLW(:) = PTOVCLW(:)+ZRECVBUF(IOFF:IOFF+NFLEVG-1)
  IOFF = IOFF+NFLEVG
  DO JGHG=1,NGHG
    PTOVGHG(:,JGHG) = PTOVGHG(:,JGHG)+ZRECVBUF(IOFF:IOFF+NFLEVG-1)
    IOFF = IOFF+NFLEVG
  ENDDO
  DO JGRG=1,NGRG
    PTOVGRG(:,JGRG) = PTOVGRG(:,JGRG)+ZRECVBUF(IOFF:IOFF+NFLEVG-1)
    IOFF = IOFF+NFLEVG
  ENDDO
  DO JAERO=1,NAERO
    PTOVAERO(:,JAERO) = PTOVAERO(:,JAERO)+ZRECVBUF(IOFF:IOFF+NFLEVG-1)
    IOFF = IOFF+NFLEVG
  ENDDO
  PTOVPS(:) = PTOVPS(:)+ZRECVBUF(IOFF:IOFF+NFLEVG-1)
  IOFF = IOFF+NFLEVG

  PSCAU = PSCAU + ZRECVBUF(IOFF)
  IOFF  = IOFF+1
  PSCAV = PSCAV + ZRECVBUF(IOFF)
  IOFF  = IOFF+1
  PSCAUN= PSCAUN+ ZRECVBUF(IOFF)
  IOFF  = IOFF+1
  PSCAVN= PSCAVN+ ZRECVBUF(IOFF)
  IOFF  = IOFF+1
  PSCAT = PSCAT + ZRECVBUF(IOFF)
  IOFF  = IOFF+1
  PSCAQ = PSCAQ + ZRECVBUF(IOFF)
  IOFF  = IOFF+1
  PSCAPS = PSCAPS + ZRECVBUF(IOFF)

ENDDO
CALL GSTATS_BARRIER2(772)

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

IF (LHOOK) CALL DR_HOOK('GATHERGOM',1,ZHOOK_HANDLE)
END SUBROUTINE GATHERGOM
