libMesh
Classes | Public Member Functions | Protected Attributes | Private Types | Private Member Functions | Private Attributes | List of all members
libMesh::MeshRefinement Class Reference

Implements (adaptive) mesh refinement algorithms for a MeshBase. More...

#include <mesh_refinement.h>

Inheritance diagram for libMesh::MeshRefinement:
[legend]

Classes

class  ElementFlagging
 Abstract base class to be used for user-specified element flagging. More...
 

Public Member Functions

 MeshRefinement (MeshBase &mesh)
 Constructor. More...
 
void set_periodic_boundaries_ptr (PeriodicBoundaries *pb_ptr)
 Sets the PeriodicBoundaries pointer. More...
 
 ~MeshRefinement ()
 Destructor. More...
 
void clear ()
 Deletes all the data that are currently stored. More...
 
void flag_elements_by_error_fraction (const ErrorVector &error_per_cell, const Real refine_fraction=0.3, const Real coarsen_fraction=0.0, const unsigned int max_level=libMesh::invalid_uint)
 Flags elements for coarsening and refinement based on the computed error passed in error_per_cell. More...
 
void flag_elements_by_error_tolerance (const ErrorVector &error_per_cell)
 Flags elements for coarsening and refinement based on the computed error passed in error_per_cell. More...
 
bool flag_elements_by_nelem_target (const ErrorVector &error_per_cell)
 Flags elements for coarsening and refinement based on the computed error passed in error_per_cell. More...
 
void flag_elements_by_elem_fraction (const ErrorVector &error_per_cell, const Real refine_fraction=0.3, const Real coarsen_fraction=0.0, const unsigned int max_level=libMesh::invalid_uint)
 Flags elements for coarsening and refinement based on the computed error passed in error_per_cell. More...
 
void flag_elements_by_mean_stddev (const ErrorVector &error_per_cell, const Real refine_fraction=1.0, const Real coarsen_fraction=0.0, const unsigned int max_level=libMesh::invalid_uint)
 Flags elements for coarsening and refinement based on the computed error passed in error_per_cell. More...
 
void flag_elements_by (ElementFlagging &element_flagging)
 Flag elements based on a function object. More...
 
void switch_h_to_p_refinement ()
 Takes a mesh whose elements are flagged for h refinement and coarsening, and switches those flags to request p refinement and coarsening instead. More...
 
void add_p_to_h_refinement ()
 Takes a mesh whose elements are flagged for h refinement and coarsening, and adds flags to request p refinement and coarsening of the same elements. More...
 
bool refine_and_coarsen_elements ()
 Refines and coarsens user-requested elements. More...
 
bool coarsen_elements ()
 Only coarsens the user-requested elements. More...
 
bool refine_elements ()
 Only refines the user-requested elements. More...
 
void uniformly_refine (unsigned int n=1)
 Uniformly refines the mesh n times. More...
 
void uniformly_coarsen (unsigned int n=1)
 Attempts to uniformly coarsen the mesh n times. More...
 
void uniformly_p_refine (unsigned int n=1)
 Uniformly p refines the mesh n times. More...
 
void uniformly_p_coarsen (unsigned int n=1)
 Attempts to uniformly p coarsen the mesh n times. More...
 
void clean_refinement_flags ()
 Sets the refinement flag to Elem::DO_NOTHING for each element in the mesh. More...
 
bool test_level_one (bool libmesh_assert_yes=false) const
 
bool test_unflagged (bool libmesh_assert_yes=false) const
 
Nodeadd_node (Elem &parent, unsigned int child, unsigned int node, processor_id_type proc_id)
 Add a node to the mesh. More...
 
Elemadd_elem (Elem *elem)
 Adds the element elem to the mesh. More...
 
Elemadd_elem (std::unique_ptr< Elem > elem)
 Same as the function above, but makes it clear that the MeshRefinement object (actually, its Mesh) takes ownership of the Elem which is passed in, so the user is not responsible for deleting it. More...
 
const MeshBaseget_mesh () const
 
MeshBaseget_mesh ()
 
bool & coarsen_by_parents ()
 If coarsen_by_parents is true, complete groups of sibling elements (elements with the same parent) will be flagged for coarsening. More...
 
Realrefine_fraction ()
 The refine_fraction sets either a desired target or a desired maximum number of elements to flag for refinement, depending on which flag_elements_by method is called. More...
 
Realcoarsen_fraction ()
 The coarsen_fraction sets either a desired target or a desired maximum number of elements to flag for coarsening, depending on which flag_elements_by method is called. More...
 
unsigned intmax_h_level ()
 The max_h_level is the greatest refinement level an element should reach. More...
 
Realcoarsen_threshold ()
 The coarsen_threshold provides hysteresis in AMR/C strategies. More...
 
dof_id_typenelem_target ()
 If nelem_target is set to a nonzero value, methods like flag_elements_by_nelem_target() will attempt to keep the number of active elements in the mesh close to nelem_target. More...
 
Realabsolute_global_tolerance ()
 If absolute_global_tolerance is set to a nonzero value, methods like flag_elements_by_global_tolerance() will attempt to reduce the global error of the mesh (defined as the square root of the sum of the squares of the errors on active elements) to below this tolerance. More...
 
unsigned char & face_level_mismatch_limit ()
 If face_level_mismatch_limit is set to a nonzero value, then refinement and coarsening will produce meshes in which the refinement level of two face neighbors will not differ by more than that limit. More...
 
unsigned char & edge_level_mismatch_limit ()
 If edge_level_mismatch_limit is set to a nonzero value, then refinement and coarsening will produce meshes in which the refinement level of two edge neighbors will not differ by more than that limit. More...
 
unsigned char & node_level_mismatch_limit ()
 If node_level_mismatch_limit is set to a nonzero value, then refinement and coarsening will produce meshes in which the refinement level of two nodal neighbors will not differ by more than that limit. More...
 
signed char & overrefined_boundary_limit ()
 If overrefined_boundary_limit is set to a nonnegative value, then refinement and coarsening will produce meshes in which the refinement level of a boundary element is no more than that many levels greater than the level of any of its interior neighbors. More...
 
signed char & underrefined_boundary_limit ()
 If underrefined_boundary_limit is set to a nonnegative value, then refinement and coarsening will produce meshes in which the refinement level of an element is no more than that many levels greater than the level of any boundary elements on its sides. More...
 
bool & allow_unrefined_patches ()
 This flag defaults to false in order to maintain the original behavior of the code, which was to always eliminate unrefined element patches. More...
 
bool make_flags_parallel_consistent ()
 Copy refinement flags on ghost elements from their local processors. More...
 
bool get_enforce_mismatch_limit_prior_to_refinement ()
 
void set_enforce_mismatch_limit_prior_to_refinement (bool enforce)
 Set _enforce_mismatch_limit_prior_to_refinement option. More...
 
bool & enforce_mismatch_limit_prior_to_refinement ()
 Get/set the _enforce_mismatch_limit_prior_to_refinement flag. More...
 
const Parallel::Communicatorcomm () const
 
processor_id_type n_processors () const
 
processor_id_type processor_id () const
 

Protected Attributes

const Parallel::Communicator_communicator
 

Private Types

enum  NeighborType { POINT, EDGE }
 This helper function enforces the desired mismatch limits prior to refinement. More...
 

Private Member Functions

 MeshRefinement (const MeshRefinement &)
 
MeshRefinementoperator= (const MeshRefinement &)
 
bool _coarsen_elements ()
 Coarsens user-requested elements. More...
 
bool _refine_elements ()
 Refines user-requested elements. More...
 
void _smooth_flags (bool refining, bool coarsening)
 Smooths refinement flags according to current settings. More...
 
bool limit_level_mismatch_at_node (const unsigned int max_mismatch)
 
This algorithm restricts the maximum level mismatch at any node in the mesh. More...
 
bool limit_level_mismatch_at_edge (const unsigned int max_mismatch)
 
bool limit_overrefined_boundary (const signed char max_mismatch)
 
bool limit_underrefined_boundary (const signed char max_mismatch)
 
bool eliminate_unrefined_patches ()
 
This algorithm selects an element for refinement if all of its neighbors are (or will be) refined. More...
 
void create_parent_error_vector (const ErrorVector &error_per_cell, ErrorVector &error_per_parent, Real &parent_error_min, Real &parent_error_max)
 Calculates the error on all coarsenable parents. More...
 
void update_nodes_map ()
 Updates the _new_nodes_map. More...
 
bool make_coarsening_compatible ()
 Take user-specified coarsening flags and augment them so that level-one dependency is satisfied. More...
 
bool make_refinement_compatible ()
 Take user-specified refinement flags and augment them so that level-one dependency is satisfied. More...
 
Elemtopological_neighbor (Elem *elem, const PointLocatorBase *point_locator, const unsigned int side) const
 Local dispatch function for getting the correct topological neighbor from the Elem class. More...
 
bool has_topological_neighbor (const Elem *elem, const PointLocatorBase *point_locator, const Elem *neighbor) const
 Local dispatch function for checking the correct has_neighbor function from the Elem class. More...
 
bool enforce_mismatch_limit_prior_to_refinement (Elem *elem, NeighborType nt, unsigned max_mismatch)
 

Private Attributes

TopologyMap _new_nodes_map
 Data structure that holds the new nodes information. More...
 
MeshBase_mesh
 Reference to the mesh. More...
 
bool _use_member_parameters
 For backwards compatibility, we initialize this as false and then set it to true if the user uses any of the refinement parameter accessor functions. More...
 
bool _coarsen_by_parents
 Refinement parameter values. More...
 
Real _refine_fraction
 
Real _coarsen_fraction
 
unsigned int _max_h_level
 
Real _coarsen_threshold
 
dof_id_type _nelem_target
 
Real _absolute_global_tolerance
 
unsigned char _face_level_mismatch_limit
 
unsigned char _edge_level_mismatch_limit
 
unsigned char _node_level_mismatch_limit
 
signed char _overrefined_boundary_limit
 
signed char _underrefined_boundary_limit
 
bool _allow_unrefined_patches
 
bool _enforce_mismatch_limit_prior_to_refinement
 
This option enforces the mismatch level prior to refinement by checking if refining any element marked for refinement would cause a mismatch greater than the limit. More...
 
PeriodicBoundaries_periodic_boundaries
 

Detailed Description

Implements (adaptive) mesh refinement algorithms for a MeshBase.

Note
Before using any of the algorithms in this class on a distributed mesh, the user needs to make sure that the mesh is prepared (MeshBase::prepare_for_use).
Author
Benjamin S. Kirk
Date
2002-2007 Responsible for mesh refinement algorithms and data.

Definition at line 61 of file mesh_refinement.h.

Member Enumeration Documentation

◆ NeighborType

This helper function enforces the desired mismatch limits prior to refinement.

It is called from the MeshRefinement::limit_level_mismatch_at_edge() and MeshRefinement::limit_level_mismatch_at_node() functions.

Returns
true if this enforcement caused the refinement flags for elem to change, false otherwise.
Enumerator
POINT 
EDGE 

Definition at line 885 of file mesh_refinement.h.

Constructor & Destructor Documentation

◆ MeshRefinement() [1/2]

libMesh::MeshRefinement::MeshRefinement ( MeshBase mesh)
explicit

Constructor.

Definition at line 94 of file mesh_refinement.C.

94  :
95  ParallelObject(m),
96  _mesh(m),
98  _coarsen_by_parents(false),
99  _refine_fraction(0.3),
100  _coarsen_fraction(0.0),
102  _coarsen_threshold(10),
103  _nelem_target(0),
112 #ifdef LIBMESH_ENABLE_PERIODIC
113  , _periodic_boundaries(nullptr)
114 #endif
115 {
116 }
117 
118 
119 
120 #ifdef LIBMESH_ENABLE_PERIODIC
121 void MeshRefinement::set_periodic_boundaries_ptr(PeriodicBoundaries * pb_ptr)
122 {
123  _periodic_boundaries = pb_ptr;
124 }
ParallelObject(const Parallel::Communicator &comm_in)
Constructor.
const unsigned int invalid_uint
A number which is used quite often to represent an invalid or uninitialized value for an unsigned int...
Definition: libmesh.h:310
MeshBase & _mesh
Reference to the mesh.
PeriodicBoundaries * _periodic_boundaries
signed char _underrefined_boundary_limit
unsigned char _face_level_mismatch_limit
bool _use_member_parameters
For backwards compatibility, we initialize this as false and then set it to true if the user uses any...
signed char _overrefined_boundary_limit
bool _enforce_mismatch_limit_prior_to_refinement
This option enforces the mismatch level prior to refinement by checking if refining any element mar...
unsigned char _node_level_mismatch_limit
unsigned char _edge_level_mismatch_limit
void set_periodic_boundaries_ptr(PeriodicBoundaries *pb_ptr)
Sets the PeriodicBoundaries pointer.
bool _coarsen_by_parents
Refinement parameter values.

◆ MeshRefinement() [2/2]

libMesh::MeshRefinement::MeshRefinement ( const MeshRefinement )
private

◆ ~MeshRefinement()

libMesh::MeshRefinement::~MeshRefinement ( )
default

Destructor.

Deletes all the elements that are currently stored.

Member Function Documentation

◆ _coarsen_elements()

bool libMesh::MeshRefinement::_coarsen_elements ( )
private

Coarsens user-requested elements.

Both coarsen_elements and refine_elements used to be in the public interface for the MeshRefinement object. Unfortunately, without proper preparation (make_refinement_compatible, make_coarsening_compatible) at least coarsen_elements() did not work alone. By making them private, we signal to the user that they are not part of the interface. It is possible that for a given set of refinement flags there is actually no change upon calling this member function.

Returns
true if the mesh actually changed (hence data needs to be projected) and false otherwise.

Definition at line 1333 of file mesh_refinement.C.

References _mesh, clear(), libMesh::Elem::COARSEN, libMesh::Elem::COARSEN_INACTIVE, libMesh::ParallelObject::comm(), libMesh::Elem::DO_NOTHING, libMesh::MeshBase::get_boundary_info(), libMesh::BoundaryInfo::is_children_on_boundary_side(), libMesh::MeshBase::is_serial(), libMesh::Elem::JUST_COARSENED, libMesh::libmesh_assert(), libMesh::MeshCommunication::make_nodes_parallel_consistent(), libMesh::MeshCommunication::make_p_levels_parallel_consistent(), TIMPI::Communicator::max(), libMesh::BoundaryInfo::remove(), libMesh::MeshCommunication::send_coarse_ghosts(), libMesh::BoundaryInfo::transfer_boundary_ids_from_children(), update_nodes_map(), and libMesh::MeshBase::update_parallel_id_counts().

Referenced by coarsen_elements(), refine_and_coarsen_elements(), and uniformly_coarsen().

1334 {
1335  // This function must be run on all processors at once
1336  parallel_object_only();
1337 
1338  LOG_SCOPE ("_coarsen_elements()", "MeshRefinement");
1339 
1340  // Flags indicating if this call actually changes the mesh
1341  bool mesh_changed = false;
1342  bool mesh_p_changed = false;
1343 
1344  // Clear the unused_elements data structure.
1345  // The elements have been packed since it was built,
1346  // so there are _no_ unused elements. We cannot trust
1347  // any iterators currently in this data structure.
1348  // _unused_elements.clear();
1349 
1350  // Loop over the elements first to determine if the mesh will
1351  // undergo h-coarsening. If it will, then we'll need to communicate
1352  // more ghosted elements. We need to communicate them *before* we
1353  // do the coarsening; otherwise it is possible to coarsen away a
1354  // one-element-thick layer partition and leave the partitions on
1355  // either side unable to figure out how to talk to each other.
1356  for (auto & elem : _mesh.element_ptr_range())
1357  if (elem->refinement_flag() == Elem::COARSEN)
1358  {
1359  mesh_changed = true;
1360  break;
1361  }
1362 
1363  // If the mesh changed on any processor, it changed globally
1364  this->comm().max(mesh_changed);
1365 
1366  // And then we may need to widen the ghosting layers.
1367  if (mesh_changed)
1368  MeshCommunication().send_coarse_ghosts(_mesh);
1369 
1370  for (auto & elem : _mesh.element_ptr_range())
1371  {
1372  // Make sure we transfer the children's boundary id(s)
1373  // up to its parent when necessary before coarsening.
1375 
1376  // active elements flagged for coarsening will
1377  // no longer be deleted until MeshRefinement::contract()
1378  if (elem->refinement_flag() == Elem::COARSEN)
1379  {
1380  // Huh? no level-0 element should be active
1381  // and flagged for coarsening.
1382  libmesh_assert_not_equal_to (elem->level(), 0);
1383 
1384  // Remove this element from any neighbor
1385  // lists that point to it.
1386  elem->nullify_neighbors();
1387 
1388  // Remove any boundary information associated
1389  // with this element if we do not allow children to have boundary info.
1390  // Otherwise, we will do the removal in `transfer_boundary_ids_from_children`
1391  // to make sure we don't delete the information before it is transferred
1393  _mesh.get_boundary_info().remove (elem);
1394 
1395  // Add this iterator to the _unused_elements
1396  // data structure so we might fill it.
1397  // The _unused_elements optimization is currently off.
1398  // _unused_elements.push_back (it);
1399 
1400  // Don't delete the element until
1401  // MeshRefinement::contract()
1402  // _mesh.delete_elem(elem);
1403  }
1404 
1405  // inactive elements flagged for coarsening
1406  // will become active
1407  else if (elem->refinement_flag() == Elem::COARSEN_INACTIVE)
1408  {
1409  elem->coarsen();
1410  libmesh_assert (elem->active());
1411 
1412  // the mesh has certainly changed
1413  mesh_changed = true;
1414  }
1415  if (elem->p_refinement_flag() == Elem::COARSEN)
1416  {
1417  if (elem->p_level() > 0)
1418  {
1419  elem->set_p_refinement_flag(Elem::JUST_COARSENED);
1420  elem->set_p_level(elem->p_level() - 1);
1421  mesh_p_changed = true;
1422  }
1423  else
1424  {
1425  elem->set_p_refinement_flag(Elem::DO_NOTHING);
1426  }
1427  }
1428  }
1429 
1430  this->comm().max(mesh_p_changed);
1431 
1432  // And we may need to update DistributedMesh values reflecting the changes
1433  if (mesh_changed)
1435 
1436  // Node processor ids may need to change if an element of that id
1437  // was coarsened away
1438  if (mesh_changed && !_mesh.is_serial())
1439  {
1440  // Update the _new_nodes_map so that processors can
1441  // find requested nodes
1442  this->update_nodes_map ();
1443 
1444  MeshCommunication().make_nodes_parallel_consistent (_mesh);
1445 
1446  // Clear the _new_nodes_map
1447  this->clear();
1448 
1449 #ifdef DEBUG
1450  MeshTools::libmesh_assert_valid_procids<Node>(_mesh);
1451 #endif
1452  }
1453 
1454  // If p levels changed all we need to do is make sure that parent p
1455  // levels changed in sync
1456  if (mesh_p_changed && !_mesh.is_serial())
1457  {
1458  MeshCommunication().make_p_levels_parallel_consistent (_mesh);
1459  }
1460 
1461  return (mesh_changed || mesh_p_changed);
1462 }
void update_nodes_map()
Updates the _new_nodes_map.
MeshBase & _mesh
Reference to the mesh.
void remove(const Node *node)
Removes the boundary conditions associated with node node, if any exist.
const Parallel::Communicator & comm() const
const BoundaryInfo & get_boundary_info() const
The information about boundary ids on the mesh.
Definition: mesh_base.h:165
virtual bool is_serial() const
Definition: mesh_base.h:211
virtual void update_parallel_id_counts()=0
Updates parallel caches so that methods like n_elem() accurately reflect changes on other processors...
libmesh_assert(ctx)
void max(const T &r, T &o, Request &req) const
void clear()
Deletes all the data that are currently stored.
bool is_children_on_boundary_side() const
void transfer_boundary_ids_from_children(const Elem *const parent)
Update parent&#39;s boundary id list so that this information is consistent with its children.

◆ _refine_elements()

bool libMesh::MeshRefinement::_refine_elements ( )
private

Refines user-requested elements.

It is possible that for a given set of refinement flags there is actually no change upon calling this member function.

Returns
true if the mesh actually changed (hence data needs to be projected) and false otherwise.

Definition at line 1466 of file mesh_refinement.C.

References _mesh, libMesh::as_range(), clear(), libMesh::ParallelObject::comm(), libMesh::MeshBase::is_prepared(), libMesh::MeshBase::is_replicated(), libMesh::Elem::JUST_REFINED, libMesh::libmesh_assert(), libMesh::MeshBase::libmesh_assert_valid_parallel_ids(), libMesh::MeshCommunication::make_elems_parallel_consistent(), libMesh::MeshCommunication::make_new_nodes_parallel_consistent(), libMesh::MeshCommunication::make_p_levels_parallel_consistent(), TIMPI::Communicator::max(), libMesh::Elem::REFINE, libMesh::Partitioner::set_node_processor_ids(), update_nodes_map(), and libMesh::MeshBase::update_parallel_id_counts().

Referenced by refine_and_coarsen_elements(), refine_elements(), and uniformly_refine().

1467 {
1469 
1470  // This function must be run on all processors at once
1471  parallel_object_only();
1472 
1473  // Update the _new_nodes_map so that elements can
1474  // find nodes to connect to.
1475  this->update_nodes_map ();
1476 
1477  LOG_SCOPE ("_refine_elements()", "MeshRefinement");
1478 
1479  // Iterate over the elements, counting the elements
1480  // flagged for h refinement.
1481  dof_id_type n_elems_flagged = 0;
1482 
1483  for (auto & elem : _mesh.element_ptr_range())
1484  if (elem->refinement_flag() == Elem::REFINE)
1485  n_elems_flagged++;
1486 
1487  // Construct a local vector of Elem * which have been
1488  // previously marked for refinement. We reserve enough
1489  // space to allow for every element to be refined.
1490  std::vector<Elem *> local_copy_of_elements;
1491  local_copy_of_elements.reserve(n_elems_flagged);
1492 
1493  // If mesh p levels changed, we might need to synchronize parent p
1494  // levels on a distributed mesh.
1495  bool mesh_p_changed = false;
1496 
1497  // Iterate over the elements, looking for elements flagged for
1498  // refinement.
1499 
1500  // If we are on a ReplicatedMesh, then we just do the refinement in
1501  // the same order on every processor and everything stays in sync.
1502 
1503  // If we are on a DistributedMesh, that's impossible.
1504  //
1505  // If the mesh is distributed, we need to make sure that if we end
1506  // up as the owner of a new node, which might happen if that node is
1507  // attached to one of our own elements, then we have given it a
1508  // legitimate node id and our own processor id. We generate
1509  // legitimate node ids and use our own processor id when we are
1510  // refining our own elements but not when we refine others'
1511  // elements. Therefore we want to refine our own elements *first*,
1512  // thereby generating all nodes which might belong to us, and then
1513  // refine others' elements *after*, thereby generating nodes with
1514  // temporary ids which we know we will discard.
1515  //
1516  // Even if the DistributedMesh is serialized, we can't just treat it
1517  // like a ReplicatedMesh, because DistributedMesh doesn't *trust*
1518  // users to refine partitioned elements in a serialized way, so it
1519  // assigns temporary ids, so we need to synchronize ids afterward to
1520  // be safe anyway, so we might as well use the distributed mesh code
1521  // path.
1522  for (auto & elem : _mesh.is_replicated() ? _mesh.active_element_ptr_range() : _mesh.active_local_element_ptr_range())
1523  {
1524  if (elem->refinement_flag() == Elem::REFINE)
1525  local_copy_of_elements.push_back(elem);
1526  if (elem->p_refinement_flag() == Elem::REFINE &&
1527  elem->active())
1528  {
1529  elem->set_p_level(elem->p_level()+1);
1530  elem->set_p_refinement_flag(Elem::JUST_REFINED);
1531  mesh_p_changed = true;
1532  }
1533  }
1534 
1535  if (!_mesh.is_replicated())
1536  {
1537  for (auto & elem : as_range(_mesh.active_not_local_elements_begin(),
1538  _mesh.active_not_local_elements_end()))
1539  {
1540  if (elem->refinement_flag() == Elem::REFINE)
1541  local_copy_of_elements.push_back(elem);
1542  if (elem->p_refinement_flag() == Elem::REFINE &&
1543  elem->active())
1544  {
1545  elem->set_p_level(elem->p_level()+1);
1546  elem->set_p_refinement_flag(Elem::JUST_REFINED);
1547  mesh_p_changed = true;
1548  }
1549  }
1550  }
1551 
1552  // Now iterate over the local copies and refine each one.
1553  // This may resize the mesh's internal container and invalidate
1554  // any existing iterators.
1555  for (auto & elem : local_copy_of_elements)
1556  elem->refine(*this);
1557 
1558  // The mesh changed if there were elements h refined
1559  bool mesh_changed = !local_copy_of_elements.empty();
1560 
1561  // If the mesh changed on any processor, it changed globally
1562  this->comm().max(mesh_changed);
1563  this->comm().max(mesh_p_changed);
1564 
1565  // And we may need to update DistributedMesh values reflecting the changes
1566  if (mesh_changed)
1568 
1569  if (mesh_changed && !_mesh.is_replicated())
1570  {
1571  MeshCommunication().make_elems_parallel_consistent (_mesh);
1572  MeshCommunication().make_new_nodes_parallel_consistent (_mesh);
1573 #ifdef DEBUG
1575 #endif
1576  }
1577 
1578  // If we're refining a ReplicatedMesh, then we haven't yet assigned
1579  // node processor ids. But if we're refining a partitioned
1580  // ReplicatedMesh, then we *need* to assign node processor ids.
1581  if (mesh_changed && _mesh.is_replicated() &&
1582  (_mesh.unpartitioned_elements_begin() ==
1583  _mesh.unpartitioned_elements_end()))
1585 
1586  if (mesh_p_changed && !_mesh.is_replicated())
1587  {
1588  MeshCommunication().make_p_levels_parallel_consistent (_mesh);
1589  }
1590 
1591  // Clear the _new_nodes_map and _unused_elements data structures.
1592  this->clear();
1593 
1594  return (mesh_changed || mesh_p_changed);
1595 }
bool is_prepared() const
Definition: mesh_base.h:198
void update_nodes_map()
Updates the _new_nodes_map.
MeshBase & _mesh
Reference to the mesh.
static void set_node_processor_ids(MeshBase &mesh)
This function is called after partitioning to set the processor IDs for the nodes.
Definition: partitioner.C:852
const Parallel::Communicator & comm() const
virtual void update_parallel_id_counts()=0
Updates parallel caches so that methods like n_elem() accurately reflect changes on other processors...
SimpleRange< IndexType > as_range(const std::pair< IndexType, IndexType > &p)
Helper function that allows us to treat a homogenous pair as a range.
Definition: simple_range.h:57
libmesh_assert(ctx)
void max(const T &r, T &o, Request &req) const
virtual bool is_replicated() const
Definition: mesh_base.h:233
void clear()
Deletes all the data that are currently stored.
virtual void libmesh_assert_valid_parallel_ids() const
Verify id and processor_id consistency of our elements and nodes containers.
Definition: mesh_base.h:1522
uint8_t dof_id_type
Definition: id_types.h:67

◆ _smooth_flags()

void libMesh::MeshRefinement::_smooth_flags ( bool  refining,
bool  coarsening 
)
private

Smooths refinement flags according to current settings.

It is possible that for a given set of refinement flags there is actually no change upon calling this member function.

