21 #include "libmesh/dof_map.h" 24 #include "libmesh/coupling_matrix.h" 25 #include "libmesh/default_coupling.h" 26 #include "libmesh/dense_matrix.h" 27 #include "libmesh/dense_vector_base.h" 28 #include "libmesh/dirichlet_boundaries.h" 29 #include "libmesh/enum_to_string.h" 30 #include "libmesh/fe_type.h" 31 #include "libmesh/fe_base.h" 32 #include "libmesh/ghosting_functor.h" 33 #include "libmesh/int_range.h" 34 #include "libmesh/mesh_base.h" 35 #include "libmesh/mesh_tools.h" 36 #include "libmesh/numeric_vector.h" 37 #include "libmesh/periodic_boundary_base.h" 38 #include "libmesh/periodic_boundaries.h" 39 #include "libmesh/sparse_matrix.h" 40 #include "libmesh/sparsity_pattern.h" 41 #include "libmesh/threads.h" 42 #include "libmesh/static_condensation_dof_map.h" 53 #include <unordered_map> 60 std::unique_ptr<SparsityPattern::Build>
62 const bool calculate_constrained,
63 const bool use_condensed_system)
const 67 LOG_SCOPE(
"build_sparsity()",
"DofMap");
83 if (use_condensed_system)
97 auto sp = std::make_unique<SparsityPattern::Build>
101 implicit_neighbor_dofs,
103 calculate_constrained,
107 mesh.active_local_elements_end()), *sp);
111 libmesh_assert_equal_to (sp->get_sparsity_pattern().size(), this->
n_local_dofs());
119 libMesh::out <<
"WARNING: You have specified both an extra sparsity function and object.\n" 120 <<
" Are you sure this is what you meant to do??" 139 _dof_coupling(nullptr),
140 _error_on_constraint_loop(false),
141 _constrained_sparsity_construction(false),
144 _variable_group_numbers(),
150 _augment_sparsity_pattern(nullptr),
151 _extra_sparsity_function(nullptr),
152 _extra_sparsity_context(nullptr),
153 _augment_send_list(nullptr),
154 _extra_send_list_function(nullptr),
155 _extra_send_list_context(nullptr),
158 need_full_sparsity_pattern(false),
160 #ifdef LIBMESH_ENABLE_AMR
161 , _first_old_scalar_df()
163 #ifdef LIBMESH_ENABLE_CONSTRAINTS
165 , _stashed_dof_constraints()
166 , _primal_constraint_values()
167 , _adjoint_constraint_values()
169 #ifdef LIBMESH_ENABLE_NODE_CONSTRAINTS
170 , _node_constraints()
172 #ifdef LIBMESH_ENABLE_PERIODIC
175 #ifdef LIBMESH_ENABLE_DIRICHLET
177 , _adjoint_dirichlet_boundaries()
179 , _implicit_neighbor_dofs_initialized(false),
180 _implicit_neighbor_dofs(false),
181 _verify_dirichlet_bc_consistency(true),
190 #ifdef LIBMESH_ENABLE_PERIODIC 213 #ifdef LIBMESH_ENABLE_PERIODIC 261 auto var_instance = new_var_group(var);
262 const auto vn = var_instance.number();
263 _variables.push_back (std::move(var_instance));
276 parallel_object_only();
295 (!
_sp->get_n_nz().empty() ||
296 !
_sp->get_n_oz().empty());
297 this->
comm().
max(computed_sparsity_already);
339 return mesh.node_ptr(i);
346 return mesh.elem_ptr(i);
351 template <
typename iterator_type>
353 iterator_type objects_end,
355 dofobject_accessor objects)
358 parallel_object_only();
362 std::unordered_map<processor_id_type, dof_id_type> ghost_objects_from_proc;
364 iterator_type it = objects_begin;
366 for (; it != objects_end; ++it)
375 ghost_objects_from_proc[obj_procid]++;
380 std::map<processor_id_type, std::vector<dof_id_type>>
385 for (
auto [p, size] : ghost_objects_from_proc)
388 requested_ids[p].reserve(size);
391 for (it = objects_begin; it != objects_end; ++it)
400 if (ghost_objects_from_proc.count(p))
401 libmesh_assert_equal_to (requested_ids[p].size(), ghost_objects_from_proc[p]);
407 typedef std::vector<dof_id_type> datum;
409 auto gather_functor =
410 [
this, &
mesh, &objects]
412 const std::vector<dof_id_type> & ids,
413 std::vector<datum> & data)
420 const std::size_t query_size = ids.size();
422 data.resize(query_size);
423 for (
auto & d : data)
424 d.resize(2 * n_var_groups);
426 for (std::size_t i=0; i != query_size; ++i)
431 libmesh_assert_equal_to (requested->
n_var_groups(sys_num), n_var_groups);
432 for (
unsigned int vg=0; vg != n_var_groups; ++vg)
434 unsigned int n_comp_g =
436 data[i][vg] = n_comp_g;
440 data[i][n_var_groups+vg] = my_first_dof;
445 auto action_functor =
446 [
this, &
mesh, &objects]
448 const std::vector<dof_id_type> & ids,
449 const std::vector<datum> & data)
460 libmesh_assert_equal_to (requested->
processor_id(), pid);
461 for (
unsigned int vg=0; vg != n_var_groups; ++vg)
463 unsigned int n_comp_g =
464 cast_int<unsigned int>(data[i][vg]);
468 dof_id_type my_first_dof = data[i][n_var_groups+vg];
471 (sys_num, vg, my_first_dof);
477 datum * ex =
nullptr;
478 Parallel::pull_parallel_vector_data
479 (this->
comm(), requested_ids, gather_functor, action_functor, ex);
483 for (it = objects_begin; it != objects_end; ++it)
488 for (
unsigned int v=0; v != num_variables; ++v)
490 unsigned int n_comp =
504 const std::map<
const Node *, std::set<subdomain_id_type>> &
505 constraining_subdomains)
509 LOG_SCOPE(
"reinit()",
"DofMap");
512 const bool constraining_subdomains_empty =
513 constraining_subdomains.empty();
523 if (this->_dof_coupling && this->_dof_coupling->empty() && !this->n_variables())
524 this->_dof_coupling =
nullptr;
525 _default_coupling->set_dof_coupling(this->_dof_coupling);
528 unsigned int standard_n_levels =
529 this->use_coupled_neighbor_dofs(
mesh);
530 _default_coupling->set_n_levels
531 (std::max(_default_coupling->n_levels(), standard_n_levels));
539 sys_num = this->sys_number(),
540 n_var_groups = this->n_variable_groups();
544 std::vector<unsigned int> n_vars_per_group; n_vars_per_group.reserve (n_var_groups);
546 for (
unsigned int vg=0; vg<n_var_groups; vg++)
547 n_vars_per_group.push_back (this->variable_group(vg).n_variables());
549 #ifdef LIBMESH_ENABLE_AMR 554 for (
auto & node :
mesh.node_ptr_range())
556 node->clear_old_dof_object();
560 for (
auto & elem :
mesh.element_ptr_range())
562 elem->clear_old_dof_object();
571 for (
auto & elem :
mesh.element_ptr_range())
577 for (
Node & node : elem->node_ref_range())
578 if (node.get_old_dof_object() ==
nullptr)
579 if (node.has_dofs(sys_num))
580 node.set_old_dof_object();
584 if (elem->has_dofs(sys_num))
585 elem->set_old_dof_object();
588 #endif // #ifdef LIBMESH_ENABLE_AMR 597 for (
auto & node :
mesh.node_ptr_range())
598 node->set_n_vars_per_group(sys_num, n_vars_per_group);
601 for (
auto & elem :
mesh.element_ptr_range())
602 elem->set_n_vars_per_group(sys_num, n_vars_per_group);
605 this->_n_SCALAR_dofs = 0;
609 for (
unsigned int vg=0; vg<n_var_groups; vg++)
611 const VariableGroup & vg_description = this->variable_group(vg);
613 const unsigned int n_var_in_group = vg_description.
n_variables();
614 const FEType & base_fe_type = vg_description.
type();
616 const bool add_p_level =
617 #ifdef LIBMESH_ENABLE_AMR 618 !_dont_p_refine.count(vg);
627 this->_n_SCALAR_dofs += base_fe_type.
order.
get_order()*n_var_in_group;
632 const bool extra_hanging_dofs =
636 for (
auto & elem :
mesh.active_element_ptr_range())
644 const bool active_on_elem =
649 if (!active_on_elem && constraining_subdomains_empty)
652 FEType fe_type = base_fe_type;
658 "ERROR: Finite element " 660 <<
" on geometric element " 662 <<
"\nonly supports FEInterface::max_order = " 664 <<
", not fe_type.order = " 665 << base_fe_type.
order);
667 #ifdef LIBMESH_ENABLE_AMR 670 if (base_fe_type.
order + add_p_level*elem->p_level() >
676 <<
" on geometric element " 678 <<
"could not be p refined past FEInterface::max_order = " 683 -
int(base_fe_type.
order));
688 for (
auto n : elem->node_index_range())
690 Node & node = elem->node_ref(n);
695 bool active_on_node = active_on_elem;
697 if (
auto it = constraining_subdomains.find(&node);
698 it != constraining_subdomains.end())
699 for (
auto s : it->second)
702 active_on_node =
true;
709 if (elem->is_vertex(n))
711 const unsigned int old_node_dofs =
714 const unsigned int vertex_dofs =
719 if (vertex_dofs > old_node_dofs)
744 for (
auto & elem :
mesh.active_element_ptr_range())
752 const bool active_on_elem =
757 if (!active_on_elem && constraining_subdomains_empty)
761 for (
auto n : elem->node_index_range())
763 Node & node = elem->node_ref(n);
768 bool active_on_node = active_on_elem;
770 if (
auto it = constraining_subdomains.find(&node);
771 it != constraining_subdomains.end())
772 for (
auto s : it->second)
775 active_on_node =
true;
782 const unsigned int old_node_dofs =
785 const unsigned int vertex_dofs = old_node_dofs?
786 cast_int<unsigned int>(node.
vg_dof_base (sys_num,vg)):0;
788 const unsigned int new_node_dofs =
792 if (elem->is_vertex(n))
794 libmesh_assert_greater_equal (old_node_dofs, vertex_dofs);
804 libmesh_assert_greater_equal (vertex_dofs, new_node_dofs);
824 else if (vertex_dofs == 0)
826 if (new_node_dofs > old_node_dofs)
838 else if (extra_hanging_dofs)
840 if (new_node_dofs > old_node_dofs - vertex_dofs)
843 vertex_dofs + new_node_dofs);
853 libmesh_assert_greater_equal (old_node_dofs, vertex_dofs);
854 if (new_node_dofs > old_node_dofs)
866 const unsigned int dofs_per_elem =
869 elem->set_n_comp_group(sys_num, vg, dofs_per_elem);
881 this->invalidate_dofs(
mesh);
888 const unsigned int sys_num = this->
sys_number();
891 for (
auto & node :
mesh.node_ptr_range())
892 node->invalidate_dofs(sys_num);
895 for (
auto & elem :
mesh.active_element_ptr_range())
896 elem->invalidate_dofs(sys_num);
921 this->_coupling_functors.clear();
938 this->_algebraic_ghosting_functors.clear();
958 #ifdef LIBMESH_ENABLE_AMR 981 parallel_object_only();
984 LOG_SCOPE(
"distribute_dofs()",
"DofMap");
994 libmesh_assert_less (proc_id, n_proc);
999 const std::map<const Node *, std::set<subdomain_id_type>>
1000 constraining_subdomains =
1005 constraining_subdomains);
1020 if (node_major_dofs)
1022 (next_free_dof,
mesh, constraining_subdomains);
1025 (next_free_dof,
mesh, constraining_subdomains);
1037 if (node_major_dofs)
1039 (next_free_dof,
mesh, constraining_subdomains);
1042 (next_free_dof,
mesh, constraining_subdomains);
1044 libmesh_assert_equal_to (next_free_dof,
_end_df[proc_id]);
1059 mesh.elements_end(),
1073 for (
auto & node :
mesh.node_ptr_range())
1082 libmesh_assert_greater_equal (dofid, this->
first_dof(obj_proc_id));
1083 libmesh_assert_less (dofid, this->
end_dof(obj_proc_id));
1087 for (
auto & elem :
mesh.element_ptr_range())
1096 libmesh_assert_greater_equal (dofid, this->
first_dof(obj_proc_id));
1097 libmesh_assert_less (dofid, this->
end_dof(obj_proc_id));
1104 #ifdef LIBMESH_ENABLE_AMR 1126 gf->dofmap_reinit();
1132 gf->dofmap_reinit();
1149 template <
typename T, std::enable_if_t<std::is_same_v<T, dof_
id_type> ||
1150 std::is_same_v<T, std::vector<dof_
id_type>>,
int>>
1153 unsigned int var_num)
const 1158 if constexpr (std::is_same_v<T, dof_id_type>)
1160 else if constexpr (std::is_same_v<T, std::vector<dof_id_type>>)
1167 const unsigned int sys_num = this->
sys_number();
1175 for (
auto & elem :
mesh.active_local_element_ptr_range())
1182 const unsigned int n_nodes = elem->n_nodes();
1185 for (
unsigned int n=0; n<
n_nodes; n++)
1187 const Node & node = elem->node_ref(n);
1192 const unsigned int n_comp = node.
n_comp(sys_num, var_num);
1193 for(
unsigned int i=0; i<n_comp; i++)
1198 if constexpr (std::is_same_v<T, dof_id_type>)
1200 if (
idx == 0 || index > greatest)
1201 {
idx++; greatest = index; }
1203 else if constexpr (std::is_same_v<T, std::vector<dof_id_type>>)
1205 if (
idx.empty() || index >
idx.back())
1206 idx.push_back(index);
1212 const unsigned int n_comp = elem->n_comp(sys_num, var_num);
1213 for (
unsigned int i=0; i<n_comp; i++)
1215 const dof_id_type index = elem->dof_number(sys_num,var_num,i);
1217 if constexpr (std::is_same_v<T, dof_id_type>)
1219 if (
idx == 0 || index > greatest)
1220 {
idx++; greatest = index; }
1222 else if constexpr (std::is_same_v<T, std::vector<dof_id_type>>)
1224 if (
idx.empty() || index >
idx.back())
1225 idx.push_back(index);
1239 for (
const auto & node :
mesh.local_node_ptr_range())
1243 const unsigned int n_comp = node->n_comp(sys_num, var_num);
1244 for (
unsigned int i=0; i<n_comp; i++)
1246 const dof_id_type index = node->dof_number(sys_num,var_num,i);
1248 if constexpr (std::is_same_v<T, dof_id_type>)
1250 if (
idx == 0 || index > greatest)
1251 {
idx++; greatest = index; }
1253 else if constexpr (std::is_same_v<T, std::vector<dof_id_type>>)
1255 if (
idx.empty() || index >
idx.back())
1256 idx.push_back(index);
1265 std::vector<dof_id_type> di_scalar;
1268 if constexpr (std::is_same_v<T, dof_id_type>)
1270 else if constexpr (std::is_same_v<T, std::vector<dof_id_type>>)
1271 idx.insert(
idx.end(), di_scalar.begin(), di_scalar.end());
1277 unsigned int)
const;
1281 unsigned int)
const;
1284 std::map<const Node *, std::set<subdomain_id_type>>
1287 std::map<const Node *, std::set<subdomain_id_type>> constraining_subdomains;
1293 if (!constraint_rows.empty())
1294 for (
auto & elem :
_mesh.active_element_ptr_range())
1298 for (
const Node & node : elem->node_ref_range())
1300 if (
auto it = constraint_rows.find(&node);
1301 it != constraint_rows.end())
1303 for (
const auto & [pr, val] : it->second)
1305 const Node * spline_node =
1306 pr.first->node_ptr(pr.second);
1308 constraining_subdomains[spline_node].insert(sbdid);
1314 return constraining_subdomains;
1321 const std::map<
const Node *, std::set<subdomain_id_type>> &
1322 constraining_subdomains)
1324 const unsigned int sys_num = this->sys_number();
1325 const unsigned int n_var_groups = this->n_variable_groups();
1328 const bool constraining_subdomains_empty =
1329 constraining_subdomains.empty();
1336 for (
auto & elem :
mesh.active_local_element_ptr_range())
1340 const unsigned int n_nodes = elem->n_nodes();
1345 for (
unsigned int n=0; n<
n_nodes; n++)
1347 Node & node = elem->node_ref(n);
1349 for (
unsigned vg=0; vg<n_var_groups; vg++)
1351 const VariableGroup & vg_description(this->variable_group(vg));
1356 bool active_on_node =
1360 if (!active_on_node && !constraining_subdomains_empty)
1361 if (
auto it = constraining_subdomains.find(&node);
1362 it != constraining_subdomains.end())
1363 for (
auto s : it->second)
1366 active_on_node =
true;
1390 for (
unsigned vg=0; vg<n_var_groups; vg++)
1392 const VariableGroup & vg_description(this->variable_group(vg));
1396 if (elem->n_comp_group(sys_num,vg) > 0)
1398 libmesh_assert_equal_to (elem->vg_dof_base(sys_num,vg),
1401 elem->set_vg_dof_base(sys_num,
1406 elem->n_comp_group(sys_num,vg));
1420 for (
auto & node :
mesh.local_node_ptr_range())
1421 for (
unsigned vg=0; vg<n_var_groups; vg++)
1423 const VariableGroup & vg_description(this->variable_group(vg));
1425 if (node->n_comp_group(sys_num,vg))
1428 node->set_vg_dof_base (sys_num,
1433 node->n_comp(sys_num,vg));
1437 this->distribute_scalar_dofs(next_free_dof);
1440 this->assert_no_nodes_missed(
mesh);
1449 const std::map<
const Node *, std::set<subdomain_id_type>> &
1450 constraining_subdomains)
1452 const unsigned int sys_num = this->sys_number();
1453 const unsigned int n_var_groups = this->n_variable_groups();
1456 const bool constraining_subdomains_empty =
1457 constraining_subdomains.empty();
1464 for (
unsigned vg=0; vg<n_var_groups; vg++)
1466 const VariableGroup & vg_description(this->variable_group(vg));
1468 const unsigned int n_vars_in_group = vg_description.
n_variables();
1474 for (
auto & elem :
mesh.active_local_element_ptr_range())
1480 const bool active_on_elem =
1485 if (!active_on_elem && constraining_subdomains_empty)
1488 const unsigned int n_nodes = elem->n_nodes();
1491 for (
unsigned int n=0; n<
n_nodes; n++)
1493 Node & node = elem->node_ref(n);
1495 bool active_on_node = active_on_elem;
1496 if (!active_on_node)
1497 if (
auto it = constraining_subdomains.find(&node);
1498 it != constraining_subdomains.end())
1499 for (
auto s : it->second)
1502 active_on_node =
true;
1506 if (!active_on_node)
1518 next_free_dof += (n_vars_in_group*
1524 if (elem->n_comp_group(sys_num,vg) > 0)
1526 libmesh_assert_equal_to (elem->vg_dof_base(sys_num,vg),
1529 elem->set_vg_dof_base(sys_num,
1533 next_free_dof += (n_vars_in_group*
1534 elem->n_comp_group(sys_num,vg));
1546 for (
auto & node :
mesh.local_node_ptr_range())
1547 if (node->n_comp_group(sys_num,vg))
1550 node->set_vg_dof_base (sys_num,
1554 next_free_dof += (n_vars_in_group*
1555 node->n_comp_group(sys_num,vg));
1559 this->distribute_scalar_dofs(next_free_dof);
1562 this->assert_no_nodes_missed(
mesh);
1594 MeshTools::libmesh_assert_valid_procids<Node>(
mesh);
1596 for (
auto & node :
mesh.local_node_ptr_range())
1598 unsigned int n_var_g = node->n_var_groups(this->
sys_number());
1599 for (
unsigned int vg=0; vg != n_var_g; ++vg)
1601 unsigned int n_comp_g =
1604 node->vg_dof_base(this->
sys_number(), vg) : 0;
1622 for (
const auto & gf :
as_range(gf_begin, gf_end))
1627 (*gf)(elems_begin, elems_end, p, more_elements_to_ghost);
1632 #if defined(LIBMESH_ENABLE_DEPRECATED) && defined(LIBMESH_ENABLE_AMR) 1633 std::vector<std::pair<const Elem*, const CouplingMatrix*>> children_to_couple;
1634 for (
auto it = more_elements_to_ghost.begin();
1635 it != more_elements_to_ghost.end();)
1637 const Elem * elem = it->first;
1640 libmesh_deprecated();
1641 std::vector<const Elem*> children_to_ghost;
1644 for (
const Elem * child : children_to_ghost)
1645 if (child->processor_id() != p)
1646 children_to_couple.emplace_back(child, it->second);
1648 it = more_elements_to_ghost.erase(it);
1653 more_elements_to_ghost.insert(children_to_couple.begin(),
1654 children_to_couple.end());
1657 for (
const auto & [elem, elem_cm] : more_elements_to_ghost)
1663 if (
const auto existing_it = elements_to_ghost.find(elem);
1664 existing_it == elements_to_ghost.end())
1665 elements_to_ghost.emplace(elem, elem_cm);
1668 if (existing_it->second)
1675 if (temporary_coupling_matrices.empty() ||
1676 !temporary_coupling_matrices.count(existing_it->second))
1682 auto result_pr = temporary_coupling_matrices.insert(std::make_unique<CouplingMatrix>(*existing_it->second));
1683 existing_it->second = result_pr.first->get();
1699 if (
const auto temp_it = temporary_coupling_matrices.find(existing_it->second);
1700 temp_it != temporary_coupling_matrices.end())
1701 temporary_coupling_matrices.erase(temp_it);
1703 existing_it->second =
nullptr;
1718 LOG_SCOPE(
"add_neighbors_to_send_list()",
"DofMap");
1727 =
mesh.active_local_elements_begin();
1729 =
mesh.active_local_elements_end();
1738 temporary_coupling_matrices,
1741 local_elem_it, local_elem_end,
mesh.processor_id());
1744 temporary_coupling_matrices,
1747 local_elem_it, local_elem_end,
mesh.processor_id());
1752 std::map<const CouplingMatrix *, std::vector<unsigned int>>
1753 column_variable_lists;
1755 for (
const auto & [partner, ghost_coupling] : elements_to_send)
1758 libmesh_assert_not_equal_to
1766 libmesh_assert_equal_to (ghost_coupling->size(), n_var);
1769 std::map<const CouplingMatrix *, std::vector<unsigned int>>::const_iterator
1770 column_variable_list = column_variable_lists.find(ghost_coupling);
1773 if (column_variable_list == column_variable_lists.end())
1775 auto inserted_variable_list_pair =
1776 column_variable_lists.emplace(ghost_coupling, std::vector<unsigned int>());
1777 column_variable_list = inserted_variable_list_pair.first;
1779 std::vector<unsigned int> & new_variable_list =
1780 inserted_variable_list_pair.first->second;
1782 std::vector<unsigned char> has_variable(n_var,
false);
1784 for (
unsigned int vi = 0; vi != n_var; ++vi)
1788 for (
const auto & vj : ccr)
1789 has_variable[vj] =
true;
1791 for (
unsigned int vj = 0; vj != n_var; ++vj)
1793 if (has_variable[vj])
1794 new_variable_list.push_back(vj);
1798 const std::vector<unsigned int> & variable_list =
1799 column_variable_list->second;
1801 for (
const auto & vj : variable_list)
1803 std::vector<dof_id_type> di;
1811 libmesh_assert_less(d, this->
n_dofs());
1818 std::vector<dof_id_type> di;
1822 for (
const auto & dof : di)
1826 libmesh_assert_less(dof, this->
n_dofs());
1834 temporary_coupling_matrices.clear();
1844 for ( ; local_elem_it != local_elem_end; ++local_elem_it)
1846 const Elem * elem = *local_elem_it;
1848 std::vector<dof_id_type> di;
1852 for (
const auto & dof : di)
1856 libmesh_assert_less(dof, this->
n_dofs());
1866 LOG_SCOPE(
"prepare_send_list()",
"DofMap");
1878 libMesh::out <<
"WARNING: You have specified both an extra send list function and object.\n" 1879 <<
" Are you sure this is what you meant to do??" 1895 std::vector<dof_id_type>::iterator new_end =
1911 #ifdef LIBMESH_ENABLE_CONSTRAINTS 1936 bool implicit_neighbor_dofs =
1943 if (implicit_neighbor_dofs)
1965 if (!implicit_neighbor_dofs)
1973 bool all_discontinuous_dofs =
true;
1977 all_discontinuous_dofs =
false;
1979 if (all_discontinuous_dofs)
1980 implicit_neighbor_dofs =
true;
1983 return implicit_neighbor_dofs;
1997 mat->attach_sparsity_pattern (*
_sp);
1999 mat->update_sparsity_pattern (
_sp->get_sparsity_pattern());
2004 _sp->clear_full_sparsity();
2037 #ifdef LIBMESH_ENABLE_DEPRECATED 2048 &coupling_functor) ==
2065 #ifndef LIBMESH_ENABLE_DEPRECATED 2077 &coupling_functor) ==
2094 #ifdef LIBMESH_ENABLE_DEPRECATED 2098 &evaluable_functor),
2105 &evaluable_functor) ==
2121 &evaluable_functor);
2123 #ifndef LIBMESH_ENABLE_DEPRECATED 2135 &evaluable_functor) ==
2148 const std::vector<dof_id_type> & dof_indices_in,
2151 const unsigned int n_original_dofs = dof_indices_in.size();
2153 #ifdef LIBMESH_ENABLE_AMR 2156 libmesh_assert_equal_to (dof_indices_in.size(), Ue.
size());
2157 bool has_constrained_dofs =
false;
2159 for (
unsigned int il=0; il != n_original_dofs; ++il)
2165 libmesh_assert_less (ig, Ug.
size());
2173 if (has_constrained_dofs)
2176 std::vector<dof_id_type> constrained_dof_indices(dof_indices_in);
2183 libmesh_assert_equal_to (dof_indices_in.size(), C.
m());
2184 libmesh_assert_equal_to (constrained_dof_indices.size(), C.
n());
2190 for (
unsigned int i=0; i != n_original_dofs; i++)
2194 const unsigned int n_constrained =
2195 cast_int<unsigned int>(constrained_dof_indices.size());
2196 for (
unsigned int j=0; j<n_constrained; j++)
2198 const dof_id_type jg = constrained_dof_indices[j];
2206 Ue.
el(i) += C(i,j)*Ug(jg);
2215 libmesh_assert_equal_to (n_original_dofs, Ue.
size());
2217 for (
unsigned int il=0; il<n_original_dofs; il++)
2230 std::vector<dof_id_type> & di)
const 2254 std::size_t tot_size = 0;
2266 std::vector<const Node *> elem_nodes;
2270 for (
unsigned int vg=0; vg<n_var_groups; vg++)
2273 const unsigned int vars_in_group = var.
n_variables();
2278 for (
unsigned int vig=0; vig != vars_in_group; ++vig)
2283 std::vector<dof_id_type> di_new;
2285 di.insert( di.end(), di_new.begin(), di_new.end());
2289 for (
unsigned int vig=0; vig != vars_in_group; ++vig)
2293 cast_int<unsigned int>(elem_nodes.size()),
2308 for (
unsigned int vg=0; vg<n_var_groups; vg++)
2311 const unsigned int vars_in_group = var.
n_variables();
2317 for (
unsigned int vig=0; vig != vars_in_group; ++vig)
2322 std::vector<dof_id_type> di_new;
2324 di.insert( di.end(), di_new.begin(), di_new.end());
2328 for (
unsigned int vig=0; vig != vars_in_group; ++vig)
2340 libmesh_assert_equal_to (tot_size, di.size());
2346 std::vector<dof_id_type> & di,
2347 const unsigned int vn,
2356 const std::vector<dof_id_type> & scalar_dof_indices) {
2368 std::vector<dof_id_type> & di)
const 2384 const unsigned int sys_num = this->
sys_number();
2387 for (
unsigned int vg=0; vg<n_var_groups; vg++)
2390 const unsigned int vars_in_group = var.
n_variables();
2394 for (
unsigned int vig=0; vig != vars_in_group; ++vig)
2396 std::vector<dof_id_type> di_new;
2398 di.insert( di.end(), di_new.begin(), di_new.end());
2404 for (
unsigned int vig=0; vig != vars_in_group; ++vig)
2406 for (
int i=0; i != n_comp; ++i)
2409 node->
dof_number(sys_num, vg, vig, i, n_comp);
2410 libmesh_assert_not_equal_to
2421 std::vector<dof_id_type> & di,
2422 const unsigned int vn)
const 2443 const unsigned int sys_num = this->
sys_number();
2451 std::vector<dof_id_type> di_new;
2453 di.insert( di.end(), di_new.begin(), di_new.end());
2457 const unsigned int vig = vn - var.
number();
2459 for (
int i=0; i != n_comp; ++i)
2462 node->
dof_number(sys_num, vg, vig, i, n_comp);
2463 libmesh_assert_not_equal_to
2473 std::vector<dof_id_type> & di,
2474 const unsigned int vn)
const 2481 #ifdef LIBMESH_ENABLE_AMR 2485 std::vector<dof_id_type> & di,
2486 const unsigned int vn)
const 2492 #endif // LIBMESH_ENABLE_AMR 2499 std::vector<dof_id_type> & di,
2500 const unsigned int vn)
const 2507 LOG_SCOPE(
"_node_dof_indices()",
"DofMap");
2509 const unsigned int sys_num = this->
sys_number();
2510 const auto [vg, vig] =
2512 const unsigned int n_comp = obj.
n_comp_group(sys_num,vg);
2516 const bool extra_hanging_dofs =
2519 const bool add_p_level =
2520 #ifdef LIBMESH_ENABLE_AMR 2530 const unsigned int nc =
2537 if (extra_hanging_dofs && nc && !elem.
is_vertex(n))
2539 const int dof_offset = n_comp - nc;
2550 for (
unsigned int i = dof_offset; i != n_comp; ++i)
2565 const unsigned int good_nc =
2566 std::min(static_cast<unsigned int>(n_comp), nc);
2567 for (
unsigned int i=0; i != good_nc; ++i)
2574 for (
unsigned int i=good_nc; i != nc; ++i)
2582 std::vector<dof_id_type> & di,
2583 const unsigned int vg,
2584 const unsigned int vig,
2585 const Node *
const * nodes,
2587 const unsigned int v
2590 std::size_t & tot_size
2608 std::vector<dof_id_type> & functor_di,
2609 const dof_id_type dof) { functor_di.push_back(dof); });
2613 const unsigned int vn,
2614 #ifdef LIBMESH_ENABLE_AMR
2621 LOG_SCOPE(
"SCALAR_dof_indices()",
"DofMap");
2625 #ifdef LIBMESH_ENABLE_AMR 2641 di.resize(n_dofs_vn);
2642 for (
int i = 0; i != n_dofs_vn; ++i)
2667 for (
const auto & di : dof_indices_in)
2676 template <
typename DofObjectSub
class>
2678 unsigned int var_num)
const 2684 std::vector<dof_id_type> di;
2696 #ifdef LIBMESH_ENABLE_AMR 2699 std::vector<dof_id_type> & di,
2700 const unsigned int vn)
const 2702 LOG_SCOPE(
"old_dof_indices()",
"DofMap");
2707 const unsigned int sys_num = this->
sys_number();
2709 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS 2710 const bool is_inf = elem->
infinite();
2724 std::vector<const Node *> elem_nodes;
2725 const Node *
const * nodes_ptr;
2732 nodes_ptr = elem_nodes.data();
2733 n_nodes = cast_int<unsigned int>(elem_nodes.size());
2743 for (
unsigned int vg=0; vg<n_var_groups; vg++)
2746 const unsigned int vars_in_group = var.
n_variables();
2748 for (
unsigned int vig=0; vig<vars_in_group; vig++)
2750 const unsigned int v = var.
number(vig);
2758 std::vector<dof_id_type> di_new;
2760 di.insert( di.end(), di_new.begin(), di_new.end());
2768 const bool add_p_level =
2769 #ifdef LIBMESH_ENABLE_AMR 2777 int p_adjustment = 0;
2780 libmesh_assert_greater (elem->
p_level(), 0);
2787 p_adjustment *= add_p_level;
2790 int extra_order =
int(add_p_level*elem->
p_level()) + p_adjustment;
2792 const bool extra_hanging_dofs =
2799 for (
unsigned int n=0; n<
n_nodes; n++)
2801 const Node * node = nodes_ptr[n];
2808 const unsigned int nc =
2809 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS 2813 ndan (type, var.
type().
order + extra_order, n);
2815 const int n_comp = old_dof_obj.
n_comp_group(sys_num,vg);
2821 if (extra_hanging_dofs && !elem->is_vertex(n))
2823 const int dof_offset = n_comp - nc;
2835 for (
int i=n_comp-1; i>=dof_offset; i--)
2838 old_dof_obj.
dof_number(sys_num, vg, vig, i, n_comp);
2857 const unsigned int old_nc =
2858 std::min(static_cast<unsigned int>(n_comp), nc);
2859 for (
unsigned int i=0; i != old_nc; ++i)
2862 old_dof_obj.
dof_number(sys_num, vg, vig, i, n_comp);
2868 for (
unsigned int i=old_nc; i != nc; ++i)
2874 const unsigned int nc =
2881 const unsigned int n_comp =
2884 if (old_dof_obj.
n_systems() > sys_num &&
2888 for (
unsigned int i=0; i<nc; i++)
2891 old_dof_obj.
dof_number(sys_num, vg, vig, i, n_comp);
2915 #endif // LIBMESH_ENABLE_AMR 2918 #ifdef LIBMESH_ENABLE_CONSTRAINTS 2922 typedef std::set<dof_id_type> RCSet;
2925 RCSet dof_set (elem_dofs.begin(), elem_dofs.end());
2934 for (
const auto & dof : elem_dofs)
2938 DofConstraints::const_iterator
2952 for (
const auto & pr : constraint_row)
2953 if (!dof_set.count (pr.first))
2955 dof_set.insert (pr.first);
2967 elem_dofs.insert (elem_dofs.end(),
2968 dof_set.begin(), dof_set.end());
2979 #endif // LIBMESH_ENABLE_CONSTRAINTS 2992 std::ostringstream os;
2997 const char * may_equal =
" <= ";
3002 if (mat->need_full_sparsity_pattern())
3006 long double avg_n_nz = 0, avg_n_oz = 0;
3010 for (
const auto & val :
_sp->get_n_nz())
3012 max_n_nz = std::max(max_n_nz, val);
3016 std::size_t n_nz_size =
_sp->get_n_nz().size();
3022 avg_n_nz /= std::max(n_nz_size,std::size_t(1));
3024 for (
const auto & val :
_sp->get_n_oz())
3026 max_n_oz = std::max(max_n_oz, val);
3030 std::size_t n_oz_size =
_sp->get_n_oz().size();
3036 avg_n_oz /= std::max(n_oz_size,std::size_t(1));
3039 os <<
" DofMap Sparsity\n Average On-Processor Bandwidth" 3040 << may_equal << avg_n_nz <<
'\n';
3042 os <<
" Average Off-Processor Bandwidth" 3043 << may_equal << avg_n_oz <<
'\n';
3045 os <<
" Maximum On-Processor Bandwidth" 3046 << may_equal << max_n_nz <<
'\n';
3048 os <<
" Maximum Off-Processor Bandwidth" 3049 << may_equal << max_n_oz << std::endl;
3051 #ifdef LIBMESH_ENABLE_CONSTRAINTS 3053 std::size_t n_constraints = 0, max_constraint_length = 0,
3055 long double avg_constraint_length = 0.;
3063 std::size_t rowsize = row.size();
3065 max_constraint_length = std::max(max_constraint_length,
3067 avg_constraint_length += rowsize;
3074 this->
comm().
sum(n_constraints);
3076 this->
comm().
sum(avg_constraint_length);
3077 this->
comm().
max(max_constraint_length);
3079 os <<
" DofMap Constraints\n Number of DoF Constraints = " 3083 <<
" Number of Heterogenous Constraints= " << n_rhss;
3086 avg_constraint_length /= n_constraints;
3089 <<
" Average DoF Constraint Length= " << avg_constraint_length;
3092 #ifdef LIBMESH_ENABLE_NODE_CONSTRAINTS 3093 std::size_t n_node_constraints = 0, max_node_constraint_length = 0,
3095 long double avg_node_constraint_length = 0.;
3104 std::size_t rowsize = row.size();
3106 max_node_constraint_length = std::max(max_node_constraint_length,
3108 avg_node_constraint_length += rowsize;
3109 n_node_constraints++;
3111 if (pr.second !=
Point(0))
3115 this->
comm().
sum(n_node_constraints);
3116 this->
comm().
sum(n_node_rhss);
3117 this->
comm().
sum(avg_node_constraint_length);
3118 this->
comm().
max(max_node_constraint_length);
3120 os <<
"\n Number of Node Constraints = " << n_node_constraints;
3123 <<
" Number of Heterogenous Node Constraints= " << n_node_rhss;
3124 if (n_node_constraints)
3126 avg_node_constraint_length /= n_node_constraints;
3127 os <<
"\n Maximum Node Constraint Length= " << max_node_constraint_length
3129 <<
" Average Node Constraint Length= " << avg_node_constraint_length;
3131 #endif // LIBMESH_ENABLE_NODE_CONSTRAINTS 3135 #endif // LIBMESH_ENABLE_CONSTRAINTS 3142 _sc = std::make_unique<StaticCondensationDofMap>(
mesh, sys, *
this);
3151 template LIBMESH_EXPORT
bool DofMap::is_evaluable<Elem>(
const Elem &,
unsigned int)
const;
3152 template LIBMESH_EXPORT
bool DofMap::is_evaluable<Node>(
const Node &,
unsigned int)
const;
std::vector< VariableGroup > _variable_groups
The finite element type for each variable group.
void find_connected_dofs(std::vector< dof_id_type > &elem_dofs) const
Finds all the DOFS associated with the element DOFs elem_dofs.
std::unique_ptr< SparsityPattern::Build > _sp
The sparsity pattern of the global matrix.
static unsigned int n_dofs_per_elem(const unsigned int dim, const FEType &fe_t, const ElemType t)
class FEType hides (possibly multiple) FEFamily and approximation orders, thereby enabling specialize...
FEFamily family
The type of finite element.
T command_line_next(std::string name, T default_value)
Use GetPot's search()/next() functions to get following arguments from the command line...
A class holding degree of freedom information pertinent to static condensation.
dof_id_type vg_dof_base(const unsigned int s, const unsigned int vg) const
VariableGroup DoF indices are indexed as id = base + var_in_vg*ncomp + comp This method allows for di...
bool _implicit_neighbor_dofs_initialized
Bools to indicate if we override the –implicit_neighbor_dofs commandline options.
ElemType
Defines an enum for geometric element types.
std::vector< GhostingFunctor * >::const_iterator GhostingFunctorIterator
Iterator type for coupling and algebraic ghosting functor ranges.
unsigned int n_variable_groups() const
bool _implicit_neighbor_dofs
dof_id_type dof_number(const unsigned int s, const unsigned int var, const unsigned int comp) const
DefaultCoupling & default_coupling()
Default coupling functor.
constraint_rows_type & get_constraint_rows()
Constraint rows accessors.
A Node is like a Point, but with more information.
This abstract base class defines the interface by which library code and user code can report associa...
dof_id_type n_SCALAR_dofs() const
void build_constraint_matrix_and_vector(DenseMatrix< Number > &C, DenseVector< Number > &H, std::vector< dof_id_type > &elem_dofs, int qoi_index=-1, const bool called_recursively=false) const
Build the constraint matrix C and the forcing vector H associated with the element degree of freedom ...
const unsigned int invalid_uint
A number which is used quite often to represent an invalid or uninitialized value for an unsigned int...
unsigned int n_comp(const unsigned int s, const unsigned int var) const
void reinit(MeshBase &mesh, const std::map< const Node *, std::set< subdomain_id_type >> &constraining_subdomains)
Reinitialize the underlying data structures conformal to the current mesh.
bool _error_on_constraint_loop
This flag indicates whether or not we do an opt-mode check for the presence of constraint loops...
unsigned int n_var_groups(const unsigned int s) const
void * _extra_sparsity_context
A pointer associated with the extra sparsity that can optionally be passed in.
void extract_local_vector(const NumericVector< Number > &Ug, const std::vector< dof_id_type > &dof_indices, DenseVectorBase< Number > &Ue) const
Builds the local element vector Ue from the global vector Ug, accounting for any constrained degrees ...
void dof_indices(const Elem *const elem, std::vector< dof_id_type > &di) const
dof_id_type n_dofs() const
The definition of the const_element_iterator struct.
std::size_t distribute_dofs(MeshBase &)
Distribute dofs on the current mesh.
void set_implicit_neighbor_dofs(bool implicit_neighbor_dofs)
Allow the implicit_neighbor_dofs flag to be set programmatically.
void add_default_ghosting()
Add the default functor(s) for coupling and algebraic ghosting.
We're using a class instead of a typedef to allow forward declarations and future flexibility...
void local_variable_indices(T &idx, const MeshBase &mesh, unsigned int var_num) const
If T == dof_id_type, counts, if T == std::vector<dof_id_type>, fills an array of, those dof indices w...
bool is_periodic_boundary(const boundary_id_type boundaryid) const
std::vector< dof_id_type > _first_df
First DOF index on processor p.
GhostingFunctorIterator algebraic_ghosting_functors_begin() const
Beginning of range of algebraic ghosting functors.
virtual numeric_index_type size() const =0
virtual void set_mesh(const MeshBase *mesh)
It should be called after cloning a ghosting functor.
RefinementState p_refinement_flag() const
std::unique_ptr< StaticCondensationDofMap > _sc
Static condensation class.
std::vector< dof_id_type > _send_list
A list containing all the global DOF indices that affect the solution on my processor.
const FEType & variable_type(const unsigned int c) const
std::unique_ptr< SparsityPattern::Build > build_sparsity(const MeshBase &mesh, bool calculate_constrained=false, bool use_condensed_system=false) const
Builds a sparsity pattern for matrices using the current degree-of-freedom numbering and coupling...
void set_verify_dirichlet_bc_consistency(bool val)
Set the _verify_dirichlet_bc_consistency flag.
bool is_attached(SparseMatrix< Number > &matrix)
Matrices should not be attached more than once.
void attach_matrix(SparseMatrix< Number > &matrix)
Additional matrices may be attached to this DofMap.
void remove_ghosting_functor(GhostingFunctor &ghosting_functor)
Removes a functor which was previously added to the set of ghosting functors.
This is the base class from which all geometric element types are derived.
void clear_send_list()
Clears the _send_list vector.
DefaultCoupling & default_algebraic_ghosting()
Default algebraic ghosting functor.
void active_family_tree(std::vector< const Elem *> &active_family, bool reset=true) const
Same as the family_tree() member, but only adds the active children.
void attach_sparsity_pattern(const SparsityPattern::Build &sp)
Set a pointer to a sparsity pattern to use.
This proxy class acts like a container of indices from a single coupling row.
const Parallel::Communicator & comm() const
unsigned int p_level() const
OrderWrapper order
The approximation order of the element.
bool use_coupled_neighbor_dofs(const MeshBase &mesh) const
Tells other library functions whether or not this problem includes coupling between dofs in neighbori...
std::map< const Elem *, const CouplingMatrix *, CompareDofObjectsByPIDAndThenID > map_type
What elements do we care about and what variables do we care about on each element?
void reinit_static_condensation()
Calls reinit on the static condensation map if it exists.
The StoredRange class defines a contiguous, divisible set of objects.
void set_vg_dof_base(const unsigned int s, const unsigned int vg, const dof_id_type db)
VariableGroup DoF indices are indexed as id = base + var_in_vg*ncomp + comp This method allows for di...
GhostingFunctorIterator algebraic_ghosting_functors_end() const
End of range of algebraic ghosting functors.
virtual void augment_send_list(std::vector< dof_id_type > &send_list)=0
User-defined function to augment the send list.
The libMesh namespace provides an interface to certain functionality in the library.
bool has_dofs(const unsigned int s=libMesh::invalid_uint) const
virtual void zero()=0
Set every element in the vector to 0.
void set_error_on_constraint_loop(bool error_on_constraint_loop)
Real distance(const Point &p)
void add_coupling_functor(GhostingFunctor &coupling_functor, bool to_mesh=true)
Adds a functor which can specify coupling requirements for creation of sparse matrices.
std::string get_info() const
Gets summary info about the sparsity bandwidth and constraints.
static unsigned int max_order(const FEType &fe_t, const ElemType &el_t)
unsigned int sys_number() const
void SCALAR_dof_indices(std::vector< dof_id_type > &di, const unsigned int vn, const bool old_dofs=false) const
Fills the vector di with the global degree of freedom indices corresponding to the SCALAR variable vn...
uint8_t processor_id_type
This is the MeshBase class.
std::vector< dof_id_type > _first_scalar_df
First DOF index for SCALAR variable v, or garbage for non-SCALAR variable v.
const Variable & variable(const unsigned int c) const override
This class implements the default algebraic coupling in libMesh: elements couple to themselves...
AdjointDofConstraintValues _adjoint_constraint_values
bool _constrained_sparsity_construction
This flag indicates whether or not we explicitly take constraint equations into account when computin...
dof_id_type end_dof() const
AugmentSendList * _augment_send_list
Function object to call to add extra entries to the send list.
bool need_full_sparsity_pattern
Default false; set to true if any attached matrix requires a full sparsity pattern.
void distribute_local_dofs_var_major(dof_id_type &next_free_dof, MeshBase &mesh, const std::map< const Node *, std::set< subdomain_id_type >> &constraining_subdomains)
Distributes the global degrees of freedom, for dofs on this processor.
virtual void clear() override
Free all new memory associated with the object, but restore its original state, with the mesh pointer...
void _node_dof_indices(const Elem &elem, unsigned int n, const DofObject &obj, std::vector< dof_id_type > &di, const unsigned int vn) const
Helper function that implements the element-nodal versions of dof_indices and old_dof_indices.
void reinit_send_list(MeshBase &mesh)
Clears the _send_list vector and then rebuilds it.
processor_id_type n_processors() const
const dof_id_type n_nodes
dof_id_type first_dof() const
std::unordered_map< unsigned int, unsigned int > _var_to_vg
A map from variable number to variable group number.
This class defines the notion of a variable in the system.
bool has_static_condensation() const
Checks whether we have static condensation.
void add_neighbors_to_send_list(MeshBase &mesh)
Adds entries to the _send_list vector corresponding to DoFs on elements neighboring the current proce...
std::vector< dof_id_type > _first_old_scalar_df
First old DOF index for SCALAR variable v, or garbage for non-SCALAR variable v.
void(* _extra_sparsity_function)(SparsityPattern::Graph &, std::vector< dof_id_type > &n_nz, std::vector< dof_id_type > &n_oz, void *)
A function pointer to a function to call to add extra entries to the sparsity pattern.
const Node & node_ref(const unsigned int i) const
dof_id_type _n_SCALAR_dofs
The total number of SCALAR dofs associated to all SCALAR variables.
void assert_no_nodes_missed(MeshBase &mesh)
void set_nonlocal_dof_objects(iterator_type objects_begin, iterator_type objects_end, MeshBase &mesh, dofobject_accessor objects)
Helper function for distributing dofs in parallel.
unsigned int n_variables() const
static bool extra_hanging_dofs(const FEType &fe_t)
virtual unsigned int n_nodes() const =0
std::set< std::unique_ptr< CouplingMatrix >, Utility::CompareUnderlying > CouplingMatricesSet
virtual unsigned int size() const =0
static const processor_id_type invalid_processor_id
An invalid processor_id to distinguish DoFs that have not been assigned to a processor.
unsigned int n_vars(const unsigned int s, const unsigned int vg) const
Manages consistently variables, degrees of freedom, and coefficient vectors.
unsigned int n_variables() const override
unsigned int n_systems() const
void add_variable_group(VariableGroup var_group)
Add an unknown of order order and finite element type type to the system of equations.
SimpleRange< IndexType > as_range(const std::pair< IndexType, IndexType > &p)
Helper function that allows us to treat a homogenous pair as a range.
This base class provides a minimal set of interfaces for satisfying user requests for...
const Node *const * get_nodes() const
We're using a class instead of a typedef to allow forward declarations and future flexibility...
bool is_constrained_dof(const dof_id_type dof) const
The Tri3Subdivision element is a three-noded subdivision surface shell element used in mechanics calc...
static const dof_id_type invalid_id
An invalid id to distinguish an uninitialized DofObject.
const VariableGroup & variable_group(const unsigned int c) const
dof_id_type n_old_dofs() const
std::vector< GhostingFunctor * > _coupling_functors
The list of all GhostingFunctor objects to be used when coupling degrees of freedom in matrix sparsit...
DofConstraints _dof_constraints
Data structure containing DOF constraints.
DofMap(const unsigned int sys_number, MeshBase &mesh)
Constructor.
CouplingMatrix * _dof_coupling
Degree of freedom coupling.
static void merge_ghost_functor_outputs(GhostingFunctor::map_type &elements_to_ghost, CouplingMatricesSet &temporary_coupling_matrices, const GhostingFunctorIterator &gf_begin, const GhostingFunctorIterator &gf_end, const MeshBase::const_element_iterator &elems_begin, const MeshBase::const_element_iterator &elems_end, processor_id_type p)
DofObject * get_old_dof_object()
Pointer accessor for previously public old_dof_object.
bool active_on_subdomain(subdomain_id_type sid) const
void create_static_condensation(MeshBase &mesh, System &system)
Add a static condensation class.
void print_info(std::ostream &os=libMesh::out) const
Prints summary info about the sparsity bandwidth and constraints.
void * _extra_send_list_context
A pointer associated with the extra send list that can optionally be passed in.
bool computed_sparsity_already() const
Returns true iff a sparsity pattern has already been computed.
This class defines a logically grouped set of variables in the system.
void update_sparsity_pattern(SparseMatrix< Number > &matrix) const
Additional matrices may be be temporarily initialized by this DofMap.
void set_n_comp_group(const unsigned int s, const unsigned int vg, const unsigned int ncomp)
Sets the number of components for VariableGroup vg of system s associated with this DofObject...
DofObject & get_old_dof_object_ref()
As above, but do not use in situations where the old_dof_object may be nullptr, since this function a...
static n_dofs_at_node_ptr n_dofs_at_node_function(const unsigned int dim, const FEType &fe_t)
std::string enum_to_string(const T e)
int get_order() const
Explicitly request the order as an int.
std::vector< SparseMatrix< Number > *> _matrices
Additional matrices handled by this object.
GhostingFunctorIterator coupling_functors_end() const
End of range of coupling functors.
DofObject * elem_ptr(MeshBase &mesh, dof_id_type i) const
std::vector< GhostingFunctor * > _algebraic_ghosting_functors
The list of all GhostingFunctor objects to be used when distributing ghosted vectors.
static FEContinuity get_continuity(const FEType &fe_type)
Returns the input FEType's FEContinuity based on the underlying FEFamily and potentially the Order...
void attach_dof_map(const DofMap &dof_map)
Set a pointer to the DofMap to use.
static unsigned int n_dofs_at_node(const unsigned int dim, const FEType &fe_t, const ElemType t, const unsigned int n)
void distribute_scalar_dofs(dof_id_type &next_free_dof)
virtual numeric_index_type first_local_index() const =0
std::unique_ptr< PeriodicBoundaries > _periodic_boundaries
Data structure containing periodic boundaries.
virtual bool need_full_sparsity_pattern() const
void remove_coupling_functor(GhostingFunctor &coupling_functor)
Removes a functor which was previously added to the set of coupling functors, from both this DofMap a...
unsigned int(* n_dofs_at_node_ptr)(const ElemType, const Order, const unsigned int)
virtual void update_sparsity_pattern(const SparsityPattern::Graph &)
Updates the matrix sparsity pattern.
void process_constraints(MeshBase &)
Postprocesses any constrained degrees of freedom to be constrained only in terms of unconstrained dof...
subdomain_id_type subdomain_id() const
void max(const T &r, T &o, Request &req) const
void _dof_indices(const Elem &elem, int p_level, std::vector< dof_id_type > &di, const unsigned int vg, const unsigned int vig, const Node *const *nodes, unsigned int n_nodes, const unsigned int v #ifdef DEBUG, std::size_t &tot_size #endif) const
Helper function that gets the dof indices on the current element for a non-SCALAR type variable...
void invalidate_dofs(MeshBase &mesh) const
Invalidates all active DofObject dofs for this system.
virtual bool is_vertex(const unsigned int i) const =0
bool _verify_dirichlet_bc_consistency
Flag which determines whether we should do some additional checking of the consistency of the Dirichl...
std::unique_ptr< DefaultCoupling > _default_coupling
The default coupling GhostingFunctor, used to implement standard libMesh sparsity pattern constructio...
DofConstraintValueMap _primal_constraint_values
std::vector< Variable > _variables
The finite element type for each variable.
DofConstraints _stashed_dof_constraints
void remove_default_ghosting()
Remove any default ghosting functor(s).
std::vector< dof_id_type > _end_old_df
Last old DOF index (plus 1) on processor p.
SparsityPattern::AugmentSparsityPattern * _augment_sparsity_pattern
Function object to call to add extra entries to the sparsity pattern.
std::map< dof_id_type, Real, std::less< dof_id_type >, Threads::scalable_allocator< std::pair< const dof_id_type, Real > > > DofConstraintRow
A row of the Dof constraint matrix.
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...
The DofObject defines an abstract base class for objects that have degrees of freedom associated with...
void clear_sparsity()
Clears the sparsity pattern.
std::size_t compute_dof_info(dof_id_type n_local_dofs)
compute the key degree of freedom information given the local number of degrees of freedom on this pr...
dof_id_type n_local_dofs() const
void parallel_reduce(const Range &range, Body &body)
Execute the provided reduction operation in parallel on the specified range.
std::unordered_set< unsigned int > _dont_p_refine
A container of variable groups that we should not p-refine.
unsigned int number(unsigned int v) const
std::pair< unsigned int, unsigned int > var_to_vg_and_offset(const unsigned int s, const unsigned int var) const
void(* _extra_send_list_function)(std::vector< dof_id_type > &, void *)
A function pointer to a function to call to add extra entries to the send list.
DofObject * node_ptr(MeshBase &mesh, dof_id_type i) const
Defines an abstract dense vector base class for use in Finite Element-type computations.
std::map< const Node *, Real, std::less< const Node * >, Threads::scalable_allocator< std::pair< const Node *const, Real > > > NodeConstraintRow
A row of the Node constraint mapping.
MeshBase & _mesh
The mesh that system uses.
void prepare_send_list()
Takes the _send_list vector (which may have duplicate entries) and sorts it.
bool all_semilocal_indices(const std::vector< dof_id_type > &dof_indices) const
bool on_command_line(std::string arg)
virtual bool infinite() const =0
std::unique_ptr< DefaultCoupling > _default_evaluating
The default algebraic GhostingFunctor, used to implement standard libMesh send_list construction...
std::vector< unsigned int > _variable_group_numbers
The variable group number for each variable.
std::map< GhostingFunctor *, std::shared_ptr< GhostingFunctor > > _shared_functors
Hang on to references to any GhostingFunctor objects we were passed in shared_ptr form...
void remove_algebraic_ghosting_functor(GhostingFunctor &evaluable_functor)
Removes a functor which was previously added to the set of algebraic ghosting functors, from both this DofMap and from the underlying mesh.
void compute_sparsity(const MeshBase &)
Computes the sparsity pattern for the matrices corresponding to proc_id and sends that data to Linear...
void add_algebraic_ghosting_functor(GhostingFunctor &evaluable_functor, bool to_mesh=true)
Adds a functor which can specify algebraic ghosting requirements for use with distributed vectors...
unsigned int n_comp_group(const unsigned int s, const unsigned int vg) const
processor_id_type processor_id() const
virtual T el(const unsigned int i) const =0
std::map< const Node *, std::set< subdomain_id_type > > calculate_constraining_subdomains()
We may have mesh constraint rows with dependent nodes in one subdomain but dependency nodes in anothe...
dof_id_type _n_old_dfs
Total number of degrees of freedom on old dof objects.
void set_error_on_cyclic_constraint(bool error_on_cyclic_constraint)
Specify whether or not we perform an extra (opt-mode enabled) check for constraint loops...
processor_id_type processor_id() const
std::vector< dof_id_type > _first_old_df
First old DOF index on processor p.
virtual ElemType type() const =0
A Point defines a location in LIBMESH_DIM dimensional Real space.
virtual numeric_index_type last_local_index() const =0
void ErrorVector unsigned int
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 is_evaluable(const DofObjectSubclass &obj, unsigned int var_num=libMesh::invalid_uint) const
bool semilocal_index(dof_id_type dof_index) const
void distribute_local_dofs_node_major(dof_id_type &next_free_dof, MeshBase &mesh, const std::map< const Node *, std::set< subdomain_id_type >> &constraining_subdomains)
Distributes the global degrees of freedom for dofs on this processor.
void old_dof_indices(const Elem &elem, unsigned int n, std::vector< dof_id_type > &di, const unsigned int vn) const
Appends to the vector di the old global degree of freedom indices for elem.node_ref(n), for one variable vn.
GhostingFunctorIterator coupling_functors_begin() const
Beginning of range of coupling functors.
void add_ghosting_functor(GhostingFunctor &ghosting_functor)
Adds a functor which can specify ghosting requirements for use on distributed meshes.
std::vector< dof_id_type > _end_df
Last DOF index (plus 1) on processor p.
bool local_index(dof_id_type dof_index) const
const FEType & type() const
NodeConstraints _node_constraints
Data structure containing DofObject constraints.
This class defines a coupling matrix.