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)
 Set whether the given variable group should be p-refined on a p-refined Elem. 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 ()
 
const StaticCondensationDofMapget_static_condensation () const
 
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...
 
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 1999 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 1916 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:2101
bool _implicit_neighbor_dofs_initialized
Bools to indicate if we override the –implicit_neighbor_dofs commandline options.
Definition: dof_map.h:2317
const unsigned int _sys_number
The number of the system we manage DOFs for.
Definition: dof_map.h:2135
bool _implicit_neighbor_dofs
Definition: dof_map.h:2318
bool _error_on_constraint_loop
This flag indicates whether or not we do an opt-mode check for the presence of constraint loops...
Definition: dof_map.h:2085
void * _extra_sparsity_context
A pointer associated with the extra sparsity that can optionally be passed in.
Definition: dof_map.h:2176
std::unique_ptr< StaticCondensationDofMap > _sc
Static condensation class.
Definition: dof_map.h:2333
std::vector< dof_id_type > _send_list
A list containing all the global DOF indices that affect the solution on my processor.
Definition: dof_map.h:2159
MeshBase & mesh
std::unique_ptr< DirichletBoundaries > _dirichlet_boundaries
Data structure containing Dirichlet functions.
Definition: dof_map.h:2302
void add_coupling_functor(GhostingFunctor &coupling_functor, bool to_mesh=true)
Adds a functor which can specify coupling requirements for creation of sparse matrices.
Definition: dof_map.C:2005
std::vector< dof_id_type > _first_scalar_df
First DOF index for SCALAR variable v, or garbage for non-SCALAR variable v.
Definition: dof_map.h:2153
AdjointDofConstraintValues _adjoint_constraint_values
Definition: dof_map.h:2278
bool _constrained_sparsity_construction
This flag indicates whether or not we explicitly take constraint equations into account when computin...
Definition: dof_map.h:2091
AugmentSendList * _augment_send_list
Function object to call to add extra entries to the send list.
Definition: dof_map.h:2181
bool need_full_sparsity_pattern
Default false; set to true if any attached matrix requires a full sparsity pattern.
Definition: dof_map.h:2245
std::vector< dof_id_type > _first_old_scalar_df
First old DOF index for SCALAR variable v, or garbage for non-SCALAR variable v.
Definition: dof_map.h:2266
void(* _extra_sparsity_function)(SparsityPattern::Graph &, std::vector< dof_id_type > &n_nz, std::vector< dof_id_type > &n_oz, void *)
A function pointer to a function to call to add extra entries to the sparsity pattern.
Definition: dof_map.h:2169
dof_id_type _n_SCALAR_dofs
The total number of SCALAR dofs associated to all SCALAR variables.
Definition: dof_map.h:2258
DofConstraints _dof_constraints
Data structure containing DOF constraints.
Definition: dof_map.h:2274
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:2191
std::vector< SparseMatrix< Number > *> _matrices
Additional matrices handled by this object.
Definition: dof_map.h:2147
std::vector< std::unique_ptr< DirichletBoundaries > > _adjoint_dirichlet_boundaries
Data structure containing Dirichlet functions.
Definition: dof_map.h:2308
std::unique_ptr< PeriodicBoundaries > _periodic_boundaries
Data structure containing periodic boundaries.
Definition: dof_map.h:2294
bool _verify_dirichlet_bc_consistency
Flag which determines whether we should do some additional checking of the consistency of the Dirichl...
Definition: dof_map.h:2330
std::unique_ptr< DefaultCoupling > _default_coupling
The default coupling GhostingFunctor, used to implement standard libMesh sparsity pattern constructio...
Definition: dof_map.h:2199
DofConstraintValueMap _primal_constraint_values
Definition: dof_map.h:2276
std::vector< Variable > _variables
The variables in this system/degree of freedom map.
Definition: dof_map.h:2096
DofConstraints _stashed_dof_constraints
Definition: dof_map.h:2274
SparsityPattern::AugmentSparsityPattern * _augment_sparsity_pattern
Function object to call to add extra entries to the sparsity pattern.
Definition: dof_map.h:2164
void(* _extra_send_list_function)(std::vector< dof_id_type > &, void *)
A function pointer to a function to call to add extra entries to the send list.
Definition: dof_map.h:2186
MeshBase & _mesh
The mesh that system uses.
Definition: dof_map.h:2140
std::unique_ptr< DefaultCoupling > _default_evaluating
The default algebraic GhostingFunctor, used to implement standard libMesh send_list construction...
Definition: dof_map.h:2207
std::vector< unsigned int > _variable_group_numbers
The variable group number for each variable.
Definition: dof_map.h:2106
void add_algebraic_ghosting_functor(GhostingFunctor &evaluable_functor, bool to_mesh=true)
Adds a functor which can specify algebraic ghosting requirements for use with distributed vectors...
Definition: dof_map.C:2062
NodeConstraints _node_constraints
Data structure containing DofObject constraints.
Definition: dof_map.h:2285

◆ ~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:1093
virtual void clear() override
Free all new memory associated with the object, but restore its original state, with the mesh pointer...
Definition: dof_map.C:871
std::unique_ptr< DefaultCoupling > _default_coupling
The default coupling GhostingFunctor, used to implement standard libMesh sparsity pattern constructio...
Definition: dof_map.h:2199
MeshBase & _mesh
The mesh that system uses.
Definition: dof_map.h:2140
std::unique_ptr< DefaultCoupling > _default_evaluating
The default algebraic GhostingFunctor, used to implement standard libMesh send_list construction...
Definition: dof_map.h:2207

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

References n_nodes.

Referenced by dof_indices().

2586 {
2587  _dof_indices(elem,
2588  p_level,
2589  di,
2590  vg,
2591  vig,
2592  nodes,
2593  n_nodes,
2594  v,
2595 #ifdef DEBUG
2596  tot_size,
2597 #endif
2598  [](const Elem &,
2599  unsigned int,
2600  unsigned int,
2601  std::vector<dof_id_type> & functor_di,
2602  const dof_id_type dof) { functor_di.push_back(dof); });
2603 }
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:2573
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 2619 of file dof_map.h.

References 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::FEType::p_refinement, libMesh::SUBDIVISION, libMesh::Elem::subdomain_id(), sys_number(), libMesh::Variable::type(), libMesh::Elem::type(), libMesh::DofObject::var_to_vg_and_offset(), and variable_group().

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

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

Referenced by dof_indices(), and old_dof_indices().

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

References _adjoint_constraint_values, and is_constrained_dof().

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

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

References _adjoint_dirichlet_boundaries.

5444 {
5445  unsigned int old_size = cast_int<unsigned int>
5447  for (unsigned int i = old_size; i <= qoi_index; ++i)
5448  _adjoint_dirichlet_boundaries.push_back(std::make_unique<DirichletBoundaries>());
5449 
5450  // Make copy of DirichletBoundary, owned by _adjoint_dirichlet_boundaries
5451  _adjoint_dirichlet_boundaries[qoi_index]->push_back
5452  (std::make_unique<DirichletBoundary>(dirichlet_boundary));
5453 }
std::vector< std::unique_ptr< DirichletBoundaries > > _adjoint_dirichlet_boundaries
Data structure containing Dirichlet functions.
Definition: dof_map.h:2308

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

