VTK-m  2.0
BoundaryTree.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_distributed_boundary_tree_h
54 #define vtk_m_worklet_contourtree_distributed_boundary_tree_h
55 
56 #include <vtkm/Types.h>
61 
62 #include <sstream>
63 #include <string>
64 #include <utility>
65 
66 namespace vtkm
67 {
68 namespace worklet
69 {
70 namespace contourtree_distributed
71 {
72 
82 { // class BoundaryTree
83 public:
84  // for each vertex, we store the index
86 
87  // and the ID of the vertex it connects to (or NO_SUCH_ELEMENT)
89 
90  // Total size of the boundary (used for logging only!)
92 
93  // Total number of boundary points used (used for logging only!).
94  // If the whole boundary is used then NumBoundaryUsed == NumBoundary
95  // but if only the boundary critical points are being used then
96  // NumBoundaryUsed >= NumBoundary
98 
99  // constructor
101 
102  // prints the contents of the BRACT for comparison with sweep and merge
103  std::string Print();
104 
105  // secondary version which takes the mesh as a parameter
106  template <typename Mesh, typename FieldArrayType>
107  std::string PrintGlobalDot(const char* label,
108  const Mesh& mesh,
109  const FieldArrayType& fieldArray,
110  const vtkm::Id3 blockOrigin,
111  const vtkm::Id3 blockSize,
112  const vtkm::Id3 globalSize) const;
113 
114  // prints the contents of the BRACT as a dot file using global IDs (version for CT mesh)
115  template <typename FieldType>
116  std::string PrintGlobalDot(
117  const char* label,
119 
120  // prints the contents of the BRACT in debug format
121  void PrintContent(std::ostream& outStream) const;
122  std::string DebugPrint(const char* message, const char* fileName, long lineNum) const;
123  inline std::string PrintArraySizes() const;
124 }; // class BoundaryTree
125 
126 
127 // prints the contents of the BRACT for comparison with sweep and merge
128 inline std::string BoundaryTree::Print()
129 { // Print
130  // Use string steam to record text so the user can print it however they like
131  std::stringstream resultStream;
132  resultStream << "Boundary-Restricted Augmented Contour Tree" << std::endl;
133  resultStream << "==========================================" << std::endl;
134  // fill it up
135  // We use regular ReadPortal here since we need access to all values anyways
136  auto superarcsPortal = this->Superarcs.ReadPortal();
137  auto vertexIndexPortal = this->VertexIndex.ReadPortal();
138  for (vtkm::Id node = 0; node < superarcsPortal.GetNumberOfValues(); node++)
139  {
140  // retrieve ID of target supernode
141  vtkm::Id from = vertexIndexPortal.Get(node);
142  vtkm::Id to = superarcsPortal.Get(node);
143  // if this is true, it is the last pruned vertex & is omitted
145  {
146  continue;
147  }
148  // print out the from & to
149  resultStream << std::setw(vtkm::worklet::contourtree_augmented::PRINT_WIDTH) << from << " ";
150  resultStream << std::setw(vtkm::worklet::contourtree_augmented::PRINT_WIDTH) << to << std::endl;
151  }
152  return resultStream.str();
153 } // Print
154 
155 // secondary version which takes the mesh as a parameter
156 template <typename Mesh, typename FieldArrayType>
157 std::string BoundaryTree::PrintGlobalDot(const char* label,
158  const Mesh& mesh,
159  const FieldArrayType& fieldArray,
160  const vtkm::Id3 blockOrigin,
161  const vtkm::Id3 blockSize,
162  const vtkm::Id3 globalSize) const
163 { // PrintGlobalDot
164  VTKM_IS_ARRAY_HANDLE(FieldArrayType);
165  std::stringstream resultStream;
166  // print the header information
167  resultStream << "digraph BRACT" << std::endl;
168  resultStream << "\t{" << std::endl;
169  resultStream << "\tlabel=\"" << label << "\"\n\tlabelloc=t\n\tfontsize=30" << std::endl;
170  // create a relabeler
172  blockOrigin, blockSize, globalSize);
173 
174  // loop through all nodes
175  // We use regular ReadPortal here since we need access to most values anyways
176  auto vertexIndexPortal = this->VertexIndex.ReadPortal();
177  auto superarcsPortal = this->Superarcs.ReadPortal();
178  auto sortOrderPortal = mesh.SortOrder.ReadPortal();
179  auto fieldArrayPortal = fieldArray.ReadPortal();
180  for (vtkm::Id node = 0; node < this->Superarcs.GetNumberOfValues(); node++)
181  {
182  // now convert to mesh IDs from node IDs
183  vtkm::Id from = vertexIndexPortal.Get(node);
184  // find the local & global IDs & data value
185  vtkm::Id fromLocal = sortOrderPortal.Get(from);
186  vtkm::Id fromGlobal = relabeler(fromLocal);
187  auto fromValue = fieldArrayPortal.Get(fromLocal);
188 
189  // print the vertex
190  resultStream << node << " [style=filled,fillcolor="
191  << "grey"
192  << ",label=\"" << fromGlobal << "\\nv" << fromValue << "\"];" << std::endl;
193  }
194 
195  for (vtkm::Id node = 0; node < this->Superarcs.GetNumberOfValues(); node++)
196  {
197  // retrieve ID of target supernode
198  vtkm::Id to = superarcsPortal.Get(node);
199  // if this is true, it is the last pruned vertex & is omitted
201  {
202  continue;
203  }
204  if (node < to)
205  {
206  resultStream << to << " -> " << node << std::endl;
207  }
208  else
209  {
210  resultStream << node << " -> " << to << std::endl;
211  }
212  }
213  resultStream << "\t}" << std::endl;
214  // return the result
215  return resultStream.str();
216 } // PrintGlobalDot
217 
218 // prints the contents of the BRACT as a dot file using global IDs (version for CT mesh)
219 template <typename FieldType>
221  const char* label,
223 { //PrintGlobalDot
224  std::stringstream resultStream;
225  // print the header information
226  resultStream << "digraph BRACT\n\t{\n";
227  resultStream << "\tsize=\"6.5, 9\"\n\tratio=\"fill\"\n";
228  resultStream << "\tlabel=\"" << label << "\"\n\tlabelloc=t\n\tfontsize=30\n" << std::endl;
229 
230  // loop through all nodes
231  // We use regular ReadPortal here since we need access to all values anyways
232  auto vertexIndexPortal = this->VertexIndex.ReadPortal();
233  auto globalMeshIndexPortal = mesh.GlobalMeshIndex.ReadPortal();
234  auto sortedValuesPortal = mesh.SortedValues.ReadPortal();
235  auto superarcsPortal = this->Superarcs.ReadPortal();
236  for (vtkm::Id node = 0; node < this->VertexIndex.GetNumberOfValues(); node++)
237  { // per node
238  // work out the node and it's value
239  vtkm::Id meshIndex = vertexIndexPortal.Get(node);
240  vtkm::Id from = globalMeshIndexPortal.Get(meshIndex);
241  auto fromValue = sortedValuesPortal.Get(meshIndex);
242  // print the vertex
243  resultStream << node << " [style=filled,fillcolor="
244  << "grey"
245  << ",label=\"" << from << "\\nv" << fromValue << "\"];" << std::endl;
246  } // per node
247 
248 
249  for (vtkm::Id node = 0; node < this->Superarcs.GetNumberOfValues(); node++)
250  { // per node
251  // retrieve ID of target supernode
252  vtkm::Id to = superarcsPortal.Get(node);
253  // if this is true, it is the last pruned vertex & is omitted
255  {
256  continue;
257  }
258  if (node < to)
259  {
260  resultStream << to << " -> " << node << std::endl;
261  }
262  else
263  {
264  resultStream << node << " -> " << to << std::endl;
265  }
266  } // per node
267  resultStream << "\t}" << std::endl;
268  // Return the resulting strin
269  return resultStream.str();
270 } //PrintGlobalDot
271 
272 // debug routine
273 inline void BoundaryTree::PrintContent(std::ostream& outStream) const
274 {
276  outStream);
278  "Vertex Index", this->VertexIndex, -1, outStream);
279  vtkm::worklet::contourtree_augmented::PrintIndices("Superarcs", this->Superarcs, -1, outStream);
280 }
281 
282 inline std::string BoundaryTree::DebugPrint(const char* message,
283  const char* fileName,
284  long lineNum) const
285 { // DebugPrint
286  std::stringstream resultStream;
287 #ifdef DEBUG_PRINT
288  resultStream << "[CUTHERE]-------------------------------------------------------" << std::endl;
289  resultStream << std::setw(30) << std::left << fileName << ":" << std::right << std::setw(4)
290  << lineNum << std::endl;
291  resultStream << std::left << std::string(message) << std::endl;
292  resultStream << "Boundary Restricted Augmented Contour Tree Contains: " << std::endl;
293  resultStream << "----------------------------------------------------------------" << std::endl;
294 
295  this->PrintContent(resultStream);
296 
297  resultStream << "---------------------------" << std::endl;
298  resultStream << std::endl;
299  resultStream << std::flush;
300 #else
301  (void)message;
302  (void)fileName;
303  (void)lineNum;
304 #endif
305  return resultStream.str();
306 } // DebugPrint
307 
308 inline std::string BoundaryTree::PrintArraySizes() const
309 { // PrintArraySizes
310  std::stringstream arraySizeLog;
311  arraySizeLog << std::setw(42) << std::left << " #VertexIndex"
312  << ": " << this->VertexIndex.GetNumberOfValues() << std::endl
313  << std::setw(42) << std::left << " #Superarcs"
314  << ": " << this->Superarcs.GetNumberOfValues() << std::endl
315  << std::setw(42) << std::left << " #Boundary"
316  << ": " << this->NumBoundary << std::endl
317  << std::setw(42) << std::left << " #BoundaryUsed"
318  << ": " << this->NumBoundaryUsed << std::endl;
319  return arraySizeLog.str();
320 } // PrintArraySizes
321 
322 
323 
324 } // namespace contourtree_distributed
325 } // namespace worklet
326 } // namespace vtkm
327 
328 #endif
vtkm::worklet::contourtree_augmented::ContourTreeMesh::GlobalMeshIndex
IdArrayType GlobalMeshIndex
Definition: ContourTreeMesh.h:200
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< vtkm::Id >
vtkm::worklet::contourtree_distributed::BoundaryTree::PrintGlobalDot
std::string PrintGlobalDot(const char *label, const Mesh &mesh, const FieldArrayType &fieldArray, const vtkm::Id3 blockOrigin, const vtkm::Id3 blockSize, const vtkm::Id3 globalSize) const
Definition: BoundaryTree.h:157
vtkm
Groups connected points that have the same field value.
Definition: Atomic.h:19
Types.h
PrintVectors.h
vtkm::worklet::contourtree_augmented::ContourTreeMesh
Definition: ContourTreeMesh.h:129
vtkm::Id
vtkm::Int32 Id
Represents an ID (index into arrays).
Definition: Types.h:191
vtkm::worklet::contourtree_distributed::BoundaryTree::DebugPrint
std::string DebugPrint(const char *message, const char *fileName, long lineNum) const
Definition: BoundaryTree.h:282
vtkm::worklet::contourtree_distributed::BoundaryTree::VertexIndex
vtkm::worklet::contourtree_augmented::IdArrayType VertexIndex
Definition: BoundaryTree.h:85
vtkm::worklet::contourtree_augmented::NoSuchElement
VTKM_EXEC_CONT bool NoSuchElement(vtkm::Id flaggedIndex)
Definition: filter/scalar_topology/worklet/contourtree_augmented/Types.h:97
vtkm::worklet::contourtree_distributed::BoundaryTree::Print
std::string Print()
Definition: BoundaryTree.h:128
IdRelabeler.h
vtkm::worklet::contourtree_distributed::BoundaryTree::NumBoundary
vtkm::Id NumBoundary
Definition: BoundaryTree.h:91
ContourTreeMesh.h
VTKM_IS_ARRAY_HANDLE
#define VTKM_IS_ARRAY_HANDLE(T)
Definition: ArrayHandle.h:132
vtkm::worklet::contourtree_augmented::ContourTreeMesh::SortedValues
vtkm::cont::ArrayHandle< FieldType > SortedValues
Definition: ContourTreeMesh.h:199
vtkm::worklet::contourtree_distributed::BoundaryTree::NumBoundaryUsed
vtkm::Id NumBoundaryUsed
Definition: BoundaryTree.h:97
Types.h
vtkm::worklet::contourtree_distributed::BoundaryTree::PrintArraySizes
std::string PrintArraySizes() const
Definition: BoundaryTree.h:308
vtkm::worklet::contourtree_augmented::mesh_dem::IdRelabeler
A utility class that converts Ids from local to global given a mesh.
Definition: IdRelabeler.h:79
vtkm::Vec< vtkm::Id, 3 >
vtkm::worklet::contourtree_distributed::BoundaryTree
Boundary Restricted Augmented Contour Tree (BRACT)
Definition: BoundaryTree.h:81
vtkm::worklet::contourtree_distributed::BoundaryTree::PrintContent
void PrintContent(std::ostream &outStream) const
Definition: BoundaryTree.h:273
vtkm::cont::ArrayHandle::ReadPortal
VTKM_CONT ReadPortalType ReadPortal() const
Get an array portal that can be used in the control environment.
Definition: ArrayHandle.h:414
vtkm::worklet::contourtree_augmented::PrintIndices
void PrintIndices(std::string label, const vtkm::cont::ArrayHandle< T > &iVec, vtkm::Id nIndices=-1, std::ostream &outStream=std::cout)
Definition: augmented/PrintVectors.h:253
vtkm::worklet::contourtree_augmented::PrintHeader
void PrintHeader(vtkm::Id howMany, std::ostream &outStream=std::cout)
Definition: augmented/PrintVectors.h:151
vtkm::worklet::contourtree_augmented::PRINT_WIDTH
constexpr int PRINT_WIDTH
Definition: augmented/PrintVectors.h:75
vtkm::worklet::contourtree_distributed::BoundaryTree::Superarcs
vtkm::worklet::contourtree_augmented::IdArrayType Superarcs
Definition: BoundaryTree.h:88
vtkm::worklet::contourtree_distributed::BoundaryTree::BoundaryTree
BoundaryTree()
Definition: BoundaryTree.h:100