Returns
true if the flags actually changed (hence data needs to be projected) and false otherwise.

Definition at line 1598 of file mesh_refinement.C.

References _edge_level_mismatch_limit, _mesh, _node_level_mismatch_limit, _overrefined_boundary_limit, _underrefined_boundary_limit, libMesh::ParallelObject::comm(), eliminate_unrefined_patches(), libMesh::MeshBase::is_serial(), libMesh::libmesh_assert(), libMesh::MeshTools::libmesh_assert_valid_neighbors(), limit_level_mismatch_at_edge(), limit_level_mismatch_at_node(), limit_overrefined_boundary(), limit_underrefined_boundary(), make_coarsening_compatible(), make_flags_parallel_consistent(), and make_refinement_compatible().

Referenced by coarsen_elements(), refine_and_coarsen_elements(), and refine_elements().

1599 {
1600  // Smoothing can break in weird ways on a mesh with broken topology
1601 #ifdef DEBUG
1603 #endif
1604 
1605  // Repeat until flag changes match on every processor
1606  do
1607  {
1608  // Repeat until coarsening & refinement flags jive
1609  bool satisfied = false;
1610  do
1611  {
1612  // If we're refining or coarsening, hit the corresponding
1613  // face level test code. Short-circuiting || is our friend
1614  const bool coarsening_satisfied =
1615  !coarsening ||
1617 
1618  const bool refinement_satisfied =
1619  !refining ||
1621 
1622  bool smoothing_satisfied =
1623  !this->eliminate_unrefined_patches();// &&
1624 
1626  smoothing_satisfied = smoothing_satisfied &&
1628 
1630  smoothing_satisfied = smoothing_satisfied &&
1632 
1634  smoothing_satisfied = smoothing_satisfied &&
1636 
1638  smoothing_satisfied = smoothing_satisfied &&
1640 
1641  satisfied = (coarsening_satisfied &&
1642  refinement_satisfied &&
1643  smoothing_satisfied);
1644 
1645  libmesh_assert(this->comm().verify(satisfied));
1646  }
1647  while (!satisfied);
1648  }
1649  while (!_mesh.is_serial() && !this->make_flags_parallel_consistent());
1650 }
bool limit_level_mismatch_at_edge(const unsigned int max_mismatch)
bool limit_level_mismatch_at_node(const unsigned int max_mismatch)
This algorithm restricts the maximum level mismatch at any node in the mesh.
bool limit_underrefined_boundary(const signed char max_mismatch)
MeshBase & _mesh
Reference to the mesh.
const Parallel::Communicator & comm() const
bool limit_overrefined_boundary(const signed char max_mismatch)
signed char _underrefined_boundary_limit
bool make_refinement_compatible()
Take user-specified refinement flags and augment them so that level-one dependency is satisfied...
virtual bool is_serial() const
Definition: mesh_base.h:211
libmesh_assert(ctx)
bool make_flags_parallel_consistent()
Copy refinement flags on ghost elements from their local processors.
signed char _overrefined_boundary_limit
bool make_coarsening_compatible()
Take user-specified coarsening flags and augment them so that level-one dependency is satisfied...
unsigned char _node_level_mismatch_limit
unsigned char _edge_level_mismatch_limit
void libmesh_assert_valid_neighbors(const MeshBase &mesh, bool assert_valid_remote_elems=true)
A function for verifying that neighbor connectivity is correct (each element is a neighbor of or desc...
Definition: mesh_tools.C:2205
bool eliminate_unrefined_patches()
This algorithm selects an element for refinement if all of its neighbors are (or will be) refined...

◆ absolute_global_tolerance()

Real & libMesh::MeshRefinement::absolute_global_tolerance ( )
inline

If absolute_global_tolerance is set to a nonzero value, methods like flag_elements_by_global_tolerance() will attempt to reduce the global error of the mesh (defined as the square root of the sum of the squares of the errors on active elements) to below this tolerance.

absolute_global_tolerance is 0 by default.

Definition at line 936 of file mesh_refinement.h.

References _absolute_global_tolerance, and _use_member_parameters.

Referenced by main().

937 {
938  _use_member_parameters = true;
940 }
bool _use_member_parameters
For backwards compatibility, we initialize this as false and then set it to true if the user uses any...

◆ add_elem() [1/2]

Elem * libMesh::MeshRefinement::add_elem ( Elem elem)

Adds the element elem to the mesh.

Definition at line 207 of file mesh_refinement.C.

References _mesh, libMesh::MeshBase::add_elem(), and libMesh::libmesh_assert().

Referenced by libMesh::Elem::refine().

208 {
209  libmesh_assert(elem);
210  return _mesh.add_elem (elem);
211 }
MeshBase & _mesh
Reference to the mesh.
virtual Elem * add_elem(Elem *e)=0
Add elem e to the end of the element array.
libmesh_assert(ctx)

◆ add_elem() [2/2]

Elem * libMesh::MeshRefinement::add_elem ( std::unique_ptr< Elem elem)

Same as the function above, but makes it clear that the MeshRefinement object (actually, its Mesh) takes ownership of the Elem which is passed in, so the user is not responsible for deleting it.

The version of add_elem() taking a dumb pointer will eventually be deprecated in favor of this version.

Definition at line 213 of file mesh_refinement.C.

References _mesh, libMesh::MeshBase::add_elem(), and libMesh::libmesh_assert().

214 {
215  libmesh_assert(elem);
216  return _mesh.add_elem(std::move(elem));
217 }
MeshBase & _mesh
Reference to the mesh.
virtual Elem * add_elem(Elem *e)=0
Add elem e to the end of the element array.
libmesh_assert(ctx)

◆ add_node()

Node * libMesh::MeshRefinement::add_node ( Elem parent,
unsigned int  child,
unsigned int  node,
processor_id_type  proc_id 
)

Add a node to the mesh.

The node should be node n of child c of parent Elem parent. The processor id proc_id is used if necessary to help determine numbering of newly created nodes, but newly created nodes are left unpartitioned until a node partitionining sweep is done later.

Returns
A pointer to a suitable existing or newly-created node.

Definition at line 140 of file mesh_refinement.C.

References _mesh, _new_nodes_map, libMesh::TopologyMap::add_node(), libMesh::MeshBase::add_point(), libMesh::TypeVector< T >::add_scaled(), libMesh::Elem::as_parent_node(), libMesh::Elem::bracketing_nodes(), libMesh::Elem::embedding_matrix(), libMesh::TopologyMap::find(), libMesh::DofObject::invalid_id, libMesh::DofObject::invalid_processor_id, libMesh::invalid_uint, libMesh::libmesh_assert(), libMesh::Elem::node_index_range(), libMesh::Elem::node_ptr(), libMesh::MeshBase::node_ptr(), libMesh::Elem::point(), libMesh::DofObject::processor_id(), and libMesh::Real.

Referenced by libMesh::Elem::refine().

144 {
145  LOG_SCOPE("add_node()", "MeshRefinement");
146 
147  unsigned int parent_n = parent.as_parent_node(child, node);
148 
149  if (parent_n != libMesh::invalid_uint)
150  return parent.node_ptr(parent_n);
151 
152  const std::vector<std::pair<dof_id_type, dof_id_type>>
153  bracketing_nodes = parent.bracketing_nodes(child, node);
154 
155  // If we're not a parent node, we *must* be bracketed by at least
156  // one pair of parent nodes
157  libmesh_assert(bracketing_nodes.size());
158 
159  // Return the node if it already exists.
160  //
161  // We'll leave the processor_id untouched in this case - if we're
162  // repartitioning later or if this is a new unpartitioned node,
163  // we'll update it then, and if not then we don't want to update it.
164  if (const auto new_node_id = _new_nodes_map.find(bracketing_nodes);
165  new_node_id != DofObject::invalid_id)
166  return _mesh.node_ptr(new_node_id);
167 
168  // Otherwise we need to add a new node.
169  //
170  // Figure out where to add the point:
171 
172  Point p; // defaults to 0,0,0
173 
174  for (auto n : parent.node_index_range())
175  {
176  // The value from the embedding matrix
177  const Real em_val = parent.embedding_matrix(child,node,n);
178 
179  if (em_val != 0.)
180  {
181  p.add_scaled (parent.point(n), em_val);
182 
183  // If we'd already found the node we shouldn't be here
184  libmesh_assert_not_equal_to (em_val, 1);
185  }
186  }
187 
188  // Although we're leaving new nodes unpartitioned at first, with a
189  // DistributedMesh we would need a default id based on the numbering
190  // scheme for the requested processor_id.
191  Node * new_node = _mesh.add_point (p, DofObject::invalid_id, proc_id);
192 
193  libmesh_assert(new_node);
194 
195  // But then we'll make sure this node is marked as unpartitioned.
196  new_node->processor_id() = DofObject::invalid_processor_id;
197 
198  // Add the node to the map.
199  _new_nodes_map.add_node(*new_node, bracketing_nodes);
200 
201  // Return the address of the new node
202  return new_node;
203 }
const unsigned int invalid_uint
A number which is used quite often to represent an invalid or uninitialized value for an unsigned int...
Definition: libmesh.h:310
TopologyMap _new_nodes_map
Data structure that holds the new nodes information.
MeshBase & _mesh
Reference to the mesh.
dof_id_type find(dof_id_type bracket_node1, dof_id_type bracket_node2) const
Definition: topology_map.C:115
void add_node(const Node &mid_node, const std::vector< std::pair< dof_id_type, dof_id_type >> &bracketing_nodes)
Add a node to the map, between each pair of specified bracketing nodes.
Definition: topology_map.C:53
virtual Node * add_point(const Point &p, const dof_id_type id=DofObject::invalid_id, const processor_id_type proc_id=DofObject::invalid_processor_id)=0
Add a new Node at Point p to the end of the vertex array, with processor_id procid.
static const processor_id_type invalid_processor_id
An invalid processor_id to distinguish DoFs that have not been assigned to a processor.
Definition: dof_object.h:493
libmesh_assert(ctx)
static const dof_id_type invalid_id
An invalid id to distinguish an uninitialized DofObject.
Definition: dof_object.h:482
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
virtual const Node * node_ptr(const dof_id_type i) const =0

◆ add_p_to_h_refinement()

void libMesh::MeshRefinement::add_p_to_h_refinement ( )

Takes a mesh whose elements are flagged for h refinement and coarsening, and adds flags to request p refinement and coarsening of the same elements.

Definition at line 673 of file mesh_refinement_flagging.C.

References _mesh.

Referenced by main().

674 {
675  for (auto & elem : _mesh.element_ptr_range())
676  elem->set_p_refinement_flag(elem->refinement_flag());
677 }
MeshBase & _mesh
Reference to the mesh.

◆ allow_unrefined_patches()

bool & libMesh::MeshRefinement::allow_unrefined_patches ( )
inline

This flag defaults to false in order to maintain the original behavior of the code, which was to always eliminate unrefined element patches.

If you set this flag to true, then the MeshRefinement::eliminate_unrefined_patches() function essentially does nothing, allowing such patches to persist. This may be particularly useful in e.g. 1D meshes where having unrefined patches does not introduce additional hanging nodes.

Definition at line 967 of file mesh_refinement.h.

References _allow_unrefined_patches.

968 {
970 }

◆ clean_refinement_flags()

void libMesh::MeshRefinement::clean_refinement_flags ( )

Sets the refinement flag to Elem::DO_NOTHING for each element in the mesh.

Definition at line 681 of file mesh_refinement_flagging.C.

References _mesh, libMesh::Elem::DO_NOTHING, and libMesh::Elem::INACTIVE.

Referenced by flag_elements_by_elem_fraction(), flag_elements_by_error_fraction(), flag_elements_by_nelem_target(), libMesh::EquationSystems::read(), libMesh::EquationSystems::reinit_mesh(), uniformly_coarsen(), and uniformly_refine().

682 {
683  // Possibly clean up the refinement flags from
684  // a previous step
685  for (auto & elem : _mesh.element_ptr_range())
686  {
687  if (elem->active())
688  {
689  elem->set_refinement_flag(Elem::DO_NOTHING);
690  elem->set_p_refinement_flag(Elem::DO_NOTHING);
691  }
692  else
693  {
694  elem->set_refinement_flag(Elem::INACTIVE);
695  elem->set_p_refinement_flag(Elem::INACTIVE);
696  }
697  }
698 }
MeshBase & _mesh
Reference to the mesh.

◆ clear()

void libMesh::MeshRefinement::clear ( )

Deletes all the data that are currently stored.

Definition at line 133 of file mesh_refinement.C.

References _new_nodes_map, and libMesh::TopologyMap::clear().

Referenced by _coarsen_elements(), and _refine_elements().

134 {
136 }
TopologyMap _new_nodes_map
Data structure that holds the new nodes information.

◆ coarsen_by_parents()

bool & libMesh::MeshRefinement::coarsen_by_parents ( )
inline

If coarsen_by_parents is true, complete groups of sibling elements (elements with the same parent) will be flagged for coarsening.

This should make the coarsening more likely to occur as requested.

coarsen_by_parents is true by default.

Definition at line 900 of file mesh_refinement.h.

References _coarsen_by_parents, and _use_member_parameters.

Referenced by main().

901 {
902  _use_member_parameters = true;
903  return _coarsen_by_parents;
904 }
bool _use_member_parameters
For backwards compatibility, we initialize this as false and then set it to true if the user uses any...
bool _coarsen_by_parents
Refinement parameter values.

◆ coarsen_elements()

bool libMesh::MeshRefinement::coarsen_elements ( )

Only coarsens the user-requested elements.

Some elements will not be coarsened to satisfy the level one rule. It is possible that for a given set of refinement flags there is actually no change upon calling this member function.

Returns
true if the mesh actually changed (hence data needs to be projected) and false otherwise.
Note
This function used to take an argument, maintain_level_one, new code should use face_level_mismatch_limit() instead.
When we allow boundaries to be directly associated with child elements, i.e., _children_on_boundary = true. A child's boundary ID may be lost during coarsening if it differs from its siblings on that parent side.

Definition at line 608 of file mesh_refinement.C.

References _coarsen_elements(), _face_level_mismatch_limit, _mesh, _smooth_flags(), libMesh::Elem::DO_NOTHING, libMesh::Elem::INACTIVE, libMesh::Elem::JUST_REFINED, libMesh::libmesh_assert(), make_coarsening_compatible(), make_flags_parallel_consistent(), libMesh::MeshBase::prepare_for_use(), and test_level_one().

Referenced by libMesh::EquationSystems::reinit_solutions(), and BoundaryInfoTest::testBoundaryOnChildrenElementsRefineCoarsen().

609 {
610  // This function must be run on all processors at once
611  parallel_object_only();
612 
613  // We can't yet turn a non-level-one mesh into a level-one mesh
616 
617  // Possibly clean up the refinement flags from
618  // a previous step
619  for (auto & elem : _mesh.element_ptr_range())
620  {
621  // Set refinement flag to INACTIVE if the
622  // element isn't active
623  if (!elem->active())
624  {
625  elem->set_refinement_flag(Elem::INACTIVE);
626  elem->set_p_refinement_flag(Elem::INACTIVE);
627  }
628 
629  // This might be left over from the last step
630  if (elem->refinement_flag() == Elem::JUST_REFINED)
631  elem->set_refinement_flag(Elem::DO_NOTHING);
632  }
633 
634  // Parallel consistency has to come first, or coarsening
635  // along processor boundaries might occasionally be falsely
636  // prevented
637  bool flags_were_consistent = this->make_flags_parallel_consistent();
638 
639  // In theory, we should be able to remove the above call, which can
640  // be expensive and should be unnecessary. In practice, doing
641  // consistent flagging in parallel is hard, it's impossible to
642  // verify at the library level if it's being done by user code, and
643  // we don't want to abort large parallel runs in opt mode... but we
644  // do want to warn that they should be fixed.
645  libmesh_assert(flags_were_consistent);
646 
647  if (!flags_were_consistent)
648  libmesh_warning("Warning: Refinement flags were not consistent between processors! "
649  "Correcting and continuing.\n");
650 
651  // Smooth coarsening flags
652  _smooth_flags(false, true);
653 
654  // Coarsen the flagged elements.
655  const bool mesh_changed =
656  this->_coarsen_elements ();
657 
661  // FIXME: This won't pass unless we add a redundant find_neighbors()
662  // call or replace find_neighbors() with on-the-fly neighbor updating
663  // libmesh_assert(!this->eliminate_unrefined_patches());
664 
665  // We can't contract the mesh ourselves anymore - a System might
666  // need to restrict old coefficient vectors first
667  // _mesh.contract();
668 
669  // Finally, the new mesh may need to be prepared for use
670  if (mesh_changed)
672 
673  return mesh_changed;
674 }
bool test_level_one(bool libmesh_assert_yes=false) const
MeshBase & _mesh
Reference to the mesh.
void prepare_for_use(const bool skip_renumber_nodes_and_elements, const bool skip_find_neighbors)
Prepare a newly ecreated (or read) mesh for use.
Definition: mesh_base.C:759
unsigned char _face_level_mismatch_limit
libmesh_assert(ctx)
bool make_flags_parallel_consistent()
Copy refinement flags on ghost elements from their local processors.
bool make_coarsening_compatible()
Take user-specified coarsening flags and augment them so that level-one dependency is satisfied...
void _smooth_flags(bool refining, bool coarsening)
Smooths refinement flags according to current settings.
bool _coarsen_elements()
Coarsens user-requested elements.

◆ coarsen_fraction()

Real & libMesh::MeshRefinement::coarsen_fraction ( )
inline

The coarsen_fraction sets either a desired target or a desired maximum number of elements to flag for coarsening, depending on which flag_elements_by method is called.

coarsen_fraction must be in \( [0,1] \), and is 0 by default.

Definition at line 912 of file mesh_refinement.h.

References _coarsen_fraction, and _use_member_parameters.

Referenced by assemble_and_solve(), and main().

913 {
914  _use_member_parameters = true;
915  return _coarsen_fraction;
916 }
bool _use_member_parameters
For backwards compatibility, we initialize this as false and then set it to true if the user uses any...

◆ coarsen_threshold()

Real & libMesh::MeshRefinement::coarsen_threshold ( )
inline

The coarsen_threshold provides hysteresis in AMR/C strategies.

Refinement of elements with error estimate E will be done even at the expense of coarsening elements whose children's accumulated error does not exceed coarsen_threshold * E.

coarsen_threshold must be in \( [0,1] \), and is 0.1 by default.

Definition at line 924 of file mesh_refinement.h.

References _coarsen_threshold, and _use_member_parameters.

Referenced by main().

925 {
926  _use_member_parameters = true;
927  return _coarsen_threshold;
928 }
bool _use_member_parameters
For backwards compatibility, we initialize this as false and then set it to true if the user uses any...

◆ comm()

const Parallel::Communicator& libMesh::ParallelObject::comm ( ) const
inlineinherited
Returns
A reference to the Parallel::Communicator object used by this mesh.

Definition at line 97 of file parallel_object.h.

References libMesh::ParallelObject::_communicator.

Referenced by libMesh::__libmesh_petsc_diff_solver_jacobian(), libMesh::__libmesh_petsc_diff_solver_monitor(), libMesh::__libmesh_petsc_diff_solver_residual(), libMesh::__libmesh_tao_equality_constraints(), libMesh::__libmesh_tao_equality_constraints_jacobian(), libMesh::__libmesh_tao_gradient(), libMesh::__libmesh_tao_hessian(), libMesh::__libmesh_tao_inequality_constraints(), libMesh::__libmesh_tao_inequality_constraints_jacobian(), libMesh::__libmesh_tao_objective(), _coarsen_elements(), libMesh::ExactSolution::_compute_error(), libMesh::UniformRefinementEstimator::_estimate_error(), libMesh::Partitioner::_find_global_index_by_pid_map(), libMesh::BoundaryInfo::_find_id_maps(), libMesh::PetscLinearSolver< Number >::_petsc_shell_matrix_get_diagonal(), libMesh::SlepcEigenSolver< libMesh::Number >::_petsc_shell_matrix_get_diagonal(), libMesh::PetscLinearSolver< Number >::_petsc_shell_matrix_mult(), libMesh::SlepcEigenSolver< libMesh::Number >::_petsc_shell_matrix_mult(), libMesh::PetscLinearSolver< Number >::_petsc_shell_matrix_mult_add(), _refine_elements(), _smooth_flags(), libMesh::DofMap::add_constraints_to_send_list(), add_cube_convex_hull_to_mesh(), libMesh::PetscDMWrapper::add_dofs_helper(), libMesh::PetscDMWrapper::add_dofs_to_section(), libMesh::TransientRBConstruction::add_IC_to_RB_space(), libMesh::RBEIMEvaluation::add_interpolation_data(), libMesh::CondensedEigenSystem::add_matrices(), libMesh::EigenSystem::add_matrices(), libMesh::System::add_matrix(), libMesh::RBConstruction::add_scaled_matrix_and_vector(), libMesh::System::add_variable(), libMesh::System::add_variables(), libMesh::System::add_vector(), libMesh::MeshTools::Modification::all_tri(), libMesh::LaplaceMeshSmoother::allgather_graph(), libMesh::DofMap::allgather_recursive_constraints(), libMesh::TransientRBConstruction::allocate_data_structures(), libMesh::RBConstruction::allocate_data_structures(), libMesh::TransientRBConstruction::assemble_affine_expansion(), libMesh::AdvectionSystem::assemble_claw_rhs(), libMesh::FEMSystem::assemble_qoi(), libMesh::Nemesis_IO::assert_symmetric_cmaps(), libMesh::MeshCommunication::assign_global_indices(), libMesh::Partitioner::assign_partitioning(), libMesh::MeshTools::Generation::build_extrusion(), libMesh::Partitioner::build_graph(), libMesh::BoundaryInfo::build_node_list_from_side_list(), libMesh::EquationSystems::build_parallel_elemental_solution_vector(), libMesh::EquationSystems::build_parallel_solution_vector(), libMesh::PetscDMWrapper::build_section(), libMesh::PetscDMWrapper::build_sf(), libMesh::MeshBase::cache_elem_data(), libMesh::System::calculate_norm(), libMesh::DofMap::check_dirichlet_bcid_consistency(), libMesh::RBConstruction::compute_Fq_representor_innerprods(), libMesh::RBConstruction::compute_max_error_bound(), libMesh::Nemesis_IO_Helper::compute_num_global_elem_blocks(), libMesh::Nemesis_IO_Helper::compute_num_global_nodesets(), libMesh::Nemesis_IO_Helper::compute_num_global_sidesets(), libMesh::RBConstruction::compute_output_dual_innerprods(), libMesh::RBConstruction::compute_residual_dual_norm_slow(), libMesh::RBSCMConstruction::compute_SCM_bounds_on_training_set(), libMesh::DofMap::computed_sparsity_already(), libMesh::Problem_Interface::computeF(), libMesh::Problem_Interface::computeJacobian(), libMesh::Problem_Interface::computePreconditioner(), libMesh::ContinuationSystem::ContinuationSystem(), libMesh::MeshBase::copy_constraint_rows(), libMesh::ExodusII_IO::copy_elemental_solution(), libMesh::ExodusII_IO::copy_nodal_solution(), libMesh::ExodusII_IO::copy_scalar_solution(), libMesh::CondensedEigenSystem::copy_super_to_sub(), libMesh::MeshTools::correct_node_proc_ids(), libMesh::MeshTools::create_bounding_box(), libMesh::DofMap::create_dof_constraints(), libMesh::MeshTools::create_nodal_bounding_box(), create_parent_error_vector(), libMesh::MeshTools::create_processor_bounding_box(), libMesh::MeshTools::create_subdomain_bounding_box(), libMesh::PetscMatrix< T >::create_submatrix_nosort(), create_wrapped_function(), libMesh::MeshCommunication::delete_remote_elements(), libMesh::RBEIMEvaluation::distribute_bfs(), DMlibMeshFunction(), DMlibMeshJacobian(), DMlibMeshSetSystem_libMesh(), DMVariableBounds_libMesh(), libMesh::DTKSolutionTransfer::DTKSolutionTransfer(), eliminate_unrefined_patches(), libMesh::RBEIMConstruction::enrich_eim_approximation_on_interiors(), libMesh::RBEIMConstruction::enrich_eim_approximation_on_nodes(), libMesh::RBEIMConstruction::enrich_eim_approximation_on_sides(), libMesh::TransientRBConstruction::enrich_RB_space(), libMesh::EpetraVector< T >::EpetraVector(), AssembleOptimization::equality_constraints(), libMesh::PatchRecoveryErrorEstimator::estimate_error(), libMesh::WeightedPatchRecoveryErrorEstimator::estimate_error(), libMesh::AdjointRefinementEstimator::estimate_error(), libMesh::ExactErrorEstimator::estimate_error(), libMesh::SmoothnessEstimator::estimate_smoothness(), flag_elements_by_elem_fraction(), flag_elements_by_error_fraction(), flag_elements_by_error_tolerance(), flag_elements_by_mean_stddev(), flag_elements_by_nelem_target(), libMesh::RBEIMEvaluation::gather_bfs(), libMesh::DofMap::gather_constraints(), libMesh::MeshfreeInterpolation::gather_remote_data(), libMesh::CondensedEigenSystem::get_eigenpair(), libMesh::RBEIMEvaluation::get_eim_basis_function_node_value(), libMesh::RBEIMEvaluation::get_eim_basis_function_side_value(), libMesh::RBEIMEvaluation::get_eim_basis_function_value(), libMesh::MeshBase::get_info(), libMesh::System::get_info(), libMesh::DofMap::get_info(), libMesh::RBEIMEvaluation::get_interior_basis_functions_as_vecs(), libMesh::ImplicitSystem::get_linear_solver(), libMesh::RBEIMConstruction::get_max_abs_value(), libMesh::RBEIMConstruction::get_node_max_abs_value(), libMesh::RBEIMEvaluation::get_parametrized_function_node_value(), libMesh::RBEIMEvaluation::get_parametrized_function_side_value(), libMesh::RBEIMEvaluation::get_parametrized_function_value(), libMesh::RBEIMConstruction::get_random_point(), AssembleOptimization::inequality_constraints(), AssembleOptimization::inequality_constraints_jacobian(), libMesh::LocationMap< T >::init(), libMesh::TimeSolver::init(), libMesh::StaticCondensation::init(), libMesh::SystemSubsetBySubdomain::init(), libMesh::PetscDMWrapper::init_and_attach_petscdm(), libMesh::AdvectionSystem::init_data(), libMesh::ClawSystem::init_data(), libMesh::PetscDMWrapper::init_petscdm(), libMesh::ExodusII_IO_Helper::initialize(), libMesh::OptimizationSystem::initialize_equality_constraints_storage(), libMesh::OptimizationSystem::initialize_inequality_constraints_storage(), libMesh::RBEIMConstruction::initialize_parametrized_functions_in_training_set(), libMesh::RBEIMConstruction::inner_product(), integrate_function(), libMesh::MeshTools::libmesh_assert_consistent_distributed(), libMesh::MeshTools::libmesh_assert_consistent_distributed_nodes(), libMesh::MeshTools::libmesh_assert_contiguous_dof_ids(), libMesh::MeshTools::libmesh_assert_equal_connectivity(), libMesh::MeshTools::libmesh_assert_equal_points(), libMesh::MeshTools::libmesh_assert_parallel_consistent_new_node_procids(), libMesh::MeshTools::libmesh_assert_parallel_consistent_procids< Elem >(), libMesh::MeshTools::libmesh_assert_parallel_consistent_procids< Node >(), libMesh::MeshTools::libmesh_assert_topology_consistent_procids< Node >(), libMesh::MeshTools::libmesh_assert_valid_boundary_ids(), libMesh::MeshTools::libmesh_assert_valid_constraint_rows(), libMesh::MeshTools::libmesh_assert_valid_dof_ids(), libMesh::MeshTools::libmesh_assert_valid_neighbors(), libMesh::DistributedMesh::libmesh_assert_valid_parallel_flags(), libMesh::DistributedMesh::libmesh_assert_valid_parallel_object_ids(), libMesh::DistributedMesh::libmesh_assert_valid_parallel_p_levels(), libMesh::MeshTools::libmesh_assert_valid_refinement_flags(), libMesh::MeshTools::libmesh_assert_valid_unique_ids(), libMesh::libmesh_petsc_linesearch_shellfunc(), libMesh::libmesh_petsc_preconditioner_apply(), libMesh::libmesh_petsc_recalculate_monitor(), libMesh::libmesh_petsc_snes_fd_residual(), libMesh::libmesh_petsc_snes_jacobian(), libMesh::libmesh_petsc_snes_mffd_interface(), libMesh::libmesh_petsc_snes_mffd_residual(), libMesh::libmesh_petsc_snes_postcheck(), libMesh::libmesh_petsc_snes_precheck(), libMesh::libmesh_petsc_snes_residual(), libMesh::libmesh_petsc_snes_residual_helper(), limit_level_mismatch_at_edge(), limit_level_mismatch_at_node(), limit_overrefined_boundary(), limit_underrefined_boundary(), libMesh::LinearImplicitSystem::LinearImplicitSystem(), main(), make_coarsening_compatible(), libMesh::MeshCommunication::make_elems_parallel_consistent(), make_flags_parallel_consistent(), libMesh::MeshCommunication::make_new_node_proc_ids_parallel_consistent(), libMesh::MeshCommunication::make_new_nodes_parallel_consistent(), libMesh::MeshCommunication::make_node_bcids_parallel_consistent(), libMesh::MeshCommunication::make_node_ids_parallel_consistent(), libMesh::MeshCommunication::make_node_proc_ids_parallel_consistent(), libMesh::MeshCommunication::make_node_unique_ids_parallel_consistent(), libMesh::MeshCommunication::make_nodes_parallel_consistent(), libMesh::MeshCommunication::make_p_levels_parallel_consistent(), make_refinement_compatible(), libMesh::TransientRBConstruction::mass_matrix_scaled_matvec(), libMesh::FEMSystem::mesh_position_set(), libMesh::TriangulatorInterface::MeshedHole::MeshedHole(), LinearElasticityWithContact::move_mesh(), libMesh::DistributedMesh::n_active_elem(), libMesh::MeshTools::n_active_levels(), libMesh::BoundaryInfo::n_boundary_conds(), libMesh::MeshTools::n_connected_components(), libMesh::DofMap::n_constrained_dofs(), libMesh::MeshBase::n_constraint_rows(), libMesh::DofMap::n_dofs(), libMesh::DofMap::n_dofs_per_processor(), libMesh::BoundaryInfo::n_edge_conds(), libMesh::CondensedEigenSystem::n_global_non_condensed_dofs(), libMesh::MeshTools::n_levels(), MixedOrderTest::n_neighbor_links(), libMesh::BoundaryInfo::n_nodeset_conds(), libMesh::SparsityPattern::Build::n_nonzeros(), libMesh::MeshTools::n_p_levels(), libMesh::BoundaryInfo::n_shellface_conds(), libMesh::RBEIMEvaluation::node_distribute_bfs(), libMesh::RBEIMEvaluation::node_gather_bfs(), libMesh::RBEIMConstruction::node_inner_product(), libMesh::MeshBase::operator==(), libMesh::DistributedMesh::parallel_max_elem_id(), libMesh::DistributedMesh::parallel_max_node_id(), libMesh::ReplicatedMesh::parallel_max_unique_id(), libMesh::DistributedMesh::parallel_max_unique_id(), libMesh::DistributedMesh::parallel_n_elem(), libMesh::DistributedMesh::parallel_n_nodes(), libMesh::SparsityPattern::Build::parallel_sync(), libMesh::BoundaryInfo::parallel_sync_node_ids(), libMesh::BoundaryInfo::parallel_sync_side_ids(), libMesh::MeshTools::paranoid_n_levels(), libMesh::Partitioner::partition(), libMesh::Partitioner::partition_unpartitioned_elements(), libMesh::petsc_auto_fieldsplit(), libMesh::System::point_gradient(), libMesh::System::point_hessian(), libMesh::System::point_value(), libMesh::MeshBase::prepare_for_use(), libMesh::MeshBase::print_constraint_rows(), libMesh::DofMap::print_dof_constraints(), libMesh::DofMap::process_mesh_constraint_rows(), libMesh::Partitioner::processor_pairs_to_interface_nodes(), libMesh::InterMeshProjection::project_system_vectors(), FEMParameters::read(), libMesh::Nemesis_IO::read(), libMesh::XdrIO::read(), libMesh::EquationSystems::read(), libMesh::ExodusII_IO::read_header(), libMesh::CheckpointIO::read_header(), libMesh::XdrIO::read_header(), libMesh::System::read_header(), libMesh::RBEIMEvaluation::read_in_interior_basis_functions(), libMesh::RBEIMEvaluation::read_in_node_basis_functions(), libMesh::RBEIMEvaluation::read_in_side_basis_functions(), libMesh::RBEvaluation::read_in_vectors_from_multiple_files(), libMesh::System::read_legacy_data(), libMesh::TransientRBConstruction::read_riesz_representors_from_files(), libMesh::RBConstruction::read_riesz_representors_from_files(), libMesh::System::read_SCALAR_dofs(), libMesh::XdrIO::read_serialized_bc_names(), libMesh::XdrIO::read_serialized_bcs_helper(), libMesh::System::read_serialized_blocked_dof_objects(), libMesh::XdrIO::read_serialized_connectivity(), libMesh::XdrIO::read_serialized_nodes(), libMesh::XdrIO::read_serialized_nodesets(), libMesh::XdrIO::read_serialized_subdomain_names(), libMesh::System::read_serialized_vector(), libMesh::Nemesis_IO_Helper::read_var_names_impl(), MeshFunctionTest::read_variable_info_from_output_data(), libMesh::MeshBase::recalculate_n_partitions(), refine_and_coarsen_elements(), libMesh::SimplexRefiner::refine_via_edges(), libMesh::StaticCondensationDofMap::reinit(), libMesh::DistributedMesh::renumber_dof_objects(), libMesh::DistributedMesh::renumber_nodes_and_elements(), LinearElasticityWithContact::residual_and_jacobian(), OverlappingAlgebraicGhostingTest::run_ghosting_test(), OverlappingCouplingGhostingTest::run_sparsity_pattern_test(), scale_mesh_and_plot(), libMesh::DofMap::scatter_constraints(), libMesh::CheckpointIO::select_split_config(), libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::send_and_insert_dof_values(), libMesh::TransientRBConstruction::set_error_temporal_data(), libMesh::Partitioner::set_interface_node_processor_ids_BFS(), libMesh::Partitioner::set_interface_node_processor_ids_linear(), libMesh::Partitioner::set_interface_node_processor_ids_petscpartitioner(), libMesh::Partitioner::set_node_processor_ids(), libMesh::DofMap::set_nonlocal_dof_objects(), libMesh::Partitioner::set_parent_processor_ids(), libMesh::PetscDMWrapper::set_point_range_in_section(), libMesh::PetscDiffSolver::setup_petsc_data(), libMesh::RBEIMEvaluation::side_distribute_bfs(), libMesh::RBEIMEvaluation::side_gather_bfs(), libMesh::RBEIMConstruction::side_inner_product(), libMesh::Partitioner::single_partition(), libMesh::LaplaceMeshSmoother::smooth(), libMesh::VariationalMeshSmoother::smooth(), libMesh::ClawSystem::solve_conservation_law(), libMesh::split_mesh(), libMesh::RBEIMConstruction::store_eim_solutions_for_training_set(), libMesh::MeshBase::subdomain_ids(), libMesh::BoundaryInfo::sync(), ConstraintOperatorTest::test1DCoarseningNewNodes(), ConstraintOperatorTest::test1DCoarseningOperator(), test_level_one(), MeshfunctionDFEM::test_mesh_function_dfem(), MeshfunctionDFEM::test_mesh_function_dfem_grad(), MeshFunctionTest::test_p_level(), test_unflagged(), DofMapTest::testBadElemFECombo(), SystemsTest::testBlockRestrictedVarNDofs(), BoundaryInfoTest::testBoundaryOnChildrenErrors(), VolumeTest::testC0PolygonMethods(), VolumeTest::testC0PolyhedronMethods(), ConstraintOperatorTest::testCoreform(), ConnectedComponentsTest::testEdge(), MeshInputTest::testExodusIGASidesets(), MeshTriangulationTest::testFoundCenters(), PointLocatorTest::testLocator(), BoundaryInfoTest::testMesh(), PointLocatorTest::testPlanar(), MeshTriangulationTest::testPoly2TriRefinementBase(), SystemsTest::testProjectCubeWithMeshFunction(), BoundaryInfoTest::testRenumber(), CheckpointIOTest::testSplitter(), MeshInputTest::testTetgenIO(), MeshTriangulationTest::testTriangulatorInterp(), MeshTriangulationTest::testTriangulatorMeshedHoles(), MeshTriangulationTest::testTriangulatorRoundHole(), libMesh::MeshTools::total_weight(), libMesh::RBConstruction::train_reduced_basis_with_POD(), libMesh::MeshFunctionSolutionTransfer::transfer(), libMesh::MeshfreeSolutionTransfer::transfer(), libMesh::Poly2TriTriangulator::triangulate(), libMesh::TransientRBConstruction::truth_assembly(), libMesh::RBConstruction::truth_assembly(), uniformly_coarsen(), update_current_local_solution(), libMesh::TransientRBConstruction::update_RB_initial_condition_all_N(), libMesh::TransientRBConstruction::update_RB_system_matrices(), libMesh::RBConstruction::update_RB_system_matrices(), libMesh::TransientRBConstruction::update_residual_terms(), libMesh::RBConstruction::update_residual_terms(), libMesh::MeshTools::volume(), libMesh::STLIO::write(), libMesh::NameBasedIO::write(), libMesh::XdrIO::write(), libMesh::VTKIO::write_nodal_data(), libMesh::RBEIMEvaluation::write_out_interior_basis_functions(), libMesh::RBEIMEvaluation::write_out_node_basis_functions(), libMesh::RBEIMEvaluation::write_out_side_basis_functions(), libMesh::RBEvaluation::write_out_vectors(), libMesh::TransientRBConstruction::write_riesz_representors_to_files(), libMesh::RBConstruction::write_riesz_representors_to_files(), libMesh::System::write_SCALAR_dofs(), libMesh::XdrIO::write_serialized_bcs_helper(), libMesh::System::write_serialized_blocked_dof_objects(), libMesh::XdrIO::write_serialized_connectivity(), libMesh::XdrIO::write_serialized_nodes(), libMesh::XdrIO::write_serialized_nodesets(), libMesh::RBDataSerialization::RBEvaluationSerialization::write_to_file(), libMesh::RBDataSerialization::TransientRBEvaluationSerialization::write_to_file(), libMesh::RBDataSerialization::RBEIMEvaluationSerialization::write_to_file(), and libMesh::RBDataSerialization::RBSCMEvaluationSerialization::write_to_file().

98  { return _communicator; }
const Parallel::Communicator & _communicator

◆ create_parent_error_vector()

void libMesh::MeshRefinement::create_parent_error_vector ( const ErrorVector error_per_cell,
ErrorVector error_per_parent,
Real parent_error_min,
Real parent_error_max 
)
private

Calculates the error on all coarsenable parents.

error_per_parent[parent_id] stores this error if parent_id corresponds to a coarsenable parent, and stores -1 otherwise.

Definition at line 220 of file mesh_refinement.C.

References _mesh, libMesh::ParallelObject::comm(), libMesh::DofObject::id(), libMesh::index_range(), libMesh::libmesh_assert(), TIMPI::Communicator::min(), libMesh::Elem::parent(), and TIMPI::Communicator::sum().

Referenced by flag_elements_by_elem_fraction(), flag_elements_by_error_fraction(), flag_elements_by_error_tolerance(), and flag_elements_by_nelem_target().

224 {
225  // This function must be run on all processors at once
226  parallel_object_only();
227 
228  // Make sure the input error vector is valid
229 #ifdef DEBUG
230  for (const auto & val : error_per_cell)
231  {
232  libmesh_assert_greater_equal (val, 0);
233  // isnan() isn't standard C++ yet
234 #ifdef isnan
235  libmesh_assert(!isnan(val));
236 #endif
237  }
238 
239  // Use a reference to std::vector to avoid confusing
240  // this->comm().verify
241  std::vector<ErrorVectorReal> & epc = error_per_parent;
242  libmesh_assert(this->comm().verify(epc));
243 #endif // #ifdef DEBUG
244 
245  // error values on uncoarsenable elements will be left at -1
246  error_per_parent.clear();
247  error_per_parent.resize(error_per_cell.size(), 0.0);
248 
249  {
250  // Find which elements are uncoarsenable
251  for (auto & elem : _mesh.active_local_element_ptr_range())
252  {
253  Elem * parent = elem->parent();
254 
255  // Active elements are uncoarsenable
256  error_per_parent[elem->id()] = -1.0;
257 
258  // Grandparents and up are uncoarsenable
259  while (parent)
260  {
261  parent = parent->parent();
262  if (parent)
263  {
264  const dof_id_type parentid = parent->id();
265  libmesh_assert_less (parentid, error_per_parent.size());
266  error_per_parent[parentid] = -1.0;
267  }
268  }
269  }
270 
271  // Sync between processors.
272  // Use a reference to std::vector to avoid confusing
273  // this->comm().min
274  std::vector<ErrorVectorReal> & epp = error_per_parent;
275  this->comm().min(epp);
276  }
277 
278  // The parent's error is defined as the square root of the
279  // sum of the children's errors squared, so errors that are
280  // Hilbert norms remain Hilbert norms.
281  //
282  // Because the children may be on different processors, we
283  // calculate local contributions to the parents' errors squared
284  // first, then sum across processors and take the square roots
285  // second.
286  for (auto & elem : _mesh.active_local_element_ptr_range())
287  {
288  Elem * parent = elem->parent();
289 
290  // Calculate each contribution to parent cells
291  if (parent)
292  {
293  const dof_id_type parentid = parent->id();
294  libmesh_assert_less (parentid, error_per_parent.size());
295 
296  // If the parent has grandchildren we won't be able to
297  // coarsen it, so forget it. Otherwise, add this child's
298  // contribution to the sum of the squared child errors
299  if (error_per_parent[parentid] != -1.0)
300  error_per_parent[parentid] += (error_per_cell[elem->id()] *
301  error_per_cell[elem->id()]);
302  }
303  }
304 
305  // Sum the vector across all processors
306  this->comm().sum(static_cast<std::vector<ErrorVectorReal> &>(error_per_parent));
307 
308  // Calculate the min and max as we loop
309  parent_error_min = std::numeric_limits<double>::max();
310  parent_error_max = 0.;
311 
312  for (auto i : index_range(error_per_parent))
313  {
314  // If this element isn't a coarsenable parent with error, we
315  // have nothing to do. Just flag it as -1 and move on
316  // Note that this->comm().sum might have left uncoarsenable
317  // elements with error_per_parent=-n_proc, so reset it to
318  // error_per_parent=-1
319  if (error_per_parent[i] < 0.)
320  {
321  error_per_parent[i] = -1.;
322  continue;
323  }
324 
325  // The error estimator might have already given us an
326  // estimate on the coarsenable parent elements; if so then
327  // we want to retain that estimate
328  if (error_per_cell[i])
329  {
330  error_per_parent[i] = error_per_cell[i];
331  continue;
332  }
333  // if not, then e_parent = sqrt(sum(e_child^2))
334  else
335  error_per_parent[i] = std::sqrt(error_per_parent[i]);
336 
337  parent_error_min = std::min (parent_error_min,
338  error_per_parent[i]);
339  parent_error_max = std::max (parent_error_max,
340  error_per_parent[i]);
341  }
342 }
MeshBase & _mesh
Reference to the mesh.
void sum(T &r) const
const Parallel::Communicator & comm() const
void min(const T &r, T &o, Request &req) const
libmesh_assert(ctx)
auto index_range(const T &sizable)
Helper function that returns an IntRange<std::size_t> representing all the indices of the passed-in v...
Definition: int_range.h:117
uint8_t dof_id_type
Definition: id_types.h:67

◆ edge_level_mismatch_limit()

unsigned char & libMesh::MeshRefinement::edge_level_mismatch_limit ( )
inline

If edge_level_mismatch_limit is set to a nonzero value, then refinement and coarsening will produce meshes in which the refinement level of two edge neighbors will not differ by more than that limit.

If edge_level_mismatch_limit is 0, then level differences will be unlimited.

edge_level_mismatch_limit is 0 by default.

Definition at line 947 of file mesh_refinement.h.

References _edge_level_mismatch_limit.

948 {
950 }
unsigned char _edge_level_mismatch_limit

◆ eliminate_unrefined_patches()

bool libMesh::MeshRefinement::eliminate_unrefined_patches ( )
private


This algorithm selects an element for refinement if all of its neighbors are (or will be) refined.

This algorithm will transform this mesh:

* o---o---o---o---o---o---o
* |   |   |   |   |   |   |
* |   |   |   |   |   |   |
* o---o---o---o---o---o---o
* |   |   |   |   |   |   |
* |   |   |   |   |   |   |
* o---o---o---o---o---o---o
* |   |   |       |   |   |
* |   |   |       |   |   |
* o---o---o       o---o---o
* |   |   |       |   |   |
* |   |   |       |   |   |
* o---o---o---o---o---o---o
* |   |   |   |   |   |   |
* |   |   |   |   |   |   |
* o---o---o---o---o---o---o
* |   |   |   |   |   |   |
* |   |   |   |   |   |   |
* o---o---o---o---o---o---o
* 

into this:

* o---o---o---o---o---o---o
* |   |   |   |   |   |   |
* |   |   |   |   |   |   |
* o---o---o---o---o---o---o
* |   |   |   |   |   |   |
* |   |   |   |   |   |   |
* o---o---o---o---o---o---o
* |   |   |   :   |   |   |
* |   |   |   :   |   |   |
* o---o---o...o...o---o---o
* |   |   |   :   |   |   |
* |   |   |   :   |   |   |
* o---o---o---o---o---o---o
* |   |   |   |   |   |   |
* |   |   |   |   |   |   |
* o---o---o---o---o---o---o
* |   |   |   |   |   |   |
* |   |   |   |   |   |   |
* o---o---o---o---o---o---o
* 

by refining the indicated element. If the _allow_unrefined_patches flag (default false) is set to true, then this function simpy returns false (indicating that no changes were made).

Definition at line 367 of file mesh_refinement_smoothing.C.

References _allow_unrefined_patches, _mesh, libMesh::Elem::COARSEN, libMesh::Elem::COARSEN_INACTIVE, libMesh::ParallelObject::comm(), libMesh::Elem::DO_NOTHING, libMesh::Elem::INACTIVE, int, libMesh::libmesh_assert(), TIMPI::Communicator::max(), libMesh::Elem::REFINE, and libMesh::remote_elem.

Referenced by _smooth_flags().

368 {
369  // This function must be run on all processors at once
370  parallel_object_only();
371 
372  bool flags_changed = false;
373 
374  // Quick return: if unrefined patches are allowed, then we are not
375  // going to do anything here and can simply return that the flags
376  // haven't changed.
378  return flags_changed;
379 
380  // Note: we *cannot* use a reference to the real pointer here, since
381  // the pointer may be reseated below and we don't want to reseat
382  // pointers held by the Mesh.
383  for (Elem * elem : _mesh.active_element_ptr_range())
384  {
385  // First, see if there's any possibility we might have to flag
386  // this element for h and p refinement - do we have any visible
387  // neighbors? Next we'll check to see if any of those neighbors
388  // are as coarse or coarser than us.
389  bool h_flag_me = false,
390  p_flag_me = false;
391  for (auto neighbor : elem->neighbor_ptr_range())
392  {
393  // Quit if the element is not a local boundary
394  if (neighbor != nullptr && neighbor != remote_elem)
395  {
396  h_flag_me = true;
397  p_flag_me = true;
398  break;
399  }
400  }
401 
402  // Skip the element if it is already fully flagged for refinement
403  if (elem->p_refinement_flag() == Elem::REFINE)
404  p_flag_me = false;
405  if (elem->refinement_flag() == Elem::REFINE)
406  {
407  h_flag_me = false;
408  if (!p_flag_me)
409  continue;
410  }
411  // Test the parent if that is already flagged for coarsening
412  else if (elem->refinement_flag() == Elem::COARSEN)
413  {
414  libmesh_assert(elem->parent());
415  elem = elem->parent();
416  // FIXME - this doesn't seem right - RHS
417  if (elem->refinement_flag() != Elem::COARSEN_INACTIVE)
418  continue;
419  p_flag_me = false;
420  }
421 
422  const unsigned int my_level = elem->level();
423  int my_p_adjustment = 0;
424  if (elem->p_refinement_flag() == Elem::REFINE)
425  my_p_adjustment = 1;
426  else if (elem->p_refinement_flag() == Elem::COARSEN)
427  {
428  libmesh_assert_greater (elem->p_level(), 0);
429  my_p_adjustment = -1;
430  }
431  const unsigned int my_new_p_level =
432  cast_int<unsigned int>(int(elem->p_level()) +
433  my_p_adjustment);
434 
435  // Check all the element neighbors
436  for (auto neighbor : elem->neighbor_ptr_range())
437  {
438  // Quit if the element is on a local boundary
439  if (neighbor == nullptr || neighbor == remote_elem)
440  {
441  h_flag_me = false;
442  p_flag_me = false;
443  break;
444  }
445  // if the neighbor will be equally or less refined than
446  // we are, then we will not become an unrefined island.
447  // So if we are still considering h refinement:
448  if (h_flag_me &&
449  // If our neighbor is already at a lower level,
450  // it can't end up at a higher level even if it
451  // is flagged for refinement once
452  ((neighbor->level() < my_level) ||
453  // If our neighbor is at the same level but isn't
454  // flagged for refinement, it won't end up at a
455  // higher level
456  ((neighbor->active()) &&
457  (neighbor->refinement_flag() != Elem::REFINE)) ||
458  // If our neighbor is currently more refined but is
459  // a parent flagged for coarsening, it will end up
460  // at the same level.
461  (neighbor->refinement_flag() == Elem::COARSEN_INACTIVE)))
462  {
463  // We've proven we won't become an unrefined island,
464  // so don't h refine to avoid that.
465  h_flag_me = false;
466 
467  // If we've also proven we don't need to p refine,
468  // we don't need to check more neighbors
469  if (!p_flag_me)
470  break;
471  }
472  if (p_flag_me)
473  {
474  // if active neighbors will have a p level
475  // equal to or lower than ours, then we do not need to p
476  // refine ourselves.
477  if (neighbor->active())
478  {
479  int p_adjustment = 0;
480  if (neighbor->p_refinement_flag() == Elem::REFINE)
481  p_adjustment = 1;
482  else if (neighbor->p_refinement_flag() == Elem::COARSEN)
483  {
484  libmesh_assert_greater (neighbor->p_level(), 0);
485  p_adjustment = -1;
486  }
487  if (my_new_p_level >=
488  cast_int<unsigned int>(int(neighbor->p_level())
489  + p_adjustment))
490  {
491  p_flag_me = false;
492  if (!h_flag_me)
493  break;
494  }
495  }
496  // If we have inactive neighbors, we need to
497  // test all their active descendants which neighbor us
498  else if (neighbor->ancestor())
499  {
500  if (neighbor->min_new_p_level_by_neighbor(elem,
501  my_new_p_level + 2) <= my_new_p_level)
502  {
503  p_flag_me = false;
504  if (!h_flag_me)
505  break;
506  }
507  }
508  }
509  }
510 
511  if (h_flag_me)
512  {
513  // Parents that would create islands should no longer
514  // coarsen
515  if (elem->refinement_flag() == Elem::COARSEN_INACTIVE)
516  {
517  for (auto & child : elem->child_ref_range())
518  {
519  libmesh_assert_equal_to (child.refinement_flag(),
520  Elem::COARSEN);
521  child.set_refinement_flag(Elem::DO_NOTHING);
522  }
523  elem->set_refinement_flag(Elem::INACTIVE);
524  }
525  else
526  elem->set_refinement_flag(Elem::REFINE);
527  flags_changed = true;
528  }
529  if (p_flag_me)
530  {
531  if (elem->p_refinement_flag() == Elem::COARSEN)
532  elem->set_p_refinement_flag(Elem::DO_NOTHING);
533  else
534  elem->set_p_refinement_flag(Elem::REFINE);
535  flags_changed = true;
536  }
537  }
538 
539  // If flags changed on any processor then they changed globally
540  this->comm().max(flags_changed);
541 
542  return flags_changed;
543 }
MeshBase & _mesh
Reference to the mesh.
const Parallel::Communicator & comm() const
libmesh_assert(ctx)
void max(const T &r, T &o, Request &req) const
void ErrorVector unsigned int
Definition: adjoints_ex3.C:360
const RemoteElem * remote_elem
Definition: remote_elem.C:57

◆ enforce_mismatch_limit_prior_to_refinement() [1/2]

bool & libMesh::MeshRefinement::enforce_mismatch_limit_prior_to_refinement ( )
inline

Get/set the _enforce_mismatch_limit_prior_to_refinement flag.

The default value for this flag is false.

Definition at line 986 of file mesh_refinement.h.

References _enforce_mismatch_limit_prior_to_refinement.

Referenced by get_enforce_mismatch_limit_prior_to_refinement(), limit_level_mismatch_at_edge(), limit_level_mismatch_at_node(), and set_enforce_mismatch_limit_prior_to_refinement().

987 {
989 }
bool _enforce_mismatch_limit_prior_to_refinement
This option enforces the mismatch level prior to refinement by checking if refining any element mar...

◆ enforce_mismatch_limit_prior_to_refinement() [2/2]

bool libMesh::MeshRefinement::enforce_mismatch_limit_prior_to_refinement ( Elem elem,
NeighborType  nt,
unsigned  max_mismatch 
)
private

Definition at line 547 of file mesh_refinement_smoothing.C.

References _enforce_mismatch_limit_prior_to_refinement, libMesh::Elem::DO_NOTHING, EDGE, libMesh::Elem::find_edge_neighbors(), libMesh::Elem::find_point_neighbors(), libMesh::Elem::level(), libMesh::Elem::p_level(), POINT, libMesh::Elem::REFINE, libMesh::Elem::refinement_flag(), libMesh::Elem::set_p_refinement_flag(), and libMesh::Elem::set_refinement_flag().

550 {
551  // Eventual return value
552  bool flags_changed = false;
553 
554  // If we are enforcing the limit prior to refinement then we
555  // need to remove flags from any elements marked for refinement that
556  // would cause a mismatch
558  && elem->refinement_flag() == Elem::REFINE)
559  {
560  // get all the relevant neighbors since we may have to refine
561  // elements off edges or corners as well
562  std::set<const Elem *> neighbor_set;
563 
564  if (nt == POINT)
565  elem->find_point_neighbors(neighbor_set);
566  else if (nt == EDGE)
567  elem->find_edge_neighbors(neighbor_set);
568  else
569  libmesh_error_msg("Unrecognized NeighborType: " << nt);
570 
571  // Loop over the neighbors of element e
572  for (const auto & neighbor : neighbor_set)
573  {
574  if ((elem->level() + 1 - max_mismatch) > neighbor->level())
575  {
576  elem->set_refinement_flag(Elem::DO_NOTHING);
577  flags_changed = true;
578  }
579  if ((elem->p_level() + 1 - max_mismatch) > neighbor->p_level())
580  {
581  elem->set_p_refinement_flag(Elem::DO_NOTHING);
582  flags_changed = true;
583  }
584  } // loop over edge/point neighbors
585  } // if _enforce_mismatch_limit_prior_to_refinement
586 
587  return flags_changed;
588 }
bool _enforce_mismatch_limit_prior_to_refinement
This option enforces the mismatch level prior to refinement by checking if refining any element mar...

