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)
 
bool test_unflagged (bool libmesh_assert_yes=false)
 
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...
 
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 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::Communicator & comm () 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)
 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)
 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 _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 858 of file mesh_refinement.h.

858 {POINT, EDGE};

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),
111 #ifdef LIBMESH_ENABLE_PERIODIC
112  , _periodic_boundaries(nullptr)
113 #endif
114 {
115 }
116 
117 
118 
119 #ifdef LIBMESH_ENABLE_PERIODIC
120 void MeshRefinement::set_periodic_boundaries_ptr(PeriodicBoundaries * pb_ptr)
121 {
122  _periodic_boundaries = pb_ptr;
123 }

◆ MeshRefinement() [2/2]

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

◆ ~MeshRefinement()

libMesh::MeshRefinement::~MeshRefinement ( )

Destructor.

Deletes all the elements that are currently stored.

Definition at line 128 of file mesh_refinement.C.

129 {
130  this->clear();
131 }

References clear().

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 1336 of file mesh_refinement.C.

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

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

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

◆ _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 1462 of file mesh_refinement.C.

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

References _mesh, libMesh::MeshBase::active_element_ptr_range(), libMesh::MeshBase::active_local_element_ptr_range(), libMesh::MeshBase::active_not_local_elements_begin(), libMesh::MeshBase::active_not_local_elements_end(), libMesh::as_range(), clear(), libMesh::ParallelObject::comm(), libMesh::MeshBase::element_ptr_range(), 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(), libMesh::Elem::REFINE, libMesh::Partitioner::set_node_processor_ids(), libMesh::MeshBase::unpartitioned_elements_begin(), libMesh::MeshBase::unpartitioned_elements_end(), update_nodes_map(), and libMesh::MeshBase::update_parallel_id_counts().

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

◆ _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 1594 of file mesh_refinement.C.

1595 {
1596  // Smoothing can break in weird ways on a mesh with broken topology
1597 #ifdef DEBUG
1599 #endif
1600 
1601  // Repeat until flag changes match on every processor
1602  do
1603  {
1604  // Repeat until coarsening & refinement flags jive
1605  bool satisfied = false;
1606  do
1607  {
1608  // If we're refining or coarsening, hit the corresponding
1609  // face level test code. Short-circuiting || is our friend
1610  const bool coarsening_satisfied =
1611  !coarsening ||
1613 
1614  const bool refinement_satisfied =
1615  !refining ||
1617 
1618  bool smoothing_satisfied =
1619  !this->eliminate_unrefined_patches();// &&
1620 
1622  smoothing_satisfied = smoothing_satisfied &&
1624 
1626  smoothing_satisfied = smoothing_satisfied &&
1628 
1630  smoothing_satisfied = smoothing_satisfied &&
1632 
1634  smoothing_satisfied = smoothing_satisfied &&
1636 
1637  satisfied = (coarsening_satisfied &&
1638  refinement_satisfied &&
1639  smoothing_satisfied);
1640 
1641  libmesh_assert(this->comm().verify(satisfied));
1642  }
1643  while (!satisfied);
1644  }
1645  while (!_mesh.is_serial() && !this->make_flags_parallel_consistent());
1646 }

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().

◆ 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 909 of file mesh_refinement.h.

910 {
911  _use_member_parameters = true;
913 }

References _absolute_global_tolerance, and _use_member_parameters.

Referenced by build_mesh_refinement(), and main().

◆ add_elem()

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

Adds the element elem to the mesh.

Definition at line 211 of file mesh_refinement.C.

212 {
213  libmesh_assert(elem);
214  _mesh.add_elem (elem);
215  return elem;
216 }

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

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

◆ 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 142 of file mesh_refinement.C.

146 {
147  LOG_SCOPE("add_node()", "MeshRefinement");
148 
149  unsigned int parent_n = parent.as_parent_node(child, node);
150 
151  if (parent_n != libMesh::invalid_uint)
152  return parent.node_ptr(parent_n);
153 
154  const std::vector<std::pair<dof_id_type, dof_id_type>>
155  bracketing_nodes = parent.bracketing_nodes(child, node);
156 
157  // If we're not a parent node, we *must* be bracketed by at least
158  // one pair of parent nodes
159  libmesh_assert(bracketing_nodes.size());
160 
161  const dof_id_type new_node_id =
162  _new_nodes_map.find(bracketing_nodes);
163 
164  // Return the node if it already exists.
165  //
166  // We'll leave the processor_id untouched in this case - if we're
167  // repartitioning later or if this is a new unpartitioned node,
168  // we'll update it then, and if not then we don't want to update it.
169  if (new_node_id != DofObject::invalid_id)
170  return _mesh.node_ptr(new_node_id);
171 
172  // Otherwise we need to add a new node.
173  //
174  // Figure out where to add the point:
175 
176  Point p; // defaults to 0,0,0
177 
178  for (auto n : parent.node_index_range())
179  {
180  // The value from the embedding matrix
181  const float em_val = parent.embedding_matrix(child,node,n);
182 
183  if (em_val != 0.)
184  {
185  p.add_scaled (parent.point(n), em_val);
186 
187  // If we'd already found the node we shouldn't be here
188  libmesh_assert_not_equal_to (em_val, 1);
189  }
190  }
191 
192  // Although we're leaving new nodes unpartitioned at first, with a
193  // DistributedMesh we would need a default id based on the numbering
194  // scheme for the requested processor_id.
195  Node * new_node = _mesh.add_point (p, DofObject::invalid_id, proc_id);
196 
197  libmesh_assert(new_node);
198 
199  // But then we'll make sure this node is marked as unpartitioned.
200  new_node->processor_id() = DofObject::invalid_processor_id;
201 
202  // Add the node to the map.
203  _new_nodes_map.add_node(*new_node, bracketing_nodes);
204 
205  // Return the address of the new node
206  return new_node;
207 }

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(), and libMesh::DofObject::processor_id().

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

◆ 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 674 of file mesh_refinement_flagging.C.

675 {
676  for (auto & elem : _mesh.element_ptr_range())
677  elem->set_p_refinement_flag(elem->refinement_flag());
678 }

References _mesh, and libMesh::MeshBase::element_ptr_range().

Referenced by main().

◆ 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 682 of file mesh_refinement_flagging.C.

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

References _mesh, libMesh::Elem::DO_NOTHING, libMesh::MeshBase::element_ptr_range(), and libMesh::Elem::INACTIVE.

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

◆ clear()

void libMesh::MeshRefinement::clear ( )

Deletes all the data that are currently stored.

Definition at line 135 of file mesh_refinement.C.

136 {
138 }

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

Referenced by _coarsen_elements(), _refine_elements(), and ~MeshRefinement().

◆ 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 873 of file mesh_refinement.h.

874 {
875  _use_member_parameters = true;
876  return _coarsen_by_parents;
877 }

References _coarsen_by_parents, and _use_member_parameters.

Referenced by build_mesh_refinement(), and main().

◆ 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.

Definition at line 608 of file mesh_refinement.C.

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  if (!flags_were_consistent)
647  {
648  libMesh::out << "Refinement flags were not consistent between processors!\n"
649  << "Correcting and continuing.";
650  }
651 
652  // Smooth coarsening flags
653  _smooth_flags(false, true);
654 
655  // Coarsen the flagged elements.
656  const bool mesh_changed =
657  this->_coarsen_elements ();
658 
662  // FIXME: This won't pass unless we add a redundant find_neighbors()
663  // call or replace find_neighbors() with on-the-fly neighbor updating
664  // libmesh_assert(!this->eliminate_unrefined_patches());
665 
666  // We can't contract the mesh ourselves anymore - a System might
667  // need to restrict old coefficient vectors first
668  // _mesh.contract();
669 
670  // Finally, the new mesh may need to be prepared for use
671  if (mesh_changed)
672  _mesh.prepare_for_use (/*skip_renumber =*/false);
673 
674  return mesh_changed;
675 }

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

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

◆ 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 885 of file mesh_refinement.h.

886 {
887  _use_member_parameters = true;
888  return _coarsen_fraction;
889 }

References _coarsen_fraction, and _use_member_parameters.

Referenced by assemble_and_solve(), build_mesh_refinement(), and main().

◆ 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 897 of file mesh_refinement.h.

898 {
899  _use_member_parameters = true;
900  return _coarsen_threshold;
901 }

References _coarsen_threshold, and _use_member_parameters.

Referenced by build_mesh_refinement(), and main().

◆ comm()

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

Definition at line 94 of file parallel_object.h.

