************************************************************************
      SUBROUTINE ADAMS
************************************************************************
      IMPLICIT REAL*8(A-H,O-Z),INTEGER*4(I-N)

*** CONSTANT
      COMMON /QCONST/PAI,RAD,DEG,RE,CVLCTY

*** INPUT
      PARAMETER (NSPEC=4)
      COMMON /QPARAM/RREF,RBTM,RREFP,
     &               PF0(NSPEC),GF0(NSPEC),
     &               XN0,THERM,ETA(NSPEC),SHINV(NSPEC),SHINVP,
     &               RRLI,HWLI,
     &               XLPP,HWPP,ERPP,DRR1,DTH1,DPH1,DRR2,DTH2,DPH2,
     &               RRMIN,RRMAX,ERRR,ERRA,HMIN,DISOUT,
     &               NPATH,NLPMAX,INDOUT,INDMSH,IEOF,
     &               IYEAR,IMNTH,IDATE
      COMMON /QINIT /R0,T0,P0,E0,D0,F0
      COMMON /QPATH /FKC,DEL,EPS,GMU,ALF,RAY

*** OUTPUT
      COMMON /QCOND /L,LL,NN,NLOOP,A

*** Variables below are only used in the ADAMS method.
      COMMON /QADAM /Y(8),P(8),F(8),
     &               H,HOLD,WT(8),PHI(8,14),PSIOLD(12),
     &               PSI(12),BETA(12),SIGMA(13),G(13),
     &               ERKM1,ERK,K,KOLD,
     &               KNEW,KS,IPHASE,IFAIL
      REAL*8 SUML(8)

      CALL OUT0

*** Initialization of Y
      Y(1)  = R0
      Y(2)  = T0
      Y(3)  = P0
      EPS   = E0
      DEL   = D0
      FKC   = F0
      Y(4)  = COS(EPS*RAD)*COS(DEL*RAD)
      Y(5)  = COS(EPS*RAD)*SIN(DEL*RAD)
      Y(6)  = SIN(EPS*RAD)
      Y(7)  = 0.0D0
      Y(8)  = 0.0D0

      L       = 0
      LL      = 0
      NN      = 0
      NLOOP   = 0
      ERR0  = MAX(ERRR,ERRA)
      ERRR  = ERRR/ERR0
      ERRA  = ERRA/ERR0

* Derivative for Y
      CALL FUNCT(Y,F,1)

      yp20 = F(2)

      do L=1,8
         WT(L)=ERRR*dABS(Y(L)+ERRA)
         SUML(L) = (F(L)/WT(L))**2
      enddo

      SUM = 0.0D0
      do L=1,8
         SUM = SUM+SUML(L)
      enddo
      SUM    = DSQRT(SUM)
      H      = 0.00001D0*dSQRT(ERR0/SUM)
      HOLD   = 0.0D0
      K      = 1
      KOLD   = 0
      IPHASE = 1
      IFAIL  = 0

      do L=1,8
         PHI(L,1) = F(L)
         PHI(L,2) = 0.0D0
      enddo

      CALL OUT1(Y)

      DO NLOOP=0,NLPMAX-1
* Adams-Bashforth Predictor
         CALL ADAM_B(NLOOP)
* Adams-Moulton Corrector
         CALL ADAM_M(ERR0,NLOOP)

*VOCL LOOP,SCALAR
         IF(LL.EQ.0) THEN
            IF(IFAIL.NE.0) THEN
               L=11
            ELSE
               IF(L.GE.21) THEN
                  LL=L
               ELSE IF(H.LT.HMIN) THEN
                  L =23
                  LL=23
               ELSE IF(Y(1).LT.RRMIN) THEN
                  L =24
                  LL=24
               ELSE IF(Y(1).GT.RRMAX) THEN
                  L =25
                  LL=25
