SUBROUTINE svvarbc(pcvparam,knparam)
!-----------------------------------------------------------------------
!   SVVARBC - Save results of variational bias parameter estimation

!   Purpose.
!   --------
!   Update and save variational bias parameters after minimization

!   Interface.
!   ----------
!   CALL svvarbc(pcvparam,knparam)

!   Input arguments:
!      pcvparam  - parameter section of the control vector
!      knparam   - length of pcvparam

!   Implicit input:
!      YVARBC

!   Author.
!   -------
!   Dick Dee (ECMWF)

!   Modifications.
!   --------------
!   Original    2004/03/19
!        P.Burton :  29-09-04 LVARBC cleanup
!        V.Guidard:  10-03-08 Add arg to call WRVARBC
!-----------------------------------------------------------------------

USE parkind1, ONLY : JPIM, JPRB
USE yomhook , ONLY : lhook, dr_hook
USE varbc_setup, ONLY : YVARBC, NOBGROUP, NOBPARAM, JPMXNPARAM, &
                      & varbc_save, varbc_print
USE yomvar,   ONLY : LINITCV, LTOVSCV
USE yomancs , ONLY : RMDI

IMPLICIT NONE

INTEGER(KIND=JPIM),INTENT(IN) :: knparam 
REAL(KIND=JPRB)   ,INTENT(IN) :: pcvparam(knparam) 

INTEGER(KIND=JPIM) :: jg, ibeg, iend, jp, inp
REAL(KIND=JPRB)    :: zp(JPMXNPARAM)
REAL(KIND=JPRB)    :: zhook_handle

#include "abor1.intfb.h"
#include "cvarbcin.intfb.h"

IF (lhook) CALL dr_hook('SVVARBC',0,zhook_handle)

IF (knparam/=NOBPARAM) CALL ABOR1('SVVARBC: knparam/=NOBPARAM')

! Put cv parameters into table
! ----------------------------
ibeg = 1
DO jg = 1, NOBGROUP
  iend = ibeg + YVARBC(jg)%NPARAM - 1
  YVARBC(jg)%APARAMS = pcvparam(ibeg:iend)
  ibeg = iend + 1
ENDDO

! Transform to physical space
! ---------------------------
CALL cvarbcin

! Update the estimates
! --------------------
DO jg = 1, NOBGROUP
  IF (YVARBC(jg)%NCOUNT>0) THEN
      WHERE (YVARBC(jg)%APARAM5 /= RMDI) &
    & YVARBC(jg)%APARAMS = YVARBC(jg)%APARAM5 + YVARBC(jg)%APARAMS
  ELSE
      YVARBC(jg)%APARAMS = YVARBC(jg)%APARAM5
  ENDIF
  IF ((.NOT.LINITCV).AND.(.NOT.LTOVSCV)) THEN
    YVARBC(jg)%APARAM0 = YVARBC(jg)%APARAMS
    YVARBC(jg)%APARAM5 = YVARBC(jg)%APARAMS
  ENDIF
ENDDO

! Write to file
! -------------
!CALL wrvarbc('VARBC.cycle',YVARBC,NOBGROUP,NOBPARAM,MPREDXHST(1:NOBGROUP,:))
CALL varbc_save

! Transform gradient values to parameter space, for printing
! ----------------------------------------------------------
DO jg = 1, NOBGROUP
  inp = YVARBC(jg)%NPARAM
  DO jp = 1, inp
    zp(jp) = SUM(YVARBC(jg)%ACVARIN(jp,:) * YVARBC(jg)%AGRAD(1:inp))
  ENDDO
  YVARBC(jg)%AGRAD = zp(1:inp)  
  DO jp = 1, inp
    zp(jp) = SUM(YVARBC(jg)%ACVARIN(jp,:) * YVARBC(jg)%AGRAD0(1:inp))
  ENDDO
  YVARBC(jg)%AGRAD0 = zp(1:inp)  
ENDDO

! Print the table
! ---------------
CALL varbc_print(1)  ! Final parameter values
CALL varbc_print(3)  ! Final gradient values
CALL varbc_print(4)  ! Final gradient reductions

IF (lhook) CALL dr_hook('SVVARBC',1,zhook_handle)

END SUBROUTINE svvarbc
