      SUBROUTINE SEARCH(XPARAM,ALPHA,SIG,NVAR,GMIN,OKF, FUNCT)
      implicit double precision (A-H,O-Z)
      include 'SIZES'
      include 'MOP6FILE'
      dimension XPARAM(*), SIG(*)
************************************************************************
*
* SEARCH PERFORMS A LINE SEARCH FOR POWSQ. IT MINIMIZES THE NORM OF
*        THE GRADIENT VECTOR IN THE DIRECTION SIG.
*
* ON INPUT  XPARAM = CURRENT POINT IN NVAR dimensionAL SPACE.
*           ALPHA  = STEP SIZE (IN FACT ALPHA IS CALCULATED IN SEARCH).
*           SIG    = SEARCH DIRECTION VECTOR.
*           NVAR   = NUMBER OF PARAMETERS IN SIG (& XPARAM)
*
* ON OUTPUT XPARAM = PARAMETERS OF MINIMUM.
*           ALPHA  = DISTANCE TO MINIMUM.
*           GMIN   = GRADIENT NORM AT MINIMUM.
*           OKF    = FUNCTION WAS IMPROVED.
************************************************************************
      common /SIGMA1/ GNEXT, AMIN, ANEXT
      common /SIGMA2/  GNEXT1(MAXPAR), GMIN1(MAXPAR)
      common/KEYWRD/ KEYWRD
      common /NUMCAL/ NUMCAL
      dimension GRAD(MAXPAR),XREF(MAXPAR), GREF(MAXPAR), XMIN1(MAXPAR)
      character*241 KEYWRD
      logical DEBUG, OKF, NOPR
      save DEBUG, G, XMAXM, TINY, LOOKS, TOLERG
      data ICALCN/0/
      if (ICALCN.NE.NUMCAL) then
         ICALCN=NUMCAL
C
C    TOLG   = CRITERION FOR EXIT BY RELATIVE CHANGE IN GRADIENT.
C
         DEBUG=(INDEX(KEYWRD,'LINMIN') .NE. 0)
         NOPR=( .NOT. DEBUG)
         LOOKS=0
         OKF=.TRUE.
         TINY=0.1D0
         TOLERG=0.02D0
         if (NVAR .EQ. 1) TIMY=0.D0
         G=100.D0
         XMAXM=2.D0
         ALPHA=0.1D0
      end if
      ANEXT1=0.D0
      do 10 I=1,NVAR
         GREF(I)  =GMIN1(I)
         GNEXT1(I)=GMIN1(I)
         XMIN1(I) =XPARAM(I)
   10 XREF(I)  =XPARAM(I)
      if (ABS(ALPHA) .GT. 0.2) ALPHA=SIGN(0.2D0,ALPHA)
      if (DEBUG) then
         write(MIOB,'('' SEARCH DIRECTION VECTOR'')')
         write(MIOB,'(6F12.6)') (SIG(I),I=1,NVAR)
         write(MIOB,'('' INITIAL GRADIENT VECTOR'')')
         write(MIOB,'(6F12.6)') (GMIN1(I),I=1,NVAR)
      end if
      GB=DOT(GMIN1,GREF,NVAR)
      if (DEBUG) write(MIOB,'('' GRADIENT AT START OF SEARCH:'',F16.6)')
     %                     SQRT(GB)
      GSTORE=GB
      AMIN=0.D0
      GMINN=1.D9
C
C
      TA=0.D0
      GA=GB
      GB=1.D9
      ITRYS=0
      go to 30
   20 SUM=GA/(GA-GB)
      ITRYS=ITRYS+1
      if (ABS(SUM) .GT. 3.D0) SUM=SIGN(3.D0,SUM)
      ALPHA=(TB-TA)*SUM+TA
C
C         XPARAM IS THE GEOMETRY OF THE PREDICTED MINIMUM ALONG THE LINE
C
   30 continue
      do 40 I=1,NVAR
   40 XPARAM(I)=XREF(I)+ALPHA*SIG(I)
C
C         CALCULATE GRADIENT NORM AND GRADIENTS AT THE PREDICTED MINIMUM
C
      if (ITRYS.EQ.1) then
         do 50 I=1,NVAR
   50    GRAD(I)=0.D0
      end if
      call COMPFG (XPARAM, .TRUE., FUNCT, .TRUE., GRAD, .TRUE.)
      LOOKS=LOOKS+1
C
C          G IS THE PROJECTION OF THE GRADIENT ALONG SIG.
C
      G=DOT(GREF,GRAD,NVAR)
      GTOT=SQRT(DOT(GRAD,GRAD,NVAR))
      if ( .NOT. NOPR)
     1  write(MIOB,'('' LOOKS'',I3,'' ALPHA ='',F12.6,
     2               '' GRADIENT'',F12.3,'' G  ='',F16.6)')
     3                        LOOKS,ALPHA,SQRT(DOT(GRAD,GRAD,NVAR)),G
      if (GTOT .LT. GMINN) then
         GMINN=GTOT
         if (ABS(AMIN-ALPHA) .GT.1.D-2) then
*
* WE CAN MOVE ANEXT TO A POINT NEAR, BUT NOT TOO NEAR, AMIN, SO THAT THE
* SECOND DERIVATIVESWILLBEREALISTIC(D2E/DX2=(GNEXT1-GMIN1)/(ANEXT-AMIN))
*
            ANEXT=AMIN
            do 60 I=1,NVAR
   60       GNEXT1(I)=GMIN1(I)
         end if
         AMIN=ALPHA
         do 70 I=1,NVAR
            if (GMINN.LT.GMIN) XMIN1(I)=XPARAM(I)
   70    GMIN1(I)=GRAD(I)
         if (GMIN.GT.GMINN) GMIN=GMINN
      end if
      if (ITRYS .GT. 8) go to 80
      if (ABS(G/GSTORE).LT.TINY .OR. ABS(G) .LT. TOLERG) go to 80
      if (ABS(G) .LT. MAX(ABS(GA),ABS(GB)) .OR.
     1     GA*GB .GT. 0.D0 .AND. G*GA .LT. 0.D0) then
C
C   G IS AN IMPROVEMENT ON GA OR GB.
C
         if (ABS(GB) .LT. ABS(GA)) then
            TA=ALPHA
            GA=G
            go to 20
         else
            TB=ALPHA
            GB=G
            go to 20
         end if
      else
C#         write(MIOB,
C#     %     '(//10X,'' FAILED IN SEARCH, SEARCH CONTINUING'')')
         go to 80
      end if
   80 LNSTOP=4
      GMINN=SQRT(DOT(GMIN1,GMIN1,NVAR))
      do 90 I=1,NVAR
   90 XPARAM(I)=XMIN1(I)
      if (DEBUG) then
         write(MIOB,'('' AT EXIT FROM SEARCH'')')
         write(MIOB,'('' XPARAM'',6F12.6)') (XPARAM(I),I=1,NVAR)
         write(MIOB,'('' GNEXT1'',6F12.6)') (GNEXT1(I),I=1,NVAR)
         write(MIOB,'('' GMIN1 '',6F12.6)') (GMIN1(I),I=1,NVAR)
         write(MIOB,'('' AMIN, ANEXT,GMIN'',4F12.6)')
     %              AMIN,ANEXT,GMIN
      end if
      if (GMINN.GT.GMIN) then
         do 100 I=1,NVAR
  100    XPARAM(I)=XREF(I)
      end if
      return
C
      end
