Poster of Linux kernelThe best gift for a Linux geek
MeshRefinement

MeshRefinement

Section: C Library Functions (3) Updated: Thu Apr 7 2011
Local index Up
 

NAME

MeshRefinement -  

SYNOPSIS


#include <mesh_refinement.h>  

Public Member Functions


MeshRefinement (MeshBase &mesh)

~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 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)

bool test_level_one (bool libmesh_assert_yes=false)

bool test_unflagged (bool libmesh_assert_yes=false)

Node * add_point (const Point &p, const unsigned int processor_id, const Real tol)

Elem * add_elem (Elem *elem)

const MeshBase & get_mesh () const

MeshBase & get_mesh ()

bool & coarsen_by_parents ()

Real & refine_fraction ()

Real & coarsen_fraction ()

unsigned int & max_h_level ()

Real & coarsen_threshold ()

unsigned int & nelem_target ()

Real & absolute_global_tolerance ()

unsigned char & face_level_mismatch_limit ()

unsigned char & edge_level_mismatch_limit ()

unsigned char & node_level_mismatch_limit ()
 

Private Member Functions


MeshRefinement (const MeshRefinement &)

MeshRefinement & operator= (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 ()

void clean_refinement_flags ()

bool make_coarsening_compatible (const bool)

bool make_refinement_compatible (const bool)

bool make_flags_parallel_consistent ()
 

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

unsigned int _nelem_target

Real _absolute_global_tolerance

unsigned char _face_level_mismatch_limit

unsigned char _edge_level_mismatch_limit

unsigned char _node_level_mismatch_limit
 

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

Constructor & Destructor Documentation

 

MeshRefinement::MeshRefinement (MeshBase &mesh)Constructor.

Definition at line 51 of file mesh_refinement.C.

                                           :
  _mesh(m),
  _use_member_parameters(false),
  _coarsen_by_parents(false),
  _refine_fraction(0.3),
  _coarsen_fraction(0.0),
  _max_h_level(libMesh::invalid_uint),
  _coarsen_threshold(10),
  _nelem_target(0),
  _absolute_global_tolerance(0.0),
  _face_level_mismatch_limit(1),
  _edge_level_mismatch_limit(0),
  _node_level_mismatch_limit(0)
{
}
 

MeshRefinement::MeshRefinement (const MeshRefinement &) [private]

 

MeshRefinement::~MeshRefinement ()Destructor. Deletes all the elements that are currently stored.

Definition at line 69 of file mesh_refinement.C.

References clear().

{
  this->clear();  
}
 

Member Function Documentation

 

bool MeshRefinement::_coarsen_elements () [private]Coarsens user-requested elements. Both coarsen_elements and refine_elements used to be in the public interface for the MeshRefinement object. Unfortunately, without proper preparation (make_refinement_compatible, make_coarsening_compatible) at least coarsen_elements() did not work alone. By making them private, we signal to the user that they are not part of the interface.

It is possible that for a given set of refinement flags there is actually no change upon calling this member function. Consequently, this function returns true if the mesh actually changed (hence data needs to be projected) and false otherwise.

Definition at line 1358 of file mesh_refinement.C.

References _mesh, _new_nodes_map, Elem::active(), MeshBase::boundary_info, clear(), Elem::coarsen(), Elem::COARSEN, Elem::COARSEN_INACTIVE, Elem::DO_NOTHING, MeshBase::elements_begin(), MeshBase::elements_end(), MeshBase::is_serial(), Elem::JUST_COARSENED, Elem::level(), MeshTools::libmesh_assert_valid_node_procids(), MeshCommunication::make_nodes_parallel_consistent(), std::max(), Elem::nullify_neighbors(), Elem::p_level(), Elem::p_refinement_flag(), Elem::refinement_flag(), Elem::set_p_level(), Elem::set_p_refinement_flag(), update_nodes_map(), and 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_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 != NULL);
      
      // 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 (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.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
  Parallel::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, _new_nodes_map);

      // Clear the _new_nodes_map
      this->clear();
  
#ifdef DEBUG
      MeshTools::libmesh_assert_valid_node_procids(_mesh);
#endif
    }

  STOP_LOG ('_coarsen_elements()', 'MeshRefinement');

  return mesh_changed;
}
 

bool MeshRefinement::_refine_elements () [private]Refines user-requested elements.

It is possible that for a given set of refinement flags there is actually no change upon calling this member function. Consequently, this function returns true if the mesh actually changed (hence data needs to be projected) and false otherwise.

Definition at line 1471 of file mesh_refinement.C.

References _mesh, _new_nodes_map, Elem::active(), clear(), MeshBase::elements_begin(), MeshBase::elements_end(), MeshBase::is_serial(), Elem::JUST_REFINED, ParallelMesh::libmesh_assert_valid_parallel_ids(), MeshCommunication::make_elems_parallel_consistent(), MeshCommunication::make_nodes_parallel_consistent(), std::max(), Elem::p_level(), Elem::p_refinement_flag(), Elem::REFINE, Elem::refinement_flag(), Elem::set_p_level(), Elem::set_p_refinement_flag(), update_nodes_map(), and 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_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.
  unsigned int 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 (unsigned int 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
  Parallel::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, _new_nodes_map);
#ifdef DEBUG
      ParallelMesh *pmesh = dynamic_cast<ParallelMesh *>(&_mesh);
      if (pmesh)
        pmesh->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;
}
 

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

absolute_global_tolerance is 0 by default.

Definition at line 667 of file mesh_refinement.h.

References _absolute_global_tolerance, and _use_member_parameters.

{
  _use_member_parameters = true;
  return _absolute_global_tolerance;
}
 

Elem * MeshRefinement::add_elem (Elem *elem)Adds the element elem to the mesh.

Definition at line 113 of file mesh_refinement.C.

