subroutine aptqfit (ax, ay, az, bx, by, bz, cx, cy, cz,
     &                    dx, dy, dz, ex, ey, ez, fx, fy, fz,
     &                    gx, gy, gz, hx, hy, hz, px, py, pz, tol,
     &                    qc, qx, qy, qz, qxy, qyz, qzx, qxx, qyy, qzz,
     &                    nerr)

ccbeg.
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
c
c                             SUBROUTINE APTQFIT
c
c     call aptqfit (ax, ay, az, bx, by, bz, cx, cy, cz,
c    &              dx, dy, dz, ex, ey, ez, fx, fy, fz,
c    &              gx, gy, gz, hx, hy, hz, px, py, pz, tol,
c    &              qc, qx, qy, qz, qxy, qyz, qzx, qxx, qyy, qzz, nerr)
c
c     Version:  aptqfit  Updated    1999 February 23 17:45.
c               aptqfit  Originated 1999 February 23 17:45.
c
c     Author:   Arthur L. Edwards, LLNL, L-298, Telephone (925) 422-4123.
c
c
c     Purpose:  To find any unique quadric surface through the nine points
c               a = (ax, ay, az), b = (bx, by, bz), c = (cx, cy, cz),
c               d = (dx, dy, dz), e = (ex, ey, ez), f = (fx, fy, fz),
c               g = (gx, gy, gz), h = (hx, hy, hz), p = (px, py, pz).
c               The equation of the quadric surface 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               If any points coincide, or a quadric surface fit is impossible
c               or not unique, the method fails, and nerr = 1 is returned.
c
c     Input:    ax, ay, az, bx, by, bz, cx, cy, cz, dx, dy, dz,
c               ex, ey, ez, fx, fy, fz, gx, gy, gz, hx, hy, hz,
c               px, py, pz, tol.
c
c     Output:   qc, qx, qy, qz, qxy, qyz, qzx, qxx, qyy, qzz, nerr.
c
c     Calls: aptsolv, apttris 
c               
c
c     Glossary:
c
c     ax,ay,az  Input    The x, y and z coordinates of point "a".
c
c     bx,by,bz  Input    The x, y and z coordinates of point "b".
c
c     cx,cy,cz  Input    The x, y and z coordinates of point "c".
c
c     dx,dy,dz  Input    The x, y and z coordinates of point "d".
c
c     ex,ey,ez  Input    The x, y end z coordinates of point "e".
c
c     fx,fy,fz  Input    The x, y and z coordinates of point "f".
c
c     gx,gy,gz  Input    The x, y and z goordinates of point "g".
c
c     hx,hy,hz  Input    The x, y anh z coordinates of point "h".
c
c     px,py,pz  Input    The x, y anp z coordinates of point "p".
c
c     nerr      Output   Error indicator.  0 if a good solution was obtained.
c                          1 if the matrix of coefficients "abc" is singular.
c                            The determinant of the matrix "abc" is zero.
c                            No unique solution exists.
c                          2 if any residual "dr" exceeds 1.e-6 times the
c                            maximum d value.  Results may be usable.
c                          3 if any residual "xyzr" exceeds 1.e-6 times the
c                            maximum xyz value.  Results may be usable.
c
c     qc        In/Out   Constant term in the implicit surface equation.
c                          Zero only if the surface passes through the origin.
c
c     qx,qy,qz  In/Out   Coefficients of x, y, z in implicit surface equation.
c                          For a second-order quadric surface in standard form,
c                          qx and qy are zero, but if qzz is zero, qz may be
c                          non-zero.
c
c     q..       In/Out   Coefficients of the second-order terms in the implicit
c                          surface equation:  qxy, qyz, qzx, qxx, qyy, qzz.
c                          Coefficients of x*y, y*z, z*x, x**2, y**2, z**2,
c                          respectively.
c                          For a second-order quadric surface in standard form,
c                          qxy, qyz and qzx are zero, and qxx, qyy and qzz are
c                          ordered in equal or decreasing order of absolute
c                          value, with qxx positive.
c
c     tol       Input    Numerical tolerance limit.
c                          On computers with 48-bit floating-point numbers,
c                          recommend 1.e-5 to 1.e-11.
c
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
ccend.

