subroutine aptptlc (pu, pv, au, av, bu, bv, np, tol, noptfd,
     &                    dpmin, fdmin, nlim, itrun, nerr)

ccbeg.
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
c
c                             SUBROUTINE APTPTLC
c
c     call aptptlc (pu, pv, au, av, bu, bv, np, tol, noptfd,
c    &              dpmin, fdmin, nlim, itrun, nerr)
c
c     Version:  aptptlc  Updated    1990 November 29 10:50.
c               aptptlc  Originated 1989 December 29 16:40.
c
c     Author:   Arthur L. Edwards, LLNL, L-298, Telephone (925) 422-4123.
c
c
c     Purpose:  To find, for each of np sets of input data, the minimum distance
c               dpmin from the point p = (pu, pv) to the straight line through
c               the points a = (au, av) and b = (bu, bv).  All points are in
c               the uv plane.  Directions u, v and w are orthogonal.
c
c               Option noptfd allows the fractional distance fdmin of the
c               proximal point along line "ab" to be calculated, and allows
c               the range of fdmin to be limited.  Flag nlim indicates
c               when such limitation has beem imposed.  If nlim = 2, dpmin is
c               the distance from point "p" to the nearest end of line
c               segment "ab".
c
c               The value of dpmin will be truncated to zero if less than the
c               estimated error in its calculation, based on tol, and if so,
c               itrun = 1 will be returned.
c
c               If the points "a" and "b" coincide, based on tol, dpmin will be
c               the distance from point "a" to point "p", and if dpmin is not
c               zero, itrun will be -1.
c
c               Flag nerr indicates any input error.
c
c     History:  1990 February 12 15:20.  Added input argument noptfd,
c               optional output arguments fdmin, nlim.
c
c     Input:    pu, pv, au, av, bu, bv, np, tol, noptfd.
c
c     Output:   dpmin, fdmin, nlim, itrun, nerr.
c
c     Calls: aptfdav, aptvaxc, aptvdic, aptvdoc 
c               
c
c     Glossary:
c
c     au, av    Input    The u and v coordinates of point "a" on line "ab".
c                          Size np.  All points are in the uv plane.
c
c     bu, bv    Input    The u and v coordinates of point "b" on line "ab".
c                          Size np.
c
c     dpmin     Output   Distance from point "p" to the line "ab".  Size np.
c                          Truncated to zero if less than the estimated error
c                          in its calculation, based on tol, and if so,
c                          itrun = 1 will be returned.
c                          If points "a" and "b" are coincident, dpmin is the
c                          distance from point "p" to point "a", and itrun = -1
c                          is returned, unless dpmin = 0.0.
c                          If noptfd is 2, and fdmin is initially not in the
c                          range from 0.0 to 1.0, dpmin is the distance from
c                          point "p" to the nearest of points "a" and "b", and
c                          nlim = 2 is returned.
c                          The value of dpmin is positive, if point "p" is
c                          to the left of the vector "ab" in the uv plane.
c
c     fdmin     Output   Fractional distance between point "a" and point "b"
c                          of the point nearest point "p".  See noptfd.
c                          Size np, if noptfd is not -1.
c
c     itrun     Output   0 if dpmin is not truncated to zero.  Size np.
c                           1 if dpmin is truncated to zero, when less than its
c                             estimated error, based on tol.
c                          -1 if dpmin is not zero, and points "a" and "b"
c                             coincide, based on tol.
c
c     nerr      Output   Indicates an input error, if not 0.
c                          1 if np is not positive.
c                          2 if noptfd is not -1, 0, 1, or 2.
c
c     nlim      Output   0 if no limit imposed on fdmin, 1 if the limit of
c                          noptfd = 1 is imposed, 2 if the limit of noptfd = 2
c                          is imposed.  Size np, if noptfd is not -1.
c                          If 2, dpmin is the distance from point "p" to the
c                          nearest end of line segment "ab".
c
c     noptfd    Input    Option to limit range of fdmin:  0 for no limit;
c                          -1 to not calculate fdmin or nlim.
c                           0 to find fdmin, but impose no limits.
c                           1 to increase fdmin to tol, if in the range from
c                             -tol to tol, and decrease fdmin to 1.0 - tol,
c                             if in the range from 1.0 - tol to 1.0 + tol.
c                           2 to impose the limits for noptfd = 1, and then
c                             limit fdmin to the range from 0.0 to 1.0, and
c                             adjust the magnitude, but not the sign of dpmin
c                             if the later limit is imposed.
c
c     np        Input    Size of arrays pu, pv, au, av, bu, bv, itrun.
c                          If noptfd is not -1, the size of arrays fdmin, nlim.
c
c     pu, pv    Input    The u and v coordinates of point "p".  Size np.
c
c     tol       Input    Numerical tolerance limit.
c                          On Cray computers, recommend 1.e-5 to 1.e-11.
c
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
ccend.