References _mesh, and MeshBase::add_elem().

Referenced by Elem::refine().

{
  libmesh_assert (elem != NULL);

  
//   // 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;
}
 

void MeshRefinement::add_p_to_h_refinement ()Takes a mesh whose elements are flagged for h refinement and coarsening, and adds flags to request p refinement and coarsening of the same elements.

Definition at line 644 of file mesh_refinement_flagging.C.

References _mesh, MeshBase::elements_begin(), and 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 * MeshRefinement::add_point (const Point &p, const unsigned intprocessor_id, const Realtol)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 83 of file mesh_refinement.C.

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

Referenced by 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, processor_id);

  libmesh_assert (node != NULL);

  // 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;
}
 

void MeshRefinement::clean_refinement_flags () [private]Sets the refinement flag to Elem::DO_NOTHING for each element in the mesh.

Definition at line 655 of file mesh_refinement_flagging.C.

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

Referenced by flag_elements_by_elem_fraction(), flag_elements_by_error_fraction(), flag_elements_by_nelem_target(), 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);
        } 
    }
}
 

void MeshRefinement::clear ()Deletes all the data that are currently stored.

Definition at line 76 of file mesh_refinement.C.

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

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

{
  _new_nodes_map.clear();
}
 

bool & MeshRefinement::coarsen_by_parents () [inline]If coarsen_by_parents is true, complete groups of sibling elements (elements with the same parent) will be flagged for coarsening. This should make the coarsening more likely to occur as requested.

coarsen_by_parents is true by default.

Definition at line 631 of file mesh_refinement.h.

References _coarsen_by_parents, and _use_member_parameters.

{
  _use_member_parameters = true;
  return _coarsen_by_parents;
}
 

bool MeshRefinement::coarsen_elements (const boolmaintain_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 515 of file mesh_refinement.C.

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

Referenced by EquationSystems::reinit().

{
  // This function must be run on all processors at once
  parallel_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
  if (!_mesh.is_serial())
    this->make_flags_parallel_consistent();

  // 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;
          Parallel::max(max_satisfied);
          Parallel::min(min_satisfied);
          libmesh_assert (satisfied == max_satisfied);
          libmesh_assert (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 ();

  return mesh_changed;
}
 

Real & MeshRefinement::coarsen_fraction () [inline]The coarsen_fraction sets either a desired target or a desired maximum number of elements to flag for coarsening, depending on which flag_elements_by method is called.

coarsen_fraction must be in $ [0,1] $, and is 0 by default.

Definition at line 643 of file mesh_refinement.h.

References _coarsen_fraction, and _use_member_parameters.

{
  _use_member_parameters = true;
  return _coarsen_fraction;
}
 

Real & MeshRefinement::coarsen_threshold () [inline]The coarsen_threshold provides hysteresis in AMR/C strategies. Refinement of elements with error estimate E will be done even at the expense of coarsening elements whose children's accumulated error does not exceed coarsen_threshold * E.

coarsen_threshold must be in $ [0,1] $, and is 0.1 by default.

Definition at line 655 of file mesh_refinement.h.

References _coarsen_threshold, and _use_member_parameters.

{
  _use_member_parameters = true;
  return _coarsen_threshold;
}
 

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

References DofObject::id(), std::max(), std::min(), and Elem::parent().

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_only();

  // Make sure the input error vector is valid
#ifdef DEBUG
  for (unsigned int i=0; i != error_per_cell.size(); ++i)
    {
      libmesh_assert(error_per_cell[i] >= 0);
  // isnan() isn't standard C++ yet
  #ifdef isnan
      libmesh_assert(!isnan(error_per_cell[i]));
  #endif
    }
#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 unsigned int parentid  = parent->id();
              libmesh_assert (parentid < error_per_parent.size());
              error_per_parent[parentid] = -1.0;
            }
        }
    }

  // Sync between processors.
  // Use a reference to std::vector to avoid confusing
  // Parallel::min
  std::vector<ErrorVectorReal> &epp = error_per_parent;
  Parallel::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 unsigned int parentid  = parent->id();
          libmesh_assert (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
  Parallel::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 (unsigned int 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 Parallel::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]);
    }
}
 

unsigned char & MeshRefinement::edge_level_mismatch_limit () [inline]If edge_level_mismatch_limit is set to a nonzero value, then refinement and coarsening will produce meshes in which the refinement level of two edge neighbors will not differ by more than that limit. If edge_level_mismatch_limit is 0, then level differences will be unlimited.

edge_level_mismatch_limit is 0 by default.

Definition at line 678 of file mesh_refinement.h.

References _edge_level_mismatch_limit.

{
  return _edge_level_mismatch_limit;
}
 

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


   o---o---o---o---o---o---o
   |   |   |   |   |   |   |
   |   |   |   |   |   |   |
   o---o---o---o---o---o---o
   |   |   |   |   |   |   |
   |   |   |   |   |   |   |
   o---o---o---o---o---o---o
   |   |   |       |   |   |
   |   |   |       |   |   |
   o---o---o       o---o---o
   |   |   |       |   |   |
   |   |   |       |   |   |
   o---o---o---o---o---o---o
   |   |   |   |   |   |   |
   |   |   |   |   |   |   |
   o---o---o---o---o---o---o
   |   |   |   |   |   |   |
   |   |   |   |   |   |   |
   o---o---o---o---o---o---o
   

into this:


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

by refining the indicated element

Definition at line 265 of file mesh_refinement_smoothing.C.

