      SUBROUTINE CNBNDS (IBTM,IRD,YNDEF)
!-----------------------------------------------------------------------
!     PURPOSE:
!     --------
!     EXTRACTION OF INTERNAL BOUNDARIES FOR DIFFERENT GROWTH REGIMES
!     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) :: IBTM
!
!     * ALLOCATE AND INITIALIZE TEMPORARY ARRAYS.
!
      ALLOCATE (RGBT(IREG))
      DO IRG=1,IREG
        ALLOCATE (RGBT(IRG)%PNTL(IRD))
        ALLOCATE (RGBT(IRG)%PNTU(IRD))
        ALLOCATE (RGBT(IRG)%DERL(IRD))
        ALLOCATE (RGBT(IRG)%DERU(IRD))
      ENDDO
      DO IRG=1,IREG
        RGBT(IRG)%PNTL(:)=YNDEF
        RGBT(IRG)%PNTU(:)=YNDEF
        RGBT(IRG)%DERL(:)=YNDEF
        RGBT(IRG)%DERU(:)=YNDEF
      ENDDO
!
!     * ALLOCATE AND INITIALIZE OUTPUT ARRAYS.
!
      ALLOCATE (BSMINP(IRD))
      ALLOCATE (BSMAXP(IRD))
      ALLOCATE (BSMINN(IRD))
      ALLOCATE (BSMAXN(IRD))
      ALLOCATE (XPMIN(IRD))
      ALLOCATE (XPMAX(IRD))
      ALLOCATE (RPMIN(IRD))
      ALLOCATE (RPMAX(IRD))
      BSMINP(:)=YNDEF
      BSMAXP(:)=YNDEF
      BSMINN(:)=YNDEF
      BSMAXN(:)=YNDEF
      XPMIN(:)=YNDEF
      XPMAX(:)=YNDEF
      RPMIN(:)=YNDEF
      RPMAX(:)=YNDEF
      ALLOCATE (RGB(IREG))
      DO IRG=1,IREG
        ALLOCATE (RGB(IRG)%FLG(IRD))
        ALLOCATE (RGB(IRG)%BSBMIN(IRD))
        ALLOCATE (RGB(IRG)%BSBMAX(IRD))
        ALLOCATE (RGB(IRG)%BSB(IBTM(IRG),IRD))
        ALLOCATE (RGB(IRG)%PNTL(IBTM(IRG),IRD))
        ALLOCATE (RGB(IRG)%PNTU(IBTM(IRG),IRD))
        ALLOCATE (RGB(IRG)%DERL(IBTM(IRG),IRD))
        ALLOCATE (RGB(IRG)%DERU(IBTM(IRG),IRD))
      ENDDO
      IDBSBT=0
      IBTMAX=0
      DO IRG=1,IREG
        RGB(IRG)%FLG(1:IRD)=.FALSE.
        RGB(IRG)%BSBMIN(1:IRD)=YNDEF
        RGB(IRG)%BSBMAX(1:IRD)=YNDEF
        RGB(IRG)%BSB(1:IBTM(IRG),1:IRD)=YNDEF
        RGB(IRG)%PNTL(1:IBTM(IRG),1:IRD)=YNDEF
        RGB(IRG)%PNTU(1:IBTM(IRG),1:IRD)=YNDEF
        RGB(IRG)%DERL(1:IBTM(IRG),1:IRD)=YNDEF
        RGB(IRG)%DERU(1:IBTM(IRG),1:IRD)=YNDEF
        RGB(IRG)%IBT=IBTM(IRG)
        IBTMAX=MAX(IBTMAX,IBTM(IRG))
        IDBSBT=IDBSBT+IBTM(IRG)
      ENDDO
      IDBSBT=IDBSBT*IRD
!
!     * DETERMINE BS RANGE.
!
      DO IRAT=1,IRD
        BSMIN=MIN(RGPNO(1)%BS(1,IRAT),RGPNO(2)%BS(1,IRAT), &
                                                   RGPNO(3)%BS(1,IRAT))
        BSMAX=MAX(RGPNO(1)%BS(IBTM(1)+1,IRAT), &
               RGPNO(2)%BS(IBTM(2)+1,IRAT),RGPNO(3)%BS(IBTM(3)+1,IRAT))
        IF ( BSMIN > BSMAX ) CALL XIT ('CNBNDS',-1)
        BSMINP(IRAT)=BSMIN
        BSMAXP(IRAT)=BSMAX
      ENDDO
      DO IRAT=1,IRD
        BSMIN=MIN(RGPNO(4)%BS(1,IRAT),RGPNO(5)%BS(1,IRAT))
        BSMAX=MAX(RGPNO(4)%BS(IBTM(4)+1,IRAT), &
                                           RGPNO(5)%BS(IBTM(5)+1,IRAT))
        IF ( BSMIN > BSMAX ) CALL XIT ('CNBNDS',-2)
        BSMINN(IRAT)=BSMIN
        BSMAXN(IRAT)=BSMAX
      ENDDO
!
!     * DETERMINE PARTICLE SIZE RANGE.
!
      DO IRAT=1,IRD
        IF ( RGPNO(1)%XP(1,1,IRAT) &
                              > RGPNO(3)%XP(RGPNO(3)%IRT,1,IRAT) ) THEN
          CALL XIT ('CNBNDS',-3)
        ENDIF
        XPMIN(IRAT)=RGPNO(1)%XP(1,1,IRAT)
        XPMAX(IRAT)=RGPNO(3)%XP(RGPNO(3)%IRT,1,IRAT)
        RPMIN(IRAT)=SQRT(2.*XPMIN(IRAT))
        RPMAX(IRAT)=SQRT(2.*XPMAX(IRAT))
      ENDDO
      IF ( IDBSBT < 1 ) CALL XIT('CNBNDS',-4)
      ALLOCATE(RBSB(IDBSBT))
      ALLOCATE(IDBSB(IREG,IRD,IBTMAX))
      ID=0
      DO IRG=1,IREG
!
!       * COPY ORIGINAL DATA INTO OUTPUT ARRAYS.
!
        DO IRAT=1,IRD
        DO IB=1,IBTM(IRG)
          RGB(IRG)%BSB(IB,IRAT)=RGPNO(IRG)%BS(IB,IRAT)
          ID=ID+1
          RBSB(ID)=RGPNO(IRG)%BS(IB,IRAT)
          IDBSB(IRG,IRAT,IB)=ID
        ENDDO
        ENDDO
!
!       * EXTRACT POINTS XP AT THE LOWER BOUNDARY OF THE DOMAIN.
!
        DO IRAT=1,IRD
          DO IB=1,IBTM(IRG)
          DO IR=1,RGPNO(IRG)%IRT
            IF ( NINT(RGPNO(IRG)%TP(IR,IB,IRAT)-YNDEF) /= 0 &
                   .AND. NINT(RGB(IRG)%PNTL(IB,IRAT)-YNDEF) == 0 ) THEN
              RGB(IRG)%PNTL(IB,IRAT)=RGPNO(IRG)%XP(IR,IB,IRAT)
            ENDIF
          ENDDO
          ENDDO
          IB=IBTM(IRG)+1
          DO IR=1,RGPNO(IRG)%IRT
            IF ( NINT(RGPNO(IRG)%TP(IR,IB,IRAT)-YNDEF) /= 0 &
                     .AND. NINT(RGBT(IRG)%PNTL(IRAT)-YNDEF) == 0 ) THEN
              RGBT(IRG)%PNTL(IRAT)=RGPNO(IRG)%XP(IR,IB,IRAT)
            ENDIF
          ENDDO
        ENDDO
!
!       * EXTRACT POINTS XP AT THE UPPER BOUNDARY OF THE DOMAIN.
!
        DO IRAT=1,IRD
          DO IB=1,IBTM(IRG)
          DO IR=RGPNO(IRG)%IRT,1,-1
            IF ( NINT(RGPNO(IRG)%TP(IR,IB,IRAT)-YNDEF) /= 0 &
                   .AND. NINT(RGB(IRG)%PNTU(IB,IRAT)-YNDEF) == 0 ) THEN
              RGB(IRG)%PNTU(IB,IRAT)=RGPNO(IRG)%XP(IR,IB,IRAT)
            ENDIF
          ENDDO
          ENDDO
          IB=IBTM(IRG)+1
          DO IR=RGPNO(IRG)%IRT,1,-1
            IF ( NINT(RGPNO(IRG)%TP(IR,IB,IRAT)-YNDEF) /= 0 &
                     .AND. NINT(RGBT(IRG)%PNTU(IRAT)-YNDEF) == 0 ) THEN
              RGBT(IRG)%PNTU(IRAT)=RGPNO(IRG)%XP(IR,IB,IRAT)
            ENDIF
          ENDDO
        ENDDO
