subroutine aptlnlc (au, av, bu, bv, cu, cv, du, dv, np, tol,
     &                    dpmin, fracab, fraccd, eu, ev, ipar, nerr)

ccbeg.
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
c
c                             SUBROUTINE APTLNLC
c
c     call aptlnlc (au, av, bu, bv, cu, cv, du, dv, np, tol,
c    &              dpmin, fracab, fraccd, eu, ev, ipar, nerr)
c
c     Version:  aptlnlc  Updated    1990 November 28 10:00.
c               aptlnlc  Originated 1990 January 11 11:10.
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 intersection
c               e = (eu, ev), if any, between the straight line between points
c               a = (au, av) and b = (bu, bv), and the straight line between
c               points c = (cu, cv), and d = (du, dv), all in the uv plane,
c               where u, v and w are orthogonal directions.  The fractional
c               distance fracab of point "e" along line "ab", and the fractional
c               distance fraccd of point "e" along line "cd" are also returned.
c               If the lines are parallel, ipar = 1 will be returned, and the
c               distance dpmin between the lines will be returned.  If dpmin is
c               smaller than the estimated error in its calculation, it will be
c               truncated to zero.  If a line segment is too short, ipar = 2, 3
c               or 4 will be returned.  Flag nerr will be 1 if np is not
c               positive.
c
c     Input:    au, av, bu, bv, cu, cv, du, dv, np, tol.
c
c     Output:   dpmin, fracab, fraccd, eu, ev, ipar, nerr.
c
c     Calls: aptvdic, aptaxc 
c               
c
c     Glossary:
c
c     au, av    Input    The u and v coordinates of the first point on line
c                          segment "ab" in the uv plane.  Size np.
c
c     bu, bv    Input    The u and v coordinates of the second point on line
c                          segment "ab" in the uv plane.  Size np.
c
c     cu, cv    Input    The u and v coordinates of the first point on line
c                          segment "cd" in the uv plane.  Size np.
c
c     dpmin     Output   Distance from line "ab" to line "cd", when they are
c                          parallel (ipar = 1).
c                          Truncated to zero if less than the estimated error
c                          in its calculation.  See tol.  Size np.
c
c     du, dv    Input    The u and v coordinates of the second point on line
c                          segment "cd" in the uv plane.  Size np.
c
c     eu, ev    Output   The u and v coordinates of the intersection of lines
c                          "ab" and "cd".  Size np.
c
c     fracab    Output   Fractional distance of "e" along line "ab".  Size np.
c                          Meaningless if ipar = 2 or 4.
c
c     fraccd    Output   Fractional distance of "e" along line "cd".  Size np.
c                          Meaningless if ipar = 3 or 4.
c
c     ipar      Output   0 if lines are not parallel.  1 if they are.  Size np.
c                          2 if line segment "ab" is too short.
c                          3 if line segment "cd" is too short.
c                          4 if "ab" and "cd" are both too short.
c
c     nerr      Output   Indicates an input error, if not 0.
c                          1 if np is not positive.
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---- Coordinate u of point "c".
      dimension cu      (1)
c---- Coordinate v of point "c".
      dimension cv      (1)
c---- Distance from line "ab" to line "cd".
      dimension dpmin   (1)
c---- Coordinate u of point "d".
      dimension du      (1)
c---- Coordinate v of point "d".
      dimension dv      (1)
c---- Coordinate u of point "e".
      dimension eu      (1)
c---- Coordinate v of point "e".
      dimension ev      (1)
c---- Fractional distance of "e" on "ab".
      dimension fracab  (1)
c---- Fractional distance of "e" on "cd".
      dimension fraccd  (1)
c---- 1 if lines parallel, 2 if bad.
      dimension ipar    (1)

c.... Local variables.

c---- Cross product of "ab" and "cd".
      common /laptlnlc/ abcd    (64)
c---- Component u of unit vector along "ab".
      common /laptlnlc/ abu     (64)
c---- Component v of unit vector along "ab".
      common /laptlnlc/ abv     (64)
c---- Cross product of "ac" and "ab".
      common /laptlnlc/ acab    (64)
c---- Cross product of "ac" and "cd".
      common /laptlnlc/ accd    (64)
c---- Component u of vector "ac".
      common /laptlnlc/ acu     (64)
c---- Component v of vector "ac".
      common /laptlnlc/ acv     (64)
c---- Component u of unit vector along "cd".
      common /laptlnlc/ cdu     (64)
c---- Component v of unit vector along "cd".
      common /laptlnlc/ cdv     (64)
c---- Distance from "a" to "b".
      common /laptlnlc/ distab  (64)
c---- Distance from "a" to "c".
      common /laptlnlc/ distac  (64)
c---- Distance from "c" to "d".
      common /laptlnlc/ distcd  (64)

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

c---- Distance between parallel lines.
      common /laptlnlc/ dpar
