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;
1616 const std::set<GhostingFunctor *>::iterator & gf_begin,
1617 const std::set<GhostingFunctor *>::iterator & gf_end,
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();
2083 const std::vector<dof_id_type> & dof_indices_in,
2086 const unsigned int n_original_dofs = dof_indices_in.size();
2088 #ifdef LIBMESH_ENABLE_AMR 2091 libmesh_assert_equal_to (dof_indices_in.size(), Ue.
size());
2092 bool has_constrained_dofs =
false;
2094 for (
unsigned int il=0; il != n_original_dofs; ++il)
2100 libmesh_assert_less (ig, Ug.
size());
2108 if (has_constrained_dofs)
2111 std::vector<dof_id_type> constrained_dof_indices(dof_indices_in);
2118 libmesh_assert_equal_to (dof_indices_in.size(), C.
m());
2119 libmesh_assert_equal_to (constrained_dof_indices.size(), C.
n());
2125 for (
unsigned int i=0; i != n_original_dofs; i++)
2129 const unsigned int n_constrained =
2130 cast_int<unsigned int>(constrained_dof_indices.size());
2131 for (
unsigned int j=0; j<n_constrained; j++)
2133 const dof_id_type jg = constrained_dof_indices[j];
2141 Ue.
el(i) += C(i,j)*Ug(jg);
2150 libmesh_assert_equal_to (n_original_dofs, Ue.
size());
2152 for (
unsigned int il=0; il<n_original_dofs; il++)
2165 std::vector<dof_id_type> & di)
const 2189 std::size_t tot_size = 0;
2201 std::vector<const Node *> elem_nodes;
2205 for (
unsigned int vg=0; vg<n_var_groups; vg++)
2208 const unsigned int vars_in_group = var.
n_variables();
2213 for (
unsigned int vig=0; vig != vars_in_group; ++vig)
2218 std::vector<dof_id_type> di_new;
2220 di.insert( di.end(), di_new.begin(), di_new.end());
2224 for (
unsigned int vig=0; vig != vars_in_group; ++vig)
2228 cast_int<unsigned int>(elem_nodes.size()),
2243 for (
unsigned int vg=0; vg<n_var_groups; vg++)
2246 const unsigned int vars_in_group = var.
n_variables();
2252 for (
unsigned int vig=0; vig != vars_in_group; ++vig)
2257 std::vector<dof_id_type> di_new;
2259 di.insert( di.end(), di_new.begin(), di_new.end());
2263 for (
unsigned int vig=0; vig != vars_in_group; ++vig)
2275 libmesh_assert_equal_to (tot_size, di.size());
2281 std::vector<dof_id_type> & di,
2282 const unsigned int vn,
2291 const std::vector<dof_id_type> & scalar_dof_indices) {
2303 std::vector<dof_id_type> & di)
const 2319 const unsigned int sys_num = this->
sys_number();
2322 for (
unsigned int vg=0; vg<n_var_groups; vg++)
2325 const unsigned int vars_in_group = var.
n_variables();
2329 for (
unsigned int vig=0; vig != vars_in_group; ++vig)
2331 std::vector<dof_id_type> di_new;
2333 di.insert( di.end(), di_new.begin(), di_new.end());
2339 for (
unsigned int vig=0; vig != vars_in_group; ++vig)
2341 for (
int i=0; i != n_comp; ++i)
2344 node->
dof_number(sys_num, vg, vig, i, n_comp);
2345 libmesh_assert_not_equal_to
2356 std::vector<dof_id_type> & di,
2357 const unsigned int vn)
const 2378 const unsigned int sys_num = this->
sys_number();
2386 std::vector<dof_id_type> di_new;
2388 di.insert( di.end(), di_new.begin(), di_new.end());
2392 const unsigned int vig = vn - var.
number();
2394 for (
int i=0; i != n_comp; ++i)
2397 node->
dof_number(sys_num, vg, vig, i, n_comp);
2398 libmesh_assert_not_equal_to
2408 std::vector<dof_id_type> & di,
2409 const unsigned int vn)
const 2416 #ifdef LIBMESH_ENABLE_AMR 2420 std::vector<dof_id_type> & di,
2421 const unsigned int vn)
const 2427 #endif // LIBMESH_ENABLE_AMR 2434 std::vector<dof_id_type> & di,
2435 const unsigned int vn)
const 2442 LOG_SCOPE(
"_node_dof_indices()",
"DofMap");
2444 const unsigned int sys_num = this->
sys_number();
2445 const auto [vg, vig] =
2447 const unsigned int n_comp = obj.
n_comp_group(sys_num,vg);
2451 const bool extra_hanging_dofs =
2454 const bool add_p_level =
2455 #ifdef LIBMESH_ENABLE_AMR 2465 const unsigned int nc =
2472 if (extra_hanging_dofs && nc && !elem.
is_vertex(n))
2474 const int dof_offset = n_comp - nc;
2485 for (
unsigned int i = dof_offset; i != n_comp; ++i)
2500 const unsigned int good_nc =
2501 std::min(static_cast<unsigned int>(n_comp), nc);
2502 for (
unsigned int i=0; i != good_nc; ++i)
2509 for (
unsigned int i=good_nc; i != nc; ++i)
2517 std::vector<dof_id_type> & di,
2518 const unsigned int vg,
2519 const unsigned int vig,
2520 const Node *
const * nodes,
2522 const unsigned int v
2525 std::size_t & tot_size
2543 std::vector<dof_id_type> & functor_di,
2544 const dof_id_type dof) { functor_di.push_back(dof); });
2548 const unsigned int vn,
2549 #ifdef LIBMESH_ENABLE_AMR
2556 LOG_SCOPE(
"SCALAR_dof_indices()",
"DofMap");
2560 #ifdef LIBMESH_ENABLE_AMR 2576 di.resize(n_dofs_vn);
2577 for (
int i = 0; i != n_dofs_vn; ++i)
2602 for (
const auto & di : dof_indices_in)
2611 template <
typename DofObjectSub
class>
2613 unsigned int var_num)
const 2619 std::vector<dof_id_type> di;
2631 #ifdef LIBMESH_ENABLE_AMR 2634 std::vector<dof_id_type> & di,
2635 const unsigned int vn)
const 2637 LOG_SCOPE(
"old_dof_indices()",
"DofMap");
2642 const unsigned int sys_num = this->
sys_number();
2644 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS 2645 const bool is_inf = elem->
infinite();
2659 std::vector<const Node *> elem_nodes;
2660 const Node *
const * nodes_ptr;
2667 nodes_ptr = elem_nodes.data();
2668 n_nodes = cast_int<unsigned int>(elem_nodes.size());
2678 for (
unsigned int vg=0; vg<n_var_groups; vg++)
2681 const unsigned int vars_in_group = var.
n_variables();
2683 for (
unsigned int vig=0; vig<vars_in_group; vig++)
2685 const unsigned int v = var.
number(vig);
2693 std::vector<dof_id_type> di_new;
2695 di.insert( di.end(), di_new.begin(), di_new.end());
2703 const bool add_p_level =
2704 #ifdef LIBMESH_ENABLE_AMR 2712 int p_adjustment = 0;
2715 libmesh_assert_greater (elem->
p_level(), 0);
2722 p_adjustment *= add_p_level;
2725 int extra_order =
int(add_p_level*elem->
p_level()) + p_adjustment;
2727 const bool extra_hanging_dofs =
2734 for (
unsigned int n=0; n<
n_nodes; n++)
2736 const Node * node = nodes_ptr[n];
2743 const unsigned int nc =
2744 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS 2748 ndan (type, var.
type().
order + extra_order, n);
2750 const int n_comp = old_dof_obj.
n_comp_group(sys_num,vg);
2756 if (extra_hanging_dofs && !elem->is_vertex(n))
2758 const int dof_offset = n_comp - nc;
2770 for (
int i=n_comp-1; i>=dof_offset; i--)
2773 old_dof_obj.
dof_number(sys_num, vg, vig, i, n_comp);
2792 const unsigned int old_nc =
2793 std::min(static_cast<unsigned int>(n_comp), nc);
2794 for (
unsigned int i=0; i != old_nc; ++i)
2797 old_dof_obj.
dof_number(sys_num, vg, vig, i, n_comp);
2803 for (
unsigned int i=old_nc; i != nc; ++i)
2809 const unsigned int nc =
2816 const unsigned int n_comp =
2819 if (old_dof_obj.
n_systems() > sys_num &&
2823 for (
unsigned int i=0; i<nc; i++)
2826 old_dof_obj.
dof_number(sys_num, vg, vig, i, n_comp);
2850 #endif // LIBMESH_ENABLE_AMR 2853 #ifdef LIBMESH_ENABLE_CONSTRAINTS 2857 typedef std::set<dof_id_type> RCSet;
2860 RCSet dof_set (elem_dofs.begin(), elem_dofs.end());
2869 for (
const auto & dof : elem_dofs)
2873 DofConstraints::const_iterator
2887 for (
const auto & pr : constraint_row)
2888 if (!dof_set.count (pr.first))
2890 dof_set.insert (pr.first);
2902 elem_dofs.insert (elem_dofs.end(),
2903 dof_set.begin(), dof_set.end());
2914 #endif // LIBMESH_ENABLE_CONSTRAINTS 2927 std::ostringstream os;
2932 const char * may_equal =
" <= ";
2937 if (mat->need_full_sparsity_pattern())
2941 long double avg_n_nz = 0, avg_n_oz = 0;
2945 for (
const auto & val :
_sp->get_n_nz())
2947 max_n_nz = std::max(max_n_nz, val);
2951 std::size_t n_nz_size =
_sp->get_n_nz().size();
2957 avg_n_nz /= std::max(n_nz_size,std::size_t(1));
2959 for (
const auto & val :
_sp->get_n_oz())
2961 max_n_oz = std::max(max_n_oz, val);
2965 std::size_t n_oz_size =
_sp->get_n_oz().size();
2971 avg_n_oz /= std::max(n_oz_size,std::size_t(1));
2974 os <<
" DofMap Sparsity\n Average On-Processor Bandwidth" 2975 << may_equal << avg_n_nz <<
'\n';
2977 os <<
" Average Off-Processor Bandwidth" 2978 << may_equal << avg_n_oz <<
'\n';
2980 os <<
" Maximum On-Processor Bandwidth" 2981 << may_equal << max_n_nz <<
'\n';
2983 os <<
" Maximum Off-Processor Bandwidth" 2984 << may_equal << max_n_oz << std::endl;
2986 #ifdef LIBMESH_ENABLE_CONSTRAINTS 2988 std::size_t n_constraints = 0, max_constraint_length = 0,
2990 long double avg_constraint_length = 0.;
2998 std::size_t rowsize = row.size();
3000 max_constraint_length = std::max(max_constraint_length,
3002 avg_constraint_length += rowsize;
3009 this->
comm().
sum(n_constraints);
3011 this->
comm().
sum(avg_constraint_length);
3012 this->
comm().
max(max_constraint_length);
3014 os <<
" DofMap Constraints\n Number of DoF Constraints = " 3018 <<
" Number of Heterogenous Constraints= " << n_rhss;
3021 avg_constraint_length /= n_constraints;
3024 <<
" Average DoF Constraint Length= " << avg_constraint_length;
3027 #ifdef LIBMESH_ENABLE_NODE_CONSTRAINTS 3028 std::size_t n_node_constraints = 0, max_node_constraint_length = 0,
3030 long double avg_node_constraint_length = 0.;
3039 std::size_t rowsize = row.size();
3041 max_node_constraint_length = std::max(max_node_constraint_length,
3043 avg_node_constraint_length += rowsize;
3044 n_node_constraints++;
3046 if (pr.second !=
Point(0))
3050 this->
comm().
sum(n_node_constraints);
3051 this->
comm().
sum(n_node_rhss);
3052 this->
comm().
sum(avg_node_constraint_length);
3053 this->
comm().
max(max_node_constraint_length);
3055 os <<
"\n Number of Node Constraints = " << n_node_constraints;
3058 <<
" Number of Heterogenous Node Constraints= " << n_node_rhss;
3059 if (n_node_constraints)
3061 avg_node_constraint_length /= n_node_constraints;
3062 os <<
"\n Maximum Node Constraint Length= " << max_node_constraint_length
3064 <<
" Average Node Constraint Length= " << avg_node_constraint_length;
3066 #endif // LIBMESH_ENABLE_NODE_CONSTRAINTS 3070 #endif // LIBMESH_ENABLE_CONSTRAINTS 3077 _sc = std::make_unique<StaticCondensationDofMap>(
mesh, sys, *
this);
3086 template LIBMESH_EXPORT
bool DofMap::is_evaluable<Elem>(
const Elem &,
unsigned int)
const;
3087 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.
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
std::set< GhostingFunctor * >::const_iterator coupling_functors_begin() const
Beginning of range of coupling functors.
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.
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
std::set< GhostingFunctor * > _algebraic_ghosting_functors
The list of all GhostingFunctor objects to be used when distributing ghosted vectors.
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...
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.
static void merge_ghost_functor_outputs(GhostingFunctor::map_type &elements_to_ghost, CouplingMatricesSet &temporary_coupling_matrices, const std::set< GhostingFunctor *>::iterator &gf_begin, const std::set< GhostingFunctor *>::iterator &gf_end, const MeshBase::const_element_iterator &elems_begin, const MeshBase::const_element_iterator &elems_end, processor_id_type p)
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
DofConstraints _dof_constraints
Data structure containing DOF constraints.
DofMap(const unsigned int sys_number, MeshBase &mesh)
Constructor.
CouplingMatrix * _dof_coupling
Degree of freedom coupling.
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.
DofObject * elem_ptr(MeshBase &mesh, dof_id_type i) const
static FEContinuity get_continuity(const FEType &fe_type)
Returns the input FEType's FEContinuity based on the underlying FEFamily and potentially the Order...
std::set< GhostingFunctor * >::const_iterator algebraic_ghosting_functors_end() const
End of range of algebraic ghosting functors.
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::set< GhostingFunctor * > _coupling_functors
The list of all GhostingFunctor objects to be used when coupling degrees of freedom in matrix sparsit...
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
std::set< GhostingFunctor * >::const_iterator coupling_functors_end() const
End of range of coupling functors.
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.
std::set< GhostingFunctor * >::const_iterator algebraic_ghosting_functors_begin() const
Beginning of range of algebraic ghosting functors.
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.
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.