SUBROUTINE RESTORE_SURFTSTP(KJ, KJREF, KSTART,KSTEP,&
           & KIDIA,KFDIA,KLON,KLEV,KLEVS,KLEVO,KTILES,KSTGLO,LDOCN_KPP,&
!           & KIDIA,KFDIA,KLON,KLEV,KLEVS,KLEVO,KSTGLO,LDOCN_KPP,&
           & PEVAPSNW,PUSTRTI,PVSTRTI,PAHFSTI,PEVAPTI,PFRSOTI,&
           & PWSA,PTSA, PZO,PHO,PHO_INV,PDO,PADVT,PADVS,PTRI0,PTRI1,PSWDK_SAVE,&
           & PUSTRC,PVSTRC,&
           & PUO0,PVO0,PUOC,PVOC,PTO0,PSO0,&
           & PFTG12,PFWROD,PFWRO1,PFWG12,PFWMLT,PFWEV,PENES,&
           & PDIFM, PDIFT, PDIFS,&
           & PSNSE1,PTSNE1,PASNE1,PRSNE1,PTSAE1,PTIAE1,&
           & PWLE1,PWSAE1,PTLICEE1,PTLMNWE1,PTLWMLE1,PTLBOTE1,PTLSFE1,&
           & PHLICEE1,PHLMLE1,PUOE1,PVOE1,PTOE1,PSOE1)

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

!**   *RESTORE_SURFTSTP* - FOR PERTURBED RUN OF THE SEKF SURFACE ANALYSIS 

!     P. DE ROSNAY   E.C.M.W.F.    12 FEBRUARY 2009

!     PURPOSE
!     -------

!     RESTORE SAVED VARIABLES TO BE USED BY SURFTSTP WHEN PERFORMING PERTURBED
!     RUNS FOR THE EKF SURFACE ANALYSIS

!     INTERFACE
!     ---------

!     *RESTORE_SURFTSTP* IS CALLED BY *CALLPAR*

!     INPUT PARAMETERS (INTEGER):

!
! KSTART  : FIRST STEP OF MODEL
! KSTEP   : CURRENT TIME STEP

!     *KIDIA*        START POINT
!     *KFDIA*        END POINT
!     *KLON*         NUMBER OF GRID POINTS PER PACKET
!     *KLEV*         NUMBER OF LEVELS
!     *KLEVO*        Number of ocean vertical layers
!     *KLEVS*        NUMBER OF LEVELS IN SOIL
!     *KLEV*         END OF VERTICAL LOOP AND VERTICAL DIMENSION
!     *KTILES*       NUMBER OF VEGETATION (SURFACE COVER) TYPES
!     *KSTGLO*       GLOBAL OFFSET (USED IN MESSAGE PASSING VERSION)
!     *LDOCN_KPP*    ocean coupling (cf surf/module/surfbc_ctl_mod.F90)


!     OUTPUT PARAMETERS (REAL):
! PWSA       : MULTI-LAYER SOIL WETNESS
! PTSA       : MULTI-LAYER SOIL TEMPERATURE

! PFTG12     UPWARD FLUX BETWEEN SURFACE AND DEEP LAYER   W/M**2
! PFWROD      DEEP LAYER RUN-OFF                          kg/m**2/s
! PFWRO1      SURFACE RUN-OFF                             kg/m**2/s
! PFWG12      WATER FLUX BETWEEN LAYER 1 AND 2            kg/m**2/s
! PFWMLT      WATER FLUX CORRESPONDING TO SNOW MELT       kg/m**2/s
! PFWEV      EVAPORATION OVER LAND SURFACE               kg/m**2/s
! PENES      SOIL ENERGY per unit area                   J/M**2
! KPP OCEAN MODEL and FLAKE
! PDIFM      
! PDIFT
! PDIFS
! PTLICEE1,PTLMNWE1,PTLWMLE1,PTLBOTE1,PTLSFE1&
! PHLICEE1,PHLMLE1,PUOE1,PVOE1,PTOE1,PSOE1
! PDHTSS     Diagnostic array for snow T (see module yomcdh)
! PDHTTS     Diagnostic array for soil T (see module yomcdh)
! PDHTIS     Diagnostic array for ice T (see module yomcdh)
! PDHSSS     Diagnostic array for snow mass (see module yomcdh)
! PDHIIS     Diagnostic array for interception layer (see module yomcdh)
! PDHWLS     Diagnostic array for soil water (see module yomcdh)


