28 #ifdef LIBMESH_ENABLE_AMR 47 #ifdef LIBMESH_ENABLE_PERIODIC 96 _use_member_parameters(false),
97 _coarsen_by_parents(false),
98 _refine_fraction(0.3),
99 _coarsen_fraction(0.0),
101 _coarsen_threshold(10),
103 _absolute_global_tolerance(0.0),
104 _face_level_mismatch_limit(1),
105 _edge_level_mismatch_limit(0),
106 _node_level_mismatch_limit(0),
107 _overrefined_boundary_limit(0),
108 _underrefined_boundary_limit(0),
109 _enforce_mismatch_limit_prior_to_refinement(false)
110 #ifdef LIBMESH_ENABLE_PERIODIC
111 , _periodic_boundaries(nullptr)
118 #ifdef LIBMESH_ENABLE_PERIODIC 146 LOG_SCOPE(
"add_node()",
"MeshRefinement");
153 const std::vector<std::pair<dof_id_type, dof_id_type>>
158 libmesh_assert(bracketing_nodes.size());
187 libmesh_assert_not_equal_to (em_val, 1);
196 libmesh_assert(new_node);
212 libmesh_assert(elem);
221 Real & parent_error_min,
222 Real & parent_error_max)
225 parallel_object_only();
229 for (std::size_t i=0; i != error_per_cell.size(); ++i)
231 libmesh_assert_greater_equal (error_per_cell[i], 0);
234 libmesh_assert(!isnan(error_per_cell[i]));
240 std::vector<ErrorVectorReal> & epc = error_per_parent;
241 libmesh_assert(this->
comm().verify(epc));
242 #endif // #ifdef DEBUG 245 error_per_parent.clear();
246 error_per_parent.resize(error_per_cell.size(), 0.0);
255 error_per_parent[elem->id()] = -1.0;
260 parent = parent->
parent();
264 libmesh_assert_less (parentid, error_per_parent.size());
265 error_per_parent[parentid] = -1.0;
273 std::vector<ErrorVectorReal> & epp = error_per_parent;
293 libmesh_assert_less (parentid, error_per_parent.size());
298 if (error_per_parent[parentid] != -1.0)
299 error_per_parent[parentid] += (error_per_cell[elem->id()] *
300 error_per_cell[elem->id()]);
305 this->
comm().
sum(
static_cast<std::vector<ErrorVectorReal> &
>(error_per_parent));
309 parent_error_max = 0.;
311 for (std::size_t i = 0; i != error_per_parent.size(); ++i)
318 if (error_per_parent[i] < 0.)
320 error_per_parent[i] = -1.;
327 if (error_per_cell[i])
329 error_per_parent[i] = error_per_cell[i];
334 error_per_parent[i] = std::sqrt(error_per_parent[i]);
336 parent_error_min =
std::min (parent_error_min,
337 error_per_parent[i]);
338 parent_error_max =
std::max (parent_error_max,
339 error_per_parent[i]);
355 parallel_object_only();
360 std::unique_ptr<PointLocatorBase> point_locator;
362 #ifdef LIBMESH_ENABLE_PERIODIC 363 bool has_periodic_boundaries =
365 libmesh_assert(this->
comm().verify(has_periodic_boundaries));
367 if (has_periodic_boundaries)
371 bool failure =
false;
374 Elem * failed_elem =
nullptr;
375 Elem * failed_neighbor =
nullptr;
379 for (
auto n : elem->side_index_range())
384 if (!neighbor || !neighbor->
active() ||
388 if ((neighbor->
level() + 1 < elem->level()) ||
389 (neighbor->
p_level() + 1 < elem->p_level()) ||
390 (neighbor->
p_level() > elem->p_level() + 1))
395 failed_neighbor = neighbor;
409 if (libmesh_assert_pass)
411 libMesh::out <<
"MeshRefinement Level one failure, element: " 414 libMesh::out <<
"MeshRefinement Level one failure, neighbor: " 419 libmesh_assert(!libmesh_assert_pass);
430 parallel_object_only();
432 bool found_flag =
false;
435 Elem * failed_elem =
nullptr;
458 if (libmesh_assert_pass)
461 "MeshRefinement test_unflagged failure, element: " <<
462 *failed_elem << std::endl;
467 libmesh_assert(!libmesh_assert_pass);
478 parallel_object_only();
487 bool elements_flagged =
false;
496 if ( !elem->active())
503 else if (!elements_flagged)
506 elements_flagged =
true;
510 elem->p_refinement_flag();
512 elements_flagged =
true;
522 if (!elements_flagged)
531 libmesh_assert (flags_were_consistent);
538 const bool coarsening_changed_mesh =
561 const bool refining_changed_mesh =
566 if (coarsening_changed_mesh || refining_changed_mesh)
610 parallel_object_only();
644 libmesh_assert(flags_were_consistent);
645 if (!flags_were_consistent)
647 libMesh::out <<
"Refinement flags were not consistent between processors!\n" 648 <<
"Correcting and continuing.";
655 const bool mesh_changed =
685 parallel_object_only();
720 libmesh_assert(flags_were_consistent);
721 if (!flags_were_consistent)
723 libMesh::out <<
"Refinement flags were not consistent between processors!\n" 724 <<
"Correcting and continuing.";
732 const bool mesh_changed =
754 parallel_object_only();
756 LOG_SCOPE (
"make_flags_parallel_consistent()",
"MeshRefinement");
771 psync.parallel_consistent;
772 this->
comm().
min(parallel_consistent);
774 return parallel_consistent;
782 parallel_object_only();
787 std::unique_ptr<PointLocatorBase> point_locator;
789 #ifdef LIBMESH_ENABLE_PERIODIC 790 bool has_periodic_boundaries =
792 libmesh_assert(this->
comm().verify(has_periodic_boundaries));
794 if (has_periodic_boundaries)
798 LOG_SCOPE (
"make_coarsening_compatible()",
"MeshRefinement");
802 bool level_one_satisfied =
true;
807 bool compatible_with_refinement =
true;
812 unsigned int max_p_level = 0;
823 static_cast<unsigned int>(elem->p_level()));
825 if ((elem->level() == 0) &&
829 if ((elem->p_level() == 0) &&
843 this->
comm().
min(compatible_with_refinement);
845 return compatible_with_refinement;
859 level_one_satisfied =
true;
863 level_one_satisfied =
true;
867 bool my_flag_changed =
false;
872 const unsigned int my_level = elem->level();
874 for (
auto n : elem->side_index_range())
876 const Elem * neighbor =
879 if (neighbor !=
nullptr &&
884 if ((neighbor->
level() == my_level) &&
889 my_flag_changed =
true;
899 my_flag_changed =
true;
908 const unsigned int my_p_level = elem->p_level();
910 for (
auto n : elem->side_index_range())
912 const Elem * neighbor =
915 if (neighbor !=
nullptr &&
920 if ((neighbor->
p_level() > my_p_level &&
922 || (neighbor->
p_level() == my_p_level &&
926 my_flag_changed =
true;
943 if ((subneighbor.p_level() > my_p_level &&
945 || (subneighbor.p_level() == my_p_level &&
949 my_flag_changed =
true;
962 level_one_satisfied =
false;
970 for (
auto n : elem->side_index_range())
981 compatible_with_refinement =
false;
992 compatible_with_refinement =
false;
998 while (!level_one_satisfied);
1009 for (
int level =
max_level; level >= 0; level--)
1011 if (elem->ancestor())
1015 bool is_a_candidate =
true;
1016 bool found_remote_child =
false;
1018 for (
auto & child : elem->child_ref_range())
1021 found_remote_child =
true;
1024 is_a_candidate =
false;
1027 if (!is_a_candidate && !found_remote_child)
1031 for (
auto & child : elem->child_ref_range())
1037 level_one_satisfied =
false;
1063 std::vector<std::vector<dof_id_type>>
1064 uncoarsenable_parents(n_proc);
1070 bool all_children_flagged_for_coarsening =
true;
1072 for (
auto & child : elem->child_ref_range())
1077 all_children_flagged_for_coarsening =
false;
1078 if (!distributed_mesh)
1080 if (child.processor_id() != elem->processor_id())
1082 uncoarsenable_parents[elem->processor_id()].push_back(elem->id());
1088 if (all_children_flagged_for_coarsening)
1096 if (distributed_mesh)
1099 parallel_object_only();
1103 std::vector<Parallel::Request> uncoarsenable_push_requests(n_proc-1);
1107 if (p == my_proc_id)
1111 uncoarsenable_push_requests[p - (p > my_proc_id)];
1114 (p, uncoarsenable_parents[p],
request, uncoarsenable_tag);
1119 std::vector<dof_id_type> my_uncoarsenable_parents;
1124 for (
const auto &
id : my_uncoarsenable_parents)
1147 this->
comm().
min(compatible_with_refinement);
1149 return compatible_with_refinement;
1162 parallel_object_only();
1167 std::unique_ptr<PointLocatorBase> point_locator;
1169 #ifdef LIBMESH_ENABLE_PERIODIC 1170 bool has_periodic_boundaries =
1172 libmesh_assert(this->
comm().verify(has_periodic_boundaries));
1174 if (has_periodic_boundaries)
1178 LOG_SCOPE (
"make_refinement_compatible()",
"MeshRefinement");
1182 bool compatible_with_coarsening =
true;
1190 bool level_one_satisfied =
true;
1194 level_one_satisfied =
true;
1198 const unsigned short n_sides = elem->n_sides();
1203 const unsigned int my_level = elem->level();
1205 for (
unsigned short side = 0;
side != n_sides;
1211 if (neighbor !=
nullptr &&
1219 if (neighbor->
level() == my_level)
1226 compatible_with_coarsening =
false;
1227 level_one_satisfied =
false;
1238 else if ((neighbor->
level()+1) == my_level)
1245 compatible_with_coarsening =
false;
1246 level_one_satisfied =
false;
1254 libmesh_error_msg(
"ERROR: Neighbor level must be equal or 1 higher than mine.");
1262 const unsigned int my_p_level = elem->p_level();
1269 if (neighbor !=
nullptr &&
1274 if (neighbor->
p_level() < my_p_level &&
1278 level_one_satisfied =
false;
1279 compatible_with_coarsening =
false;
1281 if (neighbor->
p_level() == my_p_level &&
1285 level_one_satisfied =
false;
1286 compatible_with_coarsening =
false;
1296 if (subneighbor.p_level() < my_p_level &&
1301 libmesh_assert_greater (subneighbor.p_level() + 2u,
1304 level_one_satisfied =
false;
1305 compatible_with_coarsening =
false;
1307 if (subneighbor.p_level() == my_p_level &&
1311 level_one_satisfied =
false;
1312 compatible_with_coarsening =
false;
1322 while (!level_one_satisfied);
1327 this->
comm().
min(compatible_with_coarsening);
1329 return compatible_with_coarsening;
1338 parallel_object_only();
1340 LOG_SCOPE (
"_coarsen_elements()",
"MeshRefinement");
1343 bool mesh_changed =
false;
1344 bool mesh_p_changed =
false;
1361 mesh_changed =
true;
1366 this->
comm().
max(mesh_changed);
1380 libmesh_assert_not_equal_to (elem->level(), 0);
1384 elem->nullify_neighbors();
1405 libmesh_assert (elem->active());
1408 mesh_changed =
true;
1412 if (elem->p_level() > 0)
1415 elem->set_p_level(elem->p_level() - 1);
1416 mesh_p_changed =
true;
1425 this->
comm().
max(mesh_p_changed);
1445 MeshTools::libmesh_assert_valid_procids<Node>(
_mesh);
1456 return (mesh_changed || mesh_p_changed);
1464 parallel_object_only();
1470 LOG_SCOPE (
"_refine_elements()",
"MeshRefinement");
1483 std::vector<Elem *> local_copy_of_elements;
1484 local_copy_of_elements.reserve(n_elems_flagged);
1488 bool mesh_p_changed =
false;
1518 local_copy_of_elements.push_back(elem);
1522 elem->set_p_level(elem->p_level()+1);
1524 mesh_p_changed =
true;
1534 local_copy_of_elements.push_back(elem);
1538 elem->set_p_level(elem->p_level()+1);
1540 mesh_p_changed =
true;
1549 for (std::size_t e = 0; e != local_copy_of_elements.size(); ++e)
1550 local_copy_of_elements[e]->refine(*
this);
1553 bool mesh_changed = !local_copy_of_elements.empty();
1556 this->
comm().
max(mesh_changed);
1557 this->
comm().
max(mesh_p_changed);
1588 return (mesh_changed || mesh_p_changed);
1603 bool satisfied =
false;
1608 const bool coarsening_satisfied =
1612 const bool refinement_satisfied =
1616 bool smoothing_satisfied =
1620 smoothing_satisfied = smoothing_satisfied &&
1624 smoothing_satisfied = smoothing_satisfied &&
1628 smoothing_satisfied = smoothing_satisfied &&
1632 smoothing_satisfied = smoothing_satisfied &&
1635 satisfied = (coarsening_satisfied &&
1636 refinement_satisfied &&
1637 smoothing_satisfied);
1639 libmesh_assert(this->
comm().verify(satisfied));
1650 for (
unsigned int rstep=0; rstep<n; rstep++)
1654 elem->set_p_level(elem->p_level()+1);
1664 for (
unsigned int rstep=0; rstep<n; rstep++)
1666 if (elem->p_level() > 0)
1669 elem->set_p_level(elem->p_level()-1);
1681 for (
unsigned int rstep=0; rstep<n; rstep++)
1704 for (
unsigned int rstep=0; rstep<n; rstep++)
1725 std::vector<std::vector<dof_id_type>>
1726 parents_to_coarsen(n_proc);
1729 if (elem->processor_id() != my_proc_id &&
1731 parents_to_coarsen[elem->processor_id()].push_back(elem->id());
1735 std::vector<Parallel::Request> coarsen_push_requests(n_proc-1);
1739 if (p == my_proc_id)
1743 coarsen_push_requests[p - (p > my_proc_id)];
1746 (p, parents_to_coarsen[p],
request, coarsen_tag);
1751 std::vector<dof_id_type> my_parents_to_coarsen;
1756 for (
const auto &
id : my_parents_to_coarsen)
1791 const unsigned int side)
1793 #ifdef LIBMESH_ENABLE_PERIODIC 1796 libmesh_assert(point_locator);
1807 const Elem * neighbor)
1809 #ifdef LIBMESH_ENABLE_PERIODIC 1812 libmesh_assert(point_locator);
bool limit_level_mismatch_at_edge(const unsigned int max_mismatch)
bool has_neighbor(const Elem *elem) const
RefinementState refinement_flag() const
void send(const unsigned int dest_processor_id, const T &buf, const MessageTag &tag=no_tag) const
virtual element_iterator ancestor_elements_begin()=0
void uniformly_p_refine(unsigned int n=1)
void wait(std::vector< Request > &r)
const Elem * parent() const
virtual const std::vector< std::pair< dof_id_type, dof_id_type > > bracketing_nodes(unsigned int c, unsigned int n) const
A geometric point in (x,y,z) space associated with a DOF.
const unsigned int invalid_uint
virtual element_iterator not_local_elements_end()=0
std::unique_ptr< PointLocatorBase > sub_point_locator() const
bool limit_level_mismatch_at_node(const unsigned int max_mismatch)
virtual element_iterator level_elements_begin(unsigned int level)=0
const Elem * topological_neighbor(const unsigned int i, const MeshBase &mesh, const PointLocatorBase &point_locator, const PeriodicBoundaries *pb) const
const unsigned int any_source
TopologyMap _new_nodes_map
bool limit_underrefined_boundary(const signed char max_mismatch)
void add_scaled(const TypeVector< T2 > &, const T)
Maps between boundary ids and PeriodicBoundaryBase objects.
void make_elems_parallel_consistent(MeshBase &)
static void set_node_processor_ids(MeshBase &mesh)
dof_id_type find(dof_id_type bracket_node1, dof_id_type bracket_node2) const
virtual element_iterator unpartitioned_elements_begin()=0
RefinementState p_refinement_flag() const
void add_node(const Node &mid_node, const std::vector< std::pair< dof_id_type, dof_id_type >> &bracketing_nodes)
void remove(const Node *node)
The base class for all geometric element types.
virtual element_iterator ancestor_elements_end()=0
uint8_t processor_id_type
void uniformly_p_coarsen(unsigned int n=1)
void set_refinement_flag(const RefinementState rflag)
virtual float embedding_matrix(const unsigned int child_num, const unsigned int child_node_num, const unsigned int parent_node_num) const =0
const Parallel::Communicator & comm() const
bool limit_overrefined_boundary(const signed char max_mismatch)
unsigned int p_level() const
void clean_refinement_flags()
void create_parent_error_vector(const ErrorVector &error_per_cell, ErrorVector &error_per_parent, Real &parent_error_min, Real &parent_error_max)
virtual SimpleRange< element_iterator > active_element_ptr_range()=0
MessageTag get_unique_tag(int tagvalue) const
const BoundaryInfo & get_boundary_info() const
long double max(long double a, double b)
PeriodicBoundaries * _periodic_boundaries
signed char _underrefined_boundary_limit
virtual Node * add_point(const Point &p, const dof_id_type id=DofObject::invalid_id, const processor_id_type proc_id=DofObject::invalid_processor_id)=0
SimpleRange< ChildRefIter > child_ref_range()
bool make_refinement_compatible()
bool has_topological_neighbor(const Elem *elem, const MeshBase &mesh, const PointLocatorBase &point_locator, const PeriodicBoundaries *pb) const
virtual element_iterator elements_begin()=0
virtual SimpleRange< element_iterator > active_local_element_ptr_range()=0
virtual element_iterator level_elements_end(unsigned int level)=0
processor_id_type n_processors() const
virtual bool is_serial() const
bool test_level_one(bool libmesh_assert_yes=false)
virtual SimpleRange< element_iterator > element_ptr_range()=0
unsigned char _face_level_mismatch_limit
static const processor_id_type invalid_processor_id
virtual unsigned int as_parent_node(unsigned int c, unsigned int n) const
virtual Elem * add_elem(Elem *e)=0
virtual void update_parallel_id_counts()=0
virtual element_iterator elements_end()=0
void uniformly_coarsen(unsigned int n=1)
void make_p_levels_parallel_consistent(MeshBase &)
SimpleRange< I > as_range(const std::pair< I, I > &p)
static const dof_id_type invalid_id
bool make_flags_parallel_consistent()
void prepare_for_use(const bool skip_renumber_nodes_and_elements=false, const bool skip_find_neighbors=false)
signed char _overrefined_boundary_limit
bool make_coarsening_compatible()
void sync_dofobject_data_by_id(const Communicator &comm, const Iterator &range_begin, const Iterator &range_end, SyncFunctor &sync)
An object whose state is distributed along a set of processors.
bool has_topological_neighbor(const Elem *elem, const PointLocatorBase *point_locator, const Elem *neighbor)
MeshRefinement(MeshBase &mesh)
Node * add_node(Elem &parent, unsigned int child, unsigned int node, processor_id_type proc_id)
void send_coarse_ghosts(MeshBase &) const
unsigned char _node_level_mismatch_limit
const Elem * neighbor_ptr(unsigned int i) const
virtual element_iterator active_not_local_elements_end()=0
unsigned int level() const
bool test_unflagged(bool libmesh_assert_yes=false)
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
Elem * add_elem(Elem *elem)
const Node * node_ptr(const unsigned int i) const
void make_nodes_parallel_consistent(MeshBase &)
bool refine_and_coarsen_elements()
virtual bool is_replicated() const
virtual const Elem & elem_ref(const dof_id_type i) const
Status receive(const unsigned int dest_processor_id, T &buf, const MessageTag &tag=any_tag) const
virtual element_iterator unpartitioned_elements_end()=0
IntRange< unsigned short > node_index_range() const
void _smooth_flags(bool refining, bool coarsening)
virtual element_iterator active_not_local_elements_begin()=0
virtual void libmesh_assert_valid_parallel_ids() const
unsigned char _edge_level_mismatch_limit
void set_p_refinement_flag(const RefinementState pflag)
virtual element_iterator not_local_elements_begin()=0
virtual const Node * node_ptr(const dof_id_type i) const =0
bool eliminate_unrefined_patches()
processor_id_type processor_id() const
void make_new_nodes_parallel_consistent(MeshBase &)
OStreamProxy out(std::cout)
processor_id_type processor_id() const
void set_periodic_boundaries_ptr(PeriodicBoundaries *pb_ptr)
Elem * topological_neighbor(Elem *elem, const PointLocatorBase *point_locator, const unsigned int side)
long double min(long double a, double b)
A geometric point in (x,y,z) space.
const Point & point(const unsigned int i) const
bool has_children() const
void uniformly_refine(unsigned int n=1)
const RemoteElem * remote_elem