SUBROUTINE SUJBCOV

!**** *SUJBCOV* - Setup of the background error constraint Jb

!     Purpose. Set up the error covariance model.
!     --------

!     Interface. CALL SUJBCOV
!     ----------

!     Implicit arguments : parameters in common YOMJG (already set up in SUJB)
!     -------------------- and Jb-related files.

!     Method.
!     -------
!        Read data from specific files.
!        Apply compact support to files if required.
!        Build error covariance operator or its inverse, including
!         spectral and gridpoint correlations, gridpoint variances,
!         mapping from model to error variables (e.g. balance).
!        Initialize Jb operator.
!        Diagnose the implied variances and/or structure functions.

!     Externals: see below.
!     ----------

!     Author : Francois Bouttier *ECMWF*
!     --------

!     Modifications :
!     ---------------
!     96-02-07 F.Bouttier : write original
!     96-07-16 F.Bouttier : create stat bal config for John Derber
!     97-09-24 E.Holm     : include ozone (stabal96 and GSA file only)
!     97-11-13 JN.Thepaut : New Jb at DMN also
!     00-10-26 M.Fisher   : SUJBBAL and SUJBWAVELET now called directly
!                           from SU0YOMB.
!        R. El Khatib : 01-08-07 Pruning options
!        M.Hamrud      01-Oct-2003 CY28 Cleaning
!        M.Hamrud      01-Dec-2003 CY28R1 Cleaning
!     ------------------------------------------------------------------

USE PARKIND1  ,ONLY : JPIM     ,JPRB
USE YOMHOOK   ,ONLY : LHOOK,   DR_HOOK
USE YOMDIM   , ONLY : NFLEVG   ,NSMAX
USE YOMJG    , ONLY : LJBTEST  ,LJBENER  ,NJBVERB
USE YOMLUN   , ONLY : NULOUT

IMPLICIT NONE

!       Type of Jb setup (use it to maintain self-consistent options !)
!       Shall depend only on namelist variables
CHARACTER :: CLJBTYPE*10
!       Covariance matrices for each parameter :
REAL(KIND=JPRB),ALLOCATABLE :: ZCOVTPS(:,:,:)    ! (T,Ps) for diagnostics
REAL(KIND=JPRB),ALLOCATABLE :: ZCOVP(:,:,:)      ! Balanced mass
REAL(KIND=JPRB),ALLOCATABLE :: ZCOVU(:,:,:)      ! Unbalanced mass
REAL(KIND=JPRB),ALLOCATABLE :: ZCOVD(:,:,:)      ! Divergence
REAL(KIND=JPRB),ALLOCATABLE :: ZCOVQ(:,:,:)      ! Specific humidity
REAL(KIND=JPRB),ALLOCATABLE :: ZCOVO3 (:,:,:)    ! Ozone mass mixing ratio
CHARACTER (LEN = 35) ::  CLINE
REAL(KIND=JPRB) :: ZHOOK_HANDLE

#include "abor1.intfb.h"
#include "sujbcor.intfb.h"
#include "sujbdat.intfb.h"
#include "sujbstd.intfb.h"
#include "sujbtest.intfb.h"

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

IF (LHOOK) CALL DR_HOOK('SUJBCOV',0,ZHOOK_HANDLE)
CLINE='----------------------------------'

!        1. Set up parameters and data

!     (namelist NAMJG has already been set up in SUJB under SU0YOMA)

!           1.1 Select and describe type of Jb configuration

IF (LJBENER) THEN
  CLJBTYPE='TOTENRGY'
  WRITE(NULOUT,*) ' Using a total energy formulation ',CLJBTYPE
  WRITE(NULOUT,*) ' to simulate a scaled energy inner product ',&
   & ' (J. Barkmeijer, F. Bouttier ECMWF 1996)'  
ELSE
  CLJBTYPE='STABAL96'
  WRITE(NULOUT,*) ' Using stat balance formulation ',CLJBTYPE
  WRITE(NULOUT,*) ' developed at ECMWF in 1996 ','by J. Derber'
ENDIF

!     Insert above your favourite Jb configuration

!          1.2 Allocate work arrays

IF ((CLJBTYPE == 'STABAL96').OR.&
   & (CLJBTYPE == 'TOTENRGY')    ) THEN  
!       covariances are function of total wavenumber n
  ALLOCATE (ZCOVTPS(NFLEVG+1,NFLEVG+1,0:NSMAX))
  ALLOCATE (ZCOVP  (NFLEVG,  NFLEVG,  0:NSMAX))
  ALLOCATE (ZCOVU  (NFLEVG,  NFLEVG,  0:NSMAX))
  ALLOCATE (ZCOVD  (NFLEVG,  NFLEVG,  0:NSMAX))
  ALLOCATE (ZCOVQ  (NFLEVG,  NFLEVG,  0:NSMAX))
  ALLOCATE (ZCOVO3 (NFLEVG,  NFLEVG,  0:NSMAX))
ELSE
  CALL ABOR1('SUJBCOV:BAD CLJBTYPE FOR ARRAY ALLOCATION')
ENDIF

!     Read data from ad hoc files for model geometry & variables
!     Also compute the P->(T,Ps) operator when converting covTPs into covP
IF (CLJBTYPE == 'STABAL96') THEN
  CALL SUJBDAT(CLJBTYPE,NJBVERB,ZCOVTPS,ZCOVP,ZCOVU,ZCOVD,ZCOVQ,&
   & ZCOVO3,SIZE(ZCOVP,1),SIZE(ZCOVP,3))  
ENDIF

!        2. Set up error covariance operator

!     Set up main correlation operator (spectral)
CALL SUJBCOR(CLJBTYPE,NJBVERB,ZCOVTPS,ZCOVP,ZCOVU,ZCOVD,ZCOVQ,&
 & ZCOVO3,SIZE(ZCOVP,1),SIZE(ZCOVP,3))  
!     Set up standard error profiles
CALL SUJBSTD(CLJBTYPE,NJBVERB,ZCOVTPS,ZCOVP,ZCOVD,ZCOVQ,&
 & ZCOVO3,SIZE(ZCOVP,1),SIZE(ZCOVP,3))  

!        3. Postprocessing


IF ((CLJBTYPE == 'STABAL96').OR.&
   & (CLJBTYPE == 'TOTENRGY')    ) THEN  
  DEALLOCATE (ZCOVTPS)
  DEALLOCATE (ZCOVP)
  DEALLOCATE (ZCOVU)
  DEALLOCATE (ZCOVD)
  DEALLOCATE (ZCOVQ)
  DEALLOCATE (ZCOVO3)
ENDIF

WRITE(NULOUT,*) 'Jb covariances have been set up now'
WRITE(NULOUT,*) ' '

!        4. Debugging

!     Test the correctness of Jb code (activate by hand)
IF (LJBTEST) CALL SUJBTEST(NJBVERB)

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