subroutine aptwist (ax, ay, az, vx, vy, vz, pitch,
     &                    px, py, pz, np, tol, nerr)

ccbeg.
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
c
c                             SUBROUTINE APTWIST
c
c     call aptwist (ax, ay, az, vx, vy, vz, pitch,
c    &              px, py, pz, np, tol, nerr)
c
c     Version:  aptwist  Updated    1995 May 8 13:30.
c               aptwist  Originated 1995 May 8 13:30.
c
c     Author:   Arthur L. Edwards, LLNL, L-298, Telephone (925) 422-4123.
c
c
c     Purpose:  To twist the np points p = (px, py, pz) around the axis through
c               point a = (ax, ay, az) parallel to vector v = (vx, vy, vz).
c               For a point at axial distance d from point "a", the twist is
c               clockwise 2 * pi * d / pitch (radians).
c               Note: a clockwise twist looks counterclockwise when looking in
c               the negative direction along the axis.
c               Flag nerr indicates any input error.
c
c               For example, points on a straight line parallel to the axis
c               would be twisted to lie on a curve shaped like a coil spring.
c
c     Calls: aptmovp, aptrotv, apttran, aptvusz 
c
c     Glossary:
c
c     ax,ay,az  Input    Coordinates x, y and z of point "a" on the twist axis.
c
c     nerr      Output   Indicates an input error, if not zero.
c                          1 if vector "v" has zero length.
c                          2 if pitch is zero.
c                          3 if np is not positive.
c
c     np        Input    Size of arrays px, py, pz. Number of points "p".
c
c     pitch     Input    The pitch of the twist, i.e., the distance along the
c                          axis vector for one complete revolution around the
c                          axis.
c
c     px,py,pz  In/Out   Coordinates x, y and z of point "p", to be twisted
c                          around twist axis "v" through point "a".
c
c     tol       Input    Numerical tolerance limit.
c                          On Cray computers, recommend 1.e-5 to 1.e-11.
c
c     vx,vy,vz  Input    Components x, y and z of twist axis vector "v".
c
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
ccend.

c____ Mathematical constant pi.  Dimensionless.

      parameter (pi = 3.14159265358979323)

c.... Dimensioned arguments.

      dimension px(1)                 ! Coordinate x of point "p".
      dimension py(1)                 ! Coordinate y of point "p".
      dimension pz(1)                 ! Coordinate z of point "p".

c.... Local variables.

      common /laptwist/ amx           ! Negative of coordinate ax.
      common /laptwist/ amy           ! Negative of coordinate ay.
      common /laptwist/ amz           ! Negative of coordinate az.
      common /laptwist/ angle         ! Angle around twist axis.
      common /laptwist/ cosang        ! Cosine of angle around twist axis.
      common /laptwist/ n             ! Index of a point.
      common /laptwist/ pxerr         ! Error in calculating px.
      common /laptwist/ pxold         ! Coordinate px before twist.
      common /laptwist/ pyerr         ! Error in calculating py.
      common /laptwist/ pyold         ! Coordinate py before twist.
      common /laptwist/ rotm (3,3)    ! Rotation matrix
      common /laptwist/ sinang        ! Sine of angle around twist axis.
      common /laptwist/ ux            ! Component x of unit vector.
      common /laptwist/ uy            ! Component y of unit vector.
      common /laptwist/ uz            ! Component z of unit vector.
      common /laptwist/ vlength       ! Length of vector "v".

cbugc***DEBUG begins.
cbug 9901 format (/ 'aptwist twisting points around an axis.  np=',i3,
cbug     &  '  tol=     ',1pe22.14 /
cbug     &  '  pitch=   ',1pe22.14 /
cbug     &  '  ax,ay,az=',1p3e22.14 /
cbug     &  '  vx,vy,vz=',1p3e22.14 )
cbug 9902 format (i3,'  px,py,pz=',1p3e22.14 )
cbug
cbug      write ( 3, 9901) np, tol, pitch, ax, ay, az, vx, vy, vz
cbug      do 110 n = 1, np
cbug        write ( 3, 9902) n, px(n), py(n), pz(n)
cbug  110 continue
cbugc***DEBUG ends.

c.... initialize.

      nerr = 0

c.... Test for input errors.

      call aptvusz (vx, vy, vz, tol, ux, uy, uz, vlength)

      if (vlength .eq. 0.0) then
        nerr = 1
        go to 200
      endif

      if (pitch .eq. 0.0) then
        nerr = 2
        go to 200
      endif

      if (np .le. 0) then
        nerr = 3
        go to 200
      endif

c.... Do a translation on points "p" that translates point "a" to the origin.

      call apttran (ax, ay, az, px, py, pz, np, tol, nerr)

c.... Do a rotation on points "p" that rotates vector "v" to the z axis.

      call aptrotv (vx, vy, vz, 0.0, 0.0, 1.0, tol, rotm, nerr)

      call aptmopv (rotm, 0, 0.0, 0.0, 0.0, px, py, pz, np, tol, nerr)

c.... Twist all of the points.

      do 100 n = 1, np                ! Loop over points.

c....   Find the angle of twist.

        angle = 2.0 * pi * pz(n) / pitch

c....   Twist this point.

        cosang = cos (angle)
        if (abs (cosang - 1.0) .le. tol) cosang =  1.0
        if (abs (cosang + 1.0) .le. tol) cosang = -1.0
        if (abs (cosang) .le. tol)       cosang =  0.0

        sinang = sin (angle)
        if (abs (sinang - 1.0) .le. tol) sinang =  1.0
        if (abs (sinang + 1.0) .le. tol) sinang = -1.0
        if (abs (sinang) .le. tol)       sinang =  0.0

        pxold  = px(n)
        pyold  = py(n)

        px(n)  = pxold * cosang - pyold * sinang
        pxerr  = tol * (abs (pxold * cosang) + abs (pyold * sinang))
        if (abs (px(n)) .le. pxerr) px(n) = 0.0

        py(n)  = pxold * sinang + pyold * cosang
        pyerr  = tol * (abs (pxold * sinang) + abs (pyold * cosang))
        if (abs (py(n)) .le. pyerr) py(n) = 0.0

  100 continue                        ! End of loop over points.

c.... Do a rotation on point "p" that rotates the z axis to vector "v".

      call aptmopv (rotm, 1, 0.0, 0.0, 0.0, px, py, pz, np, tol, nerr)

      if (nerr .ne. 0) nerr = 4

c.... Do a translation on point "p" that translates the origin to point "a".

      amx = -ax
      amy = -ay
      amz = -az

      call apttran (amx, amy, amz, px, py, pz, np, tol, nerr)

  200 continue
cbugc***DEBUG begins.
cbug 9903 format (/ 'aptwist results:  nerr=',i3)
cbug      write ( 3, 9903) nerr
cbug      do 205 n = 1, np
cbug        write ( 3, 9902) n, px(n), py(n), pz(n)
cbug  205 continue
cbugc***DEBUG ends.

  210 return

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

UCRL-WEB-209832