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

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

#include <mesh_refinement.h>

Inheritance diagram for libMesh::MeshRefinement:
[legend]

Classes

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

Public Member Functions

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

Protected Attributes

const Parallel::Communicator_communicator
 

Private Types

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

Private Member Functions

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

Private Attributes

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

Detailed Description

Implements (adaptive) mesh refinement algorithms for a MeshBase.

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

Definition at line 61 of file mesh_refinement.h.

Member Enumeration Documentation

◆ NeighborType

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

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

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

Definition at line 885 of file mesh_refinement.h.

Constructor & Destructor Documentation

◆ MeshRefinement() [1/2]

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

Constructor.

Definition at line 94 of file mesh_refinement.C.

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

◆ MeshRefinement() [2/2]

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

◆ ~MeshRefinement()

libMesh::MeshRefinement::~MeshRefinement ( )
default

Destructor.

Deletes all the elements that are currently stored.

Member Function Documentation

◆ _coarsen_elements()

bool libMesh::MeshRefinement::_coarsen_elements ( )
private

Coarsens user-requested elements.

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

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

Definition at line 1335 of file mesh_refinement.C.

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

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

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

◆ _refine_elements()

bool libMesh::MeshRefinement::_refine_elements ( )
private

Refines user-requested elements.

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

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

Definition at line 1468 of file mesh_refinement.C.

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

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

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

◆ _smooth_flags()

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

Smooths refinement flags according to current settings.

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

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

Definition at line 1600 of file mesh_refinement.C.

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

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

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

◆ absolute_global_tolerance()

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

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

absolute_global_tolerance is 0 by default.

Definition at line 936 of file mesh_refinement.h.

References _absolute_global_tolerance, and _use_member_parameters.

Referenced by main().

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

◆ add_elem() [1/2]

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

Adds the element elem to the mesh.

Definition at line 209 of file mesh_refinement.C.

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

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

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

◆ add_elem() [2/2]

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

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

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

Definition at line 215 of file mesh_refinement.C.

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

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

◆ add_node()

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

Add a node to the mesh.

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

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

Definition at line 140 of file mesh_refinement.C.

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

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

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

◆ add_p_to_h_refinement()

void libMesh::MeshRefinement::add_p_to_h_refinement ( )

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

Definition at line 673 of file mesh_refinement_flagging.C.

References _mesh.

Referenced by main().

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

◆ allow_unrefined_patches()

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

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

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

Definition at line 967 of file mesh_refinement.h.

References _allow_unrefined_patches.

968 {
970 }

◆ clean_refinement_flags()

void libMesh::MeshRefinement::clean_refinement_flags ( )

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

Definition at line 681 of file mesh_refinement_flagging.C.

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

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

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

◆ clear()

void libMesh::MeshRefinement::clear ( )

Deletes all the data that are currently stored.

Definition at line 133 of file mesh_refinement.C.

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

Referenced by _coarsen_elements(), and _refine_elements().

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

◆ coarsen_by_parents()

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

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

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

coarsen_by_parents is true by default.

Definition at line 900 of file mesh_refinement.h.

References _coarsen_by_parents, and _use_member_parameters.

Referenced by main().

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

◆ coarsen_elements()

bool libMesh::MeshRefinement::coarsen_elements ( )

Only coarsens the user-requested elements.

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

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

Definition at line 610 of file mesh_refinement.C.

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

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

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

◆ coarsen_fraction()

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

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

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

Definition at line 912 of file mesh_refinement.h.

References _coarsen_fraction, and _use_member_parameters.

Referenced by assemble_and_solve(), and main().

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

◆ coarsen_threshold()

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

The coarsen_threshold provides hysteresis in AMR/C strategies.

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

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

Definition at line 924 of file mesh_refinement.h.

References _coarsen_threshold, and _use_member_parameters.

Referenced by main().

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

◆ comm()

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

Definition at line 97 of file parallel_object.h.

References libMesh::ParallelObject::_communicator.

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

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

◆ create_parent_error_vector()

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

Calculates the error on all coarsenable parents.

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

Definition at line 222 of file mesh_refinement.C.

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

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

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

◆ edge_level_mismatch_limit()

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

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

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

edge_level_mismatch_limit is 0 by default.

Definition at line 947 of file mesh_refinement.h.

References _edge_level_mismatch_limit.

