subroutine aptrotp (ax, ay, az, bx, by, bz, cx, cy, cz,
     &                    dx, dy, dz, tol, rotm, nerr)

ccbeg.
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
c
c                             SUBROUTINE APTROTP
c
c     call aptrotp (ax, ay, az, bx, by, bz, cx, cy, cz,
c    &              dx, dy, dz, tol, rotm, nerr)
c
c     Version:  aptrotp  Updated    1990 October 29 17:45
c               aptrotp  Originated 1989 November 2 14:10.
c
c     Author:   Arthur L. Edwards, LLNL, L-298, Telephone (925) 422-4123.
c
c
c     Purpose:  To find the rotation matrix operator rotm, for rotating the
c               plane containing the vectors a = (ax, ay, az) and
c               b = (bx, by, bz) to be parallel to the plane containing the
c               vectors c = (cx, cy, cz) and d = (dx, dy, dz), around an axis
c               parallel to both planes.  Any components of rotm within tol
c               of -1.0, 0.0, or 1.0, will be truncated to those values.
c               Flag nerr indicates any input error.
c
c     History:  1990 March 14.  Changed tol to 0.0 in call to unit vector
c               subroutine.  Allows small magnitudes.
c               Protected costh from absolute values exceeding 1.0.
c
c     Input:    ax, ay, az, bx, by, bz, cx, cy, cz, dx, dy, dz.
c
c     Output:   rotm, nerr.
c
c     Calls: aptvaxb, aptvuna, aptvxun 
c               
c
c     Glossary:
c
c     ax,ay,az  Input    The x, y, z components of a vector.
c
c     bx,by,bz  Input    The x, y, z components of a vector.
c
c     cx,cy,cz  Input    The x, y, z components of a vector.
c
c     dx,dy,dz  Input    The x, y, z components of a vector.
c
c     nerr      Output   Indicates an input error, if not 0.
c                          1 if the magnitude of any input vector is too small,
c                          or the two vectors in a plane are almost parallel.
c
c     rotm      Output   Rotation operator (a unitary 3 x 3 matrix).
c                          Must be sized rotm(3,3).
c
c     tol       Input    Numerical tolerance limit.  Used to test and adjust
c                          unit vector components and point coordinates.
c                          On Cray computers, recommend 1.e-5 to 1.e-11.
c
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
ccend.

c.... Dimensioned arguments.

c---- Rotation matrix operator.
      dimension rotm    (3,3)

c.... Local variables.

c---- Cosine of rotation angle.
      common /laptrotp/ costh
c---- 1.0 - cosine of rotation angle.
      common /laptrotp/ costhm
c---- Index of matrix row.
      common /laptrotp/ i
c---- Index of matrix column.
      common /laptrotp/ j
c---- Sine of rotation angle.
      common /laptrotp/ sinth
c---- Component x of normal vector.
      common /laptrotp/ uabx
c---- Component y of normal vector.
      common /laptrotp/ uaby
c---- Component z of normal vector.
      common /laptrotp/ uabz
c---- Component x of normal vector.
      common /laptrotp/ ucdx
c---- Component y of normal vector.
      common /laptrotp/ ucdy
c---- Component z of normal vector.
      common /laptrotp/ ucdz
c---- Component x of unit axis vector.
      common /laptrotp/ ux
c---- Component y of unit axis vector.
      common /laptrotp/ uy
c---- Component z of unit axis vector.
      common /laptrotp/ uz
c---- Magnitude of a vector.
      common /laptrotp/ vlen
cbugc***DEBUG begins.
cbug 9901 format (/ 'aptrotp.  Rotating plane containing vectors' /
cbug     &  '  ax,ay,az=',1p3e22.14 /
cbug     &  '  bx,by,bz=',1p3e22.14 /
cbug     &  '  to be parallel to plane containing vectors' /
cbug     &  '  cx,cy,cz=',1p3e22.14 /
cbug     &  '  dx,dy,dz=',1p3e22.14)
cbug      write ( 3, 9901) ax, ay, az, bx, by, bz, cx, cy, cz,
cbug     &  dx, dy, dz
cbugc***DEBUG ends.

c.... Initialize.

      nerr = 0

c.... Find the unit vector normal to the first plane.

      call aptvxun (ax, ay, az, bx, by, bz, 1, tol,
     &              uabx, uaby, uabz, vlen, nerr)

c---- Vector magnitude too small.
      if (vlen .le. tol) then
        nerr = 1
        go to 210
      endif

c.... Find the unit vector normal to the second plane.

      call aptvxun (cx, cy, cz, dx, dy, dz, 1, tol,
     &              ucdx, ucdy, ucdz, vlen, nerr)

c---- Vector magnitude too small.
      if (vlen .le. tol) then
        nerr = 1
        go to 210
      endif

c.... Find the unit vector parallel to the axis of rotation.

      call aptvaxb (uabx, uaby, uabz, ucdx, ucdy, ucdz, 1, tol,
     &              ux, uy, uz, vlen, nerr)

c---- Planes are parallel.
      if (vlen .le. tol) then
        vlen = 1.0
        ux   = 1.0
        uy   = 0.0
        uz   = 0.0
      else
        call aptvuna (ux, uy, uz, 1, 0., vlen, nerr)
      endif

c.... Find the needed functions of the angle of rotation.

      costh  = uabx * ucdx + uaby * ucdy + uabz * ucdz
      costh = amax1 (-1.0, amin1 (costh, 1.0))
      costhm = 1.0 - costh
      sinth  = sqrt (costhm * (1.0 + costh))

c.... Form the components of the rotation matrix.

      rotm(1,1) = costhm * ux * ux + costh
      rotm(1,2) = costhm * ux * uy - sinth * uz
      rotm(1,3) = costhm * ux * uz + sinth * uy
      rotm(2,1) = costhm * uy * ux + sinth * uz
      rotm(2,2) = costhm * uy * uy + costh
      rotm(2,3) = costhm * uy * uz - sinth * ux
      rotm(3,1) = costhm * uz * ux - sinth * uy
      rotm(3,2) = costhm * uz * uy + sinth * ux
      rotm(3,3) = costhm * uz * uz + costh

c---- Adjust components near 0 or 1.
      if (tol .gt. 0.0) then

        do 120 i = 1, 3
          do 110 j = 1, 3
            if (abs (rotm(i,j)) .le. tol) then
              rotm(i,j) = 0.0
            elseif ((abs (abs (rotm(i,j)) - 1.0)) .le. tol) then
              rotm(i,j) = sign (1.0, rotm(i,j))
            endif
  110     continue
  120   continue

c---- Tested tol.
      endif
cbugc***DEBUG begins.
cbug 9902 format ('  rotm=',3(/ 11x,1p3e22.14))
cbug      write ( 3, 9902) ((rotm(i,j), j = 1, 3), i = 1, 3)
cbugc***DEBUG ends.

  210 return

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

UCRL-WEB-209832