! PUSTRTI    : E-W (INSTANTANEOUS) SURFACE STRESS FOR EACH TILE
! PVSTRTI    : N-S (INSTANTANEOUS) SURFACE STRESS FOR EACH TILE
! PAHFSTI    : (INSTANTANEOUS) SURFACE SENSIBLE HEAT FLUX FOR EACH TILE
! PEVAPTI       : (INSTANTANEOUS) EVAPORATION FOR EACH TILE



! OUTPUT PARAMETERS ARE STORED IN YOMSEKF FOR THE NEXT TIME STEP, IN THE SKF_* VARIABLES

!     Modifications.
!     --------------
!     P de Rosnay 20-10-2009 separate out and inout restorage and different cases 
!                            of initialization from ocean_ml_driver_mod.F90

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

USE PARKIND1  ,ONLY : JPIM     ,JPRB
USE YOMHOOK   ,ONLY : LHOOK,   DR_HOOK
!USE YOEPHY    ,ONLY : LEOCML
!USE YOMLUN   , ONLY : NULOUT

USE YOMSEKF  , ONLY : &
   & SKF_ZWSA,SKF_ZTSA,&
   & SKF_PZO,SKF_PHO,&
   & SKF_PHO_INV,SKF_PDO,SKF_PADVT,&
   & SKF_PADVS,SKF_PTRI0,SKF_PTRI1,SKF_PSWDK_SAVE,&
   & SKF_PUO0,SKF_PVO0,SKF_PTO0,SKF_PSO0,&
   & SKF_PUSTRC, SKF_PVSTRC,SKF_PUOC,SKF_PVOC, &
!   & SKF_PFTG12,SKF_PFWROD&
    & SKF_PFWRO1,&
!   & SKF_PFWG12, SKF_PFWMLT,SKF_PFWEV,&
!   & SKF_PENES,  SKF_PDIFM, 
!   & SKF_PDIFT, SKF_PDIFS,&   
   & SKF_PSNSE1,SKF_PTSNE1,SKF_PASNE1,SKF_PRSNE1,SKF_PTSAE1,SKF_PTIAE1,&
   & SKF_PWLE1,SKF_PWSAE1,& 
!  & SKF_PTLICEE1,&
!  & SKF_PTLMNWE1,&
!   & SKF_PTLWMLE1,SKF_PTLBOTE1,SKF_PTLSFE1,&
!   & SKF_PHLICEE1,SKF_PHLMLE1,&
   & SKF_PUOE1,SKF_PVOE1,SKF_PTOE1,SKF_PSOE1,&
! out of vdf that are insurftstp
   & SKF_ZEVAPSNW,SKF_PUSTRTI,SKF_PVSTRTI,SKF_PAHFSTI,SKF_PEVAPTI,SKF_ZFRSOTI


IMPLICIT NONE

! INPUT PARAMETERS 
INTEGER(KIND=JPIM),INTENT(IN)    :: KSTART
INTEGER(KIND=JPIM),INTENT(IN)    :: KSTEP
INTEGER(KIND=JPIM),INTENT(IN)    :: KJ
INTEGER(KIND=JPIM),INTENT(IN)    :: KJREF
INTEGER(KIND=JPIM),INTENT(IN)    :: KIDIA 
INTEGER(KIND=JPIM),INTENT(IN)    :: KFDIA 
INTEGER(KIND=JPIM),INTENT(IN)    :: KLON 
INTEGER(KIND=JPIM),INTENT(IN)    :: KLEV 
INTEGER(KIND=JPIM),INTENT(IN)    :: KLEVS
INTEGER(KIND=JPIM),INTENT(IN)    :: KLEVO
INTEGER(KIND=JPIM),INTENT(IN)    :: KSTGLO
INTEGER(KIND=JPIM),INTENT(IN)    :: KTILES
LOGICAL           ,INTENT(IN)    :: LDOCN_KPP(KLON)


