libMesh
Classes | Public Member Functions | Static Public Member Functions | Public Attributes | Protected Types | Protected Member Functions | Protected Attributes | Static Protected Attributes | Private Types | Private Member Functions | Static Private Member Functions | Private Attributes | Friends | List of all members
libMesh::DofMap Class Reference

This class handles the numbering of degrees of freedom on a mesh. More...

#include <dof_map.h>

Inheritance diagram for libMesh::DofMap:
[legend]

Classes

class  AugmentSendList
 Abstract base class to be used to add user-defined parallel degree of freedom couplings. More...
 
class  AugmentSparsityPattern
 Abstract base class to be used to add user-defined implicit degree of freedom couplings. More...
 

Public Member Functions

 DofMap (const unsigned int sys_number, MeshBase &mesh)
 Constructor. More...
 
 ~DofMap ()
 Destructor. More...
 
void attach_matrix (SparseMatrix< Number > &matrix)
 Additional matrices may be handled with this DofMap. More...
 
bool is_attached (SparseMatrix< Number > &matrix)
 Matrices should not be attached more than once. More...
 
void distribute_dofs (MeshBase &)
 Distribute dofs on the current mesh. More...
 
void compute_sparsity (const MeshBase &)
 Computes the sparsity pattern for the matrices corresponding to proc_id and sends that data to Linear Algebra packages for preallocation of sparse matrices. More...
 
void clear_sparsity ()
 Clears the sparsity pattern. More...
 
void remove_default_ghosting ()
 Remove any default ghosting functor(s). More...
 
void add_default_ghosting ()
 Add the default functor(s) for coupling and algebraic ghosting. More...
 
void add_coupling_functor (GhostingFunctor &coupling_functor, bool to_mesh=true)
 Adds a functor which can specify coupling requirements for creation of sparse matrices. More...
 
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. More...
 
void remove_coupling_functor (GhostingFunctor &coupling_functor)
 Removes a functor which was previously added to the set of coupling functors, from both this DofMap and from the underlying mesh. More...
 
std::set< GhostingFunctor * >::const_iterator coupling_functors_begin () const
 Beginning of range of coupling functors. More...
 
std::set< GhostingFunctor * >::const_iterator coupling_functors_end () const
 End of range of coupling functors. More...
 
DefaultCouplingdefault_coupling ()
 Default coupling functor. More...
 
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. More...
 
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. More...
 
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. More...
 
std::set< GhostingFunctor * >::const_iterator algebraic_ghosting_functors_begin () const
 Beginning of range of algebraic ghosting functors. More...
 
std::set< GhostingFunctor * >::const_iterator algebraic_ghosting_functors_end () const
 End of range of algebraic ghosting functors. More...
 
DefaultCouplingdefault_algebraic_ghosting ()
 Default algebraic ghosting functor. More...
 
void attach_extra_sparsity_object (DofMap::AugmentSparsityPattern &asp)
 Attach an object to use to populate the sparsity pattern with extra entries. More...
 
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. More...
 
void attach_extra_send_list_object (DofMap::AugmentSendList &asl)
 Attach an object to populate the send_list with extra entries. More...
 
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. More...
 
void prepare_send_list ()
 Takes the _send_list vector (which may have duplicate entries) and sorts it. More...
 
void clear_send_list ()
 Clears the _send_list vector. More...
 
void reinit_send_list (MeshBase &mesh)
 Clears the _send_list vector and then rebuilds it. More...
 
const std::vector< dof_id_type > & get_send_list () const
 
const std::vector< dof_id_type > & get_n_nz () const
 
const std::vector< dof_id_type > & get_n_oz () const
 
void add_variable_group (const VariableGroup &var_group)
 
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. More...
 
void set_error_on_constraint_loop (bool error_on_constraint_loop)
 
const VariableGroupvariable_group (const unsigned int c) const
 
const Variablevariable (const unsigned int c) const
 
Order variable_order (const unsigned int c) const
 
Order variable_group_order (const unsigned int vg) const
 
const FETypevariable_type (const unsigned int c) const
 
const FETypevariable_group_type (const unsigned int vg) const
 
unsigned int n_variable_groups () const
 
unsigned int n_variables () const
 
bool has_blocked_representation () const
 
unsigned int block_size () const
 
dof_id_type n_dofs () const
 
dof_id_type n_SCALAR_dofs () const
 
dof_id_type n_local_dofs () const
 
dof_id_type n_dofs_on_processor (const processor_id_type proc) const
 
dof_id_type first_dof (const processor_id_type proc) const
 
dof_id_type first_dof () const
 
dof_id_type first_old_dof (const processor_id_type proc) const
 
dof_id_type first_old_dof () const
 
dof_id_type last_dof (const processor_id_type proc) const
 
dof_id_type last_dof () const
 
dof_id_type end_dof (const processor_id_type proc) const
 
dof_id_type end_dof () const
 
processor_id_type dof_owner (const dof_id_type dof) const
 
dof_id_type end_old_dof (const processor_id_type proc) const
 
dof_id_type end_old_dof () const
 
void dof_indices (const Elem *const elem, std::vector< dof_id_type > &di) const
 Fills the vector di with the global degree of freedom indices for the element. More...
 
void 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. More...
 
void dof_indices (const Node *const node, std::vector< dof_id_type > &di) const
 Fills the vector di with the global degree of freedom indices for the node. More...
 
void dof_indices (const Node *const node, std::vector< dof_id_type > &di, const unsigned int vn) const
 Fills the vector di with the global degree of freedom indices for the node, for one variable vn. More...
 
void 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 global degree of freedom indices for elem.node_ref(n), for one variable vn. More...
 
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. More...
 
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. More...
 
bool semilocal_index (dof_id_type dof_index) const
 
bool all_semilocal_indices (const std::vector< dof_id_type > &dof_indices) const
 
bool local_index (dof_id_type dof_index) const
 
template<typename DofObjectSubclass >
bool is_evaluable (const DofObjectSubclass &obj, unsigned int var_num=libMesh::invalid_uint) const
 
void set_implicit_neighbor_dofs (bool implicit_neighbor_dofs)
 Allow the implicit_neighbor_dofs flag to be set programmatically. More...
 
bool use_coupled_neighbor_dofs (const MeshBase &mesh) const
 Tells other library functions whether or not this problem includes coupling between dofs in neighboring cells, as can currently be specified on the command line or inferred from the use of all discontinuous variables. More...
 
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 of freedom. More...
 
void local_variable_indices (std::vector< dof_id_type > &idx, const MeshBase &mesh, unsigned int var_num) const
 Fills an array of those dof indices which belong to the given variable number and live on the current processor. More...
 
dof_id_type n_constrained_dofs () const
 
dof_id_type n_local_constrained_dofs () const
 
dof_id_type n_constrained_nodes () const
 
void create_dof_constraints (const MeshBase &, Real time=0)
 Rebuilds the raw degree of freedom and DofObject constraints. More...
 
void allgather_recursive_constraints (MeshBase &)
 Gathers constraint equation dependencies from other processors. More...
 
void scatter_constraints (MeshBase &)
 Sends constraint equations to constraining processors. More...
 
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. More...
 
void process_constraints (MeshBase &)
 Postprocesses any constrained degrees of freedom to be constrained only in terms of unconstrained dofs, then adds unconstrained dofs to the send_list and prepares that for use. More...
 
void check_for_cyclic_constraints ()
 Throw an error if we detect any constraint loops, i.e. More...
 
void check_for_constraint_loops ()
 
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 for the constraint equation. More...
 
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 for the adjoint constraint equation. More...
 
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 the constraint equation. More...
 
DofConstraints::const_iterator constraint_rows_begin () const
 
DofConstraints::const_iterator constraint_rows_end () const
 
void stash_dof_constraints ()
 
void unstash_dof_constraints ()
 
void swap_dof_constraints ()
 Similar to the stash/unstash_dof_constraints() API, but swaps _dof_constraints and _stashed_dof_constraints without asserting that the source or destination is empty first. More...
 
NodeConstraints::const_iterator node_constraint_rows_begin () const
 
NodeConstraints::const_iterator node_constraint_rows_end () const
 
bool is_constrained_dof (const dof_id_type dof) const
 
bool has_heterogenous_adjoint_constraints (const unsigned int qoi_num) const
 
Number has_heterogenous_adjoint_constraint (const unsigned int qoi_num, const dof_id_type dof) const
 
DofConstraintValueMapget_primal_constraint_values ()
 
bool is_constrained_node (const Node *node) const
 
void print_dof_constraints (std::ostream &os=libMesh::out, bool print_nonlocal=false) const
 Prints (from processor 0) all DoF and Node constraints. More...
 
std::string get_local_constraints (bool print_nonlocal=false) const
 Gets a string reporting all DoF and Node constraints local to this processor. More...
 
std::pair< Real, Realmax_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 on the mesh, returning a pair whose first entry is the maximum absolute error on a constrained DoF and whose second entry is the maximum relative error. More...
 
void constrain_element_matrix (DenseMatrix< Number > &matrix, std::vector< dof_id_type > &elem_dofs, bool asymmetric_constraint_rows=true) const
 Constrains the element matrix. More...
 
void constrain_element_matrix (DenseMatrix< Number > &matrix, std::vector< dof_id_type > &row_dofs, std::vector< dof_id_type > &col_dofs, bool asymmetric_constraint_rows=true) const
 Constrains the element matrix. More...
 
void constrain_element_vector (DenseVector< Number > &rhs, std::vector< dof_id_type > &dofs, bool asymmetric_constraint_rows=true) const
 Constrains the element vector. More...
 
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. More...
 
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
 Constrains the element matrix and vector. More...
 
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
 Constrains the element vector. More...
 
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'. More...
 
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 functions would do, i.e. More...
 
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. More...
 
void enforce_adjoint_constraints_exactly (NumericVector< Number > &v, unsigned int q) const
 Heterogenously constrains the numeric vector v, which represents an adjoint solution defined on the mesh for quantity fo interest q. More...
 
void enforce_constraints_on_residual (const NonlinearImplicitSystem &system, NumericVector< Number > *rhs, NumericVector< Number > const *solution, bool homogeneous=true) const
 
void enforce_constraints_on_jacobian (const NonlinearImplicitSystem &system, SparseMatrix< Number > *jac) const
 
void add_periodic_boundary (const PeriodicBoundaryBase &periodic_boundary)
 Adds a copy of the specified periodic boundary to the system. More...
 
void add_periodic_boundary (const PeriodicBoundaryBase &boundary, const PeriodicBoundaryBase &inverse_boundary)
 Add a periodic boundary pair. More...
 
bool is_periodic_boundary (const boundary_id_type boundaryid) const
 
PeriodicBoundariesget_periodic_boundaries ()
 
void add_dirichlet_boundary (const DirichletBoundary &dirichlet_boundary)
 Adds a copy of the specified Dirichlet boundary to the system. More...
 
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 defined by Quantity of Interest q. More...
 
void remove_dirichlet_boundary (const DirichletBoundary &dirichlet_boundary)
 Removes the specified Dirichlet boundary from the system. More...
 
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 of interest index q. More...
 
const DirichletBoundariesget_dirichlet_boundaries () const
 
DirichletBoundariesget_dirichlet_boundaries ()
 
bool has_adjoint_dirichlet_boundaries (unsigned int q) const
 
const DirichletBoundariesget_adjoint_dirichlet_boundaries (unsigned int q) const
 
DirichletBoundariesget_adjoint_dirichlet_boundaries (unsigned int q)
 
void old_dof_indices (const Elem *const elem, std::vector< dof_id_type > &di, const unsigned int vn=libMesh::invalid_uint) const
 After a mesh is refined and repartitioned it is possible that the _send_list will need to be augmented. More...
 
dof_id_type n_old_dofs () const
 
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 to p refinement levels above p. More...
 
void reinit (MeshBase &mesh)
 Reinitialize the underlying data structures conformal to the current mesh. More...
 
void clear ()
 Free all new memory associated with the object, but restore its original state, with the mesh pointer and any default ghosting. More...
 
void print_info (std::ostream &os=libMesh::out) const
 Prints summary info about the sparsity bandwidth and constraints. More...
 
std::string get_info () const
 Gets summary info about the sparsity bandwidth and constraints. More...
 
unsigned int sys_number () const
 
const Parallel::Communicator & comm () const
 
processor_id_type n_processors () const
 
processor_id_type processor_id () const
 

Static Public Member Functions

static std::string get_info ()
 Gets a string containing the reference information. More...
 
static void print_info (std::ostream &out=libMesh::out)
 Prints the reference information, by default to libMesh::out. More...
 
static unsigned int n_objects ()
 Prints the number of outstanding (created, but not yet destroyed) objects. More...
 
static void enable_print_counter_info ()
 Methods to enable/disable the reference counter output from print_info() More...
 
static void disable_print_counter_info ()
 

Public Attributes

CouplingMatrix_dof_coupling
 Degree of freedom coupling. More...
 

Protected Types

typedef std::map< std::string, std::pair< unsigned int, unsigned int > > Counts
 Data structure to log the information. More...
 

Protected Member Functions

void increment_constructor_count (const std::string &name)
 Increments the construction counter. More...
 
void increment_destructor_count (const std::string &name)
 Increments the destruction counter. More...
 

Protected Attributes

const Parallel::Communicator & _communicator
 

Static Protected Attributes

static Counts _counts
 Actually holds the data. More...
 
static Threads::atomic< unsigned int_n_objects
 The number of objects. More...
 
static Threads::spin_mutex _mutex
 Mutual exclusion object to enable thread-safe reference counting. More...
 
static bool _enable_print_counter = true
 Flag to control whether reference count information is printed when print_info is called. More...
 

Private Types

typedef DofObject *(DofMap::* dofobject_accessor) (MeshBase &mesh, dof_id_type i) const
 A member function type like node_ptr() or elem_ptr(). More...
 

Private Member Functions

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 #ifdef DEBUG, const unsigned int v, std::size_t &tot_size #endif) const
 Helper function that gets the dof indices on the current element for a non-SCALAR type variable, where the variable is identified by its variable group number vg and its offset vig from the first variable in that group. More...
 
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. More...
 
std::unique_ptr< SparsityPattern::Buildbuild_sparsity (const MeshBase &mesh) const
 Builds a sparsity pattern. More...
 
void invalidate_dofs (MeshBase &mesh) const
 Invalidates all active DofObject dofs for this system. More...
 
DofObjectnode_ptr (MeshBase &mesh, dof_id_type i) const
 
DofObjectelem_ptr (MeshBase &mesh, dof_id_type i) const
 
template<typename iterator_type >
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. More...
 
void distribute_local_dofs_var_major (dof_id_type &next_free_dof, MeshBase &mesh)
 Distributes the global degrees of freedom, for dofs on this processor. More...
 
void distribute_local_dofs_node_major (dof_id_type &next_free_dof, MeshBase &mesh)
 Distributes the global degrees of freedom for dofs on this processor. More...
 
void add_neighbors_to_send_list (MeshBase &mesh)
 Adds entries to the _send_list vector corresponding to DoFs on elements neighboring the current processor. More...
 
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. More...
 
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 indices elem_dofs. More...
 
void find_connected_dofs (std::vector< dof_id_type > &elem_dofs) const
 Finds all the DOFS associated with the element DOFs elem_dofs. More...
 
void find_connected_dof_objects (std::vector< const DofObject * > &objs) const
 Finds all the DofObjects associated with the set in objs. More...
 
void add_constraints_to_send_list ()
 Adds entries to the _send_list vector corresponding to DoFs which are dependencies for constraint equations on the current processor. More...
 
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. More...
 

Static Private Member Functions

static void merge_ghost_functor_outputs (GhostingFunctor::map_type &elements_to_ghost, std::set< CouplingMatrix * > &temporary_coupling_matrices, const std::set< GhostingFunctor * >::iterator &gf_begin, const std::set< GhostingFunctor * >::iterator &gf_end, const MeshBase::const_element_iterator &elems_begin, const MeshBase::const_element_iterator &elems_end, processor_id_type p)
 

Private Attributes

bool _error_on_constraint_loop
 This flag indicates whether or not we do an opt-mode check for the presence of constraint loops, i.e. More...
 
std::vector< Variable_variables
 The finite element type for each variable. More...
 
std::vector< VariableGroup_variable_groups
 The finite element type for each variable group. More...
 
std::vector< unsigned int_variable_group_numbers
 The variable group number for each variable. More...
 
const unsigned int _sys_number
 The number of the system we manage DOFs for. More...
 
MeshBase_mesh
 The mesh that system uses. More...
 
std::vector< SparseMatrix< Number > * > _matrices
 Additional matrices handled by this object. More...
 
std::vector< dof_id_type_first_df
 First DOF index on processor p. More...
 
std::vector< dof_id_type_end_df
 Last DOF index (plus 1) on processor p. More...
 
std::vector< dof_id_type_first_scalar_df
 First DOF index for SCALAR variable v, or garbage for non-SCALAR variable v. More...
 
std::vector< dof_id_type_send_list
 A list containing all the global DOF indices that affect the solution on my processor. More...
 
AugmentSparsityPattern_augment_sparsity_pattern
 Function object to call to add extra entries to the sparsity pattern. More...
 
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. More...
 
void * _extra_sparsity_context
 A pointer associated with the extra sparsity that can optionally be passed in. More...
 
AugmentSendList_augment_send_list
 Function object to call to add extra entries to the send list. More...
 
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. More...
 
void * _extra_send_list_context
 A pointer associated with the extra send list that can optionally be passed in. More...
 
std::unique_ptr< DefaultCoupling_default_coupling
 The default coupling GhostingFunctor, used to implement standard libMesh sparsity pattern construction. More...
 
std::unique_ptr< DefaultCoupling_default_evaluating
 The default algebraic GhostingFunctor, used to implement standard libMesh send_list construction. More...
 
std::set< GhostingFunctor * > _algebraic_ghosting_functors
 The list of all GhostingFunctor objects to be used when distributing ghosted vectors. More...
 
std::set< GhostingFunctor * > _coupling_functors
 The list of all GhostingFunctor objects to be used when coupling degrees of freedom in matrix sparsity patterns. More...
 
std::map< GhostingFunctor *, std::shared_ptr< GhostingFunctor > > _shared_functors
 Hang on to references to any GhostingFunctor objects we were passed in shared_ptr form. More...
 
bool need_full_sparsity_pattern
 Default false; set to true if any attached matrix requires a full sparsity pattern. More...
 
std::unique_ptr< SparsityPattern::Build_sp
 The sparsity pattern of the global matrix, kept around if it might be needed by future additions of the same type of matrix. More...
 
std::vector< dof_id_type > * _n_nz
 The number of on-processor nonzeros in my portion of the global matrix. More...
 
std::vector< dof_id_type > * _n_oz
 The number of off-processor nonzeros in my portion of the global matrix; allocated similar to _n_nz. More...
 
dof_id_type _n_dfs
 Total number of degrees of freedom. More...
 
dof_id_type _n_SCALAR_dofs
 The total number of SCALAR dofs associated to all SCALAR variables. More...
 
dof_id_type _n_old_dfs
 Total number of degrees of freedom on old dof objects. More...
 
std::vector< dof_id_type_first_old_df
 First old DOF index on processor p. More...
 
std::vector< dof_id_type_end_old_df
 Last old DOF index (plus 1) on processor p. More...
 
std::vector< dof_id_type_first_old_scalar_df
 First old DOF index for SCALAR variable v, or garbage for non-SCALAR variable v. More...
 
DofConstraints _dof_constraints
 Data structure containing DOF constraints. More...
 
DofConstraints _stashed_dof_constraints
 
DofConstraintValueMap _primal_constraint_values
 
AdjointDofConstraintValues _adjoint_constraint_values
 
NodeConstraints _node_constraints
 Data structure containing DofObject constraints. More...
 
std::unique_ptr< PeriodicBoundaries_periodic_boundaries
 Data structure containing periodic boundaries. More...
 
std::unique_ptr< DirichletBoundaries_dirichlet_boundaries
 Data structure containing Dirichlet functions. More...
 
std::vector< DirichletBoundaries * > _adjoint_dirichlet_boundaries
 Data structure containing Dirichlet functions. More...
 
bool _implicit_neighbor_dofs_initialized
 Bools to indicate if we override the –implicit_neighbor_dofs commandline options. More...
 
bool _implicit_neighbor_dofs
 

Friends

class SparsityPattern::Build
 

Detailed Description

This class handles the numbering of degrees of freedom on a mesh.

For systems of equations the class supports a fixed number of variables. The degrees of freedom are numbered such that sequential, contiguous blocks belong to distinct processors. This is so that the resulting data structures will work well with parallel linear algebra packages.

Author
Benjamin S. Kirk
Date
2002-2007

Manages the degrees of freedom (DOFs) in a simulation.

Definition at line 176 of file dof_map.h.

Member Typedef Documentation

◆ Counts

typedef std::map<std::string, std::pair<unsigned int, unsigned int> > libMesh::ReferenceCounter::Counts
protectedinherited

Data structure to log the information.

The log is identified by the class name.

Definition at line 117 of file reference_counter.h.

◆ dofobject_accessor

typedef DofObject*(DofMap::* libMesh::DofMap::dofobject_accessor) (MeshBase &mesh, dof_id_type i) const
private

A member function type like node_ptr() or elem_ptr().

Definition at line 1501 of file dof_map.h.

Constructor & Destructor Documentation

◆ DofMap()

libMesh::DofMap::DofMap ( const unsigned int  sys_number,
MeshBase mesh 
)
explicit

Constructor.

Requires the number of the system for which we will be numbering degrees of freedom & the parent object we are contained in, which defines our communication space.

Definition at line 135 of file dof_map.C.

136  :
137  ParallelObject (mesh.comm()),
138  _dof_coupling(nullptr),
140  _variables(),
143  _sys_number(number),
144  _mesh(mesh),
145  _matrices(),
146  _first_df(),
147  _end_df(),
149  _send_list(),
150  _augment_sparsity_pattern(nullptr),
151  _extra_sparsity_function(nullptr),
152  _extra_sparsity_context(nullptr),
153  _augment_send_list(nullptr),
154  _extra_send_list_function(nullptr),
155  _extra_send_list_context(nullptr),
156  _default_coupling(libmesh_make_unique<DefaultCoupling>()),
157  _default_evaluating(libmesh_make_unique<DefaultCoupling>()),
159  _n_nz(nullptr),
160  _n_oz(nullptr),
161  _n_dfs(0),
162  _n_SCALAR_dofs(0)
163 #ifdef LIBMESH_ENABLE_AMR
164  , _n_old_dfs(0),
165  _first_old_df(),
166  _end_old_df(),
168 #endif
169 #ifdef LIBMESH_ENABLE_CONSTRAINTS
170  , _dof_constraints()
174 #endif
175 #ifdef LIBMESH_ENABLE_NODE_CONSTRAINTS
177 #endif
178 #ifdef LIBMESH_ENABLE_PERIODIC
179  , _periodic_boundaries(libmesh_make_unique<PeriodicBoundaries>())
180 #endif
181 #ifdef LIBMESH_ENABLE_DIRICHLET
182  , _dirichlet_boundaries(libmesh_make_unique<DirichletBoundaries>())
184 #endif
187 {
188  _matrices.clear();
189 
190  _default_coupling->set_mesh(&_mesh);
191  _default_evaluating->set_mesh(&_mesh);
192  _default_evaluating->set_n_levels(1);
193 
194 #ifdef LIBMESH_ENABLE_PERIODIC
195  _default_coupling->set_periodic_boundaries(_periodic_boundaries.get());
196  _default_evaluating->set_periodic_boundaries(_periodic_boundaries.get());
197 #endif
198 
201 }

References _default_coupling, _default_evaluating, _matrices, _mesh, _periodic_boundaries, add_algebraic_ghosting_functor(), and add_coupling_functor().

◆ ~DofMap()

libMesh::DofMap::~DofMap ( )

Destructor.

Definition at line 206 of file dof_map.C.

207 {
208  this->clear();
209 
210  // clear() resets all but the default DofMap-based functors. We
211  // need to remove those from the mesh too before we die.
214 
215 #ifdef LIBMESH_ENABLE_DIRICHLET
216  for (auto & bnd : _adjoint_dirichlet_boundaries)
217  delete bnd;
218 #endif
219 }

References _adjoint_dirichlet_boundaries, _default_coupling, _default_evaluating, _mesh, clear(), and libMesh::MeshBase::remove_ghosting_functor().

Member Function Documentation

◆ _dof_indices()

void libMesh::DofMap::_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 #ifdef  DEBUG,
const unsigned int  v,
std::size_t &tot_size #  endif 
) const
private

Helper function that gets the dof indices on the current element for a non-SCALAR type variable, where the variable is identified by its variable group number vg and its offset vig from the first variable in that group.

In DEBUG mode, the tot_size parameter will add up the total number of dof indices that should have been added to di, and v will be the variable number corresponding to vg and vig.

Definition at line 2349 of file dof_map.C.

2362 {
2363  const VariableGroup & var = this->variable_group(vg);
2364 
2365  if (var.active_on_subdomain(elem.subdomain_id()))
2366  {
2367  const ElemType type = elem.type();
2368  const unsigned int sys_num = this->sys_number();
2369  const unsigned int dim = elem.dim();
2370 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
2371  const bool is_inf = elem.infinite();
2372 #endif
2373 
2374  // Increase the polynomial order on p refined elements
2375  FEType fe_type = var.type();
2376  fe_type.order = static_cast<Order>(fe_type.order + p_level);
2377 
2378  const bool extra_hanging_dofs =
2380 
2381 #ifdef DEBUG
2382  // The number of dofs per element is non-static for subdivision FE
2383  if (fe_type.family == SUBDIVISION)
2384  tot_size += n_nodes;
2385  else
2386  tot_size += FEInterface::n_dofs(dim,fe_type,type);
2387 #endif
2388 
2389  const FEInterface::n_dofs_at_node_ptr ndan =
2391 
2392  // Get the node-based DOF numbers
2393  for (unsigned int n=0; n != n_nodes; n++)
2394  {
2395  const Node & node = *nodes[n];
2396 
2397  // Cache the intermediate lookups that are common to every
2398  // component
2399 #ifdef DEBUG
2400  const std::pair<unsigned int, unsigned int>
2401  vg_and_offset = node.var_to_vg_and_offset(sys_num,v);
2402  libmesh_assert_equal_to (vg, vg_and_offset.first);
2403  libmesh_assert_equal_to (vig, vg_and_offset.second);
2404 #endif
2405  const unsigned int n_comp = node.n_comp_group(sys_num,vg);
2406 
2407  // There is a potential problem with h refinement. Imagine a
2408  // quad9 that has a linear FE on it. Then, on the hanging side,
2409  // it can falsely identify a DOF at the mid-edge node. This is why
2410  // we go through FEInterface instead of node.n_comp() directly.
2411  const unsigned int nc =
2412 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
2413  is_inf ?
2414  FEInterface::n_dofs_at_node(dim, fe_type, type, n) :
2415 #endif
2416  ndan (type, fe_type.order, n);
2417 
2418  // If this is a non-vertex on a hanging node with extra
2419  // degrees of freedom, we use the non-vertex dofs (which
2420  // come in reverse order starting from the end, to
2421  // simplify p refinement)
2422  if (extra_hanging_dofs && !elem.is_vertex(n))
2423  {
2424  const int dof_offset = n_comp - nc;
2425 
2426  // We should never have fewer dofs than necessary on a
2427  // node unless we're getting indices on a parent element,
2428  // and we should never need the indices on such a node
2429  if (dof_offset < 0)
2430  {
2431  libmesh_assert(!elem.active());
2432  di.resize(di.size() + nc, DofObject::invalid_id);
2433  }
2434  else
2435  for (int i=n_comp-1; i>=dof_offset; i--)
2436  {
2437  const dof_id_type d =
2438  node.dof_number(sys_num, vg, vig, i, n_comp);
2439  libmesh_assert_not_equal_to (d, DofObject::invalid_id);
2440  di.push_back(d);
2441  }
2442  }
2443  // If this is a vertex or an element without extra hanging
2444  // dofs, our dofs come in forward order coming from the
2445  // beginning
2446  else
2447  for (unsigned int i=0; i<nc; i++)
2448  {
2449  const dof_id_type d =
2450  node.dof_number(sys_num, vg, vig, i, n_comp);
2451  libmesh_assert_not_equal_to (d, DofObject::invalid_id);
2452  di.push_back(d);
2453  }
2454  }
2455 
2456  // If there are any element-based DOF numbers, get them
2457  const unsigned int nc = FEInterface::n_dofs_per_elem(dim,
2458  fe_type,
2459  type);
2460  // We should never have fewer dofs than necessary on an
2461  // element unless we're getting indices on a parent element,
2462  // and we should never need those indices
2463  if (nc != 0)
2464  {
2465  const unsigned int n_comp = elem.n_comp_group(sys_num,vg);
2466  if (elem.n_systems() > sys_num && nc <= n_comp)
2467  {
2468  for (unsigned int i=0; i<nc; i++)
2469  {
2470  const dof_id_type d =
2471  elem.dof_number(sys_num, vg, vig, i, n_comp);
2472  libmesh_assert_not_equal_to (d, DofObject::invalid_id);
2473 
2474  di.push_back(d);
2475  }
2476  }
2477  else
2478  {
2479  libmesh_assert(!elem.active() || fe_type.family == LAGRANGE || fe_type.family == SUBDIVISION);
2480  di.resize(di.size() + nc, DofObject::invalid_id);
2481  }
2482  }
2483  }
2484 }

References libMesh::Elem::active(), libMesh::Variable::active_on_subdomain(), dim, libMesh::Elem::dim(), libMesh::DofObject::dof_number(), libMesh::FEInterface::extra_hanging_dofs(), libMesh::FEType::family, libMesh::Elem::infinite(), libMesh::DofObject::invalid_id, libMesh::Elem::is_vertex(), libMesh::LAGRANGE, libMesh::libmesh_assert(), libMesh::DofObject::n_comp_group(), libMesh::FEInterface::n_dofs(), libMesh::FEInterface::n_dofs_at_node(), libMesh::FEInterface::n_dofs_at_node_function(), libMesh::FEInterface::n_dofs_per_elem(), n_nodes, libMesh::DofObject::n_systems(), libMesh::FEType::order, libMesh::SUBDIVISION, libMesh::Elem::subdomain_id(), sys_number(), libMesh::Variable::type(), libMesh::Elem::type(), libMesh::DofObject::var_to_vg_and_offset(), and variable_group().

Referenced by dof_indices().

◆ _node_dof_indices()

void libMesh::DofMap::_node_dof_indices ( const Elem elem,
unsigned int  n,
const DofObject obj,
std::vector< dof_id_type > &  di,
const unsigned int  vn 
) const
private

Helper function that implements the element-nodal versions of dof_indices and old_dof_indices.

Definition at line 2272 of file dof_map.C.

2277 {
2278  // Half of this is a cut and paste of _dof_indices code below, but
2279  // duplication actually seems cleaner than creating a helper
2280  // function with a million arguments and hoping the compiler inlines
2281  // it properly into one of our most highly trafficked functions.
2282 
2283  LOG_SCOPE("_node_dof_indices()", "DofMap");
2284 
2285  const ElemType type = elem.type();
2286  const unsigned int dim = elem.dim();
2287 
2288  const unsigned int sys_num = this->sys_number();
2289  const std::pair<unsigned int, unsigned int>
2290  vg_and_offset = obj.var_to_vg_and_offset(sys_num,vn);
2291  const unsigned int vg = vg_and_offset.first;
2292  const unsigned int vig = vg_and_offset.second;
2293  const unsigned int n_comp = obj.n_comp_group(sys_num,vg);
2294 
2295  const VariableGroup & var = this->variable_group(vg);
2296  FEType fe_type = var.type();
2297  fe_type.order = static_cast<Order>(fe_type.order +
2298  elem.p_level());
2299  const bool extra_hanging_dofs =
2301 
2302  // There is a potential problem with h refinement. Imagine a
2303  // quad9 that has a linear FE on it. Then, on the hanging side,
2304  // it can falsely identify a DOF at the mid-edge node. This is why
2305  // we go through FEInterface instead of obj->n_comp() directly.
2306  const unsigned int nc =
2307  FEInterface::n_dofs_at_node(dim, fe_type, type, n);
2308 
2309  // If this is a non-vertex on a hanging node with extra
2310  // degrees of freedom, we use the non-vertex dofs (which
2311  // come in reverse order starting from the end, to
2312  // simplify p refinement)
2313  if (extra_hanging_dofs && nc && !elem.is_vertex(n))
2314  {
2315  const int dof_offset = n_comp - nc;
2316 
2317  // We should never have fewer dofs than necessary on a
2318  // node unless we're getting indices on a parent element,
2319  // and we should never need the indices on such a node
2320  if (dof_offset < 0)
2321  {
2322  libmesh_assert(!elem.active());
2323  di.resize(di.size() + nc, DofObject::invalid_id);
2324  }
2325  else
2326  for (unsigned int i = dof_offset; i != n_comp; ++i)
2327  {
2328  const dof_id_type d =
2329  obj.dof_number(sys_num, vg, vig, i, n_comp);
2330  libmesh_assert_not_equal_to (d, DofObject::invalid_id);
2331  di.push_back(d);
2332  }
2333  }
2334  // If this is a vertex or an element without extra hanging
2335  // dofs, our dofs come in forward order coming from the
2336  // beginning
2337  else
2338  for (unsigned int i=0; i<nc; i++)
2339  {
2340  const dof_id_type d =
2341  obj.dof_number(sys_num, vg, vig, i, n_comp);
2342  libmesh_assert_not_equal_to (d, DofObject::invalid_id);
2343  di.push_back(d);
2344  }
2345 }

References libMesh::Elem::active(), dim, libMesh::Elem::dim(), libMesh::DofObject::dof_number(), libMesh::FEInterface::extra_hanging_dofs(), libMesh::DofObject::invalid_id, libMesh::Elem::is_vertex(), libMesh::libmesh_assert(), libMesh::DofObject::n_comp_group(), libMesh::FEInterface::n_dofs_at_node(), libMesh::FEType::order, libMesh::Elem::p_level(), sys_number(), libMesh::Variable::type(), libMesh::Elem::type(), libMesh::DofObject::var_to_vg_and_offset(), and variable_group().

Referenced by dof_indices(), and old_dof_indices().

◆ add_adjoint_constraint_row()

void libMesh::DofMap::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 for the adjoint constraint equation.

forbid_constraint_overwrite here only tests for overwriting the rhs. This method should only be used when an equivalent constraint (with a potentially different rhs) already exists for the primal problem.

Definition at line 1393 of file dof_map_constraints.C.

1398 {
1399  // Optionally allow the user to overwrite constraints. Defaults to false.
1400  if (forbid_constraint_overwrite)
1401  {
1402  if (!this->is_constrained_dof(dof_number))
1403  libmesh_error_msg("ERROR: DOF " << dof_number << " has no corresponding primal constraint!");
1404 #ifndef NDEBUG
1405  // No way to do this without a non-normalized tolerance?
1406 
1407  // // If the user passed in more than just the rhs, let's check the
1408  // // coefficients for consistency
1409  // if (!constraint_row.empty())
1410  // {
1411  // DofConstraintRow row = _dof_constraints[dof_number];
1412  // for (const auto & pr : row)
1413  // libmesh_assert(constraint_row.find(pr.first)->second == pr.second);
1414  // }
1415  //
1416  // if (_adjoint_constraint_values[qoi_index].find(dof_number) !=
1417  // _adjoint_constraint_values[qoi_index].end())
1418  // libmesh_assert_equal_to(_adjoint_constraint_values[qoi_index][dof_number],
1419  // constraint_rhs);
1420 
1421 #endif
1422  }
1423 
1424  // Creates the map of rhs values if it doesn't already exist; then
1425  // adds the current value to that map
1426 
1427  // We don't get insert_or_assign until C++17 so we make do.
1428  std::pair<DofConstraintValueMap::iterator, bool> rhs_it =
1429  _adjoint_constraint_values[qoi_index].insert(std::make_pair(dof_number,
1430  constraint_rhs));
1431  if (!rhs_it.second)
1432  rhs_it.first->second = constraint_rhs;
1433 }

References _adjoint_constraint_values, and is_constrained_dof().

◆ add_adjoint_dirichlet_boundary()

void libMesh::DofMap::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 defined by Quantity of Interest q.

Definition at line 4396 of file dof_map_constraints.C.

4398 {
4399  unsigned int old_size = cast_int<unsigned int>
4401  for (unsigned int i = old_size; i <= qoi_index; ++i)
4403 
4404  _adjoint_dirichlet_boundaries[qoi_index]->push_back
4405  (new DirichletBoundary(dirichlet_boundary));
4406 }

References _adjoint_dirichlet_boundaries.

◆ add_algebraic_ghosting_functor() [1/2]

void libMesh::DofMap::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.

Degrees of freedom on other processors which match the elements and variables returned by these functors will be added to the send_list, and the elements on other processors will be ghosted on a distributed mesh, so that the elements can always be found and the solutions on them will always be evaluable.

GhostingFunctor memory must be managed by the code which calls this function; the GhostingFunctor lifetime is expected to extend until either the functor is removed or the DofMap is destructed.

When to_mesh is true, the coupling_functor is also added to our associated mesh, to ensure that evaluable elements do not get lost during mesh distribution. (if evaluable elements were already lost there's no getting them back after the fact, sorry)

If to_mesh is false, no change to mesh ghosting is made; the Mesh must already have ghosting functor(s) specifying a superset of evaluable_functor or this is a horrible bug.

Definition at line 1862 of file dof_map.C.

1864 {
1865  _algebraic_ghosting_functors.insert(&evaluable_functor);
1866  if (to_mesh)
1867  _mesh.add_ghosting_functor(evaluable_functor);
1868 }

References _algebraic_ghosting_functors, _mesh, and libMesh::MeshBase::add_ghosting_functor().

Referenced by add_algebraic_ghosting_functor(), add_default_ghosting(), clear(), DofMap(), main(), OverlappingAlgebraicGhostingTest::run_ghosting_test(), PointNeighborCouplingTest::testCoupling(), and EquationSystemsTest::testDisableDefaultGhosting().

◆ add_algebraic_ghosting_functor() [2/2]

void libMesh::DofMap::add_algebraic_ghosting_functor ( std::shared_ptr< GhostingFunctor evaluable_functor,
bool  to_mesh = true 
)
inline

Adds a functor which can specify algebraic ghosting requirements for use with distributed vectors.

GhostingFunctor memory when using this method is managed by the shared_ptr mechanism.

Definition at line 376 of file dof_map.h.

378  { _shared_functors[evaluable_functor.get()] = evaluable_functor;
379  this->add_algebraic_ghosting_functor(*evaluable_functor, to_mesh); }

References _shared_functors, and add_algebraic_ghosting_functor().

◆ add_constraint_row() [1/2]

void libMesh::DofMap::add_constraint_row ( const dof_id_type  dof_number,
const DofConstraintRow constraint_row,
const bool  forbid_constraint_overwrite = true 
)
inline

Adds a copy of the user-defined row to the constraint matrix, using a homogeneous right-hand-side for the constraint equation.

By default, produces an error if the DOF was already constrained.

Definition at line 981 of file dof_map.h.

984  { add_constraint_row(dof_number, constraint_row, 0., forbid_constraint_overwrite); }

References add_constraint_row().

◆ add_constraint_row() [2/2]

void libMesh::DofMap::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 for the constraint equation.

Definition at line 1364 of file dof_map_constraints.C.

1368 {
1369  // Optionally allow the user to overwrite constraints. Defaults to false.
1370  if (forbid_constraint_overwrite)
1371  if (this->is_constrained_dof(dof_number))
1372  libmesh_error_msg("ERROR: DOF " << dof_number << " was already constrained!");
1373 
1374  libmesh_assert_less(dof_number, this->n_dofs());
1375 #ifndef NDEBUG
1376  for (const auto & pr : constraint_row)
1377  libmesh_assert_less(pr.first, this->n_dofs());
1378 #endif
1379 
1380  // We don't get insert_or_assign until C++17 so we make do.
1381  std::pair<DofConstraints::iterator, bool> it =
1382  _dof_constraints.insert(std::make_pair(dof_number, constraint_row));
1383  if (!it.second)
1384  it.first->second = constraint_row;
1385 
1386  std::pair<DofConstraintValueMap::iterator, bool> rhs_it =
1387  _primal_constraint_values.insert(std::make_pair(dof_number, constraint_rhs));
1388  if (!rhs_it.second)
1389  rhs_it.first->second = constraint_rhs;
1390 }

References _dof_constraints, _primal_constraint_values, is_constrained_dof(), and n_dofs().

Referenced by add_constraint_row(), libMesh::DynaIO::add_spline_constraints(), and MyConstraint::constrain().

◆ add_constraints_to_send_list()

void libMesh::DofMap::add_constraints_to_send_list ( )
private

Adds entries to the _send_list vector corresponding to DoFs which are dependencies for constraint equations on the current processor.

Definition at line 4280 of file dof_map_constraints.C.

4281 {
4282  // This function must be run on all processors at once
4283  parallel_object_only();
4284 
4285  // Return immediately if there's nothing to gather
4286  if (this->n_processors() == 1)
4287  return;
4288 
4289  // We might get to return immediately if none of the processors
4290  // found any constraints
4291  unsigned int has_constraints = !_dof_constraints.empty();
4292  this->comm().max(has_constraints);
4293  if (!has_constraints)
4294  return;
4295 
4296  for (const auto & i : _dof_constraints)
4297  {
4298  dof_id_type constrained_dof = i.first;
4299 
4300  // We only need the dependencies of our own constrained dofs
4301  if (!this->local_index(constrained_dof))
4302  continue;
4303 
4304  const DofConstraintRow & constraint_row = i.second;
4305  for (const auto & j : constraint_row)
4306  {
4307  dof_id_type constraint_dependency = j.first;
4308 
4309  // No point in adding one of our own dofs to the send_list
4310  if (this->local_index(constraint_dependency))
4311  continue;
4312 
4313  _send_list.push_back(constraint_dependency);
4314  }
4315  }
4316 }

References _dof_constraints, _send_list, libMesh::ParallelObject::comm(), local_index(), and libMesh::ParallelObject::n_processors().

Referenced by process_constraints().

◆ add_coupling_functor() [1/2]

void libMesh::DofMap::add_coupling_functor ( GhostingFunctor coupling_functor,
bool  to_mesh = true 
)

Adds a functor which can specify coupling requirements for creation of sparse matrices.

Degree of freedom pairs which match the elements and variables returned by these functors will be added to the sparsity pattern, and the degrees of freedom which live on other processors will be added to the send_list for use on ghosted vectors, and the elements which live on other processors will be ghosted on a distributed mesh.

GhostingFunctor memory must be managed by the code which calls this function; the GhostingFunctor lifetime is expected to extend until either the functor is removed or the DofMap is destructed.

When to_mesh is true, the coupling_functor is also added to our associated mesh, to ensure that coupled elements do not get lost during mesh distribution. (if coupled elements were already lost there's no getting them back after the fact, sorry)

If to_mesh is false, no change to mesh ghosting is made; the Mesh must already have ghosting functor(s) specifying a superset of coupling_functor or this is a horrible bug.

Definition at line 1838 of file dof_map.C.

1840 {
1841  _coupling_functors.insert(&coupling_functor);
1842  if (to_mesh)
1843  _mesh.add_ghosting_functor(coupling_functor);
1844 }

References _coupling_functors, _mesh, and libMesh::MeshBase::add_ghosting_functor().

Referenced by add_coupling_functor(), add_default_ghosting(), clear(), DofMap(), main(), OverlappingCouplingGhostingTest::run_sparsity_pattern_test(), EquationSystemsTest::testDisableDefaultGhosting(), and SystemsTest::testDofCouplingWithVarGroups().

◆ add_coupling_functor() [2/2]

void libMesh::DofMap::add_coupling_functor ( std::shared_ptr< GhostingFunctor coupling_functor,
bool  to_mesh = true 
)
inline

Adds a functor which can specify coupling requirements for creation of sparse matrices.

GhostingFunctor memory when using this method is managed by the shared_ptr mechanism.

Definition at line 314 of file dof_map.h.

316  { _shared_functors[coupling_functor.get()] = coupling_functor;
317  this->add_coupling_functor(*coupling_functor, to_mesh); }

References _shared_functors, and add_coupling_functor().

◆ add_default_ghosting()

void libMesh::DofMap::add_default_ghosting ( )

Add the default functor(s) for coupling and algebraic ghosting.

User-added ghosting functors will be unaffected.

Definition at line 1829 of file dof_map.C.

1830 {
1831  this->add_coupling_functor(this->default_coupling());
1833 }

References add_algebraic_ghosting_functor(), add_coupling_functor(), default_algebraic_ghosting(), and default_coupling().

Referenced by libMesh::EquationSystems::enable_default_ghosting().

◆ add_dirichlet_boundary()

void libMesh::DofMap::add_dirichlet_boundary ( const DirichletBoundary dirichlet_boundary)

◆ add_neighbors_to_send_list()

void libMesh::DofMap::add_neighbors_to_send_list ( MeshBase mesh)
private

Adds entries to the _send_list vector corresponding to DoFs on elements neighboring the current processor.

Definition at line 1507 of file dof_map.C.

1508 {
1509  LOG_SCOPE("add_neighbors_to_send_list()", "DofMap");
1510 
1511  // Return immediately if there's no ghost data
1512  if (this->n_processors() == 1)
1513  return;
1514 
1515  const unsigned int n_var = this->n_variables();
1516 
1517  MeshBase::const_element_iterator local_elem_it
1518  = mesh.active_local_elements_begin();
1519  const MeshBase::const_element_iterator local_elem_end
1520  = mesh.active_local_elements_end();
1521 
1522  GhostingFunctor::map_type elements_to_send;
1523 
1524  // Man, I wish we had guaranteed unique_ptr availability...
1525  std::set<CouplingMatrix *> temporary_coupling_matrices;
1526 
1527  // We need to add dofs to the send list if they've been directly
1528  // requested by an algebraic ghosting functor or they've been
1529  // indirectly requested by a coupling functor.
1530  this->merge_ghost_functor_outputs(elements_to_send,
1531  temporary_coupling_matrices,
1534  local_elem_it, local_elem_end, mesh.processor_id());
1535 
1536  this->merge_ghost_functor_outputs(elements_to_send,
1537  temporary_coupling_matrices,
1538  this->coupling_functors_begin(),
1539  this->coupling_functors_end(),
1540  local_elem_it, local_elem_end, mesh.processor_id());
1541 
1542  // Making a list of non-zero coupling matrix columns is an
1543  // O(N_var^2) operation. We cache it so we only have to do it once
1544  // per CouplingMatrix and not once per element.
1545  std::map<const CouplingMatrix *, std::vector<unsigned int>>
1546  column_variable_lists;
1547 
1548  for (auto & pr : elements_to_send)
1549  {
1550  const Elem * const partner = pr.first;
1551 
1552  // We asked ghosting functors not to give us local elements
1553  libmesh_assert_not_equal_to
1554  (partner->processor_id(), this->processor_id());
1555 
1556  const CouplingMatrix * ghost_coupling = pr.second;
1557 
1558  // Loop over any present coupling matrix column variables if we
1559  // have a coupling matrix, or just add all variables to
1560  // send_list if not.
1561  if (ghost_coupling)
1562  {
1563  libmesh_assert_equal_to (ghost_coupling->size(), n_var);
1564 
1565  // Try to find a cached list of column variables.
1566  std::map<const CouplingMatrix *, std::vector<unsigned int>>::const_iterator
1567  column_variable_list = column_variable_lists.find(ghost_coupling);
1568 
1569  // If we didn't find it, then we need to create it.
1570  if (column_variable_list == column_variable_lists.end())
1571  {
1572  std::pair<std::map<const CouplingMatrix *, std::vector<unsigned int>>::iterator, bool>
1573  inserted_variable_list_pair = column_variable_lists.insert(std::make_pair(ghost_coupling,
1574  std::vector<unsigned int>()));
1575  column_variable_list = inserted_variable_list_pair.first;
1576 
1577  std::vector<unsigned int> & new_variable_list =
1578  inserted_variable_list_pair.first->second;
1579 
1580  std::vector<unsigned char> has_variable(n_var, false);
1581 
1582  for (unsigned int vi = 0; vi != n_var; ++vi)
1583  {
1584  ConstCouplingRow ccr(vi, *ghost_coupling);
1585 
1586  for (const auto & vj : ccr)
1587  has_variable[vj] = true;
1588  }
1589  for (unsigned int vj = 0; vj != n_var; ++vj)
1590  {
1591  if (has_variable[vj])
1592  new_variable_list.push_back(vj);
1593  }
1594  }
1595 
1596  const std::vector<unsigned int> & variable_list =
1597  column_variable_list->second;
1598 
1599  for (const auto & vj : variable_list)
1600  {
1601  std::vector<dof_id_type> di;
1602  this->dof_indices (partner, di, vj);
1603 
1604  // Insert the remote DOF indices into the send list
1605  for (auto d : di)
1606  if (!this->local_index(d))
1607  _send_list.push_back(d);
1608  }
1609  }
1610  else
1611  {
1612  std::vector<dof_id_type> di;
1613  this->dof_indices (partner, di);
1614 
1615  // Insert the remote DOF indices into the send list
1616  for (const auto & dof : di)
1617  if (!this->local_index(dof))
1618  _send_list.push_back(dof);
1619  }
1620 
1621  }
1622 
1623  // We're now done with any merged coupling matrices we had to create.
1624  for (auto & mat : temporary_coupling_matrices)
1625  delete mat;
1626 
1627  //-------------------------------------------------------------------------
1628  // Our coupling functors added dofs from neighboring elements to the
1629  // send list, but we may still need to add non-local dofs from local
1630  // elements.
1631  //-------------------------------------------------------------------------
1632 
1633  // Loop over the active local elements, adding all active elements
1634  // that neighbor an active local element to the send list.
1635  for ( ; local_elem_it != local_elem_end; ++local_elem_it)
1636  {
1637  const Elem * elem = *local_elem_it;
1638 
1639  std::vector<dof_id_type> di;
1640  this->dof_indices (elem, di);
1641 
1642  // Insert the remote DOF indices into the send list
1643  for (const auto & dof : di)
1644  if (!this->local_index(dof))
1645  _send_list.push_back(dof);
1646  }
1647 }

References _send_list, algebraic_ghosting_functors_begin(), algebraic_ghosting_functors_end(), coupling_functors_begin(), coupling_functors_end(), dof_indices(), local_index(), merge_ghost_functor_outputs(), mesh, libMesh::ParallelObject::n_processors(), n_variables(), libMesh::ParallelObject::processor_id(), and libMesh::DofObject::processor_id().

Referenced by distribute_dofs(), and reinit_send_list().

◆ add_periodic_boundary() [1/2]

void libMesh::DofMap::add_periodic_boundary ( const PeriodicBoundaryBase boundary,
const PeriodicBoundaryBase inverse_boundary 
)

Add a periodic boundary pair.

Parameters
boundary- primary boundary
inverse_boundary- inverse boundary

Definition at line 4540 of file dof_map_constraints.C.

4542 {
4543  libmesh_assert_equal_to (boundary.myboundary, inverse_boundary.pairedboundary);
4544  libmesh_assert_equal_to (boundary.pairedboundary, inverse_boundary.myboundary);
4545 
4546  // Allocate copies on the heap. The _periodic_boundaries object will manage this memory.
4547  // Note: this also means that the copy constructor for the PeriodicBoundary (or user class
4548  // derived therefrom) must be implemented!
4549  // PeriodicBoundary * p_boundary = new PeriodicBoundary(boundary);
4550  // PeriodicBoundary * p_inverse_boundary = new PeriodicBoundary(inverse_boundary);
4551 
4552  // We can't use normal copy construction since this leads to slicing with derived classes.
4553  // Use clone() "virtual constructor" instead. But, this *requires* user to override the clone()
4554  // method. Note also that clone() allocates memory. In this case, the _periodic_boundaries object
4555  // takes responsibility for cleanup.
4556  PeriodicBoundaryBase * p_boundary = boundary.clone().release();
4557  PeriodicBoundaryBase * p_inverse_boundary = inverse_boundary.clone().release();
4558 
4559  // Add the periodic boundary and its inverse to the PeriodicBoundaries data structure. The
4560  // PeriodicBoundaries data structure takes ownership of the pointers.
4561  _periodic_boundaries->insert(std::make_pair(p_boundary->myboundary, p_boundary));
4562  _periodic_boundaries->insert(std::make_pair(p_inverse_boundary->myboundary, p_inverse_boundary));
4563 }

References _periodic_boundaries, libMesh::PeriodicBoundaryBase::clone(), libMesh::PeriodicBoundaryBase::myboundary, and libMesh::PeriodicBoundaryBase::pairedboundary.

◆ add_periodic_boundary() [2/2]

void libMesh::DofMap::add_periodic_boundary ( const PeriodicBoundaryBase periodic_boundary)

Adds a copy of the specified periodic boundary to the system.

Definition at line 4510 of file dof_map_constraints.C.

4511 {
4512  // See if we already have a periodic boundary associated myboundary...
4513  PeriodicBoundaryBase * existing_boundary = _periodic_boundaries->boundary(periodic_boundary.myboundary);
4514 
4515  if (existing_boundary == nullptr)
4516  {
4517  // ...if not, clone the input (and its inverse) and add them to the PeriodicBoundaries object
4518  PeriodicBoundaryBase * boundary = periodic_boundary.clone().release();
4519  PeriodicBoundaryBase * inverse_boundary = periodic_boundary.clone(PeriodicBoundaryBase::INVERSE).release();
4520 
4521  // _periodic_boundaries takes ownership of the pointers
4522  _periodic_boundaries->insert(std::make_pair(boundary->myboundary, boundary));
4523  _periodic_boundaries->insert(std::make_pair(inverse_boundary->myboundary, inverse_boundary));
4524  }
4525  else
4526  {
4527  // ...otherwise, merge this object's variable IDs with the existing boundary object's.
4528  existing_boundary->merge(periodic_boundary);
4529 
4530  // Do the same merging process for the inverse boundary. Note: the inverse better already exist!
4531  PeriodicBoundaryBase * inverse_boundary = _periodic_boundaries->boundary(periodic_boundary.pairedboundary);
4532  libmesh_assert(inverse_boundary);
4533  inverse_boundary->merge(periodic_boundary);
4534  }
4535 }

References _periodic_boundaries, libMesh::PeriodicBoundaryBase::clone(), libMesh::PeriodicBoundaryBase::INVERSE, libMesh::libmesh_assert(), libMesh::PeriodicBoundaryBase::merge(), libMesh::PeriodicBoundaryBase::myboundary, and libMesh::PeriodicBoundaryBase::pairedboundary.

Referenced by Biharmonic::JR::JR(), and main().

◆ add_variable_group()

void libMesh::DofMap::add_variable_group ( const VariableGroup var_group)
    Add an unknown of order \p order and finite element type
    \p type to the system of equations.
   &zwj;/

void add_variable (const Variable & var);

/** Add a group of unknowns of order order and finite element type type to the system of equations.

Definition at line 257 of file dof_map.C.

258 {
259  const unsigned int vg = cast_int<unsigned int>(_variable_groups.size());
260 
261  _variable_groups.push_back(var_group);
262 
263  VariableGroup & new_var_group = _variable_groups.back();
264 
265  for (auto var : IntRange<unsigned int>(0, new_var_group.n_variables()))
266  {
267  _variables.push_back (new_var_group(var));
268  _variable_group_numbers.push_back (vg);
269  }
270 }

References _variable_group_numbers, _variable_groups, _variables, and libMesh::VariableGroup::n_variables().

◆ algebraic_ghosting_functors_begin()

std::set<GhostingFunctor *>::const_iterator libMesh::DofMap::algebraic_ghosting_functors_begin ( ) const
inline

Beginning of range of algebraic ghosting functors.

Definition at line 391 of file dof_map.h.

392  { return _algebraic_ghosting_functors.begin(); }

References _algebraic_ghosting_functors.

Referenced by add_neighbors_to_send_list().

◆ algebraic_ghosting_functors_end()

std::set<GhostingFunctor *>::const_iterator libMesh::DofMap::algebraic_ghosting_functors_end ( ) const
inline

End of range of algebraic ghosting functors.

Definition at line 397 of file dof_map.h.

398  { return _algebraic_ghosting_functors.end(); }

References _algebraic_ghosting_functors.

Referenced by add_neighbors_to_send_list().

◆ all_semilocal_indices()

bool libMesh::DofMap::all_semilocal_indices ( const std::vector< dof_id_type > &  dof_indices) const
Returns
true if all degree of freedom indices in dof_indices are either local indices or in the send_list.
Note
This is an O(logN) operation for a send_list of size N; we don't cache enough information for O(1) right now.

Definition at line 2540 of file dof_map.C.

2541 {
2542  // We're all semilocal unless we find a counterexample
2543  for (const auto & di : dof_indices_in)
2544  if (!this->semilocal_index(di))
2545  return false;
2546 
2547  return true;
2548 }

References semilocal_index().

Referenced by is_evaluable().

◆ allgather_recursive_constraints()

void libMesh::DofMap::allgather_recursive_constraints ( MeshBase mesh)

Gathers constraint equation dependencies from other processors.

Definition at line 2700 of file dof_map_constraints.C.

2701 {
2702  // This function must be run on all processors at once
2703  parallel_object_only();
2704 
2705  // Return immediately if there's nothing to gather
2706  if (this->n_processors() == 1)
2707  return;
2708 
2709  // We might get to return immediately if none of the processors
2710  // found any constraints
2711  unsigned int has_constraints = !_dof_constraints.empty()
2712 #ifdef LIBMESH_ENABLE_NODE_CONSTRAINTS
2713  || !_node_constraints.empty()
2714 #endif // LIBMESH_ENABLE_NODE_CONSTRAINTS
2715  ;
2716  this->comm().max(has_constraints);
2717  if (!has_constraints)
2718  return;
2719 
2720  // If we have heterogenous adjoint constraints we need to
2721  // communicate those too.
2722  const unsigned int max_qoi_num =
2723  _adjoint_constraint_values.empty() ?
2724  0 : _adjoint_constraint_values.rbegin()->first;
2725 
2726  // We might have calculated constraints for constrained dofs
2727  // which have support on other processors.
2728  // Push these out first.
2729  {
2730  std::map<processor_id_type, std::set<dof_id_type>> pushed_ids;
2731 
2732 #ifdef LIBMESH_ENABLE_NODE_CONSTRAINTS
2733  std::map<processor_id_type, std::set<dof_id_type>> pushed_node_ids;
2734 #endif
2735 
2736  const unsigned int sys_num = this->sys_number();
2737 
2738  // Collect the constraints to push to each processor
2739  for (auto & elem : as_range(mesh.active_not_local_elements_begin(),
2741  {
2742  const unsigned short n_nodes = elem->n_nodes();
2743 
2744  // Just checking dof_indices on the foreign element isn't
2745  // enough. Consider a central hanging node between a coarse
2746  // Q2/Q1 element and its finer neighbors on a higher-ranked
2747  // processor. The coarse element's processor will own the node,
2748  // and will thereby own the pressure dof on that node, despite
2749  // the fact that that pressure dof doesn't directly exist on the
2750  // coarse element!
2751  //
2752  // So, we loop through dofs manually.
2753 
2754  {
2755  const unsigned int n_vars = elem->n_vars(sys_num);
2756  for (unsigned int v=0; v != n_vars; ++v)
2757  {
2758  const unsigned int n_comp = elem->n_comp(sys_num,v);
2759  for (unsigned int c=0; c != n_comp; ++c)
2760  {
2761  const unsigned int id =
2762  elem->dof_number(sys_num,v,c);
2763  if (this->is_constrained_dof(id))
2764  pushed_ids[elem->processor_id()].insert(id);
2765  }
2766  }
2767  }
2768 
2769  for (unsigned short n = 0; n != n_nodes; ++n)
2770  {
2771  const Node & node = elem->node_ref(n);
2772  const unsigned int n_vars = node.n_vars(sys_num);
2773  for (unsigned int v=0; v != n_vars; ++v)
2774  {
2775  const unsigned int n_comp = node.n_comp(sys_num,v);
2776  for (unsigned int c=0; c != n_comp; ++c)
2777  {
2778  const unsigned int id =
2779  node.dof_number(sys_num,v,c);
2780  if (this->is_constrained_dof(id))
2781  pushed_ids[elem->processor_id()].insert(id);
2782  }
2783  }
2784  }
2785 
2786 #ifdef LIBMESH_ENABLE_NODE_CONSTRAINTS
2787  for (unsigned short n = 0; n != n_nodes; ++n)
2788  if (this->is_constrained_node(elem->node_ptr(n)))
2789  pushed_node_ids[elem->processor_id()].insert(elem->node_id(n));
2790 #endif
2791  }
2792 
2793  // Rewrite those id sets as vectors for sending and receiving,
2794  // then find the corresponding data for each id, then push it all.
2795  std::map<processor_id_type, std::vector<dof_id_type>>
2796  pushed_id_vecs, received_id_vecs;
2797  for (auto & p : pushed_ids)
2798  pushed_id_vecs[p.first].assign(p.second.begin(), p.second.end());
2799 
2800  std::map<processor_id_type, std::vector<std::vector<std::pair<dof_id_type,Real>>>>
2801  pushed_keys_vals, received_keys_vals;
2802  std::map<processor_id_type, std::vector<std::vector<Number>>> pushed_rhss, received_rhss;
2803  for (auto & p : pushed_id_vecs)
2804  {
2805  auto & keys_vals = pushed_keys_vals[p.first];
2806  keys_vals.reserve(p.second.size());
2807 
2808  auto & rhss = pushed_rhss[p.first];
2809  rhss.reserve(p.second.size());
2810  for (auto & pushed_id : p.second)
2811  {
2812  const DofConstraintRow & row = _dof_constraints[pushed_id];
2813  keys_vals.emplace_back(row.begin(), row.end());
2814 
2815  rhss.push_back(std::vector<Number>(max_qoi_num+1));
2816  std::vector<Number> & rhs = rhss.back();
2817  DofConstraintValueMap::const_iterator rhsit =
2818  _primal_constraint_values.find(pushed_id);
2819  rhs[max_qoi_num] =
2820  (rhsit == _primal_constraint_values.end()) ?
2821  0 : rhsit->second;
2822  for (unsigned int q = 0; q != max_qoi_num; ++q)
2823  {
2824  AdjointDofConstraintValues::const_iterator adjoint_map_it =
2826 
2827  if (adjoint_map_it == _adjoint_constraint_values.end())
2828  continue;
2829 
2830  const DofConstraintValueMap & constraint_map =
2831  adjoint_map_it->second;
2832 
2833  DofConstraintValueMap::const_iterator adj_rhsit =
2834  constraint_map.find(pushed_id);
2835 
2836  rhs[q] =
2837  (adj_rhsit == constraint_map.end()) ?
2838  0 : adj_rhsit->second;
2839  }
2840  }
2841  }
2842 
2843  auto ids_action_functor =
2844  [& received_id_vecs]
2845  (processor_id_type pid,
2846  const std::vector<dof_id_type> & data)
2847  {
2848  received_id_vecs[pid] = data;
2849  };
2850 
2851  Parallel::push_parallel_vector_data
2852  (this->comm(), pushed_id_vecs, ids_action_functor);
2853 
2854  auto keys_vals_action_functor =
2855  [& received_keys_vals]
2856  (processor_id_type pid,
2857  const std::vector<std::vector<std::pair<dof_id_type,Real>>> & data)
2858  {
2859  received_keys_vals[pid] = data;
2860  };
2861 
2862  Parallel::push_parallel_vector_data
2863  (this->comm(), pushed_keys_vals, keys_vals_action_functor);
2864 
2865  auto rhss_action_functor =
2866  [& received_rhss]
2867  (processor_id_type pid,
2868  const std::vector<std::vector<Number>> & data)
2869  {
2870  received_rhss[pid] = data;
2871  };
2872 
2873  Parallel::push_parallel_vector_data
2874  (this->comm(), pushed_rhss, rhss_action_functor);
2875 
2876  // Now we have all the DofConstraint rows and rhs values received
2877  // from others, so add the DoF constraints that we've been sent
2878 
2879 #ifdef LIBMESH_ENABLE_NODE_CONSTRAINTS
2880  std::map<processor_id_type, std::vector<dof_id_type>>
2881  pushed_node_id_vecs, received_node_id_vecs;
2882  for (auto & p : pushed_node_ids)
2883  pushed_node_id_vecs[p.first].assign(p.second.begin(), p.second.end());
2884 
2885  std::map<processor_id_type, std::vector<std::vector<std::pair<dof_id_type,Real>>>>
2886  pushed_node_keys_vals, received_node_keys_vals;
2887  std::map<processor_id_type, std::vector<Point>> pushed_offsets, received_offsets;
2888 
2889  for (auto & p : pushed_node_id_vecs)
2890  {
2891  auto & node_keys_vals = pushed_node_keys_vals[p.first];
2892  node_keys_vals.reserve(p.second.size());
2893 
2894  auto & offsets = pushed_offsets[p.first];
2895  offsets.reserve(p.second.size());
2896 
2897  for (auto & pushed_node_id : p.second)
2898  {
2899  const Node * node = mesh.node_ptr(pushed_node_id);
2900  NodeConstraintRow & row = _node_constraints[node].first;
2901  const std::size_t row_size = row.size();
2902  node_keys_vals.push_back
2903  (std::vector<std::pair<dof_id_type,Real>>());
2904  std::vector<std::pair<dof_id_type,Real>> & this_node_kv =
2905  node_keys_vals.back();
2906  this_node_kv.reserve(row_size);
2907  for (const auto & j : row)
2908  this_node_kv.push_back
2909  (std::make_pair(j.first->id(), j.second));
2910 
2911  offsets.push_back(_node_constraints[node].second);
2912  }
2913  }
2914 
2915  auto node_ids_action_functor =
2916  [& received_node_id_vecs]
2917  (processor_id_type pid,
2918  const std::vector<dof_id_type> & data)
2919  {
2920  received_node_id_vecs[pid] = data;
2921  };
2922 
2923  Parallel::push_parallel_vector_data
2924  (this->comm(), pushed_node_id_vecs, node_ids_action_functor);
2925 
2926  auto node_keys_vals_action_functor =
2927  [& received_node_keys_vals]
2928  (processor_id_type pid,
2929  const std::vector<std::vector<std::pair<dof_id_type,Real>>> & data)
2930  {
2931  received_node_keys_vals[pid] = data;
2932  };
2933 
2934  Parallel::push_parallel_vector_data
2935  (this->comm(), pushed_node_keys_vals,
2936  node_keys_vals_action_functor);
2937 
2938  auto node_offsets_action_functor =
2939  [& received_offsets]
2940  (processor_id_type pid,
2941  const std::vector<Point> & data)
2942  {
2943  received_offsets[pid] = data;
2944  };
2945 
2946  Parallel::push_parallel_vector_data
2947  (this->comm(), pushed_offsets, node_offsets_action_functor);
2948 
2949 #endif
2950 
2951  // Add all the dof constraints that I've been sent
2952  for (auto & p : received_id_vecs)
2953  {
2954  const processor_id_type pid = p.first;
2955  const auto & pushed_ids_to_me = p.second;
2956  libmesh_assert(received_keys_vals.count(pid));
2957  libmesh_assert(received_rhss.count(pid));
2958  const auto & pushed_keys_vals_to_me = received_keys_vals.at(pid);
2959  const auto & pushed_rhss_to_me = received_rhss.at(pid);
2960 
2961  libmesh_assert_equal_to (pushed_ids_to_me.size(),
2962  pushed_keys_vals_to_me.size());
2963  libmesh_assert_equal_to (pushed_ids_to_me.size(),
2964  pushed_rhss_to_me.size());
2965 
2966  for (auto i : index_range(pushed_ids_to_me))
2967  {
2968  dof_id_type constrained = pushed_ids_to_me[i];
2969 
2970  // If we don't already have a constraint for this dof,
2971  // add the one we were sent
2972  if (!this->is_constrained_dof(constrained))
2973  {
2974  DofConstraintRow & row = _dof_constraints[constrained];
2975  for (auto & kv : pushed_keys_vals_to_me[i])
2976  {
2977  libmesh_assert_less(kv.first, this->n_dofs());
2978  row[kv.first] = kv.second;
2979  }
2980 
2981  const Number primal_rhs = pushed_rhss_to_me[i][max_qoi_num];
2982 
2983  if (libmesh_isnan(primal_rhs))
2984  libmesh_assert(pushed_keys_vals_to_me[i].empty());
2985 
2986  if (primal_rhs != Number(0))
2987  _primal_constraint_values[constrained] = primal_rhs;
2988  else
2989  _primal_constraint_values.erase(constrained);
2990 
2991  for (unsigned int q = 0; q != max_qoi_num; ++q)
2992  {
2993  AdjointDofConstraintValues::iterator adjoint_map_it =
2995 
2996  const Number adj_rhs = pushed_rhss_to_me[i][q];
2997 
2998  if ((adjoint_map_it == _adjoint_constraint_values.end()) &&
2999  adj_rhs == Number(0))
3000  continue;
3001 
3002  if (adjoint_map_it == _adjoint_constraint_values.end())
3003  adjoint_map_it = _adjoint_constraint_values.insert
3004  (std::make_pair(q,DofConstraintValueMap())).first;
3005 
3006  DofConstraintValueMap & constraint_map =
3007  adjoint_map_it->second;
3008 
3009  if (adj_rhs != Number(0))
3010  constraint_map[constrained] = adj_rhs;
3011  else
3012  constraint_map.erase(constrained);
3013  }
3014  }
3015  }
3016  }
3017 
3018 #ifdef LIBMESH_ENABLE_NODE_CONSTRAINTS
3019  // Add all the node constraints that I've been sent
3020  for (auto & p : received_node_id_vecs)
3021  {
3022  const processor_id_type pid = p.first;
3023  const auto & pushed_node_ids_to_me = p.second;
3024  libmesh_assert(received_node_keys_vals.count(pid));
3025  libmesh_assert(received_offsets.count(pid));
3026  const auto & pushed_node_keys_vals_to_me = received_node_keys_vals.at(pid);
3027  const auto & pushed_offsets_to_me = received_offsets.at(pid);
3028 
3029  libmesh_assert_equal_to (pushed_node_ids_to_me.size(),
3030  pushed_node_keys_vals_to_me.size());
3031  libmesh_assert_equal_to (pushed_node_ids_to_me.size(),
3032  pushed_offsets_to_me.size());
3033 
3034  for (auto i : index_range(pushed_node_ids_to_me))
3035  {
3036  dof_id_type constrained_id = pushed_node_ids_to_me[i];
3037 
3038  // If we don't already have a constraint for this node,
3039  // add the one we were sent
3040  const Node * constrained = mesh.node_ptr(constrained_id);
3041  if (!this->is_constrained_node(constrained))
3042  {
3043  NodeConstraintRow & row = _node_constraints[constrained].first;
3044  for (auto & kv : pushed_node_keys_vals_to_me[i])
3045  {
3046  const Node * key_node = mesh.node_ptr(kv.first);
3047  libmesh_assert(key_node);
3048  row[key_node] = kv.second;
3049  }
3050  _node_constraints[constrained].second = pushed_offsets_to_me[i];
3051  }
3052  }
3053  }
3054 #endif // LIBMESH_ENABLE_NODE_CONSTRAINTS
3055  }
3056 
3057  // Now start checking for any other constraints we need
3058  // to know about, requesting them recursively.
3059 
3060  // Create sets containing the DOFs and nodes we already depend on
3061  typedef std::set<dof_id_type> DoF_RCSet;
3062  DoF_RCSet unexpanded_dofs;
3063 
3064  for (const auto & i : _dof_constraints)
3065  unexpanded_dofs.insert(i.first);
3066 
3067  // Gather all the dof constraints we need
3068  this->gather_constraints(mesh, unexpanded_dofs, false);
3069 
3070  // Gather all the node constraints we need
3071 #ifdef LIBMESH_ENABLE_NODE_CONSTRAINTS
3072  typedef std::set<const Node *> Node_RCSet;
3073  Node_RCSet unexpanded_nodes;
3074 
3075  for (const auto & i : _node_constraints)
3076  unexpanded_nodes.insert(i.first);
3077 
3078  // We have to keep recursing while the unexpanded set is
3079  // nonempty on *any* processor
3080  bool unexpanded_set_nonempty = !unexpanded_nodes.empty();
3081  this->comm().max(unexpanded_set_nonempty);
3082 
3083  // We may be receiving packed_range sends out of order with
3084  // parallel_sync tags, so make sure they're received correctly.
3085  Parallel::MessageTag range_tag = this->comm().get_unique_tag();
3086 
3087  while (unexpanded_set_nonempty)
3088  {
3089  // Let's make sure we don't lose sync in this loop.
3090  parallel_object_only();
3091 
3092  // Request sets
3093  Node_RCSet node_request_set;
3094 
3095  // Request sets to send to each processor
3096  std::map<processor_id_type, std::vector<dof_id_type>>
3097  requested_node_ids;
3098 
3099  // And the sizes of each
3100  std::map<processor_id_type, dof_id_type> node_ids_on_proc;
3101 
3102  // Fill (and thereby sort and uniq!) the main request sets
3103  for (const auto & i : unexpanded_nodes)
3104  {
3105  NodeConstraintRow & row = _node_constraints[i].first;
3106  for (const auto & j : row)
3107  {
3108  const Node * const node = j.first;
3109  libmesh_assert(node);
3110 
3111  // If it's non-local and we haven't already got a
3112  // constraint for it, we might need to ask for one
3113  if ((node->processor_id() != this->processor_id()) &&
3114  !_node_constraints.count(node))
3115  node_request_set.insert(node);
3116  }
3117  }
3118 
3119  // Clear the unexpanded constraint sets; we're about to expand
3120  // them
3121  unexpanded_nodes.clear();
3122 
3123  // Count requests by processor
3124  for (const auto & node : node_request_set)
3125  {
3126  libmesh_assert(node);
3127  libmesh_assert_less (node->processor_id(), this->n_processors());
3128  node_ids_on_proc[node->processor_id()]++;
3129  }
3130 
3131  for (auto pair : node_ids_on_proc)
3132  requested_node_ids[pair.first].reserve(pair.second);
3133 
3134  // Prepare each processor's request set
3135  for (const auto & node : node_request_set)
3136  requested_node_ids[node->processor_id()].push_back(node->id());
3137 
3138  typedef std::vector<std::pair<dof_id_type, Real>> row_datum;
3139 
3140  // We may need to send nodes ahead of data about them
3141  std::vector<Parallel::Request> packed_range_sends;
3142 
3143  auto node_row_gather_functor =
3144  [this,
3145  & mesh,
3146  & packed_range_sends,
3147  & range_tag]
3148  (processor_id_type pid,
3149  const std::vector<dof_id_type> & ids,
3150  std::vector<row_datum> & data)
3151  {
3152  // Do we need to keep track of requested nodes to send
3153  // later?
3154  const bool dist_mesh = !mesh.is_serial();
3155 
3156  // FIXME - this could be an unordered set, given a
3157  // hash<pointers> specialization
3158  std::set<const Node *> nodes_requested;
3159 
3160  // Fill those requests
3161  const std::size_t query_size = ids.size();
3162 
3163  data.resize(query_size);
3164  for (std::size_t i=0; i != query_size; ++i)
3165  {
3166  dof_id_type constrained_id = ids[i];
3167  const Node * constrained_node = mesh.node_ptr(constrained_id);
3168  if (_node_constraints.count(constrained_node))
3169  {
3170  const NodeConstraintRow & row = _node_constraints[constrained_node].first;
3171  std::size_t row_size = row.size();
3172  data[i].reserve(row_size);
3173  for (const auto & j : row)
3174  {
3175  const Node * node = j.first;
3176  data[i].push_back(std::make_pair(node->id(), j.second));
3177 
3178  // If we're not sure whether our send
3179  // destination already has this node, let's give
3180  // it a copy.
3181  if (node->processor_id() != pid && dist_mesh)
3182  nodes_requested.insert(node);
3183 
3184  // We can have 0 nodal constraint
3185  // coefficients, where no Lagrange constraint
3186  // exists but non-Lagrange basis constraints
3187  // might.
3188  // libmesh_assert(j.second);
3189  }
3190  }
3191  else
3192  {
3193  // We have to distinguish "constraint with no
3194  // constraining nodes" (e.g. due to user node
3195  // constraint equations) from "no constraint".
3196  // We'll use invalid_id for the latter.
3197  data[i].push_back
3198  (std::make_pair(DofObject::invalid_id, Real(0)));
3199  }
3200  }
3201 
3202  // Constraining nodes might not even exist on our
3203  // correspondant's subset of a distributed mesh, so let's
3204  // make them exist.
3205  if (dist_mesh)
3206  {
3207  packed_range_sends.push_back(Parallel::Request());
3208  this->comm().send_packed_range
3209  (pid, &mesh, nodes_requested.begin(), nodes_requested.end(),
3210  packed_range_sends.back(), range_tag);
3211  }
3212  };
3213 
3214  typedef Point node_rhs_datum;
3215 
3216  auto node_rhs_gather_functor =
3217  [this,
3218  & mesh]
3220  const std::vector<dof_id_type> & ids,
3221  std::vector<node_rhs_datum> & data)
3222  {
3223  // Fill those requests
3224  const std::size_t query_size = ids.size();
3225 
3226  data.resize(query_size);
3227  for (std::size_t i=0; i != query_size; ++i)
3228  {
3229  dof_id_type constrained_id = ids[i];
3230  const Node * constrained_node = mesh.node_ptr(constrained_id);
3231  if (_node_constraints.count(constrained_node))
3232  data[i] = _node_constraints[constrained_node].second;
3233  else
3234  data[i](0) = std::numeric_limits<Real>::quiet_NaN();
3235  }
3236  };
3237 
3238  auto node_row_action_functor =
3239  [this,
3240  & mesh,
3241  & range_tag,
3242  & unexpanded_nodes]
3243  (processor_id_type pid,
3244  const std::vector<dof_id_type> & ids,
3245  const std::vector<row_datum> & data)
3246  {
3247  // Before we act on any new constraint rows, we may need to
3248  // make sure we have all the nodes involved!
3249  if (!mesh.is_serial())
3250  this->comm().receive_packed_range
3252  (Node**)nullptr, range_tag);
3253 
3254  // Add any new constraint rows we've found
3255  const std::size_t query_size = ids.size();
3256 
3257  for (std::size_t i=0; i != query_size; ++i)
3258  {
3259  const dof_id_type constrained_id = ids[i];
3260 
3261  // An empty row is an constraint with an empty row; for
3262  // no constraint we use a "no row" placeholder
3263  if (data[i].empty())
3264  {
3265  const Node * constrained_node = mesh.node_ptr(constrained_id);
3266  NodeConstraintRow & row = _node_constraints[constrained_node].first;
3267  row.clear();
3268  }
3269  else if (data[i][0].first != DofObject::invalid_id)
3270  {
3271  const Node * constrained_node = mesh.node_ptr(constrained_id);
3272  NodeConstraintRow & row = _node_constraints[constrained_node].first;
3273  row.clear();
3274  for (auto & pair : data[i])
3275  {
3276  const Node * key_node =
3277  mesh.node_ptr(pair.first);
3278  libmesh_assert(key_node);
3279  row[key_node] = pair.second;
3280  }
3281 
3282  // And prepare to check for more recursive constraints
3283  unexpanded_nodes.insert(constrained_node);
3284  }
3285  }
3286  };
3287 
3288  auto node_rhs_action_functor =
3289  [this,
3290  & mesh]
3292  const std::vector<dof_id_type> & ids,
3293  const std::vector<node_rhs_datum> & data)
3294  {
3295  // Add rhs data for any new node constraint rows we've found
3296  const std::size_t query_size = ids.size();
3297 
3298  for (std::size_t i=0; i != query_size; ++i)
3299  {
3300  dof_id_type constrained_id = ids[i];
3301  const Node * constrained_node = mesh.node_ptr(constrained_id);
3302 
3303  if (!libmesh_isnan(data[i](0)))
3304  _node_constraints[constrained_node].second = data[i];
3305  else
3306  _node_constraints.erase(constrained_node);
3307  }
3308  };
3309 
3310  // Now request node constraint rows from other processors
3311  row_datum * node_row_ex = nullptr;
3312  Parallel::pull_parallel_vector_data
3313  (this->comm(), requested_node_ids, node_row_gather_functor,
3314  node_row_action_functor, node_row_ex);
3315 
3316  // And request node constraint right hand sides from other procesors
3317  node_rhs_datum * node_rhs_ex = nullptr;
3318  Parallel::pull_parallel_vector_data
3319  (this->comm(), requested_node_ids, node_rhs_gather_functor,
3320  node_rhs_action_functor, node_rhs_ex);
3321 
3322  Parallel::wait(packed_range_sends);
3323 
3324  // We have to keep recursing while the unexpanded set is
3325  // nonempty on *any* processor
3326  unexpanded_set_nonempty = !unexpanded_nodes.empty();
3327  this->comm().max(unexpanded_set_nonempty);
3328  }
3329 #endif // LIBMESH_ENABLE_NODE_CONSTRAINTS
3330 }

References _adjoint_constraint_values, _dof_constraints, _node_constraints, _primal_constraint_values, libMesh::MeshBase::active_not_local_elements_begin(), libMesh::MeshBase::active_not_local_elements_end(), libMesh::as_range(), libMesh::ParallelObject::comm(), data, libMesh::DofObject::dof_number(), gather_constraints(), libMesh::DofObject::id(), libMesh::index_range(), libMesh::DofObject::invalid_id, is_constrained_dof(), is_constrained_node(), libMesh::MeshBase::is_serial(), libMesh::libmesh_assert(), libMesh::libmesh_isnan(), mesh, libMesh::DofObject::n_comp(), n_nodes, libMesh::ParallelObject::n_processors(), n_vars, libMesh::DofObject::n_vars(), libMesh::MeshBase::node_ptr(), libMesh::ParallelObject::processor_id(), libMesh::DofObject::processor_id(), libMesh::Real, libMesh::TypeVector< T >::size(), and sys_number().

Referenced by process_constraints().

◆ attach_extra_send_list_function()

void libMesh::DofMap::attach_extra_send_list_function ( void(*)(std::vector< dof_id_type > &, void *)  func,
void *  context = nullptr 
)
inline

Attach a function pointer to use as a callback to populate the send_list with extra entries.

Definition at line 453 of file dof_map.h.

References _extra_send_list_context, and _extra_send_list_function.

◆ attach_extra_send_list_object()

void libMesh::DofMap::attach_extra_send_list_object ( DofMap::AugmentSendList asl)
inline

Attach an object to populate the send_list with extra entries.

This should only add to the send list, but no checking is done to enforce this behavior.

This is an advanced function... use at your own peril!

Definition at line 444 of file dof_map.h.

445  {
446  _augment_send_list = &asl;
447  }

References _augment_send_list.

◆ attach_extra_sparsity_function()

void libMesh::DofMap::attach_extra_sparsity_function ( void(*)(SparsityPattern::Graph &sparsity, std::vector< dof_id_type > &n_nz, std::vector< dof_id_type > &n_oz, void *)  func,
void *  context = nullptr 
)
inline

Attach a function pointer to use as a callback to populate the sparsity pattern with extra entries.

Care must be taken that when adding entries they are sorted into the Rows

Further, you must modify n_nz and n_oz properly!

This is an advanced function... use at your own peril!

Definition at line 430 of file dof_map.h.

References _extra_sparsity_context, and _extra_sparsity_function.

◆ attach_extra_sparsity_object()

void libMesh::DofMap::attach_extra_sparsity_object ( DofMap::AugmentSparsityPattern asp)
inline

Attach an object to use to populate the sparsity pattern with extra entries.

Care must be taken that when adding entries they are sorted into the Rows

Further, you must modify n_nz and n_oz properly!

This is an advanced function... use at your own peril!

Definition at line 415 of file dof_map.h.

416  {
418  }

References _augment_sparsity_pattern.

◆ attach_matrix()

void libMesh::DofMap::attach_matrix ( SparseMatrix< Number > &  matrix)

Additional matrices may be handled with this DofMap.

They are initialized to the same sparsity structure as the major matrix.

Definition at line 274 of file dof_map.C.

275 {
276  parallel_object_only();
277 
278  // We shouldn't be trying to re-attach the same matrices repeatedly
279  libmesh_assert (std::find(_matrices.begin(), _matrices.end(),
280  &matrix) == _matrices.end());
281 
282  _matrices.push_back(&matrix);
283 
284  matrix.attach_dof_map (*this);
285 
286  // If we've already computed sparsity, then it's too late
287  // to wait for "compute_sparsity" to help with sparse matrix
288  // initialization, and we need to handle this matrix individually
289  bool computed_sparsity_already =
290  ((_n_nz && !_n_nz->empty()) ||
291  (_n_oz && !_n_oz->empty()));
292  this->comm().max(computed_sparsity_already);
293  if (computed_sparsity_already &&
295  {
296  // We'd better have already computed the full sparsity pattern
297  // if we need it here
299  libmesh_assert(_sp.get());
300 
301  matrix.update_sparsity_pattern (_sp->sparsity_pattern);
302  }
303 
304  if (matrix.need_full_sparsity_pattern())
306 }

References _matrices, _n_nz, _n_oz, _sp, libMesh::SparseMatrix< T >::attach_dof_map(), libMesh::ParallelObject::comm(), libMesh::libmesh_assert(), libMesh::SparseMatrix< T >::need_full_sparsity_pattern(), need_full_sparsity_pattern, and libMesh::SparseMatrix< T >::update_sparsity_pattern().

Referenced by libMesh::TransientRBConstruction::allocate_data_structures(), libMesh::RBConstruction::allocate_data_structures(), libMesh::EigenSystem::init_matrices(), and libMesh::ImplicitSystem::init_matrices().

◆ block_size()

unsigned int libMesh::DofMap::block_size ( ) const
inline
Returns
The block size, if the variables are amenable to block storage. Otherwise 1. This routine was originally designed to enable a blocked storage, but it turns out this information is still super useful for solvers even when we do not use the blocked storage (e.g., MATMPIBAIJ in PETSc). For example (in PCHMG), for a system of PDEs, to construct an efficient multilevel preconditioner, we coarsen the matrix of one single PDE instead of the entire huge matrix. In order to accomplish this, we need to know many PDEs we have. Another use case, the fieldsplit preconditioner can be constructed in place with this info wihtout involving any user efforts.

Definition at line 617 of file dof_map.h.

618  {
619  return (this->has_blocked_representation() ? this->n_variables() : 1);
620  }

References has_blocked_representation(), and n_variables().

◆ build_constraint_matrix()

void libMesh::DofMap::build_constraint_matrix ( DenseMatrix< Number > &  C,
std::vector< dof_id_type > &  elem_dofs,
const bool  called_recursively = false 
) const
private

Build the constraint matrix C associated with the element degree of freedom indices elem_dofs.

The optional parameter called_recursively should be left at the default value false. This is used to handle the special case of an element's degrees of freedom being constrained in terms of other, local degrees of freedom. The usual case is for an elements DOFs to be constrained by some other, external DOFs.

Definition at line 2451 of file dof_map_constraints.C.

2454 {
2455  LOG_SCOPE_IF("build_constraint_matrix()", "DofMap", !called_recursively);
2456 
2457  // Create a set containing the DOFs we already depend on
2458  typedef std::set<dof_id_type> RCSet;
2459  RCSet dof_set;
2460 
2461  bool we_have_constraints = false;
2462 
2463  // Next insert any other dofs the current dofs might be constrained
2464  // in terms of. Note that in this case we may not be done: Those
2465  // may in turn depend on others. So, we need to repeat this process
2466  // in that case until the system depends only on unconstrained
2467  // degrees of freedom.
2468  for (const auto & dof : elem_dofs)
2469  if (this->is_constrained_dof(dof))
2470  {
2471  we_have_constraints = true;
2472 
2473  // If the DOF is constrained
2474  DofConstraints::const_iterator
2475  pos = _dof_constraints.find(dof);
2476 
2477  libmesh_assert (pos != _dof_constraints.end());
2478 
2479  const DofConstraintRow & constraint_row = pos->second;
2480 
2481  // Constraint rows in p refinement may be empty
2482  //libmesh_assert (!constraint_row.empty());
2483 
2484  for (const auto & item : constraint_row)
2485  dof_set.insert (item.first);
2486  }
2487 
2488  // May be safe to return at this point
2489  // (but remember to stop the perflog)
2490  if (!we_have_constraints)
2491  return;
2492 
2493  for (const auto & dof : elem_dofs)
2494  dof_set.erase (dof);
2495 
2496  // If we added any DOFS then we need to do this recursively.
2497  // It is possible that we just added a DOF that is also
2498  // constrained!
2499  //
2500  // Also, we need to handle the special case of an element having DOFs
2501  // constrained in terms of other, local DOFs
2502  if (!dof_set.empty() || // case 1: constrained in terms of other DOFs
2503  !called_recursively) // case 2: constrained in terms of our own DOFs
2504  {
2505  const unsigned int old_size =
2506  cast_int<unsigned int>(elem_dofs.size());
2507 
2508  // Add new dependency dofs to the end of the current dof set
2509  elem_dofs.insert(elem_dofs.end(),
2510  dof_set.begin(), dof_set.end());
2511 
2512  // Now we can build the constraint matrix.
2513  // Note that resize also zeros for a DenseMatrix<Number>.
2514  C.resize (old_size,
2515  cast_int<unsigned int>(elem_dofs.size()));
2516 
2517  // Create the C constraint matrix.
2518  for (unsigned int i=0; i != old_size; i++)
2519  if (this->is_constrained_dof(elem_dofs[i]))
2520  {
2521  // If the DOF is constrained
2522  DofConstraints::const_iterator
2523  pos = _dof_constraints.find(elem_dofs[i]);
2524 
2525  libmesh_assert (pos != _dof_constraints.end());
2526 
2527  const DofConstraintRow & constraint_row = pos->second;
2528 
2529  // p refinement creates empty constraint rows
2530  // libmesh_assert (!constraint_row.empty());
2531 
2532  for (const auto & item : constraint_row)
2533  for (unsigned int j=0,
2534  n_elem_dofs = cast_int<unsigned int>(elem_dofs.size());
2535  j != n_elem_dofs; j++)
2536  if (elem_dofs[j] == item.first)
2537  C(i,j) = item.second;
2538  }
2539  else
2540  {
2541  C(i,i) = 1.;
2542  }
2543 
2544  // May need to do this recursively. It is possible
2545  // that we just replaced a constrained DOF with another
2546  // constrained DOF.
2547  DenseMatrix<Number> Cnew;
2548 
2549  this->build_constraint_matrix (Cnew, elem_dofs, true);
2550 
2551  if ((C.n() == Cnew.m()) &&
2552  (Cnew.n() == elem_dofs.size())) // If the constraint matrix
2553  C.right_multiply(Cnew); // is constrained...
2554 
2555  libmesh_assert_equal_to (C.n(), elem_dofs.size());
2556  }
2557 }

References _dof_constraints, is_constrained_dof(), libMesh::libmesh_assert(), libMesh::DenseMatrixBase< T >::m(), libMesh::DenseMatrixBase< T >::n(), libMesh::DenseMatrix< T >::resize(), and libMesh::DenseMatrix< T >::right_multiply().

Referenced by max_constraint_error().

◆ build_constraint_matrix_and_vector()

void libMesh::DofMap::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
private

Build the constraint matrix C and the forcing vector H associated with the element degree of freedom indices elem_dofs.

The optional parameter called_recursively should be left at the default value false. This is used to handle the special case of an element's degrees of freedom being constrained in terms of other, local degrees of freedom. The usual case is for an elements DOFs to be constrained by some other, external DOFs and/or Dirichlet conditions.

The forcing vector will depend on which solution's heterogenous constraints are being applied. For the default qoi_index this will be the primal solution; for qoi_index >= 0 the corresponding adjoint solution's constraints will be used.

Definition at line 2561 of file dof_map_constraints.C.

2566 {
2567  LOG_SCOPE_IF("build_constraint_matrix_and_vector()", "DofMap", !called_recursively);
2568 
2569  // Create a set containing the DOFs we already depend on
2570  typedef std::set<dof_id_type> RCSet;
2571  RCSet dof_set;
2572 
2573  bool we_have_constraints = false;
2574 
2575  // Next insert any other dofs the current dofs might be constrained
2576  // in terms of. Note that in this case we may not be done: Those
2577  // may in turn depend on others. So, we need to repeat this process
2578  // in that case until the system depends only on unconstrained
2579  // degrees of freedom.
2580  for (const auto & dof : elem_dofs)
2581  if (this->is_constrained_dof(dof))
2582  {
2583  we_have_constraints = true;
2584 
2585  // If the DOF is constrained
2586  DofConstraints::const_iterator
2587  pos = _dof_constraints.find(dof);
2588 
2589  libmesh_assert (pos != _dof_constraints.end());
2590 
2591  const DofConstraintRow & constraint_row = pos->second;
2592 
2593  // Constraint rows in p refinement may be empty
2594  //libmesh_assert (!constraint_row.empty());
2595 
2596  for (const auto & item : constraint_row)
2597  dof_set.insert (item.first);
2598  }
2599 
2600  // May be safe to return at this point
2601  // (but remember to stop the perflog)
2602  if (!we_have_constraints)
2603  return;
2604 
2605  for (const auto & dof : elem_dofs)
2606  dof_set.erase (dof);
2607 
2608  // If we added any DOFS then we need to do this recursively.
2609  // It is possible that we just added a DOF that is also
2610  // constrained!
2611  //
2612  // Also, we need to handle the special case of an element having DOFs
2613  // constrained in terms of other, local DOFs
2614  if (!dof_set.empty() || // case 1: constrained in terms of other DOFs
2615  !called_recursively) // case 2: constrained in terms of our own DOFs
2616  {
2617  const DofConstraintValueMap * rhs_values = nullptr;
2618  if (qoi_index < 0)
2619  rhs_values = &_primal_constraint_values;
2620  else
2621  {
2622  const AdjointDofConstraintValues::const_iterator
2623  it = _adjoint_constraint_values.find(qoi_index);
2624  if (it != _adjoint_constraint_values.end())
2625  rhs_values = &it->second;
2626  }
2627 
2628  const unsigned int old_size =
2629  cast_int<unsigned int>(elem_dofs.size());
2630 
2631  // Add new dependency dofs to the end of the current dof set
2632  elem_dofs.insert(elem_dofs.end(),
2633  dof_set.begin(), dof_set.end());
2634 
2635  // Now we can build the constraint matrix and vector.
2636  // Note that resize also zeros for a DenseMatrix and DenseVector
2637  C.resize (old_size,
2638  cast_int<unsigned int>(elem_dofs.size()));
2639  H.resize (old_size);
2640 
2641  // Create the C constraint matrix.
2642  for (unsigned int i=0; i != old_size; i++)
2643  if (this->is_constrained_dof(elem_dofs[i]))
2644  {
2645  // If the DOF is constrained
2646  DofConstraints::const_iterator
2647  pos = _dof_constraints.find(elem_dofs[i]);
2648 
2649  libmesh_assert (pos != _dof_constraints.end());
2650 
2651  const DofConstraintRow & constraint_row = pos->second;
2652 
2653  // p refinement creates empty constraint rows
2654  // libmesh_assert (!constraint_row.empty());
2655 
2656  for (const auto & item : constraint_row)
2657  for (unsigned int j=0,
2658  n_elem_dofs = cast_int<unsigned int>(elem_dofs.size());
2659  j != n_elem_dofs; j++)
2660  if (elem_dofs[j] == item.first)
2661  C(i,j) = item.second;
2662 
2663  if (rhs_values)
2664  {
2665  DofConstraintValueMap::const_iterator rhsit =
2666  rhs_values->find(elem_dofs[i]);
2667  if (rhsit != rhs_values->end())
2668  H(i) = rhsit->second;
2669  }
2670  }
2671  else
2672  {
2673  C(i,i) = 1.;
2674  }
2675 
2676  // May need to do this recursively. It is possible
2677  // that we just replaced a constrained DOF with another
2678  // constrained DOF.
2679  DenseMatrix<Number> Cnew;
2680  DenseVector<Number> Hnew;
2681 
2682  this->build_constraint_matrix_and_vector (Cnew, Hnew, elem_dofs,
2683  qoi_index, true);
2684 
2685  if ((C.n() == Cnew.m()) && // If the constraint matrix
2686  (Cnew.n() == elem_dofs.size())) // is constrained...
2687  {
2688  // If x = Cy + h and y = Dz + g
2689  // Then x = (CD)z + (Cg + h)
2690  C.vector_mult_add(H, 1, Hnew);
2691 
2692  C.right_multiply(Cnew);
2693  }
2694 
2695  libmesh_assert_equal_to (C.n(), elem_dofs.size());
2696  }
2697 }

References _adjoint_constraint_values, _dof_constraints, _primal_constraint_values, is_constrained_dof(), libMesh::libmesh_assert(), libMesh::DenseMatrixBase< T >::m(), libMesh::DenseMatrixBase< T >::n(), libMesh::DenseVector< T >::resize(), libMesh::DenseMatrix< T >::resize(), libMesh::DenseMatrix< T >::right_multiply(), and libMesh::DenseMatrix< T >::vector_mult_add().

Referenced by extract_local_vector().

◆ build_sparsity()

std::unique_ptr< SparsityPattern::Build > libMesh::DofMap::build_sparsity ( const MeshBase mesh) const
private

Builds a sparsity pattern.

Definition at line 63 of file dof_map.C.

64 {
65  libmesh_assert (mesh.is_prepared());
66 
67  LOG_SCOPE("build_sparsity()", "DofMap");
68 
69  // Compute the sparsity structure of the global matrix. This can be
70  // fed into a PetscMatrix to allocate exactly the number of nonzeros
71  // necessary to store the matrix. This algorithm should be linear
72  // in the (# of elements)*(# nodes per element)
73 
74  // We can be more efficient in the threaded sparsity pattern assembly
75  // if we don't need the exact pattern. For some sparse matrix formats
76  // a good upper bound will suffice.
77 
78  // See if we need to include sparsity pattern entries for coupling
79  // between neighbor dofs
80  bool implicit_neighbor_dofs = this->use_coupled_neighbor_dofs(mesh);
81 
82  // We can compute the sparsity pattern in parallel on multiple
83  // threads. The goal is for each thread to compute the full sparsity
84  // pattern for a subset of elements. These sparsity patterns can
85  // be efficiently merged in the SparsityPattern::Build::join()
86  // method, especially if there is not too much overlap between them.
87  // Even better, if the full sparsity pattern is not needed then
88  // the number of nonzeros per row can be estimated from the
89  // sparsity patterns created on each thread.
90  auto sp = libmesh_make_unique<SparsityPattern::Build>
91  (mesh,
92  *this,
93  this->_dof_coupling,
94  this->_coupling_functors,
95  implicit_neighbor_dofs,
97 
98  Threads::parallel_reduce (ConstElemRange (mesh.active_local_elements_begin(),
99  mesh.active_local_elements_end()), *sp);
100 
101  sp->parallel_sync();
102 
103 #ifndef NDEBUG
104  // Avoid declaring these variables unless asserts are enabled.
105  const processor_id_type proc_id = mesh.processor_id();
106  const dof_id_type n_dofs_on_proc = this->n_dofs_on_processor(proc_id);
107 #endif
108  libmesh_assert_equal_to (sp->sparsity_pattern.size(), n_dofs_on_proc);
109 
110  // Check to see if we have any extra stuff to add to the sparsity_pattern
112  {
114  {
115  libmesh_here();
116  libMesh::out << "WARNING: You have specified both an extra sparsity function and object.\n"
117  << " Are you sure this is what you meant to do??"
118  << std::endl;
119  }
120 
122  (sp->sparsity_pattern, sp->n_nz,
123  sp->n_oz, _extra_sparsity_context);
124  }
125 
128  (sp->sparsity_pattern, sp->n_nz, sp->n_oz);
129 
130  return std::unique_ptr<SparsityPattern::Build>(sp.release());
131 }

References _augment_sparsity_pattern, _coupling_functors, _dof_coupling, _extra_sparsity_context, _extra_sparsity_function, libMesh::DofMap::AugmentSparsityPattern::augment_sparsity_pattern(), libMesh::libmesh_assert(), mesh, n_dofs_on_processor(), need_full_sparsity_pattern, libMesh::out, libMesh::Threads::parallel_reduce(), and use_coupled_neighbor_dofs().

Referenced by compute_sparsity().

◆ check_dirichlet_bcid_consistency()

void libMesh::DofMap::check_dirichlet_bcid_consistency ( const MeshBase mesh,
const DirichletBoundary boundary 
) const
private

Check that all the ids in dirichlet_bcids are actually present in the mesh.

If not, this will throw an error.

Definition at line 4479 of file dof_map_constraints.C.

4481 {
4482  const std::set<boundary_id_type>& mesh_bcids = mesh.get_boundary_info().get_boundary_ids();
4483  const std::set<boundary_id_type>& dbc_bcids = boundary.b;
4484 
4485  // DirichletBoundary id sets should be consistent across all ranks
4486  libmesh_assert(mesh.comm().verify(dbc_bcids.size()));
4487 
4488  for (const auto & bc_id : dbc_bcids)
4489  {
4490  // DirichletBoundary id sets should be consistent across all ranks
4491  libmesh_assert(mesh.comm().verify(bc_id));
4492 
4493  bool found_bcid = (mesh_bcids.find(bc_id) != mesh_bcids.end());
4494 
4495  // On a distributed mesh, boundary id sets may *not* be
4496  // consistent across all ranks, since not all ranks see all
4497  // boundaries
4498  mesh.comm().max(found_bcid);
4499 
4500  if (!found_bcid)
4501  libmesh_error_msg("Could not find Dirichlet boundary id " << bc_id << " in mesh!");
4502  }
4503 }

References libMesh::DirichletBoundary::b, libMesh::ParallelObject::comm(), libMesh::BoundaryInfo::get_boundary_ids(), libMesh::MeshBase::get_boundary_info(), libMesh::libmesh_assert(), and mesh.

Referenced by create_dof_constraints().

◆ check_for_constraint_loops()

void libMesh::DofMap::check_for_constraint_loops ( )

Definition at line 3447 of file dof_map_constraints.C.

3448 {
3449  // Create a set containing the DOFs we already depend on
3450  typedef std::set<dof_id_type> RCSet;
3451  RCSet unexpanded_set;
3452 
3453  // Use dof_constraints_copy in this method so that we don't
3454  // mess with _dof_constraints.
3455  DofConstraints dof_constraints_copy = _dof_constraints;
3456 
3457  for (const auto & i : dof_constraints_copy)
3458  unexpanded_set.insert(i.first);
3459 
3460  while (!unexpanded_set.empty())
3461  for (RCSet::iterator i = unexpanded_set.begin();
3462  i != unexpanded_set.end(); /* nothing */)
3463  {
3464  // If the DOF is constrained
3465  DofConstraints::iterator
3466  pos = dof_constraints_copy.find(*i);
3467 
3468  libmesh_assert (pos != dof_constraints_copy.end());
3469 
3470  DofConstraintRow & constraint_row = pos->second;
3471 
3472  // Comment out "rhs" parts of this method copied from process_constraints
3473  // DofConstraintValueMap::iterator rhsit =
3474  // _primal_constraint_values.find(*i);
3475  // Number constraint_rhs = (rhsit == _primal_constraint_values.end()) ?
3476  // 0 : rhsit->second;
3477 
3478  std::vector<dof_id_type> constraints_to_expand;
3479 
3480  for (const auto & item : constraint_row)
3481  if (item.first != *i && this->is_constrained_dof(item.first))
3482  {
3483  unexpanded_set.insert(item.first);
3484  constraints_to_expand.push_back(item.first);
3485  }
3486 
3487  for (const auto & expandable : constraints_to_expand)
3488  {
3489  const Real this_coef = constraint_row[expandable];
3490 
3491  DofConstraints::const_iterator
3492  subpos = dof_constraints_copy.find(expandable);
3493 
3494  libmesh_assert (subpos != dof_constraints_copy.end());
3495 
3496  const DofConstraintRow & subconstraint_row = subpos->second;
3497 
3498  for (const auto & item : subconstraint_row)
3499  {
3500  if (item.first == expandable)
3501  libmesh_error_msg("Constraint loop detected");
3502 
3503  constraint_row[item.first] += item.second * this_coef;
3504  }
3505 
3506  // Comment out "rhs" parts of this method copied from process_constraints
3507  // DofConstraintValueMap::const_iterator subrhsit =
3508  // _primal_constraint_values.find(expandable);
3509  // if (subrhsit != _primal_constraint_values.end())
3510  // constraint_rhs += subrhsit->second * this_coef;
3511 
3512  constraint_row.erase(expandable);
3513  }
3514 
3515  // Comment out "rhs" parts of this method copied from process_constraints
3516  // if (rhsit == _primal_constraint_values.end())
3517  // {
3518  // if (constraint_rhs != Number(0))
3519  // _primal_constraint_values[*i] = constraint_rhs;
3520  // else
3521  // _primal_constraint_values.erase(*i);
3522  // }
3523  // else
3524  // {
3525  // if (constraint_rhs != Number(0))
3526  // rhsit->second = constraint_rhs;
3527  // else
3528  // _primal_constraint_values.erase(rhsit);
3529  // }
3530 
3531  if (constraints_to_expand.empty())
3532  i = unexpanded_set.erase(i);
3533  else
3534  ++i;
3535  }
3536 }

References _dof_constraints, libMesh::libmesh_assert(), and libMesh::Real.

Referenced by check_for_cyclic_constraints(), and process_constraints().

◆ check_for_cyclic_constraints()

void libMesh::DofMap::check_for_cyclic_constraints ( )

Throw an error if we detect any constraint loops, i.e.

A -> B -> C -> A that is, "dof A is constrained in terms of dof B which is constrained in terms of dof C which is constrained in terms of dof A", since these are not supported by libMesh and give erroneous results if they are present.

Note
The original "cyclic constraint" terminology was unfortunate since the word cyclic is used by some software to indicate an actual type of rotational/angular contraint and not (as here) a cyclic graph. The former nomenclature will eventually be deprecated in favor of "constraint loop".

Definition at line 3441 of file dof_map_constraints.C.

3442 {
3443  // Eventually make this officially libmesh_deprecated();
3445 }

References check_for_constraint_loops().

◆ clear()

void libMesh::DofMap::clear ( )

Free all new memory associated with the object, but restore its original state, with the mesh pointer and any default ghosting.

Definition at line 834 of file dof_map.C.

835 {
836  // we don't want to clear
837  // the coupling matrix!
838  // It should not change...
839  //_dof_coupling->clear();
840  //
841  // But it would be inconsistent to leave our coupling settings
842  // through a clear()...
843  _dof_coupling = nullptr;
844 
845  // Reset ghosting functor statuses
846  {
847  for (const auto & gf : _coupling_functors)
848  {
849  libmesh_assert(gf);
851  }
852  this->_coupling_functors.clear();
853 
854  // Go back to default coupling
855 
856  _default_coupling->set_dof_coupling(this->_dof_coupling);
857  _default_coupling->set_n_levels(this->use_coupled_neighbor_dofs(this->_mesh));
858 
860  }
861 
862 
863  {
864  for (const auto & gf : _algebraic_ghosting_functors)
865  {
866  libmesh_assert(gf);
868  }
869  this->_algebraic_ghosting_functors.clear();
870 
871  // Go back to default send_list generation
872 
873  // _default_evaluating->set_dof_coupling(this->_dof_coupling);
874  _default_evaluating->set_n_levels(1);
876  }
877 
878  this->_shared_functors.clear();
879 
880  _variables.clear();
881  _variable_groups.clear();
882  _variable_group_numbers.clear();
883  _first_df.clear();
884  _end_df.clear();
885  _first_scalar_df.clear();
886  this->clear_send_list();
887  this->clear_sparsity();
889 
890 #ifdef LIBMESH_ENABLE_AMR
891 
892  _dof_constraints.clear();
893  _stashed_dof_constraints.clear();
896  _n_old_dfs = 0;
897  _first_old_df.clear();
898  _end_old_df.clear();
899  _first_old_scalar_df.clear();
900 
901 #endif
902 
903  _matrices.clear();
904 
905  _n_dfs = 0;
906 }

References _adjoint_constraint_values, _algebraic_ghosting_functors, _coupling_functors, _default_coupling, _default_evaluating, _dof_constraints, _dof_coupling, _end_df, _end_old_df, _first_df, _first_old_df, _first_old_scalar_df, _first_scalar_df, _matrices, _mesh, _n_dfs, _n_old_dfs, _primal_constraint_values, _shared_functors, _stashed_dof_constraints, _variable_group_numbers, _variable_groups, _variables, add_algebraic_ghosting_functor(), add_coupling_functor(), clear_send_list(), clear_sparsity(), libMesh::libmesh_assert(), need_full_sparsity_pattern, libMesh::MeshBase::remove_ghosting_functor(), and use_coupled_neighbor_dofs().

Referenced by ~DofMap().

◆ clear_send_list()

void libMesh::DofMap::clear_send_list ( )
inline

Clears the _send_list vector.

This should be done in order to completely rebuild the send_list from scratch rather than merely adding to the existing send_list.

Definition at line 470 of file dof_map.h.

471  {
472  _send_list.clear();
473  }

References _send_list.

Referenced by clear(), distribute_dofs(), and reinit_send_list().

◆ clear_sparsity()

void libMesh::DofMap::clear_sparsity ( )

Clears the sparsity pattern.

Definition at line 1800 of file dof_map.C.

1801 {
1803  {
1804  libmesh_assert(_sp.get());
1805  libmesh_assert(!_n_nz || _n_nz == &_sp->n_nz);
1806  libmesh_assert(!_n_oz || _n_oz == &_sp->n_oz);
1807  _sp.reset();
1808  }
1809  else
1810  {
1811  libmesh_assert(!_sp.get());
1812  delete _n_nz;
1813  delete _n_oz;
1814  }
1815  _n_nz = nullptr;
1816  _n_oz = nullptr;
1817 }

References _n_nz, _n_oz, _sp, libMesh::libmesh_assert(), and need_full_sparsity_pattern.

Referenced by clear(), libMesh::EigenSystem::reinit(), libMesh::ImplicitSystem::reinit(), and OverlappingCouplingGhostingTest::run_sparsity_pattern_test().

◆ comm()

const Parallel::Communicator& libMesh::ParallelObject::comm ( ) const
inlineinherited
Returns
A reference to the Parallel::Communicator object used by this mesh.

Definition at line 94 of file parallel_object.h.

95  { return _communicator; }

References libMesh::ParallelObject::_communicator.

Referenced by libMesh::__libmesh_petsc_diff_solver_jacobian(), libMesh::__libmesh_petsc_diff_solver_monitor(), libMesh::__libmesh_petsc_diff_solver_residual(), libMesh::__libmesh_tao_equality_constraints(), libMesh::__libmesh_tao_equality_constraints_jacobian(), libMesh::__libmesh_tao_gradient(), libMesh::__libmesh_tao_hessian(), libMesh::__libmesh_tao_inequality_constraints(), libMesh::__libmesh_tao_inequality_constraints_jacobian(), libMesh::__libmesh_tao_objective(), libMesh::MeshRefinement::_coarsen_elements(), libMesh::ExactSolution::_compute_error(), libMesh::UniformRefinementEstimator::_estimate_error(), libMesh::BoundaryInfo::_find_id_maps(), libMesh::PetscLinearSolver< Number >::_petsc_shell_matrix_get_diagonal(), libMesh::SlepcEigenSolver< libMesh::Number >::_petsc_shell_matrix_get_diagonal(), libMesh::PetscLinearSolver< Number >::_petsc_shell_matrix_mult(), libMesh::SlepcEigenSolver< libMesh::Number >::_petsc_shell_matrix_mult(), libMesh::PetscLinearSolver< Number >::_petsc_shell_matrix_mult_add(), libMesh::EquationSystems::_read_impl(), libMesh::MeshRefinement::_refine_elements(), libMesh::MeshRefinement::_smooth_flags(), add_constraints_to_send_list(), add_cube_convex_hull_to_mesh(), libMesh::PetscDMWrapper::add_dofs_helper(), libMesh::PetscDMWrapper::add_dofs_to_section(), libMesh::TransientRBConstruction::add_IC_to_RB_space(), libMesh::ImplicitSystem::add_matrix(), libMesh::RBConstruction::add_scaled_matrix_and_vector(), libMesh::DynaIO::add_spline_constraints(), libMesh::System::add_vector(), libMesh::UnstructuredMesh::all_second_order(), libMesh::MeshTools::Modification::all_tri(), libMesh::LaplaceMeshSmoother::allgather_graph(), allgather_recursive_constraints(), libMesh::TransientRBConstruction::allocate_data_structures(), libMesh::RBConstruction::allocate_data_structures(), libMesh::TransientRBConstruction::assemble_affine_expansion(), libMesh::FEMSystem::assemble_qoi(), libMesh::MeshCommunication::assign_global_indices(), attach_matrix(), libMesh::MeshTools::Generation::build_extrusion(), libMesh::BoundaryInfo::build_node_list_from_side_list(), libMesh::EquationSystems::build_parallel_elemental_solution_vector(), libMesh::EquationSystems::build_parallel_solution_vector(), libMesh::PetscDMWrapper::build_section(), libMesh::PetscDMWrapper::build_sf(), libMesh::System::calculate_norm(), check_dirichlet_bcid_consistency(), libMesh::RBConstruction::compute_Fq_representor_innerprods(), libMesh::RBConstruction::compute_max_error_bound(), libMesh::Nemesis_IO_Helper::compute_num_global_elem_blocks(), libMesh::Nemesis_IO_Helper::compute_num_global_nodesets(), libMesh::Nemesis_IO_Helper::compute_num_global_sidesets(), libMesh::RBConstruction::compute_output_dual_innerprods(), libMesh::RBConstruction::compute_residual_dual_norm_slow(), libMesh::RBSCMConstruction::compute_SCM_bounds_on_training_set(), libMesh::Problem_Interface::computeF(), libMesh::Problem_Interface::computeJacobian(), libMesh::Problem_Interface::computePreconditioner(), libMesh::ExodusII_IO::copy_elemental_solution(), libMesh::ExodusII_IO::copy_scalar_solution(), libMesh::MeshTools::correct_node_proc_ids(), libMesh::MeshTools::create_bounding_box(), create_dof_constraints(), libMesh::MeshTools::create_nodal_bounding_box(), libMesh::MeshRefinement::create_parent_error_vector(), libMesh::MeshTools::create_processor_bounding_box(), libMesh::MeshTools::create_subdomain_bounding_box(), libMesh::MeshCommunication::delete_remote_elements(), distribute_dofs(), DMlibMeshFunction(), DMlibMeshJacobian(), DMlibMeshSetSystem_libMesh(), DMVariableBounds_libMesh(), libMesh::DTKSolutionTransfer::DTKSolutionTransfer(), libMesh::MeshRefinement::eliminate_unrefined_patches(), libMesh::RBEIMConstruction::enrich_RB_space(), libMesh::TransientRBConstruction::enrich_RB_space(), libMesh::RBConstruction::enrich_RB_space(), libMesh::EpetraVector< T >::EpetraVector(), AssembleOptimization::equality_constraints(), libMesh::WeightedPatchRecoveryErrorEstimator::estimate_error(), libMesh::PatchRecoveryErrorEstimator::estimate_error(), libMesh::JumpErrorEstimator::estimate_error(), libMesh::AdjointRefinementEstimator::estimate_error(), libMesh::ExactErrorEstimator::estimate_error(), libMesh::RBEIMConstruction::evaluate_mesh_function(), libMesh::MeshRefinement::flag_elements_by_elem_fraction(), libMesh::MeshRefinement::flag_elements_by_error_fraction(), libMesh::MeshRefinement::flag_elements_by_error_tolerance(), libMesh::MeshRefinement::flag_elements_by_mean_stddev(), libMesh::MeshRefinement::flag_elements_by_nelem_target(), gather_constraints(), libMesh::MeshfreeInterpolation::gather_remote_data(), libMesh::CondensedEigenSystem::get_eigenpair(), get_info(), libMesh::ImplicitSystem::get_linear_solver(), AssembleOptimization::inequality_constraints(), AssembleOptimization::inequality_constraints_jacobian(), libMesh::LocationMap< T >::init(), libMesh::TimeSolver::init(), libMesh::SystemSubsetBySubdomain::init(), libMesh::PetscDMWrapper::init_and_attach_petscdm(), libMesh::EigenSystem::init_matrices(), libMesh::OptimizationSystem::initialize_equality_constraints_storage(), libMesh::OptimizationSystem::initialize_inequality_constraints_storage(), libMesh::RBEIMConstruction::initialize_rb_construction(), integrate_function(), libMesh::MeshTools::libmesh_assert_consistent_distributed(), libMesh::MeshTools::libmesh_assert_consistent_distributed_nodes(), libMesh::MeshTools::libmesh_assert_contiguous_dof_ids(), libMesh::MeshTools::libmesh_assert_parallel_consistent_new_node_procids(), libMesh::MeshTools::libmesh_assert_parallel_consistent_procids< Elem >(), libMesh::MeshTools::libmesh_assert_parallel_consistent_procids< Node >(), libMesh::MeshTools::libmesh_assert_topology_consistent_procids< Node >(), libMesh::MeshTools::libmesh_assert_valid_boundary_ids(), libMesh::MeshTools::libmesh_assert_valid_dof_ids(), libMesh::MeshTools::libmesh_assert_valid_neighbors(), libMesh::DistributedMesh::libmesh_assert_valid_parallel_flags(), libMesh::DistributedMesh::libmesh_assert_valid_parallel_object_ids(), libMesh::DistributedMesh::libmesh_assert_valid_parallel_p_levels(), libMesh::MeshTools::libmesh_assert_valid_refinement_flags(), libMesh::MeshTools::libmesh_assert_valid_unique_ids(), libMesh::libmesh_petsc_preconditioner_apply(), libMesh::libmesh_petsc_snes_fd_residual(), libMesh::libmesh_petsc_snes_jacobian(), libMesh::libmesh_petsc_snes_mffd_residual(), libMesh::libmesh_petsc_snes_postcheck(), libMesh::libmesh_petsc_snes_residual(), libMesh::libmesh_petsc_snes_residual_helper(), libMesh::MeshRefinement::limit_level_mismatch_at_edge(), libMesh::MeshRefinement::limit_level_mismatch_at_node(), libMesh::MeshRefinement::limit_overrefined_boundary(), libMesh::MeshRefinement::limit_underrefined_boundary(), main(), libMesh::MeshRefinement::make_coarsening_compatible(), libMesh::MeshCommunication::make_elems_parallel_consistent(), libMesh::MeshRefinement::make_flags_parallel_consistent(), libMesh::MeshCommunication::make_new_node_proc_ids_parallel_consistent(), libMesh::MeshCommunication::make_new_nodes_parallel_consistent(), libMesh::MeshCommunication::make_node_ids_parallel_consistent(), libMesh::MeshCommunication::make_node_proc_ids_parallel_consistent(), libMesh::MeshCommunication::make_node_unique_ids_parallel_consistent(), libMesh::MeshCommunication::make_nodes_parallel_consistent(), libMesh::MeshCommunication::make_p_levels_parallel_consistent(), libMesh::MeshRefinement::make_refinement_compatible(), libMesh::TransientRBConstruction::mass_matrix_scaled_matvec(), libMesh::FEMSystem::mesh_position_set(), LinearElasticityWithContact::move_mesh(), libMesh::DistributedMesh::n_active_elem(), libMesh::MeshTools::n_active_levels(), libMesh::BoundaryInfo::n_boundary_conds(), n_constrained_dofs(), libMesh::BoundaryInfo::n_edge_conds(), libMesh::CondensedEigenSystem::n_global_non_condensed_dofs(), libMesh::MeshTools::n_levels(), libMesh::BoundaryInfo::n_nodeset_conds(), libMesh::MeshTools::n_p_levels(), libMesh::BoundaryInfo::n_shellface_conds(), libMesh::DistributedMesh::parallel_max_elem_id(), libMesh::DistributedMesh::parallel_max_node_id(), libMesh::ReplicatedMesh::parallel_max_unique_id(), libMesh::DistributedMesh::parallel_max_unique_id(), libMesh::DistributedMesh::parallel_n_elem(), libMesh::DistributedMesh::parallel_n_nodes(), libMesh::SparsityPattern::Build::parallel_sync(), libMesh::MeshTools::paranoid_n_levels(), libMesh::petsc_auto_fieldsplit(), libMesh::System::point_gradient(), libMesh::System::point_hessian(), libMesh::System::point_value(), print_dof_constraints(), FEMParameters::read(), libMesh::Nemesis_IO::read(), libMesh::XdrIO::read(), libMesh::CheckpointIO::read_header(), libMesh::XdrIO::read_header(), libMesh::System::read_header(), libMesh::RBEvaluation::read_in_vectors_from_multiple_files(), libMesh::System::read_legacy_data(), libMesh::TransientRBConstruction::read_riesz_representors_from_files(), libMesh::RBConstruction::read_riesz_representors_from_files(), libMesh::System::read_SCALAR_dofs(), libMesh::XdrIO::read_serialized_bc_names(), libMesh::XdrIO::read_serialized_bcs_helper(), libMesh::System::read_serialized_blocked_dof_objects(), libMesh::XdrIO::read_serialized_connectivity(), libMesh::XdrIO::read_serialized_nodes(), libMesh::XdrIO::read_serialized_nodesets(), libMesh::XdrIO::read_serialized_subdomain_names(), libMesh::System::read_serialized_vector(), libMesh::MeshRefinement::refine_and_coarsen_elements(), libMesh::DistributedMesh::renumber_dof_objects(), LinearElasticityWithContact::residual_and_jacobian(), OverlappingAlgebraicGhostingTest::run_ghosting_test(), OverlappingCouplingGhostingTest::run_sparsity_pattern_test(), scatter_constraints(), libMesh::CheckpointIO::select_split_config(), libMesh::TransientRBConstruction::set_error_temporal_data(), libMesh::RBEIMConstruction::set_explicit_sys_subvector(), set_nonlocal_dof_objects(), libMesh::PetscDMWrapper::set_point_range_in_section(), libMesh::PetscDiffSolver::setup_petsc_data(), libMesh::LaplaceMeshSmoother::smooth(), libMesh::split_mesh(), libMesh::BoundaryInfo::sync(), libMesh::MeshRefinement::test_level_one(), MeshfunctionDFEM::test_mesh_function_dfem(), MeshfunctionDFEM::test_mesh_function_dfem_grad(), MeshFunctionTest::test_p_level(), libMesh::MeshRefinement::test_unflagged(), SystemsTest::testBlockRestrictedVarNDofs(), PointLocatorTest::testLocator(), BoundaryInfoTest::testMesh(), SystemsTest::testProjectCubeWithMeshFunction(), CheckpointIOTest::testSplitter(), libMesh::MeshTools::total_weight(), libMesh::MeshFunctionSolutionTransfer::transfer(), libMesh::MeshfreeSolutionTransfer::transfer(), libMesh::TransientRBConstruction::truth_assembly(), libMesh::RBConstruction::truth_assembly(), libMesh::MeshRefinement::uniformly_coarsen(), libMesh::TransientRBConstruction::update_RB_initial_condition_all_N(), libMesh::RBEIMConstruction::update_RB_system_matrices(), libMesh::TransientRBConstruction::update_RB_system_matrices(), libMesh::RBConstruction::update_RB_system_matrices(), libMesh::TransientRBConstruction::update_residual_terms(), libMesh::RBConstruction::update_residual_terms(), libMesh::NameBasedIO::write(), libMesh::XdrIO::write(), libMesh::VTKIO::write_nodal_data(), libMesh::RBEvaluation::write_out_vectors(), libMesh::TransientRBConstruction::write_riesz_representors_to_files(), libMesh::RBConstruction::write_riesz_representors_to_files(), libMesh::System::write_SCALAR_dofs(), libMesh::XdrIO::write_serialized_bcs_helper(), libMesh::System::write_serialized_blocked_dof_objects(), libMesh::XdrIO::write_serialized_connectivity(), libMesh::XdrIO::write_serialized_nodes(), libMesh::XdrIO::write_serialized_nodesets(), libMesh::RBDataSerialization::RBEvaluationSerialization::write_to_file(), libMesh::RBDataSerialization::TransientRBEvaluationSerialization::write_to_file(), libMesh::RBDataSerialization::RBEIMEvaluationSerialization::write_to_file(), and libMesh::RBDataSerialization::RBSCMEvaluationSerialization::write_to_file().

◆ compute_sparsity()

void libMesh::DofMap::compute_sparsity ( const MeshBase mesh)

Computes the sparsity pattern for the matrices corresponding to proc_id and sends that data to Linear Algebra packages for preallocation of sparse matrices.

Definition at line 1768 of file dof_map.C.

1769 {
1770  _sp = this->build_sparsity(mesh);
1771 
1772  // It is possible that some \p SparseMatrix implementations want to
1773  // see the sparsity pattern before we throw it away. If so, we
1774  // share a view of its arrays, and we pass it in to the matrices.
1776  {
1777  _n_nz = &_sp->n_nz;
1778  _n_oz = &_sp->n_oz;
1779 
1780  for (const auto & mat : _matrices)
1781  mat->update_sparsity_pattern (_sp->sparsity_pattern);
1782  }
1783  // If we don't need the full sparsity pattern anymore, steal the
1784  // arrays we do need and free the rest of the memory
1785  else
1786  {
1787  if (!_n_nz)
1788  _n_nz = new std::vector<dof_id_type>();
1789  _n_nz->swap(_sp->n_nz);
1790  if (!_n_oz)
1791  _n_oz = new std::vector<dof_id_type>();
1792  _n_oz->swap(_sp->n_oz);
1793 
1794  _sp.reset();
1795  }
1796 }

References _matrices, _n_nz, _n_oz, _sp, build_sparsity(), and need_full_sparsity_pattern.

Referenced by libMesh::EigenSystem::init_matrices(), libMesh::ImplicitSystem::init_matrices(), libMesh::EigenSystem::reinit(), libMesh::ImplicitSystem::reinit(), and OverlappingCouplingGhostingTest::run_sparsity_pattern_test().

◆ constrain_element_dyad_matrix()

void libMesh::DofMap::constrain_element_dyad_matrix ( DenseVector< Number > &  v,
DenseVector< Number > &  w,
std::vector< dof_id_type > &  row_dofs,
bool  asymmetric_constraint_rows = true 
) const
inline

Constrains a dyadic element matrix B = v w'.

This method requires the element matrix to be square, in which case the elem_dofs correspond to the global DOF indices of both the rows and columns of the element matrix. For this case the rows and columns of the matrix necessarily correspond to variables of the same approximation order.

Definition at line 2047 of file dof_map.h.

2050  {}

Referenced by assemble().

◆ constrain_element_matrix() [1/2]

void libMesh::DofMap::constrain_element_matrix ( DenseMatrix< Number > &  matrix,
std::vector< dof_id_type > &  elem_dofs,
bool  asymmetric_constraint_rows = true 
) const
inline

Constrains the element matrix.

This method requires the element matrix to be square, in which case the elem_dofs correspond to the global DOF indices of both the rows and columns of the element matrix. For this case the rows and columns of the matrix necessarily correspond to variables of the same approximation order.

If asymmetric_constraint_rows is set to true (as it is by default), constraint row equations will be reinforced in a way which breaks matrix symmetry but makes inexact linear solver solutions more likely to satisfy hanging node constraints.

Definition at line 2021 of file dof_map.h.

2023  {}

Referenced by assemble_mass(), assemble_matrices(), assemble_SchroedingerEquation(), LargeDeformationElasticity::jacobian(), and Biharmonic::JR::residual_and_jacobian().

◆ constrain_element_matrix() [2/2]

void libMesh::DofMap::constrain_element_matrix ( DenseMatrix< Number > &  matrix,
std::vector< dof_id_type > &  row_dofs,
std::vector< dof_id_type > &  col_dofs,
bool  asymmetric_constraint_rows = true 
) const
inline

Constrains the element matrix.

This method allows the element matrix to be non-square, in which case the row_dofs and col_dofs may be of different size and correspond to variables approximated in different spaces.

Definition at line 2025 of file dof_map.h.

2028  {}

◆ constrain_element_matrix_and_vector()

void libMesh::DofMap::constrain_element_matrix_and_vector ( DenseMatrix< Number > &  matrix,
DenseVector< Number > &  rhs,
std::vector< dof_id_type > &  elem_dofs,
bool  asymmetric_constraint_rows = true 
) const
inline

Constrains the element matrix and vector.

This method requires the element matrix to be square, in which case the elem_dofs correspond to the global DOF indices of both the rows and columns of the element matrix. For this case the rows and columns of the matrix necessarily correspond to variables of the same approximation order.

Definition at line 2034 of file dof_map.h.

2037  {}

Referenced by libMesh::RBConstruction::add_scaled_matrix_and_vector(), assemble(), LinearElasticity::assemble(), AssembleOptimization::assemble_A_and_F(), assemble_cd(), assemble_elasticity(), assemble_shell(), assemble_stokes(), and LinearElasticityWithContact::residual_and_jacobian().

◆ constrain_element_vector()

void libMesh::DofMap::constrain_element_vector ( DenseVector< Number > &  rhs,
std::vector< dof_id_type > &  dofs,
bool  asymmetric_constraint_rows = true 
) const
inline

Constrains the element vector.

Definition at line 2030 of file dof_map.h.

2032  {}

Referenced by LargeDeformationElasticity::residual(), Biharmonic::JR::residual_and_jacobian(), and libMesh::RBEIMConstruction::truth_solve().

◆ constrain_nothing()

void libMesh::DofMap::constrain_nothing ( std::vector< dof_id_type > &  dofs) const
inline

Does not actually constrain anything, but modifies dofs in the same way as any of the constrain functions would do, i.e.

adds those dofs in terms of which any of the existing dofs is constrained.

Definition at line 2052 of file dof_map.h.

2052 {}

◆ constrain_p_dofs()

void libMesh::DofMap::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 to p refinement levels above p.

Definition at line 4325 of file dof_map_constraints.C.

4329 {
4330  // We're constraining dofs on elem which correspond to p refinement
4331  // levels above p - this only makes sense if elem's p refinement
4332  // level is above p.
4333  libmesh_assert_greater (elem->p_level(), p);
4334  libmesh_assert_less (s, elem->n_sides());
4335 
4336  const unsigned int sys_num = this->sys_number();
4337  const unsigned int dim = elem->dim();
4338  ElemType type = elem->type();
4339  FEType low_p_fe_type = this->variable_type(var);
4340  FEType high_p_fe_type = this->variable_type(var);
4341  low_p_fe_type.order = static_cast<Order>(low_p_fe_type.order + p);
4342  high_p_fe_type.order = static_cast<Order>(high_p_fe_type.order +
4343  elem->p_level());
4344 
4345  const unsigned int n_nodes = elem->n_nodes();
4346  for (unsigned int n = 0; n != n_nodes; ++n)
4347  if (elem->is_node_on_side(n, s))
4348  {
4349  const Node & node = elem->node_ref(n);
4350  const unsigned int low_nc =
4351  FEInterface::n_dofs_at_node (dim, low_p_fe_type, type, n);
4352  const unsigned int high_nc =
4353  FEInterface::n_dofs_at_node (dim, high_p_fe_type, type, n);
4354 
4355  // since we may be running this method concurrently
4356  // on multiple threads we need to acquire a lock
4357  // before modifying the _dof_constraints object.
4358  Threads::spin_mutex::scoped_lock lock(Threads::spin_mtx);
4359 
4360  if (elem->is_vertex(n))
4361  {
4362  // Add "this is zero" constraint rows for high p vertex
4363  // dofs
4364  for (unsigned int i = low_nc; i != high_nc; ++i)
4365  {
4366  _dof_constraints[node.dof_number(sys_num,var,i)].clear();
4367  _primal_constraint_values.erase(node.dof_number(sys_num,var,i));
4368  }
4369  }
4370  else
4371  {
4372  const unsigned int total_dofs = node.n_comp(sys_num, var);
4373  libmesh_assert_greater_equal (total_dofs, high_nc);
4374  // Add "this is zero" constraint rows for high p
4375  // non-vertex dofs, which are numbered in reverse
4376  for (unsigned int j = low_nc; j != high_nc; ++j)
4377  {
4378  const unsigned int i = total_dofs - j - 1;
4379  _dof_constraints[node.dof_number(sys_num,var,i)].clear();
4380  _primal_constraint_values.erase(node.dof_number(sys_num,var,i));
4381  }
4382  }
4383  }
4384 }

References _dof_constraints, _primal_constraint_values, dim, libMesh::Elem::dim(), libMesh::DofObject::dof_number(), libMesh::Elem::is_node_on_side(), libMesh::Elem::is_vertex(), libMesh::DofObject::n_comp(), libMesh::FEInterface::n_dofs_at_node(), n_nodes, libMesh::Elem::n_nodes(), libMesh::Elem::n_sides(), libMesh::Elem::node_ref(), libMesh::FEType::order, libMesh::Elem::p_level(), libMesh::Threads::spin_mtx, sys_number(), libMesh::Elem::type(), and variable_type().

Referenced by libMesh::FEGenericBase< FEOutputType< T >::type >::compute_periodic_constraints(), and libMesh::FEGenericBase< FEOutputType< T >::type >::compute_proj_constraints().

◆ constraint_rows_begin()

DofConstraints::const_iterator libMesh::DofMap::constraint_rows_begin ( ) const
inline
Returns
An iterator pointing to the first DoF constraint row.

Definition at line 989 of file dof_map.h.

990  { return _dof_constraints.begin(); }

References _dof_constraints.

◆ constraint_rows_end()

DofConstraints::const_iterator libMesh::DofMap::constraint_rows_end ( ) const
inline
Returns
An iterator pointing just past the last DoF constraint row.

Definition at line 995 of file dof_map.h.

996  { return _dof_constraints.end(); }

References _dof_constraints.

◆ coupling_functors_begin()

std::set<GhostingFunctor *>::const_iterator libMesh::DofMap::coupling_functors_begin ( ) const
inline

Beginning of range of coupling functors.

Definition at line 329 of file dof_map.h.

330  { return _coupling_functors.begin(); }

References _coupling_functors.

Referenced by add_neighbors_to_send_list(), libMesh::SparsityPattern::Build::operator()(), and scatter_constraints().

◆ coupling_functors_end()

std::set<GhostingFunctor *>::const_iterator libMesh::DofMap::coupling_functors_end ( ) const
inline

End of range of coupling functors.

Definition at line 335 of file dof_map.h.

336  { return _coupling_functors.end(); }

References _coupling_functors.

Referenced by add_neighbors_to_send_list(), libMesh::SparsityPattern::Build::operator()(), and scatter_constraints().

◆ create_dof_constraints()

void libMesh::DofMap::create_dof_constraints ( const MeshBase mesh,
Real  time = 0 
)

Rebuilds the raw degree of freedom and DofObject constraints.

A time is specified for use in building time-dependent Dirichlet constraints.

Definition at line 1206 of file dof_map_constraints.C.

1207 {
1208  parallel_object_only();
1209 
1210  LOG_SCOPE("create_dof_constraints()", "DofMap");
1211 
1213 
1214  // The user might have set boundary conditions after the mesh was
1215  // prepared; we should double-check that those boundary conditions
1216  // are still consistent.
1217 #ifdef DEBUG
1219 #endif
1220 
1221  // We might get constraint equations from AMR hanging nodes in 2D/3D
1222  // or from boundary conditions in any dimension
1223  const bool possible_local_constraints = false
1224  || !mesh.n_elem()
1225 #ifdef LIBMESH_ENABLE_AMR
1226  || mesh.mesh_dimension() > 1
1227 #endif
1228 #ifdef LIBMESH_ENABLE_PERIODIC
1229  || !_periodic_boundaries->empty()
1230 #endif
1231 #ifdef LIBMESH_ENABLE_DIRICHLET
1232  || !_dirichlet_boundaries->empty()
1233 #endif
1234  ;
1235 
1236  // Even if we don't have constraints, another processor might.
1237  bool possible_global_constraints = possible_local_constraints;
1238 #if defined(LIBMESH_ENABLE_PERIODIC) || defined(LIBMESH_ENABLE_DIRICHLET) || defined(LIBMESH_ENABLE_AMR)
1239  libmesh_assert(this->comm().verify(mesh.is_serial()));
1240 
1241  this->comm().max(possible_global_constraints);
1242 #endif
1243 
1244  if (!possible_global_constraints)
1245  {
1246  // Clear out any old constraints; maybe the user just deleted
1247  // their last remaining dirichlet/periodic/user constraint?
1248  // Note: any _stashed_dof_constraints are not cleared as it
1249  // may be the user's intention to restore them later.
1250 #ifdef LIBMESH_ENABLE_CONSTRAINTS
1251  _dof_constraints.clear();
1252  _primal_constraint_values.clear();
1254 #endif
1255 #ifdef LIBMESH_ENABLE_NODE_CONSTRAINTS
1256  _node_constraints.clear();
1257 #endif
1258 
1259  return;
1260  }
1261 
1262  // Here we build the hanging node constraints. This is done
1263  // by enforcing the condition u_a = u_b along hanging sides.
1264  // u_a = u_b is collocated at the nodes of side a, which gives
1265  // one row of the constraint matrix.
1266 
1267  // Processors only compute their local constraints
1270 
1271  // Global computation fails if we're using a FEMFunctionBase BC on a
1272  // ReplicatedMesh in parallel
1273  // ConstElemRange range (mesh.elements_begin(),
1274  // mesh.elements_end());
1275 
1276  // compute_periodic_constraints requires a point_locator() from our
1277  // Mesh, but point_locator() construction is parallel and threaded.
1278  // Rather than nest threads within threads we'll make sure it's
1279  // preconstructed.
1280 #ifdef LIBMESH_ENABLE_PERIODIC
1281  bool need_point_locator = !_periodic_boundaries->empty() && !range.empty();
1282 
1283  this->comm().max(need_point_locator);
1284 
1285  if (need_point_locator)
1287 #endif
1288 
1289 #ifdef LIBMESH_ENABLE_NODE_CONSTRAINTS
1290  // recalculate node constraints from scratch
1291  _node_constraints.clear();
1292 
1293  Threads::parallel_for (range,
1294  ComputeNodeConstraints (_node_constraints,
1295 #ifdef LIBMESH_ENABLE_PERIODIC
1297 #endif
1298  mesh));
1299 #endif // LIBMESH_ENABLE_NODE_CONSTRAINTS
1300 
1301 
1302  // recalculate dof constraints from scratch
1303  // Note: any _stashed_dof_constraints are not cleared as it
1304  // may be the user's intention to restore them later.
1305  _dof_constraints.clear();
1306  _primal_constraint_values.clear();
1308 
1309  // Look at all the variables in the system. Reset the element
1310  // range at each iteration -- there is no need to reconstruct it.
1311  for (unsigned int variable_number=0; variable_number<this->n_variables();
1312  ++variable_number, range.reset())
1313  Threads::parallel_for (range,
1314  ComputeConstraints (_dof_constraints,
1315  *this,
1316 #ifdef LIBMESH_ENABLE_PERIODIC
1318 #endif
1319  mesh,
1320  variable_number));
1321 
1322 #ifdef LIBMESH_ENABLE_DIRICHLET
1323  for (DirichletBoundaries::iterator
1324  i = _dirichlet_boundaries->begin();
1325  i != _dirichlet_boundaries->end(); ++i, range.reset())
1326  {
1327  // Sanity check that the boundary ids associated with the DirichletBoundary
1328  // objects are actually present in the mesh
1329  this->check_dirichlet_bcid_consistency(mesh,**i);
1330 
1332  (range,
1333  ConstrainDirichlet(*this, mesh, time, **i,
1334  AddPrimalConstraint(*this))
1335  );
1336  }
1337 
1338  for (unsigned int qoi_index = 0,
1339  n_qois = cast_int<unsigned int>(_adjoint_dirichlet_boundaries.size());
1340  qoi_index != n_qois; ++qoi_index)
1341  {
1342  for (DirichletBoundaries::iterator
1343  i = _adjoint_dirichlet_boundaries[qoi_index]->begin();
1344  i != _adjoint_dirichlet_boundaries[qoi_index]->end();
1345  ++i, range.reset())
1346  {
1347  // Sanity check that the boundary ids associated with the DirichletBoundary
1348  // objects are actually present in the mesh
1349  this->check_dirichlet_bcid_consistency(mesh,**i);
1350 
1352  (range,
1353  ConstrainDirichlet(*this, mesh, time, **i,
1354  AddAdjointConstraint(*this, qoi_index))
1355  );
1356  }
1357  }
1358 
1359 #endif // LIBMESH_ENABLE_DIRICHLET
1360 }

References _adjoint_constraint_values, _adjoint_dirichlet_boundaries, _dirichlet_boundaries, _dof_constraints, _node_constraints, _periodic_boundaries, _primal_constraint_values, check_dirichlet_bcid_consistency(), libMesh::ParallelObject::comm(), libMesh::StoredRange< iterator_type, object_type >::empty(), libMesh::MeshBase::is_prepared(), libMesh::MeshBase::is_serial(), libMesh::libmesh_assert(), libMesh::MeshTools::libmesh_assert_valid_boundary_ids(), libMesh::MeshBase::local_elements_begin(), libMesh::MeshBase::local_elements_end(), mesh, libMesh::MeshBase::mesh_dimension(), libMesh::MeshBase::n_elem(), n_variables(), libMesh::Threads::parallel_for(), libMesh::StoredRange< iterator_type, object_type >::reset(), and libMesh::MeshBase::sub_point_locator().

Referenced by libMesh::System::reinit_constraints().

◆ default_algebraic_ghosting()

DefaultCoupling& libMesh::DofMap::default_algebraic_ghosting ( )
inline

Default algebraic ghosting functor.

Definition at line 403 of file dof_map.h.

403 { return *_default_evaluating; }

References _default_evaluating.

Referenced by add_default_ghosting(), remove_default_ghosting(), DefaultCouplingTest::testCoupling(), and PointNeighborCouplingTest::testCoupling().

◆ default_coupling()

DefaultCoupling& libMesh::DofMap::default_coupling ( )
inline

Default coupling functor.

Definition at line 341 of file dof_map.h.

341 { return *_default_coupling; }

References _default_coupling.

Referenced by add_default_ghosting(), remove_default_ghosting(), and PointNeighborCouplingTest::testCoupling().

◆ disable_print_counter_info()

void libMesh::ReferenceCounter::disable_print_counter_info ( )
staticinherited

Definition at line 106 of file reference_counter.C.

107 {
108  _enable_print_counter = false;
109  return;
110 }

References libMesh::ReferenceCounter::_enable_print_counter.

Referenced by libMesh::LibMeshInit::LibMeshInit().

◆ distribute_dofs()

void libMesh::DofMap::distribute_dofs ( MeshBase mesh)

Distribute dofs on the current mesh.

Also builds the send list for processor proc_id, which defaults to 0 for ease of use in serial applications.

Definition at line 910 of file dof_map.C.

911 {
912  // This function must be run on all processors at once
913  parallel_object_only();
914 
915  // Log how long it takes to distribute the degrees of freedom
916  LOG_SCOPE("distribute_dofs()", "DofMap");
917 
918  libmesh_assert (mesh.is_prepared());
919 
920  const processor_id_type proc_id = this->processor_id();
921  const processor_id_type n_proc = this->n_processors();
922 
923  // libmesh_assert_greater (this->n_variables(), 0);
924  libmesh_assert_less (proc_id, n_proc);
925 
926  // re-init in case the mesh has changed
927  this->reinit(mesh);
928 
929  // By default distribute variables in a
930  // var-major fashion, but allow run-time
931  // specification
932  bool node_major_dofs = libMesh::on_command_line ("--node-major-dofs");
933 
934  // The DOF counter, will be incremented as we encounter
935  // new degrees of freedom
936  dof_id_type next_free_dof = 0;
937 
938  // Clear the send list before we rebuild it
939  this->clear_send_list();
940 
941  // Set temporary DOF indices on this processor
942  if (node_major_dofs)
943  this->distribute_local_dofs_node_major (next_free_dof, mesh);
944  else
945  this->distribute_local_dofs_var_major (next_free_dof, mesh);
946 
947  // Get DOF counts on all processors
948  std::vector<dof_id_type> dofs_on_proc(n_proc, 0);
949  this->comm().allgather(next_free_dof, dofs_on_proc);
950 
951  // Resize and fill the _first_df and _end_df arrays
952 #ifdef LIBMESH_ENABLE_AMR
955 #endif
956 
957  _first_df.resize(n_proc);
958  _end_df.resize (n_proc);
959 
960  // Get DOF offsets
961  _first_df[0] = 0;
962  for (processor_id_type i=1; i < n_proc; ++i)
963  _first_df[i] = _end_df[i-1] = _first_df[i-1] + dofs_on_proc[i-1];
964  _end_df[n_proc-1] = _first_df[n_proc-1] + dofs_on_proc[n_proc-1];
965 
966  // Clear all the current DOF indices
967  // (distribute_dofs expects them cleared!)
968  this->invalidate_dofs(mesh);
969 
970  next_free_dof = _first_df[proc_id];
971 
972  // Set permanent DOF indices on this processor
973  if (node_major_dofs)
974  this->distribute_local_dofs_node_major (next_free_dof, mesh);
975  else
976  this->distribute_local_dofs_var_major (next_free_dof, mesh);
977 
978  libmesh_assert_equal_to (next_free_dof, _end_df[proc_id]);
979 
980  //------------------------------------------------------------
981  // At this point, all n_comp and dof_number values on local
982  // DofObjects should be correct, but a DistributedMesh might have
983  // incorrect values on non-local DofObjects. Let's request the
984  // correct values from each other processor.
985 
986  if (this->n_processors() > 1)
987  {
988  this->set_nonlocal_dof_objects(mesh.nodes_begin(),
989  mesh.nodes_end(),
991 
992  this->set_nonlocal_dof_objects(mesh.elements_begin(),
993  mesh.elements_end(),
995  }
996 
997 #ifdef DEBUG
998  {
999  const unsigned int
1000  sys_num = this->sys_number();
1001 
1002  // Processors should all agree on DoF ids for the newly numbered
1003  // system.
1005 
1006  // DoF processor ids should match DofObject processor ids
1007  for (auto & node : mesh.node_ptr_range())
1008  {
1009  DofObject const * const dofobj = node;
1010  const processor_id_type obj_proc_id = dofobj->processor_id();
1011 
1012  for (auto v : IntRange<unsigned int>(0, dofobj->n_vars(sys_num)))
1013  for (auto c : IntRange<unsigned int>(0, dofobj->n_comp(sys_num,v)))
1014  {
1015  const dof_id_type dofid = dofobj->dof_number(sys_num,v,c);
1016  libmesh_assert_greater_equal (dofid, this->first_dof(obj_proc_id));
1017  libmesh_assert_less (dofid, this->end_dof(obj_proc_id));
1018  }
1019  }
1020 
1021  for (auto & elem : mesh.element_ptr_range())
1022  {
1023  DofObject const * const dofobj = elem;
1024  const processor_id_type obj_proc_id = dofobj->processor_id();
1025 
1026  for (auto v : IntRange<unsigned int>(0, dofobj->n_vars(sys_num)))
1027  for (auto c : IntRange<unsigned int>(0, dofobj->n_comp(sys_num,v)))
1028  {
1029  const dof_id_type dofid = dofobj->dof_number(sys_num,v,c);
1030  libmesh_assert_greater_equal (dofid, this->first_dof(obj_proc_id));
1031  libmesh_assert_less (dofid, this->end_dof(obj_proc_id));
1032  }
1033  }
1034  }
1035 #endif
1036 
1037  // Set the total number of degrees of freedom, then start finding
1038  // SCALAR degrees of freedom
1039 #ifdef LIBMESH_ENABLE_AMR
1040  _n_old_dfs = _n_dfs;
1042 #endif
1043  _n_dfs = _end_df[n_proc-1];
1044  _first_scalar_df.clear();
1046  dof_id_type current_SCALAR_dof_index = n_dofs() - n_SCALAR_dofs();
1047 
1048  // Calculate and cache the initial DoF indices for SCALAR variables.
1049  // This is an O(N_vars) calculation so we want to do it once per
1050  // renumbering rather than once per SCALAR_dof_indices() call
1051 
1052  for (auto v : IntRange<unsigned int>(0, this->n_variables()))
1053  if (this->variable(v).type().family == SCALAR)
1054  {
1055  _first_scalar_df[v] = current_SCALAR_dof_index;
1056  current_SCALAR_dof_index += this->variable(v).type().order.get_order();
1057  }
1058 
1059  // Allow our GhostingFunctor objects to reinit if necessary
1060  for (const auto & gf : _algebraic_ghosting_functors)
1061  {
1062  libmesh_assert(gf);
1063  gf->dofmap_reinit();
1064  }
1065 
1066  for (const auto & gf : _coupling_functors)
1067  {
1068  libmesh_assert(gf);
1069  gf->dofmap_reinit();
1070  }
1071 
1072  // Note that in the add_neighbors_to_send_list nodes on processor
1073  // boundaries that are shared by multiple elements are added for
1074  // each element.
1076 
1077  // Here we used to clean up that data structure; now System and
1078  // EquationSystems call that for us, after we've added constraint
1079  // dependencies to the send_list too.
1080  // this->sort_send_list ();
1081 }

References _algebraic_ghosting_functors, _coupling_functors, _end_df, _end_old_df, _first_df, _first_old_df, _first_old_scalar_df, _first_scalar_df, _n_dfs, _n_old_dfs, add_neighbors_to_send_list(), clear_send_list(), libMesh::ParallelObject::comm(), distribute_local_dofs_node_major(), distribute_local_dofs_var_major(), libMesh::DofObject::dof_number(), elem_ptr(), libMesh::MeshBase::elements_begin(), end_dof(), first_dof(), libMesh::OrderWrapper::get_order(), libMesh::DofObject::invalid_id, invalidate_dofs(), libMesh::libmesh_assert(), libMesh::MeshTools::libmesh_assert_valid_dof_ids(), mesh, libMesh::DofObject::n_comp(), n_dofs(), libMesh::ParallelObject::n_processors(), n_SCALAR_dofs(), n_variables(), libMesh::DofObject::n_vars(), node_ptr(), libMesh::MeshBase::nodes_begin(), libMesh::on_command_line(), libMesh::FEType::order, libMesh::ParallelObject::processor_id(), libMesh::DofObject::processor_id(), reinit(), libMesh::SCALAR, set_nonlocal_dof_objects(), sys_number(), libMesh::Variable::type(), and variable().

Referenced by libMesh::EquationSystems::allgather(), libMesh::PetscDMWrapper::init_and_attach_petscdm(), libMesh::EquationSystems::reinit_solutions(), SystemsTest::testProjectMatrix1D(), SystemsTest::testProjectMatrix2D(), and SystemsTest::testProjectMatrix3D().

◆ distribute_local_dofs_node_major()

void libMesh::DofMap::distribute_local_dofs_node_major ( dof_id_type next_free_dof,
MeshBase mesh 
)
private

Distributes the global degrees of freedom for dofs on this processor.

In this format all the degrees of freedom at a node/element are in contiguous blocks. Starts at index next_free_dof, and increments it to the post-final index. If build_send_list is true, builds the send list. If false, clears and reserves the send list.

Note
The degrees of freedom for a given variable are not in contiguous blocks, as in the case of distribute_local_dofs_var_major.

Definition at line 1171 of file dof_map.C.

1173 {
1174  const unsigned int sys_num = this->sys_number();
1175  const unsigned int n_var_groups = this->n_variable_groups();
1176 
1177  // Our numbering here must be kept consistent with the numbering
1178  // scheme assumed by DofMap::local_variable_indices!
1179 
1180  //-------------------------------------------------------------------------
1181  // First count and assign temporary numbers to local dofs
1182  for (auto & elem : mesh.active_local_element_ptr_range())
1183  {
1184  // Only number dofs connected to active
1185  // elements on this processor.
1186  const unsigned int n_nodes = elem->n_nodes();
1187 
1188  // First number the nodal DOFS
1189  for (unsigned int n=0; n<n_nodes; n++)
1190  {
1191  Node & node = elem->node_ref(n);
1192 
1193  for (unsigned vg=0; vg<n_var_groups; vg++)
1194  {
1195  const VariableGroup & vg_description(this->variable_group(vg));
1196 
1197  if ((vg_description.type().family != SCALAR) &&
1198  (vg_description.active_on_subdomain(elem->subdomain_id())))
1199  {
1200  // assign dof numbers (all at once) if this is
1201  // our node and if they aren't already there
1202  if ((node.n_comp_group(sys_num,vg) > 0) &&
1203  (node.processor_id() == this->processor_id()) &&
1204  (node.vg_dof_base(sys_num,vg) ==
1206  {
1207  node.set_vg_dof_base(sys_num, vg,
1208  next_free_dof);
1209  next_free_dof += (vg_description.n_variables()*
1210  node.n_comp_group(sys_num,vg));
1211  //node.debug_buffer();
1212  }
1213  }
1214  }
1215  }
1216 
1217  // Now number the element DOFS
1218  for (unsigned vg=0; vg<n_var_groups; vg++)
1219  {
1220  const VariableGroup & vg_description(this->variable_group(vg));
1221 
1222  if ((vg_description.type().family != SCALAR) &&
1223  (vg_description.active_on_subdomain(elem->subdomain_id())))
1224  if (elem->n_comp_group(sys_num,vg) > 0)
1225  {
1226  libmesh_assert_equal_to (elem->vg_dof_base(sys_num,vg),
1228 
1229  elem->set_vg_dof_base(sys_num,
1230  vg,
1231  next_free_dof);
1232 
1233  next_free_dof += (vg_description.n_variables()*
1234  elem->n_comp(sys_num,vg));
1235  }
1236  }
1237  } // done looping over elements
1238 
1239 
1240  // we may have missed assigning DOFs to nodes that we own
1241  // but to which we have no connected elements matching our
1242  // variable restriction criterion. this will happen, for example,
1243  // if variable V is restricted to subdomain S. We may not own
1244  // any elements which live in S, but we may own nodes which are
1245  // *connected* to elements which do. in this scenario these nodes
1246  // will presently have unnumbered DOFs. we need to take care of
1247  // them here since we own them and no other processor will touch them.
1248  for (auto & node : mesh.local_node_ptr_range())
1249  for (unsigned vg=0; vg<n_var_groups; vg++)
1250  {
1251  const VariableGroup & vg_description(this->variable_group(vg));
1252 
1253  if (node->n_comp_group(sys_num,vg))
1254  if (node->vg_dof_base(sys_num,vg) == DofObject::invalid_id)
1255  {
1256  node->set_vg_dof_base (sys_num,
1257  vg,
1258  next_free_dof);
1259 
1260  next_free_dof += (vg_description.n_variables()*
1261  node->n_comp(sys_num,vg));
1262  }
1263  }
1264 
1265  // Finally, count up the SCALAR dofs
1266  this->_n_SCALAR_dofs = 0;
1267  for (unsigned vg=0; vg<n_var_groups; vg++)
1268  {
1269  const VariableGroup & vg_description(this->variable_group(vg));
1270 
1271  if (vg_description.type().family == SCALAR)
1272  {
1273  this->_n_SCALAR_dofs += (vg_description.n_variables()*
1274  vg_description.type().order.get_order());
1275  continue;
1276  }
1277  }
1278 
1279  // Only increment next_free_dof if we're on the processor
1280  // that holds this SCALAR variable
1281  if (this->processor_id() == (this->n_processors()-1))
1282  next_free_dof += _n_SCALAR_dofs;
1283 
1284 #ifdef DEBUG
1285  {
1286  // libMesh::out << "next_free_dof=" << next_free_dof << std::endl
1287  // << "_n_SCALAR_dofs=" << _n_SCALAR_dofs << std::endl;
1288 
1289  // Make sure we didn't miss any nodes
1290  MeshTools::libmesh_assert_valid_procids<Node>(mesh);
1291 
1292  for (auto & node : mesh.local_node_ptr_range())
1293  {
1294  unsigned int n_var_g = node->n_var_groups(this->sys_number());
1295  for (unsigned int vg=0; vg != n_var_g; ++vg)
1296  {
1297  unsigned int n_comp_g =
1298  node->n_comp_group(this->sys_number(), vg);
1299  dof_id_type my_first_dof = n_comp_g ?
1300  node->vg_dof_base(this->sys_number(), vg) : 0;
1301  libmesh_assert_not_equal_to (my_first_dof, DofObject::invalid_id);
1302  }
1303  }
1304  }
1305 #endif // DEBUG
1306 }

References _n_SCALAR_dofs, libMesh::Variable::active_on_subdomain(), libMesh::FEType::family, libMesh::OrderWrapper::get_order(), libMesh::DofObject::invalid_id, mesh, libMesh::DofObject::n_comp_group(), n_nodes, libMesh::ParallelObject::n_processors(), n_variable_groups(), libMesh::VariableGroup::n_variables(), libMesh::FEType::order, libMesh::ParallelObject::processor_id(), libMesh::DofObject::processor_id(), libMesh::SCALAR, libMesh::DofObject::set_vg_dof_base(), sys_number(), libMesh::Variable::type(), variable_group(), and libMesh::DofObject::vg_dof_base().

Referenced by distribute_dofs().

◆ distribute_local_dofs_var_major()

void libMesh::DofMap::distribute_local_dofs_var_major ( dof_id_type next_free_dof,
MeshBase mesh 
)
private

Distributes the global degrees of freedom, for dofs on this processor.

In this format the local degrees of freedom are in a contiguous block for each variable in the system. Starts at index next_free_dof, and increments it to the post-final index.

Definition at line 1310 of file dof_map.C.

1312 {
1313  const unsigned int sys_num = this->sys_number();
1314  const unsigned int n_var_groups = this->n_variable_groups();
1315 
1316  // Our numbering here must be kept consistent with the numbering
1317  // scheme assumed by DofMap::local_variable_indices!
1318 
1319  //-------------------------------------------------------------------------
1320  // First count and assign temporary numbers to local dofs
1321  for (unsigned vg=0; vg<n_var_groups; vg++)
1322  {
1323  const VariableGroup & vg_description(this->variable_group(vg));
1324 
1325  const unsigned int n_vars_in_group = vg_description.n_variables();
1326 
1327  // Skip the SCALAR dofs
1328  if (vg_description.type().family == SCALAR)
1329  continue;
1330 
1331  for (auto & elem : mesh.active_local_element_ptr_range())
1332  {
1333  // Only number dofs connected to active elements on this
1334  // processor and only variables which are active on on this
1335  // element's subdomain.
1336  if (!vg_description.active_on_subdomain(elem->subdomain_id()))
1337  continue;
1338 
1339  const unsigned int n_nodes = elem->n_nodes();
1340 
1341  // First number the nodal DOFS
1342  for (unsigned int n=0; n<n_nodes; n++)
1343  {
1344  Node & node = elem->node_ref(n);
1345 
1346  // assign dof numbers (all at once) if this is
1347  // our node and if they aren't already there
1348  if ((node.n_comp_group(sys_num,vg) > 0) &&
1349  (node.processor_id() == this->processor_id()) &&
1350  (node.vg_dof_base(sys_num,vg) ==
1352  {
1353  node.set_vg_dof_base(sys_num, vg, next_free_dof);
1354 
1355  next_free_dof += (n_vars_in_group*
1356  node.n_comp_group(sys_num,vg));
1357  }
1358  }
1359 
1360  // Now number the element DOFS
1361  if (elem->n_comp_group(sys_num,vg) > 0)
1362  {
1363  libmesh_assert_equal_to (elem->vg_dof_base(sys_num,vg),
1365 
1366  elem->set_vg_dof_base(sys_num,
1367  vg,
1368  next_free_dof);
1369 
1370  next_free_dof += (n_vars_in_group*
1371  elem->n_comp_group(sys_num,vg));
1372  }
1373  } // end loop on elements
1374 
1375  // we may have missed assigning DOFs to nodes that we own
1376  // but to which we have no connected elements matching our
1377  // variable restriction criterion. this will happen, for example,
1378  // if variable V is restricted to subdomain S. We may not own
1379  // any elements which live in S, but we may own nodes which are
1380  // *connected* to elements which do. in this scenario these nodes
1381  // will presently have unnumbered DOFs. we need to take care of
1382  // them here since we own them and no other processor will touch them.
1383  for (auto & node : mesh.local_node_ptr_range())
1384  if (node->n_comp_group(sys_num,vg))
1385  if (node->vg_dof_base(sys_num,vg) == DofObject::invalid_id)
1386  {
1387  node->set_vg_dof_base (sys_num,
1388  vg,
1389  next_free_dof);
1390 
1391  next_free_dof += (n_vars_in_group*
1392  node->n_comp_group(sys_num,vg));
1393  }
1394  } // end loop on variable groups
1395 
1396  // Finally, count up the SCALAR dofs
1397  this->_n_SCALAR_dofs = 0;
1398  for (unsigned vg=0; vg<n_var_groups; vg++)
1399  {
1400  const VariableGroup & vg_description(this->variable_group(vg));
1401 
1402  if (vg_description.type().family == SCALAR)
1403  {
1404  this->_n_SCALAR_dofs += (vg_description.n_variables()*
1405  vg_description.type().order.get_order());
1406  continue;
1407  }
1408  }
1409 
1410  // Only increment next_free_dof if we're on the processor
1411  // that holds this SCALAR variable
1412  if (this->processor_id() == (this->n_processors()-1))
1413  next_free_dof += _n_SCALAR_dofs;
1414 
1415 #ifdef DEBUG
1416  {
1417  // Make sure we didn't miss any nodes
1418  MeshTools::libmesh_assert_valid_procids<Node>(mesh);
1419 
1420  for (auto & node : mesh.local_node_ptr_range())
1421  {
1422  unsigned int n_var_g = node->n_var_groups(this->sys_number());
1423  for (unsigned int vg=0; vg != n_var_g; ++vg)
1424  {
1425  unsigned int n_comp_g =
1426  node->n_comp_group(this->sys_number(), vg);
1427  dof_id_type my_first_dof = n_comp_g ?
1428  node->vg_dof_base(this->sys_number(), vg) : 0;
1429  libmesh_assert_not_equal_to (my_first_dof, DofObject::invalid_id);
1430  }
1431  }
1432  }
1433 #endif // DEBUG
1434 }

References _n_SCALAR_dofs, libMesh::Variable::active_on_subdomain(), libMesh::FEType::family, libMesh::OrderWrapper::get_order(), libMesh::DofObject::invalid_id, mesh, libMesh::DofObject::n_comp_group(), n_nodes, libMesh::ParallelObject::n_processors(), n_variable_groups(), libMesh::VariableGroup::n_variables(), libMesh::FEType::order, libMesh::ParallelObject::processor_id(), libMesh::DofObject::processor_id(), libMesh::SCALAR, libMesh::DofObject::set_vg_dof_base(), sys_number(), libMesh::Variable::type(), variable_group(), and libMesh::DofObject::vg_dof_base().

Referenced by distribute_dofs().

◆ dof_indices() [1/5]

void libMesh::DofMap::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 global degree of freedom indices for elem.node_ref(n), for one variable vn.

On hanging nodes with both vertex and non-vertex DoFs, only those indices which are directly supported on elem are included.

Definition at line 2246 of file dof_map.C.

2250 {
2251  this->_node_dof_indices(elem, n, elem.node_ref(n), di, vn);
2252 }

References _node_dof_indices(), and libMesh::Elem::node_ref().

◆ dof_indices() [2/5]

void libMesh::DofMap::dof_indices ( const Elem *const  elem,
std::vector< dof_id_type > &  di 
) const

Fills the vector di with the global degree of freedom indices for the element.

Definition at line 1967 of file dof_map.C.

1969 {
1970  // We now allow elem==nullptr to request just SCALAR dofs
1971  // libmesh_assert(elem);
1972 
1973  // If we are asking for current indices on an element, it ought to
1974  // be an active element (or a Side proxy, which also thinks it's
1975  // active)
1976  libmesh_assert(!elem || elem->active());
1977 
1978  LOG_SCOPE("dof_indices()", "DofMap");
1979 
1980  // Clear the DOF indices vector
1981  di.clear();
1982 
1983  const unsigned int n_var_groups = this->n_variable_groups();
1984 
1985 #ifdef DEBUG
1986  // Check that sizes match in DEBUG mode
1987  std::size_t tot_size = 0;
1988 #endif
1989 
1990  if (elem && elem->type() == TRI3SUBDIVISION)
1991  {
1992  // Subdivision surface FE require the 1-ring around elem
1993  const Tri3Subdivision * sd_elem = static_cast<const Tri3Subdivision *>(elem);
1994 
1995  // Ghost subdivision elements have no real dofs
1996  if (!sd_elem->is_ghost())
1997  {
1998  // Determine the nodes contributing to element elem
1999  std::vector<const Node *> elem_nodes;
2000  MeshTools::Subdivision::find_one_ring(sd_elem, elem_nodes);
2001 
2002  // Get the dof numbers
2003  for (unsigned int vg=0; vg<n_var_groups; vg++)
2004  {
2005  const VariableGroup & var = this->variable_group(vg);
2006  const unsigned int vars_in_group = var.n_variables();
2007 
2008  if (var.type().family == SCALAR &&
2009  var.active_on_subdomain(elem->subdomain_id()))
2010  {
2011  for (unsigned int vig=0; vig != vars_in_group; ++vig)
2012  {
2013 #ifdef DEBUG
2014  tot_size += var.type().order;
2015 #endif
2016  std::vector<dof_id_type> di_new;
2017  this->SCALAR_dof_indices(di_new,var.number(vig));
2018  di.insert( di.end(), di_new.begin(), di_new.end());
2019  }
2020  }
2021  else
2022  for (unsigned int vig=0; vig != vars_in_group; ++vig)
2023  {
2024  _dof_indices(*elem, elem->p_level(), di, vg, vig,
2025  elem_nodes.data(),
2026  cast_int<unsigned int>(elem_nodes.size())
2027 #ifdef DEBUG
2028  , var.number(vig), tot_size
2029 #endif
2030  );
2031  }
2032  }
2033  }
2034 
2035  return;
2036  }
2037 
2038  // Get the dof numbers for each variable
2039  const unsigned int n_nodes = elem ? elem->n_nodes() : 0;
2040  for (unsigned int vg=0; vg<n_var_groups; vg++)
2041  {
2042  const VariableGroup & var = this->variable_group(vg);
2043  const unsigned int vars_in_group = var.n_variables();
2044 
2045  if (var.type().family == SCALAR &&
2046  (!elem ||
2047  var.active_on_subdomain(elem->subdomain_id())))
2048  {
2049  for (unsigned int vig=0; vig != vars_in_group; ++vig)
2050  {
2051 #ifdef DEBUG
2052  tot_size += var.type().order;
2053 #endif
2054  std::vector<dof_id_type> di_new;
2055  this->SCALAR_dof_indices(di_new,var.number(vig));
2056  di.insert( di.end(), di_new.begin(), di_new.end());
2057  }
2058  }
2059  else if (elem)
2060  for (unsigned int vig=0; vig != vars_in_group; ++vig)
2061  {
2062  _dof_indices(*elem, elem->p_level(), di, vg, vig,
2063  elem->get_nodes(), n_nodes
2064 #ifdef DEBUG
2065  , var.number(vig), tot_size
2066 #endif
2067  );
2068  }
2069  }
2070 
2071 #ifdef DEBUG
2072  libmesh_assert_equal_to (tot_size, di.size());
2073 #endif
2074 }

References _dof_indices(), libMesh::Elem::active(), libMesh::Variable::active_on_subdomain(), libMesh::FEType::family, libMesh::MeshTools::Subdivision::find_one_ring(), libMesh::Elem::get_nodes(), libMesh::Tri3Subdivision::is_ghost(), libMesh::libmesh_assert(), n_nodes, libMesh::Elem::n_nodes(), n_variable_groups(), libMesh::VariableGroup::n_variables(), libMesh::VariableGroup::number(), libMesh::FEType::order, libMesh::Elem::p_level(), libMesh::SCALAR, SCALAR_dof_indices(), libMesh::Elem::subdomain_id(), libMesh::TRI3SUBDIVISION, libMesh::Variable::type(), libMesh::Elem::type(), and variable_group().

Referenced by libMesh::ExactSolution::_compute_error(), libMesh::UniformRefinementEstimator::_estimate_error(), add_neighbors_to_send_list(), libMesh::HPCoarsenTest::add_projection(), assemble(), LinearElasticity::assemble(), AssembleOptimization::assemble_A_and_F(), assemble_cd(), assemble_elasticity(), assemble_mass(), assemble_matrices(), assemble_SchroedingerEquation(), assemble_shell(), assemble_stokes(), assemble_wave(), Biharmonic::JR::bounds(), libMesh::EquationSystems::build_discontinuous_solution_vector(), libMesh::EquationSystems::build_parallel_elemental_solution_vector(), libMesh::EquationSystems::build_parallel_solution_vector(), libMesh::System::calculate_norm(), libMesh::FEGenericBase< FEOutputType< T >::type >::coarsened_dof_values(), compute_jacobian(), libMesh::FEGenericBase< FEOutputType< T >::type >::compute_periodic_constraints(), libMesh::FEGenericBase< FEOutputType< T >::type >::compute_proj_constraints(), compute_residual(), LinearElasticityWithContact::compute_stresses(), LinearElasticity::compute_stresses(), compute_stresses(), LargeDeformationElasticity::compute_stresses(), libMesh::MeshFunction::discontinuous_gradient(), libMesh::MeshFunction::discontinuous_value(), DMCreateDomainDecomposition_libMesh(), DMCreateFieldDecomposition_libMesh(), dof_indices(), libMesh::AdjointRefinementEstimator::estimate_error(), libMesh::ExactErrorEstimator::estimate_error(), libMesh::DTKEvaluator::evaluate(), libMesh::RBEIMAssembly::evaluate_basis_function(), libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::SubFunctor::find_dofs_to_send(), libMesh::MeshFunction::gradient(), libMesh::MeshFunction::hessian(), libMesh::SystemSubsetBySubdomain::init(), libMesh::RBEIMConstruction::init_dof_map_between_systems(), is_evaluable(), LargeDeformationElasticity::jacobian(), libMesh::System::local_dof_indices(), max_constraint_error(), LinearElasticityWithContact::move_mesh(), libMesh::DGFEMContext::neighbor_side_fe_reinit(), libMesh::WeightedPatchRecoveryErrorEstimator::EstimateError::operator()(), libMesh::PatchRecoveryErrorEstimator::EstimateError::operator()(), libMesh::MeshFunction::operator()(), libMesh::BoundaryProjectSolution::operator()(), libMesh::ErrorVector::plot_error(), libMesh::System::point_gradient(), libMesh::System::point_hessian(), libMesh::System::point_value(), libMesh::FEMContext::pre_fe_reinit(), LargeDeformationElasticity::residual(), Biharmonic::JR::residual_and_jacobian(), LinearElasticityWithContact::residual_and_jacobian(), scatter_constraints(), libMesh::HPCoarsenTest::select_refinement(), libMesh::PetscDMWrapper::set_point_range_in_section(), FETest< order, family, elem_type >::setUp(), SolidSystem::side_time_derivative(), libMesh::SparsityPattern::Build::sorted_connected_dofs(), MixedDimensionMeshTest::testDofOrdering(), MixedDimensionRefinedMeshTest::testDofOrdering(), MixedDimensionNonUniformRefinement::testDofOrdering(), MixedDimensionNonUniformRefinementTriangle::testDofOrdering(), MixedDimensionNonUniformRefinement3D::testDofOrdering(), MeshInputTest::testExodusWriteElementDataFromDiscontinuousNodalData(), BoundaryInfoTest::testShellFaceConstraints(), libMesh::BoundaryVolumeSolutionTransfer::transfer_boundary_volume(), libMesh::EnsightIO::write_scalar_ascii(), and libMesh::EnsightIO::write_vector_ascii().

◆ dof_indices() [3/5]

void libMesh::DofMap::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.

For one variable, and potentially for a non-default element p refinement level

Definition at line 2077 of file dof_map.C.

2081 {
2082  // We now allow elem==nullptr to request just SCALAR dofs
2083  // libmesh_assert(elem);
2084 
2085  LOG_SCOPE("dof_indices()", "DofMap");
2086 
2087  // Clear the DOF indices vector
2088  di.clear();
2089 
2090  // Use the default p refinement level?
2091  if (p_level == -12345)
2092  p_level = elem ? elem->p_level() : 0;
2093 
2094  const unsigned int vg = this->_variable_group_numbers[vn];
2095  const VariableGroup & var = this->variable_group(vg);
2096  const unsigned int vig = vn - var.number();
2097 
2098 #ifdef DEBUG
2099  // Check that sizes match in DEBUG mode
2100  std::size_t tot_size = 0;
2101 #endif
2102 
2103  if (elem && elem->type() == TRI3SUBDIVISION)
2104  {
2105  // Subdivision surface FE require the 1-ring around elem
2106  const Tri3Subdivision * sd_elem = static_cast<const Tri3Subdivision *>(elem);
2107 
2108  // Ghost subdivision elements have no real dofs
2109  if (!sd_elem->is_ghost())
2110  {
2111  // Determine the nodes contributing to element elem
2112  std::vector<const Node *> elem_nodes;
2113  MeshTools::Subdivision::find_one_ring(sd_elem, elem_nodes);
2114 
2115  _dof_indices(*elem, p_level, di, vg, vig, elem_nodes.data(),
2116  cast_int<unsigned int>(elem_nodes.size())
2117 #ifdef DEBUG
2118  , vn, tot_size
2119 #endif
2120  );
2121  }
2122 
2123  return;
2124  }
2125 
2126  // Get the dof numbers
2127  if (var.type().family == SCALAR &&
2128  (!elem ||
2129  var.active_on_subdomain(elem->subdomain_id())))
2130  {
2131 #ifdef DEBUG
2132  tot_size += var.type().order;
2133 #endif
2134  std::vector<dof_id_type> di_new;
2135  this->SCALAR_dof_indices(di_new,vn);
2136  di.insert( di.end(), di_new.begin(), di_new.end());
2137  }
2138  else if (elem)
2139  _dof_indices(*elem, p_level, di, vg, vig, elem->get_nodes(),
2140  elem->n_nodes()
2141 #ifdef DEBUG
2142  , vn, tot_size
2143 #endif
2144  );
2145 
2146 #ifdef DEBUG
2147  libmesh_assert_equal_to (tot_size, di.size());
2148 #endif
2149 }

References _dof_indices(), _variable_group_numbers, libMesh::Variable::active_on_subdomain(), libMesh::FEType::family, libMesh::MeshTools::Subdivision::find_one_ring(), libMesh::Elem::get_nodes(), libMesh::Tri3Subdivision::is_ghost(), libMesh::Elem::n_nodes(), libMesh::VariableGroup::number(), libMesh::FEType::order, libMesh::Elem::p_level(), libMesh::SCALAR, SCALAR_dof_indices(), libMesh::Elem::subdomain_id(), libMesh::TRI3SUBDIVISION, libMesh::Variable::type(), libMesh::Elem::type(), and variable_group().

◆ dof_indices() [4/5]

void libMesh::DofMap::dof_indices ( const Node *const  node,
std::vector< dof_id_type > &  di 
) const

Fills the vector di with the global degree of freedom indices for the node.

Definition at line 2152 of file dof_map.C.

2154 {
2155  // We allow node==nullptr to request just SCALAR dofs
2156  // libmesh_assert(elem);
2157 
2158  LOG_SCOPE("dof_indices(Node)", "DofMap");
2159 
2160  // Clear the DOF indices vector
2161  di.clear();
2162 
2163  const unsigned int n_var_groups = this->n_variable_groups();
2164  const unsigned int sys_num = this->sys_number();
2165 
2166  // Get the dof numbers
2167  for (unsigned int vg=0; vg<n_var_groups; vg++)
2168  {
2169  const VariableGroup & var = this->variable_group(vg);
2170  const unsigned int vars_in_group = var.n_variables();
2171 
2172  if (var.type().family == SCALAR)
2173  {
2174  for (unsigned int vig=0; vig != vars_in_group; ++vig)
2175  {
2176  std::vector<dof_id_type> di_new;
2177  this->SCALAR_dof_indices(di_new,var.number(vig));
2178  di.insert( di.end(), di_new.begin(), di_new.end());
2179  }
2180  }
2181  else
2182  {
2183  const int n_comp = node->n_comp_group(sys_num,vg);
2184  for (unsigned int vig=0; vig != vars_in_group; ++vig)
2185  {
2186  for (int i=0; i != n_comp; ++i)
2187  {
2188  const dof_id_type d =
2189  node->dof_number(sys_num, vg, vig, i, n_comp);
2190  libmesh_assert_not_equal_to
2191  (d, DofObject::invalid_id);
2192  di.push_back(d);
2193  }
2194  }
2195  }
2196  }
2197 }

References libMesh::DofObject::dof_number(), libMesh::FEType::family, libMesh::DofObject::invalid_id, libMesh::DofObject::n_comp_group(), n_variable_groups(), libMesh::VariableGroup::n_variables(), libMesh::VariableGroup::number(), libMesh::SCALAR, SCALAR_dof_indices(), sys_number(), libMesh::Variable::type(), and variable_group().

◆ dof_indices() [5/5]

void libMesh::DofMap::dof_indices ( const Node *const  node,
std::vector< dof_id_type > &  di,
const unsigned int  vn 
) const

Fills the vector di with the global degree of freedom indices for the node, for one variable vn.

Definition at line 2200 of file dof_map.C.

2203 {
2204  if (vn == libMesh::invalid_uint)
2205  {
2206  this->dof_indices(node, di);
2207  return;
2208  }
2209 
2210  // We allow node==nullptr to request just SCALAR dofs
2211  // libmesh_assert(elem);
2212 
2213  LOG_SCOPE("dof_indices(Node)", "DofMap");
2214 
2215  // Clear the DOF indices vector
2216  di.clear();
2217 
2218  const unsigned int sys_num = this->sys_number();
2219 
2220  // Get the dof numbers
2221  const unsigned int vg = this->_variable_group_numbers[vn];
2222  const VariableGroup & var = this->variable_group(vg);
2223 
2224  if (var.type().family == SCALAR)
2225  {
2226  std::vector<dof_id_type> di_new;
2227  this->SCALAR_dof_indices(di_new,vn);
2228  di.insert( di.end(), di_new.begin(), di_new.end());
2229  }
2230  else
2231  {
2232  const unsigned int vig = vn - var.number();
2233  const int n_comp = node->n_comp_group(sys_num,vg);
2234  for (int i=0; i != n_comp; ++i)
2235  {
2236  const dof_id_type d =
2237  node->dof_number(sys_num, vg, vig, i, n_comp);
2238  libmesh_assert_not_equal_to
2239  (d, DofObject::invalid_id);
2240  di.push_back(d);
2241  }
2242  }
2243 }

References _variable_group_numbers, dof_indices(), libMesh::DofObject::dof_number(), libMesh::FEType::family, libMesh::DofObject::invalid_id, libMesh::invalid_uint, libMesh::DofObject::n_comp_group(), libMesh::VariableGroup::number(), libMesh::SCALAR, SCALAR_dof_indices(), sys_number(), libMesh::Variable::type(), and variable_group().

◆ dof_owner()

processor_id_type libMesh::DofMap::dof_owner ( const dof_id_type  dof) const
inline
Returns
The processor id that owns the dof index dof

Definition at line 701 of file dof_map.h.

702  { std::vector<dof_id_type>::const_iterator ub =
703  std::upper_bound(_end_df.begin(), _end_df.end(), dof);
704  libmesh_assert (ub != _end_df.end());
705  return cast_int<processor_id_type>(ub - _end_df.begin());
706  }

References _end_df, and libMesh::libmesh_assert().

Referenced by libMesh::PetscDMWrapper::build_sf(), and DofMapTest::testDofOwner().

◆ elem_ptr()

DofObject * libMesh::DofMap::elem_ptr ( MeshBase mesh,
dof_id_type  i 
) const
private
Returns
The Elem pointer with index i from the mesh.

Definition at line 325 of file dof_map.C.

326 {
327  return mesh.elem_ptr(i);
328 }

References mesh.

Referenced by distribute_dofs().

◆ enable_print_counter_info()

void libMesh::ReferenceCounter::enable_print_counter_info ( )
staticinherited

Methods to enable/disable the reference counter output from print_info()

Definition at line 100 of file reference_counter.C.

101 {
102  _enable_print_counter = true;
103  return;
104 }

References libMesh::ReferenceCounter::_enable_print_counter.

◆ end_dof() [1/2]

dof_id_type libMesh::DofMap::end_dof ( ) const
inline

Definition at line 695 of file dof_map.h.

696  { return this->end_dof(this->processor_id()); }

References libMesh::ParallelObject::processor_id().

Referenced by distribute_dofs(), local_index(), and n_local_constrained_dofs().

◆ end_dof() [2/2]

dof_id_type libMesh::DofMap::end_dof ( const processor_id_type  proc) const
inline

◆ end_old_dof() [1/2]

dof_id_type libMesh::DofMap::end_old_dof ( ) const
inline

Definition at line 718 of file dof_map.h.

719  { return this->end_old_dof(this->processor_id()); }

References libMesh::ParallelObject::processor_id().

◆ end_old_dof() [2/2]

dof_id_type libMesh::DofMap::end_old_dof ( const processor_id_type  proc) const
inline
Returns
The first old dof index that is after all indices local to processor proc.

Analogous to the end() member function of STL containers.

Definition at line 715 of file dof_map.h.

716  { libmesh_assert_less (proc, _end_old_df.size()); return _end_old_df[proc]; }

References _end_old_df.

Referenced by libMesh::PetscDMWrapper::init_and_attach_petscdm(), libMesh::BuildProjectionList::operator()(), SystemsTest::testProjectMatrix1D(), SystemsTest::testProjectMatrix2D(), and SystemsTest::testProjectMatrix3D().

◆ enforce_adjoint_constraints_exactly()

void libMesh::DofMap::enforce_adjoint_constraints_exactly ( NumericVector< Number > &  v,
unsigned int  q 
) const
inline

Heterogenously constrains the numeric vector v, which represents an adjoint solution defined on the mesh for quantity fo interest q.

For homogeneous constraints, use enforce_constraints_exactly instead

Definition at line 2058 of file dof_map.h.

2059  {}

Referenced by libMesh::ImplicitSystem::adjoint_solve(), and libMesh::AdjointRefinementEstimator::estimate_error().

◆ enforce_constraints_exactly()

void libMesh::DofMap::enforce_constraints_exactly ( const System system,
NumericVector< Number > *  v = nullptr,
bool  homogeneous = false 
) const
inline

Constrains the numeric vector v, which represents a solution defined on the mesh.

This may need to be used after a linear solve, if your linear solver's solutions do not satisfy your DoF constraints to a tight enough tolerance.

If v == nullptr, the system solution vector is constrained

If homogeneous == true, heterogeneous constraints are enforced as if they were homogeneous. This might be appropriate for e.g. a vector representing a difference between two heterogeneously-constrained solutions.

Definition at line 2054 of file dof_map.h.

2056  {}

Referenced by libMesh::__libmesh_petsc_diff_solver_jacobian(), libMesh::__libmesh_petsc_diff_solver_residual(), libMesh::Problem_Interface::computeF(), libMesh::Problem_Interface::computeJacobian(), libMesh::Problem_Interface::computePreconditioner(), DMlibMeshFunction(), DMlibMeshJacobian(), libMesh::libmesh_petsc_snes_jacobian(), libMesh::libmesh_petsc_snes_residual_helper(), libMesh::ImplicitSystem::sensitivity_solve(), libMesh::NewtonSolver::solve(), libMesh::PetscDiffSolver::solve(), libMesh::RBConstruction::solve_for_matrix_and_rhs(), libMesh::ImplicitSystem::weighted_sensitivity_adjoint_solve(), and libMesh::ImplicitSystem::weighted_sensitivity_solve().

◆ enforce_constraints_on_jacobian()

void libMesh::DofMap::enforce_constraints_on_jacobian ( const NonlinearImplicitSystem system,
SparseMatrix< Number > *  jac 
) const
inline

Definition at line 2069 of file dof_map.h.

2070  {}

Referenced by libMesh::libmesh_petsc_snes_jacobian().

◆ enforce_constraints_on_residual()

void libMesh::DofMap::enforce_constraints_on_residual ( const NonlinearImplicitSystem system,
NumericVector< Number > *  rhs,
NumericVector< Number > const *  solution,
bool  homogeneous = true 
) const
inline

◆ extract_local_vector()

void libMesh::DofMap::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 of freedom.

For an element without constrained degrees of freedom this is the trivial mapping \( Ue[i] = Ug[dof_indices[i]] \)

Note
The user must ensure that the element vector Ue is properly sized when calling this method. This is because there is no resize() method in the DenseVectorBase<> class.

Definition at line 1885 of file dof_map.C.

1888 {
1889  const unsigned int n_original_dofs = dof_indices_in.size();
1890 
1891 #ifdef LIBMESH_ENABLE_AMR
1892 
1893  // Trivial mapping
1894  libmesh_assert_equal_to (dof_indices_in.size(), Ue.size());
1895  bool has_constrained_dofs = false;
1896 
1897  for (unsigned int il=0; il != n_original_dofs; ++il)
1898  {
1899  const dof_id_type ig = dof_indices_in[il];
1900 
1901  if (this->is_constrained_dof (ig)) has_constrained_dofs = true;
1902 
1903  libmesh_assert_less (ig, Ug.size());
1904 
1905  Ue.el(il) = Ug(ig);
1906  }
1907 
1908  // If the element has any constrained DOFs then we need
1909  // to account for them in the mapping. This will handle
1910  // the case that the input vector is not constrained.
1911  if (has_constrained_dofs)
1912  {
1913  // Copy the input DOF indices.
1914  std::vector<dof_id_type> constrained_dof_indices(dof_indices_in);
1915 
1916  DenseMatrix<Number> C;
1917  DenseVector<Number> H;
1918 
1919  this->build_constraint_matrix_and_vector (C, H, constrained_dof_indices);
1920 
1921  libmesh_assert_equal_to (dof_indices_in.size(), C.m());
1922  libmesh_assert_equal_to (constrained_dof_indices.size(), C.n());
1923 
1924  // zero-out Ue
1925  Ue.zero();
1926 
1927  // compute Ue = C Ug, with proper mapping.
1928  for (unsigned int i=0; i != n_original_dofs; i++)
1929  {
1930  Ue.el(i) = H(i);
1931 
1932  const unsigned int n_constrained =
1933  cast_int<unsigned int>(constrained_dof_indices.size());
1934  for (unsigned int j=0; j<n_constrained; j++)
1935  {
1936  const dof_id_type jg = constrained_dof_indices[j];
1937 
1938  // If Ug is a serial or ghosted vector, then this assert is
1939  // overzealous. If Ug is a parallel vector, then this assert
1940  // is redundant.
1941  // libmesh_assert ((jg >= Ug.first_local_index()) &&
1942  // (jg < Ug.last_local_index()));
1943 
1944  Ue.el(i) += C(i,j)*Ug(jg);
1945  }
1946  }
1947  }
1948 
1949 #else
1950 
1951  // Trivial mapping
1952 
1953  libmesh_assert_equal_to (n_original_dofs, Ue.size());
1954 
1955  for (unsigned int il=0; il<n_original_dofs; il++)
1956  {
1957  const dof_id_type ig = dof_indices_in[il];
1958 
1959  libmesh_assert ((ig >= Ug.first_local_index()) && (ig < Ug.last_local_index()));
1960 
1961  Ue.el(il) = Ug(ig);
1962  }
1963 
1964 #endif
1965 }

References build_constraint_matrix_and_vector(), libMesh::DenseVectorBase< T >::el(), libMesh::NumericVector< T >::first_local_index(), is_constrained_dof(), libMesh::NumericVector< T >::last_local_index(), libMesh::libmesh_assert(), libMesh::DenseMatrixBase< T >::m(), libMesh::DenseMatrixBase< T >::n(), libMesh::DenseVectorBase< T >::size(), libMesh::NumericVector< T >::size(), and libMesh::DenseVectorBase< T >::zero().

◆ find_connected_dof_objects()

void libMesh::DofMap::find_connected_dof_objects ( std::vector< const DofObject * > &  objs) const
private

Finds all the DofObjects associated with the set in objs.

This will account for off-element couplings via hanging nodes.

◆ find_connected_dofs()

void libMesh::DofMap::find_connected_dofs ( std::vector< dof_id_type > &  elem_dofs) const
private

Finds all the DOFS associated with the element DOFs elem_dofs.

This will account for off-element couplings via hanging nodes.

Definition at line 2773 of file dof_map.C.

2774 {
2775  typedef std::set<dof_id_type> RCSet;
2776 
2777  // First insert the DOFS we already depend on into the set.
2778  RCSet dof_set (elem_dofs.begin(), elem_dofs.end());
2779 
2780  bool done = true;
2781 
2782  // Next insert any dofs those might be constrained in terms
2783  // of. Note that in this case we may not be done: Those may
2784  // in turn depend on others. So, we need to repeat this process
2785  // in that case until the system depends only on unconstrained
2786  // degrees of freedom.
2787  for (const auto & dof : elem_dofs)
2788  if (this->is_constrained_dof(dof))
2789  {
2790  // If the DOF is constrained
2791  DofConstraints::const_iterator
2792  pos = _dof_constraints.find(dof);
2793 
2794  libmesh_assert (pos != _dof_constraints.end());
2795 
2796  const DofConstraintRow & constraint_row = pos->second;
2797 
2798  // adaptive p refinement currently gives us lots of empty constraint
2799  // rows - we should optimize those DoFs away in the future. [RHS]
2800  //libmesh_assert (!constraint_row.empty());
2801 
2802  // Add the DOFs this dof is constrained in terms of.
2803  // note that these dofs might also be constrained, so
2804  // we will need to call this function recursively.
2805  for (const auto & pr : constraint_row)
2806  if (!dof_set.count (pr.first))
2807  {
2808  dof_set.insert (pr.first);
2809  done = false;
2810  }
2811  }
2812 
2813 
2814  // If not done then we need to do more work
2815  // (obviously :-) )!
2816  if (!done)
2817  {
2818  // Fill the vector with the contents of the set
2819  elem_dofs.clear();
2820  elem_dofs.insert (elem_dofs.end(),
2821  dof_set.begin(), dof_set.end());
2822 
2823 
2824  // May need to do this recursively. It is possible
2825  // that we just replaced a constrained DOF with another
2826  // constrained DOF.
2827  this->find_connected_dofs (elem_dofs);
2828 
2829  } // end if (!done)
2830 }

References _dof_constraints, is_constrained_dof(), and libMesh::libmesh_assert().

Referenced by libMesh::SparsityPattern::Build::sorted_connected_dofs().

◆ first_dof() [1/2]

dof_id_type libMesh::DofMap::first_dof ( ) const
inline

Definition at line 653 of file dof_map.h.

654  { return this->first_dof(this->processor_id()); }

References libMesh::ParallelObject::processor_id().

Referenced by distribute_dofs(), local_index(), and n_local_constrained_dofs().

◆ first_dof() [2/2]

dof_id_type libMesh::DofMap::first_dof ( const processor_id_type  proc) const
inline

◆ first_old_dof() [1/2]

dof_id_type libMesh::DofMap::first_old_dof ( ) const
inline

Definition at line 663 of file dof_map.h.

664  { return this->first_old_dof(this->processor_id()); }

References libMesh::ParallelObject::processor_id().

◆ first_old_dof() [2/2]

dof_id_type libMesh::DofMap::first_old_dof ( const processor_id_type  proc) const
inline
Returns
The first old dof index that is local to partition proc.

Definition at line 660 of file dof_map.h.

661  { libmesh_assert_less (proc, _first_old_df.size()); return _first_old_df[proc]; }

References _first_old_df.

Referenced by libMesh::PetscDMWrapper::init_and_attach_petscdm(), libMesh::BuildProjectionList::operator()(), SystemsTest::testProjectMatrix1D(), SystemsTest::testProjectMatrix2D(), and SystemsTest::testProjectMatrix3D().

◆ gather_constraints()

void libMesh::DofMap::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.

If any id in requested_dof_ids is constrained on another processor, its constraint will be added on this processor as well. If look_for_constrainees is true, then constraints will also be returned if the id appears as a constraining value not just if it appears as a constrained value.

This function operates recursively: if the constraint for a constrained dof is newly added locally, then any other dofs which constrain it are queried to see if they are in turn constrained, and so on.

Definition at line 3985 of file dof_map_constraints.C.

3988 {
3989  typedef std::set<dof_id_type> DoF_RCSet;
3990 
3991  // If we have heterogenous adjoint constraints we need to
3992  // communicate those too.
3993  const unsigned int max_qoi_num =
3994  _adjoint_constraint_values.empty() ?
3995  0 : _adjoint_constraint_values.rbegin()->first;
3996 
3997  // We have to keep recursing while the unexpanded set is
3998  // nonempty on *any* processor
3999  bool unexpanded_set_nonempty = !unexpanded_dofs.empty();
4000  this->comm().max(unexpanded_set_nonempty);
4001 
4002  while (unexpanded_set_nonempty)
4003  {
4004  // Let's make sure we don't lose sync in this loop.
4005  parallel_object_only();
4006 
4007  // Request sets
4008  DoF_RCSet dof_request_set;
4009 
4010  // Request sets to send to each processor
4011  std::map<processor_id_type, std::vector<dof_id_type>>
4012  requested_dof_ids;
4013 
4014  // And the sizes of each
4015  std::map<processor_id_type, dof_id_type>
4016  dof_ids_on_proc;
4017 
4018  // Fill (and thereby sort and uniq!) the main request sets
4019  for (const auto & unexpanded_dof : unexpanded_dofs)
4020  {
4021  DofConstraints::const_iterator
4022  pos = _dof_constraints.find(unexpanded_dof);
4023 
4024  // If we were asked for a DoF and we don't already have a
4025  // constraint for it, then we need to check for one.
4026  if (pos == _dof_constraints.end())
4027  {
4028  if (!this->local_index(unexpanded_dof) &&
4029  !_dof_constraints.count(unexpanded_dof) )
4030  dof_request_set.insert(unexpanded_dof);
4031  }
4032  // If we were asked for a DoF and we already have a
4033  // constraint for it, then we need to check if the
4034  // constraint is recursive.
4035  else
4036  {
4037  const DofConstraintRow & row = pos->second;
4038  for (const auto & j : row)
4039  {
4040  const dof_id_type constraining_dof = j.first;
4041 
4042  // If it's non-local and we haven't already got a
4043  // constraint for it, we might need to ask for one
4044  if (!this->local_index(constraining_dof) &&
4045  !_dof_constraints.count(constraining_dof))
4046  dof_request_set.insert(constraining_dof);
4047  }
4048  }
4049  }
4050 
4051  // Clear the unexpanded constraint set; we're about to expand it
4052  unexpanded_dofs.clear();
4053 
4054  // Count requests by processor
4055  processor_id_type proc_id = 0;
4056  for (const auto & i : dof_request_set)
4057  {
4058  while (i >= _end_df[proc_id])
4059  proc_id++;
4060  dof_ids_on_proc[proc_id]++;
4061  }
4062 
4063  for (auto & pair : dof_ids_on_proc)
4064  {
4065  requested_dof_ids[pair.first].reserve(pair.second);
4066  }
4067 
4068  // Prepare each processor's request set
4069  proc_id = 0;
4070  for (const auto & i : dof_request_set)
4071  {
4072  while (i >= _end_df[proc_id])
4073  proc_id++;
4074  requested_dof_ids[proc_id].push_back(i);
4075  }
4076 
4077  typedef std::vector<std::pair<dof_id_type, Real>> row_datum;
4078 
4079  typedef std::vector<Number> rhss_datum;
4080 
4081  auto row_gather_functor =
4082  [this]
4084  const std::vector<dof_id_type> & ids,
4085  std::vector<row_datum> & data)
4086  {
4087  // Fill those requests
4088  const std::size_t query_size = ids.size();
4089 
4090  data.resize(query_size);
4091  for (std::size_t i=0; i != query_size; ++i)
4092  {
4093  dof_id_type constrained = ids[i];
4094  if (_dof_constraints.count(constrained))
4095  {
4096  DofConstraintRow & row = _dof_constraints[constrained];
4097  std::size_t row_size = row.size();
4098  data[i].reserve(row_size);
4099  for (const auto & j : row)
4100  {
4101  data[i].push_back(j);
4102 
4103  // We should never have an invalid constraining
4104  // dof id
4106 
4107  // We should never have a 0 constraint
4108  // coefficient; that's implicit via sparse
4109  // constraint storage
4110  //
4111  // But we can't easily control how users add
4112  // constraints, so we can't safely assert that
4113  // we're being efficient here.
4114  //
4115  // libmesh_assert(j.second);
4116  }
4117  }
4118  else
4119  {
4120  // We have to distinguish "constraint with no
4121  // constraining dofs" (e.g. due to Dirichlet
4122  // constraint equations) from "no constraint".
4123  // We'll use invalid_id for the latter.
4124  data[i].push_back
4125  (std::make_pair(DofObject::invalid_id, Real(0)));
4126  }
4127  }
4128  };
4129 
4130  auto rhss_gather_functor =
4131  [this,
4132  max_qoi_num]
4134  const std::vector<dof_id_type> & ids,
4135  std::vector<rhss_datum> & data)
4136  {
4137  // Fill those requests
4138  const std::size_t query_size = ids.size();
4139 
4140  data.resize(query_size);
4141  for (std::size_t i=0; i != query_size; ++i)
4142  {
4143  dof_id_type constrained = ids[i];
4144  data[i].clear();
4145  if (_dof_constraints.count(constrained))
4146  {
4147  DofConstraintValueMap::const_iterator rhsit =
4148  _primal_constraint_values.find(constrained);
4149  data[i].push_back
4150  ((rhsit == _primal_constraint_values.end()) ?
4151  0 : rhsit->second);
4152 
4153  for (unsigned int q = 0; q != max_qoi_num; ++q)
4154  {
4155  AdjointDofConstraintValues::const_iterator adjoint_map_it =
4157 
4158  if (adjoint_map_it == _adjoint_constraint_values.end())
4159  {
4160  data[i].push_back(0);
4161  continue;
4162  }
4163 
4164  const DofConstraintValueMap & constraint_map =
4165  adjoint_map_it->second;
4166 
4167  DofConstraintValueMap::const_iterator adj_rhsit =
4168  constraint_map.find(constrained);
4169  data[i].push_back
4170  ((adj_rhsit == constraint_map.end()) ?
4171  0 : adj_rhsit->second);
4172  }
4173  }
4174  }
4175  };
4176 
4177  auto row_action_functor =
4178  [this,
4179  & unexpanded_dofs]
4181  const std::vector<dof_id_type> & ids,
4182  const std::vector<row_datum> & data)
4183  {
4184  // Add any new constraint rows we've found
4185  const std::size_t query_size = ids.size();
4186 
4187  for (std::size_t i=0; i != query_size; ++i)
4188  {
4189  const dof_id_type constrained = ids[i];
4190 
4191  // An empty row is an constraint with an empty row; for
4192  // no constraint we use a "no row" placeholder
4193  if (data[i].empty())
4194  {
4195  DofConstraintRow & row = _dof_constraints[constrained];
4196  row.clear();
4197  }
4198  else if (data[i][0].first != DofObject::invalid_id)
4199  {
4200  DofConstraintRow & row = _dof_constraints[constrained];
4201  row.clear();
4202  for (auto & pair : data[i])
4203  {
4204  libmesh_assert_less(pair.first, this->n_dofs());
4205  row[pair.first] = pair.second;
4206  }
4207 
4208  // And prepare to check for more recursive constraints
4209  unexpanded_dofs.insert(constrained);
4210  }
4211  }
4212  };
4213 
4214  auto rhss_action_functor =
4215  [this,
4216  max_qoi_num]
4218  const std::vector<dof_id_type> & ids,
4219  const std::vector<rhss_datum> & data)
4220  {
4221  // Add rhs data for any new constraint rows we've found
4222  const std::size_t query_size = ids.size();
4223 
4224  for (std::size_t i=0; i != query_size; ++i)
4225  {
4226  if (!data[i].empty())
4227  {
4228  dof_id_type constrained = ids[i];
4229  if (data[i][0] != Number(0))
4230  _primal_constraint_values[constrained] = data[i][0];
4231  else
4232  _primal_constraint_values.erase(constrained);
4233 
4234  for (unsigned int q = 0; q != max_qoi_num; ++q)
4235  {
4236  AdjointDofConstraintValues::iterator adjoint_map_it =
4238 
4239  if ((adjoint_map_it == _adjoint_constraint_values.end()) &&
4240  data[i][q+1] == Number(0))
4241  continue;
4242 
4243  if (adjoint_map_it == _adjoint_constraint_values.end())
4244  adjoint_map_it = _adjoint_constraint_values.insert
4245  (std::make_pair(q,DofConstraintValueMap())).first;
4246 
4247  DofConstraintValueMap & constraint_map =
4248  adjoint_map_it->second;
4249 
4250  if (data[i][q+1] != Number(0))
4251  constraint_map[constrained] =
4252  data[i][q+1];
4253  else
4254  constraint_map.erase(constrained);
4255  }
4256  }
4257  }
4258 
4259  };
4260 
4261  // Now request constraint rows from other processors
4262  row_datum * row_ex = nullptr;
4263  Parallel::pull_parallel_vector_data
4264  (this->comm(), requested_dof_ids, row_gather_functor,
4265  row_action_functor, row_ex);
4266 
4267  // And request constraint right hand sides from other procesors
4268  rhss_datum * rhs_ex = nullptr;
4269  Parallel::pull_parallel_vector_data
4270  (this->comm(), requested_dof_ids, rhss_gather_functor,
4271  rhss_action_functor, rhs_ex);
4272 
4273  // We have to keep recursing while the unexpanded set is
4274  // nonempty on *any* processor
4275  unexpanded_set_nonempty = !unexpanded_dofs.empty();
4276  this->comm().max(unexpanded_set_nonempty);
4277  }
4278 }

References _adjoint_constraint_values, _dof_constraints, _end_df, _primal_constraint_values, libMesh::ParallelObject::comm(), data, libMesh::DofObject::invalid_id, libMesh::libmesh_assert(), local_index(), and libMesh::Real.

Referenced by allgather_recursive_constraints(), and scatter_constraints().

◆ get_adjoint_dirichlet_boundaries() [1/2]

DirichletBoundaries * libMesh::DofMap::get_adjoint_dirichlet_boundaries ( unsigned int  q)

Definition at line 4427 of file dof_map_constraints.C.

4428 {
4429  unsigned int old_size = cast_int<unsigned int>
4431  for (unsigned int i = old_size; i <= q; ++i)
4433 
4435 }

References _adjoint_dirichlet_boundaries.

◆ get_adjoint_dirichlet_boundaries() [2/2]

const DirichletBoundaries * libMesh::DofMap::get_adjoint_dirichlet_boundaries ( unsigned int  q) const

Definition at line 4419 of file dof_map_constraints.C.

4420 {
4421  libmesh_assert_greater(_adjoint_dirichlet_boundaries.size(),q);
4423 }

References _adjoint_dirichlet_boundaries.

◆ get_dirichlet_boundaries() [1/2]

DirichletBoundaries* libMesh::DofMap::get_dirichlet_boundaries ( )
inline

Definition at line 1338 of file dof_map.h.

1339  {
1340  return _dirichlet_boundaries.get();
1341  }

References _dirichlet_boundaries.

◆ get_dirichlet_boundaries() [2/2]

const DirichletBoundaries* libMesh::DofMap::get_dirichlet_boundaries ( ) const
inline

Definition at line 1333 of file dof_map.h.

1334  {
1335  return _dirichlet_boundaries.get();
1336  }

References _dirichlet_boundaries.

Referenced by libMesh::DifferentiableSystem::add_dot_var_dirichlet_bcs().

◆ get_info() [1/2]

std::string libMesh::ReferenceCounter::get_info ( )
staticinherited

Gets a string containing the reference information.

Definition at line 47 of file reference_counter.C.

48 {
49 #if defined(LIBMESH_ENABLE_REFERENCE_COUNTING) && defined(DEBUG)
50 
51  std::ostringstream oss;
52 
53  oss << '\n'
54  << " ---------------------------------------------------------------------------- \n"
55  << "| Reference count information |\n"
56  << " ---------------------------------------------------------------------------- \n";
57 
58  for (const auto & pr : _counts)
59  {
60  const std::string name(pr.first);
61  const unsigned int creations = pr.second.first;
62  const unsigned int destructions = pr.second.second;
63 
64  oss << "| " << name << " reference count information:\n"
65  << "| Creations: " << creations << '\n'
66  << "| Destructions: " << destructions << '\n';
67  }
68 
69  oss << " ---------------------------------------------------------------------------- \n";
70 
71  return oss.str();
72 
73 #else
74 
75  return "";
76 
77 #endif
78 }

References libMesh::ReferenceCounter::_counts, and libMesh::Quality::name().

Referenced by libMesh::ReferenceCounter::print_info().

◆ get_info() [2/2]

std::string libMesh::DofMap::get_info ( ) const

Gets summary info about the sparsity bandwidth and constraints.

Definition at line 2843 of file dof_map.C.

2844 {
2845  std::ostringstream os;
2846 
2847  // If we didn't calculate the exact sparsity pattern, the threaded
2848  // sparsity pattern assembly may have just given us an upper bound
2849  // on sparsity.
2850  const char * may_equal = " <= ";
2851 
2852  // If we calculated the exact sparsity pattern, then we can report
2853  // exact bandwidth figures:
2854  for (const auto & mat : _matrices)
2855  if (mat->need_full_sparsity_pattern())
2856  may_equal = " = ";
2857 
2858  dof_id_type max_n_nz = 0, max_n_oz = 0;
2859  long double avg_n_nz = 0, avg_n_oz = 0;
2860 
2861  if (_n_nz)
2862  {
2863  for (const auto & val : *_n_nz)
2864  {
2865  max_n_nz = std::max(max_n_nz, val);
2866  avg_n_nz += val;
2867  }
2868 
2869  std::size_t n_nz_size = _n_nz->size();
2870 
2871  this->comm().max(max_n_nz);
2872  this->comm().sum(avg_n_nz);
2873  this->comm().sum(n_nz_size);
2874 
2875  avg_n_nz /= std::max(n_nz_size,std::size_t(1));
2876 
2878 
2879  for (const auto & val : *_n_oz)
2880  {
2881  max_n_oz = std::max(max_n_oz, val);
2882  avg_n_oz += val;
2883  }
2884 
2885  std::size_t n_oz_size = _n_oz->size();
2886 
2887  this->comm().max(max_n_oz);
2888  this->comm().sum(avg_n_oz);
2889  this->comm().sum(n_oz_size);
2890 
2891  avg_n_oz /= std::max(n_oz_size,std::size_t(1));
2892  }
2893 
2894  os << " DofMap Sparsity\n Average On-Processor Bandwidth"
2895  << may_equal << avg_n_nz << '\n';
2896 
2897  os << " Average Off-Processor Bandwidth"
2898  << may_equal << avg_n_oz << '\n';
2899 
2900  os << " Maximum On-Processor Bandwidth"
2901  << may_equal << max_n_nz << '\n';
2902 
2903  os << " Maximum Off-Processor Bandwidth"
2904  << may_equal << max_n_oz << std::endl;
2905 
2906 #ifdef LIBMESH_ENABLE_CONSTRAINTS
2907 
2908  std::size_t n_constraints = 0, max_constraint_length = 0,
2909  n_rhss = 0;
2910  long double avg_constraint_length = 0.;
2911 
2912  for (const auto & pr : _dof_constraints)
2913  {
2914  // Only count local constraints, then sum later
2915  const dof_id_type constrained_dof = pr.first;
2916  if (!this->local_index(constrained_dof))
2917  continue;
2918 
2919  const DofConstraintRow & row = pr.second;
2920  std::size_t rowsize = row.size();
2921 
2922  max_constraint_length = std::max(max_constraint_length,
2923  rowsize);
2924  avg_constraint_length += rowsize;
2925  n_constraints++;
2926 
2927  if (_primal_constraint_values.count(constrained_dof))
2928  n_rhss++;
2929  }
2930 
2931  this->comm().sum(n_constraints);
2932  this->comm().sum(n_rhss);
2933  this->comm().sum(avg_constraint_length);
2934  this->comm().max(max_constraint_length);
2935 
2936  os << " DofMap Constraints\n Number of DoF Constraints = "
2937  << n_constraints;
2938  if (n_rhss)
2939  os << '\n'
2940  << " Number of Heterogenous Constraints= " << n_rhss;
2941  if (n_constraints)
2942  {
2943  avg_constraint_length /= n_constraints;
2944 
2945  os << '\n'
2946  << " Average DoF Constraint Length= " << avg_constraint_length;
2947  }
2948 
2949 #ifdef LIBMESH_ENABLE_NODE_CONSTRAINTS
2950  std::size_t n_node_constraints = 0, max_node_constraint_length = 0,
2951  n_node_rhss = 0;
2952  long double avg_node_constraint_length = 0.;
2953 
2954  for (const auto & pr : _node_constraints)
2955  {
2956  // Only count local constraints, then sum later
2957  const Node * node = pr.first;
2958  if (node->processor_id() != this->processor_id())
2959  continue;
2960 
2961  const NodeConstraintRow & row = pr.second.first;
2962  std::size_t rowsize = row.size();
2963 
2964  max_node_constraint_length = std::max(max_node_constraint_length,
2965  rowsize);
2966  avg_node_constraint_length += rowsize;
2967  n_node_constraints++;
2968 
2969  if (pr.second.second != Point(0))
2970  n_node_rhss++;
2971  }
2972 
2973  this->comm().sum(n_node_constraints);
2974  this->comm().sum(n_node_rhss);
2975  this->comm().sum(avg_node_constraint_length);
2976  this->comm().max(max_node_constraint_length);
2977 
2978  os << "\n Number of Node Constraints = " << n_node_constraints;
2979  if (n_node_rhss)
2980  os << '\n'
2981  << " Number of Heterogenous Node Constraints= " << n_node_rhss;
2982  if (n_node_constraints)
2983  {
2984  avg_node_constraint_length /= n_node_constraints;
2985  os << "\n Maximum Node Constraint Length= " << max_node_constraint_length
2986  << '\n'
2987  << " Average Node Constraint Length= " << avg_node_constraint_length;
2988  }
2989 #endif // LIBMESH_ENABLE_NODE_CONSTRAINTS
2990 
2991  os << std::endl;
2992 
2993 #endif // LIBMESH_ENABLE_CONSTRAINTS
2994 
2995  return os.str();
2996 }

References _dof_constraints, _matrices, _n_nz, _n_oz, _node_constraints, _primal_constraint_values, libMesh::ParallelObject::comm(), libMesh::libmesh_assert(), local_index(), libMesh::ParallelObject::processor_id(), libMesh::DofObject::processor_id(), and libMesh::TypeVector< T >::size().

Referenced by libMesh::System::get_info(), and print_info().

◆ get_local_constraints()

std::string libMesh::DofMap::get_local_constraints ( bool  print_nonlocal = false) const

Gets a string reporting all DoF and Node constraints local to this processor.

If print_nonlocal is true, then nonlocal constraints which are locally known are included.

Definition at line 1464 of file dof_map_constraints.C.

1465 {
1466  std::ostringstream os;
1467 #ifdef LIBMESH_ENABLE_NODE_CONSTRAINTS
1468  if (print_nonlocal)
1469  os << "All ";
1470  else
1471  os << "Local ";
1472 
1473  os << "Node Constraints:"
1474  << std::endl;
1475 
1476  for (const auto & pr : _node_constraints)
1477  {
1478  const Node * node = pr.first;
1479 
1480  // Skip non-local nodes if requested
1481  if (!print_nonlocal &&
1482  node->processor_id() != this->processor_id())
1483  continue;
1484 
1485  const NodeConstraintRow & row = pr.second.first;
1486  const Point & offset = pr.second.second;
1487 
1488  os << "Constraints for Node id " << node->id()
1489  << ": \t";
1490 
1491  for (const auto & item : row)
1492  os << " (" << item.first->id() << "," << item.second << ")\t";
1493 
1494  os << "rhs: " << offset;
1495 
1496  os << std::endl;
1497  }
1498 #endif // LIBMESH_ENABLE_NODE_CONSTRAINTS
1499 
1500  if (print_nonlocal)
1501  os << "All ";
1502  else
1503  os << "Local ";
1504 
1505  os << "DoF Constraints:"
1506  << std::endl;
1507 
1508  for (const auto & pr : _dof_constraints)
1509  {
1510  const dof_id_type i = pr.first;
1511 
1512  // Skip non-local dofs if requested
1513  if (!print_nonlocal && !this->local_index(i))
1514  continue;
1515 
1516  const DofConstraintRow & row = pr.second;
1517  DofConstraintValueMap::const_iterator rhsit =
1518  _primal_constraint_values.find(i);
1519  const Number rhs = (rhsit == _primal_constraint_values.end()) ?
1520  0 : rhsit->second;
1521 
1522  os << "Constraints for DoF " << i
1523  << ": \t";
1524 
1525  for (const auto & item : row)
1526  os << " (" << item.first << "," << item.second << ")\t";
1527 
1528  os << "rhs: " << rhs;
1529  os << std::endl;
1530  }
1531 
1532  for (unsigned int qoi_index = 0,
1533  n_qois = cast_int<unsigned int>(_adjoint_dirichlet_boundaries.size());
1534  qoi_index != n_qois; ++qoi_index)
1535  {
1536  os << "Adjoint " << qoi_index << " DoF rhs values:"
1537  << std::endl;
1538 
1539  AdjointDofConstraintValues::const_iterator adjoint_map_it =
1540  _adjoint_constraint_values.find(qoi_index);
1541 
1542  if (adjoint_map_it != _adjoint_constraint_values.end())
1543  for (const auto & pr : adjoint_map_it->second)
1544  {
1545  const dof_id_type i = pr.first;
1546 
1547  // Skip non-local dofs if requested
1548  if (!print_nonlocal && !this->local_index(i))
1549  continue;
1550 
1551  const Number rhs = pr.second;
1552 
1553  os << "RHS for DoF " << i
1554  << ": " << rhs;
1555 
1556  os << std::endl;
1557  }
1558  }
1559 
1560  return os.str();
1561 }

References _adjoint_constraint_values, _adjoint_dirichlet_boundaries, _dof_constraints, _node_constraints, _primal_constraint_values, libMesh::DofObject::id(), local_index(), libMesh::ParallelObject::processor_id(), and libMesh::DofObject::processor_id().

Referenced by print_dof_constraints().

◆ get_n_nz()

const std::vector<dof_id_type>& libMesh::DofMap::get_n_nz ( ) const
inline
Returns
A constant reference to the _n_nz list for this processor.

The vector contains the bandwidth of the on-processor coupling for each row of the global matrix that the current processor owns. This information can be used to preallocate space for a parallel sparse matrix.

Definition at line 505 of file dof_map.h.

506  {
508  return *_n_nz;
509  }

References _n_nz, and libMesh::libmesh_assert().

◆ get_n_oz()

const std::vector<dof_id_type>& libMesh::DofMap::get_n_oz ( ) const
inline
Returns
A constant reference to the _n_oz list for this processor.

The vector contains the bandwidth of the off-processor coupling for each row of the global matrix that the current processor owns. This information can be used to preallocate space for a parallel sparse matrix.

Definition at line 518 of file dof_map.h.

519  {
521  return *_n_oz;
522  }

References _n_oz, and libMesh::libmesh_assert().

◆ get_periodic_boundaries()

PeriodicBoundaries* libMesh::DofMap::get_periodic_boundaries ( )
inline

Definition at line 1295 of file dof_map.h.

1296  {
1297  return _periodic_boundaries.get();
1298  }

References _periodic_boundaries.

Referenced by main().

◆ get_primal_constraint_values()

DofConstraintValueMap & libMesh::DofMap::get_primal_constraint_values ( )
inline
Returns
A reference to the set of right-hand-side values in primal constraint equations

Definition at line 2007 of file dof_map.h.

2008 {
2010 }

References _primal_constraint_values.

◆ get_send_list()

const std::vector<dof_id_type>& libMesh::DofMap::get_send_list ( ) const
inline

◆ has_adjoint_dirichlet_boundaries()

bool libMesh::DofMap::has_adjoint_dirichlet_boundaries ( unsigned int  q) const

Definition at line 4409 of file dof_map_constraints.C.

4410 {
4411  if (_adjoint_dirichlet_boundaries.size() > q)
4412  return true;
4413 
4414  return false;
4415 }

References _adjoint_dirichlet_boundaries.

Referenced by libMesh::AdjointRefinementEstimator::estimate_error(), and libMesh::ImplicitSystem::weighted_sensitivity_adjoint_solve().

◆ has_blocked_representation()

bool libMesh::DofMap::has_blocked_representation ( ) const
inline
Returns
true if the variables are capable of being stored in a blocked form. Presently, this means that there can only be one variable group, and that the group has more than one variable.

Definition at line 600 of file dof_map.h.

601  {
602  return ((this->n_variable_groups() == 1) && (this->n_variables() > 1));
603  }

References n_variable_groups(), and n_variables().

Referenced by block_size().

◆ has_heterogenous_adjoint_constraint()

Number libMesh::DofMap::has_heterogenous_adjoint_constraint ( const unsigned int  qoi_num,
const dof_id_type  dof 
) const
inline
Returns
The heterogeneous constraint value if the degree of freedom dof has a heterogenous constraint for adjoint solution qoi_num, zero otherwise.

Definition at line 1986 of file dof_map.h.

1988 {
1989  AdjointDofConstraintValues::const_iterator it =
1990  _adjoint_constraint_values.find(qoi_num);
1991  if (it != _adjoint_constraint_values.end())
1992  {
1993  DofConstraintValueMap::const_iterator rhsit =
1994  it->second.find(dof);
1995  if (rhsit == it->second.end())
1996  return 0;
1997  else
1998  return rhsit->second;
1999  }
2000 
2001  return 0;
2002 }

References _adjoint_constraint_values.

◆ has_heterogenous_adjoint_constraints()

bool libMesh::DofMap::has_heterogenous_adjoint_constraints ( const unsigned int  qoi_num) const
inline
Returns
true if the system has any heterogenous constraints for adjoint solution qoi_num, false otherwise.

Definition at line 1972 of file dof_map.h.

1973 {
1974  AdjointDofConstraintValues::const_iterator it =
1975  _adjoint_constraint_values.find(qoi_num);
1976  if (it == _adjoint_constraint_values.end())
1977  return false;
1978  if (it->second.empty())
1979  return false;
1980 
1981  return true;
1982 }

References _adjoint_constraint_values.

◆ heterogenously_constrain_element_matrix_and_vector()

void libMesh::DofMap::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
inline

Constrains the element matrix and vector.

This method requires the element matrix to be square, in which case the elem_dofs correspond to the global DOF indices of both the rows and columns of the element matrix. For this case the rows and columns of the matrix necessarily correspond to variables of the same approximation order.

The heterogenous version of this method creates linear systems in which heterogenously constrained degrees of freedom will solve to their correct offset values, as would be appropriate for finding a solution to a linear problem in a single algebraic solve. The non-heterogenous version of this method creates linear systems in which even heterogenously constrained degrees of freedom are solved without offset values taken into account, as would be appropriate for finding linearized updates to a solution in which heterogenous constraints are already satisfied.

By default, the constraints for the primal solution of this system are used. If a non-negative qoi_index is passed in, then the constraints for the corresponding adjoint solution are used instead.

Definition at line 2040 of file dof_map.h.

2041  {}

Referenced by assemble_stokes().

◆ heterogenously_constrain_element_vector()

void libMesh::DofMap::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
inline

Constrains the element vector.

This method requires the element matrix to be square and not-yet-constrained, in which case the elem_dofs correspond to the global DOF indices of both the rows and columns of the element matrix.

The heterogenous version of this method creates linear systems in which heterogenously constrained degrees of freedom will solve to their correct offset values, as would be appropriate for finding a solution to a linear problem in a single algebraic solve. The non-heterogenous version of this method creates linear systems in which even heterogenously constrained degrees of freedom are solved without offset values taken into account, as would be appropriate for finding linearized updates to a solution in which heterogenous constraints are already satisfied.

By default, the constraints for the primal solution of this system are used. If a non-negative qoi_index is passed in, then the constraints for the corresponding adjoint solution are used instead.

Definition at line 2044 of file dof_map.h.

2045  {}

◆ increment_constructor_count()

void libMesh::ReferenceCounter::increment_constructor_count ( const std::string &  name)
inlineprotectedinherited

Increments the construction counter.

Should be called in the constructor of any derived class that will be reference counted.

Definition at line 181 of file reference_counter.h.

182 {
183  Threads::spin_mutex::scoped_lock lock(Threads::spin_mtx);
184  std::pair<unsigned int, unsigned int> & p = _counts[name];
185 
186  p.first++;
187 }

References libMesh::ReferenceCounter::_counts, libMesh::Quality::name(), and libMesh::Threads::spin_mtx.

Referenced by libMesh::ReferenceCountedObject< RBParametrized >::ReferenceCountedObject().

◆ increment_destructor_count()

void libMesh::ReferenceCounter::increment_destructor_count ( const std::string &  name)
inlineprotectedinherited

Increments the destruction counter.

Should be called in the destructor of any derived class that will be reference counted.

Definition at line 194 of file reference_counter.h.

195 {
196  Threads::spin_mutex::scoped_lock lock(Threads::spin_mtx);
197  std::pair<unsigned int, unsigned int> & p = _counts[name];
198 
199  p.second++;
200 }

References libMesh::ReferenceCounter::_counts, libMesh::Quality::name(), and libMesh::Threads::spin_mtx.

Referenced by libMesh::ReferenceCountedObject< RBParametrized >::~ReferenceCountedObject().

◆ invalidate_dofs()

void libMesh::DofMap::invalidate_dofs ( MeshBase mesh) const
private

Invalidates all active DofObject dofs for this system.

Definition at line 819 of file dof_map.C.

820 {
821  const unsigned int sys_num = this->sys_number();
822 
823  // All the nodes
824  for (auto & node : mesh.node_ptr_range())
825  node->invalidate_dofs(sys_num);
826 
827  // All the active elements.
828  for (auto & elem : mesh.active_element_ptr_range())
829  elem->invalidate_dofs(sys_num);
830 }

References mesh, and sys_number().

Referenced by distribute_dofs(), and reinit().

◆ is_attached()

bool libMesh::DofMap::is_attached ( SparseMatrix< Number > &  matrix)

Matrices should not be attached more than once.

We can test for an already-attached matrix if necessary using is_attached

Definition at line 310 of file dof_map.C.

311 {
312  return (std::find(_matrices.begin(), _matrices.end(),
313  &matrix) != _matrices.end());
314 }

References _matrices.

Referenced by libMesh::ImplicitSystem::init_matrices(), and OverlappingCouplingGhostingTest::run_sparsity_pattern_test().

◆ is_constrained_dof()

bool libMesh::DofMap::is_constrained_dof ( const dof_id_type  dof) const
inline

◆ is_constrained_node()

bool libMesh::DofMap::is_constrained_node ( const Node node) const
inline
Returns
true if the Node is constrained, false otherwise.

Definition at line 1946 of file dof_map.h.

1951 {
1952 #ifdef LIBMESH_ENABLE_NODE_CONSTRAINTS
1953  if (_node_constraints.count(node))
1954  return true;
1955 #endif
1956 
1957  return false;
1958 }

References _node_constraints.

Referenced by allgather_recursive_constraints(), and scatter_constraints().

◆ is_evaluable()

template<typename DofObjectSubclass >
template bool libMesh::DofMap::is_evaluable< Node > ( const DofObjectSubclass &  obj,
unsigned int  var_num = libMesh::invalid_uint 
) const
Returns
true iff our solutions can be locally evaluated on obj (which should be an Elem or a Node) for variable number var_num (for all variables, if var_num is invalid_uint)

Definition at line 2553 of file dof_map.C.

2555 {
2556  // Everything is evaluable on a local object
2557  if (obj.processor_id() == this->processor_id())
2558  return true;
2559 
2560  std::vector<dof_id_type> di;
2561 
2562  if (var_num == libMesh::invalid_uint)
2563  this->dof_indices(&obj, di);
2564  else
2565  this->dof_indices(&obj, di, var_num);
2566 
2567  return this->all_semilocal_indices(di);
2568 }

References all_semilocal_indices(), dof_indices(), libMesh::invalid_uint, and libMesh::ParallelObject::processor_id().

Referenced by libMesh::System::point_gradient(), libMesh::System::point_hessian(), libMesh::System::point_value(), DefaultCouplingTest::testCoupling(), and PointNeighborCouplingTest::testCoupling().

◆ is_periodic_boundary()

bool libMesh::DofMap::is_periodic_boundary ( const boundary_id_type  boundaryid) const
Returns
true if the boundary given by boundaryid is periodic, false otherwise

Definition at line 224 of file dof_map.C.

225 {
226  if (_periodic_boundaries->count(boundaryid) != 0)
227  return true;
228 
229  return false;
230 }

References _periodic_boundaries.

◆ last_dof() [1/2]

dof_id_type libMesh::DofMap::last_dof ( ) const
inline

Definition at line 682 of file dof_map.h.

683  { return this->last_dof(this->processor_id()); }

References libMesh::ParallelObject::processor_id().

◆ last_dof() [2/2]

dof_id_type libMesh::DofMap::last_dof ( const processor_id_type  proc) const
inline
Returns
The last dof index that is local to processor proc.

Definition at line 675 of file dof_map.h.

676  {
677  libmesh_deprecated();
678  libmesh_assert_less (proc, _end_df.size());
679  return cast_int<dof_id_type>(_end_df[proc] - 1);
680  }

References _end_df.

◆ local_index()

bool libMesh::DofMap::local_index ( dof_id_type  dof_index) const
inline
Returns
true if degree of freedom index dof_index is a local index.

Definition at line 815 of file dof_map.h.

816  { return (dof_index >= this->first_dof()) && (dof_index < this->end_dof()); }

References end_dof(), and first_dof().

Referenced by add_constraints_to_send_list(), add_neighbors_to_send_list(), gather_constraints(), get_info(), get_local_constraints(), local_variable_indices(), semilocal_index(), and libMesh::PetscDMWrapper::set_point_range_in_section().

◆ local_variable_indices()

void libMesh::DofMap::local_variable_indices ( std::vector< dof_id_type > &  idx,
const MeshBase mesh,
unsigned int  var_num 
) const

Fills an array of those dof indices which belong to the given variable number and live on the current processor.

Definition at line 1084 of file dof_map.C.

1087 {
1088  // Count dofs in the *exact* order that distribute_dofs numbered
1089  // them, so that we can assume ascending indices and use push_back
1090  // instead of find+insert.
1091 
1092  const unsigned int sys_num = this->sys_number();
1093 
1094  // If this isn't a SCALAR variable, we need to find all its field
1095  // dofs on the mesh
1096  if (this->variable_type(var_num).family != SCALAR)
1097  {
1098  const Variable & var(this->variable(var_num));
1099 
1100  for (auto & elem : mesh.active_local_element_ptr_range())
1101  {
1102  if (!var.active_on_subdomain(elem->subdomain_id()))
1103  continue;
1104 
1105  // Only count dofs connected to active
1106  // elements on this processor.
1107  const unsigned int n_nodes = elem->n_nodes();
1108 
1109  // First get any new nodal DOFS
1110  for (unsigned int n=0; n<n_nodes; n++)
1111  {
1112  Node & node = elem->node_ref(n);
1113 
1114  if (node.processor_id() != this->processor_id())
1115  continue;
1116 
1117  const unsigned int n_comp = node.n_comp(sys_num, var_num);
1118  for(unsigned int i=0; i<n_comp; i++)
1119  {
1120  const dof_id_type index = node.dof_number(sys_num,var_num,i);
1121  libmesh_assert (this->local_index(index));
1122 
1123  if (idx.empty() || index > idx.back())
1124  idx.push_back(index);
1125  }
1126  }
1127 
1128  // Next get any new element DOFS
1129  const unsigned int n_comp = elem->n_comp(sys_num, var_num);
1130  for (unsigned int i=0; i<n_comp; i++)
1131  {
1132  const dof_id_type index = elem->dof_number(sys_num,var_num,i);
1133  if (idx.empty() || index > idx.back())
1134  idx.push_back(index);
1135  }
1136  } // done looping over elements
1137 
1138 
1139  // we may have missed assigning DOFs to nodes that we own
1140  // but to which we have no connected elements matching our
1141  // variable restriction criterion. this will happen, for example,
1142  // if variable V is restricted to subdomain S. We may not own
1143  // any elements which live in S, but we may own nodes which are
1144  // *connected* to elements which do. in this scenario these nodes
1145  // will presently have unnumbered DOFs. we need to take care of
1146  // them here since we own them and no other processor will touch them.
1147  for (const auto & node : mesh.local_node_ptr_range())
1148  {
1149  libmesh_assert(node);
1150 
1151  const unsigned int n_comp = node->n_comp(sys_num, var_num);
1152  for (unsigned int i=0; i<n_comp; i++)
1153  {
1154  const dof_id_type index = node->dof_number(sys_num,var_num,i);
1155  if (idx.empty() || index > idx.back())
1156  idx.push_back(index);
1157  }
1158  }
1159  }
1160  // Otherwise, count up the SCALAR dofs, if we're on the processor
1161  // that holds this SCALAR variable
1162  else if (this->processor_id() == (this->n_processors()-1))
1163  {
1164  std::vector<dof_id_type> di_scalar;
1165  this->SCALAR_dof_indices(di_scalar,var_num);
1166  idx.insert( idx.end(), di_scalar.begin(), di_scalar.end());
1167  }
1168 }

References libMesh::Variable::active_on_subdomain(), libMesh::DofObject::dof_number(), libMesh::MeshTools::Generation::Private::idx(), libMesh::libmesh_assert(), local_index(), mesh, libMesh::DofObject::n_comp(), n_nodes, libMesh::ParallelObject::n_processors(), libMesh::ParallelObject::processor_id(), libMesh::DofObject::processor_id(), libMesh::SCALAR, SCALAR_dof_indices(), sys_number(), variable(), and variable_type().

Referenced by libMesh::PetscDMWrapper::init_and_attach_petscdm(), libMesh::petsc_auto_fieldsplit(), and SystemsTest::testBlockRestrictedVarNDofs().

◆ max_constraint_error()

std::pair< Real, Real > libMesh::DofMap::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 on the mesh, returning a pair whose first entry is the maximum absolute error on a constrained DoF and whose second entry is the maximum relative error.

Useful for debugging purposes.

If v == nullptr, the system solution vector is tested.

Definition at line 2373 of file dof_map_constraints.C.

2375 {
2376  if (!v)
2377  v = system.solution.get();
2378  NumericVector<Number> & vec = *v;
2379 
2380  // We'll assume the vector is closed
2381  libmesh_assert (vec.closed());
2382 
2383  Real max_absolute_error = 0., max_relative_error = 0.;
2384 
2385  const MeshBase & mesh = system.get_mesh();
2386 
2387  libmesh_assert_equal_to (this, &(system.get_dof_map()));
2388 
2389  // indices on each element
2390  std::vector<dof_id_type> local_dof_indices;
2391 
2392  for (const auto & elem : mesh.active_local_element_ptr_range())
2393  {
2394  this->dof_indices(elem, local_dof_indices);
2395  std::vector<dof_id_type> raw_dof_indices = local_dof_indices;
2396 
2397  // Constraint matrix for each element
2399 
2400  this->build_constraint_matrix (C, local_dof_indices);
2401 
2402  // Continue if the element is unconstrained
2403  if (!C.m())
2404  continue;
2405 
2406  libmesh_assert_equal_to (C.m(), raw_dof_indices.size());
2407  libmesh_assert_equal_to (C.n(), local_dof_indices.size());
2408 
2409  for (auto i : IntRange<unsigned int>(0, C.m()))
2410  {
2411  // Recalculate any constrained dof owned by this processor
2412  dof_id_type global_dof = raw_dof_indices[i];
2413  if (this->is_constrained_dof(global_dof) &&
2414  global_dof >= vec.first_local_index() &&
2415  global_dof < vec.last_local_index())
2416  {
2417 #ifndef NDEBUG
2418  DofConstraints::const_iterator
2419  pos = _dof_constraints.find(global_dof);
2420 
2421  libmesh_assert (pos != _dof_constraints.end());
2422 #endif
2423 
2424  Number exact_value = 0;
2425  DofConstraintValueMap::const_iterator rhsit =
2426  _primal_constraint_values.find(global_dof);
2427  if (rhsit != _primal_constraint_values.end())
2428  exact_value = rhsit->second;
2429 
2430  for (auto j : IntRange<unsigned int>(0, C.n()))
2431  {
2432  if (local_dof_indices[j] != global_dof)
2433  exact_value += C(i,j) *
2434  vec(local_dof_indices[j]);
2435  }
2436 
2437  max_absolute_error = std::max(max_absolute_error,
2438  std::abs(vec(global_dof) - exact_value));
2439  max_relative_error = std::max(max_relative_error,
2440  std::abs(vec(global_dof) - exact_value)
2441  / std::abs(exact_value));
2442  }
2443  }
2444  }
2445 
2446  return std::pair<Real, Real>(max_absolute_error, max_relative_error);
2447 }

References _dof_constraints, _primal_constraint_values, std::abs(), libMesh::MeshBase::active_local_element_ptr_range(), build_constraint_matrix(), libMesh::NumericVector< T >::closed(), dof_indices(), exact_value(), libMesh::NumericVector< T >::first_local_index(), libMesh::System::get_dof_map(), libMesh::System::get_mesh(), is_constrained_dof(), libMesh::NumericVector< T >::last_local_index(), libMesh::libmesh_assert(), libMesh::DenseMatrixBase< T >::m(), mesh, libMesh::DenseMatrixBase< T >::n(), libMesh::Real, and libMesh::System::solution.

◆ merge_ghost_functor_outputs()

void libMesh::DofMap::merge_ghost_functor_outputs ( GhostingFunctor::map_type elements_to_ghost,
std::set< CouplingMatrix * > &  temporary_coupling_matrices,
const std::set< GhostingFunctor * >::iterator &  gf_begin,
const std::set< GhostingFunctor * >::iterator &  gf_end,
const MeshBase::const_element_iterator elems_begin,
const MeshBase::const_element_iterator elems_end,
processor_id_type  p 
)
staticprivate

Definition at line 1440 of file dof_map.C.

1447 {
1448  for (const auto & gf : as_range(gf_begin, gf_end))
1449  {
1450  GhostingFunctor::map_type more_elements_to_ghost;
1451 
1452  libmesh_assert(gf);
1453  (*gf)(elems_begin, elems_end, p, more_elements_to_ghost);
1454 
1455  for (const auto & pr : more_elements_to_ghost)
1456  {
1457  GhostingFunctor::map_type::iterator existing_it =
1458  elements_to_ghost.find (pr.first);
1459  if (existing_it == elements_to_ghost.end())
1460  elements_to_ghost.insert(pr);
1461  else
1462  {
1463  if (existing_it->second)
1464  {
1465  if (pr.second)
1466  {
1467  // If this isn't already a temporary
1468  // then we need to make one so we'll
1469  // have a non-const matrix to merge
1470  if (temporary_coupling_matrices.empty() ||
1471  temporary_coupling_matrices.find(const_cast<CouplingMatrix *>(existing_it->second)) == temporary_coupling_matrices.end())
1472  {
1473  CouplingMatrix * cm = new CouplingMatrix(*existing_it->second);
1474  temporary_coupling_matrices.insert(cm);
1475  existing_it->second = cm;
1476  }
1477  const_cast<CouplingMatrix &>(*existing_it->second) &= *pr.second;
1478  }
1479  else
1480  {
1481  // Any existing_it matrix merged with a full
1482  // matrix (symbolized as nullptr) gives another
1483  // full matrix (symbolizable as nullptr).
1484 
1485  // So if existing_it->second is a temporary then
1486  // we don't need it anymore; we might as well
1487  // remove it to keep the set of temporaries
1488  // small.
1489  std::set<CouplingMatrix *>::iterator temp_it =
1490  temporary_coupling_matrices.find(const_cast<CouplingMatrix *>(existing_it->second));
1491  if (temp_it != temporary_coupling_matrices.end())
1492  temporary_coupling_matrices.erase(temp_it);
1493 
1494  existing_it->second = nullptr;
1495  }
1496  }
1497  // else we have a nullptr already, then we have a full
1498  // coupling matrix, already, and merging with anything
1499  // else won't change that, so we're done.
1500  }
1501  }
1502  }
1503 }

References libMesh::as_range(), and libMesh::libmesh_assert().

Referenced by add_neighbors_to_send_list(), libMesh::SparsityPattern::Build::operator()(), and scatter_constraints().

◆ n_constrained_dofs()

dof_id_type libMesh::DofMap::n_constrained_dofs ( ) const
Returns
The total number of constrained degrees of freedom in the problem.

Definition at line 1184 of file dof_map_constraints.C.

1185 {
1186  parallel_object_only();
1187 
1188  dof_id_type nc_dofs = this->n_local_constrained_dofs();
1189  this->comm().sum(nc_dofs);
1190  return nc_dofs;
1191 }

References libMesh::ParallelObject::comm(), and n_local_constrained_dofs().

Referenced by MeshInputTest::testDynaReadPatch().

◆ n_constrained_nodes()

dof_id_type libMesh::DofMap::n_constrained_nodes ( ) const
inline
Returns
The total number of constrained Nodes in the mesh.

Definition at line 887 of file dof_map.h.

888  { return cast_int<dof_id_type>(_node_constraints.size()); }

References _node_constraints.

◆ n_dofs()

dof_id_type libMesh::DofMap::n_dofs ( ) const
inline

◆ n_dofs_on_processor()

dof_id_type libMesh::DofMap::n_dofs_on_processor ( const processor_id_type  proc) const
inline
Returns
The number of degrees of freedom on partition proc.

Definition at line 641 of file dof_map.h.

642  {
643  libmesh_assert_less (proc, _first_df.size());
644  return cast_int<dof_id_type>(_end_df[proc] - _first_df[proc]);
645  }

References _end_df, and _first_df.

Referenced by build_sparsity(), libMesh::PetscDMWrapper::init_and_attach_petscdm(), libMesh::SparsityPattern::Build::join(), n_local_dofs(), libMesh::SparsityPattern::Build::operator()(), libMesh::SparsityPattern::Build::parallel_sync(), SystemsTest::testProjectMatrix1D(), SystemsTest::testProjectMatrix2D(), and SystemsTest::testProjectMatrix3D().

◆ n_local_constrained_dofs()

dof_id_type libMesh::DofMap::n_local_constrained_dofs ( ) const
Returns
The number of constrained degrees of freedom on this processor.

Definition at line 1194 of file dof_map_constraints.C.

1195 {
1196  const DofConstraints::const_iterator lower =
1197  _dof_constraints.lower_bound(this->first_dof()),
1198  upper =
1199  _dof_constraints.upper_bound(this->end_dof()-1);
1200 
1201  return cast_int<dof_id_type>(std::distance(lower, upper));
1202 }

References _dof_constraints, distance(), end_dof(), and first_dof().

Referenced by n_constrained_dofs().

◆ n_local_dofs()

dof_id_type libMesh::DofMap::n_local_dofs ( ) const
inline
Returns
The number of degrees of freedom on this processor.

Definition at line 635 of file dof_map.h.

636  { return this->n_dofs_on_processor (this->processor_id()); }

References n_dofs_on_processor(), and libMesh::ParallelObject::processor_id().

Referenced by libMesh::PetscDMWrapper::build_sf(), libMesh::PetscDMWrapper::init_and_attach_petscdm(), and libMesh::PetscDMWrapper::set_point_range_in_section().

◆ n_objects()

static unsigned int libMesh::ReferenceCounter::n_objects ( )
inlinestaticinherited

Prints the number of outstanding (created, but not yet destroyed) objects.

Definition at line 83 of file reference_counter.h.

84  { return _n_objects; }

References libMesh::ReferenceCounter::_n_objects.

◆ n_old_dofs()

dof_id_type libMesh::DofMap::n_old_dofs ( ) const
inline
Returns
The total number of degrees of freedom on old_dof_objects

Definition at line 1384 of file dof_map.h.

1384 { return _n_old_dfs; }

References _n_old_dfs.

Referenced by SCALAR_dof_indices().

◆ n_processors()

processor_id_type libMesh::ParallelObject::n_processors ( ) const
inlineinherited
Returns
The number of processors in the group.

Definition at line 100 of file parallel_object.h.

101  { return cast_int<processor_id_type>(_communicator.size()); }

References libMesh::ParallelObject::_communicator.

Referenced by libMesh::BoundaryInfo::_find_id_maps(), add_constraints_to_send_list(), libMesh::PetscDMWrapper::add_dofs_to_section(), libMesh::DistributedMesh::add_elem(), add_neighbors_to_send_list(), libMesh::DistributedMesh::add_node(), libMesh::LaplaceMeshSmoother::allgather_graph(), allgather_recursive_constraints(), libMesh::FEMSystem::assembly(), libMesh::AztecLinearSolver< T >::AztecLinearSolver(), libMesh::BoundaryInfo::build_node_list_from_side_list(), libMesh::EquationSystems::build_parallel_elemental_solution_vector(), libMesh::DistributedMesh::clear(), libMesh::Nemesis_IO_Helper::compute_border_node_ids(), libMesh::Nemesis_IO_Helper::construct_nemesis_filename(), libMesh::ExodusII_IO::copy_scalar_solution(), libMesh::UnstructuredMesh::create_pid_mesh(), libMesh::MeshTools::create_processor_bounding_box(), distribute_dofs(), distribute_local_dofs_node_major(), distribute_local_dofs_var_major(), libMesh::EnsightIO::EnsightIO(), libMesh::SystemSubsetBySubdomain::init(), libMesh::PetscDMWrapper::init_and_attach_petscdm(), libMesh::Nemesis_IO_Helper::initialize(), libMesh::DistributedMesh::insert_elem(), libMesh::MeshTools::libmesh_assert_contiguous_dof_ids(), libMesh::MeshTools::libmesh_assert_parallel_consistent_new_node_procids(), libMesh::MeshTools::libmesh_assert_parallel_consistent_procids< Elem >(), libMesh::MeshTools::libmesh_assert_parallel_consistent_procids< Node >(), libMesh::MeshTools::libmesh_assert_topology_consistent_procids< Node >(), libMesh::MeshTools::libmesh_assert_valid_boundary_ids(), libMesh::MeshTools::libmesh_assert_valid_dof_ids(), libMesh::MeshTools::libmesh_assert_valid_neighbors(), libMesh::MeshTools::libmesh_assert_valid_refinement_flags(), local_variable_indices(), libMesh::MeshRefinement::make_coarsening_compatible(), libMesh::MeshBase::partition(), libMesh::System::point_gradient(), libMesh::System::point_hessian(), libMesh::System::point_value(), prepare_send_list(), print_dof_constraints(), libMesh::NameBasedIO::read(), libMesh::Nemesis_IO::read(), libMesh::CheckpointIO::read(), libMesh::CheckpointIO::read_connectivity(), libMesh::XdrIO::read_header(), libMesh::CheckpointIO::read_nodes(), libMesh::System::read_parallel_data(), libMesh::System::read_SCALAR_dofs(), libMesh::System::read_serialized_blocked_dof_objects(), libMesh::System::read_serialized_vector(), libMesh::DistributedMesh::renumber_dof_objects(), OverlappingFunctorTest::run_partitioner_test(), scatter_constraints(), set_nonlocal_dof_objects(), libMesh::PetscDMWrapper::set_point_range_in_section(), CheckpointIOTest::testSplitter(), WriteVecAndScalar::testWrite(), libMesh::MeshRefinement::uniformly_coarsen(), libMesh::DistributedMesh::update_parallel_id_counts(), libMesh::GMVIO::write_binary(), libMesh::GMVIO::write_discontinuous_gmv(), libMesh::VTKIO::write_nodal_data(), libMesh::System::write_parallel_data(), libMesh::System::write_SCALAR_dofs(), libMesh::XdrIO::write_serialized_bcs_helper(), libMesh::System::write_serialized_blocked_dof_objects(), libMesh::XdrIO::write_serialized_connectivity(), libMesh::XdrIO::write_serialized_nodes(), and libMesh::XdrIO::write_serialized_nodesets().

◆ n_SCALAR_dofs()

dof_id_type libMesh::DofMap::n_SCALAR_dofs ( ) const
inline
Returns
The number of SCALAR dofs.

Definition at line 630 of file dof_map.h.

630 { return _n_SCALAR_dofs; }

References _n_SCALAR_dofs.

Referenced by distribute_dofs(), SCALAR_dof_indices(), and libMesh::PetscDMWrapper::set_point_range_in_section().

◆ n_variable_groups()

unsigned int libMesh::DofMap::n_variable_groups ( ) const
inline
Returns
The number of variables in the global solution vector. Defaults to 1, should be 1 for a scalar equation, 3 for 2D incompressible Navier Stokes (u,v,p), etc...

Definition at line 584 of file dof_map.h.

585  { return cast_int<unsigned int>(_variable_groups.size()); }

References _variable_groups.

Referenced by distribute_local_dofs_node_major(), distribute_local_dofs_var_major(), dof_indices(), has_blocked_representation(), old_dof_indices(), reinit(), and set_nonlocal_dof_objects().

◆ n_variables()

unsigned int libMesh::DofMap::n_variables ( ) const
inline
Returns
The number of variables in the global solution vector. Defaults to 1, should be 1 for a scalar equation, 3 for 2D incompressible Navier Stokes (u,v,p), etc...

Definition at line 592 of file dof_map.h.

593  { return cast_int<unsigned int>(_variables.size()); }

References _variables.

Referenced by add_neighbors_to_send_list(), block_size(), libMesh::FEGenericBase< FEOutputType< T >::type >::coarsened_dof_values(), create_dof_constraints(), distribute_dofs(), DMlibMeshSetSystem_libMesh(), has_blocked_representation(), libMesh::SparsityPattern::Build::operator()(), reinit(), and use_coupled_neighbor_dofs().

◆ node_constraint_rows_begin()

NodeConstraints::const_iterator libMesh::DofMap::node_constraint_rows_begin ( ) const
inline
Returns
An iterator pointing to the first Node constraint row.

Definition at line 1031 of file dof_map.h.

1032  { return _node_constraints.begin(); }

References _node_constraints.

◆ node_constraint_rows_end()

NodeConstraints::const_iterator libMesh::DofMap::node_constraint_rows_end ( ) const
inline
Returns
An iterator pointing just past the last Node constraint row.

Definition at line 1037 of file dof_map.h.

1038  { return _node_constraints.end(); }

References _node_constraints.

◆ node_ptr()

DofObject * libMesh::DofMap::node_ptr ( MeshBase mesh,
dof_id_type  i 
) const
private
Returns
The Node pointer with index i from the mesh.

Definition at line 318 of file dof_map.C.

319 {
320  return mesh.node_ptr(i);
321 }

References mesh.

Referenced by distribute_dofs().

◆ old_dof_indices() [1/2]

void libMesh::DofMap::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.

On hanging nodes with both vertex and non-vertex DoFs, only those indices which are directly supported on elem are included.

Definition at line 2258 of file dof_map.C.

2262 {
2263  const DofObject * old_obj = elem.node_ref(n).old_dof_object;
2264  libmesh_assert(old_obj);
2265  this->_node_dof_indices(elem, n, *old_obj, di, vn);
2266 }

References _node_dof_indices(), libMesh::libmesh_assert(), libMesh::Elem::node_ref(), and libMesh::DofObject::old_dof_object.

Referenced by libMesh::FEGenericBase< FEOutputType< T >::type >::coarsened_dof_values(), libMesh::BuildProjectionList::operator()(), and libMesh::FEMContext::pre_fe_reinit().

◆ old_dof_indices() [2/2]

void libMesh::DofMap::old_dof_indices ( const Elem *const  elem,
std::vector< dof_id_type > &  di,
const unsigned int  vn = libMesh::invalid_uint 
) const

After a mesh is refined and repartitioned it is possible that the _send_list will need to be augmented.

This is the case when an element is refined and its children end up on different processors than the parent. These children will need values from the parent when projecting the solution onto the refined mesh, hence the parent's DOF indices need to be included in the _send_list. Fills the vector di with the global degree of freedom indices for the element using the DofMap::old_dof_object. If no variable number is specified then all variables are returned.

Definition at line 2574 of file dof_map.C.

2577 {
2578  LOG_SCOPE("old_dof_indices()", "DofMap");
2579 
2580  libmesh_assert(elem);
2581 
2582  const ElemType type = elem->type();
2583  const unsigned int sys_num = this->sys_number();
2584  const unsigned int n_var_groups = this->n_variable_groups();
2585  const unsigned int dim = elem->dim();
2586 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
2587  const bool is_inf = elem->infinite();
2588 #endif
2589 
2590  // If we have dof indices stored on the elem, and there's no chance
2591  // that we only have those indices because we were just p refined,
2592  // then we should have old dof indices too.
2593  libmesh_assert(!elem->has_dofs(sys_num) ||
2594  elem->p_refinement_flag() == Elem::JUST_REFINED ||
2595  elem->old_dof_object);
2596 
2597  // Clear the DOF indices vector.
2598  di.clear();
2599 
2600  // Determine the nodes contributing to element elem
2601  std::vector<const Node *> elem_nodes;
2602  const Node * const * nodes_ptr;
2603  unsigned int n_nodes;
2604  if (elem->type() == TRI3SUBDIVISION)
2605  {
2606  // Subdivision surface FE require the 1-ring around elem
2607  const Tri3Subdivision * sd_elem = static_cast<const Tri3Subdivision *>(elem);
2608  MeshTools::Subdivision::find_one_ring(sd_elem, elem_nodes);
2609  nodes_ptr = elem_nodes.data();
2610  n_nodes = cast_int<unsigned int>(elem_nodes.size());
2611  }
2612  else
2613  {
2614  // All other FE use only the nodes of elem itself
2615  nodes_ptr = elem->get_nodes();
2616  n_nodes = elem->n_nodes();
2617  }
2618 
2619  // Get the dof numbers
2620  for (unsigned int vg=0; vg<n_var_groups; vg++)
2621  {
2622  const VariableGroup & var = this->variable_group(vg);
2623  const unsigned int vars_in_group = var.n_variables();
2624 
2625  for (unsigned int vig=0; vig<vars_in_group; vig++)
2626  {
2627  const unsigned int v = var.number(vig);
2628  if ((vn == v) || (vn == libMesh::invalid_uint))
2629  {
2630  if (var.type().family == SCALAR &&
2631  (!elem ||
2632  var.active_on_subdomain(elem->subdomain_id())))
2633  {
2634  // We asked for this variable, so add it to the vector.
2635  std::vector<dof_id_type> di_new;
2636  this->SCALAR_dof_indices(di_new,v,true);
2637  di.insert( di.end(), di_new.begin(), di_new.end());
2638  }
2639  else
2640  if (var.active_on_subdomain(elem->subdomain_id()))
2641  { // Do this for all the variables if one was not specified
2642  // or just for the specified variable
2643 
2644  // Increase the polynomial order on p refined elements,
2645  // but make sure you get the right polynomial order for
2646  // the OLD degrees of freedom
2647  int p_adjustment = 0;
2648  if (elem->p_refinement_flag() == Elem::JUST_REFINED)
2649  {
2650  libmesh_assert_greater (elem->p_level(), 0);
2651  p_adjustment = -1;
2652  }
2653  else if (elem->p_refinement_flag() == Elem::JUST_COARSENED)
2654  {
2655  p_adjustment = 1;
2656  }
2657  FEType fe_type = var.type();
2658  fe_type.order = static_cast<Order>(fe_type.order +
2659  elem->p_level() +
2660  p_adjustment);
2661 
2662  const bool extra_hanging_dofs =
2664 
2665  const FEInterface::n_dofs_at_node_ptr ndan =
2667 
2668  // Get the node-based DOF numbers
2669  for (unsigned int n=0; n<n_nodes; n++)
2670  {
2671  const Node * node = nodes_ptr[n];
2672  const DofObject * old_dof_obj = node->old_dof_object;
2673  libmesh_assert(old_dof_obj);
2674 
2675  // There is a potential problem with h refinement. Imagine a
2676  // quad9 that has a linear FE on it. Then, on the hanging side,
2677  // it can falsely identify a DOF at the mid-edge node. This is why
2678  // we call FEInterface instead of node->n_comp() directly.
2679  const unsigned int nc =
2680 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
2681  is_inf ?
2682  FEInterface::n_dofs_at_node(dim, fe_type, type, n) :
2683 #endif
2684  ndan (type, fe_type.order, n);
2685 
2686  const int n_comp = old_dof_obj->n_comp_group(sys_num,vg);
2687 
2688  // If this is a non-vertex on a hanging node with extra
2689  // degrees of freedom, we use the non-vertex dofs (which
2690  // come in reverse order starting from the end, to
2691  // simplify p refinement)
2692  if (extra_hanging_dofs && !elem->is_vertex(n))
2693  {
2694  const int dof_offset = n_comp - nc;
2695 
2696  // We should never have fewer dofs than necessary on a
2697  // node unless we're getting indices on a parent element
2698  // or a just-coarsened element
2699  if (dof_offset < 0)
2700  {
2701  libmesh_assert(!elem->active() || elem->refinement_flag() ==
2703  di.resize(di.size() + nc, DofObject::invalid_id);
2704  }
2705  else
2706  for (int i=n_comp-1; i>=dof_offset; i--)
2707  {
2708  const dof_id_type d =
2709  old_dof_obj->dof_number(sys_num, vg, vig, i, n_comp);
2710  libmesh_assert_not_equal_to (d, DofObject::invalid_id);
2711  di.push_back(d);
2712  }
2713  }
2714  // If this is a vertex or an element without extra hanging
2715  // dofs, our dofs come in forward order coming from the
2716  // beginning
2717  else
2718  for (unsigned int i=0; i<nc; i++)
2719  {
2720  const dof_id_type d =
2721  old_dof_obj->dof_number(sys_num, vg, vig, i, n_comp);
2722  libmesh_assert_not_equal_to (d, DofObject::invalid_id);
2723  di.push_back(d);
2724  }
2725  }
2726 
2727  // If there are any element-based DOF numbers, get them
2728  const unsigned int nc = FEInterface::n_dofs_per_elem(dim,
2729  fe_type,
2730  type);
2731 
2732  // We should never have fewer dofs than necessary on an
2733  // element unless we're getting indices on a parent element
2734  // or a just-coarsened element
2735  if (nc != 0)
2736  {
2737  const DofObject * old_dof_obj = elem->old_dof_object;
2738  libmesh_assert(old_dof_obj);
2739 
2740  const unsigned int n_comp =
2741  old_dof_obj->n_comp_group(sys_num,vg);
2742 
2743  if (old_dof_obj->n_systems() > sys_num &&
2744  nc <= n_comp)
2745  {
2746 
2747  for (unsigned int i=0; i<nc; i++)
2748  {
2749  const dof_id_type d =
2750  old_dof_obj->dof_number(sys_num, vg, vig, i, n_comp);
2751 
2752  di.push_back(d);
2753  }
2754  }
2755  else
2756  {
2757  libmesh_assert(!elem->active() || fe_type.family == LAGRANGE ||
2758  elem->refinement_flag() == Elem::JUST_COARSENED);
2759  di.resize(di.size() + nc, DofObject::invalid_id);
2760  }
2761  }
2762  }
2763  }
2764  } // end loop over variables within group
2765  } // end loop over variable groups
2766 }

References libMesh::Elem::active(), libMesh::Variable::active_on_subdomain(), dim, libMesh::Elem::dim(), libMesh::DofObject::dof_number(), libMesh::FEInterface::extra_hanging_dofs(), libMesh::FEType::family, libMesh::MeshTools::Subdivision::find_one_ring(), libMesh::Elem::get_nodes(), libMesh::DofObject::has_dofs(), libMesh::Elem::infinite(), libMesh::DofObject::invalid_id, libMesh::invalid_uint, libMesh::Elem::is_vertex(), libMesh::Elem::JUST_COARSENED, libMesh::Elem::JUST_REFINED, libMesh::LAGRANGE, libMesh::libmesh_assert(), libMesh::DofObject::n_comp_group(), libMesh::FEInterface::n_dofs_at_node(), libMesh::FEInterface::n_dofs_at_node_function(), libMesh::FEInterface::n_dofs_per_elem(), n_nodes, libMesh::Elem::n_nodes(), libMesh::DofObject::n_systems(), n_variable_groups(), libMesh::VariableGroup::n_variables(), libMesh::VariableGroup::number(), libMesh::DofObject::old_dof_object, libMesh::FEType::order, libMesh::Elem::p_level(), libMesh::Elem::p_refinement_flag(), libMesh::Elem::refinement_flag(), libMesh::SCALAR, SCALAR_dof_indices(), libMesh::Elem::subdomain_id(), sys_number(), libMesh::TRI3SUBDIVISION, libMesh::Variable::type(), libMesh::Elem::type(), and variable_group().

◆ prepare_send_list()

void libMesh::DofMap::prepare_send_list ( )

Takes the _send_list vector (which may have duplicate entries) and sorts it.

The duplicate entries are then removed, resulting in a sorted _send_list with unique entries. Also calls any user-provided methods for adding to the send list.

Definition at line 1651 of file dof_map.C.

1652 {
1653  LOG_SCOPE("prepare_send_list()", "DofMap");
1654 
1655  // Return immediately if there's no ghost data
1656  if (this->n_processors() == 1)
1657  return;
1658 
1659  // Check to see if we have any extra stuff to add to the send_list
1661  {
1662  if (_augment_send_list)
1663  {
1664  libmesh_here();
1665  libMesh::out << "WARNING: You have specified both an extra send list function and object.\n"
1666  << " Are you sure this is what you meant to do??"
1667  << std::endl;
1668  }
1669 
1671  }
1672 
1673  if (_augment_send_list)
1675 
1676  // First sort the send list. After this
1677  // duplicated elements will be adjacent in the
1678  // vector
1679  std::sort(_send_list.begin(), _send_list.end());
1680 
1681  // Now use std::unique to remove duplicate entries
1682  std::vector<dof_id_type>::iterator new_end =
1683  std::unique (_send_list.begin(), _send_list.end());
1684 
1685  // Remove the end of the send_list. Use the "swap trick"
1686  // from Effective STL
1687  std::vector<dof_id_type> (_send_list.begin(), new_end).swap (_send_list);
1688 }

References _augment_send_list, _extra_send_list_context, _extra_send_list_function, _send_list, libMesh::DofMap::AugmentSendList::augment_send_list(), libMesh::ParallelObject::n_processors(), libMesh::out, and swap().

Referenced by libMesh::EquationSystems::allgather(), libMesh::System::reinit_constraints(), and reinit_send_list().

◆ print_dof_constraints()

void libMesh::DofMap::print_dof_constraints ( std::ostream &  os = libMesh::out,
bool  print_nonlocal = false 
) const

Prints (from processor 0) all DoF and Node constraints.

If print_nonlocal is true, then each constraint is printed once for each processor that knows about it, which may be useful for DistributedMesh debugging.

Definition at line 1438 of file dof_map_constraints.C.

1440 {
1441  parallel_object_only();
1442 
1443  std::string local_constraints =
1444  this->get_local_constraints(print_nonlocal);
1445 
1446  if (this->processor_id())
1447  {
1448  this->comm().send(0, local_constraints);
1449  }
1450  else
1451  {
1452  os << "Processor 0:\n";
1453  os << local_constraints;
1454 
1455  for (auto p : IntRange<processor_id_type>(1, this->n_processors()))
1456  {
1457  this->comm().receive(p, local_constraints);
1458  os << "Processor " << p << ":\n";
1459  os << local_constraints;
1460  }
1461  }
1462 }

References libMesh::ParallelObject::comm(), get_local_constraints(), libMesh::ParallelObject::n_processors(), and libMesh::ParallelObject::processor_id().

Referenced by main().

◆ print_info() [1/2]

void libMesh::DofMap::print_info ( std::ostream &  os = libMesh::out) const

Prints summary info about the sparsity bandwidth and constraints.

Definition at line 2836 of file dof_map.C.

2837 {
2838  os << this->get_info();
2839 }

References get_info().

◆ print_info() [2/2]

void libMesh::ReferenceCounter::print_info ( std::ostream &  out = libMesh::out)
staticinherited

Prints the reference information, by default to libMesh::out.

Definition at line 87 of file reference_counter.C.

88 {
90  out_stream << ReferenceCounter::get_info();
91 }

References libMesh::ReferenceCounter::_enable_print_counter, and libMesh::ReferenceCounter::get_info().

◆ process_constraints()

void libMesh::DofMap::process_constraints ( MeshBase mesh)

Postprocesses any constrained degrees of freedom to be constrained only in terms of unconstrained dofs, then adds unconstrained dofs to the send_list and prepares that for use.

This should be run after both system (create_dof_constraints) and user constraints have all been added.

Definition at line 3334 of file dof_map_constraints.C.

3335 {
3336  // We've computed our local constraints, but they may depend on
3337  // non-local constraints that we'll need to take into account.
3338  this->allgather_recursive_constraints(mesh);
3339 
3341  {
3342  // Optionally check for constraint loops and throw an error
3343  // if they're detected. We always do this check below in dbg/devel
3344  // mode but here we optionally do it in opt mode as well.
3346  }
3347 
3348  // Create a set containing the DOFs we already depend on
3349  typedef std::set<dof_id_type> RCSet;
3350  RCSet unexpanded_set;
3351 
3352  for (const auto & i : _dof_constraints)
3353  unexpanded_set.insert(i.first);
3354 
3355  while (!unexpanded_set.empty())
3356  for (RCSet::iterator i = unexpanded_set.begin();
3357  i != unexpanded_set.end(); /* nothing */)
3358  {
3359  // If the DOF is constrained
3360  DofConstraints::iterator
3361  pos = _dof_constraints.find(*i);
3362 
3363  libmesh_assert (pos != _dof_constraints.end());
3364 
3365  DofConstraintRow & constraint_row = pos->second;
3366 
3367  DofConstraintValueMap::iterator rhsit =
3368  _primal_constraint_values.find(*i);
3369  Number constraint_rhs = (rhsit == _primal_constraint_values.end()) ?
3370  0 : rhsit->second;
3371 
3372  std::vector<dof_id_type> constraints_to_expand;
3373 
3374  for (const auto & item : constraint_row)
3375  if (item.first != *i && this->is_constrained_dof(item.first))
3376  {
3377  unexpanded_set.insert(item.first);
3378  constraints_to_expand.push_back(item.first);
3379  }
3380 
3381  for (const auto & expandable : constraints_to_expand)
3382  {
3383  const Real this_coef = constraint_row[expandable];
3384 
3385  DofConstraints::const_iterator
3386  subpos = _dof_constraints.find(expandable);
3387 
3388  libmesh_assert (subpos != _dof_constraints.end());
3389 
3390  const DofConstraintRow & subconstraint_row = subpos->second;
3391 
3392  for (const auto & item : subconstraint_row)
3393  {
3394  // Assert that the constraint does not form a cycle.
3395  libmesh_assert(item.first != expandable);
3396  constraint_row[item.first] += item.second * this_coef;
3397  }
3398 
3399  DofConstraintValueMap::const_iterator subrhsit =
3400  _primal_constraint_values.find(expandable);
3401  if (subrhsit != _primal_constraint_values.end())
3402  constraint_rhs += subrhsit->second * this_coef;
3403 
3404  constraint_row.erase(expandable);
3405  }
3406 
3407  if (rhsit == _primal_constraint_values.end())
3408  {
3409  if (constraint_rhs != Number(0))
3410  _primal_constraint_values[*i] = constraint_rhs;
3411  else
3412  _primal_constraint_values.erase(*i);
3413  }
3414  else
3415  {
3416  if (constraint_rhs != Number(0))
3417  rhsit->second = constraint_rhs;
3418  else
3419  _primal_constraint_values.erase(rhsit);
3420  }
3421 
3422  if (constraints_to_expand.empty())
3423  i = unexpanded_set.erase(i);
3424  else
3425  ++i;
3426  }
3427 
3428  // In parallel we can't guarantee that nodes/dofs which constrain
3429  // others are on processors which are aware of that constraint, yet
3430  // we need such awareness for sparsity pattern generation. So send
3431  // other processors any constraints they might need to know about.
3432  this->scatter_constraints(mesh);
3433 
3434  // Now that we have our root constraint dependencies sorted out, add
3435  // them to the send_list
3437 }

References _dof_constraints, _error_on_constraint_loop, _primal_constraint_values, add_constraints_to_send_list(), allgather_recursive_constraints(), check_for_constraint_loops(), libMesh::libmesh_assert(), libMesh::Real, and scatter_constraints().

Referenced by libMesh::System::reinit_constraints(), and reinit_send_list().

◆ processor_id()

processor_id_type libMesh::ParallelObject::processor_id ( ) const
inlineinherited
Returns
The rank of this processor in the group.

Definition at line 106 of file parallel_object.h.

107  { return cast_int<processor_id_type>(_communicator.rank()); }

References libMesh::ParallelObject::_communicator.

Referenced by libMesh::BoundaryInfo::_find_id_maps(), libMesh::EquationSystems::_read_impl(), libMesh::PetscDMWrapper::add_dofs_to_section(), libMesh::DistributedMesh::add_elem(), libMesh::BoundaryInfo::add_elements(), add_neighbors_to_send_list(), libMesh::DistributedMesh::add_node(), libMesh::UnstructuredMesh::all_second_order(), libMesh::MeshTools::Modification::all_tri(), allgather_recursive_constraints(), libMesh::FEMSystem::assembly(), libMesh::Nemesis_IO_Helper::build_element_and_node_maps(), libMesh::InfElemBuilder::build_inf_elem(), libMesh::BoundaryInfo::build_node_list_from_side_list(), libMesh::EquationSystems::build_parallel_elemental_solution_vector(), libMesh::DistributedMesh::clear(), libMesh::ExodusII_IO_Helper::close(), libMesh::Nemesis_IO_Helper::compute_border_node_ids(), libMesh::Nemesis_IO_Helper::compute_communication_map_parameters(), libMesh::Nemesis_IO_Helper::compute_internal_and_border_elems_and_internal_nodes(), libMesh::RBConstruction::compute_max_error_bound(), libMesh::Nemesis_IO_Helper::compute_node_communication_maps(), libMesh::Nemesis_IO_Helper::compute_num_global_elem_blocks(), libMesh::Nemesis_IO_Helper::compute_num_global_nodesets(), libMesh::Nemesis_IO_Helper::compute_num_global_sidesets(), libMesh::Nemesis_IO_Helper::construct_nemesis_filename(), libMesh::ExodusII_IO::copy_scalar_solution(), libMesh::MeshTools::correct_node_proc_ids(), libMesh::ExodusII_IO_Helper::create(), libMesh::DistributedMesh::delete_elem(), libMesh::DistributedMesh::delete_node(), libMesh::MeshCommunication::delete_remote_elements(), distribute_dofs(), distribute_local_dofs_node_major(), distribute_local_dofs_var_major(), libMesh::DistributedMesh::DistributedMesh(), end_dof(), end_old_dof(), libMesh::EnsightIO::EnsightIO(), libMesh::RBEIMConstruction::evaluate_mesh_function(), libMesh::MeshFunction::find_element(), libMesh::MeshFunction::find_elements(), libMesh::UnstructuredMesh::find_neighbors(), first_dof(), first_old_dof(), libMesh::Nemesis_IO_Helper::get_cmap_params(), libMesh::Nemesis_IO_Helper::get_eb_info_global(), libMesh::Nemesis_IO_Helper::get_elem_cmap(), libMesh::Nemesis_IO_Helper::get_elem_map(), get_info(), libMesh::Nemesis_IO_Helper::get_init_global(), libMesh::Nemesis_IO_Helper::get_init_info(), libMesh::Nemesis_IO_Helper::get_loadbal_param(), get_local_constraints(), libMesh::Nemesis_IO_Helper::get_node_cmap(), libMesh::Nemesis_IO_Helper::get_node_map(), libMesh::Nemesis_IO_Helper::get_ns_param_global(), libMesh::Nemesis_IO_Helper::get_ss_param_global(), libMesh::SparsityPattern::Build::handle_vi_vj(), libMesh::SystemSubsetBySubdomain::init(), libMesh::PetscDMWrapper::init_and_attach_petscdm(), HeatSystem::init_data(), libMesh::ExodusII_IO_Helper::initialize(), libMesh::ExodusII_IO_Helper::initialize_element_variables(), libMesh::ExodusII_IO_Helper::initialize_global_variables(), libMesh::ExodusII_IO_Helper::initialize_nodal_variables(), libMesh::DistributedMesh::insert_elem(), is_evaluable(), libMesh::SparsityPattern::Build::join(), last_dof(), libMesh::TransientRBEvaluation::legacy_write_offline_data_to_files(), libMesh::RBEIMEvaluation::legacy_write_offline_data_to_files(), libMesh::RBEvaluation::legacy_write_offline_data_to_files(), libMesh::RBSCMEvaluation::legacy_write_offline_data_to_files(), libMesh::RBEIMEvaluation::legacy_write_out_interpolation_points_elem(), libMesh::MeshTools::libmesh_assert_consistent_distributed(), libMesh::MeshTools::libmesh_assert_consistent_distributed_nodes(), libMesh::MeshTools::libmesh_assert_contiguous_dof_ids(), libMesh::MeshTools::libmesh_assert_parallel_consistent_procids< Elem >(), libMesh::MeshTools::libmesh_assert_valid_neighbors(), libMesh::DistributedMesh::libmesh_assert_valid_parallel_object_ids(), local_variable_indices(), main(), libMesh::MeshRefinement::make_coarsening_compatible(), AugmentSparsityOnInterface::mesh_reinit(), libMesh::MeshBase::n_active_local_elem(), libMesh::BoundaryInfo::n_boundary_conds(), libMesh::BoundaryInfo::n_edge_conds(), n_local_dofs(), libMesh::System::n_local_dofs(), libMesh::MeshBase::n_local_elem(), libMesh::MeshBase::n_local_nodes(), libMesh::BoundaryInfo::n_nodeset_conds(), libMesh::BoundaryInfo::n_shellface_conds(), libMesh::SparsityPattern::Build::operator()(), libMesh::DistributedMesh::own_node(), libMesh::System::point_gradient(), libMesh::System::point_hessian(), libMesh::System::point_value(), print_dof_constraints(), libMesh::Nemesis_IO_Helper::put_cmap_params(), libMesh::Nemesis_IO_Helper::put_elem_cmap(), libMesh::Nemesis_IO_Helper::put_elem_map(), libMesh::Nemesis_IO_Helper::put_loadbal_param(), libMesh::Nemesis_IO_Helper::put_node_cmap(), libMesh::Nemesis_IO_Helper::put_node_map(), libMesh::NameBasedIO::read(), libMesh::Nemesis_IO::read(), libMesh::XdrIO::read(), libMesh::CheckpointIO::read(), libMesh::ExodusII_IO_Helper::read_elem_num_map(), libMesh::ExodusII_IO_Helper::read_global_values(), libMesh::CheckpointIO::read_header(), libMesh::XdrIO::read_header(), libMesh::System::read_header(), libMesh::RBEvaluation::read_in_vectors_from_multiple_files(), libMesh::System::read_legacy_data(), libMesh::ExodusII_IO_Helper::read_node_num_map(), libMesh::System::read_parallel_data(), libMesh::TransientRBConstruction::read_riesz_representors_from_files(), libMesh::RBConstruction::read_riesz_representors_from_files(), libMesh::System::read_SCALAR_dofs(), libMesh::XdrIO::read_serialized_bc_names(), libMesh::XdrIO::read_serialized_bcs_helper(), libMesh::System::read_serialized_blocked_dof_objects(), libMesh::XdrIO::read_serialized_connectivity(), libMesh::System::read_serialized_data(), libMesh::XdrIO::read_serialized_nodes(), libMesh::XdrIO::read_serialized_nodesets(), libMesh::XdrIO::read_serialized_subdomain_names(), libMesh::System::read_serialized_vector(), libMesh::System::read_serialized_vectors(), libMesh::DistributedMesh::renumber_dof_objects(), scatter_constraints(), libMesh::CheckpointIO::select_split_config(), set_nonlocal_dof_objects(), libMesh::PetscDMWrapper::set_point_range_in_section(), libMesh::LaplaceMeshSmoother::smooth(), DefaultCouplingTest::testCoupling(), PointNeighborCouplingTest::testCoupling(), MeshInputTest::testDynaReadElem(), MeshInputTest::testDynaReadPatch(), MeshInputTest::testExodusCopyElementSolution(), MeshInputTest::testExodusWriteElementDataFromDiscontinuousNodalData(), SystemsTest::testProjectMatrix1D(), SystemsTest::testProjectMatrix2D(), SystemsTest::testProjectMatrix3D(), BoundaryInfoTest::testShellFaceConstraints(), CheckpointIOTest::testSplitter(), WriteVecAndScalar::testWrite(), libMesh::MeshTools::total_weight(), libMesh::MeshRefinement::uniformly_coarsen(), libMesh::Parallel::Packing< Node * >::unpack(), libMesh::Parallel::Packing< Elem * >::unpack(), libMesh::DistributedMesh::update_parallel_id_counts(), libMesh::DTKAdapter::update_variable_values(), libMesh::NameBasedIO::write(), libMesh::XdrIO::write(), libMesh::CheckpointIO::write(), libMesh::EquationSystems::write(), libMesh::GMVIO::write_discontinuous_gmv(), libMesh::ExodusII_IO::write_element_data(), libMesh::ExodusII_IO_Helper::write_element_values(), libMesh::ExodusII_IO_Helper::write_element_values_element_major(), libMesh::ExodusII_IO_Helper::write_elements(), libMesh::ExodusII_IO::write_global_data(), libMesh::ExodusII_IO_Helper::write_global_values(), libMesh::System::write_header(), libMesh::ExodusII_IO::write_information_records(), libMesh::ExodusII_IO_Helper::write_information_records(), libMesh::ExodusII_IO_Helper::write_nodal_coordinates(), libMesh::VTKIO::write_nodal_data(), libMesh::UCDIO::write_nodal_data(), libMesh::ExodusII_IO::write_nodal_data(), libMesh::ExodusII_IO::write_nodal_data_discontinuous(), libMesh::ExodusII_IO_Helper::write_nodal_values(), libMesh::Nemesis_IO_Helper::write_nodesets(), libMesh::ExodusII_IO_Helper::write_nodesets(), libMesh::RBEvaluation::write_out_vectors(), write_output_solvedata(), libMesh::System::write_parallel_data(), libMesh::RBConstruction::write_riesz_representors_to_files(), libMesh::System::write_SCALAR_dofs(), libMesh::XdrIO::write_serialized_bc_names(), libMesh::XdrIO::write_serialized_bcs_helper(), libMesh::System::write_serialized_blocked_dof_objects(), libMesh::XdrIO::write_serialized_connectivity(), libMesh::System::write_serialized_data(), libMesh::XdrIO::write_serialized_nodes(), libMesh::XdrIO::write_serialized_nodesets(), libMesh::XdrIO::write_serialized_subdomain_names(), libMesh::System::write_serialized_vector(), libMesh::System::write_serialized_vectors(), libMesh::ExodusII_IO_Helper::write_sideset_data(), libMesh::Nemesis_IO_Helper::write_sidesets(), libMesh::ExodusII_IO_Helper::write_sidesets(), libMesh::ExodusII_IO::write_timestep(), libMesh::ExodusII_IO_Helper::write_timestep(), and libMesh::ExodusII_IO::write_timestep_discontinuous().

◆ reinit()

void libMesh::DofMap::reinit ( MeshBase mesh)

Reinitialize the underlying data structures conformal to the current mesh.

Definition at line 484 of file dof_map.C.

485 {
486  libmesh_assert (mesh.is_prepared());
487 
488  LOG_SCOPE("reinit()", "DofMap");
489 
490  // We ought to reconfigure our default coupling functor.
491  //
492  // The user might have removed it from our coupling functors set,
493  // but if so, who cares, this reconfiguration is cheap.
494 
495  // Avoid calling set_dof_coupling() with an empty/non-nullptr
496  // _dof_coupling matrix which may happen when there are actually no
497  // variables on the system.
498  if (this->_dof_coupling && this->_dof_coupling->empty() && !this->n_variables())
499  this->_dof_coupling = nullptr;
500  _default_coupling->set_dof_coupling(this->_dof_coupling);
501 
502  // By default we may want 0 or 1 levels of coupling
503  unsigned int standard_n_levels =
505  _default_coupling->set_n_levels
506  (std::max(_default_coupling->n_levels(), standard_n_levels));
507 
508  // But we *don't* want to restrict to a CouplingMatrix unless the
509  // user does so manually; the original libMesh behavior was to put
510  // ghost indices on the send_list regardless of variable.
511  //_default_evaluating->set_dof_coupling(this->_dof_coupling);
512 
513  const unsigned int
514  sys_num = this->sys_number(),
515  n_var_groups = this->n_variable_groups();
516 
517  // The DofObjects need to know how many variable groups we have, and
518  // how many variables there are in each group.
519  std::vector<unsigned int> n_vars_per_group; n_vars_per_group.reserve (n_var_groups);
520 
521  for (unsigned int vg=0; vg<n_var_groups; vg++)
522  n_vars_per_group.push_back (this->variable_group(vg).n_variables());
523 
524 #ifdef LIBMESH_ENABLE_AMR
525 
526  //------------------------------------------------------------
527  // Clear the old_dof_objects for all the nodes
528  // and elements so that we can overwrite them
529  for (auto & node : mesh.node_ptr_range())
530  {
531  node->clear_old_dof_object();
532  libmesh_assert (!node->old_dof_object);
533  }
534 
535  for (auto & elem : mesh.element_ptr_range())
536  {
537  elem->clear_old_dof_object();
538  libmesh_assert (!elem->old_dof_object);
539  }
540 
541 
542  //------------------------------------------------------------
543  // Set the old_dof_objects for the elements that
544  // weren't just created, if these old dof objects
545  // had variables
546  for (auto & elem : mesh.element_ptr_range())
547  {
548  // Skip the elements that were just refined
549  if (elem->refinement_flag() == Elem::JUST_REFINED)
550  continue;
551 
552  for (Node & node : elem->node_ref_range())
553  if (node.old_dof_object == nullptr)
554  if (node.has_dofs(sys_num))
555  node.set_old_dof_object();
556 
557  libmesh_assert (!elem->old_dof_object);
558 
559  if (elem->has_dofs(sys_num))
560  elem->set_old_dof_object();
561  }
562 
563 #endif // #ifdef LIBMESH_ENABLE_AMR
564 
565 
566  //------------------------------------------------------------
567  // Then set the number of variables for each \p DofObject
568  // equal to n_variables() for this system. This will
569  // handle new \p DofObjects that may have just been created
570 
571  // All the nodes
572  for (auto & node : mesh.node_ptr_range())
573  node->set_n_vars_per_group(sys_num, n_vars_per_group);
574 
575  // All the elements
576  for (auto & elem : mesh.element_ptr_range())
577  elem->set_n_vars_per_group(sys_num, n_vars_per_group);
578 
579  // Zero _n_SCALAR_dofs, it will be updated below.
580  this->_n_SCALAR_dofs = 0;
581 
582  //------------------------------------------------------------
583  // Next allocate space for the DOF indices
584  for (unsigned int vg=0; vg<n_var_groups; vg++)
585  {
586  const VariableGroup & vg_description = this->variable_group(vg);
587 
588  const unsigned int n_var_in_group = vg_description.n_variables();
589  const FEType & base_fe_type = vg_description.type();
590 
591  // Don't need to loop over elements for a SCALAR variable
592  // Just increment _n_SCALAR_dofs
593  if (base_fe_type.family == SCALAR)
594  {
595  this->_n_SCALAR_dofs += base_fe_type.order.get_order()*n_var_in_group;
596  continue;
597  }
598 
599  // This should be constant even on p-refined elements
600  const bool extra_hanging_dofs =
601  FEInterface::extra_hanging_dofs(base_fe_type);
602 
603  // For all the active elements, count vertex degrees of freedom.
604  for (auto & elem : mesh.active_element_ptr_range())
605  {
606  libmesh_assert(elem);
607 
608  // Skip the numbering if this variable is
609  // not active on this element's subdomain
610  if (!vg_description.active_on_subdomain(elem->subdomain_id()))
611  continue;
612 
613  const ElemType type = elem->type();
614  const unsigned int dim = elem->dim();
615 
616  FEType fe_type = base_fe_type;
617 
618 #ifdef LIBMESH_ENABLE_AMR
619  // Make sure we haven't done more p refinement than we can
620  // handle
621  if (elem->p_level() + base_fe_type.order >
622  FEInterface::max_order(base_fe_type, type))
623  {
624  libmesh_assert_less_msg(base_fe_type.order.get_order(),
625  FEInterface::max_order(base_fe_type,type),
626  "ERROR: Finite element "
627  << Utility::enum_to_string(base_fe_type.family)
628  << " on geometric element "
629  << Utility::enum_to_string(type)
630  << "\nonly supports FEInterface::max_order = "
631  << FEInterface::max_order(base_fe_type,type)
632  << ", not fe_type.order = "
633  << base_fe_type.order);
634 
635 # ifdef DEBUG
636  libMesh::err << "WARNING: Finite element "
637  << Utility::enum_to_string(base_fe_type.family)
638  << " on geometric element "
639  << Utility::enum_to_string(type) << std::endl
640  << "could not be p refined past FEInterface::max_order = "
641  << FEInterface::max_order(base_fe_type,type)
642  << std::endl;
643 # endif
644  elem->set_p_level(FEInterface::max_order(base_fe_type,type)
645  - base_fe_type.order);
646  }
647 #endif
648 
649  fe_type.order = static_cast<Order>(fe_type.order +
650  elem->p_level());
651 
652  // Allocate the vertex DOFs
653  for (auto n : elem->node_index_range())
654  {
655  Node & node = elem->node_ref(n);
656 
657  if (elem->is_vertex(n))
658  {
659  const unsigned int old_node_dofs =
660  node.n_comp_group(sys_num, vg);
661 
662  const unsigned int vertex_dofs =
663  std::max(FEInterface::n_dofs_at_node(dim, fe_type,
664  type, n),
665  old_node_dofs);
666 
667  // Some discontinuous FEs have no vertex dofs
668  if (vertex_dofs > old_node_dofs)
669  {
670  node.set_n_comp_group(sys_num, vg,
671  vertex_dofs);
672 
673  // Abusing dof_number to set a "this is a
674  // vertex" flag
675  node.set_vg_dof_base(sys_num, vg,
676  vertex_dofs);
677 
678  // libMesh::out << "sys_num,vg,old_node_dofs,vertex_dofs="
679  // << sys_num << ","
680  // << vg << ","
681  // << old_node_dofs << ","
682  // << vertex_dofs << '\n',
683  // node.debug_buffer();
684 
685  // libmesh_assert_equal_to (vertex_dofs, node.n_comp(sys_num, vg));
686  // libmesh_assert_equal_to (vertex_dofs, node.vg_dof_base(sys_num, vg));
687  }
688  }
689  }
690  } // done counting vertex dofs
691 
692  // count edge & face dofs next
693  for (auto & elem : mesh.active_element_ptr_range())
694  {
695  libmesh_assert(elem);
696 
697  // Skip the numbering if this variable is
698  // not active on this element's subdomain
699  if (!vg_description.active_on_subdomain(elem->subdomain_id()))
700  continue;
701 
702  const ElemType type = elem->type();
703  const unsigned int dim = elem->dim();
704 
705  FEType fe_type = base_fe_type;
706  fe_type.order = static_cast<Order>(fe_type.order +
707  elem->p_level());
708 
709  // Allocate the edge and face DOFs
710  for (auto n : elem->node_index_range())
711  {
712  Node & node = elem->node_ref(n);
713 
714  const unsigned int old_node_dofs =
715  node.n_comp_group(sys_num, vg);
716 
717  const unsigned int vertex_dofs = old_node_dofs?
718  cast_int<unsigned int>(node.vg_dof_base (sys_num,vg)):0;
719 
720  const unsigned int new_node_dofs =
721  FEInterface::n_dofs_at_node(dim, fe_type, type, n);
722 
723  // We've already allocated vertex DOFs
724  if (elem->is_vertex(n))
725  {
726  libmesh_assert_greater_equal (old_node_dofs, vertex_dofs);
727  // //if (vertex_dofs < new_node_dofs)
728  // libMesh::out << "sys_num,vg,old_node_dofs,vertex_dofs,new_node_dofs="
729  // << sys_num << ","
730  // << vg << ","
731  // << old_node_dofs << ","
732  // << vertex_dofs << ","
733  // << new_node_dofs << '\n',
734  // node.debug_buffer();
735 
736  libmesh_assert_greater_equal (vertex_dofs, new_node_dofs);
737  }
738  // We need to allocate the rest
739  else
740  {
741  // If this has no dofs yet, it needs no vertex
742  // dofs, so we just give it edge or face dofs
743  if (!old_node_dofs)
744  {
745  node.set_n_comp_group(sys_num, vg,
746  new_node_dofs);
747  // Abusing dof_number to set a "this has no
748  // vertex dofs" flag
749  if (new_node_dofs)
750  node.set_vg_dof_base(sys_num, vg, 0);
751  }
752 
753  // If this has dofs, but has no vertex dofs,
754  // it may still need more edge or face dofs if
755  // we're p-refined.
756  else if (vertex_dofs == 0)
757  {
758  if (new_node_dofs > old_node_dofs)
759  {
760  node.set_n_comp_group(sys_num, vg,
761  new_node_dofs);
762 
763  node.set_vg_dof_base(sys_num, vg,
764  vertex_dofs);
765  }
766  }
767  // If this is another element's vertex,
768  // add more (non-overlapping) edge/face dofs if
769  // necessary
770  else if (extra_hanging_dofs)
771  {
772  if (new_node_dofs > old_node_dofs - vertex_dofs)
773  {
774  node.set_n_comp_group(sys_num, vg,
775  vertex_dofs + new_node_dofs);
776 
777  node.set_vg_dof_base(sys_num, vg,
778  vertex_dofs);
779  }
780  }
781  // If this is another element's vertex, add any
782  // (overlapping) edge/face dofs if necessary
783  else
784  {
785  libmesh_assert_greater_equal (old_node_dofs, vertex_dofs);
786  if (new_node_dofs > old_node_dofs)
787  {
788  node.set_n_comp_group(sys_num, vg,
789  new_node_dofs);
790 
791  node.set_vg_dof_base (sys_num, vg,
792  vertex_dofs);
793  }
794  }
795  }
796  }
797  // Allocate the element DOFs
798  const unsigned int dofs_per_elem =
800  type);
801 
802  elem->set_n_comp_group(sys_num, vg, dofs_per_elem);
803 
804  }
805  } // end loop over variable groups
806 
807  // Calling DofMap::reinit() by itself makes little sense,
808  // so we won't bother with nonlocal DofObjects.
809  // Those will be fixed by distribute_dofs
810 
811  //------------------------------------------------------------
812  // Finally, clear all the current DOF indices
813  // (distribute_dofs expects them cleared!)
814  this->invalidate_dofs(mesh);
815 }

References _default_coupling, _dof_coupling, _n_SCALAR_dofs, libMesh::Variable::active_on_subdomain(), dim, libMesh::CouplingMatrix::empty(), libMesh::Utility::enum_to_string(), libMesh::err, libMesh::FEInterface::extra_hanging_dofs(), libMesh::FEType::family, libMesh::OrderWrapper::get_order(), invalidate_dofs(), libMesh::Elem::JUST_REFINED, libMesh::libmesh_assert(), libMesh::FEInterface::max_order(), mesh, libMesh::DofObject::n_comp_group(), libMesh::FEInterface::n_dofs_at_node(), libMesh::FEInterface::n_dofs_per_elem(), n_variable_groups(), libMesh::VariableGroup::n_variables(), n_variables(), libMesh::FEType::order, libMesh::SCALAR, libMesh::DofObject::set_n_comp_group(), libMesh::DofObject::set_vg_dof_base(), sys_number(), libMesh::Variable::type(), use_coupled_neighbor_dofs(), variable_group(), and libMesh::DofObject::vg_dof_base().

Referenced by distribute_dofs().

◆ reinit_send_list()

void libMesh::DofMap::reinit_send_list ( MeshBase mesh)

Clears the _send_list vector and then rebuilds it.

This may be needed in special situations, for example when an algebraic coupling functor cannot be added to the DofMap until after it is completely setup. Then this method can be used to rebuild the send_list once the algebraic coupling functor is added. Note that while this will recommunicate constraints with the updated send_list, this does assume no new constraints have been added since the previous reinit_constraints call.

Definition at line 1690 of file dof_map.C.

1691 {
1692  this->clear_send_list();
1694 
1695 #ifdef LIBMESH_ENABLE_CONSTRAINTS
1696  // This is assuming that we only need to recommunicate
1697  // the constraints and no new ones have been added since
1698  // a previous call to reinit_constraints.
1699  this->process_constraints(mesh);
1700 #endif
1701  this->prepare_send_list();
1702 }

References add_neighbors_to_send_list(), clear_send_list(), prepare_send_list(), and process_constraints().

Referenced by OverlappingAlgebraicGhostingTest::run_ghosting_test(), and OverlappingCouplingGhostingTest::run_sparsity_pattern_test().

◆ remove_adjoint_dirichlet_boundary()

void libMesh::DofMap::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 of interest index q.

Definition at line 4453 of file dof_map_constraints.C.

4455 {
4456  libmesh_assert_greater(_adjoint_dirichlet_boundaries.size(),
4457  qoi_index);
4458 
4459  auto lam = [&boundary_to_remove](const DirichletBoundary * bdy)
4460  {return bdy->b == boundary_to_remove.b && bdy->variables == boundary_to_remove.variables;};
4461 
4462  auto it = std::find_if(_adjoint_dirichlet_boundaries[qoi_index]->begin(),
4463  _adjoint_dirichlet_boundaries[qoi_index]->end(),
4464  lam);
4465 
4466  // Delete it and remove it
4467  libmesh_assert (it != _adjoint_dirichlet_boundaries[qoi_index]->end());
4468  delete *it;
4469  _adjoint_dirichlet_boundaries[qoi_index]->erase(it);
4470 }

References _adjoint_dirichlet_boundaries, libMesh::DirichletBoundary::b, end, libMesh::libmesh_assert(), and libMesh::DirichletBoundary::variables.

◆ remove_algebraic_ghosting_functor()

void libMesh::DofMap::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 at line 1873 of file dof_map.C.

1874 {
1875  _algebraic_ghosting_functors.erase(&evaluable_functor);
1876  _mesh.remove_ghosting_functor(evaluable_functor);
1877 
1878  auto it = _shared_functors.find(&evaluable_functor);
1879  if (it != _shared_functors.end())
1880  _shared_functors.erase(it);
1881 }

References _algebraic_ghosting_functors, _mesh, _shared_functors, and libMesh::MeshBase::remove_ghosting_functor().

Referenced by remove_default_ghosting(), and PointNeighborCouplingTest::testCoupling().

◆ remove_coupling_functor()

void libMesh::DofMap::remove_coupling_functor ( GhostingFunctor coupling_functor)

Removes a functor which was previously added to the set of coupling functors, from both this DofMap and from the underlying mesh.

Definition at line 1849 of file dof_map.C.

1850 {
1851  _coupling_functors.erase(&coupling_functor);
1852  _mesh.remove_ghosting_functor(coupling_functor);
1853 
1854  auto it = _shared_functors.find(&coupling_functor);
1855  if (it != _shared_functors.end())
1856  _shared_functors.erase(it);
1857 }

References _coupling_functors, _mesh, _shared_functors, and libMesh::MeshBase::remove_ghosting_functor().

Referenced by remove_default_ghosting(), and PointNeighborCouplingTest::testCoupling().

◆ remove_default_ghosting()

void libMesh::DofMap::remove_default_ghosting ( )

Remove any default ghosting functor(s).

User-added ghosting functors will be unaffected.

Unless user-added equivalent ghosting functors exist, removing the default coupling functor is only safe for explicit solves, and removing the default algebraic ghosting functor is only safe for codes where no evaluations on neighbor cells (e.g. no jump error estimators) are done.

Defaults can be restored manually via add_default_ghosting(), or automatically if clear() returns the DofMap to a default state.

Definition at line 1821 of file dof_map.C.

1822 {
1825 }

References default_algebraic_ghosting(), default_coupling(), remove_algebraic_ghosting_functor(), and remove_coupling_functor().

Referenced by libMesh::EquationSystems::enable_default_ghosting().

◆ remove_dirichlet_boundary()

void libMesh::DofMap::remove_dirichlet_boundary ( const DirichletBoundary dirichlet_boundary)

Removes the specified Dirichlet boundary from the system.

Definition at line 4438 of file dof_map_constraints.C.

4439 {
4440  // Find a boundary condition matching the one to be removed
4441  auto lam = [&boundary_to_remove](const DirichletBoundary * bdy)
4442  {return bdy->b == boundary_to_remove.b && bdy->variables == boundary_to_remove.variables;};
4443 
4444  auto it = std::find_if(_dirichlet_boundaries->begin(), _dirichlet_boundaries->end(), lam);
4445 
4446  // Delete it and remove it
4447  libmesh_assert (it != _dirichlet_boundaries->end());
4448  delete *it;
4449  _dirichlet_boundaries->erase(it);
4450 }

References _dirichlet_boundaries, libMesh::DirichletBoundary::b, libMesh::libmesh_assert(), and libMesh::DirichletBoundary::variables.

◆ SCALAR_dof_indices()

void libMesh::DofMap::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.

If old_dofs=true, the old SCALAR dof indices are returned.

Note
We do not need to pass in an element since SCALARs are global variables.

Definition at line 2488 of file dof_map.C.

2496 {
2497  LOG_SCOPE("SCALAR_dof_indices()", "DofMap");
2498 
2499  libmesh_assert(this->variable(vn).type().family == SCALAR);
2500 
2501 #ifdef LIBMESH_ENABLE_AMR
2502  // If we're asking for old dofs then we'd better have some
2503  if (old_dofs)
2504  libmesh_assert_greater_equal(n_old_dofs(), n_SCALAR_dofs());
2505 
2506  dof_id_type my_idx = old_dofs ?
2507  this->_first_old_scalar_df[vn] : this->_first_scalar_df[vn];
2508 #else
2509  dof_id_type my_idx = this->_first_scalar_df[vn];
2510 #endif
2511 
2512  libmesh_assert_not_equal_to(my_idx, DofObject::invalid_id);
2513 
2514  // The number of SCALAR dofs comes from the variable order
2515  const int n_dofs_vn = this->variable(vn).type().order.get_order();
2516 
2517  di.resize(n_dofs_vn);
2518  for (int i = 0; i != n_dofs_vn; ++i)
2519  di[i] = my_idx++;
2520 }

References _first_old_scalar_df, _first_scalar_df, libMesh::OrderWrapper::get_order(), libMesh::DofObject::invalid_id, libMesh::libmesh_assert(), n_old_dofs(), n_SCALAR_dofs(), libMesh::FEType::order, libMesh::SCALAR, libMesh::Variable::type(), and variable().

Referenced by libMesh::ExodusII_IO::copy_scalar_solution(), dof_indices(), local_variable_indices(), old_dof_indices(), libMesh::System::project_vector(), libMesh::System::projection_matrix(), libMesh::System::read_parallel_data(), libMesh::System::read_SCALAR_dofs(), libMesh::Nemesis_IO_Helper::write_nodal_solution(), libMesh::System::write_parallel_data(), and libMesh::System::write_SCALAR_dofs().

◆ scatter_constraints()

void libMesh::DofMap::scatter_constraints ( MeshBase mesh)

Sends constraint equations to constraining processors.

Definition at line 3546 of file dof_map_constraints.C.

3547 {
3548  // At this point each processor with a constrained node knows
3549  // the corresponding constraint row, but we also need each processor
3550  // with a constrainer node to know the corresponding row(s).
3551 
3552  // This function must be run on all processors at once
3553  parallel_object_only();
3554 
3555  // Return immediately if there's nothing to gather
3556  if (this->n_processors() == 1)
3557  return;
3558 
3559  // We might get to return immediately if none of the processors
3560  // found any constraints
3561  unsigned int has_constraints = !_dof_constraints.empty()
3562 #ifdef LIBMESH_ENABLE_NODE_CONSTRAINTS
3563  || !_node_constraints.empty()
3564 #endif // LIBMESH_ENABLE_NODE_CONSTRAINTS
3565  ;
3566  this->comm().max(has_constraints);
3567  if (!has_constraints)
3568  return;
3569 
3570  // We may be receiving packed_range sends out of order with
3571  // parallel_sync tags, so make sure they're received correctly.
3572  Parallel::MessageTag range_tag = this->comm().get_unique_tag();
3573 
3574 #ifdef LIBMESH_ENABLE_NODE_CONSTRAINTS
3575  std::map<processor_id_type, std::set<dof_id_type>> pushed_node_ids;
3576 #endif // LIBMESH_ENABLE_NODE_CONSTRAINTS
3577 
3578  std::map<processor_id_type, std::set<dof_id_type>> pushed_ids;
3579 
3580  // Collect the dof constraints I need to push to each processor
3581  dof_id_type constrained_proc_id = 0;
3582  for (auto & i : _dof_constraints)
3583  {
3584  const dof_id_type constrained = i.first;
3585  while (constrained >= _end_df[constrained_proc_id])
3586  constrained_proc_id++;
3587 
3588  if (constrained_proc_id != this->processor_id())
3589  continue;
3590 
3591  DofConstraintRow & row = i.second;
3592  for (auto & j : row)
3593  {
3594  const dof_id_type constraining = j.first;
3595 
3596  processor_id_type constraining_proc_id = 0;
3597  while (constraining >= _end_df[constraining_proc_id])
3598  constraining_proc_id++;
3599 
3600  if (constraining_proc_id != this->processor_id() &&
3601  constraining_proc_id != constrained_proc_id)
3602  pushed_ids[constraining_proc_id].insert(constrained);
3603  }
3604  }
3605 
3606  // Pack the dof constraint rows and rhs's to push
3607 
3608  std::map<processor_id_type,
3609  std::vector<std::vector<std::pair<dof_id_type, Real>>>>
3610  pushed_keys_vals, pushed_keys_vals_to_me;
3611 
3612  std::map<processor_id_type, std::vector<std::pair<dof_id_type, Number>>>
3613  pushed_ids_rhss, pushed_ids_rhss_to_me;
3614 
3615  auto gather_ids =
3616  [this,
3617  & pushed_ids,
3618  & pushed_keys_vals,
3619  & pushed_ids_rhss]
3620  ()
3621  {
3622  for (auto & pid_id_pair : pushed_ids)
3623  {
3624  const processor_id_type pid = pid_id_pair.first;
3625  const std::set<dof_id_type>
3626  & pid_ids = pid_id_pair.second;
3627 
3628  const std::size_t ids_size = pid_ids.size();
3629  std::vector<std::vector<std::pair<dof_id_type, Real>>> &
3630  keys_vals = pushed_keys_vals[pid];
3631  std::vector<std::pair<dof_id_type,Number>> &
3632  ids_rhss = pushed_ids_rhss[pid];
3633  keys_vals.resize(ids_size);
3634  ids_rhss.resize(ids_size);
3635 
3636  std::size_t push_i;
3637  std::set<dof_id_type>::const_iterator it;
3638  for (push_i = 0, it = pid_ids.begin();
3639  it != pid_ids.end(); ++push_i, ++it)
3640  {
3641  const dof_id_type constrained = *it;
3642  DofConstraintRow & row = _dof_constraints[constrained];
3643  keys_vals[push_i].assign(row.begin(), row.end());
3644 
3645  DofConstraintValueMap::const_iterator rhsit =
3646  _primal_constraint_values.find(constrained);
3647  ids_rhss[push_i].first = constrained;
3648  ids_rhss[push_i].second =
3649  (rhsit == _primal_constraint_values.end()) ?
3650  0 : rhsit->second;
3651  }
3652  }
3653  };
3654 
3655  gather_ids();
3656 
3657  auto ids_rhss_action_functor =
3658  [& pushed_ids_rhss_to_me]
3659  (processor_id_type pid,
3660  const std::vector<std::pair<dof_id_type, Number>> & data)
3661  {
3662  pushed_ids_rhss_to_me[pid] = data;
3663  };
3664 
3665  auto keys_vals_action_functor =
3666  [& pushed_keys_vals_to_me]
3667  (processor_id_type pid,
3668  const std::vector<std::vector<std::pair<dof_id_type, Real>>> & data)
3669  {
3670  pushed_keys_vals_to_me[pid] = data;
3671  };
3672 
3673  Parallel::push_parallel_vector_data
3674  (this->comm(), pushed_ids_rhss, ids_rhss_action_functor);
3675  Parallel::push_parallel_vector_data
3676  (this->comm(), pushed_keys_vals, keys_vals_action_functor);
3677 
3678  // Now work on traded dof constraint rows
3679  auto receive_dof_constraints =
3680  [this,
3681  & pushed_ids_rhss_to_me,
3682  & pushed_keys_vals_to_me]
3683  ()
3684  {
3685  for (auto & pid_id_pair : pushed_ids_rhss_to_me)
3686  {
3687  const processor_id_type pid = pid_id_pair.first;
3688  const auto & ids_rhss = pid_id_pair.second;
3689  const auto & keys_vals = pushed_keys_vals_to_me[pid];
3690 
3691  libmesh_assert_equal_to
3692  (ids_rhss.size(), keys_vals.size());
3693 
3694  // Add the dof constraints that I've been sent
3695  for (auto i : index_range(ids_rhss))
3696  {
3697  dof_id_type constrained = ids_rhss[i].first;
3698 
3699  // If we don't already have a constraint for this dof,
3700  // add the one we were sent
3701  if (!this->is_constrained_dof(constrained))
3702  {
3703  DofConstraintRow & row = _dof_constraints[constrained];
3704  for (auto & key_val : keys_vals[i])
3705  {
3706  libmesh_assert_less(key_val.first, this->n_dofs());
3707  row[key_val.first] = key_val.second;
3708  }
3709  if (ids_rhss[i].second != Number(0))
3710  _primal_constraint_values[constrained] =
3711  ids_rhss[i].second;
3712  else
3713  _primal_constraint_values.erase(constrained);
3714  }
3715  }
3716  }
3717  };
3718 
3719  receive_dof_constraints();
3720 
3721 #ifdef LIBMESH_ENABLE_NODE_CONSTRAINTS
3722  // Collect the node constraints to push to each processor
3723  for (auto & i : _node_constraints)
3724  {
3725  const Node * constrained = i.first;
3726 
3727  if (constrained->processor_id() != this->processor_id())
3728  continue;
3729 
3730  NodeConstraintRow & row = i.second.first;
3731  for (auto & j : row)
3732  {
3733  const Node * constraining = j.first;
3734 
3735  if (constraining->processor_id() != this->processor_id() &&
3736  constraining->processor_id() != constrained->processor_id())
3737  pushed_node_ids[constraining->processor_id()].insert(constrained->id());
3738  }
3739  }
3740 
3741  // Pack the node constraint rows and rhss to push
3742  std::map<processor_id_type,
3743  std::vector<std::vector<std::pair<dof_id_type,Real>>>>
3744  pushed_node_keys_vals, pushed_node_keys_vals_to_me;
3745  std::map<processor_id_type, std::vector<std::pair<dof_id_type, Point>>>
3746  pushed_node_ids_offsets, pushed_node_ids_offsets_to_me;
3747  std::map<processor_id_type, std::set<const Node *>> pushed_nodes;
3748 
3749  for (auto & pid_id_pair : pushed_node_ids)
3750  {
3751  const processor_id_type pid = pid_id_pair.first;
3752  const std::set<dof_id_type>
3753  & pid_ids = pid_id_pair.second;
3754 
3755  const std::size_t ids_size = pid_ids.size();
3756  std::vector<std::vector<std::pair<dof_id_type,Real>>> &
3757  keys_vals = pushed_node_keys_vals[pid];
3758  std::vector<std::pair<dof_id_type, Point>> &
3759  ids_offsets = pushed_node_ids_offsets[pid];
3760  keys_vals.resize(ids_size);
3761  ids_offsets.resize(ids_size);
3762  std::set<const Node *> & nodes = pushed_nodes[pid];
3763 
3764  std::size_t push_i;
3765  std::set<dof_id_type>::const_iterator it;
3766  for (push_i = 0, it = pid_ids.begin();
3767  it != pid_ids.end(); ++push_i, ++it)
3768  {
3769  const Node * constrained = mesh.node_ptr(*it);
3770 
3771  if (constrained->processor_id() != pid)
3772  nodes.insert(constrained);
3773 
3774  NodeConstraintRow & row = _node_constraints[constrained].first;
3775  std::size_t row_size = row.size();
3776  keys_vals[push_i].reserve(row_size);
3777  for (const auto & j : row)
3778  {
3779  const Node * constraining = j.first;
3780 
3781  keys_vals[push_i].push_back
3782  (std::make_pair(constraining->id(), j.second));
3783 
3784  if (constraining->processor_id() != pid)
3785  nodes.insert(constraining);
3786  }
3787 
3788  ids_offsets[push_i].first = *it;
3789  ids_offsets[push_i].second = _node_constraints[constrained].second;
3790  }
3791  }
3792 
3793  auto node_ids_offsets_action_functor =
3794  [& pushed_node_ids_offsets_to_me]
3795  (processor_id_type pid,
3796  const std::vector<std::pair<dof_id_type, Point>> & data)
3797  {
3798  pushed_node_ids_offsets_to_me[pid] = data;
3799  };
3800 
3801  auto node_keys_vals_action_functor =
3802  [& pushed_node_keys_vals_to_me]
3803  (processor_id_type pid,
3804  const std::vector<std::vector<std::pair<dof_id_type, Real>>> & data)
3805  {
3806  pushed_node_keys_vals_to_me[pid] = data;
3807  };
3808 
3809  // Trade pushed node constraint rows
3810  Parallel::push_parallel_vector_data
3811  (this->comm(), pushed_node_ids_offsets, node_ids_offsets_action_functor);
3812  Parallel::push_parallel_vector_data
3813  (this->comm(), pushed_node_keys_vals, node_keys_vals_action_functor);
3814 
3815  // Constraining nodes might not even exist on our subset of a
3816  // distributed mesh, so let's make them exist.
3817  std::vector<Parallel::Request> send_requests;
3818  if (!mesh.is_serial())
3819  {
3820  for (auto & pid_id_pair : pushed_node_ids_offsets)
3821  {
3822  const processor_id_type pid = pid_id_pair.first;
3823  send_requests.push_back(Parallel::Request());
3824  this->comm().send_packed_range
3825  (pid, &mesh,
3826  pushed_nodes[pid].begin(), pushed_nodes[pid].end(),
3827  send_requests.back(), range_tag);
3828  }
3829  }
3830 
3831  for (auto & pid_id_pair : pushed_node_ids_offsets_to_me)
3832  {
3833  const processor_id_type pid = pid_id_pair.first;
3834  const auto & ids_offsets = pid_id_pair.second;
3835  const auto & keys_vals = pushed_node_keys_vals_to_me[pid];
3836 
3837  libmesh_assert_equal_to
3838  (ids_offsets.size(), keys_vals.size());
3839 
3840  if (!mesh.is_serial())
3841  this->comm().receive_packed_range
3843  (Node**)nullptr, range_tag);
3844 
3845  // Add the node constraints that I've been sent
3846  for (auto i : index_range(ids_offsets))
3847  {
3848  dof_id_type constrained_id = ids_offsets[i].first;
3849 
3850  // If we don't already have a constraint for this node,
3851  // add the one we were sent
3852  const Node * constrained = mesh.node_ptr(constrained_id);
3853  if (!this->is_constrained_node(constrained))
3854  {
3855  NodeConstraintRow & row = _node_constraints[constrained].first;
3856  for (auto & key_val : keys_vals[i])
3857  {
3858  const Node * key_node = mesh.node_ptr(key_val.first);
3859  row[key_node] = key_val.second;
3860  }
3861  _node_constraints[constrained].second =
3862  ids_offsets[i].second;
3863  }
3864  }
3865  }
3866 
3867  Parallel::wait(send_requests);
3868 
3869 #endif // LIBMESH_ENABLE_NODE_CONSTRAINTS
3870 
3871  // Next we need to push constraints to processors which don't own
3872  // the constrained dof, don't own the constraining dof, but own an
3873  // element supporting the constraining dof.
3874  //
3875  // We need to be able to quickly look up constrained dof ids by what
3876  // constrains them, so that we can handle the case where we see a
3877  // foreign element containing one of our constraining DoF ids and we
3878  // need to push that constraint.
3879  //
3880  // Getting distributed adaptive sparsity patterns right is hard.
3881 
3882  typedef std::map<dof_id_type, std::set<dof_id_type>> DofConstrainsMap;
3883  DofConstrainsMap dof_id_constrains;
3884 
3885  for (auto & i : _dof_constraints)
3886  {
3887  const dof_id_type constrained = i.first;
3888  DofConstraintRow & row = i.second;
3889  for (const auto & j : row)
3890  {
3891  const dof_id_type constraining = j.first;
3892 
3893  dof_id_type constraining_proc_id = 0;
3894  while (constraining >= _end_df[constraining_proc_id])
3895  constraining_proc_id++;
3896 
3897  if (constraining_proc_id == this->processor_id())
3898  dof_id_constrains[constraining].insert(constrained);
3899  }
3900  }
3901 
3902  // Loop over all foreign elements, find any supporting our
3903  // constrained dof indices.
3904  pushed_ids.clear();
3905 
3906  for (const auto & elem : as_range(mesh.active_not_local_elements_begin(),
3908  {
3909  std::vector<dof_id_type> my_dof_indices;
3910  this->dof_indices (elem, my_dof_indices);
3911 
3912  for (const auto & dof : my_dof_indices)
3913  {
3914  DofConstrainsMap::const_iterator dcmi = dof_id_constrains.find(dof);
3915  if (dcmi != dof_id_constrains.end())
3916  {
3917  for (const auto & constrained : dcmi->second)
3918  {
3919  dof_id_type the_constrained_proc_id = 0;
3920  while (constrained >= _end_df[the_constrained_proc_id])
3921  the_constrained_proc_id++;
3922 
3923  const processor_id_type elemproc = elem->processor_id();
3924  if (elemproc != the_constrained_proc_id)
3925  pushed_ids[elemproc].insert(constrained);
3926  }
3927  }
3928  }
3929  }
3930 
3931  pushed_ids_rhss.clear();
3932  pushed_ids_rhss_to_me.clear();
3933  pushed_keys_vals.clear();
3934  pushed_keys_vals_to_me.clear();
3935 
3936  gather_ids();
3937 
3938  // Trade pushed dof constraint rows
3939  Parallel::push_parallel_vector_data
3940  (this->comm(), pushed_ids_rhss, ids_rhss_action_functor);
3941  Parallel::push_parallel_vector_data
3942  (this->comm(), pushed_keys_vals, keys_vals_action_functor);
3943 
3944  receive_dof_constraints();
3945 
3946  // Finally, we need to handle the case of remote dof coupling. If a
3947  // processor's element is coupled to a ghost element, then the
3948  // processor needs to know about all constraints which affect the
3949  // dofs on that ghost element, so we'll have to query the ghost
3950  // element's owner.
3951 
3952  GhostingFunctor::map_type elements_to_couple;
3953 
3954  // Man, I wish we had guaranteed unique_ptr availability...
3955  std::set<CouplingMatrix*> temporary_coupling_matrices;
3956 
3958  (elements_to_couple,
3959  temporary_coupling_matrices,
3960  this->coupling_functors_begin(),
3961  this->coupling_functors_end(),
3964  this->processor_id());
3965 
3966  // Each ghost-coupled element's owner should get a request for its dofs
3967  std::set<dof_id_type> requested_dofs;
3968 
3969  for (const auto & pr : elements_to_couple)
3970  {
3971  const Elem * elem = pr.first;
3972 
3973  // FIXME - optimize for the non-fully-coupled case?
3974  std::vector<dof_id_type> element_dofs;
3975  this->dof_indices(elem, element_dofs);
3976 
3977  for (auto dof : element_dofs)
3978  requested_dofs.insert(dof);
3979  }
3980 
3981  this->gather_constraints(mesh, requested_dofs, false);
3982 }

References _dof_constraints, _end_df, _node_constraints, _primal_constraint_values, libMesh::MeshBase::active_local_elements_begin(), libMesh::MeshBase::active_local_elements_end(), libMesh::MeshBase::active_not_local_elements_begin(), libMesh::MeshBase::active_not_local_elements_end(), libMesh::as_range(), libMesh::ParallelObject::comm(), coupling_functors_begin(), coupling_functors_end(), data, dof_indices(), end, gather_constraints(), libMesh::DofObject::id(), libMesh::index_range(), is_constrained_dof(), is_constrained_node(), libMesh::MeshBase::is_serial(), merge_ghost_functor_outputs(), mesh, libMesh::ParallelObject::n_processors(), libMesh::MeshBase::node_ptr(), libMesh::ParallelObject::processor_id(), and libMesh::DofObject::processor_id().

Referenced by process_constraints().

◆ semilocal_index()

bool libMesh::DofMap::semilocal_index ( dof_id_type  dof_index) const
Returns
true if degree of freedom index dof_index is either a local index or in the send_list.
Note
This is an O(logN) operation for a send_list of size N; we don't cache enough information for O(1) right now.

Definition at line 2524 of file dof_map.C.

2525 {
2526  // If it's not in the local indices
2527  if (!this->local_index(dof_index))
2528  {
2529  // and if it's not in the ghost indices, then we're not
2530  // semilocal
2531  if (!std::binary_search(_send_list.begin(), _send_list.end(), dof_index))
2532  return false;
2533  }
2534 
2535  return true;
2536 }

References _send_list, and local_index().

Referenced by all_semilocal_indices().

◆ set_error_on_constraint_loop()

void libMesh::DofMap::set_error_on_constraint_loop ( bool  error_on_constraint_loop)

Definition at line 250 of file dof_map.C.

251 {
252  _error_on_constraint_loop = error_on_constraint_loop;
253 }

References _error_on_constraint_loop.

Referenced by set_error_on_cyclic_constraint(), and DofMapTest::testConstraintLoopDetection().

◆ set_error_on_cyclic_constraint()

void libMesh::DofMap::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.

If a constraint loop is present then the system constraints are not valid, so if error_on_constraint_loop is true we will throw an error in this case.

Note
We previously referred to these types of constraints as "cyclic" but that has now been deprecated, and these will now instead be referred to as "constraint loops" in libMesh.

Definition at line 243 of file dof_map.C.

244 {
245  // This function will eventually be officially libmesh_deprecated();
246  // Call DofMap::set_error_on_constraint_loop() instead.
247  set_error_on_constraint_loop(error_on_cyclic_constraint);
248 }

References set_error_on_constraint_loop().

◆ set_implicit_neighbor_dofs()

void libMesh::DofMap::set_implicit_neighbor_dofs ( bool  implicit_neighbor_dofs)

Allow the implicit_neighbor_dofs flag to be set programmatically.

This overrides the –implicit_neighbor_dofs commandline option. We can use this to set the implicit neighbor dofs option differently for different systems, whereas the commandline option is the same for all systems.

Definition at line 1704 of file dof_map.C.

1705 {
1707  _implicit_neighbor_dofs = implicit_neighbor_dofs;
1708 }

References _implicit_neighbor_dofs, and _implicit_neighbor_dofs_initialized.

Referenced by libMesh::RBEIMConstruction::RBEIMConstruction().

◆ set_nonlocal_dof_objects()

template<typename iterator_type >
void libMesh::DofMap::set_nonlocal_dof_objects ( iterator_type  objects_begin,
iterator_type  objects_end,
MeshBase mesh,
dofobject_accessor  objects 
)
private

Helper function for distributing dofs in parallel.

Definition at line 333 of file dof_map.C.

337 {
338  // This function must be run on all processors at once
339  parallel_object_only();
340 
341  // First, iterate over local objects to find out how many
342  // are on each processor
343  std::unordered_map<processor_id_type, dof_id_type> ghost_objects_from_proc;
344 
345  iterator_type it = objects_begin;
346 
347  for (; it != objects_end; ++it)
348  {
349  DofObject * obj = *it;
350 
351  if (obj)
352  {
353  processor_id_type obj_procid = obj->processor_id();
354  // We'd better be completely partitioned by now
355  libmesh_assert_not_equal_to (obj_procid, DofObject::invalid_processor_id);
356  ghost_objects_from_proc[obj_procid]++;
357  }
358  }
359 
360  // Request sets to send to each processor
361  std::map<processor_id_type, std::vector<dof_id_type>>
362  requested_ids;
363 
364  // We know how many of our objects live on each processor, so
365  // reserve() space for requests from each.
366  for (auto pair : ghost_objects_from_proc)
367  {
368  const processor_id_type p = pair.first;
369  if (p != this->processor_id())
370  requested_ids[p].reserve(pair.second);
371  }
372 
373  for (it = objects_begin; it != objects_end; ++it)
374  {
375  DofObject * obj = *it;
376  if (obj->processor_id() != DofObject::invalid_processor_id)
377  requested_ids[obj->processor_id()].push_back(obj->id());
378  }
379 #ifdef DEBUG
380  for (auto p : IntRange<processor_id_type>(0, this->n_processors()))
381  {
382  if (ghost_objects_from_proc.count(p))
383  libmesh_assert_equal_to (requested_ids[p].size(), ghost_objects_from_proc[p]);
384  else
385  libmesh_assert(!requested_ids.count(p));
386  }
387 #endif
388 
389  typedef std::vector<dof_id_type> datum;
390 
391  auto gather_functor =
392  [this, &mesh, &objects]
394  const std::vector<dof_id_type> & ids,
395  std::vector<datum> & data)
396  {
397  // Fill those requests
398  const unsigned int
399  sys_num = this->sys_number(),
400  n_var_groups = this->n_variable_groups();
401 
402  const std::size_t query_size = ids.size();
403 
404  data.resize(query_size);
405  for (auto & d : data)
406  d.resize(2 * n_var_groups);
407 
408  for (std::size_t i=0; i != query_size; ++i)
409  {
410  DofObject * requested = (this->*objects)(mesh, ids[i]);
411  libmesh_assert(requested);
412  libmesh_assert_equal_to (requested->processor_id(), this->processor_id());
413  libmesh_assert_equal_to (requested->n_var_groups(sys_num), n_var_groups);
414  for (unsigned int vg=0; vg != n_var_groups; ++vg)
415  {
416  unsigned int n_comp_g =
417  requested->n_comp_group(sys_num, vg);
418  data[i][vg] = n_comp_g;
419  dof_id_type my_first_dof = n_comp_g ?
420  requested->vg_dof_base(sys_num, vg) : 0;
421  libmesh_assert_not_equal_to (my_first_dof, DofObject::invalid_id);
422  data[i][n_var_groups+vg] = my_first_dof;
423  }
424  }
425  };
426 
427  auto action_functor =
428  [this, &mesh, &objects]
429  (processor_id_type libmesh_dbg_var(pid),
430  const std::vector<dof_id_type> & ids,
431  const std::vector<datum> & data)
432  {
433  const unsigned int
434  sys_num = this->sys_number(),
435  n_var_groups = this->n_variable_groups();
436 
437  // Copy the id changes we've now been informed of
438  for (auto i : index_range(ids))
439  {
440  DofObject * requested = (this->*objects)(mesh, ids[i]);
441  libmesh_assert(requested);
442  libmesh_assert_equal_to (requested->processor_id(), pid);
443  for (unsigned int vg=0; vg != n_var_groups; ++vg)
444  {
445  unsigned int n_comp_g =
446  cast_int<unsigned int>(data[i][vg]);
447  requested->set_n_comp_group(sys_num, vg, n_comp_g);
448  if (n_comp_g)
449  {
450  dof_id_type my_first_dof = data[i][n_var_groups+vg];
451  libmesh_assert_not_equal_to (my_first_dof, DofObject::invalid_id);
452  requested->set_vg_dof_base
453  (sys_num, vg, my_first_dof);
454  }
455  }
456  }
457  };
458 
459  datum * ex = nullptr;
460  Parallel::pull_parallel_vector_data
461  (this->comm(), requested_ids, gather_functor, action_functor, ex);
462 
463 #ifdef DEBUG
464  // Double check for invalid dofs
465  for (it = objects_begin; it != objects_end; ++it)
466  {
467  DofObject * obj = *it;
468  libmesh_assert (obj);
469  unsigned int num_variables = obj->n_vars(this->sys_number());
470  for (unsigned int v=0; v != num_variables; ++v)
471  {
472  unsigned int n_comp =
473  obj->n_comp(this->sys_number(), v);
474  dof_id_type my_first_dof = n_comp ?
475  obj->dof_number(this->sys_number(), v, 0) : 0;
476  libmesh_assert_not_equal_to (my_first_dof, DofObject::invalid_id);
477  }
478  }
479 #endif
480 }

References libMesh::ParallelObject::comm(), data, libMesh::DofObject::dof_number(), libMesh::DofObject::id(), libMesh::index_range(), libMesh::DofObject::invalid_id, libMesh::DofObject::invalid_processor_id, libMesh::libmesh_assert(), mesh, libMesh::DofObject::n_comp(), libMesh::DofObject::n_comp_group(), libMesh::ParallelObject::n_processors(), libMesh::DofObject::n_var_groups(), n_variable_groups(), libMesh::DofObject::n_vars(), libMesh::ParallelObject::processor_id(), libMesh::DofObject::processor_id(), libMesh::DofObject::set_n_comp_group(), libMesh::DofObject::set_vg_dof_base(), sys_number(), and libMesh::DofObject::vg_dof_base().

Referenced by distribute_dofs().

◆ stash_dof_constraints()

void libMesh::DofMap::stash_dof_constraints ( )
inline

Definition at line 998 of file dof_map.h.

999  {
1002  }

References _dof_constraints, _stashed_dof_constraints, and libMesh::libmesh_assert().

◆ swap_dof_constraints()

void libMesh::DofMap::swap_dof_constraints ( )
inline

Similar to the stash/unstash_dof_constraints() API, but swaps _dof_constraints and _stashed_dof_constraints without asserting that the source or destination is empty first.

Note
There is an implicit assumption that swapping between sets of Constraints does not change the sparsity pattern or expand the send_list, since the only thing changed is the DofConstraints themselves. This is intended to work for swapping between DofConstraints A and B, where A is used to define the send_list, and B is a subset of A.

Definition at line 1022 of file dof_map.h.

1023  {
1025  }

References _dof_constraints, and _stashed_dof_constraints.

◆ sys_number()

unsigned int libMesh::DofMap::sys_number ( ) const
inline

◆ unstash_dof_constraints()

void libMesh::DofMap::unstash_dof_constraints ( )
inline

Definition at line 1004 of file dof_map.h.

1005  {
1008  }

References _dof_constraints, _stashed_dof_constraints, and libMesh::libmesh_assert().

◆ use_coupled_neighbor_dofs()

bool libMesh::DofMap::use_coupled_neighbor_dofs ( const MeshBase mesh) const

Tells other library functions whether or not this problem includes coupling between dofs in neighboring cells, as can currently be specified on the command line or inferred from the use of all discontinuous variables.

Definition at line 1711 of file dof_map.C.

1712 {
1713  // If we were asked on the command line, then we need to
1714  // include sensitivities between neighbor degrees of freedom
1715  bool implicit_neighbor_dofs =
1716  libMesh::on_command_line ("--implicit-neighbor-dofs");
1717 
1718  // If the user specifies --implicit-neighbor-dofs 0, then
1719  // presumably he knows what he is doing and we won't try to
1720  // automatically turn it on even when all the variables are
1721  // discontinuous.
1722  if (implicit_neighbor_dofs)
1723  {
1724  // No flag provided defaults to 'true'
1725  int flag = 1;
1726  flag = libMesh::command_line_next ("--implicit-neighbor-dofs", flag);
1727 
1728  if (!flag)
1729  {
1730  // The user said --implicit-neighbor-dofs 0, so he knows
1731  // what he is doing and really doesn't want it.
1732  return false;
1733  }
1734  }
1735 
1736  // Possibly override the commandline option, if set_implicit_neighbor_dofs
1737  // has been called.
1739  {
1740  implicit_neighbor_dofs = _implicit_neighbor_dofs;
1741 
1742  // Again, if the user explicitly says implicit_neighbor_dofs = false,
1743  // then we return here.
1744  if (!implicit_neighbor_dofs)
1745  return false;
1746  }
1747 
1748  // Look at all the variables in this system. If every one is
1749  // discontinuous then the user must be doing DG/FVM, so be nice
1750  // and force implicit_neighbor_dofs=true.
1751  {
1752  bool all_discontinuous_dofs = true;
1753 
1754  for (auto var : IntRange<unsigned int>(0, this->n_variables()))
1755  if (FEAbstract::build (mesh.mesh_dimension(),
1756  this->variable_type(var))->get_continuity() != DISCONTINUOUS)
1757  all_discontinuous_dofs = false;
1758 
1759  if (all_discontinuous_dofs)
1760  implicit_neighbor_dofs = true;
1761  }
1762 
1763  return implicit_neighbor_dofs;
1764 }

References _implicit_neighbor_dofs, _implicit_neighbor_dofs_initialized, libMesh::FEAbstract::build(), libMesh::command_line_next(), libMesh::DISCONTINUOUS, libMesh::MeshBase::mesh_dimension(), n_variables(), libMesh::on_command_line(), and variable_type().

Referenced by build_sparsity(), clear(), and reinit().

◆ variable()

const Variable & libMesh::DofMap::variable ( const unsigned int  c) const
inline
Returns
The variable description object for variable c.

Definition at line 1894 of file dof_map.h.

1895 {
1896  libmesh_assert_less (c, _variables.size());
1897 
1898  return _variables[c];
1899 }

References _variables.

Referenced by libMesh::FEGenericBase< FEOutputType< T >::type >::compute_proj_constraints(), distribute_dofs(), DMlibMeshSetSystem_libMesh(), local_variable_indices(), libMesh::BoundaryProjectSolution::operator()(), and SCALAR_dof_indices().

◆ variable_group()

const VariableGroup & libMesh::DofMap::variable_group ( const unsigned int  c) const
inline
Returns
The VariableGroup description object for group g.

Definition at line 1884 of file dof_map.h.

1885 {
1886  libmesh_assert_less (g, _variable_groups.size());
1887 
1888  return _variable_groups[g];
1889 }

References _variable_groups.

Referenced by _dof_indices(), _node_dof_indices(), distribute_local_dofs_node_major(), distribute_local_dofs_var_major(), dof_indices(), libMesh::System::get_info(), old_dof_indices(), and reinit().

◆ variable_group_order()

Order libMesh::DofMap::variable_group_order ( const unsigned int  vg) const
inline
Returns
The approximation order for VariableGroup vg.

Definition at line 1914 of file dof_map.h.

1915 {
1916  libmesh_assert_less (vg, _variable_groups.size());
1917 
1918  return _variable_groups[vg].type().order;
1919 }

References _variable_groups.

◆ variable_group_type()

const FEType & libMesh::DofMap::variable_group_type ( const unsigned int  vg) const
inline
Returns
The finite element type for VariableGroup vg.

Definition at line 1934 of file dof_map.h.

1935 {
1936  libmesh_assert_less (vg, _variable_groups.size());
1937 
1938  return _variable_groups[vg].type();
1939 }

References _variable_groups.

◆ variable_order()

Order libMesh::DofMap::variable_order ( const unsigned int  c) const
inline
Returns
The approximation order for variable c.

Definition at line 1904 of file dof_map.h.

1905 {
1906  libmesh_assert_less (c, _variables.size());
1907 
1908  return _variables[c].type().order;
1909 }

References _variables.

◆ variable_type()

const FEType & libMesh::DofMap::variable_type ( const unsigned int  c) const
inline
Returns
The finite element type for variable c.

Definition at line 1924 of file dof_map.h.

1925 {
1926  libmesh_assert_less (c, _variables.size());
1927 
1928  return _variables[c].type();
1929 }

References _variables.

Referenced by libMesh::ExactSolution::_compute_error(), libMesh::UniformRefinementEstimator::_estimate_error(), LinearElasticity::assemble(), AssembleOptimization::assemble_A_and_F(), assemble_elasticity(), assemble_mass(), assemble_matrices(), assemble_SchroedingerEquation(), Biharmonic::JR::bounds(), libMesh::System::calculate_norm(), libMesh::FEGenericBase< FEOutputType< T >::type >::coarsened_dof_values(), libMesh::FEInterface::compute_constraints(), compute_jacobian(), libMesh::FEGenericBase< FEOutputType< T >::type >::compute_periodic_constraints(), compute_residual(), LinearElasticityWithContact::compute_stresses(), LinearElasticity::compute_stresses(), compute_stresses(), LargeDeformationElasticity::compute_stresses(), constrain_p_dofs(), libMesh::MeshFunction::discontinuous_gradient(), libMesh::MeshFunction::discontinuous_value(), libMesh::ExactErrorEstimator::estimate_error(), libMesh::MeshFunction::gradient(), libMesh::MeshFunction::hessian(), libMesh::RBEIMAssembly::initialize_fe(), LargeDeformationElasticity::jacobian(), local_variable_indices(), LinearElasticityWithContact::move_mesh(), libMesh::WeightedPatchRecoveryErrorEstimator::EstimateError::operator()(), libMesh::PatchRecoveryErrorEstimator::EstimateError::operator()(), libMesh::MeshFunction::operator()(), libMesh::System::point_gradient(), libMesh::System::point_hessian(), libMesh::System::point_value(), LargeDeformationElasticity::residual(), Biharmonic::JR::residual_and_jacobian(), LinearElasticityWithContact::residual_and_jacobian(), libMesh::HPCoarsenTest::select_refinement(), and use_coupled_neighbor_dofs().

Friends And Related Function Documentation

◆ SparsityPattern::Build

friend class SparsityPattern::Build
friend

Definition at line 1862 of file dof_map.h.

Member Data Documentation

◆ _adjoint_constraint_values

AdjointDofConstraintValues libMesh::DofMap::_adjoint_constraint_values
private

◆ _adjoint_dirichlet_boundaries

std::vector<DirichletBoundaries *> libMesh::DofMap::_adjoint_dirichlet_boundaries
private

Data structure containing Dirichlet functions.

The ith entry is the constraint matrix row for boundaryid i.

Definition at line 1859 of file dof_map.h.

Referenced by add_adjoint_dirichlet_boundary(), create_dof_constraints(), get_adjoint_dirichlet_boundaries(), get_local_constraints(), has_adjoint_dirichlet_boundaries(), remove_adjoint_dirichlet_boundary(), and ~DofMap().

◆ _algebraic_ghosting_functors

std::set<GhostingFunctor *> libMesh::DofMap::_algebraic_ghosting_functors
private

The list of all GhostingFunctor objects to be used when distributing ghosted vectors.

The library should automatically copy these functors to the MeshBase, too, so any algebraically ghosted dofs will live on geometrically ghosted elements.

Definition at line 1731 of file dof_map.h.

Referenced by add_algebraic_ghosting_functor(), algebraic_ghosting_functors_begin(), algebraic_ghosting_functors_end(), clear(), distribute_dofs(), and remove_algebraic_ghosting_functor().

◆ _augment_send_list

AugmentSendList* libMesh::DofMap::_augment_send_list
private

Function object to call to add extra entries to the send list.

Definition at line 1695 of file dof_map.h.

Referenced by attach_extra_send_list_object(), and prepare_send_list().

◆ _augment_sparsity_pattern

AugmentSparsityPattern* libMesh::DofMap::_augment_sparsity_pattern
private

Function object to call to add extra entries to the sparsity pattern.

Definition at line 1678 of file dof_map.h.

Referenced by attach_extra_sparsity_object(), and build_sparsity().

◆ _communicator

const Parallel::Communicator& libMesh::ParallelObject::_communicator
protectedinherited

◆ _counts

ReferenceCounter::Counts libMesh::ReferenceCounter::_counts
staticprotectedinherited

◆ _coupling_functors

std::set<GhostingFunctor *> libMesh::DofMap::_coupling_functors
private

The list of all GhostingFunctor objects to be used when coupling degrees of freedom in matrix sparsity patterns.

These objects will also be used as algebraic ghosting functors, but not vice-versa.

The library should automatically copy these functors to the MeshBase, too, so any dofs coupled to local dofs will live on geometrically ghosted elements.

Definition at line 1744 of file dof_map.h.

Referenced by add_coupling_functor(), build_sparsity(), clear(), coupling_functors_begin(), coupling_functors_end(), distribute_dofs(), and remove_coupling_functor().

◆ _default_coupling

std::unique_ptr<DefaultCoupling> libMesh::DofMap::_default_coupling
private

The default coupling GhostingFunctor, used to implement standard libMesh sparsity pattern construction.

We use a std::unique_ptr here to reduce header dependencies.

Definition at line 1713 of file dof_map.h.

Referenced by clear(), default_coupling(), DofMap(), reinit(), and ~DofMap().

◆ _default_evaluating

std::unique_ptr<DefaultCoupling> libMesh::DofMap::_default_evaluating
private

The default algebraic GhostingFunctor, used to implement standard libMesh send_list construction.

We use a std::unique_ptr here to reduce header dependencies.

Definition at line 1721 of file dof_map.h.

Referenced by clear(), default_algebraic_ghosting(), DofMap(), and ~DofMap().

◆ _dirichlet_boundaries

std::unique_ptr<DirichletBoundaries> libMesh::DofMap::_dirichlet_boundaries
private

Data structure containing Dirichlet functions.

The ith entry is the constraint matrix row for boundaryid i.

Definition at line 1853 of file dof_map.h.

Referenced by add_dirichlet_boundary(), create_dof_constraints(), get_dirichlet_boundaries(), and remove_dirichlet_boundary().

◆ _dof_constraints

DofConstraints libMesh::DofMap::_dof_constraints
private

◆ _dof_coupling

CouplingMatrix* libMesh::DofMap::_dof_coupling

Degree of freedom coupling.

If left empty each DOF couples to all others. Can be used to reduce memory requirements for sparse matrices. DOF 0 might only couple to itself, in which case dof_coupling(0,0) should be 1 and dof_coupling(0,j) = 0 for j not equal to 0.

This variable is named as though it were class private, but it is in the public interface. Also there are no public methods for accessing it... This typically means you should only use it if you know what you are doing.

Definition at line 1434 of file dof_map.h.

Referenced by libMesh::RBConstruction::add_scaled_matrix_and_vector(), build_sparsity(), clear(), main(), and reinit().

◆ _enable_print_counter

bool libMesh::ReferenceCounter::_enable_print_counter = true
staticprotectedinherited

Flag to control whether reference count information is printed when print_info is called.

Definition at line 141 of file reference_counter.h.

Referenced by libMesh::ReferenceCounter::disable_print_counter_info(), libMesh::ReferenceCounter::enable_print_counter_info(), and libMesh::ReferenceCounter::print_info().

◆ _end_df

std::vector<dof_id_type> libMesh::DofMap::_end_df
private

Last DOF index (plus 1) on processor p.

Definition at line 1661 of file dof_map.h.

Referenced by clear(), distribute_dofs(), dof_owner(), end_dof(), gather_constraints(), last_dof(), n_dofs_on_processor(), and scatter_constraints().

◆ _end_old_df

std::vector<dof_id_type> libMesh::DofMap::_end_old_df
private

Last old DOF index (plus 1) on processor p.

Definition at line 1804 of file dof_map.h.

Referenced by clear(), distribute_dofs(), and end_old_dof().

◆ _error_on_constraint_loop

bool libMesh::DofMap::_error_on_constraint_loop
private

This flag indicates whether or not we do an opt-mode check for the presence of constraint loops, i.e.

cases where the constraint graph is cyclic.

Definition at line 1619 of file dof_map.h.

Referenced by process_constraints(), and set_error_on_constraint_loop().

◆ _extra_send_list_context

void* libMesh::DofMap::_extra_send_list_context
private

A pointer associated with the extra send list that can optionally be passed in.

Definition at line 1705 of file dof_map.h.

Referenced by attach_extra_send_list_function(), and prepare_send_list().

◆ _extra_send_list_function

void(* libMesh::DofMap::_extra_send_list_function) (std::vector< dof_id_type > &, void *)
private

A function pointer to a function to call to add extra entries to the send list.

Definition at line 1700 of file dof_map.h.

Referenced by attach_extra_send_list_function(), and prepare_send_list().

◆ _extra_sparsity_context

void* libMesh::DofMap::_extra_sparsity_context
private

A pointer associated with the extra sparsity that can optionally be passed in.

Definition at line 1690 of file dof_map.h.

Referenced by attach_extra_sparsity_function(), and build_sparsity().

◆ _extra_sparsity_function

void(* libMesh::DofMap::_extra_sparsity_function) (SparsityPattern::Graph &, std::vector< dof_id_type > &n_nz, std::vector< dof_id_type > &n_oz, void *)
private

A function pointer to a function to call to add extra entries to the sparsity pattern.

Definition at line 1683 of file dof_map.h.

Referenced by attach_extra_sparsity_function(), and build_sparsity().

◆ _first_df

std::vector<dof_id_type> libMesh::DofMap::_first_df
private

First DOF index on processor p.

Definition at line 1656 of file dof_map.h.

Referenced by clear(), distribute_dofs(), first_dof(), and n_dofs_on_processor().

◆ _first_old_df

std::vector<dof_id_type> libMesh::DofMap::_first_old_df
private

First old DOF index on processor p.

Definition at line 1799 of file dof_map.h.

Referenced by clear(), distribute_dofs(), and first_old_dof().

◆ _first_old_scalar_df

std::vector<dof_id_type> libMesh::DofMap::_first_old_scalar_df
private

First old DOF index for SCALAR variable v, or garbage for non-SCALAR variable v.

Definition at line 1810 of file dof_map.h.

Referenced by clear(), distribute_dofs(), and SCALAR_dof_indices().

◆ _first_scalar_df

std::vector<dof_id_type> libMesh::DofMap::_first_scalar_df
private

First DOF index for SCALAR variable v, or garbage for non-SCALAR variable v.

Definition at line 1667 of file dof_map.h.

Referenced by clear(), distribute_dofs(), and SCALAR_dof_indices().

◆ _implicit_neighbor_dofs

bool libMesh::DofMap::_implicit_neighbor_dofs
private

Definition at line 1869 of file dof_map.h.

Referenced by set_implicit_neighbor_dofs(), and use_coupled_neighbor_dofs().

◆ _implicit_neighbor_dofs_initialized

bool libMesh::DofMap::_implicit_neighbor_dofs_initialized
private

Bools to indicate if we override the –implicit_neighbor_dofs commandline options.

Definition at line 1868 of file dof_map.h.

Referenced by set_implicit_neighbor_dofs(), and use_coupled_neighbor_dofs().

◆ _matrices

std::vector<SparseMatrix<Number> * > libMesh::DofMap::_matrices
private

Additional matrices handled by this object.

These pointers do not handle the memory, instead, System, who told DofMap about them, owns them.

Definition at line 1651 of file dof_map.h.

Referenced by attach_matrix(), clear(), compute_sparsity(), DofMap(), get_info(), and is_attached().

◆ _mesh

MeshBase& libMesh::DofMap::_mesh
private

◆ _mutex

Threads::spin_mutex libMesh::ReferenceCounter::_mutex
staticprotectedinherited

Mutual exclusion object to enable thread-safe reference counting.

Definition at line 135 of file reference_counter.h.

◆ _n_dfs

dof_id_type libMesh::DofMap::_n_dfs
private

Total number of degrees of freedom.

Definition at line 1781 of file dof_map.h.

Referenced by clear(), distribute_dofs(), and n_dofs().

◆ _n_nz

std::vector<dof_id_type>* libMesh::DofMap::_n_nz
private

The number of on-processor nonzeros in my portion of the global matrix.

If need_full_sparsity_pattern is true, this will just be a pointer into the corresponding sparsity pattern vector. Otherwise we have to new/delete it ourselves.

Definition at line 1770 of file dof_map.h.

Referenced by attach_matrix(), clear_sparsity(), compute_sparsity(), get_info(), and get_n_nz().

◆ _n_objects

Threads::atomic< unsigned int > libMesh::ReferenceCounter::_n_objects
staticprotectedinherited

The number of objects.

Print the reference count information when the number returns to 0.

Definition at line 130 of file reference_counter.h.

Referenced by libMesh::ReferenceCounter::n_objects(), libMesh::ReferenceCounter::ReferenceCounter(), and libMesh::ReferenceCounter::~ReferenceCounter().

◆ _n_old_dfs

dof_id_type libMesh::DofMap::_n_old_dfs
private

Total number of degrees of freedom on old dof objects.

Definition at line 1794 of file dof_map.h.

Referenced by clear(), distribute_dofs(), and n_old_dofs().

◆ _n_oz

std::vector<dof_id_type>* libMesh::DofMap::_n_oz
private

The number of off-processor nonzeros in my portion of the global matrix; allocated similar to _n_nz.

Definition at line 1776 of file dof_map.h.

Referenced by attach_matrix(), clear_sparsity(), compute_sparsity(), get_info(), and get_n_oz().

◆ _n_SCALAR_dofs

dof_id_type libMesh::DofMap::_n_SCALAR_dofs
private

The total number of SCALAR dofs associated to all SCALAR variables.

Definition at line 1787 of file dof_map.h.

Referenced by distribute_local_dofs_node_major(), distribute_local_dofs_var_major(), n_SCALAR_dofs(), and reinit().

◆ _node_constraints

NodeConstraints libMesh::DofMap::_node_constraints
private

◆ _periodic_boundaries

std::unique_ptr<PeriodicBoundaries> libMesh::DofMap::_periodic_boundaries
private

Data structure containing periodic boundaries.

The ith entry is the constraint matrix row for boundaryid i.

Definition at line 1839 of file dof_map.h.

Referenced by add_periodic_boundary(), create_dof_constraints(), DofMap(), get_periodic_boundaries(), and is_periodic_boundary().

◆ _primal_constraint_values

DofConstraintValueMap libMesh::DofMap::_primal_constraint_values
private

◆ _send_list

std::vector<dof_id_type> libMesh::DofMap::_send_list
private

A list containing all the global DOF indices that affect the solution on my processor.

Definition at line 1673 of file dof_map.h.

Referenced by add_constraints_to_send_list(), add_neighbors_to_send_list(), clear_send_list(), get_send_list(), prepare_send_list(), and semilocal_index().

◆ _shared_functors

std::map<GhostingFunctor *, std::shared_ptr<GhostingFunctor> > libMesh::DofMap::_shared_functors
private

Hang on to references to any GhostingFunctor objects we were passed in shared_ptr form.

Definition at line 1750 of file dof_map.h.

Referenced by add_algebraic_ghosting_functor(), add_coupling_functor(), clear(), remove_algebraic_ghosting_functor(), and remove_coupling_functor().

◆ _sp

std::unique_ptr<SparsityPattern::Build> libMesh::DofMap::_sp
private

The sparsity pattern of the global matrix, kept around if it might be needed by future additions of the same type of matrix.

Definition at line 1762 of file dof_map.h.

Referenced by attach_matrix(), clear_sparsity(), and compute_sparsity().

◆ _stashed_dof_constraints

DofConstraints libMesh::DofMap::_stashed_dof_constraints
private

◆ _sys_number

const unsigned int libMesh::DofMap::_sys_number
private

The number of the system we manage DOFs for.

Definition at line 1639 of file dof_map.h.

Referenced by sys_number().

◆ _variable_group_numbers

std::vector<unsigned int> libMesh::DofMap::_variable_group_numbers
private

The variable group number for each variable.

Definition at line 1634 of file dof_map.h.

Referenced by add_variable_group(), clear(), and dof_indices().

◆ _variable_groups

std::vector<VariableGroup> libMesh::DofMap::_variable_groups
private

The finite element type for each variable group.

Definition at line 1629 of file dof_map.h.

Referenced by add_variable_group(), clear(), n_variable_groups(), variable_group(), variable_group_order(), and variable_group_type().

◆ _variables

std::vector<Variable> libMesh::DofMap::_variables
private

The finite element type for each variable.

Definition at line 1624 of file dof_map.h.

Referenced by add_variable_group(), clear(), n_variables(), variable(), variable_order(), and variable_type().

◆ need_full_sparsity_pattern

bool libMesh::DofMap::need_full_sparsity_pattern
private

Default false; set to true if any attached matrix requires a full sparsity pattern.

Definition at line 1756 of file dof_map.h.

Referenced by attach_matrix(), build_sparsity(), clear(), clear_sparsity(), and compute_sparsity().


The documentation for this class was generated from the following files:
libMesh::DofMap::_adjoint_constraint_values
AdjointDofConstraintValues _adjoint_constraint_values
Definition: dof_map.h:1823
libMesh::DofConstraints
The constraint matrix storage format.
Definition: dof_map.h:105
libMesh::DofMap::add_algebraic_ghosting_functor
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:1862
libMesh::DofMap::_primal_constraint_values
DofConstraintValueMap _primal_constraint_values
Definition: dof_map.h:1821
libMesh::Number
Real Number
Definition: libmesh_common.h:195
libMesh::dof_id_type
uint8_t dof_id_type
Definition: id_types.h:67
libMesh::DofMap::elem_ptr
DofObject * elem_ptr(MeshBase &mesh, dof_id_type i) const
Definition: dof_map.C:325
libMesh::Elem::is_node_on_side
virtual bool is_node_on_side(const unsigned int n, const unsigned int s) const =0
libMesh::OrderWrapper::get_order
int get_order() const
Explicitly request the order as an int.
Definition: fe_type.h:77
libMesh::invalid_uint
const unsigned int invalid_uint
A number which is used quite often to represent an invalid or uninitialized value.
Definition: libmesh.h:249
libMesh::DofMap::n_old_dofs
dof_id_type n_old_dofs() const
Definition: dof_map.h:1384
libMesh::FEInterface::extra_hanging_dofs
static bool extra_hanging_dofs(const FEType &fe_t)
Definition: fe_interface.C:1656
libMesh::DofMap::_mesh
MeshBase & _mesh
The mesh that system uses.
Definition: dof_map.h:1644
libMesh::DofMap::_stashed_dof_constraints
DofConstraints _stashed_dof_constraints
Definition: dof_map.h:1819
libMesh::DofMap::build_constraint_matrix
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.
Definition: dof_map_constraints.C:2451
libMesh::command_line_next
T command_line_next(std::string name, T default_value)
Use GetPot's search()/next() functions to get following arguments from the command line.
Definition: libmesh.C:963
libMesh::DofMap::prepare_send_list
void prepare_send_list()
Takes the _send_list vector (which may have duplicate entries) and sorts it.
Definition: dof_map.C:1651
libMesh::DofMap::_default_coupling
std::unique_ptr< DefaultCoupling > _default_coupling
The default coupling GhostingFunctor, used to implement standard libMesh sparsity pattern constructio...
Definition: dof_map.h:1713
libMesh::Elem::JUST_REFINED
Definition: elem.h:1172
libMesh::MeshBase::get_boundary_info
const BoundaryInfo & get_boundary_info() const
The information about boundary ids on the mesh.
Definition: mesh_base.h:132
libMesh::MeshTools::libmesh_assert_valid_boundary_ids
void libmesh_assert_valid_boundary_ids(const MeshBase &mesh)
A function for verifying that boundary condition ids match across processors.
Definition: mesh_tools.C:1396
libMesh::DofMap::dof_indices
void dof_indices(const Elem *const elem, std::vector< dof_id_type > &di) const
Fills the vector di with the global degree of freedom indices for the element.
Definition: dof_map.C:1967
n_vars
unsigned int n_vars
Definition: adaptivity_ex3.C:116
libMesh::MeshBase::is_serial
virtual bool is_serial() const
Definition: mesh_base.h:159
libMesh::MeshTools::Subdivision::find_one_ring
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.
Definition: mesh_subdivision_support.C:31
libMesh::DofMap::_periodic_boundaries
std::unique_ptr< PeriodicBoundaries > _periodic_boundaries
Data structure containing periodic boundaries.
Definition: dof_map.h:1839
libMesh::DofMap::_node_constraints
NodeConstraints _node_constraints
Data structure containing DofObject constraints.
Definition: dof_map.h:1830
libMesh::Elem::n_nodes
virtual unsigned int n_nodes() const =0
libMesh::DofMap::_first_old_df
std::vector< dof_id_type > _first_old_df
First old DOF index on processor p.
Definition: dof_map.h:1799
libMesh::DofMap::n_dofs
dof_id_type n_dofs() const
Definition: dof_map.h:625
libMesh::DofMap::_first_old_scalar_df
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:1810
libMesh::FEInterface::n_dofs_at_node_function
static n_dofs_at_node_ptr n_dofs_at_node_function(const unsigned int dim, const FEType &fe_t)
Definition: fe_interface.C:523
libMesh::MeshBase::active_local_element_ptr_range
virtual SimpleRange< element_iterator > active_local_element_ptr_range()=0
libMesh::DofMap::_extra_sparsity_function
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:1683
libMesh::MeshBase::active_local_elements_begin
virtual element_iterator active_local_elements_begin()=0
libMesh::DofMap::need_full_sparsity_pattern
bool need_full_sparsity_pattern
Default false; set to true if any attached matrix requires a full sparsity pattern.
Definition: dof_map.h:1756
libMesh::DofMap::is_constrained_node
bool is_constrained_node(const Node *node) const
Definition: dof_map.h:1946
libMesh::DofMap::get_info
std::string get_info() const
Gets summary info about the sparsity bandwidth and constraints.
Definition: dof_map.C:2843
libMesh::FEInterface::n_dofs_at_node
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:503
libMesh::DofMap::build_sparsity
std::unique_ptr< SparsityPattern::Build > build_sparsity(const MeshBase &mesh) const
Builds a sparsity pattern.
Definition: dof_map.C:63
libMesh::DofMap::_sys_number
const unsigned int _sys_number
The number of the system we manage DOFs for.
Definition: dof_map.h:1639
libMesh::MeshBase::n_elem
virtual dof_id_type n_elem() const =0
libMesh::DofMap::end_dof
dof_id_type end_dof() const
Definition: dof_map.h:695
libMesh::PeriodicBoundaryBase
The base class for defining periodic boundaries.
Definition: periodic_boundary_base.h:48
libMesh::NumericVector::last_local_index
virtual numeric_index_type last_local_index() const =0
libMesh::index_range
IntRange< std::size_t > index_range(const std::vector< T > &vec)
Helper function that returns an IntRange<std::size_t> representing all the indices of the passed-in v...
Definition: int_range.h:106
libMesh::Elem::dim
virtual unsigned short dim() const =0
libMesh::DofMap::_n_nz
std::vector< dof_id_type > * _n_nz
The number of on-processor nonzeros in my portion of the global matrix.
Definition: dof_map.h:1770
libMesh::DofMap::_end_old_df
std::vector< dof_id_type > _end_old_df
Last old DOF index (plus 1) on processor p.
Definition: dof_map.h:1804
libMesh::DofMap::remove_coupling_functor
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:1849
libMesh::DofMap::distribute_local_dofs_var_major
void distribute_local_dofs_var_major(dof_id_type &next_free_dof, MeshBase &mesh)
Distributes the global degrees of freedom, for dofs on this processor.
Definition: dof_map.C:1310
libMesh::DofMap::use_coupled_neighbor_dofs
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:1711
libMesh::DofMap::semilocal_index
bool semilocal_index(dof_id_type dof_index) const
Definition: dof_map.C:2524
end
IterBase * end
Also have a polymorphic pointer to the end object, this prevents iterating past the end.
Definition: variant_filter_iterator.h:343
libMesh::ReferenceCounter::_counts
static Counts _counts
Actually holds the data.
Definition: reference_counter.h:122
libMesh::DofMap::coupling_functors_begin
std::set< GhostingFunctor * >::const_iterator coupling_functors_begin() const
Beginning of range of coupling functors.
Definition: dof_map.h:329
libMesh::DofMap::clear_send_list
void clear_send_list()
Clears the _send_list vector.
Definition: dof_map.h:470
libMesh::ParallelObject::comm
const Parallel::Communicator & comm() const
Definition: parallel_object.h:94
libMesh::DenseMatrix< Number >
libMesh::DofMap::n_variables
unsigned int n_variables() const
Definition: dof_map.h:592
libMesh::DofMap::_n_SCALAR_dofs
dof_id_type _n_SCALAR_dofs
The total number of SCALAR dofs associated to all SCALAR variables.
Definition: dof_map.h:1787
libMesh::GhostingFunctor::map_type
std::unordered_map< const Elem *, const CouplingMatrix * > map_type
What elements do we care about and what variables do we care about on each element?
Definition: ghosting_functor.h:171
libMesh::Elem::p_level
unsigned int p_level() const
Definition: elem.h:2512
libMesh::DofMap::process_constraints
void process_constraints(MeshBase &)
Postprocesses any constrained degrees of freedom to be constrained only in terms of unconstrained dof...
Definition: dof_map_constraints.C:3334
libMesh::ReferenceCounter::_n_objects
static Threads::atomic< unsigned int > _n_objects
The number of objects.
Definition: reference_counter.h:130
libMesh::DofMap::_dof_constraints
DofConstraints _dof_constraints
Data structure containing DOF constraints.
Definition: dof_map.h:1819
libMesh::DenseMatrixBase::n
unsigned int n() const
Definition: dense_matrix_base.h:109
libMesh::Variable::type
const FEType & type() const
Definition: variable.h:119
libMesh::DofMap::_adjoint_dirichlet_boundaries
std::vector< DirichletBoundaries * > _adjoint_dirichlet_boundaries
Data structure containing Dirichlet functions.
Definition: dof_map.h:1859
mesh
MeshBase & mesh
Definition: mesh_communication.C:1257
libMesh::DofMap::default_coupling
DefaultCoupling & default_coupling()
Default coupling functor.
Definition: dof_map.h:341
libMesh::MeshBase::node_ptr
virtual const Node * node_ptr(const dof_id_type i) const =0
libMesh::MeshBase::mesh_dimension
unsigned int mesh_dimension() const
Definition: mesh_base.C:135
libMesh::DofMap::_variable_group_numbers
std::vector< unsigned int > _variable_group_numbers
The variable group number for each variable.
Definition: dof_map.h:1634
libMesh::DofMap::_first_scalar_df
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:1667
libMesh::DofMap::n_variable_groups
unsigned int n_variable_groups() const
Definition: dof_map.h:584
libMesh::DofMap::invalidate_dofs
void invalidate_dofs(MeshBase &mesh) const
Invalidates all active DofObject dofs for this system.
Definition: dof_map.C:819
libMesh::FEInterface::n_dofs_at_node_ptr
unsigned int(* n_dofs_at_node_ptr)(const ElemType, const Order, const unsigned int)
Definition: fe_interface.h:126
libMesh::DofMap::is_constrained_dof
bool is_constrained_dof(const dof_id_type dof) const
Definition: dof_map.h:1962
libMesh::ReferenceCounter::get_info
static std::string get_info()
Gets a string containing the reference information.
Definition: reference_counter.C:47
libMesh::DofObject::processor_id
processor_id_type processor_id() const
Definition: dof_object.h:829
libMesh::MeshBase::local_elements_begin
virtual element_iterator local_elements_begin()=0
libMesh::DenseMatrix::right_multiply
virtual void right_multiply(const DenseMatrixBase< T > &M2) override
Performs the operation: (*this) <- (*this) * M3.
Definition: dense_matrix_impl.h:231
libMesh::NumericVector::closed
virtual bool closed() const
Definition: numeric_vector.h:171
dim
unsigned int dim
Definition: adaptivity_ex3.C:113
libMesh::DofMap::get_local_constraints
std::string get_local_constraints(bool print_nonlocal=false) const
Gets a string reporting all DoF and Node constraints local to this processor.
Definition: dof_map_constraints.C:1464
libMesh::DirichletBoundaries
We're using a class instead of a typedef to allow forward declarations and future flexibility.
Definition: dirichlet_boundaries.h:207
libMesh::DofMap::check_dirichlet_bcid_consistency
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.
Definition: dof_map_constraints.C:4479
libMesh::DofMap::_send_list
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:1673
libMesh::DenseMatrix::resize
void resize(const unsigned int new_m, const unsigned int new_n)
Resize the matrix.
Definition: dense_matrix.h:822
libMesh::DirichletBoundary::b
std::set< boundary_id_type > b
Definition: dirichlet_boundaries.h:173
libMesh::DofMap::_first_df
std::vector< dof_id_type > _first_df
First DOF index on processor p.
Definition: dof_map.h:1656
libMesh::SparseMatrix::need_full_sparsity_pattern
virtual bool need_full_sparsity_pattern() const
Definition: sparse_matrix.h:120
libMesh::NumericVector::size
virtual numeric_index_type size() const =0
libMesh::NumericVector< Number >
libMesh::TypeVector::size
auto size() const -> decltype(std::norm(T()))
Definition: type_vector.h:944
libMesh::DofMap::set_error_on_constraint_loop
void set_error_on_constraint_loop(bool error_on_constraint_loop)
Definition: dof_map.C:250
libMesh::CouplingMatrix::empty
bool empty() const
Definition: coupling_matrix.h:631
libMesh::DofMap::_n_oz
std::vector< dof_id_type > * _n_oz
The number of off-processor nonzeros in my portion of the global matrix; allocated similar to _n_nz.
Definition: dof_map.h:1776
libMesh::DenseMatrixBase::m
unsigned int m() const
Definition: dense_matrix_base.h:104
libMesh::BoundaryInfo::get_boundary_ids
const std::set< boundary_id_type > & get_boundary_ids() const
Definition: boundary_info.h:787
libMesh::DofObject::dof_number
dof_id_type dof_number(const unsigned int s, const unsigned int var, const unsigned int comp) const
Definition: dof_object.h:956
libMesh::libmesh_assert
libmesh_assert(ctx)
libMesh::DofMap::reinit
void reinit(MeshBase &mesh)
Reinitialize the underlying data structures conformal to the current mesh.
Definition: dof_map.C:484
libMesh::IntRange
The IntRange templated class is intended to make it easy to loop over integers which are indices of a...
Definition: int_range.h:53
libMesh::MeshBase
This is the MeshBase class.
Definition: mesh_base.h:78
libMesh::DofMap::check_for_constraint_loops
void check_for_constraint_loops()
Definition: dof_map_constraints.C:3447
libMesh::ParallelObject::ParallelObject
ParallelObject(const Parallel::Communicator &comm_in)
Constructor.
Definition: parallel_object.h:63
libMesh::DofMap::AugmentSparsityPattern::augment_sparsity_pattern
virtual void augment_sparsity_pattern(SparsityPattern::Graph &sparsity, std::vector< dof_id_type > &n_nz, std::vector< dof_id_type > &n_oz)=0
User-defined function to augment the sparsity pattern.
std::abs
MetaPhysicL::DualNumber< T, D > abs(const MetaPhysicL::DualNumber< T, D > &in)
libMesh::MeshBase::remove_ghosting_functor
void remove_ghosting_functor(GhostingFunctor &ghosting_functor)
Removes a functor which was previously added to the set of ghosting functors.
Definition: mesh_base.C:450
libMesh::Threads::parallel_for
void parallel_for(const Range &range, const Body &body)
Execute the provided function object in parallel on the specified range.
Definition: threads_none.h:73
libMesh::DofConstraintValueMap
Storage for DofConstraint right hand sides for a particular problem.
Definition: dof_map.h:117
libMesh::FEInterface::n_dofs_per_elem
static unsigned int n_dofs_per_elem(const unsigned int dim, const FEType &fe_t, const ElemType t)
Definition: fe_interface.C:534
libMesh::DofMap::sys_number
unsigned int sys_number() const
Definition: dof_map.h:1876
libMesh::ParallelObject::n_processors
processor_id_type n_processors() const
Definition: parallel_object.h:100
libMesh::DofObject::n_comp
unsigned int n_comp(const unsigned int s, const unsigned int var) const
Definition: dof_object.h:926
libMesh::DofMap::_augment_sparsity_pattern
AugmentSparsityPattern * _augment_sparsity_pattern
Function object to call to add extra entries to the sparsity pattern.
Definition: dof_map.h:1678
libMesh::libmesh_isnan
bool libmesh_isnan(T x)
Definition: libmesh_common.h:177
libMesh::DofMap::_extra_sparsity_context
void * _extra_sparsity_context
A pointer associated with the extra sparsity that can optionally be passed in.
Definition: dof_map.h:1690
libMesh::DofMap::variable
const Variable & variable(const unsigned int c) const
Definition: dof_map.h:1894
libMesh::Threads::spin_mtx
spin_mutex spin_mtx
A convenient spin mutex object which can be used for obtaining locks.
Definition: threads.C:29
libMesh::DofMap::clear
void clear()
Free all new memory associated with the object, but restore its original state, with the mesh pointer...
Definition: dof_map.C:834
libMesh::FEAbstract::build
static std::unique_ptr< FEAbstract > build(const unsigned int dim, const FEType &type)
Builds a specific finite element type.
Definition: fe_abstract.C:72
libMesh::System::get_mesh
const MeshBase & get_mesh() const
Definition: system.h:2083
libMesh::ParallelObject::processor_id
processor_id_type processor_id() const
Definition: parallel_object.h:106
libMesh::DofObject::invalid_id
static const dof_id_type invalid_id
An invalid id to distinguish an uninitialized DofObject.
Definition: dof_object.h:421
libMesh::PeriodicBoundaryBase::clone
virtual std::unique_ptr< PeriodicBoundaryBase > clone(TransformationType t=FORWARD) const =0
If we want the DofMap to be able to make copies of references and store them in the underlying map,...
libMesh::DofMap::_n_dfs
dof_id_type _n_dfs
Total number of degrees of freedom.
Definition: dof_map.h:1781
libMesh::ParallelObject::_communicator
const Parallel::Communicator & _communicator
Definition: parallel_object.h:112
libMesh::Point
A Point defines a location in LIBMESH_DIM dimensional Real space.
Definition: point.h:38
libMesh::DofMap::SCALAR_dof_indices
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:2488
libMesh::ConstElemRange
StoredRange< MeshBase::const_element_iterator, const Elem * > ConstElemRange
Definition: elem_range.h:34
libMesh::processor_id_type
uint8_t processor_id_type
Definition: id_types.h:104
libMesh::DISCONTINUOUS
Definition: enum_fe_family.h:78
libMesh::MeshBase::active_local_elements_end
virtual element_iterator active_local_elements_end()=0
libMesh::DofMap::scatter_constraints
void scatter_constraints(MeshBase &)
Sends constraint equations to constraining processors.
Definition: dof_map_constraints.C:3546
libMesh::PeriodicBoundaryBase::myboundary
boundary_id_type myboundary
The boundary ID of this boundary and its counterpart.
Definition: periodic_boundary_base.h:58
libMesh::DofMap::_n_old_dfs
dof_id_type _n_old_dfs
Total number of degrees of freedom on old dof objects.
Definition: dof_map.h:1794
libMesh::DofMap::set_nonlocal_dof_objects
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:333
libMesh::DofMap::find_connected_dofs
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:2773
libMesh::Node
A Node is like a Point, but with more information.
Definition: node.h:52
libMesh::DofMap::_coupling_functors
std::set< GhostingFunctor * > _coupling_functors
The list of all GhostingFunctor objects to be used when coupling degrees of freedom in matrix sparsit...
Definition: dof_map.h:1744
libMesh::MeshTools::Generation::Private::idx
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.
Definition: mesh_generation.C:72
libMesh::DofMap::build_constraint_matrix_and_vector
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 ...
Definition: dof_map_constraints.C:2561
libMesh::Threads::parallel_reduce
void parallel_reduce(const Range &range, Body &body)
Execute the provided reduction operation in parallel on the specified range.
Definition: threads_none.h:101
libMesh::FEInterface::n_dofs
static unsigned int n_dofs(const unsigned int dim, const FEType &fe_t, const ElemType t)
Definition: fe_interface.C:472
libMesh::DofMap::variable_type
const FEType & variable_type(const unsigned int c) const
Definition: dof_map.h:1924
libMesh::as_range
SimpleRange< IndexType > as_range(const std::pair< IndexType, IndexType > &p)
Helper function that allows us to treat a homogenous pair as a range.
Definition: simple_range.h:57
libMesh::MeshBase::is_prepared
bool is_prepared() const
Definition: mesh_base.h:152
libMesh::DenseMatrix::vector_mult_add
void vector_mult_add(DenseVector< T > &dest, const T factor, const DenseVector< T > &arg) const
Performs the scaled matrix-vector multiplication, dest += factor * (*this) * arg.
Definition: dense_matrix_impl.h:529
n_nodes
const dof_id_type n_nodes
Definition: tecplot_io.C:68
libMesh::Elem::JUST_COARSENED
Definition: elem.h:1173
libMesh::DofMap::end_old_dof
dof_id_type end_old_dof() const
Definition: dof_map.h:718
libMesh::DofMap::algebraic_ghosting_functors_end
std::set< GhostingFunctor * >::const_iterator algebraic_ghosting_functors_end() const
End of range of algebraic ghosting functors.
Definition: dof_map.h:397
libMesh::DofMap::add_constraints_to_send_list
void add_constraints_to_send_list()
Adds entries to the _send_list vector corresponding to DoFs which are dependencies for constraint equ...
Definition: dof_map_constraints.C:4280
libMesh::Utility::enum_to_string
std::string enum_to_string(const T e)
libMesh::DofMap::algebraic_ghosting_functors_begin
std::set< GhostingFunctor * >::const_iterator algebraic_ghosting_functors_begin() const
Beginning of range of algebraic ghosting functors.
Definition: dof_map.h:391
libMesh::DofObject::n_vars
unsigned int n_vars(const unsigned int s, const unsigned int vg) const
Definition: dof_object.h:891
libMesh::DofMap::has_blocked_representation
bool has_blocked_representation() const
Definition: dof_map.h:600
libMesh::DofMap::_augment_send_list
AugmentSendList * _augment_send_list
Function object to call to add extra entries to the send list.
Definition: dof_map.h:1695
libMesh::DofMap::_variable_groups
std::vector< VariableGroup > _variable_groups
The finite element type for each variable group.
Definition: dof_map.h:1629
libMesh::DofMap::allgather_recursive_constraints
void allgather_recursive_constraints(MeshBase &)
Gathers constraint equation dependencies from other processors.
Definition: dof_map_constraints.C:2700
libMesh::MeshTools::libmesh_assert_valid_dof_ids
void libmesh_assert_valid_dof_ids(const MeshBase &mesh, unsigned int sysnum=libMesh::invalid_uint)
A function for verifying that degree of freedom indexing matches across processors.
Definition: mesh_tools.C:1566
libMesh::DofMap::remove_algebraic_ghosting_functor
void remove_algebraic_ghosting_functor(GhostingFunctor &evaluable_functor)
Removes a functor which was previously added to the set of algebraic ghosting functors,...
Definition: dof_map.C:1873
libMesh::mesh_inserter_iterator
A class for templated methods that expect output iterator arguments, which adds objects to the Mesh.
Definition: mesh_inserter_iterator.h:49
libMesh::DofMap::n_dofs_on_processor
dof_id_type n_dofs_on_processor(const processor_id_type proc) const
Definition: dof_map.h:641
libMesh::DofMap::_matrices
std::vector< SparseMatrix< Number > * > _matrices
Additional matrices handled by this object.
Definition: dof_map.h:1651
libMesh::MeshBase::add_ghosting_functor
void add_ghosting_functor(GhostingFunctor &ghosting_functor)
Adds a functor which can specify ghosting requirements for use on distributed meshes.
Definition: mesh_base.h:1089
libMesh::PeriodicBoundaryBase::INVERSE
Definition: periodic_boundary_base.h:53
libMesh::DofMap::_dirichlet_boundaries
std::unique_ptr< DirichletBoundaries > _dirichlet_boundaries
Data structure containing Dirichlet functions.
Definition: dof_map.h:1853
libMesh::DenseVector::resize
void resize(const unsigned int n)
Resize the vector.
Definition: dense_vector.h:355
distance
Real distance(const Point &p)
Definition: subdomains_ex3.C:50
libMesh::DofMap::local_index
bool local_index(dof_id_type dof_index) const
Definition: dof_map.h:815
libMesh::MeshBase::sub_point_locator
std::unique_ptr< PointLocatorBase > sub_point_locator() const
Definition: mesh_base.C:672
libMesh::System::solution
std::unique_ptr< NumericVector< Number > > solution
Data structure to hold solution values.
Definition: system.h:1539
swap
void swap(Iterator &lhs, Iterator &rhs)
swap, used to implement op=
Definition: variant_filter_iterator.h:478
libMesh::SparseMatrix::update_sparsity_pattern
virtual void update_sparsity_pattern(const SparsityPattern::Graph &)
Updates the matrix sparsity pattern.
Definition: sparse_matrix.h:128
libMesh::DofMap::coupling_functors_end
std::set< GhostingFunctor * >::const_iterator coupling_functors_end() const
End of range of coupling functors.
Definition: dof_map.h:335
libMesh::FEType
class FEType hides (possibly multiple) FEFamily and approximation orders, thereby enabling specialize...
Definition: fe_type.h:178
libMesh::FEType::order
OrderWrapper order
The approximation order of the element.
Definition: fe_type.h:197
libMesh::DofMap::_algebraic_ghosting_functors
std::set< GhostingFunctor * > _algebraic_ghosting_functors
The list of all GhostingFunctor objects to be used when distributing ghosted vectors.
Definition: dof_map.h:1731
libMesh::MeshBase::local_elements_end
virtual element_iterator local_elements_end()=0
libMesh::DofMap::all_semilocal_indices
bool all_semilocal_indices(const std::vector< dof_id_type > &dof_indices) const
Definition: dof_map.C:2540
libMesh::DofMap::clear_sparsity
void clear_sparsity()
Clears the sparsity pattern.
Definition: dof_map.C:1800
libMesh::DofObject::id
dof_id_type id() const
Definition: dof_object.h:767
libMesh::DofMap::_end_df
std::vector< dof_id_type > _end_df
Last DOF index (plus 1) on processor p.
Definition: dof_map.h:1661
libMesh::StoredRange
The StoredRange class defines a contiguous, divisible set of objects.
Definition: stored_range.h:52
libMesh::DirichletBoundary
This class allows one to associate Dirichlet boundary values with a given set of mesh boundary ids an...
Definition: dirichlet_boundaries.h:88
libMesh::PeriodicBoundaryBase::merge
void merge(const PeriodicBoundaryBase &pb)
Definition: periodic_boundary_base.C:61
libMesh::Elem::is_vertex
virtual bool is_vertex(const unsigned int i) const =0
libMesh::SparseMatrix::attach_dof_map
void attach_dof_map(const DofMap &dof_map)
Get a pointer to the DofMap to use.
Definition: sparse_matrix.h:108
libMesh::DofMap::last_dof
dof_id_type last_dof() const
Definition: dof_map.h:682
libMesh::DofObject::invalid_processor_id
static const processor_id_type invalid_processor_id
An invalid processor_id to distinguish DoFs that have not been assigned to a processor.
Definition: dof_object.h:432
libMesh::DofMap::_shared_functors
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:1750
libMesh::Elem
This is the base class from which all geometric element types are derived.
Definition: elem.h:100
libMesh::DofMap::node_ptr
DofObject * node_ptr(MeshBase &mesh, dof_id_type i) const
Definition: dof_map.C:318
libMesh::DofMap::distribute_local_dofs_node_major
void distribute_local_dofs_node_major(dof_id_type &next_free_dof, MeshBase &mesh)
Distributes the global degrees of freedom for dofs on this processor.
Definition: dof_map.C:1171
libMesh::on_command_line
bool on_command_line(std::string arg)
Definition: libmesh.C:898
libMesh::DofMap::n_local_constrained_dofs
dof_id_type n_local_constrained_dofs() const
Definition: dof_map_constraints.C:1194
libMesh::DofMap::AugmentSendList::augment_send_list
virtual void augment_send_list(std::vector< dof_id_type > &send_list)=0
User-defined function to augment the send list.
data
IterBase * data
Ideally this private member data should have protected access.
Definition: variant_filter_iterator.h:337
libMesh::MeshBase::active_not_local_elements_end
virtual element_iterator active_not_local_elements_end()=0
libMesh::DofMap::default_algebraic_ghosting
DefaultCoupling & default_algebraic_ghosting()
Default algebraic ghosting functor.
Definition: dof_map.h:403
libMesh::DofMap::_default_evaluating
std::unique_ptr< DefaultCoupling > _default_evaluating
The default algebraic GhostingFunctor, used to implement standard libMesh send_list construction.
Definition: dof_map.h:1721
libMesh::System::get_dof_map
const DofMap & get_dof_map() const
Definition: system.h:2099
libMesh::DofMap::_implicit_neighbor_dofs
bool _implicit_neighbor_dofs
Definition: dof_map.h:1869
libMesh::DofMap::_dof_coupling
CouplingMatrix * _dof_coupling
Degree of freedom coupling.
Definition: dof_map.h:1434
libMesh::err
OStreamProxy err
libMesh::LAGRANGE
Definition: enum_fe_family.h:36
libMesh::SCALAR
Definition: enum_fe_family.h:58
libMesh::SUBDIVISION
Definition: enum_fe_family.h:55
libMesh::Elem::node_ref
const Node & node_ref(const unsigned int i) const
Definition: elem.h:2031
libMesh::TRI3SUBDIVISION
Definition: enum_elem_type.h:69
libMesh::Real
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
Definition: libmesh_common.h:121
libMesh::PeriodicBoundaryBase::pairedboundary
boundary_id_type pairedboundary
Definition: periodic_boundary_base.h:58
libMesh::DofMap::n_SCALAR_dofs
dof_id_type n_SCALAR_dofs() const
Definition: dof_map.h:630
libMesh::ReferenceCounter::_enable_print_counter
static bool _enable_print_counter
Flag to control whether reference count information is printed when print_info is called.
Definition: reference_counter.h:141
libMesh::DofMap::add_constraint_row
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 ...
Definition: dof_map_constraints.C:1364
libMesh::Elem::n_sides
virtual unsigned int n_sides() const =0
libMesh::DofMap::_error_on_constraint_loop
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:1619
libMesh::DofMap::_variables
std::vector< Variable > _variables
The finite element type for each variable.
Definition: dof_map.h:1624
libMesh::DofMap::_dof_indices
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 #ifdef DEBUG, const unsigned int v, 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:2349
libMesh::out
OStreamProxy out
libMesh::DofMap::first_dof
dof_id_type first_dof() const
Definition: dof_map.h:653
libMesh::DofConstraintRow
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:97
libMesh::FEInterface::max_order
static unsigned int max_order(const FEType &fe_t, const ElemType &el_t)
Definition: fe_interface.C:1281
libMesh::Elem::type
virtual ElemType type() const =0
libMesh::DofMap::gather_constraints
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.
Definition: dof_map_constraints.C:3985
libMesh::DofMap::first_old_dof
dof_id_type first_old_dof() const
Definition: dof_map.h:663
libMesh::DofMap::_sp
std::unique_ptr< SparsityPattern::Build > _sp
The sparsity pattern of the global matrix, kept around if it might be needed by future additions of t...
Definition: dof_map.h:1762
libMesh::DofMap::_implicit_neighbor_dofs_initialized
bool _implicit_neighbor_dofs_initialized
Bools to indicate if we override the –implicit_neighbor_dofs commandline options.
Definition: dof_map.h:1868
libMesh::Quality::name
std::string name(const ElemQuality q)
This function returns a string containing some name for q.
Definition: elem_quality.C:42
libMesh::DenseVector< Number >
libMesh::MeshBase::active_not_local_elements_begin
virtual element_iterator active_not_local_elements_begin()=0
libMesh::DofMap::_node_dof_indices
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:2272
libMesh::DofMap::_extra_send_list_context
void * _extra_send_list_context
A pointer associated with the extra send list that can optionally be passed in.
Definition: dof_map.h:1705
libMesh::ElemType
ElemType
Defines an enum for geometric element types.
Definition: enum_elem_type.h:33
libMesh::DofMap::variable_group
const VariableGroup & variable_group(const unsigned int c) const
Definition: dof_map.h:1884
libMesh::DofMap::_extra_send_list_function
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:1700
exact_value
Number exact_value(const Point &p, const Parameters &parameters, const std::string &, const std::string &)
Definition: adaptivity_ex2.C:104
libMesh::DofMap::merge_ghost_functor_outputs
static void merge_ghost_functor_outputs(GhostingFunctor::map_type &elements_to_ghost, std::set< CouplingMatrix * > &temporary_coupling_matrices, const std::set< GhostingFunctor * >::iterator &gf_begin, const std::set< GhostingFunctor * >::iterator &gf_end, const MeshBase::const_element_iterator &elems_begin, const MeshBase::const_element_iterator &elems_end, processor_id_type p)
Definition: dof_map.C:1440
libMesh::NumericVector::first_local_index
virtual numeric_index_type first_local_index() const =0
libMesh::NodeConstraintRow
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:145
libMesh::DofMap::add_neighbors_to_send_list
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:1507
libMesh::DofMap::add_coupling_functor
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:1838