SUBROUTINE GPNORM_GFL

!**** *GPNORM_GFL*  - ROUTINE FOR CALCULATING GRID POINT NORM OF
!                     GFL VARIABLES

!     PURPOSE.
!     --------

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

!        *CALL* *GPNORM_GFL*

!     METHOD.
!     -------

!     EXTERNALS.
!     ----------

!     REFERENCE.
!     ----------

!        ECMWF Research Department documentation of the IFS

!     AUTHOR.
!     -------

!        G. Mozdzynski *ECMWF*  (based on gpnorm3 + gpnorm1)

!     MODIFICATIONS.
!     --------------
!       Original : 02 Oct 2008
!     A.Bogatchev: 12 Jun 2009 , call to egpnorm_trans
!     -----------------------------------------------------------------

USE PARKIND1  ,ONLY : JPIM     ,JPRB
USE YOMHOOK   ,ONLY : LHOOK,   DR_HOOK

USE YOMMP    , ONLY : MYPROC
USE YOMDIM   , ONLY : NPROMA, NFLEVG, NGPBLKS
USE YOMGEM   , ONLY : NGPTOT
USE YOMCT0   , ONLY : NSPPR, NPROC  , LELAM
USE YOMLUN   , ONLY : NULOUT
USE YOMGFL   , ONLY : GFL
USE YOM_YGFL , ONLY : YGFL     ,YGFLC

IMPLICIT NONE

REAL(KIND=JPRB),ALLOCATABLE :: ZGP(:,:,:)
REAL(KIND=JPRB),ALLOCATABLE :: ZAVE(:), ZMAX(:), ZMIN(:)
REAL(KIND=JPRB),ALLOCATABLE :: ZMAXBLK(:,:), ZMINBLK(:,:)


INTEGER(KIND=JPIM) :: IEND, IST, JF, JL, JKGLO, IBL, JGFL
INTEGER(KIND=JPIM) :: IFLD,IFIELDS
LOGICAL            :: LLEVELS, LLAVE_ONLY
REAL(KIND=JPRB) :: ZHOOK_HANDLE

INTERFACE
#include "gpnorm_trans.h"
#include "egpnorm_trans.h"
END INTERFACE

#include "gpnorm1.intfb.h"


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

IF (LHOOK) CALL DR_HOOK('GPNORM_GFL',0,ZHOOK_HANDLE)

LLEVELS = NSPPR>0

IF( LLEVELS )THEN

  DO JGFL=1,YGFL%NUMFLDS
    IF(YGFLC(JGFL)%LGP) THEN
      ALLOCATE(ZGP(NPROMA,NFLEVG,NGPBLKS))

      CALL GSTATS(1223,0)
!$OMP PARALLEL DO SCHEDULE(STATIC) PRIVATE(JKGLO,IST,IEND,IBL,JF,JL)
      DO JKGLO=1,NGPTOT,NPROMA
        IST=1
        IEND=MIN(NPROMA,NGPTOT-JKGLO+1)
        IBL=(JKGLO-1)/NPROMA+1
        DO JF=1,NFLEVG
          DO JL=IST,IEND
            ZGP(JL,JF,IBL) = GFL(JL,JF,JGFL,IBL)
          ENDDO
        ENDDO
      ENDDO
!$OMP END PARALLEL DO
      CALL GSTATS(1223,1)

      CALL GPNORM1(ZGP,NFLEVG,LLEVELS,YGFLC(JGFL)%CNAME)

      DEALLOCATE(ZGP)
    ENDIF
  ENDDO

ELSE

  IFLD=0
  DO JGFL=1,YGFL%NUMFLDS
    IF(YGFLC(JGFL)%LGP) THEN
      IFLD=IFLD+1
    ENDIF
  ENDDO
  IFIELDS=IFLD

  ALLOCATE(ZGP(NPROMA,IFIELDS,NGPBLKS))

  ALLOCATE(ZAVE(IFIELDS))
  ALLOCATE(ZMIN(IFIELDS))
  ALLOCATE(ZMAX(IFIELDS))
  ALLOCATE(ZMINBLK(IFIELDS,NGPBLKS))
  ALLOCATE(ZMAXBLK(IFIELDS,NGPBLKS))
  
  IFLD=0
  DO JGFL=1,YGFL%NUMFLDS
    IF(YGFLC(JGFL)%LGP) THEN
      IFLD=IFLD+1

      ZMINBLK(IFLD,:)=GFL(1,1,JGFL,1)
      ZMAXBLK(IFLD,:)=GFL(1,1,JGFL,1)

      CALL GSTATS(1427,0)
!$OMP PARALLEL DO SCHEDULE(STATIC) PRIVATE(JKGLO,IST,IEND,IBL,JF,JL)
      DO JKGLO=1,NGPTOT,NPROMA
        IST=1
        IEND=MIN(NPROMA,NGPTOT-JKGLO+1)
        IBL=(JKGLO-1)/NPROMA+1
        DO JL=IST,IEND
          ZGP(JL,IFLD,IBL) = 0.0_JPRB
        ENDDO
        DO JF=1,NFLEVG
          DO JL=IST,IEND
            ZGP(JL,IFLD,IBL) = ZGP(JL,IFLD,IBL)+GFL(JL,JF,JGFL,IBL)
            ZMINBLK(IFLD,IBL) = MIN(ZMINBLK(IFLD,IBL),GFL(JL,JF,JGFL,IBL))
            ZMAXBLK(IFLD,IBL) = MAX(ZMAXBLK(IFLD,IBL),GFL(JL,JF,JGFL,IBL))
          ENDDO
        ENDDO
      ENDDO
!$OMP END PARALLEL DO
      CALL GSTATS(1427,1)
      ZMIN(IFLD)=MINVAL(ZMINBLK(IFLD,1:NGPBLKS))
      ZMAX(IFLD)=MAXVAL(ZMAXBLK(IFLD,1:NGPBLKS))
    ENDIF
  ENDDO

  DEALLOCATE(ZMINBLK)
  DEALLOCATE(ZMAXBLK)

  LLAVE_ONLY=.TRUE. 
  IF ( .NOT. LELAM ) THEN
   CALL GPNORM_TRANS(ZGP,IFIELDS,NPROMA,ZAVE,ZMIN,ZMAX,LLAVE_ONLY)
  ELSE
   CALL EGPNORM_TRANS(ZGP,IFIELDS,NPROMA,ZAVE,ZMIN,ZMAX,LLAVE_ONLY)
  ENDIF
  IF (MYPROC == 1.OR.NPROC == 1) THEN
    IFLD=0
    DO JGFL=1,YGFL%NUMFLDS
      IF(YGFLC(JGFL)%LGP) THEN
        IFLD=IFLD+1
        WRITE(NULOUT,'(5(1X,A))') 'GPNORM',YGFLC(JGFL)%CNAME,'    AVERAGE         ',&
         & '     MINIMUM        ','      MAXIMUM        '
        WRITE(NULOUT,'(9X,A5,3(1X,E21.15))') 'AVE  ',ZAVE(IFLD)/NFLEVG,ZMIN(IFLD),ZMAX(IFLD)
      ENDIF
    ENDDO
  ENDIF

  DEALLOCATE(ZGP)
  DEALLOCATE(ZAVE)
  DEALLOCATE(ZMIN)
  DEALLOCATE(ZMAX)

ENDIF
!     -----------------------------------------------------------------

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