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" 43 #include "libmesh/system.h" 44 #include "libmesh/parallel_fe_type.h" 55 #include <unordered_map> 62 std::unique_ptr<SparsityPattern::Build>
64 const bool calculate_constrained,
65 const bool use_condensed_system)
const 69 LOG_SCOPE(
"build_sparsity()",
"DofMap");
85 if (use_condensed_system)
99 auto sp = std::make_unique<SparsityPattern::Build>
103 implicit_neighbor_dofs,
105 calculate_constrained,
109 mesh.active_local_elements_end()), *sp);
113 libmesh_assert_equal_to (sp->get_sparsity_pattern().size(), this->
n_local_dofs());
121 libMesh::out <<
"WARNING: You have specified both an extra sparsity function and object.\n" 122 <<
" Are you sure this is what you meant to do??" 141 _dof_coupling(nullptr),
142 _error_on_constraint_loop(false),
143 _constrained_sparsity_construction(false),
146 _variable_group_numbers(),
152 _augment_sparsity_pattern(nullptr),
153 _extra_sparsity_function(nullptr),
154 _extra_sparsity_context(nullptr),
155 _augment_send_list(nullptr),
156 _extra_send_list_function(nullptr),
157 _extra_send_list_context(nullptr),
160 need_full_sparsity_pattern(false),
162 #ifdef LIBMESH_ENABLE_AMR
163 , _first_old_scalar_df()
165 #ifdef LIBMESH_ENABLE_CONSTRAINTS
167 , _stashed_dof_constraints()
168 , _primal_constraint_values()
169 , _adjoint_constraint_values()
171 #ifdef LIBMESH_ENABLE_NODE_CONSTRAINTS
172 , _node_constraints()
174 #ifdef LIBMESH_ENABLE_PERIODIC
177 #ifdef LIBMESH_ENABLE_DIRICHLET
179 , _adjoint_dirichlet_boundaries()
181 , _implicit_neighbor_dofs_initialized(false),
182 _implicit_neighbor_dofs(false),
183 _verify_dirichlet_bc_consistency(true),
192 #ifdef LIBMESH_ENABLE_PERIODIC 215 #ifdef LIBMESH_ENABLE_PERIODIC 242 parallel_object_only();
261 (!
_sp->get_n_nz().empty() ||
262 !
_sp->get_n_oz().empty());
263 this->
comm().
max(computed_sparsity_already);
305 return mesh.node_ptr(i);
312 return mesh.elem_ptr(i);
317 template <
typename iterator_type>
319 iterator_type objects_end,
321 dofobject_accessor objects)
324 parallel_object_only();
328 std::unordered_map<processor_id_type, dof_id_type> ghost_objects_from_proc;
330 iterator_type it = objects_begin;
332 for (; it != objects_end; ++it)
341 ghost_objects_from_proc[obj_procid]++;
346 std::map<processor_id_type, std::vector<dof_id_type>>
351 for (
auto [p, size] : ghost_objects_from_proc)
354 requested_ids[p].reserve(size);
357 for (it = objects_begin; it != objects_end; ++it)
366 if (ghost_objects_from_proc.count(p))
367 libmesh_assert_equal_to (requested_ids[p].size(), ghost_objects_from_proc[p]);
373 typedef std::vector<dof_id_type> datum;
375 auto gather_functor =
376 [
this, &
mesh, &objects]
378 const std::vector<dof_id_type> & ids,
379 std::vector<datum> & data)
386 const std::size_t query_size = ids.size();
388 data.resize(query_size);
389 for (
auto & d : data)
390 d.resize(2 * n_var_groups);
392 for (std::size_t i=0; i != query_size; ++i)
397 libmesh_assert_equal_to (requested->
n_var_groups(sys_num), n_var_groups);
398 for (
unsigned int vg=0; vg != n_var_groups; ++vg)
400 unsigned int n_comp_g =
402 data[i][vg] = n_comp_g;
406 data[i][n_var_groups+vg] = my_first_dof;
411 auto action_functor =
412 [
this, &
mesh, &objects]
414 const std::vector<dof_id_type> & ids,
415 const std::vector<datum> & data)
426 libmesh_assert_equal_to (requested->
processor_id(), pid);
427 for (
unsigned int vg=0; vg != n_var_groups; ++vg)
429 unsigned int n_comp_g =
430 cast_int<unsigned int>(data[i][vg]);
434 dof_id_type my_first_dof = data[i][n_var_groups+vg];
437 (sys_num, vg, my_first_dof);
443 datum * ex =
nullptr;
444 Parallel::pull_parallel_vector_data
445 (this->
comm(), requested_ids, gather_functor, action_functor, ex);
449 for (it = objects_begin; it != objects_end; ++it)
454 for (
unsigned int v=0; v != num_variables; ++v)
456 unsigned int n_comp =
470 const std::map<
const Node *, std::set<subdomain_id_type>> &
471 constraining_subdomains)
475 LOG_SCOPE(
"reinit()",
"DofMap");
478 const bool constraining_subdomains_empty =
479 constraining_subdomains.empty();
489 if (this->_dof_coupling && this->_dof_coupling->empty() && !this->n_variables())
490 this->_dof_coupling =
nullptr;
491 _default_coupling->set_dof_coupling(this->_dof_coupling);
494 unsigned int standard_n_levels =
495 this->use_coupled_neighbor_dofs(
mesh);
496 _default_coupling->set_n_levels
497 (std::max(_default_coupling->n_levels(), standard_n_levels));
505 sys_num = this->sys_number(),
506 n_var_groups = this->n_variable_groups();
510 std::vector<unsigned int> n_vars_per_group; n_vars_per_group.reserve (n_var_groups);
512 for (
unsigned int vg=0; vg<n_var_groups; vg++)
513 n_vars_per_group.push_back (this->variable_group(vg).n_variables());
515 #ifdef LIBMESH_ENABLE_AMR 520 for (
auto & node :
mesh.node_ptr_range())
522 node->clear_old_dof_object();
530 for (
Elem * elem : range)
532 elem->clear_old_dof_object();
541 for (
auto & elem :
mesh.element_ptr_range())
547 for (
Node & node : elem->node_ref_range())
548 if (node.get_old_dof_object() ==
nullptr)
549 if (node.has_dofs(sys_num))
550 node.set_old_dof_object();
554 if (elem->has_dofs(sys_num))
555 elem->set_old_dof_object();
558 #endif // #ifdef LIBMESH_ENABLE_AMR 567 for (
auto & node :
mesh.node_ptr_range())
568 node->set_n_vars_per_group(sys_num, n_vars_per_group);
573 [sys_num, n_vars_per_group](
const ElemRange & range)
575 for (
Elem * elem : range)
576 elem->set_n_vars_per_group(sys_num, n_vars_per_group);
580 this->_n_SCALAR_dofs = 0;
584 for (
unsigned int vg=0; vg<n_var_groups; vg++)
586 const VariableGroup & vg_description = this->variable_group(vg);
588 const unsigned int n_var_in_group = vg_description.
n_variables();
589 const FEType & base_fe_type = vg_description.
type();
597 this->_n_SCALAR_dofs += base_fe_type.
order.
get_order()*n_var_in_group;
602 const bool extra_hanging_dofs =
606 for (
auto & elem :
mesh.active_element_ptr_range())
614 const bool active_on_elem =
619 if (!active_on_elem && constraining_subdomains_empty)
622 FEType fe_type = base_fe_type;
628 "ERROR: Finite element " 630 <<
" on geometric element " 632 <<
"\nonly supports FEInterface::max_order = " 634 <<
", not fe_type.order = " 635 << base_fe_type.
order);
637 #ifdef LIBMESH_ENABLE_AMR 640 if (base_fe_type.
order + add_p_level*elem->p_level() >
646 <<
" on geometric element " 648 <<
"could not be p refined past FEInterface::max_order = " 653 -
int(base_fe_type.
order));
658 for (
auto n : elem->node_index_range())
660 Node & node = elem->node_ref(n);
665 bool active_on_node = active_on_elem;
667 if (
auto it = constraining_subdomains.find(&node);
668 it != constraining_subdomains.end())
669 for (
auto s : it->second)
672 active_on_node =
true;
679 if (elem->is_vertex(n))
681 const unsigned int old_node_dofs =
684 const unsigned int vertex_dofs =
689 if (vertex_dofs > old_node_dofs)
714 for (
auto & elem :
mesh.active_element_ptr_range())
722 const bool active_on_elem =
727 if (!active_on_elem && constraining_subdomains_empty)
731 for (
auto n : elem->node_index_range())
733 Node & node = elem->node_ref(n);
738 bool active_on_node = active_on_elem;
740 if (
auto it = constraining_subdomains.find(&node);
741 it != constraining_subdomains.end())
742 for (
auto s : it->second)
745 active_on_node =
true;
752 const unsigned int old_node_dofs =
755 const unsigned int vertex_dofs = old_node_dofs?
756 cast_int<unsigned int>(node.
vg_dof_base (sys_num,vg)):0;
758 const unsigned int new_node_dofs =
762 if (elem->is_vertex(n))
764 libmesh_assert_greater_equal (old_node_dofs, vertex_dofs);
774 libmesh_assert_greater_equal (vertex_dofs, new_node_dofs);
794 else if (vertex_dofs == 0)
796 if (new_node_dofs > old_node_dofs)
808 else if (extra_hanging_dofs)
810 if (new_node_dofs > old_node_dofs - vertex_dofs)
813 vertex_dofs + new_node_dofs);
823 libmesh_assert_greater_equal (old_node_dofs, vertex_dofs);
824 if (new_node_dofs > old_node_dofs)
836 const unsigned int dofs_per_elem =
839 elem->set_n_comp_group(sys_num, vg, dofs_per_elem);
851 this->invalidate_dofs(
mesh);
858 const unsigned int sys_num = this->
sys_number();
861 for (
auto & node :
mesh.node_ptr_range())
862 node->invalidate_dofs(sys_num);
865 for (
auto & elem :
mesh.active_element_ptr_range())
866 elem->invalidate_dofs(sys_num);
891 this->_coupling_functors.clear();
908 this->_algebraic_ghosting_functors.clear();
929 #ifdef LIBMESH_ENABLE_AMR 952 parallel_object_only();
955 LOG_SCOPE(
"distribute_dofs()",
"DofMap");
965 libmesh_assert_less (proc_id, n_proc);
970 const std::map<const Node *, std::set<subdomain_id_type>>
971 constraining_subdomains =
976 constraining_subdomains);
993 (next_free_dof,
mesh, constraining_subdomains);
996 (next_free_dof,
mesh, constraining_subdomains);
1008 if (node_major_dofs)
1010 (next_free_dof,
mesh, constraining_subdomains);
1013 (next_free_dof,
mesh, constraining_subdomains);
1015 libmesh_assert_equal_to (next_free_dof,
_end_df[proc_id]);
1030 mesh.elements_end(),
1044 for (
auto & node :
mesh.node_ptr_range())
1053 libmesh_assert_greater_equal (dofid, this->
first_dof(obj_proc_id));
1054 libmesh_assert_less (dofid, this->
end_dof(obj_proc_id));
1058 for (
auto & elem :
mesh.element_ptr_range())
1067 libmesh_assert_greater_equal (dofid, this->
first_dof(obj_proc_id));
1068 libmesh_assert_less (dofid, this->
end_dof(obj_proc_id));
1075 #ifdef LIBMESH_ENABLE_AMR 1097 gf->dofmap_reinit();
1103 gf->dofmap_reinit();
1120 template <
typename T, std::enable_if_t<std::is_same_v<T, dof_
id_type> ||
1121 std::is_same_v<T, std::vector<dof_
id_type>>,
int>>
1124 unsigned int var_num)
const 1129 if constexpr (std::is_same_v<T, dof_id_type>)
1131 else if constexpr (std::is_same_v<T, std::vector<dof_id_type>>)
1138 const unsigned int sys_num = this->
sys_number();
1146 for (
auto & elem :
mesh.active_local_element_ptr_range())
1153 const unsigned int n_nodes = elem->n_nodes();
1156 for (
unsigned int n=0; n<
n_nodes; n++)
1158 const Node & node = elem->node_ref(n);
1163 const unsigned int n_comp = node.
n_comp(sys_num, var_num);
1164 for(
unsigned int i=0; i<n_comp; i++)
1169 if constexpr (std::is_same_v<T, dof_id_type>)
1171 if (
idx == 0 || index > greatest)
1172 {
idx++; greatest = index; }
1174 else if constexpr (std::is_same_v<T, std::vector<dof_id_type>>)
1176 if (
idx.empty() || index >
idx.back())
1177 idx.push_back(index);
1183 const unsigned int n_comp = elem->n_comp(sys_num, var_num);
1184 for (
unsigned int i=0; i<n_comp; i++)
1186 const dof_id_type index = elem->dof_number(sys_num,var_num,i);
1188 if constexpr (std::is_same_v<T, dof_id_type>)
1190 if (
idx == 0 || index > greatest)
1191 {
idx++; greatest = index; }
1193 else if constexpr (std::is_same_v<T, std::vector<dof_id_type>>)
1195 if (
idx.empty() || index >
idx.back())
1196 idx.push_back(index);
1210 for (
const auto & node :
mesh.local_node_ptr_range())
1214 const unsigned int n_comp = node->n_comp(sys_num, var_num);
1215 for (
unsigned int i=0; i<n_comp; i++)
1217 const dof_id_type index = node->dof_number(sys_num,var_num,i);
1219 if constexpr (std::is_same_v<T, dof_id_type>)
1221 if (
idx == 0 || index > greatest)
1222 {
idx++; greatest = index; }
1224 else if constexpr (std::is_same_v<T, std::vector<dof_id_type>>)
1226 if (
idx.empty() || index >
idx.back())
1227 idx.push_back(index);
1236 std::vector<dof_id_type> di_scalar;
1239 if constexpr (std::is_same_v<T, dof_id_type>)
1241 else if constexpr (std::is_same_v<T, std::vector<dof_id_type>>)
1242 idx.insert(
idx.end(), di_scalar.begin(), di_scalar.end());
1248 unsigned int)
const;
1252 unsigned int)
const;
1255 std::map<const Node *, std::set<subdomain_id_type>>
1258 std::map<const Node *, std::set<subdomain_id_type>> constraining_subdomains;
1264 if (!constraint_rows.empty())
1265 for (
auto & elem :
_mesh.active_element_ptr_range())
1269 for (
const Node & node : elem->node_ref_range())
1271 if (
auto it = constraint_rows.find(&node);
1272 it != constraint_rows.end())
1274 for (
const auto & [pr, val] : it->second)
1276 const Node * spline_node =
1277 pr.first->node_ptr(pr.second);
1279 constraining_subdomains[spline_node].insert(sbdid);
1285 return constraining_subdomains;
1292 const std::map<
const Node *, std::set<subdomain_id_type>> &
1293 constraining_subdomains)
1295 const unsigned int sys_num = this->sys_number();
1296 const unsigned int n_var_groups = this->n_variable_groups();
1299 const bool constraining_subdomains_empty =
1300 constraining_subdomains.empty();
1307 for (
auto & elem :
mesh.active_local_element_ptr_range())
1311 const unsigned int n_nodes = elem->n_nodes();
1316 for (
unsigned int n=0; n<
n_nodes; n++)
1318 Node & node = elem->node_ref(n);
1320 for (
unsigned vg=0; vg<n_var_groups; vg++)
1322 const VariableGroup & vg_description(this->variable_group(vg));
1327 bool active_on_node =
1331 if (!active_on_node && !constraining_subdomains_empty)
1332 if (
auto it = constraining_subdomains.find(&node);
1333 it != constraining_subdomains.end())
1334 for (
auto s : it->second)
1337 active_on_node =
true;
1361 for (
unsigned vg=0; vg<n_var_groups; vg++)
1363 const VariableGroup & vg_description(this->variable_group(vg));
1367 if (elem->n_comp_group(sys_num,vg) > 0)
1369 libmesh_assert_equal_to (elem->vg_dof_base(sys_num,vg),
1372 elem->set_vg_dof_base(sys_num,
1377 elem->n_comp_group(sys_num,vg));
1391 for (
auto & node :
mesh.local_node_ptr_range())
1392 for (
unsigned vg=0; vg<n_var_groups; vg++)
1394 const VariableGroup & vg_description(this->variable_group(vg));
1396 if (node->n_comp_group(sys_num,vg))
1399 node->set_vg_dof_base (sys_num,
1404 node->n_comp(sys_num,vg));
1408 this->distribute_scalar_dofs(next_free_dof);
1411 this->assert_no_nodes_missed(
mesh);
1420 const std::map<
const Node *, std::set<subdomain_id_type>> &
1421 constraining_subdomains)
1423 const unsigned int sys_num = this->sys_number();
1424 const unsigned int n_var_groups = this->n_variable_groups();
1427 const bool constraining_subdomains_empty =
1428 constraining_subdomains.empty();
1435 for (
unsigned vg=0; vg<n_var_groups; vg++)
1437 const VariableGroup & vg_description(this->variable_group(vg));
1439 const unsigned int n_vars_in_group = vg_description.
n_variables();
1445 for (
auto & elem :
mesh.active_local_element_ptr_range())
1451 const bool active_on_elem =
1456 if (!active_on_elem && constraining_subdomains_empty)
1459 const unsigned int n_nodes = elem->n_nodes();
1462 for (
unsigned int n=0; n<
n_nodes; n++)
1464 Node & node = elem->node_ref(n);
1466 bool active_on_node = active_on_elem;
1467 if (!active_on_node)
1468 if (
auto it = constraining_subdomains.find(&node);
1469 it != constraining_subdomains.end())
1470 for (
auto s : it->second)
1473 active_on_node =
true;
1477 if (!active_on_node)
1489 next_free_dof += (n_vars_in_group*
1495 if (elem->n_comp_group(sys_num,vg) > 0)
1497 libmesh_assert_equal_to (elem->vg_dof_base(sys_num,vg),
1500 elem->set_vg_dof_base(sys_num,
1504 next_free_dof += (n_vars_in_group*
1505 elem->n_comp_group(sys_num,vg));
1517 for (
auto & node :
mesh.local_node_ptr_range())
1518 if (node->n_comp_group(sys_num,vg))
1521 node->set_vg_dof_base (sys_num,
1525 next_free_dof += (n_vars_in_group*
1526 node->n_comp_group(sys_num,vg));
1530 this->distribute_scalar_dofs(next_free_dof);
1533 this->assert_no_nodes_missed(
mesh);
1565 MeshTools::libmesh_assert_valid_procids<Node>(
mesh);
1567 for (
auto & node :
mesh.local_node_ptr_range())
1569 unsigned int n_var_g = node->n_var_groups(this->
sys_number());
1570 for (
unsigned int vg=0; vg != n_var_g; ++vg)
1572 unsigned int n_comp_g =
1575 node->vg_dof_base(this->
sys_number(), vg) : 0;
1593 for (
const auto & gf :
as_range(gf_begin, gf_end))
1598 (*gf)(elems_begin, elems_end, p, more_elements_to_ghost);
1603 #if defined(LIBMESH_ENABLE_DEPRECATED) && defined(LIBMESH_ENABLE_AMR) 1604 std::vector<std::pair<const Elem*, const CouplingMatrix*>> children_to_couple;
1605 for (
auto it = more_elements_to_ghost.begin();
1606 it != more_elements_to_ghost.end();)
1608 const Elem * elem = it->first;
1611 libmesh_deprecated();
1612 std::vector<const Elem*> children_to_ghost;
1615 for (
const Elem * child : children_to_ghost)
1616 if (child->processor_id() != p)
1617 children_to_couple.emplace_back(child, it->second);
1619 it = more_elements_to_ghost.erase(it);
1624 more_elements_to_ghost.insert(children_to_couple.begin(),
1625 children_to_couple.end());
1628 for (
const auto & [elem, elem_cm] : more_elements_to_ghost)
1634 if (
const auto existing_it = elements_to_ghost.find(elem);
1635 existing_it == elements_to_ghost.end())
1636 elements_to_ghost.emplace(elem, elem_cm);
1639 if (existing_it->second)
1646 if (temporary_coupling_matrices.empty() ||
1647 !temporary_coupling_matrices.count(existing_it->second))
1653 auto result_pr = temporary_coupling_matrices.insert(std::make_unique<CouplingMatrix>(*existing_it->second));
1654 existing_it->second = result_pr.first->get();
1670 if (
const auto temp_it = temporary_coupling_matrices.find(existing_it->second);
1671 temp_it != temporary_coupling_matrices.end())
1672 temporary_coupling_matrices.erase(temp_it);
1674 existing_it->second =
nullptr;
1689 LOG_SCOPE(
"add_neighbors_to_send_list()",
"DofMap");
1698 =
mesh.active_local_elements_begin();
1700 =
mesh.active_local_elements_end();
1709 temporary_coupling_matrices,
1712 local_elem_it, local_elem_end,
mesh.processor_id());
1715 temporary_coupling_matrices,
1718 local_elem_it, local_elem_end,
mesh.processor_id());
1723 std::map<const CouplingMatrix *, std::vector<unsigned int>>
1724 column_variable_lists;
1726 for (
const auto & [partner, ghost_coupling] : elements_to_send)
1729 libmesh_assert_not_equal_to
1737 libmesh_assert_equal_to (ghost_coupling->size(), n_var);
1740 std::map<const CouplingMatrix *, std::vector<unsigned int>>::const_iterator
1741 column_variable_list = column_variable_lists.find(ghost_coupling);
1744 if (column_variable_list == column_variable_lists.end())
1746 auto inserted_variable_list_pair =
1747 column_variable_lists.emplace(ghost_coupling, std::vector<unsigned int>());
1748 column_variable_list = inserted_variable_list_pair.first;
1750 std::vector<unsigned int> & new_variable_list =
1751 inserted_variable_list_pair.first->second;
1755 for (
unsigned int vi = 0; vi != n_var; ++vi)
1759 for (
const auto & vj : ccr)
1762 for (
unsigned int vj = 0; vj != n_var; ++vj)
1765 new_variable_list.push_back(vj);
1769 const std::vector<unsigned int> & variable_list =
1770 column_variable_list->second;
1772 for (
const auto & vj : variable_list)
1774 std::vector<dof_id_type> di;
1782 libmesh_assert_less(d, this->
n_dofs());
1789 std::vector<dof_id_type> di;
1793 for (
const auto & dof : di)
1797 libmesh_assert_less(dof, this->
n_dofs());
1805 temporary_coupling_matrices.clear();
1815 for ( ; local_elem_it != local_elem_end; ++local_elem_it)
1817 const Elem * elem = *local_elem_it;
1819 std::vector<dof_id_type> di;
1823 for (
const auto & dof : di)
1827 libmesh_assert_less(dof, this->
n_dofs());
1837 LOG_SCOPE(
"prepare_send_list()",
"DofMap");
1849 libMesh::out <<
"WARNING: You have specified both an extra send list function and object.\n" 1850 <<
" Are you sure this is what you meant to do??" 1866 std::vector<dof_id_type>::iterator new_end =
1882 #ifdef LIBMESH_ENABLE_CONSTRAINTS 1907 bool implicit_neighbor_dofs =
1914 if (implicit_neighbor_dofs)
1936 if (!implicit_neighbor_dofs)
1944 bool all_discontinuous_dofs =
true;
1949 all_discontinuous_dofs =
false;
1951 if (all_discontinuous_dofs)
1952 implicit_neighbor_dofs =
true;
1955 return implicit_neighbor_dofs;
1969 mat->attach_sparsity_pattern (*
_sp);
1971 mat->update_sparsity_pattern (
_sp->get_sparsity_pattern());
1976 _sp->clear_full_sparsity();
2009 #ifdef LIBMESH_ENABLE_DEPRECATED 2020 &coupling_functor) ==
2037 #ifndef LIBMESH_ENABLE_DEPRECATED 2049 &coupling_functor) ==
2066 #ifdef LIBMESH_ENABLE_DEPRECATED 2070 &evaluable_functor),
2077 &evaluable_functor) ==
2093 &evaluable_functor);
2095 #ifndef LIBMESH_ENABLE_DEPRECATED 2107 &evaluable_functor) ==
2120 const std::vector<dof_id_type> & dof_indices_in,
2123 const unsigned int n_original_dofs = dof_indices_in.size();
2125 #ifdef LIBMESH_ENABLE_AMR 2128 libmesh_assert_equal_to (dof_indices_in.size(), Ue.
size());
2129 bool has_constrained_dofs =
false;
2131 for (
unsigned int il=0; il != n_original_dofs; ++il)
2137 libmesh_assert_less (ig, Ug.
size());
2145 if (has_constrained_dofs)
2148 std::vector<dof_id_type> constrained_dof_indices(dof_indices_in);
2155 libmesh_assert_equal_to (dof_indices_in.size(), C.
m());
2156 libmesh_assert_equal_to (constrained_dof_indices.size(), C.
n());
2162 for (
unsigned int i=0; i != n_original_dofs; i++)
2166 const unsigned int n_constrained =
2167 cast_int<unsigned int>(constrained_dof_indices.size());
2168 for (
unsigned int j=0; j<n_constrained; j++)
2170 const dof_id_type jg = constrained_dof_indices[j];
2178 Ue.
el(i) += C(i,j)*Ug(jg);
2187 libmesh_assert_equal_to (n_original_dofs, Ue.
size());
2189 for (
unsigned int il=0; il<n_original_dofs; il++)
2202 std::vector<dof_id_type> & di)
const 2226 std::size_t tot_size = 0;
2238 std::vector<const Node *> elem_nodes;
2242 for (
unsigned int vg=0; vg<n_var_groups; vg++)
2245 const unsigned int vars_in_group = var.
n_variables();
2250 for (
unsigned int vig=0; vig != vars_in_group; ++vig)
2255 std::vector<dof_id_type> di_new;
2257 di.insert( di.end(), di_new.begin(), di_new.end());
2261 for (
unsigned int vig=0; vig != vars_in_group; ++vig)
2265 cast_int<unsigned int>(elem_nodes.size()),
2280 for (
unsigned int vg=0; vg<n_var_groups; vg++)
2283 const unsigned int vars_in_group = var.
n_variables();
2289 for (
unsigned int vig=0; vig != vars_in_group; ++vig)
2294 std::vector<dof_id_type> di_new;
2296 di.insert( di.end(), di_new.begin(), di_new.end());
2300 for (
unsigned int vig=0; vig != vars_in_group; ++vig)
2312 libmesh_assert_equal_to (tot_size, di.size());
2318 std::vector<dof_id_type> & di,
2319 const unsigned int vn,
2328 const std::vector<dof_id_type> & scalar_dof_indices) {
2340 std::vector<dof_id_type> & di,
2341 const unsigned int vn,
2344 auto dof_indices_functor = [elem, p_level,
this](std::vector<dof_id_type> & functor_di,
2345 const unsigned int functor_vn) {
2346 this->
dof_indices(elem, functor_di, functor_vn, p_level);
2352 std::vector<dof_id_type> & di,
2353 const unsigned int vn)
const 2355 auto dof_indices_functor = [node,
this](std::vector<dof_id_type> & functor_di,
2356 const unsigned int functor_vn) {
2363 std::vector<dof_id_type> & di)
const 2379 const unsigned int sys_num = this->
sys_number();
2382 for (
unsigned int vg=0; vg<n_var_groups; vg++)
2385 const unsigned int vars_in_group = var.
n_variables();
2389 for (
unsigned int vig=0; vig != vars_in_group; ++vig)
2391 std::vector<dof_id_type> di_new;
2393 di.insert( di.end(), di_new.begin(), di_new.end());
2399 for (
unsigned int vig=0; vig != vars_in_group; ++vig)
2401 for (
int i=0; i != n_comp; ++i)
2404 node->
dof_number(sys_num, vg, vig, i, n_comp);
2405 libmesh_assert_not_equal_to
2416 std::vector<dof_id_type> & di,
2417 const unsigned int vn)
const 2438 const unsigned int sys_num = this->
sys_number();
2446 std::vector<dof_id_type> di_new;
2448 di.insert( di.end(), di_new.begin(), di_new.end());
2452 const unsigned int vig = vn - var.
number();
2454 for (
int i=0; i != n_comp; ++i)
2457 node->
dof_number(sys_num, vg, vig, i, n_comp);
2458 libmesh_assert_not_equal_to
2468 std::vector<dof_id_type> & di,
2469 const unsigned int vn)
const 2476 #ifdef LIBMESH_ENABLE_AMR 2480 std::vector<dof_id_type> & di,
2481 const unsigned int vn)
const 2487 #endif // LIBMESH_ENABLE_AMR 2494 std::vector<dof_id_type> & di,
2495 const unsigned int vn)
const 2507 const unsigned int sys_num = this->
sys_number();
2508 const auto [vg, vig] =
2510 const unsigned int n_comp = obj.
n_comp_group(sys_num,vg);
2514 const bool extra_hanging_dofs =
2523 const unsigned int nc =
2530 if (extra_hanging_dofs && nc && !elem.
is_vertex(n))
2532 const int dof_offset = n_comp - nc;
2543 for (
unsigned int i = dof_offset; i != n_comp; ++i)
2558 const unsigned int good_nc =
2559 std::min(static_cast<unsigned int>(n_comp), nc);
2560 for (
unsigned int i=0; i != good_nc; ++i)
2567 for (
unsigned int i=good_nc; i != nc; ++i)
2575 std::vector<dof_id_type> & di,
2576 const unsigned int vg,
2577 const unsigned int vig,
2578 const Node *
const * nodes,
2580 const unsigned int v
2583 std::size_t & tot_size
2601 std::vector<dof_id_type> & functor_di,
2602 const dof_id_type dof) { functor_di.push_back(dof); });
2606 const unsigned int vn,
2607 #ifdef LIBMESH_ENABLE_AMR
2621 #ifdef LIBMESH_ENABLE_AMR 2637 di.resize(n_dofs_vn);
2638 for (
int i = 0; i != n_dofs_vn; ++i)
2663 for (
const auto & di : dof_indices_in)
2672 template <
typename DofObjectSub
class>
2674 unsigned int var_num)
const 2680 std::vector<dof_id_type> di;
2692 #ifdef LIBMESH_ENABLE_AMR 2695 std::vector<dof_id_type> & di,
2696 const unsigned int vn)
const 2706 const unsigned int sys_num = this->
sys_number();
2708 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS 2709 const bool is_inf = elem->
infinite();
2723 std::vector<const Node *> elem_nodes;
2724 const Node *
const * nodes_ptr;
2731 nodes_ptr = elem_nodes.data();
2732 n_nodes = cast_int<unsigned int>(elem_nodes.size());
2742 for (
unsigned int vg=0; vg<n_var_groups; vg++)
2745 const unsigned int vars_in_group = var.
n_variables();
2747 for (
unsigned int vig=0; vig<vars_in_group; vig++)
2749 const unsigned int v = var.
number(vig);
2757 std::vector<dof_id_type> di_new;
2759 di.insert( di.end(), di_new.begin(), di_new.end());
2772 int p_adjustment = 0;
2775 libmesh_assert_greater (elem->
p_level(), 0);
2782 p_adjustment *= add_p_level;
2785 int extra_order =
int(add_p_level*elem->
p_level()) + p_adjustment;
2787 const bool extra_hanging_dofs =
2794 for (
unsigned int n=0; n<
n_nodes; n++)
2796 const Node * node = nodes_ptr[n];
2803 const unsigned int nc =
2804 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS 2808 ndan (type, var.
type().
order + extra_order, n);
2810 const int n_comp = old_dof_obj.
n_comp_group(sys_num,vg);
2816 if (extra_hanging_dofs && !elem->is_vertex(n))
2818 const int dof_offset = n_comp - nc;
2830 for (
int i=n_comp-1; i>=dof_offset; i--)
2833 old_dof_obj.
dof_number(sys_num, vg, vig, i, n_comp);
2852 const unsigned int old_nc =
2853 std::min(static_cast<unsigned int>(n_comp), nc);
2854 for (
unsigned int i=0; i != old_nc; ++i)
2857 old_dof_obj.
dof_number(sys_num, vg, vig, i, n_comp);
2863 for (
unsigned int i=old_nc; i != nc; ++i)
2869 const unsigned int nc =
2876 const unsigned int n_comp =
2879 if (old_dof_obj.
n_systems() > sys_num &&
2883 for (
unsigned int i=0; i<nc; i++)
2886 old_dof_obj.
dof_number(sys_num, vg, vig, i, n_comp);
2910 #endif // LIBMESH_ENABLE_AMR 2913 #ifdef LIBMESH_ENABLE_CONSTRAINTS 2917 typedef std::set<dof_id_type> RCSet;
2920 RCSet dof_set (elem_dofs.begin(), elem_dofs.end());
2929 for (
const auto & dof : elem_dofs)
2933 DofConstraints::const_iterator
2947 for (
const auto & pr : constraint_row)
2948 if (!dof_set.count (pr.first))
2950 dof_set.insert (pr.first);
2962 elem_dofs.insert (elem_dofs.end(),
2963 dof_set.begin(), dof_set.end());
2974 #endif // LIBMESH_ENABLE_CONSTRAINTS 2987 std::ostringstream os;
2992 const char * may_equal =
" <= ";
2997 if (mat->need_full_sparsity_pattern())
3001 long double avg_n_nz = 0, avg_n_oz = 0;
3005 for (
const auto & val :
_sp->get_n_nz())
3007 max_n_nz = std::max(max_n_nz, val);
3011 std::size_t n_nz_size =
_sp->get_n_nz().size();
3017 avg_n_nz /= std::max(n_nz_size,std::size_t(1));
3019 for (
const auto & val :
_sp->get_n_oz())
3021 max_n_oz = std::max(max_n_oz, val);
3025 std::size_t n_oz_size =
_sp->get_n_oz().size();
3031 avg_n_oz /= std::max(n_oz_size,std::size_t(1));
3034 os <<
" DofMap Sparsity\n Average On-Processor Bandwidth" 3035 << may_equal << avg_n_nz <<
'\n';
3037 os <<
" Average Off-Processor Bandwidth" 3038 << may_equal << avg_n_oz <<
'\n';
3040 os <<
" Maximum On-Processor Bandwidth" 3041 << may_equal << max_n_nz <<
'\n';
3043 os <<
" Maximum Off-Processor Bandwidth" 3044 << may_equal << max_n_oz << std::endl;
3046 #ifdef LIBMESH_ENABLE_CONSTRAINTS 3048 std::size_t n_constraints = 0, max_constraint_length = 0,
3050 long double avg_constraint_length = 0.;
3058 std::size_t rowsize = row.size();
3060 max_constraint_length = std::max(max_constraint_length,
3062 avg_constraint_length += rowsize;
3069 this->
comm().
sum(n_constraints);
3071 this->
comm().
sum(avg_constraint_length);
3072 this->
comm().
max(max_constraint_length);
3074 os <<
" DofMap Constraints\n Number of DoF Constraints = " 3078 <<
" Number of Heterogenous Constraints= " << n_rhss;
3081 avg_constraint_length /= n_constraints;
3084 <<
" Average DoF Constraint Length= " << avg_constraint_length;
3087 #ifdef LIBMESH_ENABLE_NODE_CONSTRAINTS 3088 std::size_t n_node_constraints = 0, max_node_constraint_length = 0,
3090 long double avg_node_constraint_length = 0.;
3099 std::size_t rowsize = row.size();
3101 max_node_constraint_length = std::max(max_node_constraint_length,
3103 avg_node_constraint_length += rowsize;
3104 n_node_constraints++;
3106 if (pr.second !=
Point(0))
3110 this->
comm().
sum(n_node_constraints);
3111 this->
comm().
sum(n_node_rhss);
3112 this->
comm().
sum(avg_node_constraint_length);
3113 this->
comm().
max(max_node_constraint_length);
3115 os <<
"\n Number of Node Constraints = " << n_node_constraints;
3118 <<
" Number of Heterogenous Node Constraints= " << n_node_rhss;
3119 if (n_node_constraints)
3121 avg_node_constraint_length /= n_node_constraints;
3122 os <<
"\n Maximum Node Constraint Length= " << max_node_constraint_length
3124 <<
" Average Node Constraint Length= " << avg_node_constraint_length;
3126 #endif // LIBMESH_ENABLE_NODE_CONSTRAINTS 3130 #endif // LIBMESH_ENABLE_CONSTRAINTS 3137 _sc = std::make_unique<StaticCondensationDofMap>(
mesh, sys, *
this);
3147 std::string_view var,
3149 const std::set<subdomain_id_type> *
const active_subdomains)
3151 parallel_object_only();
3157 if (active_subdomains)
3176 bool check1 = (!active_subdomains || active_subdomains->empty()) &&
3182 (active_subdomains && (*active_subdomains == existing_var.
active_subdomains()));
3185 if (check1 || check2)
3189 libmesh_error_msg(
"ERROR: incompatible variable " 3190 << var <<
" has already been added for this system!");
3208 const std::set<subdomain_id_type> *
const their_active_subdomains(
3212 if (vg.
type() != type)
3213 should_be_in_vg =
false;
3216 if (their_active_subdomains &&
3217 (!active_subdomains || (active_subdomains && active_subdomains->empty())))
3218 should_be_in_vg =
false;
3221 if (!their_active_subdomains && (active_subdomains && !active_subdomains->empty()))
3222 should_be_in_vg =
false;
3224 if (their_active_subdomains && active_subdomains)
3226 if (*their_active_subdomains != *active_subdomains)
3227 should_be_in_vg =
false;
3231 if (should_be_in_vg)
3233 const unsigned int vn = this->
n_vars();
3235 std::string varstr(var);
3238 vg.
append(std::move(varstr));
3250 sys, std::vector<std::string>(1, std::string(var)), type, active_subdomains);
3254 const std::vector<std::string> & vars,
3256 const std::set<subdomain_id_type> *
const active_subdomains)
3258 parallel_object_only();
3266 if (active_subdomains)
3271 for (
auto ovar : vars)
3281 libmesh_error_msg(
"ERROR: incompatible variable " 3282 << ovar <<
" has already been added for this system!");
3299 const std::set<subdomain_id_type> *
const their_active_subdomains(
3303 if (vg.
type() != type)
3304 should_be_in_vg =
false;
3307 if (their_active_subdomains &&
3308 (!active_subdomains || (active_subdomains && active_subdomains->empty())))
3309 should_be_in_vg =
false;
3312 if (!their_active_subdomains && (active_subdomains && !active_subdomains->empty()))
3313 should_be_in_vg =
false;
3315 if (their_active_subdomains && active_subdomains)
3317 if (*their_active_subdomains != *active_subdomains)
3318 should_be_in_vg =
false;
3322 if (should_be_in_vg)
3324 unsigned int vn = this->
n_vars();
3327 for (
auto ovar : vars)
3342 const unsigned int curr_n_vars = this->
n_vars();
3349 (active_subdomains ==
nullptr)
3350 ?
VariableGroup(&sys, vars, curr_n_vars, next_first_component, type)
3351 :
VariableGroup(&sys, vars, curr_n_vars, next_first_component, type, *active_subdomains));
3359 const unsigned int vn = curr_n_vars + v;
3366 libmesh_assert_equal_to((curr_n_vars + vars.size()), this->
n_vars());
3374 return cast_int<unsigned int>(curr_n_vars + vars.size() - 1);
3378 const std::vector<std::string> & vars,
3380 const std::set<subdomain_id_type> *
const active_subdomains)
3382 const unsigned int count = cast_int<unsigned int>(vars.size());
3383 const unsigned int last_var = this->
add_variables(sys, vars, type, active_subdomains);
3384 const unsigned int first_var = last_var + 1 - count;
3391 all_variable_numbers.resize(
n_vars());
3393 unsigned int count = 0;
3395 all_variable_numbers[count++] = vn.second;
3398 template LIBMESH_EXPORT
bool DofMap::is_evaluable<Elem>(
const Elem &,
unsigned int)
const;
3399 template LIBMESH_EXPORT
bool DofMap::is_evaluable<Node>(
const Node &,
unsigned int)
const;
std::vector< VariableGroup > _variable_groups
The variable groups in this system/degree of freedom map.
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...
bool is_initialized() const
FEFamily family
The type of finite element.
void parallel_for(const Range &range, const Body &body, unsigned int n_threads=libMesh::n_threads())
Execute the provided function object in parallel on the specified range.
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 p_refinement
Whether or not the finite elements for this type increase their p refinement level on geometric eleme...
bool _implicit_neighbor_dofs
dof_id_type dof_number(const unsigned int s, const unsigned int var, const unsigned int comp) const
static constexpr processor_id_type invalid_processor_id
An invalid processor_id to distinguish DoFs that have not been assigned to a processor.
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.
bool has_variable(std::string_view var) const
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.
unsigned int n_components(const MeshBase &mesh) const
std::vector< dof_id_type > _send_list
A list containing all the global DOF indices that affect the solution on my processor.
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...
unsigned int add_variables(System &sys, const std::vector< std::string > &vars, const FEType &type, const std::set< subdomain_id_type > *const active_subdomains=nullptr)
Adds the variables vars to the list of variables for this system.
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 get_all_variable_numbers(std::vector< unsigned int > &all_variable_numbers) const
Fills all_variable_numbers with all the variable numbers for the variables that have been added to th...
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 (at 0 p-refinement level).
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)
const MeshBase & get_mesh() const
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.
std::map< std::string, unsigned int, std::less<> > _variable_numbers
The variable numbers corresponding to user-specified names, useful for name-based lookups...
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.
void append(std::string var_name)
Appends a variable to the group.
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
bool identify_variable_groups() 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.
const std::set< subdomain_id_type > & active_subdomains() const
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.
unsigned int add_variable(System &sys, std::string_view var, const FEType &type, const std::set< subdomain_id_type > *const active_subdomains=nullptr)
Adds the variable var to the list of variables for this system.
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 constexpr dof_id_type invalid_id
An invalid id to distinguish an uninitialized DofObject.
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
const ElemRange & element_stored_range()
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
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
const FEType & variable_type(const unsigned int i) const
The Tri3Subdivision element is a three-noded subdivision surface shell element used in mechanics calc...
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
const std::string & variable_name(const unsigned int i) 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.
std::vector< std::pair< unsigned int, unsigned int > > _array_variables
Array variable information storage.
bool implicitly_active() const
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)
void parallel_reduce(const Range &range, Body &body, unsigned int n_threads=libMesh::n_threads())
Execute the provided reduction operation in parallel on the specified range.
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.
unsigned int n_vars() const
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.
unsigned int add_variable_array(System &sys, const std::vector< std::string > &vars, const FEType &type, const std::set< subdomain_id_type > *const active_subdomains=nullptr)
Adds variables vars to the list of variables 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 variables in this system/degree of freedom map.
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
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 array_dof_indices(const Elem *const elem, std::vector< dof_id_type > &di, const unsigned int vn, int p_level=-12345) const
Fills the vector di with the global degree of freedom indices for the element.
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.