95  { return _communicator; }

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::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(), libMesh::EquationSystems::_read_impl(), _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::ImplicitSystem::add_matrix(), libMesh::RBConstruction::add_scaled_matrix_and_vector(), libMesh::DynaIO::add_spline_constraints(), libMesh::System::add_vector(), libMesh::UnstructuredMesh::all_second_order(), 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::FEMSystem::assemble_qoi(), libMesh::MeshCommunication::assign_global_indices(), libMesh::DofMap::attach_matrix(), libMesh::MeshTools::Generation::build_extrusion(), 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::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::Problem_Interface::computeF(), libMesh::Problem_Interface::computeJacobian(), libMesh::Problem_Interface::computePreconditioner(), libMesh::ExodusII_IO::copy_elemental_solution(), libMesh::ExodusII_IO::copy_scalar_solution(), 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::MeshCommunication::delete_remote_elements(), libMesh::DofMap::distribute_dofs(), DMlibMeshFunction(), DMlibMeshJacobian(), DMlibMeshSetSystem_libMesh(), DMVariableBounds_libMesh(), libMesh::DTKSolutionTransfer::DTKSolutionTransfer(), eliminate_unrefined_patches(), libMesh::RBEIMConstruction::enrich_RB_space(), libMesh::TransientRBConstruction::enrich_RB_space(), libMesh::RBConstruction::enrich_RB_space(), libMesh::EpetraVector< T >::EpetraVector(), AssembleOptimization::equality_constraints(), libMesh::WeightedPatchRecoveryErrorEstimator::estimate_error(), libMesh::PatchRecoveryErrorEstimator::estimate_error(), libMesh::JumpErrorEstimator::estimate_error(), libMesh::AdjointRefinementEstimator::estimate_error(), libMesh::ExactErrorEstimator::estimate_error(), libMesh::RBEIMConstruction::evaluate_mesh_function(), 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::DofMap::gather_constraints(), libMesh::MeshfreeInterpolation::gather_remote_data(), libMesh::CondensedEigenSystem::get_eigenpair(), libMesh::DofMap::get_info(), libMesh::ImplicitSystem::get_linear_solver(), AssembleOptimization::inequality_constraints(), AssembleOptimization::inequality_constraints_jacobian(), libMesh::LocationMap< T >::init(), libMesh::TimeSolver::init(), libMesh::SystemSubsetBySubdomain::init(), libMesh::PetscDMWrapper::init_and_attach_petscdm(), libMesh::EigenSystem::init_matrices(), libMesh::OptimizationSystem::initialize_equality_constraints_storage(), libMesh::OptimizationSystem::initialize_inequality_constraints_storage(), libMesh::RBEIMConstruction::initialize_rb_construction(), 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_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::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_preconditioner_apply(), libMesh::libmesh_petsc_snes_fd_residual(), libMesh::libmesh_petsc_snes_jacobian(), libMesh::libmesh_petsc_snes_mffd_residual(), libMesh::libmesh_petsc_snes_postcheck(), 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(), 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_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(), LinearElasticityWithContact::move_mesh(), libMesh::DistributedMesh::n_active_elem(), libMesh::MeshTools::n_active_levels(), libMesh::BoundaryInfo::n_boundary_conds(), libMesh::DofMap::n_constrained_dofs(), libMesh::BoundaryInfo::n_edge_conds(), libMesh::CondensedEigenSystem::n_global_non_condensed_dofs(), libMesh::MeshTools::n_levels(), libMesh::BoundaryInfo::n_nodeset_conds(), libMesh::MeshTools::n_p_levels(), libMesh::BoundaryInfo::n_shellface_conds(), 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::MeshTools::paranoid_n_levels(), libMesh::petsc_auto_fieldsplit(), libMesh::System::point_gradient(), libMesh::System::point_hessian(), libMesh::System::point_value(), libMesh::DofMap::print_dof_constraints(), FEMParameters::read(), libMesh::Nemesis_IO::read(), libMesh::XdrIO::read(), libMesh::CheckpointIO::read_header(), libMesh::XdrIO::read_header(), libMesh::System::read_header(), 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(), refine_and_coarsen_elements(), libMesh::DistributedMesh::renumber_dof_objects(), LinearElasticityWithContact::residual_and_jacobian(), OverlappingAlgebraicGhostingTest::run_ghosting_test(), OverlappingCouplingGhostingTest::run_sparsity_pattern_test(), libMesh::DofMap::scatter_constraints(), libMesh::CheckpointIO::select_split_config(), libMesh::TransientRBConstruction::set_error_temporal_data(), libMesh::RBEIMConstruction::set_explicit_sys_subvector(), libMesh::DofMap::set_nonlocal_dof_objects(), libMesh::PetscDMWrapper::set_point_range_in_section(), libMesh::PetscDiffSolver::setup_petsc_data(), libMesh::LaplaceMeshSmoother::smooth(), libMesh::split_mesh(), libMesh::BoundaryInfo::sync(), test_level_one(), MeshfunctionDFEM::test_mesh_function_dfem(), MeshfunctionDFEM::test_mesh_function_dfem_grad(), MeshFunctionTest::test_p_level(), test_unflagged(), SystemsTest::testBlockRestrictedVarNDofs(), PointLocatorTest::testLocator(), BoundaryInfoTest::testMesh(), SystemsTest::testProjectCubeWithMeshFunction(), CheckpointIOTest::testSplitter(), libMesh::MeshTools::total_weight(), libMesh::MeshFunctionSolutionTransfer::transfer(), libMesh::MeshfreeSolutionTransfer::transfer(), libMesh::TransientRBConstruction::truth_assembly(), libMesh::RBConstruction::truth_assembly(), uniformly_coarsen(), libMesh::TransientRBConstruction::update_RB_initial_condition_all_N(), libMesh::RBEIMConstruction::update_RB_system_matrices(), libMesh::TransientRBConstruction::update_RB_system_matrices(), libMesh::RBConstruction::update_RB_system_matrices(), libMesh::TransientRBConstruction::update_residual_terms(), libMesh::RBConstruction::update_residual_terms(), libMesh::NameBasedIO::write(), libMesh::XdrIO::write(), libMesh::VTKIO::write_nodal_data(), 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().

◆ 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.

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 }

References _mesh, libMesh::MeshBase::active_local_element_ptr_range(), libMesh::ParallelObject::comm(), libMesh::DofObject::id(), libMesh::index_range(), libMesh::libmesh_assert(), libMesh::Elem::parent(), and std::sqrt().

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

◆ 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 920 of file mesh_refinement.h.

921 {
923 }

References _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

Definition at line 368 of file mesh_refinement_smoothing.C.

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

References _mesh, libMesh::MeshBase::active_element_ptr_range(), libMesh::Elem::COARSEN, libMesh::Elem::COARSEN_INACTIVE, libMesh::ParallelObject::comm(), libMesh::Elem::DO_NOTHING, libMesh::Elem::INACTIVE, libMesh::libmesh_assert(), libMesh::Elem::REFINE, and libMesh::remote_elem.

Referenced by _smooth_flags().

◆ 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 954 of file mesh_refinement.h.

955 {
957 }

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().

◆ 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 539 of file mesh_refinement_smoothing.C.

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

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().

◆ 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 915 of file mesh_refinement.h.

916 {
918 }

References _face_level_mismatch_limit.

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

◆ 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 648 of file mesh_refinement_flagging.C.

649 {
650  element_flagging.flag_elements();
651 }

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

◆ 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 446 of file mesh_refinement_flagging.C.

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

References _coarsen_by_parents, _coarsen_fraction, _max_h_level, _mesh, _refine_fraction, _use_member_parameters, libMesh::MeshBase::active_element_ptr_range(), libMesh::MeshBase::active_local_element_ptr_range(), 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().

◆ 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.

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 }

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

Referenced by assemble_and_solve(), and main().

◆ 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.

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 =
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 }

References _absolute_global_tolerance, _coarsen_by_parents, _coarsen_fraction, _coarsen_threshold, _max_h_level, _mesh, _refine_fraction, libMesh::MeshBase::active_element_ptr_range(), 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, libMesh::Elem::REFINE, and std::sqrt().

Referenced by main().

◆ 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 584 of file mesh_refinement_flagging.C.