c---- Distance between "c" and "ab".
      common /laptlnlc/ dparab
c---- Distance between "a" and "cd".
      common /laptlnlc/ dparcd
c---- Coordinate u of intersection on "ab".
      common /laptlnlc/ eabu
c---- Coordinate v of intersection on "ab".
      common /laptlnlc/ eabv
c---- Coordinate u of intersection on "cd".
      common /laptlnlc/ ecdu
c---- Coordinate v of intersection on "cd".
      common /laptlnlc/ ecdv
c---- Index in external array.
      common /laptlnlc/ n
c---- First index of subset of data.
      common /laptlnlc/ n1
c---- Last index of subset of data.
      common /laptlnlc/ n2
c---- Index in external array.
      common /laptlnlc/ nn
c---- Size of current subset of data.
      common /laptlnlc/ ns
cbugc***DEBUG begins.
cbug 9901 format (/ 'aptlnlc finding intersection of the line through' /
cbug     &  '  (np=',i3,' tol=',1pe13.5,'):')
cbug 9902 format (i3,' au,av= ',1p2e22.14 /
cbug     &  '    bu,bv= ',1p2e22.14 /
cbug     &  '    with the line through:' /
cbug     &  '    cu,cv= ',1p2e22.14 /
cbug     &  '    du,dv= ',1p2e22.14)
cbug      write ( 3, 9901) np, tol
cbug      write ( 3, 9902) (n, au(n), av(n), bu(n), bv(n),
cbug     &  cu(n), cv(n), du(n), dv(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

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 2-D vector "ab" from point "a" to point "b".

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

c.... Find the 2-D vector "cd" from point "c" to point "d".

      call aptvdic (cu(n1), cv(n1), du(n1), dv(n1), ns, tol,
     &              cdu, cdv, distcd, nerr)

c.... Find the 2-D vector "ac" from point "a" to point "c".

      call aptvdic (au(n1), av(n1), cu(n1), cv(n1), ns, tol,
     &              acu, acv, distac, nerr)

c.... Find the vector product of vectors "ab" and "cd".

      call aptvaxc (abu, abv, cdu, cdv, ns, tol, abcd, nerr)

c.... Find the vector product of vectors "ac" and "ab".

      call aptvaxc (acu, acv, abu, abv, ns, tol, acab, nerr)

c.... Find the vector product of vectors "ac" and "cd".

      call aptvaxc (acu, acv, cdu, cdv, ns, tol, accd, nerr)

c.... Find the fractional distances of the intersection "e" along lines
c....   "ab" and "cd".  Set dpmin to zero.

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

        nn = n + n1 - 1

        dpmin(nn)  = 0.0
        fracab(nn) = accd(n) / (abcd(n) + fuz)
        fraccd(nn) = acab(n) / (abcd(n) + fuz)

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

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

        nn = n + n1 - 1

        eabu = au(nn) + fracab(nn) * abu(n)
        eabv = av(nn) + fracab(nn) * abv(n)

        ecdu = cu(nn) + fraccd(nn) * cdu(n)
        ecdv = cv(nn) + fraccd(nn) * cdv(n)

c.... See if on line "ab" or on line "cd".  Use shorter if on both.

        if (abs (fracab(nn)) * distab(n) .lt.
     &      abs (fraccd(nn)) * distcd(n)) then
          eu(nn) = eabu
          ev(nn) = eabv
        else
          eu(nn) = ecdu
          ev(nn) = ecdv
        endif

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

c.... If the lines are parallel, find the distance between them.

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

        nn = n + n1 - 1

        if (abcd(n) .ne. 0.0) then
          ipar(nn) = 0
        else
          ipar(nn) = 1
        endif

        if (distab(n) .eq. 0.0) then
          ipar(nn) = 2
        endif

        if (distcd(n) .eq. 0.0) then
          ipar(nn) = ipar(nn) + 2
        endif

        dparab    = abs (acab(n) / (distab(n) + fuz))
        dparcd    = abs (accd(n) / (distcd(n) + fuz))
        if (distab(n) .ne. 0.0) then
          dpar = dparab
        else
          dpar = dparcd
        endif

        if (distcd(n) .eq. 0.0) then
          dpar = distac(n)
        endif

        if (ipar(nn) .ne. 1) then
          dpmin(nn) = 0.0
        else
          dpmin(nn) = dpar
        endif

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

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 (/ 'aptlnlc results:' /
cbug     &  (i3,' dpmin= ',1pe22.14,' ipar=',i2 /
cbug     &  '    fracab=',1pe22.14,' fraccd=',1pe22.14 /
cbug     &  '    eu,ev= ',1p2e22.14))
cbug      write ( 3, 9903) (n, dpmin(n), ipar(n), fracab(n), fraccd(n),
cbug     &  eu(n), ev(n), n = 1, np)
cbugc***DEBUG ends.

  210 return

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

UCRL-WEB-209832