subroutine aptparl (px, py, pz, vx, vy, vz, ax, ay, az,
     &                    bx, by, bz, cx, cy, cz, tol,
     &                    nints, atype, ptx, pty, ptz,
     &                    vtx, vty, vtz, vtlen,
     &                    dprox, dline, tprox, pltx, plty, pltz, nerr)

ccbeg.
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
c
c                             SUBROUTINE APTPARL
c
c     subroutine aptparl (px, py, pz, vx, vy, vz, ax, ay, az,
c                         bx, by, bz, cx, cy, cz, tol,
c                         nints, atype, ptx, pty, ptz,
c                         vtx, vty, vtz, vtlen,
c                         dprox, dline, tprox, pltx, plty, pltz, nerr)
c
c     Version:  aptparl  Updated    1997 April 21 15:00.
c               aptparl  Originated 1997 April 17 18:20.
c
c     Author:   Arthur L. Edwards, LLNL, L-298, Telephone (925) 422-4123.
c
c
c     Purpose:  For the particle with initial coordinates p = (px, py, pz),
c               initial velocity v = (vx, vy, vz) and constant acceleration
c               a = (ax, ay, az), and for the extended line through points
c               b = (bx, by, bz) and c = (cx, cy, cz), to find the number nints
c               (1, 2 or 3) of proximal or intersection points
c               pt(n) = (ptx(n), pty(n), ptz(n)), n = 1, nints, of the particle
c               path with the line, and for each such point pt(n), to find the
c               velocities vtlen(n) = (vtx(n), vty(n), vtz(n)), the speeds
c               (velocity magnitudes) vtlen(n), the path lengths from point p,
c               dprox(n), the distances dline(n) from points pt(n) to the line,
c               the times from point p to points pt(n), tprox(n), and the
c               corresponding proximal points plt = (pltx, plty, pltz) on
c               the line.
c
c               The particle velocity and coordinates are given by:
c                 vt = v + a*t,
c                 pt = p + v*t + 0.5*a*t**2.
c               The line direction is the unit vector u = (c - b) / |c - b|.
c
c               The distance vector from the particle to the line is given by:
c                 d = (pt - b) - ((pt - b) dot u) * u
c               where is the unit vector of the line, u = (c - b) / |c - b|.
c
c               To find the times of minimum distances, differentiate d**2
c               with respect to time, and solve the resulting cubic equation for
c               t = tprox, to find either one or three real roots.
c                 c0 + c1 * t * c2 * t**2 + c3 * t**3 = 0,
c               where
c                 c0 = 2 * bpn dot vn
c                 c1 = 2 * (bpn dot an + vn**2)
c                 c2 = 3 * vn dot an
c                 c4 = an**2
c               where
c                 bpl = ((p - b) dot u) * u
c                 vl  = (v dot u) * u
c                 al  = (a dot u) * u
c                 bpn = p - b - bpl
c                 vn  = v - vl
c                 an  = a - al
c
c               The proximal or intersection points pt, and the velocity vt are
c               found by substituting the roots tprox in the equations for pt
c               and vt.  The proximal distance dline is the magnitude of d.
c               The proximal points on the line are at t = tprox:
c                 plt = pt - d = b + bpl + vl * t + 0.5 * al * t**2
c
c               See subroutine aptparb for finding dprox.
c
c     History:
c
c     Input:    px, py, pz, vx, vy, vz, ax, ay, az, bx, by, bz, cx, cy, cz, tol.
c
c     Output:   nints, atype, ptx, pty, ptz, vtx, vty, vtz, vtlen, dprox, dline,
c               tprox, pltx, plty, pltz, nerr.
c
c     Calls: aptcubs, aptparb, aptvdis, aptvdot, aptvpap, aptvsum, aptvunb 
c               
c
c     Glossary:
c
c     ax,ay,az  Input    The x, y and z components of the constant acceleration
c                          vector "a".
c
c     atype     Output   The type of result, "proximal", "on line", or
c                        "unknown", the latter if the solution to the cubic
c                        equation for time is not accurate.
c
c     bx,by,bz  Input    The x, y and z coordinates of point "b" on the line.
c
c     cx,cy,cz  Input    The x, y and z coordinates of point "c" on the line.
c
c     dline     Output   The distances from the proximal points or intersections
c                          on the partice path to the line.  Size 3.
c
c     dprox      Output   The distance along the particle path to the proximal
c                          point.  Size = 3.
c
c     nerr      Output   Indicates an input error, if nonzero.
c                          1 if the line has zero length (points b and c are
c                          the same).
c
c     nints     Output   The number of proximal points or intersections of the
c                          particle path and the line.
c
c     pltx,y,z  Output   The x, y and z coordinates of the proximal points or
c                          intersections on the line.  Size 3.
c
c     ptx,y,z   Output   The x, y and z coordinates of the proximal points or
c                          intersections of the particle path with the line.
c                          Size 3.
c
c     px,py,pz  Input    The initial x, y and z coordinates of the particle.
c
c     tol       Input    Numerical tolerance limit.
c                          On Cray computers, recommend 1.e-5 to 1.e-11.
c
c     tprox      Output   The times along the particle path to the proximal
c                          points or intersections with the line.  Size 3.
c
c     vtlen     Output   The magnitudes of velocities vt.  Size 3.
c
c     vtx,y,z   Output   The x, y and z components of the particle velocity
c                          at points pt.  Size = 3.
c
c     vx,vy,vz  Input    The initial x, y and z components of the particle
c                          velocity.
ccend.