◆ face_level_mismatch_limit()

unsigned char & libMesh::MeshRefinement::face_level_mismatch_limit ( )
inline

If face_level_mismatch_limit is set to a nonzero value, then refinement and coarsening will produce meshes in which the refinement level of two face neighbors will not differ by more than that limit.

If face_level_mismatch_limit is 0, then level differences will be unlimited.

face_level_mismatch_limit is 1 by default. Currently the only supported options are 0 and 1.

Definition at line 942 of file mesh_refinement.h.

References _face_level_mismatch_limit.

Referenced by libMesh::EquationSystems::reinit_solutions().

943 {
945 }
unsigned char _face_level_mismatch_limit

◆ flag_elements_by()

void libMesh::MeshRefinement::flag_elements_by ( ElementFlagging element_flagging)

Flag elements based on a function object.

The class ElementFlagging defines a mechanism for implementing refinement strategies.

Definition at line 647 of file mesh_refinement_flagging.C.

References libMesh::MeshRefinement::ElementFlagging::flag_elements().

648 {
649  element_flagging.flag_elements();
650 }

◆ flag_elements_by_elem_fraction()

void libMesh::MeshRefinement::flag_elements_by_elem_fraction ( const ErrorVector error_per_cell,
const Real  refine_fraction = 0.3,
const Real  coarsen_fraction = 0.0,
const unsigned int  max_level = libMesh::invalid_uint 
)

