subroutine aptwirl (ax, ay, az, vx, vy, vz, pitch, rinv, & px, py, pz, np, tol, nerr) ccbeg. cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc c c SUBROUTINE APTWIRL c c call aptwirl (ax, ay, az, vx, vy, vz, pitch, rinv, c & px, py, pz, np, tol, nerr) c c Version: aptwirl Updated 1995 May 8 13:30. c aptwirl 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 radius r from the axis, the twist is clockwise c 2 * pi * (r - rinv) / 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 perpendicular to the axis c would be twisted to lie on an Archimedean spiral. 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 rinv is negative. c 4 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 increment in radial c distance from the axis for one complete revolution c around the 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 rinv Input Radius from the twist axis at which the twist is zero, c or an integer number of complete revolutions. 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 /laptwirl/ amx ! Negative of coordinate ax. common /laptwirl/ amy ! Negative of coordinate ay. common /laptwirl/ amz ! Negative of coordinate az. common /laptwirl/ angle ! Angle around twist axis. common /laptwirl/ cosang ! Cosine of angle around twist axis. common /laptwirl/ n ! Index of a point. common /laptwirl/ pxerr ! Error in calculating px. common /laptwirl/ pxold ! Coordinate px before twist. common /laptwirl/ pyerr ! Error in calculating py. common /laptwirl/ pyold ! Coordinate py before twist. common /laptwirl/ rotm (3,3) ! Rotation matrix common /laptwirl/ sinang ! Sine of angle around twist axis. common /laptwirl/ ux ! Component x of unit vector. common /laptwirl/ uy ! Component y of unit vector. common /laptwirl/ uz ! Component z of unit vector. common /laptwirl/ vlength ! Length of vector "v". cbugc***DEBUG begins. cbug 9901 format (/ 'aptwirl twisting points around an axis. np=',i3, cbug & ' tol= ',1pe22.14 / cbug & ' pitch= ',1pe22.14 / cbug & ' rinv= ',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, rinv, 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 (rinv .lt. 0.0) then nerr = 3 go to 200 endif if (np .le. 0) then nerr = 4 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 radial distance from the twist axis. raxis = sqrt (px(n)**2 + py(n)**2) c.... Find the angle of twist. angle = 2.0 * pi * (raxis - rinv) / 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 (/ 'aptwirl 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 aptwirl. (+1 line.) end UCRL-WEB-209832