SUBROUTINE SUPERT(YD_PERTURB,PVAL)

!**** *SUPERT*  - INITIALIZATION OF A PERTURBATION

!     Purpose.
!     --------
!           INITIALIZATION OF A PERTURBATION

!**   Interface.
!     ----------
!        *CALL* *SUPERT(PERTURB,PVAL)

!        Explicit arguments :
!        --------------------
!        PERTURB : ARRAY WHICH CONTAIN THE PERTURBATION
!        PVAL    : REAL VALUE

!        Implicit arguments :
!        --------------------
!        None

!     Method.
!     -------
!        See documentation

!     Externals.
!     ----------

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

!     Author.
!     -------
!        Mats Hamrud and Philippe Courtier  *ECMWF*

!     Modifications.
!     --------------
!        Original  87-10-15
!     J.N.Thepaut  91-09-18 : Physically sound perturbations (501)
!     P.Courtier   91-11-01 : Rewriting
!     E.Andersson  96-08-01 : Precalculated SQRT(SCALP)
!     E.Holm       98-05-19 : Make perturbations identical for each field
!                             to avoid inconsistency when testing with
!                             varying number of fields in the control variable
!     C.Fischer    99-03-04 : Not without relationship to E Holm's comment,
!                             provide scaled perturbations for the mean wind
!                             in Aladin
!     M.Fisher     02-09-30 : RANDOM_NUMBERS_MIX
!     Y.Tremolet   02-11-12 : Use control_vectors.
!     C.Soci       03-05-23 : Provisional switch off of setimzero for LAM
!                             (zeros produce corrupted TL tests in e501)
!     Y.Tremolet   03-08-04 : Avoid generating the same vector at each call.
!        M.Hamrud      01-Oct-2003 CY28 Cleaning
!     ------------------------------------------------------------------

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

USE YOMCT0, ONLY: LELAM
USE YOMDIM, ONLY: NFLEVG, NSPEC2G
USE YOMCVA, ONLY: YRSCALPSQRT, NVA3D, NVA2D
USE CONTROL_VECTORS
USE RANDOM_NUMBERS_MIX

IMPLICIT NONE

TYPE(CONTROL_VECTOR),INTENT(INOUT) :: YD_PERTURB 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PVAL 

REAL(KIND=JPRB), ALLOCATABLE :: ZRAND(:)
REAL(KIND=JPRB) :: ZRAND2(NSPEC2G), ZRAND3(NSPEC2G*NFLEVG)
INTEGER(KIND=JPIM) :: ii,jj,jf
REAL(KIND=JPRB) :: ZHOOK_HANDLE

LOGICAL, SAVE :: LLINIT=.TRUE.
TYPE(randomNumberStream), SAVE :: YL_RANDOM_STREAM

#include "setimzero.intfb.h"

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

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

!--- First call only, initialize private random number stream

IF (LLINIT) THEN
  CALL INITIALIZE_RANDOM_NUMBERS(1,YL_RANDOM_STREAM)
  LLINIT=.FALSE.
ENDIF

! This part is duplicated on all PEs.

ALLOCATE(ZRAND(YD_PERTURB%nsizeg))
CALL UNIFORM_DISTRIBUTION(ZRAND2,YL_RANDOM_STREAM)

! 2D fields first
ii=0
DO jf=1,NVA2D
  DO jj=1,NSPEC2G
    ii=ii+1
    ZRAND(ii)=ZRAND2(jj)
  ENDDO
ENDDO

! Then 3D fields
CALL UNIFORM_DISTRIBUTION(ZRAND3,YL_RANDOM_STREAM)
DO jf=1,NVA3D
  DO jj=1,NSPEC2G*NFLEVG
    ii=ii+1
    ZRAND(ii)=ZRAND3(jj)
  ENDDO
ENDDO

! Remaining part is done at once.
CALL UNIFORM_DISTRIBUTION(ZRAND(ii+1:YD_PERTURB%nsizeg),YL_RANDOM_STREAM)
YD_PERTURB=ZRAND
DEALLOCATE(ZRAND)

! Back to distributed computations.
YD_PERTURB%data(:) = pval * (1.0_JPRB-2.0_JPRB*YD_PERTURB%data(:))
YD_PERTURB%data(:) = YD_PERTURB%data(:) * YRSCALPSQRT%data(:)

IF (YD_PERTURB%ltovscv) YD_PERTURB%tovscv(:) = 0.0_JPRB
IF (YD_PERTURB%npara>0) YD_PERTURB%params(:) = 0.0_JPRB
IF (.NOT.LELAM) CALL SETIMZERO(YD_PERTURB)

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