libMesh
Classes | Public Types | 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 Types

typedef std::vector< GhostingFunctor * >::const_iterator GhostingFunctorIterator
 Iterator type for coupling and algebraic ghosting functor ranges. 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...
 
void full_sparsity_pattern_needed ()
 Sets need_full_sparsity_pattern to true regardless of the requirements by matrices. 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...
 
GhostingFunctorIterator coupling_functors_begin () const
 Beginning of range of coupling functors. More...
 
GhostingFunctorIterator 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...
 
GhostingFunctorIterator algebraic_ghosting_functors_begin () const
 Beginning of range of algebraic ghosting functors. More...
 
GhostingFunctorIterator 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
 
unsigned int n_vars () const
 
const std::string & variable_name (const unsigned int i) const
 
unsigned int n_components (const MeshBase &mesh) const
 
bool identify_variable_groups () const
 
void identify_variable_groups (const bool)
 Toggle automatic VariableGroup identification. More...
 
unsigned int variable_scalar_number (unsigned int var_num, unsigned int component) const
 
const FETypevariable_type (const unsigned int i) const
 
const FETypevariable_type (std::string_view var) const
 
unsigned int variable_number (std::string_view var) const
 
bool has_variable (std::string_view var) const
 
void get_all_variable_numbers (std::vector< unsigned int > &all_variable_numbers) const
 Fills all_variable_numbers with all the variable numbers for the variables that have been added to this system. More...
 
unsigned int add_variable (System &sys, std::string_view var, const FEType &type, const std::set< subdomain_id_type > *const active_subdomains=nullptr)
 Adds the variable var to the list of variables for this system. More...
 
unsigned int add_variables (System &sys, const std::vector< std::string > &vars, const FEType &type, const std::set< subdomain_id_type > *const active_subdomains=nullptr)
 Adds the variables vars to the list of variables for this system. More...
 
unsigned int add_variable_array (System &sys, const std::vector< std::string > &vars, const FEType &type, const std::set< subdomain_id_type > *const active_subdomains=nullptr)
 Adds variables vars to the list of variables for this system. 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 override
 
Order variable_order (const unsigned int c) const
 
Order variable_group_order (const unsigned int vg) const
 
const FETypevariable_group_type (const unsigned int vg) const
 
unsigned int n_variable_groups () const
 
unsigned int n_variables () const override
 
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 unsigned int vn) const
 
dof_id_type n_SCALAR_dofs () const
 
dof_id_type n_local_dofs (const unsigned int vn) const
 
std::vector< dof_id_typen_dofs_per_processor (const unsigned int vn) const
 
processor_id_type dof_owner (const dof_id_type dof) const
 
void dof_indices (const Elem *const elem, std::vector< dof_id_type > &di) const
 
void dof_indices (const Elem *const elem, std::vector< dof_id_type > &di, const unsigned int vn, int p_level=-12345) const override
 Fills the vector di with the global degree of freedom indices for the element. More...
 
void array_dof_indices (const Elem *const elem, std::vector< dof_id_type > &di, const unsigned int vn, int p_level=-12345) const
 Fills the vector di with the global degree of freedom indices for the element. More...
 
void array_dof_indices (const Node *const node, std::vector< dof_id_type > &di, const unsigned int vn) const
 
template<typename DofIndicesFunctor >
void array_dof_indices (const DofIndicesFunctor &functor, std::vector< dof_id_type > &di, const unsigned int vn) const
 
template<typename ScalarDofsFunctor , typename FieldDofsFunctor >
void dof_indices (const Elem *const elem, std::vector< dof_id_type > &di, const unsigned int vn, ScalarDofsFunctor scalar_dofs_functor, FieldDofsFunctor field_dofs_functor, int p_level=-12345) const
 Retrieves degree of freedom indices for a given elem and then performs actions for these indices defined by the user-provided functors scalar_dofs_functor and field_dofs_functor. 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 override
 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...
 
template<typename T , std::enable_if_t< std::is_same_v< T, dof_id_type >||std::is_same_v< T, std::vector< dof_id_type >>, int > = 0>
void local_variable_indices (T &idx, const MeshBase &mesh, unsigned int var_num) const
 If T == dof_id_type, counts, if T == std::vector<dof_id_type>, fills an array of, those dof indices which belong to the given variable number and live on the current processor. More...
 
template<typename T , std::enable_if_t< std::is_same_v< T, dof_id_type >||std::is_same_v< T, std::vector< dof_id_type >>, int > = 0>
void local_variable_indices (T &idx, unsigned int var_num) const
 If T == dof_id_type, counts, if T == std::vector<dof_id_type>, fills an array of, those dof indices 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...
 
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, const std::map< const Node *, std::set< subdomain_id_type >> &constraining_subdomains)
 Reinitialize the underlying data structures conformal to the current mesh. More...
 
virtual void clear () override
 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, bool use_condensed_system=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
 
void create_static_condensation (MeshBase &mesh, System &system)
 Add a static condensation class. More...
 
bool has_static_condensation () const
 Checks whether we have static condensation. More...
 
StaticCondensationDofMapget_static_condensation ()
 
void reinit_static_condensation ()
 Calls reinit on the static condensation map if it exists. More...
 
dof_id_type n_dofs () const
 
dof_id_type n_local_dofs () const
 
dof_id_type first_dof (const processor_id_type proc) const
 
dof_id_type first_dof () const
 
dof_id_type end_dof (const processor_id_type proc) const
 
dof_id_type end_dof () const
 
dof_id_type n_dofs () const
 
dof_id_type n_dofs_on_processor (const processor_id_type proc) const
 
dof_id_type n_local_dofs () const
 
dof_id_type n_old_dofs () const
 
dof_id_type first_old_dof (const processor_id_type proc) const
 
dof_id_type first_old_dof () const
 
dof_id_type end_old_dof (const processor_id_type proc) const
 
dof_id_type end_old_dof () const
 
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

std::size_t compute_dof_info (dof_id_type n_local_dofs)
 compute the key degree of freedom information given the local number of degrees of freedom on this process More...
 
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

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...
 
dof_id_type _n_dfs
 Total number of degrees of freedom. 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...
 
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

const std::pair< unsigned int, unsigned int > & get_variable_array (unsigned int vi) const
 Retrieve the array variable bounds for a given variable vi. More...
 
