SUBROUTINE GRID2SPECAD(YDGP,YDSP)

!   Purpose
!   -------
!     Adjoint of spectral transform from grid point fields to spectral fields.

!   Author
!   ------
!     Y. Tremolet

!   Modifications
!   -------------
!     Original   02-Aug-05
! ------------------------------------------------------------------

USE PARKIND1, ONLY: JPIM, JPRB
USE YOMHOOK , ONLY: LHOOK, DR_HOOK
USE YOMMP   , ONLY: NBSETLEV, NBSETSP
USE GRIDPOINT_FIELDS_MIX
USE SPECTRAL_FIELDS_MOD

IMPLICIT NONE
TYPE(SPECTRAL_FIELD), INTENT(INOUT) :: YDSP
TYPE(GRIDPOINT_FIELD),INTENT(INOUT) :: YDGP

LOGICAL :: LLWIND, LL2D
INTEGER(KIND=JPIM) :: ivsetsc2(1)
INTEGER(KIND=JPIM) :: jj,jf
REAL(KIND=JPRB), ALLOCATABLE :: ZSP(:,:)
REAL(KIND=JPRB) :: ZHOOK_HANDLE

INTERFACE
#include "dir_transad.h"
END INTERFACE
#include "abor1.intfb.h"

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

IF (LHOOK) CALL DR_HOOK('GRID2SPECAD',0,ZHOOK_HANDLE)
IF (YDSP%NS3D/=YDGP%NG3D) CALL ABOR1('GRID2SPECAD: Error nb 3D fields')
IF (YDSP%NS2G/=YDGP%NG2D) CALL ABOR1('GRID2SPECAD: Error nb 2D fields')

! If spectral vor and div and GP U and V convert winds,
! otherwise treat all fields as scalar fields.
! This could be improved a lot...
llwind=  (ASSOCIATED(YDSP%DIV).AND.ASSOCIATED(YDSP%VOR)) &
 & .AND. (ASSOCIATED(YDGP%W_U).AND.ASSOCIATED(YDGP%W_V))
ll2d = (YDSP%NS2G>0.AND.YDGP%NG2D>0)

IF (LL2D) THEN
  IVSETSC2(1)=NBSETSP
  ALLOCATE(ZSP(1:YDSP%NS2G,YDSP%NSPEC2))
  DO jf=1,YDSP%NS2D
    DO jj=1,YDSP%NSPEC2
      ZSP(jf,jj)=YDSP%SP2D(jj,jf)
      YDSP%SP2D(jj,jf)=0.0_JPRB
    ENDDO
  ENDDO
  IF (LLWIND) THEN
    CALL DIR_TRANSAD(PSPVOR=YDSP%VOR,  PSPDIV=YDSP%DIV,  &
                   & PGPUV =YDGP%WIND, KVSETUV=NBSETLEV, &
                   & PSPSC3A=YDSP%SCAL , PGP3A  =YDGP%SCAL, &
                   & KVSETSC3A=NBSETLEV, KPROMA=YDGP%NPROMA, &
                   & PSPSC2=ZSP, PGP2=YDGP%GP2D, KVSETSC2=IVSETSC2)
  ELSE
    CALL DIR_TRANSAD(PSPSC3A=YDSP%SCAL , PGP3A  =YDGP%SCAL, &
                   & KVSETSC3A=NBSETLEV, KPROMA=YDGP%NPROMA, &
                   & PSPSC2=ZSP, PGP2=YDGP%GP2D, KVSETSC2=IVSETSC2)
  ENDIF
  DEALLOCATE(ZSP)
ELSE
  IF (LLWIND) THEN
    CALL DIR_TRANSAD(PSPVOR=YDSP%VOR,  PSPDIV=YDSP%DIV,  &
                   & PGPUV =YDGP%WIND, KVSETUV=NBSETLEV, &
                   & PSPSC3A=YDSP%SCAL , PGP3A  =YDGP%SCAL, &
                   & KVSETSC3A=NBSETLEV, KPROMA=YDGP%NPROMA)
  ELSE
    CALL DIR_TRANSAD(PSPSC3A=YDSP%SCAL , PGP3A  =YDGP%SCAL, &
                   & KVSETSC3A=NBSETLEV, KPROMA=YDGP%NPROMA)
  ENDIF
ENDIF

CALL HUGIFY_ENDGRID(YDGP)

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