20 #ifndef vtk_m_worklet_cellmetrics_Oddy_h
21 #define vtk_m_worklet_cellmetrics_Oddy_h
42 #define UNUSED(expr) (void)(expr);
53 template <
typename OutType,
typename Po
intCoordVecType,
typename CellShapeType>
55 const PointCoordVecType& pts,
76 template <
typename Scalar,
typename Vector>
79 const Scalar two(2.0);
80 const Scalar four(4.0);
84 const Scalar q = (((liMagnitudeSquared - liPlus1MagnitudeSquared) *
85 (liMagnitudeSquared - liPlus1MagnitudeSquared)) +
86 (four *
static_cast<Scalar
>(vtkm::Dot(Li, LiPlus1) * vtkm::Dot(Li, LiPlus1)))) /
87 (two * niPlus1MagnitudeSquared);
91 template <
typename OutType,
typename Po
intCoordVecType>
93 const PointCoordVecType& pts,
94 vtkm::CellShapeTagQuad,
103 using Scalar = OutType;
104 using CollectionOfPoints = PointCoordVecType;
105 using Vector =
typename PointCoordVecType::ComponentType;
107 const Vector L0 = GetQuadL0<Scalar, Vector, CollectionOfPoints>(pts);
108 const Vector L1 = GetQuadL1<Scalar, Vector, CollectionOfPoints>(pts);
109 const Vector L2 = GetQuadL2<Scalar, Vector, CollectionOfPoints>(pts);
110 const Vector L3 = GetQuadL3<Scalar, Vector, CollectionOfPoints>(pts);
111 const Vector N0 = GetQuadN0<Scalar, Vector, CollectionOfPoints>(pts);
112 const Vector N1 = GetQuadN1<Scalar, Vector, CollectionOfPoints>(pts);
113 const Vector N2 = GetQuadN2<Scalar, Vector, CollectionOfPoints>(pts);
114 const Vector N3 = GetQuadN3<Scalar, Vector, CollectionOfPoints>(pts);
119 return vtkm::Infinity<Scalar>();
122 const Scalar q0 = GetQuadOddyQi<Scalar, Vector>(L0, L1, N1);
123 const Scalar q1 = GetQuadOddyQi<Scalar, Vector>(L1, L2, N2);
124 const Scalar q2 = GetQuadOddyQi<Scalar, Vector>(L2, L3, N3);
125 const Scalar q3 = GetQuadOddyQi<Scalar, Vector>(L3, L0, N0);
127 const Scalar q = vtkm::Max(q0, vtkm::Max(q1, vtkm::Max(q2, q3)));
138 template <
typename OutType,
typename Po
intCoordVecType>
140 const PointCoordVecType& pts,
141 vtkm::CellShapeTagHexahedron,
151 using Edge =
typename PointCoordVecType::ComponentType;
152 const Edge HexEdges[12] = {
154 pts[2] - pts[1], pts[3] - pts[2],
156 pts[4] - pts[0], pts[5] - pts[1],
158 pts[7] - pts[3], pts[5] - pts[4],
164 Edge principleXAxis = HexEdges[0] + (pts[2] - pts[3]) + HexEdges[8] + (pts[6] - pts[7]);
165 Edge principleYAxis = (pts[3] - pts[0]) + HexEdges[1] + (pts[7] - pts[4]) + HexEdges[9];
166 Edge principleZAxis = HexEdges[4] + HexEdges[5] + HexEdges[6] + HexEdges[7];
167 Edge hexJacobianMatrices[9][3] = {
168 { HexEdges[0], HexEdges[3], HexEdges[4] },
169 { HexEdges[1], (-1 * HexEdges[0]), HexEdges[5] },
170 { HexEdges[2], (-1 * HexEdges[1]), HexEdges[6] },
171 { (-1 * HexEdges[3]), (-1 * HexEdges[2]), HexEdges[7] },
172 { HexEdges[11], HexEdges[8], (-1 * HexEdges[4]) },
173 { (-1 * HexEdges[8]), HexEdges[9], (-1 * HexEdges[5]) },
174 { (-1 * HexEdges[9]), HexEdges[10], (-1 * HexEdges[6]) },
175 { (-1 * HexEdges[10]), (-1 * HexEdges[11]), (-1 * HexEdges[7]) },
176 { principleXAxis, principleYAxis, principleZAxis }
179 OutType third = (OutType)(1.0 / 3.0);
180 OutType negativeInfinity = vtkm::NegativeInfinity<OutType>();
181 OutType tempMatrix1_1, tempMatrix1_2, tempMatrix1_3, tempMatrix2_2, tempMatrix2_3, tempMatrix3_3,
183 OutType firstPartOfNumerator, secondPartOfNumerator, currentOddy, maxOddy = negativeInfinity;
193 tempMatrix1_1 =
static_cast<OutType
>(
194 vtkm::Dot(hexJacobianMatrices[matrixNumber][0], hexJacobianMatrices[matrixNumber][0]));
195 tempMatrix1_2 =
static_cast<OutType
>(
196 vtkm::Dot(hexJacobianMatrices[matrixNumber][0], hexJacobianMatrices[matrixNumber][1]));
197 tempMatrix1_3 =
static_cast<OutType
>(
198 vtkm::Dot(hexJacobianMatrices[matrixNumber][0], hexJacobianMatrices[matrixNumber][2]));
199 tempMatrix2_2 =
static_cast<OutType
>(
200 vtkm::Dot(hexJacobianMatrices[matrixNumber][1], hexJacobianMatrices[matrixNumber][1]));
201 tempMatrix2_3 =
static_cast<OutType
>(
202 vtkm::Dot(hexJacobianMatrices[matrixNumber][1], hexJacobianMatrices[matrixNumber][2]));
203 tempMatrix3_3 =
static_cast<OutType
>(
204 vtkm::Dot(hexJacobianMatrices[matrixNumber][2], hexJacobianMatrices[matrixNumber][2]));
205 determinant =
static_cast<OutType
>(vtkm::Dot(
206 hexJacobianMatrices[matrixNumber][0],
207 vtkm::Cross(hexJacobianMatrices[matrixNumber][1], hexJacobianMatrices[matrixNumber][2])));
208 if (determinant <= OutType(0.0))
210 return vtkm::Infinity<OutType>();
214 firstPartOfNumerator = (tempMatrix1_1 * tempMatrix1_1) + 2 * (tempMatrix1_2 * tempMatrix1_2) +
215 2 * (tempMatrix1_3 * tempMatrix1_3) + (tempMatrix2_2 * tempMatrix2_2) +
216 2 * (tempMatrix2_3 * tempMatrix2_3) + (tempMatrix3_3 * tempMatrix3_3);
217 secondPartOfNumerator = tempMatrix1_1 + tempMatrix2_2 + tempMatrix3_3;
218 secondPartOfNumerator *= secondPartOfNumerator;
219 secondPartOfNumerator *= third;
220 currentOddy = (firstPartOfNumerator - secondPartOfNumerator) /
221 (vtkm::Pow(determinant, OutType(4.0 * third)));
222 maxOddy = currentOddy > maxOddy ? currentOddy : maxOddy;
227 return vtkm::Min(maxOddy, vtkm::Infinity<OutType>());
230 return vtkm::Max(maxOddy, negativeInfinity);
235 #endif // vtk_m_worklet_cellmetrics_Oddy_h