948 {
950 }
unsigned char _edge_level_mismatch_limit

◆ eliminate_unrefined_patches()

bool libMesh::MeshRefinement::eliminate_unrefined_patches ( )
private


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

This algorithm will transform this mesh:

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

into this:

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

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

Definition at line 369 of file mesh_refinement_smoothing.C.

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

Referenced by _smooth_flags().

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

◆ enforce_mismatch_limit_prior_to_refinement() [1/2]

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

Get/set the _enforce_mismatch_limit_prior_to_refinement flag.

The default value for this flag is false.

Definition at line 986 of file mesh_refinement.h.

References _enforce_mismatch_limit_prior_to_refinement.

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

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

◆ enforce_mismatch_limit_prior_to_refinement() [2/2]

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

Definition at line 549 of file mesh_refinement_smoothing.C.

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

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

◆ face_level_mismatch_limit()

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

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

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

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

Definition at line 942 of file mesh_refinement.h.

References _face_level_mismatch_limit.

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

943 {
945 }
unsigned char _face_level_mismatch_limit

◆ flag_elements_by()

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

Flag elements based on a function object.

The class ElementFlagging defines a mechanism for implementing refinement strategies.

Definition at line 647 of file mesh_refinement_flagging.C.

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

648 {
649  element_flagging.flag_elements();
650 }

◆ flag_elements_by_elem_fraction()

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

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

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

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

Definition at line 445 of file mesh_refinement_flagging.C.

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

Referenced by main().

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

◆ flag_elements_by_error_fraction()

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

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

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

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

Definition at line 44 of file mesh_refinement_flagging.C.

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

Referenced by assemble_and_solve(), and main().

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

◆ flag_elements_by_error_tolerance()

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

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

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

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

Definition at line 170 of file mesh_refinement_flagging.C.

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

Referenced by main().

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

◆ flag_elements_by_mean_stddev()

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

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

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

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

Definition at line 583 of file mesh_refinement_flagging.C.

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

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

◆ flag_elements_by_nelem_target()

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

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

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

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

Definition at line 237 of file mesh_refinement_flagging.C.

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

Referenced by main().

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

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

References enforce_mismatch_limit_prior_to_refinement().

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

◆ get_mesh() [1/2]

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

Definition at line 340 of file mesh_refinement.h.

References _mesh.

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

◆ get_mesh() [2/2]

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

Definition at line 346 of file mesh_refinement.h.

References _mesh.

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

◆ has_topological_neighbor()

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

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

Definition at line 1813 of file mesh_refinement.C.

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

Referenced by make_coarsening_compatible(), and make_refinement_compatible().

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

◆ limit_level_mismatch_at_edge()

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

Definition at line 126 of file mesh_refinement_smoothing.C.

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

Referenced by _smooth_flags().

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

◆ limit_level_mismatch_at_node()

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


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

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

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

into this:

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

by refining the indicated element

Definition at line 39 of file mesh_refinement_smoothing.C.

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

Referenced by _smooth_flags().

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

◆ limit_overrefined_boundary()

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

Definition at line 256 of file mesh_refinement_smoothing.C.

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

Referenced by _smooth_flags().

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

◆ limit_underrefined_boundary()

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

Definition at line 310 of file mesh_refinement_smoothing.C.

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

Referenced by _smooth_flags().

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

◆ make_coarsening_compatible()

bool libMesh::MeshRefinement::make_coarsening_compatible ( )
private

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

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

Definition at line 779 of file mesh_refinement.C.

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

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

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

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

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

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

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

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

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

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

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

◆ max_h_level()

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

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

max_h_level is unlimited (libMesh::invalid_uint) by default

Definition at line 918 of file mesh_refinement.h.

References _max_h_level, and _use_member_parameters.

Referenced by assemble_and_solve(), and main().

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

◆ n_processors()

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

Definition at line 103 of file parallel_object.h.

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

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

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

◆ nelem_target()

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

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

nelem_target is 0 by default.

Definition at line 930 of file mesh_refinement.h.

References _nelem_target, and _use_member_parameters.

Referenced by main().

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

◆ node_level_mismatch_limit()

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

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

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

node_level_mismatch_limit is 0 by default.

Definition at line 952 of file mesh_refinement.h.

References _node_level_mismatch_limit.

953 {
955 }
unsigned char _node_level_mismatch_limit

◆ operator=()

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

