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
 Backwards compatibility for prior AugmentSparsityPattern users. 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 attached to this DofMap. More...
 
void update_sparsity_pattern (SparseMatrix< Number > &matrix) const
 Additional matrices may be be temporarily initialized by this DofMap. More...
 
bool is_attached (SparseMatrix< Number > &matrix)
 Matrices should not be attached more than once. More...
 
std::size_t 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...
 
bool computed_sparsity_already () const
 Returns true iff a sparsity pattern has already been computed. More...
 
void set_constrained_sparsity_construction (bool use_constraints)
 Sets the current policy for constructing sparsity patterns: if use_constraints is true (for robustness), we explicitly account for sparsity entries created by constraint matrix pre- and post- application. More...
 
bool constrained_sparsity_construction ()
 Returns true iff the current policy when constructing sparsity patterns is to explicitly account for sparsity entries created by constraint matrix pre- and post- application. 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 (SparsityPattern::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
 
const SparsityPattern::Buildget_sparsity_pattern () const
 
void add_variable_group (VariableGroup var_group)
 Add an unknown of order order and finite element type type to the system of equations. More...
 
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
 
unsigned int var_group_from_var_number (unsigned int var_num) 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 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...
 
void set_verify_dirichlet_bc_consistency (bool val)
 Set the _verify_dirichlet_bc_consistency flag. 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, based on attached DirichletBoundary objects and on non-conforming interface in adapted meshes. 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
 
const DofConstraintsget_dof_constraints () const
 Provide a const accessor to the DofConstraints map. More...
 
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_heterogeneous_adjoint_constraints (const unsigned int qoi_num) const
 
bool has_heterogenous_adjoint_constraints (const unsigned int qoi_num) const
 Backwards compatibility with misspelling. More...
 
Number has_heterogeneous_adjoint_constraint (const unsigned int qoi_num, const dof_id_type dof) const
 
Number has_heterogenous_adjoint_constraint (const unsigned int qoi_num, const dof_id_type dof) const
 Backwards compatibility with misspelling. More...
 
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 heterogeneously_constrain_element_matrix_and_vector (DenseMatrix< Number > &matrix, DenseVector< Number > &rhs, std::vector< dof_id_type > &elem_dofs, bool asymmetric_constraint_rows=true, int qoi_index=-1) const
 Constrains the element matrix and vector. 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
 
void heterogeneously_constrain_element_vector (const DenseMatrix< Number > &matrix, DenseVector< Number > &rhs, std::vector< dof_id_type > &elem_dofs, bool asymmetric_constraint_rows=true, int qoi_index=-1) const
 Constrains the element vector. 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
 
void heterogeneously_constrain_element_jacobian_and_residual (DenseMatrix< Number > &matrix, DenseVector< Number > &rhs, std::vector< dof_id_type > &elem_dofs, NumericVector< Number > &solution_local) const
 Constrains the element Jacobian and residual. More...
 
void heterogeneously_constrain_element_residual (DenseVector< Number > &rhs, std::vector< dof_id_type > &elem_dofs, NumericVector< Number > &solution_local) const
 Constrains the element residual. More...
 
void constrain_element_residual (DenseVector< Number > &rhs, std::vector< dof_id_type > &elem_dofs, NumericVector< Number > &solution_local) const
 Constrains the element residual. 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
 Heterogeneously 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 ()
 
const PeriodicBoundariesget_periodic_boundaries () const
 
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 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...
 
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
 
std::unique_ptr< SparsityPattern::Buildbuild_sparsity (const MeshBase &mesh, bool calculate_constrained=false) const
 Builds a sparsity pattern for matrices using the current degree-of-freedom numbering and coupling. More...
 
void should_p_refine (unsigned int g, bool p_refine)
 Describe whether the given variable group should be p-refined. More...
 
bool should_p_refine (unsigned int g) const
 Whether the given variable group should be p-refined. More...
 
bool should_p_refine_var (unsigned int var) const
 Whether the given variable should be p-refined. More...
 
void should_p_refine (FEFamily, bool)=delete
 
void should_p_refine (Order, bool)=delete
 
bool should_p_refine (FEFamily) const =delete
 
bool should_p_refine (Order) const =delete
 
const Parallel::Communicatorcomm () 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_stream=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) noexcept
 Increments the construction counter. More...
 
void increment_destructor_count (const std::string &name) noexcept
 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...
 
typedef std::set< std::unique_ptr< CouplingMatrix >, Utility::CompareUnderlyingCouplingMatricesSet
 

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...
 
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 distribute_scalar_dofs (dof_id_type &next_free_dof)
 
void assert_no_nodes_missed (MeshBase &mesh)
 
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 process_mesh_constraint_rows (const MeshBase &mesh)
 Adds any spline constraints from the Mesh to our DoF constraints. More...
 

Static Private Member Functions

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

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...
 
bool _constrained_sparsity_construction
 This flag indicates whether or not we explicitly take constraint equations into account when computing a sparsity pattern. 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...
 
std::unordered_map< unsigned int, unsigned int_var_to_vg
 A map from variable number to variable group number. 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...
 
SparsityPattern::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. 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...
 
std::unordered_set< unsigned int_dont_p_refine
 A container of variable groups that we should not p-refine. 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< std::unique_ptr< 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
 
bool _verify_dirichlet_bc_consistency
 Flag which determines whether we should do some additional checking of the consistency of the DirichletBoundary objects added by the user. More...
 

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 169 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 119 of file reference_counter.h.

◆ CouplingMatricesSet

Definition at line 1745 of file dof_map.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 1693 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.

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

136  :
137  ParallelObject (mesh.comm()),
138  _dof_coupling(nullptr),
141  _variables(),
144  _sys_number(number),
145  _mesh(mesh),
146  _matrices(),
147  _first_df(),
148  _end_df(),
150  _send_list(),
151  _augment_sparsity_pattern(nullptr),
152  _extra_sparsity_function(nullptr),
153  _extra_sparsity_context(nullptr),
154  _augment_send_list(nullptr),
155  _extra_send_list_function(nullptr),
156  _extra_send_list_context(nullptr),
157  _default_coupling(std::make_unique<DefaultCoupling>()),
158  _default_evaluating(std::make_unique<DefaultCoupling>()),
160  _n_dfs(0),
161  _n_SCALAR_dofs(0)
162 #ifdef LIBMESH_ENABLE_AMR
163  , _n_old_dfs(0),
164  _first_old_df(),
165  _end_old_df(),
167 #endif
168 #ifdef LIBMESH_ENABLE_CONSTRAINTS
169  , _dof_constraints()
173 #endif
174 #ifdef LIBMESH_ENABLE_NODE_CONSTRAINTS
176 #endif
177 #ifdef LIBMESH_ENABLE_PERIODIC
178  , _periodic_boundaries(std::make_unique<PeriodicBoundaries>())
179 #endif
180 #ifdef LIBMESH_ENABLE_DIRICHLET
181  , _dirichlet_boundaries(std::make_unique<DirichletBoundaries>())
183 #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 }
std::vector< VariableGroup > _variable_groups
The finite element type for each variable group.
Definition: dof_map.h:1847
ParallelObject(const Parallel::Communicator &comm_in)
Constructor.
bool _implicit_neighbor_dofs_initialized
Bools to indicate if we override the –implicit_neighbor_dofs commandline options.
Definition: dof_map.h:2076
const unsigned int _sys_number
The number of the system we manage DOFs for.
Definition: dof_map.h:1862
bool _implicit_neighbor_dofs
Definition: dof_map.h:2077
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:1831
void * _extra_sparsity_context
A pointer associated with the extra sparsity that can optionally be passed in.
Definition: dof_map.h:1913
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:1896
MeshBase & mesh
std::unique_ptr< DirichletBoundaries > _dirichlet_boundaries
Data structure containing Dirichlet functions.
Definition: dof_map.h:2061
std::vector< dof_id_type > _end_old_df
Last old DOF index (plus 1) on processor p.
Definition: dof_map.h:2014
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:1861
std::vector< dof_id_type > _first_old_df
First old DOF index on processor p.
Definition: dof_map.h:2009
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:1890
AdjointDofConstraintValues _adjoint_constraint_values
Definition: dof_map.h:2037
bool _constrained_sparsity_construction
This flag indicates whether or not we explicitly take constraint equations into account when computin...
Definition: dof_map.h:1837
AugmentSendList * _augment_send_list
Function object to call to add extra entries to the send list.
Definition: dof_map.h:1918
bool need_full_sparsity_pattern
Default false; set to true if any attached matrix requires a full sparsity pattern.
Definition: dof_map.h:1979
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:2020
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:1906
dof_id_type _n_SCALAR_dofs
The total number of SCALAR dofs associated to all SCALAR variables.
Definition: dof_map.h:1997
DofConstraints _dof_constraints
Data structure containing DOF constraints.
Definition: dof_map.h:2033
CouplingMatrix * _dof_coupling
Degree of freedom coupling.
Definition: dof_map.h:1592
void * _extra_send_list_context
A pointer associated with the extra send list that can optionally be passed in.
Definition: dof_map.h:1928
std::vector< SparseMatrix< Number > *> _matrices
Additional matrices handled by this object.
Definition: dof_map.h:1874
std::vector< std::unique_ptr< DirichletBoundaries > > _adjoint_dirichlet_boundaries
Data structure containing Dirichlet functions.
Definition: dof_map.h:2067
std::unique_ptr< PeriodicBoundaries > _periodic_boundaries
Data structure containing periodic boundaries.
Definition: dof_map.h:2053
bool _verify_dirichlet_bc_consistency
Flag which determines whether we should do some additional checking of the consistency of the Dirichl...
Definition: dof_map.h:2089
std::unique_ptr< DefaultCoupling > _default_coupling
The default coupling GhostingFunctor, used to implement standard libMesh sparsity pattern constructio...
Definition: dof_map.h:1936
DofConstraintValueMap _primal_constraint_values
Definition: dof_map.h:2035
std::vector< Variable > _variables
The finite element type for each variable.
Definition: dof_map.h:1842
DofConstraints _stashed_dof_constraints
Definition: dof_map.h:2033
SparsityPattern::AugmentSparsityPattern * _augment_sparsity_pattern
Function object to call to add extra entries to the sparsity pattern.
Definition: dof_map.h:1901
dof_id_type _n_old_dfs
Total number of degrees of freedom on old dof objects.
Definition: dof_map.h:2004
std::vector< dof_id_type > _end_df
Last DOF index (plus 1) on processor p.
Definition: dof_map.h:1884
std::vector< dof_id_type > _first_df
First DOF index on processor p.
Definition: dof_map.h:1879
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:1923
MeshBase & _mesh
The mesh that system uses.
Definition: dof_map.h:1867
std::unique_ptr< DefaultCoupling > _default_evaluating
The default algebraic GhostingFunctor, used to implement standard libMesh send_list construction...
Definition: dof_map.h:1944
std::vector< unsigned int > _variable_group_numbers
The variable group number for each variable.
Definition: dof_map.h:1852
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:1886
dof_id_type _n_dfs
Total number of degrees of freedom.
Definition: dof_map.h:1991
NodeConstraints _node_constraints
Data structure containing DofObject constraints.
Definition: dof_map.h:2044

◆ ~DofMap()

libMesh::DofMap::~DofMap ( )

Destructor.

Definition at line 206 of file dof_map.C.

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

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 }
void remove_ghosting_functor(GhostingFunctor &ghosting_functor)
Removes a functor which was previously added to the set of ghosting functors.
Definition: mesh_base.C:888
void clear()
Free all new memory associated with the object, but restore its original state, with the mesh pointer...
Definition: dof_map.C:850
std::unique_ptr< DefaultCoupling > _default_coupling
The default coupling GhostingFunctor, used to implement standard libMesh sparsity pattern constructio...
Definition: dof_map.h:1936
MeshBase & _mesh
The mesh that system uses.
Definition: dof_map.h:1867
std::unique_ptr< DefaultCoupling > _default_evaluating
The default algebraic GhostingFunctor, used to implement standard libMesh send_list construction...
Definition: dof_map.h:1944

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 2381 of file dof_map.C.

References _dont_p_refine, libMesh::Elem::active(), libMesh::Variable::active_on_subdomain(), 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(), 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::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().

2394 {
2395  const VariableGroup & var = this->variable_group(vg);
2396 
2397  if (var.active_on_subdomain(elem.subdomain_id()))
2398  {
2399  const ElemType type = elem.type();
2400  const unsigned int sys_num = this->sys_number();
2401 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
2402  const bool is_inf = elem.infinite();
2403 #endif
2404 
2405  const bool extra_hanging_dofs =
2406  FEInterface::extra_hanging_dofs(var.type());
2407 
2408  FEType fe_type = var.type();
2409 
2410  const bool add_p_level =
2411 #ifdef LIBMESH_ENABLE_AMR
2412  !_dont_p_refine.count(vg);
2413 #else
2414  false;
2415 #endif
2416 
2417 #ifdef DEBUG
2418  // The number of dofs per element is non-static for subdivision FE
2419  if (var.type().family == SUBDIVISION)
2420  tot_size += n_nodes;
2421  else
2422  // FIXME: Is the passed-in p_level just elem.p_level()? If so,
2423  // this seems redundant.
2424  tot_size += FEInterface::n_dofs(fe_type, add_p_level*p_level, &elem);
2425 #endif
2426 
2427  // The total Order is not required when getting the function
2428  // pointer, it is only needed when the function is called (see
2429  // below).
2430  const FEInterface::n_dofs_at_node_ptr ndan =
2431  FEInterface::n_dofs_at_node_function(fe_type, &elem);
2432 
2433  // Get the node-based DOF numbers
2434  for (unsigned int n=0; n != n_nodes; n++)
2435  {
2436  const Node & node = *nodes[n];
2437 
2438  // Cache the intermediate lookups that are common to every
2439  // component
2440 #ifdef DEBUG
2441  const std::pair<unsigned int, unsigned int>
2442  vg_and_offset = node.var_to_vg_and_offset(sys_num,v);
2443  libmesh_assert_equal_to (vg, vg_and_offset.first);
2444  libmesh_assert_equal_to (vig, vg_and_offset.second);
2445 #endif
2446  const unsigned int n_comp = node.n_comp_group(sys_num,vg);
2447 
2448  // There is a potential problem with h refinement. Imagine a
2449  // quad9 that has a linear FE on it. Then, on the hanging side,
2450  // it can falsely identify a DOF at the mid-edge node. This is why
2451  // we go through FEInterface instead of node.n_comp() directly.
2452  const unsigned int nc =
2453 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
2454  is_inf ?
2455  FEInterface::n_dofs_at_node(fe_type, add_p_level*p_level, &elem, n) :
2456 #endif
2457  ndan (type, static_cast<Order>(fe_type.order + add_p_level*p_level), n);
2458 
2459  // If this is a non-vertex on a hanging node with extra
2460  // degrees of freedom, we use the non-vertex dofs (which
2461  // come in reverse order starting from the end, to
2462  // simplify p refinement)
2463  if (extra_hanging_dofs && !elem.is_vertex(n))
2464  {
2465  const int dof_offset = n_comp - nc;
2466 
2467  // We should never have fewer dofs than necessary on a
2468  // node unless we're getting indices on a parent element,
2469  // and we should never need the indices on such a node
2470  if (dof_offset < 0)
2471  {
2472  libmesh_assert(!elem.active());
2473  di.resize(di.size() + nc, DofObject::invalid_id);
2474  }
2475  else
2476  for (int i=int(n_comp)-1; i>=dof_offset; i--)
2477  {
2478  const dof_id_type d =
2479  node.dof_number(sys_num, vg, vig, i, n_comp);
2480  libmesh_assert_not_equal_to (d, DofObject::invalid_id);
2481  di.push_back(d);
2482  }
2483  }
2484  // If this is a vertex or an element without extra hanging
2485  // dofs, our dofs come in forward order coming from the
2486  // beginning
2487  else
2488  {
2489  // We have a good component index only if it's being
2490  // used on this FE type (nc) *and* it's available on
2491  // this DofObject (n_comp).
2492  const unsigned int good_nc = std::min(n_comp, nc);
2493  for (unsigned int i=0; i!=good_nc; ++i)
2494  {
2495  const dof_id_type d =
2496  node.dof_number(sys_num, vg, vig, i, n_comp);
2497  libmesh_assert_not_equal_to (d, DofObject::invalid_id);
2498  libmesh_assert_less (d, this->n_dofs());
2499  di.push_back(d);
2500  }
2501 
2502  // With fewer good component indices than we need, e.g.
2503  // due to subdomain expansion, the remaining expected
2504  // indices are marked invalid.
2505  if (n_comp < nc)
2506  for (unsigned int i=n_comp; i!=nc; ++i)
2507  di.push_back(DofObject::invalid_id);
2508  }
2509  }
2510 
2511  // If there are any element-based DOF numbers, get them
2512  const unsigned int nc = FEInterface::n_dofs_per_elem(fe_type, add_p_level*p_level, &elem);
2513 
2514  // We should never have fewer dofs than necessary on an
2515  // element unless we're getting indices on a parent element
2516  // (and we should never need those indices) or off-domain for a
2517  // subdomain-restricted variable (where invalid_id is the
2518  // correct thing to return)
2519  if (nc != 0)
2520  {
2521  const unsigned int n_comp = elem.n_comp_group(sys_num,vg);
2522  if (elem.n_systems() > sys_num && nc <= n_comp)
2523  {
2524  for (unsigned int i=0; i<nc; i++)
2525  {
2526  const dof_id_type d =
2527  elem.dof_number(sys_num, vg, vig, i, n_comp);
2528  libmesh_assert_not_equal_to (d, DofObject::invalid_id);
2529 
2530  di.push_back(d);
2531  }
2532  }
2533  else
2534  {
2535  libmesh_assert(!elem.active() || fe_type.family == LAGRANGE || fe_type.family == SUBDIVISION);
2536  di.resize(di.size() + nc, DofObject::invalid_id);
2537  }
2538  }
2539  }
2540 }
static unsigned int n_dofs_per_elem(const unsigned int dim, const FEType &fe_t, const ElemType t)
Definition: fe_interface.C:772
ElemType
Defines an enum for geometric element types.
Order
defines an enum for polynomial orders.
Definition: enum_order.h:40
static unsigned int n_dofs(const unsigned int dim, const FEType &fe_t, const ElemType t)
Definition: fe_interface.C:597
unsigned int sys_number() const
Definition: dof_map.h:2096
const dof_id_type n_nodes
Definition: tecplot_io.C:67
dof_id_type n_dofs() const
Definition: dof_map.h:659
static bool extra_hanging_dofs(const FEType &fe_t)
libmesh_assert(ctx)
static const dof_id_type invalid_id
An invalid id to distinguish an uninitialized DofObject.
Definition: dof_object.h:477
const VariableGroup & variable_group(const unsigned int c) const
Definition: dof_map.h:2104
static n_dofs_at_node_ptr n_dofs_at_node_function(const unsigned int dim, const FEType &fe_t)
Definition: fe_interface.C:702
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:679
unsigned int(* n_dofs_at_node_ptr)(const ElemType, const Order, const unsigned int)
Definition: fe_interface.h:170
std::unordered_set< unsigned int > _dont_p_refine
A container of variable groups that we should not p-refine.
Definition: dof_map.h:2025
uint8_t dof_id_type
Definition: id_types.h:67

◆ _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 2296 of file dof_map.C.

References _dont_p_refine, libMesh::Elem::active(), 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(), sys_number(), libMesh::Variable::type(), libMesh::DofObject::var_to_vg_and_offset(), and variable_group().

Referenced by dof_indices(), and old_dof_indices().

2301 {
2302  // Half of this is a cut and paste of _dof_indices code below, but
2303  // duplication actually seems cleaner than creating a helper
2304  // function with a million arguments and hoping the compiler inlines
2305  // it properly into one of our most highly trafficked functions.
2306 
2307  LOG_SCOPE("_node_dof_indices()", "DofMap");
2308 
2309  const unsigned int sys_num = this->sys_number();
2310  const auto [vg, vig] =
2311  obj.var_to_vg_and_offset(sys_num,vn);
2312  const unsigned int n_comp = obj.n_comp_group(sys_num,vg);
2313 
2314  const VariableGroup & var = this->variable_group(vg);
2315  FEType fe_type = var.type();
2316  const bool extra_hanging_dofs =
2318 
2319  const bool add_p_level =
2320 #ifdef LIBMESH_ENABLE_AMR
2321  !_dont_p_refine.count(vg);
2322 #else
2323  false;
2324 #endif
2325 
2326  // There is a potential problem with h refinement. Imagine a
2327  // quad9 that has a linear FE on it. Then, on the hanging side,
2328  // it can falsely identify a DOF at the mid-edge node. This is why
2329  // we go through FEInterface instead of obj->n_comp() directly.
2330  const unsigned int nc =
2331  FEInterface::n_dofs_at_node(fe_type, &elem, n, add_p_level);
2332 
2333  // If this is a non-vertex on a hanging node with extra
2334  // degrees of freedom, we use the non-vertex dofs (which
2335  // come in reverse order starting from the end, to
2336  // simplify p refinement)
2337  if (extra_hanging_dofs && nc && !elem.is_vertex(n))
2338  {
2339  const int dof_offset = n_comp - nc;
2340 
2341  // We should never have fewer dofs than necessary on a
2342  // node unless we're getting indices on a parent element,
2343  // and we should never need the indices on such a node
2344  if (dof_offset < 0)
2345  {
2346  libmesh_assert(!elem.active());
2347  di.resize(di.size() + nc, DofObject::invalid_id);
2348  }
2349  else
2350  for (unsigned int i = dof_offset; i != n_comp; ++i)
2351  {
2352  const dof_id_type d =
2353  obj.dof_number(sys_num, vg, vig, i, n_comp);
2354  libmesh_assert_not_equal_to (d, DofObject::invalid_id);
2355  di.push_back(d);
2356  }
2357  }
2358  // If this is a vertex or an element without extra hanging
2359  // dofs, our dofs come in forward order coming from the
2360  // beginning. But we still might not have all those dofs, in cases
2361  // where a subdomain-restricted variable just had its subdomain
2362  // expanded.
2363  else
2364  {
2365  const unsigned int good_nc =
2366  std::min(static_cast<unsigned int>(n_comp), nc);
2367  for (unsigned int i=0; i != good_nc; ++i)
2368  {
2369  const dof_id_type d =
2370  obj.dof_number(sys_num, vg, vig, i, n_comp);
2371  libmesh_assert_not_equal_to (d, DofObject::invalid_id);
2372  di.push_back(d);
2373  }
2374  for (unsigned int i=good_nc; i != nc; ++i)
2375  di.push_back(DofObject::invalid_id);
2376  }
2377 }
unsigned int sys_number() const
Definition: dof_map.h:2096
static bool extra_hanging_dofs(const FEType &fe_t)
libmesh_assert(ctx)
static const dof_id_type invalid_id
An invalid id to distinguish an uninitialized DofObject.
Definition: dof_object.h:477
const VariableGroup & variable_group(const unsigned int c) const
Definition: dof_map.h:2104
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:679
std::unordered_set< unsigned int > _dont_p_refine
A container of variable groups that we should not p-refine.
Definition: dof_map.h:2025
uint8_t dof_id_type
Definition: id_types.h:67

◆ 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 2214 of file dof_map_constraints.C.

References _adjoint_constraint_values, and is_constrained_dof().

2219 {
2220  // Optionally allow the user to overwrite constraints. Defaults to false.
2221  if (forbid_constraint_overwrite)
2222  {
2223  libmesh_error_msg_if(!this->is_constrained_dof(dof_number),
2224  "ERROR: DOF " << dof_number << " has no corresponding primal constraint!");
2225 #ifndef NDEBUG
2226  // No way to do this without a non-normalized tolerance?
2227 
2228  // // If the user passed in more than just the rhs, let's check the
2229  // // coefficients for consistency
2230  // if (!constraint_row.empty())
2231  // {
2232  // DofConstraintRow row = _dof_constraints[dof_number];
2233  // for (const auto & [dof, val] : row)
2234  // libmesh_assert(constraint_row.find(dof)->second == val);
2235  // }
2236  //
2237  // if (_adjoint_constraint_values[qoi_index].find(dof_number) !=
2238  // _adjoint_constraint_values[qoi_index].end())
2239  // libmesh_assert_equal_to(_adjoint_constraint_values[qoi_index][dof_number],
2240  // constraint_rhs);
2241 
2242 #endif
2243  }
2244 
2245  // Creates the map of rhs values if it doesn't already exist; then
2246  // adds the current value to that map
2247 
2248  // We don't get insert_or_assign until C++17 so we make do.
2249  std::pair<DofConstraintValueMap::iterator, bool> rhs_it =
2250  _adjoint_constraint_values[qoi_index].emplace(dof_number, constraint_rhs);
2251  if (!rhs_it.second)
2252  rhs_it.first->second = constraint_rhs;
2253 }
AdjointDofConstraintValues _adjoint_constraint_values
Definition: dof_map.h:2037
bool is_constrained_dof(const dof_id_type dof) const
Definition: dof_map.h:2182

◆ 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 5452 of file dof_map_constraints.C.

References _adjoint_dirichlet_boundaries.

5454 {
5455  unsigned int old_size = cast_int<unsigned int>
5457  for (unsigned int i = old_size; i <= qoi_index; ++i)
5458  _adjoint_dirichlet_boundaries.push_back(std::make_unique<DirichletBoundaries>());
5459 
5460  // Make copy of DirichletBoundary, owned by _adjoint_dirichlet_boundaries
5461  _adjoint_dirichlet_boundaries[qoi_index]->push_back
5462  (std::make_unique<DirichletBoundary>(dirichlet_boundary));
5463 }
std::vector< std::unique_ptr< DirichletBoundaries > > _adjoint_dirichlet_boundaries
Data structure containing Dirichlet functions.
Definition: dof_map.h:2067

◆ 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 1886 of file dof_map.C.

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

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

1888 {
1889  _algebraic_ghosting_functors.insert(&evaluable_functor);
1890  evaluable_functor.set_mesh(&_mesh);
1891  if (to_mesh)
1892  _mesh.add_ghosting_functor(evaluable_functor);
1893 }
std::set< GhostingFunctor * > _algebraic_ghosting_functors
The list of all GhostingFunctor objects to be used when distributing ghosted vectors.
Definition: dof_map.h:1954
MeshBase & _mesh
The mesh that system uses.
Definition: dof_map.h:1867
void add_ghosting_functor(GhostingFunctor &ghosting_functor)
Adds a functor which can specify ghosting requirements for use on distributed meshes.
Definition: mesh_base.h:1244

◆ 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 391 of file dof_map.h.

References _shared_functors, and add_algebraic_ghosting_functor().

393  { _shared_functors[evaluable_functor.get()] = evaluable_functor;
394  this->add_algebraic_ghosting_functor(*evaluable_functor, to_mesh); }
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:1973
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:1886

◆ add_constraint_row() [1/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 2179 of file dof_map_constraints.C.

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

Referenced by add_constraint_row(), MyConstraint::constrain(), and process_mesh_constraint_rows().

2183 {
2184  // Optionally allow the user to overwrite constraints. Defaults to false.
2185  libmesh_error_msg_if(forbid_constraint_overwrite && this->is_constrained_dof(dof_number),
2186  "ERROR: DOF " << dof_number << " was already constrained!");
2187 
2188  libmesh_assert_less(dof_number, this->n_dofs());
2189 
2190  // There is an implied "1" on the diagonal of the constraint row, and the user
2191  // should not try to manually set _any_ value on the diagonal.
2192  libmesh_assert_msg(!constraint_row.count(dof_number),
2193  "Error: constraint_row for dof " << dof_number <<
2194  " should not contain an entry for dof " << dof_number);
2195 
2196 #ifndef NDEBUG
2197  for (const auto & pr : constraint_row)
2198  libmesh_assert_less(pr.first, this->n_dofs());
2199 #endif
2200 
2201  // We don't get insert_or_assign until C++17 so we make do.
2202  std::pair<DofConstraints::iterator, bool> it =
2203  _dof_constraints.emplace(dof_number, constraint_row);
2204  if (!it.second)
2205  it.first->second = constraint_row;
2206 
2207  std::pair<DofConstraintValueMap::iterator, bool> rhs_it =
2208  _primal_constraint_values.emplace(dof_number, constraint_rhs);
2209  if (!rhs_it.second)
2210  rhs_it.first->second = constraint_rhs;
2211 }
dof_id_type n_dofs() const
Definition: dof_map.h:659
bool is_constrained_dof(const dof_id_type dof) const
Definition: dof_map.h:2182
DofConstraints _dof_constraints
Data structure containing DOF constraints.
Definition: dof_map.h:2033
DofConstraintValueMap _primal_constraint_values
Definition: dof_map.h:2035

◆ add_constraint_row() [2/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 1005 of file dof_map.h.

References add_constraint_row().

1008  { add_constraint_row(dof_number, constraint_row, 0., forbid_constraint_overwrite); }
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 ...

◆ 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 5345 of file dof_map_constraints.C.

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

Referenced by process_constraints().

5346 {
5347  // This function must be run on all processors at once
5348  parallel_object_only();
5349 
5350  // Return immediately if there's nothing to gather
5351  if (this->n_processors() == 1)
5352  return;
5353 
5354  // We might get to return immediately if none of the processors
5355  // found any constraints
5356  unsigned int has_constraints = !_dof_constraints.empty();
5357  this->comm().max(has_constraints);
5358  if (!has_constraints)
5359  return;
5360 
5361  for (const auto & [constrained_dof, constraint_row] : _dof_constraints)
5362  {
5363  // We only need the dependencies of our own constrained dofs
5364  if (!this->local_index(constrained_dof))
5365  continue;
5366 
5367  for (const auto & j : constraint_row)
5368  {
5369  dof_id_type constraint_dependency = j.first;
5370 
5371  // No point in adding one of our own dofs to the send_list
5372  if (this->local_index(constraint_dependency))
5373  continue;
5374 
5375  _send_list.push_back(constraint_dependency);
5376  }
5377  }
5378 }
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:1896
const Parallel::Communicator & comm() const
processor_id_type n_processors() const
DofConstraints _dof_constraints
Data structure containing DOF constraints.
Definition: dof_map.h:2033
void max(const T &r, T &o, Request &req) const
uint8_t dof_id_type
Definition: id_types.h:67
bool local_index(dof_id_type dof_index) const
Definition: dof_map.h:831

◆ 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 1861 of file dof_map.C.

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

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

1863 {
1864  _coupling_functors.insert(&coupling_functor);
1865  coupling_functor.set_mesh(&_mesh);
1866  if (to_mesh)
1867  _mesh.add_ghosting_functor(coupling_functor);
1868 }
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:1967
MeshBase & _mesh
The mesh that system uses.
Definition: dof_map.h:1867
void add_ghosting_functor(GhostingFunctor &ghosting_functor)
Adds a functor which can specify ghosting requirements for use on distributed meshes.
Definition: mesh_base.h:1244

◆ 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 329 of file dof_map.h.

References _shared_functors, and add_coupling_functor().

331  { _shared_functors[coupling_functor.get()] = coupling_functor;
332  this->add_coupling_functor(*coupling_functor, to_mesh); }
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:1861
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:1973

◆ 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 1852 of file dof_map.C.

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

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

1853 {
1854  this->add_coupling_functor(this->default_coupling());
1856 }
DefaultCoupling & default_coupling()
Default coupling functor.
Definition: dof_map.h:356
DefaultCoupling & default_algebraic_ghosting()
Default algebraic ghosting functor.
Definition: dof_map.h:418
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:1861
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:1886

◆ add_dirichlet_boundary()

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

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

The constraints implied by DirichletBoundary objects are imposed in the same order in which DirichletBoundary objects are added to the DofMap. When multiple DirichletBoundary objects would impose competing constraints on a given DOF, the first DirichletBoundary to constrain the DOF "wins". This distinction is important when e.g. two surfaces (sidesets) intersect. The nodes on the intersection will be constrained according to whichever sideset's DirichletBoundary object was added to the DofMap first.

Definition at line 5446 of file dof_map_constraints.C.

References _dirichlet_boundaries.

Referenced by libMesh::DifferentiableSystem::add_dot_var_dirichlet_bcs(), assemble_and_solve(), HeatSystem::init_data(), SimpleRBConstruction::init_data(), LaplaceSystem::init_dirichlet_bcs(), main(), set_lid_driven_bcs(), set_poiseuille_bcs(), set_stagnation_bcs(), set_system_parameters(), MeshAssignTest::testMeshMoveAssign(), PeriodicBCTest::testPeriodicBC(), and BoundaryInfoTest::testShellFaceConstraints().

5447 {
5448  _dirichlet_boundaries->push_back(std::make_unique<DirichletBoundary>(dirichlet_boundary));
5449 }
std::unique_ptr< DirichletBoundaries > _dirichlet_boundaries
Data structure containing Dirichlet functions.
Definition: dof_map.h:2061

◆ 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 1544 of file dof_map.C.

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

Referenced by distribute_dofs(), and reinit_send_list().

1545 {
1546  LOG_SCOPE("add_neighbors_to_send_list()", "DofMap");
1547 
1548  // Return immediately if there's no ghost data
1549  if (this->n_processors() == 1)
1550  return;
1551 
1552  const unsigned int n_var = this->n_variables();
1553 
1554  MeshBase::const_element_iterator local_elem_it
1555  = mesh.active_local_elements_begin();
1556  const MeshBase::const_element_iterator local_elem_end
1557  = mesh.active_local_elements_end();
1558 
1559  GhostingFunctor::map_type elements_to_send;
1560  DofMap::CouplingMatricesSet temporary_coupling_matrices;
1561 
1562  // We need to add dofs to the send list if they've been directly
1563  // requested by an algebraic ghosting functor or they've been
1564  // indirectly requested by a coupling functor.
1565  this->merge_ghost_functor_outputs(elements_to_send,
1566  temporary_coupling_matrices,
1569  local_elem_it, local_elem_end, mesh.processor_id());
1570 
1571  this->merge_ghost_functor_outputs(elements_to_send,
1572  temporary_coupling_matrices,
1573  this->coupling_functors_begin(),
1574  this->coupling_functors_end(),
1575  local_elem_it, local_elem_end, mesh.processor_id());
1576 
1577  // Making a list of non-zero coupling matrix columns is an
1578  // O(N_var^2) operation. We cache it so we only have to do it once
1579  // per CouplingMatrix and not once per element.
1580  std::map<const CouplingMatrix *, std::vector<unsigned int>>
1581  column_variable_lists;
1582 
1583  for (const auto & [partner, ghost_coupling] : elements_to_send)
1584  {
1585  // We asked ghosting functors not to give us local elements
1586  libmesh_assert_not_equal_to
1587  (partner->processor_id(), this->processor_id());
1588 
1589  // Loop over any present coupling matrix column variables if we
1590  // have a coupling matrix, or just add all variables to
1591  // send_list if not.
1592  if (ghost_coupling)
1593  {
1594  libmesh_assert_equal_to (ghost_coupling->size(), n_var);
1595 
1596  // Try to find a cached list of column variables.
1597  std::map<const CouplingMatrix *, std::vector<unsigned int>>::const_iterator
1598  column_variable_list = column_variable_lists.find(ghost_coupling);
1599 
1600  // If we didn't find it, then we need to create it.
1601  if (column_variable_list == column_variable_lists.end())
1602  {
1603  auto inserted_variable_list_pair =
1604  column_variable_lists.emplace(ghost_coupling, std::vector<unsigned int>());
1605  column_variable_list = inserted_variable_list_pair.first;
1606 
1607  std::vector<unsigned int> & new_variable_list =
1608  inserted_variable_list_pair.first->second;
1609 
1610  std::vector<unsigned char> has_variable(n_var, false);
1611 
1612  for (unsigned int vi = 0; vi != n_var; ++vi)
1613  {
1614  ConstCouplingRow ccr(vi, *ghost_coupling);
1615 
1616  for (const auto & vj : ccr)
1617  has_variable[vj] = true;
1618  }
1619  for (unsigned int vj = 0; vj != n_var; ++vj)
1620  {
1621  if (has_variable[vj])
1622  new_variable_list.push_back(vj);
1623  }
1624  }
1625 
1626  const std::vector<unsigned int> & variable_list =
1627  column_variable_list->second;
1628 
1629  for (const auto & vj : variable_list)
1630  {
1631  std::vector<dof_id_type> di;
1632  this->dof_indices (partner, di, vj);
1633 
1634  // Insert the remote DOF indices into the send list
1635  for (auto d : di)
1636  if (d != DofObject::invalid_id &&
1637  !this->local_index(d))
1638  {
1639  libmesh_assert_less(d, this->n_dofs());
1640  _send_list.push_back(d);
1641  }
1642  }
1643  }
1644  else
1645  {
1646  std::vector<dof_id_type> di;
1647  this->dof_indices (partner, di);
1648 
1649  // Insert the remote DOF indices into the send list
1650  for (const auto & dof : di)
1651  if (dof != DofObject::invalid_id &&
1652  !this->local_index(dof))
1653  {
1654  libmesh_assert_less(dof, this->n_dofs());
1655  _send_list.push_back(dof);
1656  }
1657  }
1658 
1659  }
1660 
1661  // We're now done with any merged coupling matrices we had to create.
1662  temporary_coupling_matrices.clear();
1663 
1664  //-------------------------------------------------------------------------
1665  // Our coupling functors added dofs from neighboring elements to the
1666  // send list, but we may still need to add non-local dofs from local
1667  // elements.
1668  //-------------------------------------------------------------------------
1669 
1670  // Loop over the active local elements, adding all active elements
1671  // that neighbor an active local element to the send list.
1672  for ( ; local_elem_it != local_elem_end; ++local_elem_it)
1673  {
1674  const Elem * elem = *local_elem_it;
1675 
1676  std::vector<dof_id_type> di;
1677  this->dof_indices (elem, di);
1678 
1679  // Insert the remote DOF indices into the send list
1680  for (const auto & dof : di)
1681  if (dof != DofObject::invalid_id &&
1682  !this->local_index(dof))
1683  {
1684  libmesh_assert_less(dof, this->n_dofs());
1685  _send_list.push_back(dof);
1686  }
1687  }
1688 }
std::set< GhostingFunctor * >::const_iterator coupling_functors_begin() const
Beginning of range of coupling functors.
Definition: dof_map.h:344
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:1992
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:1896
MeshBase & mesh
unsigned int n_variables() const
Definition: dof_map.h:621
std::map< const Elem *, const CouplingMatrix *, CompareDofObjectsByPIDAndThenID > map_type
What elements do we care about and what variables do we care about on each element?
processor_id_type n_processors() const
dof_id_type n_dofs() const
Definition: dof_map.h:659
static void merge_ghost_functor_outputs(GhostingFunctor::map_type &elements_to_ghost, CouplingMatricesSet &temporary_coupling_matrices, const std::set< GhostingFunctor *>::iterator &gf_begin, const std::set< GhostingFunctor *>::iterator &gf_end, const MeshBase::const_element_iterator &elems_begin, const MeshBase::const_element_iterator &elems_end, processor_id_type p)
Definition: dof_map.C:1440
std::set< std::unique_ptr< CouplingMatrix >, Utility::CompareUnderlying > CouplingMatricesSet
Definition: dof_map.h:1745
static const dof_id_type invalid_id
An invalid id to distinguish an uninitialized DofObject.
Definition: dof_object.h:477
std::set< GhostingFunctor * >::const_iterator algebraic_ghosting_functors_end() const
End of range of algebraic ghosting functors.
Definition: dof_map.h:412
std::set< GhostingFunctor * >::const_iterator coupling_functors_end() const
End of range of coupling functors.
Definition: dof_map.h:350
std::set< GhostingFunctor * >::const_iterator algebraic_ghosting_functors_begin() const
Beginning of range of algebraic ghosting functors.
Definition: dof_map.h:406
processor_id_type processor_id() const
bool local_index(dof_id_type dof_index) const
Definition: dof_map.h:831

◆ add_periodic_boundary() [1/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 5566 of file dof_map_constraints.C.

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(), main(), and PeriodicBCTest::testPeriodicBC().

5567 {
5568  // See if we already have a periodic boundary associated myboundary...
5569  PeriodicBoundaryBase * existing_boundary = _periodic_boundaries->boundary(periodic_boundary.myboundary);
5570 
5571  if (!existing_boundary)
5572  {
5573  // ...if not, clone the input (and its inverse) and add them to the PeriodicBoundaries object
5574  // Pass the pairedboundary of the original as the boundary id of the inverse clone.
5575  _periodic_boundaries->emplace(periodic_boundary.myboundary, periodic_boundary.clone());
5576  _periodic_boundaries->emplace(periodic_boundary.pairedboundary, periodic_boundary.clone(PeriodicBoundaryBase::INVERSE));
5577  }
5578  else
5579  {
5580  // ...otherwise, merge this object's variable IDs with the existing boundary object's.
5581  existing_boundary->merge(periodic_boundary);
5582 
5583  // Do the same merging process for the inverse boundary. Note: the inverse better already exist!
5584  PeriodicBoundaryBase * inverse_boundary = _periodic_boundaries->boundary(periodic_boundary.pairedboundary);
5585  libmesh_assert(inverse_boundary);
5586  inverse_boundary->merge(periodic_boundary);
5587  }
5588 }
void merge(const PeriodicBoundaryBase &pb)
boundary_id_type myboundary
The boundary ID of this boundary and its counterpart.
libmesh_assert(ctx)
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...
std::unique_ptr< PeriodicBoundaries > _periodic_boundaries
Data structure containing periodic boundaries.
Definition: dof_map.h:2053
The base class for defining periodic boundaries.

◆ add_periodic_boundary() [2/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 5593 of file dof_map_constraints.C.

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

5595 {
5596  libmesh_assert_equal_to (boundary.myboundary, inverse_boundary.pairedboundary);
5597  libmesh_assert_equal_to (boundary.pairedboundary, inverse_boundary.myboundary);
5598 
5599  // Store clones of the passed-in objects. These will be cleaned up
5600  // automatically in the _periodic_boundaries destructor.
5601  _periodic_boundaries->emplace(boundary.myboundary, boundary.clone());
5602  _periodic_boundaries->emplace(inverse_boundary.myboundary, inverse_boundary.clone());
5603 }
boundary_id_type myboundary
The boundary ID of this boundary and its counterpart.
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...
std::unique_ptr< PeriodicBoundaries > _periodic_boundaries
Data structure containing periodic boundaries.
Definition: dof_map.h:2053

◆ add_variable_group()

void libMesh::DofMap::add_variable_group ( VariableGroup  var_group)

Add an unknown of order order and finite element type type to the system of equations.

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

Definition at line 252 of file dof_map.C.

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

253 {
254  // Ensure that we are not duplicating an existing entry in _variable_groups
255  if (std::find(_variable_groups.begin(), _variable_groups.end(), var_group) == _variable_groups.end())
256  {
257  const unsigned int vg = cast_int<unsigned int>(_variable_groups.size());
258 
259  _variable_groups.push_back(std::move(var_group));
260 
261  VariableGroup & new_var_group = _variable_groups.back();
262 
263  for (auto var : make_range(new_var_group.n_variables()))
264  {
265  auto var_instance = new_var_group(var);
266  const auto vn = var_instance.number();
267  _variables.push_back (std::move(var_instance));
268  _variable_group_numbers.push_back (vg);
269  _var_to_vg.emplace(vn, vg);
270  }
271  }
272  // End if check for var_group in _variable_groups
273 
274 }
std::vector< VariableGroup > _variable_groups
The finite element type for each variable group.
Definition: dof_map.h:1847
std::unordered_map< unsigned int, unsigned int > _var_to_vg
A map from variable number to variable group number.
Definition: dof_map.h:1857
std::vector< Variable > _variables
The finite element type for each variable.
Definition: dof_map.h:1842
IntRange< T > make_range(T beg, T end)
The 2-parameter make_range() helper function returns an IntRange<T> when both input parameters are of...
Definition: int_range.h:134
std::vector< unsigned int > _variable_group_numbers
The variable group number for each variable.
Definition: dof_map.h:1852

◆ 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 406 of file dof_map.h.

References _algebraic_ghosting_functors.

Referenced by add_neighbors_to_send_list().

407  { return _algebraic_ghosting_functors.begin(); }
std::set< GhostingFunctor * > _algebraic_ghosting_functors
The list of all GhostingFunctor objects to be used when distributing ghosted vectors.
Definition: dof_map.h:1954

◆ 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 412 of file dof_map.h.

References _algebraic_ghosting_functors.

Referenced by add_neighbors_to_send_list().

413  { return _algebraic_ghosting_functors.end(); }
std::set< GhostingFunctor * > _algebraic_ghosting_functors
The list of all GhostingFunctor objects to be used when distributing ghosted vectors.
Definition: dof_map.h:1954

◆ 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 2596 of file dof_map.C.

References semilocal_index().

Referenced by is_evaluable().

2597 {
2598  // We're all semilocal unless we find a counterexample
2599  for (const auto & di : dof_indices_in)
2600  if (!this->semilocal_index(di))
2601  return false;
2602 
2603  return true;
2604 }
bool semilocal_index(dof_id_type dof_index) const
Definition: dof_map.C:2580

◆ allgather_recursive_constraints()

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

Gathers constraint equation dependencies from other processors.

Definition at line 3704 of file dof_map_constraints.C.

References _adjoint_constraint_values, _dof_constraints, _node_constraints, _primal_constraint_values, libMesh::as_range(), libMesh::ParallelObject::comm(), libMesh::DofObject::dof_number(), gather_constraints(), TIMPI::Communicator::get_unique_tag(), 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(), TIMPI::Communicator::max(), mesh, libMesh::DofObject::n_comp(), n_nodes, libMesh::Elem::n_nodes(), libMesh::ParallelObject::n_processors(), n_vars, libMesh::DofObject::n_vars(), libMesh::Elem::node_id(), libMesh::Elem::node_ptr(), libMesh::MeshBase::node_ptr(), libMesh::Elem::node_ref(), libMesh::ParallelObject::processor_id(), libMesh::DofObject::processor_id(), libMesh::Real, TIMPI::Communicator::receive_packed_range(), TIMPI::Communicator::send_packed_range(), and sys_number().

Referenced by process_constraints().

3705 {
3706  // This function must be run on all processors at once
3707  parallel_object_only();
3708 
3709  // Return immediately if there's nothing to gather
3710  if (this->n_processors() == 1)
3711  return;
3712 
3713  // We might get to return immediately if none of the processors
3714  // found any constraints
3715  unsigned int has_constraints = !_dof_constraints.empty()
3716 #ifdef LIBMESH_ENABLE_NODE_CONSTRAINTS
3717  || !_node_constraints.empty()
3718 #endif // LIBMESH_ENABLE_NODE_CONSTRAINTS
3719  ;
3720  this->comm().max(has_constraints);
3721  if (!has_constraints)
3722  return;
3723 
3724  // If we have heterogeneous adjoint constraints we need to
3725  // communicate those too.
3726  const unsigned int max_qoi_num =
3727  _adjoint_constraint_values.empty() ?
3728  0 : _adjoint_constraint_values.rbegin()->first+1;
3729 
3730 #ifdef LIBMESH_ENABLE_NODE_CONSTRAINTS
3731  // We may need to send nodes ahead of data about them
3732  std::vector<Parallel::Request> packed_range_sends;
3733 
3734  // We may be receiving packed_range sends out of order with
3735  // parallel_sync tags, so make sure they're received correctly.
3736  Parallel::MessageTag range_tag = this->comm().get_unique_tag();
3737 
3738  // We only need to do these sends on a distributed mesh
3739  const bool dist_mesh = !mesh.is_serial();
3740 #endif
3741 
3742  // We might have calculated constraints for constrained dofs
3743  // which have support on other processors.
3744  // Push these out first.
3745  {
3746  std::map<processor_id_type, std::set<dof_id_type>> pushed_ids;
3747 
3748 #ifdef LIBMESH_ENABLE_NODE_CONSTRAINTS
3749  std::map<processor_id_type, std::set<dof_id_type>> pushed_node_ids;
3750 #endif
3751 
3752  const unsigned int sys_num = this->sys_number();
3753 
3754  // Collect the constraints to push to each processor
3755  for (auto & elem : as_range(mesh.active_not_local_elements_begin(),
3756  mesh.active_not_local_elements_end()))
3757  {
3758  const unsigned short n_nodes = elem->n_nodes();
3759 
3760  // Just checking dof_indices on the foreign element isn't
3761  // enough. Consider a central hanging node between a coarse
3762  // Q2/Q1 element and its finer neighbors on a higher-ranked
3763  // processor. The coarse element's processor will own the node,
3764  // and will thereby own the pressure dof on that node, despite
3765  // the fact that that pressure dof doesn't directly exist on the
3766  // coarse element!
3767  //
3768  // So, we loop through dofs manually.
3769 
3770  {
3771  const unsigned int n_vars = elem->n_vars(sys_num);
3772  for (unsigned int v=0; v != n_vars; ++v)
3773  {
3774  const unsigned int n_comp = elem->n_comp(sys_num,v);
3775  for (unsigned int c=0; c != n_comp; ++c)
3776  {
3777  const unsigned int id =
3778  elem->dof_number(sys_num,v,c);
3779  if (this->is_constrained_dof(id))
3780  pushed_ids[elem->processor_id()].insert(id);
3781  }
3782  }
3783  }
3784 
3785  for (unsigned short n = 0; n != n_nodes; ++n)
3786  {
3787  const Node & node = elem->node_ref(n);
3788  const unsigned int n_vars = node.n_vars(sys_num);
3789  for (unsigned int v=0; v != n_vars; ++v)
3790  {
3791  const unsigned int n_comp = node.n_comp(sys_num,v);
3792  for (unsigned int c=0; c != n_comp; ++c)
3793  {
3794  const unsigned int id =
3795  node.dof_number(sys_num,v,c);
3796  if (this->is_constrained_dof(id))
3797  pushed_ids[elem->processor_id()].insert(id);
3798  }
3799  }
3800  }
3801 
3802 #ifdef LIBMESH_ENABLE_NODE_CONSTRAINTS
3803  for (unsigned short n = 0; n != n_nodes; ++n)
3804  if (this->is_constrained_node(elem->node_ptr(n)))
3805  pushed_node_ids[elem->processor_id()].insert(elem->node_id(n));
3806 #endif
3807  }
3808 
3809  // Rewrite those id sets as vectors for sending and receiving,
3810  // then find the corresponding data for each id, then push it all.
3811  std::map<processor_id_type, std::vector<dof_id_type>>
3812  pushed_id_vecs, received_id_vecs;
3813  for (auto & p : pushed_ids)
3814  pushed_id_vecs[p.first].assign(p.second.begin(), p.second.end());
3815 
3816  std::map<processor_id_type, std::vector<std::vector<std::pair<dof_id_type,Real>>>>
3817  pushed_keys_vals, received_keys_vals;
3818  std::map<processor_id_type, std::vector<std::vector<Number>>> pushed_rhss, received_rhss;
3819  for (auto & p : pushed_id_vecs)
3820  {
3821  auto & keys_vals = pushed_keys_vals[p.first];
3822  keys_vals.reserve(p.second.size());
3823 
3824  auto & rhss = pushed_rhss[p.first];
3825  rhss.reserve(p.second.size());
3826  for (auto & pushed_id : p.second)
3827  {
3828  const DofConstraintRow & row = _dof_constraints[pushed_id];
3829  keys_vals.emplace_back(row.begin(), row.end());
3830 
3831  rhss.push_back(std::vector<Number>(max_qoi_num+1));
3832  std::vector<Number> & rhs = rhss.back();
3833  DofConstraintValueMap::const_iterator rhsit =
3834  _primal_constraint_values.find(pushed_id);
3835  rhs[max_qoi_num] =
3836  (rhsit == _primal_constraint_values.end()) ?
3837  0 : rhsit->second;
3838  for (unsigned int q = 0; q != max_qoi_num; ++q)
3839  {
3840  AdjointDofConstraintValues::const_iterator adjoint_map_it =
3842 
3843  if (adjoint_map_it == _adjoint_constraint_values.end())
3844  continue;
3845 
3846  const DofConstraintValueMap & constraint_map =
3847  adjoint_map_it->second;
3848 
3849  DofConstraintValueMap::const_iterator adj_rhsit =
3850  constraint_map.find(pushed_id);
3851 
3852  rhs[q] =
3853  (adj_rhsit == constraint_map.end()) ?
3854  0 : adj_rhsit->second;
3855  }
3856  }
3857  }
3858 
3859  auto ids_action_functor =
3860  [& received_id_vecs]
3861  (processor_id_type pid,
3862  const std::vector<dof_id_type> & data)
3863  {
3864  received_id_vecs[pid] = data;
3865  };
3866 
3867  Parallel::push_parallel_vector_data
3868  (this->comm(), pushed_id_vecs, ids_action_functor);
3869 
3870  auto keys_vals_action_functor =
3871  [& received_keys_vals]
3872  (processor_id_type pid,
3873  const std::vector<std::vector<std::pair<dof_id_type,Real>>> & data)
3874  {
3875  received_keys_vals[pid] = data;
3876  };
3877 
3878  Parallel::push_parallel_vector_data
3879  (this->comm(), pushed_keys_vals, keys_vals_action_functor);
3880 
3881  auto rhss_action_functor =
3882  [& received_rhss]
3883  (processor_id_type pid,
3884  const std::vector<std::vector<Number>> & data)
3885  {
3886  received_rhss[pid] = data;
3887  };
3888 
3889  Parallel::push_parallel_vector_data
3890  (this->comm(), pushed_rhss, rhss_action_functor);
3891 
3892  // Now we have all the DofConstraint rows and rhs values received
3893  // from others, so add the DoF constraints that we've been sent
3894 
3895 #ifdef LIBMESH_ENABLE_NODE_CONSTRAINTS
3896  std::map<processor_id_type, std::vector<dof_id_type>>
3897  pushed_node_id_vecs, received_node_id_vecs;
3898  for (auto & p : pushed_node_ids)
3899  pushed_node_id_vecs[p.first].assign(p.second.begin(), p.second.end());
3900 
3901  std::map<processor_id_type, std::vector<std::vector<std::pair<dof_id_type,Real>>>>
3902  pushed_node_keys_vals, received_node_keys_vals;
3903  std::map<processor_id_type, std::vector<Point>> pushed_offsets, received_offsets;
3904 
3905  for (auto & p : pushed_node_id_vecs)
3906  {
3907  const processor_id_type pid = p.first;
3908 
3909  // FIXME - this could be an unordered set, given a
3910  // hash<pointers> specialization
3911  std::set<const Node *> nodes_requested;
3912 
3913  auto & node_keys_vals = pushed_node_keys_vals[pid];
3914  node_keys_vals.reserve(p.second.size());
3915 
3916  auto & offsets = pushed_offsets[pid];
3917  offsets.reserve(p.second.size());
3918 
3919  for (auto & pushed_node_id : p.second)
3920  {
3921  const Node * node = mesh.node_ptr(pushed_node_id);
3922  NodeConstraintRow & row = _node_constraints[node].first;
3923  const std::size_t row_size = row.size();
3924  node_keys_vals.push_back
3925  (std::vector<std::pair<dof_id_type,Real>>());
3926  std::vector<std::pair<dof_id_type,Real>> & this_node_kv =
3927  node_keys_vals.back();
3928  this_node_kv.reserve(row_size);
3929  for (const auto & j : row)
3930  {
3931  this_node_kv.emplace_back(j.first->id(), j.second);
3932 
3933  // If we're not sure whether our send
3934  // destination already has this node, let's give
3935  // it a copy.
3936  if (j.first->processor_id() != pid && dist_mesh)
3937  nodes_requested.insert(j.first);
3938  }
3939 
3940  offsets.push_back(_node_constraints[node].second);
3941 
3942  }
3943 
3944  // Constraining nodes might not even exist on our
3945  // correspondant's subset of a distributed mesh, so let's
3946  // make them exist.
3947  if (dist_mesh)
3948  {
3949  packed_range_sends.push_back(Parallel::Request());
3950  this->comm().send_packed_range
3951  (pid, &mesh, nodes_requested.begin(), nodes_requested.end(),
3952  packed_range_sends.back(), range_tag);
3953  }
3954  }
3955 
3956  auto node_ids_action_functor =
3957  [& received_node_id_vecs]
3958  (processor_id_type pid,
3959  const std::vector<dof_id_type> & data)
3960  {
3961  received_node_id_vecs[pid] = data;
3962  };
3963 
3964  Parallel::push_parallel_vector_data
3965  (this->comm(), pushed_node_id_vecs, node_ids_action_functor);
3966 
3967  auto node_keys_vals_action_functor =
3968  [& received_node_keys_vals]
3969  (processor_id_type pid,
3970  const std::vector<std::vector<std::pair<dof_id_type,Real>>> & data)
3971  {
3972  received_node_keys_vals[pid] = data;
3973  };
3974 
3975  Parallel::push_parallel_vector_data
3976  (this->comm(), pushed_node_keys_vals,
3977  node_keys_vals_action_functor);
3978 
3979  auto node_offsets_action_functor =
3980  [& received_offsets]
3981  (processor_id_type pid,
3982  const std::vector<Point> & data)
3983  {
3984  received_offsets[pid] = data;
3985  };
3986 
3987  Parallel::push_parallel_vector_data
3988  (this->comm(), pushed_offsets, node_offsets_action_functor);
3989 
3990 #endif
3991 
3992  // Add all the dof constraints that I've been sent
3993  for (auto & [pid, pushed_ids_to_me] : received_id_vecs)
3994  {
3995  libmesh_assert(received_keys_vals.count(pid));
3996  libmesh_assert(received_rhss.count(pid));
3997  const auto & pushed_keys_vals_to_me = received_keys_vals.at(pid);
3998  const auto & pushed_rhss_to_me = received_rhss.at(pid);
3999 
4000  libmesh_assert_equal_to (pushed_ids_to_me.size(),
4001  pushed_keys_vals_to_me.size());
4002  libmesh_assert_equal_to (pushed_ids_to_me.size(),
4003  pushed_rhss_to_me.size());
4004 
4005  for (auto i : index_range(pushed_ids_to_me))
4006  {
4007  dof_id_type constrained = pushed_ids_to_me[i];
4008 
4009  // If we don't already have a constraint for this dof,
4010  // add the one we were sent
4011  if (!this->is_constrained_dof(constrained))
4012  {
4013  DofConstraintRow & row = _dof_constraints[constrained];
4014  for (auto & kv : pushed_keys_vals_to_me[i])
4015  {
4016  libmesh_assert_less(kv.first, this->n_dofs());
4017  row[kv.first] = kv.second;
4018  }
4019 
4020  const Number primal_rhs = pushed_rhss_to_me[i][max_qoi_num];
4021 
4022  if (libmesh_isnan(primal_rhs))
4023  libmesh_assert(pushed_keys_vals_to_me[i].empty());
4024 
4025  if (primal_rhs != Number(0))
4026  _primal_constraint_values[constrained] = primal_rhs;
4027  else
4028  _primal_constraint_values.erase(constrained);
4029 
4030  for (unsigned int q = 0; q != max_qoi_num; ++q)
4031  {
4032  AdjointDofConstraintValues::iterator adjoint_map_it =
4034 
4035  const Number adj_rhs = pushed_rhss_to_me[i][q];
4036 
4037  if ((adjoint_map_it == _adjoint_constraint_values.end()) &&
4038  adj_rhs == Number(0))
4039  continue;
4040 
4041  if (adjoint_map_it == _adjoint_constraint_values.end())
4042  adjoint_map_it = _adjoint_constraint_values.emplace
4043  (q, DofConstraintValueMap()).first;
4044 
4045  DofConstraintValueMap & constraint_map =
4046  adjoint_map_it->second;
4047 
4048  if (adj_rhs != Number(0))
4049  constraint_map[constrained] = adj_rhs;
4050  else
4051  constraint_map.erase(constrained);
4052  }
4053  }
4054  }
4055  }
4056 
4057 #ifdef LIBMESH_ENABLE_NODE_CONSTRAINTS
4058  // Add all the node constraints that I've been sent
4059  for (auto & [pid, pushed_node_ids_to_me] : received_node_id_vecs)
4060  {
4061  // Before we act on any new constraint rows, we may need to
4062  // make sure we have all the nodes involved!
4063  if (dist_mesh)
4064  this->comm().receive_packed_range
4065  (pid, &mesh, null_output_iterator<Node>(),
4066  (Node**)nullptr, range_tag);
4067 
4068  libmesh_assert(received_node_keys_vals.count(pid));
4069  libmesh_assert(received_offsets.count(pid));
4070  const auto & pushed_node_keys_vals_to_me = received_node_keys_vals.at(pid);
4071  const auto & pushed_offsets_to_me = received_offsets.at(pid);
4072 
4073  libmesh_assert_equal_to (pushed_node_ids_to_me.size(),
4074  pushed_node_keys_vals_to_me.size());
4075  libmesh_assert_equal_to (pushed_node_ids_to_me.size(),
4076  pushed_offsets_to_me.size());
4077 
4078  for (auto i : index_range(pushed_node_ids_to_me))
4079  {
4080  dof_id_type constrained_id = pushed_node_ids_to_me[i];
4081 
4082  // If we don't already have a constraint for this node,
4083  // add the one we were sent
4084  const Node * constrained = mesh.node_ptr(constrained_id);
4085  if (!this->is_constrained_node(constrained))
4086  {
4087  NodeConstraintRow & row = _node_constraints[constrained].first;
4088  for (auto & kv : pushed_node_keys_vals_to_me[i])
4089  {
4090  const Node * key_node = mesh.node_ptr(kv.first);
4091  libmesh_assert(key_node);
4092  row[key_node] = kv.second;
4093  }
4094  _node_constraints[constrained].second = pushed_offsets_to_me[i];
4095  }
4096  }
4097  }
4098 #endif // LIBMESH_ENABLE_NODE_CONSTRAINTS
4099  }
4100 
4101  // Now start checking for any other constraints we need
4102  // to know about, requesting them recursively.
4103 
4104  // Create sets containing the DOFs and nodes we already depend on
4105  typedef std::set<dof_id_type> DoF_RCSet;
4106  DoF_RCSet unexpanded_dofs;
4107 
4108  for (const auto & i : _dof_constraints)
4109  unexpanded_dofs.insert(i.first);
4110 
4111  // Gather all the dof constraints we need
4112  this->gather_constraints(mesh, unexpanded_dofs, false);
4113 
4114  // Gather all the node constraints we need
4115 #ifdef LIBMESH_ENABLE_NODE_CONSTRAINTS
4116  typedef std::set<const Node *> Node_RCSet;
4117  Node_RCSet unexpanded_nodes;
4118 
4119  for (const auto & i : _node_constraints)
4120  unexpanded_nodes.insert(i.first);
4121 
4122  // We have to keep recursing while the unexpanded set is
4123  // nonempty on *any* processor
4124  bool unexpanded_set_nonempty = !unexpanded_nodes.empty();
4125  this->comm().max(unexpanded_set_nonempty);
4126 
4127  while (unexpanded_set_nonempty)
4128  {
4129  // Let's make sure we don't lose sync in this loop.
4130  parallel_object_only();
4131 
4132  // Request sets
4133  Node_RCSet node_request_set;
4134 
4135  // Request sets to send to each processor
4136  std::map<processor_id_type, std::vector<dof_id_type>>
4137  requested_node_ids;
4138 
4139  // And the sizes of each
4140  std::map<processor_id_type, dof_id_type> node_ids_on_proc;
4141 
4142  // Fill (and thereby sort and uniq!) the main request sets
4143  for (const auto & i : unexpanded_nodes)
4144  {
4145  NodeConstraintRow & row = _node_constraints[i].first;
4146  for (const auto & j : row)
4147  {
4148  const Node * const node = j.first;
4149  libmesh_assert(node);
4150 
4151  // If it's non-local and we haven't already got a
4152  // constraint for it, we might need to ask for one
4153  if ((node->processor_id() != this->processor_id()) &&
4154  !_node_constraints.count(node))
4155  node_request_set.insert(node);
4156  }
4157  }
4158 
4159  // Clear the unexpanded constraint sets; we're about to expand
4160  // them
4161  unexpanded_nodes.clear();
4162 
4163  // Count requests by processor
4164  for (const auto & node : node_request_set)
4165  {
4166  libmesh_assert(node);
4167  libmesh_assert_less (node->processor_id(), this->n_processors());
4168  node_ids_on_proc[node->processor_id()]++;
4169  }
4170 
4171  for (auto pair : node_ids_on_proc)
4172  requested_node_ids[pair.first].reserve(pair.second);
4173 
4174  // Prepare each processor's request set
4175  for (const auto & node : node_request_set)
4176  requested_node_ids[node->processor_id()].push_back(node->id());
4177 
4178  typedef std::vector<std::pair<dof_id_type, Real>> row_datum;
4179 
4180  auto node_row_gather_functor =
4181  [this,
4182  & mesh,
4183  dist_mesh,
4184  & packed_range_sends,
4185  & range_tag]
4186  (processor_id_type pid,
4187  const std::vector<dof_id_type> & ids,
4188  std::vector<row_datum> & data)
4189  {
4190  // FIXME - this could be an unordered set, given a
4191  // hash<pointers> specialization
4192  std::set<const Node *> nodes_requested;
4193 
4194  // Fill those requests
4195  const std::size_t query_size = ids.size();
4196 
4197  data.resize(query_size);
4198  for (std::size_t i=0; i != query_size; ++i)
4199  {
4200  dof_id_type constrained_id = ids[i];
4201  const Node * constrained_node = mesh.node_ptr(constrained_id);
4202  if (_node_constraints.count(constrained_node))
4203  {
4204  const NodeConstraintRow & row = _node_constraints[constrained_node].first;
4205  std::size_t row_size = row.size();
4206  data[i].reserve(row_size);
4207  for (const auto & j : row)
4208  {
4209  const Node * node = j.first;
4210  data[i].emplace_back(node->id(), j.second);
4211 
4212  // If we're not sure whether our send
4213  // destination already has this node, let's give
4214  // it a copy.
4215  if (node->processor_id() != pid && dist_mesh)
4216  nodes_requested.insert(node);
4217 
4218  // We can have 0 nodal constraint
4219  // coefficients, where no Lagrange constraint
4220  // exists but non-Lagrange basis constraints
4221  // might.
4222  // libmesh_assert(j.second);
4223  }
4224  }
4225  else
4226  {
4227  // We have to distinguish "constraint with no
4228  // constraining nodes" (e.g. due to user node
4229  // constraint equations) from "no constraint".
4230  // We'll use invalid_id for the latter.
4231  data[i].emplace_back(DofObject::invalid_id, Real(0));
4232  }
4233  }
4234 
4235  // Constraining nodes might not even exist on our
4236  // correspondant's subset of a distributed mesh, so let's
4237  // make them exist.
4238  if (dist_mesh)
4239  {
4240  packed_range_sends.push_back(Parallel::Request());
4241  this->comm().send_packed_range
4242  (pid, &mesh, nodes_requested.begin(), nodes_requested.end(),
4243  packed_range_sends.back(), range_tag);
4244  }
4245  };
4246 
4247  typedef Point node_rhs_datum;
4248 
4249  auto node_rhs_gather_functor =
4250  [this,
4251  & mesh]
4253  const std::vector<dof_id_type> & ids,
4254  std::vector<node_rhs_datum> & data)
4255  {
4256  // Fill those requests
4257  const std::size_t query_size = ids.size();
4258 
4259  data.resize(query_size);
4260  for (std::size_t i=0; i != query_size; ++i)
4261  {
4262  dof_id_type constrained_id = ids[i];
4263  const Node * constrained_node = mesh.node_ptr(constrained_id);
4264  if (_node_constraints.count(constrained_node))
4265  data[i] = _node_constraints[constrained_node].second;
4266  else
4267  data[i](0) = std::numeric_limits<Real>::quiet_NaN();
4268  }
4269  };
4270 
4271  auto node_row_action_functor =
4272  [this,
4273  & mesh,
4274  dist_mesh,
4275  & range_tag,
4276  & unexpanded_nodes]
4277  (processor_id_type pid,
4278  const std::vector<dof_id_type> & ids,
4279  const std::vector<row_datum> & data)
4280  {
4281  // Before we act on any new constraint rows, we may need to
4282  // make sure we have all the nodes involved!
4283  if (dist_mesh)
4284  this->comm().receive_packed_range
4285  (pid, &mesh, null_output_iterator<Node>(),
4286  (Node**)nullptr, range_tag);
4287 
4288  // Add any new constraint rows we've found
4289  const std::size_t query_size = ids.size();
4290 
4291  for (std::size_t i=0; i != query_size; ++i)
4292  {
4293  const dof_id_type constrained_id = ids[i];
4294 
4295  // An empty row is an constraint with an empty row; for
4296  // no constraint we use a "no row" placeholder
4297  if (data[i].empty())
4298  {
4299  const Node * constrained_node = mesh.node_ptr(constrained_id);
4300  NodeConstraintRow & row = _node_constraints[constrained_node].first;
4301  row.clear();
4302  }
4303  else if (data[i][0].first != DofObject::invalid_id)
4304  {
4305  const Node * constrained_node = mesh.node_ptr(constrained_id);
4306  NodeConstraintRow & row = _node_constraints[constrained_node].first;
4307  row.clear();
4308  for (auto & pair : data[i])
4309  {
4310  const Node * key_node =
4311  mesh.node_ptr(pair.first);
4312  libmesh_assert(key_node);
4313  row[key_node] = pair.second;
4314  }
4315 
4316  // And prepare to check for more recursive constraints
4317  unexpanded_nodes.insert(constrained_node);
4318  }
4319  }
4320  };
4321 
4322  auto node_rhs_action_functor =
4323  [this,
4324  & mesh]
4326  const std::vector<dof_id_type> & ids,
4327  const std::vector<node_rhs_datum> & data)
4328  {
4329  // Add rhs data for any new node constraint rows we've found
4330  const std::size_t query_size = ids.size();
4331 
4332  for (std::size_t i=0; i != query_size; ++i)
4333  {
4334  dof_id_type constrained_id = ids[i];
4335  const Node * constrained_node = mesh.node_ptr(constrained_id);
4336 
4337  if (!libmesh_isnan(data[i](0)))
4338  _node_constraints[constrained_node].second = data[i];
4339  else
4340  _node_constraints.erase(constrained_node);
4341  }
4342  };
4343 
4344  // Now request node constraint rows from other processors
4345  row_datum * node_row_ex = nullptr;
4346  Parallel::pull_parallel_vector_data
4347  (this->comm(), requested_node_ids, node_row_gather_functor,
4348  node_row_action_functor, node_row_ex);
4349 
4350  // And request node constraint right hand sides from other procesors
4351  node_rhs_datum * node_rhs_ex = nullptr;
4352  Parallel::pull_parallel_vector_data
4353  (this->comm(), requested_node_ids, node_rhs_gather_functor,
4354  node_rhs_action_functor, node_rhs_ex);
4355 
4356 
4357  // We have to keep recursing while the unexpanded set is
4358  // nonempty on *any* processor
4359  unexpanded_set_nonempty = !unexpanded_nodes.empty();
4360  this->comm().max(unexpanded_set_nonempty);
4361  }
4362  Parallel::wait(packed_range_sends);
4363 #endif // LIBMESH_ENABLE_NODE_CONSTRAINTS
4364 }
bool is_constrained_node(const Node *node) const
Definition: dof_map.h:2166
dof_id_type dof_number(const unsigned int s, const unsigned int var, const unsigned int comp) const
Definition: dof_object.h:1025
A Node is like a Point, but with more information.
Definition: node.h:52
unsigned int n_comp(const unsigned int s, const unsigned int var) const
Definition: dof_object.h:995
MessageTag get_unique_tag(int tagvalue=MessageTag::invalid_tag) const
MeshBase & mesh
void gather_constraints(MeshBase &mesh, std::set< dof_id_type > &unexpanded_dofs, bool look_for_constrainees)
Helper function for querying about constraint equations on other processors.
const Parallel::Communicator & comm() const
bool libmesh_isnan(T x)
void send_packed_range(const unsigned int dest_processor_id, const Context *context, Iter range_begin, const Iter range_end, const MessageTag &tag=no_tag, std::size_t approx_buffer_size=1000000) const
unsigned int sys_number() const
Definition: dof_map.h:2096
uint8_t processor_id_type
Definition: id_types.h:104
AdjointDofConstraintValues _adjoint_constraint_values
Definition: dof_map.h:2037
uint8_t processor_id_type
processor_id_type n_processors() const
virtual bool is_serial() const
Definition: mesh_base.h:205
const dof_id_type n_nodes
Definition: tecplot_io.C:67
dof_id_type id() const
Definition: dof_object.h:823
unsigned int n_vars
void receive_packed_range(const unsigned int dest_processor_id, Context *context, OutputIter out, const T *output_type, const MessageTag &tag=any_tag) const
unsigned int n_vars(const unsigned int s, const unsigned int vg) const
Definition: dof_object.h:960
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_assert(ctx)
bool is_constrained_dof(const dof_id_type dof) const
Definition: dof_map.h:2182
static const dof_id_type invalid_id
An invalid id to distinguish an uninitialized DofObject.
Definition: dof_object.h:477
DofConstraints _dof_constraints
Data structure containing DOF constraints.
Definition: dof_map.h:2033
A do-nothing class for templated methods that expect output iterator arguments.
Storage for DofConstraint right hand sides for a particular problem.
Definition: dof_map.h:110
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
void max(const T &r, T &o, Request &req) const
DofConstraintValueMap _primal_constraint_values
Definition: dof_map.h:2035
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:90
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:138
virtual const Node * node_ptr(const dof_id_type i) const =0
processor_id_type processor_id() const
processor_id_type processor_id() const
Definition: dof_object.h:898
A Point defines a location in LIBMESH_DIM dimensional Real space.
Definition: point.h:39
auto index_range(const T &sizable)
Helper function that returns an IntRange<std::size_t> representing all the indices of the passed-in v...
Definition: int_range.h:111
uint8_t dof_id_type
Definition: id_types.h:67
NodeConstraints _node_constraints
Data structure containing DofObject constraints.
Definition: dof_map.h:2044

◆ assert_no_nodes_missed()

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

Definition at line 1418 of file dof_map.C.

References libMesh::DofObject::invalid_id, mesh, and sys_number().

Referenced by distribute_local_dofs_node_major(), and distribute_local_dofs_var_major().

1419 {
1420  MeshTools::libmesh_assert_valid_procids<Node>(mesh);
1421 
1422  for (auto & node : mesh.local_node_ptr_range())
1423  {
1424  unsigned int n_var_g = node->n_var_groups(this->sys_number());
1425  for (unsigned int vg=0; vg != n_var_g; ++vg)
1426  {
1427  unsigned int n_comp_g =
1428  node->n_comp_group(this->sys_number(), vg);
1429  dof_id_type my_first_dof = n_comp_g ?
1430  node->vg_dof_base(this->sys_number(), vg) : 0;
1431  libmesh_assert_not_equal_to (my_first_dof, DofObject::invalid_id);
1432  }
1433  }
1434 }
MeshBase & mesh
unsigned int sys_number() const
Definition: dof_map.h:2096
static const dof_id_type invalid_id
An invalid id to distinguish an uninitialized DofObject.
Definition: dof_object.h:477
uint8_t dof_id_type
Definition: id_types.h:67

◆ 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 468 of file dof_map.h.

References _extra_send_list_context, and _extra_send_list_function.

void * _extra_send_list_context
A pointer associated with the extra send list that can optionally be passed in.
Definition: dof_map.h:1928
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:1923

◆ 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 459 of file dof_map.h.

References _augment_send_list.

460  {
461  _augment_send_list = &asl;
462  }
AugmentSendList * _augment_send_list
Function object to call to add extra entries to the send list.
Definition: dof_map.h:1918

◆ 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 445 of file dof_map.h.

References _extra_sparsity_context, and _extra_sparsity_function.

void * _extra_sparsity_context
A pointer associated with the extra sparsity that can optionally be passed in.
Definition: dof_map.h:1913
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:1906

◆ attach_extra_sparsity_object()

void libMesh::DofMap::attach_extra_sparsity_object ( SparsityPattern::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 430 of file dof_map.h.

References _augment_sparsity_pattern.

431  {
433  }
SparsityPattern::AugmentSparsityPattern * _augment_sparsity_pattern
Function object to call to add extra entries to the sparsity pattern.
Definition: dof_map.h:1901

◆ attach_matrix()

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

Additional matrices may be attached to this DofMap.

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

Definition at line 278 of file dof_map.C.

References _matrices, libMesh::libmesh_assert(), libMesh::SparseMatrix< T >::need_full_sparsity_pattern(), need_full_sparsity_pattern, and update_sparsity_pattern().

Referenced by libMesh::TransientRBConstruction::allocate_data_structures(), libMesh::RBConstruction::allocate_data_structures(), libMesh::System::init_matrices(), and libMesh::System::late_matrix_init().

279 {
280  parallel_object_only();
281 
282  // We shouldn't be trying to re-attach the same matrices repeatedly
283  libmesh_assert (std::find(_matrices.begin(), _matrices.end(),
284  &matrix) == _matrices.end());
285 
286  _matrices.push_back(&matrix);
287 
288  this->update_sparsity_pattern(matrix);
289 
290  if (matrix.need_full_sparsity_pattern())
292 }
bool need_full_sparsity_pattern
Default false; set to true if any attached matrix requires a full sparsity pattern.
Definition: dof_map.h:1979
libmesh_assert(ctx)
void update_sparsity_pattern(SparseMatrix< Number > &matrix) const
Additional matrices may be be temporarily initialized by this DofMap.
Definition: dof_map.C:307
std::vector< SparseMatrix< Number > *> _matrices
Additional matrices handled by this object.
Definition: dof_map.h:1874
virtual bool need_full_sparsity_pattern() const

◆ 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 without involving any user efforts.

Definition at line 651 of file dof_map.h.

References has_blocked_representation(), and n_variables().

652  {
653  return (this->has_blocked_representation() ? this->n_variables() : 1);
654  }
unsigned int n_variables() const
Definition: dof_map.h:621
bool has_blocked_representation() const
Definition: dof_map.h:634

◆ 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 3455 of file dof_map_constraints.C.

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().

3458 {
3459  LOG_SCOPE_IF("build_constraint_matrix()", "DofMap", !called_recursively);
3460 
3461  // Create a set containing the DOFs we already depend on
3462  typedef std::set<dof_id_type> RCSet;
3463  RCSet dof_set;
3464 
3465  bool we_have_constraints = false;
3466 
3467  // Next insert any other dofs the current dofs might be constrained
3468  // in terms of. Note that in this case we may not be done: Those
3469  // may in turn depend on others. So, we need to repeat this process
3470  // in that case until the system depends only on unconstrained
3471  // degrees of freedom.
3472  for (const auto & dof : elem_dofs)
3473  if (this->is_constrained_dof(dof))
3474  {
3475  we_have_constraints = true;
3476 
3477  // If the DOF is constrained
3478  DofConstraints::const_iterator
3479  pos = _dof_constraints.find(dof);
3480 
3481  libmesh_assert (pos != _dof_constraints.end());
3482 
3483  const DofConstraintRow & constraint_row = pos->second;
3484 
3485  // Constraint rows in p refinement may be empty
3486  //libmesh_assert (!constraint_row.empty());
3487 
3488  for (const auto & item : constraint_row)
3489  dof_set.insert (item.first);
3490  }
3491 
3492  // May be safe to return at this point
3493  // (but remember to stop the perflog)
3494  if (!we_have_constraints)
3495  return;
3496 
3497  for (const auto & dof : elem_dofs)
3498  dof_set.erase (dof);
3499 
3500  // If we added any DOFS then we need to do this recursively.
3501  // It is possible that we just added a DOF that is also
3502  // constrained!
3503  //
3504  // Also, we need to handle the special case of an element having DOFs
3505  // constrained in terms of other, local DOFs
3506  if (!dof_set.empty() || // case 1: constrained in terms of other DOFs
3507  !called_recursively) // case 2: constrained in terms of our own DOFs
3508  {
3509  const unsigned int old_size =
3510  cast_int<unsigned int>(elem_dofs.size());
3511 
3512  // Add new dependency dofs to the end of the current dof set
3513  elem_dofs.insert(elem_dofs.end(),
3514  dof_set.begin(), dof_set.end());
3515 
3516  // Now we can build the constraint matrix.
3517  // Note that resize also zeros for a DenseMatrix<Number>.
3518  C.resize (old_size,
3519  cast_int<unsigned int>(elem_dofs.size()));
3520 
3521  // Create the C constraint matrix.
3522  for (unsigned int i=0; i != old_size; i++)
3523  if (this->is_constrained_dof(elem_dofs[i]))
3524  {
3525  // If the DOF is constrained
3526  DofConstraints::const_iterator
3527  pos = _dof_constraints.find(elem_dofs[i]);
3528 
3529  libmesh_assert (pos != _dof_constraints.end());
3530 
3531  const DofConstraintRow & constraint_row = pos->second;
3532 
3533  // p refinement creates empty constraint rows
3534  // libmesh_assert (!constraint_row.empty());
3535 
3536  for (const auto & item : constraint_row)
3537  for (unsigned int j=0,
3538  n_elem_dofs = cast_int<unsigned int>(elem_dofs.size());
3539  j != n_elem_dofs; j++)
3540  if (elem_dofs[j] == item.first)
3541  C(i,j) = item.second;
3542  }
3543  else
3544  {
3545  C(i,i) = 1.;
3546  }
3547 
3548  // May need to do this recursively. It is possible
3549  // that we just replaced a constrained DOF with another
3550  // constrained DOF.
3551  DenseMatrix<Number> Cnew;
3552 
3553  this->build_constraint_matrix (Cnew, elem_dofs, true);
3554 
3555  if ((C.n() == Cnew.m()) &&
3556  (Cnew.n() == elem_dofs.size())) // If the constraint matrix
3557  C.right_multiply(Cnew); // is constrained...
3558 
3559  libmesh_assert_equal_to (C.n(), elem_dofs.size());
3560  }
3561 }
unsigned int m() const
libmesh_assert(ctx)
bool is_constrained_dof(const dof_id_type dof) const
Definition: dof_map.h:2182
DofConstraints _dof_constraints
Data structure containing DOF constraints.
Definition: dof_map.h:2033
virtual void right_multiply(const DenseMatrixBase< T > &M2) override final
Performs the operation: (*this) <- (*this) * M3.
void resize(const unsigned int new_m, const unsigned int new_n)
Resizes the matrix to the specified size and calls zero().
Definition: dense_matrix.h:895
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:90
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...
unsigned int n() const

◆ 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 heterogeneous 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 3565 of file dof_map_constraints.C.

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().

3570 {
3571  LOG_SCOPE_IF("build_constraint_matrix_and_vector()", "DofMap", !called_recursively);
3572 
3573  // Create a set containing the DOFs we already depend on
3574  typedef std::set<dof_id_type> RCSet;
3575  RCSet dof_set;
3576 
3577  bool we_have_constraints = false;
3578 
3579  // Next insert any other dofs the current dofs might be constrained
3580  // in terms of. Note that in this case we may not be done: Those
3581  // may in turn depend on others. So, we need to repeat this process
3582  // in that case until the system depends only on unconstrained
3583  // degrees of freedom.
3584  for (const auto & dof : elem_dofs)
3585  if (this->is_constrained_dof(dof))
3586  {
3587  we_have_constraints = true;
3588 
3589  // If the DOF is constrained
3590  DofConstraints::const_iterator
3591  pos = _dof_constraints.find(dof);
3592 
3593  libmesh_assert (pos != _dof_constraints.end());
3594 
3595  const DofConstraintRow & constraint_row = pos->second;
3596 
3597  // Constraint rows in p refinement may be empty
3598  //libmesh_assert (!constraint_row.empty());
3599 
3600  for (const auto & item : constraint_row)
3601  dof_set.insert (item.first);
3602  }
3603 
3604  // May be safe to return at this point
3605  // (but remember to stop the perflog)
3606  if (!we_have_constraints)
3607  return;
3608 
3609  for (const auto & dof : elem_dofs)
3610  dof_set.erase (dof);
3611 
3612  // If we added any DOFS then we need to do this recursively.
3613  // It is possible that we just added a DOF that is also
3614  // constrained!
3615  //
3616  // Also, we need to handle the special case of an element having DOFs
3617  // constrained in terms of other, local DOFs
3618  if (!dof_set.empty() || // case 1: constrained in terms of other DOFs
3619  !called_recursively) // case 2: constrained in terms of our own DOFs
3620  {
3621  const DofConstraintValueMap * rhs_values = nullptr;
3622  if (qoi_index < 0)
3623  rhs_values = &_primal_constraint_values;
3624  else
3625  {
3626  const AdjointDofConstraintValues::const_iterator
3627  it = _adjoint_constraint_values.find(qoi_index);
3628  if (it != _adjoint_constraint_values.end())
3629  rhs_values = &it->second;
3630  }
3631 
3632  const unsigned int old_size =
3633  cast_int<unsigned int>(elem_dofs.size());
3634 
3635  // Add new dependency dofs to the end of the current dof set
3636  elem_dofs.insert(elem_dofs.end(),
3637  dof_set.begin(), dof_set.end());
3638 
3639  // Now we can build the constraint matrix and vector.
3640  // Note that resize also zeros for a DenseMatrix and DenseVector
3641  C.resize (old_size,
3642  cast_int<unsigned int>(elem_dofs.size()));
3643  H.resize (old_size);
3644 
3645  // Create the C constraint matrix.
3646  for (unsigned int i=0; i != old_size; i++)
3647  if (this->is_constrained_dof(elem_dofs[i]))
3648  {
3649  // If the DOF is constrained
3650  DofConstraints::const_iterator
3651  pos = _dof_constraints.find(elem_dofs[i]);
3652 
3653  libmesh_assert (pos != _dof_constraints.end());
3654 
3655  const DofConstraintRow & constraint_row = pos->second;
3656 
3657  // p refinement creates empty constraint rows
3658  // libmesh_assert (!constraint_row.empty());
3659 
3660  for (const auto & item : constraint_row)
3661  for (unsigned int j=0,
3662  n_elem_dofs = cast_int<unsigned int>(elem_dofs.size());
3663  j != n_elem_dofs; j++)
3664  if (elem_dofs[j] == item.first)
3665  C(i,j) = item.second;
3666 
3667  if (rhs_values)
3668  {
3669  DofConstraintValueMap::const_iterator rhsit =
3670  rhs_values->find(elem_dofs[i]);
3671  if (rhsit != rhs_values->end())
3672  H(i) = rhsit->second;
3673  }
3674  }
3675  else
3676  {
3677  C(i,i) = 1.;
3678  }
3679 
3680  // May need to do this recursively. It is possible
3681  // that we just replaced a constrained DOF with another
3682  // constrained DOF.
3683  DenseMatrix<Number> Cnew;
3684  DenseVector<Number> Hnew;
3685 
3686  this->build_constraint_matrix_and_vector (Cnew, Hnew, elem_dofs,
3687  qoi_index, true);
3688 
3689  if ((C.n() == Cnew.m()) && // If the constraint matrix
3690  (Cnew.n() == elem_dofs.size())) // is constrained...
3691  {
3692  // If x = Cy + h and y = Dz + g
3693  // Then x = (CD)z + (Cg + h)
3694  C.vector_mult_add(H, 1, Hnew);
3695 
3696  C.right_multiply(Cnew);
3697  }
3698 
3699  libmesh_assert_equal_to (C.n(), elem_dofs.size());
3700  }
3701 }
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 ...
void resize(const unsigned int n)
Resize the vector.
Definition: dense_vector.h:374
unsigned int m() const
AdjointDofConstraintValues _adjoint_constraint_values
Definition: dof_map.h:2037
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. ...
libmesh_assert(ctx)
bool is_constrained_dof(const dof_id_type dof) const
Definition: dof_map.h:2182
DofConstraints _dof_constraints
Data structure containing DOF constraints.
Definition: dof_map.h:2033
Storage for DofConstraint right hand sides for a particular problem.
Definition: dof_map.h:110
virtual void right_multiply(const DenseMatrixBase< T > &M2) override final
Performs the operation: (*this) <- (*this) * M3.
DofConstraintValueMap _primal_constraint_values
Definition: dof_map.h:2035
void resize(const unsigned int new_m, const unsigned int new_n)
Resizes the matrix to the specified size and calls zero().
Definition: dense_matrix.h:895
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:90
unsigned int n() const

◆ build_sparsity()

std::unique_ptr< SparsityPattern::Build > libMesh::DofMap::build_sparsity ( const MeshBase mesh,
bool  calculate_constrained = false 
) const

Builds a sparsity pattern for matrices using the current degree-of-freedom numbering and coupling.

By default, ignores constraint equations, for build speed; this is valid for the combination of !need_full_sparsity_pattern and constraints which only come from periodic boundary conditions and adaptive mesh refinement, where matrix constraint adds some matrix entries but removes equally many (or more) other entries.

Can be told to calculate sparsity for the constrained matrix, which may be necessary in the case of spline control node constraints or sufficiently many user constraints.

Definition at line 64 of file dof_map.C.

References _augment_sparsity_pattern, _coupling_functors, _dof_coupling, _extra_sparsity_context, _extra_sparsity_function, 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(), process_mesh_constraint_rows(), and libMesh::System::solve_for_unconstrained_dofs().

66 {
67  libmesh_assert (mesh.is_prepared());
68 
69  LOG_SCOPE("build_sparsity()", "DofMap");
70 
71  // Compute the sparsity structure of the global matrix. This can be
72  // fed into a PetscMatrix to allocate exactly the number of nonzeros
73  // necessary to store the matrix. This algorithm should be linear
74  // in the (# of elements)*(# nodes per element)
75 
76  // We can be more efficient in the threaded sparsity pattern assembly
77  // if we don't need the exact pattern. For some sparse matrix formats
78  // a good upper bound will suffice.
79 
80  // See if we need to include sparsity pattern entries for coupling
81  // between neighbor dofs
82  bool implicit_neighbor_dofs = this->use_coupled_neighbor_dofs(mesh);
83 
84  // We can compute the sparsity pattern in parallel on multiple
85  // threads. The goal is for each thread to compute the full sparsity
86  // pattern for a subset of elements. These sparsity patterns can
87  // be efficiently merged in the SparsityPattern::Build::join()
88  // method, especially if there is not too much overlap between them.
89  // Even better, if the full sparsity pattern is not needed then
90  // the number of nonzeros per row can be estimated from the
91  // sparsity patterns created on each thread.
92  auto sp = std::make_unique<SparsityPattern::Build>
93  (*this,
94  this->_dof_coupling,
95  this->_coupling_functors,
96  implicit_neighbor_dofs,
98  calculate_constrained);
99 
100  Threads::parallel_reduce (ConstElemRange (mesh.active_local_elements_begin(),
101  mesh.active_local_elements_end()), *sp);
102 
103  sp->parallel_sync();
104 
105 #ifndef NDEBUG
106  // Avoid declaring these variables unless asserts are enabled.
107  const processor_id_type proc_id = mesh.processor_id();
108  const dof_id_type n_dofs_on_proc = this->n_dofs_on_processor(proc_id);
109 #endif
110  libmesh_assert_equal_to (sp->get_sparsity_pattern().size(), n_dofs_on_proc);
111 
112  // Check to see if we have any extra stuff to add to the sparsity_pattern
114  {
116  {
117  libmesh_here();
118  libMesh::out << "WARNING: You have specified both an extra sparsity function and object.\n"
119  << " Are you sure this is what you meant to do??"
120  << std::endl;
121  }
122 
123  sp->apply_extra_sparsity_function(_extra_sparsity_function,
125  }
126 
128  sp->apply_extra_sparsity_object(*_augment_sparsity_pattern);
129 
130  return sp;
131 }
dof_id_type n_dofs_on_processor(const processor_id_type proc) const
Definition: dof_map.h:675
void * _extra_sparsity_context
A pointer associated with the extra sparsity that can optionally be passed in.
Definition: dof_map.h:1913
MeshBase & mesh
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:1760
StoredRange< MeshBase::const_element_iterator, const Elem * > ConstElemRange
Definition: elem_range.h:34
bool need_full_sparsity_pattern
Default false; set to true if any attached matrix requires a full sparsity pattern.
Definition: dof_map.h:1979
uint8_t processor_id_type
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:1906
libmesh_assert(ctx)
CouplingMatrix * _dof_coupling
Degree of freedom coupling.
Definition: dof_map.h:1592
OStreamProxy out
SparsityPattern::AugmentSparsityPattern * _augment_sparsity_pattern
Function object to call to add extra entries to the sparsity pattern.
Definition: dof_map.h:1901
void parallel_reduce(const Range &range, Body &body)
Execute the provided reduction operation in parallel on the specified range.
Definition: threads_none.h:101
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:1967
uint8_t dof_id_type
Definition: id_types.h:67

◆ check_dirichlet_bcid_consistency()

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

If not, this will throw an error.

Definition at line 5528 of file dof_map_constraints.C.

References libMesh::DirichletBoundary::b, libMesh::ParallelObject::comm(), libMesh::BoundaryInfo::get_boundary_ids(), libMesh::MeshBase::get_boundary_info(), libMesh::BoundaryInfo::get_edge_boundary_ids(), libMesh::BoundaryInfo::get_node_boundary_ids(), libMesh::libmesh_assert(), TIMPI::Communicator::max(), mesh, and TIMPI::Communicator::verify().

Referenced by create_dof_constraints().

5530 {
5531  const std::set<boundary_id_type>& mesh_side_bcids =
5533  const std::set<boundary_id_type>& mesh_edge_bcids =
5535  const std::set<boundary_id_type>& mesh_node_bcids =
5537  const std::set<boundary_id_type>& dbc_bcids = boundary.b;
5538 
5539  // DirichletBoundary id sets should be consistent across all ranks
5540  libmesh_assert(mesh.comm().verify(dbc_bcids.size()));
5541 
5542  for (const auto & bc_id : dbc_bcids)
5543  {
5544  // DirichletBoundary id sets should be consistent across all ranks
5545  libmesh_assert(mesh.comm().verify(bc_id));
5546 
5547  bool found_bcid = (mesh_side_bcids.find(bc_id) != mesh_side_bcids.end() ||
5548  mesh_edge_bcids.find(bc_id) != mesh_edge_bcids.end() ||
5549  mesh_node_bcids.find(bc_id) != mesh_node_bcids.end());
5550 
5551  // On a distributed mesh, boundary id sets may *not* be
5552  // consistent across all ranks, since not all ranks see all
5553  // boundaries
5554  mesh.comm().max(found_bcid);
5555 
5556  libmesh_error_msg_if(!found_bcid,
5557  "Could not find Dirichlet boundary id " << bc_id << " in mesh!");
5558  }
5559 }
bool verify(const T &r) const
MeshBase & mesh
const Parallel::Communicator & comm() const
const BoundaryInfo & get_boundary_info() const
The information about boundary ids on the mesh.
Definition: mesh_base.h:159
const std::set< boundary_id_type > & get_node_boundary_ids() const
libmesh_assert(ctx)
const std::set< boundary_id_type > & get_boundary_ids() const
void max(const T &r, T &o, Request &req) const
const std::set< boundary_id_type > & get_edge_boundary_ids() const
std::set< boundary_id_type > b

◆ check_for_constraint_loops()

void libMesh::DofMap::check_for_constraint_loops ( )

Definition at line 4541 of file dof_map_constraints.C.

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

Referenced by check_for_cyclic_constraints(), and process_constraints().

4542 {
4543  // Create a set containing the DOFs we already depend on
4544  typedef std::set<dof_id_type> RCSet;
4545  RCSet unexpanded_set;
4546 
4547  // Use dof_constraints_copy in this method so that we don't
4548  // mess with _dof_constraints.
4549  DofConstraints dof_constraints_copy = _dof_constraints;
4550 
4551  for (const auto & i : dof_constraints_copy)
4552  unexpanded_set.insert(i.first);
4553 
4554  while (!unexpanded_set.empty())
4555  for (RCSet::iterator i = unexpanded_set.begin();
4556  i != unexpanded_set.end(); /* nothing */)
4557  {
4558  // If the DOF is constrained
4559  DofConstraints::iterator
4560  pos = dof_constraints_copy.find(*i);
4561 
4562  libmesh_assert (pos != dof_constraints_copy.end());
4563 
4564  DofConstraintRow & constraint_row = pos->second;
4565 
4566  // Comment out "rhs" parts of this method copied from process_constraints
4567  // DofConstraintValueMap::iterator rhsit =
4568  // _primal_constraint_values.find(*i);
4569  // Number constraint_rhs = (rhsit == _primal_constraint_values.end()) ?
4570  // 0 : rhsit->second;
4571 
4572  std::vector<dof_id_type> constraints_to_expand;
4573 
4574  for (const auto & item : constraint_row)
4575  if (item.first != *i && this->is_constrained_dof(item.first))
4576  {
4577  unexpanded_set.insert(item.first);
4578  constraints_to_expand.push_back(item.first);
4579  }
4580 
4581  for (const auto & expandable : constraints_to_expand)
4582  {
4583  const Real this_coef = constraint_row[expandable];
4584 
4585  DofConstraints::const_iterator
4586  subpos = dof_constraints_copy.find(expandable);
4587 
4588  libmesh_assert (subpos != dof_constraints_copy.end());
4589 
4590  const DofConstraintRow & subconstraint_row = subpos->second;
4591 
4592  for (const auto & item : subconstraint_row)
4593  {
4594  libmesh_error_msg_if(item.first == expandable, "Constraint loop detected");
4595 
4596  constraint_row[item.first] += item.second * this_coef;
4597  }
4598 
4599  // Comment out "rhs" parts of this method copied from process_constraints
4600  // DofConstraintValueMap::const_iterator subrhsit =
4601  // _primal_constraint_values.find(expandable);
4602  // if (subrhsit != _primal_constraint_values.end())
4603  // constraint_rhs += subrhsit->second * this_coef;
4604 
4605  constraint_row.erase(expandable);
4606  }
4607 
4608  // Comment out "rhs" parts of this method copied from process_constraints
4609  // if (rhsit == _primal_constraint_values.end())
4610  // {
4611  // if (constraint_rhs != Number(0))
4612  // _primal_constraint_values[*i] = constraint_rhs;
4613  // else
4614  // _primal_constraint_values.erase(*i);
4615  // }
4616  // else
4617  // {
4618  // if (constraint_rhs != Number(0))
4619  // rhsit->second = constraint_rhs;
4620  // else
4621  // _primal_constraint_values.erase(rhsit);
4622  // }
4623 
4624  if (constraints_to_expand.empty())
4625  i = unexpanded_set.erase(i);
4626  else
4627  ++i;
4628  }
4629 }
libmesh_assert(ctx)
DofConstraints _dof_constraints
Data structure containing DOF constraints.
Definition: dof_map.h:2033
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
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:90
The constraint matrix storage format.
Definition: dof_map.h:98

◆ 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 constraint and not (as here) a cyclic graph. The former nomenclature will eventually be deprecated in favor of "constraint loop".

Definition at line 4535 of file dof_map_constraints.C.

References check_for_constraint_loops().

4536 {
4537  // Eventually make this officially libmesh_deprecated();
4539 }

◆ 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 850 of file dof_map.C.

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, _var_to_vg, _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 libMesh::ReplicatedMesh::clear(), libMesh::DistributedMesh::clear(), and ~DofMap().

851 {
852  // we don't want to clear
853  // the coupling matrix!
854  // It should not change...
855  //_dof_coupling->clear();
856  //
857  // But it would be inconsistent to leave our coupling settings
858  // through a clear()...
859  _dof_coupling = nullptr;
860 
861  // Reset ghosting functor statuses
862  {
863  for (const auto & gf : _coupling_functors)
864  {
865  libmesh_assert(gf);
867  }
868  this->_coupling_functors.clear();
869 
870  // Go back to default coupling
871 
872  _default_coupling->set_dof_coupling(this->_dof_coupling);
873  _default_coupling->set_n_levels(this->use_coupled_neighbor_dofs(this->_mesh));
874 
876  }
877 
878 
879  {
880  for (const auto & gf : _algebraic_ghosting_functors)
881  {
882  libmesh_assert(gf);
884  }
885  this->_algebraic_ghosting_functors.clear();
886 
887  // Go back to default send_list generation
888 
889  // _default_evaluating->set_dof_coupling(this->_dof_coupling);
890  _default_evaluating->set_n_levels(1);
892  }
893 
894  this->_shared_functors.clear();
895 
896  _variables.clear();
897  _variable_groups.clear();
898  _var_to_vg.clear();
899  _variable_group_numbers.clear();
900  _first_df.clear();
901  _end_df.clear();
902  _first_scalar_df.clear();
903  this->clear_send_list();
904  this->clear_sparsity();
906 
907 #ifdef LIBMESH_ENABLE_AMR
908 
909  _dof_constraints.clear();
910  _stashed_dof_constraints.clear();
913  _n_old_dfs = 0;
914  _first_old_df.clear();
915  _end_old_df.clear();
916  _first_old_scalar_df.clear();
917 
918 #endif
919 
920  _matrices.clear();
921 
922  _n_dfs = 0;
923 }
std::vector< VariableGroup > _variable_groups
The finite element type for each variable group.
Definition: dof_map.h:1847
void remove_ghosting_functor(GhostingFunctor &ghosting_functor)
Removes a functor which was previously added to the set of ghosting functors.
Definition: mesh_base.C:888
void clear_send_list()
Clears the _send_list vector.
Definition: dof_map.h:485
std::set< GhostingFunctor * > _algebraic_ghosting_functors
The list of all GhostingFunctor objects to be used when distributing ghosted vectors.
Definition: dof_map.h:1954
std::vector< dof_id_type > _end_old_df
Last old DOF index (plus 1) on processor p.
Definition: dof_map.h:2014
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:1760
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:1861
std::vector< dof_id_type > _first_old_df
First old DOF index on processor p.
Definition: dof_map.h:2009
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:1890
AdjointDofConstraintValues _adjoint_constraint_values
Definition: dof_map.h:2037
bool need_full_sparsity_pattern
Default false; set to true if any attached matrix requires a full sparsity pattern.
Definition: dof_map.h:1979
std::unordered_map< unsigned int, unsigned int > _var_to_vg
A map from variable number to variable group number.
Definition: dof_map.h:1857
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:2020
libmesh_assert(ctx)
DofConstraints _dof_constraints
Data structure containing DOF constraints.
Definition: dof_map.h:2033
CouplingMatrix * _dof_coupling
Degree of freedom coupling.
Definition: dof_map.h:1592
std::vector< SparseMatrix< Number > *> _matrices
Additional matrices handled by this object.
Definition: dof_map.h:1874
std::unique_ptr< DefaultCoupling > _default_coupling
The default coupling GhostingFunctor, used to implement standard libMesh sparsity pattern constructio...
Definition: dof_map.h:1936
DofConstraintValueMap _primal_constraint_values
Definition: dof_map.h:2035
std::vector< Variable > _variables
The finite element type for each variable.
Definition: dof_map.h:1842
DofConstraints _stashed_dof_constraints
Definition: dof_map.h:2033
dof_id_type _n_old_dfs
Total number of degrees of freedom on old dof objects.
Definition: dof_map.h:2004
void clear_sparsity()
Clears the sparsity pattern.
Definition: dof_map.C:1837
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:1967
std::vector< dof_id_type > _end_df
Last DOF index (plus 1) on processor p.
Definition: dof_map.h:1884
std::vector< dof_id_type > _first_df
First DOF index on processor p.
Definition: dof_map.h:1879
MeshBase & _mesh
The mesh that system uses.
Definition: dof_map.h:1867
std::unique_ptr< DefaultCoupling > _default_evaluating
The default algebraic GhostingFunctor, used to implement standard libMesh send_list construction...
Definition: dof_map.h:1944
std::vector< unsigned int > _variable_group_numbers
The variable group number for each variable.
Definition: dof_map.h:1852
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:1973
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:1886
dof_id_type _n_dfs
Total number of degrees of freedom.
Definition: dof_map.h:1991

◆ 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 485 of file dof_map.h.

References _send_list.

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

486  {
487  _send_list.clear();
488  }
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:1896

◆ clear_sparsity()

void libMesh::DofMap::clear_sparsity ( )

Clears the sparsity pattern.

Definition at line 1837 of file dof_map.C.

References _sp.

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

1838 {
1839  _sp.reset();
1840 }
std::unique_ptr< SparsityPattern::Build > _sp
The sparsity pattern of the global matrix.
Definition: dof_map.h:1986

◆ comm()

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

Definition at line 97 of file parallel_object.h.

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::Partitioner::_find_global_index_by_pid_map(), libMesh::BoundaryInfo::_find_id_maps(), libMesh::SlepcEigenSolver< libMesh::Number >::_petsc_shell_matrix_get_diagonal(), libMesh::PetscLinearSolver< Number >::_petsc_shell_matrix_get_diagonal(), libMesh::SlepcEigenSolver< libMesh::Number >::_petsc_shell_matrix_mult(), libMesh::PetscLinearSolver< Number >::_petsc_shell_matrix_mult(), libMesh::PetscLinearSolver< Number >::_petsc_shell_matrix_mult_add(), 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::EigenSystem::add_matrices(), libMesh::System::add_matrix(), libMesh::RBConstruction::add_scaled_matrix_and_vector(), libMesh::System::add_variable(), libMesh::System::add_variables(), libMesh::System::add_vector(), 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::Nemesis_IO::assert_symmetric_cmaps(), libMesh::MeshCommunication::assign_global_indices(), libMesh::Partitioner::assign_partitioning(), 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::MeshBase::cache_elem_data(), 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(), computed_sparsity_already(), libMesh::Problem_Interface::computeF(), libMesh::Problem_Interface::computeJacobian(), libMesh::Problem_Interface::computePreconditioner(), libMesh::ContinuationSystem::ContinuationSystem(), libMesh::MeshBase::copy_constraint_rows(), libMesh::ExodusII_IO::copy_elemental_solution(), libMesh::ExodusII_IO::copy_nodal_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::PetscMatrix< libMesh::Number >::create_submatrix_nosort(), libMesh::MeshCommunication::delete_remote_elements(), libMesh::RBEIMEvaluation::distribute_bfs(), distribute_dofs(), DMlibMeshFunction(), DMlibMeshJacobian(), DMlibMeshSetSystem_libMesh(), DMVariableBounds_libMesh(), libMesh::DTKSolutionTransfer::DTKSolutionTransfer(), libMesh::MeshRefinement::eliminate_unrefined_patches(), libMesh::RBEIMConstruction::enrich_eim_approximation_on_interiors(), libMesh::RBEIMConstruction::enrich_eim_approximation_on_nodes(), libMesh::RBEIMConstruction::enrich_eim_approximation_on_sides(), libMesh::TransientRBConstruction::enrich_RB_space(), libMesh::EpetraVector< T >::EpetraVector(), AssembleOptimization::equality_constraints(), libMesh::PatchRecoveryErrorEstimator::estimate_error(), libMesh::WeightedPatchRecoveryErrorEstimator::estimate_error(), libMesh::AdjointRefinementEstimator::estimate_error(), libMesh::ExactErrorEstimator::estimate_error(), 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(), libMesh::RBEIMEvaluation::gather_bfs(), gather_constraints(), libMesh::MeshfreeInterpolation::gather_remote_data(), libMesh::CondensedEigenSystem::get_eigenpair(), libMesh::RBEIMEvaluation::get_eim_basis_function_node_value(), libMesh::RBEIMEvaluation::get_eim_basis_function_side_value(), libMesh::RBEIMEvaluation::get_eim_basis_function_value(), libMesh::MeshBase::get_info(), libMesh::System::get_info(), get_info(), libMesh::ImplicitSystem::get_linear_solver(), libMesh::RBEIMConstruction::get_max_abs_value(), libMesh::RBEIMConstruction::get_node_max_abs_value(), libMesh::RBEIMEvaluation::get_parametrized_function_node_value(), libMesh::RBEIMEvaluation::get_parametrized_function_side_value(), libMesh::RBEIMEvaluation::get_parametrized_function_value(), libMesh::RBEIMConstruction::get_random_point(), AssembleOptimization::inequality_constraints(), AssembleOptimization::inequality_constraints_jacobian(), libMesh::LocationMap< T >::init(), libMesh::TimeSolver::init(), libMesh::SystemSubsetBySubdomain::init(), libMesh::PetscDMWrapper::init_and_attach_petscdm(), libMesh::ExodusII_IO_Helper::initialize(), libMesh::OptimizationSystem::initialize_equality_constraints_storage(), libMesh::OptimizationSystem::initialize_inequality_constraints_storage(), libMesh::RBEIMConstruction::initialize_parametrized_functions_in_training_set(), libMesh::RBEIMConstruction::inner_product(), 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_equal_connectivity(), libMesh::MeshTools::libmesh_assert_equal_points(), 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_linesearch_shellfunc(), libMesh::libmesh_petsc_preconditioner_apply(), libMesh::libmesh_petsc_recalculate_monitor(), libMesh::libmesh_petsc_snes_fd_residual(), libMesh::libmesh_petsc_snes_jacobian(), libMesh::libmesh_petsc_snes_mffd_interface(), libMesh::libmesh_petsc_snes_mffd_residual(), libMesh::libmesh_petsc_snes_postcheck(), libMesh::libmesh_petsc_snes_precheck(), 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(), libMesh::LinearImplicitSystem::LinearImplicitSystem(), 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_bcids_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(), libMesh::TriangulatorInterface::MeshedHole::MeshedHole(), 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(), MixedOrderTest::n_neighbor_links(), libMesh::BoundaryInfo::n_nodeset_conds(), libMesh::SparsityPattern::Build::n_nonzeros(), libMesh::MeshTools::n_p_levels(), libMesh::BoundaryInfo::n_shellface_conds(), libMesh::RBEIMEvaluation::node_distribute_bfs(), libMesh::RBEIMEvaluation::node_gather_bfs(), libMesh::RBEIMConstruction::node_inner_product(), libMesh::MeshBase::operator==(), 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::BoundaryInfo::parallel_sync_node_ids(), libMesh::BoundaryInfo::parallel_sync_side_ids(), libMesh::MeshTools::paranoid_n_levels(), libMesh::Partitioner::partition(), libMesh::Partitioner::partition_unpartitioned_elements(), libMesh::petsc_auto_fieldsplit(), libMesh::System::point_gradient(), libMesh::System::point_hessian(), libMesh::System::point_value(), libMesh::MeshBase::prepare_for_use(), print_dof_constraints(), process_mesh_constraint_rows(), libMesh::Partitioner::processor_pairs_to_interface_nodes(), libMesh::InterMeshProjection::project_system_vectors(), FEMParameters::read(), libMesh::Nemesis_IO::read(), libMesh::XdrIO::read(), libMesh::EquationSystems::read(), libMesh::ExodusII_IO::read_header(), libMesh::CheckpointIO::read_header(), libMesh::XdrIO::read_header(), libMesh::System::read_header(), libMesh::RBEIMEvaluation::read_in_interior_basis_functions(), libMesh::RBEIMEvaluation::read_in_node_basis_functions(), libMesh::RBEIMEvaluation::read_in_side_basis_functions(), 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::Nemesis_IO_Helper::read_var_names_impl(), libMesh::MeshBase::recalculate_n_partitions(), libMesh::MeshRefinement::refine_and_coarsen_elements(), libMesh::DistributedMesh::renumber_dof_objects(), libMesh::DistributedMesh::renumber_nodes_and_elements(), LinearElasticityWithContact::residual_and_jacobian(), OverlappingAlgebraicGhostingTest::run_ghosting_test(), OverlappingCouplingGhostingTest::run_sparsity_pattern_test(), scale_mesh_and_plot(), scatter_constraints(), libMesh::CheckpointIO::select_split_config(), libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::send_and_insert_dof_values(), libMesh::TransientRBConstruction::set_error_temporal_data(), libMesh::Partitioner::set_interface_node_processor_ids_BFS(), libMesh::Partitioner::set_interface_node_processor_ids_linear(), libMesh::Partitioner::set_interface_node_processor_ids_petscpartitioner(), libMesh::Partitioner::set_node_processor_ids(), set_nonlocal_dof_objects(), libMesh::Partitioner::set_parent_processor_ids(), libMesh::PetscDMWrapper::set_point_range_in_section(), libMesh::PetscDiffSolver::setup_petsc_data(), libMesh::RBEIMEvaluation::side_distribute_bfs(), libMesh::RBEIMEvaluation::side_gather_bfs(), libMesh::RBEIMConstruction::side_inner_product(), libMesh::Partitioner::single_partition(), libMesh::LaplaceMeshSmoother::smooth(), libMesh::split_mesh(), libMesh::RBEIMConstruction::store_eim_solutions_for_training_set(), libMesh::MeshBase::subdomain_ids(), libMesh::BoundaryInfo::sync(), ConstraintOperatorTest::test1DCoarseningNewNodes(), ConstraintOperatorTest::test1DCoarseningOperator(), libMesh::MeshRefinement::test_level_one(), MeshfunctionDFEM::test_mesh_function_dfem(), MeshfunctionDFEM::test_mesh_function_dfem_grad(), MeshFunctionTest::test_p_level(), libMesh::MeshRefinement::test_unflagged(), DofMapTest::testBadElemFECombo(), SystemsTest::testBlockRestrictedVarNDofs(), BoundaryInfoTest::testBoundaryOnChildrenErrors(), ConstraintOperatorTest::testCoreform(), MeshInputTest::testExodusIGASidesets(), MeshTriangulationTest::testFoundCenters(), PointLocatorTest::testLocator(), BoundaryInfoTest::testMesh(), PointLocatorTest::testPlanar(), MeshTriangulationTest::testPoly2TriRefinementBase(), SystemsTest::testProjectCubeWithMeshFunction(), BoundaryInfoTest::testRenumber(), CheckpointIOTest::testSplitter(), MeshInputTest::testTetgenIO(), MeshTriangulationTest::testTriangulatorInterp(), MeshTriangulationTest::testTriangulatorMeshedHoles(), MeshTriangulationTest::testTriangulatorRoundHole(), libMesh::MeshTools::total_weight(), libMesh::RBConstruction::train_reduced_basis_with_POD(), libMesh::MeshFunctionSolutionTransfer::transfer(), libMesh::MeshfreeSolutionTransfer::transfer(), libMesh::Poly2TriTriangulator::triangulate(), libMesh::TransientRBConstruction::truth_assembly(), libMesh::RBConstruction::truth_assembly(), libMesh::MeshRefinement::uniformly_coarsen(), libMesh::TransientRBConstruction::update_RB_initial_condition_all_N(), 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::RBEIMEvaluation::write_out_interior_basis_functions(), libMesh::RBEIMEvaluation::write_out_node_basis_functions(), libMesh::RBEIMEvaluation::write_out_side_basis_functions(), 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().

98  { return _communicator; }
const Parallel::Communicator & _communicator

◆ 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 1816 of file dof_map.C.

References _constrained_sparsity_construction, _matrices, _sp, build_sparsity(), and need_full_sparsity_pattern.

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

1817 {
1819 
1820  // It is possible that some \p SparseMatrix implementations want to
1821  // see the sparsity pattern before we throw it away. If so, we
1822  // share a view of its arrays, and we pass it in to the matrices.
1823  for (const auto & mat : _matrices)
1824  {
1825  mat->attach_sparsity_pattern (*_sp);
1827  mat->update_sparsity_pattern (_sp->get_sparsity_pattern());
1828  }
1829  // If we don't need the full sparsity pattern anymore, free the
1830  // parts of it we don't need.
1832  _sp->clear_full_sparsity();
1833 }
std::unique_ptr< SparsityPattern::Build > _sp
The sparsity pattern of the global matrix.
Definition: dof_map.h:1986
MeshBase & mesh
std::unique_ptr< SparsityPattern::Build > build_sparsity(const MeshBase &mesh, bool calculate_constrained=false) const
Builds a sparsity pattern for matrices using the current degree-of-freedom numbering and coupling...
Definition: dof_map.C:64
bool _constrained_sparsity_construction
This flag indicates whether or not we explicitly take constraint equations into account when computin...
Definition: dof_map.h:1837
bool need_full_sparsity_pattern
Default false; set to true if any attached matrix requires a full sparsity pattern.
Definition: dof_map.h:1979
std::vector< SparseMatrix< Number > *> _matrices
Additional matrices handled by this object.
Definition: dof_map.h:1874

◆ computed_sparsity_already()

bool libMesh::DofMap::computed_sparsity_already ( ) const

Returns true iff a sparsity pattern has already been computed.

Definition at line 296 of file dof_map.C.

References _sp, libMesh::ParallelObject::comm(), and TIMPI::Communicator::max().

Referenced by libMesh::System::solve_for_unconstrained_dofs(), and update_sparsity_pattern().

297 {
299  (!_sp->get_n_nz().empty() ||
300  !_sp->get_n_oz().empty());
301  this->comm().max(computed_sparsity_already);
303 }
std::unique_ptr< SparsityPattern::Build > _sp
The sparsity pattern of the global matrix.
Definition: dof_map.h:1986
const Parallel::Communicator & comm() const
bool computed_sparsity_already() const
Returns true iff a sparsity pattern has already been computed.
Definition: dof_map.C:296
void max(const T &r, T &o, Request &req) const

◆ 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 2267 of file dof_map.h.

Referenced by assemble().

2270  {}

◆ 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 2241 of file dof_map.h.

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

2243  {}

◆ 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 2245 of file dof_map.h.

2248  {}

◆ 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 2254 of file dof_map.h.

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().

2257  {}

◆ constrain_element_residual()

void libMesh::DofMap::constrain_element_residual ( DenseVector< Number > &  rhs,
std::vector< dof_id_type > &  elem_dofs,
NumericVector< Number > &  solution_local 
) const

Constrains the element residual.

The element Jacobian is square, and the elem_dofs should correspond to the global DOF indices of both the rows and columns of the element matrix, and the dof constraint should not include any heterogeneous terms.

The residual-constraining version of this method creates linear systems in which heterogeneously constrained degrees of freedom create non-zero residual terms when not at their correct offset values, as would be appropriate for finding a solution to a nonlinear problem in a quasi-Newton solve.

The solution vector passed in should be a serialized or ghosted primal solution

Definition at line 2778 of file dof_map_constraints.C.

References libMesh::GHOSTED, libMesh::libmesh_assert(), libMesh::DenseMatrixBase< T >::n(), libMesh::SERIAL, libMesh::DenseVector< T >::size(), libMesh::NumericVector< T >::type(), and libMesh::DenseMatrix< T >::vector_mult_transpose().

2781 {
2782  libmesh_assert_equal_to (elem_dofs.size(), rhs.size());
2783 
2784  libmesh_assert (solution_local.type() == SERIAL ||
2785  solution_local.type() == GHOSTED);
2786 
2787  // check for easy return
2788  if (this->_dof_constraints.empty())
2789  return;
2790 
2791  // The constrained RHS is built up as C^T F
2793 
2794  this->build_constraint_matrix (C, elem_dofs);
2795 
2796  LOG_SCOPE("cnstrn_elem_residual()", "DofMap");
2797 
2798  // It is possible that the matrix is not constrained at all.
2799  if (C.n() != elem_dofs.size())
2800  return;
2801 
2802  // Compute the matrix-vector product C^T F
2803  DenseVector<Number> old_rhs(rhs);
2804  C.vector_mult_transpose(rhs, old_rhs);
2805 
2806  for (unsigned int i=0,
2807  n_elem_dofs = cast_int<unsigned int>(elem_dofs.size());
2808  i != n_elem_dofs; i++)
2809  {
2810  const dof_id_type dof_id = elem_dofs[i];
2811 
2812  const DofConstraints::const_iterator
2813  pos = _dof_constraints.find(dof_id);
2814 
2815  if (pos != _dof_constraints.end())
2816  {
2817  // This will put a nonsymmetric entry in the constraint
2818  // row to ensure that the linear system produces the
2819  // correct value for the constrained DOF.
2820  const DofConstraintRow & constraint_row = pos->second;
2821 
2822  Number & rhs_val = rhs(i);
2823  rhs_val = 0;
2824  for (const auto & [constraining_dof, coef] : constraint_row)
2825  rhs_val -= coef * solution_local(constraining_dof);
2826  rhs_val += solution_local(dof_id);
2827  }
2828  }
2829 }
void vector_mult_transpose(DenseVector< T > &dest, const DenseVector< T > &arg) const
Performs the matrix-vector multiplication, dest := (*this)^T * arg.
libmesh_assert(ctx)
DofConstraints _dof_constraints
Data structure containing DOF constraints.
Definition: dof_map.h:2033
ParallelType type() const
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:90
virtual unsigned int size() const override final
Definition: dense_vector.h:104
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...
unsigned int n() const
uint8_t dof_id_type
Definition: id_types.h:67

◆ 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 2250 of file dof_map.h.

Referenced by LargeDeformationElasticity::residual(), Biharmonic::JR::residual_and_jacobian(), and InfFERadialTest::testRefinement().

2252  {}

◆ 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 2272 of file dof_map.h.

2272 {}

◆ 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 5387 of file dof_map_constraints.C.

References _dof_constraints, _primal_constraint_values, 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::Elem::p_level(), libMesh::Threads::spin_mtx, sys_number(), and variable_type().

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

5391 {
5392  // We're constraining dofs on elem which correspond to p refinement
5393  // levels above p - this only makes sense if elem's p refinement
5394  // level is above p.
5395  libmesh_assert_greater (elem->p_level(), p);
5396  libmesh_assert_less (s, elem->n_sides());
5397 
5398  const unsigned int sys_num = this->sys_number();
5399  FEType fe_type = this->variable_type(var);
5400 
5401  const unsigned int n_nodes = elem->n_nodes();
5402  for (unsigned int n = 0; n != n_nodes; ++n)
5403  if (elem->is_node_on_side(n, s))
5404  {
5405  const Node & node = elem->node_ref(n);
5406  const unsigned int low_nc =
5407  FEInterface::n_dofs_at_node (fe_type, p, elem, n);
5408  const unsigned int high_nc =
5409  FEInterface::n_dofs_at_node (fe_type, elem, n);
5410 
5411  // since we may be running this method concurrently
5412  // on multiple threads we need to acquire a lock
5413  // before modifying the _dof_constraints object.
5414  Threads::spin_mutex::scoped_lock lock(Threads::spin_mtx);
5415 
5416  if (elem->is_vertex(n))
5417  {
5418  // Add "this is zero" constraint rows for high p vertex
5419  // dofs
5420  for (unsigned int i = low_nc; i != high_nc; ++i)
5421  {
5422  _dof_constraints[node.dof_number(sys_num,var,i)].clear();
5423  _primal_constraint_values.erase(node.dof_number(sys_num,var,i));
5424  }
5425  }
5426  else
5427  {
5428  const unsigned int total_dofs = node.n_comp(sys_num, var);
5429  libmesh_assert_greater_equal (total_dofs, high_nc);
5430  // Add "this is zero" constraint rows for high p
5431  // non-vertex dofs, which are numbered in reverse
5432  for (unsigned int j = low_nc; j != high_nc; ++j)
5433  {
5434  const unsigned int i = total_dofs - j - 1;
5435  _dof_constraints[node.dof_number(sys_num,var,i)].clear();
5436  _primal_constraint_values.erase(node.dof_number(sys_num,var,i));
5437  }
5438  }
5439  }
5440 }
class FEType hides (possibly multiple) FEFamily and approximation orders, thereby enabling specialize...
Definition: fe_type.h:182
dof_id_type dof_number(const unsigned int s, const unsigned int var, const unsigned int comp) const
Definition: dof_object.h:1025
A Node is like a Point, but with more information.
Definition: node.h:52
unsigned int n_comp(const unsigned int s, const unsigned int var) const
Definition: dof_object.h:995
const FEType & variable_type(const unsigned int c) const
Definition: dof_map.h:2144
virtual bool is_node_on_side(const unsigned int n, const unsigned int s) const =0
unsigned int p_level() const
Definition: elem.h:2945
unsigned int sys_number() const
Definition: dof_map.h:2096
const dof_id_type n_nodes
Definition: tecplot_io.C:67
const Node & node_ref(const unsigned int i) const
Definition: elem.h:2353
virtual unsigned int n_nodes() const =0
DofConstraints _dof_constraints
Data structure containing DOF constraints.
Definition: dof_map.h:2033
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:679
virtual unsigned int n_sides() const =0
virtual bool is_vertex(const unsigned int i) const =0
DofConstraintValueMap _primal_constraint_values
Definition: dof_map.h:2035
spin_mutex spin_mtx
A convenient spin mutex object which can be used for obtaining locks.
Definition: threads.C:30

◆ constrained_sparsity_construction()

bool libMesh::DofMap::constrained_sparsity_construction ( )
inline

Returns true iff the current policy when constructing sparsity patterns is to explicitly account for sparsity entries created by constraint matrix pre- and post- application.

Definition at line 2312 of file dof_map.h.

References _constrained_sparsity_construction.

2313 {
2314 #ifdef LIBMESH_ENABLE_CONSTRAINTS
2316 #else
2317  return true;
2318 #endif
2319 }
bool _constrained_sparsity_construction
This flag indicates whether or not we explicitly take constraint equations into account when computin...
Definition: dof_map.h:1837

◆ 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 1013 of file dof_map.h.

References _dof_constraints.

1014  { return _dof_constraints.begin(); }
DofConstraints _dof_constraints
Data structure containing DOF constraints.
Definition: dof_map.h:2033

◆ 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 1019 of file dof_map.h.

References _dof_constraints.

1020  { return _dof_constraints.end(); }
DofConstraints _dof_constraints
Data structure containing DOF constraints.
Definition: dof_map.h:2033

◆ coupling_functors_begin()

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

Beginning of range of coupling functors.

Definition at line 344 of file dof_map.h.

References _coupling_functors.

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

345  { return _coupling_functors.begin(); }
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:1967

◆ coupling_functors_end()

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

End of range of coupling functors.

Definition at line 350 of file dof_map.h.

References _coupling_functors.

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

351  { return _coupling_functors.end(); }
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:1967

◆ create_dof_constraints()

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

Rebuilds the raw degree of freedom and DofObject constraints, based on attached DirichletBoundary objects and on non-conforming interface in adapted meshes.

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

Definition at line 1732 of file dof_map_constraints.C.

References _adjoint_constraint_values, _adjoint_dirichlet_boundaries, _dirichlet_boundaries, _dof_constraints, _node_constraints, _periodic_boundaries, _primal_constraint_values, _verify_dirichlet_bc_consistency, check_dirichlet_bcid_consistency(), libMesh::ParallelObject::comm(), libMesh::MeshBase::get_constraint_rows(), libMesh::index_range(), libMesh::MeshBase::is_prepared(), libMesh::MeshBase::is_serial(), libMesh::libmesh_assert(), libMesh::MeshTools::libmesh_assert_valid_boundary_ids(), TIMPI::Communicator::max(), mesh, libMesh::MeshBase::mesh_dimension(), TIMPI::Communicator::min(), libMesh::MeshBase::n_elem(), n_variables(), n_vars, libMesh::Threads::parallel_for(), process_mesh_constraint_rows(), and libMesh::MeshBase::sub_point_locator().

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

1733 {
1734  parallel_object_only();
1735 
1736  LOG_SCOPE("create_dof_constraints()", "DofMap");
1737 
1739 
1740  // The user might have set boundary conditions after the mesh was
1741  // prepared; we should double-check that those boundary conditions
1742  // are still consistent.
1743 #ifdef DEBUG
1745 #endif
1746 
1747  // In a distributed mesh we might have constraint rows on some
1748  // processors but not all; if we have constraint rows on *any*
1749  // processor then we need to process them.
1750  bool constraint_rows_empty = mesh.get_constraint_rows().empty();
1751  this->comm().min(constraint_rows_empty);
1752 
1753  // We might get constraint equations from AMR hanging nodes in
1754  // 2D/3D, or from spline constraint rows or boundary conditions in
1755  // any dimension
1756  const bool possible_local_constraints = false
1757  || !mesh.n_elem()
1758  || !constraint_rows_empty
1759 #ifdef LIBMESH_ENABLE_AMR
1760  || mesh.mesh_dimension() > 1
1761 #endif
1762 #ifdef LIBMESH_ENABLE_PERIODIC
1763  || !_periodic_boundaries->empty()
1764 #endif
1765 #ifdef LIBMESH_ENABLE_DIRICHLET
1766  || !_dirichlet_boundaries->empty()
1767 #endif
1768  ;
1769 
1770  // Even if we don't have constraints, another processor might.
1771  bool possible_global_constraints = possible_local_constraints;
1772 #if defined(LIBMESH_ENABLE_PERIODIC) || defined(LIBMESH_ENABLE_DIRICHLET) || defined(LIBMESH_ENABLE_AMR)
1773  libmesh_assert(this->comm().verify(mesh.is_serial()));
1774 
1775  this->comm().max(possible_global_constraints);
1776 #endif
1777 
1778  // Recalculate dof constraints from scratch. (Or just clear them,
1779  // if the user has just deleted their last dirichlet/periodic/user
1780  // constraint)
1781  // Note: any _stashed_dof_constraints are not cleared as it
1782  // may be the user's intention to restore them later.
1783 #ifdef LIBMESH_ENABLE_CONSTRAINTS
1784  _dof_constraints.clear();
1785  _primal_constraint_values.clear();
1787 #endif
1788 #ifdef LIBMESH_ENABLE_NODE_CONSTRAINTS
1789  _node_constraints.clear();
1790 #endif
1791 
1792  if (!possible_global_constraints)
1793  return;
1794 
1795  // Here we build the hanging node constraints. This is done
1796  // by enforcing the condition u_a = u_b along hanging sides.
1797  // u_a = u_b is collocated at the nodes of side a, which gives
1798  // one row of the constraint matrix.
1799 
1800  // Processors only compute their local constraints
1801  ConstElemRange range (mesh.local_elements_begin(),
1802  mesh.local_elements_end());
1803 
1804  // Global computation fails if we're using a FEMFunctionBase BC on a
1805  // ReplicatedMesh in parallel
1806  // ConstElemRange range (mesh.elements_begin(),
1807  // mesh.elements_end());
1808 
1809  // compute_periodic_constraints requires a point_locator() from our
1810  // Mesh, but point_locator() construction is parallel and threaded.
1811  // Rather than nest threads within threads we'll make sure it's
1812  // preconstructed.
1813 #ifdef LIBMESH_ENABLE_PERIODIC
1814  bool need_point_locator = !_periodic_boundaries->empty() && !range.empty();
1815 
1816  this->comm().max(need_point_locator);
1817 
1818  if (need_point_locator)
1820 #endif
1821 
1822 #ifdef LIBMESH_ENABLE_NODE_CONSTRAINTS
1823  Threads::parallel_for (range,
1824  ComputeNodeConstraints (_node_constraints,
1825 #ifdef LIBMESH_ENABLE_PERIODIC
1827 #endif
1828  mesh));
1829 #endif // LIBMESH_ENABLE_NODE_CONSTRAINTS
1830 
1831 
1832  // Look at all the variables in the system. Reset the element
1833  // range at each iteration -- there is no need to reconstruct it.
1834  const auto n_vars = this->n_variables();
1835  for (unsigned int variable_number=0; variable_number<n_vars;
1836  ++variable_number, range.reset())
1837  Threads::parallel_for (range,
1838  ComputeConstraints (_dof_constraints,
1839  *this,
1840 #ifdef LIBMESH_ENABLE_PERIODIC
1842 #endif
1843  mesh,
1844  variable_number));
1845 
1846 #ifdef LIBMESH_ENABLE_DIRICHLET
1847 
1848  if (!_dirichlet_boundaries->empty())
1849  {
1850  // Sanity check that the boundary ids associated with the
1851  // DirichletBoundary objects are actually present in the
1852  // mesh. We do this check by default, but in cases where you
1853  // intentionally add "inconsistent but valid" DirichletBoundary
1854  // objects in parallel, this check can deadlock since it does a
1855  // collective communication internally. In that case it is
1856  // possible to disable this check by setting the flag to false.
1858  for (const auto & dirichlet : *_dirichlet_boundaries)
1859  this->check_dirichlet_bcid_consistency(mesh, *dirichlet);
1860 
1861  // Threaded loop over local over elems applying all Dirichlet BCs
1863  (range,
1864  ConstrainDirichlet(*this, mesh, time, *_dirichlet_boundaries,
1865  AddPrimalConstraint(*this)));
1866 
1867  // Threaded loop over local over elems per QOI applying all adjoint
1868  // Dirichlet BCs. Note that the ConstElemRange is reset before each
1869  // execution of Threads::parallel_for().
1870 
1871  for (auto qoi_index : index_range(_adjoint_dirichlet_boundaries))
1872  {
1873  const DirichletBoundaries & adb_q =
1874  *(_adjoint_dirichlet_boundaries[qoi_index]);
1875 
1876  if (!adb_q.empty())
1878  (range.reset(),
1879  ConstrainDirichlet(*this, mesh, time, adb_q,
1880  AddAdjointConstraint(*this, qoi_index)));
1881  }
1882  }
1883 
1884 #endif // LIBMESH_ENABLE_DIRICHLET
1885 
1886  // Handle spline node constraints last, so we can try to move
1887  // existing constraints onto the spline basis if necessary.
1888  if (!constraint_rows_empty)
1889  this->process_mesh_constraint_rows(mesh);
1890 }
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.
bool is_prepared() const
Definition: mesh_base.h:192
constraint_rows_type & get_constraint_rows()
Definition: mesh_base.h:1683
std::unique_ptr< PointLocatorBase > sub_point_locator() const
Definition: mesh_base.C:1565
void process_mesh_constraint_rows(const MeshBase &mesh)
Adds any spline constraints from the Mesh to our DoF constraints.
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
MeshBase & mesh
unsigned int n_variables() const
Definition: dof_map.h:621
std::unique_ptr< DirichletBoundaries > _dirichlet_boundaries
Data structure containing Dirichlet functions.
Definition: dof_map.h:2061
const Parallel::Communicator & comm() const
The StoredRange class defines a contiguous, divisible set of objects.
Definition: stored_range.h:54
AdjointDofConstraintValues _adjoint_constraint_values
Definition: dof_map.h:2037
virtual bool is_serial() const
Definition: mesh_base.h:205
void min(const T &r, T &o, Request &req) const
unsigned int n_vars
We&#39;re using a class instead of a typedef to allow forward declarations and future flexibility...
libmesh_assert(ctx)
void libmesh_assert_valid_boundary_ids(const MeshBase &mesh)
A function for verifying that boundary condition ids match across processors.
Definition: mesh_tools.C:1534
DofConstraints _dof_constraints
Data structure containing DOF constraints.
Definition: dof_map.h:2033
std::vector< std::unique_ptr< DirichletBoundaries > > _adjoint_dirichlet_boundaries
Data structure containing Dirichlet functions.
Definition: dof_map.h:2067
std::unique_ptr< PeriodicBoundaries > _periodic_boundaries
Data structure containing periodic boundaries.
Definition: dof_map.h:2053
void max(const T &r, T &o, Request &req) const
bool _verify_dirichlet_bc_consistency
Flag which determines whether we should do some additional checking of the consistency of the Dirichl...
Definition: dof_map.h:2089
DofConstraintValueMap _primal_constraint_values
Definition: dof_map.h:2035
unsigned int mesh_dimension() const
Definition: mesh_base.C:324
virtual dof_id_type n_elem() const =0
auto index_range(const T &sizable)
Helper function that returns an IntRange<std::size_t> representing all the indices of the passed-in v...
Definition: int_range.h:111
NodeConstraints _node_constraints
Data structure containing DofObject constraints.
Definition: dof_map.h:2044

◆ default_algebraic_ghosting()

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

Default algebraic ghosting functor.

Definition at line 418 of file dof_map.h.

References _default_evaluating.

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

418 { return *_default_evaluating; }
std::unique_ptr< DefaultCoupling > _default_evaluating
The default algebraic GhostingFunctor, used to implement standard libMesh send_list construction...
Definition: dof_map.h:1944

◆ default_coupling()

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

Default coupling functor.

Definition at line 356 of file dof_map.h.

References _default_coupling.

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

356 { return *_default_coupling; }
std::unique_ptr< DefaultCoupling > _default_coupling
The default coupling GhostingFunctor, used to implement standard libMesh sparsity pattern constructio...
Definition: dof_map.h:1936

◆ disable_print_counter_info()

void libMesh::ReferenceCounter::disable_print_counter_info ( )
staticinherited

Definition at line 100 of file reference_counter.C.

References libMesh::ReferenceCounter::_enable_print_counter.

101 {
102  _enable_print_counter = false;
103  return;
104 }
static bool _enable_print_counter
Flag to control whether reference count information is printed when print_info is called...

◆ distribute_dofs()

std::size_t 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.

Returns
The total number of DOFs for the System, summed across all procs.

Definition at line 927 of file dof_map.C.

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(), TIMPI::Communicator::allgather(), clear_send_list(), libMesh::ParallelObject::comm(), distribute_local_dofs_node_major(), distribute_local_dofs_var_major(), libMesh::DofObject::dof_number(), elem_ptr(), end_dof(), first_dof(), libMesh::OrderWrapper::get_order(), libMesh::DofObject::invalid_id, invalidate_dofs(), libMesh::libmesh_assert(), libMesh::MeshTools::libmesh_assert_valid_dof_ids(), libMesh::make_range(), mesh, libMesh::DofObject::n_comp(), n_dofs(), libMesh::ParallelObject::n_processors(), n_SCALAR_dofs(), n_variables(), libMesh::DofObject::n_vars(), node_ptr(), 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().

928 {
929  // This function must be run on all processors at once
930  parallel_object_only();
931 
932  // Log how long it takes to distribute the degrees of freedom
933  LOG_SCOPE("distribute_dofs()", "DofMap");
934 
935  libmesh_assert (mesh.is_prepared());
936 
937  const processor_id_type proc_id = this->processor_id();
938  const processor_id_type n_proc = this->n_processors();
939 
940  // libmesh_assert_greater (this->n_variables(), 0);
941  libmesh_assert_less (proc_id, n_proc);
942 
943  // re-init in case the mesh has changed
944  this->reinit(mesh);
945 
946  // By default distribute variables in a
947  // var-major fashion, but allow run-time
948  // specification
949  bool node_major_dofs = libMesh::on_command_line ("--node-major-dofs");
950 
951  // The DOF counter, will be incremented as we encounter
952  // new degrees of freedom
953  dof_id_type next_free_dof = 0;
954 
955  // Clear the send list before we rebuild it
956  this->clear_send_list();
957 
958  // Set temporary DOF indices on this processor
959  if (node_major_dofs)
960  this->distribute_local_dofs_node_major (next_free_dof, mesh);
961  else
962  this->distribute_local_dofs_var_major (next_free_dof, mesh);
963 
964  // Get DOF counts on all processors
965  std::vector<dof_id_type> dofs_on_proc(n_proc, 0);
966  this->comm().allgather(next_free_dof, dofs_on_proc);
967 
968  // Resize and fill the _first_df and _end_df arrays
969 #ifdef LIBMESH_ENABLE_AMR
972 #endif
973 
974  _first_df.resize(n_proc);
975  _end_df.resize (n_proc);
976 
977  // Get DOF offsets
978  _first_df[0] = 0;
979  for (processor_id_type i=1; i < n_proc; ++i)
980  _first_df[i] = _end_df[i-1] = _first_df[i-1] + dofs_on_proc[i-1];
981  _end_df[n_proc-1] = _first_df[n_proc-1] + dofs_on_proc[n_proc-1];
982 
983  // Clear all the current DOF indices
984  // (distribute_dofs expects them cleared!)
985  this->invalidate_dofs(mesh);
986 
987  next_free_dof = _first_df[proc_id];
988 
989  // Set permanent DOF indices on this processor
990  if (node_major_dofs)
991  this->distribute_local_dofs_node_major (next_free_dof, mesh);
992  else
993  this->distribute_local_dofs_var_major (next_free_dof, mesh);
994 
995  libmesh_assert_equal_to (next_free_dof, _end_df[proc_id]);
996 
997  //------------------------------------------------------------
998  // At this point, all n_comp and dof_number values on local
999  // DofObjects should be correct, but a DistributedMesh might have
1000  // incorrect values on non-local DofObjects. Let's request the
1001  // correct values from each other processor.
1002 
1003  if (this->n_processors() > 1)
1004  {
1005  this->set_nonlocal_dof_objects(mesh.nodes_begin(),
1006  mesh.nodes_end(),
1008 
1009  this->set_nonlocal_dof_objects(mesh.elements_begin(),
1010  mesh.elements_end(),
1012  }
1013 
1014 #ifdef DEBUG
1015  {
1016  const unsigned int
1017  sys_num = this->sys_number();
1018 
1019  // Processors should all agree on DoF ids for the newly numbered
1020  // system.
1022 
1023  // DoF processor ids should match DofObject processor ids
1024  for (auto & node : mesh.node_ptr_range())
1025  {
1026  DofObject const * const dofobj = node;
1027  const processor_id_type obj_proc_id = dofobj->processor_id();
1028 
1029  for (auto v : make_range(dofobj->n_vars(sys_num)))
1030  for (auto c : make_range(dofobj->n_comp(sys_num,v)))
1031  {
1032  const dof_id_type dofid = dofobj->dof_number(sys_num,v,c);
1033  libmesh_assert_greater_equal (dofid, this->first_dof(obj_proc_id));
1034  libmesh_assert_less (dofid, this->end_dof(obj_proc_id));
1035  }
1036  }
1037 
1038  for (auto & elem : mesh.element_ptr_range())
1039  {
1040  DofObject const * const dofobj = elem;
1041  const processor_id_type obj_proc_id = dofobj->processor_id();
1042 
1043  for (auto v : make_range(dofobj->n_vars(sys_num)))
1044  for (auto c : make_range(dofobj->n_comp(sys_num,v)))
1045  {
1046  const dof_id_type dofid = dofobj->dof_number(sys_num,v,c);
1047  libmesh_assert_greater_equal (dofid, this->first_dof(obj_proc_id));
1048  libmesh_assert_less (dofid, this->end_dof(obj_proc_id));
1049  }
1050  }
1051  }
1052 #endif
1053 
1054  // Set the total number of degrees of freedom, then start finding
1055  // SCALAR degrees of freedom
1056 #ifdef LIBMESH_ENABLE_AMR
1057  _n_old_dfs = _n_dfs;
1059 #endif
1060  _n_dfs = _end_df[n_proc-1];
1061  _first_scalar_df.clear();
1063  dof_id_type current_SCALAR_dof_index = n_dofs() - n_SCALAR_dofs();
1064 
1065  // Calculate and cache the initial DoF indices for SCALAR variables.
1066  // This is an O(N_vars) calculation so we want to do it once per
1067  // renumbering rather than once per SCALAR_dof_indices() call
1068 
1069  for (auto v : make_range(this->n_variables()))
1070  if (this->variable(v).type().family == SCALAR)
1071  {
1072  _first_scalar_df[v] = current_SCALAR_dof_index;
1073  current_SCALAR_dof_index += this->variable(v).type().order.get_order();
1074  }
1075 
1076  // Allow our GhostingFunctor objects to reinit if necessary
1077  for (const auto & gf : _algebraic_ghosting_functors)
1078  {
1079  libmesh_assert(gf);
1080  gf->dofmap_reinit();
1081  }
1082 
1083  for (const auto & gf : _coupling_functors)
1084  {
1085  libmesh_assert(gf);
1086  gf->dofmap_reinit();
1087  }
1088 
1089  // Note that in the add_neighbors_to_send_list nodes on processor
1090  // boundaries that are shared by multiple elements are added for
1091  // each element.
1093 
1094  // Here we used to clean up that data structure; now System and
1095  // EquationSystems call that for us, after we've added constraint
1096  // dependencies to the send_list too.
1097  // this->sort_send_list ();
1098 
1099  // Return total number of DOFs across all procs. We compute and
1100  // return this as a std::size_t so that we can detect situations in
1101  // which the total number of DOFs across all procs would exceed the
1102  // capability of the underlying NumericVector representation to
1103  // index into it correctly (std::size_t is the largest unsigned
1104  // type, so no NumericVector representation can exceed it).
1105  return std::accumulate(dofs_on_proc.begin(), dofs_on_proc.end(), static_cast<std::size_t>(0));
1106 }
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:1196
void allgather(const T &send_data, std::vector< T, A > &recv_data) const
dof_id_type n_SCALAR_dofs() const
Definition: dof_map.h:664
void clear_send_list()
Clears the _send_list vector.
Definition: dof_map.h:485
MeshBase & mesh
unsigned int n_variables() const
Definition: dof_map.h:621
const Parallel::Communicator & comm() const
std::set< GhostingFunctor * > _algebraic_ghosting_functors
The list of all GhostingFunctor objects to be used when distributing ghosted vectors.
Definition: dof_map.h:1954
std::vector< dof_id_type > _end_old_df
Last old DOF index (plus 1) on processor p.
Definition: dof_map.h:2014
OrderWrapper order
The approximation order of the element.
Definition: fe_type.h:201
std::vector< dof_id_type > _first_old_df
First old DOF index on processor p.
Definition: dof_map.h:2009
unsigned int sys_number() const
Definition: dof_map.h:2096
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:1890
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:1704
uint8_t processor_id_type
processor_id_type n_processors() const
dof_id_type n_dofs() const
Definition: dof_map.h:659
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:1544
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:2020
const Variable & variable(const unsigned int c) const
Definition: dof_map.h:2114
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:356
libmesh_assert(ctx)
static const dof_id_type invalid_id
An invalid id to distinguish an uninitialized DofObject.
Definition: dof_object.h:477
void reinit(MeshBase &mesh)
Reinitialize the underlying data structures conformal to the current mesh.
Definition: dof_map.C:506
dof_id_type end_dof() const
Definition: dof_map.h:711
int get_order() const
Explicitly request the order as an int.
Definition: fe_type.h:80
DofObject * elem_ptr(MeshBase &mesh, dof_id_type i) const
Definition: dof_map.C:348
void invalidate_dofs(MeshBase &mesh) const
Invalidates all active DofObject dofs for this system.
Definition: dof_map.C:835
dof_id_type first_dof() const
Definition: dof_map.h:687
IntRange< T > make_range(T beg, T end)
The 2-parameter make_range() helper function returns an IntRange<T> when both input parameters are of...
Definition: int_range.h:134
dof_id_type _n_old_dfs
Total number of degrees of freedom on old dof objects.
Definition: dof_map.h:2004
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:1967
std::vector< dof_id_type > _end_df
Last DOF index (plus 1) on processor p.
Definition: dof_map.h:1884
std::vector< dof_id_type > _first_df
First DOF index on processor p.
Definition: dof_map.h:1879
DofObject * node_ptr(MeshBase &mesh, dof_id_type i) const
Definition: dof_map.C:341
bool on_command_line(std::string arg)
Definition: libmesh.C:924
processor_id_type processor_id() const
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:1299
uint8_t dof_id_type
Definition: id_types.h:67
dof_id_type _n_dfs
Total number of degrees of freedom.
Definition: dof_map.h:1991
const FEType & type() const
Definition: variable.h:140

◆ 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 1196 of file dof_map.C.

References libMesh::Variable::active_on_subdomain(), assert_no_nodes_missed(), distribute_scalar_dofs(), libMesh::FEType::family, libMesh::DofObject::invalid_id, mesh, libMesh::DofObject::n_comp_group(), n_nodes, n_variable_groups(), libMesh::VariableGroup::n_variables(), 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().

1198 {
1199  const unsigned int sys_num = this->sys_number();
1200  const unsigned int n_var_groups = this->n_variable_groups();
1201 
1202  // Our numbering here must be kept consistent with the numbering
1203  // scheme assumed by DofMap::local_variable_indices!
1204 
1205  //-------------------------------------------------------------------------
1206  // First count and assign temporary numbers to local dofs
1207  for (auto & elem : mesh.active_local_element_ptr_range())
1208  {
1209  // Only number dofs connected to active
1210  // elements on this processor.
1211  const unsigned int n_nodes = elem->n_nodes();
1212 
1213  // First number the nodal DOFS
1214  for (unsigned int n=0; n<n_nodes; n++)
1215  {
1216  Node & node = elem->node_ref(n);
1217 
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  {
1225  // assign dof numbers (all at once) if this is
1226  // our node and if they aren't already there
1227  if ((node.n_comp_group(sys_num,vg) > 0) &&
1228  (node.processor_id() == this->processor_id()) &&
1229  (node.vg_dof_base(sys_num,vg) ==
1231  {
1232  node.set_vg_dof_base(sys_num, vg,
1233  next_free_dof);
1234  next_free_dof += (vg_description.n_variables()*
1235  node.n_comp_group(sys_num,vg));
1236  //node.debug_buffer();
1237  }
1238  }
1239  }
1240  }
1241 
1242  // Now number the element DOFS
1243  for (unsigned vg=0; vg<n_var_groups; vg++)
1244  {
1245  const VariableGroup & vg_description(this->variable_group(vg));
1246 
1247  if ((vg_description.type().family != SCALAR) &&
1248  (vg_description.active_on_subdomain(elem->subdomain_id())))
1249  if (elem->n_comp_group(sys_num,vg) > 0)
1250  {
1251  libmesh_assert_equal_to (elem->vg_dof_base(sys_num,vg),
1253 
1254  elem->set_vg_dof_base(sys_num,
1255  vg,
1256  next_free_dof);
1257 
1258  next_free_dof += (vg_description.n_variables()*
1259  elem->n_comp(sys_num,vg));
1260  }
1261  }
1262  } // done looping over elements
1263 
1264 
1265  // we may have missed assigning DOFs to nodes that we own
1266  // but to which we have no connected elements matching our
1267  // variable restriction criterion. this will happen, for example,
1268  // if variable V is restricted to subdomain S. We may not own
1269  // any elements which live in S, but we may own nodes which are
1270  // *connected* to elements which do. in this scenario these nodes
1271  // will presently have unnumbered DOFs. we need to take care of
1272  // them here since we own them and no other processor will touch them.
1273  for (auto & node : mesh.local_node_ptr_range())
1274  for (unsigned vg=0; vg<n_var_groups; vg++)
1275  {
1276  const VariableGroup & vg_description(this->variable_group(vg));
1277 
1278  if (node->n_comp_group(sys_num,vg))
1279  if (node->vg_dof_base(sys_num,vg) == DofObject::invalid_id)
1280  {
1281  node->set_vg_dof_base (sys_num,
1282  vg,
1283  next_free_dof);
1284 
1285  next_free_dof += (vg_description.n_variables()*
1286  node->n_comp(sys_num,vg));
1287  }
1288  }
1289 
1290  this->distribute_scalar_dofs(next_free_dof);
1291 
1292 #ifdef DEBUG
1294 #endif // DEBUG
1295 }
unsigned int n_variable_groups() const
Definition: dof_map.h:613
MeshBase & mesh
unsigned int sys_number() const
Definition: dof_map.h:2096
const dof_id_type n_nodes
Definition: tecplot_io.C:67
void assert_no_nodes_missed(MeshBase &mesh)
Definition: dof_map.C:1418
static const dof_id_type invalid_id
An invalid id to distinguish an uninitialized DofObject.
Definition: dof_object.h:477
const VariableGroup & variable_group(const unsigned int c) const
Definition: dof_map.h:2104
void distribute_scalar_dofs(dof_id_type &next_free_dof)
Definition: dof_map.C:1394
processor_id_type processor_id() const

◆ 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 1299 of file dof_map.C.

References libMesh::Variable::active_on_subdomain(), assert_no_nodes_missed(), distribute_scalar_dofs(), libMesh::FEType::family, libMesh::DofObject::invalid_id, mesh, libMesh::DofObject::n_comp_group(), n_nodes, n_variable_groups(), libMesh::VariableGroup::n_variables(), 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().

1301 {
1302  const unsigned int sys_num = this->sys_number();
1303  const unsigned int n_var_groups = this->n_variable_groups();
1304 
1305  // Our numbering here must be kept consistent with the numbering
1306  // scheme assumed by DofMap::local_variable_indices!
1307 
1308  //-------------------------------------------------------------------------
1309  // First count and assign temporary numbers to local dofs
1310  for (unsigned vg=0; vg<n_var_groups; vg++)
1311  {
1312  const VariableGroup & vg_description(this->variable_group(vg));
1313 
1314  const unsigned int n_vars_in_group = vg_description.n_variables();
1315 
1316  // Skip the SCALAR dofs
1317  if (vg_description.type().family == SCALAR)
1318  continue;
1319 
1320  for (auto & elem : mesh.active_local_element_ptr_range())
1321  {
1322  // Only number dofs connected to active elements on this
1323  // processor and only variables which are active on on this
1324  // element's subdomain.
1325  if (!vg_description.active_on_subdomain(elem->subdomain_id()))
1326  continue;
1327 
1328  const unsigned int n_nodes = elem->n_nodes();
1329 
1330  // First number the nodal DOFS
1331  for (unsigned int n=0; n<n_nodes; n++)
1332  {
1333  Node & node = elem->node_ref(n);
1334 
1335  // assign dof numbers (all at once) if this is
1336  // our node and if they aren't already there
1337  if ((node.n_comp_group(sys_num,vg) > 0) &&
1338  (node.processor_id() == this->processor_id()) &&
1339  (node.vg_dof_base(sys_num,vg) ==
1341  {
1342  node.set_vg_dof_base(sys_num, vg, next_free_dof);
1343 
1344  next_free_dof += (n_vars_in_group*
1345  node.n_comp_group(sys_num,vg));
1346  }
1347  }
1348 
1349  // Now number the element DOFS
1350  if (elem->n_comp_group(sys_num,vg) > 0)
1351  {
1352  libmesh_assert_equal_to (elem->vg_dof_base(sys_num,vg),
1354 
1355  elem->set_vg_dof_base(sys_num,
1356  vg,
1357  next_free_dof);
1358 
1359  next_free_dof += (n_vars_in_group*
1360  elem->n_comp_group(sys_num,vg));
1361  }
1362  } // end loop on elements
1363 
1364  // we may have missed assigning DOFs to nodes that we own
1365  // but to which we have no connected elements matching our
1366  // variable restriction criterion. this will happen, for example,
1367  // if variable V is restricted to subdomain S. We may not own
1368  // any elements which live in S, but we may own nodes which are
1369  // *connected* to elements which do. in this scenario these nodes
1370  // will presently have unnumbered DOFs. we need to take care of
1371  // them here since we own them and no other processor will touch them.
1372  for (auto & node : mesh.local_node_ptr_range())
1373  if (node->n_comp_group(sys_num,vg))
1374  if (node->vg_dof_base(sys_num,vg) == DofObject::invalid_id)
1375  {
1376  node->set_vg_dof_base (sys_num,
1377  vg,
1378  next_free_dof);
1379 
1380  next_free_dof += (n_vars_in_group*
1381  node->n_comp_group(sys_num,vg));
1382  }
1383  } // end loop on variable groups
1384 
1385  this->distribute_scalar_dofs(next_free_dof);
1386 
1387 #ifdef DEBUG
1389 #endif
1390 }
unsigned int n_variable_groups() const
Definition: dof_map.h:613
MeshBase & mesh
unsigned int sys_number() const
Definition: dof_map.h:2096
const dof_id_type n_nodes
Definition: tecplot_io.C:67
void assert_no_nodes_missed(MeshBase &mesh)
Definition: dof_map.C:1418
static const dof_id_type invalid_id
An invalid id to distinguish an uninitialized DofObject.
Definition: dof_object.h:477
const VariableGroup & variable_group(const unsigned int c) const
Definition: dof_map.h:2104
void distribute_scalar_dofs(dof_id_type &next_free_dof)
Definition: dof_map.C:1394
processor_id_type processor_id() const

◆ distribute_scalar_dofs()

void libMesh::DofMap::distribute_scalar_dofs ( dof_id_type next_free_dof)
private

Definition at line 1394 of file dof_map.C.

References _n_SCALAR_dofs, libMesh::FEType::family, libMesh::OrderWrapper::get_order(), libMesh::make_range(), libMesh::ParallelObject::n_processors(), n_variable_groups(), libMesh::VariableGroup::n_variables(), libMesh::FEType::order, libMesh::ParallelObject::processor_id(), libMesh::SCALAR, libMesh::Variable::type(), and variable_group().

Referenced by distribute_local_dofs_node_major(), and distribute_local_dofs_var_major().

1395 {
1396  this->_n_SCALAR_dofs = 0;
1397  for (auto vg : make_range(this->n_variable_groups()))
1398  {
1399  const VariableGroup & vg_description(this->variable_group(vg));
1400 
1401  if (vg_description.type().family == SCALAR)
1402  {
1403  this->_n_SCALAR_dofs += (vg_description.n_variables()*
1404  vg_description.type().order.get_order());
1405  continue;
1406  }
1407  }
1408 
1409  // Only increment next_free_dof if we're on the processor
1410  // that holds this SCALAR variable
1411  if (this->processor_id() == (this->n_processors()-1))
1412  next_free_dof += _n_SCALAR_dofs;
1413 }
unsigned int n_variable_groups() const
Definition: dof_map.h:613
processor_id_type n_processors() const
dof_id_type _n_SCALAR_dofs
The total number of SCALAR dofs associated to all SCALAR variables.
Definition: dof_map.h:1997
const VariableGroup & variable_group(const unsigned int c) const
Definition: dof_map.h:2104
IntRange< T > make_range(T beg, T end)
The 2-parameter make_range() helper function returns an IntRange<T> when both input parameters are of...
Definition: int_range.h:134
processor_id_type processor_id() const

◆ dof_indices() [1/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 1992 of file dof_map.C.

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(), libMesh::MeshFunction::_gradient_on_elem(), add_neighbors_to_send_list(), libMesh::HPCoarsenTest::add_projection(), assemble(), LinearElasticity::assemble(), HDGProblem::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_parallel_elemental_solution_vector(), libMesh::EquationSystems::build_parallel_solution_vector(), libMesh::System::calculate_norm(), libMesh::FEGenericBase< FEOutputType< T >::type >::coarsened_dof_values(), compute_enriched_soln(), compute_jacobian(), libMesh::FEGenericBase< FEOutputType< T >::type >::compute_periodic_constraints(), libMesh::FEGenericBase< FEOutputType< T >::type >::compute_proj_constraints(), compute_residual(), compute_stresses(), LinearElasticityWithContact::compute_stresses(), LinearElasticity::compute_stresses(), LargeDeformationElasticity::compute_stresses(), libMesh::MeshFunction::discontinuous_value(), DMCreateDomainDecomposition_libMesh(), DMCreateFieldDecomposition_libMesh(), dof_indices(), libMesh::AdjointRefinementEstimator::estimate_error(), libMesh::ExactErrorEstimator::estimate_error(), libMesh::DTKEvaluator::evaluate(), libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::SubFunctor::find_dofs_to_send(), libMesh::MeshFunction::hessian(), libMesh::InfFE< Dim, T_radial, T_map >::inf_compute_constraints(), libMesh::SystemSubsetBySubdomain::init(), 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(), process_mesh_constraint_rows(), LargeDeformationElasticity::residual(), Biharmonic::JR::residual_and_jacobian(), LinearElasticityWithContact::residual_and_jacobian(), scatter_constraints(), libMesh::HPCoarsenTest::select_refinement(), libMesh::PetscDMWrapper::set_point_range_in_section(), FETestBase< order, family, elem_type, 1 >::setUp(), SolidSystem::side_time_derivative(), libMesh::SparsityPattern::Build::sorted_connected_dofs(), MixedDimensionMeshTest::testDofOrdering(), MixedDimensionRefinedMeshTest::testDofOrdering(), MixedDimensionNonUniformRefinement::testDofOrdering(), MixedDimensionNonUniformRefinementTriangle::testDofOrdering(), MixedDimensionNonUniformRefinement3D::testDofOrdering(), MeshInputTest::testExodusWriteElementDataFromDiscontinuousNodalData(), InfFERadialTest::testRefinement(), BoundaryInfoTest::testShellFaceConstraints(), libMesh::BoundaryVolumeSolutionTransfer::transfer_boundary_volume(), libMesh::Nemesis_IO_Helper::write_nodal_solution(), libMesh::EnsightIO::write_scalar_ascii(), and libMesh::EnsightIO::write_vector_ascii().

1994 {
1995  // We now allow elem==nullptr to request just SCALAR dofs
1996  // libmesh_assert(elem);
1997 
1998  // If we are asking for current indices on an element, it ought to
1999  // be an active element (or a Side proxy, which also thinks it's
2000  // active)
2001  libmesh_assert(!elem || elem->active());
2002 
2003  LOG_SCOPE("dof_indices()", "DofMap");
2004 
2005  // Clear the DOF indices vector
2006  di.clear();
2007 
2008  const unsigned int n_var_groups = this->n_variable_groups();
2009 
2010 #ifdef DEBUG
2011  // Check that sizes match in DEBUG mode
2012  std::size_t tot_size = 0;
2013 #endif
2014 
2015  if (elem && elem->type() == TRI3SUBDIVISION)
2016  {
2017  // Subdivision surface FE require the 1-ring around elem
2018  const Tri3Subdivision * sd_elem = static_cast<const Tri3Subdivision *>(elem);
2019 
2020  // Ghost subdivision elements have no real dofs
2021  if (!sd_elem->is_ghost())
2022  {
2023  // Determine the nodes contributing to element elem
2024  std::vector<const Node *> elem_nodes;
2025  MeshTools::Subdivision::find_one_ring(sd_elem, elem_nodes);
2026 
2027  // Get the dof numbers
2028  for (unsigned int vg=0; vg<n_var_groups; vg++)
2029  {
2030  const VariableGroup & var = this->variable_group(vg);
2031  const unsigned int vars_in_group = var.n_variables();
2032 
2033  if (var.type().family == SCALAR &&
2034  var.active_on_subdomain(elem->subdomain_id()))
2035  {
2036  for (unsigned int vig=0; vig != vars_in_group; ++vig)
2037  {
2038 #ifdef DEBUG
2039  tot_size += var.type().order;
2040 #endif
2041  std::vector<dof_id_type> di_new;
2042  this->SCALAR_dof_indices(di_new,var.number(vig));
2043  di.insert( di.end(), di_new.begin(), di_new.end());
2044  }
2045  }
2046  else
2047  for (unsigned int vig=0; vig != vars_in_group; ++vig)
2048  {
2049  _dof_indices(*elem, elem->p_level(), di, vg, vig,
2050  elem_nodes.data(),
2051  cast_int<unsigned int>(elem_nodes.size())
2052 #ifdef DEBUG
2053  , var.number(vig), tot_size
2054 #endif
2055  );
2056  }
2057  }
2058  }
2059 
2060  return;
2061  }
2062 
2063  // Get the dof numbers for each variable
2064  const unsigned int n_nodes = elem ? elem->n_nodes() : 0;
2065  for (unsigned int vg=0; vg<n_var_groups; vg++)
2066  {
2067  const VariableGroup & var = this->variable_group(vg);
2068  const unsigned int vars_in_group = var.n_variables();
2069 
2070  if (var.type().family == SCALAR &&
2071  (!elem ||
2072  var.active_on_subdomain(elem->subdomain_id())))
2073  {
2074  for (unsigned int vig=0; vig != vars_in_group; ++vig)
2075  {
2076 #ifdef DEBUG
2077  tot_size += var.type().order;
2078 #endif
2079  std::vector<dof_id_type> di_new;
2080  this->SCALAR_dof_indices(di_new,var.number(vig));
2081  di.insert( di.end(), di_new.begin(), di_new.end());
2082  }
2083  }
2084  else if (elem)
2085  for (unsigned int vig=0; vig != vars_in_group; ++vig)
2086  {
2087  _dof_indices(*elem, elem->p_level(), di, vg, vig,
2088  elem->get_nodes(), n_nodes
2089 #ifdef DEBUG
2090  , var.number(vig), tot_size
2091 #endif
2092  );
2093  }
2094  }
2095 
2096 #ifdef DEBUG
2097  libmesh_assert_equal_to (tot_size, di.size());
2098 #endif
2099 }
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:2381
unsigned int n_variable_groups() const
Definition: dof_map.h:613
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:2544
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.
const dof_id_type n_nodes
Definition: tecplot_io.C:67
libmesh_assert(ctx)
const VariableGroup & variable_group(const unsigned int c) const
Definition: dof_map.h:2104

◆ dof_indices() [2/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 2102 of file dof_map.C.

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().

2106 {
2107  // We now allow elem==nullptr to request just SCALAR dofs
2108  // libmesh_assert(elem);
2109 
2110  LOG_SCOPE("dof_indices()", "DofMap");
2111 
2112  // Clear the DOF indices vector
2113  di.clear();
2114 
2115  // Use the default p refinement level?
2116  if (p_level == -12345)
2117  p_level = elem ? elem->p_level() : 0;
2118 
2119  const unsigned int vg = this->_variable_group_numbers[vn];
2120  const VariableGroup & var = this->variable_group(vg);
2121  const unsigned int vig = vn - var.number();
2122 
2123 #ifdef DEBUG
2124  // Check that sizes match in DEBUG mode
2125  std::size_t tot_size = 0;
2126 #endif
2127 
2128  if (elem && elem->type() == TRI3SUBDIVISION)
2129  {
2130  // Subdivision surface FE require the 1-ring around elem
2131  const Tri3Subdivision * sd_elem = static_cast<const Tri3Subdivision *>(elem);
2132 
2133  // Ghost subdivision elements have no real dofs
2134  if (!sd_elem->is_ghost())
2135  {
2136  // Determine the nodes contributing to element elem
2137  std::vector<const Node *> elem_nodes;
2138  MeshTools::Subdivision::find_one_ring(sd_elem, elem_nodes);
2139 
2140  _dof_indices(*elem, p_level, di, vg, vig, elem_nodes.data(),
2141  cast_int<unsigned int>(elem_nodes.size())
2142 #ifdef DEBUG
2143  , vn, tot_size
2144 #endif
2145  );
2146  }
2147 
2148  return;
2149  }
2150 
2151  // Get the dof numbers
2152  if (var.type().family == SCALAR &&
2153  (!elem ||
2154  var.active_on_subdomain(elem->subdomain_id())))
2155  {
2156 #ifdef DEBUG
2157  tot_size += var.type().order;
2158 #endif
2159  std::vector<dof_id_type> di_new;
2160  this->SCALAR_dof_indices(di_new,vn);
2161  di.insert( di.end(), di_new.begin(), di_new.end());
2162  }
2163  else if (elem)
2164  _dof_indices(*elem, p_level, di, vg, vig, elem->get_nodes(),
2165  elem->n_nodes()
2166 #ifdef DEBUG
2167  , vn, tot_size
2168 #endif
2169  );
2170 
2171 #ifdef DEBUG
2172  libmesh_assert_equal_to (tot_size, di.size());
2173 #endif
2174 }
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:2381
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:2544
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.
const VariableGroup & variable_group(const unsigned int c) const
Definition: dof_map.h:2104
std::vector< unsigned int > _variable_group_numbers
The variable group number for each variable.
Definition: dof_map.h:1852

◆ dof_indices() [3/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 2177 of file dof_map.C.

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().

2179 {
2180  // We allow node==nullptr to request just SCALAR dofs
2181  // libmesh_assert(elem);
2182 
2183  LOG_SCOPE("dof_indices(Node)", "DofMap");
2184 
2185  // Clear the DOF indices vector
2186  di.clear();
2187 
2188  const unsigned int n_var_groups = this->n_variable_groups();
2189  const unsigned int sys_num = this->sys_number();
2190 
2191  // Get the dof numbers
2192  for (unsigned int vg=0; vg<n_var_groups; vg++)
2193  {
2194  const VariableGroup & var = this->variable_group(vg);
2195  const unsigned int vars_in_group = var.n_variables();
2196 
2197  if (var.type().family == SCALAR)
2198  {
2199  for (unsigned int vig=0; vig != vars_in_group; ++vig)
2200  {
2201  std::vector<dof_id_type> di_new;
2202  this->SCALAR_dof_indices(di_new,var.number(vig));
2203  di.insert( di.end(), di_new.begin(), di_new.end());
2204  }
2205  }
2206  else
2207  {
2208  const int n_comp = node->n_comp_group(sys_num,vg);
2209  for (unsigned int vig=0; vig != vars_in_group; ++vig)
2210  {
2211  for (int i=0; i != n_comp; ++i)
2212  {
2213  const dof_id_type d =
2214  node->dof_number(sys_num, vg, vig, i, n_comp);
2215  libmesh_assert_not_equal_to
2216  (d, DofObject::invalid_id);
2217  di.push_back(d);
2218  }
2219  }
2220  }
2221  }
2222 }
unsigned int n_variable_groups() const
Definition: dof_map.h:613
unsigned int sys_number() const
Definition: dof_map.h:2096
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:2544
static const dof_id_type invalid_id
An invalid id to distinguish an uninitialized DofObject.
Definition: dof_object.h:477
const VariableGroup & variable_group(const unsigned int c) const
Definition: dof_map.h:2104
uint8_t dof_id_type
Definition: id_types.h:67

◆ dof_indices() [4/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 2225 of file dof_map.C.

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().

2228 {
2229  if (vn == libMesh::invalid_uint)
2230  {
2231  this->dof_indices(node, di);
2232  return;
2233  }
2234 
2235  // We allow node==nullptr to request just SCALAR dofs
2236  // libmesh_assert(elem);
2237 
2238  LOG_SCOPE("dof_indices(Node)", "DofMap");
2239 
2240  // Clear the DOF indices vector
2241  di.clear();
2242 
2243  const unsigned int sys_num = this->sys_number();
2244 
2245  // Get the dof numbers
2246  const unsigned int vg = this->_variable_group_numbers[vn];
2247  const VariableGroup & var = this->variable_group(vg);
2248 
2249  if (var.type().family == SCALAR)
2250  {
2251  std::vector<dof_id_type> di_new;
2252  this->SCALAR_dof_indices(di_new,vn);
2253  di.insert( di.end(), di_new.begin(), di_new.end());
2254  }
2255  else
2256  {
2257  const unsigned int vig = vn - var.number();
2258  const int n_comp = node->n_comp_group(sys_num,vg);
2259  for (int i=0; i != n_comp; ++i)
2260  {
2261  const dof_id_type d =
2262  node->dof_number(sys_num, vg, vig, i, n_comp);
2263  libmesh_assert_not_equal_to
2264  (d, DofObject::invalid_id);
2265  di.push_back(d);
2266  }
2267  }
2268 }
const unsigned int invalid_uint
A number which is used quite often to represent an invalid or uninitialized value for an unsigned int...
Definition: libmesh.h:286
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:1992
unsigned int sys_number() const
Definition: dof_map.h:2096
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:2544
static const dof_id_type invalid_id
An invalid id to distinguish an uninitialized DofObject.
Definition: dof_object.h:477
const VariableGroup & variable_group(const unsigned int c) const
Definition: dof_map.h:2104
std::vector< unsigned int > _variable_group_numbers
The variable group number for each variable.
Definition: dof_map.h:1852
uint8_t dof_id_type
Definition: id_types.h:67

◆ dof_indices() [5/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 2271 of file dof_map.C.

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

2275 {
2276  this->_node_dof_indices(elem, n, elem.node_ref(n), di, vn);
2277 }
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:2296

◆ 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 717 of file dof_map.h.

References _end_df, and libMesh::libmesh_assert().

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

718  { std::vector<dof_id_type>::const_iterator ub =
719  std::upper_bound(_end_df.begin(), _end_df.end(), dof);
720  libmesh_assert (ub != _end_df.end());
721  return cast_int<processor_id_type>(ub - _end_df.begin());
722  }
libmesh_assert(ctx)
std::vector< dof_id_type > _end_df
Last DOF index (plus 1) on processor p.
Definition: dof_map.h:1884

◆ 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 348 of file dof_map.C.

References mesh.

Referenced by distribute_dofs().

349 {
350  return mesh.elem_ptr(i);
351 }
MeshBase & mesh

◆ 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 94 of file reference_counter.C.

References libMesh::ReferenceCounter::_enable_print_counter.

95 {
96  _enable_print_counter = true;
97  return;
98 }
static bool _enable_print_counter
Flag to control whether reference count information is printed when print_info is called...

◆ end_dof() [1/2]

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

◆ end_dof() [2/2]

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

Definition at line 711 of file dof_map.h.

References libMesh::ParallelObject::processor_id().

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

712  { return this->end_dof(this->processor_id()); }
dof_id_type end_dof() const
Definition: dof_map.h:711
processor_id_type processor_id() const

◆ end_old_dof() [1/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 731 of file dof_map.h.

References _end_old_df.

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

732  { libmesh_assert_less (proc, _end_old_df.size()); return _end_old_df[proc]; }
std::vector< dof_id_type > _end_old_df
Last old DOF index (plus 1) on processor p.
Definition: dof_map.h:2014

◆ end_old_dof() [2/2]

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

Definition at line 734 of file dof_map.h.

References libMesh::ParallelObject::processor_id().

735  { return this->end_old_dof(this->processor_id()); }
dof_id_type end_old_dof() const
Definition: dof_map.h:734
processor_id_type processor_id() const

◆ enforce_adjoint_constraints_exactly()

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

Heterogeneously 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 2278 of file dof_map.h.

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

2279  {}

◆ 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 2274 of file dof_map.h.

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(), main(), 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().

2276  {}

◆ enforce_constraints_on_jacobian()

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

Definition at line 2289 of file dof_map.h.

Referenced by libMesh::libmesh_petsc_snes_jacobian(), and libMesh::libmesh_petsc_snes_residual().

2290  {}

◆ 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 1910 of file dof_map.C.

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().

1913 {
1914  const unsigned int n_original_dofs = dof_indices_in.size();
1915 
1916 #ifdef LIBMESH_ENABLE_AMR
1917 
1918  // Trivial mapping
1919  libmesh_assert_equal_to (dof_indices_in.size(), Ue.size());
1920  bool has_constrained_dofs = false;
1921 
1922  for (unsigned int il=0; il != n_original_dofs; ++il)
1923  {
1924  const dof_id_type ig = dof_indices_in[il];
1925 
1926  if (this->is_constrained_dof (ig)) has_constrained_dofs = true;
1927 
1928  libmesh_assert_less (ig, Ug.size());
1929 
1930  Ue.el(il) = Ug(ig);
1931  }
1932 
1933  // If the element has any constrained DOFs then we need
1934  // to account for them in the mapping. This will handle
1935  // the case that the input vector is not constrained.
1936  if (has_constrained_dofs)
1937  {
1938  // Copy the input DOF indices.
1939  std::vector<dof_id_type> constrained_dof_indices(dof_indices_in);
1940 
1941  DenseMatrix<Number> C;
1942  DenseVector<Number> H;
1943 
1944  this->build_constraint_matrix_and_vector (C, H, constrained_dof_indices);
1945 
1946  libmesh_assert_equal_to (dof_indices_in.size(), C.m());
1947  libmesh_assert_equal_to (constrained_dof_indices.size(), C.n());
1948 
1949  // zero-out Ue
1950  Ue.zero();
1951 
1952  // compute Ue = C Ug, with proper mapping.
1953  for (unsigned int i=0; i != n_original_dofs; i++)
1954  {
1955  Ue.el(i) = H(i);
1956 
1957  const unsigned int n_constrained =
1958  cast_int<unsigned int>(constrained_dof_indices.size());
1959  for (unsigned int j=0; j<n_constrained; j++)
1960  {
1961  const dof_id_type jg = constrained_dof_indices[j];
1962 
1963  // If Ug is a serial or ghosted vector, then this assert is
1964  // overzealous. If Ug is a parallel vector, then this assert
1965  // is redundant.
1966  // libmesh_assert ((jg >= Ug.first_local_index()) &&
1967  // (jg < Ug.last_local_index()));
1968 
1969  Ue.el(i) += C(i,j)*Ug(jg);
1970  }
1971  }
1972  }
1973 
1974 #else
1975 
1976  // Trivial mapping
1977 
1978  libmesh_assert_equal_to (n_original_dofs, Ue.size());
1979 
1980  for (unsigned int il=0; il<n_original_dofs; il++)
1981  {
1982  const dof_id_type ig = dof_indices_in[il];
1983 
1984  libmesh_assert ((ig >= Ug.first_local_index()) && (ig < Ug.last_local_index()));
1985 
1986  Ue.el(il) = Ug(ig);
1987  }
1988 
1989 #endif
1990 }
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 ...
virtual numeric_index_type size() const =0
libmesh_assert(ctx)
bool is_constrained_dof(const dof_id_type dof) const
Definition: dof_map.h:2182
virtual numeric_index_type first_local_index() const =0
virtual numeric_index_type last_local_index() const =0
uint8_t dof_id_type
Definition: id_types.h:67

◆ 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 2852 of file dof_map.C.

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

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

2853 {
2854  typedef std::set<dof_id_type> RCSet;
2855 
2856  // First insert the DOFS we already depend on into the set.
2857  RCSet dof_set (elem_dofs.begin(), elem_dofs.end());
2858 
2859  bool done = true;
2860 
2861  // Next insert any dofs those might be constrained in terms
2862  // of. Note that in this case we may not be done: Those may
2863  // in turn depend on others. So, we need to repeat this process
2864  // in that case until the system depends only on unconstrained
2865  // degrees of freedom.
2866  for (const auto & dof : elem_dofs)
2867  if (this->is_constrained_dof(dof))
2868  {
2869  // If the DOF is constrained
2870  DofConstraints::const_iterator
2871  pos = _dof_constraints.find(dof);
2872 
2873  libmesh_assert (pos != _dof_constraints.end());
2874 
2875  const DofConstraintRow & constraint_row = pos->second;
2876 
2877  // adaptive p refinement currently gives us lots of empty constraint
2878  // rows - we should optimize those DoFs away in the future. [RHS]
2879  //libmesh_assert (!constraint_row.empty());
2880 
2881  // Add the DOFs this dof is constrained in terms of.
2882  // note that these dofs might also be constrained, so
2883  // we will need to call this function recursively.
2884  for (const auto & pr : constraint_row)
2885  if (!dof_set.count (pr.first))
2886  {
2887  dof_set.insert (pr.first);
2888  done = false;
2889  }
2890  }
2891 
2892 
2893  // If not done then we need to do more work
2894  // (obviously :-) )!
2895  if (!done)
2896  {
2897  // Fill the vector with the contents of the set
2898  elem_dofs.clear();
2899  elem_dofs.insert (elem_dofs.end(),
2900  dof_set.begin(), dof_set.end());
2901 
2902 
2903  // May need to do this recursively. It is possible
2904  // that we just replaced a constrained DOF with another
2905  // constrained DOF.
2906  this->find_connected_dofs (elem_dofs);
2907 
2908  } // end if (!done)
2909 }
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:2852
libmesh_assert(ctx)
bool is_constrained_dof(const dof_id_type dof) const
Definition: dof_map.h:2182
DofConstraints _dof_constraints
Data structure containing DOF constraints.
Definition: dof_map.h:2033
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:90

◆ first_dof() [1/2]

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

◆ first_dof() [2/2]

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

Definition at line 687 of file dof_map.h.

References libMesh::ParallelObject::processor_id().

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

688  { return this->first_dof(this->processor_id()); }
dof_id_type first_dof() const
Definition: dof_map.h:687
processor_id_type processor_id() const

◆ first_old_dof() [1/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 694 of file dof_map.h.

References _first_old_df.

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

695  { libmesh_assert_less (proc, _first_old_df.size()); return _first_old_df[proc]; }
std::vector< dof_id_type > _first_old_df
First old DOF index on processor p.
Definition: dof_map.h:2009

◆ first_old_dof() [2/2]

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

Definition at line 697 of file dof_map.h.

References libMesh::ParallelObject::processor_id().

698  { return this->first_old_dof(this->processor_id()); }
dof_id_type first_old_dof() const
Definition: dof_map.h:697
processor_id_type processor_id() const

◆ 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 5051 of file dof_map_constraints.C.

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

Referenced by allgather_recursive_constraints(), and scatter_constraints().

5054 {
5055  typedef std::set<dof_id_type> DoF_RCSet;
5056 
5057  // If we have heterogeneous adjoint constraints we need to
5058  // communicate those too.
5059  const unsigned int max_qoi_num =
5060  _adjoint_constraint_values.empty() ?
5061  0 : _adjoint_constraint_values.rbegin()->first+1;
5062 
5063  // We have to keep recursing while the unexpanded set is
5064  // nonempty on *any* processor
5065  bool unexpanded_set_nonempty = !unexpanded_dofs.empty();
5066  this->comm().max(unexpanded_set_nonempty);
5067 
5068  while (unexpanded_set_nonempty)
5069  {
5070  // Let's make sure we don't lose sync in this loop.
5071  parallel_object_only();
5072 
5073  // Request sets
5074  DoF_RCSet dof_request_set;
5075 
5076  // Request sets to send to each processor
5077  std::map<processor_id_type, std::vector<dof_id_type>>
5078  requested_dof_ids;
5079 
5080  // And the sizes of each
5081  std::map<processor_id_type, dof_id_type>
5082  dof_ids_on_proc;
5083 
5084  // Fill (and thereby sort and uniq!) the main request sets
5085  for (const auto & unexpanded_dof : unexpanded_dofs)
5086  {
5087  DofConstraints::const_iterator
5088  pos = _dof_constraints.find(unexpanded_dof);
5089 
5090  // If we were asked for a DoF and we don't already have a
5091  // constraint for it, then we need to check for one.
5092  if (pos == _dof_constraints.end())
5093  {
5094  if (!this->local_index(unexpanded_dof) &&
5095  !_dof_constraints.count(unexpanded_dof) )
5096  dof_request_set.insert(unexpanded_dof);
5097  }
5098  // If we were asked for a DoF and we already have a
5099  // constraint for it, then we need to check if the
5100  // constraint is recursive.
5101  else
5102  {
5103  const DofConstraintRow & row = pos->second;
5104  for (const auto & j : row)
5105  {
5106  const dof_id_type constraining_dof = j.first;
5107 
5108  // If it's non-local and we haven't already got a
5109  // constraint for it, we might need to ask for one
5110  if (!this->local_index(constraining_dof) &&
5111  !_dof_constraints.count(constraining_dof))
5112  dof_request_set.insert(constraining_dof);
5113  }
5114  }
5115  }
5116 
5117  // Clear the unexpanded constraint set; we're about to expand it
5118  unexpanded_dofs.clear();
5119 
5120  // Count requests by processor
5121  processor_id_type proc_id = 0;
5122  for (const auto & i : dof_request_set)
5123  {
5124  while (i >= _end_df[proc_id])
5125  proc_id++;
5126  dof_ids_on_proc[proc_id]++;
5127  }
5128 
5129  for (auto & pair : dof_ids_on_proc)
5130  {
5131  requested_dof_ids[pair.first].reserve(pair.second);
5132  }
5133 
5134  // Prepare each processor's request set
5135  proc_id = 0;
5136  for (const auto & i : dof_request_set)
5137  {
5138  while (i >= _end_df[proc_id])
5139  proc_id++;
5140  requested_dof_ids[proc_id].push_back(i);
5141  }
5142 
5143  typedef std::vector<std::pair<dof_id_type, Real>> row_datum;
5144 
5145  typedef std::vector<Number> rhss_datum;
5146 
5147  auto row_gather_functor =
5148  [this]
5150  const std::vector<dof_id_type> & ids,
5151  std::vector<row_datum> & data)
5152  {
5153  // Fill those requests
5154  const std::size_t query_size = ids.size();
5155 
5156  data.resize(query_size);
5157  for (std::size_t i=0; i != query_size; ++i)
5158  {
5159  dof_id_type constrained = ids[i];
5160  if (_dof_constraints.count(constrained))
5161  {
5162  DofConstraintRow & row = _dof_constraints[constrained];
5163  std::size_t row_size = row.size();
5164  data[i].reserve(row_size);
5165  for (const auto & j : row)
5166  {
5167  data[i].push_back(j);
5168 
5169  // We should never have an invalid constraining
5170  // dof id
5172 
5173  // We should never have a 0 constraint
5174  // coefficient; that's implicit via sparse
5175  // constraint storage
5176  //
5177  // But we can't easily control how users add
5178  // constraints, so we can't safely assert that
5179  // we're being efficient here.
5180  //
5181  // libmesh_assert(j.second);
5182  }
5183  }
5184  else
5185  {
5186  // We have to distinguish "constraint with no
5187  // constraining dofs" (e.g. due to Dirichlet
5188  // constraint equations) from "no constraint".
5189  // We'll use invalid_id for the latter.
5190  data[i].emplace_back(DofObject::invalid_id, Real(0));
5191  }
5192  }
5193  };
5194 
5195  auto rhss_gather_functor =
5196  [this,
5197  max_qoi_num]
5199  const std::vector<dof_id_type> & ids,
5200  std::vector<rhss_datum> & data)
5201  {
5202  // Fill those requests
5203  const std::size_t query_size = ids.size();
5204 
5205  data.resize(query_size);
5206  for (std::size_t i=0; i != query_size; ++i)
5207  {
5208  dof_id_type constrained = ids[i];
5209  data[i].clear();
5210  if (_dof_constraints.count(constrained))
5211  {
5212  DofConstraintValueMap::const_iterator rhsit =
5213  _primal_constraint_values.find(constrained);
5214  data[i].push_back
5215  ((rhsit == _primal_constraint_values.end()) ?
5216  0 : rhsit->second);
5217 
5218  for (unsigned int q = 0; q != max_qoi_num; ++q)
5219  {
5220  AdjointDofConstraintValues::const_iterator adjoint_map_it =
5222 
5223  if (adjoint_map_it == _adjoint_constraint_values.end())
5224  {
5225  data[i].push_back(0);
5226  continue;
5227  }
5228 
5229  const DofConstraintValueMap & constraint_map =
5230  adjoint_map_it->second;
5231 
5232  DofConstraintValueMap::const_iterator adj_rhsit =
5233  constraint_map.find(constrained);
5234  data[i].push_back
5235  ((adj_rhsit == constraint_map.end()) ?
5236  0 : adj_rhsit->second);
5237  }
5238  }
5239  }
5240  };
5241 
5242  auto row_action_functor =
5243  [this,
5244  & unexpanded_dofs]
5246  const std::vector<dof_id_type> & ids,
5247  const std::vector<row_datum> & data)
5248  {
5249  // Add any new constraint rows we've found
5250  const std::size_t query_size = ids.size();
5251 
5252  for (std::size_t i=0; i != query_size; ++i)
5253  {
5254  const dof_id_type constrained = ids[i];
5255 
5256  // An empty row is an constraint with an empty row; for
5257  // no constraint we use a "no row" placeholder
5258  if (data[i].empty())
5259  {
5260  DofConstraintRow & row = _dof_constraints[constrained];
5261  row.clear();
5262  }
5263  else if (data[i][0].first != DofObject::invalid_id)
5264  {
5265  DofConstraintRow & row = _dof_constraints[constrained];
5266  row.clear();
5267  for (auto & pair : data[i])
5268  {
5269  libmesh_assert_less(pair.first, this->n_dofs());
5270  row[pair.first] = pair.second;
5271  }
5272 
5273  // And prepare to check for more recursive constraints
5274  unexpanded_dofs.insert(constrained);
5275  }
5276  }
5277  };
5278 
5279  auto rhss_action_functor =
5280  [this,
5281  max_qoi_num]
5283  const std::vector<dof_id_type> & ids,
5284  const std::vector<rhss_datum> & data)
5285  {
5286  // Add rhs data for any new constraint rows we've found
5287  const std::size_t query_size = ids.size();
5288 
5289  for (std::size_t i=0; i != query_size; ++i)
5290  {
5291  if (!data[i].empty())
5292  {
5293  dof_id_type constrained = ids[i];
5294  if (data[i][0] != Number(0))
5295  _primal_constraint_values[constrained] = data[i][0];
5296  else
5297  _primal_constraint_values.erase(constrained);
5298 
5299  for (unsigned int q = 0; q != max_qoi_num; ++q)
5300  {
5301  AdjointDofConstraintValues::iterator adjoint_map_it =
5303 
5304  if ((adjoint_map_it == _adjoint_constraint_values.end()) &&
5305  data[i][q+1] == Number(0))
5306  continue;
5307 
5308  if (adjoint_map_it == _adjoint_constraint_values.end())
5309  adjoint_map_it = _adjoint_constraint_values.emplace
5310  (q, DofConstraintValueMap()).first;
5311 
5312  DofConstraintValueMap & constraint_map =
5313  adjoint_map_it->second;
5314 
5315  if (data[i][q+1] != Number(0))
5316  constraint_map[constrained] =
5317  data[i][q+1];
5318  else
5319  constraint_map.erase(constrained);
5320  }
5321  }
5322  }
5323 
5324  };
5325 
5326  // Now request constraint rows from other processors
5327  row_datum * row_ex = nullptr;
5328  Parallel::pull_parallel_vector_data
5329  (this->comm(), requested_dof_ids, row_gather_functor,
5330  row_action_functor, row_ex);
5331 
5332  // And request constraint right hand sides from other procesors
5333  rhss_datum * rhs_ex = nullptr;
5334  Parallel::pull_parallel_vector_data
5335  (this->comm(), requested_dof_ids, rhss_gather_functor,
5336  rhss_action_functor, rhs_ex);
5337 
5338  // We have to keep recursing while the unexpanded set is
5339  // nonempty on *any* processor
5340  unexpanded_set_nonempty = !unexpanded_dofs.empty();
5341  this->comm().max(unexpanded_set_nonempty);
5342  }
5343 }
const Parallel::Communicator & comm() const
uint8_t processor_id_type
Definition: id_types.h:104
AdjointDofConstraintValues _adjoint_constraint_values
Definition: dof_map.h:2037
uint8_t processor_id_type
libmesh_assert(ctx)
static const dof_id_type invalid_id
An invalid id to distinguish an uninitialized DofObject.
Definition: dof_object.h:477
DofConstraints _dof_constraints
Data structure containing DOF constraints.
Definition: dof_map.h:2033
Storage for DofConstraint right hand sides for a particular problem.
Definition: dof_map.h:110
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
void max(const T &r, T &o, Request &req) const
DofConstraintValueMap _primal_constraint_values
Definition: dof_map.h:2035
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:90
std::vector< dof_id_type > _end_df
Last DOF index (plus 1) on processor p.
Definition: dof_map.h:1884
uint8_t dof_id_type
Definition: id_types.h:67
bool local_index(dof_id_type dof_index) const
Definition: dof_map.h:831

◆ get_adjoint_dirichlet_boundaries() [1/2]

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

Definition at line 5476 of file dof_map_constraints.C.

References _adjoint_dirichlet_boundaries.

5477 {
5478  libmesh_assert_greater(_adjoint_dirichlet_boundaries.size(),q);
5479  return _adjoint_dirichlet_boundaries[q].get();
5480 }
std::vector< std::unique_ptr< DirichletBoundaries > > _adjoint_dirichlet_boundaries
Data structure containing Dirichlet functions.
Definition: dof_map.h:2067

◆ get_adjoint_dirichlet_boundaries() [2/2]

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

Definition at line 5484 of file dof_map_constraints.C.

References _adjoint_dirichlet_boundaries.

5485 {
5486  unsigned int old_size = cast_int<unsigned int>
5488  for (unsigned int i = old_size; i <= q; ++i)
5489  _adjoint_dirichlet_boundaries.push_back(std::make_unique<DirichletBoundaries>());
5490 
5491  return _adjoint_dirichlet_boundaries[q].get();
5492 }
std::vector< std::unique_ptr< DirichletBoundaries > > _adjoint_dirichlet_boundaries
Data structure containing Dirichlet functions.
Definition: dof_map.h:2067

◆ get_dirichlet_boundaries() [1/2]

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

Definition at line 1485 of file dof_map.h.

References _dirichlet_boundaries.

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

1486  {
1487  return _dirichlet_boundaries.get();
1488  }
std::unique_ptr< DirichletBoundaries > _dirichlet_boundaries
Data structure containing Dirichlet functions.
Definition: dof_map.h:2061

◆ get_dirichlet_boundaries() [2/2]

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

Definition at line 1490 of file dof_map.h.

References _dirichlet_boundaries.

1491  {
1492  return _dirichlet_boundaries.get();
1493  }
std::unique_ptr< DirichletBoundaries > _dirichlet_boundaries
Data structure containing Dirichlet functions.
Definition: dof_map.h:2061

◆ get_dof_constraints()

const DofConstraints& libMesh::DofMap::get_dof_constraints ( ) const
inline

Provide a const accessor to the DofConstraints map.

This allows the user to quickly search the data structure rather than just iterating over it.

Definition at line 1026 of file dof_map.h.

References _dof_constraints.

1026 { return _dof_constraints; }
DofConstraints _dof_constraints
Data structure containing DOF constraints.
Definition: dof_map.h:2033

◆ 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.

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

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

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 & [name, cd] : _counts)
59  oss << "| " << name << " reference count information:\n"
60  << "| Creations: " << cd.first << '\n'
61  << "| Destructions: " << cd.second << '\n';
62 
63  oss << " ---------------------------------------------------------------------------- \n";
64 
65  return oss.str();
66 
67 #else
68 
69  return "";
70 
71 #endif
72 }
std::string name(const ElemQuality q)
This function returns a string containing some name for q.
Definition: elem_quality.C:42
static Counts _counts
Actually holds the data.

◆ get_info() [2/2]

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

Gets summary info about the sparsity bandwidth and constraints.

Definition at line 2922 of file dof_map.C.

References _dof_constraints, _matrices, _node_constraints, _primal_constraint_values, _sp, libMesh::ParallelObject::comm(), local_index(), TIMPI::Communicator::max(), libMesh::ParallelObject::processor_id(), and TIMPI::Communicator::sum().

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

2923 {
2924  std::ostringstream os;
2925 
2926  // If we didn't calculate the exact sparsity pattern, the threaded
2927  // sparsity pattern assembly may have just given us an upper bound
2928  // on sparsity.
2929  const char * may_equal = " <= ";
2930 
2931  // If we calculated the exact sparsity pattern, then we can report
2932  // exact bandwidth figures:
2933  for (const auto & mat : _matrices)
2934  if (mat->need_full_sparsity_pattern())
2935  may_equal = " = ";
2936 
2937  dof_id_type max_n_nz = 0, max_n_oz = 0;
2938  long double avg_n_nz = 0, avg_n_oz = 0;
2939 
2940  if (_sp)
2941  {
2942  for (const auto & val : _sp->get_n_nz())
2943  {
2944  max_n_nz = std::max(max_n_nz, val);
2945  avg_n_nz += val;
2946  }
2947 
2948  std::size_t n_nz_size = _sp->get_n_nz().size();
2949 
2950  this->comm().max(max_n_nz);
2951  this->comm().sum(avg_n_nz);
2952  this->comm().sum(n_nz_size);
2953 
2954  avg_n_nz /= std::max(n_nz_size,std::size_t(1));
2955 
2956  for (const auto & val : _sp->get_n_oz())
2957  {
2958  max_n_oz = std::max(max_n_oz, val);
2959  avg_n_oz += val;
2960  }
2961 
2962  std::size_t n_oz_size = _sp->get_n_oz().size();
2963 
2964  this->comm().max(max_n_oz);
2965  this->comm().sum(avg_n_oz);
2966  this->comm().sum(n_oz_size);
2967 
2968  avg_n_oz /= std::max(n_oz_size,std::size_t(1));
2969  }
2970 
2971  os << " DofMap Sparsity\n Average On-Processor Bandwidth"
2972  << may_equal << avg_n_nz << '\n';
2973 
2974  os << " Average Off-Processor Bandwidth"
2975  << may_equal << avg_n_oz << '\n';
2976 
2977  os << " Maximum On-Processor Bandwidth"
2978  << may_equal << max_n_nz << '\n';
2979 
2980  os << " Maximum Off-Processor Bandwidth"
2981  << may_equal << max_n_oz << std::endl;
2982 
2983 #ifdef LIBMESH_ENABLE_CONSTRAINTS
2984 
2985  std::size_t n_constraints = 0, max_constraint_length = 0,
2986  n_rhss = 0;
2987  long double avg_constraint_length = 0.;
2988 
2989  for (const auto & [constrained_dof, row] : _dof_constraints)
2990  {
2991  // Only count local constraints, then sum later
2992  if (!this->local_index(constrained_dof))
2993  continue;
2994 
2995  std::size_t rowsize = row.size();
2996 
2997  max_constraint_length = std::max(max_constraint_length,
2998  rowsize);
2999  avg_constraint_length += rowsize;
3000  n_constraints++;
3001 
3002  if (_primal_constraint_values.count(constrained_dof))
3003  n_rhss++;
3004  }
3005 
3006  this->comm().sum(n_constraints);
3007  this->comm().sum(n_rhss);
3008  this->comm().sum(avg_constraint_length);
3009  this->comm().max(max_constraint_length);
3010 
3011  os << " DofMap Constraints\n Number of DoF Constraints = "
3012  << n_constraints;
3013  if (n_rhss)
3014  os << '\n'
3015  << " Number of Heterogenous Constraints= " << n_rhss;
3016  if (n_constraints)
3017  {
3018  avg_constraint_length /= n_constraints;
3019 
3020  os << '\n'
3021  << " Average DoF Constraint Length= " << avg_constraint_length;
3022  }
3023 
3024 #ifdef LIBMESH_ENABLE_NODE_CONSTRAINTS
3025  std::size_t n_node_constraints = 0, max_node_constraint_length = 0,
3026  n_node_rhss = 0;
3027  long double avg_node_constraint_length = 0.;
3028 
3029  for (const auto & [node, pr] : _node_constraints)
3030  {
3031  // Only count local constraints, then sum later
3032  if (node->processor_id() != this->processor_id())
3033  continue;
3034 
3035  const NodeConstraintRow & row = pr.first;
3036  std::size_t rowsize = row.size();
3037 
3038  max_node_constraint_length = std::max(max_node_constraint_length,
3039  rowsize);
3040  avg_node_constraint_length += rowsize;
3041  n_node_constraints++;
3042 
3043  if (pr.second != Point(0))
3044  n_node_rhss++;
3045  }
3046 
3047  this->comm().sum(n_node_constraints);
3048  this->comm().sum(n_node_rhss);
3049  this->comm().sum(avg_node_constraint_length);
3050  this->comm().max(max_node_constraint_length);
3051 
3052  os << "\n Number of Node Constraints = " << n_node_constraints;
3053  if (n_node_rhss)
3054  os << '\n'
3055  << " Number of Heterogenous Node Constraints= " << n_node_rhss;
3056  if (n_node_constraints)
3057  {
3058  avg_node_constraint_length /= n_node_constraints;
3059  os << "\n Maximum Node Constraint Length= " << max_node_constraint_length
3060  << '\n'
3061  << " Average Node Constraint Length= " << avg_node_constraint_length;
3062  }
3063 #endif // LIBMESH_ENABLE_NODE_CONSTRAINTS
3064 
3065  os << std::endl;
3066 
3067 #endif // LIBMESH_ENABLE_CONSTRAINTS
3068 
3069  return os.str();
3070 }
std::unique_ptr< SparsityPattern::Build > _sp
The sparsity pattern of the global matrix.
Definition: dof_map.h:1986
void sum(T &r) const
const Parallel::Communicator & comm() const
DofConstraints _dof_constraints
Data structure containing DOF constraints.
Definition: dof_map.h:2033
std::vector< SparseMatrix< Number > *> _matrices
Additional matrices handled by this object.
Definition: dof_map.h:1874
void max(const T &r, T &o, Request &req) const
DofConstraintValueMap _primal_constraint_values
Definition: dof_map.h:2035
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:138
processor_id_type processor_id() const
uint8_t dof_id_type
Definition: id_types.h:67
bool local_index(dof_id_type dof_index) const
Definition: dof_map.h:831
NodeConstraints _node_constraints
Data structure containing DofObject constraints.
Definition: dof_map.h:2044

◆ 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 2284 of file dof_map_constraints.C.

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

Referenced by print_dof_constraints().

2285 {
2286  std::ostringstream os;
2287 #ifdef LIBMESH_ENABLE_NODE_CONSTRAINTS
2288  if (print_nonlocal)
2289  os << "All ";
2290  else
2291  os << "Local ";
2292 
2293  os << "Node Constraints:"
2294  << std::endl;
2295 
2296  for (const auto & [node, pr] : _node_constraints)
2297  {
2298  // Skip non-local nodes if requested
2299  if (!print_nonlocal &&
2300  node->processor_id() != this->processor_id())
2301  continue;
2302 
2303  const NodeConstraintRow & row = pr.first;
2304  const Point & offset = pr.second;
2305 
2306  os << "Constraints for Node id " << node->id()
2307  << ": \t";
2308 
2309  for (const auto & [cnode, val] : row)
2310  os << " (" << cnode->id() << "," << val << ")\t";
2311 
2312  os << "rhs: " << offset;
2313 
2314  os << std::endl;
2315  }
2316 #endif // LIBMESH_ENABLE_NODE_CONSTRAINTS
2317 
2318  if (print_nonlocal)
2319  os << "All ";
2320  else
2321  os << "Local ";
2322 
2323  os << "DoF Constraints:"
2324  << std::endl;
2325 
2326  for (const auto & [i, row] : _dof_constraints)
2327  {
2328  // Skip non-local dofs if requested
2329  if (!print_nonlocal && !this->local_index(i))
2330  continue;
2331 
2332  DofConstraintValueMap::const_iterator rhsit =
2333  _primal_constraint_values.find(i);
2334  const Number rhs = (rhsit == _primal_constraint_values.end()) ?
2335  0 : rhsit->second;
2336 
2337  os << "Constraints for DoF " << i
2338  << ": \t";
2339 
2340  for (const auto & item : row)
2341  os << " (" << item.first << "," << item.second << ")\t";
2342 
2343  os << "rhs: " << rhs;
2344  os << std::endl;
2345  }
2346 
2347  for (unsigned int qoi_index = 0,
2348  n_qois = cast_int<unsigned int>(_adjoint_dirichlet_boundaries.size());
2349  qoi_index != n_qois; ++qoi_index)
2350  {
2351  os << "Adjoint " << qoi_index << " DoF rhs values:"
2352  << std::endl;
2353 
2354  AdjointDofConstraintValues::const_iterator adjoint_map_it =
2355  _adjoint_constraint_values.find(qoi_index);
2356 
2357  if (adjoint_map_it != _adjoint_constraint_values.end())
2358  for (const auto [i, rhs] : adjoint_map_it->second)
2359  {
2360  // Skip non-local dofs if requested
2361  if (!print_nonlocal && !this->local_index(i))
2362  continue;
2363 
2364  os << "RHS for DoF " << i
2365  << ": " << rhs;
2366 
2367  os << std::endl;
2368  }
2369  }
2370 
2371  return os.str();
2372 }
AdjointDofConstraintValues _adjoint_constraint_values
Definition: dof_map.h:2037
DofConstraints _dof_constraints
Data structure containing DOF constraints.
Definition: dof_map.h:2033
std::vector< std::unique_ptr< DirichletBoundaries > > _adjoint_dirichlet_boundaries
Data structure containing Dirichlet functions.
Definition: dof_map.h:2067
DofConstraintValueMap _primal_constraint_values
Definition: dof_map.h:2035
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:138
processor_id_type processor_id() const
A Point defines a location in LIBMESH_DIM dimensional Real space.
Definition: point.h:39
bool local_index(dof_id_type dof_index) const
Definition: dof_map.h:831
NodeConstraints _node_constraints
Data structure containing DofObject constraints.
Definition: dof_map.h:2044

◆ 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 520 of file dof_map.h.

References _sp, and libMesh::libmesh_assert().

521  {
523  return _sp->get_n_nz();
524  }
std::unique_ptr< SparsityPattern::Build > _sp
The sparsity pattern of the global matrix.
Definition: dof_map.h:1986
libmesh_assert(ctx)

◆ 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 533 of file dof_map.h.

References _sp, and libMesh::libmesh_assert().

534  {
536  return _sp->get_n_oz();
537  }
std::unique_ptr< SparsityPattern::Build > _sp
The sparsity pattern of the global matrix.
Definition: dof_map.h:1986
libmesh_assert(ctx)

◆ get_periodic_boundaries() [1/2]

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

Definition at line 1432 of file dof_map.h.

References _periodic_boundaries.

Referenced by main().

1433  {
1434  return _periodic_boundaries.get();
1435  }
std::unique_ptr< PeriodicBoundaries > _periodic_boundaries
Data structure containing periodic boundaries.
Definition: dof_map.h:2053

◆ get_periodic_boundaries() [2/2]

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

Definition at line 1437 of file dof_map.h.

References _periodic_boundaries.

1438  {
1439  return _periodic_boundaries.get();
1440  }
std::unique_ptr< PeriodicBoundaries > _periodic_boundaries
Data structure containing periodic boundaries.
Definition: dof_map.h:2053

◆ 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 2227 of file dof_map.h.

References _primal_constraint_values.

2228 {
2230 }
DofConstraintValueMap _primal_constraint_values
Definition: dof_map.h:2035

◆ get_send_list()

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

◆ get_sparsity_pattern()

const SparsityPattern::Build* libMesh::DofMap::get_sparsity_pattern ( ) const
inline
Returns
A constant pointer to the sparsity pattern stored here, once that has been computed. Returns null if no sparsity pattern has yet been computed.

If need_full_sparsity_pattern is false, the "sparsity pattern" may only own n_nz and n_oz lists.

Definition at line 548 of file dof_map.h.

References _sp.

Referenced by libMesh::SparseMatrix< ValOut >::attach_dof_map().

549  {
550  return _sp.get();
551  }
std::unique_ptr< SparsityPattern::Build > _sp
The sparsity pattern of the global matrix.
Definition: dof_map.h:1986

◆ has_adjoint_dirichlet_boundaries()

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

Definition at line 5466 of file dof_map_constraints.C.

References _adjoint_dirichlet_boundaries.

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

5467 {
5468  if (_adjoint_dirichlet_boundaries.size() > q)
5469  return true;
5470 
5471  return false;
5472 }
std::vector< std::unique_ptr< DirichletBoundaries > > _adjoint_dirichlet_boundaries
Data structure containing Dirichlet functions.
Definition: dof_map.h:2067

◆ 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 634 of file dof_map.h.

References n_variable_groups(), and n_variables().

Referenced by block_size().

635  {
636  return ((this->n_variable_groups() == 1) && (this->n_variables() > 1));
637  }
unsigned int n_variable_groups() const
Definition: dof_map.h:613
unsigned int n_variables() const
Definition: dof_map.h:621

◆ has_heterogeneous_adjoint_constraint()

Number libMesh::DofMap::has_heterogeneous_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 heterogeneous constraint for adjoint solution qoi_num, zero otherwise.

Definition at line 2206 of file dof_map.h.

References _adjoint_constraint_values.

Referenced by has_heterogenous_adjoint_constraint().

2208 {
2209  AdjointDofConstraintValues::const_iterator it =
2210  _adjoint_constraint_values.find(qoi_num);
2211  if (it != _adjoint_constraint_values.end())
2212  {
2213  DofConstraintValueMap::const_iterator rhsit =
2214  it->second.find(dof);
2215  if (rhsit == it->second.end())
2216  return 0;
2217  else
2218  return rhsit->second;
2219  }
2220 
2221  return 0;
2222 }
AdjointDofConstraintValues _adjoint_constraint_values
Definition: dof_map.h:2037

◆ has_heterogeneous_adjoint_constraints()

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

Definition at line 2192 of file dof_map.h.

References _adjoint_constraint_values.

Referenced by has_heterogenous_adjoint_constraints().

2193 {
2194  AdjointDofConstraintValues::const_iterator it =
2195  _adjoint_constraint_values.find(qoi_num);
2196  if (it == _adjoint_constraint_values.end())
2197  return false;
2198  if (it->second.empty())
2199  return false;
2200 
2201  return true;
2202 }
AdjointDofConstraintValues _adjoint_constraint_values
Definition: dof_map.h:2037

◆ has_heterogenous_adjoint_constraint()

Number libMesh::DofMap::has_heterogenous_adjoint_constraint ( const unsigned int  qoi_num,
const dof_id_type  dof 
) const
inline

Backwards compatibility with misspelling.

Definition at line 1102 of file dof_map.h.

References has_heterogeneous_adjoint_constraint().

1104  {
1105  return this->has_heterogeneous_adjoint_constraint (qoi_num, dof);
1106  }
Number has_heterogeneous_adjoint_constraint(const unsigned int qoi_num, const dof_id_type dof) const
Definition: dof_map.h:2206

◆ has_heterogenous_adjoint_constraints()

bool libMesh::DofMap::has_heterogenous_adjoint_constraints ( const unsigned int  qoi_num) const
inline

Backwards compatibility with misspelling.

Definition at line 1086 of file dof_map.h.

References has_heterogeneous_adjoint_constraints().

1087  {
1088  return this->has_heterogeneous_adjoint_constraints (qoi_num);
1089  }
bool has_heterogeneous_adjoint_constraints(const unsigned int qoi_num) const
Definition: dof_map.h:2192

◆ heterogeneously_constrain_element_jacobian_and_residual()

void libMesh::DofMap::heterogeneously_constrain_element_jacobian_and_residual ( DenseMatrix< Number > &  matrix,
DenseVector< Number > &  rhs,
std::vector< dof_id_type > &  elem_dofs,
NumericVector< Number > &  solution_local 
) const

Constrains the element Jacobian and residual.

The element Jacobian is square, and the elem_dofs should correspond to the global DOF indices of both the rows and columns of the element matrix.

The residual-constraining version of this method creates linear systems in which heterogeneously constrained degrees of freedom create non-zero residual terms when not at their correct offset values, as would be appropriate for finding a solution to a nonlinear problem in a quasi-Newton solve.

Note the sign difference from the linear heterogeneous constraint method: Solving u:=u_in-J has the opposite sign convention from u:=K, and we apply heterogeneous constraints accordingly.

The solution vector passed in should be a serialized or ghosted primal solution

Definition at line 2631 of file dof_map_constraints.C.

References libMesh::GHOSTED, libMesh::DenseMatrix< T >::left_multiply_transpose(), libMesh::libmesh_assert(), libMesh::DenseMatrixBase< T >::m(), libMesh::make_range(), libMesh::DenseMatrixBase< T >::n(), libMesh::DenseMatrix< T >::right_multiply(), libMesh::SERIAL, libMesh::DenseVector< T >::size(), libMesh::NumericVector< T >::type(), and libMesh::DenseMatrix< T >::vector_mult_transpose().

2635 {
2636  libmesh_assert_equal_to (elem_dofs.size(), matrix.m());
2637  libmesh_assert_equal_to (elem_dofs.size(), matrix.n());
2638  libmesh_assert_equal_to (elem_dofs.size(), rhs.size());
2639 
2640  libmesh_assert (solution_local.type() == SERIAL ||
2641  solution_local.type() == GHOSTED);
2642 
2643  // check for easy return
2644  if (this->_dof_constraints.empty())
2645  return;
2646 
2647  // The constrained matrix is built up as C^T K C.
2648  // The constrained RHS is built up as C^T F
2649  // Asymmetric residual terms are added if we do not have x = Cx+h
2652 
2653  this->build_constraint_matrix_and_vector (C, H, elem_dofs);
2654 
2655  LOG_SCOPE("hetero_cnstrn_elem_jac_res()", "DofMap");
2656 
2657  // It is possible that the matrix is not constrained at all.
2658  if ((C.m() != matrix.m()) ||
2659  (C.n() != elem_dofs.size()))
2660  return;
2661 
2662  // Compute the matrix-vector product C^T F
2663  DenseVector<Number> old_rhs(rhs);
2664  C.vector_mult_transpose(rhs, old_rhs);
2665 
2666  // Compute the matrix-matrix-matrix product C^T K C
2667  matrix.left_multiply_transpose (C);
2668  matrix.right_multiply (C);
2669 
2670  libmesh_assert_equal_to (matrix.m(), matrix.n());
2671  libmesh_assert_equal_to (matrix.m(), elem_dofs.size());
2672  libmesh_assert_equal_to (matrix.n(), elem_dofs.size());
2673 
2674  for (unsigned int i=0,
2675  n_elem_dofs = cast_int<unsigned int>(elem_dofs.size());
2676  i != n_elem_dofs; i++)
2677  {
2678  const dof_id_type dof_id = elem_dofs[i];
2679 
2680  const DofConstraints::const_iterator
2681  pos = _dof_constraints.find(dof_id);
2682 
2683  if (pos != _dof_constraints.end())
2684  {
2685  for (auto j : make_range(matrix.n()))
2686  matrix(i,j) = 0.;
2687 
2688  // If the DOF is constrained
2689  matrix(i,i) = 1.;
2690 
2691  // This will put a nonsymmetric entry in the constraint
2692  // row to ensure that the linear system produces the
2693  // correct value for the constrained DOF.
2694  const DofConstraintRow & constraint_row = pos->second;
2695 
2696  for (const auto & item : constraint_row)
2697  for (unsigned int j=0; j != n_elem_dofs; j++)
2698  if (elem_dofs[j] == item.first)
2699  matrix(i,j) = -item.second;
2700 
2701  const DofConstraintValueMap::const_iterator valpos =
2702  _primal_constraint_values.find(dof_id);
2703 
2704  Number & rhs_val = rhs(i);
2705  rhs_val = (valpos == _primal_constraint_values.end()) ?
2706  0 : -valpos->second;
2707  for (const auto & [constraining_dof, coef] : constraint_row)
2708  rhs_val -= coef * solution_local(constraining_dof);
2709  rhs_val += solution_local(dof_id);
2710  }
2711  }
2712 }
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 ...
unsigned int m() const
void vector_mult_transpose(DenseVector< T > &dest, const DenseVector< T > &arg) const
Performs the matrix-vector multiplication, dest := (*this)^T * arg.
libmesh_assert(ctx)
DofConstraints _dof_constraints
Data structure containing DOF constraints.
Definition: dof_map.h:2033
ParallelType type() const
void left_multiply_transpose(const DenseMatrix< T > &A)
Left multiplies by the transpose of the matrix A.
virtual void right_multiply(const DenseMatrixBase< T > &M2) override final
Performs the operation: (*this) <- (*this) * M3.
DofConstraintValueMap _primal_constraint_values
Definition: dof_map.h:2035
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:90
IntRange< T > make_range(T beg, T end)
The 2-parameter make_range() helper function returns an IntRange<T> when both input parameters are of...
Definition: int_range.h:134
virtual unsigned int size() const override final
Definition: dense_vector.h:104
unsigned int n() const
uint8_t dof_id_type
Definition: id_types.h:67

◆ heterogeneously_constrain_element_matrix_and_vector()

void libMesh::DofMap::heterogeneously_constrain_element_matrix_and_vector ( DenseMatrix< Number > &  matrix,
DenseVector< Number > &  rhs,
std::vector< dof_id_type > &  elem_dofs,
bool  asymmetric_constraint_rows = true,
int  qoi_index = -1 
) const
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 heterogeneous version of this method creates linear systems in which heterogeneously 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-heterogeneous version of this method creates linear systems in which even heterogeneously 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 heterogeneous 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 2260 of file dof_map.h.

Referenced by heterogenously_constrain_element_matrix_and_vector(), and process_mesh_constraint_rows().

2261  {}

◆ heterogeneously_constrain_element_residual()

void libMesh::DofMap::heterogeneously_constrain_element_residual ( DenseVector< Number > &  rhs,
std::vector< dof_id_type > &  elem_dofs,
NumericVector< Number > &  solution_local 
) const

Constrains the element residual.

The element Jacobian is square, and the elem_dofs should correspond to the global DOF indices of both the rows and columns of the element matrix.

The residual-constraining version of this method creates linear systems in which heterogeneously constrained degrees of freedom create non-zero residual terms when not at their correct offset values, as would be appropriate for finding a solution to a nonlinear problem in a quasi-Newton solve.

The solution vector passed in should be a serialized or ghosted primal solution

Definition at line 2716 of file dof_map_constraints.C.

References libMesh::GHOSTED, libMesh::libmesh_assert(), libMesh::DenseMatrixBase< T >::m(), libMesh::DenseMatrixBase< T >::n(), libMesh::SERIAL, libMesh::DenseVector< T >::size(), libMesh::NumericVector< T >::type(), and libMesh::DenseMatrix< T >::vector_mult_transpose().

2719 {
2720  libmesh_assert_equal_to (elem_dofs.size(), rhs.size());
2721 
2722  libmesh_assert (solution_local.type() == SERIAL ||
2723  solution_local.type() == GHOSTED);
2724 
2725  // check for easy return
2726  if (this->_dof_constraints.empty())
2727  return;
2728 
2729  // The constrained RHS is built up as C^T F
2730  // Asymmetric residual terms are added if we do not have x = Cx+h
2733 
2734  this->build_constraint_matrix_and_vector (C, H, elem_dofs);
2735 
2736  LOG_SCOPE("hetero_cnstrn_elem_res()", "DofMap");
2737 
2738  // It is possible that the element is not constrained at all.
2739  if ((C.m() != rhs.size()) ||
2740  (C.n() != elem_dofs.size()))
2741  return;
2742 
2743  // Compute the matrix-vector product C^T F
2744  DenseVector<Number> old_rhs(rhs);
2745  C.vector_mult_transpose(rhs, old_rhs);
2746 
2747  for (unsigned int i=0,
2748  n_elem_dofs = cast_int<unsigned int>(elem_dofs.size());
2749  i != n_elem_dofs; i++)
2750  {
2751  const dof_id_type dof_id = elem_dofs[i];
2752 
2753  const DofConstraints::const_iterator
2754  pos = _dof_constraints.find(dof_id);
2755 
2756  if (pos != _dof_constraints.end())
2757  {
2758  // This will put a nonsymmetric entry in the constraint
2759  // row to ensure that the linear system produces the
2760  // correct value for the constrained DOF.
2761  const DofConstraintRow & constraint_row = pos->second;
2762 
2763  const DofConstraintValueMap::const_iterator valpos =
2764  _primal_constraint_values.find(dof_id);
2765 
2766  Number & rhs_val = rhs(i);
2767  rhs_val = (valpos == _primal_constraint_values.end()) ?
2768  0 : -valpos->second;
2769  for (const auto & [constraining_dof, coef] : constraint_row)
2770  rhs_val -= coef * solution_local(constraining_dof);
2771  rhs_val += solution_local(dof_id);
2772  }
2773  }
2774 }
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 ...
unsigned int m() const
void vector_mult_transpose(DenseVector< T > &dest, const DenseVector< T > &arg) const
Performs the matrix-vector multiplication, dest := (*this)^T * arg.
libmesh_assert(ctx)
DofConstraints _dof_constraints
Data structure containing DOF constraints.
Definition: dof_map.h:2033
ParallelType type() const
DofConstraintValueMap _primal_constraint_values
Definition: dof_map.h:2035
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:90
virtual unsigned int size() const override final
Definition: dense_vector.h:104
unsigned int n() const
uint8_t dof_id_type
Definition: id_types.h:67

◆ heterogeneously_constrain_element_vector()

void libMesh::DofMap::heterogeneously_constrain_element_vector ( const DenseMatrix< Number > &  matrix,
DenseVector< Number > &  rhs,
std::vector< dof_id_type > &  elem_dofs,
bool  asymmetric_constraint_rows = true,
int  qoi_index = -1 
) const
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 heterogeneous version of this method creates linear systems in which heterogeneously 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-heterogeneous version of this method creates linear systems in which even heterogeneously 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 heterogeneous constraints are already satisfied.

Note the sign difference from the nonlinear heterogeneous constraint method: Solving u:=K has the opposite sign convention from u:=u_in-J, and we apply heterogeneous constraints accordingly.

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 2264 of file dof_map.h.

Referenced by heterogenously_constrain_element_vector().

2265  {}

◆ 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

Definition at line 1237 of file dof_map.h.

References heterogeneously_constrain_element_matrix_and_vector().

Referenced by assemble_stokes(), and libMesh::System::solve_for_unconstrained_dofs().

1242  {
1244  (matrix, rhs, elem_dofs, asymmetric_constraint_rows, qoi_index);
1245  }
void heterogeneously_constrain_element_matrix_and_vector(DenseMatrix< Number > &matrix, DenseVector< Number > &rhs, std::vector< dof_id_type > &elem_dofs, bool asymmetric_constraint_rows=true, int qoi_index=-1) const
Constrains the element matrix and vector.
Definition: dof_map.h:2260

◆ 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

Definition at line 1281 of file dof_map.h.

References heterogeneously_constrain_element_vector().

1286  {
1288  (matrix, rhs, elem_dofs, asymmetric_constraint_rows, qoi_index);
1289  }
void heterogeneously_constrain_element_vector(const DenseMatrix< Number > &matrix, DenseVector< Number > &rhs, std::vector< dof_id_type > &elem_dofs, bool asymmetric_constraint_rows=true, int qoi_index=-1) const
Constrains the element vector.
Definition: dof_map.h:2264

◆ increment_constructor_count()

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

Increments the construction counter.

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

Definition at line 183 of file reference_counter.h.

References libMesh::err, libMesh::BasicOStreamProxy< charT, traits >::get(), libMesh::Quality::name(), and libMesh::Threads::spin_mtx.

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

184 {
185  libmesh_try
186  {
187  Threads::spin_mutex::scoped_lock lock(Threads::spin_mtx);
188  std::pair<unsigned int, unsigned int> & p = _counts[name];
189  p.first++;
190  }
191  libmesh_catch (...)
192  {
193  auto stream = libMesh::err.get();
194  stream->exceptions(stream->goodbit); // stream must not throw
195  libMesh::err << "Encountered unrecoverable error while calling "
196  << "ReferenceCounter::increment_constructor_count() "
197  << "for a(n) " << name << " object." << std::endl;
198  std::terminate();
199  }
200 }
std::string name(const ElemQuality q)
This function returns a string containing some name for q.
Definition: elem_quality.C:42
OStreamProxy err
static Counts _counts
Actually holds the data.
streamT * get()
Rather than implement every ostream/ios/ios_base function, we&#39;ll be lazy and make esoteric uses go th...
spin_mutex spin_mtx
A convenient spin mutex object which can be used for obtaining locks.
Definition: threads.C:30

◆ increment_destructor_count()

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

Increments the destruction counter.

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

Definition at line 207 of file reference_counter.h.

References libMesh::err, libMesh::BasicOStreamProxy< charT, traits >::get(), libMesh::Quality::name(), and libMesh::Threads::spin_mtx.

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

208 {
209  libmesh_try
210  {
211  Threads::spin_mutex::scoped_lock lock(Threads::spin_mtx);
212  std::pair<unsigned int, unsigned int> & p = _counts[name];
213  p.second++;
214  }
215  libmesh_catch (...)
216  {
217  auto stream = libMesh::err.get();
218  stream->exceptions(stream->goodbit); // stream must not throw
219  libMesh::err << "Encountered unrecoverable error while calling "
220  << "ReferenceCounter::increment_destructor_count() "
221  << "for a(n) " << name << " object." << std::endl;
222  std::terminate();
223  }
224 }
std::string name(const ElemQuality q)
This function returns a string containing some name for q.
Definition: elem_quality.C:42
OStreamProxy err
static Counts _counts
Actually holds the data.
streamT * get()
Rather than implement every ostream/ios/ios_base function, we&#39;ll be lazy and make esoteric uses go th...
spin_mutex spin_mtx
A convenient spin mutex object which can be used for obtaining locks.
Definition: threads.C:30

◆ invalidate_dofs()

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

Invalidates all active DofObject dofs for this system.

Definition at line 835 of file dof_map.C.

References mesh, and sys_number().

Referenced by distribute_dofs(), and reinit().

836 {
837  const unsigned int sys_num = this->sys_number();
838 
839  // All the nodes
840  for (auto & node : mesh.node_ptr_range())
841  node->invalidate_dofs(sys_num);
842 
843  // All the active elements.
844  for (auto & elem : mesh.active_element_ptr_range())
845  elem->invalidate_dofs(sys_num);
846 }
MeshBase & mesh
unsigned int sys_number() const
Definition: dof_map.h:2096

◆ 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 333 of file dof_map.C.

References _matrices.

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

334 {
335  return (std::find(_matrices.begin(), _matrices.end(),
336  &matrix) != _matrices.end());
337 }
std::vector< SparseMatrix< Number > *> _matrices
Additional matrices handled by this object.
Definition: dof_map.h:1874

◆ 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 2166 of file dof_map.h.

References _node_constraints.

Referenced by allgather_recursive_constraints(), and scatter_constraints().

2171 {
2172 #ifdef LIBMESH_ENABLE_NODE_CONSTRAINTS
2173  if (_node_constraints.count(node))
2174  return true;
2175 #endif
2176 
2177  return false;
2178 }
NodeConstraints _node_constraints
Data structure containing DofObject constraints.
Definition: dof_map.h:2044

◆ is_evaluable()

template<typename DofObjectSubclass >
template LIBMESH_EXPORT 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 2609 of file dof_map.C.

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().

2611 {
2612  // Everything is evaluable on a local object
2613  if (obj.processor_id() == this->processor_id())
2614  return true;
2615 
2616  std::vector<dof_id_type> di;
2617 
2618  if (var_num == libMesh::invalid_uint)
2619  this->dof_indices(&obj, di);
2620  else
2621  this->dof_indices(&obj, di, var_num);
2622 
2623  return this->all_semilocal_indices(di);
2624 }
const unsigned int invalid_uint
A number which is used quite often to represent an invalid or uninitialized value for an unsigned int...
Definition: libmesh.h:286
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:1992
bool all_semilocal_indices(const std::vector< dof_id_type > &dof_indices) const
Definition: dof_map.C:2596
processor_id_type processor_id() const

◆ 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 219 of file dof_map.C.

References _periodic_boundaries.

220 {
221  if (_periodic_boundaries->count(boundaryid) != 0)
222  return true;
223 
224  return false;
225 }
std::unique_ptr< PeriodicBoundaries > _periodic_boundaries
Data structure containing periodic boundaries.
Definition: dof_map.h:2053

◆ local_index()

bool libMesh::DofMap::local_index ( dof_id_type  dof_index) const
inline

◆ 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 1109 of file dof_map.C.

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().

1112 {
1113  // Count dofs in the *exact* order that distribute_dofs numbered
1114  // them, so that we can assume ascending indices and use push_back
1115  // instead of find+insert.
1116 
1117  const unsigned int sys_num = this->sys_number();
1118 
1119  // If this isn't a SCALAR variable, we need to find all its field
1120  // dofs on the mesh
1121  if (this->variable_type(var_num).family != SCALAR)
1122  {
1123  const Variable & var(this->variable(var_num));
1124 
1125  for (auto & elem : mesh.active_local_element_ptr_range())
1126  {
1127  if (!var.active_on_subdomain(elem->subdomain_id()))
1128  continue;
1129 
1130  // Only count dofs connected to active
1131  // elements on this processor.
1132  const unsigned int n_nodes = elem->n_nodes();
1133 
1134  // First get any new nodal DOFS
1135  for (unsigned int n=0; n<n_nodes; n++)
1136  {
1137  const Node & node = elem->node_ref(n);
1138 
1139  if (node.processor_id() != this->processor_id())
1140  continue;
1141 
1142  const unsigned int n_comp = node.n_comp(sys_num, var_num);
1143  for(unsigned int i=0; i<n_comp; i++)
1144  {
1145  const dof_id_type index = node.dof_number(sys_num,var_num,i);
1146  libmesh_assert (this->local_index(index));
1147 
1148  if (idx.empty() || index > idx.back())
1149  idx.push_back(index);
1150  }
1151  }
1152 
1153  // Next get any new element DOFS
1154  const unsigned int n_comp = elem->n_comp(sys_num, var_num);
1155  for (unsigned int i=0; i<n_comp; i++)
1156  {
1157  const dof_id_type index = elem->dof_number(sys_num,var_num,i);
1158  if (idx.empty() || index > idx.back())
1159  idx.push_back(index);
1160  }
1161  } // done looping over elements
1162 
1163 
1164  // we may have missed assigning DOFs to nodes that we own
1165  // but to which we have no connected elements matching our
1166  // variable restriction criterion. this will happen, for example,
1167  // if variable V is restricted to subdomain S. We may not own
1168  // any elements which live in S, but we may own nodes which are
1169  // *connected* to elements which do. in this scenario these nodes
1170  // will presently have unnumbered DOFs. we need to take care of
1171  // them here since we own them and no other processor will touch them.
1172  for (const auto & node : mesh.local_node_ptr_range())
1173  {
1174  libmesh_assert(node);
1175 
1176  const unsigned int n_comp = node->n_comp(sys_num, var_num);
1177  for (unsigned int i=0; i<n_comp; i++)
1178  {
1179  const dof_id_type index = node->dof_number(sys_num,var_num,i);
1180  if (idx.empty() || index > idx.back())
1181  idx.push_back(index);
1182  }
1183  }
1184  }
1185  // Otherwise, count up the SCALAR dofs, if we're on the processor
1186  // that holds this SCALAR variable
1187  else if (this->processor_id() == (this->n_processors()-1))
1188  {
1189  std::vector<dof_id_type> di_scalar;
1190  this->SCALAR_dof_indices(di_scalar,var_num);
1191  idx.insert( idx.end(), di_scalar.begin(), di_scalar.end());
1192  }
1193 }
const FEType & variable_type(const unsigned int c) const
Definition: dof_map.h:2144
MeshBase & mesh
unsigned int sys_number() const
Definition: dof_map.h:2096
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:2544
processor_id_type n_processors() const
const dof_id_type n_nodes
Definition: tecplot_io.C:67
const Variable & variable(const unsigned int c) const
Definition: dof_map.h:2114
libmesh_assert(ctx)
processor_id_type processor_id() const
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.
uint8_t dof_id_type
Definition: id_types.h:67
bool local_index(dof_id_type dof_index) const
Definition: dof_map.h:831

◆ 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 3377 of file dof_map_constraints.C.

References _dof_constraints, _primal_constraint_values, std::abs(), 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(), libMesh::make_range(), mesh, libMesh::DenseMatrixBase< T >::n(), libMesh::Real, and libMesh::System::solution.

3379 {
3380  if (!v)
3381  v = system.solution.get();
3382  NumericVector<Number> & vec = *v;
3383 
3384  // We'll assume the vector is closed
3385  libmesh_assert (vec.closed());
3386 
3387  Real max_absolute_error = 0., max_relative_error = 0.;
3388 
3389  const MeshBase & mesh = system.get_mesh();
3390 
3391  libmesh_assert_equal_to (this, &(system.get_dof_map()));
3392 
3393  // indices on each element
3394  std::vector<dof_id_type> local_dof_indices;
3395 
3396  for (const auto & elem : mesh.active_local_element_ptr_range())
3397  {
3398  this->dof_indices(elem, local_dof_indices);
3399  std::vector<dof_id_type> raw_dof_indices = local_dof_indices;
3400 
3401  // Constraint matrix for each element
3403 
3404  this->build_constraint_matrix (C, local_dof_indices);
3405 
3406  // Continue if the element is unconstrained
3407  if (!C.m())
3408  continue;
3409 
3410  libmesh_assert_equal_to (C.m(), raw_dof_indices.size());
3411  libmesh_assert_equal_to (C.n(), local_dof_indices.size());
3412 
3413  for (auto i : make_range(C.m()))
3414  {
3415  // Recalculate any constrained dof owned by this processor
3416  dof_id_type global_dof = raw_dof_indices[i];
3417  if (this->is_constrained_dof(global_dof) &&
3418  global_dof >= vec.first_local_index() &&
3419  global_dof < vec.last_local_index())
3420  {
3421 #ifndef NDEBUG
3422  DofConstraints::const_iterator
3423  pos = _dof_constraints.find(global_dof);
3424 
3425  libmesh_assert (pos != _dof_constraints.end());
3426 #endif
3427 
3428  Number exact_value = 0;
3429  DofConstraintValueMap::const_iterator rhsit =
3430  _primal_constraint_values.find(global_dof);
3431  if (rhsit != _primal_constraint_values.end())
3432  exact_value = rhsit->second;
3433 
3434  for (auto j : make_range(C.n()))
3435  {
3436  if (local_dof_indices[j] != global_dof)
3437  exact_value += C(i,j) *
3438  vec(local_dof_indices[j]);
3439  }
3440 
3441  max_absolute_error = std::max(max_absolute_error,
3442  std::abs(vec(global_dof) - exact_value));
3443  max_relative_error = std::max(max_relative_error,
3444  std::abs(vec(global_dof) - exact_value)
3445  / std::abs(exact_value));
3446  }
3447  }
3448  }
3449 
3450  return std::pair<Real, Real>(max_absolute_error, max_relative_error);
3451 }
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:1992
MeshBase & mesh
unsigned int m() const
const MeshBase & get_mesh() const
Definition: system.h:2277
Number exact_value(const Point &p, const Parameters &parameters, const std::string &, const std::string &)
This is the MeshBase class.
Definition: mesh_base.h:74
ADRealEigenVector< T, D, asd > abs(const ADRealEigenVector< T, D, asd > &)
Definition: type_vector.h:57
std::unique_ptr< NumericVector< Number > > solution
Data structure to hold solution values.
Definition: system.h:1573
libmesh_assert(ctx)
bool is_constrained_dof(const dof_id_type dof) const
Definition: dof_map.h:2182
DofConstraints _dof_constraints
Data structure containing DOF constraints.
Definition: dof_map.h:2033
virtual bool closed() const
virtual numeric_index_type first_local_index() const =0
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
DofConstraintValueMap _primal_constraint_values
Definition: dof_map.h:2035
IntRange< T > make_range(T beg, T end)
The 2-parameter make_range() helper function returns an IntRange<T> when both input parameters are of...
Definition: int_range.h:134
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...
unsigned int n() const
const DofMap & get_dof_map() const
Definition: system.h:2293
virtual numeric_index_type last_local_index() const =0
uint8_t dof_id_type
Definition: id_types.h:67

◆ merge_ghost_functor_outputs()

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

Definition at line 1440 of file dof_map.C.

References libMesh::Elem::active(), libMesh::Elem::active_family_tree(), libMesh::as_range(), and libMesh::libmesh_assert().

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

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  // A GhostingFunctor should only return active elements, but
1456  // I forgot to *document* that, so let's go as easy as we
1457  // can on functors that return inactive elements.
1458 #if defined(LIBMESH_ENABLE_DEPRECATED) && defined(LIBMESH_ENABLE_AMR)
1459  std::vector<std::pair<const Elem*, const CouplingMatrix*>> children_to_couple;
1460  for (auto it = more_elements_to_ghost.begin();
1461  it != more_elements_to_ghost.end();)
1462  {
1463  const Elem * elem = it->first;
1464  if (!elem->active())
1465  {
1466  libmesh_deprecated();
1467  std::vector<const Elem*> children_to_ghost;
1468  elem->active_family_tree(children_to_ghost,
1469  /*reset=*/ false);
1470  for (const Elem * child : children_to_ghost)
1471  if (child->processor_id() != p)
1472  children_to_couple.emplace_back(child, it->second);
1473 
1474  it = more_elements_to_ghost.erase(it);
1475  }
1476  else
1477  ++it;
1478  }
1479  more_elements_to_ghost.insert(children_to_couple.begin(),
1480  children_to_couple.end());
1481 #endif
1482 
1483  for (const auto & [elem, elem_cm] : more_elements_to_ghost)
1484  {
1485  // At this point we should only have active elements, even
1486  // if we had to fix up gf output to get here.
1487  libmesh_assert(elem->active());
1488 
1489  GhostingFunctor::map_type::iterator existing_it =
1490  elements_to_ghost.find (elem);
1491 
1492  if (existing_it == elements_to_ghost.end())
1493  elements_to_ghost.emplace(elem, elem_cm);
1494  else
1495  {
1496  if (existing_it->second)
1497  {
1498  if (elem_cm)
1499  {
1500  // If this isn't already a temporary
1501  // then we need to make one so we'll
1502  // have a non-const matrix to merge
1503  if (temporary_coupling_matrices.empty() ||
1504  !temporary_coupling_matrices.count(existing_it->second))
1505  {
1506  // Make copy. This just calls the
1507  // compiler-generated copy constructor
1508  // because the CouplingMatrix class does not
1509  // define a custom copy constructor.
1510  auto result_pr = temporary_coupling_matrices.insert(std::make_unique<CouplingMatrix>(*existing_it->second));
1511  existing_it->second = result_pr.first->get();
1512  }
1513 
1514  // Merge elem_cm into existing CouplingMatrix
1515  const_cast<CouplingMatrix &>(*existing_it->second) &= *elem_cm;
1516  }
1517  else // elem_cm == nullptr
1518  {
1519  // Any existing_it matrix merged with a full
1520  // matrix (symbolized as nullptr) gives another
1521  // full matrix (symbolizable as nullptr).
1522 
1523  // So if existing_it->second is a temporary then
1524  // we don't need it anymore; we might as well
1525  // remove it to keep the set of temporaries
1526  // small.
1527  auto temp_it = temporary_coupling_matrices.find(existing_it->second);
1528  if (temp_it != temporary_coupling_matrices.end())
1529  temporary_coupling_matrices.erase(temp_it);
1530 
1531  existing_it->second = nullptr;
1532  }
1533  }
1534  // else we have a nullptr already, then we have a full
1535  // coupling matrix, already, and merging with anything
1536  // else won't change that, so we're done.
1537  }
1538  }
1539  }
1540 }
std::map< const Elem *, const CouplingMatrix *, CompareDofObjectsByPIDAndThenID > map_type
What elements do we care about and what variables do we care about on each element?
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_assert(ctx)

◆ 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 1710 of file dof_map_constraints.C.

References libMesh::ParallelObject::comm(), n_local_constrained_dofs(), and TIMPI::Communicator::sum().

Referenced by ConstraintOperatorTest::test1DCoarseningNewNodes(), ConstraintOperatorTest::test1DCoarseningOperator(), and MeshInputTest::testDynaReadPatch().

1711 {
1712  parallel_object_only();
1713 
1714  dof_id_type nc_dofs = this->n_local_constrained_dofs();
1715  this->comm().sum(nc_dofs);
1716  return nc_dofs;
1717 }
dof_id_type n_local_constrained_dofs() const
void sum(T &r) const
const Parallel::Communicator & comm() const
uint8_t dof_id_type
Definition: id_types.h:67

◆ 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 908 of file dof_map.h.

References _node_constraints.

909  { return cast_int<dof_id_type>(_node_constraints.size()); }
NodeConstraints _node_constraints
Data structure containing DofObject constraints.
Definition: dof_map.h:2044

◆ 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 675 of file dof_map.h.

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().

676  {
677  libmesh_assert_less (proc, _first_df.size());
678  return cast_int<dof_id_type>(_end_df[proc] - _first_df[proc]);
679  }
std::vector< dof_id_type > _end_df
Last DOF index (plus 1) on processor p.
Definition: dof_map.h:1884
std::vector< dof_id_type > _first_df
First DOF index on processor p.
Definition: dof_map.h:1879

◆ 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 1720 of file dof_map_constraints.C.

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

Referenced by n_constrained_dofs().

1721 {
1722  const DofConstraints::const_iterator lower =
1723  _dof_constraints.lower_bound(this->first_dof()),
1724  upper =
1725  _dof_constraints.lower_bound(this->end_dof());
1726 
1727  return cast_int<dof_id_type>(std::distance(lower, upper));
1728 }
Real distance(const Point &p)
DofConstraints _dof_constraints
Data structure containing DOF constraints.
Definition: dof_map.h:2033
dof_id_type end_dof() const
Definition: dof_map.h:711
dof_id_type first_dof() const
Definition: dof_map.h:687

◆ 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 669 of file dof_map.h.

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

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

670  { return this->n_dofs_on_processor (this->processor_id()); }
dof_id_type n_dofs_on_processor(const processor_id_type proc) const
Definition: dof_map.h:675
processor_id_type processor_id() const

◆ n_objects()

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

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

Definition at line 85 of file reference_counter.h.

References libMesh::ReferenceCounter::_n_objects.

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

86  { return _n_objects; }
static Threads::atomic< unsigned int > _n_objects
The number of 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 1542 of file dof_map.h.

References _n_old_dfs.

Referenced by libMesh::BuildProjectionList::operator()(), and SCALAR_dof_indices().

1542 { return _n_old_dfs; }
dof_id_type _n_old_dfs
Total number of degrees of freedom on old dof objects.
Definition: dof_map.h:2004

◆ n_processors()

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

Definition at line 103 of file parallel_object.h.

References libMesh::ParallelObject::_communicator, libMesh::libmesh_assert(), and TIMPI::Communicator::size().

Referenced by libMesh::Partitioner::_find_global_index_by_pid_map(), 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::System::add_vector(), libMesh::LaplaceMeshSmoother::allgather_graph(), allgather_recursive_constraints(), libMesh::FEMSystem::assembly(), libMesh::Nemesis_IO::assert_symmetric_cmaps(), libMesh::Partitioner::assign_partitioning(), libMesh::AztecLinearSolver< T >::AztecLinearSolver(), libMesh::EquationSystems::build_parallel_elemental_solution_vector(), libMesh::DistributedMesh::clear(), libMesh::DistributedMesh::clear_elems(), libMesh::Nemesis_IO_Helper::compute_border_node_ids(), libMesh::Nemesis_IO_Helper::construct_nemesis_filename(), libMesh::ExodusII_IO::copy_scalar_solution(), libMesh::Nemesis_IO::copy_scalar_solution(), libMesh::UnstructuredMesh::create_pid_mesh(), libMesh::MeshTools::create_processor_bounding_box(), distribute_dofs(), distribute_scalar_dofs(), libMesh::DistributedMesh::DistributedMesh(), libMesh::EnsightIO::EnsightIO(), libMesh::RBEIMEvaluation::gather_bfs(), libMesh::MeshBase::get_info(), libMesh::SystemSubsetBySubdomain::init(), libMesh::PetscDMWrapper::init_and_attach_petscdm(), libMesh::Nemesis_IO_Helper::initialize(), libMesh::ExodusII_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::n_active_elem_on_proc(), libMesh::MeshBase::n_elem_on_proc(), libMesh::MeshBase::n_nodes_on_proc(), libMesh::RBEIMEvaluation::node_gather_bfs(), libMesh::Partitioner::partition(), libMesh::MeshBase::partition(), libMesh::Partitioner::partition_unpartitioned_elements(), 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(), libMesh::Partitioner::repartition(), OverlappingFunctorTest::run_partitioner_test(), scatter_constraints(), libMesh::DistributedMesh::set_next_unique_id(), set_nonlocal_dof_objects(), libMesh::PetscDMWrapper::set_point_range_in_section(), WriteVecAndScalar::setupTests(), libMesh::RBEIMEvaluation::side_gather_bfs(), DistributedMeshTest::testRemoteElemError(), CheckpointIOTest::testSplitter(), libMesh::MeshRefinement::uniformly_coarsen(), libMesh::DistributedMesh::update_parallel_id_counts(), libMesh::GMVIO::write_binary(), libMesh::GMVIO::write_discontinuous_gmv(), libMesh::ExodusII_IO_Helper::write_nodal_coordinates(), libMesh::VTKIO::write_nodal_data(), libMesh::ExodusII_IO::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().

104  {
105  processor_id_type returnval =
106  cast_int<processor_id_type>(_communicator.size());
107  libmesh_assert(returnval); // We never have an empty comm
108  return returnval;
109  }
const Parallel::Communicator & _communicator
processor_id_type size() const
uint8_t processor_id_type
libmesh_assert(ctx)

◆ n_SCALAR_dofs()

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

Definition at line 664 of file dof_map.h.

References _n_SCALAR_dofs.

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

664 { return _n_SCALAR_dofs; }
dof_id_type _n_SCALAR_dofs
The total number of SCALAR dofs associated to all SCALAR variables.
Definition: dof_map.h:1997

◆ 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 613 of file dof_map.h.

References _variable_groups.

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

614  { return cast_int<unsigned int>(_variable_groups.size()); }
std::vector< VariableGroup > _variable_groups
The finite element type for each variable group.
Definition: dof_map.h:1847

◆ 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 621 of file dof_map.h.

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()(), process_mesh_constraint_rows(), reinit(), use_coupled_neighbor_dofs(), and var_group_from_var_number().

622  { return cast_int<unsigned int>(_variables.size()); }
std::vector< Variable > _variables
The finite element type for each variable.
Definition: dof_map.h:1842

◆ 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 1061 of file dof_map.h.

References _node_constraints.

1062  { return _node_constraints.begin(); }
NodeConstraints _node_constraints
Data structure containing DofObject constraints.
Definition: dof_map.h:2044

◆ 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 1067 of file dof_map.h.

References _node_constraints.

1068  { return _node_constraints.end(); }
NodeConstraints _node_constraints
Data structure containing DofObject constraints.
Definition: dof_map.h:2044

◆ 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 341 of file dof_map.C.

References mesh.

Referenced by distribute_dofs().

342 {
343  return mesh.node_ptr(i);
344 }
MeshBase & mesh

◆ 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 2283 of file dof_map.C.

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

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

2287 {
2288  const DofObject & old_obj = elem.node_ref(n).get_old_dof_object_ref();
2289  this->_node_dof_indices(elem, n, old_obj, di, vn);
2290 }
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:2296

◆ 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 2630 of file dof_map.C.

References _dont_p_refine, libMesh::Variable::active_on_subdomain(), libMesh::DofObject::dof_number(), libMesh::FEInterface::extra_hanging_dofs(), libMesh::FEType::family, libMesh::MeshTools::Subdivision::find_one_ring(), libMesh::Elem::get_nodes(), libMesh::DofObject::get_old_dof_object(), libMesh::DofObject::get_old_dof_object_ref(), libMesh::DofObject::has_dofs(), libMesh::Elem::infinite(), int, libMesh::DofObject::invalid_id, libMesh::invalid_uint, libMesh::Elem::JUST_COARSENED, libMesh::Elem::JUST_REFINED, 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::FEType::order, libMesh::Elem::p_level(), libMesh::Elem::p_refinement_flag(), libMesh::SCALAR, SCALAR_dof_indices(), libMesh::Elem::subdomain_id(), sys_number(), libMesh::TRI3SUBDIVISION, libMesh::Variable::type(), libMesh::Elem::type(), and variable_group().

2633 {
2634  LOG_SCOPE("old_dof_indices()", "DofMap");
2635 
2636  libmesh_assert(elem);
2637 
2638  const ElemType type = elem->type();
2639  const unsigned int sys_num = this->sys_number();
2640  const unsigned int n_var_groups = this->n_variable_groups();
2641 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
2642  const bool is_inf = elem->infinite();
2643 #endif
2644 
2645  // If we have dof indices stored on the elem, and there's no chance
2646  // that we only have those indices because we were just p refined,
2647  // then we should have old dof indices too.
2648  libmesh_assert(!elem->has_dofs(sys_num) ||
2649  elem->p_refinement_flag() == Elem::JUST_REFINED ||
2650  elem->get_old_dof_object());
2651 
2652  // Clear the DOF indices vector.
2653  di.clear();
2654 
2655  // Determine the nodes contributing to element elem
2656  std::vector<const Node *> elem_nodes;
2657  const Node * const * nodes_ptr;
2658  unsigned int n_nodes;
2659  if (elem->type() == TRI3SUBDIVISION)
2660  {
2661  // Subdivision surface FE require the 1-ring around elem
2662  const Tri3Subdivision * sd_elem = static_cast<const Tri3Subdivision *>(elem);
2663  MeshTools::Subdivision::find_one_ring(sd_elem, elem_nodes);
2664  nodes_ptr = elem_nodes.data();
2665  n_nodes = cast_int<unsigned int>(elem_nodes.size());
2666  }
2667  else
2668  {
2669  // All other FE use only the nodes of elem itself
2670  nodes_ptr = elem->get_nodes();
2671  n_nodes = elem->n_nodes();
2672  }
2673 
2674  // Get the dof numbers
2675  for (unsigned int vg=0; vg<n_var_groups; vg++)
2676  {
2677  const VariableGroup & var = this->variable_group(vg);
2678  const unsigned int vars_in_group = var.n_variables();
2679 
2680  for (unsigned int vig=0; vig<vars_in_group; vig++)
2681  {
2682  const unsigned int v = var.number(vig);
2683  if ((vn == v) || (vn == libMesh::invalid_uint))
2684  {
2685  if (var.type().family == SCALAR &&
2686  (!elem ||
2687  var.active_on_subdomain(elem->subdomain_id())))
2688  {
2689  // We asked for this variable, so add it to the vector.
2690  std::vector<dof_id_type> di_new;
2691  this->SCALAR_dof_indices(di_new,v,true);
2692  di.insert( di.end(), di_new.begin(), di_new.end());
2693  }
2694  else
2695  if (var.active_on_subdomain(elem->subdomain_id()))
2696  { // Do this for all the variables if one was not specified
2697  // or just for the specified variable
2698 
2699  FEType fe_type = var.type();
2700  const bool add_p_level =
2701 #ifdef LIBMESH_ENABLE_AMR
2702  !_dont_p_refine.count(vg);
2703 #else
2704  false;
2705 #endif
2706  // Increase the polynomial order on p refined elements,
2707  // but make sure you get the right polynomial order for
2708  // the OLD degrees of freedom
2709  int p_adjustment = 0;
2710  if (elem->p_refinement_flag() == Elem::JUST_REFINED)
2711  {
2712  libmesh_assert_greater (elem->p_level(), 0);
2713  p_adjustment = -1;
2714  }
2715  else if (elem->p_refinement_flag() == Elem::JUST_COARSENED)
2716  {
2717  p_adjustment = 1;
2718  }
2719  p_adjustment *= add_p_level;
2720 
2721  // Compute the net amount of "extra" order, including Elem::p_level()
2722  int extra_order = int(add_p_level*elem->p_level()) + p_adjustment;
2723 
2724  const bool extra_hanging_dofs =
2726 
2727  const FEInterface::n_dofs_at_node_ptr ndan =
2728  FEInterface::n_dofs_at_node_function(fe_type, elem);
2729 
2730  // Get the node-based DOF numbers
2731  for (unsigned int n=0; n<n_nodes; n++)
2732  {
2733  const Node * node = nodes_ptr[n];
2734  const DofObject & old_dof_obj = node->get_old_dof_object_ref();
2735 
2736  // There is a potential problem with h refinement. Imagine a
2737  // quad9 that has a linear FE on it. Then, on the hanging side,
2738  // it can falsely identify a DOF at the mid-edge node. This is why
2739  // we call FEInterface instead of node->n_comp() directly.
2740  const unsigned int nc =
2741 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
2742  is_inf ?
2743  FEInterface::n_dofs_at_node(var.type(), extra_order, elem, n) :
2744 #endif
2745  ndan (type, static_cast<Order>(var.type().order + extra_order), n);
2746 
2747  const int n_comp = old_dof_obj.n_comp_group(sys_num,vg);
2748 
2749  // If this is a non-vertex on a hanging node with extra
2750  // degrees of freedom, we use the non-vertex dofs (which
2751  // come in reverse order starting from the end, to
2752  // simplify p refinement)
2753  if (extra_hanging_dofs && !elem->is_vertex(n))
2754  {
2755  const int dof_offset = n_comp - nc;
2756 
2757  // We should never have fewer dofs than necessary on a
2758  // node unless we're getting indices on a parent element
2759  // or a just-coarsened element
2760  if (dof_offset < 0)
2761  {
2762  libmesh_assert(!elem->active() || elem->refinement_flag() ==
2764  di.resize(di.size() + nc, DofObject::invalid_id);
2765  }
2766  else
2767  for (int i=n_comp-1; i>=dof_offset; i--)
2768  {
2769  const dof_id_type d =
2770  old_dof_obj.dof_number(sys_num, vg, vig, i, n_comp);
2771 
2772  // On a newly-expanded subdomain, we
2773  // may have some DoFs that didn't
2774  // exist in the old system, in which
2775  // case we can't assert this:
2776  // libmesh_assert_not_equal_to (d, DofObject::invalid_id);
2777 
2778  di.push_back(d);
2779  }
2780  }
2781  // If this is a vertex or an element without extra hanging
2782  // dofs, our dofs come in forward order coming from the
2783  // beginning. But we still might not have all
2784  // those dofs on the old_dof_obj, in cases
2785  // where a subdomain-restricted variable just
2786  // had its subdomain expanded.
2787  else
2788  {
2789  const unsigned int old_nc =
2790  std::min(static_cast<unsigned int>(n_comp), nc);
2791  for (unsigned int i=0; i != old_nc; ++i)
2792  {
2793  const dof_id_type d =
2794  old_dof_obj.dof_number(sys_num, vg, vig, i, n_comp);
2795 
2796  libmesh_assert_not_equal_to (d, DofObject::invalid_id);
2797 
2798  di.push_back(d);
2799  }
2800  for (unsigned int i=old_nc; i != nc; ++i)
2801  di.push_back(DofObject::invalid_id);
2802  }
2803  }
2804 
2805  // If there are any element-based DOF numbers, get them
2806  const unsigned int nc =
2807  FEInterface::n_dofs_per_elem(fe_type, extra_order, elem);
2808 
2809  if (nc != 0)
2810  {
2811  const DofObject & old_dof_obj = elem->get_old_dof_object_ref();
2812 
2813  const unsigned int n_comp =
2814  old_dof_obj.n_comp_group(sys_num,vg);
2815 
2816  if (old_dof_obj.n_systems() > sys_num &&
2817  nc <= n_comp)
2818  {
2819 
2820  for (unsigned int i=0; i<nc; i++)
2821  {
2822  const dof_id_type d =
2823  old_dof_obj.dof_number(sys_num, vg, vig, i, n_comp);
2824 
2825  di.push_back(d);
2826  }
2827  }
2828  else
2829  {
2830  // We should never have fewer dofs than
2831  // necessary on an element unless we're
2832  // getting indices on a parent element, a
2833  // just-coarsened element ... or a
2834  // subdomain-restricted variable with a
2835  // just-expanded subdomain
2836  // libmesh_assert(!elem->active() || fe_type.family == LAGRANGE ||
2837  // elem->refinement_flag() == Elem::JUST_COARSENED);
2838  di.resize(di.size() + nc, DofObject::invalid_id);
2839  }
2840  }
2841  }
2842  }
2843  } // end loop over variables within group
2844  } // end loop over variable groups
2845 }
static unsigned int n_dofs_per_elem(const unsigned int dim, const FEType &fe_t, const ElemType t)
Definition: fe_interface.C:772
ElemType
Defines an enum for geometric element types.
unsigned int n_variable_groups() const
Definition: dof_map.h:613
const unsigned int invalid_uint
A number which is used quite often to represent an invalid or uninitialized value for an unsigned int...
Definition: libmesh.h:286
unsigned int sys_number() const
Definition: dof_map.h:2096
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:2544
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.
const dof_id_type n_nodes
Definition: tecplot_io.C:67
static bool extra_hanging_dofs(const FEType &fe_t)
libmesh_assert(ctx)
static const dof_id_type invalid_id
An invalid id to distinguish an uninitialized DofObject.
Definition: dof_object.h:477
const VariableGroup & variable_group(const unsigned int c) const
Definition: dof_map.h:2104
static n_dofs_at_node_ptr n_dofs_at_node_function(const unsigned int dim, const FEType &fe_t)
Definition: fe_interface.C:702
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:679
unsigned int(* n_dofs_at_node_ptr)(const ElemType, const Order, const unsigned int)
Definition: fe_interface.h:170
std::unordered_set< unsigned int > _dont_p_refine
A container of variable groups that we should not p-refine.
Definition: dof_map.h:2025
void ErrorVector unsigned int
Definition: adjoints_ex3.C:360
uint8_t dof_id_type
Definition: id_types.h:67

◆ 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 1692 of file dof_map.C.

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

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

1693 {
1694  LOG_SCOPE("prepare_send_list()", "DofMap");
1695 
1696  // Return immediately if there's no ghost data
1697  if (this->n_processors() == 1)
1698  return;
1699 
1700  // Check to see if we have any extra stuff to add to the send_list
1702  {
1703  if (_augment_send_list)
1704  {
1705  libmesh_here();
1706  libMesh::out << "WARNING: You have specified both an extra send list function and object.\n"
1707  << " Are you sure this is what you meant to do??"
1708  << std::endl;
1709  }
1710 
1712  }
1713 
1714  if (_augment_send_list)
1716 
1717  // First sort the send list. After this
1718  // duplicated elements will be adjacent in the
1719  // vector
1720  std::sort(_send_list.begin(), _send_list.end());
1721 
1722  // Now use std::unique to remove duplicate entries
1723  std::vector<dof_id_type>::iterator new_end =
1724  std::unique (_send_list.begin(), _send_list.end());
1725 
1726  // Remove the end of the send_list. Use the "swap trick"
1727  // from Effective STL
1728  std::vector<dof_id_type> (_send_list.begin(), new_end).swap (_send_list);
1729 
1730  // Make sure the send list has nothing invalid in it.
1731  libmesh_assert(_send_list.empty() || _send_list.back() < this->n_dofs());
1732 }
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:1896
virtual void augment_send_list(std::vector< dof_id_type > &send_list)=0
User-defined function to augment the send list.
AugmentSendList * _augment_send_list
Function object to call to add extra entries to the send list.
Definition: dof_map.h:1918
processor_id_type n_processors() const
dof_id_type n_dofs() const
Definition: dof_map.h:659
libmesh_assert(ctx)
void * _extra_send_list_context
A pointer associated with the extra send list that can optionally be passed in.
Definition: dof_map.h:1928
OStreamProxy out
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:1923

◆ 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 2258 of file dof_map_constraints.C.

References libMesh::ParallelObject::comm(), get_local_constraints(), libMesh::ParallelObject::n_processors(), libMesh::ParallelObject::processor_id(), TIMPI::Communicator::receive(), and TIMPI::Communicator::send().

Referenced by main().

2260 {
2261  parallel_object_only();
2262 
2263  std::string local_constraints =
2264  this->get_local_constraints(print_nonlocal);
2265 
2266  if (this->processor_id())
2267  {
2268  this->comm().send(0, local_constraints);
2269  }
2270  else
2271  {
2272  os << "Processor 0:\n";
2273  os << local_constraints;
2274 
2275  for (auto p : IntRange<processor_id_type>(1, this->n_processors()))
2276  {
2277  this->comm().receive(p, local_constraints);
2278  os << "Processor " << p << ":\n";
2279  os << local_constraints;
2280  }
2281  }
2282 }
std::string get_local_constraints(bool print_nonlocal=false) const
Gets a string reporting all DoF and Node constraints local to this processor.
The IntRange templated class is intended to make it easy to loop over integers which are indices of a...
Definition: int_range.h:53
const Parallel::Communicator & comm() const
processor_id_type n_processors() const
Status receive(const unsigned int dest_processor_id, T &buf, const MessageTag &tag=any_tag) const
void send(const unsigned int dest_processor_id, const T &buf, const MessageTag &tag=no_tag) const
processor_id_type processor_id() const

◆ print_info() [1/2]

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

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

Definition at line 81 of file reference_counter.C.

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

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

82 {
84  out_stream << ReferenceCounter::get_info();
85 }
static std::string get_info()
Gets a string containing the reference information.
static bool _enable_print_counter
Flag to control whether reference count information is printed when print_info is called...

◆ print_info() [2/2]

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

Prints summary info about the sparsity bandwidth and constraints.

Definition at line 2915 of file dof_map.C.

References get_info().

2916 {
2917  os << this->get_info();
2918 }
std::string get_info() const
Gets summary info about the sparsity bandwidth and constraints.
Definition: dof_map.C:2922

◆ 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 4368 of file dof_map_constraints.C.

References _adjoint_constraint_values, _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().

4369 {
4370  // We've computed our local constraints, but they may depend on
4371  // non-local constraints that we'll need to take into account.
4372  this->allgather_recursive_constraints(mesh);
4373 
4375  {
4376  // Optionally check for constraint loops and throw an error
4377  // if they're detected. We always do this check below in dbg/devel
4378  // mode but here we optionally do it in opt mode as well.
4380  }
4381 
4382  // Adjoints will be constrained where the primal is
4383  // Therefore, we will expand the adjoint_constraint_values
4384  // map whenever the primal_constraint_values map is expanded
4385 
4386  // First, figure out the total number of QoIs
4387  const unsigned int max_qoi_num =
4388  _adjoint_constraint_values.empty() ?
4389  0 : _adjoint_constraint_values.rbegin()->first+1;
4390 
4391  // Create a set containing the DOFs we already depend on
4392  typedef std::set<dof_id_type> RCSet;
4393  RCSet unexpanded_set;
4394 
4395  for (const auto & i : _dof_constraints)
4396  unexpanded_set.insert(i.first);
4397 
4398  while (!unexpanded_set.empty())
4399  for (RCSet::iterator i = unexpanded_set.begin();
4400  i != unexpanded_set.end(); /* nothing */)
4401  {
4402  // If the DOF is constrained
4403  DofConstraints::iterator
4404  pos = _dof_constraints.find(*i);
4405 
4406  libmesh_assert (pos != _dof_constraints.end());
4407 
4408  DofConstraintRow & constraint_row = pos->second;
4409 
4410  DofConstraintValueMap::iterator rhsit =
4411  _primal_constraint_values.find(*i);
4412  Number constraint_rhs = (rhsit == _primal_constraint_values.end()) ?
4413  0 : rhsit->second;
4414 
4415  // A vector of DofConstraintValueMaps for each adjoint variable
4416  std::vector<DofConstraintValueMap::iterator> adjoint_rhs_iterators;
4417  adjoint_rhs_iterators.resize(max_qoi_num);
4418 
4419  // Another to hold the adjoint constraint rhs
4420  std::vector<Number> adjoint_constraint_rhs(max_qoi_num, 0.0);
4421 
4422  // Find and gather recursive constraints for each adjoint variable
4423  for (auto & adjoint_map : _adjoint_constraint_values)
4424  {
4425  const std::size_t q = adjoint_map.first;
4426  adjoint_rhs_iterators[q] = adjoint_map.second.find(*i);
4427 
4428  adjoint_constraint_rhs[q] =
4429  (adjoint_rhs_iterators[q] == adjoint_map.second.end()) ?
4430  0 : adjoint_rhs_iterators[q]->second;
4431  }
4432 
4433  std::vector<dof_id_type> constraints_to_expand;
4434 
4435  for (const auto & item : constraint_row)
4436  if (item.first != *i && this->is_constrained_dof(item.first))
4437  {
4438  unexpanded_set.insert(item.first);
4439  constraints_to_expand.push_back(item.first);
4440  }
4441 
4442  for (const auto & expandable : constraints_to_expand)
4443  {
4444  const Real this_coef = constraint_row[expandable];
4445 
4446  DofConstraints::const_iterator
4447  subpos = _dof_constraints.find(expandable);
4448 
4449  libmesh_assert (subpos != _dof_constraints.end());
4450 
4451  const DofConstraintRow & subconstraint_row = subpos->second;
4452 
4453  for (const auto & item : subconstraint_row)
4454  {
4455  // Assert that the constraint does not form a cycle.
4456  libmesh_assert(item.first != expandable);
4457  constraint_row[item.first] += item.second * this_coef;
4458  }
4459 
4460  DofConstraintValueMap::const_iterator subrhsit =
4461  _primal_constraint_values.find(expandable);
4462  if (subrhsit != _primal_constraint_values.end())
4463  constraint_rhs += subrhsit->second * this_coef;
4464 
4465  // Find and gather recursive constraints for each adjoint variable
4466  for (const auto & adjoint_map : _adjoint_constraint_values)
4467  {
4468  const std::size_t q = adjoint_map.first;
4469 
4470  DofConstraintValueMap::const_iterator adjoint_subrhsit =
4471  adjoint_map.second.find(expandable);
4472 
4473  if (adjoint_subrhsit != adjoint_map.second.end())
4474  adjoint_constraint_rhs[q] += adjoint_subrhsit->second * this_coef;
4475  }
4476 
4477  constraint_row.erase(expandable);
4478  }
4479 
4480  if (rhsit == _primal_constraint_values.end())
4481  {
4482  if (constraint_rhs != Number(0))
4483  _primal_constraint_values[*i] = constraint_rhs;
4484  else
4485  _primal_constraint_values.erase(*i);
4486  }
4487  else
4488  {
4489  if (constraint_rhs != Number(0))
4490  rhsit->second = constraint_rhs;
4491  else
4492  _primal_constraint_values.erase(rhsit);
4493  }
4494 
4495  // Finally fill in the adjoint constraints for each adjoint variable if possible
4496  for (auto & adjoint_map : _adjoint_constraint_values)
4497  {
4498  const std::size_t q = adjoint_map.first;
4499 
4500  if(adjoint_rhs_iterators[q] == adjoint_map.second.end())
4501  {
4502  if (adjoint_constraint_rhs[q] != Number(0))
4503  (adjoint_map.second)[*i] = adjoint_constraint_rhs[q];
4504  else
4505  adjoint_map.second.erase(*i);
4506  }
4507  else
4508  {
4509  if (adjoint_constraint_rhs[q] != Number(0))
4510  adjoint_rhs_iterators[q]->second = adjoint_constraint_rhs[q];
4511  else
4512  adjoint_map.second.erase(adjoint_rhs_iterators[q]);
4513  }
4514  }
4515 
4516  if (constraints_to_expand.empty())
4517  i = unexpanded_set.erase(i);
4518  else
4519  ++i;
4520  }
4521 
4522  // In parallel we can't guarantee that nodes/dofs which constrain
4523  // others are on processors which are aware of that constraint, yet
4524  // we need such awareness for sparsity pattern generation. So send
4525  // other processors any constraints they might need to know about.
4526  this->scatter_constraints(mesh);
4527 
4528  // Now that we have our root constraint dependencies sorted out, add
4529  // them to the send_list
4531 }
void scatter_constraints(MeshBase &)
Sends constraint equations to constraining processors.
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:1831
AdjointDofConstraintValues _adjoint_constraint_values
Definition: dof_map.h:2037
libmesh_assert(ctx)
void allgather_recursive_constraints(MeshBase &)
Gathers constraint equation dependencies from other processors.
DofConstraints _dof_constraints
Data structure containing DOF constraints.
Definition: dof_map.h:2033
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
void add_constraints_to_send_list()
Adds entries to the _send_list vector corresponding to DoFs which are dependencies for constraint equ...
DofConstraintValueMap _primal_constraint_values
Definition: dof_map.h:2035
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:90

◆ process_mesh_constraint_rows()

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

Adds any spline constraints from the Mesh to our DoF constraints.

If any Dirichlet constraints exist on spline-constrained nodes, l2-projects those constraints onto the spline basis.

Definition at line 1894 of file dof_map_constraints.C.

References _adjoint_constraint_values, _dof_constraints, _periodic_boundaries, _primal_constraint_values, add_constraint_row(), libMesh::LinearSolver< T >::build(), libMesh::SparseMatrix< T >::build(), libMesh::NumericVector< T >::build(), build_sparsity(), libMesh::ParallelObject::comm(), dof_indices(), libMesh::DofObject::dof_number(), libMesh::MeshBase::elem_ptr(), end_dof(), libMesh::FEType::family, first_dof(), libMesh::MeshBase::get_constraint_rows(), heterogeneously_constrain_element_matrix_and_vector(), libMesh::DofObject::id(), libMesh::if(), is_constrained_dof(), libMesh::Parallel::Utils::is_sorted(), libMesh::LAGRANGE, libMesh::libmesh_assert(), local_index(), TIMPI::Communicator::max(), mesh, TIMPI::Communicator::min(), n_dofs(), n_local_dofs(), n_variables(), libMesh::MeshBase::node_ptr(), libMesh::Elem::node_ref(), libMesh::PARALLEL, libMesh::ParallelObject::processor_id(), libMesh::DofObject::processor_id(), libMesh::RATIONAL_BERNSTEIN, sys_number(), libMesh::TOLERANCE, and variable_type().

Referenced by create_dof_constraints().

1895 {
1896  // If we already have simple Dirichlet constraints (with right hand
1897  // sides but with no coupling between DoFs) on spline-constrained FE
1898  // nodes, then we'll need a solve to compute the corresponding
1899  // constraints on the relevant spline nodes. (If we already have
1900  // constraints with coupling between DoFs on spline-constrained FE
1901  // nodes, then we'll need to go sit down and cry until we figure out
1902  // how to handle that.)
1903 
1904  const auto & constraint_rows = mesh.get_constraint_rows();
1905 
1906  // This routine is too expensive to use unless we really might
1907  // need it
1908 #ifdef DEBUG
1909  bool constraint_rows_empty = constraint_rows.empty();
1910  this->comm().min(constraint_rows_empty);
1911  libmesh_assert(!constraint_rows_empty);
1912 #endif
1913 
1914  // This is fairly new code, still a bit experimental.
1915  libmesh_experimental();
1916 
1917  // We can't handle periodic boundary conditions on spline meshes
1918  // yet.
1919 #ifdef LIBMESH_ENABLE_PERIODIC
1920  libmesh_error_msg_if (!_periodic_boundaries->empty(),
1921  "Periodic boundary conditions are not yet implemented for spline meshes");
1922 #endif
1923 
1924  // We can handle existing Dirichlet constraints, but we'll need
1925  // to do solves to project them down onto the spline basis.
1926  std::unique_ptr<SparsityPattern::Build> sp;
1927  std::unique_ptr<SparseMatrix<Number>> mat;
1928 
1929  const unsigned int n_adjoint_rhs =
1931 
1932  // [0] for primal rhs, [q+1] for adjoint qoi q
1933  std::vector<std::unique_ptr<NumericVector<Number>>>
1934  solve_rhs(n_adjoint_rhs+1);
1935 
1936  // Keep track of which spline DoFs will be Dirichlet.
1937  // We use a set here to make it easier to find what processors
1938  // to send the DoFs to later.
1939  std::set<dof_id_type> my_dirichlet_spline_dofs;
1940 
1941  // And keep track of which non-spline Dofs were Dirichlet
1942  std::unordered_set<dof_id_type> was_previously_constrained;
1943 
1944  const unsigned int sys_num = this->sys_number();
1945  for (auto & node_row : constraint_rows)
1946  {
1947  const Node * node = node_row.first;
1948  libmesh_assert(node == mesh.node_ptr(node->id()));
1949 
1950  // Each processor only computes its own (and in distributed
1951  // cases, is only guaranteed to have the dependency data to
1952  // compute its own) constraints here.
1953  if (node->processor_id() != mesh.processor_id())
1954  continue;
1955 
1956  for (auto var_num : IntRange<unsigned int>(0, this->n_variables()))
1957  {
1958  const FEFamily & fe_family = this->variable_type(var_num).family;
1959 
1960  // constraint_rows only applies to nodal variables
1961  if (fe_family != LAGRANGE &&
1962  fe_family != RATIONAL_BERNSTEIN)
1963  continue;
1964 
1965  DofConstraintRow dc_row;
1966 
1967  const dof_id_type constrained_id =
1968  node->dof_number(sys_num, var_num, 0);
1969  for (const auto & [pr, val] : node_row.second)
1970  {
1971  const Elem * spline_elem = pr.first;
1972  libmesh_assert(spline_elem == mesh.elem_ptr(spline_elem->id()));
1973 
1974  const Node & spline_node =
1975  spline_elem->node_ref(pr.second);
1976 
1977  const dof_id_type spline_dof_id =
1978  spline_node.dof_number(sys_num, var_num, 0);
1979  dc_row[spline_dof_id] = val;
1980  }
1981 
1982  // See if we already have a constraint here.
1983  if (this->is_constrained_dof(constrained_id))
1984  {
1985  was_previously_constrained.insert(constrained_id);
1986 
1987  // Keep track of which spline DoFs will be
1988  // inheriting this non-spline DoF's constraints
1989  for (auto & row_entry : dc_row)
1990  my_dirichlet_spline_dofs.insert(row_entry.first);
1991 
1992  // If it wasn't a simple Dirichlet-type constraint
1993  // then I don't know what to do with it. We'll make
1994  // this an assertion only because this should only
1995  // crop up with periodic boundary conditions, which
1996  // we've already made sure we don't have.
1997  libmesh_assert(_dof_constraints[constrained_id].empty());
1998  }
1999 
2000  // Add the constraint, replacing any previous, so we can
2001  // use the new constraint in setting up the solve below
2002  this->add_constraint_row(constrained_id, dc_row, false);
2003  }
2004  }
2005 
2006  // my_dirichlet_spline_dofs may now include DoFs whose owners
2007  // don't know they need to become spline DoFs! We need to push
2008  // this data to them.
2009  if (this->comm().size() > 1)
2010  {
2011  std::unordered_map
2012  <processor_id_type, std::vector<dof_id_type>>
2013  their_dirichlet_spline_dofs;
2014 
2015  // If we ever change the underlying container here then we'd
2016  // better do some kind of sort before using it; we'll rely
2017  // on sorting to make the processor id lookup efficient.
2018  libmesh_assert(std::is_sorted(my_dirichlet_spline_dofs.begin(),
2019  my_dirichlet_spline_dofs.end()));
2020  processor_id_type destination_pid = 0;
2021  for (auto d : my_dirichlet_spline_dofs)
2022  {
2023  libmesh_assert_less(d, this->end_dof(this->comm().size()-1));
2024  while (d >= this->end_dof(destination_pid))
2025  destination_pid++;
2026 
2027  if (destination_pid != this->processor_id())
2028  their_dirichlet_spline_dofs[destination_pid].push_back(d);
2029  }
2030 
2031  auto receive_dof_functor =
2032  [& my_dirichlet_spline_dofs]
2034  const std::vector<dof_id_type> & dofs)
2035  {
2036  my_dirichlet_spline_dofs.insert(dofs.begin(), dofs.end());
2037  };
2038 
2039  Parallel::push_parallel_vector_data
2040  (this->comm(), their_dirichlet_spline_dofs, receive_dof_functor);
2041  }
2042 
2043 
2044  // If anyone had any prior constraints in effect, then we need
2045  // to convert them to constraints on the spline nodes.
2046  //
2047  // NOT simply testing prior_constraints here; maybe it turned
2048  // out that all our constraints were on non-spline-constrained
2049  // parts of a hybrid mesh?
2050  bool important_prior_constraints =
2051  !was_previously_constrained.empty();
2052  this->comm().max(important_prior_constraints);
2053 
2054  if (important_prior_constraints)
2055  {
2056  // Now that we have the spline constraints added, we can
2057  // finally construct a sparsity pattern that correctly
2058  // accounts for those constraints!
2059  mat = SparseMatrix<Number>::build(this->comm());
2060  for (auto q : IntRange<unsigned int>(0, n_adjoint_rhs+1))
2061  {
2062  solve_rhs[q] = NumericVector<Number>::build(this->comm());
2063  solve_rhs[q]->init(this->n_dofs(), this->n_local_dofs(),
2064  false, PARALLEL);
2065  }
2066 
2067  // We need to compute our own sparsity pattern, to take into
2068  // account the particularly non-sparse rows that can be
2069  // created by the spline constraints we just added.
2070  mat->attach_dof_map(*this);
2071  sp = this->build_sparsity(mesh);
2072  mat->attach_sparsity_pattern(*sp);
2073  mat->init();
2074 
2075  for (auto & node_row : constraint_rows)
2076  {
2077  const Node * node = node_row.first;
2078  libmesh_assert(node == mesh.node_ptr(node->id()));
2079 
2080  for (auto var_num : IntRange<unsigned int>(0, this->n_variables()))
2081  {
2082  const FEFamily & fe_family = this->variable_type(var_num).family;
2083 
2084  // constraint_rows only applies to nodal variables
2085  if (fe_family != LAGRANGE &&
2086  fe_family != RATIONAL_BERNSTEIN)
2087  continue;
2088 
2089  const dof_id_type constrained_id =
2090  node->dof_number(sys_num, var_num, 0);
2091 
2092  if (was_previously_constrained.count(constrained_id))
2093  {
2094  for (auto q : IntRange<int>(0, n_adjoint_rhs+1))
2095  {
2096  DenseMatrix<Number> K(1,1);
2097  DenseVector<Number> F(1);
2098  std::vector<dof_id_type> dof_indices(1, constrained_id);
2099 
2100  K(0,0) = 1;
2101 
2102  DofConstraintValueMap & vals = q ?
2105 
2106  DofConstraintValueMap::const_iterator rhsit =
2107  vals.find(constrained_id);
2108  F(0) = (rhsit == vals.end()) ? 0 : rhsit->second;
2109 
2110  // We no longer need any rhs values here directly.
2111  if (rhsit != vals.end())
2112  vals.erase(rhsit);
2113 
2115  (K, F, dof_indices, false, q ? (q-1) : -1);
2116  if (!q)
2117  mat->add_matrix(K, dof_indices);
2118  solve_rhs[q]->add_vector(F, dof_indices);
2119  }
2120  }
2121  }
2122  }
2123 
2124  // Any DoFs that aren't part of any constraint, directly or
2125  // indirectly, need a diagonal term to make the matrix
2126  // here invertible.
2127  for (dof_id_type d : IntRange<dof_id_type>(this->first_dof(),
2128  this->end_dof()))
2129  if (!was_previously_constrained.count(d) &&
2130  !my_dirichlet_spline_dofs.count(d))
2131  mat->add(d,d,1);
2132 
2133  // At this point, we're finally ready to solve for Dirichlet
2134  // constraint values on spline nodes.
2135  std::unique_ptr<LinearSolver<Number>> linear_solver =
2137 
2138  std::unique_ptr<NumericVector<Number>> projected_vals =
2140 
2141  projected_vals->init(this->n_dofs(), this->n_local_dofs(),
2142  false, PARALLEL);
2143 
2144  DofConstraintRow empty_row;
2145  for (auto sd : my_dirichlet_spline_dofs)
2146  if (this->local_index(sd))
2147  this->add_constraint_row(sd, empty_row);
2148 
2149  for (auto q : IntRange<unsigned int>(0, n_adjoint_rhs+1))
2150  {
2151  // FIXME: we don't have an EquationSystems here, but I'd
2152  // rather not hardcode these...
2153  const double tol = double(TOLERANCE * TOLERANCE);
2154  const unsigned int max_its = 5000;
2155 
2156  linear_solver->solve(*mat, *projected_vals,
2157  *(solve_rhs[q]), tol, max_its);
2158 
2159  DofConstraintValueMap & vals = q ?
2162 
2163  for (auto sd : my_dirichlet_spline_dofs)
2164  if (this->local_index(sd))
2165  {
2166  Number constraint_rhs = (*projected_vals)(sd);
2167 
2168  std::pair<DofConstraintValueMap::iterator, bool> rhs_it =
2169  vals.emplace(sd, constraint_rhs);
2170  if (!rhs_it.second)
2171  rhs_it.first->second = constraint_rhs;
2172  }
2173  }
2174  }
2175 }
FEFamily family
The type of finite element.
Definition: fe_type.h:207
dof_id_type dof_number(const unsigned int s, const unsigned int var, const unsigned int comp) const
Definition: dof_object.h:1025
dof_id_type n_local_dofs() const
Definition: dof_map.h:669
constraint_rows_type & get_constraint_rows()
Definition: mesh_base.h:1683
A Node is like a Point, but with more information.
Definition: node.h:52
The IntRange templated class is intended to make it easy to loop over integers which are indices of a...
Definition: int_range.h:53
static std::unique_ptr< LinearSolver< T > > build(const libMesh::Parallel::Communicator &comm_in, const SolverPackage solver_package=libMesh::default_solver_package())
Builds a LinearSolver using the linear solver package specified by solver_package.
Definition: linear_solver.C:59
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:1992
static constexpr Real TOLERANCE
const FEType & variable_type(const unsigned int c) const
Definition: dof_map.h:2144
This is the base class from which all geometric element types are derived.
Definition: elem.h:94
MeshBase & mesh
unsigned int n_variables() const
Definition: dof_map.h:621
std::unique_ptr< SparsityPattern::Build > build_sparsity(const MeshBase &mesh, bool calculate_constrained=false) const
Builds a sparsity pattern for matrices using the current degree-of-freedom numbering and coupling...
Definition: dof_map.C:64
const Parallel::Communicator & comm() const
static std::unique_ptr< SparseMatrix< T > > build(const Parallel::Communicator &comm, const SolverPackage solver_package=libMesh::default_solver_package(), const MatrixBuildType matrix_build_type=MatrixBuildType::AUTOMATIC)
Builds a SparseMatrix<T> using the linear solver package specified by solver_package.
unsigned int sys_number() const
Definition: dof_map.h:2096
uint8_t processor_id_type
Definition: id_types.h:104
AdjointDofConstraintValues _adjoint_constraint_values
Definition: dof_map.h:2037
uint8_t processor_id_type
dof_id_type n_dofs() const
Definition: dof_map.h:659
const Node & node_ref(const unsigned int i) const
Definition: elem.h:2353
dof_id_type id() const
Definition: dof_object.h:823
void min(const T &r, T &o, Request &req) const
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 ...
bool is_sorted(const std::vector< KeyType > &v)
libmesh_assert(ctx)
bool is_constrained_dof(const dof_id_type dof) const
Definition: dof_map.h:2182
DofConstraints _dof_constraints
Data structure containing DOF constraints.
Definition: dof_map.h:2033
dof_id_type end_dof() const
Definition: dof_map.h:711
static std::unique_ptr< NumericVector< T > > build(const Parallel::Communicator &comm, const SolverPackage solver_package=libMesh::default_solver_package())
Builds a NumericVector on the processors in communicator comm using the linear solver package specifi...
Storage for DofConstraint right hand sides for a particular problem.
Definition: dof_map.h:110
virtual const Elem * elem_ptr(const dof_id_type i) const =0
std::unique_ptr< PeriodicBoundaries > _periodic_boundaries
Data structure containing periodic boundaries.
Definition: dof_map.h:2053
void max(const T &r, T &o, Request &req) const
DofConstraintValueMap _primal_constraint_values
Definition: dof_map.h:2035
void heterogeneously_constrain_element_matrix_and_vector(DenseMatrix< Number > &matrix, DenseVector< Number > &rhs, std::vector< dof_id_type > &elem_dofs, bool asymmetric_constraint_rows=true, int qoi_index=-1) const
Constrains the element matrix and vector.
Definition: dof_map.h:2260
dof_id_type first_dof() const
Definition: dof_map.h:687
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:90
FEFamily
defines an enum for finite element families.
virtual const Node * node_ptr(const dof_id_type i) const =0
processor_id_type processor_id() const
processor_id_type processor_id() const
Definition: dof_object.h:898
uint8_t dof_id_type
Definition: id_types.h:67
bool local_index(dof_id_type dof_index) const
Definition: dof_map.h:831

◆ processor_id()

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

Definition at line 114 of file parallel_object.h.

References libMesh::ParallelObject::_communicator, and TIMPI::Communicator::rank().

Referenced by libMesh::BoundaryInfo::_find_id_maps(), libMesh::PetscDMWrapper::add_dofs_to_section(), libMesh::DistributedMesh::add_elem(), libMesh::BoundaryInfo::add_elements(), add_neighbors_to_send_list(), libMesh::DistributedMesh::add_node(), libMesh::MeshTools::Modification::all_tri(), allgather_recursive_constraints(), libMesh::FEMSystem::assembly(), libMesh::Nemesis_IO::assert_symmetric_cmaps(), libMesh::Partitioner::assign_partitioning(), libMesh::Nemesis_IO_Helper::build_element_and_node_maps(), libMesh::Partitioner::build_graph(), libMesh::InfElemBuilder::build_inf_elem(), libMesh::BoundaryInfo::build_node_list_from_side_list(), libMesh::EquationSystems::build_parallel_elemental_solution_vector(), libMesh::EquationSystems::build_parallel_solution_vector(), libMesh::DistributedMesh::clear(), libMesh::DistributedMesh::clear_elems(), 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_elemental_solution(), libMesh::ExodusII_IO::copy_nodal_solution(), libMesh::ExodusII_IO::copy_scalar_solution(), libMesh::Nemesis_IO::copy_scalar_solution(), libMesh::MeshTools::correct_node_proc_ids(), libMesh::ExodusII_IO_Helper::create(), libMesh::DistributedMesh::delete_elem(), libMesh::MeshCommunication::delete_remote_elements(), distribute_dofs(), distribute_local_dofs_node_major(), distribute_local_dofs_var_major(), distribute_scalar_dofs(), libMesh::DistributedMesh::DistributedMesh(), end_dof(), end_old_dof(), libMesh::EnsightIO::EnsightIO(), libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::SubFunctor::find_dofs_to_send(), libMesh::MeshFunction::find_element(), libMesh::MeshFunction::find_elements(), libMesh::UnstructuredMesh::find_neighbors(), first_dof(), first_old_dof(), libMesh::RBEIMEvaluation::gather_bfs(), 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(), libMesh::MeshBase::get_info(), 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::LaplaceMeshSmoother::init(), 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(), libMesh::TransientRBEvaluation::legacy_write_offline_data_to_files(), libMesh::RBSCMEvaluation::legacy_write_offline_data_to_files(), libMesh::RBEvaluation::legacy_write_offline_data_to_files(), 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::TriangulatorInterface::MeshedHole::MeshedHole(), 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::RBEIMEvaluation::node_gather_bfs(), libMesh::SparsityPattern::Build::operator()(), libMesh::DistributedMesh::own_node(), libMesh::BoundaryInfo::parallel_sync_node_ids(), libMesh::BoundaryInfo::parallel_sync_side_ids(), libMesh::System::point_gradient(), libMesh::System::point_hessian(), libMesh::System::point_value(), print_dof_constraints(), process_mesh_constraint_rows(), 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::EquationSystems::read(), libMesh::ExodusII_IO_Helper::read_elem_num_map(), libMesh::ExodusII_IO_Helper::read_global_values(), libMesh::ExodusII_IO::read_header(), libMesh::CheckpointIO::read_header(), libMesh::XdrIO::read_header(), libMesh::System::read_header(), libMesh::System::read_legacy_data(), libMesh::DynaIO::read_mesh(), 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::Nemesis_IO_Helper::read_var_names_impl(), libMesh::DistributedMesh::renumber_dof_objects(), libMesh::DistributedMesh::renumber_nodes_and_elements(), scatter_constraints(), libMesh::CheckpointIO::select_split_config(), libMesh::DistributedMesh::set_next_unique_id(), set_nonlocal_dof_objects(), libMesh::PetscDMWrapper::set_point_range_in_section(), libMesh::RBEIMEvaluation::side_gather_bfs(), ExodusTest< elem_type >::test_read_gold(), ExodusTest< elem_type >::test_write(), MeshInputTest::testAbaqusRead(), MeshInputTest::testCopyElementSolutionImpl(), MeshInputTest::testCopyElementVectorImpl(), MeshInputTest::testCopyNodalSolutionImpl(), DefaultCouplingTest::testCoupling(), PointNeighborCouplingTest::testCoupling(), MeshInputTest::testDynaFileMappings(), MeshInputTest::testDynaNoSplines(), MeshInputTest::testDynaReadElem(), MeshInputTest::testDynaReadPatch(), MeshInputTest::testExodusFileMappings(), MeshInputTest::testExodusIGASidesets(), MeshInputTest::testExodusWriteElementDataFromDiscontinuousNodalData(), MeshInputTest::testLowOrderEdgeBlocks(), SystemsTest::testProjectMatrix1D(), SystemsTest::testProjectMatrix2D(), SystemsTest::testProjectMatrix3D(), BoundaryInfoTest::testShellFaceConstraints(), MeshInputTest::testSingleElementImpl(), WriteVecAndScalar::testSolution(), CheckpointIOTest::testSplitter(), MeshInputTest::testTetgenIO(), libMesh::MeshTools::total_weight(), libMesh::MeshRefinement::uniformly_coarsen(), 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_Helper::write_elemset_data(), libMesh::ExodusII_IO_Helper::write_elemsets(), 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::UCDIO::write_nodal_data(), libMesh::VTKIO::write_nodal_data(), libMesh::ExodusII_IO::write_nodal_data(), libMesh::ExodusII_IO::write_nodal_data_common(), libMesh::ExodusII_IO::write_nodal_data_discontinuous(), libMesh::ExodusII_IO_Helper::write_nodal_values(), libMesh::ExodusII_IO_Helper::write_nodeset_data(), libMesh::Nemesis_IO_Helper::write_nodesets(), libMesh::ExodusII_IO_Helper::write_nodesets(), libMesh::RBEIMEvaluation::write_out_interior_basis_functions(), libMesh::RBEIMEvaluation::write_out_node_basis_functions(), libMesh::RBEIMEvaluation::write_out_side_basis_functions(), 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().

115  { return cast_int<processor_id_type>(_communicator.rank()); }
processor_id_type rank() const
const Parallel::Communicator & _communicator

◆ reinit()

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

Reinitialize the underlying data structures conformal to the current mesh.

Definition at line 506 of file dof_map.C.

References _default_coupling, _dof_coupling, _dont_p_refine, _n_SCALAR_dofs, libMesh::Variable::active_on_subdomain(), libMesh::CouplingMatrix::empty(), libMesh::Utility::enum_to_string(), libMesh::err, libMesh::FEInterface::extra_hanging_dofs(), libMesh::FEType::family, libMesh::OrderWrapper::get_order(), int, 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().

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

◆ 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 1734 of file dof_map.C.

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().

1735 {
1736  this->clear_send_list();
1738 
1739 #ifdef LIBMESH_ENABLE_CONSTRAINTS
1740  // This is assuming that we only need to recommunicate
1741  // the constraints and no new ones have been added since
1742  // a previous call to reinit_constraints.
1743  this->process_constraints(mesh);
1744 #endif
1745  this->prepare_send_list();
1746 }
void clear_send_list()
Clears the _send_list vector.
Definition: dof_map.h:485
MeshBase & mesh
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:1544
void process_constraints(MeshBase &)
Postprocesses any constrained degrees of freedom to be constrained only in terms of unconstrained dof...
void prepare_send_list()
Takes the _send_list vector (which may have duplicate entries) and sorts it.
Definition: dof_map.C:1692

◆ 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 5509 of file dof_map_constraints.C.

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

5511 {
5512  libmesh_assert_greater(_adjoint_dirichlet_boundaries.size(),
5513  qoi_index);
5514 
5515  auto lam = [&boundary_to_remove](const auto & bdy)
5516  {return bdy->b == boundary_to_remove.b && bdy->variables == boundary_to_remove.variables;};
5517 
5518  auto it = std::find_if(_adjoint_dirichlet_boundaries[qoi_index]->begin(),
5519  _adjoint_dirichlet_boundaries[qoi_index]->end(),
5520  lam);
5521 
5522  // Assert it was actually found and remove it from the vector
5523  libmesh_assert (it != _adjoint_dirichlet_boundaries[qoi_index]->end());
5524  _adjoint_dirichlet_boundaries[qoi_index]->erase(it);
5525 }
libmesh_assert(ctx)
std::vector< std::unique_ptr< DirichletBoundaries > > _adjoint_dirichlet_boundaries
Data structure containing Dirichlet functions.
Definition: dof_map.h:2067

◆ 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 1898 of file dof_map.C.

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

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

1899 {
1900  _algebraic_ghosting_functors.erase(&evaluable_functor);
1901  _mesh.remove_ghosting_functor(evaluable_functor);
1902 
1903  auto it = _shared_functors.find(&evaluable_functor);
1904  if (it != _shared_functors.end())
1905  _shared_functors.erase(it);
1906 }
void remove_ghosting_functor(GhostingFunctor &ghosting_functor)
Removes a functor which was previously added to the set of ghosting functors.
Definition: mesh_base.C:888
std::set< GhostingFunctor * > _algebraic_ghosting_functors
The list of all GhostingFunctor objects to be used when distributing ghosted vectors.
Definition: dof_map.h:1954
MeshBase & _mesh
The mesh that system uses.
Definition: dof_map.h:1867
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:1973

◆ 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 1873 of file dof_map.C.

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

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

1874 {
1875  _coupling_functors.erase(&coupling_functor);
1876  _mesh.remove_ghosting_functor(coupling_functor);
1877 
1878  auto it = _shared_functors.find(&coupling_functor);
1879  if (it != _shared_functors.end())
1880  _shared_functors.erase(it);
1881 }
void remove_ghosting_functor(GhostingFunctor &ghosting_functor)
Removes a functor which was previously added to the set of ghosting functors.
Definition: mesh_base.C:888
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:1967
MeshBase & _mesh
The mesh that system uses.
Definition: dof_map.h:1867
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:1973

◆ 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 1844 of file dof_map.C.

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

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

1845 {
1848 }
DefaultCoupling & default_coupling()
Default coupling functor.
Definition: dof_map.h:356
DefaultCoupling & default_algebraic_ghosting()
Default algebraic ghosting functor.
Definition: dof_map.h:418
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:1873
void remove_algebraic_ghosting_functor(GhostingFunctor &evaluable_functor)
Removes a functor which was previously added to the set of algebraic ghosting functors, from both this DofMap and from the underlying mesh.
Definition: dof_map.C:1898

◆ remove_dirichlet_boundary()

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

Removes the specified Dirichlet boundary from the system.

Definition at line 5495 of file dof_map_constraints.C.

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

5496 {
5497  // Find a boundary condition matching the one to be removed
5498  auto lam = [&boundary_to_remove](const auto & bdy)
5499  {return bdy->b == boundary_to_remove.b && bdy->variables == boundary_to_remove.variables;};
5500 
5501  auto it = std::find_if(_dirichlet_boundaries->begin(), _dirichlet_boundaries->end(), lam);
5502 
5503  // Assert it was actually found and remove it from the vector
5504  libmesh_assert (it != _dirichlet_boundaries->end());
5505  _dirichlet_boundaries->erase(it);
5506 }
std::unique_ptr< DirichletBoundaries > _dirichlet_boundaries
Data structure containing Dirichlet functions.
Definition: dof_map.h:2061
libmesh_assert(ctx)

◆ 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 2544 of file dof_map.C.

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(), libMesh::Nemesis_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().

2552 {
2553  LOG_SCOPE("SCALAR_dof_indices()", "DofMap");
2554 
2555  libmesh_assert(this->variable(vn).type().family == SCALAR);
2556 
2557 #ifdef LIBMESH_ENABLE_AMR
2558  // If we're asking for old dofs then we'd better have some
2559  if (old_dofs)
2560  libmesh_assert_greater_equal(n_old_dofs(), n_SCALAR_dofs());
2561 
2562  dof_id_type my_idx = old_dofs ?
2563  this->_first_old_scalar_df[vn] : this->_first_scalar_df[vn];
2564 #else
2565  dof_id_type my_idx = this->_first_scalar_df[vn];
2566 #endif
2567 
2568  libmesh_assert_not_equal_to(my_idx, DofObject::invalid_id);
2569 
2570  // The number of SCALAR dofs comes from the variable order
2571  const int n_dofs_vn = this->variable(vn).type().order.get_order();
2572 
2573  di.resize(n_dofs_vn);
2574  for (int i = 0; i != n_dofs_vn; ++i)
2575  di[i] = my_idx++;
2576 }
dof_id_type n_SCALAR_dofs() const
Definition: dof_map.h:664
OrderWrapper order
The approximation order of the element.
Definition: fe_type.h:201
dof_id_type n_old_dofs() const
Definition: dof_map.h:1542
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:1890
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:2020
const Variable & variable(const unsigned int c) const
Definition: dof_map.h:2114
libmesh_assert(ctx)
static const dof_id_type invalid_id
An invalid id to distinguish an uninitialized DofObject.
Definition: dof_object.h:477
int get_order() const
Explicitly request the order as an int.
Definition: fe_type.h:80
uint8_t dof_id_type
Definition: id_types.h:67
const FEType & type() const
Definition: variable.h:140

◆ scatter_constraints()

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

Sends constraint equations to constraining processors.

Definition at line 4639 of file dof_map_constraints.C.

References _dof_constraints, _end_df, _node_constraints, _primal_constraint_values, libMesh::as_range(), libMesh::ParallelObject::comm(), coupling_functors_begin(), coupling_functors_end(), dof_indices(), gather_constraints(), TIMPI::Communicator::get_unique_tag(), libMesh::DofObject::id(), libMesh::index_range(), is_constrained_dof(), is_constrained_node(), libMesh::MeshBase::is_serial(), TIMPI::Communicator::max(), 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().

4640 {
4641  // At this point each processor with a constrained node knows
4642  // the corresponding constraint row, but we also need each processor
4643  // with a constrainer node to know the corresponding row(s).
4644 
4645  // This function must be run on all processors at once
4646  parallel_object_only();
4647 
4648  // Return immediately if there's nothing to gather
4649  if (this->n_processors() == 1)
4650  return;
4651 
4652  // We might get to return immediately if none of the processors
4653  // found any constraints
4654  unsigned int has_constraints = !_dof_constraints.empty()
4655 #ifdef LIBMESH_ENABLE_NODE_CONSTRAINTS
4656  || !_node_constraints.empty()
4657 #endif // LIBMESH_ENABLE_NODE_CONSTRAINTS
4658  ;
4659  this->comm().max(has_constraints);
4660  if (!has_constraints)
4661  return;
4662 
4663  // We may be receiving packed_range sends out of order with
4664  // parallel_sync tags, so make sure they're received correctly.
4665  Parallel::MessageTag range_tag = this->comm().get_unique_tag();
4666 
4667 #ifdef LIBMESH_ENABLE_NODE_CONSTRAINTS
4668  std::map<processor_id_type, std::set<dof_id_type>> pushed_node_ids;
4669 #endif // LIBMESH_ENABLE_NODE_CONSTRAINTS
4670 
4671  std::map<processor_id_type, std::set<dof_id_type>> pushed_ids;
4672 
4673  // Collect the dof constraints I need to push to each processor
4674  dof_id_type constrained_proc_id = 0;
4675  for (const auto & [constrained, row] : _dof_constraints)
4676  {
4677  while (constrained >= _end_df[constrained_proc_id])
4678  constrained_proc_id++;
4679 
4680  if (constrained_proc_id != this->processor_id())
4681  continue;
4682 
4683  for (auto & j : row)
4684  {
4685  const dof_id_type constraining = j.first;
4686 
4687  processor_id_type constraining_proc_id = 0;
4688  while (constraining >= _end_df[constraining_proc_id])
4689  constraining_proc_id++;
4690 
4691  if (constraining_proc_id != this->processor_id() &&
4692  constraining_proc_id != constrained_proc_id)
4693  pushed_ids[constraining_proc_id].insert(constrained);
4694  }
4695  }
4696 
4697  // Pack the dof constraint rows and rhs's to push
4698 
4699  std::map<processor_id_type,
4700  std::vector<std::vector<std::pair<dof_id_type, Real>>>>
4701  pushed_keys_vals, pushed_keys_vals_to_me;
4702 
4703  std::map<processor_id_type, std::vector<std::pair<dof_id_type, Number>>>
4704  pushed_ids_rhss, pushed_ids_rhss_to_me;
4705 
4706  auto gather_ids =
4707  [this,
4708  & pushed_ids,
4709  & pushed_keys_vals,
4710  & pushed_ids_rhss]
4711  ()
4712  {
4713  for (const auto & [pid, pid_ids] : pushed_ids)
4714  {
4715  const std::size_t ids_size = pid_ids.size();
4716  std::vector<std::vector<std::pair<dof_id_type, Real>>> &
4717  keys_vals = pushed_keys_vals[pid];
4718  std::vector<std::pair<dof_id_type,Number>> &
4719  ids_rhss = pushed_ids_rhss[pid];
4720  keys_vals.resize(ids_size);
4721  ids_rhss.resize(ids_size);
4722 
4723  std::size_t push_i;
4724  std::set<dof_id_type>::const_iterator it;
4725  for (push_i = 0, it = pid_ids.begin();
4726  it != pid_ids.end(); ++push_i, ++it)
4727  {
4728  const dof_id_type constrained = *it;
4729  DofConstraintRow & row = _dof_constraints[constrained];
4730  keys_vals[push_i].assign(row.begin(), row.end());
4731 
4732  DofConstraintValueMap::const_iterator rhsit =
4733  _primal_constraint_values.find(constrained);
4734  ids_rhss[push_i].first = constrained;
4735  ids_rhss[push_i].second =
4736  (rhsit == _primal_constraint_values.end()) ?
4737  0 : rhsit->second;
4738  }
4739  }
4740  };
4741 
4742  gather_ids();
4743 
4744  auto ids_rhss_action_functor =
4745  [& pushed_ids_rhss_to_me]
4746  (processor_id_type pid,
4747  const std::vector<std::pair<dof_id_type, Number>> & data)
4748  {
4749  pushed_ids_rhss_to_me[pid] = data;
4750  };
4751 
4752  auto keys_vals_action_functor =
4753  [& pushed_keys_vals_to_me]
4754  (processor_id_type pid,
4755  const std::vector<std::vector<std::pair<dof_id_type, Real>>> & data)
4756  {
4757  pushed_keys_vals_to_me[pid] = data;
4758  };
4759 
4760  Parallel::push_parallel_vector_data
4761  (this->comm(), pushed_ids_rhss, ids_rhss_action_functor);
4762  Parallel::push_parallel_vector_data
4763  (this->comm(), pushed_keys_vals, keys_vals_action_functor);
4764 
4765  // Now work on traded dof constraint rows
4766  auto receive_dof_constraints =
4767  [this,
4768  & pushed_ids_rhss_to_me,
4769  & pushed_keys_vals_to_me]
4770  ()
4771  {
4772  for (const auto & [pid, ids_rhss] : pushed_ids_rhss_to_me)
4773  {
4774  const auto & keys_vals = pushed_keys_vals_to_me[pid];
4775 
4776  libmesh_assert_equal_to
4777  (ids_rhss.size(), keys_vals.size());
4778 
4779  // Add the dof constraints that I've been sent
4780  for (auto i : index_range(ids_rhss))
4781  {
4782  dof_id_type constrained = ids_rhss[i].first;
4783 
4784  // If we don't already have a constraint for this dof,
4785  // add the one we were sent
4786  if (!this->is_constrained_dof(constrained))
4787  {
4788  DofConstraintRow & row = _dof_constraints[constrained];
4789  for (auto & key_val : keys_vals[i])
4790  {
4791  libmesh_assert_less(key_val.first, this->n_dofs());
4792  row[key_val.first] = key_val.second;
4793  }
4794  if (ids_rhss[i].second != Number(0))
4795  _primal_constraint_values[constrained] =
4796  ids_rhss[i].second;
4797  else
4798  _primal_constraint_values.erase(constrained);
4799  }
4800  }
4801  }
4802  };
4803 
4804  receive_dof_constraints();
4805 
4806 #ifdef LIBMESH_ENABLE_NODE_CONSTRAINTS
4807  // Collect the node constraints to push to each processor
4808  for (auto & i : _node_constraints)
4809  {
4810  const Node * constrained = i.first;
4811 
4812  if (constrained->processor_id() != this->processor_id())
4813  continue;
4814 
4815  NodeConstraintRow & row = i.second.first;
4816  for (auto & j : row)
4817  {
4818  const Node * constraining = j.first;
4819 
4820  if (constraining->processor_id() != this->processor_id() &&
4821  constraining->processor_id() != constrained->processor_id())
4822  pushed_node_ids[constraining->processor_id()].insert(constrained->id());
4823  }
4824  }
4825 
4826  // Pack the node constraint rows and rhss to push
4827  std::map<processor_id_type,
4828  std::vector<std::vector<std::pair<dof_id_type,Real>>>>
4829  pushed_node_keys_vals, pushed_node_keys_vals_to_me;
4830  std::map<processor_id_type, std::vector<std::pair<dof_id_type, Point>>>
4831  pushed_node_ids_offsets, pushed_node_ids_offsets_to_me;
4832  std::map<processor_id_type, std::vector<const Node *>> pushed_node_vecs;
4833 
4834  for (const auto & [pid, pid_ids]: pushed_node_ids)
4835  {
4836  const std::size_t ids_size = pid_ids.size();
4837  std::vector<std::vector<std::pair<dof_id_type,Real>>> &
4838  keys_vals = pushed_node_keys_vals[pid];
4839  std::vector<std::pair<dof_id_type, Point>> &
4840  ids_offsets = pushed_node_ids_offsets[pid];
4841  keys_vals.resize(ids_size);
4842  ids_offsets.resize(ids_size);
4843  std::set<Node *> nodes;
4844 
4845  std::size_t push_i;
4846  std::set<dof_id_type>::const_iterator it;
4847  for (push_i = 0, it = pid_ids.begin();
4848  it != pid_ids.end(); ++push_i, ++it)
4849  {
4850  Node * constrained = mesh.node_ptr(*it);
4851 
4852  if (constrained->processor_id() != pid)
4853  nodes.insert(constrained);
4854 
4855  NodeConstraintRow & row = _node_constraints[constrained].first;
4856  std::size_t row_size = row.size();
4857  keys_vals[push_i].reserve(row_size);
4858  for (const auto & j : row)
4859  {
4860  Node * constraining = const_cast<Node *>(j.first);
4861 
4862  keys_vals[push_i].emplace_back(constraining->id(), j.second);
4863 
4864  if (constraining->processor_id() != pid)
4865  nodes.insert(constraining);
4866  }
4867 
4868  ids_offsets[push_i].first = *it;
4869  ids_offsets[push_i].second = _node_constraints[constrained].second;
4870  }
4871 
4872  if (!mesh.is_serial())
4873  {
4874  auto & pid_nodes = pushed_node_vecs[pid];
4875  pid_nodes.assign(nodes.begin(), nodes.end());
4876  }
4877  }
4878 
4879  auto node_ids_offsets_action_functor =
4880  [& pushed_node_ids_offsets_to_me]
4881  (processor_id_type pid,
4882  const std::vector<std::pair<dof_id_type, Point>> & data)
4883  {
4884  pushed_node_ids_offsets_to_me[pid] = data;
4885  };
4886 
4887  auto node_keys_vals_action_functor =
4888  [& pushed_node_keys_vals_to_me]
4889  (processor_id_type pid,
4890  const std::vector<std::vector<std::pair<dof_id_type, Real>>> & data)
4891  {
4892  pushed_node_keys_vals_to_me[pid] = data;
4893  };
4894 
4895  // Trade pushed node constraint rows
4896  Parallel::push_parallel_vector_data
4897  (this->comm(), pushed_node_ids_offsets, node_ids_offsets_action_functor);
4898  Parallel::push_parallel_vector_data
4899  (this->comm(), pushed_node_keys_vals, node_keys_vals_action_functor);
4900 
4901  // Constraining nodes might not even exist on our subset of a
4902  // distributed mesh, so let's make them exist.
4903 
4904  // Node unpack() now automatically adds them to the context mesh
4905  auto null_node_functor = [](processor_id_type, const std::vector<const Node *> &){};
4906 
4907  if (!mesh.is_serial())
4908  Parallel::push_parallel_packed_range
4909  (this->comm(), pushed_node_vecs, &mesh, null_node_functor);
4910 
4911  for (const auto & [pid, ids_offsets] : pushed_node_ids_offsets_to_me)
4912  {
4913  const auto & keys_vals = pushed_node_keys_vals_to_me[pid];
4914 
4915  libmesh_assert_equal_to
4916  (ids_offsets.size(), keys_vals.size());
4917 
4918  // Add the node constraints that I've been sent
4919  for (auto i : index_range(ids_offsets))
4920  {
4921  dof_id_type constrained_id = ids_offsets[i].first;
4922 
4923  // If we don't already have a constraint for this node,
4924  // add the one we were sent
4925  const Node * constrained = mesh.node_ptr(constrained_id);
4926  if (!this->is_constrained_node(constrained))
4927  {
4928  NodeConstraintRow & row = _node_constraints[constrained].first;
4929  for (auto & key_val : keys_vals[i])
4930  {
4931  const Node * key_node = mesh.node_ptr(key_val.first);
4932  row[key_node] = key_val.second;
4933  }
4934  _node_constraints[constrained].second =
4935  ids_offsets[i].second;
4936  }
4937  }
4938  }
4939 #endif // LIBMESH_ENABLE_NODE_CONSTRAINTS
4940 
4941  // Next we need to push constraints to processors which don't own
4942  // the constrained dof, don't own the constraining dof, but own an
4943  // element supporting the constraining dof.
4944  //
4945  // We need to be able to quickly look up constrained dof ids by what
4946  // constrains them, so that we can handle the case where we see a
4947  // foreign element containing one of our constraining DoF ids and we
4948  // need to push that constraint.
4949  //
4950  // Getting distributed adaptive sparsity patterns right is hard.
4951 
4952  typedef std::map<dof_id_type, std::set<dof_id_type>> DofConstrainsMap;
4953  DofConstrainsMap dof_id_constrains;
4954 
4955  for (const auto & [constrained, row] : _dof_constraints)
4956  {
4957  for (const auto & j : row)
4958  {
4959  const dof_id_type constraining = j.first;
4960 
4961  dof_id_type constraining_proc_id = 0;
4962  while (constraining >= _end_df[constraining_proc_id])
4963  constraining_proc_id++;
4964 
4965  if (constraining_proc_id == this->processor_id())
4966  dof_id_constrains[constraining].insert(constrained);
4967  }
4968  }
4969 
4970  // Loop over all foreign elements, find any supporting our
4971  // constrained dof indices.
4972  pushed_ids.clear();
4973 
4974  for (const auto & elem : as_range(mesh.active_not_local_elements_begin(),
4975  mesh.active_not_local_elements_end()))
4976  {
4977  std::vector<dof_id_type> my_dof_indices;
4978  this->dof_indices (elem, my_dof_indices);
4979 
4980  for (const auto & dof : my_dof_indices)
4981  {
4982  DofConstrainsMap::const_iterator dcmi = dof_id_constrains.find(dof);
4983  if (dcmi != dof_id_constrains.end())
4984  {
4985  for (const auto & constrained : dcmi->second)
4986  {
4987  dof_id_type the_constrained_proc_id = 0;
4988  while (constrained >= _end_df[the_constrained_proc_id])
4989  the_constrained_proc_id++;
4990 
4991  const processor_id_type elemproc = elem->processor_id();
4992  if (elemproc != the_constrained_proc_id)
4993  pushed_ids[elemproc].insert(constrained);
4994  }
4995  }
4996  }
4997  }
4998 
4999  pushed_ids_rhss.clear();
5000  pushed_ids_rhss_to_me.clear();
5001  pushed_keys_vals.clear();
5002  pushed_keys_vals_to_me.clear();
5003 
5004  gather_ids();
5005 
5006  // Trade pushed dof constraint rows
5007  Parallel::push_parallel_vector_data
5008  (this->comm(), pushed_ids_rhss, ids_rhss_action_functor);
5009  Parallel::push_parallel_vector_data
5010  (this->comm(), pushed_keys_vals, keys_vals_action_functor);
5011 
5012  receive_dof_constraints();
5013 
5014  // Finally, we need to handle the case of remote dof coupling. If a
5015  // processor's element is coupled to a ghost element, then the
5016  // processor needs to know about all constraints which affect the
5017  // dofs on that ghost element, so we'll have to query the ghost
5018  // element's owner.
5019 
5020  GhostingFunctor::map_type elements_to_couple;
5021  DofMap::CouplingMatricesSet temporary_coupling_matrices;
5022 
5024  (elements_to_couple,
5025  temporary_coupling_matrices,
5026  this->coupling_functors_begin(),
5027  this->coupling_functors_end(),
5028  mesh.active_local_elements_begin(),
5029  mesh.active_local_elements_end(),
5030  this->processor_id());
5031 
5032  // Each ghost-coupled element's owner should get a request for its dofs
5033  std::set<dof_id_type> requested_dofs;
5034 
5035  for (const auto & pr : elements_to_couple)
5036  {
5037  const Elem * elem = pr.first;
5038 
5039  // FIXME - optimize for the non-fully-coupled case?
5040  std::vector<dof_id_type> element_dofs;
5041  this->dof_indices(elem, element_dofs);
5042 
5043  for (auto dof : element_dofs)
5044  requested_dofs.insert(dof);
5045  }
5046 
5047  this->gather_constraints(mesh, requested_dofs, false);
5048 }
bool is_constrained_node(const Node *node) const
Definition: dof_map.h:2166
A Node is like a Point, but with more information.
Definition: node.h:52
std::set< GhostingFunctor * >::const_iterator coupling_functors_begin() const
Beginning of range of coupling functors.
Definition: dof_map.h:344
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:1992
MessageTag get_unique_tag(int tagvalue=MessageTag::invalid_tag) const
This is the base class from which all geometric element types are derived.
Definition: elem.h:94
MeshBase & mesh
void gather_constraints(MeshBase &mesh, std::set< dof_id_type > &unexpanded_dofs, bool look_for_constrainees)
Helper function for querying about constraint equations on other processors.
const Parallel::Communicator & comm() const
std::map< const Elem *, const CouplingMatrix *, CompareDofObjectsByPIDAndThenID > map_type
What elements do we care about and what variables do we care about on each element?
uint8_t processor_id_type
Definition: id_types.h:104
uint8_t processor_id_type
processor_id_type n_processors() const
virtual bool is_serial() const
Definition: mesh_base.h:205
static void merge_ghost_functor_outputs(GhostingFunctor::map_type &elements_to_ghost, CouplingMatricesSet &temporary_coupling_matrices, const std::set< GhostingFunctor *>::iterator &gf_begin, const std::set< GhostingFunctor *>::iterator &gf_end, const MeshBase::const_element_iterator &elems_begin, const MeshBase::const_element_iterator &elems_end, processor_id_type p)
Definition: dof_map.C:1440
dof_id_type id() const
Definition: dof_object.h:823
std::set< std::unique_ptr< CouplingMatrix >, Utility::CompareUnderlying > CouplingMatricesSet
Definition: dof_map.h:1745
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
bool is_constrained_dof(const dof_id_type dof) const
Definition: dof_map.h:2182
DofConstraints _dof_constraints
Data structure containing DOF constraints.
Definition: dof_map.h:2033
void max(const T &r, T &o, Request &req) const
DofConstraintValueMap _primal_constraint_values
Definition: dof_map.h:2035
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:90
std::vector< dof_id_type > _end_df
Last DOF index (plus 1) on processor p.
Definition: dof_map.h:1884
std::set< GhostingFunctor * >::const_iterator coupling_functors_end() const
End of range of coupling functors.
Definition: dof_map.h:350
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:138
virtual const Node * node_ptr(const dof_id_type i) const =0
processor_id_type processor_id() const
processor_id_type processor_id() const
Definition: dof_object.h:898
auto index_range(const T &sizable)
Helper function that returns an IntRange<std::size_t> representing all the indices of the passed-in v...
Definition: int_range.h:111
uint8_t dof_id_type
Definition: id_types.h:67
NodeConstraints _node_constraints
Data structure containing DofObject constraints.
Definition: dof_map.h:2044

◆ 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 2580 of file dof_map.C.

References _send_list, and local_index().

Referenced by all_semilocal_indices().

2581 {
2582  // If it's not in the local indices
2583  if (!this->local_index(dof_index))
2584  {
2585  // and if it's not in the ghost indices, then we're not
2586  // semilocal
2587  if (!std::binary_search(_send_list.begin(), _send_list.end(), dof_index))
2588  return false;
2589  }
2590 
2591  return true;
2592 }
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:1896
bool local_index(dof_id_type dof_index) const
Definition: dof_map.h:831

◆ set_constrained_sparsity_construction()

void libMesh::DofMap::set_constrained_sparsity_construction ( bool  use_constraints)
inline

Sets the current policy for constructing sparsity patterns: if use_constraints is true (for robustness), we explicitly account for sparsity entries created by constraint matrix pre- and post- application.

If use_constraints is false (for speed), we calculate only the sparsity pattern of an unconstrained matrix. This is false by default, because in nearly all applications our constraints do not increase the number of non-zeros required in a sparse matrix.

Definition at line 2297 of file dof_map.h.

References _constrained_sparsity_construction, and libMesh::libmesh_ignore().

2298 {
2299  // This got only partly finished...
2300  if (use_constraints)
2301  libmesh_not_implemented();
2302 
2303 #ifdef LIBMESH_ENABLE_CONSTRAINTS
2304  _constrained_sparsity_construction = use_constraints;
2305 #endif
2306  libmesh_ignore(use_constraints);
2307 }
bool _constrained_sparsity_construction
This flag indicates whether or not we explicitly take constraint equations into account when computin...
Definition: dof_map.h:1837
void libmesh_ignore(const Args &...)

◆ set_error_on_constraint_loop()

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

Definition at line 245 of file dof_map.C.

References _error_on_constraint_loop.

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

246 {
247  _error_on_constraint_loop = error_on_constraint_loop;
248 }
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:1831

◆ 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 238 of file dof_map.C.

References set_error_on_constraint_loop().

239 {
240  // This function will eventually be officially libmesh_deprecated();
241  // Call DofMap::set_error_on_constraint_loop() instead.
242  set_error_on_constraint_loop(error_on_cyclic_constraint);
243 }
void set_error_on_constraint_loop(bool error_on_constraint_loop)
Definition: dof_map.C:245

◆ 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 1748 of file dof_map.C.

References _implicit_neighbor_dofs, and _implicit_neighbor_dofs_initialized.

1749 {
1751  _implicit_neighbor_dofs = implicit_neighbor_dofs;
1752 }
bool _implicit_neighbor_dofs_initialized
Bools to indicate if we override the –implicit_neighbor_dofs commandline options.
Definition: dof_map.h:2076
bool _implicit_neighbor_dofs
Definition: dof_map.h:2077

◆ 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 356 of file dof_map.C.

References libMesh::ParallelObject::comm(), libMesh::DofObject::dof_number(), libMesh::DofObject::id(), libMesh::index_range(), libMesh::DofObject::invalid_id, libMesh::DofObject::invalid_processor_id, libMesh::libmesh_assert(), libMesh::make_range(), 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().

360 {
361  // This function must be run on all processors at once
362  parallel_object_only();
363 
364  // First, iterate over local objects to find out how many
365  // are on each processor
366  std::unordered_map<processor_id_type, dof_id_type> ghost_objects_from_proc;
367 
368  iterator_type it = objects_begin;
369 
370  for (; it != objects_end; ++it)
371  {
372  DofObject * obj = *it;
373 
374  if (obj)
375  {
376  processor_id_type obj_procid = obj->processor_id();
377  // We'd better be completely partitioned by now
378  libmesh_assert_not_equal_to (obj_procid, DofObject::invalid_processor_id);
379  ghost_objects_from_proc[obj_procid]++;
380  }
381  }
382 
383  // Request sets to send to each processor
384  std::map<processor_id_type, std::vector<dof_id_type>>
385  requested_ids;
386 
387  // We know how many of our objects live on each processor, so
388  // reserve() space for requests from each.
389  for (auto [p, size] : ghost_objects_from_proc)
390  {
391  if (p != this->processor_id())
392  requested_ids[p].reserve(size);
393  }
394 
395  for (it = objects_begin; it != objects_end; ++it)
396  {
397  DofObject * obj = *it;
398  if (obj->processor_id() != DofObject::invalid_processor_id)
399  requested_ids[obj->processor_id()].push_back(obj->id());
400  }
401 #ifdef DEBUG
402  for (auto p : make_range(this->n_processors()))
403  {
404  if (ghost_objects_from_proc.count(p))
405  libmesh_assert_equal_to (requested_ids[p].size(), ghost_objects_from_proc[p]);
406  else
407  libmesh_assert(!requested_ids.count(p));
408  }
409 #endif
410 
411  typedef std::vector<dof_id_type> datum;
412 
413  auto gather_functor =
414  [this, &mesh, &objects]
416  const std::vector<dof_id_type> & ids,
417  std::vector<datum> & data)
418  {
419  // Fill those requests
420  const unsigned int
421  sys_num = this->sys_number(),
422  n_var_groups = this->n_variable_groups();
423 
424  const std::size_t query_size = ids.size();
425 
426  data.resize(query_size);
427  for (auto & d : data)
428  d.resize(2 * n_var_groups);
429 
430  for (std::size_t i=0; i != query_size; ++i)
431  {
432  DofObject * requested = (this->*objects)(mesh, ids[i]);
433  libmesh_assert(requested);
434  libmesh_assert_equal_to (requested->processor_id(), this->processor_id());
435  libmesh_assert_equal_to (requested->n_var_groups(sys_num), n_var_groups);
436  for (unsigned int vg=0; vg != n_var_groups; ++vg)
437  {
438  unsigned int n_comp_g =
439  requested->n_comp_group(sys_num, vg);
440  data[i][vg] = n_comp_g;
441  dof_id_type my_first_dof = n_comp_g ?
442  requested->vg_dof_base(sys_num, vg) : 0;
443  libmesh_assert_not_equal_to (my_first_dof, DofObject::invalid_id);
444  data[i][n_var_groups+vg] = my_first_dof;
445  }
446  }
447  };
448 
449  auto action_functor =
450  [this, &mesh, &objects]
451  (processor_id_type libmesh_dbg_var(pid),
452  const std::vector<dof_id_type> & ids,
453  const std::vector<datum> & data)
454  {
455  const unsigned int
456  sys_num = this->sys_number(),
457  n_var_groups = this->n_variable_groups();
458 
459  // Copy the id changes we've now been informed of
460  for (auto i : index_range(ids))
461  {
462  DofObject * requested = (this->*objects)(mesh, ids[i]);
463  libmesh_assert(requested);
464  libmesh_assert_equal_to (requested->processor_id(), pid);
465  for (unsigned int vg=0; vg != n_var_groups; ++vg)
466  {
467  unsigned int n_comp_g =
468  cast_int<unsigned int>(data[i][vg]);
469  requested->set_n_comp_group(sys_num, vg, n_comp_g);
470  if (n_comp_g)
471  {
472  dof_id_type my_first_dof = data[i][n_var_groups+vg];
473  libmesh_assert_not_equal_to (my_first_dof, DofObject::invalid_id);
474  requested->set_vg_dof_base
475  (sys_num, vg, my_first_dof);
476  }
477  }
478  }
479  };
480 
481  datum * ex = nullptr;
482  Parallel::pull_parallel_vector_data
483  (this->comm(), requested_ids, gather_functor, action_functor, ex);
484 
485 #ifdef DEBUG
486  // Double check for invalid dofs
487  for (it = objects_begin; it != objects_end; ++it)
488  {
489  DofObject * obj = *it;
490  libmesh_assert (obj);
491  unsigned int num_variables = obj->n_vars(this->sys_number());
492  for (unsigned int v=0; v != num_variables; ++v)
493  {
494  unsigned int n_comp =
495  obj->n_comp(this->sys_number(), v);
496  dof_id_type my_first_dof = n_comp ?
497  obj->dof_number(this->sys_number(), v, 0) : 0;
498  libmesh_assert_not_equal_to (my_first_dof, DofObject::invalid_id);
499  }
500  }
501 #endif
502 }
unsigned int n_variable_groups() const
Definition: dof_map.h:613
MeshBase & mesh
const Parallel::Communicator & comm() const
unsigned int sys_number() const
Definition: dof_map.h:2096
uint8_t processor_id_type
Definition: id_types.h:104
uint8_t processor_id_type
processor_id_type n_processors() const
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:488
libmesh_assert(ctx)
static const dof_id_type invalid_id
An invalid id to distinguish an uninitialized DofObject.
Definition: dof_object.h:477
IntRange< T > make_range(T beg, T end)
The 2-parameter make_range() helper function returns an IntRange<T> when both input parameters are of...
Definition: int_range.h:134
processor_id_type processor_id() const
auto index_range(const T &sizable)
Helper function that returns an IntRange<std::size_t> representing all the indices of the passed-in v...
Definition: int_range.h:111
uint8_t dof_id_type
Definition: id_types.h:67

◆ set_verify_dirichlet_bc_consistency()

void libMesh::DofMap::set_verify_dirichlet_bc_consistency ( bool  val)

Set the _verify_dirichlet_bc_consistency flag.

Definition at line 1754 of file dof_map.C.

References _verify_dirichlet_bc_consistency.

1755 {
1757 }
bool _verify_dirichlet_bc_consistency
Flag which determines whether we should do some additional checking of the consistency of the Dirichl...
Definition: dof_map.h:2089

◆ should_p_refine() [1/6]

void libMesh::DofMap::should_p_refine ( unsigned int  g,
bool  p_refine 
)
inline

Describe whether the given variable group should be p-refined.

If this API is not called with false, the default is to p-refine

Definition at line 2322 of file dof_map.h.

References _dont_p_refine, and libMesh::libmesh_ignore().

Referenced by libMesh::EquationSystems::build_parallel_solution_vector(), and libMesh::FEMContext::init_internal_data().

2323 {
2324 #ifdef LIBMESH_ENABLE_AMR
2325  if (p_refine)
2326  {
2327  auto it = _dont_p_refine.find(g);
2328  if (it != _dont_p_refine.end())
2329  _dont_p_refine.erase(it);
2330  }
2331  else
2332  _dont_p_refine.insert(g);
2333 #else
2334  libmesh_ignore(g, p_refine);
2335 #endif
2336 }
void libmesh_ignore(const Args &...)
std::unordered_set< unsigned int > _dont_p_refine
A container of variable groups that we should not p-refine.
Definition: dof_map.h:2025

◆ should_p_refine() [2/6]

bool libMesh::DofMap::should_p_refine ( unsigned int  g) const
inline

Whether the given variable group should be p-refined.

Definition at line 2339 of file dof_map.h.

References _dont_p_refine, and libMesh::libmesh_ignore().

2340 {
2341 #ifdef LIBMESH_ENABLE_AMR
2342  return !_dont_p_refine.count(g);
2343 #else
2344  libmesh_ignore(g);
2345  return false;
2346 #endif
2347 }
void libmesh_ignore(const Args &...)
std::unordered_set< unsigned int > _dont_p_refine
A container of variable groups that we should not p-refine.
Definition: dof_map.h:2025

◆ should_p_refine() [3/6]

void libMesh::DofMap::should_p_refine ( FEFamily  ,
bool   
)
delete

◆ should_p_refine() [4/6]

void libMesh::DofMap::should_p_refine ( Order  ,
bool   
)
delete

◆ should_p_refine() [5/6]

bool libMesh::DofMap::should_p_refine ( FEFamily  ) const
delete

◆ should_p_refine() [6/6]

bool libMesh::DofMap::should_p_refine ( Order  ) const
delete

◆ should_p_refine_var()

bool libMesh::DofMap::should_p_refine_var ( unsigned int  var) const
inline

Whether the given variable should be p-refined.

Definition at line 2357 of file dof_map.h.

References _dont_p_refine, libMesh::libmesh_ignore(), and var_group_from_var_number().

Referenced by libMesh::FEGenericBase< FEOutputType< T >::type >::compute_proj_constraints(), and libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::ProjectSides::operator()().

2358 {
2359 #ifdef LIBMESH_ENABLE_AMR
2360  const auto vg = this->var_group_from_var_number(var);
2361  return !_dont_p_refine.count(vg);
2362 #else
2363  libmesh_ignore(var);
2364  return false;
2365 #endif
2366 }
unsigned int var_group_from_var_number(unsigned int var_num) const
Definition: dof_map.h:2350
void libmesh_ignore(const Args &...)
std::unordered_set< unsigned int > _dont_p_refine
A container of variable groups that we should not p-refine.
Definition: dof_map.h:2025

◆ stash_dof_constraints()

void libMesh::DofMap::stash_dof_constraints ( )
inline

Definition at line 1028 of file dof_map.h.

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

1029  {
1032  }
libmesh_assert(ctx)
DofConstraints _dof_constraints
Data structure containing DOF constraints.
Definition: dof_map.h:2033
DofConstraints _stashed_dof_constraints
Definition: dof_map.h:2033

◆ 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 1052 of file dof_map.h.

References _dof_constraints, and _stashed_dof_constraints.

1053  {
1055  }
DofConstraints _dof_constraints
Data structure containing DOF constraints.
Definition: dof_map.h:2033
DofConstraints _stashed_dof_constraints
Definition: dof_map.h:2033

◆ sys_number()

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

◆ unstash_dof_constraints()

void libMesh::DofMap::unstash_dof_constraints ( )
inline

Definition at line 1034 of file dof_map.h.

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

1035  {
1038  }
libmesh_assert(ctx)
DofConstraints _dof_constraints
Data structure containing DOF constraints.
Definition: dof_map.h:2033
DofConstraints _stashed_dof_constraints
Definition: dof_map.h:2033

◆ update_sparsity_pattern()

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

Additional matrices may be be temporarily initialized by this DofMap.

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

Definition at line 307 of file dof_map.C.

References _sp, libMesh::SparseMatrix< T >::attach_dof_map(), libMesh::SparseMatrix< T >::attach_sparsity_pattern(), computed_sparsity_already(), libMesh::libmesh_assert(), libMesh::SparseMatrix< T >::need_full_sparsity_pattern(), need_full_sparsity_pattern, and libMesh::SparseMatrix< T >::update_sparsity_pattern().

Referenced by attach_matrix(), and libMesh::System::solve_for_unconstrained_dofs().

308 {
309  matrix.attach_dof_map (*this);
310 
311  // If we've already computed sparsity, then it's too late
312  // to wait for "compute_sparsity" to help with sparse matrix
313  // initialization, and we need to handle this matrix individually
314  if (this->computed_sparsity_already())
315  {
316  libmesh_assert(_sp.get());
317 
318  if (matrix.need_full_sparsity_pattern())
319  {
320  // We'd better have already computed the full sparsity
321  // pattern if we need it here
323 
324  matrix.update_sparsity_pattern (_sp->get_sparsity_pattern());
325  }
326 
327  matrix.attach_sparsity_pattern(*_sp);
328  }
329 }
std::unique_ptr< SparsityPattern::Build > _sp
The sparsity pattern of the global matrix.
Definition: dof_map.h:1986
void attach_sparsity_pattern(const SparsityPattern::Build &sp)
Set a pointer to a sparsity pattern to use.
Definition: sparse_matrix.C:73
bool need_full_sparsity_pattern
Default false; set to true if any attached matrix requires a full sparsity pattern.
Definition: dof_map.h:1979
libmesh_assert(ctx)
bool computed_sparsity_already() const
Returns true iff a sparsity pattern has already been computed.
Definition: dof_map.C:296
void attach_dof_map(const DofMap &dof_map)
Set a pointer to the DofMap to use.
Definition: sparse_matrix.C:63
virtual bool need_full_sparsity_pattern() const
virtual void update_sparsity_pattern(const SparsityPattern::Graph &)
Updates the matrix sparsity pattern.

◆ 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 1760 of file dof_map.C.

References _implicit_neighbor_dofs, _implicit_neighbor_dofs_initialized, libMesh::command_line_next(), libMesh::DISCONTINUOUS, libMesh::FEInterface::get_continuity(), libMesh::make_range(), n_variables(), libMesh::on_command_line(), and variable_type().

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

1761 {
1762  // If we were asked on the command line, then we need to
1763  // include sensitivities between neighbor degrees of freedom
1764  bool implicit_neighbor_dofs =
1765  libMesh::on_command_line ("--implicit-neighbor-dofs");
1766 
1767  // If the user specifies --implicit-neighbor-dofs 0, then
1768  // presumably he knows what he is doing and we won't try to
1769  // automatically turn it on even when all the variables are
1770  // discontinuous.
1771  if (implicit_neighbor_dofs)
1772  {
1773  // No flag provided defaults to 'true'
1774  int flag = 1;
1775  flag = libMesh::command_line_next ("--implicit-neighbor-dofs", flag);
1776 
1777  if (!flag)
1778  {
1779  // The user said --implicit-neighbor-dofs 0, so he knows
1780  // what he is doing and really doesn't want it.
1781  return false;
1782  }
1783  }
1784 
1785  // Possibly override the commandline option, if set_implicit_neighbor_dofs
1786  // has been called.
1788  {
1789  implicit_neighbor_dofs = _implicit_neighbor_dofs;
1790 
1791  // Again, if the user explicitly says implicit_neighbor_dofs = false,
1792  // then we return here.
1793  if (!implicit_neighbor_dofs)
1794  return false;
1795  }
1796 
1797  // Look at all the variables in this system. If every one is
1798  // discontinuous then the user must be doing DG/FVM, so be nice
1799  // and force implicit_neighbor_dofs=true.
1800  {
1801  bool all_discontinuous_dofs = true;
1802 
1803  for (auto var : make_range(this->n_variables()))
1805  all_discontinuous_dofs = false;
1806 
1807  if (all_discontinuous_dofs)
1808  implicit_neighbor_dofs = true;
1809  }
1810 
1811  return implicit_neighbor_dofs;
1812 }
T command_line_next(std::string name, T default_value)
Use GetPot&#39;s search()/next() functions to get following arguments from the command line...
Definition: libmesh.C:1011
bool _implicit_neighbor_dofs_initialized
Bools to indicate if we override the –implicit_neighbor_dofs commandline options.
Definition: dof_map.h:2076
bool _implicit_neighbor_dofs
Definition: dof_map.h:2077
const FEType & variable_type(const unsigned int c) const
Definition: dof_map.h:2144
unsigned int n_variables() const
Definition: dof_map.h:621
static FEContinuity get_continuity(const FEType &fe_type)
Returns the input FEType&#39;s FEContinuity based on the underlying FEFamily and potentially the Order...
IntRange< T > make_range(T beg, T end)
The 2-parameter make_range() helper function returns an IntRange<T> when both input parameters are of...
Definition: int_range.h:134
bool on_command_line(std::string arg)
Definition: libmesh.C:924

◆ var_group_from_var_number()

unsigned int libMesh::DofMap::var_group_from_var_number ( unsigned int  var_num) const
inline
Returns
The variable group number that the provided variable number belongs to

Definition at line 2350 of file dof_map.h.

References _var_to_vg, libMesh::libmesh_assert(), and n_variables().

Referenced by libMesh::EquationSystems::build_parallel_solution_vector(), libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::ProjectInteriors::operator()(), should_p_refine_var(), and EquationSystemsTest::testSelectivePRefine().

2351 {
2352  libmesh_assert(var_num < n_variables());
2353  return libmesh_map_find(_var_to_vg, var_num);
2354 }
unsigned int n_variables() const
Definition: dof_map.h:621
std::unordered_map< unsigned int, unsigned int > _var_to_vg
A map from variable number to variable group number.
Definition: dof_map.h:1857
libmesh_assert(ctx)

◆ variable()

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

Definition at line 2114 of file dof_map.h.

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().

2115 {
2116  libmesh_assert_less (c, _variables.size());
2117 
2118  return _variables[c];
2119 }
std::vector< Variable > _variables
The finite element type for each variable.
Definition: dof_map.h:1842

◆ 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 2104 of file dof_map.h.

References _variable_groups.

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

2105 {
2106  libmesh_assert_less (g, _variable_groups.size());
2107 
2108  return _variable_groups[g];
2109 }
std::vector< VariableGroup > _variable_groups
The finite element type for each variable group.
Definition: dof_map.h:1847

◆ 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 2134 of file dof_map.h.

References _variable_groups.

2135 {
2136  libmesh_assert_less (vg, _variable_groups.size());
2137 
2138  return _variable_groups[vg].type().order;
2139 }
std::vector< VariableGroup > _variable_groups
The finite element type for each variable group.
Definition: dof_map.h:1847

◆ 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 2154 of file dof_map.h.

References _variable_groups.

2155 {
2156  libmesh_assert_less (vg, _variable_groups.size());
2157 
2158  return _variable_groups[vg].type();
2159 }
std::vector< VariableGroup > _variable_groups
The finite element type for each variable group.
Definition: dof_map.h:1847

◆ variable_order()

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

Definition at line 2124 of file dof_map.h.

References _variables.

2125 {
2126  libmesh_assert_less (c, _variables.size());
2127 
2128  return _variables[c].type().order;
2129 }
std::vector< Variable > _variables
The finite element type for each variable.
Definition: dof_map.h:1842

◆ 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 2144 of file dof_map.h.

References _variables.

Referenced by libMesh::ExactSolution::_compute_error(), libMesh::UniformRefinementEstimator::_estimate_error(), libMesh::MeshFunction::_gradient_on_elem(), 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_enriched_soln(), compute_jacobian(), libMesh::FEGenericBase< FEOutputType< T >::type >::compute_periodic_constraints(), libMesh::FEInterface::compute_periodic_constraints(), compute_residual(), compute_stresses(), LinearElasticityWithContact::compute_stresses(), LinearElasticity::compute_stresses(), LargeDeformationElasticity::compute_stresses(), constrain_p_dofs(), libMesh::MeshFunction::discontinuous_value(), libMesh::ExactErrorEstimator::estimate_error(), libMesh::MeshFunction::hessian(), libMesh::InfFE< Dim, T_radial, T_map >::inf_compute_constraints(), 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(), process_mesh_constraint_rows(), LargeDeformationElasticity::residual(), Biharmonic::JR::residual_and_jacobian(), LinearElasticityWithContact::residual_and_jacobian(), libMesh::HPCoarsenTest::select_refinement(), and use_coupled_neighbor_dofs().

2145 {
2146  libmesh_assert_less (c, _variables.size());
2147 
2148  return _variables[c].type();
2149 }
std::vector< Variable > _variables
The finite element type for each variable.
Definition: dof_map.h:1842

Friends And Related Function Documentation

◆ SparsityPattern::Build

friend class SparsityPattern::Build
friend

Definition at line 2070 of file dof_map.h.

Member Data Documentation

◆ _adjoint_constraint_values

AdjointDofConstraintValues libMesh::DofMap::_adjoint_constraint_values
private

◆ _adjoint_dirichlet_boundaries

std::vector<std::unique_ptr<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 2067 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(), and remove_adjoint_dirichlet_boundary().

◆ _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 1954 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 1918 of file dof_map.h.

Referenced by attach_extra_send_list_object(), and prepare_send_list().

◆ _augment_sparsity_pattern

SparsityPattern::AugmentSparsityPattern* libMesh::DofMap::_augment_sparsity_pattern
private

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

Definition at line 1901 of file dof_map.h.

Referenced by attach_extra_sparsity_object(), and build_sparsity().

◆ _communicator

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

◆ _constrained_sparsity_construction

bool libMesh::DofMap::_constrained_sparsity_construction
private

This flag indicates whether or not we explicitly take constraint equations into account when computing a sparsity pattern.

Definition at line 1837 of file dof_map.h.

Referenced by compute_sparsity(), constrained_sparsity_construction(), and set_constrained_sparsity_construction().

◆ _counts

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

Actually holds the data.

Definition at line 124 of file reference_counter.h.

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

◆ _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 1967 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 1936 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 1944 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 2061 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 1592 of file dof_map.h.

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

◆ _dont_p_refine

std::unordered_set<unsigned int> libMesh::DofMap::_dont_p_refine
private

A container of variable groups that we should not p-refine.

Definition at line 2025 of file dof_map.h.

Referenced by _dof_indices(), _node_dof_indices(), old_dof_indices(), reinit(), should_p_refine(), and should_p_refine_var().

◆ _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 143 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 1884 of file dof_map.h.

Referenced by clear(), distribute_dofs(), dof_owner(), end_dof(), gather_constraints(), 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 2014 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 1831 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 1928 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 1923 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 1913 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 1906 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 1879 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 2009 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 2020 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 1890 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 2077 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 2076 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 1874 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 137 of file reference_counter.h.

◆ _n_dfs

dof_id_type libMesh::DofMap::_n_dfs
private

Total number of degrees of freedom.

Definition at line 1991 of file dof_map.h.

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

◆ _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 132 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 2004 of file dof_map.h.

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

◆ _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 1997 of file dof_map.h.

Referenced by distribute_scalar_dofs(), 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 2053 of file dof_map.h.

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

◆ _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 1896 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 1973 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.

If need_full_sparsity_pattern is true, we save the entire sparse graph here. Otherwise we save just the n_nz and n_oz vectors.

Definition at line 1986 of file dof_map.h.

Referenced by clear_sparsity(), compute_sparsity(), computed_sparsity_already(), get_info(), get_n_nz(), get_n_oz(), get_sparsity_pattern(), and update_sparsity_pattern().

◆ _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 1862 of file dof_map.h.

Referenced by sys_number().

◆ _var_to_vg

std::unordered_map<unsigned int, unsigned int> libMesh::DofMap::_var_to_vg
private

A map from variable number to variable group number.

Definition at line 1857 of file dof_map.h.

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

◆ _variable_group_numbers

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

The variable group number for each variable.

Definition at line 1852 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 1847 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 1842 of file dof_map.h.

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

◆ _verify_dirichlet_bc_consistency

bool libMesh::DofMap::_verify_dirichlet_bc_consistency
private

Flag which determines whether we should do some additional checking of the consistency of the DirichletBoundary objects added by the user.

Defaults to true, but can be disabled in cases where you only want to add DirichletBoundary objects "locally" and can guarantee that no repartitioning will be done, since repartitioning could cause processors to own new boundary sides for which they no longer have the proper DirichletBoundary objects stored.

Definition at line 2089 of file dof_map.h.

Referenced by create_dof_constraints(), and set_verify_dirichlet_bc_consistency().

◆ 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 1979 of file dof_map.h.

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


The documentation for this class was generated from the following files: