      SUBROUTINE CNINTP (IBTT,IBTM,IRD,YNDEF)
!-----------------------------------------------------------------------
!     PURPOSE:
!     --------
!     EXTRACTION OF INTERPOLATION PARAMETERS FROM TABULATED GROWTH DATA.
!     THIS WILL PROVIDE THE TABULATED IN THE NECESSARY FORMAT FOR
!     SUBSEQUENT CALCULATIONS.
!
!     HISTORY:
!     --------
!     * AUG 11/2006 - K.VONSALZEN   NEW.
!
!-----------------------------------------------------------------------
!
      USE CNPARM
      USE CNPARMT
!
      IMPLICIT REAL (A-H,O-Z), INTEGER (I-N)
!
      INTEGER, DIMENSION(IREG) :: IBTT,IBTM
!
!-----------------------------------------------------------------------
!     * ALLOCATE WORK ARRAYS.
!
      ALLOCATE ( ITMP(IREG) )
      DO IRG=1,IREG
        ALLOCATE (ITMP(IRG)%IPL(IBTT(IRG),IRD))
        ALLOCATE (ITMP(IRG)%IPU(IBTT(IRG),IRD))
        ALLOCATE (ITMP(IRG)%IPD(IBTT(IRG),IRD))
        ALLOCATE (ITMP(IRG)%IPM(IBTM(IRG),IRD))
        ALLOCATE (ITMP(IRG)%IPNL(IBTM(IRG),IRD))
        ALLOCATE (ITMP(IRG)%IPLNKI(IBTM(IRG),IRD))
        ALLOCATE (ITMP(IRG)%IPLNKA(2*RGPNO(IRG)%IRT,IBTM(IRG),IRD))
        ALLOCATE (ITMP(IRG)%IPLNKB(2*RGPNO(IRG)%IRT,IBTM(IRG),IRD))
        ALLOCATE (ITMP(IRG)%ISLNKA(2*RGPNO(IRG)%IRT,IBTM(IRG),IRD) )
        ALLOCATE (ITMP(IRG)%ISLNKB(2*RGPNO(IRG)%IRT,IBTM(IRG),IRD) )
        ALLOCATE (ITMP(IRG)%ICHKB(RGPNO(IRG)%IRT,IBTM(IRG),IRD))
      ENDDO
      DO IRG=1,IREG
!
!       * INITIALIZE WORK ARRAYS.
!
        ITMP(IRG)%IPL(:,:)=IDEF
        ITMP(IRG)%IPU(:,:)=IDEF
        ITMP(IRG)%IPD(:,:)=IDEF
        ITMP(IRG)%IPM(:,:)=IDEF
        ITMP(IRG)%IPNL(:,:)=0
        ITMP(IRG)%IPLNKI(:,:)=IDEF
        ITMP(IRG)%IPLNKA(:,:,:)=IDEF
        ITMP(IRG)%IPLNKB(:,:,:)=IDEF
        ITMP(IRG)%ICHKB(:,:,:)=.FALSE.
!
!       * DETERMINE INDEX OF POINTS ON LOWER BOUNDARY.
!
        DO IRAT=1,IRD
        DO IB=1,IBTT(IRG)
        DO IR=1,RGPNO(IRG)%IRT
          IF ( NINT(RGPNO(IRG)%TP(IR,IB,IRAT)-YNDEF) /= 0 &
                            .AND. ITMP(IRG)%IPL(IB,IRAT) == IDEF ) THEN
            ITMP(IRG)%IPL(IB,IRAT)=IR
          ENDIF
        ENDDO
        ENDDO
        ENDDO
!
!       * DETERMINE INDEX OF POINTS ON UPPER BOUNDARY.
!
        DO IRAT=1,IRD
        DO IB=1,IBTT(IRG)
        DO IR=RGPNO(IRG)%IRT,1,-1
          IF ( NINT(RGPNO(IRG)%TP(IR,IB,IRAT)-YNDEF) /= 0 &
                            .AND. ITMP(IRG)%IPU(IB,IRAT) == IDEF ) THEN
            ITMP(IRG)%IPU(IB,IRAT)=IR
          ENDIF
        ENDDO
        ENDDO
        ENDDO