◆ overrefined_boundary_limit()

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

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

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

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

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

Definition at line 957 of file mesh_refinement.h.

References _overrefined_boundary_limit.

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

958 {
960 }
signed char _overrefined_boundary_limit

◆ processor_id()

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

Definition at line 114 of file parallel_object.h.

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

Referenced by libMesh::BoundaryInfo::_find_id_maps(), libMesh::PetscDMWrapper::add_dofs_to_section(), libMesh::DistributedMesh::add_elem(), libMesh::BoundaryInfo::add_elements(), libMesh::DofMap::add_neighbors_to_send_list(), libMesh::DistributedMesh::add_node(), libMesh::MeshTools::Modification::all_tri(), libMesh::DofMap::allgather_recursive_constraints(), libMesh::FEMSystem::assembly(), libMesh::Nemesis_IO::assert_symmetric_cmaps(), libMesh::Partitioner::assign_partitioning(), libMesh::Nemesis_IO_Helper::build_element_and_node_maps(), libMesh::Partitioner::build_graph(), libMesh::InfElemBuilder::build_inf_elem(), libMesh::BoundaryInfo::build_node_list_from_side_list(), libMesh::EquationSystems::build_parallel_elemental_solution_vector(), libMesh::EquationSystems::build_parallel_solution_vector(), libMesh::DistributedMesh::clear(), libMesh::DistributedMesh::clear_elems(), libMesh::ExodusII_IO_Helper::close(), libMesh::Nemesis_IO_Helper::compute_border_node_ids(), libMesh::Nemesis_IO_Helper::compute_communication_map_parameters(), libMesh::Nemesis_IO_Helper::compute_internal_and_border_elems_and_internal_nodes(), libMesh::RBConstruction::compute_max_error_bound(), libMesh::Nemesis_IO_Helper::compute_node_communication_maps(), libMesh::Nemesis_IO_Helper::compute_num_global_elem_blocks(), libMesh::Nemesis_IO_Helper::compute_num_global_nodesets(), libMesh::Nemesis_IO_Helper::compute_num_global_sidesets(), libMesh::Nemesis_IO_Helper::construct_nemesis_filename(), libMesh::ExodusII_IO::copy_elemental_solution(), libMesh::ExodusII_IO::copy_nodal_solution(), libMesh::ExodusII_IO::copy_scalar_solution(), libMesh::Nemesis_IO::copy_scalar_solution(), libMesh::MeshTools::correct_node_proc_ids(), libMesh::ExodusII_IO_Helper::create(), libMesh::DistributedMesh::delete_elem(), libMesh::MeshCommunication::delete_remote_elements(), libMesh::DofMap::distribute_dofs(), libMesh::DofMap::distribute_local_dofs_node_major(), libMesh::DofMap::distribute_local_dofs_var_major(), libMesh::DofMap::distribute_scalar_dofs(), libMesh::DistributedMesh::DistributedMesh(), libMesh::DofMap::end_dof(), libMesh::DofMap::end_old_dof(), libMesh::EnsightIO::EnsightIO(), libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::SubFunctor::find_dofs_to_send(), libMesh::MeshFunction::find_element(), libMesh::MeshFunction::find_elements(), libMesh::UnstructuredMesh::find_neighbors(), libMesh::DofMap::first_dof(), libMesh::DofMap::first_old_dof(), libMesh::RBEIMEvaluation::gather_bfs(), libMesh::Nemesis_IO_Helper::get_cmap_params(), libMesh::Nemesis_IO_Helper::get_eb_info_global(), libMesh::Nemesis_IO_Helper::get_elem_cmap(), libMesh::Nemesis_IO_Helper::get_elem_map(), libMesh::MeshBase::get_info(), libMesh::DofMap::get_info(), libMesh::Nemesis_IO_Helper::get_init_global(), libMesh::Nemesis_IO_Helper::get_init_info(), libMesh::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::LaplaceMeshSmoother::init(), 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::TransientRBEvaluation::legacy_write_offline_data_to_files(), libMesh::RBSCMEvaluation::legacy_write_offline_data_to_files(), libMesh::RBEvaluation::legacy_write_offline_data_to_files(), libMesh::MeshTools::libmesh_assert_consistent_distributed(), libMesh::MeshTools::libmesh_assert_consistent_distributed_nodes(), libMesh::MeshTools::libmesh_assert_contiguous_dof_ids(), libMesh::MeshTools::libmesh_assert_parallel_consistent_procids< Elem >(), libMesh::MeshTools::libmesh_assert_valid_neighbors(), libMesh::DistributedMesh::libmesh_assert_valid_parallel_object_ids(), libMesh::DofMap::local_variable_indices(), main(), make_coarsening_compatible(), AugmentSparsityOnInterface::mesh_reinit(), libMesh::TriangulatorInterface::MeshedHole::MeshedHole(), libMesh::MeshBase::n_active_local_elem(), libMesh::BoundaryInfo::n_boundary_conds(), libMesh::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::RBEIMEvaluation::node_gather_bfs(), libMesh::SparsityPattern::Build::operator()(), libMesh::DistributedMesh::own_node(), libMesh::BoundaryInfo::parallel_sync_node_ids(), libMesh::BoundaryInfo::parallel_sync_side_ids(), libMesh::System::point_gradient(), libMesh::System::point_hessian(), libMesh::System::point_value(), libMesh::DofMap::print_dof_constraints(), libMesh::DofMap::process_mesh_constraint_rows(), libMesh::Nemesis_IO_Helper::put_cmap_params(), libMesh::Nemesis_IO_Helper::put_elem_cmap(), libMesh::Nemesis_IO_Helper::put_elem_map(), libMesh::Nemesis_IO_Helper::put_loadbal_param(), libMesh::Nemesis_IO_Helper::put_node_cmap(), libMesh::Nemesis_IO_Helper::put_node_map(), libMesh::NameBasedIO::read(), libMesh::Nemesis_IO::read(), libMesh::XdrIO::read(), libMesh::CheckpointIO::read(), libMesh::EquationSystems::read(), libMesh::ExodusII_IO_Helper::read_elem_num_map(), libMesh::ExodusII_IO_Helper::read_global_values(), libMesh::ExodusII_IO::read_header(), libMesh::CheckpointIO::read_header(), libMesh::XdrIO::read_header(), libMesh::System::read_header(), libMesh::System::read_legacy_data(), libMesh::DynaIO::read_mesh(), libMesh::ExodusII_IO_Helper::read_node_num_map(), libMesh::System::read_parallel_data(), libMesh::TransientRBConstruction::read_riesz_representors_from_files(), libMesh::RBConstruction::read_riesz_representors_from_files(), libMesh::System::read_SCALAR_dofs(), libMesh::XdrIO::read_serialized_bc_names(), libMesh::XdrIO::read_serialized_bcs_helper(), libMesh::System::read_serialized_blocked_dof_objects(), libMesh::XdrIO::read_serialized_connectivity(), libMesh::System::read_serialized_data(), libMesh::XdrIO::read_serialized_nodes(), libMesh::XdrIO::read_serialized_nodesets(), libMesh::XdrIO::read_serialized_subdomain_names(), libMesh::System::read_serialized_vector(), libMesh::System::read_serialized_vectors(), libMesh::Nemesis_IO_Helper::read_var_names_impl(), libMesh::DistributedMesh::renumber_dof_objects(), libMesh::DistributedMesh::renumber_nodes_and_elements(), libMesh::DofMap::scatter_constraints(), libMesh::CheckpointIO::select_split_config(), libMesh::DistributedMesh::set_next_unique_id(), libMesh::DofMap::set_nonlocal_dof_objects(), libMesh::PetscDMWrapper::set_point_range_in_section(), libMesh::RBEIMEvaluation::side_gather_bfs(), ExodusTest< elem_type >::test_read_gold(), ExodusTest< elem_type >::test_write(), MeshInputTest::testAbaqusRead(), MeshInputTest::testCopyElementSolutionImpl(), MeshInputTest::testCopyElementVectorImpl(), MeshInputTest::testCopyNodalSolutionImpl(), DefaultCouplingTest::testCoupling(), PointNeighborCouplingTest::testCoupling(), MeshInputTest::testDynaFileMappings(), MeshInputTest::testDynaNoSplines(), MeshInputTest::testDynaReadElem(), MeshInputTest::testDynaReadPatch(), MeshInputTest::testExodusFileMappings(), MeshInputTest::testExodusIGASidesets(), MeshInputTest::testExodusWriteElementDataFromDiscontinuousNodalData(), MeshInputTest::testLowOrderEdgeBlocks(), SystemsTest::testProjectMatrix1D(), SystemsTest::testProjectMatrix2D(), SystemsTest::testProjectMatrix3D(), BoundaryInfoTest::testShellFaceConstraints(), MeshInputTest::testSingleElementImpl(), WriteVecAndScalar::testSolution(), CheckpointIOTest::testSplitter(), MeshInputTest::testTetgenIO(), libMesh::MeshTools::total_weight(), uniformly_coarsen(), 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_Helper::write_elemset_data(), libMesh::ExodusII_IO_Helper::write_elemsets(), libMesh::ExodusII_IO::write_global_data(), libMesh::ExodusII_IO_Helper::write_global_values(), libMesh::System::write_header(), libMesh::ExodusII_IO::write_information_records(), libMesh::ExodusII_IO_Helper::write_information_records(), libMesh::ExodusII_IO_Helper::write_nodal_coordinates(), libMesh::UCDIO::write_nodal_data(), libMesh::VTKIO::write_nodal_data(), libMesh::ExodusII_IO::write_nodal_data(), libMesh::ExodusII_IO::write_nodal_data_common(), libMesh::ExodusII_IO::write_nodal_data_discontinuous(), libMesh::ExodusII_IO_Helper::write_nodal_values(), libMesh::ExodusII_IO_Helper::write_nodeset_data(), libMesh::Nemesis_IO_Helper::write_nodesets(), libMesh::ExodusII_IO_Helper::write_nodesets(), libMesh::RBEIMEvaluation::write_out_interior_basis_functions(), libMesh::RBEIMEvaluation::write_out_node_basis_functions(), libMesh::RBEIMEvaluation::write_out_side_basis_functions(), write_output_solvedata(), libMesh::System::write_parallel_data(), libMesh::RBConstruction::write_riesz_representors_to_files(), libMesh::System::write_SCALAR_dofs(), libMesh::XdrIO::write_serialized_bc_names(), libMesh::XdrIO::write_serialized_bcs_helper(), libMesh::System::write_serialized_blocked_dof_objects(), libMesh::XdrIO::write_serialized_connectivity(), libMesh::System::write_serialized_data(), libMesh::XdrIO::write_serialized_nodes(), libMesh::XdrIO::write_serialized_nodesets(), libMesh::XdrIO::write_serialized_subdomain_names(), libMesh::System::write_serialized_vector(), libMesh::System::write_serialized_vectors(), libMesh::ExodusII_IO_Helper::write_sideset_data(), libMesh::Nemesis_IO_Helper::write_sidesets(), libMesh::ExodusII_IO_Helper::write_sidesets(), libMesh::ExodusII_IO::write_timestep(), libMesh::ExodusII_IO_Helper::write_timestep(), and libMesh::ExodusII_IO::write_timestep_discontinuous().

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

