diff --git a/vtkm/exec/CMakeLists.txt b/vtkm/exec/CMakeLists.txt index 8f4dae3e6..c5d9908c0 100644 --- a/vtkm/exec/CMakeLists.txt +++ b/vtkm/exec/CMakeLists.txt @@ -21,6 +21,7 @@ set(headers AtomicArray.h CellDerivative.h + CellEdge.h CellFace.h CellInterpolate.h ConnectivityExplicit.h diff --git a/vtkm/exec/CellEdge.h b/vtkm/exec/CellEdge.h new file mode 100644 index 000000000..d2db2c85d --- /dev/null +++ b/vtkm/exec/CellEdge.h @@ -0,0 +1,234 @@ +//============================================================================ +// Copyright (c) Kitware, Inc. +// All rights reserved. +// See LICENSE.txt for details. +// This software is distributed WITHOUT ANY WARRANTY; without even +// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +// PURPOSE. See the above copyright notice for more information. +// +// Copyright 2016 Sandia Corporation. +// Copyright 2016 UT-Battelle, LLC. +// Copyright 2016 Los Alamos National Security. +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// the U.S. Government retains certain rights in this software. +// +// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National +// Laboratory (LANL), the U.S. Government retains certain rights in +// this software. +//============================================================================ +#ifndef vtk_m_exec_CellFaces_h +#define vtk_m_exec_CellFaces_h + +#include +#include +#include +#include +#include +#include + +namespace vtkm { +namespace exec { + +namespace detail { + +static const vtkm::IdComponent MAX_NUM_EDGES = 12; + +VTKM_EXEC_CONSTANT +static const vtkm::IdComponent NumEdges[vtkm::NUMBER_OF_CELL_SHAPES] = { + 0, // 0: CELL_SHAPE_EMPTY + 0, // 1: CELL_SHAPE_VERTEX + 0, // 2: Unused + 0, // 3: CELL_SHAPE_LINE + 0, // 4: Unused + 3, // 5: CELL_SHAPE_TRIANGLE + 0, // 6: Unused + -1, // 7: CELL_SHAPE_POLYGON ---special case--- + 0, // 8: Unused + 4, // 9: CELL_SHAPE_QUAD + 6, // 10: CELL_SHAPE_TETRA + 0, // 11: Unused + 12, // 12: CELL_SHAPE_HEXAHEDRON + 9, // 13: CELL_SHAPE_WEDGE + 8 // 14: CELL_SHAPE_PYRAMID +}; + +VTKM_EXEC_CONSTANT +static const vtkm::IdComponent +PointsInEdge[vtkm::NUMBER_OF_CELL_SHAPES][MAX_NUM_EDGES][2] = { + // 0: CELL_SHAPE_EMPTY + { { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, + { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 } + }, + // 1: CELL_SHAPE_VERTEX + { { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, + { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 } + }, + // 2: Unused + { { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, + { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 } + }, + // 3: CELL_SHAPE_LINE + { { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, + { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 } + }, + // 4: Unused + { { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, + { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 } + }, + // 5: CELL_SHAPE_TRIANGLE + { { 0, 1 }, { 1, 2 }, { 2, 0 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, + { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 } + }, + // 6: Unused + { { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, + { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 } + }, + // 7: CELL_SHAPE_POLYGON --- special case --- + { { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, + { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 } + }, + // 8: Unused + { { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, + { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 } + }, + // 9: CELL_SHAPE_QUAD + { { 0, 1 }, { 1, 2 }, { 2, 3 }, { 3, 0 }, { -1, -1 }, { -1, -1 }, + { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 } + }, + // 10: CELL_SHAPE_TETRA + { { 0, 1 }, { 1, 2 }, { 2, 0 }, { 0, 3 }, { 1, 3 }, { 2, 3 }, + { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 } + }, + // 11: Unused + { { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, + { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 } + }, + // 12: CELL_SHAPE_HEXAHEDRON + { { 0, 1 }, { 1, 2 }, { 3, 2 }, { 0, 3 }, { 4, 5 }, { 5, 6 }, + { 7, 6 }, { 4, 7 }, { 0, 4 }, { 1, 5 }, { 3, 7 }, { 2, 6 } + }, + // 13: CELL_SHAPE_WEDGE + { { 0, 1 }, { 1, 2 }, { 2, 0 }, { 3, 4 }, { 4, 5 }, { 5, 3 }, + { 0, 3 }, { 1, 4 }, { 2, 5 }, { -1, -1 }, { -1, -1 }, { -1, -1 } + }, + // 14: CELL_SHAPE_PYRAMID + { { 0, 1 }, { 1, 2 }, { 2, 3 }, { 3, 0 }, { 0, 4 }, { 1, 4 }, + { 2, 4 }, { 3, 4 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 } + }, +}; + +} // namespace detail + +template +static inline VTKM_EXEC +vtkm::IdComponent +CellEdgeNumberOfEdges(vtkm::IdComponent numPoints, + CellShapeTag, + const vtkm::exec::FunctorBase &) +{ + (void)numPoints; // Silence compiler warnings. + VTKM_ASSERT(numPoints == vtkm::CellTraits::NUM_POINTS); + return detail::NumEdges[CellShapeTag::Id]; +} + +static inline VTKM_EXEC +vtkm::IdComponent +CellEdgeNumberOfEdges(vtkm::IdComponent numPoints, + vtkm::CellShapeTagPolygon, + const vtkm::exec::FunctorBase &) +{ + VTKM_ASSUME(numPoints > 0); + return numPoints; +} + +static inline VTKM_EXEC +vtkm::IdComponent +CellEdgeNumberOfEdges(vtkm::IdComponent numPoints, + vtkm::CellShapeTagGeneric shape, + const vtkm::exec::FunctorBase &worklet) +{ + if (shape.Id == vtkm::CELL_SHAPE_POLYGON) + { + return CellEdgeNumberOfEdges( + numPoints, vtkm::CellShapeTagPolygon(), worklet); + } + else + { + return detail::NumEdges[shape.Id]; + } +} + +template +static inline VTKM_EXEC +vtkm::Vec +CellEdgeLocalIndices(vtkm::IdComponent numPoints, + vtkm::IdComponent edgeIndex, + CellShapeTag shape, + const vtkm::exec::FunctorBase &worklet) +{ + VTKM_ASSUME(edgeIndex >= 0); + VTKM_ASSUME(edgeIndex < detail::MAX_NUM_EDGES); + if (edgeIndex >= vtkm::exec::CellEdgeNumberOfEdges(numPoints, shape, worklet)) + { + worklet.RaiseError("Invalid edge number."); + return vtkm::Vec(0); + } + + return vtkm::make_Vec(detail::PointsInEdge[CellShapeTag::Id][edgeIndex][0], + detail::PointsInEdge[CellShapeTag::Id][edgeIndex][1]); +} + +static inline VTKM_EXEC +vtkm::Vec +CellEdgeLocalIndices(vtkm::IdComponent numPoints, + vtkm::IdComponent edgeIndex, + vtkm::CellShapeTagPolygon, + const vtkm::exec::FunctorBase &) +{ + VTKM_ASSUME(numPoints >= 3); + VTKM_ASSUME(edgeIndex >= 0); + VTKM_ASSUME(edgeIndex < numPoints); + + if (edgeIndex < numPoints-1) + { + return vtkm::Vec(edgeIndex, edgeIndex+1); + } + else + { + return vtkm::Vec(edgeIndex, 0); + } +} + +static inline VTKM_EXEC +vtkm::Vec +CellEdgeLocalIndices(vtkm::IdComponent numPoints, + vtkm::IdComponent edgeIndex, + vtkm::CellShapeTagGeneric shape, + const vtkm::exec::FunctorBase &worklet) +{ + VTKM_ASSUME(edgeIndex >= 0); + VTKM_ASSUME(edgeIndex < detail::MAX_NUM_EDGES); + + if (shape.Id == vtkm::CELL_SHAPE_POLYGON) + { + return CellEdgeLocalIndices( + numPoints, edgeIndex, vtkm::CellShapeTagPolygon(), worklet); + } + else + { + if (edgeIndex >= detail::NumEdges[shape.Id]) + { + worklet.RaiseError("Invalid edge number."); + return vtkm::Vec(0); + } + + return vtkm::make_Vec(detail::PointsInEdge[shape.Id][edgeIndex][0], + detail::PointsInEdge[shape.Id][edgeIndex][1]); + } +} + +} +} // namespace vtkm::exec + +#endif //vtk_m_exec_CellFaces_h diff --git a/vtkm/exec/testing/CMakeLists.txt b/vtkm/exec/testing/CMakeLists.txt index bda73a006..fb71f0bb6 100644 --- a/vtkm/exec/testing/CMakeLists.txt +++ b/vtkm/exec/testing/CMakeLists.txt @@ -22,7 +22,7 @@ set(unit_tests UnitTestCellDerivative.cxx - UnitTestCellFace.cxx + UnitTestCellEdgeFace.cxx UnitTestCellInterpolate.cxx UnitTestParametricCoordinates.cxx ) diff --git a/vtkm/exec/testing/UnitTestCellEdgeFace.cxx b/vtkm/exec/testing/UnitTestCellEdgeFace.cxx new file mode 100644 index 000000000..1e33c80b8 --- /dev/null +++ b/vtkm/exec/testing/UnitTestCellEdgeFace.cxx @@ -0,0 +1,232 @@ +//============================================================================ +// Copyright (c) Kitware, Inc. +// All rights reserved. +// See LICENSE.txt for details. +// This software is distributed WITHOUT ANY WARRANTY; without even +// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +// PURPOSE. See the above copyright notice for more information. +// +// Copyright 2016 Sandia Corporation. +// Copyright 2016 UT-Battelle, LLC. +// Copyright 2016 Los Alamos National Security. +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// the U.S. Government retains certain rights in this software. +// +// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National +// Laboratory (LANL), the U.S. Government retains certain rights in +// this software. +//============================================================================ + +#include +#include + +#include +#include + +#include + +#include + +#include + +namespace { + +using EdgeType = vtkm::Vec; + +void MakeEdgeCononical(EdgeType &edge) +{ + if (edge[1] < edge[0]) + { + std::swap(edge[0], edge[1]); + } +} + +struct TestCellFacesFunctor +{ + template + void DoTest(vtkm::IdComponent numPoints, + CellShapeTag shape, + vtkm::CellTopologicalDimensionsTag<3>) const + { + // Stuff to fake running in the execution environment. + char messageBuffer[256]; + messageBuffer[0] = '\0'; + vtkm::exec::internal::ErrorMessageBuffer errorMessage(messageBuffer, 256); + vtkm::exec::FunctorBase workletProxy; + workletProxy.SetErrorMessageBuffer(errorMessage); + + vtkm::IdComponent numEdges = + vtkm::exec::CellEdgeNumberOfEdges(numPoints, shape, workletProxy); + VTKM_TEST_ASSERT(numEdges > 0, "No edges?"); + + std::set edgeSet; + for (vtkm::IdComponent edgeIndex = 0; edgeIndex < numEdges; edgeIndex++) + { + EdgeType edge = vtkm::exec::CellEdgeLocalIndices( + numPoints, edgeIndex, shape, workletProxy); + VTKM_TEST_ASSERT(edge[0] >= 0, "Bad index in edge."); + VTKM_TEST_ASSERT(edge[0] < numPoints, "Bad index in edge."); + VTKM_TEST_ASSERT(edge[1] >= 0, "Bad index in edge."); + VTKM_TEST_ASSERT(edge[1] < numPoints, "Bad index in edge."); + VTKM_TEST_ASSERT(edge[0] != edge[1], "Degenerate edge."); + MakeEdgeCononical(edge); + VTKM_TEST_ASSERT(edge[0] < edge[1], + "Internal test error: MakeEdgeCononical failed"); + VTKM_TEST_ASSERT(edgeSet.find(edge) == edgeSet.end(), + "Found duplicate edge"); + edgeSet.insert(edge); + } + + vtkm::IdComponent numFaces = + vtkm::exec::CellFaceNumberOfFaces(shape, workletProxy); + VTKM_TEST_ASSERT(numFaces > 0, "No faces?"); + + std::set edgesFoundInFaces; + for (vtkm::IdComponent faceIndex = 0; faceIndex < numFaces; faceIndex++) + { + vtkm::VecCConst facePoints = + vtkm::exec::CellFaceLocalIndices(faceIndex, shape, workletProxy); + vtkm::IdComponent numPointsInFace = facePoints.GetNumberOfComponents(); + VTKM_TEST_ASSERT(numPointsInFace >= 3, + "Face has fewer points than a triangle."); + + for (vtkm::IdComponent pointIndex = 0; + pointIndex < numPointsInFace; + pointIndex++) + { + VTKM_TEST_ASSERT(facePoints[pointIndex] >= 0, + "Invalid point index for face."); + VTKM_TEST_ASSERT(facePoints[pointIndex] <= numPoints, + "Invalid point index for face."); + EdgeType edge; + if (pointIndex < numPointsInFace-1) + { + edge = EdgeType(facePoints[pointIndex], facePoints[pointIndex+1]); + } + else + { + edge = EdgeType(facePoints[0], facePoints[pointIndex]); + } + MakeEdgeCononical(edge); + VTKM_TEST_ASSERT(edgeSet.find(edge) != edgeSet.end(), + "Edge in face not in cell's edges"); + edgesFoundInFaces.insert(edge); + } + } + VTKM_TEST_ASSERT(edgesFoundInFaces.size() == edgeSet.size(), + "Faces did not contain all edges in cell"); + } + + // Case of cells that have 2 dimensions (no faces) + template + void DoTest(vtkm::IdComponent numPoints, + CellShapeTag shape, + vtkm::CellTopologicalDimensionsTag<2>) const + { + // Stuff to fake running in the execution environment. + char messageBuffer[256]; + messageBuffer[0] = '\0'; + vtkm::exec::internal::ErrorMessageBuffer errorMessage(messageBuffer, 256); + vtkm::exec::FunctorBase workletProxy; + workletProxy.SetErrorMessageBuffer(errorMessage); + + vtkm::IdComponent numEdges = + vtkm::exec::CellEdgeNumberOfEdges(numPoints, shape, workletProxy); + VTKM_TEST_ASSERT(numEdges == numPoints, + "Polygons should have same number of points and edges"); + + std::set edgeSet; + for (vtkm::IdComponent edgeIndex = 0; edgeIndex < numEdges; edgeIndex++) + { + EdgeType edge = vtkm::exec::CellEdgeLocalIndices( + numPoints, edgeIndex, shape, workletProxy); + VTKM_TEST_ASSERT(edge[0] >= 0, "Bad index in edge."); + VTKM_TEST_ASSERT(edge[0] < numPoints, "Bad index in edge."); + VTKM_TEST_ASSERT(edge[1] >= 0, "Bad index in edge."); + VTKM_TEST_ASSERT(edge[1] < numPoints, "Bad index in edge."); + VTKM_TEST_ASSERT(edge[0] != edge[1], "Degenerate edge."); + MakeEdgeCononical(edge); + VTKM_TEST_ASSERT(edge[0] < edge[1], + "Internal test error: MakeEdgeCononical failed"); + VTKM_TEST_ASSERT(edgeSet.find(edge) == edgeSet.end(), + "Found duplicate edge"); + edgeSet.insert(edge); + } + + vtkm::IdComponent numFaces = + vtkm::exec::CellFaceNumberOfFaces(shape, workletProxy); + VTKM_TEST_ASSERT(numFaces == 0, "Non 3D shape should have no faces"); + } + + // Less important case of cells that have less than 2 dimensions + // (no faces or edges) + template + void DoTest(vtkm::IdComponent numPoints, + CellShapeTag shape, + vtkm::CellTopologicalDimensionsTag) const + { + // Stuff to fake running in the execution environment. + char messageBuffer[256]; + messageBuffer[0] = '\0'; + vtkm::exec::internal::ErrorMessageBuffer errorMessage(messageBuffer, 256); + vtkm::exec::FunctorBase workletProxy; + workletProxy.SetErrorMessageBuffer(errorMessage); + + vtkm::IdComponent numEdges = + vtkm::exec::CellEdgeNumberOfEdges(numPoints, shape, workletProxy); + VTKM_TEST_ASSERT(numEdges == 0, "0D or 1D shape should have no edges"); + + vtkm::IdComponent numFaces = + vtkm::exec::CellFaceNumberOfFaces(shape, workletProxy); + VTKM_TEST_ASSERT(numFaces == 0, "Non 3D shape should have no faces"); + } + + template + void TryShapeWithNumPoints(vtkm::IdComponent numPoints, + CellShapeTag) const + { + std::cout << "--- Test shape tag directly" + << " (" << numPoints << " points)" + << std::endl; + this->DoTest( + numPoints, + CellShapeTag(), + typename vtkm::CellTraits::TopologicalDimensionsTag()); + + std::cout << "--- Test generic shape tag" + << " (" << numPoints << " points)" + << std::endl; + this->DoTest( + numPoints, + vtkm::CellShapeTagGeneric(CellShapeTag::Id), + typename vtkm::CellTraits::TopologicalDimensionsTag()); + } + + template + void operator()(CellShapeTag) const + { + this->TryShapeWithNumPoints(vtkm::CellTraits::NUM_POINTS, + CellShapeTag()); + } + + void operator()(vtkm::CellShapeTagPolygon) const + { + for (vtkm::IdComponent numPoints = 3; numPoints < 7; numPoints++) + { + this->TryShapeWithNumPoints(numPoints,vtkm::CellShapeTagPolygon()); + } + } +}; + +void TestAllShapes() +{ + vtkm::testing::Testing::TryAllCellShapes(TestCellFacesFunctor()); +} + +} // anonymous namespace + +int UnitTestCellEdgeFace(int, char *[]) +{ + return vtkm::testing::Testing::Run(TestAllShapes); +} diff --git a/vtkm/exec/testing/UnitTestCellFace.cxx b/vtkm/exec/testing/UnitTestCellFace.cxx deleted file mode 100644 index 1f779c4ce..000000000 --- a/vtkm/exec/testing/UnitTestCellFace.cxx +++ /dev/null @@ -1,115 +0,0 @@ -//============================================================================ -// Copyright (c) Kitware, Inc. -// All rights reserved. -// See LICENSE.txt for details. -// This software is distributed WITHOUT ANY WARRANTY; without even -// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR -// PURPOSE. See the above copyright notice for more information. -// -// Copyright 2016 Sandia Corporation. -// Copyright 2016 UT-Battelle, LLC. -// Copyright 2016 Los Alamos National Security. -// -// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, -// the U.S. Government retains certain rights in this software. -// -// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National -// Laboratory (LANL), the U.S. Government retains certain rights in -// this software. -//============================================================================ - -#include - -#include -#include - -#include - -#include - -namespace { - -struct TestCellFacesFunctor -{ - template - void DoTest(CellShapeTag shape, - vtkm::CellTopologicalDimensionsTag<3>) const - { - // Stuff to fake running in the execution environment. - char messageBuffer[256]; - messageBuffer[0] = '\0'; - vtkm::exec::internal::ErrorMessageBuffer errorMessage(messageBuffer, 256); - vtkm::exec::FunctorBase workletProxy; - workletProxy.SetErrorMessageBuffer(errorMessage); - - vtkm::IdComponent numFaces = - vtkm::exec::CellFaceNumberOfFaces(shape, workletProxy); - VTKM_TEST_ASSERT(numFaces > 0, "No faces?"); - - for (vtkm::IdComponent faceIndex = 0; faceIndex < numFaces; faceIndex++) - { - vtkm::VecCConst facePoints = - vtkm::exec::CellFaceLocalIndices(faceIndex, shape, workletProxy); - vtkm::IdComponent numPointsInFace = facePoints.GetNumberOfComponents(); - VTKM_TEST_ASSERT(numPointsInFace >= 3, - "Face has fewer points than a triangle."); - // Currently no face has more than 5 points - VTKM_TEST_ASSERT(numPointsInFace <= 5, - "Face has too many points."); - - for (vtkm::IdComponent pointIndex = 0; - pointIndex < numPointsInFace; - pointIndex++) - { - VTKM_TEST_ASSERT(facePoints[pointIndex] >= 0, - "Invalid point index for face."); - // Currently no cell has more than 10 points - VTKM_TEST_ASSERT(facePoints[pointIndex] <= 10, - "Invalid point index for face."); - } - } - } - - // Less important case of cells that have less than 3 dimensions (no faces) - template - void DoTest(CellShapeTag shape, - vtkm::CellTopologicalDimensionsTag) const - { - // Stuff to fake running in the execution environment. - char messageBuffer[256]; - messageBuffer[0] = '\0'; - vtkm::exec::internal::ErrorMessageBuffer errorMessage(messageBuffer, 256); - vtkm::exec::FunctorBase workletProxy; - workletProxy.SetErrorMessageBuffer(errorMessage); - - vtkm::IdComponent numFaces = - vtkm::exec::CellFaceNumberOfFaces(shape, workletProxy); - VTKM_TEST_ASSERT(numFaces == 0, "Non 3D shape should have no faces"); - } - - template - void operator()(CellShapeTag) const - { - std::cout << "--- Test shape tag directly" << std::endl; - this->DoTest( - CellShapeTag(), - typename vtkm::CellTraits::TopologicalDimensionsTag()); - - std::cout << "--- Test generic shape tag" << std::endl; - this->DoTest( - vtkm::CellShapeTagGeneric(CellShapeTag::Id), - typename vtkm::CellTraits::TopologicalDimensionsTag()); - } -}; - -void TestAllShapes() -{ - vtkm::testing::Testing::TryAllCellShapes(TestCellFacesFunctor()); -} - -} // anonymous namespace - -int UnitTestCellFace(int, char *[]) -{ - return vtkm::testing::Testing::Run(TestAllShapes); -}