1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2020 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
3 
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License, or (at your option) any later version.
8 
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 // Lesser General Public License for more details.
13 
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17 
18 
19 
20 #ifndef LIBMESH_MESH_REFINEMENT_H
21 #define LIBMESH_MESH_REFINEMENT_H
22 
23 
24 
25 #include "libmesh/libmesh_config.h"
26 
27 #ifdef LIBMESH_ENABLE_AMR
28 
29 // Local Includes
30 #include "libmesh/libmesh_common.h"
31 #include "libmesh/libmesh.h" // libMesh::invalid_uint
32 #include "libmesh/topology_map.h"
33 #include "libmesh/parallel_object.h"
34 
35 // C++ Includes
36 #include <vector>
37 
38 namespace libMesh
39 {
40 
41 // Forward Declarations
42 class MeshBase;
43 class Point;
44 class Node;
45 class ErrorVector;
46 class PeriodicBoundaries;
47 class Elem;
48 class PointLocatorBase;
49 
50 /**
51  * \brief Implements (adaptive) mesh refinement algorithms for a \p MeshBase.
52  *
53  * \note Before using any of the algorithms in this class on a distributed
54  * mesh, the user needs to make sure that the mesh is prepared
55  * (MeshBase::prepare_for_use).
56  *
57  * \author Benjamin S. Kirk
58  * \date 2002-2007
59  * \brief Responsible for mesh refinement algorithms and data.
60  */
61 class MeshRefinement : public ParallelObject
62 {
63 public:
64 
65   /**
66    * Constructor.
67    */
68   explicit
69   MeshRefinement (MeshBase & mesh);
70 
71 private:
72   // Both the copy ctor and the assignment operator are
73   // declared private but not implemented.  This is the
74   // standard practice to prevent them from being used.
75   MeshRefinement (const MeshRefinement &);
76   MeshRefinement & operator=(const MeshRefinement &);
77 
78 public:
79 
80   /**
81    * Abstract base class to be used for user-specified
82    * element flagging.  This can be used instead of or to
83    * augment traditional error indicator based refinement.
84    * This simply provides a base class that can be derived
85    * from and then passed to the
86    * \p flag_elements_by () method.
87    */
88   class ElementFlagging
89   {
90   public:
91     /**
92      * Destructor.  Virtual because we will have virtual functions.
93      */
~ElementFlagging()94     virtual ~ElementFlagging () {}
95 
96     /**
97      * Callback function to be used for marking elements for refinement.
98      */
99     virtual void flag_elements () = 0;
100   };
101 
102   /**
103    * Sets the \p PeriodicBoundaries pointer.
104    */
105   void set_periodic_boundaries_ptr(PeriodicBoundaries * pb_ptr);
106 
107   /**
108    * Destructor. Deletes all the elements that are currently stored.
109    */
110   ~MeshRefinement ();
111 
112   /**
113    * Deletes all the data that are currently stored.
114    */
115   void clear ();
116 
117   /**
118    * Flags elements for coarsening and refinement based on
119    * the computed error passed in \p error_per_cell.  The two
120    * fractions \p refine_fraction and \p coarsen_fraction must be in
121    * \f$ [0,1] \f$.
122    *
123    * All the function arguments except error_per_cell
124    * have been deprecated, and will be removed in
125    * future libMesh releases - to control these parameters,
126    * set the corresponding member variables.
127    */
128   void flag_elements_by_error_fraction (const ErrorVector & error_per_cell,
129                                         const Real refine_fraction  = 0.3,
130                                         const Real coarsen_fraction = 0.0,
131                                         const unsigned int max_level = libMesh::invalid_uint);
132 
133   /**
134    * Flags elements for coarsening and refinement based on
135    * the computed error passed in \p error_per_cell.  This method refines
136    * the worst elements with errors greater than
137    * \p absolute_global_tolerance / n_active_elem, flagging at most
138    * \p refine_fraction * n_active_elem
139    * It coarsens elements with errors less than
140    * \p coarsen_threshold * \p global_tolerance / n_active_elem,
141    * flagging at most
142    * \p coarsen_fraction * n_active_elem
143    *
144    * The three fractions \p refine_fraction \p coarsen_fraction and
145    * \p coarsen_threshold should be in \f$ [0,1] \f$.
146    */
147   void flag_elements_by_error_tolerance (const ErrorVector & error_per_cell);
148 
149   /**
150    * Flags elements for coarsening and refinement based on
151    * the computed error passed in \p error_per_cell.  This method attempts to
152    * produce a mesh with slightly more than \p nelem_target active elements,
153    * trading element refinement for element coarsening when their error
154    * ratios exceed \p coarsen_threshold.  It flags no more than
155    * \p refine_fraction * n_elem elements for refinement and flags no
156    * more than \p coarsen_fraction * n_elem elements for coarsening.
157    *
158    * \returns \p true if it has done all the AMR/C it can do
159    * in a single step, or false if further adaptive steps may be required
160    * to produce a mesh with a narrow error distribution and the right
161    * number of elements.
162    */
163   bool flag_elements_by_nelem_target (const ErrorVector & error_per_cell);
164 
165   /**
166    * Flags elements for coarsening and refinement based on
167    * the computed error passed in \p error_per_cell.  This method picks
168    * the top \p refine_fraction * \p n_elem elements for refinement and
169    * the bottom \p coarsen_fraction * \p n_elem elements for coarsening.
170    * The two fractions \p refine_fraction and \p coarsen_fraction must be
171    * in \f$ [0,1] \f$.
172    *
173    * All the function arguments except error_per_cell
174    * have been deprecated, and will be removed in
175    * future libMesh releases - to control these parameters,
176    * set the corresponding member variables.
177    */
178   void flag_elements_by_elem_fraction (const ErrorVector & error_per_cell,
179                                        const Real refine_fraction  = 0.3,
180                                        const Real coarsen_fraction = 0.0,
181                                        const unsigned int max_level = libMesh::invalid_uint);
182 
183   /**
184    * Flags elements for coarsening and refinement based on
185    * the computed error passed in \p error_per_cell.  This method picks
186    * the top \p refine_fraction * \p stddev + \p mean elements for refinement
187    * and the bottom \p mean - \p coarsen_fraction * \p stddev elements for
188    * coarsening. The two fractions \p refine_fraction and \p coarsen_fraction
189    * must be in \f$ [0,1] \f$.
190    *
191    * All the function arguments except error_per_cell
192    * have been deprecated, and will be removed in
193    * future libMesh releases - to control these parameters,
194    * set the corresponding member variables.
195    */
196   void flag_elements_by_mean_stddev (const ErrorVector & error_per_cell,
197                                      const Real refine_fraction  = 1.0,
198                                      const Real coarsen_fraction = 0.0,
199                                      const unsigned int max_level = libMesh::invalid_uint);
200 
201   /**
202    * Flag elements based on a function object.  The class \p ElementFlagging
203    * defines a mechanism for implementing refinement strategies.
204    */
205   void flag_elements_by (ElementFlagging & element_flagging);
206 
207   /**
208    * Takes a mesh whose elements are flagged for h refinement and coarsening,
209    * and switches those flags to request p refinement and coarsening instead.
210    */
211   void switch_h_to_p_refinement();
212 
213   /**
214    * Takes a mesh whose elements are flagged for h refinement and coarsening,
215    * and adds flags to request p refinement and coarsening of the same elements.
216    */
217   void add_p_to_h_refinement();
218 
219   /**
220    * Refines and coarsens user-requested elements. Will also
221    * refine/coarsen additional elements to satisfy level-one rule.
222    * It is possible that for a given set of refinement flags there
223    * is actually no change upon calling this member function.
224    *
225    * \returns \p true if the mesh actually changed (hence
226    * data needs to be projected) and \p false otherwise.
227    *
228    * \note This function used to take an argument, \p maintain_level_one.
229    * New code should use \p face_level_mismatch_limit() instead.
230    */
231   bool refine_and_coarsen_elements ();
232 
233   /**
234    * Only coarsens the user-requested elements. Some elements
235    * will not be coarsened to satisfy the level one rule.
236    * It is possible that for a given set of refinement flags there
237    * is actually no change upon calling this member function.
238    *
239    * \returns \p true if the mesh actually changed (hence data needs
240    * to be projected) and \p false otherwise.
241    *
242    * \note This function used to take an argument, \p maintain_level_one,
243    * new code should use face_level_mismatch_limit() instead.
244    */
245   bool coarsen_elements ();
246 
247   /**
248    * Only refines the user-requested elements.
249    * It is possible that for a given set of refinement flags there
250    * is actually no change upon calling this member function.
251    *
252    * \returns \p true if the mesh actually changed (hence
253    * data needs to be projected) and \p false otherwise.
254    *
255    * \note This function used to take an argument, \p maintain_level_one,
256    * new code should use \p face_level_mismatch_limit() instead.
257    */
258   bool refine_elements ();
259 
260   /**
261    * Uniformly refines the mesh \p n times.
262    */
263   void uniformly_refine (unsigned int n=1);
264 
265   /**
266    * Attempts to uniformly coarsen the mesh \p n times.
267    */
268   void uniformly_coarsen (unsigned int n=1);
269 
270   /**
271    * Uniformly p refines the mesh \p n times.
272    */
273   void uniformly_p_refine (unsigned int n=1);
274 
275   /**
276    * Attempts to uniformly p coarsen the mesh \p n times.
277    */
278   void uniformly_p_coarsen (unsigned int n=1);
279 
280   /**
281    * Sets the refinement flag to \p Elem::DO_NOTHING
282    * for each element in the mesh.
283    */
284   void clean_refinement_flags ();
285 
286   /**
287    * \returns \p true if the mesh satisfies the level one restriction,
288    * and false otherwise.
289    *
290    * Aborts the program if \p libmesh_assert_yes is true and the mesh
291    * does not satisfy the level one restriction.
292    */
293   bool test_level_one (bool libmesh_assert_yes = false);
294 
295   /**
296    * \returns \p true if the mesh has no elements flagged to be
297    * coarsened or refined, and false otherwise.
298    *
299    * Aborts the program if libmesh_assert_yes is true and the mesh has
300    * flagged elements.
301    */
302   bool test_unflagged (bool libmesh_assert_yes = false);
303 
304   /**
305    * Add a node to the mesh.  The node should be node n of child c of
306    * parent Elem parent.  The processor id \p proc_id is used if
307    * necessary to help determine numbering of newly created nodes, but
308    * newly created nodes are left unpartitioned until a node
309    * partitionining sweep is done later.
310    *
311    * \returns A pointer to a suitable existing or newly-created node.
312    */
313   Node * add_node (Elem & parent,
314                    unsigned int child,
315                    unsigned int node,
316                    processor_id_type proc_id);
317 
318   /**
319    * Adds the element \p elem to the mesh.
320    */
321   Elem * add_elem (Elem * elem);
322 
323   /**
324    * Same as the function above, but makes it clear that the
325    * MeshRefinement object (actually, its Mesh) takes ownership of the
326    * Elem which is passed in, so the user is not responsible for
327    * deleting it. The version of add_elem() taking a dumb pointer will
328    * eventually be deprecated in favor of this version.
329    */
330   Elem * add_elem (std::unique_ptr<Elem> elem);
331 
332   /**
333    * \returns A constant reference to the \p MeshBase object associated
334    * with this object.
335    */
get_mesh()336   const MeshBase & get_mesh () const { return _mesh; }
337 
338   /**
339    * \returns A writable reference to the \p MeshBase object associated
340    * with this object.
341    */
get_mesh()342   MeshBase & get_mesh () { return _mesh; }
343 
344   /**
345    * If \p coarsen_by_parents is true, complete groups of sibling elements
346    * (elements with the same parent) will be flagged for coarsening.
347    * This should make the coarsening more likely to occur as requested.
348    *
349    * \p coarsen_by_parents is true by default.
350    */
351   bool & coarsen_by_parents();
352 
353   /**
354    * The \p refine_fraction sets either a desired target or a desired
355    * maximum number of elements to flag for refinement, depending on which
356    * flag_elements_by method is called.
357    *
358    * \p refine_fraction must be in \f$ [0,1] \f$, and is 0.3 by default.
359    */
360   Real & refine_fraction();
361 
362   /**
363    * The \p coarsen_fraction sets either a desired target or a desired
364    * maximum number of elements to flag for coarsening, depending on which
365    * flag_elements_by method is called.
366    *
367    * \p coarsen_fraction must be in \f$ [0,1] \f$, and is 0 by default.
368    */
369   Real & coarsen_fraction();
370 
371   /**
372    * The \p max_h_level is the greatest refinement level an element should
373    * reach.
374    *
375    * \p max_h_level is unlimited (libMesh::invalid_uint) by default
376    */
377   unsigned int & max_h_level();
378 
379   /**
380    * The \p coarsen_threshold provides hysteresis in AMR/C strategies.
381    * Refinement of elements with error estimate E will be done even
382    * at the expense of coarsening elements whose children's accumulated
383    * error does not exceed \p coarsen_threshold * E.
384    *
385    * \p coarsen_threshold must be in \f$ [0,1] \f$, and is 0.1 by default.
386    */
387   Real & coarsen_threshold();
388 
389   /**
390    * If \p nelem_target is set to a nonzero value, methods like
391    * flag_elements_by_nelem_target() will attempt to keep the number
392    * of active elements in the mesh close to nelem_target.
393    *
394    * \p nelem_target is 0 by default.
395    */
396   dof_id_type & nelem_target();
397 
398   /**
399    * If \p absolute_global_tolerance is set to a nonzero value, methods
400    * like flag_elements_by_global_tolerance() will attempt to reduce
401    * the global error of the mesh (defined as the square root of the
402    * sum of the squares of the errors on active elements) to below
403    * this tolerance.
404    *
405    * \p absolute_global_tolerance is 0 by default.
406    */
407   Real & absolute_global_tolerance();
408 
409   /**
410    * If \p face_level_mismatch_limit is set to a nonzero value, then
411    * refinement and coarsening will produce meshes in which the
412    * refinement level of two face neighbors will not differ by more than
413    * that limit.  If \p face_level_mismatch_limit is 0, then level
414    * differences will be unlimited.
415    *
416    * \p face_level_mismatch_limit is 1 by default.  Currently the only
417    * supported options are 0 and 1.
418    */
419   unsigned char & face_level_mismatch_limit();
420 
421   /**
422    * If \p edge_level_mismatch_limit is set to a nonzero value, then
423    * refinement and coarsening will produce meshes in which the
424    * refinement level of two edge neighbors will not differ by more than
425    * that limit.  If \p edge_level_mismatch_limit is 0, then level
426    * differences will be unlimited.
427    *
428    * \p edge_level_mismatch_limit is 0 by default.
429    */
430   unsigned char & edge_level_mismatch_limit();
431 
432   /**
433    * If \p node_level_mismatch_limit is set to a nonzero value, then
434    * refinement and coarsening will produce meshes in which the
435    * refinement level of two nodal neighbors will not differ by more than
436    * that limit.  If \p node_level_mismatch_limit is 0, then level
437    * differences will be unlimited.
438    *
439    * \p node_level_mismatch_limit is 0 by default.
440    */
441   unsigned char & node_level_mismatch_limit();
442 
443   /**
444    * If \p overrefined_boundary_limit is set to a nonnegative value,
445    * then refinement and coarsening will produce meshes in which the
446    * refinement level of a boundary element is no more than that many
447    * levels greater than the level of any of its interior neighbors.
448    *
449    * This may be counter-intuitive in the 1D-embedded-in-3D case: an
450    * edge has *more* interior neighbors than a face containing that
451    * edge.
452    *
453    * If \p overrefined_boundary_limit is negative, then level
454    * differences will be unlimited.
455    *
456    * \p overrefined_boundary_limit is 0 by default.  This implies that
457    * adaptive coarsening can only be done on an interior element if
458    * any boundary elements on its sides are simultaneously coarsened.
459    */
460   signed char & overrefined_boundary_limit();
461 
462   /**
463    * If \p underrefined_boundary_limit is set to a nonnegative value,
464    * then refinement and coarsening will produce meshes in which the
465    * refinement level of an element is no more than that many
466    * levels greater than the level of any boundary elements on its
467    * sides.
468    *
469    * If \p underrefined_boundary_limit is negative, then level
470    * differences will be unlimited.
471    *
472    * \p underrefined_boundary_limit is 0 by default.  This implies that
473    * adaptive coarsening can only be done on a boundary element if
474    * any interior elements it is on the side of are simultaneously
475    * coarsened.
476    */
477   signed char & underrefined_boundary_limit();
478 
479 
480   /**
481    * Copy refinement flags on ghost elements from their
482    * local processors.
483    *
484    * \returns \p true if any flags changed.
485    */
486   bool make_flags_parallel_consistent ();
487 
488   /**
489    * \returns The value of the \p _enforce_mismatch_limit_prior_to_refinement flag,
490    * false by default.
491    *
492    * \deprecated Use enforce_mismatch_limit_prior_to_refinement() instead.
493    */
494 #ifdef LIBMESH_ENABLE_DEPRECATED
495   bool get_enforce_mismatch_limit_prior_to_refinement();
496 #endif
497 
498   /**
499    * Set _enforce_mismatch_limit_prior_to_refinement option.
500    * Defaults to false.
501    *
502    * \deprecated Use enforce_mismatch_limit_prior_to_refinement() instead.
503    */
504 #ifdef LIBMESH_ENABLE_DEPRECATED
505   void set_enforce_mismatch_limit_prior_to_refinement(bool enforce);
506 #endif
507 
508   /**
509    * Get/set the _enforce_mismatch_limit_prior_to_refinement flag.
510    * The default value for this flag is false.
511    */
512   bool & enforce_mismatch_limit_prior_to_refinement();
513 
514 private:
515 
516   /**
517    * Coarsens user-requested elements.  Both coarsen_elements and
518    * refine_elements used to be in the public interface for the
519    * MeshRefinement object.  Unfortunately, without proper preparation
520    * (make_refinement_compatible, make_coarsening_compatible) at least
521    * coarsen_elements() did not work alone.  By making them private,
522    * we signal to the user that they are not part of the interface.
523    * It is possible that for a given set of refinement flags there is
524    * actually no change upon calling this member function.
525    *
526    * \returns \p true if the mesh actually changed (hence data needs
527    * to be projected) and \p false otherwise.
528    */
529   bool _coarsen_elements ();
530 
531   /**
532    * Refines user-requested elements.  It is possible that for a given
533    * set of refinement flags there is actually no change upon calling
534    * this member function.
535    *
536    * \returns \p true if the mesh actually changed (hence data needs
537    * to be projected) and \p false otherwise.
538    */
539   bool _refine_elements ();
540 
541   /**
542    * Smooths refinement flags according to current settings.  It is
543    * possible that for a given set of refinement flags there is
544    * actually no change upon calling this member function.
545    *
546    * \returns \p true if the flags actually changed (hence data needs
547    * to be projected) and \p false otherwise.
548    */
549   void _smooth_flags (bool refining, bool coarsening);
550 
551   //------------------------------------------------------
552   // "Smoothing" algorithms for refined meshes
553 
554   /**
555    * This algorithm restricts the maximum level mismatch
556    * at any node in the mesh.  Calling this with \p max_mismatch
557    * equal to 1 would transform this mesh:
558    * \verbatim
559    * o---o---o---o---o-------o-------o
560    * |   |   |   |   |       |       |
561    * |   |   |   |   |       |       |
562    * o---o---o---o---o       |       |
563    * |   |   |   |   |       |       |
564    * |   |   |   |   |       |       |
565    * o---o---o---o---o-------o-------o
566    * |   |   |   |   |       |       |
567    * |   |   |   |   |       |       |
568    * o---o---o---o---o       |       |
569    * |   |   |   |   |       |       |
570    * |   |   |   |   |       |       |
571    * o---o---o---o---o-------o-------o
572    * |       |       |               |
573    * |       |       |               |
574    * |       |       |               |
575    * |       |       |               |
576    * |       |       |               |
577    * o-------o-------o               |
578    * |       |       |               |
579    * |       |       |               |
580    * |       |       |               |
581    * |       |       |               |
582    * |       |       |               |
583    * o-------o-------o---------------o
584    * \endverbatim
585    *
586    * into this:
587    *
588    * \verbatim
589    * o---o---o---o---o-------o-------o
590    * |   |   |   |   |       |       |
591    * |   |   |   |   |       |       |
592    * o---o---o---o---o       |       |
593    * |   |   |   |   |       |       |
594    * |   |   |   |   |       |       |
595    * o---o---o---o---o-------o-------o
596    * |   |   |   |   |       |       |
597    * |   |   |   |   |       |       |
598    * o---o---o---o---o       |       |
599    * |   |   |   |   |       |       |
600    * |   |   |   |   |       |       |
601    * o---o---o---o---o-------o-------o
602    * |       |       |       :       |
603    * |       |       |       :       |
604    * |       |       |       :       |
605    * |       |       |       :       |
606    * |       |       |       :       |
607    * o-------o-------o.......o.......o
608    * |       |       |       :       |
609    * |       |       |       :       |
610    * |       |       |       :       |
611    * |       |       |       :       |
612    * |       |       |       :       |
613    * o-------o-------o-------o-------o
614    * \endverbatim
615    * by refining the indicated element
616    */
617   bool limit_level_mismatch_at_node (const unsigned int max_mismatch);
618 
619   /*
620    * This algorithm restricts the maximum level mismatch
621    * at any edge in the mesh.  See the ASCII art in the comment of
622    * limit_level_mismatch_at_node, and pretend they're hexes.
623    */
624   bool limit_level_mismatch_at_edge (const unsigned int max_mismatch);
625 
626   /*
627    * This algorithm flags interior elements for refinement as needed
628    * to prevent corresponding boundary element refinement mismatch
629    * from exceeding the given limit.
630    */
631   bool limit_overrefined_boundary (const signed char max_mismatch);
632 
633   /*
634    * This algorithm flags boundary elements for refinement as needed
635    * to prevent corresponding interior element refinement mismatch
636    * from exceeding the given limit.
637    */
638   bool limit_underrefined_boundary (const signed char max_mismatch);
639 
640   /**
641    * This algorithm selects an element for refinement
642    * if all of its neighbors are (or will be) refined.
643    * This algorithm will transform this mesh:
644    * \verbatim
645    * o---o---o---o---o---o---o
646    * |   |   |   |   |   |   |
647    * |   |   |   |   |   |   |
648    * o---o---o---o---o---o---o
649    * |   |   |   |   |   |   |
650    * |   |   |   |   |   |   |
651    * o---o---o---o---o---o---o
652    * |   |   |       |   |   |
653    * |   |   |       |   |   |
654    * o---o---o       o---o---o
655    * |   |   |       |   |   |
656    * |   |   |       |   |   |
657    * o---o---o---o---o---o---o
658    * |   |   |   |   |   |   |
659    * |   |   |   |   |   |   |
660    * o---o---o---o---o---o---o
661    * |   |   |   |   |   |   |
662    * |   |   |   |   |   |   |
663    * o---o---o---o---o---o---o
664    * \endverbatim
665    *
666    * into this:
667    * \verbatim
668    * o---o---o---o---o---o---o
669    * |   |   |   |   |   |   |
670    * |   |   |   |   |   |   |
671    * o---o---o---o---o---o---o
672    * |   |   |   |   |   |   |
673    * |   |   |   |   |   |   |
674    * o---o---o---o---o---o---o
675    * |   |   |   :   |   |   |
676    * |   |   |   :   |   |   |
677    * o---o---o...o...o---o---o
678    * |   |   |   :   |   |   |
679    * |   |   |   :   |   |   |
680    * o---o---o---o---o---o---o
681    * |   |   |   |   |   |   |
682    * |   |   |   |   |   |   |
683    * o---o---o---o---o---o---o
684    * |   |   |   |   |   |   |
685    * |   |   |   |   |   |   |
686    * o---o---o---o---o---o---o
687    * \endverbatim
688    *
689    * by refining the indicated element
690    */
691   bool eliminate_unrefined_patches ();
692 
693 
694   //---------------------------------------------
695   // Utility algorithms
696 
697   /**
698    * Calculates the error on all coarsenable parents.
699    * error_per_parent[parent_id] stores this error if parent_id corresponds
700    * to a coarsenable parent, and stores -1 otherwise.
701    */
702   void create_parent_error_vector (const ErrorVector & error_per_cell,
703                                    ErrorVector & error_per_parent,
704                                    Real & parent_error_min,
705                                    Real & parent_error_max);
706 
707   /**
708    * Updates the \p _new_nodes_map
709    */
710   void update_nodes_map ();
711 
712   /**
713    * Take user-specified coarsening flags and augment them
714    * so that level-one dependency is satisfied.
715    *
716    * This function used to take an argument, \p maintain_level_one -
717    * new code should use face_level_mismatch_limit() instead.
718    */
719   bool make_coarsening_compatible ();
720 
721   /**
722    * Take user-specified refinement flags and augment them
723    * so that level-one dependency is satisfied.
724    *
725    * This function used to take an argument, \p maintain_level_one -
726    * new code should use face_level_mismatch_limit() instead.
727    */
728   bool make_refinement_compatible ();
729 
730   /**
731    * Local dispatch function for getting the correct topological
732    * neighbor from the Elem class
733    */
734   Elem * topological_neighbor (Elem * elem,
735                                const PointLocatorBase * point_locator,
736                                const unsigned int side);
737 
738   /**
739    * Local dispatch function for checking the correct has_neighbor
740    * function from the Elem class
741    */
742   bool has_topological_neighbor (const Elem * elem,
743                                  const PointLocatorBase * point_locator,
744                                  const Elem * neighbor);
745 
746   /**
747    * Data structure that holds the new nodes information.
748    */
749   TopologyMap _new_nodes_map;
750 
751   /**
752    * Reference to the mesh.
753    */
754   MeshBase & _mesh;
755 
756   /**
757    * For backwards compatibility, we initialize this
758    * as false and then set it to true if the user uses
759    * any of the refinement parameter accessor functions
760    */
761   bool _use_member_parameters;
762 
763   /**
764    * Refinement parameter values
765    */
766 
767   bool _coarsen_by_parents;
768 
769   Real _refine_fraction;
770 
771   Real _coarsen_fraction;
772 
773   unsigned int _max_h_level;
774 
775   Real _coarsen_threshold;
776 
777   dof_id_type _nelem_target;
778 
779   Real _absolute_global_tolerance;
780 
781   unsigned char _face_level_mismatch_limit;
782   unsigned char _edge_level_mismatch_limit;
783   unsigned char _node_level_mismatch_limit;
784 
785   signed char _overrefined_boundary_limit;
786   signed char _underrefined_boundary_limit;
787 
788   /**
789    * This option enforces the mismatch level prior to refinement by checking
790    * if refining any element marked for refinement \b would cause a mismatch
791    * greater than the limit. Applies to all mismatch methods.
792    *
793    * Calling this with \p node_level_mismatch_limit() = 1
794    * would transform this mesh:
795    * \verbatim
796    * o-------o-------o-------o-------o
797    * |       |       |       |       |
798    * |       |       |       |       |
799    * |       |       |       |       |
800    * |       |       |       |       |
801    * |       |       |       |       |
802    * o-------o---o---o-------o-------o
803    * |       |   :   |       |       |
804    * |       |   :   |       |       |
805    * |       o...o...o       |       |
806    * |       |   :   |       |       |
807    * |       |   :   |       |       |
808    * o-------o---o---o-------o-------o
809    * |       |       |               |
810    * |       |       |               |
811    * |       |       |               |
812    * |       |       |               |
813    * |       |       |               |
814    * o-------o-------o               |
815    * |       |       |               |
816    * |       |       |               |
817    * |       |       |               |
818    * |       |       |               |
819    * |       |       |               |
820    * o-------o-------o---------------o
821    * \endverbatim
822    *
823    * into this:
824    *
825    * \verbatim
826    * o-------o-------o-------o-------o
827    * |       |       |       |       |
828    * |       |       |       |       |
829    * |       |       |       |       |
830    * |       |       |       |       |
831    * |       |       |       |       |
832    * o-------o-------o-------o-------o
833    * |       |       |       |       |
834    * |       |       |       |       |
835    * |       |       |       |       |
836    * |       |       |       |       |
837    * |       |       |       |       |
838    * o-------o-------o-------o-------o
839    * |       |       |       :       |
840    * |       |       |       :       |
841    * |       |       |       :       |
842    * |       |       |       :       |
843    * |       |       |       :       |
844    * o-------o-------o.......o.......o
845    * |       |       |       :       |
846    * |       |       |       :       |
847    * |       |       |       :       |
848    * |       |       |       :       |
849    * |       |       |       :       |
850    * o-------o-------o-------o-------o
851    * \endverbatim
852    * by moving the refinement flag to the indicated element.
853    *
854    * Default value is false.
855    */
856   bool _enforce_mismatch_limit_prior_to_refinement;
857 
858   /**
859    * This helper function enforces the desired mismatch limits prior
860    * to refinement.  It is called from the
861    * MeshRefinement::limit_level_mismatch_at_edge() and
862    * MeshRefinement::limit_level_mismatch_at_node() functions.
863    *
864    * \returns \p true if this enforcement caused the refinement flags for
865    * \p elem to change, false otherwise.
866    */
867   enum NeighborType {POINT, EDGE};
868   bool enforce_mismatch_limit_prior_to_refinement(Elem * elem,
869                                                   NeighborType nt,
870                                                   unsigned max_mismatch);
871 
872 #ifdef LIBMESH_ENABLE_PERIODIC
873   PeriodicBoundaries * _periodic_boundaries;
874 #endif
875 };
876 
877 
878 
879 // ------------------------------------------------------------
880 // MeshRefinement class inline members
881 
coarsen_by_parents()882 inline bool & MeshRefinement::coarsen_by_parents()
883 {
884   _use_member_parameters = true;
885   return _coarsen_by_parents;
886 }
887 
refine_fraction()888 inline Real & MeshRefinement::refine_fraction()
889 {
890   _use_member_parameters = true;
891   return _refine_fraction;
892 }
893 
coarsen_fraction()894 inline Real & MeshRefinement::coarsen_fraction()
895 {
896   _use_member_parameters = true;
897   return _coarsen_fraction;
898 }
899 
max_h_level()900 inline unsigned int & MeshRefinement::max_h_level()
901 {
902   _use_member_parameters = true;
903   return _max_h_level;
904 }
905 
coarsen_threshold()906 inline Real & MeshRefinement::coarsen_threshold()
907 {
908   _use_member_parameters = true;
909   return _coarsen_threshold;
910 }
911 
nelem_target()912 inline dof_id_type & MeshRefinement::nelem_target()
913 {
914   _use_member_parameters = true;
915   return _nelem_target;
916 }
917 
absolute_global_tolerance()918 inline Real & MeshRefinement::absolute_global_tolerance()
919 {
920   _use_member_parameters = true;
921   return _absolute_global_tolerance;
922 }
923 
face_level_mismatch_limit()924 inline unsigned char & MeshRefinement::face_level_mismatch_limit()
925 {
926   return _face_level_mismatch_limit;
927 }
928 
edge_level_mismatch_limit()929 inline unsigned char & MeshRefinement::edge_level_mismatch_limit()
930 {
931   return _edge_level_mismatch_limit;
932 }
933 
node_level_mismatch_limit()934 inline unsigned char & MeshRefinement::node_level_mismatch_limit()
935 {
936   return _node_level_mismatch_limit;
937 }
938 
overrefined_boundary_limit()939 inline signed char & MeshRefinement::overrefined_boundary_limit()
940 {
941   return _overrefined_boundary_limit;
942 }
943 
underrefined_boundary_limit()944 inline signed char & MeshRefinement::underrefined_boundary_limit()
945 {
946   return _underrefined_boundary_limit;
947 }
948 
949 #ifdef LIBMESH_ENABLE_DEPRECATED
get_enforce_mismatch_limit_prior_to_refinement()950 inline bool MeshRefinement::get_enforce_mismatch_limit_prior_to_refinement()
951 {
952   libmesh_deprecated();
953   return enforce_mismatch_limit_prior_to_refinement();
954 }
955 
set_enforce_mismatch_limit_prior_to_refinement(bool enforce)956 inline void MeshRefinement::set_enforce_mismatch_limit_prior_to_refinement(bool enforce)
957 {
958   libmesh_deprecated();
959   enforce_mismatch_limit_prior_to_refinement() = enforce;
960 }
961 #endif
962 
enforce_mismatch_limit_prior_to_refinement()963 inline bool & MeshRefinement::enforce_mismatch_limit_prior_to_refinement()
964 {
965   return _enforce_mismatch_limit_prior_to_refinement;
966 }
967 
968 
969 
970 } // namespace libMesh
971 
972 #endif // end #ifdef LIBMESH_ENABLE_AMR
973 #endif // LIBMESH_MESH_REFINEMENT_H
974