588 {
589  // Verify that our error vector is consistent, using std::vector to
590  // avoid confusing this->comm().verify
591  libmesh_assert(this->comm().verify(dynamic_cast<const std::vector<ErrorVectorReal> &>(error_per_cell)));
592 
593  // The function arguments are currently just there for
594  // backwards_compatibility
596  {
597  // If the user used non-default parameters, lets warn
598  // that they're deprecated
599  if (refine_frac != 0.3 ||
600  coarsen_frac != 0.0 ||
601  max_l != libMesh::invalid_uint)
602  libmesh_deprecated();
603 
604  _refine_fraction = refine_frac;
605  _coarsen_fraction = coarsen_frac;
606  _max_h_level = max_l;
607  }
608 
609  // Get the mean value from the error vector
610  const Real mean = error_per_cell.mean();
611 
612  // Get the standard deviation. This equals the
613  // square-root of the variance
614  const Real stddev = std::sqrt (error_per_cell.variance());
615 
616  // Check for valid fractions
617  libmesh_assert_greater_equal (_refine_fraction, 0);
618  libmesh_assert_less_equal (_refine_fraction, 1);
619  libmesh_assert_greater_equal (_coarsen_fraction, 0);
620  libmesh_assert_less_equal (_coarsen_fraction, 1);
621 
622  // The refine and coarsen cutoff
623  const Real refine_cutoff = mean + _refine_fraction * stddev;
624  const Real coarsen_cutoff = std::max(mean - _coarsen_fraction * stddev, 0.);
625 
626  // Loop over the elements and flag them for coarsening or
627  // refinement based on the element error
628  for (auto & elem : _mesh.active_element_ptr_range())
629  {
630  const dof_id_type id = elem->id();
631 
632  libmesh_assert_less (id, error_per_cell.size());
633 
634  const ErrorVectorReal elem_error = error_per_cell[id];
635 
636  // Possibly flag the element for coarsening ...
637  if (elem_error <= coarsen_cutoff)
638  elem->set_refinement_flag(Elem::COARSEN);
639 
640  // ... or refinement
641  if ((elem_error >= refine_cutoff) && (elem->level() < _max_h_level))
642  elem->set_refinement_flag(Elem::REFINE);
643  }
644 }

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

◆ 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.

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.push_back
295  (std::make_pair(error_per_cell[eid], eid));
296  }
297 
298  this->comm().max(is_active);
299 
300  this->comm().allgather(sorted_error);
301  }
302 
303  // Default sort works since pairs are sorted lexicographically
304  std::sort (sorted_error.begin(), sorted_error.end());
305  std::reverse (sorted_error.begin(), sorted_error.end());
306 
307  // Create a sorted error vector with coarsenable parent elements
308  // only, sorted by lowest errors first
309  ErrorVector error_per_parent;
310  std::vector<std::pair<ErrorVectorReal, dof_id_type>> sorted_parent_error;
311  Real parent_error_min, parent_error_max;
312 
313  create_parent_error_vector(error_per_cell,
314  error_per_parent,
315  parent_error_min,
316  parent_error_max);
317 
318  // create_parent_error_vector sets values for non-parents and
319  // non-coarsenable parents to -1. Get rid of them.
320  for (auto i : index_range(error_per_parent))
321  if (error_per_parent[i] != -1)
322  sorted_parent_error.push_back(std::make_pair(error_per_parent[i], i));
323 
324  std::sort (sorted_parent_error.begin(), sorted_parent_error.end());
325 
326  // Keep track of how many elements we plan to coarsen & refine
327  dof_id_type coarsen_count = 0;
328  dof_id_type refine_count = 0;
329 
330  const unsigned int dim = _mesh.mesh_dimension();
331  unsigned int twotodim = 1;
332  for (unsigned int i=0; i!=dim; ++i)
333  twotodim *= 2;
334 
335  // First, let's try to get our element count to target_nelem
336  if (n_elem_new >= 0)
337  {
338  // Every element refinement creates at least
339  // 2^dim-1 new elements
340  refine_count =
341  std::min(cast_int<dof_id_type>(n_elem_new / (twotodim-1)),
342  max_elem_refine);
343  }
344  else
345  {
346  // Every successful element coarsening is likely to destroy
347  // 2^dim-1 net elements.
348  coarsen_count =
349  std::min(cast_int<dof_id_type>(-n_elem_new / (twotodim-1)),
350  max_elem_coarsen);
351  }
352 
353  // Next, let's see if we can trade any refinement for coarsening
354  while (coarsen_count < max_elem_coarsen &&
355  refine_count < max_elem_refine &&
356  coarsen_count < sorted_parent_error.size() &&
357  refine_count < sorted_error.size() &&
358  sorted_error[refine_count].first >
359  sorted_parent_error[coarsen_count].first * _coarsen_threshold)
360  {
361  coarsen_count++;
362  refine_count++;
363  }
364 
365  // On a DistributedMesh, we need to communicate to know which remote ids
366  // correspond to refinable elements
367  dof_id_type successful_refine_count = 0;
368  {
369  std::vector<bool> is_refinable(max_elem_id, false);
370 
371  for (const auto & pr : sorted_error)
372  {
373  dof_id_type eid = pr.second;
374  Elem * elem = _mesh.query_elem_ptr(eid);
375  if (elem && elem->level() < _max_h_level)
376  is_refinable[eid] = true;
377  }
378  this->comm().max(is_refinable);
379 
380  if (refine_count > max_elem_refine)
381  refine_count = max_elem_refine;
382  for (const auto & pr : sorted_error)
383  {
384  if (successful_refine_count >= refine_count)
385  break;
386 
387  dof_id_type eid = pr.second;
388  Elem * elem = _mesh.query_elem_ptr(eid);
389  if (is_refinable[eid])
390  {
391  if (elem)
393  successful_refine_count++;
394  }
395  }
396  }
397 
398  // If we couldn't refine enough elements, don't coarsen too many
399  // either
400  if (coarsen_count < (refine_count - successful_refine_count))
401  coarsen_count = 0;
402  else
403  coarsen_count -= (refine_count - successful_refine_count);
404 
405  if (coarsen_count > max_elem_coarsen)
406  coarsen_count = max_elem_coarsen;
407 
408  dof_id_type successful_coarsen_count = 0;
409  if (coarsen_count)
410  {
411  for (const auto & pr : sorted_parent_error)
412  {
413  if (successful_coarsen_count >= coarsen_count * twotodim)
414  break;
415 
416  dof_id_type parent_id = pr.second;
417  Elem * parent = _mesh.query_elem_ptr(parent_id);
418 
419  // On a DistributedMesh we skip remote elements
420  if (!parent)
421  continue;
422 
423  libmesh_assert(parent->has_children());
424  for (auto & elem : parent->child_ref_range())
425  {
426  if (&elem != remote_elem)
427  {
428  libmesh_assert(elem.active());
429  elem.set_refinement_flag(Elem::COARSEN);
430  successful_coarsen_count++;
431  }
432  }
433  }
434  }
435 
436  // Return true if we've done all the AMR/C we can
437  if (!successful_coarsen_count &&
438  !successful_refine_count)
439  return true;
440  // And false if there may still be more to do.
441  return false;
442 }

References _coarsen_by_parents, _coarsen_fraction, _coarsen_threshold, _max_h_level, _mesh, _nelem_target, _refine_fraction, libMesh::MeshBase::active_local_element_ptr_range(), 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(), 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().

◆ 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.

Definition at line 941 of file mesh_refinement.h.

942 {
943  libmesh_deprecated();
945 }

References enforce_mismatch_limit_prior_to_refinement().

◆ get_mesh() [1/2]

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

Definition at line 333 of file mesh_refinement.h.

333 { return _mesh; }

References _mesh.

◆ get_mesh() [2/2]

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

Definition at line 327 of file mesh_refinement.h.

327 { return _mesh; }

References _mesh.

◆ has_topological_neighbor()

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

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

Definition at line 1807 of file mesh_refinement.C.

1810 {
1811 #ifdef LIBMESH_ENABLE_PERIODIC
1812  if (_periodic_boundaries && !_periodic_boundaries->empty())
1813  {
1814  libmesh_assert(point_locator);
1815  return elem->has_topological_neighbor(neighbor, _mesh, *point_locator, _periodic_boundaries);
1816  }
1817 #endif
1818  return elem->has_neighbor(neighbor);
1819 }

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().