!
!       * DETERMINE DERIVATIVES (D XP/D BS) FOR LOWER BOUNDARY.
!
        DO IRAT=1,IRD
          DO IB=1,IBTM(IRG)-1
            IF ( NINT(RGB(IRG)%PNTL(IB,IRAT)-YNDEF) /= 0 &
                 .AND. NINT(RGB(IRG)%PNTL(IB+1,IRAT)-YNDEF) /= 0 ) THEN
              RGB(IRG)%DERL(IB,IRAT)= &
                      (RGB(IRG)%PNTL(IB+1,IRAT)-RGB(IRG)%PNTL(IB,IRAT)) &
                     /(RGPNO(IRG)%BS(IB+1,IRAT)-RGPNO(IRG)%BS(IB,IRAT))
            ENDIF
          ENDDO
          IB=IBTM(IRG)
          IF ( NINT(RGB(IRG)%PNTL(IB,IRAT)-YNDEF) /= 0 &
                     .AND. NINT(RGBT(IRG)%PNTL(IRAT)-YNDEF) /= 0 ) THEN
            RGB(IRG)%DERL(IB,IRAT)= &
                      (RGBT(IRG)%PNTL(IRAT)-RGB(IRG)%PNTL(IB,IRAT)) &
                     /(RGPNO(IRG)%BS(IB+1,IRAT)-RGPNO(IRG)%BS(IB,IRAT))
          ENDIF
        ENDDO
!
!       * DETERMINE DERIVATIVES (D XP/D BS) FOR UPPER BOUNDARY.
!
        DO IRAT=1,IRD
          DO IB=1,IBTM(IRG)-1
            IF ( NINT(RGB(IRG)%PNTU(IB,IRAT)-YNDEF) /= 0 &
                 .AND. NINT(RGB(IRG)%PNTU(IB+1,IRAT)-YNDEF) /= 0 ) THEN
              RGB(IRG)%DERU(IB,IRAT)= &
                      (RGB(IRG)%PNTU(IB+1,IRAT)-RGB(IRG)%PNTU(IB,IRAT)) &
                     /(RGPNO(IRG)%BS(IB+1,IRAT)-RGPNO(IRG)%BS(IB,IRAT))
            ENDIF
          ENDDO
          IB=IBTM(IRG)
          IF ( NINT(RGB(IRG)%PNTU(IB,IRAT)-YNDEF) /= 0 &
                     .AND. NINT(RGBT(IRG)%PNTU(IRAT)-YNDEF) /= 0 ) THEN
            RGB(IRG)%DERU(IB,IRAT)= &
                      (RGBT(IRG)%PNTU(IRAT)-RGB(IRG)%PNTU(IB,IRAT)) &
                     /(RGPNO(IRG)%BS(IB+1,IRAT)-RGPNO(IRG)%BS(IB,IRAT))
          ENDIF
        ENDDO
      ENDDO
!
!     * OVERWRITE RESULTS FOR REGION 1 TO ACCOUNT FOR CRITICAL SIZE.
!
      DO IRAT=1,IRD
        IBM=SPP(IRAT)%IBS
        IF ( IBM /= IDEF ) THEN
          IF ( IBM <= IBTM(1) ) THEN
            RGB(1)%PNTU(IBM,IRAT)=SPP(IRAT)%XP
          ELSE
            RGBT(1)%PNTU(IRAT)=SPP(IRAT)%XP
          ENDIF
        ENDIF
      ENDDO
      DO IRAT=1,IRD
        IBM=SPP(IRAT)%IBS
        IF ( IBM /= IDEF ) THEN
          IF ( IBM <= (IBTM(1)-1) ) THEN
            IF ( NINT(RGB(1)%PNTU(IBM+1,IRAT)-YNDEF) /= 0 ) THEN
              RGB(1)%DERU(IBM,IRAT)= &
                      (RGB(1)%PNTU(IBM+1,IRAT)-SPP(IRAT)%XP) &
                     /(RGPNO(1)%BS(IBM+1,IRAT)-RGPNO(1)%BS(IBM,IRAT))
            ENDIF
          ELSE
            IF ( NINT(RGBT(1)%PNTU(IRAT)-YNDEF) /= 0 ) THEN
              RGB(1)%DERU(IBM,IRAT)= &
                      (RGBT(1)%PNTU(IRAT)-SPP(IRAT)%XP) &
                     /(RGPNO(1)%BS(IBM+1,IRAT)-RGPNO(1)%BS(IBM,IRAT))
            ENDIF
          ENDIF
        ENDIF
      ENDDO
