quadtree.h
Go to the documentation of this file.
1 //LIC// ====================================================================
2 //LIC// This file forms part of oomph-lib, the object-oriented,
3 //LIC// multi-physics finite-element library, available
4 //LIC// at http://www.oomph-lib.org.
5 //LIC//
6 //LIC// Version 1.0; svn revision $LastChangedRevision$
7 //LIC//
8 //LIC// $LastChangedDate$
9 //LIC//
10 //LIC// Copyright (C) 2006-2016 Matthias Heil and Andrew Hazel
11 //LIC//
12 //LIC// This library is free software; you can redistribute it and/or
13 //LIC// modify it under the terms of the GNU Lesser General Public
14 //LIC// License as published by the Free Software Foundation; either
15 //LIC// version 2.1 of the License, or (at your option) any later version.
16 //LIC//
17 //LIC// This library is distributed in the hope that it will be useful,
18 //LIC// but WITHOUT ANY WARRANTY; without even the implied warranty of
19 //LIC// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 //LIC// Lesser General Public License for more details.
21 //LIC//
22 //LIC// You should have received a copy of the GNU Lesser General Public
23 //LIC// License along with this library; if not, write to the Free Software
24 //LIC// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
25 //LIC// 02110-1301 USA.
26 //LIC//
27 //LIC// The authors may be contacted at oomph-lib@maths.man.ac.uk.
28 //LIC//
29 //LIC//====================================================================
30 //Header file for quadtree and quadtree forest classes
31 #ifndef OOMPH_QUADTREE_HEADER
32 #define OOMPH_QUADTREE_HEADER
33 
34 
35 // Config header generated by autoconfig
36 #ifdef HAVE_CONFIG_H
37  #include <oomph-lib-config.h>
38 #endif
39 
40 #ifdef OOMPH_HAS_MPI
41 #include "mpi.h"
42 #endif
43 
44 //OOMPH-LIB headers
45 #include "tree.h"
46 #include "matrices.h"
47 
48 
49 
50 namespace oomph
51 {
52 
53 //====================================================================
54 /// Namespace for QuadTree directions
55 //====================================================================
56 namespace QuadTreeNames
57 {
58  /// \short Directions. OMEGA is used if a direction is undefined
59  /// in a certain context
60  enum{SW,SE,NW,NE,N,E,S,W,OMEGA=26};
61 };
62 
63 // Forward class definition for class representing the root of a QuadTree
64 class QuadTreeRoot;
65 
66 //================================================================
67 /// QuadTree class: Recursively defined, generalised quadtree.
68 ///
69 /// A QuadTree has:
70 /// - a pointer to the object (of type RefineableQElement<2>) that it
71 /// represents in a mesh refinement context.
72 /// - Vector of pointers to its four (SW/SE/NW/NE) sons (which are
73 /// themselves quadtrees).
74 /// If the Vector of pointers to the sons has zero length,
75 /// the QuadTree is a "leaf node" in the overall quadtree.
76 /// - a pointer to its father. If this pointer is NULL, the QuadTree is the
77 /// the root node of the overall quadtree.
78 /// This data is stored in the Tree base class.
79 ///
80 /// The tree can also be part of a forest. If that is the case, the root
81 /// will have pointers to the roots of neighbouring quadtrees.
82 ///
83 /// The objects contained in the quadtree are assumed to be
84 /// (topologically) rectangular elements whose geometry is
85 /// parametrised by local coordinates \f$ {\bf s} \in [-1,1]^2 \f$.
86 ///
87 /// The tree can be traversed and actions performed
88 /// at all its "nodes" or only at the leaf "nodes" ("nodes" without sons).
89 ///
90 /// Finally, the leaf "nodes" can be split depending on
91 /// a criteria defined by the object.
92 ///
93 /// Note that QuadTrees are only generated by splitting existing
94 /// QuadTrees. Therefore, the constructors are protected. The
95 /// only QuadTree that "Joe User" can create is
96 /// the (derived) class QuadTreeRoot.
97 //=================================================================
98 class QuadTree : public virtual Tree
99 {
100  public:
101 
102  /// \short Destructor. Note: Deleting a quadtree also deletes the
103  /// objects associated with all non-leaf nodes!
104  virtual ~QuadTree() {}
105 
106  /// Broken copy constructor
107  QuadTree(const QuadTree& dummy)
108  {
109  BrokenCopy::broken_copy("QuadTree");
110  }
111 
112  /// Broken assignment operator
113  void operator=(const QuadTree&)
114  {
115  BrokenCopy::broken_assign("QuadTree");
116  }
117 
118  /// \short Overload the function construct_son to ensure that the son
119  /// is a specific QuadTree and not a general Tree.
121  Tree* const &father_pt, const int &son_type)
122  {
123  QuadTree* temp_quad_pt = new QuadTree(object_pt,father_pt,son_type);
124  return temp_quad_pt;
125  }
126 
127  /// \short Return pointer to greater or equal-sized edge neighbour
128  /// in specified \c direction; also provide info regarding the relative
129  /// size and orientation of neighbour:
130  /// - The vector translate_s turns the index of the local coordinate
131  /// in the present quadtree into that of the neighbour. If there are no
132  /// rotations then translate_s[i] = i, but if, for example, the neighbour's
133  /// eastern face is adjacent to our northern face translate_s[0] = 1
134  /// and translate_s[1] = 0. Of course, this could be deduced after the
135  /// fact, but it's easier to do it here.
136  /// - In the present quadtree, the lower left (south west) vertex is
137  /// located at local coordinates (-1,-1). This point is located
138  /// at the local coordinates (\c s_lo[0], \c s_lo[1]) in the neighbouring
139  /// quadtree.
140  /// - ditto with s_hi: In the present quadtree, the upper right (north east)
141  /// vertex is located at local coordinates (1,1). This point is located
142  /// at the local coordinates (\c s_hi[0], \c s_hi[1]) in the neighbouring
143  /// quadtree.
144  /// - We're looking for a neighbour in the specified \c direction. When
145  /// viewed from the neighbouring quadtree, the edge that separates
146  /// the present quadtree from its neighbour is the neighbour's \c edge
147  /// edge. If there's no rotation between the two quadtrees, this is a
148  /// simple reflection: For instance, if we're looking
149  /// for a neighhbour in the \c N [orthern] \c direction, \c edge will
150  /// be \c S [outh]
151  /// - \c diff_level <= 0 indicates the difference in refinement levels between
152  /// the two neighbours. If \c diff_level==0, the neighbour has the
153  /// same size as the current quadtree.
154  /// - \c in_neighbouring_tree indicates whether the neighbour is actually
155  /// in another tree in the forest. The introduction of this flag
156  /// was necessitated by periodic problems where a TreeRoot can be its
157  /// own neighbour.
158  QuadTree* gteq_edge_neighbour(const int& direction,
159  Vector<unsigned> &translate_s,
160  Vector<double>& s_lo, Vector<double>& s_hi,
161  int& edge, int& diff_level,
162  bool &in_neighbouring_tree) const;
163 
164  /// \short Traverse Tree: Preorder traverse and stick pointers to
165  /// neighbouring leaf nodes (only) into Vector
166  void stick_neighbouring_leaves_into_vector(
167  Vector<const QuadTree*>& tree_neighbouring_nodes,
168  Vector<Vector<double> >& tree_neighbouring_s_lo,
169  Vector<Vector<double> >& tree_neighbouring_s_hi,
170  Vector<int>& tree_neighbouring_diff_level,
171  const QuadTree* my_neigh_pt,
172  const int& direction) const;
173 
174  /// \short Self-test: Check all neighbours. Return success (0)
175  /// if the max. distance between corresponding points in the
176  /// neighbours is less than the tolerance specified in the
177  /// static value QuadTree::Max_neighbour_finding_tolerance.
178  unsigned self_test();
179 
180  /// \short Setup the static data, rotation and reflection schemes, etc
181  static void setup_static_data();
182 
183  /// \short Doc/check all neighbours of quadtree (nodes) contained in the
184  /// Vector forest_node_pt. Output into neighbours_file which can
185  /// be viewed from tecplot with QuadTreeNeighbours.mcr
186  /// Neighbour info and errors are displayed on
187  /// neighbours_txt_file. Finally, compute the max. error between
188  /// vertices when viewed from neighhbouring element.
189  /// If the two filestreams are closed, output is suppressed.
190  static void doc_neighbours(Vector<Tree*> forest_nodes_pt,
191  std::ofstream& neighbours_file,
192  std::ofstream& neighbours_txt_file,
193  double& max_error);
194 
195 
196  /// Translate (enumerated) directions into strings
198 
199  protected:
200 
201 
202  /// Default constructor (empty and broken)
204  {
205  throw OomphLibError("Don't call an empty constructor for a QuadTree object",
206  OOMPH_CURRENT_FUNCTION,OOMPH_EXCEPTION_LOCATION);
207  }
208 
209  /// \short Default constructor for empty (root) tree:
210  /// no father, no sons; just pass a pointer to its object
211  /// Protected because QuadTrees can only be created internally,
212  /// during the split operation. Only QuadTreeRoots can be
213  /// created externally.
214  QuadTree(RefineableElement* const &object_pt) : Tree(object_pt) {}
215 
216  /// \short Constructor for tree that has a father: Pass it the pointer
217  /// to its object, the pointer to its father and tell it what type
218  /// of son (SE/SW/NE/NW) it is.
219  /// Protected because QuadTrees can only be created internally,
220  /// during the split operation. Only QuadTreeRoots can be
221  /// created externally.
222  QuadTree(RefineableElement* const &object_pt,
223  Tree* const &father_pt, const int& son_type)
224  : Tree(object_pt,father_pt,son_type) {}
225 
226  /// Bool indicating that static member data has been setup
228 
229 
230  private:
231 
232  /// \short Find greater or equal-sized edge neighbour in direction.
233  /// Auxiliary internal routine which passes additional information around.
234  QuadTree* gteq_edge_neighbour(const int& direction,
235  double& s_diff,
236  int& diff_level,
237  bool& in_neighbouring_tree,
238  int max_level,
239  QuadTreeRoot* const &orig_root_pt) const;
240 
241  /// Colours for neighbours in various directions
243 
244  /// \short S_base(i,direction): Initial value for coordinate s[i] on
245  /// the edge indicated by direction (S/E/N/W)
247 
248  /// \short S_step(i,direction) Increments for coordinate s[i] when
249  /// progressing along the edge indicated by direction (S/E/N/W);
250  /// Left/lower vertex: S_base; Right/upper vertex: S_base + S_step
252 
253  /// Get opposite edge, e.g. Reflect_edge[N]=S
255 
256  /// \short Array of direction/quadrant adjacency scheme:
257  /// Is_adjacent(i_vertex_or_edge,j_quadrant): Is edge/vertex
258  /// adjacent to quadrant?
260 
261  /// \short Reflection scheme: Reflect(direction,quadrant): Get mirror
262  /// of quadrant in specified direction. E.g. Reflect(S,NE)=SE
264 
265  /// \short Rotate coordinates: If North becomes NorthIs then direction
266  /// becomes Rotate(NorthIs,direction). E.g. Rotate(E,NW)=NE;
268 
269  /// \short Angle betwen rotated coordinates: If old_direction becomes
270  /// new_direction then the angle between the axes (in anti-clockwise
271  /// direction is Rotate_angle(old_direction,new_direction); E.g.
272  /// Rotate_angle(E,N)=90;
274 
275  /// \short S_direct(direction,son_quadrant): The lower left corner
276  /// of son_quadrant has an offset of h/2 S_direct(direction,son_quadrant)
277  /// in the specified direction. E.g. S_direct(S,NE)=1 and S_direct(S,NW)=0
279 
280 };
281 
282 
283 
284 //===================================================================
285 /// QuadTreeRoot is a QuadTree that forms the root of a (recursive)
286 /// quadtree. The "root node" is special as it holds additional
287 /// information about its neighbours and their relative
288 /// rotation (inside a QuadTreeForest).
289 //==================================================================
290 class QuadTreeRoot : public virtual QuadTree, public virtual TreeRoot
291 {
292  private:
293 
294  /// \short Vector giving the north equivalent of the neighbours:
295  /// When viewed from the current quadtree's \c neighbour neighbour,
296  /// our northern direction is the neighbour's North_equivalent[neighbour]
297  /// direction. If there's no rotation, this map contains the identify
298  /// so that, e.g. \c North_equivalent[W]=N (read as: "in my Western
299  /// neighbour, my North is its North"). If the western neighbour is rotated
300  /// by 180 degrees relative to the current quadtree, say, we have
301  /// \c North_equivalent[W]=S (read as: "in my Western
302  /// neighbour, my North is its South"); etc.
304 
305  public:
306 
307  ///Constructor for the (empty) root quadtree: Pass pointer to
308  /// associated object, a RefineableQElement<2>.
309  QuadTreeRoot(RefineableElement* const &object_pt) : Tree(object_pt),
310  QuadTree(object_pt), TreeRoot(object_pt)
311  {
312 
313 #ifdef PARANOID
314  // Check that static member data has been setup
315  if (!Static_data_has_been_setup)
316  {
317  std::string error_message =
318  "Static member data hasn't been setup yet.\n";
319  error_message +=
320  "Call QuadTree::setup_static_data() before creating\n";
321  error_message += "any QuadTreeRoots\n";
322 
323  throw OomphLibError(error_message,
324  OOMPH_CURRENT_FUNCTION,
325  OOMPH_EXCEPTION_LOCATION);
326  }
327 #endif
328 
329  using namespace QuadTreeNames;
330 
331  //Initialise the North equivalents of the neighbouring QuadTreeRoots
332  North_equivalent.resize(27);
333 
334  North_equivalent[N] = N;
335  North_equivalent[E] = N;
336  North_equivalent[W] = N;
337  North_equivalent[S] = N;
338  }
339 
340 
341  /// Broken copy constructor
342  QuadTreeRoot(const QuadTreeRoot& dummy) : TreeRoot(dummy)
343  {
344  BrokenCopy::broken_copy("QuadTreeRoot");
345  }
346 
347  /// Broken assignment operator
348  void operator=(const QuadTreeRoot&)
349  {
350  BrokenCopy::broken_assign("QuadTreeRoot");
351  }
352 
353 
354  /// \short Return north equivalent of the neighbours in specified
355  /// direction: When viewed from the current quadtree's \c neighbour neighbour,
356  /// our northern direction is the neighbour's north_equivalent(neighbour)
357  /// direction. If there's no rotation, this map contains the identify
358  /// so that, e.g. \c north_equivalent(W)=N (read as: "in my Western
359  /// neighbour, my North is its North"). If the western neighbour is rotated
360  /// by 180 degrees relative to the current quadtree, say, we have
361  /// \c north_equivalent(W)=S (read as: "in my Western
362  /// neighbour, my North is its South"); etc.
363  int &north_equivalent(const int &neighbour)
364  {
365 #ifdef PARANOID
366  using namespace QuadTreeNames;
367  // Neighbour can only be located in N/S/E/W direction
368  if((neighbour!=S)&&(neighbour!=N)&&(neighbour!=W)&&(neighbour!=E))
369  {
370  std::ostringstream error_message;
371  error_message << "The neighbour can only be N,S,E,W, not"
372  << Direct_string[neighbour] << std::endl;
373 
374  throw OomphLibError(error_message.str(),
375  OOMPH_CURRENT_FUNCTION,
376  OOMPH_EXCEPTION_LOCATION);
377  }
378 #endif
379  return North_equivalent[neighbour];
380  }
381 
382 
383  /// \short If quadtree_root_pt is a neighbour, return the direction
384  /// [N/S/E/W] in which it is found, otherwise return OMEGA
385  int direction_of_neighbour(QuadTreeRoot* quadtree_root_pt)
386  {
387  using namespace QuadTreeNames;
388  if(Neighbour_pt[N]==quadtree_root_pt) {return N;}
389  if(Neighbour_pt[E]==quadtree_root_pt) {return E;}
390  if(Neighbour_pt[S]==quadtree_root_pt) {return S;}
391  if(Neighbour_pt[W]==quadtree_root_pt) {return W;}
392  //If we get here, it's not a neighbour
393  return OMEGA;
394  }
395 
396 };
397 
398 
399 
400 //================================================================
401 /// A QuadTreeForest consists of a collection of QuadTreeRoots.
402 /// Each member tree can have neighbours to its S/W/N/E
403 /// and the orientation of their compasses can differ, allowing
404 /// for complex, unstructured meshes.
405 //=================================================================
407 {
408  public:
409 
410  /// Default constructor (empty and broken)
412  {
413  //Throw an error
414  throw OomphLibError(
415  "Don't call an empty constructor for a QuadTreeForest object",
416  OOMPH_CURRENT_FUNCTION,OOMPH_EXCEPTION_LOCATION);
417  }
418 
419  /// \short Constructor: Pass vector of pointers to the roots of the
420  /// constituent QuadTrees
422 
423  /// Broken copy constructor
425  {
426  BrokenCopy::broken_copy("QuadTreeForest");
427  }
428 
429  /// Broken assignment operator
430  void operator=(const QuadTreeForest&)
431  {
432  BrokenCopy::broken_assign("QuadTreeForest");
433  }
434 
435  /// \short Destructor: Delete the constituent quadtrees (and thus
436  /// the objects associated with its non-leaf nodes!)
437  virtual ~QuadTreeForest() {}
438 
439  /// \short Document and check all the neighbours of all the nodes
440  /// in the forest. DocInfo object specifies the output directory
441  /// and file numbers for the various files. If \c doc_info.disable_doc()
442  /// has been called no output is created.
443  void check_all_neighbours(DocInfo &doc_info);
444 
445  /// \short Open output files that will store any hanging nodes in
446  /// the forest and return a vector of the streams.
447  void open_hanging_node_files(DocInfo &doc_info,
448  Vector<std::ofstream*> &output_stream);
449 
450  /// \short Self-test: Check all neighbours. Return success (0)
451  /// if the max. distance between corresponding points in the
452  /// neighbours is less than the tolerance specified in the
453  /// static value QuadTree::Max_neighbour_finding_tolerance.
454  unsigned self_test();
455 
456 private:
457 
458  /// Construct the rotation schemes
459  void construct_north_equivalents();
460 
461  /// Construct the neighbour lookup scheme
462  void find_neighbours();
463 
464  /// Return pointer to i-th root quadtree in this forest.
465  /// (Performs a dynamic cast from the TreeRoot to a
466  /// QuadTreeRoot).
467  QuadTreeRoot* quadtree_pt(const unsigned &i)
468  {return dynamic_cast<QuadTreeRoot*>(Trees_pt[i]);}
469 
470  /// \short Given the number i of the root quadtree in this forest, return
471  /// pointer to its neighbour in the specified direction. NULL
472  /// if neighbour doesn't exist. (This does the dynamic cast
473  /// from a TreeRoot to a QuadTreeRoot internally).
474  QuadTreeRoot* quad_neigh_pt(const unsigned &i, const int &direction)
475  {return dynamic_cast<QuadTreeRoot*>(Trees_pt[i]->neighbour_pt(direction));}
476 
477 };
478 
479 }
480 
481 #endif
482 
void broken_copy(const std::string &class_name)
Issue error message and terminate execution.
Vector< int > North_equivalent
Vector giving the north equivalent of the neighbours: When viewed from the current quadtree&#39;s neighbo...
Definition: quadtree.h:303
static bool Static_data_has_been_setup
Bool indicating that static member data has been setup.
Definition: quadtree.h:227
void operator=(const QuadTree &)
Broken assignment operator.
Definition: quadtree.h:113
Information for documentation of results: Directory and file number to enable output in the form RESL...
static Vector< std::string > Direct_string
Translate (enumerated) directions into strings.
Definition: quadtree.h:197
QuadTree()
Default constructor (empty and broken)
Definition: quadtree.h:203
cstr elem_len * i
Definition: cfortran.h:607
virtual ~QuadTreeForest()
Destructor: Delete the constituent quadtrees (and thus the objects associated with its non-leaf nodes...
Definition: quadtree.h:437
QuadTreeForest(const QuadTreeForest &dummy)
Broken copy constructor.
Definition: quadtree.h:424
static DenseMatrix< int > Rotate
Rotate coordinates: If North becomes NorthIs then direction becomes Rotate(NorthIs,direction). E.g. Rotate(E,NW)=NE;.
Definition: quadtree.h:267
static DenseMatrix< int > S_direct
S_direct(direction,son_quadrant): The lower left corner of son_quadrant has an offset of h/2 S_direct...
Definition: quadtree.h:278
unsigned self_test()
Self-test: Return 0 for OK.
QuadTreeRoot * quad_neigh_pt(const unsigned &i, const int &direction)
Given the number i of the root quadtree in this forest, return pointer to its neighbour in the specif...
Definition: quadtree.h:474
static DenseMatrix< int > Reflect
Reflection scheme: Reflect(direction,quadrant): Get mirror of quadrant in specified direction...
Definition: quadtree.h:263
static DenseMatrix< int > Rotate_angle
Angle betwen rotated coordinates: If old_direction becomes new_direction then the angle between the a...
Definition: quadtree.h:273
QuadTreeForest()
Default constructor (empty and broken)
Definition: quadtree.h:411
static DenseMatrix< double > S_base
S_base(i,direction): Initial value for coordinate s[i] on the edge indicated by direction (S/E/N/W) ...
Definition: quadtree.h:246
QuadTree(RefineableElement *const &object_pt)
Default constructor for empty (root) tree: no father, no sons; just pass a pointer to its object Prot...
Definition: quadtree.h:214
QuadTree(RefineableElement *const &object_pt, Tree *const &father_pt, const int &son_type)
Constructor for tree that has a father: Pass it the pointer to its object, the pointer to its father ...
Definition: quadtree.h:222
void operator=(const QuadTreeForest &)
Broken assignment operator.
Definition: quadtree.h:430
QuadTreeRoot * quadtree_pt(const unsigned &i)
Definition: quadtree.h:467
int direction_of_neighbour(QuadTreeRoot *quadtree_root_pt)
If quadtree_root_pt is a neighbour, return the direction [N/S/E/W] in which it is found...
Definition: quadtree.h:385
Tree * construct_son(RefineableElement *const &object_pt, Tree *const &father_pt, const int &son_type)
Overload the function construct_son to ensure that the son is a specific QuadTree and not a general T...
Definition: quadtree.h:120
void broken_assign(const std::string &class_name)
Issue error message and terminate execution.
int & north_equivalent(const int &neighbour)
Return north equivalent of the neighbours in specified direction: When viewed from the current quadtr...
Definition: quadtree.h:363
static DenseMatrix< double > S_step
S_step(i,direction) Increments for coordinate s[i] when progressing along the edge indicated by direc...
Definition: quadtree.h:251
std::string string(const unsigned &i)
Return the i-th string or "" if the relevant string hasn&#39;t been defined.
QuadTreeRoot(RefineableElement *const &object_pt)
Definition: quadtree.h:309
QuadTreeRoot(const QuadTreeRoot &dummy)
Broken copy constructor.
Definition: quadtree.h:342
static Vector< std::string > Colour
Colours for neighbours in various directions.
Definition: quadtree.h:242
static DenseMatrix< bool > Is_adjacent
Array of direction/quadrant adjacency scheme: Is_adjacent(i_vertex_or_edge,j_quadrant): Is edge/verte...
Definition: quadtree.h:259
void operator=(const QuadTreeRoot &)
Broken assignment operator.
Definition: quadtree.h:348
virtual ~QuadTree()
Destructor. Note: Deleting a quadtree also deletes the objects associated with all non-leaf nodes! ...
Definition: quadtree.h:104
static Vector< int > Reflect_edge
Get opposite edge, e.g. Reflect_edge[N]=S.
Definition: quadtree.h:254
QuadTree(const QuadTree &dummy)
Broken copy constructor.
Definition: quadtree.h:107