◆ refine_and_coarsen_elements()

bool libMesh::MeshRefinement::refine_and_coarsen_elements ( )

Refines and coarsens user-requested elements.

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

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

Definition at line 478 of file mesh_refinement.C.

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

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

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

◆ refine_elements()

bool libMesh::MeshRefinement::refine_elements ( )

Only refines the user-requested elements.

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

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

Definition at line 684 of file mesh_refinement.C.

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

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

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

◆ refine_fraction()

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

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

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

Definition at line 906 of file mesh_refinement.h.

References _refine_fraction, and _use_member_parameters.

Referenced by assemble_and_solve(), and main().

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

◆ set_enforce_mismatch_limit_prior_to_refinement()

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

Set _enforce_mismatch_limit_prior_to_refinement option.

Defaults to false.

Definition at line 979 of file mesh_refinement.h.

References enforce_mismatch_limit_prior_to_refinement().

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

◆ set_periodic_boundaries_ptr()

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

Sets the PeriodicBoundaries pointer.

Referenced by main().

◆ switch_h_to_p_refinement()

void libMesh::MeshRefinement::switch_h_to_p_refinement ( )

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

Definition at line 654 of file mesh_refinement_flagging.C.

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

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

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

◆ test_level_one()

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

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

Definition at line 355 of file mesh_refinement.C.

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

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

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