! OUTPUT VARIABLES (TO RESTORE)

REAL(KIND=JPRB)   ,INTENT(INOUT)    :: PWSA(KLON,KLEVS)
REAL(KIND=JPRB)   ,INTENT(INOUT)    :: PTSA(KLON,KLEVS)

REAL(KIND=JPRB), INTENT(INOUT)      :: PZO(KLON,KLEVO+1)
REAL(KIND=JPRB), INTENT(INOUT)      :: PHO(KLON,KLEVO+1)
REAL(KIND=JPRB), INTENT(INOUT)      :: PHO_INV(KLON,KLEVO+1)
REAL(KIND=JPRB), INTENT(INOUT)      :: PDO(KLON,0:KLEVO)
REAL(KIND=JPRB), INTENT(INOUT)      :: PADVT(KLON,KLEVO+1)
REAL(KIND=JPRB), INTENT(INOUT)      :: PADVS(KLON,KLEVO+1)
REAL(KIND=JPRB), INTENT(INOUT)      :: PTRI0(KLON,0:KLEVO)
REAL(KIND=JPRB), INTENT(INOUT)      :: PTRI1(KLON,0:KLEVO)
REAL(KIND=JPRB), INTENT(INOUT)      :: PSWDK_SAVE(KLON,0:KLEVO)
REAL(KIND=JPRB), INTENT(INOUT)      :: PUO0(KLON,KLEVO+1)
REAL(KIND=JPRB), INTENT(INOUT)      :: PVO0(KLON,KLEVO+1)
REAL(KIND=JPRB), INTENT(INOUT)      :: PTO0(KLON,KLEVO+1)
REAL(KIND=JPRB), INTENT(INOUT)      :: PSO0(KLON,KLEVO+1)