void _dof_indices (const Elem &elem, int p_level, std::vector< dof_id_type > &di, const unsigned int vg, const unsigned int vig, const Node *const *nodes, unsigned int n_nodes, const unsigned int v #ifdef DEBUG, std::size_t &tot_size #endif) const
 Helper function that gets the dof indices on the current element for a non-SCALAR type variable, where the variable is identified by its variable group number vg and its offset vig from the first variable in that group. More...
 
template<typename FieldDofsFunctor >
void _dof_indices (const Elem &elem, int p_level, std::vector< dof_id_type > &di, const unsigned int vg, const unsigned int vig, const Node *const *nodes, unsigned int n_nodes, const unsigned int v, #ifdef DEBUG std::size_t &tot_size, #endif FieldDofsFunctor field_dofs_functor) const
 As above except a field_dofs_functor must be provided. 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...
 
std::map< const Node *, std::set< subdomain_id_type > > calculate_constraining_subdomains ()
 We may have mesh constraint rows with dependent nodes in one subdomain but dependency nodes in another subdomain, and we may have variables whose subdomain restriction includes the dependent subdomain but not the dependency. More...
 
void distribute_local_dofs_var_major (dof_id_type &next_free_dof, MeshBase &mesh, const std::map< const Node *, std::set< subdomain_id_type >> &constraining_subdomains)
 Distributes the global degrees of freedom, for dofs on this processor. More...
 
void distribute_local_dofs_node_major (dof_id_type &next_free_dof, MeshBase &mesh, const std::map< const Node *, std::set< subdomain_id_type >> &constraining_subdomains)
 Distributes the global degrees of freedom for dofs on this processor. 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 GhostingFunctorIterator &gf_begin, const GhostingFunctorIterator &gf_end, const MeshBase::const_element_iterator &elems_begin, const MeshBase::const_element_iterator &elems_end, processor_id_type p)
 

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 variables in this system/degree of freedom map. More...
 
std::vector< VariableGroup_variable_groups
 The variable groups in this system/degree of freedom map. 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...
 
std::map< std::string, unsigned int, std::less<> > _variable_numbers
 The variable numbers corresponding to user-specified names, useful for name-based lookups. More...
 
std::vector< std::pair< unsigned int, unsigned int > > _array_variables
 Array variable information storage. More...
 
bool _identify_variable_groups = true
 true when VariableGroup structures should be automatically identified, false otherwise. 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_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::vector< GhostingFunctor * > _algebraic_ghosting_functors
 The list of all GhostingFunctor objects to be used when distributing ghosted vectors. More...
 
std::vector< 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_SCALAR_dofs
 The total number of SCALAR dofs associated to all SCALAR variables. 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...
 
std::unique_ptr< StaticCondensationDofMap_sc
 Static condensation class. 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 179 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 1992 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 1909 of file dof_map.h.

◆ GhostingFunctorIterator

typedef std::vector<GhostingFunctor *>::const_iterator libMesh::DofMap::GhostingFunctorIterator

Iterator type for coupling and algebraic ghosting functor ranges.

This has changed in the past and may change again; code should use auto or the type here.

Definition at line 315 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 138 of file dof_map.C.

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

139  :
140  DofMapBase (mesh.comm()),
141  _dof_coupling(nullptr),
144  _variables(),
147  _sys_number(number),
148  _mesh(mesh),
149  _matrices(),
151  _send_list(),
152  _augment_sparsity_pattern(nullptr),
153  _extra_sparsity_function(nullptr),
154  _extra_sparsity_context(nullptr),
155  _augment_send_list(nullptr),
156  _extra_send_list_function(nullptr),
157  _extra_send_list_context(nullptr),
158  _default_coupling(std::make_unique<DefaultCoupling>()),
159  _default_evaluating(std::make_unique<DefaultCoupling>()),
161  _n_SCALAR_dofs(0)
162 #ifdef LIBMESH_ENABLE_AMR
164 #endif
165 #ifdef LIBMESH_ENABLE_CONSTRAINTS
166  , _dof_constraints()
170 #endif
171 #ifdef LIBMESH_ENABLE_NODE_CONSTRAINTS
173 #endif
174 #ifdef LIBMESH_ENABLE_PERIODIC
175  , _periodic_boundaries(std::make_unique<PeriodicBoundaries>())
176 #endif
177 #ifdef LIBMESH_ENABLE_DIRICHLET
178  , _dirichlet_boundaries(std::make_unique<DirichletBoundaries>())
180 #endif
184  _sc(nullptr)
185 {
186  _matrices.clear();
187 
188  _default_coupling->set_mesh(&_mesh);
189  _default_evaluating->set_mesh(&_mesh);
190  _default_evaluating->set_n_levels(1);
191 
192 #ifdef LIBMESH_ENABLE_PERIODIC
193  _default_coupling->set_periodic_boundaries(_periodic_boundaries.get());
194  _default_evaluating->set_periodic_boundaries(_periodic_boundaries.get());
195 #endif
196 
199 }
std::vector< VariableGroup > _variable_groups
The variable groups in this system/degree of freedom map.
Definition: dof_map.h:2094
bool _implicit_neighbor_dofs_initialized
Bools to indicate if we override the –implicit_neighbor_dofs commandline options.
Definition: dof_map.h:2315
const unsigned int _sys_number
The number of the system we manage DOFs for.
Definition: dof_map.h:2128
bool _implicit_neighbor_dofs
Definition: dof_map.h:2316
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:2078
void * _extra_sparsity_context
A pointer associated with the extra sparsity that can optionally be passed in.
Definition: dof_map.h:2169
std::unique_ptr< StaticCondensationDofMap > _sc
Static condensation class.
Definition: dof_map.h:2331
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:2152
MeshBase & mesh
std::unique_ptr< DirichletBoundaries > _dirichlet_boundaries
Data structure containing Dirichlet functions.
Definition: dof_map.h:2300
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:2001
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:2146
AdjointDofConstraintValues _adjoint_constraint_values
Definition: dof_map.h:2276
bool _constrained_sparsity_construction
This flag indicates whether or not we explicitly take constraint equations into account when computin...
Definition: dof_map.h:2084
AugmentSendList * _augment_send_list
Function object to call to add extra entries to the send list.
Definition: dof_map.h:2174
bool need_full_sparsity_pattern
Default false; set to true if any attached matrix requires a full sparsity pattern.
Definition: dof_map.h:2238
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:2259
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:2162
dof_id_type _n_SCALAR_dofs
The total number of SCALAR dofs associated to all SCALAR variables.
Definition: dof_map.h:2251
DofConstraints _dof_constraints
Data structure containing DOF constraints.
Definition: dof_map.h:2272
CouplingMatrix * _dof_coupling
Degree of freedom coupling.
Definition: dof_map.h:1741
DofMapBase(const Parallel::Communicator &comm)
Definition: dof_map_base.C:23
void * _extra_send_list_context
A pointer associated with the extra send list that can optionally be passed in.
Definition: dof_map.h:2184
std::vector< SparseMatrix< Number > *> _matrices
Additional matrices handled by this object.
Definition: dof_map.h:2140
std::vector< std::unique_ptr< DirichletBoundaries > > _adjoint_dirichlet_boundaries
Data structure containing Dirichlet functions.
Definition: dof_map.h:2306
std::unique_ptr< PeriodicBoundaries > _periodic_boundaries
Data structure containing periodic boundaries.
Definition: dof_map.h:2292
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:2328
std::unique_ptr< DefaultCoupling > _default_coupling
The default coupling GhostingFunctor, used to implement standard libMesh sparsity pattern constructio...
Definition: dof_map.h:2192
DofConstraintValueMap _primal_constraint_values
Definition: dof_map.h:2274
std::vector< Variable > _variables
The variables in this system/degree of freedom map.
Definition: dof_map.h:2089
DofConstraints _stashed_dof_constraints
Definition: dof_map.h:2272
SparsityPattern::AugmentSparsityPattern * _augment_sparsity_pattern
Function object to call to add extra entries to the sparsity pattern.
Definition: dof_map.h:2157
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:2179
MeshBase & _mesh
The mesh that system uses.
Definition: dof_map.h:2133
std::unique_ptr< DefaultCoupling > _default_evaluating
The default algebraic GhostingFunctor, used to implement standard libMesh send_list construction...
Definition: dof_map.h:2200
std::vector< unsigned int > _variable_group_numbers
The variable group number for each variable.
Definition: dof_map.h:2099
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:2058
NodeConstraints _node_constraints
Data structure containing DofObject constraints.
Definition: dof_map.h:2283

◆ ~DofMap()

libMesh::DofMap::~DofMap ( )

Destructor.

Definition at line 204 of file dof_map.C.

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

205 {
206  this->clear();
207 
208  // clear() resets all but the default DofMap-based functors. We
209  // need to remove those from the mesh too before we die.
212 }
void remove_ghosting_functor(GhostingFunctor &ghosting_functor)
Removes a functor which was previously added to the set of ghosting functors.
Definition: mesh_base.C:970
virtual void clear() override
Free all new memory associated with the object, but restore its original state, with the mesh pointer...
Definition: dof_map.C:867
std::unique_ptr< DefaultCoupling > _default_coupling
The default coupling GhostingFunctor, used to implement standard libMesh sparsity pattern constructio...
Definition: dof_map.h:2192
MeshBase & _mesh
The mesh that system uses.
Definition: dof_map.h:2133
std::unique_ptr< DefaultCoupling > _default_evaluating
The default algebraic GhostingFunctor, used to implement standard libMesh send_list construction...
Definition: dof_map.h:2200

Member Function Documentation

◆ _dof_indices() [1/2]

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,
const unsigned int v #ifdef  DEBUG,
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 2571 of file dof_map.C.

References n_nodes.

Referenced by dof_indices().

2584 {
2585  _dof_indices(elem,
2586  p_level,
2587  di,
2588  vg,
2589  vig,
2590  nodes,
2591  n_nodes,
2592  v,
2593 #ifdef DEBUG
2594  tot_size,
2595 #endif
2596  [](const Elem &,
2597  unsigned int,
2598  unsigned int,
2599  std::vector<dof_id_type> & functor_di,
2600  const dof_id_type dof) { functor_di.push_back(dof); });
2601 }
const dof_id_type n_nodes
Definition: tecplot_io.C:67
void _dof_indices(const Elem &elem, int p_level, std::vector< dof_id_type > &di, const unsigned int vg, const unsigned int vig, const Node *const *nodes, unsigned int n_nodes, const unsigned int v #ifdef DEBUG, std::size_t &tot_size #endif) const
Helper function that gets the dof indices on the current element for a non-SCALAR type variable...
Definition: dof_map.C:2571
uint8_t dof_id_type
Definition: id_types.h:67

◆ _dof_indices() [2/2]

template<typename FieldDofsFunctor >
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,
const unsigned int  v,
#ifdef DEBUG std::size_t &  tot_size,
#endif FieldDofsFunctor  field_dofs_functor 
) const
private

As above except a field_dofs_functor must be provided.

This method is useful when the caller wants to do more than simply fill a degree of freedom container

Parameters
field_dofs_functorThis functor has the interface: void field_dofs_functor(const Elem & elem, const unsigned int node_num, const unsigned int var_num, std::vector<dof_id_type> & di, const dof_id_type field_dof) where field_dof represents a field degree of freedom to act on and is associated with node_num and var_num. If the degree of freedom is elemental than node_num will be invalid_uint. di is the degree of freedom container provided to the _dof_indices method

Definition at line 2615 of file dof_map.h.

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::invalid_uint, libMesh::Elem::is_vertex(), libMesh::LAGRANGE, libMesh::libmesh_assert(), libMesh::DofObject::n_comp_group(), libMesh::DofMapBase::n_dofs(), libMesh::FEInterface::n_dofs(), libMesh::FEInterface::n_dofs_at_node(), libMesh::FEInterface::n_dofs_at_node_function(), libMesh::FEInterface::n_dofs_per_elem(), n_nodes, libMesh::DofObject::n_systems(), libMesh::SUBDIVISION, libMesh::Elem::subdomain_id(), sys_number(), libMesh::Variable::type(), libMesh::Elem::type(), libMesh::DofObject::var_to_vg_and_offset(), and variable_group().

2627 {
2628  const VariableGroup & var = this->variable_group(vg);
2629 
2630  if (var.active_on_subdomain(elem.subdomain_id()))
2631  {
2632  const ElemType type = elem.type();
2633  const unsigned int sys_num = this->sys_number();
2634 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
2635  const bool is_inf = elem.infinite();
2636 #endif
2637 
2638  const bool extra_hanging_dofs =
2639  FEInterface::extra_hanging_dofs(var.type());
2640 
2641  FEType fe_type = var.type();
2642 
2643  const bool add_p_level =
2644 #ifdef LIBMESH_ENABLE_AMR
2645  !_dont_p_refine.count(vg);
2646 #else
2647  false;
2648 #endif
2649 
2650 #ifdef DEBUG
2651  // The number of dofs per element is non-static for subdivision FE
2652  if (var.type().family == SUBDIVISION)
2653  tot_size += n_nodes;
2654  else
2655  // FIXME: Is the passed-in p_level just elem.p_level()? If so,
2656  // this seems redundant.
2657  tot_size += FEInterface::n_dofs(fe_type, add_p_level*p_level, &elem);
2658 #endif
2659 
2660  // The total Order is not required when getting the function
2661  // pointer, it is only needed when the function is called (see
2662  // below).
2663  const FEInterface::n_dofs_at_node_ptr ndan =
2664  FEInterface::n_dofs_at_node_function(fe_type, &elem);
2665 
2666  // Get the node-based DOF numbers
2667  for (unsigned int n=0; n != n_nodes; n++)
2668  {
2669  const Node & node = *nodes[n];
2670 
2671  // Cache the intermediate lookups that are common to every
2672  // component
2673 #ifdef DEBUG
2674  const std::pair<unsigned int, unsigned int>
2675  vg_and_offset = node.var_to_vg_and_offset(sys_num,v);
2676  libmesh_assert_equal_to (vg, vg_and_offset.first);
2677  libmesh_assert_equal_to (vig, vg_and_offset.second);
2678 #endif
2679  const unsigned int n_comp = node.n_comp_group(sys_num,vg);
2680 
2681  // There is a potential problem with h refinement. Imagine a
2682  // quad9 that has a linear FE on it. Then, on the hanging side,
2683  // it can falsely identify a DOF at the mid-edge node. This is why
2684  // we go through FEInterface instead of node.n_comp() directly.
2685  const unsigned int nc =
2686 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
2687  is_inf ?
2688  FEInterface::n_dofs_at_node(fe_type, add_p_level*p_level, &elem, n) :
2689 #endif
2690  ndan (type, fe_type.order + add_p_level*p_level, n);
2691 
2692  // If this is a non-vertex on a hanging node with extra
2693  // degrees of freedom, we use the non-vertex dofs (which
2694  // come in reverse order starting from the end, to
2695  // simplify p refinement)
2696  if (extra_hanging_dofs && !elem.is_vertex(n))
2697  {
2698  const int dof_offset = n_comp - nc;
2699 
2700  // We should never have fewer dofs than necessary on a
2701  // node unless we're getting indices on a parent element,
2702  // and we should never need the indices on such a node
2703  if (dof_offset < 0)
2704  {
2705  libmesh_assert(!elem.active());
2706  di.resize(di.size() + nc, DofObject::invalid_id);
2707  }
2708  else
2709  for (int i=int(n_comp)-1; i>=dof_offset; i--)
2710  {
2711  const dof_id_type d =
2712  node.dof_number(sys_num, vg, vig, i, n_comp);
2713  libmesh_assert_not_equal_to (d, DofObject::invalid_id);
2714  field_dofs_functor(elem, n, v, di, d);
2715  }
2716  }
2717  // If this is a vertex or an element without extra hanging
2718  // dofs, our dofs come in forward order coming from the
2719  // beginning
2720  else
2721  {
2722  // We have a good component index only if it's being
2723  // used on this FE type (nc) *and* it's available on
2724  // this DofObject (n_comp).
2725  const unsigned int good_nc = std::min(n_comp, nc);
2726  for (unsigned int i=0; i!=good_nc; ++i)
2727  {
2728  const dof_id_type d =
2729  node.dof_number(sys_num, vg, vig, i, n_comp);
2730  libmesh_assert_not_equal_to (d, DofObject::invalid_id);
2731  libmesh_assert_less (d, this->n_dofs());
2732  field_dofs_functor(elem, n, v, di, d);
2733  }
2734 
2735  // With fewer good component indices than we need, e.g.
2736  // due to subdomain expansion, the remaining expected
2737  // indices are marked invalid.
2738  if (n_comp < nc)
2739  for (unsigned int i=n_comp; i!=nc; ++i)
2740  di.push_back(DofObject::invalid_id);
2741  }
2742  }
2743 
2744  // If there are any element-based DOF numbers, get them
2745  const unsigned int nc = FEInterface::n_dofs_per_elem(fe_type, add_p_level*p_level, &elem);
2746 
2747  // We should never have fewer dofs than necessary on an
2748  // element unless we're getting indices on a parent element
2749  // (and we should never need those indices) or off-domain for a
2750  // subdomain-restricted variable (where invalid_id is the
2751  // correct thing to return)
2752  if (nc != 0)
2753  {
2754  const unsigned int n_comp = elem.n_comp_group(sys_num,vg);
2755  if (elem.n_systems() > sys_num && nc <= n_comp)
2756  {
2757  for (unsigned int i=0; i<nc; i++)
2758  {
2759  const dof_id_type d =
2760  elem.dof_number(sys_num, vg, vig, i, n_comp);
2761  libmesh_assert_not_equal_to (d, DofObject::invalid_id);
2762 
2763  field_dofs_functor(elem, invalid_uint, v, di, d);
2764  }
2765  }
2766  else
2767  {
2768  libmesh_assert(!elem.active() || fe_type.family == LAGRANGE || fe_type.family == SUBDIVISION);
2769  di.resize(di.size() + nc, DofObject::invalid_id);
2770  }
2771  }
2772  }
2773 }
static unsigned int n_dofs_per_elem(const unsigned int dim, const FEType &fe_t, const ElemType t)
Definition: fe_interface.C:530
ElemType
Defines an enum for geometric element types.
static unsigned int n_dofs(const unsigned int dim, const FEType &fe_t, const ElemType t)
Definition: fe_interface.C:355
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:310
dof_id_type n_dofs() const
Definition: dof_map_base.h:105
unsigned int sys_number() const
Definition: dof_map.h:2338
const dof_id_type n_nodes
Definition: tecplot_io.C:67
static constexpr dof_id_type invalid_id
An invalid id to distinguish an uninitialized DofObject.
Definition: dof_object.h:482
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:2346
static n_dofs_at_node_ptr n_dofs_at_node_function(const unsigned int dim, const FEType &fe_t)
Definition: fe_interface.C:458
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:436
unsigned int(* n_dofs_at_node_ptr)(const ElemType, const Order, const unsigned int)
Definition: fe_interface.h:151
std::unordered_set< unsigned int > _dont_p_refine
A container of variable groups that we should not p-refine.
Definition: dof_map.h:2264
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 2487 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().

2492 {
2493  // Half of this is a cut and paste of _dof_indices code below, but
2494  // duplication actually seems cleaner than creating a helper
2495  // function with a million arguments and hoping the compiler inlines
2496  // it properly into one of our most highly trafficked functions.
2497 
2498  LOG_SCOPE("_node_dof_indices()", "DofMap");
2499 
2500  const unsigned int sys_num = this->sys_number();
2501  const auto [vg, vig] =
2502  obj.var_to_vg_and_offset(sys_num,vn);
2503  const unsigned int n_comp = obj.n_comp_group(sys_num,vg);
2504 
2505  const VariableGroup & var = this->variable_group(vg);
2506  FEType fe_type = var.type();
2507  const bool extra_hanging_dofs =
2509 
2510  const bool add_p_level =
2511 #ifdef LIBMESH_ENABLE_AMR
2512  !_dont_p_refine.count(vg);
2513 #else
2514  false;
2515 #endif
2516 
2517  // There is a potential problem with h refinement. Imagine a
2518  // quad9 that has a linear FE on it. Then, on the hanging side,
2519  // it can falsely identify a DOF at the mid-edge node. This is why
2520  // we go through FEInterface instead of obj->n_comp() directly.
2521  const unsigned int nc =
2522  FEInterface::n_dofs_at_node(fe_type, &elem, n, add_p_level);
2523 
2524  // If this is a non-vertex on a hanging node with extra
2525  // degrees of freedom, we use the non-vertex dofs (which
2526  // come in reverse order starting from the end, to
2527  // simplify p refinement)
2528  if (extra_hanging_dofs && nc && !elem.is_vertex(n))
2529  {
2530  const int dof_offset = n_comp - nc;
2531 
2532  // We should never have fewer dofs than necessary on a
2533  // node unless we're getting indices on a parent element,
2534  // and we should never need the indices on such a node
2535  if (dof_offset < 0)
2536  {
2537  libmesh_assert(!elem.active());
2538  di.resize(di.size() + nc, DofObject::invalid_id);
2539  }
2540  else
2541  for (unsigned int i = dof_offset; i != n_comp; ++i)
2542  {
2543  const dof_id_type d =
2544  obj.dof_number(sys_num, vg, vig, i, n_comp);
2545  libmesh_assert_not_equal_to (d, DofObject::invalid_id);
2546  di.push_back(d);
2547  }
2548  }
2549  // If this is a vertex or an element without extra hanging
2550  // dofs, our dofs come in forward order coming from the
2551  // beginning. But we still might not have all those dofs, in cases
2552  // where a subdomain-restricted variable just had its subdomain
2553  // expanded.
2554  else
2555  {
2556  const unsigned int good_nc =
2557  std::min(static_cast<unsigned int>(n_comp), nc);
2558  for (unsigned int i=0; i != good_nc; ++i)
2559  {
2560  const dof_id_type d =
2561  obj.dof_number(sys_num, vg, vig, i, n_comp);
2562  libmesh_assert_not_equal_to (d, DofObject::invalid_id);
2563  di.push_back(d);
2564  }
2565  for (unsigned int i=good_nc; i != nc; ++i)
2566  di.push_back(DofObject::invalid_id);
2567  }
2568 }
unsigned int sys_number() const
Definition: dof_map.h:2338
static constexpr dof_id_type invalid_id
An invalid id to distinguish an uninitialized DofObject.
Definition: dof_object.h:482
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:2346
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:436
std::unordered_set< unsigned int > _dont_p_refine
A container of variable groups that we should not p-refine.
Definition: dof_map.h:2264
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 2211 of file dof_map_constraints.C.

References _adjoint_constraint_values, and is_constrained_dof().

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

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

References _adjoint_dirichlet_boundaries.

5419 {
5420  unsigned int old_size = cast_int<unsigned int>
5422  for (unsigned int i = old_size; i <= qoi_index; ++i)
5423  _adjoint_dirichlet_boundaries.push_back(std::make_unique<DirichletBoundaries>());
5424 
5425  // Make copy of DirichletBoundary, owned by _adjoint_dirichlet_boundaries
5426  _adjoint_dirichlet_boundaries[qoi_index]->push_back
5427  (std::make_unique<DirichletBoundary>(dirichlet_boundary));
5428 }
std::vector< std::unique_ptr< DirichletBoundaries > > _adjoint_dirichlet_boundaries
Data structure containing Dirichlet functions.
Definition: dof_map.h:2306

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

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

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

2060 {
2061  // We used to implicitly support duplicate inserts to std::set
2062 #ifdef LIBMESH_ENABLE_DEPRECATED
2064  (std::remove(_algebraic_ghosting_functors.begin(),
2066  &evaluable_functor),
2068 #endif
2069 
2070  // We shouldn't have two copies of the same functor
2071  libmesh_assert(std::find(_algebraic_ghosting_functors.begin(),
2073  &evaluable_functor) ==
2075 
2076  _algebraic_ghosting_functors.push_back(&evaluable_functor);
2077  evaluable_functor.set_mesh(&_mesh);
2078  if (to_mesh)
2079  _mesh.add_ghosting_functor(evaluable_functor);
2080 }
libmesh_assert(ctx)
std::vector< GhostingFunctor * > _algebraic_ghosting_functors
The list of all GhostingFunctor objects to be used when distributing ghosted vectors.
Definition: dof_map.h:2213
MeshBase & _mesh
The mesh that system uses.
Definition: dof_map.h:2133
void add_ghosting_functor(GhostingFunctor &ghosting_functor)
Adds a functor which can specify ghosting requirements for use on distributed meshes.
Definition: mesh_base.C:948

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

References _shared_functors, and add_algebraic_ghosting_functor().

415  { _shared_functors[evaluable_functor.get()] = evaluable_functor;
416  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:2232
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:2058

◆ 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 libMesh::DofMapBase::n_dofs().

Referenced by add_constraint_row(), MyConstraint::constrain(), libMesh::VariationalSmootherConstraint::constrain_node_to_line(), libMesh::VariationalSmootherConstraint::constrain_node_to_plane(), libMesh::VariationalSmootherConstraint::fix_node(), 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  // Store the constraint_row in the map
2202  _dof_constraints.insert_or_assign(dof_number, constraint_row);
2203 
2204  std::pair<DofConstraintValueMap::iterator, bool> rhs_it =
2205  _primal_constraint_values.emplace(dof_number, constraint_rhs);
2206  if (!rhs_it.second)
2207  rhs_it.first->second = constraint_rhs;
2208 }
dof_id_type n_dofs() const
Definition: dof_map_base.h:105
bool is_constrained_dof(const dof_id_type dof) const
Definition: dof_map.h:2424
DofConstraints _dof_constraints
Data structure containing DOF constraints.
Definition: dof_map.h:2272
DofConstraintValueMap _primal_constraint_values
Definition: dof_map.h:2274

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

References add_constraint_row().

1159  { 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 5310 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().

5311 {
5312  // This function must be run on all processors at once
5313  parallel_object_only();
5314 
5315  // Return immediately if there's nothing to gather
5316  if (this->n_processors() == 1)
5317  return;
5318 
5319  // We might get to return immediately if none of the processors
5320  // found any constraints
5321  unsigned int has_constraints = !_dof_constraints.empty();
5322  this->comm().max(has_constraints);
5323  if (!has_constraints)
5324  return;
5325 
5326  for (const auto & [constrained_dof, constraint_row] : _dof_constraints)
5327  {
5328  // We only need the dependencies of our own constrained dofs
5329  if (!this->local_index(constrained_dof))
5330  continue;
5331 
5332  for (const auto & j : constraint_row)
5333  {
5334  dof_id_type constraint_dependency = j.first;
5335 
5336  // No point in adding one of our own dofs to the send_list
5337  if (this->local_index(constraint_dependency))
5338  continue;
5339 
5340  _send_list.push_back(constraint_dependency);
5341  }
5342  }
5343 }
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:2152
const Parallel::Communicator & comm() const
processor_id_type n_processors() const
DofConstraints _dof_constraints
Data structure containing DOF constraints.
Definition: dof_map.h:2272
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:967

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

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

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

2003 {
2004  // We used to implicitly support duplicate inserts to std::set
2005 #ifdef LIBMESH_ENABLE_DEPRECATED
2006  _coupling_functors.erase
2007  (std::remove(_coupling_functors.begin(),
2008  _coupling_functors.end(),
2009  &coupling_functor),
2010  _coupling_functors.end());
2011 #endif
2012 
2013  // We shouldn't have two copies of the same functor
2014  libmesh_assert(std::find(_coupling_functors.begin(),
2015  _coupling_functors.end(),
2016  &coupling_functor) ==
2017  _coupling_functors.end());
2018 
2019  _coupling_functors.push_back(&coupling_functor);
2020  coupling_functor.set_mesh(&_mesh);
2021  if (to_mesh)
2022  _mesh.add_ghosting_functor(coupling_functor);
2023 }
libmesh_assert(ctx)
std::vector< GhostingFunctor * > _coupling_functors
The list of all GhostingFunctor objects to be used when coupling degrees of freedom in matrix sparsit...
Definition: dof_map.h:2226
MeshBase & _mesh
The mesh that system uses.
Definition: dof_map.h:2133
void add_ghosting_functor(GhostingFunctor &ghosting_functor)
Adds a functor which can specify ghosting requirements for use on distributed meshes.
Definition: mesh_base.C:948

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

References _shared_functors, and add_coupling_functor().

353  { _shared_functors[coupling_functor.get()] = coupling_functor;
354  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:2001
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:2232

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

1993 {
1994  this->add_coupling_functor(this->default_coupling());
1996 }
DefaultCoupling & default_coupling()
Default coupling functor.
Definition: dof_map.h:378
DefaultCoupling & default_algebraic_ghosting()
Default algebraic ghosting functor.
Definition: dof_map.h:440
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:2001
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:2058

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

5412 {
5413  _dirichlet_boundaries->push_back(std::make_unique<DirichletBoundary>(dirichlet_boundary));
5414 }
std::unique_ptr< DirichletBoundaries > _dirichlet_boundaries
Data structure containing Dirichlet functions.
Definition: dof_map.h:2300

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

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

Referenced by distribute_dofs(), and reinit_send_list().

1684 {
1685  LOG_SCOPE("add_neighbors_to_send_list()", "DofMap");
1686 
1687  // Return immediately if there's no ghost data
1688  if (this->n_processors() == 1)
1689  return;
1690 
1691  const unsigned int n_var = this->n_variables();
1692 
1693  MeshBase::const_element_iterator local_elem_it
1694  = mesh.active_local_elements_begin();
1695  const MeshBase::const_element_iterator local_elem_end
1696  = mesh.active_local_elements_end();
1697 
1698  GhostingFunctor::map_type elements_to_send;
1699  DofMap::CouplingMatricesSet temporary_coupling_matrices;
1700 
1701  // We need to add dofs to the send list if they've been directly
1702  // requested by an algebraic ghosting functor or they've been
1703  // indirectly requested by a coupling functor.
1704  this->merge_ghost_functor_outputs(elements_to_send,
1705  temporary_coupling_matrices,
1708  local_elem_it, local_elem_end, mesh.processor_id());
1709 
1710  this->merge_ghost_functor_outputs(elements_to_send,
1711  temporary_coupling_matrices,
1712  this->coupling_functors_begin(),
1713  this->coupling_functors_end(),
1714  local_elem_it, local_elem_end, mesh.processor_id());
1715 
1716  // Making a list of non-zero coupling matrix columns is an
1717  // O(N_var^2) operation. We cache it so we only have to do it once
1718  // per CouplingMatrix and not once per element.
1719  std::map<const CouplingMatrix *, std::vector<unsigned int>>
1720  column_variable_lists;
1721 
1722  for (const auto & [partner, ghost_coupling] : elements_to_send)
1723  {
1724  // We asked ghosting functors not to give us local elements
1725  libmesh_assert_not_equal_to
1726  (partner->processor_id(), this->processor_id());
1727 
1728  // Loop over any present coupling matrix column variables if we
1729  // have a coupling matrix, or just add all variables to
1730  // send_list if not.
1731  if (ghost_coupling)
1732  {
1733  libmesh_assert_equal_to (ghost_coupling->size(), n_var);
1734 
1735  // Try to find a cached list of column variables.
1736  std::map<const CouplingMatrix *, std::vector<unsigned int>>::const_iterator
1737  column_variable_list = column_variable_lists.find(ghost_coupling);
1738 
1739  // If we didn't find it, then we need to create it.
1740  if (column_variable_list == column_variable_lists.end())
1741  {
1742  auto inserted_variable_list_pair =
1743  column_variable_lists.emplace(ghost_coupling, std::vector<unsigned int>());
1744  column_variable_list = inserted_variable_list_pair.first;
1745 
1746  std::vector<unsigned int> & new_variable_list =
1747  inserted_variable_list_pair.first->second;
1748 
1749  std::vector<unsigned char> has_variable(n_var, false);
1750 
1751  for (unsigned int vi = 0; vi != n_var; ++vi)
1752  {
1753  ConstCouplingRow ccr(vi, *ghost_coupling);
1754 
1755  for (const auto & vj : ccr)
1756  has_variable[vj] = true;
1757  }
1758  for (unsigned int vj = 0; vj != n_var; ++vj)
1759  {
1760  if (has_variable[vj])
1761  new_variable_list.push_back(vj);
1762  }
1763  }
1764 
1765  const std::vector<unsigned int> & variable_list =
1766  column_variable_list->second;
1767 
1768  for (const auto & vj : variable_list)
1769  {
1770  std::vector<dof_id_type> di;
1771  this->dof_indices (partner, di, vj);
1772 
1773  // Insert the remote DOF indices into the send list
1774  for (auto d : di)
1775  if (d != DofObject::invalid_id &&
1776  !this->local_index(d))
1777  {
1778  libmesh_assert_less(d, this->n_dofs());
1779  _send_list.push_back(d);
1780  }
1781  }
1782  }
1783  else
1784  {
1785  std::vector<dof_id_type> di;
1786  this->dof_indices (partner, di);
1787 
1788  // Insert the remote DOF indices into the send list
1789  for (const auto & dof : di)
1790  if (dof != DofObject::invalid_id &&
1791  !this->local_index(dof))
1792  {
1793  libmesh_assert_less(dof, this->n_dofs());
1794  _send_list.push_back(dof);
1795  }
1796  }
1797 
1798  }
1799 
1800  // We're now done with any merged coupling matrices we had to create.
1801  temporary_coupling_matrices.clear();
1802 
1803  //-------------------------------------------------------------------------
1804  // Our coupling functors added dofs from neighboring elements to the
1805  // send list, but we may still need to add non-local dofs from local
1806  // elements.
1807  //-------------------------------------------------------------------------
1808 
1809  // Loop over the active local elements, adding all active elements
1810  // that neighbor an active local element to the send list.
1811  for ( ; local_elem_it != local_elem_end; ++local_elem_it)
1812  {
1813  const Elem * elem = *local_elem_it;
1814 
1815  std::vector<dof_id_type> di;
1816  this->dof_indices (elem, di);
1817 
1818  // Insert the remote DOF indices into the send list
1819  for (const auto & dof : di)
1820  if (dof != DofObject::invalid_id &&
1821  !this->local_index(dof))
1822  {
1823  libmesh_assert_less(dof, this->n_dofs());
1824  _send_list.push_back(dof);
1825  }
1826  }
1827 }
void dof_indices(const Elem *const elem, std::vector< dof_id_type > &di) const
Definition: dof_map.C:2197
dof_id_type n_dofs() const
Definition: dof_map_base.h:105
bool has_variable(std::string_view var) const
Definition: dof_map.h:2975
GhostingFunctorIterator algebraic_ghosting_functors_begin() const
Beginning of range of algebraic ghosting functors.
Definition: dof_map.h:428
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:2152
MeshBase & mesh
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?
GhostingFunctorIterator algebraic_ghosting_functors_end() const
End of range of algebraic ghosting functors.
Definition: dof_map.h:434
processor_id_type n_processors() const
static constexpr dof_id_type invalid_id
An invalid id to distinguish an uninitialized DofObject.
Definition: dof_object.h:482
std::set< std::unique_ptr< CouplingMatrix >, Utility::CompareUnderlying > CouplingMatricesSet
Definition: dof_map.h:1992
unsigned int n_variables() const override
Definition: dof_map.h:736
static void merge_ghost_functor_outputs(GhostingFunctor::map_type &elements_to_ghost, CouplingMatricesSet &temporary_coupling_matrices, const GhostingFunctorIterator &gf_begin, const GhostingFunctorIterator &gf_end, const MeshBase::const_element_iterator &elems_begin, const MeshBase::const_element_iterator &elems_end, processor_id_type p)
Definition: dof_map.C:1581
GhostingFunctorIterator coupling_functors_end() const
End of range of coupling functors.
Definition: dof_map.h:372
processor_id_type processor_id() const
GhostingFunctorIterator coupling_functors_begin() const
Beginning of range of coupling functors.
Definition: dof_map.h:366
bool local_index(dof_id_type dof_index) const
Definition: dof_map.h:967

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

References libMesh::PeriodicBoundaryBase::clone(), and libMesh::PeriodicBoundaryBase::INVERSE.

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

5532 {
5533  auto inverse_boundary = periodic_boundary.clone(PeriodicBoundaryBase::INVERSE);
5534  this->add_periodic_boundary(periodic_boundary, *inverse_boundary);
5535 }
void add_periodic_boundary(const PeriodicBoundaryBase &periodic_boundary)
Adds a copy of the specified periodic boundary to the system.
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...

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

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

5541 {
5542  libmesh_assert_equal_to (boundary.myboundary, inverse_boundary.pairedboundary);
5543  libmesh_assert_equal_to (boundary.pairedboundary, inverse_boundary.myboundary);
5544  libmesh_assert(boundary.get_variables() == inverse_boundary.get_variables());
5545 
5546  // See if we already have a periodic boundary associated myboundary...
5547  PeriodicBoundaryBase * existing_boundary =
5548  _periodic_boundaries->boundary(boundary.myboundary);
5549 
5550  if (!existing_boundary)
5551  {
5552  // ...if not, clone the inputs and add them to the
5553  // PeriodicBoundaries object.
5554  // These will be cleaned up automatically in the
5555  // _periodic_boundaries destructor.
5556  _periodic_boundaries->emplace(boundary.myboundary, boundary.clone());
5557  _periodic_boundaries->emplace(inverse_boundary.myboundary, inverse_boundary.clone());
5558  }
5559  else
5560  {
5561  // ...otherwise, merge this object's variable IDs with the
5562  // existing boundary object's.
5563  existing_boundary->merge(boundary);
5564 
5565  // Do the same merging process for the inverse boundary. The
5566  // inverse had better already exist!
5567  PeriodicBoundaryBase * existing_inverse_boundary =
5568  _periodic_boundaries->boundary(boundary.pairedboundary);
5569  libmesh_assert(existing_inverse_boundary);
5570  existing_inverse_boundary->merge(inverse_boundary);
5571 
5572  // If we had to merge different *types* of boundaries then
5573  // something likely has gone wrong.
5574 #ifdef LIBMESH_HAVE_RTTI
5575  // typeid needs to be given references, not just pointers, to
5576  // return a derived class name.
5577  libmesh_assert(typeid(boundary) == typeid(*existing_boundary));
5578  libmesh_assert(typeid(inverse_boundary) == typeid(*existing_inverse_boundary));
5579 #endif
5580  }
5581 }
const std::set< unsigned int > & get_variables() const
Get the set of variables for this periodic boundary condition.
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:2292
The base class for defining periodic boundaries.

◆ add_variable()

unsigned int libMesh::DofMap::add_variable ( System sys,
std::string_view  var,
const FEType type,
const std::set< subdomain_id_type > *const  active_subdomains = nullptr 
)

Adds the variable var to the list of variables for this system.

If active_subdomains is either nullptr (the default) or points to an empty set, then it will be assumed that var has no subdomain restrictions

Returns
The index number for the new variable.

Definition at line 3142 of file dof_map.C.

References _var_to_vg, _variable_group_numbers, _variable_groups, _variable_numbers, _variables, libMesh::Variable::active_subdomains(), add_variables(), libMesh::VariableGroup::append(), libMesh::ParallelObject::comm(), identify_variable_groups(), libMesh::Variable::implicitly_active(), libMesh::System::is_initialized(), libMesh::libmesh_assert(), libMesh::make_range(), n_variable_groups(), libMesh::VariableGroup::n_variables(), n_vars(), libMesh::Variable::type(), variable(), variable_name(), and variable_type().

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

3146 {
3147  parallel_object_only(); // Not strictly needed, but the only safe way to keep in sync
3148 
3149  libmesh_assert(this->comm().verify(std::string(var)));
3150  libmesh_assert(this->comm().verify(type));
3151  libmesh_assert(this->comm().verify((active_subdomains == nullptr)));
3152 
3153  if (active_subdomains)
3154  libmesh_assert(this->comm().verify(active_subdomains->size()));
3155 
3156  // Make sure the variable isn't there already
3157  // or if it is, that it's the type we want
3158  for (auto v : make_range(this->n_vars()))
3159  if (this->variable_name(v) == var)
3160  {
3161  if (this->variable_type(v) == type)
3162  {
3163  // Check whether the existing variable's active subdomains also matches
3164  // the incoming variable's active subdomains. If they don't match, then
3165  // either it is an error by the user or the user is trying to change the
3166  // subdomain restriction after the variable has already been added, which
3167  // is not supported.
3168  const Variable & existing_var = this->variable(v);
3169 
3170  // Check whether active_subdomains is not provided/empty and the existing_var is
3171  // implicitly_active()
3172  bool check1 = (!active_subdomains || active_subdomains->empty()) &&
3173  existing_var.implicitly_active();
3174 
3175  // Check if the provided active_subdomains is equal to the existing_var's
3176  // active_subdomains
3177  bool check2 =
3178  (active_subdomains && (*active_subdomains == existing_var.active_subdomains()));
3179 
3180  // If either of these checks passed, then we already have this variable
3181  if (check1 || check2)
3182  return _variables[v].number();
3183  }
3184 
3185  libmesh_error_msg("ERROR: incompatible variable "
3186  << var << " has already been added for this system!");
3187  }
3188 
3189  libmesh_assert(!sys.is_initialized());
3190 
3191  if (this->n_variable_groups())
3192  {
3193  // Optimize for VariableGroups here - if the user is adding multiple
3194  // variables of the same FEType and subdomain restriction, catch
3195  // that here and add them as members of the same VariableGroup.
3196  //
3197  // start by setting this flag to whatever the user has requested
3198  // and then consider the conditions which should negate it.
3199  bool should_be_in_vg = this->identify_variable_groups();
3200 
3201  VariableGroup & vg = _variable_groups.back();
3202 
3203  // get a pointer to their subdomain restriction, if any.
3204  const std::set<subdomain_id_type> * const their_active_subdomains(
3205  vg.implicitly_active() ? nullptr : &vg.active_subdomains());
3206 
3207  // Different types?
3208  if (vg.type() != type)
3209  should_be_in_vg = false;
3210 
3211  // they are restricted, we aren't?
3212  if (their_active_subdomains &&
3213  (!active_subdomains || (active_subdomains && active_subdomains->empty())))
3214  should_be_in_vg = false;
3215 
3216  // they aren't restricted, we are?
3217  if (!their_active_subdomains && (active_subdomains && !active_subdomains->empty()))
3218  should_be_in_vg = false;
3219 
3220  if (their_active_subdomains && active_subdomains)
3221  // restricted to different sets?
3222  if (*their_active_subdomains != *active_subdomains)
3223  should_be_in_vg = false;
3224 
3225  // OK, after all that, append the variable to the vg if none of the conditions
3226  // were violated
3227  if (should_be_in_vg)
3228  {
3229  const unsigned int vn = this->n_vars();
3230 
3231  std::string varstr(var);
3232 
3233  _variable_numbers[varstr] = vn;
3234  vg.append(std::move(varstr));
3235  _variables.push_back(vg(vg.n_variables() - 1));
3236  const unsigned int vgn = _variable_groups.size() - 1;
3237  _variable_group_numbers.push_back(vgn);
3238  _var_to_vg.emplace(vn, vgn);
3239 
3240  return vn;
3241  }
3242  }
3243 
3244  // otherwise, fall back to adding a single variable group
3245  return this->add_variables(
3246  sys, std::vector<std::string>(1, std::string(var)), type, active_subdomains);
3247 }
std::vector< VariableGroup > _variable_groups
The variable groups in this system/degree of freedom map.
Definition: dof_map.h:2094
unsigned int n_variable_groups() const
Definition: dof_map.h:733
unsigned int add_variables(System &sys, const std::vector< std::string > &vars, const FEType &type, const std::set< subdomain_id_type > *const active_subdomains=nullptr)
Adds the variables vars to the list of variables for this system.
Definition: dof_map.C:3249
const Parallel::Communicator & comm() const
std::map< std::string, unsigned int, std::less<> > _variable_numbers
The variable numbers corresponding to user-specified names, useful for name-based lookups...
Definition: dof_map.h:2110
const Variable & variable(const unsigned int c) const override
Definition: dof_map.h:2356
bool identify_variable_groups() const
Definition: dof_map.h:2940
std::unordered_map< unsigned int, unsigned int > _var_to_vg
A map from variable number to variable group number.
Definition: dof_map.h:2104
libmesh_assert(ctx)
const FEType & variable_type(const unsigned int i) const
Definition: dof_map.h:2386
const std::string & variable_name(const unsigned int i) const
Definition: dof_map.h:2932
unsigned int n_vars() const
Definition: dof_map.h:2926
std::vector< Variable > _variables
The variables in this system/degree of freedom map.
Definition: dof_map.h:2089
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:140
std::vector< unsigned int > _variable_group_numbers
The variable group number for each variable.
Definition: dof_map.h:2099

◆ add_variable_array()

unsigned int libMesh::DofMap::add_variable_array ( System sys,
const std::vector< std::string > &  vars,
const FEType type,
const std::set< subdomain_id_type > *const  active_subdomains = nullptr 
)

Adds variables vars to the list of variables for this system.

If active_subdomains is either nullptr (the default) or points to an empty set, then it will be assumed that the vars have no subdomain restrictions. This API will end up calling this->add_variables(). However, we will additionally store data that can be leveraged by the DofMap to build degrees of freedom containers corresponding to all the variables in this variable array

An 'array variable' is simply a sequence of contiguous variable numbers defined by pair where the first member of the pair is the first number in the variable sequence and the second member of the pair is the number of the last variable in the sequence plus one. Array variables may be used in tandem with variable grouping by downstream code to build optimized physics kernels since each variable in the array will have the same shape functions.

Returns
The index number for the last of the new variables.

Definition at line 3373 of file dof_map.C.

References _array_variables, and add_variables().

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

3377 {
3378  const unsigned int count = cast_int<unsigned int>(vars.size());
3379  const unsigned int last_var = this->add_variables(sys, vars, type, active_subdomains);
3380  const unsigned int first_var = last_var + 1 - count;
3381  _array_variables.push_back({first_var, first_var + count});
3382  return last_var;
3383 }
unsigned int add_variables(System &sys, const std::vector< std::string > &vars, const FEType &type, const std::set< subdomain_id_type > *const active_subdomains=nullptr)
Adds the variables vars to the list of variables for this system.
Definition: dof_map.C:3249
std::vector< std::pair< unsigned int, unsigned int > > _array_variables
Array variable information storage.
Definition: dof_map.h:2117

◆ add_variables()

unsigned int libMesh::DofMap::add_variables ( System sys,
const std::vector< std::string > &  vars,
const FEType type,
const std::set< subdomain_id_type > *const  active_subdomains = nullptr 
)

Adds the variables vars to the list of variables for this system.

If active_subdomains is either nullptr (the default) or points to an empty set, then it will be assumed that the vars have no subdomain restrictions

Returns
The index number for the last of the new variables.

Definition at line 3249 of file dof_map.C.

References _var_to_vg, _variable_group_numbers, _variable_groups, _variable_numbers, _variables, libMesh::Variable::active_subdomains(), libMesh::VariableGroup::append(), libMesh::ParallelObject::comm(), libMesh::System::get_mesh(), identify_variable_groups(), libMesh::Variable::implicitly_active(), libMesh::System::is_initialized(), libMesh::libmesh_assert(), libMesh::make_range(), n_components(), n_variable_groups(), libMesh::VariableGroup::n_variables(), n_vars(), libMesh::Variable::type(), variable_name(), and variable_type().

Referenced by add_variable(), add_variable_array(), and libMesh::System::add_variables().

3253 {
3254  parallel_object_only(); // Not strictly needed, but the only safe way to keep in sync
3255 
3256  libmesh_assert(!sys.is_initialized());
3257 
3258  libmesh_assert(this->comm().verify(vars.size()));
3259  libmesh_assert(this->comm().verify(type));
3260  libmesh_assert(this->comm().verify((active_subdomains == nullptr)));
3261 
3262  if (active_subdomains)
3263  libmesh_assert(this->comm().verify(active_subdomains->size()));
3264 
3265  // Make sure the variable isn't there already
3266  // or if it is, that it's the type we want
3267  for (auto ovar : vars)
3268  {
3269  libmesh_assert(this->comm().verify(ovar));
3270 
3271  for (auto v : make_range(this->n_vars()))
3272  if (this->variable_name(v) == ovar)
3273  {
3274  if (this->variable_type(v) == type)
3275  return _variables[v].number();
3276 
3277  libmesh_error_msg("ERROR: incompatible variable "
3278  << ovar << " has already been added for this system!");
3279  }
3280  }
3281 
3282  if (this->n_variable_groups())
3283  {
3284  // Optimize for VariableGroups here - if the user is adding multiple
3285  // variables of the same FEType and subdomain restriction, catch
3286  // that here and add them as members of the same VariableGroup.
3287  //
3288  // start by setting this flag to whatever the user has requested
3289  // and then consider the conditions which should negate it.
3290  bool should_be_in_vg = this->identify_variable_groups();
3291 
3292  VariableGroup & vg = _variable_groups.back();
3293 
3294  // get a pointer to their subdomain restriction, if any.
3295  const std::set<subdomain_id_type> * const their_active_subdomains(
3296  vg.implicitly_active() ? nullptr : &vg.active_subdomains());
3297 
3298  // Different types?
3299  if (vg.type() != type)
3300  should_be_in_vg = false;
3301 
3302  // they are restricted, we aren't?
3303  if (their_active_subdomains &&
3304  (!active_subdomains || (active_subdomains && active_subdomains->empty())))
3305  should_be_in_vg = false;
3306 
3307  // they aren't restricted, we are?
3308  if (!their_active_subdomains && (active_subdomains && !active_subdomains->empty()))
3309  should_be_in_vg = false;
3310 
3311  if (their_active_subdomains && active_subdomains)
3312  // restricted to different sets?
3313  if (*their_active_subdomains != *active_subdomains)
3314  should_be_in_vg = false;
3315 
3316  // If after all that none of the conditions were violated,
3317  // append the variables to the vg and we're done
3318  if (should_be_in_vg)
3319  {
3320  unsigned int vn = this->n_vars();
3321  const unsigned int vgn = _variable_groups.size() - 1;
3322 
3323  for (auto ovar : vars)
3324  {
3325  vn = this->n_vars();
3326 
3327  vg.append(ovar);
3328 
3329  _variables.push_back(vg(vg.n_variables() - 1));
3330  _variable_numbers[ovar] = vn;
3331  _variable_group_numbers.push_back(vgn);
3332  _var_to_vg.emplace(vn, vgn);
3333  }
3334  return vn;
3335  }
3336  }
3337 
3338  const unsigned int curr_n_vars = this->n_vars();
3339 
3340  const unsigned int next_first_component = this->n_components(sys.get_mesh());
3341 
3342  // We weren't able to add to an existing variable group, so
3343  // add a new variable group to the list
3344  _variable_groups.push_back(
3345  (active_subdomains == nullptr)
3346  ? VariableGroup(&sys, vars, curr_n_vars, next_first_component, type)
3347  : VariableGroup(&sys, vars, curr_n_vars, next_first_component, type, *active_subdomains));
3348 
3349  const VariableGroup & vg(_variable_groups.back());
3350  const unsigned int vgn = _variable_groups.size() - 1;
3351 
3352  // Add each component of the group individually
3353  for (auto v : make_range(vars.size()))
3354  {
3355  const unsigned int vn = curr_n_vars + v;
3356  _variables.push_back(vg(v));
3357  _variable_numbers[vars[v]] = vn;
3358  _variable_group_numbers.push_back(vgn);
3359  _var_to_vg.emplace(vn, vgn);
3360  }
3361 
3362  libmesh_assert_equal_to((curr_n_vars + vars.size()), this->n_vars());
3363 
3364  // BSK - Defer this now to System::init_data() so we can detect
3365  // VariableGroups 12/28/2012
3366  // // Add the variable group to the _dof_map
3367  // _dof_map->add_variable_group (vg);
3368 
3369  // Return the number of the new variable
3370  return cast_int<unsigned int>(curr_n_vars + vars.size() - 1);
3371 }
std::vector< VariableGroup > _variable_groups
The variable groups in this system/degree of freedom map.
Definition: dof_map.h:2094
unsigned int n_variable_groups() const
Definition: dof_map.h:733
unsigned int n_components(const MeshBase &mesh) const
Definition: dof_map.h:2952
const Parallel::Communicator & comm() const
std::map< std::string, unsigned int, std::less<> > _variable_numbers
The variable numbers corresponding to user-specified names, useful for name-based lookups...
Definition: dof_map.h:2110
bool identify_variable_groups() const
Definition: dof_map.h:2940
std::unordered_map< unsigned int, unsigned int > _var_to_vg
A map from variable number to variable group number.
Definition: dof_map.h:2104
libmesh_assert(ctx)
const FEType & variable_type(const unsigned int i) const
Definition: dof_map.h:2386
const std::string & variable_name(const unsigned int i) const
Definition: dof_map.h:2932
unsigned int n_vars() const
Definition: dof_map.h:2926
std::vector< Variable > _variables
The variables in this system/degree of freedom map.
Definition: dof_map.h:2089
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:140
std::vector< unsigned int > _variable_group_numbers
The variable group number for each variable.
Definition: dof_map.h:2099

◆ algebraic_ghosting_functors_begin()

GhostingFunctorIterator libMesh::DofMap::algebraic_ghosting_functors_begin ( ) const
inline

Beginning of range of algebraic ghosting functors.

Definition at line 428 of file dof_map.h.

References _algebraic_ghosting_functors.

Referenced by add_neighbors_to_send_list().

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

◆ algebraic_ghosting_functors_end()

GhostingFunctorIterator libMesh::DofMap::algebraic_ghosting_functors_end ( ) const
inline

End of range of algebraic ghosting functors.

Definition at line 434 of file dof_map.h.

References _algebraic_ghosting_functors.

Referenced by add_neighbors_to_send_list().

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

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

References semilocal_index().

Referenced by is_evaluable().

2656 {
2657  // We're all semilocal unless we find a counterexample
2658  for (const auto & di : dof_indices_in)
2659  if (!this->semilocal_index(di))
2660  return false;
2661 
2662  return true;
2663 }
bool semilocal_index(dof_id_type dof_index) const
Definition: dof_map.C:2639

◆ allgather_recursive_constraints()

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

Gathers constraint equation dependencies from other processors.

Definition at line 3676 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(), libMesh::DofObject::n_vars(), 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().

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

◆ array_dof_indices() [1/3]

void libMesh::DofMap::array_dof_indices ( const Elem *const  elem,
std::vector< dof_id_type > &  di,
const unsigned int  vn,
int  p_level = -12345 
) const

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

This will aggregate all the degrees of the freedom from the variable array that vn is a member of, and potentially for a non-default element p refinement level

Definition at line 2335 of file dof_map.C.

References dof_indices().

Referenced by array_dof_indices().

2339 {
2340  auto dof_indices_functor = [elem, p_level, this](std::vector<dof_id_type> & functor_di,
2341  const unsigned int functor_vn) {
2342  this->dof_indices(elem, functor_di, functor_vn, p_level);
2343  };
2344  this->array_dof_indices(dof_indices_functor, di, vn);
2345 }
void dof_indices(const Elem *const elem, std::vector< dof_id_type > &di) const
Definition: dof_map.C:2197
void array_dof_indices(const Elem *const elem, std::vector< dof_id_type > &di, const unsigned int vn, int p_level=-12345) const
Fills the vector di with the global degree of freedom indices for the element.
Definition: dof_map.C:2335

◆ array_dof_indices() [2/3]

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

Definition at line 2347 of file dof_map.C.

References array_dof_indices(), and dof_indices().

2350 {
2351  auto dof_indices_functor = [node, this](std::vector<dof_id_type> & functor_di,
2352  const unsigned int functor_vn) {
2353  this->dof_indices(node, functor_di, functor_vn);
2354  };
2355  this->array_dof_indices(dof_indices_functor, di, vn);
2356 }
void dof_indices(const Elem *const elem, std::vector< dof_id_type > &di) const
Definition: dof_map.C:2197
void array_dof_indices(const Elem *const elem, std::vector< dof_id_type > &di, const unsigned int vn, int p_level=-12345) const
Fills the vector di with the global degree of freedom indices for the element.
Definition: dof_map.C:2335

◆ array_dof_indices() [3/3]

template<typename DofIndicesFunctor >
void libMesh::DofMap::array_dof_indices ( const DofIndicesFunctor &  functor,
std::vector< dof_id_type > &  di,
const unsigned int  vn 
) const

Definition at line 2879 of file dof_map.h.

References _var_to_vg, _variable_groups, libMesh::DISCONTINUOUS, libMesh::FEInterface::get_continuity(), get_variable_array(), libMesh::LAGRANGE, libMesh::libmesh_assert(), and libMesh::make_range().

2882 {
2883  const auto [begin, end] = this->get_variable_array(vn);
2884  functor(di, begin);
2885 
2886  const unsigned int count = end - begin;
2887  // We make count, which could be >> ntest, the inner index in hopes of vectorization
2888  if (count > 1)
2889  {
2890  const dof_id_type component_size = di.size();
2891  di.resize(count * component_size);
2892 
2893  const auto pack_container = [&di,
2894  component_size](const unsigned int j,
2895  const std::vector<dof_id_type> & j_dof_indices,
2896  const unsigned int stride) {
2897  if (&j_dof_indices != &di)
2898  libmesh_assert(j_dof_indices.size() == component_size);
2899  for (const auto i : make_range(component_size))
2900  di[j * component_size + i] = j_dof_indices[i] + stride * j;
2901  };
2902  pack_container(0, di, 0);
2903 
2904  const auto & fe_type = _variable_groups[libmesh_map_find(_var_to_vg, vn)].type();
2905  if (const bool lagrange = fe_type.family == LAGRANGE;
2906  lagrange || (FEInterface::get_continuity(fe_type) == DISCONTINUOUS))
2907  {
2908  const auto stride = lagrange ? 1 : component_size;
2909  for (const auto j : make_range((unsigned int)1, count))
2910  pack_container(j, di, stride);
2911  }
2912  else
2913  {
2914  static thread_local std::vector<dof_id_type> work_dof_indices;
2915  unsigned int j = 1;
2916  for (const auto i : make_range(begin + 1, end))
2917  {
2918  functor(work_dof_indices, i);
2919  pack_container(j++, work_dof_indices, 0);
2920  }
2921  }
2922  }
2923 }
std::vector< VariableGroup > _variable_groups
The variable groups in this system/degree of freedom map.
Definition: dof_map.h:2094
const std::pair< unsigned int, unsigned int > & get_variable_array(unsigned int vi) const
Retrieve the array variable bounds for a given variable vi.
Definition: dof_map.h:2862
std::unordered_map< unsigned int, unsigned int > _var_to_vg
A map from variable number to variable group number.
Definition: dof_map.h:2104
libmesh_assert(ctx)
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:140
uint8_t dof_id_type
Definition: id_types.h:67

◆ assert_no_nodes_missed()

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

Definition at line 1559 of file dof_map.C.

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

1560 {
1561  MeshTools::libmesh_assert_valid_procids<Node>(mesh);
1562 
1563  for (auto & node : mesh.local_node_ptr_range())
1564  {
1565  unsigned int n_var_g = node->n_var_groups(this->sys_number());
1566  for (unsigned int vg=0; vg != n_var_g; ++vg)
1567  {
1568  unsigned int n_comp_g =
1569  node->n_comp_group(this->sys_number(), vg);
1570  dof_id_type my_first_dof = n_comp_g ?
1571  node->vg_dof_base(this->sys_number(), vg) : 0;
1572  libmesh_assert_not_equal_to (my_first_dof, DofObject::invalid_id);
1573  }
1574  }
1575 }
MeshBase & mesh
unsigned int sys_number() const
Definition: dof_map.h:2338
static constexpr dof_id_type invalid_id
An invalid id to distinguish an uninitialized DofObject.
Definition: dof_object.h:482
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 490 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:2184
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:2179

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

References _augment_send_list.

482  {
483  _augment_send_list = &asl;
484  }
AugmentSendList * _augment_send_list
Function object to call to add extra entries to the send list.
Definition: dof_map.h:2174

◆ 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 467 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:2169
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:2162

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

References _augment_sparsity_pattern.

453  {
455  }
SparsityPattern::AugmentSparsityPattern * _augment_sparsity_pattern
Function object to call to add extra entries to the sparsity pattern.
Definition: dof_map.h:2157

◆ 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 240 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::ClawSystem::init_data(), libMesh::System::init_matrices(), and libMesh::System::late_matrix_init().

241 {
242  parallel_object_only();
243 
244  // We shouldn't be trying to re-attach the same matrices repeatedly
245  libmesh_assert (std::find(_matrices.begin(), _matrices.end(),
246  &matrix) == _matrices.end());
247 
248  _matrices.push_back(&matrix);
249 
250  this->update_sparsity_pattern(matrix);
251 
252  if (matrix.need_full_sparsity_pattern())
254 }
bool need_full_sparsity_pattern
Default false; set to true if any attached matrix requires a full sparsity pattern.
Definition: dof_map.h:2238
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:269
std::vector< SparseMatrix< Number > *> _matrices
Additional matrices handled by this object.
Definition: dof_map.h:2140
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 766 of file dof_map.h.

References has_blocked_representation(), and n_variables().

767  {
768  return (this->has_blocked_representation() ? this->n_variables() : 1);
769  }
unsigned int n_variables() const override
Definition: dof_map.h:736
bool has_blocked_representation() const
Definition: dof_map.h:749

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

3435 {
3436  LOG_SCOPE_IF("build_constraint_matrix()", "DofMap", !called_recursively);
3437 
3438  // Create a set containing the DOFs we already depend on
3439  typedef std::set<dof_id_type> RCSet;
3440  RCSet dof_set;
3441 
3442  bool we_have_constraints = false;
3443 
3444  // Next insert any other dofs the current dofs might be constrained
3445  // in terms of. Note that in this case we may not be done: Those
3446  // may in turn depend on others. So, we need to repeat this process
3447  // in that case until the system depends only on unconstrained
3448  // degrees of freedom.
3449  for (const auto & dof : elem_dofs)
3450  if (this->is_constrained_dof(dof))
3451  {
3452  we_have_constraints = true;
3453 
3454  // If the DOF is constrained
3455  DofConstraints::const_iterator
3456  pos = _dof_constraints.find(dof);
3457 
3458  libmesh_assert (pos != _dof_constraints.end());
3459 
3460  const DofConstraintRow & constraint_row = pos->second;
3461 
3462  // Constraint rows in p refinement may be empty
3463  //libmesh_assert (!constraint_row.empty());
3464 
3465  for (const auto & item : constraint_row)
3466  dof_set.insert (item.first);
3467  }
3468 
3469  // May be safe to return at this point
3470  // (but remember to stop the perflog)
3471  if (!we_have_constraints)
3472  return;
3473 
3474  for (const auto & dof : elem_dofs)
3475  dof_set.erase (dof);
3476 
3477  // If we added any DOFS then we need to do this recursively.
3478  // It is possible that we just added a DOF that is also
3479  // constrained!
3480  //
3481  // Also, we need to handle the special case of an element having DOFs
3482  // constrained in terms of other, local DOFs
3483  if (!dof_set.empty() || // case 1: constrained in terms of other DOFs
3484  !called_recursively) // case 2: constrained in terms of our own DOFs
3485  {
3486  const unsigned int old_size =
3487  cast_int<unsigned int>(elem_dofs.size());
3488 
3489  // Add new dependency dofs to the end of the current dof set
3490  elem_dofs.insert(elem_dofs.end(),
3491  dof_set.begin(), dof_set.end());
3492 
3493  // Now we can build the constraint matrix.
3494  // Note that resize also zeros for a DenseMatrix<Number>.
3495  C.resize (old_size,
3496  cast_int<unsigned int>(elem_dofs.size()));
3497 
3498  // Create the C constraint matrix.
3499  for (unsigned int i=0; i != old_size; i++)
3500  if (this->is_constrained_dof(elem_dofs[i]))
3501  {
3502  // If the DOF is constrained
3503  DofConstraints::const_iterator
3504  pos = _dof_constraints.find(elem_dofs[i]);
3505 
3506  libmesh_assert (pos != _dof_constraints.end());
3507 
3508  const DofConstraintRow & constraint_row = pos->second;
3509 
3510  // p refinement creates empty constraint rows
3511  // libmesh_assert (!constraint_row.empty());
3512 
3513  for (const auto & item : constraint_row)
3514  for (unsigned int j=0,
3515  n_elem_dofs = cast_int<unsigned int>(elem_dofs.size());
3516  j != n_elem_dofs; j++)
3517  if (elem_dofs[j] == item.first)
3518  C(i,j) = item.second;
3519  }
3520  else
3521  {
3522  C(i,i) = 1.;
3523  }
3524 
3525  // May need to do this recursively. It is possible
3526  // that we just replaced a constrained DOF with another
3527  // constrained DOF.
3528  DenseMatrix<Number> Cnew;
3529 
3530  this->build_constraint_matrix (Cnew, elem_dofs, true);
3531 
3532  if ((C.n() == Cnew.m()) &&
3533  (Cnew.n() == elem_dofs.size())) // If the constraint matrix
3534  C.right_multiply(Cnew); // is constrained...
3535 
3536  libmesh_assert_equal_to (C.n(), elem_dofs.size());
3537  }
3538 }
unsigned int m() const
libmesh_assert(ctx)
bool is_constrained_dof(const dof_id_type dof) const
Definition: dof_map.h:2424
DofConstraints _dof_constraints
Data structure containing DOF constraints.
Definition: dof_map.h:2272
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:100
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 3542 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().

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

◆ build_sparsity()

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

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

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

References _augment_sparsity_pattern, _coupling_functors, _dof_coupling, _extra_sparsity_context, _extra_sparsity_function, _sc, has_static_condensation(), libMesh::libmesh_assert(), mesh, libMesh::DofMapBase::n_local_dofs(), need_full_sparsity_pattern, libMesh::out, libMesh::Threads::parallel_reduce(), and use_coupled_neighbor_dofs().

Referenced by compute_sparsity(), process_mesh_constraint_rows(), libMesh::StaticCondensationDofMap::reinit(), 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 PetscMatrixBase 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  const StaticCondensationDofMap * sc = nullptr;
85  if (use_condensed_system)
86  {
88  sc = _sc.get();
89  }
90 
91  // We can compute the sparsity pattern in parallel on multiple
92  // threads. The goal is for each thread to compute the full sparsity
93  // pattern for a subset of elements. These sparsity patterns can
94  // be efficiently merged in the SparsityPattern::Build::join()
95  // method, especially if there is not too much overlap between them.
96  // Even better, if the full sparsity pattern is not needed then
97  // the number of nonzeros per row can be estimated from the
98  // sparsity patterns created on each thread.
99  auto sp = std::make_unique<SparsityPattern::Build>
100  (*this,
101  this->_dof_coupling,
102  this->_coupling_functors,
103  implicit_neighbor_dofs,
105  calculate_constrained,
106  sc);
107 
108  Threads::parallel_reduce (ConstElemRange (mesh.active_local_elements_begin(),
109  mesh.active_local_elements_end()), *sp);
110 
111  sp->parallel_sync();
112 
113  libmesh_assert_equal_to (sp->get_sparsity_pattern().size(), this->n_local_dofs());
114 
115  // Check to see if we have any extra stuff to add to the sparsity_pattern
117  {
119  {
120  libmesh_here();
121  libMesh::out << "WARNING: You have specified both an extra sparsity function and object.\n"
122  << " Are you sure this is what you meant to do??"
123  << std::endl;
124  }
125 
126  sp->apply_extra_sparsity_function(_extra_sparsity_function,
128  }
129 
131  sp->apply_extra_sparsity_object(*_augment_sparsity_pattern);
132 
133  return sp;
134 }
void * _extra_sparsity_context
A pointer associated with the extra sparsity that can optionally be passed in.
Definition: dof_map.h:2169
std::unique_ptr< StaticCondensationDofMap > _sc
Static condensation class.
Definition: dof_map.h:2331
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:1899
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:2238
bool has_static_condensation() const
Checks whether we have static condensation.
Definition: dof_map.h:1796
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:2162
libmesh_assert(ctx)
std::vector< GhostingFunctor * > _coupling_functors
The list of all GhostingFunctor objects to be used when coupling degrees of freedom in matrix sparsit...
Definition: dof_map.h:2226
CouplingMatrix * _dof_coupling
Degree of freedom coupling.
Definition: dof_map.h:1741
OStreamProxy out
SparsityPattern::AugmentSparsityPattern * _augment_sparsity_pattern
Function object to call to add extra entries to the sparsity pattern.
Definition: dof_map.h:2157
dof_id_type n_local_dofs() const
Definition: dof_map_base.h:115
void parallel_reduce(const Range &range, Body &body)
Execute the provided reduction operation in parallel on the specified range.
Definition: threads_none.h:101

◆ calculate_constraining_subdomains()

std::map< const Node *, std::set< subdomain_id_type > > libMesh::DofMap::calculate_constraining_subdomains ( )
private

We may have mesh constraint rows with dependent nodes in one subdomain but dependency nodes in another subdomain, and we may have variables whose subdomain restriction includes the dependent subdomain but not the dependency.

In those cases we need to place degrees of freedom on dependency nodes anyway.

The set value for node n will include all subdomain ids of elements with nodes in subdomains constrained by n.

We use a map<set> rather than a multimap here because we expect to be inserting the same subdomain multiple times and we don't need duplicate values.

Definition at line 1252 of file dof_map.C.

References _mesh, and libMesh::MeshBase::get_constraint_rows().

Referenced by distribute_dofs().

1253 {
1254  std::map<const Node *, std::set<subdomain_id_type>> constraining_subdomains;
1255  const auto & constraint_rows = _mesh.get_constraint_rows();
1256 
1257  // We can't just loop over constraint rows here because we need
1258  // element subdomain ids for the constrained nodes, but we don't
1259  // want an extra loop if there are no constraint rows.
1260  if (!constraint_rows.empty())
1261  for (auto & elem : _mesh.active_element_ptr_range())
1262  {
1263  const subdomain_id_type sbdid = elem->subdomain_id();
1264 
1265  for (const Node & node : elem->node_ref_range())
1266  {
1267  if (auto it = constraint_rows.find(&node);
1268  it != constraint_rows.end())
1269  {
1270  for (const auto & [pr, val] : it->second)
1271  {
1272  const Node * spline_node =
1273  pr.first->node_ptr(pr.second);
1274 
1275  constraining_subdomains[spline_node].insert(sbdid);
1276  }
1277  }
1278  }
1279  }
1280 
1281  return constraining_subdomains;
1282 }
constraint_rows_type & get_constraint_rows()
Constraint rows accessors.
Definition: mesh_base.h:1709
TestClass subdomain_id_type
Based on the 4-byte comment warning above, this probably doesn&#39;t work with exodusII at all...
Definition: id_types.h:43
MeshBase & _mesh
The mesh that system uses.
Definition: dof_map.h:2133

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

5495 {
5496  const std::set<boundary_id_type>& mesh_side_bcids =
5498  const std::set<boundary_id_type>& mesh_edge_bcids =
5500  const std::set<boundary_id_type>& mesh_node_bcids =
5502  const std::set<boundary_id_type>& dbc_bcids = boundary.b;
5503 
5504  // DirichletBoundary id sets should be consistent across all ranks
5505  libmesh_assert(mesh.comm().verify(dbc_bcids.size()));
5506 
5507  for (const auto & bc_id : dbc_bcids)
5508  {
5509  // DirichletBoundary id sets should be consistent across all ranks
5510  libmesh_assert(mesh.comm().verify(bc_id));
5511 
5512  bool found_bcid = (mesh_side_bcids.find(bc_id) != mesh_side_bcids.end() ||
5513  mesh_edge_bcids.find(bc_id) != mesh_edge_bcids.end() ||
5514  mesh_node_bcids.find(bc_id) != mesh_node_bcids.end());
5515 
5516  // On a distributed mesh, boundary id sets may *not* be
5517  // consistent across all ranks, since not all ranks see all
5518  // boundaries
5519  mesh.comm().max(found_bcid);
5520 
5521  libmesh_error_msg_if(!found_bcid,
5522  "Could not find Dirichlet boundary id " << bc_id << " in mesh!");
5523  }
5524 }
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:165
const std::set< boundary_id_type > & get_node_boundary_ids() const
libmesh_assert(ctx)
const std::set< boundary_id_type > & get_boundary_ids() const
timpi_pure bool verify(const T &r) 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 4508 of file dof_map_constraints.C.

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

Referenced by check_for_cyclic_constraints(), and process_constraints().

4509 {
4510  // Create a set containing the DOFs we already depend on
4511  typedef std::set<dof_id_type> RCSet;
4512  RCSet unexpanded_set;
4513 
4514  // Use dof_constraints_copy in this method so that we don't
4515  // mess with _dof_constraints.
4516  DofConstraints dof_constraints_copy = _dof_constraints;
4517 
4518  for (const auto & i : dof_constraints_copy)
4519  unexpanded_set.insert(i.first);
4520 
4521  while (!unexpanded_set.empty())
4522  for (RCSet::iterator i = unexpanded_set.begin();
4523  i != unexpanded_set.end(); /* nothing */)
4524  {
4525  // If the DOF is constrained
4526  DofConstraints::iterator
4527  pos = dof_constraints_copy.find(*i);
4528 
4529  libmesh_assert (pos != dof_constraints_copy.end());
4530 
4531  DofConstraintRow & constraint_row = pos->second;
4532 
4533  // Comment out "rhs" parts of this method copied from process_constraints
4534  // DofConstraintValueMap::iterator rhsit =
4535  // _primal_constraint_values.find(*i);
4536  // Number constraint_rhs = (rhsit == _primal_constraint_values.end()) ?
4537  // 0 : rhsit->second;
4538 
4539  std::vector<dof_id_type> constraints_to_expand;
4540 
4541  for (const auto & item : constraint_row)
4542  if (item.first != *i && this->is_constrained_dof(item.first))
4543  {
4544  unexpanded_set.insert(item.first);
4545  constraints_to_expand.push_back(item.first);
4546  }
4547 
4548  for (const auto & expandable : constraints_to_expand)
4549  {
4550  const Real this_coef = constraint_row[expandable];
4551 
4552  DofConstraints::const_iterator
4553  subpos = dof_constraints_copy.find(expandable);
4554 
4555  libmesh_assert (subpos != dof_constraints_copy.end());
4556 
4557  const DofConstraintRow & subconstraint_row = subpos->second;
4558 
4559  for (const auto & item : subconstraint_row)
4560  {
4561  libmesh_error_msg_if(item.first == expandable, "Constraint loop detected");
4562 
4563  constraint_row[item.first] += item.second * this_coef;
4564  }
4565 
4566  // Comment out "rhs" parts of this method copied from process_constraints
4567  // DofConstraintValueMap::const_iterator subrhsit =
4568  // _primal_constraint_values.find(expandable);
4569  // if (subrhsit != _primal_constraint_values.end())
4570  // constraint_rhs += subrhsit->second * this_coef;
4571 
4572  constraint_row.erase(expandable);
4573  }
4574 
4575  // Comment out "rhs" parts of this method copied from process_constraints
4576  // if (rhsit == _primal_constraint_values.end())
4577  // {
4578  // if (constraint_rhs != Number(0))
4579  // _primal_constraint_values[*i] = constraint_rhs;
4580  // else
4581  // _primal_constraint_values.erase(*i);
4582  // }
4583  // else
4584  // {
4585  // if (constraint_rhs != Number(0))
4586  // rhsit->second = constraint_rhs;
4587  // else
4588  // _primal_constraint_values.erase(rhsit);
4589  // }
4590 
4591  if (constraints_to_expand.empty())
4592  i = unexpanded_set.erase(i);
4593  else
4594  ++i;
4595  }
4596 }
libmesh_assert(ctx)
DofConstraints _dof_constraints
Data structure containing DOF constraints.
Definition: dof_map.h:2272
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:100
The constraint matrix storage format.
Definition: dof_map.h:108

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

References check_for_constraint_loops().

4503 {
4504  // Eventually make this officially libmesh_deprecated();
4506 }

◆ clear()

void libMesh::DofMap::clear ( )
overridevirtual

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

Reimplemented from libMesh::DofMapBase.

Definition at line 867 of file dof_map.C.

References _adjoint_constraint_values, _algebraic_ghosting_functors, _array_variables, _coupling_functors, _default_coupling, _default_evaluating, _dof_constraints, _dof_coupling, libMesh::DofMapBase::_end_old_df, libMesh::DofMapBase::_first_old_df, _first_old_scalar_df, _first_scalar_df, _matrices, _mesh, libMesh::DofMapBase::_n_old_dfs, _primal_constraint_values, _sc, _shared_functors, _stashed_dof_constraints, _var_to_vg, _variable_group_numbers, _variable_groups, _variables, add_algebraic_ghosting_functor(), add_coupling_functor(), libMesh::DofMapBase::clear(), 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().

868 {
870 
871  // we don't want to clear
872  // the coupling matrix!
873  // It should not change...
874  //_dof_coupling->clear();
875  //
876  // But it would be inconsistent to leave our coupling settings
877  // through a clear()...
878  _dof_coupling = nullptr;
879 
880  // Reset ghosting functor statuses
881  {
882  for (const auto & gf : _coupling_functors)
883  {
884  libmesh_assert(gf);
886  }
887  this->_coupling_functors.clear();
888 
889  // Go back to default coupling
890 
891  _default_coupling->set_dof_coupling(this->_dof_coupling);
892  _default_coupling->set_n_levels(this->use_coupled_neighbor_dofs(this->_mesh));
893 
895  }
896 
897 
898  {
899  for (const auto & gf : _algebraic_ghosting_functors)
900  {
901  libmesh_assert(gf);
903  }
904  this->_algebraic_ghosting_functors.clear();
905 
906  // Go back to default send_list generation
907 
908  // _default_evaluating->set_dof_coupling(this->_dof_coupling);
909  _default_evaluating->set_n_levels(1);
911  }
912 
913  this->_shared_functors.clear();
914 
915  _variables.clear();
916  _variable_groups.clear();
917  _var_to_vg.clear();
918  _variable_group_numbers.clear();
919  _array_variables.clear();
920  _first_scalar_df.clear();
921  this->clear_send_list();
922  this->clear_sparsity();
924 
925 #ifdef LIBMESH_ENABLE_AMR
926 
927  _dof_constraints.clear();
928  _stashed_dof_constraints.clear();
931  _n_old_dfs = 0;
932  _first_old_df.clear();
933  _end_old_df.clear();
934  _first_old_scalar_df.clear();
935 
936 #endif
937 
938  _matrices.clear();
939  if (_sc)
940  _sc->clear();
941 }
std::vector< VariableGroup > _variable_groups
The variable groups in this system/degree of freedom map.
Definition: dof_map.h:2094
virtual void clear()
Definition: dof_map_base.C:71
std::unique_ptr< StaticCondensationDofMap > _sc
Static condensation class.
Definition: dof_map.h:2331
void remove_ghosting_functor(GhostingFunctor &ghosting_functor)
Removes a functor which was previously added to the set of ghosting functors.
Definition: mesh_base.C:970
void clear_send_list()
Clears the _send_list vector.
Definition: dof_map.h:507
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:1899
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:2001
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:2146
AdjointDofConstraintValues _adjoint_constraint_values
Definition: dof_map.h:2276
bool need_full_sparsity_pattern
Default false; set to true if any attached matrix requires a full sparsity pattern.
Definition: dof_map.h:2238
std::unordered_map< unsigned int, unsigned int > _var_to_vg
A map from variable number to variable group number.
Definition: dof_map.h:2104
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:2259
libmesh_assert(ctx)
std::vector< GhostingFunctor * > _coupling_functors
The list of all GhostingFunctor objects to be used when coupling degrees of freedom in matrix sparsit...
Definition: dof_map.h:2226
DofConstraints _dof_constraints
Data structure containing DOF constraints.
Definition: dof_map.h:2272
CouplingMatrix * _dof_coupling
Degree of freedom coupling.
Definition: dof_map.h:1741
std::vector< std::pair< unsigned int, unsigned int > > _array_variables
Array variable information storage.
Definition: dof_map.h:2117
std::vector< SparseMatrix< Number > *> _matrices
Additional matrices handled by this object.
Definition: dof_map.h:2140
std::vector< GhostingFunctor * > _algebraic_ghosting_functors
The list of all GhostingFunctor objects to be used when distributing ghosted vectors.
Definition: dof_map.h:2213
std::unique_ptr< DefaultCoupling > _default_coupling
The default coupling GhostingFunctor, used to implement standard libMesh sparsity pattern constructio...
Definition: dof_map.h:2192
DofConstraintValueMap _primal_constraint_values
Definition: dof_map.h:2274
std::vector< Variable > _variables
The variables in this system/degree of freedom map.
Definition: dof_map.h:2089
DofConstraints _stashed_dof_constraints
Definition: dof_map.h:2272
std::vector< dof_id_type > _end_old_df
Last old DOF index (plus 1) on processor p.
Definition: dof_map_base.h:181
void clear_sparsity()
Clears the sparsity pattern.
Definition: dof_map.C:1977
MeshBase & _mesh
The mesh that system uses.
Definition: dof_map.h:2133
std::unique_ptr< DefaultCoupling > _default_evaluating
The default algebraic GhostingFunctor, used to implement standard libMesh send_list construction...
Definition: dof_map.h:2200
std::vector< unsigned int > _variable_group_numbers
The variable group number for each variable.
Definition: dof_map.h:2099
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:2232
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:2058
dof_id_type _n_old_dfs
Total number of degrees of freedom on old dof objects.
Definition: dof_map_base.h:171
std::vector< dof_id_type > _first_old_df
First old DOF index on processor p.
Definition: dof_map_base.h:176

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

References _send_list.

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

508  {
509  _send_list.clear();
510  }
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:2152

◆ clear_sparsity()

void libMesh::DofMap::clear_sparsity ( )

Clears the sparsity pattern.

Definition at line 1977 of file dof_map.C.

References _sp.

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

1978 {
1979  _sp.reset();
1980 }
std::unique_ptr< SparsityPattern::Build > _sp
The sparsity pattern of the global matrix.
Definition: dof_map.h:2245

◆ 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::PetscLinearSolver< Number >::_petsc_shell_matrix_get_diagonal(), libMesh::SlepcEigenSolver< libMesh::Number >::_petsc_shell_matrix_get_diagonal(), libMesh::PetscLinearSolver< Number >::_petsc_shell_matrix_mult(), libMesh::SlepcEigenSolver< libMesh::Number >::_petsc_shell_matrix_mult(), libMesh::PetscLinearSolver< Number >::_petsc_shell_matrix_mult_add(), libMesh::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::RBEIMEvaluation::add_interpolation_data(), libMesh::CondensedEigenSystem::add_matrices(), libMesh::EigenSystem::add_matrices(), libMesh::System::add_matrix(), libMesh::RBConstruction::add_scaled_matrix_and_vector(), add_variable(), 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::AdvectionSystem::assemble_claw_rhs(), 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::Partitioner::build_graph(), 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::CondensedEigenSystem::copy_super_to_sub(), 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< T >::create_submatrix_nosort(), create_wrapped_function(), libMesh::MeshCommunication::delete_remote_elements(), libMesh::RBEIMEvaluation::distribute_bfs(), 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::SmoothnessEstimator::estimate_smoothness(), 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::RBEIMEvaluation::get_interior_basis_functions_as_vecs(), 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::StaticCondensation::init(), libMesh::SystemSubsetBySubdomain::init(), libMesh::PetscDMWrapper::init_and_attach_petscdm(), libMesh::AdvectionSystem::init_data(), libMesh::ClawSystem::init_data(), libMesh::PetscDMWrapper::init_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_constraint_rows(), 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(), libMesh::MeshTools::n_connected_components(), n_constrained_dofs(), libMesh::MeshBase::n_constraint_rows(), n_dofs(), n_dofs_per_processor(), 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(), libMesh::MeshBase::print_constraint_rows(), 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(), MeshFunctionTest::read_variable_info_from_output_data(), libMesh::MeshBase::recalculate_n_partitions(), libMesh::MeshRefinement::refine_and_coarsen_elements(), libMesh::SimplexRefiner::refine_via_edges(), libMesh::StaticCondensationDofMap::reinit(), libMesh::BoundaryInfo::remove_edge_id(), libMesh::BoundaryInfo::remove_node_id(), libMesh::BoundaryInfo::remove_shellface_id(), libMesh::BoundaryInfo::remove_side_id(), 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::VariationalMeshSmoother::smooth(), libMesh::ClawSystem::solve_conservation_law(), 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(), VolumeTest::testC0PolygonMethods(), VolumeTest::testC0PolyhedronMethods(), ConstraintOperatorTest::testCoreform(), ConnectedComponentsTest::testEdge(), MeshInputTest::testExodusIGASidesets(), MeshTriangulationTest::testFoundCenters(), PointLocatorTest::testLocator(), BoundaryInfoTest::testMesh(), PointLocatorTest::testPlanar(), MeshTriangulationTest::testPoly2TriRefinementBase(), SystemsTest::testProjectCubeWithMeshFunction(), BoundaryInfoTest::testRenumber(), BoundaryInfoTest::testSelectiveRenumber(), CheckpointIOTest::testSplitter(), MeshInputTest::testTetgenIO(), MeshTriangulationTest::testTriangulatorInterp(), MeshTriangulationTest::testTriangulatorMeshedHoles(), MeshTriangulationTest::testTriangulatorRoundHole(), MeshSmootherTest::testVariationalSmoother(), 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(), update_current_local_solution(), 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::MeshTools::volume(), libMesh::STLIO::write(), 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_dof_info()

std::size_t libMesh::DofMapBase::compute_dof_info ( dof_id_type  n_local_dofs)
protectedinherited

compute the key degree of freedom information given the local number of degrees of freedom on this process

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

Referenced by distribute_dofs(), and libMesh::StaticCondensationDofMap::reinit().

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

1957 {
1959 
1960  // It is possible that some \p SparseMatrix implementations want to
1961  // see the sparsity pattern before we throw it away. If so, we
1962  // share a view of its arrays, and we pass it in to the matrices.
1963  for (const auto & mat : _matrices)
1964  {
1965  mat->attach_sparsity_pattern (*_sp);
1967  mat->update_sparsity_pattern (_sp->get_sparsity_pattern());
1968  }
1969  // If we don't need the full sparsity pattern anymore, free the
1970  // parts of it we don't need.
1972  _sp->clear_full_sparsity();
1973 }
std::unique_ptr< SparsityPattern::Build > _sp
The sparsity pattern of the global matrix.
Definition: dof_map.h:2245
std::unique_ptr< SparsityPattern::Build > build_sparsity(const MeshBase &mesh, bool calculate_constrained=false, bool use_condensed_system=false) const
Builds a sparsity pattern for matrices using the current degree-of-freedom numbering and coupling...
Definition: dof_map.C:63
MeshBase & mesh
bool _constrained_sparsity_construction
This flag indicates whether or not we explicitly take constraint equations into account when computin...
Definition: dof_map.h:2084
bool need_full_sparsity_pattern
Default false; set to true if any attached matrix requires a full sparsity pattern.
Definition: dof_map.h:2238
std::vector< SparseMatrix< Number > *> _matrices
Additional matrices handled by this object.
Definition: dof_map.h:2140

◆ computed_sparsity_already()

bool libMesh::DofMap::computed_sparsity_already ( ) const

Returns true iff a sparsity pattern has already been computed.

Definition at line 258 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().

259 {
261  (!_sp->get_n_nz().empty() ||
262  !_sp->get_n_oz().empty());
263  this->comm().max(computed_sparsity_already);
265 }
std::unique_ptr< SparsityPattern::Build > _sp
The sparsity pattern of the global matrix.
Definition: dof_map.h:2245
const Parallel::Communicator & comm() const
bool computed_sparsity_already() const
Returns true iff a sparsity pattern has already been computed.
Definition: dof_map.C:258
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 2509 of file dof_map.h.

Referenced by assemble().

2512  {}

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

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

2485  {}

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

2490  {}

◆ 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 2496 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_poisson(), assemble_shell(), assemble_stokes(), and LinearElasticityWithContact::residual_and_jacobian().

2499  {}

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

2765 {
2766  libmesh_assert_equal_to (elem_dofs.size(), rhs.size());
2767 
2768  libmesh_assert (solution_local.type() == SERIAL ||
2769  solution_local.type() == GHOSTED);
2770 
2771  // check for easy return
2772  if (this->_dof_constraints.empty())
2773  return;
2774 
2775  // The constrained RHS is built up as C^T F
2777 
2778  this->build_constraint_matrix (C, elem_dofs);
2779 
2780  LOG_SCOPE("cnstrn_elem_residual()", "DofMap");
2781 
2782  // It is possible that the matrix is not constrained at all.
2783  if (C.n() != elem_dofs.size())
2784  return;
2785 
2786  // Compute the matrix-vector product C^T F
2787  DenseVector<Number> old_rhs(rhs);
2788  C.vector_mult_transpose(rhs, old_rhs);
2789 
2790  for (unsigned int i=0,
2791  n_elem_dofs = cast_int<unsigned int>(elem_dofs.size());
2792  i != n_elem_dofs; i++)
2793  {
2794  const dof_id_type dof_id = elem_dofs[i];
2795 
2796  if (auto pos = _dof_constraints.find(dof_id);
2797  pos != _dof_constraints.end())
2798  {
2799  // This will put a nonsymmetric entry in the constraint
2800  // row to ensure that the linear system produces the
2801  // correct value for the constrained DOF.
2802  const DofConstraintRow & constraint_row = pos->second;
2803 
2804  Number & rhs_val = rhs(i);
2805  rhs_val = 0;
2806  for (const auto & [constraining_dof, coef] : constraint_row)
2807  rhs_val -= coef * solution_local(constraining_dof);
2808  rhs_val += solution_local(dof_id);
2809  }
2810  }
2811 }
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:2272
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:100
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 2492 of file dof_map.h.

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

2494  {}

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

2514 {}

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

5356 {
5357  // We're constraining dofs on elem which correspond to p refinement
5358  // levels above p - this only makes sense if elem's p refinement
5359  // level is above p.
5360  libmesh_assert_greater (elem->p_level(), p);
5361  libmesh_assert_less (s, elem->n_sides());
5362 
5363  const unsigned int sys_num = this->sys_number();
5364  FEType fe_type = this->variable_type(var);
5365 
5366  const unsigned int n_nodes = elem->n_nodes();
5367  for (unsigned int n = 0; n != n_nodes; ++n)
5368  if (elem->is_node_on_side(n, s))
5369  {
5370  const Node & node = elem->node_ref(n);
5371  const unsigned int low_nc =
5372  FEInterface::n_dofs_at_node (fe_type, p, elem, n);
5373  const unsigned int high_nc =
5374  FEInterface::n_dofs_at_node (fe_type, elem, n);
5375 
5376  // since we may be running this method concurrently
5377  // on multiple threads we need to acquire a lock
5378  // before modifying the _dof_constraints object.
5379  Threads::spin_mutex::scoped_lock lock(Threads::spin_mtx);
5380 
5381  if (elem->is_vertex(n))
5382  {
5383  // Add "this is zero" constraint rows for high p vertex
5384  // dofs
5385  for (unsigned int i = low_nc; i != high_nc; ++i)
5386  {
5387  _dof_constraints[node.dof_number(sys_num,var,i)].clear();
5388  _primal_constraint_values.erase(node.dof_number(sys_num,var,i));
5389  }
5390  }
5391  else
5392  {
5393  const unsigned int total_dofs = node.n_comp(sys_num, var);
5394  libmesh_assert_greater_equal (total_dofs, high_nc);
5395  // Add "this is zero" constraint rows for high p
5396  // non-vertex dofs, which are numbered in reverse
5397  for (unsigned int j = low_nc; j != high_nc; ++j)
5398  {
5399  const unsigned int i = total_dofs - j - 1;
5400  _dof_constraints[node.dof_number(sys_num,var,i)].clear();
5401  _primal_constraint_values.erase(node.dof_number(sys_num,var,i));
5402  }
5403  }
5404  }
5405 }
class FEType hides (possibly multiple) FEFamily and approximation orders, thereby enabling specialize...
Definition: fe_type.h:196
dof_id_type dof_number(const unsigned int s, const unsigned int var, const unsigned int comp) const
Definition: dof_object.h:1032
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:1002
virtual bool is_node_on_side(const unsigned int n, const unsigned int s) const =0
unsigned int p_level() const
Definition: elem.h:3109
unsigned int sys_number() const
Definition: dof_map.h:2338
const dof_id_type n_nodes
Definition: tecplot_io.C:67
const Node & node_ref(const unsigned int i) const
Definition: elem.h:2530
virtual unsigned int n_nodes() const =0
const FEType & variable_type(const unsigned int i) const
Definition: dof_map.h:2386
DofConstraints _dof_constraints
Data structure containing DOF constraints.
Definition: dof_map.h:2272
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:436
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:2274
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 2558 of file dof_map.h.

References _constrained_sparsity_construction.

2559 {
2560 #ifdef LIBMESH_ENABLE_CONSTRAINTS
2562 #else
2563  return true;
2564 #endif
2565 }
bool _constrained_sparsity_construction
This flag indicates whether or not we explicitly take constraint equations into account when computin...
Definition: dof_map.h:2084

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

References _dof_constraints.

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

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

References _dof_constraints.

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

◆ coupling_functors_begin()

GhostingFunctorIterator libMesh::DofMap::coupling_functors_begin ( ) const
inline

Beginning of range of coupling functors.

Definition at line 366 of file dof_map.h.

References _coupling_functors.

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

367  { return _coupling_functors.begin(); }
std::vector< GhostingFunctor * > _coupling_functors
The list of all GhostingFunctor objects to be used when coupling degrees of freedom in matrix sparsit...
Definition: dof_map.h:2226

◆ coupling_functors_end()

GhostingFunctorIterator libMesh::DofMap::coupling_functors_end ( ) const
inline

End of range of coupling functors.

Definition at line 372 of file dof_map.h.

References _coupling_functors.

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

373  { return _coupling_functors.end(); }
std::vector< GhostingFunctor * > _coupling_functors
The list of all GhostingFunctor objects to be used when coupling degrees of freedom in matrix sparsit...
Definition: dof_map.h:2226

◆ 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 1735 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(), libMesh::MeshBase::sub_point_locator(), and variable_number().

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

1736 {
1737  parallel_object_only();
1738 
1739  LOG_SCOPE("create_dof_constraints()", "DofMap");
1740 
1742 
1743  // The user might have set boundary conditions after the mesh was
1744  // prepared; we should double-check that those boundary conditions
1745  // are still consistent.
1746 #ifdef DEBUG
1748 #endif
1749 
1750  // In a distributed mesh we might have constraint rows on some
1751  // processors but not all; if we have constraint rows on *any*
1752  // processor then we need to process them.
1753  bool constraint_rows_empty = mesh.get_constraint_rows().empty();
1754  this->comm().min(constraint_rows_empty);
1755 
1756  // We might get constraint equations from AMR hanging nodes in
1757  // 2D/3D, or from spline constraint rows or boundary conditions in
1758  // any dimension
1759  const bool possible_local_constraints = false
1760  || !mesh.n_elem()
1761  || !constraint_rows_empty
1762 #ifdef LIBMESH_ENABLE_AMR
1763  || mesh.mesh_dimension() > 1
1764 #endif
1765 #ifdef LIBMESH_ENABLE_PERIODIC
1766  || !_periodic_boundaries->empty()
1767 #endif
1768 #ifdef LIBMESH_ENABLE_DIRICHLET
1769  || !_dirichlet_boundaries->empty()
1770 #endif
1771  ;
1772 
1773  // Even if we don't have constraints, another processor might.
1774  bool possible_global_constraints = possible_local_constraints;
1775 #if defined(LIBMESH_ENABLE_PERIODIC) || defined(LIBMESH_ENABLE_DIRICHLET) || defined(LIBMESH_ENABLE_AMR)
1776  libmesh_assert(this->comm().verify(mesh.is_serial()));
1777 
1778  this->comm().max(possible_global_constraints);
1779 #endif
1780 
1781  // Recalculate dof constraints from scratch. (Or just clear them,
1782  // if the user has just deleted their last dirichlet/periodic/user
1783  // constraint)
1784  // Note: any _stashed_dof_constraints are not cleared as it
1785  // may be the user's intention to restore them later.
1786 #ifdef LIBMESH_ENABLE_CONSTRAINTS
1787  _dof_constraints.clear();
1788  _primal_constraint_values.clear();
1790 #endif
1791 #ifdef LIBMESH_ENABLE_NODE_CONSTRAINTS
1792  _node_constraints.clear();
1793 #endif
1794 
1795  if (!possible_global_constraints)
1796  return;
1797 
1798  // Here we build the hanging node constraints. This is done
1799  // by enforcing the condition u_a = u_b along hanging sides.
1800  // u_a = u_b is collocated at the nodes of side a, which gives
1801  // one row of the constraint matrix.
1802 
1803  // Processors only compute their local constraints
1804  ConstElemRange range (mesh.local_elements_begin(),
1805  mesh.local_elements_end());
1806 
1807  // Global computation fails if we're using a FEMFunctionBase BC on a
1808  // ReplicatedMesh in parallel
1809  // ConstElemRange range (mesh.elements_begin(),
1810  // mesh.elements_end());
1811 
1812  // compute_periodic_constraints requires a point_locator() from our
1813  // Mesh, but point_locator() construction is parallel and threaded.
1814  // Rather than nest threads within threads we'll make sure it's
1815  // preconstructed.
1816 #ifdef LIBMESH_ENABLE_PERIODIC
1817  bool need_point_locator = !_periodic_boundaries->empty() && !range.empty();
1818 
1819  this->comm().max(need_point_locator);
1820 
1821  if (need_point_locator)
1823 #endif
1824 
1825 #ifdef LIBMESH_ENABLE_NODE_CONSTRAINTS
1826  Threads::parallel_for (range,
1827  ComputeNodeConstraints (_node_constraints,
1828 #ifdef LIBMESH_ENABLE_PERIODIC
1830 #endif
1831  mesh));
1832 #endif // LIBMESH_ENABLE_NODE_CONSTRAINTS
1833 
1834 
1835  // Look at all the variables in the system. Reset the element
1836  // range at each iteration -- there is no need to reconstruct it.
1837  const auto n_vars = this->n_variables();
1838  for (unsigned int variable_number=0; variable_number<n_vars;
1839  ++variable_number, range.reset())
1840  Threads::parallel_for (range,
1841  ComputeConstraints (_dof_constraints,
1842  *this,
1843 #ifdef LIBMESH_ENABLE_PERIODIC
1845 #endif
1846  mesh,
1847  variable_number));
1848 
1849 #ifdef LIBMESH_ENABLE_DIRICHLET
1850 
1851  if (!_dirichlet_boundaries->empty())
1852  {
1853  // Sanity check that the boundary ids associated with the
1854  // DirichletBoundary objects are actually present in the
1855  // mesh. We do this check by default, but in cases where you
1856  // intentionally add "inconsistent but valid" DirichletBoundary
1857  // objects in parallel, this check can deadlock since it does a
1858  // collective communication internally. In that case it is
1859  // possible to disable this check by setting the flag to false.
1861  for (const auto & dirichlet : *_dirichlet_boundaries)
1862  this->check_dirichlet_bcid_consistency(mesh, *dirichlet);
1863 
1864  // Threaded loop over local over elems applying all Dirichlet BCs
1866  (range,
1867  ConstrainDirichlet(*this, mesh, time, *_dirichlet_boundaries,
1868  AddPrimalConstraint(*this)));
1869 
1870  // Threaded loop over local over elems per QOI applying all adjoint
1871  // Dirichlet BCs. Note that the ConstElemRange is reset before each
1872  // execution of Threads::parallel_for().
1873 
1874  for (auto qoi_index : index_range(_adjoint_dirichlet_boundaries))
1875  {
1876  const DirichletBoundaries & adb_q =
1877  *(_adjoint_dirichlet_boundaries[qoi_index]);
1878 
1879  if (!adb_q.empty())
1881  (range.reset(),
1882  ConstrainDirichlet(*this, mesh, time, adb_q,
1883  AddAdjointConstraint(*this, qoi_index)));
1884  }
1885  }
1886 
1887 #endif // LIBMESH_ENABLE_DIRICHLET
1888 
1889  // Handle spline node constraints last, so we can try to move
1890  // existing constraints onto the spline basis if necessary.
1891  if (!constraint_rows_empty)
1892  this->process_mesh_constraint_rows(mesh);
1893 }
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:198
constraint_rows_type & get_constraint_rows()
Constraint rows accessors.
Definition: mesh_base.h:1709
std::unique_ptr< PointLocatorBase > sub_point_locator() const
Definition: mesh_base.C:1675
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
std::unique_ptr< DirichletBoundaries > _dirichlet_boundaries
Data structure containing Dirichlet functions.
Definition: dof_map.h:2300
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:2276
virtual bool is_serial() const
Definition: mesh_base.h:211
void min(const T &r, T &o, Request &req) const
unsigned int n_variables() const override
Definition: dof_map.h:736
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:1715
DofConstraints _dof_constraints
Data structure containing DOF constraints.
Definition: dof_map.h:2272
unsigned int n_vars() const
Definition: dof_map.h:2926
std::vector< std::unique_ptr< DirichletBoundaries > > _adjoint_dirichlet_boundaries
Data structure containing Dirichlet functions.
Definition: dof_map.h:2306
std::unique_ptr< PeriodicBoundaries > _periodic_boundaries
Data structure containing periodic boundaries.
Definition: dof_map.h:2292
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:2328
DofConstraintValueMap _primal_constraint_values
Definition: dof_map.h:2274
unsigned int mesh_dimension() const
Definition: mesh_base.C:372
unsigned int variable_number(std::string_view var) const
Definition: dof_map.h:2980
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:117
NodeConstraints _node_constraints
Data structure containing DofObject constraints.
Definition: dof_map.h:2283

◆ create_static_condensation()

void libMesh::DofMap::create_static_condensation ( MeshBase mesh,
System system 
)

Add a static condensation class.

Definition at line 3131 of file dof_map.C.

References _sc, and mesh.

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

3132 {
3133  _sc = std::make_unique<StaticCondensationDofMap>(mesh, sys, *this);
3134 }
std::unique_ptr< StaticCondensationDofMap > _sc
Static condensation class.
Definition: dof_map.h:2331
MeshBase & mesh

◆ default_algebraic_ghosting()

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

Default algebraic ghosting functor.

Definition at line 440 of file dof_map.h.

References _default_evaluating.

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

440 { 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:2200

◆ default_coupling()

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

Default coupling functor.

Definition at line 378 of file dof_map.h.

References _default_coupling.

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

378 { 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:2192

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

References _algebraic_ghosting_functors, _coupling_functors, libMesh::DofMapBase::_end_df, libMesh::DofMapBase::_first_df, _first_old_scalar_df, _first_scalar_df, add_neighbors_to_send_list(), calculate_constraining_subdomains(), clear_send_list(), libMesh::DofMapBase::compute_dof_info(), distribute_local_dofs_node_major(), distribute_local_dofs_var_major(), libMesh::DofObject::dof_number(), elem_ptr(), libMesh::DofMapBase::end_dof(), libMesh::DofMapBase::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(), libMesh::DofMapBase::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_petscdm(), libMesh::EquationSystems::reinit_solutions(), SystemsTest::testProjectMatrix1D(), SystemsTest::testProjectMatrix2D(), and SystemsTest::testProjectMatrix3D().

946 {
947  // This function must be run on all processors at once
948  parallel_object_only();
949 
950  // Log how long it takes to distribute the degrees of freedom
951  LOG_SCOPE("distribute_dofs()", "DofMap");
952 
953  libmesh_assert (mesh.is_prepared());
954 
955  const processor_id_type proc_id = this->processor_id();
956 #ifndef NDEBUG
957  const processor_id_type n_proc = this->n_processors();
958 #endif
959 
960  // libmesh_assert_greater (this->n_variables(), 0);
961  libmesh_assert_less (proc_id, n_proc);
962 
963  // Data structure to ensure we can correctly combine
964  // subdomain-restricted variables with constraining nodes from
965  // different subdomains
966  const std::map<const Node *, std::set<subdomain_id_type>>
967  constraining_subdomains =
969 
970  // re-init in case the mesh has changed
971  this->reinit(mesh,
972  constraining_subdomains);
973 
974  // By default distribute variables in a
975  // var-major fashion, but allow run-time
976  // specification
977  bool node_major_dofs = libMesh::on_command_line ("--node-major-dofs");
978 
979  // The DOF counter, will be incremented as we encounter
980  // new degrees of freedom
981  dof_id_type next_free_dof = 0;
982 
983  // Clear the send list before we rebuild it
984  this->clear_send_list();
985 
986  // Set temporary DOF indices on this processor
987  if (node_major_dofs)
989  (next_free_dof, mesh, constraining_subdomains);
990  else
992  (next_free_dof, mesh, constraining_subdomains);
993 
994  // Get DOF counts on all processors
995  const auto n_dofs = this->compute_dof_info(next_free_dof);
996 
997  // Clear all the current DOF indices
998  // (distribute_dofs expects them cleared!)
999  this->invalidate_dofs(mesh);
1000 
1001  next_free_dof = _first_df[proc_id];
1002 
1003  // Set permanent DOF indices on this processor
1004  if (node_major_dofs)
1006  (next_free_dof, mesh, constraining_subdomains);
1007  else
1009  (next_free_dof, mesh, constraining_subdomains);
1010 
1011  libmesh_assert_equal_to (next_free_dof, _end_df[proc_id]);
1012 
1013  //------------------------------------------------------------
1014  // At this point, all n_comp and dof_number values on local
1015  // DofObjects should be correct, but a DistributedMesh might have
1016  // incorrect values on non-local DofObjects. Let's request the
1017  // correct values from each other processor.
1018 
1019  if (this->n_processors() > 1)
1020  {
1021  this->set_nonlocal_dof_objects(mesh.nodes_begin(),
1022  mesh.nodes_end(),
1024 
1025  this->set_nonlocal_dof_objects(mesh.elements_begin(),
1026  mesh.elements_end(),
1028  }
1029 
1030 #ifdef DEBUG
1031  {
1032  const unsigned int
1033  sys_num = this->sys_number();
1034 
1035  // Processors should all agree on DoF ids for the newly numbered
1036  // system.
1038 
1039  // DoF processor ids should match DofObject processor ids
1040  for (auto & node : mesh.node_ptr_range())
1041  {
1042  DofObject const * const dofobj = node;
1043  const processor_id_type obj_proc_id = dofobj->processor_id();
1044 
1045  for (auto v : make_range(dofobj->n_vars(sys_num)))
1046  for (auto c : make_range(dofobj->n_comp(sys_num,v)))
1047  {
1048  const dof_id_type dofid = dofobj->dof_number(sys_num,v,c);
1049  libmesh_assert_greater_equal (dofid, this->first_dof(obj_proc_id));
1050  libmesh_assert_less (dofid, this->end_dof(obj_proc_id));
1051  }
1052  }
1053 
1054  for (auto & elem : mesh.element_ptr_range())
1055  {
1056  DofObject const * const dofobj = elem;
1057  const processor_id_type obj_proc_id = dofobj->processor_id();
1058 
1059  for (auto v : make_range(dofobj->n_vars(sys_num)))
1060  for (auto c : make_range(dofobj->n_comp(sys_num,v)))
1061  {
1062  const dof_id_type dofid = dofobj->dof_number(sys_num,v,c);
1063  libmesh_assert_greater_equal (dofid, this->first_dof(obj_proc_id));
1064  libmesh_assert_less (dofid, this->end_dof(obj_proc_id));
1065  }
1066  }
1067  }
1068 #endif
1069 
1070  // start finding SCALAR degrees of freedom
1071 #ifdef LIBMESH_ENABLE_AMR
1073 #endif
1074  _first_scalar_df.clear();
1076  dof_id_type current_SCALAR_dof_index = n_dofs - n_SCALAR_dofs();
1077 
1078  // Calculate and cache the initial DoF indices for SCALAR variables.
1079  // This is an O(N_vars) calculation so we want to do it once per
1080  // renumbering rather than once per SCALAR_dof_indices() call
1081 
1082  for (auto v : make_range(this->n_variables()))
1083  if (this->variable(v).type().family == SCALAR)
1084  {
1085  _first_scalar_df[v] = current_SCALAR_dof_index;
1086  current_SCALAR_dof_index += this->variable(v).type().order.get_order();
1087  }
1088 
1089  // Allow our GhostingFunctor objects to reinit if necessary
1090  for (const auto & gf : _algebraic_ghosting_functors)
1091  {
1092  libmesh_assert(gf);
1093  gf->dofmap_reinit();
1094  }
1095 
1096  for (const auto & gf : _coupling_functors)
1097  {
1098  libmesh_assert(gf);
1099  gf->dofmap_reinit();
1100  }
1101 
1102  // Note that in the add_neighbors_to_send_list nodes on processor
1103  // boundaries that are shared by multiple elements are added for
1104  // each element.
1106 
1107  // Here we used to clean up that data structure; now System and
1108  // EquationSystems call that for us, after we've added constraint
1109  // dependencies to the send_list too.
1110  // this->sort_send_list ();
1111 
1112  return n_dofs;
1113 }
dof_id_type n_SCALAR_dofs() const
Definition: dof_map.h:786
void reinit(MeshBase &mesh, const std::map< const Node *, std::set< subdomain_id_type >> &constraining_subdomains)
Reinitialize the underlying data structures conformal to the current mesh.
Definition: dof_map.C:469
dof_id_type n_dofs() const
Definition: dof_map_base.h:105
std::vector< dof_id_type > _first_df
First DOF index on processor p.
Definition: dof_map_base.h:154
void clear_send_list()
Clears the _send_list vector.
Definition: dof_map.h:507
MeshBase & mesh
OrderWrapper order
The approximation order of the element.
Definition: fe_type.h:215
unsigned int sys_number() const
Definition: dof_map.h:2338
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:2146
const Variable & variable(const unsigned int c) const override
Definition: dof_map.h:2356
dof_id_type end_dof() const
Definition: dof_map_base.h:83
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:1885
void distribute_local_dofs_var_major(dof_id_type &next_free_dof, MeshBase &mesh, const std::map< const Node *, std::set< subdomain_id_type >> &constraining_subdomains)
Distributes the global degrees of freedom, for dofs on this processor.
Definition: dof_map.C:1414
uint8_t processor_id_type
processor_id_type n_processors() const
dof_id_type first_dof() const
Definition: dof_map_base.h:73
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:1683
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:2259
void set_nonlocal_dof_objects(iterator_type objects_begin, iterator_type objects_end, MeshBase &mesh, dofobject_accessor objects)
Helper function for distributing dofs in parallel.
Definition: dof_map.C:318
static constexpr dof_id_type invalid_id
An invalid id to distinguish an uninitialized DofObject.
Definition: dof_object.h:482
unsigned int n_variables() const override
Definition: dof_map.h:736
libmesh_assert(ctx)
std::vector< GhostingFunctor * > _coupling_functors
The list of all GhostingFunctor objects to be used when coupling degrees of freedom in matrix sparsit...
Definition: dof_map.h:2226
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:310
std::vector< GhostingFunctor * > _algebraic_ghosting_functors
The list of all GhostingFunctor objects to be used when distributing ghosted vectors.
Definition: dof_map.h:2213
void invalidate_dofs(MeshBase &mesh) const
Invalidates all active DofObject dofs for this system.
Definition: dof_map.C:852
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:140
std::size_t compute_dof_info(dof_id_type n_local_dofs)
compute the key degree of freedom information given the local number of degrees of freedom on this pr...
DofObject * node_ptr(MeshBase &mesh, dof_id_type i) const
Definition: dof_map.C:303
bool on_command_line(std::string arg)
Definition: libmesh.C:1058
processor_id_type processor_id() const
std::map< const Node *, std::set< subdomain_id_type > > calculate_constraining_subdomains()
We may have mesh constraint rows with dependent nodes in one subdomain but dependency nodes in anothe...
Definition: dof_map.C:1252
void distribute_local_dofs_node_major(dof_id_type &next_free_dof, MeshBase &mesh, const std::map< const Node *, std::set< subdomain_id_type >> &constraining_subdomains)
Distributes the global degrees of freedom for dofs on this processor.
Definition: dof_map.C:1286
uint8_t dof_id_type
Definition: id_types.h:67
std::vector< dof_id_type > _end_df
Last DOF index (plus 1) on processor p.
Definition: dof_map_base.h:159
const FEType & type() const
Definition: variable.h:144

◆ distribute_local_dofs_node_major()

void libMesh::DofMap::distribute_local_dofs_node_major ( dof_id_type next_free_dof,
MeshBase mesh,
const std::map< const Node *, std::set< subdomain_id_type >> &  constraining_subdomains 
)
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.

Uses the provided constraining_subdomains map from calculate_constraining_subdomains() to ensure allocation of all DoFs on constraining nodes.

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

References libMesh::Variable::active_on_subdomain(), libMesh::FEType::family, libMesh::DofObject::invalid_id, mesh, libMesh::DofObject::n_comp_group(), n_nodes, libMesh::VariableGroup::n_variables(), libMesh::DofObject::processor_id(), libMesh::SCALAR, libMesh::DofObject::set_vg_dof_base(), libMesh::Variable::type(), and libMesh::DofObject::vg_dof_base().

Referenced by distribute_dofs().

1290 {
1291  const unsigned int sys_num = this->sys_number();
1292  const unsigned int n_var_groups = this->n_variable_groups();
1293 
1294  // This is the common case and we want to optimize for it
1295  const bool constraining_subdomains_empty =
1296  constraining_subdomains.empty();
1297 
1298  // Our numbering here must be kept consistent with the numbering
1299  // scheme assumed by DofMap::local_variable_indices!
1300 
1301  //-------------------------------------------------------------------------
1302  // First count and assign temporary numbers to local dofs
1303  for (auto & elem : mesh.active_local_element_ptr_range())
1304  {
1305  // Only number dofs connected to active
1306  // elements on this processor.
1307  const unsigned int n_nodes = elem->n_nodes();
1308 
1309  const subdomain_id_type sbdid = elem->subdomain_id();
1310 
1311  // First number the nodal DOFS
1312  for (unsigned int n=0; n<n_nodes; n++)
1313  {
1314  Node & node = elem->node_ref(n);
1315 
1316  for (unsigned vg=0; vg<n_var_groups; vg++)
1317  {
1318  const VariableGroup & vg_description(this->variable_group(vg));
1319 
1320  if (vg_description.type().family == SCALAR)
1321  continue;
1322 
1323  bool active_on_node =
1324  vg_description.active_on_subdomain(sbdid);
1325 
1326  // Are we at least active indirectly here?
1327  if (!active_on_node && !constraining_subdomains_empty)
1328  if (auto it = constraining_subdomains.find(&node);
1329  it != constraining_subdomains.end())
1330  for (auto s : it->second)
1331  if (vg_description.active_on_subdomain(s))
1332  {
1333  active_on_node = true;
1334  break;
1335  }
1336 
1337  if (active_on_node)
1338  {
1339  // assign dof numbers (all at once) if this is
1340  // our node and if they aren't already there
1341  if ((node.n_comp_group(sys_num,vg) > 0) &&
1342  (node.processor_id() == this->processor_id()) &&
1343  (node.vg_dof_base(sys_num,vg) ==
1345  {
1346  node.set_vg_dof_base(sys_num, vg,
1347  next_free_dof);
1348  next_free_dof += (vg_description.n_variables()*
1349  node.n_comp_group(sys_num,vg));
1350  //node.debug_buffer();
1351  }
1352  }
1353  }
1354  }
1355 
1356  // Now number the element DOFS
1357  for (unsigned vg=0; vg<n_var_groups; vg++)
1358  {
1359  const VariableGroup & vg_description(this->variable_group(vg));
1360 
1361  if ((vg_description.type().family != SCALAR) &&
1362  (vg_description.active_on_subdomain(elem->subdomain_id())))
1363  if (elem->n_comp_group(sys_num,vg) > 0)
1364  {
1365  libmesh_assert_equal_to (elem->vg_dof_base(sys_num,vg),
1367 
1368  elem->set_vg_dof_base(sys_num,
1369  vg,
1370  next_free_dof);
1371 
1372  next_free_dof += (vg_description.n_variables()*
1373  elem->n_comp_group(sys_num,vg));
1374  }
1375  }
1376  } // done looping over elements
1377 
1378 
1379  // we may have missed assigning DOFs to nodes that we own
1380  // but to which we have no connected elements matching our
1381  // variable restriction criterion. this will happen, for example,
1382  // if variable V is restricted to subdomain S. We may not own
1383  // any elements which live in S, but we may own nodes which are
1384  // *connected* to elements which do. in this scenario these nodes
1385  // will presently have unnumbered DOFs. we need to take care of
1386  // them here since we own them and no other processor will touch them.
1387  for (auto & node : mesh.local_node_ptr_range())
1388  for (unsigned vg=0; vg<n_var_groups; vg++)
1389  {
1390  const VariableGroup & vg_description(this->variable_group(vg));
1391 
1392  if (node->n_comp_group(sys_num,vg))
1393  if (node->vg_dof_base(sys_num,vg) == DofObject::invalid_id)
1394  {
1395  node->set_vg_dof_base (sys_num,
1396  vg,
1397  next_free_dof);
1398 
1399  next_free_dof += (vg_description.n_variables()*
1400  node->n_comp(sys_num,vg));
1401  }
1402  }
1403 
1404  this->distribute_scalar_dofs(next_free_dof);
1405 
1406 #ifdef DEBUG
1408 #endif // DEBUG
1409 }
unsigned int n_variable_groups() const
Definition: dof_map.h:733
TestClass subdomain_id_type
Based on the 4-byte comment warning above, this probably doesn&#39;t work with exodusII at all...
Definition: id_types.h:43
MeshBase & mesh
unsigned int sys_number() const
Definition: dof_map.h:2338
const dof_id_type n_nodes
Definition: tecplot_io.C:67
void assert_no_nodes_missed(MeshBase &mesh)
Definition: dof_map.C:1559
static constexpr dof_id_type invalid_id
An invalid id to distinguish an uninitialized DofObject.
Definition: dof_object.h:482
const VariableGroup & variable_group(const unsigned int c) const
Definition: dof_map.h:2346
void distribute_scalar_dofs(dof_id_type &next_free_dof)
Definition: dof_map.C:1535
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,
const std::map< const Node *, std::set< subdomain_id_type >> &  constraining_subdomains 
)
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.

Uses the provided constraining_subdomains map from calculate_constraining_subdomains() to ensure allocation of all DoFs on constraining nodes.

Definition at line 1414 of file dof_map.C.

References libMesh::Variable::active_on_subdomain(), libMesh::FEType::family, libMesh::DofObject::invalid_id, mesh, libMesh::DofObject::n_comp_group(), n_nodes, libMesh::VariableGroup::n_variables(), libMesh::DofObject::processor_id(), libMesh::SCALAR, libMesh::DofObject::set_vg_dof_base(), libMesh::Variable::type(), and libMesh::DofObject::vg_dof_base().

Referenced by distribute_dofs().

1418 {
1419  const unsigned int sys_num = this->sys_number();
1420  const unsigned int n_var_groups = this->n_variable_groups();
1421 
1422  // This is the common case and we want to optimize for it
1423  const bool constraining_subdomains_empty =
1424  constraining_subdomains.empty();
1425 
1426  // Our numbering here must be kept consistent with the numbering
1427  // scheme assumed by DofMap::local_variable_indices!
1428 
1429  //-------------------------------------------------------------------------
1430  // First count and assign temporary numbers to local dofs
1431  for (unsigned vg=0; vg<n_var_groups; vg++)
1432  {
1433  const VariableGroup & vg_description(this->variable_group(vg));
1434 
1435  const unsigned int n_vars_in_group = vg_description.n_variables();
1436 
1437  // Skip the SCALAR dofs
1438  if (vg_description.type().family == SCALAR)
1439  continue;
1440 
1441  for (auto & elem : mesh.active_local_element_ptr_range())
1442  {
1443  // Only number dofs connected to active elements on this
1444  // processor and only for variables which are active on on
1445  // this element's subdomain or which are active on the
1446  // subdomain of a node constrained by this node.
1447  const bool active_on_elem =
1448  vg_description.active_on_subdomain(elem->subdomain_id());
1449 
1450  // If there's no way we're active on this element then we're
1451  // done
1452  if (!active_on_elem && constraining_subdomains_empty)
1453  continue;
1454 
1455  const unsigned int n_nodes = elem->n_nodes();
1456 
1457  // First number the nodal DOFS
1458  for (unsigned int n=0; n<n_nodes; n++)
1459  {
1460  Node & node = elem->node_ref(n);
1461 
1462  bool active_on_node = active_on_elem;
1463  if (!active_on_node)
1464  if (auto it = constraining_subdomains.find(&node);
1465  it != constraining_subdomains.end())
1466  for (auto s : it->second)
1467  if (vg_description.active_on_subdomain(s))
1468  {
1469  active_on_node = true;
1470  break;
1471  }
1472 
1473  if (!active_on_node)
1474  continue;
1475 
1476  // assign dof numbers (all at once) if this is
1477  // our node and if they aren't already there
1478  if ((node.n_comp_group(sys_num,vg) > 0) &&
1479  (node.processor_id() == this->processor_id()) &&
1480  (node.vg_dof_base(sys_num,vg) ==
1482  {
1483  node.set_vg_dof_base(sys_num, vg, next_free_dof);
1484 
1485  next_free_dof += (n_vars_in_group*
1486  node.n_comp_group(sys_num,vg));
1487  }
1488  }
1489 
1490  // Now number the element DOFS
1491  if (elem->n_comp_group(sys_num,vg) > 0)
1492  {
1493  libmesh_assert_equal_to (elem->vg_dof_base(sys_num,vg),
1495 
1496  elem->set_vg_dof_base(sys_num,
1497  vg,
1498  next_free_dof);
1499 
1500  next_free_dof += (n_vars_in_group*
1501  elem->n_comp_group(sys_num,vg));
1502  }
1503  } // end loop on elements
1504 
1505  // we may have missed assigning DOFs to nodes that we own
1506  // but to which we have no connected elements matching our
1507  // variable restriction criterion. this will happen, for example,
1508  // if variable V is restricted to subdomain S. We may not own
1509  // any elements which live in S, but we may own nodes which are
1510  // *connected* to elements which do. in this scenario these nodes
1511  // will presently have unnumbered DOFs. we need to take care of
1512  // them here since we own them and no other processor will touch them.
1513  for (auto & node : mesh.local_node_ptr_range())
1514  if (node->n_comp_group(sys_num,vg))
1515  if (node->vg_dof_base(sys_num,vg) == DofObject::invalid_id)
1516  {
1517  node->set_vg_dof_base (sys_num,
1518  vg,
1519  next_free_dof);
1520 
1521  next_free_dof += (n_vars_in_group*
1522  node->n_comp_group(sys_num,vg));
1523  }
1524  } // end loop on variable groups
1525 
1526  this->distribute_scalar_dofs(next_free_dof);
1527 
1528 #ifdef DEBUG
1530 #endif
1531 }
unsigned int n_variable_groups() const
Definition: dof_map.h:733
MeshBase & mesh
unsigned int sys_number() const
Definition: dof_map.h:2338
const dof_id_type n_nodes
Definition: tecplot_io.C:67
void assert_no_nodes_missed(MeshBase &mesh)
Definition: dof_map.C:1559
static constexpr dof_id_type invalid_id
An invalid id to distinguish an uninitialized DofObject.
Definition: dof_object.h:482
const VariableGroup & variable_group(const unsigned int c) const
Definition: dof_map.h:2346
void distribute_scalar_dofs(dof_id_type &next_free_dof)
Definition: dof_map.C:1535
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 1535 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().

1536 {
1537  this->_n_SCALAR_dofs = 0;
1538  for (auto vg : make_range(this->n_variable_groups()))
1539  {
1540  const VariableGroup & vg_description(this->variable_group(vg));
1541 
1542  if (vg_description.type().family == SCALAR)
1543  {
1544  this->_n_SCALAR_dofs += (vg_description.n_variables()*
1545  vg_description.type().order.get_order());
1546  continue;
1547  }
1548  }
1549 
1550  // Only increment next_free_dof if we're on the processor
1551  // that holds this SCALAR variable
1552  if (this->processor_id() == (this->n_processors()-1))
1553  next_free_dof += _n_SCALAR_dofs;
1554 }
unsigned int n_variable_groups() const
Definition: dof_map.h:733
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:2251
const VariableGroup & variable_group(const unsigned int c) const
Definition: dof_map.h:2346
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:140
processor_id_type processor_id() const

◆ dof_indices() [1/6]

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

Definition at line 2197 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(), array_dof_indices(), assemble(), LinearElasticity::assemble(), AssembleOptimization::assemble_A_and_F(), libMesh::ClawSystem::assemble_advection_matrices(), libMesh::ClawSystem::assemble_avg_coupling_matrices(), libMesh::ClawSystem::assemble_boundary_condition_matrices(), assemble_cd(), assemble_elasticity(), libMesh::ClawSystem::assemble_jump_coupling_matrix(), assemble_mass(), libMesh::ClawSystem::assemble_mass_matrix(), assemble_matrices(), assemble_poisson(), 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(), libMesh::HDGProblem::jacobian(), LargeDeformationElasticity::jacobian(), libMesh::System::local_dof_indices(), max_constraint_error(), LinearElasticityWithContact::move_mesh(), libMesh::DGFEMContext::neighbor_side_fe_reinit(), libMesh::WeightedPatchRecoveryErrorEstimator::EstimateError::operator()(), libMesh::SmoothnessEstimator::EstimateSmoothness::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(), libMesh::StaticCondensationDofMap::reinit(), libMesh::HDGProblem::residual(), 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(), NonManifoldGhostingFunctorTest::verify_send_list_entries_helper(), libMesh::Nemesis_IO_Helper::write_nodal_solution(), libMesh::EnsightIO::write_scalar_ascii(), and libMesh::EnsightIO::write_vector_ascii().

2199 {
2200  // We now allow elem==nullptr to request just SCALAR dofs
2201  // libmesh_assert(elem);
2202 
2203  // If we are asking for current indices on an element, it ought to
2204  // be an active element (or a temporary side, which also thinks it's
2205  // active)
2206  libmesh_assert(!elem || elem->active());
2207 
2208  // dof_indices() is a relatively light-weight function that is
2209  // called millions of times in normal codes. Therefore, it is not a
2210  // good candidate for logging, since the cost of the logging code
2211  // itself is roughly on par with the time required to call
2212  // dof_indices().
2213  // LOG_SCOPE("dof_indices()", "DofMap");
2214 
2215  // Clear the DOF indices vector
2216  di.clear();
2217 
2218  const unsigned int n_var_groups = this->n_variable_groups();
2219 
2220 #ifdef DEBUG
2221  // Check that sizes match in DEBUG mode
2222  std::size_t tot_size = 0;
2223 #endif
2224 
2225  if (elem && elem->type() == TRI3SUBDIVISION)
2226  {
2227  // Subdivision surface FE require the 1-ring around elem
2228  const Tri3Subdivision * sd_elem = static_cast<const Tri3Subdivision *>(elem);
2229 
2230  // Ghost subdivision elements have no real dofs
2231  if (!sd_elem->is_ghost())
2232  {
2233  // Determine the nodes contributing to element elem
2234  std::vector<const Node *> elem_nodes;
2235  MeshTools::Subdivision::find_one_ring(sd_elem, elem_nodes);
2236 
2237  // Get the dof numbers
2238  for (unsigned int vg=0; vg<n_var_groups; vg++)
2239  {
2240  const VariableGroup & var = this->variable_group(vg);
2241  const unsigned int vars_in_group = var.n_variables();
2242 
2243  if (var.type().family == SCALAR &&
2244  var.active_on_subdomain(elem->subdomain_id()))
2245  {
2246  for (unsigned int vig=0; vig != vars_in_group; ++vig)
2247  {
2248 #ifdef DEBUG
2249  tot_size += var.type().order;
2250 #endif
2251  std::vector<dof_id_type> di_new;
2252  this->SCALAR_dof_indices(di_new,var.number(vig));
2253  di.insert( di.end(), di_new.begin(), di_new.end());
2254  }
2255  }
2256  else
2257  for (unsigned int vig=0; vig != vars_in_group; ++vig)
2258  {
2259  _dof_indices(*elem, elem->p_level(), di, vg, vig,
2260  elem_nodes.data(),
2261  cast_int<unsigned int>(elem_nodes.size()),
2262  var.number(vig)
2263 #ifdef DEBUG
2264  , tot_size
2265 #endif
2266  );
2267  }
2268  }
2269  }
2270 
2271  return;
2272  }
2273 
2274  // Get the dof numbers for each variable
2275  const unsigned int n_nodes = elem ? elem->n_nodes() : 0;
2276  for (unsigned int vg=0; vg<n_var_groups; vg++)
2277  {
2278  const VariableGroup & var = this->variable_group(vg);
2279  const unsigned int vars_in_group = var.n_variables();
2280 
2281  if (var.type().family == SCALAR &&
2282  (!elem ||
2283  var.active_on_subdomain(elem->subdomain_id())))
2284  {
2285  for (unsigned int vig=0; vig != vars_in_group; ++vig)
2286  {
2287 #ifdef DEBUG
2288  tot_size += var.type().order;
2289 #endif
2290  std::vector<dof_id_type> di_new;
2291  this->SCALAR_dof_indices(di_new,var.number(vig));
2292  di.insert( di.end(), di_new.begin(), di_new.end());
2293  }
2294  }
2295  else if (elem)
2296  for (unsigned int vig=0; vig != vars_in_group; ++vig)
2297  {
2298  _dof_indices(*elem, elem->p_level(), di, vg, vig,
2299  elem->get_nodes(), n_nodes, var.number(vig)
2300 #ifdef DEBUG
2301  , tot_size
2302 #endif
2303  );
2304  }
2305  }
2306 
2307 #ifdef DEBUG
2308  libmesh_assert_equal_to (tot_size, di.size());
2309 #endif
2310 }
unsigned int n_variable_groups() const
Definition: dof_map.h:733
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:2603
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:2346
void _dof_indices(const Elem &elem, int p_level, std::vector< dof_id_type > &di, const unsigned int vg, const unsigned int vig, const Node *const *nodes, unsigned int n_nodes, const unsigned int v #ifdef DEBUG, std::size_t &tot_size #endif) const
Helper function that gets the dof indices on the current element for a non-SCALAR type variable...
Definition: dof_map.C:2571

◆ dof_indices() [2/6]

void libMesh::DofMap::dof_indices ( const Elem *const  elem,
std::vector< dof_id_type > &  di,
const unsigned int  vn,
int  p_level = -12345 
) const
overridevirtual

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

Implements libMesh::DofMapBase.

Definition at line 2313 of file dof_map.C.

References dof_indices(), and int.

2317 {
2318  dof_indices(
2319  elem,
2320  di,
2321  vn,
2322  [](const Elem &,
2323  std::vector<dof_id_type> & dof_indices,
2324  const std::vector<dof_id_type> & scalar_dof_indices) {
2325  dof_indices.insert(dof_indices.end(), scalar_dof_indices.begin(), scalar_dof_indices.end());
2326  },
2327  [](const Elem &,
2328  unsigned int,
2329  unsigned int,
2330  std::vector<dof_id_type> & dof_indices,
2331  const dof_id_type dof) { dof_indices.push_back(dof); },
2332  p_level);
2333 }
void dof_indices(const Elem *const elem, std::vector< dof_id_type > &di) const
Definition: dof_map.C:2197
void ErrorVector unsigned int
Definition: adjoints_ex3.C:360
uint8_t dof_id_type
Definition: id_types.h:67

◆ dof_indices() [3/6]

template<typename ScalarDofsFunctor , typename FieldDofsFunctor >
void libMesh::DofMap::dof_indices ( const Elem *const  elem,
std::vector< dof_id_type > &  di,
const unsigned int  vn,
ScalarDofsFunctor  scalar_dofs_functor,
FieldDofsFunctor  field_dofs_functor,
int  p_level = -12345 
) const

Retrieves degree of freedom indices for a given elem and then performs actions for these indices defined by the user-provided functors scalar_dofs_functor and field_dofs_functor.

This API is useful when a user wants to do more than simply fill a degree of freedom container

Parameters
elemThe element to get degrees of freedom for
diA container for degrees of freedom. It is up to the provided functors how this gets filled
vnThe variable number to retrieve degrees of freedom for
scalar_dofs_functorThe functor that acts on scalar degrees of freedom. This functor has the interface: void scalar_dofs_functor(const Elem & elem, std::vector<dof_id_type> & di, const std::vector<dof_id_type> & scalar_dof_indices) where di is the degree of freedom container described above and scalar_dof_indices are the scalar dof indices available to elem
field_dofs_functorThe functor that acts on "field" (e.g. non-scalar, non-global) degrees of freedom. This functor has the interface: void field_dofs_functor(const Elem & elem, const unsigned int node_num, const unsigned int var_num, std::vector<dof_id_type> & di, const dof_id_type field_dof) where field_dof represents a field degree of freedom to act on and is associated with node_num and var_num. If the degree of freedom is elemental than node_num will be invalid_uint. di is again the degree of freedom container provided above

Definition at line 2778 of file dof_map.h.

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

2784 {
2785  // We now allow elem==nullptr to request just SCALAR dofs
2786  // libmesh_assert(elem);
2787 
2788  LOG_SCOPE("dof_indices()", "DofMap");
2789 
2790  // Clear the DOF indices vector
2791  di.clear();
2792 
2793  // Use the default p refinement level?
2794  if (p_level == -12345)
2795  p_level = elem ? elem->p_level() : 0;
2796 
2797  const unsigned int vg = this->_variable_group_numbers[vn];
2798  const VariableGroup & var = this->variable_group(vg);
2799  const unsigned int vig = vn - var.number();
2800 
2801 #ifdef DEBUG
2802  // Check that sizes match in DEBUG mode
2803  std::size_t tot_size = 0;
2804 #endif
2805 
2806  if (elem && elem->type() == TRI3SUBDIVISION)
2807  {
2808  // Subdivision surface FE require the 1-ring around elem
2809  const Tri3Subdivision * sd_elem = static_cast<const Tri3Subdivision *>(elem);
2810 
2811  // Ghost subdivision elements have no real dofs
2812  if (!sd_elem->is_ghost())
2813  {
2814  // Determine the nodes contributing to element elem
2815  std::vector<const Node *> elem_nodes;
2816  MeshTools::Subdivision::find_one_ring(sd_elem, elem_nodes);
2817 
2818  _dof_indices(*elem, p_level, di, vg, vig, elem_nodes.data(),
2819  cast_int<unsigned int>(elem_nodes.size()), vn,
2820 #ifdef DEBUG
2821  tot_size,
2822 #endif
2823  field_dofs_functor);
2824  }
2825 
2826  return;
2827  }
2828 
2829  // Get the dof numbers
2830  if (var.type().family == SCALAR &&
2831  (!elem ||
2832  var.active_on_subdomain(elem->subdomain_id())))
2833  {
2834 #ifdef DEBUG
2835  tot_size += var.type().order;
2836 #endif
2837  std::vector<dof_id_type> di_new;
2838  this->SCALAR_dof_indices(di_new,vn);
2839  scalar_dofs_functor(*elem, di, di_new);
2840  }
2841  else if (elem)
2842  _dof_indices(*elem, p_level, di, vg, vig, elem->get_nodes(),
2843  elem->n_nodes(), vn,
2844 #ifdef DEBUG
2845  tot_size,
2846 #endif
2847  field_dofs_functor);
2848 
2849 #ifdef DEBUG
2850  libmesh_assert_equal_to (tot_size, di.size());
2851 #endif
2852 }
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:2603
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:2346
void _dof_indices(const Elem &elem, int p_level, std::vector< dof_id_type > &di, const unsigned int vg, const unsigned int vig, const Node *const *nodes, unsigned int n_nodes, const unsigned int v #ifdef DEBUG, std::size_t &tot_size #endif) const
Helper function that gets the dof indices on the current element for a non-SCALAR type variable...
Definition: dof_map.C:2571
std::vector< unsigned int > _variable_group_numbers
The variable group number for each variable.
Definition: dof_map.h:2099

◆ dof_indices() [4/6]

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

2360 {
2361  // We allow node==nullptr to request just SCALAR dofs
2362  // libmesh_assert(elem);
2363 
2364  // dof_indices() is a relatively light-weight function that is
2365  // called millions of times in normal codes. Therefore, it is not a
2366  // good candidate for logging, since the cost of the logging code
2367  // itself is roughly on par with the time required to call
2368  // dof_indices().
2369  // LOG_SCOPE("dof_indices(Node)", "DofMap");
2370 
2371  // Clear the DOF indices vector
2372  di.clear();
2373 
2374  const unsigned int n_var_groups = this->n_variable_groups();
2375  const unsigned int sys_num = this->sys_number();
2376 
2377  // Get the dof numbers
2378  for (unsigned int vg=0; vg<n_var_groups; vg++)
2379  {
2380  const VariableGroup & var = this->variable_group(vg);
2381  const unsigned int vars_in_group = var.n_variables();
2382 
2383  if (var.type().family == SCALAR)
2384  {
2385  for (unsigned int vig=0; vig != vars_in_group; ++vig)
2386  {
2387  std::vector<dof_id_type> di_new;
2388  this->SCALAR_dof_indices(di_new,var.number(vig));
2389  di.insert( di.end(), di_new.begin(), di_new.end());
2390  }
2391  }
2392  else
2393  {
2394  const int n_comp = node->n_comp_group(sys_num,vg);
2395  for (unsigned int vig=0; vig != vars_in_group; ++vig)
2396  {
2397  for (int i=0; i != n_comp; ++i)
2398  {
2399  const dof_id_type d =
2400  node->dof_number(sys_num, vg, vig, i, n_comp);
2401  libmesh_assert_not_equal_to
2402  (d, DofObject::invalid_id);
2403  di.push_back(d);
2404  }
2405  }
2406  }
2407  }
2408 }
unsigned int n_variable_groups() const
Definition: dof_map.h:733
unsigned int sys_number() const
Definition: dof_map.h:2338
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:2603
static constexpr dof_id_type invalid_id
An invalid id to distinguish an uninitialized DofObject.
Definition: dof_object.h:482
const VariableGroup & variable_group(const unsigned int c) const
Definition: dof_map.h:2346
uint8_t dof_id_type
Definition: id_types.h:67

◆ dof_indices() [5/6]

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

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

Implements libMesh::DofMapBase.

Definition at line 2411 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().

2414 {
2415  if (vn == libMesh::invalid_uint)
2416  {
2417  this->dof_indices(node, di);
2418  return;
2419  }
2420 
2421  // We allow node==nullptr to request just SCALAR dofs
2422  // libmesh_assert(elem);
2423 
2424  // dof_indices() is a relatively light-weight function that is
2425  // called millions of times in normal codes. Therefore, it is not a
2426  // good candidate for logging, since the cost of the logging code
2427  // itself is roughly on par with the time required to call
2428  // dof_indices().
2429  // LOG_SCOPE("dof_indices(Node)", "DofMap");
2430 
2431  // Clear the DOF indices vector
2432  di.clear();
2433 
2434  const unsigned int sys_num = this->sys_number();
2435 
2436  // Get the dof numbers
2437  const unsigned int vg = this->_variable_group_numbers[vn];
2438  const VariableGroup & var = this->variable_group(vg);
2439 
2440  if (var.type().family == SCALAR)
2441  {
2442  std::vector<dof_id_type> di_new;
2443  this->SCALAR_dof_indices(di_new,vn);
2444  di.insert( di.end(), di_new.begin(), di_new.end());
2445  }
2446  else
2447  {
2448  const unsigned int vig = vn - var.number();
2449  const int n_comp = node->n_comp_group(sys_num,vg);
2450  for (int i=0; i != n_comp; ++i)
2451  {
2452  const dof_id_type d =
2453  node->dof_number(sys_num, vg, vig, i, n_comp);
2454  libmesh_assert_not_equal_to
2455  (d, DofObject::invalid_id);
2456  di.push_back(d);
2457  }
2458  }
2459 }
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:310
void dof_indices(const Elem *const elem, std::vector< dof_id_type > &di) const
Definition: dof_map.C:2197
unsigned int sys_number() const
Definition: dof_map.h:2338
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:2603
static constexpr dof_id_type invalid_id
An invalid id to distinguish an uninitialized DofObject.
Definition: dof_object.h:482
const VariableGroup & variable_group(const unsigned int c) const
Definition: dof_map.h:2346
std::vector< unsigned int > _variable_group_numbers
The variable group number for each variable.
Definition: dof_map.h:2099
uint8_t dof_id_type
Definition: id_types.h:67

◆ dof_indices() [6/6]

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

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

2466 {
2467  this->_node_dof_indices(elem, n, elem.node_ref(n), di, vn);
2468 }
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:2487

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

References libMesh::DofMapBase::_end_df, and libMesh::libmesh_assert().

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

816  { std::vector<dof_id_type>::const_iterator ub =
817  std::upper_bound(_end_df.begin(), _end_df.end(), dof);
818  libmesh_assert (ub != _end_df.end());
819  return cast_int<processor_id_type>(ub - _end_df.begin());
820  }
libmesh_assert(ctx)
std::vector< dof_id_type > _end_df
Last DOF index (plus 1) on processor p.
Definition: dof_map_base.h:159

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

References mesh.

Referenced by distribute_dofs().

311 {
312  return mesh.elem_ptr(i);
313 }
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::DofMapBase::end_dof ( const processor_id_type  proc) const
inlineinherited

◆ end_dof() [2/2]

dof_id_type libMesh::DofMapBase::end_dof ( ) const
inlineinherited

◆ end_old_dof() [1/2]

dof_id_type libMesh::DofMapBase::end_old_dof ( const processor_id_type  proc) const
inlineinherited
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 210 of file dof_map_base.h.

References libMesh::DofMapBase::_end_old_df.

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

211 {
212  libmesh_assert_less(proc, _end_old_df.size());
213  return _end_old_df[proc];
214 }
std::vector< dof_id_type > _end_old_df
Last old DOF index (plus 1) on processor p.
Definition: dof_map_base.h:181

◆ end_old_dof() [2/2]

dof_id_type libMesh::DofMapBase::end_old_dof ( ) const
inlineinherited

Definition at line 140 of file dof_map_base.h.

References libMesh::DofMapBase::end_old_dof(), and libMesh::ParallelObject::processor_id().

Referenced by libMesh::DofMapBase::end_old_dof().

140 { return this->end_old_dof(this->processor_id()); }
dof_id_type end_old_dof() const
Definition: dof_map_base.h:140
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 2520 of file dof_map.h.

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

2521  {}

◆ 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 2516 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::CondensedEigenSystem::get_eigenpair(), 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().

2518  {}

◆ enforce_constraints_on_jacobian()

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

Definition at line 2531 of file dof_map.h.

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

2532  {}

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

2118 {
2119  const unsigned int n_original_dofs = dof_indices_in.size();
2120 
2121 #ifdef LIBMESH_ENABLE_AMR
2122 
2123  // Trivial mapping
2124  libmesh_assert_equal_to (dof_indices_in.size(), Ue.size());
2125  bool has_constrained_dofs = false;
2126 
2127  for (unsigned int il=0; il != n_original_dofs; ++il)
2128  {
2129  const dof_id_type ig = dof_indices_in[il];
2130 
2131  if (this->is_constrained_dof (ig)) has_constrained_dofs = true;
2132 
2133  libmesh_assert_less (ig, Ug.size());
2134 
2135  Ue.el(il) = Ug(ig);
2136  }
2137 
2138  // If the element has any constrained DOFs then we need
2139  // to account for them in the mapping. This will handle
2140  // the case that the input vector is not constrained.
2141  if (has_constrained_dofs)
2142  {
2143  // Copy the input DOF indices.
2144  std::vector<dof_id_type> constrained_dof_indices(dof_indices_in);
2145 
2146  DenseMatrix<Number> C;
2147  DenseVector<Number> H;
2148 
2149  this->build_constraint_matrix_and_vector (C, H, constrained_dof_indices);
2150 
2151  libmesh_assert_equal_to (dof_indices_in.size(), C.m());
2152  libmesh_assert_equal_to (constrained_dof_indices.size(), C.n());
2153 
2154  // zero-out Ue
2155  Ue.zero();
2156 
2157  // compute Ue = C Ug, with proper mapping.
2158  for (unsigned int i=0; i != n_original_dofs; i++)
2159  {
2160  Ue.el(i) = H(i);
2161 
2162  const unsigned int n_constrained =
2163  cast_int<unsigned int>(constrained_dof_indices.size());
2164  for (unsigned int j=0; j<n_constrained; j++)
2165  {
2166  const dof_id_type jg = constrained_dof_indices[j];
2167 
2168  // If Ug is a serial or ghosted vector, then this assert is
2169  // overzealous. If Ug is a parallel vector, then this assert
2170  // is redundant.
2171  // libmesh_assert ((jg >= Ug.first_local_index()) &&
2172  // (jg < Ug.last_local_index()));
2173 
2174  Ue.el(i) += C(i,j)*Ug(jg);
2175  }
2176  }
2177  }
2178 
2179 #else
2180 
2181  // Trivial mapping
2182 
2183  libmesh_assert_equal_to (n_original_dofs, Ue.size());
2184 
2185  for (unsigned int il=0; il<n_original_dofs; il++)
2186  {
2187  const dof_id_type ig = dof_indices_in[il];
2188 
2189  libmesh_assert ((ig >= Ug.first_local_index()) && (ig < Ug.last_local_index()));
2190 
2191  Ue.el(il) = Ug(ig);
2192  }
2193 
2194 #endif
2195 }
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:2424
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 2911 of file dof_map.C.

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

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

2912 {
2913  typedef std::set<dof_id_type> RCSet;
2914 
2915  // First insert the DOFS we already depend on into the set.
2916  RCSet dof_set (elem_dofs.begin(), elem_dofs.end());
2917 
2918  bool done = true;
2919 
2920  // Next insert any dofs those might be constrained in terms
2921  // of. Note that in this case we may not be done: Those may
2922  // in turn depend on others. So, we need to repeat this process
2923  // in that case until the system depends only on unconstrained
2924  // degrees of freedom.
2925  for (const auto & dof : elem_dofs)
2926  if (this->is_constrained_dof(dof))
2927  {
2928  // If the DOF is constrained
2929  DofConstraints::const_iterator
2930  pos = _dof_constraints.find(dof);
2931 
2932  libmesh_assert (pos != _dof_constraints.end());
2933 
2934  const DofConstraintRow & constraint_row = pos->second;
2935 
2936  // adaptive p refinement currently gives us lots of empty constraint
2937  // rows - we should optimize those DoFs away in the future. [RHS]
2938  //libmesh_assert (!constraint_row.empty());
2939 
2940  // Add the DOFs this dof is constrained in terms of.
2941  // note that these dofs might also be constrained, so
2942  // we will need to call this function recursively.
2943  for (const auto & pr : constraint_row)
2944  if (!dof_set.count (pr.first))
2945  {
2946  dof_set.insert (pr.first);
2947  done = false;
2948  }
2949  }
2950 
2951 
2952  // If not done then we need to do more work
2953  // (obviously :-) )!
2954  if (!done)
2955  {
2956  // Fill the vector with the contents of the set
2957  elem_dofs.clear();
2958  elem_dofs.insert (elem_dofs.end(),
2959  dof_set.begin(), dof_set.end());
2960 
2961 
2962  // May need to do this recursively. It is possible
2963  // that we just replaced a constrained DOF with another
2964  // constrained DOF.
2965  this->find_connected_dofs (elem_dofs);
2966 
2967  } // end if (!done)
2968 }
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:2911
libmesh_assert(ctx)
bool is_constrained_dof(const dof_id_type dof) const
Definition: dof_map.h:2424
DofConstraints _dof_constraints
Data structure containing DOF constraints.
Definition: dof_map.h:2272
std::map< dof_id_type, Real, std::less< dof_id_type >, Threads::scalable_allocator< std::pair< const dof_id_type, Real > > > DofConstraintRow
A row of the Dof constraint matrix.
Definition: dof_map.h:100

◆ first_dof() [1/2]

dof_id_type libMesh::DofMapBase::first_dof ( const processor_id_type  proc) const
inlineinherited

◆ first_dof() [2/2]

dof_id_type libMesh::DofMapBase::first_dof ( ) const
inlineinherited

◆ first_old_dof() [1/2]

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

Definition at line 204 of file dof_map_base.h.

References libMesh::DofMapBase::_first_old_df.

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

205 {
206  libmesh_assert_less(proc, _first_old_df.size());
207  return _first_old_df[proc];
208 }
std::vector< dof_id_type > _first_old_df
First old DOF index on processor p.
Definition: dof_map_base.h:176

◆ first_old_dof() [2/2]

dof_id_type libMesh::DofMapBase::first_old_dof ( ) const
inlineinherited

Definition at line 130 of file dof_map_base.h.

References libMesh::DofMapBase::first_old_dof(), and libMesh::ParallelObject::processor_id().

Referenced by libMesh::DofMapBase::first_old_dof().

130 { return this->first_old_dof(this->processor_id()); }
dof_id_type first_old_dof() const
Definition: dof_map_base.h:130
processor_id_type processor_id() const

◆ full_sparsity_pattern_needed()

void libMesh::DofMap::full_sparsity_pattern_needed ( )
inline

Sets need_full_sparsity_pattern to true regardless of the requirements by matrices.

Definition at line 2552 of file dof_map.h.

References need_full_sparsity_pattern.

2553 {
2555 }
bool need_full_sparsity_pattern
Default false; set to true if any attached matrix requires a full sparsity pattern.
Definition: dof_map.h:2238

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

References _adjoint_constraint_values, _dof_constraints, libMesh::DofMapBase::_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().

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

◆ get_adjoint_dirichlet_boundaries() [1/2]

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

Definition at line 5441 of file dof_map_constraints.C.

References _adjoint_dirichlet_boundaries.

5442 {
5443  libmesh_assert_greater(_adjoint_dirichlet_boundaries.size(),q);
5444  return _adjoint_dirichlet_boundaries[q].get();
5445 }
std::vector< std::unique_ptr< DirichletBoundaries > > _adjoint_dirichlet_boundaries
Data structure containing Dirichlet functions.
Definition: dof_map.h:2306

◆ get_adjoint_dirichlet_boundaries() [2/2]

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

Definition at line 5449 of file dof_map_constraints.C.

References _adjoint_dirichlet_boundaries.

5450 {
5451  unsigned int old_size = cast_int<unsigned int>
5453  for (unsigned int i = old_size; i <= q; ++i)
5454  _adjoint_dirichlet_boundaries.push_back(std::make_unique<DirichletBoundaries>());
5455 
5456  return _adjoint_dirichlet_boundaries[q].get();
5457 }
std::vector< std::unique_ptr< DirichletBoundaries > > _adjoint_dirichlet_boundaries
Data structure containing Dirichlet functions.
Definition: dof_map.h:2306

◆ get_all_variable_numbers()

void libMesh::DofMap::get_all_variable_numbers ( std::vector< unsigned int > &  all_variable_numbers) const

Fills all_variable_numbers with all the variable numbers for the variables that have been added to this system.

Definition at line 3385 of file dof_map.C.

References _variable_numbers, and n_vars().

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

3386 {
3387  all_variable_numbers.resize(n_vars());
3388 
3389  unsigned int count = 0;
3390  for (auto vn : _variable_numbers)
3391  all_variable_numbers[count++] = vn.second;
3392 }
std::map< std::string, unsigned int, std::less<> > _variable_numbers
The variable numbers corresponding to user-specified names, useful for name-based lookups...
Definition: dof_map.h:2110
unsigned int n_vars() const
Definition: dof_map.h:2926

◆ get_dirichlet_boundaries() [1/2]

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

Definition at line 1636 of file dof_map.h.

References _dirichlet_boundaries.

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

1637  {
1638  return _dirichlet_boundaries.get();
1639  }
std::unique_ptr< DirichletBoundaries > _dirichlet_boundaries
Data structure containing Dirichlet functions.
Definition: dof_map.h:2300

◆ get_dirichlet_boundaries() [2/2]

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

Definition at line 1641 of file dof_map.h.

References _dirichlet_boundaries.

1642  {
1643  return _dirichlet_boundaries.get();
1644  }
std::unique_ptr< DirichletBoundaries > _dirichlet_boundaries
Data structure containing Dirichlet functions.
Definition: dof_map.h:2300

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

References _dof_constraints.

Referenced by libMesh::StaticCondensationDofMap::add_uncondensed_dof_plus_constraint_dofs().

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

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

2982 {
2983  std::ostringstream os;
2984 
2985  // If we didn't calculate the exact sparsity pattern, the threaded
2986  // sparsity pattern assembly may have just given us an upper bound
2987  // on sparsity.
2988  const char * may_equal = " <= ";
2989 
2990  // If we calculated the exact sparsity pattern, then we can report
2991  // exact bandwidth figures:
2992  for (const auto & mat : _matrices)
2993  if (mat->need_full_sparsity_pattern())
2994  may_equal = " = ";
2995 
2996  dof_id_type max_n_nz = 0, max_n_oz = 0;
2997  long double avg_n_nz = 0, avg_n_oz = 0;
2998 
2999  if (_sp)
3000  {
3001  for (const auto & val : _sp->get_n_nz())
3002  {
3003  max_n_nz = std::max(max_n_nz, val);
3004  avg_n_nz += val;
3005  }
3006 
3007  std::size_t n_nz_size = _sp->get_n_nz().size();
3008 
3009  this->comm().max(max_n_nz);
3010  this->comm().sum(avg_n_nz);
3011  this->comm().sum(n_nz_size);
3012 
3013  avg_n_nz /= std::max(n_nz_size,std::size_t(1));
3014 
3015  for (const auto & val : _sp->get_n_oz())
3016  {
3017  max_n_oz = std::max(max_n_oz, val);
3018  avg_n_oz += val;
3019  }
3020 
3021  std::size_t n_oz_size = _sp->get_n_oz().size();
3022 
3023  this->comm().max(max_n_oz);
3024  this->comm().sum(avg_n_oz);
3025  this->comm().sum(n_oz_size);
3026 
3027  avg_n_oz /= std::max(n_oz_size,std::size_t(1));
3028  }
3029 
3030  os << " DofMap Sparsity\n Average On-Processor Bandwidth"
3031  << may_equal << avg_n_nz << '\n';
3032 
3033  os << " Average Off-Processor Bandwidth"
3034  << may_equal << avg_n_oz << '\n';
3035 
3036  os << " Maximum On-Processor Bandwidth"
3037  << may_equal << max_n_nz << '\n';
3038 
3039  os << " Maximum Off-Processor Bandwidth"
3040  << may_equal << max_n_oz << std::endl;
3041 
3042 #ifdef LIBMESH_ENABLE_CONSTRAINTS
3043 
3044  std::size_t n_constraints = 0, max_constraint_length = 0,
3045  n_rhss = 0;
3046  long double avg_constraint_length = 0.;
3047 
3048  for (const auto & [constrained_dof, row] : _dof_constraints)
3049  {
3050  // Only count local constraints, then sum later
3051  if (!this->local_index(constrained_dof))
3052  continue;
3053 
3054  std::size_t rowsize = row.size();
3055 
3056  max_constraint_length = std::max(max_constraint_length,
3057  rowsize);
3058  avg_constraint_length += rowsize;
3059  n_constraints++;
3060 
3061  if (_primal_constraint_values.count(constrained_dof))
3062  n_rhss++;
3063  }
3064 
3065  this->comm().sum(n_constraints);
3066  this->comm().sum(n_rhss);
3067  this->comm().sum(avg_constraint_length);
3068  this->comm().max(max_constraint_length);
3069 
3070  os << " DofMap Constraints\n Number of DoF Constraints = "
3071  << n_constraints;
3072  if (n_rhss)
3073  os << '\n'
3074  << " Number of Heterogenous Constraints= " << n_rhss;
3075  if (n_constraints)
3076  {
3077  avg_constraint_length /= n_constraints;
3078 
3079  os << '\n'
3080  << " Average DoF Constraint Length= " << avg_constraint_length;
3081  }
3082 
3083 #ifdef LIBMESH_ENABLE_NODE_CONSTRAINTS
3084  std::size_t n_node_constraints = 0, max_node_constraint_length = 0,
3085  n_node_rhss = 0;
3086  long double avg_node_constraint_length = 0.;
3087 
3088  for (const auto & [node, pr] : _node_constraints)
3089  {
3090  // Only count local constraints, then sum later
3091  if (node->processor_id() != this->processor_id())
3092  continue;
3093 
3094  const NodeConstraintRow & row = pr.first;
3095  std::size_t rowsize = row.size();
3096 
3097  max_node_constraint_length = std::max(max_node_constraint_length,
3098  rowsize);
3099  avg_node_constraint_length += rowsize;
3100  n_node_constraints++;
3101 
3102  if (pr.second != Point(0))
3103  n_node_rhss++;
3104  }
3105 
3106  this->comm().sum(n_node_constraints);
3107  this->comm().sum(n_node_rhss);
3108  this->comm().sum(avg_node_constraint_length);
3109  this->comm().max(max_node_constraint_length);
3110 
3111  os << "\n Number of Node Constraints = " << n_node_constraints;
3112  if (n_node_rhss)
3113  os << '\n'
3114  << " Number of Heterogenous Node Constraints= " << n_node_rhss;
3115  if (n_node_constraints)
3116  {
3117  avg_node_constraint_length /= n_node_constraints;
3118  os << "\n Maximum Node Constraint Length= " << max_node_constraint_length
3119  << '\n'
3120  << " Average Node Constraint Length= " << avg_node_constraint_length;
3121  }
3122 #endif // LIBMESH_ENABLE_NODE_CONSTRAINTS
3123 
3124  os << std::endl;
3125 
3126 #endif // LIBMESH_ENABLE_CONSTRAINTS
3127 
3128  return os.str();
3129 }
std::unique_ptr< SparsityPattern::Build > _sp
The sparsity pattern of the global matrix.
Definition: dof_map.h:2245
void sum(T &r) const
const Parallel::Communicator & comm() const
DofConstraints _dof_constraints
Data structure containing DOF constraints.
Definition: dof_map.h:2272
std::vector< SparseMatrix< Number > *> _matrices
Additional matrices handled by this object.
Definition: dof_map.h:2140
void max(const T &r, T &o, Request &req) const
DofConstraintValueMap _primal_constraint_values
Definition: dof_map.h:2274
std::map< const Node *, Real, std::less< const Node * >, Threads::scalable_allocator< std::pair< const Node *const, Real > > > NodeConstraintRow
A row of the Node constraint mapping.
Definition: dof_map.h:148
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:967
NodeConstraints _node_constraints
Data structure containing DofObject constraints.
Definition: dof_map.h:2283

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

2279 {
2280  std::ostringstream os;
2281 #ifdef LIBMESH_ENABLE_NODE_CONSTRAINTS
2282  if (print_nonlocal)
2283  os << "All ";
2284  else
2285  os << "Local ";
2286 
2287  os << "Node Constraints:"
2288  << std::endl;
2289 
2290  for (const auto & [node, pr] : _node_constraints)
2291  {
2292  // Skip non-local nodes if requested
2293  if (!print_nonlocal &&
2294  node->processor_id() != this->processor_id())
2295  continue;
2296 
2297  const NodeConstraintRow & row = pr.first;
2298  const Point & offset = pr.second;
2299 
2300  os << "Constraints for Node id " << node->id()
2301  << ": \t";
2302 
2303  for (const auto & [cnode, val] : row)
2304  os << " (" << cnode->id() << "," << val << ")\t";
2305 
2306  os << "rhs: " << offset;
2307 
2308  os << std::endl;
2309  }
2310 #endif // LIBMESH_ENABLE_NODE_CONSTRAINTS
2311 
2312  if (print_nonlocal)
2313  os << "All ";
2314  else
2315  os << "Local ";
2316 
2317  os << "DoF Constraints:"
2318  << std::endl;
2319 
2320  for (const auto & [i, row] : _dof_constraints)
2321  {
2322  // Skip non-local dofs if requested
2323  if (!print_nonlocal && !this->local_index(i))
2324  continue;
2325 
2326  DofConstraintValueMap::const_iterator rhsit =
2327  _primal_constraint_values.find(i);
2328  const Number rhs = (rhsit == _primal_constraint_values.end()) ?
2329  0 : rhsit->second;
2330 
2331  os << "Constraints for DoF " << i
2332  << ": \t";
2333 
2334  for (const auto & item : row)
2335  os << " (" << item.first << "," << item.second << ")\t";
2336 
2337  os << "rhs: " << rhs;
2338  os << std::endl;
2339  }
2340 
2341  for (unsigned int qoi_index = 0,
2342  n_qois = cast_int<unsigned int>(_adjoint_dirichlet_boundaries.size());
2343  qoi_index != n_qois; ++qoi_index)
2344  {
2345  os << "Adjoint " << qoi_index << " DoF rhs values:"
2346  << std::endl;
2347 
2348  if (auto adjoint_map_it = _adjoint_constraint_values.find(qoi_index);
2349  adjoint_map_it != _adjoint_constraint_values.end())
2350  for (const auto & [i, rhs] : adjoint_map_it->second)
2351  {
2352  // Skip non-local dofs if requested
2353  if (!print_nonlocal && !this->local_index(i))
2354  continue;
2355 
2356  os << "RHS for DoF " << i
2357  << ": " << rhs;
2358 
2359  os << std::endl;
2360  }
2361  }
2362 
2363  return os.str();
2364 }
AdjointDofConstraintValues _adjoint_constraint_values
Definition: dof_map.h:2276
DofConstraints _dof_constraints
Data structure containing DOF constraints.
Definition: dof_map.h:2272
std::vector< std::unique_ptr< DirichletBoundaries > > _adjoint_dirichlet_boundaries
Data structure containing Dirichlet functions.
Definition: dof_map.h:2306
DofConstraintValueMap _primal_constraint_values
Definition: dof_map.h:2274
std::map< const Node *, Real, std::less< const Node * >, Threads::scalable_allocator< std::pair< const Node *const, Real > > > NodeConstraintRow
A row of the Node constraint mapping.
Definition: dof_map.h:148
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:967
NodeConstraints _node_constraints
Data structure containing DofObject constraints.
Definition: dof_map.h:2283

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

References _sp, and libMesh::libmesh_assert().

543  {
545  return _sp->get_n_nz();
546  }
std::unique_ptr< SparsityPattern::Build > _sp
The sparsity pattern of the global matrix.
Definition: dof_map.h:2245
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 555 of file dof_map.h.

References _sp, and libMesh::libmesh_assert().

556  {
558  return _sp->get_n_oz();
559  }
std::unique_ptr< SparsityPattern::Build > _sp
The sparsity pattern of the global matrix.
Definition: dof_map.h:2245
libmesh_assert(ctx)

◆ get_periodic_boundaries() [1/2]

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

Definition at line 1583 of file dof_map.h.

References _periodic_boundaries.

Referenced by main().

1584  {
1585  return _periodic_boundaries.get();
1586  }
std::unique_ptr< PeriodicBoundaries > _periodic_boundaries
Data structure containing periodic boundaries.
Definition: dof_map.h:2292

◆ get_periodic_boundaries() [2/2]

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

Definition at line 1588 of file dof_map.h.

References _periodic_boundaries.

1589  {
1590  return _periodic_boundaries.get();
1591  }
std::unique_ptr< PeriodicBoundaries > _periodic_boundaries
Data structure containing periodic boundaries.
Definition: dof_map.h:2292

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

References _primal_constraint_values.

2470 {
2472 }
DofConstraintValueMap _primal_constraint_values
Definition: dof_map.h:2274

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

References _sp.

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

571  {
572  return _sp.get();
573  }
std::unique_ptr< SparsityPattern::Build > _sp
The sparsity pattern of the global matrix.
Definition: dof_map.h:2245

◆ get_static_condensation()

StaticCondensationDofMap & libMesh::DofMap::get_static_condensation ( )
inline
Returns
the static condensation class. This should have been already added with a call to add_static_condensation()

Definition at line 2855 of file dof_map.h.

References _sc, and libMesh::libmesh_assert().

Referenced by libMesh::System::add_matrix(), and libMesh::ImplicitSystem::create_static_condensation_system_matrix().

2856 {
2858  return *_sc;
2859 }
std::unique_ptr< StaticCondensationDofMap > _sc
Static condensation class.
Definition: dof_map.h:2331
libmesh_assert(ctx)

◆ get_variable_array()

const std::pair< unsigned int, unsigned int > & libMesh::DofMap::get_variable_array ( unsigned int  vi) const
inlineprivate

Retrieve the array variable bounds for a given variable vi.

This variable may lie anywhere within an array variable range. An 'array variable' is simply a sequence of contiguous variable numbers defined by pair where the first member of the pair is the first number in the variable sequence and the second member of the pair is the number of the last variable in the sequence plus one. Array variables may be used in tandem with variable grouping by downstream code to build optimized physics kernels since each variable in the array will have the same shape functions.

We note that we store array variables as a container of the above described pairs. Within this API we will do a binary search such that the complexity is O(log(N)) where N is the number of array variables present in this

Definition at line 2862 of file dof_map.h.

References _array_variables, and value.

Referenced by array_dof_indices().

2863 {
2864  auto it = std::upper_bound(
2865  _array_variables.begin(),
2866  _array_variables.end(),
2867  vi,
2868  [](unsigned int value, const std::pair<unsigned int, unsigned int> & b) { return value < b.first; });
2869 
2870  libmesh_assert_msg(it != _array_variables.begin(),
2871  "Passed in " << std::to_string(vi) << " is not in any of our array variables");
2872  --it;
2873  libmesh_assert_msg(vi < it->second,
2874  "Passed in " << std::to_string(vi) << " is not in any of our array variables");
2875  return *it;
2876 }
std::vector< std::pair< unsigned int, unsigned int > > _array_variables
Array variable information storage.
Definition: dof_map.h:2117
static const bool value
Definition: xdr_io.C:55

◆ has_adjoint_dirichlet_boundaries()

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

Definition at line 5431 of file dof_map_constraints.C.

References _adjoint_dirichlet_boundaries.

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

5432 {
5433  if (_adjoint_dirichlet_boundaries.size() > q)
5434  return true;
5435 
5436  return false;
5437 }
std::vector< std::unique_ptr< DirichletBoundaries > > _adjoint_dirichlet_boundaries
Data structure containing Dirichlet functions.
Definition: dof_map.h:2306

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

References n_variable_groups(), and n_variables().

Referenced by block_size().

750  {
751  return ((this->n_variable_groups() == 1) && (this->n_variables() > 1));
752  }
unsigned int n_variable_groups() const
Definition: dof_map.h:733
unsigned int n_variables() const override
Definition: dof_map.h:736

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

References _adjoint_constraint_values.

Referenced by has_heterogenous_adjoint_constraint().

2450 {
2451  AdjointDofConstraintValues::const_iterator it =
2452  _adjoint_constraint_values.find(qoi_num);
2453  if (it != _adjoint_constraint_values.end())
2454  {
2455  DofConstraintValueMap::const_iterator rhsit =
2456  it->second.find(dof);
2457  if (rhsit == it->second.end())
2458  return 0;
2459  else
2460  return rhsit->second;
2461  }
2462 
2463  return 0;
2464 }
AdjointDofConstraintValues _adjoint_constraint_values
Definition: dof_map.h:2276

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

References _adjoint_constraint_values.

Referenced by has_heterogenous_adjoint_constraints().

2435 {
2436  AdjointDofConstraintValues::const_iterator it =
2437  _adjoint_constraint_values.find(qoi_num);
2438  if (it == _adjoint_constraint_values.end())
2439  return false;
2440  if (it->second.empty())
2441  return false;
2442 
2443  return true;
2444 }
AdjointDofConstraintValues _adjoint_constraint_values
Definition: dof_map.h:2276

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

References has_heterogeneous_adjoint_constraint().

1255  {
1256  return this->has_heterogeneous_adjoint_constraint (qoi_num, dof);
1257  }
Number has_heterogeneous_adjoint_constraint(const unsigned int qoi_num, const dof_id_type dof) const
Definition: dof_map.h:2448

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

References has_heterogeneous_adjoint_constraints().

1238  {
1239  return this->has_heterogeneous_adjoint_constraints (qoi_num);
1240  }
bool has_heterogeneous_adjoint_constraints(const unsigned int qoi_num) const
Definition: dof_map.h:2434

◆ has_static_condensation()

bool libMesh::DofMap::has_static_condensation ( ) const
inline

Checks whether we have static condensation.

Definition at line 1796 of file dof_map.h.

References _sc.

Referenced by build_sparsity(), and libMesh::System::has_static_condensation().

1796 { return _sc.get(); }
std::unique_ptr< StaticCondensationDofMap > _sc
Static condensation class.
Definition: dof_map.h:2331

◆ has_variable()

bool libMesh::DofMap::has_variable ( std::string_view  var) const
inline
Returns
true if a variable named var exists in this System

Definition at line 2975 of file dof_map.h.

References _variable_numbers.

Referenced by add_neighbors_to_send_list(), and libMesh::System::has_variable().

2976 {
2977  return _variable_numbers.count(var);
2978 }
std::map< std::string, unsigned int, std::less<> > _variable_numbers
The variable numbers corresponding to user-specified names, useful for name-based lookups...
Definition: dof_map.h:2110

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

2623 {
2624  libmesh_assert_equal_to (elem_dofs.size(), matrix.m());
2625  libmesh_assert_equal_to (elem_dofs.size(), matrix.n());
2626  libmesh_assert_equal_to (elem_dofs.size(), rhs.size());
2627 
2628  libmesh_assert (solution_local.type() == SERIAL ||
2629  solution_local.type() == GHOSTED);
2630 
2631  // check for easy return
2632  if (this->_dof_constraints.empty())
2633  return;
2634 
2635  // The constrained matrix is built up as C^T K C.
2636  // The constrained RHS is built up as C^T F
2637  // Asymmetric residual terms are added if we do not have x = Cx+h
2640 
2641  this->build_constraint_matrix_and_vector (C, H, elem_dofs);
2642 
2643  LOG_SCOPE("hetero_cnstrn_elem_jac_res()", "DofMap");
2644 
2645  // It is possible that the matrix is not constrained at all.
2646  if ((C.m() != matrix.m()) ||
2647  (C.n() != elem_dofs.size()))
2648  return;
2649 
2650  // Compute the matrix-vector product C^T F
2651  DenseVector<Number> old_rhs(rhs);
2652  C.vector_mult_transpose(rhs, old_rhs);
2653 
2654  // Compute the matrix-matrix-matrix product C^T K C
2655  matrix.left_multiply_transpose (C);
2656  matrix.right_multiply (C);
2657 
2658  libmesh_assert_equal_to (matrix.m(), matrix.n());
2659  libmesh_assert_equal_to (matrix.m(), elem_dofs.size());
2660  libmesh_assert_equal_to (matrix.n(), elem_dofs.size());
2661 
2662  for (unsigned int i=0,
2663  n_elem_dofs = cast_int<unsigned int>(elem_dofs.size());
2664  i != n_elem_dofs; i++)
2665  {
2666  const dof_id_type dof_id = elem_dofs[i];
2667 
2668  if (auto pos = _dof_constraints.find(dof_id);
2669  pos != _dof_constraints.end())
2670  {
2671  for (auto j : make_range(matrix.n()))
2672  matrix(i,j) = 0.;
2673 
2674  // If the DOF is constrained
2675  matrix(i,i) = 1.;
2676 
2677  // This will put a nonsymmetric entry in the constraint
2678  // row to ensure that the linear system produces the
2679  // correct value for the constrained DOF.
2680  const DofConstraintRow & constraint_row = pos->second;
2681 
2682  for (const auto & item : constraint_row)
2683  for (unsigned int j=0; j != n_elem_dofs; j++)
2684  if (elem_dofs[j] == item.first)
2685  matrix(i,j) = -item.second;
2686 
2687  const DofConstraintValueMap::const_iterator valpos =
2688  _primal_constraint_values.find(dof_id);
2689 
2690  Number & rhs_val = rhs(i);
2691  rhs_val = (valpos == _primal_constraint_values.end()) ?
2692  0 : -valpos->second;
2693  for (const auto & [constraining_dof, coef] : constraint_row)
2694  rhs_val -= coef * solution_local(constraining_dof);
2695  rhs_val += solution_local(dof_id);
2696  }
2697  }
2698 }
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:2272
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:2274
std::map< dof_id_type, Real, std::less< dof_id_type >, Threads::scalable_allocator< std::pair< const dof_id_type, Real > > > DofConstraintRow
A row of the Dof constraint matrix.
Definition: dof_map.h:100
IntRange< T > make_range(T beg, T end)
The 2-parameter make_range() helper function returns an IntRange<T> when both input parameters are of...
Definition: int_range.h:140
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 2502 of file dof_map.h.

Referenced by heterogenously_constrain_element_matrix_and_vector(), and process_mesh_constraint_rows().

2503  {}

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

2705 {
2706  libmesh_assert_equal_to (elem_dofs.size(), rhs.size());
2707 
2708  libmesh_assert (solution_local.type() == SERIAL ||
2709  solution_local.type() == GHOSTED);
2710 
2711  // check for easy return
2712  if (this->_dof_constraints.empty())
2713  return;
2714 
2715  // The constrained RHS is built up as C^T F
2716  // Asymmetric residual terms are added if we do not have x = Cx+h
2719 
2720  this->build_constraint_matrix_and_vector (C, H, elem_dofs);
2721 
2722  LOG_SCOPE("hetero_cnstrn_elem_res()", "DofMap");
2723 
2724  // It is possible that the element is not constrained at all.
2725  if ((C.m() != rhs.size()) ||
2726  (C.n() != elem_dofs.size()))
2727  return;
2728 
2729  // Compute the matrix-vector product C^T F
2730  DenseVector<Number> old_rhs(rhs);
2731  C.vector_mult_transpose(rhs, old_rhs);
2732 
2733  for (unsigned int i=0,
2734  n_elem_dofs = cast_int<unsigned int>(elem_dofs.size());
2735  i != n_elem_dofs; i++)
2736  {
2737  const dof_id_type dof_id = elem_dofs[i];
2738 
2739  if (auto pos = _dof_constraints.find(dof_id);
2740  pos != _dof_constraints.end())
2741  {
2742  // This will put a nonsymmetric entry in the constraint
2743  // row to ensure that the linear system produces the
2744  // correct value for the constrained DOF.
2745  const DofConstraintRow & constraint_row = pos->second;
2746 
2747  const DofConstraintValueMap::const_iterator valpos =
2748  _primal_constraint_values.find(dof_id);
2749 
2750  Number & rhs_val = rhs(i);
2751  rhs_val = (valpos == _primal_constraint_values.end()) ?
2752  0 : -valpos->second;
2753  for (const auto & [constraining_dof, coef] : constraint_row)
2754  rhs_val -= coef * solution_local(constraining_dof);
2755  rhs_val += solution_local(dof_id);
2756  }
2757  }
2758 }
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:2272
ParallelType type() const
DofConstraintValueMap _primal_constraint_values
Definition: dof_map.h:2274
std::map< dof_id_type, Real, std::less< dof_id_type >, Threads::scalable_allocator< std::pair< const dof_id_type, Real > > > DofConstraintRow
A row of the Dof constraint matrix.
Definition: dof_map.h:100
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 2506 of file dof_map.h.

Referenced by heterogenously_constrain_element_vector().

2507  {}

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

References heterogeneously_constrain_element_matrix_and_vector().

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

1393  {
1395  (matrix, rhs, elem_dofs, asymmetric_constraint_rows, qoi_index);
1396  }
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:2502

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

References heterogeneously_constrain_element_vector().

1437  {
1439  (matrix, rhs, elem_dofs, asymmetric_constraint_rows, qoi_index);
1440  }
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:2506

◆ identify_variable_groups() [1/2]

bool libMesh::DofMap::identify_variable_groups ( ) const
inline
Returns
true when VariableGroup structures should be automatically identified, false otherwise.

Definition at line 2940 of file dof_map.h.

References _identify_variable_groups.

Referenced by add_variable(), add_variables(), and libMesh::System::identify_variable_groups().

2941 {
2943 }
bool _identify_variable_groups
true when VariableGroup structures should be automatically identified, false otherwise.
Definition: dof_map.h:2123

◆ identify_variable_groups() [2/2]

void libMesh::DofMap::identify_variable_groups ( const bool  ivg)
inline

Toggle automatic VariableGroup identification.

Definition at line 2946 of file dof_map.h.

References _identify_variable_groups.

2947 {
2949 }
bool _identify_variable_groups
true when VariableGroup structures should be automatically identified, false otherwise.
Definition: dof_map.h:2123

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

References mesh, and sys_number().

Referenced by distribute_dofs().

853 {
854  const unsigned int sys_num = this->sys_number();
855 
856  // All the nodes
857  for (auto & node : mesh.node_ptr_range())
858  node->invalidate_dofs(sys_num);
859 
860  // All the active elements.
861  for (auto & elem : mesh.active_element_ptr_range())
862  elem->invalidate_dofs(sys_num);
863 }
MeshBase & mesh
unsigned int sys_number() const
Definition: dof_map.h:2338

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

References _matrices.

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

296 {
297  return (std::find(_matrices.begin(), _matrices.end(),
298  &matrix) != _matrices.end());
299 }
std::vector< SparseMatrix< Number > *> _matrices
Additional matrices handled by this object.
Definition: dof_map.h:2140

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

References _node_constraints.

Referenced by allgather_recursive_constraints(), and scatter_constraints().

2413 {
2414 #ifdef LIBMESH_ENABLE_NODE_CONSTRAINTS
2415  if (_node_constraints.count(node))
2416  return true;
2417 #endif
2418 
2419  return false;
2420 }
NodeConstraints _node_constraints
Data structure containing DofObject constraints.
Definition: dof_map.h:2283

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

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

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

2670 {
2671  // Everything is evaluable on a local object
2672  if (obj.processor_id() == this->processor_id())
2673  return true;
2674 
2675  std::vector<dof_id_type> di;
2676 
2677  if (var_num == libMesh::invalid_uint)
2678  this->dof_indices(&obj, di);
2679  else
2680  this->dof_indices(&obj, di, var_num);
2681 
2682  return this->all_semilocal_indices(di);
2683 }
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:310
void dof_indices(const Elem *const elem, std::vector< dof_id_type > &di) const
Definition: dof_map.C:2197
bool all_semilocal_indices(const std::vector< dof_id_type > &dof_indices) const
Definition: dof_map.C:2655
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 217 of file dof_map.C.

References _periodic_boundaries.

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

◆ local_index()

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

◆ local_variable_indices() [1/2]

template<typename T , std::enable_if_t< std::is_same_v< T, dof_id_type >||std::is_same_v< T, std::vector< dof_id_type >>, int > >
void libMesh::DofMap::local_variable_indices ( T &  idx,
const MeshBase mesh,
unsigned int  var_num 
) const

If T == dof_id_type, counts, if T == std::vector<dof_id_type>, fills an array of, those dof indices which belong to the given variable number and live on the current processor.

Definition at line 1118 of file dof_map.C.

References libMesh::Variable::active_on_subdomain(), distance(), 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_petscdm(), local_variable_indices(), n_local_dofs(), libMesh::petsc_auto_fieldsplit(), and SystemsTest::testBlockRestrictedVarNDofs().

1121 {
1122  // Only used if T == dof_id_type to keep track of the greatest dof we've seen
1123  dof_id_type greatest = 0;
1124 
1125  if constexpr (std::is_same_v<T, dof_id_type>)
1126  idx = 0;
1127  else if constexpr (std::is_same_v<T, std::vector<dof_id_type>>)
1128  idx.clear();
1129 
1130  // Count dofs in the *exact* order that distribute_dofs numbered
1131  // them, so that we can assume ascending indices and use push_back
1132  // instead of find+insert.
1133 
1134  const unsigned int sys_num = this->sys_number();
1135 
1136  // If this isn't a SCALAR variable, we need to find all its field
1137  // dofs on the mesh
1138  if (this->variable_type(var_num).family != SCALAR)
1139  {
1140  const Variable & var(this->variable(var_num));
1141 
1142  for (auto & elem : mesh.active_local_element_ptr_range())
1143  {
1144  if (!var.active_on_subdomain(elem->subdomain_id()))
1145  continue;
1146 
1147  // Only count dofs connected to active
1148  // elements on this processor.
1149  const unsigned int n_nodes = elem->n_nodes();
1150 
1151  // First get any new nodal DOFS
1152  for (unsigned int n=0; n<n_nodes; n++)
1153  {
1154  const Node & node = elem->node_ref(n);
1155 
1156  if (node.processor_id() != this->processor_id())
1157  continue;
1158 
1159  const unsigned int n_comp = node.n_comp(sys_num, var_num);
1160  for(unsigned int i=0; i<n_comp; i++)
1161  {
1162  const dof_id_type index = node.dof_number(sys_num,var_num,i);
1163  libmesh_assert (this->local_index(index));
1164 
1165  if constexpr (std::is_same_v<T, dof_id_type>)
1166  {
1167  if (idx == 0 || index > greatest)
1168  { idx++; greatest = index; }
1169  }
1170  else if constexpr (std::is_same_v<T, std::vector<dof_id_type>>)
1171  {
1172  if (idx.empty() || index > idx.back())
1173  idx.push_back(index);
1174  }
1175  }
1176  }
1177 
1178  // Next get any new element DOFS
1179  const unsigned int n_comp = elem->n_comp(sys_num, var_num);
1180  for (unsigned int i=0; i<n_comp; i++)
1181  {
1182  const dof_id_type index = elem->dof_number(sys_num,var_num,i);
1183 
1184  if constexpr (std::is_same_v<T, dof_id_type>)
1185  {
1186  if (idx == 0 || index > greatest)
1187  { idx++; greatest = index; }
1188  }
1189  else if constexpr (std::is_same_v<T, std::vector<dof_id_type>>)
1190  {
1191  if (idx.empty() || index > idx.back())
1192  idx.push_back(index);
1193  }
1194  }
1195  } // done looping over elements
1196 
1197 
1198  // we may have missed assigning DOFs to nodes that we own
1199  // but to which we have no connected elements matching our
1200  // variable restriction criterion. this will happen, for example,
1201  // if variable V is restricted to subdomain S. We may not own
1202  // any elements which live in S, but we may own nodes which are
1203  // *connected* to elements which do. in this scenario these nodes
1204  // will presently have unnumbered DOFs. we need to take care of
1205  // them here since we own them and no other processor will touch them.
1206  for (const auto & node : mesh.local_node_ptr_range())
1207  {
1208  libmesh_assert(node);
1209 
1210  const unsigned int n_comp = node->n_comp(sys_num, var_num);
1211  for (unsigned int i=0; i<n_comp; i++)
1212  {
1213  const dof_id_type index = node->dof_number(sys_num,var_num,i);
1214 
1215  if constexpr (std::is_same_v<T, dof_id_type>)
1216  {
1217  if (idx == 0 || index > greatest)
1218  { idx++; greatest = index; }
1219  }
1220  else if constexpr (std::is_same_v<T, std::vector<dof_id_type>>)
1221  {
1222  if (idx.empty() || index > idx.back())
1223  idx.push_back(index);
1224  }
1225  }
1226  }
1227  }
1228  // Otherwise, count up the SCALAR dofs, if we're on the processor
1229  // that holds this SCALAR variable
1230  else if (this->processor_id() == (this->n_processors()-1))
1231  {
1232  std::vector<dof_id_type> di_scalar;
1233  this->SCALAR_dof_indices(di_scalar,var_num);
1234 
1235  if constexpr (std::is_same_v<T, dof_id_type>)
1236  idx += std::distance(di_scalar.begin(), di_scalar.end());
1237  else if constexpr (std::is_same_v<T, std::vector<dof_id_type>>)
1238  idx.insert(idx.end(), di_scalar.begin(), di_scalar.end());
1239  }
1240 }
MeshBase & mesh
Real distance(const Point &p)
unsigned int sys_number() const
Definition: dof_map.h:2338
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:2603
const Variable & variable(const unsigned int c) const override
Definition: dof_map.h:2356
virtual void clear() override
Free all new memory associated with the object, but restore its original state, with the mesh pointer...
Definition: dof_map.C:867
processor_id_type n_processors() const
const dof_id_type n_nodes
Definition: tecplot_io.C:67
libmesh_assert(ctx)
const FEType & variable_type(const unsigned int i) const
Definition: dof_map.h:2386
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:967

◆ local_variable_indices() [2/2]

template<typename T , std::enable_if_t< std::is_same_v< T, dof_id_type >||std::is_same_v< T, std::vector< dof_id_type >>, int > = 0>
void libMesh::DofMap::local_variable_indices ( T &  idx,
unsigned int  var_num 
) const
inline

If T == dof_id_type, counts, if T == std::vector<dof_id_type>, fills an array of, those dof indices which belong to the given variable number and live on the current processor.

Definition at line 1035 of file dof_map.h.

References _mesh, and local_variable_indices().

1036  { this->local_variable_indices(idx, this->_mesh, var_num); }
void local_variable_indices(T &idx, const MeshBase &mesh, unsigned int var_num) const
If T == dof_id_type, counts, if T == std::vector<dof_id_type>, fills an array of, those dof indices w...
Definition: dof_map.C:1118
MeshBase & _mesh
The mesh that system uses.
Definition: dof_map.h:2133
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.

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

References _dof_constraints, _primal_constraint_values, 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.

3356 {
3357  if (!v)
3358  v = system.solution.get();
3359  NumericVector<Number> & vec = *v;
3360 
3361  // We'll assume the vector is closed
3362  libmesh_assert (vec.closed());
3363 
3364  Real max_absolute_error = 0., max_relative_error = 0.;
3365 
3366  const MeshBase & mesh = system.get_mesh();
3367 
3368  libmesh_assert_equal_to (this, &(system.get_dof_map()));
3369 
3370  // indices on each element
3371  std::vector<dof_id_type> local_dof_indices;
3372 
3373  for (const auto & elem : mesh.active_local_element_ptr_range())
3374  {
3375  this->dof_indices(elem, local_dof_indices);
3376  std::vector<dof_id_type> raw_dof_indices = local_dof_indices;
3377 
3378  // Constraint matrix for each element
3380 
3381  this->build_constraint_matrix (C, local_dof_indices);
3382 
3383  // Continue if the element is unconstrained
3384  if (!C.m())
3385  continue;
3386 
3387  libmesh_assert_equal_to (C.m(), raw_dof_indices.size());
3388  libmesh_assert_equal_to (C.n(), local_dof_indices.size());
3389 
3390  for (auto i : make_range(C.m()))
3391  {
3392  // Recalculate any constrained dof owned by this processor
3393  dof_id_type global_dof = raw_dof_indices[i];
3394  if (this->is_constrained_dof(global_dof) &&
3395  global_dof >= vec.first_local_index() &&
3396  global_dof < vec.last_local_index())
3397  {
3398 #ifndef NDEBUG
3399  DofConstraints::const_iterator
3400  pos = _dof_constraints.find(global_dof);
3401 
3402  libmesh_assert (pos != _dof_constraints.end());
3403 #endif
3404 
3405  Number exact_value = 0;
3406  DofConstraintValueMap::const_iterator rhsit =
3407  _primal_constraint_values.find(global_dof);
3408  if (rhsit != _primal_constraint_values.end())
3409  exact_value = rhsit->second;
3410 
3411  for (auto j : make_range(C.n()))
3412  {
3413  if (local_dof_indices[j] != global_dof)
3414  exact_value += C(i,j) *
3415  vec(local_dof_indices[j]);
3416  }
3417 
3418  max_absolute_error = std::max(max_absolute_error,
3419  std::abs(vec(global_dof) - exact_value));
3420  max_relative_error = std::max(max_relative_error,
3421  std::abs(vec(global_dof) - exact_value)
3422  / std::abs(exact_value));
3423  }
3424  }
3425  }
3426 
3427  return std::pair<Real, Real>(max_absolute_error, max_relative_error);
3428 }
void dof_indices(const Elem *const elem, std::vector< dof_id_type > &di) const
Definition: dof_map.C:2197
MeshBase & mesh
unsigned int m() const
const MeshBase & get_mesh() const
Definition: system.h:2359
Number exact_value(const Point &p, const Parameters &parameters, const std::string &, const std::string &)
This is the MeshBase class.
Definition: mesh_base.h:75
std::unique_ptr< NumericVector< Number > > solution
Data structure to hold solution values.
Definition: system.h:1616
libmesh_assert(ctx)
bool is_constrained_dof(const dof_id_type dof) const
Definition: dof_map.h:2424
DofConstraints _dof_constraints
Data structure containing DOF constraints.
Definition: dof_map.h:2272
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:2274
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:140
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:2375
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 GhostingFunctorIterator gf_begin,
const GhostingFunctorIterator gf_end,
const MeshBase::const_element_iterator elems_begin,
const MeshBase::const_element_iterator elems_end,
processor_id_type  p 
)
staticprivate

Definition at line 1581 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().

1588 {
1589  for (const auto & gf : as_range(gf_begin, gf_end))
1590  {
1591  GhostingFunctor::map_type more_elements_to_ghost;
1592 
1593  libmesh_assert(gf);
1594  (*gf)(elems_begin, elems_end, p, more_elements_to_ghost);
1595 
1596  // A GhostingFunctor should only return active elements, but
1597  // I forgot to *document* that, so let's go as easy as we
1598  // can on functors that return inactive elements.
1599 #if defined(LIBMESH_ENABLE_DEPRECATED) && defined(LIBMESH_ENABLE_AMR)
1600  std::vector<std::pair<const Elem*, const CouplingMatrix*>> children_to_couple;
1601  for (auto it = more_elements_to_ghost.begin();
1602  it != more_elements_to_ghost.end();)
1603  {
1604  const Elem * elem = it->first;
1605  if (!elem->active())
1606  {
1607  libmesh_deprecated();
1608  std::vector<const Elem*> children_to_ghost;
1609  elem->active_family_tree(children_to_ghost,
1610  /*reset=*/ false);
1611  for (const Elem * child : children_to_ghost)
1612  if (child->processor_id() != p)
1613  children_to_couple.emplace_back(child, it->second);
1614 
1615  it = more_elements_to_ghost.erase(it);
1616  }
1617  else
1618  ++it;
1619  }
1620  more_elements_to_ghost.insert(children_to_couple.begin(),
1621  children_to_couple.end());
1622 #endif
1623 
1624  for (const auto & [elem, elem_cm] : more_elements_to_ghost)
1625  {
1626  // At this point we should only have active elements, even
1627  // if we had to fix up gf output to get here.
1628  libmesh_assert(elem->active());
1629 
1630  if (const auto existing_it = elements_to_ghost.find(elem);
1631  existing_it == elements_to_ghost.end())
1632  elements_to_ghost.emplace(elem, elem_cm);
1633  else
1634  {
1635  if (existing_it->second)
1636  {
1637  if (elem_cm)
1638  {
1639  // If this isn't already a temporary
1640  // then we need to make one so we'll
1641  // have a non-const matrix to merge
1642  if (temporary_coupling_matrices.empty() ||
1643  !temporary_coupling_matrices.count(existing_it->second))
1644  {
1645  // Make copy. This just calls the
1646  // compiler-generated copy constructor
1647  // because the CouplingMatrix class does not
1648  // define a custom copy constructor.
1649  auto result_pr = temporary_coupling_matrices.insert(std::make_unique<CouplingMatrix>(*existing_it->second));
1650  existing_it->second = result_pr.first->get();
1651  }
1652 
1653  // Merge elem_cm into existing CouplingMatrix
1654  const_cast<CouplingMatrix &>(*existing_it->second) &= *elem_cm;
1655  }
1656  else // elem_cm == nullptr
1657  {
1658  // Any existing_it matrix merged with a full
1659  // matrix (symbolized as nullptr) gives another
1660  // full matrix (symbolizable as nullptr).
1661 
1662  // So if existing_it->second is a temporary then
1663  // we don't need it anymore; we might as well
1664  // remove it to keep the set of temporaries
1665  // small.
1666  if (const auto temp_it = temporary_coupling_matrices.find(existing_it->second);
1667  temp_it != temporary_coupling_matrices.end())
1668  temporary_coupling_matrices.erase(temp_it);
1669 
1670  existing_it->second = nullptr;
1671  }
1672  }
1673  // else we have a nullptr already, then we have a full
1674  // coupling matrix, already, and merging with anything
1675  // else won't change that, so we're done.
1676  }
1677  }
1678  }
1679 }
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_components()

unsigned int libMesh::DofMap::n_components ( const MeshBase mesh) const
inline
Returns
The total number of scalar components in the system's variables. This will equal n_vars() in the case of all scalar-valued variables. If vector variables are involved, we will need to leverage the mesh

Definition at line 2952 of file dof_map.h.

References _variables, libMesh::Variable::first_scalar_number(), mesh, and libMesh::Variable::n_components().

Referenced by add_variables(), and libMesh::System::n_components().

2953 {
2954  if (_variables.empty())
2955  return 0;
2956 
2957  const Variable & last = _variables.back();
2958  return last.first_scalar_number() + last.n_components(mesh);
2959 }
MeshBase & mesh
std::vector< Variable > _variables
The variables in this system/degree of freedom map.
Definition: dof_map.h:2089

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

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

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

1714 {
1715  parallel_object_only();
1716 
1717  dof_id_type nc_dofs = this->n_local_constrained_dofs();
1718  this->comm().sum(nc_dofs);
1719  return nc_dofs;
1720 }
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 1059 of file dof_map.h.

References _node_constraints.

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

◆ n_dofs() [1/3]

dof_id_type libMesh::DofMapBase::n_dofs ( ) const
inlineinherited
Returns
The total number of degrees of freedom in the problem.

Definition at line 105 of file dof_map_base.h.

References libMesh::DofMapBase::_n_dfs.

Referenced by _dof_indices(), add_constraint_row(), add_neighbors_to_send_list(), distribute_dofs(), libMesh::StaticCondensation::init(), prepare_send_list(), and process_mesh_constraint_rows().

105 { return _n_dfs; }
dof_id_type _n_dfs
Total number of degrees of freedom.
Definition: dof_map_base.h:164

◆ n_dofs() [2/3]

dof_id_type libMesh::DofMapBase::n_dofs
inline
Returns
The total number of degrees of freedom in the problem.

Definition at line 105 of file dof_map_base.h.

105 { return _n_dfs; }
dof_id_type _n_dfs
Total number of degrees of freedom.
Definition: dof_map_base.h:164

◆ n_dofs() [3/3]

dof_id_type libMesh::DofMap::n_dofs ( const unsigned int  vn) const
inline

◆ n_dofs_on_processor()

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

Definition at line 197 of file dof_map_base.h.

References libMesh::DofMapBase::_end_df, and libMesh::DofMapBase::_first_df.

Referenced by libMesh::DofMapBase::n_local_dofs(), and SystemsTest::testProjectMatrix3D().

198 {
199  libmesh_assert_less(proc, _first_df.size());
200  return cast_int<dof_id_type>(_end_df[proc] - _first_df[proc]);
201 }
std::vector< dof_id_type > _first_df
First DOF index on processor p.
Definition: dof_map_base.h:154
std::vector< dof_id_type > _end_df
Last DOF index (plus 1) on processor p.
Definition: dof_map_base.h:159

◆ n_dofs_per_processor()

std::vector<dof_id_type> libMesh::DofMap::n_dofs_per_processor ( const unsigned int  vn) const
inline
Returns
The number of degrees of freedom on each partition for a particular variable vn.

Definition at line 805 of file dof_map.h.

References TIMPI::Communicator::allgather(), libMesh::ParallelObject::comm(), libMesh::DofMapBase::n_local_dofs(), and libMesh::ParallelObject::n_processors().

Referenced by SystemsTest::test100KVariables().

806  {
807  std::vector<dof_id_type> n_local_dofs(this->n_processors(), 0);
808  this->comm().allgather(this->n_local_dofs(vn), n_local_dofs);
809  return n_local_dofs;
810  }
void allgather(const T &send_data, std::vector< T, A > &recv_data) const
const Parallel::Communicator & comm() const
processor_id_type n_processors() const
dof_id_type n_local_dofs() const
Definition: dof_map_base.h:115

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

References _dof_constraints, distance(), libMesh::DofMapBase::end_dof(), and libMesh::DofMapBase::first_dof().

Referenced by libMesh::CondensedEigenSystem::copy_sub_to_super(), libMesh::CondensedEigenSystem::copy_super_to_sub(), and n_constrained_dofs().

1724 {
1725  const DofConstraints::const_iterator lower =
1726  _dof_constraints.lower_bound(this->first_dof()),
1727  upper =
1728  _dof_constraints.lower_bound(this->end_dof());
1729 
1730  return cast_int<dof_id_type>(std::distance(lower, upper));
1731 }
Real distance(const Point &p)
dof_id_type end_dof() const
Definition: dof_map_base.h:83
dof_id_type first_dof() const
Definition: dof_map_base.h:73
DofConstraints _dof_constraints
Data structure containing DOF constraints.
Definition: dof_map.h:2272

◆ n_local_dofs() [1/3]

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

Definition at line 115 of file dof_map_base.h.

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

Referenced by build_sparsity(), libMesh::StaticCondensation::init(), n_dofs(), n_dofs_per_processor(), and process_mesh_constraint_rows().

115 { 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_base.h:197
processor_id_type processor_id() const

◆ n_local_dofs() [2/3]

dof_id_type libMesh::DofMapBase::n_local_dofs
inline
Returns
The number of degrees of freedom on this processor.

Definition at line 115 of file dof_map_base.h.

115 { 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_base.h:197
processor_id_type processor_id() const

◆ n_local_dofs() [3/3]

dof_id_type libMesh::DofMap::n_local_dofs ( const unsigned int  vn) const
inline
Returns
The number of degrees of freedom on this processor for a particular variable vn. This is an O(N) operation on serialized or O(N/Nproc) operation on distributed meshes.

Definition at line 794 of file dof_map.h.

References _mesh, and local_variable_indices().

Referenced by libMesh::PetscDMWrapper::build_sf(), libMesh::PetscDMWrapper::init_petscdm(), libMesh::SparsityPattern::Build::join(), libMesh::SparsityPattern::Build::operator()(), libMesh::SparsityPattern::Build::parallel_sync(), libMesh::PetscDMWrapper::set_point_range_in_section(), libMesh::System::solve_for_unconstrained_dofs(), SystemsTest::testProjectMatrix1D(), and SystemsTest::testProjectMatrix2D().

795  {
796  dof_id_type n;
797  this->local_variable_indices(n, _mesh, vn);
798  return n;
799  }
void local_variable_indices(T &idx, const MeshBase &mesh, unsigned int var_num) const
If T == dof_id_type, counts, if T == std::vector<dof_id_type>, fills an array of, those dof indices w...
Definition: dof_map.C:1118
MeshBase & _mesh
The mesh that system uses.
Definition: dof_map.h:2133
uint8_t dof_id_type
Definition: id_types.h:67

◆ 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::DofMapBase::n_old_dofs ( ) const
inlineinherited
Returns
The total number of degrees of freedom on old_dof_objects

Definition at line 123 of file dof_map_base.h.

References libMesh::DofMapBase::_n_old_dfs.

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

123 { return _n_old_dfs; }
dof_id_type _n_old_dfs
Total number of degrees of freedom on old dof objects.
Definition: dof_map_base.h:171

◆ 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::Partitioner::build_graph(), 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::UnstructuredMesh::copy_nodes_and_elements(), 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::StaticCondensation::init(), libMesh::SystemSubsetBySubdomain::init(), libMesh::PetscDMWrapper::init_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(), n_dofs_per_processor(), 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(), libMesh::MeshBase::print_constraint_rows(), 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 786 of file dof_map.h.

References _n_SCALAR_dofs.

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

786 { 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:2251

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

References _variable_groups.

Referenced by add_variable(), add_variables(), distribute_scalar_dofs(), dof_indices(), has_blocked_representation(), libMesh::System::n_variable_groups(), old_dof_indices(), libMesh::StaticCondensationDofMap::reinit(), and set_nonlocal_dof_objects().

734  { return cast_int<unsigned int>(_variable_groups.size()); }
std::vector< VariableGroup > _variable_groups
The variable groups in this system/degree of freedom map.
Definition: dof_map.h:2094

◆ n_variables()

unsigned int libMesh::DofMap::n_variables ( ) const
inlineoverridevirtual
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...

Implements libMesh::DofMapBase.

Definition at line 736 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(), and var_group_from_var_number().

737  { return cast_int<unsigned int>(_variables.size()); }
std::vector< Variable > _variables
The variables in this system/degree of freedom map.
Definition: dof_map.h:2089

◆ n_vars()

unsigned int libMesh::DofMap::n_vars ( ) const
inline
Returns
The number of variables in the system

Definition at line 2926 of file dof_map.h.

References _variables.

Referenced by add_variable(), add_variables(), allgather_recursive_constraints(), create_dof_constraints(), get_all_variable_numbers(), and libMesh::System::n_vars().

2927 {
2928  return cast_int<unsigned int>(_variables.size());
2929 }
std::vector< Variable > _variables
The variables in this system/degree of freedom map.
Definition: dof_map.h:2089

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

References _node_constraints.

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

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

References _node_constraints.

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

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

References mesh.

Referenced by distribute_dofs().

304 {
305  return mesh.node_ptr(i);
306 }
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 2474 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().

2478 {
2479  const DofObject & old_obj = elem.node_ref(n).get_old_dof_object_ref();
2480  this->_node_dof_indices(elem, n, old_obj, di, vn);
2481 }
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:2487

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

2692 {
2693  LOG_SCOPE("old_dof_indices()", "DofMap");
2694 
2695  libmesh_assert(elem);
2696 
2697  const ElemType type = elem->type();
2698  const unsigned int sys_num = this->sys_number();
2699  const unsigned int n_var_groups = this->n_variable_groups();
2700 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
2701  const bool is_inf = elem->infinite();
2702 #endif
2703 
2704  // If we have dof indices stored on the elem, and there's no chance
2705  // that we only have those indices because we were just p refined,
2706  // then we should have old dof indices too.
2707  libmesh_assert(!elem->has_dofs(sys_num) ||
2708  elem->p_refinement_flag() == Elem::JUST_REFINED ||
2709  elem->get_old_dof_object());
2710 
2711  // Clear the DOF indices vector.
2712  di.clear();
2713 
2714  // Determine the nodes contributing to element elem
2715  std::vector<const Node *> elem_nodes;
2716  const Node * const * nodes_ptr;
2717  unsigned int n_nodes;
2718  if (elem->type() == TRI3SUBDIVISION)
2719  {
2720  // Subdivision surface FE require the 1-ring around elem
2721  const Tri3Subdivision * sd_elem = static_cast<const Tri3Subdivision *>(elem);
2722  MeshTools::Subdivision::find_one_ring(sd_elem, elem_nodes);
2723  nodes_ptr = elem_nodes.data();
2724  n_nodes = cast_int<unsigned int>(elem_nodes.size());
2725  }
2726  else
2727  {
2728  // All other FE use only the nodes of elem itself
2729  nodes_ptr = elem->get_nodes();
2730  n_nodes = elem->n_nodes();
2731  }
2732 
2733  // Get the dof numbers
2734  for (unsigned int vg=0; vg<n_var_groups; vg++)
2735  {
2736  const VariableGroup & var = this->variable_group(vg);
2737  const unsigned int vars_in_group = var.n_variables();
2738 
2739  for (unsigned int vig=0; vig<vars_in_group; vig++)
2740  {
2741  const unsigned int v = var.number(vig);
2742  if ((vn == v) || (vn == libMesh::invalid_uint))
2743  {
2744  if (var.type().family == SCALAR &&
2745  (!elem ||
2746  var.active_on_subdomain(elem->subdomain_id())))
2747  {
2748  // We asked for this variable, so add it to the vector.
2749  std::vector<dof_id_type> di_new;
2750  this->SCALAR_dof_indices(di_new,v,true);
2751  di.insert( di.end(), di_new.begin(), di_new.end());
2752  }
2753  else
2754  if (var.active_on_subdomain(elem->subdomain_id()))
2755  { // Do this for all the variables if one was not specified
2756  // or just for the specified variable
2757 
2758  FEType fe_type = var.type();
2759  const bool add_p_level =
2760 #ifdef LIBMESH_ENABLE_AMR
2761  !_dont_p_refine.count(vg);
2762 #else
2763  false;
2764 #endif
2765  // Increase the polynomial order on p refined elements,
2766  // but make sure you get the right polynomial order for
2767  // the OLD degrees of freedom
2768  int p_adjustment = 0;
2769  if (elem->p_refinement_flag() == Elem::JUST_REFINED)
2770  {
2771  libmesh_assert_greater (elem->p_level(), 0);
2772  p_adjustment = -1;
2773  }
2774  else if (elem->p_refinement_flag() == Elem::JUST_COARSENED)
2775  {
2776  p_adjustment = 1;
2777  }
2778  p_adjustment *= add_p_level;
2779 
2780  // Compute the net amount of "extra" order, including Elem::p_level()
2781  int extra_order = int(add_p_level*elem->p_level()) + p_adjustment;
2782 
2783  const bool extra_hanging_dofs =
2785 
2786  const FEInterface::n_dofs_at_node_ptr ndan =
2787  FEInterface::n_dofs_at_node_function(fe_type, elem);
2788 
2789  // Get the node-based DOF numbers
2790  for (unsigned int n=0; n<n_nodes; n++)
2791  {
2792  const Node * node = nodes_ptr[n];
2793  const DofObject & old_dof_obj = node->get_old_dof_object_ref();
2794 
2795  // There is a potential problem with h refinement. Imagine a
2796  // quad9 that has a linear FE on it. Then, on the hanging side,
2797  // it can falsely identify a DOF at the mid-edge node. This is why
2798  // we call FEInterface instead of node->n_comp() directly.
2799  const unsigned int nc =
2800 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
2801  is_inf ?
2802  FEInterface::n_dofs_at_node(var.type(), extra_order, elem, n) :
2803 #endif
2804  ndan (type, var.type().order + extra_order, n);
2805 
2806  const int n_comp = old_dof_obj.n_comp_group(sys_num,vg);
2807 
2808  // If this is a non-vertex on a hanging node with extra
2809  // degrees of freedom, we use the non-vertex dofs (which
2810  // come in reverse order starting from the end, to
2811  // simplify p refinement)
2812  if (extra_hanging_dofs && !elem->is_vertex(n))
2813  {
2814  const int dof_offset = n_comp - nc;
2815 
2816  // We should never have fewer dofs than necessary on a
2817  // node unless we're getting indices on a parent element
2818  // or a just-coarsened element
2819  if (dof_offset < 0)
2820  {
2821  libmesh_assert(!elem->active() || elem->refinement_flag() ==
2823  di.resize(di.size() + nc, DofObject::invalid_id);
2824  }
2825  else
2826  for (int i=n_comp-1; i>=dof_offset; i--)
2827  {
2828  const dof_id_type d =
2829  old_dof_obj.dof_number(sys_num, vg, vig, i, n_comp);
2830 
2831  // On a newly-expanded subdomain, we
2832  // may have some DoFs that didn't
2833  // exist in the old system, in which
2834  // case we can't assert this:
2835  // libmesh_assert_not_equal_to (d, DofObject::invalid_id);
2836 
2837  di.push_back(d);
2838  }
2839  }
2840  // If this is a vertex or an element without extra hanging
2841  // dofs, our dofs come in forward order coming from the
2842  // beginning. But we still might not have all
2843  // those dofs on the old_dof_obj, in cases
2844  // where a subdomain-restricted variable just
2845  // had its subdomain expanded.
2846  else
2847  {
2848  const unsigned int old_nc =
2849  std::min(static_cast<unsigned int>(n_comp), nc);
2850  for (unsigned int i=0; i != old_nc; ++i)
2851  {
2852  const dof_id_type d =
2853  old_dof_obj.dof_number(sys_num, vg, vig, i, n_comp);
2854 
2855  libmesh_assert_not_equal_to (d, DofObject::invalid_id);
2856 
2857  di.push_back(d);
2858  }
2859  for (unsigned int i=old_nc; i != nc; ++i)
2860  di.push_back(DofObject::invalid_id);
2861  }
2862  }
2863 
2864  // If there are any element-based DOF numbers, get them
2865  const unsigned int nc =
2866  FEInterface::n_dofs_per_elem(fe_type, extra_order, elem);
2867 
2868  if (nc != 0)
2869  {
2870  const DofObject & old_dof_obj = elem->get_old_dof_object_ref();
2871 
2872  const unsigned int n_comp =
2873  old_dof_obj.n_comp_group(sys_num,vg);
2874 
2875  if (old_dof_obj.n_systems() > sys_num &&
2876  nc <= n_comp)
2877  {
2878 
2879  for (unsigned int i=0; i<nc; i++)
2880  {
2881  const dof_id_type d =
2882  old_dof_obj.dof_number(sys_num, vg, vig, i, n_comp);
2883 
2884  di.push_back(d);
2885  }
2886  }
2887  else
2888  {
2889  // We should never have fewer dofs than
2890  // necessary on an element unless we're
2891  // getting indices on a parent element, a
2892  // just-coarsened element ... or a
2893  // subdomain-restricted variable with a
2894  // just-expanded subdomain
2895  // libmesh_assert(!elem->active() || fe_type.family == LAGRANGE ||
2896  // elem->refinement_flag() == Elem::JUST_COARSENED);
2897  di.resize(di.size() + nc, DofObject::invalid_id);
2898  }
2899  }
2900  }
2901  }
2902  } // end loop over variables within group
2903  } // end loop over variable groups
2904 }
static unsigned int n_dofs_per_elem(const unsigned int dim, const FEType &fe_t, const ElemType t)
Definition: fe_interface.C:530
ElemType
Defines an enum for geometric element types.
unsigned int n_variable_groups() const
Definition: dof_map.h:733
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:310
unsigned int sys_number() const
Definition: dof_map.h:2338
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:2603
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 constexpr dof_id_type invalid_id
An invalid id to distinguish an uninitialized DofObject.
Definition: dof_object.h:482
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:2346
static n_dofs_at_node_ptr n_dofs_at_node_function(const unsigned int dim, const FEType &fe_t)
Definition: fe_interface.C:458
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:436
unsigned int(* n_dofs_at_node_ptr)(const ElemType, const Order, const unsigned int)
Definition: fe_interface.h:151
std::unordered_set< unsigned int > _dont_p_refine
A container of variable groups that we should not p-refine.
Definition: dof_map.h:2264
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 1831 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(), libMesh::DofMapBase::n_dofs(), libMesh::ParallelObject::n_processors(), and libMesh::out.

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

1832 {
1833  LOG_SCOPE("prepare_send_list()", "DofMap");
1834 
1835  // Return immediately if there's no ghost data
1836  if (this->n_processors() == 1)
1837  return;
1838 
1839  // Check to see if we have any extra stuff to add to the send_list
1841  {
1842  if (_augment_send_list)
1843  {
1844  libmesh_here();
1845  libMesh::out << "WARNING: You have specified both an extra send list function and object.\n"
1846  << " Are you sure this is what you meant to do??"
1847  << std::endl;
1848  }
1849 
1851  }
1852 
1853  if (_augment_send_list)
1855 
1856  // First sort the send list. After this
1857  // duplicated elements will be adjacent in the
1858  // vector
1859  std::sort(_send_list.begin(), _send_list.end());
1860 
1861  // Now use std::unique to remove duplicate entries
1862  std::vector<dof_id_type>::iterator new_end =
1863  std::unique (_send_list.begin(), _send_list.end());
1864 
1865  // Remove the end of the send_list. Use the "swap trick"
1866  // from Effective STL
1867  std::vector<dof_id_type> (_send_list.begin(), new_end).swap (_send_list);
1868 
1869  // Make sure the send list has nothing invalid in it.
1870  libmesh_assert(_send_list.empty() || _send_list.back() < this->n_dofs());
1871 }
dof_id_type n_dofs() const
Definition: dof_map_base.h:105
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:2152
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:2174
processor_id_type n_processors() const
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:2184
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:2179

◆ 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 2252 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(), and libMesh::System::reinit_constraints().

2254 {
2255  parallel_object_only();
2256 
2257  std::string local_constraints =
2258  this->get_local_constraints(print_nonlocal);
2259 
2260  if (this->processor_id())
2261  {
2262  this->comm().send(0, local_constraints);
2263  }
2264  else
2265  {
2266  os << "Processor 0:\n";
2267  os << local_constraints;
2268 
2269  for (auto p : IntRange<processor_id_type>(1, this->n_processors()))
2270  {
2271  this->comm().receive(p, local_constraints);
2272  os << "Processor " << p << ":\n";
2273  os << local_constraints;
2274  }
2275  }
2276 }
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 2974 of file dof_map.C.

References get_info().

2975 {
2976  os << this->get_info();
2977 }
std::string get_info() const
Gets summary info about the sparsity bandwidth and constraints.
Definition: dof_map.C:2981

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

4341 {
4342  // We've computed our local constraints, but they may depend on
4343  // non-local constraints that we'll need to take into account.
4344  this->allgather_recursive_constraints(mesh);
4345 
4347  {
4348  // Optionally check for constraint loops and throw an error
4349  // if they're detected. We always do this check below in dbg/devel
4350  // mode but here we optionally do it in opt mode as well.
4352  }
4353 
4354  // Adjoints will be constrained where the primal is
4355  // Therefore, we will expand the adjoint_constraint_values
4356  // map whenever the primal_constraint_values map is expanded
4357 
4358  // First, figure out the total number of QoIs
4359  const unsigned int max_qoi_num =
4360  _adjoint_constraint_values.empty() ?
4361  0 : _adjoint_constraint_values.rbegin()->first+1;
4362 
4363  // Create a set containing the DOFs we already depend on
4364  typedef std::set<dof_id_type> RCSet;
4365  RCSet unexpanded_set;
4366 
4367  for (const auto & i : _dof_constraints)
4368  unexpanded_set.insert(i.first);
4369 
4370  while (!unexpanded_set.empty())
4371  for (RCSet::iterator i = unexpanded_set.begin();
4372  i != unexpanded_set.end(); /* nothing */)
4373  {
4374  // If the DOF is constrained
4375  DofConstraints::iterator
4376  pos = _dof_constraints.find(*i);
4377 
4378  libmesh_assert (pos != _dof_constraints.end());
4379 
4380  DofConstraintRow & constraint_row = pos->second;
4381 
4382  DofConstraintValueMap::iterator rhsit =
4383  _primal_constraint_values.find(*i);
4384  Number constraint_rhs = (rhsit == _primal_constraint_values.end()) ?
4385  0 : rhsit->second;
4386 
4387  // A vector of DofConstraintValueMaps for each adjoint variable
4388  std::vector<DofConstraintValueMap::iterator> adjoint_rhs_iterators;
4389  adjoint_rhs_iterators.resize(max_qoi_num);
4390 
4391  // Another to hold the adjoint constraint rhs
4392  std::vector<Number> adjoint_constraint_rhs(max_qoi_num, 0.0);
4393 
4394  // Find and gather recursive constraints for each adjoint variable
4395  for (auto & adjoint_map : _adjoint_constraint_values)
4396  {
4397  const std::size_t q = adjoint_map.first;
4398  adjoint_rhs_iterators[q] = adjoint_map.second.find(*i);
4399 
4400  adjoint_constraint_rhs[q] =
4401  (adjoint_rhs_iterators[q] == adjoint_map.second.end()) ?
4402  0 : adjoint_rhs_iterators[q]->second;
4403  }
4404 
4405  std::vector<dof_id_type> constraints_to_expand;
4406 
4407  for (const auto & item : constraint_row)
4408  if (item.first != *i && this->is_constrained_dof(item.first))
4409  {
4410  unexpanded_set.insert(item.first);
4411  constraints_to_expand.push_back(item.first);
4412  }
4413 
4414  for (const auto & expandable : constraints_to_expand)
4415  {
4416  const Real this_coef = constraint_row[expandable];
4417 
4418  DofConstraints::const_iterator
4419  subpos = _dof_constraints.find(expandable);
4420 
4421  libmesh_assert (subpos != _dof_constraints.end());
4422 
4423  const DofConstraintRow & subconstraint_row = subpos->second;
4424 
4425  for (const auto & item : subconstraint_row)
4426  {
4427  // Assert that the constraint does not form a cycle.
4428  libmesh_assert(item.first != expandable);
4429  constraint_row[item.first] += item.second * this_coef;
4430  }
4431 
4432  if (auto subrhsit = _primal_constraint_values.find(expandable);
4433  subrhsit != _primal_constraint_values.end())
4434  constraint_rhs += subrhsit->second * this_coef;
4435 
4436  // Find and gather recursive constraints for each adjoint variable
4437  for (const auto & adjoint_map : _adjoint_constraint_values)
4438  {
4439  if (auto adjoint_subrhsit = adjoint_map.second.find(expandable);
4440  adjoint_subrhsit != adjoint_map.second.end())
4441  adjoint_constraint_rhs[adjoint_map.first] += adjoint_subrhsit->second * this_coef;
4442  }
4443 
4444  constraint_row.erase(expandable);
4445  }
4446 
4447  if (rhsit == _primal_constraint_values.end())
4448  {
4449  if (constraint_rhs != Number(0))
4450  _primal_constraint_values[*i] = constraint_rhs;
4451  else
4452  _primal_constraint_values.erase(*i);
4453  }
4454  else
4455  {
4456  if (constraint_rhs != Number(0))
4457  rhsit->second = constraint_rhs;
4458  else
4459  _primal_constraint_values.erase(rhsit);
4460  }
4461 
4462  // Finally fill in the adjoint constraints for each adjoint variable if possible
4463  for (auto & adjoint_map : _adjoint_constraint_values)
4464  {
4465  const std::size_t q = adjoint_map.first;
4466 
4467  if(adjoint_rhs_iterators[q] == adjoint_map.second.end())
4468  {
4469  if (adjoint_constraint_rhs[q] != Number(0))
4470  (adjoint_map.second)[*i] = adjoint_constraint_rhs[q];
4471  else
4472  adjoint_map.second.erase(*i);
4473  }
4474  else
4475  {
4476  if (adjoint_constraint_rhs[q] != Number(0))
4477  adjoint_rhs_iterators[q]->second = adjoint_constraint_rhs[q];
4478  else
4479  adjoint_map.second.erase(adjoint_rhs_iterators[q]);
4480  }
4481  }
4482 
4483  if (constraints_to_expand.empty())
4484  i = unexpanded_set.erase(i);
4485  else
4486  ++i;
4487  }
4488 
4489  // In parallel we can't guarantee that nodes/dofs which constrain
4490  // others are on processors which are aware of that constraint, yet
4491  // we need such awareness for sparsity pattern generation. So send
4492  // other processors any constraints they might need to know about.
4493  this->scatter_constraints(mesh);
4494 
4495  // Now that we have our root constraint dependencies sorted out, add
4496  // them to the send_list
4498 }
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:2078
AdjointDofConstraintValues _adjoint_constraint_values
Definition: dof_map.h:2276
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:2272
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:2274
std::map< dof_id_type, Real, std::less< dof_id_type >, Threads::scalable_allocator< std::pair< const dof_id_type, Real > > > DofConstraintRow
A row of the Dof constraint matrix.
Definition: dof_map.h:100

◆ 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 1897 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(), libMesh::DofMapBase::end_dof(), libMesh::FEType::family, libMesh::DofMapBase::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(), libMesh::DofMapBase::n_dofs(), libMesh::DofMapBase::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().

1898 {
1899  // If we already have simple Dirichlet constraints (with right hand
1900  // sides but with no coupling between DoFs) on spline-constrained FE
1901  // nodes, then we'll need a solve to compute the corresponding
1902  // constraints on the relevant spline nodes. (If we already have
1903  // constraints with coupling between DoFs on spline-constrained FE
1904  // nodes, then we'll need to go sit down and cry until we figure out
1905  // how to handle that.)
1906 
1907  const auto & constraint_rows = mesh.get_constraint_rows();
1908 
1909  // This routine is too expensive to use unless we really might
1910  // need it
1911 #ifdef DEBUG
1912  bool constraint_rows_empty = constraint_rows.empty();
1913  this->comm().min(constraint_rows_empty);
1914  libmesh_assert(!constraint_rows_empty);
1915 #endif
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:221
dof_id_type dof_number(const unsigned int s, const unsigned int var, const unsigned int comp) const
Definition: dof_object.h:1032
constraint_rows_type & get_constraint_rows()
Constraint rows accessors.
Definition: mesh_base.h:1709
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
Definition: dof_map.C:2197
dof_id_type n_dofs() const
Definition: dof_map_base.h:105
static constexpr Real TOLERANCE
std::unique_ptr< SparsityPattern::Build > build_sparsity(const MeshBase &mesh, bool calculate_constrained=false, bool use_condensed_system=false) const
Builds a sparsity pattern for matrices using the current degree-of-freedom numbering and coupling...
Definition: dof_map.C:63
This is the base class from which all geometric element types are derived.
Definition: elem.h:94
MeshBase & mesh
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:2338
uint8_t processor_id_type
Definition: id_types.h:104
AdjointDofConstraintValues _adjoint_constraint_values
Definition: dof_map.h:2276
dof_id_type end_dof() const
Definition: dof_map_base.h:83
uint8_t processor_id_type
dof_id_type first_dof() const
Definition: dof_map_base.h:73
const Node & node_ref(const unsigned int i) const
Definition: elem.h:2530
dof_id_type id() const
Definition: dof_object.h:828
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)
unsigned int n_variables() const override
Definition: dof_map.h:736
libmesh_assert(ctx)
bool is_constrained_dof(const dof_id_type dof) const
Definition: dof_map.h:2424
const FEType & variable_type(const unsigned int i) const
Definition: dof_map.h:2386
DofConstraints _dof_constraints
Data structure containing DOF constraints.
Definition: dof_map.h:2272
Storage for DofConstraint right hand sides for a particular problem.
Definition: dof_map.h:120
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:2292
void max(const T &r, T &o, Request &req) const
DofConstraintValueMap _primal_constraint_values
Definition: dof_map.h:2274
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:2502
std::map< dof_id_type, Real, std::less< dof_id_type >, Threads::scalable_allocator< std::pair< const dof_id_type, Real > > > DofConstraintRow
A row of the Dof constraint matrix.
Definition: dof_map.h:100
static std::unique_ptr< NumericVector< T > > build(const Parallel::Communicator &comm, SolverPackage solver_package=libMesh::default_solver_package(), ParallelType parallel_type=AUTOMATIC)
Builds a NumericVector on the processors in communicator comm using the linear solver package specifi...
dof_id_type n_local_dofs() const
Definition: dof_map_base.h:115
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:905
uint8_t dof_id_type
Definition: id_types.h:67
bool local_index(dof_id_type dof_index) const
Definition: dof_map.h:967

◆ 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::MeshFunction::check_found_elem(), 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_scalar_dofs(), libMesh::DistributedMesh::DistributedMesh(), libMesh::DofMapBase::end_dof(), libMesh::DofMapBase::end_old_dof(), libMesh::EnsightIO::EnsightIO(), libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::SubFunctor::find_dofs_to_send(), libMesh::UnstructuredMesh::find_neighbors(), libMesh::DofMapBase::first_dof(), libMesh::DofMapBase::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::RBEIMEvaluation::get_interior_basis_functions_as_vecs(), libMesh::Nemesis_IO_Helper::get_loadbal_param(), get_local_constraints(), libMesh::MeshBase::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(), 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::MeshTools::n_connected_components(), libMesh::MeshBase::n_constraint_rows(), libMesh::BoundaryInfo::n_edge_conds(), libMesh::DofMapBase::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::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(), libMesh::MeshBase::print_constraint_rows(), 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::SimplexRefiner::refine_via_edges(), libMesh::StaticCondensationDofMap::reinit(), 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::testBadGmsh(), BoundaryInfoTest::testBoundaryIDs(), 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::testGmshBCIDOverlap(), MeshInputTest::testGoodGmsh(), MeshInputTest::testGoodSTL(), MeshInputTest::testGoodSTLBinary(), MeshInputTest::testLowOrderEdgeBlocks(), SystemsTest::testProjectMatrix3D(), BoundaryInfoTest::testShellFaceConstraints(), MeshInputTest::testSingleElementImpl(), WriteVecAndScalar::testSolution(), CheckpointIOTest::testSplitter(), MeshInputTest::testTetgenIO(), libMesh::MeshTools::total_weight(), libMesh::NetGenMeshInterface::triangulate(), libMesh::MeshRefinement::uniformly_coarsen(), libMesh::DistributedMesh::update_parallel_id_counts(), libMesh::DTKAdapter::update_variable_values(), libMesh::MeshTools::volume(), libMesh::STLIO::write(), 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,
const std::map< const Node *, std::set< subdomain_id_type >> &  constraining_subdomains 
)

Reinitialize the underlying data structures conformal to the current mesh.

Definition at line 469 of file dof_map.C.

References libMesh::Variable::active_on_subdomain(), libMesh::Utility::enum_to_string(), libMesh::err, libMesh::FEInterface::extra_hanging_dofs(), libMesh::FEType::family, libMesh::OrderWrapper::get_order(), int, libMesh::MeshBase::is_prepared(), 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(), libMesh::VariableGroup::n_variables(), libMesh::FEType::order, libMesh::SCALAR, libMesh::DofObject::set_n_comp_group(), libMesh::DofObject::set_vg_dof_base(), libMesh::Variable::type(), and libMesh::DofObject::vg_dof_base().

Referenced by distribute_dofs().

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

1874 {
1875  this->clear_send_list();
1877 
1878 #ifdef LIBMESH_ENABLE_CONSTRAINTS
1879  // This is assuming that we only need to recommunicate
1880  // the constraints and no new ones have been added since
1881  // a previous call to reinit_constraints.
1882  this->process_constraints(mesh);
1883 #endif
1884  this->prepare_send_list();
1885 }
void clear_send_list()
Clears the _send_list vector.
Definition: dof_map.h:507
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:1683
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:1831

◆ reinit_static_condensation()

void libMesh::DofMap::reinit_static_condensation ( )

Calls reinit on the static condensation map if it exists.

Definition at line 3136 of file dof_map.C.

References _sc.

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

3137 {
3138  if (_sc)
3139  _sc->reinit();
3140 }
std::unique_ptr< StaticCondensationDofMap > _sc
Static condensation class.
Definition: dof_map.h:2331

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

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

5476 {
5477  libmesh_assert_greater(_adjoint_dirichlet_boundaries.size(),
5478  qoi_index);
5479 
5480  auto lam = [&boundary_to_remove](const auto & bdy)
5481  {return bdy->b == boundary_to_remove.b && bdy->variables == boundary_to_remove.variables;};
5482 
5483  auto it = std::find_if(_adjoint_dirichlet_boundaries[qoi_index]->begin(),
5484  _adjoint_dirichlet_boundaries[qoi_index]->end(),
5485  lam);
5486 
5487  // Assert it was actually found and remove it from the vector
5488  libmesh_assert (it != _adjoint_dirichlet_boundaries[qoi_index]->end());
5489  _adjoint_dirichlet_boundaries[qoi_index]->erase(it);
5490 }
libmesh_assert(ctx)
std::vector< std::unique_ptr< DirichletBoundaries > > _adjoint_dirichlet_boundaries
Data structure containing Dirichlet functions.
Definition: dof_map.h:2306

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

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

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

2086 {
2087  auto raw_it = std::find(_algebraic_ghosting_functors.begin(),
2089  &evaluable_functor);
2090 
2091 #ifndef LIBMESH_ENABLE_DEPRECATED
2092  // We shouldn't be trying to remove a functor that isn't there
2094 #else
2095  // Our old API supported trying to remove a functor that isn't there
2096  if (raw_it != _algebraic_ghosting_functors.end())
2097 #endif
2098  _algebraic_ghosting_functors.erase(raw_it);
2099 
2100  // We shouldn't have had two copies of the same functor
2101  libmesh_assert(std::find(_algebraic_ghosting_functors.begin(),
2103  &evaluable_functor) ==
2105 
2106  _mesh.remove_ghosting_functor(evaluable_functor);
2107 
2108  if (const auto it = _shared_functors.find(&evaluable_functor);
2109  it != _shared_functors.end())
2110  _shared_functors.erase(it);
2111 }
void remove_ghosting_functor(GhostingFunctor &ghosting_functor)
Removes a functor which was previously added to the set of ghosting functors.
Definition: mesh_base.C:970
libmesh_assert(ctx)
std::vector< GhostingFunctor * > _algebraic_ghosting_functors
The list of all GhostingFunctor objects to be used when distributing ghosted vectors.
Definition: dof_map.h:2213
MeshBase & _mesh
The mesh that system uses.
Definition: dof_map.h:2133
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:2232

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

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

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

2029 {
2030  auto raw_it = std::find(_coupling_functors.begin(),
2031  _coupling_functors.end(), &coupling_functor);
2032 
2033 #ifndef LIBMESH_ENABLE_DEPRECATED
2034  // We shouldn't be trying to remove a functor that isn't there
2035  libmesh_assert(raw_it != _coupling_functors.end());
2036 #else
2037  // Our old API supported trying to remove a functor that isn't there
2038  if (raw_it != _coupling_functors.end())
2039 #endif
2040  _coupling_functors.erase(raw_it);
2041 
2042  // We shouldn't have had two copies of the same functor
2043  libmesh_assert(std::find(_coupling_functors.begin(),
2044  _coupling_functors.end(),
2045  &coupling_functor) ==
2046  _coupling_functors.end());
2047 
2048  _mesh.remove_ghosting_functor(coupling_functor);
2049 
2050  if (const auto it = _shared_functors.find(&coupling_functor);
2051  it != _shared_functors.end())
2052  _shared_functors.erase(it);
2053 }
void remove_ghosting_functor(GhostingFunctor &ghosting_functor)
Removes a functor which was previously added to the set of ghosting functors.
Definition: mesh_base.C:970
libmesh_assert(ctx)
std::vector< GhostingFunctor * > _coupling_functors
The list of all GhostingFunctor objects to be used when coupling degrees of freedom in matrix sparsit...
Definition: dof_map.h:2226
MeshBase & _mesh
The mesh that system uses.
Definition: dof_map.h:2133
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:2232

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

1985 {
1988 }
DefaultCoupling & default_coupling()
Default coupling functor.
Definition: dof_map.h:378
DefaultCoupling & default_algebraic_ghosting()
Default algebraic ghosting functor.
Definition: dof_map.h:440
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:2028
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:2085

◆ remove_dirichlet_boundary()

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

Removes the specified Dirichlet boundary from the system.

Definition at line 5460 of file dof_map_constraints.C.

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

5461 {
5462  // Find a boundary condition matching the one to be removed
5463  auto lam = [&boundary_to_remove](const auto & bdy)
5464  {return bdy->b == boundary_to_remove.b && bdy->variables == boundary_to_remove.variables;};
5465 
5466  auto it = std::find_if(_dirichlet_boundaries->begin(), _dirichlet_boundaries->end(), lam);
5467 
5468  // Assert it was actually found and remove it from the vector
5469  libmesh_assert (it != _dirichlet_boundaries->end());
5470  _dirichlet_boundaries->erase(it);
5471 }
std::unique_ptr< DirichletBoundaries > _dirichlet_boundaries
Data structure containing Dirichlet functions.
Definition: dof_map.h:2300
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 2603 of file dof_map.C.

References _first_old_scalar_df, _first_scalar_df, libMesh::OrderWrapper::get_order(), libMesh::DofObject::invalid_id, libMesh::libmesh_assert(), libMesh::DofMapBase::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::StaticCondensationDofMap::reinit(), libMesh::Nemesis_IO_Helper::write_nodal_solution(), libMesh::System::write_parallel_data(), and libMesh::System::write_SCALAR_dofs().

2611 {
2612  LOG_SCOPE("SCALAR_dof_indices()", "DofMap");
2613 
2614  libmesh_assert(this->variable(vn).type().family == SCALAR);
2615 
2616 #ifdef LIBMESH_ENABLE_AMR
2617  // If we're asking for old dofs then we'd better have some
2618  if (old_dofs)
2619  libmesh_assert_greater_equal(n_old_dofs(), n_SCALAR_dofs());
2620 
2621  dof_id_type my_idx = old_dofs ?
2622  this->_first_old_scalar_df[vn] : this->_first_scalar_df[vn];
2623 #else
2624  dof_id_type my_idx = this->_first_scalar_df[vn];
2625 #endif
2626 
2627  libmesh_assert_not_equal_to(my_idx, DofObject::invalid_id);
2628 
2629  // The number of SCALAR dofs comes from the variable order
2630  const int n_dofs_vn = this->variable(vn).type().order.get_order();
2631 
2632  di.resize(n_dofs_vn);
2633  for (int i = 0; i != n_dofs_vn; ++i)
2634  di[i] = my_idx++;
2635 }
dof_id_type n_SCALAR_dofs() const
Definition: dof_map.h:786
OrderWrapper order
The approximation order of the element.
Definition: fe_type.h:215
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:2146
const Variable & variable(const unsigned int c) const override
Definition: dof_map.h:2356
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:2259
static constexpr dof_id_type invalid_id
An invalid id to distinguish an uninitialized DofObject.
Definition: dof_object.h:482
libmesh_assert(ctx)
dof_id_type n_old_dofs() const
Definition: dof_map_base.h:123
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:144

◆ scatter_constraints()

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

Sends constraint equations to constraining processors.

Definition at line 4606 of file dof_map_constraints.C.

References _dof_constraints, libMesh::DofMapBase::_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().

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

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

References _send_list, and local_index().

Referenced by all_semilocal_indices().

2640 {
2641  // If it's not in the local indices
2642  if (!this->local_index(dof_index))
2643  {
2644  // and if it's not in the ghost indices, then we're not
2645  // semilocal
2646  if (!std::binary_search(_send_list.begin(), _send_list.end(), dof_index))
2647  return false;
2648  }
2649 
2650  return true;
2651 }
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:2152
bool local_index(dof_id_type dof_index) const
Definition: dof_map.h:967

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

References _constrained_sparsity_construction, and libMesh::libmesh_ignore().

2540 {
2541  // This got only partly finished...
2542  if (use_constraints)
2543  libmesh_not_implemented();
2544 
2545 #ifdef LIBMESH_ENABLE_CONSTRAINTS
2546  _constrained_sparsity_construction = use_constraints;
2547 #endif
2548  libmesh_ignore(use_constraints);
2549 }
bool _constrained_sparsity_construction
This flag indicates whether or not we explicitly take constraint equations into account when computin...
Definition: dof_map.h:2084
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 234 of file dof_map.C.

References _error_on_constraint_loop.

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

235 {
236  _error_on_constraint_loop = error_on_constraint_loop;
237 }
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:2078

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

References set_error_on_constraint_loop().

228 {
229  // This function will eventually be officially libmesh_deprecated();
230  // Call DofMap::set_error_on_constraint_loop() instead.
231  set_error_on_constraint_loop(error_on_cyclic_constraint);
232 }
void set_error_on_constraint_loop(bool error_on_constraint_loop)
Definition: dof_map.C:234

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

References _implicit_neighbor_dofs, and _implicit_neighbor_dofs_initialized.

1888 {
1890  _implicit_neighbor_dofs = implicit_neighbor_dofs;
1891 }
bool _implicit_neighbor_dofs_initialized
Bools to indicate if we override the –implicit_neighbor_dofs commandline options.
Definition: dof_map.h:2315
bool _implicit_neighbor_dofs
Definition: dof_map.h:2316

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

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

References _verify_dirichlet_bc_consistency.

1894 {
1896 }
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:2328

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

2569 {
2570 #ifdef LIBMESH_ENABLE_AMR
2571  if (p_refine)
2572  {
2573  auto it = _dont_p_refine.find(g);
2574  if (it != _dont_p_refine.end())
2575  _dont_p_refine.erase(it);
2576  }
2577  else
2578  _dont_p_refine.insert(g);
2579 #else
2580  libmesh_ignore(g, p_refine);
2581 #endif
2582 }
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:2264

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

References _dont_p_refine, and libMesh::libmesh_ignore().

2586 {
2587 #ifdef LIBMESH_ENABLE_AMR
2588  return !_dont_p_refine.count(g);
2589 #else
2590  libmesh_ignore(g);
2591  return false;
2592 #endif
2593 }
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:2264

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

2604 {
2605 #ifdef LIBMESH_ENABLE_AMR
2606  const auto vg = this->var_group_from_var_number(var);
2607  return !_dont_p_refine.count(vg);
2608 #else
2609  libmesh_ignore(var);
2610  return false;
2611 #endif
2612 }
unsigned int var_group_from_var_number(unsigned int var_num) const
Definition: dof_map.h:2596
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:2264

◆ stash_dof_constraints()

void libMesh::DofMap::stash_dof_constraints ( )
inline

Definition at line 1179 of file dof_map.h.

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

1180  {
1183  }
libmesh_assert(ctx)
DofConstraints _dof_constraints
Data structure containing DOF constraints.
Definition: dof_map.h:2272
DofConstraints _stashed_dof_constraints
Definition: dof_map.h:2272

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

References _dof_constraints, and _stashed_dof_constraints.

1204  {
1206  }
DofConstraints _dof_constraints
Data structure containing DOF constraints.
Definition: dof_map.h:2272
DofConstraints _stashed_dof_constraints
Definition: dof_map.h:2272

◆ sys_number()

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

◆ unstash_dof_constraints()

void libMesh::DofMap::unstash_dof_constraints ( )
inline

Definition at line 1185 of file dof_map.h.

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

1186  {
1189  }
libmesh_assert(ctx)
DofConstraints _dof_constraints
Data structure containing DOF constraints.
Definition: dof_map.h:2272
DofConstraints _stashed_dof_constraints
Definition: dof_map.h:2272

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

270 {
271  matrix.attach_dof_map (*this);
272 
273  // If we've already computed sparsity, then it's too late
274  // to wait for "compute_sparsity" to help with sparse matrix
275  // initialization, and we need to handle this matrix individually
276  if (this->computed_sparsity_already())
277  {
278  libmesh_assert(_sp.get());
279 
280  if (matrix.need_full_sparsity_pattern())
281  {
282  // We'd better have already computed the full sparsity
283  // pattern if we need it here
285 
286  matrix.update_sparsity_pattern (_sp->get_sparsity_pattern());
287  }
288 
289  matrix.attach_sparsity_pattern(*_sp);
290  }
291 }
std::unique_ptr< SparsityPattern::Build > _sp
The sparsity pattern of the global matrix.
Definition: dof_map.h:2245
void attach_sparsity_pattern(const SparsityPattern::Build &sp)
Set a pointer to a sparsity pattern to use.
Definition: sparse_matrix.C:87
bool need_full_sparsity_pattern
Default false; set to true if any attached matrix requires a full sparsity pattern.
Definition: dof_map.h:2238
libmesh_assert(ctx)
bool computed_sparsity_already() const
Returns true iff a sparsity pattern has already been computed.
Definition: dof_map.C:258
void attach_dof_map(const DofMap &dof_map)
Set a pointer to the DofMap to use.
Definition: sparse_matrix.C:77
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 1899 of file dof_map.C.

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

Referenced by build_sparsity(), and clear().

1900 {
1901  // If we were asked on the command line, then we need to
1902  // include sensitivities between neighbor degrees of freedom
1903  bool implicit_neighbor_dofs =
1904  libMesh::on_command_line ("--implicit-neighbor-dofs");
1905 
1906  // If the user specifies --implicit-neighbor-dofs 0, then
1907  // presumably he knows what he is doing and we won't try to
1908  // automatically turn it on even when all the variables are
1909  // discontinuous.
1910  if (implicit_neighbor_dofs)
1911  {
1912  // No flag provided defaults to 'true'
1913  int flag = 1;
1914  flag = libMesh::command_line_next ("--implicit-neighbor-dofs", flag);
1915 
1916  if (!flag)
1917  {
1918  // The user said --implicit-neighbor-dofs 0, so he knows
1919  // what he is doing and really doesn't want it.
1920  return false;
1921  }
1922  }
1923 
1924  // Possibly override the commandline option, if set_implicit_neighbor_dofs
1925  // has been called.
1927  {
1928  implicit_neighbor_dofs = _implicit_neighbor_dofs;
1929 
1930  // Again, if the user explicitly says implicit_neighbor_dofs = false,
1931  // then we return here.
1932  if (!implicit_neighbor_dofs)
1933  return false;
1934  }
1935 
1936  // Look at all the variables in this system. If every one is
1937  // discontinuous then the user must be doing DG/FVM, so be nice
1938  // and force implicit_neighbor_dofs=true.
1939  {
1940  bool all_discontinuous_dofs = true;
1941 
1942  // We may call this method even without ever having initialized our data
1943  for (auto var : index_range(this->_variables))
1945  all_discontinuous_dofs = false;
1946 
1947  if (all_discontinuous_dofs)
1948  implicit_neighbor_dofs = true;
1949  }
1950 
1951  return implicit_neighbor_dofs;
1952 }
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:1149
bool _implicit_neighbor_dofs_initialized
Bools to indicate if we override the –implicit_neighbor_dofs commandline options.
Definition: dof_map.h:2315
bool _implicit_neighbor_dofs
Definition: dof_map.h:2316
const FEType & variable_type(const unsigned int i) const
Definition: dof_map.h:2386
static FEContinuity get_continuity(const FEType &fe_type)
Returns the input FEType&#39;s FEContinuity based on the underlying FEFamily and potentially the Order...
std::vector< Variable > _variables
The variables in this system/degree of freedom map.
Definition: dof_map.h:2089
bool on_command_line(std::string arg)
Definition: libmesh.C:1058
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:117

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

2597 {
2598  libmesh_assert(var_num < n_variables());
2599  return libmesh_map_find(_var_to_vg, var_num);
2600 }
std::unordered_map< unsigned int, unsigned int > _var_to_vg
A map from variable number to variable group number.
Definition: dof_map.h:2104
unsigned int n_variables() const override
Definition: dof_map.h:736
libmesh_assert(ctx)

◆ variable()

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

Implements libMesh::DofMapBase.

Definition at line 2356 of file dof_map.h.

References _variables.

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

2357 {
2358  libmesh_assert_less (c, _variables.size());
2359 
2360  return _variables[c];
2361 }
std::vector< Variable > _variables
The variables in this system/degree of freedom map.
Definition: dof_map.h:2089

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

References _variable_groups.

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

2347 {
2348  libmesh_assert_less (g, _variable_groups.size());
2349 
2350  return _variable_groups[g];
2351 }
std::vector< VariableGroup > _variable_groups
The variable groups in this system/degree of freedom map.
Definition: dof_map.h:2094

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

References _variable_groups.

2377 {
2378  libmesh_assert_less (vg, _variable_groups.size());
2379 
2380  return _variable_groups[vg].type().order;
2381 }
std::vector< VariableGroup > _variable_groups
The variable groups in this system/degree of freedom map.
Definition: dof_map.h:2094

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

References _variable_groups.

2397 {
2398  libmesh_assert_less (vg, _variable_groups.size());
2399 
2400  return _variable_groups[vg].type();
2401 }
std::vector< VariableGroup > _variable_groups
The variable groups in this system/degree of freedom map.
Definition: dof_map.h:2094

◆ variable_name()

const std::string & libMesh::DofMap::variable_name ( const unsigned int  i) const
inline
Returns
The name of variable i.

Definition at line 2932 of file dof_map.h.

References _variables.

Referenced by add_variable(), add_variables(), and libMesh::System::variable_name().

2933 {
2934  libmesh_assert_less (i, _variables.size());
2935 
2936  return _variables[i].name();
2937 }
std::vector< Variable > _variables
The variables in this system/degree of freedom map.
Definition: dof_map.h:2089

◆ variable_number()

unsigned int libMesh::DofMap::variable_number ( std::string_view  var) const
inline
Returns
The variable number associated with the user-specified variable named var.

Definition at line 2980 of file dof_map.h.

References _variable_numbers, _variables, and libMesh::Quality::name().

Referenced by create_dof_constraints(), libMesh::System::variable_number(), and variable_type().

2981 {
2982  auto var_num = libmesh_map_find(_variable_numbers, var);
2983  libmesh_assert_equal_to(_variables[var_num].name(), var);
2984  return var_num;
2985 }
std::string name(const ElemQuality q)
This function returns a string containing some name for q.
Definition: elem_quality.C:42
std::map< std::string, unsigned int, std::less<> > _variable_numbers
The variable numbers corresponding to user-specified names, useful for name-based lookups...
Definition: dof_map.h:2110
std::vector< Variable > _variables
The variables in this system/degree of freedom map.
Definition: dof_map.h:2089

◆ variable_order()

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

Definition at line 2366 of file dof_map.h.

References _variables.

2367 {
2368  libmesh_assert_less (c, _variables.size());
2369 
2370  return _variables[c].type().order;
2371 }
std::vector< Variable > _variables
The variables in this system/degree of freedom map.
Definition: dof_map.h:2089

◆ variable_scalar_number()

unsigned int libMesh::DofMap::variable_scalar_number ( unsigned int  var_num,
unsigned int  component 
) const
inline
Returns
An index, starting from 0 for the first component of the first variable, and incrementing for each component of each (potentially vector-valued) variable in the system in order. For systems with only scalar-valued variables, this will be the same as var_num

Irony: currently our only non-scalar-valued variable type is SCALAR.

Definition at line 2963 of file dof_map.h.

References _variables.

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

2965 {
2966  return _variables[var_num].first_scalar_number() + component;
2967 }
std::vector< Variable > _variables
The variables in this system/degree of freedom map.
Definition: dof_map.h:2089

◆ variable_type() [1/2]

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

Definition at line 2386 of file dof_map.h.

References _variables.

Referenced by libMesh::ExactSolution::_compute_error(), libMesh::UniformRefinementEstimator::_estimate_error(), libMesh::MeshFunction::_gradient_on_elem(), add_variable(), add_variables(), LinearElasticity::assemble(), AssembleOptimization::assemble_A_and_F(), assemble_elasticity(), assemble_mass(), assemble_matrices(), assemble_poisson(), 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::SmoothnessEstimator::EstimateSmoothness::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(), use_coupled_neighbor_dofs(), and libMesh::System::variable_type().

2387 {
2388  libmesh_assert_less (c, _variables.size());
2389 
2390  return _variables[c].type();
2391 }
std::vector< Variable > _variables
The variables in this system/degree of freedom map.
Definition: dof_map.h:2089

◆ variable_type() [2/2]

const FEType & libMesh::DofMap::variable_type ( std::string_view  var) const
inline
Returns
The finite element type for variable var.

Definition at line 2970 of file dof_map.h.

References _variables, and variable_number().

2971 {
2972  return _variables[this->variable_number(var)].type();
2973 }
std::vector< Variable > _variables
The variables in this system/degree of freedom map.
Definition: dof_map.h:2089
unsigned int variable_number(std::string_view var) const
Definition: dof_map.h:2980

Friends And Related Function Documentation

◆ SparsityPattern::Build

friend class SparsityPattern::Build
friend

Definition at line 2309 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 2306 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::vector<GhostingFunctor *> libMesh::DofMap::_algebraic_ghosting_functors
private

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

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

Keep these in a vector so any parallel computation is done in the same order on all processors.

Definition at line 2213 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().

◆ _array_variables

std::vector<std::pair<unsigned int, unsigned int> > libMesh::DofMap::_array_variables
private

Array variable information storage.

For a given array "variable", the first member of the pair denotes the first variable number present in the array variable and the second member of the pair denotes the last variable number present in the array variables plus one

Definition at line 2117 of file dof_map.h.

Referenced by add_variable_array(), clear(), and get_variable_array().

◆ _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 2174 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 2157 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 2084 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::vector<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 refer these functors to the MeshBase, too, so any dofs coupled to local dofs will live on geometrically ghosted elements.

Definition at line 2226 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 2192 of file dof_map.h.

Referenced by clear(), default_coupling(), DofMap(), 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 2200 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 2300 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 1741 of file dof_map.h.

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

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

Referenced by _dof_indices(), _node_dof_indices(), old_dof_indices(), 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::DofMapBase::_end_df
protectedinherited

◆ _end_old_df

std::vector<dof_id_type> libMesh::DofMapBase::_end_old_df
protectedinherited

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

Definition at line 181 of file dof_map_base.h.

Referenced by clear(), and libMesh::DofMapBase::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 2078 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 2184 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 2179 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 2169 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 2162 of file dof_map.h.

Referenced by attach_extra_sparsity_function(), and build_sparsity().

◆ _first_df

std::vector<dof_id_type> libMesh::DofMapBase::_first_df
protectedinherited

◆ _first_old_df

std::vector<dof_id_type> libMesh::DofMapBase::_first_old_df
protectedinherited

First old DOF index on processor p.

Definition at line 176 of file dof_map_base.h.

Referenced by clear(), and libMesh::DofMapBase::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 2259 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 2146 of file dof_map.h.

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

◆ _identify_variable_groups

bool libMesh::DofMap::_identify_variable_groups = true
private

true when VariableGroup structures should be automatically identified, false otherwise.

Defaults to true.

Definition at line 2123 of file dof_map.h.

Referenced by identify_variable_groups().

◆ _implicit_neighbor_dofs

bool libMesh::DofMap::_implicit_neighbor_dofs
private

Definition at line 2316 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 2315 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 2140 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::DofMapBase::_n_dfs
protectedinherited

Total number of degrees of freedom.

Definition at line 164 of file dof_map_base.h.

Referenced by libMesh::DofMapBase::clear(), and libMesh::DofMapBase::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::DofMapBase::_n_old_dfs
protectedinherited

Total number of degrees of freedom on old dof objects.

Definition at line 171 of file dof_map_base.h.

Referenced by clear(), and libMesh::DofMapBase::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 2251 of file dof_map.h.

Referenced by distribute_scalar_dofs(), and n_SCALAR_dofs().

◆ _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 2292 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

◆ _sc

std::unique_ptr<StaticCondensationDofMap> libMesh::DofMap::_sc
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 2152 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 2232 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 2245 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 2128 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 2104 of file dof_map.h.

Referenced by add_variable(), add_variables(), array_dof_indices(), 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 2099 of file dof_map.h.

Referenced by add_variable(), add_variables(), clear(), and dof_indices().

◆ _variable_groups

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

The variable groups in this system/degree of freedom map.

Definition at line 2094 of file dof_map.h.

Referenced by add_variable(), add_variables(), array_dof_indices(), clear(), n_variable_groups(), variable_group(), variable_group_order(), and variable_group_type().

◆ _variable_numbers

std::map<std::string, unsigned int, std::less<> > libMesh::DofMap::_variable_numbers
private

The variable numbers corresponding to user-specified names, useful for name-based lookups.

Definition at line 2110 of file dof_map.h.

Referenced by add_variable(), add_variables(), get_all_variable_numbers(), has_variable(), and variable_number().

◆ _variables

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

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

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


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