c.... Dimensioned arguments.

      dimension atype(1)              ! Type of point, "proximal" or "on point".
      character*8 atype               ! Type of point, "proximal" or "on point".
      dimension dprox(1)              ! Path distance to prox or intersection.
      dimension dline(1)              ! Path distance to prox or intersection.
      dimension pltx(1)               ! Coordinate x of prox point on line.
      dimension plty(1)               ! Coordinate y of prox point on line.
      dimension pltz(1)               ! Coordinate z of prox point on line.
      dimension ptx(1)                ! Coordinate x of prox point on path.
      dimension pty(1)                ! Coordinate y of prox point on path.
      dimension ptz(1)                ! Coordinate z of prox point on path.
      dimension tprox(1)              ! Time to proximity or intersection.
      dimension vtlen(1)              ! Magnitude of particle velocity.
      dimension vtx(1)                ! Component x of particle velocity.
      dimension vty(1)                ! Component y of particle velocity.
      dimension vtz(1)                ! Component z of particle velocity.

c.... Local variables.

      dimension timag(3)              ! Imaginary part of complex time.
cbugc***DEBUG begins.
cbug 9901 format (/ 'aptparl finding proximal points or intersections' /
cbug     &  '  of particle path and a line.  tol=      ',1pe22.14)
cbug 9902 format ('  Particle at p with velocity v, acceleration a:' /
cbug     &  '  px,py,pz=   ',1p3e22.14 /
cbug     &  '  vx,vy,vz=   ',1p3e22.14 /
cbug     &  '  ax,ay,az=   ',1p3e22.14 )
cbug 9903 format ('  Points b and c:' /
cbug     &  '  bx,by,bz=   ',1p3e22.14 /
cbug     &  '  cx,cy,cz=   ',1p3e22.14 )
cbug      write ( 3, 9901) tol
cbug      write ( 3, 9902) px, py, pz, vx, vy, vz, ax, ay, az
cbug      write ( 3, 9903) bx, by, bz, cx, cy, cz
cbugc***DEBUG ends.

c.... Initialize.

      nerr  = 0
      nints = 0

      do 100 n = 1, 3
        dprox(n) = -1.e99
        pltx(n)  = -1.e99
        plty(n)  = -1.e99
        pltz(n)  = -1.e99
        ptx(n)   = -1.e99
        pty(n)   = -1.e99
        ptz(n)   = -1.e99
        tprox(n) = -1.e99
        vtlen(n) = -1.e99
        vtx(n)   = -1.e99
        vty(n)   = -1.e99
        vtz(n)   = -1.e99
  100 continue

c.... Test for input errors.

c.... Find the unit vector ubc from point "b" to point "c".

      call aptvdis (bx, by, bz, cx, cy, cz, 1, tol,
     &              bcx, bcy, bcz, bclen, nerr)

      if (bclen .eq. 0.0) then        ! Line has zero length, no direction.
        nerr = 1
        go to 999
      endif

      call aptvunb (bcx, bcy, bcz, 1, tol, ux, uy, uz, ulen, nerr)

c.... Find the vector "bp" from point "b" to point "p".

      call aptvdis (bx, by, bz, px, py, pz, 1, tol,
     &              bpx, bpy, bpz, bplen, nerr)

c.... Find the components of vector "bp" parallel and perpendicular to line.

      call aptvpap (bpx, bpy, bpz, bcx, bcy, bcz, 1, tol,
     &              bplx, bply, bplz, bpllen,
     &              bpnx, bpny, bpnz, bpnlen, nerr)

