refineable_quad_mesh.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// Copyright (C) 2006-2022 Matthias Heil and Andrew Hazel
7 // LIC//
8 // LIC// This library is free software; you can redistribute it and/or
9 // LIC// modify it under the terms of the GNU Lesser General Public
10 // LIC// License as published by the Free Software Foundation; either
11 // LIC// version 2.1 of the License, or (at your option) any later version.
12 // LIC//
13 // LIC// This library is distributed in the hope that it will be useful,
14 // LIC// but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // LIC// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 // LIC// Lesser General Public License for more details.
17 // LIC//
18 // LIC// You should have received a copy of the GNU Lesser General Public
19 // LIC// License along with this library; if not, write to the Free Software
20 // LIC// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 // LIC// 02110-1301 USA.
22 // LIC//
23 // LIC// The authors may be contacted at oomph-lib@maths.man.ac.uk.
24 // LIC//
25 // LIC//====================================================================
26 #ifndef OOMPH_GENERIC_REFINEABLE_QUAD_MESH_HEADER
27 #define OOMPH_GENERIC_REFINEABLE_QUAD_MESH_HEADER
28 
29 #include <limits.h>
30 
31 #include "quad_mesh.h"
32 #include "refineable_mesh.h"
34 // Include to fill in additional_setup_shared_node_scheme() function
36 
37 namespace oomph
38 {
39  //=======================================================================
49  //=======================================================================
50  template<class ELEMENT>
51  class RefineableQuadMesh : public virtual TreeBasedRefineableMesh<ELEMENT>,
52  public virtual QuadMeshBase
53  {
54  public:
57  {
58  // QuadTree static data needs to be setup before quadtree-based mesh
59  // refinement works
61  }
62 
64  RefineableQuadMesh(const RefineableQuadMesh& dummy) = delete;
65 
67  // Commented out broken assignment operator because this can lead to a
68  // conflict warning when used in the virtual inheritence hierarchy.
69  // Essentially the compiler doesn't realise that two separate
70  // implementations of the broken function are the same and so, quite
71  // rightly, it shouts.
72  /*void operator=(const RefineableQuadMesh&) = delete;*/
73 
75  virtual ~RefineableQuadMesh() {}
76 
77 
80  virtual void setup_tree_forest()
81  {
83  }
84 
89  {
90  // A forst pointer is setup at least once when the mesh is initially
91  // created in serial and stays around
92  if (this->Forest_pt != 0)
93  {
94  // Get all the tree nodes
95  Vector<Tree*> all_tree_nodes_pt;
96  this->Forest_pt->stick_all_tree_nodes_into_vector(all_tree_nodes_pt);
97 
98  // Get min and max refinement level from the tree
99  unsigned local_min_ref = 0;
100  unsigned local_max_ref = 0;
101  this->get_refinement_levels(local_min_ref, local_max_ref);
102 
103 #ifdef OOMPH_HAS_MPI
104 
105  // Reconcile between processors: If (e.g. following
106  // distribution/pruning) the mesh has no elements on this processor)
107  // then ignore its contribution to the poll of max/min refinement levels
108  int int_local_min_ref = local_min_ref;
109 
110  if (this->nelement() == 0)
111  {
112  int_local_min_ref = INT_MAX;
113  }
114 
115  int int_min_ref = 0;
116  MPI_Allreduce(&int_local_min_ref,
117  &int_min_ref,
118  1,
119  MPI_INT,
120  MPI_MIN,
121  Comm_pt->mpi_comm());
122 
123  unsigned min_ref = unsigned(int_min_ref);
124 
125 #else
126 
127  unsigned min_ref = local_min_ref;
128 
129 #endif
130 
131  // If we have no elements there's nothing more to be done --
132  // we only came in here to participate in the communication
133  if (this->nelement() == 0)
134  {
135  // Flush the Forest's current trees
136  this->Forest_pt->flush_trees();
137 
138  // Delete the old Forest
139  delete this->Forest_pt;
140 
141  // Empty dummy vector to build empty forest
142  Vector<TreeRoot*> trees_pt;
143 
144  // Make a new (empty) Forest
145  this->Forest_pt = new QuadTreeForest(trees_pt);
146  return;
147  }
148 
149  // Vector to store trees for new Forest
150  Vector<TreeRoot*> trees_pt;
151 
152  // Loop over tree nodes (e.g. elements)
153  unsigned n_tree_nodes = all_tree_nodes_pt.size();
154  for (unsigned e = 0; e < n_tree_nodes; e++)
155  {
156  Tree* tree_pt = all_tree_nodes_pt[e];
157 
158  // If the object_pt has been flushed then we don't want to keep
159  // this tree
160  if (tree_pt->object_pt() != 0)
161  {
162  // Get the refinement level of the current tree node
163  RefineableElement* el_pt =
164  dynamic_cast<RefineableElement*>(tree_pt->object_pt());
165  unsigned level = el_pt->refinement_level();
166 
167  // If we are below the minimum refinement level, remove tree
168  if (level < min_ref)
169  {
170  // Flush sons for this tree
171  tree_pt->flush_sons();
172 
173  // Delete the tree (no recursion)
174  delete tree_pt;
175 
176  // Delete the element
177  delete el_pt;
178  }
179  else if (level == min_ref)
180  {
181  // Get the sons (if there are any) and store them
182  unsigned n_sons = tree_pt->nsons();
183  Vector<Tree*> backed_up_sons(n_sons);
184  for (unsigned i_son = 0; i_son < n_sons; i_son++)
185  {
186  backed_up_sons[i_son] = tree_pt->son_pt(i_son);
187  }
188 
189  // Make the element into a new tree-root
190  QuadTreeRoot* tree_root_pt = new QuadTreeRoot(el_pt);
191 
192  // Pass sons
193  tree_root_pt->set_son_pt(backed_up_sons);
194 
195  // Loop over sons and make the new treeroot their father
196  for (unsigned i_son = 0; i_son < n_sons; i_son++)
197  {
198  Tree* son_pt = backed_up_sons[i_son];
199 
200  // Tell the son about its new father (which is also the root)
201  son_pt->set_father_pt(tree_root_pt);
202  son_pt->root_pt() = tree_root_pt;
203 
204  // ...and then tell all the descendants too
205  Vector<Tree*> all_sons_pt;
206  son_pt->stick_all_tree_nodes_into_vector(all_sons_pt);
207  unsigned n = all_sons_pt.size();
208  for (unsigned i = 0; i < n; i++)
209  {
210  all_sons_pt[i]->root_pt() = tree_root_pt;
211  }
212  }
213 
214  // Add tree-root to the trees_pt vector
215  trees_pt.push_back(tree_root_pt);
216 
217  // Now kill the original (non-root) tree: First
218  // flush sons for this tree
219  tree_pt->flush_sons();
220 
221  // ...then delete the tree (no recursion)
222  delete tree_pt;
223  }
224  }
225  else // tree_pt->object_pt() is null, so delete tree
226  {
227  // Flush sons for this tree
228  tree_pt->flush_sons();
229 
230  // Delete the tree (no recursion)
231  delete tree_pt;
232  }
233  }
234 
235  // Flush the Forest's current trees
236  this->Forest_pt->flush_trees();
237 
238  // Delete the old Forest
239  delete this->Forest_pt;
240 
241  // Make a new Forest with the trees_pt roots created earlier
242  this->Forest_pt = new QuadTreeForest(trees_pt);
243  }
244  else // Create a new Forest from scratch in the "usual" uniform way
245  {
246  // Each finite element in the coarse base mesh gets associated
247  // with (the root of) a QuadTree. Store QuadTreeRoots in vector:
248  Vector<TreeRoot*> trees_pt;
249 
250  // Loop over all elements, build corresponding QuadTree
251  // and store QuadTreeRoots in vector:
252  unsigned n_element = this->nelement();
253  for (unsigned e = 0; e < n_element; e++)
254  {
255  // Get pointer to full element type
256  ELEMENT* el_pt = dynamic_cast<ELEMENT*>(this->element_pt(e));
257 
258  // Build associated quadtree(root) -- pass pointer to corresponding
259  // finite element and add the pointer to vector of quadtree (roots):
260  trees_pt.push_back(new QuadTreeRoot(el_pt));
261  }
262 
263  // Plant QuadTreeRoots in QuadTreeForest
264  this->Forest_pt = new QuadTreeForest(trees_pt);
265  }
266  }
267  };
268 
269 } // namespace oomph
270 
271 #endif
int i
Definition: BiCGSTAB_step_by_step.cpp:9
const unsigned n
Definition: CG3DPackingUnitTest.cpp:11
Array< double, 1, 3 > e(1./3., 0.5, 2.)
const Vector< GeneralisedElement * > & element_pt() const
Return reference to the Vector of elements.
Definition: mesh.h:460
unsigned long nelement() const
Return number of elements in the mesh.
Definition: mesh.h:590
Base class for quad meshes (meshes made of 2D quad elements).
Definition: quad_mesh.h:57
Definition: quadtree.h:409
Definition: quadtree.h:293
static void setup_static_data()
Setup the static data, rotation and reflection schemes, etc.
Definition: quadtree.cc:120
Definition: refineable_elements.h:97
unsigned refinement_level() const
Return the Refinement level.
Definition: refineable_elements.h:314
Definition: refineable_quad_mesh.h:53
virtual ~RefineableQuadMesh()
Broken assignment operator.
Definition: refineable_quad_mesh.h:75
RefineableQuadMesh(const RefineableQuadMesh &dummy)=delete
Broken copy constructor.
RefineableQuadMesh()
Constructor: Setup static quadtree data.
Definition: refineable_quad_mesh.h:56
void setup_quadtree_forest()
Definition: refineable_quad_mesh.h:88
virtual void setup_tree_forest()
Definition: refineable_quad_mesh.h:80
virtual void get_refinement_levels(unsigned &min_refinement_level, unsigned &max_refinement_level)
Get max/min refinement levels in mesh.
Definition: refineable_mesh.cc:830
TreeForest * Forest_pt
Forest representation of the mesh.
Definition: refineable_mesh.h:768
Definition: refineable_mesh.h:809
void flush_trees()
Flush trees from forest.
Definition: tree.h:472
void stick_all_tree_nodes_into_vector(Vector< Tree * > &all_forest_nodes)
Traverse forest and stick pointers to all "nodes" into Vector.
Definition: tree.cc:405
Definition: tree.h:74
void stick_all_tree_nodes_into_vector(Vector< Tree * > &)
Traverse and stick pointers to all "nodes" into Vector.
Definition: tree.cc:277
RefineableElement * object_pt() const
Definition: tree.h:88
unsigned nsons() const
Return number of sons (zero if it's a leaf node)
Definition: tree.h:129
void flush_sons()
Flush the sons.
Definition: tree.h:135
Tree * son_pt(const int &son_index) const
Definition: tree.h:103
void set_son_pt(const Vector< Tree * > &son_pt)
Definition: tree.h:123
void set_father_pt(Tree *const &father_pt)
Set the father.
Definition: tree.h:241
TreeRoot *& root_pt()
Return pointer to root of the tree.
Definition: tree.h:141
Definition: oomph-lib/src/generic/Vector.h:58
DRAIG: Change all instances of (SPATIAL_DIM) to (DIM-1).
Definition: AnisotropicHookean.h:10