Add CellEdge functions

These provide the general ability to get the edges for each cell type.
This commit is contained in:
Kenneth Moreland 2016-12-01 20:08:18 -07:00
parent 5ab43f8d9e
commit 91f9883599
5 changed files with 468 additions and 116 deletions

@ -21,6 +21,7 @@
set(headers
AtomicArray.h
CellDerivative.h
CellEdge.h
CellFace.h
CellInterpolate.h
ConnectivityExplicit.h

234
vtkm/exec/CellEdge.h Normal file

@ -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 <vtkm/Assert.h>
#include <vtkm/CellShape.h>
#include <vtkm/CellTraits.h>
#include <vtkm/Types.h>
#include <vtkm/internal/Assume.h>
#include <vtkm/exec/FunctorBase.h>
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<typename CellShapeTag>
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<CellShapeTag>::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<typename CellShapeTag>
static inline VTKM_EXEC
vtkm::Vec<vtkm::IdComponent,2>
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<vtkm::IdComponent,2>(0);
}
return vtkm::make_Vec(detail::PointsInEdge[CellShapeTag::Id][edgeIndex][0],
detail::PointsInEdge[CellShapeTag::Id][edgeIndex][1]);
}
static inline VTKM_EXEC
vtkm::Vec<vtkm::IdComponent,2>
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<vtkm::IdComponent,2>(edgeIndex, edgeIndex+1);
}
else
{
return vtkm::Vec<vtkm::IdComponent,2>(edgeIndex, 0);
}
}
static inline VTKM_EXEC
vtkm::Vec<vtkm::IdComponent,2>
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<vtkm::IdComponent,2>(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

@ -22,7 +22,7 @@
set(unit_tests
UnitTestCellDerivative.cxx
UnitTestCellFace.cxx
UnitTestCellEdgeFace.cxx
UnitTestCellInterpolate.cxx
UnitTestParametricCoordinates.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 <vtkm/exec/CellEdge.h>
#include <vtkm/exec/CellFace.h>
#include <vtkm/CellShape.h>
#include <vtkm/CellTraits.h>
#include <vtkm/exec/FunctorBase.h>
#include <vtkm/testing/Testing.h>
#include <set>
namespace {
using EdgeType = vtkm::Vec<vtkm::IdComponent,2>;
void MakeEdgeCononical(EdgeType &edge)
{
if (edge[1] < edge[0])
{
std::swap(edge[0], edge[1]);
}
}
struct TestCellFacesFunctor
{
template<typename CellShapeTag>
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<EdgeType> 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<EdgeType> edgesFoundInFaces;
for (vtkm::IdComponent faceIndex = 0; faceIndex < numFaces; faceIndex++)
{
vtkm::VecCConst<vtkm::IdComponent> 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<typename CellShapeTag>
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<EdgeType> 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<typename CellShapeTag, vtkm::IdComponent NumDimensions>
void DoTest(vtkm::IdComponent numPoints,
CellShapeTag shape,
vtkm::CellTopologicalDimensionsTag<NumDimensions>) 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<typename CellShapeTag>
void TryShapeWithNumPoints(vtkm::IdComponent numPoints,
CellShapeTag) const
{
std::cout << "--- Test shape tag directly"
<< " (" << numPoints << " points)"
<< std::endl;
this->DoTest(
numPoints,
CellShapeTag(),
typename vtkm::CellTraits<CellShapeTag>::TopologicalDimensionsTag());
std::cout << "--- Test generic shape tag"
<< " (" << numPoints << " points)"
<< std::endl;
this->DoTest(
numPoints,
vtkm::CellShapeTagGeneric(CellShapeTag::Id),
typename vtkm::CellTraits<CellShapeTag>::TopologicalDimensionsTag());
}
template<typename CellShapeTag>
void operator()(CellShapeTag) const
{
this->TryShapeWithNumPoints(vtkm::CellTraits<CellShapeTag>::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);
}

@ -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 <vtkm/exec/CellFace.h>
#include <vtkm/CellShape.h>
#include <vtkm/CellTraits.h>
#include <vtkm/exec/FunctorBase.h>
#include <vtkm/testing/Testing.h>
namespace {
struct TestCellFacesFunctor
{
template<typename CellShapeTag>
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<vtkm::IdComponent> 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<typename CellShapeTag, vtkm::IdComponent NumDimensions>
void DoTest(CellShapeTag shape,
vtkm::CellTopologicalDimensionsTag<NumDimensions>) 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<typename CellShapeTag>
void operator()(CellShapeTag) const
{
std::cout << "--- Test shape tag directly" << std::endl;
this->DoTest(
CellShapeTag(),
typename vtkm::CellTraits<CellShapeTag>::TopologicalDimensionsTag());
std::cout << "--- Test generic shape tag" << std::endl;
this->DoTest(
vtkm::CellShapeTagGeneric(CellShapeTag::Id),
typename vtkm::CellTraits<CellShapeTag>::TopologicalDimensionsTag());
}
};
void TestAllShapes()
{
vtkm::testing::Testing::TryAllCellShapes(TestCellFacesFunctor());
}
} // anonymous namespace
int UnitTestCellFace(int, char *[])
{
return vtkm::testing::Testing::Run(TestAllShapes);
}