subroutine aptsphl (r1, r2, r3, r4, tol, x4, y4, z4, nerr) ccbeg. cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc c c SUBROUTINE APTSPHL c c call aptsphl (r1, r2, r3, r4, tol, x4, y4, z4, nerr) c c Version: aptsphl Updated 2001 June 13 13:20. c aptsphl Originated 1999 January 28 11:30. c c Author: Arthur L. Edwards, LLNL, L-298, Telephone (925) 422-4123. c c c Purpose: For the four mutually tangent spheres with radii r1, r2, r3 and c r4, with the center of the first sphere at the origin, the c center of the second sphere at coordinate r1 + r2 on the x axis, c and the center of the third sphere at c x3 = r1 + r3 * (r1 - r2) / (r1 + r2) c y3 = 2.0 * sqrt (r1*r2*r3*(r1+r2+r3)) / abs (r1 + r2) c z3 = 0, c unless r1 + r2 + r3 = 0, and r4 has a unique required value, c r4 = 1 / sqrt (1/r1**2 + 1/r2**2 + 1/r3**2) c in which case: c x3 = r2 c y3 = 0 c z3 = 0, c find the center point p4 = (x4, y4, z4) of the fourth sphere. c Flag nerr indicates any input or result error, if not zero. c c Method: The center of the fourth sphere, point p4 = (x4, y4, z4) is at: c c x4 = r1 + r4 * (r1 - r2) / (r1 + r2) c y4 = 2 * (r1*r2*(r1+r2)*(r3+r4)-r3*r4*(r1**2+r2**2)) / c (y3*(r1+r2)**2) c y4**2 + z4**2 = 4.0 * r1*r2*r4*(r1+r2+r4) / (r1 + r2)**2 c z4 = sqrt ((y4**2 + z4**2) - y4**2) c unless r1 + r2 + r3 = 0, and r4 has a unique required value, c r4 = 1 / sqrt (1/r1**2 + 1/r2**2 + 1/r3**2), c in which case: c x4 = r1 + r4 * (r1 - r2) / (r1 + r2). c y4 = 2.0 * r4 c z4 = 0. c c Input: r1, r2, r3, r4, tol. c c Output: x4, y4, z4, nerr. c c Calls: aptcirl c c Glossary: c c nerr Output Indicates an input or result error, if not 0. c -1 if the magnitude of z4 is small but uncertain. c A zero value of z4 is returned. c 1 if two or more of the radii are negative, or if c one radius is negative, but not large enough in c magnitude for that sphere to enclose the other c three, or one radius is too small for that sphere c to touch each of the other three spheres. c 2 if any of the radii are zero. c 3 if r1 + r2 = 0. c c r1-r4 Input The radii of four mutually tangent spheres. A negative c radius indicates a sphere that surrounds the other c three spheres. A very large radius, relative to the c other three, indicates a straight line. c c x4,y4,z4 Output The x, y, z coordinates of the center of the fourth c sphere. Returned as -1.e99 if nerr = 1. c The sign of z4 is arbitrary. The positive value of c z4 is returned. c c tol Input Numerical tolerance limit. c On computers with 64-bit floating point numbers, c recommend 1.e-5 to 1.e-11. c cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc ccend. cbugc***DEBUG begins. cbug 9901 format (/ 'aptsphl finding coordinates of 4th of four', cbug & ' tangent spheres with radii:' / cbug & ' r1, r2 =',1p2e22.14 / cbug & ' r3, r4 =',1p2e22.14 / cbug & ' tol = ',1pe22.14 ) cbug write ( 3, 9901) r1, r2, r3, r4, tol cbugc***DEBUG ends. c.... Initialize. x4 = -1.e99 y4 = -1.e99 z4 = -1.e99 nerr = 0 c.... Test for input errors. if (r1 * r2 * r3 * r4 .eq. 0.0) then nerr = 2 go to 210 endif s12 = r1 + r2 if (abs (s12) .le. tol * (abs (r1) + abs (r2))) s12 = 0.0 if (s12 .eq. 0.0) then nerr = 3 go to 210 endif c.... Find the curvature of the first four spheres. b1 = 1.0 / r1 b2 = 1.0 / r2 b3 = 1.0 / r3 b4 = 1.0 / r4 c.... Test for special case r1 + r2 + r3 = 0, r4 just fits. s123 = r1 + r2 + r3 errs = tol * (abs (r1) + abs (r2) + abs (r3)) if (abs (s123) .le. errs) then ! Special case. b4 = sqrt (b1**2 + b2**2 + b3**2) rx = 1.0 / b4 if (abs (rx - r4) .gt. tol * (rx + r4)) then nerr = 1 go to 210 endif x1 = 0.0 y1 = 0.0 z1 = 0.0 x2 = r1 + r2 y2 = 0.0 z2 = 0.0 x3 = r2 y3 = 0.0 z3 = 0.0 x4 = r1 + r4 * (r1 - r2) / (r1 + r2) y4 = 2.0 * r4 z4 = 0.0 go to 210 endif ! Special case. c.... Find the center of sphere 3. call aptcirl (r1, r2, r3, tol, x3, y3, nerra) if (nerra .ne. 0) then nerr = 1 go to 210 endif if (y3 .eq. 0.0) then nerr = 1 go to 210 endif z3 = 0.0 c.... Find the differences between radii. d12 = r2 - r1 err12 = tol * (abs (r1) + abs (r2)) if (abs (d12) .le. err12) d12 = 0.0 d23 = r3 - r2 err23 = tol * (abs (r2) + abs (r3)) if (abs (d23) .le. err23) d23 = 0.0 d31 = r1 - r3 err31 = tol * (abs (r3) + abs (r1)) if (abs (d31) .le. err31) d31 = 0.0 d14 = r4 - r1 err14 = tol * (abs (r1) + abs (r4)) if (abs (d14) .le. err14) d14 = 0.0 d24 = r4 - r2 err24 = tol * (abs (r2) + abs (r4)) if (abs (d24) .le. err24) d24 = 0.0 d34 = r4 - r3 err34 = tol * (abs (r3) + abs (r4)) if (abs (d34) .le. err34) d34 = 0.0 c.... Find the center of sphere 4 (x4, y4, z4). c.... Find x4, and the value of argyz = sqrt (y4**2 + z4**2). call aptcirl (r1, r2, r4, tol, x4, argyz, nerra) cbugcbugc***DEBUG begins. cbugcbug 9501 format (' x4, argyz =',1p2e22.14) cbugcbug write ( 3, 9501) x4, argyz cbugcbugc***DEBUG ends. if (nerra .ne. 0) then nerr = 1 go to 210 endif c.... Find y4. if ((d12 .eq. 0.0) .and. & ((d23 .eq. 0.0) .or. (d24 .eq. 0.0))) then y4 = r1**2 / y3 elseif (((d31 .eq. 0.0) .and. (d24 .eq. 0.0)) .or. & ((d14 .eq. 0.0) .and. (d23 .eq. 0.0))) then y4 = 4.0 / ((b1 + b2)**2 * y3) elseif (d12 .eq. 0.0) then arg = b3 + b4 - b1 err = tol * (abs (b3) + abs (b4) + abs (b1)) cbugcbugc***DEBUG begins. cbugcbug 9701 format (' arg12, err =',1p2e22.14 ) cbugcbug write ( 3, 9701) arg, err cbugcbugc***DEBUG ends. if (abs (arg) .le. err) arg = 0.0 cbugcbugc***DEBUG begins. cbugcbug write ( 3, 9701) arg, err cbugcbugc***DEBUG ends. y4 = arg / (b1 * b3 * b4 * y3) elseif (d23 .eq. 0.0) then arg = b1 * (b2 + b4 - b1) + b2 * b4 err = tol * (abs (b1 * b2) + abs (b1 * b4) + & b1**2 + abs (b2 * b4)) cbugcbugc***DEBUG begins. cbugcbug 9702 format (' arg23, err =',1p2e22.14 ) cbugcbug write ( 3, 9702) arg, err cbugcbugc***DEBUG ends. if (abs (arg) .le. err) arg = 0.0 cbugcbugc***DEBUG begins. cbugcbug write ( 3, 9702) arg, err cbugcbugc***DEBUG ends. y4 = 2.0 * arg / (b2 * b4 * (b1 + b2)**2 * y3) elseif (d31 .eq. 0.0) then arg = b2 * (b1 + b4 - b2) + b1 * b4 err = tol * (abs (b1 * b2) + abs (b2 * b4) + & b2**2 + abs (b1 * b4)) cbugcbugc***DEBUG begins. cbugcbug 9703 format (' arg31, err =',1p2e22.14 ) cbugcbug write ( 3, 9703) arg, err cbugcbugc***DEBUG ends. if (abs (arg) .le. err) arg = 0.0 cbugcbugc***DEBUG begins. cbugcbug write ( 3, 9703) arg, err cbugcbugc***DEBUG ends. y4 = 2.0 * arg / (b1 * b4 * (b1 + b2)**2 * y3) elseif (d14 .eq. 0.0) then arg = b2 * (b1 + b3 - b2) + b1 * b3 err = tol * (abs (b1 * b2) + abs (b2 * b3) + & b2**2 + abs (b1 * b3)) cbugcbugc***DEBUG begins. cbugcbug 9704 format (' arg14, err =',1p2e22.14 ) cbugcbug write ( 3, 9704) arg, err cbugcbugc***DEBUG ends. if (abs (arg) .le. err) arg = 0.0 cbugcbugc***DEBUG begins. cbugcbug write ( 3, 9704) arg, err cbugcbugc***DEBUG ends. y4 = 2.0 * arg / (b1 * b3 * (b1 + b2)**2 * y3) elseif (d24 .eq. 0.0) then arg = b1 * (b2 + b3 - b1) + b2 * b3 err = tol * (abs (b1 * b2) + abs (b1 * b3) + & b1**2 + abs (b2 * b3)) cbugcbugc***DEBUG begins. cbugcbug 9705 format (' arg24, err =',1p2e22.14 ) cbugcbug write ( 3, 9705) arg, err cbugcbugc***DEBUG ends. if (abs (arg) .le. err) arg = 0.0 cbugcbugc***DEBUG begins. cbugcbug write ( 3, 9705) arg, err cbugcbugc***DEBUG ends. y4 = 2.0 * arg / (b2 * b3 * (b1 + b2)**2 * y3) else arg = (b1 + b2) * (b3 + b4) - (b1**2 + b2**2) err = tol * (abs (b1 * b3) + abs (b1 * b4) + & abs (b2 * b3) + abs (b2 * b4) + & b1**2 + b2**2) cbugcbugc***DEBUG begins. cbugcbug 9706 format (' arg , err =',1p2e22.14 ) cbugcbug write ( 3, 9706) arg, err cbugcbugc***DEBUG ends. if (abs (arg) .le. err) arg = 0.0 cbugcbugc***DEBUG begins. cbugcbug write ( 3, 9706) arg, err cbugcbugc***DEBUG ends. y4 = 2.0 * arg / (b3 * b4 * (b1 + b2)**2 * y3) endif c.... Find z4. if (d12 .eq. 0.0) then cbugcbugc***DEBUG begins. cbugcbug 9301 format ('r1 = r2 =',1p2e22.14 ) cbugcbug 9302 format ('y3, y3**2 =',1p2e22.14 ) cbugcbug 9303 format ('y4, y4**2 =',1p2e22.14 ) cbugcbug 9304 format ('y4**2 + z4**2=',1p2e22.14 ) cbugcbug 9305 format ('z4**2, z4**2 =',1p2e22.14 ) cbugcbug 9306 format ('z4a , z4b =',1p2e22.14 ) cbugcbug write ( 3, 9301) r1, r2 cbugcbug y3a = sqrt (r3 * (2.0 * r1 + r3)) cbugcbug y3a2 = r3 * (2.0 * r1 + r3) cbugcbug write ( 3, 9302) y3a, y3a2 cbugcbug y4a = (r1 * (r3 + r4) - r3 * r4) / sqrt (r3 * (2.0 * r1 + r3)) cbugcbug y4a2 = (r1 * (r3 + r4) - r3 * r4)**2 / (r3 * (2.0 * r1 + r3)) cbugcbug write ( 3, 9303) y4a, y4a2 cbugcbug ssq = r4 * (2.0 * r1 + r4) cbugcbug write ( 3, 9304) ssq cbugcbug z4a2 = ssq - y4a2 cbugcbug z4b2 = r1 * (r3 + r4) * (4.0 * r3 * r4 + r1 * (r4 - r3)) / cbugcbug & (r3 * (2.0 * r1 + r3)) cbugcbug write ( 3, 9305) z4a2, z4b2 cbugcbug z4a = -1.e99 cbugcbug z4b = -1.e99 cbugcbug if (z4a2 .ge. 0.0) z4a = sqrt (z4a2) cbugcbug if (z4b2 .ge. 0.0) z4b = sqrt (z4b2) cbugcbug write ( 3, 9306) z4a, z4b cbugcbugc***DEBUG ends. if (d34 .eq. 0.0) then arg = 8.0 * r1 * r3**2 / (2.0 * r1 + r3) err = 0.0 else arg = r1 * (4.0 * r3 * r4 * (r3 + r4) - r1 * (r3 - r4)**2) / & (r3 * (2.0 * r1 + r3)) a3 = abs (r3) a4 = abs (r4) err = tol * r1 * (4.0 * a3 * a4 * (a3 + a4) + & r1 * (a3 + a4)**2) / & (a3 * (2.0 * r1 + a3)) cold ssq = r4 * (2.0 * r1 + r4) cold y4a2 = (r1 * (r3 + r4) - r3 * r4)**2 / (r3 * (2.0 * r1 + r3)) cold arg = ssq - y4a2 cbugcbugc***DEBUG begins. cbugcbug adiffg = 4.0 * r1 * r3 * r4 * (r3 + r4) - r1**2 * (r3 - r4)**2 cbugcbug aden = r3 * (2.0 * r1 + r3) cbugcbug arg2 = adiffg / aden cbugcbug cbugcbug 9609 format ('arg, arg2 =',1p2e22.14 ) cbugcbug write ( 3, 9609) arg, arg2 cbugcbugc***DEBUG ends. err = 0.0 endif else arg = argyz**2 - y4**2 err = tol**2 * (argyz**2 + y4**2) endif cbugcbugc***DEBUG begins. cbugcbug arg1 = 8.0 * r1 * r3**2 / (2.0 * r1 + r3) cbugcbug arg2 = r1 * (4.0 * r3 * r4 * (r3 + r4) - r1 * (r3 - r4)**2) / cbugcbug & (r3 * (2.0 * r1 + r3)) cbugcbug arg3 = argyz**2 - y4**2 cbugcbug 9708 format (' arg1,2,3 =',1p3e22.14 ) cbugcbug write ( 3, 9708) arg1, arg2, arg3 cbugcbugc***DEBUG ends. cbugcbugc***DEBUG begins. cbugcbug 9707 format (' argz , err =',1p2e22.14 ) cbugcbug write ( 3, 9707) arg, err cbugcbugc***DEBUG ends. if (abs (arg) .le. err) arg = 0.0 cbugcbugc***DEBUG begins. cbugcbug write ( 3, 9707) arg, err cbugcbugc***DEBUG ends. if (arg .ge. 0.0) then z4 = sqrt (arg) else nerr = -1 z4 = 0.0 endif 210 continue cbugc***DEBUG begins. cbug 9902 format (/ 'aptsphl results: nerr=',i3 / cbug & ' x4, y4, z4 =',1p3e22.14 ) cbug write ( 3, 9902) nerr, x4, y4, z4 cbugc***DEBUG ends. return c.... End of subroutine aptsphl. (+1 line.) end UCRL-WEB-209832