21#include "libmesh/libmesh_config.h"
24#include "libmesh/boundary_info.h"
25#include "libmesh/libmesh_logging.h"
26#include "libmesh/elem.h"
27#include "libmesh/ghost_point_neighbors.h"
28#include "libmesh/mesh_base.h"
29#include "libmesh/mesh_communication.h"
30#include "libmesh/mesh_serializer.h"
31#include "libmesh/mesh_tools.h"
32#include "libmesh/parallel.h"
33#include "libmesh/parallel_algebra.h"
34#include "libmesh/parallel_fe_type.h"
35#include "libmesh/partitioner.h"
36#include "libmesh/point_locator_base.h"
37#include "libmesh/sparse_matrix.h"
38#include "libmesh/threads.h"
39#include "libmesh/enum_elem_type.h"
40#include "libmesh/enum_point_locator_type.h"
41#include "libmesh/enum_to_string.h"
42#include "libmesh/point_locator_nanoflann.h"
43#include "libmesh/elem_side_builder.h"
44#include "libmesh/elem_range.h"
45#include "libmesh/node_range.h"
52#include <unordered_map>
54#include "libmesh/periodic_boundaries.h"
55#include "libmesh/periodic_boundary.h"
70 _default_mapping_data(0),
72 _element_stored_range (),
73 _const_active_local_element_stored_range (),
75 _count_lower_dim_elems_in_point_locator(true),
77#ifdef LIBMESH_ENABLE_UNIQUE_ID
78 _next_unique_id(
DofObject::invalid_unique_id),
81 _skip_noncritical_partitioning(false),
83 _skip_renumber_nodes_and_elements(false),
84 _skip_find_neighbors(false),
85 _skip_detect_interior_parents(false),
86 _allow_remote_element_removal(true),
87 _allow_node_and_elem_unique_id_overlap(false),
88 _spatial_dimension(d),
90 _point_locator_close_to_point_tol(0.)
94 libmesh_assert_less_equal (LIBMESH_DIM, 3);
95 libmesh_assert_greater_equal (LIBMESH_DIM, d);
104 _n_parts (other_mesh._n_parts),
105 _default_mapping_type(other_mesh._default_mapping_type),
106 _default_mapping_data(other_mesh._default_mapping_data),
107 _preparation (other_mesh._preparation),
108 _element_stored_range (),
109 _const_active_local_element_stored_range (),
111 _count_lower_dim_elems_in_point_locator(other_mesh._count_lower_dim_elems_in_point_locator),
113#ifdef LIBMESH_ENABLE_UNIQUE_ID
114 _next_unique_id(other_mesh._next_unique_id),
118 _interior_mesh((other_mesh._interior_mesh == &other_mesh) ?
119 this : other_mesh._interior_mesh),
120 _skip_noncritical_partitioning(other_mesh._skip_noncritical_partitioning),
121 _skip_all_partitioning(other_mesh._skip_all_partitioning),
122 _skip_renumber_nodes_and_elements(other_mesh._skip_renumber_nodes_and_elements),
123 _skip_find_neighbors(other_mesh._skip_find_neighbors),
124 _skip_detect_interior_parents(other_mesh._skip_detect_interior_parents),
125 _allow_remote_element_removal(other_mesh._allow_remote_element_removal),
126 _allow_node_and_elem_unique_id_overlap(other_mesh._allow_node_and_elem_unique_id_overlap),
127 _elem_dims(other_mesh._elem_dims),
128 _elem_default_orders(other_mesh._elem_default_orders),
129 _supported_nodal_order(other_mesh._supported_nodal_order),
130 _mesh_subdomains(other_mesh._mesh_subdomains),
131 _elemset_codes_inverse_map(other_mesh._elemset_codes_inverse_map),
132 _all_elemset_ids(other_mesh._all_elemset_ids),
133 _spatial_dimension(other_mesh._spatial_dimension),
135 _point_locator_close_to_point_tol(other_mesh._point_locator_close_to_point_tol)
143 if (gf == other_default_ghosting)
149 std::shared_ptr<GhostingFunctor> clone_gf = gf->clone();
158 clone_gf->set_mesh(
this);
163 libmesh_deprecated();
171#ifdef LIBMESH_ENABLE_PERIODIC
179 (*_disjoint_neighbor_boundary_pairs)[id] = pb->clone();
191 LOG_SCOPE(
"operator=(&&)",
"MeshBase");
196 _n_parts = other_mesh.n_partitions();
204#ifdef LIBMESH_ENABLE_UNIQUE_ID
210 this : other_mesh._interior_mesh;
219 _elem_dims = std::move(other_mesh.elem_dimensions());
233#ifdef LIBMESH_ENABLE_PERIODIC
237 if (other_mesh._disjoint_neighbor_boundary_pairs)
241 for (
const auto & [
id, pb] : *other_mesh._disjoint_neighbor_boundary_pairs)
243 (*_disjoint_neighbor_boundary_pairs)[id] = pb->clone();
258 "Elemset code " << code <<
" not found in _elmset_codes container.");
259 libmesh_assert_equal_to(it->second, &set);
273 LOG_SCOPE(
"operator==()",
"MeshBase");
376 auto it = other_rows.find(other_node);
377 if (it == other_rows.end())
380 const auto & other_row = it->second;
381 if (row.size() != other_row.size())
386 const auto & [elem_pair, coef] = row[i];
387 const auto & [other_elem_pair, other_coef] = other_row[i];
390 if (elem_pair.first->id() !=
391 other_elem_pair.first->id() ||
393 other_elem_pair.second ||
399 for (
const auto & [elemset_code, elemset_ptr] : this->
_elemset_codes)
401 it == other_mesh.
_elemset_codes.end() || *elemset_ptr != *it->second)
433 return cast_int<unsigned int>(*
_elem_dims.rbegin());
444 parallel_object_only();
448 "Specified element dimensions does not match true element dimensions!");
462 const auto & inserted_id_set = it1->first;
472 auto [it2, inserted2] =
_elemset_codes.emplace(code, &inserted_id_set);
476 libmesh_error_msg_if(!inserted2 && it2->second != &inserted_id_set,
477 "The elemset code " << code <<
" already exists with a different id_set.");
490 id_set_to_fill.clear();
494 id_set_to_fill.insert(it->second->begin(), it->second->end());
505 std::vector<dof_id_type> ret;
508 ret.push_back(pr.first);
531 "Expected _elemset_codes_inverse_map entry for elemset code " << old_code);
552 [elemset_index, old_code, new_code](
const ElemRange & range)
554 for (
Elem * elem : range)
557 elem->get_extra_integer(elemset_index);
559 if (elemset_code == old_code)
560 elem->set_extra_integer(elemset_index, new_code);
573 "Cannot change elemset id " << old_id <<
574 " to " << new_id <<
", " << new_id <<
" already exists.");
578 std::map<MeshBase::elemset_type, dof_id_type> new_elemset_codes_inverse_map;
581 auto id_set_copy = id_set;
582 if (id_set_copy.count(old_id))
585 id_set_copy.erase(old_id);
586 id_set_copy.insert(new_id);
590 new_elemset_codes_inverse_map.emplace(id_set_copy, elemset_code);
648 const std::vector<dof_id_type> * default_values)
650 libmesh_assert(!default_values || default_values->size() == names.size());
653 std::unordered_map<std::string, std::size_t> name_indices;
657 std::vector<unsigned int> returnval(names.size());
659 bool added_an_integer =
false;
662 const std::string & name = names[i];
663 if (
const auto it = name_indices.find(name);
664 it != name_indices.end())
666 returnval[i] = it->second;
673 name_indices[name] = returnval[i];
677 added_an_integer =
true;
681 if (allocate_data && added_an_integer)
695 libmesh_error_msg(
"Unknown elem integer " << name);
737 const std::vector<dof_id_type> * default_values)
739 libmesh_assert(!default_values || default_values->size() == names.size());
742 std::unordered_map<std::string, std::size_t> name_indices;
746 std::vector<unsigned int> returnval(names.size());
748 bool added_an_integer =
false;
751 const std::string & name = names[i];
752 if (
const auto it = name_indices.find(name);
753 it != name_indices.end())
755 returnval[i] = it->second;
762 name_indices[name] = returnval[i];
766 added_an_integer =
true;
770 if (allocate_data && added_an_integer)
784 libmesh_error_msg(
"Unknown node integer " << name);
803 LOG_SCOPE(
"remove_orphaned_nodes()",
"MeshBase");
806 std::unordered_set<Node *> connected_nodes;
810 for (
const auto & element : this->element_ptr_range())
811 for (
auto & n : element->node_ref_range())
812 connected_nodes.insert(&n);
814 for (
const auto & node : this->node_ptr_range())
815 if (!connected_nodes.count(node))
823#ifdef LIBMESH_ENABLE_DEPRECATED
826 libmesh_deprecated();
831 if (skip_renumber_nodes_and_elements)
845 libmesh_deprecated();
850 if (skip_renumber_nodes_and_elements)
876 LOG_SCOPE(
"complete_preparation()",
"MeshBase");
878 parallel_object_only();
968#if defined(DEBUG) && defined(LIBMESH_ENABLE_UNIQUE_ID)
1018#ifdef LIBMESH_ENABLE_UNIQUE_ID
1081#ifdef LIBMESH_ENABLE_DEPRECATED
1092 &ghosting_functor) ==
1116 &ghosting_functor) ==
1130 parallel_object_only();
1132 struct SBDInserter {
1133 std::set<subdomain_id_type> my_ids;
1139 for (
const Elem * elem : range)
1140 my_ids.insert(elem->subdomain_id());
1143 void join(SBDInserter & other) {
1144 my_ids.merge(other.my_ids);
1148 SBDInserter inserter;
1151 ids.swap(inserter.my_ids);
1158 for (
const auto & elem : this->active_unpartitioned_element_ptr_range())
1159 ids.insert(elem->subdomain_id());
1193 parallel_object_only();
1195 std::set<subdomain_id_type> ids;
1199 return cast_int<subdomain_id_type>(ids.size());
1206 std::set<subdomain_id_type> ids;
1210 return cast_int<subdomain_id_type>(ids.size());
1223 return static_cast<dof_id_type>(std::distance (this->pid_nodes_begin(proc_id),
1224 this->pid_nodes_end (proc_id)));
1236 return static_cast<dof_id_type>(std::distance (this->pid_elements_begin(proc_id),
1237 this->pid_elements_end (proc_id)));
1245 return static_cast<dof_id_type>(std::distance (this->active_pid_elements_begin(proc_id),
1246 this->active_pid_elements_end (proc_id)));
1255 for (
const auto & elem : this->element_ptr_range())
1256 ne += elem->n_sub_elem();
1267 for (
const auto & elem : this->active_element_ptr_range())
1268 ne += elem->n_sub_elem();
1277 std::ostringstream oss;
1279 oss <<
" Mesh Information:" <<
'\n';
1283 oss <<
" elem_dimensions()={";
1286 std::ostream_iterator<unsigned int>(oss,
", "));
1287 oss << cast_int<unsigned int>(*
_elem_dims.rbegin());
1293 oss <<
" elem_default_orders()={";
1296 std::ostream_iterator<std::string>(oss,
", "),
1298 { return Utility::enum_to_string<Order>(o); });
1305 <<
" n_nodes()=" << this->
n_nodes() <<
'\n'
1307 <<
" n_elem()=" << this->
n_elem() <<
'\n'
1309#ifdef LIBMESH_ENABLE_AMR
1310 oss <<
" n_active_elem()=" << this->
n_active_elem() <<
'\n';
1313 oss <<
" n_subdomains()=" <<
static_cast<std::size_t
>(this->
n_subdomains()) <<
'\n';
1315 oss <<
" n_local_subdomains()= " <<
static_cast<std::size_t
>(this->
n_local_subdomains()) <<
'\n';
1316 oss <<
" n_elemsets()=" <<
static_cast<std::size_t
>(this->
n_elemsets()) <<
'\n';
1319 oss <<
" n_partitions()=" <<
static_cast<std::size_t
>(this->
n_partitions()) <<
'\n'
1320 <<
" n_processors()=" <<
static_cast<std::size_t
>(this->
n_processors()) <<
'\n'
1322 <<
" processor_id()=" <<
static_cast<std::size_t
>(this->
processor_id()) <<
'\n'
1323 <<
" is_prepared()=" << (this->
is_prepared() ?
"true" :
"false") <<
'\n'
1324 <<
" is_replicated()=" << (this->
is_replicated() ?
"true" :
"false") <<
'\n';
1330 libmesh_parallel_only(this->
comm());
1332 oss <<
"\n Detailed global get_info() (verbosity > 0) is reduced and output to only rank 0.";
1336 const auto elem_type_helper = [](
const std::set<int> & elem_types) {
1337 std::stringstream ss;
1338 for (
auto it = elem_types.begin(); it != elem_types.end();)
1341 if (++it != elem_types.end())
1349 const auto include_object = [
this, &global](
const DofObject & dof_object) {
1350 return this->
processor_id() == dof_object.processor_id() ||
1361 oss <<
"\n " << (global ?
"" :
"Local ") <<
"Mesh Bounding Box:\n"
1362 <<
" Minimum: " << bbox.min() <<
"\n"
1363 <<
" Maximum: " << bbox.max() <<
"\n"
1364 <<
" Delta: " << (bbox.max() - bbox.min()) <<
"\n";
1367 std::set<int> elem_types;
1368 for (
const Elem * elem : this->active_local_element_ptr_range())
1369 elem_types.insert(elem->type());
1374 for (
const Elem * elem : this->active_unpartitioned_element_ptr_range())
1375 elem_types.insert(elem->type());
1382 oss <<
"\n " << (global ?
"" :
"Local ") <<
"Mesh Element Type(s):\n "
1383 << elem_type_helper(elem_types) <<
"\n";
1393 std::size_t num_nodes = 0;
1396 std::map<boundary_id_type, NodesetInfo> nodeset_info_map;
1399 if (!include_object(*node))
1402 NodesetInfo & info = nodeset_info_map[id];
1407 info.bbox.union_with(*node);
1413 oss <<
"\n " << (global ?
"" :
"Local ") <<
"Mesh Nodesets:\n";
1414 if (nodeset_ids.empty())
1419 for (
const auto id : nodeset_ids)
1421 NodesetInfo & info = nodeset_info_map[id];
1426 this->
comm().
sum(info.num_nodes);
1429 this->
comm().
min(info.bbox.min());
1430 this->
comm().
max(info.bbox.max());
1434 const bool has_name = nodeset_name_map.count(
id) && nodeset_name_map.at(
id).size();
1435 const std::string name = has_name ? nodeset_name_map.at(
id) :
"";
1439 if (global ? this->
processor_id() == 0 : info.num_nodes > 0)
1441 oss <<
" Nodeset " << id;
1443 oss <<
" (" << name <<
")";
1444 oss <<
", " << info.num_nodes <<
" " << (global ?
"" :
"local ") <<
"nodes\n";
1448 oss <<
" " << (global ?
"Bounding" :
"Local bounding") <<
" box minimum: "
1449 << info.bbox.min() <<
"\n"
1450 <<
" " << (global ?
"Bounding" :
"Local bounding") <<
" box maximum: "
1451 << info.bbox.max() <<
"\n"
1452 <<
" " << (global ?
"Bounding" :
"Local bounding") <<
" box delta: "
1453 << (info.bbox.max() - info.bbox.min()) <<
"\n";
1466 std::size_t num_sides = 0;
1468 std::set<int> side_elem_types;
1469 std::set<int> elem_types;
1470 std::set<dof_id_type> elem_ids;
1471 std::set<dof_id_type> node_ids;
1475 std::map<boundary_id_type, SidesetInfo> sideset_info_map;
1478 const Elem * elem = pair.first;
1479 if (!include_object(*elem))
1482 const auto id = pair.second.second;
1483 SidesetInfo & info = sideset_info_map[id];
1485 const auto s = pair.second.first;
1486 const Elem & side = side_builder(*elem, s);
1489 info.side_elem_types.insert(side.
type());
1490 info.elem_types.insert(elem->
type());
1491 info.elem_ids.insert(elem->
id());
1494 if (include_object(node))
1495 info.node_ids.insert(node.id());
1499 info.volume += side.
volume();
1507 oss <<
"\n " << (global ?
"" :
"Local ") <<
"Mesh Sidesets:\n";
1508 if (sideset_ids.empty())
1512 for (
const auto id : sideset_ids)
1514 SidesetInfo & info = sideset_info_map[id];
1516 auto num_elems = info.elem_ids.size();
1517 auto num_nodes = info.node_ids.size();
1522 this->
comm().
sum(info.num_sides);
1529 this->
comm().
sum(info.volume);
1530 this->
comm().
min(info.bbox.min());
1531 this->
comm().
max(info.bbox.max());
1535 const bool has_name = sideset_name_map.count(
id) && sideset_name_map.at(
id).size();
1536 const std::string name = has_name ? sideset_name_map.at(
id) :
"";
1540 if (global ? this->
processor_id() == 0 : info.num_sides > 0)
1542 oss <<
" Sideset " << id;
1544 oss <<
" (" << name <<
")";
1545 oss <<
", " << info.num_sides <<
" sides (" << elem_type_helper(info.side_elem_types) <<
")"
1546 <<
", " << num_elems <<
" " << (global ?
"" :
"local ") <<
"elems (" << elem_type_helper(info.elem_types) <<
")"
1547 <<
", " << num_nodes <<
" " << (global ?
"" :
"local ") <<
"nodes\n";
1551 oss <<
" " << (global ?
"Side" :
"Local side") <<
" volume: " << info.volume <<
"\n"
1552 <<
" " << (global ?
"Bounding" :
"Local bounding") <<
" box minimum: "
1553 << info.bbox.min() <<
"\n"
1554 <<
" " << (global ?
"Bounding" :
"Local bounding") <<
" box maximum: "
1555 << info.bbox.max() <<
"\n"
1556 <<
" " << (global ?
"Bounding" :
"Local bounding") <<
" box delta: "
1557 << (info.bbox.max() - info.bbox.min()) <<
"\n";
1570 std::size_t num_edges = 0;
1571 std::set<int> edge_elem_types;
1574 std::map<boundary_id_type, EdgesetInfo> edgeset_info_map;
1575 std::unique_ptr<const Elem> edge;
1579 const Elem * elem = pair.first;
1580 if (!include_object(*elem))
1583 const auto id = pair.second.second;
1584 EdgesetInfo & info = edgeset_info_map[id];
1589 info.edge_elem_types.insert(edge->type());
1592 info.bbox.union_with(edge->loose_bounding_box());
1598 oss <<
"\n " << (global ?
"" :
"Local ") <<
"Mesh Edgesets:\n";
1599 if (edgeset_ids.empty())
1604 for (
const auto id : edgeset_ids)
1606 EdgesetInfo & info = edgeset_info_map[id];
1611 this->
comm().
sum(info.num_edges);
1615 this->
comm().
min(info.bbox.min());
1616 this->
comm().
min(info.bbox.max());
1620 const bool has_name = edgeset_name_map.count(
id) && edgeset_name_map.at(
id).size();
1621 const std::string name = has_name ? edgeset_name_map.at(
id) :
"";
1625 if (global ? this->
processor_id() == 0 : info.num_edges > 0)
1627 oss <<
" Edgeset " << id;
1629 oss <<
" (" << name <<
")";
1630 oss <<
", " << info.num_edges <<
" " << (global ?
"" :
"local ") <<
"edges ("
1631 << elem_type_helper(info.edge_elem_types) <<
")\n";
1635 oss <<
" " << (global ?
"Bounding" :
"Local bounding") <<
" box minimum: "
1636 << info.bbox.min() <<
"\n"
1637 <<
" " << (global ?
"Bounding" :
"Local bounding") <<
" box maximum: "
1638 << info.bbox.max() <<
"\n"
1639 <<
" " << (global ?
"Bounding" :
"Local bounding") <<
" box delta: "
1640 << (info.bbox.max() - info.bbox.min()) <<
"\n";
1646 std::set<subdomain_id_type> subdomains;
1647 for (
const Elem * elem : this->active_element_ptr_range())
1648 if (include_object(*elem))
1649 subdomains.insert(elem->subdomain_id());
1654 struct SubdomainInfo
1656 std::size_t num_elems = 0;
1658 std::set<int> elem_types;
1659 std::set<dof_id_type> active_node_ids;
1660#ifdef LIBMESH_ENABLE_AMR
1661 std::size_t num_active_elems = 0;
1665 std::map<subdomain_id_type, SubdomainInfo> subdomain_info_map;
1666 for (
const Elem * elem : this->element_ptr_range())
1667 if (include_object(*elem))
1669 SubdomainInfo & info = subdomain_info_map[elem->subdomain_id()];
1672 info.elem_types.insert(elem->type());
1674#ifdef LIBMESH_ENABLE_AMR
1676 ++info.num_active_elems;
1679 for (
const Node & node : elem->node_ref_range())
1680 if (include_object(node) && node.active())
1681 info.active_node_ids.insert(node.id());
1683 if (verbosity > 1 && elem->active())
1685 info.volume += elem->volume();
1686 info.bbox.union_with(elem->loose_bounding_box());
1691 oss <<
"\n " << (global ?
"" :
"Local ") <<
"Mesh Subdomains:\n";
1693 for (
const auto id : subdomains)
1695 SubdomainInfo & info = subdomain_info_map[id];
1697 auto num_active_nodes = info.active_node_ids.size();
1702 this->
comm().
sum(info.num_elems);
1703#ifdef LIBMESH_ENABLE_AMR
1704 this->
comm().
sum(info.num_active_elems);
1706 this->
comm().
sum(num_active_nodes);
1710 this->
comm().
min(info.bbox.min());
1711 this->
comm().
max(info.bbox.max());
1712 this->
comm().
sum(info.volume);
1716 volume += info.volume;
1718 const bool has_name = subdomain_name_map.count(
id);
1719 const std::string name = has_name ? subdomain_name_map.at(
id) :
"";
1725 oss <<
" Subdomain " << id;
1727 oss <<
" (" << name <<
")";
1728 oss <<
": " << info.num_elems <<
" " << (global ?
"" :
"local ") <<
"elems "
1729 <<
"(" << elem_type_helper(info.elem_types);
1730#ifdef LIBMESH_ENABLE_AMR
1731 oss <<
", " << info.num_active_elems <<
" active";
1733 oss <<
"), " << num_active_nodes <<
" " << (global ?
"" :
"local ") <<
"active nodes\n";
1736 oss <<
" " << (global ?
"Volume" :
"Local volume") <<
": " << info.volume <<
"\n";
1737 oss <<
" " << (global ?
"Bounding" :
"Local bounding") <<
" box minimum: "
1738 << info.bbox.min() <<
"\n"
1739 <<
" " << (global ?
"Bounding" :
"Local bounding") <<
" box maximum: "
1740 << info.bbox.max() <<
"\n"
1741 <<
" " << (global ?
"Bounding" :
"Local bounding") <<
" box delta: "
1742 << (info.bbox.max() - info.bbox.min()) <<
"\n";
1747 oss <<
" " << (global ?
"Global" :
"Local") <<
" mesh volume = " << volume <<
"\n";
1757 os << this->
get_info(verbosity, global)
1816 parallel_object_only();
1818 unsigned int max_proc_id=0;
1820 for (
const auto & elem : this->active_local_element_ptr_range())
1821 max_proc_id = std::max(max_proc_id,
static_cast<unsigned int>(elem->processor_id()));
1842 parallel_object_only();
1844#ifdef LIBMESH_ENABLE_NANOFLANN_POINTLOCATOR
1857#ifdef LIBMESH_ENABLE_NANOFLANN_POINTLOCATOR
1886#ifdef LIBMESH_ENABLE_DEPRECATED
1890 libmesh_deprecated();
1905 static const std::string empty;
1911 return iter->second;
1915 const std::string & name,
1916 const bool synchronous)
1919 parallel_object_only();
1930 if (sbd_name == name)
1947 std::make_unique<ElemRange>(this->elements_begin(),
1948 this->elements_end());
1962 std::make_unique<ConstElemRange>(this->active_local_elements_begin(),
1963 this->active_local_elements_end());
1976#ifdef LIBMESH_ENABLE_DEPRECATED
1979 libmesh_deprecated();
1988 parallel_object_only();
1997 for (
const auto & elem : this->active_element_ptr_range())
1999 _elem_dims.insert(cast_int<unsigned char>(elem->dim()));
2005 static_cast<int>(elem->supported_nodal_order())));
2032 for (
const auto & node : this->node_ptr_range())
2051 if ((*node)(2) != 0.)
2069 parallel_object_only();
2079 LOG_SCOPE(
"detect_interior_parents()",
"MeshBase");
2082 parallel_object_only();
2088 std::set<unsigned char> elem_dims_copy;
2093 for (
const auto & elem : this->active_element_ptr_range())
2094 elem_dims_copy.insert(cast_int<unsigned char>(elem->dim()));
2100 if (elem_dims_copy.size() <= 1)
2107 const auto dim_start = elem_dims_copy.begin();
2108 const auto dim_end = elem_dims_copy.end();
2116 std::vector<bool> skip_dimension_for_interior_parents(LIBMESH_DIM+1,
false);
2117 skip_dimension_for_interior_parents.back() =
true;
2124 std::vector<bool> skip_dimensions_for_node_to_el_map(LIBMESH_DIM+1,
false);
2125 skip_dimensions_for_node_to_el_map[*dim_start] =
true;
2129 bool skip_all_dimensions =
true;
2132 for (
auto [it, next] = std::make_tuple(dim_start, std::next(dim_start));
2133 next != dim_end; ++it, ++next)
2135 if (*it + 1 != *next)
2137 skip_dimension_for_interior_parents[*it] =
true;
2138 skip_dimensions_for_node_to_el_map[*next] =
true;
2140 else if (!skip_dimension_for_interior_parents[*it])
2141 skip_all_dimensions =
false;
2148 if (skip_all_dimensions)
2157 const bool separate_interior_mesh = (&(this->
interior_mesh()) !=
this);
2160 std::unordered_map<dof_id_type, std::vector<dof_id_type>> node_to_elem;
2162 for (
const auto & elem : this->element_ptr_range())
2165 if (skip_dimensions_for_node_to_el_map[elem->dim()])
2169 for (
auto n :
make_range(elem->n_vertices()))
2171 libmesh_assert_less (elem->id(), this->max_elem_id());
2173 node_to_elem[elem->node_id(n)].push_back(elem->id());
2178 for (
const auto & element : this->element_ptr_range())
2182 if (skip_dimension_for_interior_parents[element->dim()] || element->interior_parent())
2191 std::vector<std::set<dof_id_type>> neighbors( element->n_vertices() );
2193 bool found_interior_parents =
true;
2195 for (
auto n :
make_range(element->n_vertices()))
2197 auto it = node_to_elem.find(element->node_id(n));
2200 if (it == node_to_elem.end())
2202 found_interior_parents =
false;
2206 for (
const auto & vertex_neighbor_id : it->second)
2207 if (this->
elem_ref(vertex_neighbor_id).
dim() == element->dim()+1)
2208 neighbors[n].insert(vertex_neighbor_id);
2210 if (neighbors[n].empty())
2214 found_interior_parents =
false;
2224 if (found_interior_parents)
2226 std::set<dof_id_type> & neighbors_0 = neighbors[0];
2227 for (
const auto & interior_parent_id : neighbors_0)
2229 found_interior_parents =
false;
2230 for (
auto n :
make_range(1u, element->n_vertices()))
2232 if (neighbors[n].count(interior_parent_id))
2234 found_interior_parents =
true;
2238 found_interior_parents =
false;
2243 if (found_interior_parents)
2245 element->set_interior_parent(this->
elem_ptr(interior_parent_id));
2254 if (separate_interior_mesh)
2255 libmesh_not_implemented_msg
2256 (
"interior_parent() values in multiple meshes are unsupported.");
2268#ifdef LIBMESH_ENABLE_PERIODIC
2292 db.emplace(b1, forward.
clone());
2293 db.emplace(b2, inverse.
clone());
2320 auto it = pb_map.find(key);
2321 if (it != pb_map.end())
2323 const auto & pb = *(it->second);
2325 if ((pb.myboundary == key && pb.pairedboundary == pair) ||
2326 (pb.pairedboundary == key && pb.myboundary == pair))
2331 erase_if_match(b1, b2, pairs);
2332 erase_if_match(b2, b1, pairs);
2367 [new_size,
this](
const ElemRange & range)
2369 for (
Elem * elem : range)
2370 elem->add_extra_integers(new_size, this->_elem_integer_default_values);
2379 for (
auto node : this->node_ptr_range())
2384std::pair<std::vector<unsigned int>, std::vector<unsigned int>>
2387 std::pair<std::vector<unsigned int>, std::vector<unsigned int>> returnval;
2419 (sf.second)->set_mesh(
this);
2425 if (other_mesh.partitioner())
2443 for (
const auto & other_node : other_mesh.node_ptr_range())
2448 if (*other_node != *node)
2451 for (
const auto & node : this->node_ptr_range())
2455 for (
const auto & other_elem : other_mesh.element_ptr_range())
2460 if (!other_elem->topologically_equal(*elem))
2463 for (
const auto & elem : this->element_ptr_range())
2473 dof_id_type n_local_rows=0, n_unpartitioned_rows=0;
2478 n_unpartitioned_rows++;
2483 this->
comm().
sum(n_local_rows);
2485 return n_unpartitioned_rows + n_local_rows;
2492 LOG_SCOPE(
"copy_constraint_rows(mesh)",
"MeshBase");
2497 for (
const auto & [other_node, other_node_constraints] : other_constraint_rows)
2499 const Node *
const our_node = this->
node_ptr(other_node->id());
2501 for (
const auto & [other_inner_key_pair, constraint_value] : other_node_constraints)
2503 const auto & [other_elem, local_node_id] = other_inner_key_pair;
2504 const Elem *
const our_elem = this->
elem_ptr(other_elem->id());
2505 our_node_constraints.emplace_back(std::make_pair(our_elem, local_node_id), constraint_value);
2512template <
typename T>
2515 bool precondition_constraint_operator)
2517 LOG_SCOPE(
"copy_constraint_rows(mat)",
"MeshBase");
2527 libmesh_error_msg_if(this->
n_nodes() != constraint_operator.
m(),
2528 "Constraint operator matrix with " <<
2529 constraint_operator.
m() <<
2530 "rows does not match this mesh with " <<
2531 this->n_nodes() <<
" nodes");
2540 std::map<dof_id_type, dof_id_type> existing_unconstrained_columns;
2541 std::set<dof_id_type> existing_unconstrained_nodes;
2547 std::vector<std::pair<dof_id_type, Real>>>
2549 columns_type columns(constraint_operator.
n());
2557 std::unordered_map<dof_id_type, Real> column_sums;
2563 std::vector<numeric_index_type> indices;
2564 std::vector<T> values;
2566 constraint_operator.
get_row(i, indices, values);
2567 libmesh_assert_equal_to(indices.size(), values.size());
2569 if (indices.size() == 1 &&
2575 if (existing_unconstrained_columns.find(indices[0]) !=
2576 existing_unconstrained_columns.end())
2578 const auto j = indices[0];
2579 columns[j].emplace_back(i, 1);
2583 existing_unconstrained_nodes.insert(i);
2584 existing_unconstrained_columns.emplace(indices[0],i);
2590 const auto j = indices[jj];
2592 libmesh_assert_equal_to(coef, values[jj]);
2593 columns[j].emplace_back(i, coef);
2601 std::vector<columns_type> all_columns;
2606 for (
auto & [j, subcol] : all_columns[p])
2607 for (
auto [i, v] : subcol)
2608 columns[j].emplace_back(i,v);
2613 std::unordered_map<const Node *, std::pair<dof_id_type, unsigned int>> node_to_elem_ptrs;
2620 for (
const Elem * elem : this->element_ptr_range())
2625 const Node * node = elem->node_ptr(n);
2626 if (existing_unconstrained_nodes.count(node->
id()))
2627 node_to_elem_ptrs.emplace(node, std::make_pair(elem->id(), n));
2633 for (
auto j :
make_range(constraint_operator.
n()))
2636 if (existing_unconstrained_columns.count(j))
2645 Real total_scaling = 0;
2646 unsigned int total_entries = 0;
2650 std::map<processor_id_type, int> pids;
2652 auto & column = columns[j];
2653 for (
auto [i, r] : column)
2656 const Point constrained_pt = constrained_node;
2657 newpt += r*constrained_pt;
2663 if (precondition_constraint_operator)
2664 column_sums[j] = total_scaling;
2666 libmesh_error_msg_if
2668 "Empty column " << j <<
2669 " found in constraint operator matrix");
2675 newpt /= total_scaling;
2677 newpt /= total_entries;
2681 elem->set_node(0, n);
2682 elem->subdomain_id() = new_sbd_id;
2692 node_to_elem_ptrs.emplace(n, std::make_pair(added_elem->
id(), 0));
2693 existing_unconstrained_columns.emplace(j,n->
id());
2699 for (
auto [pid, count] : pids)
2700 if (count >= n_pids)
2711 std::vector<std::pair<std::pair<dof_id_type, unsigned int>,
Real>>>
2712 indexed_constraint_rows;
2717 if (existing_unconstrained_nodes.count(i))
2720 std::vector<numeric_index_type> indices;
2721 std::vector<T> values;
2723 constraint_operator.
get_row(i, indices, values);
2725 std::vector<std::pair<std::pair<dof_id_type, unsigned int>,
Real>> constraint_row;
2730 existing_unconstrained_columns[indices[jj]];
2736 auto p = node_to_elem_ptrs[&constraining_node];
2739 libmesh_assert_equal_to(coef, values[jj]);
2745 if (precondition_constraint_operator)
2746 if (
auto sum_it = column_sums.find(indices[jj]);
2747 sum_it != column_sums.end())
2749 const Real scaling = sum_it->second;
2755 constraint_row.emplace_back(std::make_pair(p, coef));
2758 indexed_constraint_rows.emplace(i, std::move(constraint_row));
2764 for (
auto & [node_id, indexed_row] : indexed_constraint_rows)
2770 for (
auto [p, coef] : indexed_row)
2773 constraint_row.emplace_back
2774 (std::make_pair(std::make_pair(elem, p.second), coef));
2778 std::move(constraint_row));
2784 bool print_nonlocal)
const
2786 parallel_object_only();
2788 std::string local_constraints =
2793 this->
comm().
send(0, local_constraints);
2797 os <<
"Processor 0:\n";
2798 os << local_constraints;
2803 os <<
"Processor " << p <<
":\n";
2804 os << local_constraints;
2813 std::ostringstream os;
2820 os <<
"Mesh Constraint Rows:"
2825 const bool local = (node->processor_id() == this->
processor_id());
2828 if (!print_nonlocal && !local)
2831 os <<
"Constraints for " << (local ?
"Local" :
"Ghost") <<
" Node " << node->id()
2834 for (
const auto & [elem_and_node, coef] : row)
2835 os <<
" ((" << elem_and_node.first->id() <<
',' << elem_and_node.second <<
"), " << coef <<
")\t";
2844 is_partitioned(false),
2845 has_synched_id_counts(false),
2846 has_neighbor_ptrs(false),
2847 has_cached_elem_data(false),
2848 has_interior_parent_ptrs(false),
2849 has_removed_remote_elements(false),
2850 has_removed_orphaned_nodes(false),
2851 has_boundary_id_sets(false),
2852 has_reinit_ghosting_functors(false),
2853 has_synched_subdomain_name_map(false)
2856MeshBase::Preparation::operator bool()
const
2858 return is_partitioned &&
2859 has_synched_id_counts &&
2860 has_neighbor_ptrs &&
2861 has_cached_elem_data &&
2862 has_interior_parent_ptrs &&
2863 has_removed_remote_elements &&
2864 has_removed_orphaned_nodes &&
2865 has_reinit_ghosting_functors &&
2866 has_boundary_id_sets &&
2867 has_synched_subdomain_name_map;
2873 is_partitioned = set_all;
2874 has_synched_id_counts = set_all;
2875 has_neighbor_ptrs = set_all;
2876 has_cached_elem_data = set_all;
2877 has_interior_parent_ptrs = set_all;
2878 has_removed_remote_elements = set_all;
2879 has_removed_orphaned_nodes = set_all;
2880 has_reinit_ghosting_functors = set_all;
2881 has_boundary_id_sets = set_all;
2882 has_synched_subdomain_name_map = set_all;
2917 return !(*
this == other);
2922template LIBMESH_EXPORT
void
2924 bool precondition_constraint_operator);
2926#ifdef LIBMESH_USE_COMPLEX_NUMBERS
2927template LIBMESH_EXPORT
void
2929 bool precondition_constraint_operator);
void max(const T &r, T &o, Request &req) const
Status receive(const unsigned int dest_processor_id, T &buf, const MessageTag &tag=any_tag) const
void min(const T &r, T &o, Request &req) const
void set_union(T &data, const unsigned int root_id) const
void allgather(const T &send_data, std::vector< T, A > &recv_data) const
void send(const unsigned int dest_processor_id, const T &buf, const MessageTag &tag=no_tag) const
The BoundaryInfo class contains information relevant to boundary conditions including storing faces,...
const std::set< boundary_id_type > & get_edge_boundary_ids() const
const std::multimap< const Elem *, std::pair< unsigned short int, boundary_id_type > > & get_edgeset_map() const
const std::multimap< const Node *, boundary_id_type > & get_nodeset_map() const
const std::multimap< const Elem *, std::pair< unsigned short int, boundary_id_type > > & get_sideset_map() const
const std::set< boundary_id_type > & get_node_boundary_ids() const
const std::set< boundary_id_type > & get_side_boundary_ids() const
void regenerate_id_sets()
Clears and regenerates the cached sets of ids.
const std::map< boundary_id_type, std::string > & get_edgeset_name_map() const
const std::map< boundary_id_type, std::string > & get_nodeset_name_map() const
const std::map< boundary_id_type, std::string > & get_sideset_name_map() const
Defines a Cartesian bounding box by the two corner extremum.
The DofObject defines an abstract base class for objects that have degrees of freedom associated with...
processor_id_type processor_id() const
static constexpr dof_id_type invalid_id
An invalid id to distinguish an uninitialized DofObject.
static constexpr processor_id_type invalid_processor_id
An invalid processor_id to distinguish DoFs that have not been assigned to a processor.
Helper for building element sides that minimizes the construction of new elements.
This is the base class from which all geometric element types are derived.
virtual BoundingBox loose_bounding_box() const
SimpleRange< NodeRefIter > node_ref_range()
Returns a range with all nodes of an element, usable in range-based for loops.
virtual Order default_order() const =0
static std::unique_ptr< Elem > build(const ElemType type, Elem *p=nullptr)
virtual Order supported_nodal_order() const
static constexpr subdomain_id_type invalid_subdomain_id
A static integral constant representing an invalid subdomain id.
virtual unsigned short dim() const =0
virtual std::unique_ptr< Elem > build_edge_ptr(const unsigned int i)=0
virtual Real volume() const
virtual ElemType type() const =0
This class implements the original default geometry ghosting requirements in libMesh: point neighbors...
This abstract base class defines the interface by which library code and user code can report associa...
The IntRange templated class is intended to make it easy to loop over integers which are indices of a...
This is the MeshBase class.
void set_subdomain_name(subdomain_id_type id, const std::string &name, bool synchronous=false)
Sets the name for the provided id.
virtual const Node & node_ref(const dof_id_type i) const
virtual bool is_serial() const
void size_elem_extra_integers()
Size extra-integer arrays of all elements in the mesh.
const BoundaryInfo & get_boundary_info() const
The information about boundary ids on the mesh.
void set_spatial_dimension(unsigned char d)
Sets the "spatial dimension" of the Mesh.
virtual std::unique_ptr< Partitioner > & partitioner()
A partitioner to use at each partitioning.
bool allow_renumbering() const
virtual const Node * node_ptr(const dof_id_type i) const =0
MeshBase::elemset_type _all_elemset_ids
MeshBase(const Parallel::Communicator &comm_in, unsigned char dim=1)
Constructor.
unsigned int mesh_dimension() const
bool _allow_node_and_elem_unique_id_overlap
The Exodus reader (and potentially other readers in the future?) now supports setting Node and Elem u...
virtual dof_id_type n_elem() const =0
virtual bool is_replicated() const
void complete_preparation()
bool _skip_detect_interior_parents
If this is true then we will skip detect_interior_parents in prepare_for_use.
bool operator==(const MeshBase &other_mesh) const
This tests for exactly-equal data in all the senses that a mathematician would care about (element co...
void set_elem_dimensions(std::set< unsigned char > elem_dims)
Most of the time you should not need to call this, as the element dimensions will be set automaticall...
const std::set< unsigned char > & elem_dimensions() const
void print_constraint_rows(std::ostream &os=libMesh::out, bool print_nonlocal=false) const
Prints (from processor 0) all mesh constraint rows.
bool skip_partitioning() const
Order supported_nodal_order() const
Order _supported_nodal_order
We cache the maximum nodal order supported by all the mesh's elements (the minimum supported_nodal_or...
void subdomain_ids(std::set< subdomain_id_type > &ids, const bool global=true) const
Constructs a list of all subdomain identifiers in the local mesh if global == false,...
unsigned int recalculate_n_partitions()
In a few (very rare) cases, the user may have manually tagged the elements with specific processor ID...
virtual void renumber_nodes_and_elements()=0
After partitioning a mesh it is useful to renumber the nodes and elements so that they lie in contigu...
void set_point_locator_close_to_point_tol(Real val)
Set value used by PointLocatorBase::close_to_point_tol().
dof_id_type n_active_elem_on_proc(const processor_id_type proc) const
bool has_node_integer(std::string_view name) const
unsigned int spatial_dimension() const
PeriodicBoundaries * get_disjoint_neighbor_boundary_pairs()
void change_elemset_id(elemset_id_type old_id, elemset_id_type new_id)
Replace elemset id "old_id" with "new_id".
unsigned int get_elem_integer_index(std::string_view name) const
const std::map< subdomain_id_type, std::string > & get_subdomain_name_map() const
subdomain_id_type n_local_subdomains() const
void all_second_order(const bool full_ordered=true)
Calls the range-based version of this function with a range consisting of all elements in the mesh.
virtual void delete_node(Node *n)=0
Removes the Node n from the mesh.
unsigned int get_node_integer_index(std::string_view name) const
std::map< dof_id_type, const MeshBase::elemset_type * > _elemset_codes
Map from "element set code" to list of set ids to which that element belongs (and vice-versa).
dof_id_type get_elemset_code(const MeshBase::elemset_type &id_set) const
dof_id_type n_sub_elem() const
const ConstElemRange & active_local_element_stored_range() const
virtual void redistribute()
Redistribute elements between processors.
const ElemRange & element_stored_range()
std::unique_ptr< PeriodicBoundaries > _disjoint_neighbor_boundary_pairs
The disjoint neighbor boundary id pairs.
std::vector< unsigned int > add_node_integers(const std::vector< std::string > &names, bool allocate_data=true, const std::vector< dof_id_type > *default_values=nullptr)
Register integer data (of type dof_id_type) to be added to each node in the mesh.
unsigned char _spatial_dimension
The "spatial dimension" of the Mesh.
virtual ~MeshBase()
Destructor.
std::map< MeshBase::elemset_type, dof_id_type > _elemset_codes_inverse_map
bool _count_lower_dim_elems_in_point_locator
Do we count lower dimensional elements in point locator refinement? This is relevant in tree-based po...
dof_id_type n_active_sub_elem() const
Same as n_sub_elem(), but only counts active elements.
bool _allow_remote_element_removal
If this is false then even on DistributedMesh remote elements will not be deleted during mesh prepara...
unsigned int add_node_integer(std::string name, bool allocate_data=true, dof_id_type default_value=DofObject::invalid_id)
Register an integer datum (of type dof_id_type) to be added to each node in the mesh.
void change_elemset_code(dof_id_type old_code, dof_id_type new_code)
Replace elemset code "old_code" with "new_code".
std::vector< dof_id_type > get_elemset_codes() const
Return a vector of all elemset codes defined on the mesh.
virtual dof_id_type n_nodes() const =0
std::vector< dof_id_type > _node_integer_default_values
The array of default initialization values for integer data associated with each node in the mesh.
unique_id_type _next_unique_id
The next available unique id for assigning ids to DOF objects.
bool _skip_renumber_nodes_and_elements
If this is true then renumbering will be kept to a minimum.
void remove_ghosting_functor(GhostingFunctor &ghosting_functor)
Removes a functor which was previously added to the set of ghosting functors.
virtual const Node * query_node_ptr(const dof_id_type i) const =0
std::vector< std::pair< std::pair< const Elem *, unsigned int >, Real > > constraint_rows_mapped_type
virtual void all_second_order_range(const SimpleRange< element_iterator > &range, const bool full_ordered=true)=0
Converts a set of this Mesh's elements defined by range from FIRST order to SECOND order.
GhostingFunctorIterator ghosting_functors_begin() const
Beginning of range of ghosting functors.
void unset_has_synched_subdomain_name_map()
Tells this we have done some operation which may have left the subdomain id to name map inconsistent ...
std::map< GhostingFunctor *, std::shared_ptr< GhostingFunctor > > _shared_functors
Hang on to references to any GhostingFunctor objects we were passed in shared_ptr form.
virtual Node * add_point(const Point &p, const dof_id_type id=DofObject::invalid_id, const processor_id_type proc_id=DofObject::invalid_processor_id)=0
Add a new Node at Point p to the end of the vertex array, with processor_id procid.
std::set< subdomain_id_type > _mesh_subdomains
We cache the subdomain ids of the elements present in the mesh.
dof_id_type n_unpartitioned_elem() const
virtual void update_post_partitioning()
Recalculate any cached data (or invalidate any caches that are computed on the fly) after elements an...
bool get_count_lower_dim_elems_in_point_locator() const
Get the current value of _count_lower_dim_elems_in_point_locator.
std::unique_ptr< PointLocatorBase > _point_locator
A PointLocator class for this mesh.
virtual const Elem * elem_ptr(const dof_id_type i) const =0
unsigned int add_elem_integer(std::string name, bool allocate_data=true, dof_id_type default_value=DofObject::invalid_id)
Register an integer datum (of type dof_id_type) to be added to each element in the mesh.
bool _skip_all_partitioning
If this is true then no partitioning should be done.
virtual void all_complete_order_range(const SimpleRange< element_iterator > &range)=0
Converts a set of elements in this (conforming, non-refined) mesh into "complete" order elements,...
std::vector< std::string > _elem_integer_names
The array of names for integer data associated with each element in the mesh.
std::vector< dof_id_type > _elem_integer_default_values
The array of default initialization values for integer data associated with each element in the mesh.
void remove_orphaned_nodes()
Removes any orphaned nodes, nodes not connected to any elements.
Real get_point_locator_close_to_point_tol() const
unsigned int n_partitions() const
bool has_elem_integer(std::string_view name) const
dof_id_type n_local_elem() const
dof_id_type n_unpartitioned_nodes() const
bool _skip_noncritical_partitioning
If this is true then no partitioning should be done with the possible exception of orphaned nodes.
bool _skip_find_neighbors
If this is true then we will skip find_neighbors in prepare_for_use.
dof_id_type n_elem_on_proc(const processor_id_type proc) const
virtual void delete_remote_elements()
When supported, deletes all nonlocal elements of the mesh except for "ghosts" which touch a local ele...
MeshBase & operator=(const MeshBase &)=delete
Copy and move assignment are not allowed because MeshBase subclasses manually manage memory (Elems an...
ElemMappingType _default_mapping_type
The default mapping type (typically Lagrange) between master and physical space to assign to newly ad...
std::unique_ptr< BoundaryInfo > boundary_info
This class holds the boundary information.
std::set< Order > _elem_default_orders
We cache the (default) order of the geometric elements present in the mesh.
bool skip_noncritical_partitioning() const
MeshBase * _interior_mesh
Defaulting to this, a pointer to the mesh used to generate boundary elements on this.
std::vector< GhostingFunctor * > _ghosting_functors
The list of all GhostingFunctor objects to be used when distributing a DistributedMesh.
virtual void clear()
Deletes all the element and node data that is currently stored.
std::pair< std::vector< unsigned int >, std::vector< unsigned int > > merge_extra_integer_names(const MeshBase &other)
Merge extra-integer arrays from an other mesh.
dof_id_type n_local_nodes() const
std::unique_ptr< ConstElemRange > _const_active_local_element_stored_range
A cached ConstElemRange for threaded calculation on all local elements of this mesh.
std::map< subdomain_id_type, std::string > _block_id_to_name
This structure maintains the mapping of named blocks for file formats that support named blocks.
virtual bool subclass_locally_equals(const MeshBase &other_mesh) const =0
Shim to allow operator == (&) to behave like a virtual function without having to be one.
constraint_rows_type _constraint_rows
std::unique_ptr< Partitioner > _partitioner
A partitioner to use at each prepare_for_use().
unsigned int n_elemsets() const
Returns the number of unique elemset ids which have been added via add_elemset_code(),...
constraint_rows_type & get_constraint_rows()
Constraint rows accessors.
const MeshBase & interior_mesh() const
std::unique_ptr< GhostingFunctor > _default_ghosting
The default geometric GhostingFunctor, used to implement standard libMesh element ghosting behavior.
void add_elemset_code(dof_id_type code, MeshBase::elemset_type id_set)
Tabulate a user-defined "code" for elements which belong to the element sets specified in id_set.
unsigned char _default_mapping_data
The default mapping data (unused with Lagrange, used for nodal weight lookup index with rational base...
virtual const Elem * query_elem_ptr(const dof_id_type i) const =0
dof_id_type n_constraint_rows() const
virtual void all_complete_order()
Calls the range-based version of this function with a range consisting of all elements in the mesh.
virtual Elem * add_elem(Elem *e)=0
Add elem e to the end of the element array.
Real _point_locator_close_to_point_tol
If nonzero, we will call PointLocatorBase::set_close_to_point_tol() on any PointLocators that we crea...
dof_id_type n_nodes_on_proc(const processor_id_type proc) const
std::string & subdomain_name(subdomain_id_type id)
bool allow_find_neighbors() const
void sync_subdomain_name_map()
libMesh often expects all processors to know about names of all subdomain ids, but distributed mesh g...
virtual const Elem & elem_ref(const dof_id_type i) const
void size_node_extra_integers()
Size extra-integer arrays of all nodes in the mesh.
unsigned int _n_parts
The number of partitions the mesh has.
std::map< const Node *, constraint_rows_mapped_type > constraint_rows_type
void get_elemsets(dof_id_type elemset_code, MeshBase::elemset_type &id_set_to_fill) const
Look up the element sets for a given elemset code and vice-versa.
void remove_disjoint_boundary_pair(const boundary_id_type b1, const boundary_id_type b2)
void clear_point_locator()
Releases the current PointLocator object.
GhostingFunctorIterator ghosting_functors_end() const
End of range of ghosting functors.
void set_count_lower_dim_elems_in_point_locator(bool count_lower_dim_elems)
In the point locator, do we count lower dimensional elements when we refine point locator regions?...
void add_ghosting_functor(GhostingFunctor &ghosting_functor)
Adds a functor which can specify ghosting requirements for use on distributed meshes.
void copy_constraint_rows(const MeshBase &other_mesh)
Copy the constraints from the other mesh to this mesh.
std::set< elemset_id_type > elemset_type
Typedef for the "set" container used to store elemset ids.
std::set< unsigned char > _elem_dims
We cache the dimension of the elements present in the mesh.
std::vector< unsigned int > add_elem_integers(const std::vector< std::string > &names, bool allocate_data=true, const std::vector< dof_id_type > *default_values=nullptr)
Register integer data (of type dof_id_type) to be added to each element in the mesh,...
std::vector< std::string > _node_integer_names
The array of names for integer data associated with each node in the mesh.
std::unique_ptr< PointLocatorBase > sub_point_locator() const
void add_disjoint_neighbor_boundary_pairs(const boundary_id_type b1, const boundary_id_type b2, const RealVectorValue &translation)
Register a pair of boundaries as disjoint neighbor boundary pairs.
subdomain_id_type get_id_by_name(std::string_view name) const
void print_info(std::ostream &os=libMesh::out, const unsigned int verbosity=0, const bool global=true) const
Prints relevant information about the mesh.
virtual void update_parallel_id_counts()=0
Updates parallel caches so that methods like n_elem() accurately reflect changes on other processors.
bool locally_equals(const MeshBase &other_mesh) const
This behaves the same as operator==, but only for the local and ghosted aspects of the mesh; i....
virtual dof_id_type n_active_elem() const =0
void reinit_ghosting_functors()
Loops over ghosting functors and calls mesh_reinit()
Preparation _preparation
Flags indicating in what ways this mesh has been prepared.
subdomain_id_type n_subdomains() const
std::string get_info(const unsigned int verbosity=0, const bool global=true) const
std::string get_local_constraints(bool print_nonlocal=false) const
Gets a string reporting all mesh constraint rows local to this processor.
bool nodes_and_elements_equal(const MeshBase &other_mesh) const
Tests for equality of all elements and nodes in the mesh.
void copy_cached_data(const MeshBase &other_mesh)
Helper class to copy cached data, to synchronize with a possibly unprepared other_mesh.
void unset_is_prepared()
Tells this we have done some operation where we should no longer consider ourself prepared.
virtual void find_neighbors(const bool reset_remote_elements=false, const bool reset_current_list=true, const bool assert_valid=true)=0
Locate element face (edge in 2D) neighbors.
void post_dofobject_moves(MeshBase &&other_mesh)
Moves any superclass data (e.g.
void detect_interior_parents()
Search the mesh for elements that have a neighboring element of dim+1 and set that element as the int...
void clear_stored_ranges()
Clears stored ranges, to indicate that the mesh has changed and they should be regenerated when next ...
std::unique_ptr< ElemRange > _element_stored_range
A cached ElemRange for threaded mutation of all semilocal elements of this mesh.
Temporarily serialize a DistributedMesh for non-distributed-mesh capable code paths.
A Node is like a Point, but with more information.
An object whose state is distributed along a set of processors.
processor_id_type processor_id() const
ParallelObject & operator=(const ParallelObject &libmesh_dbg_var(other))
"Assignment" operator.
const Parallel::Communicator & comm() const
processor_id_type n_processors() const
We're using a class instead of a typedef to allow forward declarations and future flexibility.
boundary_id_type myboundary
The boundary ID of this boundary and its counterpart.
boundary_id_type pairedboundary
The definition of a periodic boundary.
virtual std::unique_ptr< PeriodicBoundaryBase > clone(TransformationType t=FORWARD) const override
If we want the DofMap to be able to make copies of references and store them in the underlying map,...
static std::unique_ptr< PointLocatorBase > build(PointLocatorType t, const MeshBase &mesh, const PointLocatorBase *master=nullptr)
Builds an PointLocator for the mesh mesh.
A Point defines a location in LIBMESH_DIM dimensional Real space.
virtual void get_row(numeric_index_type i, std::vector< numeric_index_type > &indices, std::vector< T > &values) const =0
Get a row from the matrix.
virtual numeric_index_type n() const =0
virtual numeric_index_type row_stop() const =0
virtual numeric_index_type m() const =0
virtual numeric_index_type row_start() const =0
The StoredRange class defines a contiguous, divisible set of objects.
Dummy "splitting object" used to distinguish splitting constructors from copy constructors.
bool in_threads
A boolean which is true iff we are in a Threads:: function It may be useful to assert(!...
void parallel_reduce(const Range &range, Body &body, unsigned int n_threads=libMesh::n_threads())
Execute the provided reduction operation in parallel on the specified range.
void parallel_for(const Range &range, const Body &body, unsigned int n_threads=libMesh::n_threads())
Execute the provided function object in parallel on the specified range.
std::string enum_to_string(const T e)
The libMesh namespace provides an interface to certain functionality in the library.
SimpleRange< IndexType > as_range(const std::pair< IndexType, IndexType > &p)
Helper function that allows us to treat a homogenous pair as a range.
auto index_range(const T &sizable)
Helper function that returns an IntRange<std::size_t> representing all the indices of the passed-in v...
bool closed()
Checks that the library has been closed.
ElemType
Defines an enum for geometric element types.
std::ostream & operator<<(std::ostream &os, const OrderWrapper &order)
Overload stream operators.
const unsigned int invalid_uint
A number which is used quite often to represent an invalid or uninitialized value for an unsigned int...
bool initialized()
Checks that library initialization has been done.
static constexpr Real TOLERANCE
bool on_command_line(std::string arg)
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
uint8_t processor_id_type
IntRange< T > make_range(T beg, T end)
The 2-parameter make_range() helper function returns an IntRange<T> when both input parameters are of...
Flags indicating in what ways a mesh has been prepared for use.
bool has_reinit_ghosting_functors
bool has_cached_elem_data
bool operator!=(const Preparation &other) const
bool has_removed_orphaned_nodes
Preparation & operator=(bool set_all)
Set all flags to the "set_all" value.
Preparation()
Constructor.
bool operator==(const Preparation &other) const
Two Preparation objects are equivalent iff all the flags match, regardless of the true/false status o...
bool has_interior_parent_ptrs
bool has_removed_remote_elements
bool has_synched_id_counts
bool has_synched_subdomain_name_map
bool has_boundary_id_sets