!
!       * NUMBER OF VALID POINTS.
!
        DO IRAT=1,IRD
        DO IB=1,IBTT(IRG)
          IF ( ITMP(IRG)%IPL(IB,IRAT) /= IDEF &
                            .AND. ITMP(IRG)%IPU(IB,IRAT) /= IDEF ) THEN
            ITMP(IRG)%IPD(IB,IRAT)=ITMP(IRG)%IPU(IB,IRAT) &
                                  -ITMP(IRG)%IPL(IB,IRAT)+1
          ENDIF
        ENDDO
        ENDDO
!
!       * NUMBER OF VALID POINTS FOR INTERPOLATION BETWEEN 2 ADJACENT ROWS.
!
        DO IRAT=1,IRD
        DO IB=1,IBTM(IRG)
          IF ( ITMP(IRG)%IPD(IB,IRAT) /= IDEF &
                          .AND. ITMP(IRG)%IPD(IB+1,IRAT) /= IDEF ) THEN
            IF ( ITMP(IRG)%IPD(IB,IRAT) &
                                     >= ITMP(IRG)%IPD(IB+1,IRAT) ) THEN
              ITMP(IRG)%IPLNKI(IB,IRAT)=0
              ITMP(IRG)%IPM(IB,IRAT)=ITMP(IRG)%IPD(IB,IRAT)
            ELSE
              ITMP(IRG)%IPLNKI(IB,IRAT)=1
              ITMP(IRG)%IPM(IB,IRAT)=ITMP(IRG)%IPD(IB+1,IRAT)
            ENDIF
          ENDIF
        ENDDO
        ENDDO
!
!       * ESTABLISH LINK BETWEEN NEAREST POINTS FOR ADJACENT ROWS.
!       * THESE LINKS START AT POINTS THAT ARE PART OF THE ROW THAT
!       * HAS THE LARGEST TOTAL NUMBER OF POINTS AND CONNECT TO THE
!       * POINTS IN THE ADJACENT ROW SO THAT THE DISTANCE BETWEEN
!       * THE POINTS WILL BE AT ITS MINIMUM.
!
        DO IRAT=1,IRD
        DO IB=1,IBTM(IRG)
          IN=ITMP(IRG)%IPLNKI(IB,IRAT)
          IF ( IN /= IDEF ) THEN
            IBS=IB+IN
            IBE=IB+1-IN
            DO IR1=ITMP(IRG)%IPL(IBS,IRAT),ITMP(IRG)%IPU(IBS,IRAT)
              XPDIFF=YLARGE
              DO IR2=ITMP(IRG)%IPL(IBE,IRAT),ITMP(IRG)%IPU(IBE,IRAT)
                XPDIFFT=ABS(RGPNO(IRG)%XP(IR1,IBS,IRAT) &
                                          -RGPNO(IRG)%XP(IR2,IBE,IRAT))
                IF ( XPDIFFT < XPDIFF ) THEN
                  IR1T=IR1
                  IR2T=IR2
                  XPDIFF=XPDIFFT
                ENDIF
              ENDDO
              ITMP(IRG)%IPNL(IB,IRAT)=ITMP(IRG)%IPNL(IB,IRAT)+1
              IPNLT=ITMP(IRG)%IPNL(IB,IRAT)
              ITMP(IRG)%IPLNKA(IPNLT,IB,IRAT)=IR1T
              ITMP(IRG)%IPLNKB(IPNLT,IB,IRAT)=IR2T
              ITMP(IRG)%ICHKB(IR2T,IB,IRAT)=.TRUE.
            ENDDO
          ENDIF
        ENDDO
        ENDDO
