VTK-m  2.1
CellSetSingleType.h
Go to the documentation of this file.
1 //============================================================================
2 // Copyright (c) Kitware, Inc.
3 // All rights reserved.
4 // See LICENSE.txt for details.
5 //
6 // This software is distributed WITHOUT ANY WARRANTY; without even
7 // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
8 // PURPOSE. See the above copyright notice for more information.
9 //============================================================================
10 #ifndef vtk_m_cont_CellSetSingleType_h
11 #define vtk_m_cont_CellSetSingleType_h
12 
13 #include <vtkm/CellShape.h>
14 #include <vtkm/CellTraits.h>
17 #include <vtkm/cont/CellSet.h>
19 
20 #include <map>
21 #include <utility>
22 
23 namespace vtkm
24 {
25 namespace cont
26 {
27 
39 template <typename ConnectivityStorageTag = VTKM_DEFAULT_CONNECTIVITY_STORAGE_TAG>
40 class VTKM_ALWAYS_EXPORT CellSetSingleType
42  typename vtkm::cont::ArrayHandleConstant<vtkm::UInt8>::StorageTag, //ShapesStorageTag
43  ConnectivityStorageTag,
44  typename vtkm::cont::ArrayHandleCounting<vtkm::Id>::StorageTag //OffsetsStorageTag
45  >
46 {
48  using Superclass =
50  ConnectivityStorageTag,
52 
53 public:
54  VTKM_CONT
56  : Superclass()
57  , ExpectedNumberOfCellsAdded(-1)
58  , CellShapeAsId(CellShapeTagEmpty::Id)
59  , NumberOfPointsPerCell(0)
60  {
61  }
62 
63  VTKM_CONT
65  : Superclass(src)
66  , ExpectedNumberOfCellsAdded(-1)
67  , CellShapeAsId(src.CellShapeAsId)
68  , NumberOfPointsPerCell(src.NumberOfPointsPerCell)
69  {
70  }
71 
72  VTKM_CONT
73  CellSetSingleType(Thisclass&& src) noexcept
74  : Superclass(std::forward<Superclass>(src))
75  , ExpectedNumberOfCellsAdded(-1)
76  , CellShapeAsId(src.CellShapeAsId)
77  , NumberOfPointsPerCell(src.NumberOfPointsPerCell)
78  {
79  }
80 
81 
82  VTKM_CONT
84  {
85  this->Superclass::operator=(src);
86  this->CellShapeAsId = src.CellShapeAsId;
87  this->NumberOfPointsPerCell = src.NumberOfPointsPerCell;
88  return *this;
89  }
90 
91  VTKM_CONT
92  Thisclass& operator=(Thisclass&& src) noexcept
93  {
94  this->Superclass::operator=(std::forward<Superclass>(src));
95  this->CellShapeAsId = src.CellShapeAsId;
96  this->NumberOfPointsPerCell = src.NumberOfPointsPerCell;
97  return *this;
98  }
99 
100  ~CellSetSingleType() override {}
101 
106  VTKM_CONT void PrepareToAddCells(vtkm::Id numCells, vtkm::Id connectivityMaxLen)
107  {
108  this->CellShapeAsId = vtkm::CELL_SHAPE_EMPTY;
109 
110  this->Data->CellPointIds.Connectivity.Allocate(connectivityMaxLen);
111 
112  this->Data->NumberOfCellsAdded = 0;
113  this->Data->ConnectivityAdded = 0;
114  this->ExpectedNumberOfCellsAdded = numCells;
115  }
116 
120  template <typename IdVecType>
121  VTKM_CONT void AddCell(vtkm::UInt8 shapeId, vtkm::IdComponent numVertices, const IdVecType& ids)
122  {
123  using Traits = vtkm::VecTraits<IdVecType>;
124  VTKM_STATIC_ASSERT_MSG((std::is_same<typename Traits::ComponentType, vtkm::Id>::value),
125  "CellSetSingleType::AddCell requires vtkm::Id for indices.");
126 
127  if (Traits::GetNumberOfComponents(ids) < numVertices)
128  {
129  throw vtkm::cont::ErrorBadValue("Not enough indices given to CellSetSingleType::AddCell.");
130  }
131 
132  if (this->Data->ConnectivityAdded + numVertices >
133  this->Data->CellPointIds.Connectivity.GetNumberOfValues())
134  {
136  "Connectivity increased past estimated maximum connectivity.");
137  }
138 
139  if (this->CellShapeAsId == vtkm::CELL_SHAPE_EMPTY)
140  {
141  if (shapeId == vtkm::CELL_SHAPE_EMPTY)
142  {
143  throw vtkm::cont::ErrorBadValue("Cannot create cells of type empty.");
144  }
145  this->CellShapeAsId = shapeId;
146  this->CheckNumberOfPointsPerCell(numVertices);
147  this->NumberOfPointsPerCell = numVertices;
148  }
149  else
150  {
151  if (shapeId != this->GetCellShape(0))
152  {
153  throw vtkm::cont::ErrorBadValue("Cannot have differing shapes in CellSetSingleType.");
154  }
155  if (numVertices != this->NumberOfPointsPerCell)
156  {
158  "Inconsistent number of points in cells for CellSetSingleType.");
159  }
160  }
161  auto conn = this->Data->CellPointIds.Connectivity.WritePortal();
162  for (vtkm::IdComponent iVert = 0; iVert < numVertices; ++iVert)
163  {
164  conn.Set(this->Data->ConnectivityAdded + iVert, Traits::GetComponent(ids, iVert));
165  }
166  this->Data->NumberOfCellsAdded++;
167  this->Data->ConnectivityAdded += numVertices;
168  }
169 
172  {
173  this->Data->NumberOfPoints = numPoints;
174  this->Data->CellPointIds.Connectivity.Allocate(this->Data->ConnectivityAdded,
176 
177  vtkm::Id numCells = this->Data->NumberOfCellsAdded;
178 
179  this->Data->CellPointIds.Shapes =
180  vtkm::cont::make_ArrayHandleConstant(this->GetCellShape(0), numCells);
181  this->Data->CellPointIds.Offsets = vtkm::cont::make_ArrayHandleCounting(
182  vtkm::Id(0), static_cast<vtkm::Id>(this->NumberOfPointsPerCell), numCells);
183 
184  this->Data->CellPointIds.ElementsValid = true;
185 
186  if (this->ExpectedNumberOfCellsAdded != this->GetNumberOfCells())
187  {
188  throw vtkm::cont::ErrorBadValue("Did not add the expected number of cells.");
189  }
190 
191  this->Data->NumberOfCellsAdded = -1;
192  this->Data->ConnectivityAdded = -1;
193  this->ExpectedNumberOfCellsAdded = -1;
194  }
195 
200  VTKM_CONT void Fill(vtkm::Id numPoints,
201  vtkm::UInt8 shapeId,
202  vtkm::IdComponent numberOfPointsPerCell,
204  {
205  this->Data->NumberOfPoints = numPoints;
206  this->CellShapeAsId = shapeId;
207  this->CheckNumberOfPointsPerCell(numberOfPointsPerCell);
208 
209  const vtkm::Id numCells = connectivity.GetNumberOfValues() / numberOfPointsPerCell;
210  VTKM_ASSERT((connectivity.GetNumberOfValues() % numberOfPointsPerCell) == 0);
211 
212  this->Data->CellPointIds.Shapes = vtkm::cont::make_ArrayHandleConstant(shapeId, numCells);
213 
214  this->Data->CellPointIds.Offsets = vtkm::cont::make_ArrayHandleCounting(
215  vtkm::Id(0), static_cast<vtkm::Id>(numberOfPointsPerCell), numCells + 1);
216 
217  this->Data->CellPointIds.Connectivity = connectivity;
218 
219  this->Data->CellPointIds.ElementsValid = true;
220 
221  this->ResetConnectivity(TopologyElementTagPoint{}, TopologyElementTagCell{});
222  }
223 
224  VTKM_CONT
225  vtkm::Id GetCellShapeAsId() const { return this->CellShapeAsId; }
226 
228  VTKM_CONT
229  vtkm::UInt8 GetCellShape(vtkm::Id vtkmNotUsed(cellIndex)) const override
230  {
231  return static_cast<vtkm::UInt8>(this->CellShapeAsId);
232  }
234 
235  VTKM_CONT
236  std::shared_ptr<CellSet> NewInstance() const override
237  {
238  return std::make_shared<CellSetSingleType>();
239  }
240 
241  VTKM_CONT
242  void DeepCopy(const CellSet* src) override
243  {
244  const auto* other = dynamic_cast<const CellSetSingleType*>(src);
245  if (!other)
246  {
247  throw vtkm::cont::ErrorBadType("CellSetSingleType::DeepCopy types don't match");
248  }
249 
250  this->Superclass::DeepCopy(other);
251  this->CellShapeAsId = other->CellShapeAsId;
252  this->NumberOfPointsPerCell = other->NumberOfPointsPerCell;
253  }
254 
255  void PrintSummary(std::ostream& out) const override
256  {
257  out << " CellSetSingleType: Type=" << this->CellShapeAsId << std::endl;
258  out << " CellPointIds:" << std::endl;
259  this->Data->CellPointIds.PrintSummary(out);
260  out << " PointCellIds:" << std::endl;
261  this->Data->PointCellIds.PrintSummary(out);
262  }
263 
264 private:
265  template <typename CellShapeTag>
266  void CheckNumberOfPointsPerCell(CellShapeTag,
268  vtkm::IdComponent numVertices) const
269  {
271  {
272  throw vtkm::cont::ErrorBadValue("Passed invalid number of points for cell shape.");
273  }
274  }
275 
276  template <typename CellShapeTag>
277  void CheckNumberOfPointsPerCell(CellShapeTag,
279  vtkm::IdComponent vtkmNotUsed(numVertices)) const
280  {
281  // Technically, a shape with a variable number of points probably has a
282  // minimum number of points, but we are not being sophisticated enough to
283  // check that. Instead, just pass the check by returning without error.
284  }
285 
287  {
288  switch (this->CellShapeAsId)
289  {
290  vtkmGenericCellShapeMacro(this->CheckNumberOfPointsPerCell(
291  CellShapeTag(), vtkm::CellTraits<CellShapeTag>::IsSizeFixed(), numVertices));
292  default:
293  throw vtkm::cont::ErrorBadValue("CellSetSingleType unable to determine the cell type");
294  }
295  }
296 
300 };
301 }
302 } // namespace vtkm::cont
303 
304 //=============================================================================
305 // Specializations of serialization related classes
307 namespace vtkm
308 {
309 namespace cont
310 {
311 
312 template <typename ConnectivityST>
313 struct SerializableTypeString<vtkm::cont::CellSetSingleType<ConnectivityST>>
314 {
315  static VTKM_CONT const std::string& Get()
316  {
317  static std::string name = "CS_Single<" +
318  SerializableTypeString<vtkm::cont::ArrayHandle<vtkm::Id, ConnectivityST>>::Get() + "_ST>";
319 
320  return name;
321  }
322 };
323 }
324 } // vtkm::cont
325 
326 namespace mangled_diy_namespace
327 {
328 
329 template <typename ConnectivityST>
330 struct Serialization<vtkm::cont::CellSetSingleType<ConnectivityST>>
331 {
332 private:
334 
335 public:
336  static VTKM_CONT void save(BinaryBuffer& bb, const Type& cs)
337  {
338  vtkmdiy::save(bb, cs.GetNumberOfPoints());
339  vtkmdiy::save(bb, cs.GetCellShape(0));
340  vtkmdiy::save(bb, cs.GetNumberOfPointsInCell(0));
341  vtkmdiy::save(
342  bb, cs.GetConnectivityArray(vtkm::TopologyElementTagCell{}, vtkm::TopologyElementTagPoint{}));
343  }
344 
345  static VTKM_CONT void load(BinaryBuffer& bb, Type& cs)
346  {
347  vtkm::Id numberOfPoints = 0;
348  vtkmdiy::load(bb, numberOfPoints);
349  vtkm::UInt8 shape;
350  vtkmdiy::load(bb, shape);
351  vtkm::IdComponent count;
352  vtkmdiy::load(bb, count);
354  vtkmdiy::load(bb, connectivity);
355 
356  cs = Type{};
357  cs.Fill(numberOfPoints, shape, count, connectivity);
358  }
359 };
360 
361 } // diy
363 
364 #endif //vtk_m_cont_CellSetSingleType_h
vtkm::TopologyElementTagPoint
A tag used to identify the point elements in a topology.
Definition: TopologyElementTag.h:34
vtkm::cont::ArrayHandle
Manages an array-worth of data.
Definition: ArrayHandle.h:300
vtkm::cont::CellSetSingleType::Fill
void Fill(vtkm::Id numPoints, vtkm::UInt8 shapeId, vtkm::IdComponent numberOfPointsPerCell, const vtkm::cont::ArrayHandle< vtkm::Id, ConnectivityStorageTag > &connectivity)
Set all the cells of the mesh.
Definition: CellSetSingleType.h:200
vtkm::exec::arg::load
T load(const U &u, vtkm::Id v)
Definition: FetchTagArrayDirectIn.h:36
vtkm
Groups connected points that have the same field value.
Definition: Atomic.h:19
vtkm::cont::CellSetSingleType::CellSetSingleType
CellSetSingleType()
Definition: CellSetSingleType.h:55
vtkm::Get
auto Get(const vtkm::Tuple< Ts... > &tuple)
Retrieve the object from a vtkm::Tuple at the given index.
Definition: Tuple.h:81
VTKM_ASSERT
#define VTKM_ASSERT(condition)
Definition: Assert.h:43
CellSetExplicit.h
vtkm::IdComponent
vtkm::Int32 IdComponent
Base type to use to index small lists.
Definition: Types.h:194
vtkm::cont::CellSetSingleType::DeepCopy
void DeepCopy(const CellSet *src) override
Definition: CellSetSingleType.h:242
vtkm::cont::CellSetSingleType::CellShapeAsId
vtkm::Id CellShapeAsId
Definition: CellSetSingleType.h:298
vtkm::cont::CellSetSingleType::CellSetSingleType
CellSetSingleType(Thisclass &&src) noexcept
Definition: CellSetSingleType.h:73
vtkm::cont::CellSetSingleType
An explicit cell set with all cells of the same shape.
Definition: CastAndCall.h:34
vtkm::cont::ArrayHandle::GetNumberOfValues
vtkm::Id GetNumberOfValues() const
Returns the number of entries in the array.
Definition: ArrayHandle.h:466
vtkm::cont::make_ArrayHandleConstant
vtkm::cont::ArrayHandleConstant< T > make_ArrayHandleConstant(T value, vtkm::Id numberOfValues)
make_ArrayHandleConstant is convenience function to generate an ArrayHandleImplicit.
Definition: ArrayHandleConstant.h:96
ArrayHandleConstant.h
vtkm::cont::CellSetSingleType::CompleteAddingCells
void CompleteAddingCells(vtkm::Id numPoints)
Finish adding cells one at a time.
Definition: CellSetSingleType.h:171
vtkm::CellTraitsTagSizeVariable
Tag for cell shapes that can have a variable number of points.
Definition: CellTraits.h:35
vtkm::CELL_SHAPE_EMPTY
@ CELL_SHAPE_EMPTY
Placeholder for empty or invalid cells.
Definition: CellShape.h:37
vtkm::cont::CellSetSingleType::GetCellShape
vtkm::UInt8 GetCellShape(vtkm::Id) const override
Definition: CellSetSingleType.h:229
vtkm::cont::ErrorBadType
This class is thrown when VTK-m encounters data of a type that is incompatible with the current opera...
Definition: ErrorBadType.h:25
CellShape.h
vtkm::cont::make_ArrayHandleCounting
vtkm::cont::ArrayHandleCounting< CountingValueType > make_ArrayHandleCounting(CountingValueType start, CountingValueType step, vtkm::Id length)
A convenience function for creating an ArrayHandleCounting.
Definition: ArrayHandleCounting.h:145
mangled_diy_namespace
Definition: Particle.h:351
VTKM_DEPRECATED_SUPPRESS_END
#define VTKM_DEPRECATED_SUPPRESS_END
Definition: Deprecated.h:123
vtkm::cont::CellSetSingleType::AddCell
void AddCell(vtkm::UInt8 shapeId, vtkm::IdComponent numVertices, const IdVecType &ids)
Add a cell.
Definition: CellSetSingleType.h:121
vtkmGenericCellShapeMacro
#define vtkmGenericCellShapeMacro(call)
A macro used in a switch statement to determine cell shape.
Definition: CellShape.h:250
vtkm::cont::CellSetSingleType::ExpectedNumberOfCellsAdded
vtkm::Id ExpectedNumberOfCellsAdded
Definition: CellSetSingleType.h:297
vtkm::cont::CellSetSingleType::CheckNumberOfPointsPerCell
void CheckNumberOfPointsPerCell(CellShapeTag, vtkm::CellTraitsTagSizeVariable, vtkm::IdComponent) const
Definition: CellSetSingleType.h:277
vtkm::cont::CellSetSingleType::CheckNumberOfPointsPerCell
void CheckNumberOfPointsPerCell(CellShapeTag, vtkm::CellTraitsTagSizeFixed, vtkm::IdComponent numVertices) const
Definition: CellSetSingleType.h:266
vtkm::cont::CellSetSingleType::GetCellShapeAsId
vtkm::Id GetCellShapeAsId() const
Definition: CellSetSingleType.h:225
VTKM_STATIC_ASSERT_MSG
#define VTKM_STATIC_ASSERT_MSG(condition, message)
Definition: StaticAssert.h:18
vtkm::cont::CellSetSingleType::PrintSummary
void PrintSummary(std::ostream &out) const override
Definition: CellSetSingleType.h:255
vtkm::cont::CellSetSingleType::~CellSetSingleType
~CellSetSingleType() override
Definition: CellSetSingleType.h:100
vtkm::cont::CellSetSingleType::NumberOfPointsPerCell
vtkm::IdComponent NumberOfPointsPerCell
Definition: CellSetSingleType.h:299
VTKM_CONT
#define VTKM_CONT
Definition: ExportMacros.h:57
CellSet.h
vtkm::Id
vtkm::Int64 Id
Base type to use to index arrays.
Definition: Types.h:227
vtkm::cont::CellSet
Defines the topological structure of the data in a DataSet.
Definition: CellSet.h:28
vtkm::cont::CellSetSingleType::PrepareToAddCells
void PrepareToAddCells(vtkm::Id numCells, vtkm::Id connectivityMaxLen)
Start adding cells one at a time.
Definition: CellSetSingleType.h:106
vtkm::CellShapeTagEmpty
Definition: CellShape.h:147
vtkm::cont::CellSetSingleType::operator=
Thisclass & operator=(const Thisclass &src)
Definition: CellSetSingleType.h:83
vtkm::UInt8
uint8_t UInt8
Base type to use for 8-bit unsigned integer numbers.
Definition: Types.h:169
vtkm::CopyFlag::On
@ On
vtkmNotUsed
#define vtkmNotUsed(parameter_name)
Simple macro to identify a parameter as unused.
Definition: ExportMacros.h:128
VTKM_DEPRECATED_SUPPRESS_BEGIN
#define VTKM_DEPRECATED_SUPPRESS_BEGIN
Definition: Deprecated.h:122
vtkm::cont::CellSetSingleType::CheckNumberOfPointsPerCell
void CheckNumberOfPointsPerCell(vtkm::IdComponent numVertices) const
Definition: CellSetSingleType.h:286
vtkm::cont::ErrorBadValue
This class is thrown when a VTKm function or method encounters an invalid value that inhibits progres...
Definition: ErrorBadValue.h:25
vtkm::cont::CellSetExplicit
Defines an irregular collection of cells.
Definition: CastAndCall.h:36
ArrayHandleCounting.h
vtkm::TopologyElementTagCell
A tag used to identify the cell elements in a topology.
Definition: TopologyElementTag.h:24
CellTraits.h
vtkm::VecTraits
Traits that can be queried to treat any type as a Vec.
Definition: VecTraits.h:61
vtkm::cont::CellSetSingleType::operator=
Thisclass & operator=(Thisclass &&src) noexcept
Definition: CellSetSingleType.h:92
VTKM_ALWAYS_EXPORT
#define VTKM_ALWAYS_EXPORT
Definition: ExportMacros.h:89
vtkm::cont::CellSetSingleType::CellSetSingleType
CellSetSingleType(const Thisclass &src)
Definition: CellSetSingleType.h:64
vtkm::cont::ArrayHandleCounting::StorageTag
typename Superclass::StorageTag StorageTag
Definition: ArrayHandleCounting.h:127
vtkm::CellTraitsTagSizeFixed
Tag for cell shapes with a fixed number of points.
Definition: CellTraits.h:29
vtkm::cont::CellSetSingleType::NewInstance
std::shared_ptr< CellSet > NewInstance() const override
Definition: CellSetSingleType.h:236
vtkm::CellTraits
Information about a cell based on its tag.
Definition: CellTraits.h:46