REAL(KIND=JPRB)   ,INTENT(INOUT)    :: PUOC(KLON,KLEVO+1)
REAL(KIND=JPRB)   ,INTENT(INOUT)    :: PVOC(KLON,KLEVO+1)
REAL(KIND=JPRB)   ,INTENT(INOUT)    :: PUSTRC(KLON)
REAL(KIND=JPRB)   ,INTENT(INOUT)    :: PVSTRC(KLON)
REAL(KIND=JPRB)   ,INTENT(INOUT)    :: PFTG12(KLON)
REAL(KIND=JPRB)   ,INTENT(INOUT)    :: PFWROD(KLON)
REAL(KIND=JPRB)   ,INTENT(INOUT)    :: PFWRO1(KLON)
REAL(KIND=JPRB)   ,INTENT(INOUT)    :: PFWG12(KLON)
REAL(KIND=JPRB)   ,INTENT(INOUT)    :: PFWMLT(KLON)
REAL(KIND=JPRB)   ,INTENT(INOUT)    :: PFWEV(KLON)
REAL(KIND=JPRB)   ,INTENT(INOUT)    :: PENES(KLON,KLEV)
REAL(KIND=JPRB)   ,INTENT(INOUT)    :: PDIFM(KLON,0:KLEVO+1)         
REAL(KIND=JPRB)   ,INTENT(INOUT)    :: PDIFT(KLON,0:KLEVO+1)        
REAL(KIND=JPRB)   ,INTENT(INOUT)    :: PDIFS(KLON,0:KLEVO+1)      
REAL(KIND=JPRB)   ,INTENT(INOUT)    :: PSNSE1(KLON)
REAL(KIND=JPRB)   ,INTENT(INOUT)    :: PTSNE1(KLON)
REAL(KIND=JPRB)   ,INTENT(INOUT)    :: PASNE1(KLON)
REAL(KIND=JPRB)   ,INTENT(INOUT)    :: PRSNE1(KLON)
REAL(KIND=JPRB)   ,INTENT(INOUT)    :: PTSAE1(KLON,KLEVS)
REAL(KIND=JPRB)   ,INTENT(INOUT)    :: PTIAE1(KLON,KLEVS)
REAL(KIND=JPRB)   ,INTENT(INOUT)    :: PWLE1(KLON)
REAL(KIND=JPRB)   ,INTENT(INOUT)    :: PWSAE1(KLON,KLEVS)
REAL(KIND=JPRB)   ,INTENT(INOUT)    :: PTLICEE1(KLON)
REAL(KIND=JPRB)   ,INTENT(INOUT)    :: PTLMNWE1(KLON)
REAL(KIND=JPRB)   ,INTENT(INOUT)    :: PTLWMLE1(KLON)
REAL(KIND=JPRB)   ,INTENT(INOUT)    :: PTLBOTE1(KLON)
REAL(KIND=JPRB)   ,INTENT(INOUT)    :: PTLSFE1(KLON)
REAL(KIND=JPRB)   ,INTENT(INOUT)    :: PHLICEE1(KLON)
REAL(KIND=JPRB)   ,INTENT(INOUT)    :: PHLMLE1(KLON)
REAL(KIND=JPRB)   ,INTENT(INOUT)    :: PUOE1(KLON,KLEVO+1)
REAL(KIND=JPRB)   ,INTENT(INOUT)    :: PVOE1(KLON,KLEVO+1)
REAL(KIND=JPRB)   ,INTENT(INOUT)    :: PTOE1(KLON,KLEVO+1)
REAL(KIND=JPRB)   ,INTENT(INOUT)    :: PSOE1(KLON,KLEVO+1)

!input surfstp but out vdf
REAL(KIND=JPRB)   ,INTENT(INOUT)   :: PEVAPSNW(KLON)
REAL(KIND=JPRB)   ,INTENT(INOUT)   :: PUSTRTI(KLON,KTILES)
REAL(KIND=JPRB)   ,INTENT(INOUT)   :: PVSTRTI(KLON,KTILES)
REAL(KIND=JPRB)   ,INTENT(INOUT)   :: PAHFSTI(KLON,KTILES)
REAL(KIND=JPRB)   ,INTENT(INOUT)   :: PEVAPTI(KLON,KTILES)
REAL(KIND=JPRB)   ,INTENT(INOUT)   :: PFRSOTI(KLON,KTILES)




! LOCAL VARIABLE 

REAL(KIND=JPRB) :: ZHOOK_HANDLE
INTEGER(KIND=JPIM)  :: JL,IBLK

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


! RESTORE VARIABLES of the KJth run
! KJ=1 : store/restore reference inout only
! KJ=2 : Offline / perturbe SM layer1
! KJ=3 : Offline / perturbe SM layer2
! KJ=4 : Offline / perturbe SM layer3
! KJ=5 : Offline / non perturbed


IBLK=(KSTGLO-1)/KLON + 1

! 1. Restore surftstp's out variables:
!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
! Restore after Kstep or for perturbed loops
! ie store in all case except for (KSTART.and.kj=1)

!IF(KSTEP /= KSTART) THEN
IBLK=(KSTGLO-1)/KLON + 1
!IF(IBLK.eq.52) THEN
!write(nulout,*) 'restoresurfstp, inputJK:',KJ
!write(nulout,*) 'ZWSA ', PWSA(53,:)
!write(nulout,*) 'SKF ',SKF_ZWSA(53,IBLK,:,KJ)
!ENDIF

  DO JL=KIDIA,KFDIA
    PWSA(JL,1:KLEVS) = SKF_ZWSA(JL,IBLK,1:KLEVS,KJ)
    PTSA(JL,1:KLEVS) = SKF_ZTSA(JL,IBLK,1:KLEVS,KJ)

