*     *************************************************************************

      subroutine fdelhf( iel, elptr, elvar, xst, x, w1, w2,
     +                   hptr,  fuval,  nefval,  inform )

*     *************************************************************************

*     Purpose :
*     ---------

*     This routine estimates the IELth element Hessian matrix
*     by forward differences in the element function values.
*     This IELth element Hessian has an elemental representation.

*     Every time information on the element function value is needed,
*     a return is made to the main program. This routine is then
*     re-entered with the information available and the calculation
*     proceeds.

*     Parameters :
*     ------------

*     iel     ( int )

*       input  : the indice of the element Hessian matrix
*                that will be estimated.
*       output : unmodified.

*     elptr   ( int )

*       input  : array whose kth value is the position of
*                the first variable of element k, in the
*                list ELVAR.
*       output : unmodified.

*     elvar   ( int )

*       input  : array containing the indices of the varaibles
*                in the first element, followed by those in the
*                second element, etc.
*       output : unmodified.

*     xst     ( int )

*       input  : vector containing the status of the variables.
*       output : unmodified.

*     x       ( dble )

*       input  : the current iterate vector.
*       output : unmodified.

*     w1      ( dble )

*       input  : array used as workspace.
*       output : meaningless.

*     w2      ( dble )

*       input  : array used as workspace.
*       output : meaningless.

*     hptr    ( int )

*       input  : array whose ith value is the position of the
*                first component of the ith element Hessian
*                in FUVAL.
*       output : unmodified.

*     fuval   ( dble )

*       input  : array used to store the function and derivative
*                values of the element functions.
*       output : the components of indices HPTR(IEL) up to
*                HPTR(IEL+1)-1 will be set to the estimate
*                of the element Hessian matrix by forward
*                differences in the element function values.

*     nefval  ( int )

*       input  : the number of element function evaluations.
*       output : this number is increased by one each time
*                one element function needs to be evaluated.

*     inform  ( int )

*       input  : must be set to zero the first time this routine
*                is called.
*                If it is not equal to zero, the routine is re-entered
*                with an element function value that was needed
*                to proceed the calculation.
*       output : If it is not equal to zero, an element function
*                value is needed to proceed the calculation. A return
*                is then made to the main program.
*                Otherwise, no further information is needed.

*     Routines used :
*     ---------------

*     max, abs, sign.
*     gxfix, dsetvl.

*     Programming :
*     -------------

*     D. Tuyttens

*     ========================================================================

*     Routine parameters

      integer           iel, elptr(*), elvar(*), xst(*),
     +                  hptr(*), nefval, inform
      double precision  x(*), w1(*), w2(*), fuval(*)

*     Internal variables

      integer           i, j, k, ik, kk, eldim, debh,
     +                  isout, ieout, isin, iein
      logical           gxfix
      double precision  thrdem, tempf, tempx, tempxx

*     Save variables

      save              i, j, k, ik, kk, eldim, debh,
     +                  isout, ieout, isin, iein
      save              thrdem, tempf, tempx, tempxx

*     Common specifications

      double precision  epsmch, huge, tiny, tol
      common / prbmch / epsmch, huge, tiny, tol

      double precision  zero, one, two, three, half, tenm1, tenm2, tenm4
      common / prbcst / zero, one, two, three, half, tenm1, tenm2, tenm4
*
*     Reverse communication test.
*
      if( inform.eq.8  ) goto 100
      if( inform.eq.9  ) goto 200
      if( inform.eq.10 ) goto 300
*
*     Estimate of the IELth element Hessian matrix by
*     forward differences in the element function values.
*
      thrdem = epsmch**(one/three)
      eldim  = elptr(iel+1) - elptr(iel)
      tempf  = fuval(iel)
      ik = 0
      isout = elptr(iel)
      ieout = elptr(iel+1)-1
      if ( ieout .ge. isout ) then
        i = isout
 10     continue
        k  = elvar(i)
        ik = ik + 1
        if( gxfix(xst(k)) ) then
          w2(ik) = tempf
        else
          tempx  = x(k)
          w1(ik) = thrdem * sign( max(abs(tempx),one) , tempx )
          x(k)   = tempx + w1(ik)
          nefval = nefval + 1
          inform = 8
          return
*
*         Element function evaluation.
*
 100      continue
          x(k) = tempx
          inform = 0
          w2(ik) = fuval(iel)
        endif
        i = i + 1
        if ( i .le. ieout ) go to 10
      endif
*
      debh = hptr(iel)
      ik = 0
      if ( ieout .ge. isout ) then
        i = isout
 20     continue
        k  = elvar(i)
        ik = ik + 1
        if( gxfix(xst(k)) ) then
          call dsetvl( eldim-ik+1, fuval(debh), 1, zero )
        else
          tempx = x(k)
          x(k)  = tempx + w1(ik)
          isin = ik+1
          iein = eldim
          if ( iein .ge. isin ) then
            j = isin
 30         continue
            kk = elvar(elptr(iel)+j-1)
            if( gxfix(xst(kk)) ) then
              fuval(debh+j-ik) = zero
            else
              tempxx = x(kk)
              x(kk)  = tempxx + w1(j)
              nefval = nefval + 1
              inform = 9
              return
*
*             Element function evaluation.
*
 200          continue
              x(kk)  = tempxx
              inform = 0
              fuval(debh+j-ik) = ((tempf-w2(j))+(fuval(iel)-w2(ik))) /
     +                           (w1(ik)*w1(j))
            endif
            j = j + 1
            if ( j .le. iein ) go to 30
          endif
          x(k)   = tempx + 2.0d0*w1(ik)
          nefval = nefval + 1
          inform = 10
          return
*
*         Element function evaluation.
*
 300      continue
          x(k)   = tempx
          inform = 0
          fuval(debh) = ((tempf-w2(ik))+(fuval(iel)-w2(ik))) /
     +                  (w1(ik)*w1(ik))
        endif
        debh = debh + eldim - ik + 1
        i = i + 1
        if ( i .le. ieout ) go to 20
      endif
      fuval(iel) = tempf
*
      return
      end