◆ test_unflagged()

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

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

Definition at line 430 of file mesh_refinement.C.

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

Referenced by refine_and_coarsen_elements().

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

◆ topological_neighbor()

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

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

Definition at line 1797 of file mesh_refinement.C.

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

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

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

◆ underrefined_boundary_limit()

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

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

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

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

Definition at line 962 of file mesh_refinement.h.

References _underrefined_boundary_limit.

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

963 {
965 }
signed char _underrefined_boundary_limit

◆ uniformly_coarsen()

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

Attempts to uniformly coarsen the mesh n times.

Definition at line 1709 of file mesh_refinement.C.

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

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

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

◆ uniformly_p_coarsen()

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

Attempts to uniformly p coarsen the mesh n times.

Definition at line 1669 of file mesh_refinement.C.

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

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

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

◆ uniformly_p_refine()

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

Uniformly p refines the mesh n times.

Definition at line 1655 of file mesh_refinement.C.

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

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

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

◆ uniformly_refine()

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

Uniformly refines the mesh n times.

Definition at line 1684 of file mesh_refinement.C.

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

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

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

◆ update_nodes_map()

void libMesh::MeshRefinement::update_nodes_map ( )
private

Updates the _new_nodes_map.

Definition at line 348 of file mesh_refinement.C.

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

