subroutine aptsphp (ax, ay, az, bx, by, bz, cx, cy, cz,
     &                    dx, dy, dz, np, tol, px, py, pz, rad, nerr)

ccbeg.
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
c
c                             SUBROUTINE APTSPHP
c
c     call aptsphp (ax, ay, az, bx, by, bz, cx, cy, cz,
c    &              dx, dy, dz, np, tol, px, py, pz, rad, nerr)
c
c     Version:  aptsphp  Updated    1993 April 28 14:00.
c               aptsphp  Originated 1993 April 28 14:00.
c
c     Author:   Arthur L. Edwards, LLNL, L-298, Telephone (925) 422-4123.
c
c
c     Purpose:  For each of the np sets of 4 distinct points a = (ax, ay, az),
c               b = (bx, by, bz), c = (cx, cy, cz) and d = (dx, dy, dz), to find
c               the center p = (px, py, pz) and radius rad of the sphere through
c               points (a, b, c, d).
c               Flag nerr indicates any input error, if not zero.
c
c     Method:   Point "p" is in each of the three planes bisecting vectors "ab",
c               "ac" and "ad", respectively:
c                 (p - 0.5 * (b + a)) dot (b - a) = 0
c                 (p - 0.5 * (c + a)) dot (c - a) = 0
c                 (p - 0.5 * (d + a)) dot (d - a) = 0
c               These 3 equations are solved for px, py and pz.
c
c     Input:    ax, ay, az, bx, by, bz, cx, cy, cz, dx, dy, dz, np, tol.
c
c     Output:   px, py, pz, rad, nerr.
c
c     Calls: aptvdis, aptvsum, aptvdot, aptsolv 
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 coordinates of point "b".  Size np.
c
c     cx,cy,cz  Input    The x, y, z coordinates of point "c".  Size np.
c
c     dx,dy,dz  Input    The x, y, z coordinates of point "d".  Size np.
c
c     nerr      Output   Indicates an input error, if not 0.
c                          1 if np is not positive.
c
c     np        Input    The number of sets of points (a, b, c, d) for which the
c                          sphere is to be found.  Must be positive.
c
c     px,py,pz  Output   The x, y, z coordinates of the center of the sphere.
c                          Each 1.e99 if the points (a, b, c, d) are congruent,
c                          colinear or coplanar.  Size np.
c
c     rad       Output   The radius of the sphere, larger than 1.e99 if the
c                          points (a, b, c, d) are congruent, colinear, or
c                          coplanar.  Size np.
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 input point "a".
      dimension ax      (1)
c---- Coordinate y of input point "a".
      dimension ay      (1)
c---- Coordinate z of input point "a".
      dimension az      (1)
c---- Coordinate x of input point "b".
      dimension bx      (1)
c---- Coordinate y of input point "b".
      dimension by      (1)
c---- Coordinate z of input point "b".
      dimension bz      (1)
c---- Coordinate x of input point "c".
      dimension cx      (1)
c---- Coordinate y of input point "c".
      dimension cy      (1)
c---- Coordinate z of input point "c".
      dimension cz      (1)
c---- Coordinate x of input point "d".
      dimension dx      (1)
c---- Coordinate y of input point "d".
      dimension dy      (1)
c---- Coordinate z of input point "d".
      dimension dz      (1)
c---- Coordinate x of center of sphere "p".
      dimension px      (1)
c---- Coordinate y of center of sphere "p".
      dimension py      (1)
c---- Coordinate z of center of sphere "p".
      dimension pz      (1)
c---- Radius of sphere.
      dimension rad     (1)

c.... Local variables.  Floating point.

c---- Coefficients of equations for "p".
      common /laptsphp/ a       (3,3)
c---- Dot product of "ab" and "abmid".
      common /laptsphp/ abdot   (64)
c---- Length of vector "abmid".
      common /laptsphp/ abmidl  (64)
c---- Component x of vector "abmid".
      common /laptsphp/ abmidx  (64)
c---- Component y of vector "abmid".
      common /laptsphp/ abmidy  (64)
c---- Component z of vector "abmid".
      common /laptsphp/ abmidz  (64)
c---- Length of vector "ab".
      common /laptsphp/ abvlen  (64)
c---- Component x of vector "ab".
      common /laptsphp/ abx     (64)
c---- Component y of vector "ab".
      common /laptsphp/ aby     (64)
c---- Component z of vector "ab".
      common /laptsphp/ abz     (64)
c---- Dot product of "ac" and "acmid".
      common /laptsphp/ acdot   (64)
c---- Length of vector "acmid".
      common /laptsphp/ acmidl  (64)
c---- Component x of vector "acmid".
      common /laptsphp/ acmidx  (64)
c---- Component y of vector "acmid".
      common /laptsphp/ acmidy  (64)
c---- Component z of vector "acmid".
      common /laptsphp/ acmidz  (64)
c---- Length of vector "ac".
      common /laptsphp/ acvlen  (64)
c---- Component x of vector "ac".
      common /laptsphp/ acx     (64)
c---- Component y of vector "ac".
      common /laptsphp/ acy     (64)
c---- Component z of vector "ac".
      common /laptsphp/ acz     (64)
c---- Dot product of "ad" and "admid".
      common /laptsphp/ addot   (64)
c---- Length of vector "admid".
      common /laptsphp/ admidl  (64)
c---- Component x of vector "admid".
      common /laptsphp/ admidx  (64)
c---- Component y of vector "admid".
      common /laptsphp/ admidy  (64)
c---- Component z of vector "admid".
      common /laptsphp/ admidz  (64)