!
!       * CHECK IF THERE ARE ANY POINTS THAT HAVE NOT YET BEEN CONNECTED
!       * IN THE ROW THAT CONTAINS FEWER POINTS. ADD NEW LINKS FOR THESE
!       * POINTS TO THE ARRAY THAT CONTAINS THE PREVIOUS LINKS.
!
        DO IRAT=1,IRD
        DO IB=1,IBTM(IRG)
          IN=ITMP(IRG)%IPLNKI(IB,IRAT)
          IF ( IN /= IDEF ) THEN
            IBS=IB+IN
            IBE=IB+1-IN
            DO IR2=ITMP(IRG)%IPL(IBE,IRAT),ITMP(IRG)%IPU(IBE,IRAT)
              IF ( .NOT.ITMP(IRG)%ICHKB(IR2,IB,IRAT) ) THEN
                XPDIFF=YLARGE
                DO IR1=ITMP(IRG)%IPL(IBS,IRAT),ITMP(IRG)%IPU(IBS,IRAT)
                  XPDIFFT=ABS(RGPNO(IRG)%XP(IR1,IBS,IRAT) &
                                          -RGPNO(IRG)%XP(IR2,IBE,IRAT))
                  IF ( XPDIFFT < XPDIFF ) THEN
                    IR1T=IR1
                    IR2T=IR2
                    XPDIFF=XPDIFFT
                  ENDIF
                ENDDO
                ITMP(IRG)%IPNL(IB,IRAT)=ITMP(IRG)%IPNL(IB,IRAT)+1
                IPNLT=ITMP(IRG)%IPNL(IB,IRAT)
                ITMP(IRG)%IPLNKA(IPNLT,IB,IRAT)=IR1T
                ITMP(IRG)%IPLNKB(IPNLT,IB,IRAT)=IR2T
              ENDIF
            ENDDO
          ENDIF
        ENDDO
        ENDDO
!
!       * SORT LINKS IN ASCENDING ORDER FOR GRID POINT INDICES.
!
        DO IRAT=1,IRD
        DO IB=1,IBTM(IRG)
          IN=ITMP(IRG)%IPLNKI(IB,IRAT)
          IF ( IN /= IDEF ) THEN
            DO IRX1=1,ITMP(IRG)%IPNL(IB,IRAT)
              IMINA=ILARGE
              IMINB=ILARGE
              DO IRX2=1,ITMP(IRG)%IPNL(IB,IRAT)
                IF (     ITMP(IRG)%IPLNKA(IRX2,IB,IRAT) <= IMINA &
                   .AND. ITMP(IRG)%IPLNKB(IRX2,IB,IRAT)  < IMINB ) THEN
                  IMINA=ITMP(IRG)%IPLNKA(IRX2,IB,IRAT)
                  IMINB=ITMP(IRG)%IPLNKB(IRX2,IB,IRAT)
                  IRX2M=IRX2
                ENDIF
              ENDDO
              ITMP(IRG)%ISLNKA(IRX1,IB,IRAT)= &
                                        ITMP(IRG)%IPLNKA(IRX2M,IB,IRAT)
              ITMP(IRG)%ISLNKB(IRX1,IB,IRAT)= &
                                        ITMP(IRG)%IPLNKB(IRX2M,IB,IRAT)
              ITMP(IRG)%IPLNKA(IRX2M,IB,IRAT)=ILARGE
              ITMP(IRG)%IPLNKB(IRX2M,IB,IRAT)=ILARGE
            ENDDO
          ENDIF
        ENDDO
        ENDDO
      ENDDO
!
!     * ALLOCATE OUTPUT ARRAYS.
!
      ALLOCATE ( RGPN(IREG) )
      DO IRG=1,IREG
        ALLOCATE ( RGPN(IRG)%KOPEN(IBTM(IRG),IRD) )
        ALLOCATE ( RGPN(IRG)%IPNTS(IBTM(IRG),IRD) )
        ALLOCATE ( RGPN(IRG)%XP(IBTM(IRG),IRD) )
        ALLOCATE ( RGPN(IRG)%TP(IBTM(IRG),IRD) )
        DO IRAT=1,IRD
        DO IB=1,IBTM(IRG)
          IN=ITMP(IRG)%IPM(IB,IRAT)
          IF ( IN /= IDEF ) THEN
            INS=ITMP(IRG)%IPNL(IB,IRAT)
            ALLOCATE (RGPN(IRG)%XP(IB,IRAT)%PNT(INS))
            ALLOCATE (RGPN(IRG)%XP(IB,IRAT)%DER(INS))
            ALLOCATE (RGPN(IRG)%TP(IB,IRAT)%PNT(INS))
            ALLOCATE (RGPN(IRG)%TP(IB,IRAT)%DER(INS))
          ENDIF
        ENDDO
        ENDDO
      ENDDO