Referenced by _coarsen_elements(), and _refine_elements().

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

Member Data Documentation

◆ _absolute_global_tolerance

Real libMesh::MeshRefinement::_absolute_global_tolerance
private

◆ _allow_unrefined_patches

bool libMesh::MeshRefinement::_allow_unrefined_patches
private

Definition at line 804 of file mesh_refinement.h.

Referenced by allow_unrefined_patches(), and eliminate_unrefined_patches().

◆ _coarsen_by_parents

bool libMesh::MeshRefinement::_coarsen_by_parents
private

◆ _coarsen_fraction

Real libMesh::MeshRefinement::_coarsen_fraction
private

◆ _coarsen_threshold

Real libMesh::MeshRefinement::_coarsen_threshold
private

◆ _communicator

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

◆ _edge_level_mismatch_limit

unsigned char libMesh::MeshRefinement::_edge_level_mismatch_limit
private

Definition at line 798 of file mesh_refinement.h.

Referenced by _smooth_flags(), and edge_level_mismatch_limit().

◆ _enforce_mismatch_limit_prior_to_refinement

bool libMesh::MeshRefinement::_enforce_mismatch_limit_prior_to_refinement
private


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

Applies to all mismatch methods.

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

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

into this:

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

by moving the refinement flag to the indicated element.

Default value is false.

Definition at line 874 of file mesh_refinement.h.

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

◆ _face_level_mismatch_limit

unsigned char libMesh::MeshRefinement::_face_level_mismatch_limit
private

◆ _max_h_level

unsigned int libMesh::MeshRefinement::_max_h_level
private

◆ _mesh

MeshBase& libMesh::MeshRefinement::_mesh
private

◆ _nelem_target

dof_id_type libMesh::MeshRefinement::_nelem_target
private

Definition at line 793 of file mesh_refinement.h.

Referenced by flag_elements_by_nelem_target(), and nelem_target().

◆ _new_nodes_map

TopologyMap libMesh::MeshRefinement::_new_nodes_map
private

Data structure that holds the new nodes information.

Definition at line 765 of file mesh_refinement.h.

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

◆ _node_level_mismatch_limit

unsigned char libMesh::MeshRefinement::_node_level_mismatch_limit
private

Definition at line 799 of file mesh_refinement.h.

Referenced by _smooth_flags(), and node_level_mismatch_limit().

◆ _overrefined_boundary_limit

signed char libMesh::MeshRefinement::_overrefined_boundary_limit
private

Definition at line 801 of file mesh_refinement.h.

Referenced by _smooth_flags(), and overrefined_boundary_limit().

◆ _periodic_boundaries

PeriodicBoundaries* libMesh::MeshRefinement::_periodic_boundaries
private

◆ _refine_fraction

Real libMesh::MeshRefinement::_refine_fraction
private

◆ _underrefined_boundary_limit

signed char libMesh::MeshRefinement::_underrefined_boundary_limit
private

Definition at line 802 of file mesh_refinement.h.

Referenced by _smooth_flags(), and underrefined_boundary_limit().

◆ _use_member_parameters

bool libMesh::MeshRefinement::_use_member_parameters
private

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

Definition at line 777 of file mesh_refinement.h.

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


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