c---- Length of vector "ad".
      common /laptsphp/ advlen  (64)
c---- Component x of vector "ad".
      common /laptsphp/ adx     (64)
c---- Component y of vector "ad".
      common /laptsphp/ ady     (64)
c---- Component z of vector "ad".
      common /laptsphp/ adz     (64)
c---- Inverse of matrix a.
      common /laptsphp/ b       (3,3)
c---- A big number.
      common /laptsphp/ big
c---- Solution for "p".
      common /laptsphp/ q       (3)
c---- Solution for "p" (check).
      common /laptsphp/ qm      (3)
c---- Residuals for "p" (check).
      common /laptsphp/ qr      (3)
c---- Right side of equations for "p".
      common /laptsphp/ s       (3)
c---- Right side of equations for "p" (check).
      common /laptsphp/ sm      (3)
c---- Residuals of right side of equations for "p" (check).
      common /laptsphp/ sr      (3)
c---- Working memory for aptsolv.
      common /laptsphp/ w       (3,4)

c.... Local variables.  Integers.

c---- Index in arrays.
      common /laptsphp/ n
c---- First index of subset of data.
      common /laptsphp/ n1
c---- Last index of subset of data.
      common /laptsphp/ n2
c---- Index in external array.
      common /laptsphp/ nn
c---- Size of current subset of data.
      common /laptsphp/ ns
cbugc***DEBUG begins.
cbug 9901 format (/ 'aptsphp finding sphere through points:' /
cbug     &  (i4,' ax,ay,az=',1p3e22.14 /
cbug     &  '     bx,by,bz=',1p3e22.14 /
cbug     &  '     cx,cy,cz=',1p3e22.14 /
cbug     &  '     dx,dy,dz=',1p3e22.14))
cbug      write ( 3, 9901) (n, ax(n), ay(n), az(n), bx(n), by(n), bz(n),
cbug     &  cx(n), cy(n), cz(n), dx(n), dy(n), dz(n), n = 1, np)
cbugc***DEBUG ends.

c.... Initialize.

      big = 1.e99

      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)

c.... Loop over subsets of data.

  110 ns = n2 - n1 + 1

c.... Find the difference vectors "ab", "ac" and "ad".

      call aptvdis (ax(n1), ay(n1), az(n1), bx(n1), by(n1), bz(n1), ns,
     &              tol, abx, aby, abz, abvlen, nerr)

      call aptvdis (ax(n1), ay(n1), az(n1), cx(n1), cy(n1), cz(n1), ns,
     &              tol, acx, acy, acz, acvlen, nerr)

      call aptvdis (ax(n1), ay(n1), az(n1), dx(n1), dy(n1), dz(n1), ns,
     &              tol, adx, ady, adz, advlen, nerr)

c.... Find the midpoint vectors "abmid", "acmid" and "admid".

      call aptvsum (0, 0.5, ax(n1), ay(n1), az(n1),
     &                 0.5, bx(n1), by(n1), bz(n1), ns, tol,
     &              abmidx, abmidy, abmidz, abmidl, nerr)

      call aptvsum (0, 0.5, ax(n1), ay(n1), az(n1),
     &                 0.5, cx(n1), cy(n1), cz(n1), ns, tol,
     &              acmidx, acmidy, acmidz, acmidl, nerr)

      call aptvsum (0, 0.5, ax(n1), ay(n1), az(n1),
     &                 0.5, dx(n1), dy(n1), dz(n1), ns, tol,
     &              admidx, admidy, admidz, admidl, nerr)

c.... Find the vector dot products ab.abmid, ac.acmid and ad.admid.

      call aptvdot (abx, aby, abz, abmidx, abmidy, abmidz, ns, tol,
     &              abdot, nerr)

      call aptvdot (acx, acy, acz, acmidx, acmidy, acmidz, ns, tol,
     &              acdot, nerr)

      call aptvdot (adx, ady, adz, admidx, admidy, admidz, ns, tol,
     &              addot, nerr)

c.... Find the center of each sphere.

      do 120 n = 1, ns

        nn = n1 + n - 1

        a(1,1) = abx(n)
        a(1,2) = aby(n)
        a(1,3) = abz(n)
        a(2,1) = acx(n)
        a(2,2) = acy(n)
        a(2,3) = acz(n)
        a(3,1) = adx(n)
        a(3,2) = ady(n)
        a(3,3) = adz(n)
        s(1)   = abdot(n)
        s(2)   = acdot(n)
        s(3)   = addot(n)

        call aptsolv (a, s, 3, w, 3, tol, q, b, qm, qr, sm, sr, nerr)

        px(nn) = q(1)
        py(nn) = q(2)
        pz(nn) = q(3)

c....   Test for colinear, congruent or coplanar points (a, b, c, d).

        if (nerr .eq. 1) then
          px(nn) = big
          py(nn) = big
          pz(nn) = big
          nerr   = 0
        endif

  120 continue

c.... Find the radius of each sphere.

      call aptvdis (ax(n1), ay(n1), az(n1), px(n1), py(n1), pz(n1), ns,
     &              tol, abx, aby, abz, rad(n1), nerr)

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
cbugc***DEBUG begins.
cbug 9902 format (/ 'aptsphp results:' /
cbug     &  (i4,' px,py,pz=',1p3e22.14 /
cbug     &  '     rad=     ',1pe22.14))
cbug      write ( 3, 9902) (n, px(n), py(n), pz(n),
cbug     &  rad(n), n = 1, np)
cbugc***DEBUG ends.

  210 return

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

UCRL-WEB-209832