VTK-m  2.0
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 
28 //Only works with fixed sized cell sets
29 
30 template <typename ConnectivityStorageTag = VTKM_DEFAULT_CONNECTIVITY_STORAGE_TAG>
31 class VTKM_ALWAYS_EXPORT CellSetSingleType
33  typename vtkm::cont::ArrayHandleConstant<vtkm::UInt8>::StorageTag, //ShapesStorageTag
34  ConnectivityStorageTag,
35  typename vtkm::cont::ArrayHandleCounting<vtkm::Id>::StorageTag //OffsetsStorageTag
36  >
37 {
39  using Superclass =
41  ConnectivityStorageTag,
43 
44 public:
45  VTKM_CONT
47  : Superclass()
48  , ExpectedNumberOfCellsAdded(-1)
49  , CellShapeAsId(CellShapeTagEmpty::Id)
50  , NumberOfPointsPerCell(0)
51  {
52  }
53 
54  VTKM_CONT
56  : Superclass(src)
57  , ExpectedNumberOfCellsAdded(-1)
58  , CellShapeAsId(src.CellShapeAsId)
59  , NumberOfPointsPerCell(src.NumberOfPointsPerCell)
60  {
61  }
62 
63  VTKM_CONT
64  CellSetSingleType(Thisclass&& src) noexcept
65  : Superclass(std::forward<Superclass>(src))
66  , ExpectedNumberOfCellsAdded(-1)
67  , CellShapeAsId(src.CellShapeAsId)
68  , NumberOfPointsPerCell(src.NumberOfPointsPerCell)
69  {
70  }
71 
72 
73  VTKM_CONT
75  {
76  this->Superclass::operator=(src);
77  this->CellShapeAsId = src.CellShapeAsId;
78  this->NumberOfPointsPerCell = src.NumberOfPointsPerCell;
79  return *this;
80  }
81 
82  VTKM_CONT
83  Thisclass& operator=(Thisclass&& src) noexcept
84  {
85  this->Superclass::operator=(std::forward<Superclass>(src));
86  this->CellShapeAsId = src.CellShapeAsId;
87  this->NumberOfPointsPerCell = src.NumberOfPointsPerCell;
88  return *this;
89  }
90 
91  virtual ~CellSetSingleType() override {}
92 
94  VTKM_CONT
95  void PrepareToAddCells(vtkm::Id numCells, vtkm::Id connectivityMaxLen)
96  {
97  this->CellShapeAsId = vtkm::CELL_SHAPE_EMPTY;
98 
99  this->Data->CellPointIds.Connectivity.Allocate(connectivityMaxLen);
100 
101  this->Data->NumberOfCellsAdded = 0;
102  this->Data->ConnectivityAdded = 0;
103  this->ExpectedNumberOfCellsAdded = numCells;
104  }
105 
107  template <typename IdVecType>
108  VTKM_CONT void AddCell(vtkm::UInt8 shapeId, vtkm::IdComponent numVertices, const IdVecType& ids)
109  {
110  using Traits = vtkm::VecTraits<IdVecType>;
111  VTKM_STATIC_ASSERT_MSG((std::is_same<typename Traits::ComponentType, vtkm::Id>::value),
112  "CellSetSingleType::AddCell requires vtkm::Id for indices.");
113 
114  if (Traits::GetNumberOfComponents(ids) < numVertices)
115  {
116  throw vtkm::cont::ErrorBadValue("Not enough indices given to CellSetSingleType::AddCell.");
117  }
118 
119  if (this->Data->ConnectivityAdded + numVertices >
120  this->Data->CellPointIds.Connectivity.GetNumberOfValues())
121  {
123  "Connectivity increased past estimated maximum connectivity.");
124  }
125 
126  if (this->CellShapeAsId == vtkm::CELL_SHAPE_EMPTY)
127  {
128  if (shapeId == vtkm::CELL_SHAPE_EMPTY)
129  {
130  throw vtkm::cont::ErrorBadValue("Cannot create cells of type empty.");
131  }
132  this->CellShapeAsId = shapeId;
133  this->CheckNumberOfPointsPerCell(numVertices);
134  this->NumberOfPointsPerCell = numVertices;
135  }
136  else
137  {
138  if (shapeId != this->GetCellShape(0))
139  {
140  throw vtkm::cont::ErrorBadValue("Cannot have differing shapes in CellSetSingleType.");
141  }
142  if (numVertices != this->NumberOfPointsPerCell)
143  {
145  "Inconsistent number of points in cells for CellSetSingleType.");
146  }
147  }
148  auto conn = this->Data->CellPointIds.Connectivity.WritePortal();
149  for (vtkm::IdComponent iVert = 0; iVert < numVertices; ++iVert)
150  {
151  conn.Set(this->Data->ConnectivityAdded + iVert, Traits::GetComponent(ids, iVert));
152  }
153  this->Data->NumberOfCellsAdded++;
154  this->Data->ConnectivityAdded += numVertices;
155  }
156 
158  VTKM_CONT
160  {
161  this->Data->NumberOfPoints = numPoints;
162  this->Data->CellPointIds.Connectivity.Allocate(this->Data->ConnectivityAdded,
164 
165  vtkm::Id numCells = this->Data->NumberOfCellsAdded;
166 
167  this->Data->CellPointIds.Shapes =
168  vtkm::cont::make_ArrayHandleConstant(this->GetCellShape(0), numCells);
169  this->Data->CellPointIds.Offsets = vtkm::cont::make_ArrayHandleCounting(
170  vtkm::Id(0), static_cast<vtkm::Id>(this->NumberOfPointsPerCell), numCells);
171 
172  this->Data->CellPointIds.ElementsValid = true;
173 
174  if (this->ExpectedNumberOfCellsAdded != this->GetNumberOfCells())
175  {
176  throw vtkm::cont::ErrorBadValue("Did not add the expected number of cells.");
177  }
178 
179  this->Data->NumberOfCellsAdded = -1;
180  this->Data->ConnectivityAdded = -1;
181  this->ExpectedNumberOfCellsAdded = -1;
182  }
183 
184  //This is the way you can fill the memory from another system without copying
185  VTKM_CONT
186  void Fill(vtkm::Id numPoints,
187  vtkm::UInt8 shapeId,
188  vtkm::IdComponent numberOfPointsPerCell,
190  {
191  this->Data->NumberOfPoints = numPoints;
192  this->CellShapeAsId = shapeId;
193  this->CheckNumberOfPointsPerCell(numberOfPointsPerCell);
194 
195  const vtkm::Id numCells = connectivity.GetNumberOfValues() / numberOfPointsPerCell;
196  VTKM_ASSERT((connectivity.GetNumberOfValues() % numberOfPointsPerCell) == 0);
197 
198  this->Data->CellPointIds.Shapes = vtkm::cont::make_ArrayHandleConstant(shapeId, numCells);
199 
200  this->Data->CellPointIds.Offsets = vtkm::cont::make_ArrayHandleCounting(
201  vtkm::Id(0), static_cast<vtkm::Id>(numberOfPointsPerCell), numCells + 1);
202 
203  this->Data->CellPointIds.Connectivity = connectivity;
204 
205  this->Data->CellPointIds.ElementsValid = true;
206 
207  this->ResetConnectivity(TopologyElementTagPoint{}, TopologyElementTagCell{});
208  }
209 
210  VTKM_CONT
211  vtkm::Id GetCellShapeAsId() const { return this->CellShapeAsId; }
212 
214  VTKM_CONT
215  vtkm::UInt8 GetCellShape(vtkm::Id vtkmNotUsed(cellIndex)) const override
216  {
217  return static_cast<vtkm::UInt8>(this->CellShapeAsId);
218  }
220 
221  VTKM_CONT
222  std::shared_ptr<CellSet> NewInstance() const override
223  {
224  return std::make_shared<CellSetSingleType>();
225  }
226 
227  VTKM_CONT
228  void DeepCopy(const CellSet* src) override
229  {
230  const auto* other = dynamic_cast<const CellSetSingleType*>(src);
231  if (!other)
232  {
233  throw vtkm::cont::ErrorBadType("CellSetSingleType::DeepCopy types don't match");
234  }
235 
236  this->Superclass::DeepCopy(other);
237  this->CellShapeAsId = other->CellShapeAsId;
238  this->NumberOfPointsPerCell = other->NumberOfPointsPerCell;
239  }
240 
241  virtual void PrintSummary(std::ostream& out) const override
242  {
243  out << " CellSetSingleType: Type=" << this->CellShapeAsId << std::endl;
244  out << " CellPointIds:" << std::endl;
245  this->Data->CellPointIds.PrintSummary(out);
246  out << " PointCellIds:" << std::endl;
247  this->Data->PointCellIds.PrintSummary(out);
248  }
249 
250 private:
251  template <typename CellShapeTag>
252  void CheckNumberOfPointsPerCell(CellShapeTag,
254  vtkm::IdComponent numVertices) const
255  {
257  {
258  throw vtkm::cont::ErrorBadValue("Passed invalid number of points for cell shape.");
259  }
260  }
261 
262  template <typename CellShapeTag>
263  void CheckNumberOfPointsPerCell(CellShapeTag,
265  vtkm::IdComponent vtkmNotUsed(numVertices)) const
266  {
267  // Technically, a shape with a variable number of points probably has a
268  // minimum number of points, but we are not being sophisticated enough to
269  // check that. Instead, just pass the check by returning without error.
270  }
271 
273  {
274  switch (this->CellShapeAsId)
275  {
276  vtkmGenericCellShapeMacro(this->CheckNumberOfPointsPerCell(
277  CellShapeTag(), vtkm::CellTraits<CellShapeTag>::IsSizeFixed(), numVertices));
278  default:
279  throw vtkm::cont::ErrorBadValue("CellSetSingleType unable to determine the cell type");
280  }
281  }
282 
286 };
287 }
288 } // namespace vtkm::cont
289 
290 //=============================================================================
291 // Specializations of serialization related classes
293 namespace vtkm
294 {
295 namespace cont
296 {
297 
298 template <typename ConnectivityST>
299 struct SerializableTypeString<vtkm::cont::CellSetSingleType<ConnectivityST>>
300 {
301  static VTKM_CONT const std::string& Get()
302  {
303  static std::string name = "CS_Single<" +
304  SerializableTypeString<vtkm::cont::ArrayHandle<vtkm::Id, ConnectivityST>>::Get() + "_ST>";
305 
306  return name;
307  }
308 };
309 }
310 } // vtkm::cont
311 
312 namespace mangled_diy_namespace
313 {
314 
315 template <typename ConnectivityST>
316 struct Serialization<vtkm::cont::CellSetSingleType<ConnectivityST>>
317 {
318 private:
320 
321 public:
322  static VTKM_CONT void save(BinaryBuffer& bb, const Type& cs)
323  {
324  vtkmdiy::save(bb, cs.GetNumberOfPoints());
325  vtkmdiy::save(bb, cs.GetCellShape(0));
326  vtkmdiy::save(bb, cs.GetNumberOfPointsInCell(0));
327  vtkmdiy::save(
328  bb, cs.GetConnectivityArray(vtkm::TopologyElementTagCell{}, vtkm::TopologyElementTagPoint{}));
329  }
330 
331  static VTKM_CONT void load(BinaryBuffer& bb, Type& cs)
332  {
333  vtkm::Id numberOfPoints = 0;
334  vtkmdiy::load(bb, numberOfPoints);
335  vtkm::UInt8 shape;
336  vtkmdiy::load(bb, shape);
337  vtkm::IdComponent count;
338  vtkmdiy::load(bb, count);
340  vtkmdiy::load(bb, connectivity);
341 
342  cs = Type{};
343  cs.Fill(numberOfPoints, shape, count, connectivity);
344  }
345 };
346 
347 } // diy
349 
350 #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::GetNumberOfValues
VTKM_CONT vtkm::Id GetNumberOfValues() const
Returns the number of entries in the array.
Definition: ArrayHandle.h:448
vtkm::cont::ArrayHandle
Manages an array-worth of data.
Definition: ArrayHandle.h:283
vtkm::cont::CellSetSingleType::CellSetSingleType
VTKM_CONT CellSetSingleType(const Thisclass &src)
Definition: CellSetSingleType.h:55
vtkm::cont::CellSetSingleType::DeepCopy
VTKM_CONT void DeepCopy(const CellSet *src) override
Definition: CellSetSingleType.h:228
vtkm
Groups connected points that have the same field value.
Definition: Atomic.h:19
VTKM_ASSERT
#define VTKM_ASSERT(condition)
Definition: Assert.h:43
CellSetExplicit.h
vtkm::Get
VTKM_SUPPRESS_EXEC_WARNINGS VTKM_EXEC_CONT auto Get(const vtkm::Tuple< Ts... > &tuple) -> decltype(tuple.template Get< Index >())
Retrieve the object from a vtkm::Tuple at the given index.
Definition: Tuple.h:83
vtkm::cont::CellSetSingleType::CheckNumberOfPointsPerCell
void CheckNumberOfPointsPerCell(CellShapeTag, vtkm::CellTraitsTagSizeVariable, vtkm::IdComponent vtkmNotUsed(numVertices)) const
Definition: CellSetSingleType.h:263
vtkm::cont::make_ArrayHandleCounting
VTKM_CONT vtkm::cont::ArrayHandleCounting< CountingValueType > make_ArrayHandleCounting(CountingValueType start, CountingValueType step, vtkm::Id length)
A convenience function for creating an ArrayHandleCounting.
Definition: ArrayHandleCounting.h:151
vtkm::IdComponent
vtkm::Int32 IdComponent
Represents a component ID (index of component in a vector).
Definition: Types.h:168
vtkm::cont::CellSetSingleType::CellShapeAsId
vtkm::Id CellShapeAsId
Definition: CellSetSingleType.h:284
vtkm::cont::CellSetSingleType::NewInstance
VTKM_DEPRECATED_SUPPRESS_END VTKM_CONT std::shared_ptr< CellSet > NewInstance() const override
Definition: CellSetSingleType.h:222
vtkm::cont::CellSetSingleType
Definition: CastAndCall.h:34
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:89
ArrayHandleConstant.h
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
Definition: CellShape.h:36
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
mangled_diy_namespace
Definition: Particle.h:331
vtkm::Id
vtkm::Int32 Id
Represents an ID (index into arrays).
Definition: Types.h:191
vtkm::exec::arg::load
VTKM_SUPPRESS_EXEC_WARNINGS VTKM_EXEC T load(const U &u, vtkm::Id v)
Definition: FetchTagArrayDirectIn.h:36
VTKM_DEPRECATED_SUPPRESS_END
#define VTKM_DEPRECATED_SUPPRESS_END
Definition: Deprecated.h:123
vtkm::cont::CellSetSingleType::GetCellShape
VTKM_DEPRECATED_SUPPRESS_BEGIN VTKM_CONT vtkm::UInt8 GetCellShape(vtkm::Id vtkmNotUsed(cellIndex)) const override
Definition: CellSetSingleType.h:215
vtkmGenericCellShapeMacro
#define vtkmGenericCellShapeMacro(call)
A macro used in a switch statement to determine cell shape.
Definition: CellShape.h:230
vtkm::cont::StorageTagCounting
Definition: ArrayHandleCounting.h:23
vtkm::cont::CellSetSingleType::ExpectedNumberOfCellsAdded
vtkm::Id ExpectedNumberOfCellsAdded
Definition: CellSetSingleType.h:283
vtkm::cont::CellSetSingleType::PrepareToAddCells
VTKM_CONT void PrepareToAddCells(vtkm::Id numCells, vtkm::Id connectivityMaxLen)
First method to add cells – one at a time.
Definition: CellSetSingleType.h:95
vtkm::cont::CellSetSingleType::CheckNumberOfPointsPerCell
void CheckNumberOfPointsPerCell(CellShapeTag, vtkm::CellTraitsTagSizeFixed, vtkm::IdComponent numVertices) const
Definition: CellSetSingleType.h:252
VTKM_STATIC_ASSERT_MSG
#define VTKM_STATIC_ASSERT_MSG(condition, message)
Definition: StaticAssert.h:18
vtkm::cont::CellSetSingleType::NumberOfPointsPerCell
vtkm::IdComponent NumberOfPointsPerCell
Definition: CellSetSingleType.h:285
VTKM_CONT
#define VTKM_CONT
Definition: ExportMacros.h:57
vtkm::cont::CellSetSingleType::operator=
VTKM_CONT Thisclass & operator=(const Thisclass &src)
Definition: CellSetSingleType.h:74
CellSet.h
vtkm::cont::CellSet
Definition: CellSet.h:24
vtkm::UInt8
uint8_t UInt8
Definition: Types.h:157
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:272
vtkm::cont::CellSetSingleType::CellSetSingleType
VTKM_CONT CellSetSingleType()
Definition: CellSetSingleType.h:46
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
Definition: CastAndCall.h:36
ArrayHandleCounting.h
vtkm::cont::CellSetSingleType::CellSetSingleType
VTKM_CONT CellSetSingleType(Thisclass &&src) noexcept
Definition: CellSetSingleType.h:64
vtkm::cont::CellSetSingleType::CompleteAddingCells
VTKM_CONT void CompleteAddingCells(vtkm::Id numPoints)
Third and final method to add cells – one at a time.
Definition: CellSetSingleType.h:159
vtkm::cont::CellSetSingleType::AddCell
VTKM_CONT void AddCell(vtkm::UInt8 shapeId, vtkm::IdComponent numVertices, const IdVecType &ids)
Second method to add cells – one at a time.
Definition: CellSetSingleType.h:108
vtkm::TopologyElementTagCell
A tag used to identify the cell elements in a topology.
Definition: TopologyElementTag.h:24
CellTraits.h
vtkm::VecTraits
The VecTraits class gives several static members that define how to use a given type as a vector.
Definition: VecTraits.h:66
VTKM_ALWAYS_EXPORT
#define VTKM_ALWAYS_EXPORT
Definition: ExportMacros.h:92
vtkm::cont::CellSetSingleType::~CellSetSingleType
virtual ~CellSetSingleType() override
Definition: CellSetSingleType.h:91
vtkm::cont::CellSetSingleType::Fill
VTKM_CONT void Fill(vtkm::Id numPoints, vtkm::UInt8 shapeId, vtkm::IdComponent numberOfPointsPerCell, const vtkm::cont::ArrayHandle< vtkm::Id, ConnectivityStorageTag > &connectivity)
Definition: CellSetSingleType.h:186
vtkm::cont::CellSetSingleType::GetCellShapeAsId
VTKM_CONT vtkm::Id GetCellShapeAsId() const
Definition: CellSetSingleType.h:211
vtkm::cont::CellSetSingleType::operator=
VTKM_CONT Thisclass & operator=(Thisclass &&src) noexcept
Definition: CellSetSingleType.h:83
vtkm::CellTraitsTagSizeFixed
Tag for cell shapes with a fixed number of points.
Definition: CellTraits.h:29
vtkm::cont::CellSetSingleType::PrintSummary
virtual void PrintSummary(std::ostream &out) const override
Definition: CellSetSingleType.h:241
vtkm::CellTraits
Information about a cell based on its tag.
Definition: CellTraits.h:46