◆ 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.

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  // Loop over all the active elements & fill the maps
141  for (auto & elem : _mesh.active_element_ptr_range())
142  {
143  const unsigned char elem_level =
144  cast_int<unsigned char>(elem->level() +
145  ((elem->refinement_flag() == Elem::REFINE) ? 1 : 0));
146  const unsigned char elem_p_level =
147  cast_int<unsigned char>(elem->p_level() +
148  ((elem->p_refinement_flag() == Elem::REFINE) ? 1 : 0));
149 
150  // Set the max_level at each edge
151  for (auto n : elem->edge_index_range())
152  {
153  std::unique_ptr<const Elem> edge = elem->build_edge_ptr(n);
154  dof_id_type childnode0 = edge->node_id(0);
155  dof_id_type childnode1 = edge->node_id(1);
156  if (childnode1 < childnode0)
157  std::swap(childnode0, childnode1);
158 
159  for (const Elem * p = elem; p != nullptr; p = p->parent())
160  {
161  std::unique_ptr<const Elem> pedge = p->build_edge_ptr(n);
162  dof_id_type node0 = pedge->node_id(0);
163  dof_id_type node1 = pedge->node_id(1);
164 
165  if (node1 < node0)
166  std::swap(node0, node1);
167 
168  // If elem does not share this edge with its ancestor
169  // p, refinement levels of elements sharing p's edge
170  // are not restricted by refinement levels of elem.
171  // Furthermore, elem will not share this edge with any
172  // of p's ancestors, so we can safely break out of the
173  // for loop early.
174  if (node0 != childnode0 && node1 != childnode1)
175  break;
176 
177  childnode0 = node0;
178  childnode1 = node1;
179 
180  std::pair<unsigned int, unsigned int> edge_key =
181  std::make_pair(node0, node1);
182 
183  if (max_level_at_edge.find(edge_key) ==
184  max_level_at_edge.end())
185  {
186  max_level_at_edge[edge_key] = elem_level;
187  max_p_level_at_edge[edge_key] = elem_p_level;
188  }
189  else
190  {
191  max_level_at_edge[edge_key] =
192  std::max (max_level_at_edge[edge_key], elem_level);
193  max_p_level_at_edge[edge_key] =
194  std::max (max_p_level_at_edge[edge_key], elem_p_level);
195  }
196  }
197  }
198  }
199 
200 
201  // Now loop over the active elements and flag the elements
202  // who violate the requested level mismatch
203  for (auto & elem : _mesh.active_element_ptr_range())
204  {
205  const unsigned int elem_level = elem->level();
206  const unsigned int elem_p_level = elem->p_level();
207 
208  // Skip the element if it is already fully flagged
209  if (elem->refinement_flag() == Elem::REFINE &&
210  elem->p_refinement_flag() == Elem::REFINE
212  continue;
213 
214  // Loop over the nodes, check for possible mismatch
215  for (auto n : elem->edge_index_range())
216  {
217  std::unique_ptr<Elem> edge = elem->build_edge_ptr(n);
218  dof_id_type node0 = edge->node_id(0);
219  dof_id_type node1 = edge->node_id(1);
220  if (node1 < node0)
221  std::swap(node0, node1);
222 
223  std::pair<dof_id_type, dof_id_type> edge_key =
224  std::make_pair(node0, node1);
225 
226  // Flag the element for refinement if it violates
227  // the requested level mismatch
228  if ((elem_level + max_mismatch) < max_level_at_edge[edge_key]
229  && elem->refinement_flag() != Elem::REFINE)
230  {
231  elem->set_refinement_flag (Elem::REFINE);
232  flags_changed = true;
233  }
234 
235  if ((elem_p_level + max_mismatch) < max_p_level_at_edge[edge_key]
236  && elem->p_refinement_flag() != Elem::REFINE)
237  {
238  elem->set_p_refinement_flag (Elem::REFINE);
239  flags_changed = true;
240  }
241 
242  // Possibly enforce limit mismatch prior to refinement
243  flags_changed |= this->enforce_mismatch_limit_prior_to_refinement(elem, EDGE, max_mismatch);
244  } // loop over edges
245  } // loop over active elements
246 
247  // If flags changed on any processor then they changed globally
248  this->comm().max(flags_changed);
249 
250  return flags_changed;
251 }

References _enforce_mismatch_limit_prior_to_refinement, _mesh, libMesh::MeshBase::active_element_ptr_range(), libMesh::ParallelObject::comm(), EDGE, enforce_mismatch_limit_prior_to_refinement(), libMesh::Elem::parent(), libMesh::Elem::REFINE, and swap().

Referenced by _smooth_flags().

◆ 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.

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 }

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

Referenced by _smooth_flags().

◆ limit_overrefined_boundary()

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

Definition at line 255 of file mesh_refinement_smoothing.C.

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

References _mesh, libMesh::MeshBase::active_element_ptr_range(), libMesh::ParallelObject::comm(), and libMesh::Elem::REFINE.

Referenced by _smooth_flags().

◆ limit_underrefined_boundary()

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

Definition at line 309 of file mesh_refinement_smoothing.C.

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

References _mesh, libMesh::MeshBase::active_element_ptr_range(), libMesh::ParallelObject::comm(), and libMesh::Elem::REFINE.

Referenced by _smooth_flags().

◆ 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 780 of file mesh_refinement.C.

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

References _face_level_mismatch_limit, _mesh, _periodic_boundaries, libMesh::Elem::active(), libMesh::MeshBase::active_element_ptr_range(), libMesh::MeshBase::ancestor_elements_begin(), libMesh::MeshBase::ancestor_elements_end(), 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(), libMesh::Elem::has_children(), has_topological_neighbor(), libMesh::Elem::INACTIVE, libMesh::MeshBase::is_replicated(), libMesh::MeshBase::is_serial(), libMesh::Elem::level(), libMesh::MeshBase::level_elements_begin(), libMesh::MeshBase::level_elements_end(), libMesh::libmesh_assert(), libMesh::MeshTools::max_level(), libMesh::ParallelObject::n_processors(), libMesh::MeshBase::not_local_elements_begin(), libMesh::MeshBase::not_local_elements_end(), libMesh::Elem::p_level(), libMesh::Elem::p_refinement_flag(), libMesh::ParallelObject::processor_id(), libMesh::DofObject::processor_id(), 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(), libMesh::Parallel::sync_dofobject_data_by_id(), and topological_neighbor().

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

◆ 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 752 of file mesh_refinement.C.

