VTK-m  2.0
MeshStructureFreudenthal3D.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 // Copyright (c) 2018, The Regents of the University of California, through
11 // Lawrence Berkeley National Laboratory (subject to receipt of any required approvals
12 // from the U.S. Dept. of Energy). All rights reserved.
13 //
14 // Redistribution and use in source and binary forms, with or without modification,
15 // are permitted provided that the following conditions are met:
16 //
17 // (1) Redistributions of source code must retain the above copyright notice, this
18 // list of conditions and the following disclaimer.
19 //
20 // (2) Redistributions in binary form must reproduce the above copyright notice,
21 // this list of conditions and the following disclaimer in the documentation
22 // and/or other materials provided with the distribution.
23 //
24 // (3) Neither the name of the University of California, Lawrence Berkeley National
25 // Laboratory, U.S. Dept. of Energy nor the names of its contributors may be
26 // used to endorse or promote products derived from this software without
27 // specific prior written permission.
28 //
29 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
30 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
31 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
32 // IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
33 // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34 // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
36 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
37 // OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
38 // OF THE POSSIBILITY OF SUCH DAMAGE.
39 //
40 //=============================================================================
41 //
42 // This code is an extension of the algorithm presented in the paper:
43 // Parallel Peak Pruning for Scalable SMP Contour Tree Computation.
44 // Hamish Carr, Gunther Weber, Christopher Sewell, and James Ahrens.
45 // Proceedings of the IEEE Symposium on Large Data Analysis and Visualization
46 // (LDAV), October 2016, Baltimore, Maryland.
47 //
48 // The PPP2 algorithm and software were jointly developed by
49 // Hamish Carr (University of Leeds), Gunther H. Weber (LBNL), and
50 // Oliver Ruebel (LBNL)
51 //==============================================================================
52 
53 #ifndef vtk_m_worklet_contourtree_augmented_meshtypes_MeshStructureFreudenthal3D_h
54 #define vtk_m_worklet_contourtree_augmented_meshtypes_MeshStructureFreudenthal3D_h
55 
56 #include <vtkm/Pair.h>
57 #include <vtkm/Types.h>
58 #include <vtkm/cont/ArrayHandle.h>
63 
64 
65 namespace vtkm
66 {
67 namespace worklet
68 {
69 namespace contourtree_augmented
70 {
71 
72 // Worklet for computing the sort indices from the sort order
74 {
75 public:
77 
80 
82 
85 
86  // Default constructor needed to make the CUDA build work
89  : data_set_mesh::MeshStructure3D()
90  , GetMax(false)
91  , NumIncidentEdge(m3d_freudenthal::N_INCIDENT_EDGES)
92  {
93  }
94 
95  // Main constructore used in the code
97  vtkm::Id3 meshSize,
98  vtkm::Id nincident_edges,
99  bool getmax,
100  const IdArrayType& sortIndices,
101  const IdArrayType& sortOrder,
102  const m3d_freudenthal::EdgeBoundaryDetectionMasksType& edgeBoundaryDetectionMasksIn,
103  const m3d_freudenthal::NeighbourOffsetsType& neighbourOffsetsIn,
104  const m3d_freudenthal::LinkComponentCaseTableType& linkComponentCaseTableIn,
106  vtkm::cont::Token& token)
107  : data_set_mesh::MeshStructure3D(meshSize)
108  , GetMax(getmax)
109  , NumIncidentEdge(nincident_edges)
110  {
111  this->SortIndicesPortal = sortIndices.PrepareForInput(device, token);
112  this->SortOrderPortal = sortOrder.PrepareForInput(device, token);
114  edgeBoundaryDetectionMasksIn.PrepareForInput(device, token);
115  this->NeighbourOffsetsPortal = neighbourOffsetsIn.PrepareForInput(device, token);
116  this->LinkComponentCaseTablePortal = linkComponentCaseTableIn.PrepareForInput(device, token);
117  }
118 
119  VTKM_EXEC
120  vtkm::Id GetMaxNumberOfNeighbours() const { return m3d_freudenthal::N_INCIDENT_EDGES; }
121 
122 
123  VTKM_EXEC
124  inline vtkm::Id GetNeighbourIndex(vtkm::Id sortIndex, vtkm::Id edgeNo) const
125  { // GetNeighbourIndex
126  vtkm::Id meshIndex = SortOrderPortal.Get(sortIndex);
127  // NOTE: Offsets are stored in "reversed" zyx [2][1][0] order (remaining artifact from
128  // using slices, rows, columns instead of xyz/[0][1][2])
129  return SortIndicesPortal.Get(meshIndex +
130  (NeighbourOffsetsPortal.Get(edgeNo)[0] * this->MeshSize[1] +
131  NeighbourOffsetsPortal.Get(edgeNo)[1]) *
132  this->MeshSize[0] +
133  NeighbourOffsetsPortal.Get(edgeNo)[2]);
134  } // GetNeighbourIndex
135 
136 
137 // Disable conversion warnings for Add, Subtract, Multiply, Divide on GCC only.
138 // GCC creates false positive warnings for signed/unsigned char* operations.
139 // This occurs because the values are implicitly casted up to int's for the
140 // operation, and than casted back down to char's when return.
141 // This causes a false positive warning, even when the values is within
142 // the value types range
143 #if (defined(VTKM_GCC) || defined(VTKM_CLANG))
144 #pragma GCC diagnostic push
145 #pragma GCC diagnostic ignored "-Wconversion"
146 #endif // gcc || clang
147 
148  // sets outgoing paths for saddles
149  VTKM_EXEC
150  inline vtkm::Id GetExtremalNeighbour(vtkm::Id sortIndex) const
151  { // GetExtremalNeighbour()
152  // convert to a mesh index
153  using namespace m3d_freudenthal;
154  vtkm::Id meshIndex = SortOrderPortal.Get(sortIndex);
155 
156  vtkm::Id3 pos = this->VertexPos(meshIndex);
157  vtkm::Int8 boundaryConfig = ((pos[0] == 0) ? LeftBit : 0) |
158  ((pos[0] == this->MeshSize[0] - 1) ? RightBit : 0) | ((pos[1] == 0) ? TopBit : 0) |
159  ((pos[1] == this->MeshSize[1] - 1) ? BottomBit : 0) | ((pos[2] == 0) ? FrontBit : 0) |
160  ((pos[2] == this->MeshSize[2] - 1) ? BackBit : 0);
161 
162  // in what follows, the boundary conditions always reset wasAscent
163  // loop downwards so that we pick the same edges as previous versions
164  for (vtkm::Id nbrNo = 0; nbrNo < NumIncidentEdge; ++nbrNo)
165  {
166  // only consider valid edges
167  if (!(boundaryConfig & EdgeBoundaryDetectionMasksPortal.Get(nbrNo)))
168  {
169  vtkm::Id nbrSortIndex = GetNeighbourIndex(sortIndex, nbrNo);
170  // explicit test allows reversal between join and split trees
171  if (GetMax ? (nbrSortIndex > sortIndex) : (nbrSortIndex < sortIndex))
172  { // valid edge and outbound
173  return nbrSortIndex;
174  } // valid edge and outbound
175  }
176  } // per edge
177  return sortIndex | TERMINAL_ELEMENT;
178  } // GetExtremalNeighbour()
179 
180 
181  // NOTE/FIXME: The following also iterates over all values and could be combined with GetExtremalNeighbour(). However, the
182  // results are needed at different places and splitting the two functions leads to a cleaner design
183  VTKM_EXEC
185  vtkm::Id sortIndex,
186  bool getMaxComponents) const
187  { // GetNeighbourComponentsMaskAndDegree()
188  // convert to a meshIndex
189  using namespace m3d_freudenthal;
190  vtkm::Id meshIndex = SortOrderPortal.Get(sortIndex);
191 
192  // get the row and column
193  vtkm::Id3 pos = this->VertexPos(meshIndex);
194  vtkm::Int8 boundaryConfig = ((pos[0] == 0) ? LeftBit : 0) |
195  ((pos[0] == this->MeshSize[0] - 1) ? RightBit : 0) | ((pos[1] == 0) ? TopBit : 0) |
196  ((pos[1] == this->MeshSize[1] - 1) ? BottomBit : 0) | ((pos[2] == 0) ? FrontBit : 0) |
197  ((pos[2] == this->MeshSize[2] - 1) ? BackBit : 0);
198 
199  // Initialize "union find"
200  vtkm::Id caseNo = 0;
201 
202  // Compute components of upper link
203  for (int edgeNo = 0; edgeNo < N_INCIDENT_EDGES; ++edgeNo)
204  {
205  if (!(boundaryConfig & EdgeBoundaryDetectionMasksPortal.Get(edgeNo)))
206  {
207  vtkm::Id nbrSortIndex = GetNeighbourIndex(sortIndex, edgeNo);
208  if (getMaxComponents ? (sortIndex < nbrSortIndex) : (sortIndex > nbrSortIndex))
209  {
210  caseNo |= vtkm::Id{ 1 } << edgeNo;
211  }
212  } // inside grid
213  } // for each edge
214 
215  // we now know which edges are ascents, so we count to get the updegree
216  vtkm::Id outDegree = 0;
217  vtkm::Id neighbourComponentMask = 0;
218 
219  for (int nbrNo = 0; nbrNo < N_INCIDENT_EDGES; ++nbrNo)
220  if (LinkComponentCaseTablePortal.Get(caseNo) & (1 << nbrNo))
221  {
222  outDegree++;
223  neighbourComponentMask |= vtkm::Id{ 1 } << nbrNo;
224  }
225 
226  vtkm::Pair<vtkm::Id, vtkm::Id> re(neighbourComponentMask, outDegree);
227  return re;
228  } // GetNeighbourComponentsMaskAndDegree()
229 
230 
231 #if (defined(VTKM_GCC) || defined(VTKM_CLANG))
232 #pragma GCC diagnostic pop
233 #endif // gcc || clang
234 
235 
236 private:
242  bool GetMax;
244 
245 }; // ExecutionObjec_MeshStructure_3Dt
246 
247 } // namespace contourtree_augmented
248 } // namespace worklet
249 } // namespace vtkm
250 
251 #endif
vtkm::worklet::contourtree_augmented::MeshStructureFreudenthal3D::NeighbourOffsetsPortal
NeighbourOffsetsPortalType NeighbourOffsetsPortal
Definition: MeshStructureFreudenthal3D.h:240
vtkm::cont::ArrayHandle< vtkm::Id >
ArrayHandle.h
VTKM_EXEC
#define VTKM_EXEC
Definition: ExportMacros.h:51
vtkm
Groups connected points that have the same field value.
Definition: Atomic.h:19
vtkm::worklet::contourtree_augmented::MeshStructureFreudenthal3D::GetExtremalNeighbour
VTKM_EXEC vtkm::Id GetExtremalNeighbour(vtkm::Id sortIndex) const
Definition: MeshStructureFreudenthal3D.h:150
Types.h
VTKM_EXEC_CONT
#define VTKM_EXEC_CONT
Definition: ExportMacros.h:52
vtkm::worklet::contourtree_augmented::MeshStructureFreudenthal3D::GetMaxNumberOfNeighbours
VTKM_EXEC vtkm::Id GetMaxNumberOfNeighbours() const
Definition: MeshStructureFreudenthal3D.h:120
vtkm::cont::ArrayHandle::PrepareForInput
VTKM_CONT ReadPortalType PrepareForInput(vtkm::cont::DeviceAdapterId device, vtkm::cont::Token &token) const
Prepares this array to be used as an input to an operation in the execution environment.
Definition: ArrayHandle.h:574
Pair.h
vtkm::worklet::contourtree_augmented::MeshStructureFreudenthal3D
Definition: MeshStructureFreudenthal3D.h:73
vtkm::worklet::contourtree_augmented::MeshStructureFreudenthal3D::LinkComponentCaseTablePortal
LinkComponentCaseTablePortalType LinkComponentCaseTablePortal
Definition: MeshStructureFreudenthal3D.h:241
N_INCIDENT_EDGES
#define N_INCIDENT_EDGES
Definition: Mesh2D_DEM_Triangulation_Macros.h:75
vtkm::worklet::contourtree_augmented::MeshStructureFreudenthal3D::MeshStructureFreudenthal3D
MeshStructureFreudenthal3D(vtkm::Id3 meshSize, vtkm::Id nincident_edges, bool getmax, const IdArrayType &sortIndices, const IdArrayType &sortOrder, const m3d_freudenthal::EdgeBoundaryDetectionMasksType &edgeBoundaryDetectionMasksIn, const m3d_freudenthal::NeighbourOffsetsType &neighbourOffsetsIn, const m3d_freudenthal::LinkComponentCaseTableType &linkComponentCaseTableIn, vtkm::cont::DeviceAdapterId device, vtkm::cont::Token &token)
Definition: MeshStructureFreudenthal3D.h:96
vtkm::worklet::contourtree_augmented::MeshStructureFreudenthal3D::GetNeighbourComponentsMaskAndDegree
VTKM_EXEC vtkm::Pair< vtkm::Id, vtkm::Id > GetNeighbourComponentsMaskAndDegree(vtkm::Id sortIndex, bool getMaxComponents) const
Definition: MeshStructureFreudenthal3D.h:184
vtkm::worklet::contourtree_augmented::MeshStructureFreudenthal3D::NumIncidentEdge
vtkm::Id NumIncidentEdge
Definition: MeshStructureFreudenthal3D.h:243
vtkm::worklet::contourtree_augmented::TERMINAL_ELEMENT
constexpr vtkm::Id TERMINAL_ELEMENT
Definition: filter/scalar_topology/worklet/contourtree_augmented/Types.h:74
vtkm::worklet::contourtree_augmented::MeshStructureFreudenthal3D::SortOrderPortal
SortIndicesPortalType SortOrderPortal
Definition: MeshStructureFreudenthal3D.h:238
vtkm::cont::ArrayHandle< vtkm::Id >::ReadPortalType
typename StorageType::ReadPortalType ReadPortalType
Definition: ArrayHandle.h:294
vtkm::Id
vtkm::Int32 Id
Represents an ID (index into arrays).
Definition: Types.h:191
vtkm::worklet::contourtree_augmented::data_set_mesh::MeshStructure3D::VertexPos
VTKM_EXEC vtkm::Id3 VertexPos(vtkm::Id v) const
Definition: MeshStructure3D.h:91
vtkm::cont::Token
A token to hold the scope of an ArrayHandle or other object.
Definition: Token.h:35
vtkm::worklet::contourtree_augmented::MeshStructureFreudenthal3D::LinkComponentCaseTablePortalType
m3d_freudenthal::LinkComponentCaseTableType::ReadPortalType LinkComponentCaseTablePortalType
Definition: MeshStructureFreudenthal3D.h:84
vtkm::worklet::contourtree_augmented::MeshStructureFreudenthal3D::GetMax
bool GetMax
Definition: MeshStructureFreudenthal3D.h:242
vtkm::worklet::contourtree_augmented::MeshStructureFreudenthal3D::SortIndicesPortal
SortIndicesPortalType SortIndicesPortal
Definition: MeshStructureFreudenthal3D.h:237
vtkm::Int8
int8_t Int8
Definition: Types.h:156
vtkm::worklet::contourtree_augmented::data_set_mesh::MeshStructure3D::MeshStructure3D
VTKM_EXEC_CONT MeshStructure3D()
Definition: MeshStructure3D.h:72
vtkm::worklet::contourtree_augmented::MeshStructureFreudenthal3D::SortIndicesPortalType
IdArrayType::ReadPortalType SortIndicesPortalType
Definition: MeshStructureFreudenthal3D.h:76
Types.h
vtkm::worklet::contourtree_augmented::MeshStructureFreudenthal3D::MeshStructureFreudenthal3D
VTKM_EXEC_CONT MeshStructureFreudenthal3D()
Definition: MeshStructureFreudenthal3D.h:88
vtkm::worklet::contourtree_augmented::MeshStructureFreudenthal3D::GetNeighbourIndex
VTKM_EXEC vtkm::Id GetNeighbourIndex(vtkm::Id sortIndex, vtkm::Id edgeNo) const
Definition: MeshStructureFreudenthal3D.h:124
ArrayHandleGroupVec.h
vtkm::worklet::contourtree_augmented::data_set_mesh::MeshStructure3D::MeshSize
vtkm::Id3 MeshSize
Definition: MeshStructure3D.h:137
vtkm::cont::DeviceAdapterId
Definition: DeviceAdapterTag.h:52
vtkm::Vec< vtkm::Id, 3 >
vtkm::worklet::contourtree_augmented::data_set_mesh::MeshStructure3D
Definition: MeshStructure3D.h:68
MeshStructure3D.h
vtkm::cont::ArrayHandleGroupVec< vtkm::cont::ArrayHandle< vtkm::IdComponent >, 3 >
vtkm::Pair
A vtkm::Pair is essentially the same as an STL pair object except that the methods (constructors and ...
Definition: Pair.h:29
vtkm::worklet::contourtree_augmented::MeshStructureFreudenthal3D::EdgeBoundaryDetectionMasksPortal
EdgeBoundaryDetectionMasksPortalType EdgeBoundaryDetectionMasksPortal
Definition: MeshStructureFreudenthal3D.h:239
vtkm::worklet::contourtree_augmented::MeshStructureFreudenthal3D::NeighbourOffsetsPortalType
m3d_freudenthal::NeighbourOffsetsType::ReadPortalType NeighbourOffsetsPortalType
Definition: MeshStructureFreudenthal3D.h:81
vtkm::worklet::contourtree_augmented::MeshStructureFreudenthal3D::EdgeBoundaryDetectionMasksPortalType
m3d_freudenthal::EdgeBoundaryDetectionMasksType::ReadPortalType EdgeBoundaryDetectionMasksPortalType
Definition: MeshStructureFreudenthal3D.h:79
Types.h