SUBROUTINE SPNORMB(PX,KLEV,PSN,PSM,PMET,KFLEV,KFLSUR,LDNWAVE)

!**** *SPNORMB* - Compute norms in spectral space

!     Purpose.
!     --------
!        Compute the norm in spectral space for a given level and
!        a given n (and m)

!**   Interface.
!     ----------
!        *CALL* *SPNORMB(PX,KLEV,PSN,PSM,PMET,KFLEV,KFLSUR,LDNWAVE)

!        Explicit arguments :
!        --------------------
!        PX      : Input array
!        PSN     : spectrum at constant n
!        PSM     : spectrum at constant m
!        KLEV    : number of levels of computation
!        PMET    : Metric
!        KFLEV   : first dimensioning of output arrays.
!        KFLSUR  : first dimensioning of input array.
!        LDNWAVE : .TRUE. to compute spectrum at constant n

!        Implicit arguments :  none.
!        --------------------

!     Method.
!     -------

!     Externals. None
!     ----------
!      Called by SPNORMBM.

!     Reference.
!     ----------
!        ECMWF Research Department documentation of the IFS

!     Author.
!     -------
!        Philippe Courtier  *ECMWF*

!     Modifications.
!     --------------
!        Original : 92-12-20
!        Modified : 95-06-06 L.Isaksen   Reordering of spectral arrays
!        Modified : 97-02-02 L.Isaksen   Merged with MP version
!      R. El Khatib 99-02-09 LDNWAVE
!        M.Hamrud      01-Oct-2003 CY28 Cleaning
!      R. El Khatib 04-08-09 Loops on levels and local wave numbers
!     ------------------------------------------------------------------

USE PARKIND1  ,ONLY : JPIM     ,JPRB
USE YOMHOOK   ,ONLY : LHOOK,   DR_HOOK
USE YOMDIM   , ONLY : NSMAX    ,NUMP
USE YOMLAP   , ONLY : NASM0    ,NASRN    ,MYMS

IMPLICIT NONE

INTEGER(KIND=JPIM),INTENT(IN)    :: KFLEV 
INTEGER(KIND=JPIM),INTENT(IN)    :: KFLSUR 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PX(:,:) 
INTEGER(KIND=JPIM),INTENT(IN)    :: KLEV 
REAL(KIND=JPRB)   ,INTENT(OUT)   :: PSN(:,:) 
REAL(KIND=JPRB)   ,INTENT(OUT)   :: PSM(:,:) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PMET(0:) 
LOGICAL           ,INTENT(IN)    :: LDNWAVE 
INTEGER(KIND=JPIM) :: INM, ISP, ISP0, JM, JN, JLEV, JNML
REAL(KIND=JPRB) :: ZHOOK_HANDLE

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

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

!$OMP PARALLEL DO SCHEDULE(STATIC,1)  PRIVATE(JNML,JLEV,INM,JM,ISP,ISP0,JN)
DO JNML=1,NUMP
  INM=MYMS(JNML)
  DO JLEV=1,KLEV

!*       1.    COMPUTE for a given n (=KNM).
!              -----------------------------

    IF (LDNWAVE) THEN
      PSN(JLEV,JNML)=0.0_JPRB
      DO JM=NASRN(INM),1,-1
        ISP=NASM0(JM)+(INM-JM)*2
        PSN(JLEV,JNML)=PSN(JLEV,JNML) &
         & +2.0_JPRB*(PX(JLEV,ISP)**2+PX(JLEV,ISP+1)**2)
      ENDDO
      PSN(JLEV,JNML)=(PSN(JLEV,JNML)+PX(JLEV,ISP0)**2)*PMET(INM)
      ISP0=NASM0(0)+INM*2
    ENDIF

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

!*       2.    COMPUTE for a given m (=KNM).
!              -----------------------------

    PSM(JLEV,JNML)=0.0_JPRB
    IF(INM == 0)THEN
      DO JN=0,NSMAX
        ISP=NASM0(0)+JN*2
        PSM(JLEV,JNML)=PSM(JLEV,JNML)+PMET(JN)*PX(JLEV,ISP)**2
      ENDDO
    ELSE
      DO JN=INM,NSMAX
        ISP=NASM0(INM)+(JN-INM)*2
        PSM(JLEV,JNML)=PSM(JLEV,JNML)+2.0_JPRB*PMET(JN)*&
         & (PX(JLEV,ISP)**2+PX(JLEV,ISP+1)**2)  
      ENDDO
    ENDIF

  ENDDO
ENDDO
!$OMP END PARALLEL DO

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

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