753 {
754  // This function must be run on all processors at once
755  parallel_object_only();
756 
757  LOG_SCOPE ("make_flags_parallel_consistent()", "MeshRefinement");
758 
759  SyncRefinementFlags hsync(_mesh, &Elem::refinement_flag,
762  (this->comm(), _mesh.elements_begin(), _mesh.elements_end(), hsync);
763 
764  SyncRefinementFlags psync(_mesh, &Elem::p_refinement_flag,
767  (this->comm(), _mesh.elements_begin(), _mesh.elements_end(), psync);
768 
769  // If we weren't consistent in both h and p on every processor then
770  // we weren't globally consistent
771  bool parallel_consistent = hsync.parallel_consistent &&
772  psync.parallel_consistent;
773  this->comm().min(parallel_consistent);
774 
775  return parallel_consistent;
776 }

References _mesh, libMesh::ParallelObject::comm(), libMesh::MeshBase::elements_begin(), libMesh::MeshBase::elements_end(), 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().

◆ 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 1160 of file mesh_refinement.C.

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

References _face_level_mismatch_limit, _mesh, _periodic_boundaries, libMesh::Elem::active(), libMesh::MeshBase::active_element_ptr_range(), 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(), 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().

◆ 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 891 of file mesh_refinement.h.

892 {
893  _use_member_parameters = true;
894  return _max_h_level;
895 }

References _max_h_level, and _use_member_parameters.

Referenced by assemble_and_solve(), and main().

◆ n_processors()

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

Definition at line 100 of file parallel_object.h.

101  { return cast_int<processor_id_type>(_communicator.size()); }

References libMesh::ParallelObject::_communicator.

Referenced by 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::LaplaceMeshSmoother::allgather_graph(), libMesh::DofMap::allgather_recursive_constraints(), libMesh::FEMSystem::assembly(), libMesh::AztecLinearSolver< T >::AztecLinearSolver(), libMesh::BoundaryInfo::build_node_list_from_side_list(), libMesh::EquationSystems::build_parallel_elemental_solution_vector(), libMesh::DistributedMesh::clear(), libMesh::Nemesis_IO_Helper::compute_border_node_ids(), libMesh::Nemesis_IO_Helper::construct_nemesis_filename(), libMesh::ExodusII_IO::copy_scalar_solution(), libMesh::UnstructuredMesh::create_pid_mesh(), libMesh::MeshTools::create_processor_bounding_box(), libMesh::DofMap::distribute_dofs(), libMesh::DofMap::distribute_local_dofs_node_major(), libMesh::DofMap::distribute_local_dofs_var_major(), libMesh::EnsightIO::EnsightIO(), libMesh::SystemSubsetBySubdomain::init(), libMesh::PetscDMWrapper::init_and_attach_petscdm(), libMesh::Nemesis_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::partition(), libMesh::System::point_gradient(), libMesh::System::point_hessian(), libMesh::System::point_value(), libMesh::DofMap::prepare_send_list(), 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(), OverlappingFunctorTest::run_partitioner_test(), libMesh::DofMap::scatter_constraints(), libMesh::DofMap::set_nonlocal_dof_objects(), libMesh::PetscDMWrapper::set_point_range_in_section(), CheckpointIOTest::testSplitter(), WriteVecAndScalar::testWrite(), uniformly_coarsen(), libMesh::DistributedMesh::update_parallel_id_counts(), libMesh::GMVIO::write_binary(), libMesh::GMVIO::write_discontinuous_gmv(), libMesh::VTKIO::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().

◆ 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 903 of file mesh_refinement.h.

904 {
905  _use_member_parameters = true;
906  return _nelem_target;
907 }

References _nelem_target, and _use_member_parameters.

Referenced by build_mesh_refinement(), and main().

◆ 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 925 of file mesh_refinement.h.

926 {
928 }

References _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 930 of file mesh_refinement.h.

931 {
933 }

References _overrefined_boundary_limit.

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

◆ processor_id()

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

Definition at line 106 of file parallel_object.h.

107  { return cast_int<processor_id_type>(_communicator.rank()); }

References libMesh::ParallelObject::_communicator.

Referenced by libMesh::BoundaryInfo::_find_id_maps(), libMesh::EquationSystems::_read_impl(), 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::UnstructuredMesh::all_second_order(), libMesh::MeshTools::Modification::all_tri(), libMesh::DofMap::allgather_recursive_constraints(), libMesh::FEMSystem::assembly(), libMesh::Nemesis_IO_Helper::build_element_and_node_maps(), libMesh::InfElemBuilder::build_inf_elem(), libMesh::BoundaryInfo::build_node_list_from_side_list(), libMesh::EquationSystems::build_parallel_elemental_solution_vector(), libMesh::DistributedMesh::clear(), 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_scalar_solution(), libMesh::MeshTools::correct_node_proc_ids(), libMesh::ExodusII_IO_Helper::create(), libMesh::DistributedMesh::delete_elem(), libMesh::DistributedMesh::delete_node(), libMesh::MeshCommunication::delete_remote_elements(), libMesh::DofMap::distribute_dofs(), libMesh::DofMap::distribute_local_dofs_node_major(), libMesh::DofMap::distribute_local_dofs_var_major(), libMesh::DistributedMesh::DistributedMesh(), libMesh::DofMap::end_dof(), libMesh::DofMap::end_old_dof(), libMesh::EnsightIO::EnsightIO(), libMesh::RBEIMConstruction::evaluate_mesh_function(), libMesh::MeshFunction::find_element(), libMesh::MeshFunction::find_elements(), libMesh::UnstructuredMesh::find_neighbors(), libMesh::DofMap::first_dof(), libMesh::DofMap::first_old_dof(), 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::DofMap::get_info(), libMesh::Nemesis_IO_Helper::get_init_global(), libMesh::Nemesis_IO_Helper::get_init_info(), libMesh::Nemesis_IO_Helper::get_loadbal_param(), libMesh::DofMap::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::SystemSubsetBySubdomain::init(), libMesh::PetscDMWrapper::init_and_attach_petscdm(), 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::DofMap::last_dof(), libMesh::TransientRBEvaluation::legacy_write_offline_data_to_files(), libMesh::RBEIMEvaluation::legacy_write_offline_data_to_files(), libMesh::RBEvaluation::legacy_write_offline_data_to_files(), libMesh::RBSCMEvaluation::legacy_write_offline_data_to_files(), libMesh::RBEIMEvaluation::legacy_write_out_interpolation_points_elem(), 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::MeshBase::n_active_local_elem(), libMesh::BoundaryInfo::n_boundary_conds(), libMesh::BoundaryInfo::n_edge_conds(), libMesh::DofMap::n_local_dofs(), libMesh::System::n_local_dofs(), libMesh::MeshBase::n_local_elem(), libMesh::MeshBase::n_local_nodes(), libMesh::BoundaryInfo::n_nodeset_conds(), libMesh::BoundaryInfo::n_shellface_conds(), libMesh::SparsityPattern::Build::operator()(), libMesh::DistributedMesh::own_node(), libMesh::System::point_gradient(), libMesh::System::point_hessian(), libMesh::System::point_value(), libMesh::DofMap::print_dof_constraints(), 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::ExodusII_IO_Helper::read_elem_num_map(), libMesh::ExodusII_IO_Helper::read_global_values(), libMesh::CheckpointIO::read_header(), libMesh::XdrIO::read_header(), libMesh::System::read_header(), libMesh::RBEvaluation::read_in_vectors_from_multiple_files(), libMesh::System::read_legacy_data(), 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::DistributedMesh::renumber_dof_objects(), libMesh::DofMap::scatter_constraints(), libMesh::CheckpointIO::select_split_config(), libMesh::DofMap::set_nonlocal_dof_objects(), libMesh::PetscDMWrapper::set_point_range_in_section(), libMesh::LaplaceMeshSmoother::smooth(), DefaultCouplingTest::testCoupling(), PointNeighborCouplingTest::testCoupling(), MeshInputTest::testDynaReadElem(), MeshInputTest::testDynaReadPatch(), MeshInputTest::testExodusCopyElementSolution(), MeshInputTest::testExodusWriteElementDataFromDiscontinuousNodalData(), SystemsTest::testProjectMatrix1D(), SystemsTest::testProjectMatrix2D(), SystemsTest::testProjectMatrix3D(), BoundaryInfoTest::testShellFaceConstraints(), CheckpointIOTest::testSplitter(), WriteVecAndScalar::testWrite(), libMesh::MeshTools::total_weight(), uniformly_coarsen(), libMesh::Parallel::Packing< Node * >::unpack(), libMesh::Parallel::Packing< Elem * >::unpack(), libMesh::DistributedMesh::update_parallel_id_counts(), libMesh::DTKAdapter::update_variable_values(), 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::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::VTKIO::write_nodal_data(), libMesh::UCDIO::write_nodal_data(), libMesh::ExodusII_IO::write_nodal_data(), libMesh::ExodusII_IO::write_nodal_data_discontinuous(), libMesh::ExodusII_IO_Helper::write_nodal_values(), libMesh::Nemesis_IO_Helper::write_nodesets(), libMesh::ExodusII_IO_Helper::write_nodesets(), libMesh::RBEvaluation::write_out_vectors(), 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().

◆ 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.

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 
573  _mesh.prepare_for_use (/*skip_renumber =*/false);
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 }

References _coarsen_elements(), _face_level_mismatch_limit, _mesh, _refine_elements(), _smooth_flags(), libMesh::Elem::COARSEN, libMesh::ParallelObject::comm(), libMesh::Elem::DO_NOTHING, libMesh::MeshBase::element_ptr_range(), 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(), 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().

◆ 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 683 of file mesh_refinement.C.

684 {
685  // This function must be run on all processors at once
686  parallel_object_only();
687 
690 
691  // Possibly clean up the refinement flags from
692  // a previous step
693  for (auto & elem : _mesh.element_ptr_range())
694  {
695  // Set refinement flag to INACTIVE if the
696  // element isn't active
697  if (!elem->active())
698  {
699  elem->set_refinement_flag(Elem::INACTIVE);
700  elem->set_p_refinement_flag(Elem::INACTIVE);
701  }
702 
703  // This might be left over from the last step
704  if (elem->refinement_flag() == Elem::JUST_REFINED)
705  elem->set_refinement_flag(Elem::DO_NOTHING);
706  }
707 
708 
709 
710  // Parallel consistency has to come first, or coarsening
711  // along processor boundaries might occasionally be falsely
712  // prevented
713  bool flags_were_consistent = this->make_flags_parallel_consistent();
714 
715  // In theory, we should be able to remove the above call, which can
716  // be expensive and should be unnecessary. In practice, doing
717  // consistent flagging in parallel is hard, it's impossible to
718  // verify at the library level if it's being done by user code, and
719  // we don't want to abort large parallel runs in opt mode... but we
720  // do want to warn that they should be fixed.
721  libmesh_assert(flags_were_consistent);
722  if (!flags_were_consistent)
723  {
724  libMesh::out << "Refinement flags were not consistent between processors!\n"
725  << "Correcting and continuing.";
726  }
727 
728  // Smooth refinement flags
729  _smooth_flags(true, false);
730 
731  // Now refine the flagged elements. This will
732  // take up some space, maybe more than what was freed.
733  const bool mesh_changed =
734  this->_refine_elements();
735 
739  // FIXME: This won't pass unless we add a redundant find_neighbors()
740  // call or replace find_neighbors() with on-the-fly neighbor updating
741  // libmesh_assert(!this->eliminate_unrefined_patches());
742 
743  // Finally, the new mesh needs to be prepared for use
744  if (mesh_changed)
745  _mesh.prepare_for_use (/*skip_renumber =*/false);
746 
747  return mesh_changed;
748 }

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

Referenced by main(), libMesh::EquationSystems::reinit_solutions(), and EquationSystemsTest::testRefineThenReinitPreserveFlags().

◆ 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 879 of file mesh_refinement.h.

880 {
881  _use_member_parameters = true;
882  return _refine_fraction;
883 }

References _refine_fraction, and _use_member_parameters.

Referenced by assemble_and_solve(), build_mesh_refinement(), and main().

◆ 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.

Definition at line 947 of file mesh_refinement.h.

948 {
949  libmesh_deprecated();
951 }

References enforce_mismatch_limit_prior_to_refinement().

◆ 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 655 of file mesh_refinement_flagging.C.

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

References _mesh, libMesh::Elem::DO_NOTHING, libMesh::MeshBase::element_ptr_range(), and libMesh::Elem::INACTIVE.

Referenced by main().

◆ test_level_one()

bool libMesh::MeshRefinement::test_level_one ( bool  libmesh_assert_yes = false)
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.

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 }

