$extrastylesheet
libMesh::MeshRefinement Class Reference

#include <mesh_refinement.h>

Inheritance diagram for libMesh::MeshRefinement:

List of all members.

Classes

class  ElementFlagging

Public Member Functions

 MeshRefinement (MeshBase &mesh)
void set_periodic_boundaries_ptr (PeriodicBoundaries *pb_ptr)
 ~MeshRefinement ()
void clear ()
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)
void flag_elements_by_error_tolerance (const ErrorVector &error_per_cell)
bool flag_elements_by_nelem_target (const ErrorVector &error_per_cell)
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)
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)
void flag_elements_by (ElementFlagging &element_flagging)
void switch_h_to_p_refinement ()
void add_p_to_h_refinement ()
bool refine_and_coarsen_elements (const bool maintain_level_one=true)
bool coarsen_elements (const bool maintain_level_one=true)
bool refine_elements (const bool maintain_level_one=true)
void uniformly_refine (unsigned int n=1)
void uniformly_coarsen (unsigned int n=1)
void uniformly_p_refine (unsigned int n=1)
void uniformly_p_coarsen (unsigned int n=1)
void clean_refinement_flags ()
bool test_level_one (bool libmesh_assert_yes=false)
bool test_unflagged (bool libmesh_assert_yes=false)
Nodeadd_point (const Point &p, const processor_id_type proc_id, const Real tol)
Elemadd_elem (Elem *elem)
const MeshBaseget_mesh () const
MeshBaseget_mesh ()
bool & coarsen_by_parents ()
Realrefine_fraction ()
Realcoarsen_fraction ()
unsigned int & max_h_level ()
Realcoarsen_threshold ()
dof_id_typenelem_target ()
Realabsolute_global_tolerance ()
unsigned char & face_level_mismatch_limit ()
unsigned char & edge_level_mismatch_limit ()
unsigned char & node_level_mismatch_limit ()
bool make_flags_parallel_consistent ()
bool get_enforce_mismatch_limit_prior_to_refinement ()
void set_enforce_mismatch_limit_prior_to_refinement (bool enforce)
bool & enforce_mismatch_limit_prior_to_refinement ()
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 }

Private Member Functions

 MeshRefinement (const MeshRefinement &)
MeshRefinementoperator= (const MeshRefinement &)
bool _coarsen_elements ()
bool _refine_elements ()
bool limit_level_mismatch_at_node (const unsigned int max_mismatch)
bool limit_level_mismatch_at_edge (const unsigned int max_mismatch)
bool eliminate_unrefined_patches ()
void create_parent_error_vector (const ErrorVector &error_per_cell, ErrorVector &error_per_parent, Real &parent_error_min, Real &parent_error_max)
void update_nodes_map ()
bool make_coarsening_compatible (const bool)
bool make_refinement_compatible (const bool)
Elemtopological_neighbor (Elem *elem, const PointLocatorBase *point_locator, const unsigned int side)
bool has_topological_neighbor (Elem *elem, const PointLocatorBase *point_locator, Elem *neighbor)
bool enforce_mismatch_limit_prior_to_refinement (Elem *elem, NeighborType nt, unsigned max_mismatch)

Private Attributes

LocationMap< Node_new_nodes_map
MeshBase_mesh
bool _use_member_parameters
bool _coarsen_by_parents
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
bool _enforce_mismatch_limit_prior_to_refinement
PeriodicBoundaries_periodic_boundaries

Detailed Description

This is the MeshRefinement class. This class implements adaptive mesh refinement algorithms for a MeshBase.

Author:
Benjamin S. Kirk, 2002-2007.

Definition at line 62 of file mesh_refinement.h.


Member Enumeration Documentation

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

{POINT, EDGE};

Constructor & Destructor Documentation

Destructor. Deletes all the elements that are currently stored.

Definition at line 87 of file mesh_refinement.C.

References clear().

{
  this->clear();
}

Member Function Documentation

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. Consequently, this function returns true if the mesh actually changed (hence data needs to be projected) and false otherwise.

Definition at line 1501 of file mesh_refinement.C.

References _mesh, libMesh::Elem::active(), clear(), libMesh::Elem::COARSEN, libMesh::Elem::coarsen(), libMesh::Elem::COARSEN_INACTIVE, libMesh::ParallelObject::comm(), libMesh::Elem::DO_NOTHING, libMesh::MeshBase::elements_begin(), libMesh::MeshBase::elements_end(), end, libMesh::MeshBase::get_boundary_info(), libMesh::MeshBase::is_serial(), libMesh::Elem::JUST_COARSENED, libMesh::Elem::level(), libMesh::libmesh_assert(), libMesh::MeshTools::libmesh_assert_valid_procids< Node >(), libMesh::MeshCommunication::make_nodes_parallel_consistent(), libMesh::Parallel::Communicator::max(), libMesh::Elem::nullify_neighbors(), libMesh::Elem::p_level(), libMesh::Elem::p_refinement_flag(), libMesh::Elem::refinement_flag(), libMesh::BoundaryInfo::remove(), libMesh::Elem::set_p_level(), libMesh::Elem::set_p_refinement_flag(), libMesh::START_LOG(), update_nodes_map(), and libMesh::MeshBase::update_parallel_id_counts().

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

{
  // This function must be run on all processors at once
  parallel_object_only();

  START_LOG ("_coarsen_elements()", "MeshRefinement");

  // Flag indicating if this call actually changes the mesh
  bool mesh_changed = false;

  // Clear the unused_elements data structure.
  // The elements have been packed since it was built,
  // so there are _no_ unused elements.  We cannot trust
  // any iterators currently in this data structure.
  // _unused_elements.clear();

  MeshBase::element_iterator       it  = _mesh.elements_begin();
  const MeshBase::element_iterator end = _mesh.elements_end();

  // Loop over the elements.
  for ( ; it != end; ++it)
    {
      Elem* elem = *it;

      // Not necessary when using elem_iterator
      // libmesh_assert(elem);

      // active elements flagged for coarsening will
      // no longer be deleted until MeshRefinement::contract()
      if (elem->refinement_flag() == Elem::COARSEN)
        {
          // Huh?  no level-0 element should be active
          // and flagged for coarsening.
          libmesh_assert_not_equal_to (elem->level(), 0);

          // Remove this element from any neighbor
          // lists that point to it.
          elem->nullify_neighbors();

          // Remove any boundary information associated
          // with this element
          _mesh.get_boundary_info().remove (elem);

          // Add this iterator to the _unused_elements
          // data structure so we might fill it.
          // The _unused_elements optimization is currently off.
          // _unused_elements.push_back (it);

          // Don't delete the element until
          // MeshRefinement::contract()
          // _mesh.delete_elem(elem);

          // the mesh has certainly changed
          mesh_changed = true;
        }

      // inactive elements flagged for coarsening
      // will become active
      else if (elem->refinement_flag() == Elem::COARSEN_INACTIVE)
        {
          elem->coarsen();
          libmesh_assert (elem->active());

          // the mesh has certainly changed
          mesh_changed = true;
        }
      if (elem->p_refinement_flag() == Elem::COARSEN)
        {
          if (elem->p_level() > 0)
            {
              elem->set_p_refinement_flag(Elem::JUST_COARSENED);
              elem->set_p_level(elem->p_level() - 1);
              mesh_changed = true;
            }
          else
            {
              elem->set_p_refinement_flag(Elem::DO_NOTHING);
            }
        }
    }

  // If the mesh changed on any processor, it changed globally
  this->comm().max(mesh_changed);
  // And we may need to update ParallelMesh values reflecting the changes
  if (mesh_changed)
    _mesh.update_parallel_id_counts();

  // Node processor ids may need to change if an element of that id
  // was coarsened away
  if (mesh_changed && !_mesh.is_serial())
    {
      // Update the _new_nodes_map so that processors can
      // find requested nodes
      this->update_nodes_map ();

      MeshCommunication().make_nodes_parallel_consistent (_mesh);

      // Clear the _new_nodes_map
      this->clear();

#ifdef DEBUG
      MeshTools::libmesh_assert_valid_procids<Node>(_mesh);
#endif
    }

  STOP_LOG ("_coarsen_elements()", "MeshRefinement");

  return mesh_changed;
}

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. Consequently, this function returns true if the mesh actually changed (hence data needs to be projected) and false otherwise.

Definition at line 1613 of file mesh_refinement.C.

References _mesh, libMesh::Elem::active(), clear(), libMesh::ParallelObject::comm(), libMesh::MeshBase::elements_begin(), libMesh::MeshBase::elements_end(), end, libMesh::MeshBase::is_serial(), libMesh::Elem::JUST_REFINED, libMesh::MeshBase::libmesh_assert_valid_parallel_ids(), libMesh::MeshCommunication::make_elems_parallel_consistent(), libMesh::MeshCommunication::make_nodes_parallel_consistent(), libMesh::Parallel::Communicator::max(), libMesh::Elem::p_level(), libMesh::Elem::p_refinement_flag(), libMesh::Elem::REFINE, libMesh::Elem::refinement_flag(), libMesh::Elem::set_p_level(), libMesh::Elem::set_p_refinement_flag(), libMesh::START_LOG(), update_nodes_map(), and libMesh::MeshBase::update_parallel_id_counts().

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

{
  // This function must be run on all processors at once
  parallel_object_only();

  // Update the _new_nodes_map so that elements can
  // find nodes to connect to.
  this->update_nodes_map ();

  START_LOG ("_refine_elements()", "MeshRefinement");

  // Iterate over the elements, counting the elements
  // flagged for h refinement.
  dof_id_type n_elems_flagged = 0;

  MeshBase::element_iterator       it  = _mesh.elements_begin();
  const MeshBase::element_iterator end = _mesh.elements_end();

  for (; it != end; ++it)
    {
      Elem* elem = *it;
      if (elem->refinement_flag() == Elem::REFINE)
        n_elems_flagged++;
    }

  // Construct a local vector of Elem* which have been
  // previously marked for refinement.  We reserve enough
  // space to allow for every element to be refined.
  std::vector<Elem*> local_copy_of_elements;
  local_copy_of_elements.reserve(n_elems_flagged);

  // Iterate over the elements, looking for elements
  // flagged for refinement.
  for (it = _mesh.elements_begin(); it != end; ++it)
    {
      Elem* elem = *it;
      if (elem->refinement_flag() == Elem::REFINE)
        local_copy_of_elements.push_back(elem);
      if (elem->p_refinement_flag() == Elem::REFINE &&
          elem->active())
        {
          elem->set_p_level(elem->p_level()+1);
          elem->set_p_refinement_flag(Elem::JUST_REFINED);
        }
    }

  // Now iterate over the local copies and refine each one.
  // This may resize the mesh's internal container and invalidate
  // any existing iterators.

  for (std::size_t e = 0; e != local_copy_of_elements.size(); ++e)
    local_copy_of_elements[e]->refine(*this);

  // The mesh changed if there were elements h refined
  bool mesh_changed = !local_copy_of_elements.empty();

  // If the mesh changed on any processor, it changed globally
  this->comm().max(mesh_changed);

  // And we may need to update ParallelMesh values reflecting the changes
  if (mesh_changed)
    _mesh.update_parallel_id_counts();

  if (mesh_changed && !_mesh.is_serial())
    {
      MeshCommunication().make_elems_parallel_consistent (_mesh);
      MeshCommunication().make_nodes_parallel_consistent (_mesh);
#ifdef DEBUG
      _mesh.libmesh_assert_valid_parallel_ids();
#endif
    }

  // Clear the _new_nodes_map and _unused_elements data structures.
  this->clear();

  STOP_LOG ("_refine_elements()", "MeshRefinement");

  return mesh_changed;
}

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

References _absolute_global_tolerance, and _use_member_parameters.

Adds the element elem to the mesh.

Definition at line 131 of file mesh_refinement.C.

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

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

{
  libmesh_assert(elem);


  //   // If the unused_elements has any iterators from
  //   // old elements, take the first one
  //   if (!_unused_elements.empty())
  //     {
  //       std::vector<Elem*>::iterator it = _unused_elements.front();

  //       *it = elem;

  //       _unused_elements.pop_front();
  //     }

  //   // Otherwise, use the conventional add method
  //   else
  //     {
  //       _mesh.add_elem (elem);
  //     }

  // The _unused_elements optimization has been turned off.
  _mesh.add_elem (elem);

  return elem;
}

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

References _mesh, libMesh::MeshBase::elements_begin(), and libMesh::MeshBase::elements_end().

{
  MeshBase::element_iterator       elem_it  = _mesh.elements_begin();
  const MeshBase::element_iterator elem_end = _mesh.elements_end();

  for ( ; elem_it != elem_end; ++elem_it)
    (*elem_it)->set_p_refinement_flag((*elem_it)->refinement_flag());
}
Node * libMesh::MeshRefinement::add_point ( const Point p,
const processor_id_type  proc_id,
const Real  tol 
)