!
!     * DETERMINE BS RANGE FOR EACH GROWTH REGIME.
!
      DO IRG=1,IREG
      DO IRAT=1,IRD
        IF ( RGPNO(IRG)%BS(1,IRAT) > RGPNO(IRG)%BS(IBTM(IRG)+1,IRAT) &
                                                                 ) THEN
          CALL XIT ('CNBNDS',-5)
        ENDIF
        DO IB=1,IBTM(IRG)
          IF (       NINT(RGB(IRG)%PNTL(IB,IRAT)-YNDEF) /= 0 &
               .AND. NINT(RGB(IRG)%PNTU(IB,IRAT)-YNDEF) /= 0 &
                    .AND. NINT(RGB(IRG)%BSBMIN(IRAT)-YNDEF) == 0 ) THEN
            RGB(IRG)%BSBMIN(IRAT)=RGPNO(IRG)%BS(IB,IRAT)
          ENDIF
        ENDDO
        DO IB=IBTM(IRG),1,-1
          IF (       NINT(RGB(IRG)%PNTL(IB,IRAT)-YNDEF) /= 0 &
               .AND. NINT(RGB(IRG)%PNTU(IB,IRAT)-YNDEF) /= 0 &
                    .AND. NINT(RGB(IRG)%BSBMAX(IRAT)-YNDEF) == 0 ) THEN
            RGB(IRG)%BSBMAX(IRAT)=RGPNO(IRG)%BS(IB+1,IRAT)
          ENDIF
        ENDDO
        IF (         NINT(RGB(IRG)%BSBMIN(IRAT)-YNDEF) /= 0 &
               .AND. NINT(RGB(IRG)%BSBMAX(IRAT)-YNDEF) /= 0      ) THEN
            RGB(IRG)%FLG(IRAT)=.TRUE.
        ENDIF
      ENDDO
      ENDDO
      IDPLT=0
      IDPUT=0
      DO IRG=1,IREG
!
!       * REORDER TERMS TO PRODUCE A SIMPLE LINEAR EXPRESSION FOR
!       * EXTRAPOLATION FOR LOWER BOUNDARY.
!
        DO IRAT=1,IRD
        DO IB=1,IBTM(IRG)
          IF ( NINT(RGB(IRG)%PNTL(IB,IRAT)-YNDEF) /= 0 ) THEN
            RGB(IRG)%PNTL(IB,IRAT)=RGB(IRG)%PNTL(IB,IRAT) &
                         -RGB(IRG)%DERL(IB,IRAT)*RGPNO(IRG)%BS(IB,IRAT)
            IDPLT=IDPLT+1
          ENDIF
        ENDDO
        ENDDO
!
!       * REORDER TERMS TO PRODUCE A SIMPLE LINEAR EXPRESSION FOR
!       * EXTRAPOLATION FOR UPPER BOUNDARY.
!
        DO IRAT=1,IRD
        DO IB=1,IBTM(IRG)
          IF ( NINT(RGB(IRG)%PNTU(IB,IRAT)-YNDEF) /= 0 ) THEN
            RGB(IRG)%PNTU(IB,IRAT)=RGB(IRG)%PNTU(IB,IRAT) &
                         -RGB(IRG)%DERU(IB,IRAT)*RGPNO(IRG)%BS(IB,IRAT)
            IDPUT=IDPUT+1
          ENDIF
        ENDDO
        ENDDO
      ENDDO
!
!     * COPY RESULTS FOR REFERENCE POINT (PNTU/L) AND DERIVATIVE (DERU/L)
!     * INTO HOLDING ARRAYS. THE USE OF HOLDING ARRAYS WILL SPEED
!     * UP THE LOOK-UP OF THE RESULTS FROM MEMORY IN SUBSEQUENT
!     * CALCULATIONS.
!
      IF ( IDPLT < 1 .OR. IDPUT < 1 .OR. IBTMAX < 1 ) &
                                                  CALL XIT('CNBNDS',-6)
      ALLOCATE(XPPNTL(IDPLT))
      ALLOCATE(XPPNTU(IDPUT))
      ALLOCATE(XPDERL(IDPLT))
      ALLOCATE(XPDERU(IDPUT))
      ALLOCATE(IDPL(IREG,IRD,IBTMAX))
      ALLOCATE(IDPU(IREG,IRD,IBTMAX))
      IDPL=IDEF
      IDPU=IDEF
      IDL=0
      IDU=0
      DO IRG=1,IREG
        DO IRAT=1,IRD
        DO IB=1,IBTM(IRG)
          IF ( NINT(RGB(IRG)%PNTL(IB,IRAT)-YNDEF) /= 0 ) THEN
            IDL=IDL+1
            XPPNTL(IDL)=RGB(IRG)%PNTL(IB,IRAT)
            XPDERL(IDL)=RGB(IRG)%DERL(IB,IRAT)
            IDPL(IRG,IRAT,IB)=IDL
          ENDIF
          IF ( NINT(RGB(IRG)%PNTU(IB,IRAT)-YNDEF) /= 0 ) THEN
            IDU=IDU+1
            XPPNTU(IDU)=RGB(IRG)%PNTU(IB,IRAT)
            XPDERU(IDU)=RGB(IRG)%DERU(IB,IRAT)
            IDPU(IRG,IRAT,IB)=IDU
          ENDIF
        ENDDO
        ENDDO
      ENDDO
!
!     * DEALLOCATE TEMPORARY ARRAY.
!
      DEALLOCATE(RGBT)
!
      END SUBROUTINE CNBNDS