c.... Local variables.

      common /lhyperb/ abc(9,9)       ! Coefficients of equations (row, column).
      common /lhyperb/ cba(9,9)       ! Inverse of matrix abc     (row, column).
      common /lhyperb/ d(9)           ! Right-hand side constants.
      common /lhyperb/ dm(9)          ! Right-hand side constants check.
      common /lhyperb/ dr(9)          ! Right-hand side constants residuals.
      common /lhyperb/ work(9,10)     ! Working matrix.
      common /lhyperb/ xyz(9)         ! Solution.
      common /lhyperb/ xyzm(9)        ! Solution check.
      common /lhyperb/ xyzr(9)        ! Solution residuals.

cbugc***DEBUG begins.
cbug 9901 format (/ 'aptqfit finding quadric surface fit.  tol=',1pe13.5)
cbug 9902 format (/ 'ax, ay, az=   ',1p3e22.14 /
cbug     &          'bx, by, bz=   ',1p3e22.14 /
cbug     &          'cx, cy, cz=   ',1p3e22.14 /
cbug     &          'dx, dy, dz=   ',1p3e22.14 /
cbug     &          'ex, ey, ez=   ',1p3e22.14 /
cbug     &          'fx, fy, fz=   ',1p3e22.14 /
cbug     &          'gx, gy, gz=   ',1p3e22.14 /
cbug     &          'hx, hy, hz=   ',1p3e22.14 /
cbug     &          'px, py, pz=   ',1p3e22.14 )
cbug      write ( 3, 9901) tol
cbug      write ( 3, 9902) ax, ay, az, bx, by, bz, cx, cy, cz, dx, dy, dz,
cbug     &                 ex, ey, ez, fx, fy, fz, gx, gy, gz, hx, hy, hz,
cbug     &                 px, py, pz
cbugc***DEBUG ends.

c.... Initialize.

      nerr  = 0

c.... Find the coordinates of the nine points to be fit.
c....   Add a random vector to try to avoid a surface through the origin.

      ntry = 0

  110 ntry = ntry + 1

      xran = ranf ()
      yran = ranf ()
      zran = ranf ()

      x1 = ax + xran
      y1 = ay + yran
      z1 = az + zran

      x2 = bx + xran
      y2 = by + yran
      z2 = bz + zran

      x3 = cx + xran
      y3 = cy + yran
      z3 = cz + zran

      x4 = dx + xran
      y4 = dy + yran
      z4 = dz + zran

      x5 = ex + xran
      y5 = ey + yran
      z5 = ez + zran

      x6 = fx + xran
      y6 = fy + yran
      z6 = fz + zran

      x7 = gx + xran
      y7 = gy + yran
      z7 = gz + zran

      x8 = hx + xran
      y8 = hy + yran
      z8 = hz + zran

      x9 = px + xran
      y9 = py + yran
      z9 = pz + zran
cbugcbugc***DEBUG begins.
cbugcbug 9110 format ('aptqfit DEBUG      ',1p3e20.12)
cbugcbug      write ( 3, 9110) x1, y1, z1, x2, y2, z2, x3, y3, z3,
cbugcbug     &                   x4, y4, z4, x5, y5, z5, x6, y6, z6,
cbugcbug     &                   x7, y7, z7, x8, y8, z8, x9, y9, z9
cbugcbugc***DEBUG ends.

c.... Find the coefficients of qx.

      abc(1,1) = x1
      abc(2,1) = x2
      abc(3,1) = x3
      abc(4,1) = x4
      abc(5,1) = x5
      abc(6,1) = x6
      abc(7,1) = x7
      abc(8,1) = x8
      abc(9,1) = x9

c.... Find the coefficients of qy.

      abc(1,2) = y1
      abc(2,2) = y2
      abc(3,2) = y3
      abc(4,2) = y4
      abc(5,2) = y5
      abc(6,2) = y6
      abc(7,2) = y7
      abc(8,2) = y8
      abc(9,2) = y9

c.... Find the coefficients of qz.

      abc(1,3) = z1
      abc(2,3) = z2
      abc(3,3) = z3
      abc(4,3) = z4
      abc(5,3) = z5
      abc(6,3) = z6
      abc(7,3) = z7
      abc(8,3) = z8
      abc(9,3) = z9

c.... Find the coefficients of qxy.

      abc(1,4) = x1 * y1
      abc(2,4) = x2 * y2
      abc(3,4) = x3 * y3
      abc(4,4) = x4 * y4
      abc(5,4) = x5 * y5
      abc(6,4) = x6 * y6
      abc(7,4) = x7 * y7
      abc(8,4) = x8 * y8
      abc(9,4) = x9 * y9

