subroutine aptcris (ax, ay, az, qc, qx, qy, qz, qxy, qyz, qzx, & qxx, qyy, qzz, tol, bx, by, bz, & nrad, rcurve, cx, cy, cz, ux, uy, uz, nerr) ccbeg. cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc c c SUBROUTINE APTCRIS c c call aptcris (ax, ay, az, qc, qx, qy, qz, qxy, qyz, qzx, c & qxx, qyy, qzz, tol, bx, by, bz, c & nrad, rcurve, cx, cy, cz, ux, uy, uz, nerr) c c Version: aptcris Updated 1997 December 3 13:50. c aptcris Originated 1997 October 31 14:00. c c Author: Arthur L. Edwards, LLNL, L-298, Telephone (925) 422-4123. c c Source: In directory ~edwards/work/apt/src on the DEC Compass Cluster. c c Purpose: To find, at point a = (ax, ay, az) on the quadric surface c specified by the coefficients qx to qzz (with qc adjusted to c make the quadric surface pass through point "a"), the normal c vector b = (bx, by, bz), the number nrad of tangent directions c in the surface, with extreme values of the radius of curvature c rcurve, the corresponding centers of curvature c = (cx, cy, cz), c and the tangent unit vectors u = (ux, uy, uz). c c The implicit equation of the quadric curve is: c c F(x,y,z) = qc + qx * x + qy * y + c qxy * x * y + qyz * y * z + qzx * z * x + c qxx * x**2 + qyy * y**2 + qzz * z**2 = 0 . c c Results may be unpredictable if the coefficients of the quadric c surface differ by many orders of magnitude. c c Flag nerr indicates any error. c c Method: c c The normal vector "b" at point "a" has the components: c c bx = qx + 2.0 * qxx * ax + qxy * ay + qzx * az c by = qy + 2.0 * qyy * ay + qyz * az + qxy * ax c bz = qz + 2.0 * qzz * az + qzx * ax + qyz * ay c c If the system is rotated to point vector "b" in the z direction, c then all tangent unit vectors through point "a" will satisfy c u = (cos(t), sin(t), 0), c where t is an arbitrary angle, and c rcurve = -|b| / (2*W), c where |b| is the magnitude of vector "b", and c W = qxx*cos(t)**2 + qxy*cos(t)*sin(t) + qyy*sin(t)**2. c The extreme values of rcurve occur at W = 0, if there are any c real values of t that give that result, and at the extreme c values of W, found by differentiating the equation for W with c respect to t, setting the result to zero, and solving for t: c (qyy - qxx) * cos(2*t) + qxy * sin(2*t) = 0 c For each solution t, the values of W, rcurve and U may be found. c The center of curvature is at c = a - b / (2*W). c c Input: ax, ay, az, qc, qx, qy, qz, qxy, qyz, qzx, qxx, qyy, qzz, tol. c c Output: rcurve, cx, cy, cz, ux, uy, uz, nerr. c c Calls: aptmopv, aptqnor, aptqrts, aptrotv c c c Glossary: c c ax,ay,az Input The x, y and z coordinates of point "a", at which to c find the normal vector, extreme radii of curvature c and the corresponding tangent vectors, for the c quadric surface though point "a". c c bx,by,bz Output The x, y and z components at point "a" of the normal c vector of the quadric surface through point "a". c c cx,cy,cz Output The x, y and z coordinates of point "c", the center of c curvature corresponding to each value of rcurve. c Size 4. c = a + rcurve * b / |b|. c c nerr Output Indicates an indeterminate point "a", if not zero: c 1 if the normal vector "b" is zero at point "a". c c nrad Output Number of values of extreme radii of curvature rcurve c and unit vectors "u" found. c If zero, the normal vector "b" is zero at point "a", c and the values are indeterminate. c c rcurve Output The nrad extreme values of the radius of curvature, c in the direction of vector "b", of all possible c curves in the quadric surface through point "a". c Size 4. c Actually, values for which the reciprocal of rcurve c has extreme values, or is zero. c c qc-qzz Input Coefficients of the implicit equation of one quadric c surface of the family of quadric surfaces represented c by all possible values of qc. Any value of qc may be c specified, and it will not be changed. c c tol Input Numerical tolerance limit. c On 64-bit computers, recommend 1.e-11. c On 32-bit computers, recommend 1.e-6. c c ux,uy,uz Output The x, y and z components of nrad unit vectors "u" c tangent to the curves lying in the quadric surface c through point "a", having the nrad extreme values c rcurve of the radius of curvature. Size 4. c c History: c cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc ccend. c.... Dimensioned arguments. dimension cx(4) ! Coordinate x of a center of curvature. dimension cy(4) ! Coordinate y of a center of curvature. dimension cz(4) ! Coordinate z of a center of curvature. dimension rcurve(4) ! An extreme radius of curvature. dimension ux(4) ! Component x of a tangent unit vector. dimension uy(4) ! Component y of a tangent unit vector. dimension uz(4) ! Component z of a tangent unit vector. c.... Local variables. common /laptcris/ rotm(3,3) ! Rotation matrix, vector "d" to z axis. common /laptcris/ theta(4) ! Angle of unit vector from x axis. common /laptcris/ pi ! Mathematic constant, pi. cbugc***DEBUG begins. cbug 9901 format (/ 'aptcris 001 finding extreme radii of curvature.' / cbug & ' tol=',1pe13.5 / cbug & ' ax,ay,az= ',1p3e22.14 ) cbug 9902 format ( cbug & ' qc= ',1pe22.14 / cbug & ' qx,qy,qz= ',1p3e22.14 / cbug & ' qxy,qyz,qzx=',1p3e22.14 / cbug & ' qxx,qyy,qzz=',1p3e22.14) cbug write ( 3, 9901) tol, ax, ay, az cbug write ( 3, 9902) qc, qx, qy, qz, qxy, qyz, qzx, qxx, qyy, qzz cbugc***DEBUG ends. c.... Initialize. pi = 3.14159265358979323 ! Mathematical constant, pi. nerr = 0 nrad = 0 do 110 n = 1, 4 rcurve(n) = 0.0 cx(n) = -1.e99 cy(n) = -1.e99 cz(n) = -1.e99 ux(n) = -1.e99 uy(n) = -1.e99 uz(n) = -1.e99 110 continue c.... Find the normal vector "b" at point "a" of the quadric surface. call aptqnor (ax, ay, az, qc, qx, qy, qz, qxy, qyz, qzx, & qxx, qyy, qzz, tol, bc, bx, by, bz, blen, nerra) cbugcbugc***DEBUG begins. cbugcbug 9961 format ('aptcris DEBUG. blen=',1pe22.14) cbugcbug write ( 3, 9961) blen cbugcbugc***DEBUG ends. if (nerra .ne. 0) then nerr = 1 go to 999 endif c.... Find the rotation operator to rotate vector "b" to the z axis. call aptrotv (bx, by, bz, 0., 0., 1., tol, rotm, nerra) cbugcbugc***DEBUG begins. cbugcbug 9990 format (' op11,op12,op13 ',1p3e20.12 / cbugcbug & ' op21,op22,op23 ',1p3e20.12 / cbugcbug & ' op31,op32,op33 ',1p3e20.12) cbugcbug write ( 3, 9990) ((rotm(i,j), j = 1, 3), i = 1, 3) cbugcbugc***DEBUG ends. if (nerra .ne. 0) then nerr = 1 go to 999 endif c.... Rotate the quadric surface around point "a" to make vector "b" c.... point in the z direction. sc = qc sx = qx sy = qy sz = qz sxy = qxy syz = qyz szx = qzx sxx = qxx syy = qyy szz = qzz cbugcbugc***DEBUG begins. cbugcbug 9960 format (' sc ',1pe20.12 ) cbugcbug 9980 format (' sx, sy, sz ',1p3e20.12 ) cbugcbug 9985 format (' sxy, syz, szx ',1p3e20.12 ) cbugcbug 9991 format (' sxx, syy, szz ',1p3e20.12 ) cbugcbug write ( 3, 9960) sc cbugcbug write ( 3, 9980) sx, sy, sz cbugcbug write ( 3, 9985) sxy, syz, szx cbugcbug write ( 3, 9991) sxx, syy, szz cbugcbugc***DEBUG ends. call aptrois (rotm, 0, ax, ay, az, sc, sx, sy, sz, & sxy, syz, szx, sxx, syy, szz, tol, nerra) cbugcbugc***DEBUG begins. cbugcbug write ( 3, 9960) sc cbugcbug write ( 3, 9980) sx, sy, sz cbugcbug write ( 3, 9985) sxy, syz, szx cbugcbug write ( 3, 9991) sxx, syy, szz cbugcbugc***DEBUG ends. c.... Find any infinite radii of curvature. c.... sxx + sxy * tan(theta) + syy * tan(theta)**2 = 0. c.... Solve equation for tan(theta). call aptqrts (0, syy, sxy, sxx, qq, tol, & nroots, root1, root2, itrun) if (nroots .eq. -1) then c.... Solve equation for cot(theta). call aptqrts (0, sxx, sxy, syy, qq, tol, & nroots, root1, root2, itrun) if (nroots .eq. -1) then ! All angles same. No curvature. nrad = 4 theta(1) = 0.0 theta(2) = 0.25 * pi theta(3) = 0.50 * pi theta(4) = 0.75 * pi rcurve(1) = 1.e99 rcurve(2) = 1.e99 rcurve(3) = 1.e99 rcurve(4) = 1.e99 go to 120 elseif (nroots .eq. 1) then nrad = 1 theta(1) = atan2 (1.0, root1) rcurve(1) = 1.e99 elseif (nroots .eq. 2) then nrad = 2 theta(1) = atan2 (1.0, root1) theta(2) = atan2 (1.0, root2) rcurve(1) = 1.e99 rcurve(2) = 1.e99 go to 120 endif elseif (nroots .eq. 1) then nrad = 1 theta(1) = atan (root1) rcurve(1) = 1.e99 elseif (nroots .eq. 2) then nrad = 2 theta(1) = atan (root1) theta(2) = atan (root2) rcurve(1) = 1.e99 rcurve(2) = 1.e99 endif cbugcbugc***DEBUG begins. cbugcbug 9981 format ('aptcris DEBUG. # of infinite radii =',i3) cbugcbug if (nrad .ne. 0) then cbugcbug write ( 3, 9981) nrad cbugcbug endif cbugcbugc***DEBUG ends. c.... Find any extreme values of curvature. c.... (syy - sxx) * sin(2*theta) + sxy * cos(2*theta) = 0 if ((syy .eq. sxx) .and. (sxy .eq. 0.0)) then ! All angles same. nrad = 4 theta(1) = 0.0 theta(2) = 0.25 * pi theta(3) = 0.50 * pi theta(4) = 0.75 * pi else ! Two angles 90 degrees apart. sinth = sxy costh = sxx - syy angle = 0.5 * atan2 (sinth, costh) nrad = nrad + 1 theta(nrad) = angle angle = angle + 0.5 * pi do 115 n = 1, nrad dang = abs (angle - theta(n)) - pi if (abs (dang) .le. tol) go to 120 115 continue nrad = nrad + 1 theta(nrad) = angle endif ! Tested coefficients. c.... Find the tangent unit vectors and the radii and centers of curvature. 120 if (nrad .gt. 0) then ! Extreme radii of curvature found. cbugcbugc***DEBUG begins. cbugcbug 9971 format ('theta=',1p4e15.8) cbugcbug write ( 3, 9971) (theta(n), n = 1, nrad) cbugcbugc***DEBUG ends. do 130 n = 1, nrad ! Loop over extreme radii. costh = cos (theta(n)) sinth = sin (theta(n)) cbugcbugc***DEBUG begins. cbugcbug 9983 format ('costh, sinth=',1p2e22.14) cbugcbug write ( 3, 9983) costh, sinth cbugcbugc***DEBUG ends. if (abs (costh) .le. tol) costh = 0.0 if (abs (sinth) .le. tol) sinth = 0.0 cbugcbugc***DEBUG begins. cbugcbug write ( 3, 9983) costh, sinth cbugcbugc***DEBUG ends. ux(n) = costh uy(n) = sinth uz(n) = 0.0 den = sxx * costh**2 + sxy * costh*sinth + syy * sinth**2 denerr = 3.0 * tol * (abs (sxx) * costh**2 + & abs (sxy * costh * sinth) + & abs (syy) * sinth**2) if (abs (den) .le. denerr) den = 0.0 if (den .eq. 0.0) then ! No curvature. rcurve(n) = 1.e99 else ! Some curvature. if (rcurve(n) .ne. 1.e99) then rcurve(n) = -0.5 * blen / den endif endif cbugcbugc***DEBUG begins. cbugcbug 9972 format ('n, den, denerr, rcurve=',i3,2x,1p3e15.7) cbugcbug write ( 3, 9972) n, den, denerr, rcurve(n) cbugcbugc***DEBUG ends. call aptvsum (0, 1.0, ax, ay, az, rcurve(n), 0., 0., 1., & 1, tol, cx(n), cy(n), cz(n), clen, nerr) 130 continue ! End of loop over extreme radii. endif ! Tested nrad. c.... Rotate any centers of curvature and tangent unit vectors back to the c.... original direction. if (nrad .gt. 0) then call aptmopv (rotm, 1, 0., 0., 0., ux, uy, uz, nrad, tol, nerra) call aptmopv (rotm, 1, ax, ay, az, cx, cy, cz, nrad, tol, nerra) endif c.... Remove any duplicate results. if (nrad .gt. 1) then ! Remove any duplicate results. nrads = nrad ! Number of original results. nrad = 1 ! Initial number of unique results. do 150 n = 2, nrads ! Loop over original results. do 140 nn = 1, nrad ! Loop over unique results. if ((ux(n) .eq. ux(nn)) .and. & (uy(n) .eq. uy(nn)) .and. & (uz(n) .eq. uz(nn)) .and. & (cx(n) .eq. cx(nn)) .and. & (cy(n) .eq. cy(nn)) .and. & (cz(n) .eq. cz(nn)) .and. & (rcurve(n) .eq. rcurve(nn))) go to 150 ! Not unique. 140 continue ! End of loop over unique results. c.... This result is unique. Save. nrad = nrad + 1 ux(nrad) = ux(n) uy(nrad) = uy(n) uz(nrad) = uz(n) cx(nrad) = cx(n) cy(nrad) = cy(n) cz(nrad) = cz(n) rcurve(nrad) = rcurve(n) 150 continue ! End of loop over original results. endif ! Remove any duplicate results. 999 continue cbugc***DEBUG begins. cbug 9910 format (/ 'aptcris results: nrad=',i2,' nerr=',i2) cbug 9911 format ( 'Normal (xyz)=',1p3e22.14 ) cbug 9912 format (/ 'Tangent (xyz)=',1p3e22.14 / cbug & 'Center (xyz)=',1p3e22.14 / cbug & 'Radius =',1pe22.14 ) cbug write ( 3, 9910) nrad, nerr cbug write ( 3, 9911) bx, by, bz cbug if (nrad .gt. 0) then cbug do 991 n = 1, nrad cbug write ( 3, 9912) ux(n), uy(n), uz(n), cbug & cx(n), cy(n), cz(n), rcurve(n) cbug 991 continue cbug endif cbugc***DEBUG ends. return c.... End of subroutine aptcris. (+1 line) end UCRL-WEB-209832