References _mesh, Elem::active(), MeshBase::active_elements_begin(), MeshBase::active_elements_end(), Elem::ancestor(), Elem::child(), Elem::COARSEN, Elem::COARSEN_INACTIVE, Elem::DO_NOTHING, Elem::INACTIVE, Elem::level(), std::max(), Elem::min_new_p_level_by_neighbor(), Elem::n_children(), Elem::n_neighbors(), Elem::neighbor(), Elem::p_level(), Elem::p_refinement_flag(), Elem::parent(), Elem::REFINE, Elem::refinement_flag(), remote_elem, Elem::set_p_refinement_flag(), and 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_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(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(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(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
  Parallel::max(flags_changed);

  return flags_changed;
}
 

unsigned char & MeshRefinement::face_level_mismatch_limit () [inline]If face_level_mismatch_limit is set to a nonzero value, then refinement and coarsening will produce meshes in which the refinement level of two face neighbors will not differ by more than that limit. If face_level_mismatch_limit is 0, then level differences will be unlimited.

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

Definition at line 673 of file mesh_refinement.h.

References _face_level_mismatch_limit.

Referenced by EquationSystems::reinit().

{
  return _face_level_mismatch_limit;
}
 

void MeshRefinement::flag_elements_by_elem_fraction (const ErrorVector &error_per_cell, const Realrefine_fraction = 0.3, const Realcoarsen_fraction = 0.0, const unsigned intmax_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 409 of file mesh_refinement_flagging.C.

References _coarsen_by_parents, _coarsen_fraction, _max_h_level, _mesh, _refine_fraction, _use_member_parameters, MeshBase::active_elements_begin(), MeshBase::active_elements_end(), clean_refinement_flags(), Elem::COARSEN, create_parent_error_vector(), DofObject::id(), libMesh::invalid_uint, MeshBase::is_serial(), Elem::level(), MeshBase::mesh_dimension(), MeshBase::n_elem(), Elem::parent(), libMesh::processor_id(), Elem::REFINE, and Elem::set_refinement_flag().

{
  // FIXME - this won't work on a non-serialized mesh yet
  if (!_mesh.is_serial())
    {
      if (libMesh::processor_id() == 0)
        std::cerr << 'flag_elements_by_elem_fraction does not yet '
                  << 'work on a parallel mesh.' << std::endl;
      libmesh_error();
    }

  // 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 (_refine_fraction  >= 0. && _refine_fraction  <= 1.);
  libmesh_assert (_coarsen_fraction >= 0. && _coarsen_fraction <= 1.);

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

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

  // The number of elements to flag for refinement
  const unsigned int n_elem_refine =
    static_cast<unsigned int>(_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<float> 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_elements_begin();
  const MeshBase::element_iterator elem_end = _mesh.active_elements_end(); 

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

  // 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());
  }
  

  float 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;

      unsigned int 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 + 1];

  // 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 MeshRefinement::flag_elements_by_error_fraction (const ErrorVector &error_per_cell, const Realrefine_fraction = 0.3, const Realcoarsen_fraction = 0.0, const unsigned intmax_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 43 of file mesh_refinement_flagging.C.

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

Referenced by Adaptive< T >::solve().

{
  // 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 (_refine_fraction  >= 0. && _refine_fraction  <= 1.);
  libmesh_assert (_coarsen_fraction >= 0. && _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 unsigned int id  = (*el_it)->id();
    libmesh_assert (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]);
  }
  Parallel::max(error_max);
  Parallel::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
//   std::cout << ' 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 unsigned int id  = elem->id();

    libmesh_assert (id < error_per_cell.size());
      
    const float elem_error = error_per_cell[id];

    if (_coarsen_by_parents)
    {
      Elem* parent           = elem->parent();
      if (parent)
      {
        const unsigned int 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);
  }
}
 

void MeshRefinement::flag_elements_by_error_tolerance (const ErrorVector &error_per_cell)Flags elements for coarsening and refinement based on the computed error passed in error_per_cell. This method refines the worst elements with errors greater than absolute_global_tolerance / n_active_elem, flagging at most refine_fraction * n_active_elem It coarsens elements with errors less than coarsen_threshold * global_tolerance / n_active_elem, flagging at most coarsen_fraction * n_active_elem

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

Definition at line 172 of file mesh_refinement_flagging.C.

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

{
  // Check for valid fractions..
  // The fraction values must be in [0,1]
  libmesh_assert (_coarsen_threshold  >= 0. && _refine_fraction  <= 1.);
  libmesh_assert (_refine_fraction  >= 0. && _refine_fraction  <= 1.);
  libmesh_assert (_coarsen_fraction >= 0. && _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 unsigned int elem_number = elem->id();
    const float        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)
    {
      float 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 MeshRefinement::flag_elements_by_mean_stddev (const ErrorVector &error_per_cell, const Realrefine_fraction = 1.0, const Realcoarsen_fraction = 0.0, const unsigned intmax_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 551 of file mesh_refinement_flagging.C.

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

{
  // FIXME - this won't work on a non-serialized mesh yet
  if (!_mesh.is_serial())
    {
      if (libMesh::processor_id() == 0)
        std::cerr << 'flag_elements_by_mean_stddev does not yet '
                  << 'work on a parallel mesh.' << std::endl;
      libmesh_error();
    }

  // 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 (_refine_fraction  >= 0. && _refine_fraction  <= 1.);
  libmesh_assert (_coarsen_fraction >= 0. && _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 unsigned int id  = elem->id();

      libmesh_assert (id < error_per_cell.size());
      
      const float 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);
    }
}
 

bool MeshRefinement::flag_elements_by_nelem_target (const ErrorVector &error_per_cell)Flags elements for coarsening and refinement based on the computed error passed in error_per_cell. This method attempts to produce a mesh with slightly more than nelem_target active elements, trading element refinement for element coarsening when their error ratios exceed coarsen_threshold. It flags no more than refine_fraction * n_elem elements for refinement and flags no more than coarsen_fraction * n_elem elements for coarsening. 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 234 of file mesh_refinement_flagging.C.

References _coarsen_by_parents, _coarsen_fraction, _coarsen_threshold, _max_h_level, _mesh, _nelem_target, _refine_fraction, Elem::active(), MeshBase::active_elements_begin(), MeshBase::active_elements_end(), Elem::child(), clean_refinement_flags(), Elem::COARSEN, create_parent_error_vector(), MeshBase::elem(), Elem::has_children(), MeshBase::is_serial(), Elem::level(), MeshBase::mesh_dimension(), std::min(), MeshBase::n_active_elem(), Elem::n_children(), libMesh::processor_id(), Elem::REFINE, and Elem::set_refinement_flag().

{
  // Check for valid fractions..
  // The fraction values must be in [0,1]
  libmesh_assert (_refine_fraction  >= 0. && _refine_fraction  <= 1.);
  libmesh_assert (_coarsen_fraction >= 0. && _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 unsigned int n_active_elem  = _mesh.n_active_elem();

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

  // The maximum number of elements to flag for refinement
  const unsigned int max_elem_refine  =
    static_cast<unsigned int>(_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 int n_elem_new = _nelem_target - n_active_elem;

  // Create an vector with active element errors and ids,
  // sorted by highest errors first
  std::vector<std::pair<float, unsigned int> > sorted_error;

  sorted_error.reserve (n_active_elem);

  // FIXME - this won't work on a non-serialized mesh yet
  if (!_mesh.is_serial())
    {
      if (libMesh::processor_id() == 0)
        std::cerr << 'flag_elements_by_nelem_target does not yet '
                  << 'work on a parallel mesh.' << std::endl;
      libmesh_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)
    {
      unsigned int eid = (*elem_it)->id();
      libmesh_assert(eid < error_per_cell.size());
      sorted_error.push_back
        (std::make_pair(error_per_cell[eid], eid));
    }

  // 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<float, unsigned int> > 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 (unsigned int 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
  unsigned int coarsen_count = 0;
  unsigned int 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(static_cast<unsigned int>(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(static_cast<unsigned int>(-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++;
  }

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

      unsigned int eid = sorted_error[i].second;
      Elem *elem = _mesh.elem(eid);
      if (elem->level() < _max_h_level)
        {
          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;
  unsigned int successful_coarsen_count = 0;
  for (unsigned int i=0; i != sorted_parent_error.size(); ++i)
    {
      if (successful_coarsen_count >= coarsen_count * twotodim)
        break;

      unsigned int parent_id = sorted_parent_error[i].second;
      Elem *parent = _mesh.elem(parent_id);
      libmesh_assert(parent->has_children());
      for (unsigned int c=0; c != parent->n_children(); ++c)
        {
          Elem *elem = parent->child(c);
          if (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;
}
 

const MeshBase& MeshRefinement::get_mesh () const [inline]Returns:

a constant reference to the MeshBase object associated with this object.

Definition at line 276 of file mesh_refinement.h.

References _mesh.

{ return _mesh; }
 

MeshBase& MeshRefinement::get_mesh () [inline]Returns:

a writeable reference to the MeshBase object associated with this object.

Definition at line 282 of file mesh_refinement.h.

References _mesh.

{ return _mesh; }
 

bool MeshRefinement::limit_level_mismatch_at_edge (const unsigned intmax_mismatch) [private]

Definition at line 130 of file mesh_refinement_smoothing.C.

References _mesh, MeshBase::active_elements_begin(), MeshBase::active_elements_end(), Elem::build_edge(), Elem::level(), std::max(), Elem::n_edges(), Elem::p_level(), Elem::p_refinement_flag(), Elem::parent(), Elem::REFINE, Elem::refinement_flag(), Elem::set_p_refinement_flag(), and 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_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 =
          elem->level() + ((elem->refinement_flag() == Elem::REFINE) ? 1 : 0);
        const unsigned char elem_p_level =
          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++)
          {
            AutoPtr<Elem> edge = elem->build_edge(n);
            unsigned int childnode0 = edge->node(0);
            unsigned int childnode1 = edge->node(1);
            if (childnode1 < childnode0)
              std::swap(childnode0, childnode1);

            for (const Elem *p = elem; p != NULL; p = p->parent())
              {
                AutoPtr<Elem> pedge = p->build_edge(n);
                unsigned int node0 = pedge->node(0);
                unsigned int 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)
          continue;

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

            std::pair<unsigned int, unsigned int> 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;
              }
          }
      }     
  }
  
  // If flags changed on any processor then they changed globally
  Parallel::max(flags_changed);

  return flags_changed;
}
 

bool MeshRefinement::limit_level_mismatch_at_node (const unsigned intmax_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     
   .fi

 by refining the indicated element 

Definition at line 38 of file mesh_refinement_smoothing.C.

References _mesh, MeshBase::active_elements_begin(), MeshBase::active_elements_end(), Elem::level(), std::max(), Elem::n_nodes(), MeshBase::n_nodes(), Elem::node(), Elem::p_level(), Elem::p_refinement_flag(), Elem::REFINE, Elem::refinement_flag(), Elem::set_p_refinement_flag(), and 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_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 =
          elem->level() + ((elem->refinement_flag() == Elem::REFINE) ? 1 : 0);
        const unsigned char elem_p_level =
          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 unsigned int node_number = elem->node(n);

            libmesh_assert (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
  {
    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)
          continue;

        // Loop over the nodes, check for possible mismatch
        for (unsigned int n=0; n<elem->n_nodes(); n++)
          {
            const unsigned int 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;
              }
          }
      }     
  }
  
  // If flags changed on any processor then they changed globally
  Parallel::max(flags_changed);

  return flags_changed;
}
 

bool MeshRefinement::make_coarsening_compatible (const boolmaintain_level_one) [private]Take user-specified coarsening flags and augment them so that level-one dependency is satisfied.

Definition at line 840 of file mesh_refinement.C.

References _face_level_mismatch_limit, _mesh, Elem::active(), MeshBase::active_elements_begin(), MeshBase::active_elements_end(), Elem::ancestor(), Elem::child(), Elem::COARSEN, Elem::COARSEN_INACTIVE, Elem::DO_NOTHING, MeshBase::elements_begin(), MeshBase::elements_end(), Elem::has_children(), Elem::has_neighbor(), Elem::INACTIVE, MeshBase::is_serial(), Elem::level(), MeshBase::level_elements_begin(), MeshBase::level_elements_end(), std::max(), MeshTools::max_level(), std::min(), Elem::n_children(), Elem::n_neighbors(), Elem::neighbor(), Elem::p_level(), Elem::p_refinement_flag(), libMesh::processor_id(), DofObject::processor_id(), Elem::REFINE, Elem::refinement_flag(), remote_elem, Elem::set_p_refinement_flag(), and Elem::set_refinement_flag().

Referenced by coarsen_elements(), and refine_and_coarsen_elements().

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

  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
      Parallel::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++)
                    if (elem->neighbor(n) != NULL &&      // I have a
                        elem->neighbor(n) != remote_elem) // neighbor here
                      {
                        if (elem->neighbor(n)->active()) // and it is active
                          {
                            const Elem* neighbor = elem->neighbor(n);
                          
                            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++)
                    if (elem->neighbor(n) != NULL &&      // I have a
                        elem->neighbor(n) != remote_elem) // neighbor here
                      {
                        if (elem->neighbor(n)->active()) // and it is active
                          {
                            const Elem* neighbor = elem->neighbor(n);

                            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
                            const Elem* neighbor = elem->neighbor(n);

                             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() &&
                                     subneighbor->has_neighbor(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 = elem->neighbor(n);
                  if (!neigh)
                    continue;
                  if (neigh == remote_elem ||
                      neigh->processor_id() !=
                      libMesh::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() !=
                          libMesh::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
  Parallel::min(compatible_with_refinement);
  
  return compatible_with_refinement;
}
 

bool MeshRefinement::make_flags_parallel_consistent () [private]Copy refinement flags on ghost elements from their local processors. Return true if any flags changed.

Definition at line 810 of file mesh_refinement.C.

References _mesh, MeshBase::elements_begin(), MeshBase::elements_end(), std::min(), Elem::p_refinement_flag(), Elem::refinement_flag(), Elem::set_p_refinement_flag(), Elem::set_refinement_flag(), and 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_only();

  START_LOG ('make_flags_parallel_consistent()', 'MeshRefinement');

  SyncRefinementFlags hsync(_mesh, &Elem::refinement_flag,
                            &Elem::set_refinement_flag);
  Parallel::sync_dofobject_data_by_id
    (_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
    (_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;
  Parallel::min(parallel_consistent);

  STOP_LOG ('make_flags_parallel_consistent()', 'MeshRefinement');

  return parallel_consistent;
}
 

bool MeshRefinement::make_refinement_compatible (const boolmaintain_level_one) [private]Take user-specified refinement flags and augment them so that level-one dependency is satisfied.

Definition at line 1167 of file mesh_refinement.C.

References _face_level_mismatch_limit, _mesh, Elem::active(), MeshBase::active_elements_begin(), MeshBase::active_elements_end(), Elem::child(), Elem::COARSEN, Elem::DO_NOTHING, Elem::has_children(), Elem::has_neighbor(), Elem::INACTIVE, Elem::level(), std::min(), Elem::n_children(), Elem::n_sides(), Elem::neighbor(), Elem::p_level(), Elem::p_refinement_flag(), Elem::parent(), Elem::REFINE, Elem::refinement_flag(), remote_elem, Elem::set_p_refinement_flag(), and Elem::set_refinement_flag().

Referenced by refine_and_coarsen_elements(), and refine_elements().

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

  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 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 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)
    {  
      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 = elem->neighbor(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            
                        
                        // Sanity check. We should never get into a
                        // case when our neighbot is more than one
                        // level away.                   
                        else if ((neighbor->level()+1) < my_level)
                          {
                            libmesh_error();
                          }
                        
                        
                        // 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();
                          }
#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 = elem->neighbor(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() &&
                                    subneighbor->has_neighbor(elem))
                                  {
                                    if (subneighbor->p_level() < my_p_level &&
                                        subneighbor->p_refinement_flag() != Elem::REFINE)
                                      {
                                        // We should already be level one
                                        // compatible
                                        libmesh_assert(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
  Parallel::min(compatible_with_coarsening);
  
  STOP_LOG ('make_refinement_compatible()', 'MeshRefinement');

  return compatible_with_coarsening;
}
 

unsigned int & 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 649 of file mesh_refinement.h.

References _max_h_level, and _use_member_parameters.

{
  _use_member_parameters = true;
  return _max_h_level;
}
 

unsigned int & MeshRefinement::nelem_target () [inline]If nelem_target is set to a nonzero value, methods like flag_elements_by_nelem_target() will attempt to keep the number of active elements in the mesh close to nelem_target.

nelem_target is 0 by default.

Definition at line 661 of file mesh_refinement.h.

References _nelem_target, and _use_member_parameters.

{
  _use_member_parameters = true;
  return _nelem_target;
}
 

unsigned char & MeshRefinement::node_level_mismatch_limit () [inline]If node_level_mismatch_limit is set to a nonzero value, then refinement and coarsening will produce meshes in which the refinement level of two nodal neighbors will not differ by more than that limit. If node_level_mismatch_limit is 0, then level differences will be unlimited.

node_level_mismatch_limit is 0 by default.

Definition at line 683 of file mesh_refinement.h.

References _node_level_mismatch_limit.

{
  return _node_level_mismatch_limit;
}
 

MeshRefinement& MeshRefinement::operator= (const MeshRefinement &) [private]

 

bool MeshRefinement::refine_and_coarsen_elements (const boolmaintain_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 370 of file mesh_refinement.C.

References _coarsen_elements(), _edge_level_mismatch_limit, _face_level_mismatch_limit, _mesh, _node_level_mismatch_limit, _refine_elements(), Elem::active(), Elem::DO_NOTHING, MeshBase::elements_begin(), MeshBase::elements_end(), eliminate_unrefined_patches(), Elem::INACTIVE, MeshBase::is_serial(), Elem::JUST_REFINED, ParallelMesh::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(), std::max(), std::min(), MeshBase::prepare_for_use(), Elem::refinement_flag(), Elem::set_p_refinement_flag(), Elem::set_refinement_flag(), test_level_one(), and test_unflagged().

Referenced by Adaptive< T >::solve().

{
  // This function must be run on all processors at once
  parallel_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
  if (!_mesh.is_serial())
    this->make_flags_parallel_consistent();

  // 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;
          Parallel::max(max_satisfied);
          Parallel::min(min_satisfied);
          libmesh_assert (satisfied == max_satisfied);
          libmesh_assert (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 ();

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

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

  // Finally, the new mesh needs to be prepared for use
  if (coarsening_changed_mesh || refining_changed_mesh)
    {
#ifdef DEBUG
      ParallelMesh *pmesh = dynamic_cast<ParallelMesh *>(&_mesh);
      if (pmesh)
        pmesh->libmesh_assert_valid_parallel_ids();
#endif
      _mesh.prepare_for_use ();
      
      return true;
    }

  // 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 MeshRefinement::refine_elements (const boolmaintain_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 628 of file mesh_refinement.C.

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

Referenced by EquationSystems::reinit().

{
  // This function must be run on all processors at once
  parallel_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
  if (!_mesh.is_serial())
    this->make_flags_parallel_consistent();

  // 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;
          Parallel::max(max_satisfied);
          Parallel::min(min_satisfied);
          libmesh_assert (satisfied == max_satisfied);
          libmesh_assert (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 ();

  return mesh_changed;
}
 

Real & MeshRefinement::refine_fraction () [inline]The refine_fraction sets either a desired target or a desired maximum number of elements to flag for refinement, depending on which flag_elements_by method is called.

refine_fraction must be in $ [0,1] $, and is 0.3 by default.

Definition at line 637 of file mesh_refinement.h.

References _refine_fraction, and _use_member_parameters.

{
  _use_member_parameters = true;
  return _refine_fraction;
}
 

void MeshRefinement::switch_h_to_p_refinement ()Takes a mesh whose elements are flagged for h refinement and coarsening, and switches those flags to request p refinement and coarsening instead.

Definition at line 622 of file mesh_refinement_flagging.C.

References _mesh, Elem::DO_NOTHING, MeshBase::elements_begin(), MeshBase::elements_end(), and 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 MeshRefinement::test_level_one (boollibmesh_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 281 of file mesh_refinement.C.

References _mesh, Elem::active(), MeshBase::active_local_elements_begin(), MeshBase::active_local_elements_end(), Elem::level(), std::max(), Elem::n_neighbors(), Elem::neighbor(), Elem::p_level(), and remote_elem.

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

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

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

  bool failure = false;

  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 = elem->neighbor(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;
              break;
            }
        }
    }

  // If any processor failed, we failed globally
  Parallel::max(failure);

  if (failure)
    {
      // We didn't pass the level one test, so libmesh_assert that 
      // we're allowed not to
      libmesh_assert(!libmesh_assert_pass);
      return false;
    }
  return true;
}
 

bool MeshRefinement::test_unflagged (boollibmesh_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 329 of file mesh_refinement.C.

References _mesh, MeshBase::active_local_elements_begin(), MeshBase::active_local_elements_end(), Elem::COARSEN, std::max(), Elem::p_refinement_flag(), Elem::REFINE, and Elem::refinement_flag().

Referenced by refine_and_coarsen_elements().

{
  // This function must be run on all processors at once
  parallel_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();

  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;
          break;
        }
    }

  // If we found a flag on any processor, it counts
  Parallel::max(found_flag);

  if (found_flag)
    {
      // 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;
}
 

void MeshRefinement::uniformly_coarsen (unsigned intn = 1)Attempts to uniformly coarsen the mesh n times.

Definition at line 1624 of file mesh_refinement.C.

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

Referenced by UniformRefinementEstimator::_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 needs to be prepared for use
  _mesh.prepare_for_use ();
}
 

void MeshRefinement::uniformly_p_coarsen (unsigned intn = 1)Attempts to uniformly p coarsen the mesh n times.

Definition at line 1575 of file mesh_refinement.C.

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

Referenced by UniformRefinementEstimator::_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 MeshRefinement::uniformly_p_refine (unsigned intn = 1)Uniformly p refines the mesh n times.

Definition at line 1556 of file mesh_refinement.C.

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

Referenced by UniformRefinementEstimator::_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 MeshRefinement::uniformly_refine (unsigned intn = 1)Uniformly refines the mesh n times.

Definition at line 1597 of file mesh_refinement.C.

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

Referenced by UniformRefinementEstimator::_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 needs to be prepared for use
  _mesh.prepare_for_use ();
}
 

void MeshRefinement::update_nodes_map () [private]Updates the _new_nodes_map

Definition at line 274 of file mesh_refinement.C.

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

Referenced by _coarsen_elements(), and _refine_elements().

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

Member Data Documentation

 

Real MeshRefinement::_absolute_global_tolerance [private]

Definition at line 620 of file mesh_refinement.h.

Referenced by absolute_global_tolerance(), and flag_elements_by_error_tolerance().  

bool MeshRefinement::_coarsen_by_parents [private]Refinement parameter values

Definition at line 608 of file mesh_refinement.h.

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

Real MeshRefinement::_coarsen_fraction [private]

Definition at line 612 of file mesh_refinement.h.

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

Real MeshRefinement::_coarsen_threshold [private]

Definition at line 616 of file mesh_refinement.h.

Referenced by coarsen_threshold(), flag_elements_by_error_tolerance(), and flag_elements_by_nelem_target().  

unsigned char MeshRefinement::_edge_level_mismatch_limit [private]

Definition at line 622 of file mesh_refinement.h.

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

unsigned char MeshRefinement::_face_level_mismatch_limit [private]

Definition at line 622 of file mesh_refinement.h.

Referenced by coarsen_elements(), face_level_mismatch_limit(), make_coarsening_compatible(), make_refinement_compatible(), refine_and_coarsen_elements(), and refine_elements().  

unsigned int MeshRefinement::_max_h_level [private]

Definition at line 614 of file mesh_refinement.h.

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

MeshBase& MeshRefinement::_mesh [private]Reference to the mesh.

Definition at line 595 of file mesh_refinement.h.

Referenced by _coarsen_elements(), _refine_elements(), add_elem(), add_p_to_h_refinement(), add_point(), clean_refinement_flags(), coarsen_elements(), eliminate_unrefined_patches(), flag_elements_by_elem_fraction(), flag_elements_by_error_fraction(), flag_elements_by_error_tolerance(), flag_elements_by_mean_stddev(), flag_elements_by_nelem_target(), get_mesh(), limit_level_mismatch_at_edge(), limit_level_mismatch_at_node(), make_coarsening_compatible(), make_flags_parallel_consistent(), make_refinement_compatible(), refine_and_coarsen_elements(), refine_elements(), switch_h_to_p_refinement(), test_level_one(), test_unflagged(), uniformly_coarsen(), uniformly_p_coarsen(), uniformly_p_refine(), uniformly_refine(), and update_nodes_map().  

unsigned int MeshRefinement::_nelem_target [private]

Definition at line 618 of file mesh_refinement.h.

Referenced by flag_elements_by_nelem_target(), and nelem_target().  

LocationMap<Node> MeshRefinement::_new_nodes_map [private]Data structure that holds the new nodes information.

Definition at line 590 of file mesh_refinement.h.

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

unsigned char MeshRefinement::_node_level_mismatch_limit [private]

Definition at line 622 of file mesh_refinement.h.

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

Real MeshRefinement::_refine_fraction [private]

Definition at line 610 of file mesh_refinement.h.

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

bool MeshRefinement::_use_member_parameters [private]For backwards compatibility, we initialize this as false and then set it to true if the user uses any of the refinement parameter accessor functions

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

 

Author

Generated automatically by Doxygen for libMesh from the source code.


 

Index

NAME
SYNOPSIS
Public Member Functions
Private Member Functions
Private Attributes
Detailed Description
Constructor & Destructor Documentation
MeshRefinement::MeshRefinement (MeshBase &mesh)Constructor.
MeshRefinement::MeshRefinement (const MeshRefinement &) [private]
MeshRefinement::~MeshRefinement ()Destructor. Deletes all the elements that are currently stored.
Member Function Documentation
bool MeshRefinement::_coarsen_elements () [private]Coarsens user-requested elements. Both coarsen_elements and refine_elements used to be in the public interface for the MeshRefinement object. Unfortunately, without proper preparation (make_refinement_compatible, make_coarsening_compatible) at least coarsen_elements() did not work alone. By making them private, we signal to the user that they are not part of the interface.
bool MeshRefinement::_refine_elements () [private]Refines user-requested elements.
Real & MeshRefinement::absolute_global_tolerance () [inline]If absolute_global_tolerance is set to a nonzero value, methods like flag_elements_by_global_tolerance() will attempt to reduce the global error of the mesh (defined as the square root of the sum of the squares of the errors on active elements) to below this tolerance.
Elem * MeshRefinement::add_elem (Elem *elem)Adds the element elem to the mesh.
void MeshRefinement::add_p_to_h_refinement ()Takes a mesh whose elements are flagged for h refinement and coarsening, and adds flags to request p refinement and coarsening of the same elements.
Node * MeshRefinement::add_point (const Point &p, const unsigned intprocessor_id, const Realtol)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.
void MeshRefinement::clean_refinement_flags () [private]Sets the refinement flag to Elem::DO_NOTHING for each element in the mesh.
void MeshRefinement::clear ()Deletes all the data that are currently stored.
bool & MeshRefinement::coarsen_by_parents () [inline]If coarsen_by_parents is true, complete groups of sibling elements (elements with the same parent) will be flagged for coarsening. This should make the coarsening more likely to occur as requested.
bool MeshRefinement::coarsen_elements (const boolmaintain_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.
Real & MeshRefinement::coarsen_fraction () [inline]The coarsen_fraction sets either a desired target or a desired maximum number of elements to flag for coarsening, depending on which flag_elements_by method is called.
Real & MeshRefinement::coarsen_threshold () [inline]The coarsen_threshold provides hysteresis in AMR/C strategies. Refinement of elements with error estimate E will be done even at the expense of coarsening elements whose children's accumulated error does not exceed coarsen_threshold * E.
void 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.
unsigned char & MeshRefinement::edge_level_mismatch_limit () [inline]If edge_level_mismatch_limit is set to a nonzero value, then refinement and coarsening will produce meshes in which the refinement level of two edge neighbors will not differ by more than that limit. If edge_level_mismatch_limit is 0, then level differences will be unlimited.
bool MeshRefinement::eliminate_unrefined_patches () [private]This algorithm selects an element for refinement if all of its neighbors are (or will be) refined. This algorithm will transform this mesh:
unsigned char & MeshRefinement::face_level_mismatch_limit () [inline]If face_level_mismatch_limit is set to a nonzero value, then refinement and coarsening will produce meshes in which the refinement level of two face neighbors will not differ by more than that limit. If face_level_mismatch_limit is 0, then level differences will be unlimited.
void MeshRefinement::flag_elements_by_elem_fraction (const ErrorVector &error_per_cell, const Realrefine_fraction = 0.3, const Realcoarsen_fraction = 0.0, const unsigned intmax_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] $.
void MeshRefinement::flag_elements_by_error_fraction (const ErrorVector &error_per_cell, const Realrefine_fraction = 0.3, const Realcoarsen_fraction = 0.0, const unsigned intmax_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] $.
void MeshRefinement::flag_elements_by_error_tolerance (const ErrorVector &error_per_cell)Flags elements for coarsening and refinement based on the computed error passed in error_per_cell. This method refines the worst elements with errors greater than absolute_global_tolerance / n_active_elem, flagging at most refine_fraction * n_active_elem It coarsens elements with errors less than coarsen_threshold * global_tolerance / n_active_elem, flagging at most coarsen_fraction * n_active_elem
void MeshRefinement::flag_elements_by_mean_stddev (const ErrorVector &error_per_cell, const Realrefine_fraction = 1.0, const Realcoarsen_fraction = 0.0, const unsigned intmax_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] $.
bool MeshRefinement::flag_elements_by_nelem_target (const ErrorVector &error_per_cell)Flags elements for coarsening and refinement based on the computed error passed in error_per_cell. This method attempts to produce a mesh with slightly more than nelem_target active elements, trading element refinement for element coarsening when their error ratios exceed coarsen_threshold. It flags no more than refine_fraction * n_elem elements for refinement and flags no more than coarsen_fraction * n_elem elements for coarsening. 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.
const MeshBase& MeshRefinement::get_mesh () const [inline]Returns:
MeshBase& MeshRefinement::get_mesh () [inline]Returns:
bool MeshRefinement::limit_level_mismatch_at_edge (const unsigned intmax_mismatch) [private]
bool MeshRefinement::limit_level_mismatch_at_node (const unsigned intmax_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:
bool MeshRefinement::make_coarsening_compatible (const boolmaintain_level_one) [private]Take user-specified coarsening flags and augment them so that level-one dependency is satisfied.
bool MeshRefinement::make_flags_parallel_consistent () [private]Copy refinement flags on ghost elements from their local processors. Return true if any flags changed.
bool MeshRefinement::make_refinement_compatible (const boolmaintain_level_one) [private]Take user-specified refinement flags and augment them so that level-one dependency is satisfied.
unsigned int & MeshRefinement::max_h_level () [inline]The max_h_level is the greatest refinement level an element should reach.
unsigned int & MeshRefinement::nelem_target () [inline]If nelem_target is set to a nonzero value, methods like flag_elements_by_nelem_target() will attempt to keep the number of active elements in the mesh close to nelem_target.
unsigned char & MeshRefinement::node_level_mismatch_limit () [inline]If node_level_mismatch_limit is set to a nonzero value, then refinement and coarsening will produce meshes in which the refinement level of two nodal neighbors will not differ by more than that limit. If node_level_mismatch_limit is 0, then level differences will be unlimited.
MeshRefinement& MeshRefinement::operator= (const MeshRefinement &) [private]
bool MeshRefinement::refine_and_coarsen_elements (const boolmaintain_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.
bool MeshRefinement::refine_elements (const boolmaintain_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.
Real & MeshRefinement::refine_fraction () [inline]The refine_fraction sets either a desired target or a desired maximum number of elements to flag for refinement, depending on which flag_elements_by method is called.
void MeshRefinement::switch_h_to_p_refinement ()Takes a mesh whose elements are flagged for h refinement and coarsening, and switches those flags to request p refinement and coarsening instead.
bool MeshRefinement::test_level_one (boollibmesh_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
bool MeshRefinement::test_unflagged (boollibmesh_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
void MeshRefinement::uniformly_coarsen (unsigned intn = 1)Attempts to uniformly coarsen the mesh n times.
void MeshRefinement::uniformly_p_coarsen (unsigned intn = 1)Attempts to uniformly p coarsen the mesh n times.
void MeshRefinement::uniformly_p_refine (unsigned intn = 1)Uniformly p refines the mesh n times.
void MeshRefinement::uniformly_refine (unsigned intn = 1)Uniformly refines the mesh n times.
void MeshRefinement::update_nodes_map () [private]Updates the _new_nodes_map
Member Data Documentation
Real MeshRefinement::_absolute_global_tolerance [private]
bool MeshRefinement::_coarsen_by_parents [private]Refinement parameter values
Real MeshRefinement::_coarsen_fraction [private]
Real MeshRefinement::_coarsen_threshold [private]
unsigned char MeshRefinement::_edge_level_mismatch_limit [private]
unsigned char MeshRefinement::_face_level_mismatch_limit [private]
unsigned int MeshRefinement::_max_h_level [private]
MeshBase& MeshRefinement::_mesh [private]Reference to the mesh.
unsigned int MeshRefinement::_nelem_target [private]
LocationMap<Node> MeshRefinement::_new_nodes_map [private]Data structure that holds the new nodes information.
unsigned char MeshRefinement::_node_level_mismatch_limit [private]
Real MeshRefinement::_refine_fraction [private]
bool MeshRefinement::_use_member_parameters [private]For backwards compatibility, we initialize this as false and then set it to true if the user uses any of the refinement parameter accessor functions
Author

This document was created by man2html, using the manual pages.
Time: 21:50:11 GMT, April 16, 2011