!
!     * INITIALIZE FLAG THAT INDICATES WHETHER UPPER BOUNDARY OF
!     * GROWTH DOMAIN (AT LARGE PARTICLE SIZES) IS AN OPEN OR CLOSED
!     * BOUNDARY. THE DEFAULT VALUE IS FOR A CLOSED BOUNDARY.
!
      DO IRG=1,IREG
      DO IRAT=1,IRD
      DO IB=1,IBTM(IRG)
        RGPN(IRG)%KOPEN(IB,IRAT)=.FALSE.
      ENDDO
      ENDDO
      ENDDO
!
!     * SPECIFY BOUNDARY AT LARGE PARTICLE SIZES FOR GROWTH DOMAINS
!     * 1 AND 3 TO BE OPEN. FOR DOMAIN 1, ONLY THE REGION CORRESPONDING
!     * TO SUFFICIENTLY LARGE SUPERSATURATION (I.E. GREATER THAN THE
!     * CRITICAL SUPERSATURATION) IS CONSIDERED.
!
      DO IRAT=1,IRD
        IBM=SPP(IRAT)%IBS
        IF ( IBM /= IDEF ) THEN
!
!         * FOR SUPERSATURATION GREATER THAN THE CRITICAL VALUE,
!         * DOMAIN 1 HAS AN OPEN BOUNDARY.
!
          DO IB=1,IBM-1
            RGPN(1)%KOPEN(IB,IRAT)=.TRUE.
          ENDDO
!
!         * DOMAIN 3 IS ALWAYS OPEN AT ITS UPPER BOUNDARY FOR THE
!         * SCALED PARTICLE SIZE.
!
          DO IB=1,IBTM(3)
            RGPN(3)%KOPEN(IB,IRAT)=.TRUE.
          ENDDO
        ENDIF
!
!       * DOMAIN 1 COULD ALSO HAVE AN OPEN BOUNDARY IF THE BOUNDARY
!       * FOR THE LARGEST PARTICLE SIZES IS FOR A SIZE THAT IS SMALLER
!       * THAN THE CRITICAL SIZE AND IF THE SUPERSATURATION IS GREATER
!       * THAN THE EQUILIBRIUM SUPERSATURATION. IN THAT CASE, THE VALUES
!       * FOR XP WILL ALL BE MAXIMAL.
!
        XMAX=-YLARGE
        DO IB=1,IBTM(1)
          XMAX=MAX(RGPNO(1)%XP(RGPNO(1)%IRT,IB,IRAT),XMAX)
        ENDDO
        DO IB=1,IBTM(1)
          IF (      RGPNO(1)%XP(RGPNO(1)%IRT,IB,IRAT) == XMAX &
             .AND. NINT(RGPNO(1)%TP(RGPNO(1)%IRT,IB  ,IRAT)-YNDEF) /= 0 &
             .AND. NINT(RGPNO(1)%TP(RGPNO(1)%IRT,IB+1,IRAT)-YNDEF) /= 0 &
                                                                 ) THEN
            RGPN(1)%KOPEN(IB,IRAT)=.TRUE.
          ENDIF
        ENDDO
      ENDDO
      IDBT=0
      IDRT=0
      IDPDT=0
      DO IRG=1,IREG
        IDBT=MAX(IDBT,IBTM(IRG))
!
!       * INITIALIZE OUTPUT ARRAYS FOR SCALED PARTICLE SIZE AND GROWTH
!       * TIMES.
!
        DO IRAT=1,IRD
        DO IB=1,IBTM(IRG)
          IN=ITMP(IRG)%IPM(IB,IRAT)
          IF ( IN /= IDEF ) THEN
            INS=ITMP(IRG)%IPNL(IB,IRAT)
            RGPN(IRG)%XP(IB,IRAT)%PNT(1:INS)=YNDEF
            RGPN(IRG)%TP(IB,IRAT)%PNT(1:INS)=YNDEF
            RGPN(IRG)%XP(IB,IRAT)%DER(1:INS)=YNDEF
            RGPN(IRG)%TP(IB,IRAT)%DER(1:INS)=YNDEF
          ENDIF
        ENDDO
        ENDDO