References _mesh, _periodic_boundaries, libMesh::Elem::active(), libMesh::MeshBase::active_local_element_ptr_range(), libMesh::ParallelObject::comm(), libMesh::Elem::level(), libMesh::libmesh_assert(), 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().

◆ test_unflagged()

bool libMesh::MeshRefinement::test_unflagged ( bool  libmesh_assert_yes = false)
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.

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 }

References _mesh, libMesh::MeshBase::active_local_element_ptr_range(), libMesh::Elem::COARSEN, libMesh::ParallelObject::comm(), libMesh::libmesh_assert(), libMesh::out, and libMesh::Elem::REFINE.

Referenced by refine_and_coarsen_elements().

◆ topological_neighbor()

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

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

Definition at line 1791 of file mesh_refinement.C.

1794 {
1795 #ifdef LIBMESH_ENABLE_PERIODIC
1796  if (_periodic_boundaries && !_periodic_boundaries->empty())
1797  {
1798  libmesh_assert(point_locator);
1799  return elem->topological_neighbor(side, _mesh, *point_locator, _periodic_boundaries);
1800  }
1801 #endif
1802  return elem->neighbor_ptr(side);
1803 }

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().

◆ 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 935 of file mesh_refinement.h.

936 {
938 }

References _underrefined_boundary_limit.

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

◆ uniformly_coarsen()

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

Attempts to uniformly coarsen the mesh n times.

Definition at line 1703 of file mesh_refinement.C.

