LCOV - code coverage report
Current view: top level - include/mesh - mesh_refinement.h (source / functions) Hit Total Coverage
Test: libMesh/libmesh: #4476 (4beb67) with base a68cc6 Lines: 7 7 100.0 %
Date: 2026-06-03 20:22:46 Functions: 5 5 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : // The libMesh Finite Element Library.
       2             : // Copyright (C) 2002-2026 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       18032 : 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             :      */
      94             :     virtual ~ElementFlagging () = default;
      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             :    * \note When we allow boundaries to be directly associated with child elements,
     246             :    * i.e., `_children_on_boundary = true`. A child's boundary ID may be
     247             :    * lost during coarsening if it differs from its siblings on that parent side.
     248             :    */
     249             :   bool coarsen_elements ();
     250             : 
     251             :   /**
     252             :    * Only refines the user-requested elements.
     253             :    * It is possible that for a given set of refinement flags there
     254             :    * is actually no change upon calling this member function.
     255             :    *
     256             :    * \returns \p true if the mesh actually changed (hence
     257             :    * data needs to be projected) and \p false otherwise.
     258             :    *
     259             :    * \note This function used to take an argument, \p maintain_level_one,
     260             :    * new code should use \p face_level_mismatch_limit() instead.
     261             :    */
     262             :   bool refine_elements ();
     263             : 
     264             :   /**
     265             :    * Uniformly refines the mesh \p n times.
     266             :    */
     267             :   void uniformly_refine (unsigned int n=1);
     268             : 
     269             :   /**
     270             :    * Attempts to uniformly coarsen the mesh \p n times.
     271             :    */
     272             :   void uniformly_coarsen (unsigned int n=1);
     273             : 
     274             :   /**
     275             :    * Uniformly p refines the mesh \p n times.
     276             :    */
     277             :   void uniformly_p_refine (unsigned int n=1);
     278             : 
     279             :   /**
     280             :    * Attempts to uniformly p coarsen the mesh \p n times.
     281             :    */
     282             :   void uniformly_p_coarsen (unsigned int n=1);
     283             : 
     284             :   /**
     285             :    * Sets the refinement flag to \p Elem::DO_NOTHING
     286             :    * for each element in the mesh.
     287             :    */
     288             :   void clean_refinement_flags ();
     289             : 
     290             :   /**
     291             :    * \returns \p true if the mesh satisfies the level one restriction,
     292             :    * and false otherwise.
     293             :    *
     294             :    * Aborts the program if \p libmesh_assert_yes is true and the mesh
     295             :    * does not satisfy the level one restriction.
     296             :    */
     297             :   bool test_level_one (bool libmesh_assert_yes = false) const;
     298             : 
     299             :   /**
     300             :    * \returns \p true if the mesh has no elements flagged to be
     301             :    * coarsened or refined, and false otherwise.
     302             :    *
     303             :    * Aborts the program if libmesh_assert_yes is true and the mesh has
     304             :    * flagged elements.
     305             :    */
     306             :   bool test_unflagged (bool libmesh_assert_yes = false) const;
     307             : 
     308             :   /**
     309             :    * Add a node to the mesh.  The node should be node n of child c of
     310             :    * parent Elem parent.  The processor id \p proc_id is used if
     311             :    * necessary to help determine numbering of newly created nodes, but
     312             :    * newly created nodes are left unpartitioned until a node
     313             :    * partitionining sweep is done later.
     314             :    *
     315             :    * \returns A pointer to a suitable existing or newly-created node.
     316             :    */
     317             :   Node * add_node (Elem & parent,
     318             :                    unsigned int child,
     319             :                    unsigned int node,
     320             :                    processor_id_type proc_id);
     321             : 
     322             :   /**
     323             :    * Adds the element \p elem to the mesh.
     324             :    */
     325             :   Elem * add_elem (Elem * elem);
     326             : 
     327             :   /**
     328             :    * Same as the function above, but makes it clear that the
     329             :    * MeshRefinement object (actually, its Mesh) takes ownership of the
     330             :    * Elem which is passed in, so the user is not responsible for
     331             :    * deleting it. The version of add_elem() taking a dumb pointer will
     332             :    * eventually be deprecated in favor of this version.
     333             :    */
     334             :   Elem * add_elem (std::unique_ptr<Elem> elem);
     335             : 
     336             :   /**
     337             :    * \returns A constant reference to the \p MeshBase object associated
     338             :    * with this object.
     339             :    */
     340             :   const MeshBase & get_mesh () const { return _mesh; }
     341             : 
     342             :   /**
     343             :    * \returns A writable reference to the \p MeshBase object associated
     344             :    * with this object.
     345             :    */
     346             :   MeshBase & get_mesh () { return _mesh; }
     347             : 
     348             :   /**
     349             :    * If \p coarsen_by_parents is true, complete groups of sibling elements
     350             :    * (elements with the same parent) will be flagged for coarsening.
     351             :    * This should make the coarsening more likely to occur as requested.
     352             :    *
     353             :    * \p coarsen_by_parents is true by default.
     354             :    */
     355             :   bool & coarsen_by_parents();
     356             : 
     357             :   /**
     358             :    * The \p refine_fraction sets either a desired target or a desired
     359             :    * maximum number of elements to flag for refinement, depending on which
     360             :    * flag_elements_by method is called.
     361             :    *
     362             :    * \p refine_fraction must be in \f$ [0,1] \f$, and is 0.3 by default.
     363             :    */
     364             :   Real & refine_fraction();
     365             : 
     366             :   /**
     367             :    * The \p coarsen_fraction sets either a desired target or a desired
     368             :    * maximum number of elements to flag for coarsening, depending on which
     369             :    * flag_elements_by method is called.
     370             :    *
     371             :    * \p coarsen_fraction must be in \f$ [0,1] \f$, and is 0 by default.
     372             :    */
     373             :   Real & coarsen_fraction();
     374             : 
     375             :   /**
     376             :    * The \p max_h_level is the greatest refinement level an element should
     377             :    * reach.
     378             :    *
     379             :    * \p max_h_level is unlimited (libMesh::invalid_uint) by default
     380             :    */
     381             :   unsigned int & max_h_level();
     382             : 
     383             :   /**
     384             :    * The \p coarsen_threshold provides hysteresis in AMR/C strategies.
     385             :    * Refinement of elements with error estimate E will be done even
     386             :    * at the expense of coarsening elements whose children's accumulated
     387             :    * error does not exceed \p coarsen_threshold * E.
     388             :    *
     389             :    * \p coarsen_threshold must be in \f$ [0,1] \f$, and is 0.1 by default.
     390             :    */
     391             :   Real & coarsen_threshold();
     392             : 
     393             :   /**
     394             :    * If \p nelem_target is set to a nonzero value, methods like
     395             :    * flag_elements_by_nelem_target() will attempt to keep the number
     396             :    * of active elements in the mesh close to nelem_target.
     397             :    *
     398             :    * \p nelem_target is 0 by default.
     399             :    */
     400             :   dof_id_type & nelem_target();
     401             : 
     402             :   /**
     403             :    * If \p absolute_global_tolerance is set to a nonzero value, methods
     404             :    * like flag_elements_by_global_tolerance() will attempt to reduce
     405             :    * the global error of the mesh (defined as the square root of the
     406             :    * sum of the squares of the errors on active elements) to below
     407             :    * this tolerance.
     408             :    *
     409             :    * \p absolute_global_tolerance is 0 by default.
     410             :    */
     411             :   Real & absolute_global_tolerance();
     412             : 
     413             :   /**
     414             :    * If \p face_level_mismatch_limit is set to a nonzero value, then
     415             :    * refinement and coarsening will produce meshes in which the
     416             :    * refinement level of two face neighbors will not differ by more than
     417             :    * that limit.  If \p face_level_mismatch_limit is 0, then level
     418             :    * differences will be unlimited.
     419             :    *
     420             :    * \p face_level_mismatch_limit is 1 by default.  Currently the only
     421             :    * supported options are 0 and 1.
     422             :    */
     423             :   unsigned char & face_level_mismatch_limit();
     424             : 
     425             :   /**
     426             :    * If \p edge_level_mismatch_limit is set to a nonzero value, then
     427             :    * refinement and coarsening will produce meshes in which the
     428             :    * refinement level of two edge neighbors will not differ by more than
     429             :    * that limit.  If \p edge_level_mismatch_limit is 0, then level
     430             :    * differences will be unlimited.
     431             :    *
     432             :    * \p edge_level_mismatch_limit is 0 by default.
     433             :    */
     434             :   unsigned char & edge_level_mismatch_limit();
     435             : 
     436             :   /**
     437             :    * If \p node_level_mismatch_limit is set to a nonzero value, then
     438             :    * refinement and coarsening will produce meshes in which the
     439             :    * refinement level of two nodal neighbors will not differ by more than
     440             :    * that limit.  If \p node_level_mismatch_limit is 0, then level
     441             :    * differences will be unlimited.
     442             :    *
     443             :    * \p node_level_mismatch_limit is 0 by default.
     444             :    */
     445             :   unsigned char & node_level_mismatch_limit();
     446             : 
     447             :   /**
     448             :    * If \p overrefined_boundary_limit is set to a nonnegative value,
     449             :    * then refinement and coarsening will produce meshes in which the
     450             :    * refinement level of a boundary element is no more than that many
     451             :    * levels greater than the level of any of its interior neighbors.
     452             :    *
     453             :    * This may be counter-intuitive in the 1D-embedded-in-3D case: an
     454             :    * edge has *more* interior neighbors than a face containing that
     455             :    * edge.
     456             :    *
     457             :    * If \p overrefined_boundary_limit is negative, then level
     458             :    * differences will be unlimited.
     459             :    *
     460             :    * \p overrefined_boundary_limit is 0 by default.  This implies that
     461             :    * adaptive coarsening can only be done on an interior element if
     462             :    * any boundary elements on its sides are simultaneously coarsened.
     463             :    */
     464             :   signed char & overrefined_boundary_limit();
     465             : 
     466             :   /**
     467             :    * If \p underrefined_boundary_limit is set to a nonnegative value,
     468             :    * then refinement and coarsening will produce meshes in which the
     469             :    * refinement level of an element is no more than that many
     470             :    * levels greater than the level of any boundary elements on its
     471             :    * sides.
     472             :    *
     473             :    * If \p underrefined_boundary_limit is negative, then level
     474             :    * differences will be unlimited.
     475             :    *
     476             :    * \p underrefined_boundary_limit is 0 by default.  This implies that
     477             :    * adaptive coarsening can only be done on a boundary element if
     478             :    * any interior elements it is on the side of are simultaneously
     479             :    * coarsened.
     480             :    */
     481             :   signed char & underrefined_boundary_limit();
     482             : 
     483             :   /**
     484             :    * This flag defaults to false in order to maintain the original
     485             :    * behavior of the code, which was to always eliminate unrefined
     486             :    * element patches. If you set this flag to true, then the
     487             :    * MeshRefinement::eliminate_unrefined_patches() function
     488             :    * essentially does nothing, allowing such patches to persist. This
     489             :    * may be particularly useful in e.g. 1D meshes where having
     490             :    * unrefined patches does not introduce additional hanging nodes.
     491             :    */
     492             :   bool & allow_unrefined_patches();
     493             : 
     494             :   /**
     495             :    * Copy refinement flags on ghost elements from their
     496             :    * local processors.
     497             :    *
     498             :    * \returns \p true if any flags changed.
     499             :    */
     500             :   bool make_flags_parallel_consistent ();
     501             : 
     502             :   /**
     503             :    * Get/set the _enforce_mismatch_limit_prior_to_refinement flag.
     504             :    * The default value for this flag is false.
     505             :    */
     506             :   bool & enforce_mismatch_limit_prior_to_refinement();
     507             :   bool enforce_mismatch_limit_prior_to_refinement() const;
     508             :   void enforce_mismatch_limit_prior_to_refinement(bool enforce);
     509             : 
     510             : private:
     511             : 
     512             :   /**
     513             :    * Coarsens user-requested elements.  Both coarsen_elements and
     514             :    * refine_elements used to be in the public interface for the
     515             :    * MeshRefinement object.  Unfortunately, without proper preparation
     516             :    * (make_refinement_compatible, make_coarsening_compatible) at least
     517             :    * coarsen_elements() did not work alone.  By making them private,
     518             :    * we signal to the user that they are not part of the interface.
     519             :    * It is possible that for a given set of refinement flags there is
     520             :    * actually no change upon calling this member function.
     521             :    *
     522             :    * \returns \p true if the mesh actually changed (hence data needs
     523             :    * to be projected) and \p false otherwise.
     524             :    */
     525             :   bool _coarsen_elements ();
     526             : 
     527             :   /**
     528             :    * Refines user-requested elements.  It is possible that for a given
     529             :    * set of refinement flags there is actually no change upon calling
     530             :    * this member function.
     531             :    *
     532             :    * \returns \p true if the mesh actually changed (hence data needs
     533             :    * to be projected) and \p false otherwise.
     534             :    */
     535             :   bool _refine_elements ();
     536             : 
     537             :   /**
     538             :    * Smooths refinement flags according to current settings.  It is
     539             :    * possible that for a given set of refinement flags there is
     540             :    * actually no change upon calling this member function.
     541             :    *
     542             :    * \returns \p true if the flags actually changed (hence data needs
     543             :    * to be projected) and \p false otherwise.
     544             :    */
     545             :   void _smooth_flags (bool refining, bool coarsening);
     546             : 
     547             :   //------------------------------------------------------
     548             :   // "Smoothing" algorithms for refined meshes
     549             : 
     550             :   /**
     551             :    * This algorithm restricts the maximum level mismatch
     552             :    * at any node in the mesh.  Calling this with \p max_mismatch
     553             :    * equal to 1 would transform this mesh:
     554             :    * \verbatim
     555             :    * o---o---o---o---o-------o-------o
     556             :    * |   |   |   |   |       |       |
     557             :    * |   |   |   |   |       |       |
     558             :    * o---o---o---o---o       |       |
     559             :    * |   |   |   |   |       |       |
     560             :    * |   |   |   |   |       |       |
     561             :    * o---o---o---o---o-------o-------o
     562             :    * |   |   |   |   |       |       |
     563             :    * |   |   |   |   |       |       |
     564             :    * o---o---o---o---o       |       |
     565             :    * |   |   |   |   |       |       |
     566             :    * |   |   |   |   |       |       |
     567             :    * o---o---o---o---o-------o-------o
     568             :    * |       |       |               |
     569             :    * |       |       |               |
     570             :    * |       |       |               |
     571             :    * |       |       |               |
     572             :    * |       |       |               |
     573             :    * o-------o-------o               |
     574             :    * |       |       |               |
     575             :    * |       |       |               |
     576             :    * |       |       |               |
     577             :    * |       |       |               |
     578             :    * |       |       |               |
     579             :    * o-------o-------o---------------o
     580             :    * \endverbatim
     581             :    *
     582             :    * into this:
     583             :    *
     584             :    * \verbatim
     585             :    * o---o---o---o---o-------o-------o
     586             :    * |   |   |   |   |       |       |
     587             :    * |   |   |   |   |       |       |
     588             :    * o---o---o---o---o       |       |
     589             :    * |   |   |   |   |       |       |
     590             :    * |   |   |   |   |       |       |
     591             :    * o---o---o---o---o-------o-------o
     592             :    * |   |   |   |   |       |       |
     593             :    * |   |   |   |   |       |       |
     594             :    * o---o---o---o---o       |       |
     595             :    * |   |   |   |   |       |       |
     596             :    * |   |   |   |   |       |       |
     597             :    * o---o---o---o---o-------o-------o
     598             :    * |       |       |       :       |
     599             :    * |       |       |       :       |
     600             :    * |       |       |       :       |
     601             :    * |       |       |       :       |
     602             :    * |       |       |       :       |
     603             :    * o-------o-------o.......o.......o
     604             :    * |       |       |       :       |
     605             :    * |       |       |       :       |
     606             :    * |       |       |       :       |
     607             :    * |       |       |       :       |
     608             :    * |       |       |       :       |
     609             :    * o-------o-------o-------o-------o
     610             :    * \endverbatim
     611             :    * by refining the indicated element
     612             :    */
     613             :   bool limit_level_mismatch_at_node (const unsigned int max_mismatch);
     614             : 
     615             :   /*
     616             :    * This algorithm restricts the maximum level mismatch
     617             :    * at any edge in the mesh.  See the ASCII art in the comment of
     618             :    * limit_level_mismatch_at_node, and pretend they're hexes.
     619             :    */
     620             :   bool limit_level_mismatch_at_edge (const unsigned int max_mismatch);
     621             : 
     622             :   /*
     623             :    * This algorithm flags interior elements for refinement as needed
     624             :    * to prevent corresponding boundary element refinement mismatch
     625             :    * from exceeding the given limit.
     626             :    */
     627             :   bool limit_overrefined_boundary (const signed char max_mismatch);
     628             : 
     629             :   /*
     630             :    * This algorithm flags boundary elements for refinement as needed
     631             :    * to prevent corresponding interior element refinement mismatch
     632             :    * from exceeding the given limit.
     633             :    */
     634             :   bool limit_underrefined_boundary (const signed char max_mismatch);
     635             : 
     636             :   /**
     637             :    * This algorithm selects an element for refinement
     638             :    * if all of its neighbors are (or will be) refined.
     639             :    * This algorithm will transform this mesh:
     640             :    * \verbatim
     641             :    * o---o---o---o---o---o---o
     642             :    * |   |   |   |   |   |   |
     643             :    * |   |   |   |   |   |   |
     644             :    * o---o---o---o---o---o---o
     645             :    * |   |   |   |   |   |   |
     646             :    * |   |   |   |   |   |   |
     647             :    * o---o---o---o---o---o---o
     648             :    * |   |   |       |   |   |
     649             :    * |   |   |       |   |   |
     650             :    * o---o---o       o---o---o
     651             :    * |   |   |       |   |   |
     652             :    * |   |   |       |   |   |
     653             :    * o---o---o---o---o---o---o
     654             :    * |   |   |   |   |   |   |
     655             :    * |   |   |   |   |   |   |
     656             :    * o---o---o---o---o---o---o
     657             :    * |   |   |   |   |   |   |
     658             :    * |   |   |   |   |   |   |
     659             :    * o---o---o---o---o---o---o
     660             :    * \endverbatim
     661             :    *
     662             :    * into this:
     663             :    * \verbatim
     664             :    * o---o---o---o---o---o---o
     665             :    * |   |   |   |   |   |   |
     666             :    * |   |   |   |   |   |   |
     667             :    * o---o---o---o---o---o---o
     668             :    * |   |   |   |   |   |   |
     669             :    * |   |   |   |   |   |   |
     670             :    * o---o---o---o---o---o---o
     671             :    * |   |   |   :   |   |   |
     672             :    * |   |   |   :   |   |   |
     673             :    * o---o---o...o...o---o---o
     674             :    * |   |   |   :   |   |   |
     675             :    * |   |   |   :   |   |   |
     676             :    * o---o---o---o---o---o---o
     677             :    * |   |   |   |   |   |   |
     678             :    * |   |   |   |   |   |   |
     679             :    * o---o---o---o---o---o---o
     680             :    * |   |   |   |   |   |   |
     681             :    * |   |   |   |   |   |   |
     682             :    * o---o---o---o---o---o---o
     683             :    * \endverbatim
     684             :    *
     685             :    * by refining the indicated element. If the _allow_unrefined_patches
     686             :    * flag (default false) is set to true, then this function simpy returns
     687             :    * false (indicating that no changes were made).
     688             :    */
     689             :   bool eliminate_unrefined_patches ();
     690             : 
     691             : 
     692             :   //---------------------------------------------
     693             :   // Utility algorithms
     694             : 
     695             :   /**
     696             :    * Calculates the error on all coarsenable parents.
     697             :    * error_per_parent[parent_id] stores this error if parent_id corresponds
     698             :    * to a coarsenable parent, and stores -1 otherwise.
     699             :    */
     700             :   void create_parent_error_vector (const ErrorVector & error_per_cell,
     701             :                                    ErrorVector & error_per_parent,
     702             :                                    Real & parent_error_min,
     703             :                                    Real & parent_error_max);
     704             : 
     705             :   /**
     706             :    * Updates the \p _new_nodes_map
     707             :    */
     708             :   void update_nodes_map ();
     709             : 
     710             :   /**
     711             :    * Take user-specified coarsening flags and augment them
     712             :    * so that level-one dependency is satisfied.
     713             :    *
     714             :    * This function used to take an argument, \p maintain_level_one -
     715             :    * new code should use face_level_mismatch_limit() instead.
     716             :    */
     717             :   bool make_coarsening_compatible ();
     718             : 
     719             :   /**
     720             :    * Take user-specified refinement flags and augment them
     721             :    * so that level-one dependency is satisfied.
     722             :    *
     723             :    * This function used to take an argument, \p maintain_level_one -
     724             :    * new code should use face_level_mismatch_limit() instead.
     725             :    */
     726             :   bool make_refinement_compatible ();
     727             : 
     728             :   /**
     729             :    * Local dispatch function for getting the correct topological
     730             :    * neighbor from the Elem class
     731             :    */
     732             :   Elem * topological_neighbor (Elem * elem,
     733             :                                const PointLocatorBase * point_locator,
     734             :                                const unsigned int side) const;
     735             : 
     736             :   /**
     737             :    * Local dispatch function for checking the correct has_neighbor
     738             :    * function from the Elem class
     739             :    */
     740             :   bool has_topological_neighbor (const Elem * elem,
     741             :                                  const PointLocatorBase * point_locator,
     742             :                                  const Elem * neighbor) const;
     743             : 
     744             :   /**
     745             :    * Data structure that holds the new nodes information.
     746             :    */
     747             :   TopologyMap _new_nodes_map;
     748             : 
     749             :   /**
     750             :    * Reference to the mesh.
     751             :    */
     752             :   MeshBase & _mesh;
     753             : 
     754             :   /**
     755             :    * For backwards compatibility, we initialize this
     756             :    * as false and then set it to true if the user uses
     757             :    * any of the refinement parameter accessor functions
     758             :    */
     759             :   bool _use_member_parameters;
     760             : 
     761             :   /**
     762             :    * Refinement parameter values
     763             :    */
     764             : 
     765             :   bool _coarsen_by_parents;
     766             : 
     767             :   Real _refine_fraction;
     768             : 
     769             :   Real _coarsen_fraction;
     770             : 
     771             :   unsigned int _max_h_level;
     772             : 
     773             :   Real _coarsen_threshold;
     774             : 
     775             :   dof_id_type _nelem_target;
     776             : 
     777             :   Real _absolute_global_tolerance;
     778             : 
     779             :   unsigned char _face_level_mismatch_limit;
     780             :   unsigned char _edge_level_mismatch_limit;
     781             :   unsigned char _node_level_mismatch_limit;
     782             : 
     783             :   signed char _overrefined_boundary_limit;
     784             :   signed char _underrefined_boundary_limit;
     785             : 
     786             :   bool _allow_unrefined_patches;
     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             : 
     882             : inline bool & MeshRefinement::coarsen_by_parents()
     883             : {
     884             :   _use_member_parameters = true;
     885             :   return _coarsen_by_parents;
     886             : }
     887             : 
     888             : inline Real & MeshRefinement::refine_fraction()
     889             : {
     890             :   _use_member_parameters = true;
     891             :   return _refine_fraction;
     892             : }
     893             : 
     894             : inline Real & MeshRefinement::coarsen_fraction()
     895             : {
     896             :   _use_member_parameters = true;
     897             :   return _coarsen_fraction;
     898             : }
     899             : 
     900             : inline unsigned int & MeshRefinement::max_h_level()
     901             : {
     902             :   _use_member_parameters = true;
     903             :   return _max_h_level;
     904             : }
     905             : 
     906             : inline Real & MeshRefinement::coarsen_threshold()
     907             : {
     908             :   _use_member_parameters = true;
     909             :   return _coarsen_threshold;
     910             : }
     911             : 
     912             : inline dof_id_type & MeshRefinement::nelem_target()
     913             : {
     914             :   _use_member_parameters = true;
     915             :   return _nelem_target;
     916             : }
     917             : 
     918             : inline Real & MeshRefinement::absolute_global_tolerance()
     919             : {
     920             :   _use_member_parameters = true;
     921             :   return _absolute_global_tolerance;
     922             : }
     923             : 
     924         850 : inline unsigned char & MeshRefinement::face_level_mismatch_limit()
     925             : {
     926         850 :   return _face_level_mismatch_limit;
     927             : }
     928             : 
     929             : inline unsigned char & MeshRefinement::edge_level_mismatch_limit()
     930             : {
     931             :   return _edge_level_mismatch_limit;
     932             : }
     933             : 
     934             : inline unsigned char & MeshRefinement::node_level_mismatch_limit()
     935             : {
     936             :   return _node_level_mismatch_limit;
     937             : }
     938             : 
     939         850 : inline signed char & MeshRefinement::overrefined_boundary_limit()
     940             : {
     941         850 :   return _overrefined_boundary_limit;
     942             : }
     943             : 
     944         850 : inline signed char & MeshRefinement::underrefined_boundary_limit()
     945             : {
     946         850 :   return _underrefined_boundary_limit;
     947             : }
     948             : 
     949             : inline bool & MeshRefinement::allow_unrefined_patches()
     950             : {
     951             :   return _allow_unrefined_patches;
     952             : }
     953             : 
     954             : inline bool & MeshRefinement::enforce_mismatch_limit_prior_to_refinement()
     955             : {
     956             :   return _enforce_mismatch_limit_prior_to_refinement;
     957             : }
     958             : 
     959             : inline bool
     960             : MeshRefinement::enforce_mismatch_limit_prior_to_refinement() const
     961             : {
     962             :   return _enforce_mismatch_limit_prior_to_refinement;
     963             : }
     964             : 
     965             : inline void
     966             : MeshRefinement::enforce_mismatch_limit_prior_to_refinement(bool enforce)
     967             : {
     968             :   _enforce_mismatch_limit_prior_to_refinement = enforce;
     969             : }
     970             : 
     971             : 
     972             : 
     973             : } // namespace libMesh
     974             : 
     975             : #endif // end #ifdef LIBMESH_ENABLE_AMR
     976             : #endif // LIBMESH_MESH_REFINEMENT_H

Generated by: LCOV version 1.14