Mesh Oriented datABase  (version 5.5.0)
An array-based unstructured mesh library
Tree.hpp
Go to the documentation of this file.
1 /**\file Tree.hpp
2  * \class moab::Tree
3  * \brief Parent class of various tree types in MOAB
4  */
5 
6 #ifndef MOAB_TREE_HPP
7 #define MOAB_TREE_HPP
8 
9 #include "moab/Interface.hpp"
10 #include "moab/BoundBox.hpp"
11 #include "moab/CartVect.hpp"
12 #include "moab/FileOptions.hpp"
13 #include "moab/TreeStats.hpp"
14 
15 #include <string>
16 #include <vector>
17 #include <cmath>
18 #include <cassert>
19 
20 namespace moab
21 {
22 
23 class Interface;
24 class Range;
25 class ElemEvaluator;
26 
27 class Tree
28 {
29  public:
30  /** \brief Constructor (bare)
31  * \param iface MOAB instance
32  */
33  Tree( Interface* iface );
34 
35  /** \brief Destructor
36  */
37  virtual ~Tree();
38 
39  /** \brief Destroy the tree maintained by this object, optionally checking we have the right
40  * root. \param root If non-NULL, check that this is the root, return failure if not
41  */
42  virtual ErrorCode reset_tree() = 0;
43 
44  /** \brief Delete the entity sets associated with the tree, starting with the root and
45  * traversing children
46  */
48 
49  /** Build the tree
50  * Build a tree with the entities input. If a non-NULL tree_root_set pointer is input,
51  * use the pointed-to set as the root of this tree (*tree_root_set!=0) otherwise construct
52  * a new root set and pass its handle back in *tree_root_set. Options vary by tree type,
53  * with a few common to all types of trees. Common options:
54  * MAX_PER_LEAF: max entities per leaf; default = 6
55  * MAX_DEPTH: max depth of the tree; default = 30
56  * MIN_WIDTH: minimum width of box, used like a tolerance; default = 1.0e-10
57  * MESHSET_FLAGS: flags passed into meshset creation for tree nodes; should be a value from
58  * ENTITY_SET_PROPERTY (see Types.hpp); default = MESHSET_SET
59  * CLEAN_UP: if false, do not delete tree sets upon tree class destruction; default = true
60  * TAG_NAME: tag name to store tree information on tree nodes; default determined by tree type
61  * \param entities Entities with which to build the tree
62  * \param tree_root Root set for tree (see function description)
63  * \param opts Options for tree (see function description)
64  * \return Error is returned only on build failure
65  */
67  EntityHandle* tree_root_set = NULL,
68  FileOptions* options = NULL ) = 0;
69 
70  /** \brief Get bounding box for tree below tree_node, or entire tree
71  * If no tree has been built yet, returns +/- DBL_MAX for all dimensions. Note for some tree
72  * types, boxes are not available for non-root nodes, and this function will return failure if
73  * non-root is passed in \param box The box for this tree \param tree_node If non-NULL, node for
74  * which box is requested, tree root if NULL \return Only returns error on fatal condition
75  */
76  virtual ErrorCode get_bounding_box( BoundBox& box, EntityHandle* tree_node = NULL ) const;
77 
78  /** \brief Return some basic information about the tree
79  * Stats are returned for tree starting from input node or tree root (root = 0)
80  * \param root If non-0, give stats below and including root
81  * \param min Minimum corner of bounding box
82  * \param max Maximum corner of bounding box
83  * \param max_dep Maximum depth of tree below root
84  */
85  virtual ErrorCode get_info( EntityHandle root, double min[3], double max[3], unsigned int& max_dep );
86 
87  /** \brief Find all trees, by bounding box tag
88  */
89  ErrorCode find_all_trees( Range& results );
90 
91  /** \brief Get leaf containing input position.
92  *
93  * Does not take into account global bounding box of tree.
94  * - Therefore there is always one leaf containing the point.
95  * - If caller wants to account for global bounding box, then
96  * caller can test against that box and not call this method
97  * at all if the point is outside the box, as there is no leaf
98  * containing the point in that case.
99  * \param point Point to be located in tree
100  * \param leaf_out Leaf containing point
101  * \param iter_tol Tolerance for convergence of point search
102  * \param inside_tol Tolerance for inside element calculation
103  * \param multiple_leaves Some tree types can have multiple leaves containing a point;
104  * if non-NULL, this parameter is returned true if multiple leaves contain
105  * the input point
106  * \param start_node Start from this tree node (non-NULL) instead of tree root (NULL)
107  * \return Non-success returned only in case of failure; not-found indicated by leaf_out=0
108  */
109  virtual ErrorCode point_search( const double* point,
110  EntityHandle& leaf_out,
111  const double iter_tol = 1.0e-10,
112  const double inside_tol = 1.0e-6,
113  bool* multiple_leaves = NULL,
114  EntityHandle* start_node = NULL,
115  CartVect* params = NULL ) = 0;
116 
117  /** \brief Find all leaves within a given distance from point
118  * If dists_out input non-NULL, also returns distances from each leaf; if
119  * point i is inside leaf, 0 is given as dists_out[i].
120  * If params_out is non-NULL and myEval is non-NULL, will evaluate individual entities
121  * in tree nodes and return containing entities in leaves_out. In those cases, if params_out
122  * is also non-NULL, will return parameters in those elements in that vector.
123  * \param point Point to be located in tree
124  * \param distance Distance within which to query
125  * \param leaves_out Leaves within distance or containing point
126  * \param iter_tol Tolerance for convergence of point search
127  * \param inside_tol Tolerance for inside element calculation
128  * \param dists_out If non-NULL, will contain distsances to leaves
129  * \param params_out If non-NULL, will contain parameters of the point in the ents in leaves_out
130  * \param start_node Start from this tree node (non-NULL) instead of tree root (NULL)
131  */
132  virtual ErrorCode distance_search( const double* point,
133  const double distance,
134  std::vector< EntityHandle >& leaves_out,
135  const double iter_tol = 1.0e-10,
136  const double inside_tol = 1.0e-6,
137  std::vector< double >* dists_out = NULL,
138  std::vector< CartVect >* params_out = NULL,
139  EntityHandle* start_node = NULL ) = 0;
140 
141  /** \brief Return the MOAB interface associated with this tree
142  */
144  {
145  return mbImpl;
146  }
147 
148  /** \brief Return the MOAB interface associated with this tree
149  */
150  const Interface* moab() const
151  {
152  return mbImpl;
153  }
154 
155  /** \brief Get max depth set on tree */
156  double get_max_depth()
157  {
158  return maxDepth;
159  }
160 
161  /** \brief Get max entities per leaf set on tree */
163  {
164  return maxPerLeaf;
165  }
166 
167  /** \brief Get tree traversal stats object */
169  {
170  return treeStats;
171  }
172 
173  /** \brief Get tree traversal stats object */
174  const TreeStats& tree_stats() const
175  {
176  return treeStats;
177  }
178 
179  /** \brief Create tree root and tag with bounding box
180  */
181  ErrorCode create_root( const double box_min[3], const double box_max[3], EntityHandle& root_handle );
182 
183  //! print various things about this tree
184  virtual ErrorCode print() = 0;
185 
186  //! get/set the ElemEvaluator
188  {
189  return myEval;
190  }
191 
192  //! get/set the ElemEvaluator
193  inline void set_eval( ElemEvaluator* eval )
194  {
195  myEval = eval;
196  }
197 
198  /** \brief Parse options for this tree, including common options for all trees
199  * \param opts Options
200  */
201  virtual ErrorCode parse_options( FileOptions& opts ) = 0;
202 
203  protected:
204  /** \brief Parse options common to all trees
205  * \param options Options for representing tree; see Tree::build_tree() and subclass
206  * build_tree() functions for allowed options \return Non-success returned from base class
207  * function only under catastrophic circumstances; derived classes also can recognize
208  * subclass-specific options
209  */
211 
212  /** \brief Get the box tag, possibly constructing it first
213  * \param create_if_missing If true and it has not been made yet, make it
214  */
215  Tag get_box_tag( bool create_if_missing = true );
216 
217  // moab instance
219 
220  // bounding box for entire tree
222 
223  // max entities per leaf
225 
226  // max depth of tree
227  int maxDepth;
228 
229  // tree depth, set by build_tree
231 
232  // min width of box, handled like tolerance
233  double minWidth;
234 
235  // meshset creation flags
236  unsigned int meshsetFlags;
237 
238  // clean up flag
239  bool cleanUp;
240 
241  // tree root
243 
244  // tag used to mark bounding box of nodes
246 
247  // tag name used for boxTag
248  std::string boxTagName;
249 
250  // tree traversal stats
252 
253  // element evaluator
255 };
256 
258  : mbImpl( iface ), maxPerLeaf( 6 ), maxDepth( 30 ), treeDepth( -1 ), minWidth( 1.0e-10 ), meshsetFlags( 0 ),
259  cleanUp( true ), myRoot( 0 ), boxTag( 0 ), myEval( 0 )
260 {
261 }
262 
263 inline Tree::~Tree() {}
264 
265 inline ErrorCode Tree::get_bounding_box( BoundBox& box, EntityHandle* tree_node ) const
266 {
267  if( ( tree_node && *tree_node == myRoot ) || !tree_node )
268  {
269  box = boundBox;
270  return MB_SUCCESS;
271  }
272  else
273  return MB_FAILURE;
274 }
275 
277  double* /*min[3]*/,
278  double* /* max[3]*/,
279  unsigned int& /*dep*/ )
280 {
281  return MB_NOT_IMPLEMENTED;
282 }
283 
284 inline Tag Tree::get_box_tag( bool create_if_missing )
285 {
286  if( !boxTag && create_if_missing )
287  {
288  assert( boxTagName.length() > 0 );
289  ErrorCode rval =
291  if( MB_INVALID_SIZE == rval )
292  {
293  // delete the tag and get it again, legacy file...
294  rval = moab()->tag_delete( boxTag );
295  if( MB_SUCCESS != rval ) return 0;
296  boxTag = 0;
297  return get_box_tag( true );
298  }
299 
300  if( MB_SUCCESS != rval ) return 0;
301  }
302 
303  return boxTag;
304 }
305 
306 } // namespace moab
307 
308 #endif