c.... Find the point "pl" on the line proximal to point "p".

        call aptvsum (0, 1., bx, by, bz, 1., bplx, bply, bplz, 1, tol,
     &                plx, ply, plz, pllen, nerr)

c.... Find the components of vector "v" parallel and perpendicular to line.

      call aptvpap (vx, vy, vz, bcx, bcy, bcz, 1, tol,
     &              vlx, vly, vlz, vllen,
     &              vnx, vny, vnz, vnlen, nerr)

c.... Find the components of vector "a" parallel and perpendicular to line.

      call aptvpap (ax, ay, az, bcx, bcy, bcz, 1, tol,
     &              alx, aly, alz, allen,
     &              anx, any, anz, anlen, nerr)

c.... Find the dot product of bpn and vn.

      call aptvdot (bpnx, bpny, bpnz, vnx, vny, vnz, 1, tol,
     &              bpdotv, nerr)

c.... Find the dot product of bpn and an.

      call aptvdot (bpnx, bpny, bpnz, anx, any, anz, 1, tol,
     &              bpdota, nerr)

c.... Find the dot product of vn and an.

      call aptvdot (vnx, vny, vnz, anx, any, anz, 1, tol,
     &              vdota, nerr)

c.... Find the times of proximity or intersection.

      if ((vnlen .eq. 0.0) .and. (anlen .eq. 0.0)) then

        nints    = 1
        tprox(1) = 0.0

      elseif (anlen .eq. 0.0) then    ! Path is linear.

        nints    = 1
        tprox(1) = -bpdotv / vnlen**2

      else                            ! Path is parabolic.

c....   Find the coefficients of the cubic equation for time.

        c0 = 2.0 * bpdotv / anlen**2
        c1 = 2.0 * (bpdota + vnlen**2) / anlen**2
        c2 = 3.0 * vdota / anlen**2

        tolx = tol
        if (tol .eq. 0.0) tolx = 1.e-11

        call aptcubs (c0, c1, c2, tolx,
     &                nints, tprox, timag, atype, itrun)

      endif                           ! Tested type of path.

c.... Find the proximal or intersection points on the path and the line.

      do 140 n = 1, nints

        call aptparb (px, py, pz, vx, vy, vz, ax, ay, az,
     &                tprox(n), tol,
     &                ptx(n), pty(n), ptz(n),
     &                vtx(n), vty(n), vtz(n), vtlen(n),
     &                dprox(n), ntype)

        call aptparb (plx, ply, plz, vlx, vly, vlz, alx, aly, alz,
     &                tprox(n), tol,
     &                pltx(n), plty(n), pltz(n),
     &                vltx, vlty, vltz, vltlen,
     &                dlprox, ntype)

        call aptvdis (ptx(n), pty(n), ptz(n),
     &                pltx(n), plty(n), pltz(n), 1, tol, 
     &                dx, dy, dz, dline(n), nerr)

      if (itrun .eq. 2) then
        atype(n) = 'unknown'
      elseif (dline(n) .eq. 0.0) then
        atype(n) = 'ON LINE'
      else
        atype(n) = 'proximal'
      endif

  140 continue

  999 continue
cbugc***DEBUG begins.
cbug 9904 format (/ 'aptparl results:  nints=',i2 )
cbug 9905 format (/ 'Path point type ',a8 /
cbug     &          'Proximal dist ',1pe22.14,2x,a8)
cbug 9906 format (  'Time, path len',1p2e22.14)
cbug 9907 format (  'Prox pt(xyz)  ',1p3e22.14)
cbug 9908 format (  'Prox vel(xyz) ',1p3e22.14 /
cbug     &          '  speed       ',1pe22.14 )
cbug 9909 format (  'Line pt(xyz)  ',1p3e22.14)
cbug      write ( 3, 9904) nints
cbug      do 710 n = 1, nints             ! Loop over proximal points.
cbug        write ( 3, 9905) atype(n), dline(n)
cbug        write ( 3, 9906) tprox(n), dprox(n)
cbug        write ( 3, 9907) ptx(n), pty(n), ptz(n)
cbug        write ( 3, 9908) vtx(n), vty(n), vtz(n), vtlen(n)
cbug        write ( 3, 9909) pltx(n), plty(n), pltz(n)
cbug  710 continue                        ! End of loop over proximal points.
cbugc***DEBUG ends.

      return

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

UCRL-WEB-209832