1 //============================================================================
2 // Copyright (c) Kitware, Inc.
3 // All rights reserved.
4 // See LICENSE.txt for details.
5 // This software is distributed WITHOUT ANY WARRANTY; without even
6 // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
7 // PURPOSE. See the above copyright notice for more information.
8 //
9 // Copyright 2015 Sandia Corporation.
10 // Copyright 2015 UT-Battelle, LLC.
11 // Copyright 2015 Los Alamos National Security.
12 //
13 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
14 // the U.S. Government retains certain rights in this software.
15 //
16 // Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
17 // Laboratory (LANL), the U.S. Government retains certain rights in
18 // this software.
19 //============================================================================
20 #include "vtkmlib/Storage.h"
21 #include "vtkmCellSetSingleType.h"
22 #include "vtkmConnectivityExec.h"
23
24 #include <vtkm/cont/internal/ReverseConnectivityBuilder.h>
25 #include <vtkm/worklet/WorkletMapField.h>
26 #include <vtkm/worklet/DispatcherMapField.h>
27
28 namespace
29 {
30
31 // Converts [0, rconnSize) to [0, connSize), skipping cell length entries.
32 struct SingleTypeRConnToConn
33 {
34 vtkm::Id PointsPerCell;
35
36 VTKM_EXEC
operator ()__anon3e3ba9110111::SingleTypeRConnToConn37 vtkm::Id operator()(vtkm::Id rconnIdx) const
38 {
39 return rconnIdx + 1 + (rconnIdx / this->PointsPerCell);
40 }
41 };
42
43 // Converts a connectivity index to a cell id:
44 struct SingleTypeCellIdCalc
45 {
46 vtkm::Id EncodedCellSize;
47
48 VTKM_EXEC
operator ()__anon3e3ba9110111::SingleTypeCellIdCalc49 vtkm::Id operator()(vtkm::Id connIdx) const
50 {
51 return connIdx / this->EncodedCellSize;
52 }
53 };
54
55 } // end anon namespace
56
57 namespace vtkm {
58 namespace cont {
59
60 //------------------------------------------------------------------------------
DetermineNumberOfPoints() const61 vtkm::IdComponent vtkmCellSetSingleType::DetermineNumberOfPoints() const
62 {
63 vtkm::IdComponent numberOfPointsPerCell = -1;
64 switch (this->CellTypeAsId)
65 {
66 vtkmGenericCellShapeMacro(this->DetermineNumberOfPoints(
67 CellShapeTag(), vtkm::CellTraits<CellShapeTag>::IsSizeFixed(),
68 numberOfPointsPerCell));
69 default:
70 throw vtkm::cont::ErrorBadValue(
71 "CellSetSingleType unable to determine the cell type");
72 }
73 return numberOfPointsPerCell;
74 }
75
76 //------------------------------------------------------------------------------
Fill(vtkm::Id numberOfPoints,const vtkm::cont::ArrayHandle<vtkm::Id,tovtkm::vtkCellArrayContainerTag> & connectivity)77 void vtkmCellSetSingleType::Fill(
78 vtkm::Id numberOfPoints,
79 const vtkm::cont::ArrayHandle<vtkm::Id, tovtkm::vtkCellArrayContainerTag>&
80 connectivity)
81 {
82 const vtkm::IdComponent numberOfPointsPerCell =
83 this->DetermineNumberOfPoints();
84 this->NumberOfCells =
85 connectivity.GetNumberOfValues() / (numberOfPointsPerCell + 1);
86 this->Connectivity = connectivity;
87 this->NumberOfPoints = numberOfPoints;
88 }
89
90 //------------------------------------------------------------------------------
91 template <typename Device>
92 typename vtkm::exec::ConnectivityVTKSingleType<Device>
PrepareForInput(Device,vtkm::TopologyElementTagPoint,vtkm::TopologyElementTagCell) const93 vtkmCellSetSingleType::PrepareForInput(Device,
94 vtkm::TopologyElementTagPoint,
95 vtkm::TopologyElementTagCell) const
96 {
97 const vtkm::IdComponent numberOfPointsPerCell =
98 this->DetermineNumberOfPoints();
99 const vtkm::UInt8 shapeTypeValue =
100 static_cast<vtkm::UInt8>(this->CellTypeAsId);
101
102 return vtkm::exec::ConnectivityVTKSingleType<Device>(
103 this->Connectivity.PrepareForInput(Device()), this->NumberOfCells,
104 numberOfPointsPerCell, shapeTypeValue);
105 }
106
107 //------------------------------------------------------------------------------
108 template <typename Device>
109 typename vtkm::exec::ReverseConnectivityVTK<Device>
PrepareForInput(Device,vtkm::TopologyElementTagCell,vtkm::TopologyElementTagPoint) const110 vtkmCellSetSingleType::PrepareForInput(Device,
111 vtkm::TopologyElementTagCell,
112 vtkm::TopologyElementTagPoint) const
113 {
114 if(!this->ReverseConnectivityBuilt)
115 {
116 const vtkm::Id numberOfPoints = this->GetNumberOfPoints();
117 const vtkm::Id numberOfCells = this->GetNumberOfCells();
118 const vtkm::Id numberOfPointsPerCell = this->DetermineNumberOfPoints();
119 const vtkm::Id rconnSize = numberOfCells*numberOfPointsPerCell;
120
121 const SingleTypeRConnToConn rconnToConnCalc{numberOfPointsPerCell};
122 const SingleTypeCellIdCalc cellIdCalc{numberOfPointsPerCell + 1}; // +1 for cell length entries
123
124 vtkm::cont::internal::ReverseConnectivityBuilder builder;
125
126 builder.Run(this->Connectivity,
127 this->RConn,
128 this->RNumIndices,
129 this->RIndexOffsets,
130 rconnToConnCalc,
131 cellIdCalc,
132 numberOfPoints,
133 rconnSize,
134 Device{});
135
136 this->NumberOfPoints = this->RIndexOffsets.GetNumberOfValues();
137 this->ReverseConnectivityBuilt = true;
138 } // End if !RConnBuilt
139
140 //no need to have a reverse shapes array, as everything has the shape type
141 //of vertex
142 return vtkm::exec::ReverseConnectivityVTK<Device>(
143 this->RConn.PrepareForInput(Device()),
144 this->RNumIndices.PrepareForInput(Device()),
145 this->RIndexOffsets.PrepareForInput(Device()));
146 }
147
148 //------------------------------------------------------------------------------
PrintSummary(std::ostream & out) const149 void vtkmCellSetSingleType::PrintSummary(std::ostream& out) const
150 {
151 out << " vtkmCellSetSingleType: " << this->Name << std::endl;
152 out << " NumberOfCells: " << this->NumberOfCells << std::endl;
153 out << " CellTypeAsId: " << this->CellTypeAsId << std::endl;
154 out << " Connectivity: " << std::endl;
155 vtkm::cont::printSummary_ArrayHandle(this->Connectivity, out);
156 }
157
158 // template methods we want to compile only once
159 template VTKACCELERATORSVTKM_EXPORT
160 vtkm::exec::ConnectivityVTKSingleType<vtkm::cont::DeviceAdapterTagSerial>
161 vtkmCellSetSingleType::PrepareForInput(vtkm::cont::DeviceAdapterTagSerial,
162 vtkm::TopologyElementTagPoint, vtkm::TopologyElementTagCell) const;
163
164 template VTKACCELERATORSVTKM_EXPORT
165 vtkm::exec::ReverseConnectivityVTK<vtkm::cont::DeviceAdapterTagSerial>
166 vtkmCellSetSingleType::PrepareForInput(vtkm::cont::DeviceAdapterTagSerial,
167 vtkm::TopologyElementTagCell, vtkm::TopologyElementTagPoint) const;
168
169 #ifdef VTKM_ENABLE_TBB
170 template VTKACCELERATORSVTKM_EXPORT
171 vtkm::exec::ConnectivityVTKSingleType<vtkm::cont::DeviceAdapterTagTBB>
172 vtkmCellSetSingleType::PrepareForInput(vtkm::cont::DeviceAdapterTagTBB,
173 vtkm::TopologyElementTagPoint, vtkm::TopologyElementTagCell) const;
174
175 template VTKACCELERATORSVTKM_EXPORT
176 vtkm::exec::ReverseConnectivityVTK<vtkm::cont::DeviceAdapterTagTBB>
177 vtkmCellSetSingleType::PrepareForInput(vtkm::cont::DeviceAdapterTagTBB,
178 vtkm::TopologyElementTagCell, vtkm::TopologyElementTagPoint) const;
179 #endif
180
181 #ifdef VTKM_ENABLE_OPENMP
182 template VTKACCELERATORSVTKM_EXPORT
183 vtkm::exec::ConnectivityVTKSingleType<vtkm::cont::DeviceAdapterTagOpenMP>
184 vtkmCellSetSingleType::PrepareForInput(vtkm::cont::DeviceAdapterTagOpenMP,
185 vtkm::TopologyElementTagPoint, vtkm::TopologyElementTagCell) const;
186
187 template VTKACCELERATORSVTKM_EXPORT
188 vtkm::exec::ReverseConnectivityVTK<vtkm::cont::DeviceAdapterTagOpenMP>
189 vtkmCellSetSingleType::PrepareForInput(vtkm::cont::DeviceAdapterTagOpenMP,
190 vtkm::TopologyElementTagCell, vtkm::TopologyElementTagPoint) const;
191 #endif
192 }
193 }
194