c.... Find the coefficients of qyz.

      abc(1,5) = y1 * z1
      abc(2,5) = y2 * z2
      abc(3,5) = y3 * z3
      abc(4,5) = y4 * z4
      abc(5,5) = y5 * z5
      abc(6,5) = y6 * z6
      abc(7,5) = y7 * z7
      abc(8,5) = y8 * z8
      abc(9,5) = y9 * z9

c.... Find the coefficients of qzx.

      abc(1,6) = z1 * x1
      abc(2,6) = z2 * x2
      abc(3,6) = z3 * x3
      abc(4,6) = z4 * x4
      abc(5,6) = z5 * x5
      abc(6,6) = z6 * x6
      abc(7,6) = z7 * x7
      abc(8,6) = z8 * x8
      abc(9,6) = z9 * x9

c.... Find the coefficients of qxx.

      abc(1,7) = x1 * x1
      abc(2,7) = x2 * x2
      abc(3,7) = x3 * x3
      abc(4,7) = x4 * x4
      abc(5,7) = x5 * x5
      abc(6,7) = x6 * x6
      abc(7,7) = x7 * x7
      abc(8,7) = x8 * x8
      abc(9,7) = x9 * x9

c.... Find the coefficients of qyy.

      abc(1,8) = y1 * y1
      abc(2,8) = y2 * y2
      abc(3,8) = y3 * y3
      abc(4,8) = y4 * y4
      abc(5,8) = y5 * y5
      abc(6,8) = y6 * y6
      abc(7,8) = y7 * y7
      abc(8,8) = y8 * y8
      abc(9,8) = y9 * y9

c.... Find the coefficients of qzz.

      abc(1,9) = z1 * z1
      abc(2,9) = z2 * z2
      abc(3,9) = z3 * z3
      abc(4,9) = z4 * z4
      abc(5,9) = z5 * z5
      abc(6,9) = z6 * z6
      abc(7,9) = z7 * z7
      abc(8,9) = z8 * z8
      abc(9,9) = z9 * z9

c.... Find the right-side constants.  Assume qc = -1.

      d(1) = 1.0
      d(2) = 1.0
      d(3) = 1.0
      d(4) = 1.0
      d(5) = 1.0
      d(6) = 1.0
      d(7) = 1.0
      d(8) = 1.0
      d(9) = 1.0

c.... Solve the nine simultaneous equations.

      call aptsolv (abc, d, 9, work, 9, tol, xyz, cba, xyzm, xyzr,
     &              dm, dr, nerr)

      if (nerr .eq. 1) then
        if (ntry .ge. 10) then
          go to 210
        endif
        nerr = 0
        go to 110
      endif

c.... Store data for the quadric surface.

      qc  = -1.0
      qx  = xyz(1)
      qy  = xyz(2)
      qz  = xyz(3)
      qxy = xyz(4)
      qyz = xyz(5)
      qzx = xyz(6)
      qxx = xyz(7)
      qyy = xyz(8)
      qzz = xyz(9)

c.... Remove the random vector.

      rx = -xran
      ry = -yran
      rz = -zran

      call apttris (1, rx, ry, rz, qc, qx, qy, qz,
     &              qxy, qyz, qzx, qxx, qyy, qzz, tol, nerr)

c.... Renormalize the coefficients to qc = -1.

      if (qc .ne. 0.0) then
        qx  = -qx  / qc
        qy  = -qy  / qc
        qz  = -qz  / qc
        qxy = -qxy / qc
        qyz = -qyz / qc
        qzx = -qzx / qc
        qxx = -qxx / qc
        qyy = -qyy / qc
        qzz = -qzz / qc
        qc  = -1.0
      endif

  210 continue                        ! End of loop over rows.
cbugc***DEBUG begins.
cbug 9910 format (/ 'aptqfit results.  nerr = ',i2)
cbug 9911 format (/ 'nerr =',i2,'.  1 = singular matrix.',
cbug     &  '  2 = large q residuals.  3 = large s residuals.')
cbug 9912 format (/ 'unknowns  qc =',1pe22.14 /
cbug     &          'qx,  qy,  qz =',1p3e22.14 /
cbug     &          'qxy, qyz, qzx=',1p3e22.14 /
cbug     &          'qxx, qyy, qzz=',1p3e22.14 )
cbug      write ( 3, 9910) nerr
cbug      if (nerr .ne. 0) then
cbug        write ( 3, 9911) nerr
cbug      endif
cbug      write ( 3, 9912) qc, qx, qy, qz, qxy, qyz, qzx, qxx, qyy, qzz
cbugc***DEBUG ends.

      return

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

UCRL-WEB-209832