C               ELSE IF((T0-90.0)*F(2).GT.0.0D0) THEN
C                  L =26
C                  LL=26
C               ELSE IF(yp20*yp(2).lt.0.0D0) THEN
C                  L =27
C                  LL=27
               ELSE
                  L =0
                  NN=NN+1
               ENDIF
            ENDIF
         ENDIF

         CALL OUT1(Y)
         IF (LL.NE.0) THEN
            write(*,*) "Stop Condition: ", LL
            GOTO 999
         ENDIF
         do I=1,7
            WT(I)=ERRR*ABS(Y(I)+ERRA)
         enddo
      ENDDO

 999  CONTINUE
      write(*,*) 'Number of LOOP=',NLOOP,', Number of calculation=',A
      write(*,*) 'Last interval=',H,', IFAIL=',IFAIL
      write(21,*)
      write(25,*)

      RETURN
      END

************************************************************************
      SUBROUTINE ADAM_B(NLOOP)
*     Calculation of Adams-Bashforth Predictor      
************************************************************************
      IMPLICIT REAL*8(A-H,O-Z),INTEGER*4(I-N)

      COMMON /QADAM /Y(8),P(8),F(8),
     &               H,HOLD,WT(8),PHI(8,14),PSIOLD(12),
     &               PSI(12),BETA(12),SIGMA(13),G(13),
     &               ERKM1,ERK,K,KOLD,
     &               KNEW,KS,IPHASE,IFAIL

      real*8 ALPHA(12),V(12),W(12)
      save ALPHA,V,W

      G(1)   = 1.0D0
      G(2)   = 0.5D0
      SIGMA(1) = 1.0D0

* KS is the maximum order 
* In case step size is changed, KS->0.
      IF (H .NE.HOLD) KS = 0 
      IF (KS.LE.KOLD) KS = KS + 1

      IF (K.GE.KS) THEN

*** PSI
      do I=KS,K-1
         PSIOLD(I) = PSI(I)
      enddo
      PSI(KS) = H*KS
      do I=KS+1,K
         PSI(I) = PSIOLD(I-1)+H
      enddo

*** ALPHA
      ALPHA(KS) = 1.0D0/DBLE(KS)
      do I=KS+1,K
         ALPHA(I) = H/(PSIOLD(I-1)+H)
      enddo

*** BETA
         BETA(KS) = 1.0D0
         do I=KS+1,K
            BETA(I) = BETA(I-1)*PSI(I-1)/PSIOLD(I-1)
         enddo

*** SIGMA
         SIGMA(KS+1) = 1.0D0
         do I=KS+1,K
            SIGMA(I+1) = I*ALPHA(I)*SIGMA(I)
         enddo

*** G (Integral of C)
         if (KS.EQ.0) write(0,*) 'Error! KS=0'

         if (KS.EQ.1) then
            do I=1,K
               V(I) = 1.0D0/DBLE(I*(I+1))
               W(I) = V(I)
            enddo
         else
            if (K.gt.KOLD) then
               V(K) = 1.0D0/DBLE(K*(K+1))
               do J=1,KS-2
                  V(K-J) = V(K-J)-ALPHA(J+1)*V(K-J+1)
               enddo
            endif
            do IQ=1,K+1-KS
               V(IQ) = V(IQ)-ALPHA(KS)*V(IQ+1)
               W(IQ) = V(IQ)
            enddo
            G(KS+1) = W(1)
         endif
         
         do I=KS+1,K
            do IQ=1,K+1-I
               W(IQ) = W(IQ)-ALPHA(I)*W(IQ+1)
            enddo
            G(I+1) = W(1)
         enddo

      ENDIF

*** PREDICTOR
      do L=1,8

         do I=KS+1,K
            PHI(L,I) = BETA(I)*PHI(L,I)
         enddo
         PHI(L,K+2) = PHI(L,K+1)
         PHI(L,K+1) = 0.0D0

         SUM  = 0.0D0
         do I=K,1, -1
            SUM = SUM + G(I)*PHI(L,I)
            PHI(L,I) = PHI(L,I) + PHI(L,I+1)
         enddo
         P(L) = Y(L) + H * SUM

      enddo

