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