c.... Dimensioned arguments.

c---- Coordinate u of point "a".
      dimension au      (1)
c---- Coordinate v of point "a".
      dimension av      (1)
c---- Coordinate u of point "b".
      dimension bu      (1)
c---- Coordinate v of point "b".
      dimension bv      (1)
c---- Distance from line "ab" to point "p".
      dimension dpmin   (1)
c---- Fractional distance along "ab".
      dimension fdmin   (1)
c---- Indicates dpmin zero, if 1.
      dimension itrun   (1)
c---- Indicates fdmin limited, if not 0.
      dimension nlim    (1)
c---- Coordinate u of point "p".
      dimension pu      (1)
c---- Coordinate v of point "p".
      dimension pv      (1)

c.... Local variables.

c---- Component u of vector "ab".
      common /laptptlc/ abu     (64)
c---- Component v of vector "ab".
      common /laptptlc/ abv     (64)
c---- Component u of vector "ap".
      common /laptptlc/ apu     (64)
c---- Component v of vector "ap".
      common /laptptlc/ apv     (64)
c---- Component u of vector "bp".
      common /laptptlc/ bpu     (64)
c---- Component v of vector "bp".
      common /laptptlc/ bpv     (64)
c---- Magnitude of vector "ab".
      common /laptptlc/ dab     (64)
c---- Magnitude of vector "ap".
      common /laptptlc/ dap     (64)
c---- Magnitude of vector "bp".
      common /laptptlc/ dbp     (64)
c---- Signed value of dap.
      common /laptptlc/ dpmina
c---- Signed value of dbp.
      common /laptptlc/ dpminb
c---- Component w of vector "ab" x "ap".
      common /laptptlc/ dw      (64)

c---- A very small number.
      common /laptptlc/ fuz

c---- Index in arrays.
      common /laptptlc/ n
c---- First index of subset of data.
      common /laptptlc/ n1
c---- Last index of subset of data.
      common /laptptlc/ n2
c---- Index in external array.
      common /laptptlc/ nn
c---- Size of current subset of data.
      common /laptptlc/ ns
cbugc***DEBUG begins.
cbug 9901 format (/ 'aptptlc finding distance from points',
cbug     &  ' (noptfd=',i2,' tol=',1pe13.5,'):')
cbug 9902 format (
cbug     &  i3,' pu,pv=',1p2e22.14 /
cbug     &  '    to the line segment with endpoints:' /
cbug     &  '    au,av=',1p2e22.14 /
cbug     &  '    bu,bv=',1p2e22.14)
cbug      write ( 3, 9901) noptfd, tol
cbug      write ( 3, 9902) (n, pu(n), pv(n), au(n), av(n),
cbug     &  bu(n), bv(n), n = 1, np)
cbugc***DEBUG ends.

c.... Initialize.

c---- A very small number.
      fuz = 1.e-99

      nerr = 0

c.... Test for input errors.

      if (np .le. 0) then
        nerr = 1
        go to 210
      endif

      if ((noptfd .lt. -1) .or. (noptfd .gt. 2)) then
        nerr = 2
        go to 210
      endif

c.... Set up the indices of the first subset of data.

      n1 = 1
      n2 = min (np, 64)

c.... Loop over subsets of data.

  110 ns = n2 - n1 + 1

c.... Find the vector "ab" along the line segment, and its length, dab.

      call aptvdic (au(n1), av(n1), bu(n1), bv(n1), ns, tol,
     &              abu, abv, dab, nerr)

