$extrastylesheet
#include <mesh_refinement.h>

This is the MeshRefinement class. This class implements adaptive mesh refinement algorithms for a MeshBase.
Definition at line 62 of file mesh_refinement.h.
enum libMesh::MeshRefinement::NeighborType [private] |
This helper function enforces the desired mismatch limits prior to refinement. It is called from the MeshRefinement::limit_level_mismatch_at_edge() and MeshRefinement::limit_level_mismatch_at_node() functions. Returns true if this enforcement caused the refinement flags for elem to change, false otherwise.
Definition at line 774 of file mesh_refinement.h.
| libMesh::MeshRefinement::MeshRefinement | ( | MeshBase & | mesh | ) | [explicit] |
Constructor.
Definition at line 55 of file mesh_refinement.C.
: ParallelObject(m), _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), _enforce_mismatch_limit_prior_to_refinement(false) #ifdef LIBMESH_ENABLE_PERIODIC , _periodic_boundaries(NULL) #endif { }
| libMesh::MeshRefinement::MeshRefinement | ( | const MeshRefinement & | ) | [private] |
Destructor. Deletes all the elements that are currently stored.
Definition at line 87 of file mesh_refinement.C.
References clear().
{
this->clear();
}
| bool libMesh::MeshRefinement::_coarsen_elements | ( | ) | [private] |
Coarsens user-requested elements. Both coarsen_elements and refine_elements used to be in the public interface for the MeshRefinement object. Unfortunately, without proper preparation (make_refinement_compatible, make_coarsening_compatible) at least coarsen_elements() did not work alone. By making them private, we signal to the user that they are not part of the interface.
It is possible that for a given set of refinement flags there is actually no change upon calling this member function. Consequently, this function returns true if the mesh actually changed (hence data needs to be projected) and false otherwise.
Definition at line 1501 of file mesh_refinement.C.
References _mesh, libMesh::Elem::active(), clear(), libMesh::Elem::COARSEN, libMesh::Elem::coarsen(), libMesh::Elem::COARSEN_INACTIVE, libMesh::ParallelObject::comm(), libMesh::Elem::DO_NOTHING, libMesh::MeshBase::elements_begin(), libMesh::MeshBase::elements_end(), end, libMesh::MeshBase::get_boundary_info(), libMesh::MeshBase::is_serial(), libMesh::Elem::JUST_COARSENED, libMesh::Elem::level(), libMesh::libmesh_assert(), libMesh::MeshTools::libmesh_assert_valid_procids< Node >(), libMesh::MeshCommunication::make_nodes_parallel_consistent(), libMesh::Parallel::Communicator::max(), libMesh::Elem::nullify_neighbors(), libMesh::Elem::p_level(), libMesh::Elem::p_refinement_flag(), libMesh::Elem::refinement_flag(), libMesh::BoundaryInfo::remove(), libMesh::Elem::set_p_level(), libMesh::Elem::set_p_refinement_flag(), libMesh::START_LOG(), update_nodes_map(), and libMesh::MeshBase::update_parallel_id_counts().
Referenced by coarsen_elements(), refine_and_coarsen_elements(), and uniformly_coarsen().
{
// This function must be run on all processors at once
parallel_object_only();
START_LOG ("_coarsen_elements()", "MeshRefinement");
// Flag indicating if this call actually changes the mesh
bool mesh_changed = false;
// Clear the unused_elements data structure.
// The elements have been packed since it was built,
// so there are _no_ unused elements. We cannot trust
// any iterators currently in this data structure.
// _unused_elements.clear();
MeshBase::element_iterator it = _mesh.elements_begin();
const MeshBase::element_iterator end = _mesh.elements_end();
// Loop over the elements.
for ( ; it != end; ++it)
{
Elem* elem = *it;
// Not necessary when using elem_iterator
// libmesh_assert(elem);
// active elements flagged for coarsening will
// no longer be deleted until MeshRefinement::contract()
if (elem->refinement_flag() == Elem::COARSEN)
{
// Huh? no level-0 element should be active
// and flagged for coarsening.
libmesh_assert_not_equal_to (elem->level(), 0);
// Remove this element from any neighbor
// lists that point to it.
elem->nullify_neighbors();
// Remove any boundary information associated
// with this element
_mesh.get_boundary_info().remove (elem);
// Add this iterator to the _unused_elements
// data structure so we might fill it.
// The _unused_elements optimization is currently off.
// _unused_elements.push_back (it);
// Don't delete the element until
// MeshRefinement::contract()
// _mesh.delete_elem(elem);
// the mesh has certainly changed
mesh_changed = true;
}
// inactive elements flagged for coarsening
// will become active
else if (elem->refinement_flag() == Elem::COARSEN_INACTIVE)
{
elem->coarsen();
libmesh_assert (elem->active());
// the mesh has certainly changed
mesh_changed = true;
}
if (elem->p_refinement_flag() == Elem::COARSEN)
{
if (elem->p_level() > 0)
{
elem->set_p_refinement_flag(Elem::JUST_COARSENED);
elem->set_p_level(elem->p_level() - 1);
mesh_changed = true;
}
else
{
elem->set_p_refinement_flag(Elem::DO_NOTHING);
}
}
}
// If the mesh changed on any processor, it changed globally
this->comm().max(mesh_changed);
// And we may need to update ParallelMesh values reflecting the changes
if (mesh_changed)
_mesh.update_parallel_id_counts();
// Node processor ids may need to change if an element of that id
// was coarsened away
if (mesh_changed && !_mesh.is_serial())
{
// Update the _new_nodes_map so that processors can
// find requested nodes
this->update_nodes_map ();
MeshCommunication().make_nodes_parallel_consistent (_mesh);
// Clear the _new_nodes_map
this->clear();
#ifdef DEBUG
MeshTools::libmesh_assert_valid_procids<Node>(_mesh);
#endif
}
STOP_LOG ("_coarsen_elements()", "MeshRefinement");
return mesh_changed;
}
| bool libMesh::MeshRefinement::_refine_elements | ( | ) | [private] |
Refines user-requested elements.
It is possible that for a given set of refinement flags there is actually no change upon calling this member function. Consequently, this function returns true if the mesh actually changed (hence data needs to be projected) and false otherwise.
Definition at line 1613 of file mesh_refinement.C.
References _mesh, libMesh::Elem::active(), clear(), libMesh::ParallelObject::comm(), libMesh::MeshBase::elements_begin(), libMesh::MeshBase::elements_end(), end, libMesh::MeshBase::is_serial(), libMesh::Elem::JUST_REFINED, libMesh::MeshBase::libmesh_assert_valid_parallel_ids(), libMesh::MeshCommunication::make_elems_parallel_consistent(), libMesh::MeshCommunication::make_nodes_parallel_consistent(), libMesh::Parallel::Communicator::max(), libMesh::Elem::p_level(), libMesh::Elem::p_refinement_flag(), libMesh::Elem::REFINE, libMesh::Elem::refinement_flag(), libMesh::Elem::set_p_level(), libMesh::Elem::set_p_refinement_flag(), libMesh::START_LOG(), update_nodes_map(), and libMesh::MeshBase::update_parallel_id_counts().
Referenced by refine_and_coarsen_elements(), refine_elements(), and uniformly_refine().
{
// This function must be run on all processors at once
parallel_object_only();
// Update the _new_nodes_map so that elements can
// find nodes to connect to.
this->update_nodes_map ();
START_LOG ("_refine_elements()", "MeshRefinement");
// Iterate over the elements, counting the elements
// flagged for h refinement.
dof_id_type n_elems_flagged = 0;
MeshBase::element_iterator it = _mesh.elements_begin();
const MeshBase::element_iterator end = _mesh.elements_end();
for (; it != end; ++it)
{
Elem* elem = *it;
if (elem->refinement_flag() == Elem::REFINE)
n_elems_flagged++;
}
// Construct a local vector of Elem* which have been
// previously marked for refinement. We reserve enough
// space to allow for every element to be refined.
std::vector<Elem*> local_copy_of_elements;
local_copy_of_elements.reserve(n_elems_flagged);
// Iterate over the elements, looking for elements
// flagged for refinement.
for (it = _mesh.elements_begin(); it != end; ++it)
{
Elem* elem = *it;
if (elem->refinement_flag() == Elem::REFINE)
local_copy_of_elements.push_back(elem);
if (elem->p_refinement_flag() == Elem::REFINE &&
elem->active())
{
elem->set_p_level(elem->p_level()+1);
elem->set_p_refinement_flag(Elem::JUST_REFINED);
}
}
// Now iterate over the local copies and refine each one.
// This may resize the mesh's internal container and invalidate
// any existing iterators.
for (std::size_t e = 0; e != local_copy_of_elements.size(); ++e)
local_copy_of_elements[e]->refine(*this);
// The mesh changed if there were elements h refined
bool mesh_changed = !local_copy_of_elements.empty();
// If the mesh changed on any processor, it changed globally
this->comm().max(mesh_changed);
// And we may need to update ParallelMesh values reflecting the changes
if (mesh_changed)
_mesh.update_parallel_id_counts();
if (mesh_changed && !_mesh.is_serial())
{
MeshCommunication().make_elems_parallel_consistent (_mesh);
MeshCommunication().make_nodes_parallel_consistent (_mesh);
#ifdef DEBUG
_mesh.libmesh_assert_valid_parallel_ids();
#endif
}
// Clear the _new_nodes_map and _unused_elements data structures.
this->clear();
STOP_LOG ("_refine_elements()", "MeshRefinement");
return mesh_changed;
}
| Real & libMesh::MeshRefinement::absolute_global_tolerance | ( | ) | [inline] |
If absolute_global_tolerance is set to a nonzero value, methods like flag_elements_by_global_tolerance() will attempt to reduce the global error of the mesh (defined as the square root of the sum of the squares of the errors on active elements) to below this tolerance.
absolute_global_tolerance is 0 by default.
Definition at line 825 of file mesh_refinement.h.
References _absolute_global_tolerance, and _use_member_parameters.
{
_use_member_parameters = true;
return _absolute_global_tolerance;
}
| Elem * libMesh::MeshRefinement::add_elem | ( | Elem * | elem | ) |
Adds the element elem to the mesh.
Definition at line 131 of file mesh_refinement.C.
References _mesh, libMesh::MeshBase::add_elem(), and libMesh::libmesh_assert().
Referenced by libMesh::Elem::refine().
{
libmesh_assert(elem);
// // If the unused_elements has any iterators from
// // old elements, take the first one
// if (!_unused_elements.empty())
// {
// std::vector<Elem*>::iterator it = _unused_elements.front();
// *it = elem;
// _unused_elements.pop_front();
// }
// // Otherwise, use the conventional add method
// else
// {
// _mesh.add_elem (elem);
// }
// The _unused_elements optimization has been turned off.
_mesh.add_elem (elem);
return elem;
}
Takes a mesh whose elements are flagged for h refinement and coarsening, and adds flags to request p refinement and coarsening of the same elements.
Definition at line 684 of file mesh_refinement_flagging.C.
References _mesh, libMesh::MeshBase::elements_begin(), and libMesh::MeshBase::elements_end().
{
MeshBase::element_iterator elem_it = _mesh.elements_begin();
const MeshBase::element_iterator elem_end = _mesh.elements_end();
for ( ; elem_it != elem_end; ++elem_it)
(*elem_it)->set_p_refinement_flag((*elem_it)->refinement_flag());
}
| Node * libMesh::MeshRefinement::add_point | ( | const Point & | p, |
| const processor_id_type | proc_id, | ||
| const Real | tol | ||
| ) |
Add point p to the mesh. The function returns a pointer to the new node. The processor_id is assigned to the new node (only if no existing node is found. The tolerance tol tells the method how far away from p to search for existing nodes.
Definition at line 101 of file mesh_refinement.C.
References _mesh, _new_nodes_map, libMesh::MeshBase::add_point(), libMesh::LocationMap< T >::find(), libMesh::LocationMap< T >::insert(), libMesh::DofObject::invalid_id, libMesh::libmesh_assert(), and libMesh::START_LOG().
Referenced by libMesh::Elem::refine().
{
START_LOG("add_point()", "MeshRefinement");
// Return the node if it already exists
Node *node = _new_nodes_map.find(p, tol);
if (node)
{
STOP_LOG("add_point()", "MeshRefinement");
return node;
}
// Add the node, with a default id and the requested
// processor_id
node = _mesh.add_point (p, DofObject::invalid_id, proc_id);
libmesh_assert(node);
// Add the node to the map.
_new_nodes_map.insert(*node);
// Return the address of the new node
STOP_LOG("add_point()", "MeshRefinement");
return node;
}
Sets the refinement flag to Elem::DO_NOTHING for each element in the mesh.
Definition at line 695 of file mesh_refinement_flagging.C.
References _mesh, libMesh::Elem::DO_NOTHING, libMesh::MeshBase::elements_begin(), libMesh::MeshBase::elements_end(), and libMesh::Elem::INACTIVE.
Referenced by flag_elements_by_elem_fraction(), flag_elements_by_error_fraction(), flag_elements_by_nelem_target(), libMesh::EquationSystems::init(), libMesh::EquationSystems::read(), uniformly_coarsen(), and uniformly_refine().
{
// Possibly clean up the refinement flags from
// a previous step
// elem_iterator elem_it (_mesh.elements_begin());
// const elem_iterator elem_end(_mesh.elements_end());
MeshBase::element_iterator elem_it = _mesh.elements_begin();
const MeshBase::element_iterator elem_end = _mesh.elements_end();
for ( ; elem_it != elem_end; ++elem_it)
{
if ((*elem_it)->active())
{
(*elem_it)->set_refinement_flag(Elem::DO_NOTHING);
(*elem_it)->set_p_refinement_flag(Elem::DO_NOTHING);
}
else
{
(*elem_it)->set_refinement_flag(Elem::INACTIVE);
(*elem_it)->set_p_refinement_flag(Elem::INACTIVE);
}
}
}
| void libMesh::MeshRefinement::clear | ( | ) |
Deletes all the data that are currently stored.
Definition at line 94 of file mesh_refinement.C.
References _new_nodes_map, and libMesh::LocationMap< T >::clear().
Referenced by _coarsen_elements(), _refine_elements(), and ~MeshRefinement().
{
_new_nodes_map.clear();
}
| bool & libMesh::MeshRefinement::coarsen_by_parents | ( | ) | [inline] |
If coarsen_by_parents is true, complete groups of sibling elements (elements with the same parent) will be flagged for coarsening. This should make the coarsening more likely to occur as requested.
coarsen_by_parents is true by default.
Definition at line 789 of file mesh_refinement.h.
References _coarsen_by_parents, and _use_member_parameters.
{
_use_member_parameters = true;
return _coarsen_by_parents;
}
| bool libMesh::MeshRefinement::coarsen_elements | ( | const bool | maintain_level_one = true | ) |
Only coarsens the user-requested elements. Some elements will not be coarsened to satisfy the level one rule. It is possible that for a given set of refinement flags there is actually no change upon calling this member function. Consequently, this function returns true if the mesh actually changed (hence data needs to be projected) and false otherwise.
The argument maintain_level_one is now deprecated; use the option face_level_mismatch_limit() instead.
Definition at line 612 of file mesh_refinement.C.
References _coarsen_elements(), _edge_level_mismatch_limit, _face_level_mismatch_limit, _mesh, _node_level_mismatch_limit, libMesh::Elem::active(), libMesh::ParallelObject::comm(), libMesh::Elem::DO_NOTHING, libMesh::MeshBase::elements_begin(), libMesh::MeshBase::elements_end(), eliminate_unrefined_patches(), libMesh::Elem::INACTIVE, libMesh::MeshBase::is_serial(), libMesh::Elem::JUST_REFINED, libMesh::libmesh_assert(), limit_level_mismatch_at_edge(), limit_level_mismatch_at_node(), make_coarsening_compatible(), make_flags_parallel_consistent(), libMesh::Parallel::Communicator::max(), libMesh::Parallel::Communicator::min(), libMesh::out, libMesh::MeshBase::prepare_for_use(), libMesh::Elem::refinement_flag(), libMesh::Elem::set_p_refinement_flag(), libMesh::Elem::set_refinement_flag(), and test_level_one().
Referenced by libMesh::EquationSystems::reinit().
{
// This function must be run on all processors at once
parallel_object_only();
bool _maintain_level_one = maintain_level_one;
// If the user used non-default parameters, let's warn that they're
// deprecated
if (!maintain_level_one)
{
libmesh_deprecated();
}
else
_maintain_level_one = _face_level_mismatch_limit;
// We can't yet turn a non-level-one mesh into a level-one mesh
if (_maintain_level_one)
libmesh_assert(test_level_one(true));
// Possibly clean up the refinement flags from
// a previous step
MeshBase::element_iterator elem_it = _mesh.elements_begin();
const MeshBase::element_iterator elem_end = _mesh.elements_end();
for ( ; elem_it != elem_end; ++elem_it)
{
// Pointer to the element
Elem* elem = *elem_it;
// Set refinement flag to INACTIVE if the
// element isn't active
if ( !elem->active())
{
elem->set_refinement_flag(Elem::INACTIVE);
elem->set_p_refinement_flag(Elem::INACTIVE);
}
// This might be left over from the last step
if (elem->refinement_flag() == Elem::JUST_REFINED)
elem->set_refinement_flag(Elem::DO_NOTHING);
}
// Parallel consistency has to come first, or coarsening
// along processor boundaries might occasionally be falsely
// prevented
bool flags_were_consistent = this->make_flags_parallel_consistent();
// In theory, we should be able to remove the above call, which can
// be expensive and should be unnecessary. In practice, doing
// consistent flagging in parallel is hard, it's impossible to
// verify at the library level if it's being done by user code, and
// we don't want to abort large parallel runs in opt mode... but we
// do want to warn that they should be fixed.
libmesh_assert(flags_were_consistent);
if (!flags_were_consistent)
{
libMesh::out << "Refinement flags were not consistent between processors!\n"
<< "Correcting and continuing.";
}
// Repeat until flag changes match on every processor
do
{
// Repeat until the flags form a conforming mesh.
bool satisfied = false;
do
{
const bool coarsening_satisfied =
this->make_coarsening_compatible(maintain_level_one);
bool smoothing_satisfied =
!this->eliminate_unrefined_patches();// &&
if (_edge_level_mismatch_limit)
smoothing_satisfied = smoothing_satisfied &&
!this->limit_level_mismatch_at_edge (_edge_level_mismatch_limit);
if (_node_level_mismatch_limit)
smoothing_satisfied = smoothing_satisfied &&
!this->limit_level_mismatch_at_node (_node_level_mismatch_limit);
satisfied = (coarsening_satisfied &&
smoothing_satisfied);
#ifdef DEBUG
bool max_satisfied = satisfied,
min_satisfied = satisfied;
this->comm().max(max_satisfied);
this->comm().min(min_satisfied);
libmesh_assert_equal_to (satisfied, max_satisfied);
libmesh_assert_equal_to (satisfied, min_satisfied);
#endif
}
while (!satisfied);
}
while (!_mesh.is_serial() && !this->make_flags_parallel_consistent());
// Coarsen the flagged elements.
const bool mesh_changed =
this->_coarsen_elements ();
if (_maintain_level_one)
libmesh_assert(test_level_one(true));
libmesh_assert(this->make_coarsening_compatible(maintain_level_one));
// FIXME: This won't pass unless we add a redundant find_neighbors()
// call or replace find_neighbors() with on-the-fly neighbor updating
// libmesh_assert(!this->eliminate_unrefined_patches());
// We can't contract the mesh ourselves anymore - a System might
// need to restrict old coefficient vectors first
// _mesh.contract();
// Finally, the new mesh may need to be prepared for use
if (mesh_changed)
_mesh.prepare_for_use (/*skip_renumber =*/false);
return mesh_changed;
}
| Real & libMesh::MeshRefinement::coarsen_fraction | ( | ) | [inline] |
The coarsen_fraction sets either a desired target or a desired maximum number of elements to flag for coarsening, depending on which flag_elements_by method is called.
coarsen_fraction must be in
, and is 0 by default.
Definition at line 801 of file mesh_refinement.h.
References _coarsen_fraction, and _use_member_parameters.
{
_use_member_parameters = true;
return _coarsen_fraction;
}
| Real & libMesh::MeshRefinement::coarsen_threshold | ( | ) | [inline] |
The coarsen_threshold provides hysteresis in AMR/C strategies. Refinement of elements with error estimate E will be done even at the expense of coarsening elements whose children's accumulated error does not exceed coarsen_threshold * E.
coarsen_threshold must be in
, and is 0.1 by default.
Definition at line 813 of file mesh_refinement.h.
References _coarsen_threshold, and _use_member_parameters.
{
_use_member_parameters = true;
return _coarsen_threshold;
}
| const Parallel::Communicator& libMesh::ParallelObject::comm | ( | ) | const [inline, inherited] |
Parallel::Communicator object used by this mesh. Definition at line 86 of file parallel_object.h.
References libMesh::ParallelObject::_communicator.
Referenced by libMesh::__libmesh_petsc_diff_solver_monitor(), libMesh::__libmesh_petsc_diff_solver_residual(), libMesh::__libmesh_petsc_snes_residual(), _coarsen_elements(), libMesh::ExactSolution::_compute_error(), libMesh::MetisPartitioner::_do_partition(), libMesh::ParmetisPartitioner::_do_repartition(), libMesh::UniformRefinementEstimator::_estimate_error(), libMesh::SlepcEigenSolver< T >::_petsc_shell_matrix_get_diagonal(), libMesh::PetscLinearSolver< T >::_petsc_shell_matrix_get_diagonal(), libMesh::SlepcEigenSolver< T >::_petsc_shell_matrix_mult(), libMesh::PetscLinearSolver< T >::_petsc_shell_matrix_mult(), libMesh::PetscLinearSolver< T >::_petsc_shell_matrix_mult_add(), libMesh::EquationSystems::_read_impl(), _refine_elements(), libMesh::ImplicitSystem::add_matrix(), libMesh::System::add_vector(), libMesh::UnstructuredMesh::all_second_order(), libMesh::LaplaceMeshSmoother::allgather_graph(), libMesh::FEMSystem::assemble_qoi(), libMesh::MeshCommunication::assign_global_indices(), libMesh::ParmetisPartitioner::assign_partitioning(), libMesh::DofMap::attach_matrix(), libMesh::MeshTools::bounding_box(), libMesh::MeshBase::cache_elem_dims(), libMesh::System::calculate_norm(), coarsen_elements(), libMesh::Nemesis_IO_Helper::compute_num_global_elem_blocks(), libMesh::Nemesis_IO_Helper::compute_num_global_nodesets(), libMesh::Nemesis_IO_Helper::compute_num_global_sidesets(), libMesh::Problem_Interface::computeF(), libMesh::Problem_Interface::computeJacobian(), libMesh::Problem_Interface::computePreconditioner(), libMesh::MeshTools::correct_node_proc_ids(), libMesh::MeshCommunication::delete_remote_elements(), libMesh::DofMap::distribute_dofs(), DMlibMeshFunction(), DMlibMeshSetSystem_libMesh(), eliminate_unrefined_patches(), libMesh::WeightedPatchRecoveryErrorEstimator::estimate_error(), libMesh::PatchRecoveryErrorEstimator::estimate_error(), libMesh::JumpErrorEstimator::estimate_error(), libMesh::AdjointRefinementEstimator::estimate_error(), libMesh::ExactErrorEstimator::estimate_error(), flag_elements_by_elem_fraction(), flag_elements_by_error_fraction(), flag_elements_by_nelem_target(), libMesh::CondensedEigenSystem::get_eigenpair(), libMesh::ImplicitSystem::get_linear_solver(), libMesh::LocationMap< T >::init(), libMesh::TimeSolver::init(), libMesh::SystemSubsetBySubdomain::init(), libMesh::EigenSystem::init_data(), libMesh::EigenSystem::init_matrices(), libMesh::ParmetisPartitioner::initialize(), libMesh::MeshTools::libmesh_assert_valid_dof_ids(), libMesh::ParallelMesh::libmesh_assert_valid_parallel_flags(), libMesh::MeshTools::libmesh_assert_valid_procids< Elem >(), libMesh::MeshTools::libmesh_assert_valid_procids< Node >(), libMesh::MeshTools::libmesh_assert_valid_refinement_flags(), limit_level_mismatch_at_edge(), limit_level_mismatch_at_node(), make_coarsening_compatible(), libMesh::MeshCommunication::make_elems_parallel_consistent(), make_flags_parallel_consistent(), libMesh::MeshCommunication::make_node_ids_parallel_consistent(), libMesh::MeshCommunication::make_node_proc_ids_parallel_consistent(), libMesh::MeshCommunication::make_nodes_parallel_consistent(), make_refinement_compatible(), libMesh::FEMSystem::mesh_position_set(), libMesh::MeshSerializer::MeshSerializer(), libMesh::ParallelMesh::n_active_elem(), libMesh::MeshTools::n_active_levels(), libMesh::BoundaryInfo::n_boundary_conds(), libMesh::BoundaryInfo::n_edge_conds(), libMesh::CondensedEigenSystem::n_global_non_condensed_dofs(), libMesh::MeshTools::n_levels(), libMesh::BoundaryInfo::n_nodeset_conds(), libMesh::MeshTools::n_p_levels(), libMesh::ParallelMesh::parallel_max_elem_id(), libMesh::ParallelMesh::parallel_max_node_id(), libMesh::ParallelMesh::parallel_n_elem(), libMesh::ParallelMesh::parallel_n_nodes(), libMesh::Partitioner::partition(), libMesh::Partitioner::partition_unpartitioned_elements(), libMesh::petsc_auto_fieldsplit(), libMesh::System::point_gradient(), libMesh::System::point_hessian(), libMesh::System::point_value(), libMesh::MeshBase::prepare_for_use(), libMesh::System::project_vector(), libMesh::Nemesis_IO::read(), libMesh::XdrIO::read(), libMesh::System::read_header(), libMesh::System::read_legacy_data(), libMesh::System::read_SCALAR_dofs(), libMesh::XdrIO::read_serialized_bc_names(), libMesh::XdrIO::read_serialized_bcs(), libMesh::System::read_serialized_blocked_dof_objects(), libMesh::XdrIO::read_serialized_connectivity(), libMesh::XdrIO::read_serialized_nodes(), libMesh::XdrIO::read_serialized_nodesets(), libMesh::XdrIO::read_serialized_subdomain_names(), libMesh::System::read_serialized_vector(), libMesh::MeshBase::recalculate_n_partitions(), refine_and_coarsen_elements(), refine_elements(), libMesh::Partitioner::set_node_processor_ids(), libMesh::DofMap::set_nonlocal_dof_objects(), libMesh::LaplaceMeshSmoother::smooth(), libMesh::MeshBase::subdomain_ids(), libMesh::BoundaryInfo::sync(), libMesh::Parallel::sync_element_data_by_parent_id(), libMesh::Parallel::sync_node_data_by_element_id(), test_level_one(), test_unflagged(), libMesh::MeshTools::total_weight(), libMesh::NameBasedIO::write(), libMesh::CheckpointIO::write(), libMesh::XdrIO::write(), libMesh::LegacyXdrIO::write_mesh(), libMesh::System::write_SCALAR_dofs(), libMesh::XdrIO::write_serialized_bcs(), libMesh::System::write_serialized_blocked_dof_objects(), libMesh::XdrIO::write_serialized_connectivity(), libMesh::XdrIO::write_serialized_nodes(), libMesh::XdrIO::write_serialized_nodesets(), and libMesh::DivaIO::write_stream().
{ return _communicator; }
| void libMesh::MeshRefinement::create_parent_error_vector | ( | const ErrorVector & | error_per_cell, |
| ErrorVector & | error_per_parent, | ||
| Real & | parent_error_min, | ||
| Real & | parent_error_max | ||
| ) | [private] |
Calculates the error on all coarsenable parents. error_per_parent[parent_id] stores this error if parent_id corresponds to a coarsenable parent, and stores -1 otherwise.
Definition at line 162 of file mesh_refinement.C.
References libMesh::DofObject::id(), libMesh::libmesh_assert(), std::max(), std::min(), libMesh::Elem::parent(), and libMesh::Parallel::verify().
Referenced by flag_elements_by_elem_fraction(), flag_elements_by_error_fraction(), flag_elements_by_error_tolerance(), and flag_elements_by_nelem_target().
{
// This function must be run on all processors at once
parallel_object_only();
// Make sure the input error vector is valid
#ifdef DEBUG
for (std::size_t i=0; i != error_per_cell.size(); ++i)
{
libmesh_assert_greater_equal (error_per_cell[i], 0);
// isnan() isn't standard C++ yet
#ifdef isnan
libmesh_assert(!isnan(error_per_cell[i]));
#endif
}
// Use a reference to std::vector to avoid confusing
// this->comm().verify
std::vector<ErrorVectorReal> &epc = error_per_parent;
libmesh_assert(this->comm().verify(epc));
#endif // #ifdef DEBUG
// error values on uncoarsenable elements will be left at -1
error_per_parent.clear();
error_per_parent.resize(error_per_cell.size(), 0.0);
{
// Find which elements are uncoarsenable
MeshBase::element_iterator elem_it = _mesh.active_local_elements_begin();
const MeshBase::element_iterator elem_end = _mesh.active_local_elements_end();
for (; elem_it != elem_end; ++elem_it)
{
Elem* elem = *elem_it;
Elem* parent = elem->parent();
// Active elements are uncoarsenable
error_per_parent[elem->id()] = -1.0;
// Grandparents and up are uncoarsenable
while (parent)
{
parent = parent->parent();
if (parent)
{
const dof_id_type parentid = parent->id();
libmesh_assert_less (parentid, error_per_parent.size());
error_per_parent[parentid] = -1.0;
}
}
}
// Sync between processors.
// Use a reference to std::vector to avoid confusing
// this->comm().min
std::vector<ErrorVectorReal> &epp = error_per_parent;
this->comm().min(epp);
}
// The parent's error is defined as the square root of the
// sum of the children's errors squared, so errors that are
// Hilbert norms remain Hilbert norms.
//
// Because the children may be on different processors, we
// calculate local contributions to the parents' errors squared
// first, then sum across processors and take the square roots
// second.
{
MeshBase::element_iterator elem_it = _mesh.active_local_elements_begin();
const MeshBase::element_iterator elem_end = _mesh.active_local_elements_end();
for (; elem_it != elem_end; ++elem_it)
{
Elem* elem = *elem_it;
Elem* parent = elem->parent();
// Calculate each contribution to parent cells
if (parent)
{
const dof_id_type parentid = parent->id();
libmesh_assert_less (parentid, error_per_parent.size());
// If the parent has grandchildren we won't be able to
// coarsen it, so forget it. Otherwise, add this child's
// contribution to the sum of the squared child errors
if (error_per_parent[parentid] != -1.0)
error_per_parent[parentid] += (error_per_cell[elem->id()] *
error_per_cell[elem->id()]);
}
}
}
// Sum the vector across all processors
this->comm().sum(static_cast<std::vector<ErrorVectorReal>&>(error_per_parent));
// Calculate the min and max as we loop
parent_error_min = std::numeric_limits<double>::max();
parent_error_max = 0.;
for (std::size_t i = 0; i != error_per_parent.size(); ++i)
{
// If this element isn't a coarsenable parent with error, we
// have nothing to do. Just flag it as -1 and move on
// Note that this->comm().sum might have left uncoarsenable
// elements with error_per_parent=-n_proc, so reset it to
// error_per_parent=-1
if (error_per_parent[i] < 0.)
{
error_per_parent[i] = -1.;
continue;
}
// The error estimator might have already given us an
// estimate on the coarsenable parent elements; if so then
// we want to retain that estimate
if (error_per_cell[i])
{
error_per_parent[i] = error_per_cell[i];
continue;
}
// if not, then e_parent = sqrt(sum(e_child^2))
else
error_per_parent[i] = std::sqrt(error_per_parent[i]);
parent_error_min = std::min (parent_error_min,
error_per_parent[i]);
parent_error_max = std::max (parent_error_max,
error_per_parent[i]);
}
}
| unsigned char & libMesh::MeshRefinement::edge_level_mismatch_limit | ( | ) | [inline] |
If edge_level_mismatch_limit is set to a nonzero value, then refinement and coarsening will produce meshes in which the refinement level of two edge neighbors will not differ by more than that limit. If edge_level_mismatch_limit is 0, then level differences will be unlimited.
edge_level_mismatch_limit is 0 by default.
Definition at line 836 of file mesh_refinement.h.
References _edge_level_mismatch_limit.
{
return _edge_level_mismatch_limit;
}
| bool libMesh::MeshRefinement::eliminate_unrefined_patches | ( | ) | [private] |
This algorithm selects an element for refinement if all of its neighbors are (or will be) refined. This algorithm will transform this mesh:
* o---o---o---o---o---o---o * | | | | | | | * | | | | | | | * o---o---o---o---o---o---o * | | | | | | | * | | | | | | | * o---o---o---o---o---o---o * | | | | | | * | | | | | | * o---o---o o---o---o * | | | | | | * | | | | | | * o---o---o---o---o---o---o * | | | | | | | * | | | | | | | * o---o---o---o---o---o---o * | | | | | | | * | | | | | | | * o---o---o---o---o---o---o *
into this:
* o---o---o---o---o---o---o * | | | | | | | * | | | | | | | * o---o---o---o---o---o---o * | | | | | | | * | | | | | | | * o---o---o---o---o---o---o * | | | : | | | * | | | : | | | * o---o---o...o...o---o---o * | | | : | | | * | | | : | | | * o---o---o---o---o---o---o * | | | | | | | * | | | | | | | * o---o---o---o---o---o---o * | | | | | | | * | | | | | | | * o---o---o---o---o---o---o *
by refining the indicated element
Definition at line 282 of file mesh_refinement_smoothing.C.
References _mesh, libMesh::Elem::active(), libMesh::MeshBase::active_elements_begin(), libMesh::MeshBase::active_elements_end(), libMesh::Elem::ancestor(), libMesh::Elem::child(), libMesh::Elem::COARSEN, libMesh::Elem::COARSEN_INACTIVE, libMesh::ParallelObject::comm(), libMesh::Elem::DO_NOTHING, libMesh::Elem::INACTIVE, libMesh::Elem::level(), libMesh::libmesh_assert(), libMesh::Parallel::Communicator::max(), libMesh::Elem::min_new_p_level_by_neighbor(), libMesh::Elem::n_children(), libMesh::Elem::n_neighbors(), libMesh::Elem::neighbor(), libMesh::Elem::p_level(), libMesh::Elem::p_refinement_flag(), libMesh::Elem::parent(), libMesh::Elem::REFINE, libMesh::Elem::refinement_flag(), libMesh::remote_elem, libMesh::Elem::set_p_refinement_flag(), and libMesh::Elem::set_refinement_flag().
Referenced by coarsen_elements(), refine_and_coarsen_elements(), and refine_elements().
{
// This function must be run on all processors at once
parallel_object_only();
bool flags_changed = false;
MeshBase::element_iterator elem_it = _mesh.active_elements_begin();
const MeshBase::element_iterator elem_end = _mesh.active_elements_end();
for (; elem_it != elem_end; ++elem_it)
{
Elem* elem = *elem_it;
// First assume that we'll have to flag this element for both h
// and p refinement, then change our minds if we see any
// neighbors that are as coarse or coarser than us.
bool h_flag_me = true,
p_flag_me = true;
// Skip the element if it is already fully flagged for refinement
if (elem->p_refinement_flag() == Elem::REFINE)
p_flag_me = false;
if (elem->refinement_flag() == Elem::REFINE)
{
h_flag_me = false;
if (!p_flag_me)
continue;
}
// Test the parent if that is already flagged for coarsening
else if (elem->refinement_flag() == Elem::COARSEN)
{
libmesh_assert(elem->parent());
elem = elem->parent();
// FIXME - this doesn't seem right - RHS
if (elem->refinement_flag() != Elem::COARSEN_INACTIVE)
continue;
p_flag_me = false;
}
const unsigned int my_level = elem->level();
int my_p_adjustment = 0;
if (elem->p_refinement_flag() == Elem::REFINE)
my_p_adjustment = 1;
else if (elem->p_refinement_flag() == Elem::COARSEN)
{
libmesh_assert_greater (elem->p_level(), 0);
my_p_adjustment = -1;
}
const unsigned int my_new_p_level = elem->p_level() +
my_p_adjustment;
// Check all the element neighbors
for (unsigned int n=0; n<elem->n_neighbors(); n++)
{
const Elem *neighbor = elem->neighbor(n);
// Quit if the element is on a local boundary
if (neighbor == NULL || neighbor == remote_elem)
{
h_flag_me = false;
p_flag_me = false;
break;
}
// if the neighbor will be equally or less refined than
// we are, then we will not become an unrefined island.
// So if we are still considering h refinement:
if (h_flag_me &&
// If our neighbor is already at a lower level,
// it can't end up at a higher level even if it
// is flagged for refinement once
((neighbor->level() < my_level) ||
// If our neighbor is at the same level but isn't
// flagged for refinement, it won't end up at a
// higher level
((neighbor->active()) &&
(neighbor->refinement_flag() != Elem::REFINE)) ||
// If our neighbor is currently more refined but is
// a parent flagged for coarsening, it will end up
// at the same level.
(neighbor->refinement_flag() == Elem::COARSEN_INACTIVE)))
{
// We've proven we won't become an unrefined island,
// so don't h refine to avoid that.
h_flag_me = false;
// If we've also proven we don't need to p refine,
// we don't need to check more neighbors
if (!p_flag_me)
break;
}
if (p_flag_me)
{
// if active neighbors will have a p level
// equal to or lower than ours, then we do not need to p
// refine ourselves.
if (neighbor->active())
{
int p_adjustment = 0;
if (neighbor->p_refinement_flag() == Elem::REFINE)
p_adjustment = 1;
else if (neighbor->p_refinement_flag() == Elem::COARSEN)
{
libmesh_assert_greater (neighbor->p_level(), 0);
p_adjustment = -1;
}
if (my_new_p_level >= neighbor->p_level() + p_adjustment)
{
p_flag_me = false;
if (!h_flag_me)
break;
}
}
// If we have inactive neighbors, we need to
// test all their active descendants which neighbor us
else if (neighbor->ancestor())
{
if (neighbor->min_new_p_level_by_neighbor(elem,
my_new_p_level + 2) <= my_new_p_level)
{
p_flag_me = false;
if (!h_flag_me)
break;
}
}
}
}
if (h_flag_me)
{
// Parents that would create islands should no longer
// coarsen
if (elem->refinement_flag() == Elem::COARSEN_INACTIVE)
{
for (unsigned int c=0; c<elem->n_children(); c++)
{
libmesh_assert_equal_to (elem->child(c)->refinement_flag(),
Elem::COARSEN);
elem->child(c)->set_refinement_flag(Elem::DO_NOTHING);
}
elem->set_refinement_flag(Elem::INACTIVE);
}
else
elem->set_refinement_flag(Elem::REFINE);
flags_changed = true;
}
if (p_flag_me)
{
if (elem->p_refinement_flag() == Elem::COARSEN)
elem->set_p_refinement_flag(Elem::DO_NOTHING);
else
elem->set_p_refinement_flag(Elem::REFINE);
flags_changed = true;
}
}
// If flags changed on any processor then they changed globally
this->comm().max(flags_changed);
return flags_changed;
}
| bool & libMesh::MeshRefinement::enforce_mismatch_limit_prior_to_refinement | ( | ) | [inline] |
Get/set the _enforce_mismatch_limit_prior_to_refinement flag. The default value for this flag is false.
Definition at line 858 of file mesh_refinement.h.
References _enforce_mismatch_limit_prior_to_refinement.
Referenced by get_enforce_mismatch_limit_prior_to_refinement(), limit_level_mismatch_at_edge(), limit_level_mismatch_at_node(), and set_enforce_mismatch_limit_prior_to_refinement().
{
return _enforce_mismatch_limit_prior_to_refinement;
}
| bool libMesh::MeshRefinement::enforce_mismatch_limit_prior_to_refinement | ( | Elem * | elem, |
| NeighborType | nt, | ||
| unsigned | max_mismatch | ||
| ) | [private] |
Definition at line 445 of file mesh_refinement_smoothing.C.
References _enforce_mismatch_limit_prior_to_refinement, libMesh::Elem::DO_NOTHING, EDGE, libMesh::Elem::find_edge_neighbors(), libMesh::Elem::find_point_neighbors(), libMesh::Elem::level(), libMesh::Elem::p_level(), POINT, libMesh::Elem::REFINE, libMesh::Elem::refinement_flag(), libMesh::Elem::set_p_refinement_flag(), and libMesh::Elem::set_refinement_flag().
{
// Eventual return value
bool flags_changed = false;
// If we are enforcing the limit prior to refinement then we
// need to remove flags from any elements marked for refinement that
// would cause a mismatch
if (_enforce_mismatch_limit_prior_to_refinement
&& elem->refinement_flag() == Elem::REFINE)
{
// get all the POINT neighbors since we may have to refine
// elements off the corner as well
std::set<const Elem*> neighbor_set;
if (nt == POINT)
elem->find_point_neighbors(neighbor_set);
else if (nt == EDGE)
elem->find_edge_neighbors(neighbor_set);
else
libmesh_error_msg("Unrecognized NeighborType: " << nt);
// Loop over the neighbors of element e
std::set<const Elem*>::iterator n_it = neighbor_set.begin();
for (; n_it != neighbor_set.end(); ++n_it)
{
const Elem* neighbor = *n_it;
if ((elem->level() + 1 - max_mismatch) > neighbor->level())
{
elem->set_refinement_flag(Elem::DO_NOTHING);
flags_changed = true;
}
if ((elem->p_level() + 1 - max_mismatch) > neighbor->p_level())
{
elem->set_p_refinement_flag(Elem::DO_NOTHING);
flags_changed = true;
}
} // loop over edge/point neighbors
} // if _enforce_mismatch_limit_prior_to_refinement
return flags_changed;
}
| unsigned char & libMesh::MeshRefinement::face_level_mismatch_limit | ( | ) | [inline] |
If face_level_mismatch_limit is set to a nonzero value, then refinement and coarsening will produce meshes in which the refinement level of two face neighbors will not differ by more than that limit. If face_level_mismatch_limit is 0, then level differences will be unlimited.
face_level_mismatch_limit is 1 by default. Currently the only supported options are 0 and 1.
Definition at line 831 of file mesh_refinement.h.
References _face_level_mismatch_limit.
Referenced by libMesh::EquationSystems::reinit().
{
return _face_level_mismatch_limit;
}
| void libMesh::MeshRefinement::flag_elements_by | ( | ElementFlagging & | element_flagging | ) |
Flag elements based on a function object. The class ElementFlagging defines a mechanism for implementing refinement strategies.
Definition at line 655 of file mesh_refinement_flagging.C.
References libMesh::MeshRefinement::ElementFlagging::flag_elements().
{
element_flagging.flag_elements();
}
| void libMesh::MeshRefinement::flag_elements_by_elem_fraction | ( | const ErrorVector & | error_per_cell, |
| const Real | refine_fraction = 0.3, |
||
| const Real | coarsen_fraction = 0.0, |
||
| const unsigned int | max_level = libMesh::invalid_uint |
||
| ) |
Flags elements for coarsening and refinement based on the computed error passed in error_per_cell. This method picks the top refine_fraction * n_elem elements for refinement and the bottom coarsen_fraction * n_elem elements for coarsening. The two fractions refine_fraction and coarsen_fraction must be in
.
All the function arguments except error_per_cell have been deprecated, and will be removed in future libMesh releases - to control these parameters, set the corresponding member variables.
Definition at line 452 of file mesh_refinement_flagging.C.
References _coarsen_by_parents, _coarsen_fraction, _max_h_level, _mesh, _refine_fraction, _use_member_parameters, libMesh::MeshBase::active_elements_begin(), libMesh::MeshBase::active_local_elements_begin(), libMesh::MeshBase::active_local_elements_end(), libMesh::Parallel::Communicator::allgather(), clean_refinement_flags(), libMesh::Elem::COARSEN, libMesh::ParallelObject::comm(), create_parent_error_vector(), libMesh::ErrorVectorReal, libMesh::DofObject::id(), libMesh::invalid_uint, libMesh::Elem::level(), libMesh::MeshBase::mesh_dimension(), libMesh::MeshBase::n_elem(), libMesh::Elem::parent(), libMesh::Real, libMesh::Elem::REFINE, and libMesh::Elem::set_refinement_flag().
{
parallel_object_only();
// The function arguments are currently just there for
// backwards_compatibility
if (!_use_member_parameters)
{
// If the user used non-default parameters, lets warn
// that they're deprecated
if (refine_frac != 0.3 ||
coarsen_frac != 0.0 ||
max_l != libMesh::invalid_uint)
libmesh_deprecated();
_refine_fraction = refine_frac;
_coarsen_fraction = coarsen_frac;
_max_h_level = max_l;
}
// Check for valid fractions..
// The fraction values must be in [0,1]
libmesh_assert_greater_equal (_refine_fraction, 0);
libmesh_assert_less_equal (_refine_fraction, 1);
libmesh_assert_greater_equal (_coarsen_fraction, 0);
libmesh_assert_less_equal (_coarsen_fraction, 1);
// The number of active elements in the mesh
const dof_id_type n_active_elem = _mesh.n_elem();
// The number of elements to flag for coarsening
const dof_id_type n_elem_coarsen =
static_cast<dof_id_type>(_coarsen_fraction * n_active_elem);
// The number of elements to flag for refinement
const dof_id_type n_elem_refine =
static_cast<dof_id_type>(_refine_fraction * n_active_elem);
// Clean up the refinement flags. These could be left
// over from previous refinement steps.
this->clean_refinement_flags();
// This vector stores the error and element number for all the
// active elements. It will be sorted and the top & bottom
// elements will then be flagged for coarsening & refinement
std::vector<ErrorVectorReal> sorted_error;
sorted_error.reserve (n_active_elem);
// Loop over the active elements and create the entry
// in the sorted_error vector
MeshBase::element_iterator elem_it = _mesh.active_local_elements_begin();
const MeshBase::element_iterator elem_end = _mesh.active_local_elements_end();
for (; elem_it != elem_end; ++elem_it)
sorted_error.push_back (error_per_cell[(*elem_it)->id()]);
this->comm().allgather(sorted_error);
// Now sort the sorted_error vector
std::sort (sorted_error.begin(), sorted_error.end());
// If we're coarsening by parents:
// Create a sorted error vector with coarsenable parent elements
// only, sorted by lowest errors first
ErrorVector error_per_parent, sorted_parent_error;
if (_coarsen_by_parents)
{
Real parent_error_min, parent_error_max;
create_parent_error_vector(error_per_cell,
error_per_parent,
parent_error_min,
parent_error_max);
sorted_parent_error = error_per_parent;
std::sort (sorted_parent_error.begin(), sorted_parent_error.end());
// All the other error values will be 0., so get rid of them.
sorted_parent_error.erase (std::remove(sorted_parent_error.begin(),
sorted_parent_error.end(), 0.),
sorted_parent_error.end());
}
ErrorVectorReal top_error= 0., bottom_error = 0.;
// Get the maximum error value corresponding to the
// bottom n_elem_coarsen elements
if (_coarsen_by_parents && n_elem_coarsen)
{
const unsigned int dim = _mesh.mesh_dimension();
unsigned int twotodim = 1;
for (unsigned int i=0; i!=dim; ++i)
twotodim *= 2;
dof_id_type n_parent_coarsen = n_elem_coarsen / (twotodim - 1);
if (n_parent_coarsen)
bottom_error = sorted_parent_error[n_parent_coarsen - 1];
}
else if (n_elem_coarsen)
{
bottom_error = sorted_error[n_elem_coarsen - 1];
}
if (n_elem_refine)
top_error = sorted_error[sorted_error.size() - n_elem_refine];
// Finally, let's do the element flagging
elem_it = _mesh.active_elements_begin();
for (; elem_it != elem_end; ++elem_it)
{
Elem* elem = *elem_it;
Elem* parent = elem->parent();
if (_coarsen_by_parents && parent && n_elem_coarsen &&
error_per_parent[parent->id()] <= bottom_error)
elem->set_refinement_flag(Elem::COARSEN);
if (!_coarsen_by_parents && n_elem_coarsen &&
error_per_cell[elem->id()] <= bottom_error)
elem->set_refinement_flag(Elem::COARSEN);
if (n_elem_refine &&
elem->level() < _max_h_level &&
error_per_cell[elem->id()] >= top_error)
elem->set_refinement_flag(Elem::REFINE);
}
}
| void libMesh::MeshRefinement::flag_elements_by_error_fraction | ( | const ErrorVector & | error_per_cell, |
| const Real | refine_fraction = 0.3, |
||
| const Real | coarsen_fraction = 0.0, |
||
| const unsigned int | max_level = libMesh::invalid_uint |
||
| ) |
Flags elements for coarsening and refinement based on the computed error passed in error_per_cell. The two fractions refine_fraction and coarsen_fraction must be in
.
All the function arguments except error_per_cell have been deprecated, and will be removed in future libMesh releases - to control these parameters, set the corresponding member variables.
Definition at line 45 of file mesh_refinement_flagging.C.
References _coarsen_by_parents, _coarsen_fraction, _max_h_level, _mesh, _refine_fraction, _use_member_parameters, libMesh::MeshBase::active_elements_begin(), libMesh::MeshBase::active_elements_end(), libMesh::MeshBase::active_local_elements_begin(), libMesh::MeshBase::active_local_elements_end(), clean_refinement_flags(), libMesh::Elem::COARSEN, libMesh::ParallelObject::comm(), create_parent_error_vector(), libMesh::ErrorVectorReal, libMesh::DofObject::id(), libMesh::invalid_uint, libMesh::Elem::level(), std::max(), libMesh::Parallel::Communicator::max(), std::min(), libMesh::Parallel::Communicator::min(), libMesh::Elem::parent(), libMesh::Real, libMesh::Elem::REFINE, and libMesh::Elem::set_refinement_flag().
{
parallel_object_only();
// The function arguments are currently just there for
// backwards_compatibility
if (!_use_member_parameters)
{
// If the user used non-default parameters, lets warn
// that they're deprecated
if (refine_frac != 0.3 ||
coarsen_frac != 0.0 ||
max_l != libMesh::invalid_uint)
libmesh_deprecated();
_refine_fraction = refine_frac;
_coarsen_fraction = coarsen_frac;
_max_h_level = max_l;
}
// Check for valid fractions..
// The fraction values must be in [0,1]
libmesh_assert_greater_equal (_refine_fraction, 0);
libmesh_assert_less_equal (_refine_fraction, 1);
libmesh_assert_greater_equal (_coarsen_fraction, 0);
libmesh_assert_less_equal (_coarsen_fraction, 1);
// Clean up the refinement flags. These could be left
// over from previous refinement steps.
this->clean_refinement_flags();
// We're getting the minimum and maximum error values
// for the ACTIVE elements
Real error_min = 1.e30;
Real error_max = 0.;
// And, if necessary, for their parents
Real parent_error_min = 1.e30;
Real parent_error_max = 0.;
// Prepare another error vector if we need to sum parent errors
ErrorVector error_per_parent;
if (_coarsen_by_parents)
{
create_parent_error_vector(error_per_cell,
error_per_parent,
parent_error_min,
parent_error_max);
}
// We need to loop over all active elements to find the minimum
MeshBase::element_iterator el_it =
_mesh.active_local_elements_begin();
const MeshBase::element_iterator el_end =
_mesh.active_local_elements_end();
for (; el_it != el_end; ++el_it)
{
const dof_id_type id = (*el_it)->id();
libmesh_assert_less (id, error_per_cell.size());
error_max = std::max (error_max, error_per_cell[id]);
error_min = std::min (error_min, error_per_cell[id]);
}
this->comm().max(error_max);
this->comm().min(error_min);
// Compute the cutoff values for coarsening and refinement
const Real error_delta = (error_max - error_min);
const Real parent_error_delta = parent_error_max - parent_error_min;
const Real refine_cutoff = (1.- _refine_fraction)*error_max;
const Real coarsen_cutoff = _coarsen_fraction*error_delta + error_min;
const Real parent_cutoff = _coarsen_fraction*parent_error_delta + error_min;
// // Print information about the error
// libMesh::out << " Error Information:" << std::endl
// << " ------------------" << std::endl
// << " min: " << error_min << std::endl
// << " max: " << error_max << std::endl
// << " delta: " << error_delta << std::endl
// << " refine_cutoff: " << refine_cutoff << std::endl
// << " coarsen_cutoff: " << coarsen_cutoff << std::endl;
// Loop over the elements and flag them for coarsening or
// refinement based on the element error
MeshBase::element_iterator e_it =
_mesh.active_elements_begin();
const MeshBase::element_iterator e_end =
_mesh.active_elements_end();
for (; e_it != e_end; ++e_it)
{
Elem* elem = *e_it;
const dof_id_type id = elem->id();
libmesh_assert_less (id, error_per_cell.size());
const ErrorVectorReal elem_error = error_per_cell[id];
if (_coarsen_by_parents)
{
Elem* parent = elem->parent();
if (parent)
{
const dof_id_type parentid = parent->id();
if (error_per_parent[parentid] >= 0. &&
error_per_parent[parentid] <= parent_cutoff)
elem->set_refinement_flag(Elem::COARSEN);
}
}
// Flag the element for coarsening if its error
// is <= coarsen_fraction*delta + error_min
else if (elem_error <= coarsen_cutoff)
{
elem->set_refinement_flag(Elem::COARSEN);
}
// Flag the element for refinement if its error
// is >= refinement_cutoff.
if (elem_error >= refine_cutoff)
if (elem->level() < _max_h_level)
elem->set_refinement_flag(Elem::REFINE);
}
}
| void libMesh::MeshRefinement::flag_elements_by_error_tolerance | ( | const ErrorVector & | error_per_cell | ) |
Flags elements for coarsening and refinement based on the computed error passed in error_per_cell. This method refines the worst elements with errors greater than absolute_global_tolerance / n_active_elem, flagging at most refine_fraction * n_active_elem It coarsens elements with errors less than coarsen_threshold * global_tolerance / n_active_elem, flagging at most coarsen_fraction * n_active_elem
The three fractions refine_fraction coarsen_fraction and coarsen_threshold should be in
.
Definition at line 178 of file mesh_refinement_flagging.C.
References _absolute_global_tolerance, _coarsen_by_parents, _coarsen_fraction, _coarsen_threshold, _max_h_level, _mesh, _refine_fraction, libMesh::MeshBase::active_elements_begin(), libMesh::MeshBase::active_elements_end(), libMesh::Elem::COARSEN, create_parent_error_vector(), libMesh::ErrorVectorReal, libMesh::DofObject::id(), libMesh::Elem::level(), libMesh::MeshBase::n_active_elem(), libMesh::Elem::n_children(), libMesh::Elem::parent(), libMesh::Real, libMesh::Elem::REFINE, and libMesh::Elem::set_refinement_flag().
{
parallel_object_only();
libmesh_assert_greater (_coarsen_threshold, 0);
// Check for valid fractions..
// The fraction values must be in [0,1]
libmesh_assert_greater_equal (_refine_fraction, 0);
libmesh_assert_less_equal (_refine_fraction, 1);
libmesh_assert_greater_equal (_coarsen_fraction, 0);
libmesh_assert_less_equal (_coarsen_fraction, 1);
// How much error per cell will we tolerate?
const Real local_refinement_tolerance =
_absolute_global_tolerance / std::sqrt(static_cast<Real>(_mesh.n_active_elem()));
const Real local_coarsening_tolerance =
local_refinement_tolerance * _coarsen_threshold;
// Prepare another error vector if we need to sum parent errors
ErrorVector error_per_parent;
if (_coarsen_by_parents)
{
Real parent_error_min, parent_error_max;
create_parent_error_vector(error_per_cell_in,
error_per_parent,
parent_error_min,
parent_error_max);
}
MeshBase::element_iterator elem_it = _mesh.active_elements_begin();
const MeshBase::element_iterator elem_end = _mesh.active_elements_end();
for (; elem_it != elem_end; ++elem_it)
{
Elem* elem = *elem_it;
Elem* parent = elem->parent();
const dof_id_type elem_number = elem->id();
const ErrorVectorReal elem_error = error_per_cell_in[elem_number];
if (elem_error > local_refinement_tolerance &&
elem->level() < _max_h_level)
elem->set_refinement_flag(Elem::REFINE);
if (!_coarsen_by_parents && elem_error <
local_coarsening_tolerance)
elem->set_refinement_flag(Elem::COARSEN);
if (_coarsen_by_parents && parent)
{
ErrorVectorReal parent_error = error_per_parent[parent->id()];
if (parent_error >= 0.)
{
const Real parent_coarsening_tolerance =
std::sqrt(parent->n_children() *
local_coarsening_tolerance *
local_coarsening_tolerance);
if (parent_error < parent_coarsening_tolerance)
elem->set_refinement_flag(Elem::COARSEN);
}
}
}
}
| void libMesh::MeshRefinement::flag_elements_by_mean_stddev | ( | const ErrorVector & | error_per_cell, |
| const Real | refine_fraction = 1.0, |
||
| const Real | coarsen_fraction = 0.0, |
||
| const unsigned int | max_level = libMesh::invalid_uint |
||
| ) |
Flags elements for coarsening and refinement based on the computed error passed in error_per_cell. This method picks the top refine_fraction * stddev + mean elements for refinement and the bottom mean - coarsen_fraction * stddev elements for coarsening. The two fractions refine_fraction and coarsen_fraction must be in
.
All the function arguments except error_per_cell have been deprecated, and will be removed in future libMesh releases - to control these parameters, set the corresponding member variables.
Definition at line 591 of file mesh_refinement_flagging.C.
References _coarsen_fraction, _max_h_level, _mesh, _refine_fraction, _use_member_parameters, libMesh::MeshBase::active_elements_begin(), libMesh::MeshBase::active_elements_end(), libMesh::Elem::COARSEN, libMesh::ErrorVectorReal, libMesh::DofObject::id(), libMesh::invalid_uint, libMesh::Elem::level(), std::max(), libMesh::ErrorVector::mean(), libMesh::Real, libMesh::Elem::REFINE, libMesh::Elem::set_refinement_flag(), and libMesh::ErrorVector::variance().
{
// The function arguments are currently just there for
// backwards_compatibility
if (!_use_member_parameters)
{
// If the user used non-default parameters, lets warn
// that they're deprecated
if (refine_frac != 0.3 ||
coarsen_frac != 0.0 ||
max_l != libMesh::invalid_uint)
libmesh_deprecated();
_refine_fraction = refine_frac;
_coarsen_fraction = coarsen_frac;
_max_h_level = max_l;
}
// Get the mean value from the error vector
const Real mean = error_per_cell.mean();
// Get the standard deviation. This equals the
// square-root of the variance
const Real stddev = std::sqrt (error_per_cell.variance());
// Check for valid fractions
libmesh_assert_greater_equal (_refine_fraction, 0);
libmesh_assert_less_equal (_refine_fraction, 1);
libmesh_assert_greater_equal (_coarsen_fraction, 0);
libmesh_assert_less_equal (_coarsen_fraction, 1);
// The refine and coarsen cutoff
const Real refine_cutoff = mean + _refine_fraction * stddev;
const Real coarsen_cutoff = std::max(mean - _coarsen_fraction * stddev, 0.);
// Loop over the elements and flag them for coarsening or
// refinement based on the element error
MeshBase::element_iterator elem_it = _mesh.active_elements_begin();
const MeshBase::element_iterator elem_end = _mesh.active_elements_end();
for (; elem_it != elem_end; ++elem_it)
{
Elem* elem = *elem_it;
const dof_id_type id = elem->id();
libmesh_assert_less (id, error_per_cell.size());
const ErrorVectorReal elem_error = error_per_cell[id];
// Possibly flag the element for coarsening ...
if (elem_error <= coarsen_cutoff)
elem->set_refinement_flag(Elem::COARSEN);
// ... or refinement
if ((elem_error >= refine_cutoff) && (elem->level() < _max_h_level))
elem->set_refinement_flag(Elem::REFINE);
}
}
| bool libMesh::MeshRefinement::flag_elements_by_nelem_target | ( | const ErrorVector & | error_per_cell | ) |
Flags elements for coarsening and refinement based on the computed error passed in error_per_cell. This method attempts to produce a mesh with slightly more than nelem_target active elements, trading element refinement for element coarsening when their error ratios exceed coarsen_threshold. It flags no more than refine_fraction * n_elem elements for refinement and flags no more than coarsen_fraction * n_elem elements for coarsening. This method returns true if it has done all the AMR/C it can do in a single step, or false if further adaptive steps may be required to produce a mesh with a narrow error distribution and the right number of elements.
Definition at line 245 of file mesh_refinement_flagging.C.
References _coarsen_by_parents, _coarsen_fraction, _coarsen_threshold, _max_h_level, _mesh, _nelem_target, _refine_fraction, libMesh::Elem::active(), libMesh::MeshBase::active_local_elements_begin(), libMesh::MeshBase::active_local_elements_end(), libMesh::Parallel::Communicator::allgather(), libMesh::Elem::child(), clean_refinement_flags(), libMesh::Elem::COARSEN, libMesh::ParallelObject::comm(), create_parent_error_vector(), libMesh::Elem::has_children(), libMesh::Elem::level(), libMesh::libmesh_assert(), libMesh::Parallel::Communicator::max(), libMesh::MeshBase::max_elem_id(), libMesh::MeshBase::mesh_dimension(), std::min(), libMesh::MeshBase::n_active_elem(), libMesh::Elem::n_children(), libMesh::MeshBase::query_elem(), libMesh::Real, libMesh::Elem::REFINE, libMesh::remote_elem, and libMesh::Elem::set_refinement_flag().
{
parallel_object_only();
// Check for valid fractions..
// The fraction values must be in [0,1]
libmesh_assert_greater_equal (_refine_fraction, 0);
libmesh_assert_less_equal (_refine_fraction, 1);
libmesh_assert_greater_equal (_coarsen_fraction, 0);
libmesh_assert_less_equal (_coarsen_fraction, 1);
// This function is currently only coded to work when coarsening by
// parents - it's too hard to guess how many coarsenings will be
// performed otherwise.
libmesh_assert (_coarsen_by_parents);
// The number of active elements in the mesh - hopefully less than
// 2 billion on 32 bit machines
const dof_id_type n_active_elem = _mesh.n_active_elem();
// The maximum number of active elements to flag for coarsening
const dof_id_type max_elem_coarsen =
static_cast<dof_id_type>(_coarsen_fraction * n_active_elem) + 1;
// The maximum number of elements to flag for refinement
const dof_id_type max_elem_refine =
static_cast<dof_id_type>(_refine_fraction * n_active_elem) + 1;
// Clean up the refinement flags. These could be left
// over from previous refinement steps.
this->clean_refinement_flags();
// The target number of elements to add or remove
const std::ptrdiff_t n_elem_new = _nelem_target - n_active_elem;
// Create an vector with active element errors and ids,
// sorted by highest errors first
const dof_id_type max_elem_id = _mesh.max_elem_id();
std::vector<std::pair<ErrorVectorReal, dof_id_type> > sorted_error;
sorted_error.reserve (n_active_elem);
// On a ParallelMesh, we need to communicate to know which remote ids
// correspond to active elements.
{
std::vector<bool> is_active(max_elem_id, false);
MeshBase::element_iterator elem_it = _mesh.active_local_elements_begin();
const MeshBase::element_iterator elem_end = _mesh.active_local_elements_end();
for (; elem_it != elem_end; ++elem_it)
{
const dof_id_type eid = (*elem_it)->id();
is_active[eid] = true;
libmesh_assert_less (eid, error_per_cell.size());
sorted_error.push_back
(std::make_pair(error_per_cell[eid], eid));
}
this->comm().max(is_active);
this->comm().allgather(sorted_error);
}
// Default sort works since pairs are sorted lexicographically
std::sort (sorted_error.begin(), sorted_error.end());
std::reverse (sorted_error.begin(), sorted_error.end());
// Create a sorted error vector with coarsenable parent elements
// only, sorted by lowest errors first
ErrorVector error_per_parent;
std::vector<std::pair<ErrorVectorReal, dof_id_type> > sorted_parent_error;
Real parent_error_min, parent_error_max;
create_parent_error_vector(error_per_cell,
error_per_parent,
parent_error_min,
parent_error_max);
// create_parent_error_vector sets values for non-parents and
// non-coarsenable parents to -1. Get rid of them.
for (dof_id_type i=0; i != error_per_parent.size(); ++i)
if (error_per_parent[i] != -1)
sorted_parent_error.push_back(std::make_pair(error_per_parent[i], i));
std::sort (sorted_parent_error.begin(), sorted_parent_error.end());
// Keep track of how many elements we plan to coarsen & refine
dof_id_type coarsen_count = 0;
dof_id_type refine_count = 0;
const unsigned int dim = _mesh.mesh_dimension();
unsigned int twotodim = 1;
for (unsigned int i=0; i!=dim; ++i)
twotodim *= 2;
// First, let's try to get our element count to target_nelem
if (n_elem_new >= 0)
{
// Every element refinement creates at least
// 2^dim-1 new elements
refine_count =
std::min(cast_int<dof_id_type>(n_elem_new / (twotodim-1)),
max_elem_refine);
}
else
{
// Every successful element coarsening is likely to destroy
// 2^dim-1 net elements.
coarsen_count =
std::min(cast_int<dof_id_type>(-n_elem_new / (twotodim-1)),
max_elem_coarsen);
}
// Next, let's see if we can trade any refinement for coarsening
while (coarsen_count < max_elem_coarsen &&
refine_count < max_elem_refine &&
coarsen_count < sorted_parent_error.size() &&
refine_count < sorted_error.size() &&
sorted_error[refine_count].first >
sorted_parent_error[coarsen_count].first * _coarsen_threshold)
{
coarsen_count++;
refine_count++;
}
// On a ParallelMesh, we need to communicate to know which remote ids
// correspond to refinable elements
dof_id_type successful_refine_count = 0;
{
std::vector<bool> is_refinable(max_elem_id, false);
for (dof_id_type i=0; i != sorted_error.size(); ++i)
{
dof_id_type eid = sorted_error[i].second;
Elem *elem = _mesh.query_elem(eid);
if (elem && elem->level() < _max_h_level)
is_refinable[eid] = true;
}
this->comm().max(is_refinable);
if (refine_count > max_elem_refine)
refine_count = max_elem_refine;
for (dof_id_type i=0; i != sorted_error.size(); ++i)
{
if (successful_refine_count >= refine_count)
break;
dof_id_type eid = sorted_error[i].second;
Elem *elem = _mesh.query_elem(eid);
if (is_refinable[eid])
{
if (elem)
elem->set_refinement_flag(Elem::REFINE);
successful_refine_count++;
}
}
}
// If we couldn't refine enough elements, don't coarsen too many
// either
if (coarsen_count < (refine_count - successful_refine_count))
coarsen_count = 0;
else
coarsen_count -= (refine_count - successful_refine_count);
if (coarsen_count > max_elem_coarsen)
coarsen_count = max_elem_coarsen;
dof_id_type successful_coarsen_count = 0;
if (coarsen_count)
{
for (dof_id_type i=0; i != sorted_parent_error.size(); ++i)
{
if (successful_coarsen_count >= coarsen_count * twotodim)
break;
dof_id_type parent_id = sorted_parent_error[i].second;
Elem *parent = _mesh.query_elem(parent_id);
// On a ParallelMesh we skip remote elements
if (!parent)
continue;
libmesh_assert(parent->has_children());
for (unsigned int c=0; c != parent->n_children(); ++c)
{
Elem *elem = parent->child(c);
if (elem && elem != remote_elem)
{
libmesh_assert(elem->active());
elem->set_refinement_flag(Elem::COARSEN);
successful_coarsen_count++;
}
}
}
}
// Return true if we've done all the AMR/C we can
if (!successful_coarsen_count &&
!successful_refine_count)
return true;
// And false if there may still be more to do.
return false;
}
| bool libMesh::MeshRefinement::get_enforce_mismatch_limit_prior_to_refinement | ( | ) | [inline] |
Returns the state of the _enforce_mismatch_limit_prior_to_refinement flag. Defaults to false. Deprecated - use enforce_mismatch_limit_prior_to_refinement() instead.
Definition at line 846 of file mesh_refinement.h.
References enforce_mismatch_limit_prior_to_refinement().
{
libmesh_deprecated();
return enforce_mismatch_limit_prior_to_refinement();
}
| const MeshBase& libMesh::MeshRefinement::get_mesh | ( | ) | const [inline] |
MeshBase object associated with this object. Definition at line 320 of file mesh_refinement.h.
References _mesh.
{ return _mesh; }
| MeshBase& libMesh::MeshRefinement::get_mesh | ( | ) | [inline] |
MeshBase object associated with this object. Definition at line 326 of file mesh_refinement.h.
References _mesh.
{ return _mesh; }
| bool libMesh::MeshRefinement::has_topological_neighbor | ( | Elem * | elem, |
| const PointLocatorBase * | point_locator, | ||
| Elem * | neighbor | ||
| ) | [private] |
Local dispatch function for checking the correct has_neighbor function from the Elem class
Definition at line 1811 of file mesh_refinement.C.
References _mesh, _periodic_boundaries, libMesh::Elem::has_neighbor(), libMesh::Elem::has_topological_neighbor(), and libMesh::libmesh_assert().
Referenced by make_coarsening_compatible(), and make_refinement_compatible().
{
#ifdef LIBMESH_ENABLE_PERIODIC
if (_periodic_boundaries && !_periodic_boundaries->empty())
{
libmesh_assert(point_locator);
return elem->has_topological_neighbor(neighbor, _mesh, *point_locator, _periodic_boundaries);
}
#endif
return elem->has_neighbor(neighbor);
}
| bool libMesh::MeshRefinement::limit_level_mismatch_at_edge | ( | const unsigned int | max_mismatch | ) | [private] |
Definition at line 140 of file mesh_refinement_smoothing.C.
References _enforce_mismatch_limit_prior_to_refinement, _mesh, libMesh::MeshBase::active_elements_begin(), libMesh::MeshBase::active_elements_end(), libMesh::Elem::build_edge(), libMesh::ParallelObject::comm(), EDGE, enforce_mismatch_limit_prior_to_refinement(), libMesh::Elem::level(), std::max(), libMesh::Parallel::Communicator::max(), libMesh::Elem::n_edges(), libMesh::Elem::p_level(), libMesh::Elem::p_refinement_flag(), libMesh::Elem::parent(), libMesh::Elem::REFINE, libMesh::Elem::refinement_flag(), libMesh::Elem::set_p_refinement_flag(), libMesh::Elem::set_refinement_flag(), and libMesh::swap().
Referenced by coarsen_elements(), refine_and_coarsen_elements(), and refine_elements().
{
// This function must be run on all processors at once
parallel_object_only();
bool flags_changed = false;
// Maps holding the maximum element level that touches an edge
std::map<std::pair<unsigned int, unsigned int>, unsigned char>
max_level_at_edge;
std::map<std::pair<unsigned int, unsigned int>, unsigned char>
max_p_level_at_edge;
// Loop over all the active elements & fill the maps
{
MeshBase::element_iterator elem_it = _mesh.active_elements_begin();
const MeshBase::element_iterator elem_end = _mesh.active_elements_end();
for (; elem_it != elem_end; ++elem_it)
{
const Elem* elem = *elem_it;
const unsigned char elem_level =
cast_int<unsigned char>(elem->level() +
((elem->refinement_flag() == Elem::REFINE) ? 1 : 0));
const unsigned char elem_p_level =
cast_int<unsigned char>(elem->p_level() +
((elem->p_refinement_flag() == Elem::REFINE) ? 1 : 0));
// Set the max_level at each edge
for (unsigned int n=0; n<elem->n_edges(); n++)
{
UniquePtr<Elem> edge = elem->build_edge(n);
dof_id_type childnode0 = edge->node(0);
dof_id_type childnode1 = edge->node(1);
if (childnode1 < childnode0)
std::swap(childnode0, childnode1);
for (const Elem *p = elem; p != NULL; p = p->parent())
{
UniquePtr<Elem> pedge = p->build_edge(n);
dof_id_type node0 = pedge->node(0);
dof_id_type node1 = pedge->node(1);
if (node1 < node0)
std::swap(node0, node1);
// If elem does not share this edge with its ancestor
// p, refinement levels of elements sharing p's edge
// are not restricted by refinement levels of elem.
// Furthermore, elem will not share this edge with any
// of p's ancestors, so we can safely break out of the
// for loop early.
if (node0 != childnode0 && node1 != childnode1)
break;
childnode0 = node0;
childnode1 = node1;
std::pair<unsigned int, unsigned int> edge_key =
std::make_pair(node0, node1);
if (max_level_at_edge.find(edge_key) ==
max_level_at_edge.end())
{
max_level_at_edge[edge_key] = elem_level;
max_p_level_at_edge[edge_key] = elem_p_level;
}
else
{
max_level_at_edge[edge_key] =
std::max (max_level_at_edge[edge_key], elem_level);
max_p_level_at_edge[edge_key] =
std::max (max_p_level_at_edge[edge_key], elem_p_level);
}
}
}
}
}
// Now loop over the active elements and flag the elements
// who violate the requested level mismatch
{
MeshBase::element_iterator elem_it = _mesh.active_elements_begin();
const MeshBase::element_iterator elem_end = _mesh.active_elements_end();
for (; elem_it != elem_end; ++elem_it)
{
Elem* elem = *elem_it;
const unsigned int elem_level = elem->level();
const unsigned int elem_p_level = elem->p_level();
// Skip the element if it is already fully flagged
if (elem->refinement_flag() == Elem::REFINE &&
elem->p_refinement_flag() == Elem::REFINE
&& !_enforce_mismatch_limit_prior_to_refinement)
continue;
// Loop over the nodes, check for possible mismatch
for (unsigned int n=0; n<elem->n_edges(); n++)
{
UniquePtr<Elem> edge = elem->build_edge(n);
dof_id_type node0 = edge->node(0);
dof_id_type node1 = edge->node(1);
if (node1 < node0)
std::swap(node0, node1);
std::pair<dof_id_type, dof_id_type> edge_key =
std::make_pair(node0, node1);
// Flag the element for refinement if it violates
// the requested level mismatch
if ((elem_level + max_mismatch) < max_level_at_edge[edge_key]
&& elem->refinement_flag() != Elem::REFINE)
{
elem->set_refinement_flag (Elem::REFINE);
flags_changed = true;
}
if ((elem_p_level + max_mismatch) < max_p_level_at_edge[edge_key]
&& elem->p_refinement_flag() != Elem::REFINE)
{
elem->set_p_refinement_flag (Elem::REFINE);
flags_changed = true;
}
// Possibly enforce limit mismatch prior to refinement
flags_changed |= this->enforce_mismatch_limit_prior_to_refinement(elem, EDGE, max_mismatch);
} // loop over edges
} // loop over active elements
}
// If flags changed on any processor then they changed globally
this->comm().max(flags_changed);
return flags_changed;
}
| bool libMesh::MeshRefinement::limit_level_mismatch_at_node | ( | const unsigned int | max_mismatch | ) | [private] |
This algorithm restricts the maximum level mismatch at any node in the mesh. Calling this with max_mismatch equal to 1 would transform this mesh:
* o---o---o---o---o-------o-------o * | | | | | | | * | | | | | | | * o---o---o---o---o | | * | | | | | | | * | | | | | | | * o---o---o---o---o-------o-------o * | | | | | | | * | | | | | | | * o---o---o---o---o | | * | | | | | | | * | | | | | | | * o---o---o---o---o-------o-------o * | | | | * | | | | * | | | | * | | | | * | | | | * o-------o-------o | * | | | | * | | | | * | | | | * | | | | * | | | | * o-------o-------o---------------o *
into this:
* o---o---o---o---o-------o-------o * | | | | | | | * | | | | | | | * o---o---o---o---o | | * | | | | | | | * | | | | | | | * o---o---o---o---o-------o-------o * | | | | | | | * | | | | | | | * o---o---o---o---o | | * | | | | | | | * | | | | | | | * o---o---o---o---o-------o-------o * | | | : | * | | | : | * | | | : | * | | | : | * | | | : | * o-------o-------o.......o.......o * | | | : | * | | | : | * | | | : | * | | | : | * | | | : | * o-------o-------o-------o-------o *
by refining the indicated element
Definition at line 39 of file mesh_refinement_smoothing.C.
References _enforce_mismatch_limit_prior_to_refinement, _mesh, libMesh::MeshBase::active_elements_begin(), libMesh::MeshBase::active_elements_end(), libMesh::ParallelObject::comm(), enforce_mismatch_limit_prior_to_refinement(), libMesh::Elem::level(), std::max(), libMesh::Parallel::Communicator::max(), libMesh::MeshBase::n_nodes(), libMesh::Elem::n_nodes(), libMesh::Elem::node(), libMesh::Elem::p_level(), libMesh::Elem::p_refinement_flag(), POINT, libMesh::Elem::REFINE, libMesh::Elem::refinement_flag(), libMesh::Elem::set_p_refinement_flag(), and libMesh::Elem::set_refinement_flag().
Referenced by coarsen_elements(), refine_and_coarsen_elements(), and refine_elements().
{
// This function must be run on all processors at once
parallel_object_only();
bool flags_changed = false;
// Vector holding the maximum element level that touches a node.
std::vector<unsigned char> max_level_at_node (_mesh.n_nodes(), 0);
std::vector<unsigned char> max_p_level_at_node (_mesh.n_nodes(), 0);
// Loop over all the active elements & fill the vector
{
MeshBase::element_iterator elem_it = _mesh.active_elements_begin();
const MeshBase::element_iterator elem_end = _mesh.active_elements_end();
for (; elem_it != elem_end; ++elem_it)
{
const Elem* elem = *elem_it;
const unsigned char elem_level =
cast_int<unsigned char>(elem->level() +
((elem->refinement_flag() == Elem::REFINE) ? 1 : 0));
const unsigned char elem_p_level =
cast_int<unsigned char>(elem->p_level() +
((elem->p_refinement_flag() == Elem::REFINE) ? 1 : 0));
// Set the max_level at each node
for (unsigned int n=0; n<elem->n_nodes(); n++)
{
const dof_id_type node_number = elem->node(n);
libmesh_assert_less (node_number, max_level_at_node.size());
max_level_at_node[node_number] =
std::max (max_level_at_node[node_number], elem_level);
max_p_level_at_node[node_number] =
std::max (max_p_level_at_node[node_number], elem_p_level);
}
}
}
// Now loop over the active elements and flag the elements
// who violate the requested level mismatch. Alternatively, if
// _enforce_mismatch_limit_prior_to_refinement is true, swap refinement flags
// accordingly.
{
MeshBase::element_iterator elem_it = _mesh.active_elements_begin();
const MeshBase::element_iterator elem_end = _mesh.active_elements_end();
for (; elem_it != elem_end; ++elem_it)
{
Elem* elem = *elem_it;
const unsigned int elem_level = elem->level();
const unsigned int elem_p_level = elem->p_level();
// Skip the element if it is already fully flagged
// unless we are enforcing mismatch prior to refienemnt and may need to
// remove the refinement flag(s)
if (elem->refinement_flag() == Elem::REFINE &&
elem->p_refinement_flag() == Elem::REFINE
&& !_enforce_mismatch_limit_prior_to_refinement)
continue;
// Loop over the nodes, check for possible mismatch
for (unsigned int n=0; n<elem->n_nodes(); n++)
{
const dof_id_type node_number = elem->node(n);
// Flag the element for refinement if it violates
// the requested level mismatch
if ((elem_level + max_mismatch) < max_level_at_node[node_number]
&& elem->refinement_flag() != Elem::REFINE)
{
elem->set_refinement_flag (Elem::REFINE);
flags_changed = true;
}
if ((elem_p_level + max_mismatch) < max_p_level_at_node[node_number]
&& elem->p_refinement_flag() != Elem::REFINE)
{
elem->set_p_refinement_flag (Elem::REFINE);
flags_changed = true;
}
// Possibly enforce limit mismatch prior to refinement
flags_changed |= this->enforce_mismatch_limit_prior_to_refinement(elem, POINT, max_mismatch);
}
}
}
// If flags changed on any processor then they changed globally
this->comm().max(flags_changed);
return flags_changed;
}
| bool libMesh::MeshRefinement::make_coarsening_compatible | ( | const bool | maintain_level_one | ) | [private] |
Take user-specified coarsening flags and augment them so that level-one dependency is satisfied.
Definition at line 957 of file mesh_refinement.C.
References _face_level_mismatch_limit, _mesh, _periodic_boundaries, libMesh::Elem::active(), libMesh::MeshBase::active_elements_begin(), libMesh::MeshBase::active_elements_end(), libMesh::Elem::ancestor(), libMesh::Elem::child(), libMesh::Elem::COARSEN, libMesh::Elem::COARSEN_INACTIVE, libMesh::ParallelObject::comm(), libMesh::Elem::DO_NOTHING, libMesh::MeshBase::elements_begin(), libMesh::MeshBase::elements_end(), libMesh::Elem::has_children(), has_topological_neighbor(), libMesh::Elem::INACTIVE, libMesh::MeshBase::is_serial(), libMesh::Elem::level(), libMesh::MeshBase::level_elements_begin(), libMesh::MeshBase::level_elements_end(), libMesh::libmesh_assert(), std::max(), libMesh::MeshTools::max_level(), libMesh::Parallel::Communicator::min(), libMesh::Elem::n_children(), libMesh::Elem::n_neighbors(), libMesh::Elem::p_level(), libMesh::Elem::p_refinement_flag(), libMesh::ParallelObject::processor_id(), libMesh::DofObject::processor_id(), libMesh::Elem::REFINE, libMesh::Elem::refinement_flag(), libMesh::remote_elem, libMesh::Elem::set_p_refinement_flag(), libMesh::Elem::set_refinement_flag(), libMesh::START_LOG(), libMesh::MeshBase::sub_point_locator(), topological_neighbor(), and libMesh::Parallel::verify().
Referenced by coarsen_elements(), and refine_and_coarsen_elements().
{
// This function must be run on all processors at once
parallel_object_only();
// We may need a PointLocator for topological_neighbor() tests
// later, which we need to make sure gets constructed on all
// processors at once.
UniquePtr<PointLocatorBase> point_locator;
#ifdef LIBMESH_ENABLE_PERIODIC
bool has_periodic_boundaries =
_periodic_boundaries && !_periodic_boundaries->empty();
libmesh_assert(this->comm().verify(has_periodic_boundaries));
if (has_periodic_boundaries)
point_locator = _mesh.sub_point_locator();
#endif
START_LOG ("make_coarsening_compatible()", "MeshRefinement");
bool _maintain_level_one = maintain_level_one;
// If the user used non-default parameters, let's warn that they're
// deprecated
if (!maintain_level_one)
{
libmesh_deprecated();
}
else
_maintain_level_one = _face_level_mismatch_limit;
// Unless we encounter a specific situation level-one
// will be satisfied after executing this loop just once
bool level_one_satisfied = true;
// Unless we encounter a specific situation we will be compatible
// with any selected refinement flags
bool compatible_with_refinement = true;
// find the maximum h and p levels in the mesh
unsigned int max_level = 0;
unsigned int max_p_level = 0;
{
// First we look at all the active level-0 elements. Since it doesn't make
// sense to coarsen them we must un-set their coarsen flags if
// they are set.
MeshBase::element_iterator el = _mesh.active_elements_begin();
const MeshBase::element_iterator end_el = _mesh.active_elements_end();
for (; el != end_el; ++el)
{
Elem *elem = *el;
max_level = std::max(max_level, elem->level());
max_p_level =
std::max(max_p_level,
static_cast<unsigned int>(elem->p_level()));
if ((elem->level() == 0) &&
(elem->refinement_flag() == Elem::COARSEN))
elem->set_refinement_flag(Elem::DO_NOTHING);
if ((elem->p_level() == 0) &&
(elem->p_refinement_flag() == Elem::COARSEN))
elem->set_p_refinement_flag(Elem::DO_NOTHING);
}
}
// if there are no refined elements on this processor then
// there is no work for us to do
if (max_level == 0 && max_p_level == 0)
{
STOP_LOG ("make_coarsening_compatible()", "MeshRefinement");
// But we still have to check with other processors
this->comm().min(compatible_with_refinement);
return compatible_with_refinement;
}
// Loop over all the active elements. If an element is marked
// for coarsening we better check its neighbors. If ANY of these neighbors
// are marked for refinement AND are at the same level then there is a
// conflict. By convention refinement wins, so we un-mark the element for
// coarsening. Level-one would be violated in this case so we need to re-run
// the loop.
if (_maintain_level_one)
{
repeat:
level_one_satisfied = true;
do
{
level_one_satisfied = true;
MeshBase::element_iterator el = _mesh.active_elements_begin();
const MeshBase::element_iterator end_el = _mesh.active_elements_end();
for (; el != end_el; ++el)
{
Elem* elem = *el;
bool my_flag_changed = false;
if (elem->refinement_flag() == Elem::COARSEN) // If the element is active and
// the coarsen flag is set
{
const unsigned int my_level = elem->level();
for (unsigned int n=0; n<elem->n_neighbors(); n++)
{
const Elem* neighbor =
topological_neighbor(elem, point_locator.get(), n);
if (neighbor != NULL && // I have a
neighbor != remote_elem) // neighbor here
{
if (neighbor->active()) // and it is active
{
if ((neighbor->level() == my_level) &&
(neighbor->refinement_flag() == Elem::REFINE)) // the neighbor is at my level
// and wants to be refined
{
elem->set_refinement_flag(Elem::DO_NOTHING);
my_flag_changed = true;
break;
}
}
else // I have a neighbor and it is not active. That means it has children.
{ // While it _may_ be possible to coarsen us if all the children of
// that element want to be coarsened, it is impossible to know at this
// stage. Forget about it for the moment... This can be handled in
// two steps.
elem->set_refinement_flag(Elem::DO_NOTHING);
my_flag_changed = true;
break;
}
}
}
}
if (elem->p_refinement_flag() == Elem::COARSEN) // If
// the element is active and the order reduction flag is set
{
const unsigned int my_p_level = elem->p_level();
for (unsigned int n=0; n<elem->n_neighbors(); n++)
{
const Elem* neighbor =
topological_neighbor(elem, point_locator.get(), n);
if (neighbor != NULL && // I have a
neighbor != remote_elem) // neighbor here
{
if (neighbor->active()) // and it is active
{
if ((neighbor->p_level() > my_p_level &&
neighbor->p_refinement_flag() != Elem::COARSEN)
|| (neighbor->p_level() == my_p_level &&
neighbor->p_refinement_flag() == Elem::REFINE))
{
elem->set_p_refinement_flag(Elem::DO_NOTHING);
my_flag_changed = true;
break;
}
}
else // I have a neighbor and it is not active.
{ // We need to find which of its children
// have me as a neighbor, and maintain
// level one p compatibility with them.
// Because we currently have level one h
// compatibility, we don't need to check
// grandchildren
libmesh_assert(neighbor->has_children());
for (unsigned int c=0; c!=neighbor->n_children(); c++)
{
Elem *subneighbor = neighbor->child(c);
if (subneighbor != remote_elem &&
subneighbor->active() &&
has_topological_neighbor(subneighbor, point_locator.get(), elem))
if ((subneighbor->p_level() > my_p_level &&
subneighbor->p_refinement_flag() != Elem::COARSEN)
|| (subneighbor->p_level() == my_p_level &&
subneighbor->p_refinement_flag() == Elem::REFINE))
{
elem->set_p_refinement_flag(Elem::DO_NOTHING);
my_flag_changed = true;
break;
}
}
if (my_flag_changed)
break;
}
}
}
}
// If the current element's flag changed, we hadn't
// satisfied the level one rule.
if (my_flag_changed)
level_one_satisfied = false;
// Additionally, if it has non-local neighbors, and
// we're not in serial, then we'll eventually have to
// return compatible_with_refinement = false, because
// our change has to propagate to neighboring
// processors.
if (my_flag_changed && !_mesh.is_serial())
for (unsigned int n=0; n != elem->n_neighbors(); ++n)
{
Elem* neigh =
topological_neighbor(elem, point_locator.get(), n);
if (!neigh)
continue;
if (neigh == remote_elem ||
neigh->processor_id() !=
this->processor_id())
{
compatible_with_refinement = false;
break;
}
// FIXME - for non-level one meshes we should
// test all descendants
if (neigh->has_children())
for (unsigned int c=0; c != neigh->n_children(); ++c)
if (neigh->child(c) == remote_elem ||
neigh->child(c)->processor_id() !=
this->processor_id())
{
compatible_with_refinement = false;
break;
}
}
}
}
while (!level_one_satisfied);
} // end if (_maintain_level_one)
// Next we look at all of the ancestor cells.
// If there is a parent cell with all of its children
// wanting to be unrefined then the element is a candidate
// for unrefinement. If all the children don't
// all want to be unrefined then ALL of them need to have their
// unrefinement flags cleared.
for (int level=(max_level); level >= 0; level--)
{
MeshBase::element_iterator el = _mesh.level_elements_begin(level);
const MeshBase::element_iterator end_el = _mesh.level_elements_end(level);
for (; el != end_el; ++el)
{
Elem *elem = *el;
if (elem->ancestor())
{
// right now the element hasn't been disqualified
// as a candidate for unrefinement
bool is_a_candidate = true;
bool found_remote_child = false;
for (unsigned int c=0; c<elem->n_children(); c++)
{
Elem *child = elem->child(c);
if (child == remote_elem)
found_remote_child = true;
else if ((child->refinement_flag() != Elem::COARSEN) ||
!child->active() )
is_a_candidate = false;
}
if (!is_a_candidate && !found_remote_child)
{
elem->set_refinement_flag(Elem::INACTIVE);
for (unsigned int c=0; c<elem->n_children(); c++)
{
Elem *child = elem->child(c);
if (child == remote_elem)
continue;
if (child->refinement_flag() == Elem::COARSEN)
{
level_one_satisfied = false;
child->set_refinement_flag(Elem::DO_NOTHING);
}
}
}
}
}
}
if (!level_one_satisfied && _maintain_level_one) goto repeat;
// If all the children of a parent are set to be coarsened
// then flag the parent so that they can kill thier kids...
MeshBase::element_iterator all_el = _mesh.elements_begin();
const MeshBase::element_iterator all_el_end = _mesh.elements_end();
for (; all_el != all_el_end; ++all_el)
{
Elem *elem = *all_el;
if (elem->ancestor())
{
// Presume all the children are local and flagged for
// coarsening and then look for a contradiction
bool all_children_flagged_for_coarsening = true;
bool found_remote_child = false;
for (unsigned int c=0; c<elem->n_children(); c++)
{
Elem *child = elem->child(c);
if (child == remote_elem)
found_remote_child = true;
else if (child->refinement_flag() != Elem::COARSEN)
all_children_flagged_for_coarsening = false;
}
if (!found_remote_child &&
all_children_flagged_for_coarsening)
elem->set_refinement_flag(Elem::COARSEN_INACTIVE);
else if (!found_remote_child)
elem->set_refinement_flag(Elem::INACTIVE);
}
}
STOP_LOG ("make_coarsening_compatible()", "MeshRefinement");
// If one processor finds an incompatibility, we're globally
// incompatible
this->comm().min(compatible_with_refinement);
return compatible_with_refinement;
}
Copy refinement flags on ghost elements from their local processors. Return true if any flags changed.
Definition at line 927 of file mesh_refinement.C.
References _mesh, libMesh::ParallelObject::comm(), libMesh::MeshBase::elements_begin(), libMesh::MeshBase::elements_end(), libMesh::Parallel::Communicator::min(), libMesh::Elem::p_refinement_flag(), parallel_consistent, libMesh::Elem::refinement_flag(), libMesh::Elem::set_p_refinement_flag(), libMesh::Elem::set_refinement_flag(), libMesh::START_LOG(), and libMesh::Parallel::sync_dofobject_data_by_id().
Referenced by coarsen_elements(), refine_and_coarsen_elements(), and refine_elements().
{
// This function must be run on all processors at once
parallel_object_only();
START_LOG ("make_flags_parallel_consistent()", "MeshRefinement");
SyncRefinementFlags hsync(_mesh, &Elem::refinement_flag,
&Elem::set_refinement_flag);
Parallel::sync_dofobject_data_by_id
(this->comm(), _mesh.elements_begin(), _mesh.elements_end(), hsync);
SyncRefinementFlags psync(_mesh, &Elem::p_refinement_flag,
&Elem::set_p_refinement_flag);
Parallel::sync_dofobject_data_by_id
(this->comm(), _mesh.elements_begin(), _mesh.elements_end(), psync);
// If we weren't consistent in both h and p on every processor then
// we weren't globally consistent
bool parallel_consistent = hsync.parallel_consistent &&
psync.parallel_consistent;
this->comm().min(parallel_consistent);
STOP_LOG ("make_flags_parallel_consistent()", "MeshRefinement");
return parallel_consistent;
}
| bool libMesh::MeshRefinement::make_refinement_compatible | ( | const bool | maintain_level_one | ) | [private] |
Take user-specified refinement flags and augment them so that level-one dependency is satisfied.
Definition at line 1306 of file mesh_refinement.C.
References _face_level_mismatch_limit, _mesh, _periodic_boundaries, libMesh::Elem::active(), libMesh::MeshBase::active_elements_begin(), libMesh::MeshBase::active_elements_end(), libMesh::Elem::child(), libMesh::Elem::COARSEN, libMesh::ParallelObject::comm(), libMesh::Elem::DO_NOTHING, libMesh::Elem::has_children(), has_topological_neighbor(), libMesh::Elem::INACTIVE, libMesh::Elem::level(), libMesh::libmesh_assert(), libMesh::Parallel::Communicator::min(), libMesh::Elem::n_children(), libMesh::Elem::n_sides(), libMesh::Elem::p_level(), libMesh::Elem::p_refinement_flag(), libMesh::Elem::parent(), libMesh::Elem::REFINE, libMesh::Elem::refinement_flag(), libMesh::remote_elem, libMesh::Elem::set_p_refinement_flag(), libMesh::Elem::set_refinement_flag(), side, libMesh::START_LOG(), libMesh::MeshBase::sub_point_locator(), topological_neighbor(), and libMesh::Parallel::verify().
Referenced by refine_and_coarsen_elements(), and refine_elements().
{
// This function must be run on all processors at once
parallel_object_only();
// We may need a PointLocator for topological_neighbor() tests
// later, which we need to make sure gets constructed on all
// processors at once.
UniquePtr<PointLocatorBase> point_locator;
#ifdef LIBMESH_ENABLE_PERIODIC
bool has_periodic_boundaries =
_periodic_boundaries && !_periodic_boundaries->empty();
libmesh_assert(this->comm().verify(has_periodic_boundaries));
if (has_periodic_boundaries)
point_locator = _mesh.sub_point_locator();
#endif
START_LOG ("make_refinement_compatible()", "MeshRefinement");
bool _maintain_level_one = maintain_level_one;
// If the user used non-default parameters, let's warn that they're
// deprecated
if (!maintain_level_one)
{
libmesh_deprecated();
}
else
_maintain_level_one = _face_level_mismatch_limit;
// Unless we encounter a specific situation we will be compatible
// with any selected coarsening flags
bool compatible_with_coarsening = true;
// This loop enforces the level-1 rule. We should only
// execute it if the user indeed wants level-1 satisfied!
if (_maintain_level_one)
{
// Unless we encounter a specific situation level-one
// will be satisfied after executing this loop just once
bool level_one_satisfied = true;
do
{
level_one_satisfied = true;
MeshBase::element_iterator el = _mesh.active_elements_begin();
const MeshBase::element_iterator end_el = _mesh.active_elements_end();
for (; el != end_el; ++el)
{
Elem *elem = *el;
if (elem->refinement_flag() == Elem::REFINE) // If the element is active and the
// h refinement flag is set
{
const unsigned int my_level = elem->level();
for (unsigned int side=0; side != elem->n_sides(); side++)
{
Elem* neighbor =
topological_neighbor(elem, point_locator.get(), side);
if (neighbor != NULL && // I have a
neighbor != remote_elem && // neighbor here
neighbor->active()) // and it is active
{
// Case 1: The neighbor is at the same level I am.
// 1a: The neighbor will be refined -> NO PROBLEM
// 1b: The neighbor won't be refined -> NO PROBLEM
// 1c: The neighbor wants to be coarsened -> PROBLEM
if (neighbor->level() == my_level)
{
if (neighbor->refinement_flag() == Elem::COARSEN)
{
neighbor->set_refinement_flag(Elem::DO_NOTHING);
if (neighbor->parent())
neighbor->parent()->set_refinement_flag(Elem::INACTIVE);
compatible_with_coarsening = false;
level_one_satisfied = false;
}
}
// Case 2: The neighbor is one level lower than I am.
// The neighbor thus MUST be refined to satisfy
// the level-one rule, regardless of whether it
// was originally flagged for refinement. If it
// wasn't flagged already we need to repeat
// this process.
else if ((neighbor->level()+1) == my_level)
{
if (neighbor->refinement_flag() != Elem::REFINE)
{
neighbor->set_refinement_flag(Elem::REFINE);
if (neighbor->parent())
neighbor->parent()->set_refinement_flag(Elem::INACTIVE);
compatible_with_coarsening = false;
level_one_satisfied = false;
}
}
#ifdef DEBUG
// Note that the only other possibility is that the
// neighbor is already refined, in which case it isn't
// active and we should never get here.
else
libmesh_error_msg("ERROR: Neighbor level must be equal or 1 higher than mine.");
#endif
}
}
}
if (elem->p_refinement_flag() == Elem::REFINE) // If the element is active and the
// p refinement flag is set
{
const unsigned int my_p_level = elem->p_level();
for (unsigned int side=0; side != elem->n_sides(); side++)
{
Elem* neighbor =
topological_neighbor(elem, point_locator.get(), side);
if (neighbor != NULL && // I have a
neighbor != remote_elem) // neighbor here
{
if (neighbor->active()) // and it is active
{
if (neighbor->p_level() < my_p_level &&
neighbor->p_refinement_flag() != Elem::REFINE)
{
neighbor->set_p_refinement_flag(Elem::REFINE);
level_one_satisfied = false;
compatible_with_coarsening = false;
}
if (neighbor->p_level() == my_p_level &&
neighbor->p_refinement_flag() == Elem::COARSEN)
{
neighbor->set_p_refinement_flag(Elem::DO_NOTHING);
level_one_satisfied = false;
compatible_with_coarsening = false;
}
}
else // I have an inactive neighbor
{
libmesh_assert(neighbor->has_children());
for (unsigned int c=0; c!=neighbor->n_children(); c++)
{
Elem *subneighbor = neighbor->child(c);
if (subneighbor == remote_elem)
continue;
if (subneighbor->active() &&
has_topological_neighbor(subneighbor, point_locator.get(), elem))
{
if (subneighbor->p_level() < my_p_level &&
subneighbor->p_refinement_flag() != Elem::REFINE)
{
// We should already be level one
// compatible
libmesh_assert_greater (subneighbor->p_level() + 2u,
my_p_level);
subneighbor->set_p_refinement_flag(Elem::REFINE);
level_one_satisfied = false;
compatible_with_coarsening = false;
}
if (subneighbor->p_level() == my_p_level &&
subneighbor->p_refinement_flag() == Elem::COARSEN)
{
subneighbor->set_p_refinement_flag(Elem::DO_NOTHING);
level_one_satisfied = false;
compatible_with_coarsening = false;
}
}
}
}
}
}
}
}
}
while (!level_one_satisfied);
} // end if (_maintain_level_one)
// If we're not compatible on one processor, we're globally not
// compatible
this->comm().min(compatible_with_coarsening);
STOP_LOG ("make_refinement_compatible()", "MeshRefinement");
return compatible_with_coarsening;
}
| unsigned int & libMesh::MeshRefinement::max_h_level | ( | ) | [inline] |
The max_h_level is the greatest refinement level an element should reach.
max_h_level is unlimited (libMesh::invalid_uint) by default
Definition at line 807 of file mesh_refinement.h.
References _max_h_level, and _use_member_parameters.
{
_use_member_parameters = true;
return _max_h_level;
}
| processor_id_type libMesh::ParallelObject::n_processors | ( | ) | const [inline, inherited] |
Definition at line 92 of file parallel_object.h.
References libMesh::ParallelObject::_communicator, and libMesh::Parallel::Communicator::size().
Referenced by libMesh::ParmetisPartitioner::_do_repartition(), libMesh::ParallelMesh::add_elem(), libMesh::ParallelMesh::add_node(), libMesh::LaplaceMeshSmoother::allgather_graph(), libMesh::FEMSystem::assembly(), libMesh::ParmetisPartitioner::assign_partitioning(), libMesh::ParallelMesh::assign_unique_ids(), libMesh::AztecLinearSolver< T >::AztecLinearSolver(), libMesh::ParallelMesh::clear(), libMesh::Nemesis_IO_Helper::compute_border_node_ids(), libMesh::Nemesis_IO_Helper::construct_nemesis_filename(), libMesh::UnstructuredMesh::create_pid_mesh(), libMesh::DofMap::distribute_dofs(), libMesh::DofMap::distribute_local_dofs_node_major(), libMesh::DofMap::distribute_local_dofs_var_major(), libMesh::EnsightIO::EnsightIO(), libMesh::MeshBase::get_info(), libMesh::EquationSystems::init(), libMesh::SystemSubsetBySubdomain::init(), libMesh::ParmetisPartitioner::initialize(), libMesh::Nemesis_IO_Helper::initialize(), libMesh::MeshTools::libmesh_assert_valid_dof_ids(), libMesh::MeshTools::libmesh_assert_valid_procids< Elem >(), libMesh::MeshTools::libmesh_assert_valid_procids< Node >(), libMesh::MeshTools::libmesh_assert_valid_refinement_flags(), libMesh::DofMap::local_variable_indices(), libMesh::MeshBase::n_active_elem_on_proc(), libMesh::MeshBase::n_elem_on_proc(), libMesh::MeshBase::n_nodes_on_proc(), libMesh::Partitioner::partition(), libMesh::MeshBase::partition(), libMesh::Partitioner::partition_unpartitioned_elements(), libMesh::PetscLinearSolver< T >::PetscLinearSolver(), libMesh::System::point_gradient(), libMesh::System::point_hessian(), libMesh::System::point_value(), libMesh::MeshTools::processor_bounding_box(), libMesh::System::project_vector(), libMesh::NameBasedIO::read(), libMesh::Nemesis_IO::read(), libMesh::CheckpointIO::read(), libMesh::XdrIO::read(), libMesh::System::read_parallel_data(), libMesh::System::read_SCALAR_dofs(), libMesh::System::read_serialized_blocked_dof_objects(), libMesh::System::read_serialized_vector(), libMesh::Partitioner::repartition(), libMesh::Partitioner::set_node_processor_ids(), libMesh::DofMap::set_nonlocal_dof_objects(), libMesh::BoundaryInfo::sync(), libMesh::ParallelMesh::update_parallel_id_counts(), libMesh::CheckpointIO::write(), libMesh::GMVIO::write_binary(), libMesh::GMVIO::write_discontinuous_gmv(), libMesh::System::write_parallel_data(), libMesh::System::write_SCALAR_dofs(), libMesh::XdrIO::write_serialized_bcs(), libMesh::System::write_serialized_blocked_dof_objects(), libMesh::XdrIO::write_serialized_connectivity(), libMesh::XdrIO::write_serialized_nodes(), and libMesh::XdrIO::write_serialized_nodesets().
{ return cast_int<processor_id_type>(_communicator.size()); }
| dof_id_type & libMesh::MeshRefinement::nelem_target | ( | ) | [inline] |
If nelem_target is set to a nonzero value, methods like flag_elements_by_nelem_target() will attempt to keep the number of active elements in the mesh close to nelem_target.
nelem_target is 0 by default.
Definition at line 819 of file mesh_refinement.h.
References _nelem_target, and _use_member_parameters.
{
_use_member_parameters = true;
return _nelem_target;
}
| unsigned char & libMesh::MeshRefinement::node_level_mismatch_limit | ( | ) | [inline] |
If node_level_mismatch_limit is set to a nonzero value, then refinement and coarsening will produce meshes in which the refinement level of two nodal neighbors will not differ by more than that limit. If node_level_mismatch_limit is 0, then level differences will be unlimited.
node_level_mismatch_limit is 0 by default.
Definition at line 841 of file mesh_refinement.h.
References _node_level_mismatch_limit.
{
return _node_level_mismatch_limit;
}
| MeshRefinement& libMesh::MeshRefinement::operator= | ( | const MeshRefinement & | ) | [private] |
| processor_id_type libMesh::ParallelObject::processor_id | ( | ) | const [inline, inherited] |
Definition at line 98 of file parallel_object.h.
References libMesh::ParallelObject::_communicator, and libMesh::Parallel::Communicator::rank().
Referenced by libMesh::MetisPartitioner::_do_partition(), libMesh::EquationSystems::_read_impl(), libMesh::SerialMesh::active_local_elements_begin(), libMesh::ParallelMesh::active_local_elements_begin(), libMesh::SerialMesh::active_local_elements_end(), libMesh::ParallelMesh::active_local_elements_end(), libMesh::SerialMesh::active_local_subdomain_elements_begin(), libMesh::ParallelMesh::active_local_subdomain_elements_begin(), libMesh::SerialMesh::active_local_subdomain_elements_end(), libMesh::ParallelMesh::active_local_subdomain_elements_end(), libMesh::SerialMesh::active_not_local_elements_begin(), libMesh::ParallelMesh::active_not_local_elements_begin(), libMesh::SerialMesh::active_not_local_elements_end(), libMesh::ParallelMesh::active_not_local_elements_end(), libMesh::ParallelMesh::add_elem(), libMesh::DofMap::add_neighbors_to_send_list(), libMesh::ParallelMesh::add_node(), libMesh::UnstructuredMesh::all_second_order(), libMesh::FEMSystem::assembly(), libMesh::ParmetisPartitioner::assign_partitioning(), libMesh::ParallelMesh::assign_unique_ids(), libMesh::EquationSystems::build_discontinuous_solution_vector(), libMesh::Nemesis_IO_Helper::build_element_and_node_maps(), libMesh::ParmetisPartitioner::build_graph(), libMesh::InfElemBuilder::build_inf_elem(), libMesh::DofMap::build_sparsity(), libMesh::ParallelMesh::clear(), libMesh::ExodusII_IO_Helper::close(), libMesh::Nemesis_IO_Helper::compute_border_node_ids(), libMesh::Nemesis_IO_Helper::compute_communication_map_parameters(), libMesh::Nemesis_IO_Helper::compute_internal_and_border_elems_and_internal_nodes(), libMesh::Nemesis_IO_Helper::compute_node_communication_maps(), libMesh::Nemesis_IO_Helper::compute_num_global_elem_blocks(), libMesh::Nemesis_IO_Helper::compute_num_global_nodesets(), libMesh::Nemesis_IO_Helper::compute_num_global_sidesets(), libMesh::Nemesis_IO_Helper::construct_nemesis_filename(), libMesh::ExodusII_IO_Helper::create(), libMesh::ParallelMesh::delete_elem(), libMesh::ParallelMesh::delete_node(), libMesh::DofMap::distribute_dofs(), libMesh::DofMap::distribute_local_dofs_node_major(), libMesh::DofMap::distribute_local_dofs_var_major(), libMesh::DofMap::end_dof(), libMesh::DofMap::end_old_dof(), libMesh::EnsightIO::EnsightIO(), libMesh::SerialMesh::facelocal_elements_begin(), libMesh::ParallelMesh::facelocal_elements_begin(), libMesh::SerialMesh::facelocal_elements_end(), libMesh::ParallelMesh::facelocal_elements_end(), libMesh::MeshFunction::find_element(), libMesh::UnstructuredMesh::find_neighbors(), libMesh::DofMap::first_dof(), libMesh::DofMap::first_old_dof(), libMesh::Nemesis_IO_Helper::get_cmap_params(), libMesh::Nemesis_IO_Helper::get_eb_info_global(), libMesh::Nemesis_IO_Helper::get_elem_cmap(), libMesh::Nemesis_IO_Helper::get_elem_map(), libMesh::MeshBase::get_info(), libMesh::Nemesis_IO_Helper::get_init_global(), libMesh::Nemesis_IO_Helper::get_init_info(), libMesh::Nemesis_IO_Helper::get_loadbal_param(), libMesh::Nemesis_IO_Helper::get_node_cmap(), libMesh::Nemesis_IO_Helper::get_node_map(), libMesh::Nemesis_IO_Helper::get_ns_param_global(), libMesh::Nemesis_IO_Helper::get_ss_param_global(), libMesh::SystemSubsetBySubdomain::init(), libMesh::ParmetisPartitioner::initialize(), libMesh::ExodusII_IO_Helper::initialize(), libMesh::ExodusII_IO_Helper::initialize_element_variables(), libMesh::ExodusII_IO_Helper::initialize_global_variables(), libMesh::ExodusII_IO_Helper::initialize_nodal_variables(), libMesh::ParallelMesh::insert_elem(), libMesh::SparsityPattern::Build::join(), libMesh::DofMap::last_dof(), libMesh::MeshTools::libmesh_assert_valid_procids< Elem >(), libMesh::MeshTools::libmesh_assert_valid_procids< Node >(), libMesh::SerialMesh::local_elements_begin(), libMesh::ParallelMesh::local_elements_begin(), libMesh::SerialMesh::local_elements_end(), libMesh::ParallelMesh::local_elements_end(), libMesh::SerialMesh::local_level_elements_begin(), libMesh::ParallelMesh::local_level_elements_begin(), libMesh::SerialMesh::local_level_elements_end(), libMesh::ParallelMesh::local_level_elements_end(), libMesh::SerialMesh::local_nodes_begin(), libMesh::ParallelMesh::local_nodes_begin(), libMesh::SerialMesh::local_nodes_end(), libMesh::ParallelMesh::local_nodes_end(), libMesh::SerialMesh::local_not_level_elements_begin(), libMesh::ParallelMesh::local_not_level_elements_begin(), libMesh::SerialMesh::local_not_level_elements_end(), libMesh::ParallelMesh::local_not_level_elements_end(), libMesh::DofMap::local_variable_indices(), make_coarsening_compatible(), libMesh::MeshBase::n_active_local_elem(), libMesh::BoundaryInfo::n_boundary_conds(), libMesh::BoundaryInfo::n_edge_conds(), libMesh::DofMap::n_local_dofs(), libMesh::System::n_local_dofs(), libMesh::MeshBase::n_local_elem(), libMesh::MeshBase::n_local_nodes(), libMesh::BoundaryInfo::n_nodeset_conds(), libMesh::SerialMesh::not_local_elements_begin(), libMesh::ParallelMesh::not_local_elements_begin(), libMesh::SerialMesh::not_local_elements_end(), libMesh::ParallelMesh::not_local_elements_end(), libMesh::WeightedPatchRecoveryErrorEstimator::EstimateError::operator()(), libMesh::SparsityPattern::Build::operator()(), libMesh::PatchRecoveryErrorEstimator::EstimateError::operator()(), libMesh::ParallelMesh::ParallelMesh(), libMesh::System::point_gradient(), libMesh::System::point_hessian(), libMesh::System::point_value(), libMesh::System::project_vector(), libMesh::Nemesis_IO_Helper::put_cmap_params(), libMesh::Nemesis_IO_Helper::put_elem_cmap(), libMesh::Nemesis_IO_Helper::put_elem_map(), libMesh::Nemesis_IO_Helper::put_loadbal_param(), libMesh::Nemesis_IO_Helper::put_node_cmap(), libMesh::Nemesis_IO_Helper::put_node_map(), libMesh::NameBasedIO::read(), libMesh::Nemesis_IO::read(), libMesh::CheckpointIO::read(), libMesh::XdrIO::read(), libMesh::ExodusII_IO_Helper::read_elem_num_map(), libMesh::System::read_header(), libMesh::System::read_legacy_data(), libMesh::ExodusII_IO_Helper::read_node_num_map(), libMesh::System::read_parallel_data(), libMesh::System::read_SCALAR_dofs(), libMesh::XdrIO::read_serialized_bc_names(), libMesh::XdrIO::read_serialized_bcs(), libMesh::System::read_serialized_blocked_dof_objects(), libMesh::XdrIO::read_serialized_connectivity(), libMesh::System::read_serialized_data(), libMesh::XdrIO::read_serialized_nodes(), libMesh::XdrIO::read_serialized_nodesets(), libMesh::XdrIO::read_serialized_subdomain_names(), libMesh::System::read_serialized_vector(), libMesh::System::read_serialized_vectors(), libMesh::MeshData::read_xdr(), libMesh::SerialMesh::semilocal_elements_begin(), libMesh::ParallelMesh::semilocal_elements_begin(), libMesh::SerialMesh::semilocal_elements_end(), libMesh::ParallelMesh::semilocal_elements_end(), libMesh::Partitioner::set_node_processor_ids(), libMesh::DofMap::set_nonlocal_dof_objects(), libMesh::LaplaceMeshSmoother::smooth(), libMesh::BoundaryInfo::sync(), libMesh::MeshTools::total_weight(), libMesh::ParallelMesh::update_parallel_id_counts(), libMesh::MeshTools::weight(), libMesh::NameBasedIO::write(), libMesh::ExodusII_IO::write(), libMesh::CheckpointIO::write(), libMesh::XdrIO::write(), libMesh::EquationSystems::write(), libMesh::GMVIO::write_discontinuous_gmv(), libMesh::ExodusII_IO::write_element_data(), libMesh::ExodusII_IO_Helper::write_element_values(), libMesh::ExodusII_IO_Helper::write_elements(), libMesh::ExodusII_IO::write_global_data(), libMesh::ExodusII_IO_Helper::write_global_values(), libMesh::System::write_header(), libMesh::ExodusII_IO::write_information_records(), libMesh::ExodusII_IO_Helper::write_information_records(), libMesh::ExodusII_IO_Helper::write_nodal_coordinates(), libMesh::UCDIO::write_nodal_data(), libMesh::ExodusII_IO::write_nodal_data(), libMesh::ExodusII_IO::write_nodal_data_discontinuous(), libMesh::ExodusII_IO_Helper::write_nodal_values(), libMesh::ExodusII_IO_Helper::write_nodesets(), libMesh::Nemesis_IO_Helper::write_nodesets(), libMesh::System::write_parallel_data(), libMesh::System::write_SCALAR_dofs(), libMesh::XdrIO::write_serialized_bc_names(), libMesh::XdrIO::write_serialized_bcs(), libMesh::System::write_serialized_blocked_dof_objects(), libMesh::XdrIO::write_serialized_connectivity(), libMesh::System::write_serialized_data(), libMesh::XdrIO::write_serialized_nodes(), libMesh::XdrIO::write_serialized_nodesets(), libMesh::XdrIO::write_serialized_subdomain_names(), libMesh::System::write_serialized_vector(), libMesh::System::write_serialized_vectors(), libMesh::ExodusII_IO_Helper::write_sidesets(), libMesh::Nemesis_IO_Helper::write_sidesets(), libMesh::ExodusII_IO::write_timestep(), and libMesh::ExodusII_IO_Helper::write_timestep().
{ return cast_int<processor_id_type>(_communicator.rank()); }
| bool libMesh::MeshRefinement::refine_and_coarsen_elements | ( | const bool | maintain_level_one = true | ) |
Refines and coarsens user-requested elements. Will also refine/coarsen additional elements to satisy level-one rule. It is possible that for a given set of refinement flags there is actually no change upon calling this member function. Consequently, this function returns true if the mesh actually changed (hence data needs to be projected) and false otherwise.
The argument maintain_level_one is now deprecated; use the option face_level_mismatch_limit() instead.
Definition at line 443 of file mesh_refinement.C.
References _coarsen_elements(), _edge_level_mismatch_limit, _face_level_mismatch_limit, _mesh, _node_level_mismatch_limit, _refine_elements(), libMesh::Elem::active(), libMesh::ParallelObject::comm(), libMesh::Elem::DO_NOTHING, libMesh::MeshBase::elements_begin(), libMesh::MeshBase::elements_end(), eliminate_unrefined_patches(), libMesh::Elem::INACTIVE, libMesh::MeshBase::is_serial(), libMesh::Elem::JUST_REFINED, libMesh::libmesh_assert(), libMesh::MeshBase::libmesh_assert_valid_parallel_ids(), limit_level_mismatch_at_edge(), limit_level_mismatch_at_node(), make_coarsening_compatible(), make_flags_parallel_consistent(), make_refinement_compatible(), libMesh::Parallel::Communicator::max(), libMesh::Parallel::Communicator::min(), libMesh::out, libMesh::MeshBase::prepare_for_use(), libMesh::Elem::refinement_flag(), libMesh::Elem::set_p_refinement_flag(), libMesh::Elem::set_refinement_flag(), test_level_one(), and test_unflagged().
{
// This function must be run on all processors at once
parallel_object_only();
bool _maintain_level_one = maintain_level_one;
// If the user used non-default parameters, let's warn that they're
// deprecated
if (!maintain_level_one)
{
libmesh_deprecated();
}
else
_maintain_level_one = _face_level_mismatch_limit;
// We can't yet turn a non-level-one mesh into a level-one mesh
if (_maintain_level_one)
libmesh_assert(test_level_one(true));
// Possibly clean up the refinement flags from
// a previous step
MeshBase::element_iterator elem_it = _mesh.elements_begin();
const MeshBase::element_iterator elem_end = _mesh.elements_end();
for ( ; elem_it != elem_end; ++elem_it)
{
// Pointer to the element
Elem *elem = *elem_it;
// Set refinement flag to INACTIVE if the
// element isn't active
if ( !elem->active())
{
elem->set_refinement_flag(Elem::INACTIVE);
elem->set_p_refinement_flag(Elem::INACTIVE);
}
// This might be left over from the last step
if (elem->refinement_flag() == Elem::JUST_REFINED)
elem->set_refinement_flag(Elem::DO_NOTHING);
}
// Parallel consistency has to come first, or coarsening
// along processor boundaries might occasionally be falsely
// prevented
bool flags_were_consistent = this->make_flags_parallel_consistent();
// In theory, we should be able to remove the above call, which can
// be expensive and should be unnecessary. In practice, doing
// consistent flagging in parallel is hard, it's impossible to
// verify at the library level if it's being done by user code, and
// we don't want to abort large parallel runs in opt mode... but we
// do want to warn that they should be fixed.
if (!flags_were_consistent)
{
libMesh::out << "Refinement flags were not consistent between processors!\n"
<< "Correcting and continuing.";
}
// Repeat until flag changes match on every processor
do
{
// Repeat until coarsening & refinement flags jive
bool satisfied = false;
do
{
const bool coarsening_satisfied =
this->make_coarsening_compatible(maintain_level_one);
const bool refinement_satisfied =
this->make_refinement_compatible(maintain_level_one);
bool smoothing_satisfied =
!this->eliminate_unrefined_patches();
if (_edge_level_mismatch_limit)
smoothing_satisfied = smoothing_satisfied &&
!this->limit_level_mismatch_at_edge (_edge_level_mismatch_limit);
if (_node_level_mismatch_limit)
smoothing_satisfied = smoothing_satisfied &&
!this->limit_level_mismatch_at_node (_node_level_mismatch_limit);
satisfied = (coarsening_satisfied &&
refinement_satisfied &&
smoothing_satisfied);
#ifdef DEBUG
bool max_satisfied = satisfied,
min_satisfied = satisfied;
this->comm().max(max_satisfied);
this->comm().min(min_satisfied);
libmesh_assert_equal_to (satisfied, max_satisfied);
libmesh_assert_equal_to (satisfied, min_satisfied);
#endif
}
while (!satisfied);
}
while (!_mesh.is_serial() && !this->make_flags_parallel_consistent());
// First coarsen the flagged elements.
const bool coarsening_changed_mesh =
this->_coarsen_elements ();
// FIXME: test_level_one now tests consistency across periodic
// boundaries, which requires a point_locator, which just got
// invalidated by _coarsen_elements() and hasn't yet been cleared by
// prepare_for_use().
// if (_maintain_level_one)
// libmesh_assert(test_level_one(true));
// libmesh_assert(this->make_coarsening_compatible(maintain_level_one));
// libmesh_assert(this->make_refinement_compatible(maintain_level_one));
// FIXME: This won't pass unless we add a redundant find_neighbors()
// call or replace find_neighbors() with on-the-fly neighbor updating
// libmesh_assert(!this->eliminate_unrefined_patches());
// We can't contract the mesh ourselves anymore - a System might
// need to restrict old coefficient vectors first
// _mesh.contract();
// Now refine the flagged elements. This will
// take up some space, maybe more than what was freed.
const bool refining_changed_mesh =
this->_refine_elements();
// Finally, the new mesh needs to be prepared for use
if (coarsening_changed_mesh || refining_changed_mesh)
{
#ifdef DEBUG
_mesh.libmesh_assert_valid_parallel_ids();
#endif
_mesh.prepare_for_use (/*skip_renumber =*/false);
if (_maintain_level_one)
libmesh_assert(test_level_one(true));
libmesh_assert(test_unflagged(true));
libmesh_assert(this->make_coarsening_compatible(maintain_level_one));
libmesh_assert(this->make_refinement_compatible(maintain_level_one));
// FIXME: This won't pass unless we add a redundant find_neighbors()
// call or replace find_neighbors() with on-the-fly neighbor updating
// libmesh_assert(!this->eliminate_unrefined_patches());
return true;
}
else
{
if (_maintain_level_one)
libmesh_assert(test_level_one(true));
libmesh_assert(test_unflagged(true));
libmesh_assert(this->make_coarsening_compatible(maintain_level_one));
libmesh_assert(this->make_refinement_compatible(maintain_level_one));
}
// Otherwise there was no change in the mesh,
// let the user know. Also, there is no need
// to prepare the mesh for use since it did not change.
return false;
}
| bool libMesh::MeshRefinement::refine_elements | ( | const bool | maintain_level_one = true | ) |
Only refines the user-requested elements. It is possible that for a given set of refinement flags there is actually no change upon calling this member function. Consequently, this function returns true if the mesh actually changed (hence data needs to be projected) and false otherwise.
The argument maintain_level_one is now deprecated; use the option face_level_mismatch_limit() instead.
Definition at line 737 of file mesh_refinement.C.
References _edge_level_mismatch_limit, _face_level_mismatch_limit, _mesh, _node_level_mismatch_limit, _refine_elements(), libMesh::Elem::active(), libMesh::ParallelObject::comm(), libMesh::Elem::DO_NOTHING, libMesh::MeshBase::elements_begin(), libMesh::MeshBase::elements_end(), eliminate_unrefined_patches(), libMesh::Elem::INACTIVE, libMesh::MeshBase::is_serial(), libMesh::Elem::JUST_REFINED, libMesh::libmesh_assert(), limit_level_mismatch_at_edge(), limit_level_mismatch_at_node(), make_flags_parallel_consistent(), make_refinement_compatible(), libMesh::Parallel::Communicator::max(), libMesh::Parallel::Communicator::min(), libMesh::out, libMesh::MeshBase::prepare_for_use(), libMesh::Elem::refinement_flag(), libMesh::Elem::set_p_refinement_flag(), libMesh::Elem::set_refinement_flag(), and test_level_one().
Referenced by libMesh::EquationSystems::reinit().
{
// This function must be run on all processors at once
parallel_object_only();
bool _maintain_level_one = maintain_level_one;
// If the user used non-default parameters, let's warn that they're
// deprecated
if (!maintain_level_one)
{
libmesh_deprecated();
}
else
_maintain_level_one = _face_level_mismatch_limit;
if (_maintain_level_one)
libmesh_assert(test_level_one(true));
// Possibly clean up the refinement flags from
// a previous step
MeshBase::element_iterator elem_it = _mesh.elements_begin();
const MeshBase::element_iterator elem_end = _mesh.elements_end();
for ( ; elem_it != elem_end; ++elem_it)
{
// Pointer to the element
Elem *elem = *elem_it;
// Set refinement flag to INACTIVE if the
// element isn't active
if ( !elem->active())
{
elem->set_refinement_flag(Elem::INACTIVE);
elem->set_p_refinement_flag(Elem::INACTIVE);
}
// This might be left over from the last step
if (elem->refinement_flag() == Elem::JUST_REFINED)
elem->set_refinement_flag(Elem::DO_NOTHING);
}
// Parallel consistency has to come first, or coarsening
// along processor boundaries might occasionally be falsely
// prevented
bool flags_were_consistent = this->make_flags_parallel_consistent();
// In theory, we should be able to remove the above call, which can
// be expensive and should be unnecessary. In practice, doing
// consistent flagging in parallel is hard, it's impossible to
// verify at the library level if it's being done by user code, and
// we don't want to abort large parallel runs in opt mode... but we
// do want to warn that they should be fixed.
libmesh_assert(flags_were_consistent);
if (!flags_were_consistent)
{
libMesh::out << "Refinement flags were not consistent between processors!\n"
<< "Correcting and continuing.";
}
// Repeat until flag changes match on every processor
do
{
// Repeat until coarsening & refinement flags jive
bool satisfied = false;
do
{
const bool refinement_satisfied =
this->make_refinement_compatible(maintain_level_one);
bool smoothing_satisfied =
!this->eliminate_unrefined_patches();// &&
if (_edge_level_mismatch_limit)
smoothing_satisfied = smoothing_satisfied &&
!this->limit_level_mismatch_at_edge (_edge_level_mismatch_limit);
if (_node_level_mismatch_limit)
smoothing_satisfied = smoothing_satisfied &&
!this->limit_level_mismatch_at_node (_node_level_mismatch_limit);
satisfied = (refinement_satisfied &&
smoothing_satisfied);
#ifdef DEBUG
bool max_satisfied = satisfied,
min_satisfied = satisfied;
this->comm().max(max_satisfied);
this->comm().min(min_satisfied);
libmesh_assert_equal_to (satisfied, max_satisfied);
libmesh_assert_equal_to (satisfied, min_satisfied);
#endif
}
while (!satisfied);
}
while (!_mesh.is_serial() && !this->make_flags_parallel_consistent());
// Now refine the flagged elements. This will
// take up some space, maybe more than what was freed.
const bool mesh_changed =
this->_refine_elements();
if (_maintain_level_one)
libmesh_assert(test_level_one(true));
libmesh_assert(this->make_refinement_compatible(maintain_level_one));
// FIXME: This won't pass unless we add a redundant find_neighbors()
// call or replace find_neighbors() with on-the-fly neighbor updating
// libmesh_assert(!this->eliminate_unrefined_patches());
// Finally, the new mesh needs to be prepared for use
if (mesh_changed)
_mesh.prepare_for_use (/*skip_renumber =*/false);
return mesh_changed;
}
| Real & libMesh::MeshRefinement::refine_fraction | ( | ) | [inline] |
The refine_fraction sets either a desired target or a desired maximum number of elements to flag for refinement, depending on which flag_elements_by method is called.
refine_fraction must be in
, and is 0.3 by default.
Definition at line 795 of file mesh_refinement.h.
References _refine_fraction, and _use_member_parameters.
{
_use_member_parameters = true;
return _refine_fraction;
}
| void libMesh::MeshRefinement::set_enforce_mismatch_limit_prior_to_refinement | ( | bool | enforce | ) | [inline] |
Set _enforce_mismatch_limit_prior_to_refinement option. Defaults to false. Deprecated - use enforce_mismatch_limit_prior_to_refinement() instead.
Definition at line 852 of file mesh_refinement.h.
References enforce_mismatch_limit_prior_to_refinement().
{
libmesh_deprecated();
enforce_mismatch_limit_prior_to_refinement() = enforce;
}
| void libMesh::MeshRefinement::set_periodic_boundaries_ptr | ( | PeriodicBoundaries * | pb_ptr | ) |
Sets the PeriodicBoundaries pointer.
Definition at line 79 of file mesh_refinement.C.
References _periodic_boundaries.
{
_periodic_boundaries = pb_ptr;
}
Takes a mesh whose elements are flagged for h refinement and coarsening, and switches those flags to request p refinement and coarsening instead.
Definition at line 662 of file mesh_refinement_flagging.C.
References _mesh, libMesh::Elem::DO_NOTHING, libMesh::MeshBase::elements_begin(), libMesh::MeshBase::elements_end(), and libMesh::Elem::INACTIVE.
{
MeshBase::element_iterator elem_it = _mesh.elements_begin();
const MeshBase::element_iterator elem_end = _mesh.elements_end();
for ( ; elem_it != elem_end; ++elem_it)
{
if ((*elem_it)->active())
{
(*elem_it)->set_p_refinement_flag((*elem_it)->refinement_flag());
(*elem_it)->set_refinement_flag(Elem::DO_NOTHING);
}
else
{
(*elem_it)->set_p_refinement_flag((*elem_it)->refinement_flag());
(*elem_it)->set_refinement_flag(Elem::INACTIVE);
}
}
}
| bool libMesh::MeshRefinement::test_level_one | ( | bool | libmesh_assert_yes = false | ) |
Returns true if and only if the mesh is level one smooth Returns false otherwise Aborts the program if libmesh_assert_yes is true and the mesh is not level one smooth
Definition at line 304 of file mesh_refinement.C.
References _mesh, _periodic_boundaries, libMesh::Elem::active(), libMesh::MeshBase::active_local_elements_begin(), libMesh::MeshBase::active_local_elements_end(), libMesh::ParallelObject::comm(), libMesh::Elem::level(), libMesh::libmesh_assert(), libMesh::Parallel::Communicator::max(), libMesh::Elem::n_neighbors(), libMesh::out, libMesh::Elem::p_level(), libMesh::remote_elem, libMesh::MeshBase::sub_point_locator(), topological_neighbor(), and libMesh::Parallel::verify().
Referenced by coarsen_elements(), refine_and_coarsen_elements(), and refine_elements().
{
// This function must be run on all processors at once
parallel_object_only();
// We may need a PointLocator for topological_neighbor() tests
// later, which we need to make sure gets constructed on all
// processors at once.
UniquePtr<PointLocatorBase> point_locator;
#ifdef LIBMESH_ENABLE_PERIODIC
bool has_periodic_boundaries =
_periodic_boundaries && !_periodic_boundaries->empty();
libmesh_assert(this->comm().verify(has_periodic_boundaries));
if (has_periodic_boundaries)
point_locator = _mesh.sub_point_locator();
#endif
MeshBase::element_iterator elem_it = _mesh.active_local_elements_begin();
const MeshBase::element_iterator elem_end = _mesh.active_local_elements_end();
bool failure = false;
#ifndef NDEBUG
Elem *failed_elem = NULL;
Elem *failed_neighbor = NULL;
#endif // !NDEBUG
for ( ; elem_it != elem_end && !failure; ++elem_it)
{
// Pointer to the element
Elem *elem = *elem_it;
for (unsigned int n=0; n<elem->n_neighbors(); n++)
{
Elem *neighbor =
topological_neighbor(elem, point_locator.get(), n);
if (!neighbor || !neighbor->active() ||
neighbor == remote_elem)
continue;
if ((neighbor->level() + 1 < elem->level()) ||
(neighbor->p_level() + 1 < elem->p_level()) ||
(neighbor->p_level() > elem->p_level() + 1))
{
failure = true;
#ifndef NDEBUG
failed_elem = elem;
failed_neighbor = neighbor;
#endif // !NDEBUG
break;
}
}
}
// If any processor failed, we failed globally
this->comm().max(failure);
if (failure)
{
// We didn't pass the level one test, so libmesh_assert that
// we're allowed not to
#ifndef NDEBUG
if (libmesh_assert_pass)
{
libMesh::out <<
"MeshRefinement Level one failure, element: " <<
*failed_elem << std::endl;
libMesh::out <<
"MeshRefinement Level one failure, neighbor: " <<
*failed_neighbor << std::endl;
}
#endif // !NDEBUG
libmesh_assert(!libmesh_assert_pass);
return false;
}
return true;
}
| bool libMesh::MeshRefinement::test_unflagged | ( | bool | libmesh_assert_yes = false | ) |
Returns true if and only if the mesh has no elements flagged to be coarsened or refined Returns false otherwise Aborts the program if libmesh_assert_yes is true and the mesh has flagged elements
Definition at line 387 of file mesh_refinement.C.
References _mesh, libMesh::MeshBase::active_local_elements_begin(), libMesh::MeshBase::active_local_elements_end(), libMesh::Elem::COARSEN, libMesh::ParallelObject::comm(), libMesh::libmesh_assert(), libMesh::Parallel::Communicator::max(), libMesh::out, libMesh::Elem::p_refinement_flag(), libMesh::Elem::REFINE, and libMesh::Elem::refinement_flag().
Referenced by refine_and_coarsen_elements().
{
// This function must be run on all processors at once
parallel_object_only();
bool found_flag = false;
// Search for local flags
MeshBase::element_iterator elem_it = _mesh.active_local_elements_begin();
const MeshBase::element_iterator elem_end = _mesh.active_local_elements_end();
#ifndef NDEBUG
Elem *failed_elem = NULL;
#endif
for ( ; elem_it != elem_end; ++elem_it)
{
// Pointer to the element
Elem *elem = *elem_it;
if (elem->refinement_flag() == Elem::REFINE ||
elem->refinement_flag() == Elem::COARSEN ||
elem->p_refinement_flag() == Elem::REFINE ||
elem->p_refinement_flag() == Elem::COARSEN)
{
found_flag = true;
#ifndef NDEBUG
failed_elem = elem;
#endif
break;
}
}
// If we found a flag on any processor, it counts
this->comm().max(found_flag);
if (found_flag)
{
#ifndef NDEBUG
if (libmesh_assert_pass)
{
libMesh::out <<
"MeshRefinement test_unflagged failure, element: " <<
*failed_elem << std::endl;
}
#endif
// We didn't pass the "elements are unflagged" test,
// so libmesh_assert that we're allowed not to
libmesh_assert(!libmesh_assert_pass);
return false;
}
return true;
}
| Elem * libMesh::MeshRefinement::topological_neighbor | ( | Elem * | elem, |
| const PointLocatorBase * | point_locator, | ||
| const unsigned int | side | ||
| ) | [private] |
Local dispatch function for getting the correct topological neighbor from the Elem class
Definition at line 1795 of file mesh_refinement.C.
References _mesh, _periodic_boundaries, libMesh::libmesh_assert(), libMesh::Elem::neighbor(), and libMesh::Elem::topological_neighbor().
Referenced by make_coarsening_compatible(), make_refinement_compatible(), and test_level_one().
{
#ifdef LIBMESH_ENABLE_PERIODIC
if (_periodic_boundaries && !_periodic_boundaries->empty())
{
libmesh_assert(point_locator);
return elem->topological_neighbor(side, _mesh, *point_locator, _periodic_boundaries);
}
#endif
return elem->neighbor(side);
}
| void libMesh::MeshRefinement::uniformly_coarsen | ( | unsigned int | n = 1 | ) |
Attempts to uniformly coarsen the mesh n times.
Definition at line 1764 of file mesh_refinement.C.
References _coarsen_elements(), _mesh, libMesh::MeshBase::active_elements_begin(), libMesh::MeshBase::active_elements_end(), clean_refinement_flags(), libMesh::Elem::COARSEN, libMesh::Elem::COARSEN_INACTIVE, and libMesh::MeshBase::prepare_for_use().
Referenced by libMesh::UniformRefinementEstimator::_estimate_error(), and libMesh::AdjointRefinementEstimator::estimate_error().
{
// Coarsen n times
for (unsigned int rstep=0; rstep<n; rstep++)
{
// Clean up the refinement flags
this->clean_refinement_flags();
// Flag all the active elements for coarsening
MeshBase::element_iterator elem_it = _mesh.active_elements_begin();
const MeshBase::element_iterator elem_end = _mesh.active_elements_end();
for ( ; elem_it != elem_end; ++elem_it)
{
(*elem_it)->set_refinement_flag(Elem::COARSEN);
if ((*elem_it)->parent())
(*elem_it)->parent()->set_refinement_flag(Elem::COARSEN_INACTIVE);
}
// Coarsen all the elements we just flagged.
this->_coarsen_elements();
}
// Finally, the new mesh probably needs to be prepared for use
if (n > 0)
_mesh.prepare_for_use (/*skip_renumber =*/false);
}
| void libMesh::MeshRefinement::uniformly_p_coarsen | ( | unsigned int | n = 1 | ) |
Attempts to uniformly p coarsen the mesh n times.
Definition at line 1714 of file mesh_refinement.C.
References _mesh, libMesh::MeshBase::active_elements_begin(), libMesh::MeshBase::active_elements_end(), and libMesh::Elem::JUST_COARSENED.
Referenced by libMesh::UniformRefinementEstimator::_estimate_error(), and libMesh::AdjointRefinementEstimator::estimate_error().
{
// Coarsen p times
for (unsigned int rstep=0; rstep<n; rstep++)
{
// P coarsen all the active elements
MeshBase::element_iterator elem_it = _mesh.active_elements_begin();
const MeshBase::element_iterator elem_end = _mesh.active_elements_end();
for ( ; elem_it != elem_end; ++elem_it)
{
if ((*elem_it)->p_level() > 0)
{
(*elem_it)->set_p_level((*elem_it)->p_level()-1);
(*elem_it)->set_p_refinement_flag(Elem::JUST_COARSENED);
}
}
}
}
| void libMesh::MeshRefinement::uniformly_p_refine | ( | unsigned int | n = 1 | ) |
Uniformly p refines the mesh n times.
Definition at line 1695 of file mesh_refinement.C.
References _mesh, libMesh::MeshBase::active_elements_begin(), libMesh::MeshBase::active_elements_end(), and libMesh::Elem::JUST_REFINED.
Referenced by libMesh::UniformRefinementEstimator::_estimate_error(), and libMesh::AdjointRefinementEstimator::estimate_error().
{
// Refine n times
for (unsigned int rstep=0; rstep<n; rstep++)
{
// P refine all the active elements
MeshBase::element_iterator elem_it = _mesh.active_elements_begin();
const MeshBase::element_iterator elem_end = _mesh.active_elements_end();
for ( ; elem_it != elem_end; ++elem_it)
{
(*elem_it)->set_p_level((*elem_it)->p_level()+1);
(*elem_it)->set_p_refinement_flag(Elem::JUST_REFINED);
}
}
}
| void libMesh::MeshRefinement::uniformly_refine | ( | unsigned int | n = 1 | ) |
Uniformly refines the mesh n times.
Definition at line 1736 of file mesh_refinement.C.
References _mesh, _refine_elements(), libMesh::MeshBase::active_elements_begin(), libMesh::MeshBase::active_elements_end(), clean_refinement_flags(), libMesh::MeshBase::prepare_for_use(), and libMesh::Elem::REFINE.
Referenced by libMesh::UniformRefinementEstimator::_estimate_error(), and libMesh::AdjointRefinementEstimator::estimate_error().
{
// Refine n times
// FIXME - this won't work if n>1 and the mesh
// has already been attached to an equation system
for (unsigned int rstep=0; rstep<n; rstep++)
{
// Clean up the refinement flags
this->clean_refinement_flags();
// Flag all the active elements for refinement.
MeshBase::element_iterator elem_it = _mesh.active_elements_begin();
const MeshBase::element_iterator elem_end = _mesh.active_elements_end();
for ( ; elem_it != elem_end; ++elem_it)
(*elem_it)->set_refinement_flag(Elem::REFINE);
// Refine all the elements we just flagged.
this->_refine_elements();
}
// Finally, the new mesh probably needs to be prepared for use
if (n > 0)
_mesh.prepare_for_use (/*skip_renumber =*/false);
}
| void libMesh::MeshRefinement::update_nodes_map | ( | ) | [private] |
Updates the _new_nodes_map
Definition at line 297 of file mesh_refinement.C.
References _mesh, _new_nodes_map, and libMesh::LocationMap< T >::init().
Referenced by _coarsen_elements(), and _refine_elements().
{
this->_new_nodes_map.init(_mesh);
}
Definition at line 691 of file mesh_refinement.h.
Referenced by absolute_global_tolerance(), and flag_elements_by_error_tolerance().
bool libMesh::MeshRefinement::_coarsen_by_parents [private] |
Refinement parameter values
Definition at line 679 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().
Definition at line 683 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().
Definition at line 687 of file mesh_refinement.h.
Referenced by coarsen_threshold(), flag_elements_by_error_tolerance(), and flag_elements_by_nelem_target().
const Parallel::Communicator& libMesh::ParallelObject::_communicator [protected, inherited] |
Definition at line 104 of file parallel_object.h.
Referenced by libMesh::EquationSystems::build_solution_vector(), libMesh::ParallelObject::comm(), libMesh::EquationSystems::get_solution(), libMesh::ParallelObject::n_processors(), libMesh::ParallelObject::operator=(), and libMesh::ParallelObject::processor_id().
unsigned char libMesh::MeshRefinement::_edge_level_mismatch_limit [private] |
Definition at line 693 of file mesh_refinement.h.
Referenced by coarsen_elements(), edge_level_mismatch_limit(), refine_and_coarsen_elements(), and refine_elements().
This option enforces the mismatch level prior to refinement by checking if refining any element marked for refinement would cause a mismatch greater than the limit. Applies to all mismatch methods.
Calling this with node_level_mismatch_limit() = 1 would transform this mesh:
* o-------o-------o-------o-------o * | | | | | * | | | | | * | | | | | * | | | | | * | | | | | * o-------o---o---o-------o-------o * | | : | | | * | | : | | | * | o...o...o | | * | | : | | | * | | : | | | * o-------o---o---o-------o-------o * | | | | * | | | | * | | | | * | | | | * | | | | * o-------o-------o | * | | | | * | | | | * | | | | * | | | | * | | | | * o-------o-------o---------------o *
into this:
* o-------o-------o-------o-------o * | | | | | * | | | | | * | | | | | * | | | | | * | | | | | * o-------o-------o-------o-------o * | | | | | * | | | | | * | | | | | * | | | | | * | | | | | * o-------o-------o-------o-------o * | | | : | * | | | : | * | | | : | * | | | : | * | | | : | * o-------o-------o.......o.......o * | | | : | * | | | : | * | | | : | * | | | : | * | | | : | * o-------o-------o-------o-------o *
by moving the refinement flag to the indicated element.
Default value is false.
Definition at line 764 of file mesh_refinement.h.
Referenced by enforce_mismatch_limit_prior_to_refinement(), limit_level_mismatch_at_edge(), and limit_level_mismatch_at_node().
unsigned char libMesh::MeshRefinement::_face_level_mismatch_limit [private] |
Definition at line 693 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 libMesh::MeshRefinement::_max_h_level [private] |
Definition at line 685 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& libMesh::MeshRefinement::_mesh [private] |
Reference to the mesh.
Definition at line 666 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(), has_topological_neighbor(), 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(), topological_neighbor(), uniformly_coarsen(), uniformly_p_coarsen(), uniformly_p_refine(), uniformly_refine(), and update_nodes_map().
Definition at line 689 of file mesh_refinement.h.
Referenced by flag_elements_by_nelem_target(), and nelem_target().
Data structure that holds the new nodes information.
Definition at line 661 of file mesh_refinement.h.
Referenced by add_point(), clear(), and update_nodes_map().
unsigned char libMesh::MeshRefinement::_node_level_mismatch_limit [private] |
Definition at line 693 of file mesh_refinement.h.
Referenced by coarsen_elements(), node_level_mismatch_limit(), refine_and_coarsen_elements(), and refine_elements().
Definition at line 780 of file mesh_refinement.h.
Referenced by has_topological_neighbor(), make_coarsening_compatible(), make_refinement_compatible(), set_periodic_boundaries_ptr(), test_level_one(), and topological_neighbor().
Definition at line 681 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 libMesh::MeshRefinement::_use_member_parameters [private] |
For backwards compatibility, we initialize this as false and then set it to true if the user uses any of the refinement parameter accessor functions
Definition at line 673 of file mesh_refinement.h.
Referenced by absolute_global_tolerance(), coarsen_by_parents(), coarsen_fraction(), coarsen_threshold(), flag_elements_by_elem_fraction(), flag_elements_by_error_fraction(), flag_elements_by_mean_stddev(), max_h_level(), nelem_target(), and refine_fraction().