Flags elements for coarsening and refinement based on the computed error passed in error_per_cell.

This method picks the top refine_fraction * n_elem elements for refinement and the bottom coarsen_fraction * n_elem elements for coarsening. The two fractions refine_fraction and coarsen_fraction must be in \( [0,1] \).

All the function arguments except error_per_cell have been deprecated, and will be removed in future libMesh releases - to control these parameters, set the corresponding member variables.

Definition at line 445 of file mesh_refinement_flagging.C.

References _coarsen_by_parents, _coarsen_fraction, _max_h_level, _mesh, _refine_fraction, _use_member_parameters, TIMPI::Communicator::allgather(), clean_refinement_flags(), libMesh::Elem::COARSEN, libMesh::ParallelObject::comm(), create_parent_error_vector(), dim, libMesh::ErrorVectorReal, libMesh::DofObject::id(), libMesh::invalid_uint, libMesh::libmesh_assert(), libMesh::MeshBase::mesh_dimension(), libMesh::MeshBase::n_active_elem(), libMesh::Elem::parent(), libMesh::Real, libMesh::Elem::REFINE, and libMesh::Elem::set_refinement_flag().

Referenced by main().

449 {
450  parallel_object_only();
451 
452  // Verify that our error vector is consistent, using std::vector to
453  // avoid confusing this->comm().verify
454  libmesh_assert(this->comm().verify(dynamic_cast<const std::vector<ErrorVectorReal> &>(error_per_cell)));
455 
456  // The function arguments are currently just there for
457  // backwards_compatibility
459  {
460  // If the user used non-default parameters, lets warn
461  // that they're deprecated
462  if (refine_frac != 0.3 ||
463  coarsen_frac != 0.0 ||
464  max_l != libMesh::invalid_uint)
465  libmesh_deprecated();
466 
467  _refine_fraction = refine_frac;
468  _coarsen_fraction = coarsen_frac;
469  _max_h_level = max_l;
470  }
471 
472  // Check for valid fractions..
473  // The fraction values must be in [0,1]
474  libmesh_assert_greater_equal (_refine_fraction, 0);
475  libmesh_assert_less_equal (_refine_fraction, 1);
476  libmesh_assert_greater_equal (_coarsen_fraction, 0);
477  libmesh_assert_less_equal (_coarsen_fraction, 1);
478 
479  // The number of active elements in the mesh
480  const dof_id_type n_active_elem = _mesh.n_active_elem();
481 
482  // The number of elements to flag for coarsening
483  const dof_id_type n_elem_coarsen =
484  static_cast<dof_id_type>(_coarsen_fraction * n_active_elem);
485 
486  // The number of elements to flag for refinement
487  const dof_id_type n_elem_refine =
488  static_cast<dof_id_type>(_refine_fraction * n_active_elem);
489 
490 
491 
492  // Clean up the refinement flags. These could be left
493  // over from previous refinement steps.
494  this->clean_refinement_flags();
495 
496 
497  // This vector stores the error and element number for all the
498  // active elements. It will be sorted and the top & bottom
499  // elements will then be flagged for coarsening & refinement
500  std::vector<ErrorVectorReal> sorted_error;
501 
502  sorted_error.reserve (n_active_elem);
503 
504  // Loop over the active elements and create the entry
505  // in the sorted_error vector
506  for (auto & elem : _mesh.active_local_element_ptr_range())
507  sorted_error.push_back (error_per_cell[elem->id()]);
508 
509  this->comm().allgather(sorted_error);
510 
511  // Now sort the sorted_error vector
512  std::sort (sorted_error.begin(), sorted_error.end());
513 
514  // If we're coarsening by parents:
515  // Create a sorted error vector with coarsenable parent elements
516  // only, sorted by lowest errors first
517  ErrorVector error_per_parent, sorted_parent_error;
519  {
520  Real parent_error_min, parent_error_max;
521 
522  create_parent_error_vector(error_per_cell,
523  error_per_parent,
524  parent_error_min,
525  parent_error_max);
526 
527  sorted_parent_error = error_per_parent;
528  std::sort (sorted_parent_error.begin(), sorted_parent_error.end());
529 
530  // All the other error values will be 0., so get rid of them.
531  sorted_parent_error.erase (std::remove(sorted_parent_error.begin(),
532  sorted_parent_error.end(), 0.),
533  sorted_parent_error.end());
534  }
535 
536 
537  ErrorVectorReal top_error= 0., bottom_error = 0.;
538 
539  // Get the maximum error value corresponding to the
540  // bottom n_elem_coarsen elements
541  if (_coarsen_by_parents && n_elem_coarsen)
542  {
543  const unsigned int dim = _mesh.mesh_dimension();
544  unsigned int twotodim = 1;
545  for (unsigned int i=0; i!=dim; ++i)
546  twotodim *= 2;
547 
548  dof_id_type n_parent_coarsen = n_elem_coarsen / (twotodim - 1);
549 
550  if (n_parent_coarsen)
551  bottom_error = sorted_parent_error[n_parent_coarsen - 1];
552  }
553  else if (n_elem_coarsen)
554  {
555  bottom_error = sorted_error[n_elem_coarsen - 1];
556  }
557 
558  if (n_elem_refine)
559  top_error = sorted_error[sorted_error.size() - n_elem_refine];
560 
561  // Finally, let's do the element flagging
562  for (auto & elem : _mesh.active_element_ptr_range())
563  {
564  Elem * parent = elem->parent();
565 
566  if (_coarsen_by_parents && parent && n_elem_coarsen &&
567  error_per_parent[parent->id()] <= bottom_error)
568  elem->set_refinement_flag(Elem::COARSEN);
569 
570  if (!_coarsen_by_parents && n_elem_coarsen &&
571  error_per_cell[elem->id()] <= bottom_error)
572  elem->set_refinement_flag(Elem::COARSEN);
573 
574  if (n_elem_refine &&
575  elem->level() < _max_h_level &&
576  error_per_cell[elem->id()] >= top_error)
577  elem->set_refinement_flag(Elem::REFINE);
578  }
579 }
void allgather(const T &send_data, std::vector< T, A > &recv_data) const
virtual dof_id_type n_active_elem() const =0
const unsigned int invalid_uint
A number which is used quite often to represent an invalid or uninitialized value for an unsigned int...
Definition: libmesh.h:310
MeshBase & _mesh
Reference to the mesh.
unsigned int dim
const Parallel::Communicator & comm() const
void clean_refinement_flags()
Sets the refinement flag to Elem::DO_NOTHING for each element in the mesh.
void create_parent_error_vector(const ErrorVector &error_per_cell, ErrorVector &error_per_parent, Real &parent_error_min, Real &parent_error_max)
Calculates the error on all coarsenable parents.
DIE A HORRIBLE DEATH HERE typedef float ErrorVectorReal
bool _use_member_parameters
For backwards compatibility, we initialize this as false and then set it to true if the user uses any...
libmesh_assert(ctx)
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
unsigned int mesh_dimension() const
Definition: mesh_base.C:372
bool _coarsen_by_parents
Refinement parameter values.
uint8_t dof_id_type
Definition: id_types.h:67

◆ flag_elements_by_error_fraction()

void libMesh::MeshRefinement::flag_elements_by_error_fraction ( const ErrorVector error_per_cell,
const Real  refine_fraction = 0.3,
const Real  coarsen_fraction = 0.0,
const unsigned int  max_level = libMesh::invalid_uint 
)

Flags elements for coarsening and refinement based on the computed error passed in error_per_cell.

The two fractions refine_fraction and coarsen_fraction must be in \( [0,1] \).

All the function arguments except error_per_cell have been deprecated, and will be removed in future libMesh releases - to control these parameters, set the corresponding member variables.

Definition at line 44 of file mesh_refinement_flagging.C.

References _coarsen_by_parents, _coarsen_fraction, _max_h_level, _mesh, _refine_fraction, _use_member_parameters, clean_refinement_flags(), libMesh::Elem::COARSEN, libMesh::ParallelObject::comm(), create_parent_error_vector(), libMesh::ErrorVectorReal, libMesh::DofObject::id(), libMesh::invalid_uint, libMesh::libmesh_assert(), TIMPI::Communicator::max(), TIMPI::Communicator::min(), libMesh::Elem::parent(), libMesh::Real, and libMesh::Elem::REFINE.

Referenced by assemble_and_solve(), and main().

48 {
49  parallel_object_only();
50 
51  // Verify that our error vector is consistent, using std::vector to
52  // avoid confusing this->comm().verify
53  libmesh_assert(this->comm().verify(dynamic_cast<const std::vector<ErrorVectorReal> &>(error_per_cell)));
54 
55  // The function arguments are currently just there for
56  // backwards_compatibility
58  {
59  // If the user used non-default parameters, lets warn
60  // that they're deprecated
61  if (refine_frac != 0.3 ||
62  coarsen_frac != 0.0 ||
63  max_l != libMesh::invalid_uint)
64  libmesh_deprecated();
65 
66  _refine_fraction = refine_frac;
67  _coarsen_fraction = coarsen_frac;
68  _max_h_level = max_l;
69  }
70 
71  // Check for valid fractions..
72  // The fraction values must be in [0,1]
73  libmesh_assert_greater_equal (_refine_fraction, 0);
74  libmesh_assert_less_equal (_refine_fraction, 1);
75  libmesh_assert_greater_equal (_coarsen_fraction, 0);
76  libmesh_assert_less_equal (_coarsen_fraction, 1);
77 
78  // Clean up the refinement flags. These could be left
79  // over from previous refinement steps.
80  this->clean_refinement_flags();
81 
82  // We're getting the minimum and maximum error values
83  // for the ACTIVE elements
84  Real error_min = 1.e30;
85  Real error_max = 0.;
86 
87  // And, if necessary, for their parents
88  Real parent_error_min = 1.e30;
89  Real parent_error_max = 0.;
90 
91  // Prepare another error vector if we need to sum parent errors
92  ErrorVector error_per_parent;
94  {
95  create_parent_error_vector(error_per_cell,
96  error_per_parent,
97  parent_error_min,
98  parent_error_max);
99  }
100 
101  // We need to loop over all active elements to find the minimum
102  for (auto & elem : _mesh.active_local_element_ptr_range())
103  {
104  const dof_id_type id = elem->id();
105  libmesh_assert_less (id, error_per_cell.size());
106 
107  error_max = std::max (error_max, error_per_cell[id]);
108  error_min = std::min (error_min, error_per_cell[id]);
109  }
110  this->comm().max(error_max);
111  this->comm().min(error_min);
112 
113  // Compute the cutoff values for coarsening and refinement
114  const Real error_delta = (error_max - error_min);
115  const Real parent_error_delta = parent_error_max - parent_error_min;
116 
117  const Real refine_cutoff = (1.- _refine_fraction)*error_max;
118  const Real coarsen_cutoff = _coarsen_fraction*error_delta + error_min;
119  const Real parent_cutoff = _coarsen_fraction*parent_error_delta + error_min;
120 
121  // // Print information about the error
122  // libMesh::out << " Error Information:" << std::endl
123  // << " ------------------" << std::endl
124  // << " min: " << error_min << std::endl
125  // << " max: " << error_max << std::endl
126  // << " delta: " << error_delta << std::endl
127  // << " refine_cutoff: " << refine_cutoff << std::endl
128  // << " coarsen_cutoff: " << coarsen_cutoff << std::endl;
129 
130 
131 
132  // Loop over the elements and flag them for coarsening or
133  // refinement based on the element error
134  for (auto & elem : _mesh.active_element_ptr_range())
135  {
136  const dof_id_type id = elem->id();
137 
138  libmesh_assert_less (id, error_per_cell.size());
139 
140  const ErrorVectorReal elem_error = error_per_cell[id];
141 
143  {
144  Elem * parent = elem->parent();
145  if (parent)
146  {
147  const dof_id_type parentid = parent->id();
148  if (error_per_parent[parentid] >= 0. &&
149  error_per_parent[parentid] <= parent_cutoff)
150  elem->set_refinement_flag(Elem::COARSEN);
151  }
152  }
153  // Flag the element for coarsening if its error
154  // is <= coarsen_fraction*delta + error_min
155  else if (elem_error <= coarsen_cutoff)
156  {
157  elem->set_refinement_flag(Elem::COARSEN);
158  }
159 
160  // Flag the element for refinement if its error
161  // is >= refinement_cutoff.
162  if (elem_error >= refine_cutoff)
163  if (elem->level() < _max_h_level)
164  elem->set_refinement_flag(Elem::REFINE);
165  }
166 }
const unsigned int invalid_uint
A number which is used quite often to represent an invalid or uninitialized value for an unsigned int...
Definition: libmesh.h:310
MeshBase & _mesh
Reference to the mesh.
const Parallel::Communicator & comm() const
void clean_refinement_flags()
Sets the refinement flag to Elem::DO_NOTHING for each element in the mesh.
void create_parent_error_vector(const ErrorVector &error_per_cell, ErrorVector &error_per_parent, Real &parent_error_min, Real &parent_error_max)
Calculates the error on all coarsenable parents.
DIE A HORRIBLE DEATH HERE typedef float ErrorVectorReal
void min(const T &r, T &o, Request &req) const
bool _use_member_parameters
For backwards compatibility, we initialize this as false and then set it to true if the user uses any...
libmesh_assert(ctx)
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
void max(const T &r, T &o, Request &req) const
bool _coarsen_by_parents
Refinement parameter values.
uint8_t dof_id_type
Definition: id_types.h:67

◆ flag_elements_by_error_tolerance()

void libMesh::MeshRefinement::flag_elements_by_error_tolerance ( const ErrorVector error_per_cell)

Flags elements for coarsening and refinement based on the computed error passed in error_per_cell.

This method refines the worst elements with errors greater than absolute_global_tolerance / n_active_elem, flagging at most refine_fraction * n_active_elem It coarsens elements with errors less than coarsen_threshold * global_tolerance / n_active_elem, flagging at most coarsen_fraction * n_active_elem

The three fractions refine_fraction coarsen_fraction and coarsen_threshold should be in \( [0,1] \).

Definition at line 170 of file mesh_refinement_flagging.C.

References _absolute_global_tolerance, _coarsen_by_parents, _coarsen_fraction, _coarsen_threshold, _max_h_level, _mesh, _refine_fraction, libMesh::Elem::COARSEN, libMesh::ParallelObject::comm(), create_parent_error_vector(), libMesh::ErrorVectorReal, libMesh::DofObject::id(), libMesh::libmesh_assert(), libMesh::MeshBase::n_active_elem(), libMesh::Elem::n_children(), libMesh::Elem::parent(), libMesh::Real, and libMesh::Elem::REFINE.

Referenced by main().

171 {
172  parallel_object_only();
173 
174  // Verify that our error vector is consistent, using std::vector to
175  // avoid confusing this->comm().verify
176  libmesh_assert(this->comm().verify(dynamic_cast<const std::vector<ErrorVectorReal> &>(error_per_cell_in)));
177 
178  libmesh_assert_greater (_coarsen_threshold, 0);
179 
180  // Check for valid fractions..
181  // The fraction values must be in [0,1]
182  libmesh_assert_greater_equal (_refine_fraction, 0);
183  libmesh_assert_less_equal (_refine_fraction, 1);
184  libmesh_assert_greater_equal (_coarsen_fraction, 0);
185  libmesh_assert_less_equal (_coarsen_fraction, 1);
186 
187  // How much error per cell will we tolerate?
188  const Real local_refinement_tolerance =
189  _absolute_global_tolerance / std::sqrt(static_cast<Real>(_mesh.n_active_elem()));
190  const Real local_coarsening_tolerance =
191  local_refinement_tolerance * _coarsen_threshold;
192 
193  // Prepare another error vector if we need to sum parent errors
194  ErrorVector error_per_parent;
196  {
197  Real parent_error_min, parent_error_max;
198 
199  create_parent_error_vector(error_per_cell_in,
200  error_per_parent,
201  parent_error_min,
202  parent_error_max);
203  }
204 
205  for (auto & elem : _mesh.active_element_ptr_range())
206  {
207  Elem * parent = elem->parent();
208  const dof_id_type elem_number = elem->id();
209  const ErrorVectorReal elem_error = error_per_cell_in[elem_number];
210 
211  if (elem_error > local_refinement_tolerance &&
212  elem->level() < _max_h_level)
213  elem->set_refinement_flag(Elem::REFINE);
214 
215  if (!_coarsen_by_parents && elem_error <
216  local_coarsening_tolerance)
217  elem->set_refinement_flag(Elem::COARSEN);
218 
219  if (_coarsen_by_parents && parent)
220  {
221  ErrorVectorReal parent_error = error_per_parent[parent->id()];
222  if (parent_error >= 0.)
223  {
224  const Real parent_coarsening_tolerance =
225  std::sqrt(parent->n_children() *
226  local_coarsening_tolerance *
227  local_coarsening_tolerance);
228  if (parent_error < parent_coarsening_tolerance)
229  elem->set_refinement_flag(Elem::COARSEN);
230  }
231  }
232  }
233 }
virtual dof_id_type n_active_elem() const =0
MeshBase & _mesh
Reference to the mesh.
const Parallel::Communicator & comm() const
void create_parent_error_vector(const ErrorVector &error_per_cell, ErrorVector &error_per_parent, Real &parent_error_min, Real &parent_error_max)
Calculates the error on all coarsenable parents.
DIE A HORRIBLE DEATH HERE typedef float ErrorVectorReal
libmesh_assert(ctx)
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
bool _coarsen_by_parents
Refinement parameter values.
uint8_t dof_id_type
Definition: id_types.h:67

◆ flag_elements_by_mean_stddev()

void libMesh::MeshRefinement::flag_elements_by_mean_stddev ( const ErrorVector error_per_cell,
const Real  refine_fraction = 1.0,
const Real  coarsen_fraction = 0.0,
const unsigned int  max_level = libMesh::invalid_uint 
)

Flags elements for coarsening and refinement based on the computed error passed in error_per_cell.

This method picks the top refine_fraction * stddev + mean elements for refinement and the bottom mean - coarsen_fraction * stddev elements for coarsening. The two fractions refine_fraction and coarsen_fraction must be in \( [0,1] \).

All the function arguments except error_per_cell have been deprecated, and will be removed in future libMesh releases - to control these parameters, set the corresponding member variables.

Definition at line 583 of file mesh_refinement_flagging.C.

References _coarsen_fraction, _max_h_level, _mesh, _refine_fraction, _use_member_parameters, libMesh::Elem::COARSEN, libMesh::ParallelObject::comm(), libMesh::ErrorVectorReal, libMesh::invalid_uint, libMesh::libmesh_assert(), libMesh::ErrorVector::mean(), libMesh::Real, libMesh::Elem::REFINE, and libMesh::ErrorVector::variance().

587 {
588  // Verify that our error vector is consistent, using std::vector to
589  // avoid confusing this->comm().verify
590  libmesh_assert(this->comm().verify(dynamic_cast<const std::vector<ErrorVectorReal> &>(error_per_cell)));
591 
592  // The function arguments are currently just there for
593  // backwards_compatibility
595  {
596  // If the user used non-default parameters, lets warn
597  // that they're deprecated
598  if (refine_frac != 0.3 ||
599  coarsen_frac != 0.0 ||
600  max_l != libMesh::invalid_uint)
601  libmesh_deprecated();
602 
603  _refine_fraction = refine_frac;
604  _coarsen_fraction = coarsen_frac;
605  _max_h_level = max_l;
606  }
607 
608  // Get the mean value from the error vector
609  const Real mean = error_per_cell.mean();
610 
611  // Get the standard deviation. This equals the
612  // square-root of the variance
613  const Real stddev = std::sqrt (error_per_cell.variance());
614 
615  // Check for valid fractions
616  libmesh_assert_greater_equal (_refine_fraction, 0);
617  libmesh_assert_less_equal (_refine_fraction, 1);
618  libmesh_assert_greater_equal (_coarsen_fraction, 0);
619  libmesh_assert_less_equal (_coarsen_fraction, 1);
620 
621  // The refine and coarsen cutoff
622  const Real refine_cutoff = mean + _refine_fraction * stddev;
623  const Real coarsen_cutoff = std::max(mean - _coarsen_fraction * stddev, 0.);
624 
625  // Loop over the elements and flag them for coarsening or
626  // refinement based on the element error
627  for (auto & elem : _mesh.active_element_ptr_range())
628  {
629  const dof_id_type id = elem->id();
630 
631  libmesh_assert_less (id, error_per_cell.size());
632 
633  const ErrorVectorReal elem_error = error_per_cell[id];
634 
635  // Possibly flag the element for coarsening ...
636  if (elem_error <= coarsen_cutoff)
637  elem->set_refinement_flag(Elem::COARSEN);
638 
639  // ... or refinement
640  if ((elem_error >= refine_cutoff) && (elem->level() < _max_h_level))
641  elem->set_refinement_flag(Elem::REFINE);
642  }
643 }
const unsigned int invalid_uint
A number which is used quite often to represent an invalid or uninitialized value for an unsigned int...
Definition: libmesh.h:310
MeshBase & _mesh
Reference to the mesh.
const Parallel::Communicator & comm() const
DIE A HORRIBLE DEATH HERE typedef float ErrorVectorReal
bool _use_member_parameters
For backwards compatibility, we initialize this as false and then set it to true if the user uses any...
libmesh_assert(ctx)
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
uint8_t dof_id_type
Definition: id_types.h:67

◆ flag_elements_by_nelem_target()

bool libMesh::MeshRefinement::flag_elements_by_nelem_target ( const ErrorVector error_per_cell)

Flags elements for coarsening and refinement based on the computed error passed in error_per_cell.

This method attempts to produce a mesh with slightly more than nelem_target active elements, trading element refinement for element coarsening when their error ratios exceed coarsen_threshold. It flags no more than refine_fraction * n_elem elements for refinement and flags no more than coarsen_fraction * n_elem elements for coarsening.

Returns
true if it has done all the AMR/C it can do in a single step, or false if further adaptive steps may be required to produce a mesh with a narrow error distribution and the right number of elements.

Definition at line 237 of file mesh_refinement_flagging.C.

References _coarsen_by_parents, _coarsen_fraction, _coarsen_threshold, _max_h_level, _mesh, _nelem_target, _refine_fraction, TIMPI::Communicator::allgather(), libMesh::Elem::child_ref_range(), clean_refinement_flags(), libMesh::Elem::COARSEN, libMesh::ParallelObject::comm(), create_parent_error_vector(), dim, libMesh::Elem::has_children(), libMesh::index_range(), libMesh::Elem::level(), libMesh::libmesh_assert(), TIMPI::Communicator::max(), libMesh::MeshBase::max_elem_id(), libMesh::MeshBase::mesh_dimension(), libMesh::MeshBase::n_active_elem(), libMesh::MeshBase::query_elem_ptr(), libMesh::Real, libMesh::Elem::REFINE, libMesh::remote_elem, and libMesh::Elem::set_refinement_flag().

Referenced by main().