! input surftstp (from output vdf)
  PEVAPSNW(JL) = SKF_ZEVAPSNW(JL,IBLK,KJ)
  PUSTRTI(JL,1:KTILES) = SKF_PUSTRTI(JL,IBLK,1:KTILES,KJ)
  PVSTRTI(JL,1:KTILES) = SKF_PVSTRTI(JL,IBLK,1:KTILES,KJ)
  PAHFSTI(JL,1:KTILES) = SKF_PAHFSTI(JL,IBLK,1:KTILES,KJ)
  PEVAPTI(JL,1:KTILES) = SKF_PEVAPTI(JL,IBLK,1:KTILES,KJ)
  PFRSOTI(JL,1:KTILES) = SKF_ZFRSOTI(JL,IBLK,1:KTILES,KJ)



!    PFTG12(JL) = SKF_PFTG12(JL,IBLK,KJREF) 
!    PFWROD(JL) = SKF_PFWROD(JL,IBLK,KJREF) 
!    PFWG12(JL) = SKF_PFWG12(JL,IBLK,KJREF) 
!    PFWMLT(JL) = SKF_PFWMLT(JL,IBLK,KJREF) 
!    PFWEV(JL) = SKF_PFWEV(JL,IBLK,KJREF) 
!    PENES(JL,:) = SKF_PENES(JL,IBLK,:,KJREF) 
!    PDIFM(JL,:) = SKF_PDIFM(JL,IBLK,:,KJREF) 
!    PDIFT(JL,:) = SKF_PDIFT(JL,IBLK,:,KJREF) 
!    PDIFS(JL,:) = SKF_PDIFS(JL,IBLK,:,KJREF) 
!    PTLICEE1(JL) = SKF_PTLICEE1(JL,IBLK,KJREF) 
!    PTLMNWE1(JL) = SKF_PTLMNWE1(JL,IBLK,KJREF) 
!    PTLWMLE1(JL) = SKF_PTLWMLE1(JL,IBLK,KJREF) 
!    PTLBOTE1(JL) = SKF_PTLBOTE1(JL,IBLK,KJREF) 
!    PTLSFE1(JL) = SKF_PTLSFE1(JL,IBLK,KJREF) 
!    PHLICEE1(JL) = SKF_PHLICEE1(JL,IBLK,KJREF) 
!    PHLMLE1(JL) = SKF_PHLMLE1(JL,IBLK,KJREF) 
!
! include inout variables that could be just out variables (diagnosed below surftstp):
!    PFWRO1(JL) = SKF_PFWRO1(JL,IBLK,KJREF) 

  ENDDO
!ENDIF 


! 2. Restore surftstp's inout variables already initialized in callpar:
!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
DO JL=KIDIA,KFDIA
  PSNSE1(JL) = SKF_PSNSE1(JL,IBLK,KJREF) 
  PTSNE1(JL) = SKF_PTSNE1(JL,IBLK,KJREF) 
  PASNE1(JL) = SKF_PASNE1(JL,IBLK,KJREF) 
  PRSNE1(JL) = SKF_PRSNE1(JL,IBLK,KJREF) 
  PTIAE1(JL,1:KLEVS) = SKF_PTIAE1(JL,IBLK,1:KLEVS,KJREF) 
  PWLE1(JL) = SKF_PWLE1(JL,IBLK,KJREF) 
  PFWRO1(JL) = SKF_PFWRO1(JL,IBLK,KJREF) 

  PTSAE1(JL,1:KLEVS) = SKF_PTSAE1(JL,IBLK,1:KLEVS,KJREF) 
  PWSAE1(JL,1:KLEVS) = SKF_PWSAE1(JL,IBLK,1:KLEVS,KJREF) 
ENDDO


! 3. Restore surftstp's inout variables initialized below surftstp:
!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
! Skip the restore of this variables for KSTART

IF(KSTEP /= KSTART) THEN
DO JL=KIDIA,KFDIA
! Take care not to restore not computed variables (KPP not coupled points)
  IF( LDOCN_KPP(JL) ) THEN
    PZO(JL,1:KLEVO+1) = SKF_PZO(JL,IBLK,1:KLEVO+1,KJREF) 
    PHO(JL,1:KLEVO+1) = SKF_PHO(JL,IBLK,1:KLEVO+1,KJREF) 
    PDO(JL,0:KLEVO) = SKF_PDO(JL,IBLK,0:KLEVO,KJREF) 
    PHO_INV(JL,1:KLEVO+1) = SKF_PHO_INV(JL,IBLK,1:KLEVO+1,KJREF) 
    PUO0(JL,1:KLEVO+1) = SKF_PUO0(JL,IBLK,1:KLEVO+1,KJREF) 
    PVO0(JL,1:KLEVO+1) = SKF_PVO0(JL,IBLK,1:KLEVO+1,KJREF) 
    PTO0(JL,1:KLEVO+1) = SKF_PTO0(JL,IBLK,1:KLEVO+1,KJREF) 
    PSO0(JL,1:KLEVO+1) = SKF_PSO0(JL,IBLK,1:KLEVO+1,KJREF) 
    PUOE1(JL,1:KLEVO+1) = SKF_PUOE1(JL,IBLK,1:KLEVO+1,KJREF) 
    PVOE1(JL,1:KLEVO+1) = SKF_PVOE1(JL,IBLK,1:KLEVO+1,KJREF) 
    PTOE1(JL,1:KLEVO+1) = SKF_PTOE1(JL,IBLK,1:KLEVO+1,KJREF) 
    PSOE1(JL,1:KLEVO+1) = SKF_PSOE1(JL,IBLK,1:KLEVO+1,KJREF) 
    PADVT(JL,1:KLEVO+1) = SKF_PADVT(JL,IBLK,1:KLEVO+1,KJREF) 
    PADVS(JL,1:KLEVO+1) = SKF_PADVS(JL,IBLK,1:KLEVO+1,KJREF) 
    PTRI0(JL,0:KLEVO) = SKF_PTRI0(JL,IBLK,0:KLEVO,KJREF) 
    PTRI1(JL,0:KLEVO) = SKF_PTRI1(JL,IBLK,0:KLEVO,KJREF) 
    PSWDK_SAVE(JL,0:KLEVO) = SKF_PSWDK_SAVE(JL,IBLK,0:KLEVO,KJREF) 
    PUOC(JL,0:KLEVO) = SKF_PUOC(JL,IBLK,0:KLEVO,KJREF)
    PVOC(JL,0:KLEVO) = SKF_PVOC(JL,IBLK,0:KLEVO,KJREF)
    PUSTRC(JL) = SKF_PUSTRC(JL,IBLK,KJREF)
    PVSTRC(JL) = SKF_PVSTRC(JL,IBLK,KJREF)
!  ELSE
!    PUOE1(JL,1:KLEVO+1) = 0.0_JPRB 
!    PVOE1(JL,1:KLEVO+1) = 0.0_JPRB 
!    PTOE1(JL,1:KLEVO+1) = 0.0_JPRB 
!    PSOE1(JL,1:KLEVO+1) = 0.0_JPRB 
!    PSWDK_SAVE(JL,0:KLEVO) = 0.0_JPRB
  ENDIF
ENDDO
ENDIF

!IF(IBLK.eq.52) THEN
!write(nulout,*) 'restoresurfstp, outputJK:',KJ
!write(nulout,*) 'ZWSA ', PWSA(53,:)
!write(nulout,*) 'ZTSA ', PTSA(53,:)
!write(nulout,*) 'SKF ',SKF_ZWSA(53,IBLK,:,KJ)
!ENDIF
IF (LHOOK) CALL DR_HOOK('RESTORE_SURFTSTP',1,ZHOOK_HANDLE)
END SUBROUTINE RESTORE_SURFTSTP
