MODULE TESTVAR_MIX

!     Purpose.
!     --------
!       Setup for tests of variational assimilation components.

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

!     Modifications.
!     --------------
!       Original    20-11-03
!        Y.Tremolet    18-Feb-2005 Identical twin experiments
!        Y.Tremolet    30-Mar-2005 Improve incremental 4D-Var test
! ------------------------------------------------------------------

USE PARKIND1, ONLY: JPIM, JPRB
USE YOMHOOK , ONLY: LHOOK, DR_HOOK
USE YOMDYN  , ONLY: TSTEP
USE YOMCT0  , ONLY: NSTART, NSTOP
USE YOMLUN  , ONLY: NULOUT, NULERR, NULNAM
USE GRIB_HEADER_MIX

IMPLICIT NONE
SAVE

PRIVATE
PUBLIC SETUP_TESTVAR, &
 & ntestvar,lintest,ltltest,ladtest,lgrtest,lcvtest, &
 & nstop_tltest, nphys_tltest, ltestadjm, ltestadjh, ltestadjb, &
 & ltestinc, lstep_testinc, interp_test, ygrb_testinc, ltestsppa, &
 & ltwintruth, ltwinexp, twindepart

LOGICAL :: ltltest   ! Test of tangent linear model
LOGICAL :: lintest   ! Test linearity of tangent linear model
LOGICAL :: ladtest   ! Test of adjoint
LOGICAL :: lgrtest   ! Gradient test
LOGICAL :: lcvtest   ! Test change of variable (inverse and adjoint)

INTEGER(KIND=JPIM) :: ntestvar       ! Controls when tests are performed:
                            ! 0 - No tests
                            ! 1 - Tests run before minimisation
                            ! 2 - Tests run after  minimisation
                            ! 3 - Tests run before and after minimisation

INTEGER(KIND=JPIM) :: nstop_tltest   ! Number of time-steps to run TL test for
INTEGER(KIND=JPIM) :: nphys_tltest   ! Type of physics used in TL test:
                            ! 0 - No physics in NL or TL models
                            ! 1 - Only physics available in TL model is used
                            !     NL model
                            ! 2 - All physics available in each model is used
LOGICAL :: LTESTADJM        ! Test of M adjoint is being run (internal switch)
LOGICAL :: LTESTADJH        ! Test of H adjoint is being run (internal switch)
LOGICAL :: LTESTADJB        ! Save "b" term for test of H adjoint (internal switch)

LOGICAL :: ltestinc                  ! Save data for test of incremental 4D-Var
REAL(KIND=JPRB) :: tstep_testinc     ! Interval (seconds) for incr. 4D-Var test
                                     ! save for initial time only if set to 0
REAL(KIND=JPRB) :: tstep_testbgn     ! Interval of additional incr. 4D-Var test
REAL(KIND=JPRB) :: tstop_testbgn     ! Stop time   additional incr. 4D-Var test
INTEGER(KIND=JPIM) :: interp_test    ! Interpolation algo for incr. 4D-Var test
LOGICAL, ALLOCATABLE :: lstep_testinc(:)   ! Active steps for incr. 4D-Var test
TYPE(GRIB_HEADER) :: ygrb_testinc
LOGICAL :: ltestsppa                 ! Surf pressure in Pa (LNSP otherwise)

LOGICAL :: ltwintruth          ! Running "truth" for identical twin experiment
LOGICAL :: ltwinexp            ! Running identical twin experiment
REAL(KIND=JPRB) :: twindepart  ! Obs departure from truth in twin exp

! ------------------------------------------------------------------
NAMELIST/NAMTESTVAR/ntestvar,lintest,ltltest,ladtest,lgrtest,lcvtest, &
                  & nstop_tltest,nphys_tltest, ltestinc, &
                  & interp_test,tstep_testinc,tstep_testbgn,tstop_testbgn, &
                  & ltwintruth, ltwinexp, twindepart
! ------------------------------------------------------------------

#include "posnam.intfb.h"

! ------------------------------------------------------------------
CONTAINS
! ------------------------------------------------------------------

SUBROUTINE SETUP_TESTVAR

INTEGER(KIND=JPIM) :: istep_testinc, istep_testbgn, istop_testbgn, ii, jj
CHARACTER(LEN=12) :: clfile
REAL(KIND=JPRB) :: ZHOOK_HANDLE

IF (LHOOK) CALL DR_HOOK('TESTVAR_MIX:SETUP_TESTVAR',0,ZHOOK_HANDLE)

! Internal consistency tests (inner loop)
ntestvar=0
ltltest =.false.
lintest =.false.
ladtest =.false.
lgrtest =.false.
lcvtest =.false.
nstop_tltest=-1
nphys_tltest=0

! Incremental 4D-Var tests (inner vs. outer loops)
ltestinc=.false.
tstep_testinc=0.0_JPRB
tstep_testbgn=0.0_JPRB
tstop_testbgn=0.0_JPRB
interp_test=2          ! 3 for conserving interpolation
ltestsppa=.true.

! Identical twin experiments
ltwintruth=.false.
ltwinexp=.false.
twindepart=0.0_JPRB

CALL POSNAM(NULNAM,'NAMTESTVAR')
READ(NULNAM,NAMTESTVAR)

WRITE(NULOUT,*)'TESTVAR_MIX: NTESTVAR=',NTESTVAR
WRITE(NULOUT,*)'TESTVAR_MIX: LCVTEST, LINTEST, LTLTEST, LADTEST, LGRTEST= ', &
                           & LCVTEST, LINTEST, LTLTEST, LADTEST, LGRTEST  

IF (ltltest) THEN
  WRITE(NULOUT,*)'TESTVAR_MIX: NSTOP_TLTEST=',nstop_tltest, &
                           & ' NPHYS_TLTEST=',nphys_tltest
ENDIF

WRITE(NULOUT,*)'TESTVAR_MIX: LTESTINC=',LTESTINC
IF (ltestinc) THEN
  ALLOCATE(lstep_testinc(nstart:nstop))
  lstep_testinc(:)=.false.
  IF (tstep_testinc==0.0_JPRB) lstep_testinc(nstart)=.true.
  istep_testinc=NINT(tstep_testinc/TSTEP)
  IF (istep_testinc>0) THEN
    DO jj=nstart,nstop
      ii=jj-nstart
      lstep_testinc(jj)=(MOD(ii,istep_testinc)==0)
    ENDDO
  ENDIF
  istep_testbgn=NINT(tstep_testbgn/TSTEP)
  istop_testbgn=NINT(tstop_testbgn/TSTEP)
  IF (istep_testbgn>0 .AND. istop_testbgn>0) THEN
    DO jj=nstart,nstart+istop_testbgn
      ii=jj-nstart
      lstep_testinc(jj)=lstep_testinc(jj).OR.(MOD(ii,istep_testbgn)==0)
    ENDDO
  ENDIF
  WRITE(NULOUT,*)'TESTVAR_MIX: TSTEP_TESTINC=',tstep_testinc
  WRITE(NULOUT,*)'TESTVAR_MIX: TSTEP_TESTBGN, TSTOP_TESTBGN=', &
                         & TSTEP_TESTBGN, TSTOP_TESTBGN
  WRITE(NULOUT,*)'TESTVAR_MIX: LSTEP_TESTINC=',lstep_testinc(:)

  clfile='test4dinc_gg'
  CALL allocate_grib_header(ygrb_testinc)
  CALL init_grib_header(clfile,.true.,ygrb_testinc)
ENDIF

WRITE(NULOUT,*)'TESTVAR_MIX: LTWINTRUTH= ',LTWINTRUTH,', LTWINEXP= ',LTWINEXP
WRITE(NULOUT,*)'TESTVAR_MIX: TWINDEPART=',twindepart
IF (twindepart/=0.0_JPRB) THEN
  WRITE(NULOUT,*)'TESTVAR_MIX: WARNING: non zero departure specified'
  WRITE(NULERR,*)'TESTVAR_MIX: WARNING: non zero departure specified'
ENDIF

LTESTADJM=.false.
LTESTADJH=.false.

IF (LHOOK) CALL DR_HOOK('TESTVAR_MIX:SETUP_TESTVAR',1,ZHOOK_HANDLE)
END SUBROUTINE SETUP_TESTVAR

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

END MODULE TESTVAR_MIX