2064 {
2065  // We used to implicitly support duplicate inserts to std::set
2066 #ifdef LIBMESH_ENABLE_DEPRECATED
2068  (std::remove(_algebraic_ghosting_functors.begin(),
2070  &evaluable_functor),
2072 #endif
2073 
2074  // We shouldn't have two copies of the same functor
2075  libmesh_assert(std::find(_algebraic_ghosting_functors.begin(),
2077  &evaluable_functor) ==
2079 
2080  _algebraic_ghosting_functors.push_back(&evaluable_functor);
2081  evaluable_functor.set_mesh(&_mesh);
2082  if (to_mesh)
2083  _mesh.add_ghosting_functor(evaluable_functor);
2084 }
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:2220
MeshBase & _mesh
The mesh that system uses.
Definition: dof_map.h:2140
void add_ghosting_functor(GhostingFunctor &ghosting_functor)
Adds a functor which can specify ghosting requirements for use on distributed meshes.
Definition: mesh_base.C:1071

◆ 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:2239
void add_algebraic_ghosting_functor(GhostingFunctor &evaluable_functor, bool to_mesh=true)
Adds a functor which can specify algebraic ghosting requirements for use with distributed vectors...
Definition: dof_map.C:2062

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

2184 {
2185  // Optionally allow the user to overwrite constraints. Defaults to false.
2186  libmesh_error_msg_if(forbid_constraint_overwrite && this->is_constrained_dof(dof_number),
2187  "ERROR: DOF " << dof_number << " was already constrained!");
2188 
2189  libmesh_assert_less(dof_number, this->n_dofs());
2190 
2191  // There is an implied "1" on the diagonal of the constraint row, and the user
2192  // should not try to manually set _any_ value on the diagonal.
2193  libmesh_assert_msg(!constraint_row.count(dof_number),
2194  "Error: constraint_row for dof " << dof_number <<
2195  " should not contain an entry for dof " << dof_number);
2196 
2197 #ifndef NDEBUG
2198  for (const auto & pr : constraint_row)
2199  libmesh_assert_less(pr.first, this->n_dofs());
2200 #endif
2201 
2202  // Store the constraint_row in the map
2203  _dof_constraints.insert_or_assign(dof_number, constraint_row);
2204 
2205  std::pair<DofConstraintValueMap::iterator, bool> rhs_it =
2206  _primal_constraint_values.emplace(dof_number, constraint_rhs);
2207  if (!rhs_it.second)
2208  rhs_it.first->second = constraint_rhs;
2209 }
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:2426
DofConstraints _dof_constraints
Data structure containing DOF constraints.
Definition: dof_map.h:2274
DofConstraintValueMap _primal_constraint_values
Definition: dof_map.h:2276

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

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

Referenced by process_constraints().

5312 {
5313  // This function must be run on all processors at once
5314  parallel_object_only();
5315 
5316  // Return immediately if there's nothing to gather
5317  if (this->n_processors() == 1)
5318  return;
5319 
5320  // We might get to return immediately if none of the processors
5321  // found any constraints
5322  unsigned int has_constraints = !_dof_constraints.empty();
5323  this->comm().max(has_constraints);
5324  if (!has_constraints)
5325  return;
5326 
5327  auto add_row = [this](const DofConstraintRow & constraint_row) {
5328  for (const auto & j : constraint_row)
5329  {
5330  dof_id_type constraint_dependency = j.first;
5331 
5332  // No point in adding one of our own dofs to the send_list
5333  if (this->local_index(constraint_dependency))
5334  continue;
5335 
5336  _send_list.push_back(constraint_dependency);
5337  }
5338  };
5339 
5340  // We usually only need dependencies of our own constrained dofs
5341  for (const auto & [constrained_dof, constraint_row] : _dof_constraints)
5342  if (this->local_index(constrained_dof))
5343  add_row(constraint_row);
5344 
5345  // If we only need constraint DoFs constraining DoFs which are
5346  // algebraically local, we're done.
5347  if (!this->has_static_condensation())
5348  return;
5349 
5350  // If we use StaticCondensation, though, we may need constraint DoFs
5351  // constraining DoFs which are not local (they're on someone else's
5352  // node) but which are supported on local elements. Let's get those
5353  // too if we have to.
5354  //
5355  // We'll potentially be hitting the same constrained DoFs from
5356  // multiple directions.
5357  std::unordered_set<dof_id_type> extra_dependencies;
5358  for (auto & elem : this->get_static_condensation().mesh().active_local_element_ptr_range())
5359  {
5360  std::vector<dof_id_type> di;
5361  this->dof_indices (elem, di);
5362  for (const auto & dof_id : di)
5363  if (!this->local_index(dof_id))
5364  if (auto pos = _dof_constraints.find(dof_id);
5365  pos != _dof_constraints.end())
5366  add_row(pos->second);
5367  }
5368 }
void dof_indices(const Elem *const elem, std::vector< dof_id_type > &di) const
Definition: dof_map.C:2201
std::vector< dof_id_type > _send_list
A list containing all the global DOF indices that affect the solution on my processor.
Definition: dof_map.h:2159
MeshBase & mesh
const Parallel::Communicator & comm() const
processor_id_type n_processors() const
bool has_static_condensation() const
Checks whether we have static condensation.
Definition: dof_map.h:1797
StaticCondensationDofMap & get_static_condensation()
Definition: dof_map.h:2859
DofConstraints _dof_constraints
Data structure containing DOF constraints.
Definition: dof_map.h:2274
void max(const T &r, T &o, Request &req) 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
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 2005 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().

2007 {
2008  // We used to implicitly support duplicate inserts to std::set
2009 #ifdef LIBMESH_ENABLE_DEPRECATED
2010  _coupling_functors.erase
2011  (std::remove(_coupling_functors.begin(),
2012  _coupling_functors.end(),
2013  &coupling_functor),
2014  _coupling_functors.end());
2015 #endif
2016 
2017  // We shouldn't have two copies of the same functor
2018  libmesh_assert(std::find(_coupling_functors.begin(),
2019  _coupling_functors.end(),
2020  &coupling_functor) ==
2021  _coupling_functors.end());
2022 
2023  _coupling_functors.push_back(&coupling_functor);
2024  coupling_functor.set_mesh(&_mesh);
2025  if (to_mesh)
2026  _mesh.add_ghosting_functor(coupling_functor);
2027 }
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:2233
MeshBase & _mesh
The mesh that system uses.
Definition: dof_map.h:2140
void add_ghosting_functor(GhostingFunctor &ghosting_functor)
Adds a functor which can specify ghosting requirements for use on distributed meshes.
Definition: mesh_base.C:1071

◆ 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:2005
std::map< GhostingFunctor *, std::shared_ptr< GhostingFunctor > > _shared_functors
Hang on to references to any GhostingFunctor objects we were passed in shared_ptr form...
Definition: dof_map.h:2239

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

1997 {
1998  this->add_coupling_functor(this->default_coupling());
2000 }
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:2005
void add_algebraic_ghosting_functor(GhostingFunctor &evaluable_functor, bool to_mesh=true)
Adds a functor which can specify algebraic ghosting requirements for use with distributed vectors...
Definition: dof_map.C:2062

◆ 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 5436 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(), BoundaryInfoTest::testShellFaceConstraints(), DisjointNeighborTest::testTempJump(), and DisjointNeighborTest::testTempJumpRefine().

5437 {
5438  _dirichlet_boundaries->push_back(std::make_unique<DirichletBoundary>(dirichlet_boundary));
5439 }
std::unique_ptr< DirichletBoundaries > _dirichlet_boundaries
Data structure containing Dirichlet functions.
Definition: dof_map.h:2302

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

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

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

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

5557 {
5558  auto inverse_boundary = periodic_boundary.clone(PeriodicBoundaryBase::INVERSE);
5559  this->add_periodic_boundary(periodic_boundary, *inverse_boundary);
5560 }
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 5564 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.

5566 {
5567  libmesh_assert_equal_to (boundary.myboundary, inverse_boundary.pairedboundary);
5568  libmesh_assert_equal_to (boundary.pairedboundary, inverse_boundary.myboundary);
5569  libmesh_assert(boundary.get_variables() == inverse_boundary.get_variables());
5570 
5571  // See if we already have a periodic boundary associated myboundary...
5572  PeriodicBoundaryBase * existing_boundary =
5573  _periodic_boundaries->boundary(boundary.myboundary);
5574 
5575  if (!existing_boundary)
5576  {
5577  // ...if not, clone the inputs and add them to the
5578  // PeriodicBoundaries object.
5579  // These will be cleaned up automatically in the
5580  // _periodic_boundaries destructor.
5581  _periodic_boundaries->emplace(boundary.myboundary, boundary.clone());
5582  _periodic_boundaries->emplace(inverse_boundary.myboundary, inverse_boundary.clone());
5583  }
5584  else
5585  {
5586  // ...otherwise, merge this object's variable IDs with the
5587  // existing boundary object's.
5588  existing_boundary->merge(boundary);
5589 
5590  // Do the same merging process for the inverse boundary. The
5591  // inverse had better already exist!
5592  PeriodicBoundaryBase * existing_inverse_boundary =
5593  _periodic_boundaries->boundary(boundary.pairedboundary);
5594  libmesh_assert(existing_inverse_boundary);
5595  existing_inverse_boundary->merge(inverse_boundary);
5596 
5597  // If we had to merge different *types* of boundaries then
5598  // something likely has gone wrong.
5599 #ifdef LIBMESH_HAVE_RTTI
5600  // typeid needs to be given references, not just pointers, to
5601  // return a derived class name.
5602  libmesh_assert(typeid(boundary) == typeid(*existing_boundary));
5603  libmesh_assert(typeid(inverse_boundary) == typeid(*existing_inverse_boundary));
5604 #endif
5605  }
5606 }
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:2294
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 3146 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().

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

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

References _array_variables, and add_variables().

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

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

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

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

◆ 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:2220

◆ 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:2220

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

References semilocal_index().

Referenced by is_evaluable().

2661 {
2662  // We're all semilocal unless we find a counterexample
2663  for (const auto & di : dof_indices_in)
2664  if (!this->semilocal_index(di))
2665  return false;
2666 
2667  return true;
2668 }
bool semilocal_index(dof_id_type dof_index) const
Definition: dof_map.C:2644

◆ allgather_recursive_constraints()

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

Gathers constraint equation dependencies from other processors.

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

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

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

References dof_indices().

Referenced by array_dof_indices().

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

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

References array_dof_indices(), and dof_indices().

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

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

2893 {
2894  const auto [begin, end] = this->get_variable_array(vn);
2895  functor(di, begin);
2896 
2897  const unsigned int count = end - begin;
2898  // We make count, which could be >> ntest, the inner index in hopes of vectorization
2899  if (count > 1)
2900  {
2901  const dof_id_type component_size = di.size();
2902  di.resize(count * component_size);
2903 
2904  const auto pack_container = [&di,
2905  component_size](const unsigned int j,
2906  const std::vector<dof_id_type> & j_dof_indices,
2907  const unsigned int stride) {
2908  if (&j_dof_indices != &di)
2909  libmesh_assert(j_dof_indices.size() == component_size);
2910  for (const auto i : make_range(component_size))
2911  di[j * component_size + i] = j_dof_indices[i] + stride * j;
2912  };
2913  pack_container(0, di, 0);
2914 
2915  const auto & fe_type = _variable_groups[libmesh_map_find(_var_to_vg, vn)].type();
2916  if (const bool lagrange = fe_type.family == LAGRANGE;
2917  lagrange || (FEInterface::get_continuity(fe_type) == DISCONTINUOUS))
2918  {
2919  const auto stride = lagrange ? 1 : component_size;
2920  for (const auto j : make_range((unsigned int)1, count))
2921  pack_container(j, di, stride);
2922  }
2923  else
2924  {
2925  static thread_local std::vector<dof_id_type> work_dof_indices;
2926  unsigned int j = 1;
2927  for (const auto i : make_range(begin + 1, end))
2928  {
2929  functor(work_dof_indices, i);
2930  pack_container(j++, work_dof_indices, 0);
2931  }
2932  }
2933  }
2934 }
std::vector< VariableGroup > _variable_groups
The variable groups in this system/degree of freedom map.
Definition: dof_map.h:2101
const std::pair< unsigned int, unsigned int > & get_variable_array(unsigned int vi) const
Retrieve the array variable bounds for a given variable vi.
Definition: dof_map.h:2873
std::unordered_map< unsigned int, unsigned int > _var_to_vg
A map from variable number to variable group number.
Definition: dof_map.h:2111
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:176
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 1563 of file dof_map.C.

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

1564 {
1565  MeshTools::libmesh_assert_valid_procids<Node>(mesh);
1566 
1567  for (auto & node : mesh.local_node_ptr_range())
1568  {
1569  unsigned int n_var_g = node->n_var_groups(this->sys_number());
1570  for (unsigned int vg=0; vg != n_var_g; ++vg)
1571  {
1572  unsigned int n_comp_g =
1573  node->n_comp_group(this->sys_number(), vg);
1574  dof_id_type my_first_dof = n_comp_g ?
1575  node->vg_dof_base(this->sys_number(), vg) : 0;
1576  libmesh_assert_not_equal_to (my_first_dof, DofObject::invalid_id);
1577  }
1578  }
1579 }
MeshBase & mesh
unsigned int sys_number() const
Definition: dof_map.h:2340
static constexpr dof_id_type invalid_id
An invalid id to distinguish an uninitialized DofObject.
Definition: dof_object.h:473
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:2191
void(* _extra_send_list_function)(std::vector< dof_id_type > &, void *)
A function pointer to a function to call to add extra entries to the send list.
Definition: dof_map.h:2186

◆ 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:2181

◆ 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:2176
void(* _extra_sparsity_function)(SparsityPattern::Graph &, std::vector< dof_id_type > &n_nz, std::vector< dof_id_type > &n_oz, void *)
A function pointer to a function to call to add extra entries to the sparsity pattern.
Definition: dof_map.h:2169

◆ 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:2164

◆ 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:2245
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:2147
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 3433 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().

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

3548 {
3549  LOG_SCOPE_IF("build_constraint_matrix_and_vector()", "DofMap", !called_recursively);
3550 
3551  // Create a set containing the DOFs we already depend on
3552  typedef std::set<dof_id_type> RCSet;
3553  RCSet dof_set;
3554 
3555  bool we_have_constraints = false;
3556 
3557  // Next insert any other dofs the current dofs might be constrained
3558  // in terms of. Note that in this case we may not be done: Those
3559  // may in turn depend on others. So, we need to repeat this process
3560  // in that case until the system depends only on unconstrained
3561  // degrees of freedom.
3562  for (const auto & dof : elem_dofs)
3563  if (this->is_constrained_dof(dof))
3564  {
3565  we_have_constraints = true;
3566 
3567  // If the DOF is constrained
3568  DofConstraints::const_iterator
3569  pos = _dof_constraints.find(dof);
3570 
3571  libmesh_assert (pos != _dof_constraints.end());
3572 
3573  const DofConstraintRow & constraint_row = pos->second;
3574 
3575  // Constraint rows in p refinement may be empty
3576  //libmesh_assert (!constraint_row.empty());
3577 
3578  for (const auto & item : constraint_row)
3579  dof_set.insert (item.first);
3580  }
3581 
3582  // May be safe to return at this point
3583  // (but remember to stop the perflog)
3584  if (!we_have_constraints)
3585  return;
3586 
3587  for (const auto & dof : elem_dofs)
3588  dof_set.erase (dof);
3589 
3590  // If we added any DOFS then we need to do this recursively.
3591  // It is possible that we just added a DOF that is also
3592  // constrained!
3593  //
3594  // Also, we need to handle the special case of an element having DOFs
3595  // constrained in terms of other, local DOFs
3596  if (!dof_set.empty() || // case 1: constrained in terms of other DOFs
3597  !called_recursively) // case 2: constrained in terms of our own DOFs
3598  {
3599  const DofConstraintValueMap * rhs_values = nullptr;
3600  if (qoi_index < 0)
3601  rhs_values = &_primal_constraint_values;
3602  else if (auto it = _adjoint_constraint_values.find(qoi_index);
3603  it != _adjoint_constraint_values.end())
3604  rhs_values = &it->second;
3605 
3606  const unsigned int old_size =
3607  cast_int<unsigned int>(elem_dofs.size());
3608 
3609  // Add new dependency dofs to the end of the current dof set
3610  elem_dofs.insert(elem_dofs.end(),
3611  dof_set.begin(), dof_set.end());
3612 
3613  // Now we can build the constraint matrix and vector.
3614  // Note that resize also zeros for a DenseMatrix and DenseVector
3615  C.resize (old_size,
3616  cast_int<unsigned int>(elem_dofs.size()));
3617  H.resize (old_size);
3618 
3619  // Create the C constraint matrix.
3620  for (unsigned int i=0; i != old_size; i++)
3621  if (this->is_constrained_dof(elem_dofs[i]))
3622  {
3623  // If the DOF is constrained
3624  DofConstraints::const_iterator
3625  pos = _dof_constraints.find(elem_dofs[i]);
3626 
3627  libmesh_assert (pos != _dof_constraints.end());
3628 
3629  const DofConstraintRow & constraint_row = pos->second;
3630 
3631  // p refinement creates empty constraint rows
3632  // libmesh_assert (!constraint_row.empty());
3633 
3634  for (const auto & item : constraint_row)
3635  for (unsigned int j=0,
3636  n_elem_dofs = cast_int<unsigned int>(elem_dofs.size());
3637  j != n_elem_dofs; j++)
3638  if (elem_dofs[j] == item.first)
3639  C(i,j) = item.second;
3640 
3641  if (rhs_values)
3642  {
3643  if (const auto rhsit = rhs_values->find(elem_dofs[i]);
3644  rhsit != rhs_values->end())
3645  H(i) = rhsit->second;
3646  }
3647  }
3648  else
3649  {
3650  C(i,i) = 1.;
3651  }
3652 
3653  // May need to do this recursively. It is possible
3654  // that we just replaced a constrained DOF with another
3655  // constrained DOF.
3656  DenseMatrix<Number> Cnew;
3657  DenseVector<Number> Hnew;
3658 
3659  this->build_constraint_matrix_and_vector (Cnew, Hnew, elem_dofs,
3660  qoi_index, true);
3661 
3662  if ((C.n() == Cnew.m()) && // If the constraint matrix
3663  (Cnew.n() == elem_dofs.size())) // is constrained...
3664  {
3665  // If x = Cy + h and y = Dz + g
3666  // Then x = (CD)z + (Cg + h)
3667  C.vector_mult_add(H, 1, Hnew);
3668 
3669  C.right_multiply(Cnew);
3670  }
3671 
3672  libmesh_assert_equal_to (C.n(), elem_dofs.size());
3673  }
3674 }
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:2278
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:2426
DofConstraints _dof_constraints
Data structure containing DOF constraints.
Definition: dof_map.h:2274
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:2276
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:2176
std::unique_ptr< StaticCondensationDofMap > _sc
Static condensation class.
Definition: dof_map.h:2333
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:1903
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:2245
bool has_static_condensation() const
Checks whether we have static condensation.
Definition: dof_map.h:1797
void(* _extra_sparsity_function)(SparsityPattern::Graph &, std::vector< dof_id_type > &n_nz, std::vector< dof_id_type > &n_oz, void *)
A function pointer to a function to call to add extra entries to the sparsity pattern.
Definition: dof_map.h:2169
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:2233
CouplingMatrix * _dof_coupling
Degree of freedom coupling.
Definition: dof_map.h:1741
void parallel_reduce(const Range &range, Body &body, unsigned int n_threads=libMesh::n_threads())
Execute the provided reduction operation in parallel on the specified range.
Definition: threads_none.h:109
OStreamProxy out
SparsityPattern::AugmentSparsityPattern * _augment_sparsity_pattern
Function object to call to add extra entries to the sparsity pattern.
Definition: dof_map.h:2164
dof_id_type n_local_dofs() const
Definition: dof_map_base.h:115

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

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

Referenced by distribute_dofs().

1257 {
1258  std::map<const Node *, std::set<subdomain_id_type>> constraining_subdomains;
1259  const auto & constraint_rows = _mesh.get_constraint_rows();
1260 
1261  // We can't just loop over constraint rows here because we need
1262  // element subdomain ids for the constrained nodes, but we don't
1263  // want an extra loop if there are no constraint rows.
1264  if (!constraint_rows.empty())
1265  for (auto & elem : _mesh.active_element_ptr_range())
1266  {
1267  const subdomain_id_type sbdid = elem->subdomain_id();
1268 
1269  for (const Node & node : elem->node_ref_range())
1270  {
1271  if (auto it = constraint_rows.find(&node);
1272  it != constraint_rows.end())
1273  {
1274  for (const auto & [pr, val] : it->second)
1275  {
1276  const Node * spline_node =
1277  pr.first->node_ptr(pr.second);
1278 
1279  constraining_subdomains[spline_node].insert(sbdid);
1280  }
1281  }
1282  }
1283  }
1284 
1285  return constraining_subdomains;
1286 }
constraint_rows_type & get_constraint_rows()
Constraint rows accessors.
Definition: mesh_base.h:1905
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:2140

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

5520 {
5521  const std::set<boundary_id_type>& mesh_side_bcids =
5523  const std::set<boundary_id_type>& mesh_edge_bcids =
5525  const std::set<boundary_id_type>& mesh_node_bcids =
5527  const std::set<boundary_id_type>& dbc_bcids = boundary.b;
5528 
5529  // DirichletBoundary id sets should be consistent across all ranks
5530  libmesh_assert(mesh.comm().verify(dbc_bcids.size()));
5531 
5532  for (const auto & bc_id : dbc_bcids)
5533  {
5534  // DirichletBoundary id sets should be consistent across all ranks
5535  libmesh_assert(mesh.comm().verify(bc_id));
5536 
5537  bool found_bcid = (mesh_side_bcids.find(bc_id) != mesh_side_bcids.end() ||
5538  mesh_edge_bcids.find(bc_id) != mesh_edge_bcids.end() ||
5539  mesh_node_bcids.find(bc_id) != mesh_node_bcids.end());
5540 
5541  // On a distributed mesh, boundary id sets may *not* be
5542  // consistent across all ranks, since not all ranks see all
5543  // boundaries
5544  mesh.comm().max(found_bcid);
5545 
5546  libmesh_error_msg_if(!found_bcid,
5547  "Could not find Dirichlet boundary id " << bc_id << " in mesh!");
5548  }
5549 }
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:170
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 4509 of file dof_map_constraints.C.

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

Referenced by check_for_cyclic_constraints(), and process_constraints().

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

References check_for_constraint_loops().

4504 {
4505  // Eventually make this officially libmesh_deprecated();
4507 }

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

872 {
874 
875  // we don't want to clear
876  // the coupling matrix!
877  // It should not change...
878  //_dof_coupling->clear();
879  //
880  // But it would be inconsistent to leave our coupling settings
881  // through a clear()...
882  _dof_coupling = nullptr;
883 
884  // Reset ghosting functor statuses
885  {
886  for (const auto & gf : _coupling_functors)
887  {
888  libmesh_assert(gf);
890  }
891  this->_coupling_functors.clear();
892 
893  // Go back to default coupling
894 
895  _default_coupling->set_dof_coupling(this->_dof_coupling);
896  _default_coupling->set_n_levels(this->use_coupled_neighbor_dofs(this->_mesh));
897 
899  }
900 
901 
902  {
903  for (const auto & gf : _algebraic_ghosting_functors)
904  {
905  libmesh_assert(gf);
907  }
908  this->_algebraic_ghosting_functors.clear();
909 
910  // Go back to default send_list generation
911 
912  // _default_evaluating->set_dof_coupling(this->_dof_coupling);
913  _default_evaluating->set_n_levels(1);
915  }
916 
917  this->_shared_functors.clear();
918 
919  _variables.clear();
920  _variable_groups.clear();
921  _var_to_vg.clear();
922  _variable_group_numbers.clear();
923  _array_variables.clear();
924  _first_scalar_df.clear();
925  this->clear_send_list();
926  this->clear_sparsity();
928 
929 #ifdef LIBMESH_ENABLE_AMR
930 
931  _dof_constraints.clear();
932  _stashed_dof_constraints.clear();
935  _n_old_dfs = 0;
936  _first_old_df.clear();
937  _end_old_df.clear();
938  _first_old_scalar_df.clear();
939 
940 #endif
941 
942  _matrices.clear();
943  if (_sc)
944  _sc->clear();
945 }
std::vector< VariableGroup > _variable_groups
The variable groups in this system/degree of freedom map.
Definition: dof_map.h:2101
virtual void clear()
Definition: dof_map_base.C:71
std::unique_ptr< StaticCondensationDofMap > _sc
Static condensation class.
Definition: dof_map.h:2333
void remove_ghosting_functor(GhostingFunctor &ghosting_functor)
Removes a functor which was previously added to the set of ghosting functors.
Definition: mesh_base.C:1093
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:1903
void add_coupling_functor(GhostingFunctor &coupling_functor, bool to_mesh=true)
Adds a functor which can specify coupling requirements for creation of sparse matrices.
Definition: dof_map.C:2005
std::vector< dof_id_type > _first_scalar_df
First DOF index for SCALAR variable v, or garbage for non-SCALAR variable v.
Definition: dof_map.h:2153
AdjointDofConstraintValues _adjoint_constraint_values
Definition: dof_map.h:2278
bool need_full_sparsity_pattern
Default false; set to true if any attached matrix requires a full sparsity pattern.
Definition: dof_map.h:2245
std::unordered_map< unsigned int, unsigned int > _var_to_vg
A map from variable number to variable group number.
Definition: dof_map.h:2111
std::vector< dof_id_type > _first_old_scalar_df
First old DOF index for SCALAR variable v, or garbage for non-SCALAR variable v.
Definition: dof_map.h:2266
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:2233
DofConstraints _dof_constraints
Data structure containing DOF constraints.
Definition: dof_map.h:2274
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:2124
std::vector< SparseMatrix< Number > *> _matrices
Additional matrices handled by this object.
Definition: dof_map.h:2147
std::vector< GhostingFunctor * > _algebraic_ghosting_functors
The list of all GhostingFunctor objects to be used when distributing ghosted vectors.
Definition: dof_map.h:2220
std::unique_ptr< DefaultCoupling > _default_coupling
The default coupling GhostingFunctor, used to implement standard libMesh sparsity pattern constructio...
Definition: dof_map.h:2199
DofConstraintValueMap _primal_constraint_values
Definition: dof_map.h:2276
std::vector< Variable > _variables
The variables in this system/degree of freedom map.
Definition: dof_map.h:2096
DofConstraints _stashed_dof_constraints
Definition: dof_map.h:2274
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:1981
MeshBase & _mesh
The mesh that system uses.
Definition: dof_map.h:2140
std::unique_ptr< DefaultCoupling > _default_evaluating
The default algebraic GhostingFunctor, used to implement standard libMesh send_list construction...
Definition: dof_map.h:2207
std::vector< unsigned int > _variable_group_numbers
The variable group number for each variable.
Definition: dof_map.h:2106
std::map< GhostingFunctor *, std::shared_ptr< GhostingFunctor > > _shared_functors
Hang on to references to any GhostingFunctor objects we were passed in shared_ptr form...
Definition: dof_map.h:2239
void add_algebraic_ghosting_functor(GhostingFunctor &evaluable_functor, bool to_mesh=true)
Adds a functor which can specify algebraic ghosting requirements for use with distributed vectors...
Definition: dof_map.C:2062
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:2159

◆ clear_sparsity()

void libMesh::DofMap::clear_sparsity ( )

Clears the sparsity pattern.

Definition at line 1981 of file dof_map.C.

References _sp.

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

1982 {
1983  _sp.reset();
1984 }
std::unique_ptr< SparsityPattern::Build > _sp
The sparsity pattern of the global matrix.
Definition: dof_map.h:2252

◆ 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::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::PetscDMWrapper::build_section(), libMesh::PetscDMWrapper::build_sf(), libMesh::MeshBase::cache_elem_data(), libMesh::System::calculate_norm(), check_dirichlet_bcid_consistency(), libMesh::MeshTetInterface::check_hull_integrity(), libMesh::MeshBase::complete_preparation(), 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::System::get_info(), libMesh::MeshBase::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(), libMesh::MeshTetInterface::improve_hull_integrity(), 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::PetscVector< libMesh::Number >::operator=(), 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::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::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(), libMesh::MeshBase::sync_subdomain_name_map(), ConstraintOperatorTest::test1DCoarseningNewNodes(), ConstraintOperatorTest::test1DCoarseningOperator(), MeshFunctionTest::test_bad_gradient_var_with_out_of_mesh_value(), MeshFunctionTest::test_bad_hessian_var_with_out_of_mesh_value(), 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 1960 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().

1961 {
1963 
1964  // It is possible that some \p SparseMatrix implementations want to
1965  // see the sparsity pattern before we throw it away. If so, we
1966  // share a view of its arrays, and we pass it in to the matrices.
1967  for (const auto & mat : _matrices)
1968  {
1969  mat->attach_sparsity_pattern (*_sp);
1971  mat->update_sparsity_pattern (_sp->get_sparsity_pattern());
1972  }
1973  // If we don't need the full sparsity pattern anymore, free the
1974  // parts of it we don't need.
1976  _sp->clear_full_sparsity();
1977 }
std::unique_ptr< SparsityPattern::Build > _sp
The sparsity pattern of the global matrix.
Definition: dof_map.h:2252
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:2091
bool need_full_sparsity_pattern
Default false; set to true if any attached matrix requires a full sparsity pattern.
Definition: dof_map.h:2245
std::vector< SparseMatrix< Number > *> _matrices
Additional matrices handled by this object.
Definition: dof_map.h:2147

◆ 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:2252
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 2511 of file dof_map.h.

Referenced by assemble().

2514  {}

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

2487  {}

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

2492  {}

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

2501  {}

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

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

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

2496  {}

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

2516 {}

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

5381 {
5382  // We're constraining dofs on elem which correspond to p refinement
5383  // levels above p - this only makes sense if elem's p refinement
5384  // level is above p.
5385  libmesh_assert_greater (elem->p_level(), p);
5386  libmesh_assert_less (s, elem->n_sides());
5387 
5388  const unsigned int sys_num = this->sys_number();
5389  FEType fe_type = this->variable_type(var);
5390 
5391  const unsigned int n_nodes = elem->n_nodes();
5392  for (unsigned int n = 0; n != n_nodes; ++n)
5393  if (elem->is_node_on_side(n, s))
5394  {
5395  const Node & node = elem->node_ref(n);
5396  const unsigned int low_nc =
5397  FEInterface::n_dofs_at_node (fe_type, p, elem, n);
5398  const unsigned int high_nc =
5399  FEInterface::n_dofs_at_node (fe_type, elem, n);
5400 
5401  // since we may be running this method concurrently
5402  // on multiple threads we need to acquire a lock
5403  // before modifying the _dof_constraints object.
5404  Threads::spin_mutex::scoped_lock lock(Threads::spin_mtx);
5405 
5406  if (elem->is_vertex(n))
5407  {
5408  // Add "this is zero" constraint rows for high p vertex
5409  // dofs
5410  for (unsigned int i = low_nc; i != high_nc; ++i)
5411  {
5412  _dof_constraints[node.dof_number(sys_num,var,i)].clear();
5413  _primal_constraint_values.erase(node.dof_number(sys_num,var,i));
5414  }
5415  }
5416  else
5417  {
5418  const unsigned int total_dofs = node.n_comp(sys_num, var);
5419  libmesh_assert_greater_equal (total_dofs, high_nc);
5420  // Add "this is zero" constraint rows for high p
5421  // non-vertex dofs, which are numbered in reverse
5422  for (unsigned int j = low_nc; j != high_nc; ++j)
5423  {
5424  const unsigned int i = total_dofs - j - 1;
5425  _dof_constraints[node.dof_number(sys_num,var,i)].clear();
5426  _primal_constraint_values.erase(node.dof_number(sys_num,var,i));
5427  }
5428  }
5429  }
5430 }
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:1008
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:978
virtual bool is_node_on_side(const unsigned int n, const unsigned int s) const =0
unsigned int p_level() const
Definition: elem.h:3122
unsigned int sys_number() const
Definition: dof_map.h:2340
const dof_id_type n_nodes
Definition: tecplot_io.C:67
const Node & node_ref(const unsigned int i) const
Definition: elem.h:2535
virtual unsigned int n_nodes() const =0
const FEType & variable_type(const unsigned int i) const
Definition: dof_map.h:2388
DofConstraints _dof_constraints
Data structure containing DOF constraints.
Definition: dof_map.h:2274
static unsigned int n_dofs_at_node(const unsigned int dim, const FEType &fe_t, const ElemType t, const unsigned int n)
Definition: fe_interface.C:437
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:2276
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 2560 of file dof_map.h.

References _constrained_sparsity_construction.

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

◆ 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:2274

◆ 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:2274

◆ 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:2233

◆ 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:2233

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

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

◆ create_static_condensation()

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

Add a static condensation class.

Definition at line 3135 of file dof_map.C.

References _sc, and mesh.

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

3136 {
3137  _sc = std::make_unique<StaticCondensationDofMap>(mesh, sys, *this);
3138 }
std::unique_ptr< StaticCondensationDofMap > _sc
Static condensation class.
Definition: dof_map.h:2333
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:2207

◆ 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:2199

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

950 {
951  // This function must be run on all processors at once
952  parallel_object_only();
953 
954  // Log how long it takes to distribute the degrees of freedom
955  LOG_SCOPE("distribute_dofs()", "DofMap");
956 
957  libmesh_assert (mesh.is_prepared());
958 
959  const processor_id_type proc_id = this->processor_id();
960 #ifndef NDEBUG
961  const processor_id_type n_proc = this->n_processors();
962 #endif
963 
964  // libmesh_assert_greater (this->n_variables(), 0);
965  libmesh_assert_less (proc_id, n_proc);
966 
967  // Data structure to ensure we can correctly combine
968  // subdomain-restricted variables with constraining nodes from
969  // different subdomains
970  const std::map<const Node *, std::set<subdomain_id_type>>
971  constraining_subdomains =
973 
974  // re-init in case the mesh has changed
975  this->reinit(mesh,
976  constraining_subdomains);
977 
978  // By default distribute variables in a
979  // var-major fashion, but allow run-time
980  // specification
981  bool node_major_dofs = libMesh::on_command_line ("--node-major-dofs");
982 
983  // The DOF counter, will be incremented as we encounter
984  // new degrees of freedom
985  dof_id_type next_free_dof = 0;
986 
987  // Clear the send list before we rebuild it
988  this->clear_send_list();
989 
990  // Set temporary DOF indices on this processor
991  if (node_major_dofs)
993  (next_free_dof, mesh, constraining_subdomains);
994  else
996  (next_free_dof, mesh, constraining_subdomains);
997 
998  // Get DOF counts on all processors
999  const auto n_dofs = this->compute_dof_info(next_free_dof);
1000 
1001  // Clear all the current DOF indices
1002  // (distribute_dofs expects them cleared!)
1003  this->invalidate_dofs(mesh);
1004 
1005  next_free_dof = _first_df[proc_id];
1006 
1007  // Set permanent DOF indices on this processor
1008  if (node_major_dofs)
1010  (next_free_dof, mesh, constraining_subdomains);
1011  else
1013  (next_free_dof, mesh, constraining_subdomains);
1014 
1015  libmesh_assert_equal_to (next_free_dof, _end_df[proc_id]);
1016 
1017  //------------------------------------------------------------
1018  // At this point, all n_comp and dof_number values on local
1019  // DofObjects should be correct, but a DistributedMesh might have
1020  // incorrect values on non-local DofObjects. Let's request the
1021  // correct values from each other processor.
1022 
1023  if (this->n_processors() > 1)
1024  {
1025  this->set_nonlocal_dof_objects(mesh.nodes_begin(),
1026  mesh.nodes_end(),
1028 
1029  this->set_nonlocal_dof_objects(mesh.elements_begin(),
1030  mesh.elements_end(),
1032  }
1033 
1034 #ifdef DEBUG
1035  {
1036  const unsigned int
1037  sys_num = this->sys_number();
1038 
1039  // Processors should all agree on DoF ids for the newly numbered
1040  // system.
1042 
1043  // DoF processor ids should match DofObject processor ids
1044  for (auto & node : mesh.node_ptr_range())
1045  {
1046  DofObject const * const dofobj = node;
1047  const processor_id_type obj_proc_id = dofobj->processor_id();
1048 
1049  for (auto v : make_range(dofobj->n_vars(sys_num)))
1050  for (auto c : make_range(dofobj->n_comp(sys_num,v)))
1051  {
1052  const dof_id_type dofid = dofobj->dof_number(sys_num,v,c);
1053  libmesh_assert_greater_equal (dofid, this->first_dof(obj_proc_id));
1054  libmesh_assert_less (dofid, this->end_dof(obj_proc_id));
1055  }
1056  }
1057 
1058  for (auto & elem : mesh.element_ptr_range())
1059  {
1060  DofObject const * const dofobj = elem;
1061  const processor_id_type obj_proc_id = dofobj->processor_id();
1062 
1063  for (auto v : make_range(dofobj->n_vars(sys_num)))
1064  for (auto c : make_range(dofobj->n_comp(sys_num,v)))
1065  {
1066  const dof_id_type dofid = dofobj->dof_number(sys_num,v,c);
1067  libmesh_assert_greater_equal (dofid, this->first_dof(obj_proc_id));
1068  libmesh_assert_less (dofid, this->end_dof(obj_proc_id));
1069  }
1070  }
1071  }
1072 #endif
1073 
1074  // start finding SCALAR degrees of freedom
1075 #ifdef LIBMESH_ENABLE_AMR
1077 #endif
1078  _first_scalar_df.clear();
1080  dof_id_type current_SCALAR_dof_index = n_dofs - n_SCALAR_dofs();
1081 
1082  // Calculate and cache the initial DoF indices for SCALAR variables.
1083  // This is an O(N_vars) calculation so we want to do it once per
1084  // renumbering rather than once per SCALAR_dof_indices() call
1085 
1086  for (auto v : make_range(this->n_variables()))
1087  if (this->variable(v).type().family == SCALAR)
1088  {
1089  _first_scalar_df[v] = current_SCALAR_dof_index;
1090  current_SCALAR_dof_index += this->variable(v).type().order.get_order();
1091  }
1092 
1093  // Allow our GhostingFunctor objects to reinit if necessary
1094  for (const auto & gf : _algebraic_ghosting_functors)
1095  {
1096  libmesh_assert(gf);
1097  gf->dofmap_reinit();
1098  }
1099 
1100  for (const auto & gf : _coupling_functors)
1101  {
1102  libmesh_assert(gf);
1103  gf->dofmap_reinit();
1104  }
1105 
1106  // Note that in the add_neighbors_to_send_list nodes on processor
1107  // boundaries that are shared by multiple elements are added for
1108  // each element.
1110 
1111  // Here we used to clean up that data structure; now System and
1112  // EquationSystems call that for us, after we've added constraint
1113  // dependencies to the send_list too.
1114  // this->sort_send_list ();
1115 
1116  return n_dofs;
1117 }
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 (at 0 p-refinement level).
Definition: fe_type.h:203
unsigned int sys_number() const
Definition: dof_map.h:2340
std::vector< dof_id_type > _first_scalar_df
First DOF index for SCALAR variable v, or garbage for non-SCALAR variable v.
Definition: dof_map.h:2153
const Variable & variable(const unsigned int c) const override
Definition: dof_map.h:2358
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:1958
void distribute_local_dofs_var_major(dof_id_type &next_free_dof, MeshBase &mesh, const std::map< const Node *, std::set< subdomain_id_type >> &constraining_subdomains)
Distributes the global degrees of freedom, for dofs on this processor.
Definition: dof_map.C:1418
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:1687
std::vector< dof_id_type > _first_old_scalar_df
First old DOF index for SCALAR variable v, or garbage for non-SCALAR variable v.
Definition: dof_map.h:2266
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:473
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:2233
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:2220
void invalidate_dofs(MeshBase &mesh) const
Invalidates all active DofObject dofs for this system.
Definition: dof_map.C:856
IntRange< T > make_range(T beg, T end)
The 2-parameter make_range() helper function returns an IntRange<T> when both input parameters are of...
Definition: int_range.h:176
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:934
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:1256
void distribute_local_dofs_node_major(dof_id_type &next_free_dof, MeshBase &mesh, const std::map< const Node *, std::set< subdomain_id_type >> &constraining_subdomains)
Distributes the global degrees of freedom for dofs on this processor.
Definition: dof_map.C:1290
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 1290 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().

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

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

1540 {
1541  this->_n_SCALAR_dofs = 0;
1542  for (auto vg : make_range(this->n_variable_groups()))
1543  {
1544  const VariableGroup & vg_description(this->variable_group(vg));
1545 
1546  if (vg_description.type().family == SCALAR)
1547  {
1548  this->_n_SCALAR_dofs += (vg_description.n_variables()*
1549  vg_description.type().order.get_order());
1550  continue;
1551  }
1552  }
1553 
1554  // Only increment next_free_dof if we're on the processor
1555  // that holds this SCALAR variable
1556  if (this->processor_id() == (this->n_processors()-1))
1557  next_free_dof += _n_SCALAR_dofs;
1558 }
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:2258
const VariableGroup & variable_group(const unsigned int c) const
Definition: dof_map.h:2348
IntRange< T > make_range(T beg, T end)
The 2-parameter make_range() helper function returns an IntRange<T> when both input parameters are of...
Definition: int_range.h:176
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 2201 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_constraints_to_send_list(), 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, N_x >::setUp(), SolidSystem::side_time_derivative(), libMesh::SparsityPattern::Build::sorted_connected_dofs(), ProjectSolutionTest::test_partial_project_solution(), 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().

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

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

References dof_indices(), and int.

2321 {
2322  dof_indices(
2323  elem,
2324  di,
2325  vn,
2326  [](const Elem &,
2327  std::vector<dof_id_type> & dof_indices,
2328  const std::vector<dof_id_type> & scalar_dof_indices) {
2329  dof_indices.insert(dof_indices.end(), scalar_dof_indices.begin(), scalar_dof_indices.end());
2330  },
2331  [](const Elem &,
2332  unsigned int,
2333  unsigned int,
2334  std::vector<dof_id_type> & dof_indices,
2335  const dof_id_type dof) { dof_indices.push_back(dof); },
2336  p_level);
2337 }
void dof_indices(const Elem *const elem, std::vector< dof_id_type > &di) const
Definition: dof_map.C:2201
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 2777 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().

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

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

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

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

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

2470 {
2471  this->_node_dof_indices(elem, n, elem.node_ref(n), di, vn);
2472 }
void _node_dof_indices(const Elem &elem, unsigned int n, const DofObject &obj, std::vector< dof_id_type > &di, const unsigned int vn) const
Helper function that implements the element-nodal versions of dof_indices and old_dof_indices.
Definition: dof_map.C:2491

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

Enabled by default.

Definition at line 94 of file reference_counter.C.

References libMesh::ReferenceCounter::_enable_print_counter.

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

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

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

2523  {}

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

2520  {}

◆ enforce_constraints_on_jacobian()

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

Definition at line 2533 of file dof_map.h.

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

2534  {}

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

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

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

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

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

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

References need_full_sparsity_pattern.

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

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

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

References _adjoint_dirichlet_boundaries.

5467 {
5468  libmesh_assert_greater(_adjoint_dirichlet_boundaries.size(),q);
5469  return _adjoint_dirichlet_boundaries[q].get();
5470 }
std::vector< std::unique_ptr< DirichletBoundaries > > _adjoint_dirichlet_boundaries
Data structure containing Dirichlet functions.
Definition: dof_map.h:2308

◆ get_adjoint_dirichlet_boundaries() [2/2]

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

Definition at line 5474 of file dof_map_constraints.C.

References _adjoint_dirichlet_boundaries.

5475 {
5476  unsigned int old_size = cast_int<unsigned int>
5478  for (unsigned int i = old_size; i <= q; ++i)
5479  _adjoint_dirichlet_boundaries.push_back(std::make_unique<DirichletBoundaries>());
5480 
5481  return _adjoint_dirichlet_boundaries[q].get();
5482 }
std::vector< std::unique_ptr< DirichletBoundaries > > _adjoint_dirichlet_boundaries
Data structure containing Dirichlet functions.
Definition: dof_map.h:2308

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

References _variable_numbers, and n_vars().

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

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

◆ 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:2302

◆ 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:2302

◆ 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:2274

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

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

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

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

◆ 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:2252
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:2252
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:2294

◆ 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:2294

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

References _primal_constraint_values.

2472 {
2474 }
DofConstraintValueMap _primal_constraint_values
Definition: dof_map.h:2276

◆ 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:2252

◆ get_static_condensation() [1/2]

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

References _sc, and libMesh::libmesh_assert().

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

2860 {
2862  return *_sc;
2863 }
std::unique_ptr< StaticCondensationDofMap > _sc
Static condensation class.
Definition: dof_map.h:2333
libmesh_assert(ctx)

◆ get_static_condensation() [2/2]

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

Definition at line 2866 of file dof_map.h.

References _sc, and libMesh::libmesh_assert().

2867 {
2869  return *_sc;
2870 }
std::unique_ptr< StaticCondensationDofMap > _sc
Static condensation class.
Definition: dof_map.h:2333
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 2873 of file dof_map.h.

References _array_variables, b, and value.

Referenced by array_dof_indices().

2874 {
2875  auto it = std::upper_bound(
2876  _array_variables.begin(),
2877  _array_variables.end(),
2878  vi,
2879  [](unsigned int value, const std::pair<unsigned int, unsigned int> & b) { return value < b.first; });
2880 
2881  libmesh_assert_msg(it != _array_variables.begin(),
2882  "Passed in " << std::to_string(vi) << " is not in any of our array variables");
2883  --it;
2884  libmesh_assert_msg(vi < it->second,
2885  "Passed in " << std::to_string(vi) << " is not in any of our array variables");
2886  return *it;
2887 }
std::vector< std::pair< unsigned int, unsigned int > > _array_variables
Array variable information storage.
Definition: dof_map.h:2124
static const Real b
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 5456 of file dof_map_constraints.C.

References _adjoint_dirichlet_boundaries.

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

5457 {
5458  if (_adjoint_dirichlet_boundaries.size() > q)
5459  return true;
5460 
5461  return false;
5462 }
std::vector< std::unique_ptr< DirichletBoundaries > > _adjoint_dirichlet_boundaries
Data structure containing Dirichlet functions.
Definition: dof_map.h:2308

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

References _adjoint_constraint_values.

Referenced by has_heterogenous_adjoint_constraint().

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

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

References _adjoint_constraint_values.

Referenced by has_heterogenous_adjoint_constraints().

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

◆ 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:2450

◆ 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:2436

◆ has_static_condensation()

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

Checks whether we have static condensation.

Definition at line 1797 of file dof_map.h.

References _sc.

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

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

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

References _variable_numbers.

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

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

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

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

Referenced by heterogenously_constrain_element_matrix_and_vector(), and process_mesh_constraint_rows().

2505  {}

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

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

Referenced by heterogenously_constrain_element_vector().

2509  {}

◆ 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:2504

◆ 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:2508

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

References _identify_variable_groups.

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

2952 {
2954 }
bool _identify_variable_groups
true when VariableGroup structures should be automatically identified, false otherwise.
Definition: dof_map.h:2130

◆ identify_variable_groups() [2/2]

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

Toggle automatic VariableGroup identification.

Definition at line 2957 of file dof_map.h.

References _identify_variable_groups.

2958 {
2960 }
bool _identify_variable_groups
true when VariableGroup structures should be automatically identified, false otherwise.
Definition: dof_map.h:2130

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

References mesh, and sys_number().

Referenced by distribute_dofs().

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

◆ 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:2147

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

References _node_constraints.

Referenced by allgather_recursive_constraints(), and scatter_constraints().

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

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

2675 {
2676  // Everything is evaluable on a local object
2677  if (obj.processor_id() == this->processor_id())
2678  return true;
2679 
2680  std::vector<dof_id_type> di;
2681 
2682  if (var_num == libMesh::invalid_uint)
2683  this->dof_indices(&obj, di);
2684  else
2685  this->dof_indices(&obj, di, var_num);
2686 
2687  return this->all_semilocal_indices(di);
2688 }
const unsigned int invalid_uint
A number which is used quite often to represent an invalid or uninitialized value for an unsigned int...
Definition: libmesh.h:303
void dof_indices(const Elem *const elem, std::vector< dof_id_type > &di) const
Definition: dof_map.C:2201
bool all_semilocal_indices(const std::vector< dof_id_type > &dof_indices) const
Definition: dof_map.C:2660
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:2294

◆ 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 1122 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(), libMesh::PetscPreconditioner< T >::set_hypre_ads_data(), libMesh::PetscPreconditioner< T >::set_hypre_ams_data(), and SystemsTest::testBlockRestrictedVarNDofs().

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

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

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

2964 {
2965  if (_variables.empty())
2966  return 0;
2967 
2968  const Variable & last = _variables.back();
2969  return last.first_scalar_number() + last.n_components(mesh);
2970 }
MeshBase & mesh
std::vector< Variable > _variables
The variables in this system/degree of freedom map.
Definition: dof_map.h:2096

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

1715 {
1716  parallel_object_only();
1717 
1718  dof_id_type nc_dofs = this->n_local_constrained_dofs();
1719  this->comm().sum(nc_dofs);
1720  return nc_dofs;
1721 }
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:2285

◆ 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::System::get_info(), 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 libMesh::PetscPreconditioner< T >::set_hypre_ads_data(), libMesh::PetscPreconditioner< T >::set_hypre_ams_data(), and 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 1724 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().

1725 {
1726  const DofConstraints::const_iterator lower =
1727  _dof_constraints.lower_bound(this->first_dof()),
1728  upper =
1729  _dof_constraints.lower_bound(this->end_dof());
1730 
1731  return cast_int<dof_id_type>(std::distance(lower, upper));
1732 }
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:2274

◆ 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::PetscPreconditioner< T >::set_hypre_ads_data(), libMesh::PetscPreconditioner< T >::set_hypre_ams_data(), 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:1122
MeshBase & _mesh
The mesh that system uses.
Definition: dof_map.h:2140
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::Nemesis_IO::copy_scalar_solution(), libMesh::ExodusII_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::NumericVector< Number >::is_effectively_ghosted(), libMesh::NumericVector< Number >::is_effectively_serial(), 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:2258

◆ 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:2101

◆ 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:2096

◆ n_vars()

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

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

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

◆ 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:2285

◆ 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:2285

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

2482 {
2483  const DofObject & old_obj = elem.node_ref(n).get_old_dof_object_ref();
2484  this->_node_dof_indices(elem, n, old_obj, di, vn);
2485 }
void _node_dof_indices(const Elem &elem, unsigned int n, const DofObject &obj, std::vector< dof_id_type > &di, const unsigned int vn) const
Helper function that implements the element-nodal versions of dof_indices and old_dof_indices.
Definition: dof_map.C:2491

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

References 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::FEType::p_refinement, 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().

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

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

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

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

References get_info().

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

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

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

1899 {
1900  // If we already have simple Dirichlet constraints (with right hand
1901  // sides but with no coupling between DoFs) on spline-constrained FE
1902  // nodes, then we'll need a solve to compute the corresponding
1903  // constraints on the relevant spline nodes. (If we already have
1904  // constraints with coupling between DoFs on spline-constrained FE
1905  // nodes, then we'll need to go sit down and cry until we figure out
1906  // how to handle that.)
1907 
1908  const auto & constraint_rows = mesh.get_constraint_rows();
1909 
1910  // This routine is too expensive to use unless we really might
1911  // need it
1912 #ifdef DEBUG
1913  bool constraint_rows_empty = constraint_rows.empty();
1914  this->comm().min(constraint_rows_empty);
1915  libmesh_assert(!constraint_rows_empty);
1916 #endif
1917 
1918  // We can't handle periodic boundary conditions on spline meshes
1919  // yet.
1920 #ifdef LIBMESH_ENABLE_PERIODIC
1921  libmesh_error_msg_if (!_periodic_boundaries->empty(),
1922  "Periodic boundary conditions are not yet implemented for spline meshes");
1923 #endif
1924 
1925  // We can handle existing Dirichlet constraints, but we'll need
1926  // to do solves to project them down onto the spline basis.
1927  std::unique_ptr<SparsityPattern::Build> sp;
1928  std::unique_ptr<SparseMatrix<Number>> mat;
1929 
1930  const unsigned int n_adjoint_rhs =
1932 
1933  // [0] for primal rhs, [q+1] for adjoint qoi q
1934  std::vector<std::unique_ptr<NumericVector<Number>>>
1935  solve_rhs(n_adjoint_rhs+1);
1936 
1937  // Keep track of which spline DoFs will be Dirichlet.
1938  // We use a set here to make it easier to find what processors
1939  // to send the DoFs to later.
1940  std::set<dof_id_type> my_dirichlet_spline_dofs;
1941 
1942  // And keep track of which non-spline Dofs were Dirichlet
1943  std::unordered_set<dof_id_type> was_previously_constrained;
1944 
1945  const unsigned int sys_num = this->sys_number();
1946  for (auto & node_row : constraint_rows)
1947  {
1948  const Node * node = node_row.first;
1949  libmesh_assert(node == mesh.node_ptr(node->id()));
1950 
1951  // Each processor only computes its own (and in distributed
1952  // cases, is only guaranteed to have the dependency data to
1953  // compute its own) constraints here.
1954  if (node->processor_id() != mesh.processor_id())
1955  continue;
1956 
1957  for (auto var_num : IntRange<unsigned int>(0, this->n_variables()))
1958  {
1959  const FEFamily & fe_family = this->variable_type(var_num).family;
1960 
1961  // constraint_rows only applies to nodal variables
1962  if (fe_family != LAGRANGE &&
1963  fe_family != RATIONAL_BERNSTEIN)
1964  continue;
1965 
1966  DofConstraintRow dc_row;
1967 
1968  const dof_id_type constrained_id =
1969  node->dof_number(sys_num, var_num, 0);
1970  for (const auto & [pr, val] : node_row.second)
1971  {
1972  const Elem * spline_elem = pr.first;
1973  libmesh_assert(spline_elem == mesh.elem_ptr(spline_elem->id()));
1974 
1975  const Node & spline_node =
1976  spline_elem->node_ref(pr.second);
1977 
1978  const dof_id_type spline_dof_id =
1979  spline_node.dof_number(sys_num, var_num, 0);
1980  dc_row[spline_dof_id] = val;
1981  }
1982 
1983  // See if we already have a constraint here.
1984  if (this->is_constrained_dof(constrained_id))
1985  {
1986  was_previously_constrained.insert(constrained_id);
1987 
1988  // Keep track of which spline DoFs will be
1989  // inheriting this non-spline DoF's constraints
1990  for (auto & row_entry : dc_row)
1991  my_dirichlet_spline_dofs.insert(row_entry.first);
1992 
1993  // If it wasn't a simple Dirichlet-type constraint
1994  // then I don't know what to do with it. We'll make
1995  // this an assertion only because this should only
1996  // crop up with periodic boundary conditions, which
1997  // we've already made sure we don't have.
1998  libmesh_assert(_dof_constraints[constrained_id].empty());
1999  }
2000 
2001  // Add the constraint, replacing any previous, so we can
2002  // use the new constraint in setting up the solve below
2003  this->add_constraint_row(constrained_id, dc_row, false);
2004  }
2005  }
2006 
2007  // my_dirichlet_spline_dofs may now include DoFs whose owners
2008  // don't know they need to become spline DoFs! We need to push
2009  // this data to them.
2010  if (this->comm().size() > 1)
2011  {
2012  std::unordered_map
2013  <processor_id_type, std::vector<dof_id_type>>
2014  their_dirichlet_spline_dofs;
2015 
2016  // If we ever change the underlying container here then we'd
2017  // better do some kind of sort before using it; we'll rely
2018  // on sorting to make the processor id lookup efficient.
2019  libmesh_assert(std::is_sorted(my_dirichlet_spline_dofs.begin(),
2020  my_dirichlet_spline_dofs.end()));
2021  processor_id_type destination_pid = 0;
2022  for (auto d : my_dirichlet_spline_dofs)
2023  {
2024  libmesh_assert_less(d, this->end_dof(this->comm().size()-1));
2025  while (d >= this->end_dof(destination_pid))
2026  destination_pid++;
2027 
2028  if (destination_pid != this->processor_id())
2029  their_dirichlet_spline_dofs[destination_pid].push_back(d);
2030  }
2031 
2032  auto receive_dof_functor =
2033  [& my_dirichlet_spline_dofs]
2035  const std::vector<dof_id_type> & dofs)
2036  {
2037  my_dirichlet_spline_dofs.insert(dofs.begin(), dofs.end());
2038  };
2039 
2040  Parallel::push_parallel_vector_data
2041  (this->comm(), their_dirichlet_spline_dofs, receive_dof_functor);
2042  }
2043 
2044 
2045  // If anyone had any prior constraints in effect, then we need
2046  // to convert them to constraints on the spline nodes.
2047  //
2048  // NOT simply testing prior_constraints here; maybe it turned
2049  // out that all our constraints were on non-spline-constrained
2050  // parts of a hybrid mesh?
2051  bool important_prior_constraints =
2052  !was_previously_constrained.empty();
2053  this->comm().max(important_prior_constraints);
2054 
2055  if (important_prior_constraints)
2056  {
2057  // Now that we have the spline constraints added, we can
2058  // finally construct a sparsity pattern that correctly
2059  // accounts for those constraints!
2060  mat = SparseMatrix<Number>::build(this->comm());
2061  for (auto q : IntRange<unsigned int>(0, n_adjoint_rhs+1))
2062  {
2063  solve_rhs[q] = NumericVector<Number>::build(this->comm());
2064  solve_rhs[q]->init(this->n_dofs(), this->n_local_dofs(),
2065  false, PARALLEL);
2066  }
2067 
2068  // We need to compute our own sparsity pattern, to take into
2069  // account the particularly non-sparse rows that can be
2070  // created by the spline constraints we just added.
2071  mat->attach_dof_map(*this);
2072  sp = this->build_sparsity(mesh);
2073  mat->attach_sparsity_pattern(*sp);
2074  mat->init();
2075 
2076  for (auto & node_row : constraint_rows)
2077  {
2078  const Node * node = node_row.first;
2079  libmesh_assert(node == mesh.node_ptr(node->id()));
2080 
2081  for (auto var_num : IntRange<unsigned int>(0, this->n_variables()))
2082  {
2083  const FEFamily & fe_family = this->variable_type(var_num).family;
2084 
2085  // constraint_rows only applies to nodal variables
2086  if (fe_family != LAGRANGE &&
2087  fe_family != RATIONAL_BERNSTEIN)
2088  continue;
2089 
2090  const dof_id_type constrained_id =
2091  node->dof_number(sys_num, var_num, 0);
2092 
2093  if (was_previously_constrained.count(constrained_id))
2094  {
2095  for (auto q : IntRange<int>(0, n_adjoint_rhs+1))
2096  {
2097  DenseMatrix<Number> K(1,1);
2098  DenseVector<Number> F(1);
2099  std::vector<dof_id_type> dof_indices(1, constrained_id);
2100 
2101  K(0,0) = 1;
2102 
2103  DofConstraintValueMap & vals = q ?
2106 
2107  DofConstraintValueMap::const_iterator rhsit =
2108  vals.find(constrained_id);
2109  F(0) = (rhsit == vals.end()) ? 0 : rhsit->second;
2110 
2111  // We no longer need any rhs values here directly.
2112  if (rhsit != vals.end())
2113  vals.erase(rhsit);
2114 
2116  (K, F, dof_indices, false, q ? (q-1) : -1);
2117  if (!q)
2118  mat->add_matrix(K, dof_indices);
2119  solve_rhs[q]->add_vector(F, dof_indices);
2120  }
2121  }
2122  }
2123  }
2124 
2125  // Any DoFs that aren't part of any constraint, directly or
2126  // indirectly, need a diagonal term to make the matrix
2127  // here invertible.
2128  for (dof_id_type d : IntRange<dof_id_type>(this->first_dof(),
2129  this->end_dof()))
2130  if (!was_previously_constrained.count(d) &&
2131  !my_dirichlet_spline_dofs.count(d))
2132  mat->add(d,d,1);
2133 
2134  // At this point, we're finally ready to solve for Dirichlet
2135  // constraint values on spline nodes.
2136  std::unique_ptr<LinearSolver<Number>> linear_solver =
2138 
2139  std::unique_ptr<NumericVector<Number>> projected_vals =
2141 
2142  projected_vals->init(this->n_dofs(), this->n_local_dofs(),
2143  false, PARALLEL);
2144 
2145  DofConstraintRow empty_row;
2146  for (auto sd : my_dirichlet_spline_dofs)
2147  if (this->local_index(sd))
2148  this->add_constraint_row(sd, empty_row);
2149 
2150  for (auto q : IntRange<unsigned int>(0, n_adjoint_rhs+1))
2151  {
2152  // FIXME: we don't have an EquationSystems here, but I'd
2153  // rather not hardcode these...
2154  const double tol = double(TOLERANCE * TOLERANCE);
2155  const unsigned int max_its = 5000;
2156 
2157  linear_solver->solve(*mat, *projected_vals,
2158  *(solve_rhs[q]), tol, max_its);
2159 
2160  DofConstraintValueMap & vals = q ?
2163 
2164  for (auto sd : my_dirichlet_spline_dofs)
2165  if (this->local_index(sd))
2166  {
2167  Number constraint_rhs = (*projected_vals)(sd);
2168 
2169  std::pair<DofConstraintValueMap::iterator, bool> rhs_it =
2170  vals.emplace(sd, constraint_rhs);
2171  if (!rhs_it.second)
2172  rhs_it.first->second = constraint_rhs;
2173  }
2174  }
2175  }
2176 }
FEFamily family
The type of finite element.
Definition: fe_type.h:228
dof_id_type dof_number(const unsigned int s, const unsigned int var, const unsigned int comp) const
Definition: dof_object.h:1008
constraint_rows_type & get_constraint_rows()
Constraint rows accessors.
Definition: mesh_base.h:1905
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:2201
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:2340
uint8_t processor_id_type
Definition: id_types.h:104
AdjointDofConstraintValues _adjoint_constraint_values
Definition: dof_map.h:2278
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:2535
dof_id_type id() const
Definition: dof_object.h:819
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 ...
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:2426
const FEType & variable_type(const unsigned int i) const
Definition: dof_map.h:2388
DofConstraints _dof_constraints
Data structure containing DOF constraints.
Definition: dof_map.h:2274
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:2294
void max(const T &r, T &o, Request &req) const
DofConstraintValueMap _primal_constraint_values
Definition: dof_map.h:2276
void heterogeneously_constrain_element_matrix_and_vector(DenseMatrix< Number > &matrix, DenseVector< Number > &rhs, std::vector< dof_id_type > &elem_dofs, bool asymmetric_constraint_rows=true, int qoi_index=-1) const
Constrains the element matrix and vector.
Definition: dof_map.h:2504
std::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:881
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::Nemesis_IO::copy_scalar_solution(), libMesh::ExodusII_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::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(), MeshFunctionTest::test_bad_gradient_var_with_out_of_mesh_value(), MeshFunctionTest::test_bad_hessian_var_with_out_of_mesh_value(), 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(), BoundaryInfoTest::testInternalBoundary(), MeshInputTest::testLowOrderEdgeBlocks(), SystemsTest::testProjectMatrix3D(), BoundaryInfoTest::testShellFaceConstraints(), MeshInputTest::testSingleElementImpl(), WriteVecAndScalar::testSolution(), CheckpointIOTest::testSplitter(), MeshInputTest::testTetgenIO(), MeshSmootherTest::testVariationalSmoother(), 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::MeshBase::element_stored_range(), 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::FEType::p_refinement, libMesh::Threads::parallel_for(), 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 
527  (mesh.element_stored_range(),
528  [](const ElemRange & range)
529  {
530  for (Elem * elem : range)
531  {
532  elem->clear_old_dof_object();
533  libmesh_assert (!elem->get_old_dof_object());
534  }
535  });
536 
537  //------------------------------------------------------------
538  // Set the old_dof_objects for the elements that
539  // weren't just created, if these old dof objects
540  // had variables
541  for (auto & elem : mesh.element_ptr_range())
542  {
543  // Skip the elements that were just refined
544  if (elem->refinement_flag() == Elem::JUST_REFINED)
545  continue;
546 
547  for (Node & node : elem->node_ref_range())
548  if (node.get_old_dof_object() == nullptr)
549  if (node.has_dofs(sys_num))
550  node.set_old_dof_object();
551 
552  libmesh_assert (!elem->get_old_dof_object());
553 
554  if (elem->has_dofs(sys_num))
555  elem->set_old_dof_object();
556  }
557 
558 #endif // #ifdef LIBMESH_ENABLE_AMR
559 
560 
561  //------------------------------------------------------------
562  // Then set the number of variables for each \p DofObject
563  // equal to n_variables() for this system. This will
564  // handle new \p DofObjects that may have just been created
565 
566  // All the nodes
567  for (auto & node : mesh.node_ptr_range())
568  node->set_n_vars_per_group(sys_num, n_vars_per_group);
569 
570  // All the elements
572  (mesh.element_stored_range(),
573  [sys_num, n_vars_per_group](const ElemRange & range)
574  {
575  for (Elem * elem : range)
576  elem->set_n_vars_per_group(sys_num, n_vars_per_group);
577  });
578 
579  // Zero _n_SCALAR_dofs, it will be updated below.
580  this->_n_SCALAR_dofs = 0;
581 
582  //------------------------------------------------------------
583  // Next allocate space for the DOF indices
584  for (unsigned int vg=0; vg<n_var_groups; vg++)
585  {
586  const VariableGroup & vg_description = this->variable_group(vg);
587 
588  const unsigned int n_var_in_group = vg_description.n_variables();
589  const FEType & base_fe_type = vg_description.type();
590 
591  const bool add_p_level = base_fe_type.p_refinement;
592 
593  // Don't need to loop over elements for a SCALAR variable
594  // Just increment _n_SCALAR_dofs
595  if (base_fe_type.family == SCALAR)
596  {
597  this->_n_SCALAR_dofs += base_fe_type.order.get_order()*n_var_in_group;
598  continue;
599  }
600 
601  // This should be constant even on p-refined elements
602  const bool extra_hanging_dofs =
603  FEInterface::extra_hanging_dofs(base_fe_type);
604 
605  // For all the active elements, count vertex degrees of freedom.
606  for (auto & elem : mesh.active_element_ptr_range())
607  {
608  libmesh_assert(elem);
609 
610  // Only number dofs connected to active elements on this
611  // processor and only for variables which are active on on
612  // this element's subdomain or which are active on the
613  // subdomain of a node constrained by this node.
614  const bool active_on_elem =
615  vg_description.active_on_subdomain(elem->subdomain_id());
616 
617  // If there's no way we're active on this element then we're
618  // done
619  if (!active_on_elem && constraining_subdomains_empty)
620  continue;
621 
622  FEType fe_type = base_fe_type;
623 
624  const ElemType type = elem->type();
625 
626  libmesh_error_msg_if(base_fe_type.order.get_order() >
627  int(FEInterface::max_order(base_fe_type,type)),
628  "ERROR: Finite element "
629  << Utility::enum_to_string(base_fe_type.family)
630  << " on geometric element "
631  << Utility::enum_to_string(type)
632  << "\nonly supports FEInterface::max_order = "
633  << FEInterface::max_order(base_fe_type,type)
634  << ", not fe_type.order = "
635  << base_fe_type.order);
636 
637 #ifdef LIBMESH_ENABLE_AMR
638  // Make sure we haven't done more p refinement than we can
639  // handle
640  if (base_fe_type.order + add_p_level*elem->p_level() >
641  FEInterface::max_order(base_fe_type, type))
642  {
643 # ifdef DEBUG
644  libMesh::err << "WARNING: Finite element "
645  << Utility::enum_to_string(base_fe_type.family)
646  << " on geometric element "
647  << Utility::enum_to_string(type) << std::endl
648  << "could not be p refined past FEInterface::max_order = "
649  << FEInterface::max_order(base_fe_type,type)
650  << std::endl;
651 # endif
652  elem->set_p_level(int(FEInterface::max_order(base_fe_type,type))
653  - int(base_fe_type.order));
654  }
655 #endif
656 
657  // Allocate the vertex DOFs
658  for (auto n : elem->node_index_range())
659  {
660  Node & node = elem->node_ref(n);
661 
662  // If we're active on the element then we're active on
663  // its nodes. If we're not then we might *still* be
664  // active on particular constraining nodes.
665  bool active_on_node = active_on_elem;
666  if (!active_on_node)
667  if (auto it = constraining_subdomains.find(&node);
668  it != constraining_subdomains.end())
669  for (auto s : it->second)
670  if (vg_description.active_on_subdomain(s))
671  {
672  active_on_node = true;
673  break;
674  }
675 
676  if (!active_on_node)
677  continue;
678 
679  if (elem->is_vertex(n))
680  {
681  const unsigned int old_node_dofs =
682  node.n_comp_group(sys_num, vg);
683 
684  const unsigned int vertex_dofs =
685  std::max(FEInterface::n_dofs_at_node(fe_type, elem, n, add_p_level),
686  old_node_dofs);
687 
688  // Some discontinuous FEs have no vertex dofs
689  if (vertex_dofs > old_node_dofs)
690  {
691  node.set_n_comp_group(sys_num, vg,
692  vertex_dofs);
693 
694  // Abusing dof_number to set a "this is a
695  // vertex" flag
696  node.set_vg_dof_base(sys_num, vg,
697  vertex_dofs);
698 
699  // libMesh::out << "sys_num,vg,old_node_dofs,vertex_dofs="
700  // << sys_num << ","
701  // << vg << ","
702  // << old_node_dofs << ","
703  // << vertex_dofs << '\n',
704  // node.debug_buffer();
705 
706  // libmesh_assert_equal_to (vertex_dofs, node.n_comp(sys_num, vg));
707  // libmesh_assert_equal_to (vertex_dofs, node.vg_dof_base(sys_num, vg));
708  }
709  }
710  }
711  } // done counting vertex dofs
712 
713  // count edge & face dofs next
714  for (auto & elem : mesh.active_element_ptr_range())
715  {
716  libmesh_assert(elem);
717 
718  // Only number dofs connected to active elements on this
719  // processor and only for variables which are active on on
720  // this element's subdomain or which are active on the
721  // subdomain of a node constrained by this node.
722  const bool active_on_elem =
723  vg_description.active_on_subdomain(elem->subdomain_id());
724 
725  // If there's no way we're active on this element then we're
726  // done
727  if (!active_on_elem && constraining_subdomains_empty)
728  continue;
729 
730  // Allocate the edge and face DOFs
731  for (auto n : elem->node_index_range())
732  {
733  Node & node = elem->node_ref(n);
734 
735  // If we're active on the element then we're active on
736  // its nodes. If we're not then we might *still* be
737  // active on particular constraining nodes.
738  bool active_on_node = active_on_elem;
739  if (!active_on_node)
740  if (auto it = constraining_subdomains.find(&node);
741  it != constraining_subdomains.end())
742  for (auto s : it->second)
743  if (vg_description.active_on_subdomain(s))
744  {
745  active_on_node = true;
746  break;
747  }
748 
749  if (!active_on_node)
750  continue;
751 
752  const unsigned int old_node_dofs =
753  node.n_comp_group(sys_num, vg);
754 
755  const unsigned int vertex_dofs = old_node_dofs?
756  cast_int<unsigned int>(node.vg_dof_base (sys_num,vg)):0;
757 
758  const unsigned int new_node_dofs =
759  FEInterface::n_dofs_at_node(base_fe_type, elem, n, add_p_level);
760 
761  // We've already allocated vertex DOFs
762  if (elem->is_vertex(n))
763  {
764  libmesh_assert_greater_equal (old_node_dofs, vertex_dofs);
765  // //if (vertex_dofs < new_node_dofs)
766  // libMesh::out << "sys_num,vg,old_node_dofs,vertex_dofs,new_node_dofs="
767  // << sys_num << ","
768  // << vg << ","
769  // << old_node_dofs << ","
770  // << vertex_dofs << ","
771  // << new_node_dofs << '\n',
772  // node.debug_buffer();
773 
774  libmesh_assert_greater_equal (vertex_dofs, new_node_dofs);
775  }
776  // We need to allocate the rest
777  else
778  {
779  // If this has no dofs yet, it needs no vertex
780  // dofs, so we just give it edge or face dofs
781  if (!old_node_dofs)
782  {
783  node.set_n_comp_group(sys_num, vg,
784  new_node_dofs);
785  // Abusing dof_number to set a "this has no
786  // vertex dofs" flag
787  if (new_node_dofs)
788  node.set_vg_dof_base(sys_num, vg, 0);
789  }
790 
791  // If this has dofs, but has no vertex dofs,
792  // it may still need more edge or face dofs if
793  // we're p-refined.
794  else if (vertex_dofs == 0)
795  {
796  if (new_node_dofs > old_node_dofs)
797  {
798  node.set_n_comp_group(sys_num, vg,
799  new_node_dofs);
800 
801  node.set_vg_dof_base(sys_num, vg,
802  vertex_dofs);
803  }
804  }
805  // If this is another element's vertex,
806  // add more (non-overlapping) edge/face dofs if
807  // necessary
808  else if (extra_hanging_dofs)
809  {
810  if (new_node_dofs > old_node_dofs - vertex_dofs)
811  {
812  node.set_n_comp_group(sys_num, vg,
813  vertex_dofs + new_node_dofs);
814 
815  node.set_vg_dof_base(sys_num, vg,
816  vertex_dofs);
817  }
818  }
819  // If this is another element's vertex, add any
820  // (overlapping) edge/face dofs if necessary
821  else
822  {
823  libmesh_assert_greater_equal (old_node_dofs, vertex_dofs);
824  if (new_node_dofs > old_node_dofs)
825  {
826  node.set_n_comp_group(sys_num, vg,
827  new_node_dofs);
828 
829  node.set_vg_dof_base (sys_num, vg,
830  vertex_dofs);
831  }
832  }
833  }
834  }
835  // Allocate the element DOFs
836  const unsigned int dofs_per_elem =
837  FEInterface::n_dofs_per_elem(base_fe_type, elem, add_p_level);
838 
839  elem->set_n_comp_group(sys_num, vg, dofs_per_elem);
840 
841  }
842  } // end loop over variable groups
843 
844  // Calling DofMap::reinit() by itself makes little sense,
845  // so we won't bother with nonlocal DofObjects.
846  // Those will be fixed by distribute_dofs
847 
848  //------------------------------------------------------------
849  // Finally, clear all the current DOF indices
850  // (distribute_dofs expects them cleared!)
851  this->invalidate_dofs(mesh);
852 }
static unsigned int n_dofs_per_elem(const unsigned int dim, const FEType &fe_t, const ElemType t)
Definition: fe_interface.C:531
OStreamProxy err
void parallel_for(const Range &range, const Body &body, unsigned int n_threads=libMesh::n_threads())
Execute the provided function object in parallel on the specified range.
Definition: threads_none.h:73
ElemType
Defines an enum for geometric element types.
StoredRange< MeshBase::element_iterator, Elem * > ElemRange
Definition: elem_range.h:31
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:1903
static unsigned int max_order(const FEType &fe_t, const ElemType &el_t)
unsigned int sys_number() const
Definition: dof_map.h:2340
dof_id_type _n_SCALAR_dofs
The total number of SCALAR dofs associated to all SCALAR variables.
Definition: dof_map.h:2258
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:2348
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:437
void invalidate_dofs(MeshBase &mesh) const
Invalidates all active DofObject dofs for this system.
Definition: dof_map.C:856
std::unique_ptr< DefaultCoupling > _default_coupling
The default coupling GhostingFunctor, used to implement standard libMesh sparsity pattern constructio...
Definition: dof_map.h:2199
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 1877 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().

1878 {
1879  this->clear_send_list();
1881 
1882 #ifdef LIBMESH_ENABLE_CONSTRAINTS
1883  // This is assuming that we only need to recommunicate
1884  // the constraints and no new ones have been added since
1885  // a previous call to reinit_constraints.
1886  this->process_constraints(mesh);
1887 #endif
1888  this->prepare_send_list();
1889 }
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:1687
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:1835

◆ reinit_static_condensation()

void libMesh::DofMap::reinit_static_condensation ( )

Calls reinit on the static condensation map if it exists.

Definition at line 3140 of file dof_map.C.

References _sc.

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

3141 {
3142  if (_sc)
3143  _sc->reinit();
3144 }
std::unique_ptr< StaticCondensationDofMap > _sc
Static condensation class.
Definition: dof_map.h:2333

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

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

5501 {
5502  libmesh_assert_greater(_adjoint_dirichlet_boundaries.size(),
5503  qoi_index);
5504 
5505  auto lam = [&boundary_to_remove](const auto & bdy)
5506  {return bdy->b == boundary_to_remove.b && bdy->variables == boundary_to_remove.variables;};
5507 
5508  auto it = std::find_if(_adjoint_dirichlet_boundaries[qoi_index]->begin(),
5509  _adjoint_dirichlet_boundaries[qoi_index]->end(),
5510  lam);
5511 
5512  // Assert it was actually found and remove it from the vector
5513  libmesh_assert (it != _adjoint_dirichlet_boundaries[qoi_index]->end());
5514  _adjoint_dirichlet_boundaries[qoi_index]->erase(it);
5515 }
libmesh_assert(ctx)
std::vector< std::unique_ptr< DirichletBoundaries > > _adjoint_dirichlet_boundaries
Data structure containing Dirichlet functions.
Definition: dof_map.h:2308

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

2090 {
2091  auto raw_it = std::find(_algebraic_ghosting_functors.begin(),
2093  &evaluable_functor);
2094 
2095 #ifndef LIBMESH_ENABLE_DEPRECATED
2096  // We shouldn't be trying to remove a functor that isn't there
2098 #else
2099  // Our old API supported trying to remove a functor that isn't there
2100  if (raw_it != _algebraic_ghosting_functors.end())
2101 #endif
2102  _algebraic_ghosting_functors.erase(raw_it);
2103 
2104  // We shouldn't have had two copies of the same functor
2105  libmesh_assert(std::find(_algebraic_ghosting_functors.begin(),
2107  &evaluable_functor) ==
2109 
2110  _mesh.remove_ghosting_functor(evaluable_functor);
2111 
2112  if (const auto it = _shared_functors.find(&evaluable_functor);
2113  it != _shared_functors.end())
2114  _shared_functors.erase(it);
2115 }
void remove_ghosting_functor(GhostingFunctor &ghosting_functor)
Removes a functor which was previously added to the set of ghosting functors.
Definition: mesh_base.C:1093
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:2220
MeshBase & _mesh
The mesh that system uses.
Definition: dof_map.h:2140
std::map< GhostingFunctor *, std::shared_ptr< GhostingFunctor > > _shared_functors
Hang on to references to any GhostingFunctor objects we were passed in shared_ptr form...
Definition: dof_map.h:2239

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

2033 {
2034  auto raw_it = std::find(_coupling_functors.begin(),
2035  _coupling_functors.end(), &coupling_functor);
2036 
2037 #ifndef LIBMESH_ENABLE_DEPRECATED
2038  // We shouldn't be trying to remove a functor that isn't there
2039  libmesh_assert(raw_it != _coupling_functors.end());
2040 #else
2041  // Our old API supported trying to remove a functor that isn't there
2042  if (raw_it != _coupling_functors.end())
2043 #endif
2044  _coupling_functors.erase(raw_it);
2045 
2046  // We shouldn't have had two copies of the same functor
2047  libmesh_assert(std::find(_coupling_functors.begin(),
2048  _coupling_functors.end(),
2049  &coupling_functor) ==
2050  _coupling_functors.end());
2051 
2052  _mesh.remove_ghosting_functor(coupling_functor);
2053 
2054  if (const auto it = _shared_functors.find(&coupling_functor);
2055  it != _shared_functors.end())
2056  _shared_functors.erase(it);
2057 }
void remove_ghosting_functor(GhostingFunctor &ghosting_functor)
Removes a functor which was previously added to the set of ghosting functors.
Definition: mesh_base.C:1093
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:2233
MeshBase & _mesh
The mesh that system uses.
Definition: dof_map.h:2140
std::map< GhostingFunctor *, std::shared_ptr< GhostingFunctor > > _shared_functors
Hang on to references to any GhostingFunctor objects we were passed in shared_ptr form...
Definition: dof_map.h:2239

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

1989 {
1992 }
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:2032
void remove_algebraic_ghosting_functor(GhostingFunctor &evaluable_functor)
Removes a functor which was previously added to the set of algebraic ghosting functors, from both this DofMap and from the underlying mesh.
Definition: dof_map.C:2089

◆ remove_dirichlet_boundary()

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

Removes the specified Dirichlet boundary from the system.

Definition at line 5485 of file dof_map_constraints.C.

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

5486 {
5487  // Find a boundary condition matching the one to be removed
5488  auto lam = [&boundary_to_remove](const auto & bdy)
5489  {return bdy->b == boundary_to_remove.b && bdy->variables == boundary_to_remove.variables;};
5490 
5491  auto it = std::find_if(_dirichlet_boundaries->begin(), _dirichlet_boundaries->end(), lam);
5492 
5493  // Assert it was actually found and remove it from the vector
5494  libmesh_assert (it != _dirichlet_boundaries->end());
5495  _dirichlet_boundaries->erase(it);
5496 }
std::unique_ptr< DirichletBoundaries > _dirichlet_boundaries
Data structure containing Dirichlet functions.
Definition: dof_map.h:2302
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 2605 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::Nemesis_IO::copy_scalar_solution(), libMesh::ExodusII_IO::copy_scalar_solution(), dof_indices(), local_variable_indices(), old_dof_indices(), libMesh::System::project_vector(), libMesh::System::projection_matrix(), libMesh::System::read_parallel_data(), libMesh::System::read_SCALAR_dofs(), libMesh::StaticCondensationDofMap::reinit(), libMesh::Nemesis_IO_Helper::write_nodal_solution(), libMesh::System::write_parallel_data(), and libMesh::System::write_SCALAR_dofs().

2613 {
2614  // dof_indices() is a relatively light-weight function; the cost of
2615  // the logging code itself is roughly on par with the time required
2616  // to call dof_indices().
2617  // LOG_SCOPE("SCALAR_dof_indices()", "DofMap");
2618 
2619  libmesh_assert(this->variable(vn).type().family == SCALAR);
2620 
2621 #ifdef LIBMESH_ENABLE_AMR
2622  // If we're asking for old dofs then we'd better have some
2623  if (old_dofs)
2624  libmesh_assert_greater_equal(n_old_dofs(), n_SCALAR_dofs());
2625 
2626  dof_id_type my_idx = old_dofs ?
2627  this->_first_old_scalar_df[vn] : this->_first_scalar_df[vn];
2628 #else
2629  dof_id_type my_idx = this->_first_scalar_df[vn];
2630 #endif
2631 
2632  libmesh_assert_not_equal_to(my_idx, DofObject::invalid_id);
2633 
2634  // The number of SCALAR dofs comes from the variable order
2635  const int n_dofs_vn = this->variable(vn).type().order.get_order();
2636 
2637  di.resize(n_dofs_vn);
2638  for (int i = 0; i != n_dofs_vn; ++i)
2639  di[i] = my_idx++;
2640 }
dof_id_type n_SCALAR_dofs() const
Definition: dof_map.h:786
OrderWrapper order
The approximation order of the element (at 0 p-refinement level).
Definition: fe_type.h:203
std::vector< dof_id_type > _first_scalar_df
First DOF index for SCALAR variable v, or garbage for non-SCALAR variable v.
Definition: dof_map.h:2153
const Variable & variable(const unsigned int c) const override
Definition: dof_map.h:2358
std::vector< dof_id_type > _first_old_scalar_df
First old DOF index for SCALAR variable v, or garbage for non-SCALAR variable v.
Definition: dof_map.h:2266
static constexpr dof_id_type invalid_id
An invalid id to distinguish an uninitialized DofObject.
Definition: dof_object.h:473
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 4607 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().

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

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

References _send_list, and local_index().

Referenced by all_semilocal_indices().

2645 {
2646  // If it's not in the local indices
2647  if (!this->local_index(dof_index))
2648  {
2649  // and if it's not in the ghost indices, then we're not
2650  // semilocal
2651  if (!std::binary_search(_send_list.begin(), _send_list.end(), dof_index))
2652  return false;
2653  }
2654 
2655  return true;
2656 }
std::vector< dof_id_type > _send_list
A list containing all the global DOF indices that affect the solution on my processor.
Definition: dof_map.h:2159
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 2541 of file dof_map.h.

References _constrained_sparsity_construction, and libMesh::libmesh_ignore().

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

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

References _implicit_neighbor_dofs, and _implicit_neighbor_dofs_initialized.

Referenced by DisjointNeighborTest::testTempJump(), and DisjointNeighborTest::testTempJumpRefine().

1892 {
1894  _implicit_neighbor_dofs = implicit_neighbor_dofs;
1895 }
bool _implicit_neighbor_dofs_initialized
Bools to indicate if we override the –implicit_neighbor_dofs commandline options.
Definition: dof_map.h:2317
bool _implicit_neighbor_dofs
Definition: dof_map.h:2318

◆ 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:484
MeshBase & mesh
const Parallel::Communicator & comm() const
unsigned int sys_number() const
Definition: dof_map.h:2340
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:473
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:176
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:153
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 1897 of file dof_map.C.

References _verify_dirichlet_bc_consistency.

1898 {
1900 }
bool _verify_dirichlet_bc_consistency
Flag which determines whether we should do some additional checking of the consistency of the Dirichl...
Definition: dof_map.h:2330

◆ should_p_refine() [1/6]

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

Set whether the given variable group should be p-refined on a p-refined Elem.

This changes the FEType of the variable group to enable or disable p-refinement.

Definition at line 2570 of file dof_map.h.

References _variable_groups, _variables, libMesh::VariableGroup::first_scalar_number(), libMesh::libmesh_ignore(), libMesh::make_range(), libMesh::VariableGroup::n_variables(), libMesh::FEType::p_refinement, and libMesh::Variable::type().

Referenced by should_p_refine_var().

2571 {
2572 #ifdef LIBMESH_ENABLE_AMR
2573  VariableGroup & var = _variable_groups[g];
2574  var.type().p_refinement = p_refine;
2575 
2576  for (auto v : make_range(var.first_scalar_number(0),
2577  var.first_scalar_number(0) +
2578  var.n_variables()))
2579  this->_variables[v].type().p_refinement = p_refine;
2580 
2581 
2582 #else
2583  libmesh_ignore(g, p_refine);
2584 #endif
2585 }
std::vector< VariableGroup > _variable_groups
The variable groups in this system/degree of freedom map.
Definition: dof_map.h:2101
void libmesh_ignore(const Args &...)
std::vector< Variable > _variables
The variables in this system/degree of freedom map.
Definition: dof_map.h:2096
IntRange< T > make_range(T beg, T end)
The 2-parameter make_range() helper function returns an IntRange<T> when both input parameters are of...
Definition: int_range.h:176

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

References libMesh::libmesh_ignore(), libMesh::FEType::p_refinement, libMesh::Variable::type(), and variable_group().

2589 {
2590 #ifdef LIBMESH_ENABLE_AMR
2591  const VariableGroup & var = this->variable_group(g);
2592  return var.type().p_refinement;
2593 #else
2594  libmesh_ignore(g);
2595  return false;
2596 #endif
2597 }
void libmesh_ignore(const Args &...)
const VariableGroup & variable_group(const unsigned int c) const
Definition: dof_map.h:2348

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

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

2608 {
2609 #ifdef LIBMESH_ENABLE_AMR
2610  const auto vg = this->var_group_from_var_number(var);
2611  return this->should_p_refine(vg);
2612 #else
2613  libmesh_ignore(var);
2614  return false;
2615 #endif
2616 }
void should_p_refine(unsigned int g, bool p_refine)
Set whether the given variable group should be p-refined on a p-refined Elem.
Definition: dof_map.h:2570
unsigned int var_group_from_var_number(unsigned int var_num) const
Definition: dof_map.h:2600
void libmesh_ignore(const Args &...)

◆ 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:2274
DofConstraints _stashed_dof_constraints
Definition: dof_map.h:2274

◆ 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:2274
DofConstraints _stashed_dof_constraints
Definition: dof_map.h:2274

◆ 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:2274
DofConstraints _stashed_dof_constraints
Definition: dof_map.h:2274

◆ 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:2252
void attach_sparsity_pattern(const SparsityPattern::Build &sp)
Set a pointer to a sparsity pattern to use.
bool need_full_sparsity_pattern
Default false; set to true if any attached matrix requires a full sparsity pattern.
Definition: dof_map.h:2245
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.
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 1903 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().

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

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

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

Referenced by should_p_refine_var(), and EquationSystemsTest::testSelectivePRefine().

2601 {
2602  libmesh_assert(var_num < n_variables());
2603  return libmesh_map_find(_var_to_vg, var_num);
2604 }
std::unordered_map< unsigned int, unsigned int > _var_to_vg
A map from variable number to variable group number.
Definition: dof_map.h:2111
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 2358 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().

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

◆ 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 2348 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(), should_p_refine(), and libMesh::System::variable_group().

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

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

References _variable_groups.

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

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

References _variable_groups.

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

◆ variable_name()

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

Definition at line 2943 of file dof_map.h.

References _variables.

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

2944 {
2945  libmesh_assert_less (i, _variables.size());
2946 
2947  return _variables[i].name();
2948 }
std::vector< Variable > _variables
The variables in this system/degree of freedom map.
Definition: dof_map.h:2096

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

2992 {
2993  auto var_num = libmesh_map_find(_variable_numbers, var);
2994  libmesh_assert_equal_to(_variables[var_num].name(), var);
2995  return var_num;
2996 }
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:2117
std::vector< Variable > _variables
The variables in this system/degree of freedom map.
Definition: dof_map.h:2096

◆ variable_order()

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

Definition at line 2368 of file dof_map.h.

References _variables.

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

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

References _variables.

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

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

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

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

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

References _variables, and variable_number().

2982 {
2983  return _variables[this->variable_number(var)].type();
2984 }
std::vector< Variable > _variables
The variables in this system/degree of freedom map.
Definition: dof_map.h:2096
unsigned int variable_number(std::string_view var) const
Definition: dof_map.h:2991

Friends And Related Function Documentation

◆ SparsityPattern::Build

friend class SparsityPattern::Build
friend

Definition at line 2311 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 2308 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 2220 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 2124 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 2181 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 2164 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 2091 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 2233 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 2199 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 2207 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 2302 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().

◆ _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 2085 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 2191 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 2186 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 2176 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 2169 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 2266 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 2153 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 2130 of file dof_map.h.

Referenced by identify_variable_groups().

◆ _implicit_neighbor_dofs

bool libMesh::DofMap::_implicit_neighbor_dofs
private

Definition at line 2318 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 2317 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 2147 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 2258 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 2294 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 2159 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 2239 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 2252 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 2135 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 2111 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 2106 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 2101 of file dof_map.h.

Referenced by add_variable(), add_variables(), array_dof_indices(), clear(), n_variable_groups(), should_p_refine(), 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 2117 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 2330 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 2245 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: