8#include <boost/multi_array.hpp>
33Kernel::Logger logger(
"Quadratic");
55 res += BaseEqn[0] * Pt[0] * Pt[0];
56 res += BaseEqn[1] * Pt[1] * Pt[1];
57 res += BaseEqn[2] * Pt[2] * Pt[2];
58 res += BaseEqn[3] * Pt[0] * Pt[1];
59 res += BaseEqn[4] * Pt[0] * Pt[2];
60 res += BaseEqn[5] * Pt[1] * Pt[2];
61 res += BaseEqn[6] * Pt[0];
62 res += BaseEqn[7] * Pt[1];
63 res += BaseEqn[8] * Pt[2];
78 double res = eqnValue(Pt);
81 return (res > 0) ? 1 : -1;
94 Kernel::V3D N(2 * BaseEqn[0] * Pt[0] + BaseEqn[3] * Pt[1] + BaseEqn[4] * Pt[2] + BaseEqn[6],
95 2 * BaseEqn[1] * Pt[1] + BaseEqn[3] * Pt[0] + BaseEqn[5] * Pt[2] + BaseEqn[7],
96 2 * BaseEqn[2] * Pt[2] + BaseEqn[4] * Pt[0] + BaseEqn[5] * Pt[1] + BaseEqn[8]);
111 for (
int i = 0; i < 3; i++)
112 A[i][i] = BaseEqn[i];
114 A[0][1] = A[1][0] = BaseEqn[3] / 2.0;
115 A[0][2] = A[2][0] = BaseEqn[4] / 2.0;
116 A[1][2] = A[2][1] = BaseEqn[5] / 2.0;
118 for (
int i = 0; i < 3; i++)
119 B[i] = BaseEqn[6 + i];
134 matrixForm(A, B, cc);
140 logger.warning() <<
"Problem with matrix :: distance now guessed at\n";
148 const double aa(alpha[0]);
149 const double aa2(aa * aa);
150 const double ab(alpha[1]);
151 const double ab2(ab * ab);
152 const double ac(alpha[2]);
153 const double ac2(ac * ac);
155 const double ba(beta[0]);
156 const double ba2(ba * ba);
157 const double bb(beta[1]);
158 const double bb2(bb * bb);
159 const double bc(beta[2]);
160 const double bc2(bc * bc);
162 const double da(D[0][0]);
163 const double da2(da * da);
164 const double db(D[1][1]);
165 const double db2(db * db);
166 const double dc(D[2][2]);
167 const double dc2(dc * dc);
171 T[0] = aa * ba + ab * bb + ac * bc + cc + aa2 * da + ab2 * db + ac2 * dc;
173 T[1] = -ba2 - bb2 - bc2 + 4 * ab * bb * da + 4 * ac * bc * da + 4 * cc * da + 4 * aa * ba * db + 4 * ac * bc * db +
174 4 * cc * db + 4 * aa2 * da * db + 4 * ab2 * da * db + 4 * aa * ba * dc + 4 * ab * bb * dc + 4 * cc * dc +
175 4 * aa2 * da * dc + 4 * ac2 * da * dc + 4 * ab2 * db * dc + 4 * ac2 * db * dc;
177 T[2] = -ba2 * da - 4 * bb2 * da - 4 * bc2 * da + 4 * ab * bb * da2 + 4 * ac * bc * da2 + 4 * cc * da2 - 4 * ba2 * db -
178 bb2 * db - 4 * bc2 * db + 16 * ac * bc * da * db + 16 * cc * da * db + 4 * ab2 * da2 * db + 4 * aa * ba * db2 +
179 4 * ac * bc * db2 + 4 * cc * db2 + 4 * aa2 * da * db2 - 4 * ba2 * dc - 4 * bb2 * dc - bc2 * dc +
180 16 * ab * bb * da * dc + 16 * cc * da * dc + 4 * ac2 * da2 * dc + 16 * aa * ba * db * dc + 16 * cc * db * dc +
181 16 * aa2 * da * db * dc + 16 * ab2 * da * db * dc + 16 * ac2 * da * db * dc + 4 * ac2 * db2 * dc +
182 4 * aa * ba * dc2 + 4 * ab * bb * dc2 + 4 * cc * dc2 + 4 * aa2 * da * dc2 + 4 * ab2 * db * dc2;
184 T[3] = -4 * bb2 * da2 - 4 * bc2 * da2 - 4 * ba2 * da * db - 4 * bb2 * da * db - 16 * bc2 * da * db +
185 16 * ac * bc * da2 * db + 16 * cc * da2 * db - 4 * ba2 * db2 - 4 * bc2 * db2 + 16 * ac * bc * da * db2 +
186 16 * cc * da * db2 - 4 * ba2 * da * dc - 16 * bb2 * da * dc - 4 * bc2 * da * dc + 16 * ab * bb * da2 * dc +
187 16 * cc * da2 * dc - 16 * ba2 * db * dc - 4 * bb2 * db * dc - 4 * bc2 * db * dc + 64 * cc * da * db * dc +
188 16 * ab2 * da2 * db * dc + 16 * ac2 * da2 * db * dc + 16 * aa * ba * db2 * dc + 16 * cc * db2 * dc +
189 16 * aa2 * da * db2 * dc + 16 * ac2 * da * db2 * dc - 4 * ba2 * dc2 - 4 * bb2 * dc2 + 16 * ab * bb * da * dc2 +
190 16 * cc * da * dc2 + 16 * aa * ba * db * dc2 + 16 * cc * db * dc2 + 16 * aa2 * da * db * dc2 +
191 16 * ab2 * da * db * dc2;
193 T[4] = -4 * bb2 * da2 * db - 16 * bc2 * da2 * db - 4 * ba2 * da * db2 - 16 * bc2 * da * db2 +
194 16 * ac * bc * da2 * db2 + 16 * cc * da2 * db2 - 16 * bb2 * da2 * dc - 4 * bc2 * da2 * dc -
195 16 * ba2 * da * db * dc - 16 * bb2 * da * db * dc - 16 * bc2 * da * db * dc + 64 * cc * da2 * db * dc -
196 16 * ba2 * db2 * dc - 4 * bc2 * db2 * dc + 64 * cc * da * db2 * dc + 16 * ac2 * da2 * db2 * dc -
197 4 * ba2 * da * dc2 - 16 * bb2 * da * dc2 + 16 * ab * bb * da2 * dc2 + 16 * cc * da2 * dc2 -
198 16 * ba2 * db * dc2 - 4 * bb2 * db * dc2 + 64 * cc * da * db * dc2 + 16 * ab2 * da2 * db * dc2 +
199 16 * aa * ba * db2 * dc2 + 16 * cc * db2 * dc2 + 16 * aa2 * da * db2 * dc2;
201 T[5] = -16 * bc2 * da2 * db2 - 16 * bb2 * da2 * db * dc - 16 * bc2 * da2 * db * dc - 16 * ba2 * da * db2 * dc -
202 16 * bc2 * da * db2 * dc + 64 * cc * da2 * db2 * dc - 16 * bb2 * da2 * dc2 - 16 * ba2 * da * db * dc2 -
203 16 * bb2 * da * db * dc2 + 64 * cc * da2 * db * dc2 - 16 * ba2 * db2 * dc2 + 64 * cc * da * db2 * dc2;
205 T[6] = 16 * da * db * dc * (-bc2 * da * db - bb2 * da * dc - ba2 * db * dc + 4 * cc * da * db * dc);
207 std::vector<double> TRange = T.
realRoots(1e-10);
213 std::vector<double>::const_iterator vc;
214 for (vc = TRange.begin(); vc != TRange.end(); ++vc) {
215 const double daI = 1.0 + 2 * (*vc) * da;
216 const double dbI = 1.0 + 2 * (*vc) * db;
217 const double dcI = 1.0 + 2 * (*vc) * dc;
220 DI[0][0] = 1.0 / daI;
221 DI[1][1] = 1.0 / dbI;
222 DI[2][2] = 1.0 / dcI;
223 xvec = R * (DI * (alpha - beta * *vc));
225 const double Dist = xvec.
distance(Pt);
226 if (Out < 0 || Out > Dist)
240 const double res = eqnValue(Pt);
266 const double a(MA[0][0]), b(MA[0][1]), c(MA[0][2]);
267 const double d(MA[1][0]), e(MA[1][1]), f(MA[1][2]);
268 const double g(MA[2][0]), h(MA[2][1]), j(MA[2][2]);
294 for (
int i = 0; i < 9; i++)
305 for (
int i = 0; i < 10; i++)
306 logger.debug() <<
BaseEqn[i] <<
" ";
307 logger.debug() <<
'\n';
318 std::ostringstream cx;
322 for (
int i = 0; i < 4; i++)
323 cx <<
" " << BaseEqn[i] <<
" ";
324 cx <<
" " << BaseEqn[5] <<
" ";
325 cx <<
" " << BaseEqn[4] <<
" ";
326 for (
int i = 6; i < 10; i++)
327 cx <<
" " << BaseEqn[i] <<
" ";
double distance(const Kernel::V3D &) const override
distance between point and surface (approx)
Kernel::V3D surfaceNormal(const Kernel::V3D &) const override
Normal at surface.
bool onSurface(const Kernel::V3D &) const override
is point valid on surface
std::vector< double > BaseEqn
Base equation (as a 10 point vector)
void displace(const Kernel::V3D &) override
Apply a general displacement to the surface.
void rotate(const Kernel::Matrix< double > &) override
Rotate the surface by matrix MX.
std::unique_ptr< Quadratic > clone() const
void matrixForm(Kernel::Matrix< double > &, Kernel::V3D &, double &) const
Converts the baseEqn into the matrix form such that.
void print() const override
Print out the genreal equation for debugging.
void write(std::ostream &) const override
Writes out an MCNPX surface description Note : Swap since base equation is swapped in gq output (mcnp...
int side(const Kernel::V3D &) const override
Determine if the the Point is true to the surface or on the other side.
Quadratic * doClone() const override=0
Abstract clone function.
double eqnValue(const Kernel::V3D &) const
Helper function to calcuate the value of the equation at a fixed point.
Holds a basic quadratic surface.
static const int Nprecision
Precision of the output.
virtual void print() const
Simple print out function for surface header.
T Invert()
LU inversion routine.
Matrix< T > Tprime() const
Transpose the matrix.
int Diagonalise(Matrix< T > &, Matrix< T > &) const
(only Symmetric matrix)
double distance(const V3D &v) const noexcept
Calculates the distance between two vectors.
double normalize()
Make a normalized vector (return norm value)
Holds a polynominal as a primary type.
std::vector< double > realRoots(double const =-1.0)
Get just the real roots.
MANTID_KERNEL_DLL void writeMCNPX(const std::string &Line, std::ostream &OX)
Write file in standard MCNPX input form.
constexpr double Tolerance
Standard tolerance value.