subroutine aptrkis (ax, ay, az, bx, by, bz, qc, qx, qy, qz, & qxy, qyz, qzx, qxx, qyy, qzz, dintmn, dintmx, & np, tol, nints, cx, cy, cz, dint, & sx, sy, sz, costh, nerr) ccbeg. cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc c c SUBROUTINE APTRKIS c c call aptrkis (ax, ay, az, bx, by, bz, qc, qx, qy, qz, c & qxy, qyz, qzx, qxx, qyy, qzz, dintmn, dintmx, c & np, tol, nints, cx, cy, cz, dint, c & sx, sy, sz, costh, nerr) c c Version: aptrkis Updated 1994 October 13 11:00. c aptrkis Originated 1990 February 23 10:00. 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 distance dint c to the intersection c = (cx, cy, cz) of the linear track through c point a = (ax, ay, az) with direction vector b = (bx, by, bz), c and the general second order surface for which the equation is c c f(x,y,z) = qc + qx * x + qy * y + qz * z + c qxy * x * y + qyz * y * z + qzx * z * x + c qxx * x**2 + qyy * y**2 + qzz * z**2 = 0, c c and for which dint is between dintmn and dintmx. If two such c intersections occur, the one with the smaller magnitude of dint c will be returned. If no such intersection is found, nints will c be 0, and dint and the coordinates of point "c" will be very c large. Also, to find the vector "s" normal to the surface at c point "c", and the angle costh between vector "b" and vector c "s". Flag nerr indicates any input error. If dint is less c than tol times the distance from the origin to point "a", dint c will be truncated to zero, and "c" will equal "a". c c The vector normal to the surface is s = (df/dx, df/dy, df/dz). c The sign of the direction of the intersection is determined by c the dot product b * s. c c History: 1990 March 14. Changed tol to 0.0 in call to unit vector c subroutine. Allows small magnitudes. c 1994 February 15. Truncated dint to 0.0 if small compared with c the distance from the origin to point "a". c 1994 October 13. Added arguments sx, sy, sz and costh. c c Input: ax, ay, az, bx, by, bz, qc, qx, qy, qz, c qxy, qyz, qzx, qxx, qyy, qzz, dintmn, dintmx, np, tol. c c Output: nints, cx, cy, cz, dint, sx, sy, sz, costh, nerr. c c Calls: aptqrtv, aptvadd, aptvunb c c c Glossary: c c ax,ay,az Input The x, y, z coordinates of point "a". Size np. c c bx,by,bz Input The x, y, z components of direction vector "b". c If the magnitude is too small, nints will be -1. c c costh Output The cosine of the angle between direction vector "b" c and the normal vector "s" at the intersection point c "c". Size np. c c cx,cy,cz Output The x, y, z coordinates of the point of intersection c of the line through point "a" with unit direction c vector "b", and the surface, if nints = 1. Size np. c c dint Output The distance of the point of intersection "c" from c point "a", if nints = 1. Size np. c Positive if in the same direction as vector "b". c Acceptable only if between dintmn and dintmx. c c dintmn Input The minimum allowable value of dint. Size np. c c dintmx Input The maximum allowable value of dint. Size np. c c nerr Output Indicates an input error, if not 0. c 1 if np is not positive. c c nints Output Indicates the type of intersection found: c 1 if the track through point "a" in direction "b" c intersects the surface at a distance dint between c dintmn and dintmx. c 0 if no such intersection was found. c -1 if vector "b" is too short, based on tol. c Size np. c c np Input Size of arrays. c c q.. Input Coefficients of the implicit equation of a second-order c surface in xyz space (qc, qx, qy, qz, qxy, qyz, qzx, c qxx, qyy, qzz). Size np. c c sx,sy,sz Output The x, y z components of the normal vector at the c intersection point "c" on the quadric surface. 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 x of point "a". dimension ax (1) c---- Coordinate y of point "a". dimension ay (1) c---- Coordinate z of point "a". dimension az (1) c---- Cosine of angle between "b" and "s". dimension costh (1) c---- Coordinate x of point "c". dimension cx (1) c---- Coordinate y of point "c". dimension cy (1) c---- Coordinate z of point "c". dimension cz (1) c---- Component x of vector "b". dimension bx (1) c---- Component y of vector "b". dimension by (1) c---- Component z of vector "b". dimension bz (1) c---- Distance from point "a" to point "c". dimension dint (1) c---- Minimum allowed value of dint. dimension dintmn (1) c---- Maximum allowed value of dint. dimension dintmx (1) c---- Track intersects surface, if 1. dimension nints (1) c---- Coefficient of term 1. dimension qc (1) c---- Coefficient of term x. dimension qx (1) c---- Coefficient of term x**2. dimension qxx (1) c---- Coefficient of term xy. dimension qxy (1) c---- Coefficient of term y. dimension qy (1) c---- Coefficient of term y**2. dimension qyy (1) c---- Coefficient of term yz. dimension qyz (1) c---- Coefficient of term z. dimension qz (1) c---- Coefficient of term zx. dimension qzx (1) c---- Coefficient of term z**2. dimension qzz (1) c---- Component x of vector "s". dimension sx (1) c---- Component y of vector "s". dimension sy (1) c---- Component z of vector "s". dimension sz (1) c.... Local variables. c---- Coefficient of dint**2 in quadratic. common /laptrkis/ aa (64) c---- Coefficient of dint in quadratic. common /laptrkis/ bb (64) c---- A very big number. common /laptrkis/ big c---- Magnitude of vector "b". common /laptrkis/ blen (64) c---- Constant term in quadratic. common /laptrkis/ cc (64) c---- First real root, if nroots .gt. 0. common /laptrkis/ dint1 (64) c---- Second real root, if nroots = 2. common /laptrkis/ dint2 (64) c---- Truncation error in qq, if 1. common /laptrkis/ itrun (64) c---- Index in arrays. common /laptrkis/ n c---- First index of subset of data. common /laptrkis/ n1 c---- Last index of subset of data. common /laptrkis/ n2 c---- 1 if dint1 acceptable. common /laptrkis/ nexit1 c---- 1 if dint2 acceptable. common /laptrkis/ nexit2 c---- Index in external array. common /laptrkis/ nn c---- Number of real roots of quadratic. common /laptrkis/ nroots (64) c---- Size of current subset of data. common /laptrkis/ ns c---- Value of bb**2 - 4.0 * aa * cc. common /laptrkis/ qq (64) c---- Component x of unit vector "u". common /laptrkis/ ux (64) c---- Component y of unit vector "u". common /laptrkis/ uy (64) c---- Component z of unit vector "u". common /laptrkis/ uz (64) c---- Magnitude of a vector. common /laptrkis/ vlen (64) cbugc***DEBUG begins. cbug common /laptrkis/ ddistx (64) cbug common /laptrkis/ ddisty (64) cbug common /laptrkis/ ddistz (64) cbug common /laptrkis/ ddist (64) cbug 9901 format (/ 'aptrkis finding intersection of the line through' / cbug & ' point a with direction vector b, with the second-order' / cbug & ' surface with the coefficients of the given terms:' / cbug & (i3,' ax,ay,az=',1p3e22.14 / cbug & ' bx,by,bz=',1p3e22.14 / cbug & ' 1 =',1pe22.14 / cbug & ' x, y, z =',1p3e22.14 / cbug & " xy,yz,zx=",1p3e22.14 / cbug & " xx,yy,zz=",1p3e22.14 / cbug & " dintmn,x=",1p2e22.14)) cbug write ( 3, 9901) (n, ax(n), ay(n), az(n), bx(n), by(n), bz(n), cbug & qc(n), qx(n), qy(n), qz(n), qxy(n), qyz(n), qzx(n), cbug & qxx(n), qyy(n), qzz(n), dintmn(n), dintmx(n), n = 1, np) cbugc***DEBUG ends. c.... Initialize. c---- A very big number. big = 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) 110 ns = n2 - n1 + 1 c.... Find the unit vector parallel to direction vector "b". call aptvunb (bx(n1), by(n1), bz(n1), ns, 0., & ux, uy, uz, blen, nerr) c.... Find the coefficients of the equation for dint. c---- Loop over subset of data. do 120 n = 1, ns nn = n + n1 - 1 aa(n) = ux(n) * (qxx(nn) * ux(n) + qxy(nn) * uy(n)) + & uy(n) * (qyy(nn) * uy(n) + qyz(nn) * uz(n)) + & uz(n) * (qzz(nn) * uz(n) + qzx(nn) * ux(n)) bb(n) = ux(n) * (qx(nn) + 2.0 * qxx(nn) * ax(nn) + & qxy(nn) * ay(nn) + qzx(nn) * az(nn)) + & uy(n) * (qy(nn) + 2.0 * qyy(nn) * ay(nn) + & qyz(nn) * az(nn) + qxy(nn) * ax(nn)) + & uz(n) * (qz(nn) + 2.0 * qzz(nn) * az(nn) + & qzx(nn) * ax(nn) + qyz(nn) * ay(nn)) cc(n) = qc(nn) + & ax(nn) * (qx(nn) + qxx(nn) * ax(nn) + qxy(nn) * ay(nn)) + & ay(nn) * (qy(nn) + qyy(nn) * ay(nn) + qyz(nn) * az(nn)) + & az(nn) * (qz(nn) + qzz(nn) * az(nn) + qzx(nn) * ax(nn)) c---- End of loop over subset of data. 120 continue c.... Find the roots of the equation for dint. call aptqrtv (0, aa, bb, cc, qq, ns, tol, & nroots, dint1, dint2, itrun, nerr) c.... Find the nearest value of dint between dintmn and dintmx, if any. c---- Loop over local arrays. do 130 n = 1, ns nn = n + n1 - 1 if ((nroots(n) .ge. 1) .and. & (dint1(n) .ge. dintmn(nn)) .and. & (dint1(n) .le. dintmx(nn)) ) then nexit1 = 1 else nexit1 = 0 endif if (nexit1 .ne. 1) then dint1(n) = -big endif if ((nroots(n) .eq. 2) .and. & (abs (dint2(n)) .lt. & abs (dint1(n))) .and. & (dint2(n) .ge. dintmn(nn)) .and. & (dint2(n) .le. dintmx(nn)) ) then nexit2 = 1 else nexit2 = 0 endif if (nexit1 .eq. 1) then nints(nn) = 1 else nints(nn) = 0 endif if (nexit2 .eq. 1) then nints(nn) = 1 endif if (blen((n)) .le. tol) then nints(nn) = -1 endif if (nexit1 .eq. 1) then dint(nn) = dint1(n) else dint(nn) = -big endif if (nexit2 .eq. 1) then dint(nn) = dint2(n) endif dinterr2 = tol**2 * (ax(nn)**2 + ay(nn)**2 + az(nn)**2) if (dint(nn)**2 .lt. dinterr2) dint(nn) = 0.0 c---- End of loop over local arrays. 130 continue c.... Find the intersection points "c". call aptvadd (ax(n1), ay(n1), az(n1), 1.0, dint(n1), & ux(n1), uy(n1), uz(n1), ns, tol, & cx(n1), cy(n1), cz(n1), vlen, nerr) c.... Find the normal vectors "s". do 140 n = 1, ns nn = n + n1 - 1 sx(nn) = qx(nn) + 2.0 * qxx(nn) * cx(nn) + qxy(nn) * cy(nn) + & qzx(nn) * cz(nn) sy(nn) = qy(nn) + qxy(nn) * cx(nn) + 2.0 * qyy(nn) * cy(nn) + & qyz(nn) * cz(nn) sz(nn) = qz(nn) + qzx(nn) * cx(nn) + qyz(nn) * cy(nn) + & 2.0 * qzz(nn) * cz(nn) 140 continue c.... Find the cosines of the angles between "b" and "s". call aptvang (bx(n1), by(n1), bz(n1), sx(n1), sy(n1), sz(n1), & 1, tol, costh(n1), nerr) cbugc***DEBUG begins. cbug call aptvdis (ax(n1), ay(n1), az(n1), cx(n1), cy(n1), cz(n1), cbug & ns, tol, dbugx, dbugy, dbugz, ddist, nerra) cbugc***DEBUG ends. 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 210 continue cbugc***DEBUG begins. cbug 9902 format (/ 'aptrkis results: nerr=',i3 / cbug & (i3,' dint= ',1pe22.14,' nints=',i2 / cbug & ' cx,cy,cz=',1p3e22.14 / cbug & ' sx,sy,sz=',1p3e22.14 / cbug & ' costh= ',1pe22.14 )) cbug 9903 format (i3,' ddist= ',1pe22.14) cbug write ( 3, 9902) nerr, (n, dint(n), nints(n), cbug & cx(n), cy(n), cz(n), sx(n), sy(n), sz(n), costh(n), n = 1, np) cbug npx = np cbug if (npx .gt. 64) npx = 64 cbug call aptvdis (ax, ay, az, cx, cy, cz, cbug & npx, tol, ddistx, ddisty, ddistz, ddist, nerra) cbug write ( 3, 9903) (n, ddist(n), n = 1, npx) cbugc***DEBUG ends. return c.... End of subroutine aptrkis. (+1 line.) end UCRL-WEB-209832