!
!       * SAVE NUMBER OF VALID POINTS TO CORRESPONDING OUTPUT ARRAYS.
!
        DO IRAT=1,IRD
        DO IB=1,IBTM(IRG)
          IN=ITMP(IRG)%IPM(IB,IRAT)
          IF ( IN /= IDEF ) THEN
            INS=ITMP(IRG)%IPNL(IB,IRAT)
            RGPN(IRG)%IPNTS(IB,IRAT)=INS
          ELSE
            RGPN(IRG)%IPNTS(IB,IRAT)=0
          ENDIF
        ENDDO
        ENDDO
        RGPN(IRG)%IBT=IBTM(IRG)
!
!       * EXTRACT POINTS XP AND TP.
!
        DO IRAT=1,IRD
        DO IB=1,IBTM(IRG)
          IN=ITMP(IRG)%IPLNKI(IB,IRAT)
          IF ( IN /= IDEF ) THEN
            IBS=IB+IN
            INS=ITMP(IRG)%IPNL(IB,IRAT)
            DO IR=1,INS
              IR1=ITMP(IRG)%ISLNKA(IR,IB,IRAT)
              RGPN(IRG)%XP(IB,IRAT)%PNT(IR)=RGPNO(IRG)%XP(IR1,IBS,IRAT)
              RGPN(IRG)%TP(IB,IRAT)%PNT(IR)=RGPNO(IRG)%TP(IR1,IBS,IRAT)
            ENDDO
          ENDIF
        ENDDO
        ENDDO
!
!       * DETERMINE DERIVATIVES (D XP/D BS AND D TP/D BS ).
!
        DO IRAT=1,IRD
        DO IB=1,IBTM(IRG)
          IN=ITMP(IRG)%IPLNKI(IB,IRAT)
          IF ( IN /= IDEF ) THEN
            IBS=IB+IN
            IBE=IB+1-IN
            INS=ITMP(IRG)%IPNL(IB,IRAT)
            DO IR=1,INS
              IR1=ITMP(IRG)%ISLNKA(IR,IB,IRAT)
              IR2=ITMP(IRG)%ISLNKB(IR,IB,IRAT)
              RGPN(IRG)%XP(IB,IRAT)%DER(IR)= &
              (RGPNO(IRG)%XP(IR2,IBE,IRAT)-RGPNO(IRG)%XP(IR1,IBS,IRAT)) &
              /(RGPNO(IRG)%BS(IBE,IRAT)-RGPNO(IRG)%BS(IBS,IRAT))
              RGPN(IRG)%TP(IB,IRAT)%DER(IR)= &
              (RGPNO(IRG)%TP(IR2,IBE,IRAT)-RGPNO(IRG)%TP(IR1,IBS,IRAT)) &
              /(RGPNO(IRG)%BS(IBE,IRAT)-RGPNO(IRG)%BS(IBS,IRAT))
              IDPDT=IDPDT+1
            ENDDO
            IDRT=MAX(IDRT,INS)
          ENDIF
        ENDDO
        ENDDO
      ENDDO
!
!     * OVERWRITE RESULTS FOR REGION 1 TO ACCOUNT FOR CRITICAL SIZE.
!     * THIS IS NECESSARY BECAUSE THE INTERPOLATION PERFORMED PREVIOUSLY
!     * DOES NOT PROVIDE THE NECESSARY STEP-WISE CHANGE IN BS-DIRECTION.
!     * HOWEVER, THIS CAN BE ACHIEVED BY MOVING ALL POINTS IN XP-DIRECTION
!     * TO THE CIRITICAL SIZE AT THE BS-COORDINATE THAT CORRESPONDS TO
!     * THE CRITICAL SUPERSATURATION. THE INTERPOLATION IS THEN DONE
!     * STARTING AT THESE POINTS TO THE NEXT ROW OF POINTS WHICH HAVE
!     * A SUPERSATURATION BELOW THE CRITICAL VALUE.
!
      DO IRAT=1,IRD
        IBM=SPP(IRAT)%IBS
        IF ( IBM /= IDEF ) THEN
          IN=ITMP(1)%IPLNKI(IBM,IRAT)
          IF ( IN /= IDEF ) THEN
            IBS=IBM+IN
            IBE=IB+1-IN
            INS=ITMP(1)%IPNL(IBM,IRAT)
            DO IR=1,INS
              IF ( RGPN(1)%XP(IBM,IRAT)%PNT(IR) > SPP(IRAT)%XP ) THEN
                IR2=ITMP(1)%ISLNKB(IR,IBM,IRAT)
                RGPN(1)%XP(IBM,IRAT)%PNT(IR)=SPP(IRAT)%XP
                RGPN(1)%TP(IBM,IRAT)%PNT(IR)=SPP(IRAT)%TP
                RGPN(1)%XP(IBM,IRAT)%DER(IR)= &
                          (RGPNO(1)%XP(IR2,IBE,IRAT)-SPP(IRAT)%XP) &
                         /(RGPNO(1)%BS(IBE,IRAT)-RGPNO(1)%BS(IBS,IRAT))
                RGPN(1)%TP(IBM,IRAT)%DER(IR)= &
                          (RGPNO(1)%TP(IR2,IBE,IRAT)-SPP(IRAT)%TP) &
                         /(RGPNO(1)%BS(IBE,IRAT)-RGPNO(1)%BS(IBS,IRAT))
              ENDIF
            ENDDO
          ENDIF
        ENDIF
      ENDDO
      DO IRG=1,IREG