Add point p to the mesh. The function returns a pointer to the new node. The processor_id is assigned to the new node (only if no existing node is found. The tolerance tol tells the method how far away from p to search for existing nodes.

Definition at line 101 of file mesh_refinement.C.

References _mesh, _new_nodes_map, libMesh::MeshBase::add_point(), libMesh::LocationMap< T >::find(), libMesh::LocationMap< T >::insert(), libMesh::DofObject::invalid_id, libMesh::libmesh_assert(), and libMesh::START_LOG().

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

{
  START_LOG("add_point()", "MeshRefinement");

  // Return the node if it already exists
  Node *node = _new_nodes_map.find(p, tol);
  if (node)
    {
      STOP_LOG("add_point()", "MeshRefinement");
      return node;
    }

  // Add the node, with a default id and the requested
  // processor_id
  node = _mesh.add_point (p, DofObject::invalid_id, proc_id);

  libmesh_assert(node);

  // Add the node to the map.
  _new_nodes_map.insert(*node);

  // Return the address of the new node
  STOP_LOG("add_point()", "MeshRefinement");
  return node;
}

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

Definition at line 695 of file mesh_refinement_flagging.C.

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

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

{
  // Possibly clean up the refinement flags from
  // a previous step
  //   elem_iterator       elem_it (_mesh.elements_begin());
  //   const elem_iterator elem_end(_mesh.elements_end());

  MeshBase::element_iterator       elem_it  = _mesh.elements_begin();
  const MeshBase::element_iterator elem_end = _mesh.elements_end();

  for ( ; elem_it != elem_end; ++elem_it)
    {
      if ((*elem_it)->active())
        {
          (*elem_it)->set_refinement_flag(Elem::DO_NOTHING);
          (*elem_it)->set_p_refinement_flag(Elem::DO_NOTHING);
        }
      else
        {
          (*elem_it)->set_refinement_flag(Elem::INACTIVE);
          (*elem_it)->set_p_refinement_flag(Elem::INACTIVE);
        }
    }
}

Deletes all the data that are currently stored.

Definition at line 94 of file mesh_refinement.C.

References _new_nodes_map, and libMesh::LocationMap< T >::clear().

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

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

References _coarsen_by_parents, and _use_member_parameters.

bool libMesh::MeshRefinement::coarsen_elements ( const bool  maintain_level_one = true)

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. Consequently, this function returns true if the mesh actually changed (hence data needs to be projected) and false otherwise.

The argument maintain_level_one is now deprecated; use the option face_level_mismatch_limit() instead.

Definition at line 612 of file mesh_refinement.C.

References _coarsen_elements(), _edge_level_mismatch_limit, _face_level_mismatch_limit, _mesh, _node_level_mismatch_limit, libMesh::Elem::active(), libMesh::ParallelObject::comm(), libMesh::Elem::DO_NOTHING, libMesh::MeshBase::elements_begin(), libMesh::MeshBase::elements_end(), eliminate_unrefined_patches(), libMesh::Elem::INACTIVE, libMesh::MeshBase::is_serial(), libMesh::Elem::JUST_REFINED, libMesh::libmesh_assert(), limit_level_mismatch_at_edge(), limit_level_mismatch_at_node(), make_coarsening_compatible(), make_flags_parallel_consistent(), libMesh::Parallel::Communicator::max(), libMesh::Parallel::Communicator::min(), libMesh::out, libMesh::MeshBase::prepare_for_use(), libMesh::Elem::refinement_flag(), libMesh::Elem::set_p_refinement_flag(), libMesh::Elem::set_refinement_flag(), and test_level_one().

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

{
  // This function must be run on all processors at once
  parallel_object_only();

  bool _maintain_level_one = maintain_level_one;

  // If the user used non-default parameters, let's warn that they're
  // deprecated
  if (!maintain_level_one)
    {
      libmesh_deprecated();
    }
  else
    _maintain_level_one = _face_level_mismatch_limit;

  // We can't yet turn a non-level-one mesh into a level-one mesh
  if (_maintain_level_one)
    libmesh_assert(test_level_one(true));

  // Possibly clean up the refinement flags from
  // a previous step
  MeshBase::element_iterator       elem_it  = _mesh.elements_begin();
  const MeshBase::element_iterator elem_end = _mesh.elements_end();

  for ( ; elem_it != elem_end; ++elem_it)
    {
      // Pointer to the element
      Elem* elem = *elem_it;

      // Set refinement flag to INACTIVE if the
      // element isn't active
      if ( !elem->active())
        {
          elem->set_refinement_flag(Elem::INACTIVE);
          elem->set_p_refinement_flag(Elem::INACTIVE);
        }

      // This might be left over from the last step
      if (elem->refinement_flag() == Elem::JUST_REFINED)
        elem->set_refinement_flag(Elem::DO_NOTHING);
    }

  // Parallel consistency has to come first, or coarsening
  // along processor boundaries might occasionally be falsely
  // prevented
  bool flags_were_consistent = this->make_flags_parallel_consistent();

  // In theory, we should be able to remove the above call, which can
  // be expensive and should be unnecessary.  In practice, doing
  // consistent flagging in parallel is hard, it's impossible to
  // verify at the library level if it's being done by user code, and
  // we don't want to abort large parallel runs in opt mode... but we
  // do want to warn that they should be fixed.
  libmesh_assert(flags_were_consistent);
  if (!flags_were_consistent)
    {
      libMesh::out << "Refinement flags were not consistent between processors!\n"
                   << "Correcting and continuing.";
    }

  // Repeat until flag changes match on every processor
  do
    {
      // Repeat until the flags form a conforming mesh.
      bool satisfied = false;
      do
        {
          const bool coarsening_satisfied =
            this->make_coarsening_compatible(maintain_level_one);

          bool smoothing_satisfied =
            !this->eliminate_unrefined_patches();// &&

          if (_edge_level_mismatch_limit)
            smoothing_satisfied = smoothing_satisfied &&
              !this->limit_level_mismatch_at_edge (_edge_level_mismatch_limit);

          if (_node_level_mismatch_limit)
            smoothing_satisfied = smoothing_satisfied &&
              !this->limit_level_mismatch_at_node (_node_level_mismatch_limit);

          satisfied = (coarsening_satisfied &&
                       smoothing_satisfied);
#ifdef DEBUG
          bool max_satisfied = satisfied,
            min_satisfied = satisfied;
          this->comm().max(max_satisfied);
          this->comm().min(min_satisfied);
          libmesh_assert_equal_to (satisfied, max_satisfied);
          libmesh_assert_equal_to (satisfied, min_satisfied);
#endif
        }
      while (!satisfied);
    }
  while (!_mesh.is_serial() && !this->make_flags_parallel_consistent());

  // Coarsen the flagged elements.
  const bool mesh_changed =
    this->_coarsen_elements ();

  if (_maintain_level_one)
    libmesh_assert(test_level_one(true));
  libmesh_assert(this->make_coarsening_compatible(maintain_level_one));
  // FIXME: This won't pass unless we add a redundant find_neighbors()
  // call or replace find_neighbors() with on-the-fly neighbor updating
  // libmesh_assert(!this->eliminate_unrefined_patches());

  // We can't contract the mesh ourselves anymore - a System might
  // need to restrict old coefficient vectors first
  // _mesh.contract();

  // Finally, the new mesh may need to be prepared for use
  if (mesh_changed)
    _mesh.prepare_for_use (/*skip_renumber =*/false);

  return mesh_changed;
}

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

References _coarsen_fraction, and _use_member_parameters.

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

References _coarsen_threshold, and _use_member_parameters.

const Parallel::Communicator& libMesh::ParallelObject::comm ( ) const [inline, inherited]
Returns:
a reference to the Parallel::Communicator object used by this mesh.

Definition at line 86 of file parallel_object.h.

References libMesh::ParallelObject::_communicator.

Referenced by libMesh::__libmesh_petsc_diff_solver_monitor(), libMesh::__libmesh_petsc_diff_solver_residual(), libMesh::__libmesh_petsc_snes_residual(), _coarsen_elements(), libMesh::ExactSolution::_compute_error(), libMesh::MetisPartitioner::_do_partition(), libMesh::ParmetisPartitioner::_do_repartition(), libMesh::UniformRefinementEstimator::_estimate_error(), libMesh::SlepcEigenSolver< T >::_petsc_shell_matrix_get_diagonal(), libMesh::PetscLinearSolver< T >::_petsc_shell_matrix_get_diagonal(), libMesh::SlepcEigenSolver< T >::_petsc_shell_matrix_mult(), libMesh::PetscLinearSolver< T >::_petsc_shell_matrix_mult(), libMesh::PetscLinearSolver< T >::_petsc_shell_matrix_mult_add(), libMesh::EquationSystems::_read_impl(), _refine_elements(), libMesh::ImplicitSystem::add_matrix(), libMesh::System::add_vector(), libMesh::UnstructuredMesh::all_second_order(), libMesh::LaplaceMeshSmoother::allgather_graph(), libMesh::FEMSystem::assemble_qoi(), libMesh::MeshCommunication::assign_global_indices(), libMesh::ParmetisPartitioner::assign_partitioning(), libMesh::DofMap::attach_matrix(), libMesh::MeshTools::bounding_box(), libMesh::MeshBase::cache_elem_dims(), libMesh::System::calculate_norm(), coarsen_elements(), 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::Problem_Interface::computeF(), libMesh::Problem_Interface::computeJacobian(), libMesh::Problem_Interface::computePreconditioner(), libMesh::MeshTools::correct_node_proc_ids(), libMesh::MeshCommunication::delete_remote_elements(), libMesh::DofMap::distribute_dofs(), DMlibMeshFunction(), DMlibMeshSetSystem_libMesh(), eliminate_unrefined_patches(), libMesh::WeightedPatchRecoveryErrorEstimator::estimate_error(), libMesh::PatchRecoveryErrorEstimator::estimate_error(), libMesh::JumpErrorEstimator::estimate_error(), libMesh::AdjointRefinementEstimator::estimate_error(), libMesh::ExactErrorEstimator::estimate_error(), flag_elements_by_elem_fraction(), flag_elements_by_error_fraction(), flag_elements_by_nelem_target(), libMesh::CondensedEigenSystem::get_eigenpair(), libMesh::ImplicitSystem::get_linear_solver(), libMesh::LocationMap< T >::init(), libMesh::TimeSolver::init(), libMesh::SystemSubsetBySubdomain::init(), libMesh::EigenSystem::init_data(), libMesh::EigenSystem::init_matrices(), libMesh::ParmetisPartitioner::initialize(), libMesh::MeshTools::libmesh_assert_valid_dof_ids(), libMesh::ParallelMesh::libmesh_assert_valid_parallel_flags(), libMesh::MeshTools::libmesh_assert_valid_procids< Elem >(), libMesh::MeshTools::libmesh_assert_valid_procids< Node >(), libMesh::MeshTools::libmesh_assert_valid_refinement_flags(), limit_level_mismatch_at_edge(), limit_level_mismatch_at_node(), make_coarsening_compatible(), libMesh::MeshCommunication::make_elems_parallel_consistent(), make_flags_parallel_consistent(), libMesh::MeshCommunication::make_node_ids_parallel_consistent(), libMesh::MeshCommunication::make_node_proc_ids_parallel_consistent(), libMesh::MeshCommunication::make_nodes_parallel_consistent(), make_refinement_compatible(), libMesh::FEMSystem::mesh_position_set(), libMesh::MeshSerializer::MeshSerializer(), libMesh::ParallelMesh::n_active_elem(), libMesh::MeshTools::n_active_levels(), libMesh::BoundaryInfo::n_boundary_conds(), libMesh::BoundaryInfo::n_edge_conds(), libMesh::CondensedEigenSystem::n_global_non_condensed_dofs(), libMesh::MeshTools::n_levels(), libMesh::BoundaryInfo::n_nodeset_conds(), libMesh::MeshTools::n_p_levels(), libMesh::ParallelMesh::parallel_max_elem_id(), libMesh::ParallelMesh::parallel_max_node_id(), libMesh::ParallelMesh::parallel_n_elem(), libMesh::ParallelMesh::parallel_n_nodes(), 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::System::project_vector(), libMesh::Nemesis_IO::read(), libMesh::XdrIO::read(), libMesh::System::read_header(), libMesh::System::read_legacy_data(), libMesh::System::read_SCALAR_dofs(), libMesh::XdrIO::read_serialized_bc_names(), libMesh::XdrIO::read_serialized_bcs(), 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::MeshBase::recalculate_n_partitions(), refine_and_coarsen_elements(), refine_elements(), libMesh::Partitioner::set_node_processor_ids(), libMesh::DofMap::set_nonlocal_dof_objects(), libMesh::LaplaceMeshSmoother::smooth(), libMesh::MeshBase::subdomain_ids(), libMesh::BoundaryInfo::sync(), libMesh::Parallel::sync_element_data_by_parent_id(), libMesh::Parallel::sync_node_data_by_element_id(), test_level_one(), test_unflagged(), libMesh::MeshTools::total_weight(), libMesh::NameBasedIO::write(), libMesh::CheckpointIO::write(), libMesh::XdrIO::write(), libMesh::LegacyXdrIO::write_mesh(), libMesh::System::write_SCALAR_dofs(), libMesh::XdrIO::write_serialized_bcs(), libMesh::System::write_serialized_blocked_dof_objects(), libMesh::XdrIO::write_serialized_connectivity(), libMesh::XdrIO::write_serialized_nodes(), libMesh::XdrIO::write_serialized_nodesets(), and libMesh::DivaIO::write_stream().

  { return _communicator; }
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 162 of file mesh_refinement.C.

References libMesh::DofObject::id(), libMesh::libmesh_assert(), std::max(), std::min(), libMesh::Elem::parent(), and libMesh::Parallel::verify().

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

{
  // This function must be run on all processors at once
  parallel_object_only();

  // Make sure the input error vector is valid
#ifdef DEBUG
  for (std::size_t i=0; i != error_per_cell.size(); ++i)
    {
      libmesh_assert_greater_equal (error_per_cell[i], 0);
      // isnan() isn't standard C++ yet
#ifdef isnan
      libmesh_assert(!isnan(error_per_cell[i]));
#endif
    }

  // Use a reference to std::vector to avoid confusing
  // this->comm().verify
  std::vector<ErrorVectorReal> &epc = error_per_parent;
  libmesh_assert(this->comm().verify(epc));
#endif // #ifdef DEBUG

  // error values on uncoarsenable elements will be left at -1
  error_per_parent.clear();
  error_per_parent.resize(error_per_cell.size(), 0.0);

  {
    // Find which elements are uncoarsenable
    MeshBase::element_iterator       elem_it  = _mesh.active_local_elements_begin();
    const MeshBase::element_iterator elem_end = _mesh.active_local_elements_end();
    for (; elem_it != elem_end; ++elem_it)
      {
        Elem* elem   = *elem_it;
        Elem* parent = elem->parent();

        // Active elements are uncoarsenable
        error_per_parent[elem->id()] = -1.0;

        // Grandparents and up are uncoarsenable
        while (parent)
          {
            parent = parent->parent();
            if (parent)
              {
                const dof_id_type parentid  = parent->id();
                libmesh_assert_less (parentid, error_per_parent.size());
                error_per_parent[parentid] = -1.0;
              }
          }
      }

    // Sync between processors.
    // Use a reference to std::vector to avoid confusing
    // this->comm().min
    std::vector<ErrorVectorReal> &epp = error_per_parent;
    this->comm().min(epp);
  }

  // The parent's error is defined as the square root of the
  // sum of the children's errors squared, so errors that are
  // Hilbert norms remain Hilbert norms.
  //
  // Because the children may be on different processors, we
  // calculate local contributions to the parents' errors squared
  // first, then sum across processors and take the square roots
  // second.
  {
    MeshBase::element_iterator       elem_it  = _mesh.active_local_elements_begin();
    const MeshBase::element_iterator elem_end = _mesh.active_local_elements_end();

    for (; elem_it != elem_end; ++elem_it)
      {
        Elem* elem   = *elem_it;
        Elem* parent = elem->parent();

        // Calculate each contribution to parent cells
        if (parent)
          {
            const dof_id_type parentid  = parent->id();
            libmesh_assert_less (parentid, error_per_parent.size());

            // If the parent has grandchildren we won't be able to
            // coarsen it, so forget it.  Otherwise, add this child's
            // contribution to the sum of the squared child errors
            if (error_per_parent[parentid] != -1.0)
              error_per_parent[parentid] += (error_per_cell[elem->id()] *
                                             error_per_cell[elem->id()]);
          }
      }
  }

  // Sum the vector across all processors
  this->comm().sum(static_cast<std::vector<ErrorVectorReal>&>(error_per_parent));

  // Calculate the min and max as we loop
  parent_error_min = std::numeric_limits<double>::max();
  parent_error_max = 0.;

  for (std::size_t i = 0; i != error_per_parent.size(); ++i)
    {
      // If this element isn't a coarsenable parent with error, we
      // have nothing to do.  Just flag it as -1 and move on
      // Note that this->comm().sum might have left uncoarsenable
      // elements with error_per_parent=-n_proc, so reset it to
      // error_per_parent=-1
      if (error_per_parent[i] < 0.)
        {
          error_per_parent[i] = -1.;
          continue;
        }

      // The error estimator might have already given us an
      // estimate on the coarsenable parent elements; if so then
      // we want to retain that estimate
      if (error_per_cell[i])
        {
          error_per_parent[i] = error_per_cell[i];
          continue;
        }
      // if not, then e_parent = sqrt(sum(e_child^2))
      else
        error_per_parent[i] = std::sqrt(error_per_parent[i]);

      parent_error_min = std::min (parent_error_min,
                                   error_per_parent[i]);
      parent_error_max = std::max (parent_error_max,
                                   error_per_parent[i]);
    }
}

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

References _edge_level_mismatch_limit.

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

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

into this:

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

by refining the indicated element

Definition at line 282 of file mesh_refinement_smoothing.C.

References _mesh, libMesh::Elem::active(), libMesh::MeshBase::active_elements_begin(), libMesh::MeshBase::active_elements_end(), libMesh::Elem::ancestor(), libMesh::Elem::child(), libMesh::Elem::COARSEN, libMesh::Elem::COARSEN_INACTIVE, libMesh::ParallelObject::comm(), libMesh::Elem::DO_NOTHING, libMesh::Elem::INACTIVE, libMesh::Elem::level(), libMesh::libmesh_assert(), libMesh::Parallel::Communicator::max(), libMesh::Elem::min_new_p_level_by_neighbor(), libMesh::Elem::n_children(), libMesh::Elem::n_neighbors(), libMesh::Elem::neighbor(), 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(), and libMesh::Elem::set_refinement_flag().

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

{
  // This function must be run on all processors at once
  parallel_object_only();

  bool flags_changed = false;

  MeshBase::element_iterator       elem_it  = _mesh.active_elements_begin();
  const MeshBase::element_iterator elem_end = _mesh.active_elements_end();

  for (; elem_it != elem_end; ++elem_it)
    {
      Elem* elem = *elem_it;
      // First assume that we'll have to flag this element for both h
      // and p refinement, then change our minds if we see any
      // neighbors that are as coarse or coarser than us.
      bool h_flag_me = true,
        p_flag_me = true;


      // Skip the element if it is already fully flagged for refinement
      if (elem->p_refinement_flag() == Elem::REFINE)
        p_flag_me = false;
      if (elem->refinement_flag() == Elem::REFINE)
        {
          h_flag_me = false;
          if (!p_flag_me)
            continue;
        }
      // Test the parent if that is already flagged for coarsening
      else if (elem->refinement_flag() == Elem::COARSEN)
        {
          libmesh_assert(elem->parent());
          elem = elem->parent();
          // FIXME - this doesn't seem right - RHS
          if (elem->refinement_flag() != Elem::COARSEN_INACTIVE)
            continue;
          p_flag_me = false;
        }

      const unsigned int my_level = elem->level();
      int my_p_adjustment = 0;
      if (elem->p_refinement_flag() == Elem::REFINE)
        my_p_adjustment = 1;
      else if (elem->p_refinement_flag() == Elem::COARSEN)
        {
          libmesh_assert_greater (elem->p_level(), 0);
          my_p_adjustment = -1;
        }
      const unsigned int my_new_p_level = elem->p_level() +
        my_p_adjustment;

      // Check all the element neighbors
      for (unsigned int n=0; n<elem->n_neighbors(); n++)
        {
          const Elem *neighbor = elem->neighbor(n);
          // Quit if the element is on a local boundary
          if (neighbor == NULL || neighbor == remote_elem)
            {
              h_flag_me = false;
              p_flag_me = false;
              break;
            }
          // if the neighbor will be equally or less refined than
          // we are, then we will not become an unrefined island.
          // So if we are still considering h refinement:
          if (h_flag_me &&
              // If our neighbor is already at a lower level,
              // it can't end up at a higher level even if it
              // is flagged for refinement once
              ((neighbor->level() < my_level) ||
               // If our neighbor is at the same level but isn't
               // flagged for refinement, it won't end up at a
               // higher level
               ((neighbor->active()) &&
                (neighbor->refinement_flag() != Elem::REFINE)) ||
               // If our neighbor is currently more refined but is
               // a parent flagged for coarsening, it will end up
               // at the same level.
               (neighbor->refinement_flag() == Elem::COARSEN_INACTIVE)))
            {
              // We've proven we won't become an unrefined island,
              // so don't h refine to avoid that.
              h_flag_me = false;

              // If we've also proven we don't need to p refine,
              // we don't need to check more neighbors
              if (!p_flag_me)
                break;
            }
          if (p_flag_me)
            {
              // if active neighbors will have a p level
              // equal to or lower than ours, then we do not need to p
              // refine ourselves.
              if (neighbor->active())
                {
                  int p_adjustment = 0;
                  if (neighbor->p_refinement_flag() == Elem::REFINE)
                    p_adjustment = 1;
                  else if (neighbor->p_refinement_flag() == Elem::COARSEN)
                    {
                      libmesh_assert_greater (neighbor->p_level(), 0);
                      p_adjustment = -1;
                    }
                  if (my_new_p_level >= neighbor->p_level() + p_adjustment)
                    {
                      p_flag_me = false;
                      if (!h_flag_me)
                        break;
                    }
                }
              // If we have inactive neighbors, we need to
              // test all their active descendants which neighbor us
              else if (neighbor->ancestor())
                {
                  if (neighbor->min_new_p_level_by_neighbor(elem,
                                                            my_new_p_level + 2) <= my_new_p_level)
                    {
                      p_flag_me = false;
                      if (!h_flag_me)
                        break;
                    }
                }
            }
        }

      if (h_flag_me)
        {
          // Parents that would create islands should no longer
          // coarsen
          if (elem->refinement_flag() == Elem::COARSEN_INACTIVE)
            {
              for (unsigned int c=0; c<elem->n_children(); c++)
                {
                  libmesh_assert_equal_to (elem->child(c)->refinement_flag(),
                                           Elem::COARSEN);
                  elem->child(c)->set_refinement_flag(Elem::DO_NOTHING);
                }
              elem->set_refinement_flag(Elem::INACTIVE);
            }
          else
            elem->set_refinement_flag(Elem::REFINE);
          flags_changed = true;
        }
      if (p_flag_me)
        {
          if (elem->p_refinement_flag() == Elem::COARSEN)
            elem->set_p_refinement_flag(Elem::DO_NOTHING);
          else
            elem->set_p_refinement_flag(Elem::REFINE);
          flags_changed = true;
        }
    }

  // If flags changed on any processor then they changed globally
  this->comm().max(flags_changed);

  return flags_changed;
}
bool libMesh::MeshRefinement::enforce_mismatch_limit_prior_to_refinement ( Elem elem,
NeighborType  nt,
unsigned  max_mismatch 
) [private]

Definition at line 445 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().

{
  // Eventual return value
  bool flags_changed = false;

  // If we are enforcing the limit prior to refinement then we
  // need to remove flags from any elements marked for refinement that
  // would cause a mismatch
  if (_enforce_mismatch_limit_prior_to_refinement
      && elem->refinement_flag() == Elem::REFINE)
    {
      // get all the POINT neighbors since we may have to refine
      // elements off the corner as well
      std::set<const Elem*> neighbor_set;

      if (nt == POINT)
        elem->find_point_neighbors(neighbor_set);
      else if (nt == EDGE)
        elem->find_edge_neighbors(neighbor_set);
      else
        libmesh_error_msg("Unrecognized NeighborType: " << nt);

      // Loop over the neighbors of element e
      std::set<const Elem*>::iterator n_it = neighbor_set.begin();
      for (; n_it != neighbor_set.end(); ++n_it)
        {
          const Elem* neighbor = *n_it;

          if ((elem->level() + 1 - max_mismatch) > neighbor->level())
            {
              elem->set_refinement_flag(Elem::DO_NOTHING);
              flags_changed = true;
            }
          if ((elem->p_level() + 1 - max_mismatch) > neighbor->p_level())
            {
              elem->set_p_refinement_flag(Elem::DO_NOTHING);
              flags_changed = true;
            }
        } // loop over edge/point neighbors
    } // if _enforce_mismatch_limit_prior_to_refinement

  return flags_changed;
}

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

References _face_level_mismatch_limit.

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

Flag elements based on a function object. The class ElementFlagging defines a mechanism for implementing refinement strategies.

Definition at line 655 of file mesh_refinement_flagging.C.

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

{
  element_flagging.flag_elements();
}
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 452 of file mesh_refinement_flagging.C.

References _coarsen_by_parents, _coarsen_fraction, _max_h_level, _mesh, _refine_fraction, _use_member_parameters, libMesh::MeshBase::active_elements_begin(), libMesh::MeshBase::active_local_elements_begin(), libMesh::MeshBase::active_local_elements_end(), libMesh::Parallel::Communicator::allgather(), clean_refinement_flags(), libMesh::Elem::COARSEN, libMesh::ParallelObject::comm(), create_parent_error_vector(), libMesh::ErrorVectorReal, libMesh::DofObject::id(), libMesh::invalid_uint, libMesh::Elem::level(), libMesh::MeshBase::mesh_dimension(), libMesh::MeshBase::n_elem(), libMesh::Elem::parent(), libMesh::Real, libMesh::Elem::REFINE, and libMesh::Elem::set_refinement_flag().

{
  parallel_object_only();

  // The function arguments are currently just there for
  // backwards_compatibility
  if (!_use_member_parameters)
    {
      // If the user used non-default parameters, lets warn
      // that they're deprecated
      if (refine_frac != 0.3 ||
          coarsen_frac != 0.0 ||
          max_l != libMesh::invalid_uint)
        libmesh_deprecated();

      _refine_fraction = refine_frac;
      _coarsen_fraction = coarsen_frac;
      _max_h_level = max_l;
    }

  // Check for valid fractions..
  // The fraction values must be in [0,1]
  libmesh_assert_greater_equal (_refine_fraction, 0);
  libmesh_assert_less_equal (_refine_fraction, 1);
  libmesh_assert_greater_equal (_coarsen_fraction, 0);
  libmesh_assert_less_equal (_coarsen_fraction, 1);

  // The number of active elements in the mesh
  const dof_id_type n_active_elem  = _mesh.n_elem();

  // The number of elements to flag for coarsening
  const dof_id_type n_elem_coarsen =
    static_cast<dof_id_type>(_coarsen_fraction * n_active_elem);

  // The number of elements to flag for refinement
  const dof_id_type n_elem_refine =
    static_cast<dof_id_type>(_refine_fraction  * n_active_elem);



  // Clean up the refinement flags.  These could be left
  // over from previous refinement steps.
  this->clean_refinement_flags();


  // This vector stores the error and element number for all the
  // active elements.  It will be sorted and the top & bottom
  // elements will then be flagged for coarsening & refinement
  std::vector<ErrorVectorReal> sorted_error;

  sorted_error.reserve (n_active_elem);

  // Loop over the active elements and create the entry
  // in the sorted_error vector
  MeshBase::element_iterator       elem_it  = _mesh.active_local_elements_begin();
  const MeshBase::element_iterator elem_end = _mesh.active_local_elements_end();

  for (; elem_it != elem_end; ++elem_it)
    sorted_error.push_back (error_per_cell[(*elem_it)->id()]);

  this->comm().allgather(sorted_error);

  // Now sort the sorted_error vector
  std::sort (sorted_error.begin(), sorted_error.end());

  // If we're coarsening by parents:
  // Create a sorted error vector with coarsenable parent elements
  // only, sorted by lowest errors first
  ErrorVector error_per_parent, sorted_parent_error;
  if (_coarsen_by_parents)
    {
      Real parent_error_min, parent_error_max;

      create_parent_error_vector(error_per_cell,
                                 error_per_parent,
                                 parent_error_min,
                                 parent_error_max);

      sorted_parent_error = error_per_parent;
      std::sort (sorted_parent_error.begin(), sorted_parent_error.end());

      // All the other error values will be 0., so get rid of them.
      sorted_parent_error.erase (std::remove(sorted_parent_error.begin(),
                                             sorted_parent_error.end(), 0.),
                                 sorted_parent_error.end());
    }


  ErrorVectorReal top_error= 0., bottom_error = 0.;

  // Get the maximum error value corresponding to the
  // bottom n_elem_coarsen elements
  if (_coarsen_by_parents && n_elem_coarsen)
    {
      const unsigned int dim = _mesh.mesh_dimension();
      unsigned int twotodim = 1;
      for (unsigned int i=0; i!=dim; ++i)
        twotodim *= 2;

      dof_id_type n_parent_coarsen = n_elem_coarsen / (twotodim - 1);

      if (n_parent_coarsen)
        bottom_error = sorted_parent_error[n_parent_coarsen - 1];
    }
  else if (n_elem_coarsen)
    {
      bottom_error = sorted_error[n_elem_coarsen - 1];
    }

  if (n_elem_refine)
    top_error = sorted_error[sorted_error.size() - n_elem_refine];

  // Finally, let's do the element flagging
  elem_it  = _mesh.active_elements_begin();
  for (; elem_it != elem_end; ++elem_it)
    {
      Elem* elem = *elem_it;
      Elem* parent = elem->parent();

      if (_coarsen_by_parents && parent && n_elem_coarsen &&
          error_per_parent[parent->id()] <= bottom_error)
        elem->set_refinement_flag(Elem::COARSEN);

      if (!_coarsen_by_parents && n_elem_coarsen &&
          error_per_cell[elem->id()] <= bottom_error)
        elem->set_refinement_flag(Elem::COARSEN);

      if (n_elem_refine &&
          elem->level() < _max_h_level &&
          error_per_cell[elem->id()] >= top_error)
        elem->set_refinement_flag(Elem::REFINE);
    }
}
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 45 of file mesh_refinement_flagging.C.

References _coarsen_by_parents, _coarsen_fraction, _max_h_level, _mesh, _refine_fraction, _use_member_parameters, libMesh::MeshBase::active_elements_begin(), libMesh::MeshBase::active_elements_end(), libMesh::MeshBase::active_local_elements_begin(), libMesh::MeshBase::active_local_elements_end(), clean_refinement_flags(), libMesh::Elem::COARSEN, libMesh::ParallelObject::comm(), create_parent_error_vector(), libMesh::ErrorVectorReal, libMesh::DofObject::id(), libMesh::invalid_uint, libMesh::Elem::level(), std::max(), libMesh::Parallel::Communicator::max(), std::min(), libMesh::Parallel::Communicator::min(), libMesh::Elem::parent(), libMesh::Real, libMesh::Elem::REFINE, and libMesh::Elem::set_refinement_flag().

{
  parallel_object_only();

  // The function arguments are currently just there for
  // backwards_compatibility
  if (!_use_member_parameters)
    {
      // If the user used non-default parameters, lets warn
      // that they're deprecated
      if (refine_frac != 0.3 ||
          coarsen_frac != 0.0 ||
          max_l != libMesh::invalid_uint)
        libmesh_deprecated();

      _refine_fraction = refine_frac;
      _coarsen_fraction = coarsen_frac;
      _max_h_level = max_l;
    }

  // Check for valid fractions..
  // The fraction values must be in [0,1]
  libmesh_assert_greater_equal (_refine_fraction, 0);
  libmesh_assert_less_equal (_refine_fraction, 1);
  libmesh_assert_greater_equal (_coarsen_fraction, 0);
  libmesh_assert_less_equal (_coarsen_fraction, 1);

  // Clean up the refinement flags.  These could be left
  // over from previous refinement steps.
  this->clean_refinement_flags();

  // We're getting the minimum and maximum error values
  // for the ACTIVE elements
  Real error_min = 1.e30;
  Real error_max = 0.;

  // And, if necessary, for their parents
  Real parent_error_min = 1.e30;
  Real parent_error_max = 0.;

  // Prepare another error vector if we need to sum parent errors
  ErrorVector error_per_parent;
  if (_coarsen_by_parents)
    {
      create_parent_error_vector(error_per_cell,
                                 error_per_parent,
                                 parent_error_min,
                                 parent_error_max);
    }

  // We need to loop over all active elements to find the minimum
  MeshBase::element_iterator       el_it  =
    _mesh.active_local_elements_begin();
  const MeshBase::element_iterator el_end =
    _mesh.active_local_elements_end();

  for (; el_it != el_end; ++el_it)
    {
      const dof_id_type id  = (*el_it)->id();
      libmesh_assert_less (id, error_per_cell.size());

      error_max = std::max (error_max, error_per_cell[id]);
      error_min = std::min (error_min, error_per_cell[id]);
    }
  this->comm().max(error_max);
  this->comm().min(error_min);

  // Compute the cutoff values for coarsening and refinement
  const Real error_delta = (error_max - error_min);
  const Real parent_error_delta = parent_error_max - parent_error_min;

  const Real refine_cutoff  = (1.- _refine_fraction)*error_max;
  const Real coarsen_cutoff = _coarsen_fraction*error_delta + error_min;
  const Real parent_cutoff = _coarsen_fraction*parent_error_delta + error_min;

  //   // Print information about the error
  //   libMesh::out << " Error Information:"                     << std::endl
  //     << " ------------------"                     << std::endl
  //     << "   min:              " << error_min      << std::endl
  //     << "   max:              " << error_max      << std::endl
  //     << "   delta:            " << error_delta    << std::endl
  //     << "     refine_cutoff:  " << refine_cutoff  << std::endl
  //     << "     coarsen_cutoff: " << coarsen_cutoff << std::endl;



  // Loop over the elements and flag them for coarsening or
  // refinement based on the element error

  MeshBase::element_iterator       e_it  =
    _mesh.active_elements_begin();
  const MeshBase::element_iterator e_end =
    _mesh.active_elements_end();
  for (; e_it != e_end; ++e_it)
    {
      Elem* elem           = *e_it;
      const dof_id_type id = elem->id();

      libmesh_assert_less (id, error_per_cell.size());

      const ErrorVectorReal elem_error = error_per_cell[id];

      if (_coarsen_by_parents)
        {
          Elem* parent           = elem->parent();
          if (parent)
            {
              const dof_id_type parentid  = parent->id();
              if (error_per_parent[parentid] >= 0. &&
                  error_per_parent[parentid] <= parent_cutoff)
                elem->set_refinement_flag(Elem::COARSEN);
            }
        }
      // Flag the element for coarsening if its error
      // is <= coarsen_fraction*delta + error_min
      else if (elem_error <= coarsen_cutoff)
        {
          elem->set_refinement_flag(Elem::COARSEN);
        }

      // Flag the element for refinement if its error
      // is >= refinement_cutoff.
      if (elem_error >= refine_cutoff)
        if (elem->level() < _max_h_level)
          elem->set_refinement_flag(Elem::REFINE);
    }
}

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

References _absolute_global_tolerance, _coarsen_by_parents, _coarsen_fraction, _coarsen_threshold, _max_h_level, _mesh, _refine_fraction, libMesh::MeshBase::active_elements_begin(), libMesh::MeshBase::active_elements_end(), libMesh::Elem::COARSEN, create_parent_error_vector(), libMesh::ErrorVectorReal, libMesh::DofObject::id(), libMesh::Elem::level(), libMesh::MeshBase::n_active_elem(), libMesh::Elem::n_children(), libMesh::Elem::parent(), libMesh::Real, libMesh::Elem::REFINE, and libMesh::Elem::set_refinement_flag().

{
  parallel_object_only();

  libmesh_assert_greater (_coarsen_threshold, 0);

  // Check for valid fractions..
  // The fraction values must be in [0,1]
  libmesh_assert_greater_equal (_refine_fraction, 0);
  libmesh_assert_less_equal (_refine_fraction, 1);
  libmesh_assert_greater_equal (_coarsen_fraction, 0);
  libmesh_assert_less_equal (_coarsen_fraction, 1);

  // How much error per cell will we tolerate?
  const Real local_refinement_tolerance =
    _absolute_global_tolerance / std::sqrt(static_cast<Real>(_mesh.n_active_elem()));
  const Real local_coarsening_tolerance =
    local_refinement_tolerance * _coarsen_threshold;

  // Prepare another error vector if we need to sum parent errors
  ErrorVector error_per_parent;
  if (_coarsen_by_parents)
    {
      Real parent_error_min, parent_error_max;

      create_parent_error_vector(error_per_cell_in,
                                 error_per_parent,
                                 parent_error_min,
                                 parent_error_max);
    }

  MeshBase::element_iterator       elem_it  = _mesh.active_elements_begin();
  const MeshBase::element_iterator elem_end = _mesh.active_elements_end();

  for (; elem_it != elem_end; ++elem_it)
    {
      Elem* elem = *elem_it;
      Elem* parent = elem->parent();
      const dof_id_type elem_number    = elem->id();
      const ErrorVectorReal elem_error = error_per_cell_in[elem_number];

      if (elem_error > local_refinement_tolerance &&
          elem->level() < _max_h_level)
        elem->set_refinement_flag(Elem::REFINE);

      if (!_coarsen_by_parents && elem_error <
          local_coarsening_tolerance)
        elem->set_refinement_flag(Elem::COARSEN);

      if (_coarsen_by_parents && parent)
        {
          ErrorVectorReal parent_error = error_per_parent[parent->id()];
          if (parent_error >= 0.)
            {
              const Real parent_coarsening_tolerance =
                std::sqrt(parent->n_children() *
                          local_coarsening_tolerance *
                          local_coarsening_tolerance);
              if (parent_error < parent_coarsening_tolerance)
                elem->set_refinement_flag(Elem::COARSEN);
            }
        }
    }
}
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 591 of file mesh_refinement_flagging.C.

References _coarsen_fraction, _max_h_level, _mesh, _refine_fraction, _use_member_parameters, libMesh::MeshBase::active_elements_begin(), libMesh::MeshBase::active_elements_end(), libMesh::Elem::COARSEN, libMesh::ErrorVectorReal, libMesh::DofObject::id(), libMesh::invalid_uint, libMesh::Elem::level(), std::max(), libMesh::ErrorVector::mean(), libMesh::Real, libMesh::Elem::REFINE, libMesh::Elem::set_refinement_flag(), and libMesh::ErrorVector::variance().

{
  // The function arguments are currently just there for
  // backwards_compatibility
  if (!_use_member_parameters)
    {
      // If the user used non-default parameters, lets warn
      // that they're deprecated
      if (refine_frac != 0.3 ||
          coarsen_frac != 0.0 ||
          max_l != libMesh::invalid_uint)
        libmesh_deprecated();

      _refine_fraction = refine_frac;
      _coarsen_fraction = coarsen_frac;
      _max_h_level = max_l;
    }

  // Get the mean value from the error vector
  const Real mean = error_per_cell.mean();

  // Get the standard deviation.  This equals the
  // square-root of the variance
  const Real stddev = std::sqrt (error_per_cell.variance());

  // Check for valid fractions
  libmesh_assert_greater_equal (_refine_fraction, 0);
  libmesh_assert_less_equal (_refine_fraction, 1);
  libmesh_assert_greater_equal (_coarsen_fraction, 0);
  libmesh_assert_less_equal (_coarsen_fraction, 1);

  // The refine and coarsen cutoff
  const Real refine_cutoff  =  mean + _refine_fraction  * stddev;
  const Real coarsen_cutoff =  std::max(mean - _coarsen_fraction * stddev, 0.);

  // Loop over the elements and flag them for coarsening or
  // refinement based on the element error
  MeshBase::element_iterator       elem_it  = _mesh.active_elements_begin();
  const MeshBase::element_iterator elem_end = _mesh.active_elements_end();

  for (; elem_it != elem_end; ++elem_it)
    {
      Elem* elem             = *elem_it;
      const dof_id_type id  = elem->id();

      libmesh_assert_less (id, error_per_cell.size());

      const ErrorVectorReal elem_error = error_per_cell[id];

      // Possibly flag the element for coarsening ...
      if (elem_error <= coarsen_cutoff)
        elem->set_refinement_flag(Elem::COARSEN);

      // ... or refinement
      if ((elem_error >= refine_cutoff) && (elem->level() < _max_h_level))
        elem->set_refinement_flag(Elem::REFINE);
    }
}

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. This method 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 245 of file mesh_refinement_flagging.C.

References _coarsen_by_parents, _coarsen_fraction, _coarsen_threshold, _max_h_level, _mesh, _nelem_target, _refine_fraction, libMesh::Elem::active(), libMesh::MeshBase::active_local_elements_begin(), libMesh::MeshBase::active_local_elements_end(), libMesh::Parallel::Communicator::allgather(), libMesh::Elem::child(), clean_refinement_flags(), libMesh::Elem::COARSEN, libMesh::ParallelObject::comm(), create_parent_error_vector(), libMesh::Elem::has_children(), libMesh::Elem::level(), libMesh::libmesh_assert(), libMesh::Parallel::Communicator::max(), libMesh::MeshBase::max_elem_id(), libMesh::MeshBase::mesh_dimension(), std::min(), libMesh::MeshBase::n_active_elem(), libMesh::Elem::n_children(), libMesh::MeshBase::query_elem(), libMesh::Real, libMesh::Elem::REFINE, libMesh::remote_elem, and libMesh::Elem::set_refinement_flag().

{
  parallel_object_only();

  // Check for valid fractions..
  // The fraction values must be in [0,1]
  libmesh_assert_greater_equal (_refine_fraction, 0);
  libmesh_assert_less_equal (_refine_fraction, 1);
  libmesh_assert_greater_equal (_coarsen_fraction, 0);
  libmesh_assert_less_equal (_coarsen_fraction, 1);

  // This function is currently only coded to work when coarsening by
  // parents - it's too hard to guess how many coarsenings will be
  // performed otherwise.
  libmesh_assert (_coarsen_by_parents);

  // The number of active elements in the mesh - hopefully less than
  // 2 billion on 32 bit machines
  const dof_id_type n_active_elem  = _mesh.n_active_elem();

  // The maximum number of active elements to flag for coarsening
  const dof_id_type max_elem_coarsen =
    static_cast<dof_id_type>(_coarsen_fraction * n_active_elem) + 1;

  // The maximum number of elements to flag for refinement
  const dof_id_type max_elem_refine  =
    static_cast<dof_id_type>(_refine_fraction  * n_active_elem) + 1;

  // Clean up the refinement flags.  These could be left
  // over from previous refinement steps.
  this->clean_refinement_flags();

  // The target number of elements to add or remove
  const std::ptrdiff_t n_elem_new = _nelem_target - n_active_elem;

  // Create an vector with active element errors and ids,
  // sorted by highest errors first
  const dof_id_type max_elem_id = _mesh.max_elem_id();
  std::vector<std::pair<ErrorVectorReal, dof_id_type> > sorted_error;

  sorted_error.reserve (n_active_elem);

  // On a ParallelMesh, we need to communicate to know which remote ids
  // correspond to active elements.
  {
    std::vector<bool> is_active(max_elem_id, false);

    MeshBase::element_iterator       elem_it  = _mesh.active_local_elements_begin();
    const MeshBase::element_iterator elem_end = _mesh.active_local_elements_end();
    for (; elem_it != elem_end; ++elem_it)
      {
        const dof_id_type eid = (*elem_it)->id();
        is_active[eid] = true;
        libmesh_assert_less (eid, error_per_cell.size());
        sorted_error.push_back
          (std::make_pair(error_per_cell[eid], eid));
      }

    this->comm().max(is_active);

    this->comm().allgather(sorted_error);
  }

  // Default sort works since pairs are sorted lexicographically
  std::sort (sorted_error.begin(), sorted_error.end());
  std::reverse (sorted_error.begin(), sorted_error.end());

  // Create a sorted error vector with coarsenable parent elements
  // only, sorted by lowest errors first
  ErrorVector error_per_parent;
  std::vector<std::pair<ErrorVectorReal, dof_id_type> > sorted_parent_error;
  Real parent_error_min, parent_error_max;

  create_parent_error_vector(error_per_cell,
                             error_per_parent,
                             parent_error_min,
                             parent_error_max);

  // create_parent_error_vector sets values for non-parents and
  // non-coarsenable parents to -1.  Get rid of them.
  for (dof_id_type i=0; i != error_per_parent.size(); ++i)
    if (error_per_parent[i] != -1)
      sorted_parent_error.push_back(std::make_pair(error_per_parent[i], i));

  std::sort (sorted_parent_error.begin(), sorted_parent_error.end());

  // Keep track of how many elements we plan to coarsen & refine
  dof_id_type coarsen_count = 0;
  dof_id_type refine_count = 0;

  const unsigned int dim = _mesh.mesh_dimension();
  unsigned int twotodim = 1;
  for (unsigned int i=0; i!=dim; ++i)
    twotodim *= 2;

  // First, let's try to get our element count to target_nelem
  if (n_elem_new >= 0)
    {
      // Every element refinement creates at least
      // 2^dim-1 new elements
      refine_count =
        std::min(cast_int<dof_id_type>(n_elem_new / (twotodim-1)),
                 max_elem_refine);
    }
  else
    {
      // Every successful element coarsening is likely to destroy
      // 2^dim-1 net elements.
      coarsen_count =
        std::min(cast_int<dof_id_type>(-n_elem_new / (twotodim-1)),
                 max_elem_coarsen);
    }

  // Next, let's see if we can trade any refinement for coarsening
  while (coarsen_count < max_elem_coarsen &&
         refine_count < max_elem_refine &&
         coarsen_count < sorted_parent_error.size() &&
         refine_count < sorted_error.size() &&
         sorted_error[refine_count].first >
         sorted_parent_error[coarsen_count].first * _coarsen_threshold)
    {
      coarsen_count++;
      refine_count++;
    }

  // On a ParallelMesh, we need to communicate to know which remote ids
  // correspond to refinable elements
  dof_id_type successful_refine_count = 0;
  {
    std::vector<bool> is_refinable(max_elem_id, false);

    for (dof_id_type i=0; i != sorted_error.size(); ++i)
      {
        dof_id_type eid = sorted_error[i].second;
        Elem *elem = _mesh.query_elem(eid);
        if (elem && elem->level() < _max_h_level)
          is_refinable[eid] = true;
      }
    this->comm().max(is_refinable);

    if (refine_count > max_elem_refine)
      refine_count = max_elem_refine;
    for (dof_id_type i=0; i != sorted_error.size(); ++i)
      {
        if (successful_refine_count >= refine_count)
          break;

        dof_id_type eid = sorted_error[i].second;
        Elem *elem = _mesh.query_elem(eid);
        if (is_refinable[eid])
          {
            if (elem)
              elem->set_refinement_flag(Elem::REFINE);
            successful_refine_count++;
          }
      }
  }

  // If we couldn't refine enough elements, don't coarsen too many
  // either
  if (coarsen_count < (refine_count - successful_refine_count))
    coarsen_count = 0;
  else
    coarsen_count -= (refine_count - successful_refine_count);

  if (coarsen_count > max_elem_coarsen)
    coarsen_count = max_elem_coarsen;

  dof_id_type successful_coarsen_count = 0;
  if (coarsen_count)
    {
      for (dof_id_type i=0; i != sorted_parent_error.size(); ++i)
        {
          if (successful_coarsen_count >= coarsen_count * twotodim)
            break;

          dof_id_type parent_id = sorted_parent_error[i].second;
          Elem *parent = _mesh.query_elem(parent_id);

          // On a ParallelMesh we skip remote elements
          if (!parent)
            continue;

          libmesh_assert(parent->has_children());
          for (unsigned int c=0; c != parent->n_children(); ++c)
            {
              Elem *elem = parent->child(c);
              if (elem && elem != remote_elem)
                {
                  libmesh_assert(elem->active());
                  elem->set_refinement_flag(Elem::COARSEN);
                  successful_coarsen_count++;
                }
            }
        }
    }

  // Return true if we've done all the AMR/C we can
  if (!successful_coarsen_count &&
      !successful_refine_count)
    return true;
  // And false if there may still be more to do.
  return false;
}

Returns the state of the _enforce_mismatch_limit_prior_to_refinement flag. Defaults to false. Deprecated - use enforce_mismatch_limit_prior_to_refinement() instead.

Definition at line 846 of file mesh_refinement.h.

References enforce_mismatch_limit_prior_to_refinement().

{
  libmesh_deprecated();
  return enforce_mismatch_limit_prior_to_refinement();
}
const MeshBase& libMesh::MeshRefinement::get_mesh ( ) const [inline]
Returns:
a constant reference to the MeshBase object associated with this object.

Definition at line 320 of file mesh_refinement.h.

References _mesh.

{ return _mesh; }
Returns:
a writeable reference to the MeshBase object associated with this object.

Definition at line 326 of file mesh_refinement.h.

References _mesh.

{ return _mesh; }
bool libMesh::MeshRefinement::has_topological_neighbor ( Elem elem,
const PointLocatorBase point_locator,
Elem neighbor 
) [private]

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

Definition at line 1811 of file mesh_refinement.C.

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

Referenced by make_coarsening_compatible(), and make_refinement_compatible().

{
#ifdef LIBMESH_ENABLE_PERIODIC
  if (_periodic_boundaries && !_periodic_boundaries->empty())
    {
      libmesh_assert(point_locator);
      return elem->has_topological_neighbor(neighbor, _mesh, *point_locator, _periodic_boundaries);
    }
#endif
  return elem->has_neighbor(neighbor);
}
bool libMesh::MeshRefinement::limit_level_mismatch_at_edge ( const unsigned int  max_mismatch) [private]

Definition at line 140 of file mesh_refinement_smoothing.C.

References _enforce_mismatch_limit_prior_to_refinement, _mesh, libMesh::MeshBase::active_elements_begin(), libMesh::MeshBase::active_elements_end(), libMesh::Elem::build_edge(), libMesh::ParallelObject::comm(), EDGE, enforce_mismatch_limit_prior_to_refinement(), libMesh::Elem::level(), std::max(), libMesh::Parallel::Communicator::max(), libMesh::Elem::n_edges(), libMesh::Elem::p_level(), libMesh::Elem::p_refinement_flag(), libMesh::Elem::parent(), libMesh::Elem::REFINE, libMesh::Elem::refinement_flag(), libMesh::Elem::set_p_refinement_flag(), libMesh::Elem::set_refinement_flag(), and libMesh::swap().

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

{
  // This function must be run on all processors at once
  parallel_object_only();

  bool flags_changed = false;


  // Maps holding the maximum element level that touches an edge
  std::map<std::pair<unsigned int, unsigned int>, unsigned char>
    max_level_at_edge;
  std::map<std::pair<unsigned int, unsigned int>, unsigned char>
    max_p_level_at_edge;

  // Loop over all the active elements & fill the maps
  {
    MeshBase::element_iterator       elem_it  = _mesh.active_elements_begin();
    const MeshBase::element_iterator elem_end = _mesh.active_elements_end();

    for (; elem_it != elem_end; ++elem_it)
      {
        const Elem* elem = *elem_it;
        const unsigned char elem_level =
          cast_int<unsigned char>(elem->level() +
                                  ((elem->refinement_flag() == Elem::REFINE) ? 1 : 0));
        const unsigned char elem_p_level =
          cast_int<unsigned char>(elem->p_level() +
                                  ((elem->p_refinement_flag() == Elem::REFINE) ? 1 : 0));

        // Set the max_level at each edge
        for (unsigned int n=0; n<elem->n_edges(); n++)
          {
            UniquePtr<Elem> edge = elem->build_edge(n);
            dof_id_type childnode0 = edge->node(0);
            dof_id_type childnode1 = edge->node(1);
            if (childnode1 < childnode0)
              std::swap(childnode0, childnode1);

            for (const Elem *p = elem; p != NULL; p = p->parent())
              {
                UniquePtr<Elem> pedge = p->build_edge(n);
                dof_id_type node0 = pedge->node(0);
                dof_id_type node1 = pedge->node(1);

                if (node1 < node0)
                  std::swap(node0, node1);

                // If elem does not share this edge with its ancestor
                // p, refinement levels of elements sharing p's edge
                // are not restricted by refinement levels of elem.
                // Furthermore, elem will not share this edge with any
                // of p's ancestors, so we can safely break out of the
                // for loop early.
                if (node0 != childnode0 && node1 != childnode1)
                  break;

                childnode0 = node0;
                childnode1 = node1;

                std::pair<unsigned int, unsigned int> edge_key =
                  std::make_pair(node0, node1);

                if (max_level_at_edge.find(edge_key) ==
                    max_level_at_edge.end())
                  {
                    max_level_at_edge[edge_key] = elem_level;
                    max_p_level_at_edge[edge_key] = elem_p_level;
                  }
                else
                  {
                    max_level_at_edge[edge_key] =
                      std::max (max_level_at_edge[edge_key], elem_level);
                    max_p_level_at_edge[edge_key] =
                      std::max (max_p_level_at_edge[edge_key], elem_p_level);
                  }
              }
          }
      }
  }


  // Now loop over the active elements and flag the elements
  // who violate the requested level mismatch
  {
    MeshBase::element_iterator       elem_it  = _mesh.active_elements_begin();
    const MeshBase::element_iterator elem_end = _mesh.active_elements_end();

    for (; elem_it != elem_end; ++elem_it)
      {
        Elem* elem = *elem_it;
        const unsigned int elem_level = elem->level();
        const unsigned int elem_p_level = elem->p_level();

        // Skip the element if it is already fully flagged
        if (elem->refinement_flag() == Elem::REFINE &&
            elem->p_refinement_flag() == Elem::REFINE
            && !_enforce_mismatch_limit_prior_to_refinement)
          continue;

        // Loop over the nodes, check for possible mismatch
        for (unsigned int n=0; n<elem->n_edges(); n++)
          {
            UniquePtr<Elem> edge = elem->build_edge(n);
            dof_id_type node0 = edge->node(0);
            dof_id_type node1 = edge->node(1);
            if (node1 < node0)
              std::swap(node0, node1);

            std::pair<dof_id_type, dof_id_type> edge_key =
              std::make_pair(node0, node1);

            // Flag the element for refinement if it violates
            // the requested level mismatch
            if ((elem_level + max_mismatch) < max_level_at_edge[edge_key]
                && elem->refinement_flag() != Elem::REFINE)
              {
                elem->set_refinement_flag (Elem::REFINE);
                flags_changed = true;
              }

            if ((elem_p_level + max_mismatch) < max_p_level_at_edge[edge_key]
                && elem->p_refinement_flag() != Elem::REFINE)
              {
                elem->set_p_refinement_flag (Elem::REFINE);
                flags_changed = true;
              }

            // Possibly enforce limit mismatch prior to refinement
            flags_changed |= this->enforce_mismatch_limit_prior_to_refinement(elem, EDGE, max_mismatch);
          } // loop over edges
      } // loop over active elements
  }

  // If flags changed on any processor then they changed globally
  this->comm().max(flags_changed);

  return flags_changed;
}
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::MeshBase::active_elements_begin(), libMesh::MeshBase::active_elements_end(), libMesh::ParallelObject::comm(), enforce_mismatch_limit_prior_to_refinement(), libMesh::Elem::level(), std::max(), libMesh::Parallel::Communicator::max(), libMesh::MeshBase::n_nodes(), libMesh::Elem::n_nodes(), libMesh::Elem::node(), libMesh::Elem::p_level(), libMesh::Elem::p_refinement_flag(), POINT, libMesh::Elem::REFINE, libMesh::Elem::refinement_flag(), libMesh::Elem::set_p_refinement_flag(), and libMesh::Elem::set_refinement_flag().

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

{
  // This function must be run on all processors at once
  parallel_object_only();

  bool flags_changed = false;


  // Vector holding the maximum element level that touches a node.
  std::vector<unsigned char> max_level_at_node (_mesh.n_nodes(), 0);
  std::vector<unsigned char> max_p_level_at_node (_mesh.n_nodes(), 0);

  // Loop over all the active elements & fill the vector
  {
    MeshBase::element_iterator       elem_it  = _mesh.active_elements_begin();
    const MeshBase::element_iterator elem_end = _mesh.active_elements_end();

    for (; elem_it != elem_end; ++elem_it)
      {
        const Elem* elem = *elem_it;
        const unsigned char elem_level =
          cast_int<unsigned char>(elem->level() +
                                  ((elem->refinement_flag() == Elem::REFINE) ? 1 : 0));
        const unsigned char elem_p_level =
          cast_int<unsigned char>(elem->p_level() +
                                  ((elem->p_refinement_flag() == Elem::REFINE) ? 1 : 0));

        // Set the max_level at each node
        for (unsigned int n=0; n<elem->n_nodes(); n++)
          {
            const dof_id_type node_number = elem->node(n);

            libmesh_assert_less (node_number, max_level_at_node.size());

            max_level_at_node[node_number] =
              std::max (max_level_at_node[node_number], elem_level);
            max_p_level_at_node[node_number] =
              std::max (max_p_level_at_node[node_number], elem_p_level);
          }
      }
  }


  // Now loop over the active elements and flag the elements
  // who violate the requested level mismatch. Alternatively, if
  // _enforce_mismatch_limit_prior_to_refinement is true, swap refinement flags
  // accordingly.
  {
    MeshBase::element_iterator       elem_it  = _mesh.active_elements_begin();
    const MeshBase::element_iterator elem_end = _mesh.active_elements_end();

    for (; elem_it != elem_end; ++elem_it)
      {
        Elem* elem = *elem_it;
        const unsigned int elem_level = elem->level();
        const unsigned int elem_p_level = elem->p_level();

        // Skip the element if it is already fully flagged
        // unless we are enforcing mismatch prior to refienemnt and may need to
        // remove the refinement flag(s)
        if (elem->refinement_flag() == Elem::REFINE &&
            elem->p_refinement_flag() == Elem::REFINE
            && !_enforce_mismatch_limit_prior_to_refinement)
          continue;

        // Loop over the nodes, check for possible mismatch
        for (unsigned int n=0; n<elem->n_nodes(); n++)
          {
            const dof_id_type node_number = elem->node(n);

            // Flag the element for refinement if it violates
            // the requested level mismatch
            if ((elem_level + max_mismatch) < max_level_at_node[node_number]
                && elem->refinement_flag() != Elem::REFINE)
              {
                elem->set_refinement_flag (Elem::REFINE);
                flags_changed = true;
              }
            if ((elem_p_level + max_mismatch) < max_p_level_at_node[node_number]
                && elem->p_refinement_flag() != Elem::REFINE)
              {
                elem->set_p_refinement_flag (Elem::REFINE);
                flags_changed = true;
              }

            // Possibly enforce limit mismatch prior to refinement
            flags_changed |= this->enforce_mismatch_limit_prior_to_refinement(elem, POINT, max_mismatch);
          }
      }
  }

  // If flags changed on any processor then they changed globally
  this->comm().max(flags_changed);

  return flags_changed;
}
bool libMesh::MeshRefinement::make_coarsening_compatible ( const bool  maintain_level_one) [private]

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

Definition at line 957 of file mesh_refinement.C.

References _face_level_mismatch_limit, _mesh, _periodic_boundaries, libMesh::Elem::active(), libMesh::MeshBase::active_elements_begin(), libMesh::MeshBase::active_elements_end(), libMesh::Elem::ancestor(), libMesh::Elem::child(), libMesh::Elem::COARSEN, libMesh::Elem::COARSEN_INACTIVE, libMesh::ParallelObject::comm(), libMesh::Elem::DO_NOTHING, libMesh::MeshBase::elements_begin(), libMesh::MeshBase::elements_end(), libMesh::Elem::has_children(), has_topological_neighbor(), libMesh::Elem::INACTIVE, libMesh::MeshBase::is_serial(), libMesh::Elem::level(), libMesh::MeshBase::level_elements_begin(), libMesh::MeshBase::level_elements_end(), libMesh::libmesh_assert(), std::max(), libMesh::MeshTools::max_level(), libMesh::Parallel::Communicator::min(), libMesh::Elem::n_children(), libMesh::Elem::n_neighbors(), libMesh::Elem::p_level(), libMesh::Elem::p_refinement_flag(), libMesh::ParallelObject::processor_id(), libMesh::DofObject::processor_id(), libMesh::Elem::REFINE, libMesh::Elem::refinement_flag(), libMesh::remote_elem, libMesh::Elem::set_p_refinement_flag(), libMesh::Elem::set_refinement_flag(), libMesh::START_LOG(), libMesh::MeshBase::sub_point_locator(), topological_neighbor(), and libMesh::Parallel::verify().

Referenced by coarsen_elements(), and refine_and_coarsen_elements().

{
  // This function must be run on all processors at once
  parallel_object_only();

  // We may need a PointLocator for topological_neighbor() tests
  // later, which we need to make sure gets constructed on all
  // processors at once.
  UniquePtr<PointLocatorBase> point_locator;

#ifdef LIBMESH_ENABLE_PERIODIC
  bool has_periodic_boundaries =
    _periodic_boundaries && !_periodic_boundaries->empty();
  libmesh_assert(this->comm().verify(has_periodic_boundaries));

  if (has_periodic_boundaries)
    point_locator = _mesh.sub_point_locator();
#endif

  START_LOG ("make_coarsening_compatible()", "MeshRefinement");

  bool _maintain_level_one = maintain_level_one;

  // If the user used non-default parameters, let's warn that they're
  // deprecated
  if (!maintain_level_one)
    {
      libmesh_deprecated();
    }
  else
    _maintain_level_one = _face_level_mismatch_limit;


  // Unless we encounter a specific situation level-one
  // will be satisfied after executing this loop just once
  bool level_one_satisfied = true;


  // Unless we encounter a specific situation we will be compatible
  // with any selected refinement flags
  bool compatible_with_refinement = true;


  // find the maximum h and p levels in the mesh
  unsigned int max_level = 0;
  unsigned int max_p_level = 0;

  {
    // First we look at all the active level-0 elements.  Since it doesn't make
    // sense to coarsen them we must un-set their coarsen flags if
    // they are set.
    MeshBase::element_iterator       el     = _mesh.active_elements_begin();
    const MeshBase::element_iterator end_el = _mesh.active_elements_end();

    for (; el != end_el; ++el)
      {
        Elem *elem = *el;
        max_level = std::max(max_level, elem->level());
        max_p_level =
          std::max(max_p_level,
                   static_cast<unsigned int>(elem->p_level()));

        if ((elem->level() == 0) &&
            (elem->refinement_flag() == Elem::COARSEN))
          elem->set_refinement_flag(Elem::DO_NOTHING);

        if ((elem->p_level() == 0) &&
            (elem->p_refinement_flag() == Elem::COARSEN))
          elem->set_p_refinement_flag(Elem::DO_NOTHING);
      }
  }

  // if there are no refined elements on this processor then
  // there is no work for us to do
  if (max_level == 0 && max_p_level == 0)
    {
      STOP_LOG ("make_coarsening_compatible()", "MeshRefinement");

      // But we still have to check with other processors
      this->comm().min(compatible_with_refinement);

      return compatible_with_refinement;
    }



  // Loop over all the active elements.  If an element is marked
  // for coarsening we better check its neighbors.  If ANY of these neighbors
  // are marked for refinement AND are at the same level then there is a
  // conflict.  By convention refinement wins, so we un-mark the element for
  // coarsening.  Level-one would be violated in this case so we need to re-run
  // the loop.
  if (_maintain_level_one)
    {

    repeat:
      level_one_satisfied = true;

      do
        {
          level_one_satisfied = true;

          MeshBase::element_iterator       el     = _mesh.active_elements_begin();
          const MeshBase::element_iterator end_el = _mesh.active_elements_end();

          for (; el != end_el; ++el)
            {
              Elem* elem = *el;
              bool my_flag_changed = false;

              if (elem->refinement_flag() == Elem::COARSEN) // If the element is active and
                // the coarsen flag is set
                {
                  const unsigned int my_level = elem->level();

                  for (unsigned int n=0; n<elem->n_neighbors(); n++)
                    {
                      const Elem* neighbor =
                        topological_neighbor(elem, point_locator.get(), n);

                      if (neighbor != NULL &&      // I have a
                          neighbor != remote_elem) // neighbor here
                        {
                          if (neighbor->active()) // and it is active
                            {
                              if ((neighbor->level() == my_level) &&
                                  (neighbor->refinement_flag() == Elem::REFINE)) // the neighbor is at my level
                                // and wants to be refined
                                {
                                  elem->set_refinement_flag(Elem::DO_NOTHING);
                                  my_flag_changed = true;
                                  break;
                                }
                            }
                          else // I have a neighbor and it is not active. That means it has children.
                            {  // While it _may_ be possible to coarsen us if all the children of
                              // that element want to be coarsened, it is impossible to know at this
                              // stage.  Forget about it for the moment...  This can be handled in
                              // two steps.
                              elem->set_refinement_flag(Elem::DO_NOTHING);
                              my_flag_changed = true;
                              break;
                            }
                        }
                    }
                }
              if (elem->p_refinement_flag() == Elem::COARSEN) // If
                // the element is active and the order reduction flag is set
                {
                  const unsigned int my_p_level = elem->p_level();

                  for (unsigned int n=0; n<elem->n_neighbors(); n++)
                    {
                      const Elem* neighbor =
                        topological_neighbor(elem, point_locator.get(), n);

                      if (neighbor != NULL &&      // I have a
                          neighbor != remote_elem) // neighbor here
                        {
                          if (neighbor->active()) // and it is active
                            {
                              if ((neighbor->p_level() > my_p_level &&
                                   neighbor->p_refinement_flag() != Elem::COARSEN)
                                  || (neighbor->p_level() == my_p_level &&
                                      neighbor->p_refinement_flag() == Elem::REFINE))
                                {
                                  elem->set_p_refinement_flag(Elem::DO_NOTHING);
                                  my_flag_changed = true;
                                  break;
                                }
                            }
                          else // I have a neighbor and it is not active.
                            {  // We need to find which of its children
                              // have me as a neighbor, and maintain
                              // level one p compatibility with them.
                              // Because we currently have level one h
                              // compatibility, we don't need to check
                              // grandchildren

                              libmesh_assert(neighbor->has_children());
                              for (unsigned int c=0; c!=neighbor->n_children(); c++)
                                {
                                  Elem *subneighbor = neighbor->child(c);
                                  if (subneighbor != remote_elem &&
                                      subneighbor->active() &&
                                      has_topological_neighbor(subneighbor, point_locator.get(), elem))
                                    if ((subneighbor->p_level() > my_p_level &&
                                         subneighbor->p_refinement_flag() != Elem::COARSEN)
                                        || (subneighbor->p_level() == my_p_level &&
                                            subneighbor->p_refinement_flag() == Elem::REFINE))
                                      {
                                        elem->set_p_refinement_flag(Elem::DO_NOTHING);
                                        my_flag_changed = true;
                                        break;
                                      }
                                }
                              if (my_flag_changed)
                                break;
                            }
                        }
                    }
                }

              // If the current element's flag changed, we hadn't
              // satisfied the level one rule.
              if (my_flag_changed)
                level_one_satisfied = false;

              // Additionally, if it has non-local neighbors, and
              // we're not in serial, then we'll eventually have to
              // return compatible_with_refinement = false, because
              // our change has to propagate to neighboring
              // processors.
              if (my_flag_changed && !_mesh.is_serial())
                for (unsigned int n=0; n != elem->n_neighbors(); ++n)
                  {
                    Elem* neigh =
                      topological_neighbor(elem, point_locator.get(), n);

                    if (!neigh)
                      continue;
                    if (neigh == remote_elem ||
                        neigh->processor_id() !=
                        this->processor_id())
                      {
                        compatible_with_refinement = false;
                        break;
                      }
                    // FIXME - for non-level one meshes we should
                    // test all descendants
                    if (neigh->has_children())
                      for (unsigned int c=0; c != neigh->n_children(); ++c)
                        if (neigh->child(c) == remote_elem ||
                            neigh->child(c)->processor_id() !=
                            this->processor_id())
                          {
                            compatible_with_refinement = false;
                            break;
                          }
                  }
            }
        }
      while (!level_one_satisfied);

    } // end if (_maintain_level_one)


  // Next we look at all of the ancestor cells.
  // If there is a parent cell with all of its children
  // wanting to be unrefined then the element is a candidate
  // for unrefinement.  If all the children don't
  // all want to be unrefined then ALL of them need to have their
  // unrefinement flags cleared.
  for (int level=(max_level); level >= 0; level--)
    {
      MeshBase::element_iterator       el     = _mesh.level_elements_begin(level);
      const MeshBase::element_iterator end_el = _mesh.level_elements_end(level);
      for (; el != end_el; ++el)
        {
          Elem *elem = *el;
          if (elem->ancestor())
            {

              // right now the element hasn't been disqualified
              // as a candidate for unrefinement
              bool is_a_candidate = true;
              bool found_remote_child = false;

              for (unsigned int c=0; c<elem->n_children(); c++)
                {
                  Elem *child = elem->child(c);
                  if (child == remote_elem)
                    found_remote_child = true;
                  else if ((child->refinement_flag() != Elem::COARSEN) ||
                           !child->active() )
                    is_a_candidate = false;
                }

              if (!is_a_candidate && !found_remote_child)
                {
                  elem->set_refinement_flag(Elem::INACTIVE);

                  for (unsigned int c=0; c<elem->n_children(); c++)
                    {
                      Elem *child = elem->child(c);
                      if (child == remote_elem)
                        continue;
                      if (child->refinement_flag() == Elem::COARSEN)
                        {
                          level_one_satisfied = false;
                          child->set_refinement_flag(Elem::DO_NOTHING);
                        }
                    }
                }
            }
        }
    }

  if (!level_one_satisfied && _maintain_level_one) goto repeat;


  // If all the children of a parent are set to be coarsened
  // then flag the parent so that they can kill thier kids...
  MeshBase::element_iterator       all_el     = _mesh.elements_begin();
  const MeshBase::element_iterator all_el_end = _mesh.elements_end();
  for (; all_el != all_el_end; ++all_el)
    {
      Elem *elem = *all_el;
      if (elem->ancestor())
        {

          // Presume all the children are local and flagged for
          // coarsening and then look for a contradiction
          bool all_children_flagged_for_coarsening = true;
          bool found_remote_child = false;

          for (unsigned int c=0; c<elem->n_children(); c++)
            {
              Elem *child = elem->child(c);
              if (child == remote_elem)
                found_remote_child = true;
              else if (child->refinement_flag() != Elem::COARSEN)
                all_children_flagged_for_coarsening = false;
            }

          if (!found_remote_child &&
              all_children_flagged_for_coarsening)
            elem->set_refinement_flag(Elem::COARSEN_INACTIVE);
          else if (!found_remote_child)
            elem->set_refinement_flag(Elem::INACTIVE);
        }
    }

  STOP_LOG ("make_coarsening_compatible()", "MeshRefinement");

  // If one processor finds an incompatibility, we're globally
  // incompatible
  this->comm().min(compatible_with_refinement);

  return compatible_with_refinement;
}

Copy refinement flags on ghost elements from their local processors. Return true if any flags changed.

Definition at line 927 of file mesh_refinement.C.

References _mesh, libMesh::ParallelObject::comm(), libMesh::MeshBase::elements_begin(), libMesh::MeshBase::elements_end(), libMesh::Parallel::Communicator::min(), libMesh::Elem::p_refinement_flag(), parallel_consistent, libMesh::Elem::refinement_flag(), libMesh::Elem::set_p_refinement_flag(), libMesh::Elem::set_refinement_flag(), libMesh::START_LOG(), and libMesh::Parallel::sync_dofobject_data_by_id().

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

{
  // This function must be run on all processors at once
  parallel_object_only();

  START_LOG ("make_flags_parallel_consistent()", "MeshRefinement");

  SyncRefinementFlags hsync(_mesh, &Elem::refinement_flag,
                            &Elem::set_refinement_flag);
  Parallel::sync_dofobject_data_by_id
    (this->comm(), _mesh.elements_begin(), _mesh.elements_end(), hsync);

  SyncRefinementFlags psync(_mesh, &Elem::p_refinement_flag,
                            &Elem::set_p_refinement_flag);
  Parallel::sync_dofobject_data_by_id
    (this->comm(), _mesh.elements_begin(), _mesh.elements_end(), psync);

  // If we weren't consistent in both h and p on every processor then
  // we weren't globally consistent
  bool parallel_consistent = hsync.parallel_consistent &&
    psync.parallel_consistent;
  this->comm().min(parallel_consistent);

  STOP_LOG ("make_flags_parallel_consistent()", "MeshRefinement");

  return parallel_consistent;
}
bool libMesh::MeshRefinement::make_refinement_compatible ( const bool  maintain_level_one) [private]

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

Definition at line 1306 of file mesh_refinement.C.

References _face_level_mismatch_limit, _mesh, _periodic_boundaries, libMesh::Elem::active(), libMesh::MeshBase::active_elements_begin(), libMesh::MeshBase::active_elements_end(), libMesh::Elem::child(), libMesh::Elem::COARSEN, libMesh::ParallelObject::comm(), libMesh::Elem::DO_NOTHING, libMesh::Elem::has_children(), has_topological_neighbor(), libMesh::Elem::INACTIVE, libMesh::Elem::level(), libMesh::libmesh_assert(), libMesh::Parallel::Communicator::min(), libMesh::Elem::n_children(), libMesh::Elem::n_sides(), 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(), side, libMesh::START_LOG(), libMesh::MeshBase::sub_point_locator(), topological_neighbor(), and libMesh::Parallel::verify().

Referenced by refine_and_coarsen_elements(), and refine_elements().

{
  // This function must be run on all processors at once
  parallel_object_only();

  // We may need a PointLocator for topological_neighbor() tests
  // later, which we need to make sure gets constructed on all
  // processors at once.
  UniquePtr<PointLocatorBase> point_locator;

#ifdef LIBMESH_ENABLE_PERIODIC
  bool has_periodic_boundaries =
    _periodic_boundaries && !_periodic_boundaries->empty();
  libmesh_assert(this->comm().verify(has_periodic_boundaries));

  if (has_periodic_boundaries)
    point_locator = _mesh.sub_point_locator();
#endif

  START_LOG ("make_refinement_compatible()", "MeshRefinement");

  bool _maintain_level_one = maintain_level_one;

  // If the user used non-default parameters, let's warn that they're
  // deprecated
  if (!maintain_level_one)
    {
      libmesh_deprecated();
    }
  else
    _maintain_level_one = _face_level_mismatch_limit;

  // Unless we encounter a specific situation we will be compatible
  // with any selected coarsening flags
  bool compatible_with_coarsening = true;

  // This loop enforces the level-1 rule.  We should only
  // execute it if the user indeed wants level-1 satisfied!
  if (_maintain_level_one)
    {
      // Unless we encounter a specific situation level-one
      // will be satisfied after executing this loop just once
      bool level_one_satisfied = true;

      do
        {
          level_one_satisfied = true;

          MeshBase::element_iterator       el     = _mesh.active_elements_begin();
          const MeshBase::element_iterator end_el = _mesh.active_elements_end();

          for (; el != end_el; ++el)
            {
              Elem *elem = *el;
              if (elem->refinement_flag() == Elem::REFINE)  // If the element is active and the
                // h refinement flag is set
                {
                  const unsigned int my_level = elem->level();

                  for (unsigned int side=0; side != elem->n_sides(); side++)
                    {
                      Elem* neighbor =
                        topological_neighbor(elem, point_locator.get(), side);

                      if (neighbor != NULL        && // I have a
                          neighbor != remote_elem && // neighbor here
                          neighbor->active()) // and it is active
                        {
                          // Case 1:  The neighbor is at the same level I am.
                          //        1a: The neighbor will be refined       -> NO PROBLEM
                          //        1b: The neighbor won't be refined      -> NO PROBLEM
                          //        1c: The neighbor wants to be coarsened -> PROBLEM
                          if (neighbor->level() == my_level)
                            {
                              if (neighbor->refinement_flag() == Elem::COARSEN)
                                {
                                  neighbor->set_refinement_flag(Elem::DO_NOTHING);
                                  if (neighbor->parent())
                                    neighbor->parent()->set_refinement_flag(Elem::INACTIVE);
                                  compatible_with_coarsening = false;
                                  level_one_satisfied = false;
                                }
                            }


                          // Case 2: The neighbor is one level lower than I am.
                          //         The neighbor thus MUST be refined to satisfy
                          //         the level-one rule, regardless of whether it
                          //         was originally flagged for refinement. If it
                          //         wasn't flagged already we need to repeat
                          //         this process.
                          else if ((neighbor->level()+1) == my_level)
                            {
                              if (neighbor->refinement_flag() != Elem::REFINE)
                                {
                                  neighbor->set_refinement_flag(Elem::REFINE);
                                  if (neighbor->parent())
                                    neighbor->parent()->set_refinement_flag(Elem::INACTIVE);
                                  compatible_with_coarsening = false;
                                  level_one_satisfied = false;
                                }
                            }
#ifdef DEBUG
                          // Note that the only other possibility is that the
                          // neighbor is already refined, in which case it isn't
                          // active and we should never get here.
                          else
                            libmesh_error_msg("ERROR: Neighbor level must be equal or 1 higher than mine.");
#endif
                        }
                    }
                }
              if (elem->p_refinement_flag() == Elem::REFINE)  // If the element is active and the
                // p refinement flag is set
                {
                  const unsigned int my_p_level = elem->p_level();

                  for (unsigned int side=0; side != elem->n_sides(); side++)
                    {
                      Elem* neighbor =
                        topological_neighbor(elem, point_locator.get(), side);

                      if (neighbor != NULL &&      // I have a
                          neighbor != remote_elem) // neighbor here
                        {
                          if (neighbor->active()) // and it is active
                            {
                              if (neighbor->p_level() < my_p_level &&
                                  neighbor->p_refinement_flag() != Elem::REFINE)
                                {
                                  neighbor->set_p_refinement_flag(Elem::REFINE);
                                  level_one_satisfied = false;
                                  compatible_with_coarsening = false;
                                }
                              if (neighbor->p_level() == my_p_level &&
                                  neighbor->p_refinement_flag() == Elem::COARSEN)
                                {
                                  neighbor->set_p_refinement_flag(Elem::DO_NOTHING);
                                  level_one_satisfied = false;
                                  compatible_with_coarsening = false;
                                }
                            }
                          else // I have an inactive neighbor
                            {
                              libmesh_assert(neighbor->has_children());
                              for (unsigned int c=0; c!=neighbor->n_children(); c++)
                                {
                                  Elem *subneighbor = neighbor->child(c);
                                  if (subneighbor == remote_elem)
                                    continue;
                                  if (subneighbor->active() &&
                                      has_topological_neighbor(subneighbor, point_locator.get(), elem))
                                    {
                                      if (subneighbor->p_level() < my_p_level &&
                                          subneighbor->p_refinement_flag() != Elem::REFINE)
                                        {
                                          // We should already be level one
                                          // compatible
                                          libmesh_assert_greater (subneighbor->p_level() + 2u,
                                                                  my_p_level);
                                          subneighbor->set_p_refinement_flag(Elem::REFINE);
                                          level_one_satisfied = false;
                                          compatible_with_coarsening = false;
                                        }
                                      if (subneighbor->p_level() == my_p_level &&
                                          subneighbor->p_refinement_flag() == Elem::COARSEN)
                                        {
                                          subneighbor->set_p_refinement_flag(Elem::DO_NOTHING);
                                          level_one_satisfied = false;
                                          compatible_with_coarsening = false;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }

      while (!level_one_satisfied);
    } // end if (_maintain_level_one)

  // If we're not compatible on one processor, we're globally not
  // compatible
  this->comm().min(compatible_with_coarsening);

  STOP_LOG ("make_refinement_compatible()", "MeshRefinement");

  return compatible_with_coarsening;
}
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 807 of file mesh_refinement.h.

References _max_h_level, and _use_member_parameters.

Returns:
the number of processors in the group.

Definition at line 92 of file parallel_object.h.

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

Referenced by libMesh::ParmetisPartitioner::_do_repartition(), libMesh::ParallelMesh::add_elem(), libMesh::ParallelMesh::add_node(), libMesh::LaplaceMeshSmoother::allgather_graph(), libMesh::FEMSystem::assembly(), libMesh::ParmetisPartitioner::assign_partitioning(), libMesh::ParallelMesh::assign_unique_ids(), libMesh::AztecLinearSolver< T >::AztecLinearSolver(), libMesh::ParallelMesh::clear(), libMesh::Nemesis_IO_Helper::compute_border_node_ids(), libMesh::Nemesis_IO_Helper::construct_nemesis_filename(), libMesh::UnstructuredMesh::create_pid_mesh(), libMesh::DofMap::distribute_dofs(), libMesh::DofMap::distribute_local_dofs_node_major(), libMesh::DofMap::distribute_local_dofs_var_major(), libMesh::EnsightIO::EnsightIO(), libMesh::MeshBase::get_info(), libMesh::EquationSystems::init(), libMesh::SystemSubsetBySubdomain::init(), libMesh::ParmetisPartitioner::initialize(), libMesh::Nemesis_IO_Helper::initialize(), libMesh::MeshTools::libmesh_assert_valid_dof_ids(), libMesh::MeshTools::libmesh_assert_valid_procids< Elem >(), libMesh::MeshTools::libmesh_assert_valid_procids< Node >(), libMesh::MeshTools::libmesh_assert_valid_refinement_flags(), libMesh::DofMap::local_variable_indices(), libMesh::MeshBase::n_active_elem_on_proc(), libMesh::MeshBase::n_elem_on_proc(), libMesh::MeshBase::n_nodes_on_proc(), libMesh::Partitioner::partition(), libMesh::MeshBase::partition(), libMesh::Partitioner::partition_unpartitioned_elements(), libMesh::PetscLinearSolver< T >::PetscLinearSolver(), libMesh::System::point_gradient(), libMesh::System::point_hessian(), libMesh::System::point_value(), libMesh::MeshTools::processor_bounding_box(), libMesh::System::project_vector(), libMesh::NameBasedIO::read(), libMesh::Nemesis_IO::read(), libMesh::CheckpointIO::read(), libMesh::XdrIO::read(), libMesh::System::read_parallel_data(), libMesh::System::read_SCALAR_dofs(), libMesh::System::read_serialized_blocked_dof_objects(), libMesh::System::read_serialized_vector(), libMesh::Partitioner::repartition(), libMesh::Partitioner::set_node_processor_ids(), libMesh::DofMap::set_nonlocal_dof_objects(), libMesh::BoundaryInfo::sync(), libMesh::ParallelMesh::update_parallel_id_counts(), libMesh::CheckpointIO::write(), libMesh::GMVIO::write_binary(), libMesh::GMVIO::write_discontinuous_gmv(), libMesh::System::write_parallel_data(), libMesh::System::write_SCALAR_dofs(), libMesh::XdrIO::write_serialized_bcs(), libMesh::System::write_serialized_blocked_dof_objects(), libMesh::XdrIO::write_serialized_connectivity(), libMesh::XdrIO::write_serialized_nodes(), and libMesh::XdrIO::write_serialized_nodesets().

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

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

References _nelem_target, and _use_member_parameters.

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

References _node_level_mismatch_limit.

MeshRefinement& libMesh::MeshRefinement::operator= ( const MeshRefinement ) [private]
Returns:
the rank of this processor in the group.

Definition at line 98 of file parallel_object.h.

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

Referenced by libMesh::MetisPartitioner::_do_partition(), libMesh::EquationSystems::_read_impl(), libMesh::SerialMesh::active_local_elements_begin(), libMesh::ParallelMesh::active_local_elements_begin(), libMesh::SerialMesh::active_local_elements_end(), libMesh::ParallelMesh::active_local_elements_end(), libMesh::SerialMesh::active_local_subdomain_elements_begin(), libMesh::ParallelMesh::active_local_subdomain_elements_begin(), libMesh::SerialMesh::active_local_subdomain_elements_end(), libMesh::ParallelMesh::active_local_subdomain_elements_end(), libMesh::SerialMesh::active_not_local_elements_begin(), libMesh::ParallelMesh::active_not_local_elements_begin(), libMesh::SerialMesh::active_not_local_elements_end(), libMesh::ParallelMesh::active_not_local_elements_end(), libMesh::ParallelMesh::add_elem(), libMesh::DofMap::add_neighbors_to_send_list(), libMesh::ParallelMesh::add_node(), libMesh::UnstructuredMesh::all_second_order(), libMesh::FEMSystem::assembly(), libMesh::ParmetisPartitioner::assign_partitioning(), libMesh::ParallelMesh::assign_unique_ids(), libMesh::EquationSystems::build_discontinuous_solution_vector(), libMesh::Nemesis_IO_Helper::build_element_and_node_maps(), libMesh::ParmetisPartitioner::build_graph(), libMesh::InfElemBuilder::build_inf_elem(), libMesh::DofMap::build_sparsity(), libMesh::ParallelMesh::clear(), libMesh::ExodusII_IO_Helper::close(), libMesh::Nemesis_IO_Helper::compute_border_node_ids(), libMesh::Nemesis_IO_Helper::compute_communication_map_parameters(), libMesh::Nemesis_IO_Helper::compute_internal_and_border_elems_and_internal_nodes(), libMesh::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_Helper::create(), libMesh::ParallelMesh::delete_elem(), libMesh::ParallelMesh::delete_node(), libMesh::DofMap::distribute_dofs(), libMesh::DofMap::distribute_local_dofs_node_major(), libMesh::DofMap::distribute_local_dofs_var_major(), libMesh::DofMap::end_dof(), libMesh::DofMap::end_old_dof(), libMesh::EnsightIO::EnsightIO(), libMesh::SerialMesh::facelocal_elements_begin(), libMesh::ParallelMesh::facelocal_elements_begin(), libMesh::SerialMesh::facelocal_elements_end(), libMesh::ParallelMesh::facelocal_elements_end(), libMesh::MeshFunction::find_element(), libMesh::UnstructuredMesh::find_neighbors(), libMesh::DofMap::first_dof(), libMesh::DofMap::first_old_dof(), libMesh::Nemesis_IO_Helper::get_cmap_params(), libMesh::Nemesis_IO_Helper::get_eb_info_global(), libMesh::Nemesis_IO_Helper::get_elem_cmap(), libMesh::Nemesis_IO_Helper::get_elem_map(), libMesh::MeshBase::get_info(), libMesh::Nemesis_IO_Helper::get_init_global(), libMesh::Nemesis_IO_Helper::get_init_info(), libMesh::Nemesis_IO_Helper::get_loadbal_param(), 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::SystemSubsetBySubdomain::init(), libMesh::ParmetisPartitioner::initialize(), 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::ParallelMesh::insert_elem(), libMesh::SparsityPattern::Build::join(), libMesh::DofMap::last_dof(), libMesh::MeshTools::libmesh_assert_valid_procids< Elem >(), libMesh::MeshTools::libmesh_assert_valid_procids< Node >(), libMesh::SerialMesh::local_elements_begin(), libMesh::ParallelMesh::local_elements_begin(), libMesh::SerialMesh::local_elements_end(), libMesh::ParallelMesh::local_elements_end(), libMesh::SerialMesh::local_level_elements_begin(), libMesh::ParallelMesh::local_level_elements_begin(), libMesh::SerialMesh::local_level_elements_end(), libMesh::ParallelMesh::local_level_elements_end(), libMesh::SerialMesh::local_nodes_begin(), libMesh::ParallelMesh::local_nodes_begin(), libMesh::SerialMesh::local_nodes_end(), libMesh::ParallelMesh::local_nodes_end(), libMesh::SerialMesh::local_not_level_elements_begin(), libMesh::ParallelMesh::local_not_level_elements_begin(), libMesh::SerialMesh::local_not_level_elements_end(), libMesh::ParallelMesh::local_not_level_elements_end(), libMesh::DofMap::local_variable_indices(), make_coarsening_compatible(), 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::SerialMesh::not_local_elements_begin(), libMesh::ParallelMesh::not_local_elements_begin(), libMesh::SerialMesh::not_local_elements_end(), libMesh::ParallelMesh::not_local_elements_end(), libMesh::WeightedPatchRecoveryErrorEstimator::EstimateError::operator()(), libMesh::SparsityPattern::Build::operator()(), libMesh::PatchRecoveryErrorEstimator::EstimateError::operator()(), libMesh::ParallelMesh::ParallelMesh(), libMesh::System::point_gradient(), libMesh::System::point_hessian(), libMesh::System::point_value(), libMesh::System::project_vector(), 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::CheckpointIO::read(), libMesh::XdrIO::read(), libMesh::ExodusII_IO_Helper::read_elem_num_map(), libMesh::System::read_header(), libMesh::System::read_legacy_data(), libMesh::ExodusII_IO_Helper::read_node_num_map(), libMesh::System::read_parallel_data(), libMesh::System::read_SCALAR_dofs(), libMesh::XdrIO::read_serialized_bc_names(), libMesh::XdrIO::read_serialized_bcs(), 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::MeshData::read_xdr(), libMesh::SerialMesh::semilocal_elements_begin(), libMesh::ParallelMesh::semilocal_elements_begin(), libMesh::SerialMesh::semilocal_elements_end(), libMesh::ParallelMesh::semilocal_elements_end(), libMesh::Partitioner::set_node_processor_ids(), libMesh::DofMap::set_nonlocal_dof_objects(), libMesh::LaplaceMeshSmoother::smooth(), libMesh::BoundaryInfo::sync(), libMesh::MeshTools::total_weight(), libMesh::ParallelMesh::update_parallel_id_counts(), libMesh::MeshTools::weight(), libMesh::NameBasedIO::write(), libMesh::ExodusII_IO::write(), libMesh::CheckpointIO::write(), libMesh::XdrIO::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_elements(), libMesh::ExodusII_IO::write_global_data(), libMesh::ExodusII_IO_Helper::write_global_values(), libMesh::System::write_header(), libMesh::ExodusII_IO::write_information_records(), libMesh::ExodusII_IO_Helper::write_information_records(), libMesh::ExodusII_IO_Helper::write_nodal_coordinates(), libMesh::UCDIO::write_nodal_data(), libMesh::ExodusII_IO::write_nodal_data(), libMesh::ExodusII_IO::write_nodal_data_discontinuous(), libMesh::ExodusII_IO_Helper::write_nodal_values(), libMesh::ExodusII_IO_Helper::write_nodesets(), libMesh::Nemesis_IO_Helper::write_nodesets(), libMesh::System::write_parallel_data(), libMesh::System::write_SCALAR_dofs(), libMesh::XdrIO::write_serialized_bc_names(), libMesh::XdrIO::write_serialized_bcs(), 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_sidesets(), libMesh::Nemesis_IO_Helper::write_sidesets(), libMesh::ExodusII_IO::write_timestep(), and libMesh::ExodusII_IO_Helper::write_timestep().

  { return cast_int<processor_id_type>(_communicator.rank()); }
bool libMesh::MeshRefinement::refine_and_coarsen_elements ( const bool  maintain_level_one = true)

Refines and coarsens user-requested elements. Will also refine/coarsen additional elements to satisy level-one rule. It is possible that for a given set of refinement flags there is actually no change upon calling this member function. Consequently, this function returns true if the mesh actually changed (hence data needs to be projected) and false otherwise.

The argument maintain_level_one is now deprecated; use the option face_level_mismatch_limit() instead.

Definition at line 443 of file mesh_refinement.C.

References _coarsen_elements(), _edge_level_mismatch_limit, _face_level_mismatch_limit, _mesh, _node_level_mismatch_limit, _refine_elements(), libMesh::Elem::active(), libMesh::ParallelObject::comm(), libMesh::Elem::DO_NOTHING, libMesh::MeshBase::elements_begin(), libMesh::MeshBase::elements_end(), eliminate_unrefined_patches(), libMesh::Elem::INACTIVE, libMesh::MeshBase::is_serial(), libMesh::Elem::JUST_REFINED, libMesh::libmesh_assert(), libMesh::MeshBase::libmesh_assert_valid_parallel_ids(), limit_level_mismatch_at_edge(), limit_level_mismatch_at_node(), make_coarsening_compatible(), make_flags_parallel_consistent(), make_refinement_compatible(), libMesh::Parallel::Communicator::max(), libMesh::Parallel::Communicator::min(), libMesh::out, libMesh::MeshBase::prepare_for_use(), libMesh::Elem::refinement_flag(), libMesh::Elem::set_p_refinement_flag(), libMesh::Elem::set_refinement_flag(), test_level_one(), and test_unflagged().

{
  // This function must be run on all processors at once
  parallel_object_only();

  bool _maintain_level_one = maintain_level_one;

  // If the user used non-default parameters, let's warn that they're
  // deprecated
  if (!maintain_level_one)
    {
      libmesh_deprecated();
    }
  else
    _maintain_level_one = _face_level_mismatch_limit;

  // We can't yet turn a non-level-one mesh into a level-one mesh
  if (_maintain_level_one)
    libmesh_assert(test_level_one(true));

  // Possibly clean up the refinement flags from
  // a previous step
  MeshBase::element_iterator       elem_it  = _mesh.elements_begin();
  const MeshBase::element_iterator elem_end = _mesh.elements_end();

  for ( ; elem_it != elem_end; ++elem_it)
    {
      // Pointer to the element
      Elem *elem = *elem_it;

      // Set refinement flag to INACTIVE if the
      // element isn't active
      if ( !elem->active())
        {
          elem->set_refinement_flag(Elem::INACTIVE);
          elem->set_p_refinement_flag(Elem::INACTIVE);
        }

      // This might be left over from the last step
      if (elem->refinement_flag() == Elem::JUST_REFINED)
        elem->set_refinement_flag(Elem::DO_NOTHING);
    }

  // Parallel consistency has to come first, or coarsening
  // along processor boundaries might occasionally be falsely
  // prevented
  bool flags_were_consistent = this->make_flags_parallel_consistent();

  // In theory, we should be able to remove the above call, which can
  // be expensive and should be unnecessary.  In practice, doing
  // consistent flagging in parallel is hard, it's impossible to
  // verify at the library level if it's being done by user code, and
  // we don't want to abort large parallel runs in opt mode... but we
  // do want to warn that they should be fixed.
  if (!flags_were_consistent)
    {
      libMesh::out << "Refinement flags were not consistent between processors!\n"
                   << "Correcting and continuing.";
    }

  // Repeat until flag changes match on every processor
  do
    {
      // Repeat until coarsening & refinement flags jive
      bool satisfied = false;
      do
        {
          const bool coarsening_satisfied =
            this->make_coarsening_compatible(maintain_level_one);

          const bool refinement_satisfied =
            this->make_refinement_compatible(maintain_level_one);

          bool smoothing_satisfied =
            !this->eliminate_unrefined_patches();

          if (_edge_level_mismatch_limit)
            smoothing_satisfied = smoothing_satisfied &&
              !this->limit_level_mismatch_at_edge (_edge_level_mismatch_limit);

          if (_node_level_mismatch_limit)
            smoothing_satisfied = smoothing_satisfied &&
              !this->limit_level_mismatch_at_node (_node_level_mismatch_limit);

          satisfied = (coarsening_satisfied &&
                       refinement_satisfied &&
                       smoothing_satisfied);
#ifdef DEBUG
          bool max_satisfied = satisfied,
            min_satisfied = satisfied;
          this->comm().max(max_satisfied);
          this->comm().min(min_satisfied);
          libmesh_assert_equal_to (satisfied, max_satisfied);
          libmesh_assert_equal_to (satisfied, min_satisfied);
#endif
        }
      while (!satisfied);
    }
  while (!_mesh.is_serial() && !this->make_flags_parallel_consistent());

  // First coarsen the flagged elements.
  const bool coarsening_changed_mesh =
    this->_coarsen_elements ();

  // FIXME: test_level_one now tests consistency across periodic
  // boundaries, which requires a point_locator, which just got
  // invalidated by _coarsen_elements() and hasn't yet been cleared by
  // prepare_for_use().

  //  if (_maintain_level_one)
  //    libmesh_assert(test_level_one(true));
  //  libmesh_assert(this->make_coarsening_compatible(maintain_level_one));
  //  libmesh_assert(this->make_refinement_compatible(maintain_level_one));

  // FIXME: This won't pass unless we add a redundant find_neighbors()
  // call or replace find_neighbors() with on-the-fly neighbor updating
  // libmesh_assert(!this->eliminate_unrefined_patches());

  // We can't contract the mesh ourselves anymore - a System might
  // need to restrict old coefficient vectors first
  // _mesh.contract();

  // Now refine the flagged elements.  This will
  // take up some space, maybe more than what was freed.
  const bool refining_changed_mesh =
    this->_refine_elements();

  // Finally, the new mesh needs to be prepared for use
  if (coarsening_changed_mesh || refining_changed_mesh)
    {
#ifdef DEBUG
      _mesh.libmesh_assert_valid_parallel_ids();
#endif

      _mesh.prepare_for_use (/*skip_renumber =*/false);

      if (_maintain_level_one)
        libmesh_assert(test_level_one(true));
      libmesh_assert(test_unflagged(true));
      libmesh_assert(this->make_coarsening_compatible(maintain_level_one));
      libmesh_assert(this->make_refinement_compatible(maintain_level_one));
      // FIXME: This won't pass unless we add a redundant find_neighbors()
      // call or replace find_neighbors() with on-the-fly neighbor updating
      // libmesh_assert(!this->eliminate_unrefined_patches());

      return true;
    }
  else
    {
      if (_maintain_level_one)
        libmesh_assert(test_level_one(true));
      libmesh_assert(test_unflagged(true));
      libmesh_assert(this->make_coarsening_compatible(maintain_level_one));
      libmesh_assert(this->make_refinement_compatible(maintain_level_one));
    }

  // Otherwise there was no change in the mesh,
  // let the user know.  Also, there is no need
  // to prepare the mesh for use since it did not change.
  return false;

}
bool libMesh::MeshRefinement::refine_elements ( const bool  maintain_level_one = true)

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. Consequently, this function returns true if the mesh actually changed (hence data needs to be projected) and false otherwise.

The argument maintain_level_one is now deprecated; use the option face_level_mismatch_limit() instead.

Definition at line 737 of file mesh_refinement.C.

References _edge_level_mismatch_limit, _face_level_mismatch_limit, _mesh, _node_level_mismatch_limit, _refine_elements(), libMesh::Elem::active(), libMesh::ParallelObject::comm(), libMesh::Elem::DO_NOTHING, libMesh::MeshBase::elements_begin(), libMesh::MeshBase::elements_end(), eliminate_unrefined_patches(), libMesh::Elem::INACTIVE, libMesh::MeshBase::is_serial(), libMesh::Elem::JUST_REFINED, libMesh::libmesh_assert(), limit_level_mismatch_at_edge(), limit_level_mismatch_at_node(), make_flags_parallel_consistent(), make_refinement_compatible(), libMesh::Parallel::Communicator::max(), libMesh::Parallel::Communicator::min(), libMesh::out, libMesh::MeshBase::prepare_for_use(), libMesh::Elem::refinement_flag(), libMesh::Elem::set_p_refinement_flag(), libMesh::Elem::set_refinement_flag(), and test_level_one().

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

{
  // This function must be run on all processors at once
  parallel_object_only();

  bool _maintain_level_one = maintain_level_one;

  // If the user used non-default parameters, let's warn that they're
  // deprecated
  if (!maintain_level_one)
    {
      libmesh_deprecated();
    }
  else
    _maintain_level_one = _face_level_mismatch_limit;

  if (_maintain_level_one)
    libmesh_assert(test_level_one(true));

  // Possibly clean up the refinement flags from
  // a previous step
  MeshBase::element_iterator       elem_it  = _mesh.elements_begin();
  const MeshBase::element_iterator elem_end = _mesh.elements_end();

  for ( ; elem_it != elem_end; ++elem_it)
    {
      // Pointer to the element
      Elem *elem = *elem_it;

      // Set refinement flag to INACTIVE if the
      // element isn't active
      if ( !elem->active())
        {
          elem->set_refinement_flag(Elem::INACTIVE);
          elem->set_p_refinement_flag(Elem::INACTIVE);
        }

      // This might be left over from the last step
      if (elem->refinement_flag() == Elem::JUST_REFINED)
        elem->set_refinement_flag(Elem::DO_NOTHING);
    }



  // Parallel consistency has to come first, or coarsening
  // along processor boundaries might occasionally be falsely
  // prevented
  bool flags_were_consistent = this->make_flags_parallel_consistent();

  // In theory, we should be able to remove the above call, which can
  // be expensive and should be unnecessary.  In practice, doing
  // consistent flagging in parallel is hard, it's impossible to
  // verify at the library level if it's being done by user code, and
  // we don't want to abort large parallel runs in opt mode... but we
  // do want to warn that they should be fixed.
  libmesh_assert(flags_were_consistent);
  if (!flags_were_consistent)
    {
      libMesh::out << "Refinement flags were not consistent between processors!\n"
                   << "Correcting and continuing.";
    }

  // Repeat until flag changes match on every processor
  do
    {
      // Repeat until coarsening & refinement flags jive
      bool satisfied = false;
      do
        {
          const bool refinement_satisfied =
            this->make_refinement_compatible(maintain_level_one);

          bool smoothing_satisfied =
            !this->eliminate_unrefined_patches();// &&

          if (_edge_level_mismatch_limit)
            smoothing_satisfied = smoothing_satisfied &&
              !this->limit_level_mismatch_at_edge (_edge_level_mismatch_limit);

          if (_node_level_mismatch_limit)
            smoothing_satisfied = smoothing_satisfied &&
              !this->limit_level_mismatch_at_node (_node_level_mismatch_limit);

          satisfied = (refinement_satisfied &&
                       smoothing_satisfied);
#ifdef DEBUG
          bool max_satisfied = satisfied,
            min_satisfied = satisfied;
          this->comm().max(max_satisfied);
          this->comm().min(min_satisfied);
          libmesh_assert_equal_to (satisfied, max_satisfied);
          libmesh_assert_equal_to (satisfied, min_satisfied);
#endif
        }
      while (!satisfied);
    }
  while (!_mesh.is_serial() && !this->make_flags_parallel_consistent());

  // Now refine the flagged elements.  This will
  // take up some space, maybe more than what was freed.
  const bool mesh_changed =
    this->_refine_elements();

  if (_maintain_level_one)
    libmesh_assert(test_level_one(true));
  libmesh_assert(this->make_refinement_compatible(maintain_level_one));
  // FIXME: This won't pass unless we add a redundant find_neighbors()
  // call or replace find_neighbors() with on-the-fly neighbor updating
  // libmesh_assert(!this->eliminate_unrefined_patches());

  // Finally, the new mesh needs to be prepared for use
  if (mesh_changed)
    _mesh.prepare_for_use (/*skip_renumber =*/false);

  return mesh_changed;
}

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

References _refine_fraction, and _use_member_parameters.

Set _enforce_mismatch_limit_prior_to_refinement option. Defaults to false. Deprecated - use enforce_mismatch_limit_prior_to_refinement() instead.

Definition at line 852 of file mesh_refinement.h.

References enforce_mismatch_limit_prior_to_refinement().

{
  libmesh_deprecated();
  enforce_mismatch_limit_prior_to_refinement() = enforce;
}

Sets the PeriodicBoundaries pointer.

Definition at line 79 of file mesh_refinement.C.

References _periodic_boundaries.

{
  _periodic_boundaries = pb_ptr;
}

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

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

{
  MeshBase::element_iterator       elem_it  = _mesh.elements_begin();
  const MeshBase::element_iterator elem_end = _mesh.elements_end();

  for ( ; elem_it != elem_end; ++elem_it)
    {
      if ((*elem_it)->active())
        {
          (*elem_it)->set_p_refinement_flag((*elem_it)->refinement_flag());
          (*elem_it)->set_refinement_flag(Elem::DO_NOTHING);
        }
      else
        {
          (*elem_it)->set_p_refinement_flag((*elem_it)->refinement_flag());
          (*elem_it)->set_refinement_flag(Elem::INACTIVE);
        }
    }
}
bool libMesh::MeshRefinement::test_level_one ( bool  libmesh_assert_yes = false)

Returns true if and only if the mesh is level one smooth Returns false otherwise Aborts the program if libmesh_assert_yes is true and the mesh is not level one smooth

Definition at line 304 of file mesh_refinement.C.

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

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

{
  // This function must be run on all processors at once
  parallel_object_only();

  // We may need a PointLocator for topological_neighbor() tests
  // later, which we need to make sure gets constructed on all
  // processors at once.
  UniquePtr<PointLocatorBase> point_locator;

#ifdef LIBMESH_ENABLE_PERIODIC
  bool has_periodic_boundaries =
    _periodic_boundaries && !_periodic_boundaries->empty();
  libmesh_assert(this->comm().verify(has_periodic_boundaries));

  if (has_periodic_boundaries)
    point_locator = _mesh.sub_point_locator();
#endif

  MeshBase::element_iterator       elem_it  = _mesh.active_local_elements_begin();
  const MeshBase::element_iterator elem_end = _mesh.active_local_elements_end();

  bool failure = false;

#ifndef NDEBUG
  Elem *failed_elem = NULL;
  Elem *failed_neighbor = NULL;
#endif // !NDEBUG

  for ( ; elem_it != elem_end && !failure; ++elem_it)
    {
      // Pointer to the element
      Elem *elem = *elem_it;

      for (unsigned int n=0; n<elem->n_neighbors(); n++)
        {
          Elem *neighbor =
            topological_neighbor(elem, point_locator.get(), n);

          if (!neighbor || !neighbor->active() ||
              neighbor == remote_elem)
            continue;

          if ((neighbor->level() + 1 < elem->level()) ||
              (neighbor->p_level() + 1 < elem->p_level()) ||
              (neighbor->p_level() > elem->p_level() + 1))
            {
              failure = true;
#ifndef NDEBUG
              failed_elem = elem;
              failed_neighbor = neighbor;
#endif // !NDEBUG
              break;
            }
        }
    }

  // If any processor failed, we failed globally
  this->comm().max(failure);

  if (failure)
    {
      // We didn't pass the level one test, so libmesh_assert that
      // we're allowed not to
#ifndef NDEBUG
      if (libmesh_assert_pass)
        {
          libMesh::out <<
            "MeshRefinement Level one failure, element: " <<
            *failed_elem << std::endl;
          libMesh::out <<
            "MeshRefinement Level one failure, neighbor: " <<
            *failed_neighbor << std::endl;
        }
#endif // !NDEBUG
      libmesh_assert(!libmesh_assert_pass);
      return false;
    }
  return true;
}
bool libMesh::MeshRefinement::test_unflagged ( bool  libmesh_assert_yes = false)

Returns true if and only if the mesh has no elements flagged to be coarsened or refined Returns false otherwise Aborts the program if libmesh_assert_yes is true and the mesh has flagged elements

Definition at line 387 of file mesh_refinement.C.

References _mesh, libMesh::MeshBase::active_local_elements_begin(), libMesh::MeshBase::active_local_elements_end(), libMesh::Elem::COARSEN, libMesh::ParallelObject::comm(), libMesh::libmesh_assert(), libMesh::Parallel::Communicator::max(), libMesh::out, libMesh::Elem::p_refinement_flag(), libMesh::Elem::REFINE, and libMesh::Elem::refinement_flag().

Referenced by refine_and_coarsen_elements().

{
  // This function must be run on all processors at once
  parallel_object_only();

  bool found_flag = false;

  // Search for local flags
  MeshBase::element_iterator       elem_it  = _mesh.active_local_elements_begin();
  const MeshBase::element_iterator elem_end = _mesh.active_local_elements_end();

#ifndef NDEBUG
  Elem *failed_elem = NULL;
#endif

  for ( ; elem_it != elem_end; ++elem_it)
    {
      // Pointer to the element
      Elem *elem = *elem_it;

      if (elem->refinement_flag() == Elem::REFINE ||
          elem->refinement_flag() == Elem::COARSEN ||
          elem->p_refinement_flag() == Elem::REFINE ||
          elem->p_refinement_flag() == Elem::COARSEN)
        {
          found_flag = true;
#ifndef NDEBUG
          failed_elem = elem;
#endif
          break;
        }
    }

  // If we found a flag on any processor, it counts
  this->comm().max(found_flag);

  if (found_flag)
    {
#ifndef NDEBUG
      if (libmesh_assert_pass)
        {
          libMesh::out <<
            "MeshRefinement test_unflagged failure, element: " <<
            *failed_elem << std::endl;
        }
#endif
      // We didn't pass the "elements are unflagged" test,
      // so libmesh_assert that we're allowed not to
      libmesh_assert(!libmesh_assert_pass);
      return false;
    }
  return true;
}
Elem * libMesh::MeshRefinement::topological_neighbor ( Elem elem,
const PointLocatorBase point_locator,
const unsigned int  side 
) [private]

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

Definition at line 1795 of file mesh_refinement.C.

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

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

{
#ifdef LIBMESH_ENABLE_PERIODIC
  if (_periodic_boundaries && !_periodic_boundaries->empty())
    {
      libmesh_assert(point_locator);
      return elem->topological_neighbor(side, _mesh, *point_locator, _periodic_boundaries);
    }
#endif
  return elem->neighbor(side);
}
void libMesh::MeshRefinement::uniformly_coarsen ( unsigned int  n = 1)

Attempts to uniformly coarsen the mesh n times.

Definition at line 1764 of file mesh_refinement.C.

References _coarsen_elements(), _mesh, libMesh::MeshBase::active_elements_begin(), libMesh::MeshBase::active_elements_end(), clean_refinement_flags(), libMesh::Elem::COARSEN, libMesh::Elem::COARSEN_INACTIVE, and libMesh::MeshBase::prepare_for_use().

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

{
  // Coarsen n times
  for (unsigned int rstep=0; rstep<n; rstep++)
    {
      // Clean up the refinement flags
      this->clean_refinement_flags();

      // Flag all the active elements for coarsening
      MeshBase::element_iterator       elem_it  = _mesh.active_elements_begin();
      const MeshBase::element_iterator elem_end = _mesh.active_elements_end();

      for ( ; elem_it != elem_end; ++elem_it)
        {
          (*elem_it)->set_refinement_flag(Elem::COARSEN);
          if ((*elem_it)->parent())
            (*elem_it)->parent()->set_refinement_flag(Elem::COARSEN_INACTIVE);
        }

      // Coarsen all the elements we just flagged.
      this->_coarsen_elements();
    }


  // Finally, the new mesh probably needs to be prepared for use
  if (n > 0)
    _mesh.prepare_for_use (/*skip_renumber =*/false);
}
void libMesh::MeshRefinement::uniformly_p_coarsen ( unsigned int  n = 1)

Attempts to uniformly p coarsen the mesh n times.

Definition at line 1714 of file mesh_refinement.C.

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

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

{
  // Coarsen p times
  for (unsigned int rstep=0; rstep<n; rstep++)
    {
      // P coarsen all the active elements
      MeshBase::element_iterator       elem_it  = _mesh.active_elements_begin();
      const MeshBase::element_iterator elem_end = _mesh.active_elements_end();

      for ( ; elem_it != elem_end; ++elem_it)
        {
          if ((*elem_it)->p_level() > 0)
            {
              (*elem_it)->set_p_level((*elem_it)->p_level()-1);
              (*elem_it)->set_p_refinement_flag(Elem::JUST_COARSENED);
            }
        }
    }
}
void libMesh::MeshRefinement::uniformly_p_refine ( unsigned int  n = 1)

Uniformly p refines the mesh n times.

Definition at line 1695 of file mesh_refinement.C.

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

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

{
  // Refine n times
  for (unsigned int rstep=0; rstep<n; rstep++)
    {
      // P refine all the active elements
      MeshBase::element_iterator       elem_it  = _mesh.active_elements_begin();
      const MeshBase::element_iterator elem_end = _mesh.active_elements_end();

      for ( ; elem_it != elem_end; ++elem_it)
        {
          (*elem_it)->set_p_level((*elem_it)->p_level()+1);
          (*elem_it)->set_p_refinement_flag(Elem::JUST_REFINED);
        }
    }
}
void libMesh::MeshRefinement::uniformly_refine ( unsigned int  n = 1)

Uniformly refines the mesh n times.

Definition at line 1736 of file mesh_refinement.C.

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

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

{
  // Refine n times
  // FIXME - this won't work if n>1 and the mesh
  // has already been attached to an equation system
  for (unsigned int rstep=0; rstep<n; rstep++)
    {
      // Clean up the refinement flags
      this->clean_refinement_flags();

      // Flag all the active elements for refinement.
      MeshBase::element_iterator       elem_it  = _mesh.active_elements_begin();
      const MeshBase::element_iterator elem_end = _mesh.active_elements_end();

      for ( ; elem_it != elem_end; ++elem_it)
        (*elem_it)->set_refinement_flag(Elem::REFINE);

      // Refine all the elements we just flagged.
      this->_refine_elements();
    }

  // Finally, the new mesh probably needs to be prepared for use
  if (n > 0)
    _mesh.prepare_for_use (/*skip_renumber =*/false);
}

Updates the _new_nodes_map

Definition at line 297 of file mesh_refinement.C.

References _mesh, _new_nodes_map, and libMesh::LocationMap< T >::init().

Referenced by _coarsen_elements(), and _refine_elements().


Member Data Documentation

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

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

Data structure that holds the new nodes information.

Definition at line 661 of file mesh_refinement.h.

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

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 673 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: