libMesh
dof_map.h
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2026 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
3 
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License, or (at your option) any later version.
8 
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
13 
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 
18 
19 
20 #ifndef LIBMESH_DOF_MAP_H
21 #define LIBMESH_DOF_MAP_H
22 
23 // Local Includes
24 #include "libmesh/libmesh_common.h"
25 #include "libmesh/reference_counted_object.h"
26 #include "libmesh/libmesh.h" // libMesh::invalid_uint
27 #include "libmesh/variable.h"
28 #include "libmesh/threads.h"
29 #include "libmesh/threads_allocators.h"
30 #include "libmesh/elem_range.h"
31 #include "libmesh/ghosting_functor.h"
32 #include "libmesh/sparsity_pattern.h"
33 #include "libmesh/parallel_object.h"
34 #include "libmesh/point.h"
35 #include "libmesh/utility.h"
36 #include "libmesh/elem.h"
37 #include "libmesh/fe_interface.h"
38 #include "libmesh/libmesh_logging.h"
39 #include "libmesh/enum_elem_type.h"
40 #include "libmesh/mesh_subdivision_support.h"
41 #include "libmesh/dof_map_base.h"
42 
43 // TIMPI includes
45 #include "timpi/parallel_sync.h"
46 
47 // C++ Includes
48 #include <algorithm>
49 #include <cstddef>
50 #include <iterator>
51 #include <map>
52 #include <string>
53 #include <vector>
54 #include <memory>
55 
56 namespace libMesh
57 {
58 
59 // Forward Declarations
60 class CouplingMatrix;
61 class DefaultCoupling;
62 class DirichletBoundary;
63 class DirichletBoundaries;
64 class DofMap;
65 class DofObject;
66 class FEType;
67 class MeshBase;
68 class PeriodicBoundaryBase;
69 class PeriodicBoundaries;
70 class System;
71 class NonlinearImplicitSystem;
72 class StaticCondensationDofMap;
73 template <typename T> class DenseVectorBase;
74 template <typename T> class DenseVector;
75 template <typename T> class DenseMatrix;
76 template <typename T> class SparseMatrix;
77 template <typename T> class NumericVector;
78 enum Order : int;
79 
80 
81 
82 // ------------------------------------------------------------
83 // Do we need constraints for anything?
84 
85 #if defined(LIBMESH_ENABLE_AMR) || \
86  defined(LIBMESH_ENABLE_PERIODIC) || \
87  defined(LIBMESH_ENABLE_DIRICHLET)
88 # define LIBMESH_ENABLE_CONSTRAINTS 1
89 #endif
90 
91 // ------------------------------------------------------------
92 // AMR constraint matrix types
93 
94 #ifdef LIBMESH_ENABLE_CONSTRAINTS
95 
98 typedef std::map<dof_id_type, Real,
99  std::less<dof_id_type>,
101 
108 class DofConstraints : public std::map<dof_id_type,
109  DofConstraintRow,
110  std::less<dof_id_type>,
111  Threads::scalable_allocator<std::pair<const dof_id_type, DofConstraintRow>>>
112 {
113 };
114 
121  public std::map<dof_id_type, Number,
122  std::less<dof_id_type>,
123  Threads::scalable_allocator<std::pair<const dof_id_type, Number>>>
124 {
125 };
126 
132  public std::map<unsigned int, DofConstraintValueMap,
133  std::less<unsigned int>,
134  Threads::scalable_allocator
135  <std::pair<const unsigned int, DofConstraintValueMap>>>
136 {
137 };
138 
139 #ifdef LIBMESH_ENABLE_NODE_CONSTRAINTS
140 
146 typedef std::map<const Node *, Real,
147  std::less<const Node *>,
149 
156 class NodeConstraints : public std::map<const Node *,
157  std::pair<NodeConstraintRow,Point>,
158  std::less<const Node *>,
159  Threads::scalable_allocator<std::pair<const Node * const, std::pair<NodeConstraintRow,Point>>>>
160 {
161 };
162 #endif // LIBMESH_ENABLE_NODE_CONSTRAINTS
163 
164 #endif // LIBMESH_ENABLE_CONSTRAINTS
165 
166 
167 
179 class DofMap : public DofMapBase,
180  public ReferenceCountedObject<DofMap>
181 {
182 public:
183 
189  explicit
190  DofMap(const unsigned int sys_number,
191  MeshBase & mesh);
192 
196  ~DofMap();
197 
202  {};
203 
209  {
210  public:
211  virtual ~AugmentSendList () = default;
212 
216  virtual void augment_send_list (std::vector<dof_id_type> & send_list) = 0;
217  };
218 
224  void attach_matrix (SparseMatrix<Number> & matrix);
225 
232  void update_sparsity_pattern(SparseMatrix<Number> & matrix) const;
233 
238  bool is_attached (SparseMatrix<Number> & matrix);
239 
246  std::size_t distribute_dofs (MeshBase &);
247 
253  void compute_sparsity (const MeshBase &);
254 
258  bool computed_sparsity_already () const;
259 
270  void set_constrained_sparsity_construction(bool use_constraints);
271 
276 
283 
287  void clear_sparsity();
288 
303 
308  void add_default_ghosting();
309 
315  typedef std::vector<GhostingFunctor *>::const_iterator GhostingFunctorIterator;
316 
341  void add_coupling_functor(GhostingFunctor & coupling_functor,
342  bool to_mesh = true);
343 
351  void add_coupling_functor(std::shared_ptr<GhostingFunctor> coupling_functor,
352  bool to_mesh = true)
353  { _shared_functors[coupling_functor.get()] = coupling_functor;
354  this->add_coupling_functor(*coupling_functor, to_mesh); }
355 
361  void remove_coupling_functor(GhostingFunctor & coupling_functor);
362 
367  { return _coupling_functors.begin(); }
368 
373  { return _coupling_functors.end(); }
374 
379 
403  void add_algebraic_ghosting_functor(GhostingFunctor & evaluable_functor,
404  bool to_mesh = true);
405 
413  void add_algebraic_ghosting_functor(std::shared_ptr<GhostingFunctor> evaluable_functor,
414  bool to_mesh = true)
415  { _shared_functors[evaluable_functor.get()] = evaluable_functor;
416  this->add_algebraic_ghosting_functor(*evaluable_functor, to_mesh); }
417 
423  void remove_algebraic_ghosting_functor(GhostingFunctor & evaluable_functor);
424 
429  { return _algebraic_ghosting_functors.begin(); }
430 
435  { return _algebraic_ghosting_functors.end(); }
436 
441 
453  {
455  }
456 
468  std::vector<dof_id_type> & n_nz,
469  std::vector<dof_id_type> & n_oz,
470  void *),
471  void * context = nullptr)
473 
482  {
483  _augment_send_list = &asl;
484  }
485 
490  void attach_extra_send_list_function(void (*func)(std::vector<dof_id_type> &, void *),
491  void * context = nullptr)
493 
500  void prepare_send_list ();
501 
508  {
509  _send_list.clear();
510  }
511 
521  void reinit_send_list (MeshBase & mesh);
522 
523 
533  const std::vector<dof_id_type> & get_send_list() const { return _send_list; }
534 
542  const std::vector<dof_id_type> & get_n_nz() const
543  {
545  return _sp->get_n_nz();
546  }
547 
555  const std::vector<dof_id_type> & get_n_oz() const
556  {
558  return _sp->get_n_oz();
559  }
560 
561 
571  {
572  return _sp.get();
573  }
574 
578  unsigned int n_vars() const;
579 
583  const std::string & variable_name(const unsigned int i) const;
584 
591  unsigned int n_components(const MeshBase & mesh) const;
592 
597  bool identify_variable_groups () const;
598 
602  void identify_variable_groups (const bool);
603 
614  unsigned int variable_scalar_number (unsigned int var_num,
615  unsigned int component) const;
616 
620  const FEType & variable_type (const unsigned int i) const;
621 
625  const FEType & variable_type (std::string_view var) const;
626 
631  unsigned int variable_number (std::string_view var) const;
632 
636  bool has_variable(std::string_view var) const;
637 
642  void get_all_variable_numbers(std::vector<unsigned int> & all_variable_numbers) const;
643 
652  unsigned int add_variable (System & sys,
653  std::string_view var,
654  const FEType & type,
655  const std::set<subdomain_id_type> * const active_subdomains = nullptr);
656 
665  unsigned int add_variables (System & sys,
666  const std::vector<std::string> & vars,
667  const FEType & type,
668  const std::set<subdomain_id_type> * const active_subdomains = nullptr);
669 
688  unsigned int add_variable_array (System & sys,
689  const std::vector<std::string> & vars,
690  const FEType & type,
691  const std::set<subdomain_id_type> * const active_subdomains = nullptr);
692 
703  void set_error_on_cyclic_constraint(bool error_on_cyclic_constraint);
704  void set_error_on_constraint_loop(bool error_on_constraint_loop);
705 
709  const VariableGroup & variable_group (const unsigned int c) const;
710 
711  const Variable & variable (const unsigned int c) const override;
712 
716  Order variable_order (const unsigned int c) const;
717 
721  Order variable_group_order (const unsigned int vg) const;
722 
726  const FEType & variable_group_type (const unsigned int vg) const;
727 
733  unsigned int n_variable_groups() const
734  { return cast_int<unsigned int>(_variable_groups.size()); }
735 
736  unsigned int n_variables() const override
737  { return cast_int<unsigned int>(_variables.size()); }
738 
742  unsigned int var_group_from_var_number(unsigned int var_num) const;
743 
750  {
751  return ((this->n_variable_groups() == 1) && (this->n_variables() > 1));
752  }
753 
766  unsigned int block_size() const
767  {
768  return (this->has_blocked_representation() ? this->n_variables() : 1);
769  }
770 
771  using DofMapBase::n_dofs;
776  dof_id_type n_dofs(const unsigned int vn) const
777  {
778  dof_id_type n = this->n_local_dofs(vn);
779  this->comm().sum(n);
780  return n;
781  }
782 
787 
794  dof_id_type n_local_dofs(const unsigned int vn) const
795  {
796  dof_id_type n;
797  this->local_variable_indices(n, _mesh, vn);
798  return n;
799  }
800 
805  std::vector<dof_id_type> n_dofs_per_processor(const unsigned int vn) const
806  {
807  std::vector<dof_id_type> n_local_dofs(this->n_processors(), 0);
808  this->comm().allgather(this->n_local_dofs(vn), n_local_dofs);
809  return n_local_dofs;
810  }
811 
816  { std::vector<dof_id_type>::const_iterator ub =
817  std::upper_bound(_end_df.begin(), _end_df.end(), dof);
818  libmesh_assert (ub != _end_df.end());
819  return cast_int<processor_id_type>(ub - _end_df.begin());
820  }
821 
822  void dof_indices (const Elem * const elem,
823  std::vector<dof_id_type> & di) const;
824 
830  void dof_indices (const Elem * const elem,
831  std::vector<dof_id_type> & di,
832  const unsigned int vn,
833  int p_level = -12345) const override;
834 
841  void array_dof_indices(const Elem * const elem,
842  std::vector<dof_id_type> & di,
843  const unsigned int vn,
844  int p_level = -12345) const;
845 
846  void array_dof_indices(const Node * const node,
847  std::vector<dof_id_type> & di,
848  const unsigned int vn) const;
849 
850  template <typename DofIndicesFunctor>
851  void array_dof_indices(const DofIndicesFunctor & functor,
852  std::vector<dof_id_type> & di,
853  const unsigned int vn) const;
854 
884  template <typename ScalarDofsFunctor, typename FieldDofsFunctor>
885  void dof_indices(const Elem * const elem,
886  std::vector<dof_id_type> & di,
887  const unsigned int vn,
888  ScalarDofsFunctor scalar_dofs_functor,
889  FieldDofsFunctor field_dofs_functor,
890  int p_level = -12345) const;
891 
896  void dof_indices (const Node * const node,
897  std::vector<dof_id_type> & di) const;
898 
903  void dof_indices (const Node * const node,
904  std::vector<dof_id_type> & di,
905  const unsigned int vn) const override;
906 
913  void dof_indices (const Elem & elem,
914  unsigned int n,
915  std::vector<dof_id_type> & di,
916  const unsigned int vn) const;
917 
918 #ifdef LIBMESH_ENABLE_AMR
919 
926  void old_dof_indices (const Elem & elem,
927  unsigned int n,
928  std::vector<dof_id_type> & di,
929  const unsigned int vn) const;
930 
931 #endif // LIBMESH_ENABLE_AMR
932 
941  void SCALAR_dof_indices (std::vector<dof_id_type> & di,
942  const unsigned int vn,
943  const bool old_dofs=false) const;
944 
952  bool semilocal_index (dof_id_type dof_index) const;
953 
961  bool all_semilocal_indices (const std::vector<dof_id_type> & dof_indices) const;
962 
967  bool local_index (dof_id_type dof_index) const
968  { return (dof_index >= this->first_dof()) && (dof_index < this->end_dof()); }
969 
975  template <typename DofObjectSubclass>
976  bool is_evaluable(const DofObjectSubclass & obj,
977  unsigned int var_num = libMesh::invalid_uint) const;
978 
986  void set_implicit_neighbor_dofs(bool implicit_neighbor_dofs);
987 
992 
999  bool use_coupled_neighbor_dofs(const MeshBase & mesh) const;
1000 
1012  const std::vector<dof_id_type> & dof_indices,
1013  DenseVectorBase<Number> & Ue) const;
1014 
1020  template <typename T, std::enable_if_t<std::is_same_v<T, dof_id_type> ||
1021  std::is_same_v<T, std::vector<dof_id_type>>, int> = 0>
1022  void local_variable_indices(T & idx,
1023  const MeshBase & mesh,
1024  unsigned int var_num) const;
1025 
1031  template <typename T,
1032  std::enable_if_t<std::is_same_v<T, dof_id_type> ||
1033  std::is_same_v<T, std::vector<dof_id_type>>,
1034  int> = 0>
1035  void local_variable_indices(T & idx, unsigned int var_num) const
1036  { this->local_variable_indices(idx, this->_mesh, var_num); }
1037 
1038 #ifdef LIBMESH_ENABLE_CONSTRAINTS
1039 
1040  //--------------------------------------------------------------------
1041  // Constraint-specific methods
1047 
1053 
1054 #ifdef LIBMESH_ENABLE_NODE_CONSTRAINTS
1055 
1060  { return cast_int<dof_id_type>(_node_constraints.size()); }
1061 #endif // LIBMESH_ENABLE_NODE_CONSTRAINTS
1062 
1071  void create_dof_constraints (const MeshBase &, Real time=0);
1072 
1077 
1081  void scatter_constraints (MeshBase &);
1082 
1097  std::set<dof_id_type> & unexpanded_dofs,
1098  bool look_for_constrainees);
1099 
1107  void process_constraints (MeshBase &);
1108 
1125 
1130  void add_constraint_row (const dof_id_type dof_number,
1131  const DofConstraintRow & constraint_row,
1132  const Number constraint_rhs,
1133  const bool forbid_constraint_overwrite);
1134 
1145  void add_adjoint_constraint_row (const unsigned int qoi_index,
1146  const dof_id_type dof_number,
1147  const DofConstraintRow & constraint_row,
1148  const Number constraint_rhs,
1149  const bool forbid_constraint_overwrite);
1150 
1156  void add_constraint_row (const dof_id_type dof_number,
1157  const DofConstraintRow & constraint_row,
1158  const bool forbid_constraint_overwrite = true)
1159  { add_constraint_row(dof_number, constraint_row, 0., forbid_constraint_overwrite); }
1160 
1164  DofConstraints::const_iterator constraint_rows_begin() const
1165  { return _dof_constraints.begin(); }
1166 
1170  DofConstraints::const_iterator constraint_rows_end() const
1171  { return _dof_constraints.end(); }
1172 
1178 
1180  {
1183  }
1184 
1186  {
1189  }
1190 
1204  {
1206  }
1207 
1208 #ifdef LIBMESH_ENABLE_NODE_CONSTRAINTS
1209 
1212  NodeConstraints::const_iterator node_constraint_rows_begin() const
1213  { return _node_constraints.begin(); }
1214 
1218  NodeConstraints::const_iterator node_constraint_rows_end() const
1219  { return _node_constraints.end(); }
1220 #endif // LIBMESH_ENABLE_NODE_CONSTRAINTS
1221 
1226  bool is_constrained_dof (const dof_id_type dof) const;
1227 
1232  bool has_heterogeneous_adjoint_constraints (const unsigned int qoi_num) const;
1233 
1237  bool has_heterogenous_adjoint_constraints (const unsigned int qoi_num) const
1238  {
1239  return this->has_heterogeneous_adjoint_constraints (qoi_num);
1240  }
1241 
1247  Number has_heterogeneous_adjoint_constraint (const unsigned int qoi_num,
1248  const dof_id_type dof) const;
1249 
1253  Number has_heterogenous_adjoint_constraint (const unsigned int qoi_num,
1254  const dof_id_type dof) const
1255  {
1256  return this->has_heterogeneous_adjoint_constraint (qoi_num, dof);
1257  }
1258 
1264 
1269  bool is_constrained_node (const Node * node) const;
1270 
1277  void print_dof_constraints(std::ostream & os=libMesh::out,
1278  bool print_nonlocal=false) const;
1279 
1285  std::string get_local_constraints(bool print_nonlocal=false) const;
1286 
1287 
1296  std::pair<Real, Real> max_constraint_error(const System & system,
1297  NumericVector<Number> * v = nullptr) const;
1298 
1299 #endif // LIBMESH_ENABLE_CONSTRAINTS
1300 
1301  //--------------------------------------------------------------------
1302  // Constraint-specific methods
1303  // Some of these methods are enabled (but inlined away to nothing)
1304  // when constraints are disabled at configure-time. This is to
1305  // increase API compatibility of user code with different library
1306  // builds.
1307 
1322  std::vector<dof_id_type> & elem_dofs,
1323  bool asymmetric_constraint_rows = true) const;
1324 
1332  std::vector<dof_id_type> & row_dofs,
1333  std::vector<dof_id_type> & col_dofs,
1334  bool asymmetric_constraint_rows = true) const;
1335 
1340  std::vector<dof_id_type> & dofs,
1341  bool asymmetric_constraint_rows = true) const;
1342 
1352  DenseVector<Number> & rhs,
1353  std::vector<dof_id_type> & elem_dofs,
1354  bool asymmetric_constraint_rows = true) const;
1355 
1380  DenseVector<Number> & rhs,
1381  std::vector<dof_id_type> & elem_dofs,
1382  bool asymmetric_constraint_rows = true,
1383  int qoi_index = -1) const;
1384 
1385  /*
1386  * Backwards compatibility with misspelling.
1387  */
1389  DenseVector<Number> & rhs,
1390  std::vector<dof_id_type> & elem_dofs,
1391  bool asymmetric_constraint_rows = true,
1392  int qoi_index = -1) const
1393  {
1395  (matrix, rhs, elem_dofs, asymmetric_constraint_rows, qoi_index);
1396  }
1397 
1424  DenseVector<Number> & rhs,
1425  std::vector<dof_id_type> & elem_dofs,
1426  bool asymmetric_constraint_rows = true,
1427  int qoi_index = -1) const;
1428 
1429  /*
1430  * Backwards compatibility with misspelling.
1431  */
1433  DenseVector<Number> & rhs,
1434  std::vector<dof_id_type> & elem_dofs,
1435  bool asymmetric_constraint_rows = true,
1436  int qoi_index = -1) const
1437  {
1439  (matrix, rhs, elem_dofs, asymmetric_constraint_rows, qoi_index);
1440  }
1441 
1462  DenseVector<Number> & rhs,
1463  std::vector<dof_id_type> & elem_dofs,
1464  NumericVector<Number> & solution_local) const;
1465 
1481  std::vector<dof_id_type> & elem_dofs,
1482  NumericVector<Number> & solution_local) const;
1483 
1484 
1501  std::vector<dof_id_type> & elem_dofs,
1502  NumericVector<Number> & solution_local) const;
1503 
1513  DenseVector<Number> & w,
1514  std::vector<dof_id_type> & row_dofs,
1515  bool asymmetric_constraint_rows = true) const;
1516 
1523  void constrain_nothing (std::vector<dof_id_type> & dofs) const;
1524 
1538  void enforce_constraints_exactly (const System & system,
1539  NumericVector<Number> * v = nullptr,
1540  bool homogeneous = false) const;
1541 
1549  unsigned int q) const;
1550 
1552  NumericVector<Number> * rhs,
1553  NumericVector<Number> const * solution,
1554  bool homogeneous = true) const;
1555 
1557  SparseMatrix<Number> * jac) const;
1558 
1559 #ifdef LIBMESH_ENABLE_PERIODIC
1560 
1561  //--------------------------------------------------------------------
1562  // PeriodicBoundary-specific methods
1563 
1567  void add_periodic_boundary (const PeriodicBoundaryBase & periodic_boundary);
1568 
1575  void add_periodic_boundary (const PeriodicBoundaryBase & boundary, const PeriodicBoundaryBase & inverse_boundary);
1576 
1581  bool is_periodic_boundary (const boundary_id_type boundaryid) const;
1582 
1584  {
1585  return _periodic_boundaries.get();
1586  }
1587 
1589  {
1590  return _periodic_boundaries.get();
1591  }
1592 
1593 #endif // LIBMESH_ENABLE_PERIODIC
1594 
1595 
1596 #ifdef LIBMESH_ENABLE_DIRICHLET
1597 
1598  //--------------------------------------------------------------------
1599  // DirichletBoundary-specific methods
1600 
1614  void add_dirichlet_boundary (const DirichletBoundary & dirichlet_boundary);
1615 
1621  void add_adjoint_dirichlet_boundary (const DirichletBoundary & dirichlet_boundary,
1622  unsigned int q);
1623 
1627  void remove_dirichlet_boundary (const DirichletBoundary & dirichlet_boundary);
1628 
1633  void remove_adjoint_dirichlet_boundary (const DirichletBoundary & dirichlet_boundary,
1634  unsigned int q);
1635 
1637  {
1638  return _dirichlet_boundaries.get();
1639  }
1640 
1642  {
1643  return _dirichlet_boundaries.get();
1644  }
1645 
1646  bool has_adjoint_dirichlet_boundaries(unsigned int q) const;
1647 
1648  const DirichletBoundaries *
1649  get_adjoint_dirichlet_boundaries(unsigned int q) const;
1650 
1652  get_adjoint_dirichlet_boundaries(unsigned int q);
1653 
1659  const DirichletBoundary & boundary) const;
1660 #endif // LIBMESH_ENABLE_DIRICHLET
1661 
1662 
1663 #ifdef LIBMESH_ENABLE_AMR
1664 
1665  //--------------------------------------------------------------------
1666  // AMR-specific methods
1667 
1676  // void augment_send_list_for_projection(const MeshBase &);
1677 
1678 #ifdef LIBMESH_ENABLE_AMR
1679 
1686  void old_dof_indices (const Elem * const elem,
1687  std::vector<dof_id_type> & di,
1688  const unsigned int vn = libMesh::invalid_uint) const;
1689 
1690 #endif // LIBMESH_ENABLE_AMR
1691 
1697  void constrain_p_dofs (unsigned int var,
1698  const Elem * elem,
1699  unsigned int s,
1700  unsigned int p);
1701 
1702 #endif // LIBMESH_ENABLE_AMR
1703 
1707  void reinit
1708  (MeshBase & mesh,
1709  const std::map<const Node *, std::set<subdomain_id_type>> &
1710  constraining_subdomains);
1711 
1716  virtual void clear () override;
1717 
1721  void print_info(std::ostream & os=libMesh::out) const;
1722 
1726  std::string get_info() const;
1727 
1742 
1746  unsigned int sys_number() const;
1747 
1762  std::unique_ptr<SparsityPattern::Build> build_sparsity(const MeshBase & mesh,
1763  bool calculate_constrained = false,
1764  bool use_condensed_system = false) const;
1765 
1771  void should_p_refine(unsigned int g, bool p_refine);
1772 
1776  bool should_p_refine(unsigned int g) const;
1777 
1781  bool should_p_refine_var(unsigned int var) const;
1782 
1783  // Prevent bad user implicit conversions
1784  void should_p_refine(FEFamily, bool) = delete;
1785  void should_p_refine(Order, bool) = delete;
1786  bool should_p_refine(FEFamily) const = delete;
1787  bool should_p_refine(Order) const = delete;
1788 
1792  void create_static_condensation(MeshBase & mesh, System & system);
1793 
1797  bool has_static_condensation() const { return _sc.get(); }
1798 
1804 
1810 
1815 
1816 private:
1817 
1831  const std::pair<unsigned int, unsigned int> &
1832  get_variable_array(unsigned int vi) const;
1833 
1844  void _dof_indices (const Elem & elem,
1845  int p_level,
1846  std::vector<dof_id_type> & di,
1847  const unsigned int vg,
1848  const unsigned int vig,
1849  const Node * const * nodes,
1850  unsigned int n_nodes,
1851  const unsigned int v
1852 #ifdef DEBUG
1853  ,
1854  std::size_t & tot_size
1855 #endif
1856  ) const;
1857 
1873  template <typename FieldDofsFunctor>
1874  void _dof_indices (const Elem & elem,
1875  int p_level,
1876  std::vector<dof_id_type> & di,
1877  const unsigned int vg,
1878  const unsigned int vig,
1879  const Node * const * nodes,
1880  unsigned int n_nodes,
1881  const unsigned int v,
1882 #ifdef DEBUG
1883  std::size_t & tot_size,
1884 #endif
1885  FieldDofsFunctor field_dofs_functor) const;
1886 
1891  void _node_dof_indices (const Elem & elem,
1892  unsigned int n,
1893  const DofObject & obj,
1894  std::vector<dof_id_type> & di,
1895  const unsigned int vn) const;
1896 
1900  void invalidate_dofs(MeshBase & mesh) const;
1901 
1905  DofObject * node_ptr(MeshBase & mesh, dof_id_type i) const;
1906 
1910  DofObject * elem_ptr(MeshBase & mesh, dof_id_type i) const;
1911 
1915  typedef DofObject * (DofMap::*dofobject_accessor)
1916  (MeshBase & mesh, dof_id_type i) const;
1917 
1921  template<typename iterator_type>
1922  void set_nonlocal_dof_objects(iterator_type objects_begin,
1923  iterator_type objects_end,
1924  MeshBase & mesh,
1925  dofobject_accessor objects);
1926 
1941  std::map<const Node *, std::set<subdomain_id_type>>
1943 
1957  (dof_id_type & next_free_dof,
1958  MeshBase & mesh,
1959  const std::map<const Node *, std::set<subdomain_id_type>> &
1960  constraining_subdomains);
1961 
1978  (dof_id_type & next_free_dof,
1979  MeshBase & mesh,
1980  const std::map<const Node *, std::set<subdomain_id_type>> &
1981  constraining_subdomains);
1982 
1983  /*
1984  * Helper method for the above two to count + distriubte SCALAR dofs
1985  */
1986  void distribute_scalar_dofs (dof_id_type & next_free_dof);
1987 
1988 #ifdef DEBUG
1989  /*
1990  * Internal assertions for distribute_local_dofs_*
1991  */
1993 #endif
1994 
1995  /*
1996  * A utility method for obtaining a set of elements to ghost along
1997  * with merged coupling matrices.
1998  */
1999  typedef std::set<std::unique_ptr<CouplingMatrix>, Utility::CompareUnderlying> CouplingMatricesSet;
2000  static void
2002  CouplingMatricesSet & temporary_coupling_matrices,
2003  const GhostingFunctorIterator & gf_begin,
2004  const GhostingFunctorIterator & gf_end,
2005  const MeshBase::const_element_iterator & elems_begin,
2006  const MeshBase::const_element_iterator & elems_end,
2007  processor_id_type p);
2008 
2014 
2015 #ifdef LIBMESH_ENABLE_CONSTRAINTS
2016 
2028  std::vector<dof_id_type> & elem_dofs,
2029  const bool called_recursively=false) const;
2030 
2047  DenseVector<Number> & H,
2048  std::vector<dof_id_type> & elem_dofs,
2049  int qoi_index = -1,
2050  const bool called_recursively=false) const;
2051 
2056  void find_connected_dofs (std::vector<dof_id_type> & elem_dofs) const;
2057 
2062  void find_connected_dof_objects (std::vector<const DofObject *> & objs) const;
2063 
2070 
2077 
2078 #endif // LIBMESH_ENABLE_CONSTRAINTS
2079 
2086 
2092 
2096  std::vector<Variable> _variables;
2097 
2101  std::vector<VariableGroup> _variable_groups;
2102 
2106  std::vector<unsigned int> _variable_group_numbers;
2107 
2111  std::unordered_map<unsigned int, unsigned int> _var_to_vg;
2112 
2117  std::map<std::string, unsigned int, std::less<>> _variable_numbers;
2118 
2124  std::vector<std::pair<unsigned int, unsigned int>> _array_variables;
2125 
2131 
2135  const unsigned int _sys_number;
2136 
2141 
2147  std::vector<SparseMatrix<Number> * > _matrices;
2148 
2153  std::vector<dof_id_type> _first_scalar_df;
2154 
2159  std::vector<dof_id_type> _send_list;
2160 
2165 
2170  std::vector<dof_id_type> & n_nz,
2171  std::vector<dof_id_type> & n_oz,
2172  void *);
2177 
2182 
2186  void (*_extra_send_list_function)(std::vector<dof_id_type> &, void *);
2187 
2192 
2199  std::unique_ptr<DefaultCoupling> _default_coupling;
2200 
2207  std::unique_ptr<DefaultCoupling> _default_evaluating;
2208 
2220  std::vector<GhostingFunctor *> _algebraic_ghosting_functors;
2221 
2233  std::vector<GhostingFunctor *> _coupling_functors;
2234 
2239  std::map<GhostingFunctor *, std::shared_ptr<GhostingFunctor> > _shared_functors;
2240 
2246 
2252  std::unique_ptr<SparsityPattern::Build> _sp;
2253 
2259 
2260 #ifdef LIBMESH_ENABLE_AMR
2261 
2266  std::vector<dof_id_type> _first_old_scalar_df;
2267 #endif
2268 
2269 #ifdef LIBMESH_ENABLE_CONSTRAINTS
2270 
2275 
2277 
2279 #endif
2280 
2281 #ifdef LIBMESH_ENABLE_NODE_CONSTRAINTS
2282 
2286 #endif // LIBMESH_ENABLE_NODE_CONSTRAINTS
2287 
2288 
2289 #ifdef LIBMESH_ENABLE_PERIODIC
2290 
2294  std::unique_ptr<PeriodicBoundaries> _periodic_boundaries;
2295 #endif
2296 
2297 #ifdef LIBMESH_ENABLE_DIRICHLET
2298 
2302  std::unique_ptr<DirichletBoundaries> _dirichlet_boundaries;
2303 
2308  std::vector<std::unique_ptr<DirichletBoundaries>> _adjoint_dirichlet_boundaries;
2309 #endif
2310 
2312 
2319 
2331 
2333  std::unique_ptr<StaticCondensationDofMap> _sc;
2334 };
2335 
2336 
2337 // ------------------------------------------------------------
2338 // Dof Map inline member functions
2339 inline
2340 unsigned int DofMap::sys_number() const
2341 {
2342  return _sys_number;
2343 }
2344 
2345 
2346 
2347 inline
2348 const VariableGroup & DofMap::variable_group (const unsigned int g) const
2349 {
2350  libmesh_assert_less (g, _variable_groups.size());
2351 
2352  return _variable_groups[g];
2353 }
2354 
2355 
2356 
2357 inline
2358 const Variable & DofMap::variable (const unsigned int c) const
2359 {
2360  libmesh_assert_less (c, _variables.size());
2361 
2362  return _variables[c];
2363 }
2364 
2365 
2366 
2367 inline
2368 Order DofMap::variable_order (const unsigned int c) const
2369 {
2370  libmesh_assert_less (c, _variables.size());
2371 
2372  return _variables[c].type().order;
2373 }
2374 
2375 
2376 
2377 inline
2378 Order DofMap::variable_group_order (const unsigned int vg) const
2379 {
2380  libmesh_assert_less (vg, _variable_groups.size());
2381 
2382  return _variable_groups[vg].type().order;
2383 }
2384 
2385 
2386 
2387 inline
2388 const FEType & DofMap::variable_type (const unsigned int c) const
2389 {
2390  libmesh_assert_less (c, _variables.size());
2391 
2392  return _variables[c].type();
2393 }
2394 
2395 
2396 
2397 inline
2398 const FEType & DofMap::variable_group_type (const unsigned int vg) const
2399 {
2400  libmesh_assert_less (vg, _variable_groups.size());
2401 
2402  return _variable_groups[vg].type();
2403 }
2404 
2405 
2406 #ifdef LIBMESH_ENABLE_CONSTRAINTS
2407 
2408 
2409 inline
2411 #ifdef LIBMESH_ENABLE_NODE_CONSTRAINTS
2412  node
2413 #endif
2414  ) const
2415 {
2416 #ifdef LIBMESH_ENABLE_NODE_CONSTRAINTS
2417  if (_node_constraints.count(node))
2418  return true;
2419 #endif
2420 
2421  return false;
2422 }
2423 
2424 
2425 inline
2427 {
2428  if (_dof_constraints.count(dof))
2429  return true;
2430 
2431  return false;
2432 }
2433 
2434 
2435 inline
2436 bool DofMap::has_heterogeneous_adjoint_constraints (const unsigned int qoi_num) const
2437 {
2438  AdjointDofConstraintValues::const_iterator it =
2439  _adjoint_constraint_values.find(qoi_num);
2440  if (it == _adjoint_constraint_values.end())
2441  return false;
2442  if (it->second.empty())
2443  return false;
2444 
2445  return true;
2446 }
2447 
2448 
2449 inline
2451  const dof_id_type dof) const
2452 {
2453  AdjointDofConstraintValues::const_iterator it =
2454  _adjoint_constraint_values.find(qoi_num);
2455  if (it != _adjoint_constraint_values.end())
2456  {
2457  DofConstraintValueMap::const_iterator rhsit =
2458  it->second.find(dof);
2459  if (rhsit == it->second.end())
2460  return 0;
2461  else
2462  return rhsit->second;
2463  }
2464 
2465  return 0;
2466 }
2467 
2468 
2469 
2470 inline
2472 {
2474 }
2475 
2476 
2477 
2478 #else
2479 
2480 //--------------------------------------------------------------------
2481 // Constraint-specific methods get inlined into nothing if
2482 // constraints are disabled, so there's no reason for users not to
2483 // use them.
2484 
2486  std::vector<dof_id_type> &,
2487  bool) const {}
2488 
2490  std::vector<dof_id_type> &,
2491  std::vector<dof_id_type> &,
2492  bool) const {}
2493 
2495  std::vector<dof_id_type> &,
2496  bool) const {}
2497 
2500  std::vector<dof_id_type> &,
2501  bool) const {}
2502 
2505  std::vector<dof_id_type> &, bool, int) const {}
2506 
2509  std::vector<dof_id_type> &, bool, int) const {}
2510 
2513  std::vector<dof_id_type> &,
2514  bool) const {}
2515 
2516 inline void DofMap::constrain_nothing (std::vector<dof_id_type> &) const {}
2517 
2520  bool) const {}
2521 
2523  unsigned int) const {}
2524 
2525 
2529  NumericVector<Number> const *,
2530  bool) const {}
2531 
2534  SparseMatrix<Number> *) const {}
2535 
2536 #endif // LIBMESH_ENABLE_CONSTRAINTS
2537 
2538 
2539 
2540 inline
2542 {
2543  // This got only partly finished...
2544  if (use_constraints)
2545  libmesh_not_implemented();
2546 
2547 #ifdef LIBMESH_ENABLE_CONSTRAINTS
2548  _constrained_sparsity_construction = use_constraints;
2549 #endif
2550  libmesh_ignore(use_constraints);
2551 }
2552 
2553 inline
2555 {
2557 }
2558 
2559 inline
2561 {
2562 #ifdef LIBMESH_ENABLE_CONSTRAINTS
2564 #else
2565  return true;
2566 #endif
2567 }
2568 
2569 inline
2570 void DofMap::should_p_refine(const unsigned int g, const bool p_refine)
2571 {
2572 #ifdef LIBMESH_ENABLE_AMR
2573  VariableGroup & var = _variable_groups[g];
2574  var.type().p_refinement = p_refine;
2575 
2576  for (auto v : make_range(var.first_scalar_number(0),
2577  var.first_scalar_number(0) +
2578  var.n_variables()))
2579  this->_variables[v].type().p_refinement = p_refine;
2580 
2581 
2582 #else
2583  libmesh_ignore(g, p_refine);
2584 #endif
2585 }
2586 
2587 inline
2588 bool DofMap::should_p_refine(const unsigned int g) const
2589 {
2590 #ifdef LIBMESH_ENABLE_AMR
2591  const VariableGroup & var = this->variable_group(g);
2592  return var.type().p_refinement;
2593 #else
2594  libmesh_ignore(g);
2595  return false;
2596 #endif
2597 }
2598 
2599 inline
2600 unsigned int DofMap::var_group_from_var_number(const unsigned int var_num) const
2601 {
2602  libmesh_assert(var_num < n_variables());
2603  return libmesh_map_find(_var_to_vg, var_num);
2604 }
2605 
2606 inline
2607 bool DofMap::should_p_refine_var(const unsigned int var) const
2608 {
2609 #ifdef LIBMESH_ENABLE_AMR
2610  const auto vg = this->var_group_from_var_number(var);
2611  return this->should_p_refine(vg);
2612 #else
2613  libmesh_ignore(var);
2614  return false;
2615 #endif
2616 }
2617 
2618 template <typename FieldDofsFunctor>
2619 void DofMap::_dof_indices (const Elem & elem,
2620  int p_level,
2621  std::vector<dof_id_type> & di,
2622  const unsigned int vg,
2623  const unsigned int vig,
2624  const Node * const * nodes,
2625  unsigned int n_nodes,
2626  const unsigned int v,
2627 #ifdef DEBUG
2628  std::size_t & tot_size,
2629 #endif
2630  FieldDofsFunctor field_dofs_functor) const
2631 {
2632  const VariableGroup & var = this->variable_group(vg);
2633 
2634  if (var.active_on_subdomain(elem.subdomain_id()))
2635  {
2636  const ElemType type = elem.type();
2637  const unsigned int sys_num = this->sys_number();
2638 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
2639  const bool is_inf = elem.infinite();
2640 #endif
2641 
2642  const bool extra_hanging_dofs =
2644 
2645  FEType fe_type = var.type();
2646 
2647  const bool add_p_level = fe_type.p_refinement;
2648 
2649 #ifdef DEBUG
2650  // The number of dofs per element is non-static for subdivision FE
2651  if (var.type().family == SUBDIVISION)
2652  tot_size += n_nodes;
2653  else
2654  // FIXME: Is the passed-in p_level just elem.p_level()? If so,
2655  // this seems redundant.
2656  tot_size += FEInterface::n_dofs(fe_type, add_p_level*p_level, &elem);
2657 #endif
2658 
2659  // The total Order is not required when getting the function
2660  // pointer, it is only needed when the function is called (see
2661  // below).
2662  const FEInterface::n_dofs_at_node_ptr ndan =
2663  FEInterface::n_dofs_at_node_function(fe_type, &elem);
2664 
2665  // Get the node-based DOF numbers
2666  for (unsigned int n=0; n != n_nodes; n++)
2667  {
2668  const Node & node = *nodes[n];
2669 
2670  // Cache the intermediate lookups that are common to every
2671  // component
2672 #ifdef DEBUG
2673  const std::pair<unsigned int, unsigned int>
2674  vg_and_offset = node.var_to_vg_and_offset(sys_num,v);
2675  libmesh_assert_equal_to (vg, vg_and_offset.first);
2676  libmesh_assert_equal_to (vig, vg_and_offset.second);
2677 #endif
2678  const unsigned int n_comp = node.n_comp_group(sys_num,vg);
2679 
2680  // There is a potential problem with h refinement. Imagine a
2681  // quad9 that has a linear FE on it. Then, on the hanging side,
2682  // it can falsely identify a DOF at the mid-edge node. This is why
2683  // we go through FEInterface instead of node.n_comp() directly.
2684  const unsigned int nc =
2685 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
2686  is_inf ?
2687  FEInterface::n_dofs_at_node(fe_type, add_p_level*p_level, &elem, n) :
2688 #endif
2689  ndan (type, fe_type.order + add_p_level*p_level, n);
2690 
2691  // If this is a non-vertex on a hanging node with extra
2692  // degrees of freedom, we use the non-vertex dofs (which
2693  // come in reverse order starting from the end, to
2694  // simplify p refinement)
2695  if (extra_hanging_dofs && !elem.is_vertex(n))
2696  {
2697  const int dof_offset = n_comp - nc;
2698 
2699  // We should never have fewer dofs than necessary on a
2700  // node unless we're getting indices on a parent element,
2701  // and we should never need the indices on such a node
2702  if (dof_offset < 0)
2703  {
2704  libmesh_assert(!elem.active());
2705  di.resize(di.size() + nc, DofObject::invalid_id);
2706  }
2707  else
2708  for (int i=int(n_comp)-1; i>=dof_offset; i--)
2709  {
2710  const dof_id_type d =
2711  node.dof_number(sys_num, vg, vig, i, n_comp);
2712  libmesh_assert_not_equal_to (d, DofObject::invalid_id);
2713  field_dofs_functor(elem, n, v, di, d);
2714  }
2715  }
2716  // If this is a vertex or an element without extra hanging
2717  // dofs, our dofs come in forward order coming from the
2718  // beginning
2719  else
2720  {
2721  // We have a good component index only if it's being
2722  // used on this FE type (nc) *and* it's available on
2723  // this DofObject (n_comp).
2724  const unsigned int good_nc = std::min(n_comp, nc);
2725  for (unsigned int i=0; i!=good_nc; ++i)
2726  {
2727  const dof_id_type d =
2728  node.dof_number(sys_num, vg, vig, i, n_comp);
2729  libmesh_assert_not_equal_to (d, DofObject::invalid_id);
2730  libmesh_assert_less (d, this->n_dofs());
2731  field_dofs_functor(elem, n, v, di, d);
2732  }
2733 
2734  // With fewer good component indices than we need, e.g.
2735  // due to subdomain expansion, the remaining expected
2736  // indices are marked invalid.
2737  if (n_comp < nc)
2738  for (unsigned int i=n_comp; i!=nc; ++i)
2739  di.push_back(DofObject::invalid_id);
2740  }
2741  }
2742 
2743  // If there are any element-based DOF numbers, get them
2744  const unsigned int nc = FEInterface::n_dofs_per_elem(fe_type, add_p_level*p_level, &elem);
2745 
2746  // We should never have fewer dofs than necessary on an
2747  // element unless we're getting indices on a parent element
2748  // (and we should never need those indices) or off-domain for a
2749  // subdomain-restricted variable (where invalid_id is the
2750  // correct thing to return)
2751  if (nc != 0)
2752  {
2753  const unsigned int n_comp = elem.n_comp_group(sys_num,vg);
2754  if (elem.n_systems() > sys_num && nc <= n_comp)
2755  {
2756  for (unsigned int i=0; i<nc; i++)
2757  {
2758  const dof_id_type d =
2759  elem.dof_number(sys_num, vg, vig, i, n_comp);
2760  libmesh_assert_not_equal_to (d, DofObject::invalid_id);
2761 
2762  field_dofs_functor(elem, invalid_uint, v, di, d);
2763  }
2764  }
2765  else
2766  {
2767  libmesh_assert(!elem.active() || fe_type.family == LAGRANGE || fe_type.family == SUBDIVISION);
2768  di.resize(di.size() + nc, DofObject::invalid_id);
2769  }
2770  }
2771  }
2772 }
2773 
2774 
2775 
2776 template <typename ScalarDofsFunctor, typename FieldDofsFunctor>
2777 void DofMap::dof_indices (const Elem * const elem,
2778  std::vector<dof_id_type> & di,
2779  const unsigned int vn,
2780  ScalarDofsFunctor scalar_dofs_functor,
2781  FieldDofsFunctor field_dofs_functor,
2782  int p_level) const
2783 {
2784  // We now allow elem==nullptr to request just SCALAR dofs
2785  // libmesh_assert(elem);
2786 
2787  // dof_indices() is a relatively light-weight function that is
2788  // called millions of times in normal codes. Therefore, it is not a
2789  // good candidate for logging, since the cost of the logging code
2790  // itself is roughly on par with the time required to call
2791  // dof_indices().
2792  // LOG_SCOPE("dof_indices()", "DofMap");
2793 
2794  // Clear the DOF indices vector
2795  di.clear();
2796 
2797  // Use the default p refinement level?
2798  if (p_level == -12345)
2799  p_level = elem ? elem->p_level() : 0;
2800 
2801  const unsigned int vg = this->_variable_group_numbers[vn];
2802  const VariableGroup & var = this->variable_group(vg);
2803  const unsigned int vig = vn - var.number();
2804 
2805 #ifdef DEBUG
2806  // Check that sizes match in DEBUG mode
2807  std::size_t tot_size = 0;
2808 #endif
2809 
2810  if (elem && elem->type() == TRI3SUBDIVISION)
2811  {
2812  // Subdivision surface FE require the 1-ring around elem
2813  const Tri3Subdivision * sd_elem = static_cast<const Tri3Subdivision *>(elem);
2814 
2815  // Ghost subdivision elements have no real dofs
2816  if (!sd_elem->is_ghost())
2817  {
2818  // Determine the nodes contributing to element elem
2819  std::vector<const Node *> elem_nodes;
2820  MeshTools::Subdivision::find_one_ring(sd_elem, elem_nodes);
2821 
2822  _dof_indices(*elem, p_level, di, vg, vig, elem_nodes.data(),
2823  cast_int<unsigned int>(elem_nodes.size()), vn,
2824 #ifdef DEBUG
2825  tot_size,
2826 #endif
2827  field_dofs_functor);
2828  }
2829 
2830  return;
2831  }
2832 
2833  // Get the dof numbers
2834  if (var.type().family == SCALAR &&
2835  (!elem ||
2836  var.active_on_subdomain(elem->subdomain_id())))
2837  {
2838 #ifdef DEBUG
2839  tot_size += var.type().order;
2840 #endif
2841  std::vector<dof_id_type> di_new;
2842  this->SCALAR_dof_indices(di_new,vn);
2843  scalar_dofs_functor(*elem, di, di_new);
2844  }
2845  else if (elem)
2846  _dof_indices(*elem, p_level, di, vg, vig, elem->get_nodes(),
2847  elem->n_nodes(), vn,
2848 #ifdef DEBUG
2849  tot_size,
2850 #endif
2851  field_dofs_functor);
2852 
2853 #ifdef DEBUG
2854  libmesh_assert_equal_to (tot_size, di.size());
2855 #endif
2856 }
2857 
2858 inline
2860 {
2862  return *_sc;
2863 }
2864 
2865 inline
2867 {
2869  return *_sc;
2870 }
2871 
2872 inline const std::pair<unsigned int, unsigned int> &
2873 DofMap::get_variable_array(const unsigned int vi) const
2874 {
2875  auto it = std::upper_bound(
2876  _array_variables.begin(),
2877  _array_variables.end(),
2878  vi,
2879  [](unsigned int value, const std::pair<unsigned int, unsigned int> & b) { return value < b.first; });
2880 
2881  libmesh_assert_msg(it != _array_variables.begin(),
2882  "Passed in " << std::to_string(vi) << " is not in any of our array variables");
2883  --it;
2884  libmesh_assert_msg(vi < it->second,
2885  "Passed in " << std::to_string(vi) << " is not in any of our array variables");
2886  return *it;
2887 }
2888 
2889 template <typename DofIndicesFunctor>
2890 void DofMap::array_dof_indices(const DofIndicesFunctor & functor,
2891  std::vector<dof_id_type> & di,
2892  const unsigned int vn) const
2893 {
2894  const auto [begin, end] = this->get_variable_array(vn);
2895  functor(di, begin);
2896 
2897  const unsigned int count = end - begin;
2898  // We make count, which could be >> ntest, the inner index in hopes of vectorization
2899  if (count > 1)
2900  {
2901  const dof_id_type component_size = di.size();
2902  di.resize(count * component_size);
2903 
2904  const auto pack_container = [&di,
2905  component_size](const unsigned int j,
2906  const std::vector<dof_id_type> & j_dof_indices,
2907  const unsigned int stride) {
2908  if (&j_dof_indices != &di)
2909  libmesh_assert(j_dof_indices.size() == component_size);
2910  for (const auto i : make_range(component_size))
2911  di[j * component_size + i] = j_dof_indices[i] + stride * j;
2912  };
2913  pack_container(0, di, 0);
2914 
2915  const auto & fe_type = _variable_groups[libmesh_map_find(_var_to_vg, vn)].type();
2916  if (const bool lagrange = fe_type.family == LAGRANGE;
2917  lagrange || (FEInterface::get_continuity(fe_type) == DISCONTINUOUS))
2918  {
2919  const auto stride = lagrange ? 1 : component_size;
2920  for (const auto j : make_range((unsigned int)1, count))
2921  pack_container(j, di, stride);
2922  }
2923  else
2924  {
2925  static thread_local std::vector<dof_id_type> work_dof_indices;
2926  unsigned int j = 1;
2927  for (const auto i : make_range(begin + 1, end))
2928  {
2929  functor(work_dof_indices, i);
2930  pack_container(j++, work_dof_indices, 0);
2931  }
2932  }
2933  }
2934 }
2935 
2936 inline
2937 unsigned int DofMap::n_vars() const
2938 {
2939  return cast_int<unsigned int>(_variables.size());
2940 }
2941 
2942 inline
2943 const std::string & DofMap::variable_name (const unsigned int i) const
2944 {
2945  libmesh_assert_less (i, _variables.size());
2946 
2947  return _variables[i].name();
2948 }
2949 
2950 inline
2952 {
2954 }
2955 
2956 inline
2958 {
2960 }
2961 
2962 inline
2963 unsigned int DofMap::n_components(const MeshBase & mesh) const
2964 {
2965  if (_variables.empty())
2966  return 0;
2967 
2968  const Variable & last = _variables.back();
2969  return last.first_scalar_number() + last.n_components(mesh);
2970 }
2971 
2972 inline
2973 unsigned int
2974 DofMap::variable_scalar_number (unsigned int var_num,
2975  unsigned int component) const
2976 {
2977  return _variables[var_num].first_scalar_number() + component;
2978 }
2979 
2980 inline
2981 const FEType & DofMap::variable_type (std::string_view var) const
2982 {
2983  return _variables[this->variable_number(var)].type();
2984 }
2985 
2986 inline bool DofMap::has_variable(std::string_view var) const
2987 {
2988  return _variable_numbers.count(var);
2989 }
2990 
2991 inline unsigned int DofMap::variable_number(std::string_view var) const
2992 {
2993  auto var_num = libmesh_map_find(_variable_numbers, var);
2994  libmesh_assert_equal_to(_variables[var_num].name(), var);
2995  return var_num;
2996 }
2997 
2998 } // namespace libMesh
2999 
3000 #endif // LIBMESH_DOF_MAP_H
std::vector< VariableGroup > _variable_groups
The variable groups in this system/degree of freedom map.
Definition: dof_map.h:2101
void remove_adjoint_dirichlet_boundary(const DirichletBoundary &dirichlet_boundary, unsigned int q)
Removes from the system the specified Dirichlet boundary for the adjoint equation defined by Quantity...
void find_connected_dofs(std::vector< dof_id_type > &elem_dofs) const
Finds all the DOFS associated with the element DOFs elem_dofs.
Definition: dof_map.C:2915
std::string name(const ElemQuality q)
This function returns a string containing some name for q.
Definition: elem_quality.C:42
std::unique_ptr< SparsityPattern::Build > _sp
The sparsity pattern of the global matrix.
Definition: dof_map.h:2252
static unsigned int n_dofs_per_elem(const unsigned int dim, const FEType &fe_t, const ElemType t)
Definition: fe_interface.C:531
class FEType hides (possibly multiple) FEFamily and approximation orders, thereby enabling specialize...
Definition: fe_type.h:196
std::string get_local_constraints(bool print_nonlocal=false) const
Gets a string reporting all DoF and Node constraints local to this processor.
FEFamily family
The type of finite element.
Definition: fe_type.h:228
void constrain_element_dyad_matrix(DenseVector< Number > &v, DenseVector< Number > &w, std::vector< dof_id_type > &row_dofs, bool asymmetric_constraint_rows=true) const
Constrains a dyadic element matrix B = v w&#39;.
Definition: dof_map.h:2511
A class holding degree of freedom information pertinent to static condensation.
bool _implicit_neighbor_dofs_initialized
Bools to indicate if we override the –implicit_neighbor_dofs commandline options.
Definition: dof_map.h:2317
ElemType
Defines an enum for geometric element types.
bool is_constrained_node(const Node *node) const
Definition: dof_map.h:2410
std::vector< GhostingFunctor * >::const_iterator GhostingFunctorIterator
Iterator type for coupling and algebraic ghosting functor ranges.
Definition: dof_map.h:315
void allgather(const T &send_data, std::vector< T, A > &recv_data) const
unsigned int n_variable_groups() const
Definition: dof_map.h:733
void add_adjoint_dirichlet_boundary(const DirichletBoundary &dirichlet_boundary, unsigned int q)
Adds a copy of the specified Dirichlet boundary to the system, corresponding to the adjoint problem d...
bool p_refinement
Whether or not the finite elements for this type increase their p refinement level on geometric eleme...
Definition: fe_type.h:292
const unsigned int _sys_number
The number of the system we manage DOFs for.
Definition: dof_map.h:2135
bool _implicit_neighbor_dofs
Definition: dof_map.h:2318
DofConstraintValueMap & get_primal_constraint_values()
Definition: dof_map.h:2471
void check_dirichlet_bcid_consistency(const MeshBase &mesh, const DirichletBoundary &boundary) const
Check that all the ids in dirichlet_bcids are actually present in the mesh.
dof_id_type dof_number(const unsigned int s, const unsigned int var, const unsigned int comp) const
Definition: dof_object.h:1008
Order
defines an enum for polynomial orders.
Definition: enum_order.h:40
DefaultCoupling & default_coupling()
Default coupling functor.
Definition: dof_map.h:378
const std::vector< dof_id_type > & get_n_oz() const
Definition: dof_map.h:555
A Node is like a Point, but with more information.
Definition: node.h:52
static unsigned int n_dofs(const unsigned int dim, const FEType &fe_t, const ElemType t)
Definition: fe_interface.C:353
This abstract base class defines the interface by which library code and user code can report associa...
dof_id_type n_SCALAR_dofs() const
Definition: dof_map.h:786
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 ...
~DofMap()
Destructor.
Definition: dof_map.C:204
This helper class can be called on multiple threads to compute the sparsity pattern (or graph) of the...
const unsigned int invalid_uint
A number which is used quite often to represent an invalid or uninitialized value for an unsigned int...
Definition: libmesh.h:303
void local_variable_indices(T &idx, 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...
Definition: dof_map.h:1035
processor_id_type dof_owner(const dof_id_type dof) const
Definition: dof_map.h:815
void scatter_constraints(MeshBase &)
Sends constraint equations to constraining processors.
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.
Definition: dof_map.C:469
void add_periodic_boundary(const PeriodicBoundaryBase &periodic_boundary)
Adds a copy of the specified periodic boundary to the system.
bool _error_on_constraint_loop
This flag indicates whether or not we do an opt-mode check for the presence of constraint loops...
Definition: dof_map.h:2085
void add_adjoint_constraint_row(const unsigned int qoi_index, const dof_id_type dof_number, const DofConstraintRow &constraint_row, const Number constraint_rhs, const bool forbid_constraint_overwrite)
Adds a copy of the user-defined row to the constraint matrix, using an inhomogeneous right-hand-side ...
void process_mesh_constraint_rows(const MeshBase &mesh)
Adds any spline constraints from the Mesh to our DoF constraints.
void * _extra_sparsity_context
A pointer associated with the extra sparsity that can optionally be passed in.
Definition: dof_map.h:2176
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 ...
Definition: dof_map.C:2119
void constrain_element_matrix_and_vector(DenseMatrix< Number > &matrix, DenseVector< Number > &rhs, std::vector< dof_id_type > &elem_dofs, bool asymmetric_constraint_rows=true) const
Constrains the element matrix and vector.
Definition: dof_map.h:2498
void dof_indices(const Elem *const elem, std::vector< dof_id_type > &di) const
Definition: dof_map.C:2201
dof_id_type n_dofs() const
Definition: dof_map_base.h:105
The definition of the const_element_iterator struct.
Definition: mesh_base.h:2521
std::size_t distribute_dofs(MeshBase &)
Distribute dofs on the current mesh.
Definition: dof_map.C:949
void set_implicit_neighbor_dofs(bool implicit_neighbor_dofs)
Allow the implicit_neighbor_dofs flag to be set programmatically.
Definition: dof_map.C:1891
bool has_variable(std::string_view var) const
Definition: dof_map.h:2986
void add_default_ghosting()
Add the default functor(s) for coupling and algebraic ghosting.
Definition: dof_map.C:1996
We&#39;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...
Definition: dof_map.C:1122
bool is_periodic_boundary(const boundary_id_type boundaryid) const
Definition: dof_map.C:217
Number has_heterogenous_adjoint_constraint(const unsigned int qoi_num, const dof_id_type dof) const
Backwards compatibility with misspelling.
Definition: dof_map.h:1253
GhostingFunctorIterator algebraic_ghosting_functors_begin() const
Beginning of range of algebraic ghosting functors.
Definition: dof_map.h:428
dof_id_type n_local_constrained_dofs() const
void remove_dirichlet_boundary(const DirichletBoundary &dirichlet_boundary)
Removes the specified Dirichlet boundary from the system.
const FEType & variable_group_type(const unsigned int vg) const
Definition: dof_map.h:2398
std::unique_ptr< StaticCondensationDofMap > _sc
Static condensation class.
Definition: dof_map.h:2333
unsigned int n_components(const MeshBase &mesh) const
Definition: dof_map.h:2963
NodeConstraints::const_iterator node_constraint_rows_begin() const
Definition: dof_map.h:1212
std::vector< dof_id_type > _send_list
A list containing all the global DOF indices that affect the solution on my processor.
Definition: dof_map.h:2159
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...
Definition: dof_map.C:63
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.
Definition: dof_map.C:3253
void set_verify_dirichlet_bc_consistency(bool val)
Set the _verify_dirichlet_bc_consistency flag.
Definition: dof_map.C:1897
unsigned int block_size() const
Definition: dof_map.h:766
void sum(T &r) const
bool is_attached(SparseMatrix< Number > &matrix)
Matrices should not be attached more than once.
Definition: dof_map.C:295
void attach_matrix(SparseMatrix< Number > &matrix)
Additional matrices may be attached to this DofMap.
Definition: dof_map.C:240
This is the base class from which all geometric element types are derived.
Definition: elem.h:94
void clear_send_list()
Clears the _send_list vector.
Definition: dof_map.h:507
MeshBase & mesh
void gather_constraints(MeshBase &mesh, std::set< dof_id_type > &unexpanded_dofs, bool look_for_constrainees)
Helper function for querying about constraint equations on other processors.
DefaultCoupling & default_algebraic_ghosting()
Default algebraic ghosting functor.
Definition: dof_map.h:440
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...
Definition: dof_map.C:3389
std::unique_ptr< DirichletBoundaries > _dirichlet_boundaries
Data structure containing Dirichlet functions.
Definition: dof_map.h:2302
This class allows one to associate Dirichlet boundary values with a given set of mesh boundary ids an...
Provides a uniform interface to vector storage schemes for different linear algebra libraries...
Definition: vector_fe_ex5.C:44
const Parallel::Communicator & comm() const
The Node constraint storage format.
Definition: dof_map.h:156
unsigned int p_level() const
Definition: elem.h:3122
OrderWrapper order
The approximation order of the element (at 0 p-refinement level).
Definition: fe_type.h:203
bool use_coupled_neighbor_dofs(const MeshBase &mesh) const
Tells other library functions whether or not this problem includes coupling between dofs in neighbori...
Definition: dof_map.C:1903
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.
Definition: dof_map.C:3140
void should_p_refine(unsigned int g, bool p_refine)
Set whether the given variable group should be p-refined on a p-refined Elem.
Definition: dof_map.h:2570
dof_id_type n_dofs(const unsigned int vn) const
Definition: dof_map.h:776
GhostingFunctorIterator algebraic_ghosting_functors_end() const
End of range of algebraic ghosting functors.
Definition: dof_map.h:434
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.
void add_constraint_row(const dof_id_type dof_number, const DofConstraintRow &constraint_row, const bool forbid_constraint_overwrite=true)
Adds a copy of the user-defined row to the constraint matrix, using a homogeneous right-hand-side for...
Definition: dof_map.h:1156
dof_id_type n_local_dofs(const unsigned int vn) const
Definition: dof_map.h:794
void set_error_on_constraint_loop(bool error_on_constraint_loop)
Definition: dof_map.C:234
void add_coupling_functor(GhostingFunctor &coupling_functor, bool to_mesh=true)
Adds a functor which can specify coupling requirements for creation of sparse matrices.
Definition: dof_map.C:2005
const SparsityPattern::Build * get_sparsity_pattern() const
Definition: dof_map.h:570
std::string get_info() const
Gets summary info about the sparsity bandwidth and constraints.
Definition: dof_map.C:2985
std::map< std::string, unsigned int, std::less<> > _variable_numbers
The variable numbers corresponding to user-specified names, useful for name-based lookups...
Definition: dof_map.h:2117
unsigned int sys_number() const
Definition: dof_map.h:2340
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...
Definition: dof_map.C:2605
uint8_t processor_id_type
Definition: id_types.h:104
This is the MeshBase class.
Definition: mesh_base.h:80
std::vector< dof_id_type > _first_scalar_df
First DOF index for SCALAR variable v, or garbage for non-SCALAR variable v.
Definition: dof_map.h:2153
const Variable & variable(const unsigned int c) const override
Definition: dof_map.h:2358
This class implements the default algebraic coupling in libMesh: elements couple to themselves...
const std::pair< unsigned int, unsigned int > & get_variable_array(unsigned int vi) const
Retrieve the array variable bounds for a given variable vi.
Definition: dof_map.h:2873
void enforce_adjoint_constraints_exactly(NumericVector< Number > &v, unsigned int q) const
Heterogeneously constrains the numeric vector v, which represents an adjoint solution defined on the ...
Definition: dof_map.h:2522
AdjointDofConstraintValues _adjoint_constraint_values
Definition: dof_map.h:2278
bool _constrained_sparsity_construction
This flag indicates whether or not we explicitly take constraint equations into account when computin...
Definition: dof_map.h:2091
bool should_p_refine_var(unsigned int var) const
Whether the given variable should be p-refined.
Definition: dof_map.h:2607
unsigned int var_group_from_var_number(unsigned int var_num) const
Definition: dof_map.h:2600
dof_id_type end_dof() const
Definition: dof_map_base.h:83
AugmentSendList * _augment_send_list
Function object to call to add extra entries to the send list.
Definition: dof_map.h:2181
void heterogenously_constrain_element_vector(const DenseMatrix< Number > &matrix, DenseVector< Number > &rhs, std::vector< dof_id_type > &elem_dofs, bool asymmetric_constraint_rows=true, int qoi_index=-1) const
Definition: dof_map.h:1432
bool need_full_sparsity_pattern
Default false; set to true if any attached matrix requires a full sparsity pattern.
Definition: dof_map.h:2245
bool constrained_sparsity_construction()
Returns true iff the current policy when constructing sparsity patterns is to explicitly account for ...
Definition: dof_map.h:2560
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.
Definition: dof_map.C:1418
Generic sparse matrix.
Definition: vector_fe_ex5.C:46
void enforce_constraints_on_residual(const NonlinearImplicitSystem &system, NumericVector< Number > *rhs, NumericVector< Number > const *solution, bool homogeneous=true) const
Definition: dof_map.h:2527
This class handles the numbering of degrees of freedom on a mesh.
Definition: dof_map.h:179
virtual void clear() override
Free all new memory associated with the object, but restore its original state, with the mesh pointer...
Definition: dof_map.C:871
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.
Definition: dof_map.C:2491
void add_algebraic_ghosting_functor(std::shared_ptr< GhostingFunctor > evaluable_functor, bool to_mesh=true)
Adds a functor which can specify algebraic ghosting requirements for use with distributed vectors...
Definition: dof_map.h:413
void find_one_ring(const Tri3Subdivision *elem, std::vector< const Node *> &nodes)
Determines the 1-ring of element elem, and writes it to the nodes vector.
unsigned int variable_scalar_number(unsigned int var_num, unsigned int component) const
Definition: dof_map.h:2974
bool _identify_variable_groups
true when VariableGroup structures should be automatically identified, false otherwise.
Definition: dof_map.h:2130
unsigned int first_scalar_number() const
Definition: variable.h:138
void reinit_send_list(MeshBase &mesh)
Clears the _send_list vector and then rebuilds it.
Definition: dof_map.C:1877
processor_id_type n_processors() const
void libmesh_ignore(const Args &...)
bool identify_variable_groups() const
Definition: dof_map.h:2951
const dof_id_type n_nodes
Definition: tecplot_io.C:67
dof_id_type first_dof() const
Definition: dof_map_base.h:73
std::unordered_map< unsigned int, unsigned int > _var_to_vg
A map from variable number to variable group number.
Definition: dof_map.h:2111
This class defines the notion of a variable in the system.
Definition: variable.h:50
bool has_static_condensation() const
Checks whether we have static condensation.
Definition: dof_map.h:1797
void add_neighbors_to_send_list(MeshBase &mesh)
Adds entries to the _send_list vector corresponding to DoFs on elements neighboring the current proce...
Definition: dof_map.C:1687
std::vector< dof_id_type > _first_old_scalar_df
First old DOF index for SCALAR variable v, or garbage for non-SCALAR variable v.
Definition: dof_map.h:2266
int8_t boundary_id_type
Definition: id_types.h:51
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.
Definition: dof_map.C:3146
bool has_adjoint_dirichlet_boundaries(unsigned int q) const
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.
Definition: dof_map.h:2169
dof_id_type _n_SCALAR_dofs
The total number of SCALAR dofs associated to all SCALAR variables.
Definition: dof_map.h:2258
void assert_no_nodes_missed(MeshBase &mesh)
Definition: dof_map.C:1563
PeriodicBoundaries * get_periodic_boundaries()
Definition: dof_map.h:1583
StaticCondensationDofMap & get_static_condensation()
Definition: dof_map.h:2859
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.
Definition: dof_map.C:318
unsigned int n_variables() const
Definition: variable.h:278
void add_constraint_row(const dof_id_type dof_number, const DofConstraintRow &constraint_row, const Number constraint_rhs, const bool forbid_constraint_overwrite)
Adds a copy of the user-defined row to the constraint matrix, using an inhomogeneous right-hand-side ...
static constexpr dof_id_type invalid_id
An invalid id to distinguish an uninitialized DofObject.
Definition: dof_object.h:473
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
Definition: dof_map.h:1999
DofConstraints::const_iterator constraint_rows_begin() const
Definition: dof_map.h:1164
unsigned int n_components() const
Definition: variable.C:23
void heterogeneously_constrain_element_vector(const DenseMatrix< Number > &matrix, DenseVector< Number > &rhs, std::vector< dof_id_type > &elem_dofs, bool asymmetric_constraint_rows=true, int qoi_index=-1) const
Constrains the element vector.
Definition: dof_map.h:2508
Manages consistently variables, degrees of freedom, and coefficient vectors.
Definition: system.h:98
unsigned int n_variables() const override
Definition: dof_map.h:736
unsigned int n_systems() const
Definition: dof_object.h:913
void swap_dof_constraints()
Similar to the stash/unstash_dof_constraints() API, but swaps _dof_constraints and _stashed_dof_const...
Definition: dof_map.h:1203
NodeConstraints::const_iterator node_constraint_rows_end() const
Definition: dof_map.h:1218
This base class provides a minimal set of interfaces for satisfying user requests for...
Definition: dof_map_base.h:51
dof_id_type n_constrained_nodes() const
Definition: dof_map.h:1059
const Node *const * get_nodes() const
Definition: elem.h:2505
We&#39;re using a class instead of a typedef to allow forward declarations and future flexibility...
void print_dof_constraints(std::ostream &os=libMesh::out, bool print_nonlocal=false) const
Prints (from processor 0) all DoF and Node constraints.
libmesh_assert(ctx)
void attach_extra_sparsity_object(SparsityPattern::AugmentSparsityPattern &asp)
Attach an object to use to populate the sparsity pattern with extra entries.
Definition: dof_map.h:452
DirichletBoundaries * get_dirichlet_boundaries()
Definition: dof_map.h:1641
bool is_constrained_dof(const dof_id_type dof) const
Definition: dof_map.h:2426
Manages consistently variables, degrees of freedom, coefficient vectors, matrices and non-linear solv...
const FEType & variable_type(const unsigned int i) const
Definition: dof_map.h:2388
The Tri3Subdivision element is a three-noded subdivision surface shell element used in mechanics calc...
void allgather_recursive_constraints(MeshBase &)
Gathers constraint equation dependencies from other processors.
const VariableGroup & variable_group(const unsigned int c) const
Definition: dof_map.h:2348
std::vector< GhostingFunctor * > _coupling_functors
The list of all GhostingFunctor objects to be used when coupling degrees of freedom in matrix sparsit...
Definition: dof_map.h:2233
DofConstraints _dof_constraints
Data structure containing DOF constraints.
Definition: dof_map.h:2274
void add_coupling_functor(std::shared_ptr< GhostingFunctor > coupling_functor, bool to_mesh=true)
Adds a functor which can specify coupling requirements for creation of sparse matrices.
Definition: dof_map.h:351
DofMap(const unsigned int sys_number, MeshBase &mesh)
Constructor.
Definition: dof_map.C:138
CouplingMatrix * _dof_coupling
Degree of freedom coupling.
Definition: dof_map.h:1741
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)
Definition: dof_map.C:1585
bool active_on_subdomain(subdomain_id_type sid) const
Definition: variable.h:167
const std::string & variable_name(const unsigned int i) const
Definition: dof_map.h:2943
void create_static_condensation(MeshBase &mesh, System &system)
Add a static condensation class.
Definition: dof_map.C:3135
void print_info(std::ostream &os=libMesh::out) const
Prints summary info about the sparsity bandwidth and constraints.
Definition: dof_map.C:2978
void * _extra_send_list_context
A pointer associated with the extra send list that can optionally be passed in.
Definition: dof_map.h:2191
Number has_heterogeneous_adjoint_constraint(const unsigned int qoi_num, const dof_id_type dof) const
Definition: dof_map.h:2450
This class implements reference counting.
const DirichletBoundaries * get_dirichlet_boundaries() const
Definition: dof_map.h:1636
bool computed_sparsity_already() const
Returns true iff a sparsity pattern has already been computed.
Definition: dof_map.C:258
This class defines a logically grouped set of variables in the system.
Definition: variable.h:215
void update_sparsity_pattern(SparseMatrix< Number > &matrix) const
Additional matrices may be be temporarily initialized by this DofMap.
Definition: dof_map.C:269
std::vector< std::pair< unsigned int, unsigned int > > _array_variables
Array variable information storage.
Definition: dof_map.h:2124
std::pair< Real, Real > max_constraint_error(const System &system, NumericVector< Number > *v=nullptr) const
Tests the constrained degrees of freedom on the numeric vector v, which represents a solution defined...
static n_dofs_at_node_ptr n_dofs_at_node_function(const unsigned int dim, const FEType &fe_t)
Definition: fe_interface.C:459
Storage for DofConstraint right hand sides for a particular problem.
Definition: dof_map.h:120
std::vector< SparseMatrix< Number > *> _matrices
Additional matrices handled by this object.
Definition: dof_map.h:2147
GhostingFunctorIterator coupling_functors_end() const
End of range of coupling functors.
Definition: dof_map.h:372
DofObject * elem_ptr(MeshBase &mesh, dof_id_type i) const
Definition: dof_map.C:310
Storage for DofConstraint right hand sides for all adjoint problems.
Definition: dof_map.h:131
std::vector< GhostingFunctor * > _algebraic_ghosting_functors
The list of all GhostingFunctor objects to be used when distributing ghosted vectors.
Definition: dof_map.h:2220
unsigned int n_vars() const
Definition: dof_map.h:2937
static FEContinuity get_continuity(const FEType &fe_type)
Returns the input FEType&#39;s FEContinuity based on the underlying FEFamily and potentially the Order...
std::vector< std::unique_ptr< DirichletBoundaries > > _adjoint_dirichlet_boundaries
Data structure containing Dirichlet functions.
Definition: dof_map.h:2308
static unsigned int n_dofs_at_node(const unsigned int dim, const FEType &fe_t, const ElemType t, const unsigned int n)
Definition: fe_interface.C:437
void distribute_scalar_dofs(dof_id_type &next_free_dof)
Definition: dof_map.C:1539
DofConstraints::const_iterator constraint_rows_end() const
Definition: dof_map.h:1170
std::unique_ptr< PeriodicBoundaries > _periodic_boundaries
Data structure containing periodic boundaries.
Definition: dof_map.h:2294
void heterogenously_constrain_element_matrix_and_vector(DenseMatrix< Number > &matrix, DenseVector< Number > &rhs, std::vector< dof_id_type > &elem_dofs, bool asymmetric_constraint_rows=true, int qoi_index=-1) const
Definition: dof_map.h:1388
bool has_heterogenous_adjoint_constraints(const unsigned int qoi_num) const
Backwards compatibility with misspelling.
Definition: dof_map.h:1237
void unstash_dof_constraints()
Definition: dof_map.h:1185
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...
Definition: dof_map.C:2032
unsigned int(* n_dofs_at_node_ptr)(const ElemType, const Order, const unsigned int)
Definition: fe_interface.h:151
DofObject *(DofMap::* dofobject_accessor)(MeshBase &mesh, dof_id_type i) const
A member function type like node_ptr() or elem_ptr().
Definition: dof_map.h:1916
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
Struct which defines a custom comparison object that can be used with std::sets of std::unique_ptrs...
Definition: utility.h:485
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
Definition: elem.h:2588
void stash_dof_constraints()
Definition: dof_map.h:1179
dof_id_type n_constrained_dofs() const
void constrain_element_vector(DenseVector< Number > &rhs, std::vector< dof_id_type > &dofs, bool asymmetric_constraint_rows=true) const
Constrains the element vector.
Definition: dof_map.h:2494
const DofConstraints & get_dof_constraints() const
Provide a const accessor to the DofConstraints map.
Definition: dof_map.h:1177
const std::vector< dof_id_type > & get_n_nz() const
Definition: dof_map.h:542
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...
Definition: dof_map.C:2573
void invalidate_dofs(MeshBase &mesh) const
Invalidates all active DofObject dofs for this system.
Definition: dof_map.C:856
const DirichletBoundaries * get_adjoint_dirichlet_boundaries(unsigned int q) const
void attach_extra_send_list_function(void(*func)(std::vector< dof_id_type > &, void *), void *context=nullptr)
Attach a function pointer to use as a callback to populate the send_list with extra entries...
Definition: dof_map.h:490
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.
Definition: dof_map.C:3377
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...
Definition: dof_map.h:2330
std::unique_ptr< DefaultCoupling > _default_coupling
The default coupling GhostingFunctor, used to implement standard libMesh sparsity pattern constructio...
Definition: dof_map.h:2199
static const Real b
void add_constraints_to_send_list()
Adds entries to the _send_list vector corresponding to DoFs which are dependencies for constraint equ...
OStreamProxy out
DofConstraintValueMap _primal_constraint_values
Definition: dof_map.h:2276
void heterogeneously_constrain_element_matrix_and_vector(DenseMatrix< Number > &matrix, DenseVector< Number > &rhs, std::vector< dof_id_type > &elem_dofs, bool asymmetric_constraint_rows=true, int qoi_index=-1) const
Constrains the element matrix and vector.
Definition: dof_map.h:2504
std::vector< Variable > _variables
The variables in this system/degree of freedom map.
Definition: dof_map.h:2096
DofConstraints _stashed_dof_constraints
Definition: dof_map.h:2274
void remove_default_ghosting()
Remove any default ghosting functor(s).
Definition: dof_map.C:1988
void attach_extra_sparsity_function(void(*func)(SparsityPattern::Graph &sparsity, std::vector< dof_id_type > &n_nz, std::vector< dof_id_type > &n_oz, void *), void *context=nullptr)
Attach a function pointer to use as a callback to populate the sparsity pattern with extra entries...
Definition: dof_map.h:467
SparsityPattern::AugmentSparsityPattern * _augment_sparsity_pattern
Function object to call to add extra entries to the sparsity pattern.
Definition: dof_map.h:2164
static const bool value
Definition: xdr_io.C:55
void find_connected_dof_objects(std::vector< const DofObject *> &objs) const
Finds all the DofObjects associated with the set in objs.
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.
Definition: dof_map.h:100
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...
Definition: int_range.h:176
The DofObject defines an abstract base class for objects that have degrees of freedom associated with...
Definition: dof_object.h:54
void clear_sparsity()
Clears the sparsity pattern.
Definition: dof_map.C:1981
void set_constrained_sparsity_construction(bool use_constraints)
Sets the current policy for constructing sparsity patterns: if use_constraints is true (for robustnes...
Definition: dof_map.h:2541
Order variable_order(const unsigned int c) const
Definition: dof_map.h:2368
unsigned int variable_number(std::string_view var) const
Definition: dof_map.h:2991
dof_id_type n_local_dofs() const
Definition: dof_map_base.h:115
void add_dirichlet_boundary(const DirichletBoundary &dirichlet_boundary)
Adds a copy of the specified Dirichlet boundary to the system.
unsigned int number(unsigned int v) const
Definition: variable.h:316
void build_constraint_matrix(DenseMatrix< Number > &C, std::vector< dof_id_type > &elem_dofs, const bool called_recursively=false) const
Build the constraint matrix C associated with the element degree of freedom indices elem_dofs...
std::pair< unsigned int, unsigned int > var_to_vg_and_offset(const unsigned int s, const unsigned int var) const
Definition: dof_object.h:1176
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.
Definition: dof_map.h:2186
Scalable allocator to be used in multithreaded code chunks which allocate a lot of dynamic memory...
DofObject * node_ptr(MeshBase &mesh, dof_id_type i) const
Definition: dof_map.C:303
void heterogeneously_constrain_element_residual(DenseVector< Number > &rhs, std::vector< dof_id_type > &elem_dofs, NumericVector< Number > &solution_local) const
Constrains the element residual.
The base class for defining periodic boundaries.
void create_dof_constraints(const MeshBase &, Real time=0)
Rebuilds the raw degree of freedom and DofObject constraints, based on attached DirichletBoundary obj...
Defines an abstract dense vector base class for use in Finite Element-type computations.
Definition: dof_map.h:73
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.
Definition: dof_map.h:148
MeshBase & _mesh
The mesh that system uses.
Definition: dof_map.h:2140
void prepare_send_list()
Takes the _send_list vector (which may have duplicate entries) and sorts it.
Definition: dof_map.C:1835
bool all_semilocal_indices(const std::vector< dof_id_type > &dof_indices) const
Definition: dof_map.C:2660
Defines a dense vector for use in Finite Element-type computations.
Definition: dof_map.h:74
virtual bool infinite() const =0
std::unique_ptr< DefaultCoupling > _default_evaluating
The default algebraic GhostingFunctor, used to implement standard libMesh send_list construction...
Definition: dof_map.h:2207
void full_sparsity_pattern_needed()
Sets need_full_sparsity_pattern to true regardless of the requirements by matrices.
Definition: dof_map.h:2554
std::vector< unsigned int > _variable_group_numbers
The variable group number for each variable.
Definition: dof_map.h:2106
std::map< GhostingFunctor *, std::shared_ptr< GhostingFunctor > > _shared_functors
Hang on to references to any GhostingFunctor objects we were passed in shared_ptr form...
Definition: dof_map.h:2239
void heterogeneously_constrain_element_jacobian_and_residual(DenseMatrix< Number > &matrix, DenseVector< Number > &rhs, std::vector< dof_id_type > &elem_dofs, NumericVector< Number > &solution_local) const
Constrains the element Jacobian and residual.
FEFamily
defines an enum for finite element families.
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.
Definition: dof_map.C:2089
virtual ~AugmentSendList()=default
Backwards compatibility for prior AugmentSparsityPattern users.
Definition: dof_map.h:201
void attach_extra_send_list_object(DofMap::AugmentSendList &asl)
Attach an object to populate the send_list with extra entries.
Definition: dof_map.h:481
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.
Definition: dof_map.C:2339
Order variable_group_order(const unsigned int vg) const
Definition: dof_map.h:2378
void compute_sparsity(const MeshBase &)
Computes the sparsity pattern for the matrices corresponding to proc_id and sends that data to Linear...
Definition: dof_map.C:1960
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...
Definition: dof_map.C:2062
unsigned int n_comp_group(const unsigned int s, const unsigned int vg) const
Definition: dof_object.h:991
bool has_heterogeneous_adjoint_constraints(const unsigned int qoi_num) const
Definition: dof_map.h:2436
void constrain_element_residual(DenseVector< Number > &rhs, std::vector< dof_id_type > &elem_dofs, NumericVector< Number > &solution_local) const
Constrains the element residual.
const PeriodicBoundaries * get_periodic_boundaries() const
Definition: dof_map.h:1588
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...
Definition: dof_map.C:1256
Defines a dense matrix for use in Finite Element-type computations.
Definition: dof_map.h:75
bool active() const
Definition: elem.h:2955
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...
Definition: dof_map.C:227
virtual ElemType type() const =0
Abstract base class to be used to add user-defined implicit degree of freedom couplings.
bool has_blocked_representation() const
Definition: dof_map.h:749
The constraint matrix storage format.
Definition: dof_map.h:108
void ErrorVector unsigned int
Definition: adjoints_ex3.C:360
const std::vector< dof_id_type > & get_send_list() const
Definition: dof_map.h:533
unsigned int first_scalar_number(unsigned int v) const
Definition: variable.h:329
std::vector< dof_id_type > n_dofs_per_processor(const unsigned int vn) const
Definition: dof_map.h:805
Abstract base class to be used to add user-defined parallel degree of freedom couplings.
Definition: dof_map.h:208
void constrain_nothing(std::vector< dof_id_type > &dofs) const
Does not actually constrain anything, but modifies dofs in the same way as any of the constrain funct...
Definition: dof_map.h:2516
bool is_evaluable(const DofObjectSubclass &obj, unsigned int var_num=libMesh::invalid_uint) const
Definition: dof_map.C:2673
bool semilocal_index(dof_id_type dof_index) const
Definition: dof_map.C:2644
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.
Definition: dof_map.C:1290
void constrain_p_dofs(unsigned int var, const Elem *elem, unsigned int s, unsigned int p)
Constrains degrees of freedom on side s of element elem which correspond to variable number var and t...
void check_for_cyclic_constraints()
Throw an error if we detect any constraint loops, i.e.
unsigned int idx(const ElemType type, const unsigned int nx, const unsigned int i, const unsigned int j)
A useful inline function which replaces the macros used previously.
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.
Definition: dof_map.C:2478
GhostingFunctorIterator coupling_functors_begin() const
Beginning of range of coupling functors.
Definition: dof_map.h:366
uint8_t dof_id_type
Definition: id_types.h:67
std::vector< dof_id_type > _end_df
Last DOF index (plus 1) on processor p.
Definition: dof_map_base.h:159
bool local_index(dof_id_type dof_index) const
Definition: dof_map.h:967
const FEType & type() const
Definition: variable.h:144
NodeConstraints _node_constraints
Data structure containing DofObject constraints.
Definition: dof_map.h:2285
void enforce_constraints_exactly(const System &system, NumericVector< Number > *v=nullptr, bool homogeneous=false) const
Constrains the numeric vector v, which represents a solution defined on the mesh. ...
Definition: dof_map.h:2518
This class defines a coupling matrix.
void constrain_element_matrix(DenseMatrix< Number > &matrix, std::vector< dof_id_type > &elem_dofs, bool asymmetric_constraint_rows=true) const
Constrains the element matrix.
Definition: dof_map.h:2485
void enforce_constraints_on_jacobian(const NonlinearImplicitSystem &system, SparseMatrix< Number > *jac) const
Definition: dof_map.h:2533