!
!       * REORDER TERMS TO PRODUCE SIMPLE LINEAR EXPRESSIONS FOR
!       * EXTRAPOLATION.
!
        DO IRAT=1,IRD
        DO IB=1,IBTM(IRG)
          IN=ITMP(IRG)%IPLNKI(IB,IRAT)
          IF ( IN /= IDEF ) THEN
            IBS=IB+IN
            INS=ITMP(IRG)%IPNL(IB,IRAT)
            DO IR=1,INS
              RGPN(IRG)%XP(IB,IRAT)%PNT(IR)= &
                                          RGPN(IRG)%XP(IB,IRAT)%PNT(IR) &
                 -RGPN(IRG)%XP(IB,IRAT)%DER(IR)*RGPNO(IRG)%BS(IBS,IRAT)
              RGPN(IRG)%TP(IB,IRAT)%PNT(IR)= &
                                          RGPN(IRG)%TP(IB,IRAT)%PNT(IR) &
                 -RGPN(IRG)%TP(IB,IRAT)%DER(IR)*RGPNO(IRG)%BS(IBS,IRAT)
            ENDDO
          ENDIF
        ENDDO
        ENDDO
      ENDDO
!
!     * COPY RESULTS FOR REFERENCE POINT (PNT) AND DERIVATIVE (DER)
!     * INTO HOLDING ARRAYS. THE USE OF HOLDING ARRAYS WILL SPEED
!     * UP THE LOOK-UP OF THE RESULTS FROM MEMORY IN SUBSEQUENT
!     * CALCULATIONS.
!
      IF ( IDPDT < 1 .OR. IDBT < 1 .OR. IDRT < 1 ) &
                                                  CALL XIT('CNINTP',-1)
      ALLOCATE(XPPNT(IDPDT))
      ALLOCATE(XPDER(IDPDT))
      ALLOCATE(TPPNT(IDPDT))
      ALLOCATE(TPDER(IDPDT))
      ALLOCATE(IDPD(IREG,IRD,IDBT,IDRT))
      IDPD=IDEF
      ID=0
      DO IRG=1,IREG
        DO IRAT=1,IRD
        DO IB=1,IBTM(IRG)
          IN=ITMP(IRG)%IPLNKI(IB,IRAT)
          IF ( IN /= IDEF ) THEN
            INS=ITMP(IRG)%IPNL(IB,IRAT)
            DO IR=1,INS
              ID=ID+1
              XPPNT(ID)=RGPN(IRG)%XP(IB,IRAT)%PNT(IR)
              XPDER(ID)=RGPN(IRG)%XP(IB,IRAT)%DER(IR)
              TPPNT(ID)=RGPN(IRG)%TP(IB,IRAT)%PNT(IR)
              TPDER(ID)=RGPN(IRG)%TP(IB,IRAT)%DER(IR)
              IDPD(IRG,IRAT,IB,IR)=ID
            ENDDO
          ENDIF
        ENDDO
        ENDDO
      ENDDO
!
!     * DEALLOCATE TEMPORARY ARRAYS.
!
      DEALLOCATE(ITMP)
!
      END SUBROUTINE CNINTP