1704 {
1705  // Coarsen n times
1706  for (unsigned int rstep=0; rstep<n; rstep++)
1707  {
1708  // Clean up the refinement flags
1709  this->clean_refinement_flags();
1710 
1711  // Flag all the active elements for coarsening.
1712  for (auto & elem : _mesh.active_element_ptr_range())
1713  {
1714  elem->set_refinement_flag(Elem::COARSEN);
1715  if (elem->parent())
1716  elem->parent()->set_refinement_flag(Elem::COARSEN_INACTIVE);
1717  }
1718 
1719  // On a distributed mesh, we may have parent elements with
1720  // remote active children. To keep flags consistent, we'll need
1721  // a communication step.
1722  if (!_mesh.is_replicated())
1723  {
1724  const processor_id_type n_proc = _mesh.n_processors();
1725  const processor_id_type my_proc_id = _mesh.processor_id();
1726 
1727  std::vector<std::vector<dof_id_type>>
1728  parents_to_coarsen(n_proc);
1729 
1730  for (const auto & elem : as_range(_mesh.ancestor_elements_begin(), _mesh.ancestor_elements_end()))
1731  if (elem->processor_id() != my_proc_id &&
1732  elem->refinement_flag() == Elem::COARSEN_INACTIVE)
1733  parents_to_coarsen[elem->processor_id()].push_back(elem->id());
1734 
1735  Parallel::MessageTag
1736  coarsen_tag = this->comm().get_unique_tag();
1737  std::vector<Parallel::Request> coarsen_push_requests(n_proc-1);
1738 
1739  for (processor_id_type p = 0; p != n_proc; ++p)
1740  {
1741  if (p == my_proc_id)
1742  continue;
1743 
1744  Parallel::Request &request =
1745  coarsen_push_requests[p - (p > my_proc_id)];
1746 
1747  _mesh.comm().send
1748  (p, parents_to_coarsen[p], request, coarsen_tag);
1749  }
1750 
1751  for (processor_id_type p = 1; p != n_proc; ++p)
1752  {
1753  std::vector<dof_id_type> my_parents_to_coarsen;
1754  _mesh.comm().receive
1755  (Parallel::any_source, my_parents_to_coarsen,
1756  coarsen_tag);
1757 
1758  for (const auto & id : my_parents_to_coarsen)
1759  {
1760  Elem & elem = _mesh.elem_ref(id);
1761  libmesh_assert(elem.refinement_flag() == Elem::INACTIVE ||
1762  elem.refinement_flag() == Elem::COARSEN_INACTIVE);
1763  elem.set_refinement_flag(Elem::COARSEN_INACTIVE);
1764  }
1765  }
1766 
1767  Parallel::wait(coarsen_push_requests);
1768 
1769  SyncRefinementFlags hsync(_mesh, &Elem::refinement_flag,
1772  (this->comm(), _mesh.not_local_elements_begin(),
1774  // We'd like a smaller sync, but this leads to bugs?
1775  // SyncCoarsenInactive(),
1776  hsync);
1777  }
1778 
1779  // Coarsen all the elements we just flagged.
1780  this->_coarsen_elements();
1781  }
1782 
1783 
1784  // Finally, the new mesh probably needs to be prepared for use
1785  if (n > 0)
1786  _mesh.prepare_for_use (/*skip_renumber =*/false);
1787 }

References _coarsen_elements(), _mesh, libMesh::MeshBase::active_element_ptr_range(), libMesh::MeshBase::ancestor_elements_begin(), libMesh::MeshBase::ancestor_elements_end(), libMesh::as_range(), clean_refinement_flags(), libMesh::Elem::COARSEN, libMesh::Elem::COARSEN_INACTIVE, libMesh::ParallelObject::comm(), libMesh::MeshBase::elem_ref(), libMesh::Elem::INACTIVE, libMesh::MeshBase::is_replicated(), libMesh::libmesh_assert(), libMesh::ParallelObject::n_processors(), libMesh::MeshBase::not_local_elements_begin(), libMesh::MeshBase::not_local_elements_end(), libMesh::MeshBase::prepare_for_use(), libMesh::ParallelObject::processor_id(), libMesh::Elem::refinement_flag(), 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_and_attach_petscdm().

◆ 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 1663 of file mesh_refinement.C.

1664 {
1665  // Coarsen p times
1666  for (unsigned int rstep=0; rstep<n; rstep++)
1667  for (auto & elem : _mesh.active_element_ptr_range())
1668  if (elem->p_level() > 0)
1669  {
1670  // P coarsen all the active elements
1671  elem->set_p_level(elem->p_level()-1);
1672  elem->set_p_refinement_flag(Elem::JUST_COARSENED);
1673  }
1674 }

References _mesh, libMesh::MeshBase::active_element_ptr_range(), and libMesh::Elem::JUST_COARSENED.

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

◆ uniformly_p_refine()

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

Uniformly p refines the mesh n times.

Definition at line 1649 of file mesh_refinement.C.

1650 {
1651  // Refine n times
1652  for (unsigned int rstep=0; rstep<n; rstep++)
1653  for (auto & elem : _mesh.active_element_ptr_range())
1654  {
1655  // P refine all the active elements
1656  elem->set_p_level(elem->p_level()+1);
1657  elem->set_p_refinement_flag(Elem::JUST_REFINED);
1658  }
1659 }

References _mesh, libMesh::MeshBase::active_element_ptr_range(), and libMesh::Elem::JUST_REFINED.

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

◆ uniformly_refine()

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

Uniformly refines the mesh n times.

Definition at line 1678 of file mesh_refinement.C.

1679 {
1680  // Refine n times
1681  // FIXME - this won't work if n>1 and the mesh
1682  // has already been attached to an equation system
1683  for (unsigned int rstep=0; rstep<n; rstep++)
1684  {
1685  // Clean up the refinement flags
1686  this->clean_refinement_flags();
1687 
1688  // Flag all the active elements for refinement.
1689  for (auto & elem : _mesh.active_element_ptr_range())
1690  elem->set_refinement_flag(Elem::REFINE);
1691 
1692  // Refine all the elements we just flagged.
1693  this->_refine_elements();
1694  }
1695 
1696  // Finally, the new mesh probably needs to be prepared for use
1697  if (n > 0)
1698  _mesh.prepare_for_use (/*skip_renumber =*/false);
1699 }

References _mesh, _refine_elements(), libMesh::MeshBase::active_element_ptr_range(), 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_and_attach_petscdm(), main(), OverlappingFunctorTest::run_coupling_functor_test(), OverlappingFunctorTest::run_partitioner_test(), SlitMeshRefinedMeshTest::setUp(), MixedDimensionRefinedMeshTest::setUp(), SlitMeshRefinedSystemTest::setUp(), BoundaryRefinedMeshTest::setUp(), ExtraIntegersTest::test_helper(), SystemsTest::testProjectMatrix1D(), SystemsTest::testProjectMatrix2D(), and SystemsTest::testProjectMatrix3D().

◆ update_nodes_map()

void libMesh::MeshRefinement::update_nodes_map ( )
private

Updates the _new_nodes_map.

Definition at line 346 of file mesh_refinement.C.

347 {
348  this->_new_nodes_map.init(_mesh);
349 }

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

Referenced by _coarsen_elements(), and _refine_elements().

Member Data Documentation

◆ _absolute_global_tolerance

Real libMesh::MeshRefinement::_absolute_global_tolerance
private

◆ _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 773 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 847 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 768 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 740 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 774 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 776 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 777 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 752 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:
libMesh::MeshRefinement::_node_level_mismatch_limit
unsigned char _node_level_mismatch_limit
Definition: mesh_refinement.h:774
libMesh::dof_id_type
uint8_t dof_id_type
Definition: id_types.h:67
libMesh::MeshRefinement::_coarsen_threshold
Real _coarsen_threshold
Definition: mesh_refinement.h:766
libMesh::invalid_uint
const unsigned int invalid_uint
A number which is used quite often to represent an invalid or uninitialized value.
Definition: libmesh.h:249
libMesh::MeshRefinement::_edge_level_mismatch_limit
unsigned char _edge_level_mismatch_limit
Definition: mesh_refinement.h:773
libMesh::MeshRefinement::_mesh
MeshBase & _mesh
Reference to the mesh.
Definition: mesh_refinement.h:745
libMesh::Elem::set_p_refinement_flag
void set_p_refinement_flag(const RefinementState pflag)
Sets the value of the p-refinement flag for the element.
Definition: elem.h:2638
libMesh::Elem::JUST_REFINED
Definition: elem.h:1172
libMesh::MeshBase::get_boundary_info
const BoundaryInfo & get_boundary_info() const
The information about boundary ids on the mesh.
Definition: mesh_base.h:132
libMesh::MeshRefinement::eliminate_unrefined_patches
bool eliminate_unrefined_patches()
This algorithm selects an element for refinement if all of its neighbors are (or will be) refined.
Definition: mesh_refinement_smoothing.C:368
libMesh::MeshRefinement::_coarsen_by_parents
bool _coarsen_by_parents
Refinement parameter values.
Definition: mesh_refinement.h:758
libMesh::MeshBase::is_serial
virtual bool is_serial() const
Definition: mesh_base.h:159
libMesh::MeshBase::libmesh_assert_valid_parallel_ids
virtual void libmesh_assert_valid_parallel_ids() const
Verify id and processor_id consistency of our elements and nodes containers.
Definition: mesh_base.h:1297
libMesh::MeshRefinement::_refine_elements
bool _refine_elements()
Refines user-requested elements.
Definition: mesh_refinement.C:1462
libMesh::MeshRefinement::_underrefined_boundary_limit
signed char _underrefined_boundary_limit
Definition: mesh_refinement.h:777
libMesh::MeshBase::active_local_element_ptr_range
virtual SimpleRange< element_iterator > active_local_element_ptr_range()=0
libMesh::Elem::COARSEN
Definition: elem.h:1169
libMesh::MeshRefinement::_coarsen_fraction
Real _coarsen_fraction
Definition: mesh_refinement.h:762
libMesh::MeshRefinement::_overrefined_boundary_limit
signed char _overrefined_boundary_limit
Definition: mesh_refinement.h:776
libMesh::MeshBase::active_element_ptr_range
virtual SimpleRange< element_iterator > active_element_ptr_range()=0
libMesh::MeshBase::elem_ref
virtual const Elem & elem_ref(const dof_id_type i) const
Definition: mesh_base.h:521
libMesh::ErrorVectorReal
DIE A HORRIBLE DEATH HERE typedef float ErrorVectorReal
Definition: libmesh_common.h:206
libMesh::index_range
IntRange< std::size_t > index_range(const std::vector< T > &vec)
Helper function that returns an IntRange<std::size_t> representing all the indices of the passed-in v...
Definition: int_range.h:106
libMesh::MeshBase::max_elem_id
virtual dof_id_type max_elem_id() const =0
libMesh::Elem::COARSEN_INACTIVE
Definition: elem.h:1175
libMesh::MeshRefinement::make_flags_parallel_consistent
bool make_flags_parallel_consistent()
Copy refinement flags on ghost elements from their local processors.
Definition: mesh_refinement.C:752
libMesh::MeshTools::libmesh_assert_valid_neighbors
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:2061
std::sqrt
MetaPhysicL::DualNumber< T, D > sqrt(const MetaPhysicL::DualNumber< T, D > &in)
libMesh::ParallelObject::comm
const Parallel::Communicator & comm() const
Definition: parallel_object.h:94
libMesh::MeshTools::max_level
unsigned int max_level(const MeshBase &mesh)
Find the maximum h-refinement level in a mesh.
libMesh::Elem::RefinementState
RefinementState
Enumeration of possible element refinement states.
Definition: elem.h:1169
libMesh::MeshRefinement::_max_h_level
unsigned int _max_h_level
Definition: mesh_refinement.h:764
libMesh::MeshBase::node_ptr
virtual const Node * node_ptr(const dof_id_type i) const =0
libMesh::MeshBase::mesh_dimension
unsigned int mesh_dimension() const
Definition: mesh_base.C:135
libMesh::MeshBase::not_local_elements_begin
virtual element_iterator not_local_elements_begin()=0
libMesh::MeshRefinement::limit_overrefined_boundary
bool limit_overrefined_boundary(const signed char max_mismatch)
Definition: mesh_refinement_smoothing.C:255
libMesh::DofObject::processor_id
processor_id_type processor_id() const
Definition: dof_object.h:829
libMesh::MeshBase::elements_begin
virtual element_iterator elements_begin()=0
Iterate over all the elements in the Mesh.
libMesh::Elem::active
bool active() const
Definition: elem.h:2345
libMesh::BoundaryInfo::remove
void remove(const Node *node)
Removes the boundary conditions associated with node node, if any exist.
Definition: boundary_info.C:1358
dim
unsigned int dim
Definition: adaptivity_ex3.C:113
libMesh::MeshRefinement::_smooth_flags
void _smooth_flags(bool refining, bool coarsening)
Smooths refinement flags according to current settings.
Definition: mesh_refinement.C:1594
libMesh::MeshBase::query_elem_ptr
virtual const Elem * query_elem_ptr(const dof_id_type i) const =0
libMesh::MeshRefinement::_coarsen_elements
bool _coarsen_elements()
Coarsens user-requested elements.
Definition: mesh_refinement.C:1336
libMesh::MeshBase::element_ptr_range
virtual SimpleRange< element_iterator > element_ptr_range()=0
libMesh::libmesh_assert
libmesh_assert(ctx)
libMesh::ParallelObject::ParallelObject
ParallelObject(const Parallel::Communicator &comm_in)
Constructor.
Definition: parallel_object.h:63
libMesh::MeshRefinement::_absolute_global_tolerance
Real _absolute_global_tolerance
Definition: mesh_refinement.h:770
libMesh::MeshRefinement::_face_level_mismatch_limit
unsigned char _face_level_mismatch_limit
Definition: mesh_refinement.h:772
libMesh::MeshRefinement::make_refinement_compatible
bool make_refinement_compatible()
Take user-specified refinement flags and augment them so that level-one dependency is satisfied.
Definition: mesh_refinement.C:1160
libMesh::MeshBase::level_elements_begin
virtual element_iterator level_elements_begin(unsigned int level)=0
Iterate over elements of a given level.
libMesh::MeshRefinement::clear
void clear()
Deletes all the data that are currently stored.
Definition: mesh_refinement.C:135
libMesh::ParallelObject::n_processors
processor_id_type n_processors() const
Definition: parallel_object.h:100
libMesh::Elem::p_refinement_flag
RefinementState p_refinement_flag() const
Definition: elem.h:2630
libMesh::MeshRefinement::_new_nodes_map
TopologyMap _new_nodes_map
Data structure that holds the new nodes information.
Definition: mesh_refinement.h:740
libMesh::MeshRefinement::create_parent_error_vector
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.
Definition: mesh_refinement.C:220
libMesh::ParallelObject::processor_id
processor_id_type processor_id() const
Definition: parallel_object.h:106
libMesh::DofObject::invalid_id
static const dof_id_type invalid_id
An invalid id to distinguish an uninitialized DofObject.
Definition: dof_object.h:421
libMesh::ParallelObject::_communicator
const Parallel::Communicator & _communicator
Definition: parallel_object.h:112
libMesh::MeshRefinement::limit_underrefined_boundary
bool limit_underrefined_boundary(const signed char max_mismatch)
Definition: mesh_refinement_smoothing.C:309
libMesh::processor_id_type
uint8_t processor_id_type
Definition: id_types.h:104
libMesh::MeshBase::ancestor_elements_end
virtual element_iterator ancestor_elements_end()=0
libMesh::TypeVector::add_scaled
void add_scaled(const TypeVector< T2 > &, const T &)
Add a scaled value to this vector without creating a temporary.
Definition: type_vector.h:665
libMesh::MeshRefinement::clean_refinement_flags
void clean_refinement_flags()
Sets the refinement flag to Elem::DO_NOTHING for each element in the mesh.
Definition: mesh_refinement_flagging.C:682
libMesh::TopologyMap::clear
void clear()
Definition: topology_map.h:76
libMesh::Elem::DO_NOTHING
Definition: elem.h:1170
libMesh::as_range
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::MeshBase::is_prepared
bool is_prepared() const
Definition: mesh_base.h:152
libMesh::MeshRefinement::enforce_mismatch_limit_prior_to_refinement
bool & enforce_mismatch_limit_prior_to_refinement()
Get/set the _enforce_mismatch_limit_prior_to_refinement flag.
Definition: mesh_refinement.h:954
libMesh::Elem::JUST_COARSENED
Definition: elem.h:1173
libMesh::Elem::REFINE
Definition: elem.h:1171
libMesh::MeshBase::n_nodes
virtual dof_id_type n_nodes() const =0
libMesh::Elem::refinement_flag
RefinementState refinement_flag() const
Definition: elem.h:2614
libMesh::MeshRefinement::test_unflagged
bool test_unflagged(bool libmesh_assert_yes=false)
Definition: mesh_refinement.C:428
libMesh::Parallel::sync_dofobject_data_by_id
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.
Definition: parallel_ghost_sync.h:338
libMesh::MeshBase::sub_point_locator
std::unique_ptr< PointLocatorBase > sub_point_locator() const
Definition: mesh_base.C:672
swap
void swap(Iterator &lhs, Iterator &rhs)
swap, used to implement op=
Definition: variant_filter_iterator.h:478
libMesh::MeshRefinement::_periodic_boundaries
PeriodicBoundaries * _periodic_boundaries
Definition: mesh_refinement.h:864
libMesh::MeshRefinement::_use_member_parameters
bool _use_member_parameters
For backwards compatibility, we initialize this as false and then set it to true if the user uses any...
Definition: mesh_refinement.h:752
libMesh::TopologyMap::add_node
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
libMesh::TopologyMap::init
void init(MeshBase &)
Definition: topology_map.C:36
libMesh::MeshBase::add_elem
virtual Elem * add_elem(Elem *e)=0
Add elem e to the end of the element array.
libMesh::Partitioner::set_node_processor_ids
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:691
libMesh::MeshBase::ancestor_elements_begin
virtual element_iterator ancestor_elements_begin()=0
Iterate over elements for which elem->ancestor() is true.
libMesh::MeshBase::elements_end
virtual element_iterator elements_end()=0
libMesh::DofObject::invalid_processor_id
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:432
libMesh::MeshRefinement::set_periodic_boundaries_ptr
void set_periodic_boundaries_ptr(PeriodicBoundaries *pb_ptr)
Sets the PeriodicBoundaries pointer.
libMesh::MeshRefinement::limit_level_mismatch_at_edge
bool limit_level_mismatch_at_edge(const unsigned int max_mismatch)
Definition: mesh_refinement_smoothing.C:126
libMesh::MeshBase::active_not_local_elements_end
virtual element_iterator active_not_local_elements_end()=0
libMesh::Elem::set_refinement_flag
void set_refinement_flag(const RefinementState rflag)
Sets the value of the refinement flag for the element.
Definition: elem.h:2622
libMesh::MeshBase::add_point
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.
libMesh::MeshBase::level_elements_end
virtual element_iterator level_elements_end(unsigned int level)=0
libMesh::TopologyMap::find
dof_id_type find(dof_id_type bracket_node1, dof_id_type bracket_node2) const
Definition: topology_map.C:117
libMesh::MeshRefinement::topological_neighbor
Elem * topological_neighbor(Elem *elem, const PointLocatorBase *point_locator, const unsigned int side)
Local dispatch function for getting the correct topological neighbor from the Elem class.
Definition: mesh_refinement.C:1791
libMesh::Real
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
Definition: libmesh_common.h:121
libMesh::MeshBase::prepare_for_use
void prepare_for_use(const bool skip_renumber_nodes_and_elements=false, const bool skip_find_neighbors=false)
Prepare a newly ecreated (or read) mesh for use.
Definition: mesh_base.C:318
libMesh::Elem::INACTIVE
Definition: elem.h:1174
libMesh::MeshRefinement::has_topological_neighbor
bool has_topological_neighbor(const Elem *elem, const PointLocatorBase *point_locator, const Elem *neighbor)
Local dispatch function for checking the correct has_neighbor function from the Elem class.
Definition: mesh_refinement.C:1807
libMesh::MeshBase::not_local_elements_end
virtual element_iterator not_local_elements_end()=0
libMesh::MeshRefinement::update_nodes_map
void update_nodes_map()
Updates the _new_nodes_map.
Definition: mesh_refinement.C:346
libMesh::MeshRefinement::_enforce_mismatch_limit_prior_to_refinement
bool _enforce_mismatch_limit_prior_to_refinement
This option enforces the mismatch level prior to refinement by checking if refining any element marke...
Definition: mesh_refinement.h:847
libMesh::MeshRefinement::test_level_one
bool test_level_one(bool libmesh_assert_yes=false)
Definition: mesh_refinement.C:353
libMesh::MeshBase::update_parallel_id_counts
virtual void update_parallel_id_counts()=0
Updates parallel caches so that methods like n_elem() accurately reflect changes on other processors.
libMesh::out
OStreamProxy out
libMesh::MeshRefinement::POINT
Definition: mesh_refinement.h:858
libMesh::MeshRefinement::_refine_fraction
Real _refine_fraction
Definition: mesh_refinement.h:760
libMesh::MeshRefinement::make_coarsening_compatible
bool make_coarsening_compatible()
Take user-specified coarsening flags and augment them so that level-one dependency is satisfied.
Definition: mesh_refinement.C:780
libMesh::remote_elem
const RemoteElem * remote_elem
Definition: remote_elem.C:57
libMesh::MeshRefinement::limit_level_mismatch_at_node
bool limit_level_mismatch_at_node(const unsigned int max_mismatch)
This algorithm restricts the maximum level mismatch at any node in the mesh.
Definition: mesh_refinement_smoothing.C:39
libMesh::MeshRefinement::_nelem_target
dof_id_type _nelem_target
Definition: mesh_refinement.h:768
libMesh::MeshBase::n_active_elem
virtual dof_id_type n_active_elem() const =0
libMesh::MeshBase::is_replicated
virtual bool is_replicated() const
Definition: mesh_base.h:181
libMesh::MeshRefinement::EDGE
Definition: mesh_refinement.h:858
libMesh::MeshBase::active_not_local_elements_begin
virtual element_iterator active_not_local_elements_begin()=0
libMesh::MeshBase::unpartitioned_elements_end
virtual element_iterator unpartitioned_elements_end()=0
libMesh::MeshBase::unpartitioned_elements_begin
virtual element_iterator unpartitioned_elements_begin()=0
Iterate over unpartitioned elements in the Mesh.