238 {
239  parallel_object_only();
240 
241  // Verify that our error vector is consistent, using std::vector to
242  // avoid confusing this->comm().verify
243  libmesh_assert(this->comm().verify(dynamic_cast<const std::vector<ErrorVectorReal> &>(error_per_cell)));
244 
245  // Check for valid fractions..
246  // The fraction values must be in [0,1]
247  libmesh_assert_greater_equal (_refine_fraction, 0);
248  libmesh_assert_less_equal (_refine_fraction, 1);
249  libmesh_assert_greater_equal (_coarsen_fraction, 0);
250  libmesh_assert_less_equal (_coarsen_fraction, 1);
251 
252  // This function is currently only coded to work when coarsening by
253  // parents - it's too hard to guess how many coarsenings will be
254  // performed otherwise.
256 
257  // The number of active elements in the mesh - hopefully less than
258  // 2 billion on 32 bit machines
259  const dof_id_type n_active_elem = _mesh.n_active_elem();
260 
261  // The maximum number of active elements to flag for coarsening
262  const dof_id_type max_elem_coarsen =
263  static_cast<dof_id_type>(_coarsen_fraction * n_active_elem) + 1;
264 
265  // The maximum number of elements to flag for refinement
266  const dof_id_type max_elem_refine =
267  static_cast<dof_id_type>(_refine_fraction * n_active_elem) + 1;
268 
269  // Clean up the refinement flags. These could be left
270  // over from previous refinement steps.
271  this->clean_refinement_flags();
272 
273  // The target number of elements to add or remove
274  const std::ptrdiff_t n_elem_new =
275  std::ptrdiff_t(_nelem_target) - std::ptrdiff_t(n_active_elem);
276 
277  // Create an vector with active element errors and ids,
278  // sorted by highest errors first
279  const dof_id_type max_elem_id = _mesh.max_elem_id();
280  std::vector<std::pair<ErrorVectorReal, dof_id_type>> sorted_error;
281 
282  sorted_error.reserve (n_active_elem);
283 
284  // On a DistributedMesh, we need to communicate to know which remote ids
285  // correspond to active elements.
286  {
287  std::vector<bool> is_active(max_elem_id, false);
288 
289  for (auto & elem : _mesh.active_local_element_ptr_range())
290  {
291  const dof_id_type eid = elem->id();
292  is_active[eid] = true;
293  libmesh_assert_less (eid, error_per_cell.size());
294  sorted_error.emplace_back(error_per_cell[eid], eid);
295  }
296 
297  this->comm().max(is_active);
298 
299  this->comm().allgather(sorted_error);
300  }
301 
302  // Default sort works since pairs are sorted lexicographically
303  std::sort (sorted_error.begin(), sorted_error.end());
304  std::reverse (sorted_error.begin(), sorted_error.end());
305 
306  // Create a sorted error vector with coarsenable parent elements
307  // only, sorted by lowest errors first
308  ErrorVector error_per_parent;
309  std::vector<std::pair<ErrorVectorReal, dof_id_type>> sorted_parent_error;
310  Real parent_error_min, parent_error_max;
311 
312  create_parent_error_vector(error_per_cell,
313  error_per_parent,
314  parent_error_min,
315  parent_error_max);
316 
317  // create_parent_error_vector sets values for non-parents and
318  // non-coarsenable parents to -1. Get rid of them.
319  for (auto i : index_range(error_per_parent))
320  if (error_per_parent[i] != -1)
321  sorted_parent_error.emplace_back(error_per_parent[i], i);
322 
323  std::sort (sorted_parent_error.begin(), sorted_parent_error.end());
324 
325  // Keep track of how many elements we plan to coarsen & refine
326  dof_id_type coarsen_count = 0;
327  dof_id_type refine_count = 0;
328 
329  const unsigned int dim = _mesh.mesh_dimension();
330  unsigned int twotodim = 1;
331  for (unsigned int i=0; i!=dim; ++i)
332  twotodim *= 2;
333 
334  // First, let's try to get our element count to target_nelem
335  if (n_elem_new >= 0)
336  {
337  // Every element refinement creates at least
338  // 2^dim-1 new elements
339  refine_count =
340  std::min(cast_int<dof_id_type>(n_elem_new / (twotodim-1)),
341  max_elem_refine);
342  }
343  else
344  {
345  // Every successful element coarsening is likely to destroy
346  // 2^dim-1 net elements.
347  coarsen_count =
348  std::min(cast_int<dof_id_type>(-n_elem_new / (twotodim-1)),
349  max_elem_coarsen);
350  }
351 
352  // Next, let's see if we can trade any refinement for coarsening
353  while (coarsen_count < max_elem_coarsen &&
354  refine_count < max_elem_refine &&
355  coarsen_count < sorted_parent_error.size() &&
356  refine_count < sorted_error.size() &&
357  sorted_error[refine_count].first >
358  sorted_parent_error[coarsen_count].first * _coarsen_threshold)
359  {
360  coarsen_count++;
361  refine_count++;
362  }
363 
364  // On a DistributedMesh, we need to communicate to know which remote ids
365  // correspond to refinable elements
366  dof_id_type successful_refine_count = 0;
367  {
368  std::vector<bool> is_refinable(max_elem_id, false);
369 
370  for (const auto & pr : sorted_error)
371  {
372  dof_id_type eid = pr.second;
373  Elem * elem = _mesh.query_elem_ptr(eid);
374  if (elem && elem->level() < _max_h_level)
375  is_refinable[eid] = true;
376  }
377  this->comm().max(is_refinable);
378 
379  if (refine_count > max_elem_refine)
380  refine_count = max_elem_refine;
381  for (const auto & pr : sorted_error)
382  {
383  if (successful_refine_count >= refine_count)
384  break;
385 
386  dof_id_type eid = pr.second;
387  Elem * elem = _mesh.query_elem_ptr(eid);
388  if (is_refinable[eid])
389  {
390  if (elem)
392  successful_refine_count++;
393  }
394  }
395  }
396 
397  // If we couldn't refine enough elements, don't coarsen too many
398  // either
399  if (coarsen_count < (refine_count - successful_refine_count))
400  coarsen_count = 0;
401  else
402  coarsen_count -= (refine_count - successful_refine_count);
403 
404  if (coarsen_count > max_elem_coarsen)
405  coarsen_count = max_elem_coarsen;
406 
407  dof_id_type successful_coarsen_count = 0;
408  if (coarsen_count)
409  {
410  for (const auto & pr : sorted_parent_error)
411  {
412  if (successful_coarsen_count >= coarsen_count * twotodim)
413  break;
414 
415  dof_id_type parent_id = pr.second;
416  Elem * parent = _mesh.query_elem_ptr(parent_id);
417 
418  // On a DistributedMesh we skip remote elements
419  if (!parent)
420  continue;
421 
422  libmesh_assert(parent->has_children());
423  for (auto & elem : parent->child_ref_range())
424  {
425  if (&elem != remote_elem)
426  {
427  libmesh_assert(elem.active());
428  elem.set_refinement_flag(Elem::COARSEN);
429  successful_coarsen_count++;
430  }
431  }
432  }
433  }
434 
435  // Return true if we've done all the AMR/C we can
436  if (!successful_coarsen_count &&
437  !successful_refine_count)
438  return true;
439  // And false if there may still be more to do.
440  return false;
441 }
void allgather(const T &send_data, std::vector< T, A > &recv_data) const
virtual dof_id_type n_active_elem() const =0
MeshBase & _mesh
Reference to the mesh.
unsigned int dim
void set_refinement_flag(const RefinementState rflag)
Sets the value of the refinement flag for the element.
Definition: elem.h:3218
const Parallel::Communicator & comm() const
void clean_refinement_flags()
Sets the refinement flag to Elem::DO_NOTHING for each element in the mesh.
void create_parent_error_vector(const ErrorVector &error_per_cell, ErrorVector &error_per_parent, Real &parent_error_min, Real &parent_error_max)
Calculates the error on all coarsenable parents.
virtual dof_id_type max_elem_id() const =0
libmesh_assert(ctx)
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
virtual const Elem * query_elem_ptr(const dof_id_type i) const =0
void max(const T &r, T &o, Request &req) const
unsigned int mesh_dimension() const
Definition: mesh_base.C:372
auto index_range(const T &sizable)
Helper function that returns an IntRange<std::size_t> representing all the indices of the passed-in v...
Definition: int_range.h:117
bool _coarsen_by_parents
Refinement parameter values.
uint8_t dof_id_type
Definition: id_types.h:67
const RemoteElem * remote_elem
Definition: remote_elem.C:57

◆ get_enforce_mismatch_limit_prior_to_refinement()

bool libMesh::MeshRefinement::get_enforce_mismatch_limit_prior_to_refinement ( )
inline
Returns
The value of the _enforce_mismatch_limit_prior_to_refinement flag, false by default.
Deprecated:
Use enforce_mismatch_limit_prior_to_refinement() instead.

Definition at line 973 of file mesh_refinement.h.

References enforce_mismatch_limit_prior_to_refinement().

974 {
975  libmesh_deprecated();
977 }
bool & enforce_mismatch_limit_prior_to_refinement()
Get/set the _enforce_mismatch_limit_prior_to_refinement flag.

◆ get_mesh() [1/2]

const MeshBase& libMesh::MeshRefinement::get_mesh ( ) const
inline
Returns
A constant reference to the MeshBase object associated with this object.

Definition at line 340 of file mesh_refinement.h.

References _mesh.

340 { return _mesh; }
MeshBase & _mesh
Reference to the mesh.

◆ get_mesh() [2/2]

MeshBase& libMesh::MeshRefinement::get_mesh ( )
inline
Returns
A writable reference to the MeshBase object associated with this object.

Definition at line 346 of file mesh_refinement.h.

References _mesh.

346 { return _mesh; }
MeshBase & _mesh
Reference to the mesh.

◆ has_topological_neighbor()

bool libMesh::MeshRefinement::has_topological_neighbor ( const Elem elem,
const PointLocatorBase point_locator,
const Elem neighbor 
) const
private

Local dispatch function for checking the correct has_neighbor function from the Elem class.

Definition at line 1811 of file mesh_refinement.C.

References _mesh, _periodic_boundaries, libMesh::Elem::has_neighbor(), libMesh::Elem::has_topological_neighbor(), and libMesh::libmesh_assert().

Referenced by make_coarsening_compatible(), and make_refinement_compatible().

1814 {
1815 #ifdef LIBMESH_ENABLE_PERIODIC
1816  if (_periodic_boundaries && !_periodic_boundaries->empty())
1817  {
1818  libmesh_assert(point_locator);
1819  return elem->has_topological_neighbor(neighbor, _mesh, *point_locator, _periodic_boundaries);
1820  }
1821 #endif
1822  return elem->has_neighbor(neighbor);
1823 }
MeshBase & _mesh
Reference to the mesh.
PeriodicBoundaries * _periodic_boundaries
libmesh_assert(ctx)

◆ limit_level_mismatch_at_edge()

bool libMesh::MeshRefinement::limit_level_mismatch_at_edge ( const unsigned int  max_mismatch)
private

Definition at line 126 of file mesh_refinement_smoothing.C.

References _enforce_mismatch_limit_prior_to_refinement, _mesh, libMesh::ParallelObject::comm(), EDGE, enforce_mismatch_limit_prior_to_refinement(), TIMPI::Communicator::max(), libMesh::Elem::parent(), and libMesh::Elem::REFINE.

Referenced by _smooth_flags().

