20 #ifndef vtk_m_worklet_cellmetrics_ScaledJacobian_h
21 #define vtk_m_worklet_cellmetrics_ScaledJacobian_h
43 #define UNUSED(expr) (void)(expr);
57 template <
typename OutType,
typename Po
intCoordVecType,
typename CellShapeType>
59 const PointCoordVecType& pts,
79 template <
typename OutType,
typename Po
intCoordVecType>
81 const PointCoordVecType& pts,
82 vtkm::CellShapeTagTriangle,
90 using Scalar = OutType;
91 using CollectionOfPoints = PointCoordVecType;
92 using Vector =
typename PointCoordVecType::ComponentType;
94 const Vector l0 = GetTriangleL0<Scalar, Vector, CollectionOfPoints>(pts);
95 const Vector l1 = GetTriangleL1<Scalar, Vector, CollectionOfPoints>(pts);
96 const Vector l2 = GetTriangleL2<Scalar, Vector, CollectionOfPoints>(pts);
98 const Scalar modifier = (Scalar)(2 *
vtkm::Sqrt(3) / 3);
99 const Scalar l0_magnitude = GetTriangleL0Magnitude<Scalar, Vector, CollectionOfPoints>(pts);
100 const Scalar l1_magnitude = GetTriangleL1Magnitude<Scalar, Vector, CollectionOfPoints>(pts);
101 const Scalar l2_magnitude = GetTriangleL2Magnitude<Scalar, Vector, CollectionOfPoints>(pts);
102 const Scalar l0l1_product = l0_magnitude * l1_magnitude;
103 const Scalar l0l2_product = l0_magnitude * l2_magnitude;
104 const Scalar l1l2_product = l1_magnitude * l2_magnitude;
105 const Scalar productMax = vtkm::Max(l0l1_product, vtkm::Max(l0l2_product, l1l2_product));
106 if (productMax <= Scalar(0.0))
112 Scalar scaledJacobian =
static_cast<OutType
>(
vtkm::Magnitude(TriCross));
116 Vector normalVector = (Scalar(1.0) / Scalar(3.0)) * (l0 + l1 + l2);
118 if (vtkm::Dot(surfaceNormalAtCenter, TriCross) < 0)
120 scaledJacobian *= -1;
122 scaledJacobian *= modifier;
123 const Scalar q = scaledJacobian / productMax;
136 template <
typename OutType,
typename Po
intCoordVecType>
138 const PointCoordVecType& pts,
139 vtkm::CellShapeTagQuad,
147 using Scalar = OutType;
148 using CollectionOfPoints = PointCoordVecType;
149 using Vector =
typename PointCoordVecType::ComponentType;
151 const Scalar l0_magnitude = GetQuadL0Magnitude<Scalar, Vector, CollectionOfPoints>(pts);
152 const Scalar l1_magnitude = GetQuadL1Magnitude<Scalar, Vector, CollectionOfPoints>(pts);
153 const Scalar l2_magnitude = GetQuadL2Magnitude<Scalar, Vector, CollectionOfPoints>(pts);
154 const Scalar l3_magnitude = GetQuadL3Magnitude<Scalar, Vector, CollectionOfPoints>(pts);
155 const Scalar negativeInfinity = vtkm::NegativeInfinity<Scalar>();
157 if (l0_magnitude < negativeInfinity || l1_magnitude < negativeInfinity ||
158 l2_magnitude < negativeInfinity || l3_magnitude < negativeInfinity)
162 const Scalar l0l3_product = l0_magnitude * l3_magnitude;
163 const Scalar l1l0_product = l1_magnitude * l0_magnitude;
164 const Scalar l2l1_product = l2_magnitude * l1_magnitude;
165 const Scalar l3l2_product = l3_magnitude * l2_magnitude;
174 Scalar alpha0Scaled = GetQuadAlpha0<Scalar, Vector, CollectionOfPoints>(pts);
175 Scalar alpha1Scaled = GetQuadAlpha1<Scalar, Vector, CollectionOfPoints>(pts);
176 Scalar alpha2Scaled = GetQuadAlpha2<Scalar, Vector, CollectionOfPoints>(pts);
177 Scalar alpha3Scaled = GetQuadAlpha3<Scalar, Vector, CollectionOfPoints>(pts);
179 alpha0Scaled /= l0l3_product;
180 alpha1Scaled /= l1l0_product;
181 alpha2Scaled /= l2l1_product;
182 alpha3Scaled /= l3l2_product;
184 vtkm::Min(alpha0Scaled, vtkm::Min(alpha1Scaled, vtkm::Min(alpha2Scaled, alpha3Scaled)));
196 template <
typename OutType,
typename Po
intCoordVecType>
198 const PointCoordVecType& pts,
199 vtkm::CellShapeTagHexahedron,
209 using Edge =
typename PointCoordVecType::ComponentType;
210 Edge HexEdges[12] = { pts[1] - pts[0], pts[2] - pts[1], pts[3] - pts[2], pts[3] - pts[0],
211 pts[4] - pts[0], pts[5] - pts[1], pts[6] - pts[2], pts[7] - pts[3],
212 pts[5] - pts[4], pts[6] - pts[5], pts[7] - pts[6], pts[7] - pts[4] };
213 Edge principleXAxis = HexEdges[0] + (pts[2] - pts[3]) + HexEdges[8] + (pts[6] - pts[7]);
214 Edge principleYAxis = (pts[3] - pts[0]) + HexEdges[1] + (pts[7] - pts[4]) + HexEdges[9];
215 Edge principleZAxis = HexEdges[4] + HexEdges[5] + HexEdges[6] + HexEdges[7];
216 Edge hexMatrices[9][3] = { { HexEdges[0], HexEdges[3], HexEdges[4] },
217 { HexEdges[1], (-1 * HexEdges[0]), HexEdges[5] },
218 { HexEdges[2], (-1 * HexEdges[1]), HexEdges[6] },
219 { (-1 * HexEdges[3]), (-1 * HexEdges[2]), HexEdges[7] },
220 { HexEdges[11], HexEdges[8], (-1 * HexEdges[4]) },
221 { (-1 * HexEdges[8]), HexEdges[9], (-1 * HexEdges[5]) },
222 { (-1 * HexEdges[9]), HexEdges[10], (-1 * HexEdges[6]) },
223 { (-1 * HexEdges[10]), (-1 * HexEdges[11]), (-1 * HexEdges[7]) },
224 { principleXAxis, principleYAxis, principleZAxis } };
225 OutType currDeterminant, minDeterminant = vtkm::Infinity<OutType>();
226 FloatType lenSquared1, lenSquared2, lenSquared3, minLengthSquared = vtkm::Infinity<FloatType>();
228 for (matrixIndex = 0; matrixIndex < 9; matrixIndex++)
231 minLengthSquared = lenSquared1 < minLengthSquared ? lenSquared1 : minLengthSquared;
233 minLengthSquared = lenSquared2 < minLengthSquared ? lenSquared2 : minLengthSquared;
235 minLengthSquared = lenSquared3 < minLengthSquared ? lenSquared3 : minLengthSquared;
241 (OutType)vtkm::Dot(hexMatrices[matrixIndex][0],
242 vtkm::Cross(hexMatrices[matrixIndex][1], hexMatrices[matrixIndex][2]));
243 if (currDeterminant < minDeterminant)
245 minDeterminant = currDeterminant;
248 if (minLengthSquared < vtkm::NegativeInfinity<FloatType>())
250 return vtkm::Infinity<OutType>();
252 OutType toReturn = minDeterminant;
254 return vtkm::Min(toReturn, vtkm::Infinity<OutType>());
256 return vtkm::Max(toReturn, vtkm::NegativeInfinity<OutType>());
267 template <
typename OutType,
typename Po
intCoordVecType>
269 const PointCoordVecType& pts,
270 vtkm::CellShapeTagTetra,
280 using Edge =
typename PointCoordVecType::ComponentType;
281 Edge Edges[6] = { pts[1] - pts[0], pts[2] - pts[1], pts[0] - pts[2],
282 pts[3] - pts[0], pts[3] - pts[1], pts[3] - pts[2] };
283 OutType EdgesSquared[6];
284 OutType jacobian =
static_cast<OutType
>(vtkm::Dot(
vtkm::Cross(Edges[2], Edges[0]), Edges[3]));
286 OutType currSide, maxSide = vtkm::NegativeInfinity<OutType>();
288 for (edgeIndex = 0; edgeIndex < 6; edgeIndex++)
292 OutType Sides[4] = { EdgesSquared[0] * EdgesSquared[2] * EdgesSquared[3],
293 EdgesSquared[0] * EdgesSquared[1] * EdgesSquared[4],
294 EdgesSquared[1] * EdgesSquared[2] * EdgesSquared[5],
295 EdgesSquared[3] * EdgesSquared[4] * EdgesSquared[5] };
296 for (sideIndex = 0; sideIndex < 4; sideIndex++)
298 currSide = Sides[sideIndex];
299 maxSide = currSide > maxSide ? currSide : maxSide;
302 OutType toUseInCalculation = jacobian > maxSide ? jacobian : maxSide;
303 if (toUseInCalculation < vtkm::NegativeInfinity<OutType>())
305 return vtkm::Infinity<OutType>();
307 return (vtkm::Sqrt<OutType>(2) * jacobian) / toUseInCalculation;
312 #endif // vtk_m_worklet_cellmetrics_ScaledJacobian_h