*** Derivative
      CALL FUNCT(P,F,0)

      RETURN
      END

************************************************************************
      SUBROUTINE ADAM_M(ERR0,NLOOP)
*     Calculation of Adams-Moulton Corrector
************************************************************************
      IMPLICIT REAL*8(A-H,O-Z),INTEGER*4(I-N)

      COMMON /QADAM /Y(8),P(8),F(8),
     &               H,HOLD,WT(8),PHI(8,14),PSIOLD(12),
     &               PSI(12),BETA(12),SIGMA(13),G(13),
     &               ERKM1,ERK,K,KOLD,
     &               KNEW,KS,IPHASE,IFAIL

      DIMENSION GSTR(13)
      DATA GSTR/0.500D0  ,0.0833D0 ,0.0417D0 ,0.0264D0 ,0.0188D0 ,
     &          0.0143D0 ,0.0114D0 ,0.00936D0,0.00789D0,0.00679D0,
     &          0.00592D0,0.00524D0,0.00468D0/


      KNEW  = K

*** ERK, ERKM1, ERKM2
      ERK   = 0.0D0
      ERKM1 = 0.0D0
      ERKM2 = 0.0D0
      do L=1,8
         TEMP1 = 1.0D0/WT(L)
         TEMP2 = F(L)-PHI(L,1)
         ERK   = ERK+(TEMP2 *TEMP1)**2
         IF (K.EQ.2) THEN
            ERKM1 = ERKM1+((PHI(L,K  )+TEMP2)*TEMP1)**2
         ELSE IF (K.GT.2) THEN
            ERKM1 = ERKM1+((PHI(L,K  )+TEMP2)*TEMP1)**2
            ERKM2 = ERKM2+((PHI(L,K-1)+TEMP2)*TEMP1)**2
         ENDIF
      enddo

      TEMP = DABS(H)*DSQRT(ERK)
      ERK  = TEMP*SIGMA(K+1)*GSTR(K)
      IF (k.EQ.2) THEN
         ERKM1 = DABS(H)*SIGMA(K  )*GSTR(K-1)*DSQRT(ERKM1)
         IF(ERKM1.LE.0.5D0*ERK) KNEW = K-1
      ELSE IF (K.GT.2) THEN
         ERKM1 = DABS(H)*SIGMA(K  )*GSTR(K-1)*DSQRT(ERKM1)
         ERKM2 = DABS(H)*SIGMA(K-1)*GSTR(K-2)*DSQRT(ERKM2)
         IF(DMAX1(ERKM1,ERKM2).LE.ERK) KNEW = K-1
      ENDIF

*** Validity check
      ERR   = TEMP*(G(K)-G(K+1))
      IF(ERR.LE.ERR0) THEN
         CALL ADAM_UPDATE(ERR0)
      ELSE
         CALL ADAM_RETRY(ERR0)
      ENDIF

      RETURN
      END

************************************************************************
      SUBROUTINE ADAM_UPDATE(ERR0)
************************************************************************
      IMPLICIT REAL*8(A-H,O-Z),INTEGER*4(I-N)

      COMMON /QADAM /Y(8),P(8),F(8),
     &               H,HOLD,WT(8),PHI(8,14),PSIOLD(12),
     &               PSI(12),BETA(12),SIGMA(13),G(13),
     &               ERKM1,ERK,K,KOLD,
     &               KNEW,KS,IPHASE,IFAIL

      DIMENSION GSTR(13),TWO(13)
      DATA GSTR/0.500D0  ,0.0833D0 ,0.0417D0 ,0.0264D0 ,0.0188D0 ,
     &          0.0143D0 ,0.0114D0 ,0.00936D0,0.00789D0,0.00679D0,
     &          0.00592D0,0.00524D0,0.00468D0/
      DATA TWO/   2.0D0,   4.0D0,   8.0D0,  16.0D0,  32.0D0,
     &           64.0D0, 128.0D0, 256.0D0, 512.0D0,1024.0D0,
     &         2048.0D0,4096.0D0,8192.0D0/

      do L=1,8
         Y(L) = P(L) + H * G(K+1) * (F(L)-PHI(L,1))
      enddo
      IFAIL = 0
      KOLD  = K
      HOLD  = H