127 {
128  // This function must be run on all processors at once
129  parallel_object_only();
130 
131  bool flags_changed = false;
132 
133 
134  // Maps holding the maximum element level that touches an edge
135  std::map<std::pair<unsigned int, unsigned int>, unsigned char>
136  max_level_at_edge;
137  std::map<std::pair<unsigned int, unsigned int>, unsigned char>
138  max_p_level_at_edge;
139 
140  std::unique_ptr<const Elem> edge, pedge;
141  // Loop over all the active elements & fill the maps
142  for (auto & elem : _mesh.active_element_ptr_range())
143  {
144  const unsigned char elem_level =
145  cast_int<unsigned char>(elem->level() +
146  ((elem->refinement_flag() == Elem::REFINE) ? 1 : 0));
147  const unsigned char elem_p_level =
148  cast_int<unsigned char>(elem->p_level() +
149  ((elem->p_refinement_flag() == Elem::REFINE) ? 1 : 0));
150 
151  // Set the max_level at each edge
152  for (auto n : elem->edge_index_range())
153  {
154  elem->build_edge_ptr(edge, n);
155  dof_id_type childnode0 = edge->node_id(0);
156  dof_id_type childnode1 = edge->node_id(1);
157  if (childnode1 < childnode0)
158  std::swap(childnode0, childnode1);
159 
160  for (const Elem * p = elem; p != nullptr; p = p->parent())
161  {
162  p->build_edge_ptr(pedge, n);
163  dof_id_type node0 = pedge->node_id(0);
164  dof_id_type node1 = pedge->node_id(1);
165 
166  if (node1 < node0)
167  std::swap(node0, node1);
168 
169  // If elem does not share this edge with its ancestor
170  // p, refinement levels of elements sharing p's edge
171  // are not restricted by refinement levels of elem.
172  // Furthermore, elem will not share this edge with any
173  // of p's ancestors, so we can safely break out of the
174  // for loop early.
175  if (node0 != childnode0 && node1 != childnode1)
176  break;
177 
178  childnode0 = node0;
179  childnode1 = node1;
180 
181  std::pair<unsigned int, unsigned int> edge_key =
182  std::make_pair(node0, node1);
183 
184  // Try emplacing (edge_key, elem_level) into max_level_at_edge map.
185  // If emplacing fails, it means the edge_key already existed, so
186  // we need to take the max of the previous and current values.
187  if (auto [it, emplaced] = max_level_at_edge.emplace(edge_key, elem_level);
188  !emplaced)
189  it->second = std::max(it->second, elem_level);
190 
191  // Same thing for p_level
192  if (auto [it, emplaced] = max_p_level_at_edge.emplace(edge_key, elem_p_level);
193  !emplaced)
194  it->second = std::max(it->second, elem_p_level);
195  }
196  }
197  }
198 
199 
200  // Now loop over the active elements and flag the elements
201  // who violate the requested level mismatch
202  for (auto & elem : _mesh.active_element_ptr_range())
203  {
204  const unsigned int elem_level = elem->level();
205  const unsigned int elem_p_level = elem->p_level();
206 
207  // Skip the element if it is already fully flagged
208  if (elem->refinement_flag() == Elem::REFINE &&
209  elem->p_refinement_flag() == Elem::REFINE
211  continue;
212 
213  // Loop over the nodes, check for possible mismatch
214  for (auto n : elem->edge_index_range())
215  {
216  elem->build_edge_ptr(edge, n);
217  dof_id_type node0 = edge->node_id(0);
218  dof_id_type node1 = edge->node_id(1);
219  if (node1 < node0)
220  std::swap(node0, node1);
221 
222  std::pair<dof_id_type, dof_id_type> edge_key =
223  std::make_pair(node0, node1);
224 
225  // Flag the element for refinement if it violates
226  // the requested level mismatch
227  if ((elem_level + max_mismatch) < max_level_at_edge[edge_key]
228  && elem->refinement_flag() != Elem::REFINE)
229  {
230  elem->set_refinement_flag (Elem::REFINE);
231  flags_changed = true;
232  }
233 
234  if ((elem_p_level + max_mismatch) < max_p_level_at_edge[edge_key]
235  && elem->p_refinement_flag() != Elem::REFINE)
236  {
237  elem->set_p_refinement_flag (Elem::REFINE);
238  flags_changed = true;
239  }
240 
241  // Possibly enforce limit mismatch prior to refinement
242  flags_changed |= this->enforce_mismatch_limit_prior_to_refinement(elem, EDGE, max_mismatch);
243  } // loop over edges
244  } // loop over active elements
245 
246  // If flags changed on any processor then they changed globally
247  this->comm().max(flags_changed);
248 
249  return flags_changed;
250 }
bool & enforce_mismatch_limit_prior_to_refinement()
Get/set the _enforce_mismatch_limit_prior_to_refinement flag.
MeshBase & _mesh
Reference to the mesh.
const Parallel::Communicator & comm() const
bool _enforce_mismatch_limit_prior_to_refinement
This option enforces the mismatch level prior to refinement by checking if refining any element mar...
void max(const T &r, T &o, Request &req) const
uint8_t dof_id_type
Definition: id_types.h:67

◆ limit_level_mismatch_at_node()

bool libMesh::MeshRefinement::limit_level_mismatch_at_node ( const unsigned int  max_mismatch)
private


This algorithm restricts the maximum level mismatch at any node in the mesh.

Calling this with max_mismatch equal to 1 would transform this mesh:

* o---o---o---o---o-------o-------o
* |   |   |   |   |       |       |
* |   |   |   |   |       |       |
* o---o---o---o---o       |       |
* |   |   |   |   |       |       |
* |   |   |   |   |       |       |
* o---o---o---o---o-------o-------o
* |   |   |   |   |       |       |
* |   |   |   |   |       |       |
* o---o---o---o---o       |       |
* |   |   |   |   |       |       |
* |   |   |   |   |       |       |
* o---o---o---o---o-------o-------o
* |       |       |               |
* |       |       |               |
* |       |       |               |
* |       |       |               |
* |       |       |               |
* o-------o-------o               |
* |       |       |               |
* |       |       |               |
* |       |       |               |
* |       |       |               |
* |       |       |               |
* o-------o-------o---------------o
* 

into this:

* o---o---o---o---o-------o-------o
* |   |   |   |   |       |       |
* |   |   |   |   |       |       |
* o---o---o---o---o       |       |
* |   |   |   |   |       |       |
* |   |   |   |   |       |       |
* o---o---o---o---o-------o-------o
* |   |   |   |   |       |       |
* |   |   |   |   |       |       |
* o---o---o---o---o       |       |
* |   |   |   |   |       |       |
* |   |   |   |   |       |       |
* o---o---o---o---o-------o-------o
* |       |       |       :       |
* |       |       |       :       |
* |       |       |       :       |
* |       |       |       :       |
* |       |       |       :       |
* o-------o-------o.......o.......o
* |       |       |       :       |
* |       |       |       :       |
* |       |       |       :       |
* |       |       |       :       |
* |       |       |       :       |
* o-------o-------o-------o-------o
* 

by refining the indicated element

Definition at line 39 of file mesh_refinement_smoothing.C.

References _enforce_mismatch_limit_prior_to_refinement, _mesh, libMesh::ParallelObject::comm(), enforce_mismatch_limit_prior_to_refinement(), TIMPI::Communicator::max(), libMesh::MeshBase::n_nodes(), POINT, and libMesh::Elem::REFINE.

Referenced by _smooth_flags().

40 {
41  // This function must be run on all processors at once
42  parallel_object_only();
43 
44  bool flags_changed = false;
45 
46 
47  // Vector holding the maximum element level that touches a node.
48  std::vector<unsigned char> max_level_at_node (_mesh.n_nodes(), 0);
49  std::vector<unsigned char> max_p_level_at_node (_mesh.n_nodes(), 0);
50 
51  // Loop over all the active elements & fill the vector
52  for (auto & elem : _mesh.active_element_ptr_range())
53  {
54  const unsigned char elem_level =
55  cast_int<unsigned char>(elem->level() +
56  ((elem->refinement_flag() == Elem::REFINE) ? 1 : 0));
57  const unsigned char elem_p_level =
58  cast_int<unsigned char>(elem->p_level() +
59  ((elem->p_refinement_flag() == Elem::REFINE) ? 1 : 0));
60 
61  // Set the max_level at each node
62  for (const Node & node : elem->node_ref_range())
63  {
64  const dof_id_type node_number = node.id();
65 
66  libmesh_assert_less (node_number, max_level_at_node.size());
67 
68  max_level_at_node[node_number] =
69  std::max (max_level_at_node[node_number], elem_level);
70  max_p_level_at_node[node_number] =
71  std::max (max_p_level_at_node[node_number], elem_p_level);
72  }
73  }
74 
75 
76  // Now loop over the active elements and flag the elements
77  // who violate the requested level mismatch. Alternatively, if
78  // _enforce_mismatch_limit_prior_to_refinement is true, swap refinement flags
79  // accordingly.
80  for (auto & elem : _mesh.active_element_ptr_range())
81  {
82  const unsigned int elem_level = elem->level();
83  const unsigned int elem_p_level = elem->p_level();
84 
85  // Skip the element if it is already fully flagged
86  // unless we are enforcing mismatch prior to refinement and may need to
87  // remove the refinement flag(s)
88  if (elem->refinement_flag() == Elem::REFINE &&
89  elem->p_refinement_flag() == Elem::REFINE
91  continue;
92 
93  // Loop over the nodes, check for possible mismatch
94  for (const Node & node : elem->node_ref_range())
95  {
96  const dof_id_type node_number = node.id();
97 
98  // Flag the element for refinement if it violates
99  // the requested level mismatch
100  if ((elem_level + max_mismatch) < max_level_at_node[node_number]
101  && elem->refinement_flag() != Elem::REFINE)
102  {
103  elem->set_refinement_flag (Elem::REFINE);
104  flags_changed = true;
105  }
106  if ((elem_p_level + max_mismatch) < max_p_level_at_node[node_number]
107  && elem->p_refinement_flag() != Elem::REFINE)
108  {
109  elem->set_p_refinement_flag (Elem::REFINE);
110  flags_changed = true;
111  }
112 
113  // Possibly enforce limit mismatch prior to refinement
114  flags_changed |= this->enforce_mismatch_limit_prior_to_refinement(elem, POINT, max_mismatch);
115  }
116  }
117 
118  // If flags changed on any processor then they changed globally
119  this->comm().max(flags_changed);
120 
121  return flags_changed;
122 }
bool & enforce_mismatch_limit_prior_to_refinement()
Get/set the _enforce_mismatch_limit_prior_to_refinement flag.
MeshBase & _mesh
Reference to the mesh.
const Parallel::Communicator & comm() const
bool _enforce_mismatch_limit_prior_to_refinement
This option enforces the mismatch level prior to refinement by checking if refining any element mar...
void max(const T &r, T &o, Request &req) const
virtual dof_id_type n_nodes() const =0
uint8_t dof_id_type
Definition: id_types.h:67

◆ limit_overrefined_boundary()

bool libMesh::MeshRefinement::limit_overrefined_boundary ( const signed char  max_mismatch)
private

Definition at line 254 of file mesh_refinement_smoothing.C.

References _mesh, libMesh::ParallelObject::comm(), TIMPI::Communicator::max(), and libMesh::Elem::REFINE.

Referenced by _smooth_flags().

255 {
256  // This function must be run on all processors at once
257  parallel_object_only();
258 
259  bool flags_changed = false;
260 
261  // Loop over all the active elements & look for mismatches to fix.
262  for (auto & elem : _mesh.active_element_ptr_range())
263  {
264  // If we don't have an interior_parent then there's nothing to
265  // be mismatched with.
266  if ((elem->dim() >= LIBMESH_DIM) ||
267  !elem->interior_parent())
268  continue;
269 
270  const unsigned char elem_level =
271  cast_int<unsigned char>(elem->level() +
272  ((elem->refinement_flag() == Elem::REFINE) ? 1 : 0));
273  const unsigned char elem_p_level =
274  cast_int<unsigned char>(elem->p_level() +
275  ((elem->p_refinement_flag() == Elem::REFINE) ? 1 : 0));
276 
277  // get all relevant interior elements
278  std::set<Elem *> neighbor_set;
279  elem->find_interior_neighbors(neighbor_set);
280 
281  for (auto & neighbor : neighbor_set)
282  if (max_mismatch >= 0)
283  {
284  if ((elem_level > neighbor->level() + max_mismatch) &&
285  (neighbor->refinement_flag() != Elem::REFINE))
286  {
287  neighbor->set_refinement_flag(Elem::REFINE);
288  flags_changed = true;
289  }
290 
291  if ((elem_p_level > neighbor->p_level() + max_mismatch) &&
292  (neighbor->p_refinement_flag() != Elem::REFINE))
293  {
294  neighbor->set_p_refinement_flag(Elem::REFINE);
295  flags_changed = true;
296  }
297  }
298  }
299 
300  // If flags changed on any processor then they changed globally
301  this->comm().max(flags_changed);
302 
303  return flags_changed;
304 }
MeshBase & _mesh
Reference to the mesh.
const Parallel::Communicator & comm() const
void max(const T &r, T &o, Request &req) const

◆ limit_underrefined_boundary()

bool libMesh::MeshRefinement::limit_underrefined_boundary ( const signed char  max_mismatch)
private

Definition at line 308 of file mesh_refinement_smoothing.C.

References _mesh, libMesh::ParallelObject::comm(), TIMPI::Communicator::max(), and libMesh::Elem::REFINE.

Referenced by _smooth_flags().

309 {
310  // This function must be run on all processors at once
311  parallel_object_only();
312 
313  bool flags_changed = false;
314 
315  // Loop over all the active elements & look for mismatches to fix.
316  for (auto & elem : _mesh.active_element_ptr_range())
317  {
318  // If we don't have an interior_parent then there's nothing to
319  // be mismatched with.
320  if ((elem->dim() >= LIBMESH_DIM) ||
321  !elem->interior_parent())
322  continue;
323 
324  // get all relevant interior elements
325  std::set<const Elem *> neighbor_set;
326  elem->find_interior_neighbors(neighbor_set);
327 
328  for (const Elem * neighbor : neighbor_set)
329  {
330  const unsigned char neighbor_level =
331  cast_int<unsigned char>(neighbor->level() +
332  ((neighbor->refinement_flag() == Elem::REFINE) ? 1 : 0));
333 
334  const unsigned char neighbor_p_level =
335  cast_int<unsigned char>(neighbor->p_level() +
336  ((neighbor->p_refinement_flag() == Elem::REFINE) ? 1 : 0));
337 
338  if (max_mismatch >= 0)
339  {
340  if ((neighbor_level >
341  elem->level() + max_mismatch) &&
342  (elem->refinement_flag() != Elem::REFINE))
343  {
344  elem->set_refinement_flag(Elem::REFINE);
345  flags_changed = true;
346  }
347 
348  if ((neighbor_p_level >
349  elem->p_level() + max_mismatch) &&
350  (elem->p_refinement_flag() != Elem::REFINE))
351  {
352  elem->set_p_refinement_flag(Elem::REFINE);
353  flags_changed = true;
354  }
355  }
356  } // loop over interior neighbors
357  }
358 
359  // If flags changed on any processor then they changed globally
360  this->comm().max(flags_changed);
361 
362  return flags_changed;
363 }
MeshBase & _mesh
Reference to the mesh.
const Parallel::Communicator & comm() const
void max(const T &r, T &o, Request &req) const

◆ make_coarsening_compatible()

bool libMesh::MeshRefinement::make_coarsening_compatible ( )
private

Take user-specified coarsening flags and augment them so that level-one dependency is satisfied.

This function used to take an argument, maintain_level_one - new code should use face_level_mismatch_limit() instead.

Definition at line 777 of file mesh_refinement.C.

References _face_level_mismatch_limit, _mesh, _periodic_boundaries, libMesh::Elem::active(), libMesh::as_range(), libMesh::Elem::child_ref_range(), libMesh::Elem::COARSEN, libMesh::Elem::COARSEN_INACTIVE, libMesh::ParallelObject::comm(), libMesh::Elem::DO_NOTHING, libMesh::MeshBase::elem_ref(), TIMPI::Communicator::get_unique_tag(), libMesh::Elem::has_children(), has_topological_neighbor(), libMesh::Elem::INACTIVE, libMesh::MeshBase::is_replicated(), libMesh::MeshBase::is_serial(), libMesh::Elem::level(), libMesh::libmesh_assert(), TIMPI::Communicator::min(), libMesh::ParallelObject::n_processors(), libMesh::Elem::p_level(), libMesh::Elem::p_refinement_flag(), libMesh::ParallelObject::processor_id(), libMesh::DofObject::processor_id(), TIMPI::Communicator::receive(), libMesh::Elem::REFINE, libMesh::Elem::refinement_flag(), libMesh::remote_elem, TIMPI::Communicator::send(), libMesh::Elem::set_p_refinement_flag(), libMesh::Elem::set_refinement_flag(), libMesh::MeshBase::sub_point_locator(), libMesh::Parallel::sync_dofobject_data_by_id(), and topological_neighbor().

Referenced by _smooth_flags(), coarsen_elements(), and refine_and_coarsen_elements().

778 {
779  // This function must be run on all processors at once
780  parallel_object_only();
781 
782  // We may need a PointLocator for topological_neighbor() tests
783  // later, which we need to make sure gets constructed on all
784  // processors at once.
785  std::unique_ptr<PointLocatorBase> point_locator;
786 
787 #ifdef LIBMESH_ENABLE_PERIODIC
788  bool has_periodic_boundaries =
790  libmesh_assert(this->comm().verify(has_periodic_boundaries));
791 
792  if (has_periodic_boundaries)
793  point_locator = _mesh.sub_point_locator();
794 #endif
795 
796  LOG_SCOPE ("make_coarsening_compatible()", "MeshRefinement");
797 
798  // Unless we encounter a specific situation level-one
799  // will be satisfied after executing this loop just once
800  bool level_one_satisfied = true;
801 
802 
803  // Unless we encounter a specific situation we will be compatible
804  // with any selected refinement flags
805  bool compatible_with_refinement = true;
806 
807 
808  // find the maximum h and p levels in the mesh
809  unsigned int max_level = 0;
810  unsigned int max_p_level = 0;
811 
812  {
813  // First we look at all the active level-0 elements. Since it doesn't make
814  // sense to coarsen them we must un-set their coarsen flags if
815  // they are set.
816  for (auto & elem : _mesh.active_element_ptr_range())
817  {
818  max_level = std::max(max_level, elem->level());
819  max_p_level =
820  std::max(max_p_level,
821  static_cast<unsigned int>(elem->p_level()));
822 
823  if ((elem->level() == 0) &&
824  (elem->refinement_flag() == Elem::COARSEN))
825  elem->set_refinement_flag(Elem::DO_NOTHING);
826 
827  if ((elem->p_level() == 0) &&
828  (elem->p_refinement_flag() == Elem::COARSEN))
829  elem->set_p_refinement_flag(Elem::DO_NOTHING);
830  }
831  }
832 
833  // Even if there are no refined elements on this processor then
834  // there may still be work for us to do on e.g. ancestor elements.
835  // At the very least we need to be in the loop if a distributed mesh
836  // needs to synchronize data.
837 #if 0
838  if (max_level == 0 && max_p_level == 0)
839  {
840  // But we still have to check with other processors
841  this->comm().min(compatible_with_refinement);
842 
843  return compatible_with_refinement;
844  }
845 #endif
846 
847  // Loop over all the active elements. If an element is marked
848  // for coarsening we better check its neighbors. If ANY of these neighbors
849  // are marked for refinement AND are at the same level then there is a
850  // conflict. By convention refinement wins, so we un-mark the element for
851  // coarsening. Level-one would be violated in this case so we need to re-run
852  // the loop.
854  {
855 
856  repeat:
857  level_one_satisfied = true;
858 
859  do
860  {
861  level_one_satisfied = true;
862 
863  for (auto & elem : _mesh.active_element_ptr_range())
864  {
865  bool my_flag_changed = false;
866 
867  if (elem->refinement_flag() == Elem::COARSEN) // If the element is active and
868  // the coarsen flag is set
869  {
870  const unsigned int my_level = elem->level();
871 
872  for (auto n : elem->side_index_range())
873  {
874  const Elem * neighbor =
875  topological_neighbor(elem, point_locator.get(), n);
876 
877  if (neighbor != nullptr && // I have a
878  neighbor != remote_elem) // neighbor here
879  {
880  if (neighbor->active()) // and it is active
881  {
882  if ((neighbor->level() == my_level) &&
883  (neighbor->refinement_flag() == Elem::REFINE)) // the neighbor is at my level
884  // and wants to be refined
885  {
887  my_flag_changed = true;
888  break;
889  }
890  }
891  else // I have a neighbor and it is not active. That means it has children.
892  { // While it _may_ be possible to coarsen us if all the children of
893  // that element want to be coarsened, it is impossible to know at this
894  // stage. Forget about it for the moment... This can be handled in
895  // two steps.
896  elem->set_refinement_flag(Elem::DO_NOTHING);
897  my_flag_changed = true;
898  break;
899  }
900  }
901  }
902  }
903  if (elem->p_refinement_flag() == Elem::COARSEN) // If
904  // the element is active and the order reduction flag is set
905  {
906  const unsigned int my_p_level = elem->p_level();
907 
908  for (auto n : elem->side_index_range())
909  {
910  const Elem * neighbor =
911  topological_neighbor(elem, point_locator.get(), n);
912 
913  if (neighbor != nullptr && // I have a
914  neighbor != remote_elem) // neighbor here
915  {
916  if (neighbor->active()) // and it is active
917  {
918  if ((neighbor->p_level() > my_p_level &&
919  neighbor->p_refinement_flag() != Elem::COARSEN)
920  || (neighbor->p_level() == my_p_level &&
921  neighbor->p_refinement_flag() == Elem::REFINE))
922  {
924  my_flag_changed = true;
925  break;
926  }
927  }
928  else // I have a neighbor and it is not active.
929  { // We need to find which of its children
930  // have me as a neighbor, and maintain
931  // level one p compatibility with them.
932  // Because we currently have level one h
933  // compatibility, we don't need to check
934  // grandchildren
935 
936  libmesh_assert(neighbor->has_children());
937  for (auto & subneighbor : neighbor->child_ref_range())
938  if (&subneighbor != remote_elem &&
939  subneighbor.active() &&
940  has_topological_neighbor(&subneighbor, point_locator.get(), elem))
941  if ((subneighbor.p_level() > my_p_level &&
942  subneighbor.p_refinement_flag() != Elem::COARSEN)
943  || (subneighbor.p_level() == my_p_level &&
944  subneighbor.p_refinement_flag() == Elem::REFINE))
945  {
946  elem->set_p_refinement_flag(Elem::DO_NOTHING);
947  my_flag_changed = true;
948  break;
949  }
950  if (my_flag_changed)
951  break;
952  }
953  }
954  }
955  }
956 
957  // If the current element's flag changed, we hadn't
958  // satisfied the level one rule.
959  if (my_flag_changed)
960  level_one_satisfied = false;
961 
962  // Additionally, if it has non-local neighbors, and
963  // we're not in serial, then we'll eventually have to
964  // return compatible_with_refinement = false, because
965  // our change has to propagate to neighboring
966  // processors.
967  if (my_flag_changed && !_mesh.is_serial())
968  for (auto n : elem->side_index_range())
969  {
970  Elem * neigh =
971  topological_neighbor(elem, point_locator.get(), n);
972 
973  if (!neigh)
974  continue;
975  if (neigh == remote_elem ||
976  neigh->processor_id() !=
977  this->processor_id())
978  {
979  compatible_with_refinement = false;
980  break;
981  }
982  // FIXME - for non-level one meshes we should
983  // test all descendants
984  if (neigh->has_children())
985  for (auto & child : neigh->child_ref_range())
986  if (&child == remote_elem ||
987  child.processor_id() !=
988  this->processor_id())
989  {
990  compatible_with_refinement = false;
991  break;
992  }
993  }
994  }
995  }
996  while (!level_one_satisfied);
997 
998  } // end if (_face_level_mismatch_limit)
999 
1000 
1001  // Next we look at all of the ancestor cells.
1002  // If there is a parent cell with all of its children
1003  // wanting to be unrefined then the element is a candidate
1004  // for unrefinement. If all the children don't
1005  // all want to be unrefined then ALL of them need to have their
1006  // unrefinement flags cleared.
1007  for (int level = max_level; level >= 0; level--)
1008  for (auto & elem : as_range(_mesh.level_elements_begin(level), _mesh.level_elements_end(level)))
1009  if (elem->ancestor())
1010  {
1011  // right now the element hasn't been disqualified
1012  // as a candidate for unrefinement
1013  bool is_a_candidate = true;
1014  bool found_remote_child = false;
1015 
1016  for (auto & child : elem->child_ref_range())
1017  {
1018  if (&child == remote_elem)
1019  found_remote_child = true;
1020  else if ((child.refinement_flag() != Elem::COARSEN) ||
1021  !child.active() )
1022  is_a_candidate = false;
1023  }
1024 
1025  if (!is_a_candidate && !found_remote_child)
1026  {
1028 
1029  for (auto & child : elem->child_ref_range())
1030  {
1031  if (&child == remote_elem)
1032  continue;
1033  if (child.refinement_flag() == Elem::COARSEN)
1034  {
1035  level_one_satisfied = false;
1036  child.set_refinement_flag(Elem::DO_NOTHING);
1037  }
1038  }
1039  }
1040  }
1041 
1042  if (!level_one_satisfied && _face_level_mismatch_limit) goto repeat;
1043 
1044 
1045  // If all the children of a parent are set to be coarsened
1046  // then flag the parent so that they can kill their kids.
1047 
1048  // On a distributed mesh, we won't always be able to determine this
1049  // on parent elements with remote children, even if we own the
1050  // parent, without communication.
1051  //
1052  // We'll first communicate *to* parents' owners when we determine
1053  // they cannot be coarsened, then we'll sync the final refinement
1054  // flag *from* the parents.
1055 
1056  // uncoarsenable_parents[p] live on processor id p
1057  const processor_id_type n_proc = _mesh.n_processors();
1058  const processor_id_type my_proc_id = _mesh.processor_id();
1059  const bool distributed_mesh = !_mesh.is_replicated();
1060 
1061  std::vector<std::vector<dof_id_type>>
1062  uncoarsenable_parents(n_proc);
1063 
1064  for (auto & elem : as_range(_mesh.ancestor_elements_begin(), _mesh.ancestor_elements_end()))
1065  {
1066  // Presume all the children are flagged for coarsening and
1067  // then look for a contradiction
1068  bool all_children_flagged_for_coarsening = true;
1069 
1070  for (auto & child : elem->child_ref_range())
1071  {
1072  if (&child != remote_elem &&
1073  child.refinement_flag() != Elem::COARSEN)
1074  {
1075  all_children_flagged_for_coarsening = false;
1076  if (!distributed_mesh)
1077  break;
1078  if (child.processor_id() != elem->processor_id())
1079  {
1080  uncoarsenable_parents[elem->processor_id()].push_back(elem->id());
1081  break;
1082  }
1083  }
1084  }
1085 
1086  if (all_children_flagged_for_coarsening)
1087  elem->set_refinement_flag(Elem::COARSEN_INACTIVE);
1088  else
1089  elem->set_refinement_flag(Elem::INACTIVE);
1090  }
1091 
1092  // If we have a distributed mesh, we might need to sync up
1093  // INACTIVE vs. COARSEN_INACTIVE flags.
1094  if (distributed_mesh)
1095  {
1096  // We'd better still be in sync here
1097  parallel_object_only();
1098 
1099  Parallel::MessageTag
1100  uncoarsenable_tag = this->comm().get_unique_tag();
1101  std::vector<Parallel::Request> uncoarsenable_push_requests(n_proc-1);
1102 
1103  for (processor_id_type p = 0; p != n_proc; ++p)
1104  {
1105  if (p == my_proc_id)
1106  continue;
1107 
1108  Parallel::Request &request =
1109  uncoarsenable_push_requests[p - (p > my_proc_id)];
1110 
1111  _mesh.comm().send
1112  (p, uncoarsenable_parents[p], request, uncoarsenable_tag);
1113  }
1114 
1115  for (processor_id_type p = 1; p != n_proc; ++p)
1116  {
1117  std::vector<dof_id_type> my_uncoarsenable_parents;
1118  _mesh.comm().receive
1119  (Parallel::any_source, my_uncoarsenable_parents,
1120  uncoarsenable_tag);
1121 
1122  for (const auto & id : my_uncoarsenable_parents)
1123  {
1124  Elem & elem = _mesh.elem_ref(id);
1125  libmesh_assert(elem.refinement_flag() == Elem::INACTIVE ||
1126  elem.refinement_flag() == Elem::COARSEN_INACTIVE);
1127  elem.set_refinement_flag(Elem::INACTIVE);
1128  }
1129  }
1130 
1131  Parallel::wait(uncoarsenable_push_requests);
1132 
1133  SyncRefinementFlags hsync(_mesh, &Elem::refinement_flag,
1136  (this->comm(), _mesh.not_local_elements_begin(),
1137  _mesh.not_local_elements_end(),
1138  // We'd like a smaller sync, but this leads to bugs?
1139  // SyncCoarsenInactive(),
1140  hsync);
1141  }
1142 
1143  // If one processor finds an incompatibility, we're globally
1144  // incompatible
1145  this->comm().min(compatible_with_refinement);
1146 
1147  return compatible_with_refinement;
1148 }
RefinementState refinement_flag() const
Definition: elem.h:3210
MPI_Request request
std::unique_ptr< PointLocatorBase > sub_point_locator() const
Definition: mesh_base.C:1675
bool has_topological_neighbor(const Elem *elem, const PointLocatorBase *point_locator, const Elem *neighbor) const
Local dispatch function for checking the correct has_neighbor function from the Elem class...
MeshBase & _mesh
Reference to the mesh.
MessageTag get_unique_tag(int tagvalue=MessageTag::invalid_tag) const
void set_refinement_flag(const RefinementState rflag)
Sets the value of the refinement flag for the element.
Definition: elem.h:3218
const Parallel::Communicator & comm() const
PeriodicBoundaries * _periodic_boundaries
uint8_t processor_id_type
processor_id_type n_processors() const
virtual bool is_serial() const
Definition: mesh_base.h:211
Status receive(const unsigned int dest_processor_id, T &buf, const MessageTag &tag=any_tag) const
void min(const T &r, T &o, Request &req) const
unsigned char _face_level_mismatch_limit
SimpleRange< IndexType > as_range(const std::pair< IndexType, IndexType > &p)
Helper function that allows us to treat a homogenous pair as a range.
Definition: simple_range.h:57
libmesh_assert(ctx)
void sync_dofobject_data_by_id(const Communicator &comm, const Iterator &range_begin, const Iterator &range_end, SyncFunctor &sync)
Request data about a range of ghost dofobjects uniquely identified by their id.
void send(const unsigned int dest_processor_id, const T &buf, const MessageTag &tag=no_tag) const
virtual bool is_replicated() const
Definition: mesh_base.h:233
virtual const Elem & elem_ref(const dof_id_type i) const
Definition: mesh_base.h:639
Elem * topological_neighbor(Elem *elem, const PointLocatorBase *point_locator, const unsigned int side) const
Local dispatch function for getting the correct topological neighbor from the Elem class...
void set_p_refinement_flag(const RefinementState pflag)
Sets the value of the p-refinement flag for the element.
Definition: elem.h:3234
processor_id_type processor_id() const
bool active() const
Definition: elem.h:2941
processor_id_type processor_id() const
Definition: dof_object.h:905
const RemoteElem * remote_elem
Definition: remote_elem.C:57

◆ make_flags_parallel_consistent()

bool libMesh::MeshRefinement::make_flags_parallel_consistent ( )

Copy refinement flags on ghost elements from their local processors.

Returns
true if any flags changed.

Definition at line 749 of file mesh_refinement.C.

References _mesh, libMesh::ParallelObject::comm(), TIMPI::Communicator::min(), libMesh::Elem::p_refinement_flag(), libMesh::SyncRefinementFlags::parallel_consistent, libMesh::Elem::refinement_flag(), libMesh::Elem::set_p_refinement_flag(), libMesh::Elem::set_refinement_flag(), and libMesh::Parallel::sync_dofobject_data_by_id().

Referenced by _smooth_flags(), coarsen_elements(), refine_and_coarsen_elements(), refine_elements(), and libMesh::HPCoarsenTest::select_refinement().

750 {
751  // This function must be run on all processors at once
752  parallel_object_only();
753 
754  LOG_SCOPE ("make_flags_parallel_consistent()", "MeshRefinement");
755 
756  SyncRefinementFlags hsync(_mesh, &Elem::refinement_flag,
759  (this->comm(), _mesh.elements_begin(), _mesh.elements_end(), hsync);
760 
761  SyncRefinementFlags psync(_mesh, &Elem::p_refinement_flag,
764  (this->comm(), _mesh.elements_begin(), _mesh.elements_end(), psync);
765 
766  // If we weren't consistent in both h and p on every processor then
767  // we weren't globally consistent
768  bool parallel_consistent = hsync.parallel_consistent &&
769  psync.parallel_consistent;
770  this->comm().min(parallel_consistent);
771 
772  return parallel_consistent;
773 }
RefinementState refinement_flag() const
Definition: elem.h:3210
MeshBase & _mesh
Reference to the mesh.
RefinementState p_refinement_flag() const
Definition: elem.h:3226
void set_refinement_flag(const RefinementState rflag)
Sets the value of the refinement flag for the element.
Definition: elem.h:3218
const Parallel::Communicator & comm() const
void min(const T &r, T &o, Request &req) const
void sync_dofobject_data_by_id(const Communicator &comm, const Iterator &range_begin, const Iterator &range_end, SyncFunctor &sync)
Request data about a range of ghost dofobjects uniquely identified by their id.
void set_p_refinement_flag(const RefinementState pflag)
Sets the value of the p-refinement flag for the element.
Definition: elem.h:3234

◆ make_refinement_compatible()

bool libMesh::MeshRefinement::make_refinement_compatible ( )
private

Take user-specified refinement flags and augment them so that level-one dependency is satisfied.

This function used to take an argument, maintain_level_one - new code should use face_level_mismatch_limit() instead.

Definition at line 1157 of file mesh_refinement.C.

References _face_level_mismatch_limit, _mesh, _periodic_boundaries, libMesh::Elem::active(), libMesh::Elem::child_ref_range(), libMesh::Elem::COARSEN, libMesh::ParallelObject::comm(), libMesh::Elem::DO_NOTHING, libMesh::Elem::has_children(), has_topological_neighbor(), libMesh::Elem::INACTIVE, libMesh::Elem::level(), libMesh::libmesh_assert(), TIMPI::Communicator::min(), libMesh::Elem::p_level(), libMesh::Elem::p_refinement_flag(), libMesh::Elem::parent(), libMesh::Elem::REFINE, libMesh::Elem::refinement_flag(), libMesh::remote_elem, libMesh::Elem::set_p_refinement_flag(), libMesh::Elem::set_refinement_flag(), libMesh::MeshBase::sub_point_locator(), and topological_neighbor().

Referenced by _smooth_flags(), refine_and_coarsen_elements(), and refine_elements().

1158 {
1159  // This function must be run on all processors at once
1160  parallel_object_only();
1161 
1162  // We may need a PointLocator for topological_neighbor() tests
1163  // later, which we need to make sure gets constructed on all
1164  // processors at once.
1165  std::unique_ptr<PointLocatorBase> point_locator;
1166 
1167 #ifdef LIBMESH_ENABLE_PERIODIC
1168  bool has_periodic_boundaries =
1170  libmesh_assert(this->comm().verify(has_periodic_boundaries));
1171 
1172  if (has_periodic_boundaries)
1173  point_locator = _mesh.sub_point_locator();
1174 #endif
1175 
1176  LOG_SCOPE ("make_refinement_compatible()", "MeshRefinement");
1177 
1178  // Unless we encounter a specific situation we will be compatible
1179  // with any selected coarsening flags
1180  bool compatible_with_coarsening = true;
1181 
1182  // This loop enforces the level-1 rule. We should only
1183  // execute it if the user indeed wants level-1 satisfied!
1185  {
1186  // Unless we encounter a specific situation level-one
1187  // will be satisfied after executing this loop just once
1188  bool level_one_satisfied = true;
1189 
1190  do
1191  {
1192  level_one_satisfied = true;
1193 
1194  for (auto & elem : _mesh.active_element_ptr_range())
1195  {
1196  const unsigned short n_sides = elem->n_sides();
1197 
1198  if (elem->refinement_flag() == Elem::REFINE) // If the element is active and the
1199  // h refinement flag is set
1200  {
1201  const unsigned int my_level = elem->level();
1202 
1203  for (unsigned short side = 0; side != n_sides;
1204  ++side)
1205  {
1206  Elem * neighbor =
1207  topological_neighbor(elem, point_locator.get(), side);
1208 
1209  if (neighbor != nullptr && // I have a
1210  neighbor != remote_elem && // neighbor here
1211  neighbor->active()) // and it is active
1212  {
1213  // Case 1: The neighbor is at the same level I am.
1214  // 1a: The neighbor will be refined -> NO PROBLEM
1215  // 1b: The neighbor won't be refined -> NO PROBLEM
1216  // 1c: The neighbor wants to be coarsened -> PROBLEM
1217  if (neighbor->level() == my_level)
1218  {
1219  if (neighbor->refinement_flag() == Elem::COARSEN)
1220  {
1222  if (neighbor->parent())
1223  neighbor->parent()->set_refinement_flag(Elem::INACTIVE);
1224  compatible_with_coarsening = false;
1225  level_one_satisfied = false;
1226  }
1227  }
1228 
1229 
1230  // Case 2: The neighbor is one level lower than I am.
1231  // The neighbor thus MUST be refined to satisfy
1232  // the level-one rule, regardless of whether it
1233  // was originally flagged for refinement. If it
1234  // wasn't flagged already we need to repeat
1235  // this process.
1236  else if ((neighbor->level()+1) == my_level)
1237  {
1238  if (neighbor->refinement_flag() != Elem::REFINE)
1239  {
1240  neighbor->set_refinement_flag(Elem::REFINE);
1241  if (neighbor->parent())
1242  neighbor->parent()->set_refinement_flag(Elem::INACTIVE);
1243  compatible_with_coarsening = false;
1244  level_one_satisfied = false;
1245  }
1246  }
1247 #ifdef DEBUG
1248  // Note that the only other possibility is that the
1249  // neighbor is already refined, in which case it isn't
1250  // active and we should never get here.
1251  else
1252  libmesh_error_msg("ERROR: Neighbor level must be equal or 1 higher than mine.");
1253 #endif
1254  }
1255  }
1256  }
1257  if (elem->p_refinement_flag() == Elem::REFINE) // If the element is active and the
1258  // p refinement flag is set
1259  {
1260  const unsigned int my_p_level = elem->p_level();
1261 
1262  for (unsigned int side=0; side != n_sides; side++)
1263  {
1264  Elem * neighbor =
1265  topological_neighbor(elem, point_locator.get(), side);
1266 
1267  if (neighbor != nullptr && // I have a
1268  neighbor != remote_elem) // neighbor here
1269  {
1270  if (neighbor->active()) // and it is active
1271  {
1272  if (neighbor->p_level() < my_p_level &&
1273  neighbor->p_refinement_flag() != Elem::REFINE)
1274  {
1276  level_one_satisfied = false;
1277  compatible_with_coarsening = false;
1278  }
1279  if (neighbor->p_level() == my_p_level &&
1280  neighbor->p_refinement_flag() == Elem::COARSEN)
1281  {
1282  neighbor->set_p_refinement_flag(Elem::DO_NOTHING);
1283  level_one_satisfied = false;
1284  compatible_with_coarsening = false;
1285  }
1286  }
1287  else // I have an inactive neighbor
1288  {
1289  libmesh_assert(neighbor->has_children());
1290  for (auto & subneighbor : neighbor->child_ref_range())
1291  if (&subneighbor != remote_elem && subneighbor.active() &&
1292  has_topological_neighbor(&subneighbor, point_locator.get(), elem))
1293  {
1294  if (subneighbor.p_level() < my_p_level &&
1295  subneighbor.p_refinement_flag() != Elem::REFINE)
1296  {
1297  // We should already be level one
1298  // compatible
1299  libmesh_assert_greater (subneighbor.p_level() + 2u,
1300  my_p_level);
1301  subneighbor.set_p_refinement_flag(Elem::REFINE);
1302  level_one_satisfied = false;
1303  compatible_with_coarsening = false;
1304  }
1305  if (subneighbor.p_level() == my_p_level &&
1306  subneighbor.p_refinement_flag() == Elem::COARSEN)
1307  {
1308  subneighbor.set_p_refinement_flag(Elem::DO_NOTHING);
1309  level_one_satisfied = false;
1310  compatible_with_coarsening = false;
1311  }
1312  }
1313  }
1314  }
1315  }
1316  }
1317  }
1318  }
1319 
1320  while (!level_one_satisfied);
1321  } // end if (_face_level_mismatch_limit)
1322 
1323  // If we're not compatible on one processor, we're globally not
1324  // compatible
1325  this->comm().min(compatible_with_coarsening);
1326 
1327  return compatible_with_coarsening;
1328 }
std::unique_ptr< PointLocatorBase > sub_point_locator() const
Definition: mesh_base.C:1675
bool has_topological_neighbor(const Elem *elem, const PointLocatorBase *point_locator, const Elem *neighbor) const
Local dispatch function for checking the correct has_neighbor function from the Elem class...
MeshBase & _mesh
Reference to the mesh.
void set_refinement_flag(const RefinementState rflag)
Sets the value of the refinement flag for the element.
Definition: elem.h:3218
const Parallel::Communicator & comm() const
PeriodicBoundaries * _periodic_boundaries
void min(const T &r, T &o, Request &req) const
unsigned char _face_level_mismatch_limit
libmesh_assert(ctx)
Elem * topological_neighbor(Elem *elem, const PointLocatorBase *point_locator, const unsigned int side) const
Local dispatch function for getting the correct topological neighbor from the Elem class...
void set_p_refinement_flag(const RefinementState pflag)
Sets the value of the p-refinement flag for the element.
Definition: elem.h:3234
bool active() const
Definition: elem.h:2941
const RemoteElem * remote_elem
Definition: remote_elem.C:57

◆ max_h_level()

unsigned int & libMesh::MeshRefinement::max_h_level ( )
inline

The max_h_level is the greatest refinement level an element should reach.

max_h_level is unlimited (libMesh::invalid_uint) by default

Definition at line 918 of file mesh_refinement.h.

References _max_h_level, and _use_member_parameters.

Referenced by assemble_and_solve(), and main().

919 {
920  _use_member_parameters = true;
921  return _max_h_level;
922 }
bool _use_member_parameters
For backwards compatibility, we initialize this as false and then set it to true if the user uses any...

◆ n_processors()

processor_id_type libMesh::ParallelObject::n_processors ( ) const
inlineinherited
Returns
The number of processors in the group.

Definition at line 103 of file parallel_object.h.

References libMesh::ParallelObject::_communicator, libMesh::libmesh_assert(), and TIMPI::Communicator::size().

Referenced by libMesh::Partitioner::_find_global_index_by_pid_map(), libMesh::BoundaryInfo::_find_id_maps(), libMesh::DofMap::add_constraints_to_send_list(), libMesh::PetscDMWrapper::add_dofs_to_section(), libMesh::DistributedMesh::add_elem(), libMesh::DofMap::add_neighbors_to_send_list(), libMesh::DistributedMesh::add_node(), libMesh::System::add_vector(), libMesh::LaplaceMeshSmoother::allgather_graph(), libMesh::DofMap::allgather_recursive_constraints(), libMesh::FEMSystem::assembly(), libMesh::Nemesis_IO::assert_symmetric_cmaps(), libMesh::Partitioner::assign_partitioning(), libMesh::AztecLinearSolver< T >::AztecLinearSolver(), libMesh::Partitioner::build_graph(), libMesh::EquationSystems::build_parallel_elemental_solution_vector(), libMesh::DistributedMesh::clear(), libMesh::DistributedMesh::clear_elems(), libMesh::Nemesis_IO_Helper::compute_border_node_ids(), libMesh::Nemesis_IO_Helper::construct_nemesis_filename(), libMesh::UnstructuredMesh::copy_nodes_and_elements(), libMesh::ExodusII_IO::copy_scalar_solution(), libMesh::Nemesis_IO::copy_scalar_solution(), libMesh::UnstructuredMesh::create_pid_mesh(), libMesh::MeshTools::create_processor_bounding_box(), libMesh::DofMap::distribute_dofs(), libMesh::DofMap::distribute_scalar_dofs(), libMesh::DistributedMesh::DistributedMesh(), libMesh::EnsightIO::EnsightIO(), libMesh::RBEIMEvaluation::gather_bfs(), libMesh::MeshBase::get_info(), libMesh::StaticCondensation::init(), libMesh::SystemSubsetBySubdomain::init(), libMesh::PetscDMWrapper::init_petscdm(), libMesh::Nemesis_IO_Helper::initialize(), libMesh::ExodusII_IO_Helper::initialize(), libMesh::DistributedMesh::insert_elem(), libMesh::MeshTools::libmesh_assert_contiguous_dof_ids(), libMesh::MeshTools::libmesh_assert_parallel_consistent_new_node_procids(), libMesh::MeshTools::libmesh_assert_parallel_consistent_procids< Elem >(), libMesh::MeshTools::libmesh_assert_parallel_consistent_procids< Node >(), libMesh::MeshTools::libmesh_assert_topology_consistent_procids< Node >(), libMesh::MeshTools::libmesh_assert_valid_boundary_ids(), libMesh::MeshTools::libmesh_assert_valid_dof_ids(), libMesh::MeshTools::libmesh_assert_valid_neighbors(), libMesh::MeshTools::libmesh_assert_valid_refinement_flags(), libMesh::DofMap::local_variable_indices(), make_coarsening_compatible(), libMesh::MeshBase::n_active_elem_on_proc(), libMesh::DofMap::n_dofs_per_processor(), libMesh::MeshBase::n_elem_on_proc(), libMesh::MeshBase::n_nodes_on_proc(), libMesh::RBEIMEvaluation::node_gather_bfs(), libMesh::Partitioner::partition(), libMesh::MeshBase::partition(), libMesh::Partitioner::partition_unpartitioned_elements(), libMesh::System::point_gradient(), libMesh::System::point_hessian(), libMesh::System::point_value(), libMesh::DofMap::prepare_send_list(), libMesh::MeshBase::print_constraint_rows(), libMesh::DofMap::print_dof_constraints(), libMesh::NameBasedIO::read(), libMesh::Nemesis_IO::read(), libMesh::CheckpointIO::read(), libMesh::CheckpointIO::read_connectivity(), libMesh::XdrIO::read_header(), libMesh::CheckpointIO::read_nodes(), libMesh::System::read_parallel_data(), libMesh::System::read_SCALAR_dofs(), libMesh::System::read_serialized_blocked_dof_objects(), libMesh::System::read_serialized_vector(), libMesh::DistributedMesh::renumber_dof_objects(), libMesh::Partitioner::repartition(), OverlappingFunctorTest::run_partitioner_test(), libMesh::DofMap::scatter_constraints(), libMesh::DistributedMesh::set_next_unique_id(), libMesh::DofMap::set_nonlocal_dof_objects(), libMesh::PetscDMWrapper::set_point_range_in_section(), WriteVecAndScalar::setupTests(), libMesh::RBEIMEvaluation::side_gather_bfs(), DistributedMeshTest::testRemoteElemError(), CheckpointIOTest::testSplitter(), uniformly_coarsen(), libMesh::DistributedMesh::update_parallel_id_counts(), libMesh::GMVIO::write_binary(), libMesh::GMVIO::write_discontinuous_gmv(), libMesh::ExodusII_IO_Helper::write_nodal_coordinates(), libMesh::VTKIO::write_nodal_data(), libMesh::ExodusII_IO::write_nodal_data(), libMesh::System::write_parallel_data(), libMesh::System::write_SCALAR_dofs(), libMesh::XdrIO::write_serialized_bcs_helper(), libMesh::System::write_serialized_blocked_dof_objects(), libMesh::XdrIO::write_serialized_connectivity(), libMesh::XdrIO::write_serialized_nodes(), and libMesh::XdrIO::write_serialized_nodesets().

104  {
105  processor_id_type returnval =
106  cast_int<processor_id_type>(_communicator.size());
107  libmesh_assert(returnval); // We never have an empty comm
108  return returnval;
109  }
const Parallel::Communicator & _communicator
processor_id_type size() const
uint8_t processor_id_type
libmesh_assert(ctx)

◆ nelem_target()

dof_id_type & libMesh::MeshRefinement::nelem_target ( )
inline

If nelem_target is set to a nonzero value, methods like flag_elements_by_nelem_target() will attempt to keep the number of active elements in the mesh close to nelem_target.

nelem_target is 0 by default.

Definition at line 930 of file mesh_refinement.h.

References _nelem_target, and _use_member_parameters.

Referenced by main().

931 {
932  _use_member_parameters = true;
933  return _nelem_target;
934 }
bool _use_member_parameters
For backwards compatibility, we initialize this as false and then set it to true if the user uses any...

◆ node_level_mismatch_limit()

unsigned char & libMesh::MeshRefinement::node_level_mismatch_limit ( )
inline

If node_level_mismatch_limit is set to a nonzero value, then refinement and coarsening will produce meshes in which the refinement level of two nodal neighbors will not differ by more than that limit.

If node_level_mismatch_limit is 0, then level differences will be unlimited.

node_level_mismatch_limit is 0 by default.

Definition at line 952 of file mesh_refinement.h.

References _node_level_mismatch_limit.

953 {
955 }
unsigned char _node_level_mismatch_limit

◆ operator=()

MeshRefinement& libMesh::MeshRefinement::operator= ( const MeshRefinement )
private

◆ overrefined_boundary_limit()

signed char & libMesh::MeshRefinement::overrefined_boundary_limit ( )
inline

If overrefined_boundary_limit is set to a nonnegative value, then refinement and coarsening will produce meshes in which the refinement level of a boundary element is no more than that many levels greater than the level of any of its interior neighbors.

This may be counter-intuitive in the 1D-embedded-in-3D case: an edge has more interior neighbors than a face containing that edge.

If overrefined_boundary_limit is negative, then level differences will be unlimited.

overrefined_boundary_limit is 0 by default. This implies that adaptive coarsening can only be done on an interior element if any boundary elements on its sides are simultaneously coarsened.

Definition at line 957 of file mesh_refinement.h.

References _overrefined_boundary_limit.

Referenced by libMesh::EquationSystems::reinit_solutions().

958 {
960 }
signed char _overrefined_boundary_limit

◆ processor_id()

processor_id_type libMesh::ParallelObject::processor_id ( ) const
inlineinherited
Returns
The rank of this processor in the group.

Definition at line 114 of file parallel_object.h.

References libMesh::ParallelObject::_communicator, and TIMPI::Communicator::rank().

Referenced by libMesh::BoundaryInfo::_find_id_maps(), libMesh::PetscDMWrapper::add_dofs_to_section(), libMesh::DistributedMesh::add_elem(), libMesh::BoundaryInfo::add_elements(), libMesh::DofMap::add_neighbors_to_send_list(), libMesh::DistributedMesh::add_node(), libMesh::MeshTools::Modification::all_tri(), libMesh::DofMap::allgather_recursive_constraints(), libMesh::FEMSystem::assembly(), libMesh::Nemesis_IO::assert_symmetric_cmaps(), libMesh::Partitioner::assign_partitioning(), libMesh::Nemesis_IO_Helper::build_element_and_node_maps(), libMesh::Partitioner::build_graph(), libMesh::InfElemBuilder::build_inf_elem(), libMesh::BoundaryInfo::build_node_list_from_side_list(), libMesh::EquationSystems::build_parallel_elemental_solution_vector(), libMesh::EquationSystems::build_parallel_solution_vector(), libMesh::MeshFunction::check_found_elem(), libMesh::DistributedMesh::clear(), libMesh::DistributedMesh::clear_elems(), libMesh::ExodusII_IO_Helper::close(), libMesh::Nemesis_IO_Helper::compute_border_node_ids(), libMesh::Nemesis_IO_Helper::compute_communication_map_parameters(), libMesh::Nemesis_IO_Helper::compute_internal_and_border_elems_and_internal_nodes(), libMesh::RBConstruction::compute_max_error_bound(), libMesh::Nemesis_IO_Helper::compute_node_communication_maps(), libMesh::Nemesis_IO_Helper::compute_num_global_elem_blocks(), libMesh::Nemesis_IO_Helper::compute_num_global_nodesets(), libMesh::Nemesis_IO_Helper::compute_num_global_sidesets(), libMesh::Nemesis_IO_Helper::construct_nemesis_filename(), libMesh::ExodusII_IO::copy_elemental_solution(), libMesh::ExodusII_IO::copy_nodal_solution(), libMesh::ExodusII_IO::copy_scalar_solution(), libMesh::Nemesis_IO::copy_scalar_solution(), libMesh::MeshTools::correct_node_proc_ids(), libMesh::ExodusII_IO_Helper::create(), libMesh::DistributedMesh::delete_elem(), libMesh::MeshCommunication::delete_remote_elements(), libMesh::DofMap::distribute_dofs(), libMesh::DofMap::distribute_scalar_dofs(), libMesh::DistributedMesh::DistributedMesh(), libMesh::DofMapBase::end_dof(), libMesh::DofMapBase::end_old_dof(), libMesh::EnsightIO::EnsightIO(), libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::SubFunctor::find_dofs_to_send(), libMesh::UnstructuredMesh::find_neighbors(), libMesh::DofMapBase::first_dof(), libMesh::DofMapBase::first_old_dof(), libMesh::RBEIMEvaluation::gather_bfs(), libMesh::Nemesis_IO_Helper::get_cmap_params(), libMesh::Nemesis_IO_Helper::get_eb_info_global(), libMesh::Nemesis_IO_Helper::get_elem_cmap(), libMesh::Nemesis_IO_Helper::get_elem_map(), libMesh::MeshBase::get_info(), libMesh::DofMap::get_info(), libMesh::Nemesis_IO_Helper::get_init_global(), libMesh::Nemesis_IO_Helper::get_init_info(), libMesh::RBEIMEvaluation::get_interior_basis_functions_as_vecs(), libMesh::Nemesis_IO_Helper::get_loadbal_param(), libMesh::DofMap::get_local_constraints(), libMesh::MeshBase::get_local_constraints(), libMesh::Nemesis_IO_Helper::get_node_cmap(), libMesh::Nemesis_IO_Helper::get_node_map(), libMesh::Nemesis_IO_Helper::get_ns_param_global(), libMesh::Nemesis_IO_Helper::get_ss_param_global(), libMesh::SparsityPattern::Build::handle_vi_vj(), libMesh::LaplaceMeshSmoother::init(), libMesh::SystemSubsetBySubdomain::init(), HeatSystem::init_data(), libMesh::ExodusII_IO_Helper::initialize(), libMesh::ExodusII_IO_Helper::initialize_element_variables(), libMesh::ExodusII_IO_Helper::initialize_global_variables(), libMesh::ExodusII_IO_Helper::initialize_nodal_variables(), libMesh::DistributedMesh::insert_elem(), libMesh::DofMap::is_evaluable(), libMesh::SparsityPattern::Build::join(), libMesh::TransientRBEvaluation::legacy_write_offline_data_to_files(), libMesh::RBSCMEvaluation::legacy_write_offline_data_to_files(), libMesh::RBEvaluation::legacy_write_offline_data_to_files(), libMesh::MeshTools::libmesh_assert_consistent_distributed(), libMesh::MeshTools::libmesh_assert_consistent_distributed_nodes(), libMesh::MeshTools::libmesh_assert_contiguous_dof_ids(), libMesh::MeshTools::libmesh_assert_parallel_consistent_procids< Elem >(), libMesh::MeshTools::libmesh_assert_valid_neighbors(), libMesh::DistributedMesh::libmesh_assert_valid_parallel_object_ids(), libMesh::DofMap::local_variable_indices(), main(), make_coarsening_compatible(), AugmentSparsityOnInterface::mesh_reinit(), libMesh::TriangulatorInterface::MeshedHole::MeshedHole(), libMesh::MeshBase::n_active_local_elem(), libMesh::BoundaryInfo::n_boundary_conds(), libMesh::MeshTools::n_connected_components(), libMesh::MeshBase::n_constraint_rows(), libMesh::BoundaryInfo::n_edge_conds(), libMesh::DofMapBase::n_local_dofs(), libMesh::MeshBase::n_local_elem(), libMesh::MeshBase::n_local_nodes(), libMesh::BoundaryInfo::n_nodeset_conds(), libMesh::BoundaryInfo::n_shellface_conds(), libMesh::RBEIMEvaluation::node_gather_bfs(), libMesh::DistributedMesh::own_node(), libMesh::BoundaryInfo::parallel_sync_node_ids(), libMesh::BoundaryInfo::parallel_sync_side_ids(), libMesh::System::point_gradient(), libMesh::System::point_hessian(), libMesh::System::point_value(), libMesh::MeshBase::print_constraint_rows(), libMesh::DofMap::print_dof_constraints(), libMesh::DofMap::process_mesh_constraint_rows(), libMesh::Nemesis_IO_Helper::put_cmap_params(), libMesh::Nemesis_IO_Helper::put_elem_cmap(), libMesh::Nemesis_IO_Helper::put_elem_map(), libMesh::Nemesis_IO_Helper::put_loadbal_param(), libMesh::Nemesis_IO_Helper::put_node_cmap(), libMesh::Nemesis_IO_Helper::put_node_map(), libMesh::NameBasedIO::read(), libMesh::Nemesis_IO::read(), libMesh::XdrIO::read(), libMesh::CheckpointIO::read(), libMesh::EquationSystems::read(), libMesh::ExodusII_IO_Helper::read_elem_num_map(), libMesh::ExodusII_IO_Helper::read_global_values(), libMesh::ExodusII_IO::read_header(), libMesh::CheckpointIO::read_header(), libMesh::XdrIO::read_header(), libMesh::System::read_header(), libMesh::System::read_legacy_data(), libMesh::DynaIO::read_mesh(), libMesh::ExodusII_IO_Helper::read_node_num_map(), libMesh::System::read_parallel_data(), libMesh::TransientRBConstruction::read_riesz_representors_from_files(), libMesh::RBConstruction::read_riesz_representors_from_files(), libMesh::System::read_SCALAR_dofs(), libMesh::XdrIO::read_serialized_bc_names(), libMesh::XdrIO::read_serialized_bcs_helper(), libMesh::System::read_serialized_blocked_dof_objects(), libMesh::XdrIO::read_serialized_connectivity(), libMesh::System::read_serialized_data(), libMesh::XdrIO::read_serialized_nodes(), libMesh::XdrIO::read_serialized_nodesets(), libMesh::XdrIO::read_serialized_subdomain_names(), libMesh::System::read_serialized_vector(), libMesh::System::read_serialized_vectors(), libMesh::Nemesis_IO_Helper::read_var_names_impl(), libMesh::SimplexRefiner::refine_via_edges(), libMesh::StaticCondensationDofMap::reinit(), libMesh::DistributedMesh::renumber_dof_objects(), libMesh::DistributedMesh::renumber_nodes_and_elements(), libMesh::DofMap::scatter_constraints(), libMesh::CheckpointIO::select_split_config(), libMesh::DistributedMesh::set_next_unique_id(), libMesh::DofMap::set_nonlocal_dof_objects(), libMesh::PetscDMWrapper::set_point_range_in_section(), libMesh::RBEIMEvaluation::side_gather_bfs(), ExodusTest< elem_type >::test_read_gold(), ExodusTest< elem_type >::test_write(), MeshInputTest::testAbaqusRead(), MeshInputTest::testBadGmsh(), MeshInputTest::testCopyElementSolutionImpl(), MeshInputTest::testCopyElementVectorImpl(), MeshInputTest::testCopyNodalSolutionImpl(), DefaultCouplingTest::testCoupling(), PointNeighborCouplingTest::testCoupling(), MeshInputTest::testDynaFileMappings(), MeshInputTest::testDynaNoSplines(), MeshInputTest::testDynaReadElem(), MeshInputTest::testDynaReadPatch(), MeshInputTest::testExodusFileMappings(), MeshInputTest::testExodusIGASidesets(), MeshInputTest::testExodusWriteElementDataFromDiscontinuousNodalData(), MeshInputTest::testGmshBCIDOverlap(), MeshInputTest::testGoodGmsh(), MeshInputTest::testGoodSTL(), MeshInputTest::testGoodSTLBinary(), MeshInputTest::testLowOrderEdgeBlocks(), SystemsTest::testProjectMatrix3D(), BoundaryInfoTest::testShellFaceConstraints(), MeshInputTest::testSingleElementImpl(), WriteVecAndScalar::testSolution(), CheckpointIOTest::testSplitter(), MeshInputTest::testTetgenIO(), libMesh::MeshTools::total_weight(), libMesh::NetGenMeshInterface::triangulate(), uniformly_coarsen(), libMesh::DistributedMesh::update_parallel_id_counts(), libMesh::DTKAdapter::update_variable_values(), libMesh::MeshTools::volume(), libMesh::STLIO::write(), libMesh::NameBasedIO::write(), libMesh::XdrIO::write(), libMesh::CheckpointIO::write(), libMesh::EquationSystems::write(), libMesh::GMVIO::write_discontinuous_gmv(), libMesh::ExodusII_IO::write_element_data(), libMesh::ExodusII_IO_Helper::write_element_values(), libMesh::ExodusII_IO_Helper::write_element_values_element_major(), libMesh::ExodusII_IO_Helper::write_elements(), libMesh::ExodusII_IO_Helper::write_elemset_data(), libMesh::ExodusII_IO_Helper::write_elemsets(), libMesh::ExodusII_IO::write_global_data(), libMesh::ExodusII_IO_Helper::write_global_values(), libMesh::System::write_header(), libMesh::ExodusII_IO::write_information_records(), libMesh::ExodusII_IO_Helper::write_information_records(), libMesh::ExodusII_IO_Helper::write_nodal_coordinates(), libMesh::UCDIO::write_nodal_data(), libMesh::VTKIO::write_nodal_data(), libMesh::ExodusII_IO::write_nodal_data(), libMesh::ExodusII_IO::write_nodal_data_common(), libMesh::ExodusII_IO::write_nodal_data_discontinuous(), libMesh::ExodusII_IO_Helper::write_nodal_values(), libMesh::ExodusII_IO_Helper::write_nodeset_data(), libMesh::Nemesis_IO_Helper::write_nodesets(), libMesh::ExodusII_IO_Helper::write_nodesets(), libMesh::RBEIMEvaluation::write_out_interior_basis_functions(), libMesh::RBEIMEvaluation::write_out_node_basis_functions(), libMesh::RBEIMEvaluation::write_out_side_basis_functions(), write_output_solvedata(), libMesh::System::write_parallel_data(), libMesh::RBConstruction::write_riesz_representors_to_files(), libMesh::System::write_SCALAR_dofs(), libMesh::XdrIO::write_serialized_bc_names(), libMesh::XdrIO::write_serialized_bcs_helper(), libMesh::System::write_serialized_blocked_dof_objects(), libMesh::XdrIO::write_serialized_connectivity(), libMesh::System::write_serialized_data(), libMesh::XdrIO::write_serialized_nodes(), libMesh::XdrIO::write_serialized_nodesets(), libMesh::XdrIO::write_serialized_subdomain_names(), libMesh::System::write_serialized_vector(), libMesh::System::write_serialized_vectors(), libMesh::ExodusII_IO_Helper::write_sideset_data(), libMesh::Nemesis_IO_Helper::write_sidesets(), libMesh::ExodusII_IO_Helper::write_sidesets(), libMesh::ExodusII_IO::write_timestep(), libMesh::ExodusII_IO_Helper::write_timestep(), and libMesh::ExodusII_IO::write_timestep_discontinuous().

115  { return cast_int<processor_id_type>(_communicator.rank()); }
processor_id_type rank() const
const Parallel::Communicator & _communicator

◆ refine_and_coarsen_elements()

bool libMesh::MeshRefinement::refine_and_coarsen_elements ( )

Refines and coarsens user-requested elements.

Will also refine/coarsen additional elements to satisfy level-one rule. It is possible that for a given set of refinement flags there is actually no change upon calling this member function.

Returns
true if the mesh actually changed (hence data needs to be projected) and false otherwise.
Note
This function used to take an argument, maintain_level_one. New code should use face_level_mismatch_limit() instead.

Definition at line 476 of file mesh_refinement.C.

References _coarsen_elements(), _face_level_mismatch_limit, _mesh, _refine_elements(), _smooth_flags(), libMesh::Elem::COARSEN, libMesh::ParallelObject::comm(), libMesh::Elem::DO_NOTHING, libMesh::Elem::INACTIVE, libMesh::Elem::JUST_REFINED, libMesh::libmesh_assert(), libMesh::MeshBase::libmesh_assert_valid_parallel_ids(), make_coarsening_compatible(), make_flags_parallel_consistent(), make_refinement_compatible(), TIMPI::Communicator::max(), libMesh::MeshBase::prepare_for_use(), libMesh::Elem::REFINE, test_level_one(), and test_unflagged().

Referenced by assemble_and_solve(), MixedDimensionNonUniformRefinement::build_mesh(), MixedDimensionNonUniformRefinementTriangle::build_mesh(), MixedDimensionNonUniformRefinement3D::build_mesh(), and main().

477 {
478  // This function must be run on all processors at once
479  parallel_object_only();
480 
481  // We can't yet turn a non-level-one mesh into a level-one mesh
484 
485  // Possibly clean up the refinement flags from
486  // a previous step. While we're at it, see if this method should be
487  // a no-op.
488  bool elements_flagged = false;
489 
490  for (auto & elem : _mesh.element_ptr_range())
491  {
492  // This might be left over from the last step
493  const Elem::RefinementState flag = elem->refinement_flag();
494 
495  // Set refinement flag to INACTIVE if the
496  // element isn't active
497  if ( !elem->active())
498  {
499  elem->set_refinement_flag(Elem::INACTIVE);
500  elem->set_p_refinement_flag(Elem::INACTIVE);
501  }
502  else if (flag == Elem::JUST_REFINED)
503  elem->set_refinement_flag(Elem::DO_NOTHING);
504  else if (!elements_flagged)
505  {
506  if (flag == Elem::REFINE || flag == Elem::COARSEN)
507  elements_flagged = true;
508  else
509  {
510  const Elem::RefinementState pflag =
511  elem->p_refinement_flag();
512  if (pflag == Elem::REFINE || pflag == Elem::COARSEN)
513  elements_flagged = true;
514  }
515  }
516  }
517 
518  // Did *any* processor find elements flagged for AMR/C?
519  _mesh.comm().max(elements_flagged);
520 
521  // If we have nothing to do, let's not bother verifying that nothing
522  // is compatible with nothing.
523  if (!elements_flagged)
524  return false;
525 
526  // Parallel consistency has to come first, or coarsening
527  // along processor boundaries might occasionally be falsely
528  // prevented
529 #ifdef DEBUG
530  bool flags_were_consistent = this->make_flags_parallel_consistent();
531 
532  libmesh_assert (flags_were_consistent);
533 #endif
534 
535  // Smooth refinement and coarsening flags
536  _smooth_flags(true, true);
537 
538  // First coarsen the flagged elements.
539  const bool coarsening_changed_mesh =
540  this->_coarsen_elements ();
541 
542  // First coarsen the flagged elements.
543  // FIXME: test_level_one now tests consistency across periodic
544  // boundaries, which requires a point_locator, which just got
545  // invalidated by _coarsen_elements() and hasn't yet been cleared by
546  // prepare_for_use().
547 
548  // libmesh_assert(this->make_coarsening_compatible());
549  // libmesh_assert(this->make_refinement_compatible());
550 
551  // FIXME: This won't pass unless we add a redundant find_neighbors()
552  // call or replace find_neighbors() with on-the-fly neighbor updating
553  // libmesh_assert(!this->eliminate_unrefined_patches());
554 
555  // We can't contract the mesh ourselves anymore - a System might
556  // need to restrict old coefficient vectors first
557  // _mesh.contract();
558 
559  // First coarsen the flagged elements.
560  // Now refine the flagged elements. This will
561  // take up some space, maybe more than what was freed.
562  const bool refining_changed_mesh =
563  this->_refine_elements();
564 
565  // First coarsen the flagged elements.
566  // Finally, the new mesh needs to be prepared for use
567  if (coarsening_changed_mesh || refining_changed_mesh)
568  {
569 #ifdef DEBUG
571 #endif
572 
574 
580  // FIXME: This won't pass unless we add a redundant find_neighbors()
581  // call or replace find_neighbors() with on-the-fly neighbor updating
582  // libmesh_assert(!this->eliminate_unrefined_patches());
583 
584  return true;
585  }
586  else
587  {
593  }
594 
595  // Otherwise there was no change in the mesh,
596  // let the user know. Also, there is no need
597  // to prepare the mesh for use since it did not change.
598  return false;
599 
600 }
bool _refine_elements()
Refines user-requested elements.
bool test_level_one(bool libmesh_assert_yes=false) const
MeshBase & _mesh
Reference to the mesh.
void prepare_for_use(const bool skip_renumber_nodes_and_elements, const bool skip_find_neighbors)
Prepare a newly ecreated (or read) mesh for use.
Definition: mesh_base.C:759
RefinementState
Enumeration of possible element refinement states.
Definition: elem.h:1452
const Parallel::Communicator & comm() const
bool make_refinement_compatible()
Take user-specified refinement flags and augment them so that level-one dependency is satisfied...
unsigned char _face_level_mismatch_limit
libmesh_assert(ctx)
bool test_unflagged(bool libmesh_assert_yes=false) const
bool make_flags_parallel_consistent()
Copy refinement flags on ghost elements from their local processors.
bool make_coarsening_compatible()
Take user-specified coarsening flags and augment them so that level-one dependency is satisfied...
void max(const T &r, T &o, Request &req) const
void _smooth_flags(bool refining, bool coarsening)
Smooths refinement flags according to current settings.
virtual void libmesh_assert_valid_parallel_ids() const
Verify id and processor_id consistency of our elements and nodes containers.
Definition: mesh_base.h:1522
bool _coarsen_elements()
Coarsens user-requested elements.

◆ refine_elements()

bool libMesh::MeshRefinement::refine_elements ( )

Only refines the user-requested elements.

It is possible that for a given set of refinement flags there is actually no change upon calling this member function.

Returns
true if the mesh actually changed (hence data needs to be projected) and false otherwise.
Note
This function used to take an argument, maintain_level_one, new code should use face_level_mismatch_limit() instead.

Definition at line 682 of file mesh_refinement.C.

References _face_level_mismatch_limit, _mesh, _refine_elements(), _smooth_flags(), libMesh::Elem::DO_NOTHING, libMesh::Elem::INACTIVE, libMesh::Elem::JUST_REFINED, libMesh::libmesh_assert(), make_flags_parallel_consistent(), make_refinement_compatible(), libMesh::MeshBase::prepare_for_use(), and test_level_one().

Referenced by main(), libMesh::EquationSystems::reinit_solutions(), BoundaryInfoTest::testBoundaryOnChildrenBoundaryIDs(), BoundaryInfoTest::testBoundaryOnChildrenBoundarySides(), BoundaryInfoTest::testBoundaryOnChildrenElementsRefineCoarsen(), BoundaryInfoTest::testBoundaryOnChildrenErrors(), InfFERadialTest::testRefinement(), EquationSystemsTest::testRefineThenReinitPreserveFlags(), and EquationSystemsTest::testSelectivePRefine().

683 {
684  // This function must be run on all processors at once
685  parallel_object_only();
686 
689 
690  // Possibly clean up the refinement flags from
691  // a previous step
692  for (auto & elem : _mesh.element_ptr_range())
693  {
694  // Set refinement flag to INACTIVE if the
695  // element isn't active
696  if (!elem->active())
697  {
698  elem->set_refinement_flag(Elem::INACTIVE);
699  elem->set_p_refinement_flag(Elem::INACTIVE);
700  }
701 
702  // This might be left over from the last step
703  if (elem->refinement_flag() == Elem::JUST_REFINED)
704  elem->set_refinement_flag(Elem::DO_NOTHING);
705  }
706 
707  // Parallel consistency has to come first, or coarsening
708  // along processor boundaries might occasionally be falsely
709  // prevented
710  bool flags_were_consistent = this->make_flags_parallel_consistent();
711 
712  // In theory, we should be able to remove the above call, which can
713  // be expensive and should be unnecessary. In practice, doing
714  // consistent flagging in parallel is hard, it's impossible to
715  // verify at the library level if it's being done by user code, and
716  // we don't want to abort large parallel runs in opt mode... but we
717  // do want to warn that they should be fixed.
718  libmesh_assert(flags_were_consistent);
719 
720  if (!flags_were_consistent)
721  libmesh_warning("Warning: Refinement flags were not consistent between processors! "
722  "Correcting and continuing.\n");
723 
724  // Smooth refinement flags
725  _smooth_flags(true, false);
726 
727  // Now refine the flagged elements. This will
728  // take up some space, maybe more than what was freed.
729  const bool mesh_changed =
730  this->_refine_elements();
731 
735 
736  // FIXME: This won't pass unless we add a redundant find_neighbors()
737  // call or replace find_neighbors() with on-the-fly neighbor updating
738  // libmesh_assert(!this->eliminate_unrefined_patches());
739 
740  // Finally, the new mesh needs to be prepared for use
741  if (mesh_changed)
743 
744  return mesh_changed;
745 }
bool _refine_elements()
Refines user-requested elements.
bool test_level_one(bool libmesh_assert_yes=false) const
MeshBase & _mesh
Reference to the mesh.
void prepare_for_use(const bool skip_renumber_nodes_and_elements, const bool skip_find_neighbors)
Prepare a newly ecreated (or read) mesh for use.
Definition: mesh_base.C:759
bool make_refinement_compatible()
Take user-specified refinement flags and augment them so that level-one dependency is satisfied...
unsigned char _face_level_mismatch_limit
libmesh_assert(ctx)
bool make_flags_parallel_consistent()
Copy refinement flags on ghost elements from their local processors.
void _smooth_flags(bool refining, bool coarsening)
Smooths refinement flags according to current settings.

◆ refine_fraction()

Real & libMesh::MeshRefinement::refine_fraction ( )
inline

The refine_fraction sets either a desired target or a desired maximum number of elements to flag for refinement, depending on which flag_elements_by method is called.

refine_fraction must be in \( [0,1] \), and is 0.3 by default.

Definition at line 906 of file mesh_refinement.h.

References _refine_fraction, and _use_member_parameters.

Referenced by assemble_and_solve(), and main().

907 {
908  _use_member_parameters = true;
909  return _refine_fraction;
910 }
bool _use_member_parameters
For backwards compatibility, we initialize this as false and then set it to true if the user uses any...

◆ set_enforce_mismatch_limit_prior_to_refinement()

void libMesh::MeshRefinement::set_enforce_mismatch_limit_prior_to_refinement ( bool  enforce)
inline

Set _enforce_mismatch_limit_prior_to_refinement option.

Defaults to false.

Deprecated:
Use enforce_mismatch_limit_prior_to_refinement() instead.

Definition at line 979 of file mesh_refinement.h.

References enforce_mismatch_limit_prior_to_refinement().

980 {
981  libmesh_deprecated();
983 }
bool & enforce_mismatch_limit_prior_to_refinement()
Get/set the _enforce_mismatch_limit_prior_to_refinement flag.

◆ set_periodic_boundaries_ptr()

void libMesh::MeshRefinement::set_periodic_boundaries_ptr ( PeriodicBoundaries pb_ptr)

Sets the PeriodicBoundaries pointer.

Referenced by main().

◆ switch_h_to_p_refinement()

void libMesh::MeshRefinement::switch_h_to_p_refinement ( )

Takes a mesh whose elements are flagged for h refinement and coarsening, and switches those flags to request p refinement and coarsening instead.

Definition at line 654 of file mesh_refinement_flagging.C.

References _mesh, libMesh::Elem::DO_NOTHING, and libMesh::Elem::INACTIVE.

Referenced by main(), and EquationSystemsTest::testSelectivePRefine().

655 {
656  for (auto & elem : _mesh.element_ptr_range())
657  {
658  if (elem->active())
659  {
660  elem->set_p_refinement_flag(elem->refinement_flag());
661  elem->set_refinement_flag(Elem::DO_NOTHING);
662  }
663  else
664  {
665  elem->set_p_refinement_flag(elem->refinement_flag());
666  elem->set_refinement_flag(Elem::INACTIVE);
667  }
668  }
669 }
MeshBase & _mesh
Reference to the mesh.

◆ test_level_one()

bool libMesh::MeshRefinement::test_level_one ( bool  libmesh_assert_yes = false) const
Returns
true if the mesh satisfies the level one restriction, and false otherwise.

Aborts the program if libmesh_assert_yes is true and the mesh does not satisfy the level one restriction.

Definition at line 353 of file mesh_refinement.C.

References _mesh, _periodic_boundaries, libMesh::Elem::active(), libMesh::ParallelObject::comm(), libMesh::Elem::level(), libMesh::libmesh_assert(), TIMPI::Communicator::max(), libMesh::out, libMesh::Elem::p_level(), libMesh::remote_elem, libMesh::MeshBase::sub_point_locator(), and topological_neighbor().

Referenced by coarsen_elements(), refine_and_coarsen_elements(), and refine_elements().

354 {
355  // This function must be run on all processors at once
356  parallel_object_only();
357 
358  // We may need a PointLocator for topological_neighbor() tests
359  // later, which we need to make sure gets constructed on all
360  // processors at once.
361  std::unique_ptr<PointLocatorBase> point_locator;
362 
363 #ifdef LIBMESH_ENABLE_PERIODIC
364  bool has_periodic_boundaries =
366  libmesh_assert(this->comm().verify(has_periodic_boundaries));
367 
368  if (has_periodic_boundaries)
369  point_locator = _mesh.sub_point_locator();
370 #endif
371 
372  bool failure = false;
373 
374 #ifndef NDEBUG
375  Elem * failed_elem = nullptr;
376  Elem * failed_neighbor = nullptr;
377 #endif // !NDEBUG
378 
379  for (auto & elem : _mesh.active_local_element_ptr_range())
380  for (auto n : elem->side_index_range())
381  {
382  Elem * neighbor =
383  topological_neighbor(elem, point_locator.get(), n);
384 
385  if (!neighbor || !neighbor->active() ||
386  neighbor == remote_elem)
387  continue;
388 
389  if ((neighbor->level() + 1 < elem->level()) ||
390  (neighbor->p_level() + 1 < elem->p_level()) ||
391  (neighbor->p_level() > elem->p_level() + 1))
392  {
393  failure = true;
394 #ifndef NDEBUG
395  failed_elem = elem;
396  failed_neighbor = neighbor;
397 #endif // !NDEBUG
398  break;
399  }
400  }
401 
402  // If any processor failed, we failed globally
403  this->comm().max(failure);
404 
405  if (failure)
406  {
407  // We didn't pass the level one test, so libmesh_assert that
408  // we're allowed not to
409 #ifndef NDEBUG
410  if (libmesh_assert_pass)
411  {
412  libMesh::out << "MeshRefinement Level one failure, element: "
413  << *failed_elem
414  << std::endl;
415  libMesh::out << "MeshRefinement Level one failure, neighbor: "
416  << *failed_neighbor
417  << std::endl;
418  }
419 #endif // !NDEBUG
420  libmesh_assert(!libmesh_assert_pass);
421  return false;
422  }
423  return true;
424 }
std::unique_ptr< PointLocatorBase > sub_point_locator() const
Definition: mesh_base.C:1675
MeshBase & _mesh
Reference to the mesh.
const Parallel::Communicator & comm() const
PeriodicBoundaries * _periodic_boundaries
libmesh_assert(ctx)
void max(const T &r, T &o, Request &req) const
OStreamProxy out
Elem * topological_neighbor(Elem *elem, const PointLocatorBase *point_locator, const unsigned int side) const
Local dispatch function for getting the correct topological neighbor from the Elem class...
const RemoteElem * remote_elem
Definition: remote_elem.C:57

◆ test_unflagged()

bool libMesh::MeshRefinement::test_unflagged ( bool  libmesh_assert_yes = false) const
Returns
true if the mesh has no elements flagged to be coarsened or refined, and false otherwise.

Aborts the program if libmesh_assert_yes is true and the mesh has flagged elements.

Definition at line 428 of file mesh_refinement.C.

References _mesh, libMesh::Elem::COARSEN, libMesh::ParallelObject::comm(), libMesh::libmesh_assert(), TIMPI::Communicator::max(), libMesh::out, and libMesh::Elem::REFINE.

Referenced by refine_and_coarsen_elements().

429 {
430  // This function must be run on all processors at once
431  parallel_object_only();
432 
433  bool found_flag = false;
434 
435 #ifndef NDEBUG
436  Elem * failed_elem = nullptr;
437 #endif
438 
439  // Search for local flags
440  for (auto & elem : _mesh.active_local_element_ptr_range())
441  if (elem->refinement_flag() == Elem::REFINE ||
442  elem->refinement_flag() == Elem::COARSEN ||
443  elem->p_refinement_flag() == Elem::REFINE ||
444  elem->p_refinement_flag() == Elem::COARSEN)
445  {
446  found_flag = true;
447 #ifndef NDEBUG
448  failed_elem = elem;
449 #endif
450  break;
451  }
452 
453  // If we found a flag on any processor, it counts
454  this->comm().max(found_flag);
455 
456  if (found_flag)
457  {
458 #ifndef NDEBUG
459  if (libmesh_assert_pass)
460  {
461  libMesh::out <<
462  "MeshRefinement test_unflagged failure, element: " <<
463  *failed_elem << std::endl;
464  }
465 #endif
466  // We didn't pass the "elements are unflagged" test,
467  // so libmesh_assert that we're allowed not to
468  libmesh_assert(!libmesh_assert_pass);
469  return false;
470  }
471  return true;
472 }
MeshBase & _mesh
Reference to the mesh.
const Parallel::Communicator & comm() const
libmesh_assert(ctx)
void max(const T &r, T &o, Request &req) const
OStreamProxy out

◆ topological_neighbor()

Elem * libMesh::MeshRefinement::topological_neighbor ( Elem elem,
const PointLocatorBase point_locator,
const unsigned int  side 
) const
private

Local dispatch function for getting the correct topological neighbor from the Elem class.

Definition at line 1795 of file mesh_refinement.C.

References _mesh, _periodic_boundaries, libMesh::libmesh_assert(), libMesh::Elem::neighbor_ptr(), and libMesh::Elem::topological_neighbor().

Referenced by make_coarsening_compatible(), make_refinement_compatible(), and test_level_one().

1798 {
1799 #ifdef LIBMESH_ENABLE_PERIODIC
1800  if (_periodic_boundaries && !_periodic_boundaries->empty())
1801  {
1802  libmesh_assert(point_locator);
1803  return elem->topological_neighbor(side, _mesh, *point_locator, _periodic_boundaries);
1804  }
1805 #endif
1806  return elem->neighbor_ptr(side);
1807 }
MeshBase & _mesh
Reference to the mesh.
PeriodicBoundaries * _periodic_boundaries
libmesh_assert(ctx)

◆ underrefined_boundary_limit()

signed char & libMesh::MeshRefinement::underrefined_boundary_limit ( )
inline

If underrefined_boundary_limit is set to a nonnegative value, then refinement and coarsening will produce meshes in which the refinement level of an element is no more than that many levels greater than the level of any boundary elements on its sides.

If underrefined_boundary_limit is negative, then level differences will be unlimited.

underrefined_boundary_limit is 0 by default. This implies that adaptive coarsening can only be done on a boundary element if any interior elements it is on the side of are simultaneously coarsened.

Definition at line 962 of file mesh_refinement.h.

References _underrefined_boundary_limit.

Referenced by libMesh::EquationSystems::reinit_solutions().

963 {
965 }
signed char _underrefined_boundary_limit

◆ uniformly_coarsen()

void libMesh::MeshRefinement::uniformly_coarsen ( unsigned int  n = 1)

Attempts to uniformly coarsen the mesh n times.

Definition at line 1707 of file mesh_refinement.C.

References _coarsen_elements(), _mesh, libMesh::as_range(), clean_refinement_flags(), libMesh::Elem::COARSEN, libMesh::Elem::COARSEN_INACTIVE, libMesh::ParallelObject::comm(), libMesh::MeshBase::elem_ref(), TIMPI::Communicator::get_unique_tag(), libMesh::Elem::INACTIVE, libMesh::MeshBase::is_replicated(), libMesh::libmesh_assert(), libMesh::ParallelObject::n_processors(), libMesh::MeshBase::prepare_for_use(), libMesh::ParallelObject::processor_id(), TIMPI::Communicator::receive(), libMesh::Elem::refinement_flag(), TIMPI::Communicator::send(), libMesh::Elem::set_refinement_flag(), and libMesh::Parallel::sync_dofobject_data_by_id().

Referenced by libMesh::UniformRefinementEstimator::_estimate_error(), libMesh::AdjointRefinementEstimator::estimate_error(), and libMesh::PetscDMWrapper::init_petscdm().

1708 {
1709  // Coarsen n times
1710  for (unsigned int rstep=0; rstep<n; rstep++)
1711  {
1712  // Clean up the refinement flags
1713  this->clean_refinement_flags();
1714 
1715  // Flag all the active elements for coarsening.
1716  for (auto & elem : _mesh.active_element_ptr_range())
1717  {
1718  elem->set_refinement_flag(Elem::COARSEN);
1719  if (elem->parent())
1720  elem->parent()->set_refinement_flag(Elem::COARSEN_INACTIVE);
1721  }
1722 
1723  // On a distributed mesh, we may have parent elements with
1724  // remote active children. To keep flags consistent, we'll need
1725  // a communication step.
1726  if (!_mesh.is_replicated())
1727  {
1728  const processor_id_type n_proc = _mesh.n_processors();
1729  const processor_id_type my_proc_id = _mesh.processor_id();
1730 
1731  std::vector<std::vector<dof_id_type>>
1732  parents_to_coarsen(n_proc);
1733 
1734  for (const auto & elem : as_range(_mesh.ancestor_elements_begin(), _mesh.ancestor_elements_end()))
1735  if (elem->processor_id() != my_proc_id &&
1736  elem->refinement_flag() == Elem::COARSEN_INACTIVE)
1737  parents_to_coarsen[elem->processor_id()].push_back(elem->id());
1738 
1739  Parallel::MessageTag
1740  coarsen_tag = this->comm().get_unique_tag();
1741  std::vector<Parallel::Request> coarsen_push_requests(n_proc-1);
1742 
1743  for (processor_id_type p = 0; p != n_proc; ++p)
1744  {
1745  if (p == my_proc_id)
1746  continue;
1747 
1748  Parallel::Request &request =
1749  coarsen_push_requests[p - (p > my_proc_id)];
1750 
1751  _mesh.comm().send
1752  (p, parents_to_coarsen[p], request, coarsen_tag);
1753  }
1754 
1755  for (processor_id_type p = 1; p != n_proc; ++p)
1756  {
1757  std::vector<dof_id_type> my_parents_to_coarsen;
1758  _mesh.comm().receive
1759  (Parallel::any_source, my_parents_to_coarsen,
1760  coarsen_tag);
1761 
1762  for (const auto & id : my_parents_to_coarsen)
1763  {
1764  Elem & elem = _mesh.elem_ref(id);
1765  libmesh_assert(elem.refinement_flag() == Elem::INACTIVE ||
1766  elem.refinement_flag() == Elem::COARSEN_INACTIVE);
1767  elem.set_refinement_flag(Elem::COARSEN_INACTIVE);
1768  }
1769  }
1770 
1771  Parallel::wait(coarsen_push_requests);
1772 
1773  SyncRefinementFlags hsync(_mesh, &Elem::refinement_flag,
1776  (this->comm(), _mesh.not_local_elements_begin(),
1777  _mesh.not_local_elements_end(),
1778  // We'd like a smaller sync, but this leads to bugs?
1779  // SyncCoarsenInactive(),
1780  hsync);
1781  }
1782 
1783  // Coarsen all the elements we just flagged.
1784  this->_coarsen_elements();
1785  }
1786 
1787 
1788  // Finally, the new mesh probably needs to be prepared for use
1789  if (n > 0)
1791 }
RefinementState refinement_flag() const
Definition: elem.h:3210
MPI_Request request
MeshBase & _mesh
Reference to the mesh.
MessageTag get_unique_tag(int tagvalue=MessageTag::invalid_tag) const
void prepare_for_use(const bool skip_renumber_nodes_and_elements, const bool skip_find_neighbors)
Prepare a newly ecreated (or read) mesh for use.
Definition: mesh_base.C:759
void set_refinement_flag(const RefinementState rflag)
Sets the value of the refinement flag for the element.
Definition: elem.h:3218
const Parallel::Communicator & comm() const
void clean_refinement_flags()
Sets the refinement flag to Elem::DO_NOTHING for each element in the mesh.
uint8_t processor_id_type
processor_id_type n_processors() const
Status receive(const unsigned int dest_processor_id, T &buf, const MessageTag &tag=any_tag) const
SimpleRange< IndexType > as_range(const std::pair< IndexType, IndexType > &p)
Helper function that allows us to treat a homogenous pair as a range.
Definition: simple_range.h:57
libmesh_assert(ctx)
void sync_dofobject_data_by_id(const Communicator &comm, const Iterator &range_begin, const Iterator &range_end, SyncFunctor &sync)
Request data about a range of ghost dofobjects uniquely identified by their id.
void send(const unsigned int dest_processor_id, const T &buf, const MessageTag &tag=no_tag) const
virtual bool is_replicated() const
Definition: mesh_base.h:233
virtual const Elem & elem_ref(const dof_id_type i) const
Definition: mesh_base.h:639
bool _coarsen_elements()
Coarsens user-requested elements.
processor_id_type processor_id() const

◆ uniformly_p_coarsen()

void libMesh::MeshRefinement::uniformly_p_coarsen ( unsigned int  n = 1)

Attempts to uniformly p coarsen the mesh n times.

Definition at line 1667 of file mesh_refinement.C.

References _mesh, and libMesh::Elem::JUST_COARSENED.

Referenced by libMesh::UniformRefinementEstimator::_estimate_error(), and libMesh::AdjointRefinementEstimator::estimate_error().

1668 {
1669  // Coarsen p times
1670  for (unsigned int rstep=0; rstep<n; rstep++)
1671  for (auto & elem : _mesh.active_element_ptr_range())
1672  if (elem->p_level() > 0)
1673  {
1674  // P coarsen all the active elements
1675  elem->set_p_level(elem->p_level()-1);
1676  elem->set_p_refinement_flag(Elem::JUST_COARSENED);
1677  }
1678 }
MeshBase & _mesh
Reference to the mesh.

◆ uniformly_p_refine()

void libMesh::MeshRefinement::uniformly_p_refine ( unsigned int  n = 1)

Uniformly p refines the mesh n times.

Definition at line 1653 of file mesh_refinement.C.

References _mesh, and libMesh::Elem::JUST_REFINED.

Referenced by libMesh::UniformRefinementEstimator::_estimate_error(), libMesh::AdjointRefinementEstimator::estimate_error(), and main().

1654 {
1655  // Refine n times
1656  for (unsigned int rstep=0; rstep<n; rstep++)
1657  for (auto & elem : _mesh.active_element_ptr_range())
1658  {
1659  // P refine all the active elements
1660  elem->set_p_level(elem->p_level()+1);
1661  elem->set_p_refinement_flag(Elem::JUST_REFINED);
1662  }
1663 }
MeshBase & _mesh
Reference to the mesh.

◆ uniformly_refine()

void libMesh::MeshRefinement::uniformly_refine ( unsigned int  n = 1)

Uniformly refines the mesh n times.

Definition at line 1682 of file mesh_refinement.C.

References _mesh, _refine_elements(), clean_refinement_flags(), libMesh::MeshBase::prepare_for_use(), and libMesh::Elem::REFINE.

Referenced by libMesh::UniformRefinementEstimator::_estimate_error(), OverlappingTestBase::build_quad_mesh(), libMesh::AdjointRefinementEstimator::estimate_error(), libMesh::PetscDMWrapper::init_petscdm(), main(), OverlappingFunctorTest::run_coupling_functor_test(), OverlappingFunctorTest::run_partitioner_test(), MixedDimensionRefinedMeshTest::setUp(), SlitMeshRefinedMeshTest::setUp(), SlitMeshRefinedSystemTest::setUp(), BoundaryRefinedMeshTest::setUp(), BoundaryOfRefinedMeshTest::setUp(), ExtraIntegersTest::test_helper(), ElemTest< elem_type >::test_n_refinements(), SystemsTest::testProjectMatrix1D(), SystemsTest::testProjectMatrix2D(), and SystemsTest::testProjectMatrix3D().

1683 {
1684  // Refine n times
1685  // FIXME - this won't work if n>1 and the mesh
1686  // has already been attached to an equation system
1687  for (unsigned int rstep=0; rstep<n; rstep++)
1688  {
1689  // Clean up the refinement flags
1690  this->clean_refinement_flags();
1691 
1692  // Flag all the active elements for refinement.
1693  for (auto & elem : _mesh.active_element_ptr_range())
1694  elem->set_refinement_flag(Elem::REFINE);
1695 
1696  // Refine all the elements we just flagged.
1697  this->_refine_elements();
1698  }
1699 
1700  // Finally, the new mesh probably needs to be prepared for use
1701  if (n > 0)
1703 }
bool _refine_elements()
Refines user-requested elements.
MeshBase & _mesh
Reference to the mesh.
void prepare_for_use(const bool skip_renumber_nodes_and_elements, const bool skip_find_neighbors)
Prepare a newly ecreated (or read) mesh for use.
Definition: mesh_base.C:759
void clean_refinement_flags()
Sets the refinement flag to Elem::DO_NOTHING for each element in the mesh.

◆ update_nodes_map()

void libMesh::MeshRefinement::update_nodes_map ( )
private

Updates the _new_nodes_map.

Definition at line 346 of file mesh_refinement.C.

References _mesh, _new_nodes_map, and libMesh::TopologyMap::init().

Referenced by _coarsen_elements(), and _refine_elements().

347 {
348  this->_new_nodes_map.init(_mesh);
349 }
TopologyMap _new_nodes_map
Data structure that holds the new nodes information.
MeshBase & _mesh
Reference to the mesh.
void init(MeshBase &)
Definition: topology_map.C:36

Member Data Documentation

◆ _absolute_global_tolerance

Real libMesh::MeshRefinement::_absolute_global_tolerance
private

◆ _allow_unrefined_patches

bool libMesh::MeshRefinement::_allow_unrefined_patches
private

Definition at line 804 of file mesh_refinement.h.

Referenced by allow_unrefined_patches(), and eliminate_unrefined_patches().

◆ _coarsen_by_parents

bool libMesh::MeshRefinement::_coarsen_by_parents
private

◆ _coarsen_fraction

Real libMesh::MeshRefinement::_coarsen_fraction
private

◆ _coarsen_threshold

Real libMesh::MeshRefinement::_coarsen_threshold
private

◆ _communicator

const Parallel::Communicator& libMesh::ParallelObject::_communicator
protectedinherited

◆ _edge_level_mismatch_limit

unsigned char libMesh::MeshRefinement::_edge_level_mismatch_limit
private

Definition at line 798 of file mesh_refinement.h.

Referenced by _smooth_flags(), and edge_level_mismatch_limit().

◆ _enforce_mismatch_limit_prior_to_refinement

bool libMesh::MeshRefinement::_enforce_mismatch_limit_prior_to_refinement
private


This option enforces the mismatch level prior to refinement by checking if refining any element marked for refinement would cause a mismatch greater than the limit.

Applies to all mismatch methods.

Calling this with node_level_mismatch_limit() = 1 would transform this mesh:

* o-------o-------o-------o-------o
* |       |       |       |       |
* |       |       |       |       |
* |       |       |       |       |
* |       |       |       |       |
* |       |       |       |       |
* o-------o---o---o-------o-------o
* |       |   :   |       |       |
* |       |   :   |       |       |
* |       o...o...o       |       |
* |       |   :   |       |       |
* |       |   :   |       |       |
* o-------o---o---o-------o-------o
* |       |       |               |
* |       |       |               |
* |       |       |               |
* |       |       |               |
* |       |       |               |
* o-------o-------o               |
* |       |       |               |
* |       |       |               |
* |       |       |               |
* |       |       |               |
* |       |       |               |
* o-------o-------o---------------o
* 

into this:

* o-------o-------o-------o-------o
* |       |       |       |       |
* |       |       |       |       |
* |       |       |       |       |
* |       |       |       |       |
* |       |       |       |       |
* o-------o-------o-------o-------o
* |       |       |       |       |
* |       |       |       |       |
* |       |       |       |       |
* |       |       |       |       |
* |       |       |       |       |
* o-------o-------o-------o-------o
* |       |       |       :       |
* |       |       |       :       |
* |       |       |       :       |
* |       |       |       :       |
* |       |       |       :       |
* o-------o-------o.......o.......o
* |       |       |       :       |
* |       |       |       :       |
* |       |       |       :       |
* |       |       |       :       |
* |       |       |       :       |
* o-------o-------o-------o-------o
* 

by moving the refinement flag to the indicated element.

Default value is false.

Definition at line 874 of file mesh_refinement.h.

Referenced by enforce_mismatch_limit_prior_to_refinement(), limit_level_mismatch_at_edge(), and limit_level_mismatch_at_node().

◆ _face_level_mismatch_limit

unsigned char libMesh::MeshRefinement::_face_level_mismatch_limit
private

◆ _max_h_level

unsigned int libMesh::MeshRefinement::_max_h_level
private

◆ _mesh

MeshBase& libMesh::MeshRefinement::_mesh
private

◆ _nelem_target

dof_id_type libMesh::MeshRefinement::_nelem_target
private

Definition at line 793 of file mesh_refinement.h.

Referenced by flag_elements_by_nelem_target(), and nelem_target().

◆ _new_nodes_map

TopologyMap libMesh::MeshRefinement::_new_nodes_map
private

Data structure that holds the new nodes information.

Definition at line 765 of file mesh_refinement.h.

Referenced by add_node(), clear(), and update_nodes_map().

◆ _node_level_mismatch_limit

unsigned char libMesh::MeshRefinement::_node_level_mismatch_limit
private

Definition at line 799 of file mesh_refinement.h.

Referenced by _smooth_flags(), and node_level_mismatch_limit().

◆ _overrefined_boundary_limit

signed char libMesh::MeshRefinement::_overrefined_boundary_limit
private

Definition at line 801 of file mesh_refinement.h.

Referenced by _smooth_flags(), and overrefined_boundary_limit().

◆ _periodic_boundaries

PeriodicBoundaries* libMesh::MeshRefinement::_periodic_boundaries
private

◆ _refine_fraction

Real libMesh::MeshRefinement::_refine_fraction
private

◆ _underrefined_boundary_limit

signed char libMesh::MeshRefinement::_underrefined_boundary_limit
private

Definition at line 802 of file mesh_refinement.h.

Referenced by _smooth_flags(), and underrefined_boundary_limit().

◆ _use_member_parameters

bool libMesh::MeshRefinement::_use_member_parameters
private

For backwards compatibility, we initialize this as false and then set it to true if the user uses any of the refinement parameter accessor functions.

Definition at line 777 of file mesh_refinement.h.

Referenced by absolute_global_tolerance(), coarsen_by_parents(), coarsen_fraction(), coarsen_threshold(), flag_elements_by_elem_fraction(), flag_elements_by_error_fraction(), flag_elements_by_mean_stddev(), max_h_level(), nelem_target(), and refine_fraction().


The documentation for this class was generated from the following files: