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();
526 for (
auto & elem :
mesh.element_ptr_range())
528 elem->clear_old_dof_object();
537 for (
auto & elem :
mesh.element_ptr_range())
543 for (
Node & node : elem->node_ref_range())
544 if (node.get_old_dof_object() ==
nullptr)
545 if (node.has_dofs(sys_num))
546 node.set_old_dof_object();
550 if (elem->has_dofs(sys_num))
551 elem->set_old_dof_object();
554 #endif // #ifdef LIBMESH_ENABLE_AMR 563 for (
auto & node :
mesh.node_ptr_range())
564 node->set_n_vars_per_group(sys_num, n_vars_per_group);
567 for (
auto & elem :
mesh.element_ptr_range())
568 elem->set_n_vars_per_group(sys_num, n_vars_per_group);
571 this->_n_SCALAR_dofs = 0;
575 for (
unsigned int vg=0; vg<n_var_groups; vg++)
577 const VariableGroup & vg_description = this->variable_group(vg);
579 const unsigned int n_var_in_group = vg_description.
n_variables();
580 const FEType & base_fe_type = vg_description.
type();
582 const bool add_p_level =
583 #ifdef LIBMESH_ENABLE_AMR 584 !_dont_p_refine.count(vg);
593 this->_n_SCALAR_dofs += base_fe_type.
order.
get_order()*n_var_in_group;
598 const bool extra_hanging_dofs =
602 for (
auto & elem :
mesh.active_element_ptr_range())
610 const bool active_on_elem =
615 if (!active_on_elem && constraining_subdomains_empty)
618 FEType fe_type = base_fe_type;
624 "ERROR: Finite element " 626 <<
" on geometric element " 628 <<
"\nonly supports FEInterface::max_order = " 630 <<
", not fe_type.order = " 631 << base_fe_type.
order);
633 #ifdef LIBMESH_ENABLE_AMR 636 if (base_fe_type.
order + add_p_level*elem->p_level() >
642 <<
" on geometric element " 644 <<
"could not be p refined past FEInterface::max_order = " 649 -
int(base_fe_type.
order));
654 for (
auto n : elem->node_index_range())
656 Node & node = elem->node_ref(n);
661 bool active_on_node = active_on_elem;
663 if (
auto it = constraining_subdomains.find(&node);
664 it != constraining_subdomains.end())
665 for (
auto s : it->second)
668 active_on_node =
true;
675 if (elem->is_vertex(n))
677 const unsigned int old_node_dofs =
680 const unsigned int vertex_dofs =
685 if (vertex_dofs > old_node_dofs)
710 for (
auto & elem :
mesh.active_element_ptr_range())
718 const bool active_on_elem =
723 if (!active_on_elem && constraining_subdomains_empty)
727 for (
auto n : elem->node_index_range())
729 Node & node = elem->node_ref(n);
734 bool active_on_node = active_on_elem;
736 if (
auto it = constraining_subdomains.find(&node);
737 it != constraining_subdomains.end())
738 for (
auto s : it->second)
741 active_on_node =
true;
748 const unsigned int old_node_dofs =
751 const unsigned int vertex_dofs = old_node_dofs?
752 cast_int<unsigned int>(node.
vg_dof_base (sys_num,vg)):0;
754 const unsigned int new_node_dofs =
758 if (elem->is_vertex(n))
760 libmesh_assert_greater_equal (old_node_dofs, vertex_dofs);
770 libmesh_assert_greater_equal (vertex_dofs, new_node_dofs);
790 else if (vertex_dofs == 0)
792 if (new_node_dofs > old_node_dofs)
804 else if (extra_hanging_dofs)
806 if (new_node_dofs > old_node_dofs - vertex_dofs)
809 vertex_dofs + new_node_dofs);
819 libmesh_assert_greater_equal (old_node_dofs, vertex_dofs);
820 if (new_node_dofs > old_node_dofs)
832 const unsigned int dofs_per_elem =
835 elem->set_n_comp_group(sys_num, vg, dofs_per_elem);
847 this->invalidate_dofs(
mesh);
854 const unsigned int sys_num = this->
sys_number();
857 for (
auto & node :
mesh.node_ptr_range())
858 node->invalidate_dofs(sys_num);
861 for (
auto & elem :
mesh.active_element_ptr_range())
862 elem->invalidate_dofs(sys_num);
887 this->_coupling_functors.clear();
904 this->_algebraic_ghosting_functors.clear();
925 #ifdef LIBMESH_ENABLE_AMR 948 parallel_object_only();
951 LOG_SCOPE(
"distribute_dofs()",
"DofMap");
961 libmesh_assert_less (proc_id, n_proc);
966 const std::map<const Node *, std::set<subdomain_id_type>>
967 constraining_subdomains =
972 constraining_subdomains);
989 (next_free_dof,
mesh, constraining_subdomains);
992 (next_free_dof,
mesh, constraining_subdomains);
1004 if (node_major_dofs)
1006 (next_free_dof,
mesh, constraining_subdomains);
1009 (next_free_dof,
mesh, constraining_subdomains);
1011 libmesh_assert_equal_to (next_free_dof,
_end_df[proc_id]);
1026 mesh.elements_end(),
1040 for (
auto & node :
mesh.node_ptr_range())
1049 libmesh_assert_greater_equal (dofid, this->
first_dof(obj_proc_id));
1050 libmesh_assert_less (dofid, this->
end_dof(obj_proc_id));
1054 for (
auto & elem :
mesh.element_ptr_range())
1063 libmesh_assert_greater_equal (dofid, this->
first_dof(obj_proc_id));
1064 libmesh_assert_less (dofid, this->
end_dof(obj_proc_id));
1071 #ifdef LIBMESH_ENABLE_AMR 1093 gf->dofmap_reinit();
1099 gf->dofmap_reinit();
1116 template <
typename T, std::enable_if_t<std::is_same_v<T, dof_
id_type> ||
1117 std::is_same_v<T, std::vector<dof_
id_type>>,
int>>
1120 unsigned int var_num)
const 1125 if constexpr (std::is_same_v<T, dof_id_type>)
1127 else if constexpr (std::is_same_v<T, std::vector<dof_id_type>>)
1134 const unsigned int sys_num = this->
sys_number();
1142 for (
auto & elem :
mesh.active_local_element_ptr_range())
1149 const unsigned int n_nodes = elem->n_nodes();
1152 for (
unsigned int n=0; n<
n_nodes; n++)
1154 const Node & node = elem->node_ref(n);
1159 const unsigned int n_comp = node.
n_comp(sys_num, var_num);
1160 for(
unsigned int i=0; i<n_comp; i++)
1165 if constexpr (std::is_same_v<T, dof_id_type>)
1167 if (
idx == 0 || index > greatest)
1168 {
idx++; greatest = index; }
1170 else if constexpr (std::is_same_v<T, std::vector<dof_id_type>>)
1172 if (
idx.empty() || index >
idx.back())
1173 idx.push_back(index);
1179 const unsigned int n_comp = elem->n_comp(sys_num, var_num);
1180 for (
unsigned int i=0; i<n_comp; i++)
1182 const dof_id_type index = elem->dof_number(sys_num,var_num,i);
1184 if constexpr (std::is_same_v<T, dof_id_type>)
1186 if (
idx == 0 || index > greatest)
1187 {
idx++; greatest = index; }
1189 else if constexpr (std::is_same_v<T, std::vector<dof_id_type>>)
1191 if (
idx.empty() || index >
idx.back())
1192 idx.push_back(index);
1206 for (
const auto & node :
mesh.local_node_ptr_range())
1210 const unsigned int n_comp = node->n_comp(sys_num, var_num);
1211 for (
unsigned int i=0; i<n_comp; i++)
1213 const dof_id_type index = node->dof_number(sys_num,var_num,i);
1215 if constexpr (std::is_same_v<T, dof_id_type>)
1217 if (
idx == 0 || index > greatest)
1218 {
idx++; greatest = index; }
1220 else if constexpr (std::is_same_v<T, std::vector<dof_id_type>>)
1222 if (
idx.empty() || index >
idx.back())
1223 idx.push_back(index);
1232 std::vector<dof_id_type> di_scalar;
1235 if constexpr (std::is_same_v<T, dof_id_type>)
1237 else if constexpr (std::is_same_v<T, std::vector<dof_id_type>>)
1238 idx.insert(
idx.end(), di_scalar.begin(), di_scalar.end());
1244 unsigned int)
const;
1248 unsigned int)
const;
1251 std::map<const Node *, std::set<subdomain_id_type>>
1254 std::map<const Node *, std::set<subdomain_id_type>> constraining_subdomains;
1260 if (!constraint_rows.empty())
1261 for (
auto & elem :
_mesh.active_element_ptr_range())
1265 for (
const Node & node : elem->node_ref_range())
1267 if (
auto it = constraint_rows.find(&node);
1268 it != constraint_rows.end())
1270 for (
const auto & [pr, val] : it->second)
1272 const Node * spline_node =
1273 pr.first->node_ptr(pr.second);
1275 constraining_subdomains[spline_node].insert(sbdid);
1281 return constraining_subdomains;
1288 const std::map<
const Node *, std::set<subdomain_id_type>> &
1289 constraining_subdomains)
1291 const unsigned int sys_num = this->sys_number();
1292 const unsigned int n_var_groups = this->n_variable_groups();
1295 const bool constraining_subdomains_empty =
1296 constraining_subdomains.empty();
1303 for (
auto & elem :
mesh.active_local_element_ptr_range())
1307 const unsigned int n_nodes = elem->n_nodes();
1312 for (
unsigned int n=0; n<
n_nodes; n++)
1314 Node & node = elem->node_ref(n);
1316 for (
unsigned vg=0; vg<n_var_groups; vg++)
1318 const VariableGroup & vg_description(this->variable_group(vg));
1323 bool active_on_node =
1327 if (!active_on_node && !constraining_subdomains_empty)
1328 if (
auto it = constraining_subdomains.find(&node);
1329 it != constraining_subdomains.end())
1330 for (
auto s : it->second)
1333 active_on_node =
true;
1357 for (
unsigned vg=0; vg<n_var_groups; vg++)
1359 const VariableGroup & vg_description(this->variable_group(vg));
1363 if (elem->n_comp_group(sys_num,vg) > 0)
1365 libmesh_assert_equal_to (elem->vg_dof_base(sys_num,vg),
1368 elem->set_vg_dof_base(sys_num,
1373 elem->n_comp_group(sys_num,vg));
1387 for (
auto & node :
mesh.local_node_ptr_range())
1388 for (
unsigned vg=0; vg<n_var_groups; vg++)
1390 const VariableGroup & vg_description(this->variable_group(vg));
1392 if (node->n_comp_group(sys_num,vg))
1395 node->set_vg_dof_base (sys_num,
1400 node->n_comp(sys_num,vg));
1404 this->distribute_scalar_dofs(next_free_dof);
1407 this->assert_no_nodes_missed(
mesh);
1416 const std::map<
const Node *, std::set<subdomain_id_type>> &
1417 constraining_subdomains)
1419 const unsigned int sys_num = this->sys_number();
1420 const unsigned int n_var_groups = this->n_variable_groups();
1423 const bool constraining_subdomains_empty =
1424 constraining_subdomains.empty();
1431 for (
unsigned vg=0; vg<n_var_groups; vg++)
1433 const VariableGroup & vg_description(this->variable_group(vg));
1435 const unsigned int n_vars_in_group = vg_description.
n_variables();
1441 for (
auto & elem :
mesh.active_local_element_ptr_range())
1447 const bool active_on_elem =
1452 if (!active_on_elem && constraining_subdomains_empty)
1455 const unsigned int n_nodes = elem->n_nodes();
1458 for (
unsigned int n=0; n<
n_nodes; n++)
1460 Node & node = elem->node_ref(n);
1462 bool active_on_node = active_on_elem;
1463 if (!active_on_node)
1464 if (
auto it = constraining_subdomains.find(&node);
1465 it != constraining_subdomains.end())
1466 for (
auto s : it->second)
1469 active_on_node =
true;
1473 if (!active_on_node)
1485 next_free_dof += (n_vars_in_group*
1491 if (elem->n_comp_group(sys_num,vg) > 0)
1493 libmesh_assert_equal_to (elem->vg_dof_base(sys_num,vg),
1496 elem->set_vg_dof_base(sys_num,
1500 next_free_dof += (n_vars_in_group*
1501 elem->n_comp_group(sys_num,vg));
1513 for (
auto & node :
mesh.local_node_ptr_range())
1514 if (node->n_comp_group(sys_num,vg))
1517 node->set_vg_dof_base (sys_num,
1521 next_free_dof += (n_vars_in_group*
1522 node->n_comp_group(sys_num,vg));
1526 this->distribute_scalar_dofs(next_free_dof);
1529 this->assert_no_nodes_missed(
mesh);
1561 MeshTools::libmesh_assert_valid_procids<Node>(
mesh);
1563 for (
auto & node :
mesh.local_node_ptr_range())
1565 unsigned int n_var_g = node->n_var_groups(this->
sys_number());
1566 for (
unsigned int vg=0; vg != n_var_g; ++vg)
1568 unsigned int n_comp_g =
1571 node->vg_dof_base(this->
sys_number(), vg) : 0;
1589 for (
const auto & gf :
as_range(gf_begin, gf_end))
1594 (*gf)(elems_begin, elems_end, p, more_elements_to_ghost);
1599 #if defined(LIBMESH_ENABLE_DEPRECATED) && defined(LIBMESH_ENABLE_AMR) 1600 std::vector<std::pair<const Elem*, const CouplingMatrix*>> children_to_couple;
1601 for (
auto it = more_elements_to_ghost.begin();
1602 it != more_elements_to_ghost.end();)
1604 const Elem * elem = it->first;
1607 libmesh_deprecated();
1608 std::vector<const Elem*> children_to_ghost;
1611 for (
const Elem * child : children_to_ghost)
1612 if (child->processor_id() != p)
1613 children_to_couple.emplace_back(child, it->second);
1615 it = more_elements_to_ghost.erase(it);
1620 more_elements_to_ghost.insert(children_to_couple.begin(),
1621 children_to_couple.end());
1624 for (
const auto & [elem, elem_cm] : more_elements_to_ghost)
1630 if (
const auto existing_it = elements_to_ghost.find(elem);
1631 existing_it == elements_to_ghost.end())
1632 elements_to_ghost.emplace(elem, elem_cm);
1635 if (existing_it->second)
1642 if (temporary_coupling_matrices.empty() ||
1643 !temporary_coupling_matrices.count(existing_it->second))
1649 auto result_pr = temporary_coupling_matrices.insert(std::make_unique<CouplingMatrix>(*existing_it->second));
1650 existing_it->second = result_pr.first->get();
1666 if (
const auto temp_it = temporary_coupling_matrices.find(existing_it->second);
1667 temp_it != temporary_coupling_matrices.end())
1668 temporary_coupling_matrices.erase(temp_it);
1670 existing_it->second =
nullptr;
1685 LOG_SCOPE(
"add_neighbors_to_send_list()",
"DofMap");
1694 =
mesh.active_local_elements_begin();
1696 =
mesh.active_local_elements_end();
1705 temporary_coupling_matrices,
1708 local_elem_it, local_elem_end,
mesh.processor_id());
1711 temporary_coupling_matrices,
1714 local_elem_it, local_elem_end,
mesh.processor_id());
1719 std::map<const CouplingMatrix *, std::vector<unsigned int>>
1720 column_variable_lists;
1722 for (
const auto & [partner, ghost_coupling] : elements_to_send)
1725 libmesh_assert_not_equal_to
1733 libmesh_assert_equal_to (ghost_coupling->size(), n_var);
1736 std::map<const CouplingMatrix *, std::vector<unsigned int>>::const_iterator
1737 column_variable_list = column_variable_lists.find(ghost_coupling);
1740 if (column_variable_list == column_variable_lists.end())
1742 auto inserted_variable_list_pair =
1743 column_variable_lists.emplace(ghost_coupling, std::vector<unsigned int>());
1744 column_variable_list = inserted_variable_list_pair.first;
1746 std::vector<unsigned int> & new_variable_list =
1747 inserted_variable_list_pair.first->second;
1751 for (
unsigned int vi = 0; vi != n_var; ++vi)
1755 for (
const auto & vj : ccr)
1758 for (
unsigned int vj = 0; vj != n_var; ++vj)
1761 new_variable_list.push_back(vj);
1765 const std::vector<unsigned int> & variable_list =
1766 column_variable_list->second;
1768 for (
const auto & vj : variable_list)
1770 std::vector<dof_id_type> di;
1778 libmesh_assert_less(d, this->
n_dofs());
1785 std::vector<dof_id_type> di;
1789 for (
const auto & dof : di)
1793 libmesh_assert_less(dof, this->
n_dofs());
1801 temporary_coupling_matrices.clear();
1811 for ( ; local_elem_it != local_elem_end; ++local_elem_it)
1813 const Elem * elem = *local_elem_it;
1815 std::vector<dof_id_type> di;
1819 for (
const auto & dof : di)
1823 libmesh_assert_less(dof, this->
n_dofs());
1833 LOG_SCOPE(
"prepare_send_list()",
"DofMap");
1845 libMesh::out <<
"WARNING: You have specified both an extra send list function and object.\n" 1846 <<
" Are you sure this is what you meant to do??" 1862 std::vector<dof_id_type>::iterator new_end =
1878 #ifdef LIBMESH_ENABLE_CONSTRAINTS 1903 bool implicit_neighbor_dofs =
1910 if (implicit_neighbor_dofs)
1932 if (!implicit_neighbor_dofs)
1940 bool all_discontinuous_dofs =
true;
1945 all_discontinuous_dofs =
false;
1947 if (all_discontinuous_dofs)
1948 implicit_neighbor_dofs =
true;
1951 return implicit_neighbor_dofs;
1965 mat->attach_sparsity_pattern (*
_sp);
1967 mat->update_sparsity_pattern (
_sp->get_sparsity_pattern());
1972 _sp->clear_full_sparsity();
2005 #ifdef LIBMESH_ENABLE_DEPRECATED 2016 &coupling_functor) ==
2033 #ifndef LIBMESH_ENABLE_DEPRECATED 2045 &coupling_functor) ==
2062 #ifdef LIBMESH_ENABLE_DEPRECATED 2066 &evaluable_functor),
2073 &evaluable_functor) ==
2089 &evaluable_functor);
2091 #ifndef LIBMESH_ENABLE_DEPRECATED 2103 &evaluable_functor) ==
2116 const std::vector<dof_id_type> & dof_indices_in,
2119 const unsigned int n_original_dofs = dof_indices_in.size();
2121 #ifdef LIBMESH_ENABLE_AMR 2124 libmesh_assert_equal_to (dof_indices_in.size(), Ue.
size());
2125 bool has_constrained_dofs =
false;
2127 for (
unsigned int il=0; il != n_original_dofs; ++il)
2133 libmesh_assert_less (ig, Ug.
size());
2141 if (has_constrained_dofs)
2144 std::vector<dof_id_type> constrained_dof_indices(dof_indices_in);
2151 libmesh_assert_equal_to (dof_indices_in.size(), C.
m());
2152 libmesh_assert_equal_to (constrained_dof_indices.size(), C.
n());
2158 for (
unsigned int i=0; i != n_original_dofs; i++)
2162 const unsigned int n_constrained =
2163 cast_int<unsigned int>(constrained_dof_indices.size());
2164 for (
unsigned int j=0; j<n_constrained; j++)
2166 const dof_id_type jg = constrained_dof_indices[j];
2174 Ue.
el(i) += C(i,j)*Ug(jg);
2183 libmesh_assert_equal_to (n_original_dofs, Ue.
size());
2185 for (
unsigned int il=0; il<n_original_dofs; il++)
2198 std::vector<dof_id_type> & di)
const 2222 std::size_t tot_size = 0;
2234 std::vector<const Node *> elem_nodes;
2238 for (
unsigned int vg=0; vg<n_var_groups; vg++)
2241 const unsigned int vars_in_group = var.
n_variables();
2246 for (
unsigned int vig=0; vig != vars_in_group; ++vig)
2251 std::vector<dof_id_type> di_new;
2253 di.insert( di.end(), di_new.begin(), di_new.end());
2257 for (
unsigned int vig=0; vig != vars_in_group; ++vig)
2261 cast_int<unsigned int>(elem_nodes.size()),
2276 for (
unsigned int vg=0; vg<n_var_groups; vg++)
2279 const unsigned int vars_in_group = var.
n_variables();
2285 for (
unsigned int vig=0; vig != vars_in_group; ++vig)
2290 std::vector<dof_id_type> di_new;
2292 di.insert( di.end(), di_new.begin(), di_new.end());
2296 for (
unsigned int vig=0; vig != vars_in_group; ++vig)
2308 libmesh_assert_equal_to (tot_size, di.size());
2314 std::vector<dof_id_type> & di,
2315 const unsigned int vn,
2324 const std::vector<dof_id_type> & scalar_dof_indices) {
2336 std::vector<dof_id_type> & di,
2337 const unsigned int vn,
2340 auto dof_indices_functor = [elem, p_level,
this](std::vector<dof_id_type> & functor_di,
2341 const unsigned int functor_vn) {
2342 this->
dof_indices(elem, functor_di, functor_vn, p_level);
2348 std::vector<dof_id_type> & di,
2349 const unsigned int vn)
const 2351 auto dof_indices_functor = [node,
this](std::vector<dof_id_type> & functor_di,
2352 const unsigned int functor_vn) {
2359 std::vector<dof_id_type> & di)
const 2375 const unsigned int sys_num = this->
sys_number();
2378 for (
unsigned int vg=0; vg<n_var_groups; vg++)
2381 const unsigned int vars_in_group = var.
n_variables();
2385 for (
unsigned int vig=0; vig != vars_in_group; ++vig)
2387 std::vector<dof_id_type> di_new;
2389 di.insert( di.end(), di_new.begin(), di_new.end());
2395 for (
unsigned int vig=0; vig != vars_in_group; ++vig)
2397 for (
int i=0; i != n_comp; ++i)
2400 node->
dof_number(sys_num, vg, vig, i, n_comp);
2401 libmesh_assert_not_equal_to
2412 std::vector<dof_id_type> & di,
2413 const unsigned int vn)
const 2434 const unsigned int sys_num = this->
sys_number();
2442 std::vector<dof_id_type> di_new;
2444 di.insert( di.end(), di_new.begin(), di_new.end());
2448 const unsigned int vig = vn - var.
number();
2450 for (
int i=0; i != n_comp; ++i)
2453 node->
dof_number(sys_num, vg, vig, i, n_comp);
2454 libmesh_assert_not_equal_to
2464 std::vector<dof_id_type> & di,
2465 const unsigned int vn)
const 2472 #ifdef LIBMESH_ENABLE_AMR 2476 std::vector<dof_id_type> & di,
2477 const unsigned int vn)
const 2483 #endif // LIBMESH_ENABLE_AMR 2490 std::vector<dof_id_type> & di,
2491 const unsigned int vn)
const 2498 LOG_SCOPE(
"_node_dof_indices()",
"DofMap");
2500 const unsigned int sys_num = this->
sys_number();
2501 const auto [vg, vig] =
2503 const unsigned int n_comp = obj.
n_comp_group(sys_num,vg);
2507 const bool extra_hanging_dofs =
2510 const bool add_p_level =
2511 #ifdef LIBMESH_ENABLE_AMR 2521 const unsigned int nc =
2528 if (extra_hanging_dofs && nc && !elem.
is_vertex(n))
2530 const int dof_offset = n_comp - nc;
2541 for (
unsigned int i = dof_offset; i != n_comp; ++i)
2556 const unsigned int good_nc =
2557 std::min(static_cast<unsigned int>(n_comp), nc);
2558 for (
unsigned int i=0; i != good_nc; ++i)
2565 for (
unsigned int i=good_nc; i != nc; ++i)
2573 std::vector<dof_id_type> & di,
2574 const unsigned int vg,
2575 const unsigned int vig,
2576 const Node *
const * nodes,
2578 const unsigned int v
2581 std::size_t & tot_size
2599 std::vector<dof_id_type> & functor_di,
2600 const dof_id_type dof) { functor_di.push_back(dof); });
2604 const unsigned int vn,
2605 #ifdef LIBMESH_ENABLE_AMR
2612 LOG_SCOPE(
"SCALAR_dof_indices()",
"DofMap");
2616 #ifdef LIBMESH_ENABLE_AMR 2632 di.resize(n_dofs_vn);
2633 for (
int i = 0; i != n_dofs_vn; ++i)
2658 for (
const auto & di : dof_indices_in)
2667 template <
typename DofObjectSub
class>
2669 unsigned int var_num)
const 2675 std::vector<dof_id_type> di;
2687 #ifdef LIBMESH_ENABLE_AMR 2690 std::vector<dof_id_type> & di,
2691 const unsigned int vn)
const 2693 LOG_SCOPE(
"old_dof_indices()",
"DofMap");
2698 const unsigned int sys_num = this->
sys_number();
2700 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS 2701 const bool is_inf = elem->
infinite();
2715 std::vector<const Node *> elem_nodes;
2716 const Node *
const * nodes_ptr;
2723 nodes_ptr = elem_nodes.data();
2724 n_nodes = cast_int<unsigned int>(elem_nodes.size());
2734 for (
unsigned int vg=0; vg<n_var_groups; vg++)
2737 const unsigned int vars_in_group = var.
n_variables();
2739 for (
unsigned int vig=0; vig<vars_in_group; vig++)
2741 const unsigned int v = var.
number(vig);
2749 std::vector<dof_id_type> di_new;
2751 di.insert( di.end(), di_new.begin(), di_new.end());
2759 const bool add_p_level =
2760 #ifdef LIBMESH_ENABLE_AMR 2768 int p_adjustment = 0;
2771 libmesh_assert_greater (elem->
p_level(), 0);
2778 p_adjustment *= add_p_level;
2781 int extra_order =
int(add_p_level*elem->
p_level()) + p_adjustment;
2783 const bool extra_hanging_dofs =
2790 for (
unsigned int n=0; n<
n_nodes; n++)
2792 const Node * node = nodes_ptr[n];
2799 const unsigned int nc =
2800 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS 2804 ndan (type, var.
type().
order + extra_order, n);
2806 const int n_comp = old_dof_obj.
n_comp_group(sys_num,vg);
2812 if (extra_hanging_dofs && !elem->is_vertex(n))
2814 const int dof_offset = n_comp - nc;
2826 for (
int i=n_comp-1; i>=dof_offset; i--)
2829 old_dof_obj.
dof_number(sys_num, vg, vig, i, n_comp);
2848 const unsigned int old_nc =
2849 std::min(static_cast<unsigned int>(n_comp), nc);
2850 for (
unsigned int i=0; i != old_nc; ++i)
2853 old_dof_obj.
dof_number(sys_num, vg, vig, i, n_comp);
2859 for (
unsigned int i=old_nc; i != nc; ++i)
2865 const unsigned int nc =
2872 const unsigned int n_comp =
2875 if (old_dof_obj.
n_systems() > sys_num &&
2879 for (
unsigned int i=0; i<nc; i++)
2882 old_dof_obj.
dof_number(sys_num, vg, vig, i, n_comp);
2906 #endif // LIBMESH_ENABLE_AMR 2909 #ifdef LIBMESH_ENABLE_CONSTRAINTS 2913 typedef std::set<dof_id_type> RCSet;
2916 RCSet dof_set (elem_dofs.begin(), elem_dofs.end());
2925 for (
const auto & dof : elem_dofs)
2929 DofConstraints::const_iterator
2943 for (
const auto & pr : constraint_row)
2944 if (!dof_set.count (pr.first))
2946 dof_set.insert (pr.first);
2958 elem_dofs.insert (elem_dofs.end(),
2959 dof_set.begin(), dof_set.end());
2970 #endif // LIBMESH_ENABLE_CONSTRAINTS 2983 std::ostringstream os;
2988 const char * may_equal =
" <= ";
2993 if (mat->need_full_sparsity_pattern())
2997 long double avg_n_nz = 0, avg_n_oz = 0;
3001 for (
const auto & val :
_sp->get_n_nz())
3003 max_n_nz = std::max(max_n_nz, val);
3007 std::size_t n_nz_size =
_sp->get_n_nz().size();
3013 avg_n_nz /= std::max(n_nz_size,std::size_t(1));
3015 for (
const auto & val :
_sp->get_n_oz())
3017 max_n_oz = std::max(max_n_oz, val);
3021 std::size_t n_oz_size =
_sp->get_n_oz().size();
3027 avg_n_oz /= std::max(n_oz_size,std::size_t(1));
3030 os <<
" DofMap Sparsity\n Average On-Processor Bandwidth" 3031 << may_equal << avg_n_nz <<
'\n';
3033 os <<
" Average Off-Processor Bandwidth" 3034 << may_equal << avg_n_oz <<
'\n';
3036 os <<
" Maximum On-Processor Bandwidth" 3037 << may_equal << max_n_nz <<
'\n';
3039 os <<
" Maximum Off-Processor Bandwidth" 3040 << may_equal << max_n_oz << std::endl;
3042 #ifdef LIBMESH_ENABLE_CONSTRAINTS 3044 std::size_t n_constraints = 0, max_constraint_length = 0,
3046 long double avg_constraint_length = 0.;
3054 std::size_t rowsize = row.size();
3056 max_constraint_length = std::max(max_constraint_length,
3058 avg_constraint_length += rowsize;
3065 this->
comm().
sum(n_constraints);
3067 this->
comm().
sum(avg_constraint_length);
3068 this->
comm().
max(max_constraint_length);
3070 os <<
" DofMap Constraints\n Number of DoF Constraints = " 3074 <<
" Number of Heterogenous Constraints= " << n_rhss;
3077 avg_constraint_length /= n_constraints;
3080 <<
" Average DoF Constraint Length= " << avg_constraint_length;
3083 #ifdef LIBMESH_ENABLE_NODE_CONSTRAINTS 3084 std::size_t n_node_constraints = 0, max_node_constraint_length = 0,
3086 long double avg_node_constraint_length = 0.;
3095 std::size_t rowsize = row.size();
3097 max_node_constraint_length = std::max(max_node_constraint_length,
3099 avg_node_constraint_length += rowsize;
3100 n_node_constraints++;
3102 if (pr.second !=
Point(0))
3106 this->
comm().
sum(n_node_constraints);
3107 this->
comm().
sum(n_node_rhss);
3108 this->
comm().
sum(avg_node_constraint_length);
3109 this->
comm().
max(max_node_constraint_length);
3111 os <<
"\n Number of Node Constraints = " << n_node_constraints;
3114 <<
" Number of Heterogenous Node Constraints= " << n_node_rhss;
3115 if (n_node_constraints)
3117 avg_node_constraint_length /= n_node_constraints;
3118 os <<
"\n Maximum Node Constraint Length= " << max_node_constraint_length
3120 <<
" Average Node Constraint Length= " << avg_node_constraint_length;
3122 #endif // LIBMESH_ENABLE_NODE_CONSTRAINTS 3126 #endif // LIBMESH_ENABLE_CONSTRAINTS 3133 _sc = std::make_unique<StaticCondensationDofMap>(
mesh, sys, *
this);
3143 std::string_view var,
3145 const std::set<subdomain_id_type> *
const active_subdomains)
3147 parallel_object_only();
3153 if (active_subdomains)
3172 bool check1 = (!active_subdomains || active_subdomains->empty()) &&
3178 (active_subdomains && (*active_subdomains == existing_var.
active_subdomains()));
3181 if (check1 || check2)
3185 libmesh_error_msg(
"ERROR: incompatible variable " 3186 << var <<
" has already been added for this system!");
3204 const std::set<subdomain_id_type> *
const their_active_subdomains(
3208 if (vg.
type() != type)
3209 should_be_in_vg =
false;
3212 if (their_active_subdomains &&
3213 (!active_subdomains || (active_subdomains && active_subdomains->empty())))
3214 should_be_in_vg =
false;
3217 if (!their_active_subdomains && (active_subdomains && !active_subdomains->empty()))
3218 should_be_in_vg =
false;
3220 if (their_active_subdomains && active_subdomains)
3222 if (*their_active_subdomains != *active_subdomains)
3223 should_be_in_vg =
false;
3227 if (should_be_in_vg)
3229 const unsigned int vn = this->
n_vars();
3231 std::string varstr(var);
3234 vg.
append(std::move(varstr));
3246 sys, std::vector<std::string>(1, std::string(var)), type, active_subdomains);
3250 const std::vector<std::string> & vars,
3252 const std::set<subdomain_id_type> *
const active_subdomains)
3254 parallel_object_only();
3262 if (active_subdomains)
3267 for (
auto ovar : vars)
3277 libmesh_error_msg(
"ERROR: incompatible variable " 3278 << ovar <<
" has already been added for this system!");
3295 const std::set<subdomain_id_type> *
const their_active_subdomains(
3299 if (vg.
type() != type)
3300 should_be_in_vg =
false;
3303 if (their_active_subdomains &&
3304 (!active_subdomains || (active_subdomains && active_subdomains->empty())))
3305 should_be_in_vg =
false;
3308 if (!their_active_subdomains && (active_subdomains && !active_subdomains->empty()))
3309 should_be_in_vg =
false;
3311 if (their_active_subdomains && active_subdomains)
3313 if (*their_active_subdomains != *active_subdomains)
3314 should_be_in_vg =
false;
3318 if (should_be_in_vg)
3320 unsigned int vn = this->
n_vars();
3323 for (
auto ovar : vars)
3338 const unsigned int curr_n_vars = this->
n_vars();
3345 (active_subdomains ==
nullptr)
3346 ?
VariableGroup(&sys, vars, curr_n_vars, next_first_component, type)
3347 :
VariableGroup(&sys, vars, curr_n_vars, next_first_component, type, *active_subdomains));
3355 const unsigned int vn = curr_n_vars + v;
3362 libmesh_assert_equal_to((curr_n_vars + vars.size()), this->
n_vars());
3370 return cast_int<unsigned int>(curr_n_vars + vars.size() - 1);
3374 const std::vector<std::string> & vars,
3376 const std::set<subdomain_id_type> *
const active_subdomains)
3378 const unsigned int count = cast_int<unsigned int>(vars.size());
3379 const unsigned int last_var = this->
add_variables(sys, vars, type, active_subdomains);
3380 const unsigned int first_var = last_var + 1 - count;
3387 all_variable_numbers.resize(
n_vars());
3389 unsigned int count = 0;
3391 all_variable_numbers[count++] = vn.second;
3394 template LIBMESH_EXPORT
bool DofMap::is_evaluable<Elem>(
const Elem &,
unsigned int)
const;
3395 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.
T command_line_next(std::string name, T default_value)
Use GetPot's search()/next() functions to get following arguments from the command line...
A class holding degree of freedom information pertinent to static condensation.
dof_id_type vg_dof_base(const unsigned int s, const unsigned int vg) const
VariableGroup DoF indices are indexed as id = base + var_in_vg*ncomp + comp This method allows for di...
bool _implicit_neighbor_dofs_initialized
Bools to indicate if we override the –implicit_neighbor_dofs commandline options.
ElemType
Defines an enum for geometric element types.
std::vector< GhostingFunctor * >::const_iterator GhostingFunctorIterator
Iterator type for coupling and algebraic ghosting functor ranges.
unsigned int n_variable_groups() const
bool _implicit_neighbor_dofs
dof_id_type dof_number(const unsigned int s, const unsigned int var, const unsigned int comp) const
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.
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
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)
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
void parallel_reduce(const Range &range, Body &body)
Execute the provided reduction operation in parallel on the specified range.
std::unordered_set< unsigned int > _dont_p_refine
A container of variable groups that we should not p-refine.
unsigned int number(unsigned int v) const
std::pair< unsigned int, unsigned int > var_to_vg_and_offset(const unsigned int s, const unsigned int var) const
void(* _extra_send_list_function)(std::vector< dof_id_type > &, void *)
A function pointer to a function to call to add extra entries to the send list.
DofObject * node_ptr(MeshBase &mesh, dof_id_type i) const
Defines an abstract dense vector base class for use in Finite Element-type computations.
std::map< const Node *, Real, std::less< const Node * >, Threads::scalable_allocator< std::pair< const Node *const, Real > > > NodeConstraintRow
A row of the Node constraint mapping.
MeshBase & _mesh
The mesh that system uses.
void prepare_send_list()
Takes the _send_list vector (which may have duplicate entries) and sorts it.
bool all_semilocal_indices(const std::vector< dof_id_type > &dof_indices) const
bool on_command_line(std::string arg)
virtual bool infinite() const =0
std::unique_ptr< DefaultCoupling > _default_evaluating
The default algebraic GhostingFunctor, used to implement standard libMesh send_list construction...
std::vector< unsigned int > _variable_group_numbers
The variable group number for each variable.
std::map< GhostingFunctor *, std::shared_ptr< GhostingFunctor > > _shared_functors
Hang on to references to any GhostingFunctor objects we were passed in shared_ptr form...
void remove_algebraic_ghosting_functor(GhostingFunctor &evaluable_functor)
Removes a functor which was previously added to the set of algebraic ghosting functors, from both this DofMap and from the underlying mesh.
void 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.