*** Derivative
      CALL FUNCT(Y,F,1)

      do L=1,8
         PHI(L,K+1) = F(L)-PHI(L,1)
         PHI(L,K+2) = PHI(L,K+1)-PHI(L,K+2)
      enddo
      do I=1,K
         do L=1,8
            PHI(L,I) = PHI(L,I)+PHI(L,K+1)
         enddo
      enddo

      ERKP1 = 0.0D0
      IF(KNEW.EQ.K-1.OR.K.EQ.12) IPHASE=0

      IF(IPHASE.EQ.1) THEN
         K   = K+1
         ERK = ERKP1
         GOTO 500
      ENDIF
      IF(KNEW.EQ.K-1) THEN
         K   = K-1
         ERK = ERKM1
         GOTO 500
      ENDIF

      IF(K+1.LE.KS) THEN

         do L=1,8
            ERKP1 = ERKP1+(PHI(L,K+2)/WT(L))**2
         enddo
         ERKP1 = DABS(H)*GSTR(K+1)*DSQRT(ERKP1)

         IF(K.LE.1) THEN
            IF(ERKP1.LT.0.5D0*ERK) THEN
               K   = K+1
               ERK = ERKP1
            ENDIF
            GOTO 500
         ENDIF
         
         IF(ERKM1.LE.DMIN1(ERK,ERKP1)) THEN
            K   = K-1
            ERK = ERKM1
         ELSE IF(ERKP1.LT.ERK .AND. K.NE.12) THEN
            K   = K+1
            ERK = ERKP1
         ENDIF
      ENDIF

 500  CONTINUE

*** H ->>
      IF (ERK*TWO(K+1).LT.0.5D0*ERR0 .OR. IPHASE.EQ.1) THEN
         HNEW = 1.01D0*H
         GOTO 1000
      ENDIF

*** <<- H
      IF (ERK.GT.0.5D0*ERR0) THEN
         R    = (0.5D0*ERR0/ERK)**(1.0D0/DBLE(K+1))
         HNEW =  DMIN1(0.9D0,DMAX1(0.5D0,R)) * H
         GOTO 1000
      ENDIF

*** -> H <-
      HNEW = H
 1000 CONTINUE
      H = HNEW
      WRITE(25,800) Y(1)-6370.0, HNEW, ERK
 800  FORMAT(F18.2, F18.6, F18.8)

      RETURN
      END

************************************************************************
      SUBROUTINE ADAM_RETRY(ERR0)
************************************************************************
      IMPLICIT REAL*8(A-H,O-Z),INTEGER*4(I-N)

      COMMON /QADAM /Y(8),P(8),F(8),
     &               H,HOLD,WT(8),PHI(8,14),PSIOLD(12),
     &               PSI(12),BETA(12),SIGMA(13),G(13),
     &               ERKM1,ERK,K,KOLD,
     &               KNEW,KS,IPHASE,IFAIL

      IPHASE = 0
      do I=1,K
         do L=1,8
            PHI(L,I) = (PHI(L,I)-PHI(L,I+1))/BETA(I)
         enddo
      enddo
      do I = 2,K
         PSI(I-1) = PSI(I)-H
      enddo

      IFAIL = IFAIL+1
* Euler method
      IF (IFAIL.GE.3) KNEW = 1
      K = KNEW
      
      IF (IFAIL.GT.3 .AND. 0.5D0*ERR0.LT.0.25D0*ERK) THEN
         H = DSQRT(0.5D0*ERR0/ERK) * H
      ELSE
         H = 0.5D0 * H
      ENDIF

*** Derivative
      CALL FUNCT(Y,F,1)
            
      RETURN
      END