c.... Find the vector "ap" from point "a" to point "p", and its length, dap.

      call aptvdic (au(n1), av(n1), pu(n1), pv(n1), ns, tol,
     &              apu, apv, dap, nerr)

c.... Find the parallelogram area for vectors "ab", "ap".

      call aptvaxc (abu, abv, apu, apv, ns, tol, dw, nerr)

c.... Find the minimum distance dpmin from point "p" to line "ab".
c....   Recalculate dpmin if points "a" and "b" coincide.

c---- Loop over subset of data.
      do 120 n = 1, ns

        nn        = n + n1 - 1
        dpmin(nn) = dw(n) / (dab(n) + fuz)
        if (dab(n) .le. 0.0) then
          dpmin(nn) = dap(n)
          itrun(nn) = -1
        else
          itrun(nn) = 0
        endif

c---- End of loop over subset of data.
  120 continue

c.... Reduce dpmin to zero if it is small, relative to the line length,
c....   or less than the estimated error in its calculation.
c....   (May have already been done in aptvdic.)

c---- Loop over subset of data.
      do 130 n = 1, ns

        nn = n + n1 - 1

        if (abs (dpmin(nn)) .le. tol * dab(n)) then
          itrun(nn) = itrun(nn) + 1
          dpmin(nn) = 0.0
        endif

c---- End of loop over subset of data.
  130 continue

c.... Find fdmin if noptfd is not -1.

c---- Find fdmin.
      if (noptfd .ne. -1) then

c....   Find the scalar product of vectors "ab" and "ap".

        call aptvdoc (abu, abv, apu, apv, ns, tol, fdmin(n1), nerr)

c---- Loop over subset of data.
        do 140 n = 1, ns

          nn        = n + n1 - 1
          fdmin(nn) = fdmin(nn) / (dab(n)**2 + fuz)

c---- End of loop over subset of data.
  140   continue

c....   Test fdmin for limits if noptfd = 1 or 2.

c---- Impose limits on fdmin.
        if (noptfd .ne. 0) then

          call aptfdav (fdmin(n1), ns, noptfd, tol, nlim(n1), nerr)

c---- Tested for noptfd = 1 or 2.
        endif

c---- Adjust dpmin when nlim = 2.
        if (noptfd .eq. 2) then

c....     Find the vector "bp" from point "b" to point "p",
c....       and its length, dbp.

          call aptvdic (bu(n1), bv(n1), pu(n1), pv(n1), ns, tol,
     &                  bpu, bpv, dbp, nerr)

c....     Adjust dpmin if nlim = 2.

c---- Loop over subset of data.
          do 150 n = 1, ns

            nn = n + n1 - 1
            dpmina    = sign (dap(n), dpmin(nn))
            dpminb    = sign (dbp(n), dpmin(nn))

            if ((nlim(nn) .eq. 2) .and. (fdmin(nn) .eq. 0.0)) then
              dpmin(nn) = dpmina
            endif
            if ((nlim(nn) .eq. 2) .and. (fdmin(nn) .eq. 1.0)) then
              dpmin(nn) = dpminb
            endif
            if ((itrun(nn) .eq. 1) .and. (dpmin(nn) .ne. 0.0)) then
              itrun(nn) = 0
            endif

c---- End of loop over subset of data.
  150     continue

c---- Tested for noptfd = 2.
        endif

c---- Tested for noptfd .ne. -1.
      endif

c.... See if all data subsets are done.

c---- Do another subset of data.
      if (n2 .lt. np) then
        n1 = n2 + 1
        n2 = min (np, n1 + 63)
        go to 110
      endif
cbugc***DEBUG begins.
cbug 9903 format (/ 'aptptlc results:')
cbug 9904 format (i3,' itrun=',i2,' dpmin=',1pe22.14)
cbug 9905 format ('    nlim= ',i2,' fdmin=',1pe22.14)
cbug      write ( 3, 9903)
cbug      do 160 n = 1, np
cbug        write ( 3, 9904) n, itrun(n), dpmin(n)
cbug        if (noptfd .ne. -1) then
cbug          write ( 3, 9905) nlim(n), fdmin(n)
cbug        endif
cbug  160 continue
cbugc***DEBUG ends.

  210 return

c.... End of subroutine aptptlc.      (+1 line.)
      end

UCRL-WEB-209832